dsh-plugin-dev-kb 1.0.8 → 1.0.9

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 +11 -0
  2. package/README.en.md +6 -6
  3. package/README.md +6 -6
  4. package/kb/INDEX.md +19 -5
  5. package/kb/README.md +11 -10
  6. package/kb/extra/AGENTS.md +4 -4
  7. package/kb/extra/cookbook/adding-a-vendored-package.md +2 -2
  8. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +2 -2
  9. package/kb/extra/deepseek-llm-api-wire-extensions.md +159 -0
  10. package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +159 -0
  11. package/kb/extra/development.md +8 -14
  12. package/kb/extra/development.zh.md +8 -14
  13. package/kb/extra/event-producer-consumer.md +47 -41
  14. package/kb/extra/event-producer-consumer.zh.md +47 -41
  15. package/kb/extra/glossary.md +1 -1
  16. package/kb/extra/glossary.zh.md +1 -1
  17. package/kb/extra/graph-atlas.md +0 -2
  18. package/kb/extra/graph-atlas.zh.md +0 -2
  19. package/kb/extra/i18n/README.md +4 -4
  20. package/kb/extra/i18n/README.zh.md +4 -4
  21. package/kb/extra/module-graph.md +680 -413
  22. package/kb/extra/module-graph.zh.md +681 -414
  23. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +2 -2
  24. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +2 -2
  25. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +2 -2
  26. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +2 -2
  27. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +2 -2
  28. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +2 -2
  29. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +1 -1
  30. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
  31. package/kb/extra/rescope.md +2 -2
  32. package/kb/extra/rescope.zh.md +2 -2
  33. package/kb/extra/subsystems/agent-team.md +24 -1
  34. package/kb/extra/subsystems/agent-team.zh.md +24 -1
  35. package/kb/extra/subsystems/attachment.md +12 -4
  36. package/kb/extra/subsystems/attachment.zh.md +12 -4
  37. package/kb/extra/subsystems/extensions.md +18 -0
  38. package/kb/extra/subsystems/extensions.zh.md +18 -0
  39. package/kb/extra/subsystems/feedback.md +2 -2
  40. package/kb/extra/subsystems/feedback.zh.md +2 -2
  41. package/kb/extra/subsystems/todo.md +32 -0
  42. package/kb/extra/subsystems/todo.zh.md +32 -0
  43. package/kb/extra/subsystems/webhook.md +70 -0
  44. package/kb/extra/subsystems/webhook.zh.md +70 -0
  45. package/kb/extra/testing.md +11 -10
  46. package/kb/extra/testing.zh.md +8 -7
  47. package/kb/meta/search-index.json +269 -161
  48. package/kb/meta/site-pages.txt +182 -168
  49. package/kb/meta/source.json +5 -5
  50. package/kb/meta/topics.md +14 -6
  51. package/kb/site/develop/basic/publish.md +2 -2
  52. package/kb/site/develop/basic/tool.md +1 -1
  53. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +4 -4
  54. package/kb/site/develop/framework/events.md +1 -1
  55. package/kb/site/develop/practice/dynamic-cordis.md +17 -0
  56. package/kb/site/develop/practice/llm-adapter.md +3 -3
  57. package/kb/site/en/develop/basic/publish.md +2 -2
  58. package/kb/site/en/develop/basic/tool.md +1 -1
  59. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +4 -4
  60. package/kb/site/en/develop/framework/events.md +1 -1
  61. package/kb/site/en/develop/practice/dynamic-cordis.md +17 -0
  62. package/kb/site/en/develop/practice/llm-adapter.md +3 -3
  63. package/kb/site/en/guide/github-review.md +104 -0
  64. package/kb/site/en/guide/mcp-memory.md +103 -0
  65. package/kb/site/en/guide/python-sdk.md +80 -34
  66. package/kb/site/en/guide/schedule.md +21 -0
  67. package/kb/site/en/reference/agent-lifecycle.md +1 -1
  68. package/kb/{extra → site/en/reference}/api-gateway.md +11 -9
  69. package/kb/site/en/reference/capability-seams.md +115 -67
  70. package/kb/site/en/reference/config-catalog.md +358 -164
  71. package/kb/site/en/reference/cookbook/adding-a-package.md +2 -2
  72. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +2 -2
  73. package/kb/site/en/reference/cookbook/adding-a-tool.md +11 -4
  74. package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +1 -1
  75. package/kb/site/en/reference/cookbook/extension-cookbook.md +6 -6
  76. package/kb/site/en/reference/cordis-api/inherited.md +1 -1
  77. package/kb/site/en/reference/cordis-primer.md +2 -1
  78. package/kb/site/en/reference/index.md +19 -7
  79. package/kb/site/en/reference/persistence-catalog.md +91 -44
  80. package/kb/site/en/reference/subsystems/approval.md +10 -10
  81. package/kb/site/en/reference/subsystems/client-modules.md +58 -16
  82. package/kb/site/en/reference/subsystems/code-runtime.md +3 -3
  83. package/kb/site/en/reference/subsystems/compaction.md +2 -2
  84. package/kb/site/en/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +43 -24
  85. package/kb/site/en/reference/subsystems/core.md +70 -12
  86. package/kb/site/en/reference/subsystems/credentials.md +43 -3
  87. package/kb/site/en/reference/subsystems/filesystem.md +12 -2
  88. package/kb/site/en/reference/subsystems/index.md +6 -1
  89. package/kb/site/en/reference/subsystems/jobs.md +1 -1
  90. package/kb/site/en/reference/subsystems/llm-streaming.md +132 -11
  91. package/kb/site/en/reference/subsystems/permission-presets.md +1 -1
  92. package/kb/site/en/reference/subsystems/persistence.md +22 -3
  93. package/kb/site/en/reference/subsystems/plan.md +1 -1
  94. package/kb/site/en/reference/subsystems/session-projection.md +74 -33
  95. package/kb/site/en/reference/subsystems/session-query.md +9 -1
  96. package/kb/site/en/reference/subsystems/session-reference.md +28 -7
  97. package/kb/site/en/reference/subsystems/session-telemetry.md +2 -3
  98. package/kb/site/en/reference/subsystems/session.md +260 -41
  99. package/kb/site/en/reference/subsystems/settings.md +78 -1
  100. package/kb/site/en/reference/subsystems/skills.md +23 -0
  101. package/kb/site/en/reference/subsystems/slots.md +177 -0
  102. package/kb/site/en/reference/subsystems/spill.md +2 -2
  103. package/kb/site/en/reference/subsystems/storage.md +9 -1
  104. package/kb/site/en/reference/subsystems/subagent.md +90 -23
  105. package/kb/site/en/reference/subsystems/system-prompt.md +4 -4
  106. package/kb/site/en/reference/subsystems/token-meter.md +25 -10
  107. package/kb/site/en/reference/subsystems/tools.md +39 -39
  108. package/kb/site/en/reference/subsystems/typert.md +44 -37
  109. package/kb/site/en/reference/subsystems/user-questions.md +33 -33
  110. package/kb/site/en/reference/subsystems/web-client.md +98 -0
  111. package/kb/site/en/reference/subsystems/web-server.md +11 -5
  112. package/kb/site/en/reference/subsystems/web.md +7 -1
  113. package/kb/site/en/reference/subsystems/workspace.md +95 -2
  114. package/kb/site/en/reference/tool-catalog.md +76 -18
  115. package/kb/site/en/reference/tool-execution-pipeline.md +1 -1
  116. package/kb/site/guide/github-review.md +104 -0
  117. package/kb/site/guide/mcp-memory.md +103 -0
  118. package/kb/site/guide/python-sdk.md +87 -41
  119. package/kb/site/guide/schedule.md +21 -0
  120. package/kb/site/reference/agent-lifecycle.md +1 -1
  121. package/kb/{extra/api-gateway.zh.md → site/reference/api-gateway.md} +11 -9
  122. package/kb/site/reference/capability-seams.md +115 -67
  123. package/kb/site/reference/config-catalog.md +357 -163
  124. package/kb/site/reference/cookbook/adding-a-package.md +2 -2
  125. package/kb/site/reference/cookbook/adding-a-settings-card.md +2 -2
  126. package/kb/site/reference/cookbook/adding-a-tool.md +11 -4
  127. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +1 -1
  128. package/kb/site/reference/cookbook/extension-cookbook.md +6 -6
  129. package/kb/site/reference/cordis-api/inherited.md +1 -1
  130. package/kb/site/reference/cordis-primer.md +2 -1
  131. package/kb/site/reference/index.md +19 -7
  132. package/kb/site/reference/persistence-catalog.md +87 -40
  133. package/kb/site/reference/subsystems/approval.md +10 -10
  134. package/kb/site/reference/subsystems/client-modules.md +58 -16
  135. package/kb/site/reference/subsystems/code-runtime.md +3 -3
  136. package/kb/site/reference/subsystems/compaction.md +2 -2
  137. package/kb/site/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +43 -24
  138. package/kb/site/reference/subsystems/core.md +70 -12
  139. package/kb/site/reference/subsystems/credentials.md +43 -3
  140. package/kb/site/reference/subsystems/filesystem.md +12 -2
  141. package/kb/site/reference/subsystems/index.md +6 -1
  142. package/kb/site/reference/subsystems/jobs.md +1 -1
  143. package/kb/site/reference/subsystems/llm-streaming.md +132 -11
  144. package/kb/site/reference/subsystems/persistence.md +22 -3
  145. package/kb/site/reference/subsystems/plan.md +1 -1
  146. package/kb/site/reference/subsystems/session-projection.md +74 -33
  147. package/kb/site/reference/subsystems/session-query.md +9 -1
  148. package/kb/site/reference/subsystems/session-reference.md +28 -7
  149. package/kb/site/reference/subsystems/session-telemetry.md +2 -3
  150. package/kb/site/reference/subsystems/session.md +260 -41
  151. package/kb/site/reference/subsystems/settings.md +78 -1
  152. package/kb/site/reference/subsystems/skills.md +23 -0
  153. package/kb/site/reference/subsystems/slots.md +177 -0
  154. package/kb/site/reference/subsystems/spill.md +2 -2
  155. package/kb/site/reference/subsystems/storage.md +9 -1
  156. package/kb/site/reference/subsystems/subagent.md +90 -23
  157. package/kb/site/reference/subsystems/system-prompt.md +4 -4
  158. package/kb/site/reference/subsystems/token-meter.md +25 -10
  159. package/kb/site/reference/subsystems/tools.md +39 -39
  160. package/kb/site/reference/subsystems/typert.md +44 -37
  161. package/kb/site/reference/subsystems/user-questions.md +33 -33
  162. package/kb/site/reference/subsystems/web-client.md +98 -0
  163. package/kb/site/reference/subsystems/web-server.md +11 -5
  164. package/kb/site/reference/subsystems/web.md +7 -1
  165. package/kb/site/reference/subsystems/workspace.md +95 -2
  166. package/kb/site/reference/tool-catalog.md +76 -18
  167. package/kb/site/reference/tool-execution-pipeline.md +1 -1
  168. package/package.json +2 -2
  169. package/skills/dsh-plugin-dev-kb.md +8 -6
