dsh-plugin-guide 0.3.1 → 0.3.2

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/README.es.md +1 -1
  2. package/README.hi.md +1 -1
  3. package/README.md +1 -1
  4. package/README.pt.md +1 -1
  5. package/README.zh.md +1 -1
  6. package/SKILL.md +1 -1
  7. package/dist/dsh-plugin-dev.js +5 -5
  8. package/guide/links.md +1 -1
  9. package/guide/plugin-dev-guide.md +1 -1
  10. package/guide/quick-reference.es.md +2 -2
  11. package/guide/quick-reference.hi.md +1 -1
  12. package/guide/quick-reference.md +2 -2
  13. package/guide/quick-reference.pt.md +2 -2
  14. package/guide/quick-reference.zh-CN.md +2 -2
  15. package/package.json +3 -3
  16. package/references/cordis-paper-and-community.md +1 -1
  17. package/references/official-docs/AGENTS.md +27 -22
  18. package/references/official-docs/README.i18n.yaml +2 -2
  19. package/references/official-docs/README.md +1 -1
  20. package/references/official-docs/README.zh.md +19 -9
  21. package/references/official-docs/SNAPSHOT.md +5 -5
  22. package/references/official-docs/THIRD_PARTY_NOTICES.md +36 -13
  23. package/references/official-docs/docs/AGENTS.md +4 -4
  24. package/references/official-docs/docs/agent-lifecycle.i18n.yaml +2 -2
  25. package/references/official-docs/docs/agent-lifecycle.md +1 -1
  26. package/references/official-docs/docs/agent-lifecycle.zh.md +2 -2
  27. package/references/official-docs/docs/api-gateway.i18n.yaml +2 -2
  28. package/references/official-docs/docs/api-gateway.md +8 -8
  29. package/references/official-docs/docs/api-gateway.zh.md +8 -8
  30. package/references/official-docs/docs/architecture.i18n.yaml +2 -2
  31. package/references/official-docs/docs/architecture.md +23 -7
  32. package/references/official-docs/docs/architecture.zh.md +36 -20
  33. package/references/official-docs/docs/capability-seams.i18n.yaml +2 -2
  34. package/references/official-docs/docs/capability-seams.md +132 -67
  35. package/references/official-docs/docs/capability-seams.zh.md +132 -67
  36. package/references/official-docs/docs/config-catalog.i18n.yaml +2 -2
  37. package/references/official-docs/docs/config-catalog.md +659 -373
  38. package/references/official-docs/docs/config-catalog.zh.md +677 -391
  39. package/references/official-docs/docs/cookbook/adding-a-package.i18n.yaml +2 -2
  40. package/references/official-docs/docs/cookbook/adding-a-package.md +2 -3
  41. package/references/official-docs/docs/cookbook/adding-a-package.zh.md +8 -7
  42. package/references/official-docs/docs/cookbook/{adding-a-conversation-node.i18n.yaml → adding-a-remote-api.i18n.yaml} +3 -3
  43. package/references/official-docs/docs/cookbook/adding-a-remote-api.md +197 -0
  44. package/references/official-docs/docs/cookbook/adding-a-remote-api.zh.md +197 -0
  45. package/references/official-docs/docs/cookbook/adding-a-settings-card.i18n.yaml +6 -0
  46. package/references/official-docs/docs/cookbook/adding-a-settings-card.md +102 -0
  47. package/references/official-docs/docs/cookbook/adding-a-settings-card.zh.md +102 -0
  48. package/references/official-docs/docs/cookbook/adding-a-tool.i18n.yaml +2 -2
  49. package/references/official-docs/docs/cookbook/adding-a-tool.md +11 -4
  50. package/references/official-docs/docs/cookbook/adding-a-tool.zh.md +16 -9
  51. package/references/official-docs/docs/cookbook/adding-a-vendored-package.i18n.yaml +2 -2
  52. package/references/official-docs/docs/cookbook/adding-a-vendored-package.md +2 -2
  53. package/references/official-docs/docs/cookbook/adding-a-vendored-package.zh.md +4 -4
  54. package/references/official-docs/docs/cookbook/adding-an-llm-adapter.i18n.yaml +2 -2
  55. package/references/official-docs/docs/cookbook/adding-an-llm-adapter.md +1 -1
  56. package/references/official-docs/docs/cookbook/adding-an-llm-adapter.zh.md +3 -3
  57. package/references/official-docs/docs/cookbook/extension-cookbook.i18n.yaml +2 -2
  58. package/references/official-docs/docs/cookbook/extension-cookbook.md +9 -8
  59. package/references/official-docs/docs/cookbook/extension-cookbook.zh.md +17 -14
  60. package/references/official-docs/docs/cookbook/maintaining-dsh-code-review.i18n.yaml +1 -1
  61. package/references/official-docs/docs/cookbook/maintaining-dsh-code-review.zh.md +1 -1
  62. package/references/official-docs/docs/cookbook/responding-to-pr-review-on-a-stack.i18n.yaml +1 -1
  63. package/references/official-docs/docs/cookbook/responding-to-pr-review-on-a-stack.zh.md +1 -1
  64. package/references/official-docs/docs/cordis-api/context.i18n.yaml +1 -1
  65. package/references/official-docs/docs/cordis-api/context.zh.md +1 -1
  66. package/references/official-docs/docs/cordis-api/events.i18n.yaml +1 -1
  67. package/references/official-docs/docs/cordis-api/events.zh.md +1 -1
  68. package/references/official-docs/docs/cordis-api/inherited.md +1 -1
  69. package/references/official-docs/docs/cordis-primer.i18n.yaml +2 -2
  70. package/references/official-docs/docs/cordis-primer.md +2 -1
  71. package/references/official-docs/docs/cordis-primer.zh.md +3 -2
  72. package/references/official-docs/docs/cordis-tutorial/01-first-plugin.i18n.yaml +1 -1
  73. package/references/official-docs/docs/cordis-tutorial/01-first-plugin.zh.md +4 -4
  74. package/references/official-docs/docs/cordis-tutorial/02-lifecycle-and-effects.i18n.yaml +1 -1
  75. package/references/official-docs/docs/cordis-tutorial/02-lifecycle-and-effects.zh.md +4 -4
  76. package/references/official-docs/docs/cordis-tutorial/03-services.i18n.yaml +1 -1
  77. package/references/official-docs/docs/cordis-tutorial/03-services.zh.md +4 -4
  78. package/references/official-docs/docs/cordis-tutorial/04-events.i18n.yaml +1 -1
  79. package/references/official-docs/docs/cordis-tutorial/04-events.zh.md +4 -4
  80. package/references/official-docs/docs/cordis-tutorial/05-config.i18n.yaml +1 -1
  81. package/references/official-docs/docs/cordis-tutorial/05-config.zh.md +2 -2
  82. package/references/official-docs/docs/cordis-tutorial/06-composition-and-hmr.i18n.yaml +1 -1
  83. package/references/official-docs/docs/cordis-tutorial/06-composition-and-hmr.zh.md +3 -3
  84. package/references/official-docs/docs/cordis-tutorial/07-into-the-harness.i18n.yaml +2 -2
  85. package/references/official-docs/docs/cordis-tutorial/07-into-the-harness.md +5 -4
  86. package/references/official-docs/docs/cordis-tutorial/07-into-the-harness.zh.md +11 -10
  87. package/references/official-docs/docs/cordis-tutorial/index.i18n.yaml +1 -1
  88. package/references/official-docs/docs/cordis-tutorial/index.zh.md +10 -10
  89. package/references/official-docs/docs/deepseek-llm-api-wire-extensions.i18n.yaml +6 -0
  90. package/references/official-docs/docs/deepseek-llm-api-wire-extensions.md +159 -0
  91. package/references/official-docs/docs/deepseek-llm-api-wire-extensions.zh.md +159 -0
  92. package/references/official-docs/docs/defensive-patterns.i18n.yaml +1 -1
  93. package/references/official-docs/docs/defensive-patterns.zh.md +3 -1
  94. package/references/official-docs/docs/development.i18n.yaml +2 -2
  95. package/references/official-docs/docs/development.md +9 -13
  96. package/references/official-docs/docs/development.zh.md +23 -21
  97. package/references/official-docs/docs/event-producer-consumer.i18n.yaml +2 -2
  98. package/references/official-docs/docs/event-producer-consumer.md +55 -46
  99. package/references/official-docs/docs/event-producer-consumer.zh.md +55 -46
  100. package/references/official-docs/docs/glossary.i18n.yaml +2 -2
  101. package/references/official-docs/docs/glossary.md +1 -1
  102. package/references/official-docs/docs/glossary.zh.md +1 -1
  103. package/references/official-docs/docs/graph-atlas.i18n.yaml +2 -2
  104. package/references/official-docs/docs/graph-atlas.md +0 -2
  105. package/references/official-docs/docs/graph-atlas.zh.md +7 -9
  106. package/references/official-docs/docs/i18n/README.i18n.yaml +2 -2
  107. package/references/official-docs/docs/i18n/README.md +7 -7
  108. package/references/official-docs/docs/i18n/README.zh.md +11 -9
  109. package/references/official-docs/docs/i18n/style-samples.md +3 -3
  110. package/references/official-docs/docs/i18n/translation-prompt.md +3 -3
  111. package/references/official-docs/docs/i18n/translation-rules.i18n.yaml +2 -2
  112. package/references/official-docs/docs/i18n/translation-rules.md +2 -2
  113. package/references/official-docs/docs/i18n/translation-rules.zh.md +3 -3
  114. package/references/official-docs/docs/module-graph.i18n.yaml +2 -2
  115. package/references/official-docs/docs/module-graph.md +666 -747
  116. package/references/official-docs/docs/module-graph.zh.md +668 -749
  117. package/references/official-docs/docs/persistence-catalog.i18n.yaml +2 -2
  118. package/references/official-docs/docs/persistence-catalog.md +172 -40
  119. package/references/official-docs/docs/persistence-catalog.zh.md +180 -48
  120. package/references/official-docs/docs/postmortem/0001-acp-default-export-drops-inject.i18n.yaml +2 -2
  121. package/references/official-docs/docs/postmortem/0001-acp-default-export-drops-inject.md +2 -2
  122. package/references/official-docs/docs/postmortem/0001-acp-default-export-drops-inject.zh.md +3 -3
  123. package/references/official-docs/docs/postmortem/0002-js-expression-disabled-filesystem-tools.i18n.yaml +2 -2
  124. package/references/official-docs/docs/postmortem/0002-js-expression-disabled-filesystem-tools.md +2 -2
  125. package/references/official-docs/docs/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +2 -2
  126. package/references/official-docs/docs/postmortem/0003-web-agent-gui-feedback-loop.i18n.yaml +2 -2
  127. package/references/official-docs/docs/postmortem/0003-web-agent-gui-feedback-loop.md +2 -2
  128. package/references/official-docs/docs/postmortem/0003-web-agent-gui-feedback-loop.zh.md +2 -2
  129. package/references/official-docs/docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.i18n.yaml +2 -2
  130. package/references/official-docs/docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +1 -1
  131. package/references/official-docs/docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +2 -2
  132. package/references/official-docs/docs/postmortem/README.i18n.yaml +1 -1
  133. package/references/official-docs/docs/postmortem/README.zh.md +5 -5
  134. package/references/official-docs/docs/rescope.i18n.yaml +2 -2
  135. package/references/official-docs/docs/rescope.md +2 -2
  136. package/references/official-docs/docs/rescope.zh.md +3 -3
  137. package/references/official-docs/docs/subsystems/README.i18n.yaml +2 -2
  138. package/references/official-docs/docs/subsystems/README.md +8 -2
  139. package/references/official-docs/docs/subsystems/README.zh.md +53 -47
  140. package/references/official-docs/docs/subsystems/agent-team.i18n.yaml +6 -0
  141. package/references/official-docs/docs/subsystems/agent-team.md +206 -0
  142. package/references/official-docs/docs/subsystems/agent-team.zh.md +206 -0
  143. package/references/official-docs/docs/subsystems/approval.i18n.yaml +2 -2
  144. package/references/official-docs/docs/subsystems/approval.md +12 -12
  145. package/references/official-docs/docs/subsystems/approval.zh.md +13 -13
  146. package/references/official-docs/docs/subsystems/attachment.i18n.yaml +2 -2
  147. package/references/official-docs/docs/subsystems/attachment.md +90 -7
  148. package/references/official-docs/docs/subsystems/attachment.zh.md +90 -7
  149. package/references/official-docs/docs/subsystems/client-modules.i18n.yaml +2 -2
  150. package/references/official-docs/docs/subsystems/client-modules.md +69 -19
  151. package/references/official-docs/docs/subsystems/client-modules.zh.md +69 -19
  152. package/references/official-docs/docs/subsystems/code-runtime.i18n.yaml +2 -2
  153. package/references/official-docs/docs/subsystems/code-runtime.md +5 -5
  154. package/references/official-docs/docs/subsystems/code-runtime.zh.md +6 -6
  155. package/references/official-docs/docs/subsystems/commands.i18n.yaml +2 -2
  156. package/references/official-docs/docs/subsystems/commands.md +29 -6
  157. package/references/official-docs/docs/subsystems/commands.zh.md +30 -7
  158. package/references/official-docs/docs/subsystems/compaction.i18n.yaml +2 -2
  159. package/references/official-docs/docs/subsystems/compaction.md +5 -5
  160. package/references/official-docs/docs/subsystems/compaction.zh.md +11 -11
  161. package/references/official-docs/docs/subsystems/conversation.i18n.yaml +6 -0
  162. package/references/official-docs/docs/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +49 -24
  163. package/references/official-docs/docs/{cookbook/adding-a-conversation-node.zh.md → subsystems/conversation.zh.md} +49 -24
  164. package/references/official-docs/docs/subsystems/core.i18n.yaml +2 -2
  165. package/references/official-docs/docs/subsystems/core.md +110 -33
  166. package/references/official-docs/docs/subsystems/core.zh.md +141 -62
  167. package/references/official-docs/docs/subsystems/credentials.i18n.yaml +2 -2
  168. package/references/official-docs/docs/subsystems/credentials.md +207 -11
  169. package/references/official-docs/docs/subsystems/credentials.zh.md +207 -11
  170. package/references/official-docs/docs/subsystems/extensions.i18n.yaml +2 -2
  171. package/references/official-docs/docs/subsystems/extensions.md +27 -9
  172. package/references/official-docs/docs/subsystems/extensions.zh.md +30 -12
  173. package/references/official-docs/docs/subsystems/feedback.i18n.yaml +2 -2
  174. package/references/official-docs/docs/subsystems/feedback.md +4 -4
  175. package/references/official-docs/docs/subsystems/feedback.zh.md +4 -4
  176. package/references/official-docs/docs/subsystems/filesystem.i18n.yaml +2 -2
  177. package/references/official-docs/docs/subsystems/filesystem.md +17 -7
  178. package/references/official-docs/docs/subsystems/filesystem.zh.md +19 -9
  179. package/references/official-docs/docs/subsystems/goal.i18n.yaml +2 -2
  180. package/references/official-docs/docs/subsystems/goal.md +4 -4
  181. package/references/official-docs/docs/subsystems/goal.zh.md +8 -8
  182. package/references/official-docs/docs/subsystems/invariants.i18n.yaml +2 -2
  183. package/references/official-docs/docs/subsystems/invariants.md +2 -2
  184. package/references/official-docs/docs/subsystems/invariants.zh.md +5 -5
  185. package/references/official-docs/docs/subsystems/jobs.i18n.yaml +2 -2
  186. package/references/official-docs/docs/subsystems/jobs.md +3 -3
  187. package/references/official-docs/docs/subsystems/jobs.zh.md +6 -6
  188. package/references/official-docs/docs/subsystems/llm-streaming.i18n.yaml +2 -2
  189. package/references/official-docs/docs/subsystems/llm-streaming.md +193 -22
  190. package/references/official-docs/docs/subsystems/llm-streaming.zh.md +199 -28
  191. package/references/official-docs/docs/subsystems/lsp.i18n.yaml +2 -2
  192. package/references/official-docs/docs/subsystems/lsp.md +2 -2
  193. package/references/official-docs/docs/subsystems/lsp.zh.md +3 -3
  194. package/references/official-docs/docs/subsystems/permission-presets.i18n.yaml +2 -2
  195. package/references/official-docs/docs/subsystems/permission-presets.md +8 -8
  196. package/references/official-docs/docs/subsystems/permission-presets.zh.md +8 -8
  197. package/references/official-docs/docs/subsystems/persistence.i18n.yaml +2 -2
  198. package/references/official-docs/docs/subsystems/persistence.md +35 -17
  199. package/references/official-docs/docs/subsystems/persistence.zh.md +38 -20
  200. package/references/official-docs/docs/subsystems/plan.i18n.yaml +2 -2
  201. package/references/official-docs/docs/subsystems/plan.md +4 -4
  202. package/references/official-docs/docs/subsystems/plan.zh.md +10 -10
  203. package/references/official-docs/docs/subsystems/sandbox.i18n.yaml +2 -2
  204. package/references/official-docs/docs/subsystems/sandbox.md +5 -3
  205. package/references/official-docs/docs/subsystems/sandbox.zh.md +8 -6
  206. package/references/official-docs/docs/subsystems/schedule.i18n.yaml +2 -2
  207. package/references/official-docs/docs/subsystems/schedule.md +9 -3
  208. package/references/official-docs/docs/subsystems/schedule.zh.md +11 -5
  209. package/references/official-docs/docs/subsystems/scope.i18n.yaml +1 -1
  210. package/references/official-docs/docs/subsystems/scope.zh.md +1 -1
  211. package/references/official-docs/docs/subsystems/session-projection.i18n.yaml +2 -2
  212. package/references/official-docs/docs/subsystems/session-projection.md +136 -67
  213. package/references/official-docs/docs/subsystems/session-projection.zh.md +136 -67
  214. package/references/official-docs/docs/subsystems/session-query.i18n.yaml +2 -2
  215. package/references/official-docs/docs/subsystems/session-query.md +11 -3
  216. package/references/official-docs/docs/subsystems/session-query.zh.md +12 -4
  217. package/references/official-docs/docs/subsystems/session-reference.i18n.yaml +2 -2
  218. package/references/official-docs/docs/subsystems/session-reference.md +94 -7
  219. package/references/official-docs/docs/subsystems/session-reference.zh.md +95 -8
  220. package/references/official-docs/docs/subsystems/session-telemetry.i18n.yaml +2 -2
  221. package/references/official-docs/docs/subsystems/session-telemetry.md +5 -6
  222. package/references/official-docs/docs/subsystems/session-telemetry.zh.md +9 -10
  223. package/references/official-docs/docs/subsystems/session-title.i18n.yaml +2 -2
  224. package/references/official-docs/docs/subsystems/session-title.md +3 -3
  225. package/references/official-docs/docs/subsystems/session-title.zh.md +5 -5
  226. package/references/official-docs/docs/subsystems/session.i18n.yaml +2 -2
  227. package/references/official-docs/docs/subsystems/session.md +284 -39
  228. package/references/official-docs/docs/subsystems/session.zh.md +301 -54
  229. package/references/official-docs/docs/subsystems/settings.i18n.yaml +2 -2
  230. package/references/official-docs/docs/subsystems/settings.md +105 -10
  231. package/references/official-docs/docs/subsystems/settings.zh.md +105 -10
  232. package/references/official-docs/docs/subsystems/shell.i18n.yaml +2 -2
  233. package/references/official-docs/docs/subsystems/shell.md +3 -3
  234. package/references/official-docs/docs/subsystems/shell.zh.md +11 -11
  235. package/references/official-docs/docs/subsystems/skills.i18n.yaml +2 -2
  236. package/references/official-docs/docs/subsystems/skills.md +26 -3
  237. package/references/official-docs/docs/subsystems/skills.zh.md +29 -6
  238. package/references/official-docs/docs/subsystems/slots.i18n.yaml +6 -0
  239. package/references/official-docs/docs/subsystems/slots.md +174 -0
  240. package/references/official-docs/docs/subsystems/slots.zh.md +174 -0
  241. package/references/official-docs/docs/subsystems/spill.i18n.yaml +2 -2
  242. package/references/official-docs/docs/subsystems/spill.md +4 -4
  243. package/references/official-docs/docs/subsystems/spill.zh.md +6 -6
  244. package/references/official-docs/docs/subsystems/storage.i18n.yaml +2 -2
  245. package/references/official-docs/docs/subsystems/storage.md +13 -5
  246. package/references/official-docs/docs/subsystems/storage.zh.md +16 -8
  247. package/references/official-docs/docs/subsystems/subagent.i18n.yaml +2 -2
  248. package/references/official-docs/docs/subsystems/subagent.md +120 -32
  249. package/references/official-docs/docs/subsystems/subagent.zh.md +131 -41
  250. package/references/official-docs/docs/subsystems/subprocess.i18n.yaml +2 -2
  251. package/references/official-docs/docs/subsystems/subprocess.md +3 -3
  252. package/references/official-docs/docs/subsystems/subprocess.zh.md +5 -5
  253. package/references/official-docs/docs/subsystems/system-prompt.i18n.yaml +2 -2
  254. package/references/official-docs/docs/subsystems/system-prompt.md +21 -8
  255. package/references/official-docs/docs/subsystems/system-prompt.zh.md +23 -10
  256. package/references/official-docs/docs/subsystems/terminal.i18n.yaml +2 -2
  257. package/references/official-docs/docs/subsystems/terminal.md +2 -2
  258. package/references/official-docs/docs/subsystems/terminal.zh.md +4 -4
  259. package/references/official-docs/docs/subsystems/todo.i18n.yaml +6 -0
  260. package/references/official-docs/docs/subsystems/todo.md +32 -0
  261. package/references/official-docs/docs/subsystems/todo.zh.md +32 -0
  262. package/references/official-docs/docs/subsystems/token-meter.i18n.yaml +2 -2
  263. package/references/official-docs/docs/subsystems/token-meter.md +27 -12
  264. package/references/official-docs/docs/subsystems/token-meter.zh.md +28 -13
  265. package/references/official-docs/docs/subsystems/tools.i18n.yaml +2 -2
  266. package/references/official-docs/docs/subsystems/tools.md +46 -46
  267. package/references/official-docs/docs/subsystems/tools.zh.md +54 -54
  268. package/references/official-docs/docs/subsystems/typert.i18n.yaml +2 -2
  269. package/references/official-docs/docs/subsystems/typert.md +65 -58
  270. package/references/official-docs/docs/subsystems/typert.zh.md +67 -60
  271. package/references/official-docs/docs/subsystems/user-questions.i18n.yaml +2 -2
  272. package/references/official-docs/docs/subsystems/user-questions.md +35 -35
  273. package/references/official-docs/docs/subsystems/user-questions.zh.md +35 -35
  274. package/references/official-docs/docs/subsystems/web-client.i18n.yaml +6 -0
  275. package/references/official-docs/docs/subsystems/web-client.md +95 -0
  276. package/references/official-docs/docs/subsystems/web-client.zh.md +95 -0
  277. package/references/official-docs/docs/subsystems/web-server.i18n.yaml +2 -2
  278. package/references/official-docs/docs/subsystems/web-server.md +55 -9
  279. package/references/official-docs/docs/subsystems/web-server.zh.md +56 -10
  280. package/references/official-docs/docs/subsystems/web.i18n.yaml +2 -2
  281. package/references/official-docs/docs/subsystems/web.md +14 -7
  282. package/references/official-docs/docs/subsystems/web.zh.md +16 -9
  283. package/references/official-docs/docs/subsystems/webhook.i18n.yaml +6 -0
  284. package/references/official-docs/docs/subsystems/webhook.md +70 -0
  285. package/references/official-docs/docs/subsystems/webhook.zh.md +70 -0
  286. package/references/official-docs/docs/subsystems/workflow.i18n.yaml +2 -2
  287. package/references/official-docs/docs/subsystems/workflow.md +8 -8
  288. package/references/official-docs/docs/subsystems/workflow.zh.md +13 -13
  289. package/references/official-docs/docs/subsystems/workspace.i18n.yaml +2 -2
  290. package/references/official-docs/docs/subsystems/workspace.md +98 -5
  291. package/references/official-docs/docs/subsystems/workspace.zh.md +102 -9
  292. package/references/official-docs/docs/testing.i18n.yaml +2 -2
  293. package/references/official-docs/docs/testing.md +15 -10
  294. package/references/official-docs/docs/testing.zh.md +15 -10
  295. package/references/official-docs/docs/tool-catalog.i18n.yaml +2 -2
  296. package/references/official-docs/docs/tool-catalog.md +433 -27
  297. package/references/official-docs/docs/tool-catalog.zh.md +438 -29
  298. package/references/official-docs/docs/tool-execution-pipeline.i18n.yaml +2 -2
  299. package/references/official-docs/docs/tool-execution-pipeline.md +1 -1
  300. package/references/official-docs/docs/tool-execution-pipeline.zh.md +1 -1
  301. package/references/official-docs/docs/user/develop/basic/config.i18n.yaml +2 -2
  302. package/references/official-docs/docs/user/develop/basic/config.md +1 -1
  303. package/references/official-docs/docs/user/develop/basic/config.zh.md +4 -4
  304. package/references/official-docs/docs/user/develop/basic/index.i18n.yaml +1 -1
  305. package/references/official-docs/docs/user/develop/basic/index.zh.md +5 -5
  306. package/references/official-docs/docs/user/develop/basic/publish.i18n.yaml +2 -2
  307. package/references/official-docs/docs/user/develop/basic/publish.md +3 -3
  308. package/references/official-docs/docs/user/develop/basic/publish.zh.md +7 -7
  309. package/references/official-docs/docs/user/develop/basic/tool.i18n.yaml +2 -2
  310. package/references/official-docs/docs/user/develop/basic/tool.md +3 -3
  311. package/references/official-docs/docs/user/develop/basic/tool.zh.md +4 -4
  312. package/references/official-docs/docs/user/develop/framework/events.i18n.yaml +2 -2
  313. package/references/official-docs/docs/user/develop/framework/events.md +2 -2
  314. package/references/official-docs/docs/user/develop/framework/events.zh.md +3 -3
  315. package/references/official-docs/docs/user/develop/framework/index.i18n.yaml +1 -1
  316. package/references/official-docs/docs/user/develop/framework/index.zh.md +3 -3
  317. package/references/official-docs/docs/user/develop/framework/service.i18n.yaml +2 -2
  318. package/references/official-docs/docs/user/develop/framework/service.md +1 -1
  319. package/references/official-docs/docs/user/develop/framework/service.zh.md +3 -3
  320. package/references/official-docs/docs/user/develop/practice/dynamic-cordis.i18n.yaml +6 -0
  321. package/references/official-docs/docs/user/develop/practice/dynamic-cordis.md +15 -0
  322. package/references/official-docs/docs/user/develop/practice/dynamic-cordis.zh.md +15 -0
  323. package/references/official-docs/docs/user/develop/practice/index.i18n.yaml +2 -2
  324. package/references/official-docs/docs/user/develop/practice/index.md +1 -1
  325. package/references/official-docs/docs/user/develop/practice/index.zh.md +3 -3
  326. package/references/official-docs/docs/user/develop/practice/llm-adapter.i18n.yaml +2 -2
  327. package/references/official-docs/docs/user/develop/practice/llm-adapter.md +4 -3
  328. package/references/official-docs/docs/user/develop/practice/llm-adapter.zh.md +4 -3
  329. package/references/official-docs/docs/user/guide/github-review.i18n.yaml +6 -0
  330. package/references/official-docs/docs/user/guide/github-review.md +102 -0
  331. package/references/official-docs/docs/user/guide/github-review.zh.md +102 -0
  332. package/references/official-docs/docs/user/guide/index.i18n.yaml +2 -2
  333. package/references/official-docs/docs/user/guide/index.md +2 -2
  334. package/references/official-docs/docs/user/guide/index.zh.md +8 -8
  335. package/references/official-docs/docs/user/guide/mcp-memory.i18n.yaml +6 -0
  336. package/references/official-docs/docs/user/guide/mcp-memory.md +101 -0
  337. package/references/official-docs/docs/user/guide/mcp-memory.zh.md +101 -0
  338. package/references/official-docs/docs/user/guide/providers.i18n.yaml +2 -2
  339. package/references/official-docs/docs/user/guide/providers.md +40 -1
  340. package/references/official-docs/docs/user/guide/providers.zh.md +41 -2
  341. package/references/official-docs/docs/user/guide/python-sdk.i18n.yaml +2 -2
  342. package/references/official-docs/docs/user/guide/python-sdk.md +80 -34
  343. package/references/official-docs/docs/user/guide/python-sdk.zh.md +87 -41
  344. package/references/official-docs/docs/user/guide/schedule.i18n.yaml +6 -0
  345. package/references/official-docs/docs/user/guide/schedule.md +21 -0
  346. package/references/official-docs/docs/user/guide/schedule.zh.md +21 -0
  347. package/references/official-docs/docs/web-styling.i18n.yaml +1 -1
  348. package/references/official-docs/docs/web-styling.zh.md +2 -2
  349. package/references/official-docs/packages/AGENTS.md +3 -2
  350. package/references/official-docs/packages/README.md +104 -59
  351. package/references/official-docs/vendor/README.md +1 -0
  352. package/references/official-docs/website-docs.ts +52 -11
  353. package/references/sources.md +2 -2
  354. package/references/website-pages.md +3 -3
  355. package/scripts/download-sources.ps1 +1 -1
  356. package/scripts/sync-official-docs.ps1 +19 -11
  357. package/scripts/verify-kit.ps1 +0 -4
  358. package/templates/js/README.es.md +1 -1
  359. package/templates/js/README.hi.md +1 -1
  360. package/templates/js/README.md +1 -1
  361. package/templates/js/README.pt.md +1 -1
  362. package/templates/js/README.zh.md +1 -1
  363. package/templates/js/package.json +4 -4
  364. package/templates/ts/README.es.md +1 -1
  365. package/templates/ts/README.hi.md +1 -1
  366. package/templates/ts/README.md +1 -1
  367. package/templates/ts/README.pt.md +1 -1
  368. package/templates/ts/README.zh.md +1 -1
  369. package/templates/ts/package.json +4 -4
  370. package/references/official-docs/examples/AGENTS.md +0 -20
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](skills.md) | 中文
4
4
 
