P0.U-workspace-io-actions · ADR-12 followup #13 · 左 Dock §Workspace 6 操作 UI 入口
Worker:TBD · 部门:前端 (frontend_vue3) 预计:0.5d · 优先级:P1 · 状态:dispatched 隔离:文件隔离(drawers/left/Workspace/ 全新 + store IO actions 扩展 · 与 #2 dashboard/ 零重叠)
🔍 触发与解锁链
- 触发:用户 2026-05-29 反馈 #2 prompt 漏覆盖左 Dock §Workspace pane + 6 操作 UI 入口(ref §六)· 17:10 拍板 start
- 前置就位:Workspace + WorkspacePreset types(
9fc31c4)+ xiTestWorkspaceStore 骨架 + LeftDock pane 注册模式(6050959)+ Drawer 挂载模式(77b7a50) - 本任务 zombie 后解锁:用户首次看到完整左 Dock §Workspace pane · 6 操作按钮可点击 · 配合 #2(等其 zombie)形成 Workspace 完整 IO 闭环
- 与 #2 协作边界:本任务 actions(saveWorkspace/loadWorkspace/exportWorkspace/...)所需的 widgets[] + gridLayout 持久化字段由 #2 落地 · 本任务的 actions 可先实施(用空数组占位 · #2 zombie 后字段自然填充)
任务定义(基于 ref/ADR-AIOS-XiTest-realtime.md §五+§六)
按 ref 文件 §五 Left Dock 总结构(8 段:Workspace/Session/Engine/Measurements/Recordings/Snapshots/Validation/Task Flow · 本任务只做 §Workspace 一段)+ §六 Workspace 功能定义(Save/Load/Export/Share/Clone/Lock 6 操作)落地 UI 入口 + store actions。
完整 prompt(直接复制粘贴 worker 终端)
[U-thread] P0.U-workspace-io-actions
[部门] 前端 (frontend_vue3) · 推荐 skill: vuejs-typescript-best-practices
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/
[Occupies] P0.K2-global-stores(写 xiTestWorkspaceStore) · P0.K-shared-types(read · 复用 Workspace/WorkspacePreset)· P4.K1-page-layout(read · stages/xitest/index.vue 注册新 pane)
[隔离] 文件隔离 · 仅写:
- frontend_vue3/src/stages/xitest/drawers/left/Workspace/*(全新 · WorkspaceList.vue + 6 操作按钮)
- frontend_vue3/src/stores/xiTestWorkspaceStore.ts(扩展 6 IO actions · 不破坏 #1/#3 已落字段)
- frontend_vue3/src/stages/xitest/index.vue(注册 xtest-workspace LeftDock pane · 与 xtest-measurements 同模式)
- frontend_vue3/src/stages/xitest/__tests__/*(新增 2 个测试文件)
严禁动 stages/xitest/dashboard/*(#2 写权)· 严禁动 drawers/left/Measurements/*(#3 已落)· 严禁动 inspector/*(#4 已落)
[优先级] P1 · 0.5d · ADR-12 followup #13 · 补 ref §六 漏项
[ADR] docs/08-implementation/40-aios/ADR/ADR-AIOS-12-xitest-realtime-arch.md(主 ADR)
[ref 详细设计](绝对路径 · 必读 §五+§六)
d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ref/ADR-AIOS-XiTest-realtime.md
[业务行为契约引用]
本任务是 UI 入口 + store actions stub · widget 业务行为 + 完整 IO 持久化(IndexedDB)留 #11 P0.U-bottom-dock-storage-engine
本期实施级别:Save/Load/Clone localStorage 落地 · Export 序列化 JSON 下载 · Share/Lock 仅 store flag(后端 IO 留 Phase 3)
[参考文档](绝对路径)
- d:/work/25_claude/workspace/AlgoDepartment/04_development/frontend_vue3/src/types/dashboard-widget.ts(Workspace + WorkspacePreset · #1 落地)
- d:/work/25_claude/workspace/AlgoDepartment/04_development/frontend_vue3/src/stores/xiTestWorkspaceStore.ts(#1 骨架 · 本任务扩展 · 严格仿写已有 actions 风格)
- d:/work/25_claude/workspace/AlgoDepartment/04_development/frontend_vue3/src/stages/xitest/drawers/left/Measurements/MeasurementsList.vue(#3 标本 · 严格仿写 LeftDock pane 模式)
- d:/work/25_claude/workspace/AlgoDepartment/04_development/frontend_vue3/src/stages/xitest/drawers/right/Inspector/InspectorDrawer.vue(#4 标本 · drawer 模板)
- d:/work/25_claude/workspace/AlgoDepartment/04_development/frontend_vue3/src/stages/xitest/index.vue(#3+#4 已注册 xtest-measurements/xtest-inspector · 本任务再加 xtest-workspace)
- d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/done/P0.U-measurement-node-registry--6050959.md(同部门标本 · 8 段 prompt 格式 · LeftDock pane 模式)
【背景】
ref §六 Workspace 6 操作(Save/Load/Export/Share/Clone/Lock)是 widget workspace 完整 IO 闭环的入口 · 漏自 #2 prompt(scope 为主画布骨架 + 4 套 Preset)· 本任务 0.5d 短平快补齐左 Dock §Workspace pane + 按钮 UI + store actions stub · 后端持久化(IndexedDB)留 Phase 3 #11。
【执行步骤】
Step 1 · read 已有基础(只读 · 严格仿写)
- read types/dashboard-widget.ts(Workspace + WorkspacePreset 字段)
- read stores/xiTestWorkspaceStore.ts(#1 骨架 + #3 加的 measurementNodes/addMeasurementNode/addWidget · 仿写风格扩展 6 IO actions)
- read drawers/left/Measurements/MeasurementsList.vue(#3 LeftDock pane 模式 · 仿写)
- read drawers/right/Inspector/InspectorDrawer.vue(#4 drawer 模板 · 仿写挂载点)
- read stages/xitest/index.vue(#3+#4 已注册 pane 模式 · 本任务在此追加 xtest-workspace 注册)
Step 2 · 扩展 xiTestWorkspaceStore actions(6 操作 + Lock state)
- saveWorkspace(name: string):序列化当前 widgets[] + gridLayout + 当前 preset 为 Workspace 对象 · 写 localStorage 'xitest:workspaces:<name>'
- loadWorkspace(name: string):读 localStorage · 反序列化为 Workspace · 替换当前 state
- exportWorkspace():序列化为 JSON Blob · 触发浏览器下载(<workspace-name>.xiworkspace.json)
- shareWorkspace():序列化 → btoa 压缩 → 生成 share URL · 复制到剪贴板(navigator.clipboard.writeText)· 后端服务留 Phase 3
- cloneWorkspace(sourceName: string, newName: string):read sourceName · 深拷贝 · saveWorkspace(newName)
- lockWorkspace(locked: boolean):store 加 isWorkspaceLocked: boolean state · DashboardCanvas 读此 flag 禁用 drag/resize(#2 留 TODO 引用)
Step 3 · 新建 stages/xitest/drawers/left/Workspace/(全新)
- WorkspaceList.vue(主组件 · 仿 MeasurementsList.vue 风格)
- 顶部:6 操作按钮(Save/Load/Export/Share/Clone/Lock)· 用 emoji 图标 + tooltip
- 中部:已保存 workspace 列表(从 localStorage 读 · 显示名称 + 创建时间)· 点击触发 loadWorkspace
- 底部:输入框 + Save 按钮(创建新 workspace · 询问名称)
- 同 drawers/left/Measurements 一样有 index.ts 桶文件
Step 4 · 新建 drawers/left/Workspace/WorkspaceDrawer.vue(若需要)+ 在 stages/xitest/index.vue 注册
- 仿照 #3 xtest-measurements LeftDock pane 注册模式
- 加 paneId: 'xtest-workspace' · 图标 emoji 或 SVG · 排序在 §Measurements 之前(ref §五 Workspace 是第 1 段)
Step 5 · 单元测试
- workspace-io-actions.test.ts(13+ 用例 · 6 actions × 1-2 用例 + Lock state + localStorage 持久化 + clone 深拷贝独立性)
- workspace-list.test.ts(8+ 用例 · 6 按钮渲染 + workspace 列表渲染 + 点击事件 + Save 流程 + Lock 视觉反馈)
- 目标 test:unit 356/3 → ≥ 377/3(+21 用例)
Step 6 · 验收
- npm run typecheck → ✓ exit 0
- npm run build → ✓ 零错误
- npm run test:unit → ≥ 377/3
- 手动浏览器:打开 /xitest?mode=realtime → 左 Dock 看到 §Workspace pane(在 §Measurements 之前)→ 点 Save 输入名称保存 → reload 页面 → Load 列表里出现该 workspace → 点击恢复 · Lock 按钮切换 isWorkspaceLocked
【验收】
- typecheck/build 全绿 · test:unit ≥ 377/3
- xiTestWorkspaceStore 加 6 IO actions(saveWorkspace/loadWorkspace/exportWorkspace/shareWorkspace/cloneWorkspace/lockWorkspace)+ isWorkspaceLocked state
- WorkspaceList.vue + WorkspaceDrawer.vue + index.ts(drawers/left/Workspace/* 全新)
- xtest-workspace LeftDock pane 注册(stages/xitest/index.vue)· 不破坏现有 5 个 pane(menu/measurements/inspector + 原 P4 已有)
- localStorage 'xitest:workspaces:<name>' 真持久化 · reload 后数据保留
- Lock state 暴露到 DashboardCanvas(#2 留 TODO · 本任务仅暴露 store flag · 不动 #2 写权)
**端到端真值** ⭐(.clinerules v1.8 §业务行为契约必填段强制要求)
- e2e 真值:浏览器打开 /xitest?mode=realtime · 左 Dock §Workspace pane 可见 · 点 Save 按钮输入"my-test-1" → localStorage 看到 'xitest:workspaces:my-test-1' 项 → reload 页面 → Load 列表里 my-test-1 可见 · 点击恢复(widgets[] 由 #2 实施 · 本任务 console.log 验证 action 调用即可)· 点 Export 触发文件下载(JSON 结构含 widgets/gridLayout/preset 字段)
- 自查清单:
- [ ] 输入/输出契约:Workspace JSON schema(name/createdAt/widgets[]/gridLayout/preset/locked 字段单位明确)
- [ ] 收敛判据:saveWorkspace 后 localStorage 立即可读 · loadWorkspace 后 store state 立即更新 · 6 操作各 1 truthy assertion
- [ ] 失败回退 5 类:① localStorage quota 满 → catch + 提示用户 ② name 重复 → 询问覆盖 ③ JSON 反序列化失败 → 提示 corrupt + 跳过 ④ Share clipboard 不可用(http)→ fallback 显示 URL 文本 ⑤ Export 浏览器拒绝下载 → catch + 提示
- [ ] 用户操作流 5 步:打开左 Dock §Workspace → 输入名称 → 点 Save → 看到列表新增 → 点 Load 恢复
- [ ] 端到端 e2e:6 actions 各跑 1 vitest + 浏览器手动验证 reload 后持久化
【commit】
- subject:`feat(P0.U-workspace-io-actions/workspace): LeftDock §Workspace pane + 6 IO actions · ADR-12 followup #13`
- trailer:`[step=6/6] [pid=P0] [uid=U-workspace-io-actions] [occupies=P0.K2+P0.K-shared-types(read)+P4.K1] [files=stages/xitest/drawers/left/Workspace/*+stores/xiTestWorkspaceStore.ts+stages/xitest/index.vue+tests/*]`
【禁止】
1. ❌ 不动 stages/xitest/dashboard/*(#2 P0.U-widget-workspace-framework 写权 · 本任务仅引用 store)
2. ❌ 不动 drawers/left/Measurements/*(#3 写权 · 仅 read 仿写)
3. ❌ 不动 inspector/*(#4 写权)
4. ❌ 不实施 IndexedDB / 后端 IO(留 Phase 3 #11 P0.U-bottom-dock-storage-engine · 本任务仅 localStorage)
5. ❌ 不实施 Share 后端服务(仅 clipboard URL · 后端服务留下季度 ADR-13+)
6. ❌ 不嵌入完整 Vue SFC 骨架(.clinerules v1.6 §prompt 内容硬约束)· 严格仿写 #3 #4 风格自决
7. ❌ 不验"typecheck 全绿就 commit"——必须按业务行为契约 5 项自查 · 浏览器手动验证 6 操作 + reload 持久化
解锁链(本任务 zombie 后)
- ✅ 用户首次看到完整左 Dock §Workspace pane(6 操作按钮 UI + drawer)
- ✅ #2 widget-workspace-framework 实施 DashboardCanvas 时直接读 isWorkspaceLocked 禁用 drag/resize · 形成 Lock 闭环
- ⏳ Phase 3 #11 P0.U-bottom-dock-storage-engine 时升级 localStorage → IndexedDB + 后端 Share Service
风险评估
| 风险 | 缓解 |
|---|---|
| ⚠️ #2 widget-workspace-framework running · 同时改 xiTestWorkspaceStore.ts 的 widgets[] 字段冲突 | 本任务只加 isWorkspaceLocked + 6 IO actions · 不改 widgets[]/gridLayout 字段(由 #2 写)· git merge 时 actions/state 段独立 · 0 冲突 |
| ⚠️ localStorage 容量限制(5MB)· 多 workspace 大数据爆 | 本期不解决 · workspaces 列表只显示前 20 个 + Phase 3 #11 升级 IndexedDB |
| ⚠️ Share clipboard 不可用(http 环境) | fallback 显示完整 URL 文本(用户手动复制)· 5 类失败回退含此项 |
历史
| 时间 | 事件 | hash |
|---|---|---|
| 2026-05-29 17:10 | dispatched · 用户拍板补 ref §六 漏项 · 0.5d 短平快 · 与 #2 写权 0 重叠 | — |
| 2026-05-29 18:35 | ✅ zombie · 主画布全宽修复(flex: 1; min-width: 0)· ⚠️ commit 描述偏 #2 主画布 scope · 用户指令 stop | 956fdd0 |