dsh-plugin-dev-kb 1.0.3 → 1.0.5

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 (142) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +14 -0
  3. package/kb/README.md +1 -1
  4. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +3 -3
  5. package/kb/extra/cookbook/maintaining-dsh-code-review.zh.md +1 -1
  6. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +1 -1
  7. package/kb/extra/defensive-patterns.zh.md +3 -1
  8. package/kb/extra/development.zh.md +15 -9
  9. package/kb/extra/event-producer-consumer.md +5 -2
  10. package/kb/extra/event-producer-consumer.zh.md +5 -2
  11. package/kb/extra/graph-atlas.zh.md +7 -7
  12. package/kb/extra/i18n/README.md +3 -3
  13. package/kb/extra/i18n/README.zh.md +9 -7
  14. package/kb/extra/i18n/style-samples.md +1 -1
  15. package/kb/extra/i18n/translation-prompt.md +3 -3
  16. package/kb/extra/i18n/translation-rules.md +2 -2
  17. package/kb/extra/i18n/translation-rules.zh.md +3 -3
  18. package/kb/extra/module-graph.md +18 -9
  19. package/kb/extra/module-graph.zh.md +18 -9
  20. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +1 -1
  21. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +1 -1
  22. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
  23. package/kb/extra/postmortem/README.zh.md +5 -5
  24. package/kb/extra/rescope.zh.md +1 -1
  25. package/kb/extra/subsystems/agent-team.md +2 -2
  26. package/kb/extra/subsystems/agent-team.zh.md +6 -6
  27. package/kb/extra/subsystems/attachment.md +63 -12
  28. package/kb/extra/subsystems/attachment.zh.md +63 -12
  29. package/kb/extra/subsystems/extensions.md +9 -9
  30. package/kb/extra/subsystems/extensions.zh.md +12 -12
  31. package/kb/extra/subsystems/feedback.md +2 -2
  32. package/kb/extra/subsystems/feedback.zh.md +2 -2
  33. package/kb/extra/testing.md +1 -1
  34. package/kb/extra/testing.zh.md +7 -7
  35. package/kb/extra/web-styling.zh.md +2 -2
  36. package/kb/meta/search-index.json +132 -132
  37. package/kb/meta/source.json +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/package.json +2 -1
@@ -5,7 +5,7 @@ outline: [2,3]
5
5
 
6
6
  # 用户命令
7
7
 
8
- [`dsh-commands`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/interaction/commands) 提供的用户命令注册表服务。交互式适配器用它发现插件拥有的命令,并针对确切的 agent(智能体)直接执行这些命令,而不创建模型消息。[命令 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md) 负责分发与生命周期的决策依据;[包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/commands/README.md) 负责组合方式与限制。
8
+ [`dsh-commands`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/interaction/commands) 提供的用户命令注册表服务。交互式适配器用它发现插件拥有的命令,并针对确切的 agent(智能体)直接执行这些命令,而不创建模型消息。[命令 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.zh.md) 负责分发与生命周期的决策依据;[包 README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/commands/README.zh.md) 负责组合方式与限制。
9
9
 
