dsh-plugin-dev-kb 1.0.9 → 1.3.0

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 (169) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.en.md +14 -8
  3. package/README.md +14 -8
  4. package/docs/banner.svg +25 -0
  5. package/kb/INDEX.md +8 -2
  6. package/kb/README.md +4 -4
  7. package/kb/extra/AGENTS.md +3 -3
  8. package/kb/extra/cookbook/adding-a-remote-api.md +197 -0
  9. package/kb/extra/cookbook/adding-a-remote-api.zh.md +197 -0
  10. package/kb/extra/cookbook/adding-a-session-format-version.md +109 -0
  11. package/kb/extra/cookbook/adding-a-session-format-version.zh.md +109 -0
  12. package/kb/extra/cookbook/adding-a-vendored-package.md +1 -1
  13. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +1 -1
  14. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.md +1 -1
  15. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +1 -1
  16. package/kb/extra/deepseek-llm-api-wire-extensions.md +19 -15
  17. package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +19 -15
  18. package/kb/extra/development.md +13 -3
  19. package/kb/extra/development.zh.md +13 -3
  20. package/kb/extra/event-producer-consumer.md +49 -46
  21. package/kb/extra/event-producer-consumer.zh.md +52 -49
  22. package/kb/extra/i18n/README.md +2 -1
  23. package/kb/extra/i18n/README.zh.md +3 -2
  24. package/kb/extra/i18n/style-samples.md +2 -2
  25. package/kb/extra/i18n/translation-prompt.md +1 -1
  26. package/kb/extra/module-graph.md +493 -1002
  27. package/kb/extra/module-graph.zh.md +495 -1004
  28. package/kb/extra/rescope.md +1 -1
  29. package/kb/extra/rescope.zh.md +1 -1
  30. package/kb/extra/session-format-status.md +47 -0
  31. package/kb/extra/session-format-status.zh.md +47 -0
  32. package/kb/extra/subsystems/agent-team.md +3 -2
  33. package/kb/extra/subsystems/agent-team.zh.md +3 -2
  34. package/kb/extra/subsystems/attachment.md +157 -4
  35. package/kb/extra/subsystems/attachment.zh.md +157 -4
  36. package/kb/extra/subsystems/feedback.md +164 -30
  37. package/kb/extra/subsystems/feedback.zh.md +164 -30
  38. package/kb/extra/testing.md +9 -4
  39. package/kb/extra/testing.zh.md +9 -4
  40. package/kb/extra/web-styling.md +5 -0
  41. package/kb/extra/web-styling.zh.md +5 -0
  42. package/kb/meta/search-index.json +223 -151
  43. package/kb/meta/site-pages.txt +187 -181
  44. package/kb/meta/source.json +5 -5
  45. package/kb/meta/topics.md +5 -5
  46. package/kb/site/develop/basic/publish.md +1 -1
  47. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +3 -2
  48. package/kb/site/develop/practice/llm-adapter.md +4 -3
  49. package/kb/site/en/develop/basic/publish.md +1 -1
  50. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +3 -2
  51. package/kb/site/en/develop/practice/llm-adapter.md +4 -3
  52. package/kb/site/en/guide/network-proxy.md +87 -0
  53. package/kb/site/en/guide/providers.md +70 -17
  54. package/kb/site/en/guide/python-sdk.md +19 -3
  55. package/kb/site/en/guide/schedule.md +2 -0
  56. package/kb/site/en/reference/agent-lifecycle.md +17 -8
  57. package/kb/site/en/reference/api-gateway.md +2 -2
  58. package/kb/site/en/reference/capability-seams.md +24 -10
  59. package/kb/site/en/reference/config-catalog.md +322 -264
  60. package/kb/site/en/reference/cookbook/adding-a-package.md +1 -2
  61. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +10 -8
  62. package/kb/site/en/reference/cookbook/adding-a-tool.md +1 -1
  63. package/kb/site/en/reference/cookbook/extension-cookbook.md +16 -13
  64. package/kb/site/en/reference/index.md +26 -9
  65. package/kb/site/en/reference/persistence-catalog.md +189 -95
  66. package/kb/site/en/reference/subsystems/approval.md +1 -1
  67. package/kb/site/en/reference/subsystems/client-modules.md +9 -0
  68. package/kb/site/en/reference/subsystems/client-resources.md +94 -0
  69. package/kb/site/en/reference/subsystems/code-runtime.md +7 -3
  70. package/kb/site/en/reference/subsystems/commands.md +25 -16
  71. package/kb/site/en/reference/subsystems/compaction.md +10 -10
  72. package/kb/site/en/reference/subsystems/conversation.md +11 -4
  73. package/kb/site/en/reference/subsystems/core.md +173 -29
  74. package/kb/site/en/reference/subsystems/credentials.md +5 -4
  75. package/kb/site/en/reference/subsystems/filesystem.md +15 -0
  76. package/kb/site/en/reference/subsystems/goal.md +38 -2
  77. package/kb/site/en/reference/subsystems/index.md +3 -1
  78. package/kb/site/en/reference/subsystems/invariants.md +1 -1
  79. package/kb/site/en/reference/subsystems/llm-streaming.md +43 -12
  80. package/kb/site/en/reference/subsystems/lsp.md +1 -1
  81. package/kb/site/en/reference/subsystems/permission-presets.md +5 -5
  82. package/kb/site/en/reference/subsystems/persistence.md +211 -199
  83. package/kb/site/en/reference/subsystems/plan.md +3 -3
  84. package/kb/site/en/reference/subsystems/sandbox.md +2 -0
  85. package/kb/site/en/reference/subsystems/schedule.md +9 -3
  86. package/kb/site/en/reference/subsystems/scope.md +1 -1
  87. package/kb/site/en/reference/subsystems/session-projection.md +50 -24
  88. package/kb/site/en/reference/subsystems/session-query.md +19 -13
  89. package/kb/site/en/reference/subsystems/session-reference.md +29 -1
  90. package/kb/site/en/reference/subsystems/session-telemetry.md +27 -10
  91. package/kb/site/en/reference/subsystems/session-title.md +6 -6
  92. package/kb/site/en/reference/subsystems/session.md +208 -103
  93. package/kb/site/en/reference/subsystems/settings.md +30 -12
  94. package/kb/site/en/reference/subsystems/shell.md +9 -6
  95. package/kb/site/en/reference/subsystems/sidebar-right.md +151 -0
  96. package/kb/site/en/reference/subsystems/skills.md +1 -1
  97. package/kb/site/en/reference/subsystems/slots.md +41 -32
  98. package/kb/site/en/reference/subsystems/spill.md +13 -6
  99. package/kb/site/en/reference/subsystems/storage.md +28 -5
  100. package/kb/site/en/reference/subsystems/subagent.md +58 -105
  101. package/kb/site/en/reference/subsystems/subprocess.md +25 -26
  102. package/kb/site/en/reference/subsystems/system-prompt.md +18 -3
  103. package/kb/site/en/reference/subsystems/token-meter.md +4 -3
  104. package/kb/site/en/reference/subsystems/tools.md +5 -5
  105. package/kb/site/en/reference/subsystems/typert.md +18 -18
  106. package/kb/site/en/reference/subsystems/web-client.md +1 -1
  107. package/kb/site/en/reference/subsystems/workspace.md +88 -9
  108. package/kb/site/en/reference/tool-catalog.md +56 -66
  109. package/kb/site/en/reference/tool-execution-pipeline.md +2 -2
  110. package/kb/site/guide/network-proxy.md +87 -0
  111. package/kb/site/guide/providers.md +70 -17
  112. package/kb/site/guide/python-sdk.md +19 -3
  113. package/kb/site/guide/schedule.md +2 -0
  114. package/kb/site/reference/agent-lifecycle.md +17 -8
  115. package/kb/site/reference/api-gateway.md +2 -2
  116. package/kb/site/reference/capability-seams.md +24 -10
  117. package/kb/site/reference/config-catalog.md +321 -263
  118. package/kb/site/reference/cookbook/adding-a-package.md +1 -2
  119. package/kb/site/reference/cookbook/adding-a-settings-card.md +10 -8
  120. package/kb/site/reference/cookbook/adding-a-tool.md +1 -1
  121. package/kb/site/reference/cookbook/extension-cookbook.md +16 -13
  122. package/kb/site/reference/index.md +26 -9
  123. package/kb/site/reference/persistence-catalog.md +190 -96
  124. package/kb/site/reference/subsystems/approval.md +1 -1
  125. package/kb/site/reference/subsystems/client-modules.md +9 -0
  126. package/kb/site/reference/subsystems/client-resources.md +94 -0
  127. package/kb/site/reference/subsystems/code-runtime.md +7 -3
  128. package/kb/site/reference/subsystems/commands.md +25 -16
  129. package/kb/site/reference/subsystems/compaction.md +10 -10
  130. package/kb/site/reference/subsystems/conversation.md +11 -4
  131. package/kb/site/reference/subsystems/core.md +173 -29
  132. package/kb/site/reference/subsystems/credentials.md +5 -4
  133. package/kb/site/reference/subsystems/filesystem.md +15 -0
  134. package/kb/site/reference/subsystems/goal.md +38 -2
  135. package/kb/site/reference/subsystems/index.md +14 -12
  136. package/kb/site/reference/subsystems/invariants.md +1 -1
  137. package/kb/site/reference/subsystems/llm-streaming.md +43 -12
  138. package/kb/site/reference/subsystems/lsp.md +1 -1
  139. package/kb/site/reference/subsystems/permission-presets.md +5 -5
  140. package/kb/site/reference/subsystems/persistence.md +210 -198
  141. package/kb/site/reference/subsystems/plan.md +3 -3
  142. package/kb/site/reference/subsystems/schedule.md +9 -3
  143. package/kb/site/reference/subsystems/scope.md +1 -1
  144. package/kb/site/reference/subsystems/session-projection.md +50 -24
  145. package/kb/site/reference/subsystems/session-query.md +19 -13
  146. package/kb/site/reference/subsystems/session-reference.md +29 -1
  147. package/kb/site/reference/subsystems/session-telemetry.md +27 -10
  148. package/kb/site/reference/subsystems/session-title.md +6 -6
  149. package/kb/site/reference/subsystems/session.md +208 -103
  150. package/kb/site/reference/subsystems/settings.md +30 -12
  151. package/kb/site/reference/subsystems/shell.md +9 -6
  152. package/kb/site/reference/subsystems/sidebar-right.md +151 -0
  153. package/kb/site/reference/subsystems/skills.md +1 -1
  154. package/kb/site/reference/subsystems/slots.md +41 -32
  155. package/kb/site/reference/subsystems/spill.md +13 -6
  156. package/kb/site/reference/subsystems/storage.md +28 -5
  157. package/kb/site/reference/subsystems/subagent.md +58 -105
  158. package/kb/site/reference/subsystems/subprocess.md +25 -26
  159. package/kb/site/reference/subsystems/system-prompt.md +18 -3
  160. package/kb/site/reference/subsystems/token-meter.md +4 -3
  161. package/kb/site/reference/subsystems/tools.md +5 -5
  162. package/kb/site/reference/subsystems/typert.md +18 -18
  163. package/kb/site/reference/subsystems/web-client.md +1 -1
  164. package/kb/site/reference/subsystems/workspace.md +88 -9
  165. package/kb/site/reference/tool-catalog.md +55 -65
  166. package/kb/site/reference/tool-execution-pipeline.md +2 -2
  167. package/lib/index.js +25 -44
  168. package/package.json +3 -2
  169. package/skills/dsh-plugin-dev-kb.md +4 -4
