dsh-plugin-dev-kb 1.0.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 (234) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -0
  3. package/cordis.patch.yml +12 -0
  4. package/kb/INDEX.md +210 -0
  5. package/kb/README.md +69 -0
  6. package/kb/extra/AGENTS.md +75 -0
  7. package/kb/extra/api-gateway.md +164 -0
  8. package/kb/extra/api-gateway.zh.md +164 -0
  9. package/kb/extra/cookbook/adding-a-vendored-package.md +59 -0
  10. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +59 -0
  11. package/kb/extra/cookbook/maintaining-dsh-code-review.md +64 -0
  12. package/kb/extra/cookbook/maintaining-dsh-code-review.zh.md +64 -0
  13. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.md +32 -0
  14. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +32 -0
  15. package/kb/extra/defensive-patterns.md +33 -0
  16. package/kb/extra/defensive-patterns.zh.md +33 -0
  17. package/kb/extra/development.md +171 -0
  18. package/kb/extra/development.zh.md +171 -0
  19. package/kb/extra/event-producer-consumer.md +76 -0
  20. package/kb/extra/event-producer-consumer.zh.md +78 -0
  21. package/kb/extra/glossary.md +45 -0
  22. package/kb/extra/glossary.zh.md +45 -0
  23. package/kb/extra/graph-atlas.md +24 -0
  24. package/kb/extra/graph-atlas.zh.md +26 -0
  25. package/kb/extra/i18n/README.md +60 -0
  26. package/kb/extra/i18n/README.zh.md +60 -0
  27. package/kb/extra/i18n/style-samples.md +87 -0
  28. package/kb/extra/i18n/terminology.md +214 -0
  29. package/kb/extra/i18n/translation-prompt.md +263 -0
  30. package/kb/extra/i18n/translation-rules.md +69 -0
  31. package/kb/extra/i18n/translation-rules.zh.md +69 -0
  32. package/kb/extra/module-graph.md +1641 -0
  33. package/kb/extra/module-graph.zh.md +1643 -0
  34. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +113 -0
  35. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +113 -0
  36. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +47 -0
  37. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +47 -0
  38. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +53 -0
  39. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +53 -0
  40. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +55 -0
  41. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +55 -0
  42. package/kb/extra/postmortem/README.md +18 -0
  43. package/kb/extra/postmortem/README.zh.md +18 -0
  44. package/kb/extra/rescope.md +53 -0
  45. package/kb/extra/rescope.zh.md +53 -0
  46. package/kb/extra/subsystems/attachment.md +125 -0
  47. package/kb/extra/subsystems/attachment.zh.md +125 -0
  48. package/kb/extra/subsystems/extensions.md +364 -0
  49. package/kb/extra/subsystems/extensions.zh.md +364 -0
  50. package/kb/extra/subsystems/feedback.md +266 -0
  51. package/kb/extra/subsystems/feedback.zh.md +266 -0
  52. package/kb/extra/testing.md +49 -0
  53. package/kb/extra/testing.zh.md +49 -0
  54. package/kb/extra/web-styling.md +25 -0
  55. package/kb/extra/web-styling.zh.md +25 -0
  56. package/kb/meta/search-index.json +1328 -0
  57. package/kb/meta/site-pages.txt +168 -0
  58. package/kb/meta/source.json +13 -0
  59. package/kb/meta/topics.md +75 -0
  60. package/kb/site/develop/basic/config.md +108 -0
  61. package/kb/site/develop/basic/index.md +146 -0
  62. package/kb/site/develop/basic/publish.md +185 -0
  63. package/kb/site/develop/basic/tool.md +54 -0
  64. package/kb/site/develop/cordis-tutorial/01-first-plugin.md +95 -0
  65. package/kb/site/develop/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
  66. package/kb/site/develop/cordis-tutorial/03-services.md +98 -0
  67. package/kb/site/develop/cordis-tutorial/04-events.md +144 -0
  68. package/kb/site/develop/cordis-tutorial/05-config.md +84 -0
  69. package/kb/site/develop/cordis-tutorial/06-composition-and-hmr.md +113 -0
  70. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +107 -0
  71. package/kb/site/develop/cordis-tutorial/index.md +62 -0
  72. package/kb/site/develop/framework/events.md +145 -0
  73. package/kb/site/develop/framework/index.md +139 -0
  74. package/kb/site/develop/framework/service.md +152 -0
  75. package/kb/site/develop/practice/index.md +157 -0
  76. package/kb/site/develop/practice/llm-adapter.md +190 -0
  77. package/kb/site/en/develop/basic/config.md +108 -0
  78. package/kb/site/en/develop/basic/index.md +146 -0
  79. package/kb/site/en/develop/basic/publish.md +185 -0
  80. package/kb/site/en/develop/basic/tool.md +54 -0
  81. package/kb/site/en/develop/cordis-tutorial/01-first-plugin.md +95 -0
  82. package/kb/site/en/develop/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
  83. package/kb/site/en/develop/cordis-tutorial/03-services.md +98 -0
  84. package/kb/site/en/develop/cordis-tutorial/04-events.md +144 -0
  85. package/kb/site/en/develop/cordis-tutorial/05-config.md +84 -0
  86. package/kb/site/en/develop/cordis-tutorial/06-composition-and-hmr.md +113 -0
  87. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +107 -0
  88. package/kb/site/en/develop/cordis-tutorial/index.md +60 -0
  89. package/kb/site/en/develop/framework/events.md +145 -0
  90. package/kb/site/en/develop/framework/index.md +139 -0
  91. package/kb/site/en/develop/framework/service.md +150 -0
  92. package/kb/site/en/develop/practice/index.md +157 -0
  93. package/kb/site/en/develop/practice/llm-adapter.md +190 -0
  94. package/kb/site/en/guide/providers-custom-form.png +0 -0
  95. package/kb/site/en/guide/providers-models-page.png +0 -0
  96. package/kb/site/en/guide/providers.md +100 -0
  97. package/kb/site/en/guide/python-sdk.md +106 -0
  98. package/kb/site/en/guide/quickstart.md +32 -0
  99. package/kb/site/en/index.md +8 -0
  100. package/kb/site/en/reference/agent-lifecycle.md +86 -0
  101. package/kb/site/en/reference/capability-seams.md +475 -0
  102. package/kb/site/en/reference/config-catalog.md +3155 -0
  103. package/kb/site/en/reference/cookbook/adding-a-conversation-node.md +235 -0
  104. package/kb/site/en/reference/cookbook/adding-a-package.md +120 -0
  105. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +102 -0
  106. package/kb/site/en/reference/cookbook/adding-a-tool.md +96 -0
  107. package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +45 -0
  108. package/kb/site/en/reference/cookbook/extension-cookbook.md +131 -0
  109. package/kb/site/en/reference/cordis-api/context.md +368 -0
  110. package/kb/site/en/reference/cordis-api/events.md +211 -0
  111. package/kb/site/en/reference/cordis-api/fiber.md +379 -0
  112. package/kb/site/en/reference/cordis-api/inherited.md +43 -0
  113. package/kb/site/en/reference/cordis-api/registry.md +156 -0
  114. package/kb/site/en/reference/cordis-api/service.md +106 -0
  115. package/kb/site/en/reference/cordis-primer.md +46 -0
  116. package/kb/site/en/reference/index.md +131 -0
  117. package/kb/site/en/reference/persistence-catalog.md +949 -0
  118. package/kb/site/en/reference/subsystems/approval.md +173 -0
  119. package/kb/site/en/reference/subsystems/client-modules.md +121 -0
  120. package/kb/site/en/reference/subsystems/code-runtime.md +194 -0
  121. package/kb/site/en/reference/subsystems/commands.md +190 -0
  122. package/kb/site/en/reference/subsystems/compaction.md +241 -0
  123. package/kb/site/en/reference/subsystems/core.md +1073 -0
  124. package/kb/site/en/reference/subsystems/credentials.md +136 -0
  125. package/kb/site/en/reference/subsystems/filesystem.md +498 -0
  126. package/kb/site/en/reference/subsystems/goal.md +280 -0
  127. package/kb/site/en/reference/subsystems/index.md +58 -0
  128. package/kb/site/en/reference/subsystems/invariants.md +91 -0
  129. package/kb/site/en/reference/subsystems/jobs.md +293 -0
  130. package/kb/site/en/reference/subsystems/llm-streaming.md +920 -0
  131. package/kb/site/en/reference/subsystems/lsp.md +205 -0
  132. package/kb/site/en/reference/subsystems/permission-presets.md +134 -0
  133. package/kb/site/en/reference/subsystems/persistence.md +388 -0
  134. package/kb/site/en/reference/subsystems/plan.md +90 -0
  135. package/kb/site/en/reference/subsystems/sandbox.md +221 -0
  136. package/kb/site/en/reference/subsystems/schedule.md +189 -0
  137. package/kb/site/en/reference/subsystems/scope.md +62 -0
  138. package/kb/site/en/reference/subsystems/session-projection.md +265 -0
  139. package/kb/site/en/reference/subsystems/session-query.md +498 -0
  140. package/kb/site/en/reference/subsystems/session-reference.md +111 -0
  141. package/kb/site/en/reference/subsystems/session-telemetry.md +197 -0
  142. package/kb/site/en/reference/subsystems/session-title.md +207 -0
  143. package/kb/site/en/reference/subsystems/session.md +852 -0
  144. package/kb/site/en/reference/subsystems/settings.md +313 -0
  145. package/kb/site/en/reference/subsystems/shell.md +306 -0
  146. package/kb/site/en/reference/subsystems/skills.md +334 -0
  147. package/kb/site/en/reference/subsystems/spill.md +120 -0
  148. package/kb/site/en/reference/subsystems/storage.md +232 -0
  149. package/kb/site/en/reference/subsystems/subagent.md +737 -0
  150. package/kb/site/en/reference/subsystems/subprocess.md +327 -0
  151. package/kb/site/en/reference/subsystems/system-prompt.md +210 -0
  152. package/kb/site/en/reference/subsystems/terminal.md +187 -0
  153. package/kb/site/en/reference/subsystems/token-meter.md +93 -0
  154. package/kb/site/en/reference/subsystems/tools.md +723 -0
  155. package/kb/site/en/reference/subsystems/typert.md +339 -0
  156. package/kb/site/en/reference/subsystems/user-questions.md +181 -0
  157. package/kb/site/en/reference/subsystems/web-server.md +111 -0
  158. package/kb/site/en/reference/subsystems/web.md +202 -0
  159. package/kb/site/en/reference/subsystems/workflow.md +281 -0
  160. package/kb/site/en/reference/subsystems/workspace.md +231 -0
  161. package/kb/site/en/reference/tool-catalog.md +1877 -0
  162. package/kb/site/en/reference/tool-execution-pipeline.md +66 -0
  163. package/kb/site/guide/providers-custom-form.zh.png +0 -0
  164. package/kb/site/guide/providers-models-page.zh.png +0 -0
  165. package/kb/site/guide/providers.md +100 -0
  166. package/kb/site/guide/python-sdk.md +106 -0
  167. package/kb/site/guide/quickstart.md +32 -0
  168. package/kb/site/index.md +8 -0
  169. package/kb/site/reference/agent-lifecycle.md +86 -0
  170. package/kb/site/reference/capability-seams.md +475 -0
  171. package/kb/site/reference/config-catalog.md +3154 -0
  172. package/kb/site/reference/cookbook/adding-a-conversation-node.md +235 -0
  173. package/kb/site/reference/cookbook/adding-a-package.md +120 -0
  174. package/kb/site/reference/cookbook/adding-a-settings-card.md +102 -0
  175. package/kb/site/reference/cookbook/adding-a-tool.md +98 -0
  176. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +45 -0
  177. package/kb/site/reference/cookbook/extension-cookbook.md +133 -0
  178. package/kb/site/reference/cordis-api/context.md +368 -0
  179. package/kb/site/reference/cordis-api/events.md +211 -0
  180. package/kb/site/reference/cordis-api/fiber.md +379 -0
  181. package/kb/site/reference/cordis-api/inherited.md +43 -0
  182. package/kb/site/reference/cordis-api/registry.md +156 -0
  183. package/kb/site/reference/cordis-api/service.md +106 -0
  184. package/kb/site/reference/cordis-primer.md +52 -0
  185. package/kb/site/reference/index.md +135 -0
  186. package/kb/site/reference/persistence-catalog.md +949 -0
  187. package/kb/site/reference/subsystems/approval.md +173 -0
  188. package/kb/site/reference/subsystems/client-modules.md +121 -0
  189. package/kb/site/reference/subsystems/code-runtime.md +194 -0
  190. package/kb/site/reference/subsystems/commands.md +190 -0
  191. package/kb/site/reference/subsystems/compaction.md +241 -0
  192. package/kb/site/reference/subsystems/core.md +1081 -0
  193. package/kb/site/reference/subsystems/credentials.md +136 -0
  194. package/kb/site/reference/subsystems/filesystem.md +498 -0
  195. package/kb/site/reference/subsystems/goal.md +280 -0
  196. package/kb/site/reference/subsystems/index.md +58 -0
  197. package/kb/site/reference/subsystems/invariants.md +91 -0
  198. package/kb/site/reference/subsystems/jobs.md +293 -0
  199. package/kb/site/reference/subsystems/llm-streaming.md +926 -0
  200. package/kb/site/reference/subsystems/lsp.md +205 -0
  201. package/kb/site/reference/subsystems/permission-presets.md +134 -0
  202. package/kb/site/reference/subsystems/persistence.md +388 -0
  203. package/kb/site/reference/subsystems/plan.md +90 -0
  204. package/kb/site/reference/subsystems/sandbox.md +221 -0
  205. package/kb/site/reference/subsystems/schedule.md +189 -0
  206. package/kb/site/reference/subsystems/scope.md +62 -0
  207. package/kb/site/reference/subsystems/session-projection.md +265 -0
  208. package/kb/site/reference/subsystems/session-query.md +498 -0
  209. package/kb/site/reference/subsystems/session-reference.md +111 -0
  210. package/kb/site/reference/subsystems/session-telemetry.md +197 -0
  211. package/kb/site/reference/subsystems/session-title.md +207 -0
  212. package/kb/site/reference/subsystems/session.md +854 -0
  213. package/kb/site/reference/subsystems/settings.md +313 -0
  214. package/kb/site/reference/subsystems/shell.md +306 -0
  215. package/kb/site/reference/subsystems/skills.md +334 -0
  216. package/kb/site/reference/subsystems/spill.md +120 -0
  217. package/kb/site/reference/subsystems/storage.md +232 -0
  218. package/kb/site/reference/subsystems/subagent.md +739 -0
  219. package/kb/site/reference/subsystems/subprocess.md +327 -0
  220. package/kb/site/reference/subsystems/system-prompt.md +210 -0
  221. package/kb/site/reference/subsystems/terminal.md +187 -0
  222. package/kb/site/reference/subsystems/token-meter.md +93 -0
  223. package/kb/site/reference/subsystems/tools.md +723 -0
  224. package/kb/site/reference/subsystems/typert.md +339 -0
  225. package/kb/site/reference/subsystems/user-questions.md +181 -0
  226. package/kb/site/reference/subsystems/web-server.md +111 -0
  227. package/kb/site/reference/subsystems/web.md +202 -0
  228. package/kb/site/reference/subsystems/workflow.md +281 -0
  229. package/kb/site/reference/subsystems/workspace.md +231 -0
  230. package/kb/site/reference/tool-catalog.md +1880 -0
  231. package/kb/site/reference/tool-execution-pipeline.md +66 -0
  232. package/package.json +40 -0
  233. package/scripts/rebuild-index.mjs +88 -0
  234. package/skills/dsh-plugin-dev-kb.md +66 -0
