dsh-plugin-dev-kb 1.1.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 (370) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.en.md +14 -8
  3. package/README.md +15 -9
  4. package/docs/banner.svg +25 -0
  5. package/kb/INDEX.md +23 -19
  6. package/kb/README.md +8 -6
  7. package/kb/extra/AGENTS.md +11 -10
  8. package/kb/extra/cookbook/adding-a-remote-api.md +2 -2
  9. package/kb/extra/cookbook/adding-a-remote-api.zh.md +2 -2
  10. package/kb/extra/cookbook/adding-a-session-format-version.md +151 -0
  11. package/kb/extra/cookbook/adding-a-session-format-version.zh.md +151 -0
  12. package/kb/extra/cookbook/adding-a-vendored-package.md +1 -1
  13. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +1 -1
  14. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.md +1 -1
  15. package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +1 -1
  16. package/kb/extra/cookbook/reviewing-persistence-type-changes.md +120 -0
  17. package/kb/extra/cookbook/reviewing-persistence-type-changes.zh.md +120 -0
  18. package/kb/extra/deepseek-llm-api-wire-extensions.md +19 -20
  19. package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +18 -19
  20. package/kb/extra/development.md +37 -10
  21. package/kb/extra/development.zh.md +37 -10
  22. package/kb/extra/event-producer-consumer.md +90 -67
  23. package/kb/extra/event-producer-consumer.zh.md +91 -68
  24. package/kb/extra/glossary.md +1 -1
  25. package/kb/extra/glossary.zh.md +1 -1
  26. package/kb/extra/i18n/README.md +16 -7
  27. package/kb/extra/i18n/README.zh.md +17 -8
  28. package/kb/extra/i18n/terminology.md +4 -4
  29. package/kb/extra/i18n/translation-prompt.md +3 -3
  30. package/kb/extra/module-graph.md +621 -335
  31. package/kb/extra/module-graph.zh.md +621 -335
  32. package/kb/extra/persistence-changes/2026-09-11-initial.md +280 -0
  33. package/kb/extra/persistence-changes/2026-09-11-initial.zh.md +280 -0
  34. package/kb/extra/persistence-changes/2026-09-12-auto-review-error-metadata.md +52 -0
  35. package/kb/extra/persistence-changes/2026-09-12-auto-review-error-metadata.zh.md +52 -0
  36. package/kb/extra/persistence-changes/2026-09-14-image-offload.md +96 -0
  37. package/kb/extra/persistence-changes/2026-09-14-image-offload.zh.md +96 -0
  38. package/kb/extra/persistence-changes/2026-09-14-workspace-changes-event.md +48 -0
  39. package/kb/extra/persistence-changes/2026-09-14-workspace-changes-event.zh.md +48 -0
  40. package/kb/extra/persistence-changes/2026-09-16-session-format-v4.md +120 -0
  41. package/kb/extra/persistence-changes/2026-09-16-session-format-v4.zh.md +120 -0
  42. package/kb/extra/persistence-changes/2026-09-18-schedule-optional-title.md +48 -0
  43. package/kb/extra/persistence-changes/2026-09-18-schedule-optional-title.zh.md +48 -0
  44. package/kb/extra/persistence-changes/2026-09-20-unknown-child-catalog.md +48 -0
  45. package/kb/extra/persistence-changes/2026-09-20-unknown-child-catalog.zh.md +48 -0
  46. package/kb/extra/persistence-changes/2026-09-21-user-question-reply.md +60 -0
  47. package/kb/extra/persistence-changes/2026-09-21-user-question-reply.zh.md +60 -0
  48. package/kb/extra/persistence-changes/README.md +88 -0
  49. package/kb/extra/persistence-changes/README.zh.md +88 -0
  50. package/kb/extra/persistence-changes/historical-formats/README.md +75 -0
  51. package/kb/extra/persistence-changes/historical-formats/README.zh.md +75 -0
  52. package/kb/extra/persistence-changes/historical-formats/v0.md +5105 -0
  53. package/kb/extra/persistence-changes/historical-formats/v0.zh.md +5105 -0
  54. package/kb/extra/persistence-changes/historical-formats/v1.md +5107 -0
  55. package/kb/extra/persistence-changes/historical-formats/v1.zh.md +5107 -0
  56. package/kb/extra/persistence-changes/historical-formats/v2.md +5362 -0
  57. package/kb/extra/persistence-changes/historical-formats/v2.zh.md +5362 -0
  58. package/kb/extra/persistence-changes/historical-formats/v3.md +5634 -0
  59. package/kb/extra/persistence-changes/historical-formats/v3.zh.md +5634 -0
  60. package/kb/extra/persistence-changes/releases/README.md +103 -0
  61. package/kb/extra/persistence-changes/releases/README.zh.md +103 -0
  62. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.1.md +201 -0
  63. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.1.zh.md +201 -0
  64. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.2.md +261 -0
  65. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.2.zh.md +261 -0
  66. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.3.md +126 -0
  67. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.3.zh.md +126 -0
  68. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.4.md +75 -0
  69. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.4.zh.md +75 -0
  70. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.5.md +75 -0
  71. package/kb/extra/persistence-changes/releases/dsh-v0.0.1-rc.5.zh.md +75 -0
  72. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.1.md +75 -0
  73. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.1.zh.md +75 -0
  74. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.2.md +75 -0
  75. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.2.zh.md +75 -0
  76. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.3.md +75 -0
  77. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.3.zh.md +75 -0
  78. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.5.md +75 -0
  79. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.5.zh.md +75 -0
  80. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.6.md +75 -0
  81. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.6.zh.md +75 -0
  82. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.7.md +82 -0
  83. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.7.zh.md +82 -0
  84. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.8.md +110 -0
  85. package/kb/extra/persistence-changes/releases/dsh-v0.1.0-rc.8.zh.md +110 -0
  86. package/kb/extra/persistence-changes/releases/dsh-v0.1.1-rc.1.md +82 -0
  87. package/kb/extra/persistence-changes/releases/dsh-v0.1.1-rc.1.zh.md +82 -0
  88. package/kb/extra/persistence-changes/releases/dsh-v0.1.1-rc.2.md +119 -0
  89. package/kb/extra/persistence-changes/releases/dsh-v0.1.1-rc.2.zh.md +119 -0
  90. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.1.md +295 -0
  91. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.1.zh.md +295 -0
  92. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.2.md +286 -0
  93. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.2.zh.md +286 -0
  94. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.3.md +75 -0
  95. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.3.zh.md +75 -0
  96. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.4.md +95 -0
  97. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.4.zh.md +95 -0
  98. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.5.md +75 -0
  99. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-alpha.5.zh.md +75 -0
  100. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-rc.1.md +75 -0
  101. package/kb/extra/persistence-changes/releases/dsh-v0.1.2-rc.1.zh.md +75 -0
  102. package/kb/extra/persistence-changes/releases/dsh-v0.1.3-alpha.1.md +154 -0
  103. package/kb/extra/persistence-changes/releases/dsh-v0.1.3-alpha.1.zh.md +154 -0
  104. package/kb/extra/persistence-changes/releases/dsh-v0.1.3-alpha.2.md +86 -0
  105. package/kb/extra/persistence-changes/releases/dsh-v0.1.3-alpha.2.zh.md +86 -0
  106. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-alpha.1.md +139 -0
  107. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-alpha.1.zh.md +139 -0
  108. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-alpha.2.md +95 -0
  109. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-alpha.2.zh.md +95 -0
  110. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-rc.1.md +75 -0
  111. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-rc.1.zh.md +75 -0
  112. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-rc.2.md +75 -0
  113. package/kb/extra/persistence-changes/releases/dsh-v0.1.5-rc.2.zh.md +75 -0
  114. package/kb/extra/rescope.md +2 -2
  115. package/kb/extra/rescope.zh.md +2 -2
  116. package/kb/extra/session-format-status.md +63 -0
  117. package/kb/extra/session-format-status.zh.md +63 -0
  118. package/kb/extra/subsystems/agent-team.md +52 -28
  119. package/kb/extra/subsystems/agent-team.zh.md +52 -28
  120. package/kb/extra/subsystems/attachment.md +19 -9
  121. package/kb/extra/subsystems/attachment.zh.md +19 -9
  122. package/kb/extra/subsystems/boot.md +323 -0
  123. package/kb/extra/subsystems/boot.zh.md +323 -0
  124. package/kb/extra/subsystems/browser-use.md +67 -0
  125. package/kb/extra/subsystems/browser-use.zh.md +67 -0
  126. package/kb/extra/subsystems/claude-code-mods.md +146 -0
  127. package/kb/extra/subsystems/claude-code-mods.zh.md +146 -0
  128. package/kb/extra/subsystems/computer-use.md +56 -0
  129. package/kb/extra/subsystems/computer-use.zh.md +56 -0
  130. package/kb/extra/subsystems/deliverables.md +178 -0
  131. package/kb/extra/subsystems/deliverables.zh.md +178 -0
  132. package/kb/extra/subsystems/extensions.md +6 -4
  133. package/kb/extra/subsystems/extensions.zh.md +6 -4
  134. package/kb/extra/subsystems/feedback.md +165 -31
  135. package/kb/extra/subsystems/feedback.zh.md +165 -31
  136. package/kb/extra/subsystems/mcp.md +139 -0
  137. package/kb/extra/subsystems/mcp.zh.md +139 -0
  138. package/kb/extra/subsystems/office-to-pdf.md +87 -0
  139. package/kb/extra/subsystems/office-to-pdf.zh.md +87 -0
  140. package/kb/extra/subsystems/otel.md +44 -0
  141. package/kb/extra/subsystems/otel.zh.md +44 -0
  142. package/kb/extra/subsystems/product-telemetry.md +79 -0
  143. package/kb/extra/subsystems/product-telemetry.zh.md +79 -0
  144. package/kb/extra/subsystems/ssh.md +135 -0
  145. package/kb/extra/subsystems/ssh.zh.md +135 -0
  146. package/kb/extra/subsystems/todo.md +3 -3
  147. package/kb/extra/subsystems/todo.zh.md +3 -3
  148. package/kb/extra/subsystems/voice-input.md +164 -0
  149. package/kb/extra/subsystems/voice-input.zh.md +164 -0
  150. package/kb/extra/subsystems/webhook.md +3 -3
  151. package/kb/extra/subsystems/webhook.zh.md +1 -1
  152. package/kb/extra/testing.md +5 -4
  153. package/kb/extra/testing.zh.md +5 -4
  154. package/kb/extra/ui-radius.md +115 -0
  155. package/kb/extra/ui-radius.zh.md +115 -0
  156. package/kb/extra/upgrade-guide/v0.1.7-rc.2/schedule-optional-bundle/guide.md +22 -0
  157. package/kb/extra/upgrade-guide/v0.1.7-rc.2/schedule-optional-bundle/guide.zh.md +22 -0
  158. package/kb/extra/upgrade-guide/v0.1.7-rc.2/transcript-view-legacy-normal/guide.md +25 -0
  159. package/kb/extra/upgrade-guide/v0.1.7-rc.2/transcript-view-legacy-normal/guide.zh.md +25 -0
  160. package/kb/extra/upgrade-guide/v0.2.0-rc.2/account-sign-in-errors/guide.md +18 -0
  161. package/kb/extra/upgrade-guide/v0.2.0-rc.2/account-sign-in-errors/guide.zh.md +18 -0
  162. package/kb/extra/upgrade-guide/v0.2.0-rc.2/remove-runtime-invariants/guide.md +23 -0
  163. package/kb/extra/upgrade-guide/v0.2.0-rc.2/remove-runtime-invariants/guide.zh.md +23 -0
  164. package/kb/extra/upgrade-guide/v0.2.0-rc.2/schedule-bundle-retired/guide.md +22 -0
  165. package/kb/extra/upgrade-guide/v0.2.0-rc.2/schedule-bundle-retired/guide.zh.md +22 -0
  166. package/kb/extra/upgrade-guide/v0.2.0-rc.2/subpath-plugin-display-manifest/guide.md +27 -0
  167. package/kb/extra/upgrade-guide/v0.2.0-rc.2/subpath-plugin-display-manifest/guide.zh.md +27 -0
  168. package/kb/extra/web-styling.md +12 -2
  169. package/kb/extra/web-styling.zh.md +12 -2
  170. package/kb/meta/search-index.json +1019 -251
  171. package/kb/meta/site-pages.txt +187 -183
  172. package/kb/meta/source.json +8 -8
  173. package/kb/meta/topics.md +11 -7
  174. package/kb/site/develop/basic/config.md +1 -0
  175. package/kb/site/develop/basic/index.md +1 -0
  176. package/kb/site/develop/basic/publish.md +10 -3
  177. package/kb/site/develop/basic/tool.md +1 -0
  178. package/kb/site/develop/cordis-tutorial/01-first-plugin.md +1 -0
  179. package/kb/site/develop/cordis-tutorial/02-lifecycle-and-effects.md +1 -0
  180. package/kb/site/develop/cordis-tutorial/03-services.md +1 -0
  181. package/kb/site/develop/cordis-tutorial/04-events.md +1 -0
  182. package/kb/site/develop/cordis-tutorial/05-config.md +28 -0
  183. package/kb/site/develop/cordis-tutorial/06-composition-and-hmr.md +3 -2
  184. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +1 -0
  185. package/kb/site/develop/cordis-tutorial/index.md +1 -0
  186. package/kb/site/develop/framework/events.md +1 -0
  187. package/kb/site/develop/framework/index.md +2 -1
  188. package/kb/site/develop/framework/service.md +1 -0
  189. package/kb/site/develop/practice/dynamic-cordis.md +9 -8
  190. package/kb/site/develop/practice/index.md +1 -0
  191. package/kb/site/develop/practice/llm-adapter.md +2 -1
  192. package/kb/site/en/develop/basic/config.md +1 -0
  193. package/kb/site/en/develop/basic/index.md +1 -0
  194. package/kb/site/en/develop/basic/publish.md +10 -3
  195. package/kb/site/en/develop/basic/tool.md +1 -0
  196. package/kb/site/en/develop/cordis-tutorial/01-first-plugin.md +1 -0
  197. package/kb/site/en/develop/cordis-tutorial/02-lifecycle-and-effects.md +1 -0
  198. package/kb/site/en/develop/cordis-tutorial/03-services.md +1 -0
  199. package/kb/site/en/develop/cordis-tutorial/04-events.md +1 -0
  200. package/kb/site/en/develop/cordis-tutorial/05-config.md +28 -0
  201. package/kb/site/en/develop/cordis-tutorial/06-composition-and-hmr.md +3 -2
  202. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +1 -0
  203. package/kb/site/en/develop/cordis-tutorial/index.md +1 -0
  204. package/kb/site/en/develop/framework/events.md +1 -0
  205. package/kb/site/en/develop/framework/index.md +2 -1
  206. package/kb/site/en/develop/framework/service.md +1 -0
  207. package/kb/site/en/develop/practice/dynamic-cordis.md +9 -8
  208. package/kb/site/en/develop/practice/index.md +1 -0
  209. package/kb/site/en/develop/practice/llm-adapter.md +2 -1
  210. package/kb/site/en/guide/github-review.md +1 -0
  211. package/kb/site/en/guide/mcp-memory.md +1 -0
  212. package/kb/site/en/guide/network-proxy.md +2 -1
  213. package/kb/site/en/guide/providers-custom-form.png +0 -0
  214. package/kb/site/en/guide/providers-models-page.png +0 -0
  215. package/kb/site/en/guide/providers.md +98 -83
  216. package/kb/site/en/guide/public-deployments.md +36 -0
  217. package/kb/site/en/guide/python-sdk.md +60 -23
  218. package/kb/site/en/guide/quickstart.md +2 -0
  219. package/kb/site/en/guide/schedule.md +70 -11
  220. package/kb/site/en/reference/agent-lifecycle.md +13 -5
  221. package/kb/site/en/reference/api-gateway.md +13 -11
  222. package/kb/site/en/reference/capability-seams.md +187 -62
  223. package/kb/site/en/reference/config-catalog.md +1887 -819
  224. package/kb/site/en/reference/cookbook/adding-a-package.md +57 -3
  225. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +35 -64
  226. package/kb/site/en/reference/cookbook/adding-a-tool.md +5 -4
  227. package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +1 -0
  228. package/kb/site/en/reference/cookbook/extension-cookbook.md +7 -6
  229. package/kb/site/en/reference/cordis-api/context.md +1 -0
  230. package/kb/site/en/reference/cordis-api/events.md +1 -0
  231. package/kb/site/en/reference/cordis-api/fiber.md +4 -3
  232. package/kb/site/en/reference/cordis-api/inherited.md +16 -16
  233. package/kb/site/en/reference/cordis-api/registry.md +1 -0
  234. package/kb/site/en/reference/cordis-api/service.md +1 -0
  235. package/kb/site/en/reference/cordis-primer.md +1 -0
  236. package/kb/site/en/reference/index.md +32 -15
  237. package/kb/site/en/reference/persistence-catalog.md +7787 -81
  238. package/kb/site/en/reference/subsystems/approval.md +3 -2
  239. package/kb/site/en/reference/subsystems/client-modules.md +30 -13
  240. package/kb/site/en/reference/subsystems/client-resources.md +96 -0
  241. package/kb/site/en/reference/subsystems/commands.md +6 -1
  242. package/kb/site/en/reference/subsystems/compaction.md +50 -3
  243. package/kb/site/en/reference/subsystems/conversation.md +36 -6
  244. package/kb/site/en/reference/subsystems/core.md +174 -271
  245. package/kb/site/en/reference/subsystems/credentials.md +169 -5
  246. package/kb/site/en/reference/subsystems/filesystem.md +26 -0
  247. package/kb/site/en/reference/subsystems/goal.md +39 -2
  248. package/kb/site/en/reference/subsystems/index.md +18 -5
  249. package/kb/site/en/reference/subsystems/jobs.md +337 -127
  250. package/kb/site/en/reference/subsystems/llm-streaming.md +93 -43
  251. package/kb/site/en/reference/subsystems/lsp.md +2 -1
  252. package/kb/site/en/reference/subsystems/permission-presets.md +66 -29
  253. package/kb/site/en/reference/subsystems/persistence.md +40 -18
  254. package/kb/site/en/reference/subsystems/plan.md +2 -1
  255. package/kb/site/en/reference/subsystems/ptc-runtime.md +236 -0
  256. package/kb/site/en/reference/subsystems/sandbox.md +7 -5
  257. package/kb/site/en/reference/subsystems/schedule.md +392 -33
  258. package/kb/site/en/reference/subsystems/scope.md +2 -1
  259. package/kb/site/en/reference/subsystems/session-projection.md +22 -19
  260. package/kb/site/en/reference/subsystems/session-query.md +1 -0
  261. package/kb/site/en/reference/subsystems/session-reference.md +12 -6
  262. package/kb/site/en/reference/subsystems/session-telemetry.md +27 -8
  263. package/kb/site/en/reference/subsystems/session-title.md +6 -5
  264. package/kb/site/en/reference/subsystems/session.md +258 -118
  265. package/kb/site/en/reference/subsystems/settings.md +43 -292
  266. package/kb/site/en/reference/subsystems/shell.md +44 -32
  267. package/kb/site/en/reference/subsystems/sidebar-right.md +162 -0
  268. package/kb/site/en/reference/subsystems/skills.md +5 -6
  269. package/kb/site/en/reference/subsystems/slots.md +68 -39
  270. package/kb/site/en/reference/subsystems/spill.md +15 -7
  271. package/kb/site/en/reference/subsystems/storage.md +2 -2
  272. package/kb/site/en/reference/subsystems/subagent.md +65 -72
  273. package/kb/site/en/reference/subsystems/subprocess.md +42 -44
  274. package/kb/site/en/reference/subsystems/system-prompt.md +7 -2
  275. package/kb/site/en/reference/subsystems/terminal.md +1 -0
  276. package/kb/site/en/reference/subsystems/token-meter.md +3 -1
  277. package/kb/site/en/reference/subsystems/tools.md +44 -16
  278. package/kb/site/en/reference/subsystems/typert.md +153 -10
  279. package/kb/site/en/reference/subsystems/user-questions.md +131 -1
  280. package/kb/site/en/reference/subsystems/web-client.md +15 -9
  281. package/kb/site/en/reference/subsystems/web-server.md +74 -1
  282. package/kb/site/en/reference/subsystems/web.md +1 -0
  283. package/kb/site/en/reference/subsystems/workflow.md +10 -9
  284. package/kb/site/en/reference/subsystems/workspace.md +343 -4
  285. package/kb/site/en/reference/tool-catalog.md +806 -311
  286. package/kb/site/en/reference/tool-execution-pipeline.md +9 -5
  287. package/kb/site/guide/github-review.md +1 -0
  288. package/kb/site/guide/mcp-memory.md +1 -0
  289. package/kb/site/guide/network-proxy.md +2 -1
  290. package/kb/site/guide/providers-custom-form.zh.png +0 -0
  291. package/kb/site/guide/providers-models-page.zh.png +0 -0
  292. package/kb/site/guide/providers.md +109 -94
  293. package/kb/site/guide/public-deployments.md +36 -0
  294. package/kb/site/guide/python-sdk.md +60 -23
  295. package/kb/site/guide/quickstart.md +2 -0
  296. package/kb/site/guide/schedule.md +70 -11
  297. package/kb/site/reference/agent-lifecycle.md +13 -5
  298. package/kb/site/reference/api-gateway.md +13 -11
  299. package/kb/site/reference/capability-seams.md +187 -62
  300. package/kb/site/reference/config-catalog.md +1889 -820
  301. package/kb/site/reference/cookbook/adding-a-package.md +55 -3
  302. package/kb/site/reference/cookbook/adding-a-settings-card.md +35 -64
  303. package/kb/site/reference/cookbook/adding-a-tool.md +5 -4
  304. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +1 -0
  305. package/kb/site/reference/cookbook/extension-cookbook.md +7 -6
  306. package/kb/site/reference/cordis-api/context.md +1 -0
  307. package/kb/site/reference/cordis-api/events.md +1 -0
  308. package/kb/site/reference/cordis-api/fiber.md +4 -3
  309. package/kb/site/reference/cordis-api/inherited.md +16 -16
  310. package/kb/site/reference/cordis-api/registry.md +1 -0
  311. package/kb/site/reference/cordis-api/service.md +1 -0
  312. package/kb/site/reference/cordis-primer.md +1 -0
  313. package/kb/site/reference/index.md +32 -15
  314. package/kb/site/reference/persistence-catalog.md +7791 -85
  315. package/kb/site/reference/subsystems/approval.md +3 -2
  316. package/kb/site/reference/subsystems/client-modules.md +30 -13
  317. package/kb/site/reference/subsystems/client-resources.md +96 -0
  318. package/kb/site/reference/subsystems/commands.md +6 -1
  319. package/kb/site/reference/subsystems/compaction.md +50 -3
  320. package/kb/site/reference/subsystems/conversation.md +35 -5
  321. package/kb/site/reference/subsystems/core.md +174 -271
  322. package/kb/site/reference/subsystems/credentials.md +169 -5
  323. package/kb/site/reference/subsystems/filesystem.md +26 -0
  324. package/kb/site/reference/subsystems/goal.md +39 -2
  325. package/kb/site/reference/subsystems/index.md +28 -15
  326. package/kb/site/reference/subsystems/jobs.md +336 -126
  327. package/kb/site/reference/subsystems/llm-streaming.md +93 -43
  328. package/kb/site/reference/subsystems/lsp.md +2 -1
  329. package/kb/site/reference/subsystems/permission-presets.md +66 -29
  330. package/kb/site/reference/subsystems/persistence.md +40 -18
  331. package/kb/site/reference/subsystems/plan.md +2 -1
  332. package/kb/site/reference/subsystems/ptc-runtime.md +236 -0
  333. package/kb/site/reference/subsystems/sandbox.md +7 -5
  334. package/kb/site/reference/subsystems/schedule.md +392 -33
  335. package/kb/site/reference/subsystems/scope.md +2 -1
  336. package/kb/site/reference/subsystems/session-projection.md +22 -19
  337. package/kb/site/reference/subsystems/session-query.md +1 -0
  338. package/kb/site/reference/subsystems/session-reference.md +12 -6
  339. package/kb/site/reference/subsystems/session-telemetry.md +27 -8
  340. package/kb/site/reference/subsystems/session-title.md +6 -5
  341. package/kb/site/reference/subsystems/session.md +258 -118
  342. package/kb/site/reference/subsystems/settings.md +43 -292
  343. package/kb/site/reference/subsystems/shell.md +44 -32
  344. package/kb/site/reference/subsystems/sidebar-right.md +162 -0
  345. package/kb/site/reference/subsystems/skills.md +5 -6
  346. package/kb/site/reference/subsystems/slots.md +68 -39
  347. package/kb/site/reference/subsystems/spill.md +15 -7
  348. package/kb/site/reference/subsystems/storage.md +2 -2
  349. package/kb/site/reference/subsystems/subagent.md +64 -71
  350. package/kb/site/reference/subsystems/subprocess.md +42 -44
  351. package/kb/site/reference/subsystems/system-prompt.md +7 -2
  352. package/kb/site/reference/subsystems/terminal.md +1 -0
  353. package/kb/site/reference/subsystems/token-meter.md +3 -1
  354. package/kb/site/reference/subsystems/tools.md +44 -16
  355. package/kb/site/reference/subsystems/typert.md +153 -10
  356. package/kb/site/reference/subsystems/user-questions.md +132 -2
  357. package/kb/site/reference/subsystems/web-client.md +15 -9
  358. package/kb/site/reference/subsystems/web-server.md +74 -1
  359. package/kb/site/reference/subsystems/web.md +1 -0
  360. package/kb/site/reference/subsystems/workflow.md +10 -9
  361. package/kb/site/reference/subsystems/workspace.md +343 -4
  362. package/kb/site/reference/tool-catalog.md +810 -315
  363. package/kb/site/reference/tool-execution-pipeline.md +9 -5
  364. package/lib/index.js +25 -44
  365. package/package.json +3 -2
  366. package/skills/dsh-plugin-dev-kb.md +6 -5
  367. package/kb/site/en/reference/subsystems/code-runtime.md +0 -198
  368. package/kb/site/en/reference/subsystems/invariants.md +0 -91
  369. package/kb/site/reference/subsystems/code-runtime.md +0 -198
  370. package/kb/site/reference/subsystems/invariants.md +0 -91