10
10
  来源:[`packages/interaction/commands/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/commands/src/index.ts)
11
11
 
@@ -125,7 +125,7 @@ interface ParsedCommand {
125
125
 
126
126
  ## Cordis API
127
127
 
128
- 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).
128
+ 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).
129
129
 
130
130
  <a id="ctxcommands--commandruntime"></a>
131
131
 
@@ -185,9 +185,9 @@ find(agent: Agent, name: string): CommandDefinition | undefined
185
185
  @Remote async execute( agent: Agent, line: string, images: readonly EncodedImageAttachment[], signal: AbortSignal, ): Promise<CommandExecution | undefined>
186
186
  ```
187
187
 
188
- Types: [Agent](./core.md) · [EncodedImageAttachment](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/attachment.md)
188
+ Types: [Agent](./core.md) · [EncodedImageAttachment](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/attachment.zh.md)
189
189
 
190
- Source: [`packages/interaction/commands/src/index.ts:250`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/commands/src/index.ts)
190
+ Source: [`packages/interaction/commands/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/commands/src/index.ts)
191
191
 
192
192
  <a id="commands-events"></a>
193
193
 
@@ -209,5 +209,5 @@ A command was registered or unregistered. This is an unfiltered registry notific
209
209
  'commands/change'(): void
210
210
  ```
211
211
 
212
- Source: [`packages/interaction/commands/src/types.ts:80`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/commands/src/types.ts)
212
+ Source: [`packages/interaction/commands/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/commands/src/types.ts)
213
213
  <!-- END GENERATED cordis-surface -->
@@ -5,13 +5,13 @@ outline: [2,3]
5
5
 
6
6
  # 压缩(compaction)
7
7
 
8
- 压缩 seam 是一个[能力 seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md),与 bash 一样分为 Service Definition([dsh-compaction](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction),`ctx.compaction`)、Service Provider(例如 [dsh-compaction-basic](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction-basic) 后端)和面向用户的 Consumer([dsh-command-compact](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/command-compact))。压缩是**一项可选能力**,不属于 agent loop(智能体循环)主干,因此其词汇定义在此而非 [core.md](./core.md) 中。基于 tokenizer 或模板的后端是实现同一接口的兄弟包。与 bash 不同,该接口必然依赖 `dsh-session` 和 `dsh-llm`:其动词作用于 agent 所有的 `Session`,而其持久摘要事件使用 `ContentBlock` 词汇(见[压缩能力 seam Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.md))。
8
+ 压缩 seam 是一个[能力 seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md),与 bash 一样分为 Service Definition([dsh-compaction](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction),`ctx.compaction`)、Service Provider(例如 [dsh-compaction-basic](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction-basic) 后端)和面向用户的 Consumer([dsh-command-compact](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/command-compact))。压缩是**一项可选能力**,不属于 agent loop(智能体循环)主干,因此其词汇定义在此而非 [core.md](./core.md) 中。基于 tokenizer 或模板的后端是实现同一接口的兄弟包。与 bash 不同,该接口必然依赖 `dsh-session` 和 `dsh-llm`:其动词作用于 agent 所有的 `Session`,而其持久摘要事件使用 `ContentBlock` 词汇(见[压缩能力 seam Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.zh.md))。
9
9
 
10
10
  源码:[`packages/compaction/compaction/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/types.ts)
11
11
 
12
12
  ## `compaction/*` 会话事件
13
13
 
14
- 压缩通过声明合并为 [`SessionEventMap`](./session.md) 扩展三种事件类型。三者都**仅写入日志**——它们记录锁、摘要、选中范围、被遮蔽事件 seq、token 数以及模型调用,绝不进入 surface。这里有意不扩展 `SurfaceEventType`(只有产生消息的事件才到达模型),因此摘要本身承载在另一条带有 `surfaceOp: { op: 'replace', start, end }` 的 `user/message` 上——这是摘要压缩执行的唯一 surface 变更。[Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.md) 负责复用 `user/message` 的决策依据。
14
+ 压缩通过声明合并为 [`SessionEventMap`](./session.md) 扩展三种事件类型。三者都**仅写入日志**——它们记录锁、摘要、选中范围、被遮蔽事件 seq、token 数以及模型调用,绝不进入 surface。这里有意不扩展 `SurfaceEventType`(只有产生消息的事件才到达模型),因此摘要本身承载在另一条带有 `surfaceOp: { op: 'replace', start, end }` 的 `user/message` 上——这是摘要压缩执行的唯一 surface 变更。[Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.zh.md) 负责复用 `user/message` 的决策依据。
15
15
 
16
16
  | 事件 | 载荷 | 作用 |
17
17
  |---|---|---|
@@ -86,9 +86,9 @@ type ManualCompactionErrorCode =
86
86
 
87
87
  `changed` 和 `summary` 保持会话表层不变,但仍会闭合失败尝试并将其持久化到日志。`commit` 可能发生在部分变更之后;`persistence` 表示内存中的标记对已闭合,但 flush 失败。取消独立于这些失败,并在完成必要清理后抛出原始 abort 原因。
88
88
 
89
- 压力压缩在串行 `agent/pre-step` 中运行,先于请求推导。一旦压力或规范化溢出满足条件,compaction-basic 会在选择范围前调用可选的 [`ctx.toolResultPruner`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/README.md),再通过 `ctx.tokenMeter` 重新测量,并且可以在不生成摘要的情况下推进 surface。失败请求的恢复在失败的步骤关闭后通过 `agent/request-error` 运行;仅当 surface replacement generation 前进时才返回重试动作,即便后续摘要工作在剪枝后抛异常亦如此;取消仍然优先。区域边界保持工具调用/结果配对,但不保持整个轮次,因此一个过大轮次中较早关闭的步骤可以被压缩。`dsh-compaction-basic` 拥有阈值、保留尾部策略、溢出上限与失败处理。
89
+ 压力压缩在串行 `agent/pre-step` 中运行,先于请求推导。一旦压力或规范化溢出满足条件,compaction-basic 会在选择范围前调用可选的 [`ctx.toolResultPruner`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/README.zh.md),再通过 `ctx.tokenMeter` 重新测量,并且可以在不生成摘要的情况下推进 surface。失败请求的恢复在失败的步骤关闭后通过 `agent/request-error` 运行;仅当 surface replacement generation 前进时才返回重试动作,即便后续摘要工作在剪枝后抛异常亦如此;取消仍然优先。区域边界保持工具调用/结果配对,但不保持整个轮次,因此一个过大轮次中较早关闭的步骤可以被压缩。`dsh-compaction-basic` 拥有阈值、保留尾部策略、溢出上限与失败处理。
90
90
 
91
- 该 Service Definition 导出 `toolPairingBalancedBefore(session, seq)` 与 `toolPairingBalancedAfter(session, seq)`,用于检查 seq 之前与之后的工具调用/结果配对。两者都会验证当前 surface 成员关系,并拒绝缺失的 seq 与遗留结果;[包约定](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/README.md#tool-pairing-boundaries)定义其缓存行为。
91
+ 该 Service Definition 导出 `toolPairingBalancedBefore(session, seq)` 与 `toolPairingBalancedAfter(session, seq)`,用于检查 seq 之前与之后的工具调用/结果配对。两者都会验证当前 surface 成员关系,并拒绝缺失的 seq 与遗留结果;[包约定](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/README.zh.md#tool-pairing-boundaries)定义其缓存行为。
92
92
 
93
93
  ## 工具结果剪枝产出
94
94
 
@@ -126,7 +126,7 @@ interface PruneResult {
126
126
 
127
127
  ## Cordis API
128
128
 
129
- 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).
129
+ 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).
130
130
 
131
131
  <a id="ctxcompaction--compactionengine-abstract-seam"></a>
132
132
 
@@ -195,7 +195,7 @@ abstract compactRegion( start: number, end: number, agent: CompactionAgentContex
195
195
 
196
196
  Types: [CommandId](./commands.md)
197
197
 
198
- Source: [`packages/compaction/compaction/src/index.ts:96`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/index.ts)
198
+ Source: [`packages/compaction/compaction/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/index.ts)
199
199
 
200
200
  <a id="ctxtoolresultpruner--toolresultpruner"></a>
201
201
 
@@ -237,5 +237,5 @@ pruneSession(session: Session): PruneResult
237
237
 
238
238
  Types: [ContentBlock](./llm-streaming.md) · [Session](./session.md)
239
239
 
240
- Source: [`packages/compaction/compaction-tool-result-pruner/src/index.ts:44`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/src/index.ts)
240
+ Source: [`packages/compaction/compaction-tool-result-pruner/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/src/index.ts)
241
241
  <!-- END GENERATED cordis-surface -->
@@ -5,11 +5,11 @@ outline: [2,3]
5
5
 
6
6
  # 核心
7
7
 
8
- **核心**子系统即 [`packages/core`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/README.md),包含每个组合都会启动的包:事件溯源的会话日志、系统提示词组装、工具注册表、agent(智能体)类型,以及驱动它们的具体循环。本页说明 `agent`/`agent-loop` 这对包所声明的内容:agent 如何被创建与拥有,以及 `Agent` 句柄的投递、取消与拦截约定;本页还说明每个子系统都遵循的两个类型模式。该组的专属页面与目录其余部分见[子系统 README](./index.md)。
8
+ **核心**子系统即 [`packages/core`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/README.zh.md),包含每个组合都会启动的包:事件溯源的会话日志、系统提示词组装、工具注册表、agent(智能体)类型,以及驱动它们的具体循环。本页说明 `agent`/`agent-loop` 这对包所声明的内容:agent 如何被创建与拥有,以及 `Agent` 句柄的投递、取消与拦截约定;本页还说明每个子系统都遵循的两个类型模式。该组的专属页面与目录其余部分见[子系统 README](./index.md)。
9
9
 
10
10
  ## 主干逐包速览
11
11
 
12
- 一个轮次按同一条循环流经六个包:[`agent-loop`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/core/agent-loop) 中的 driver 认领一条排队的提示词,在[会话日志](./session.md)(`ctx.sessions`)上开启轮次,通过 [system-prompt](./system-prompt.md)(`ctx.systemPrompt`)组装请求前缀并从日志派生历史,经 [LLM(大语言模型) seam](./llm-streaming.md) 流式获取模型响应,经[工具注册表](./tools.md)(`ctx.tools`)分发工具调用,并把每个模型可见的事实追加回日志,供下一步派生。循环搬运的对话词汇——`Message`、`ContentBlock`、`StreamChunk`、模型请求——由 [`packages/llm`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/README.md) 声明,记录在 [llm-streaming.md](./llm-streaming.md)。
12
+ 一个轮次按同一条循环流经六个包:[`agent-loop`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/core/agent-loop) 中的 driver 认领一条排队的提示词,在[会话日志](./session.md)(`ctx.sessions`)上开启轮次,通过 [system-prompt](./system-prompt.md)(`ctx.systemPrompt`)组装请求前缀并从日志派生历史,经 [LLM(大语言模型) seam](./llm-streaming.md) 流式获取模型响应,经[工具注册表](./tools.md)(`ctx.tools`)分发工具调用,并把每个模型可见的事实追加回日志,供下一步派生。循环搬运的对话词汇——`Message`、`ContentBlock`、`StreamChunk`、模型请求——由 [`packages/llm`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/README.zh.md) 声明,记录在 [llm-streaming.md](./llm-streaming.md)。
13
13
 
14
14
  | 包 | 负责内容 | 页面 |
15
15
  |---|---|---|
@@ -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.md)。
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)。
24
24
 
25
25
  <a id="creation-and-ownership"></a>
26
26
 
@@ -159,7 +159,7 @@ interface Agent {
159
159
  type AgentStatus = 'idle' | 'running'
160
160
  ```
161
161
 
162
- `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.md))。
162
+ `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
163
 
164
164
  ```ts type-equiv
165
165
  /** Merge-extensible agent creation options. Persona belongs to system-prompt sections. */
@@ -215,7 +215,9 @@ cause 是由 TypeScript 强制约束的同进程输入。活跃的取消持有
215
215
 
216
216
  ## 发起 Agent
217
217
 
218
- `ctx.agents` 携带的进程本地 initiator 就是上面的确切 `Agent`,不是单独的 frame 或复制的标识。环境中存在该值既不能证明存活,也不代表授权;[initiator 作用域决策](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.md)定义其生命周期和作用域规则。
218
+ `ctx.agents` 携带的进程本地 initiator 就是上面的确切 `Agent`,不是单独的 frame 或复制的标识。环境中存在该值既不能证明存活,也不代表授权;[initiator 作用域决策](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.zh.md)定义其生命周期和作用域规则。
219
+
220
+ <a id="interception-decisions"></a>
219
221
 
220
222
  ## 拦截决策
221
223
 
@@ -325,7 +327,7 @@ type Branded<B extends string> = string & { readonly [BRAND]: B }
325
327
 
326
328
  ## Cordis API
327
329
 
328
- 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).
330
+ 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).
329
331
 