@@ -20,7 +20,7 @@ outline: [2,3]
20
20
  | `agent-loop/` | 实现公开 `Agent` 约定的具体 driver(`ctx.agentLoop`) | 本页 |
21
21
  | `scope/` | 注册表与循环用于构建按 agent 作用域的注册原语 | [scope.md](./scope.md) |
22
22
 
23
- `scope/` 是这里唯一的非服务包:一个零依赖库(`createScope`/`scopeOf`/`scopeTarget`),在模块图中位于 `session/` 与 `system-prompt/` 之下,正是为了让它们消费它而不形成环。`agent-loop` 是公开 `Agent` 约定的唯一具体实现,放在这里因为它是 harness 的默认产品循环;它在 `ctx.agents.withInitiator()` 内运行每个 driver。扩展插件依赖 `agent`——包括需要发起 Agent 时——而绝不直接依赖 `agent-loop`,因此循环保持可替换。把这条主干接成可运行 agent 的默认组合是 [`examples/agent-spine-demo`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/examples/agent-spine-demo/README.zh.md)
23
+ `scope/` 是这里唯一的非服务包:一个零依赖库(`createScope`/`scopeOf`/`scopeTarget`),在模块图中位于 `session/` 与 `system-prompt/` 之下,正是为了让它们消费它而不形成环。`agent-loop` 是公开 `Agent` 约定的唯一具体实现,放在这里因为它是 harness 的默认产品循环;它在 `ctx.agents.withInitiator()` 内运行每个 driver。扩展插件依赖 `agent`——包括需要发起 Agent 时——而绝不直接依赖 `agent-loop`,因此循环保持可替换。[`dsh-base`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/bundle/base/README.zh.md) 是默认产品组合,[`dsh-sdk-minimal`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/bundle/sdk-minimal/README.zh.md) 则声明一棵更小的独立配置树。
24
24
 
25
25
  <a id="creation-and-ownership"></a>
26
26
 
@@ -51,9 +51,9 @@ interface AgentHandle {
51
51
  }
