dsh-plugin-dev-kb 1.3.0 → 1.4.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 (364) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.en.md +4 -4
  3. package/README.md +5 -5
  4. package/kb/INDEX.md +18 -18
  5. package/kb/README.md +6 -4
  6. package/kb/extra/AGENTS.md +11 -10
  7. package/kb/extra/cookbook/adding-a-remote-api.md +2 -2
  8. package/kb/extra/cookbook/adding-a-remote-api.zh.md +2 -2
  9. package/kb/extra/cookbook/adding-a-session-format-version.md +48 -6
  10. package/kb/extra/cookbook/adding-a-session-format-version.zh.md +48 -6
  11. package/kb/extra/cookbook/reviewing-persistence-type-changes.md +120 -0
  12. package/kb/extra/cookbook/reviewing-persistence-type-changes.zh.md +120 -0
  13. package/kb/extra/deepseek-llm-api-wire-extensions.md +18 -19
  14. package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +17 -18
  15. package/kb/extra/development.md +27 -10
  16. package/kb/extra/development.zh.md +27 -10
  17. package/kb/extra/event-producer-consumer.md +89 -68
  18. package/kb/extra/event-producer-consumer.zh.md +90 -69
  19. package/kb/extra/glossary.md +1 -1
  20. package/kb/extra/glossary.zh.md +1 -1
  21. package/kb/extra/i18n/README.md +15 -7
  22. package/kb/extra/i18n/README.zh.md +15 -7
  23. package/kb/extra/i18n/terminology.md +4 -4
  24. package/kb/extra/i18n/translation-prompt.md +2 -2
  25. package/kb/extra/module-graph.md +574 -326
  26. package/kb/extra/module-graph.zh.md +574 -326
  27. package/kb/extra/persistence-changes/2026-09-11-initial.md +280 -0
  28. package/kb/extra/persistence-changes/2026-09-11-initial.zh.md +280 -0
  29. package/kb/extra/persistence-changes/2026-09-12-auto-review-error-metadata.md +52 -0
  30. package/kb/extra/persistence-changes/2026-09-12-auto-review-error-metadata.zh.md +52 -0
  31. package/kb/extra/persistence-changes/2026-09-14-image-offload.md +96 -0
  32. package/kb/extra/persistence-changes/2026-09-14-image-offload.zh.md +96 -0
  33. package/kb/extra/persistence-changes/2026-09-14-workspace-changes-event.md +48 -0
  34. package/kb/extra/persistence-changes/2026-09-14-workspace-changes-event.zh.md +48 -0
  35. package/kb/extra/persistence-changes/2026-09-16-session-format-v4.md +120 -0
  36. package/kb/extra/persistence-changes/2026-09-16-session-format-v4.zh.md +120 -0
  37. package/kb/extra/persistence-changes/2026-09-18-schedule-optional-title.md +48 -0
  38. package/kb/extra/persistence-changes/2026-09-18-schedule-optional-title.zh.md +48 -0
  39. package/kb/extra/persistence-changes/2026-09-20-unknown-child-catalog.md +48 -0
  40. package/kb/extra/persistence-changes/2026-09-20-unknown-child-catalog.zh.md +48 -0
  41. package/kb/extra/persistence-changes/2026-09-21-user-question-reply.md +60 -0
  42. package/kb/extra/persistence-changes/2026-09-21-user-question-reply.zh.md +60 -0
  43. package/kb/extra/persistence-changes/README.md +88 -0
  44. package/kb/extra/persistence-changes/README.zh.md +88 -0
  45. package/kb/extra/persistence-changes/historical-formats/README.md +75 -0
  46. package/kb/extra/persistence-changes/historical-formats/README.zh.md +75 -0
  47. package/kb/extra/persistence-changes/historical-formats/v0.md +5105 -0
  48. package/kb/extra/persistence-changes/historical-formats/v0.zh.md +5105 -0
  49. package/kb/extra/persistence-changes/historical-formats/v1.md +5107 -0
  50. package/kb/extra/persistence-changes/historical-formats/v1.zh.md +5107 -0
  51. package/kb/extra/persistence-changes/historical-formats/v2.md +5362 -0
  52. package/kb/extra/persistence-changes/historical-formats/v2.zh.md +5362 -0
  53. package/kb/extra/persistence-changes/historical-formats/v3.md +5634 -0
  54. package/kb/extra/persistence-changes/historical-formats/v3.zh.md +5634 -0
  55. package/kb/extra/persistence-changes/releases/README.md +103 -0
  56. package/kb/extra/persistence-changes/releases/README.zh.md +103 -0
  57. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.1.md +201 -0
  58. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.1.zh.md +201 -0
  59. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.2.md +261 -0
  60. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.2.zh.md +261 -0
  61. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.3.md +126 -0
  62. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.3.zh.md +126 -0
  63. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.4.md +75 -0
  64. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.4.zh.md +75 -0
  65. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.5.md +75 -0
  66. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.5.zh.md +75 -0
  67. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.1.md +75 -0
  68. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.1.zh.md +75 -0
  69. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.2.md +75 -0
  70. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.2.zh.md +75 -0
  71. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.3.md +75 -0
  72. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.3.zh.md +75 -0
  73. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.5.md +75 -0
  74. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.5.zh.md +75 -0
  75. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.6.md +75 -0
  76. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.6.zh.md +75 -0
  77. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.7.md +82 -0
  78. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.7.zh.md +82 -0
  79. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.8.md +110 -0
  80. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.8.zh.md +110 -0
  81. package/kb/extra/persistence-changes/releases/dsh-v0.1.1-rc.1.md +82 -0
  82. package/kb/extra/persistence-changes/releases/dsh-v0.1.1-rc.1.zh.md +82 -0
  83. package/kb/extra/persistence-changes/releases/dsh-v0.1.1-rc.2.md +119 -0
  84. package/kb/extra/persistence-changes/releases/dsh-v0.1.1-rc.2.zh.md +119 -0
  85. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.1.md +295 -0
  86. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.1.zh.md +295 -0
  87. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.2.md +286 -0
  88. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.2.zh.md +286 -0
  89. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.3.md +75 -0
  90. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.3.zh.md +75 -0
  91. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.4.md +95 -0
  92. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.4.zh.md +95 -0
  93. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.5.md +75 -0
  94. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.5.zh.md +75 -0
  95. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-rc.1.md +75 -0
  96. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-rc.1.zh.md +75 -0
  97. package/kb/extra/persistence-changes/releases/dsh-v0.1.3-alpha.1.md +154 -0
  98. package/kb/extra/persistence-changes/releases/dsh-v0.1.3-alpha.1.zh.md +154 -0
  99. package/kb/extra/persistence-changes/releases/dsh-v0.1.3-alpha.2.md +86 -0
  100. package/kb/extra/persistence-changes/releases/dsh-v0.1.3-alpha.2.zh.md +86 -0
  101. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-alpha.1.md +139 -0
  102. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-alpha.1.zh.md +139 -0
  103. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-alpha.2.md +95 -0
  104. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-alpha.2.zh.md +95 -0
  105. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-rc.1.md +75 -0
  106. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-rc.1.zh.md +75 -0
  107. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-rc.2.md +75 -0
  108. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-rc.2.zh.md +75 -0
  109. package/kb/extra/rescope.md +1 -1
  110. package/kb/extra/rescope.zh.md +1 -1
  111. package/kb/extra/session-format-status.md +22 -6
  112. package/kb/extra/session-format-status.zh.md +22 -6
  113. package/kb/extra/subsystems/agent-team.md +52 -28
  114. package/kb/extra/subsystems/agent-team.zh.md +52 -28
  115. package/kb/extra/subsystems/attachment.md +19 -9
  116. package/kb/extra/subsystems/attachment.zh.md +19 -9
  117. package/kb/extra/subsystems/boot.md +323 -0
  118. package/kb/extra/subsystems/boot.zh.md +323 -0
  119. package/kb/extra/subsystems/browser-use.md +67 -0
  120. package/kb/extra/subsystems/browser-use.zh.md +67 -0
  121. package/kb/extra/subsystems/claude-code-mods.md +146 -0
  122. package/kb/extra/subsystems/claude-code-mods.zh.md +146 -0
  123. package/kb/extra/subsystems/computer-use.md +56 -0
  124. package/kb/extra/subsystems/computer-use.zh.md +56 -0
  125. package/kb/extra/subsystems/deliverables.md +178 -0
  126. package/kb/extra/subsystems/deliverables.zh.md +178 -0
  127. package/kb/extra/subsystems/extensions.md +6 -4
  128. package/kb/extra/subsystems/extensions.zh.md +6 -4
  129. package/kb/extra/subsystems/feedback.md +4 -4
  130. package/kb/extra/subsystems/feedback.zh.md +4 -4
  131. package/kb/extra/subsystems/mcp.md +139 -0
  132. package/kb/extra/subsystems/mcp.zh.md +139 -0
  133. package/kb/extra/subsystems/office-to-pdf.md +87 -0
  134. package/kb/extra/subsystems/office-to-pdf.zh.md +87 -0
  135. package/kb/extra/subsystems/otel.md +44 -0
  136. package/kb/extra/subsystems/otel.zh.md +44 -0
  137. package/kb/extra/subsystems/product-telemetry.md +79 -0
  138. package/kb/extra/subsystems/product-telemetry.zh.md +79 -0
  139. package/kb/extra/subsystems/ssh.md +135 -0
  140. package/kb/extra/subsystems/ssh.zh.md +135 -0
  141. package/kb/extra/subsystems/todo.md +3 -3
  142. package/kb/extra/subsystems/todo.zh.md +3 -3
  143. package/kb/extra/subsystems/voice-input.md +164 -0
  144. package/kb/extra/subsystems/voice-input.zh.md +164 -0
  145. package/kb/extra/subsystems/webhook.md +3 -3
  146. package/kb/extra/subsystems/webhook.zh.md +1 -1
  147. package/kb/extra/testing.md +3 -3
  148. package/kb/extra/testing.zh.md +3 -3
  149. package/kb/extra/ui-radius.md +115 -0
  150. package/kb/extra/ui-radius.zh.md +115 -0
  151. package/kb/extra/upgrade-guide/v0.1.7-rc.2/schedule-optional-bundle/guide.md +22 -0
  152. package/kb/extra/upgrade-guide/v0.1.7-rc.2/schedule-optional-bundle/guide.zh.md +22 -0
  153. package/kb/extra/upgrade-guide/v0.1.7-rc.2/transcript-view-legacy-normal/guide.md +25 -0
  154. package/kb/extra/upgrade-guide/v0.1.7-rc.2/transcript-view-legacy-normal/guide.zh.md +25 -0
  155. package/kb/extra/upgrade-guide/v0.2.0-rc.2/account-sign-in-errors/guide.md +18 -0
  156. package/kb/extra/upgrade-guide/v0.2.0-rc.2/account-sign-in-errors/guide.zh.md +18 -0
  157. package/kb/extra/upgrade-guide/v0.2.0-rc.2/remove-runtime-invariants/guide.md +23 -0
  158. package/kb/extra/upgrade-guide/v0.2.0-rc.2/remove-runtime-invariants/guide.zh.md +23 -0
  159. package/kb/extra/upgrade-guide/v0.2.0-rc.2/schedule-bundle-retired/guide.md +22 -0
  160. package/kb/extra/upgrade-guide/v0.2.0-rc.2/schedule-bundle-retired/guide.zh.md +22 -0
  161. package/kb/extra/upgrade-guide/v0.2.0-rc.2/subpath-plugin-display-manifest/guide.md +27 -0
  162. package/kb/extra/upgrade-guide/v0.2.0-rc.2/subpath-plugin-display-manifest/guide.zh.md +27 -0
  163. package/kb/extra/web-styling.md +12 -3
  164. package/kb/extra/web-styling.zh.md +12 -3
  165. package/kb/meta/search-index.json +976 -256
  166. package/kb/meta/site-pages.txt +188 -188
  167. package/kb/meta/source.json +6 -6
  168. package/kb/meta/topics.md +10 -6
  169. package/kb/site/develop/basic/config.md +1 -0
  170. package/kb/site/develop/basic/index.md +1 -0
  171. package/kb/site/develop/basic/publish.md +9 -2
  172. package/kb/site/develop/basic/tool.md +1 -0
  173. package/kb/site/develop/cordis-tutorial/01-first-plugin.md +1 -0
  174. package/kb/site/develop/cordis-tutorial/02-lifecycle-and-effects.md +1 -0
  175. package/kb/site/develop/cordis-tutorial/03-services.md +1 -0
  176. package/kb/site/develop/cordis-tutorial/04-events.md +1 -0
  177. package/kb/site/develop/cordis-tutorial/05-config.md +28 -0
  178. package/kb/site/develop/cordis-tutorial/06-composition-and-hmr.md +3 -2
  179. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +1 -0
  180. package/kb/site/develop/cordis-tutorial/index.md +1 -0
  181. package/kb/site/develop/framework/events.md +1 -0
  182. package/kb/site/develop/framework/index.md +2 -1
  183. package/kb/site/develop/framework/service.md +1 -0
  184. package/kb/site/develop/practice/dynamic-cordis.md +9 -8
  185. package/kb/site/develop/practice/index.md +1 -0
  186. package/kb/site/develop/practice/llm-adapter.md +2 -1
  187. package/kb/site/en/develop/basic/config.md +1 -0
  188. package/kb/site/en/develop/basic/index.md +1 -0
  189. package/kb/site/en/develop/basic/publish.md +9 -2
  190. package/kb/site/en/develop/basic/tool.md +1 -0
  191. package/kb/site/en/develop/cordis-tutorial/01-first-plugin.md +1 -0
  192. package/kb/site/en/develop/cordis-tutorial/02-lifecycle-and-effects.md +1 -0
  193. package/kb/site/en/develop/cordis-tutorial/03-services.md +1 -0
  194. package/kb/site/en/develop/cordis-tutorial/04-events.md +1 -0
  195. package/kb/site/en/develop/cordis-tutorial/05-config.md +28 -0
  196. package/kb/site/en/develop/cordis-tutorial/06-composition-and-hmr.md +3 -2
  197. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +1 -0
  198. package/kb/site/en/develop/cordis-tutorial/index.md +1 -0
  199. package/kb/site/en/develop/framework/events.md +1 -0
  200. package/kb/site/en/develop/framework/index.md +2 -1
  201. package/kb/site/en/develop/framework/service.md +1 -0
  202. package/kb/site/en/develop/practice/dynamic-cordis.md +9 -8
  203. package/kb/site/en/develop/practice/index.md +1 -0
  204. package/kb/site/en/develop/practice/llm-adapter.md +2 -1
  205. package/kb/site/en/guide/github-review.md +1 -0
  206. package/kb/site/en/guide/mcp-memory.md +1 -0
  207. package/kb/site/en/guide/network-proxy.md +2 -1
  208. package/kb/site/en/guide/providers-custom-form.png +0 -0
  209. package/kb/site/en/guide/providers-models-page.png +0 -0
  210. package/kb/site/en/guide/providers.md +97 -82
  211. package/kb/site/en/guide/public-deployments.md +36 -0
  212. package/kb/site/en/guide/python-sdk.md +42 -21
  213. package/kb/site/en/guide/quickstart.md +2 -0
  214. package/kb/site/en/guide/schedule.md +70 -11
  215. package/kb/site/en/reference/agent-lifecycle.md +1 -0
  216. package/kb/site/en/reference/api-gateway.md +13 -11
  217. package/kb/site/en/reference/capability-seams.md +177 -59
  218. package/kb/site/en/reference/config-catalog.md +1758 -821
  219. package/kb/site/en/reference/cookbook/adding-a-package.md +57 -3
  220. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +35 -64
  221. package/kb/site/en/reference/cookbook/adding-a-tool.md +4 -3
  222. package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +1 -0
  223. package/kb/site/en/reference/cookbook/extension-cookbook.md +6 -5
  224. package/kb/site/en/reference/cordis-api/context.md +1 -0
  225. package/kb/site/en/reference/cordis-api/events.md +1 -0
  226. package/kb/site/en/reference/cordis-api/fiber.md +4 -3
  227. package/kb/site/en/reference/cordis-api/inherited.md +16 -16
  228. package/kb/site/en/reference/cordis-api/registry.md +1 -0
  229. package/kb/site/en/reference/cordis-api/service.md +1 -0
  230. package/kb/site/en/reference/cordis-primer.md +1 -0
  231. package/kb/site/en/reference/index.md +18 -11
  232. package/kb/site/en/reference/persistence-catalog.md +7687 -54
  233. package/kb/site/en/reference/subsystems/approval.md +2 -1
  234. package/kb/site/en/reference/subsystems/client-modules.md +23 -15
  235. package/kb/site/en/reference/subsystems/client-resources.md +3 -1
  236. package/kb/site/en/reference/subsystems/commands.md +6 -1
  237. package/kb/site/en/reference/subsystems/compaction.md +50 -3
  238. package/kb/site/en/reference/subsystems/conversation.md +36 -6
  239. package/kb/site/en/reference/subsystems/core.md +97 -257
  240. package/kb/site/en/reference/subsystems/credentials.md +169 -5
  241. package/kb/site/en/reference/subsystems/filesystem.md +11 -0
  242. package/kb/site/en/reference/subsystems/goal.md +2 -1
  243. package/kb/site/en/reference/subsystems/index.md +16 -5
  244. package/kb/site/en/reference/subsystems/jobs.md +337 -127
  245. package/kb/site/en/reference/subsystems/llm-streaming.md +76 -36
  246. package/kb/site/en/reference/subsystems/lsp.md +1 -0
  247. package/kb/site/en/reference/subsystems/permission-presets.md +66 -29
  248. package/kb/site/en/reference/subsystems/persistence.md +4 -3
  249. package/kb/site/en/reference/subsystems/plan.md +2 -1
  250. package/kb/site/en/reference/subsystems/ptc-runtime.md +236 -0
  251. package/kb/site/en/reference/subsystems/sandbox.md +7 -5
  252. package/kb/site/en/reference/subsystems/schedule.md +392 -33
  253. package/kb/site/en/reference/subsystems/scope.md +2 -1
  254. package/kb/site/en/reference/subsystems/session-projection.md +22 -19
  255. package/kb/site/en/reference/subsystems/session-query.md +1 -0
  256. package/kb/site/en/reference/subsystems/session-reference.md +8 -6
  257. package/kb/site/en/reference/subsystems/session-telemetry.md +7 -4
  258. package/kb/site/en/reference/subsystems/session-title.md +6 -5
  259. package/kb/site/en/reference/subsystems/session.md +199 -81
  260. package/kb/site/en/reference/subsystems/settings.md +43 -292
  261. package/kb/site/en/reference/subsystems/shell.md +37 -28
  262. package/kb/site/en/reference/subsystems/sidebar-right.md +23 -12
  263. package/kb/site/en/reference/subsystems/skills.md +5 -6
  264. package/kb/site/en/reference/subsystems/slots.md +34 -13
  265. package/kb/site/en/reference/subsystems/spill.md +4 -3
  266. package/kb/site/en/reference/subsystems/storage.md +2 -2
  267. package/kb/site/en/reference/subsystems/subagent.md +50 -64
  268. package/kb/site/en/reference/subsystems/subprocess.md +17 -18
  269. package/kb/site/en/reference/subsystems/system-prompt.md +4 -1
  270. package/kb/site/en/reference/subsystems/terminal.md +1 -0
  271. package/kb/site/en/reference/subsystems/token-meter.md +1 -0
  272. package/kb/site/en/reference/subsystems/tools.md +40 -12
  273. package/kb/site/en/reference/subsystems/typert.md +153 -10
  274. package/kb/site/en/reference/subsystems/user-questions.md +131 -1
  275. package/kb/site/en/reference/subsystems/web-client.md +15 -9
  276. package/kb/site/en/reference/subsystems/web-server.md +74 -1
  277. package/kb/site/en/reference/subsystems/web.md +1 -0
  278. package/kb/site/en/reference/subsystems/workflow.md +10 -9
  279. package/kb/site/en/reference/subsystems/workspace.md +294 -34
  280. package/kb/site/en/reference/tool-catalog.md +782 -331
  281. package/kb/site/en/reference/tool-execution-pipeline.md +7 -3
  282. package/kb/site/guide/github-review.md +1 -0
  283. package/kb/site/guide/mcp-memory.md +1 -0
  284. package/kb/site/guide/network-proxy.md +2 -1
  285. package/kb/site/guide/providers-custom-form.zh.png +0 -0
  286. package/kb/site/guide/providers-models-page.zh.png +0 -0
  287. package/kb/site/guide/providers.md +109 -94
  288. package/kb/site/guide/public-deployments.md +36 -0
  289. package/kb/site/guide/python-sdk.md +42 -21
  290. package/kb/site/guide/quickstart.md +2 -0
  291. package/kb/site/guide/schedule.md +70 -11
  292. package/kb/site/reference/agent-lifecycle.md +1 -0
  293. package/kb/site/reference/api-gateway.md +13 -11
  294. package/kb/site/reference/capability-seams.md +177 -59
  295. package/kb/site/reference/config-catalog.md +1760 -822
  296. package/kb/site/reference/cookbook/adding-a-package.md +55 -3
  297. package/kb/site/reference/cookbook/adding-a-settings-card.md +35 -64
  298. package/kb/site/reference/cookbook/adding-a-tool.md +4 -3
  299. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +1 -0
  300. package/kb/site/reference/cookbook/extension-cookbook.md +6 -5
  301. package/kb/site/reference/cordis-api/context.md +1 -0
  302. package/kb/site/reference/cordis-api/events.md +1 -0
  303. package/kb/site/reference/cordis-api/fiber.md +4 -3
  304. package/kb/site/reference/cordis-api/inherited.md +16 -16
  305. package/kb/site/reference/cordis-api/registry.md +1 -0
  306. package/kb/site/reference/cordis-api/service.md +1 -0
  307. package/kb/site/reference/cordis-primer.md +1 -0
  308. package/kb/site/reference/index.md +18 -11
  309. package/kb/site/reference/persistence-catalog.md +7693 -60
  310. package/kb/site/reference/subsystems/approval.md +2 -1
  311. package/kb/site/reference/subsystems/client-modules.md +23 -15
  312. package/kb/site/reference/subsystems/client-resources.md +3 -1
  313. package/kb/site/reference/subsystems/commands.md +6 -1
  314. package/kb/site/reference/subsystems/compaction.md +50 -3
  315. package/kb/site/reference/subsystems/conversation.md +35 -5
  316. package/kb/site/reference/subsystems/core.md +97 -257
  317. package/kb/site/reference/subsystems/credentials.md +169 -5
  318. package/kb/site/reference/subsystems/filesystem.md +11 -0
  319. package/kb/site/reference/subsystems/goal.md +2 -1
  320. package/kb/site/reference/subsystems/index.md +16 -5
  321. package/kb/site/reference/subsystems/jobs.md +336 -126
  322. package/kb/site/reference/subsystems/llm-streaming.md +76 -36
  323. package/kb/site/reference/subsystems/lsp.md +1 -0
  324. package/kb/site/reference/subsystems/permission-presets.md +66 -29
  325. package/kb/site/reference/subsystems/persistence.md +4 -3
  326. package/kb/site/reference/subsystems/plan.md +2 -1
  327. package/kb/site/reference/subsystems/ptc-runtime.md +236 -0
  328. package/kb/site/reference/subsystems/sandbox.md +7 -5
  329. package/kb/site/reference/subsystems/schedule.md +392 -33
  330. package/kb/site/reference/subsystems/scope.md +2 -1
  331. package/kb/site/reference/subsystems/session-projection.md +22 -19
  332. package/kb/site/reference/subsystems/session-query.md +1 -0
  333. package/kb/site/reference/subsystems/session-reference.md +8 -6
  334. package/kb/site/reference/subsystems/session-telemetry.md +7 -4
  335. package/kb/site/reference/subsystems/session-title.md +6 -5
  336. package/kb/site/reference/subsystems/session.md +199 -81
  337. package/kb/site/reference/subsystems/settings.md +43 -292
  338. package/kb/site/reference/subsystems/shell.md +37 -28
  339. package/kb/site/reference/subsystems/sidebar-right.md +23 -12
  340. package/kb/site/reference/subsystems/skills.md +5 -6
  341. package/kb/site/reference/subsystems/slots.md +34 -13
  342. package/kb/site/reference/subsystems/spill.md +3 -2
  343. package/kb/site/reference/subsystems/storage.md +2 -2
  344. package/kb/site/reference/subsystems/subagent.md +49 -63
  345. package/kb/site/reference/subsystems/subprocess.md +17 -18
  346. package/kb/site/reference/subsystems/system-prompt.md +4 -1
  347. package/kb/site/reference/subsystems/terminal.md +1 -0
  348. package/kb/site/reference/subsystems/token-meter.md +1 -0
  349. package/kb/site/reference/subsystems/tools.md +40 -12
  350. package/kb/site/reference/subsystems/typert.md +153 -10
  351. package/kb/site/reference/subsystems/user-questions.md +132 -2
  352. package/kb/site/reference/subsystems/web-client.md +15 -9
  353. package/kb/site/reference/subsystems/web-server.md +74 -1
  354. package/kb/site/reference/subsystems/web.md +1 -0
  355. package/kb/site/reference/subsystems/workflow.md +10 -9
  356. package/kb/site/reference/subsystems/workspace.md +294 -34
  357. package/kb/site/reference/tool-catalog.md +784 -333
  358. package/kb/site/reference/tool-execution-pipeline.md +7 -3
  359. package/package.json +2 -2
  360. package/skills/dsh-plugin-dev-kb.md +5 -4
  361. package/kb/site/en/reference/subsystems/code-runtime.md +0 -198
  362. package/kb/site/en/reference/subsystems/invariants.md +0 -91
  363. package/kb/site/reference/subsystems/code-runtime.md +0 -198
  364. package/kb/site/reference/subsystems/invariants.md +0 -91
