dsh-plugin-guide 0.3.1 → 0.3.3

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 (371) 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 +28 -23
  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 +25 -8
  32. package/references/official-docs/docs/architecture.zh.md +38 -21
  33. package/references/official-docs/docs/capability-seams.i18n.yaml +2 -2
  34. package/references/official-docs/docs/capability-seams.md +134 -67
  35. package/references/official-docs/docs/capability-seams.zh.md +134 -67
  36. package/references/official-docs/docs/config-catalog.i18n.yaml +2 -2
  37. package/references/official-docs/docs/config-catalog.md +731 -403
  38. package/references/official-docs/docs/config-catalog.zh.md +747 -419
  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 +3 -4
  41. package/references/official-docs/docs/cookbook/adding-a-package.zh.md +9 -8
  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 +660 -909
  116. package/references/official-docs/docs/module-graph.zh.md +662 -911
  117. package/references/official-docs/docs/persistence-catalog.i18n.yaml +2 -2
  118. package/references/official-docs/docs/persistence-catalog.md +185 -53
  119. package/references/official-docs/docs/persistence-catalog.zh.md +193 -61
  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 +207 -0
  142. package/references/official-docs/docs/subsystems/agent-team.zh.md +207 -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 +12 -8
  154. package/references/official-docs/docs/subsystems/code-runtime.zh.md +13 -9
  155. package/references/official-docs/docs/subsystems/commands.i18n.yaml +2 -2
  156. package/references/official-docs/docs/subsystems/commands.md +30 -7
  157. package/references/official-docs/docs/subsystems/commands.zh.md +31 -8
  158. package/references/official-docs/docs/subsystems/compaction.i18n.yaml +2 -2
  159. package/references/official-docs/docs/subsystems/compaction.md +14 -14
  160. package/references/official-docs/docs/subsystems/compaction.zh.md +19 -19
  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 +114 -36
  166. package/references/official-docs/docs/subsystems/core.zh.md +145 -65
  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 +6 -6
  175. package/references/official-docs/docs/subsystems/feedback.zh.md +6 -6
  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 +183 -173
  199. package/references/official-docs/docs/subsystems/persistence.zh.md +182 -172
  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 +148 -75
  213. package/references/official-docs/docs/subsystems/session-projection.zh.md +148 -75
  214. package/references/official-docs/docs/subsystems/session-query.i18n.yaml +2 -2
  215. package/references/official-docs/docs/subsystems/session-query.md +30 -16
  216. package/references/official-docs/docs/subsystems/session-query.zh.md +31 -17
  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 +8 -8
  225. package/references/official-docs/docs/subsystems/session-title.zh.md +10 -10
  226. package/references/official-docs/docs/subsystems/session.i18n.yaml +2 -2
  227. package/references/official-docs/docs/subsystems/session.md +376 -71
  228. package/references/official-docs/docs/subsystems/session.zh.md +392 -85
  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 +175 -0
  240. package/references/official-docs/docs/subsystems/slots.zh.md +175 -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 +38 -7
  246. package/references/official-docs/docs/subsystems/storage.zh.md +41 -10
  247. package/references/official-docs/docs/subsystems/subagent.i18n.yaml +2 -2
  248. package/references/official-docs/docs/subsystems/subagent.md +148 -116
  249. package/references/official-docs/docs/subsystems/subagent.zh.md +158 -124
  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 +29 -14
  264. package/references/official-docs/docs/subsystems/token-meter.zh.md +30 -15
  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 +413 -61
  297. package/references/official-docs/docs/tool-catalog.zh.md +418 -63
  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 +2 -2
  348. package/references/official-docs/docs/web-styling.md +3 -0
  349. package/references/official-docs/docs/web-styling.zh.md +5 -2
  350. package/references/official-docs/packages/AGENTS.md +4 -3
  351. package/references/official-docs/packages/README.md +104 -59
  352. package/references/official-docs/vendor/README.md +1 -0
  353. package/references/official-docs/website-docs.ts +52 -11
  354. package/references/sources.md +2 -2
  355. package/references/website-pages.md +3 -3
  356. package/scripts/download-sources.ps1 +1 -1
  357. package/scripts/sync-official-docs.ps1 +19 -11
  358. package/scripts/verify-kit.ps1 +0 -4
  359. package/templates/js/README.es.md +1 -1
  360. package/templates/js/README.hi.md +1 -1
  361. package/templates/js/README.md +1 -1
  362. package/templates/js/README.pt.md +1 -1
  363. package/templates/js/README.zh.md +1 -1
  364. package/templates/js/package.json +4 -4
  365. package/templates/ts/README.es.md +1 -1
  366. package/templates/ts/README.hi.md +1 -1
  367. package/templates/ts/README.md +1 -1
  368. package/templates/ts/README.pt.md +1 -1
  369. package/templates/ts/README.zh.md +1 -1
  370. package/templates/ts/package.json +4 -4
  371. package/references/official-docs/examples/AGENTS.md +0 -20
@@ -2,31 +2,114 @@
2
2
 
3
3
  [English](persistence.md) | 中文
4
4
 
5
- 事件日志的**持久性 seam**。[session.md](session.md) 描述了内存中的 `Session`:仅追加的 `SessionEvent` 日志即为真源。本页描述如何使该日志持久化:抽象的 `SessionPersistence` 服务、它的后端、flush 检查点、崩溃恢复,以及随日志一同存储的元数据头。日志承载的事件词汇在生成的[持久化日志事件目录](../persistence-catalog.md)中逐项列举。
5
+ 事件日志的**持久性 seam**。[session.md](session.zh.md) 描述了内存中的 `Session`:仅追加的 `SessionEvent` 日志即为真源。本页描述如何使该日志持久化:抽象的 `SessionPersistence` 服务、它的提供方模型与随产品交付的 JSONL 后端、flush 检查点、崩溃恢复,以及随日志一同存储的元数据头。日志承载的事件词汇在生成的[持久化日志事件目录](../persistence-catalog.zh.md)中逐项列举。
6
6
 
