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
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  editSource: "docs/subsystems/approval.md"
3
+ rawMarkdownPath: "en/reference/subsystems/approval.md"
3
4
  outline: [2,3]
4
5
  ---
5
6
 
@@ -49,11 +50,11 @@ type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable'
49
50
  type ApprovalPolicy = 'ask' | 'never'
50
51
  ```
51
52
 
52
- Both policies contribute their complete current meaning to the cache-safe runtime-context snapshot. The sourced `user/message` is the durable model-visible input; changing approval state appends a new full snapshot after retained history without rewriting the request header's system prompt.
53
+ Both policies contribute their complete current meaning to the cache-safe runtime-context snapshot. The sourced `user/message` is the durable model-visible input; changing approval state appends a new full snapshot after retained history without touching the `system/message` nodes that hold the rendered system prompt.
53
54
 
54
55
  ## Approval request
55
56
 
56
- `ApprovalRequest` identifies the agent and tool action closely enough to route and audit the question. It deliberately omits tool arguments: an answerer attaches the prompt to the already-streamed tool call through `callId` instead of rendering a second copy that could drift.
57
+ `ApprovalRequest` identifies the agent and tool action closely enough to route and audit the question. It deliberately omits tool arguments: an answerer attaches the prompt to the already-streamed tool call through `callId` instead of rendering a second copy that could drift. Optional `displayReason` carries requester-owned locale strings to presentation; `reason` remains the audit text.
57
58
 
58
59
  ```ts type-equiv
59
60
  /**
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  editSource: "docs/subsystems/client-modules.md"
3
+ rawMarkdownPath: "en/reference/subsystems/client-modules.md"
3
4
  outline: [2,3]
4
5
  ---
5
6
 
@@ -25,7 +26,10 @@ The graph is the wire single source between the Node and browser halves. The hos
25
26
  interface WebBootEntry {
26
27
  /** Entry name == package name. */
27
28
  id: string
28
- /** Revisioned single-resource combo endpoint used by HMR. */
29
+ /**
30
+ * Revisioned single-resource combo reference used by HMR. It is relative to
31
+ * the document, so the browser resolves it under whatever mount served the page.
32
+ */
29
33
  url: string
30
34
  /** Opaque plugin-artifact revision used for HMR cache busting. */
31
35
  rev: string
