dsh-plugin-dev-kb 1.0.2 → 1.0.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.
Files changed (144) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/kb/README.md +1 -1
  3. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +3 -3
  4. package/kb/extra/cookbook/maintaining-dsh-code-review.zh.md +1 -1
  5. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +1 -1
  6. package/kb/extra/defensive-patterns.zh.md +3 -1
  7. package/kb/extra/development.zh.md +15 -9
  8. package/kb/extra/event-producer-consumer.md +5 -2
  9. package/kb/extra/event-producer-consumer.zh.md +5 -2
  10. package/kb/extra/graph-atlas.zh.md +7 -7
  11. package/kb/extra/i18n/README.md +3 -3
  12. package/kb/extra/i18n/README.zh.md +9 -7
  13. package/kb/extra/i18n/style-samples.md +1 -1
  14. package/kb/extra/i18n/translation-prompt.md +3 -3
  15. package/kb/extra/i18n/translation-rules.md +2 -2
  16. package/kb/extra/i18n/translation-rules.zh.md +3 -3
  17. package/kb/extra/module-graph.md +18 -9
  18. package/kb/extra/module-graph.zh.md +18 -9
  19. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +1 -1
  20. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +1 -1
  21. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
  22. package/kb/extra/postmortem/README.zh.md +5 -5
  23. package/kb/extra/rescope.zh.md +1 -1
  24. package/kb/extra/subsystems/agent-team.md +2 -2
  25. package/kb/extra/subsystems/agent-team.zh.md +6 -6
  26. package/kb/extra/subsystems/attachment.md +63 -12
  27. package/kb/extra/subsystems/attachment.zh.md +63 -12
  28. package/kb/extra/subsystems/extensions.md +9 -9
  29. package/kb/extra/subsystems/extensions.zh.md +12 -12
  30. package/kb/extra/subsystems/feedback.md +2 -2
  31. package/kb/extra/subsystems/feedback.zh.md +2 -2
  32. package/kb/extra/testing.md +1 -1
  33. package/kb/extra/testing.zh.md +7 -7
  34. package/kb/extra/web-styling.zh.md +2 -2
  35. package/kb/meta/search-index.json +132 -132
  36. package/kb/meta/source.json +2 -2
  37. package/kb/meta/topics.md +2 -2
  38. package/kb/site/develop/basic/index.md +1 -1
  39. package/kb/site/develop/basic/publish.md +3 -3
  40. package/kb/site/develop/cordis-tutorial/index.md +1 -1
  41. package/kb/site/en/reference/capability-seams.md +5 -0
  42. package/kb/site/en/reference/config-catalog.md +52 -17
  43. package/kb/site/en/reference/persistence-catalog.md +1 -1
  44. package/kb/site/en/reference/subsystems/approval.md +3 -3
  45. package/kb/site/en/reference/subsystems/client-modules.md +7 -7
  46. package/kb/site/en/reference/subsystems/code-runtime.md +2 -2
  47. package/kb/site/en/reference/subsystems/commands.md +3 -3
  48. package/kb/site/en/reference/subsystems/compaction.md +3 -3
  49. package/kb/site/en/reference/subsystems/core.md +19 -19
  50. package/kb/site/en/reference/subsystems/credentials.md +163 -8
  51. package/kb/site/en/reference/subsystems/filesystem.md +5 -5
  52. package/kb/site/en/reference/subsystems/goal.md +3 -3
  53. package/kb/site/en/reference/subsystems/invariants.md +2 -2
  54. package/kb/site/en/reference/subsystems/jobs.md +2 -2
  55. package/kb/site/en/reference/subsystems/llm-streaming.md +16 -4
  56. package/kb/site/en/reference/subsystems/lsp.md +2 -2
  57. package/kb/site/en/reference/subsystems/permission-presets.md +2 -2
  58. package/kb/site/en/reference/subsystems/persistence.md +2 -2
  59. package/kb/site/en/reference/subsystems/plan.md +2 -2
  60. package/kb/site/en/reference/subsystems/sandbox.md +3 -3
  61. package/kb/site/en/reference/subsystems/session-projection.md +60 -35
  62. package/kb/site/en/reference/subsystems/session-query.md +2 -2
  63. package/kb/site/en/reference/subsystems/session-reference.md +3 -3
  64. package/kb/site/en/reference/subsystems/session-telemetry.md +3 -3
  65. package/kb/site/en/reference/subsystems/session-title.md +2 -2
  66. package/kb/site/en/reference/subsystems/session.md +6 -6
  67. package/kb/site/en/reference/subsystems/settings.md +4 -4
  68. package/kb/site/en/reference/subsystems/shell.md +3 -3
  69. package/kb/site/en/reference/subsystems/skills.md +3 -3
  70. package/kb/site/en/reference/subsystems/spill.md +2 -2
  71. package/kb/site/en/reference/subsystems/storage.md +4 -4
  72. package/kb/site/en/reference/subsystems/subagent.md +6 -6
  73. package/kb/site/en/reference/subsystems/subprocess.md +3 -3
  74. package/kb/site/en/reference/subsystems/system-prompt.md +4 -4
  75. package/kb/site/en/reference/subsystems/terminal.md +2 -2
  76. package/kb/site/en/reference/subsystems/token-meter.md +2 -2
  77. package/kb/site/en/reference/subsystems/tools.md +8 -8
  78. package/kb/site/en/reference/subsystems/typert.md +4 -4
  79. package/kb/site/en/reference/subsystems/user-questions.md +2 -2
  80. package/kb/site/en/reference/subsystems/web-server.md +46 -6
  81. package/kb/site/en/reference/subsystems/web.md +2 -2
  82. package/kb/site/en/reference/subsystems/workflow.md +8 -8
  83. package/kb/site/en/reference/subsystems/workspace.md +3 -3
  84. package/kb/site/en/reference/tool-catalog.md +3 -3
  85. package/kb/site/guide/providers.md +2 -2
  86. package/kb/site/guide/python-sdk.md +2 -2
  87. package/kb/site/guide/quickstart.md +2 -2
  88. package/kb/site/reference/capability-seams.md +5 -0
  89. package/kb/site/reference/config-catalog.md +53 -18
  90. package/kb/site/reference/cookbook/adding-a-conversation-node.md +1 -1
  91. package/kb/site/reference/cookbook/adding-a-package.md +5 -3
  92. package/kb/site/reference/cookbook/adding-a-settings-card.md +1 -1
  93. package/kb/site/reference/cookbook/adding-a-tool.md +6 -6
  94. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +2 -2
  95. package/kb/site/reference/cookbook/extension-cookbook.md +6 -4
  96. package/kb/site/reference/index.md +4 -4
  97. package/kb/site/reference/persistence-catalog.md +5 -5
  98. package/kb/site/reference/subsystems/approval.md +3 -3
  99. package/kb/site/reference/subsystems/client-modules.md +8 -8
  100. package/kb/site/reference/subsystems/code-runtime.md +4 -4
  101. package/kb/site/reference/subsystems/commands.md +5 -5
  102. package/kb/site/reference/subsystems/compaction.md +7 -7
  103. package/kb/site/reference/subsystems/core.md +26 -24
  104. package/kb/site/reference/subsystems/credentials.md +163 -8
  105. package/kb/site/reference/subsystems/filesystem.md +6 -6
  106. package/kb/site/reference/subsystems/goal.md +5 -5
  107. package/kb/site/reference/subsystems/index.md +5 -5
  108. package/kb/site/reference/subsystems/invariants.md +5 -5
  109. package/kb/site/reference/subsystems/jobs.md +4 -4
  110. package/kb/site/reference/subsystems/llm-streaming.md +21 -9
  111. package/kb/site/reference/subsystems/lsp.md +3 -3
  112. package/kb/site/reference/subsystems/permission-presets.md +3 -3
  113. package/kb/site/reference/subsystems/persistence.md +6 -6
  114. package/kb/site/reference/subsystems/plan.md +4 -4
  115. package/kb/site/reference/subsystems/sandbox.md +7 -5
  116. package/kb/site/reference/subsystems/schedule.md +1 -1
  117. package/kb/site/reference/subsystems/scope.md +1 -1
  118. package/kb/site/reference/subsystems/session-projection.md +61 -36
  119. package/kb/site/reference/subsystems/session-query.md +2 -2
  120. package/kb/site/reference/subsystems/session-reference.md +3 -3
  121. package/kb/site/reference/subsystems/session-telemetry.md +5 -5
  122. package/kb/site/reference/subsystems/session-title.md +2 -2
  123. package/kb/site/reference/subsystems/session.md +13 -11
  124. package/kb/site/reference/subsystems/settings.md +4 -4
  125. package/kb/site/reference/subsystems/shell.md +6 -6
  126. package/kb/site/reference/subsystems/skills.md +3 -3
  127. package/kb/site/reference/subsystems/spill.md +3 -3
  128. package/kb/site/reference/subsystems/storage.md +7 -7
  129. package/kb/site/reference/subsystems/subagent.md +11 -9
  130. package/kb/site/reference/subsystems/subprocess.md +4 -4
  131. package/kb/site/reference/subsystems/system-prompt.md +5 -5
  132. package/kb/site/reference/subsystems/terminal.md +3 -3
  133. package/kb/site/reference/subsystems/token-meter.md +2 -2
  134. package/kb/site/reference/subsystems/tools.md +9 -9
  135. package/kb/site/reference/subsystems/typert.md +5 -5
  136. package/kb/site/reference/subsystems/user-questions.md +2 -2
  137. package/kb/site/reference/subsystems/web-server.md +48 -8
  138. package/kb/site/reference/subsystems/web.md +3 -3
  139. package/kb/site/reference/subsystems/workflow.md +11 -11
  140. package/kb/site/reference/subsystems/workspace.md +5 -5
  141. package/kb/site/reference/tool-catalog.md +9 -5
  142. package/lib/index.js +9 -1
  143. package/package.json +2 -1
  144. package/skills/dsh-plugin-dev-kb.md +1 -1