5
- [skill(技能)能力族](../../packages/skill) 包含 Service Definition([dsh-skill](../../packages/skill/skill),`ctx.skills`)、本地 Service Provider([dsh-skill-filesystem](../../packages/skill/skill-filesystem))、可选的随包徽章提供方([dsh-skill-badge](../../packages/skill/skill-badge))和 Consumer([dsh-tool-skill](../../packages/skill/tool-skill))。注册表在其宿主层与各 scope 层之间合并各提供方的目录;提供方贡献本地或随包 skill;Consumer 拥有初始目录和替换目录,以及面向模型的 `skill` 工具。skill 是可选的指令而非会话事件,因此其词汇定义在此处而非 [core.md](core.md)。
5
+ [skill(技能)能力族](../../packages/skill) 包含 Service Definition([dsh-skill](../../packages/skill/skill),`ctx.skills`)、本地 Service Provider([dsh-skill-filesystem](../../packages/skill/skill-filesystem))、可选的随包徽章提供方([dsh-skill-badge](../../packages/skill/skill-badge))和 Consumer([dsh-tool-skill](../../packages/skill/tool-skill))。注册表在其宿主层与各 scope 层之间合并各提供方的目录;提供方贡献本地或随包 skill;Consumer 拥有初始目录和替换目录,以及面向模型的 `skill` 工具。skill 是可选的指令而非会话事件,因此其词汇定义在此处而非 [core.md](core.zh.md)。
6
6
 