@@ -39,7 +43,7 @@ interface WebBootEntry {
39
43
  ```
40
44
 
41
45
  ```ts type-equiv
42
- /** Initial scheduling phase for one content-addressed combo script. */
46
+ /** Initial scheduling phase for one revisioned combo script. */
43
47
  type WebBootBatchPhase = 'bootstrap' | 'application'
44
48
  ```
45
49
 
@@ -48,9 +52,9 @@ type WebBootBatchPhase = 'bootstrap' | 'application'
48
52
  interface WebBootBatch {
49
53
  /** Parser-blocking bootstrap or preloaded application scheduling. */
50
54
  phase: WebBootBatchPhase
51
- /** Content-addressed combo script endpoint. */
55
+ /** Content-addressed combo script reference, document-relative like {@link WebBootEntry.url}. */
52
56
  url: string
53
- /** Revision over the combined plugin script bytes and indexed source map. */
57
+ /** Revision derived from the ordered entry revisions. */
54
58
  rev: string
55
59
  /** Graph entry ids whose factories the script registers, in execution order. */
56
60
  entries: string[]
@@ -60,7 +64,7 @@ interface WebBootBatch {
60
64
  ```ts type-equiv
61
65
  /** The composed client entry graph the host injects as `window.__DSH_BOOT__`. */
62
66
  interface WebBootGraph {
63
- /** Consistency anchor over the whole graph (content + bundle hashes). */
67
+ /** Consistency anchor over the current entry and batch descriptors. */
64
68
  rev: string
65
69
  /**
66
70
  * Composed entries in module-graph order — a dynamic package row precedes
@@ -73,7 +77,7 @@ interface WebBootGraph {
73
77
  }
74
78
  ```
75
79
 
76
- Each initial row's `rev` is an opaque process nonce plus sequence, so graph composition does not hash every plugin artifact. After HMR observes a change, that row's revision becomes the hash of its new bundle and available source map. The initial descriptors partition rows into bootstrap and application scheduling phases, and either phase may contain several descriptors. Their URLs contain only the ordered package-resource list and revision; phase names do not enter the route. Graph composition preserves row order while greedily splitting before the map-form URL exceeds 3 KiB. Startup combo revisions hash the combined plugin script bytes and indexed source map, and the graph revision hashes both rows and descriptors. `immediately` marks the stage-one registration barrier; rows within one combo share its script transport, while separate combos load independently.
80
+ Initial publication and HMR derive each row's `rev` from the entry's mtime, ctime, and size, without hashing executable bytes. The same artifacts retain their revisions across Host restarts. The initial descriptors partition rows into bootstrap and application scheduling phases, and either phase may contain several descriptors. Their URLs contain only the ordered package-resource list and a revision derived from those row revisions; phase names do not enter the route. Graph composition preserves row order while greedily splitting before the map-form URL exceeds 3 KiB, without concatenating scripts or reading maps. The graph revision hashes the entry and batch descriptors. `immediately` marks the stage-one registration barrier; rows within one combo share its script transport, while separate combos load independently.
77
81
 
78
82
  ## The scan
79
83
 
@@ -85,7 +89,7 @@ Package metadata — including the negative "not a client package" verdict — i
85
89
 
86
90
  ## The bundle route and index injection
87
91
 
88
- `GET`/`HEAD /plugins/??<package-a>/client.js,<package-b>/client.js&rev=<rev>` serves an exact generated combo script; a one-resource request uses the same form and is the HMR path. Its absolute `sourceMappingURL` changes every resource suffix in parallel, yielding `/plugins/??<package-a>/client.js.map,<package-b>/client.js.map&rev=<rev>`. The map is Indexed Source Map v3 even for one resource. An authored component map supplies its section; a component without one receives an identity section whose `sourcesContent` is the generated bundle and whose source name is its packaged `sourceURL` or plugin route. Every startup request URL is at most 3 KiB measured as UTF-8 bytes; partitioning uses the longer map form. All application URLs are preloaded, and all bootstrap URLs execute before the graph global and Vite entry. All advertised responses use long-lived immutable caching. Unknown or altered resource lists, missing revisions, and stale revisions answer 404 rather than serving different bytes or letting the SPA fallback return HTML as JavaScript; other methods are 405. The injection rows carry the current graph on every index render, so a reload always boots against the live composition.
92
+ `GET`/`HEAD /plugins/??<package-a>/client.js,<package-b>/client.js&rev=<rev>` addresses one generated combo script; a one-resource request uses the same form and is the HMR path. The script is concatenated once on its first `GET` and ends with a `sourceMappingURL` that carries the combo query alone — `??<package-a>/client.js.map,<package-b>/client.js.map&rev=<rev>`, resolved against the script's own directory rather than the document. The map files are not read by startup, index rendering, script `GET`, or `HEAD`; the first map `GET` reads and validates them, composes one Indexed Source Map v3, and caches that body. An authored component map supplies its section; a component without one receives an identity section whose `sourcesContent` is the captured bundle and whose source name is its packaged `sourceURL` or plugin route. Every startup request URL is at most 3 KiB measured as UTF-8 bytes; partitioning uses the longer map form. All application URLs are preloaded, and all bootstrap URLs execute before the graph global and Vite entry. Materialized responses use long-lived immutable caching. Unknown or altered resource lists, missing revisions, and stale revisions answer 404 rather than serving different bytes or letting the SPA fallback return HTML as JavaScript; other methods are 405. The injection rows carry the current graph on every index render, so a reload always boots against the live composition.
89
93
 
90
94
  ## The service
91
95
 
@@ -96,14 +100,16 @@ interface ClientArtifactBaseline {
96
100
  readonly path: string
97
101
  /** Bundle modification time in milliseconds. */
98
102
  readonly mtimeMs: number
103
+ /** Bundle status-change time in milliseconds, including writes that preserve mtime. */
104
+ readonly ctimeMs: number
99
105
  /** Bundle size in bytes. */
100
106
  readonly size: number
101
107
  }
102
108
  ```
103
109
 
104
- `ClientModuleRegistry` (`ctx.clientModules`, defined in [`packages/client/modules/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/modules/src/index.ts)) exposes reads and the rebuild face; signatures are in the generated [service catalog](#ctxclientmodules--clientmoduleregistry). `graph()` returns the current composed graph (a stable object between changes), `clientPath(id)` returns the bundle's absolute path, and `artifactBaseline(id)` returns the bundle stat values captured before the current snapshot was read. `rebuilt(id)` is the only entry point through which changed bundle content reaches the graph: it re-hashes the bundle together with its current source map, and only a real rev change recomposes the graph and notifies. `onRebuilt` fires per changed bundle with the new rev; `onGraphChanged` fires after any flush that recomposed the graph (row added or removed, or a rebuilt rev change) and is pull-model — listeners re-read `graph()`. Both notification paths contain listener exceptions so one throwing subscriber cannot skip later subscribers or kill whatever triggered the flush.
110
+ `ClientModuleRegistry` (`ctx.clientModules`, defined in [`packages/client/modules/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/modules/src/index.ts)) exposes reads and the rebuild face; signatures are in the generated [service catalog](#ctxclientmodules--clientmoduleregistry). `graph()` returns the current composed graph (a stable object between changes), `clientPath(id)` returns the bundle's absolute path, and `artifactBaseline(id)` returns the bundle stat values captured before the current snapshot was read. `fetchBundle()` resolves the same lazy response used by the HTTP route. `rebuilt(id)` is the only entry point through which changed bundle content reaches the graph: it derives the revision from filesystem metadata, and only a revision change reads the new bytes, recomposes the graph, and notifies. `onRebuilt` fires per changed bundle with the new revision; `onGraphChanged` fires after any flush that recomposed the graph (row added or removed, or a rebuilt revision change) and is pull-model — listeners re-read `graph()`. Both notification paths contain listener exceptions so one throwing subscriber cannot skip later subscribers or kill whatever triggered the flush.
105
111
 
106
- In development, [dsh-client-hmr](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/hmr/README.md) is the registry's watch driver: its node half stat-polls every graph row's bundle from the module host's pre-read baseline, calls `rebuilt(id)` only for a changed or dirty row, resyncs its watch set through `onGraphChanged`, and broadcasts rev changes to the browser half over SSE. Source-map changes alone do not trigger a reload; the current map joins the snapshot when a bundle change does. Production graphs omit the HMR row entirely; the module host itself never watches files.
112
+ [`dsh-client-hmr`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/hmr/README.md) delivers live graph snapshots in the shipped Web composition. The Host forwards existing graph-change notifications immediately, and reconnect sends the current full graph. A graph describes desired browser entries without asserting that Host cleanup has completed. Its artifact poll separately reports rebuilt revisions. Source-map changes alone do not trigger a reload; a new combo-map URL appears only after a bundle revision changes, and each map body is fixed by its first `GET`. Client Modules validates snapshots and serializes reconciliation with those rebuilds; it owns the boot-created entry map, single-resource arrivals, asynchronous removal, unused-module/style cleanup and page-local retry status. Static platform modules and the bootstrap retain their page lifetime; Electron installation is a separate flow.
107
113
 
108
114
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
109
115
 
@@ -133,6 +139,16 @@ graph(): WebBootGraph
133
139
  */
134
140
  clientPath(id: string): string | undefined
135
141
 
142
+ /**
143
+ * Serve an advertised revisioned bundle or source map without a Web server.
144
+ * Unknown URLs return 404, unsupported methods return 405, and `HEAD`
145
+ * returns the same immutable headers without materializing a body. Each body
146
+ * is built once on its first `GET`; script construction never reads maps.
147
+ * @param request - shell-carrier request for a `/plugins` resource.
148
+ * @returns the exact response also exposed by the optional Web route.
149
+ */
150
+ async fetchBundle(request: Request): Promise<Response>
151
+
136
152
  /**
137
153
  * Filesystem baseline captured before an entry's current bytes were read.
138
154
  * HMR compares it with the live files when installing a watch, so a write
@@ -144,15 +160,16 @@ clientPath(id: string): string | undefined
144
160
  artifactBaseline(id: string): ClientArtifactBaseline | undefined
145
161
 
146
162
  /**
147
- * Re-hash one bundle (the HMR watch's registration hook — the only entry
148
- * point through which bundle content changes reach the graph).
163
+ * Publish one completed bundle generation (the HMR watch's registration
164
+ * hook — the only entry point through which build changes reach the graph).
165
+ * Unchanged mtime, ctime and size preserve the graph without reading the bundle.
149
166
  * @param id - entry id (package name).
150
- * @returns the new rev, or undefined for an unknown id.
167
+ * @returns the current artifact rev, or undefined for an unknown id.
151
168
  */
152
169
  rebuilt(id: string): string | undefined
153
170
 
154
171
  /**
155
- * Subscribe to bundle rebuilds; fires only when the re-hash changed the rev.
172
+ * Subscribe to bundle rebuilds; fires only when artifact metadata changes the rev.
156
173
  * @param listener - receives the entry id and its new bundle rev.
157
174
  * @returns the unsubscriber.
158
175
  */
@@ -0,0 +1,96 @@
1
+ ---
2
+ editSource: "docs/subsystems/client-resources.md"
3
+ rawMarkdownPath: "en/reference/subsystems/client-resources.md"
4
+ outline: [2,3]
5
+ ---
6
+
7
+ # Client Resources
8
+
9
+ The client resource model turns an address into live data for any Web Client component. [`dsh-client-resources`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/resources/README.md) provides the `ctx.resources` service and the `useResource` global standard hook; a package that owns a kind of content registers one **provider** for its **protocol**, and a component reads the content's current state by **address** without importing the owner's runtime. The right Sidebar's tabs are the model's first consumer ([Right Sidebar](./sidebar-right.md)); the decision record is the [client resource model Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-09-05-client-resource-model.md).
10
+
11
+ This page is the developer reference: how to write an address, how to register a provider, how to read a resource, what the states and failures mean, and how the model holds and releases a resource.
12
+
13
+ ## Addresses
14
+
15
+ A resource address is a `dsh-resource://<type>/…` URL. The host names the protocol and must be a key of `ResourceProtocolMap`; the path is the protocol's own, and its owner percent-encodes each segment. A protocol that needs a scope puts it in the path: the `file` protocol's addresses read `dsh-resource://file/session/<sessionId>/<path>`, where path is workspace-relative or absolute with its leading slashes preserved, built with `fileAddressFor(sessionId, cwd, path)` and read back with `parseFileAddress(address)` from [`dsh-util-workspace-path`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/util/workspace-path/README.md). The model itself reads only the scheme and the host: `protocolOf(address)` returns the lower-cased host of a `dsh-resource://` URL and `undefined` for anything else. Addresses under any other scheme — the Sidebar's `sidebar://guide` — name no resource and read as `none`.
16
+
17
+ | Address | Protocol key | Reads as |
18
+ |---|---|---|
19
+ | `dsh-resource://file/session/s1/notes/a.md` | `file` | the metadata of `notes/a.md` under session `s1`'s workspace root, when the `file` provider is registered |
20
+ | `dsh-resource://file/absolute/home/me/notes.md` | `file` | parseable but fails with `workspace-file/unknown-workspace`: no authorizing Session, and neither current nor Tab Session is borrowed |
21
+ | `DSH-RESOURCE://File/session/s1/a` | `file` | a distinct record: addresses compare as strings, and `openResource` accepts only the canonical lower-case spelling that `fileAddressFor` emits |
22
+ | `dsh-resource://subagentchat/session/c1?parent=p1&mode=continuable` | `subagentchat` | an addressed subagent Conversation whose value owns a `SessionReference` until the resource closes |
23
+ | `sidebar://guide` | — | `none`: a navigation address |
24
+ | `/home/me/notes.md` | — | `none`: not a URL |
25
+
26
+ ## Registering a provider
27
+
28
+ The owner of a protocol declares its value type on `ResourceProtocolMap` and registers one provider inside its own `ctx.effect`, so the protocol lives exactly as long as the plugin ([provide a protocol](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/resources/README.md#provide-a-protocol)). `open(address, { signal })` returns a stream of `RemoteResult` frames — the current state first, then one frame per change — and must stop when `signal` aborts. A failure is an `ok: false` frame carrying a `RemoteFailure`; a throw inside the stream is a programming error and is not caught.
29
+
30
+ ```ts ignore-check
31
+ import type { Context } from '@deepseek-ai/cordis'
32
+ import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol'
33
+ import type {} from '@deepseek-ai/dsh-client-resources/client'
34
+
35
+ interface NoteView { readonly title: string; readonly updatedAt: string }
36
+
37
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
38
+ interface ResourceProtocolMap { note: NoteView }
39
+ }
40
+
41
+ export const inject = ['resources', 'remote']
42
+
43
+ export function apply(ctx: Context): void {
44
+ ctx.effect(() => ctx.resources.register<'note'>({
45
+ protocol: 'note',
46
+ async *open(address, { signal }): AsyncIterable<RemoteResult<NoteView>> {
47
+ const id = new URL(address).pathname.slice(1)
48
+ yield await ctx.remote.notes.read(id, signal)
49
+ for await (const change of ctx.remote.notes.follow(id, signal)) yield change
50
+ },
51
+ }), 'my-notes: note resource provider')
52
+ }
53
+ ```
54
+
55
+ A protocol has exactly one provider; a second registration throws. Registering while addresses of the protocol are already held opens their streams at once; disposing the provider ends those streams and the addresses read `none` until a provider returns.
56
+
57
+ ## Reading a resource
58
+
59
+ Every slot component receives `useResource` in its props, whatever its scope ([Slots](./slots.md)). `useResource<P>(address)` names the protocol as the type argument and returns the address's current snapshot; subscribing is what holds the resource open, and a component that mounts while another holder keeps the resource alive reads the latest value at once without reopening the stream ([read a resource](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/resources/README.md#read-a-resource)).
60
+
61
+ | `status` | Meaning | `value` | `failure` |
62
+ |---|---|---|---|
63
+ | `none` | No provider is registered for the address's protocol, or the address is not a resource address | `undefined` | `undefined` |
64
+ | `loading` | The provider's stream is open and has not yielded yet | `undefined` | `undefined` |
65
+ | `live` | The latest frame succeeded | the latest `ok` value | `undefined` |
66
+ | `failed` | The latest frame reported a failure | the last `ok` value, kept | the frame's `RemoteFailure` |
67
+
68
+ ```tsx ignore-check
69
+ import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
70
+ import type {} from '@deepseek-ai/dsh-api-workspace-files/client'
71
+
72
+ type Props = PropsRuntime<'sidebar.right.pane.tab'>
73
+
74
+ export function FileHeader({ useTabInfo, useResource, t }: Props) {
75
+ const { tab } = useTabInfo()
76
+ const meta = useResource<'file'>(tab.contentId)
77
+ if (meta.status === 'failed') return <p role="alert">{t('failed', { code: meta.failure.code })}</p>
78
+ return (
79
+ <header>
80
+ {tab.title}
81
+ </header>
82
+ )
83
+ }
84
+ ```
85
+
86
+ A consumer presents `failed` itself: the model keeps the last value beside the failure so a body can show stale content with a notice rather than a blank, and the next `ok` frame clears the failure. Nothing in the model produces user-visible text.
87
+
88
+ ## Holding and releasing
89
+
90
+ A resource is alive while it has a holder: a subscribed `useResource`, or a pin. `ctx.resources.pin(address, signal)` keeps a resource open without subscribing until `signal` aborts, and an already-aborted signal pins nothing; the right Sidebar pins every open tab record's address for the record's life, so switching tabs unmounts a body without closing its stream. The first holder opens the provider's stream; the last release aborts it, discards the value, and returns the snapshot to `loading` (provider present) or `none` (absent). A frame the provider yields after that release is dropped, and the iterator is returned. `ctx.resources.source(address)` is the bare observable behind the hook, reference-stable per address, for callers outside React; reading its snapshot does not hold the resource ([lifecycle](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/resources/README.md#lifecycle)).
91
+
92
+ Most streams carry metadata rather than content. The `file` provider's value is `WorkspaceFileStat { absolutePath, version, bytes? }`: the first frame comes from Host `stat`, and later observations update the version. A consumer reads content through the Workspace Files Remote namespace; Preview owns refresh independently per tab ([`dsh-api-workspace-files`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/workspace-files/README.md)). The `subagentchat` provider retains the addressed Session and yields its `SessionReference`, then releases that reference when the resource signal aborts.
93
+
94
+ ## Limits
95
+
96
+ Records live for the page lifetime: an address's record stays after its last holder leaves, holding no stream and no value, so memory grows with the number of distinct addresses ever read. A provider that ignores `signal` keeps running until its next frame. The failure type is the Remote face's `RemoteFailure`, so a provider whose source is not a Remote call mints one. A misspelled protocol or a malformed address reads as `none` with no other diagnostic.
@@ -1,11 +1,12 @@
1
1
  ---
2
2
  editSource: "docs/subsystems/commands.md"
3
+ rawMarkdownPath: "en/reference/subsystems/commands.md"
3
4
  outline: [2,3]
4
5
  ---
5
6
 
6
7
  # Human Commands
7
8
 
8
- The human-command registry service from [`dsh-commands`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/interaction/commands). Interactive adapters use it to discover and directly execute plugin-owned commands for an exact agent without creating a model message. The [command Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-07-19-plugin-command-registration.md) owns dispatch and lifecycle rationale; the [package README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/commands/README.md) owns composition and limitations.
9
+ The human-command registry service from [`dsh-commands`](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/interaction/commands). Interactive adapters use it to discover and directly execute plugin-owned commands for an exact agent without creating a model message. The [historical command Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/archived/feature/2026-07-19-plugin-command-registration.md) records dispatch and lifecycle rationale; the [package README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/commands/README.md) owns composition and limitations.
9
10
 
10
11
  Source: [`packages/interaction/commands/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/interaction/commands/src/index.ts)
11
12
 
@@ -36,6 +37,8 @@ interface CommandInputDescriptor {
36
37
  ```ts type-equiv
37
38
  /** Plugin-owned command registration. */
38
39
  interface CommandDefinition {
40
+ /** Stable plugin-owned identity; absent for definitions without identity-based client behavior. */
41
+ readonly definitionId?: CommandDefinitionId
39
42
  /** Lowercase command name without the leading slash. */
40
43
  readonly name: string
41
44
  /** Human-readable summary used in discovery UI. */
@@ -100,6 +103,8 @@ Adapters receive handler-free immutable descriptors after scope resolution. `par
100
103
  ```ts type-equiv
101
104
  /** Handler-free immutable command view returned to UI adapters. */
102
105
  interface CommandDescriptor {
106
+ /** Stable plugin-owned identity; absent for definitions without identity-based client behavior. */
107
+ readonly definitionId?: CommandDefinitionId
103
108
  /** Lowercase command name without the leading slash. */
104
109
  readonly name: string
105
110
  /** Human-readable summary used in discovery UI. */
@@ -1,17 +1,18 @@
1
1
  ---
2
2
  editSource: "docs/subsystems/compaction.md"
3
+ rawMarkdownPath: "en/reference/subsystems/compaction.md"
3
4
  outline: [2,3]
4
5
  ---
5
6
 
6
7
  # Compaction
7
8
 
8
- The compaction seam — a [capability seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md) split like bash: Service Definition ([dsh-compaction](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction), `ctx.compaction`), Service Provider (a backend such as [dsh-compaction-basic](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction-basic)), and human Consumer ([dsh-command-compact](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/command-compact)). Compaction is **one optional capability**, not part of the agent-loop spine — so its vocabulary lives here, not in [core.md](./core.md). A tokenizer- or template-based backend is a sibling package implementing the same interface. Unlike bash, the interface necessarily depends on `dsh-session` and `dsh-llm`: its verbs act on an agent-owned `Session`, and its durable summary event uses the `ContentBlock` vocabulary (see the [compaction capability-seam Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.md)).
9
+ The compaction seam — a [capability seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md) split like bash: Service Definition ([dsh-compaction](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction), `ctx.compaction`), Service Provider (a backend such as [dsh-compaction-basic](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction-basic)), and human Consumer ([dsh-command-compact](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/command-compact)). Compaction is **one optional capability**, not part of the agent-loop spine — so its vocabulary lives here, not in [core.md](./core.md). A tokenizer- or template-based backend is a sibling package implementing the same interface. Unlike bash, the interface necessarily depends on `dsh-session` and `dsh-llm`: its verbs act on an agent-owned `Session`, and its durable summary event uses the `ContentBlock` vocabulary (see the [compaction capability-seam reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/README.md)).
9
10
 
10
11
  Source: [`packages/compaction/compaction/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/types.ts)
11
12
 
12
13
  ## The `compaction/*` session events
13
14
 
14
- Compaction extends [`SessionEventMap`](./session.md) with three event types via declaration merging. All three are **log-only** — they record the lock, summary, selected range, shadowed event seqs, token count, and model call without joining the surface. `SurfaceEventType` is deliberately NOT extended (only message-producing events reach the model), so the summary itself rides on a separate `user/message` with `surfaceOp: { op: 'replace', start, end }` — the only surface mutation performed by summary compaction. The [Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/feature/2026-06-18-compaction-capability-seam.md) owns the rationale for reusing `user/message`.
15
+ Compaction extends [`SessionEventMap`](./session.md) with three event types via declaration merging. All three are **log-only** — they record the lock, summary, selected range, shadowed event seqs, token count, and model call without joining the surface. `SurfaceEventType` is deliberately NOT extended (only message-producing events reach the model), so the summary itself rides on a separate `user/message` with `surfaceOp: { op: 'replace', startSeq, endSeq }` — the only surface mutation performed by summary compaction. The [historical Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/archived/feature/2026-06-18-compaction-capability-seam.md) records the rationale for reusing `user/message`.
15
16
 
16
17
  | Event | Payload | Role |
17
18
  |---|---|---|
@@ -25,6 +26,21 @@ The markers are lock time points, not an exclusive container. An unrelated idle
25
26
 
26
27
  These variants are merged inside a `declare module '@deepseek-ai/dsh-session/types'` block, so — unlike the top-level types on the other subsystem pages — they are not pasted as a drift-checked ` ```ts type-equiv ` block (the `verify-type-equiv` extractor matches only top-level declarations by name). The payload table above is the catalog entry; follow the source link for the authoritative fields.
27
28
 
29
+ <a id="image-offload"></a>
30
+ ## Image offload
31
+
32
+ `compaction-image-offload` owns the `image/offload` declaration and its pure message projection. Each target identifies a current input node and exact depth-first image occurrences. The event preserves node and message identities and carries no `surfaceOp`. The [package README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-image-offload/README.md) owns recovery policy, registration, and detached replay.
33
+
34
+ ```ts type-equiv
35
+ /** Exact input-image occurrences selected by one durable offload decision. */
36
+ interface ImageOffloadTarget {
37
+ /** Current message-producing event containing these occurrences. */
38
+ seq: SessionSeq
39
+ /** Zero-based depth-first image indexes within the immutable message. */
40
+ imageIndexes: number[]
41
+ }
42
+ ```
43
+
28
44
  ## `CompactionResult`
29
45
 
30
46
  What a successful compaction returns to its caller: the bookkeeping-event seqs, safe summary projection, shadowed range and seqs, and estimated token count.
@@ -84,7 +100,7 @@ type ManualCompactionErrorCode =
84
100
  | 'persistence'
85
101
  ```
86
102
 
87
- `changed` and `summary` leave the conversation surface unchanged but still close and persist the failed attempt in the log. `commit` may follow partial mutation; `persistence` means the in-memory bracket closed but its flush failed. Cancellation remains separate and throws the exact abort reason after required cleanup.
103
+ `changed` and `summary` close and persist the failed attempt without a summary replacement; image omissions recorded during recovery remain effective. `commit` may follow partial mutation; `persistence` means the in-memory bracket closed but its flush failed. Cancellation remains separate and throws the exact abort reason after required cleanup.
88
104
 
89
105
  Pressure compaction runs at the `agent/pre-step` waterfall before request derivation. Once pressure or canonical overflow qualifies, compaction-basic invokes optional [`ctx.toolResultPruner`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/README.md) before range selection, remeasures through `ctx.tokenMeter`, and can advance the surface without a summary. Failed-request recovery runs through `agent/request-error` after the failed step closes and returns a retry action only when the surface replacement generation advances, even if later summary work throws after pruning; cancellation still wins. Region boundaries preserve tool-call/result pairing but not whole turns, allowing early closed steps of one oversized turn to compact. `dsh-compaction-basic` owns thresholds, retained-tail policy, overflow caps, and failure handling.
90
106
 
@@ -238,4 +254,35 @@ pruneSession(session: Session): PruneResult
238
254
  Types: [ContentBlock](./llm-streaming.md) · [Session](./session.md)
239
255
 
240
256
  Source: [`packages/compaction/compaction-tool-result-pruner/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/src/index.ts)
257
+
258
+ <a id="compaction-events"></a>
259
+
260
+ ### `compaction/*` events
261
+
262
+ <a id="compactionsummary-error--waterfall"></a>
263
+
264
+ #### `compaction/summary-error` — waterfall
265
+
266
+ Recover a failed summary request by synchronously recording a durable change to its selected input. Return true only after making progress; the provider re-derives and re-prices the selection before retrying. Call next() when the failure cannot be recovered. Decisions survive a later summary failure or cancellation.
267
+
268
+ ```ts cordis-catalog
269
+ /**
270
+ * Recover a failed summary request by synchronously recording a durable
271
+ * change to its selected input. Return true only after making progress;
272
+ * the provider re-derives and re-prices the selection before retrying.
273
+ * Call next() when the failure cannot be recovered. Decisions survive a
274
+ * later summary failure or cancellation.
275
+ * @param payload.session - session containing the selected input.
276
+ * @param payload.sourceEventSeqs - selected message events in request order.
277
+ * @param payload.error - failure thrown by the summarizer.
278
+ * @param payload.signal - optional compaction cancellation signal.
279
+ * @param next - delegate to the next recovery listener.
280
+ * @mode waterfall
281
+ */
282
+ 'compaction/summary-error'(payload: { session: Session; sourceEventSeqs: readonly SessionSeq[]; error: unknown; signal?: AbortSignal }, next: () => boolean): boolean
283
+ ```
284
+
285
+ Types: [Session](./session.md) · [SessionSeq](./session.md)
286
+
287
+ Source: [`packages/compaction/compaction/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/index.ts)
241
288
  <!-- END GENERATED cordis-surface -->
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  editSource: "docs/subsystems/conversation.md"
3
+ rawMarkdownPath: "en/reference/subsystems/conversation.md"
3
4
  outline: [2,3]
4
5
  ---
5
6
 
@@ -16,9 +17,10 @@ The Session Controller owns the contiguous loaded logical-event window. Each `Se
16
17
  | Concept | Owner and purpose |
17
18
  |---|---|
18
19
  | Event Definition | A business package matches one durable or Client-only transient event at a time, correlates it by stable `(kind, id)`, folds deterministic State, and optionally materializes one target node. |
19
- | Context | The engine-owned ordered Matches and current State for one `(kind, id)`. A transient event occupies one update Match; update-only evidence may remain pending until pagination supplies its unique durable start. |
20
+ | Context | The engine-owned ordered Matches and current State for one `(kind, id)`. Durable and transient events may be starts. The earliest loaded start initializes State; later Matches update it. Update-only evidence stays pending until its start is loaded. |
20
21
  | Location | The engine-owned Session, Turn, or Step coordinates derived from durable boundary events. Definitions may publish typed data onto one Turn or Step. |
21
22
  | View Definition | A target package creates one incremental builder per Session and owns the final snapshot type for that target. |
23
+ | Group Definition | A business package derives one target's root references and group snapshots from materialized Nodes; it owns membership, segmentation, summaries, and incremental caches. |
22
24
  | View | A Slot entry such as Chat or Trajectory reads only its target snapshot and renders target-owned nodes. |
23
25
 
24
26
  Chat and Trajectory may recognize the same durable event family, but each keeps its own Definition State and final node payload. Shared target-neutral machinery is limited to identity routing, ordered replay, Location data, predecessor dependencies, and publication cadence.
@@ -27,7 +29,33 @@ Chat and Trajectory may recognize the same durable event family, but each keeps
27
29
 
28
30
  Each Session keeps a monotonic set of active targets. Creating or reading a target source does not activate it. The shell explicitly activates its persisted or newly selected View, while another consumer activates a target through its first source subscription. First activation creates that target's builder and calls `replace()` once from the current target-indexed Contexts. Later flushes call `apply()` for every active target, and unsubscription does not remove one.
29
31
 
30
- The shell owns View selection and resolves the registered preferred View or Chat fallback before rendering when a binding is created or selected as current, and after View-roster changes. The assembler receives only the resolved target id and does not select Chat or another default target. A third-party View participates through the same selection and activation operations.
32
+ The shell owns View selection and resolves the registered preferred View or Chat fallback before rendering when a binding is created or selected as current, and after View-roster changes. The assembler receives only the resolved target id and does not select Chat or another default target. A third-party View participates through the same selection and activation operations. A View Definition may expose `toolCallFocus(callId)`; the shell supplies Inspect only for a visible target that declares this capability, and the target maps the call id to its own focus identity.
33
+
34
+ <a id="group-definitions"></a>
35
+ ## Group Definitions
36
+
37
+ The optional `ctx.uiConversation.groups.register(definition)` contribution uses the same effect-owned registry lifecycle as event and view registrations. It requires an existing View target and rejects duplicate target registrations without constructing a Builder. Each Session creates its own Group context only when that target activates. Registration replacement discards the old context and clears its observed groups during the existing registry rebuild.
38
+
39
+ The [group types](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/ui-conversation/src/client/contract/groups.ts) define the complete protocol:
40
+
41
+ | Type | Meaning |
42
+ |---|---|
43
+ | `ConversationGroupDefinition<Node, State, Data>` | `create()` initializes Session-local State; `update(context, input)` returns its next State; `buildGroups(context)` returns pending output or `null`. Replacement input requires entries and a complete group replacement. |
44
+ | `ConversationGroupInput<Node>` | `replace` supplies target order, timeline, and synchronous `readNode`, `readTurn`, and `readPosition` readers. `apply` adds projected `previous/current` Node changes, lifecycle `changedTurns`, and `changedTurnOrders`. Do not retain readers in State. |
45
+ | `GroupNodePosition` | Owning Turn, when present, and immediate previous/next visible Node keys. Neighbours preserve interruptions that a Turn-only key list omits. |
46
+ | `NodeReference` / `GroupReference` | Branded `NodeKey` or `GroupKey`, distinguished by `kind`. A Node reference may select a renderer-owned `groupPart`; omission selects the whole Node. |
47
+ | `GroupSnapshot<Data>` | Immutable group key, business data, and ordered Node references. Groups cannot contain other groups or own source Node data. |
48
+ | `GroupUpdate<Data>` | `entries` replaces the complete root sequence; only apply input may omit it to preserve the sequence. Replacement input requires both `entries` and `groups.replace`. `groups.replace.snapshots` replaces all groups; `groups.apply.upserts/removes` updates only named group records. Removal does not delete Nodes. |
49
+ | `ConversationGroupDataMap` | Declaration-merged target-to-data association shared by registration and `views.grouped(target)`. Undeclared targets have no group payload type. |
50
+ | `ConversationGroupedView<Data>` | Stable root `entries` and keyed `groupSource(key)` readers; a removed group reads as `undefined`. |
51
+
52
+ The Builder exposes `groupInput()` when grouping is registered; missing input fails at first activation. It records the Node values after its own projections and preserves content-only order identity. The assembler supplies changed Turns with every update; direct ungrouped Builder callers may omit them. Builders with independent sources defer their notifications to `publish()`. First activation and ordinary flush share the same sequence: materialize Location data and Nodes, update the Builder, call the Group Definition, validate and install grouping, then publish every affected target and Location source. The group phase reuses the existing publication cadence.
53
+
54
+ Target position indexes supply the readers and identify Turns whose visible keys or neighbours changed. `changedTurnOrders` includes both owners of a moved Node and Turns adjacent to inserted or removed unscoped Nodes; lifecycle-only changes remain in `changedTurns`. A business Definition can resegment those Turns and refresh only groups containing changed content. Structural output still replaces the complete root-reference array, without requiring unchanged Node contents to be reread.
55
+
56
+ The Group store validates the whole submitted result before installation: root Group references and records correspond one-to-one, all referenced Nodes exist, and each `(NodeKey, groupPart)` occupies at most one root or member position. A whole Node cannot coexist with one of its parts. Duplicate upserts, duplicate removals, and simultaneous upsert/removal of a group fail. Data-only upserts retain root and member arrays, do not read Nodes, and notify only changed group sources; full replacement revalidates every reference.
57
+
58
+ Renderers switch on the two reference kinds and choose components in the owning View, not through a renderer field in group data. Root Node references and referenced group members form the complete render list; unreferenced target Nodes remain stored but do not render. The group body reads members separately from summary data. Presentation modes must retain component types, keys, and member parents; changing data membership may legitimately remount a moved member. The framework does not interpret part completeness, segmentation, or presentation policies.
31
59
 
32
60
  ## Replayable event families
33
61
 
@@ -45,7 +73,7 @@ Use the producer-owned branded id type across the process boundary. Put the `Ses
45
73
 
46
74
  Incremental events are supported. Prefer whole-value checkpoints when the producer can emit them cheaply, because they remain useful when the start is outside the loaded window. Each delta must carry the stable id and produce deterministic State when replayed in ascending log `seq`; it must not depend on live-only memory. If the current history window contains only updates, the assembler keeps a pending Context and builds no State until an older page supplies the start. If the product must render before the start is loaded, a terminal or checkpoint event must carry enough whole fallback state for the Definition to build that result directly; do not recover it by scanning unrelated events.
47
75
 
48
- Live Assistant deltas arrive as Client-only `assistant/live-chunk` updates. Reconnect baselines expand the active process-local compact stream into the same transient events, while durable `assistant/message` and `assistant/attempt` events embed complete compact streams for history replay. Transient events can only be updates; `start()` receives a standard `SessionEvent`. A Definition that consumes Assistant output handles live chunks and durable settlements in the same `match()` and `update()` methods, while unrelated Definitions return `null` without expanding a stream.
76
+ Live Assistant deltas arrive as Client-only `assistant/live-chunk` events. Reconnect baselines expand the active process-local compact stream into the same transient events, while durable `assistant/message` and `assistant/attempt` events embed complete compact streams for history replay. A transient event may initialize a Context. Every tool delta and its later `tool/call` can match as start under the same callId, even before the name arrives; only the earliest calls `start()`, and later Matches call `update()`. A preparing Tool node becomes visible only after its name is available. Historical pages do not expand settled messages into live deltas. A Definition that consumes Assistant output handles live chunks and durable settlements through the same matching and update interfaces, while unrelated Definitions return `null` without expanding a stream.
49
77
 
50
78
  ## Definition and typed Chat payload
51
79
 
@@ -219,11 +247,13 @@ export function apply(ctx: ClientContext): void {
219
247
  }
220
248
  ```
221
249
 
222
- `match(event)` is an identity extractor, not a fold: it receives only the current `SessionEventLike` and returns the Definition-local id and lifecycle role. After a match, the assembler locates the Context by `(kind, id)` and calls `start` once for a standard event or `update` for a standard or packed event. Both functions return the State that the engine adopts; returning a new immutable value is preferred, but a function that mutates and returns the same object has the same adoption semantics.
250
+ `match(event)` is an identity extractor, not a fold: it receives only the current `SessionEventLike` and returns the Definition-local id and lifecycle role. After a match, the assembler locates the Context by `(kind, id)` and initializes from its earliest loaded start, whether durable or transient. Every later Match calls `update`, including another start. Removing transient Matches reselects the start from remaining evidence and recomputes State; no remaining start leaves State undefined. Both functions return the State that the engine adopts; returning a new immutable value is preferred, but a function that mutates and returns the same object has the same adoption semantics.
251
+
252
+ `ConversationNodeDefinitionInput` accepts either this function or a read-only table from event type to matching function. Function-form registrations receive every event; table registrations receive only their listed types. The Registry copies table entries and precomputes ordered candidate Sets when registrations change, keeping candidate construction out of per-event dispatch. Replace a table by unregistering and registering again. Resolved `ConversationNodeDefinition` values retain a callable `match(event)` in both cases.
223
253
 
224
254
  `buildLocationData(context, scope)` optionally publishes Definition-owned data onto an engine-owned Turn or Step. Use declaration merging to give each key a precise value type. Another Node in the same Location can consume that value through its constrained slot hook, such as `useTurnData(key)`, without receiving the Session or scanning `snapshot.chat.nodes`.
225
255
 
226
- `target` and `buildViewNode(context)` declare one target-owned rendering contribution and must appear together. Preserve `context.key` as the React-facing identity, choose `anchorSeq` from durable ordering evidence, and return only renderer-ready data. Once a target Node has been published, keep returning the same key; use `visibility: 'hidden'` when it must temporarily leave the visible flow rather than withdrawing it with `null`.
256
+ `target` and `buildViewNode(context)` declare one target-owned rendering contribution and must appear together. Preserve `context.key` as the React-facing identity, choose `anchorSeq` from the matched event ordering, and return only renderer-ready data. Once a target Node has been published, keep returning the same key; use `visibility: 'hidden'` when it must temporarily leave the visible flow rather than withdrawing it with `null`.
227
257
 
228
258
  ## Predecessor reads
229
259
 
@@ -250,7 +280,7 @@ With `D` registered Definitions, one incoming scalar event or packed run perform
250
280
  Add focused tests that establish these outcomes:
251
281
 
252
282
  1. A complete window passed through replace produces the expected final State, Location data, Node payload, and `anchorSeq`.
253
- 2. An update-only tail stays pending; prepending the unique start produces the same result as a complete replace.
283
+ 2. An update-only tail stays pending; prepending its start produces the same result as a complete replace.
254
284
  3. Initial history followed by live append produces the same result as replaying the combined window.
255
285
  4. Prepending an older page adds earlier rows without replacing existing keyed Node values whose data did not change.
256
286
  5. Repeated visible deltas preserve `context.key` and publish at most once per animation frame when requested.