52
52
  ```
53
53
 
54
- `CreateAgentOptions` 携带共享标识以及新 agent 发布前所需的一切:会话元数据(`meta`——已校验的 `cwd`、fork 谱系、seed 边界、来源分类、委派深度)、fork 用的可选 `seed` 回放前缀、按 agent 的 `AgentOptions`、仅创建期有效的取消 `signal`,以及 `setup`。`ResumeAgentOptions` 是持久标识的对应项:`resumeSessionId`、`agentOptions`、`signal` 与 `setup`。`setup` 回调(`AgentSetup`)在两个 id 都尚未发布时组装 agent 的作用域世界——凡经 `agentCtx` 注册的内容都先于 `agent/created` 与第一次提示词组装存在——并可返回一个在发布前一刻调用的同步 commit;setup 拒绝、commit 抛出或所有者 dispose(资源释放)都会回滚事务,两个 id 均不发布。
54
+ `CreateAgentOptions` 携带共享标识以及新 agent 发布前所需的一切:可选的存活 `parentAgent`、会话元数据(`meta`——已校验的 `cwd`、fork 谱系、`isSeeded` 标记、来源分类、委派深度与 `agentPreset`)、同级字段 `inheritedEventCount` 所表示的精确 fork cut、可选的 `seed` 回放前缀、按 agent 的 `AgentOptions`、仅创建期有效的取消 `signal`,以及 `setup`。`ResumeAgentOptions` 是持久标识的对应项:`resumeSessionId`、`parentAgent`、`agentOptions`、`signal` 与 `setup`。`setup` 回调(`AgentSetup`)在两个 id 均未发布时接收 `(agentCtx, agent)`:上下文拥有作用域注册,显式 Agent 提供确切的子 Session,Context 无需反向属性。凡经 `agentCtx` 注册的内容都先于 `agent/created` 与第一次提示词组装存在。Setup 可以返回在发布前一刻调用的同步 commit;setup 拒绝、commit 抛出或所有者 dispose(资源释放)都会回滚事务,两个 id 均不发布。
55
55
 
56
- `AgentFactory` 是注册表背后的创建接口:循环经 `ctx.agents.setFactory()` 注册其工厂,因此消费方使用 `ctx.agents` 时无需依赖具体循环包。确切的 `create`/`resume` 签名及回滚约定见下方[生成区块](#ctxagents--agentregistry)。
56
+ `AgentFactory` 是注册表背后的创建接口:循环经 `ctx.agents.setFactory()` 注册其工厂,因此消费方使用 `ctx.agents` 时无需依赖具体循环包。运行时子 Agent 的创建方设置 `options.parentAgent`;注册表把 options 与调用方 Context 传给工厂,不从其中一项推导另一项。确切的 `create`/`resume` 签名及回滚约定见下方[生成区块](#ctxagents--agentregistry)。
57
57
 
58
58
  <a id="the-agent-handle"></a>
59
59
 
@@ -72,7 +72,7 @@ interface Agent {
72
72
  readonly options: AgentOptions
73
73
  /** The live session this agent drives; its log is the durable source of truth. */
74
74
  readonly session: Session
75
- /** The agent-owned projection of durable pending work. */
75
+ /** Agent-owned access to durable pending work. */
76
76
  readonly inbox: Inbox
77
77
  /** The current lifecycle state, mirrored on every `agent/status` transition. */
78
78
  readonly status: AgentStatus
@@ -159,6 +159,44 @@ interface Agent {
159
159
  type AgentStatus = 'idle' | 'running'
160
160
  ```
161
161
 
162
+ ```ts type-equiv
163
+ /** One process-local live assistant streaming publication. */
164
+ type AssistantStreamFrame =
165
+ | {
166
+ readonly type: 'start'
167
+ readonly attemptId: LlmAttemptId
168
+ /** Monotone within one attached Agent lifecycle; replacement restarts at 1. */
169
+ readonly revision: number
170
+ readonly turn: number
171
+ readonly step: number
172
+ }
173
+ | {
174
+ readonly type: 'chunk'
175
+ readonly attemptId: LlmAttemptId
176
+ readonly revision: number
177
+ /** Dense zero-based position within the attempt. */
178
+ readonly index: number
179
+ /** Safe-integer timestamp reused by the durable embedded stream. */
180
+ readonly time: number
181
+ readonly chunk: StreamChunk
182
+ }
183
+ | {
184
+ readonly type: 'end'
185
+ readonly attemptId: LlmAttemptId
186
+ readonly revision: number
187
+ /** Number of chunk frames emitted by this attempt. */
188
+ readonly index: number
189
+ /** Durable settlement committed before this notification, or live abandonment without one. */
190
+ readonly outcome:
191
+ | {
192
+ readonly kind: 'committed'
193
+ readonly eventType: 'assistant/message' | 'assistant/attempt'
194
+ readonly seq: SessionSeq
195
+ }
196
+ | { readonly kind: 'abandoned' }
197
+ }
198
+ ```
199
+
162
200
  `running` 描述整个驱动器的排空区间,可能跨越连续的排队轮次;它不能证明某个轮次仍然打开。dispose 会把 agent 从注册表移除并发出 `agent/disposed`;它不是一个终态 status 值。`followup()` 不返回句柄:其 `MessageId` 标识的是持久的 inbox 插入、认领与丢弃事实,而非之后的助手输出或轮次结束。`whenIdle()` 观察的是整个 agent,因此只有当调用方明确拥有从回执到空闲的这段区间时,才能把它称为一次 run([决策](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-30-followup-enqueue-and-owned-runs.zh.md))。
163
201
 
164
202
  ```ts type-equiv
@@ -175,16 +213,73 @@ interface AgentOptions {
175
213
  }
176
214
  ```
177
215
 
178
- 在 `agent/request` 之后,分发要求 `provider` 与 `model` 都存在。显式 `reasoningEffort` 会为该路由的首次请求提供初始值;确切模型解析会校验该值,省略时则允许填入适配器默认值。提供 `maxTokens` 时,它必须是正安全整数,并限制每次对话模型请求的输出;省略时,系统会在写入请求 header 前填入确切模型的适配器默认值,否则提供方行为保持不变。agent 作用域的 `deployment:persona` 提示词段落可以遮蔽全局默认 persona。
216
+ 在 `agent/request` 之后,分发要求 `provider` 与 `model` 都存在。显式 `reasoningEffort` 会为该路由的首次请求提供初始值;确切模型解析会校验该值,省略时则允许填入适配器默认值。提供 `maxTokens` 时,它必须是正安全整数,并限制每次对话模型请求的输出;省略时,系统会在写入请求 header 前填入确切模型的适配器默认值,否则提供方行为保持不变。agent 作用域的 `deployment:persona-prefix` 提示词段落可以遮蔽全局默认 persona。
179
217
 
180
218
  inbox 即投递词汇——agent 以持久投影形式拥有的两条有序待处理消息列表:
181
219
 
220
+ ```ts type-equiv
221
+ /** Agent-owned access to pending work; concrete storage belongs to the driver. */
222
+ interface Inbox {
223
+ /** Prompts awaiting individual turns. */
224
+ readonly nextTurn: readonly UserMessage[]
225
+ /** Input awaiting the next step boundary. */
226
+ readonly nextStep: readonly UserMessage[]
227
+
228
+ /** Durably cancel all pending input, clearing next-step before next-turn. */
229
+ clear(): void
230
+
231
+ /**
232
+ * Append one message to a pending list.
233
+ * @param target - pending list to extend.
234
+ * @param message - message to append.
235
+ */
236
+ append(target: InboxTarget, message: UserMessage): void
237
+
238
+ /**
239
+ * Prepend one message to a pending list.
240
+ * @param target - pending list to extend.
241
+ * @param message - message to prepend.
242
+ */
243
+ prepend(target: InboxTarget, message: UserMessage): void
244
+
245
+ /**
246
+ * Replace one pending message in place.
247
+ * @param messageId - identity of the pending message to replace.
248
+ * @param newMessage - replacement message.
249
+ * @returns whether the message was still pending.
250
+ */
251
+ replace(messageId: MessageId, newMessage: UserMessage): boolean
252
+
253
+ /**
254
+ * Remove one pending message.
255
+ * @param messageId - identity of the pending message to remove.
256
+ * @returns whether the message was still pending.
257
+ */
258
+ remove(messageId: MessageId): boolean
259
+
260
+ /**
261
+ * Apply standard splice semantics and durably record the normalized result.
262
+ * @param target - pending list to mutate.
263
+ * @param start - splice position.
264
+ * @param deleteCount - maximum number of messages to remove.
265
+ * @param inserted - messages to insert at the resolved position.
266
+ * @returns messages removed by the splice.
267
+ */
268
+ splice(
269
+ target: InboxTarget,
270
+ start: number,
271
+ deleteCount: number,
272
+ inserted: UserMessage[],
273
+ ): UserMessage[]
274
+ }
275
+ ```
276
+
182
277
  ```ts type-equiv
183
278
  /** One of the two ordered pending-message lists owned by an agent. */
184
279
  type InboxTarget = 'next-turn' | 'next-step'
185
280
  ```
