botmux 3.4.2 → 3.5.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 +10 -7
- package/README.md +11 -6
- package/dist/adapters/backend/herdr-backend.d.ts +43 -6
- package/dist/adapters/backend/herdr-backend.d.ts.map +1 -1
- package/dist/adapters/backend/herdr-backend.js +362 -28
- package/dist/adapters/backend/herdr-backend.js.map +1 -1
- package/dist/adapters/backend/reproduce-command.d.ts +39 -0
- package/dist/adapters/backend/reproduce-command.d.ts.map +1 -0
- package/dist/adapters/backend/reproduce-command.js +63 -0
- package/dist/adapters/backend/reproduce-command.js.map +1 -0
- package/dist/adapters/backend/session-backend-selector.d.ts +10 -1
- package/dist/adapters/backend/session-backend-selector.d.ts.map +1 -1
- package/dist/adapters/backend/session-backend-selector.js +73 -4
- package/dist/adapters/backend/session-backend-selector.js.map +1 -1
- package/dist/adapters/backend/types.d.ts +16 -0
- package/dist/adapters/backend/types.d.ts.map +1 -1
- package/dist/adapters/backend/types.js.map +1 -1
- package/dist/adapters/cli/pi-initial-prompt-extension.d.ts +27 -0
- package/dist/adapters/cli/pi-initial-prompt-extension.d.ts.map +1 -0
- package/dist/adapters/cli/pi-initial-prompt-extension.js +38 -0
- package/dist/adapters/cli/pi-initial-prompt-extension.js.map +1 -0
- package/dist/adapters/cli/pi-initial-prompt.d.ts +21 -0
- package/dist/adapters/cli/pi-initial-prompt.d.ts.map +1 -0
- package/dist/adapters/cli/pi-initial-prompt.js +59 -0
- package/dist/adapters/cli/pi-initial-prompt.js.map +1 -0
- package/dist/adapters/cli/pi.d.ts.map +1 -1
- package/dist/adapters/cli/pi.js +15 -4
- package/dist/adapters/cli/pi.js.map +1 -1
- package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
- package/dist/adapters/cli/read-isolation.js +5 -0
- package/dist/adapters/cli/read-isolation.js.map +1 -1
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +8 -0
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/adapters/cli/traex.d.ts.map +1 -1
- package/dist/adapters/cli/traex.js +5 -0
- package/dist/adapters/cli/traex.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +23 -3
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/adapters/hook-installer.d.ts +7 -0
- package/dist/adapters/hook-installer.d.ts.map +1 -1
- package/dist/adapters/hook-installer.js +56 -0
- package/dist/adapters/hook-installer.js.map +1 -1
- package/dist/bot-registry.d.ts +13 -0
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +118 -2
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/capabilities.d.ts +24 -0
- package/dist/cli/capabilities.d.ts.map +1 -0
- package/dist/cli/capabilities.js +25 -0
- package/dist/cli/capabilities.js.map +1 -0
- package/dist/cli/create-group-resolver.d.ts +24 -0
- package/dist/cli/create-group-resolver.d.ts.map +1 -1
- package/dist/cli/create-group-resolver.js +23 -0
- package/dist/cli/create-group-resolver.js.map +1 -1
- package/dist/cli/daemon-lifecycle-env.d.ts +5 -7
- package/dist/cli/daemon-lifecycle-env.d.ts.map +1 -1
- package/dist/cli/daemon-lifecycle-env.js +13 -7
- package/dist/cli/daemon-lifecycle-env.js.map +1 -1
- package/dist/cli/exact-chat-grant-client.d.ts +48 -0
- package/dist/cli/exact-chat-grant-client.d.ts.map +1 -0
- package/dist/cli/exact-chat-grant-client.js +108 -0
- package/dist/cli/exact-chat-grant-client.js.map +1 -0
- package/dist/cli/exact-chat-grant.d.ts +18 -0
- package/dist/cli/exact-chat-grant.d.ts.map +1 -0
- package/dist/cli/exact-chat-grant.js +97 -0
- package/dist/cli/exact-chat-grant.js.map +1 -0
- package/dist/cli.d.ts +10 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +770 -126
- package/dist/cli.js.map +1 -1
- package/dist/codex-rpc-engine.d.ts +26 -0
- package/dist/codex-rpc-engine.d.ts.map +1 -1
- package/dist/codex-rpc-engine.js +113 -2
- package/dist/codex-rpc-engine.js.map +1 -1
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +16 -0
- package/dist/config.js.map +1 -1
- package/dist/core/bot-live-control.d.ts +41 -0
- package/dist/core/bot-live-control.d.ts.map +1 -0
- package/dist/core/bot-live-control.js +135 -0
- package/dist/core/bot-live-control.js.map +1 -0
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +28 -8
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/daemon-config-fence.d.ts +8 -0
- package/dist/core/daemon-config-fence.d.ts.map +1 -0
- package/dist/core/daemon-config-fence.js +13 -0
- package/dist/core/daemon-config-fence.js.map +1 -0
- package/dist/core/dashboard-events.d.ts +5 -0
- package/dist/core/dashboard-events.d.ts.map +1 -1
- package/dist/core/dashboard-events.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +21 -2
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +232 -5
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dispatch-registry.d.ts +12 -0
- package/dist/core/dispatch-registry.d.ts.map +1 -0
- package/dist/core/dispatch-registry.js +33 -0
- package/dist/core/dispatch-registry.js.map +1 -0
- package/dist/core/dispatch.d.ts +99 -0
- package/dist/core/dispatch.d.ts.map +1 -1
- package/dist/core/dispatch.js +136 -0
- package/dist/core/dispatch.js.map +1 -1
- package/dist/core/inflight-input-tracker.d.ts +1 -0
- package/dist/core/inflight-input-tracker.d.ts.map +1 -1
- package/dist/core/inflight-input-tracker.js.map +1 -1
- package/dist/core/maintenance.d.ts.map +1 -1
- package/dist/core/maintenance.js +10 -3
- package/dist/core/maintenance.js.map +1 -1
- package/dist/core/persistent-backend.d.ts +16 -2
- package/dist/core/persistent-backend.d.ts.map +1 -1
- package/dist/core/persistent-backend.js +40 -0
- package/dist/core/persistent-backend.js.map +1 -1
- package/dist/core/session-discovery.d.ts +8 -1
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +140 -8
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +12 -8
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-title.d.ts +8 -0
- package/dist/core/session-title.d.ts.map +1 -1
- package/dist/core/session-title.js +54 -0
- package/dist/core/session-title.js.map +1 -1
- package/dist/core/terminal-write-auth.d.ts +15 -0
- package/dist/core/terminal-write-auth.d.ts.map +1 -1
- package/dist/core/terminal-write-auth.js +20 -0
- package/dist/core/terminal-write-auth.js.map +1 -1
- package/dist/core/trigger-session.d.ts.map +1 -1
- package/dist/core/trigger-session.js +3 -2
- package/dist/core/trigger-session.js.map +1 -1
- package/dist/core/types.d.ts +33 -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 +27 -8
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +389 -19
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts +4 -2
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +397 -26
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/bot-onboarding.d.ts +127 -1
- package/dist/dashboard/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/bot-onboarding.js +1104 -25
- package/dist/dashboard/bot-onboarding.js.map +1 -1
- package/dist/dashboard/debug-terminal.d.ts +18 -0
- package/dist/dashboard/debug-terminal.d.ts.map +1 -0
- package/dist/dashboard/debug-terminal.js +338 -0
- package/dist/dashboard/debug-terminal.js.map +1 -0
- package/dist/dashboard/public-redact.d.ts +2 -0
- package/dist/dashboard/public-redact.d.ts.map +1 -1
- package/dist/dashboard/public-redact.js +12 -3
- package/dist/dashboard/public-redact.js.map +1 -1
- package/dist/dashboard/registry.d.ts +8 -0
- package/dist/dashboard/registry.d.ts.map +1 -1
- package/dist/dashboard/registry.js +13 -0
- package/dist/dashboard/registry.js.map +1 -1
- package/dist/dashboard/settings-write-applier.d.ts +47 -1
- package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
- package/dist/dashboard/settings-write-applier.js +102 -1
- package/dist/dashboard/settings-write-applier.js.map +1 -1
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +2 -0
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.d.ts +1 -0
- package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.js +24 -5
- package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
- package/dist/dashboard/web/bot-defaults.d.ts +15 -0
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults.js +19 -0
- package/dist/dashboard/web/bot-defaults.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +76 -6
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/icon-tooltip.d.ts +3 -0
- package/dist/dashboard/web/icon-tooltip.d.ts.map +1 -0
- package/dist/dashboard/web/icon-tooltip.js +108 -0
- package/dist/dashboard/web/icon-tooltip.js.map +1 -0
- package/dist/dashboard/web/sessions-kanban.js +2 -2
- 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 +48 -9
- package/dist/dashboard/web/sessions-page.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts +2 -0
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +46 -2
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard/web/settings-page.d.ts +78 -0
- package/dist/dashboard/web/settings-page.d.ts.map +1 -1
- package/dist/dashboard/web/settings-page.js +88 -1
- package/dist/dashboard/web/settings-page.js.map +1 -1
- package/dist/dashboard/web/store.d.ts +2 -0
- package/dist/dashboard/web/store.d.ts.map +1 -1
- package/dist/dashboard/web/store.js +13 -1
- package/dist/dashboard/web/store.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-O376WSER.js +5 -0
- package/dist/dashboard-web/chunks/{chunk-JNRSPKLS.js → chunk-EJDYUINZ.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-CUV65BIQ.js → chunk-H7P5UV4W.js} +6 -6
- package/dist/dashboard-web/chunks/{chunk-P6GO5KT4.js → chunk-QCPPKCX3.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-UBOLHQCK.js → chunk-WXPMNEYV.js} +1 -1
- package/dist/dashboard-web/chunks/{connectors-page-KTC2QWNW.js → connectors-page-IR54AOAI.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-B3EKGOLY.js → groups-page-3P4TLUMF.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-X6RXNCWX.js → insights-page-TDCZV56A.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-LLRA5LQW.js → monitor-room-QWCWL3SX.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-7MT5FEOS.js → monitoring-page-IOWFSNVC.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-KD46D5TD.js → office-page-5AUPEHZP.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-JUWNH32O.js → overview-page-QJMI6NLW.js} +1 -1
- package/dist/dashboard-web/chunks/{roles-page-P6F7NLOI.js → roles-page-WJVB52ET.js} +1 -1
- package/dist/dashboard-web/chunks/{schedules-page-XIHWZST4.js → schedules-page-RVRWHP4V.js} +1 -1
- package/dist/dashboard-web/chunks/sessions-page-KWLGBX6G.js +3 -0
- package/dist/dashboard-web/chunks/settings-page-TNZEPC7V.js +2 -0
- package/dist/dashboard-web/chunks/{skills-page-A46KVWBL.js → skills-page-7YT5TIX5.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-SDUC56DF.js → team-federation-page-NJZKTU7A.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-J5JOTUSQ.js → v3-page-NQ73UA2Q.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-U7LSOAWI.js → whiteboards-page-DSM3MDMN.js} +1 -1
- package/dist/dashboard-web/style.css +198 -7
- package/dist/dashboard.js +294 -7
- package/dist/dashboard.js.map +1 -1
- package/dist/features/codex-notifier/adoption.d.ts +11 -0
- package/dist/features/codex-notifier/adoption.d.ts.map +1 -0
- package/dist/features/codex-notifier/adoption.js +11 -0
- package/dist/features/codex-notifier/adoption.js.map +1 -0
- package/dist/features/codex-notifier/app-opener.d.ts +21 -0
- package/dist/features/codex-notifier/app-opener.d.ts.map +1 -0
- package/dist/features/codex-notifier/app-opener.js +33 -0
- package/dist/features/codex-notifier/app-opener.js.map +1 -0
- package/dist/features/codex-notifier/card-action.d.ts +27 -0
- package/dist/features/codex-notifier/card-action.d.ts.map +1 -0
- package/dist/features/codex-notifier/card-action.js +84 -0
- package/dist/features/codex-notifier/card-action.js.map +1 -0
- package/dist/features/codex-notifier/card.d.ts +12 -0
- package/dist/features/codex-notifier/card.d.ts.map +1 -0
- package/dist/features/codex-notifier/card.js +150 -0
- package/dist/features/codex-notifier/card.js.map +1 -0
- package/dist/features/codex-notifier/codex-context.d.ts +12 -0
- package/dist/features/codex-notifier/codex-context.d.ts.map +1 -0
- package/dist/features/codex-notifier/codex-context.js +161 -0
- package/dist/features/codex-notifier/codex-context.js.map +1 -0
- package/dist/features/codex-notifier/config.d.ts +9 -0
- package/dist/features/codex-notifier/config.d.ts.map +1 -0
- package/dist/features/codex-notifier/config.js +11 -0
- package/dist/features/codex-notifier/config.js.map +1 -0
- package/dist/features/codex-notifier/confirmed-turn.d.ts +20 -0
- package/dist/features/codex-notifier/confirmed-turn.d.ts.map +1 -0
- package/dist/features/codex-notifier/confirmed-turn.js +130 -0
- package/dist/features/codex-notifier/confirmed-turn.js.map +1 -0
- package/dist/features/codex-notifier/emitter.d.ts +13 -0
- package/dist/features/codex-notifier/emitter.d.ts.map +1 -0
- package/dist/features/codex-notifier/emitter.js +33 -0
- package/dist/features/codex-notifier/emitter.js.map +1 -0
- package/dist/features/codex-notifier/event-store.d.ts +29 -0
- package/dist/features/codex-notifier/event-store.d.ts.map +1 -0
- package/dist/features/codex-notifier/event-store.js +217 -0
- package/dist/features/codex-notifier/event-store.js.map +1 -0
- package/dist/features/codex-notifier/event.d.ts +46 -0
- package/dist/features/codex-notifier/event.d.ts.map +1 -0
- package/dist/features/codex-notifier/event.js +188 -0
- package/dist/features/codex-notifier/event.js.map +1 -0
- package/dist/features/codex-notifier/hook-cli.d.ts +23 -0
- package/dist/features/codex-notifier/hook-cli.d.ts.map +1 -0
- package/dist/features/codex-notifier/hook-cli.js +130 -0
- package/dist/features/codex-notifier/hook-cli.js.map +1 -0
- package/dist/features/codex-notifier/hook-installer.d.ts +19 -0
- package/dist/features/codex-notifier/hook-installer.d.ts.map +1 -0
- package/dist/features/codex-notifier/hook-installer.js +158 -0
- package/dist/features/codex-notifier/hook-installer.js.map +1 -0
- package/dist/features/codex-notifier/index.d.ts +21 -0
- package/dist/features/codex-notifier/index.d.ts.map +1 -0
- package/dist/features/codex-notifier/index.js +19 -0
- package/dist/features/codex-notifier/index.js.map +1 -0
- package/dist/features/codex-notifier/internal-turn.d.ts +5 -0
- package/dist/features/codex-notifier/internal-turn.d.ts.map +1 -0
- package/dist/features/codex-notifier/internal-turn.js +43 -0
- package/dist/features/codex-notifier/internal-turn.js.map +1 -0
- package/dist/features/codex-notifier/outbox-worker.d.ts +71 -0
- package/dist/features/codex-notifier/outbox-worker.d.ts.map +1 -0
- package/dist/features/codex-notifier/outbox-worker.js +290 -0
- package/dist/features/codex-notifier/outbox-worker.js.map +1 -0
- package/dist/features/codex-notifier/outbox.d.ts +25 -0
- package/dist/features/codex-notifier/outbox.d.ts.map +1 -0
- package/dist/features/codex-notifier/outbox.js +225 -0
- package/dist/features/codex-notifier/outbox.js.map +1 -0
- package/dist/features/codex-notifier/paths.d.ts +7 -0
- package/dist/features/codex-notifier/paths.d.ts.map +1 -0
- package/dist/features/codex-notifier/paths.js +20 -0
- package/dist/features/codex-notifier/paths.js.map +1 -0
- package/dist/features/codex-notifier/screen-lock.d.ts +12 -0
- package/dist/features/codex-notifier/screen-lock.d.ts.map +1 -0
- package/dist/features/codex-notifier/screen-lock.js +47 -0
- package/dist/features/codex-notifier/screen-lock.js.map +1 -0
- package/dist/features/codex-notifier/side-conversation-monitor.d.ts +102 -0
- package/dist/features/codex-notifier/side-conversation-monitor.d.ts.map +1 -0
- package/dist/features/codex-notifier/side-conversation-monitor.js +774 -0
- package/dist/features/codex-notifier/side-conversation-monitor.js.map +1 -0
- package/dist/features/codex-notifier/types.d.ts +42 -0
- package/dist/features/codex-notifier/types.d.ts.map +1 -0
- package/dist/features/codex-notifier/types.js +2 -0
- package/dist/features/codex-notifier/types.js.map +1 -0
- package/dist/features/codex-notifier/worker-lock.d.ts +8 -0
- package/dist/features/codex-notifier/worker-lock.d.ts.map +1 -0
- package/dist/features/codex-notifier/worker-lock.js +108 -0
- package/dist/features/codex-notifier/worker-lock.js.map +1 -0
- package/dist/global-config.d.ts +13 -0
- package/dist/global-config.d.ts.map +1 -1
- package/dist/global-config.js +30 -0
- package/dist/global-config.js.map +1 -1
- package/dist/im/lark/card-builder.js +2 -2
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts +2 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +165 -34
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +62 -4
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +237 -29
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +20 -30
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/platform/secure-host-file.d.ts.map +1 -1
- package/dist/platform/secure-host-file.js +173 -54
- package/dist/platform/secure-host-file.js.map +1 -1
- package/dist/services/codex-app-threads.d.ts +47 -0
- package/dist/services/codex-app-threads.d.ts.map +1 -1
- package/dist/services/codex-app-threads.js +502 -10
- package/dist/services/codex-app-threads.js.map +1 -1
- package/dist/services/exact-chat-grant.d.ts +83 -0
- package/dist/services/exact-chat-grant.d.ts.map +1 -0
- package/dist/services/exact-chat-grant.js +249 -0
- package/dist/services/exact-chat-grant.js.map +1 -0
- package/dist/services/group-creator.d.ts +11 -0
- package/dist/services/group-creator.d.ts.map +1 -1
- package/dist/services/group-creator.js +18 -9
- package/dist/services/group-creator.js.map +1 -1
- package/dist/services/local-cli-opener.d.ts.map +1 -1
- package/dist/services/local-cli-opener.js +10 -5
- package/dist/services/local-cli-opener.js.map +1 -1
- package/dist/services/traex-user-input.d.ts +19 -0
- package/dist/services/traex-user-input.d.ts.map +1 -0
- package/dist/services/traex-user-input.js +57 -0
- package/dist/services/traex-user-input.js.map +1 -0
- package/dist/setup/open-platform-automation.d.ts +24 -3
- package/dist/setup/open-platform-automation.d.ts.map +1 -1
- package/dist/setup/open-platform-automation.js +45 -8
- package/dist/setup/open-platform-automation.js.map +1 -1
- package/dist/setup/verify-permissions.d.ts +18 -0
- package/dist/setup/verify-permissions.d.ts.map +1 -1
- package/dist/setup/verify-permissions.js +60 -0
- package/dist/setup/verify-permissions.js.map +1 -1
- package/dist/types.d.ts +70 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/child-env.d.ts +1 -1
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +2 -0
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/pending-input-queue.d.ts +19 -0
- package/dist/utils/pending-input-queue.d.ts.map +1 -1
- package/dist/utils/pending-input-queue.js +21 -1
- package/dist/utils/pending-input-queue.js.map +1 -1
- package/dist/utils/stuck-detector.d.ts +45 -0
- package/dist/utils/stuck-detector.d.ts.map +1 -0
- package/dist/utils/stuck-detector.js +188 -0
- package/dist/utils/stuck-detector.js.map +1 -0
- package/dist/utils/stuck-key-guard.d.ts +75 -0
- package/dist/utils/stuck-key-guard.d.ts.map +1 -0
- package/dist/utils/stuck-key-guard.js +77 -0
- package/dist/utils/stuck-key-guard.js.map +1 -0
- package/dist/worker.js +807 -117
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-B5AY4B2J.js +0 -5
- package/dist/dashboard-web/chunks/sessions-page-2VECQ27T.js +0 -3
- package/dist/dashboard-web/chunks/settings-page-HMIUE2JA.js +0 -2
package/dist/dashboard.js
CHANGED
|
@@ -11,8 +11,9 @@ import { logger } from './utils/logger.js';
|
|
|
11
11
|
import { config } from './config.js';
|
|
12
12
|
import { listenWithProbe } from './utils/listen-with-probe.js';
|
|
13
13
|
import { generateToken, parseCookie, buildSetCookie, verifyHmac, cliAuthBind, decideDashboardAuth, loadPersistedToken, persistToken, loadDashboardSecret, loadOrCreateDashboardSecret, } from './dashboard/auth.js';
|
|
14
|
-
import { DaemonRegistry } from './dashboard/registry.js';
|
|
14
|
+
import { DaemonRegistry, botsRosterSignature } from './dashboard/registry.js';
|
|
15
15
|
import { Aggregator, subscribeDaemon } from './dashboard/aggregator.js';
|
|
16
|
+
import { createDebugTerminalManager } from './dashboard/debug-terminal.js';
|
|
16
17
|
import { pickCreatorForGroup } from './dashboard/operator-selector.js';
|
|
17
18
|
import { buildTeamGroupCreatePayload, planGroupCreator } from './dashboard/team-group.js';
|
|
18
19
|
import { jsonRes } from './dashboard/http.js';
|
|
@@ -21,7 +22,7 @@ import { defaultRunsDir as v3RunsDir } from './workflows/v3/ops-projection.js';
|
|
|
21
22
|
import { verifyWorkflowDaemonIpcResponse, workflowDaemonIpcHeaders, WORKFLOW_DAEMON_IPC_ROUTE_PREFIX, } from './workflows/v3/daemon-ipc-auth.js';
|
|
22
23
|
import { handleDashboardTriggerApi } from './dashboard/trigger-api.js';
|
|
23
24
|
import { handleConnectorApi } from './dashboard/connector-api.js';
|
|
24
|
-
import { redactGroupsForPublic, redactSchedulesForPublic } from './dashboard/public-redact.js';
|
|
25
|
+
import { redactGroupsForPublic, redactSchedulesForPublic, redactSettingsForPublic, } from './dashboard/public-redact.js';
|
|
25
26
|
import { handleWebhookRoute } from './dashboard/webhook-routes.js';
|
|
26
27
|
import { handleFederationApi } from './dashboard/federation-api.js';
|
|
27
28
|
import { handleFederationSpokeApi, syncAllMemberships, autoBindOwnerIfUnambiguous } from './dashboard/federation-spoke-api.js';
|
|
@@ -46,7 +47,7 @@ import { listCliRuntimeUpdateEntries } from './core/cli-runtime-update.js';
|
|
|
46
47
|
import { claimRestartLease, clearRestartIntent, clearRestartLease, hasActiveRestartLease, writeManualIntentIfAbsent, writeRestartIntent, } from './services/restart-intent-store.js';
|
|
47
48
|
import { withFileLock } from './utils/file-lock.js';
|
|
48
49
|
import { spawn } from 'node:child_process';
|
|
49
|
-
import { applySettingsWrite, defaultSettingsWriteApplierDeps, } from './dashboard/settings-write-applier.js';
|
|
50
|
+
import { applySettingsWrite, defaultSettingsWriteApplierDeps, hasResolvedCodexNotifierRecipient, resolveCodexNotifierRecipientView, } from './dashboard/settings-write-applier.js';
|
|
50
51
|
import { addBotsToGroup, bindOncall, disbandGroup, leaveGroup, unbindOncall, } from './dashboard/groups-action-helpers.js';
|
|
51
52
|
import { createDaemonInternalApi } from './dashboard/daemon-internal-api.js';
|
|
52
53
|
import { listTeamReports, readTeamBoard, setTeamBoardEntry } from './services/team-board-store.js';
|
|
@@ -56,6 +57,7 @@ import { buildSkillInstallAuditSummary, installLocalSkillLinks, readSkillRegistr
|
|
|
56
57
|
import { redactGitUrlCredentials } from './core/skills/sources.js';
|
|
57
58
|
import { effectiveDefaultWorkingDir, getBot, loadBotConfigs, parseBotConfigsFromText } from './bot-registry.js';
|
|
58
59
|
import { findEntryIndex, readRawConfig, requireConfigPath, writeRawConfigAtomic } from './services/config-store.js';
|
|
60
|
+
import { emitCodexNotifierOutboxItem, installCodexNotifierHook, isCodexNotifierWorkerStateFresh, isCodexNotifierHookInstalled, listCodexNotifierOutbox, readCodexNotifierWorkerState, resolveCodexNotifierConfig, runCodexSideConversationMonitor, runCodexNotifierWorkerSupervisor, } from './features/codex-notifier/index.js';
|
|
59
61
|
import { discoverNativeCliSkillGroups } from './core/skills/discovery.js';
|
|
60
62
|
import { analyzeSkillReferences } from './core/skills/references.js';
|
|
61
63
|
import { discoverDashboardSkills, installDashboardSkill, parseDashboardSkillInstallRequest, parseInstallLocalLinksSources, MAX_LOCAL_LINK_SOURCES } from './dashboard/skill-install-request.js';
|
|
@@ -189,6 +191,20 @@ function verifyDashboardBinding(port) {
|
|
|
189
191
|
mkdirSync(REGISTRY_DIR, { recursive: true });
|
|
190
192
|
const registry = new DaemonRegistry(REGISTRY_DIR);
|
|
191
193
|
const aggregator = new Aggregator();
|
|
194
|
+
// 调试终端(owner-only 裸 bash)。默认工作目录取当前所有 session 的工作目录去重,
|
|
195
|
+
// 让 owner 从熟悉的目录起终端复现问题;都没有时模块内退回 homedir。
|
|
196
|
+
const debugTerminalManager = createDebugTerminalManager({
|
|
197
|
+
getActiveToken: () => activeToken,
|
|
198
|
+
defaultWorkingDirs: () => {
|
|
199
|
+
const dirs = new Set();
|
|
200
|
+
for (const s of aggregator.getSessions()) {
|
|
201
|
+
const wd = s.workingDir;
|
|
202
|
+
if (typeof wd === 'string' && wd.trim())
|
|
203
|
+
dirs.add(wd.trim());
|
|
204
|
+
}
|
|
205
|
+
return [...dirs];
|
|
206
|
+
},
|
|
207
|
+
});
|
|
192
208
|
/**
|
|
193
209
|
* Resolve which daemon owns a schedule row. For rows with an explicit
|
|
194
210
|
* `larkAppId`, returns that. For legacy rows (no owner stamp), falls back to
|
|
@@ -269,8 +285,58 @@ function spawnStartBotLive(appId) {
|
|
|
269
285
|
}
|
|
270
286
|
});
|
|
271
287
|
}
|
|
288
|
+
function spawnStopBotLive(appId) {
|
|
289
|
+
return new Promise((resolve) => {
|
|
290
|
+
let out = '';
|
|
291
|
+
let err = '';
|
|
292
|
+
let settled = false;
|
|
293
|
+
const done = (r) => { if (!settled) {
|
|
294
|
+
settled = true;
|
|
295
|
+
resolve(r);
|
|
296
|
+
} };
|
|
297
|
+
try {
|
|
298
|
+
const child = spawn(process.execPath, [botmuxCliEntry(), 'stop-bot', appId, '--json'], {
|
|
299
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
300
|
+
env: process.env,
|
|
301
|
+
cwd: globalInstallUpdateCwd(),
|
|
302
|
+
});
|
|
303
|
+
const timer = setTimeout(() => {
|
|
304
|
+
try {
|
|
305
|
+
child.kill('SIGKILL');
|
|
306
|
+
}
|
|
307
|
+
catch { /* already gone */ }
|
|
308
|
+
done({ ok: false, message: 'stop-bot 超时(30s)' });
|
|
309
|
+
}, 30_000);
|
|
310
|
+
timer.unref?.();
|
|
311
|
+
child.stdout?.on('data', (d) => { out += String(d); });
|
|
312
|
+
child.stderr?.on('data', (d) => { err += String(d); });
|
|
313
|
+
child.on('error', (e) => {
|
|
314
|
+
clearTimeout(timer);
|
|
315
|
+
done({ ok: false, message: e instanceof Error ? e.message : String(e) });
|
|
316
|
+
});
|
|
317
|
+
child.on('exit', (code) => {
|
|
318
|
+
clearTimeout(timer);
|
|
319
|
+
let parsed;
|
|
320
|
+
try {
|
|
321
|
+
parsed = JSON.parse(out.trim());
|
|
322
|
+
}
|
|
323
|
+
catch { /* non-JSON */ }
|
|
324
|
+
if (code === 0) {
|
|
325
|
+
done({ ok: true, message: parsed?.processName ? `${parsed.processName} 已停止` : undefined });
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
done({ ok: false, message: parsed?.message || err.trim() || `stop-bot 退出码 ${code}` });
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
catch (e) {
|
|
333
|
+
done({ ok: false, message: e instanceof Error ? e.message : String(e) });
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
}
|
|
272
337
|
const botOnboarding = new BotOnboardingManager({
|
|
273
338
|
botsJsonPath: BOTS_JSON_PATH,
|
|
339
|
+
stopBotLive: spawnStopBotLive,
|
|
274
340
|
startBotLive: spawnStartBotLive,
|
|
275
341
|
});
|
|
276
342
|
// 飞书 Web 登录态刷新(机器人改名缺登录态时的 dashboard 扫码入口)。机器级单例,
|
|
@@ -306,6 +372,51 @@ async function validateVcMeetingListenerBotAppId(appId) {
|
|
|
306
372
|
return { ok: false, error: 'vcMeetingAgent_listenerBot_unknown' };
|
|
307
373
|
return { ok: true };
|
|
308
374
|
}
|
|
375
|
+
async function validateCodexNotifierTargetBotAppId(appId, options = {}) {
|
|
376
|
+
try {
|
|
377
|
+
const bot = loadBotConfigs().find(candidate => candidate.larkAppId === appId);
|
|
378
|
+
if (!bot)
|
|
379
|
+
return { ok: false, error: 'codexNotifier_target_unknown' };
|
|
380
|
+
if (bot.cliId !== 'codex' && bot.cliId !== 'codex-app') {
|
|
381
|
+
return { ok: false, error: 'codexNotifier_target_cli_unsupported' };
|
|
382
|
+
}
|
|
383
|
+
if (!(bot.allowedUsers ?? []).some(user => typeof user === 'string' && user.trim())) {
|
|
384
|
+
return { ok: false, error: 'codexNotifier_target_owner_missing' };
|
|
385
|
+
}
|
|
386
|
+
if (options.requireReady !== true)
|
|
387
|
+
return { ok: true };
|
|
388
|
+
const daemon = registry.list().find(candidate => candidate.larkAppId === appId);
|
|
389
|
+
if (!daemon)
|
|
390
|
+
return { ok: false, error: 'codexNotifier_target_daemon_offline' };
|
|
391
|
+
const resolvedOwners = daemon.resolvedAllowedUsers ?? [];
|
|
392
|
+
if (!hasResolvedCodexNotifierRecipient(resolvedOwners)) {
|
|
393
|
+
return { ok: false, error: 'codexNotifier_target_owner_unverified' };
|
|
394
|
+
}
|
|
395
|
+
return { ok: true };
|
|
396
|
+
}
|
|
397
|
+
catch {
|
|
398
|
+
return { ok: false, error: 'codexNotifier_target_unknown' };
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
function codexNotifierBotOptions() {
|
|
402
|
+
try {
|
|
403
|
+
const onlineByAppId = new Map(registry.list().map(bot => [bot.larkAppId, bot]));
|
|
404
|
+
return loadBotConfigs()
|
|
405
|
+
.filter(bot => bot.cliId === 'codex' || bot.cliId === 'codex-app')
|
|
406
|
+
.map(bot => {
|
|
407
|
+
const resolvedOwners = onlineByAppId.get(bot.larkAppId)?.resolvedAllowedUsers ?? [];
|
|
408
|
+
return {
|
|
409
|
+
larkAppId: bot.larkAppId,
|
|
410
|
+
botName: bot.displayName ?? onlineByAppId.get(bot.larkAppId)?.botName ?? bot.name ?? null,
|
|
411
|
+
cliId: onlineByAppId.get(bot.larkAppId)?.cliId ?? bot.cliId,
|
|
412
|
+
...resolveCodexNotifierRecipientView(bot.allowedUsers, resolvedOwners),
|
|
413
|
+
};
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
return [];
|
|
418
|
+
}
|
|
419
|
+
}
|
|
309
420
|
function normalizeVcMeetingAgentRecord(raw) {
|
|
310
421
|
return raw && typeof raw === 'object' && !Array.isArray(raw)
|
|
311
422
|
? { ...raw }
|
|
@@ -664,6 +775,9 @@ async function syncVcMeetingListenerBotConfig(listenerBotAppId, previousListener
|
|
|
664
775
|
function resolveDashboardSettings() {
|
|
665
776
|
const global = readGlobalConfig();
|
|
666
777
|
const dashboard = global.dashboard ?? {};
|
|
778
|
+
const codexNotifier = resolveCodexNotifierConfig();
|
|
779
|
+
const codexNotifierBots = codexNotifierBotOptions();
|
|
780
|
+
const codexNotifierState = readCodexNotifierWorkerState(config.session.dataDir);
|
|
667
781
|
const larkCli = checkLarkCliVersion();
|
|
668
782
|
return {
|
|
669
783
|
publicReadOnly: dashboard.publicReadOnly ?? config.dashboard.publicReadOnly,
|
|
@@ -679,6 +793,19 @@ function resolveDashboardSettings() {
|
|
|
679
793
|
recommendedRef: TRAEX_RECOMMENDED_REF,
|
|
680
794
|
},
|
|
681
795
|
codexRpcInput: dashboard.codexRpcInput === true, // default OFF until live-verified
|
|
796
|
+
codexNotifier: {
|
|
797
|
+
enabled: codexNotifier.enabled,
|
|
798
|
+
targetBotAppId: codexNotifier.targetBotAppId ?? null,
|
|
799
|
+
notifyWhen: codexNotifier.notifyWhen,
|
|
800
|
+
platformSupported: process.platform === 'darwin',
|
|
801
|
+
hookInstalled: isCodexNotifierHookInstalled(),
|
|
802
|
+
botOptions: codexNotifierBots,
|
|
803
|
+
targetDaemonOnline: !!codexNotifier.targetBotAppId
|
|
804
|
+
&& registry.list().some(bot => bot.larkAppId === codexNotifier.targetBotAppId),
|
|
805
|
+
pendingCount: listCodexNotifierOutbox(config.session.dataDir).length,
|
|
806
|
+
workerOnline: isCodexNotifierWorkerStateFresh(codexNotifierState),
|
|
807
|
+
lastError: codexNotifierState?.lastError ?? null,
|
|
808
|
+
},
|
|
682
809
|
vcMeetingAgent: {
|
|
683
810
|
enabled: global.vcMeetingAgent?.enabled !== false,
|
|
684
811
|
listenerBotAppId: global.vcMeetingAgent?.listenerBotAppId ?? null,
|
|
@@ -707,6 +834,7 @@ async function reloadLocaleOnAllDaemons() {
|
|
|
707
834
|
const settingsWriteApplierDeps = defaultSettingsWriteApplierDeps(resolveDashboardSettings, reloadLocaleOnAllDaemons);
|
|
708
835
|
settingsWriteApplierDeps.syncVcMeetingListenerBotConfig = syncVcMeetingListenerBotConfig;
|
|
709
836
|
settingsWriteApplierDeps.validateVcMeetingListenerBotAppId = validateVcMeetingListenerBotAppId;
|
|
837
|
+
settingsWriteApplierDeps.validateCodexNotifierTargetBotAppId = validateCodexNotifierTargetBotAppId;
|
|
710
838
|
/** Helper to render a {status, body} HandlerResult through `res`. */
|
|
711
839
|
function writeHandlerResult(res, result) {
|
|
712
840
|
const headers = { 'content-type': 'application/json', ...(result.headers ?? {}) };
|
|
@@ -940,6 +1068,29 @@ registry.on(syncSubscriptions);
|
|
|
940
1068
|
// Initial attach for every daemon already known. Run in parallel so a slow
|
|
941
1069
|
// daemon doesn't block the others.
|
|
942
1070
|
await Promise.all(registry.list().map(attachDaemon));
|
|
1071
|
+
const codexNotifierAbort = new AbortController();
|
|
1072
|
+
if (resolveCodexNotifierConfig().enabled) {
|
|
1073
|
+
try {
|
|
1074
|
+
installCodexNotifierHook();
|
|
1075
|
+
}
|
|
1076
|
+
catch (error) {
|
|
1077
|
+
logger.warn(`[codex-notifier] Hook reconcile failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
void runCodexNotifierWorkerSupervisor({
|
|
1081
|
+
dataDir: config.session.dataDir,
|
|
1082
|
+
signal: codexNotifierAbort.signal,
|
|
1083
|
+
emit: item => emitCodexNotifierOutboxItem(item, { signal: codexNotifierAbort.signal }),
|
|
1084
|
+
runProducer: signal => runCodexSideConversationMonitor({
|
|
1085
|
+
dataDir: config.session.dataDir,
|
|
1086
|
+
signal,
|
|
1087
|
+
logger,
|
|
1088
|
+
}),
|
|
1089
|
+
logger,
|
|
1090
|
+
onLeaseUnavailable: path => {
|
|
1091
|
+
logger.warn(`[codex-notifier] outbox worker 已由另一 Dashboard 持有,等待接管:${path}`);
|
|
1092
|
+
},
|
|
1093
|
+
});
|
|
943
1094
|
const resourceMonitor = createResourceMonitorService({
|
|
944
1095
|
intervalMs: 10_000,
|
|
945
1096
|
topSessionLimit: 30,
|
|
@@ -2104,14 +2255,15 @@ const server = createServer(async (req, res) => {
|
|
|
2104
2255
|
return jsonRes(res, 200, { ok: true });
|
|
2105
2256
|
}
|
|
2106
2257
|
const presentedToken = authedToken(req, url);
|
|
2107
|
-
const
|
|
2258
|
+
const globalDashboardConfig = readGlobalConfig().dashboard;
|
|
2108
2259
|
const decision = decideDashboardAuth({
|
|
2109
2260
|
method: req.method ?? 'GET',
|
|
2110
2261
|
pathname: url.pathname,
|
|
2111
2262
|
hasTokenParam: url.searchParams.has('t'),
|
|
2112
2263
|
presentedToken,
|
|
2113
2264
|
activeToken: activeToken ?? '',
|
|
2114
|
-
publicReadOnly:
|
|
2265
|
+
publicReadOnly: globalDashboardConfig?.publicReadOnly
|
|
2266
|
+
?? config.dashboard.publicReadOnly,
|
|
2115
2267
|
});
|
|
2116
2268
|
// `authed` is consumed by route handlers that distinguish the public-read
|
|
2117
2269
|
// carve-out from a valid management cookie (notably v3 run details).
|
|
@@ -2160,6 +2312,16 @@ const server = createServer(async (req, res) => {
|
|
|
2160
2312
|
&& await handlePluginManagementApi(req, res, url)) {
|
|
2161
2313
|
return;
|
|
2162
2314
|
}
|
|
2315
|
+
// 调试终端(owner-only):HTTP 路由挂在 auth gate 之后 → 已确保是管理 token。
|
|
2316
|
+
// /api/debug-terminal(创建/关闭)+ /debug-terminal/<id>(xterm 页面)。
|
|
2317
|
+
// WS 升级 /debug-terminal/<id>/ws 在下方 server.on('upgrade') 里由本 manager
|
|
2318
|
+
// 自行校验 cookie(upgrade 不经这段 gate)。
|
|
2319
|
+
if (url.pathname === '/api/debug-terminal'
|
|
2320
|
+
|| url.pathname.startsWith('/api/debug-terminal/')
|
|
2321
|
+
|| url.pathname.startsWith('/debug-terminal/')) {
|
|
2322
|
+
if (debugTerminalManager.handleHttp(req, res, url))
|
|
2323
|
+
return;
|
|
2324
|
+
}
|
|
2163
2325
|
if (req.method === 'GET' && url.pathname === '/api/plugins/dashboard') {
|
|
2164
2326
|
return jsonRes(res, 200, { plugins: listDashboardPluginEntries() });
|
|
2165
2327
|
}
|
|
@@ -2326,6 +2488,7 @@ const server = createServer(async (req, res) => {
|
|
|
2326
2488
|
return jsonRes(res, 200, { schedules, timezone: scheduleTimeZone() });
|
|
2327
2489
|
}
|
|
2328
2490
|
if (req.method === 'GET' && url.pathname === '/api/settings') {
|
|
2491
|
+
const dashboardSettings = resolveDashboardSettings();
|
|
2329
2492
|
// `authed` lets the Settings page disable toggles for read-only
|
|
2330
2493
|
// visitors up front, instead of letting them flip a switch that
|
|
2331
2494
|
// 401s + rolls back on save.
|
|
@@ -2335,7 +2498,7 @@ const server = createServer(async (req, res) => {
|
|
|
2335
2498
|
// `bound` reflects central-platform binding; the Settings UI only shows the
|
|
2336
2499
|
// 远程访问 toggle when bound (the central URLs are meaningless otherwise).
|
|
2337
2500
|
return jsonRes(res, 200, {
|
|
2338
|
-
settings: dashboardSettings,
|
|
2501
|
+
settings: authed ? dashboardSettings : redactSettingsForPublic(dashboardSettings),
|
|
2339
2502
|
lang: readGlobalConfig().lang ?? null,
|
|
2340
2503
|
authed,
|
|
2341
2504
|
bound: readPlatformBinding() !== null,
|
|
@@ -3053,6 +3216,14 @@ const server = createServer(async (req, res) => {
|
|
|
3053
3216
|
return jsonRes(res, 400, { ok: false, error: 'missing_expected_identity', message: '免扫码添加前必须确认当前账号与企业' });
|
|
3054
3217
|
}
|
|
3055
3218
|
const sessionMode = sessionModeRaw === 'reuse' ? 'reuse' : 'qr';
|
|
3219
|
+
if (parsed.requireCriticalScopesBeforeActivation !== undefined
|
|
3220
|
+
&& typeof parsed.requireCriticalScopesBeforeActivation !== 'boolean') {
|
|
3221
|
+
return jsonRes(res, 400, {
|
|
3222
|
+
ok: false,
|
|
3223
|
+
error: 'invalid_critical_scope_activation_gate',
|
|
3224
|
+
message: 'requireCriticalScopesBeforeActivation 必须是 boolean',
|
|
3225
|
+
});
|
|
3226
|
+
}
|
|
3056
3227
|
const job = botOnboarding.start({
|
|
3057
3228
|
appName,
|
|
3058
3229
|
registrationMode,
|
|
@@ -3062,9 +3233,93 @@ const server = createServer(async (req, res) => {
|
|
|
3062
3233
|
workingDir,
|
|
3063
3234
|
dirMode,
|
|
3064
3235
|
model,
|
|
3236
|
+
...(parsed.requireCriticalScopesBeforeActivation === true
|
|
3237
|
+
? { requireCriticalScopesBeforeActivation: true }
|
|
3238
|
+
: {}),
|
|
3065
3239
|
});
|
|
3066
3240
|
return jsonRes(res, 202, { job: botOnboarding.get(job.id) });
|
|
3067
3241
|
}
|
|
3242
|
+
if (req.method === 'POST' && url.pathname === '/api/bot-onboarding/recover-permissions') {
|
|
3243
|
+
let parsed;
|
|
3244
|
+
try {
|
|
3245
|
+
const chunks = [];
|
|
3246
|
+
for await (const c of req)
|
|
3247
|
+
chunks.push(c);
|
|
3248
|
+
const raw = Buffer.concat(chunks).toString('utf8');
|
|
3249
|
+
parsed = raw ? JSON.parse(raw) : {};
|
|
3250
|
+
}
|
|
3251
|
+
catch {
|
|
3252
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3253
|
+
}
|
|
3254
|
+
const workingDir = typeof parsed.workingDir === 'string' ? parsed.workingDir.trim() : '';
|
|
3255
|
+
const predecessorJobId = typeof parsed.predecessorJobId === 'string' ? parsed.predecessorJobId.trim() : '';
|
|
3256
|
+
const expectedAppId = typeof parsed.expectedAppId === 'string' ? parsed.expectedAppId.trim() : '';
|
|
3257
|
+
const priorRecoveryJobId = typeof parsed.priorRecoveryJobId === 'string' ? parsed.priorRecoveryJobId.trim() : undefined;
|
|
3258
|
+
if (parsed.requireCriticalScopesBeforeActivation !== undefined
|
|
3259
|
+
&& typeof parsed.requireCriticalScopesBeforeActivation !== 'boolean') {
|
|
3260
|
+
return jsonRes(res, 400, {
|
|
3261
|
+
ok: false,
|
|
3262
|
+
error: 'invalid_critical_scope_activation_gate',
|
|
3263
|
+
message: 'requireCriticalScopesBeforeActivation 必须是 boolean',
|
|
3264
|
+
});
|
|
3265
|
+
}
|
|
3266
|
+
if (!workingDir || !predecessorJobId || !expectedAppId || invalidWorkingDirs({ workingDir }).length > 0) {
|
|
3267
|
+
return jsonRes(res, 400, { ok: false, error: 'permission_recovery_target_invalid' });
|
|
3268
|
+
}
|
|
3269
|
+
const recovered = botOnboarding.startPermissionRecovery({
|
|
3270
|
+
workingDir,
|
|
3271
|
+
predecessorJobId,
|
|
3272
|
+
expectedAppId,
|
|
3273
|
+
priorRecoveryJobId,
|
|
3274
|
+
...(parsed.requireCriticalScopesBeforeActivation === true
|
|
3275
|
+
? { requireCriticalScopesBeforeActivation: true }
|
|
3276
|
+
: {}),
|
|
3277
|
+
});
|
|
3278
|
+
if (!recovered.ok) {
|
|
3279
|
+
const status = recovered.error === 'permission_recovery_target_missing' ? 404
|
|
3280
|
+
: recovered.error === 'permission_recovery_target_ambiguous' ? 409
|
|
3281
|
+
: recovered.error === 'permission_recovery_state_unavailable' ? 503
|
|
3282
|
+
: 400;
|
|
3283
|
+
return jsonRes(res, status, recovered);
|
|
3284
|
+
}
|
|
3285
|
+
return jsonRes(res, 202, { job: botOnboarding.get(recovered.job.id) });
|
|
3286
|
+
}
|
|
3287
|
+
let mScopePropagation;
|
|
3288
|
+
if (req.method === 'POST'
|
|
3289
|
+
&& (mScopePropagation = url.pathname.match(/^\/api\/bot-onboarding\/([^/]+)\/complete-scope-propagation$/))) {
|
|
3290
|
+
const onboardingId = decodeURIComponent(mScopePropagation[1]);
|
|
3291
|
+
let parsed;
|
|
3292
|
+
try {
|
|
3293
|
+
const chunks = [];
|
|
3294
|
+
for await (const c of req)
|
|
3295
|
+
chunks.push(c);
|
|
3296
|
+
const raw = Buffer.concat(chunks).toString('utf8');
|
|
3297
|
+
parsed = raw ? JSON.parse(raw) : {};
|
|
3298
|
+
}
|
|
3299
|
+
catch {
|
|
3300
|
+
return jsonRes(res, 400, { ok: false, error: 'bad_json' });
|
|
3301
|
+
}
|
|
3302
|
+
const workingDir = typeof parsed.workingDir === 'string' ? parsed.workingDir.trim() : '';
|
|
3303
|
+
const expectedAppId = typeof parsed.expectedAppId === 'string' ? parsed.expectedAppId.trim() : '';
|
|
3304
|
+
if (!workingDir || !expectedAppId || invalidWorkingDirs({ workingDir }).length > 0) {
|
|
3305
|
+
return jsonRes(res, 400, { ok: false, error: 'permission_recovery_target_invalid' });
|
|
3306
|
+
}
|
|
3307
|
+
const completed = await botOnboarding.completeScopePropagation({
|
|
3308
|
+
jobId: onboardingId,
|
|
3309
|
+
workingDir,
|
|
3310
|
+
expectedAppId,
|
|
3311
|
+
});
|
|
3312
|
+
if (!completed.ok) {
|
|
3313
|
+
const status = completed.error === 'permission_recovery_target_missing' ? 404
|
|
3314
|
+
: completed.error === 'permission_recovery_target_ambiguous' ? 409
|
|
3315
|
+
: completed.error === 'permission_recovery_scopes_pending' ? 425
|
|
3316
|
+
: (completed.error === 'permission_recovery_state_unavailable'
|
|
3317
|
+
|| completed.error === 'permission_recovery_activation_failed') ? 503
|
|
3318
|
+
: 400;
|
|
3319
|
+
return jsonRes(res, status, completed);
|
|
3320
|
+
}
|
|
3321
|
+
return jsonRes(res, 200, { job: botOnboarding.get(onboardingId) });
|
|
3322
|
+
}
|
|
3068
3323
|
let mOwner;
|
|
3069
3324
|
if (req.method === 'POST' && (mOwner = url.pathname.match(/^\/api\/bot-onboarding\/([^/]+)\/owner$/))) {
|
|
3070
3325
|
// needs_owner 状态下用户手动提交 owner:扫码人身份验证不了时的兜底入口。
|
|
@@ -3219,6 +3474,18 @@ const server = createServer(async (req, res) => {
|
|
|
3219
3474
|
res.end(await upstream.text());
|
|
3220
3475
|
return;
|
|
3221
3476
|
}
|
|
3477
|
+
// Dashboard「复现命令」:透传到 owning daemon 取该 session 的真实 CLI 调用。
|
|
3478
|
+
// 与 write-link 同样只在管理 cookie(写权限)下可达:命令含 token/凭证。
|
|
3479
|
+
if (req.method === 'GET' && (m = url.pathname.match(/^\/api\/sessions\/([^/]+)\/spawn-command$/))) {
|
|
3480
|
+
const sid = decodeURIComponent(m[1]);
|
|
3481
|
+
const owner = aggregator.ownerOf(sid);
|
|
3482
|
+
if (!owner)
|
|
3483
|
+
return jsonRes(res, 404, { ok: false, error: 'unknown_session' });
|
|
3484
|
+
const upstream = await proxyToDaemon(owner, `/api/sessions/${sid}/spawn-command`, { method: 'GET' });
|
|
3485
|
+
res.writeHead(upstream.status, { 'content-type': 'application/json' });
|
|
3486
|
+
res.end(await upstream.text());
|
|
3487
|
+
return;
|
|
3488
|
+
}
|
|
3222
3489
|
// Sandbox landing: review the clone's diff (GET) then apply/discard (POST).
|
|
3223
3490
|
if (req.method === 'GET' && (m = url.pathname.match(/^\/api\/sessions\/([^/]+)\/sandbox-diff$/))) {
|
|
3224
3491
|
const sid = decodeURIComponent(m[1]);
|
|
@@ -4325,7 +4592,20 @@ const server = createServer(async (req, res) => {
|
|
|
4325
4592
|
const hb = setInterval(() => {
|
|
4326
4593
|
res.write(`event: heartbeat\ndata: ${JSON.stringify({ ts: Date.now() })}\n\n`);
|
|
4327
4594
|
}, 15_000);
|
|
4328
|
-
|
|
4595
|
+
// Push a bots.changed frame whenever the online bot roster actually
|
|
4596
|
+
// changes (bot added / removed / renamed / re-indexed) so the Bot 配置
|
|
4597
|
+
// page can auto-refresh without a manual reload. registry.on fires on
|
|
4598
|
+
// every 15s poll and 30s heartbeat rewrite, so gate on a roster signature
|
|
4599
|
+
// that ignores lastHeartbeat — otherwise we'd spam a frame every poll.
|
|
4600
|
+
let lastRoster = botsRosterSignature(registry.list());
|
|
4601
|
+
const offRoster = registry.on(online => {
|
|
4602
|
+
const sig = botsRosterSignature(online);
|
|
4603
|
+
if (sig === lastRoster)
|
|
4604
|
+
return;
|
|
4605
|
+
lastRoster = sig;
|
|
4606
|
+
res.write(`event: bots.changed\ndata: ${JSON.stringify({ body: { signature: sig } })}\n\n`);
|
|
4607
|
+
});
|
|
4608
|
+
res.on('close', () => { off(); offRoster(); clearInterval(hb); });
|
|
4329
4609
|
return;
|
|
4330
4610
|
}
|
|
4331
4611
|
// Public API + static frontend land in Task 17 / 18. For now: 404.
|
|
@@ -4346,6 +4626,11 @@ const server = createServer(async (req, res) => {
|
|
|
4346
4626
|
server.on('upgrade', (req, clientSocket, head) => {
|
|
4347
4627
|
try {
|
|
4348
4628
|
const rawUrl = req.url ?? '/';
|
|
4629
|
+
// 调试终端 WS(owner-only):manager 内部自校验管理 cookie。命中即接管。
|
|
4630
|
+
if (rawUrl.startsWith('/debug-terminal/')) {
|
|
4631
|
+
if (debugTerminalManager.handleUpgrade(req, clientSocket, head))
|
|
4632
|
+
return;
|
|
4633
|
+
}
|
|
4349
4634
|
if (!(rawUrl === '/s' || rawUrl.startsWith('/s/') || rawUrl.startsWith('/s?'))) {
|
|
4350
4635
|
return clientSocket.destroy();
|
|
4351
4636
|
}
|
|
@@ -4671,12 +4956,14 @@ async function maybeAnnounceHallPresence() {
|
|
|
4671
4956
|
}
|
|
4672
4957
|
// Graceful shutdown
|
|
4673
4958
|
function shutdown() {
|
|
4959
|
+
codexNotifierAbort.abort();
|
|
4674
4960
|
for (const off of subs.values())
|
|
4675
4961
|
off();
|
|
4676
4962
|
subs.clear();
|
|
4677
4963
|
registry.stop();
|
|
4678
4964
|
resourceMonitor.stop();
|
|
4679
4965
|
platformTunnel?.stop();
|
|
4966
|
+
debugTerminalManager.shutdown();
|
|
4680
4967
|
server.close(() => process.exit(0));
|
|
4681
4968
|
// Hard-exit fallback after 5s
|
|
4682
4969
|
setTimeout(() => process.exit(0), 5_000).unref();
|