docs: rescan rebased documentation hierarchy
This commit is contained in:
@@ -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 packages/ui/README.md
|
||||
README.md: 76ca80e5685f70e73a6c46fe8d980f951b965ed3
|
||||
README.zh.md: 3958b0bdfb5d8cbab82f9fecfe54d12d462738ea
|
||||
README.md: 15754410a4a81eb3fc898dd55269ddd1637e1dab
|
||||
README.zh.md: 4023b80085998f57ed321bfda3a0abdd08b70a28
|
||||
|
||||
@@ -6,16 +6,12 @@ Human-facing channels and the out-of-process SDK server. These are **product** p
|
||||
|
||||
| Package | Role | ctx key |
|
||||
|---|---|---|
|
||||
| `commands/` | Human-command registry: shared discovery metadata, scoped shadowing, cancellation, and direct UI dispatch | `ctx.commands` |
|
||||
| `user-approval/` | One-shot user-approval mechanism, closed outcome vocabulary, audit events, and per-session approval policy | `ctx.approval` |
|
||||
| `permission/` | User-facing permission presets (`workspace-write`/`danger-full-access`): one product-level select bundling the sandbox-mode and approval-policy knobs, written through to their session events | `ctx.permission` |
|
||||
| `user-interaction/` | Abstract human question/answer seam used by UI-backed confirmation tools | `ctx.userInteraction` |
|
||||
| `tool-ask-user/` | Model-facing `ask_user_question` tool over `ctx.userInteraction` | (registers on `ctx.tools`) |
|
||||
| `jsonrpc/` | Stdio JSON-RPC server for out-of-process SDK clients | (drives `ctx.agents`) |
|
||||
| `app-boot/` | Shared boot glue for the app bins: `.env` loading, fail-loud Loader guards, snapshot-aware config resolution, the settle-the-tree boot sequence | (library for the bins) |
|
||||
| [`commands/`](commands/README.md) | Registers and dispatches human commands for interactive adapters. | `ctx.commands` |
|
||||
| [`user-approval/`](user-approval/README.md) | Coordinates one-shot approval decisions. | `ctx.approval` |
|
||||
| [`permission/`](permission/README.md) | Presents and persists user-facing permission presets. | `ctx.permission` |
|
||||
| [`user-interaction/`](user-interaction/README.md) | Defines the provider-neutral human question/answer seam. | `ctx.userInteraction` |
|
||||
| [`tool-ask-user/`](tool-ask-user/README.md) | Exposes human questions to the model. | (registers on `ctx.tools`) |
|
||||
| [`jsonrpc/`](jsonrpc/README.md) | Serves out-of-process SDK clients over stdio JSON-RPC. | (drives `ctx.agents`) |
|
||||
| [`app-boot/`](app-boot/README.md) | Provides shared boot support for application launchers. | (library for the bins) |
|
||||
|
||||
A UI integration is a client-driver plugin, not a loop change: it consumes the existing `agent/*` event taxonomy and the `dsh-agent` factory. [`jsonrpc`](jsonrpc/README.md) serves out-of-process SDK clients, while non-interactive one-shot tasks use `cli-demo`. [`commands`](commands/README.md) is the human-only discovery and dispatch plane for interactive adapters; command input and output do not become model messages.
|
||||
|
||||
`user-approval`, `user-interaction`, and `tool-ask-user` live here because asking a human is a UI-backed product affordance, not part of the providerless core spine. `user-approval` owns the one-shot `ctx.approval` decision mechanism and its policy tier; answerers remain with the channel or automation transport that owns the agent. `user-interaction` remains provider-neutral (`ctx.userInteraction`), while `tool-ask-user` is its model-facing consumer and interactive app packages provide concrete providers.
|
||||
|
||||
The runnable app bundles composed over [`agent-spine-demo`](../examples/agent-spine-demo/README.md) live in [`examples/`](../examples/README.md) (`cli-demo`, `acp-demo`, `jsonrpc-demo`), each with its own entry contract. The product [`dsh`](../../apps/cli/README.md) CLI uses no demo bundle. `ui/` keeps the reusable human/SDK channel plugins and shared `app-boot` glue; the automation-only ACP transport lives in [`acp/`](../acp/README.md). Each front door owns its stdout policy, and a leaf `cordis.yml` supplies backends and optional tools.
|
||||
These packages integrate through existing agent and session contracts rather than changing the loop. Interactive applications provide the concrete command, approval, and question adapters; automation uses [`acp/`](../acp/README.md), and runnable demo bundles live under [`examples/`](../examples/README.md). The product [`dsh`](../../apps/cli/README.md) CLI composes these packages directly.
|
||||
|
||||
@@ -2,20 +2,16 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
面向用户的交互通道和进程外 SDK 服务器。这些是**产品**包(package):由用户或 SDK 客户端直接操作的真实接口。
|
||||
面向用户的通道和进程外 SDK 服务器。这些是**产品**包:由用户或 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`) |
|
||||
| `jsonrpc/` | 面向进程外 SDK 客户端的 stdio JSON-RPC 服务器 | (驱动 `ctx.agents`) |
|
||||
| `app-boot/` | app bin 的共享启动粘合层:加载 `.env`、会明确报错的 Loader 保护机制、感知快照的配置解析,以及等待整棵树停稳的启动序列 | (供各 bin 使用的库) |
|
||||
| [`commands/`](commands/README.md) | 为交互式适配器注册并分派用户命令。 | `ctx.commands` |
|
||||
| [`user-approval/`](user-approval/README.md) | 协调一次性审批决策。 | `ctx.approval` |
|
||||
| [`permission/`](permission/README.md) | 呈现并持久化面向用户的权限预设。 | `ctx.permission` |
|
||||
| [`user-interaction/`](user-interaction/README.md) | 定义与提供方无关的用户问答 seam。 | `ctx.userInteraction` |
|
||||
| [`tool-ask-user/`](tool-ask-user/README.md) | 向模型公开用户问题。 | (注册到 `ctx.tools`) |
|
||||
| [`jsonrpc/`](jsonrpc/README.md) | 通过 stdio JSON-RPC 为进程外 SDK 客户端提供服务。 | (驱动 `ctx.agents`) |
|
||||
| [`app-boot/`](app-boot/README.md) | 为应用启动器提供共享启动支持。 | (供各 bin 使用的库) |
|
||||
|
||||
UI 集成属于由客户端驱动的插件,而非对循环的修改:它使用现有的 `agent/*` 事件分类和 `dsh-agent` 工厂。[`jsonrpc`](jsonrpc/README.md) 为进程外 SDK 客户端提供服务,非交互式的一次性任务则使用 `cli-demo`。[`commands`](commands/README.md) 是面向交互式适配器的仅面向用户的发现与分派通道;命令输入和输出不会成为模型消息。
|
||||
|
||||
`user-approval`、`user-interaction` 和 `tool-ask-user` 位于此处,因为向用户提问是由 UI 支持的产品功能,并不属于无提供方的核心主干。`user-approval` 负责一次性的 `ctx.approval` 决策机制及其策略层级;应答逻辑仍由负责 agent(智能体)的通道或自动化传输层提供。`user-interaction` 保持提供方无关(`ctx.userInteraction`),`tool-ask-user` 是其模型侧消费方,而交互式 app 包提供具体的提供方。
|
||||
|
||||
基于 [`agent-spine-demo`](../examples/agent-spine-demo/README.md) 组合的可运行 app bundle 位于 [`examples/`](../examples/README.md)(`cli-demo`、`acp-demo`、`jsonrpc-demo`),各自拥有入口契约。产品 [`dsh`](../../apps/cli/README.md) CLI(命令行界面)不使用 demo bundle。`ui/` 保留可复用的用户/SDK 通道插件和共享 `app-boot` 粘合层;仅供自动化使用的 ACP(Agent Client Protocol)传输层位于 [`acp/`](../acp/README.md)。每个入口都负责自己的 stdout 策略,叶子 `cordis.yml` 则提供后端与可选工具。
|
||||
这些包通过现有的 agent(智能体)和会话契约集成,而不改变循环。交互式应用提供具体的命令、审批和提问适配器;自动化使用 [`acp/`](../acp/README.md),可运行的演示组合包位于 [`examples/`](../examples/README.md)。产品 [`dsh`](../../apps/cli/README.md) CLI(命令行界面)直接组合这些包。
|
||||
|
||||
@@ -340,10 +340,10 @@ export async function watchPersonalPatches(
|
||||
try {
|
||||
return await register
|
||||
} catch (error) {
|
||||
// A surface can dispose the whole tree while the watcher is still opening
|
||||
// (a TUI `/exit` typed during startup): the HMR effect registration then
|
||||
// fails with INACTIVE_EFFECT. That is the app exiting exactly as asked,
|
||||
// not a watch failure — return a no-op disposer instead of crashing.
|
||||
// A surface can dispose the whole tree while the watcher is still opening;
|
||||
// the HMR effect registration then fails with INACTIVE_EFFECT. That is the
|
||||
// app exiting exactly as asked, not a watch failure, so return a no-op
|
||||
// disposer instead of crashing.
|
||||
if ((error as { code?: string } | null)?.code === 'INACTIVE_EFFECT') return async () => {}
|
||||
throw error
|
||||
}
|
||||
@@ -625,11 +625,10 @@ export async function boot(
|
||||
stage = 'plugin tree failed to load'
|
||||
await mountRootInclude(ctx, absoluteConfigPath, patches)
|
||||
// A surface can finish and dispose the whole tree while startup is still
|
||||
// in flight: the TUI renders as soon as its own fiber starts, so an `/exit`
|
||||
// typed before the last entry settles tears the context down under us. The
|
||||
// Loader service goes with it, and the activation audit describes a live
|
||||
// tree — reading `ctx.loader` past this point would throw a TypeError over
|
||||
// an app that exited exactly as asked. Transactional group updates settle
|
||||
// in flight, before the last entry settles. The Loader service goes with
|
||||
// it, and the activation audit describes a live tree — reading `ctx.loader`
|
||||
// past this point would throw a TypeError over an app that exited exactly
|
||||
// as asked. Transactional group updates settle
|
||||
// lifecycle inside the mount, so the teardown can land before it returns;
|
||||
// re-check after every await.
|
||||
await ctx.get('loader')?.await()
|
||||
|
||||
@@ -435,11 +435,10 @@ describe('boot', () => {
|
||||
})
|
||||
|
||||
it('returns instead of asserting over a tree a surface disposed mid-startup', async () => {
|
||||
// What a TUI `/exit` does (ui-tui's disposeRootAndExit): dispose the root
|
||||
// fiber, which lands while boot() is still awaiting the Loader whenever the
|
||||
// surface renders before the last entry settles. The Loader service goes
|
||||
// with the tree, so reading it for the post-boot assertions would crash an
|
||||
// app that exited exactly as the user asked.
|
||||
// A surface can dispose the root fiber while boot() is still awaiting the
|
||||
// Loader, before the last entry settles. The Loader service goes with the
|
||||
// tree, so reading it for the post-boot assertions would crash an app that
|
||||
// exited exactly as the user asked.
|
||||
const dir = tmp()
|
||||
writeFileSync(join(dir, 'exiting.mjs'), [
|
||||
'export const name = "exiting"',
|
||||
|
||||
@@ -344,9 +344,8 @@ describe('include patches layered over one base', () => {
|
||||
// The surface/`--config`/personal composition: `dsh` includes one shared
|
||||
// base and applies each source as its own patch list at the SAME include
|
||||
// level, because patches never cross an include boundary. A later layer
|
||||
// must therefore be able to reach a row an earlier layer inserted —
|
||||
// otherwise every surface-only row (the whole TUI front door) would be
|
||||
// invisible to the user's `~/.dsh/config.yaml`.
|
||||
// must therefore be able to reach a row an earlier layer inserted, or
|
||||
// surface-only rows would be invisible to the user's personal config.
|
||||
const dir = mkdtempSync(join(tmpdir(), 'dsh-config-layered-'))
|
||||
writeFileSync(join(dir, 'noop.mjs'), NOOP_PLUGIN)
|
||||
writeFileSync(join(dir, 'base.yml'), '- id: shared\n name: ./noop.mjs\n config:\n value: base\n')
|
||||
|
||||
@@ -235,11 +235,11 @@ describe('boot with personal patches', () => {
|
||||
})
|
||||
|
||||
it('returns a no-op disposer when the tree is disposed while the watcher opens', async () => {
|
||||
// A TUI `/exit` typed during startup disposes the whole tree while
|
||||
// registerConfig's effect registration is still in flight (the HMR effect
|
||||
// then fails with INACTIVE_EFFECT); the app is exiting exactly as asked,
|
||||
// so the watcher must not crash the process. The stub makes the race
|
||||
// deterministic — the live-teardown ordering itself is not stageable.
|
||||
// A surface can dispose the whole tree while registerConfig's effect
|
||||
// registration is still in flight (the HMR effect then fails with
|
||||
// INACTIVE_EFFECT); the app is exiting exactly as asked, so the watcher
|
||||
// must not crash the process. The stub makes the race deterministic — the
|
||||
// live-teardown ordering itself is not stageable.
|
||||
const dir = tmp()
|
||||
const ctx = await boot(NAME, writeTree(dir))
|
||||
try {
|
||||
|
||||
@@ -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 packages/ui/commands/README.md
|
||||
README.md: 4ad72cf9e232c8d41e525f42eecde5637032a391
|
||||
README.zh.md: ba214cb7a4c0370128b188db0a08fcd0bc4fa127
|
||||
README.md: a931628df28cb11ffb8e91068f7602a4a30cff94
|
||||
README.zh.md: e1ef7288ca7dca2945ec93d0ba23a3d1d6edf90c
|
||||
|
||||
@@ -16,7 +16,7 @@ Handlers return `success` or `error` plus optional UI text. Results are rendered
|
||||
|
||||
## Composition
|
||||
|
||||
The terminal app bundle mounts this service with `dsh-tui`; the UI-less agent spine and ACP automation app do not. Custom interactive compositions and command producers mount `@deepseek-ai/dsh-commands` explicitly.
|
||||
The shipped `dsh` base mounts this service and the Web client dispatches through it. UI-less demo spines and ACP automation do not provide a command adapter. Custom interactive compositions and command producers mount `@deepseek-ai/dsh-commands` explicitly.
|
||||
|
||||
## Model Experience
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
## 组合
|
||||
|
||||
终端应用组合包会将此服务与 `dsh-tui` 一起挂载;无 UI 的 agent 主干和 ACP(Agent Client Protocol)自动化应用不会挂载它。自定义交互式组合与命令生产方会显式挂载 `@deepseek-ai/dsh-commands`。
|
||||
随产品交付的 `dsh` 基础组合会挂载此服务,Web 客户端通过它分派命令。无 UI 的演示主干和 ACP(Agent Client Protocol)自动化不提供命令适配器。自定义交互式组合与命令生产方会显式挂载 `@deepseek-ai/dsh-commands`。
|
||||
|
||||
## 模型体验
|
||||
|
||||
|
||||
@@ -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 packages/ui/user-interaction/README.md
|
||||
README.md: c7fec590d6e44a13b94cc682f5e069b2d3c5e416
|
||||
README.zh.md: 094cd2bf81eafc7d4f24385cfb30e97478cbb58d
|
||||
README.md: 7d3c4e87c018e42794d319b540fd0a94abc9b43c
|
||||
README.zh.md: 0e5d15a673c124abab4b13e869623df1a5c63acd
|
||||
|
||||
@@ -28,7 +28,7 @@ For a single-select question, `custom` overrides the selected choice and `select
|
||||
|
||||
## Role
|
||||
|
||||
This is the interface package. Model-facing consumers such as `@deepseek-ai/dsh-tool-ask-user` depend on this seam; `dsh-tui` and the host runtime provide interactive implementations. The loop stays unchanged: a tool call awaits a promise, and the tool result resumes the normal agent loop.
|
||||
This is the interface package. Model-facing consumers such as `@deepseek-ai/dsh-tool-ask-user` depend on this seam; the Web host runtime provides the shipped interactive implementation. The loop stays unchanged: a tool call awaits a promise, and the tool result resumes the normal agent loop.
|
||||
|
||||
## Model Experience
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
## 职责
|
||||
|
||||
这是接口包。`@deepseek-ai/dsh-tool-ask-user` 等面向模型的消费方依赖此 seam;`dsh-tui` 和宿主运行时提供交互式实现。循环保持不变:工具调用等待 Promise,工具结果随后恢复正常的 agent loop(智能体循环)。
|
||||
这是接口包。`@deepseek-ai/dsh-tool-ask-user` 等面向模型的消费方依赖此 seam;Web 宿主运行时提供随产品交付的交互式实现。循环保持不变:工具调用等待 Promise,工具结果随后恢复正常的 agent loop(智能体循环)。
|
||||
|
||||
## 模型体验
|
||||
|
||||
|
||||
Reference in New Issue
Block a user