7
7
  源码:[`packages/skill/skill/src/index.ts`](../../packages/skill/skill/src/index.ts)、[`packages/skill/skill-filesystem/src/index.ts`](../../packages/skill/skill-filesystem/src/index.ts)、[`packages/skill/skill-badge/src/index.ts`](../../packages/skill/skill-badge/src/index.ts) 与 [`packages/skill/tool-skill/src/index.ts`](../../packages/skill/tool-skill/src/index.ts)。
8
8
 
@@ -10,7 +10,7 @@
10
10
 
11
11
  `ctx.skills` 组合本地、内嵌、远程或其他提供方。注册是同步的;远程初始化与发现属于 `list()` 的 await 阶段。提供方对象、选项与候选项以只读方式借用,语义字段会被校验。
12
12
 
13
- 注册表采用宿主 + 按 scope 的分层结构,即[工具注册表](tools.md)在 [dsh-scope](../../packages/core/scope) 之上确立的形态:注册会落入调用方上下文 scope 对应的层——宿主行与 repository 插件落入全局层,由 agent(智能体) preset 常驻组合挂载的插件落入该 preset 的层——提供方名称在每层内唯一,而非进程级唯一。读取时将全局层与观察 scope 的链合并:最近层的条目直接赢得重名 skill,下文的 rank 顺序只在单层内裁决重名。发现缓存以解析后的 scope 链为键,因此重设 scope 父级(空会话重组)无需注册表变更即可被下一次读取看到。
13
+ 注册表采用宿主 + 按 scope 的分层结构,即[工具注册表](tools.zh.md)在 [dsh-scope](../../packages/core/scope) 之上确立的形态:注册会落入调用方上下文 scope 对应的层——宿主行与 repository 插件落入全局层,由 agent(智能体) preset 常驻组合挂载的插件落入该 preset 的层——提供方名称在每层内唯一,而非进程级唯一。读取时将全局层与观察 scope 的链合并:最近层的条目直接赢得重名 skill,下文的 rank 顺序只在单层内裁决重名。发现缓存以解析后的 scope 链为键,因此重设 scope 父级(空会话重组)无需注册表变更即可被下一次读取看到。
14
14
 
