@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.
- package/README.i18n.yaml +10 -10
- package/README.md +16 -1
- package/README.zh.md +16 -1
- package/lib/bin.js +62 -11
- package/lib/{command-errors-CBJRI2gy.js → command-errors-CScdshCl.js} +12 -12
- package/lib/{command-trees-Dvq4C7a4.js → command-trees-Dc17MYfV.js} +2 -2
- package/lib/{component-identity-DPdJglJO.js → component-identity-DFJD_d-P.js} +3 -3
- package/lib/{dump-config-CauO75nE.js → dump-config-BcH-VYuv.js} +5 -5
- package/lib/dump-config-CyopmD85.js +2 -0
- package/lib/{dump-config-schema-CObLWWaW.js → dump-config-schema-DM0fb6Ns.js} +2 -2
- package/lib/{extension-events-Be9LWvHD.js → extension-events-qXmhzmHo.js} +20 -20
- package/lib/{frames-7PAg0Q9b.js → frames-B89znn_0.js} +4 -4
- package/lib/headless-compat.js +2 -2
- package/lib/{host-access-DeCjoRQP.js → host-access-B0CRAwsX.js} +1 -1
- package/lib/{keymap-CRUxM_qn.js → keymap-CIoVICBI.js} +17 -16
- package/lib/{plugin-CDFSDE_y.js → plugin-BKQsL2xn.js} +3264 -2301
- package/lib/{plugin-Cn-hyYY8.js → plugin-eJjD6r12.js} +1 -1
- package/lib/{profile-boot-SJGbpLgN.js → profile-boot-BNQry1NM.js} +97 -14
- package/lib/profile-boot.js +2 -2
- package/lib/{scenes-D6jV1EEi.js → scenes-BRf-zMpF.js} +3 -3
- package/lib/{settings-sections-DJQRNBo9.js → settings-sections-4gMhveN_.js} +7 -3
- package/lib/statusBarSettings-CnmdSHkO.js +382 -0
- package/lib/{themes-BCly4_y9.js → themes-Ce97Zsri.js} +13 -13
- package/lib/tui-compat-command-trees.js +1 -1
- package/lib/tui-compat-extensions.js +3 -3
- package/lib/tui-compat-plugin-host.js +5 -5
- package/lib/tui-compat-scenes.js +1 -1
- package/lib/tui-compat-settings-sections.js +1 -1
- package/lib/tui-compat-working-activity.js +4 -4
- package/lib/tui-compat-workspaces.js +1 -1
- package/lib/tui-compat.js +9 -26
- package/lib/types/args.d.ts +2 -0
- package/lib/types/permission-bypass.d.ts +16 -0
- package/lib/types/profile-boot.d.ts +12 -0
- package/lib/types/tui-compat.d.ts +4 -0
- package/lib/types/web-browser.d.ts +6 -0
- package/lib/types/web-instance.d.ts +42 -0
- package/lib/web-browser-Vcgfdsv_.js +46 -0
- package/lib/web-instance-B0jec7cq.js +2 -0
- package/lib/web-instance-DbP7IHPv.js +280 -0
- package/lib/{workspaces-Bb3kCAFb.js → workspaces-1xrm-e3V.js} +2 -2
- package/package.json +36 -33
- package/runtime/manifest.json +4 -2
- package/runtime/node_modules/@deepseek-ai/dsh-agent-default-model/lib/index.js +137 -11
- package/runtime/node_modules/@deepseek-ai/dsh-agent-default-model/lib/types/index.d.ts +27 -1
- package/runtime/node_modules/@deepseek-ai/dsh-agent-preset/skills/cordis-composition-reference/references/packages.md +2 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-gateway/lib/client.js +2 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-gateway/lib/types/client/remote-stream.js +4 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/client.js +152 -39
- package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/index.js +4 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/types/remote-events.d.ts +3 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-remotes/lib/types/remote-events.js +1 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/index.js +179 -35
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.host.js +57 -30
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/typert.remote-client.js +31 -19
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.d.ts +9 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/agent.js +36 -6
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/archived-session-gate.js +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/catalog.js +12 -2
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/client/sessions/service.d.ts +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.d.ts +2 -2
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/commands.js +24 -8
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.d.ts +4 -3
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/index.js +31 -14
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/list.d.ts +6 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/list.js +89 -4
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/remote-events.d.ts +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-session-controller/lib/types/types.d.ts +27 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/index.js +28 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/typert.host.js +39 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/typert.remote-client.d.ts +2 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/typert.remote-client.js +32 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/types/index.d.ts +8 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-settings-controller/lib/types/index.js +19 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/client.js +30 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/index.js +111 -2
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/typert.host.js +104 -11
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/typert.remote-client.d.ts +5 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/typert.remote-client.js +78 -11
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/model.d.ts +14 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/model.js +17 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/service.d.ts +15 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/client/service.js +12 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/commands.d.ts +13 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/commands.js +44 -2
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/feed.js +17 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/index.d.ts +13 -1
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/index.js +22 -0
- package/runtime/node_modules/@deepseek-ai/dsh-api-workspace-controller/lib/types/types.d.ts +17 -0
- package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js +67 -19
- package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/types/index.d.ts +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/types/profile-context.d.ts +11 -1
- package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/worker/profile-resolution-bootstrap.js +22 -3
- package/runtime/node_modules/@deepseek-ai/dsh-base/cordis.patch.yml +9 -3
- package/runtime/node_modules/@deepseek-ai/dsh-base/package.json +2 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/client.js +931 -7
- package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/index.js +57 -19
- package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/client/index.d.ts +5 -2
- package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/config.d.ts +12 -0
- package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/events.d.ts +4 -4
- package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/lib/types/index.d.ts +3 -8
- package/runtime/node_modules/@deepseek-ai/dsh-client-hmr/package.json +6 -2
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-chat/lib/client.js +3 -2
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-chat/lib/types/index.d.ts +2 -2
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-commands/lib/client.js +10 -0
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-deliverables/lib/types/client/present-open.d.ts +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-goal/lib/client.js +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/client.js +68 -16
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/types/client/directory.d.ts +3 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-model-selection/lib/types/client/locales.d.ts +6 -0
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-primitives/lib/markdown/CodeBlock.module.css +3 -5
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-primitives/lib/markdown/MarkdownText.module.css +23 -27
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings/lib/types/client/contract/slots.d.ts +3 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-account/lib/client.js +2 -2
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-account/lib/types/index.d.ts +2 -2
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/client.js +8 -7
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/types/client/SettingsDocumentAction.d.ts +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/types/client/settings-document-store.d.ts +2 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-models/lib/client.js +33 -12
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-models/lib/types/client/locales.d.ts +2 -0
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-plugin-inventory/lib/client.js +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar/lib/client.js +3 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-theme/lib/client.js +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/client.js +1925 -207
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/ArchivedSessions.d.ts +13 -0
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/contract/slots.d.ts +4 -0
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/locales.d.ts +42 -0
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/recent.d.ts +11 -0
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/rows/RecentList.d.ts +15 -0
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/rows/Rows.d.ts +6 -1
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/session-actions/DeleteSession.d.ts +24 -0
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/stores.d.ts +2 -2
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/tree.d.ts +15 -13
- package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/package.json +3 -1
- package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/index.js +16 -0
- package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/typert.host.js +7 -3
- package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/typert.remote-client.js +6 -2
- package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/types/index.js +20 -0
- package/runtime/node_modules/@deepseek-ai/dsh-commands/lib/types/types.d.ts +5 -0
- package/runtime/node_modules/@deepseek-ai/dsh-computer-use/lib/index.js +35 -0
- package/runtime/node_modules/@deepseek-ai/dsh-computer-use/lib/types/brand.d.ts +11 -0
- package/runtime/node_modules/@deepseek-ai/dsh-computer-use/lib/types/brand.js +10 -0
- package/runtime/node_modules/@deepseek-ai/dsh-computer-use/lib/types/index.d.ts +28 -0
- package/runtime/node_modules/@deepseek-ai/dsh-computer-use/lib/types/index.js +36 -0
- package/runtime/node_modules/@deepseek-ai/dsh-computer-use/package.json +42 -0
- package/runtime/node_modules/@deepseek-ai/dsh-config-editor/lib/index.js +102 -14
- package/runtime/node_modules/@deepseek-ai/dsh-config-editor/lib/types/index.d.ts +34 -4
- package/runtime/node_modules/@deepseek-ai/dsh-config-editor/package.json +1 -0
- package/runtime/node_modules/@deepseek-ai/dsh-cordis-client-runner/lib/client.js +5 -2
- package/runtime/node_modules/@deepseek-ai/dsh-host-webserver/lib/index.js +2 -1
- package/runtime/node_modules/@deepseek-ai/dsh-native-command/lib/index.js +21 -8
- package/runtime/node_modules/@deepseek-ai/dsh-native-command/lib/types/path-opener.d.ts +4 -6
- package/runtime/node_modules/@deepseek-ai/dsh-native-command/lib/types/path-opener.js +18 -7
- package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/index.js +4 -0
- package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/typert.host.js +5 -5
- package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/typert.remote-client.js +5 -5
- package/runtime/node_modules/@deepseek-ai/dsh-schedule/lib/types/index.js +5 -0
- package/runtime/node_modules/@deepseek-ai/dsh-session/lib/types/index.d.ts +21 -0
- package/runtime/node_modules/@deepseek-ai/dsh-session-persistence/lib/index.js +12 -0
- package/runtime/node_modules/@deepseek-ai/dsh-session-persistence/lib/types/index.d.ts +15 -0
- package/runtime/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/index.js +95 -2
- package/runtime/node_modules/@deepseek-ai/dsh-session-persistence-jsonl/lib/types/index.d.ts +3 -1
- package/runtime/node_modules/@deepseek-ai/dsh-session-projection-cache/lib/index.js +25 -1
- package/runtime/node_modules/@deepseek-ai/dsh-session-projection-cache/lib/types/index.d.ts +1 -0
- package/runtime/node_modules/@deepseek-ai/dsh-session-projection-cache/package.json +2 -1
- package/runtime/node_modules/@deepseek-ai/dsh-session-query/lib/index.js +13 -0
- package/runtime/node_modules/@deepseek-ai/dsh-session-query/lib/types/observation.d.ts +5 -0
- package/runtime/node_modules/@deepseek-ai/dsh-session-query-sqlite/lib/index.js +26 -0
- package/runtime/node_modules/@deepseek-ai/dsh-session-query-sqlite/package.json +2 -1
- package/runtime/node_modules/@deepseek-ai/dsh-settings/lib/index.js +5 -4
- package/runtime/node_modules/@deepseek-ai/dsh-settings/lib/types/index.d.ts +4 -3
- package/runtime/node_modules/@deepseek-ai/dsh-settings/lib/types/index.js +4 -3
- package/runtime/node_modules/@deepseek-ai/dsh-storage/lib/types/backend.d.ts +4 -0
- package/runtime/node_modules/@deepseek-ai/dsh-storage-domain/lib/index.js +65 -1
- package/runtime/node_modules/@deepseek-ai/dsh-storage-domain/lib/types/domain.d.ts +17 -2
- package/runtime/node_modules/@deepseek-ai/dsh-storage-json/lib/index.js +25 -0
- package/runtime/node_modules/@deepseek-ai/dsh-storage-json/package.json +1 -0
- package/runtime/node_modules/@deepseek-ai/dsh-subagent/lib/types/control.d.ts +1 -1
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/index.js +5522 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/command-args.d.ts +17 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/commands/tianti/cicd.d.ts +8 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/commands/tianti/tianti.d.ts +7 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/commands/tianti-deliver/tianti-deliver.d.ts +8 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/config.d.ts +27 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/index.d.ts +13 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/memory-config.d.ts +10 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/runtime.d.ts +105 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/aliases.d.ts +11 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/auth.d.ts +20 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/client.d.ts +206 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/config.d.ts +22 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/index.d.ts +6 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/log.d.ts +16 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/tianti/types.d.ts +136 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/codebase.d.ts +19 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/dynamicWorkflow.d.ts +10 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/engine.d.ts +8 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/executor.d.ts +11 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/executors.d.ts +15 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/index.d.ts +23 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/memorySuggestions.d.ts +12 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/openspec.d.ts +31 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/recommend.d.ts +8 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/render.d.ts +8 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/requirementContext.d.ts +12 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/scenarioUpgrade.d.ts +24 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/state.d.ts +16 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/store.d.ts +33 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/templates.d.ts +8 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/types.d.ts +385 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/wanmaDevelopmentWorkflow/writeReviewSync.d.ts +6 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/writeReview/index.d.ts +29 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/writeReview/store.d.ts +20 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/services/writeReview/types.d.ts +49 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/lib/types/tools.d.ts +12 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tianti/package.json +57 -0
- package/runtime/node_modules/@deepseek-ai/dsh-tool-cordis/lib/types/api-catalog.js +157 -22
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-D5kpKf--.css +1 -0
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-Dz_cDcce.js +133 -0
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-Dz_cDcce.js.map +1 -0
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/chatcode-apple-touch-icon.png +0 -0
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/chatcode-icon-32.png +0 -0
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/chatcode-mask-icon.svg +1 -0
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/favicon-dark.svg +1 -3
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/favicon.ico +0 -0
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/favicon.svg +1 -3
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/index.html +8 -4
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/preview.html +8 -4
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/package.json +2 -1
- package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/index.js +325 -37
- package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/invariant.js +6 -1
- package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/entity.d.ts +6 -0
- package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/entity.js +23 -17
- package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.d.ts +41 -0
- package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.js +314 -23
- package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/spec.d.ts +4 -0
- package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/spec.js +4 -0
- package/lib/dump-config-CijLv_kn.js +0 -2
- package/lib/tuiDisplayPrefs-Dm_fULiR.js +0 -204
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-DUvMhLle.css +0 -1
- package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/index-Q6zc2uHV.js +0 -127
- 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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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.
|
|
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
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
await this.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
return await
|
|
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
|