Merge branch 'codex/goal-commands' into codex/ralph-tool

# Conflicts:
#	examples/repl-agent/README.md
#	examples/repl-agent/composition.md
#	examples/repl-agent/cordis.yml
This commit is contained in:
Tianyi Cui
2026-07-20 22:25:16 +08:00
249 changed files with 2921 additions and 4563 deletions

View File

@@ -116,7 +116,7 @@ Two failure paths, both documented:
- **`SessionEventMap`** gains `compact/start` / `compact/summary` / `compact/end` by declaration merging (merge-extensible); `SurfaceEventType` is **not** touched. These are session events, not cordis `Events`, so the event-taxonomy gate needs no entry.
- **`dsh-compact`** owns `toolPairingBalancedBefore(session, seq)` and `toolPairingBalancedAfter(session, seq)`, the cached surface-edge checks that `compactRegion` and `compactIfNeeded` use to avoid splitting a tool-call/result pair. The cache validates current membership by seq and answers both edges from one per-cut balance sequence; stale or missing seqs and orphan results reject.
- **`dsh-session`** validates positional replacement, complete provenance, and content-only single-node `tool/result` rewrites through its one surface manager. `dsh-invariants` treats fresh appended tool results as executions that require an open step and pending call; validated replacements remain turn-enclosed rewrites.
- **Wiring**: `examples/repl-agent/cordis.yml` loads zero-config `dsh-token-meter`, `dsh-compact-tool-result-prune`, then `dsh-compact-basic`; service-wide defaults make the composition usable without repeated numeric policy.
- **Wiring**: `examples/tui-agent/cordis.yml` loads zero-config `dsh-token-meter`, `dsh-compact-tool-result-prune`, then `dsh-compact-basic`; service-wide defaults make the composition usable without repeated numeric policy.
## Testing

View File

@@ -20,7 +20,7 @@ Providers return `{ answers: [{ id, selected, custom? }] }`. `selected` is alway
## UI mappings
`dsh-stdio-demo`'s in-package readline module renders each question, shows each option's `description` on the next line, supports comma/space-separated numeric choices for `multi_select`, accepts free-form custom answers, and rejects pending questions on abort, provider disposal, or stdin EOF. A batched request is asked in order and resolved as one answer object. The stdio provider serializes simultaneous requests with an internal queue so only one prompt owns stdin at a time.
`dsh-tui` renders each question as a keyboard overlay, shows option descriptions, supports single- and multi-select choices plus free-form custom answers, and rejects pending questions on abort, provider disposal, or terminal shutdown. Batched and simultaneous requests are queued so one overlay owns keyboard focus at a time.
`dsh-acp` provides the same seam for ACP sessions. It resolves the calling `Agent` through `ownedRecord`, requiring the forward session-map record at `agent.session.id` to own that exact agent object, and calls ACP `unstable_createElicitation` with a session-scoped form for each question. Single-select options become a `choice` string enum; `multi_select` options become a `choice` array enum; optionless questions use a required `custom` text field. If the client returns both `choice` and non-empty `custom`, the custom answer wins. ACP `decline`/`cancel`, a missing answer, a missing session, and a client without elicitation support all become structured `UserInteractionError`s.
@@ -42,8 +42,8 @@ ACP elicitation is currently marked unstable in the SDK. The fallback is still s
The feature gives the model a powerful pause primitive, so prompt guidance matters. The tool description tells the model to ask concise questions and use options when possible. Product policy can later wrap `tools/execute` to restrict when the tool is allowed, but the loop should not special-case it.
`dsh-user-interaction` and `dsh-tool-ask-user` both live in `packages/ui` because they form one product-facing human-interaction capability. `agent-core` does not load either the tool or a provider. `stdio-agent` opts into the seam, its readline provider, and the model-facing tool. `acp-agent` keeps only the `userInteraction` seam/provider by default: ACP elicitation support is still client-dependent, so an ACP leaf must opt into the model-facing tool deliberately once its client can complete elicitation requests.
`dsh-user-interaction` and `dsh-tool-ask-user` both live in `packages/ui` because they form one product-facing human-interaction capability. `agent-core` does not load either the tool or a provider. `dsh-tui-demo` opts into the seam, TUI provider, and model-facing tool. `acp-agent` keeps only the `userInteraction` seam/provider by default: ACP elicitation support is still client-dependent, so an ACP leaf must opt into the model-facing tool deliberately once its client can complete elicitation requests.
## Testing
Unit coverage pins provider registration/disposal, duplicate-provider rejection, abort-before-provider, empty-question rejection, structured tool errors through `ctx.tools.execute()`, batched answers, multi-select answers, custom answers, and the model schema including the removal of `value`, `recommended`, `allow_custom`, and `desc`. `dsh-stdio-demo` tests cover option descriptions, queued requests, EOF/abort cleanup, optionless free-form input, invalid option reprompts, duplicate multi-select numbers, and batched question flows. ACP bridge tests drive a real in-memory ACP connection with the real `ask_user_question` tool and verify selected-option, custom-overrides-choice, multi-select, and optionless free-form elicitation paths continue the agent loop.
Unit coverage pins provider registration/disposal, duplicate-provider rejection, abort-before-provider, empty-question rejection, structured tool errors through `ctx.tools.execute()`, batched answers, multi-select answers, custom answers, and the model schema including the removal of `value`, `recommended`, `allow_custom`, and `desc`. TUI tests cover option descriptions, queued requests, shutdown/abort cleanup, optionless free-form input, invalid choices, duplicate multi-select selections, and batched question flows. ACP bridge tests drive a real in-memory ACP connection with the real `ask_user_question` tool and verify selected-option, custom-overrides-choice, multi-select, and optionless free-form elicitation paths continue the agent loop.