15
15
  在单层内,重名项依次按 rank、提供方顺序和本地顺序确定优先级;摘要按名称排序。提供方的 `list()` 被拒绝时,系统会记录日志,并从不完整观测中省略该提供方的结果;显式的不完整观测会提供可用候选项,但不会使结果变得可缓存;格式错误的候选项快速失败。每个提供方工厂都会接收一项注册作用域内的控制能力;仅当该精确注册仍处于活动状态时,其 `invalidate()` 才会清除已完成目录;注册失败或 dispose(资源释放)时,其信号会中止。若提供方代次在发现进行期间发生变化,该发现会重试一次;若再次变化,则返回最新候选项,并将结果标为不完整且不予缓存。提供方和运行时变更会发出不带过滤条件的 `skills/change` 失效事件;该事件不携带 diff,因此消费方会使用自身的查找选项重新获取 `snapshot()`。
16
16
 
@@ -216,7 +216,7 @@ interface SkillViewOptions extends SkillLookupOptions {
216
216
  }
217
217
  ```
218
218
 
219
- 注册表只拥有其发现缓存上限。本地提供方拥有文件系统根目录(`dshHome`、`agentsHome`、`customSkillDirs`,以及可选的 `bundledSkillDir`/`DSH_BUNDLED_SKILL_DIR`),以及 watcher 启用、轮询、稳定性、符号链接和项目容量控制。消费方拥有其目录描述上限。确切的默认值和校验规则见自动生成的[插件配置目录](../config-catalog.md)。
219
+ 注册表只拥有其发现缓存上限。本地提供方拥有文件系统根目录(`dshHome`、`agentsHome`、`customSkillDirs`,以及可选的 `bundledSkillDir`/`DSH_BUNDLED_SKILL_DIR`),以及 watcher 启用、轮询、稳定性、符号链接和项目容量控制。消费方拥有其目录描述上限。确切的默认值和校验规则见自动生成的[插件配置目录](../config-catalog.zh.md)。
220
220
 
221
221
  ```ts type-equiv
222
222
  /** Skill registry configuration. */
