--- id: T-003 title: 建立 Gio 空窗口 AppShell 与平台层 stub phase: 0 deps: [T-001] status: DONE created: 2026-07-16 issue: null context_ref: 0e20dd76b215015030c184436fb216f34e9b27e2 claim_branch: null work_branch: agent/codex/T-003 write_paths: - docs/tasks/T-003.md - app-modern/cmd/softbox/ - app-modern/ui/gio/ - app-modern/platform/windows/ - app-win7/cmd/softbox/ - app-win7/ui/gio/ - app-win7/platform/windows/ - scripts/check_core_boundaries.py - go.work.sum - docs/current-state.md --- ## 问题 / 背景 两个应用模块当前只有控制台占位入口,尚不能打开桌面窗口;平台层也只有空包。需要建立 modern 与 Win7 各自适配 Gio 版本的最小 AppShell,并为后续 Windows 能力注入提供可在非 Windows 环境编译的接口/stub。 ## 方案 1. modern 使用 Gio v0.10.1 API,win7 使用 Gio v0.6.0 API,各自建立窗口事件循环和 `ui/gio.AppShell`。 2. AppShell 只展示高对比标题、版本标识与占位说明,使用 8dp 间距节奏,不做业务 IO、动画或交互。 3. 两个 `platform/windows` 包定义最小 `Platform` 接口,分别提供 Windows 实现与 `!windows` stub。 4. 新增离线边界检查脚本,通过 `go list -json` 拒绝 core 直接 import Gio、Windows 专属包或 SQLite。 5. 生成并提交两个 app 模块所需的依赖校验文件。 ## 验收要点 - modern 与 win7 两个 Windows amd64 目标都能编译为 GUI EXE。 - 两个窗口均有 AppShell 骨架;Win7 版明确显示 Legacy 标识。 - Gio 代码只位于 `ui/gio` 与 `cmd` 装配层;Layout 不包含磁盘、网络或哈希操作。 - `platform/windows` 在 Windows 有实现,在非 Windows 有 stub,包级测试可在当前环境运行。 - `python scripts/check_core_boundaries.py` 与 `--self-test` 通过,并能检测禁止依赖前缀。 - core vet/test 与治理检查继续通过。 ## 边界(不改什么) - 不实现软件列表、搜索、下载队列或其他业务页面。 - 不让 modern 与 win7 共享 Gio 控件代码;只保持布局语义一致。 - 不新增 Windows API 调用或第三方依赖。 - 不引入装饰动画、图标或品牌资产。 ## 协作约束 未启用 Gitea;本任务在 `agent/codex/T-003` 分支串行执行。UI 采用 `ui-ux-pro-max` 的工具型桌面应用原则,但以 Gio/Windows 任务边界和仓库架构为最高约束。 ## 执行记录 - 2026-07-16:modern 使用 Gio v0.10.1、win7 使用 Gio v0.6.0 建立各自窗口事件循环与 `AppShell`;两个版本共享相同布局语义,Win7 标题和页脚明确显示 Legacy。 - 2026-07-16:依据 `ui-ux-pro-max` 的工具型产品建议,采用高对比语义色、16sp 正文、8dp 间距节奏与 44dp 交互基线;本任务没有交互控件,因此不添加动画、图标或装饰效果。 - 2026-07-16:两个 `platform/windows` 包建立 `Platform` 接口、Windows 实现与 `!windows` stub,并添加包级契约测试。 - 2026-07-16:新增 `scripts/check_core_boundaries.py`,通过 `go list -json` 检查 core 的普通/测试 import,拒绝 Gio、Windows、SQLite 与 app 反向依赖;`--self-test` 验证前缀匹配器。 - 2026-07-16:`go mod tidy` 会忽略 workspace 本地替换并尝试下载 `softbox.local/core`;为避免把 `replace ../core` 写入 go.mod,保留 go.work 作为唯一替换源,由实际 test/build 生成 `go.work.sum`。 - 验证通过:modern Go 1.25.0 执行 `go vet ./...`、UI/platform 测试与 Windows amd64 构建。 - 验证通过:win7 Go 1.20.14 执行 `go vet ./...`、UI/platform 测试与 Windows amd64 构建。 - 验证通过:两个 EXE 在当前 Windows 环境启动后保持运行,随后由 smoke 脚本关闭。 - 验证通过:`python scripts/check_core_boundaries.py --self-test`、`python scripts/check_core_boundaries.py`、core vet/test 与治理检查。