@chatcode/chatcode-cli 3.0.3 → 3.0.4-rc.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 (243) hide show
  1. package/README.i18n.yaml +10 -10
  2. package/README.md +16 -1
  3. package/README.zh.md +16 -1
  4. package/lib/bin.js +62 -11
  5. package/lib/{command-errors-CBJRI2gy.js → command-errors-CScdshCl.js} +12 -12
  6. package/lib/{command-trees-Dvq4C7a4.js → command-trees-Dc17MYfV.js} +2 -2
  7. package/lib/{component-identity-DPdJglJO.js → component-identity-DFJD_d-P.js} +3 -3
  8. package/lib/{dump-config-CauO75nE.js → dump-config-BcH-VYuv.js} +5 -5
  9. package/lib/dump-config-CyopmD85.js +2 -0
  10. package/lib/{dump-config-schema-CObLWWaW.js → dump-config-schema-DM0fb6Ns.js} +2 -2
  11. package/lib/{extension-events-Be9LWvHD.js → extension-events-qXmhzmHo.js} +20 -20
  12. package/lib/{frames-7PAg0Q9b.js → frames-B89znn_0.js} +4 -4
  13. package/lib/headless-compat.js +2 -2
  14. package/lib/{host-access-DeCjoRQP.js → host-access-B0CRAwsX.js} +1 -1
  15. package/lib/{keymap-CRUxM_qn.js → keymap-CIoVICBI.js} +17 -16
  16. package/lib/{plugin-CDFSDE_y.js → plugin-BKQsL2xn.js} +3264 -2301
  17. package/lib/{plugin-Cn-hyYY8.js → plugin-eJjD6r12.js} +1 -1
  18. package/lib/{profile-boot-SJGbpLgN.js → profile-boot-BNQry1NM.js} +97 -14
  19. package/lib/profile-boot.js +2 -2
  20. package/lib/{scenes-D6jV1EEi.js → scenes-BRf-zMpF.js} +3 -3
  21. package/lib/{settings-sections-DJQRNBo9.js → settings-sections-4gMhveN_.js} +7 -3
  22. package/lib/statusBarSettings-CnmdSHkO.js +382 -0
  23. package/lib/{themes-BCly4_y9.js → themes-Ce97Zsri.js} +13 -13
  24. package/lib/tui-compat-command-trees.js +1 -1
  25. package/lib/tui-compat-extensions.js +3 -3
  26. package/lib/tui-compat-plugin-host.js +5 -5
  27. package/lib/tui-compat-scenes.js +1 -1
  28. package/lib/tui-compat-settings-sections.js +1 -1
  29. package/lib/tui-compat-working-activity.js +4 -4
  30. package/lib/tui-compat-workspaces.js +1 -1
  31. package/lib/tui-compat.js +9 -26
  32. package/lib/types/args.d.ts +2 -0
  33. package/lib/types/permission-bypass.d.ts +16 -0
  34. package/lib/types/profile-boot.d.ts +12 -0
  35. package/lib/types/tui-compat.d.ts +4 -0
  36. package/lib/types/web-browser.d.ts +6 -0
  37. package/lib/types/web-instance.d.ts +42 -0
  38. package/lib/web-browser-Vcgfdsv_.js +46 -0
  39. package/lib/web-instance-B0jec7cq.js +2 -0
  40. package/lib/web-instance-DbP7IHPv.js +280 -0
  41. package/lib/{workspaces-Bb3kCAFb.js → workspaces-1xrm-e3V.js} +2 -2
  42. package/package.json +36 -33
  43. package/runtime/manifest.json +4 -2
  44. package/runtime/node_modules/@deepseek-ai/dsh-agent-default-model/lib/index.js +137 -11
  45. package/runtime/node_modules/@deepseek-ai/dsh-agent-default-model/lib/types/index.d.ts +27 -1
  46. package/runtime/node_modules/@deepseek-ai/dsh-agent-preset/skills/cordis-composition-reference/references/packages.md +2 -1
  47. package/runtime/node_modules/@deepseek-ai/dsh-api-gateway/lib/client.js +2 -0
  48. package/runtime/node_modules/@deepseek-ai/dsh-api-gateway/lib/types/client/remote-stream.js +4 -0
  49. package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/client.js +152 -39
  50. package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/index.js +4 -0
  51. package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/types/remote-events.d.ts +3 -0
  52. package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/types/remote-events.js +1 -0
  53. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/index.js +179 -35
  54. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.host.js +57 -30
  55. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.js +31 -19
  56. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.d.ts +9 -1
  57. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.js +36 -6
  58. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/archived-session-gate.js +1 -1
  59. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/catalog.js +12 -2
  60. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.d.ts +1 -1
  61. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.d.ts +2 -2
  62. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.js +24 -8
  63. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.d.ts +4 -3
  64. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.js +31 -14
  65. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/list.d.ts +6 -0
  66. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/list.js +89 -4
  67. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/remote-events.d.ts +1 -1
  68. package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/types.d.ts +27 -0
  69. package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/index.js +28 -1
  70. package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/typert.host.js +39 -0
  71. package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/typert.remote-client.d.ts +2 -0
  72. package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/typert.remote-client.js +32 -0
  73. package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/types/index.d.ts +8 -0
  74. package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/types/index.js +19 -1
  75. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/client.js +30 -0
  76. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/index.js +111 -2
  77. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/typert.host.js +104 -11
  78. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/typert.remote-client.d.ts +5 -1
  79. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/typert.remote-client.js +78 -11
  80. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/model.d.ts +14 -1
  81. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/model.js +17 -0
  82. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/service.d.ts +15 -0
  83. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/service.js +12 -0
  84. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/commands.d.ts +13 -1
  85. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/commands.js +44 -2
  86. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/feed.js +17 -0
  87. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/index.d.ts +13 -1
  88. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/index.js +22 -0
  89. package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/types.d.ts +17 -0
  90. package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js +67 -19
  91. package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/types/index.d.ts +1 -1
  92. package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/types/profile-context.d.ts +11 -1
  93. package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/worker/profile-resolution-bootstrap.js +22 -3
  94. package/runtime/node_modules/@deepseek-ai/dsh-base/cordis.patch.yml +9 -3
  95. package/runtime/node_modules/@deepseek-ai/dsh-base/package.json +2 -1
  96. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/client.js +931 -7
  97. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/index.js +57 -19
  98. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/client/index.d.ts +5 -2
  99. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/config.d.ts +12 -0
  100. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/events.d.ts +4 -4
  101. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/index.d.ts +3 -8
  102. package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/package.json +6 -2
  103. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-chat/lib/client.js +3 -2
  104. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-chat/lib/types/index.d.ts +2 -2
  105. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-commands/lib/client.js +10 -0
  106. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js +1 -1
  107. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/types/client/present-open.d.ts +1 -1
  108. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-goal/lib/client.js +1 -1
  109. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/client.js +68 -16
  110. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/types/client/directory.d.ts +3 -1
  111. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/types/client/locales.d.ts +6 -0
  112. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-primitives/lib/markdown/CodeBlock.module.css +3 -5
  113. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-primitives/lib/markdown/MarkdownText.module.css +23 -27
  114. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings/lib/types/client/contract/slots.d.ts +3 -1
  115. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-account/lib/client.js +2 -2
  116. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-account/lib/types/index.d.ts +2 -2
  117. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/client.js +8 -7
  118. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/types/client/SettingsDocumentAction.d.ts +1 -1
  119. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/types/client/settings-document-store.d.ts +2 -1
  120. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-models/lib/client.js +33 -12
  121. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-models/lib/types/client/locales.d.ts +2 -0
  122. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-plugin-inventory/lib/client.js +1 -1
  123. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar/lib/client.js +3 -1
  124. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-theme/lib/client.js +1 -1
  125. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/client.js +1925 -207
  126. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/ArchivedSessions.d.ts +13 -0
  127. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/contract/slots.d.ts +4 -0
  128. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/locales.d.ts +42 -0
  129. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/recent.d.ts +11 -0
  130. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/rows/RecentList.d.ts +15 -0
  131. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/rows/Rows.d.ts +6 -1
  132. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/session-actions/DeleteSession.d.ts +24 -0
  133. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/stores.d.ts +2 -2
  134. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/tree.d.ts +15 -13
  135. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/package.json +3 -1
  136. package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/index.js +16 -0
  137. package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/typert.host.js +7 -3
  138. package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/typert.remote-client.js +6 -2
  139. package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/types/index.js +20 -0
  140. package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/types/types.d.ts +5 -0
  141. package/runtime/node_modules/@deepseek-ai/dsh-computer-use/lib/index.js +35 -0
  142. package/runtime/node_modules/@deepseek-ai/dsh-computer-use/lib/types/brand.d.ts +11 -0
  143. package/runtime/node_modules/@deepseek-ai/dsh-computer-use/lib/types/brand.js +10 -0
  144. package/runtime/node_modules/@deepseek-ai/dsh-computer-use/lib/types/index.d.ts +28 -0
  145. package/runtime/node_modules/@deepseek-ai/dsh-computer-use/lib/types/index.js +36 -0
  146. package/runtime/node_modules/@deepseek-ai/dsh-computer-use/package.json +42 -0
  147. package/runtime/node_modules/@deepseek-ai/dsh-config-editor/lib/index.js +102 -14
  148. package/runtime/node_modules/@deepseek-ai/dsh-config-editor/lib/types/index.d.ts +34 -4
  149. package/runtime/node_modules/@deepseek-ai/dsh-config-editor/package.json +1 -0
  150. package/runtime/node_modules/@deepseek-ai/dsh-cordis-client-runner/lib/client.js +5 -2
  151. package/runtime/node_modules/@deepseek-ai/dsh-host-webserver/lib/index.js +2 -1
  152. package/runtime/node_modules/@deepseek-ai/dsh-native-command/lib/index.js +21 -8
  153. package/runtime/node_modules/@deepseek-ai/dsh-native-command/lib/types/path-opener.d.ts +4 -6
  154. package/runtime/node_modules/@deepseek-ai/dsh-native-command/lib/types/path-opener.js +18 -7
  155. package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/index.js +4 -0
  156. package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/typert.host.js +5 -5
  157. package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/typert.remote-client.js +5 -5
  158. package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/types/index.js +5 -0
  159. package/runtime/node_modules/@deepseek-ai/dsh-session/lib/types/index.d.ts +21 -0
  160. package/runtime/node_modules/@deepseek-ai/dsh-session-persistence/lib/index.js +12 -0
  161. package/runtime/node_modules/@deepseek-ai/dsh-session-persistence/lib/types/index.d.ts +15 -0
  162. package/runtime/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/index.js +95 -2
  163. package/runtime/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/types/index.d.ts +3 -1
  164. package/runtime/node_modules/@deepseek-ai/dsh-session-projection-cache/lib/index.js +25 -1
  165. package/runtime/node_modules/@deepseek-ai/dsh-session-projection-cache/lib/types/index.d.ts +1 -0
  166. package/runtime/node_modules/@deepseek-ai/dsh-session-projection-cache/package.json +2 -1
  167. package/runtime/node_modules/@deepseek-ai/dsh-session-query/lib/index.js +13 -0
  168. package/runtime/node_modules/@deepseek-ai/dsh-session-query/lib/types/observation.d.ts +5 -0
  169. package/runtime/node_modules/@deepseek-ai/dsh-session-query-sqlite/lib/index.js +26 -0
  170. package/runtime/node_modules/@deepseek-ai/dsh-session-query-sqlite/package.json +2 -1
  171. package/runtime/node_modules/@deepseek-ai/dsh-settings/lib/index.js +5 -4
  172. package/runtime/node_modules/@deepseek-ai/dsh-settings/lib/types/index.d.ts +4 -3
  173. package/runtime/node_modules/@deepseek-ai/dsh-settings/lib/types/index.js +4 -3
  174. package/runtime/node_modules/@deepseek-ai/dsh-storage/lib/types/backend.d.ts +4 -0
  175. package/runtime/node_modules/@deepseek-ai/dsh-storage-domain/lib/index.js +65 -1
  176. package/runtime/node_modules/@deepseek-ai/dsh-storage-domain/lib/types/domain.d.ts +17 -2
  177. package/runtime/node_modules/@deepseek-ai/dsh-storage-json/lib/index.js +25 -0
  178. package/runtime/node_modules/@deepseek-ai/dsh-storage-json/package.json +1 -0
  179. package/runtime/node_modules/@deepseek-ai/dsh-subagent/lib/types/control.d.ts +1 -1
  180. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/index.js +5522 -0
  181. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/command-args.d.ts +17 -0
  182. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/commands/tianti/cicd.d.ts +8 -0
  183. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/commands/tianti/tianti.d.ts +7 -0
  184. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/commands/tianti-deliver/tianti-deliver.d.ts +8 -0
  185. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/config.d.ts +27 -0
  186. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/index.d.ts +13 -0
  187. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/memory-config.d.ts +10 -0
  188. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/runtime.d.ts +105 -0
  189. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/aliases.d.ts +11 -0
  190. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/auth.d.ts +20 -0
  191. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/client.d.ts +206 -0
  192. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/config.d.ts +22 -0
  193. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/index.d.ts +6 -0
  194. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/log.d.ts +16 -0
  195. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/types.d.ts +136 -0
  196. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/codebase.d.ts +19 -0
  197. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/dynamicWorkflow.d.ts +10 -0
  198. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/engine.d.ts +8 -0
  199. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/executor.d.ts +11 -0
  200. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/executors.d.ts +15 -0
  201. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/index.d.ts +23 -0
  202. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/memorySuggestions.d.ts +12 -0
  203. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/openspec.d.ts +31 -0
  204. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/recommend.d.ts +8 -0
  205. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/render.d.ts +8 -0
  206. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/requirementContext.d.ts +12 -0
  207. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/scenarioUpgrade.d.ts +24 -0
  208. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/state.d.ts +16 -0
  209. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/store.d.ts +33 -0
  210. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/templates.d.ts +8 -0
  211. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/types.d.ts +385 -0
  212. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/writeReviewSync.d.ts +6 -0
  213. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/writeReview/index.d.ts +29 -0
  214. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/writeReview/store.d.ts +20 -0
  215. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/writeReview/types.d.ts +49 -0
  216. package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/tools.d.ts +12 -0
  217. package/runtime/node_modules/@deepseek-ai/dsh-tianti/package.json +57 -0
  218. package/runtime/node_modules/@deepseek-ai/dsh-tool-cordis/lib/types/api-catalog.js +157 -22
  219. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-D5kpKf--.css +1 -0
  220. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-Dz_cDcce.js +133 -0
  221. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-Dz_cDcce.js.map +1 -0
  222. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/chatcode-apple-touch-icon.png +0 -0
  223. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/chatcode-icon-32.png +0 -0
  224. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/chatcode-mask-icon.svg +1 -0
  225. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/favicon-dark.svg +1 -3
  226. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/favicon.ico +0 -0
  227. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/favicon.svg +1 -3
  228. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/index.html +8 -4
  229. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/preview.html +8 -4
  230. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/package.json +2 -1
  231. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/index.js +325 -37
  232. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/invariant.js +6 -1
  233. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/entity.d.ts +6 -0
  234. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/entity.js +23 -17
  235. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.d.ts +41 -0
  236. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.js +314 -23
  237. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/spec.d.ts +4 -0
  238. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/spec.js +4 -0
  239. package/lib/dump-config-CijLv_kn.js +0 -2
  240. package/lib/tuiDisplayPrefs-Dm_fULiR.js +0 -204
  241. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-DUvMhLle.css +0 -1
  242. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-Q6zc2uHV.js +0 -127
  243. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-Q6zc2uHV.js.map +0 -1
