跳转至

Plan Canvas — 在浏览器中交互式审阅计划

状态:已实现(feat/plan-canvas) 灵感来源:lavish-axi,作者 @kunchenguid。其核心理念是对智能体(agent)生成的产物进行本地化的「注释 + 聊天」式审阅循环。Plan Canvas 是该理念的原创、ECC 原生实现,而非移植版本。

Plan Canvas reviewing a plan on the left while the agent works in the terminal on the right

问题

/plan 以一个硬性闸门(hard gate)收尾:智能体写入 .claude/plans/{name}.plan.md 后必须等待用户确认。目前,这种审阅只是终端里一堵 Markdown 文本墙,反馈循环的方式是「在聊天中重新输入你想修改的内容」。社区一直期待 lavish-axi 推广的那种循环:以正确的渲染方式查看计划、直接指出你想说的部分、并从页面上与智能体对话。

它是什么

一个仅回环(loopback)的 Web 编辑器,用于查看计划产物(以及任何本地 HTML 产物):

  • 智能体在写完计划后运行 node scripts/plan-canvas.js open <artifact>。
  • 产物会在浏览器中打开,并带有 ECC 风格的界面外壳(与 scripts/dashboard-web.js 使用相同的设计令牌):默认深色、--accent #6885e8、accent→pink 品牌渐变、支持浅色主题切换。
  • 用户以可视化方式进行审阅,点击元素或选中文本以附加带编号的注释,并通过侧边栏与智能体聊天。
  • 针对计划的裁决操作——批准计划(Approve plan) / 请求变更(Request changes)——直接映射到 /plan 的 CONFIRM 闸门,因此可以直接在画布上完成批准,而无需回到终端。
  • 智能体会阻塞在 node scripts/plan-canvas.js await <artifact> 上(长轮询)。反馈以 JSON 形式出现在 stdout 上:聊天消息、带有 CSS 选择器 + 文本范围锚点的注释、裁决结果,或会话结束信号。
  • 智能体通过 await --reply "..." 回复,消息会出现在画布聊天中;对产物文件的编辑会实时重新加载页面。

如何融入 ECC