@@ -234,13 +234,36 @@ interface Config {
234
234
 
235
235
  面向模型的 `skill({ name })` 工具校验 kebab-case 名称,在与调用策略无关的目录中查找摘要,并在加载前通过 `isModelInvocable` 拒绝无权访问的 skill;随后它根据调用方 agent 的 cwd 重新读取完整定义,并在返回内容前再次检查策略。该工具将无法解析的 skill 报告为未知或已不可用,并返回包含 `<skill_content name="...">`、`<skill_resources>` 和 `<skill_instructions>` 的工具结果。`resourceBase` 仅按需解析显式引用的脚本、参考资料和资产;加载结果不枚举 skill 目录。因此,仅修改正文会改变后续工具调用,而不会生成目录消息或改写先前工具结果。
236
236
 
237
+ ## 浏览器 Session 目录
238
+
239
+ `SkillListRequest` 通过 `sessionId` 指定一个 Session;`SkillListValue` 返回允许用户调用的条目,其中包含名称、描述、可选使用提示与模型调用可用性。`SessionSkillCatalog` 在不激活 Agent 的前提下读取 Session cwd 与记录的 preset。live Agent 可以提供其作用域 registry,冷 Session 则使用 preset 的 standing scope。
240
+
237
241
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
238
242
 
239
243
  <a id="cordis-surface"></a>
240
244
 
241
245
  ## Cordis API
242
246
 
243
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
247
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.zh.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
248
+
249
+ <a id="ctxsessionskillcatalog--sessionskillcatalog"></a>
250
+
251
+ ### `ctx.sessionSkillCatalog` — `SessionSkillCatalog`
252
+
253
+ Host service backing `ctx.remote.skills` without activating a cold Agent.
254
+
255
+ ```ts cordis-catalog
256
+ /**
257
+ * List the user-invocable skills visible to one Session composition.
258
+ * @param request - Session identity whose cwd and preset select the catalog view.
259
+ * @param signal - caller lifetime carried by the Remote transport; admitted catalog reads retain their existing completion semantics.
260
+ * @returns user-invocable skill metadata without loading skill bodies.
261
+ * @throws RemoteError when the Session cannot be inspected or no registry can serve it.
262
+ */
263
+ @Remote async list(request: SkillListRequest, signal: AbortSignal): Promise<SkillListValue>
264
+ ```
265
+
266
+ Source: [`packages/api/session-controller/src/skill-catalog.ts`](../../packages/api/session-controller/src/skill-catalog.ts)
244
267
 
245
268
  <a id="ctxskills--skillregistry"></a>
246
269
 
@@ -304,7 +327,7 @@ async snapshot(options: SkillViewOptions = {}): Promise<SkillCatalogSnapshot>
304
327
  async get(name: string, options: SkillViewOptions = {}): Promise<SkillDefinition | undefined>
305
328
  ```
306
329
 
307
- Source: [`packages/skill/skill/src/index.ts:357`](../../packages/skill/skill/src/index.ts)
330
+ Source: [`packages/skill/skill/src/index.ts`](../../packages/skill/skill/src/index.ts)
308
331
 
309
332
  <a id="skills-events"></a>
310
333
 
@@ -327,5 +350,5 @@ A skill provider, runtime contribution, or provider-backed catalog may have chan
327
350
  'skills/change'(): void
328
351
  ```
329
352
 
330
- Source: [`packages/skill/skill/src/index.ts:297`](../../packages/skill/skill/src/index.ts)
353
+ Source: [`packages/skill/skill/src/index.ts`](../../packages/skill/skill/src/index.ts)
331
354
  <!-- END GENERATED cordis-surface -->
@@ -0,0 +1,6 @@
1
+ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
2
+ # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
+ # after editing either side, bring the other along and re-record with:
4
+ # pnpm run verify-translation-pairing --write docs/subsystems/slots.md
5
+ slots.md: 8e115e30aed68e543eca2f1aac6e28ad9f57cf73
6
+ slots.zh.md: 3894b69d8d020b4bb67ce325d389ab3f20cfcc9a
@@ -0,0 +1,174 @@
1
+ # Web Client Slots
2
+
3
+ English | [中文](slots.zh.md)
4
+
5
+ Slots are the Web Client's typed React composition system. [`dsh-client-ui-slots`](../../packages/client/ui-slots/README.md) defines the React-free registry and type algebra; [`dsh-client-ui-renderer`](../../packages/client/ui-renderer/README.md) binds observable sources to hooks, renders the tree, and owns React contexts internally. A feature plugin contributes UI through `ctx.slots.register()` and never imports another feature plugin's component.
6
+
7
+ 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).
8
+
9
+ ## Declaration and lifecycle
10
+
11
+ `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.
12
+
13
+ Declaring a child has three effects: it makes the child key live, authorizes that parent entry's `renderSlot` or `renderSlotChain` call, and records the runtime dispatch specification. One live entry owns each declaration. Registering into an undeclared slot or declaring a child already owned elsewhere fails during plugin activation.
14
+
15
+ `root` is the only built-in declaration and the only key rendered through the Cordis service itself. `ui-renderer` calls `ctx.slots.renderSlot('root', {})`; every descendant is rendered through the `renderSlot` or `renderSlotChain` prop of the entry that declared it.
16
+
17
+ Registrations and declarations follow Cordis effect lifetimes. Disposing an entry removes its contribution and recursively collapses the child slots it declared. A feature that contributes into another package's slot therefore uses `ctx.slots.inject(key, callback)`: the callback runs for each declaration lifetime, its effects are removed when the owner collapses, and it runs again if the owner is mounted again.
18
+
19
+ ```tsx ignore-check
20
+ import type { Context } from '@deepseek-ai/cordis'
21
+ import type {} from '@deepseek-ai/dsh-client-ui-conversation/client'
22
+ import type {} from '@deepseek-ai/dsh-client-ui-session/client'
23
+ import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
24
+
25
+ type HeaderActionProps = PropsRuntime<'conversation.session.header.actions'>
26
+
27
+ function HeaderAction({ useSession }: HeaderActionProps) {
28
+ const running = useSession(snapshot => snapshot.running)
29
+ return <button disabled={running}>Review</button>
30
+ }
31
+
32
+ export const inject = ['slots']
33
+
34
+ export function apply(ctx: Context): void {
35
+ ctx.slots.inject('conversation.session.header.actions', () =>
36
+ ctx.slots.register({
37
+ name: 'conversation.session.header.actions',
38
+ id: 'review',
39
+ order: 100,
40
+ }, HeaderAction))
41
+ }
42
+ ```
43
+
44
+ ## Cardinality and scope
45
+
46
+ The slot declaration fixes two independent axes.
47
+
48
+ | Axis | Value | Meaning |
49
+ |---|---|---|
50
+ | cardinality | `single` | One cell. The active priority winner renders. Use a child slot instead of treating this as an additive list. |
51
+ | cardinality | `list` | Cells are addressed by required `id` and ordered by `order`, then registration order. |
52
+ | cardinality | `keyed` | The owner dispatches an `entryKey`; the matching cell renders with any key-specific props. |
53
+ | 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. |
54
+ | scope | `root` | One root-scoped component and store instance. |
55
+ | scope | `session-maybe` | Follows current selection but stays renderable without a Session; Session values are optional. |
56
+ | scope | `session` | Requires a resolved Session binding and receives definite Session values. |
57
+
58
+ `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.
59
+
60
+ ## Component inputs
61
+
62
+ A registered component receives inputs assembled at its binding site. Components derive these types rather than copying their members.
63
+
64
+ | Input | Declared by | Component type |
65
+ |---|---|---|
66
+ | owner values and standard scope values | the `SlotMap` row and installed scope adapters | `PropsRuntime<K>` |
67
+ | authorized child renderers | the registration's `children` keys | `PropsRenderSlots<S>` |
68
+ | selector hook and mutation callbacks for shared view state | the registration's `store` | `PropsStore<H>` |
69
+ | private data, callbacks, and observable hooks | the registration's `inject` factory | `InjectFace<I>` |
70
+ | localized `t` function | the registration's `locale` namespace | `PropsLocale<N>` |
71
+ | selected chain value | the registration's `select` result | `matched` through `ComposedProps` |
72
+
73
+ `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.
74
+
75
+ 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.
76
+
77
+ ## Framework-provided hooks
78
+
79
+ The shipped adapters add these standard props. They are available according to the target slot's scope, independent of which package registered the component.
80
+
81
+ | Availability | Props | Owner |
82
+ |---|---|---|
83
+ | every scope | `useSessions`, `useSessionPendingInteraction` | `ui-session` |
84
+ | every scope | `useWorkspaces` | `ui-workspace` |
85
+ | `session` | `sessionId`, `useSession`, `useProjection` | `ui-session` |
86
+ | `session-maybe` | optional `sessionId`, `useSession`, `useProjection` results | `ui-session` |
87
+ | `session` | `useConversation`, `useInput`, `inputActions` | `ui-conversation` |
88
+ | `session-maybe` | optional `useConversation`, `useInput`, `inputActions` results | `ui-conversation` |
89
+ | `session` | `useChat` | `ui-chat` |
90
+ | `session` | `useTrajectory` | `ui-trajectory` |
91
+
92
+ The renderer also creates `useStore` from a declared store and `t` from a declared locale namespace. These are registration-derived props rather than global standard props.
93
+
94
+ Framework and domain-adapter owners may extend the standard set through `ctx.slots.provideRoot()` or `ctx.uiSession.provide()` together with the corresponding `GlobalStandardProps`, `SessionStandardProps`, or `SessionMaybeStandardProps` declaration merge. A feature component should not create a React hook prop itself or add a global standard prop for entry-private data.
95
+
96
+ ## Developer-provided injection
97
+
98
+ The `inject` option on a registration is the ordinary feature-owned injection point. Its factory runs in the plugin's `apply` world, may close over injected Cordis services, and returns only the data and callbacks that the component needs. For a `session` slot it receives `sessionId`; for `session-maybe` it receives `sessionId | undefined`; when a store is declared it also receives the store's bound actions.
99
+
100
+ A reserved `hooks` object in that return value accepts bare `getSnapshot`/`subscribe` sources. The renderer converts `hooks: { status }` into a `useStatus(selector)` component prop and caches the binding by source identity. Components do not receive the source itself and do not call `useSyncExternalStore` directly.
101
+
102
+ The owner of a slot may put an `inject` face in the child declaration when every occupant needs the same capability. Plain members reach all occupants unchanged. Function-valued members inside its `hooks` object are hook factories; they receive the slot's standard props and optional per-render `hookContext`, then return the constrained hook exposed to the occupant. `conversation.chat.node` uses this mechanism to provide `useTurnData(key)` for the node currently being rendered.
103
+
104
+ Use owner props for values already known at one render occurrence, registration `inject` for one entry's callbacks and private observables, slot-level `inject` for a capability controlled by the slot owner, and a declared store for mutable view state shared across entries or preserved across remounts. React nodes compose through child slots, not through injected values.
105
+
106
+ ## Current hierarchy
107
+
108
+ The hierarchy below is the shipped declaration tree. A child exists only while the named parent entry is mounted; optional feature entries can therefore make a subtree appear or disappear as one lifecycle unit.
109
+
110
+ ```text
111
+ root
112
+ ├─ sidebar
113
+ │ ├─ sidebar.brand.mark
114
+ │ ├─ sidebar.brand.name
115
+ │ ├─ sidebar.footer.action
116
+ │ ├─ sidebar.workspaces
117
+ │ │ └─ sidebar.workspaces.directoryFlow
118
+ │ └─ sidebar.settings
119
+ │ ├─ settings.trigger
120
+ │ ├─ settings.header
121
+ │ ├─ settings.action
122
+ │ ├─ settings.close
123
+ │ ├─ settings.onboarding
124
+ │ └─ settings.section
125
+ │ ├─ settings.general.item
126
+ │ ├─ settings.models.provider-card
127
+ │ ├─ settings.models.footer
128
+ │ └─ settings.plugins.tab
129
+ │ └─ settings.plugin.item
130
+ ├─ conversation
131
+ │ ├─ conversation.session
132
+ │ │ └─ conversation.view
133
+ │ │ ├─ conversation.chat.node
134
+ │ │ │ ├─ conversation.chat.assistant-actions
135
+ │ │ │ ├─ conversation.chat.commandview
136
+ │ │ │ ├─ conversation.chat.turnTail
137
+ │ │ │ └─ tool.call.toolview
138
+ │ │ │ └─ tool.view.cordis
139
+ │ │ ├─ conversation.message.images
140
+ │ │ └─ conversation.trajectory.images
141
+ │ ├─ conversation.session.header
142
+ │ │ ├─ conversation.session.header.lineage
143
+ │ │ ├─ conversation.session.header.actions
144
+ │ │ └─ conversation.session.header.utilities
145
+ │ ├─ conversation.composer
146
+ │ │ └─ conversation.approval.detail
147
+ │ ├─ conversation.composer.bar
148
+ │ │ ├─ conversation.input.attachments
149
+ │ │ ├─ conversation.input.plan
150
+ │ │ └─ conversation.input.model
151
+ │ ├─ conversation.input.overlay
152
+ │ ├─ conversation.input.dock
153
+ │ ├─ conversation.composer.dock
154
+ │ ├─ conversation.input.left
155
+ │ ├─ conversation.input.right
156
+ │ ├─ conversation.hero.brand.mark
157
+ │ ├─ conversation.hero.workspace
158
+ │ │ └─ conversation.hero.workspace.directoryFlow
159
+ │ └─ conversation.hero.agentPreset
160
+ ├─ details
161
+ │ └─ conversation.details.tool
162
+ └─ shell.overlay
163
+ ```
164
+
165
+ 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`.
166
+
167
+ ## Extension rules
168
+
169
+ - Import another feature package only for declarations with `import type`; never import or re-export its runtime values.
170
+ - Declare a new child slot only in the component that owns and renders that location. Other packages wait with `ctx.slots.inject()` and contribute through `ctx.slots.register()`.
171
+ - Keep business and transport state in their owning Cordis services or Client models. Slot stores hold shared viewing and interaction state only.
172
+ - Keep observable source and snapshot identities stable between changes. Republish through the same source whenever its value changes.
173
+ - Pass JSON-compatible data and callbacks between UI domains. The `hooks` compartment is the sole exception for bare observables; React content travels through slots.
174
+ - Treat `single` and an occupied keyed cell as replacement points. Use list ids or an unoccupied key for additive extensions.
@@ -0,0 +1,174 @@
1
+ # Web Client Slots
2
+
3
+ [English](slots.md) | 中文
4
+
5
+ Slots 是 Web Client 的类型化 React 组合系统。[`dsh-client-ui-slots`](../../packages/client/ui-slots/README.zh.md)定义不依赖 React 的注册表与类型代数;[`dsh-client-ui-renderer`](../../packages/client/ui-renderer/README.zh.md)把可观测源绑定成钩子、渲染整棵树,并在内部拥有 React context。功能插件通过 `ctx.slots.register()` 贡献 UI,绝不导入其他功能插件的组件。
6
+
7
+ 本文记录 slot 的所有权、组件输入、扩展 API 与当前层级。外围的启动、Remote、Client model 与 Conversation 数据通路见 [Web Client 架构](web-client.zh.md)。
8
+
9
+ ## 声明与生命周期
10
+
11
+ `SlotMap` 是编译期注册表。包通过声明合并写入 key、cardinality(基数)、scope、owner props、keyed props 与可选的 slot 级 inject face。运行时声明则是拥有该渲染位置的组件在 `children` 中给出的对应条目。
12
+
13
+ 声明一个 child 会同时产生三种效果:令该 child key 生效、授权 parent entry 调用 `renderSlot` 或 `renderSlotChain`,以及记录运行时 dispatch 规格。每个声明只能有一个存活 owner。向未声明 slot 注册,或重复声明其他 entry 已拥有的 child,都会在插件激活时失败。
14
+
15
+ `root` 是唯一内建声明,也是唯一由 Cordis service 自身渲染的 key。`ui-renderer` 调用 `ctx.slots.renderSlot('root', {})`;其余每个后代都通过声明它的 entry 所收到的 `renderSlot` 或 `renderSlotChain` prop 渲染。
16
+
17
+ 注册和声明遵循 Cordis effect 生命周期。销毁一个 entry 会移除其贡献,并递归折叠它声明的 child slots。因此,向其他包的 slot 贡献功能时使用 `ctx.slots.inject(key, callback)`:callback 会在每段声明生命周期内运行,owner 折叠时其 effect 随之移除,owner 再次挂载时则重新运行。
18
+
19
+ ```tsx ignore-check
20
+ import type { Context } from '@deepseek-ai/cordis'
21
+ import type {} from '@deepseek-ai/dsh-client-ui-conversation/client'
22
+ import type {} from '@deepseek-ai/dsh-client-ui-session/client'
23
+ import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
24
+
25
+ type HeaderActionProps = PropsRuntime<'conversation.session.header.actions'>
26
+
27
+ function HeaderAction({ useSession }: HeaderActionProps) {
28
+ const running = useSession(snapshot => snapshot.running)
29
+ return <button disabled={running}>Review</button>
30
+ }
31
+
32
+ export const inject = ['slots']
33
+
34
+ export function apply(ctx: Context): void {
35
+ ctx.slots.inject('conversation.session.header.actions', () =>
36
+ ctx.slots.register({
37
+ name: 'conversation.session.header.actions',
38
+ id: 'review',
39
+ order: 100,
40
+ }, HeaderAction))
41
+ }
42
+ ```
43
+
44
+ ## Cardinality 与 scope
45
+
46
+ Slot 声明固定两个相互独立的维度。
47
+
48
+ | 维度 | 值 | 含义 |
49
+ |---|---|---|
50
+ | cardinality | `single` | 单个 cell,渲染当前 priority 胜者;需要并列内容时应声明 child slot,而不是把它当作列表。 |
51
+ | cardinality | `list` | cell 由必填 `id` 定址,先按 `order`、再按注册顺序排列。 |
52
+ | cardinality | `keyed` | owner 传入 `entryKey`;匹配 cell 以该 key 对应的 props 渲染。 |
53
+ | cardinality | `chain` | 每个 entry 提供纯 `select(owner)` 函数;按 priority 顺序遇到的第一个非 null 结果获选,并以 `matched` 传给组件;全部拒绝时渲染 owner fallback。 |
54
+ | scope | `root` | 一个 root 作用域组件和 store 实例。 |
55
+ | scope | `session-maybe` | 跟随当前选择,但没有 Session 时仍可渲染;Session 值是可选的。 |
56
+ | scope | `session` | 要求可解析的 Session binding,并收到确定存在的 Session 值。 |
57
+
58
+ 对于 `single`、`list` 和 `keyed` cell,`priority` 是遮蔽优先级;对于 `chain`,它是选举顺序。数值越小越先运行或渲染。普通增量贡献应选用新的 list `id` 或 keyed `key`;复用已有 cell 表示有意替换其展示。
59
+
60
+ ## 组件输入
61
+
62
+ 注册组件会在 binding 位置收到组装后的输入。组件应从这些类型推导 props,不要重新抄写成员。
63
+
64
+ | 输入 | 声明者 | 组件类型 |
65
+ |---|---|---|
66
+ | owner 值与标准 scope 值 | `SlotMap` 条目与已安装的 scope adapter | `PropsRuntime<K>` |
67
+ | 获授权的 child renderer | 注册项的 `children` keys | `PropsRenderSlots<S>` |
68
+ | 共享视图状态的 selector hook 与 mutation callback | 注册项的 `store` | `PropsStore<H>` |
69
+ | 私有数据、callback 与 observable hook | 注册项的 `inject` factory | `InjectFace<I>` |
70
+ | 本地化 `t` 函数 | 注册项的 `locale` namespace | `PropsLocale<N>` |
71
+ | chain 选中的值 | 注册项的 `select` 结果 | 通过 `ComposedProps` 提供的 `matched` |
72
+
73
+ 当 entry 声明 strict Session child 时,`PropsRenderSlots` 还会提供 `SessionProvider`。它把子树绑定到当前 Session identity,并在 identity 改变时重新挂载 body。
74
+
75
+ 组件绝不会收到 `ctx`。父组件在某次渲染时已经知道的值通过 `renderSlot` 的 owner 参数进入;共享视图状态使用声明的 store;service 与 model object 留在 `apply` closure 中,只向组件投影 callback 或 observable source。
76
+
77
+ ## 框架提供的 hooks
78
+
79
+ 当前组合中的 adapter 会添加以下标准 props。它们按目标 slot 的 scope 提供,与注册组件来自哪个包无关。
80
+
81
+ | 可用范围 | Props | Owner |
82
+ |---|---|---|
83
+ | 所有 scope | `useSessions`、`useSessionPendingInteraction` | `ui-session` |
84
+ | 所有 scope | `useWorkspaces` | `ui-workspace` |
85
+ | `session` | `sessionId`、`useSession`、`useProjection` | `ui-session` |
86
+ | `session-maybe` | 结果可选的 `sessionId`、`useSession`、`useProjection` | `ui-session` |
87
+ | `session` | `useConversation`、`useInput`、`inputActions` | `ui-conversation` |
88
+ | `session-maybe` | 结果可选的 `useConversation`、`useInput`、`inputActions` | `ui-conversation` |
89
+ | `session` | `useChat` | `ui-chat` |
90
+ | `session` | `useTrajectory` | `ui-trajectory` |
91
+
92
+ Renderer 还会根据声明的 store 创建 `useStore`,并根据声明的 locale namespace 创建 `t`。这些是由注册项推导的 props,不属于全局标准 props。
93
+
94
+ 框架与领域 adapter owner 可以通过 `ctx.slots.provideRoot()` 或 `ctx.uiSession.provide()` 扩展标准集合,同时提供对应的 `GlobalStandardProps`、`SessionStandardProps` 或 `SessionMaybeStandardProps` 声明合并。普通功能组件不应自行创建 React hook prop,也不应为 entry 私有数据添加全局标准 prop。
95
+
96
+ ## 开发者提供的 injection
97
+
98
+ 注册项的 `inject` 选项是通常使用的功能私有注入点。它的 factory 在插件的 `apply` 世界中运行,可以闭包捕获已经注入的 Cordis service,并且只返回组件所需的数据与 callback。对于 `session` slot,它会收到 `sessionId`;对于 `session-maybe`,它收到 `sessionId | undefined`;声明 store 后,它还会收到该 store 绑定后的 actions。
99
+
100
+ 返回值中保留的 `hooks` 对象接收裸 `getSnapshot`/`subscribe` source。Renderer 把 `hooks: { status }` 转换为组件 prop `useStatus(selector)`,并按 source identity 缓存绑定。组件不会收到 source 本身,也不直接调用 `useSyncExternalStore`。
101
+
102
+ 当每个 occupant 都需要同一种能力时,slot owner 可以在 child 声明里放置 `inject` face。普通成员会原样交给所有 occupant;其 `hooks` 对象中的函数成员是 hook factory,它会收到 slot 的标准 props 与可选的逐次渲染 `hookContext`,再返回提供给 occupant 的受限 hook。`conversation.chat.node` 正是通过这种机制,为当前渲染的 node 提供 `useTurnData(key)`。
103
+
104
+ 一次渲染时 owner 已知的值走 owner props;单个 entry 的 callback 与私有 observable 走注册项 `inject`;由 slot owner 控制、所有 occupant 共享的能力走 slot 级 `inject`;需要跨 entry 共享或跨重新挂载保留的可变视图状态走声明的 store。React node 通过 child slot 组合,不通过注入值传递。
105
+
106
+ ## 当前层级
107
+
108
+ 下图是当前发布组合的声明树。只有具名 parent entry 已挂载时,其 child 才存在;因此可选功能 entry 可以作为一个生命周期单元让整棵子树出现或消失。
109
+
110
+ ```text
111
+ root
112
+ ├─ sidebar
113
+ │ ├─ sidebar.brand.mark
114
+ │ ├─ sidebar.brand.name
115
+ │ ├─ sidebar.footer.action
116
+ │ ├─ sidebar.workspaces
117
+ │ │ └─ sidebar.workspaces.directoryFlow
118
+ │ └─ sidebar.settings
119
+ │ ├─ settings.trigger
120
+ │ ├─ settings.header
121
+ │ ├─ settings.action
122
+ │ ├─ settings.close
123
+ │ ├─ settings.onboarding
124
+ │ └─ settings.section
125
+ │ ├─ settings.general.item
126
+ │ ├─ settings.models.provider-card
127
+ │ ├─ settings.models.footer
128
+ │ └─ settings.plugins.tab
129
+ │ └─ settings.plugin.item
130
+ ├─ conversation
131
+ │ ├─ conversation.session
132
+ │ │ └─ conversation.view
133
+ │ │ ├─ conversation.chat.node
134
+ │ │ │ ├─ conversation.chat.assistant-actions
135
+ │ │ │ ├─ conversation.chat.commandview
136
+ │ │ │ ├─ conversation.chat.turnTail
137
+ │ │ │ └─ tool.call.toolview
138
+ │ │ │ └─ tool.view.cordis
139
+ │ │ ├─ conversation.message.images
140
+ │ │ └─ conversation.trajectory.images
141
+ │ ├─ conversation.session.header
142
+ │ │ ├─ conversation.session.header.lineage
143
+ │ │ ├─ conversation.session.header.actions
144
+ │ │ └─ conversation.session.header.utilities
145
+ │ ├─ conversation.composer
146
+ │ │ └─ conversation.approval.detail
147
+ │ ├─ conversation.composer.bar
148
+ │ │ ├─ conversation.input.attachments
149
+ │ │ ├─ conversation.input.plan
150
+ │ │ └─ conversation.input.model
151
+ │ ├─ conversation.input.overlay
152
+ │ ├─ conversation.input.dock
153
+ │ ├─ conversation.composer.dock
154
+ │ ├─ conversation.input.left
155
+ │ ├─ conversation.input.right
156
+ │ ├─ conversation.hero.brand.mark
157
+ │ ├─ conversation.hero.workspace
158
+ │ │ └─ conversation.hero.workspace.directoryFlow
159
+ │ └─ conversation.hero.agentPreset
160
+ ├─ details
161
+ │ └─ conversation.details.tool
162
+ └─ shell.overlay
163
+ ```
164
+
165
+ 生成的 Client inspect catalog 是每个 key 的完整参考,包含 cardinality、scope、owner props、标准 props、当前 occupant、声明 owner 与替换风险。运行中的动态包可以用 `cordis_inspect what:"client"` 查询实时树与某个精确 key;源码 catalog 由 `pnpm run gen-client-catalog` 根据 `SlotMap` 声明和 `slots.register()` 调用点生成。
166
+
167
+ ## 扩展规则
168
+
169
+ - 另一个功能包只能通过 `import type` 引入声明;绝不导入或转发它的运行时值。
170
+ - 只在拥有并渲染某个位置的组件中声明新的 child slot。其他包通过 `ctx.slots.inject()` 等待,再通过 `ctx.slots.register()` 贡献内容。
171
+ - 业务与传输状态留在所属 Cordis service 或 Client model 中。Slot store 只承载共享的视图与交互状态。
172
+ - 可观测 source 及其 snapshot identity 在值变化前保持稳定;值变化时通过同一个 source 发布。
173
+ - UI domain 之间只传 JSON 兼容数据和 callback。`hooks` compartment 是裸 observable 的唯一例外;React 内容通过 slot 传递。
174
+ - 将 `single` 和已有 occupant 的 keyed cell 视为替换点。增量扩展使用 list id 或尚未占用的 key。
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write docs/subsystems/spill.md
5
- spill.md: ad59e88b1f059d0127bdf48155450890b1bf7c9a
6
- spill.zh.md: 015ff6fc378c21e30f1cd84c985843f8c06cd44a
5
+ spill.md: 366cacbef06e18e79d593e946536b062d8d83d50
6
+ spill.zh.md: 82e2ad9efe418175642c3523614c2601b17e4450
@@ -38,7 +38,7 @@ interface SpillOwner {
38
38
  }