@@ -36,6 +36,10 @@ export class WorkspaceEntity {
36
36
  this.id = id;
37
37
  this.record = record;
38
38
  }
39
+ /** Replace the cached record without changing this entity's identity.
40
+ * @param record Latest validated workspace record.
41
+ */
42
+ replace(record) { this.record = record; }
39
43
  get path() {
40
44
  return this.record.path;
41
45
  }
@@ -134,23 +138,25 @@ export class WorkspaceEntity {
134
138
  * rewrites the medium nor emits a change event.
135
139
  */
136
140
  async mutate(fn) {
137
- let next;
138
- try {
139
- next = await this.host.table().update(this.id, (current) => {
140
- const changed = fn(current);
141
- const sessionIds = changed.sessionIds.filter(id => this.host.sessionPath(id) === changed.path);
142
- if (changed === current && sessionIds.length === current.sessionIds.length) {
143
- throw unchangedSentinel;
144
- }
145
- return { ...changed, sessionIds, updatedAt: new Date().toISOString() };
146
- });
147
- }
148
- catch (error) {
149
- if (error === unchangedSentinel)
150
- return;
151
- throw error;
152
- }
153
- this.record = next;
141
+ await this.host.enqueue(async () => {
142
+ let next;
143
+ try {
144
+ next = await this.host.table().update(this.id, (current) => {
145
+ const changed = fn(current);
146
+ const sessionIds = changed.sessionIds.filter(id => this.host.sessionPath(id) === changed.path);
147
+ if (changed === current && sessionIds.length === current.sessionIds.length) {
148
+ throw unchangedSentinel;
149
+ }
150
+ return { ...changed, sessionIds, updatedAt: new Date().toISOString() };
151
+ });
152
+ }
153
+ catch (error) {
154
+ if (error === unchangedSentinel)
155
+ return;
156
+ throw error;
157
+ }
158
+ this.record = next;
159
+ });
154
160
  }
155
161
  }
