Files
deepseek-harness/packages/ui/README.zh.md
Turtle f290a8b851 refactor(cli)!: one shared base config with per-surface overlays
`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml
composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml
whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a
twenty-key pass-through Config. Neither file was what its location claimed —
apps/cli hardcoded the "example" as the product default and the "demo" bundle
was the application — and every capability change had to be made twice.

- apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and
  web.cordis.yml are patch lists stating only what differs per surface
- overlays apply as SIBLING patch lists at one include level, because include
  patches never cross an include boundary. Precedence: base < surface <
  (--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches
- `--config` now applies an overlay INSTEAD OF the personal one, so a demo or
  test tree never inherits the user's route; new `--config-replace` boots a file
  as the entire tree (the old `--config` behaviour). Both survive /resume
- vendor/include: index each `insert`ed row as it is added so a later patch can
  configure or disable it. Upstream built the id index once before the patch
  loop, leaving every surface-only row — the whole TUI front door — silently
  unpatchable from user config. Logged as local modification 8
- session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY;
  dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it)
- delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo;
  TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests,
  examples/code-mode survives as an overlay leaf
- `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay

Three latent defects surfaced and are fixed here: the TUI captured the optional
sessionQuery service once at construction and could permanently disable /resume
when it won the mount race; the session-store root silently reverted to a
project-local ./.sessions; --config-replace was dropped by the resume handoff.

Verified by booting each tree through the real Loader (TUI 55 entries, web 75,
zero unsettled) rather than reading YAML. All eight terminal snapshots replay
byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene
and lint clean.
2026-07-29 21:15:42 +08:00

3.8 KiB
Raw Blame History

ui/:面向用户和 SDK 客户端的集成接口

English | 中文

面向用户的交互通道和进程外 SDK 服务器。这些是产品package由用户或 SDK 客户端直接操作的真实接口。

职责 ctx 键
commands/ 用户命令注册表:共享发现元数据、作用域遮蔽、取消以及 UI 直接分派 ctx.commands
user-approval/ 一次性用户审批机制、封闭的结果词汇、审计事件和逐会话审批策略 ctx.approval
permission/ 面向用户的权限预设(workspace-write/danger-full-access):通过一项产品级选择组合沙箱模式与审批策略两个可调参数,并写入各自的会话事件 ctx.permission
user-interaction/ UI 支持的确认工具所使用的抽象用户问答 seam ctx.userInteraction
tool-ask-user/ 模型侧 ask_user_question 工具,基于 ctx.userInteraction 实现 (注册到 ctx.tools
tui/ 交互式 pi-tui 终端通道:渲染会话标题、事件和工具意图,响应 ctx.userInteraction,并托管由 effect 持有的插件浮层 ctx.tui(驱动 ctx.agents
jsonrpc/ 面向进程外 SDK 客户端的 stdio JSON-RPC 服务器 (驱动 ctx.agents
app-boot/ app bin 的共享启动粘合层:加载 .env、会明确报错的 Loader 保护机制、感知快照的配置解析,以及等待整棵树停稳的启动序列 (供各 bin 使用的库)

UI 集成属于由客户端驱动的插件,而非对循环的修改:它使用现有的 agent/* 事件分类和 dsh-agent 工厂。tui 是交互式终端入口,并提供终端本地的 ctx.tui 扩展服务;jsonrpc 为进程外 SDK 客户端提供服务,非交互式的一次性任务则使用 cli-democommands 是 TUI 使用的仅面向用户的发现与分派通道;命令输入和输出不会成为模型消息。

user-approvaluser-interactiontool-ask-user 位于此处,因为向用户提问是由 UI 支持的产品功能,并不属于无提供方的核心主干。user-approval 负责一次性的 ctx.approval 决策机制及其策略层级;应答逻辑仍由负责 agent智能体的通道或自动化传输层提供。user-interaction 保持提供方无关(ctx.userInteractiontool-ask-user 是其模型侧消费方,而交互式 app 包提供具体的提供方。

<<<<<<< HEAD 基于 agent-spine-demo 组合的可运行 app bundle 位于 examples/tui-demoacp-demojsonrpc-demo)。acp-demojsonrpc-demo 各自提供启动 bintui-demo bundle 则由产品 dsh CLI命令行界面启动。ui/ 保留可复用的用户SDK 通道插件和共享 app-boot 粘合层;仅供自动化使用的 ACPAgent Client Protocol传输层位于 acp/。每个入口都负责自己的 stdout 策略,叶子 cordis.yml 则提供后端与可选工具。

基于 agent-spine-demo 组合的可运行 app bundle 位于 examples/cli-demoacp-demojsonrpc-demo)。acp-demojsonrpc-demo 持有启动 bin产品 dsh CLI 不使用 bundle它启动 apps/cli 中的平铺 config tree。ui/ 保留可复用的用户SDK 通道插件和共享 app-boot 粘合层;仅供自动化使用的 ACP 传输层位于 acp/。每个入口都持有自己的 stdout 策略,叶子 cordis.yml 则提供后端与可选工具。

a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)