迁移计划

August 17, 2026 · View on GitHub

目标:保持现有 TUI 体验,同时把扩展能力收敛到独立的 Cordis client 树; ACP 负责 agent 控制面,私有 compositor 通道负责 Node → Rust 绘制数据。

已完成 — ACP client 控制面

  • profile 主路径在 Host Base tree 挂 ACP plugin,并用标准 stdin/stdout 连接独立 TUI Client 进程;standalone acp-client 仍可 spawn/attach 任意 ACP agent。
  • Rust 使用官方 agent-client-protocol 处理 initialize、认证、session、prompt、 permission、config option 与 update。
  • Agent Cordis 树与 TUI Client Cordis 树位于不同进程,只通过 ACP 通信。
  • 双方通过 initialize _meta.dsh.cordis.protocol = 0 协商;inspect/run/lifecycle 使用 _dsh/cordis/*,painter 子能力使用 _dsh/cordis/tui/*
  • 所有自定义 wire 方法都是下划线前缀的 ACP Extension Request/Notification; theme/slots/commands/overlay 被 Node mux 截获,不进入 agent 流。
  • tui-cordis-client-runner 是 client 树上的独立 sibling;shell 只绑定并转发 transport。

已完成 — Theme 插件 POC

  • tui-theme 是真实 Cordis service 插件,提供 ctx.tuiTheme
  • 配色包作为 sibling plugin,inject: ['tuiTheme'] 后调用 register
  • 18 个 token 名封闭;每个 dark/light pack 必须完整且只接受 #RRGGBB
  • Node 通过 _dsh/cordis/tui/theme/update notification 通知 Rust;插件看不到传输方法。
  • --demo 保持内置 default--demo-skin 挂载并激活 gallery ember

已完成 — Creator skill overlay

  • TUI 包内部的 Host overlay 在上游 cordis preset 的 standing scope 上注册 tui-plugin-development,不复制或修改 Creator composition。
  • skill 只对 Creator agent 可见;bundle 卸载后立即移除。
  • skill 的装载不依赖 ACP;Client inspect/run 仍只负责运行期 TUI 能力与动态包。

已完成 — 根级右栏 slot POC

  • tui-slots 是真实 Cordis service,声明 root/list chrome.right
  • 静态和动态插件都用 inject / register 贡献任意合法 TuiNode 树; panel.update 即时替换,fiber 卸载即撤销。
  • Registry 聚合 contribution、命名空间 node id,并生成带单调 rev 的完整 snapshot。
  • Node 经 _dsh/cordis/tui/slots/update notification 送给 Rust;Rust 校验并在独立右栏渲染。
  • 最后一个 contribution 消失时主界面恢复全宽;窄终端只暂时隐藏右栏。
  • Client inspect 的 Slots.list 让 Creator 能生成 code.client;gallery export @openma/deepseek-harness-tui/right-demo 不默认挂载。

验收:

make rust-test
cd npm && npm test
cd ../host && npm test
dsh-tui --demo
dsh-tui --demo-skin

下一步 — 对话槽

复用现有 tuiSlots service 和 tui-node.v0.schema.json

  1. 壳声明 conversation.chat
  2. 独立插件使用 tuiSlots.inject(slot, () => tuiSlots.register(...))
  3. Registry 聚合 contribution,生成带单调 rev 的完整 snapshot。
  4. Node 经 _dsh/cordis/tui/slots/update notification 送给 Rust。
  5. Rust 校验 schema,按稳定 node id 保留展开、选择和滚动状态。

首版只允许向对话时间线追加节点,不能替换 composer,也不能把插件节点伪装成 durable ACP session event。ACP session/update 仍是 transcript 真源。

后续

  • /refresh:重建 Client 插件 fiber,不杀 agent、不丢草稿。
  • chrome.status 等壳槽:复用同一 registry/snapshot 协议。
  • 可选 JS painter:只替换 renderer,不改变插件 ABI、slot 名或 token 名。

Token 名、node kind 和 slot 名一旦发布只追加;字段语义变化必须提升 protocol。