7
- 该 seam 是一个[能力 seam](../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md):一个抽象服务([dsh-session-persistence](../../packages/session/session-persistence),`ctx.sessionPersistence`)在现有 `SessionEvent` 上定义 locate/create/append、可复用的 Session 准备流程、逻辑 load/inspect、物理后缀读取,以及轻量的 list/snapshot 观察——**没有平行的持久化事件类型**——以及两个实现同一约定的可互换后端。见 [session-persistence Agent Note](../../.agents/notes/implemented/architecture/2026-06-14-session-persistence.md)。
7
+ 该 seam 是一个[能力 seam](../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md):一个抽象服务([dsh-session-persistence](../../packages/session/session-persistence),`ctx.sessionPersistence`)在现有 `SessionEvent` 上暴露 `create`/`open`/`stat`/`list`——**没有平行的持久化事件类型**——其中 `create` `open` 返回逐会话的 `SessionHandle`(`read`/`append`/`flush`/`close`),它承载全部日志访问与单写者所有权。仓库随产品交付 [dsh-session-persistence-jsonl](../../packages/session/session-persistence-jsonl) 作为其 provider;仓库外 provider 可以实现同一服务约定。见[基于句柄的持久化 Agent Note](../../.agents/notes/implemented/architecture/2026-08-27-handle-based-session-persistence.zh.md)与 [session-persistence Agent Note](../../.agents/notes/implemented/architecture/2026-06-14-session-persistence.zh.md)。
8
+
9
+ ## `SessionHandle`——通向已存储会话的一条打开通道
10
+
11
+ 每一次日志读写都经由句柄流动,绝不经由按 id 寻址的服务方法:句柄是未来跨进程写租约将要把守的那扇唯一的门。一种句柄类型同时服务两种访问——在 `read` 句柄上执行修改是运行时的 `SessionReadOnlyError`,而非类型层面的拆分——而进程内单写者所有权使得在已有活跃持有者时第二次 `open(id, 'write')` 以 `SessionAlreadyOwnedError` 拒绝。
12
+
13
+ ```ts type-equiv
14
+ /**
15
+ * One open channel onto a stored session. A handle is single-owner state, not
16
+ * a shared service: `read` never backtracks below what this handle already
17
+ * observed, a `write` handle reads its own successful appends, and `close()`
18
+ * is the one teardown (idempotent, uncancellable; `Symbol.asyncDispose`
19
+ * delegates to it). Every operation on a closed handle rejects with
20
+ * `SessionHandleClosedError`.
21
+ *
22
+ * Freshness across handles: once an `append` or `flush` resolves on a write
23
+ * handle, every read STARTED afterwards on the same backend instance — on any
24
+ * handle, or through `stat`/`list` — observes at least that prefix.
25
+ * Reads concurrent with a mutation carry no ordering promise beyond the valid
26
+ * contiguous prefix.
27
+ */
28
+ interface SessionHandle extends AsyncDisposable {
29
+ /** The stored session this handle addresses. */
30
+ readonly id: SessionId
31
+ /** The immutable stored header, fixed at `create`/`open`. */
32
+ readonly header: SessionHeader
33
+ /**
34
+ * Exact fork-inherited prefix length stored with the log; `0` when
35
+ * `header.isSeeded` is false. Storage metadata paired with the header for
36
+ * every body read, never part of the replayable event log.
37
+ */
38
+ readonly inheritedEventCount: SessionLogOffset
39
+ /** Whether this handle may mutate the log. */
40
+ readonly access: SessionAccess
41
+
42
+ /**
43
+ * Read a slice of the valid contiguous logical log. The slice is a legal log
44
+ * prefix segment: a torn physical tail is never returned, and repeated reads
45
+ * on this handle never observe an older state than a prior read.
46
+ * @param offset - first logical event seq to include; defaults to `0`.
47
+ * @param length - maximum number of events to return; defaults to the rest
48
+ * of the log. An offset at or past the end returns an empty list.
49
+ * @param options - optional cancellation.
50
+ * @returns the events with `seq >= offset`, at most `length` of them.
51
+ */
52
+ read(offset?: number, length?: number, options?: SessionHandleReadOptions): Promise<readonly SessionEvent[]>
53
+
54
+ /**
55
+ * Append a contiguous batch continuing the current logical end. The first
56
+ * event's `seq` MUST equal the stored next-seq; committed events are never
57
+ * rewritten. Persistence is best-effort: on resolution the batch is
58
+ * accepted, ordered, and visible to reads on this backend instance, but
59
+ * only a resolved {@link flush} promises it survives a crash — a backend
60
+ * may buffer or batch physical writes behind append. Rejects with
61
+ * `SessionReadOnlyError` on a read handle and `SessionOwnershipLostError`
62
+ * when write ownership is gone.
63
+ * @param events - the contiguous batch, in seq order.
64
+ * @param options - optional cancellation observed before the write starts.
65
+ */
66
+ append(events: readonly SessionEvent[], options?: SessionHandleAppendOptions): Promise<void>
67
+
68
+ /**
69
+ * The durability barrier — the one operation that promises storage: on
70
+ * resolution every acknowledged append is durable and the session is
71
+ * materialized for other processes; an empty created session becomes
72
+ * durably listable here. Callers that must survive a crash flush; a backend
73
+ * whose `append` already persists on resolution treats this as
74
+ * materialize-if-needed. Rejects with `SessionReadOnlyError` on a read
75
+ * handle.
76
+ * @param options - optional cancellation observed before the barrier starts.
77
+ */
78
+ flush(options?: SessionHandleFlushOptions): Promise<void>
79
+
80
+ /**
81
+ * Release the handle: a read handle frees local resources; a write handle
82
+ * completes pending durability and releases write ownership. Idempotent,
83
+ * asynchronous, and deliberately not cancellable.
84
+ */
85
+ close(): Promise<void>
86
+ }
87
+ ```
88
+
89
+ 已创建的会话自 `create` 完成之刻起即可在本进程内被观察到,而后端可以把物理实体化(纯粹的优化)推迟到第一次 `append` 或 `flush`;其他进程只能看到已实体化的会话,一个在崩溃前从未实体化的会话等于从未存在。
8
90
 
9
91
  ## flush 检查点
10
92
 