330
332
  <a id="ctxagentdefaultmodel--agentdefaultmodelconfig"></a>
331
333
 
@@ -349,7 +351,7 @@ currentSelection(): ModelSelection
349
351
  async saveSelection(next: ModelSelection): Promise<void>
350
352
  ```
351
353
 
352
- Source: [`packages/core/agent-default-model/src/index.ts:64`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent-default-model/src/index.ts)
354
+ Source: [`packages/core/agent-default-model/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent-default-model/src/index.ts)
353
355
 
354
356
  <a id="ctxagentloop--agentloop"></a>
355
357
 
@@ -388,7 +390,7 @@ async resume(ownerCtx: Context, options: ResumeAgentOptions): Promise<AgentHandl
388
390
 
389
391
  Types: [SessionHeader](./persistence.md)
390
392
 
391
- Source: [`packages/core/agent-loop/src/index.ts:296`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent-loop/src/index.ts)
393
+ Source: [`packages/core/agent-loop/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent-loop/src/index.ts)
392
394
 
393
395
  <a id="ctxagentpresets--agentpresets"></a>
394
396
 
@@ -559,7 +561,7 @@ async standingKeyFor(id?: string): Promise<ScopeKey>
559
561
 
560
562
  Types: [ScopeKey](./scope.md)
561
563
 
562
- Source: [`packages/preset/agent-presets/src/index.ts:82`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/preset/agent-presets/src/index.ts)
564
+ Source: [`packages/preset/agent-presets/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/preset/agent-presets/src/index.ts)
563
565
 