39
39
  ```
40
40
 
41
- `SpillOwner.sessionId` is the save-time storage namespace. Forked sessions inherit existing spill locators from the seeded log; those artifacts are not copied or re-owned, and spills produced after the fork use the child session id. A retention-period cleanup may expire old locators with other old session artifacts; the spill seam does not define a per-session cleanup policy.
41
+ A retention-period cleanup may expire old locators with other old session artifacts; the spill seam does not define a per-session cleanup policy.
42
42
 
43
43
  ```ts type-equiv
44
44
  /**
@@ -50,7 +50,7 @@ interface SpillSource {
50
50
  /** The tool whose result was spilled (e.g. `web_fetch`). */
51
51
  toolName: string
52
52
  /** The model-issued call id the result belongs to. */
53
- callId: CallId
53
+ callId: ToolCallId
54
54
  /** A short human label for the artifact (e.g. `result`). */
55
55
  label: string
56
56
  }
@@ -90,7 +90,7 @@ The local backend ([dsh-spill-local](../../packages/spill/spill-local)) writes u
90
90
 
91
91
  ## Cordis API
92
92
 
93
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
93
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
94
94
 
95
95
  <a id="ctxspillstore--spillstore-abstract-seam"></a>
96
96
 
@@ -113,5 +113,5 @@ Semantics every implementation must honor:
113
113
  abstract saveText(input: SaveTextSpill): Promise<SpillRef>