@@ -1,11 +1,12 @@
1
1
  ---
2
2
  editSource: "docs/subsystems/jobs.md"
3
+ rawMarkdownPath: "en/reference/subsystems/jobs.md"
3
4
  outline: [2,3]
4
5
  ---
5
6
 
6
- # Background Task Runtime
7
+ # Background Job Runtime
7
8
 
8
- Types shared by long-running producers, `ctx.jobs`, and job controls. The [runtime Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-20-generic-long-running-tool-runtime.md) owns the design; this page records the exact fields and variants from [`packages/jobs/jobs/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/types.ts).
9
+ Types shared by long-running producers, `ctx.jobs`, and job controls. The [seam consolidation Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-09-03-jobs-seam-consolidation.md) owns the current design and the [runtime reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/README.md) its origin; this page records the exact fields and variants from [`packages/jobs/jobs/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/types.ts) and the client-safe [`view.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/view.ts) leaf.
9
10
 
10
11
  ## Ids and status
11
12
 
@@ -22,45 +23,83 @@ interface JobKindMap {
22
23
  }
23
24
  ```
24
25
 
25
- `JobStatus` is `'running' | 'stopping' | 'completed' | 'killed' | 'failed'`; producer-specific facts belong in `JobSnapshot.detail`.
26
+ `JobStatus` is `'running' | 'stopping' | 'completed' | 'killed' | 'failed'`; producer-specific facts belong in `JobView.progress` while the job runs and in `JobView.detail` once it settled.
26
27
 
27
28
  ## Producer contract
28
29
 
29
- `JobStart` declares identity and a starter. The runtime finishes preflight before calling `run()` and commits without a later failable step. Producers own execution resources; the runtime owns identity, access, and lifecycle state.
30
+ A `JobSpec` declares identity, the owning session, optional pull `output` sources, and a starter. The runtime finishes preflight before calling `run()` with the job's `JobHandle` and commits without a later failable step. Producers own execution resources; the runtime owns identity, access, lifecycle state, and the output ring.
30
31
 
31
32
  ```ts type-equiv
32
33
  /**
33
34
  * Producer declaration passed to {@link JobRegistry.start}. The runtime
34
35
  * preflights access and cleanup before invoking {@link run}; the producer owns
35
- * execution resources while the runtime owns identity and lifecycle state.
36
+ * execution resources while the runtime owns identity, lifecycle state, and
37
+ * the output ring.
36
38
  */
37
- interface JobStart {
39
+ interface JobSpec {
38
40
  /** Producer kind — also the id prefix (`bash`, `subagent`, …). */
39
41
  kind: JobKind
40
42
  /** One-line model-facing label (the command; the delegation description). */
41
43
  label: string
44
+ /**
45
+ * Owning session. Access is fenced by it, and the owner's live Agent must be
46
+ * the one currently registered under that id: its disposal cancels and
47
+ * awaits the job. Omitting the owner creates an unowned job, open to any
48
+ * caller until service disposal.
49
+ */
50
+ owner?: SessionId
42
51
  /**
43
52
  * Optional UTF-8 byte cap for each complete model-facing completion notice or
44
- * output read, including controller status metadata.
53
+ * output read, including controller status metadata. Independent of ring
54
+ * retention: it bounds the consuming model surface, never observers.
45
55
  */
46
56
  outputLimitBytes?: number
47
57
  /**
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.
58
+ * Pull sources the registry pumps into the ring at its own cadence.
59
+ * Producers that narrate their own progress use {@link JobHandle.append}
60
+ * instead; a job may use both.
52
61
  */
53
- owner?: Agent
62
+ output?: readonly JobOutputSource[]
54
63
  /**
55
64
  * 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.
65
+ * once with the job's producer face; a throw leaves nothing registered (the
66
+ * spent ordinal is skipped), and the producer must clean up any partially
67
+ * started resources.
68
+ * @param job - the issued id plus the ring append and progress writers.
69
+ */
70
+ run(job: JobHandle): JobHooks
71
+ }
72
+ ```
73
+
74
+ ```ts type-equiv
75
+ /**
76
+ * Producer face of one registered job, handed to {@link JobSpec.run} and
77
+ * valid for the job's whole life. All methods are synchronous. Writes staged
78
+ * inside the starter call are retained and become visible with the
79
+ * registration commit; after settlement — the producer's own outcome, a kill,
80
+ * or a registry-forced teardown end — writes log and drop instead of
81
+ * throwing, so a producer's trailing flush cannot break its own teardown path.
82
+ */
83
+ interface JobHandle {
84
+ /** The registry-issued id (`<kind>-N`). */
85
+ readonly id: JobId
86
+ /**
87
+ * Append one chunk to the output ring. Offsets advance by the chunk's UTF-8
88
+ * byte length; an empty chunk is dropped without waking observers.
89
+ * @param text - the chunk text, exactly as produced.
90
+ * @param options - stream label and gap marker.
91
+ */
92
+ append(text: string, options?: JobAppendOptions): void
93
+ /**
94
+ * Replace the live progress line (`3/10`, the current phase). Settlement
95
+ * clears it; the terminal reason travels in {@link JobOutcome.detail}.
96
+ * @param line - the new progress line.
58
97
  */
59
- run(): JobHooks
98
+ updateProgress(line: string): void
60
99
  }
61
100
  ```
62
101
 
63
- `JobHooks.done` resolves after the producer releases its resources, not merely when work finishes. Optional `readOutput` distinguishes consuming stream jobs from final-output-only jobs.
102
+ `JobHooks.done` resolves after the producer releases its resources, not merely when work finishes. A job whose result is a value rather than a stream — a subagent's report, a workflow's rendered result — returns it as `JobOutcome.result`; the model's first read after settlement carries it once.
64
103
 
65
104
  ```ts type-equiv
66
105
  /** Hooks through which the runtime controls and observes producer work. */
@@ -77,12 +116,6 @@ interface JobHooks {
77
116
  * registry record without claiming that the work stopped.
78
117
  */
79
118
  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
119
  }
87
120
  ```
88
121
 
@@ -91,73 +124,215 @@ interface JobHooks {
91
124
  interface JobOutcome {
92
125
  /** How the job ended: finished (`completed`), cancelled (`killed`), or broke (`failed`). */
93
126
  status: 'completed' | 'killed' | 'failed'
94
- /** Kind-specific detail rendered into status lines ('exit code: 3', 'max-tokens'). */
127
+ /**
128
+ * Terminal reason rendered into status lines (`exit code: 3`, `max-tokens`).
129
+ * When the job settles `killed` after a {@link JobRegistry.kill} with a
130
+ * reason, the registry appends that reason.
131
+ */
95
132
  detail?: string
96
- /** Final output for jobs without `readOutput`; stream jobs leave it unset. */
97
- output?: string
133
+ /**
134
+ * Return value for jobs whose result is a value rather than a stream (a
135
+ * workflow's rendered result, a subagent's report). The output ring carries
136
+ * the stream; this is handed out once by the model's next {@link JobRegistry.read}.
137
+ */
138
+ result?: string
139
+ }
140
+ ```
141
+
142
+ A pull source hands the registry a non-consuming offset reader — the subprocess `readFrom` family. The registry pumps every source at its own cadence (`pumpPollMs` on `dsh-jobs-local`) and drains it once more before settlement closes the ring, so producers fold nothing into `done`.
143
+
144
+ ```ts type-equiv
145
+ /**
146
+ * A pull source the registry pumps into the job's output ring — the subprocess
147
+ * `readFrom` family. The registry owns the cadence and drains every source one
148
+ * last time before settlement closes the ring, so a producer folds nothing
149
+ * into its `done`.
150
+ */
151
+ interface JobOutputSource {
152
+ /** Stream label attached to every chunk this source yields. */
153
+ channel?: JobChannel
154
+ /**
155
+ * Read everything captured since `fromByte` without consuming it.
156
+ * @param fromByte - whole-stream offset to resume from (a prior read's `nextOffset`; 0 first).
157
+ * @returns the delta text, the next offset, the lossy flag, and the spill path the source currently keeps.
158
+ */
159
+ read(fromByte: number): JobSourceRead
160
+ }
161
+ ```
162
+
163
+ ```ts type-equiv
164
+ /** One incremental read from a {@link JobOutputSource}. */
165
+ interface JobSourceRead {
166
+ /** Text captured since the requested offset (the whole retained tail when lossy). */
167
+ text: string
168
+ /** Whole-stream offset to resume from on the next read. */
169
+ nextOffset: number
170
+ /** True when the requested offset slid out of the source's retained window. */
171
+ lossy: boolean
172
+ /**
173
+ * Host path of a file holding the complete stream, when the source
174
+ * currently keeps an intact one. Reported on every read, so the registry
175
+ * tracks it as source metadata: a later read without it withdraws the file.
176
+ */
177
+ spillPath?: string
178
+ }
179
+ ```
180
+
181
+ ## The output ring
182
+
183
+ Every job owns one bounded ring. Pull sources are pumped into it and `JobHandle.append` pushes land whole; the model consumes the ring through a registry-kept cursor (`JobRegistry.read`), any number of observers read it at absolute byte offsets (`JobRegistry.readAt`), and neither disturbs the other. `JobChannel` labels `stdout`, `stderr`, and `log`; `log` is producer narration that reaches observers only, never the model's consuming read. Settlement ends the stream and trims retention to the settled cap — the ring has no separate lifecycle. The spill file a pull source keeps is job metadata (`JobView.output.spillPaths`, refreshed by every pump read), not per-chunk metadata, so the model's dropped-output notice names it after the ring evicted the bytes and even after the gap chunk itself is gone. Browsers reach the roster and the ring through `job.list` and `job.follow`, the Remote streams of [`dsh-api-job-controller`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/job-controller/README.md), whose frames are listed under its Cordis API section below.
184
+
185
+ ```ts type-equiv
186
+ /** One chunk of a job's output ring: absolute offset, text, channel, and loss marker. */
187
+ interface JobChunk {
188
+ /** Absolute offset of the chunk's first byte; offsets never move once assigned. */
189
+ readonly at: number
190
+ /** Chunk text exactly as appended (possibly tail-trimmed by retention). */
191
+ readonly text: string
192
+ /** Stream label, when the producer supplied one. */
193
+ readonly channel?: JobChannel
194
+ /** Bytes immediately before this chunk were lost, at the producer or to retention. */
195
+ readonly gapBefore?: true
196
+ }
197
+ ```
198
+
199
+ ```ts type-equiv
200
+ /** Result of one non-consuming {@link JobRegistry.readAt}. */
201
+ interface JobOutputRead {
202
+ /** Retained chunks overlapping `[from, total)`, in offset order. */
203
+ chunks: readonly JobChunk[]
204
+ /**
205
+ * Offset to resume from — the ring's current `total`. Always a chunk
206
+ * boundary: appends land whole and trimming only advances chunk starts, and
207
+ * consumers concatenate `chunks` under that assumption, so a provider
208
+ * serving partial chunks would silently duplicate text.
209
+ */
210
+ next: number
211
+ /** True when `from` fell below the oldest retained byte, so bytes are missing before `chunks`. */
212
+ lossy: boolean
98
213
  }
99
214
  ```
100
215
 
101
216
  ## Consumer views
102
217
 
103
- Snapshots are fresh read-only projections. `ownerSession` carries the shared `SessionId` used for authorization; completion listeners separately receive the exact owner object used for lifecycle cleanup. `reported` suppresses a completion notice after another reporter has delivered or committed to deliver the terminal state, including the teardown cancel that drains an owner or the service.
218
+ `JobView` is the one projection every reader consumes: the model tools, the browser roster, and the observation stream. `owner` carries the session id that fences access; the registry resolves the live `Agent` behind it for lifecycle cleanup and never hands the object out. `progress` is the producer's live line and is cleared at settlement; `detail` is the terminal reason, with a recorded kill reason merged in.
104
219
 
105
220
  ```ts type-equiv
106
221
  /**
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.
222
+ * Read-only projection of one job — a fresh object per call, never live
223
+ * registry state. The model tools, the browser roster, and the observation
224
+ * stream all consume this one shape.
109
225
  */
110
- interface JobSnapshot {
226
+ interface JobView {
111
227
  /** 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
228
+ readonly id: JobId
119
229
  /**
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}.
230
+ * The producer kind the job was registered with: a Host-registered
231
+ * `JobKind`, carried as an open string because a browser bundle or a Remote
232
+ * codec sees only the `JobKindMap` merges its own program compiles.
123
233
  */
124
- ownerSession?: SessionId
234
+ readonly kind: string
235
+ /** The producer-supplied one-line label. */
236
+ readonly label: string
237
+ /** Owning session; absent for an unowned job, which every caller can see. */
238
+ readonly owner?: SessionId
239
+ /** Producer-owned cap for complete model-facing notices and reads, in UTF-8 bytes. */
240
+ readonly outputLimitBytes?: number
125
241
  /** Current lifecycle state. */
126
- status: JobStatus
127
- /** Kind-specific status detail, present once the producer supplied one (usually terminal). */
128
- detail?: string
242
+ readonly status: JobStatus
243
+ /** The producer's live progress line (`3/10`, the current phase); cleared at settlement. */
244
+ readonly progress?: string
245
+ /** Terminal reason (`exit code: 3`); a recorded kill reason is merged in. */
246
+ readonly detail?: string
129
247
  /** Epoch ms when the job was registered. */
130
- startedAt: number
131
- /** Epoch ms when the job settled; absent while `running`/`stopping`. */
132
- finishedAt?: number
248
+ readonly startedAt: number
249
+ /** Epoch ms when the job settled; absent while live. */
250
+ readonly finishedAt?: number
133
251
  /**
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.
252
+ * The output ring's absolute coordinates and the complete-stream files
253
+ * behind it. `total` is the offset the next chunk starts at (0 while
254
+ * nothing was written); `earliest` is the oldest retained byte, greater
255
+ * than zero exactly when retention dropped the head. `spillPaths` lists the
256
+ * spill files the job's pull sources currently keep, in source order and
257
+ * deduplicated, and is absent while no source keeps one: it outlives any
258
+ * chunk, so a reader below `earliest` can still name where the bytes went.
139
259
  */
140
- reported: boolean
260
+ readonly output: { readonly total: number; readonly earliest: number; readonly spillPaths?: readonly string[] }
141
261
  }
142
262
  ```
143
263
 
264
+ `JobRegistry.list`, `get`, `read`, `readAt`, `kill`, and `wait` each accept the caller’s `SessionId`; omitting it permits only unowned jobs, while a session may also access its own jobs.
265
+
144
266
  ```ts type-equiv
145
- /** Output and post-read state returned by {@link JobRegistry.read}. */
267
+ /** Output and post-read state returned by the consuming {@link JobRegistry.read}. */
146
268
  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
269
+ /** Ring chunks appended since the model cursor, in offset order; every channel included. */
270
+ chunks: readonly JobChunk[]
271
+ /** True when the cursor fell below the oldest retained byte, so bytes are missing before `chunks`. */
272
+ lossy: boolean
273
+ /** The producer's {@link JobOutcome.result}, handed out by the first read after settlement only. */
274
+ result?: string
153
275
  /** The job's state at read time. */
154
- snapshot: JobSnapshot
276
+ job: JobView
155
277
  }
156
278
  ```
157
279
 
280
+ ## Events
281
+
282
+ The registry announces every commit through one filtered stream. Lifecycle events carry the projection after the commit they announce; `settled` names its cause so a completion reporter can skip a teardown; `output` carries only the id and the new total, so observers read from their own cursor and the registry never pushes payloads.
283
+
284
+ ```ts type-equiv
285
+ /**
286
+ * One lifecycle or output event. Lifecycle events carry the job's projection
287
+ * after the commit they announce; `output` carries only the id and the new
288
+ * total, so an observer schedules a {@link JobRegistry.readAt} from its own
289
+ * cursor and the registry never pushes payloads.
290
+ */
291
+ type JobEvent =
292
+ | {
293
+ /** Registration commit, progress line change, stopping transition, or removal from the visible set. */
294
+ readonly type: 'registered' | 'progress' | 'stopping' | 'removed'
295
+ readonly job: JobView
296
+ }
297
+ | {
298
+ readonly type: 'settled'
299
+ readonly job: JobView
300
+ readonly cause: JobSettleCause
301
+ /**
302
+ * Whether this settlement released a live {@link JobRegistry.wait}. That
303
+ * waiter's caller receives the terminal projection as its own result, so
304
+ * a completion reporter treats an awaited settlement as already delivered
305
+ * and reports only the unawaited ones. A wait that timed out or was
306
+ * aborted before the settlement does not count.
307
+ */
308
+ readonly awaited: boolean
309
+ }
310
+ | {
311
+ readonly type: 'output'
312
+ readonly id: JobId
313
+ /** Owning session, absent for an unowned job. */
314
+ readonly owner?: SessionId
315
+ /** The ring's total after the append (or at settlement, which ends the stream). */
316
+ readonly total: number
317
+ }
318
+ ```
319
+
320
+ ```ts type-equiv
321
+ /**
322
+ * Who a subscription hears about. `{ owner }` delivers that session's jobs
323
+ * plus every unowned job (the set that session can see). `{ owners: 'scope' }`
324
+ * delivers the owners composed under the subscribing context — one registry
325
+ * serves every composition in the process, and a mount under one preset must
326
+ * not hear another preset's agents. `{ owners: 'all' }` delivers everything.
327
+ */
328
+ type JobEventFilter =
329
+ | { readonly owner: SessionId }
330
+ | { readonly owners: 'all' | 'scope' }
331
+ ```
332
+
158
333
  ## Service behavior
159
334
 
160
- The abstract [`JobRegistry`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/index.ts) Service Definition specifies atomic `start`, caller-scoped `get` and `list`, `read`, `kill`, bounded `wait`, failure-isolated `onJobDone` and `onJobsChanged` listeners, and `attachController`; [`LocalJobRegistry`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs-local/src/index.ts) is the process-local Service Provider. Authorization compares owner sessions; owner cleanup and admission use the exact registered `Agent` instance. The local provider's positive-safe-integer `maxConcurrentJobsPerOwner` config defaults to `10` and counts `running` plus `stopping` records per exact owner, with one shared bucket for unowned jobs; terminal producer settlement releases capacity. See [`dsh-jobs`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/README.md) for the Service Definition contract, [`dsh-jobs-local`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs-local/README.md) for the registry lifecycle and admission policy, and [`dsh-tool-jobs`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/tool-jobs/README.md) for the model-facing Consumer.
335
+ The abstract [`JobRegistry`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/index.ts) Service Definition specifies atomic `start`, caller-scoped `list`, `get`, consuming `read`, non-consuming `readAt`, `kill`, and bounded `wait`, the filtered `events` stream, and `attachController`; [`LocalJobRegistry`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs-local/src/index.ts) is the process-local Service Provider. Authorization compares owner sessions; owner cleanup and admission use the live `Agent` registered under the owner session when the job starts. The local provider's positive-safe-integer `maxConcurrentJobsPerOwner` config defaults to `10` and counts `running` plus `stopping` records per exact owner, with one shared bucket for unowned jobs; terminal producer settlement releases capacity; `retainBytes` (default 262144) and `settledRetainBytes` (default 16384) bound each ring's live and settled retention, and `pumpPollMs` (default 150) is the pull cadence. See [`dsh-jobs`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/README.md) for the Service Definition contract, [`dsh-jobs-local`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs-local/README.md) for the registry lifecycle and admission policy, and [`dsh-tool-jobs`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/tool-jobs/README.md) for the model-facing Consumer.
161
336
 
162
337
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
163
338
 
@@ -167,18 +342,66 @@ The abstract [`JobRegistry`](https://github.com/deepseek-ai/deepseek-harness/blo
167
342
 
168
343
  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).
169
344
 
345
+ <a id="ctxjobcontroller--jobcontroller"></a>
346
+
347
+ ### `ctx.jobController` — `JobController`
348
+
349
+ Host service backing the generated `ctx.remote.job` namespace.
350
+
351
+ ```ts cordis-catalog
352
+ /**
353
+ * Stream the jobs one session can see — its own plus every unowned job —
354
+ * as whole-set frames: one on open, then one after each coalesced burst of
355
+ * lifecycle commits. The stream has no natural end; the carrier closes it.
356
+ * @param request - the session whose visible set to mirror.
357
+ * @param signal - cancellation owned by the Remote stream carrier.
358
+ * @returns the roster frames.
359
+ */
360
+ @Remote({ mode: 'stream' }) list(request: JobListRequest, signal: AbortSignal): AsyncIterable<JobListFrame>
361
+
362
+ /**
363
+ * Stream one job's retained output from an absolute byte offset, then its
364
+ * terminal projection once settled and drained. Non-consuming: the
365
+ * model-facing cursor and notice state never observe these reads. The
366
+ * request's session is the fenced read's caller; the registry rejects a
367
+ * job the session cannot see and an unknown job.
368
+ * @param request - target job, owning session, and optional resume offset.
369
+ * @param signal - cancellation owned by the Remote stream carrier.
370
+ * @returns anchor, coalesced output frames, and the terminal status.
371
+ */
372
+ @Remote({ mode: 'stream' }) follow(request: JobFollowRequest, signal: AbortSignal): AsyncIterable<JobFollowFrame>
373
+
374
+ /**
375
+ * Kill one background job on a human's behalf. The request's session is
376
+ * the fenced read's caller, so the job must be one that session can see:
377
+ * the registry's owner fence is the only access rule, and a child session's
378
+ * own jobs are killable from its list like any other. The kill records
379
+ * `cancelled by the user` as its reason; it is not one the model requested,
380
+ * so the owning agent still receives the completion notice, and a shell
381
+ * tool waiting on that job reads the reason in its own result.
382
+ * @param request - Session whose job list carries the job, and the job id.
383
+ * @returns the registry's admission of the kill request.
384
+ */
385
+ @Remote('kill') kill(request: JobKillRequest): JobKillValue
386
+ ```
387
+
388
+ Source: [`packages/api/job-controller/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/job-controller/src/index.ts)
389
+
170
390
  <a id="ctxjobs--jobregistry-abstract-seam"></a>
171
391
 
172
392
  ### `ctx.jobs` — `JobRegistry` (abstract seam)
173
393
 
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).
394
+ Abstract background job registry. Subclass, implement the abstract members, 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
395
 