156
162
  //# sourceMappingURL=entity.js.map
@@ -55,6 +55,16 @@ export declare class WorkspaceArchivedSessionPinError extends Error {
55
55
  */
56
56
  constructor(sessionId: SessionId);
57
57
  }
58
+ /** Permanent deletion requires an archived root and no active Session ownership. */
59
+ export declare class WorkspaceSessionDeletionError extends Error {
60
+ readonly sessionId: SessionId;
61
+ readonly reason: 'not-archived' | 'in-use' | 'deleted' | 'scope-changed';
62
+ /**
63
+ * @param sessionId - identity whose lifecycle prevents the requested operation.
64
+ * @param reason - stable refusal discriminant shared by the Web and TUI.
65
+ */
66
+ constructor(sessionId: SessionId, reason: 'not-archived' | 'in-use' | 'deleted' | 'scope-changed');
67
+ }
58
68
  /** A workspace reorder named a source or anchor absent from the durable registry order. */
59
69
  export declare class WorkspaceOrderInvalidError extends Error {
60
70
  readonly workspaceId: WorkspaceId;
@@ -82,6 +92,10 @@ declare module '@deepseek-ai/cordis' {
82
92
  workspaceRegistry: WorkspaceRegistry;
83
93
  }
84
94
  interface Events {
95
+ /** A refreshed cross-process workspace projection is ready for consumers.
96
+ * @mode emit
97
+ */
98
+ 'workspace/refreshed'(): void;
85
99
  /**
86
100
  * Ask the composed providers what still runs for a session before it is
87
101
  * archived. A listener prepends its own {@link SessionActivity} entries to
@@ -120,6 +134,7 @@ declare module '@deepseek-ai/cordis' {
120
134
  export declare class WorkspaceRegistry extends Service {
121
135
  static inject: string[];
122
136
  private table?;
137
+ private domain?;
123
138
  private global?;
124
139
  private state?;
125
140
  private readonly entities;
@@ -127,10 +142,14 @@ export declare class WorkspaceRegistry extends Service {
127
142
  private readonly sessionPaths;
128
143
  private readonly invalidSessionPaths;
129
144
  private operationTail;
145
+ private stopping;
146
+ private refreshedState;
130
147
  private readonly host;
131
148
  constructor(ctx: Context);
132
149
  /** Open the domain, finish bootstrap when required, and rebuild the ordered cache. */
133
150
  protected [Service.init](): Promise<void>;
151
+ /** Refresh shared membership, pins and archives before reading a new view; never auto-attach detached sessions. */
152
+ refresh(): Promise<void>;
134
153
  /**
135
154
  * Create or reuse a workspace for an existing directory. The fully qualified
136
155
  * path is canonicalized through `fs.realpath`; a relative, nonexistent, or
@@ -193,6 +212,27 @@ export declare class WorkspaceRegistry extends Service {
193
212
  * @returns the archived session ids in archive order.
194
213
  */
195
214
  get archivedSessionIds(): readonly SessionId[];
215
+ /** Permanently deleted identities retained for cross-process invalidation and stale-operation refusal. */
216
+ get deletedSessionIds(): readonly SessionId[];
217
+ /**
218
+ * Permanently delete an archived, inactive root and its owned subagent descendants.
219
+ * Independent forks are preserved. Reserve every writer before recording a recovery
220
+ * marker; a failure after that marker is retried on refresh or restart.
221
+ * @param sessionId - archived root identity; repeated deletion is idempotent.
222
+ * @param expectedIds - identities confirmed by the user; a changed scope refuses deletion.
223
+ * @returns deleted root and descendant identities after durable cleanup.
224
+ */
225
+ deleteSession(sessionId: SessionId, expectedIds?: readonly SessionId[]): Promise<readonly SessionId[]>;
226
+ /**
227
+ * Preview the root and owned descendants without opening their histories.
228
+ * @param sessionId - archived root to preview.
229
+ * @returns identities to show in the deletion confirmation.
230
+ */
231
+ sessionDeletionScope(sessionId: SessionId): Promise<readonly SessionId[]>;
232
+ private collectSessionDeletionScope;
233
+ private recoverSessionDeletion;
234
+ private notifyDeleted;
235
+ private finishSessionDeletion;
196
236
  /**
197
237
  * Archive one session durably. The session must exist (live or in session
198
238
  * persistence); its workspace accounting — or lack of one — is irrelevant.
@@ -285,6 +325,7 @@ export declare class WorkspaceRegistry extends Service {
285
325
  private requireState;
286
326
  private setState;
287
327
  private enqueueOperation;
328
+ private snapshotIdentity;
288
329
  }
289
330
  export default WorkspaceRegistry;
290
331
  //# sourceMappingURL=index.d.ts.map
@@ -4,9 +4,62 @@
4
4
  * domain data form.
5
5
  * @module @deepseek-ai/dsh-workspace
6
6
  */
7
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
8
+ if (value !== null && value !== void 0) {
9
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
10
+ var dispose, inner;
11
+ if (async) {
12
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
13
+ dispose = value[Symbol.asyncDispose];
14
+ }
15
+ if (dispose === void 0) {
16
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
17
+ dispose = value[Symbol.dispose];
18
+ if (async) inner = dispose;
19
+ }
20
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
21
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
22
+ env.stack.push({ value: value, dispose: dispose, async: async });
23
+ }
24
+ else if (async) {
25
+ env.stack.push({ async: true });
26
+ }
27
+ return value;
28
+ };
29
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
30
+ return function (env) {
31
+ function fail(e) {
32
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
33
+ env.hasError = true;
34
+ }
35
+ var r, s = 0;
36
+ function next() {
37
+ while (r = env.stack.pop()) {
38
+ try {
39
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
40
+ if (r.dispose) {
41
+ var result = r.dispose.call(r.value);
42
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
43
+ }
44
+ else s |= 1;
45
+ }
46
+ catch (e) {
47
+ fail(e);
48
+ }
49
+ }
50
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
51
+ if (env.hasError) throw env.error;
52
+ }
53
+ return next();
54
+ };
55
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
56
+ var e = new Error(message);
57
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
58
+ });
7
59
  import { randomUUID } from 'node:crypto';