@@ -0,0 +1,162 @@
1
+ ---
2
+ editSource: "docs/subsystems/sidebar-right.md"
3
+ rawMarkdownPath: "en/reference/subsystems/sidebar-right.md"
4
+ outline: [2,3]
5
+ ---
6
+
7
+ # Right Sidebar
8
+
9
+ The right Sidebar is the Web Client's per-Session docking surface: a column of panes and tabs beside the conversation in which addressed content — a workspace file, a directory tree, the product's own pages — opens, splits, floats, and closes. [`dsh-client-ui-sidebar-right`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md) owns the surface, the tab-type registry, and the navigation service; [`dsh-client-ui-dockkit`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-dockkit/README.md) is its internal layout engine; [`dsh-client-resources`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/resources/README.md) turns addresses into live values for any component; [`dsh-api-workspace-files`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-files/README.md) provides both the Host workspace service and the Client `file` resource provider.
10
+
11
+ This page is the reference for the subsystem's contracts: addresses, tab-type registration, the navigation service, the extension slots and their owner props, the resource model, the Workspace Files service, the shipped types, and what is deliberately not built. How the layout engine, the frame, and the surface fit together is in the [Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-09-04-right-sidebar-docking-infrastructure.md); slot mechanics are in the [Slots reference](./slots.md).
12
+
13
+ ## Position and ownership
14
+
15
+ One docking surface exists per Session, held in a session-scoped slot store and drawn by `rightbar.session`. The root-scoped `rightbar` controller retains separate seats for the selected Session and background Sessions with initialized `keepMounted` bodies; only the foreground Conversation is visible. Reload restores saved layouts ([state](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#state)). The surface's every change is one recorded history entry computed by the kit's pure planners; a docked pane never stays empty, and an empty root pane receives the default page selected from registered guide entries.
16
+
17
+ A tab type is two registrations that share the definition's `id`: a static definition in `ctx.sidebarRightTabs` saying which addresses its `kind` opens, and a keyed slot registration supplying its body. The framework injects `useTabInfo()` for live Sidebar, pane and tab information; each type keeps its own state in its slot store. Packages import each other's declarations only as types.
18
+
19
+ | Package | Role |
20
+ |---|---|
21
+ | [`client/ui-sidebar-right`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md) | The panel and rail seats, the layout store, `ctx.sidebarRightTabs`, `ctx.sidebarRight`, the Tab domain, the guide type |
22
+ | [`client/ui-dockkit`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-dockkit/README.md) | Pure layout engine and React surface; an internal dependency of `ui-sidebar-right`, not a stable interface |
23
+ | [`client/resources`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/resources/README.md) | `ctx.resources`, `useResource`, the protocol → value roster `ResourceProtocolMap` |
24
+ | [`api/workspace-files`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-files/README.md) | Host `ctx.workspaceFiles`, the `workspaceFiles` Remote namespace, and the Client `file` resource provider |
25
+ | [`util/workspace-path`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/util/workspace-path/README.md) | The file address grammar: `fileAddressFor`, `parseFileAddress` |
26
+ | [`client/ui-sidebar-documentpreview`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-documentpreview/README.md), [`client/ui-sidebar-files`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-files/README.md), [`client/ui-sidebar-browser`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-browser/README.md) | The shipped `text`, `files`, and `browser` types |
27
+
28
+ ## Addresses
29
+
30
+ Every tab is opened by an address string, and the address is the tab's content identity. Two families exist.
31
+
32
+ A **resource address** is a `dsh-resource://<type>/…` URL. The host names the resource protocol — the key of `ResourceProtocolMap` — and everything after it is the protocol's own path; one scheme serves every protocol, so adding a protocol adds a host, never a scheme. The `file` protocol's path opens with its scope: `session/<sessionId>` followed by the path relative to that session's workspace root (`dsh-resource://file/session/abc/src/notes.txt`), or `absolute` followed by the absolute path with its leading `/` dropped (`dsh-resource://file/absolute/home/ys/notes.txt`, `dsh-resource://file/absolute/C:/x/y.txt` on Windows). Every id and path segment is component-encoded, with `:` kept literal for drive letters. `fileAddressFor(sessionId, cwd, path)` builds one — a relative path or an absolute path inside the workspace becomes `session`-relative, any other absolute path becomes `absolute` — and `parseFileAddress(address)` reads it back or returns `undefined` ([grammar](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/util/workspace-path/README.md)).
33
+
34
+ A **page address** is what the Sidebar records for a tab opened by kind rather than by resource: `sidebar://<kind>`, written by the Sidebar itself when `openTab(kind)` runs. Callers never build one — the guide and the file tree are opened as `openTab('guide')` and `openTab('files')` — and no other navigation address exists ([not built](#not-built)).
35
+
36
+ Tab identity is the pair `(kind, address)`: the registry's claim uses the address verbatim as the record's `contentId`, so opening the same address through the same type finds the existing tab, and the same address through two types is two tabs.
37
+
38
+ ## Tab-type registration
39
+
40
+ `ctx.sidebarRightTabs.register(definition)` registers one implementation of a type for the caller's lifetime and returns the disposer; the caller holds it inside its own `ctx.effect`, so an implementation lives exactly as long as the plugin that contributed it, and a second registration of the same `id` throws ([extension seats](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#extension-seats)). The definition is static: no runtime hook, nothing per tab or per session.
41
+
42
+ | Field | Meaning |
43
+ |---|---|
44
+ | `id` | The implementation's identity, unique across every registration; a package name is the natural value (`@deepseek-ai/dsh-client-ui-sidebar-files`). It is the key the body and title register under. |
45
+ | `kind` | The type's discriminator: what its tabs are, and what `openTab` names. Not unique — an extension may take over a builtin's kind. The shipped kinds are `guide`, `text`, `files`. |
46
+ | `patterns` | Optional resource-address globs the type recognizes; a page type opened by kind omits them. A pattern containing `:` matches the whole address (`dsh-resource://file/**`); one without matches the URL's path at any depth (`*.md`), and an address that is not a URL matches no such pattern. Matching is case-insensitive and does not hide dotfiles; the syntax is picomatch's POSIX dialect. |
47
+ | `priority` | One of three literal bands: `extension` (the default and the highest: a type from outside the product outranks every shipped viewer), `builtin` (types shipped with the product), `fallback` (plain-content viewers anything more specific should beat). |
48
+ | `canOpen(address)` | Optional synchronous veto of a glob match; it runs on every routing decision. |
49
+ | `title(address)` | The chip's text, captured into the layout record when the tab opens and never rewritten. |
50
+ | `keepMounted` | Optional lazy retention of visited bodies across hiding, Session switches and docking; the owning View holds the Session reference. |
51
+ | `guide` | Optional entry boxes for the guide page: `{ order, title(), description?(), icon? }`. Picking a box opens the contributing type as a page; omit to stay off the page. |
52
+
53
+ Routing is a ranked claim. `candidates(address)` ranks the types whose patterns match and whose `canOpen` does not veto: by band, then by the length of the longest matched pattern, then by registration order. `claim(address, kind?)` picks the first candidate, or the named `kind` outright — its globs are skipped, its `canOpen` still applies — and returns `{ kind, contentId: address, title }`. An address no type claims throws: it is a wiring mistake, not a user error.
54
+
55
+ One `kind` may carry one `builtin` and one `extension` registration at the same time. The extension is the one in force for claims, `get(kind)`, `openTab(kind)`, and the guide page, and the seat finds a tab's body and title under the definition in force's `id`, so no slot priority is involved; when the extension unregisters, the builtin resumes. Every other collision on a kind, and every duplicate `id`, throws.
56
+
57
+ ```ts ignore-check
58
+ import type { Context } from '@deepseek-ai/cordis'
59
+ import type {} from '@deepseek-ai/dsh-client-ui-sidebar-right/client'
60
+
61
+ export const inject = ['sidebarRightTabs', 'slots']
62
+
63
+ export function apply(ctx: Context): void {
64
+ ctx.effect(() => ctx.sidebarRightTabs.register({
65
+ id: '@acme/dsh-client-ui-image',
66
+ kind: 'image',
67
+ patterns: ['*.png', '*.jpg', '*.gif', '*.svg'],
68
+ canOpen: address => address.startsWith('dsh-resource://file/'),
69
+ title: address => address.slice(address.lastIndexOf('/') + 1),
70
+ }), 'image type')
71
+ ctx.effect(() => ctx.slots.inject('sidebar.right.pane.tab', () => ctx.slots.register(
72
+ { name: 'sidebar.right.pane.tab', key: '@acme/dsh-client-ui-image' },
73
+ ImageBody,
74
+ )), 'image body')
75
+ }
76
+ ```
77
+
78
+ ## Navigation: `ctx.sidebarRight`
79
+
80
+ Two opens are the navigation controller, and every way into the column calls one of them: `openResource(address, options?)` for a `dsh-resource://` address — the conversation's file links, a tool row's line reference, a file tree's rows — and `openTab(kind, options?)` for a page — the strip's add control, a guide entry box, or an HTTP(S) link in Assistant Markdown. Both run four steps as one history entry — claim (the registry ranks the resource's types, or the named `kind`'s implementation in force answers); focus a tab already showing the same `(kind, address)`; otherwise seat a new tab; expand the column — and then record the navigation in the Tab domain ([service](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#ctxsidebarright)). Content the user cannot see is not opened, so a collapsed column expands in the same step. `openResource` throws for an address outside `dsh-resource://` or one no type claims; `openTab` throws for a kind nothing registered: both are wiring mistakes, not user errors.
81
+
82
+ | Option | Meaning |
83
+ |---|---|
84
+ | `paneId` | Land a new tab in this pane; default is the active docked pane (the first docked pane while a floating pane is active). |
85
+ | `replaceTab` | Take this tab's pane and strip slot, closing it in the same step; a floating tab lends no place, so the new tab lands as if unplaced. |
86
+ | `revealIfOpened` | Default `true`: a tab already showing the same `(kind, address)` is focused and handed `params`. `false` opens another tab regardless. |
87
+ | `preferNewPane` | Prefer a new docked pane under the normal pane budget and room rule; fall back to the target pane when it cannot split. Ignored with `replaceTab`. |
88
+ | `kind` (`openResource` only) | Name the opening type instead of ranking claims; its implementation in force opens the address, and its `canOpen` still applies. |
89
+ | `params` | Navigation parameters for the body, delivered as `navigation.params`. `openResource` types them by resource type through the merge-extensible `SidebarRightResourceParamsMap` (the text preview declares `{ line?: number }`); `openTab<K>` types them by kind through `SidebarRightTabParamsMap`, `undefined` for a kind that declares none; a body reads `SidebarRightNavigationParams`, the union of both. Values are JSON-shaped by convention and not validated at run time. |
90
+
91
+ Placement is the caller's option, never a type's property. The conversation calls `openResource(fileAddressFor(sessionId, cwd, path))` and, from a `read` tool row, adds `{ params: { line } }` from the call's 1-based `offset`; a guide entry box calls `tab.actions.openTab(entry.kind, { replaceTab: true })`; a file-tree row calls `tab.actions.openResource(address)`; the strip's add control calls `openTab('guide', { paneId, revealIfOpened: false })`.
92
+
93
+ `close(tabId)` closes a tab; `active()` returns the active pane's active tab; `isExpanded()` and `toggleExpanded()` read and flip the column, the flip recorded in the sequence. Reads answer for the no-Session case with `undefined` or `false`; writes need a mounted Session surface and throw without one rather than write into a surface nobody draws.
94
+
95
+ `focus(tabId)` makes a tab its pane's active tab; `split(paneId?)` splits the active docked pane, or the named one, and returns the new pane's id — or `undefined`, recording nothing, when the pane budget or the column's width forbids a split; `float(tabId, rect?)` lifts a tab into a floating pane; `dock(paneId)` returns a floating pane to the docked area. All four run the store's existing actions and record one history entry each; a target that does not exist or is already in the requested state is a no-op, and like `open` they throw without a mounted Session surface. `TabId`, `PaneId`, `TabRecord`, and `FloatRect` are re-exported from the package's `/client` entry so a caller needs no dockkit import.
96
+
97
+ `focusedTarget(element?)` captures the visible page under live DOM focus, including an embedding iframe; outside or stale sidebar markup yields no target. `commandTarget(element?)` also permits the mounted Session's active dock pane for an open initiated outside the sidebar. A `SidebarRightTarget` captures Session, pane, host, tab occurrence, and navigation revision. `isTargetCurrent(target)` checks that identity before execution, so reopening a record or navigating it invalidates a captured action; it never retargets to another page. See the [controller methods](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/src/client/service.ts) for close and placement outcomes.
98
+
99
+ ## Slots and owner props
100
+
101
+ The Sidebar declares four extension slots; its document tab declares the additional keyed document body below ([hierarchy](./slots.md)).
102
+
103
+ | Slot | Cardinality | Purpose |
104
+ |---|---|---|
105
+ | `sidebar.right.pane.tab` | keyed by the definition's `id`, Session scope | One tab's body. The seat dispatches a tab to the `id` of its kind's implementation in force, so the registrant receives every tab of its kind, docked or floating. A kind whose implementation registered no body renders the owner's "nothing can view this" notice. |
106
+ | `sidebar.right.pane.tab.title` | keyed by the definition's `id`, Session scope | The chip's title, with the same owner share as the body. Optional: without an entry the chip shows the `title(address)` text captured at open time; a type with a live title reads its own store here. |
107
+ | `sidebar.right.tab.guide` | chain, Session scope | Replaces the guide tab's contents without replacing the tab; the first non-declining entry takes the body, otherwise the shipped guide renders. |
108
+ | `sidebar.right.tab.menu.item` | list, Session scope | Content-level actions appended after the kit's own layout actions. An item that acts must call the owner's `dismiss()`. |
109
+ | `sidebar.right.tab.document` | keyed by the document implementation's `id`, Session scope | The selected file renderer inside the document tab; the parent owns shared loading and toolbar controls. |
110
+
111
+ A body, title and guide replacement receive the framework-injected `useTabInfo()`. It returns `{ sidebar, panel, tab }`: `sidebar` holds `expanded` and `fullscreen`, `panel.id` names the containing pane, and `tab` contains its record fields plus `visible`, `navigation`, `signal`, and `actions`. All tabs require a foreground Session. Docked bodies also require expansion and selection; docked titles require expansion; foreground floats survive collapse. `signal` aborts when the record disappears or the plugin unloads, not on hiding or Session switching. `tab.actions` provides `openResource`, `openTab`, and `close`, bound to the tab's own Session. Open placement defaults to its current pane; `revealIfOpened` defaults to `true`, and `replaceTab: true` replaces this record in the same history entry. Menu entries retain plain `tab` and `dismiss` owner parameters.
112
+
113
+ `navigation.revision` increments on every navigation to the tab whether or not `params` changed, so a body can act on "navigated again" alone; it is `1` for a tab opened by address and `0` for a record nobody opened by address — a seeded guide, or a tab restored by undo. The Tab domain holds one occurrence per open record: a record that appears is pinned in the resource model, so switching tabs unmounts a body without dropping its content; a record that vanishes is aborted and dropped; a record restored by undo is a new occurrence ([Tab domain](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#the-tab-domain)).
114
+
115
+ `tab.actions.bindCommands(commands)` contributes `SidebarRightTabCommands`, currently an optional `refresh` callback, for the mounted body. Omitted operations are unavailable; the returned disposer releases that registration without removing a newer body's commands. The tab lifetime also releases them. `tab.refreshShortcut` supplies the effective refresh catalog entry for page controls; it is optional when no entry is available. These fields are declared in the [slot owner types](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/src/client/contract/slots.ts).
116
+
117
+ ## Document renderers
118
+
119
+ The `text` tab is the shared Document Preview owner. Its [root registration](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-documentpreview/src/client/index.ts) declares `sidebar.right.tab.document` and provides `ctx.documentPreviews`. A renderer registers `DocumentPreviewDefinition` metadata in its own effect, then waits through `ctx.slots.inject('sidebar.right.tab.document', ...)` and registers its component with `key: definition.id` and its locale namespace. A renderer registers its own body and can reuse shared presentation through its child slots. Changing the renderer does not change the tab or resource address; the [extension decision](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-09-08-document-preview-operations.md) separates preview policy from resource ownership.
120
+
121
+ The [registry](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-documentpreview/src/client/document/registry.ts) records unique `id`, `extensions`, localized `title()`, `loading`, optional `priority`, and optional `wrap`. Case-insensitive suffix matching ranks `extension` (the default) before `builtin`, then longer suffixes before shorter ones, then registration order. Unlike tab-kind replacement, the registry keeps all implementations available; the toolbar lists matching alternatives and remembers the selection per tab. Unknown extensions use plain text. Suffixes declared in `binaryExtensions` suppress the plain-text alternative, as described in the [package README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-documentpreview/README.md#what-it-registers). `loading` is `text-pages`, `bytes-complete`, or `renderer`; `wrap` advertises support for the shared source-wrap control.
122
+
123
+ [`DocumentPreviewProps`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-documentpreview/src/client/document/contract.ts) derives from `PropsRuntime<'sidebar.right.tab.document'>`. The owner supplies the original `resourceAddress`, `content`, current `wrap`, and `addResource` / `setResources` dependency callbacks: text content is `{ kind: 'text', text, pages: [{ offset, text, lines }], eof }`, with cumulative `text`; complete bytes are `{ kind: 'bytes', data }`, with `Uint8Array<ArrayBuffer>` data. These transient buffers are borrowed read-only and must not enter durable layout or Session JSON. PDF copies the bytes before Worker transfer, preserving the owner's buffer. The child receives the same framework-bound `useTabInfo` and the global metadata-only `useResource`. The parent reads text through `remote.workspaceFiles.read` and bytes through `remote.workspaceFiles.readBytes`, and owns page appends, per-tab refresh, and loading status. HTML passes `baseFile` to the same byte reader; Host code resolves paths. Markdown and code retain one incremental renderer across appends and settle at EOF; HTML and PDF receive complete bytes.
124
+
125
+ Preview records its loaded version and the version observed when a read starts. Automatic refresh defaults to enabled; initial member metadata establishes a baseline, and later changes reload the tab. Refresh rereads only that tab, without changing shared metadata or another tab's content. Reads are non-transactional; versions are opaque equality tokens, not ordered timestamps ([resource observation and Preview RPC](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-09-08-document-preview-operations.md)).
126
+
127
+ A renderer that owns loading receives `{ kind: 'renderer', revision, loaded, failed, reload }` instead of file bytes. The body invokes its injected face, cancels on revision changes and unmount, and reports its displayed source version through `loaded(version)`. A failed load calls `failed()` so a later file change can retry. The parent ignores stale reports and retains the shared reload and source-change controls. Office uses this mode to request [Host-rendered PDFs](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/office-to-pdf.md); its face writes converted bytes, font metadata, and failures to its own store, while its body renders a nested PDF view. `OfficeFontAction` renders the missing-font warning before reload through `sidebar.right.tab.document.action`. The [package README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-documentpreview/README.md#what-it-registers) defines the loading lifecycle.
128
+
129
+ ## Resource model
130
+
131
+ The model is documented in [Client Resources](./client-resources.md); this section states what the Sidebar relies on. A resource is one address, and a resource address is a `dsh-resource://<type>/…` URL whose lower-cased host is the protocol key. The protocol's owning client package registers one provider with `ctx.resources.register(provider)` for its own lifetime; a second provider for the same protocol throws ([provide a protocol](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/resources/README.md#provide-a-protocol)). A provider is `{ protocol, open(address, { signal }) }`: `open` yields `RemoteResult` frames — the current state first, one frame per later change — and stops when `signal` aborts; a failure is an `{ ok: false, error }` frame, never a throw, and a throw inside the stream is a programming error the model does not catch.
132
+
133
+ `useResource<P>(address)` is a global standard prop on every slot component, whatever its scope. It returns `{ status, value, failure }`: `none` when the address's protocol has no provider or the address is not a resource address (`sidebar://guide` names no resource), `loading` until the first frame, `live` with the latest `ok` value, `failed` with the latest frame's failure beside the last value. ([read a resource](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/resources/README.md#read-a-resource)).
134
+
135
+ A resource stays open while it has a holder — a subscribed `useResource` or a `ctx.resources.pin(address, signal)`; the first holder opens the provider's stream, later holders share it and read the latest value at once, and the last release aborts the stream and discards the value. Streams carry metadata, not content: the `file` value is `{ absolutePath, version, bytes? }`, and a consumer reads file text itself, by page, through the Workspace Files service ([lifecycle](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/resources/README.md#lifecycle)).
136
+
137
+ ## Workspace Files
138
+
139
+ The Host `ctx.workspaceFiles` service and generated `workspaceFiles` Remote namespace read files allowed by the Session filesystem backend: `stat(path)` returns `{ absolutePath, version, bytes? }`; `read(path, { offset?, limit? })` returns one page of lines (`offset` 1-based, `limit` capped by the configured page size) as `{ …stat, offset, text, eof }`; `readBytes(path, { range?, baseFile? })` returns a complete file under `maxFileBytes` or a byte window under `maxBytes` as `{ …stat, offset, data, eof }` with native `Uint8Array` data. Its optional `range` uses 0-based `offset` and a byte `length`; `baseFile` resolves the relative target from another file’s directory. `list(path)` remains inside the workspace root and returns a directory's direct children (`name`, `type: 'file' | 'directory' | 'other'`, `size?`) cut to the configured cap with `truncated` set. `changes(path)` watches one target; the Host determines its type and confines directories to the workspace. It yields `{ kind: 'ready' }` once subscribed, then `{ kind: 'change', change }` frames whose payload is `{ absolutePath, version }` or `{ absolutePath, absent: true }` ([README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-files/README.md#use-this-package)). File reads reject final symlinks and enforce transfer caps; `read` additionally requires UTF-8 text. Failures use `workspace-file/*` codes ([failures](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-files/README.md)).
140
+
141
+ [`dsh-api-workspace-files`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-files/README.md) registers the `file` provider, with `ResourceProtocolMap.file` directly naming `WorkspaceFileStat`. A Session address carries the authorizing Session and a relative or absolute path, passed unchanged to the Host for resolution. The provider waits for Host `ready` before stat and filters changes by `stat.absolutePath`. Bare `absolute` addresses have no authorizing Session and fail with `workspace-file/unknown-workspace`, without borrowing current or Tab Session. Any UI, including Global components, shares the observation for the same complete address. Preview's Remote callbacks use the Session in that address; `remote.workspaceFiles.readBytes` returns native bytes through Connection's binary RPC transport.
142
+
143
+ ## Shipped types
144
+
145
+ - **`guide`** — `builtin`, opened as `openTab('guide')`. A muted compass sits above one capsule per contributed `guide` entry, in `order`; short lists show registered descriptions, and every missing icon uses the shipped placeholder. Picking a capsule opens the contributing type as a page in the guide tab's place. A pane holds at most one guide tab, and the strip's add control appears only while its pane has none. A new pane receives the registered default page: the sole guide entry directly, or the guide when the entry count is not one ([guide](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-right/README.md#the-guide)).
146
+ - **`text`** — `fallback`, `dsh-resource://file/**`, claiming Session addresses only. Document Preview observes metadata through `useResource<'file'>`, loads content through Remote callbacks, and owns renderer selection, the toolbar, per-tab refresh, scroll, and source navigation; unknown extensions render as plain text ([README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-documentpreview/README.md)).
147
+ - **`files`** — `builtin`, opened as `openTab('files')`. The workspace directory tree, listed lazily through `list` and watched by expanded directory, opening a file with `tab.actions.openResource(fileAddressFor(sessionId, root, path))` into its own pane ([README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-files/README.md)).
148
+ - **`browser`** — multi-instance `builtin`, opened as `openTab('browser', { params: { url? } })`. Chat's [link preference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-chat/README.md) controls whether Assistant Markdown opens HTTP(S) links here. It accepts public and loopback HTTP(S) targets under the default sandbox, rejects local files in favor of Document Preview, and uses application-known iframe history ([README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-sidebar-browser/README.md)).
149
+ - **`subagentchat`** — `builtin`, `dsh-resource://subagentchat/session/<child>?parent=<parent>&mode=<mode>`. An explicitly addressed subagent Conversation retained by the resource provider and rendered through the shared Conversation Factory ([README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-subagent/README.md)).
150
+
151
+ <a id="not-built"></a>
152
+ ## Not built
153
+
154
+ - Persistence: layout state is memory-only; a reload starts every session collapsed, and no session's tabs are visible from another.
155
+ - A read-only layout snapshot or subscription on `ctx.sidebarRight`: the service exposes operations only, and dockkit's `LayoutState`/`LayoutOp` are internal.
156
+ - A capability-discovery array (`features`) on the service.
157
+ - An `option` priority band for tab types: nothing lists a tab type without letting it claim.
158
+ - Retitling a record: `title(address)` is captured once; a live chip comes from the title slot, not from the record.
159
+ - Naming a tab implementation when opening: `openResource` names a kind at most; document-renderer selection belongs to the file tab's toolbar.
160
+ - An address lookup on the service (`find`): a caller opens with `revealIfOpened` and lets the surface de-duplicate.
161
+ - Navigation addresses beyond the Sidebar's own `sidebar://<kind>` bookkeeping; their grammar waits for the navigation controller as a whole.
162
+ - A user-facing undo and general cross-type content navigation stack ([deferred](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-09-04-right-sidebar-docking-infrastructure.md#deferred)); Browser owns only its own page history.
@@ -1,13 +1,14 @@
1
1
  ---
2
2
  editSource: "docs/subsystems/skills.md"
3
+ rawMarkdownPath: "en/reference/subsystems/skills.md"
3
4
  outline: [2,3]
4
5
  ---
5
6
 
6
7
  # Skills
7
8
 
8
- The [skill capability family](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill) includes the Service Definition ([dsh-skill](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill/skill), `ctx.skills`), the local Service Provider ([dsh-skill-filesystem](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill/skill-filesystem)), the optional packaged badge provider ([dsh-skill-badge](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill/skill-badge)), and the Consumer ([dsh-tool-skill](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill/tool-skill)). The registry merges provider catalogs across its host and per-scope layers; providers contribute local or packaged skills; the Consumer owns the initial and replacement catalogs plus the model-facing `skill` tool. Skills are optional instructions, not session events, so their vocabulary lives here rather than in [core.md](./core.md).
9
+ The [skill capability family](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill) includes the Service Definition ([dsh-skill](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill/skill), `ctx.skills`), the local Service Provider ([dsh-skill-filesystem](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill/skill-filesystem)), optional packaged providers ([dsh-skill-badge](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill/skill-badge), [dsh-skill-office](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill/skill-office), and the Windows ACL diagnosis provider in [dsh-sandbox-windows-acl](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/sandbox/sandbox-windows-acl)), and the Consumer ([dsh-tool-skill](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/skill/tool-skill)). The registry merges provider catalogs across its host and per-scope layers; providers contribute local or packaged skills; the Consumer owns the initial and replacement catalogs plus the model-facing `skill` tool. Skills are optional instructions, not session events, so their vocabulary lives here rather than in [core.md](./core.md).
9
10
 
10
- Source: [`packages/skill/skill/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill/src/index.ts), [`packages/skill/skill-filesystem/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill-filesystem/src/index.ts), [`packages/skill/skill-badge/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill-badge/src/index.ts), and [`packages/skill/tool-skill/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/tool-skill/src/index.ts).
11
+ Source: [`packages/skill/skill/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill/src/index.ts), [`packages/skill/skill-filesystem/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill-filesystem/src/index.ts), [`packages/skill/skill-badge/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill-badge/src/index.ts), [`packages/skill/skill-office/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/skill-office/src/index.ts), [`packages/sandbox/sandbox-windows-acl/src/acl-skill.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/sandbox/sandbox-windows-acl/src/acl-skill.ts), and [`packages/skill/tool-skill/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/skill/tool-skill/src/index.ts).
11
12
 
12
13
  ## Provider registry
13
14
 
@@ -109,6 +110,8 @@ interface SkillInvocationPolicy {
109
110
  ```ts type-equiv
110
111
  /** Invocation-neutral skill metadata returned by `ctx.skills.list()`. */
111
112
  interface SkillSummary {
113
+ /** Absolute instruction file path when supplied by the provider; absent for virtual skills. */
114
+ readonly path?: string
112
115
  /** Kebab-case identifier used to address the skill. */
113
116
  readonly name: string
114
117
  /** Short routing description shown by discovery consumers. */
@@ -149,8 +152,6 @@ interface SkillCandidate extends SkillSummary {
149
152
  readonly rank: number
150
153
  /** Opaque provider-owned handle passed back to `provider.get()`. */
151
154
  readonly locator: unknown
152
- /** Absolute file path when the provider has one. */
153
- readonly path?: string
154
155
  /** Parsed optional metadata object from provider-specific skill frontmatter. */
155
156
  readonly metadata?: Readonly<Record<string, unknown>>
156
157
  }
@@ -171,8 +172,6 @@ type SkillResourceBase =
171
172
  interface SkillDefinition extends SkillSummary {
172
173
  /** Markdown instruction body after any provider-specific metadata removal. */
173
174
  readonly content: string
174
- /** Absolute file path when the skill came from disk. */
175
- readonly path?: string
176
175
  /** Parsed optional metadata object from frontmatter. */
177
176
  readonly metadata?: Readonly<Record<string, unknown>>
178
177
  }
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  editSource: "docs/subsystems/slots.md"
3
+ rawMarkdownPath: "en/reference/subsystems/slots.md"
3
4
  outline: [2,3]
4
5
  ---
5
6
 
@@ -9,6 +10,10 @@ Slots are the Web Client's typed React composition system. [`dsh-client-ui-slots
9
10
 
10
11
  This page documents slot ownership, component inputs, extension APIs, and the shipped hierarchy. The surrounding boot, Remote, Client model, and Conversation paths are in [Web Client architecture](./web-client.md).
11
12
 
13
+ `plugins.bundle.config` supplies bundle detail configuration, keyed by npm package name. `plugins.bundle.activation` renders optional guidance after user-requested enablement, with owner callbacks to dismiss or open that bundle’s details. `conversation.input.activity` supplies one action between the model selector and Send, with toolbar expansion released on unmount.
14
+
15
+ The plugin catalog declares `plugins.add.actions`, a root-scoped list for `MenuItemButton` rows after installation in the Add plugin menu. Its owner supplies `onDismiss()` to close the menu before starting an action. The slot follows the owning Plugins page declaration lifetime.
16
+
12
17
  ## Declaration and lifecycle
13
18
 
14
19
  `SlotMap` is the compile-time registry. A package declaration-merges the key, cardinality, scope, owner props, keyed props, and optional slot-level inject face. The runtime declaration is the matching `children` entry on the component that owns the render location.
@@ -55,8 +60,8 @@ The slot declaration fixes two independent axes.
55
60
  | cardinality | `keyed` | The owner dispatches an `entryKey`; the matching cell renders with any key-specific props. |
56
61
  | cardinality | `chain` | Each entry supplies a pure `select(owner)` function. The first non-null result in priority order renders and receives that result as `matched`; otherwise the owner fallback renders. |
57
62
  | scope | `root` | One root-scoped component and store instance. |
58
- | scope | `session-maybe` | Follows current selection but stays renderable without a Session; Session values are optional. |
59
- | scope | `session` | Requires a resolved Session binding and receives definite Session values. |
63
+ | scope | `session-maybe` | Inherits the surrounding Provider binding but stays renderable without one; Session values are optional. |
64
+ | scope | `session` | Requires a resolved surrounding Provider binding and receives definite Session values. |
60
65
 
61
66
  `priority` is a shadowing rank for `single`, `list`, and `keyed` cells and an election order for `chain`. Lower values run or render first. Ordinary additive contributions should choose a fresh list `id` or keyed `key`; intentionally reusing a shipped cell replaces its presentation.
62
67
 
@@ -73,7 +78,7 @@ A registered component receives inputs assembled at its binding site. Components
73
78
  | localized `t` function | the registration's `locale` namespace | `PropsLocale<N>` |
74
79
  | selected chain value | the registration's `select` result | `matched` through `ComposedProps` |
75
80
 
76
- `SessionProvider` is also present in `PropsRenderSlots` when an entry declares a strict Session child. It binds that subtree to the current Session identity and remounts the body when the identity changes.
81
+ `SessionProvider` is also present in `PropsRenderSlots` when an entry declares a `session` or `session-maybe` child. With no `session` prop it inherits the surrounding binding; an explicit `SessionReference` or `undefined` overrides only that subtree. The Provider does not key its whole body. A strict `session` entry remounts when its binding generation changes. A blank `session-maybe` entry adopts its first binding without remounting, then remounts for a later generation or a return to absence.
77
82
 
78
83
  Components never receive `ctx`. Parent-owned point-in-time values enter through the owner argument to `renderSlot`; shared view state uses a declared store; services and model objects stay in the `apply` closure and are projected into callbacks or observable sources.
79
84
 
@@ -83,8 +88,9 @@ The shipped adapters add these standard props. They are available according to t
83
88
 
84
89
  | Availability | Props | Owner |
85
90
  |---|---|---|
86
- | every scope | `useSessions`, `useSessionPendingInteraction` | `ui-session` |
91
+ | every scope | `useSessions`, `useSessionStatus`, `useSessionRetainInfo` | `ui-session` |
87
92
  | every scope | `useWorkspaces` | `ui-workspace` |
93
+ | every scope | `usePanelInfo` | `ui-layout` |
88
94
  | `session` | `sessionId`, `useSession`, `useProjection` | `ui-session` |
89
95
  | `session-maybe` | optional `sessionId`, `useSession`, `useProjection` results | `ui-session` |
90
96
  | `session` | `useConversation`, `useInput`, `inputActions` | `ui-conversation` |
@@ -115,9 +121,12 @@ root
115
121
  ├─ sidebar
116
122
  │ ├─ sidebar.brand.mark
117
123
  │ ├─ sidebar.brand.name
124
+ │ ├─ sidebar.panellist
118
125
  │ ├─ sidebar.footer.action
119
126
  │ ├─ sidebar.workspaces
120
- │ │ └─ sidebar.workspaces.directoryFlow
127
+ │ │ ├─ sidebar.workspaces.directoryFlow
128
+ │ │ ├─ sidebar.workspaces.session.menu.item
129
+ │ │ └─ sidebar.workspaces.session.row.action
121
130
  │ └─ sidebar.settings
122
131
  │ ├─ settings.trigger
123
132
  │ ├─ settings.header
@@ -129,41 +138,61 @@ root
129
138
  │ ├─ settings.models.provider-card
130
139
  │ ├─ settings.models.footer
131
140
  │ └─ settings.plugins.tab
132
- │ └─ settings.plugin.item
133
- ├─ conversation
134
- │ ├─ conversation.session
135
- │ │ └─ conversation.view
136
- │ │ ├─ conversation.chat.node
137
- │ │ │ ├─ conversation.chat.assistant-actions
138
- │ │ │ ├─ conversation.chat.commandview
139
- │ │ │ ├─ conversation.chat.turnTail
140
- │ │ │ └─ tool.call.toolview
141
- │ │ │ ├─ tool.call.images
142
- │ │ │ └─ tool.view.cordis
143
- │ │ ├─ conversation.message.images
144
- │ │ └─ conversation.trajectory.images
145
- │ ├─ conversation.session.header
146
- │ │ ├─ conversation.session.header.lineage
147
- │ │ ├─ conversation.session.header.actions
148
- │ │ └─ conversation.session.header.utilities
149
- │ ├─ conversation.composer
150
- │ │ └─ conversation.approval.detail
151
- │ ├─ conversation.composer.bar
152
- │ │ ├─ conversation.input.attachments
153
- │ │ ├─ conversation.input.plan
154
- │ │ └─ conversation.input.model
155
- │ ├─ conversation.input.overlay
156
- │ ├─ conversation.input.dock
157
- │ ├─ conversation.composer.dock
158
- │ ├─ conversation.input.left
159
- │ ├─ conversation.input.right
160
- │ ├─ conversation.hero.brand.mark
161
- │ ├─ conversation.hero.workspace
162
- │ │ └─ conversation.hero.workspace.directoryFlow
163
- │ └─ conversation.hero.agentPreset
164
- ├─ details
165
- │ └─ conversation.details.tool
141
+ ├─ main
142
+ │ ├─ plugins.add.actions
143
+ │ ├─ plugins.item
144
+ │ ├─ plugins.bundle.config
145
+ │ ├─ plugins.row.config
146
+ │ ├─ plugins.detail.actions
147
+ │ ├─ plugins.detail.badge
148
+ │ ├─ plugins.detail.section
149
+ │ └─ main.conversation
150
+ │ ├─ conversation.session
151
+ │ │ └─ conversation.view
152
+ │ │ ├─ conversation.chat.node
153
+ │ │ │ ├─ conversation.chat.assistant-actions
154
+ │ │ │ ├─ conversation.chat.commandview
155
+ │ │ │ ├─ conversation.chat.turnTail
156
+ │ │ │ └─ tool.call.toolview
157
+ │ │ │ ├─ tool.call.images
158
+ │ │ │ └─ tool.view.cordis
159
+ │ │ ├─ conversation.message.images
160
+ │ │ └─ conversation.trajectory.images
161
+ │ ├─ conversation.header
162
+ │ │ ├─ conversation.header.leading
163
+ │ │ └─ conversation.session.header
164
+ │ │ ├─ conversation.session.header.lineage
165
+ │ │ ├─ conversation.session.header.actions
166
+ │ │ ├─ conversation.session.header.utilities
167
+ │ │ └─ conversation.session.header.corner
168
+ │ ├─ conversation.composer
169
+ │ │ ├─ conversation.approval.detail
170
+ │ │ └─ conversation.plan-review.actions
171
+ │ ├─ conversation.composer.bar
172
+ │ │ ├─ conversation.input.attachments
173
+ │ │ ├─ conversation.input.permission
174
+ │ │ ├─ conversation.input.plan
175
+ │ │ └─ conversation.input.model
176
+ │ ├─ conversation.input.overlay
177
+ │ ├─ conversation.input.dock
178
+ │ ├─ conversation.composer.dock
179
+ │ ├─ conversation.input.left
180
+ │ ├─ conversation.input.right
181
+ │ ├─ conversation.hero.brand.mark
182
+ │ ├─ conversation.hero.workspace
183
+ │ │ └─ conversation.hero.workspace.directoryFlow
184
+ │ └─ conversation.hero.agentPreset
185
+ ├─ rightbar
186
+ │ └─ rightbar.session
187
+ │ ├─ sidebar.right.pane.tab
188
+ │ │ ├─ sidebar.right.tab.guide
189
+ │ │ └─ sidebar.right.tab.guide.entry
190
+ │ ├─ sidebar.right.pane.tab.title
191
+ │ └─ sidebar.right.tab.menu.item
192
+ ├─ shell.bottom
193
+ ├─ shell.leading
166
194
  └─ shell.overlay
195
+ └─ shell.quota-notice
167
196
  ```
168
197
 
169
198
  The generated Client inspect catalog is the exhaustive contract for each key: cardinality, scope, owner props, standard props, current occupants, declaration owner, and replacement risk. A running dynamic package can query the live tree and an exact key with `cordis_inspect what:"client"`; the source catalog is generated from `SlotMap` declarations and `slots.register()` call sites by `pnpm run gen-client-catalog`.
@@ -1,17 +1,18 @@
1
1
  ---
2
2
  editSource: "docs/subsystems/spill.md"
3
+ rawMarkdownPath: "en/reference/subsystems/spill.md"
3
4
  outline: [2,3]
4
5
  ---
5
6
 
6
7
  # Spill Storage
7
8
 
8
- The spill storage seam — a [capability seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.md) that persists a tool's oversized text and returns a model-facing locator plus retrieval guidance, split across packages: Service Definition ([dsh-spill](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill), `ctx.spillStore`), Service Provider ([dsh-spill-local](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-local), private session-scoped files on the host filesystem), and Consumer ([dsh-spill-policy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-policy), the `tools/post-execute` policy). Spill is **one optional capability**, not part of the agent-loop spine — so its vocabulary lives here, not in [core.md](./core.md). Preview mechanics stay in [dsh-output-retention](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/util/output-retention); this seam only saves the final text the policy hands it.
9
+ The spill storage [capability seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.md) persists caller-provided text and returns a model-facing locator with retrieval guidance. Its Service Definition is [dsh-spill](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill) (`ctx.spillStore`), and its local Service Provider is [dsh-spill-local](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-local). Consumers include the [tool-result policy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-policy) and [session references](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/context/session-reference/README.md). Spill is optional, not part of the [agent-loop spine](./core.md); consumers own preview and spill decisions, while storage saves the supplied text verbatim.
9
10
 
10
11
  Source: [`packages/spill/spill/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/spill/spill/src/types.ts)
11
12
 
12
13
  ## The save request
13
14
 
14
- `saveText` is the sole service operation: persist `content` verbatim, return an opaque locator, a backend-supplied retrieval hint, and the exact byte count. The request carries the save-time storage namespace (`owner`), the tool and call that produced it (`source`, used for naming and inspection — not access control), and a `suggestedName` the backend may use as a naming hint (it is not a path).
15
+ `saveText` is the sole service operation: persist `content` verbatim, return an opaque locator, a backend-supplied retrieval hint, and the exact byte count. The request carries the save-time storage namespace (`owner`), descriptive producer details (`source`, never access control), and a `suggestedName` the backend may use as a naming hint, not a path. A tool source identifies the actual tool call; a session-reference source identifies the captured source session, while its owner is the target session receiving the context.
15
16
 
16
17
  ```ts type-equiv
17
18
  /** One request to persist text to a spill artifact. */
@@ -45,17 +46,24 @@ A retention-period cleanup may expire old locators with other old session artifa
45
46
 
46
47
  ```ts type-equiv
47
48
  /**
48
- * Tool and call that produced one spilled artifact — recorded by the backend for a readable
49
- * filename and inspection. Not interpreted for access control; purely
50
- * descriptive.
49
+ * Producer of a spilled artifact. Tool results carry their model-issued call id;
50
+ * session references identify the captured source session instead. Descriptive
51
+ * source description only, never access control.
51
52
  */
52
- interface SpillSource {
53
+ type SpillSource = {
54
+ kind: 'tool'
53
55
  /** The tool whose result was spilled (e.g. `web_fetch`). */
54
56
  toolName: string
55
57
  /** The model-issued call id the result belongs to. */
56
58
  callId: ToolCallId
57
59
  /** A short human label for the artifact (e.g. `result`). */
58
60
  label: string
61
+ } | {
62
+ kind: 'session-reference'
63
+ /** Session whose projected conversation was captured. */
64
+ sessionId: SessionId
65
+ /** Host-provided label for the referenced session. */
66
+ label: string
59
67
  }
60
68
  ```
61
69
 
@@ -85,7 +93,7 @@ type SpillLocator = Branded<'SpillLocator'>
85
93
 
86
94
  `SpillStore` (`ctx.spillStore`, defined in [`packages/spill/spill/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/spill/spill/src/index.ts)) is a one-method abstract service: `saveText(input) → Promise<SpillRef>`. It persists the FULL `content` and REJECTS on a real storage failure (permissions, ENOSPC, backend unavailable). The seam owns storage only: no retention policy, no tool-result replacement, no retrieval/search API.
87
95
 
88
- The local backend ([dsh-spill-local](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-local)) writes under `<root>/session-<hash>/<random>-<safeName>` — a configured or lazily-created private (0700) root, a `sha256(sessionId)` session subdir, and an exclusive owner-only (`open(path, 'wx', 0o600)`) write so a planted symlink cannot redirect it. Its `locator` is the local path and its `retrievalHint` tells the model to use `read` or `grep` on that path. The policy consumer ([dsh-spill-policy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-policy)) replaces an over-`maxInlineBytes` plain-text final result with a retention-library head/tail preview plus the spill reference, best-effort: a save failure keeps the original inline result rather than turning a successful call into an `isError`.
96
+ The local backend ([dsh-spill-local](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-local)) writes under `<root>/session-<hash>/<random>-<safeName>` — a configured or lazily-created private (0700) root, a `sha256(sessionId)` session subdir, and an exclusive owner-only (`open(path, 'wx', 0o600)`) write so a planted symlink cannot redirect it. Its `locator` is the local path and its `retrievalHint` tells the model to use `read` or `grep` on that path. The policy consumer ([dsh-spill-policy](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/spill/spill-policy)) replaces an over-`maxInlineTokens` text/image result with ordered head/tail content and a spill address, best-effort: a save failure keeps the original inline result rather than turning a successful call into an `isError`.
89
97
 
90
98
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
91
99
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  editSource: "docs/subsystems/storage.md"
3
+ rawMarkdownPath: "en/reference/subsystems/storage.md"
3
4
  outline: [2,3]
4
5
  ---
5
6
 
@@ -218,8 +219,7 @@ The mounted domain facility. Opens declared domains over routed backends; one fa
218
219
  async open<S extends DomainSpec>(spec: S): Promise<Domain<S>>
219
220
 
220
221
  /**
221
- * Look up an open domain by name, untyped. Diagnostic surface (the package
222
- * invariant cross-checks change events against live domain state); typed
222
+ * Look up an open domain by name, untyped. Diagnostic surface; typed
223
223
  * consumers hold the handle returned by {@link open}.
224
224
  * @param name - Domain name.
225
225
  * @returns the open domain runtime, or `undefined` when not open.