114
114
  ```
115
115
 
116
- Source: [`packages/spill/spill/src/index.ts:45`](../../packages/spill/spill/src/index.ts)
116
+ Source: [`packages/spill/spill/src/index.ts`](../../packages/spill/spill/src/index.ts)
117
117
  <!-- END GENERATED cordis-surface -->
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](spill.md) | 中文
4
4
 
5
- spill 存储 seam 是一项[能力 seam](../../.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.md),它持久保存工具的超大文本,并返回面向模型的定位符与检索指引;该能力拆分到三个包:Service Definition([dsh-spill](../../packages/spill/spill),`ctx.spillStore`)、Service Provider([dsh-spill-local](../../packages/spill/spill-local),宿主文件系统中会话作用域的私有文件)和 Consumer([dsh-spill-policy](../../packages/spill/spill-policy),`tools/post-execute` 策略)。spill 是**一项可选能力**,不属于 agent loop(智能体循环)主干,因此其词汇记录在此处,而不在 [core.md](core.md) 中。预览机制仍归 [dsh-output-retention](../../packages/util/output-retention) 所有;该 seam 只保存策略交给它的最终文本。
5
+ spill 存储 seam 是一项[能力 seam](../../.agents/notes/implemented/architecture/2026-07-08-tool-output-spill-files.zh.md),它持久保存工具的超大文本,并返回面向模型的定位符与检索指引;该能力拆分到三个包:Service Definition([dsh-spill](../../packages/spill/spill),`ctx.spillStore`)、Service Provider([dsh-spill-local](../../packages/spill/spill-local),宿主文件系统中会话作用域的私有文件)和 Consumer([dsh-spill-policy](../../packages/spill/spill-policy),`tools/post-execute` 策略)。spill 是**一项可选能力**,不属于 agent loop(智能体循环)主干,因此其词汇记录在此处,而不在 [core.md](core.zh.md) 中。预览机制仍归 [dsh-output-retention](../../packages/util/output-retention) 所有;该 seam 只保存策略交给它的最终文本。
6
6
 
7
7
  源码:[`packages/spill/spill/src/types.ts`](../../packages/spill/spill/src/types.ts)
8
8
 
@@ -38,7 +38,7 @@ interface SpillOwner {
38
38
  }
39
39
  ```