View File

@@ -21,7 +21,7 @@ The system-prompt assembly owns the canonical model-facing tool order, exactly w
Scope is deliberately narrow: this fixes the REGISTRATION-ORDER race, not plugin behavior. A `system-prompt/assemble` listener may still add, remove, or rearrange tools — same as it may edit sections after their sort — and owns the determinism of what it emits; the waterfall contract already demands deterministic listeners (the reconstructability invariant would catch a listener that diverges between build and replay).
Config plumbing follows the `persona` precedent, and `toolOrder` sits beside it: the app configs (`dsh-stdio-demo`, `dsh-acp-demo`) accept the key and forward it through `dsh-agent-spine-demo` (whose schema is the intersection of the owners' schemas) to the `SystemPrompt` child. One schemastery footnote is load-bearing: a schemastery array defaults to `[]`, but an omitted `toolOrder` must stay ABSENT (= lexicographic) rather than become an explicitly-configured empty list (invalid — it lacks the rest entry), so every schema on the chain forces the default to `undefined`.
Config plumbing follows the `persona` precedent, and `toolOrder` sits beside it: the TUI, Headless, and ACP app configs accept the key and forward it through `dsh-agent-spine-demo` (whose schema is the intersection of the owners' schemas) to the `SystemPrompt` child. One schemastery footnote is load-bearing: a schemastery array defaults to `[]`, but an omitted `toolOrder` must stay ABSENT (= lexicographic) rather than become an explicitly-configured empty list (invalid — it lacks the rest entry), so every schema on the chain forces the default to `undefined`.
## Alternatives considered

View File

@@ -155,7 +155,7 @@ If the complete logical result fits under the inline cap, no formatted spill art
- The tools execute through `ctx.bash.resolve(request)``ctx.bash.run(spec)`, forward `exec.signal`, never call `ctx.bash.start()`, and never expose a bash task id. The bash request workdir comes from `exec.agent?.session.header.cwd` when available; the resolved `spec.workdir` drives execution and relative-path display.
- The tools request `stdoutMaxBytes: rawOutputMaxBytes` from the bash seam, parse only untruncated stdout within that cap, and treat over-cap or still-truncated raw output as a clear search failure; raw `rg` output is never exposed to the model.
- Oversized complete formatted results are saved through `ctx.spillStore.saveText()` when available while inline results stay bounded; spill failure, a missing backend, or a missing owner preserves the inline result and reports the unsaved remainder — never an `isError`.
- The package README, the generated config catalog, and exported JSDoc document the Config fields and `SEARCH_*` codes; the repl-agent example ships the conditional tool plugin (the acp-agent tree waits on the snapshot re-record above); the fs group README records the `rg` availability and co-located bash/filesystem deployment requirements.
- The package README, the generated config catalog, and exported JSDoc document the Config fields and `SEARCH_*` codes; the tui-agent example ships the conditional tool plugin (the acp-agent tree waits on the snapshot re-record above); the fs group README records the `rg` availability and co-located bash/filesystem deployment requirements.
## Risks

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-17-dedicated-full-screen-tui-front-door.md: 178b5ea44be67f820a8ea7fed8acb987dffb3f80
2026-07-17-dedicated-full-screen-tui-front-door.zh.md: ac055bad1b7a692c7a980430fdbd1e34737a9994
2026-07-17-dedicated-full-screen-tui-front-door.md: 8fbc5dddc029190b346075a65c9e7857187f3d2b
2026-07-17-dedicated-full-screen-tui-front-door.zh.md: 6ddc3523b7a7173013efe2ef15c5ca0e940929fb

View File

@@ -6,7 +6,7 @@ English | [中文](2026-07-17-dedicated-full-screen-tui-front-door.zh.md)
## Problem
The line-oriented `@deepseek-ai/dsh-stdio` front door works in pipes and ordinary terminals, but a full-screen coding interface must own raw input, differential screen drawing, cursor state, overlays, and terminal restoration. Combining those contracts in one UI plugin couples the pipe-safe path to a TTY-only lifecycle and makes it unclear which terminal behavior a composition selects.
At the time this front door was introduced, the line-oriented agent handled pipes and ordinary terminals, but a full-screen coding interface had to own raw input, differential screen drawing, cursor state, overlays, and terminal restoration. Combining those contracts in one UI plugin would have coupled a stream-oriented path to a TTY-only lifecycle. The later [redundant-agent removal](../simplification/2026-07-20-remove-stdio-and-echo-agents.md) removes that line agent; this Note continues to own the TUI design.
The interactive channel must remain a Cordis plugin over the same agent, session, tool, and user-interaction services as every other front door. It needs to resume durable history, follow compaction replacements, display tool-owned presentation, and restore the terminal on startup failure and disposal. A standalone chat application or a second agent composition would duplicate behavior outside the plugin graph.
@@ -14,7 +14,7 @@ The interactive channel must remain a Cordis plugin over the same agent, session
DeepSeek Harness ships [`@deepseek-ai/dsh-tui`](../../../../packages/ui/tui/README.md) as a dedicated Cordis plugin. It owns terminal input and presentation only; agent lifecycle, session persistence, tool execution, and the model-facing question tool remain separate composition entries. The plugin requires both stdin and stdout to be TTYs and fails instead of silently changing to line-oriented behavior.
The app layer selects a concrete terminal front door before mounting it. `@deepseek-ai/dsh-stdio-demo` can resolve `auto` from the two process streams, while the `repl-agent` and `tui-agent` leaves explicitly select readline and TUI respectively. The TUI leaf reuses the repl-agent backend and tool composition through an asserted include patch, so the three runnable agent leaves remain symmetric without duplicating deployment choices.
The app layer has one terminal front door. `@deepseek-ai/dsh-tui-demo` mounts the TUI before the configured agent, and `examples/tui-agent` owns the interactive coding composition and Code Mode overlay directly. Non-interactive tasks use `@deepseek-ai/dsh-cli-demo`; ACP remains a separate editor protocol.
The selected front door receives the exact generated or resumed `SessionId` used by the pre-created agent. It mounts before the agent composition, waits for the matching root agent, and enters full-screen mode only after that agent exists. A matching `agent-loop/config-start-failed` event is therefore reported before screen takeover and exits with status 1.
@@ -42,7 +42,7 @@ The implemented [TUI terminal-state snapshot Agent Note](../testing/2026-07-18-t
## Consequences
- Interactive terminal work gains a stateful Markdown, card, plan, and question interface without changing the line-oriented protocol used by pipes and automation.
- The TUI carries a pi-tui dependency and a strict TTY requirement; non-TTY deployments select `@deepseek-ai/dsh-stdio` at composition time.
- Interactive terminal work has a stateful Markdown, card, plan, and question interface with no second terminal protocol to keep aligned.
- The TUI carries a pi-tui dependency and a strict TTY requirement; non-TTY deployments use the Headless app or a structured protocol.
- Session projection makes resume and compaction consistent with the durable conversation, but one configured session owns the transcript and editor.
- Tool packages extend terminal cards through their existing presentation methods without adding tool-specific branches to the TUI.

View File

@@ -6,7 +6,7 @@ Status: implemented
## 问题
逐行输出的 `@deepseek-ai/dsh-stdio` 入口适用于管道和普通终端,但全屏编码界面必须负责原始输入、差分绘制、光标状态、浮层和终端恢复。把这两类契约合并到一个 UI 插件中,会迫使管道安全路径依赖仅适用于 TTY 的生命周期,也使组合无法明确表达所选终端行为
在本入口引入时,面向行的 agent 负责 pipe 与普通终端,但全屏 coding 界面必须负责原始输入、差分绘制、光标状态、浮层和终端恢复。把这两类契约合并到一个 UI 插件中,会迫使面向 stream 的路径依赖仅适用于 TTY 的生命周期。后续的[移除重复 agent 决策](../simplification/2026-07-20-remove-stdio-and-echo-agents.md)移除了这个面向行 agent本 Note 继续负责 TUI 设计
交互通道必须继续作为 Cordis 插件,使用与其他入口相同的 agent智能体、会话、工具和用户交互服务。它需要恢复持久历史、跟随压缩替换、显示工具自有的呈现内容并在启动失败和资源释放时恢复终端。独立聊天应用或第二套 agent 组合会在插件图之外重复实现这些行为。
@@ -14,7 +14,7 @@ Status: implemented
DeepSeek Harness 将 [`@deepseek-ai/dsh-tui`](../../../../packages/ui/tui/README.md) 作为独立的 Cordis 插件交付。该插件只负责终端输入与呈现agent 生命周期、会话持久化、工具执行以及模型可见的提问工具仍由不同组合项负责。插件要求 stdin 和 stdout 均为 TTY条件不满足时会失败不会静默切换为逐行输出。
应用组合层在挂载前选择具体的终端入口。`@deepseek-ai/dsh-stdio-demo` 可以根据两个进程流通过 `auto` 作出选择,`repl-agent``tui-agent` 叶节点则分别明确选择 readline 与 TUI。TUI 叶节点通过带断言的 include patch 复用 repl-agent 的后端和工具组合,使三个可运行的 agent 叶节点保持对称,同时避免重复部署选项
应用组合层只有一个终端入口。`@deepseek-ai/dsh-tui-demo` 在已配置 agent 之前挂载 TUI`examples/tui-agent` 直接拥有交互式 coding 组装及其 Code Mode overlay。非交互任务使用 `@deepseek-ai/dsh-cli-demo`ACP 仍是独立的编辑器协议
所选入口接收预创建 agent 使用的同一个新建或恢复 `SessionId`。入口先于 agent 组合挂载,等待相符的根 agent 出现,然后才进入全屏模式。因此,相符的 `agent-loop/config-start-failed` 事件会在接管屏幕前报告,并以状态码 1 退出。
@@ -42,7 +42,7 @@ agent 空闲时,编辑器输入调用 `agent.send()`;轮次运行中则调
## 后果
- 交互式终端获得带状态的 Markdown、卡片、计划和提问界面同时不会改变管道与自动化使用的逐行协议。
- TUI 会引入 pi-tui 依赖并严格要求 TTY非 TTY 部署在组合时选择 `@deepseek-ai/dsh-stdio`
- 交互式终端拥有带状态的 Markdown、卡片、计划和提问界面无需再对齐第二套终端协议。
- TUI 会引入 pi-tui 依赖并严格要求 TTY非 TTY 部署使用 Headless app 或结构化协议
- 会话投影使恢复和压缩与持久会话保持一致,但只有一个已配置会话拥有 transcript 和编辑器。
- 工具包通过既有呈现方法扩展终端卡片,无需在 TUI 中增加工具专用分支。

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-19-fresh-agent-ralph-workflow-tool.md: 46816b8cc06f0acf5615ffb44035c79ea13b6794
2026-07-19-fresh-agent-ralph-workflow-tool.zh.md: 188a0bf50a7a6a683cd6aa1004c4d78673d3631d
2026-07-19-fresh-agent-ralph-workflow-tool.md: c2db4d7dd30c27a25adecdfc425db261cc3dfeb5
2026-07-19-fresh-agent-ralph-workflow-tool.zh.md: e33e9848d71c98c8f83494ebe8bf171ef10b9305

View File

@@ -40,7 +40,7 @@ The workflow language maps a normally settled but unsuccessful child to `null`.
The model may supply only `objective` and optional `maxRounds`; provider selection, report schema, handoff cap, and script are deployment-owned. A fixed prompt section says to use `ralph` only when the direct human explicitly asks for Ralph or fresh-agent iteration, and distinguishes it from same-session goals, bounded delegation, and general fan-out workflows. This is guidance rather than a new goal UX state machine.
ACP and terminal presentation use a generic `ralph` card whose raw input is the objective. Successful completion and blocker envelopes say that a worker reported the outcome rather than presenting it as independent certification. The parent transcript retains the original tool call and one bounded successful terminal report or an error, not intermediate child messages. Shipped headless, REPL/TUI, and ACP compositions load the plugin beside the existing workflow engine; JSON-RPC remains unchanged because its default composition does not expose workflows.
ACP and terminal presentation use a generic `ralph` card whose raw input is the objective. Successful completion and blocker envelopes say that a worker reported the outcome rather than presenting it as independent certification. The parent transcript retains the original tool call and one bounded successful terminal report or an error, not intermediate child messages. Shipped headless, TUI, and ACP compositions load the plugin beside the existing workflow engine; JSON-RPC remains unchanged because its default composition does not expose workflows.
## Testing

View File

@@ -40,7 +40,7 @@ Ralph 插件的 `subagentProvider` 默认为 `spawn`。每次调用前,它要
模型只能提供 `objective` 和可选的 `maxRounds`provider 选择、报告 schema、交接上限和脚本都由部署拥有。固定提示区段说明只有直接人类明确要求 Ralph 或全新 agent 迭代时才使用 `ralph`,并将其与同会话目标、有界委派和通用扇出工作流区分开。这是指导,而不是新的目标 UX 状态机。
ACP 和终端展示使用通用 `ralph` 卡片,并把目标作为原始输入。成功完成与阻塞的外层文本会说明结果由工作者报告,而不会把它呈现为独立认证。父转录只保留原始工具调用,以及一份有界成功终止报告或一个错误,不包含中间子 agent 消息。发布的无头、REPL/TUI 与 ACP 组合会在现有工作流引擎旁加载该插件JSON-RPC 保持不变,因为其默认组合不暴露工作流。
ACP 和终端展示使用通用 `ralph` 卡片,并把目标作为原始输入。成功完成与阻塞的外层文本会说明结果由工作者报告,而不会把它呈现为独立认证。父转录只保留原始工具调用,以及一份有界成功终止报告或一个错误,不包含中间子 agent 消息。发布的无头、TUI 与 ACP 组合会在现有工作流引擎旁加载该插件JSON-RPC 保持不变,因为其默认组合不暴露工作流。
## 测试

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-19-human-goal-command.md: e2a59c3bddd7e135b0878cb59c964c3e7be64002
2026-07-19-human-goal-command.zh.md: 0d6a0e22de091cd7a4a00ef59f1ac1b936c930f9
2026-07-19-human-goal-command.md: a272206a3bfad50a01ce871c56c7e7bcf924684e
2026-07-19-human-goal-command.zh.md: 370c9bc24510320c70e3d789926c492e543968b1

View File

@@ -40,11 +40,11 @@ Generic slash input, status text, and errors are not persisted. Successful goal
`agent-spine-demo` accepts an optional `goals` composition object containing the goal-domain and model-tool owner configs. Omission or `false` leaves the stack unmounted. This explicit opt-in is important for headless one-shot callers: their result API settles one correlated physical turn and must not silently become a long-running logical goal operation.
The interactive app bundles make the opposite product choice. ACP defaults `goals` to the owner defaults and mounts the goal domain, model tools, same-session driver, command registry, and this producer. The terminal app enables the same goal stack by default but mounts the producer only for TUI mode; line-oriented stdio does not consume the command plane, so a typed `/goal` there remains an ordinary human prompt that the model may interpret through its separately authorized goal tools. Both apps accept `goals: false` as one coherent stack opt-out. The Python SDK runtime closure ships this producer alongside ACP, commands, and the goal stack so an external `cordis.yml` can compose the same command.
The interactive app bundles make the opposite product choice. ACP and TUI default `goals` to the owner defaults and mount the goal domain, model tools, same-session driver, command registry, and this producer. Both apps accept `goals: false` as one coherent stack opt-out. The Python SDK runtime closure ships this producer alongside ACP, commands, and the goal stack so an external `cordis.yml` can compose the same command.
## Testing
The producer suite uses the real command registry, goal service, agent registry, and session log. It covers Loader-safe exports, registry discovery, disposal, empty status, objective parsing, unfinished replacement refusal, inline edit, completed replacement, all missing-state controls, pause/resume/clear, every durable phase, blocked code/explanation presentation, armed/disarmed presentation, sanitized domain errors, unexpected failures, and persisted mutation records. App composition tests cover explicit spine opt-in, TUI/ACP defaults, readline producer absence, coherent opt-out, forwarded domain/tool config, command discovery, the packaged-runtime closure, and the expanded model-tool assembly. A keyless snapshot boots the shipped ACP application, observes its advertised `/goal` metadata, invokes `/goal` directly, and pins the no-model-turn result; the surrounding ACP snapshots also pin the goal tool schemas in that composition.
The producer suite uses the real command registry, goal service, agent registry, and session log. It covers Loader-safe exports, registry discovery, disposal, empty status, objective parsing, unfinished replacement refusal, inline edit, completed replacement, all missing-state controls, pause/resume/clear, every durable phase, blocked code/explanation presentation, armed/disarmed presentation, sanitized domain errors, unexpected failures, and persisted mutation records. App composition tests cover explicit spine opt-in, TUI/ACP defaults, coherent opt-out, forwarded domain/tool config, command discovery, the packaged-runtime closure, and the expanded model-tool assembly. A keyless snapshot boots the shipped ACP application, observes its advertised `/goal` metadata, invokes `/goal` directly, and pins the no-model-turn result; the surrounding ACP snapshots also pin the goal tool schemas in that composition.
## Alternatives considered
@@ -68,5 +68,5 @@ The producer suite uses the real command registry, goal service, agent registry,
- The portable command contract has no modal editor or confirmation interaction; inline edit and explicit clear are intentional until a general cross-surface interaction primitive exists.
- `/goal` does not accept a per-command round cap. Deployment config owns the default, and the authorized model tool can edit a cap after direct human instruction.
- TUI and ACP render portable plain text rather than a continuously updated goal status widget. Reconnectable command output and adapter-specific status indicators are deferred.
- The line-oriented stdio and JSON-RPC front doors do not consume the command registry.
- The headless CLI and JSON-RPC front doors do not consume the command registry.
- The command observes and mutates state but does not certify completion or blockers. Evaluator-backed certification remains deferred to a separate policy layer with an explicit authority and isolation contract.

View File

@@ -40,11 +40,11 @@ Status: implemented
`agent-spine-demo` 接受可选的 `goals` 组合对象,其中包含目标领域与模型工具的所有者配置。省略或设为 `false` 时不会挂载该栈。对无头单次调用方而言,明确选择加入非常重要:它们的结果 API 会在一个相关物理轮次后结束,不能静默变成长时间运行的逻辑目标操作。
交互式应用包作出相反的产品选择。ACP 默认让 `goals` 使用所有者默认值,并挂载目标领域、模型工具、同会话驱动器、命令注册表与本生产方。终端应用默认启用相同目标栈,但只在 TUI 模式挂载本生产方;行式 stdio 不消费命令平面,因此在那里输入的 `/goal` 仍是普通人类提示词,模型可以通过独立授权的目标工具解释它。两个应用都接受 `goals: false` 作为一致的整体退出选项。Python SDK 运行时闭包把本生产方与 ACP、命令及目标栈一并交付使外部 `cordis.yml` 能组合相同命令。
交互式应用包作出相反的产品选择。ACP 与 TUI 默认让 `goals` 使用所有者默认值,并挂载目标领域、模型工具、同会话驱动器、命令注册表与本生产方。两个应用都接受 `goals: false` 作为一致的整体退出选项。Python SDK 运行时闭包把本生产方与 ACP、命令及目标栈一并交付使外部 `cordis.yml` 能组合相同命令。
## 测试
生产方测试套件使用真实命令注册表、目标服务、agent 注册表与会话日志。它覆盖 Loader 安全导出、注册表发现、资源释放、空状态、目标描述解析、拒绝未完成目标替换、行内编辑、已完成目标替换、所有缺失状态控制、暂停/恢复/清除、每个持久阶段、阻塞代码/说明展示、已激活/未激活展示、经净化的领域错误、意外失败与持久变更记录。应用组合测试覆盖显式主干选择加入、TUI/ACP 默认值、readline 不挂载生产方、一致退出、转发的领域/工具配置、命令发现、打包运行时闭包与扩展后的模型工具组装。一个无密钥快照会启动交付的 ACP 应用,观察其公布的 `/goal` 元数据,直接调用 `/goal`,并固定不经过模型轮次的结果;周边 ACP 快照还会固定该组合中的目标工具 schema。
生产方测试套件使用真实命令注册表、目标服务、agent 注册表与会话日志。它覆盖 Loader 安全导出、注册表发现、资源释放、空状态、目标描述解析、拒绝未完成目标替换、行内编辑、已完成目标替换、所有缺失状态控制、暂停/恢复/清除、每个持久阶段、阻塞代码/说明展示、已激活/未激活展示、经净化的领域错误、意外失败与持久变更记录。应用组合测试覆盖显式主干选择加入、TUI/ACP 默认值、一致退出、转发的领域/工具配置、命令发现、打包运行时闭包与扩展后的模型工具组装。一个无密钥快照会启动交付的 ACP 应用,观察其公布的 `/goal` 元数据,直接调用 `/goal`,并固定不经过模型轮次的结果;周边 ACP 快照还会固定该组合中的目标工具 schema。
## 考虑过的替代方案
@@ -68,5 +68,5 @@ Status: implemented
- 可移植命令契约没有模态编辑器或确认交互;在出现通用跨表面交互原语之前,行内编辑与明确清除是有意选择。
- `/goal` 不接受逐命令回合上限。部署配置拥有默认值;得到直接人类指示后,已授权模型工具可以编辑上限。
- TUI 与 ACP 渲染可移植纯文本,而不是持续更新的目标状态组件。可重连命令输出和适配器专用状态指示器予以延期。
- 行式 stdio 与 JSON-RPC 前端不消费命令注册表。
- 无头 CLI 与 JSON-RPC 前端不消费命令注册表。
- 该命令观察并改变状态,但不认证完成或阻塞。基于评估器的认证延期到具有明确权限与隔离契约的独立策略层。

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-19-plugin-command-registration.md: c414f8183e100f712a552828992d108193fc33cf
2026-07-19-plugin-command-registration.zh.md: 3cd820c55ec30f3b2f6cf471376abfd8edd8ac5e
2026-07-19-plugin-command-registration.md: a207c6257bd4e9e4013f1abb661dd967ed2a52dc
2026-07-19-plugin-command-registration.zh.md: e21d187ded0ee0f4daa370655994eb306fb1c5fd

View File

@@ -78,4 +78,4 @@ TUI tests exercise all migrated built-ins, live plugin discovery, help/autocompl
- Input metadata is ACP's current unstructured text hint. Typed forms, argument schemas, and completion providers remain command-owned or require a later protocol extension.
- Generic command output is live-only and is not reconstructed after TUI restart or ACP reconnect.
- Registry cancellation stops awaiting immediately, but external work stops only when a handler cooperates with its signal.
- The shipped line-oriented `dsh-stdio` and JSON-RPC SDK front doors do not expose the command plane; only TUI and ACP consume it.
- The headless CLI and JSON-RPC SDK front doors do not expose the command plane; only TUI and ACP consume it.

View File

@@ -78,4 +78,4 @@ TUI 测试覆盖全部迁移后的内置命令、实时插件发现、帮助与
- 输入元数据仅为 ACP 当前的非结构化文本提示。类型化表单、参数模式和补全提供器仍由命令拥有,或需要后续协议扩展。
- 通用命令输出仅实时存在TUI 重启或 ACP 重新连接后不会重建。
- 注册表取消会立即停止等待,但外部工作只有在处理器配合信号时才会停止。
- 已发布的行式 `dsh-stdio` 与 JSON-RPC SDK 前端不暴露命令平面;只有 TUI 和 ACP 消费它。
- 无头 CLI 与 JSON-RPC SDK 前端不暴露命令平面;只有 TUI 和 ACP 消费它。