564
566
  <a id="ctxagents--agentregistry"></a>
565
567
 
@@ -731,7 +733,7 @@ list(): Agent[]
731
733
  roots(): Agent[]
732
734
  ```
733
735
 
734
- Source: [`packages/core/agent/src/index.ts:256`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/index.ts)
736
+ Source: [`packages/core/agent/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/index.ts)
735
737
 
736
738
  <a id="agent-events"></a>
737
739
 
@@ -759,7 +761,7 @@ A fully configured agent and live session were published. Setup is composition-o
759
761
 
760
762
  Types: [Scoped](./scope.md)
761
763
 
762
- Source: [`packages/core/agent/src/runtime-types.ts:159`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
764
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
763
765
 
764
766
  <a id="agentdisposed--emit"></a>
765
767
 
@@ -781,7 +783,7 @@ An agent left the registry; AgentLoop emits this after driver quiescence and sco
781
783
 
782
784
  Types: [Scoped](./scope.md)
783
785
 
784
- Source: [`packages/core/agent/src/runtime-types.ts:168`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
786
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
785
787
 
786
788
  <a id="agenterror--emit"></a>
787
789
 
@@ -805,7 +807,7 @@ A step or turn errored. The machine reports a failure here even when the error h
805
807
 
806
808
  Types: [Scoped](./scope.md)
807
809
 
808
- Source: [`packages/core/agent/src/runtime-types.ts:290`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
810
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
809
811
 
810
812
  <a id="agentinboxclaimed--emit"></a>
811
813
 
@@ -829,7 +831,7 @@ One message left the inbox inside its open turn. If the proposed step is rejecte
829
831
 
830
832
  Types: [Scoped](./scope.md) · [UserMessage](./session.md)
831
833
 
832
- Source: [`packages/core/agent/src/runtime-types.ts:197`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
834
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
833
835
 
834
836
  <a id="agentinboxdiscarded--emit"></a>
835
837
 
@@ -850,7 +852,7 @@ One message was discarded from the live inbox.
850
852
 
851
853
  Types: [Scoped](./scope.md) · [UserMessage](./session.md)
852
854
 
853
- Source: [`packages/core/agent/src/runtime-types.ts:205`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
855
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
854
856
 
855
857
  <a id="agentinboxinserted--emit"></a>
856
858
 
@@ -871,7 +873,7 @@ One message entered the live inbox.
871
873
 
872
874
  Types: [Scoped](./scope.md) · [UserMessage](./session.md)
873
875
 
874
- Source: [`packages/core/agent/src/runtime-types.ts:186`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
876
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
875
877
 
876
878
  <a id="agentpre-step--waterfall"></a>
877
879
 
@@ -896,7 +898,7 @@ Reject a proposed step or replace the messages that enter it. Calling `next()` p
896
898
 
897
899
  Types: [Scoped](./scope.md) · [UserMessage](./session.md)
898
900
 
899
- Source: [`packages/core/agent/src/runtime-types.ts:231`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
901
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
900
902
 
901
903
  <a id="agentrequest--waterfall"></a>
902
904
 
@@ -922,7 +924,7 @@ Replace the frozen call configuration. `await next()` yields the config the mach
922
924
 
923
925
  Types: [LlmCallConfig](./llm-streaming.md) · [Scoped](./scope.md)
924
926
 
925
- Source: [`packages/core/agent/src/runtime-types.ts:244`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
927
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
926
928
 
927
929
  <a id="agentrequest-error--waterfall"></a>
928
930
 
@@ -951,7 +953,7 @@ Handle one failed model-request attempt before the loop retries or closes its st
951
953
 
952
954
  Types: [LlmFailure](./llm-streaming.md) · [ResolvedRetryPolicy](./llm-streaming.md) · [Scoped](./scope.md)
953
955
 
954
- Source: [`packages/core/agent/src/runtime-types.ts:260`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
956
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
955
957
 
956
958
  <a id="agentsession-start--emit"></a>
957
959
 
@@ -975,7 +977,7 @@ The session lifecycle began, once before the first turn. Use `agent.inject()` to
975
977
 
976
978
  Types: [Scoped](./scope.md)
977
979
 
978
- Source: [`packages/core/agent/src/runtime-types.ts:217`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
980
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
979
981
 
980
982
  <a id="agentstatus--emit"></a>
981
983
 
@@ -998,7 +1000,7 @@ Agent status changed (`idle` ⇄ `running`). A waking delivery enters `running`
998
1000
 
999
1001
  Types: [Scoped](./scope.md)
1000
1002
 
1001
- Source: [`packages/core/agent/src/runtime-types.ts:178`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
1003
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
1002
1004
 
1003
1005
  <a id="agentturn-stopping--serial"></a>
1004
1006
 
@@ -1029,7 +1031,7 @@ The turn is about to close: the model owes no response (no live tool calls, no f
1029
1031
 
1030
1032
  Types: [Scoped](./scope.md)
1031
1033
 
1032
- Source: [`packages/core/agent/src/runtime-types.ts:278`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
1034
+ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
1033
1035
 
1034
1036
  <a id="agent-loop-events"></a>
1035
1037
 
@@ -1054,7 +1056,7 @@ A declarative agent entry failed before it could publish a live agent. Consumers
1054
1056
  'agent-loop/config-start-failed'(payload: { sessionId: SessionId; error: unknown }): void
1055
1057
  ```
1056
1058
 
1057
- Source: [`packages/core/agent-loop/src/index.ts:183`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent-loop/src/index.ts)
1059
+ Source: [`packages/core/agent-loop/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent-loop/src/index.ts)
1058
1060
 
1059
1061
  <a id="agent-preset-events"></a>
1060
1062
 
@@ -1077,5 +1079,5 @@ One session committed a different agent preset to its durable log. Consumers inv
1077
1079
  'agent-preset/selected'(sessionId: SessionId, agentPreset: string): void
1078
1080
  ```
1079
1081
 
1080
- Source: [`packages/preset/agent-presets/src/types.ts:13`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/preset/agent-presets/src/types.ts)
1082
+ Source: [`packages/preset/agent-presets/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/preset/agent-presets/src/types.ts)
1081
1083
  <!-- END GENERATED cordis-surface -->
@@ -50,7 +50,7 @@ interface CredentialInfo {
50
50
 
51
51
  ## 已提交的变更
52
52
 
53
- `credentials/updated (ref)` 在提供方管理的来源发生已提交变更后发出——`set`、`unset` 或在存储中观察到的外部编辑。进程环境自身的变化不可观测,永不发出事件。消费方不需要该事件(它们按操作重新解析);它服务于配置界面刷新「已配置」徽标。
53
+ `credentials/reference-updated (ref)` 在提供方管理的来源发生已提交变更后发出——`set`、`unset` 或在存储中观察到的外部编辑。进程环境自身的变化不可观测,永不发出事件。消费方不需要该事件(它们按操作重新解析);它服务于配置界面刷新「已配置」徽标。
54
54
 
55
55
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
56
56
 
@@ -58,13 +58,78 @@ interface CredentialInfo {
58
58
 
59
59
  ## Cordis API
60
60
 
61
- 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).
61
+ 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).
62
+
63
+ <a id="ctxauthorization--authorizationservice"></a>
64
+
65
+ ### `ctx.authorization` — `AuthorizationService`
66
+
67
+ `ctx.authorization`: a registry of credential-obtaining flows, one attempt at a time per key.
68
+
69
+ ```ts cordis-catalog
70
+ /**
71
+ * Offer a way to obtain one credential. One flow per key: two plugins
72
+ * claiming the same key would each write a record in their own format, and
73
+ * whichever ran last would leave the other reading a payload it cannot parse.
74
+ *
75
+ * @param flow - the key it writes, its label, its methods, and its runner.
76
+ * @returns Disposer that withdraws this flow.
77
+ * @throws {AuthorizationError} code `DUPLICATE_FLOW` when the key is already claimed.
78
+ */
79
+ registerFlow(flow: AuthorizationFlow): () => void
80
+
81
+ /**
82
+ * Every registered flow, for a surface listing what can be authorized.
83
+ * @returns one entry per flow, in registration order.
84
+ */
85
+ list(): readonly AuthorizationEntry[]
86
+
87
+ /**
88
+ * One registered flow.
89
+ * @param key - the credential record to ask about.
90
+ * @returns the entry, or undefined when no flow claims that key.
91
+ */
92
+ describe(key: CredentialKey): AuthorizationEntry | undefined
93
+
94
+ /**
95
+ * Withdraw the attempt running for a key, if any. Separate from the
96
+ * request's own signal because a request/response transport answers a Cancel
97
+ * button on a second call, with no handle on the first one's signal.
98
+ * @param key - the credential record whose attempt should stop.
99
+ */
100
+ cancel(key: CredentialKey): void
101
+
102
+ /**
103
+ * Run one attempt to authorize a key, and report how it ended.
104
+ *
105
+ * One attempt per key at a time. A second caller is refused rather than
106
+ * joined: the two would be prompting different humans through the same flow,
107
+ * and the second would answer questions the first was asked.
108
+ *
109
+ * @param request - the key, the method, the surface, and the cancel signal.
110
+ * @returns `authorized` once the flow's record is committed during this
111
+ * attempt and observed, or `cancelled` when the human declined or the
112
+ * caller withdrew.
113
+ * @throws {AuthorizationError} code `NO_FLOW` when nothing claims the key,
114
+ * `UNKNOWN_METHOD` when the named method is not one the flow offers,
115
+ * `ALREADY_IN_FLIGHT` when an attempt is already running for the key, or
116
+ * `NOT_COMMITTED` when the flow resolved without committing a record
117
+ * during the attempt.
118
+ */
119
+ async begin(request: AuthorizationRequest): Promise<AuthorizationOutcome>
120
+ ```
121
+
122
+ Source: [`packages/credentials/authorization/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/credentials/authorization/src/index.ts)
62
123
 
63
124
  <a id="ctxcredentials--credentialprovider-abstract-seam"></a>
64
125
 
65
126
  ### `ctx.credentials` — `CredentialProvider` (abstract seam)
66
127
 
67
- Abstract credential service. Providers implement the four operations over their source layers; one seam-wide rule binds them all: an empty stored value is absent everywhere — `resolve` skips it, `describe` reports it unconfigured — so a blank never masquerades as a configured secret.
128
+ Abstract credential service over two key spaces that answer two questions.
129
+
130
+ A CredentialRef answers "what is behind this environment-variable name", layered over the process environment, the provider-managed store, and `.env` files. One seam-wide rule binds that half: an empty stored value is absent everywhere — `resolve` skips it, `describe` reports it unconfigured — so a blank never masquerades as a configured secret.
131
+
132
+ A CredentialKey answers "what credential does this plugin hold for this id". Nothing can layer here — an authorization grant has no environment to be read from — so presence of the record is the whole fact, and modifyRecord is the only write path because a correct write depends on the current value (a token refresh is read-decide-replace under one lock).
68
133
 
69
134
  ```ts cordis-catalog
70
135
  /**
@@ -102,17 +167,107 @@ abstract set(ref: CredentialRef, value: string): Promise<void>
102
167
  * @param ref - the reference to remove.
103
168
  */
104
169
  abstract unset(ref: CredentialRef): Promise<void>
170
+
171
+ /**
172
+ * Read one stored record. The value is returned as its owner wrote it; a
173
+ * {@link GrantRecord} payload is not interpreted on the way out.
174
+ * @param key - the record to read.
175
+ * @returns the record, or `undefined` while none is stored.
176
+ */
177
+ abstract readRecord(key: CredentialKey): Promise<CredentialRecord | undefined>
178
+
179
+ /**
180
+ * Describe one record for configuration surfaces without exposing its value.
181
+ * @param key - the record to describe.
182
+ * @returns presence, discriminant, and writability.
183
+ */
184
+ abstract describeRecord(key: CredentialKey): Promise<CredentialRecordInfo>
185
+
186
+ /**
187
+ * Enumerate every stored record's address and tag. Unlike the reference
188
+ * half, which has no enumeration because configuration surfaces learn which
189
+ * references exist from settings schemas, records have no such discovery
190
+ * path: a surface that cannot list them cannot show what a user is
191
+ * authorized for, nor find an orphan left by an uninstalled plugin.
192
+ * @returns every stored record, values excluded.
193
+ */
194
+ abstract listRecords(): Promise<readonly CredentialRecordEntry[]>
195
+
196
+ /**
197
+ * Serialized read-modify-write over one record — the only write path.
198
+ * `mutate` sees the record as it stands at the moment the write is
199
+ * exclusive, and returning `undefined` leaves the entry untouched. Exclusion
200
+ * holds across processes where the backing store supports it, which is what
201
+ * makes a token refresh safe: two processes rotating one refresh token
202
+ * concurrently would otherwise lose whichever wrote first.
203
+ * @param key - the record to modify.
204
+ * @param mutate - receives the current record and returns its replacement, or `undefined` to leave it.
205
+ * @returns the record after the write, or the current one when `mutate` declined.
206
+ */
207
+ abstract modifyRecord( key: CredentialKey, mutate: (current: CredentialRecord | undefined) => Promise<CredentialRecord | undefined>, ): Promise<CredentialRecord | undefined>
208
+
209
+ /**
210
+ * Remove one record; removing an absent record is a no-op.
211
+ * @param key - the record to remove.
212
+ */
213
+ abstract deleteRecord(key: CredentialKey): Promise<void>
214
+ ```
215
+
216
+ Source: [`packages/credentials/credentials/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/credentials/credentials/src/index.ts)
217
+
218
+ <a id="authorization-events"></a>
219
+
220
+ ### `authorization/*` events
221
+
222
+ <a id="authorizationsettled--emit"></a>
223
+
224
+ #### `authorization/settled` — emit
225
+
226
+ One authorization attempt has finished and released its key. Fires for every terminal outcome, failures included, so a surface watching a key it did not start (a second browser tab) learns the attempt is over.
227
+
228
+ ```ts cordis-catalog
229
+ /**
230
+ * One authorization attempt has finished and released its key. Fires for
231
+ * every terminal outcome, failures included, so a surface watching a key it
232
+ * did not start (a second browser tab) learns the attempt is over.
233
+ * @mode emit
234
+ * @param key - the credential record the finished attempt was authorizing.
235
+ * @param settlement - how it ended, including the `failed` case its caller sees as a thrown error.
236
+ */
237
+ 'authorization/settled'(key: CredentialKey, settlement: AuthorizationSettlement): void
105
238
  ```
106
239
 
107
- Source: [`packages/credentials/credentials/src/index.ts:60`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/credentials/credentials/src/index.ts)
240
+ Source: [`packages/credentials/authorization/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/credentials/authorization/src/index.ts)
108
241
 
109
242
  <a id="credentials-events"></a>
110
243
 
111
244
  ### `credentials/*` events
112
245
 
113
- <a id="credentialsupdated--emit"></a>
246
+ <a id="credentialsrecord-updated--emit"></a>
247
+
248
+ #### `credentials/record-updated` — emit
249
+
250
+ Committed change to a stored credential record: a `modifyRecord` that wrote, a `deleteRecord` that removed, or an external edit observed in storage. Separate from `credentials/reference-updated` because the two key grammars are disjoint — a listener that received both on one event could not tell which space a subject belongs to. Listener failures are contained on the same terms as `credentials/reference-updated`.
251
+
252
+ ```ts cordis-catalog
253
+ /**
254
+ * Committed change to a stored credential record: a `modifyRecord` that
255
+ * wrote, a `deleteRecord` that removed, or an external edit observed in
256
+ * storage. Separate from `credentials/reference-updated` because the two key
257
+ * grammars are disjoint — a listener that received both on one event could
258
+ * not tell which space a subject belongs to. Listener failures are
259
+ * contained on the same terms as `credentials/reference-updated`.
260
+ * @param key - the record whose stored value changed.
261
+ * @mode emit
262
+ */
263
+ 'credentials/record-updated'(key: CredentialKey): void
264
+ ```
265
+
266
+ Source: [`packages/credentials/credentials/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/credentials/credentials/src/types.ts)
267
+
268
+ <a id="credentialsreference-updated--emit"></a>
114
269
 
115
- #### `credentials/updated` — emit
270
+ #### `credentials/reference-updated` — emit
116
271
 
117
272
  Committed change to a provider-managed credential source: a `set`, an `unset`, or an external edit observed in storage. Ambient process-environment changes are not observable and never emit. Listener failures are contained and logged — a sync throw and an async rejection alike — without changing the committed operation's outcome, except `INVARIANT`-coded failures, which rethrow after every listener ran; that rethrow reaches the emitter only from synchronous listeners, so invariant checks on this event must not be async functions.
118
273
 
@@ -129,8 +284,8 @@ Committed change to a provider-managed credential source: a `set`, an `unset`, o
129
284
  * @param ref - the reference whose stored value changed.
130
285
  * @mode emit
131
286
  */
132
- 'credentials/updated'(ref: CredentialRef): void
287
+ 'credentials/reference-updated'(ref: CredentialRef): void
133
288
  ```
134
289
 
135
- Source: [`packages/credentials/credentials/src/types.ts:29`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/credentials/credentials/src/types.ts)
290
+ Source: [`packages/credentials/credentials/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/credentials/credentials/src/types.ts)
136
291
  <!-- END GENERATED cordis-surface -->
@@ -274,7 +274,7 @@ type FsErrorCode =
274
274
 
275
275
  ## 文件 IO 不设超时
276
276
 
277
- `read`/`write`/`edit` **不**接受 `timeoutMs`,提供方约定也不设置截止时间——不同于 bash 与 web(它们消费 [`@deepseek-ai/dsh-timeout`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/util/timeout/README.md))以及 subprocess 支撑的 `glob`/`grep`(其声明的 `timeoutMs` 由 `@deepseek-ai/dsh-tool-call-timeout-policy` 强制执行):那些是进程支撑的,截止时间可以真正终止工作。本地系统调用至多是尽力中止——超时无法迫使进行中的 `fsync`/`rename` 停下,因此这里的 `timeoutMs` 会成为 seam 无法强制执行的截止时间,而且恰好落在「显式优于隐式」禁止隐式默认值的位置。取消仍通过工具执行 signal 传播,在系统调用边界尽力中止。
277
+ `read`/`write`/`edit` **不**接受 `timeoutMs`,提供方约定也不设置截止时间——不同于 bash 与 web(它们消费 [`@deepseek-ai/dsh-timeout`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/util/timeout/README.zh.md))以及 subprocess 支撑的 `glob`/`grep`(其声明的 `timeoutMs` 由 `@deepseek-ai/dsh-tool-call-timeout-policy` 强制执行):那些是进程支撑的,截止时间可以真正终止工作。本地系统调用至多是尽力中止——超时无法迫使进行中的 `fsync`/`rename` 停下,因此这里的 `timeoutMs` 会成为 seam 无法强制执行的截止时间,而且恰好落在「显式优于隐式」禁止隐式默认值的位置。取消仍通过工具执行 signal 传播,在系统调用边界尽力中止。
278
278
 
279
279
  ## 服务与插件
280
280
 
@@ -286,7 +286,7 @@ type FsErrorCode =
286
286
 
287
287
  ## Cordis API
288
288
 
289
- 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).
289
+ 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).
290
290
 
291
291
  <a id="ctxfs--filesystem-abstract-seam"></a>
292
292
 
@@ -430,7 +430,7 @@ abstract editText( target: FsTarget, edit: FsEditRequest, expected?: { version:
430
430
 
431
431
  Types: [SandboxExecutionPolicy](./sandbox.md)
432
432
 
433
- Source: [`packages/fs/fs/src/index.ts:86`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
433
+ Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
434
434
 
435
435
  <a id="fs-events"></a>
436
436
 
@@ -453,7 +453,7 @@ Single-slot decision for the next FileSystem.editText. Calling `next()` yields a
453
453
  'fs/edit-intent'(target: FsTarget, actor: object | undefined, next: () => { version: FsVersion } | undefined | Promise<{ version: FsVersion } | undefined>): Promise<{ version: FsVersion } | undefined>
454
454
  ```
455
455
 
456
- Source: [`packages/fs/fs/src/index.ts:66`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
456
+ Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
457
457
 
458
458
  <a id="fsobserved--emit"></a>
459
459
 
@@ -474,7 +474,7 @@ Record an authoritative positive or negative observation. Listeners must be sync
474
474
  'fs/observed'(target: FsTarget, observation: FsObservation, actor: object | undefined): void
475
475
  ```
476
476
 
477
- Source: [`packages/fs/fs/src/index.ts:76`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
477
+ Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
478
478
 
479
479
  <a id="fswrite-intent--waterfall"></a>
480
480
 
@@ -494,5 +494,5 @@ Single-slot decision for the next FileSystem.writeText. Calling `next()` yields
494
494
  'fs/write-intent'(target: FsTarget, actor: object | undefined, next: () => FsWriteIntent | undefined | Promise<FsWriteIntent | undefined>): Promise<FsWriteIntent | undefined>
495
495
  ```
496
496
 
497
- Source: [`packages/fs/fs/src/index.ts:58`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
497
+ Source: [`packages/fs/fs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/fs/fs/src/index.ts)
498
498
  <!-- END GENERATED cordis-surface -->