跳转至

P3.A25.F2-xitune-subgraphs-dock · XiTune 左 Dock 第 6 项 SubgraphsDock(子图列表 + 单击切 active + 双击进入子图)

Worker:ClaudeA · 部门:前端 P3-xitune · 预计:0.7d · 优先级:P0 · 状态:dispatched · isolation:🧵 file(同 worktree 同 branch · 与 F1 chain-mini-bar 子图识别文件正交可并行)

🔍 触发与解锁链

触发:用户 2026-06-15 13:42 拍板 accept ADR-AIOS-25(supersedes ADR-23 范围迁移)· 13:50 拍板双连 start P3.A25.F1 + start P3.A25.F2(F1+F2 文件正交独立可起手)。

用户原话(verbatim · ADR-25 §1.1 范围纠正):

"我说的是在 xitune 中无法显示和打开 xilink 工程中的子图 · mini node 的结构都是针对 xitune stage 的 · 你为何去改 xilink 呢"

架构契约(ADR-25 §3.2 ① 输入/输出契约 · 业务契约 5 必填段): - 输入:linkStore.subgraphDefs(子图定义)+ linkStore.modules(查 instanceCount 实例化次数) - 输出:左 Dock 第 6 项 📦 子图列表 drawer · 列表项含 name + moduleCount + instanceCount + hasError 标记 · 单击 → 切 activeInstanceId · 双击 → emit 'open-subgraph'(F3 接管) - 性能基线:dock 加载 ≤ 50ms · 列表项 ≤ 20 时渲染 ≤ 16ms · instanceCount 实时 reactive 同步 100% - 5 类失败回退(ADR-25 §3.2 ③):subgraphDefs 空 → 显示空占位 / instanceCount=0 → 灰显副字 / instanceCount>1 → 弹下拉选 instance / hasError → ⚠️ 红字禁用单击 / dock 切换 → 复用现有 drawer 体系无特殊处理

解锁链(本任务 zombie 后): - ✅ xitune 左 dock 第 6 项 📦 子图列表 drawer 上线 · 用户三件套盲区第 2 件解决(子图列表入口可见) - ⏳ F4 e2e 部分依赖(F2 zombie 不直接解锁 F4 · 需 F1+F3 也 zombie · 三齐后 F4 ready)

任务定义(基于 ADR-25 §3.2)

子任务 ① · useSubgraphList composable(0.2d)

Step 1.1:NEW frontend_vue3/src/stages/xitune/composables/useSubgraphList.ts: - 接口:useSubgraphList() → reactive Ref<SubgraphListItem[]> - 内部:遍历 linkStore.subgraphDefs · 派生 SubgraphListItem(defId / name / moduleCount = nodes.length / instanceCount = linkStore.modules 中 subgraphDefId === defId 的数量 / hasError = ADR-08-R1 R1.5 dirty 标记) - watch linkStore.modules → instanceCount 实时 reactive 同步(ADR-25 §3.2 ② 收敛判据 3) - 排序:按 name 字典序 · 异常 hasError=true 项排末尾

子任务 ② · SubgraphListItem 列表项组件(0.15d)

Step 2.1:NEW frontend_vue3/src/stages/xitune/drawers/SubgraphListItem.vue: - props:{ item: SubgraphListItem; isActive: boolean } - emit:click(单击)· dblclick(双击) - 模板:头部 📦 + name + 副字 ${moduleCount}个 · 主链路使用 ${instanceCount}次(instanceCount=0 显示"未在主链路使用"灰字) - hasError=true 状态:⚠️ + 红字"定义错误" + 禁用单击(@click.stop + 不 emit) - 视觉风格:仿写 ProjectDock 列表项(头部 + 副字 + 高亮 active)· 不用 svg

子任务 ③ · SubgraphsDock 主组件(0.2d)