@@ -5,7 +5,7 @@ outline: [2,3]
5
5
 
6
6
  # 存储
7
7
 
8
- 存储子系统持久保存一切不属于会话事件日志的数据(会话日志有自己的 seam——见 [persistence.md](./persistence.md))。它是一项可选能力,不属于 agent loop(智能体循环)主干,并按[能力 seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md) 拆分:枢纽(hub)与 Service Definition([dsh-storage](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage),`ctx.storage`)、Service Provider(注册为 `json` 的 [dsh-storage-json](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-json) 与注册为 `sqlite` 的 [dsh-storage-sqlite](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-sqlite)),以及 Consumer 数据形式([dsh-storage-domain](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-domain),`ctx.storageDomain`,也可经 `ctx.storage.domain` 访问)——它是后端约定的唯一 Consumer,也是其他一切所使用的类型化 API。枢纽自身不做任何 IO:后端拥有介质,数据形式拥有语义,产品包绝不直接触碰后端。设计记录:[领域 KV 存储 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.md)。
8
+ 存储子系统持久保存一切不属于会话事件日志的数据(会话日志有自己的 seam——见 [persistence.md](./persistence.md))。它是一项可选能力,不属于 agent loop(智能体循环)主干,并按[能力 seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md) 拆分:枢纽(hub)与 Service Definition([dsh-storage](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage),`ctx.storage`)、Service Provider(注册为 `json` 的 [dsh-storage-json](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-json) 与注册为 `sqlite` 的 [dsh-storage-sqlite](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-sqlite)),以及 Consumer 数据形式([dsh-storage-domain](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/storage/storage-domain),`ctx.storageDomain`,也可经 `ctx.storage.domain` 访问)——它是后端约定的唯一 Consumer,也是其他一切所使用的类型化 API。枢纽自身不做任何 IO:后端拥有介质,数据形式拥有语义,产品包绝不直接触碰后端。设计记录:[领域 KV 存储 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/proposed/architecture/2026-07-24-domain-kv-storage-and-workspace.zh.md)。
9
9
 