186
281
 
187
- 每个待处理入队项就是其 `UserMessage`;`MessageId` 是唯一标识。`Inbox.append`、`prepend`、`replace`、`remove`、`clear`、`splice` `claim` 会记录规范化的持久 `agent/inbox/spliced` 变更,并拒绝重复的待处理 id。`replace(messageId, newMessage)` 与 `remove(messageId)` 通过 `MessageId` 跨两份列表定位待处理消息;替换可以改变标识,并先将旧消息作为 discarded 发布,再将新消息作为 inserted 发布。普通删除和 `clear()` 都表示取消。`claim(target)` 通过纯删除 splice 移除拟进入步骤的批次——全部 `next-step` 输入,外加轮次边界上的一条 `next-turn` 消息——且不发出 discarded 通知;循环另行逐条发出 claimed 通知。UI 投影等整体队列消费方通过持久 splice 重建 `nextTurn` `nextStep`,而跟踪单条消息的消费方使用精确的 `agent/inbox/inserted`、`claimed` 与 `discarded` 通知。
282
+ 每个待处理入队项就是其 `UserMessage`;`MessageId` 是唯一标识。结构化 `Inbox` 方法会记录规范化的持久 `agent/inbox/spliced` 变更,并拒绝重复的待处理 id。`replace(messageId, newMessage)` 与 `remove(messageId)` 通过 `MessageId` 跨两份列表定位待处理消息;替换可以改变标识,并先将旧消息作为 discarded 发布,再将新消息作为 inserted 发布。普通删除和 `clear()` 都表示取消。在步骤边界,dsh-agent-loop 包内部的 `ReactLoopInbox` 会通过纯删除 splice 移除拟进入步骤的批次——全部 `next-step` 输入,外加轮次边界上的一条 `next-turn` 消息——且不发出 discarded 通知,随后逐条发出 claimed 通知。仅供循环使用的待处理检测与领取操作不属于 `Agent.inbox`。每个 `ReactLoopInbox` 构造函数都从其 agent 作用域贡献标准 `inbox` 投影;注册表通过引用计数在多个 agent 之间共享该定义,其 cell 是唯一 live 状态,同一份折叠也服务于冷消费方。该 fold 会拒绝不安全或越界的 splice 坐标,以及跨两份列表重复的标识,并通过事件 seq 指出格式错误的持久历史。跟踪单条消息的消费方使用精确的 `agent/inbox/inserted`、`claimed` 与 `discarded` 通知。
188
283
 
189
284
  取消:
190
285
 
@@ -263,7 +358,7 @@ type SessionStartSource = 'startup' | 'resume' | 'clear' | 'compact'
263
358
 
264
359
  `Session` 是一份类型化 `SessionEvent` 的**仅追加日志**——唯一的真源。LLM 消息历史从日志*派生*(`deriveMessages()`),而非单独存储。每个条目携带单调的 `seq`、`time` 与按 `type` 判别的 `data` payload;surface 变体还可以在 `sourceEventSeqs` 中列出被引用的较早事件,并携带 `surfaceOp`。
265
360
 
266
- `SessionEvent` 信封的确切条件字段、十二种核心事件变体(`turn/start`、`turn/end`、`step/start`、`step/end`、`user/message`、`assistant/chunk`、`assistant/message`、`tool/call`、`tool/result`、`request/header`、`request/context`、`session/end-seed`)、`deriveMessages()` 投影规则、`TurnEndReason` 原因以及执行封闭和独立事件规则都在 **[session.md](./session.md)** 中。日志如何持久化——`SessionPersistence` 接口、JSONL/SQLite 后端、`session/flush` 检查点、崩溃恢复与 `SessionHeader`——则在 **[persistence.md](./persistence.md)** 中。
361
+ `SessionEvent` 信封的确切条件字段、十三种核心事件变体(`turn/start`、`turn/end`、`step/start`、`step/end`、`user/message`、`system/message`、`assistant/message`、`assistant/attempt`、`tool/call`、`tool/result`、`request/header`、`request/context`、`session/end-seed`)、`deriveMessages()` 投影规则、`TurnEndReason` 原因以及执行封闭和独立事件规则都在 **[session.md](./session.md)** 中。日志如何持久化——`SessionPersistence` 接口、JSONL provider、`session/flush` 检查点、崩溃恢复与 `SessionHeader`——则在 **[persistence.md](./persistence.md)** 中。
267
362
 
268
363
  ## `ToolDefinition`
269
364
 