组件 位置 遵循
CLI 入口 scripts/plan-canvas.js(+ npm bin ecc-plan-canvas) 遵循 scripts/control-pane.js 的模式
服务器 scripts/lib/plan-canvas/server.js 与 control-pane 相同的回环服务器,host-header + Origin 白名单(DNS 重绑定防护)
编辑器外壳 scripts/lib/plan-canvas/ui.js 参照 scripts/lib/control-pane/ui.js,设计令牌来自 scripts/dashboard-web.js
Markdown 计划渲染器 scripts/lib/plan-canvas/markdown.js 零新增依赖;渲染 commands/plan.md 的产物 schema(表格、任务、代码围栏、Mermaid 代码块)
Mermaid 图表 scripts/lib/plan-canvas/ui.js ```mermaid 代码块在浏览器中渲染,并使用 ECC 主题;固定版本的 CDN,带离线回退(可用 ECC_PLAN_CANVAS_MERMAID_URL 指向本地镜像)
会话状态 scripts/lib/plan-canvas/sessions.js 以文件路径为键的会话,状态存放于 ~/.claude/plan-canvas/(可用 ECC_PLAN_CANVAS_STATE_DIR 覆盖)
技能 skills/plan-canvas/SKILL.md 技能优先的入口;教授 open → await → reply 循环;视觉指导部分交给 frontend-design-direction、artifact-design、dataviz
命令垫片 commands/plan-canvas.md 遗留兼容入口,指向该技能
/plan 指引 commands/plan.md 写入产物后,提供画布审阅选项
钩子(可选) scripts/hooks/plan-canvas-sessions.js, SessionStart 展示打开的画布会话,使新会话可以恢复审阅
测试 tests/lib/plan-canvas/*, tests/integration/plan-canvas-e2e.test.js node:test 风格的纯断言,由 tests/run-all.js 运行

注册方式:package.json(bin、files[])、manifests/install-components.json(+ install-modules.json 中的 workflow-quality 路径)、agent.yaml 技能列表、catalog 与命令注册表的重新生成。

跨执行框架 / 模型兼容性

该功能在设计上不依赖特定模型或执行框架(harness):CLI 输出纯 JSON,技能教授的是「shell + stdout」循环,因此任何有能力的智能体都能以完全相同的方式驱动它——这与 lavish-axi 所采用的「就是一个 CLI」的思路一致。核心循环中没有任何仅限 Claude 的依赖;SessionStart 钩子只是 Claude Code 的一项附加便利(其他执行框架可以通过裸调用 ecc-plan-canvas 查看打开的会话)。

各入口与 ECC 各执行框架中同级 workflow-quality 技能的发布方式保持一致:

  • skills/plan-canvas/ —— 规范版本(Claude Code 及安装器各目标适配器使用)。
  • .agents/skills/plan-canvas/(+ agents/openai.yaml 接口清单)—— Codex,与 tdd-workflow、e2e-testing、verification-loop 并列。
  • agent.yaml 技能列表 —— Codex gitagent 清单。
  • CLI 可从任何项目中通过 ecc-plan-canvas bin(全局/插件安装)或 $CLAUDE_PLUGIN_ROOT/scripts/plan-canvas.js 解析,绝不会使用相对于当前工作目录(cwd)的路径。

Cursor 所检入(checked-in)的子集仅包含内容/营销技能,因此与同类技能的做法一致,plan-canvas 未被加入其中;安装器仍会从规范的 skills/ 目录为 Cursor 安装它。

协议

会话以规范化产物路径(sha256(realpath)[:12])为键。CLI 与一个独立(detached)服务器通信(状态目录中的 server.json 记录 pid/端口/版本;空闲 30 分钟后自动关闭,可用 ECC_PLAN_CANVAS_IDLE_MS 调整)。反馈采用「投递并排空」(deliver-and-drain)机制:队列中的条目只会交给恰好一次 await 调用,在此之前会持久化到磁盘,因此即使轮询被中断也不会丢失任何内容。

  • GET /health —— {ok, app: "ecc-plan-canvas", version}(CLI/服务器版本握手)
  • GET / —— 会话列表(ECC 外壳)
  • POST /api/sessions {file, reopen?} —— 打开/恢复会话;除非指定 reopen,否则返回 409 user-ended
  • GET /canvas/<key> —— 编辑器外壳;GET /artifact/<key>/ —— 渲染后的产物(markdown → ECC 计划模板,HTML 直接透传),并注入注释 SDK;同级的静态资源仅限于产物目录内
  • POST /api/session/<key>/feedback {items[], endSession?} —— 浏览器入队聊天 / 注释 / 裁决条目
  • GET /api/await?file=<path>[&timeoutMs=n] —— 智能体长轮询(空白字符心跳);返回 {status: feedback|ended|waiting|missing, items[], sessionEnded?, endedBy?}
  • POST /api/session/<key>/reply {text} —— 智能体消息 → 画布聊天
  • POST /api/session/<key>/end(用户)/ POST /api/end {file}(智能体)—— 记录结束方;用户结束具有粘性:不带 --reopen 的普通 open 会拒绝重新打开
  • GET /events/<key> —— 通过 SSE 推送给浏览器:chat-sync、presence(waiting/listening/working)、reload(产物文件已变更)、ended

与 lavish-axi 的有意差异

  • 计划优先:原生渲染 .plan.md / .md(包括 Mermaid);lavish 仅支持 HTML。
  • 裁决操作已接入 ECC 的计划确认工作流。
  • 采用 ECC 设计令牌和界面框架;代理输出为 JSON(而非 TOON)。
  • Mermaid 按 ECC 主题渲染,但不具备 lavish 的平移/缩放或节点 ID 捕获—— 整体元素注释可覆盖指向图表或节点。
  • 不提供导出/共享托管、布局审计门禁或内置剧本——ECC 现有的 设计技能(frontend-design-direction、artifact-design、dataviz)已覆盖编写。

安全态势

默认仅绑定回环地址;每个请求都执行 Host 和 Origin 白名单检查(与 control-pane 相同的方法);工件仅从已注册的会话路径提供,同级资源访问被限制在工件目录内;状态目录位于用户本地。服务器从不执行工件内容——它只将其提供给浏览器。

唯一可选的出站请求是固定版本的 Mermaid 库,仅由浏览器为包含图表的工件获取;它以 securityLevel: 'strict' 渲染,不可用时降级为显示图表源码,并可通过 ECC_PLAN_CANVAS_MERMAID_URL 指向本地镜像。服务器本身仍不发起任何网络调用。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 ev/ECC