11
- `session/event` 是一个*同步*通知;持久化插件会将事件复制到逐会话控制器,而不阻塞生产方。第一个待处理事件会开启固定批处理窗口,后续事件会加入但不会重置截止时间。窗口到期后会启动一个持久化批次;该次写入期间接纳的事件会获得自己的截止时间,并形成后续批次。`session/flush` 会取消等待并排空至完全停稳,因此循环仍将其用作在领取下一个普通轮次之前的顺序与错误观察检查点。后台写入被拒绝时会保留对应事件并暂停自动重试;新事件会开启新的固定窗口,而显式 flush 会立即重试,并通过 `agent/error` logger 报告失败,绝不会把失败记录成已关闭轮次之后的会话事件。dispose(资源释放)会执行同样的最终排空。配置的最大值只限制有意的批处理等待,不限制事件循环调度或后端完成持久化的延迟([决策](../../.agents/notes/implemented/architecture/2026-08-08-bounded-session-persistence-write-batching.md))。
93
+ `session/event` 是一个*同步*通知;挂载的后端按会话 id 把它路由进活跃写句柄的有界 write-behind 窗口,而不阻塞生产方(后端一次性安装这些监听器,因为持久化已保证每个 id 只有一个活跃写句柄)。第一个待处理事件会开启固定的内部批处理窗口,后续事件会加入但不会重置其截止时间。窗口到期后会通过该会话的写句柄启动一次持久化 `append`;该次写入期间接纳的事件会获得自己的截止时间,并形成后续批次。`session/flush` 会取消等待并排空至完全停稳,因此循环仍将其用作在领取下一个普通轮次之前的顺序与错误观察检查点。后台写入被拒绝时会按序保留对应事件、暂停自动路径,并通过 logger 报告;下一次显式 flush 会重试,并向其调用方响亮地拒绝。`session/disposed` 会执行同样的最终排空并关闭句柄,而 `close()` 本身会经由仍然打开的存储排空已路由的缓冲,因此后端 teardown 的关闭清扫不丢任何数据。该窗口只限制有意的批处理等待,不限制事件循环调度或后端完成持久化的延迟([决策](../../.agents/notes/implemented/architecture/2026-08-08-bounded-session-persistence-write-batching.zh.md))。
12
94
 
13
95
  ## 崩溃恢复保留被中断的轮次
14
96
 
