botmux 2.107.0 → 2.108.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 +17 -14
- package/README.md +19 -14
- package/dist/adapters/backend/sandbox.d.ts +3 -1
- package/dist/adapters/backend/sandbox.d.ts.map +1 -1
- package/dist/adapters/backend/sandbox.js +19 -3
- package/dist/adapters/backend/sandbox.js.map +1 -1
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +16 -1
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.d.ts +24 -15
- package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.js +75 -43
- package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
- package/dist/adapters/cli/genius.d.ts.map +1 -1
- package/dist/adapters/cli/genius.js +9 -15
- package/dist/adapters/cli/genius.js.map +1 -1
- package/dist/adapters/cli/grok.d.ts +73 -0
- package/dist/adapters/cli/grok.d.ts.map +1 -0
- package/dist/adapters/cli/grok.js +298 -0
- package/dist/adapters/cli/grok.js.map +1 -0
- package/dist/adapters/cli/oh-my-pi.d.ts.map +1 -1
- package/dist/adapters/cli/oh-my-pi.js +133 -12
- package/dist/adapters/cli/oh-my-pi.js.map +1 -1
- package/dist/adapters/cli/registry.d.ts +2 -1
- package/dist/adapters/cli/registry.d.ts.map +1 -1
- package/dist/adapters/cli/registry.js +3 -1
- package/dist/adapters/cli/registry.js.map +1 -1
- package/dist/adapters/cli/shared-hints.d.ts +8 -4
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +8 -4
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +18 -16
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/adapters/hook-installer.d.ts +5 -4
- package/dist/adapters/hook-installer.d.ts.map +1 -1
- package/dist/adapters/hook-installer.js +42 -0
- package/dist/adapters/hook-installer.js.map +1 -1
- package/dist/cli/send-dispatch.d.ts +21 -0
- package/dist/cli/send-dispatch.d.ts.map +1 -1
- package/dist/cli/send-dispatch.js +159 -0
- package/dist/cli/send-dispatch.js.map +1 -1
- package/dist/cli/session-list-liveness.d.ts +22 -0
- package/dist/cli/session-list-liveness.d.ts.map +1 -0
- package/dist/cli/session-list-liveness.js +22 -0
- package/dist/cli/session-list-liveness.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +182 -33
- package/dist/cli.js.map +1 -1
- package/dist/core/ask-types.d.ts +4 -0
- package/dist/core/ask-types.d.ts.map +1 -1
- package/dist/core/ask-types.js +10 -0
- package/dist/core/ask-types.js.map +1 -1
- package/dist/core/cost-calculator.d.ts.map +1 -1
- package/dist/core/cost-calculator.js +35 -13
- package/dist/core/cost-calculator.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +89 -16
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dashboard-rows.d.ts.map +1 -1
- package/dist/core/dashboard-rows.js +6 -2
- package/dist/core/dashboard-rows.js.map +1 -1
- package/dist/core/dashboard-url.d.ts +6 -5
- package/dist/core/dashboard-url.d.ts.map +1 -1
- package/dist/core/dashboard-url.js +11 -8
- package/dist/core/dashboard-url.js.map +1 -1
- package/dist/core/maintenance.d.ts +11 -8
- package/dist/core/maintenance.d.ts.map +1 -1
- package/dist/core/maintenance.js +45 -20
- package/dist/core/maintenance.js.map +1 -1
- package/dist/core/per-bot-env.d.ts.map +1 -1
- package/dist/core/per-bot-env.js +4 -0
- package/dist/core/per-bot-env.js.map +1 -1
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +4 -0
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/skills/cli-admin-command.d.ts.map +1 -1
- package/dist/core/skills/cli-admin-command.js +8 -2
- package/dist/core/skills/cli-admin-command.js.map +1 -1
- package/dist/core/skills/im-command.d.ts.map +1 -1
- package/dist/core/skills/im-command.js +3 -1
- package/dist/core/skills/im-command.js.map +1 -1
- package/dist/core/skills/sources.d.ts +33 -1
- package/dist/core/skills/sources.d.ts.map +1 -1
- package/dist/core/skills/sources.js +97 -0
- package/dist/core/skills/sources.js.map +1 -1
- package/dist/core/skills/types.d.ts +8 -0
- package/dist/core/skills/types.d.ts.map +1 -1
- package/dist/core/terminal-url.d.ts.map +1 -1
- package/dist/core/terminal-url.js +12 -2
- package/dist/core/terminal-url.js.map +1 -1
- package/dist/core/terminal-write-auth.d.ts +34 -0
- package/dist/core/terminal-write-auth.d.ts.map +1 -0
- package/dist/core/terminal-write-auth.js +76 -0
- package/dist/core/terminal-write-auth.js.map +1 -0
- package/dist/core/tmux-recovery.d.ts +11 -0
- package/dist/core/tmux-recovery.d.ts.map +1 -0
- package/dist/core/tmux-recovery.js +19 -0
- package/dist/core/tmux-recovery.js.map +1 -0
- package/dist/core/types.d.ts +10 -4
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/update-check.d.ts +2 -2
- package/dist/core/update-check.js +2 -2
- package/dist/core/worker-pool.d.ts +3 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +70 -3
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +15 -8
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/auth.d.ts +1 -1
- package/dist/dashboard/auth.d.ts.map +1 -1
- package/dist/dashboard/auth.js +7 -2
- package/dist/dashboard/auth.js.map +1 -1
- package/dist/dashboard/bot-payload.d.ts +3 -0
- package/dist/dashboard/bot-payload.d.ts.map +1 -1
- package/dist/dashboard/bot-payload.js +3 -0
- package/dist/dashboard/bot-payload.js.map +1 -1
- package/dist/dashboard/connector-api.d.ts.map +1 -1
- package/dist/dashboard/connector-api.js +39 -13
- package/dist/dashboard/connector-api.js.map +1 -1
- package/dist/dashboard/history-senders.d.ts +37 -0
- package/dist/dashboard/history-senders.d.ts.map +1 -0
- package/dist/dashboard/history-senders.js +60 -0
- package/dist/dashboard/history-senders.js.map +1 -0
- package/dist/dashboard/roles-batch.d.ts +31 -0
- package/dist/dashboard/roles-batch.d.ts.map +1 -0
- package/dist/dashboard/roles-batch.js +87 -0
- package/dist/dashboard/roles-batch.js.map +1 -0
- package/dist/dashboard/settings-card-model.d.ts +4 -2
- package/dist/dashboard/settings-card-model.d.ts.map +1 -1
- package/dist/dashboard/settings-card-model.js +13 -5
- package/dist/dashboard/settings-card-model.js.map +1 -1
- package/dist/dashboard/settings-write-applier.d.ts +4 -1
- package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
- package/dist/dashboard/settings-write-applier.js +6 -1
- package/dist/dashboard/settings-write-applier.js.map +1 -1
- package/dist/dashboard/skill-install-request.d.ts +4 -0
- package/dist/dashboard/skill-install-request.d.ts.map +1 -1
- package/dist/dashboard/skill-install-request.js +11 -1
- package/dist/dashboard/skill-install-request.js.map +1 -1
- package/dist/dashboard/trigger-api.d.ts +9 -1
- package/dist/dashboard/trigger-api.d.ts.map +1 -1
- package/dist/dashboard/trigger-api.js +48 -10
- package/dist/dashboard/trigger-api.js.map +1 -1
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +286 -271
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.d.ts +26 -0
- package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.js +1408 -12
- package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
- package/dist/dashboard/web/bot-defaults.d.ts +91 -4
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults.js +43 -2141
- package/dist/dashboard/web/bot-defaults.js.map +1 -1
- package/dist/dashboard/web/bot-onboarding.d.ts +6 -1
- package/dist/dashboard/web/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/web/bot-onboarding.js +261 -306
- package/dist/dashboard/web/bot-onboarding.js.map +1 -1
- package/dist/dashboard/web/connectors-page.d.ts +4 -0
- package/dist/dashboard/web/connectors-page.d.ts.map +1 -1
- package/dist/dashboard/web/connectors-page.js +228 -48
- package/dist/dashboard/web/connectors-page.js.map +1 -1
- package/dist/dashboard/web/dashboard-api.d.ts +9 -0
- package/dist/dashboard/web/dashboard-api.d.ts.map +1 -0
- package/dist/dashboard/web/dashboard-api.js +18 -0
- package/dist/dashboard/web/dashboard-api.js.map +1 -0
- package/dist/dashboard/web/dashboard-components.d.ts +92 -0
- package/dist/dashboard/web/dashboard-components.d.ts.map +1 -0
- package/dist/dashboard/web/dashboard-components.js +250 -0
- package/dist/dashboard/web/dashboard-components.js.map +1 -0
- package/dist/dashboard/web/dashboard-routes.d.ts.map +1 -1
- package/dist/dashboard/web/dashboard-routes.js +30 -183
- package/dist/dashboard/web/dashboard-routes.js.map +1 -1
- package/dist/dashboard/web/floating-scrollbars.d.ts +2 -0
- package/dist/dashboard/web/floating-scrollbars.d.ts.map +1 -0
- package/dist/dashboard/web/floating-scrollbars.js +264 -0
- package/dist/dashboard/web/floating-scrollbars.js.map +1 -0
- package/dist/dashboard/web/groups-api.d.ts +36 -0
- package/dist/dashboard/web/groups-api.d.ts.map +1 -0
- package/dist/dashboard/web/groups-api.js +44 -0
- package/dist/dashboard/web/groups-api.js.map +1 -0
- package/dist/dashboard/web/groups-page.d.ts.map +1 -1
- package/dist/dashboard/web/groups-page.js +746 -15
- package/dist/dashboard/web/groups-page.js.map +1 -1
- package/dist/dashboard/web/groups.d.ts +51 -18
- package/dist/dashboard/web/groups.d.ts.map +1 -1
- package/dist/dashboard/web/groups.js +145 -1096
- package/dist/dashboard/web/groups.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +545 -255
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/insights-page.d.ts.map +1 -1
- package/dist/dashboard/web/insights-page.js +1047 -14
- package/dist/dashboard/web/insights-page.js.map +1 -1
- package/dist/dashboard/web/insights.d.ts +177 -7
- package/dist/dashboard/web/insights.d.ts.map +1 -1
- package/dist/dashboard/web/insights.js +187 -1926
- package/dist/dashboard/web/insights.js.map +1 -1
- package/dist/dashboard/web/legacy-workflow-page.d.ts +3 -0
- package/dist/dashboard/web/legacy-workflow-page.d.ts.map +1 -0
- package/dist/dashboard/web/legacy-workflow-page.js +717 -0
- package/dist/dashboard/web/legacy-workflow-page.js.map +1 -0
- package/dist/dashboard/web/monitor-room.d.ts.map +1 -1
- package/dist/dashboard/web/monitor-room.js +10 -8
- package/dist/dashboard/web/monitor-room.js.map +1 -1
- package/dist/dashboard/web/monitoring-page.d.ts.map +1 -1
- package/dist/dashboard/web/monitoring-page.js +188 -14
- package/dist/dashboard/web/monitoring-page.js.map +1 -1
- package/dist/dashboard/web/office-page.d.ts.map +1 -1
- package/dist/dashboard/web/office-page.js +11 -23
- package/dist/dashboard/web/office-page.js.map +1 -1
- package/dist/dashboard/web/overview-page.d.ts.map +1 -1
- package/dist/dashboard/web/overview-page.js +141 -147
- package/dist/dashboard/web/overview-page.js.map +1 -1
- package/dist/dashboard/web/overview.d.ts +0 -1
- package/dist/dashboard/web/overview.d.ts.map +1 -1
- package/dist/dashboard/web/overview.js +3 -275
- package/dist/dashboard/web/overview.js.map +1 -1
- package/dist/dashboard/web/preferences.d.ts +1 -6
- package/dist/dashboard/web/preferences.d.ts.map +1 -1
- package/dist/dashboard/web/preferences.js +0 -21
- package/dist/dashboard/web/preferences.js.map +1 -1
- package/dist/dashboard/web/role-batch.d.ts +9 -0
- package/dist/dashboard/web/role-batch.d.ts.map +1 -0
- package/dist/dashboard/web/role-batch.js +42 -0
- package/dist/dashboard/web/role-batch.js.map +1 -0
- package/dist/dashboard/web/roles-page.d.ts.map +1 -1
- package/dist/dashboard/web/roles-page.js +538 -13
- package/dist/dashboard/web/roles-page.js.map +1 -1
- package/dist/dashboard/web/roles.d.ts +98 -1
- package/dist/dashboard/web/roles.d.ts.map +1 -1
- package/dist/dashboard/web/roles.js +117 -903
- package/dist/dashboard/web/roles.js.map +1 -1
- package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
- package/dist/dashboard/web/schedules-page.js +82 -24
- package/dist/dashboard/web/schedules-page.js.map +1 -1
- package/dist/dashboard/web/sessions-kanban.d.ts +67 -0
- package/dist/dashboard/web/sessions-kanban.d.ts.map +1 -0
- package/dist/dashboard/web/sessions-kanban.js +481 -0
- package/dist/dashboard/web/sessions-kanban.js.map +1 -0
- package/dist/dashboard/web/sessions-page.d.ts +4 -0
- package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
- package/dist/dashboard/web/sessions-page.js +1633 -18
- package/dist/dashboard/web/sessions-page.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts +45 -4
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +53 -2535
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard/web/settings-page.d.ts +0 -2
- package/dist/dashboard/web/settings-page.d.ts.map +1 -1
- package/dist/dashboard/web/settings-page.js +127 -117
- package/dist/dashboard/web/settings-page.js.map +1 -1
- package/dist/dashboard/web/skills-page.d.ts +10 -1
- package/dist/dashboard/web/skills-page.d.ts.map +1 -1
- package/dist/dashboard/web/skills-page.js +235 -93
- package/dist/dashboard/web/skills-page.js.map +1 -1
- package/dist/dashboard/web/team-federation-page.d.ts.map +1 -1
- package/dist/dashboard/web/team-federation-page.js +446 -28
- package/dist/dashboard/web/team-federation-page.js.map +1 -1
- package/dist/dashboard/web/team-federation.d.ts +91 -2
- package/dist/dashboard/web/team-federation.d.ts.map +1 -1
- package/dist/dashboard/web/team-federation.js +87 -474
- package/dist/dashboard/web/team-federation.js.map +1 -1
- package/dist/dashboard/web/theme-menu.d.ts +1 -0
- package/dist/dashboard/web/theme-menu.d.ts.map +1 -1
- package/dist/dashboard/web/theme-menu.js +79 -20
- package/dist/dashboard/web/theme-menu.js.map +1 -1
- package/dist/dashboard/web/ui.d.ts +1 -2
- package/dist/dashboard/web/ui.d.ts.map +1 -1
- package/dist/dashboard/web/ui.js +8 -20
- package/dist/dashboard/web/ui.js.map +1 -1
- package/dist/dashboard/web/v3-api.d.ts +16 -0
- package/dist/dashboard/web/v3-api.d.ts.map +1 -0
- package/dist/dashboard/web/v3-api.js +21 -0
- package/dist/dashboard/web/v3-api.js.map +1 -0
- package/dist/dashboard/web/v3-components.d.ts +2 -0
- package/dist/dashboard/web/v3-components.d.ts.map +1 -0
- package/dist/dashboard/web/v3-components.js +290 -0
- package/dist/dashboard/web/v3-components.js.map +1 -0
- package/dist/dashboard/web/v3-model.d.ts +80 -0
- package/dist/dashboard/web/v3-model.d.ts.map +1 -0
- package/dist/dashboard/web/v3-model.js +240 -0
- package/dist/dashboard/web/v3-model.js.map +1 -0
- package/dist/dashboard/web/v3-page.d.ts.map +1 -1
- package/dist/dashboard/web/v3-page.js +2 -22
- package/dist/dashboard/web/v3-page.js.map +1 -1
- package/dist/dashboard/web/v3-terminal.d.ts +14 -0
- package/dist/dashboard/web/v3-terminal.d.ts.map +1 -1
- package/dist/dashboard/web/v3-terminal.js +31 -19
- package/dist/dashboard/web/v3-terminal.js.map +1 -1
- package/dist/dashboard/web/webhook-logs-page.d.ts +16 -0
- package/dist/dashboard/web/webhook-logs-page.d.ts.map +1 -0
- package/dist/dashboard/web/webhook-logs-page.js +195 -0
- package/dist/dashboard/web/webhook-logs-page.js.map +1 -0
- package/dist/dashboard/web/whiteboards-page.d.ts.map +1 -1
- package/dist/dashboard/web/whiteboards-page.js +18 -23
- package/dist/dashboard/web/whiteboards-page.js.map +1 -1
- package/dist/dashboard/web/workflow-version-switch.d.ts +8 -0
- package/dist/dashboard/web/workflow-version-switch.d.ts.map +1 -0
- package/dist/dashboard/web/workflow-version-switch.js +9 -0
- package/dist/dashboard/web/workflow-version-switch.js.map +1 -0
- package/dist/dashboard/web/workflows.d.ts +272 -1
- package/dist/dashboard/web/workflows.d.ts.map +1 -1
- package/dist/dashboard/web/workflows.js +211 -1397
- package/dist/dashboard/web/workflows.js.map +1 -1
- package/dist/dashboard/webhook-routes.d.ts.map +1 -1
- package/dist/dashboard/webhook-routes.js +92 -39
- package/dist/dashboard/webhook-routes.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -65
- package/dist/dashboard-web/brand-logo.png +0 -0
- package/dist/dashboard-web/chunks/bot-defaults-page-HSQ6HR3R.js +1 -0
- package/dist/dashboard-web/chunks/chunk-6TPODDDC.js +1 -0
- package/dist/dashboard-web/chunks/chunk-73EJP2MO.js +1 -0
- package/dist/dashboard-web/chunks/chunk-BRTZFELS.js +1 -0
- package/dist/dashboard-web/chunks/chunk-EVK77ASG.js +1 -0
- package/dist/dashboard-web/chunks/chunk-R3FXBFQH.js +1 -0
- package/dist/dashboard-web/chunks/chunk-VRLL7SNU.js +1 -0
- package/dist/dashboard-web/chunks/chunk-XCPSHD3G.js +37 -0
- package/dist/dashboard-web/chunks/chunk-XJ7BGPJH.js +1 -0
- package/dist/dashboard-web/chunks/chunk-YVRWYGXR.js +1 -0
- package/dist/dashboard-web/chunks/chunk-ZJING6FY.js +66 -0
- package/dist/dashboard-web/chunks/connectors-page-ODUA5UCW.js +1 -0
- package/dist/dashboard-web/chunks/groups-page-OYX5M6NK.js +8 -0
- package/dist/dashboard-web/chunks/insights-page-YCQO6OCR.js +22 -0
- package/dist/dashboard-web/chunks/legacy-workflow-page-XJAUNONP.js +2 -0
- package/dist/dashboard-web/chunks/{monitor-room-RFX4HPS5.js → monitor-room-WTZNYAFV.js} +17 -15
- package/dist/dashboard-web/chunks/monitoring-page-R6LJUK7G.js +2 -0
- package/dist/dashboard-web/chunks/office-page-4OXK3GNR.js +1 -0
- package/dist/dashboard-web/chunks/overview-page-4MVEJY6U.js +1 -0
- package/dist/dashboard-web/chunks/roles-page-NQDW27VV.js +1 -0
- package/dist/dashboard-web/chunks/schedules-page-JRNKYHOX.js +1 -0
- package/dist/dashboard-web/chunks/sessions-page-LF7UVI7B.js +3 -0
- package/dist/dashboard-web/chunks/settings-page-WGW7KQQS.js +2 -0
- package/dist/dashboard-web/chunks/skills-page-AMD4XP3T.js +3 -0
- package/dist/dashboard-web/chunks/team-federation-page-SYG3K4GG.js +1 -0
- package/dist/dashboard-web/chunks/v3-page-6NFFWNUK.js +94 -0
- package/dist/dashboard-web/chunks/whiteboards-page-FBRUK2AS.js +1 -0
- package/dist/dashboard-web/favicon.png +0 -0
- package/dist/dashboard-web/index.html +5 -69
- package/dist/dashboard-web/style.css +18835 -7211
- package/dist/dashboard.js +150 -32
- package/dist/dashboard.js.map +1 -1
- package/dist/global-config.d.ts +2 -2
- package/dist/global-config.d.ts.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +3 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +3 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts +7 -5
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +10 -7
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +25 -1
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +84 -0
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/platform/binding.d.ts +9 -0
- package/dist/platform/binding.d.ts.map +1 -1
- package/dist/platform/binding.js +14 -0
- package/dist/platform/binding.js.map +1 -1
- package/dist/platform/tunnel-client.d.ts.map +1 -1
- package/dist/platform/tunnel-client.js +9 -0
- package/dist/platform/tunnel-client.js.map +1 -1
- package/dist/services/bot-config-store.d.ts +1 -1
- package/dist/services/bot-config-store.d.ts.map +1 -1
- package/dist/services/bot-config-store.js +11 -5
- package/dist/services/bot-config-store.js.map +1 -1
- package/dist/services/file-bridge-path.d.ts +8 -0
- package/dist/services/file-bridge-path.d.ts.map +1 -0
- package/dist/services/file-bridge-path.js +75 -0
- package/dist/services/file-bridge-path.js.map +1 -0
- package/dist/services/grok-paths.d.ts +27 -0
- package/dist/services/grok-paths.d.ts.map +1 -0
- package/dist/services/grok-paths.js +106 -0
- package/dist/services/grok-paths.js.map +1 -0
- package/dist/services/grok-transcript.d.ts +67 -0
- package/dist/services/grok-transcript.d.ts.map +1 -0
- package/dist/services/grok-transcript.js +630 -0
- package/dist/services/grok-transcript.js.map +1 -0
- package/dist/services/hermes-session-filter.d.ts +28 -0
- package/dist/services/hermes-session-filter.d.ts.map +1 -0
- package/dist/services/hermes-session-filter.js +53 -0
- package/dist/services/hermes-session-filter.js.map +1 -0
- package/dist/services/hermes-transcript.d.ts +3 -0
- package/dist/services/hermes-transcript.d.ts.map +1 -1
- package/dist/services/hermes-transcript.js +20 -2
- package/dist/services/hermes-transcript.js.map +1 -1
- package/dist/services/resumable-session-discovery.d.ts +3 -0
- package/dist/services/resumable-session-discovery.d.ts.map +1 -1
- package/dist/services/resumable-session-discovery.js +6 -1
- package/dist/services/resumable-session-discovery.js.map +1 -1
- package/dist/services/skill-registry-store.d.ts +9 -0
- package/dist/services/skill-registry-store.d.ts.map +1 -1
- package/dist/services/skill-registry-store.js +304 -1
- package/dist/services/skill-registry-store.js.map +1 -1
- package/dist/services/structured-bridge-clis.d.ts +29 -0
- package/dist/services/structured-bridge-clis.d.ts.map +1 -0
- package/dist/services/structured-bridge-clis.js +76 -0
- package/dist/services/structured-bridge-clis.js.map +1 -0
- package/dist/services/trigger-log-store.d.ts +59 -0
- package/dist/services/trigger-log-store.d.ts.map +1 -1
- package/dist/services/trigger-log-store.js +81 -10
- package/dist/services/trigger-log-store.js.map +1 -1
- package/dist/services/usage-ledger.d.ts +4 -1
- package/dist/services/usage-ledger.d.ts.map +1 -1
- package/dist/services/usage-ledger.js +48 -10
- package/dist/services/usage-ledger.js.map +1 -1
- package/dist/services/webhook-audit.d.ts +10 -0
- package/dist/services/webhook-audit.d.ts.map +1 -0
- package/dist/services/webhook-audit.js +116 -0
- package/dist/services/webhook-audit.js.map +1 -0
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +2 -0
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/setup/ensure-tmux.d.ts +26 -12
- package/dist/setup/ensure-tmux.d.ts.map +1 -1
- package/dist/setup/ensure-tmux.js +85 -18
- package/dist/setup/ensure-tmux.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +14 -1
- package/dist/skills/definitions.js.map +1 -1
- package/dist/skills/injection-mode.d.ts +16 -0
- package/dist/skills/injection-mode.d.ts.map +1 -1
- package/dist/skills/injection-mode.js +25 -0
- package/dist/skills/injection-mode.js.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/global-install.d.ts +22 -0
- package/dist/utils/global-install.d.ts.map +1 -0
- package/dist/utils/global-install.js +106 -0
- package/dist/utils/global-install.js.map +1 -0
- package/dist/utils/install-diagnostics.d.ts +1 -1
- package/dist/utils/install-diagnostics.d.ts.map +1 -1
- package/dist/utils/install-diagnostics.js +6 -4
- package/dist/utils/install-diagnostics.js.map +1 -1
- package/dist/utils/install-info.d.ts +2 -0
- package/dist/utils/install-info.d.ts.map +1 -1
- package/dist/utils/install-info.js +10 -4
- package/dist/utils/install-info.js.map +1 -1
- package/dist/worker.js +293 -172
- package/dist/worker.js.map +1 -1
- package/dist/workflows/events/payloads.d.ts +10 -10
- package/dist/workflows/events/schema.d.ts +28 -28
- package/package.json +8 -7
- package/dist/dashboard/web/connectors.d.ts +0 -2
- package/dist/dashboard/web/connectors.d.ts.map +0 -1
- package/dist/dashboard/web/connectors.js +0 -2
- package/dist/dashboard/web/connectors.js.map +0 -1
- package/dist/dashboard/web/office.d.ts +0 -2
- package/dist/dashboard/web/office.d.ts.map +0 -1
- package/dist/dashboard/web/office.js +0 -2
- package/dist/dashboard/web/office.js.map +0 -1
- package/dist/dashboard/web/schedules.d.ts +0 -2
- package/dist/dashboard/web/schedules.d.ts.map +0 -1
- package/dist/dashboard/web/schedules.js +0 -2
- package/dist/dashboard/web/schedules.js.map +0 -1
- package/dist/dashboard/web/settings.d.ts +0 -2
- package/dist/dashboard/web/settings.d.ts.map +0 -1
- package/dist/dashboard/web/settings.js +0 -2
- package/dist/dashboard/web/settings.js.map +0 -1
- package/dist/dashboard/web/skills.d.ts +0 -2
- package/dist/dashboard/web/skills.d.ts.map +0 -1
- package/dist/dashboard/web/skills.js +0 -2
- package/dist/dashboard/web/skills.js.map +0 -1
- package/dist/dashboard/web/skin-intro.d.ts +0 -4
- package/dist/dashboard/web/skin-intro.d.ts.map +0 -1
- package/dist/dashboard/web/skin-intro.js +0 -49
- package/dist/dashboard/web/skin-intro.js.map +0 -1
- package/dist/dashboard/web/v3.d.ts +0 -3
- package/dist/dashboard/web/v3.d.ts.map +0 -1
- package/dist/dashboard/web/v3.js +0 -539
- package/dist/dashboard/web/v3.js.map +0 -1
- package/dist/dashboard/web/whiteboards.d.ts +0 -2
- package/dist/dashboard/web/whiteboards.d.ts.map +0 -1
- package/dist/dashboard/web/whiteboards.js +0 -2
- package/dist/dashboard/web/whiteboards.js.map +0 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-OCIHPGEU.js +0 -438
- package/dist/dashboard-web/chunks/chunk-3N2PPQVD.js +0 -1
- package/dist/dashboard-web/chunks/chunk-3UJYRR2Q.js +0 -37
- package/dist/dashboard-web/chunks/chunk-5E3MJJL4.js +0 -1
- package/dist/dashboard-web/chunks/chunk-7SZRL6FY.js +0 -1
- package/dist/dashboard-web/chunks/chunk-JTSE5VP6.js +0 -54
- package/dist/dashboard-web/chunks/chunk-LXIK7OUJ.js +0 -1
- package/dist/dashboard-web/chunks/chunk-PE6W3C2C.js +0 -1
- package/dist/dashboard-web/chunks/chunk-QW54DWU3.js +0 -325
- package/dist/dashboard-web/chunks/connectors-IGETYWCP.js +0 -1
- package/dist/dashboard-web/chunks/groups-page-MYBS4ZYJ.js +0 -207
- package/dist/dashboard-web/chunks/insights-page-UPA32V2S.js +0 -309
- package/dist/dashboard-web/chunks/monitoring-page-7T3BESZ2.js +0 -1
- package/dist/dashboard-web/chunks/office-page-6DXYOG55.js +0 -1
- package/dist/dashboard-web/chunks/overview-page-LJSBCQW4.js +0 -1
- package/dist/dashboard-web/chunks/roles-page-ESURTVQH.js +0 -98
- package/dist/dashboard-web/chunks/schedules-LML2ISOT.js +0 -1
- package/dist/dashboard-web/chunks/sessions-YB73XOTU.js +0 -1
- package/dist/dashboard-web/chunks/sessions-page-MCO5QR7Z.js +0 -1
- package/dist/dashboard-web/chunks/settings-page-OSDKNVS3.js +0 -2
- package/dist/dashboard-web/chunks/skills-page-PXBZJ6P6.js +0 -2
- package/dist/dashboard-web/chunks/team-federation-page-TTPVHFPX.js +0 -10
- package/dist/dashboard-web/chunks/v3-page-FVPUL665.js +0 -149
- package/dist/dashboard-web/chunks/whiteboards-page-HLCTYSSV.js +0 -1
- package/dist/dashboard-web/chunks/workflows-FCPM4S4D.js +0 -184
- package/dist/dashboard-web/skins/bluearchive-hero.webp +0 -0
- package/dist/dashboard-web/skins/dragonball-goku.webp +0 -0
- package/dist/dashboard-web/skins/dragonball-wukong.webp +0 -0
- package/dist/dashboard-web/skins/genshin-breeze.webp +0 -0
- package/dist/dashboard-web/skins/ikun-hero.webp +0 -0
- package/dist/dashboard-web/skins/prts-priestess.webp +0 -0
- package/dist/dashboard-web/skins/zzz-hero.webp +0 -0
- package/dist/dashboard-web/skins/zzz-pattern.svg +0 -25
|
@@ -1,64 +1,252 @@
|
|
|
1
|
-
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Dashboard SPA entry: React chrome + lazy route host + SSE bootstrap.
|
|
3
|
+
import { createRoot } from 'react-dom/client';
|
|
4
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
5
|
import { bootstrap, store } from './store.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { initThemeMenu, paintThemeMenu } from './theme-menu.js';
|
|
6
|
+
import { attentionReason, attentionWaitSince, botDisplayName, escapeHtml, loadNameMaps, relTime, t, ui, } from './ui.js';
|
|
7
|
+
import { CLOSE_THEME_MENU_EVENT, initThemeMenu, paintThemeMenu } from './theme-menu.js';
|
|
6
8
|
import { normalizeDashboardLocale } from './i18n.js';
|
|
7
|
-
import { readStoredSidebarMode, writeStoredSidebarMode } from './preferences.js';
|
|
8
9
|
import { findDashboardRoute, loadOverviewPage } from './dashboard-routes.js';
|
|
9
10
|
import { beginDashboardRoute, createDashboardRouteState, loadAndRenderDashboardRoute, } from './route-lifecycle.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
import { buildBotCards, loadGroupsSnapshot } from './overview.js';
|
|
12
|
+
import { BotOnboardingDialog, OPEN_BOT_ONBOARDING_EVENT } from './bot-onboarding.js';
|
|
13
|
+
import { InfoTip } from './dashboard-components.js';
|
|
14
|
+
import { initFloatingScrollbars } from './floating-scrollbars.js';
|
|
15
|
+
const MANAGE_ROUTES = [
|
|
16
|
+
'roles',
|
|
17
|
+
'role-profiles',
|
|
18
|
+
'bot-defaults',
|
|
19
|
+
'skills',
|
|
20
|
+
'team',
|
|
21
|
+
'connectors',
|
|
22
|
+
'insights',
|
|
23
|
+
'whiteboards',
|
|
24
|
+
];
|
|
25
|
+
const NAV_ITEMS = [
|
|
26
|
+
{
|
|
27
|
+
id: 'overview',
|
|
28
|
+
href: '#/',
|
|
29
|
+
labelKey: 'nav.overview',
|
|
30
|
+
icon: (_jsxs(_Fragment, { children: [_jsx("rect", { x: "1.5", y: "1.5", width: "5.4", height: "5.4", rx: "1.5" }), _jsx("rect", { x: "9.1", y: "1.5", width: "5.4", height: "5.4", rx: "1.5" }), _jsx("rect", { x: "1.5", y: "9.1", width: "5.4", height: "5.4", rx: "1.5" }), _jsx("rect", { x: "9.1", y: "9.1", width: "5.4", height: "5.4", rx: "1.5" })] })),
|
|
31
|
+
},
|
|
32
|
+
{ id: 'sessions', href: '#/sessions', labelKey: 'nav.sessions', icon: _jsx("path", { d: "M2 3.5h12v7H6l-3 3v-3H2z" }) },
|
|
33
|
+
{
|
|
34
|
+
id: 'groups',
|
|
35
|
+
href: '#/groups',
|
|
36
|
+
labelKey: 'nav.groups',
|
|
37
|
+
icon: (_jsxs(_Fragment, { children: [_jsx("circle", { cx: "5.6", cy: "5.8", r: "2.4" }), _jsx("circle", { cx: "11", cy: "6.8", r: "1.9" }), _jsx("path", { d: "M1.8 13.2c.5-2.4 2-3.6 3.8-3.6s3.3 1.2 3.8 3.6M9.8 12.6c.4-1.7 1.5-2.6 2.8-2.6 1 0 1.9.5 2.4 1.6" })] })),
|
|
38
|
+
},
|
|
39
|
+
{ id: 'roles', href: '#/roles', labelKey: 'nav.roles', manage: true, icon: _jsxs(_Fragment, { children: [_jsx("path", { d: "M8 1.8l5.2 2v3.4c0 3.4-2.2 5.9-5.2 7-3-1.1-5.2-3.6-5.2-7V3.8z" }), _jsx("path", { d: "M5.8 8l1.6 1.6 2.8-3" })] }) },
|
|
40
|
+
{
|
|
41
|
+
id: 'monitoring',
|
|
42
|
+
href: '#/monitoring',
|
|
43
|
+
labelKey: 'nav.monitoring',
|
|
44
|
+
icon: (_jsxs(_Fragment, { children: [_jsx("path", { d: "M2 9.2h2.3l1.3-4.8 2.5 8.4 1.8-5.1h4.1" }), _jsx("path", { d: "M2 2.5h12v11H2z" })] })),
|
|
45
|
+
},
|
|
46
|
+
{ id: 'insights', href: '#/insights', labelKey: 'nav.insights', manage: true, icon: _jsx(_Fragment, { children: _jsx("path", { d: "M2 2v12h12M5 11V7M8.5 11V4.5M12 11V8.5" }) }) },
|
|
47
|
+
{
|
|
48
|
+
id: 'workflows',
|
|
49
|
+
href: '#/workflows',
|
|
50
|
+
labelKey: 'nav.workflows',
|
|
51
|
+
icon: (_jsxs(_Fragment, { children: [_jsx("circle", { cx: "3.4", cy: "3.6", r: "1.9" }), _jsx("circle", { cx: "3.4", cy: "12.4", r: "1.9" }), _jsx("circle", { cx: "12.6", cy: "8", r: "1.9" }), _jsx("path", { d: "M5.2 4.4l5.6 2.8M5.2 11.6l5.6-2.8" })] })),
|
|
52
|
+
},
|
|
53
|
+
{ id: 'schedules', href: '#/schedules', labelKey: 'nav.schedules', icon: _jsxs(_Fragment, { children: [_jsx("circle", { cx: "8", cy: "8", r: "6.2" }), _jsx("path", { d: "M8 4.5V8l2.4 1.6" })] }) },
|
|
54
|
+
{ id: 'whiteboards', href: '#/whiteboards', labelKey: 'nav.whiteboards', manage: true, icon: _jsxs(_Fragment, { children: [_jsx("rect", { x: "2.2", y: "2.2", width: "11.6", height: "11.6", rx: "2" }), _jsx("path", { d: "M4.8 5.2h6.4M4.8 8h6.4M4.8 10.8h4" })] }) },
|
|
55
|
+
{ id: 'office', href: '#/office', labelKey: 'nav.office', icon: _jsxs(_Fragment, { children: [_jsx("rect", { x: "3", y: "4", width: "10", height: "7", rx: "2" }), _jsx("circle", { cx: "6", cy: "7.5", r: "1" }), _jsx("circle", { cx: "10", cy: "7.5", r: "1" }), _jsx("path", { d: "M8 4V2M4.5 11v2M11.5 11v2" })] }) },
|
|
56
|
+
{ id: 'bot-defaults', href: '#/bot-defaults', labelKey: 'nav.botDefaults', manage: true, icon: _jsxs(_Fragment, { children: [_jsx("rect", { x: "2.5", y: "5", width: "11", height: "8", rx: "2" }), _jsx("circle", { cx: "5.8", cy: "9", r: "1" }), _jsx("circle", { cx: "10.2", cy: "9", r: "1" }), _jsx("path", { d: "M8 5V2.5M5.5 13v1.2M10.5 13v1.2" })] }) },
|
|
57
|
+
{ id: 'skills', href: '#/skills', labelKey: 'nav.skills', manage: true, icon: _jsxs(_Fragment, { children: [_jsx("path", { d: "M3 2.5h10v3H3zM3 7h10v6.5H3z" }), _jsx("path", { d: "M5.4 9.2h5.2M5.4 11.2h3.8" })] }) },
|
|
58
|
+
{ id: 'team', href: '#/team', labelKey: 'nav.team', manage: true, icon: _jsxs(_Fragment, { children: [_jsx("circle", { cx: "8", cy: "8", r: "6.2" }), _jsx("path", { d: "M1.8 8h12.4M8 1.8c-2 1.8-2 10.6 0 12.4 2-1.8 2-10.6 0-12.4z" })] }) },
|
|
59
|
+
{ id: 'connectors', href: '#/connectors', labelKey: 'nav.connectors', manage: true, icon: _jsxs(_Fragment, { children: [_jsx("path", { d: "M5.5 6.5v-3a2.5 2.5 0 0 1 5 0v3" }), _jsx("rect", { x: "3.5", y: "6.5", width: "9", height: "7", rx: "2" })] }) },
|
|
60
|
+
{ id: 'settings', href: '#/settings', labelKey: 'nav.settings', icon: _jsxs(_Fragment, { children: [_jsx("path", { d: "M8 1.75 9.35 2.05 10 3.28l1.38.3 1.04-.96.96.96-.96 1.04.3 1.38 1.23.65L14.25 8l-.3 1.35-1.23.65-.3 1.38.96 1.04-.96.96-1.04-.96-1.38.3-.65 1.23L8 14.25l-1.35-.3L6 12.72l-1.38-.3-1.04.96-.96-.96.96-1.04-.3-1.38-1.23-.65L1.75 8l.3-1.35 1.23-.65.3-1.38-.96-1.04.96-.96 1.04.96 1.38-.3.65-1.23z" }), _jsx("circle", { cx: "8", cy: "8", r: "2" })] }) },
|
|
61
|
+
];
|
|
17
62
|
let isAuthed = true;
|
|
18
63
|
let publicReadOnly = false;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
64
|
+
let activeHash = location.hash || '#/';
|
|
65
|
+
let ownerAvatar = null;
|
|
66
|
+
let updateBehind = false;
|
|
67
|
+
let latestVersion = null;
|
|
68
|
+
let routeRoot = null;
|
|
69
|
+
let appRoot = null;
|
|
70
|
+
const routeState = createDashboardRouteState();
|
|
71
|
+
const OWNER_AVATAR_KEY = 'botmux.ownerAvatar.v1';
|
|
72
|
+
const BUSY_STATUSES = new Set(['working', 'analyzing', 'active', 'starting']);
|
|
73
|
+
const AUTH_EXPIRED_EVENT = 'botmux:auth-expired';
|
|
74
|
+
function icon(children) {
|
|
75
|
+
return _jsx("svg", { viewBox: "0 0 16 16", "aria-hidden": "true", children: children });
|
|
76
|
+
}
|
|
77
|
+
function labelOf(item) {
|
|
78
|
+
return item.labelKey ? t(item.labelKey) : (item.label ?? '');
|
|
79
|
+
}
|
|
80
|
+
function isActiveNav(item, hash) {
|
|
81
|
+
const current = hash || '#/';
|
|
82
|
+
if (item.id === 'workflows' &&
|
|
83
|
+
(current === '#/legacy-workflow' || current.startsWith('#/legacy-workflow?') || current.startsWith('#/legacy-workflow/'))) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
if (item.id === 'sessions' &&
|
|
87
|
+
(current === '#/monitor-room' || current.startsWith('#/monitor-room?') || current.startsWith('#/monitor-room/'))) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
if (item.id === 'connectors' && (current === '#/webhook-logs' || current.startsWith('#/webhook-logs?') || current.startsWith('#/webhook-logs/'))) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
return item.href === current || (item.href !== '#/' && (current.startsWith(`${item.href}?`) || current.startsWith(`${item.href}/`)));
|
|
94
|
+
}
|
|
95
|
+
function navClassName(item) {
|
|
96
|
+
const classes = [];
|
|
97
|
+
if (isActiveNav(item, activeHash))
|
|
98
|
+
classes.push('active');
|
|
99
|
+
if (item.id === 'settings' && updateBehind)
|
|
100
|
+
classes.push('nav-has-update');
|
|
101
|
+
return classes.length ? classes.join(' ') : undefined;
|
|
102
|
+
}
|
|
103
|
+
function setRouteRoot(node) {
|
|
104
|
+
routeRoot = node;
|
|
105
|
+
}
|
|
106
|
+
function getRouteRoot() {
|
|
107
|
+
if (routeRoot)
|
|
108
|
+
return routeRoot;
|
|
109
|
+
const el = document.getElementById('root');
|
|
110
|
+
if (!el)
|
|
111
|
+
throw new Error('dashboard root is not mounted');
|
|
112
|
+
routeRoot = el;
|
|
113
|
+
return el;
|
|
114
|
+
}
|
|
115
|
+
function ThemeMenuSlot() {
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
initThemeMenu();
|
|
118
|
+
}, []);
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
paintThemeMenu();
|
|
121
|
+
});
|
|
122
|
+
return (_jsxs("div", { className: "theme-menu", id: "theme-menu", children: [_jsx("button", { type: "button", className: "theme-menu-btn", id: "theme-menu-btn", "aria-haspopup": "listbox", "aria-expanded": "false", "aria-label": "Theme", children: _jsx("span", { className: "tm-ic", children: _jsxs("svg", { className: "tm-svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("circle", { cx: "13.5", cy: "6.5", r: ".5", fill: "currentColor" }), _jsx("circle", { cx: "17.5", cy: "10.5", r: ".5", fill: "currentColor" }), _jsx("circle", { cx: "8.5", cy: "7.5", r: ".5", fill: "currentColor" }), _jsx("circle", { cx: "6.5", cy: "12.5", r: ".5", fill: "currentColor" }), _jsx("path", { d: "M12 2a10 10 0 0 0 0 20h1.7a2.3 2.3 0 0 0 1.6-4c-.5-.5-.2-1.3.5-1.3H17a5 5 0 0 0 5-5 9.7 9.7 0 0 0-10-9.7z" })] }) }) }), _jsx("div", { className: "theme-menu-pop", id: "theme-menu-pop", role: "listbox", hidden: true })] }));
|
|
123
|
+
}
|
|
124
|
+
function dashboardStatusSummary() {
|
|
125
|
+
const sessions = [...store.sessions.values()];
|
|
126
|
+
const active = sessions.filter(s => s.status !== 'closed');
|
|
127
|
+
const attention = active
|
|
128
|
+
.map(s => ({ s, reason: attentionReason(s) }))
|
|
129
|
+
.filter((x) => !!x.reason)
|
|
130
|
+
.sort((a, b) => attentionWaitSince(a.s) - attentionWaitSince(b.s));
|
|
131
|
+
const attentionIds = new Set(attention.map(item => String(item.s.sessionId ?? '')));
|
|
132
|
+
const working = active.filter(s => BUSY_STATUSES.has(String(s.status)) && !attentionIds.has(String(s.sessionId ?? ''))).length;
|
|
133
|
+
const longest = attention[0] ?? null;
|
|
134
|
+
const onlineBots = buildBotCards(sessions).filter(c => c.online || c.active.length > 0).length;
|
|
135
|
+
const idle = Math.max(0, active.length - attention.length - working);
|
|
136
|
+
return {
|
|
137
|
+
working,
|
|
138
|
+
attention: attention.length,
|
|
139
|
+
idle,
|
|
140
|
+
onlineBots,
|
|
141
|
+
attentionNotice: longest ? {
|
|
142
|
+
count: attention.length,
|
|
143
|
+
time: relTime(attentionWaitSince(longest.s)),
|
|
144
|
+
bot: botDisplayName(longest.s),
|
|
145
|
+
reason: longest.reason,
|
|
146
|
+
} : null,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function TopbarStatusRow(props) {
|
|
150
|
+
return (_jsxs("div", { className: `topbar-status-row${props.hot ? ' topbar-status-row-hot' : ''}`, children: [_jsx("span", { children: props.label }), _jsx("b", { className: props.value > 0 ? 'status-count-on' : undefined, children: props.value })] }));
|
|
151
|
+
}
|
|
152
|
+
function TopbarStatusDonut(props) {
|
|
153
|
+
const { attention, idle, working } = props.summary;
|
|
154
|
+
const total = working + attention + idle;
|
|
155
|
+
const background = total === 0
|
|
156
|
+
? 'conic-gradient(var(--border) 0 360deg)'
|
|
157
|
+
: (() => {
|
|
158
|
+
const workingDeg = (working / total) * 360;
|
|
159
|
+
const attentionDeg = workingDeg + (attention / total) * 360;
|
|
160
|
+
return `conic-gradient(var(--accent) 0 ${workingDeg}deg, var(--warning) ${workingDeg}deg ${attentionDeg}deg, var(--success) ${attentionDeg}deg 360deg)`;
|
|
161
|
+
})();
|
|
162
|
+
return (_jsxs("div", { className: "topbar-status-donut-wrap", "aria-hidden": "true", children: [_jsx("div", { className: "topbar-status-donut", style: { background } }), _jsxs("div", { className: "topbar-status-donut-center", children: [_jsx("b", { children: total }), _jsx("span", { children: t('overview.openSessions') })] })] }));
|
|
163
|
+
}
|
|
164
|
+
function closeThemeMenuFromStatus() {
|
|
165
|
+
window.dispatchEvent(new Event(CLOSE_THEME_MENU_EVENT));
|
|
166
|
+
}
|
|
167
|
+
function TopbarStatusMenu(props) {
|
|
168
|
+
const { autoOpen = false, summary } = props;
|
|
169
|
+
return (_jsxs("div", { className: `topbar-status-menu${autoOpen ? ' topbar-status-auto-open' : ''}`, onPointerEnter: closeThemeMenuFromStatus, onFocusCapture: closeThemeMenuFromStatus, children: [_jsx("span", { id: "status", className: "connection-status", "aria-haspopup": "true", "aria-expanded": autoOpen, children: t('overview.sessionOverview') }), _jsxs("div", { className: "topbar-status-pop", children: [summary.attentionNotice ? (_jsxs("a", { className: "topbar-attention-notice", href: "#/sessions", children: [_jsx("span", { className: "topbar-attention-dot", "aria-hidden": "true" }), _jsxs("span", { className: "topbar-attention-copy", children: [_jsx("b", { children: t('strip.pending', { count: summary.attentionNotice.count }) }), _jsx("small", { children: t('strip.longestCompact', {
|
|
170
|
+
time: summary.attentionNotice.time,
|
|
171
|
+
bot: summary.attentionNotice.bot,
|
|
172
|
+
reason: summary.attentionNotice.reason,
|
|
173
|
+
}) })] }), _jsx("span", { className: "topbar-attention-action", children: t('strip.handle') })] })) : null, _jsxs("div", { className: "topbar-status-list", children: [_jsx(TopbarStatusRow, { label: t('overview.workingSessions'), value: summary.working }), _jsx(TopbarStatusRow, { label: t('overview.idleSessions'), value: summary.idle }), _jsx(TopbarStatusRow, { label: t('overview.attention'), value: summary.attention, hot: summary.attention > 0 }), _jsx(TopbarStatusRow, { label: t('overview.onlineBots'), value: summary.onlineBots })] }), _jsx(TopbarStatusDonut, { summary: summary })] })] }));
|
|
174
|
+
}
|
|
175
|
+
function AuthExpiredOverlay(props) {
|
|
176
|
+
if (!props.open)
|
|
177
|
+
return null;
|
|
178
|
+
return (_jsx("div", { id: "auth-expired-overlay", className: "auth-expired-overlay", role: "presentation", onClick: event => { if (event.target === event.currentTarget)
|
|
179
|
+
props.onClose(); }, children: _jsxs("div", { className: "auth-expired-dialog", role: "dialog", "aria-modal": "true", "aria-labelledby": "auth-expired-title", children: [_jsx("h2", { id: "auth-expired-title", children: "\u8BBF\u95EE\u94FE\u63A5\u5DF2\u5931\u6548" }), _jsx("p", { children: "\u5F53\u524D\u94FE\u63A5/\u8BBF\u95EE\u5DF2\u5931\u6548\uFF0C\u8BF7\u4F7F\u7528\u6700\u65B0\u6388\u6743\u94FE\u63A5\u91CD\u65B0\u8FDB\u5165\uFF08\u8FD0\u884C botmux dashboard \u83B7\u53D6\uFF09\u3002" }), _jsx("button", { id: "auth-expired-dismiss", type: "button", className: "primary", onClick: props.onClose, children: "\u77E5\u9053\u4E86" })] }) }));
|
|
180
|
+
}
|
|
181
|
+
function DashboardShell() {
|
|
182
|
+
const statusSummary = dashboardStatusSummary();
|
|
183
|
+
const [botOnboardingOpen, setBotOnboardingOpen] = useState(false);
|
|
184
|
+
const [authExpiredOpen, setAuthExpiredOpen] = useState(false);
|
|
185
|
+
const [statusAutoOpen, setStatusAutoOpen] = useState(false);
|
|
186
|
+
const previousAttentionRef = useRef(statusSummary.attention);
|
|
187
|
+
const statusAutoOpenTimerRef = useRef(null);
|
|
188
|
+
const clearStatusAutoOpenTimer = () => {
|
|
189
|
+
if (statusAutoOpenTimerRef.current === null)
|
|
190
|
+
return;
|
|
191
|
+
window.clearTimeout(statusAutoOpenTimerRef.current);
|
|
192
|
+
statusAutoOpenTimerRef.current = null;
|
|
193
|
+
};
|
|
194
|
+
useEffect(() => {
|
|
195
|
+
const open = () => setBotOnboardingOpen(true);
|
|
196
|
+
window.addEventListener(OPEN_BOT_ONBOARDING_EVENT, open);
|
|
197
|
+
return () => window.removeEventListener(OPEN_BOT_ONBOARDING_EVENT, open);
|
|
198
|
+
}, []);
|
|
199
|
+
useEffect(() => {
|
|
200
|
+
const open = () => setAuthExpiredOpen(true);
|
|
201
|
+
window.addEventListener(AUTH_EXPIRED_EVENT, open);
|
|
202
|
+
// Catch a 401 that latched expiredShown before this listener mounted (else the overlay
|
|
203
|
+
// would be permanently suppressed by the module-level guard).
|
|
204
|
+
if (expiredShown)
|
|
205
|
+
setAuthExpiredOpen(true);
|
|
206
|
+
return () => window.removeEventListener(AUTH_EXPIRED_EVENT, open);
|
|
207
|
+
}, []);
|
|
208
|
+
useEffect(() => {
|
|
209
|
+
return () => clearStatusAutoOpenTimer();
|
|
210
|
+
}, []);
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
const previousAttention = previousAttentionRef.current;
|
|
213
|
+
previousAttentionRef.current = statusSummary.attention;
|
|
214
|
+
if (statusSummary.attention === 0) {
|
|
215
|
+
clearStatusAutoOpenTimer();
|
|
216
|
+
setStatusAutoOpen(false);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (previousAttention !== 0 || document.body.classList.contains('theme-menu-open'))
|
|
220
|
+
return;
|
|
221
|
+
setStatusAutoOpen(true);
|
|
222
|
+
clearStatusAutoOpenTimer();
|
|
223
|
+
statusAutoOpenTimerRef.current = window.setTimeout(() => {
|
|
224
|
+
statusAutoOpenTimerRef.current = null;
|
|
225
|
+
setStatusAutoOpen(false);
|
|
226
|
+
}, 4000);
|
|
227
|
+
}, [statusSummary.attention]);
|
|
228
|
+
const closeAuthExpired = () => {
|
|
229
|
+
expiredShown = false;
|
|
230
|
+
setAuthExpiredOpen(false);
|
|
231
|
+
};
|
|
232
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "aurora", "aria-hidden": "true", children: [_jsx("i", { className: "a1" }), _jsx("i", { className: "a2" }), _jsx("i", { className: "a3" })] }), _jsxs("div", { className: "app-shell", children: [_jsxs("header", { className: "topbar", children: [_jsx("div", { className: "topbar-left", children: _jsxs("a", { className: "brand", href: "#/", children: [_jsx("span", { className: "brand-mark", "aria-hidden": "true", children: _jsx("img", { className: "brand-logo-img", src: "/assets/brand-logo.png", alt: "", decoding: "sync", loading: "eager", fetchPriority: "high" }) }), _jsx("strong", { className: "brand-wordmark", children: "Botmux" }), _jsx("span", { className: "brand-product", children: "Dashboard" })] }) }), _jsxs("div", { className: "topbar-actions", children: [_jsx(TopbarStatusMenu, { summary: statusSummary, autoOpen: statusAutoOpen }), _jsxs("div", { className: "topbar-tool-group", children: [_jsx("button", { type: "button", className: "topbar-locale-toggle", "aria-label": ui.locale === 'zh' ? 'Switch to English' : '切换到中文', title: ui.locale === 'zh' ? 'Switch to English' : '切换到中文', onClick: () => setLocale(ui.locale === 'zh' ? 'en' : 'zh'), children: ui.locale === 'zh' ? 'CN' : 'EN' }), _jsx(ThemeMenuSlot, {}), _jsxs("a", { className: "topbar-docs-link", href: "https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/", target: "_blank", rel: "noopener noreferrer", title: t('nav.docs'), "aria-label": t('nav.docs'), children: [icon(_jsxs(_Fragment, { children: [_jsx("rect", { x: "2.2", y: "2.2", width: "11.6", height: "11.6", rx: "2" }), _jsx("path", { d: "M4.8 5.2h6.4M4.8 8h6.4M4.8 10.8h4" })] })), _jsx("span", { children: t('nav.docs') })] })] }), _jsxs("span", { className: "topbar-owner", title: ownerAvatar?.name, "aria-label": ownerAvatar?.name ?? 'Owner', children: [_jsx("span", { className: "topbar-owner-placeholder", "aria-hidden": "true", children: icon(_jsxs(_Fragment, { children: [_jsx("circle", { cx: "8", cy: "6", r: "2.4" }), _jsx("path", { d: "M3.7 13c.7-2.5 2.2-3.7 4.3-3.7s3.6 1.2 4.3 3.7" })] })) }), ownerAvatar?.avatarUrl ? (_jsx("img", { className: "topbar-owner-img", src: ownerAvatar.avatarUrl, alt: "", decoding: "async", referrerPolicy: "no-referrer", onError: (e) => { e.currentTarget.remove(); } })) : null] })] })] }), _jsxs("div", { className: "chrome-body", children: [_jsx("aside", { className: "sidebar", children: _jsx("nav", { className: "sidebar-nav", "aria-label": "Dashboard", children: NAV_ITEMS.filter(item => isAuthed || !item.manage).map(item => (_jsxs("a", { href: item.href, "data-route": item.id, className: navClassName(item), children: [icon(item.icon), _jsx("span", { className: "sidebar-nav-label", children: labelOf(item) }), item.id === 'settings' && updateBehind ? (_jsx(InfoTip, { className: "nav-update-tip", label: t('update.navBadgeTitle', { version: latestVersion ? `v${latestVersion}` : '' }), trigger: _jsx("span", { className: "nav-update-dot", "aria-hidden": "true" }), preventClick: false, focusable: false, children: t('update.navBadgeTitle', { version: latestVersion ? `v${latestVersion}` : '' }) })) : null] }, item.id))) }) }), _jsxs("div", { className: "workspace", children: [_jsx("dialog", { id: "create-session-modal", className: "create-session-modal" }), _jsx(BotOnboardingDialog, { open: botOnboardingOpen, onClose: () => setBotOnboardingOpen(false) }), _jsx("main", { id: "root", ref: setRouteRoot })] })] })] }), _jsx(AuthExpiredOverlay, { open: authExpiredOpen, onClose: closeAuthExpired })] }));
|
|
233
|
+
}
|
|
234
|
+
function renderShell() {
|
|
235
|
+
appRoot?.render(_jsx(DashboardShell, {}));
|
|
236
|
+
}
|
|
237
|
+
function setLocale(locale) {
|
|
238
|
+
ui.setLocale(locale);
|
|
239
|
+
void persistLocale(locale);
|
|
240
|
+
}
|
|
22
241
|
// ── Auth-expiry overlay ──────────────────────────────────────────────────────
|
|
23
|
-
|
|
24
|
-
// (a real hard lockout). Under public read-only a 401 is a soft toast instead
|
|
25
|
-
// (see patchedFetch) — so this no longer fires for read-only visitors.
|
|
26
|
-
let _expiredShown = false;
|
|
242
|
+
let expiredShown = false;
|
|
27
243
|
export function showAuthExpiredOverlay() {
|
|
28
|
-
if (
|
|
244
|
+
if (expiredShown)
|
|
29
245
|
return;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
el.id = 'auth-expired-overlay';
|
|
33
|
-
el.style.cssText =
|
|
34
|
-
'position:fixed;inset:0;background:rgba(0,0,0,.65);display:flex;' +
|
|
35
|
-
'align-items:center;justify-content:center;z-index:9999';
|
|
36
|
-
el.innerHTML =
|
|
37
|
-
'<div style="background:var(--surface);color:var(--fg);border:1px solid var(--border);border-radius:12px;' +
|
|
38
|
-
'padding:36px 40px;max-width:460px;width:90vw;text-align:center;' +
|
|
39
|
-
'box-shadow:0 12px 40px rgba(0,0,0,.35)">' +
|
|
40
|
-
'<h2 style="margin:0 0 14px;font-size:19px;color:var(--fg)">访问链接已失效</h2>' +
|
|
41
|
-
'<p style="margin:0 0 24px;line-height:1.7;color:var(--muted,#8f959e);font-size:14px">' +
|
|
42
|
-
'当前链接/访问已失效,请使用最新授权链接重新进入(运行 botmux dashboard 获取)。</p>' +
|
|
43
|
-
'<button id="auth-expired-dismiss" type="button" ' +
|
|
44
|
-
'style="padding:8px 22px;background:var(--accent);color:var(--on-accent);border:none;' +
|
|
45
|
-
'border-radius:8px;cursor:pointer;font-size:14px">知道了</button>' +
|
|
46
|
-
'</div>';
|
|
47
|
-
document.body.appendChild(el);
|
|
48
|
-
// `window.close()` can't close a tab the user opened, so the old inline
|
|
49
|
-
// onclick was a dead button (overlay got stuck). Dismiss the overlay instead,
|
|
50
|
-
// and let it reappear on the next genuine 401.
|
|
51
|
-
const dismiss = () => { el.remove(); _expiredShown = false; };
|
|
52
|
-
el.querySelector('#auth-expired-dismiss')?.addEventListener('click', dismiss);
|
|
53
|
-
el.addEventListener('click', (e) => { if (e.target === el)
|
|
54
|
-
dismiss(); });
|
|
246
|
+
expiredShown = true;
|
|
247
|
+
window.dispatchEvent(new Event(AUTH_EXPIRED_EVENT));
|
|
55
248
|
}
|
|
56
|
-
|
|
57
|
-
// In public read-only mode browsing GETs never 401, but a write action
|
|
58
|
-
// (close session, cancel run, …) without the active token does. That's not
|
|
59
|
-
// "your link died" — it's "you're a read-only visitor", so show a transient
|
|
60
|
-
// toast instead of the blocking overlay.
|
|
61
|
-
let _roToastTimer;
|
|
249
|
+
let roToastTimer;
|
|
62
250
|
export function showReadOnlyToast() {
|
|
63
251
|
let el = document.getElementById('readonly-toast');
|
|
64
252
|
if (!el) {
|
|
@@ -67,29 +255,21 @@ export function showReadOnlyToast() {
|
|
|
67
255
|
el.style.cssText =
|
|
68
256
|
'position:fixed;left:50%;bottom:28px;transform:translateX(-50%);z-index:9999;' +
|
|
69
257
|
'background:var(--fg,#1f2329);color:var(--bg,#fff);padding:10px 18px;' +
|
|
70
|
-
'border-radius:
|
|
258
|
+
'border-radius:var(--radius-lg);font-size:13px;box-shadow:0 8px 24px rgba(0,0,0,.25)';
|
|
71
259
|
document.body.appendChild(el);
|
|
72
260
|
}
|
|
73
261
|
el.textContent = '当前是只读访问,此操作需要授权链接(运行 botmux dashboard 获取)';
|
|
74
262
|
el.style.display = 'block';
|
|
75
|
-
if (
|
|
76
|
-
window.clearTimeout(
|
|
77
|
-
|
|
263
|
+
if (roToastTimer)
|
|
264
|
+
window.clearTimeout(roToastTimer);
|
|
265
|
+
roToastTimer = window.setTimeout(() => { el.style.display = 'none'; }, 4000);
|
|
78
266
|
}
|
|
79
|
-
|
|
80
|
-
// was rotated while this tab was open (only possible when public read-only
|
|
81
|
-
// mode is off) → blocking overlay; a write 401 means "read-only visitor" →
|
|
82
|
-
// transient toast.
|
|
83
|
-
const _origFetch = window.fetch.bind(window);
|
|
267
|
+
const origFetch = window.fetch.bind(window);
|
|
84
268
|
window.fetch = async function patchedFetch(...args) {
|
|
85
|
-
const res = await
|
|
269
|
+
const res = await origFetch(...args);
|
|
86
270
|
if (res.status === 401) {
|
|
87
271
|
const method = (args[1]?.method ?? 'GET').toUpperCase();
|
|
88
272
|
const isRead = method === 'GET' || method === 'HEAD';
|
|
89
|
-
// A read 401 is a hard lockout (token rotated → blocking overlay) ONLY when
|
|
90
|
-
// public read-only is off. Under public read-only a read 401 just means a
|
|
91
|
-
// tokenless visitor touched a token-gated page → soft toast, never the
|
|
92
|
-
// stuck overlay. Writes are always a soft "needs the active token".
|
|
93
273
|
if (isRead && !publicReadOnly)
|
|
94
274
|
showAuthExpiredOverlay();
|
|
95
275
|
else
|
|
@@ -97,61 +277,15 @@ window.fetch = async function patchedFetch(...args) {
|
|
|
97
277
|
}
|
|
98
278
|
return res;
|
|
99
279
|
};
|
|
100
|
-
// ── 全局 attention strip ─────────────────────────────────────────────────────
|
|
101
|
-
// 「需要你」是全局最高优先级:不管在哪个页面,待处理数和最久等待项都常驻
|
|
102
|
-
// 顶部一条琥珀色 strip,点「立即处理」跳到会话页(needs-you 列置顶)。
|
|
103
|
-
let lastStripHtml = '';
|
|
104
|
-
function paintAttentionStrip() {
|
|
105
|
-
const el = document.getElementById('attention-strip');
|
|
106
|
-
if (!el)
|
|
107
|
-
return;
|
|
108
|
-
const pending = [...store.sessions.values()]
|
|
109
|
-
.map(s => ({ s, reason: attentionReason(s) }))
|
|
110
|
-
.filter((x) => !!x.reason)
|
|
111
|
-
.sort((a, b) => attentionWaitSince(a.s) - attentionWaitSince(b.s));
|
|
112
|
-
if (pending.length === 0) {
|
|
113
|
-
el.hidden = true;
|
|
114
|
-
el.innerHTML = '';
|
|
115
|
-
lastStripHtml = '';
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
const longest = pending[0];
|
|
119
|
-
const html = `
|
|
120
|
-
<span class="attention-strip-ic" aria-hidden="true">!</span>
|
|
121
|
-
<b>${escapeHtml(t('strip.pending', { count: pending.length }))}</b>
|
|
122
|
-
<span class="attention-strip-longest">${escapeHtml(t('strip.longest', {
|
|
123
|
-
time: relTime(attentionWaitSince(longest.s)),
|
|
124
|
-
bot: botDisplayName(longest.s),
|
|
125
|
-
reason: longest.reason,
|
|
126
|
-
}))}</span>
|
|
127
|
-
<a class="attention-strip-go" href="#/sessions">${escapeHtml(t('strip.handle'))}</a>`;
|
|
128
|
-
el.hidden = false;
|
|
129
|
-
// 内容没变就不重写 — innerHTML 重建会把 strip-pulse 动画打回起点(视觉跳变)
|
|
130
|
-
if (html === lastStripHtml)
|
|
131
|
-
return;
|
|
132
|
-
lastStripHtml = html;
|
|
133
|
-
el.innerHTML = html;
|
|
134
|
-
}
|
|
135
|
-
store.on(paintAttentionStrip);
|
|
136
|
-
// bot 友好名异步解析回来后刷一次 strip(页面级重绘由各 mount 自己处理)
|
|
137
|
-
void loadNameMaps().then(paintAttentionStrip);
|
|
138
|
-
// Resolve the read-only/authed state from /api/settings (authed reflects the
|
|
139
|
-
// cookie; publicReadOnly is the global toggle). Errors keep the authed default
|
|
140
|
-
// so a transient probe failure never hides nav from a real token holder.
|
|
141
280
|
async function loadAuthState() {
|
|
142
281
|
try {
|
|
143
282
|
const r = await fetch('/api/settings');
|
|
144
283
|
if (r.ok) {
|
|
145
284
|
const j = await r.json();
|
|
146
285
|
isAuthed = !!j.authed;
|
|
147
|
-
// Share the cookie-auth verdict with per-row renderers (the sessions
|
|
148
|
-
// board's writable-terminal segment reads ui.authed at render time).
|
|
149
286
|
ui.authed = isAuthed;
|
|
150
287
|
publicReadOnly = !!(j.settings && j.settings.publicReadOnly);
|
|
151
|
-
|
|
152
|
-
// set, it wins over the browser-detected / locally-stored locale so the
|
|
153
|
-
// dashboard always reflects the same language as the Feishu cards. When
|
|
154
|
-
// unset (null), keep the browser/local default ui.init() already picked.
|
|
288
|
+
ui.publicReadOnly = publicReadOnly;
|
|
155
289
|
const serverLocale = normalizeDashboardLocale(j.lang);
|
|
156
290
|
if (serverLocale)
|
|
157
291
|
ui.setLocale(serverLocale);
|
|
@@ -159,10 +293,6 @@ async function loadAuthState() {
|
|
|
159
293
|
}
|
|
160
294
|
catch { /* keep defaults */ }
|
|
161
295
|
}
|
|
162
|
-
// Persist a language choice back to the global config so it drives `botmux lang`
|
|
163
|
-
// and the Feishu cards too (the server fans the change out to every daemon
|
|
164
|
-
// live). Authed-only — read-only visitors just change their local view, which
|
|
165
|
-
// the server-authoritative locale overrides on their next load.
|
|
166
296
|
async function persistLocale(locale) {
|
|
167
297
|
if (!isAuthed)
|
|
168
298
|
return;
|
|
@@ -175,26 +305,6 @@ async function persistLocale(locale) {
|
|
|
175
305
|
}
|
|
176
306
|
catch { /* best-effort; UI already switched locally */ }
|
|
177
307
|
}
|
|
178
|
-
// Read-only visitors can't use the management pages (all token-gated), so hide
|
|
179
|
-
// their nav entries + the add-bot action instead of luring them into a 401.
|
|
180
|
-
function applyAuthVisibility() {
|
|
181
|
-
for (const r of MANAGE_ROUTES) {
|
|
182
|
-
const a = document.querySelector(`.sidebar-nav a[data-route="${r}"]`);
|
|
183
|
-
if (a)
|
|
184
|
-
a.style.display = isAuthed ? '' : 'none';
|
|
185
|
-
}
|
|
186
|
-
const addBot = document.getElementById('add-bot-btn');
|
|
187
|
-
if (addBot)
|
|
188
|
-
addBot.style.display = isAuthed ? '' : 'none';
|
|
189
|
-
// 创建会话同为管理动作(/api/sessions/create token-gated),只读访客隐藏。
|
|
190
|
-
const createSession = document.getElementById('create-session-btn');
|
|
191
|
-
if (createSession)
|
|
192
|
-
createSession.style.display = isAuthed ? '' : 'none';
|
|
193
|
-
}
|
|
194
|
-
// Show a small dot on the Settings nav when a newer botmux version is published,
|
|
195
|
-
// so an available update is visible without opening the page. Authed-only (the
|
|
196
|
-
// status endpoint is token-gated; the result is server-cached so this is cheap).
|
|
197
|
-
// Best-effort and silent on failure.
|
|
198
308
|
async function checkUpdateBadge() {
|
|
199
309
|
if (!isAuthed)
|
|
200
310
|
return;
|
|
@@ -203,68 +313,40 @@ async function checkUpdateBadge() {
|
|
|
203
313
|
if (!r.ok)
|
|
204
314
|
return;
|
|
205
315
|
const j = await r.json();
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const behind = j.behind === true;
|
|
210
|
-
a.classList.toggle('nav-has-update', behind);
|
|
211
|
-
if (behind)
|
|
212
|
-
a.title = t('update.navBadgeTitle', { version: `v${j.latest}` });
|
|
213
|
-
else
|
|
214
|
-
a.removeAttribute('title');
|
|
316
|
+
updateBehind = j.behind === true;
|
|
317
|
+
latestVersion = updateBehind && j.latest ? String(j.latest) : null;
|
|
318
|
+
renderShell();
|
|
215
319
|
}
|
|
216
320
|
catch { /* best-effort */ }
|
|
217
321
|
}
|
|
218
322
|
function renderAuthRequiredPage(host) {
|
|
219
323
|
host.innerHTML =
|
|
220
324
|
'<section class="auth-required" style="max-width:520px;margin:64px auto;text-align:center;' +
|
|
221
|
-
'background:var(--surface);color:var(--fg);border:1px solid var(--border);border-radius:
|
|
325
|
+
'background:var(--surface);color:var(--fg);border:1px solid var(--border);border-radius:var(--radius-lg);' +
|
|
222
326
|
'padding:40px 36px;box-shadow:0 8px 28px rgba(0,0,0,.12)">' +
|
|
223
327
|
'<h2 style="margin:0 0 12px;font-size:20px;color:var(--fg)">此页需要授权链接</h2>' +
|
|
224
328
|
'<p style="margin:0 0 24px;line-height:1.7;color:var(--muted);font-size:14px">' +
|
|
225
329
|
'你当前是只读访问,管理页(群角色 / Profiles / Bot 配置 / 团队 / Webhook)需要授权链接。' +
|
|
226
330
|
'运行 <code>botmux dashboard</code> 获取最新链接后即可管理。</p>' +
|
|
227
331
|
'<a href="#/" style="display:inline-block;padding:8px 22px;background:var(--accent);' +
|
|
228
|
-
'color:var(--on-accent);border-radius:
|
|
332
|
+
'color:var(--on-accent);border-radius:var(--radius-lg);text-decoration:none;font-size:14px">返回总览</a>' +
|
|
229
333
|
'</section>';
|
|
230
334
|
}
|
|
231
|
-
// Pages that own a polling loop / cleanup return a disposer; we run it
|
|
232
|
-
// on the next route switch so timers don't leak across navigations.
|
|
233
|
-
const routeState = createDashboardRouteState();
|
|
234
|
-
function highlightNav(hash) {
|
|
235
|
-
for (const a of document.querySelectorAll('.sidebar-nav a')) {
|
|
236
|
-
const href = a.getAttribute('href') ?? '#/';
|
|
237
|
-
const current = hash || '#/';
|
|
238
|
-
const isActive = href === current || (href !== '#/' && (current.startsWith(`${href}?`) || current.startsWith(`${href}/`)));
|
|
239
|
-
a.classList.toggle('active', isActive);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
335
|
async function route() {
|
|
243
336
|
const seq = beginDashboardRoute(routeState);
|
|
244
337
|
const hash = location.hash || '#/';
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
// stuck "link expired" overlay).
|
|
338
|
+
activeHash = hash;
|
|
339
|
+
renderShell();
|
|
248
340
|
if (!isAuthed && MANAGE_ROUTES.some(r => hash.startsWith('#/' + r))) {
|
|
249
|
-
renderAuthRequiredPage(
|
|
341
|
+
renderAuthRequiredPage(getRouteRoot());
|
|
250
342
|
routeState.rerenderOnUiChange = true;
|
|
251
|
-
highlightNav(hash);
|
|
252
343
|
return;
|
|
253
344
|
}
|
|
254
|
-
// The "工作流" nav now points at the v3 runs page (#/workflows). The v2 (v0.2)
|
|
255
|
-
// engine is kept (backend + Feishu cards), so its run-detail page survives at
|
|
256
|
-
// the dedicated #/legacy-workflow route (where v2 cards now link). Legacy URL
|
|
257
|
-
// upkeep so old bookmarks/pasted links don't 404:
|
|
258
|
-
// - `#/v3[/<id>]` → `#/workflows[/<id>]` (v3 promoted)
|
|
259
|
-
// - `#/workflows/catalog`, `#/workflows-catalog` → `#/workflows` (v2 catalog gone)
|
|
260
345
|
if (hash.startsWith('#/v3')) {
|
|
261
346
|
window.location.replace(`#/workflows${hash.slice('#/v3'.length)}`);
|
|
262
347
|
return;
|
|
263
348
|
}
|
|
264
349
|
else if (/^#\/workflows(?:\/|-)catalog(?:[/?].*)?$/.test(hash)) {
|
|
265
|
-
// Bounded match (NOT startsWith): a v3 runId can begin with "catalog"
|
|
266
|
-
// (goal slug → `catalog-all-open-prs-…`), and `#/workflows/catalog-…`
|
|
267
|
-
// must open that run's detail, not bounce to the list.
|
|
268
350
|
window.location.replace('#/workflows');
|
|
269
351
|
return;
|
|
270
352
|
}
|
|
@@ -274,133 +356,64 @@ async function route() {
|
|
|
274
356
|
}
|
|
275
357
|
try {
|
|
276
358
|
const matched = findDashboardRoute(hash);
|
|
277
|
-
await loadAndRenderDashboardRoute(routeState, seq,
|
|
359
|
+
await loadAndRenderDashboardRoute(routeState, seq, getRouteRoot(), matched ? matched.load : loadOverviewPage, { rerenderOnUiChange: matched ? matched.rerenderOnUiChange : false });
|
|
278
360
|
}
|
|
279
361
|
catch (err) {
|
|
280
362
|
if (seq !== routeState.seq)
|
|
281
363
|
return;
|
|
282
|
-
|
|
364
|
+
getRouteRoot().innerHTML = `<section class="page"><div class="empty">Dashboard route failed: ${escapeHtml(String(err))}</div></section>`;
|
|
283
365
|
routeState.pageDispose = null;
|
|
284
366
|
routeState.rerenderOnUiChange = true;
|
|
285
367
|
}
|
|
286
|
-
finally {
|
|
287
|
-
if (seq === routeState.seq)
|
|
288
|
-
highlightNav(hash);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
const statusEl = document.getElementById('status');
|
|
292
|
-
function paintStatus() {
|
|
293
|
-
if (!statusEl)
|
|
294
|
-
return;
|
|
295
|
-
statusEl.textContent = store.online ? t('status.live') : t('status.disconnected');
|
|
296
|
-
statusEl.className = 'connection-status ' + (store.online ? 'online' : 'offline');
|
|
297
|
-
}
|
|
298
|
-
store.on(paintStatus);
|
|
299
|
-
function paintChrome() {
|
|
300
|
-
document.querySelectorAll('[data-i18n]').forEach(el => {
|
|
301
|
-
el.textContent = t(el.dataset.i18n ?? '');
|
|
302
|
-
});
|
|
303
|
-
document.querySelectorAll('[data-locale]').forEach(btn => {
|
|
304
|
-
btn.classList.toggle('active', btn.dataset.locale === ui.locale);
|
|
305
|
-
});
|
|
306
|
-
paintThemeMenu();
|
|
307
|
-
paintStatus();
|
|
308
|
-
}
|
|
309
|
-
function wireChromeControls() {
|
|
310
|
-
document.querySelectorAll('[data-locale]').forEach(btn => {
|
|
311
|
-
btn.onclick = () => {
|
|
312
|
-
const locale = btn.dataset.locale;
|
|
313
|
-
ui.setLocale(locale);
|
|
314
|
-
void persistLocale(locale);
|
|
315
|
-
};
|
|
316
|
-
});
|
|
317
|
-
initThemeMenu();
|
|
318
|
-
wireSidebarToggle();
|
|
319
368
|
}
|
|
320
|
-
|
|
321
|
-
// 防闪烁,再后台刷新;拿不到(未绑定 owner / 只读访客 401)保持渐变球。
|
|
322
|
-
const OWNER_AVATAR_KEY = 'botmux.ownerAvatar.v1';
|
|
323
|
-
function paintOwnerAvatar(avatarUrl, name) {
|
|
324
|
-
const mark = document.querySelector('.brand-mark');
|
|
325
|
-
if (!mark || !avatarUrl)
|
|
326
|
-
return;
|
|
327
|
-
mark.innerHTML = `<img class="brand-owner-img" src="${escapeHtml(avatarUrl)}" alt="" decoding="async" referrerpolicy="no-referrer" onerror="this.remove()">`;
|
|
328
|
-
if (name)
|
|
329
|
-
mark.title = name;
|
|
330
|
-
}
|
|
331
|
-
function initOwnerAvatar() {
|
|
369
|
+
function readCachedOwnerAvatar() {
|
|
332
370
|
try {
|
|
333
371
|
const cached = JSON.parse(window.localStorage.getItem(OWNER_AVATAR_KEY) ?? 'null');
|
|
334
|
-
if (cached?.avatarUrl)
|
|
335
|
-
|
|
372
|
+
if (cached?.avatarUrl) {
|
|
373
|
+
return {
|
|
374
|
+
avatarUrl: String(cached.avatarUrl),
|
|
375
|
+
name: cached.name ? String(cached.name) : undefined,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
336
378
|
}
|
|
337
|
-
catch { /*
|
|
379
|
+
catch { /* ignore corrupt cache */ }
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
function initOwnerAvatar() {
|
|
383
|
+
ownerAvatar = readCachedOwnerAvatar();
|
|
384
|
+
renderShell();
|
|
338
385
|
void fetch('/api/owner-profile')
|
|
339
386
|
.then(r => (r.ok ? r.json() : null))
|
|
340
387
|
.then(body => {
|
|
341
388
|
if (!body?.ok || !body.avatarUrl)
|
|
342
389
|
return;
|
|
343
|
-
|
|
390
|
+
ownerAvatar = { avatarUrl: String(body.avatarUrl), name: body.name ? String(body.name) : undefined };
|
|
344
391
|
try {
|
|
345
392
|
window.localStorage.setItem(OWNER_AVATAR_KEY, JSON.stringify({ avatarUrl: body.avatarUrl, name: body.name ?? '' }));
|
|
346
393
|
}
|
|
347
|
-
catch { /*
|
|
394
|
+
catch { /* ignore */ }
|
|
395
|
+
renderShell();
|
|
348
396
|
})
|
|
349
397
|
.catch(() => { });
|
|
350
398
|
}
|
|
351
|
-
// 左侧菜单栏收起/展开:状态挂在 <html data-sidebar>,CSS 收窄成图标栏;
|
|
352
|
-
// 偏好进 localStorage,刷新/换页保持。
|
|
353
|
-
function wireSidebarToggle() {
|
|
354
|
-
const btn = document.getElementById('sidebar-toggle');
|
|
355
|
-
if (!btn)
|
|
356
|
-
return;
|
|
357
|
-
let mode = readStoredSidebarMode(window.localStorage);
|
|
358
|
-
const apply = () => {
|
|
359
|
-
document.documentElement.dataset.sidebar = mode;
|
|
360
|
-
btn.title = t(mode === 'collapsed' ? 'nav.sidebarExpand' : 'nav.sidebarCollapse');
|
|
361
|
-
};
|
|
362
|
-
apply();
|
|
363
|
-
btn.addEventListener('click', () => {
|
|
364
|
-
mode = mode === 'collapsed' ? 'expanded' : 'collapsed';
|
|
365
|
-
writeStoredSidebarMode(window.localStorage, mode);
|
|
366
|
-
apply();
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
// 全局顶栏「创建会话」按钮:点击时按需动态 import 较重的 sessions 模块并拉起弹窗,
|
|
370
|
-
// 让创建逻辑留在懒加载 chunk 里、不撑大主包(对应 wireBotOnboardingButton,但走懒加载)。
|
|
371
|
-
function wireCreateSessionButton() {
|
|
372
|
-
const btn = document.getElementById('create-session-btn');
|
|
373
|
-
if (!btn)
|
|
374
|
-
return;
|
|
375
|
-
btn.onclick = async () => {
|
|
376
|
-
btn.disabled = true;
|
|
377
|
-
try {
|
|
378
|
-
const mod = await import('./sessions.js');
|
|
379
|
-
await mod.openCreateSessionModal();
|
|
380
|
-
}
|
|
381
|
-
finally {
|
|
382
|
-
btn.disabled = false;
|
|
383
|
-
}
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
// Keep bootstrap sequencing explicit even though the dashboard bundle is ESM.
|
|
387
399
|
void (async () => {
|
|
388
400
|
ui.init();
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
401
|
+
const host = document.getElementById('app-root');
|
|
402
|
+
if (!host)
|
|
403
|
+
throw new Error('missing dashboard app root');
|
|
404
|
+
initFloatingScrollbars(host);
|
|
405
|
+
appRoot = createRoot(host);
|
|
406
|
+
renderShell();
|
|
392
407
|
ui.on(() => {
|
|
393
|
-
|
|
394
|
-
paintAttentionStrip();
|
|
408
|
+
renderShell();
|
|
395
409
|
if (routeState.rerenderOnUiChange)
|
|
396
410
|
void route();
|
|
397
411
|
});
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
// hidden and route guards are active for read-only visitors from frame one.
|
|
412
|
+
store.on(() => {
|
|
413
|
+
renderShell();
|
|
414
|
+
});
|
|
402
415
|
await loadAuthState();
|
|
403
|
-
|
|
416
|
+
renderShell();
|
|
404
417
|
void checkUpdateBadge();
|
|
405
418
|
initOwnerAvatar();
|
|
406
419
|
try {
|
|
@@ -410,7 +423,9 @@ void (async () => {
|
|
|
410
423
|
console.error('botmux dashboard bootstrap failed', err);
|
|
411
424
|
store.setOnline(false);
|
|
412
425
|
}
|
|
413
|
-
|
|
426
|
+
void loadNameMaps().then(renderShell);
|
|
427
|
+
void loadGroupsSnapshot().then(renderShell);
|
|
428
|
+
window.addEventListener('hashchange', () => { void route(); });
|
|
414
429
|
void route();
|
|
415
430
|
})();
|
|
416
431
|
//# sourceMappingURL=app.js.map
|