Step 3.1:NEW frontend_vue3/src/stages/xitune/drawers/SubgraphsDock.vue: - 头部:<div class="dock-header">📦 子图列表</div>(仿 ProjectDock 风格) - 列表:<SubgraphListItem v-for="item in subgraphList" ...> - 空占位:subgraphList.length === 0 → "暂无子图 · 请在 XiLink 创建" - 单击事件 onSubgraphClick(item): - instanceCount === 1 → 直接切 activeInstanceId(查 linkStore.modules 第一个 subgraphDefId === item.defId 的 instance) - instanceCount > 1 → 弹下拉菜单(el-dropdown 选 instance#1/#2/...)+ 用户选后切 activeInstanceId - instanceCount === 0 → 不响应(灰显) - 双击事件 onSubgraphDblClick(item):emit 'open-subgraph' { defId, name }(F3 实施时接管 enterSubgraph)

子任务 ④ · LEFT_DOCK 注册第 6 项(0.05d)

Step 4.1:更新 frontend_vue3/src/stages/xitune/index.vue: - LEFT_DOCK 数组(line 440-520 范围)末尾追加第 6 项:{ key: 'xt-subgraph', icon: '📦', tip: '子图列表 · 查看 xilink 工程定义的子图', component: SubgraphsDock } - 加 import SubgraphsDock from './drawers/SubgraphsDock.vue' - ⚠️ 不动现有 5 项 · 不动其他 drawer 注册逻辑 · append-only 第 6 项

Step 4.2:onSubgraphsDockOpenSubgraph 监听器(SubgraphsDock 'open-subgraph' emit)· 本 F2 占位 console.log(F3 实装时替换为 enterSubgraph 调用)

子任务 ⑤ · 测试(0.1d)

Step 5.1:vitest 加 ≥ 5 case: - useSubgraphList:linkStore.subgraphDefs 含 2 子图 + linkStore.modules 含 1 EQ_A 实例 + 0 EQ_B 实例 → list 含 2 项 · instanceCount 分别 1/0 - useSubgraphList:linkStore.modules 增加 EQ_A 第 2 实例 → list[0].instanceCount reactive 更新到 2 - SubgraphListItem:hasError=true 渲染 ⚠️ 红字 + 禁用单击 emit - SubgraphsDock:subgraphList 空 → 显示"暂无子图 · 请在 XiLink 创建"占位 - SubgraphsDock:instanceCount=1 单击 → 切 activeInstanceId · instanceCount=0 单击不响应

Step 5.2:vue-tsc + build + 全测试基线零回归

完整 prompt(直接复制粘贴 ClaudeA 终端)

[U-thread] P3.A25.F2-xitune-subgraphs-dock · ADR-25 §3.2 SubgraphsDock 左 dock 第 6 项(子图列表 + 单击切 active + 双击进入)
[部门] 前端 P3-xitune
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/
[Occupies] P3.K-shared-xitune-drawers
[优先级] P0(0.7d · 与 F1 chain-mini-bar 文件正交可并行 · 解锁用户三件套盲区第 2 件)
[ADR] docs/08-implementation/40-aios/ADR/ADR-AIOS-25-xitune-load-xilink-subgraph.md(必读 §3.2 + §1.4 边界铁律 + §1.2 ADR-23 失败教训 + §9.1 grep 现状)
[isolation] file(同 worktree 同 branch · 与 F1 chain-mini-bar 文件正交并行)

[参考文档绝对路径]
  - 业务契约:ADR-25 §3.2 完整 5 必填段(① SubgraphListItem + LEFT_DOCK 注册接口 / ② dock ≤50ms + 列表 ≤16ms / ③ 5 类失败回退 / ④ 5 步操作流 / ⑤ playwright e2e 模板)
  - 用户 2026-06-15 11:30 verbatim 纠正(ADR-25 §1.1):"我说的是在 xitune 中无法显示和打开 xilink 工程中的子图 · 你为何去改 xilink 呢"
  - 用户 2026-06-15 12:00 拍板方案 1(ADR-25 §1.1):"先起 ADR-25 + 调研 xitune 现状 · 复用价值低则全 revert"
  - 教训承接标本(必读避坑):
    * ADR-25 §1.2 失败教训表(ADR-23 SubgraphDockPanel 折叠面板风格在 xitune drawer 体系零复用)
    * ADR-25 §9.1 起 ADR 前必须 grep 目标 stage 现状(本 F2 Step 0 强制 read ProjectDock + FlowReadonlyDock 仿写)
    * commit 27ec16d revert(2026-06-15 12:11 · -1792/+56 · ADR-23 三 zombie 全部回滚)
  - 范式 commits(worker 必读 · 强制 read 全文对齐格式):
    * a5b52de P1.A21.F1 dock-host-generalize(同 ClaudeA 前端 · isolation: file · 8 段 prompt + commit 七元组标本)
    * 4ed8699 P1.A21.F2 fft-scope-controls-enhance(ClaudeA append-only 控件增强 · 文件正交并行案例)
  - 现状参考(Step 0 强制 read · 仿写视觉风格):
    * frontend_vue3/src/stages/xitune/drawers/FlowReadonlyDock.vue(单层 SVG 流图 · 头部 + 内容布局参考)
    * frontend_vue3/src/stages/xitune/drawers/ProjectDock.vue(若存在 · 列表 drawer 标本)· 否则 read 任意现有 12 drawer 之一确认头部 + 列表布局风格
    * frontend_vue3/src/stages/xitune/index.vue(line 440-520 LEFT_DOCK 数组 · 现有 5 项注册结构 · 本 F2 追加第 6 项)
    * frontend_vue3/src/stores/linkStore.ts(subgraphDefs API + modules.subgraphDefId 真签名)
  - 三层分工:ADR-07 §1.3.4(L3 前端零数学 · 本任务纯 UI 渲染 + computed 派生 + reactive · 不做 DSP)

[文件正交策略](.clinerules §任务隔离类型分配准则 v1.4):
  isolation: file · 同 worktree 同 branch · 与 F1 文件正交并行
  本 F2 文件:frontend_vue3/src/stages/xitune/drawers/{SubgraphsDock.vue + SubgraphListItem.vue} + composables/useSubgraphList.ts + xitune/index.vue (仅 LEFT_DOCK 数组追加第 6 项 · 不动其他)
  F1 文件:xitune/index.vue (line 7-58 chain-mini-bar 模板 + 双击 stub) + composables/useChainMiniNodes.ts
  ⚠️ F1 与 F2 唯一交叉点:xitune/index.vue · 但 F2 仅追加 LEFT_DOCK 第 6 项(line 440-520 末尾)+ import 一行 · F1 仅改 line 7-58 模板 + onMiniNodeDoubleClick 函数 · 行号正交不冲突
  ⚠️ 若 F1 已先 commit 改了 xitune/index.vue,F2 在 F1 基础上 git pull rebase 追加 LEFT_DOCK 第 6 项即可(merge 冲突概率极低)

【背景】
  用户 2026-06-15 11:30 verbatim 纠正"应改 xitune 不是 xilink" · 12:00 拍板方案 1 · 12:11 revert 27ec16d · 12:12 ADR-25 起草 · 13:42 accept · 13:50 双连 start F1+F2。
  ADR-25 范围严格限定 xitune/ 命名空间(ADR-25 §1.4)· 仅消费 linkStore.subgraphDefs API · 不动 store schema。
  本 F2 解决"xitune 左 dock 没有子图列表入口"的盲区(ADR-25 §1.3 调研结论:xitune 完全不引用 linkStore.subgraphDefs)。
  教训承接:ADR-23 SubgraphDockPanel 折叠面板 + svg 缩略图风格在 xitune 12 drawer 体系零复用 → 本 F2 严格仿写 xitune 现有 drawer 风格(头部 + 列表 + 复用 ProjectDock 视觉)· 不引入 svg 缩略图 / 折叠面板。

【架构关键约束】
  ⚡ 范围铁律(ADR-25 §1.4):本 ADR 仅动 xitune/ 命名空间 · xilink/ 完全不动 · linkStore schema 不动
  🎨 视觉风格仿写 ProjectDock / FlowReadonlyDock:头部 📦 子图列表 + 列表项(name + moduleCount + instanceCount + 高亮 active)· **不引入 svg 缩略图 / 折叠面板**(ADR-23 错误方向 · 已 revert)
  📋 LEFT_DOCK append-only 第 6 项:不动现有 5 项 · 仅追加 { key: 'xt-subgraph', icon: '📦', tip, component: SubgraphsDock }
  📋 单击 → 切 activeInstanceId(instanceCount=1 直接切 / >1 弹下拉 / =0 不响应灰显)
  📋 双击 → emit 'open-subgraph'(F3 接管 · 本 F2 占位 console.log)· **严禁本 F2 实装 enterSubgraph 本体**(那是 F3 范围)
  📋 三层分工(ADR-07 §1.3.4):L3 前端纯 UI 渲染 + computed 派生 + reactive · 不做 DSP 数学
  🚫 严禁动 linkStore.ts schema(仅消费 subgraphDefs + modules.subgraphDefId · 不动 store)
  🚫 严禁与 F1 抢改 xitune/index.vue 同一行号区间(F2 仅追加 LEFT_DOCK 第 6 项 + import 一行)

【执行步骤】
  Step 0 · 文件注入真值核查(强制门槛 · ADR-23 教训承接)
    - read frontend_vue3/src/stages/xitune/drawers/FlowReadonlyDock.vue · 确认 xitune drawer 风格(头部 + 内容)
    - list frontend_vue3/src/stages/xitune/drawers/ · 找到 ProjectDock.vue 或类似列表 drawer · read 仿写视觉
    - read frontend_vue3/src/stages/xitune/index.vue line 440-520 · 确认 LEFT_DOCK 现有 5 项注册结构 + drawer component 加载机制
    - grep "subgraphDefs\|subgraphDefId" frontend_vue3/src/stores/linkStore.ts · 确认 SubgraphDef 接口 + modules.subgraphDefId 真签名
    - 确认 ADR-23 三 zombie 已 revert(commit 27ec16d 在 HEAD 链上 · grep "SubgraphDockPanel" 应 0 命中)
    - 留 commit log:Step 0 五层核查记录

  Step 1 · useSubgraphList composable 0.2d(子任务 ①)
    - NEW frontend_vue3/src/stages/xitune/composables/useSubgraphList.ts
    - 派生 SubgraphListItem[](defId/name/moduleCount/instanceCount/hasError)
    - watch linkStore.modules · instanceCount reactive 同步
    - 排序 name 字典 · hasError 末尾

  Step 2 · SubgraphListItem 组件 0.15d(子任务 ②)
    - NEW drawers/SubgraphListItem.vue
    - props { item, isActive } + emit click/dblclick
    - 模板 📦 + name + 副字 + active 高亮 + hasError 红字禁用

  Step 3 · SubgraphsDock 主组件 0.2d(子任务 ③)
    - NEW drawers/SubgraphsDock.vue
    - 头部 + 列表 v-for + 空占位
    - onSubgraphClick:instanceCount === 1 直接切 / >1 弹 el-dropdown / =0 不响应
    - onSubgraphDblClick:emit 'open-subgraph' { defId, name }

  Step 4 · LEFT_DOCK 注册第 6 项 0.05d(子任务 ④)
    - xitune/index.vue 仅 append:import SubgraphsDock + LEFT_DOCK 数组末尾追加第 6 项
    - onSubgraphsDockOpenSubgraph 占位 console.log(F3 替换 enterSubgraph)
    - ⚠️ 不动现有 5 项注册 · 不动其他逻辑

  Step 5 · 测试 + 类型/构建/测试全绿 0.1d(子任务 ⑤)
    - vitest 加 ≥ 5 case
    - vue-tsc --noEmit 0 errors
    - npm run build 0 errors
    - npm run test 全过(基线 + 5 新增)

  Step 6 · 浏览器实测 + commit
    - 启动 backend(dotnet run)+ frontend(npm run dev)
    - 准备 fixture:xilink 工程含 2 子图(EQ_A 3 modules · EQ_B 2 modules · 主链路 1 EQ_A 实例 · 0 EQ_B 实例)· 切到 xitune
    - 验收点(ADR-25 §3.2 ④ 用户操作流):
      ☐ xitune 左 dock 第 6 项 📦 图标可见(默认收起)
      ☐ 单击 📦 → SubgraphsDock 展开 · 显示 EQ_A(3个 · 主链路使用 1次)+ EQ_B(2个 · 未在主链路使用 灰字)
      ☐ 单击 EQ_A 列表项 → mini-bar 中 📦 EQ_A 节点高亮(active)+ 主区显示该子图实例摘要 placeholder
      ☐ 单击 EQ_B 列表项 → 不响应(instanceCount=0 灰显)
      ☐ 双击 EQ_A 列表项 → console.log "[A25.F2] open-subgraph emit · F3 接管 enterSubgraph"
      ☐ 测试空 fixture(无子图)→ 显示"暂无子图 · 请在 XiLink 创建"占位
    - git add . && git commit -m "feat(xitune/drawers): P3.A25.F2 SubgraphsDock 左 dock 第 6 项(子图列表 + 单击切 active + 双击进入)

      用户 2026-06-15 13:42 拍板 accept ADR-AIOS-25(supersedes ADR-23 范围迁移)· 13:50 双连 start F1+F2。
      F2 本任务(ADR-25 §3.2):
      ① useSubgraphList composable 派生 SubgraphListItem[](name/moduleCount/instanceCount/hasError)+ watch linkStore.modules reactive 同步
      ② SubgraphListItem.vue 组件(头部 + name + 副字 + active 高亮 + hasError 红字禁用)
      ③ SubgraphsDock.vue 主组件(头部 + 列表 + 空占位 + 单击 instanceCount 三分支 + 双击 emit 'open-subgraph')
      ④ xitune/index.vue LEFT_DOCK append-only 第 6 项注册(不动现有 5 项)+ onSubgraphsDockOpenSubgraph 占位 console.log
      ⑤ vitest +5 case · vue-tsc + build 全绿 · 基线零回归

      ADR-23 教训承接:严守 xitune drawer 风格(头部 + 列表 仿 ProjectDock)· 不引入 svg/折叠面板
      与 F1 文件正交并行(F2 仅 xitune/index.vue LEFT_DOCK 数组末尾追加 + 新建 3 文件)

      [step=6/6] [pid=P3] [uid=P3.A25.F2-xitune-subgraphs-dock] [type=fork] [isolation=file]
      [occupies=P3.K-shared-xitune-drawers] [files=4] [ipc=none]
      [adr=ADR-AIOS-25 §3.2 SubgraphsDock 左 dock 第 6 项 + §1.4 边界铁律 + §1.2 ADR-23 失败教训承接]"

【验收】
  ☐ Step 0 文件注入真值核查通过(read FlowReadonlyDock + ProjectDock + xitune/index.vue line 440-520 + grep linkStore subgraphDefs · commit log 留痕)
  ☐ Step 1 useSubgraphList 派生 SubgraphListItem[] 准确 + watch instanceCount reactive 同步
  ☐ Step 2 SubgraphListItem.vue 头部 + 副字 + active 高亮 + hasError 红字禁用
  ☐ Step 3 SubgraphsDock.vue 头部 + 列表 + 空占位 + 单击三分支(=1/>1/=0)+ 双击 emit
  ☐ Step 4 xitune/index.vue LEFT_DOCK 第 6 项注册(不动现有 5 项)· import 一行追加
  ☐ Step 5 vitest +5 case 全过 · vue-tsc + build 0 errors · 全测试基线零回归
  ☐ Step 6 浏览器实测 6 验收点全过(dock icon + 展开列表 + EQ_A 单击高亮 + EQ_B 灰显 + 双击 emit log + 空占位)
  ☐ commit message 含 7 元组 trailer + ADR-25 §3.2 + §1.4 + §1.2 引用

【禁止】
  ❌ 禁止跳过 Step 0 文件注入真值核查(ADR-23 失败根因:未 grep 目标 stage drawer 风格 · ADR-25 §9.1 强制铁律)
  ❌ 禁止动 xilink/ 任何文件(ADR-25 §1.4 范围铁律)
  ❌ 禁止动 linkStore.ts schema(仅消费 subgraphDefs + modules.subgraphDefId · 不动 store)
  ❌ 禁止引入 svg 缩略图 / 折叠面板风格(ADR-23 错误方向 · 已 revert · 严守 xitune drawer 文字+列表风格)
  ❌ 禁止超前实施 F3 范围(currentSubgraphId state / 面包屑 / 嵌套 mini-bar / enterSubgraph 实装 · 那是 F3 fork 范围)
  ❌ 禁止与 F1 抢改 xitune/index.vue 同一行号区间(F2 仅追加 LEFT_DOCK 第 6 项 + import 一行 · F1 改 line 7-58 模板 + onMiniNodeDoubleClick · 错开)
  ❌ 禁止破坏现有 5 项 LEFT_DOCK drawer 注册(LEFT 5 项 + RIGHT 7 项共 12 drawer 体系不动)
  ❌ 禁止跳过 vitest +5 case(验收硬门槛)
  ❌ 禁止 commit 缺三元组 trailer(.clinerules v2.0 铁律)
  ❌ 禁止嵌入完整 SFC > 60 行 / TS interface > 5 行(.clinerules v2.0)· composable 拆独立 ts + 列表项拆 child component

解锁链(本任务 zombie 后)

  • ✅ xitune 左 dock 第 6 项 📦 子图列表 drawer 上线 · 用户三件套盲区第 2 件解决(子图列表入口可见)
  • ✅ 单击 → 切 activeInstanceId · 双击 → emit 'open-subgraph'(F3 实施时接管为 enterSubgraph 调用)
  • ⏳ F4 e2e 部分依赖(F2 zombie 不直接解锁 F4 · 需 F1+F3 也 zombie · 三齐后 F4 ready · ClaudeC 0.5d)
  • 🔥 F1+F2 双 zombie → ClaudeA 接 F3(blocked-by-F1 解除 · 1.0d 实装 enterSubgraph + 面包屑 + 嵌套 mini-bar + F1+F2 双击接管)

风险评估

风险 缓解
linkStore.subgraphDefs schema 与 ADR-25 §3.2 假设不一致(SubgraphDef 字段名 / nodes 类型) Step 0 强制 grep + read linkStore.ts 真签名 · 不猜 · 若实际字段不同则 fork 内适配派生(append-only)· ADR-25 §5 风险 1 已备案
ADR-08-R1 R1.5 dirty 标记字段实际不存在(hasError 派生失败) Step 0 grep "dirty|hasError" linkStore + subgraphStore 确认 · 若缺则 hasError 始终 false(回退方案 · 不影响主流程)
xitune drawer 12 项体系实际不是 component 注入式(LEFT_DOCK 配置可能用 lazy 路由) Step 0 read xitune/index.vue line 440-520 · 仿写现有 5 项注册结构 · 若用 defineAsyncComponent 则 SubgraphsDock 也用
与 F1 同时改 xitune/index.vue 引发 git 冲突 F2 仅追加 LEFT_DOCK 数组末尾 + import 一行(行号 line 440-520 末尾)· F1 改 line 7-58 模板 + onMiniNodeDoubleClick(行号正交)· 若并行 commit 推到同一 branch 用 git rebase 解(冲突概率极低 · 已识别)
el-dropdown(instanceCount>1 弹下拉)与 xitune 现有组件库(可能用 element-plus / naive-ui)不一致 Step 0 grep "el-dropdown|n-dropdown" 确认现有组件库 · 仿写现有用法 · 若都没用则用原生 v-if + 列表
ProjectDock 实际不存在(xitune drawer 体系可能用其他命名) Step 0 list drawers/ 目录 · 选任意现有列表式 drawer 仿写 · 若 12 drawer 都是非列表风格则参考 FlowReadonlyDock 头部 + 自定义列表布局
ClaudeA 排队膨胀(本 F2 0.7d + F1 0.5d + F3 1.0d + 后续 ADR-21-R1 4 hotfix 3.8d 共 6.0d 串行) F1+F2 文件正交可并行(实际工时 max(0.5, 0.7) = 0.7d)· F3 接 F1+F2 后串行 · F4 e2e ClaudeC · ADR-21-R1 hotfix 排队后接力
用户期望"双击进入新 doc tab"(ADR-23 设计) vs 本 ADR"嵌套展示+面包屑" 用户已 2026-06-15 12:00 拍板方案 1 · 本 F2 仅 emit 'open-subgraph' · F3 实装 enterSubgraph 嵌套展示 · 若用户后续要求新 tab 再修订 R1

历史

时间 事件 hash
2026-06-15 13:50 dispatched(用户 13:42 accept ADR-AIOS-25 · 13:50 双连 start F1+F2 · ClaudeA 与 F1 文件正交并行 · 0.7d 解锁用户三件套盲区第 2 件 · F1+F2 双 zombie → F3 ready)