dsh-plugin-guide 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.es.md +5 -1
- package/README.hi.md +5 -1
- package/README.md +5 -1
- package/README.pt.md +5 -1
- package/README.zh.md +5 -1
- package/dist/dsh-plugin-dev.js +3 -3
- package/guide/plugin-dev-guide.md +2 -2
- package/guide/quick-reference.es.md +2 -2
- package/guide/quick-reference.hi.md +1 -1
- package/guide/quick-reference.md +2 -2
- package/guide/quick-reference.pt.md +2 -2
- package/guide/quick-reference.zh-CN.md +2 -2
- package/package.json +3 -3
- package/references/official-docs/AGENTS.md +3 -3
- package/references/official-docs/SNAPSHOT.md +4 -4
- package/references/official-docs/THIRD_PARTY_NOTICES.md +4 -6
- package/references/official-docs/docs/agent-lifecycle.i18n.yaml +2 -2
- package/references/official-docs/docs/agent-lifecycle.md +5 -3
- package/references/official-docs/docs/agent-lifecycle.zh.md +5 -3
- package/references/official-docs/docs/architecture.i18n.yaml +2 -2
- package/references/official-docs/docs/architecture.md +9 -4
- package/references/official-docs/docs/architecture.zh.md +9 -4
- package/references/official-docs/docs/capability-seams.i18n.yaml +2 -2
- package/references/official-docs/docs/capability-seams.md +8 -1
- package/references/official-docs/docs/capability-seams.zh.md +8 -1
- package/references/official-docs/docs/config-catalog.i18n.yaml +2 -2
- package/references/official-docs/docs/config-catalog.md +104 -68
- package/references/official-docs/docs/config-catalog.zh.md +101 -65
- package/references/official-docs/docs/cookbook/adding-a-package.i18n.yaml +2 -2
- package/references/official-docs/docs/cookbook/adding-a-package.md +1 -1
- package/references/official-docs/docs/cookbook/adding-a-package.zh.md +1 -1
- package/references/official-docs/docs/cookbook/extension-cookbook.i18n.yaml +2 -2
- package/references/official-docs/docs/cookbook/extension-cookbook.md +12 -10
- package/references/official-docs/docs/cookbook/extension-cookbook.zh.md +12 -10
- package/references/official-docs/docs/deepseek-llm-api-wire-extensions.i18n.yaml +2 -2
- package/references/official-docs/docs/deepseek-llm-api-wire-extensions.md +16 -12
- package/references/official-docs/docs/deepseek-llm-api-wire-extensions.zh.md +16 -12
- package/references/official-docs/docs/event-producer-consumer.i18n.yaml +2 -2
- package/references/official-docs/docs/event-producer-consumer.md +30 -29
- package/references/official-docs/docs/event-producer-consumer.zh.md +35 -34
- package/references/official-docs/docs/module-graph.i18n.yaml +2 -2
- package/references/official-docs/docs/module-graph.md +214 -360
- package/references/official-docs/docs/module-graph.zh.md +214 -360
- package/references/official-docs/docs/persistence-catalog.i18n.yaml +2 -2
- package/references/official-docs/docs/persistence-catalog.md +74 -64
- package/references/official-docs/docs/persistence-catalog.zh.md +72 -62
- package/references/official-docs/docs/subsystems/agent-team.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/agent-team.md +4 -3
- package/references/official-docs/docs/subsystems/agent-team.zh.md +4 -3
- package/references/official-docs/docs/subsystems/attachment.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/attachment.md +157 -4
- package/references/official-docs/docs/subsystems/attachment.zh.md +157 -4
- package/references/official-docs/docs/subsystems/code-runtime.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/code-runtime.md +7 -3
- package/references/official-docs/docs/subsystems/code-runtime.zh.md +7 -3
- package/references/official-docs/docs/subsystems/commands.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/commands.md +25 -16
- package/references/official-docs/docs/subsystems/commands.zh.md +25 -16
- package/references/official-docs/docs/subsystems/compaction.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/compaction.md +9 -9
- package/references/official-docs/docs/subsystems/compaction.zh.md +9 -9
- package/references/official-docs/docs/subsystems/conversation.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/conversation.md +4 -4
- package/references/official-docs/docs/subsystems/conversation.zh.md +4 -4
- package/references/official-docs/docs/subsystems/core.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/core.md +66 -4
- package/references/official-docs/docs/subsystems/core.zh.md +66 -4
- package/references/official-docs/docs/subsystems/feedback.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/feedback.md +2 -2
- package/references/official-docs/docs/subsystems/feedback.zh.md +2 -2
- package/references/official-docs/docs/subsystems/llm-streaming.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/llm-streaming.md +23 -2
- package/references/official-docs/docs/subsystems/llm-streaming.zh.md +23 -2
- package/references/official-docs/docs/subsystems/persistence.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/persistence.md +183 -191
- package/references/official-docs/docs/subsystems/persistence.zh.md +183 -191
- package/references/official-docs/docs/subsystems/schedule.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/schedule.md +1 -1
- package/references/official-docs/docs/subsystems/schedule.zh.md +1 -1
- package/references/official-docs/docs/subsystems/session-projection.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/session-projection.md +40 -17
- package/references/official-docs/docs/subsystems/session-projection.zh.md +40 -17
- package/references/official-docs/docs/subsystems/session-query.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/session-query.md +19 -13
- package/references/official-docs/docs/subsystems/session-query.zh.md +19 -13
- package/references/official-docs/docs/subsystems/session-reference.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/session-reference.md +25 -1
- package/references/official-docs/docs/subsystems/session-reference.zh.md +25 -1
- package/references/official-docs/docs/subsystems/session-telemetry.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/session-telemetry.md +6 -5
- package/references/official-docs/docs/subsystems/session-telemetry.zh.md +6 -5
- package/references/official-docs/docs/subsystems/session-title.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/session-title.md +5 -5
- package/references/official-docs/docs/subsystems/session-title.zh.md +5 -5
- package/references/official-docs/docs/subsystems/session.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/session.md +143 -71
- package/references/official-docs/docs/subsystems/session.zh.md +143 -71
- package/references/official-docs/docs/subsystems/slots.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/slots.md +1 -0
- package/references/official-docs/docs/subsystems/slots.zh.md +1 -0
- package/references/official-docs/docs/subsystems/storage.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/storage.md +28 -5
- package/references/official-docs/docs/subsystems/storage.zh.md +28 -5
- package/references/official-docs/docs/subsystems/subagent.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/subagent.md +32 -88
- package/references/official-docs/docs/subsystems/subagent.zh.md +31 -87
- package/references/official-docs/docs/subsystems/token-meter.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/token-meter.md +2 -2
- package/references/official-docs/docs/subsystems/token-meter.zh.md +2 -2
- package/references/official-docs/docs/subsystems/web-client.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/web-client.md +1 -1
- package/references/official-docs/docs/subsystems/web-client.zh.md +1 -1
- package/references/official-docs/docs/subsystems/workspace.i18n.yaml +2 -2
- package/references/official-docs/docs/subsystems/workspace.md +8 -8
- package/references/official-docs/docs/subsystems/workspace.zh.md +8 -8
- package/references/official-docs/docs/testing.i18n.yaml +2 -2
- package/references/official-docs/docs/testing.md +2 -2
- package/references/official-docs/docs/testing.zh.md +2 -2
- package/references/official-docs/docs/tool-catalog.i18n.yaml +2 -2
- package/references/official-docs/docs/tool-catalog.md +9 -63
- package/references/official-docs/docs/tool-catalog.zh.md +8 -62
- package/references/official-docs/docs/user/guide/network-proxy.i18n.yaml +6 -0
- package/references/official-docs/docs/user/guide/network-proxy.md +85 -0
- package/references/official-docs/docs/user/guide/network-proxy.zh.md +85 -0
- package/references/official-docs/docs/user/guide/providers.i18n.yaml +2 -2
- package/references/official-docs/docs/user/guide/providers.md +70 -17
- package/references/official-docs/docs/user/guide/providers.zh.md +70 -17
- package/references/official-docs/docs/web-styling.i18n.yaml +2 -2
- package/references/official-docs/docs/web-styling.md +4 -0
- package/references/official-docs/docs/web-styling.zh.md +4 -0
- package/references/official-docs/packages/AGENTS.md +2 -2
- package/references/official-docs/website-docs.ts +8 -0
- package/templates/js/README.es.md +1 -1
- package/templates/js/README.hi.md +1 -1
- package/templates/js/README.md +1 -1
- package/templates/js/README.pt.md +1 -1
- package/templates/js/README.zh.md +1 -1
- package/templates/ts/README.es.md +1 -1
- package/templates/ts/README.hi.md +1 -1
- package/templates/ts/README.md +1 -1
- package/templates/ts/README.pt.md +1 -1
- package/templates/ts/README.zh.md +1 -1
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write docs/subsystems/web-client.md
|
|
5
|
-
web-client.md:
|
|
6
|
-
web-client.zh.md:
|
|
5
|
+
web-client.md: 7e7f483131585dc66c45dbb147d40e848f40d6d1
|
|
6
|
+
web-client.zh.md: 603af505dbd1fc6e2f9fd3bf9542ce19cb63732f
|
|
@@ -55,7 +55,7 @@ This pairing is not a second source of business truth. Host controllers decide d
|
|
|
55
55
|
|
|
56
56
|
`ui-session` installs the `session` scope adapter and publishes `useSessions`, `useSession`, `sessionId`, and `useProjection`. Domain adapters add further standard sources without putting React hooks on the model objects.
|
|
57
57
|
|
|
58
|
-
`ui-conversation` binds once to each `SessionBinding.eventSource`. Its event registry correlates
|
|
58
|
+
`ui-conversation` binds once to each `SessionBinding.eventSource`. Its event registry correlates durable Session events and Client-only `assistant/live-chunk` updates into stable business Contexts, and its view registry materializes target snapshots. Chat Assistant, Trajectory Assistant, and Turn Tail interpret both live chunks and the compact streams embedded in durable settlements, so reconnect and paged history reproduce the same Assistant state without durable token rows. `ui-chat` and `ui-trajectory` register separate Definitions and builders: they may interpret the same event family, but they do not import or share each other's final display model. The shell selects a registered view and passes its snapshot through standard hooks and Slots. [Conversation](conversation.md) defines Context identity, replay, Location data, target builders, and keyed renderers.
|
|
59
59
|
|
|
60
60
|
`ui-slots` provides the typed registry and lifecycle ledger; `ui-renderer` is the only package that binds bare observables through `useSyncExternalStore`, owns React contexts, and renders the root tree. Feature components receive framework hooks, owner props, store actions, and explicit injection through their derived props. [Web Client Slots](slots.md) lists those inputs, extension APIs, and the current Slot hierarchy.
|
|
61
61
|
|
|
@@ -55,7 +55,7 @@ Connection 拥有 request correlation、`/api` carrier、trust check、精确 Fe
|
|
|
55
55
|
|
|
56
56
|
`ui-session` 安装 `session` scope adapter,并提供 `useSessions`、`useSession`、`sessionId` 和 `useProjection`。领域 adapter 可以继续添加标准 source,但不会把 React hook 放进 model object。
|
|
57
57
|
|
|
58
|
-
`ui-conversation` 对每个 `SessionBinding.eventSource` 只绑定一次。它的 event registry
|
|
58
|
+
`ui-conversation` 对每个 `SessionBinding.eventSource` 只绑定一次。它的 event registry 把持久 Session event 与 Client-only `assistant/live-chunk` update 关联成稳定的业务 Context,view registry 则 materialize target snapshot。Chat Assistant、Trajectory Assistant 与 Turn Tail 同时解释 live chunk 和持久 settlement 中嵌入的紧凑 stream,因此重连与分页历史无需持久 token 行即可复现相同 Assistant 状态。`ui-chat` 与 `ui-trajectory` 分别注册自己的 Definition 和 builder:它们可以解释同一 event family,但不会导入或共享彼此的最终 display model。Shell 选择一个已注册 view,再通过标准 hook 与 Slot 交付其 snapshot。[Conversation](conversation.zh.md)定义 Context identity、replay、Location data、target builder 与 keyed renderer。
|
|
59
59
|
|
|
60
60
|
`ui-slots` 提供类型化 registry 与 lifecycle ledger;`ui-renderer` 是唯一通过 `useSyncExternalStore` 绑定裸 observable、拥有 React context 并渲染 root tree 的包。功能 component 通过推导出的 props 接收 framework hook、owner prop、store action 与显式 injection。[Web Client Slots](slots.zh.md)列出这些输入、扩展 API 与当前 Slot 层级。
|
|
61
61
|
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write docs/subsystems/workspace.md
|
|
5
|
-
workspace.md:
|
|
6
|
-
workspace.zh.md:
|
|
5
|
+
workspace.md: 3c53300a5be6678802da950d22854da76fa46bf1
|
|
6
|
+
workspace.zh.md: b651a21f7641619c28bad9d3fdf368c718ca2c29
|
|
@@ -40,7 +40,7 @@ interface Workspace {
|
|
|
40
40
|
*/
|
|
41
41
|
readonly path: string
|
|
42
42
|
|
|
43
|
-
/** Display title. Defaults to
|
|
43
|
+
/** Display title. Defaults to the final path segment, or a filesystem root's own spelling; duplicates are allowed. */
|
|
44
44
|
readonly title: string
|
|
45
45
|
|
|
46
46
|
/** ISO-8601 creation instant, stamped at create and never rewritten. */
|
|
@@ -117,7 +117,7 @@ Ownership truth is the record's ordered `sessionIds`, never derived from session
|
|
|
117
117
|
|
|
118
118
|
## The registry: `ctx.workspaceRegistry`
|
|
119
119
|
|
|
120
|
-
`WorkspaceRegistry` ([signatures](#ctxworkspaceregistry--workspaceregistry)) owns registration and resolution. `create(path, title?)`
|
|
120
|
+
`WorkspaceRegistry` ([signatures](#ctxworkspaceregistry--workspaceregistry)) owns registration and resolution. `create(path, title?)` requires a fully qualified path, canonicalizes it, rejects a nonexistent path (the original `ENOENT`) or a non-directory, returns the existing entity unchanged when the canonical path is already owned, and otherwise creates a record with `title ?? defaultWorkspaceTitle(path)` prepended to the durable registry order (different canonical paths may share a display title, and a path with no final segment uses its root spelling). `get(id)` and the ordered `list()` are synchronous cache reads; `resolveByPath(path)` applies the same fully qualified realpath canon without creating. `delete(id)` removes only the registration, order entry, and session account — the directory, user files, live sessions, and persisted logs are never touched, so those sessions become Ungrouped ([decision](../../.agents/notes/implemented/feature/2026-07-27-workspace-registration-deletion.md)); unknown ids return `false`. Create and delete persist a pending-mutation marker before their two writes (record + order) can diverge; startup resolves exactly the marked mutation — by deleting the marked table row, which completes an interrupted delete and rolls back an interrupted create (the registration is re-creatable, so rollback is the safe direction) — and an unmarked order/table mismatch fails loud as corruption.
|
|
121
121
|
|
|
122
122
|
Sessions get their cwd at create time from whoever creates them, not from this registry — the API gateway resolves a new session's cwd from the chosen workspace's `path` (falling back to an explicit or default cwd), creates the session so the cwd lands in its immutable [`SessionHeader`](persistence.md#sessionheader--metadata-beside-the-log), then calls `attachSession`, which re-validates that stored header cwd against the workspace path. On the first successful start, the registry bootstraps history from persisted headers alone (`id`, `cwd`, `createdAt` — never event bodies), grouping sessions with a valid canonical cwd into per-directory workspaces, newest first; the initialized marker is written last so an interrupted bootstrap resumes safely. The bootstrap is one-time: cwd-less legacy sessions stay Ungrouped, and sessions created afterwards join a workspace only through `attachSession`.
|
|
123
123
|
|
|
@@ -250,13 +250,13 @@ Durable workspace registry. Startup waits for `sessionPersistence`, builds one c
|
|
|
250
250
|
|
|
251
251
|
```ts cordis-catalog
|
|
252
252
|
/**
|
|
253
|
-
* Create or reuse a workspace for an existing directory. The
|
|
254
|
-
* canonicalized through `fs.realpath`; a nonexistent
|
|
255
|
-
*
|
|
256
|
-
*
|
|
253
|
+
* Create or reuse a workspace for an existing directory. The fully qualified
|
|
254
|
+
* path is canonicalized through `fs.realpath`; a relative, nonexistent, or
|
|
255
|
+
* non-directory path rejects. Repeated calls for the same canonical path
|
|
256
|
+
* return the existing entity without changing its title.
|
|
257
257
|
* A newly created workspace is prepended to the durable registry order.
|
|
258
258
|
* Different canonical paths may share a display title.
|
|
259
|
-
* @param path - Existing directory to own, in
|
|
259
|
+
* @param path - Existing directory to own, in a fully qualified path spelling.
|
|
260
260
|
* @param title - Display title used only when a new record is created.
|
|
261
261
|
* @returns the existing or newly durable workspace.
|
|
262
262
|
*/
|
|
@@ -309,7 +309,7 @@ archiveSession(sessionId: SessionId): Promise<void>
|
|
|
309
309
|
* Resolve by canonical directory path without creating or mutating a
|
|
310
310
|
* workspace. A missing path rejects during `realpath`; an existing unowned
|
|
311
311
|
* directory returns `undefined`.
|
|
312
|
-
* @param path - Existing directory path in
|
|
312
|
+
* @param path - Existing directory path in a fully qualified spelling.
|
|
313
313
|
* @returns the workspace owning the canonical path, when one exists.
|
|
314
314
|
*/
|
|
315
315
|
async resolveByPath(path: string): Promise<Workspace | undefined>
|
|
@@ -40,7 +40,7 @@ interface Workspace {
|
|
|
40
40
|
*/
|
|
41
41
|
readonly path: string
|
|
42
42
|
|
|
43
|
-
/** Display title. Defaults to
|
|
43
|
+
/** Display title. Defaults to the final path segment, or a filesystem root's own spelling; duplicates are allowed. */
|
|
44
44
|
readonly title: string
|
|
45
45
|
|
|
46
46
|
/** ISO-8601 creation instant, stamped at create and never rewritten. */
|
|
@@ -117,7 +117,7 @@ interface Workspace {
|
|
|
117
117
|
|
|
118
118
|
## 注册表:`ctx.workspaceRegistry`
|
|
119
119
|
|
|
120
|
-
`WorkspaceRegistry`([签名](#ctxworkspaceregistry--workspaceregistry))拥有注册与解析。`create(path, title?)`
|
|
120
|
+
`WorkspaceRegistry`([签名](#ctxworkspaceregistry--workspaceregistry))拥有注册与解析。`create(path, title?)` 要求完全限定路径并将其规范化,拒绝不存在的路径(原样传出原始 `ENOENT`)或非目录;当规范路径已被拥有时原样返回既有实体;否则创建一条标题为 `title ?? defaultWorkspaceTitle(path)` 的记录并前插到持久的注册表顺序中(不同规范路径可以共享同一显示标题,没有最终路径段时使用根路径拼写)。`get(id)` 与有序的 `list()` 是同步缓存读取;`resolveByPath(path)` 应用同一套完全限定 realpath 规范但不创建。`delete(id)` 只移除注册记录、顺序条目和会话账本——目录、用户文件、实时会话和已持久化日志一概不动,因此这些会话变为 Ungrouped([决策](../../.agents/notes/implemented/feature/2026-07-27-workspace-registration-deletion.zh.md));未知 id 返回 `false`。create 与 delete 会在其两次写入(记录 + 顺序)可能分叉之前先持久写入一个待定变更标记;启动时恰好解决被标记的那次变更——通过删除被标记的表行:这会补完被中断的 delete,并回滚被中断的 create(注册可以重建,因此回滚是安全方向)——而没有标记的顺序/表不一致则作为损坏大声失败。
|
|
121
121
|
|
|
122
122
|
会话的 cwd 在创建时由创建者赋予,而不是由本注册表赋予——API 网关从所选工作区的 `path` 解析新会话的 cwd(回退到显式或默认 cwd),先创建会话使 cwd 落入其不可变的 [`SessionHeader`](persistence.zh.md#sessionheader--metadata-beside-the-log),再调用 `attachSession`,后者会把已存储的 header cwd 与工作区路径重新校验一遍。首次成功启动时,注册表仅凭已持久化的 header(`id`、`cwd`、`createdAt`——绝不读事件正文)引导历史:把规范 cwd 有效的会话按目录分组为工作区,最新的排在最前;「已初始化」标记最后写入,因此被中断的引导可以安全续跑。引导只发生这一次:没有 cwd 的历史遗留会话保持 Ungrouped,此后创建的会话只能通过 `attachSession` 加入工作区。
|
|
123
123
|
|
|
@@ -250,13 +250,13 @@ Durable workspace registry. Startup waits for `sessionPersistence`, builds one c
|
|
|
250
250
|
|
|
251
251
|
```ts cordis-catalog
|
|
252
252
|
/**
|
|
253
|
-
* Create or reuse a workspace for an existing directory. The
|
|
254
|
-
* canonicalized through `fs.realpath`; a nonexistent
|
|
255
|
-
*
|
|
256
|
-
*
|
|
253
|
+
* Create or reuse a workspace for an existing directory. The fully qualified
|
|
254
|
+
* path is canonicalized through `fs.realpath`; a relative, nonexistent, or
|
|
255
|
+
* non-directory path rejects. Repeated calls for the same canonical path
|
|
256
|
+
* return the existing entity without changing its title.
|
|
257
257
|
* A newly created workspace is prepended to the durable registry order.
|
|
258
258
|
* Different canonical paths may share a display title.
|
|
259
|
-
* @param path - Existing directory to own, in
|
|
259
|
+
* @param path - Existing directory to own, in a fully qualified path spelling.
|
|
260
260
|
* @param title - Display title used only when a new record is created.
|
|
261
261
|
* @returns the existing or newly durable workspace.
|
|
262
262
|
*/
|
|
@@ -309,7 +309,7 @@ archiveSession(sessionId: SessionId): Promise<void>
|
|
|
309
309
|
* Resolve by canonical directory path without creating or mutating a
|
|
310
310
|
* workspace. A missing path rejects during `realpath`; an existing unowned
|
|
311
311
|
* directory returns `undefined`.
|
|
312
|
-
* @param path - Existing directory path in
|
|
312
|
+
* @param path - Existing directory path in a fully qualified spelling.
|
|
313
313
|
* @returns the workspace owning the canonical path, when one exists.
|
|
314
314
|
*/
|
|
315
315
|
async resolveByPath(path: string): Promise<Workspace | undefined>
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write docs/testing.md
|
|
5
|
-
testing.md:
|
|
6
|
-
testing.zh.md:
|
|
5
|
+
testing.md: fbf075ecde1dc38b816bcfbbee551f2e1a8178e0
|
|
6
|
+
testing.zh.md: 6b5e553b3089d30f104947b8570e6388d807758f
|
|
@@ -10,10 +10,10 @@ How this repo tests, tier by tier, and the rules that keep a green suite meaning
|
|
|
10
10
|
- **Coverage gate** (`pnpm run test:coverage`): the gating run, per-file 100% on `packages/*/*/src`. An uncovered line is often dead code the gate flags for deletion, not a missing test to bolt on. Line coverage is necessary, never sufficient — it proves lines ran, not that the feature works as shipped. Per-file 100% on `packages/shell/pwsh-local/src` needs a real `pwsh`: without one its executor suites self-skip and `vitest.config.ts` exempts the file so pwsh-less hosts stay green, while CI runners ship pwsh and enforce the full bar.
|
|
11
11
|
- **Real-API e2e** (`pnpm run test:e2e`): with-key tests against live provider APIs — the DeepSeek model plus provider-specific smokes that gate on their own keys (`EXA_API_KEY`, `PERPLEXITY_API_KEY`, …); each suite self-skips without its key so keyless CI stays green ([real-API e2e Agent Note](../.agents/notes/implemented/testing/2026-06-19-real-api-e2e-ci.md)).
|
|
12
12
|
- **Owner-local expected output** (`pnpm run test:expected`): keyless assembled CLI/process expectations without a recorded-session round trip. Drivers use `*.expected.e2e.ts` beside `tests/expected/`; CI runs built exports. Package/script expectations use `test`, while browser expectations use `test:web`.
|
|
13
|
-
- **Snapshot** (`pnpm run test:snapshot`): a top-level scenario's recorded
|
|
13
|
+
- **Snapshot** (`pnpm run test:snapshot`): a top-level scenario's highest recorded parent generation supplies user input and model replay, then serves as the expected persisted result. Parent filenames are `session[.vN].jsonl`; child roles are `session.<ordinal>[.vN].jsonl`; v0 omits `.v0`, positive versions require lowercase `.vN`, and each filename must agree with its header. Process scenarios start through `dsh`: headless owns one-shot behavior, the SDK owns persistent control, ACP owns automation-protocol behavior, and Web retains browser/ARIA evidence beside the same Session. `snapshot.yml` declares the profile, composition/header class, recording policy, exceptional replay or input metadata, and workspace facts. Typed tokens preserve parent/child identity relationships; only header pins own prompt/schema sidecars. A mutating scenario independently compares the complete `workspace.expected/` tree, which record and refresh never rewrite. Use `test:snapshot:record` when a model transcript changes and `test:snapshot:refresh` when replay input remains valid; review every resulting diff.
|
|
14
14
|
- **Web browser snapshot** (`pnpm run test:web`; required Linux PR gate): Chromium compares session-driven output under `snapshots/web/` and UI-only output under `apps/web/tests/expected/`. CI forces read-only `DSH_SNAPSHOT=replay`, never writing expected outputs; record/refresh stay local and every diff is reviewed ([web e2e lane](../.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.md), [CI gate decision](../.agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.md)). `test:web` [builds first](../.agents/notes/implemented/bug-fix/2026-07-28-themed-scrollbars-and-reserved-gutter.md) for plugin CSS.
|
|
15
15
|
|
|
16
|
-
Session fixtures
|
|
16
|
+
Session fixtures retain headers and payloads but omit body sequence/time envelopes; replay synthesizes them. Replay, record, and refresh select each parent/child role's highest generation. Current v2 uses `.v2`, one row per event, and embedded compact Assistant streams; retained v0 (suffixless) and v1 (`.v1`) may keep canonical packed rows for migration coverage. [The migrator](../scripts/migrate-packed-session-fixtures.ts) rewrites older historical layouts.
|
|
17
17
|
|
|
18
18
|
## How specs execute
|
|
19
19
|
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
- **覆盖率门禁**(`pnpm run test:coverage`):门禁级运行,对 `packages/*/*/src` 按文件 100% 覆盖。未覆盖的行往往是门禁正确标记出的死代码(应删除),而非需要补写的测试。行覆盖率是必要条件,但永远不是充分条件:它证明行被执行过,不证明功能按交付预期工作。`packages/shell/pwsh-local/src` 的按文件 100% 覆盖需要真实的 `pwsh`:缺少它时其执行器套件会自动跳过,`vitest.config.ts` 会豁免该文件以使无 pwsh 的主机保持绿色,而 CI runner 自带 pwsh,仍按完整标准执行门禁。
|
|
11
11
|
- **真实 API e2e**(`pnpm run test:e2e`):带密钥测试调用真实提供方 API,包括 DeepSeek 模型以及各提供方特有的冒烟测试;这些测试各自由自己的密钥控制(`EXA_API_KEY`、`PERPLEXITY_API_KEY` 等),缺少密钥时套件会自动跳过,使 keyless CI 保持绿色([真实 API e2e Agent Note](../.agents/notes/implemented/testing/2026-06-19-real-api-e2e-ci.zh.md))。
|
|
12
12
|
- **所属位置的预期输出**(`pnpm run test:expected`):无录制会话往返的无密钥组装 CLI/进程预期。驱动使用 `*.expected.e2e.ts`,并与 `tests/expected/` 同属一处;CI 针对构建产物运行。包/脚本预期使用 `test`,浏览器预期使用 `test:web`。
|
|
13
|
-
- **快照**(`pnpm run test:snapshot
|
|
13
|
+
- **快照**(`pnpm run test:snapshot`):顶层场景数值最高的已录制 parent generation 同时提供用户输入和模型回放,并作为持久化结果的预期值。parent 文件名是 `session[.vN].jsonl`;child 角色使用 `session.<ordinal>[.vN].jsonl`;v0 省略 `.v0`,正版本必须使用小写 `.vN`,且每个文件名必须与其 header 一致。进程级场景都通过 `dsh` 启动:headless 负责一次性行为,SDK 负责持久控制,ACP 负责自动化协议行为,Web 在同一 Session 旁保留浏览器与 ARIA 证据。`snapshot.yml` 声明 profile、组合与请求头类别、录制策略、例外回放或输入元数据以及 workspace 事实。带类型的 token 保留父子身份关系;只有请求头 pin 拥有 prompt/schema sidecar。变更 workspace 的场景会独立比较完整的 `workspace.expected/` 目录,record 与 refresh 绝不改写该目录。当模型 transcript(文本记录)变化时使用 `test:snapshot:record`,回放输入仍有效时使用 `test:snapshot:refresh`;请审查所有结果差异。
|
|
14
14
|
- **Web 浏览器快照**(`pnpm run test:web`;必需的 Linux PR(Pull Request)门禁):Chromium 比较 `snapshots/web/` 下由会话驱动的输出,以及 `apps/web/tests/expected/` 下仅含 UI 的输出。CI 强制只读的 `DSH_SNAPSHOT=replay`,绝不写入预期输出;record/refresh 留在本地,每处 diff 都须评审([web e2e 车道](../.agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.zh.md)、[CI 门禁决策](../.agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.zh.md))。`test:web` 会[先构建](../.agents/notes/implemented/bug-fix/2026-07-28-themed-scrollbars-and-reserved-gutter.zh.md)以交付插件 CSS。
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Session fixture 保留 header 与 payload,但省略正文 seq/time envelope;replay 会合成这些 envelope。Replay、record 与 refresh 会选择每个 parent/child 角色的最高 generation。当前 v2 使用 `.v2`、每个事件一行,并嵌入紧凑 Assistant stream;保留的 v0(无后缀)与 v1(`.v1`)可以为迁移覆盖保留规范 packed row。[迁移器](../scripts/migrate-packed-session-fixtures.ts)会改写更旧的历史布局。
|
|
17
17
|
|
|
18
18
|
## spec 如何被执行
|
|
19
19
|
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write docs/tool-catalog.md
|
|
5
|
-
tool-catalog.md:
|
|
6
|
-
tool-catalog.zh.md:
|
|
5
|
+
tool-catalog.md: 416585106de28296a3105fafbbe6e4edc0d0f16b
|
|
6
|
+
tool-catalog.zh.md: 89d2e467863c09b78805fd9db8ec785ad7936a9d
|
|
@@ -35,9 +35,8 @@ This table connects model-visible tool names to the plugin package and service s
|
|
|
35
35
|
| `@deepseek-ai/dsh-tool-session-query` | `session_event_read`, `session_event_search`, `session_event_trace`, `session_search`, `session_trace` | `ctx.tools`, `ctx.systemPrompt`, `ctx.sessionQuery`, `a calling Agent for workspace authority` | `tool/call`, `tool/result` | - | The five read-only tools hide provider cursors and authorize every result from the immutable calling agent session. The package is opt-in; compositions that need enforced deadlines or bounded inline output also mount the generic timeout or spill policies. |
|
|
36
36
|
| `@deepseek-ai/dsh-tool-subagent` | `list_subagent_models`, `subagent` | `ctx.tools`, `ctx.subagents`, `ctx.systemPrompt`, `ctx.llm for model discovery and selected-route validation` | `tool/call`, `tool/result`, `child session events through the chosen provider` | `subagent`, `subagent_fork` | The registered delegation name is the load-time `toolName` config (default `subagent`); the default schema above has model selection off, while the discovery schema is shown as the fixed companion available in an enabled Session. Web presets sample the Plugins preference for each new top-level Session and preserve that decision for its child Sessions; `subagent_fork` remains fixed-route. Each instance independently controls whether it reads model-selection settings and its background behavior through `modelSelectionSettings`, `backgroundMode`, and `enableRunInBackground`. |
|
|
37
37
|
| `@deepseek-ai/dsh-tool-subagent-control` | `interrupt_agent`, `list_agents`, `send_message` | `ctx.tools`, `ctx.subagents`, `ctx.agents and ctx.sessionProjections (list_agents only)` | `tool/call`, `tool/result`, `child session events through ctx.subagents` | - | The globally named control tools over continuable background subagents: provider-bound `tool-subagent` instances register distinct delegation tools, while this package registers `send_message` and `interrupt_agent` once, plus `list_agents` from its separately loaded `/list-agents` plugin (whose catalog rows use the sessionProjections and live Agent registries). |
|
|
38
|
-
| `@deepseek-ai/dsh-tool-subagent-report` | `report` | `ctx.subagents`, `ctx.systemPrompt`, `a live continuable in-process child Agent` | `tool/call`, `tool/result`, `a user-role message in the direct parent session` | - | Registered per continuable in-process child rather than globally, so this schema is visible only inside such a child and survives its global `toolFilter`. The same contribution installs the child-scoped `tool:report` prompt section, which this catalog does not render. The parent-facing `send_message` tool is installed independently. |
|
|
39
38
|
| `@deepseek-ai/dsh-tool-jobs` | `job_kill`, `job_list`, `job_output` | `ctx.tools`, `ctx.jobs`, `ctx.systemPrompt` | `tool/call`, `tool/result`, `user/message via agent.inject() for background completion notices` | - | The kind-agnostic background-job controller: background bash commands, PTY sends, and subagents are read, listed, and killed through the same three tools. Loading the plugin attaches the controller that arms producers' `ctx.jobs.start()`. |
|
|
40
|
-
| `@deepseek-ai/dsh-experimental-tool-agent-team` | `
|
|
39
|
+
| `@deepseek-ai/dsh-experimental-tool-agent-team` | `interrupt_agent`, `list_agents`, `send_message`, `spawn_teammate`, `team_task_create`, `team_task_get`, `team_task_list`, `team_task_update`, `wait_agent` | `ctx.tools`, `ctx.systemPrompt`, `ctx.agentTeams`, `an exact live Team member Agent` | `tool/call`, `team/member`, `team/message/queued`, `team/message/delivered`, `team/task`, `tool/result` | - | All nine tools are scoped to implicit Team Leads and durable teammates. The shipped dsh-base bundle keeps the package disabled; the documented Agent Teams profile patch enables it while disabling the legacy continuable-child control names. |
|
|
41
40
|
| `@deepseek-ai/dsh-tool-todo` | `todo_write` | `ctx.tools`, `owning Agent session` | `tool/call`, `todo/write`, `tool/result` | - | todo_write is session-owned state; UIs render the latest todo/write event as a checklist. `allowParallelInProgress` is required with no default, so the catalog states its choice: `true`, whose description invites several `in_progress` items. A deployment choosing `false` receives the same tool with a description asking for exactly one active task. |
|
|
42
41
|
| `@deepseek-ai/dsh-tool-workflow` | `workflow` | `ctx.tools`, `ctx.workflowEngine`, `ctx.systemPrompt`, `a calling Agent (exec.agent parents the script children)` | `tool/call`, `tool/result` | - | - |
|
|
43
42
|
| `@deepseek-ai/dsh-tool-web` | `web_fetch`, `web_search` | `ctx.tools`, `ctx.web`, `ctx.systemPrompt` | `tool/call`, `tool/result` | - | web_search and web_fetch keep provider selection behind ctx.web so model-visible schemas stay stable across backend swaps. |
|
|
@@ -1618,7 +1617,7 @@ Source: [`packages/subagent/tool-subagent-control/src/index.ts`](../packages/sub
|
|
|
1618
1617
|
|
|
1619
1618
|
### `list_agents`
|
|
1620
1619
|
|
|
1621
|
-
List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a
|
|
1620
|
+
List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` steers a running child at its nearest step boundary or starts a turn for an idle or ready child, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only.
|
|
1622
1621
|
|
|
1623
1622
|
```json
|
|
1624
1623
|
{
|
|
@@ -1640,23 +1639,23 @@ Source: [`packages/subagent/tool-subagent-control/src/list-agents.ts`](../packag
|
|
|
1640
1639
|
|
|
1641
1640
|
### `send_message`
|
|
1642
1641
|
|
|
1643
|
-
Send a message to a
|
|
1642
|
+
Send a message to a direct continuable child by its agent id. If you are a resident continuable child, you may also target your direct parent. If the target is still working, the message steers its nearest step; if it is idle, the message starts a turn. This call returns no answer from the agent — only confirmation that the message was delivered. A failure means the message was NOT delivered.
|
|
1644
1643
|
|
|
1645
1644
|
```json
|
|
1646
1645
|
{
|
|
1647
1646
|
"type": "object",
|
|
1648
1647
|
"properties": {
|
|
1649
|
-
"
|
|
1648
|
+
"agent_id": {
|
|
1650
1649
|
"type": "string",
|
|
1651
|
-
"description": "The
|
|
1650
|
+
"description": "The agent id of your direct continuable child, or your direct parent when you are a resident continuable child."
|
|
1652
1651
|
},
|
|
1653
1652
|
"message": {
|
|
1654
1653
|
"type": "string",
|
|
1655
|
-
"description": "The message to deliver to the
|
|
1654
|
+
"description": "The message to deliver to the agent."
|
|
1656
1655
|
}
|
|
1657
1656
|
},
|
|
1658
1657
|
"required": [
|
|
1659
|
-
"
|
|
1658
|
+
"agent_id",
|
|
1660
1659
|
"message"
|
|
1661
1660
|
]
|
|
1662
1661
|
}
|
|
@@ -1666,33 +1665,6 @@ Source: [`packages/subagent/tool-subagent-control/src/index.ts`](../packages/sub
|
|
|
1666
1665
|
|
|
1667
1666
|
The globally named control tools over continuable background subagents: provider-bound `tool-subagent` instances register distinct delegation tools, while this package registers `send_message` and `interrupt_agent` once, plus `list_agents` from its separately loaded `/list-agents` plugin (whose catalog rows use the sessionProjections and live Agent registries).
|
|
1668
1667
|
|
|
1669
|
-
<a id="deepseek-aidsh-tool-subagent-report"></a>
|
|
1670
|
-
|
|
1671
|
-
## `@deepseek-ai/dsh-tool-subagent-report`
|
|
1672
|
-
|
|
1673
|
-
### `report`
|
|
1674
|
-
|
|
1675
|
-
Report selected content to the agent that started you. Call this once before you finish, with a self-contained final result, and earlier for progress or findings that change what that agent does next. That agent shares your workspace but does not automatically receive your transcript, tool output, or reasoning, so finishing your work is not itself a result. Reporting does not end your turn or finish your work, and only your direct parent receives it. A failed call may still have arrived, so do not blindly repeat it.
|
|
1676
|
-
|
|
1677
|
-
```json
|
|
1678
|
-
{
|
|
1679
|
-
"type": "object",
|
|
1680
|
-
"properties": {
|
|
1681
|
-
"output": {
|
|
1682
|
-
"type": "string",
|
|
1683
|
-
"description": "Actionable content for your parent; summarize conclusions and reference relevant shared paths."
|
|
1684
|
-
}
|
|
1685
|
-
},
|
|
1686
|
-
"required": [
|
|
1687
|
-
"output"
|
|
1688
|
-
]
|
|
1689
|
-
}
|
|
1690
|
-
```
|
|
1691
|
-
|
|
1692
|
-
Source: [`packages/subagent/tool-subagent-report/src/index.ts`](../packages/subagent/tool-subagent-report/src/index.ts)
|
|
1693
|
-
|
|
1694
|
-
Registered per continuable in-process child rather than globally, so this schema is visible only inside such a child and survives its global `toolFilter`. The same contribution installs the child-scoped `tool:report` prompt section, which this catalog does not render. The parent-facing `send_message` tool is installed independently.
|
|
1695
|
-
|
|
1696
1668
|
<a id="deepseek-aidsh-tool-jobs"></a>
|
|
1697
1669
|
|
|
1698
1670
|
## `@deepseek-ai/dsh-tool-jobs`
|
|
@@ -1770,32 +1742,6 @@ The kind-agnostic background-job controller: background bash commands, PTY sends
|
|
|
1770
1742
|
|
|
1771
1743
|
## `@deepseek-ai/dsh-experimental-tool-agent-team`
|
|
1772
1744
|
|
|
1773
|
-
### `followup_task`
|
|
1774
|
-
|
|
1775
|
-
Send a durable follow-up task to another Team member and start a turn when needed.
|
|
1776
|
-
|
|
1777
|
-
```json
|
|
1778
|
-
{
|
|
1779
|
-
"type": "object",
|
|
1780
|
-
"properties": {
|
|
1781
|
-
"target": {
|
|
1782
|
-
"type": "string",
|
|
1783
|
-
"description": "Team member name, or lead."
|
|
1784
|
-
},
|
|
1785
|
-
"message": {
|
|
1786
|
-
"type": "string",
|
|
1787
|
-
"description": "Self-contained message for the target."
|
|
1788
|
-
}
|
|
1789
|
-
},
|
|
1790
|
-
"required": [
|
|
1791
|
-
"target",
|
|
1792
|
-
"message"
|
|
1793
|
-
]
|
|
1794
|
-
}
|
|
1795
|
-
```
|
|
1796
|
-
|
|
1797
|
-
Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
|
|
1798
|
-
|
|
1799
1745
|
### `interrupt_agent`
|
|
1800
1746
|
|
|
1801
1747
|
Interrupt one teammate's current turn while preserving its pending inbox. Team Lead only.
|
|
@@ -1832,7 +1778,7 @@ Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/exper
|
|
|
1832
1778
|
|
|
1833
1779
|
### `send_message`
|
|
1834
1780
|
|
|
1835
|
-
Send durable
|
|
1781
|
+
Send one durable message to another Team member. A running target receives it at the nearest step boundary; an idle target starts a turn; an inactive teammate cold-resumes.
|
|
1836
1782
|
|
|
1837
1783
|
```json
|
|
1838
1784
|
{
|
|
@@ -2080,7 +2026,7 @@ Wait for the next teammate status, mailbox, or shared-task change after this cal
|
|
|
2080
2026
|
|
|
2081
2027
|
Source: [`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
|
|
2082
2028
|
|
|
2083
|
-
All
|
|
2029
|
+
All nine tools are scoped to implicit Team Leads and durable teammates. The shipped dsh-base bundle keeps the package disabled; the documented Agent Teams profile patch enables it while disabling the legacy continuable-child control names.
|
|
2084
2030
|
|
|
2085
2031
|
<a id="deepseek-aidsh-tool-todo"></a>
|
|
2086
2032
|
|
|
@@ -39,9 +39,8 @@
|
|
|
39
39
|
| `@deepseek-ai/dsh-tool-session-query` | `session_event_read`、`session_event_search`、`session_event_trace`、`session_search`、`session_trace` | `ctx.tools`、`ctx.systemPrompt`、`ctx.sessionQuery`、`a calling Agent for workspace authority` | `tool/call`、`tool/result` | - | 这 5 个只读工具会隐藏提供方游标,并根据不可变的调用 agent 会话为每个结果授权。该包需要选择启用;需要强制截止时间或限制行内输出的组合还会挂载通用超时或 spill 策略。 |
|
|
40
40
|
| `@deepseek-ai/dsh-tool-subagent` | `list_subagent_models`、`subagent` | `ctx.tools`、`ctx.subagents`、`ctx.systemPrompt`、`用于模型发现和所选路由校验的 ctx.llm` | `tool/call`、`tool/result`、`child session events through the chosen provider` | `subagent`、`subagent_fork` | 注册的委派工具名称取决于加载时 `toolName` 配置(默认为 `subagent`);上述默认 schema 关闭模型选择,而发现 schema 则展示为已启用 Session 中可用的固定配套工具。Web preset 会在每个新顶层 Session 创建时读取插件页偏好,并为其子 Session 保留该决定;`subagent_fork` 始终使用固定路由。每个实例通过 `modelSelectionSettings`、`backgroundMode` 与 `enableRunInBackground` 独立控制是否读取模型选择设置及其后台行为。 |
|
|
41
41
|
| `@deepseek-ai/dsh-tool-subagent-control` | `interrupt_agent`、`list_agents`、`send_message` | `ctx.tools`、`ctx.subagents`、`ctx.agents and ctx.sessionProjections (list_agents only)` | `tool/call`、`tool/result`、`child session events through ctx.subagents` | - | 这些是控制可继续后台 subagent 的全局命名工具:绑定提供方的 `tool-subagent` 实例注册不同的委派工具;本包注册一次 `send_message` 和 `interrupt_agent`,另由 `list_agents` 通过单独加载的 `/list-agents` 插件提供,其目录行使用 sessionProjections 和实时 Agent 注册表。 |
|
|
42
|
-
| `@deepseek-ai/dsh-tool-subagent-report` | `report` | `ctx.subagents`、`ctx.systemPrompt`、`a live continuable in-process child Agent` | `tool/call`、`tool/result`、`a user-role message in the direct parent session` | - | 按可继续的进程内子级注册,而非全局注册,因此该 schema 仅在这种子级内部可见,并且不受其全局 `toolFilter` 影响。同一份贡献还会安装子级作用域的 `tool:report` 系统提示词 section,本目录不渲染该 section。面向父级的 `send_message` 工具单独安装。 |
|
|
43
42
|
| `@deepseek-ai/dsh-tool-jobs` | `job_kill`、`job_list`、`job_output` | `ctx.tools`、`ctx.jobs`、`ctx.systemPrompt` | `tool/call`、`tool/result`、`user/message via agent.inject() for background completion notices` | - | 与任务种类无关的后台任务控制器:后台 bash 命令、PTY 发送和 subagent 都通过相同的 3 个工具读取、列出和终止。加载该插件会挂接控制器,从而启用生产方的 `ctx.jobs.start()`。 |
|
|
44
|
-
| `@deepseek-ai/dsh-experimental-tool-agent-team` | `
|
|
43
|
+
| `@deepseek-ai/dsh-experimental-tool-agent-team` | `interrupt_agent`、`list_agents`、`send_message`、`spawn_teammate`、`team_task_create`、`team_task_get`、`team_task_list`、`team_task_update`、`wait_agent` | `ctx.tools`、`ctx.systemPrompt`、`ctx.agentTeams`、`an exact live Team member Agent` | `tool/call`、`team/member`、`team/message/queued`、`team/message/delivered`、`team/task`、`tool/result` | - | 这 9 个工具限定于隐式 Team Lead 与持久 teammate 作用域。随产品发布的 dsh-base bundle 默认禁用该包;文档中的 Agent Teams profile patch 会启用它,并禁用旧 continuable child 的同名控制工具。 |
|
|
45
44
|
| `@deepseek-ai/dsh-tool-todo` | `todo_write` | `ctx.tools`、`owning Agent session` | `tool/call`、`todo/write`、`tool/result` | - | todo_write 是会话所有的状态;UI 将最新的 todo/write 事件渲染为检查清单。`allowParallelInProgress` 是没有默认值的必填项,因此本目录明确选择 `true`,对应描述允许同时存在多个 `in_progress` 项。选择 `false` 的部署会获得同一工具,但描述会要求只能有 1 个活动任务。 |
|
|
46
45
|
| `@deepseek-ai/dsh-tool-workflow` | `workflow` | `ctx.tools`、`ctx.workflowEngine`、`ctx.systemPrompt`、`a calling Agent (exec.agent parents the script children)` | `tool/call`、`tool/result` | - | - |
|
|
47
46
|
| `@deepseek-ai/dsh-tool-web` | `web_fetch`、`web_search` | `ctx.tools`、`ctx.web`、`ctx.systemPrompt` | `tool/call`、`tool/result` | - | web_search 和 web_fetch 将提供方选择置于 ctx.web 之后,使模型可见 schema 在更换后端时保持稳定。 |
|
|
@@ -1624,7 +1623,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
|
|
|
1624
1623
|
|
|
1625
1624
|
### `list_agents`
|
|
1626
1625
|
|
|
1627
|
-
按持久 id 和标签列出你的可继续后台 subagent。用它回忆你启动过哪些 subagent,而不是轮询完成情况——subagent 完成时你会被告知。状态来自实时注册表:running 表示 agent 此刻正在工作;idle 表示已加载但处于轮次之间,可能正在等待它启动的 agent;ready 表示它只存在于存储中——可恢复而非终态,也不表示有结果等待收集;`send_message`
|
|
1626
|
+
按持久 id 和标签列出你的可继续后台 subagent。用它回忆你启动过哪些 subagent,而不是轮询完成情况——subagent 完成时你会被告知。状态来自实时注册表:running 表示 agent 此刻正在工作;idle 表示已加载但处于轮次之间,可能正在等待它启动的 agent;ready 表示它只存在于存储中——可恢复而非终态,也不表示有结果等待收集;`send_message` 会在运行中 child 的最近 step 边界 steer 消息,或为 idle、ready child 启动轮次,且无论处于哪种状态,直接子级都仍可作为 `send_message` 的目标。该快照并非投递承诺;`send_message` 会执行权威检查,仍可能失败。无法读取的子级会作为诊断信息报告,而不会被静默丢弃。`descendants` 作用域会按稳定的前序顺序遍历你下方的整棵树,并为每个条目标注其持久的直接父会话 id 和深度。只有深度为 1 的条目可以使用 `send_message`;更深的条目只能作为 `interrupt_agent` 的候选目标。
|
|
1628
1627
|
|
|
1629
1628
|
```json
|
|
1630
1629
|
{
|
|
@@ -1646,23 +1645,23 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
|
|
|
1646
1645
|
|
|
1647
1646
|
### `send_message`
|
|
1648
1647
|
|
|
1649
|
-
根据
|
|
1648
|
+
根据 agent id 向直接可继续 child 发送消息。如果你是驻留的可继续 child,也可以把自己的直接 parent 作为目标。如果目标仍在工作,消息会 steer 其最近的 step;如果目标处于 idle,消息会启动一个轮次。此调用不会返回该 agent 的答案,只会确认消息已投递。调用失败表示消息**未**投递。
|
|
1650
1649
|
|
|
1651
1650
|
```json
|
|
1652
1651
|
{
|
|
1653
1652
|
"type": "object",
|
|
1654
1653
|
"properties": {
|
|
1655
|
-
"
|
|
1654
|
+
"agent_id": {
|
|
1656
1655
|
"type": "string",
|
|
1657
|
-
"description": "The
|
|
1656
|
+
"description": "The agent id of your direct continuable child, or your direct parent when you are a resident continuable child."
|
|
1658
1657
|
},
|
|
1659
1658
|
"message": {
|
|
1660
1659
|
"type": "string",
|
|
1661
|
-
"description": "The message to deliver to the
|
|
1660
|
+
"description": "The message to deliver to the agent."
|
|
1662
1661
|
}
|
|
1663
1662
|
},
|
|
1664
1663
|
"required": [
|
|
1665
|
-
"
|
|
1664
|
+
"agent_id",
|
|
1666
1665
|
"message"
|
|
1667
1666
|
]
|
|
1668
1667
|
}
|
|
@@ -1672,33 +1671,6 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
|
|
|
1672
1671
|
|
|
1673
1672
|
这些是控制可继续后台 subagent 的全局命名工具:绑定提供方的 `tool-subagent` 实例注册不同的委派工具;本包注册一次 `send_message` 和 `interrupt_agent`,另由 `list_agents` 通过单独加载的 `/list-agents` 插件提供,其目录行使用 sessionProjections 和实时 Agent 注册表。
|
|
1674
1673
|
|
|
1675
|
-
<a id="deepseek-aidsh-tool-subagent-report"></a>
|
|
1676
|
-
|
|
1677
|
-
## `@deepseek-ai/dsh-tool-subagent-report`
|
|
1678
|
-
|
|
1679
|
-
### `report`
|
|
1680
|
-
|
|
1681
|
-
向启动你的 agent 报告选定内容。在你结束前调用一次,给出自包含的最终结果;当进度或发现会改变该 agent 接下来的行动时,也可以更早调用。该 agent 与你共享工作区,但不会自动收到你的 transcript(文本记录)、工具输出或推理,因此完成你的工作本身并不等于交出结果。报告不会结束你的轮次或完成你的工作,且只有直接父级会收到。失败的调用仍可能已经送达,因此不要盲目重复。
|
|
1682
|
-
|
|
1683
|
-
```json
|
|
1684
|
-
{
|
|
1685
|
-
"type": "object",
|
|
1686
|
-
"properties": {
|
|
1687
|
-
"output": {
|
|
1688
|
-
"type": "string",
|
|
1689
|
-
"description": "Actionable content for your parent; summarize conclusions and reference relevant shared paths."
|
|
1690
|
-
}
|
|
1691
|
-
},
|
|
1692
|
-
"required": [
|
|
1693
|
-
"output"
|
|
1694
|
-
]
|
|
1695
|
-
}
|
|
1696
|
-
```
|
|
1697
|
-
|
|
1698
|
-
来源:[`packages/subagent/tool-subagent-report/src/index.ts`](../packages/subagent/tool-subagent-report/src/index.ts)
|
|
1699
|
-
|
|
1700
|
-
按可继续的进程内子级注册,而非全局注册,因此该 schema 仅在这种子级内部可见,并且不受其全局 `toolFilter` 影响。同一份贡献还会安装子级作用域的 `tool:report` 系统提示词 section,本目录不渲染该 section。面向父级的 `send_message` 工具单独安装。
|
|
1701
|
-
|
|
1702
1674
|
<a id="deepseek-aidsh-tool-jobs"></a>
|
|
1703
1675
|
|
|
1704
1676
|
## `@deepseek-ai/dsh-tool-jobs`
|
|
@@ -1776,32 +1748,6 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
|
|
|
1776
1748
|
|
|
1777
1749
|
## `@deepseek-ai/dsh-experimental-tool-agent-team`
|
|
1778
1750
|
|
|
1779
|
-
### `followup_task`
|
|
1780
|
-
|
|
1781
|
-
向另一名 Team member 发送持久 follow-up task,并在需要时启动一个 turn。
|
|
1782
|
-
|
|
1783
|
-
```json
|
|
1784
|
-
{
|
|
1785
|
-
"type": "object",
|
|
1786
|
-
"properties": {
|
|
1787
|
-
"target": {
|
|
1788
|
-
"type": "string",
|
|
1789
|
-
"description": "Team member name, or lead."
|
|
1790
|
-
},
|
|
1791
|
-
"message": {
|
|
1792
|
-
"type": "string",
|
|
1793
|
-
"description": "Self-contained message for the target."
|
|
1794
|
-
}
|
|
1795
|
-
},
|
|
1796
|
-
"required": [
|
|
1797
|
-
"target",
|
|
1798
|
-
"message"
|
|
1799
|
-
]
|
|
1800
|
-
}
|
|
1801
|
-
```
|
|
1802
|
-
|
|
1803
|
-
来源:[`packages/experimental/tool-agent-team/src/index.ts`](../packages/experimental/tool-agent-team/src/index.ts)
|
|
1804
|
-
|
|
1805
1751
|
### `interrupt_agent`
|
|
1806
1752
|
|
|
1807
1753
|
中断一名 teammate 的当前 turn,同时保留其待处理 inbox。仅 Team Lead 可用。
|
|
@@ -1838,7 +1784,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
|
|
|
1838
1784
|
|
|
1839
1785
|
### `send_message`
|
|
1840
1786
|
|
|
1841
|
-
向另一名 Team member
|
|
1787
|
+
向另一名 Team member 发送一条持久消息。running target 会在最近的步骤边界收到消息;idle target 会启动一个 turn;inactive teammate 会冷恢复。
|
|
1842
1788
|
|
|
1843
1789
|
```json
|
|
1844
1790
|
{
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write docs/user/guide/network-proxy.md
|
|
5
|
+
network-proxy.md: d53d48688490c741f0ed7f950c5ff39db02dc1e9
|
|
6
|
+
network-proxy.zh.md: 1eee1e67abb700e15f3b2cea1b22bf036c694302
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Run DSH behind a network proxy
|
|
2
|
+
|
|
3
|
+
English | [中文](network-proxy.zh.md)
|
|
4
|
+
|
|
5
|
+
DSH routes its outbound requests — model calls, web search, page fetches, and MCP servers over HTTP — through the proxy named by the standard proxy environment variables. It reads them at launch; nothing else needs configuring. A few paths stay direct by design or by runtime limit, listed under "What stays direct" below.
|
|
6
|
+
|
|
7
|
+
## Export the variables
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
export HTTPS_PROXY=http://127.0.0.1:7890
|
|
11
|
+
export HTTP_PROXY=http://127.0.0.1:7890
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Put both lines in your shell profile so every `dsh` invocation inherits them, or in `$DSH_HOME/.env` (`~/.dsh/.env` by default) next to your API key; an exported variable always wins over that file. A project's own `.env` cannot set them: it arrives with `git clone`, and DSH refuses to start rather than let a repository decide where your traffic goes.
|
|
15
|
+
|
|
16
|
+
A proxy that needs credentials takes them in the URL: `http://user:password@proxy.example:8080`. DSH never prints the URL back: a diagnostic names the variable it rejected, so neither the username nor the password appears anywhere.
|
|
17
|
+
|
|
18
|
+
## Why your browser is proxied but your terminal is not
|
|
19
|
+
|
|
20
|
+
This is the most common surprise, and it is not specific to DSH. There is no single "system proxy" that all software obeys — there are three unrelated mechanisms:
|
|
21
|
+
|
|
22
|
+
| Mechanism | Who follows it |
|
|
23
|
+
|---|---|
|
|
24
|
+
| The operating system's proxy settings | Safari, most native macOS apps, Chrome and Edge |
|
|
25
|
+
| The `HTTP_PROXY` / `HTTPS_PROXY` environment variables | `curl`, `git`, `npm`, `pip`, and DSH |
|
|
26
|
+
| TUN mode (a virtual network interface) | Everything, transparently |
|
|
27
|
+
|
|
28
|
+
The "system proxy" switch in a proxy application such as Clash writes only the first one. Browsers pick it up; command-line tools never see it. That is why exporting the variables is a separate step, and why turning on TUN mode makes both work without any variables at all.
|
|
29
|
+
|
|
30
|
+
DSH does not read the operating system's proxy settings. Export the variables, or use TUN mode.
|
|
31
|
+
|
|
32
|
+
## Choose what stays direct
|
|
33
|
+
|
|
34
|
+
`NO_PROXY` lists hosts to reach directly:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
export NO_PROXY=internal.example.com,.corp.example.com,registry.local
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
An entry names a host and matches it together with every subdomain under it: `NO_PROXY=example.com` also sends `api.example.com` direct. A leading `.` or `*.` is accepted and means the same thing. An entry may carry a `:port`, and `*` bypasses everything.
|
|
41
|
+
|
|
42
|
+
**CIDR ranges do not work.** An operating system bypass list often contains entries like `10.0.0.0/8` or `192.168.0.0/16`; copying those into `NO_PROXY` has no effect. Use host names or domain suffixes instead.
|
|
43
|
+
|
|
44
|
+
You do not need to list `localhost` or `127.0.0.1`. DSH always bypasses loopback, because its own Web UI and local servers would otherwise route through the proxy and loop.
|
|
45
|
+
|
|
46
|
+
## Limits worth knowing
|
|
47
|
+
|
|
48
|
+
**SOCKS proxies are not supported.** A `socks5://` value is reported at startup and skipped, and DSH connects directly for the scheme that named it — setting `HTTPS_PROXY=socks5://…` alongside a usable `HTTP_PROXY` leaves `https:` direct rather than borrowing the HTTP proxy. Point the variables at your proxy application's HTTP port instead — most expose both, and the HTTP one is usually a neighbouring port number.
|
|
49
|
+
|
|
50
|
+
**`ALL_PROXY` alone is enough.** DSH falls back to it for both schemes, even though Node and curl differ on this. Setting `HTTPS_PROXY` explicitly is still clearer.
|
|
51
|
+
|
|
52
|
+
**A TLS-intercepting corporate proxy needs its certificate.** If requests fail with a certificate error once the proxy is reachable, point Node at your organisation's CA bundle before launching:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
export NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Node reads that variable only at process start, so export it before running `dsh`.
|
|
59
|
+
|
|
60
|
+
**Tools DSH runs for you follow the same proxy.** Commands in the bash tool, `git`, `gh`, and MCP servers started as child processes all inherit these variables. A child that is itself a Node program honors them only on Node 22.21 or later; an older Node connects directly. If one of your proxy variables holds a value DSH rejected — a SOCKS URL, say — Node-based tools also connect directly rather than fail to start, while `curl` and `git` still read that value.
|
|
61
|
+
|
|
62
|
+
**A password in the proxy URL reaches those tools too.** `HTTPS_PROXY=http://alice:s3cret@proxy.example:8080` is a normal environment variable, so every command DSH runs — including the ones the model writes — can read it, and a command that prints its environment puts the password in output that is kept. This is how the variable already behaves for everything else in your shell. If that matters, give the proxy a credential-free entry point, or authenticate it some other way than in the URL.
|
|
63
|
+
|
|
64
|
+
## What stays direct
|
|
65
|
+
|
|
66
|
+
Not every request DSH makes goes through the proxy:
|
|
67
|
+
|
|
68
|
+
- **Anything on this machine.** Loopback is always direct: `localhost`, the whole `127.0.0.0/8` range, `::1`, and `0.0.0.0`. A proxy cannot usefully reach a service that only listens locally.
|
|
69
|
+
- **Code the model writes.** The workflow and code-runtime workers never receive the proxy settings, so a script the model authors cannot read a proxy URL that may carry a password. Such a script reaches the network only if it configures that itself.
|
|
70
|
+
- **Usage telemetry.** The OTLP exporter uses Node's own HTTP client rather than the one a proxy configures, so telemetry connects directly and simply fails where direct egress is blocked. Nothing you do in DSH depends on it. Set `DSH_TELEMETRY_MODE=DISABLED` to turn it off entirely.
|
|
71
|
+
- **`web_fetch` to a literal private address.** A URL naming an address like `http://10.0.0.5/` is refused rather than handed to the proxy, the same refusal it gets with no proxy configured.
|
|
72
|
+
|
|
73
|
+
## Check that it worked
|
|
74
|
+
|
|
75
|
+
Ask the agent to fetch a page and watch your proxy application's connection log:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
dsh --profile headless "fetch https://example.com and tell me the page title"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
If the request does not appear there, confirm the variables survive into DSH's own environment:
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
env | grep -i proxy
|
|
85
|
+
```
|