| Files | Last commit | Last update |
|---|---|---|
docs(smoke): Wave 1 双姿态真机验收销账 + AGENTS.md 折叠强制规则落地 改了什么 - AGENTS.md 运行时冒烟章节新增《折叠 + 非折叠双姿态强制(2026-09-09 拍板)》: 只要改动会经过 gsy_adaptive_shell.dart / navigator_utils.dart 分栏分支 (列表 → 详情、右列 detail navigator、wrapListChild、canShowTwoPane 门控、 弹窗路由等),冒烟证据必须覆盖 CLOSED(adb emu fold)+ OPENED(adb emu unfold) 两档硬件姿态,缺一档视为汇报不完整;纯模型/工具函数可豁免。收尾必须 emu unfold 复位到 default identifier=2 OPENED。 - 新增 tool/ai/smoke/open_discussion_verify.md:Wave 1 Discussions 家族 5 条真机 验收缺口的 SOP,写死 fixture(BettaFish#417/#511/#697/#309 + vercel/next.js #49607),双姿态策略、mcp_dart 触发 / 命中 / 收尾三段式,禁止 adb 坐标脚本。 - docs/00-overview/roadmap.md §3.1 新增《2026-09-09 Wave 1 双姿态真机验收整体销账》 段落:pt.1 视觉侧 / pt.2 / pt.3 视觉侧 / pt.4 / pt.5 双姿态各留一档证据; 三个已知缺口显式列进 Wave 2(reactions 写操作、loadMore 60→90 触发、 长嵌套 replies)。声明 probe_device_rotation.ps1 不再作为 Wave 1 前置。 为何这么改 - 用户 2026-09-09 二次拍板:Wave 1 首次冒烟只做了 CLOSED 一档就报进度,被当场 纠正。discussion 详情走 _openDetailOrRouter,compact 用 Navigator.push 到主 Navigator、expanded 用 detailNavigatorKey 到右列,两条代码路径不同、UI 呈现 不同,只跑一档等于漏一半。 - 硬件姿态命令走 adb emu fold / adb emu unfold(Android SDK platform-tools 内置 Emulator Console),跨 Flutter / Android SDK 版本演进,替代之前 wm size / wm density / mediaQuery.override 等伪造分档手段(一律禁止)。 - AGENTS.md 是团队协作规约的唯一权威入口,把强制规则写在这里可让 reviewer 在 未来 PR 上直接引用;SOP 沉淀到 tool/ai/smoke/ 供下一轮跟进 Wave 2 或长嵌套 fixture 时复用。 测试与验证 - 看代码:本次仅新增/修改文档,无 Dart 代码改动,不触发 build_runner / gen_l10n。 - 看编译:无需 analyze / build(文档改动)。 - 看运行: - 设备:emulator-5554(gsy_pixel_fold, Android 16 API 36, versionName 8.1.1) + 真机 jfxgpjeul7lrpjkz 仅做人眼对拍 - DTD:ws://127.0.0.1:11931/kWq1R9CKmy0= - VM Service:ws://127.0.0.1:11932/AhATIvYGwtI=/ws - pt.1~pt.5 双姿态共 12 张截图 + 每条路径 mcp_dart get_runtime_errors 全绿 (baseline 与 final diff 无新增 Dart 异常),证据落地绝对路径见 d:\workspace\project\gsy_github_app_flutter\tool\ai\smoke\evidence\20260909-discussion-verify\ (目录已 gitignore,仅入档路径供 reviewer 复核) - 复位:结束时 adb -s emulator-5554 emu unfold 已跑,cmd device_state state 确认 identifier=2 OPENED - 已知缺口(Wave 2 收敛): a) reactions 写操作两姿态(_toggleReaction 私有方法,需在 lib/app.dart 加 gsySmokeToggleDiscussionReaction hook 或人肉降级) b) loadMore 60→90 触发两姿态(_loadMore 私有 + 需滚到列表尾) c) 长嵌套(20+ replies)压力 | 1 month ago | |
fix: consolidate monitoring and application runtime improvements Integrate the pinned monitoring SDK with authenticated transport and page attribution. Correct request ownership, resource loading and page lifecycles, preserve offline code rendering and use the official repository primary language. | 17 days ago | |
fix: consolidate monitoring and application runtime improvements Integrate the pinned monitoring SDK with authenticated transport and page attribution. Correct request ownership, resource loading and page lifecycles, preserve offline code rendering and use the official repository primary language. | 17 days ago | |
fix: consolidate monitoring and application runtime improvements Integrate the pinned monitoring SDK with authenticated transport and page attribution. Correct request ownership, resource loading and page lifecycles, preserve offline code rendering and use the official repository primary language. | 17 days ago | |
fix(adaptive): shellDetail 跨断点迁移保栈 + 修复动态点击卡死 & Search 月牙形残留 问题 ---- 基于 08d73be 的 Master-Detail 契约收紧,本轮把 shellDetail 路由跨断点 迁移做完,并修掉两条上一版遗留的连锁副作用: 1. bug(a) expanded → 直接切 compact:detail 栈原地丢失(Search 在右列, 一折叠就消失); 2. bug(b) compact → 直接切 expanded:detail 页原地"铺满全屏",没有回到 右列 detail 语义; 3. observer 单例被同时挂到 root/detail 两个 Navigator,触发 Flutter assert(observer.navigator == null),表现为**动态列表 item 点击整体 无响应**(上一版"越改越傻逼"的直接锅); 4. compact 侧 Search 页 [CRAnimation](lib/page/search/search_page.dart) 在迁移重放场景下用了 expanded 分档缓存下来的 centerPosition, 导致稳态渲染出现"月牙形"缺角。 修法 ---- lib/common/style/gsy_adaptive_shell.dart - 引入 GSYShellDetailEntry { routeName, builder } + _shellDetailStack 做 shellDetail 的记账;observer 从**单例**改成 createShellDetailObserver() 工厂,root/detail 各挂一份,避免 NavigatorObserver 断言炸裂。 - 新增 migrateShellDetailStack(toTwoPane):断点切换时把源 Navigator 的 shellDetail 栈 pop 干净、按记账重建到目标 Navigator。 - toTwoPane=true → 目标是 detail,MaterialPageRoute(右列滑入); - toTwoPane=false → 目标是 root,CupertinoPageRoute(与 compact 常规 push 观感一致)。 - 迁移期加 _migrating 屏蔽 observer 的 didPop 回调,避免 pop 时 误把栈清成空。 - migrateShellDetailStack null 兜底:expanded→compact 时 detail Navigator 可能已经 disposed,source 允许为 null,跳过 pop 直接 push 到 target。 lib/common/utils/navigator_utils.dart - 把 goPerson / goReposDetail / goIssueDetail / goSearch / ... 这类 shellDetail caller 统一走 _openDetailOrRouter(routeName, pageBuilder):**用 builder 记账**,迁移重放时能重新构造 route。 - route settings.name 做 /null → /- 兜底(避免脏 key 污染 talker / observer / 埋点)。 - compact 侧 goReposDetail 的自定义 SizeTransition 收敛为 Cupertino 默认转场,与 Search / Discussion 一致;换取跨断点保栈 + 保业务参数。 lib/widget/gsy_tabbar_widget.dart, lib/app.dart - shell / root 各持一个 _shellDetailObserver 实例(不再共享单例), 绑定生命周期到 State,dispose 时释放。 - shell 断点跨越时调用 migrateShellDetailStack,触发路由迁移。 lib/page/search/search_page.dart - build 里加 endAnima || controller.isCompleted 判定:迁移重放场景 controller 已完成时**跳过 CRAnimation ClipPath**,只保留 endAnima 底色, 避免用 expanded 分档缓存下来的 centerPosition 画出月牙形残留。 其余 ---- - 补 unit / widget test: - test/common/style/gsy_adaptive_shell_test.dart 加迁移契约覆盖; - test/common/utils/navigator_utils_search_test.dart 覆盖 goSearch 在 compact / expanded 下的落点差异; - test/page/search/search_page_route_topology_test.dart 覆盖 Search 迁移重放不再走 CRAnimation clip; - test/page/repos/repos_detail_tab_wrap_list_child_test.dart 补 Repos detail tab 子项契约; - test/widget/gsy_tabbar_widget_test.dart 覆盖 shell observer 生命周期; - test/widget/pull/gsy_(nested_)pull_load_widget_test.dart 覆盖上拉 加载在嵌套滚动下的边界。 - docs/01-architecture/route-topology.md 新增,描述 shellDetail 与 root/detail 的路由归属分档;顺带订正 roadmap / app-layering / smoke-matrix / test-strategy / ADR-0005 若干处术语。 - 补 tool/ai/smoke/vm_eval.ps1 / vm_rpc.ps1:mcp_dart 未挂载时用 VM Service RPC 兜底抓 widget tree / evaluate,evidence 章节可复用。 - .gitignore:logs/ 与 tool/dbg/**/*.dart 都算 debug 产物,收敛不入库。 已知缺口 / 待补 -------------- - 本轮**没有跑通 mcp_dart 一等公民验证**:会话环境只挂了 integrated_browser,走的是 adb screencap + logcat fallback, 违反 AGENTS.md "mcp_dart 一等公民" 规则。 - Fold 展开态双栏渲染未复核:之前的 adb wm size 1080x2092 hack 把设备锁死在 compact 分档,已 wm size reset 恢复 2208×1840, 但没在展开态复核 canShowTwoPane 是否真的进双栏——这一段需要在 挂载 mcp_dart 的会话里 widget_inspector get_widget_tree 命中 两列结构才算数。 - 上述缺口先在 commit 里显式挂账,next step 由挂 mcp_dart 的会话 在真机上收尾并补 evidence 截图/widget tree dump。 | 2 months ago | |
feat(adaptive): P0/P1/P2 大屏与折叠屏自适应导航 + Master-Detail 双栏 + 修复 squash 20 commits from feature/adaptive-layout-p1-rail into master rebase, preserving全部里程碑记录。原 commit 序保存于 backup 分支 backup/adaptive-layout-p1-rail-before-rebase-260903(本地)。 - feat(responsive): 引入 GSYBreakpoints (compact <600 / medium <840 / expanded) + GSYResponsiveContext 扩展;识别 vertical hinge display feature - fix(orient): 离开代码详情不再锁竖屏 - fix(tabbar): 旋转时重算 PageView offset - refactor(pull-load): LayoutBuilder 计算空态高度 - feat(nav-rail): home shell 在 medium/expanded 切 NavigationRail、compact 保底部 tab - fix(nav-rail): rail 兼容手机横屏、移除 tabView 限宽避免 MyPage 溢出 - refactor(nav-shell): 提取 GSYAdaptiveNavigation delegate 单例(可替换契约) - fixup(adaptive-shell): 处理 F1~F7 blocking:generic push type、 detail Navigator popUntil、shell dispose 清栈、单例 delegate reset for tests、 错误 shell context 兜底 - refactor(nav-shell): wrapListChild + wrapUserStatsBar 契约 - feat(list-card): GSYPullLoadWidget item 沿用 wrapListChild 限宽 - feat(my-page-stats): medium 断点下 5 列 stats 折成 "3 + 2" - feat(adaptive/p2s2): Home Master-Detail 双栏(Trend/Dynamic/Notify), openDetail 分派到 detailNavigatorKey、canShowTwoPane 判定 expanded && !narrowHeight - fix(adaptive) M1/M2 fixup: shell 订阅 force full-screen provider、 切 tab 清 detail 栈避免残留、GlobalKey reparent 防御 - fix(adaptive/p2): 硬件返回键先弹 detail navigator 栈,栈空才 exit; 单栏下 detailNavigatorKey.currentState == null 走原行为,zero regression - fix(adaptive/p2): ReposItem 用 LayoutBuilder 拿 constraints.maxWidth 避免 在 ~500dp master 列 overflow 141/243 px - docs(adaptive/p2): tabbar popDetailToRoot 顺序对齐 tap/PageView 双路径 - test(responsive): breakpoint / verticalHinge 契约 - test(nav-shell): rail↔tab 切换、canShowTwoPane、force full-screen、 wrapListChild/wrapUserStatsBar、openDetail 分派、popDetailToRoot、 切 tab 清栈、HomePage.PopScope 契约 - test(page/repos): ReposItem 在 500dp 容器下 tester.takeException() == null - expanded 2400x1080 / density 240:detail 弹回 placeholder、master 保留、 ReposItem 无 overflow - compact 1080x2400 / density 440:root Navigator 弹全屏 detail、PopScope 未误触发;HomePage 栈顶 back 走 _dialogExitApp 回桌面 - adb logcat -d -s flutter 无 Exception|Error|Overflow 匹配 - 详见 tool/dbg/m1m2_20260903/(本地保留、不入库) - fold 折叠屏物理翻转 → expanded 未真机验证,需 P4 阶段 Galaxy Fold/Pixel Fold 真机上端到端跑 posture→windowSize→layout 链路 原分层 commits: 7bbdbc0 feat(responsive) b3a29c1 fix(orient) c3302d1 fix(tabbar) 17fafbd refactor(pull-load) 9769ee4 feat(nav-rail) bf43f92 fix(nav-rail) 87705ec refactor(nav-shell) delegate 0dd0f0f fixup(adaptive-shell) F1~F7 4e69ccc chore(rebase) pubspec.lock rive 0.14 be0b867 refactor(nav-shell) wrapListChild 77d2f67 feat(list-card) apply wrapListChild 1a8554b fixup F1-F2 01f9b7b refactor(nav-shell) wrapUserStatsBar e10a687 feat(my-page-stats) 16f7871 fixup W1-W4 + N1/N5 b9c6659 feat(adaptive/p2s2) Master-Detail 9ae97e8 docs(adaptive/p2s2) fcfb602 fix(adaptive) M1/M2 7fb271f fix(adaptive/p2) back + ReposItem 97498b7 docs(adaptive/p2) tabbar 顺序订正 | 2 months ago | |
fix(adaptive): shellDetail 跨断点迁移保栈 + 修复动态点击卡死 & Search 月牙形残留 问题 ---- 基于 08d73be 的 Master-Detail 契约收紧,本轮把 shellDetail 路由跨断点 迁移做完,并修掉两条上一版遗留的连锁副作用: 1. bug(a) expanded → 直接切 compact:detail 栈原地丢失(Search 在右列, 一折叠就消失); 2. bug(b) compact → 直接切 expanded:detail 页原地"铺满全屏",没有回到 右列 detail 语义; 3. observer 单例被同时挂到 root/detail 两个 Navigator,触发 Flutter assert(observer.navigator == null),表现为**动态列表 item 点击整体 无响应**(上一版"越改越傻逼"的直接锅); 4. compact 侧 Search 页 [CRAnimation](lib/page/search/search_page.dart) 在迁移重放场景下用了 expanded 分档缓存下来的 centerPosition, 导致稳态渲染出现"月牙形"缺角。 修法 ---- lib/common/style/gsy_adaptive_shell.dart - 引入 GSYShellDetailEntry { routeName, builder } + _shellDetailStack 做 shellDetail 的记账;observer 从**单例**改成 createShellDetailObserver() 工厂,root/detail 各挂一份,避免 NavigatorObserver 断言炸裂。 - 新增 migrateShellDetailStack(toTwoPane):断点切换时把源 Navigator 的 shellDetail 栈 pop 干净、按记账重建到目标 Navigator。 - toTwoPane=true → 目标是 detail,MaterialPageRoute(右列滑入); - toTwoPane=false → 目标是 root,CupertinoPageRoute(与 compact 常规 push 观感一致)。 - 迁移期加 _migrating 屏蔽 observer 的 didPop 回调,避免 pop 时 误把栈清成空。 - migrateShellDetailStack null 兜底:expanded→compact 时 detail Navigator 可能已经 disposed,source 允许为 null,跳过 pop 直接 push 到 target。 lib/common/utils/navigator_utils.dart - 把 goPerson / goReposDetail / goIssueDetail / goSearch / ... 这类 shellDetail caller 统一走 _openDetailOrRouter(routeName, pageBuilder):**用 builder 记账**,迁移重放时能重新构造 route。 - route settings.name 做 /null → /- 兜底(避免脏 key 污染 talker / observer / 埋点)。 - compact 侧 goReposDetail 的自定义 SizeTransition 收敛为 Cupertino 默认转场,与 Search / Discussion 一致;换取跨断点保栈 + 保业务参数。 lib/widget/gsy_tabbar_widget.dart, lib/app.dart - shell / root 各持一个 _shellDetailObserver 实例(不再共享单例), 绑定生命周期到 State,dispose 时释放。 - shell 断点跨越时调用 migrateShellDetailStack,触发路由迁移。 lib/page/search/search_page.dart - build 里加 endAnima || controller.isCompleted 判定:迁移重放场景 controller 已完成时**跳过 CRAnimation ClipPath**,只保留 endAnima 底色, 避免用 expanded 分档缓存下来的 centerPosition 画出月牙形残留。 其余 ---- - 补 unit / widget test: - test/common/style/gsy_adaptive_shell_test.dart 加迁移契约覆盖; - test/common/utils/navigator_utils_search_test.dart 覆盖 goSearch 在 compact / expanded 下的落点差异; - test/page/search/search_page_route_topology_test.dart 覆盖 Search 迁移重放不再走 CRAnimation clip; - test/page/repos/repos_detail_tab_wrap_list_child_test.dart 补 Repos detail tab 子项契约; - test/widget/gsy_tabbar_widget_test.dart 覆盖 shell observer 生命周期; - test/widget/pull/gsy_(nested_)pull_load_widget_test.dart 覆盖上拉 加载在嵌套滚动下的边界。 - docs/01-architecture/route-topology.md 新增,描述 shellDetail 与 root/detail 的路由归属分档;顺带订正 roadmap / app-layering / smoke-matrix / test-strategy / ADR-0005 若干处术语。 - 补 tool/ai/smoke/vm_eval.ps1 / vm_rpc.ps1:mcp_dart 未挂载时用 VM Service RPC 兜底抓 widget tree / evaluate,evidence 章节可复用。 - .gitignore:logs/ 与 tool/dbg/**/*.dart 都算 debug 产物,收敛不入库。 已知缺口 / 待补 -------------- - 本轮**没有跑通 mcp_dart 一等公民验证**:会话环境只挂了 integrated_browser,走的是 adb screencap + logcat fallback, 违反 AGENTS.md "mcp_dart 一等公民" 规则。 - Fold 展开态双栏渲染未复核:之前的 adb wm size 1080x2092 hack 把设备锁死在 compact 分档,已 wm size reset 恢复 2208×1840, 但没在展开态复核 canShowTwoPane 是否真的进双栏——这一段需要在 挂载 mcp_dart 的会话里 widget_inspector get_widget_tree 命中 两列结构才算数。 - 上述缺口先在 commit 里显式挂账,next step 由挂 mcp_dart 的会话 在真机上收尾并补 evidence 截图/widget tree dump。 | 2 months ago | |
docs: Add AI collaboration ecosystem and architecture guides - Initialize docs/ directory with project map, architecture layering, and state management matrix. - Add AGENTS.md and context-specific agent guides in lib/ directories. - Implement AI task playbooks, feature playbooks, and review harness in docs/05-ai/. - Add ADRs for state management policies in docs/06-decisions/. - SearchPage: Refactor filter reset logic to SearchBloc and GSYSearchDrawer to ensure proper cleanup on dispose. - README.md: Update with entry points for AI collaboration. | 7 months ago | |
fix: consolidate monitoring and application runtime improvements Integrate the pinned monitoring SDK with authenticated transport and page attribution. Correct request ownership, resource loading and page lifecycles, preserve offline code rendering and use the official repository primary language. | 17 days ago |
文档索引
这个目录同时服务于人类协作者和代码 agent。 第一次进入仓库时,建议按顺序阅读,不要只看根 README 就直接改代码。
推荐阅读顺序
00-overview/project-map.md00-overview/roadmap.md01-architecture/app-layering.md01-architecture/state-management-matrix.md03-runbooks/local-setup.md04-quality/test-strategy.md04-quality/smoke-matrix.md05-ai/agent-guide.md06-decisions/(长期决策,按 ADR 编号从旧到新读)
目录说明
00-overview/:快速理解项目和目录职责01-architecture/:分层边界、状态管理边界、生成代码与配置规则02-features/:按功能说明关键页面、数据流和高风险点03-runbooks/:本地运行和常见操作手册04-quality/:验证方式、质量门槛、测试策略05-ai/:面向 agent 的工作约束和执行方式06-decisions/:需要长期保留的架构决策记录
当前关键文档
- 架构边界:
01-architecture/app-layering.md - 状态管理边界:
01-architecture/state-management-matrix.md - 当前现状与待办清单:
00-overview/roadmap.md - 手工回归入口:
04-quality/smoke-matrix.md - 线上性能监控接入与验收:
03-runbooks/performance-monitoring.md - 长期规则:
06-decisions/ADR-0001-状态管理收敛策略.md06-decisions/ADR-0005-大屏与折叠屏自适应导航抽象.md
- 任务模板入口:
05-ai/task-playbooks/ - 功能模板入口:
05-ai/feature-playbooks/ - AI 协作导航:
CONTRIBUTING_AI.md
当前目标
当前这批文档的重点不是先做“AI 功能”,而是先把仓库整理成:
- 更容易理解
- 更容易局部修改
- 更容易验证
- 更不容易让 agent 猜错边界