10
10
  源码:[`packages/storage/storage/src/backend.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/src/backend.ts) · [`packages/storage/storage-domain/src/spec.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/src/spec.ts) · [`packages/storage/storage-domain/src/events.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/src/events.ts)
11
11
 
@@ -47,7 +47,7 @@ interface StorageBackend {
47
47
  }
48
48
  ```
49
49
 
50
- 一个后端拥有一个介质(一棵文件树的根目录、一个数据库文件),并提供可选的操作组;目前 `kv` 是唯一一组。`KvFacet.open(descriptor)` 打开一个具名 unit——`KvUnitDescriptor` 携带名称、格式版本、表名清单,以及是否存在全局单例 slot——并返回提供 `loadAll`、`putRecord`、`deleteRecord`、`setGlobal` 和 `close` 的 `KvUnit`。unit 名与表名必须匹配 `UNIT_NAME_RE`(既可安全用作文件名,也可安全用作 SQL 标识符片段);记录键是任意字符串,绝不进入文件路径。unit 不对并发写入做串行化——顺序由调用方负责——但每次单独调用在介质上都是原子的,且 resolve 后即已持久。介质上记录的版本与之不同时拒绝 `version-mismatch`;无法按该 unit 解析的介质拒绝 `malformed-medium`(不做迁移:预发布立场)。[`backend.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/src/backend.ts) 是逐条款的规范性约定,[`tests/contract.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/tests/contract.ts) 中的共享一致性套件会针对每个后端检查每项条款。[json 后端](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-json/README.md)以原子方式为每个 unit 整文件重新发布一份人类可读文件;[sqlite 后端](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-sqlite/README.md)在单个数据库中每行存储一份文档,用于频繁更新的数据。
50
+ 一个后端拥有一个介质(一棵文件树的根目录、一个数据库文件),并提供可选的操作组;目前 `kv` 是唯一一组。`KvFacet.open(descriptor)` 打开一个具名 unit——`KvUnitDescriptor` 携带名称、格式版本、表名清单,以及是否存在全局单例 slot——并返回提供 `loadAll`、`putRecord`、`deleteRecord`、`setGlobal` 和 `close` 的 `KvUnit`。unit 名与表名必须匹配 `UNIT_NAME_RE`(既可安全用作文件名,也可安全用作 SQL 标识符片段);记录键是任意字符串,绝不进入文件路径。unit 不对并发写入做串行化——顺序由调用方负责——但每次单独调用在介质上都是原子的,且 resolve 后即已持久。介质上记录的版本与之不同时拒绝 `version-mismatch`;无法按该 unit 解析的介质拒绝 `malformed-medium`(不做迁移:预发布立场)。[`backend.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/src/backend.ts) 是逐条款的规范性约定,[`tests/contract.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/tests/contract.ts) 中的共享一致性套件会针对每个后端检查每项条款。[json 后端](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-json/README.zh.md)以原子方式为每个 unit 整文件重新发布一份人类可读文件;[sqlite 后端](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-sqlite/README.zh.md)在单个数据库中每行存储一份文档,用于频繁更新的数据。
51
51
 
52
52
  ## 声明领域
53
53
 
@@ -125,7 +125,7 @@ interface DomainChangedBase {
125
125
  type DomainChanged = DomainChangedPut | DomainChangedDeleted
126
126
  ```
127
127
 
128
- `put`(插入、覆写和 global 写入)在 `value` 中携带新快照——绝不携带旧值;需要做差异比较的消费方自行保留上一份快照。`deleted` 是不携带值的墓碑。该事件是通知,不是事务参与者:发出时提交点已经过去,因此同步抛出的监听器会被兜住并记录一条警告,而不会让已经持久的写入被拒绝;发出的值等于发出时刻的内存态。该事件仅限进程内;跨进程的变更推送是一项已记录的限制([包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/README.md))。
128
+ `put`(插入、覆写和 global 写入)在 `value` 中携带新快照——绝不携带旧值;需要做差异比较的消费方自行保留上一份快照。`deleted` 是不携带值的墓碑。该事件是通知,不是事务参与者:发出时提交点已经过去,因此同步抛出的监听器会被兜住并记录一条警告,而不会让已经持久的写入被拒绝;发出的值等于发出时刻的内存态。该事件仅限进程内;跨进程的变更推送是一项已记录的限制([包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/README.zh.md))。
129
129
 
130
130
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
131
131
 
@@ -133,7 +133,7 @@ type DomainChanged = DomainChangedPut | DomainChangedDeleted
133
133
 
134
134
  ## Cordis API
135
135
 
136
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
136
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
137
137
 
138
138
  <a id="ctxstorage--storage"></a>
139
139
 
@@ -159,7 +159,7 @@ mount<K extends keyof StorageForms>(form: K, facility: StorageForms[K]): () => v
159
159
  form<K extends keyof StorageForms>(form: K): StorageForms[K]
160
160
  ```
161
161
 
162
- Source: [`packages/storage/storage/src/index.ts:47`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/src/index.ts)
162
+ Source: [`packages/storage/storage/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage/src/index.ts)
163
163
 
164
164
  <a id="ctxstoragedomain--domainfacility"></a>
165
165
 
@@ -204,7 +204,7 @@ get(name: string): DomainImpl | undefined
204
204
  async closeAll(): Promise<void>
205
205
  ```
206
206
 
207
- Source: [`packages/storage/storage-domain/src/index.ts:69`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/src/index.ts)
207
+ Source: [`packages/storage/storage-domain/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/src/index.ts)
208
208
 
209
209
  <a id="domain-events"></a>
210
210
 
@@ -228,5 +228,5 @@ A domain record or the global singleton changed, emitted once per write strictly
228
228
  'domain/changed'(change: DomainChanged): void
229
229
  ```
230
230
 
231
- Source: [`packages/storage/storage-domain/src/events.ts:46`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/src/events.ts)
231
+ Source: [`packages/storage/storage-domain/src/events.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/storage/storage-domain/src/events.ts)
232
232
  <!-- END GENERATED cordis-surface -->
@@ -7,7 +7,7 @@ outline: [2,3]
7
7
 
8
8
  subagent seam 让一个 agent(智能体)将工作委派给子 agent。与 [bash](./shell.md) 一样,它是**一项可选能力**,不属于 agent loop(智能体循环),因此其类型定义在此而非 [core.md](./core.md) 中。它不同于其他能力 seam,因为**同一上下文中可共存多个提供方实现**,并按名称注册(`ctx.subagents`),而 bash 只允许一个执行器。该注册表遵循 [LLM(大语言模型)适配器注册表](./llm-streaming.md),而非单服务的 bash 执行器。
9
9
 
10
- Service Definition:[dsh-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/subagent)(`ctx.subagents` + 下文词汇)。Service Provider 是六个兄弟包:`dsh-subagent-spawn-in-process`、`-fork`、`-acp`、`-codex`、`-claude-code`、`-dsh-sdk`;面向模型的 Consumer 包括 [dsh-tool-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent)(按提供方委派)、[dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control)(可选的全局 `send_message`、`interrupt_agent` 与 `list_agents` 控制工具)和 [dsh-tool-subagent-report](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-report)(可选的 child 作用域 `report` 返回通道)。同一个 `ctx.subagents` 服务通过内部激活管理器负责可继续子 agent 编排,并直接基于会话存储和可选的会话持久化提供只读的 child 与后代发现。产品提供方设计理由见 [Codex 与 Claude Code Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.md);通用 seam 的设计理由见 [subagent Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.md)、[可继续 subagent Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.md)、[report 工具 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-30-continuable-subagent-report-tool.md)、[持久化目录 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-22-durable-subagent-catalog-and-list-agents.md)、[列表身份投影 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.md)和[服务合并 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-07-26-merge-subagent-control-service.md)。
10
+ Service Definition:[dsh-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/subagent)(`ctx.subagents` + 下文词汇)。Service Provider 是六个兄弟包:`dsh-subagent-spawn-in-process`、`-fork`、`-acp`、`-codex`、`-claude-code`、`-dsh-sdk`;面向模型的 Consumer 包括 [dsh-tool-subagent](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent)(按提供方委派)、[dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control)(可选的全局 `send_message`、`interrupt_agent` 与 `list_agents` 控制工具)和 [dsh-tool-subagent-report](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-report)(可选的 child 作用域 `report` 返回通道)。同一个 `ctx.subagents` 服务通过内部激活管理器负责可继续子 agent 编排,并直接基于会话存储和可选的会话持久化提供只读的 child 与后代发现。产品提供方设计理由见 [Codex 与 Claude Code Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.zh.md);通用 seam 的设计理由见 [subagent Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-21-subagent-capability-seam.zh.md)、[可继续 subagent Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.zh.md)、[report 工具 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-30-continuable-subagent-report-tool.zh.md)、[持久化目录 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-22-durable-subagent-catalog-and-list-agents.zh.md)、[列表身份投影 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.zh.md)和[服务合并 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/simplification/2026-07-26-merge-subagent-control-service.zh.md)。
11
11
 
12
12
  源码:[`packages/subagent/subagent/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/types.ts)、[`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)和 [`packages/subagent/subagent/src/continuation.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/continuation.ts)
13
13
 
@@ -99,7 +99,7 @@ interface SubagentStartRequest {
99
99
  }
100
100
  ```
101
101
 
102
- `signal` 是就绪前后唯一的取消通道。[subagent 组合控制 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md)规定 persona、live 全局工具过滤、绝对深度以及「可见性而非权限」的设计理由。
102
+ `signal` 是就绪前后唯一的取消通道。[subagent 组合控制 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.zh.md)规定 persona、live 全局工具过滤、绝对深度以及「可见性而非权限」的设计理由。
103
103
 
104
104
  面向调用方的请求不携带目录格式细节或继续执行状态。`SubagentRuntime.start()` 会在能力检查后解析分离的一次性描述符,再将以下面向提供方的请求传给所选传输;可继续子 agent 绝不会到达 `SubagentProvider.start()`:
105
105
 
@@ -289,7 +289,7 @@ interface ContinuableCreateSpec {
289
289
 
290
290
  ## 持久化枚举:`listChildren()`、`listDescendants()` 与其条目
291
291
 
292
- `SubagentRuntime.listChildren(parentSessionId)` 从 `ctx.sessions.list()` 与可选 `ctx.sessionPersistence.list()` 的实时优先合并中枚举 parent 直接且由会话支撑的 subagent——不经查询服务,也不会加载或恢复任何 Agent。候选是持久 header 携带 `origin: 'subagent'` 的直接 child;该标记只负责枚举分类与粗粒度的通用路由拒绝,不能证明描述符有效、child 可恢复或操作已获授权——身份由投影折叠负责,恢复由 Activation 约定负责。每行的 `mode`/`label` 是已注册 `subagent` projection unit 的值,经三级阶梯供值:存活 child 由注册表水位缓存供值(零日志读取);冷 child 先读可选的投影 checkpoint 缓存(`cachedSnapshot`——过 own-suffix seq 门的身份即定值,own descriptor 一经追加不可变);否则在一次 `persistence.inspect()` 读取上经注册表折叠(有界并发,每次列表重新计算)。该缓存是纯可选加速层:服务缺席、行里是 `null` 哨兵或 key 缺席、seq 门不过、读取出错,都静默落到权威重折。折叠规则是 `subagent/descriptor` last-wins 且没有失败通道:子 agent 自己的描述符覆盖 fork seed 中祖先的描述符,格式错误或版本不认识的载荷折叠为可序列化的 `null` 哨兵,视同无值。结果是按 `createdAt`、再按 id 排序的 `SubagentListEntry[]`:取到身份即生成带有 `mode: 'one-shot' | 'continuable'` 和 `activity: 'running' | 'inactive'` 的 `child` 条目;可继续条目始终携带 `label`,一次性条目则只在启动调用方提供展示元数据时携带该字段。已定局而折叠无身份的候选生成 `corrupt` diagnostic——缺失、格式错误与版本不认识的描述符有意不再细分(`unsupported` 仍保留在类型中但从不产出);运行中而无身份的候选被省略(描述符落盘前的创建窗口);冷检查失败生成一条 `unavailable` diagnostic 并在下次列表自然重试,因此一个损坏的 sibling 不会隐藏健康 child。`hasChildren` 标记存在持久 subagent origin 的直接后代,读取自同一份合并材料。活动状态只表示逻辑记录是否在 `ctx.sessions` 中存活,而不表示结果或可恢复性。缺少持久化时,枚举退化为仅存活枚举而不是报错——此时冷 child 本就无法恢复。缺少 `ctx.sessionProjections` 注册表时,`listChildren()` 抛出携带错误码 `SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE` 的 `SubagentError`,缺少会话存储时则抛出 `SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE`,两者都在任何读取之前检查,因此零 child 的部署同样确定失败;列表工具在插件加载时要求 `ctx.subagents` 与 `ctx.agents`。UI 等服务消费方可以展示两种模式,并为无标签的一次性 child 选择回退展示;面向模型的 `list_agents` 适配器([dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control) 中可单独加载的 `/list-agents` 插件)则只保留可继续条目,并通过在线 Agent 注册表将状态细化为自己的 `running`/`idle`/`ready` 词汇,其中 `ready` 把仅存于存储的 child 命名为可恢复而非终态。枚举不会查询继续执行管理器的 Activation map、Agent 注册表或提供方可用性;`send_message` 仍是消息送达时的权威操作,列表中的运行中可继续 child 仍可能因所有权冲突而拒绝投递。读路径的设计理由见[列表身份投影 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.md)。
292
+ `SubagentRuntime.listChildren(parentSessionId)` 从 `ctx.sessions.list()` 与可选 `ctx.sessionPersistence.list()` 的实时优先合并中枚举 parent 直接且由会话支撑的 subagent——不经查询服务,也不会加载或恢复任何 Agent。候选是持久 header 携带 `origin: 'subagent'` 的直接 child;该标记只负责枚举分类与粗粒度的通用路由拒绝,不能证明描述符有效、child 可恢复或操作已获授权——身份由投影折叠负责,恢复由 Activation 约定负责。每行的 `mode`/`label` 是已注册 `subagent` projection unit 的值,经三级阶梯供值:存活 child 由注册表水位缓存供值(零日志读取);冷 child 先读可选的投影 checkpoint 缓存(`cachedSnapshot`——过 own-suffix seq 门的身份即定值,own descriptor 一经追加不可变);否则在一次 `persistence.inspect()` 读取上经注册表折叠(有界并发,每次列表重新计算)。该缓存是纯可选加速层:服务缺席、行里是 `null` 哨兵或 key 缺席、seq 门不过、读取出错,都静默落到权威重折。折叠规则是 `subagent/descriptor` last-wins 且没有失败通道:子 agent 自己的描述符覆盖 fork seed 中祖先的描述符,格式错误或版本不认识的载荷折叠为可序列化的 `null` 哨兵,视同无值。结果是按 `createdAt`、再按 id 排序的 `SubagentListEntry[]`:取到身份即生成带有 `mode: 'one-shot' | 'continuable'` 和 `activity: 'running' | 'inactive'` 的 `child` 条目;可继续条目始终携带 `label`,一次性条目则只在启动调用方提供展示元数据时携带该字段。已定局而折叠无身份的候选生成 `corrupt` diagnostic——缺失、格式错误与版本不认识的描述符有意不再细分(`unsupported` 仍保留在类型中但从不产出);运行中而无身份的候选被省略(描述符落盘前的创建窗口);冷检查失败生成一条 `unavailable` diagnostic 并在下次列表自然重试,因此一个损坏的 sibling 不会隐藏健康 child。`hasChildren` 标记存在持久 subagent origin 的直接后代,读取自同一份合并材料。活动状态只表示逻辑记录是否在 `ctx.sessions` 中存活,而不表示结果或可恢复性。缺少持久化时,枚举退化为仅存活枚举而不是报错——此时冷 child 本就无法恢复。缺少 `ctx.sessionProjections` 注册表时,`listChildren()` 抛出携带错误码 `SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE` 的 `SubagentError`,缺少会话存储时则抛出 `SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE`,两者都在任何读取之前检查,因此零 child 的部署同样确定失败;列表工具在插件加载时要求 `ctx.subagents` 与 `ctx.agents`。UI 等服务消费方可以展示两种模式,并为无标签的一次性 child 选择回退展示;面向模型的 `list_agents` 适配器([dsh-tool-subagent-control](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/subagent/tool-subagent-control) 中可单独加载的 `/list-agents` 插件)则只保留可继续条目,并通过在线 Agent 注册表将状态细化为自己的 `running`/`idle`/`ready` 词汇,其中 `ready` 把仅存于存储的 child 命名为可恢复而非终态。枚举不会查询继续执行管理器的 Activation map、Agent 注册表或提供方可用性;`send_message` 仍是消息送达时的权威操作,列表中的运行中可继续 child 仍可能因所有权冲突而拒绝投递。读路径的设计理由见[列表身份投影 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-06-subagent-list-identity-projection.zh.md)。
293
293
 
294
294
  `SubagentRuntime.listDescendants(rootSessionId)` 将同一份实时优先语料与基于投影的解释应用到根的完整后代树,并按稳定 pre-order 输出。普通会话和一次性 child 仍作为遍历节点,因此其下的可继续后代仍可发现;只有 `origin: 'subagent'` 的候选会生成条目。每个返回的 child 或 diagnostic 都从枚举所得的持久 header 附加树位置;冷检查在提供身份前还会重新校验完整生命周期:
295
295
 
@@ -308,6 +308,8 @@ type SubagentDescendantListEntry = SubagentListEntry & {
308
308
  ```
309
309
 
310
310
 
311
+ <a id="the-terminal-result-subagentresult"></a>
312
+
311
313
  ## 终态结果:`SubagentResult`
312
314
 
313
315
  单次 run 的最终产出,由 `SubagentRun.result` resolve。`structured` 仅在请求了 `outputSchema` 且成功满足时才存在;请求 schema 不保证一定能得到它,当子 agent 失败或结束时未产出有效 capture 时,提供方可能返回 `stopReason: 'error'`。提供方可以为非 `completed` 结果附带安全且不属于 assistant 内容的 `diagnostic`;在消费方将它与 `output` 分开呈现前,提供方会排除工具输入、文件内容、环境值、凭证与原始协议载荷,并把完整值限制在 4096 个 UTF-8 字节以内。非 `completed` 的 `stopReason` 意味着 `output` 可能不完整——消费方将其映射为 `isError` 的工具结果,而非将部分输出报告为成功。
@@ -485,7 +487,7 @@ spawn 和 fork 后端通过 `parent.ctx` 创建一个普通的单次 agent,将
485
487
 
486
488
  ## Cordis API
487
489
 
488
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
490
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
489
491
 
490
492
  <a id="ctxsubagents--subagentruntime"></a>
491
493
 
@@ -670,7 +672,7 @@ async start(name: string, request: SubagentStartRequest): Promise<SubagentRun>
670
672
 
671
673
  Types: [Agent](./core.md) · [ContentBlock](./llm-streaming.md) · [MessageId](./llm-streaming.md) · [SessionId](./core.md)
672
674
 
673
- Source: [`packages/subagent/subagent/src/index.ts:171`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
675
+ Source: [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
674
676
 
675
677
  <a id="subagent-events"></a>
676
678
 
@@ -696,7 +698,7 @@ A published child settled. Scope-filtered dispatch uses the same delegating pare
696
698
 
697
699
  Types: [Scoped](./scope.md)
698
700
 
699
- Source: [`packages/subagent/subagent/src/index.ts:166`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
701
+ Source: [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
700
702
 
701
703
  <a id="subagentprovider-added--emit"></a>
702
704
 
@@ -713,7 +715,7 @@ A provider became resolvable in the registry.
713
715
  'subagent/provider-added'(provider: SubagentProvider): void
714
716
  ```
715
717
 
716
- Source: [`packages/subagent/subagent/src/index.ts:140`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
718
+ Source: [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
717
719
 
718
720
  <a id="subagentprovider-removed--emit"></a>
719
721
 
@@ -730,7 +732,7 @@ A provider left the registry. Accepted runs remain holder-owned.
730
732
  'subagent/provider-removed'(name: string): void
731
733
  ```
732
734
 
733
- Source: [`packages/subagent/subagent/src/index.ts:146`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
735
+ Source: [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
734
736
 
735
737
  <a id="subagentstart--emit"></a>
736
738
 
@@ -754,5 +756,5 @@ A provider established a published child. For in-process providers, `ctx.agents.
754
756
 
755
757
  Types: [Scoped](./scope.md)
756
758
 
757
- Source: [`packages/subagent/subagent/src/index.ts:157`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
759
+ Source: [`packages/subagent/subagent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subagent/subagent/src/index.ts)
758
760
  <!-- END GENERATED cordis-surface -->
@@ -249,7 +249,7 @@ interface SubprocessOutcome {
249
249
 
250
250
  ## 服务行为
251
251
 
252
- 抽象的 [`SubprocessRuntime`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/src/index.ts) Service Definition 规定执行世界坐标、可执行文件查找、普通 `spawn` 与 `spawnTerminal`。[`LocalSubprocessRuntime`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess-local/src/index.ts) 以 detached 进程树、按处置方式接线、凭据清除、`node-pty`、平台进程检查,以及先终止再等待退出的资源释放提供这些能力。Service Definition 约定见 [`dsh-subprocess`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/README.md),本地机制见 [`dsh-subprocess-local`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess-local/README.md)。
252
+ 抽象的 [`SubprocessRuntime`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/src/index.ts) Service Definition 规定执行世界坐标、可执行文件查找、普通 `spawn` 与 `spawnTerminal`。[`LocalSubprocessRuntime`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess-local/src/index.ts) 以 detached 进程树、按处置方式接线、凭据清除、`node-pty`、平台进程检查,以及先终止再等待退出的资源释放提供这些能力。Service Definition 约定见 [`dsh-subprocess`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/README.zh.md),本地机制见 [`dsh-subprocess-local`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess-local/README.zh.md)。
253
253
 
254
254
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
255
255
 
@@ -257,7 +257,7 @@ interface SubprocessOutcome {
257
257
 
258
258
  ## Cordis API
259
259
 
260
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
260
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
261
261
 
262
262
  <a id="ctxe2b--e2bruntime"></a>
263
263
 
@@ -274,7 +274,7 @@ Creates one lazily consumable E2B SDK handle and deletes the sandbox at timeout
274
274
  async getSandbox(): Promise<Sandbox>
275
275
  ```
276
276
 
277
- Source: [`packages/e2b/e2b/src/index.ts:74`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/e2b/e2b/src/index.ts)
277
+ Source: [`packages/e2b/e2b/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/e2b/e2b/src/index.ts)
278
278
 
279
279
  <a id="ctxsubprocess--subprocessruntime-abstract-seam"></a>
280
280
 
@@ -323,5 +323,5 @@ abstract spawn(spec: SubprocessSpawnSpec): SubprocessHandle
323
323
  abstract spawnTerminal(spec: SubprocessTerminalSpawnSpec): Promise<SubprocessTerminalHandle>
324
324
  ```
325
325
 
326
- Source: [`packages/subprocess/subprocess/src/index.ts:102`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/src/index.ts)
326
+ Source: [`packages/subprocess/subprocess/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/subprocess/subprocess/src/index.ts)
327
327
  <!-- END GENERATED cordis-surface -->
@@ -5,7 +5,7 @@ outline: [2,3]
5
5
 
6
6
  # 系统提示词组装
7
7
 
8
- [system-prompt 包](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/core/system-prompt)负责管理提示词贡献者与一次组装调用之间交换的数据。该包的 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/README.md) 记录注册、排序、作用域与渲染行为;本页记录各插件实现或传递的确切跨包类型。
8
+ [system-prompt 包](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/core/system-prompt)负责管理提示词贡献者与一次组装调用之间交换的数据。该包的 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/README.zh.md) 记录注册、排序、作用域与渲染行为;本页记录各插件实现或传递的确切跨包类型。
9
9
 
10
10
  源码:[`packages/core/system-prompt/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)。
11
11
 
@@ -93,7 +93,7 @@ interface PromptContext {
93
93
 
94
94
  ## Cordis API
95
95
 
96
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
96
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
97
97
 
98
98
  <a id="ctxsystemprompt--systemprompt"></a>
99
99
 
@@ -159,7 +159,7 @@ variable(name: string, provider: (context: AssembleContext) => string | undefine
159
159
  async assemble(context: AssembleContext = {}): Promise<PromptAssembly>
160
160
  ```
161
161
 
162
- Source: [`packages/core/system-prompt/src/index.ts:338`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)
162
+ Source: [`packages/core/system-prompt/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)
163
163
 
164
164
  <a id="system-prompt-events"></a>
165
165
 
@@ -189,7 +189,7 @@ Expert waterfall over the assembled sections, contexts, tools, and variables. Sc
189
189
 
190
190
  Types: [Scoped](./scope.md)
191
191
 
192
- Source: [`packages/core/system-prompt/src/index.ts:31`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)
192
+ Source: [`packages/core/system-prompt/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)
193
193
 
194
194
  <a id="system-promptchange--emit"></a>
195
195
 
@@ -206,5 +206,5 @@ Emitted when any prompt provider changes. This registry notification is unfilter
206
206
  'system-prompt/change'(): void
207
207
  ```
208
208
 
209
- Source: [`packages/core/system-prompt/src/index.ts:37`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)
209
+ Source: [`packages/core/system-prompt/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/system-prompt/src/index.ts)
210
210
  <!-- END GENERATED cordis-surface -->
@@ -5,7 +5,7 @@ outline: [2,3]
5
5
 
6
6
  # 持久 PTY 会话
7
7
 
8
- PTY 后端、`ctx.terminals` 与面向模型的消费方共享的类型。[持久 PTY Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.md) 负责记录决策依据;本页记录来自 [`packages/terminal/terminal/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/terminal/terminal/src/types.ts) 的跨包词汇。
8
+ PTY 后端、`ctx.terminals` 与面向模型的消费方共享的类型。[持久 PTY Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.zh.md) 负责记录决策依据;本页记录来自 [`packages/terminal/terminal/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/terminal/terminal/src/types.ts) 的跨包词汇。
9
9
 
10
10
  ## 标识与就绪
11
11
 
@@ -99,7 +99,7 @@ interface TerminalSendResult {
99
99
 
100
100
  ## Cordis API
101
101
 
102
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
102
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
103
103
 
104
104
  <a id="ctxterminals--terminalsessionservice"></a>
105
105
 
@@ -183,5 +183,5 @@ list(owner: Agent): TerminalSessionSnapshot[]
183
183
 
184
184
  Types: [Agent](./core.md)
185
185
 
186
- Source: [`packages/terminal/terminal/src/index.ts:105`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/terminal/terminal/src/index.ts)
186
+ Source: [`packages/terminal/terminal/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/terminal/terminal/src/index.ts)
187
187
  <!-- END GENERATED cordis-surface -->
@@ -51,7 +51,7 @@ interface TokenSurfaceNode {
51
51
 
52
52
  ## Cordis API
53
53
 
54
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
54
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
55
55
 
56
56
  <a id="ctxtokenmeter--tokenmeter"></a>
57
57
 
@@ -89,5 +89,5 @@ estimateMessage(message: Message): number
89
89
 
90
90
  Types: [EpochHeader](./session.md) · [Message](./llm-streaming.md) · [Session](./session.md)
91
91
 
92
- Source: [`packages/llm/token-meter/src/index.ts:74`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/token-meter/src/index.ts)
92
+ Source: [`packages/llm/token-meter/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/token-meter/src/index.ts)
93
93
  <!-- END GENERATED cordis-surface -->
@@ -466,7 +466,7 @@ type ObjectJsonSchema = JsonSchemaNode & { type: 'object' }
466
466
  - `ToolCallView`(待执行):`{ card: 'generic', title, kind?, rawInput?, content?, locations? }`(默认卡片;`locations` 是 `{ path, line? }[]`,表示调用读取/修改的文件,供编辑器跟随)、`{ card: 'terminal', title, description?, cwd? }`(shell 命令→终端卡片)、或 `{ card: 'diff', title, diffs, locations? }`(文件创建/修改→行内 diff 卡片;`diffs` 是 `{ path, oldText, newText }[]`,新文件时 `oldText: null`)。
467
467
  - `ToolResultView`(已完成):`{ card: 'generic', title?, content? }`、`{ card: 'terminal', title?, output?, exitCode?, signal? }`(捕获的运行输出 + 退出状态;有能力的 UI 显示退出状态标签,其他 UI 可以派生围栏 ` ```console ` 回退)、`{ card: 'diff', title?, diffs }`(已完成的文件变更→要展示的变更,通常是从变更前后内容计算出带上下文行的已应用 hunk,或在没有前像时的整文件 diff)、`{ card: 'search', shape, title?, truncated, total, … }`(已完成的发现型搜索→`shape: 'matches'`(grep)为按文件分组的匹配,`shape: 'paths'`(glob)为扁平路径列表;`truncated`/`total` 报告内联结果是否被截断,使 UI 永不把部分结果当作完整结果呈现;该视图不携带结果文本——无 search 卡片的 UI 回退到原始结果内容)、`{ card: 'read', title?, path, offset, lines, totalLines, lang?, content? }`(已完成的文件读取→带行号、可选语法高亮的代码视图;`offset` 是窗口请求的 1-based 起始行,即使 `lines` 为空也保留;`lang` 是从扩展名推得的语言提示,`content` 是无读取能力的 UI 回退时使用的去信封文本)、或 `{ card: 'web', kind: 'search' | 'fetch', title?, … }`(已完成的 web 检索;`kind: 'search'` 携带结构化的 `sources`/`answer?`/`truncated`,`kind: 'fetch'` 携带 `url`/`statusCode`/`truncated`,不具备 `web` 能力的 UI 回退到原始结果内容——正文不会重复进视图)。已完成视图会替换待执行视图,因此变更工具即使与调用时的片段重复也要返回 diff 结果;搜索和 web 检索都没有 `card` 的调用时对应视图(其 pending 状态保持为 generic 卡片,因为结构化结果只在 `execute` 之后才存在)。
468
468
 
469
- `ToolCallKind`(`'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'fetch' | 'other'`)用于为通用卡片选择图标。`FileLocation`(`{ path, line? }`)、`FileDiff`(`{ path, oldText, newText }`)与 `ReadFileLine`(`{ number, text }`,读取窗口中一行带 1-based 行号的内容)是共享的文件卡片词汇。该设计由[渲染意图联合类型 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.md)固定;host/client 运行时将这套中性词汇投影为各自的视图。
469
+ `ToolCallKind`(`'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'fetch' | 'other'`)用于为通用卡片选择图标。`FileLocation`(`{ path, line? }`)、`FileDiff`(`{ path, oldText, newText }`)与 `ReadFileLine`(`{ number, text }`,读取窗口中一行带 1-based 行号的内容)是共享的文件卡片词汇。该设计由[渲染意图联合类型 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-02-tool-render-intent-union.zh.md)固定;host/client 运行时将这套中性词汇投影为各自的视图。
470
470
 
471
471
  完整的展示字段文档见 [`packages/core/tools/src/presentation.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/presentation.ts)。`bash` schema 与执行器见 [shell.md](./shell.md);通用后台控制见 [jobs.md](./jobs.md)。
472
472
 
@@ -476,7 +476,7 @@ type ObjectJsonSchema = JsonSchemaNode & { type: 'object' }
476
476
 
477
477
  ## Cordis API
478
478
 
479
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
479
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
480
480
 
481
481
  <a id="ctxtools--toolruntime"></a>
482
482
 
@@ -574,7 +574,7 @@ async execute(exec: ToolExecutionInput): Promise<ToolExecutionResult>
574
574
 
575
575
  Types: [ScopeKey](./scope.md)
576
576
 
577
- Source: [`packages/core/tools/src/index.ts:787`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
577
+ Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
578
578
 
579
579
  <a id="tools-events"></a>
580
580
 
@@ -599,7 +599,7 @@ A tool was registered or unregistered, or a scoped restriction changed (the avai
599
599
  'tools/change'(): void
600
600
  ```
601
601
 
602
- Source: [`packages/core/tools/src/index.ts:207`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
602
+ Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
603
603
 
604
604
  <a id="toolscode-dispatch-log--waterfall"></a>
605
605
 
@@ -626,7 +626,7 @@ Allow a listener to replace content in the DURABLE LOG COPY of one `run_code` su
626
626
 
627
627
  Types: [ContentBlock](./llm-streaming.md) · [Scoped](./scope.md)
628
628
 
629
- Source: [`packages/core/tools/src/index.ts:189`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
629
+ Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
630
630
 
631
631
  <a id="toolsexecute--waterfall"></a>
632
632
 
@@ -650,7 +650,7 @@ Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns a nor
650
650
 
651
651
  Types: [Scoped](./scope.md)
652
652
 
653
- Source: [`packages/core/tools/src/index.ts:163`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
653
+ Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
654
654
 
655
655
  <a id="toolspost-execute--waterfall"></a>
656
656
 
@@ -675,7 +675,7 @@ Accept, replace, enrich, or block a normalized dispatch result. `next()` accepts
675
675
 
676
676
  Types: [Scoped](./scope.md)
677
677
 
678
- Source: [`packages/core/tools/src/index.ts:175`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
678
+ Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
679
679
 
680
680
  <a id="toolspre-execute--waterfall"></a>
681
681
 
@@ -698,7 +698,7 @@ Allow, deny, or ask before dispatch. `next()` delegates to allow; missing approv
698
698
 
699
699
  Types: [Scoped](./scope.md)
700
700
 
701
- Source: [`packages/core/tools/src/index.ts:152`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
701
+ Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
702
702
 
703
703
  <a id="toolsresult--emit"></a>
704
704
 
@@ -719,5 +719,5 @@ Observe the frozen, lossless-JSON final outcome. Listener failures are contained
719
719
 
720
720
  Types: [Scoped](./scope.md)
721
721
 
722
- Source: [`packages/core/tools/src/index.ts:197`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
722
+ Source: [`packages/core/tools/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/tools/src/index.ts)
723
723
  <!-- END GENERATED cordis-surface -->
@@ -5,7 +5,7 @@ outline: [2,3]
5
5
 
6
6
  # Typert 远程调用
7
7
 
8
- 以下类型由生成的 Remote 产物、Host Gateway 与消费方 API assembly 共用。[Typert Gateway Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-02-typert-remote-method-calls.md) 负责架构与传输决策;本页记录 [`dsh-typert-protocol`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/typert/protocol/src/types.ts) 和 [`dsh-api-gateway`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/gateway/src/types.ts) 中公共约定的字面定义。
8
+ 以下类型由生成的 Remote 产物、Host Gateway 与消费方 API assembly 共用。[Typert Gateway Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-08-02-typert-remote-method-calls.zh.md) 负责架构与传输决策;本页记录 [`dsh-typert-protocol`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/typert/protocol/src/types.ts) 和 [`dsh-api-gateway`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/gateway/src/types.ts) 中公共约定的字面定义。
9
9
 
10
10
  ## Lookup 与上下文声明
11
11
 
@@ -234,7 +234,7 @@ interface TypertClientRemote extends TypertRemoteNamespaceMap {
234
234
 
235
235
  ## Cordis API
236
236
 
237
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
237
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
238
238
 
239
239
  <a id="ctxapiproxy--apiproxy"></a>
240
240
 
@@ -251,7 +251,7 @@ Root interface of the unified API. New client-request domain = one new file pair
251
251
  respond(message: ClientResponse): Promise<RpcReceipt>
252
252
  ```
253
253
 
254
- Source: [`packages/host/apiproxy/src/api/index.ts:22`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/apiproxy/src/api/index.ts)
254
+ Source: [`packages/host/apiproxy/src/api/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/apiproxy/src/api/index.ts)
255
255
 
256
256
  <a id="ctxtypert--typertregistry"></a>
257
257
 
@@ -317,7 +317,7 @@ toJSONSchema(key: string, params?: z.core.ToJSONSchemaParams): z.core.JSONSchema
317
317
 
318
318
  Types: [TypertContribution](./invariants.md) · [TypertFace](./invariants.md) · [TypertPackageFilter](./invariants.md) · [TypertPackageRecord](./invariants.md) · [TypertSchemaFilter](./invariants.md) · [TypertSchemaRecord](./invariants.md)
319
319
 
320
- Source: [`packages/typert/registry/src/service.ts:446`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/typert/registry/src/service.ts)
320
+ Source: [`packages/typert/registry/src/service.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/typert/registry/src/service.ts)
321
321
 
322
322
  <a id="ctxtypertgateway--typertgatewayservice"></a>
323
323
 
@@ -335,5 +335,5 @@ Resolve strict generated definitions or conservative SRC markers against current
335
335
  async invoke(request: InvokeRemoteRequest): Promise<unknown>
336
336
  ```
337
337
 
338
- Source: [`packages/api/gateway/src/index.ts:90`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/gateway/src/index.ts)
338
+ Source: [`packages/api/gateway/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/gateway/src/index.ts)
339
339
  <!-- END GENERATED cordis-surface -->
@@ -142,7 +142,7 @@ class UserQuestionError extends HarnessError {
142
142
 
143
143
  ## Cordis API
144
144
 
145
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
145
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
146
146
 
147
147
  <a id="ctxuserquestions--userquestionservice"></a>
148
148
 
@@ -177,5 +177,5 @@ registerProvider(provider: UserQuestionProvider): () => void
177
177
  async ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>
178
178
  ```
179
179
 
180
- Source: [`packages/interaction/user-questions/src/index.ts:51`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/user-questions/src/index.ts)
180
+ Source: [`packages/interaction/user-questions/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/user-questions/src/index.ts)
181
181
  <!-- END GENERATED cordis-surface -->
@@ -5,7 +5,7 @@ outline: [2,3]
5
5
 
6
6
  # HTTP 服务器
7
7
 
8
- [dsh-host-webserver](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/host/webserver) 是 GUI 宿主的浏览器 HTTP 载体:它是一个提供 `ctx.webServer` 的 `node:http` 插件,包含具名路由注册表、index.html 转换回调,以及一个可由插件认领的回退处理器。它不属于 agent loop(智能体循环),也不是能力 seam;它不了解任何 harness 概念。其他插件负责注册所有功能路由,包括 `/api` 桥接、插件 bundle 和 HMR(热模块替换)事件流([分层说明](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.md))。该服务器只服务浏览器:Electron 通过 `file://` 加载已构建文件,并经 IPC 桥接发送 fetch 请求,不使用本服务器。
8
+ [dsh-host-webserver](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/host/webserver) 是 GUI 宿主的浏览器 HTTP 载体:它是一个提供 `ctx.webServer` 的 `node:http` 插件,包含具名路由注册表、index.html 转换回调,以及一个可由插件认领的回退处理器。它不属于 agent loop(智能体循环),也不是能力 seam;它不了解任何 harness 概念。其他插件负责注册所有功能路由,包括 `/api` 桥接、插件 bundle 和 HMR(热模块替换)事件流([分层说明](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.zh.md))。该服务器只服务浏览器:Electron 通过 `file://` 加载已构建文件,并经 IPC 桥接发送 fetch 请求,不使用本服务器。
9
9
 
10
10
  源码:[`packages/host/webserver/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/src/index.ts)
11
11
 
@@ -27,7 +27,7 @@ interface WebRoute {
27
27
  }
28
28
  ```
29
29
 
30
- 匹配顺序固定:先查 exact 表,再取最长匹配前缀,最后落到已注册的回退。注册顺序不携带任何面向请求的语义:具名路由在组合上互不相交,任何未被具名路由认领的请求都由回退席位应答;席位只有一个所有者,第二次注册会抛出异常。发布的 Web 组合用 [`dsh-host-frontend-static`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/frontend-static/src/index.ts) 认领席位,即遵循固定语义的 SPA dist 服务器:非 GET/HEAD 返回 405,越出 dist 根目录的遍历返回 403,任何未命中都以 HTTP 200 回退到 `index.html`(SPA 路由),未知扩展名按 octet-stream 发送。
30
+ 匹配顺序固定:先查 exact 表,再取最长匹配前缀,最后落到已注册的回退。注册顺序不携带任何面向请求的语义:具名路由在组合上互不相交,任何未被具名路由认领的请求都由回退席位应答;席位只有一个所有者,第二次注册会抛出异常。发布的 Web 组合用 [`dsh-host-frontend-static`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/frontend-static/src/index.ts) 认领席位,即遵循固定语义的 SPA dist 服务器:非 GET/HEAD 返回 405,越出 dist 根目录的遍历返回 403,可读的 index dist 根目录和配置的 index 路径渲染,现有文件直接提供,缺失或不是文件的目标返回空的 404,未知扩展名按 octet-stream 发送。
31
31
 
32
32
  ## 配置
33
33
 
@@ -45,9 +45,9 @@ interface Config {
45
45
 
46
46
  ## 服务
47
47
 
48
- `WebServer`(`ctx.webServer`)在激活时立即监听;监听失败(EADDRINUSE 等)会使初始化被拒绝,启动进程会报告失败的 fiber。`register(route)` 添加一条具名路由并返回其 disposer;重复的 `(kind, path)` 抛出异常,因为路由模式是组合层约定,冲突即配置错误。`tapIndex(transform)` 添加一个纯 HTML HTML 转换函数,按注册顺序应用于每个 index 响应(`/` 和每次 SPA 回退);[dsh-client-modules](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/client/modules) 用它注入启动 manifest(元数据清单)。`port` 读取监听端口,包括 `config.port` 为 0 时操作系统分配的端口。
48
+ `WebServer`(`ctx.webServer`)在激活时立即监听;监听失败(EADDRINUSE 等)会使初始化被拒绝,启动进程会报告失败的 fiber。`register(route)` 添加一条具名路由并返回其 disposer;重复的 `(kind, path)` 抛出异常,因为路由模式是组合层约定,冲突即配置错误。`collectIndexInjections()` 经一次 `webserver/index-inject` emit 收集结构化 `IndexInjection` 行,`renderIndex(html)` 把它们渲染进成功的根路径和配置 index 响应,随后再按注册顺序应用原始的 `tapIndex(transform)` 逃生口转换;[dsh-client-modules](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/client/modules) 以启动 manifest(元数据清单)行回应该事件。`port` 读取监听端口,包括 `config.port` 为 0 时操作系统分配的端口。
49
49
 
50
- 处理过程中抛出异常的请求(畸形的 % 转义撞上 `decodeURIComponent`、客户端在请求体中途断开)会记录为警告并应答 400(响应头已发出时则销毁 socket),绝不导致进程退出。dispose(资源释放)把 `close()` 与 `closeAllConnections()` 配对使用,因为处理器可能像 SSE(Server-Sent Events)那样保持响应打开,而这类连接永远不会自行结束;没有强制关闭,拆卸就会挂起。该包从不打印输出:URL 行归 shell 所有。逐包运维细节(含开发模式的 bundle 监视流水线)留在 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/README.md) 中。
50
+ 处理过程中抛出异常的请求(畸形的 % 转义撞上 `decodeURIComponent`、客户端在请求体中途断开)会记录为警告并应答 400(响应头已发出时则销毁 socket),绝不导致进程退出。dispose(资源释放)把 `close()` 与 `closeAllConnections()` 配对使用,因为处理器可能像 SSE(Server-Sent Events)那样保持响应打开,而这类连接永远不会自行结束;没有强制关闭,拆卸就会挂起。该包从不打印输出:URL 行归 shell 所有。逐包运维细节(含开发模式的 bundle 监视流水线)留在 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/README.zh.md) 中。
51
51
 
52
52
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
53
53
 
@@ -55,7 +55,7 @@ interface Config {
55
55
 
56
56
  ## Cordis API
57
57
 
58
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
58
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
59
59
 
60
60
  <a id="ctxwebserver--webserver"></a>
61
61
 
@@ -91,8 +91,9 @@ registerUpgrade(route: WebUpgradeRoute): () => void
91
91
  registerFallback(handler: WebRoute['handler']): () => void
92
92
 
93
93
  /**
94
- * Register an index.html transform, applied by the fallback owner to every
95
- * index response ({@link applyIndexTaps}) in registration order.
94
+ * Register a raw-HTML index transform, the escape hatch for markup no
95
+ * {@link IndexInjection} row expresses: {@link renderIndex} applies taps in
96
+ * registration order after rendering the structured rows.
96
97
  * @param transform - pure html-to-html function.
97
98
  * @returns the disposer removing the transform.
98
99
  */
@@ -105,7 +106,46 @@ tapIndex(transform: (html: string) => string): () => void
105
106
  * @returns the transformed body.
106
107
  */
107
108
  applyIndexTaps(html: string): string
109
+
110
+ /**
111
+ * Gather the structured injection table: one `webserver/index-inject` emit,
112
+ * every subscriber pushes its current rows. Fresh per call, so subscribers
113
+ * read live state (module graph, theme preference) at emit time.
114
+ * @returns rows in subscriber activation order.
115
+ */
116
+ collectIndexInjections(): IndexInjection[]
117
+
118
+ /**
119
+ * Render one index.html body: the structured injection table first, then
120
+ * the raw `tapIndex` transforms over the result.
121
+ * @param html - the raw index.html body.
122
+ * @returns the transformed body.
123
+ */
124
+ renderIndex(html: string): string
125
+ ```
126
+
127
+ Source: [`packages/host/webserver/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/src/index.ts)
128
+
129
+ <a id="webserver-events"></a>
130
+
131
+ ### `webserver/*` events
132
+
133
+ <a id="webserverindex-inject--emit"></a>
134
+
135
+ #### `webserver/index-inject` — emit
136
+
137
+ Collect the structured index injection table. Emitted on every index render and every worker boot-payload request; listeners push their current rows, so a row's data is read fresh at emit time.
138
+
139
+ ```ts cordis-catalog
140
+ /**
141
+ * Collect the structured index injection table. Emitted on every index
142
+ * render and every worker boot-payload request; listeners push their
143
+ * current rows, so a row's data is read fresh at emit time.
144
+ * @param table - Mutable row table; listeners append in activation order.
145
+ * @mode emit
146
+ */
147
+ 'webserver/index-inject'(table: IndexInjection[]): void
108
148
  ```
109
149
 
110
- Source: [`packages/host/webserver/src/index.ts:59`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/src/index.ts)
150
+ Source: [`packages/host/webserver/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/host/webserver/src/index.ts)
111
151
  <!-- END GENERATED cordis-surface -->