40
40
 
41
- `SpillOwner.sessionId` 是保存时的存储命名空间。fork 后的会话会从种子日志继承已有的 spill 定位符;这些产物不会被复制或重新取得所有权,fork 后产生的 spill 则使用子会话 id。保留期清理可以连同其他旧会话产物一起使旧定位符失效;spill seam 不定义逐会话的清理策略。
41
+ 保留期清理可以连同其他旧会话产物一起使旧定位符失效;spill seam 不定义逐会话的清理策略。
42
42
 
43
43
  ```ts type-equiv
44
44
  /**
@@ -50,7 +50,7 @@ interface SpillSource {
50
50
  /** The tool whose result was spilled (e.g. `web_fetch`). */
51
51
  toolName: string
52
52
  /** The model-issued call id the result belongs to. */
53
- callId: CallId
53
+ callId: ToolCallId
54
54
  /** A short human label for the artifact (e.g. `result`). */
55
55
  label: string
56
56
  }
@@ -67,7 +67,7 @@ interface SpillRef {
67
67
  }
68
68
  ```
69
69
 
70
- `SpillLocator` 是后端返回的[品牌化](core.md#branded-ids)面向模型句柄。本地后端将它渲染为文件系统路径;远程或数据库后端可以渲染 URI、键或命令 token。消费方将它视为不透明值,并使用 `retrievalHint` 渲染,而不是假定 `read` 始终是正确的检索机制。
70
+ `SpillLocator` 是后端返回的[品牌化](core.zh.md#branded-ids)面向模型句柄。本地后端将它渲染为文件系统路径;远程或数据库后端可以渲染 URI、键或命令 token。消费方将它视为不透明值,并使用 `retrievalHint` 渲染,而不是假定 `read` 始终是正确的检索机制。
71
71
 
72
72
  ```ts type-equiv
73
73
  /**
@@ -90,7 +90,7 @@ type SpillLocator = Branded<'SpillLocator'>
90
90
 
91
91
  ## Cordis API
92
92
 
93
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
93
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.zh.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
94
94
 
95
95
  <a id="ctxspillstore--spillstore-abstract-seam"></a>
96
96
 
@@ -113,5 +113,5 @@ Semantics every implementation must honor:
113
113
  abstract saveText(input: SaveTextSpill): Promise<SpillRef>
114
114
  ```
115
115
 
116
- Source: [`packages/spill/spill/src/index.ts:45`](../../packages/spill/spill/src/index.ts)
116
+ Source: [`packages/spill/spill/src/index.ts`](../../packages/spill/spill/src/index.ts)
117
117
  <!-- END GENERATED cordis-surface -->
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write docs/subsystems/storage.md
5
- storage.md: 7e7f8d2b5a98b20308ae8115484a25066c045d52
6
- storage.zh.md: 41d2d1520a846d988c6c7a0b08a7576cee44ff7a
5
+ storage.md: 1e4141e6ef1c6f8e1c2593e21e788b626d6b1ed7
6
+ storage.zh.md: f0433c600674741c3de0ce3e99430297839ce124
@@ -44,7 +44,7 @@ interface StorageBackend {
44
44
  }
45
45
  ```
46
46
 
47
- A backend owns one medium (a file-tree root, a database file) and exposes optional operation groups; `kv` is the only group today. `KvFacet.open(descriptor)` opens one named unit — `KvUnitDescriptor` carries the name, format version, table names, and whether a global singleton slot exists — and returns a `KvUnit` with `loadAll`, `putRecord`, `deleteRecord`, `setGlobal`, and `close`. Unit and table names must match `UNIT_NAME_RE` (safe as a file name and as a SQL identifier segment); record keys are arbitrary strings that never reach file paths. A unit does not serialize concurrent writes — ordering belongs to the caller — but each single call is atomic on the medium and durable once resolved. A medium stamped with a different version rejects `version-mismatch`; one that cannot be parsed as the unit rejects `malformed-medium` (no migration, pre-release stance). [`backend.ts`](../../packages/storage/storage/src/backend.ts) is the normative clause-by-clause contract, and the shared conformance suite in [`tests/contract.ts`](../../packages/storage/storage/tests/contract.ts) checks every clause against each backend. The [json backend](../../packages/storage/storage-json/README.md) republishes one whole human-readable file per unit atomically; the [sqlite backend](../../packages/storage/storage-sqlite/README.md) stores one document per row in one database for frequently updated data.
47
+ A backend owns one medium (a file-tree root, a database file) and exposes optional operation groups; `kv` is the only shipped group. `KvFacet.open(descriptor)` opens one named unit — `KvUnitDescriptor` carries the name, format version, table names, and whether a global singleton slot exists — and returns a `KvUnit` with `loadAll`, `putRecord`, `deleteRecord`, `setGlobal`, and `close`. Unit and table names must match `UNIT_NAME_RE` (safe as a file name and as a SQL identifier segment); record keys are arbitrary strings that never reach file paths. A unit does not serialize concurrent writes — ordering belongs to the caller — but each single call is atomic on the medium and durable once resolved. A medium stamped with a different version rejects `version-mismatch`; one that cannot be parsed as the unit rejects `malformed-medium` (no migration, pre-release stance). [`backend.ts`](../../packages/storage/storage/src/backend.ts) is the normative clause-by-clause contract, and the shared conformance suite in [`tests/contract.ts`](../../packages/storage/storage/tests/contract.ts) checks every clause against each backend. The [json backend](../../packages/storage/storage-json/README.md) republishes one whole human-readable file per unit atomically; the [sqlite backend](../../packages/storage/storage-sqlite/README.md) stores one document per row in one database for frequently updated data.
48
48
 
49
49
  ## Declaring a domain
50
50
 
@@ -57,6 +57,14 @@ interface DomainSpec {
57
57
  readonly name: string
58
58
  /** Domain format version; a medium stamped with a different version rejects at open. */
59
59
  readonly version: number
60
+ /**
61
+ * Medium layout for the backend unit: `single` (the default) stores the
62
+ * whole unit as one document; `per-record` stores each record as its own
63
+ * document, for units whose records are large, sparse, or individually
64
+ * disposable — the projection cache — and scopes version bumps per record
65
+ * (a stale record document is discarded, never migrated).
66
+ */
67
+ readonly layout?: 'single' | 'per-record'
60
68
  /** Optional global singleton slot. */
61
69
  readonly global?: DomainGlobalSpec<unknown>
62
70
  /** Table declarations keyed by table name; each name must match `UNIT_NAME_RE`. */
@@ -130,7 +138,7 @@ type DomainChanged = DomainChangedPut | DomainChangedDeleted
130
138
 
131
139
  ## Cordis API
132
140
 
133
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
141
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
134
142
 
135
143
  <a id="ctxstorage--storage"></a>
136
144
 
@@ -156,7 +164,7 @@ mount<K extends keyof StorageForms>(form: K, facility: StorageForms[K]): () => v
156
164
  form<K extends keyof StorageForms>(form: K): StorageForms[K]
157
165
  ```
158
166
 
159
- Source: [`packages/storage/storage/src/index.ts:47`](../../packages/storage/storage/src/index.ts)
167
+ Source: [`packages/storage/storage/src/index.ts`](../../packages/storage/storage/src/index.ts)
160
168
 
161
169
  <a id="ctxstoragedomain--domainfacility"></a>
162
170
 
@@ -201,7 +209,7 @@ get(name: string): DomainImpl | undefined
201
209
  async closeAll(): Promise<void>
202
210
  ```
203
211
 
204
- Source: [`packages/storage/storage-domain/src/index.ts:69`](../../packages/storage/storage-domain/src/index.ts)
212
+ Source: [`packages/storage/storage-domain/src/index.ts`](../../packages/storage/storage-domain/src/index.ts)
205
213
 
206
214
  <a id="domain-events"></a>
207
215
 
@@ -225,5 +233,5 @@ A domain record or the global singleton changed, emitted once per write strictly
225
233
  'domain/changed'(change: DomainChanged): void
226
234
  ```
227
235
 
228
- Source: [`packages/storage/storage-domain/src/events.ts:46`](../../packages/storage/storage-domain/src/events.ts)
236
+ Source: [`packages/storage/storage-domain/src/events.ts`](../../packages/storage/storage-domain/src/events.ts)
229
237
  <!-- END GENERATED cordis-surface -->