将 feat/sdk-backend 分支中 workflow 相关的 20 个 commit 压缩为单 commit: - 工作流引擎核心:phase / agent / parallel / pipeline 编排原语(packages/workflow-engine/) - /workflows 面板:三区焦点布局(顶部 run tabs + 左侧 phase 侧栏 + 右侧 agent 列表) - /ultracode skill:多 agent workflow 编排入口 - 进度存储 / journal / notification 系统 - WorkflowService 生命周期管理 + SentryErrorBoundary - 脚本沙箱:禁用 dynamic import()、JSON args 防御性归一化 - journal 与 named-workflow 路径统一在 projectRoot - 错误处理:parallel/pipeline hooks 错误日志、failure routing、semaphore abort - workflow 工具升级为 core 工具 + PascalCase 命名 Co-Authored-By: glm-5.1 <zai-org@claude-code-best.win>
11 KiB
/workflows 面板重设计:顶 tab + 左 phase 侧栏 + 右 agent 列表
状态:草案(待用户 review → writing-plans 产出实施计划) 日期:2026-06-13 关联:上一期整体设计
docs/superpowers/specs/2026-06-13-workflow-tui-ultracode-design.md(其 §9 双栏面板已实现,本 spec 取代该 §9 的面板部分)
1. 背景与现状
上一期整体设计已落地:WorkflowService 门面、claude-code AgentAdapter、进度 bus+store、引擎 agentId 关联、/ultracode skill 全部实现完成。/workflows 面板按旧 spec §9 实现为双栏:
src/workflow/panel/WorkflowsPanel.tsx:左栏WorkflowList(扁平 run 列表)+ 右栏WorkflowDetail(phase 横条 + 扁平 agent 列表)。- 键位
j/k在左栏选 run,选中即聚焦、右栏随之切换。
问题:监控「单个 run 内多 phase / 多 agent」时,左右是「run 列表 vs 单 run 详情」——切换 run 与查看 agent 共用一对键位;phase 仅一行横条,无法按 phase 筛选 agent;多个 run 间切换要上下翻列表。
本 spec 把面板原地重写为三区焦点模型:顶部 run tab + 左 phase 筛选侧栏 + 右 agent 列表,贴合「聚焦一个 run → 按 phase 收窄 → 看 agent 状态」的实际监控动线。
2. 目标与非目标
目标
- 顶 tab 按 run(同名脚本多次跑会多个 tab,标签附 runId 短码消歧如
review-changes#a3f)。 - 左 phase 侧栏:合并
meta声明 phase(pending○)与 store phase(running●/ done✓)+ 一个固定All项;选中即决定右栏筛选。 - 右 agent 列表:按选中 phase 过滤(
All则全显);状态用颜色 + 文字标记(object/text/dead)。 - 焦点轮转键位:
Tab/Shift+Tab切 run、←/→切 phases↔agents、↑/↓列内移动、xkill /rresume /q/Escquit。 - 视觉极简:无内框,左右栏中间一条竖线;选中/光标行用底色条(
backgroundColor,非反白);聚焦列标题橙粗、非聚焦灰。 - 显示 pending phase(meta 声明但未启动)。
非目标
- 不改引擎包(
run_started已携带meta.phases,见 §3)。 - 不动
service/registry/backends/ports/wiring/Workflow 工具//ultracode。 - 不做 per-agent 操作 UI(仅 run 级
kill/resume)。 - 不改
BackgroundTasksDialog(Shift+Down)跳转协议。 - 不做 agent 输出详情抽屉(留未来)。
3. 关键发现:零引擎改动
ProgressEvent.run_started 已携带 meta: WorkflowMeta | null(packages/workflow-engine/src/types.ts:60-66,emit 点 engine/runWorkflow.ts:72-77),且 WorkflowMeta.phases 已是 Array<{ title: string; detail?: string }>(types.ts:22-27)。
→ pending phase 所需数据全在事件流里。面板只需让 store 在 run_started 时落地 declaredPhases,再与 store 的 run.phases(running/done)合并即可。不触碰引擎包。
4. 数据模型变更(src/workflow/progress/store.ts)
-
RunProgress新增字段:declaredPhases: string[] // 来自 run_started.meta.phases[].title;无 meta → [] -
reducer
run_started分支补一行(当前第 74-77 行只用event.workflowName,忽略event.meta):case 'run_started': p.workflowName = event.workflowName p.status = 'running' p.declaredPhases = event.meta?.phases?.map(ph => ph.title) ?? [] break -
ensure()初始化declaredPhases: []。 -
其余 reducer 分支、
AgentProgress、快照排序逻辑不变。
测试(progress/store.test.ts 或对应测试文件):
run_started带meta.phases→declaredPhases落地且顺序保留。run_started的meta为null→declaredPhases === []。- 已有
agentId关联、phase 切换、run_done终态用例保持绿。
5. 面板布局(定稿 ASCII)
焦点在 PHASES(默认进入态):
╭─ Workflows ──────────────────────────── 2 running · 3 done ─╮
│ │
│ ● review-changes ✓ find-bugs ● migrate-auth │
│ ═════════════════ ← Tab / Shift+Tab 切 │
│ │
│ PHASES │ AGENTS · Review │
│ │ │
│ ✓ Find 3/3 │ ● review:bugs running │
│ ▓▶● Review 2/5▓ │ ● review:perf running │
│ ○ Verify 0/2 │ ✓ review:sec object │
│ │ ✗ review:api dead │
│ All 10 │ ✓ review:auth text │
│ │ │
│ Tab 切 run · ←/→ 切焦点 · ↑/↓ 移动 · x kill · q quit │
╰─────────────────────────────────────────────────────────────╯
按 → 焦点到 AGENTS(PHASES 标题变灰、AGENTS 变橙、光标行铺底色):
phases (灰) │ AGENTS · Review (橙)
│
✓ Find 3/3 │ ● review:bugs running
● Review 2/5 │ ▓● review:perf running ▓ ← 光标行底色
○ Verify 0/2 │ ✓ review:sec object
All 10 │ ✗ review:api dead
6. 焦点与键位状态机
面板状态(WorkflowsPanel 内 useState):
| 状态 | 含义 | 默认 |
|---|---|---|
activeRunId |
当前 tab 的 runId | 首个 run(无则 null) |
focusColumn |
'phases' | 'agents' |
'phases'(该 run 无任何 phase 则 'agents') |
selectedPhaseIndex |
phase 侧栏选中项(0 = All) |
0 |
selectedAgentIndex |
agent 列表光标行 | 0 |
键位:
| 键 | 作用 |
|---|---|
Tab / Shift+Tab |
切顶部 run tab(正/反);切 tab 时重置 selectedPhaseIndex=0、selectedAgentIndex=0、focusColumn 回默认 |
← / → |
phases ↔ agents 焦点切换(tabs 不参与左右,由 Tab 管) |
↑ / ↓ |
当前焦点列内移动选中(phase 改筛选;agent 滚光标) |
x |
kill 当前 tab 的 run |
r |
resume 当前 tab 的 run(缺 canUseTool 时 onDone 提示用 /<name> resume) |
q / Esc |
退出面板 |
夹紧:复用 WorkflowsPanel 已导出的 clampSelected——切 tab / 列表变动后把 selectedPhaseIndex、selectedAgentIndex 夹到有效区间。
筛选语义:selectedPhaseIndex===0(All)→ 右栏显示全部 agent;否则按 phase === 选中 phase title 过滤。
7. 组件拆分(src/workflow/panel/)
| 文件 | 动作 | 职责 |
|---|---|---|
WorkflowsPanel.tsx |
重写 | 订阅 store、持焦点状态、渲染 TabsBar + 左右双栏、绑 useWorkflowKeyboard;保留导出 clampSelected |
TabsBar.tsx |
新建 | 顶部 run tab 行(状态点 + 名 + runId 短码;当前 tab 橙色 ═══ 下划线) |
PhaseSidebar.tsx |
新建 | 左 phase 列表:All + 合并 declaredPhases(pending ○)与 run.phases(●/✓),每行附 done/total agent 计数 |
AgentList.tsx |
新建 | 右 agent 列表:按选中 phase 过滤;状态色 + 行尾 object/text/dead 文字标记 |
status.ts |
新建 | 共享状态→字符/颜色映射(STATUS_DOT、phase/agent mark 函数),三组件复用 |
useWorkflowKeyboard.ts |
改写 | 焦点模型键位(见 §6) |
WorkflowList.tsx |
删除 | run 列表职责迁入 TabsBar |
WorkflowDetail.tsx |
删除 | phase+agent 职责拆入 PhaseSidebar+AgentList |
panelCall.ts |
不变 | local-jsx 入口仍渲染 WorkflowsPanel |
外部接口不变:/workflows 命令注册、panelCall、getWorkflowService() 订阅协议、BackgroundTasksDialog 跳转均不动。
8. 视觉规则
-
无内框:左右两栏中间一条
│竖线,仅此一条分割线;最外层保留最朴素的 round border 界定面板。 -
聚焦列:标题
claude橙粗体;非聚焦列标题subtle灰。 -
选中/光标行:整行铺
backgroundColor="claude"橙底(ASCII 用▓示意),文字色不变,状态点保留各自颜色。 -
状态色(沿用现有 Ink theme token,无新增):
元素 状态 字符 颜色 Tab (run) running ●warningcompleted ✓successfailed ✗errorkilled ■subtle当前 ═══claude下划线Phase running ●warningdone ✓successpending ○subtle选中 ▶claude+ 底色Agent running ●warningdone·text ✓success+ 行尾textdone·object ✓success+ 行尾objectdead ✗error+ 行尾dead -
object 标记:行尾纯文字
object(不用◆符号)。 -
左窄右宽:phase 栏约 20%、agent 栏约 80%(或固定 phase 栏 ~20 字符,agent 栏吃剩余宽度)。
9. 测试策略
- store:
declaredPhases落地 + null meta 回归(§4)。 - 面板(
WorkflowsPanel.test.tsx,ink-testing-library,遵循仓库 mock 规范):- 多 run → tab 渲染 + 当前 tab 下划线;
Tab/Shift+Tab切换且重置子选择。 ←/→切focusColumn(标题颜色 / 光标落点)。- phase 侧栏选中 → 右栏 agent 按 phase 过滤;
All显全部。 - pending phase(
declaredPhases有、store 无)显示○。 - 选中行/光标行底色条(断言对应
<Text backgroundColor>)。 xkill、rresume(mock service)、q/Esc退出。- 空态(无 run):占位文案 +
n提示。 - 订阅刷新:store 变更后面板重渲染(agent 状态 running→done)。
- 多 run → tab 渲染 + 当前 tab 下划线;
- 回归:
bun run precheck零错误;现有 workflow 集成测试(canonical scripts / review / loop / resume)保持绿。
10. 里程碑与提交切分
每个里程碑结束 bun run precheck 必须零错误。
- M1 store:
RunProgress.declaredPhases+ reducerrun_started落地 + 测试。 - M2 panel 组件:新建
status.ts/TabsBar/PhaseSidebar/AgentList;WorkflowsPanel重写为焦点状态机;useWorkflowKeyboard改焦点模型;删除WorkflowList/WorkflowDetail。 - M3 测试:
WorkflowsPanel.test.tsx全量用例 + precheck 绿。 - M4 文档:
docs/features/workflow-scripts.md§六 更新为三区布局/键位;旧 spec §六/§9 加注「面板部分已被2026-06-13-workflow-panel-redesign.md取代」。
11. 未做 / 未来工作
- per-agent skip/retry 的 UI 接线(引擎 seam 已在)。
- agent 详情抽屉:选中 agent 后展开其 prompt/输出/token。
- 多 run 并排对比视图。
declaredPhases与实际phase()调用不一致时的告警(如脚本声明了 phase 却没调用)。