Files
soft_quay/docs/tasks/T-610.md
T

90 lines
8.7 KiB
Markdown

---
id: T-610
title: 拆分双端 Gio shell 职责
phase: 2
deps: [T-609]
status: DONE
created: 2026-07-17
issue: null
context_ref: 75b1803564dd95284dc5bc25719ccdb5b3e55274
claim_branch: null
work_branch: agent/codex/T-610
write_paths:
- docs/tasks/T-610.md
- app-modern/ui/gio/
- app-win7/ui/gio/
- docs/routes.md
- docs/04-architecture.md
- docs/05-coding-rules.md
- docs/review/phase2-review.md
- docs/00-ai-start-here.md
- docs/06-tasks.md
- docs/current-state.md
---
## 问题 / 背景
modern 与 Win7 的 `ui/gio/shell.go` 分别达到 959 行和 880 行,同时承载 `AppShell` 状态与快照生命周期、根布局编排、输入 drain、header/category/view 导航、catalog/list/row/icon、detail 和样式/文案 helper。代码图也把 `Layout`、`layoutContent`、`layoutAppRow`、`layoutDetail` 与 `panel` 识别为同一高耦合热点。继续在单文件中增加下载、设置或授权视图,会扩大冲突范围和两套隔离 Gio 适配器的人工 diff 噪声。
双端平行实现是既定架构取舍:modern 锁定 Gio v0.10.1,Win7 锁定 Gio v0.6.0,布局细节和可用 API 存在有意差异。本任务不尝试共享 Gio 控件代码,只在各自现有 `gio` package 内按一致职责拆文件,让后续改动有明确落点。T-608 已提供双端适配器交互契约,T-609 已冻结列表快照生命周期,当前保护面足以约束纯组织性移动。
本任务是行为不变的维护性重构,不交付新界面或业务能力,也不借拆分修正视觉、文案、事件时序或模型语义。
## 方案
1. 在移动前用代码图记录两个 `shell.go` 的声明清单和调用关系,把现有公开/未公开符号作为重构基线;移动后再次核对每个符号恰有一个定义,没有遗漏、复制或意外改名。
2. 在 modern 与 Win7 的 `ui/gio` package 中采用相同文件职责:
- `shell.go`:保留 `AppShell` 状态、构造、`ApplyIcon`/`SetItems` 生命周期、根 `Layout` 与 `drainInput` 编排。
- `shell_header.go`:承载 header、category、view/filter 导航和 footer 等顶部/导航职责。
- `shell_catalog.go`:承载 content/catalog、虚拟列表、app row、icon 与 empty state;行控件状态跟随该职责。
- `shell_detail.go`:承载 detail 布局及其字段、动作和 fallback/reason helper。
- `shell_style.go`:承载 palette/theme、panel 绘制、view/status 文案与颜色 helper。
modern-only 的 `layoutCatalog`、`layoutFooter`、`actionLabel` 等放入对应职责文件,Win7 不为追求文本一致而增加空壳或复制 modern 实现。
3. 只移动完整声明并收敛各文件 import,保持 package 名、接收者、函数签名、常量值、控件实例、map/list 所有权和调用顺序不变;执行 `gofmt`,不做顺手重命名或逻辑整理。
4. 冻结根布局与交互不变量:
- 每帧仍先 drain application/UI input,再按原顺序布局 header、content/detail/footer。
- 搜索、分类、view、行点击、关闭详情、空状态恢复和虚拟列表 viewport 的事件处理顺序不变。
- `rowControls` 继续按 app ID 保持,删除项/category controls 继续释放;`layout.List.Position` 与 selection/detail 上下文不重置。
- 图标请求身份、UI goroutine drain、`ApplyEvent`/`ApplyIcon`、过期结果拒绝和 ImageOp 剪枝规则不变。
- Layout 继续无 IO,所有尺寸、颜色、圆角、间距、控件顺序、可见文案和语义标签不变。
5. 复用 T-608 适配器契约、T-607 图标事件测试和既有 shell 测试;双端分别重复运行 UI 测试,再执行完整隔离 workspace 构建闸门。测试只在发现现有保护面无法观察拆分不变量时补充,不得为新文件布局复制 ViewModel 纯逻辑测试。
6. 同步架构、路由和编码规则,记录双端 shell 文件职责、同 package 边界和未来 UI 变更的落点;审核追踪与当前状态在任务完成时更新。
## 验收要点
- modern 与 Win7 均存在 `shell.go`、`shell_header.go`、`shell_catalog.go`、`shell_detail.go`、`shell_style.go`,职责镜像且仍属于各自 `gio` package;允许版本特有声明只出现在一端。
- 两个 `shell.go` 只保留 AppShell 状态/生命周期与根编排,不再定义 catalog row/icon、detail 或 panel/style helper;原声明清单中的每个符号在各自 package 内恰有一个定义。
- `NewAppShell`、`NewTheme`、`Layout`、`SetItems`、`ApplyIcon` 等既有可调用 API、签名和接收者不变;不新增跨 workspace import、共享 Gio package 或兼容 shim。
- `git diff` 可解释为声明移动、import 收敛和必要文档同步;无颜色/尺寸/文案、控件顺序、事件 drain、列表/selection、图标或快照语义变化。
- modern Go 1.25.0 与 Win7 Go 1.20.14 下 `go test -count=10 ./ui/gio` 分别通过;T-608 的 Editor/Clickable、AppID、detail context、500 项 viewport、controls lifecycle 和空状态矩阵保持全绿。
- 双端图标事件/过期拒绝测试保持通过;完整 `./scripts/verify_phase0.ps1` 通过,继续证明 Gio v0.10.1/v0.6.0 隔离及 Windows amd64 双目标可构建。
- `python scripts/validate_agent_context.py`、`python scripts/validate_harness_governance.py` 与提交前差异检查通过。
## 边界(不改什么)
- 不增加下载、安装、设置、授权或其他新视图,不改变任何可见 UI、交互、可访问文案、窗口尺寸或主题。
- 不拆分 `AppShell` 为多个状态对象,不重写布局算法,不调整事件处理、列表虚拟化、控件生命周期、图标生命周期或 `VisibleItems` generation 契约。
- 不提取跨 modern/win7 的 Gio 共享层,不让任一 workspace import 另一端,不升级或统一 Go/Gio 版本。
- 不修改 core/domain/application、平台层、命令入口、协议或 Schema,不恢复 T-302,不顺带处理 `ErrIconCacheUnsafe` 诊断/quarantine。
- 不以文件行数为目标制造过度碎片;验收以职责边界和行为不变为准,不设机械最大行数。
- 不修改、提交或删除用户的 `soft_quay.code-workspace`。
## 协作约束
- 按仓库当前规则由单 Agent 串行执行,不启动子 Agent。
- 本任务只允许修改 frontmatter 中的 `write_paths`;若拆分暴露必须改行为才能通过的既有缺陷,停止并记录,不得在 T-610 内扩边修复。
- T-610 完成、完整验证并提交前,不落成或领取 unsafe cache 诊断、Phase 1 后续整改或 T-302。
## 执行记录
- 2026-07-17:根据 `docs/review/phase2-review.md` 交叉复核定稿的第五优先级维护项落成任务;现有全局最大任务为 T-609,因此取 T-610,依赖已完成的 T-609。
- 2026-07-17:代码图确认 modern `shell.go` 为 959 行、29 个声明,Win7 `shell.go` 为 880 行、25 个声明;两端都把状态/根编排、header、catalog/list、detail 和 style 聚合在单文件,主要差异为 modern 独有的 `layoutCatalog`、`layoutFooter` 与 `actionLabel` 等实现。
- 2026-07-17:冻结为各自 `gio` package 内五文件镜像职责拆分;保留版本特有差异,不共享 Gio 代码、不改变行为,并以 T-607/T-608/T-609 已有事件、适配器和 snapshot 契约作为回归保护面。
- 2026-07-18:在 `agent/codex/T-610` 分支领取任务,基线为 `75b1803564dd95284dc5bc25719ccdb5b3e55274`;保持单 Agent 串行执行。
- 2026-07-18:基线 `./init.ps1` 通过,包含治理/上下文/边界/依赖版本检查、Go 1.20.14 core vet/test、modern Go 1.25 与 Win7 Go 1.20.14 的 UI/平台测试和 Windows amd64 构建。
- 2026-07-18:modern 与 Win7 各自新增 `shell_header.go`、`shell_catalog.go`、`shell_detail.go`、`shell_style.go`;根 `shell.go` 分别从 959/880 行收敛到 186/190 行,只保留 AppShell 状态/构造、SetItems/ApplyIcon 生命周期、根 Layout 与 drainInput。所有函数体按完整声明机械移动并由 `gofmt` 收敛 import,未改名或调整调用顺序。
- 2026-07-18:重新索引代码图后确认拆分前后的声明总数均为 54,每个 qualified name 恰有一个定义;modern 的 Layout 仍直接调用 drainInput/header/content/footer,Win7 仍直接调用 drainInput/header/content,二阶 catalog/detail/style 调用链保持不变。
- 2026-07-18:modern Go 1.25.0 与 Win7 Go 1.20.14 的 `go test -count=10 ./ui/gio` 分别通过;T-608 适配器矩阵、T-607 图标事件/过期拒绝及既有 shell 测试无需修改。
- 2026-07-18:完整 `./scripts/verify_phase0.ps1` 通过,覆盖治理/上下文/链接/任务校验、core 边界与 Go/Gio pin、Go 1.20.14 core vet/test、modern/Win7 UI 与平台测试及 Windows amd64 双目标构建;路由、架构、编码规则、审核追踪和当前状态已同步。
- 2026-07-18:提交前 modern/Win7 `go vet ./ui/gio`、`validate_agent_context.py`、`validate_harness_governance.py` 与 `git diff --check` 均通过;工作区唯一范围外文件仍是用户未跟踪的 `soft_quay.code-workspace`,未修改或暂存。