8
60
  import { mkdir, stat } from 'node:fs/promises';
9
61
  import { Service } from '@deepseek-ai/cordis';
62
+ import { SessionAlreadyOwnedError } from '@deepseek-ai/dsh-session-persistence';
10
63
  import { WorkspaceEntity } from "./entity.js";
11
64
  export { WorkspaceMoveInvalidError } from "./entity.js";
12
65
  import { defaultWorkspaceTitle, fullyQualifiedWorkspacePath, realpathNormalize } from "./paths.js";
@@ -69,6 +122,21 @@ export class WorkspaceArchivedSessionPinError extends Error {
69
122
  this.name = 'WorkspaceArchivedSessionPinError';
70
123
  }
71
124
  }
125
+ /** Permanent deletion requires an archived root and no active Session ownership. */
126
+ export class WorkspaceSessionDeletionError extends Error {
127
+ sessionId;
128
+ reason;
129
+ /**
130
+ * @param sessionId - identity whose lifecycle prevents the requested operation.
131
+ * @param reason - stable refusal discriminant shared by the Web and TUI.
132
+ */
133
+ constructor(sessionId, reason) {
134
+ super(`cannot delete session '${sessionId}': ${reason}`);
135
+ this.sessionId = sessionId;
136
+ this.reason = reason;
137
+ this.name = 'WorkspaceSessionDeletionError';
138
+ }
139
+ }
72
140
  /** A workspace reorder named a source or anchor absent from the durable registry order. */