@@ -314,9 +409,9 @@ declare module '@deepseek-ai/dsh-llm' {
314
409
 
315
410
  ### 品牌化 ID
316
411
 
317
- 在包之间传递的 ID 都经过**品牌化**——结构上是字符串,但在类型层面不可互换(不能把 `SessionId` 传给需要 `ToolCallId` 的位置)。每种类型通过各自的工厂构造;比较、日志记录和 JSON 行为与普通字符串相同。
412
+ 在包之间传递的 ID 都经过**品牌化**——结构上是字符串,但在类型层面不可互换(不能把 `SessionId` 传给需要 `ToolCallId` 的位置)。构造使用共享 `brandString<T>()` helper 或所属方自定义的校验工厂;比较、日志记录和 JSON 行为与普通字符串相同。
318
413
 
319
- `Branded<B>` 原语位于独立的纯类型包 [dsh-brand](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/util/brand) 中(没有运行时代码,也不依赖 harness 包),因此任何包都能品牌化其拥有的 id,而无需依赖无关的能力包。
414
+ `Branded<B>` 原语与无状态构造函数位于 [dsh-brand](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/util/brand),该包不依赖 harness 能力。`brandString<T>()` 应用仅编译期存在的字符串品牌。
320
415
 
321
416
  源码:[`packages/util/brand/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/util/brand/src/index.ts)
322
417
 
@@ -369,18 +464,19 @@ Concrete agent factory and driver service.
369
464
  /**
370
465
  * Create an agent and session under one caller-supplied identity, owned by
371
466
  * the accessing fiber. Constructor-driven config calls mint a fresh combined
372
- * id before entering this boundary.
467
+ * id before entering this boundary. When a persistence backend is mounted,
468
+ * the session's durable identity and any seed are stored before publication.
373
469
  * @param id - shared agent/session identity.
374
470
  * @param options - concrete loop options.
375
471
  * @param meta - optional fresh-session workspace metadata.
376
472
  * @returns the published running agent.
377
473
  */
378
- create(id: SessionId, options: AgentOptions = {}, meta: Pick<SessionHeader, 'cwd'> = {}): Agent
474
+ async create(id: SessionId, options: AgentOptions = {}, meta: Pick<SessionHeader, 'cwd'> = {}): Promise<Agent>
379
475
 
380
476
  /**
381
477
  * Create an owned agent on a caller-supplied session id.
382
478
  * @param ownerCtx - caller context that structurally owns the lifecycle.
383
- * @param options - identities, session seed/metadata, loop options, setup, and cancellation.
479
+ * @param options - identities, optional live parent, session seed/metadata, loop options, setup, and cancellation.
384
480
  * @returns the published handle.
385
481
  */
386
482
  async createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise<AgentHandle>
@@ -388,7 +484,7 @@ async createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise<Agent
388
484
  /**
389
485
  * Resume an owned agent from the configured persistence service.
390
486
  * @param ownerCtx - caller context that owns load, setup, and the live lifecycle.
391
- * @param options - persisted identity, loop options, setup, and cancellation.
487
+ * @param options - persisted identity, optional live parent, loop options, setup, and cancellation.
392
488
  * @returns the published handle.
393
489
  */
394
490
  async resume(ownerCtx: Context, options: ResumeAgentOptions): Promise<AgentHandle>
@@ -423,6 +519,25 @@ async list(): Promise<AgentPreset[]>
423
519
  */
424
520
  @Remote('list') async remoteExportList(): Promise<AgentPresetRoster>
425
521
 
522
+ /**
523
+ * Every preset's composition as flattened plugin rows, for plugin-listing
524
+ * surfaces beside the roster's own picker.
525
+ *
526
+ * A preset with a live standing mount answers from its newest generation's
527
+ * Loader entries — the composition new sessions join — even when the file
528
+ * behind it has since been edited into an unreadable state: the mount is
529
+ * what sessions actually run, so the broken verdict only applies to a
530
+ * preset nothing composed. One never composed since boot answers from its
531
+ * file, with `!!js` disabled gates evaluated against the Loader context so
532
+ * both answers reflect the same host. Reading never mounts: an unmounted
533
+ * preset is parsed, not composed, so listing a preset's plugins cannot
534
+ * activate them early. A composition that stopped reading between
535
+ * discovery's health verdict and this read is reported broken with the
536
+ * raced reason rather than dropped.
537
+ * @returns one composition per roster preset, in roster order.
538
+ */
539
+ async compositionInventory(): Promise<AgentPresetComposition[]>
540
+
426
541
  /**
427
542
  * Resolve one preset by id.
428
543
  *
@@ -501,8 +616,8 @@ async read(id: string): Promise<string>
501
616
  * One preset's composition text with the roster row it belongs to.
502
617
  * @param agentPreset - the preset id.
503
618
  * @returns the composition beside its trust and published metadata.
504
- * @throws {TypertRemoteFailure} `bad-request` for an empty id, or
505
- * `agent-preset-not-found` when no configured root supplies it.
619
+ * @throws {RemoteError} `gateway/bad-request` for an empty id, or
620
+ * `agent-preset/not-found` when no configured root supplies it.
506
621
  */
507
622
  @Remote('read') async readDocument(agentPreset: string): Promise<AgentPresetDocument>
508
623
 
@@ -529,8 +644,8 @@ async copy(from: string, id: string, name?: string): Promise<void>
529
644
  * @param id - the new preset id.
530
645
  * @param name - the copy's optional display name.
531
646
  * @returns once the copy is stored.
532
- * @throws {TypertRemoteFailure} with the corresponding stable preset code
533
- * and details when the copy is refused.
647
+ * @throws {RemoteError} with the corresponding stable preset code and
648
+ * details when the copy is refused.
534
649
  */
535
650
  @Remote('copy') async remoteExportCopy(from: string, id: string, name?: string): Promise<void>
536
651
 
@@ -546,8 +661,8 @@ async remove(id: string): Promise<void>
546
661
  * Delete one preset through the Remote API.
547
662
  * @param id - the preset id.
548
663
  * @returns once the preset is deleted.
549
- * @throws {TypertRemoteFailure} with the corresponding stable preset code
550
- * and details when deletion is refused.
664
+ * @throws {RemoteError} with the corresponding stable preset code and
665
+ * details when deletion is refused.
551
666
  */
552
667
  @Remote('deletePreset') async remoteExportDelete(id: string): Promise<void>
553
668
 
@@ -598,8 +713,8 @@ async recompose(agentCtx: Context, id: string): Promise<AgentPreset>
598
713
  * @param agent - the session's live agent, resolved from the wire identity.
599
714
  * @param agentPreset - the preset to compose the agent from instead.
600
715
  * @returns the preset id that was recorded.
601
- * @throws {TypertRemoteFailure} with `bad-request`, `agent-preset-locked`,
602
- * `agent-preset-not-found`, or `agent-preset-invalid` when refused.
716
+ * @throws {RemoteError} with `gateway/bad-request`, `agent-preset/locked`,
717
+ * `agent-preset/not-found`, or `agent-preset/invalid` when refused.
603
718
  */
604
719
  @Remote('select') async select(agent: Agent, agentPreset: string): Promise<string>
605
720
 
@@ -634,7 +749,8 @@ Initiator methods provide same-process causal attribution only. Ambient presence
634
749
  * Read the Agent that initiated the inherited asynchronous driver chain.
635
750
  * Use this optional form for logging, tracing, metrics, or host attribution
636
751
  * that also supports agentless calls. When a parent creates a child, setup
637
- * reports the causal parent while `agentCtx.agent` identifies the child.
752
+ * reports the causal parent while the setup callback's Agent parameter
753
+ * identifies the child.
638
754
  * @returns the inherited Agent, or `undefined` outside an initiator boundary
639
755
  * and inside an explicit clearing boundary.
640
756
  * @throws when this service instance has been disposed.
@@ -699,7 +815,7 @@ setFactory(factory: AgentFactory): () => void
699
815
  * agent): this constructs the agent and its session. Rejects if no factory is
700
816
  * registered or creation/setup fails. The resolved {@link AgentHandle} lets
701
817
  * the owner tear down exactly this agent.
702
- * @param options - shared identity, session seed/metadata, and agent options.
818
+ * @param options - shared identity, optional live parent, session seed/metadata, and agent options.
703
819
  * @returns the handle after setup, rollback-covered publication, and loop start complete.
704
820
  */
705
821
  async create(options: CreateAgentOptions): Promise<AgentHandle>
@@ -708,7 +824,7 @@ async create(options: CreateAgentOptions): Promise<AgentHandle>
708
824
  * Load a persisted session and resume an agent on it through the registered
709
825
  * factory. Rejects if no factory is registered; the factory rejects if
710
826
  * session persistence is not configured or persistence/setup fails.
711
- * @param options - persisted identity, configuration, and optional setup.
827
+ * @param options - persisted identity, optional live parent, configuration, and setup.
712
828
  * @returns the handle after setup, rollback-covered publication, and loop start complete.
713
829
  */
714
830
  async resume(options: ResumeAgentOptions): Promise<AgentHandle>
@@ -720,7 +836,8 @@ async resume(options: ResumeAgentOptions): Promise<AgentHandle>
720
836
  * (`scopeTarget(agent, agent)`): the subject is the agent in hand, so the
721
837
  * emits are scope-filtered regardless of which context invoked `register`
722
838
  * (calling through `agent.ctx` scopes EFFECTS; dispatch scoping always
723
- * requires passing the carrier). Returns the disposer.
839
+ * requires passing the carrier). The entry is a runtime root; factory-backed
840
+ * creation uses `options.parentAgent` for child ownership. Returns the disposer.
724
841
  * @param agent - the already-constructed agent to record in the store.
725
842
  * @returns the EXACT Cordis effect disposer (single-shot; a repeat call
726
843
  * returns undefined without awaiting an in-flight teardown). Exact
@@ -740,7 +857,7 @@ register(agent: Agent): () => void
740
857
  * returned detach closure into its pre-installed composite teardown before
741
858
  * calling {@link announce}. Ordinary callers use {@link register}.
742
859
  * @param agent - the prepared, unpublished agent.
743
- * @param owner - live agent whose scoped context created this agent, or
860
+ * @param owner - explicitly supplied live runtime owner, or
744
861
  * undefined for a top-level runtime root. This is runtime ownership, not
745
862
  * the resumed session's durable parent lineage.
746
863
  * @returns an idempotent closure that removes this exact entry and emits
@@ -797,6 +914,29 @@ Source: [`packages/core/agent/src/index.ts`](https://github.com/deepseek-ai/deep
797
914
 
798
915
  ### `agent/*` events
799
916
 
917
+ <a id="agentassistant-stream--emit"></a>
918
+
919
+ #### `agent/assistant-stream` — emit
920
+
921
+ Process-local assistant-stream publication. Chunk frames are transient; the loop appends one final v2 `assistant/message` or `assistant/attempt` with the same stream before a committed end frame.
922
+
923
+ ```ts cordis-catalog
924
+ /**
925
+ * Process-local assistant-stream publication. Chunk frames are transient;
926
+ * the loop appends one final v2 `assistant/message` or `assistant/attempt`
927
+ * with the same stream before a committed end frame.
928
+ * @param payload.agent - the agent whose attempt produced the frame.
929
+ * @param payload.frame - one ordered start, chunk, or end publication.
930
+ * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
931
+ * @mode emit
932
+ */
933
+ 'agent/assistant-stream'(this: Scoped<Agent>, payload: { agent: Agent; frame: AssistantStreamFrame }): void
934
+ ```
935
+
936
+ Types: [Scoped](./scope.md)
937
+
938
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
939
+
800
940
  <a id="agentcreated--emit"></a>
801
941
 
802
942
  #### `agent/created` — emit
@@ -962,14 +1102,18 @@ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek
962
1102
 
963
1103
  #### `agent/request` — waterfall
964
1104
 
965
- Replace the frozen call configuration. `await next()` yields the config the machine would use (agent options on the first request, the logged header afterwards); return a replacement to switch. Model-visible content must use logged channels; this waterfall cannot mutate messages.
1105
+ Replace the frozen call configuration. `await next()` yields the config the machine would use (agent options on the first request, the logged header afterwards); return a replacement to switch. On step admission, this runs after assembly and `step/start`, before the system prompt and accepted user batch are committed. Cancellation here or during subsequent `prepareCall()` resolution commits neither. The prepared call capability governs prompt admission. Model-visible content must use logged channels; this waterfall cannot mutate messages.
966
1106
 
967
1107
  ```ts cordis-catalog
968
1108
  /**
969
1109
  * Replace the frozen call configuration. `await next()` yields the config
970
1110
  * the machine would use (agent options on the first request, the logged
971
- * header afterwards); return a replacement to switch. Model-visible
972
- * content must use logged channels; this waterfall cannot mutate messages.
1111
+ * header afterwards); return a replacement to switch. On step admission,
1112
+ * this runs after assembly and `step/start`, before the system prompt and
1113
+ * accepted user batch are committed. Cancellation here or during subsequent
1114
+ * `prepareCall()` resolution commits neither. The prepared call capability
1115
+ * governs prompt admission. Model-visible content must use logged channels;
1116
+ * this waterfall cannot mutate messages.
973
1117
  * @param payload.agent - the agent making the model call.
974
1118
  * @param payload.turn - the open turn number.
975
1119
  * @param payload.step - the step whose request this is.
@@ -230,9 +230,10 @@ Host service backing the generated `ctx.remote.credentials` namespace. It carrie
230
230
  * Describe several references for one configuration surface. Batched because
231
231
  * a settings page describes every reference its rows name at once, and one
232
232
  * round trip keeps those rows from settling separately.
233
- * @param refs - reference names, at most {@link MAX_DESCRIBE_REFS}; a name outside the grammar rejects the whole call as `bad-request`.
233
+ * @param refs - reference names, at most {@link MAX_DESCRIBE_REFS}; a name outside the grammar
234
+ * rejects the whole call as `gateway/bad-request`.
234
235
  * @returns one view per requested name, keyed by that name.
235
- * @throws TypertRemoteFailure when the request is invalid or no credential provider is mounted.
236
+ * @throws RemoteError when the request is invalid or no credential provider is mounted.
236
237
  */
237
238
  @Remote async describe(refs: string[]): Promise<Record<string, CredentialInfo>>
238
239
 
@@ -241,14 +242,14 @@ Host service backing the generated `ctx.remote.credentials` namespace. It carrie
241
242
  * this direction only: no read path returns it.
242
243
  * @param ref - reference name to store under.
243
244
  * @param value - the non-empty secret value.
244
- * @throws TypertRemoteFailure when the request is invalid, no provider is mounted, or the provider refuses the write.
245
+ * @throws RemoteError when the request is invalid, no provider is mounted, or the provider refuses the write.
245
246
  */
246
247
  @Remote async set(ref: string, value: string): Promise<void>
247
248
 
248
249
  /**
249
250
  * Remove one reference from a configuration surface.
250
251
  * @param ref - reference name to remove.
251
- * @throws TypertRemoteFailure when the request is invalid, no provider is mounted, or the provider refuses the write.
252
+ * @throws RemoteError when the request is invalid, no provider is mounted, or the provider refuses the write.
252
253
  */
253
254
  @Remote async unset(ref: string): Promise<void>
254
255
  ```
@@ -399,6 +399,21 @@ abstract streamText(target: FsTarget, signal?: AbortSignal): Promise<AsyncIterab
399
399
  */
400
400
  abstract readBytes(target: FsTarget, signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array>
401
401
 
402
+ /**
403
+ * Read one byte window of the regular file as raw bytes with no decoding or
404
+ * binary rejection: the bytes at `[offset, offset + length)`, shorter when
405
+ * the file ends inside the window and empty when `offset` lies at or past
406
+ * its end. The window is the bound here, not the file: a backend transfers
407
+ * at most `length` bytes of content beyond the prefix it skips to reach
408
+ * `offset` and never buffers the whole file, so the caller's cap on `length`
409
+ * is the guard against unbounded buffering.
410
+ * @param target - the resolved target to read.
411
+ * @param range - `offset`, the 0-based first byte, and `length`, the largest byte count; both non-negative integers.
412
+ * @param signal - aborts the read.
413
+ * @returns the window's bytes, at most `length` long.
414
+ */
415
+ abstract readByteRange(target: FsTarget, range: { offset: number; length: number }, signal?: AbortSignal): Promise<Uint8Array>
416
+
402
417
  /**
403
418
  * List direct children of a directory in stable name order. Returns resolved
404
419
  * child targets plus cheap metadata only; never reads file contents.
@@ -72,6 +72,25 @@ interface GoalView extends GoalSnapshot {
72
72
  }
73
73
  ```
74
74
 
75
+ 服务还会在不改变持久状态的情况下发布进程本地 activation 边沿;客户端消费该事件获得实时状态。
76
+
77
+ ```ts type-equiv
78
+ /** Live process-local activation update forwarded to UI clients. */
79
+ interface GoalActivationChanged {
80
+ /** Session whose live goal activation changed. */
81
+ readonly sessionId: SessionId
82
+ /** Current exact activation, absent when no goal is current. */
83
+ readonly goal?: {
84
+ /** Exact current goal identity. */
85
+ readonly id: GoalId
86
+ /** Exact current goal revision. */
87
+ readonly revision: number
88
+ /** Current process-local continuation state. */
89
+ readonly activation: GoalActivation
90
+ }
91
+ }
92
+ ```
93
+
75
94
  ## 持久变更
76
95
 
77
96
  每次变更都是持久的 `goal/change` 会话事件,其载荷要么是变更后的完整快照,要么是清除墓碑。严格折叠与持久投影只从这些事件派生生命周期状态;inbox 变更不会影响 goal 状态。
@@ -145,7 +164,7 @@ interface GoalChanged {
145
164
 
146
165
  ## 服务行为
147
166
 
148
- [`GoalService`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/goal/goal/src/index.ts) 解析创建默认值、从持久 `goal/change` 事件执行严格回放折叠、校验传入的 agent(智能体)是注册表中的确切活跃实例、以比较并设置方式执行变更,并发出 `goal/changed` 通知;监听器故障会被隔离。包 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/goal/goal/README.zh.md) 定义可调用 API 和面向模型的约定。
167
+ [`GoalService`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/goal/goal/src/index.ts) 解析创建默认值、从可选注册的 `goal` 投影读取严格回放结果、校验传入的 agent(智能体)是注册表中的确切活跃实例、以比较并设置方式执行变更,并发出 `goal/changed` 通知;监听器故障会被隔离。注册表或 key 缺失时,第一次依赖它们的访问会失败。包 [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/goal/goal/README.zh.md) 定义可调用 API 和面向模型的约定。
149
168
 
150
169
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
151
170
 
@@ -168,7 +187,7 @@ Goal service (`ctx.goals`) backed exclusively by the owning session log.
168
187
  * @returns a fresh view or `undefined` when no goal is current.
169
188
  * @throws {@link GoalError} when the agent is not the registry's live instance.
170
189
  */
171
- get(agent: Agent): GoalView | undefined
190
+ @Remote('get') get(agent: Agent): GoalView | undefined
172
191
 
173
192
  /**
174
193
  * Remove process-local continuation authority without changing durable goal
@@ -256,6 +275,23 @@ Source: [`packages/goal/goal/src/index.ts`](https://github.com/deepseek-ai/deeps
256
275
 
257
276
  ### `goal/*` events
258
277
 
278
+ <a id="goalactivation-changed--emit"></a>
279
+
280
+ #### `goal/activation-changed` — emit
281
+
282
+ Process-local goal activation changed for one session.
283
+
284
+ ```ts cordis-catalog
285
+ /**
286
+ * Process-local goal activation changed for one session.
287
+ * @mode emit
288
+ * @param payload - session id and the exact current goal activation, or no goal after a clear.
289
+ */
290
+ 'goal/activation-changed'(payload: GoalActivationChanged): void
291
+ ```
292
+
293
+ Source: [`packages/goal/goal/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/goal/goal/src/types.ts)
294
+
259
295
  <a id="goalchanged--emit"></a>
260
296
 
261
297
  #### `goal/changed` — emit
@@ -9,21 +9,21 @@ outline: [2,3]
9
9
 
10
10
  | 页面 | 负责内容 |
11
11
  |---|---|
12
- | [core.md](./core.md) | `packages/core` 如何控制 agent loop(智能体循环):逐包的循环说明、agent 创建与所有权(`AgentHandle`)、`Agent` 句柄的投递/取消/拦截约定,以及全仓通用类型模式(`…Map → 派生联合`、品牌化 id) |
12
+ | [core.md](./core.md) | `packages/core` 如何控制 agent loop(智能体循环):逐包的循环说明、agent 创建与所有权(`AgentHandle`)、`Agent` 句柄的投递/取消/拦截约定,以及全仓通用类型模式(`…Map → derived-union`、品牌化 id) |
13
13
  | [llm-streaming.md](./llm-streaming.md) | `packages/llm` 的对话类型——`Message`/`ContentBlock`、组装完成的模型请求、`StreamChunk` wire protocol 和适配器约定(adapter contract)、`BlockAssembler`,以及 `LlmAdapter` 提供方约定 |
14
14
  | [token-meter.md](./token-meter.md) | 不可变的标量与位置回放度量,附带已消费日志修订号 |
15
15
  | [scope.md](./scope.md) | 作用域注册标识、dispatch 载体,以及拥有的 `Scope` 上下文 |
16
16
  | [typert.md](./typert.md) | 远程调用描述符、lookup/Context 声明、Typert 注册表,以及 Host Gateway/Client API 边界 |
17
17
  | [goal.md](./goal.md) | 持久 goal 标识、生命周期快照、激活、变更记录与 Round 归属 |
18
- | [schedule.md](./schedule.md) | 仅限 Session 内的提醒记录、持久转换、活动视图与普通对话交付 |
19
- | [todo.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/todo.zh.md) | todo 包的整列表条目类型、持久事件所有权、投影和开放轮次不变量 |
18
+ | [schedule.md](./schedule.md) | 仅限会话内的提醒记录、持久转换、活动视图与普通对话交付 |
19
+ | [todo.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/todo.zh.md) | todo 包的整列表条目类型、持久事件所有权、投影和未结束轮次不变式 |
20
20
  | [commands.md](./commands.md) | 人类命令注册表服务:定义、适配器发现、直接调用、结果与解析视图 |
21
21
  | [session.md](./session.md) | 完整的 `SessionEventMap` 变体目录、`TurnEndReason`、`deriveMessages()`、执行封闭与独立事件 |
22
- | [persistence.md](./persistence.md) | 持久性 seam:`SessionPersistence`、JSONL + SQLite 后端、`session/flush`、崩溃恢复、`SessionHeader` |
22
+ | [persistence.md](./persistence.md) | 持久性 seam:`SessionPersistence`、JSONL 提供方、`session/flush`、崩溃恢复、`SessionHeader` |
23
23
  | [settings.md](./settings.md) | 用户设置 seam:`SettingsNamespace` 注册、分层解析(默认值 → 组合 `base` → 用户文档)、owner scope、热提交 |
24
24
  | [credentials.md](./credentials.md) | 凭据 seam:配置中的 `CredentialRef` 引用(绝不含值)、按操作解析、对 UI 安全的 `CredentialInfo`、提供方来源层 |
25
25
  | [session-query.md](./session-query.md) | 逻辑记录、有界精确事件读取、关系追踪、语义筛选器/文档与全文检索结果页 |
26
- | [feedback.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/feedback.zh.md) | 绑定生命周期的逐消息反馈记录、乐观版本、伴随记录持久化与 Host Remote 契约 |
26
+ | [feedback.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/feedback.zh.md) | 绑定生命周期的逐消息反馈记录、乐观版本、伴随记录持久化与 Host Remote 约定 |
27
27
  | [session-title.md](./session-title.md) | 持久标题快照、被引用的来源消息 seq 与异步提供方约定 |
28
28
  | [session-reference.md](./session-reference.md) | 结构化跨会话引用:`SessionReferenceInput`/`Candidate`、prepared 消息上下文、稳定错误分类 |
29
29
  | [system-prompt.md](./system-prompt.md) | 逐次组装的上下文、工具提供方结果、提示词段落与协作式组装 |
@@ -36,7 +36,7 @@ outline: [2,3]
36
36
  | [terminal.md](./terminal.md) | 持久化终端 ID、后端/会话约定、发送就绪状态、有界读取与 owner 可见快照 |
37
37
  | [sandbox.md](./sandbox.md) | 每会话策略解析与进程约束 seam:文件效果模式、执行/提供方策略、`ConfinedArgv`、强制执行与故障关闭错误 |
38
38
  | [code-runtime.md](./code-runtime.md) | 代码执行 seam:`CodeRunRequest`/`Result`、绑定命名空间、捕获日志、`CodeRunFailure` 分类体系 |
39
- | [extensions.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/extensions.zh.md) | 带版本的动态 Cordis Plugin 与 Package、Host/Client 激活、审批、运行时检查和生命周期撤销 |
39
+ | [extensions.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/extensions.zh.md) | 带版本的动态 Cordis 插件与包、Host/Client 激活、审批、运行时检查和生命周期清理 |
40
40
  | [filesystem.md](./filesystem.md) | 文件系统 seam:`FsTarget`、读/写/编辑结果、观测到的文件状态、`FsErrorCode` |
41
41
  | [lsp.md](./lsp.md) | LSP 导航 seam:`LspQueryRequest`/`Result`、`LspProvider`/`Service`、四种操作、`LspError` |
42
42
  | [skills.md](./skills.md) | skill(技能)服务:发现优先级、`SkillSummary`/`SkillDefinition`、会话前缀目录、面向模型的 `skill` 加载 |
@@ -51,14 +51,16 @@ outline: [2,3]
51
51
  | [plan.md](./plan.md) | 计划模式:仅记日志的 `plan/mode` 状态、待定选择的冲刷、`PlanModeConfig`、`exit_plan_mode` 审阅流程 |
52
52
  | [invariants.md](./invariants.md) | 运行时不变式注册表:选择配置 `Config`、`InvariantInstaller`/`InvariantFailure`、空配套插件约定 |
53
53
  | [web-server.md](./web-server.md) | HTTP 载体:`WebRouteKind`/`WebRoute`、匹配顺序、可认领的回退席位、index 渲染挂接点 |
54
- | [webhook.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/webhook.zh.md) | 通过身份验证的提供方交付、任意程序化规则,以及 fire-and-forget 的 Workspace Session 创建 |
54
+ | [webhook.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/webhook.zh.md) | 通过身份验证的提供方交付、任意程序化规则,以及发起 Workspace 会话创建后不等待结果 |
55
55
  | [storage.md](./storage.md) | 存储子系统:后端约定(`StorageBackend`)、`StorageForms`、`DomainSpec`/`Domain`、`domain/changed` |
56
56
  | [workspace.md](./workspace.md) | 工作区注册表:`Workspace`/`WorkspaceId`、注册与解析、与会话 `cwd` 的关系 |
57
- | [web-client.md](./web-client.md) | 浏览器架构:启动、Remote 通信、配对的 Client model、UI adapter、Conversation 组装、Slots 与重连语义 |
58
- | [client-modules.md](./client-modules.md) | Web 插件表:`dsh.client` 声明、`WebBootGraph` 线上组合、bundle 路由与 index 转换 |
59
- | [slots.md](./slots.md) | 类型化 Web UI 组合:声明所有权、cardinality 与 scope、框架与功能注入、props 推导及当前层级 |
60
- | [conversation.md](./conversation.md) | target-neutral Session event 组装:Context identity、Location data、replay 路径、view builder 与 target 自有 render node |
57
+ | [web-client.md](./web-client.md) | 浏览器架构:启动、Remote 通信、配对的 Client model、UI 适配器、Conversation 组装、slot 与重连语义 |
58
+ | [client-modules.md](./client-modules.md) | Web 插件表:`dsh.client` 声明、`WebBootGraph` 协议格式组合、bundle 路由与 index 挂接点 |
59
+ | [slots.md](./slots.md) | 类型化 Web UI 组合:声明所有权、cardinality 与 scope、框架与功能注入、props 推导及已交付的层级结构 |
60
+ | [client-resources.md](./client-resources.md) | 客户端资源模型:`dsh-resource://<type>/…` 地址、协议提供方与 `ResourceProtocolMap`、`useResource` 全局钩子及其状态、钉住与释放 |
61
+ | [sidebar-right.md](./sidebar-right.md) | 右侧 Sidebar:资源地址与导航地址、tab 类型注册与路由、`ctx.sidebarRight` 导航服务、pane-tab slot 与 owner props、资源模型及 Workspace Files 服务 |
62
+ | [conversation.md](./conversation.md) | 目标无关的会话事件组装:上下文标识、位置数据、回放路径、视图构建器与目标自有的渲染节点 |
61
63
  | [session-projection.md](./session-projection.md) | 投影 seam:`SessionProjectionMap`、纯函数 `ProjectionDefinition` 单元、`ProjectionSnapshot` 的一致切面、变更馈送 |
62
- | [session-telemetry.md](./session-telemetry.md) | 对外会话上报能力 seam:`SessionTelemetryRecord`/`SessionTelemetrySeverity`、`SessionTelemetrySink` 约定和 `session-telemetry/record` 脱敏 waterfall |
64
+ | [session-telemetry.md](./session-telemetry.md) | 对外会话上报能力 seam:`SessionTelemetryRecord`/`SessionTelemetrySeverity`、`SessionTelemetrySink` 约定和 `session-telemetry/record` 脱敏 waterfall(瀑布式事件) |
63
65
 
64
66
  > 这些页面上的类型声明及其 JSDoc 与源码等价,并由 `pnpm run verify-type-equiv` 检查漂移(见 [development.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/development.zh.md#documenting-types-verbatim-ts-type-equiv))。普通块保留完整声明;`public-api` 块保留去除实现体的公开 class 声明。Cordis 服务与事件使用每页生成的 **Cordis API** 小节。
@@ -5,7 +5,7 @@ outline: [2,3]
5
5
 
6
6
  # 运行时不变式
7
7
 
8
- [dsh-invariants](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/runtime-diagnostics/invariants) 是面向包自有运行时不变式检查的可配置注册表服务(`ctx.invariants`)。它是一个 support 组的包,不是三包能力 seam,也不属于 agent loop(智能体循环)主干:注册表拥有选择逻辑、名称保留、子 fiber 生命周期和归因到包的失败,而每个工作区包发布一个 `./invariant` 配套插件,以自己确切的 npm 包名注册检查。检查可以断言什么(权威事件流或可变数据,绝不是服务或方法是否存在)是 [AGENTS.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/AGENTS.md#conventions) 中的运行时不变式约定;注册表设计由[不变式服务 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-19-package-owned-invariant-service.zh.md)规定。
8
+ [dsh-invariants](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/runtime-diagnostics/invariants) 是面向包自有运行时不变式检查的可配置注册表服务(`ctx.invariants`)。它是一个 support 组的包,不是三包能力 seam,也不属于 agent loop(智能体循环)主干:注册表拥有选择逻辑、名称保留、子 fiber 生命周期和归因到包的失败,而每个工作区包发布一个 `./invariant` 配套插件,以自己确切的 npm 包名注册检查。检查可以断言什么(权威事件流或可变数据,绝不是服务或方法是否存在)是 [AGENTS.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/AGENTS.md#conventions) 中的运行时不变式约定。
9
9
 
10
10
  源码:[`packages/runtime-diagnostics/invariants/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/runtime-diagnostics/invariants/src/index.ts)
11
11