@@ -0,0 +1,293 @@
1
+ ---
2
+ editSource: "docs/subsystems/jobs.zh.md"
3
+ outline: [2,3]
4
+ ---
5
+
6
+ # 后台任务运行时
7
+
8
+ 长时间运行的生产方、`ctx.jobs` 与任务控制命令共用的类型。[运行时 Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md) 负责设计;本页记录 [`packages/jobs/jobs/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/types.ts) 中的确切字段和变体。
9
+
10
+ ## ID 与状态
11
+
12
+ `JobId` 是按 `<kind>-N` 生成的[品牌化 id](./core.md#branded-ids)。访问控制依赖拥有者授权,而非 id 的保密性。`JobKind` 派生自可合并扩展的 map;注册表将各个 kind 视为不透明的 id 命名空间。
13
+
14
+ ```ts type-equiv
15
+ /**
16
+ * Producer-defined job kinds. Plugins extend this map by declaration merging;
17
+ * the registry treats every value as an opaque id namespace.
18
+ */
19
+ interface JobKindMap {
20
+ bash: 'bash'
21
+ subagent: 'subagent'
22
+ }
23
+ ```
24
+
25
+ `JobStatus` 为 `'running' | 'stopping' | 'completed' | 'killed' | 'failed'`;生产方特有的事实归入 `JobSnapshot.detail`。
26
+
27
+ ## 生产方约定
28
+
29
+ `JobStart` 声明身份和启动器。运行时会在调用 `run()` 前完成预检,随后提交注册,不再执行可能失败的步骤。生产方拥有执行资源;运行时拥有身份、访问权限和生命周期状态。
30
+
31
+ ```ts type-equiv
32
+ /**
33
+ * Producer declaration passed to {@link JobRegistry.start}. The runtime
34
+ * preflights access and cleanup before invoking {@link run}; the producer owns
35
+ * execution resources while the runtime owns identity and lifecycle state.
36
+ */
37
+ interface JobStart {
38
+ /** Producer kind — also the id prefix (`bash`, `subagent`, …). */
39
+ kind: JobKind
40
+ /** One-line model-facing label (the command; the delegation description). */
41
+ label: string
42
+ /**
43
+ * Optional UTF-8 byte cap for each complete model-facing completion notice or
44
+ * output read, including controller status metadata.
45
+ */
46
+ outputLimitBytes?: number
47
+ /**
48
+ * Owning live agent. Access is fenced by its session id, and agent disposal
49
+ * cancels and awaits the job. The instance must be the one currently
50
+ * registered under its agent id. Omitting the owner creates an unowned job,
51
+ * open to any caller until service disposal.
52
+ */
53
+ owner?: Agent
54
+ /**
55
+ * Start the work after preflight and synchronously return its hooks. Called
56
+ * once; a throw leaves nothing registered, and the producer must clean up any
57
+ * partially started resources.
58
+ */
59
+ run(): JobHooks
60
+ }
61
+ ```
62
+
63
+ `JobHooks.done` 会在生产方释放其资源后 resolve,而不是仅在工作完成时 resolve。可选的 `readOutput` 用来区分会消费输出的流式任务和仅有最终输出的任务。
64
+
65
+ ```ts type-equiv
66
+ /** Hooks through which the runtime controls and observes producer work. */
67
+ interface JobHooks {
68
+ /**
69
+ * Request termination. Must be synchronous, idempotent, and eventually settle
70
+ * {@link done}; throws propagate. The optional reason is forwarded verbatim.
71
+ */
72
+ cancel(reason?: string): void
73
+ /**
74
+ * Resolves after the producer releases its resources, not merely when work
75
+ * finishes. Must not reject; the runtime converts a rejection to `failed`.
76
+ * If teardown cancellation throws, the runtime may force-fail only the
77
+ * registry record without claiming that the work stopped.
78
+ */
79
+ done: Promise<JobOutcome>
80
+ /**
81
+ * Consume output produced since the previous call. The producer formats
82
+ * truncation and spill notices. Absence marks a final-output-only job; each
83
+ * job has one consuming cursor.
84
+ */
85
+ readOutput?(): string
86
+ }
87
+ ```
88
+
89
+ ```ts type-equiv
90
+ /** Terminal result supplied by a producer through {@link JobHooks.done}. */
91
+ interface JobOutcome {
92
+ /** How the job ended: finished (`completed`), cancelled (`killed`), or broke (`failed`). */
93
+ status: 'completed' | 'killed' | 'failed'
94
+ /** Kind-specific detail rendered into status lines ('exit code: 3', 'max-tokens'). */
95
+ detail?: string
96
+ /** Final output for jobs without `readOutput`; stream jobs leave it unset. */
97
+ output?: string
98
+ }
99
+ ```
100
+
101
+ ## 消费方视图
102
+
103
+ 快照是每次新建的只读投影。`ownerSession` 携带用于授权的共享 `SessionId`;完成监听器则会另行收到用于生命周期清理的确切拥有者对象。另一个接口已经交付终止状态或承诺交付时,`reported` 会抑制完成通知;排空 owner 或服务的 teardown 取消同样计入。
104
+
105
+ ```ts type-equiv
106
+ /**
107
+ * A read-only projection of one job, safe to hand to listeners and tools —
108
+ * a fresh object per call, never live registry state.
109
+ */
110
+ interface JobSnapshot {
111
+ /** The registry-issued id (`<kind>-N`). */
112
+ id: JobId
113
+ /** The producer kind the job was registered with. */
114
+ kind: JobKind
115
+ /** The producer-supplied one-line label. */
116
+ label: string
117
+ /** Producer-owned cap for complete model-facing notices and output reads. */
118
+ outputLimitBytes?: number
119
+ /**
120
+ * Owner session id used for authorization and correlation; absent for
121
+ * unowned jobs. Completion listeners receive the exact {@link Agent}
122
+ * separately through {@link JobDoneListener}.
123
+ */
124
+ ownerSession?: SessionId
125
+ /** Current lifecycle state. */
126
+ status: JobStatus
127
+ /** Kind-specific status detail, present once the producer supplied one (usually terminal). */
128
+ detail?: string
129
+ /** Epoch ms when the job was registered. */
130
+ startedAt: number
131
+ /** Epoch ms when the job settled; absent while `running`/`stopping`. */
132
+ finishedAt?: number
133
+ /**
134
+ * True when a kill, read, wait, or teardown cancel has reported or committed
135
+ * to report the terminal state. Completion reporters suppress redundant
136
+ * notices when set. Teardown claims it because the owner or service being
137
+ * destroyed leaves no reader: a reporter that opens a turn on notice would
138
+ * otherwise spend a model request per teardown layer.
139
+ */
140
+ reported: boolean
141
+ }
142
+ ```
143
+
144
+ ```ts type-equiv
145
+ /** Output and post-read state returned by {@link JobRegistry.read}. */
146
+ interface JobRead {
147
+ /**
148
+ * Stream kinds: the consuming delta since the previous read. Final-output
149
+ * kinds: empty while live, the terminal {@link JobOutcome.output} (or
150
+ * empty) once settled — idempotent, never consumed.
151
+ */
152
+ text: string
153
+ /** The job's state at read time. */
154
+ snapshot: JobSnapshot
155
+ }
156
+ ```
157
+
158
+ ## 服务行为
159
+
160
+ 抽象的 [`JobRegistry`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/index.ts) Service Definition 规定原子 `start`、限定调用方作用域的 `get` 和 `list`、`read`、`kill`、有界 `wait`、故障隔离的 `onJobDone` 与 `onJobsChanged` 监听器,以及 `attachController` 何时可用;[`LocalJobRegistry`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs-local/src/index.ts) 是其进程局部 Service Provider。授权会比较拥有者会话;拥有者清理与准入会使用确切的已注册 `Agent` 实例。本地 Service Provider 的 `maxConcurrentJobsPerOwner` 配置必须是正的安全整数,默认值为 `10`;它按确切 owner 统计 `running` 与 `stopping` 记录,所有无 owner 任务共享一个服务级桶,并在生产方终止结算后释放容量。Service Definition 约定见 [`dsh-jobs`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/README.md),注册表生命周期与准入策略见 [`dsh-jobs-local`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs-local/README.md),面向模型的 Consumer 见 [`dsh-tool-jobs`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/tool-jobs/README.md)。
161
+
162
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
163
+
164
+ <a id="cordis-surface"></a>
165
+
166
+ ## Cordis API
167
+
168
+ 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).
169
+
170
+ <a id="ctxjobs--jobregistry-abstract-seam"></a>
171
+
172
+ ### `ctx.jobs` — `JobRegistry` (abstract seam)
173
+
174
+ Abstract background job registry. Subclass, implement the abstract methods, and load the subclass as a plugin — it registers as `ctx.jobs` (one implementation per context; loading a second throws, which is cordis' standard duplicate-service behavior).
175
+
176
+ Implementations must honor these semantics:
177
+
178
+ - Registrations outlive producer and controller fibers. Owner and service disposal cancel live work and await compliant producers; a throwing teardown cancel force-fails only the record. Teardown cancellation also marks the record reported, because a record its owner is being destroyed for has no reader left.
179
+ - Owned-job access is fenced by the owner's session id. Ids are predictable, so authorization — not secrecy — is the boundary.
180
+ - Settlement is first-wins: one terminal record, released waiters, and one round of contained listener notification, even against a late producer outcome. Completion is announced last, after the record is committed and every other observer of the settlement has seen it, because a reporter may open a model turn synchronously.
181
+ - start refuses work while no attached job controller serves the spec's owner, so a producer cannot start work that owner cannot collect or stop. One registry serves every composition in the process, so this question — and completion-listener delivery — is owner-relative rather than process-wide: registrations made from an unscoped context serve every owner, and registrations made under an agent composition's scope serve exactly the agents composed under it.
182
+
183
+ ```ts cordis-catalog
184
+ /**
185
+ * Preflight access, validation, owner cleanup, and implementation-owned
186
+ * admission before starting and atomically registering work. Any preflight
187
+ * rejection leaves no job id or execution resource. A throwing starter
188
+ * leaves nothing registered; after it returns, registration cannot fail.
189
+ * Settlement records the outcome, notifies listeners, and releases waiters.
190
+ * @param spec - job identity, owner, and synchronous starter.
191
+ * @returns the registry-issued `<kind>-N` id.
192
+ */
193
+ abstract start(spec: JobStart): JobId
194
+
195
+ /**
196
+ * List caller-owned and unowned jobs in registration order without exposing
197
+ * another session's labels.
198
+ * @param caller - reading agent; a non-agent caller sees only unowned jobs.
199
+ * @returns fresh snapshots.
200
+ */
201
+ abstract list(caller?: Agent): JobSnapshot[]
202
+
203
+ /**
204
+ * Return a non-consuming snapshot without changing its read cursor or notice
205
+ * state. Throws for an unknown or foreign job.
206
+ * @param id - job to look up.
207
+ * @param caller - reading agent checked against the owner.
208
+ * @returns a fresh snapshot.
209
+ */
210
+ abstract get(id: JobId, caller?: Agent): JobSnapshot
211
+
212
+ /**
213
+ * Read the next stream delta, or the idempotent final output after settlement.
214
+ * A terminal read marks the job reported. Throws for an unknown or foreign
215
+ * job.
216
+ * @param id - job to read.
217
+ * @param caller - reading agent checked against the owner.
218
+ * @returns output text and the post-read snapshot.
219
+ */
220
+ abstract read(id: JobId, caller?: Agent): JobRead
221
+
222
+ /**
223
+ * Request cancellation, then mark the job stopping and reported. A producer
224
+ * throw propagates without changing job state. Throws for an unknown or
225
+ * foreign job.
226
+ * @param id - job to cancel.
227
+ * @param caller - killing agent checked against the owner.
228
+ * @param reason - logged reason forwarded to the producer.
229
+ * @returns `requested` for live work, otherwise `already-finished`.
230
+ */
231
+ abstract kill(id: JobId, caller?: Agent, reason?: string): 'requested' | 'already-finished'
232
+
233
+ /**
234
+ * Wait for settlement or timeout without cancelling the job. Caller abort
235
+ * rejects only while the job is live; after settlement the terminal
236
+ * snapshot wins so a notice suppressed for this waiter is still delivered.
237
+ * Throws for invalid, unknown, or foreign input.
238
+ * @param id - job to wait for.
239
+ * @param timeoutMs - positive finite wait bound in milliseconds.
240
+ * @param caller - waiting agent checked against the owner.
241
+ * @param signal - optional cancellation of the wait itself.
242
+ * @returns snapshot at settlement or timeout.
243
+ */
244
+ abstract wait(id: JobId, timeoutMs: number, caller?: Agent, signal?: AbortSignal): Promise<JobSnapshot>
245
+
246
+ /**
247
+ * Register an effect-scoped completion listener. It receives the settlements
248
+ * of the owners its registering context's scope covers; each listener is
249
+ * contained; returned promises are observed but not awaited. No listener runs
250
+ * after service disposal.
251
+ * @param listener - receives each terminal snapshot and its exact owner.
252
+ * @returns disposer that unregisters the listener.
253
+ */
254
+ abstract onJobDone(listener: JobDoneListener): () => void
255
+
256
+ /**
257
+ /**
258
+ * Register an effect-scoped observer of visible-set changes. It fires after
259
+ * every commit that changes what {@link list} returns for that owner —
260
+ * registration, every stopping transition (including the one teardown
261
+ * performs before it awaits a slow producer), settlement, owner-disposal
262
+ * removal, and the emptying that service disposal commits — so an observer
263
+ * re-reads rather than accumulating deltas.
264
+ *
265
+ * Delivery is owner-relative on the same terms as {@link onJobDone}: an
266
+ * observer registered from an unscoped context — a host composition's own
267
+ * carrier — sees every owner, while one registered under an agent
268
+ * composition's scope sees exactly the agents composed under it.
269
+ *
270
+ * This is not a superset of {@link onJobDone}: that one delivers the terminal
271
+ * record under first-wins semantics a job controller couples to notice
272
+ * delivery, while this one carries no delivery meaning and marks nothing
273
+ * reported. Listeners are contained and never awaited.
274
+ * @param listener - receives the owner whose visible set changed, or
275
+ * `undefined` when an unowned job changed and every caller's set did.
276
+ * @returns disposer that unregisters the listener.
277
+ */
278
+ abstract onJobsChanged(listener: JobsChangedListener): () => void
279
+
280
+ /**
281
+ * Attach an effect-scoped controller that can read and stop jobs. It serves the
282
+ * owners its registering context's scope covers, and {@link start} refuses an
283
+ * owner no attached controller serves.
284
+ * @param name - diagnostic label; duplicate names remain independent.
285
+ * @returns disposer that detaches this controller.
286
+ */
287
+ abstract attachController(name: string): () => void
288
+ ```
289
+
290
+ Types: [Agent](./core.md)
291
+
292
+ Source: [`packages/jobs/jobs/src/index.ts:62`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/index.ts)
293
+ <!-- END GENERATED cordis-surface -->