176
396
  Implementations must honor these semantics:
177
397
 
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.
398
+ - 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. Such settlements announce `cause: 'teardown'`, because a job whose owner is being destroyed has no reader left.
179
399
  - 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.
400
+ - Settlement is first-wins: one terminal record, released waiters, then one round of contained event delivery, even against a late producer outcome. The `settled` event follows every released waiter and reports whether it released one (`awaited`), so a completion reporter can skip settlements a waiting caller already collected.
401
+ - A settled record stays listed until its owner's disposal, service disposal, or an explicit remove by a caller that collected the terminal state itself and never handed the id out.
402
+ - 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 event delivery under `{ owners: 'scope' }` — 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.
403
+ - Every job owns one output ring. Pull sources named by the spec are pumped by the registry and drained once more before settlement; pushed appends land whole. The model's consuming cursor and observers' absolute offsets read the same bytes and never disturb each other.
404
+ - Ring retention is bounded. Appends past the live cap drop the oldest retained bytes; a reader below the retained window gets a lossy read, never an error. Settlement trims retention to the settled cap and ends the stream; the ring has no separate lifecycle.
182
405
 
183
406
  ```ts cordis-catalog
184
407
  /**
@@ -186,96 +409,83 @@ Implementations must honor these semantics:
186
409
  * admission before starting and atomically registering work. Any preflight
187
410
  * rejection leaves no job id or execution resource. A throwing starter
188
411
  * 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.
412
+ * @param spec - job identity, owner, output sources, and synchronous starter.
191
413
  * @returns the registry-issued `<kind>-N` id.
192
414
  */
193
- abstract start(spec: JobStart): JobId
415
+ abstract start(spec: JobSpec): JobId
194
416
 
195
417
  /**
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.
418
+ * List caller-owned and unowned jobs in registration order.
419
+ * @param caller - reading session; omission sees only unowned jobs.
420
+ * @returns fresh projections.
200
421
  */
201
- abstract list(caller?: Agent): JobSnapshot[]
422
+ abstract list(caller?: SessionId): JobView[]
202
423
 
203
424
  /**
204
- * Return a non-consuming snapshot without changing its read cursor or notice
205
- * state. Throws for an unknown or foreign job.
425
+ * Project one job without changing its cursor. Throws for an unknown or
426
+ * foreign job.
206
427
  * @param id - job to look up.
207
- * @param caller - reading agent checked against the owner.
208
- * @returns a fresh snapshot.
428
+ * @param caller - reading session checked against the owner.
429
+ * @returns a fresh projection.
209
430
  */
210
- abstract get(id: JobId, caller?: Agent): JobSnapshot
431
+ abstract get(id: JobId, caller?: SessionId): JobView
211
432
 
212
433
  /**
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.
434
+ * Consume the ring from the model cursor and advance it to the current
435
+ * total. After settlement the first read also carries the producer's
436
+ * result. Throws for an unknown or foreign job.
216
437
  * @param id - job to read.
217
- * @param caller - reading agent checked against the owner.
218
- * @returns output text and the post-read snapshot.
438
+ * @param caller - reading session checked against the owner.
439
+ * @returns the chunks since the cursor, the lossy flag, the result once, and the post-read projection.
219
440
  */
220
- abstract read(id: JobId, caller?: Agent): JobRead
441
+ abstract read(id: JobId, caller?: SessionId): JobRead
221
442
 
222
443
  /**
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.
444
+ * Read retained ring output without moving the model cursor. Resume with
445
+ * a previous read's `next`; an offset inside a retained chunk returns the
446
+ * whole chunk (its `at` may precede `from`). Throws for a negative or
447
+ * non-integer offset, or an unknown or foreign job.
448
+ * @param id - job to read.
449
+ * @param from - absolute byte offset to read from (0 for the retained head).
450
+ * @param caller - reading session checked against the owner.
451
+ * @returns retained chunks overlapping `[from, total)`, the resume offset, and the lossy flag.
452
+ */
453
+ abstract readAt(id: JobId, from: number, caller?: SessionId): JobOutputRead
454
+
455
+ /**
456
+ * Request cancellation, then mark the job stopping. A producer throw
457
+ * propagates without changing job state. A supplied reason is merged into
458
+ * terminal `detail` when the job settles `killed`. Throws for an unknown
459
+ * or foreign job.
226
460
  * @param id - job to cancel.
227
- * @param caller - killing agent checked against the owner.
228
- * @param reason - logged reason forwarded to the producer.
461
+ * @param caller - killing session checked against the owner.
462
+ * @param reason - cancellation reason forwarded verbatim to the producer.
229
463
  * @returns `requested` for live work, otherwise `already-finished`.
230
464
  */
231
- abstract kill(id: JobId, caller?: Agent, reason?: string): 'requested' | 'already-finished'
465
+ abstract kill(id: JobId, caller?: SessionId, reason?: string): 'requested' | 'already-finished'
232
466
 
233
467
  /**
234
468
  * Wait for settlement or timeout without cancelling the job. Caller abort
235
469
  * 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.
470
+ * projection wins. Rejects for an invalid timeout or an unknown or foreign
471
+ * job.
238
472
  * @param id - job to wait for.
239
473
  * @param timeoutMs - positive finite wait bound in milliseconds.
240
- * @param caller - waiting agent checked against the owner.
474
+ * @param caller - waiting session checked against the owner.
241
475
  * @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.
476
+ * @returns projection at settlement or timeout.
253
477
  */
254
- abstract onJobDone(listener: JobDoneListener): () => void
478
+ abstract wait(id: JobId, timeoutMs: number, caller?: SessionId, signal?: AbortSignal): Promise<JobView>
255
479
 
256
480
  /**
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.
481
+ * Drop one settled job's record from the visible set and announce
482
+ * `removed`. For a caller that collected the terminal state through its own
483
+ * {@link wait} and never handed the id to the model, such as a shell tool's
484
+ * foreground call. Throws for a job that is still live, unknown, or foreign.
485
+ * @param id - settled job to drop.
486
+ * @param caller - removing session checked against the owner.
277
487
  */
278
- abstract onJobsChanged(listener: JobsChangedListener): () => void
488
+ abstract remove(id: JobId, caller?: SessionId): void
279
489
 
280
490
  /**
281
491
  * Attach an effect-scoped controller that can read and stop jobs. It serves the
@@ -287,7 +497,7 @@ abstract onJobsChanged(listener: JobsChangedListener): () => void
287
497
  abstract attachController(name: string): () => void
288
498
  ```
289
499
 
290
- Types: [Agent](./core.md)
500
+ Types: [SessionId](./core.md)
291
501
 
292
502
  Source: [`packages/jobs/jobs/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/index.ts)
293
503
  <!-- END GENERATED cordis-surface -->