@@ -74,7 +74,7 @@ interface SessionEventMap {
74
74
  * JSON string exactly as the model produced it (unparsed). `callId` pairs the
75
75
  * call with its `tool/result`.
76
76
  */
77
- 'tool/call': { turn: number; step: number; callId: CallId; name: string; arguments: string }
77
+ 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string }
78
78
  /**
79
79
  * A completed tool call's model-facing result, optional internal failure
80
80
  * identity, and optional tool-private `meta` presentation payload. `meta` is
@@ -93,13 +93,16 @@ interface SessionEventMap {
93
93
  error?: { name: string; code: string }
94
94
  meta?: JsonValue
95
95
  }
96
- /** Whole-list snapshot; latest write wins on replay. Log-only UI state; never derived history. */
97
- 'todo/write': { todos: TodoItem[] }
98
96
  /**
99
97
  * Full header for the next request, appended inside its step before dispatch.
100
98
  * It is log-only; the latest snapshot reconstructs the request header.
101
99
  */
102
- 'request/header': { header: EpochHeader; reason: RequestHeaderReason }
100
+ 'request/header': {
101
+ header: EpochHeader
102
+ reason: RequestHeaderReason
103
+ /** A changed header also begins a distinct model-message series. */
104
+ startsSeries?: true
105
+ }
103
106
  /**
104
107
  * Route metadata for the next request, logged only when the route or capacity
105
108
  * changes. It does not participate in request reconstruction or header equality.
@@ -133,34 +136,11 @@ interface SessionEventMap {
133
136
 
134
137
  `UserMessage` 是普通提示词、注入上下文、steering(中途引导)与实时收件箱事件共享的带标识且冻结的 user-role 值。事件包装层只会增加事件本地的位置或结果事实;条目待处理期间,loop 只额外附加驱动器自有的路由状态。
135
138
 
136
- ### `TodoItem`:一条待办项
137
-
138
- 这是 `todo/write` 事件全量列表快照中的单元。它有意保持精简:一行 `content` 加一个三态 `status`(没有 id、优先级或 `activeForm`);列表在每次写入时整体替换,因此条目无需稳定标识。见 [todo_write Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-29-todo-write-tool.zh.md)。
139
-
140
- ```ts type-equiv
141
- /**
142
- * One entry in an agent's todo list — the unit of the `todo/write`
143
- * {@link SessionEventMap} event's whole-list snapshot.
144
- *
145
- * Deliberately minimal: a human-readable `content` line and a three-state
146
- * `status`. No id, priority, or `activeForm` — the list is replaced wholesale
147
- * on every write (last-write-wins), so entries need no stable identity. The
148
- * three statuses describe the complete portable lifecycle needed by model and
149
- * UI consumers.
150
- */
151
- interface TodoItem {
152
- /** What this task is — a short imperative line shown in the UI. */
153
- content: string
154
- /** Lifecycle state. `in_progress` marks a task being worked now; parallel work may mark several. */
155
- status: 'pending' | 'in_progress' | 'completed'
156
- }
157
- ```
158
-
159
139
  <a id="the-request-header-event-requestheader"></a>
160
140
 
161
141
  ### 请求头事件:`request/header`
162
142
 
163
- 请求信封(即 `EpochHeader`:调用配置 + 适配器所提供默认值的标记 + 渲染后的系统提示词 + 已组装的工具 schema)会作为会话状态写入日志,因此每个对话请求都是日志的纯函数(见可重建性 Agent Note)。带有 reason `'initial'` 或 `'resume'` 的完整 `request/header` 快照记录每个 agent loop 实例的边界;之后请求发生变化时,系统会以 reason `'change'` 记录另一份完整快照。`foldRequestHeader(events)` 通过选择最新快照重建请求头。该事件不是 `SurfaceEventType`,不产生 LLM 消息。
143
+ 请求信封(即 `EpochHeader`:调用配置 + 适配器所提供默认值的标记 + 渲染后的系统提示词 + 已组装的工具 schema)会作为会话状态写入日志,因此每个对话请求都是日志的纯函数(见可重建性 Agent Note)。带有 reason `'initial'` 或 `'resume'` 的完整 `request/header` 快照记录每个 agent loop 实例的边界;请求变化时会追加 reason `'change'` 的快照;未变的信封显式开启消息序列或跟随 surface 替换时,会追加 reason 为 `'series'` 的快照。如果发生变化的快照所属请求同时开启序列,它会携带 `startsSeries: true`。普通的仅追加后续 Turn,以及同一模型消息序列内的后续 Step 与重试沿用最新快照。`foldRequestHeader(events)` 通过选择最新快照重建请求头。该事件不是 `SurfaceEventType`,不产生 LLM 消息。
164
144
 
165
145
  ```ts type-equiv