73
141
  export class WorkspaceOrderInvalidError extends Error {
74
142
  workspaceId;
@@ -93,6 +161,7 @@ const compareHeaders = (left, right) => right.createdAt - left.createdAt || Stri
93
161
  export class WorkspaceRegistry extends Service {
94
162
  static inject = ['storageDomain', 'sessionPersistence'];
95
163
  table;
164
+ domain;
96
165
  global;
97
166
  state;
98
167
  entities = new Map();
@@ -100,8 +169,11 @@ export class WorkspaceRegistry extends Service {
100
169
  sessionPaths = new Map();
101
170
  invalidSessionPaths = new Map();
102
171
  operationTail = Promise.resolve();
172
+ stopping = false;
173
+ refreshedState = '';
103
174
  host = {
104
175
  table: () => this.requireTable(),
176
+ enqueue: operation => this.enqueueOperation(operation),
105
177
  sessionPath: id => this.sessionPaths.get(id),
106
178
  readSessionHeader: id => this.readSessionHeader(id),
107
179
  rememberSessionPath: (id, path) => {
@@ -115,24 +187,57 @@ export class WorkspaceRegistry extends Service {
115
187
  /** Open the domain, finish bootstrap when required, and rebuild the ordered cache. */
116
188
  async [Service.init]() {
117
189
  const domain = await this.ctx.storageDomain.open(workspaceDomainSpec);
118
- this.ctx.effect(() => () => domain.close(), 'workspace.domainClose');
190
+ this.domain = domain;
191
+ let timer;
192
+ this.ctx.effect(() => async () => {
193
+ this.stopping = true;
194
+ clearTimeout(timer);
195
+ await this.operationTail;
196
+ await domain.close();
197
+ }, 'workspace.domainClose');
119
198
  this.table = domain.table('workspaces');
120
199
  this.global = domain.global;
121
200
  this.state = domain.global.get();
122
- await this.recoverPendingMutation();
123
- this.validateStoredState(this.state);
124
- if (!this.state.initialized) {
125
- const headers = await this.listStoredHeaders();
126
- await this.replaceHeaderIndex(headers);
127
- await this.bootstrap(headers);
128
- }
129
- else if (this.table.size > 0) {
130
- await this.replaceHeaderIndex(await this.listStoredHeaders());
131
- }
132
- await this.indexLiveSessions();
133
- this.validateStoredState(this.requireState());
134
- this.rebuildEntities();
135
- this.reportFilteredCandidates();
201
+ await domain.exclusive(async () => {
202
+ await domain.refresh();
203
+ this.state = domain.global.get();
204
+ await this.recoverPendingMutation();
205
+ await this.recoverSessionDeletion();
206
+ this.validateStoredState(this.requireState());
207
+ if (!this.requireState().initialized) {
208
+ const headers = await this.listStoredHeaders();
209
+ await this.replaceHeaderIndex(headers);
210
+ await this.bootstrap(headers);
211
+ }
212
+ else if (this.requireTable().size > 0) {
213
+ await this.replaceHeaderIndex(await this.listStoredHeaders());
214
+ }
215
+ await this.indexLiveSessions();
216
+ this.validateStoredState(this.requireState());
217
+ this.rebuildEntities();
218
+ this.reportFilteredCandidates();
219
+ this.refreshedState = this.snapshotIdentity();
220
+ });
221
+ const poll = async () => {
222
+ try {
223
+ await this.refresh();
224
+ }
225
+ catch (error) {
226
+ this.ctx.logger.warn(`workspace: shared state refresh failed: ${String(error)}`);
227
+ }
228
+ finally {
229
+ if (!this.stopping) {
230
+ timer = setTimeout(() => { void poll(); }, 1500);
231
+ timer.unref();
232
+ }
233
+ }
234
+ };
235
+ timer = setTimeout(() => { void poll(); }, 1500);
236
+ timer.unref();
237
+ }
238
+ /** Refresh shared membership, pins and archives before reading a new view; never auto-attach detached sessions. */
239
+ refresh() {
240
+ return this.enqueueOperation(async () => { });
136
241
  }
137
242
  /**
138
243
  * Create or reuse a workspace for an existing directory. The fully qualified
@@ -260,6 +365,144 @@ export class WorkspaceRegistry extends Service {
260
365
  get archivedSessionIds() {
261
366
  return this.requireState().archivedSessionIds;
262
367
  }
368
+ /** Permanently deleted identities retained for cross-process invalidation and stale-operation refusal. */
369
+ get deletedSessionIds() {
370
+ return this.requireState().deletedSessionIds ?? [];
371
+ }
372
+ /**
373
+ * Permanently delete an archived, inactive root and its owned subagent descendants.
374
+ * Independent forks are preserved. Reserve every writer before recording a recovery
375
+ * marker; a failure after that marker is retried on refresh or restart.
376
+ * @param sessionId - archived root identity; repeated deletion is idempotent.
377
+ * @param expectedIds - identities confirmed by the user; a changed scope refuses deletion.
378
+ * @returns deleted root and descendant identities after durable cleanup.
379
+ */
380
+ deleteSession(sessionId, expectedIds) {
381
+ return this.enqueueOperation(async () => {
382
+ const env_1 = { stack: [], error: void 0, hasError: false };
383
+ try {
384
+ if (this.deletedSessionIds.includes(sessionId))
385
+ return [sessionId];
386
+ if (!this.archivedSessionIds.includes(sessionId))
387
+ throw new WorkspaceSessionDeletionError(sessionId, 'not-archived');
388
+ const ids = new Set(await this.collectSessionDeletionScope(sessionId));
389
+ if (expectedIds !== undefined && (expectedIds.length !== ids.size
390
+ || new Set(expectedIds).size !== ids.size || expectedIds.some(id => !ids.has(id)))) {
391
+ throw new WorkspaceSessionDeletionError(sessionId, 'scope-changed');
392
+ }
393
+ for (const id of ids) {
394
+ const activity = await this.ctx.waterfall('workspace/session-activity', { sessionId: id }, () => Promise.resolve([]));
395
+ if (activity.length > 0)
396
+ throw new WorkspaceActiveSessionError(id, activity);
397
+ }
398
+ const targets = [...ids];
399
+ await this.ctx.parallel('session/delete-release', { sessionIds: targets });
400
+ for (const id of ids) {
401
+ if (this.ctx.get('sessions')?.get(id) !== undefined)
402
+ throw new WorkspaceSessionDeletionError(id, 'in-use');
403
+ }
404
+ const reservation = __addDisposableResource(env_1, await this.ctx.sessionPersistence.prepareDeletion(targets).catch((error) => {
405
+ if (error instanceof SessionAlreadyOwnedError)
406
+ throw new WorkspaceSessionDeletionError(sessionId, 'in-use');
407
+ throw error;
408
+ }), true);
409
+ await this.setState({ ...this.requireState(), pendingSessionDeletion: targets });
410
+ await reservation.commit();
411
+ await this.finishSessionDeletion(targets);
412
+ return targets;
413
+ }
414
+ catch (e_1) {
415
+ env_1.error = e_1;
416
+ env_1.hasError = true;
417
+ }
418
+ finally {
419
+ const result_1 = __disposeResources(env_1);
420
+ if (result_1)
421
+ await result_1;
422
+ }
423
+ });
424
+ }
425
+ /**
426
+ * Preview the root and owned descendants without opening their histories.
427
+ * @param sessionId - archived root to preview.
428
+ * @returns identities to show in the deletion confirmation.
429
+ */
430
+ sessionDeletionScope(sessionId) {
431
+ return this.enqueueOperation(async () => {
432
+ if (!this.archivedSessionIds.includes(sessionId))
433
+ throw new WorkspaceSessionDeletionError(sessionId, 'not-archived');
434
+ return this.collectSessionDeletionScope(sessionId);
435
+ });
436
+ }
437
+ async collectSessionDeletionScope(sessionId) {
438
+ const headers = await this.listStoredHeaders();
439
+ const ids = new Set([sessionId]);
440
+ for (let changed = true; changed;) {
441
+ changed = false;
442
+ for (const header of headers) {
443
+ if (header.origin === 'subagent' && header.parentSession !== undefined
444
+ && ids.has(header.parentSession) && !ids.has(header.id)) {
445
+ ids.add(header.id);
446
+ changed = true;
447
+ }
448
+ }
449
+ }
450
+ return [...ids];
451
+ }
452
+ async recoverSessionDeletion() {
453
+ const env_2 = { stack: [], error: void 0, hasError: false };
454
+ try {
455
+ const ids = this.requireState().pendingSessionDeletion;
456
+ if (ids === undefined)
457
+ return;
458
+ const reservation = __addDisposableResource(env_2, await this.ctx.sessionPersistence.prepareDeletion(ids), true);
459
+ await reservation.commit();
460
+ await this.finishSessionDeletion(ids);
461
+ }
462
+ catch (e_2) {
463
+ env_2.error = e_2;
464
+ env_2.hasError = true;
465
+ }
466
+ finally {
467
+ const result_2 = __disposeResources(env_2);
468
+ if (result_2)
469
+ await result_2;
470
+ }
471
+ }
472
+ notifyDeleted(ids) {
473
+ try {
474
+ this.ctx.emit('session/deleted', ids);
475
+ }
476
+ catch (error) {
477
+ this.ctx.logger.warn(`workspace: deletion listener failed: ${String(error)}`);
478
+ }
479
+ }
480
+ async finishSessionDeletion(ids) {
481
+ await this.ctx.parallel('session/deleting', { sessionIds: ids });
482
+ const removed = new Set(ids);
483
+ for (const [id, record] of this.requireTable().entries()) {
484
+ if (record.sessionIds.some(member => removed.has(member))) {
485
+ await this.requireTable().update(id, current => ({
486
+ ...current, sessionIds: current.sessionIds.filter(member => !removed.has(member)), updatedAt: new Date().toISOString(),
487
+ }));
488
+ }
489
+ }
490
+ const state = this.requireState();
491
+ await this.setState({
492
+ ...state,
493
+ archivedSessionIds: state.archivedSessionIds.filter(id => !removed.has(id)),
494
+ pinnedSessionIds: state.pinnedSessionIds.filter(id => !removed.has(id)),
495
+ deletedSessionIds: [...new Set([...(state.deletedSessionIds ?? []), ...ids])],
496
+ pendingSessionDeletion: undefined,
497
+ });
498
+ for (const id of ids) {
499
+ this.headers.delete(id);
500
+ this.sessionPaths.delete(id);
501
+ this.invalidSessionPaths.delete(id);
502
+ }
503
+ this.rebuildEntities();
504
+ this.notifyDeleted(ids);
505
+ }
263
506
  /**
264
507
  * Archive one session durably. The session must exist (live or in session
265
508
  * persistence); its workspace accounting — or lack of one — is irrelevant.
@@ -313,6 +556,8 @@ export class WorkspaceRegistry extends Service {
313
556
  */
314
557
  unarchiveSession(sessionId) {
315
558
  return this.enqueueOperation(async () => {
559
+ if (this.deletedSessionIds.includes(sessionId))
560
+ throw new WorkspaceSessionDeletionError(sessionId, 'deleted');
316
561
  // The chain slot serializes against every other registry write, so this
317
562
  // check-then-write pair cannot interleave with a concurrent archive.
318
563
  const state = this.requireState();
@@ -386,6 +631,8 @@ export class WorkspaceRegistry extends Service {
386
631
  * masquerade as an unknown session.
387
632
  */
388
633
  async sessionKnown(id) {
634
+ if (this.deletedSessionIds.includes(id))
635
+ return false;
389
636
  if (this.ctx.get('sessions')?.get(id) !== undefined)
390
637
  return true;
391
638
  if (this.headers.has(id))
@@ -684,10 +931,17 @@ export class WorkspaceRegistry extends Service {
684
931
  }
685
932
  }
686
933
  rebuildEntities() {
687
- this.entities.clear();
934
+ const ids = new Set(this.requireState().workspaceIds);
935
+ for (const id of this.entities.keys())
936
+ if (!ids.has(id))
937
+ this.entities.delete(id);
688
938
  for (const id of this.requireState().workspaceIds) {
689
939
  const record = this.requireTable().get(id);
690
- this.entities.set(id, new WorkspaceEntity(this.host, id, record));
940
+ const entity = this.entities.get(id);
941
+ if (entity === undefined)
942
+ this.entities.set(id, new WorkspaceEntity(this.host, id, record));
943
+ else
944
+ entity.replace(record);
691
945
  }
692
946
  }
693
947
  async replaceHeaderIndex(headers) {
@@ -723,13 +977,14 @@ export class WorkspaceRegistry extends Service {
723
977
  /** Every stored session's header, projected from the persistence snapshot listing. */
724
978
  async listStoredHeaders() {
725
979
  const snapshots = await this.ctx.sessionPersistence.list();
726
- return snapshots.map(snapshot => snapshot.header);
980
+ const deleted = new Set(this.deletedSessionIds);
981
+ return snapshots.map(snapshot => snapshot.header).filter(header => !deleted.has(header.id));
727
982
  }
728
983
  async indexLiveSessions() {
729
984
  const sessions = this.ctx.get('sessions');
730
985
  if (sessions === undefined)
731
986
  return;
732
- await this.indexHeaders(sessions.list().map(session => session.header));
987
+ await this.indexHeaders(sessions.list().filter(session => !this.deletedSessionIds.includes(session.id)).map(session => session.header));
733
988
  }
734
989
  reportFilteredCandidates() {
735
990
  for (const entity of this.entities.values()) {
@@ -778,15 +1033,51 @@ export class WorkspaceRegistry extends Service {
778
1033
  this.state = state;
779
1034
  }
780
1035
  enqueueOperation(operation) {
1036
+ if (this.stopping)
1037
+ return Promise.reject(new Error('workspace registry is closing'));
781
1038
  const result = this.operationTail.then(async () => {
782
- // A committed delete may leave only its marker cleanup pending. Retry
783
- // recovery before another create/delete can overwrite that pending operation record.
784
- await this.recoverPendingMutation();
785
- return await operation();
1039
+ const domain = this.domain;
1040
+ if (domain === undefined)
1041
+ throw new Error('workspace registry is not started yet');
1042
+ return await domain.exclusive(async () => {
1043
+ const before = JSON.stringify([...this.entities.values()].map(entity => [entity.id, entity.sessionIds]));
1044
+ const previousDeleted = new Set(this.deletedSessionIds);
1045
+ await domain.refresh();
1046
+ const changed = this.snapshotIdentity() !== this.refreshedState;
1047
+ this.state = domain.global.get();
1048
+ const missingHeaders = [...this.requireTable().entries()].some(([, record]) => record.sessionIds.some(id => !this.sessionPaths.has(id)));
1049
+ if (changed || missingHeaders) {
1050
+ await this.replaceHeaderIndex(await this.listStoredHeaders());
1051
+ await this.indexLiveSessions();
1052
+ this.rebuildEntities();
1053
+ }
1054
+ await this.recoverPendingMutation();
1055
+ await this.recoverSessionDeletion();
1056
+ const newlyDeleted = this.deletedSessionIds.filter(id => !previousDeleted.has(id));
1057
+ if (newlyDeleted.length > 0)
1058
+ this.notifyDeleted(newlyDeleted);
1059
+ this.validateStoredState(this.requireState());
1060
+ const after = JSON.stringify([...this.entities.values()].map(entity => [entity.id, entity.sessionIds]));
1061
+ if (changed || before !== after) {
1062
+ try {
1063
+ this.ctx.emit('workspace/refreshed');
1064
+ }
1065
+ catch (error) {
1066
+ this.ctx.logger.warn(`workspace: refresh listener failed: ${String(error)}`);
1067
+ }
1068
+ }
1069
+ this.refreshedState = this.snapshotIdentity();
1070
+ const result = await operation();
1071
+ this.refreshedState = this.snapshotIdentity();
1072
+ return result;
1073
+ });
786
1074
  });
787
1075
  this.operationTail = result.then(() => { }, () => { });
788
1076
  return result;
789
1077
  }
1078
+ snapshotIdentity() {
1079
+ return JSON.stringify([this.domain?.global.get(), [...this.requireTable().entries()]]);
1080
+ }
790
1081
  }
791
1082
  const sameSessionIds = (left, right) => left.length === right.length && left.every((id, index) => id === right[index]);
792
1083
  export default WorkspaceRegistry;
@@ -46,6 +46,8 @@ export declare const workspaceDomainState: z.ZodObject<{
46
46
  operation: z.ZodLiteral<"delete">;
47
47
  workspaceId: z.ZodPipe<z.ZodString, z.ZodTransform<WorkspaceId, string>>;
48
48
  }, z.core.$strip>], "operation">>;
49
+ deletedSessionIds: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<SessionId, string>>>>;
50
+ pendingSessionDeletion: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<SessionId, string>>>>;
49
51
  }, z.core.$strip>;
50
52
  /** Durable registry state inferred from {@link workspaceDomainState}. */
51
53
  export type WorkspaceDomainState = z.infer<typeof workspaceDomainState>;
@@ -72,6 +74,8 @@ export declare const workspaceDomainSpec: {
72
74
  operation: z.ZodLiteral<"delete">;
73
75
  workspaceId: z.ZodPipe<z.ZodString, z.ZodTransform<WorkspaceId, string>>;
74
76
  }, z.core.$strip>], "operation">>;
77
+ deletedSessionIds: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<SessionId, string>>>>;
78
+ pendingSessionDeletion: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<SessionId, string>>>>;
75
79
  }, z.core.$strip>;
76
80
  initial: {
77
81
  initialized: boolean;
@@ -51,6 +51,10 @@ export const workspaceDomainState = z.object({
51
51
  archivedSessionIds: z.array(sessionId).default([]),
52
52
  pinnedSessionIds: z.array(sessionId).default([]),
53
53
  pendingMutation: workspacePendingMutation.optional(),
54
+ /** Payload deletion committed identities; old processes must never restore these Sessions. */
55
+ deletedSessionIds: z.array(sessionId).optional(),
56
+ /** Complete deletion scope retained until payloads and secondary owners finish cleanup. */
57
+ pendingSessionDeletion: z.array(sessionId).optional(),
54
58
  });
55
59
  /**
56
60
  * The workspace domain spec: one `workspaces` table keyed by
@@ -1,2 +0,0 @@
1
- import { n as runDumpConfig } from "./dump-config-CauO75nE.js";
2
- export { runDumpConfig };