15
- 后端重新加载一个在轮次中途崩溃的日志时,会发现一个已打开的 `turn/start` 却没有 `turn/end`。它**不会**截断日志:在长周期任务中,单个轮次可能非常庞大(许多步骤、大量工具输出),而这些事件在崩溃前已被持久追加。后端改为用一个合成的 `turn/end { reason: { kind: 'interrupted' } }` 关闭这个遗留轮次,在不改变其前后任何独立事件的情况下配平被中断的执行。`interrupted` 是唯一一个不由循环发出的 `TurnEndReason`(见 [session.md](session.md#why-a-turn-ended-turnendreasonmap))。
97
+ 一个在轮次中途崩溃的日志以打开的 `turn/start` 而无 `turn/end` 结束。持久化**不会**截断或修复它:在长周期任务中,单个轮次可能非常庞大(许多步骤、大量工具输出),而这些事件在崩溃前已被持久追加。它返回物理上有效的连续日志;只有撕裂物理尾部——属于一次从未完成的 append——中不完整的碎片会被丢弃:从中恢复的完整记录(JSONL 后端会部分解码撕裂的 Zstandard 帧)由写路径在句柄的第一次新 append 之前持久重写。修复是读方的职责:resume(agent-loop)通过其写句柄读取已存储的日志,计算 `interruptedTurnClosers`——缺失的工具错误、任何未闭合的 `step/end`,以及一个合成的 `turn/end { reason: { kind: 'interrupted' } }`——并在发布 Session 之前把它们作为普通批次通过同一句柄追加。`interrupted` 是唯一一个不由循环发出的 `TurnEndReason`(见 [session.md](session.zh.md#why-a-turn-ended-turnendreasonmap))。
16
98
 
17
- 修复仅适用于冷会话。对于活跃 id,`SessionPersistence.load(id)` 会等待权威内存快照完成持久化,并且只在日志平衡时返回;若活跃轮次仍未闭合,则拒绝操作,而不是添加合成的中断边界。HMR(热模块替换)会接管活跃前缀,而不会关闭其中正在进行的轮次。
99
+ 因此修复只在写所有权之下写入:活跃会话的写句柄由其生命周期所有者持有,故并发的 `open(id, 'write')` 会以 `SessionAlreadyOwnedError` 拒绝,而不是让修复与活跃轮次竞速。只读观察方(session-query)仅在内存中用同样的闭合事件配平被中断的冷日志,不回写任何内容。
18
100
 
19
- `SessionPersistence.inspect(id)` 会构造一个不可变的逻辑 Session,但不发布它,也不写入恢复内容。冷检查会在内存中配平中断的轮次,同时保持撕裂的物理尾部不变;检查已处于活跃状态的 Session 则借用其当前不可变快照,因此可能包含未闭合的轮次。使用协调器的实现会在有界 LRU 中保留这个精确的冷未发布 Session,因此重复历史读取与后续 `prepare(id)` 可复用同一次读取、解压、验证、冻结及 Session 构造。`prepare(id)` 会预留该 Session、提交待处理修复并返回可 dispose 的发布句柄;`load(id)` 使用相同机制提交修复,但不会发布 Session。该生命周期由 [Session 准备阶段决策](../../.agents/notes/implemented/architecture/2026-08-05-session-preparation.md)定义。
101
+ 只读观察即 `open(id, 'read')`:句柄提供经过验证的连续前缀切片,绝不返回撕裂尾部,且同一句柄上的重复读取绝不会观察到比先前读取更旧的状态。持久化侧不存在已准备 Session 缓存:session-query 拥有自己的冷读缓存,按 `stat().revision` 变更令牌为每个 id 缓存一个已配平的冷 Session,仅在令牌变化时重新读取。该生命周期由[基于句柄的持久化 Agent Note](../../.agents/notes/implemented/architecture/2026-08-27-handle-based-session-persistence.zh.md)定义;[Session 准备阶段决策](../../.agents/notes/implemented/architecture/2026-08-05-session-preparation.zh.md)记录仍然保留的发布边界 `SessionPreparation`。
20
102
 
21
- ## `SessionLocation`——可选的逐会话产物目标
103
+ ## `SessionLocation`——拒绝诊断的产物目标
22
104
 
23
- `SessionPersistence.locate(meta)` 会同步解析一个归后端所有的独立产物,而不会读取、创建或 flush 它。JSONL 返回其项目/会话目录内 transcript(文本记录)的绝对路径;SQLite 因各会话共享一个数据库而返回 `undefined`。因此,返回的路径可能指向尚不存在的文件,或指向还不包含当前尚未 flush 轮次的文件;它是位置提示,不是授权或新鲜度保证。
105
+ `SessionLocation` 不是面向消费者的查询:日志访问走会话句柄的 `read`。它仅作为拒绝诊断存在,使 `SessionFormatUnsupportedError` 能指出本构建拒绝解读的原始日志。JSONL 提供其项目/会话目录内 transcript(文本记录)的绝对路径;没有逐会话工件的后端则不提供。
24
106
 
25
107
  ```ts type-equiv
26
108
  /**
27
- * A backend-resolved, per-session local artifact location. The path is an
28
- * absolute target path and can name an artifact that has not materialized yet.
29
- * Consumers must treat it as a location hint, never as an authorization token.
109
+ * A backend-resolved, per-session local artifact location. Carried only by
110
+ * refusal diagnostics ({@link SessionFormatUnsupportedError}) so a user can
111
+ * find the raw log a build refused to interpret; it is not a consumer-facing
112
+ * query — log access goes through a session handle's `read`.
30
113
  */
31
114
  interface SessionLocation {
32
115
  /** Backend-specific artifact kind, for example `jsonl`. */
@@ -40,7 +123,7 @@ interface SessionLocation {
40
123
 
41
124
  ## `SessionHeader`:日志旁的元数据
42
125
 
43
- 每个会话的元数据与事件日志**分开**存储:格式版本、cwd、血统与 seed 边界是存储层关注点而非对话事件,因此不进入 `SessionEventMap`,也不会到达 `deriveMessages()`。header 通过 `session.header` 附加到 `Session` 上。
126
+ 每个会话的元数据与事件日志**分开**存储:header 携带格式版本、cwd `isSeeded` 谱系 bit,含正文的存储值则在其旁边单独携带精确 inherited cut。二者都不进入 `SessionEventMap`,也不会到达 `deriveMessages()`。logical header 通过 `session.header` 附加,Session 则以 `inheritedEventCount` 暴露其 cut。
44
127
 
45
128
  源码:[`packages/core/session/src/types.ts`](../../packages/core/session/src/types.ts)
46
129
 
@@ -64,10 +147,10 @@ interface SessionHeader {
64
147
  /** The session this one was forked from (seed lineage), if any. */
65
148
  readonly parentSession?: SessionId
66
149
  /**
67
- * How many leading events were inherited through a seed. Persisting this
68
- * boundary lets resume and replay distinguish parent history from child work.
150
+ * Whether this Session contains a fork-inherited event prefix. The exact prefix
151
+ * length is Session state rather than ordinary header metadata.
69
152
  */
70
- readonly seedLength?: number
153
+ readonly isSeeded: boolean
71
154
  /**
72
155
  * Coarse product classification for a session created as a subagent child.
73
156
  * This is presentation metadata, not proof that the child is continuable.
@@ -91,11 +174,11 @@ interface SessionHeader {
91
174
 
92
175
  ## 格式拒绝:本构建无法可靠读取的日志
93
176
 
94
- 后端用 `SessionFormatUnsupportedError` 拒绝无法可靠解读的日志,它与 `SessionPersistenceCorruptionError` 区分,因为数据没有损坏。header 的 `version` 比 `SESSION_FORMAT_VERSION` 新时,消息说明方向("由更新的 harness 写入,请升级 harness 后打开");比它旧时说明本构建没有升级路径。经过 legacy 形状归一化后,本构建生成集合(`KNOWN_SESSION_EVENT_TYPES`,由 `gen-persistence-catalog` 生成)之外的事件类型也会拒绝重建,因为静默跳过该事件可能改变日志其余部分的解读方式。后端为每个会话保留独立文件时,消息附上原始日志路径,被拒绝的文本仍然可读。JSONL 后端直接从原始 header 行拒绝外来版本,先于校验本格式版本的 header 字段和解码任何事件行,因此结构完全不同的未来格式仍会报告升级方向,绝不会报"损坏";SQLite 则先由自己的 `SCHEMA_VERSION` pragma 把关整个文件的结构。设计理由与推迟建设的升级器链见[事件词汇表显式拒绝 Agent Note](../../.agents/notes/implemented/simplification/2026-08-25-fail-closed-session-event-vocabulary.zh.md)。
177
+ 后端用 `SessionFormatUnsupportedError` 拒绝无法可靠解读的日志,它与 `SessionPersistenceCorruptionError` 区分,因为数据没有损坏。header 的 `version` 比 `SESSION_FORMAT_VERSION` 新时,消息说明方向("由更新的 harness 写入,请升级 harness 后打开");比它旧时说明本构建没有升级路径。本构建生成词汇表(`KNOWN_SESSION_EVENT_TYPES`,由 `gen-persistence-catalog` 生成)之外的事件类型同样被拒绝,除非该事件的信封带 `ignorable: true`:静默跳过一个不认识的必需事件可能改变日志其余部分的解读方式。后端为每个会话保留独立文件时,消息附上原始日志路径,被拒绝的文本仍然可读。JSONL 后端直接从原始 header 行拒绝外来版本,先于本格式版本的 header 形状校验和任何事件行解码,因此结构完全不同的未来格式仍会报告升级方向,绝不会报"损坏"。仓库外后端必须在自己的物理格式入口执行等价的方向感知拒绝。设计理由与推迟建设的升级器链见 [session-log 版本机制 Agent Note](../../.agents/notes/implemented/architecture/2026-08-10-session-log-version-mechanism.zh.md)。
95
178
 
96
179
  ## `CreateSessionOptions`:seed 与元数据
97
180
 
98
- 通过 store 创建 `Session` 时会接收 `seed`(初始回放或 fork 历史)与 `meta`(store 整合进 `SessionHeader` 的存储层字段)。store 填充 `version`/`id` 并为 `createdAt` 提供默认值;调用方可以提供已校验的绝对 `cwd`、`parentSession` 谱系、`seedLength` 种子边界、可选的粗粒度 `origin`、`delegationDepth`、用于组装该 agent(智能体)的 `agentPreset` 以及已有的 `createdAt`。`origin: 'subagent'` 让产品导航能够隐藏重复的 child 行;它不证明描述符有效,也不证明 child 可以恢复。
181
+ 通过 store 创建 `Session` 时会接收 `seed`(初始回放或 fork 历史)、可选的精确 `inheritedEventCount` 与 `meta`(store 整合进 `SessionHeader` 的存储层字段)。store 填充 `version`/`id` 并为 `createdAt` 提供默认值;调用方可以提供已校验的绝对 `cwd`、`parentSession` 谱系、`isSeeded` 谱系标记、可选的粗粒度 `origin`、`delegationDepth`、用于组装该 agent(智能体)的 `agentPreset` 以及已有的 `createdAt`。seeded 创建必须同时显式提供 seed 与精确 cut,因为继承前缀之后还可能存在 child-owned setup event。`origin: 'subagent'` 让产品导航能够隐藏重复的 child 行;它不证明描述符有效,也不证明 child 可以恢复。
99
182
 
100
183
  ```ts type-equiv
101
184
  /**
@@ -107,14 +190,19 @@ interface CreateSessionOptions {
107
190
  /** Initial replay or fork history supplied at construction. */
108
191
  readonly seed?: readonly SessionEvent[]
109
192
  /**
110
- * Storage metadata read once before publication. `seedLength` is explicit
111
- * because a resumed seed contains the full stored log, not only its inherited prefix.
193
+ * Exact fork-inherited prefix length when `meta.isSeeded` is true. A
194
+ * constructor seed may also contain child-owned setup events after this cut.
195
+ */
196
+ readonly inheritedEventCount?: SessionLogOffset
197
+ /**
198
+ * Storage metadata read once before publication. `isSeeded` marks fork
199
+ * lineage; supplying replay history alone does not make it inherited.
112
200
  */
113
201
  readonly meta?: {
114
202
  readonly cwd?: string
115
203
  readonly parentSession?: SessionId
116
204
  readonly createdAt?: number
117
- readonly seedLength?: number
205
+ readonly isSeeded?: boolean
118
206
  readonly origin?: 'subagent'
119
207
  readonly delegationDepth?: number
120
208
  readonly agentPreset?: string
@@ -122,27 +210,11 @@ interface CreateSessionOptions {
122
210
  }
123
211
  ```
124
212
 
125
- 因此,回放/fork 的调用方式为 `ctx.sessions.create(id, { seed: seedEvents })`;将一个*持久化*会话恢复为活跃 agent 的调用方式为 `ctx.agents.resume({ resumeSessionId })`。
126
-
127
- ## `SessionRawArtifact`——逐字存储工件文本
128
-
129
- 后端为单个会话自持的工件文本,与其持久化写入的字节逐字一致(按物理编码解码)。`readRaw` 返回它而不从解析后事件重建,因此后端特定的序列化(chunk 打包、键序、换行)得以保留。Consumer 须先检查 `supportsRawArtifacts`:`false` 表示后端不提供此能力(如 SQLite),而 `readRaw(...) === undefined` 表示受支持的后端没有该会话的已实体化工件。
130
-
131
- ```ts type-equiv
132
- /** A backend's own raw artifact text for one session, verbatim. */
133
- interface SessionRawArtifact {
134
- /** The session header parsed from the artifact's own first line. */
135
- readonly meta: SessionHeader
136
- /** The artifact's base filename on disk, without any physical encoding suffix. */
137
- readonly filename: string
138
- /** The artifact's full text content, decoded from the backend's physical encoding. */
139
- readonly content: string
140
- }
141
- ```
213
+ 因此,回放/fork 的调用方式为 `ctx.agents.create({ sessionId, seed, meta })`——fork 还会随 `meta.isSeeded: true` 提供 `inheritedEventCount`,且只有经 agent-loop 发布的会话才会持久化,且循环会在发布之前通过新会话的写句柄存储 seed;将一个*持久化*会话恢复为活跃 agent 的调用方式为 `ctx.agents.resume({ resumeSessionId })`。
142
214
 
143
215
  ## 准备与恢复所有权
144
216
 
145
- `SessionStore.prepare()` 接收普通创建选项,或通过 `RestoredSessionOptions` 转移所有权的全新的持久化对象图。恢复分支会就地验证并冻结转移来的 header 与事件,因此调用方不得保留可变别名。`SessionPreparation` 随后持有该精确的未发布 Session,直至发布或回滚;dispose 是同步且幂等的。持久化检查只暴露 `SessionInspection`,即从同一个已准备 Session 借用的不可变逻辑视图。
217
+ `SessionStore.prepare()` 接收普通创建选项,或通过 `RestoredSessionOptions` 转移所有权的全新的持久化对象图。恢复分支会就地验证并冻结转移来的 header 与事件,因此调用方不得保留可变别名。`SessionPreparation` 随后持有该精确的未发布 Session,直至发布或回滚;dispose 是同步且幂等的。agent-loop resume 通过该会话的写句柄读取已存储的日志,并在准备之前追加所需的 `interruptedTurnClosers`,以此构建这些对象图。
146
218
 
147
219
  ```ts type-equiv
148
220
  /**
@@ -154,6 +226,8 @@ interface RestoredSessionOptions {
154
226
  readonly seed: SessionEvent[]
155
227
  /** Fresh detached storage metadata to validate and freeze in place. */
156
228
  readonly meta: SessionHeader
229
+ /** Exact number of fork-inherited leading events decoded from storage. */
230
+ readonly inheritedEventCount: SessionLogOffset
157
231
  /** Select the persistence ownership-transfer path. */
158
232
  readonly seedSource: 'persistence'
159
233
  }
@@ -196,19 +270,9 @@ declare class SessionPreparation implements Disposable {
196
270
  }
197
271
  ```
198
272
 
199
- ```ts type-equiv
200
- /** Immutable logical session prepared from persistence or a live owner. */
201
- interface SessionInspection {
202
- /** Validated immutable session metadata. */
203
- readonly meta: SessionHeader
204
- /** Validated contiguous logical event log. */
205
- readonly events: readonly SessionEvent[]
206
- }
207
- ```
208
-
209
273
  ## 轻量源修订号
210
274
 
211
- 派生状态的消费方会在加载完整事件日志之前比较一个低开销的不透明修订号。其表示由持久化后端拥有,并随 append 或会修改数据的 load 修复以事务方式改变;调用方仅比较修订号是否相等。
275
+ 派生读取模型的消费方会在加载完整事件日志之前比较一个低开销的不透明修订号。该修订号是来自 `stat`/`list` 的逐后端实例变更令牌:修订号相等可视为日志未变;不相等则不作任何承诺,且写所有权的变动绝不会改变修订号。session-query 以它为键管理冷读缓存;该令牌在 open、read 或 resume 中不起任何作用。
212
276
 
213
277
  ```ts type-equiv
214
278
  /**
@@ -219,21 +283,29 @@ type SessionPersistenceRevision = Branded<'SessionPersistenceRevision'>
219
283
  ```
220
284
 
221
285
  ```ts type-equiv
222
- /** Lightweight immutable source identity returned without loading a full log. */
286
+ /**
287
+ * Lightweight stored-session observation returned by {@link SessionPersistence.stat}
288
+ * and {@link SessionPersistence.list} without reading the full event log.
289
+ */
223
290
  interface SessionPersistenceSnapshot {
224
- /** Detached metadata for one materialized session. */
225
- header: SessionHeader
226
- /** Opaque source-qualified token that changes whenever this stored log changes. */
227
- revision: SessionPersistenceRevision
291
+ /** Detached metadata for one stored session. */
292
+ readonly header: SessionHeader
293
+ /** Opaque change token; see {@link SessionPersistence.stat}. */
294
+ readonly revision: SessionPersistenceRevision
295
+ /** Logical event count, when the backend can provide it cheaply from metadata; otherwise absent. */
296
+ readonly eventCount?: number
297
+ /** Physical artifact byte size, when the backend can provide it cheaply (JSONL); otherwise absent. */
298
+ readonly sizeBytes?: number
228
299
  }
229
300
  ```
230
301
 
302
+ 可选的 `eventCount`/`sizeBytes` 提示让会话列表的冷空白探测(cold blank probe)仅凭元数据即可限定其工作量(session-controller 配置 `coldBlankProbeMaxEvents`/`coldBlankProbeMaxBytes`),而无需打开任何日志。
303
+
231
304
  ## 后端
232
305
 
233
- 两者都实现同一个抽象 `SessionPersistence`(在 `SessionEvent` 上执行 locate/create/append/prepare/load/inspect/readFrom/list/listSnapshots,观察方法可选支持取消),并通过共享的 `runPersistenceContract` 套件:
306
+ 随产品交付的 provider 实现抽象 `SessionPersistence` 约定(`create`/`open`/`stat`/`list`,逐会话 `SessionHandle` 承载 `read`/`append`/`flush`/`close`,全程可选支持取消),并通过共享的持久化契约套件:
234
307
 
235
- - **[dsh-session-persistence-jsonl](../../packages/session/session-persistence-jsonl)**——每个会话一份仅追加的逻辑 JSONL 日志,默认存储为带 checksum 的连续 Zstandard frame,也可配置为原始行;支持崩溃安全的原子写入、被中断轮次的恢复以及读取/回放路径。
236
- - **[dsh-session-persistence-sqlite](../../packages/session/session-persistence-sqlite)**:基于 `node:sqlite`,每个 `SessionEvent` 一行。行字段 `(session_id, seq, type, time, data, source_event_seqs, surface_op)` 与事件 1:1 映射(包含可选的 surface 元数据),因此没有需要保持同步的并行持久化 schema。
308
+ - **[dsh-session-persistence-jsonl](../../packages/session/session-persistence-jsonl)**——逐会话仅追加的逻辑 JSONL 日志,默认存储为带 checksum 的连续 Zstandard frame,也可配置为原始行;具备崩溃安全的原子实体化、逐批 `fsync` 的 append,以及在第一次新 append 之前截断撕裂尾部。`stat`/`list` 携带 `sizeBytes` 与尽力而为的、由 `fs.stat` 派生的修订号。
237
309
 
238
310
  <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
239
311
 
@@ -241,145 +313,83 @@ interface SessionPersistenceSnapshot {
241
313
 
242
314
  ## Cordis API
243
315
 
244
- 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).
316
+ 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).
245
317
 
246
318
  <a id="ctxsessionpersistence--sessionpersistence-abstract-seam"></a>
247
319
 
248
320
  ### `ctx.sessionPersistence` — `SessionPersistence` (abstract seam)
249
321
 
250
- Durable append-only session storage. Implementations preserve contiguous, losslessly JSON-serializable events; append resolves only after durability, and load balances a complete interrupted tail without rewriting committed events.
322
+ Durable append-only session storage addressed through per-session handles.
251
323
 
252
- ```ts cordis-catalog
253
- /**
254
- * Resolve this backend's independent local artifact for a session without
255
- * reading, creating, flushing, or otherwise materializing it. Backends such
256
- * as SQLite that do not own one artifact per session return `undefined`.
257
- * @param meta - the immutable session header whose artifact is requested.
258
- * @returns the backend-specific absolute location, when one exists.
259
- */
260
- abstract locate(meta: SessionHeader): SessionLocation | undefined
324
+ Storage semantics shared by every backend: events are contiguous from seq 0 and never rewritten; a torn physical tail is never returned to a reader and is truncated by the write path before its first append; reads validate current-format records only and refuse unknown vocabulary fail-closed. `append` persists best-effort; `flush` — per handle or service-wide — is the durability barrier.
261
325
 
262
- /**
263
- * Read a session's backend-owned artifact text verbatim — the exact durable
264
- * bytes the backend wrote (decoded from its physical encoding, e.g. a
265
- * decompressed JSONL). The returned `content` is the raw text, not a
266
- * reconstruction from parsed events, so it preserves backend-specific
267
- * serialization (chunk packing, key order, line breaks). Callers first test
268
- * {@link supportsRawArtifacts}; `undefined` then means only that the requested
269
- * session has no materialized artifact.
270
- * @param _id - the persisted session to read (unused by the default: no
271
- * per-session artifact).
272
- * @param signal - optional cancellation for backend read work.
273
- * @returns the raw artifact plus its parsed header, or `undefined` when the
274
- * session is absent.
275
- * @throws when this backend does not expose per-session raw artifacts.
276
- */
277
- readRaw(_id: SessionId, signal?: AbortSignal): Promise<SessionRawArtifact | undefined>
278
-
279
- /**
280
- * Register a new session's metadata. A backend MAY defer the physical write
281
- * until the first {@link append} (lazy materialization), in which case a
282
- * created-but-never-appended session is absent from {@link list}
283
- * — abandoned sessions leave nothing behind.
284
- * @param meta - the immutable header (id, version, cwd, lineage) to record.
285
- */
286
- abstract create(meta: SessionHeader): Promise<void>
287
-
288
- /**
289
- * Durably persist a batch of events. Honors the append-only and contiguous-
290
- * seq contracts: the first event's `seq` MUST equal the stored next-seq
291
- * (after `load` has durably closed any interrupted turn). Rejects non-JSON-
292
- * serializable `event.data` with an error naming the offending event type.
293
- * @param id - the session the batch belongs to.
294
- * @param events - the contiguous batch to persist, in seq order.
295
- */
296
- abstract append(id: SessionId, events: readonly SessionEvent[]): Promise<void>
326
+ Visibility: a created session is observable through `stat`/`list`/`open` in this process from the moment `create` resolves, even while a backend defers physical materialization (a pure optimization); other processes see the session only once it materializes, and a session that never materialized before a crash never existed. `SessionHandle.flush` forces materialization.
297
327
 
298
- /**
299
- * Prepare the exact unpublished Session used by resume. Implementations may
300
- * reuse object graphs retained by an earlier {@link inspect} after confirming
301
- * their durable revision is still current; disposal releases an unpublished
302
- * reservation. Revision retries require the durable log to remain unchanged
303
- * for one read/check round trip; continuous external writers may delay completion.
304
- * @param id - persisted session to prepare.
305
- * @param signal - optional cancellation for preparation work.
306
- * @returns one owned unpublished Session preparation.
307
- */
308
- async prepare(id: SessionId, signal?: AbortSignal): Promise<SessionPreparation>
328
+ Freshness: once an `append` or `flush` resolves, reads started afterwards on this backend instance observe at least that prefix.
309
329
 
330
+ ```ts cordis-catalog
310
331
  /**
311
- * Load an immutable balanced logical view and commit any required cold
312
- * recovery. A complete interrupted final turn is preserved and durably
313
- * closed with missing tool errors plus any open step and turn boundaries;
314
- * only a torn final record is discarded. Unknown versions and corruption in
315
- * the committed prefix reject. Implementations MUST NOT crash-repair an
316
- * identity still bound to a live Session: a balanced live log may return as a
317
- * durable snapshot, while an open live turn rejects. Returned values may be
318
- * shared with immutable live or prepared state and must not be mutated.
319
- * Revision-based implementations may wait for one stable read/check round trip.
320
- * @param id - the persisted session to reload.
321
- * @returns the header and a log ending on a balanced `turn/end`.
332
+ * Create a new stored session and take its write ownership.
333
+ * @param header - the immutable header (id, version, cwd, lineage) to store.
334
+ * @param options - optional cancellation.
335
+ * @returns a `write` handle owned by the caller; close it to release ownership.
336
+ * @throws {SessionAlreadyExistsError} when the id already exists.
322
337
  */
323
- abstract load(id: SessionId): Promise<SessionInspection>
338
+ abstract create(header: SessionHeader, options?: SessionPersistenceCreateOptions): Promise<SessionHandle>
324
339
 
325
340
  /**
326
- * Inspect an immutable logical session without committing recovery or
327
- * publishing it. A cold complete interrupted turn receives synthetic closers
328
- * in memory and a torn physical tail remains untouched. An already-live
329
- * Session instead yields its current immutable snapshot, which may contain an
330
- * open turn and its `session/end-seed` boundary. Coordinator-backed
331
- * implementations retain the exact cold unpublished Session for bounded
332
- * reuse by a later {@link prepare}. A stale ready source is reloaded; a source
333
- * already committing or reserved for resume remains exclusive, and inspection
334
- * may borrow its immutable view. Callers borrow only the immutable header and
335
- * log. Continuous external writers may delay revision convergence.
336
- * @param id - the persisted session to inspect.
337
- * @param signal - optional cancellation for queued and backend read work.
338
- * @returns the validated header and current logical event log.
341
+ * Open an existing stored session.
342
+ *
343
+ * `read` never takes ownership and works while another handle (or process)
344
+ * holds write ownership. `write` atomically claims single-writer ownership;
345
+ * an existing active owner rejects.
346
+ * @param id - the stored session to open.
347
+ * @param access - `read` or `write`.
348
+ * @param options - optional cancellation.
349
+ * @returns the open handle.
350
+ * @throws {SessionPersistenceNotFoundError} when the session does not exist.
351
+ * @throws {SessionAlreadyOwnedError} for `write` when ownership is taken.
339
352
  */
340
- abstract inspect(id: SessionId, signal?: AbortSignal): Promise<SessionInspection>
353
+ abstract open(id: SessionId, access: SessionAccess, options?: SessionPersistenceOpenOptions): Promise<SessionHandle>
341
354
 
342
355
  /**
343
- * Read the stored events from `fromSeq` onward the read-from-seq
344
- * primitive for read models that resume from a watermark (e.g. a persisted
345
- * projection cache folding only the tail past its checkpoint). Unlike
346
- * {@link inspect}, it is a detached physical suffix read: no preparation
347
- * cache, torn-tail truncation, synthetic closers, or coordinator-state
348
- * publication. Only events from the valid contiguous stored prefix are
349
- * returned, so a torn fragment never reaches the caller. `fromSeq` at or
350
- * beyond the stored prefix returns an empty event list (never an error).
351
- * Backends whose medium can seek by seq
352
- * (SQLite) read only the suffix; sequential media (JSONL, both encodings)
353
- * still parse the whole artifact and skip forward — the primitive bounds
354
- * what is RETURNED and refolded, not every backend's physical read.
355
- * @param id - the persisted session to read.
356
- * @param fromSeq - first event seq to include; a non-negative safe integer.
357
- * @param signal - optional cancellation for queued and backend read work.
358
- * @returns the header and the stored events with `seq >= fromSeq`.
356
+ * Flush every active write handle owned by this service instance in one
357
+ * durability barrier: each handle's routed live events drain durably and
358
+ * its session materializes, exactly as that handle's own
359
+ * `SessionHandle.flush` would. Read handles buffer nothing and are
360
+ * untouched. A handle closed concurrently counts as flushed — close itself
361
+ * drains durably.
362
+ * @returns resolution once every write handle active at the call has flushed.
363
+ * @throws {AggregateError} naming each session whose flush failed; the
364
+ * remaining handles still flush.
359
365
  */
360
- abstract readFrom(id: SessionId, fromSeq: number, signal?: AbortSignal): Promise<{ meta: SessionHeader; events: SessionEvent[] }>
366
+ abstract flush(): Promise<void>
361
367
 
362
368
  /**
363
- * Lightweight listing from metadata, without a full-log parse.
364
- * @param signal - optional cancellation for backend listing work.
365
- * @returns one header per materialized session.
369
+ * Observe one stored session without reading its event log or taking
370
+ * ownership.
371
+ *
372
+ * The snapshot's `revision` is an opaque change token comparable only
373
+ * against revisions from the same service instance and session id: equal
374
+ * revisions may be treated as an unchanged log; unequal revisions promise
375
+ * nothing. Write-ownership churn does not change a revision. It exists for
376
+ * derived read-model caches keyed off `stat`/`list`; it plays no part in
377
+ * open, read, or resume.
378
+ * @param id - the stored session to observe.
379
+ * @param options - optional cancellation.
380
+ * @returns the snapshot, or `undefined` when the session does not exist.
366
381
  */
367
- abstract list(signal?: AbortSignal): Promise<SessionHeader[]>
382
+ abstract stat(id: SessionId, options?: SessionPersistenceStatOptions): Promise<SessionPersistenceSnapshot | undefined>
368
383
 
369
384
  /**
370
- * List materialized sessions with cheap per-log change tokens.
371
- *
372
- * Repeated observations of an unchanged log return the same revision. A
373
- * successful mutating {@link load} repair changes the next listed revision.
374
- * Revisions also distinguish independently backed stores so backend-local
375
- * counters cannot compare equal across different persistence sources.
376
- * @param signal - optional cancellation for backend snapshot-listing work.
377
- * @returns one header and opaque revision per materialized session without loading full logs.
385
+ * List every stored session visible to this process, in no promised order.
386
+ * @param options - optional cancellation.
387
+ * @returns one snapshot per stored session.
378
388
  */
379
- abstract listSnapshots(signal?: AbortSignal): Promise<SessionPersistenceSnapshot[]>
389
+ abstract list(options?: SessionPersistenceListOptions): Promise<readonly SessionPersistenceSnapshot[]>
380
390
  ```
381
391
 
382
- Types: [SessionEvent](session.md) · [SessionId](core.md)
392
+ Types: [SessionId](core.zh.md)
383
393
 
384
- Source: [`packages/session/session-persistence/src/index.ts:84`](../../packages/session/session-persistence/src/index.ts)
394
+ Source: [`packages/session/session-persistence/src/index.ts`](../../packages/session/session-persistence/src/index.ts)
385
395
  <!-- 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/plan.md
5
- plan.md: 4e6eb98e7c7cce295feeed0150984934f1a853e5
6
- plan.zh.md: f8236e6cbeca841bdab630aa831e844cc68179a0
5
+ plan.md: 913a5acb45d0a0be684795cf1ff294ca9d464df1
6
+ plan.zh.md: 98e926346b66a97695fae9516bd87818e764ba01
@@ -8,7 +8,7 @@ Source: [`packages/plan/plan-mode/src/index.ts`](../../packages/plan/plan-mode/s
8
8
 
9
9
  ## Logged state and recovery
10
10
 
11
- `plan/mode` (`{ active: boolean }`) is a log-only, whole-value-replace [session event](session.md): durable and replayable, never in the model transcript. `foldPlanMode(events, end?)` returns the last logged value in the prefix, or `false` when there is none the state in force is always a pure fold of the session log, so resume, fork, and compaction recover it with no live mirror, and UIs observe committed flips through `session/event`. The complete event declaration is in the [persistence log event catalog](../persistence-catalog.md).
11
+ `plan/mode` (`{ active: boolean }`) is a log-only, whole-value-replace [session event](session.md): durable and replayable, never in the model transcript. The optionally registered `plan` unit folds committed mode, command settlement, and the mode recorded at the latest request header. `ctx.planMode` reads that state through `stateOf()`; the first dependent access fails if the registry, `plan` key, or `turnBoundary` key is absent. Clients receive only `{ active, pending }`; resume, fork, and compaction recover both from the log. The complete event declaration is in the [persistence log event catalog](../persistence-catalog.md).
12
12
 
13
13
  ## Pending selections and the pre-step append
14
14
 
@@ -44,13 +44,13 @@ When [`ctx.commands`](commands.md) is composed, the plugin registers `/plan [off
44
44
 
45
45
  ## Cordis API
46
46
 
47
- 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).
47
+ 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).
48
48
 
49
49
  <a id="ctxplanmode--planmodecontroller"></a>
50
50
 
51
51
  ### `ctx.planMode` — `PlanModeController`
52
52
 
53
- `ctx.planMode`: owns logged plan state, applies and narrates selected state at step start, the `plan:policy` section, the `/plan` command, and the stable exit tool. UIs observe committed flips through `session/event`; there is no live mirror.
53
+ `ctx.planMode`: owns logged plan state, applies and narrates selected state at step start, the `plan:policy` section, the `/plan` command, and the stable exit tool. Client carriers expose the projection's cropped `{ active, pending }` view.
54
54
 
55
55
  ```ts cordis-catalog
56
56
  /**
@@ -83,5 +83,5 @@ set(agent: Agent, active: boolean): 'committed' | 'queued' | 'cancelled' | 'noop
83
83
 
84
84
  Types: [Agent](core.md)
85
85
 
86
- Source: [`packages/plan/plan-mode/src/index.ts:184`](../../packages/plan/plan-mode/src/index.ts)
86
+ Source: [`packages/plan/plan-mode/src/index.ts`](../../packages/plan/plan-mode/src/index.ts)
87
87
  <!-- END GENERATED cordis-surface -->