@songsid/agend 2.3.0-beta.2 → 2.3.0-beta.20
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.md +7 -1
- package/README.zh-TW.md +7 -1
- package/dist/agent-cli-instructions.md +9 -2
- package/dist/agent-cli.js +63 -2
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +4 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-file-read.d.ts +4 -1
- package/dist/agent-file-read.js +189 -16
- package/dist/agent-file-read.js.map +1 -1
- package/dist/agent-whats-new.d.ts +11 -0
- package/dist/agent-whats-new.js +29 -5
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/auth-api.d.ts +30 -1
- package/dist/auth-api.js +45 -13
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/authority-state.d.ts +38 -0
- package/dist/authority/authority-state.js +114 -0
- package/dist/authority/authority-state.js.map +1 -0
- package/dist/authority/session-authorizations.d.ts +43 -0
- package/dist/authority/session-authorizations.js +102 -0
- package/dist/authority/session-authorizations.js.map +1 -0
- package/dist/authority/web-authority.d.ts +120 -0
- package/dist/authority/web-authority.js +157 -0
- package/dist/authority/web-authority.js.map +1 -0
- package/dist/backend/claude-code.d.ts +2 -2
- package/dist/backend/claude-code.js +18 -8
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-metadata.d.ts +8 -0
- package/dist/backend/codex-metadata.js +74 -17
- package/dist/backend/codex-metadata.js.map +1 -1
- package/dist/backend/codex.js +15 -2
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/credential-profile.d.ts +2 -0
- package/dist/backend/credential-profile.js +2 -0
- package/dist/backend/credential-profile.js.map +1 -1
- package/dist/backend/types.d.ts +6 -0
- package/dist/backend/types.js +15 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/backend-availability.d.ts +120 -0
- package/dist/backend-availability.js +396 -0
- package/dist/backend-availability.js.map +1 -0
- package/dist/backend-command.d.ts +23 -3
- package/dist/backend-command.js +25 -4
- package/dist/backend-command.js.map +1 -1
- package/dist/bug-report-cli.d.ts +30 -0
- package/dist/bug-report-cli.js +138 -0
- package/dist/bug-report-cli.js.map +1 -0
- package/dist/bug-report.d.ts +47 -0
- package/dist/bug-report.js +136 -0
- package/dist/bug-report.js.map +1 -0
- package/dist/bundled-skills.d.ts +14 -0
- package/dist/bundled-skills.js +29 -0
- package/dist/bundled-skills.js.map +1 -0
- package/dist/cache-ledger.d.ts +16 -3
- package/dist/cache-ledger.js +33 -13
- package/dist/cache-ledger.js.map +1 -1
- package/dist/cache-service.d.ts +55 -3
- package/dist/cache-service.js +152 -16
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord-client-retirement.d.ts +5 -0
- package/dist/channel/adapters/discord-client-retirement.js +57 -0
- package/dist/channel/adapters/discord-client-retirement.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +9 -0
- package/dist/channel/adapters/discord.js +49 -4
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/mcp-tools.js +22 -11
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/types.d.ts +6 -0
- package/dist/classic-channel-manager.d.ts +10 -5
- package/dist/classic-channel-manager.js +12 -9
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +224 -111
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.d.ts +6 -0
- package/dist/config-validator.js +129 -3
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +13 -1
- package/dist/config.js +14 -5
- package/dist/config.js.map +1 -1
- package/dist/cross-instance-notice.d.ts +7 -0
- package/dist/cross-instance-notice.js +10 -0
- package/dist/cross-instance-notice.js.map +1 -1
- package/dist/daemon.d.ts +24 -1
- package/dist/daemon.js +151 -19
- package/dist/daemon.js.map +1 -1
- package/dist/decision-list.d.ts +25 -0
- package/dist/decision-list.js +30 -0
- package/dist/decision-list.js.map +1 -0
- package/dist/delivery-outbox.d.ts +10 -0
- package/dist/delivery-outbox.js +17 -1
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/diagnostic-redaction.d.ts +10 -0
- package/dist/diagnostic-redaction.js +167 -0
- package/dist/diagnostic-redaction.js.map +1 -0
- package/dist/fleet-context.d.ts +10 -0
- package/dist/fleet-manager.d.ts +505 -15
- package/dist/fleet-manager.js +1870 -204
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.d.ts +18 -0
- package/dist/fleet-process-handlers.js +69 -0
- package/dist/fleet-process-handlers.js.map +1 -0
- package/dist/fleet-traffic.d.ts +74 -0
- package/dist/fleet-traffic.js +196 -0
- package/dist/fleet-traffic.js.map +1 -0
- package/dist/general-knowledge/skills/bug-report/SKILL.md +31 -0
- package/dist/general-knowledge/skills/credential-profiles/SKILL.md +17 -6
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +6 -1
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +2 -0
- package/dist/general-knowledge/skills/multi-channel/SKILL.md +3 -2
- package/dist/general-knowledge/skills/persona-emoji/SKILL.md +1 -1
- package/dist/general-knowledge/skills/scheduling/SKILL.md +4 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +190 -47
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +545 -0
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/human-delivery-receipts.d.ts +24 -1
- package/dist/human-delivery-receipts.js +64 -11
- package/dist/human-delivery-receipts.js.map +1 -1
- package/dist/instance-config-impact.js +7 -1
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +10 -1
- package/dist/instance-lifecycle.js +79 -18
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instance-names.d.ts +4 -0
- package/dist/instance-names.js +12 -0
- package/dist/instance-names.js.map +1 -0
- package/dist/instructions.d.ts +12 -1
- package/dist/instructions.js +13 -2
- package/dist/instructions.js.map +1 -1
- package/dist/locale.js +173 -12
- package/dist/locale.js.map +1 -1
- package/dist/log-steps.d.ts +1 -0
- package/dist/log-steps.js +15 -0
- package/dist/log-steps.js.map +1 -1
- package/dist/login-controller.d.ts +45 -0
- package/dist/login-controller.js +101 -5
- package/dist/login-controller.js.map +1 -1
- package/dist/ls-attach-resolve.d.ts +96 -0
- package/dist/ls-attach-resolve.js +180 -0
- package/dist/ls-attach-resolve.js.map +1 -0
- package/dist/ls-rows.d.ts +12 -0
- package/dist/ls-rows.js +82 -3
- package/dist/ls-rows.js.map +1 -1
- package/dist/memory-hogs.d.ts +27 -0
- package/dist/memory-hogs.js +124 -0
- package/dist/memory-hogs.js.map +1 -0
- package/dist/needs-you.d.ts +10 -0
- package/dist/needs-you.js +2 -1
- package/dist/needs-you.js.map +1 -1
- package/dist/outbound-handlers.d.ts +11 -0
- package/dist/outbound-handlers.js +139 -11
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +200 -4
- package/dist/outbound-schemas.js +124 -11
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +17 -4
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +9 -0
- package/dist/public-web-link.js +8 -0
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.d.ts +19 -1
- package/dist/quickstart-api.js +94 -4
- package/dist/quickstart-api.js.map +1 -1
- package/dist/reply-buttons-controller.d.ts +4 -0
- package/dist/reply-buttons-controller.js +2 -2
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/restart-progress.d.ts +80 -1
- package/dist/restart-progress.js +306 -21
- package/dist/restart-progress.js.map +1 -1
- package/dist/rollout-index.d.ts +5 -0
- package/dist/rollout-index.js +26 -5
- package/dist/rollout-index.js.map +1 -1
- package/dist/scheduler/db.d.ts +40 -13
- package/dist/scheduler/db.js +123 -89
- package/dist/scheduler/db.js.map +1 -1
- package/dist/scheduler/task-board-text.d.ts +26 -0
- package/dist/scheduler/task-board-text.js +135 -0
- package/dist/scheduler/task-board-text.js.map +1 -0
- package/dist/scheduler/task-board.d.ts +650 -0
- package/dist/scheduler/task-board.js +1938 -0
- package/dist/scheduler/task-board.js.map +1 -0
- package/dist/scheduler/types.d.ts +6 -1
- package/dist/search/search-docs.d.ts +58 -0
- package/dist/search/search-docs.js +63 -0
- package/dist/search/search-docs.js.map +1 -0
- package/dist/search/search-index.d.ts +141 -0
- package/dist/search/search-index.js +440 -0
- package/dist/search/search-index.js.map +1 -0
- package/dist/search/search-store.d.ts +122 -0
- package/dist/search/search-store.js +236 -0
- package/dist/search/search-store.js.map +1 -0
- package/dist/search/search-worker.d.ts +1 -0
- package/dist/search/search-worker.js +163 -0
- package/dist/search/search-worker.js.map +1 -0
- package/dist/service-installer.js +12 -0
- package/dist/service-installer.js.map +1 -1
- package/dist/settings-api.d.ts +23 -0
- package/dist/settings-api.js +164 -3
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +104 -0
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-confirmation.d.ts +3 -1
- package/dist/settings-confirmation.js +2 -0
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-effect.js +34 -3
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.d.ts +11 -0
- package/dist/settings-http-confirmation.js +10 -0
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +23 -7
- package/dist/setup-form.js.map +1 -1
- package/dist/spawn-gate.d.ts +1 -0
- package/dist/spawn-gate.js +13 -3
- package/dist/spawn-gate.js.map +1 -1
- package/dist/task-board-tool.d.ts +25 -0
- package/dist/task-board-tool.js +154 -0
- package/dist/task-board-tool.js.map +1 -0
- package/dist/task-board-waker.d.ts +44 -0
- package/dist/task-board-waker.js +128 -0
- package/dist/task-board-waker.js.map +1 -0
- package/dist/tmux-exec-helper.d.ts +94 -0
- package/dist/tmux-exec-helper.js +407 -0
- package/dist/tmux-exec-helper.js.map +1 -0
- package/dist/tmux-manager.d.ts +5 -0
- package/dist/tmux-manager.js +42 -11
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tool-permissions.d.ts +0 -7
- package/dist/tool-permissions.js +44 -5
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +17 -1
- package/dist/topic-commands.js +45 -19
- package/dist/topic-commands.js.map +1 -1
- package/dist/tunnel/cloudflared.js +37 -2
- package/dist/tunnel/cloudflared.js.map +1 -1
- package/dist/tunnel/types.d.ts +3 -1
- package/dist/tunnel/types.js.map +1 -1
- package/dist/types.d.ts +63 -1
- package/dist/ui/app-effects.js +90 -32
- package/dist/ui/backend-signin.js +297 -0
- package/dist/ui/chat-ambient.js +307 -0
- package/dist/ui/chat-effect-posters.js +8 -8
- package/dist/ui/chat-effects.js +110 -15
- package/dist/ui/chat-msg-actions.js +176 -0
- package/dist/ui/chat-render.js +21 -3
- package/dist/ui/chat-store.js +64 -12
- package/dist/ui/chat-strings.js +85 -8
- package/dist/ui/chat-thread.js +204 -21
- package/dist/ui/effect-trial-controller.js +13 -8
- package/dist/ui/effect-trial-panel.js +19 -16
- package/dist/ui/effects-waker.js +70 -0
- package/dist/ui/fleet-canvas-layout.js +117 -0
- package/dist/ui/fleet-canvas.js +555 -0
- package/dist/ui/fleet-org.js +27 -12
- package/dist/ui/fleet-route-scene.js +207 -0
- package/dist/ui/fleet-route-worker.js +21 -0
- package/dist/ui/fleet-route.js +88 -0
- package/dist/ui/fleet-task-card.js +436 -0
- package/dist/ui/fleet-task-common.js +448 -0
- package/dist/ui/fleet-tasks.js +535 -0
- package/dist/ui/fleet-traffic.js +359 -0
- package/dist/ui/fleet-usage.js +435 -0
- package/dist/ui/panel-chat.js +264 -66
- package/dist/ui/panel-details.js +2 -1
- package/dist/ui/panel-fleet.js +65 -83
- package/dist/ui/panel-needs.js +4 -2
- package/dist/ui/panel-settings.js +56 -11
- package/dist/ui/preview.js +3 -2
- package/dist/ui/search-dialog.js +349 -0
- package/dist/ui/settings-appearance.js +44 -19
- package/dist/ui/settings-apply.js +3 -3
- package/dist/ui/settings-catalog.js +92 -0
- package/dist/ui/settings-confirm.js +7 -2
- package/dist/ui/settings-dialogs.js +40 -12
- package/dist/ui/settings-effects.js +4 -3
- package/dist/ui/settings-guests.js +117 -0
- package/dist/ui/settings-learn.js +25 -0
- package/dist/ui/settings-model.js +15 -6
- package/dist/ui/settings-mods.js +23 -9
- package/dist/ui/settings-owner-effects.js +15 -13
- package/dist/ui/settings-strings.js +122 -42
- package/dist/ui/settings-web-authority.js +91 -0
- package/dist/ui/shared/agend-auth.js +1 -1
- package/dist/ui/shared/app-i18n.js +11 -2
- package/dist/ui/shared/app-prefs.js +17 -4
- package/dist/ui/shared/app-route.js +19 -1
- package/dist/ui/shared/app-session.js +2 -0
- package/dist/ui/shared/app-shell.js +174 -30
- package/dist/ui/shared/app-store.js +26 -1
- package/dist/ui/shared/app-stream.js +5 -1
- package/dist/ui/shared/app-themes.js +140 -7
- package/dist/ui/shared/app.css +704 -20
- package/dist/ui/shared/app.js +26 -15
- package/dist/ui/shared/card-strings.js +8 -0
- package/dist/ui/shared/effect-app-runtime.js +68 -19
- package/dist/ui/shared/effect-chat-runtime.js +16 -3
- package/dist/ui/shared/effect-frame.js +26 -7
- package/dist/ui/shared/effect-geometry.js +24 -9
- package/dist/ui/shared/effect-owner-source.js +8 -1
- package/dist/ui/shared/effect-policy.js +21 -7
- package/dist/ui/shared/effect-profiler.js +31 -9
- package/dist/ui/shared/effect-registry.js +97 -50
- package/dist/ui/shared/effect-stock-snapshot.js +9 -0
- package/dist/ui/shared/effect-stock-trust.js +62 -10
- package/dist/ui/shared/effect-trial-shadow.js +62 -0
- package/dist/ui/shared/effect-trial-source.js +1 -1
- package/dist/ui/shared/effect-trial-stage.js +54 -31
- package/dist/ui/shared/effect-trial.css +40 -0
- package/dist/ui/shared/fx-motion.js +67 -0
- package/dist/ui/shared/identity-card.js +100 -11
- package/dist/ui/shared/identity-color.js +14 -10
- package/dist/ui/shared/instance-nav.js +179 -23
- package/dist/ui/shared/owner-css.js +30 -1
- package/dist/ui/shared/panel-view.js +24 -4
- package/dist/ui/shared/tokens.css +9 -3
- package/dist/ui/shared/ui-icons.js +2 -0
- package/dist/ui/shared/ui-menu.js +20 -7
- package/dist/ui/shared/ui-toast.js +16 -3
- package/dist/ui/shared/usage-dialog.js +34 -3
- package/dist/ui/shared/view-strings.js +72 -0
- package/dist/ui/shared/web-authorize.js +198 -0
- package/dist/ui/web-terminal/terminal.css +4 -4
- package/dist/ui/web-terminal/terminal.html +1 -1
- package/dist/update-launch.d.ts +9 -0
- package/dist/update-launch.js +38 -12
- package/dist/update-launch.js.map +1 -1
- package/dist/usage/format-rich.js +6 -3
- package/dist/usage/format-rich.js.map +1 -1
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +2 -1
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/i18n.d.ts +13 -1
- package/dist/usage/i18n.js +29 -0
- package/dist/usage/i18n.js.map +1 -1
- package/dist/usage/providers.d.ts +81 -2
- package/dist/usage/providers.js +240 -38
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/usage-api.d.ts +5 -1
- package/dist/usage/usage-api.js +184 -58
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/usage-report.d.ts +158 -0
- package/dist/usage-report.js +226 -0
- package/dist/usage-report.js.map +1 -0
- package/dist/usage-rollup.d.ts +51 -0
- package/dist/usage-rollup.js +168 -0
- package/dist/usage-rollup.js.map +1 -0
- package/dist/user-systemd.d.ts +24 -0
- package/dist/user-systemd.js +75 -0
- package/dist/user-systemd.js.map +1 -0
- package/dist/view-api.d.ts +39 -0
- package/dist/view-api.js +69 -6
- package/dist/view-api.js.map +1 -1
- package/dist/web-ambient.d.ts +72 -0
- package/dist/web-ambient.js +161 -0
- package/dist/web-ambient.js.map +1 -0
- package/dist/web-api.d.ts +98 -14
- package/dist/web-api.js +1027 -83
- package/dist/web-api.js.map +1 -1
- package/dist/web-appearance-policy.d.ts +4 -6
- package/dist/web-appearance-policy.js +5 -12
- package/dist/web-appearance-policy.js.map +1 -1
- package/dist/web-appearance-tools.d.ts +3 -0
- package/dist/web-appearance-tools.js +22 -3
- package/dist/web-appearance-tools.js.map +1 -1
- package/dist/web-appearance-view.d.ts +27 -2
- package/dist/web-appearance-view.js +129 -14
- package/dist/web-appearance-view.js.map +1 -1
- package/dist/web-appearance.d.ts +17 -3
- package/dist/web-appearance.js +85 -8
- package/dist/web-appearance.js.map +1 -1
- package/dist/web-asset-parts.d.ts +2 -2
- package/dist/web-asset-parts.js +3 -3
- package/dist/web-asset-parts.js.map +1 -1
- package/dist/web-auth.js +3 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-backend-login.d.ts +130 -0
- package/dist/web-backend-login.js +225 -0
- package/dist/web-backend-login.js.map +1 -0
- package/dist/web-card.d.ts +14 -0
- package/dist/web-card.js +40 -6
- package/dist/web-card.js.map +1 -1
- package/dist/web-channel-echo.d.ts +7 -1
- package/dist/web-channel-echo.js +6 -2
- package/dist/web-channel-echo.js.map +1 -1
- package/dist/web-chat-history.d.ts +83 -0
- package/dist/web-chat-history.js +137 -5
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.d.ts +6 -1
- package/dist/web-commands.js +1 -1
- package/dist/web-commands.js.map +1 -1
- package/dist/web-effect-bootstrap.d.ts +12 -0
- package/dist/web-effect-bootstrap.js +49 -0
- package/dist/web-effect-bootstrap.js.map +1 -0
- package/dist/web-effect-bundle.js +46 -1
- package/dist/web-effect-bundle.js.map +1 -1
- package/dist/web-effect-playback.d.ts +30 -0
- package/dist/web-effect-playback.js +71 -0
- package/dist/web-effect-playback.js.map +1 -0
- package/dist/web-effect-profiles.d.ts +4 -4
- package/dist/web-effect-service.d.ts +11 -4
- package/dist/web-effect-service.js +25 -4
- package/dist/web-effect-service.js.map +1 -1
- package/dist/web-effect-tools.d.ts +1 -0
- package/dist/web-effect-tools.js +4 -4
- package/dist/web-effect-tools.js.map +1 -1
- package/dist/web-effect-trials.d.ts +2 -2
- package/dist/web-effect-trials.js +3 -3
- package/dist/web-effect-trials.js.map +1 -1
- package/dist/web-effect-upload.js +1 -1
- package/dist/web-effect-upload.js.map +1 -1
- package/dist/web-effect-worker.d.ts +1 -1
- package/dist/web-effect-worker.js +2 -2
- package/dist/web-effect-worker.js.map +1 -1
- package/dist/web-effect.d.ts +1 -1
- package/dist/web-guest-access.d.ts +126 -0
- package/dist/web-guest-access.js +238 -0
- package/dist/web-guest-access.js.map +1 -0
- package/dist/web-guest-rooms.d.ts +82 -0
- package/dist/web-guest-rooms.js +135 -0
- package/dist/web-guest-rooms.js.map +1 -0
- package/dist/web-host-guard.d.ts +11 -0
- package/dist/web-host-guard.js +11 -0
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-identity-color.d.ts +1 -1
- package/dist/web-identity-color.js +2 -2
- package/dist/web-identity-color.js.map +1 -1
- package/dist/web-identity-palette.d.ts +1 -1
- package/dist/web-identity-palette.js +2 -2
- package/dist/web-identity-palette.js.map +1 -1
- package/dist/web-image-meta.d.ts +13 -0
- package/dist/web-image-meta.js +62 -0
- package/dist/web-image-meta.js.map +1 -1
- package/dist/web-libavoid.d.ts +14 -0
- package/dist/web-libavoid.js +46 -0
- package/dist/web-libavoid.js.map +1 -0
- package/dist/web-login.d.ts +47 -0
- package/dist/web-login.js +115 -0
- package/dist/web-login.js.map +1 -1
- package/dist/web-mod-agent.d.ts +1 -1
- package/dist/web-mod-agent.js +7 -5
- package/dist/web-mod-agent.js.map +1 -1
- package/dist/web-mod-bundle.d.ts +9 -1
- package/dist/web-mod-bundle.js +62 -3
- package/dist/web-mod-bundle.js.map +1 -1
- package/dist/web-mod-export.d.ts +9 -0
- package/dist/web-mod-export.js +21 -0
- package/dist/web-mod-export.js.map +1 -1
- package/dist/web-mod-store.d.ts +7 -1
- package/dist/web-mod-store.js +19 -6
- package/dist/web-mod-store.js.map +1 -1
- package/dist/web-owner-css-store.d.ts +44 -1
- package/dist/web-owner-css-store.js +70 -9
- package/dist/web-owner-css-store.js.map +1 -1
- package/dist/web-prefs.d.ts +14 -0
- package/dist/web-prefs.js +37 -4
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-preview.d.ts +6 -2
- package/dist/web-preview.js +4 -2
- package/dist/web-preview.js.map +1 -1
- package/dist/web-returning-device.d.ts +41 -0
- package/dist/web-returning-device.js +57 -5
- package/dist/web-returning-device.js.map +1 -1
- package/dist/web-session-authorization.d.ts +132 -0
- package/dist/web-session-authorization.js +193 -0
- package/dist/web-session-authorization.js.map +1 -0
- package/dist/web-session.d.ts +70 -10
- package/dist/web-session.js +137 -22
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +49 -2
- package/dist/web-settings-patch.js +145 -1
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-settings-tools.d.ts +94 -0
- package/dist/web-settings-tools.js +301 -0
- package/dist/web-settings-tools.js.map +1 -0
- package/dist/web-shell-routes.d.ts +1 -1
- package/dist/web-shell-routes.js +1 -1
- package/dist/web-shell-routes.js.map +1 -1
- package/dist/web-terminal-http.js +15 -2
- package/dist/web-terminal-http.js.map +1 -1
- package/dist/web-theme-store.d.ts +39 -0
- package/dist/web-theme-store.js +122 -11
- package/dist/web-theme-store.js.map +1 -1
- package/dist/web-theme.d.ts +31 -0
- package/dist/web-theme.js +99 -2
- package/dist/web-theme.js.map +1 -1
- package/dist/web-upload.d.ts +13 -0
- package/dist/web-upload.js +39 -3
- package/dist/web-upload.js.map +1 -1
- package/dist/windows-shortcuts.d.ts +78 -0
- package/dist/windows-shortcuts.js +203 -0
- package/dist/windows-shortcuts.js.map +1 -0
- package/dist/workflow-templates/default.md +4 -1
- package/dist/yaml-shared-nodes.d.ts +25 -0
- package/dist/yaml-shared-nodes.js +185 -0
- package/dist/yaml-shared-nodes.js.map +1 -0
- package/launcher/agend-install.cjs +553 -0
- package/launcher/install-admission.cjs +4 -39
- package/launcher/postinstall.cjs +14 -12
- package/package.json +4 -2
- package/scripts/preinstall-guard.cjs +2 -5
- package/templates/windows-shortcuts.ps1 +181 -0
- package/launcher/old-updater-note.cjs +0 -48
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
// #1918 phase 3: live cross-instance traffic on the org canvas (fleet-canvas.js) — what src/fleet-traffic.ts sends: the
|
|
2
|
+
// stream's `traffic` items, and GET /ui/traffic's snapshot when the tab opens (and on the public link, which has no
|
|
3
|
+
// stream, every POLL_MS while the page is shown — the user's decision 1). Ids are opaque; there is never any text.
|
|
4
|
+
//
|
|
5
|
+
// - The store keeps each message's latest state: queued (a dotted line), delivering (a dash and a pulse), delivered
|
|
6
|
+
// or consumed (the line stays FADE_MS while it fades, then goes — long enough to see: an MCP send is delivered and
|
|
7
|
+
// read almost at once); failed, uncertain or cancelled ends it at once (a failed or uncertain delivery is Needs you's
|
|
8
|
+
// to show, #1386). A finished message never comes back.
|
|
9
|
+
// - And the work (the server's Delegations, stream event `delegation`, the snapshot's `delegations`): a task's
|
|
10
|
+
// delegator → worker line stays, "in progress" (a moving dash), until its report comes back; then a short return
|
|
11
|
+
// pulse worker → delegator (RETURN_MS), and it goes. One that waits past DELEGATION_TTL_MS fades as "no report yet".
|
|
12
|
+
// - Every line ends on something drawn: a card, or a folded team's box (a name not on the canvas draws nothing), and
|
|
13
|
+
// runs through lanes that touch the boxes it joins — two cards in one box are joined inside it.
|
|
14
|
+
// - Edges are routed metro-style through the lanes the layout keeps empty (beside the columns and between card rows
|
|
15
|
+
// inside a box; the bus above each row of teams; the trunk at the left), so a line never crosses a card.
|
|
16
|
+
// - Near: one edge per (from, to, kind, phase), ×N when several share it. Far (zoomed out): one edge per team pair.
|
|
17
|
+
// A broadcast (one message per recipient, sharing an `op`) is a fan-out from its sender; more than BUNDLE_AT
|
|
18
|
+
// recipients, or far, it is one edge per recipient team, ×N (the user's decision 3). At most MAX_EDGES are drawn.
|
|
19
|
+
import { OC } from "./fleet-canvas-layout.js";
|
|
20
|
+
|
|
21
|
+
export const FADE_MS = 12000;
|
|
22
|
+
export const RETURN_MS = 2400;
|
|
23
|
+
/** As the server's (src/fleet-traffic.ts): how long a delegation waits for its report. */
|
|
24
|
+
export const DELEGATION_TTL_MS = 4 * 3_600_000;
|
|
25
|
+
export const POLL_MS = 5000;
|
|
26
|
+
export const MAX_EDGES = 60;
|
|
27
|
+
export const BUNDLE_AT = 8;
|
|
28
|
+
export const FAR_K = 0.55;
|
|
29
|
+
const MAX_ITEMS = 400, MAX_DONE = 2000, MAX_WORK = 200;
|
|
30
|
+
const DSTATES = new Set(["open", "done", "expired", "cancelled"]);
|
|
31
|
+
const LIVE = new Set(["queued", "delivering"]);
|
|
32
|
+
const ENDS = new Set(["failed", "uncertain", "cancelled"]);
|
|
33
|
+
/** Delivered, or read: the line fades out (FADE_MS). */
|
|
34
|
+
const SETTLED = new Set(["delivered", "consumed"]);
|
|
35
|
+
const KINDS = new Set(["task", "report", "query", "update", "send", "broadcast"]);
|
|
36
|
+
const mono = () => (typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now());
|
|
37
|
+
|
|
38
|
+
/** A traffic item as the server sends it, checked; null for anything else. */
|
|
39
|
+
export function itemOk(x) {
|
|
40
|
+
if (!x || typeof x !== "object") return null;
|
|
41
|
+
const { id, from, to, kind, state, op } = x;
|
|
42
|
+
if (typeof id !== "string" || !/^[0-9a-f]{16}$/.test(id) || typeof from !== "string" || !from || typeof to !== "string" || !to) return null;
|
|
43
|
+
if (!KINDS.has(kind) || !(LIVE.has(state) || SETTLED.has(state) || ENDS.has(state))) return null;
|
|
44
|
+
return { id, from, to, kind, state, ...(typeof op === "string" && /^[0-9a-f]{16}$/.test(op) ? { op } : {}) };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** A delegation as the server sends it, checked; null for anything else. */
|
|
48
|
+
export function delegationOk(x) {
|
|
49
|
+
if (!x || typeof x !== "object") return null;
|
|
50
|
+
const { id, from, to, state, age_ms } = x;
|
|
51
|
+
if (typeof id !== "string" || !/^[0-9a-f]{16}$/.test(id) || typeof from !== "string" || !from || typeof to !== "string" || !to || from === to) return null;
|
|
52
|
+
if (!DSTATES.has(state) || typeof age_ms !== "number" || !Number.isFinite(age_ms) || age_ms < 0) return null;
|
|
53
|
+
return { id, from, to, state, age: age_ms };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The page's traffic: `apply(item, nowMs)` one stream item, `delegation(d, nowMs)` one delegation event,
|
|
58
|
+
* `load(snapshot, nowMs, since)` a snapshot, `sweep(nowMs)` drops faded lines; each returns whether anything shown
|
|
59
|
+
* changed. `items()` what to draw: { …item, fading }. `streamRev()` counts the stream's events: a snapshot asked for
|
|
60
|
+
* before the latest one (`since` older than it) may be older than what the stream already said, so it adds only what
|
|
61
|
+
* is new and ends or rewinds nothing (#2135 review).
|
|
62
|
+
* Ended work is remembered (bounded): a late snapshot never draws a delegation that is done, expired or taken back.
|
|
63
|
+
*/
|
|
64
|
+
export function createTrafficStore() {
|
|
65
|
+
const items = new Map(); // id → { item, fadeAt }
|
|
66
|
+
const work = new Map(); // delegation id → { d, phase: "work" | "return" | "stale", until }
|
|
67
|
+
const done = new Set(); // message ids that ended: a late item for one is ignored
|
|
68
|
+
const ended = new Set(); // delegation ids that ended: never drawn in progress again
|
|
69
|
+
let rev = 0;
|
|
70
|
+
const finish = (id) => {
|
|
71
|
+
items.delete(id);
|
|
72
|
+
done.add(id);
|
|
73
|
+
if (done.size > MAX_DONE) done.delete(done.values().next().value);
|
|
74
|
+
};
|
|
75
|
+
const end = (id) => {
|
|
76
|
+
ended.add(id);
|
|
77
|
+
if (ended.size > MAX_DONE) ended.delete(ended.values().next().value);
|
|
78
|
+
};
|
|
79
|
+
const applyItem = (raw, now) => {
|
|
80
|
+
const it = itemOk(raw);
|
|
81
|
+
if (!it || done.has(it.id)) return false;
|
|
82
|
+
const prev = items.get(it.id);
|
|
83
|
+
if (ENDS.has(it.state)) { const had = !!prev; finish(it.id); return had; }
|
|
84
|
+
if (prev && prev.fadeAt !== null) return false; // fading: never goes back, nor starts again
|
|
85
|
+
if (prev && prev.item.state === it.state) return false;
|
|
86
|
+
if (it.state === "consumed" && !prev) { finish(it.id); return false; } // read before this page drew it
|
|
87
|
+
items.delete(it.id);
|
|
88
|
+
// A message keeps what it was (from, to, kind) through its states; only the state moves.
|
|
89
|
+
items.set(it.id, { item: prev ? { ...prev.item, state: it.state } : it, fadeAt: SETTLED.has(it.state) ? now + FADE_MS : null });
|
|
90
|
+
while (items.size > MAX_ITEMS) items.delete(items.keys().next().value);
|
|
91
|
+
return true;
|
|
92
|
+
};
|
|
93
|
+
const applyDelegation = (raw, now) => {
|
|
94
|
+
const d = delegationOk(raw);
|
|
95
|
+
if (!d || ended.has(d.id)) return false;
|
|
96
|
+
const prev = work.get(d.id);
|
|
97
|
+
if (d.state === "open") {
|
|
98
|
+
if (prev) return false;
|
|
99
|
+
work.set(d.id, { d, phase: "work", until: now + Math.max(0, DELEGATION_TTL_MS - d.age) });
|
|
100
|
+
while (work.size > MAX_WORK) { const oldest = work.keys().next().value; work.delete(oldest); end(oldest); }
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
end(d.id);
|
|
104
|
+
if (d.state === "cancelled") return work.delete(d.id);
|
|
105
|
+
if (d.state === "done") { work.set(d.id, { d, phase: "return", until: now + RETURN_MS }); return true; }
|
|
106
|
+
if (!prev || prev.phase !== "work") return false; // expired: only one this page shows
|
|
107
|
+
work.set(d.id, { d, phase: "stale", until: now + FADE_MS });
|
|
108
|
+
return true;
|
|
109
|
+
};
|
|
110
|
+
const store = {
|
|
111
|
+
apply(raw, now = mono()) { rev++; return applyItem(raw, now); },
|
|
112
|
+
delegation(raw, now = mono()) { rev++; return applyDelegation(raw, now); },
|
|
113
|
+
streamRev: () => rev,
|
|
114
|
+
/**
|
|
115
|
+
* A snapshot is the truth for what is in flight: anything live it no longer lists has ended (missed while away) —
|
|
116
|
+
* unless the stream has spoken since it was asked for (`since`): then it may be older than what is drawn, and only
|
|
117
|
+
* what is new to this page is taken from it.
|
|
118
|
+
*/
|
|
119
|
+
load(snap, now = mono(), since = rev) {
|
|
120
|
+
const fresh = since === rev;
|
|
121
|
+
const list = snap && Array.isArray(snap.items) ? snap.items.map(itemOk).filter(Boolean) : [];
|
|
122
|
+
const listed = new Set(list.map((i) => i.id));
|
|
123
|
+
let changed = false;
|
|
124
|
+
if (fresh) for (const [id, e] of items) if (!listed.has(id) && LIVE.has(e.item.state)) { finish(id); changed = true; }
|
|
125
|
+
// Delivered or read, for a line drawn here: it fades now (with no stream, the snapshot is the only news of it). Any
|
|
126
|
+
// other finished message is not drawn (it finished up to two minutes ago), and an ended one goes.
|
|
127
|
+
for (const it of list) {
|
|
128
|
+
if (!fresh && items.has(it.id)) continue; // the stream knows it better
|
|
129
|
+
if (LIVE.has(it.state) || (SETTLED.has(it.state) && items.has(it.id))) changed = applyItem(it, now) || changed;
|
|
130
|
+
else if (fresh) { const had = items.has(it.id); finish(it.id); changed = changed || had; }
|
|
131
|
+
}
|
|
132
|
+
// The open delegations: the snapshot's list is the truth (one it no longer lists ended while this page was away).
|
|
133
|
+
const open = snap && Array.isArray(snap.delegations) ? snap.delegations.filter((d) => delegationOk(d)?.state === "open") : [];
|
|
134
|
+
const ids = new Set(open.map((d) => d.id));
|
|
135
|
+
if (fresh) for (const [id, e] of work) if (e.phase === "work" && !ids.has(id)) { work.delete(id); end(id); changed = true; }
|
|
136
|
+
for (const d of open) changed = applyDelegation(d, now) || changed;
|
|
137
|
+
return changed;
|
|
138
|
+
},
|
|
139
|
+
sweep(now = mono()) {
|
|
140
|
+
let changed = false;
|
|
141
|
+
for (const [id, e] of items) if (e.fadeAt !== null && now >= e.fadeAt) { finish(id); changed = true; }
|
|
142
|
+
for (const [id, e] of work) {
|
|
143
|
+
if (now < e.until) continue;
|
|
144
|
+
if (e.phase === "work") { end(id); work.set(id, { ...e, phase: "stale", until: now + FADE_MS }); } // its wait ran out here
|
|
145
|
+
else work.delete(id);
|
|
146
|
+
changed = true;
|
|
147
|
+
}
|
|
148
|
+
return changed;
|
|
149
|
+
},
|
|
150
|
+
/** What to draw: the messages, then the work (a done one is its return, worker → delegator). */
|
|
151
|
+
items: () => [...[...items.values()].map((e) => ({ ...e.item, fading: e.fadeAt !== null })),
|
|
152
|
+
...[...work.values()].map(({ d, phase }) => phase === "return"
|
|
153
|
+
? { id: `r${d.id}`, from: d.to, to: d.from, kind: "report", state: "delivering", phase, fading: false }
|
|
154
|
+
: { id: `w${d.id}`, from: d.from, to: d.to, kind: "task", state: "delivering", phase, fading: false })],
|
|
155
|
+
fadingCount: () => [...items.values()].filter((e) => e.fadeAt !== null).length,
|
|
156
|
+
};
|
|
157
|
+
return store;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// ── Where a name is on the canvas ──
|
|
161
|
+
|
|
162
|
+
/** The team a name is drawn in (its first, if it is in two), null for General, undefined when it is not on the canvas. */
|
|
163
|
+
function teamOf(L, name) {
|
|
164
|
+
if (L.tops.some((c) => c.node.name === name)) return null;
|
|
165
|
+
const b = L.boxes.find((x) => x.nodes.some((n) => n.name === name));
|
|
166
|
+
return b ? b : undefined;
|
|
167
|
+
}
|
|
168
|
+
/** An end of a line: General's card, a member's card, or its folded team's box. */
|
|
169
|
+
function endOf(L, name) {
|
|
170
|
+
const top = L.tops.find((c) => c.node.name === name);
|
|
171
|
+
if (top) return { kind: "top", c: top, key: top.key };
|
|
172
|
+
const b = teamOf(L, name);
|
|
173
|
+
if (!b) return null;
|
|
174
|
+
if (b.folded) return { kind: "box", b, key: `box:${b.key}` };
|
|
175
|
+
const i = b.cells.findIndex((c) => c.node.name === name);
|
|
176
|
+
return { kind: "cell", b, i, c: b.cells[i], key: b.cells[i].key };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ── Routing: lanes the layout keeps empty ──
|
|
180
|
+
|
|
181
|
+
/** A side lane's offset from the middle of the box's padding: at least 6 px from the box's border and from its cards. */
|
|
182
|
+
const laneOffset = (o, PAD = OC.PAD) => Math.max(-PAD / 2 + 6, Math.min(PAD / 2 - 6, o * 0.5));
|
|
183
|
+
/** The layout's own box padding and gutter (a phone's are narrower). */
|
|
184
|
+
const spacing = (L) => ({ PAD: L.pad ?? OC.PAD, GAP: L.gap ?? OC.GAP });
|
|
185
|
+
|
|
186
|
+
const firstBusOf = (L) => Math.min(...L.boxes.map((b) => b.busY));
|
|
187
|
+
/** From an end up to its row's bus lane: the points, and the lane's y. `o` spreads lines sharing a lane. */
|
|
188
|
+
function outward(L, end, o) {
|
|
189
|
+
if (end.kind === "top") {
|
|
190
|
+
const x = end.c.x + end.c.w / 2 + Math.max(-end.c.w / 2 + 12, Math.min(end.c.w / 2 - 12, o * 2.4));
|
|
191
|
+
const bus = firstBusOf(L) + o;
|
|
192
|
+
return { pts: [{ x, y: end.c.y + end.c.h }, { x, y: bus }], bus };
|
|
193
|
+
}
|
|
194
|
+
const b = end.b;
|
|
195
|
+
if (end.kind === "box") {
|
|
196
|
+
const x = b.x + b.w / 2 + o * 1.5;
|
|
197
|
+
return { pts: [{ x, y: b.y }, { x, y: b.busY + o }], bus: b.busY + o };
|
|
198
|
+
}
|
|
199
|
+
const { NW, NH } = OC, { PAD, GAP } = spacing(L);
|
|
200
|
+
const card = end.c, col = end.i % b.cols, rowI = Math.floor(end.i / b.cols), lines = Math.ceil(b.cells.length / b.cols);
|
|
201
|
+
const io = laneOffset(o, PAD);
|
|
202
|
+
const leftLane = b.x + PAD / 2 + io, rightLane = b.x + b.w - PAD / 2 + io;
|
|
203
|
+
let pts;
|
|
204
|
+
if (col === 0 || col === b.cols - 1) {
|
|
205
|
+
const left = col === 0, lane = left ? leftLane : rightLane, cy = card.y + NH / 2 + io;
|
|
206
|
+
pts = [{ x: left ? card.x : card.x + NW, y: cy }, { x: lane, y: cy }, { x: lane, y: b.y }];
|
|
207
|
+
} else {
|
|
208
|
+
// A middle column: down into the gutter below its row, across to the nearer side lane.
|
|
209
|
+
const gy = card.y + NH + (rowI === lines - 1 ? PAD : GAP) / 2 + io / 2, cx = card.x + NW / 2 + o;
|
|
210
|
+
const lane = cx - b.x < b.w / 2 ? leftLane : rightLane;
|
|
211
|
+
pts = [{ x: cx, y: card.y + NH }, { x: cx, y: gy }, { x: lane, y: gy }, { x: lane, y: b.y }];
|
|
212
|
+
}
|
|
213
|
+
const top = pts[pts.length - 1];
|
|
214
|
+
pts.push({ x: top.x, y: b.busY + o });
|
|
215
|
+
return { pts, bus: b.busY + o };
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Inside a box, from a card to one of its side lanes (x `lane`): straight out when the card is in that lane's column,
|
|
219
|
+
* else down into the gutter under its row (no card is there) and across. The last point is on the lane.
|
|
220
|
+
*/
|
|
221
|
+
function toLane(L, end, lane, o) {
|
|
222
|
+
const { NW, NH } = OC, { PAD, GAP } = spacing(L);
|
|
223
|
+
const b = end.b, card = end.c, col = end.i % b.cols, rowI = Math.floor(end.i / b.cols), lines = Math.ceil(b.cells.length / b.cols);
|
|
224
|
+
const io = laneOffset(o, PAD);
|
|
225
|
+
const left = lane < b.x + b.w / 2;
|
|
226
|
+
if ((left && col === 0) || (!left && col === b.cols - 1)) {
|
|
227
|
+
const cy = card.y + NH / 2 + io;
|
|
228
|
+
return [{ x: left ? card.x : card.x + NW, y: cy }, { x: lane, y: cy }];
|
|
229
|
+
}
|
|
230
|
+
const gy = card.y + NH + (rowI === lines - 1 ? PAD : GAP) / 2 + io / 2, cx = card.x + NW / 2 + o;
|
|
231
|
+
return [{ x: cx, y: card.y + NH }, { x: cx, y: gy }, { x: lane, y: gy }];
|
|
232
|
+
}
|
|
233
|
+
/** Two cards in one open box: joined inside it, through the side lane nearer to them both (never out to the bus). */
|
|
234
|
+
function inBox(L, a, z, o) {
|
|
235
|
+
const b = a.b, { PAD } = spacing(L);
|
|
236
|
+
const io = laneOffset(o, PAD);
|
|
237
|
+
const mid = ((a.i % b.cols) + (z.i % b.cols)) / 2;
|
|
238
|
+
const lane = mid <= (b.cols - 1) / 2 ? b.x + PAD / 2 + io : b.x + b.w - PAD / 2 + io;
|
|
239
|
+
return [...toLane(L, a, lane, o), ...toLane(L, z, lane, o).reverse()];
|
|
240
|
+
}
|
|
241
|
+
/** Two of General's cards: under them, through the gap above the first row (or the canvas's empty space below). */
|
|
242
|
+
function betweenTops(a, z, o) {
|
|
243
|
+
const y = a.c.y + a.c.h + 30 + o * 0.6;
|
|
244
|
+
const ax = a.c.x + a.c.w / 2 + o, zx = z.c.x + z.c.w / 2 + o;
|
|
245
|
+
return [{ x: ax, y: a.c.y + a.c.h }, { x: ax, y }, { x: zx, y }, { x: zx, y: z.c.y + z.c.h }];
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The points of a line from one end to the other: up to the bus, along it (and the trunk, between rows), down — or,
|
|
249
|
+
* for two cards in one box, inside the box; for two of General's cards, just under them.
|
|
250
|
+
*/
|
|
251
|
+
export function route(L, a, z, o) {
|
|
252
|
+
if (a.kind === "cell" && z.kind === "cell" && a.b === z.b) return inBox(L, a, z, o);
|
|
253
|
+
if (a.kind === "top" && z.kind === "top") return betweenTops(a, z, o);
|
|
254
|
+
const p = outward(L, a, o), q = outward(L, z, o);
|
|
255
|
+
const back = [...q.pts].reverse();
|
|
256
|
+
if (Math.abs(p.bus - q.bus) < 1) return [...p.pts, ...back];
|
|
257
|
+
const tx = OC.TRUNK - 12 - o;
|
|
258
|
+
return [...p.pts, { x: tx, y: p.bus }, { x: tx, y: q.bus }, ...back];
|
|
259
|
+
}
|
|
260
|
+
/** An orthogonal polyline as SVG path data, its corners rounded. */
|
|
261
|
+
export function pathOf(pts, r = 8) {
|
|
262
|
+
const q = pts.filter((pt, i) => !i || pt.x !== pts[i - 1].x || pt.y !== pts[i - 1].y);
|
|
263
|
+
let d = `M${q[0].x} ${q[0].y}`;
|
|
264
|
+
for (let i = 1; i < q.length - 1; i++) {
|
|
265
|
+
const a = q[i - 1], b = q[i], c = q[i + 1];
|
|
266
|
+
const r1 = Math.min(r, Math.hypot(b.x - a.x, b.y - a.y) / 2, Math.hypot(c.x - b.x, c.y - b.y) / 2);
|
|
267
|
+
const u = { x: Math.sign(a.x - b.x), y: Math.sign(a.y - b.y) }, v = { x: Math.sign(c.x - b.x), y: Math.sign(c.y - b.y) };
|
|
268
|
+
d += ` L${b.x + u.x * r1} ${b.y + u.y * r1} Q${b.x} ${b.y} ${b.x + v.x * r1} ${b.y + v.y * r1}`;
|
|
269
|
+
}
|
|
270
|
+
const last = q[q.length - 1];
|
|
271
|
+
return `${d} L${last.x} ${last.y}`;
|
|
272
|
+
}
|
|
273
|
+
/** Where a line's ×N goes: the middle of its longest straight run. */
|
|
274
|
+
export function badgeAt(pts) {
|
|
275
|
+
let best = pts[0], len = -1;
|
|
276
|
+
for (let i = 1; i < pts.length; i++) {
|
|
277
|
+
const l = Math.hypot(pts[i].x - pts[i - 1].x, pts[i].y - pts[i - 1].y);
|
|
278
|
+
if (l > len) { len = l; best = { x: (pts[i].x + pts[i - 1].x) / 2, y: (pts[i].y + pts[i - 1].y) / 2 }; }
|
|
279
|
+
}
|
|
280
|
+
return best;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// ── Edges ──
|
|
284
|
+
|
|
285
|
+
/** The colour family of a kind: task, report, broadcast, and the rest (send, query, update). */
|
|
286
|
+
export const hue = (kind) => (kind === "task" || kind === "report" || kind === "broadcast" ? kind : "send");
|
|
287
|
+
// A message: queued, live, fading. The work: in progress (work), its report coming back (return), or no report (stale).
|
|
288
|
+
const phaseOf = (it) => it.phase || (it.fading ? "fading" : it.state === "queued" ? "queued" : "live");
|
|
289
|
+
const RANK = { live: 0, return: 0, work: 1, queued: 2, fading: 3, stale: 3 };
|
|
290
|
+
const settled = (phase) => (phase === "fading" || phase === "stale" ? "fading" : phase);
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* The lines to draw from the store's items on layout `L`. `far`: zoomed out (one line per team pair). Each edge:
|
|
294
|
+
* { key, hue, phase, n, from, to, d, pts, badge, a, z, routed } — `from`/`to` the instance (or team) names it joins, for
|
|
295
|
+
* search; `a`/`z` its two ends (fleet-route-scene.js routes the ones on cards). `routed` (#2182): the router's points by
|
|
296
|
+
* line key (fleet-route.js); a line it has none for keeps its lane route — or, while a new answer is on its way, the
|
|
297
|
+
* points the same two ends and kind had in the last one (a line changing phase keeps its place).
|
|
298
|
+
*/
|
|
299
|
+
export function trafficEdges(items, L, { far = false, max = MAX_EDGES, routed = null } = {}) {
|
|
300
|
+
if (!L.boxes.length && L.tops.length < 2) return [];
|
|
301
|
+
// A top's way out is the first row's bus: with no box there is none, so only top ↔ top lines (betweenTops) are drawn.
|
|
302
|
+
const groups = new Map();
|
|
303
|
+
const add = (key, g) => { const cur = groups.get(key); if (cur) { cur.n += g.n; cur.names.push(...g.names); } else groups.set(key, g); };
|
|
304
|
+
const teamKey = (name) => { const t = teamOf(L, name); return t === null ? "\u0000general" : t ? t.key : undefined; };
|
|
305
|
+
const teamEnd = (name) => { const t = teamOf(L, name); return t === null ? endOf(L, name) : t ? { kind: "box", b: t, key: `box:${t.key}` } : null; };
|
|
306
|
+
// Broadcasts: one fan-out per op; big ones (or far) bundle per recipient team.
|
|
307
|
+
const byOp = new Map();
|
|
308
|
+
for (const it of items) if (it.kind === "broadcast" && it.op) { const l = byOp.get(it.op) || []; l.push(it); byOp.set(it.op, l); }
|
|
309
|
+
const bundled = new Set();
|
|
310
|
+
for (const list of byOp.values()) if (far || list.length > BUNDLE_AT) for (const it of list) bundled.add(it.id);
|
|
311
|
+
for (const it of items) {
|
|
312
|
+
const phase = phaseOf(it), names = [it.from, it.to];
|
|
313
|
+
if (far || bundled.has(it.id)) {
|
|
314
|
+
const ta = teamKey(it.from), tb = teamKey(it.to);
|
|
315
|
+
if (ta === tb) continue; // inside one team: not drawn far away
|
|
316
|
+
const k = far ? "team" : "broadcast";
|
|
317
|
+
const a = far ? teamEnd(it.from) : endOf(L, it.from), z = teamEnd(it.to);
|
|
318
|
+
if (!a || !z) continue;
|
|
319
|
+
// Queued and live messages share a line far away (as before); the work keeps its own.
|
|
320
|
+
const ph = settled(phase), lane = ph === "queued" ? "live" : ph;
|
|
321
|
+
add(`${k}|${a.key}>${z.key}|${lane}`, { a, z, hue: k === "team" ? "team" : "broadcast", phase: ph, n: 1, names });
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
const a = endOf(L, it.from), z = endOf(L, it.to);
|
|
325
|
+
if (!a || !z || a.key === z.key) continue; // both in one folded team
|
|
326
|
+
add(`${a.key}>${z.key}|${hue(it.kind)}|${phase}`, { a, z, hue: hue(it.kind), phase, n: 1, names });
|
|
327
|
+
}
|
|
328
|
+
const list = [...groups.entries()].sort((x, y) => RANK[x[1].phase] - RANK[y[1].phase]).slice(0, max);
|
|
329
|
+
const lent = new Set();
|
|
330
|
+
const routedBy = (key) => {
|
|
331
|
+
if (!routed || far) return null;
|
|
332
|
+
const exact = routed.get(key);
|
|
333
|
+
if (exact) return exact;
|
|
334
|
+
const kin = key.slice(0, key.lastIndexOf("|") + 1);
|
|
335
|
+
for (const [k, pts] of routed) if (k.startsWith(kin) && !groups.has(k) && !lent.has(k)) { lent.add(k); return pts; }
|
|
336
|
+
return null;
|
|
337
|
+
};
|
|
338
|
+
return list.map(([key, g], i) => {
|
|
339
|
+
const o = ((i % 7) - 3) * 7; // neighbours 7 px apart (within the ±22 px bus lane)
|
|
340
|
+
const viaRouter = routedBy(key);
|
|
341
|
+
const pts = viaRouter ?? route(L, g.a, g.z, o);
|
|
342
|
+
return { key, hue: g.hue, phase: g.phase, n: g.n, names: [...new Set(g.names)], d: pathOf(pts), pts, badge: g.n > 1 ? badgeAt(pts) : null,
|
|
343
|
+
a: g.a, z: g.z, routed: !!viaRouter };
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/** For the list: what each instance is sending now, in words ("task → quill"), live messages only. */
|
|
348
|
+
export function sendingBy(items) {
|
|
349
|
+
const out = new Map();
|
|
350
|
+
for (const it of items) {
|
|
351
|
+
if (it.fading || it.phase === "stale" || it.phase === "return") continue;
|
|
352
|
+
const l = out.get(it.from) || [];
|
|
353
|
+
const working = it.phase === "work";
|
|
354
|
+
const key = `${it.kind}>${it.to}>${working ? "work" : it.state}`;
|
|
355
|
+
if (!l.some((x) => x.key === key)) l.push({ key, kind: it.kind, to: it.to, queued: it.state === "queued", working });
|
|
356
|
+
out.set(it.from, l);
|
|
357
|
+
}
|
|
358
|
+
return out;
|
|
359
|
+
}
|