166
146
  /**
@@ -224,17 +204,6 @@ type SessionEvent<T extends SessionEventType = SessionEventType> = {
224
204
  /** Unix epoch milliseconds. */
225
205
  time: number
226
206
  data: SessionEventMap[K]
227
- /**
228
- * Marks an event a reader may safely skip when it does not recognize
229
- * `type`. Absent means required: a reader meeting an unrecognized type
230
- * without this marker MUST refuse to reconstruct the session instead of
231
- * silently dropping the event, because an unrecognized required event may
232
- * change how the rest of the log is interpreted. A writer sets `true` only
233
- * on purely informational records whose loss cannot affect reconstruction;
234
- * defaulting to required means a forgotten marker over-refuses (an
235
- * inconvenience) rather than silently resuming a gutted session.
236
- */
237
- ignorable?: true
238
207
  } & (K extends SurfaceEventType ? {
239
208
  /**
240
209
  * Seq numbers of earlier events that this event cites as sources
@@ -603,9 +572,9 @@ interface TurnEndReasonMap {
603
572
 
604
573
  ## 插件贡献的仅日志事件
605
574
 
606
- 插件可以通过 declaration merging 添加额外的 `SessionEventMap` 类型。这些是**仅日志**事件:不是 `SurfaceEventType`(不携带 `surfaceOp`,不参与派生历史)。事件所有方决定它们属于一个开放的执行轮次,还是可以独立位于轮次之间,并在自己的不变量配套插件中强制所需关系。生成的[持久化日志事件目录](../persistence-catalog.md)会列出每个核心或插件贡献的事件,以及其 payload、surface 标记和声明位置;压缩 seam 的 `compaction/*` 语义在 [compaction.md](./compaction.md) 中讨论。
575
+ 插件可以通过 declaration merging 添加额外的 `SessionEventMap` 类型。这些是**仅日志**事件:不是 `SurfaceEventType`(不携带 `surfaceOp`,不参与派生历史)。事件所有方决定它们属于一个开放的执行轮次,还是可以独立位于轮次之间,并在自己的不变量配套插件中强制所需关系。生成的[持久化日志事件目录](../persistence-catalog.md)会列出每个核心或插件贡献的事件;压缩 seam 的 `compaction/*` 语义在 [compaction.md](./compaction.md) 中讨论。
607
576
 
608
- 如果同一个插件事件族中的多条事件要组装成一个 Web Client Conversation Node,该事件族中的每条 start、update、result、resource 或 interruption 事件都必须携带或独立推导出同一个稳定业务 id。此要求只约束需要关联的 Node 事件族,并不要求每条 Session 事件都有业务 id;Client 因此无须根据相邻关系猜测归属,也无须扫描历史。参见 [Conversation Node 实操手册](../cookbook/adding-a-conversation-node.md)。
577
+ 如果同一个插件事件族中的多条事件要组装成一个 Web Client Conversation Node,该事件族中的每条 start、update、result、resource 或 interruption 事件都必须携带或独立推导出同一个稳定业务 id。此要求只约束需要关联的 Node 事件族,并不要求每条 Session 事件都有业务 id;Client 因此无须根据相邻关系猜测归属,也无须扫描历史。参见 [Conversation 子系统](./conversation.md)。
609
578
 
610
579
  钩子桥接层的 `hook/invoked` / `hook/result` 对(来自 `@deepseek-ai/dsh-hook-protocol`)通过 `handlerId` 关联。`UserPromptSubmit`、`PreToolUse`、`PostToolUse` 与 `Stop` 在 loop 已打开的轮次内触发,因此其 `hook/*` 记录天然位于轮次之内。`SessionStart` 不生成 `hook/*` 记录,因为它在轮次 1 之前运行;其上下文会在 inbox 中保持待处理,直到唤醒交付打开一个轮次(见[钩子桥接 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-30-hook-bridges.zh.md))。
611
580
 
@@ -615,6 +584,12 @@ interface TurnEndReasonMap {
615
584
 
616
585
  消费此约定的后端见 [persistence.md](./persistence.md)。
617
586
 
587
+ ## Remote 目录与 workspace 打开
588
+
589
+ `ModelCatalog` 是 `session/modelCatalog` 返回的 Host generation 模型目录:它携带部署默认值、可路由 provider id、成功的 provider 分组与相互隔离的 provider 失败。它不由某个 Session 派生,因此与 Session projection 分开保存。
590
+
591
+ `SessionOpenWorkspacePathRequest` 携带绝对路径或已按 workspace 解析的 `path`。`SessionOpenWorkspacePathValue` 确认 Host 已接受原生交接。Session-aware Client 会在已知当前 Session cwd 时据此解析相对路径;controller 将路径原样交给打开器,并通过 Session Remote 错误词汇表报告无效请求、取消与打开器失败。
592
+
618
593
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
619
594
 
620
595
  <a id="cordis-surface"></a>
@@ -623,6 +598,150 @@ interface TurnEndReasonMap {
623
598
 
624
599
  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).
625
600
 
601
+ <a id="ctxsessioncontroller--sessioncontroller"></a>
602
+
603
+ ### `ctx.sessionController` — `SessionController`
604
+
605
+ Host service backing the generated `ctx.remote.session` namespace.
606
+
607
+ ```ts cordis-catalog
608
+ /**
609
+ * Resolve or resume one ordinary Session for another Host API domain.
610
+ * @param sessionId - Session identity whose Agent owns the operation.
611
+ * @returns the live Agent or the stable Session-domain failure.
612
+ */
613
+ resolveAgent(sessionId: SessionId): Promise<ApiSessionAgentResult>
614
+
615
+ /**
616
+ * Inspect one attached or persisted Session without activating its Agent.
617
+ * @param sessionId - durable Session identity.
618
+ * @param signal - optional caller cancellation for persistence reads.
619
+ * @returns the current attached state or persisted header and event prefix.
620
+ */
621
+ inspect( sessionId: SessionId, signal?: AbortSignal, ): Promise<{ meta: SessionHeader; events: SessionEvent[] }>
622
+
623
+ /**
624
+ * Read all visible Session rows without resuming an Agent.
625
+ * @param _request - reserved empty list request.
626
+ * @param signal - cancellation for persistence reads.
627
+ * @returns visible Session summaries ordered by activity.
628
+ */
629
+ @Remote('list') async list(_request: SessionListRequest, signal: AbortSignal): Promise<SessionListValue>
630
+
631
+ /**
632
+ * Search visible Session content without resuming an Agent.
633
+ * @param request - literal message-content query.
634
+ * @param signal - cancellation for list and search reads.
635
+ * @returns authorized bounded Session search results.
636
+ */
637
+ @Remote('search') search(request: SessionSearchRequest, signal: AbortSignal): Promise<SessionSearchValue>
638
+
639
+ /**
640
+ * Create or idempotently adopt one ordinary Session.
641
+ * @param request - requested identity, location, and Agent preset.
642
+ * @returns the Session identity and resolved preset when configured.
643
+ */
644
+ @Remote('create') create(request: SessionCreateRequest): Promise<SessionCreateValue>
645
+
646
+ /**
647
+ * Select one Session-local model after explicitly resuming the Session.
648
+ * @param request - Session identity and requested model selection.
649
+ * @returns the normalized selection installed for the Session.
650
+ */
651
+ @Remote('selectModel') selectModel(request: SessionSelectModelRequest): Promise<SessionSelectModelValue>
652
+
653
+ /**
654
+ * Describe every currently routable model for Host-generation selectors.
655
+ * @returns provider-grouped models, the deployment default, and isolated provider failures.
656
+ */
657
+ @Remote('modelCatalog') modelCatalog(): Promise<ModelCatalog>
658
+
659
+ /**
660
+ * Report whether this deployment can hand a Session workspace path to a native desktop.
661
+ * @returns true when the matching open operation is available.
662
+ */
663
+ @Remote canOpenWorkspacePath(): boolean
664
+
665
+ /**
666
+ * Open one path prepared by a Session-aware caller on the Host desktop.
667
+ * @param request - path after best-effort Session workspace resolution.
668
+ * @param signal - caller lifetime; abort terminates the native command.
669
+ * @returns confirmation after the native opener accepts the path.
670
+ * @throws TypertRemoteFailure when the request is invalid, cancelled, or the opener fails.
671
+ */
672
+ @Remote('openWorkspacePath') async openWorkspacePath( request: SessionOpenWorkspacePathRequest, signal: AbortSignal, ): Promise<SessionOpenWorkspacePathValue>
673
+
674
+ /**
675
+ * Rename one Session after explicitly resuming it.
676
+ * @param request - Session identity and proposed title.
677
+ * @returns the accepted title and durable event sequence.
678
+ */
679
+ @Remote('rename') rename(request: SessionRenameRequest): Promise<SessionRenameValue>
680
+
681
+ /**
682
+ * Fork one cold-readable completed-turn prefix into a new Session.
683
+ * @param request - source Session and optional event anchor.
684
+ * @returns the new Session identity.
685
+ */
686
+ @Remote('fork') fork(request: SessionForkRequest): Promise<SessionForkValue>
687
+
688
+ /**
689
+ * Admit one prompt after explicitly resuming its Session.
690
+ * @param request - Session identity, prompt content, source metadata, and delivery mode.
691
+ * @param signal - caller cancellation before prompt admission begins.
692
+ * @returns acknowledgement that the Agent accepted the prompt.
693
+ */
694
+ @Remote('prompt') prompt(request: SessionPromptRequest, signal: AbortSignal): Promise<SessionPromptValue>
695
+
696
+ /**
697
+ * Read one image proven reachable from the addressed Session log.
698
+ * @param request - Session and attachment identities used for authorization.
699
+ * @returns the durable attachment reference and base64-encoded bytes.
700
+ */
701
+ @Remote('attachment') attachment(request: SessionAttachmentRequest): Promise<SessionAttachmentValue>
702
+
703
+ /**
704
+ * Mutate one still-pending queue occurrence on a live Agent.
705
+ * @param request - Session, queue item, and requested mutation.
706
+ * @returns acknowledgement that the queue mutation was applied.
707
+ */
708
+ @Remote('updateQueue') updateQueue(request: SessionUpdateQueueRequest): SessionUpdateQueueValue
709
+
710
+ /**
711
+ * Cancel one active Agent turn without dropping its pending inbox.
712
+ * @param request - Session whose active Agent turn is cancelled.
713
+ * @returns acknowledgement that cancellation was requested.
714
+ */
715
+ @Remote('cancel') cancel(request: SessionCancelRequest): SessionCancelValue
716
+
717
+ /**
718
+ * Read one cold-safe, message-aligned Session history page.
719
+ * @param request - durable address, backward cursor, and page budget.
720
+ * @param signal - cancellation for persistence reads.
721
+ * @returns one chronological page.
722
+ */
723
+ @Remote('page') page(request: SessionPageRequest, signal: AbortSignal): Promise<SessionPage>
724
+
725
+ /**
726
+ * Follow one Session log from its opening or resume cursor.
727
+ * @param request - durable address and last committed sequence already held by the caller.
728
+ * @param signal - cancellation owned by the Remote stream carrier.
729
+ * @returns a complete opening snapshot followed by gap-free event frames.
730
+ */
731
+ @Remote({ mode: 'stream' }) follow(request: SessionFollowRequest, signal: AbortSignal): AsyncIterable<SessionFollowFrame>
732
+
733
+ /**
734
+ * Stream a complete live-control baseline followed by replacement frames.
735
+ * @param signal - cancellation owned by the Remote stream carrier.
736
+ * @returns one complete baseline followed by live replacement frames.
737
+ */
738
+ @Remote({ mode: 'stream' }) control(signal: AbortSignal): AsyncIterable<SessionControlFrame>
739
+ ```
740
+
741
+ Types: [SessionHeader](./persistence.md) · [SessionId](./core.md) · [SessionSearchRequest](./session-query.md)
742
+
743
+ Source: [`packages/api/session-controller/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/session-controller/src/index.ts)
744
+
626
745
  <a id="ctxsessions--sessionstore"></a>
627
746
 
628
747
  ### `ctx.sessions` — `SessionStore`
@@ -759,6 +878,106 @@ Types: [CreateSessionOptions](./persistence.md) · [PrepareSessionOptions](./per
759
878
 
760
879
  Source: [`packages/core/session/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/session/src/index.ts)
761
880
 
881
+ <a id="api-session-events"></a>
882
+
883
+ ### `api-session/*` events
884
+
885
+ <a id="api-sessionactivity--emit"></a>
886
+
887
+ #### `api-session/activity` — emit
888
+
889
+ One user-authored durable message advanced Session list activity.
890
+
891
+ ```ts cordis-catalog
892
+ /**
893
+ * One user-authored durable message advanced Session list activity.
894
+ * @mode emit
895
+ * @param sessionId - addressed Session identity.
896
+ * @param updatedAt - durable message time used for list ordering.
897
+ */
898
+ 'api-session/activity'(sessionId: SessionId, updatedAt: number): void
899
+ ```
900
+
901
+ Types: [SessionId](./core.md)
902
+
903
+ Source: [`packages/api/session-controller/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/session-controller/src/types.ts)
904
+
905
+ <a id="api-sessionadded--emit"></a>
906
+
907
+ #### `api-session/added` — emit
908
+
909
+ A Session became visible to Session list consumers.
910
+
911
+ ```ts cordis-catalog
912
+ /**
913
+ * A Session became visible to Session list consumers.
914
+ * @mode emit
915
+ * @param summary - initial list row for the Session.
916
+ */
917
+ 'api-session/added'(summary: SessionSummary): void
918
+ ```
919
+
920
+ Source: [`packages/api/session-controller/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/session-controller/src/types.ts)
921
+
922
+ <a id="api-sessionerror--emit"></a>
923
+
924
+ #### `api-session/error` — emit
925
+
926
+ One Agent failed outside a durable turn position.
927
+
928
+ ```ts cordis-catalog
929
+ /**
930
+ * One Agent failed outside a durable turn position.
931
+ * @mode emit
932
+ * @param sessionId - Agent and Session identity.
933
+ * @param message - user-safe failure chain.
934
+ */
935
+ 'api-session/error'(sessionId: SessionId, message: string): void
936
+ ```
937
+
938
+ Types: [SessionId](./core.md)
939
+
940
+ Source: [`packages/api/session-controller/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/session-controller/src/types.ts)
941
+
942
+ <a id="api-sessionremoved--emit"></a>
943
+
944
+ #### `api-session/removed` — emit
945
+
946
+ A Session left the live Host registry.
947
+
948
+ ```ts cordis-catalog
949
+ /**
950
+ * A Session left the live Host registry.
951
+ * @mode emit
952
+ * @param sessionId - removed Session identity.
953
+ */
954
+ 'api-session/removed'(sessionId: SessionId): void
955
+ ```
956
+
957
+ Types: [SessionId](./core.md)
958
+
959
+ Source: [`packages/api/session-controller/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/session-controller/src/types.ts)
960
+
961
+ <a id="api-sessionstatus--emit"></a>
962
+
963
+ #### `api-session/status` — emit
964
+
965
+ One Agent changed running state.
966
+
967
+ ```ts cordis-catalog
968
+ /**
969
+ * One Agent changed running state.
970
+ * @mode emit
971
+ * @param sessionId - Agent and Session identity.
972
+ * @param running - whether the Agent is running.
973
+ */
974
+ 'api-session/status'(sessionId: SessionId, running: boolean): void
975
+ ```
976
+
977
+ Types: [SessionId](./core.md)
978
+
979
+ Source: [`packages/api/session-controller/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/session-controller/src/types.ts)
980
+
762
981
  <a id="session-events"></a>
763
982
 
764
983
  ### `session/*` events
@@ -54,7 +54,7 @@ interface SettingsRegisterOptions<T> {
54
54
 
55
55
  `validate` 在 schema 接纳该值之后运行,因此它看到的默认值和组合 base 与 owner 实际看到的完全一致。`dsh-llm-pi-ai` 用它在写入处拒绝自己无法服务的提供方 profile,而不是先存下来、再让该 namespace 下每条路由失效。
56
56
 
57
- `applies` 是 UI 提示而非机制:`restart` 的 owner 只是从不 watch,其值在构造期读取一次,配置界面可为待生效变更加标。
57
+ `applies` 是 UI 提示而非机制:`restart` 的 owner 从不 watch,其值在构造期读取一次,配置界面可为待生效变更加标。
58
58
 
59
59
  ```ts type-equiv
60
60
  /** When a namespace's changes take effect for its owner. */
@@ -164,6 +164,10 @@ interface SettingsDescribeOptions {
164
164
  type SettingsUpdateSource = 'update' | 'provider'
165
165
  ```
166
166
 
167
+ ## 原生文档操作
168
+
169
+ `SettingsDocumentOpenValue` 确认 `settings/openSettingsDocument` 已准备好 provider 持有的文档,并将其交给原生文本编辑器。`AgentPresetDirectoryOpenValue` 报告已完成的原生交接,或在桌面打开不可用时返回解析后的用户 preset 目录。两项操作都不接受由浏览器选择的 Host 路径。
170
+
167
171
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
168
172
 
169
173
  <a id="cordis-surface"></a>
@@ -257,6 +261,79 @@ async mutate(ns: SettingsNamespace, ops: readonly SettingsPathOp[], expectedRevi
257
261
 
258
262
  Source: [`packages/settings/settings/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/settings/settings/src/index.ts)
259
263
 
264
+ <a id="ctxsettingscontroller--settingscontroller"></a>
265
+
266
+ ### `ctx.settingsController` — `SettingsController`
267
+
268
+ Host service backing the generated `ctx.remote.settings` namespace. Every remote read uses `redactSecrets: true`, so a `role('secret')` field cannot ride a response. Writes expose the settings service's merge, replacement, and path-addressed operations, and classify every provider refusal as `settings-conflict` or `settings-rejected` with the service's message.
269
+
270
+ ```ts cordis-catalog
271
+ /**
272
+ * Describe every registered namespace for a configuration page: redacted
273
+ * layered values plus the serialized schema the page renders its form from.
274
+ * @returns provider writability, local-document presence, and one view per namespace.
275
+ * @throws TypertRemoteFailure when no settings provider is mounted.
276
+ */
277
+ @Remote describe(): SettingsDescribeValue
278
+
279
+ /**
280
+ * Report whether this deployment can open an authored Agent preset directory natively.
281
+ * @returns true when the matching open operation is available.
282
+ */
283
+ @Remote canOpenAgentPresetDirectory(): boolean
284
+
285
+ /**
286
+ * Merge a patch into one namespace's stored user section.
287
+ * @param ns - namespace key to write.
288
+ * @param patch - fields to merge into the user section.
289
+ * @param expectedRevision - revision the caller read; `undefined` writes unconditionally.
290
+ * @returns the namespace's redacted view after the write.
291
+ * @throws TypertRemoteFailure when the request is invalid, no provider is mounted, or the provider refuses the write.
292
+ */
293
+ @Remote update( ns: string, patch: Record<string, JsonValue>, expectedRevision: number | undefined, ): Promise<SettingsNamespaceView>
294
+
295
+ /**
296
+ * Replace one namespace's stored user section wholesale.
297
+ * @param ns - namespace key to write.
298
+ * @param section - complete replacement user section.
299
+ * @param expectedRevision - revision the caller read; `undefined` writes unconditionally.
300
+ * @returns the namespace's redacted view after the write.
301
+ * @throws TypertRemoteFailure when the request is invalid, no provider is mounted, or the provider refuses the write.
302
+ */
303
+ @Remote replace( ns: string, section: Record<string, JsonValue>, expectedRevision: number | undefined, ): Promise<SettingsNamespaceView>
304
+
305
+ /**
306
+ * Apply path-addressed edits to one namespace's user section, resolved against
307
+ * the section as stored rather than against whatever the caller last read,
308
+ * then answer with that namespace's new redacted view.
309
+ * @param ns - namespace key to write.
310
+ * @param ops - the edits to apply, in order.
311
+ * @param expectedRevision - revision the caller read; `undefined` writes unconditionally.
312
+ * @returns the namespace's redacted view after the write.
313
+ * @throws TypertRemoteFailure when the request is invalid, no provider is mounted, or the provider refuses the write.
314
+ */
315
+ @Remote async mutate( ns: string, ops: SettingsPathOpView[], expectedRevision: number | undefined, ): Promise<SettingsNamespaceView>
316
+
317
+ /**
318
+ * Materialize the provider-owned settings document and open it in a native text editor.
319
+ * @param signal - caller lifetime; abort terminates preparation or the native command.
320
+ * @returns confirmation after the native opener accepts the document.
321
+ * @throws TypertRemoteFailure when no document exists, preparation fails, or opening fails.
322
+ */
323
+ @Remote async openSettingsDocument(signal: AbortSignal): Promise<SettingsDocumentOpenValue>
324
+
325
+ /**
326
+ * Open one user-authored Agent preset directory or return its path when no native opener exists.
327
+ * @param agentPreset - preset id resolved against Host-owned roots.
328
+ * @param signal - caller lifetime; abort terminates the native command.
329
+ * @returns an opened confirmation or the resolved directory for text display.
330
+ * @throws TypertRemoteFailure when the preset is missing, read-only, invalid, or cannot be opened.
331
+ */
332
+ @Remote async openAgentPresetDirectory( agentPreset: string, signal: AbortSignal, ): Promise<AgentPresetDirectoryOpenValue>
333
+ ```
334
+
335
+ Source: [`packages/api/settings-controller/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/settings-controller/src/index.ts)
336
+
260
337
  <a id="settings-events"></a>
261
338
 
262
339
  ### `settings/*` events
@@ -237,6 +237,10 @@ interface Config {
237
237
 
238
238
  面向模型的 `skill({ name })` 工具校验 kebab-case 名称,在与调用策略无关的目录中查找摘要,并在加载前通过 `isModelInvocable` 拒绝无权访问的 skill;随后它根据调用方 agent 的 cwd 重新读取完整定义,并在返回内容前再次检查策略。该工具将无法解析的 skill 报告为未知或已不可用,并返回包含 `<skill_content name="...">`、`<skill_resources>` 和 `<skill_instructions>` 的工具结果。`resourceBase` 仅按需解析显式引用的脚本、参考资料和资产;加载结果不枚举 skill 目录。因此,仅修改正文会改变后续工具调用,而不会生成目录消息或改写先前工具结果。
239
239
 
240
+ ## 浏览器 Session 目录
241
+
242
+ `SkillListRequest` 通过 `sessionId` 指定一个 Session;`SkillListValue` 返回允许用户调用的条目,其中包含名称、描述、可选使用提示与模型调用可用性。`SessionSkillCatalog` 在不激活 Agent 的前提下读取 Session cwd 与记录的 preset。live Agent 可以提供其作用域 registry,冷 Session 则使用 preset 的 standing scope。
243
+
240
244
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
241
245
 
242
246
  <a id="cordis-surface"></a>
@@ -245,6 +249,25 @@ interface Config {
245
249
 
246
250
  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).
247
251
 
252
+ <a id="ctxsessionskillcatalog--sessionskillcatalog"></a>
253
+
254
+ ### `ctx.sessionSkillCatalog` — `SessionSkillCatalog`
255
+
256
+ Host service backing `ctx.remote.skills` without activating a cold Agent.
257
+
258
+ ```ts cordis-catalog
259
+ /**
260
+ * List the user-invocable skills visible to one Session composition.
261
+ * @param request - Session identity whose cwd and preset select the catalog view.
262
+ * @param signal - caller lifetime carried by the Remote transport; admitted catalog reads retain their existing completion semantics.
263
+ * @returns user-invocable skill metadata without loading skill bodies.
264
+ * @throws TypertRemoteFailure when the Session cannot be inspected or no registry can serve it.
265
+ */
266
+ @Remote async list(request: SkillListRequest, signal: AbortSignal): Promise<SkillListValue>
267
+ ```
268
+
269
+ Source: [`packages/api/session-controller/src/skill-catalog.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/session-controller/src/skill-catalog.ts)
270
+
248
271
  <a id="ctxskills--skillregistry"></a>
249
272
 
250
273
  ### `ctx.skills` — `SkillRegistry`