botmux 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +56 -396
- package/README.md +55 -396
- package/dist/.runtime-build-id +1 -0
- package/dist/adapters/backend/sandbox.d.ts +99 -279
- package/dist/adapters/backend/sandbox.d.ts.map +1 -1
- package/dist/adapters/backend/sandbox.js +424 -826
- package/dist/adapters/backend/sandbox.js.map +1 -1
- package/dist/adapters/cli/claude-code.d.ts +6 -0
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +197 -11
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/adapters/cli/coco.js +4 -4
- package/dist/adapters/cli/coco.js.map +1 -1
- package/dist/adapters/cli/codex-app.d.ts.map +1 -1
- package/dist/adapters/cli/codex-app.js +9 -6
- package/dist/adapters/cli/codex-app.js.map +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +9 -5
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/fs-policy.d.ts +244 -0
- package/dist/adapters/cli/fs-policy.d.ts.map +1 -0
- package/dist/adapters/cli/fs-policy.js +537 -0
- package/dist/adapters/cli/fs-policy.js.map +1 -0
- package/dist/adapters/cli/grok.d.ts +2 -1
- package/dist/adapters/cli/grok.d.ts.map +1 -1
- package/dist/adapters/cli/grok.js +2 -1
- package/dist/adapters/cli/grok.js.map +1 -1
- package/dist/adapters/cli/hermes.d.ts.map +1 -1
- package/dist/adapters/cli/hermes.js +8 -4
- package/dist/adapters/cli/hermes.js.map +1 -1
- package/dist/adapters/cli/mtr.d.ts.map +1 -1
- package/dist/adapters/cli/mtr.js +3 -2
- package/dist/adapters/cli/mtr.js.map +1 -1
- package/dist/adapters/cli/opencode.d.ts.map +1 -1
- package/dist/adapters/cli/opencode.js +5 -4
- package/dist/adapters/cli/opencode.js.map +1 -1
- package/dist/adapters/cli/read-isolation.d.ts +14 -200
- package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
- package/dist/adapters/cli/read-isolation.js +18 -477
- package/dist/adapters/cli/read-isolation.js.map +1 -1
- package/dist/adapters/cli/relay.js +2 -2
- package/dist/adapters/cli/relay.js.map +1 -1
- package/dist/adapters/cli/runner-input.d.ts +2 -2
- package/dist/adapters/cli/runner-input.d.ts.map +1 -1
- package/dist/adapters/cli/runner-input.js +9 -6
- package/dist/adapters/cli/runner-input.js.map +1 -1
- package/dist/adapters/cli/seed.d.ts.map +1 -1
- package/dist/adapters/cli/seed.js +2 -1
- package/dist/adapters/cli/seed.js.map +1 -1
- package/dist/adapters/cli/traex.d.ts.map +1 -1
- package/dist/adapters/cli/traex.js +3 -2
- package/dist/adapters/cli/traex.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +25 -18
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/bot-registry.d.ts +54 -23
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +91 -0
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +297 -104
- package/dist/cli.js.map +1 -1
- package/dist/codex-app-runner.js +85 -192
- package/dist/codex-app-runner.js.map +1 -1
- package/dist/config.d.ts +0 -16
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -30
- package/dist/config.js.map +1 -1
- package/dist/core/ask-broker.d.ts +12 -0
- package/dist/core/ask-broker.d.ts.map +1 -1
- package/dist/core/ask-broker.js +41 -0
- package/dist/core/ask-broker.js.map +1 -1
- package/dist/core/bot-turn-mutation-gate.d.ts +24 -0
- package/dist/core/bot-turn-mutation-gate.d.ts.map +1 -0
- package/dist/core/bot-turn-mutation-gate.js +369 -0
- package/dist/core/bot-turn-mutation-gate.js.map +1 -0
- package/dist/core/command-handler.d.ts +5 -0
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +53 -73
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +356 -84
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dashboard-rows.d.ts +8 -0
- package/dist/core/dashboard-rows.d.ts.map +1 -1
- package/dist/core/dashboard-rows.js.map +1 -1
- package/dist/core/host-overload-alert.d.ts +157 -0
- package/dist/core/host-overload-alert.d.ts.map +1 -0
- package/dist/core/host-overload-alert.js +251 -0
- package/dist/core/host-overload-alert.js.map +1 -0
- package/dist/core/passthrough-commands.d.ts +8 -0
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +20 -1
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/core/plugins/mcp/gateway-installer.d.ts.map +1 -1
- package/dist/core/plugins/mcp/gateway-installer.js +14 -2
- package/dist/core/plugins/mcp/gateway-installer.js.map +1 -1
- package/dist/core/restart-coordinator.d.ts +28 -0
- package/dist/core/restart-coordinator.d.ts.map +1 -0
- package/dist/core/restart-coordinator.js +82 -0
- package/dist/core/restart-coordinator.js.map +1 -0
- package/dist/core/restart-followup-policy.d.ts +112 -0
- package/dist/core/restart-followup-policy.d.ts.map +1 -0
- package/dist/core/restart-followup-policy.js +49 -0
- package/dist/core/restart-followup-policy.js.map +1 -0
- package/dist/core/role-library.d.ts +1 -1
- package/dist/core/role-library.js +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js +8 -0
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/session-discovery.d.ts +14 -0
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +25 -0
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-liveness.d.ts +15 -0
- package/dist/core/session-liveness.d.ts.map +1 -0
- package/dist/core/session-liveness.js +76 -0
- package/dist/core/session-liveness.js.map +1 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +90 -60
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-row-enrichment.d.ts +15 -0
- package/dist/core/session-row-enrichment.d.ts.map +1 -0
- package/dist/core/session-row-enrichment.js +93 -0
- package/dist/core/session-row-enrichment.js.map +1 -0
- package/dist/core/slash-inject.js +1 -1
- package/dist/core/slash-inject.js.map +1 -1
- package/dist/core/trigger-final-suppression.d.ts +24 -0
- package/dist/core/trigger-final-suppression.d.ts.map +1 -0
- package/dist/core/trigger-final-suppression.js +97 -0
- package/dist/core/trigger-final-suppression.js.map +1 -0
- package/dist/core/trigger-session.d.ts.map +1 -1
- package/dist/core/trigger-session.js +64 -4
- package/dist/core/trigger-session.js.map +1 -1
- package/dist/core/types.d.ts +6 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +44 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +333 -38
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts +5 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +526 -35
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/aggregator.d.ts +1 -0
- package/dist/dashboard/aggregator.d.ts.map +1 -1
- package/dist/dashboard/aggregator.js +34 -6
- package/dist/dashboard/aggregator.js.map +1 -1
- package/dist/dashboard/bot-payload.d.ts +8 -0
- package/dist/dashboard/bot-payload.d.ts.map +1 -1
- package/dist/dashboard/bot-payload.js +10 -0
- package/dist/dashboard/bot-payload.js.map +1 -1
- package/dist/dashboard/compat.d.ts +102 -2
- package/dist/dashboard/compat.d.ts.map +1 -1
- package/dist/dashboard/compat.js +78 -14
- package/dist/dashboard/compat.js.map +1 -1
- package/dist/dashboard/connector-api.d.ts.map +1 -1
- package/dist/dashboard/connector-api.js +1 -0
- package/dist/dashboard/connector-api.js.map +1 -1
- package/dist/dashboard/desktop-asks.d.ts +21 -0
- package/dist/dashboard/desktop-asks.d.ts.map +1 -0
- package/dist/dashboard/desktop-asks.js +49 -0
- package/dist/dashboard/desktop-asks.js.map +1 -0
- package/dist/dashboard/public-redact.d.ts +7 -0
- package/dist/dashboard/public-redact.d.ts.map +1 -1
- package/dist/dashboard/public-redact.js +35 -3
- package/dist/dashboard/public-redact.js.map +1 -1
- package/dist/dashboard/session-presentation.d.ts +16 -0
- package/dist/dashboard/session-presentation.d.ts.map +1 -0
- package/dist/dashboard/session-presentation.js +62 -0
- package/dist/dashboard/session-presentation.js.map +1 -0
- package/dist/dashboard/settings-write-applier.d.ts +2 -1
- package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
- package/dist/dashboard/settings-write-applier.js +19 -1
- package/dist/dashboard/settings-write-applier.js.map +1 -1
- package/dist/dashboard/trigger-api.d.ts.map +1 -1
- package/dist/dashboard/trigger-api.js +19 -1
- package/dist/dashboard/trigger-api.js.map +1 -1
- package/dist/dashboard/vc-consumer-profiles-api.d.ts +7 -2
- package/dist/dashboard/vc-consumer-profiles-api.d.ts.map +1 -1
- package/dist/dashboard/vc-consumer-profiles-api.js +13 -0
- package/dist/dashboard/vc-consumer-profiles-api.js.map +1 -1
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +18 -5
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.d.ts +16 -0
- package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.js +288 -7
- package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
- package/dist/dashboard/web/bot-defaults.d.ts +10 -0
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults.js.map +1 -1
- package/dist/dashboard/web/client-shell.d.ts +29 -0
- package/dist/dashboard/web/client-shell.d.ts.map +1 -0
- package/dist/dashboard/web/client-shell.js +89 -0
- package/dist/dashboard/web/client-shell.js.map +1 -0
- package/dist/dashboard/web/connectors-page.d.ts.map +1 -1
- package/dist/dashboard/web/connectors-page.js +5 -1
- package/dist/dashboard/web/connectors-page.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +130 -22
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/preferences.d.ts +7 -0
- package/dist/dashboard/web/preferences.d.ts.map +1 -1
- package/dist/dashboard/web/preferences.js +32 -0
- package/dist/dashboard/web/preferences.js.map +1 -1
- package/dist/dashboard/web/sessions-kanban.d.ts +1 -1
- package/dist/dashboard/web/sessions-kanban.d.ts.map +1 -1
- package/dist/dashboard/web/sessions-kanban.js +1 -1
- package/dist/dashboard/web/sessions-kanban.js.map +1 -1
- package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
- package/dist/dashboard/web/sessions-page.js +78 -67
- package/dist/dashboard/web/sessions-page.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts +4 -0
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +14 -1
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard/web/settings-page.d.ts +6 -0
- package/dist/dashboard/web/settings-page.d.ts.map +1 -1
- package/dist/dashboard/web/settings-page.js +55 -30
- package/dist/dashboard/web/settings-page.js.map +1 -1
- package/dist/dashboard/web/store.d.ts +1 -2
- package/dist/dashboard/web/store.d.ts.map +1 -1
- package/dist/dashboard/web/store.js +69 -20
- package/dist/dashboard/web/store.js.map +1 -1
- package/dist/dashboard/web/vc-consumer-profiles-section.d.ts.map +1 -1
- package/dist/dashboard/web/vc-consumer-profiles-section.js +128 -42
- package/dist/dashboard/web/vc-consumer-profiles-section.js.map +1 -1
- package/dist/dashboard/webhook-routes.d.ts.map +1 -1
- package/dist/dashboard/webhook-routes.js +9 -2
- package/dist/dashboard/webhook-routes.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-VQMPUJ4Y.js +10 -0
- package/dist/dashboard-web/chunks/chunk-AGCPF6MT.js +1 -0
- package/dist/dashboard-web/chunks/{chunk-QCPPKCX3.js → chunk-JMRGZQDB.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-EJDYUINZ.js → chunk-NP4JUBGS.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-WXPMNEYV.js → chunk-P327LXOT.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-SNKATZWK.js +49 -0
- package/dist/dashboard-web/chunks/connectors-page-DOY4J3ZL.js +1 -0
- package/dist/dashboard-web/chunks/{groups-page-3P4TLUMF.js → groups-page-74TS2DIH.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-TDCZV56A.js → insights-page-AYCO65JC.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-QWCWL3SX.js → monitor-room-YKYLTSAN.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-IOWFSNVC.js → monitoring-page-QBIUNRBR.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-5AUPEHZP.js → office-page-4PH2A26P.js} +1 -1
- package/dist/dashboard-web/chunks/overview-page-H73D5UT4.js +1 -0
- package/dist/dashboard-web/chunks/{roles-page-WJVB52ET.js → roles-page-U4BTOQ7F.js} +1 -1
- package/dist/dashboard-web/chunks/{schedules-page-RVRWHP4V.js → schedules-page-RHRHX7R7.js} +1 -1
- package/dist/dashboard-web/chunks/sessions-page-VSC6AM5G.js +2 -0
- package/dist/dashboard-web/chunks/settings-page-LF3RKM5P.js +2 -0
- package/dist/dashboard-web/chunks/{skills-page-7YT5TIX5.js → skills-page-SYOIGGXH.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-NJZKTU7A.js → team-federation-page-RMBLASTW.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-NQ73UA2Q.js → v3-page-XJXKKJRN.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-DSM3MDMN.js → whiteboards-page-K3YVSTHJ.js} +1 -1
- package/dist/dashboard-web/style.css +571 -3
- package/dist/dashboard.js +238 -9
- package/dist/dashboard.js.map +1 -1
- package/dist/global-config.d.ts +11 -0
- package/dist/global-config.d.ts.map +1 -1
- package/dist/global-config.js +27 -1
- package/dist/global-config.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +6 -19
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +6 -19
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts +1 -14
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +1 -35
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts +10 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +161 -44
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +47 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +127 -18
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +13 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +48 -3
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/identity-cache.d.ts +25 -1
- package/dist/im/lark/identity-cache.d.ts.map +1 -1
- package/dist/im/lark/identity-cache.js +47 -1
- package/dist/im/lark/identity-cache.js.map +1 -1
- package/dist/im/lark/overload-nonce.d.ts +19 -0
- package/dist/im/lark/overload-nonce.d.ts.map +1 -0
- package/dist/im/lark/overload-nonce.js +72 -0
- package/dist/im/lark/overload-nonce.js.map +1 -0
- package/dist/im/lark/v3-progress-card.d.ts.map +1 -1
- package/dist/im/lark/v3-progress-card.js +5 -0
- package/dist/im/lark/v3-progress-card.js.map +1 -1
- package/dist/services/async-trigger-state.d.ts +82 -0
- package/dist/services/async-trigger-state.d.ts.map +1 -0
- package/dist/services/async-trigger-state.js +95 -0
- package/dist/services/async-trigger-state.js.map +1 -0
- package/dist/services/async-trigger-store.d.ts +28 -0
- package/dist/services/async-trigger-store.d.ts.map +1 -0
- package/dist/services/async-trigger-store.js +120 -0
- package/dist/services/async-trigger-store.js.map +1 -0
- package/dist/services/bot-config-store.d.ts.map +1 -1
- package/dist/services/bot-config-store.js +34 -2
- package/dist/services/bot-config-store.js.map +1 -1
- package/dist/services/bridge-fallback-gate.d.ts +32 -0
- package/dist/services/bridge-fallback-gate.d.ts.map +1 -1
- package/dist/services/bridge-fallback-gate.js +39 -0
- package/dist/services/bridge-fallback-gate.js.map +1 -1
- package/dist/services/bridge-turn-queue.d.ts.map +1 -1
- package/dist/services/bridge-turn-queue.js +15 -1
- package/dist/services/bridge-turn-queue.js.map +1 -1
- package/dist/services/card-prefs-store.d.ts +4 -0
- package/dist/services/card-prefs-store.d.ts.map +1 -1
- package/dist/services/card-prefs-store.js +8 -0
- package/dist/services/card-prefs-store.js.map +1 -1
- package/dist/services/claude-transcript.d.ts +23 -0
- package/dist/services/claude-transcript.d.ts.map +1 -1
- package/dist/services/claude-transcript.js +33 -0
- package/dist/services/claude-transcript.js.map +1 -1
- package/dist/services/codex-app-runner-protocol.d.ts +61 -0
- package/dist/services/codex-app-runner-protocol.d.ts.map +1 -0
- package/dist/services/codex-app-runner-protocol.js +170 -0
- package/dist/services/codex-app-runner-protocol.js.map +1 -0
- package/dist/services/codex-app-turn-controller.d.ts +72 -0
- package/dist/services/codex-app-turn-controller.d.ts.map +1 -0
- package/dist/services/codex-app-turn-controller.js +524 -0
- package/dist/services/codex-app-turn-controller.js.map +1 -0
- package/dist/services/codex-runner-freshness.d.ts +39 -0
- package/dist/services/codex-runner-freshness.d.ts.map +1 -0
- package/dist/services/codex-runner-freshness.js +78 -0
- package/dist/services/codex-runner-freshness.js.map +1 -0
- package/dist/services/connector-store.d.ts +6 -0
- package/dist/services/connector-store.d.ts.map +1 -1
- package/dist/services/connector-store.js.map +1 -1
- package/dist/services/grant-store.d.ts.map +1 -1
- package/dist/services/grant-store.js +16 -0
- package/dist/services/grant-store.js.map +1 -1
- package/dist/services/hermes-transcript.d.ts +1 -0
- package/dist/services/hermes-transcript.d.ts.map +1 -1
- package/dist/services/hermes-transcript.js +49 -0
- package/dist/services/hermes-transcript.js.map +1 -1
- package/dist/services/sandbox-migration.d.ts +14 -0
- package/dist/services/sandbox-migration.d.ts.map +1 -0
- package/dist/services/sandbox-migration.js +85 -0
- package/dist/services/sandbox-migration.js.map +1 -0
- package/dist/services/sandbox-store.d.ts +28 -0
- package/dist/services/sandbox-store.d.ts.map +1 -1
- package/dist/services/sandbox-store.js +82 -0
- package/dist/services/sandbox-store.js.map +1 -1
- package/dist/services/schedule-split-migration.d.ts +2 -0
- package/dist/services/schedule-split-migration.d.ts.map +1 -0
- package/dist/services/schedule-split-migration.js +159 -0
- package/dist/services/schedule-split-migration.js.map +1 -0
- package/dist/services/schedule-store.d.ts +28 -4
- package/dist/services/schedule-store.d.ts.map +1 -1
- package/dist/services/schedule-store.js +118 -33
- package/dist/services/schedule-store.js.map +1 -1
- package/dist/services/trigger-types.d.ts +18 -1
- package/dist/services/trigger-types.d.ts.map +1 -1
- package/dist/services/trigger-types.js +3 -0
- package/dist/services/trigger-types.js.map +1 -1
- package/dist/services/vc-meeting-consumer-profile-store.d.ts.map +1 -1
- package/dist/services/vc-meeting-consumer-profile-store.js +1 -0
- package/dist/services/vc-meeting-consumer-profile-store.js.map +1 -1
- package/dist/services/vc-meeting-consumer-profile-templates.d.ts +32 -0
- package/dist/services/vc-meeting-consumer-profile-templates.d.ts.map +1 -0
- package/dist/services/vc-meeting-consumer-profile-templates.js +106 -0
- package/dist/services/vc-meeting-consumer-profile-templates.js.map +1 -0
- package/dist/services/vc-meeting-delivery-feed.d.ts +1 -1
- package/dist/services/vc-meeting-delivery-feed.d.ts.map +1 -1
- package/dist/services/vc-meeting-delivery-feed.js +2 -1
- package/dist/services/vc-meeting-delivery-feed.js.map +1 -1
- package/dist/services/vc-meeting-delivery-hub-store.d.ts +3 -1
- package/dist/services/vc-meeting-delivery-hub-store.d.ts.map +1 -1
- package/dist/services/vc-meeting-delivery-hub-store.js +11 -0
- package/dist/services/vc-meeting-delivery-hub-store.js.map +1 -1
- package/dist/services/vc-meeting-delivery-protocol.d.ts +9 -2
- package/dist/services/vc-meeting-delivery-protocol.d.ts.map +1 -1
- package/dist/services/vc-meeting-delivery-protocol.js +10 -1
- package/dist/services/vc-meeting-delivery-protocol.js.map +1 -1
- package/dist/services/vc-meeting-delivery-receiver.d.ts.map +1 -1
- package/dist/services/vc-meeting-delivery-receiver.js +10 -1
- package/dist/services/vc-meeting-delivery-receiver.js.map +1 -1
- package/dist/services/vc-meeting-delivery-store.d.ts +12 -2
- package/dist/services/vc-meeting-delivery-store.d.ts.map +1 -1
- package/dist/services/vc-meeting-delivery-store.js +14 -2
- package/dist/services/vc-meeting-delivery-store.js.map +1 -1
- package/dist/services/vc-meeting-im-reply.d.ts +2 -1
- package/dist/services/vc-meeting-im-reply.d.ts.map +1 -1
- package/dist/services/vc-meeting-im-reply.js +19 -3
- package/dist/services/vc-meeting-im-reply.js.map +1 -1
- package/dist/services/vc-meeting-listener-output-protocol.d.ts +27 -0
- package/dist/services/vc-meeting-listener-output-protocol.d.ts.map +1 -0
- package/dist/services/vc-meeting-listener-output-protocol.js +58 -0
- package/dist/services/vc-meeting-listener-output-protocol.js.map +1 -0
- package/dist/services/vc-meeting-listener-topic-store.d.ts +31 -0
- package/dist/services/vc-meeting-listener-topic-store.d.ts.map +1 -0
- package/dist/services/vc-meeting-listener-topic-store.js +120 -0
- package/dist/services/vc-meeting-listener-topic-store.js.map +1 -0
- package/dist/services/vc-meeting-runtime-store.d.ts +2 -1
- package/dist/services/vc-meeting-runtime-store.d.ts.map +1 -1
- package/dist/services/vc-meeting-runtime-store.js +8 -0
- package/dist/services/vc-meeting-runtime-store.js.map +1 -1
- package/dist/services/vc-meeting-send-policy.d.ts +8 -1
- package/dist/services/vc-meeting-send-policy.d.ts.map +1 -1
- package/dist/services/vc-meeting-send-policy.js +8 -0
- package/dist/services/vc-meeting-send-policy.js.map +1 -1
- package/dist/types.d.ts +53 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/allowed-users-apply.d.ts +76 -0
- package/dist/utils/allowed-users-apply.d.ts.map +1 -0
- package/dist/utils/allowed-users-apply.js +123 -0
- package/dist/utils/allowed-users-apply.js.map +1 -0
- package/dist/utils/allowed-users-cache.d.ts +29 -0
- package/dist/utils/allowed-users-cache.d.ts.map +1 -0
- package/dist/utils/allowed-users-cache.js +82 -0
- package/dist/utils/allowed-users-cache.js.map +1 -0
- package/dist/utils/child-env.d.ts +4 -3
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +16 -1
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/cli-usage-limit.d.ts +27 -1
- package/dist/utils/cli-usage-limit.d.ts.map +1 -1
- package/dist/utils/cli-usage-limit.js +92 -20
- package/dist/utils/cli-usage-limit.js.map +1 -1
- package/dist/utils/input-gate.d.ts +2 -0
- package/dist/utils/input-gate.d.ts.map +1 -1
- package/dist/utils/input-gate.js +2 -0
- package/dist/utils/input-gate.js.map +1 -1
- package/dist/utils/runtime-build-id.d.ts +21 -0
- package/dist/utils/runtime-build-id.d.ts.map +1 -0
- package/dist/utils/runtime-build-id.js +83 -0
- package/dist/utils/runtime-build-id.js.map +1 -0
- package/dist/utils/terminal-renderer.d.ts +3 -3
- package/dist/utils/terminal-renderer.js +3 -3
- package/dist/vc-agent/cards.d.ts.map +1 -1
- package/dist/vc-agent/cards.js +21 -1
- package/dist/vc-agent/cards.js.map +1 -1
- package/dist/worker.js +1010 -669
- package/dist/worker.js.map +1 -1
- package/dist/workflows/events/payloads.d.ts +56 -0
- package/dist/workflows/events/payloads.d.ts.map +1 -1
- package/dist/workflows/events/payloads.js +9 -0
- package/dist/workflows/events/payloads.js.map +1 -1
- package/dist/workflows/events/schema.d.ts +86 -0
- package/dist/workflows/events/schema.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.js +13 -1
- package/dist/workflows/hostExecutors/botmux-schedule.js.map +1 -1
- package/dist/workflows/migration/v2-run-archive-schema.d.ts +20 -20
- package/dist/workflows/migration/v2-to-v3.d.ts.map +1 -1
- package/dist/workflows/migration/v2-to-v3.js +5 -1
- package/dist/workflows/migration/v2-to-v3.js.map +1 -1
- package/dist/workflows/shared/sandbox-policy.d.ts +10 -1
- package/dist/workflows/shared/sandbox-policy.d.ts.map +1 -1
- package/dist/workflows/shared/sandbox-policy.js +12 -0
- package/dist/workflows/shared/sandbox-policy.js.map +1 -1
- package/dist/workflows/v3/architect.d.ts.map +1 -1
- package/dist/workflows/v3/architect.js +1 -0
- package/dist/workflows/v3/architect.js.map +1 -1
- package/dist/workflows/v3/bot-resolve.d.ts.map +1 -1
- package/dist/workflows/v3/bot-resolve.js +36 -0
- package/dist/workflows/v3/bot-resolve.js.map +1 -1
- package/dist/workflows/v3/cli-run.d.ts +9 -0
- package/dist/workflows/v3/cli-run.d.ts.map +1 -1
- package/dist/workflows/v3/cli-run.js +17 -2
- package/dist/workflows/v3/cli-run.js.map +1 -1
- package/dist/workflows/v3/contract.d.ts +8 -0
- package/dist/workflows/v3/contract.d.ts.map +1 -1
- package/dist/workflows/v3/contract.js.map +1 -1
- package/dist/workflows/v3/goal-cli.d.ts +58 -0
- package/dist/workflows/v3/goal-cli.d.ts.map +1 -0
- package/dist/workflows/v3/goal-cli.js +430 -0
- package/dist/workflows/v3/goal-cli.js.map +1 -0
- package/dist/workflows/v3/library-materialize.d.ts.map +1 -1
- package/dist/workflows/v3/library-materialize.js +5 -1
- package/dist/workflows/v3/library-materialize.js.map +1 -1
- package/dist/workflows/v3/library-schema.d.ts +21 -0
- package/dist/workflows/v3/library-schema.d.ts.map +1 -1
- package/dist/workflows/v3/library-schema.js +95 -1
- package/dist/workflows/v3/library-schema.js.map +1 -1
- package/dist/workflows/v3/progress-projection.d.ts +3 -0
- package/dist/workflows/v3/progress-projection.d.ts.map +1 -1
- package/dist/workflows/v3/progress-projection.js +23 -1
- package/dist/workflows/v3/progress-projection.js.map +1 -1
- package/dist/workflows/v3/run-envelope.d.ts +46 -1
- package/dist/workflows/v3/run-envelope.d.ts.map +1 -1
- package/dist/workflows/v3/run-envelope.js +32 -1
- package/dist/workflows/v3/run-envelope.js.map +1 -1
- package/package.json +2 -2
- package/dist/dashboard-web/chunks/bot-defaults-page-O376WSER.js +0 -5
- package/dist/dashboard-web/chunks/chunk-H7P5UV4W.js +0 -49
- package/dist/dashboard-web/chunks/chunk-SZOB6VK2.js +0 -1
- package/dist/dashboard-web/chunks/connectors-page-IR54AOAI.js +0 -1
- package/dist/dashboard-web/chunks/overview-page-QJMI6NLW.js +0 -1
- package/dist/dashboard-web/chunks/sessions-page-KWLGBX6G.js +0 -3
- package/dist/dashboard-web/chunks/settings-page-TNZEPC7V.js +0 -2
- package/dist/services/sandbox-land.d.ts +0 -45
- package/dist/services/sandbox-land.d.ts.map +0 -1
- package/dist/services/sandbox-land.js +0 -394
- package/dist/services/sandbox-land.js.map +0 -1
- package/dist/utils/screen-analyzer.d.ts +0 -75
- package/dist/utils/screen-analyzer.d.ts.map +0 -1
- package/dist/utils/screen-analyzer.js +0 -333
- package/dist/utils/screen-analyzer.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-ipc-server.d.ts","sourceRoot":"","sources":["../../src/core/dashboard-ipc-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAe,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"dashboard-ipc-server.d.ts","sourceRoot":"","sources":["../../src/core/dashboard-ipc-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,8 @@ import { V3_SESSION_RUN_MUTATION_ROUTE_PREFIX } from '../workflows/v3/session-re
|
|
|
9
9
|
import { listenWithProbe } from '../utils/listen-with-probe.js';
|
|
10
10
|
import { dashboardSecretPath } from './dashboard-secret.js';
|
|
11
11
|
import * as sessionStore from '../services/session-store.js';
|
|
12
|
+
import * as asyncTriggerStore from '../services/async-trigger-store.js';
|
|
13
|
+
import { resolveAsyncTriggerState, decideAsyncOwnership } from '../services/async-trigger-state.js';
|
|
12
14
|
import * as scheduleStore from '../services/schedule-store.js';
|
|
13
15
|
import * as groupsStore from '../services/groups-store.js';
|
|
14
16
|
import { createGroupWithBots, transferGroupOwner } from '../services/group-creator.js';
|
|
@@ -58,7 +60,6 @@ import { findConfigField, applyConfigField, coerceConfigValue } from '../service
|
|
|
58
60
|
import { globalBuiltinSkillInjectionDefault, resolveSkillInjectionSupport } from '../skills/injection-mode.js';
|
|
59
61
|
import { summaryRangeFromBotConfig, updateDashboardSummaryRange } from '../services/summary-range-store.js';
|
|
60
62
|
import { config } from '../config.js';
|
|
61
|
-
import { computeSandboxDiff, applySandboxDiff } from '../services/sandbox-land.js';
|
|
62
63
|
import { buildSafeInsightConversation, buildSafeInsightOverview, buildSafeInsightReport, buildSafeInsightTurnDetail } from '../services/insight/report.js';
|
|
63
64
|
import { readRawConfig, findEntryIndex, requireConfigPath, rmwBotEntry } from '../services/config-store.js';
|
|
64
65
|
import { setDefaultLocale, localeForBot, t } from '../i18n/index.js';
|
|
@@ -69,6 +70,7 @@ import * as chatFirstSeenStore from '../services/chat-first-seen-store.js';
|
|
|
69
70
|
import * as scheduler from './scheduler.js';
|
|
70
71
|
import { listActiveSessions, findActiveBySessionId, closeSession, getActiveSessionsRegistry, transferSession, deliverWriteLinkCardToOwners, forkWorker, suspendWorker, killWorker } from './worker-pool.js';
|
|
71
72
|
import { listOnlineDaemons } from '../utils/daemon-discovery.js';
|
|
73
|
+
import { isSessionStopped } from './session-liveness.js';
|
|
72
74
|
import { getChatMode, replyMessage, sendMessage, resolveUnionIdFromOpenId, listThreadMessages, listChatMessages, listChatBotMembers, getUserProfile, getUserProfileStrict, resolveAllowedUsersWithMap } from '../im/lark/client.js';
|
|
73
75
|
import { parseApiMessage, cardContentHasUpgradeFallback, resolveMergedCardContent } from '../im/lark/message-parser.js';
|
|
74
76
|
import { resumeSession, spawnDashboardSession, activateQueuedSession, closeCliMismatchedSessionsForBot, suspendActiveSessionsForBot } from './session-manager.js';
|
|
@@ -86,6 +88,7 @@ import { validateTriggerRequest } from '../services/trigger-types.js';
|
|
|
86
88
|
import { resolveCliSelection, selectionKeyForBot } from '../setup/cli-selection.js';
|
|
87
89
|
import { checkCliAvailability } from '../setup/cli-availability.js';
|
|
88
90
|
import { enrichHistorySenders } from '../dashboard/history-senders.js';
|
|
91
|
+
import { listPendingAsks, submitAskFromDesktop } from './ask-broker.js';
|
|
89
92
|
let exactChatGrantHandler = applyExactChatGrantRequest;
|
|
90
93
|
/** Test seam: replace the exact-grant service without touching live Feishu/config state. */
|
|
91
94
|
export function setExactChatGrantHandler(handler) {
|
|
@@ -112,6 +115,11 @@ import { sessionAnchorId } from './types.js';
|
|
|
112
115
|
import { attachSkillPolicy, detachSkillPolicy } from './skills/im-command.js';
|
|
113
116
|
import { readSkillRegistry } from '../services/skill-registry-store.js';
|
|
114
117
|
import { commitDeviceIsolationActivation, DEVICE_ISOLATION_COMMIT_PATH, DEVICE_ISOLATION_PREPARE_PATH, DEVICE_ISOLATION_RELEASE_PATH, logDeviceIsolationActivationError, prepareDeviceIsolationActivation, releaseDeviceIsolationActivation, } from './device-isolation-daemon.js';
|
|
118
|
+
// Daemon process start (module load ≈ daemon boot). Used by the SSE snapshot
|
|
119
|
+
// replay to bound the "recently closed" set to sessions that flipped
|
|
120
|
+
// active→closed during THIS run — i.e. restore-time zombies — without replaying
|
|
121
|
+
// the entire closed-session history on every connect.
|
|
122
|
+
const PROCESS_START_MS = Date.now();
|
|
115
123
|
const routes = [];
|
|
116
124
|
/** Requests that crossed the server-wide trusted-host gate. The legacy
|
|
117
125
|
* write-link handlers consult this marker so they do not verify (and consume)
|
|
@@ -327,11 +335,12 @@ function routeHasNarrowUntrustedAuth(method, pathname) {
|
|
|
327
335
|
return true;
|
|
328
336
|
if (method === 'POST' && pathname === '/api/asks')
|
|
329
337
|
return true;
|
|
330
|
-
// botmux slash / botmux
|
|
331
|
-
// 读隔离下读不到 host secret
|
|
338
|
+
// botmux slash / botmux role switch(角色切换)/ botmux delete(关闭自身):合法调用方
|
|
339
|
+
// 是会话内的 CLI 自身,沙箱 / 读隔离下读不到 host secret。handler 内验证
|
|
340
|
+
// 该会话的 rotating per-turn
|
|
332
341
|
// capability 并绑定到 URL 里的 sessionId(同 /api/asks 姿势)——capability 只
|
|
333
342
|
// 证明「我是这个会话当前这一轮的 CLI」,选不了别的会话。
|
|
334
|
-
if (method === 'POST' && /^\/api\/sessions\/[^/]+\/(?:slash|cd)$/.test(pathname))
|
|
343
|
+
if (method === 'POST' && /^\/api\/sessions\/[^/]+\/(?:slash|cd|close)$/.test(pathname))
|
|
335
344
|
return true;
|
|
336
345
|
if (method === 'POST' && pathname === '/api/hooks/emit')
|
|
337
346
|
return true;
|
|
@@ -399,6 +408,47 @@ async function handleDeviceIsolationActivationRoute(req, res, handler) {
|
|
|
399
408
|
ipcRoute('POST', DEVICE_ISOLATION_PREPARE_PATH, (req, res) => handleDeviceIsolationActivationRoute(req, res, prepareDeviceIsolationActivation));
|
|
400
409
|
ipcRoute('POST', DEVICE_ISOLATION_COMMIT_PATH, (req, res) => handleDeviceIsolationActivationRoute(req, res, commitDeviceIsolationActivation));
|
|
401
410
|
ipcRoute('POST', DEVICE_ISOLATION_RELEASE_PATH, (req, res) => handleDeviceIsolationActivationRoute(req, res, releaseDeviceIsolationActivation));
|
|
411
|
+
// ─── Pending asks (trusted Desktop/dashboard operator only) ─────────────────
|
|
412
|
+
ipcRoute('GET', '/api/asks/pending', (req, res) => {
|
|
413
|
+
if (!isTrustedHostIpcRequest(req)) {
|
|
414
|
+
return jsonRes(res, 403, { ok: false, error: 'trusted_host_required' });
|
|
415
|
+
}
|
|
416
|
+
const asks = listPendingAsks().map((ask) => ({
|
|
417
|
+
askId: ask.askId,
|
|
418
|
+
sessionId: ask.sessionId,
|
|
419
|
+
larkAppId: ask.larkAppId,
|
|
420
|
+
chatId: ask.chatId,
|
|
421
|
+
rootMessageId: ask.rootMessageId,
|
|
422
|
+
questions: ask.questions,
|
|
423
|
+
deadlineAt: ask.deadlineAt,
|
|
424
|
+
createdAt: ask.createdAt,
|
|
425
|
+
}));
|
|
426
|
+
return jsonRes(res, 200, { asks });
|
|
427
|
+
});
|
|
428
|
+
ipcRoute('POST', '/api/asks/answer', async (req, res) => {
|
|
429
|
+
if (!isTrustedHostIpcRequest(req)) {
|
|
430
|
+
return jsonRes(res, 403, { ok: false, error: 'trusted_host_required' });
|
|
431
|
+
}
|
|
432
|
+
let body;
|
|
433
|
+
try {
|
|
434
|
+
body = await readJsonBody(req);
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
438
|
+
}
|
|
439
|
+
if (!body.askId || !Array.isArray(body.selections)) {
|
|
440
|
+
return jsonRes(res, 400, { ok: false, error: 'askId_and_selections_required' });
|
|
441
|
+
}
|
|
442
|
+
const outcome = submitAskFromDesktop({
|
|
443
|
+
askId: body.askId,
|
|
444
|
+
selections: body.selections,
|
|
445
|
+
by: typeof body.by === 'string' ? body.by : 'desktop',
|
|
446
|
+
});
|
|
447
|
+
if (outcome !== 'accepted') {
|
|
448
|
+
return jsonRes(res, 409, { ok: false, error: outcome });
|
|
449
|
+
}
|
|
450
|
+
return jsonRes(res, 200, { ok: true, outcome });
|
|
451
|
+
});
|
|
402
452
|
ipcRoute('GET', '/api/sessions', (_req, res) => {
|
|
403
453
|
// Active first (live state), closed appended (historical)
|
|
404
454
|
const active = listActiveSessions().map(composeRowFromActive);
|
|
@@ -417,7 +467,16 @@ ipcRoute('GET', '/api/sessions/:sessionId', (_req, res, params) => {
|
|
|
417
467
|
return jsonRes(res, 200, { session: composeRowFromClosed(closed) });
|
|
418
468
|
jsonRes(res, 404, { error: 'not_found' });
|
|
419
469
|
});
|
|
420
|
-
|
|
470
|
+
/** Canonical daemon-side close used by the dashboard and `botmux delete`.
|
|
471
|
+
* Host callers authenticate with HMAC; a read-isolated CLI may close only its
|
|
472
|
+
* exact live session with the rotating per-turn capability. */
|
|
473
|
+
ipcRoute('POST', '/api/sessions/:sessionId/close', async (req, res, params) => {
|
|
474
|
+
const body = await readJsonBody(req)
|
|
475
|
+
.catch(() => ({}));
|
|
476
|
+
const ds = findActiveBySessionId(params.sessionId);
|
|
477
|
+
const auth = sessionCliIpcAuth(req, ds, params.sessionId, body);
|
|
478
|
+
if (!auth.ok)
|
|
479
|
+
return jsonRes(res, 403, { ok: false, error: auth.error });
|
|
421
480
|
const r = await closeSession(params.sessionId);
|
|
422
481
|
jsonRes(res, 200, r);
|
|
423
482
|
});
|
|
@@ -504,6 +563,92 @@ ipcRoute('POST', '/api/sessions/:sessionId/suspend', (_req, res, params) => {
|
|
|
504
563
|
}
|
|
505
564
|
jsonRes(res, 200, { ok: true, sessionId: params.sessionId, suspended: true });
|
|
506
565
|
});
|
|
566
|
+
/**
|
|
567
|
+
* Count host-overload降压 candidates for THIS daemon's scope, so the alert card
|
|
568
|
+
* can show "僵尸 N / 闲置 M" before the owner clicks. `stopped` counts zombies
|
|
569
|
+
* from the SHARED session store (same answer on every daemon — the card handler
|
|
570
|
+
* only takes it from one), `idle` counts THIS daemon's own idle live workers
|
|
571
|
+
* (owning-daemon-authoritative — the handler sums across daemons). Mirrors the
|
|
572
|
+
* exact classification the sweep uses so the preview matches what a click does.
|
|
573
|
+
*/
|
|
574
|
+
ipcRoute('GET', '/api/host-overload/counts', (_req, res) => {
|
|
575
|
+
const stopped = sessionStore.listSessions().filter(s => s.status === 'active' && isSessionStopped(s)).length;
|
|
576
|
+
let idle = 0;
|
|
577
|
+
for (const ds of listActiveSessions()) {
|
|
578
|
+
if (!ds.worker || ds.worker.killed)
|
|
579
|
+
continue;
|
|
580
|
+
if (ds.adoptedFrom || ds.initConfig?.adoptMode)
|
|
581
|
+
continue;
|
|
582
|
+
if (ds.lastScreenStatus !== 'idle')
|
|
583
|
+
continue;
|
|
584
|
+
idle++;
|
|
585
|
+
}
|
|
586
|
+
jsonRes(res, 200, { ok: true, stopped, idle });
|
|
587
|
+
});
|
|
588
|
+
/**
|
|
589
|
+
* Bulk host-overload降压 sweep, driven by the overload-alert card buttons.
|
|
590
|
+
* `mode`:
|
|
591
|
+
* - `clean_stopped`: close stopped zombie sessions (dead CLI + no tmux) from
|
|
592
|
+
* the SHARED session store — machine-wide, so a single daemon's sweep is
|
|
593
|
+
* enough (the alert-owning daemon calls this once, no fan-out needed).
|
|
594
|
+
* - `suspend_idle`: suspend THIS daemon's own idle (non-busy, suspendable,
|
|
595
|
+
* non-adopt) live workers. Live workers only exist in their owning daemon's
|
|
596
|
+
* process, so the card handler fans this mode out to every online daemon.
|
|
597
|
+
* Returns `{ ok, mode, affected }` — `affected` counts sessions acted on here.
|
|
598
|
+
*/
|
|
599
|
+
ipcRoute('POST', '/api/host-overload/sweep', async (req, res) => {
|
|
600
|
+
let body;
|
|
601
|
+
try {
|
|
602
|
+
body = await readJsonBody(req);
|
|
603
|
+
}
|
|
604
|
+
catch {
|
|
605
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
606
|
+
}
|
|
607
|
+
const mode = body?.mode;
|
|
608
|
+
if (mode === 'clean_stopped') {
|
|
609
|
+
const stopped = sessionStore.listSessions().filter(s => s.status === 'active' && isSessionStopped(s));
|
|
610
|
+
let affected = 0;
|
|
611
|
+
for (const s of stopped) {
|
|
612
|
+
try {
|
|
613
|
+
const r = await closeSession(s.sessionId);
|
|
614
|
+
// Only count sessions this call actually closed. A shared-store session
|
|
615
|
+
// already closed by another daemon's concurrent sweep returns
|
|
616
|
+
// alreadyClosed=true — counting it would inflate `affected` by the
|
|
617
|
+
// number of daemons that raced on the same zombie.
|
|
618
|
+
if (r.ok && !r.alreadyClosed)
|
|
619
|
+
affected++;
|
|
620
|
+
}
|
|
621
|
+
catch (err) {
|
|
622
|
+
logger.warn(`[overload-sweep] close failed for ${s.sessionId.slice(0, 8)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
logger.info(`[overload-sweep] clean_stopped: closed ${affected}/${stopped.length} zombie session(s)`);
|
|
626
|
+
return jsonRes(res, 200, { ok: true, mode, affected });
|
|
627
|
+
}
|
|
628
|
+
if (mode === 'suspend_idle') {
|
|
629
|
+
// This daemon's own idle live workers only. Correctness guards mirror the
|
|
630
|
+
// idle-worker sweeper: never touch adopt sessions or mid-turn (busy) ones.
|
|
631
|
+
let affected = 0;
|
|
632
|
+
for (const ds of listActiveSessions()) {
|
|
633
|
+
if (!ds.worker || ds.worker.killed)
|
|
634
|
+
continue; // no live worker
|
|
635
|
+
if (ds.adoptedFrom || ds.initConfig?.adoptMode)
|
|
636
|
+
continue; // never suspend adopt
|
|
637
|
+
if (ds.lastScreenStatus !== 'idle')
|
|
638
|
+
continue; // never cut an in-flight reply
|
|
639
|
+
try {
|
|
640
|
+
if (suspendWorker(ds, 'host_overload_suspend'))
|
|
641
|
+
affected++;
|
|
642
|
+
}
|
|
643
|
+
catch (err) {
|
|
644
|
+
logger.warn(`[overload-sweep] suspend failed for ${ds.session.sessionId.slice(0, 8)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
logger.info(`[overload-sweep] suspend_idle: suspended ${affected} idle worker(s)`);
|
|
648
|
+
return jsonRes(res, 200, { ok: true, mode, affected });
|
|
649
|
+
}
|
|
650
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_mode' });
|
|
651
|
+
});
|
|
507
652
|
/** 会话级 CLI IPC(slash/cd)的调用方证明:trusted-host(.dashboard-secret HMAC,
|
|
508
653
|
* 外层 gate 已验)直接放行;否则(沙箱/读隔离 CLI 读不到 secret,走
|
|
509
654
|
* routeHasNarrowUntrustedAuth 窄孔进来)必须出示该会话当前轮换的 capability,
|
|
@@ -564,7 +709,18 @@ ipcRoute('POST', '/api/sessions/:sessionId/slash', async (req, res, params) => {
|
|
|
564
709
|
jsonRes(res, 200, { ok: true, sessionId: params.sessionId, queued: v.command });
|
|
565
710
|
});
|
|
566
711
|
/** 会话内切换工作目录(角色切换专用):硬校验角色库根 → 更新记录落盘(唯一事实源)
|
|
567
|
-
* →
|
|
712
|
+
* → 活 worker 走「带 --resume 的进程重启、respawn 在新 cwd」,无活 worker 杀残留
|
|
713
|
+
* pane 让下条消息冷启动。
|
|
714
|
+
*
|
|
715
|
+
* 为什么是 respawn 而不是向活进程注入 /cd(旧实现):CLI 的系统上下文(CLAUDE.md、
|
|
716
|
+
* 记忆路径/索引)是开场按启动 cwd 注入一次的静态快照,/cd 只改 cwd 不重刷——注入
|
|
717
|
+
* 切换后模型仍拿着旧角色的记忆索引读写(读旧索引、写错桶)。respawn 让「开场」在
|
|
718
|
+
* 新 cwd 重新发生:新角色的 CLAUDE.md/记忆索引开场即注入,--resume 回放对话历史
|
|
719
|
+
* 保留上下文(“换角色外壳、留对话内核”)。旧桶 transcript 由 claude-code 适配器的
|
|
720
|
+
* resume 预检 syncClaudeResumeTargetToCwd(worker.ts 每次 resume respawn、probe 之前
|
|
721
|
+
* 把最新 <sid>.jsonl COPY 进新 cwd 的 project 目录,已在 master)接住,不会探空丢
|
|
722
|
+
* 上下文。故本改动可独立部署,不硬依赖任何跨桶迁移专项 PR。
|
|
723
|
+
*
|
|
568
724
|
* 鉴权双路径(见 sessionCliIpcAuth):trusted-host 签名或本会话 rotating
|
|
569
725
|
* capability;目录面由 validateRoleLibraryPath 硬校验承担(realpath 归一 +
|
|
570
726
|
* dev/ino 包含判断,角色库根之外一律拒)。
|
|
@@ -588,21 +744,14 @@ ipcRoute('POST', '/api/sessions/:sessionId/cd', async (req, res, params) => {
|
|
|
588
744
|
return jsonRes(res, v.error === 'outside_role_library' ? 403 : 400, { ok: false, error: v.error });
|
|
589
745
|
}
|
|
590
746
|
repinSessionWorkingDir(ds, v.resolvedPath);
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
}
|
|
596
|
-
catch { /* unknown cli */ }
|
|
597
|
-
if (ds.worker && !ds.worker.killed && canInject) {
|
|
598
|
-
// updateWorkingDir 随 inject_command 带给 worker:会话内 /cd 后 worker 内部的
|
|
599
|
-
// respawn(claude_exit 自动重启 / IM /restart / dashboard restart)必须收敛到
|
|
600
|
-
// 新目录,而不是陈旧的 lastInitConfig.workingDir。daemon 侧的 ds.initConfig 同步
|
|
601
|
-
// 更新,保持与 worker 侧一致(下次 forkWorker 用它重建 init 消息)。
|
|
747
|
+
if (ds.worker && !ds.worker.killed) {
|
|
748
|
+
// updateWorkingDir 随 restart 带给 worker:respawn 必须收敛到新目录,而不是
|
|
749
|
+
// 陈旧的 lastInitConfig.workingDir。daemon 侧的 ds.initConfig 同步更新,保持
|
|
750
|
+
// 与 worker 侧一致(下次 forkWorker 用它重建 init 消息)。
|
|
602
751
|
if (ds.initConfig)
|
|
603
752
|
ds.initConfig.workingDir = v.resolvedPath;
|
|
604
753
|
try {
|
|
605
|
-
ds.worker.send({ type: '
|
|
754
|
+
ds.worker.send({ type: 'restart', updateWorkingDir: v.resolvedPath });
|
|
606
755
|
}
|
|
607
756
|
catch {
|
|
608
757
|
// send() 抛异常:worker 进程实际上已经不可达(管道已断),但 above 的
|
|
@@ -611,7 +760,7 @@ ipcRoute('POST', '/api/sessions/:sessionId/cd', async (req, res, params) => {
|
|
|
611
760
|
killWorker(ds);
|
|
612
761
|
return jsonRes(res, 200, { ok: true, mode: 'cold-restart', dir: v.resolvedPath });
|
|
613
762
|
}
|
|
614
|
-
return jsonRes(res, 200, { ok: true, mode: '
|
|
763
|
+
return jsonRes(res, 200, { ok: true, mode: 'respawn-resume', dir: v.resolvedPath });
|
|
615
764
|
}
|
|
616
765
|
// Unconditional (no `ds.worker` guard), matching the IM `/cd` command handler
|
|
617
766
|
// (src/core/command-handler.ts) — killWorker() already no-ops safely when there
|
|
@@ -629,45 +778,61 @@ ipcRoute('POST', '/api/sessions/:sessionId/cd', async (req, res, params) => {
|
|
|
629
778
|
function findSessionRecord(sessionId) {
|
|
630
779
|
return findActiveBySessionId(sessionId)?.session ?? sessionStore.getSession(sessionId);
|
|
631
780
|
}
|
|
781
|
+
/** Four-state async lookup with durable fallback (design A).
|
|
782
|
+
*
|
|
783
|
+
* In-memory `asyncTriggerResults` lives only on the active DaemonSession and is
|
|
784
|
+
* lost on daemon restart / idle-suspend. To keep a poller from misreading an
|
|
785
|
+
* already-completed turn as `not_found`, this resolves against BOTH the live
|
|
786
|
+
* session and the on-disk stores:
|
|
787
|
+
* - completed (mem or disk) → completed + output.content + finishedAt
|
|
788
|
+
* - pending in mem / session active → running
|
|
789
|
+
* - session record closed, no output → failed (no_output; soft terminal —
|
|
790
|
+
* may be a real failure OR a caller close)
|
|
791
|
+
* - no session record AND no result → not_found (never existed / invalid id)
|
|
792
|
+
*
|
|
793
|
+
* Legacy `action`/`async` fields are still populated so existing webhook
|
|
794
|
+
* consumers keep working; new callers branch on `state`. */
|
|
632
795
|
function buildAsyncTriggerLookupResponse(sessionId, triggerId) {
|
|
633
796
|
const ds = findActiveBySessionId(sessionId);
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
797
|
+
const storedRaw = ds?.session ?? sessionStore.getSession(sessionId);
|
|
798
|
+
const persistedRaw = asyncTriggerStore.lookup(sessionId, triggerId);
|
|
799
|
+
// Cross-bot isolation (fail-closed / positive-proof) — see decideAsyncOwnership.
|
|
800
|
+
// Both sessionStore.getSession() (cross-scans every bot's sessions-*.json) and
|
|
801
|
+
// the async store (machine-wide shared dir) can surface another bot's data for
|
|
802
|
+
// a sessionId routed to THIS daemon; keep only sources positively proven ours.
|
|
803
|
+
const decision = decideAsyncOwnership({
|
|
804
|
+
owner: cachedLarkAppId,
|
|
805
|
+
liveDs: !!ds,
|
|
806
|
+
storedOwner: storedRaw?.larkAppId,
|
|
807
|
+
storedExists: !!storedRaw,
|
|
808
|
+
persistedOwner: persistedRaw?.ownerLarkAppId,
|
|
809
|
+
persistedExists: !!persistedRaw,
|
|
810
|
+
});
|
|
811
|
+
const stored = decision.keepStored ? storedRaw : undefined;
|
|
812
|
+
const persisted = decision.keepPersisted ? persistedRaw : undefined;
|
|
813
|
+
if (decision.foreignLeak) {
|
|
646
814
|
return {
|
|
647
815
|
ok: true,
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
status: 'completed',
|
|
654
|
-
sessionId,
|
|
655
|
-
completedAt: state.completedAt ? new Date(state.completedAt).toISOString() : undefined,
|
|
656
|
-
},
|
|
657
|
-
message: 'async trigger completed',
|
|
816
|
+
state: 'not_found',
|
|
817
|
+
triggerId,
|
|
818
|
+
errorCode: 'session_not_found',
|
|
819
|
+
error: `no session record for: ${sessionId}`,
|
|
820
|
+
message: 'no session found',
|
|
658
821
|
};
|
|
659
822
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
823
|
+
const memTriggerId = triggerId || ds?.latestAsyncTriggerId;
|
|
824
|
+
const memResult = ds && memTriggerId ? ds.asyncTriggerResults?.get(memTriggerId) : undefined;
|
|
825
|
+
return resolveAsyncTriggerState({
|
|
826
|
+
sessionId,
|
|
827
|
+
liveActive: !!ds,
|
|
828
|
+
chatId: ds?.chatId ?? stored?.chatId,
|
|
829
|
+
memResult: memResult ? { status: memResult.status, content: memResult.content, completedAt: memResult.completedAt } : undefined,
|
|
830
|
+
memTriggerId: memResult ? memTriggerId : undefined,
|
|
831
|
+
persisted,
|
|
832
|
+
storedStatus: stored ? (stored.status === 'closed' ? 'closed' : 'open') : undefined,
|
|
833
|
+
closedAt: stored?.closedAt,
|
|
834
|
+
requestedTriggerId: triggerId,
|
|
835
|
+
});
|
|
671
836
|
}
|
|
672
837
|
// 看板放置:dashboard 看板视图拖拽卡片后持久化列 + 列内排序位置。
|
|
673
838
|
// 改完广播 session.update,所有打开的 dashboard 实时同步。
|
|
@@ -881,12 +1046,10 @@ ipcRoute('GET', '/api/sessions/:sessionId/trigger-result', (req, res, params) =>
|
|
|
881
1046
|
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
882
1047
|
const triggerId = url.searchParams.get('triggerId') ?? undefined;
|
|
883
1048
|
const result = buildAsyncTriggerLookupResponse(params.sessionId, triggerId);
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
: 400;
|
|
889
|
-
jsonRes(res, status, result);
|
|
1049
|
+
// Four-state semantics: the query itself succeeds (HTTP 200) for every
|
|
1050
|
+
// resolved state including not_found — task state lives in `result.state`,
|
|
1051
|
+
// not the HTTP status. Only a malformed lookup (ok:false) maps to non-200.
|
|
1052
|
+
jsonRes(res, result.ok ? 200 : 400, result);
|
|
890
1053
|
});
|
|
891
1054
|
// 会话 insight:只读解析本会话的 transcript,产出动作 span / 失败聚合 / 规则建议
|
|
892
1055
|
// (SafeInsightReport)。底层 services/insight 已做 fail-closed 脱敏投影——raw 命令
|
|
@@ -1134,32 +1297,6 @@ function workingDirForSession(sessionId) {
|
|
|
1134
1297
|
return ds.session.workingDir;
|
|
1135
1298
|
return sessionStore.listSessions().find(s => s.sessionId === sessionId)?.workingDir;
|
|
1136
1299
|
}
|
|
1137
|
-
ipcRoute('GET', '/api/sessions/:sessionId/sandbox-diff', (_req, res, params) => {
|
|
1138
|
-
const d = computeSandboxDiff(config.session.dataDir, params.sessionId, localeForBot(cachedLarkAppId));
|
|
1139
|
-
if (!d.ok)
|
|
1140
|
-
return jsonRes(res, 200, { ok: false, error: d.error });
|
|
1141
|
-
jsonRes(res, 200, {
|
|
1142
|
-
ok: true, empty: d.empty, files: d.files, insertions: d.insertions, deletions: d.deletions,
|
|
1143
|
-
statText: d.statText, patch: d.patch, workingDir: workingDirForSession(params.sessionId) ?? null,
|
|
1144
|
-
});
|
|
1145
|
-
});
|
|
1146
|
-
ipcRoute('POST', '/api/sessions/:sessionId/sandbox-land/:action', (_req, res, params) => {
|
|
1147
|
-
if (params.action === 'discard')
|
|
1148
|
-
return jsonRes(res, 200, { ok: true, discarded: true });
|
|
1149
|
-
if (params.action !== 'apply')
|
|
1150
|
-
return jsonRes(res, 400, { ok: false, error: 'unknown action' });
|
|
1151
|
-
const locLand = localeForBot(cachedLarkAppId);
|
|
1152
|
-
const wd = workingDirForSession(params.sessionId);
|
|
1153
|
-
if (!wd)
|
|
1154
|
-
return jsonRes(res, 404, { ok: false, error: t('sandbox.workingdir_not_found', undefined, locLand) });
|
|
1155
|
-
const d = computeSandboxDiff(config.session.dataDir, params.sessionId, locLand);
|
|
1156
|
-
if (!d.ok)
|
|
1157
|
-
return jsonRes(res, 200, { ok: false, error: d.error });
|
|
1158
|
-
if (d.empty)
|
|
1159
|
-
return jsonRes(res, 200, { ok: false, error: t('sandbox.no_changes_left', undefined, locLand) });
|
|
1160
|
-
const a = applySandboxDiff(wd, config.session.dataDir, params.sessionId, locLand);
|
|
1161
|
-
jsonRes(res, 200, a.ok ? { ok: true, files: d.files, insertions: d.insertions, deletions: d.deletions, workingDir: wd } : { ok: false, error: a.error });
|
|
1162
|
-
});
|
|
1163
1300
|
/**
|
|
1164
1301
|
* Reactivate a closed session — counterpart to `/close`. Used by both the
|
|
1165
1302
|
* "▶️ 恢复会话" card button (via card-handler) and the `botmux resume <id>`
|
|
@@ -2209,6 +2346,20 @@ ipcRoute('GET', '/api/bot-default-oncall', async (_req, res) => {
|
|
|
2209
2346
|
startupCommands = sc.join('\n');
|
|
2210
2347
|
}
|
|
2211
2348
|
catch { /* none */ }
|
|
2349
|
+
// customPassthroughCommands / canTalkDaemonCommands → space-joined for the
|
|
2350
|
+
// dashboard slash-command editors. Empty string = not configured (回默认).
|
|
2351
|
+
let customPassthroughCommands = '';
|
|
2352
|
+
let canTalkDaemonCommands = '';
|
|
2353
|
+
try {
|
|
2354
|
+
const cfg = getBot(cachedLarkAppId).config;
|
|
2355
|
+
if (Array.isArray(cfg.customPassthroughCommands) && cfg.customPassthroughCommands.length) {
|
|
2356
|
+
customPassthroughCommands = cfg.customPassthroughCommands.join(' ');
|
|
2357
|
+
}
|
|
2358
|
+
if (Array.isArray(cfg.canTalkDaemonCommands) && cfg.canTalkDaemonCommands.length) {
|
|
2359
|
+
canTalkDaemonCommands = cfg.canTalkDaemonCommands.join(' ');
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
catch { /* none */ }
|
|
2212
2363
|
// Per-bot env → pretty JSON for the dashboard textarea. The dashboard is
|
|
2213
2364
|
// owner-authenticated, so showing the real values here is acceptable (same
|
|
2214
2365
|
// as editing bots.json directly); the chat-facing /config get masks them.
|
|
@@ -2256,6 +2407,7 @@ ipcRoute('GET', '/api/bot-default-oncall', async (_req, res) => {
|
|
|
2256
2407
|
autoboundChatCount: autoboundChats.length,
|
|
2257
2408
|
brandLabel: brandStore.getBotBrandLabel(cachedLarkAppId) ?? null,
|
|
2258
2409
|
sandbox: sandboxStore.getBotSandbox(cachedLarkAppId),
|
|
2410
|
+
sandboxPaths: sandboxStore.getBotSandboxPaths(cachedLarkAppId) ?? null,
|
|
2259
2411
|
readIsolation: sandboxStore.getBotReadIsolation(cachedLarkAppId),
|
|
2260
2412
|
// Full enforceability (adapter support + no wrapperCli + macOS) — the UI
|
|
2261
2413
|
// disables the toggle wherever the worker would fail-close on it.
|
|
@@ -2266,6 +2418,7 @@ ipcRoute('GET', '/api/bot-default-oncall', async (_req, res) => {
|
|
|
2266
2418
|
codexAppCleanInput: cardPrefs.codexAppCleanInput,
|
|
2267
2419
|
writableTerminalLinkInCard: cardPrefs.writableTerminalLinkInCard,
|
|
2268
2420
|
privateCard: cardPrefs.privateCard,
|
|
2421
|
+
overloadAlert: cardPrefs.overloadAlert,
|
|
2269
2422
|
botToBotSameDir: cardPrefs.botToBotSameDir,
|
|
2270
2423
|
autoStartOnGroupJoin: cardPrefs.autoStartOnGroupJoin,
|
|
2271
2424
|
autoStartOnGroupJoinPrompt: cardPrefs.autoStartOnGroupJoinPrompt,
|
|
@@ -2288,6 +2441,8 @@ ipcRoute('GET', '/api/bot-default-oncall', async (_req, res) => {
|
|
|
2288
2441
|
residentSessionCount,
|
|
2289
2442
|
dormantSessionCount,
|
|
2290
2443
|
startupCommands,
|
|
2444
|
+
customPassthroughCommands,
|
|
2445
|
+
canTalkDaemonCommands,
|
|
2291
2446
|
launchShell: getBot(cachedLarkAppId).config.launchShell ?? '',
|
|
2292
2447
|
env,
|
|
2293
2448
|
riff: redactRiffForClient(getBot(cachedLarkAppId).config.riff),
|
|
@@ -2320,6 +2475,8 @@ ipcRoute('PUT', '/api/bot-card-prefs', async (req, res) => {
|
|
|
2320
2475
|
patch.writableTerminalLinkInCard = body.writableTerminalLinkInCard;
|
|
2321
2476
|
if (typeof body.privateCard === 'boolean')
|
|
2322
2477
|
patch.privateCard = body.privateCard;
|
|
2478
|
+
if (typeof body.overloadAlert === 'boolean')
|
|
2479
|
+
patch.overloadAlert = body.overloadAlert;
|
|
2323
2480
|
if (typeof body.autoStartOnGroupJoin === 'boolean')
|
|
2324
2481
|
patch.autoStartOnGroupJoin = body.autoStartOnGroupJoin;
|
|
2325
2482
|
if (typeof body.autoStartOnGroupJoinPrompt === 'string')
|
|
@@ -2768,6 +2925,72 @@ ipcRoute('PUT', '/api/bot-startup-commands', async (req, res) => {
|
|
|
2768
2925
|
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
2769
2926
|
jsonRes(res, 200, { ok: true, startupCommands: (value ?? []).join('\n') });
|
|
2770
2927
|
});
|
|
2928
|
+
// Per-bot 透传 slash 命令 customPassthroughCommands。Body `{ customPassthroughCommands: string }`
|
|
2929
|
+
// (原始文本,逗号/空格分隔;空白=清除→回仅内置白名单)。走 stringList 的
|
|
2930
|
+
// coerceConfigValue(用字段自带 parseList,与 /botconfig 同口径)+ applyConfigField
|
|
2931
|
+
// (写盘 + 内存热更新),immediate 生效。回包 space-joined 供输入框回填。
|
|
2932
|
+
ipcRoute('PUT', '/api/bot-custom-passthrough', async (req, res) => {
|
|
2933
|
+
if (!cachedLarkAppId)
|
|
2934
|
+
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2935
|
+
let body;
|
|
2936
|
+
try {
|
|
2937
|
+
body = await readJsonBody(req);
|
|
2938
|
+
}
|
|
2939
|
+
catch {
|
|
2940
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
2941
|
+
}
|
|
2942
|
+
const spec = findConfigField('customPassthroughCommands');
|
|
2943
|
+
if (!spec)
|
|
2944
|
+
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
2945
|
+
const raw = typeof body.customPassthroughCommands === 'string' ? body.customPassthroughCommands : '';
|
|
2946
|
+
let value;
|
|
2947
|
+
if (!raw.trim()) {
|
|
2948
|
+
value = null; // 清除 → 回仅内置白名单
|
|
2949
|
+
}
|
|
2950
|
+
else {
|
|
2951
|
+
const coerced = coerceConfigValue(spec, raw);
|
|
2952
|
+
if (!coerced.ok)
|
|
2953
|
+
return jsonRes(res, 400, { ok: false, error: coerced.reason });
|
|
2954
|
+
value = coerced.value;
|
|
2955
|
+
}
|
|
2956
|
+
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
2957
|
+
if (!r.ok)
|
|
2958
|
+
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
2959
|
+
jsonRes(res, 200, { ok: true, customPassthroughCommands: (value ?? []).join(' ') });
|
|
2960
|
+
});
|
|
2961
|
+
// Per-bot daemon 命令降权名单 canTalkDaemonCommands。Body
|
|
2962
|
+
// `{ canTalkDaemonCommands: string }`(原始文本,逗号/空格分隔;空白=清除→回全部
|
|
2963
|
+
// 仅管理员)。走 stringList 的 coerceConfigValue(字段自带 parseList 只认 daemon
|
|
2964
|
+
// 命令,透传/拼错条目被滤掉)+ applyConfigField(写盘 + 内存热更新),immediate 生效。
|
|
2965
|
+
ipcRoute('PUT', '/api/bot-cantalk-daemon-commands', async (req, res) => {
|
|
2966
|
+
if (!cachedLarkAppId)
|
|
2967
|
+
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
2968
|
+
let body;
|
|
2969
|
+
try {
|
|
2970
|
+
body = await readJsonBody(req);
|
|
2971
|
+
}
|
|
2972
|
+
catch {
|
|
2973
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
2974
|
+
}
|
|
2975
|
+
const spec = findConfigField('canTalkDaemonCommands');
|
|
2976
|
+
if (!spec)
|
|
2977
|
+
return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
|
|
2978
|
+
const raw = typeof body.canTalkDaemonCommands === 'string' ? body.canTalkDaemonCommands : '';
|
|
2979
|
+
let value;
|
|
2980
|
+
if (!raw.trim()) {
|
|
2981
|
+
value = null; // 清除 → 回全部仅管理员
|
|
2982
|
+
}
|
|
2983
|
+
else {
|
|
2984
|
+
const coerced = coerceConfigValue(spec, raw);
|
|
2985
|
+
if (!coerced.ok)
|
|
2986
|
+
return jsonRes(res, 400, { ok: false, error: coerced.reason });
|
|
2987
|
+
value = coerced.value;
|
|
2988
|
+
}
|
|
2989
|
+
const r = await applyConfigField(cachedLarkAppId, spec, value);
|
|
2990
|
+
if (!r.ok)
|
|
2991
|
+
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
2992
|
+
jsonRes(res, 200, { ok: true, canTalkDaemonCommands: (value ?? []).join(' ') });
|
|
2993
|
+
});
|
|
2771
2994
|
// Per-bot launch-shell override launchShell。Body `{ launchShell: string }`:
|
|
2772
2995
|
// 空字符串=清除(回 $SHELL)。走 applyConfigField(与 /config launchShell 同一写盘
|
|
2773
2996
|
// + 内存热更新路径),next-session 生效(下个会话起用新 shell 启动 CLI)。
|
|
@@ -3004,6 +3227,31 @@ ipcRoute('PUT', '/api/bot-sandbox', async (req, res) => {
|
|
|
3004
3227
|
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3005
3228
|
jsonRes(res, 200, { ok: true, sandbox: r.sandbox });
|
|
3006
3229
|
});
|
|
3230
|
+
// Per-bot sandboxPaths (three-tier whitelist: readWrite / readOnly / deny).
|
|
3231
|
+
// Body `{ readWrite?: string[]; readOnly?: string[]; deny?: string[] }`. Highest-
|
|
3232
|
+
// precedence layer of the FsPolicy — an empty/absent tier falls back to the
|
|
3233
|
+
// deny-by-default baseline. Passing all-empty CLEARS the field. next-session
|
|
3234
|
+
// 生效:running sessions keep their spawn-time policy, only new spawns re-read it.
|
|
3235
|
+
ipcRoute('PUT', '/api/bot-sandbox-paths', async (req, res) => {
|
|
3236
|
+
if (!cachedLarkAppId)
|
|
3237
|
+
return jsonRes(res, 503, { error: 'larkAppId_not_set' });
|
|
3238
|
+
let body;
|
|
3239
|
+
try {
|
|
3240
|
+
body = await readJsonBody(req);
|
|
3241
|
+
}
|
|
3242
|
+
catch {
|
|
3243
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3244
|
+
}
|
|
3245
|
+
const asList = (v) => Array.isArray(v) ? v.filter((x) => typeof x === 'string') : undefined;
|
|
3246
|
+
const r = await sandboxStore.updateBotSandboxPaths(cachedLarkAppId, {
|
|
3247
|
+
readWrite: asList(body.readWrite),
|
|
3248
|
+
readOnly: asList(body.readOnly),
|
|
3249
|
+
deny: asList(body.deny),
|
|
3250
|
+
});
|
|
3251
|
+
if (!r.ok)
|
|
3252
|
+
return jsonRes(res, 400, { ok: false, error: r.reason });
|
|
3253
|
+
jsonRes(res, 200, { ok: true, sandboxPaths: r.sandboxPaths ?? null });
|
|
3254
|
+
});
|
|
3007
3255
|
// Per-bot read-isolation toggle. Body `{ enabled: boolean }`. When on, this bot's
|
|
3008
3256
|
// CLI sessions run under macOS Seatbelt read-deny (siblings' creds/sessions/content
|
|
3009
3257
|
// unreadable). The macOS counterpart of the file sandbox above.
|
|
@@ -3352,9 +3600,33 @@ ipcRoute('GET', '/api/events', (_req, res) => {
|
|
|
3352
3600
|
// aggregator and the browser store upsert by sessionId, so any row also
|
|
3353
3601
|
// delivered live just refreshes the same entry.
|
|
3354
3602
|
try {
|
|
3603
|
+
const activeIds = new Set();
|
|
3355
3604
|
for (const ds of listActiveSessions()) {
|
|
3605
|
+
activeIds.add(ds.session.sessionId);
|
|
3356
3606
|
res.write(`event: session.spawned\ndata: ${JSON.stringify({ session: composeRowFromActive(ds) })}\n\n`);
|
|
3357
3607
|
}
|
|
3608
|
+
// Also replay sessions CLOSED during this run as `session.spawned` carrying a
|
|
3609
|
+
// closed row. The active-only replay above can't cover a restore-time zombie:
|
|
3610
|
+
// restoreActiveSessions registers it, announces it, then immediately probes it
|
|
3611
|
+
// 'missing' and closeSession()s it (evicting it from the active Map) — all
|
|
3612
|
+
// before a racing dashboard's SSE subscription exists. By connect time it is
|
|
3613
|
+
// neither in the active Map nor was it a closed row at the dashboard's early
|
|
3614
|
+
// (pre-restore) hydrate, so without this it stays invisible (or, if the
|
|
3615
|
+
// dashboard cached it active from before the restart, lingers as a stale
|
|
3616
|
+
// active row — hydrateSessions only upserts, never deletes absent rows).
|
|
3617
|
+
// Bounded to closedAt >= PROCESS_START_MS so we replay only this run's
|
|
3618
|
+
// closures (the full closed history is already served by GET /api/sessions
|
|
3619
|
+
// on hydrate). `session.spawned` (not session.update) because the row may be
|
|
3620
|
+
// unknown to the client — both consumers upsert by sessionId, and the closed
|
|
3621
|
+
// row's status:'closed' overwrites any stale active entry.
|
|
3622
|
+
for (const s of sessionStore.listSessions()) {
|
|
3623
|
+
if (s.status !== 'closed' || activeIds.has(s.sessionId))
|
|
3624
|
+
continue;
|
|
3625
|
+
const closedMs = s.closedAt ? Date.parse(s.closedAt) : NaN;
|
|
3626
|
+
if (!Number.isFinite(closedMs) || closedMs < PROCESS_START_MS)
|
|
3627
|
+
continue;
|
|
3628
|
+
res.write(`event: session.spawned\ndata: ${JSON.stringify({ session: composeRowFromClosed(s) })}\n\n`);
|
|
3629
|
+
}
|
|
3358
3630
|
}
|
|
3359
3631
|
catch (err) {
|
|
3360
3632
|
logger.warn(`[dashboard-ipc] /api/events snapshot replay failed: ${err}`);
|