跨平台、本地优先、注重隐私的日记 App。Flutter / Dart,stable 渠道最新版。
| 想知道 | 看这里 |
|---|---|
| 技术选型 / 加密 / 备份 / 编辑器等冻结决策 | docs/README.md → docs/design/0X-*.md |
| spec 怎么写、执行协议、档位选择 | spec-kit/spec-guide.md(规则真源);DayZ overlay docs/spec-guide-ai.md |
| 当前功能列表、状态、优先级、依赖 | specs/README.md |
| 单个功能的需求 / 设计 / 任务 | specs/active/<feature>/ |
| 端到端原生测试 / 验收分层(Patrol,iOS+Android 冒烟已通) | spec specs/active/e2e-harness/;一次性接入 SOP runbook docs/patrol-e2e-onboarding.md;跑测经 scripts/patrol_test.sh(flaky 防护+零执行守卫) |
| UI 像素级对齐还原与避坑 SOP | docs/design/10-ui-restore-and-design-sync.md |
- 接到任务 → 在
specs/active/<feature>/tasks.md找对应 T# 项。 - 按
spec-kit/spec-guide.md执行协议做事(DayZ 专项见docs/spec-guide-ai.md);可改文件、验收方式都在任务卡里。 - 完成后填验收记录,按
specs/README.md更新状态。
屏幕 spec 交付 v1 后进入「已交付·随设计维护」泳道,终态→归档规则被 DayZ overlay override;细则见 docs/spec-guide-ai.md。
新增功能或重大改动 → 先开 spec,不在源码里直接做。开 spec 时按 spec-guide「排序维护纪律」想清依赖、相对现有 spec 定优先级,并落到 specs/README.md 的依赖 / 优先级列——别留空或无脑同档。spec 已经写明的事,不要在这里、commit message、PR 描述里重复。
- 中文回复:本项目的问答与开发指导始终使用中文。
- 绝对禁止自行提交:未经当次明确的交互授权,严禁自行执行
git commit或 push。即使在用户泛指“收尾提交”的语境下,也必须在执行 commit 前,向用户出示 Diff 与 commit message,并在用户明确回复“确认提交”或类似确认指令后,方可执行 commit 动作。 - 作者署名统一
@Ray。 - 授权 MPL-2.0(混合授权):新建 Dart 源文件 MUST 加 MPL-2.0 头注(模板见 README「License」)。
packages/appflowy-editor/保留上游 AGPL-3.0 / MPL-2.0 双授权,不可重新授权。 - 包名
com.dayz,iOS 13+,Android minSdk 26。 - 本地 Package 独立提交:
packages/下的代码、测试、pubspec.lock及packages/CHANGELOG.md必须作为独立 Git Commit,不得同业务或 Demo 层代码混合。 - vendored 包改动留痕(三件套缺一不可):① 成对标记
// >>> DAYZ-PATCH[Pxxx]…// <<< DAYZ-PATCH[Pxxx];②packages/CHANGELOG.md台账登记;③ 提交前bash scripts/check_patches.sh须退出 0。详见specs/active/appflowy-patch-tracking/。 - 静态资源
flutter_gen:禁止硬编码资源路径,必须用Assets.images.xxx等强类型引用。新增/修改资源后运行dart run build_runner build。 - 国际化
gen-l10n:用户可见文案经AppLocalizations.of(context)取用,禁止硬编码。新增文案 MUST 同时补app_zh.arb与app_en.arb(key 一致)。详见docs/design/11-internationalization-and-localization.md。 - 端到端原生测试(Patrol)+ 验收分层:原生跨界流程(权限 / 相册
image_picker/ 文件 IO / Keychain / 前后台)的 E2E 用 Patrol——用例放patrol_test/(不是integration_test/,4.0 起目录变了)、屏 specdependsOn e2e-harness;纯 in-Flutter 行为继续 widget test。屏 spec 的verification.md按**「自动化可覆盖 / 必须人工」分层**;安全·不可逆链路(加密 / 备份 / 还原)即便 E2E 绿也保留人工终验(patrol 有静默假阳性先例)。一次性接入 SOP + 成本账 + flaky 防护见specs/active/e2e-harness/。 - 屏幕 spec 维护态 override:屏幕级 spec 交付 v1 后不按通用「终态→归档」处理,转入
specs/README.md「已交付·随设计维护」泳道;该 override 仅限屏幕 spec,见docs/spec-guide-ai.md。 - UI 设计稿未到,基础层先行:基础 spec 末尾挂 Debug Home 入口,真机调试走 demo 页。
- Flutter SDK cache 沙箱权限:在 Codex 沙箱内,
flutter pub get/flutter test/flutter build .../flutter run等 Flutter 命令都可能先执行 SDK 内部update_engine_version.sh,写/opt/homebrew/Caskroom/flutter/.../bin/cache/engine.stamp.tmp.*、engine.realm等工作区外缓存;若报Operation not permitted,这通常是沙箱权限问题,不是依赖解析或业务代码问题。按审批机制对同一条 Flutter 命令提升权限重跑;不要在普通沙箱里反复重试,也不要先改源码排查。 - build_runner 权限注意:本环境里普通沙箱曾出现
dart run build_runner ...无输出卡住;需要 codegen 时优先用已批准的提升权限dart run build_runner ...。若已卡住,先终止卡住的dart.*build_runner进程,再dart run build_runner clean后重跑。 - Git index 写入权限:
git add/git commit/ 部分git update-index会创建或更新.git/index.lock;若在 Codex 沙箱内实际报Operation not permitted,按审批机制对该 git 命令请求提升权限重跑,不要在普通沙箱里反复重试。git status/git diff等只读检查不需要升权。 - Flutter/Dart 命令串行:不要并行跑多个
flutter test/dart run build_runner/ Flutter 工具命令;它们可能抢启动锁、ios/Flutter/ephemeral、.dart_tool/build或build/native_assets/*,导致偶发删除失败、签名失败或旧产物误判。涉及 native assets / SQLCipher 的测试统一-j 1串行跑。 - iOS 构建排障权限:在 Codex 内跑
flutter build ios/flutter run会写 Flutter SDK cache、Xcode DerivedData、CoreSimulator 等工作区外目录;若沙箱里出现Operation not permitted,或 Xcode Pods embed framework 脚本偶发Killed: 9,先提升权限单独重跑一次确认。若提升权限能过、用户终端仍失败,再清 DerivedData/Pods 缓存排查,不要先改业务源码。 - Drift 测试导入冲突:测试文件若只需要
Value,用import 'package:drift/drift.dart' show Value;,避免引入不必要符号并减少与flutter_test/matcher断言命名互扰。 - SQLite DateTime 断言:Drift/SQLite 读回
DateTime时可能变成本地时区表示同一瞬间;测试比较同一时刻时先.toUtc(),不要直接和 UTC 字面值比对象。 - timezone UTC 别名:
timezone的UTCalias 支持可能随包版本 / 数据集变化;项目工具已将UTC归一到Etc/UTC。后续测试和调用优先用 IANA 名称,常见 UTC 输入仍应保持兼容。 - SQLCipher 探测口径:当前
sqlite33.x + SQLite3MultipleCiphers 下PRAGMA cipher_version可能为空;验证 SQLCipher 模式用PRAGMA cipher == sqlcipher,并结合密文文件头与错密钥抛WrongKeyException行为验证。 - Patrol 跑测别裸调(会假崩 / 假阴):① 启动遥测偶发 TLS handshake 崩 CLI → 写
~/.config/patrol_cli/analytics.json{"enabled":false}+ 带PATROL_ANALYTICS_ENABLED=false;②sqlite33.3.x hook 的download-*目录默认跨 Dart VM 进程不稳定,会让sqlite3mcdylib/.so绕开 shared-cache 反复下载 → wrapper 给 Flutter tool 注入--deterministic稳定缓存目录,若 native assets / Maven(kotlin-compiler-embeddable)下载或 handshake 中途断再 retry;③ Android 首跑偶发Total:0(app-service 时序)、重跑即绿,并校验Total:非零防静默假阳性。Rust 交叉编译(argon2id, aarch64-linux-android)需 rustup 接管(rust 已brew unlink)+ android target + NDK。iOS 一次性建 UITest target 用scripts/setup_patrol_ios.rb(CocoaPods 的xcodeprojgem)。