agent-tempo 1.0.1
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/CLAUDE.md +213 -0
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/assets/icon-32.png +0 -0
- package/assets/icon-512.png +0 -0
- package/assets/icon-64.png +0 -0
- package/assets/icon-dark-32.png +0 -0
- package/assets/icon-dark-64.png +0 -0
- package/assets/icon-dark.svg +9 -0
- package/assets/icon.svg +9 -0
- package/assets/logo-dark.svg +11 -0
- package/assets/logo-light.svg +11 -0
- package/dashboard/README.md +91 -0
- package/dashboard/dist/assets/index-CB78ToNE.css +2 -0
- package/dashboard/dist/assets/index-_5jV0Znu.js +62 -0
- package/dashboard/dist/assets/index-_5jV0Znu.js.map +1 -0
- package/dashboard/dist/index.html +21 -0
- package/dashboard/package.json +47 -0
- package/dist/activities/hard-terminate.d.ts +32 -0
- package/dist/activities/hard-terminate.js +460 -0
- package/dist/activities/maestro.d.ts +72 -0
- package/dist/activities/maestro.js +254 -0
- package/dist/activities/outbox.d.ts +188 -0
- package/dist/activities/outbox.js +849 -0
- package/dist/activities/resolve.d.ts +64 -0
- package/dist/activities/resolve.js +129 -0
- package/dist/activities/schedule-fire.d.ts +36 -0
- package/dist/activities/schedule-fire.js +147 -0
- package/dist/adapters/base.d.ts +426 -0
- package/dist/adapters/base.js +1270 -0
- package/dist/adapters/claude-api/adapter.d.ts +168 -0
- package/dist/adapters/claude-api/adapter.js +797 -0
- package/dist/adapters/claude-api/api-error.d.ts +96 -0
- package/dist/adapters/claude-api/api-error.js +191 -0
- package/dist/adapters/claude-api/index.d.ts +16 -0
- package/dist/adapters/claude-api/index.js +21 -0
- package/dist/adapters/claude-api/mcp-bridge.d.ts +50 -0
- package/dist/adapters/claude-api/mcp-bridge.js +157 -0
- package/dist/adapters/claude-code/adapter.d.ts +133 -0
- package/dist/adapters/claude-code/adapter.js +274 -0
- package/dist/adapters/claude-code/index.d.ts +15 -0
- package/dist/adapters/claude-code/index.js +20 -0
- package/dist/adapters/claude-code-headless/adapter.d.ts +131 -0
- package/dist/adapters/claude-code-headless/adapter.js +710 -0
- package/dist/adapters/claude-code-headless/error-mapper.d.ts +107 -0
- package/dist/adapters/claude-code-headless/error-mapper.js +281 -0
- package/dist/adapters/claude-code-headless/index.d.ts +17 -0
- package/dist/adapters/claude-code-headless/index.js +26 -0
- package/dist/adapters/claude-code-headless/pre-flight.d.ts +51 -0
- package/dist/adapters/claude-code-headless/pre-flight.js +207 -0
- package/dist/adapters/claude-code-headless/prompt.d.ts +93 -0
- package/dist/adapters/claude-code-headless/prompt.js +79 -0
- package/dist/adapters/claude-code-headless/stream-json.d.ts +242 -0
- package/dist/adapters/claude-code-headless/stream-json.js +208 -0
- package/dist/adapters/claude-code-headless/types.d.ts +28 -0
- package/dist/adapters/claude-code-headless/types.js +36 -0
- package/dist/adapters/copilot/adapter.d.ts +100 -0
- package/dist/adapters/copilot/adapter.js +730 -0
- package/dist/adapters/copilot/index.d.ts +15 -0
- package/dist/adapters/copilot/index.js +20 -0
- package/dist/adapters/index.d.ts +42 -0
- package/dist/adapters/index.js +115 -0
- package/dist/adapters/opencode/adapter.d.ts +82 -0
- package/dist/adapters/opencode/adapter.js +710 -0
- package/dist/adapters/opencode/config.d.ts +90 -0
- package/dist/adapters/opencode/config.js +137 -0
- package/dist/adapters/opencode/helpers.d.ts +40 -0
- package/dist/adapters/opencode/helpers.js +144 -0
- package/dist/adapters/opencode/index.d.ts +12 -0
- package/dist/adapters/opencode/index.js +17 -0
- package/dist/adapters/opencode/server-bridge.d.ts +124 -0
- package/dist/adapters/opencode/server-bridge.js +216 -0
- package/dist/adapters/sdk/base.d.ts +95 -0
- package/dist/adapters/sdk/base.js +134 -0
- package/dist/adapters/sdk/system-prompt.d.ts +64 -0
- package/dist/adapters/sdk/system-prompt.js +78 -0
- package/dist/adapters/terminal-error.d.ts +27 -0
- package/dist/adapters/terminal-error.js +39 -0
- package/dist/channel.d.ts +3 -0
- package/dist/channel.js +48 -0
- package/dist/cli/commands.d.ts +245 -0
- package/dist/cli/commands.js +2438 -0
- package/dist/cli/config-command.d.ts +8 -0
- package/dist/cli/config-command.js +254 -0
- package/dist/cli/daemon-command.d.ts +57 -0
- package/dist/cli/daemon-command.js +493 -0
- package/dist/cli/daemon.d.ts +217 -0
- package/dist/cli/daemon.js +632 -0
- package/dist/cli/dashboard-command.d.ts +20 -0
- package/dist/cli/dashboard-command.js +241 -0
- package/dist/cli/dev-banner.d.ts +107 -0
- package/dist/cli/dev-banner.js +190 -0
- package/dist/cli/dev-mode-bootstrap.d.ts +29 -0
- package/dist/cli/dev-mode-bootstrap.js +36 -0
- package/dist/cli/dev-verbs.d.ts +43 -0
- package/dist/cli/dev-verbs.js +254 -0
- package/dist/cli/help-text.d.ts +1 -0
- package/dist/cli/help-text.js +158 -0
- package/dist/cli/legacy-migration.d.ts +35 -0
- package/dist/cli/legacy-migration.js +335 -0
- package/dist/cli/mcp.d.ts +8 -0
- package/dist/cli/mcp.js +63 -0
- package/dist/cli/output.d.ts +12 -0
- package/dist/cli/output.js +37 -0
- package/dist/cli/preflight.d.ts +9 -0
- package/dist/cli/preflight.js +96 -0
- package/dist/cli/removed-verbs.d.ts +9 -0
- package/dist/cli/removed-verbs.js +78 -0
- package/dist/cli/sa-preflight.d.ts +99 -0
- package/dist/cli/sa-preflight.js +183 -0
- package/dist/cli/scenarios-command.d.ts +6 -0
- package/dist/cli/scenarios-command.js +167 -0
- package/dist/cli/startup.d.ts +112 -0
- package/dist/cli/startup.js +641 -0
- package/dist/cli/upgrade-command.d.ts +5 -0
- package/dist/cli/upgrade-command.js +240 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +680 -0
- package/dist/client/core.d.ts +33 -0
- package/dist/client/core.js +1260 -0
- package/dist/client/ensure-conductor-spawned.d.ts +35 -0
- package/dist/client/ensure-conductor-spawned.js +48 -0
- package/dist/client/index.d.ts +32 -0
- package/dist/client/index.js +22 -0
- package/dist/client/interface.d.ts +461 -0
- package/dist/client/interface.js +2 -0
- package/dist/client/subscribe.d.ts +108 -0
- package/dist/client/subscribe.js +598 -0
- package/dist/client/with-spawn.d.ts +27 -0
- package/dist/client/with-spawn.js +87 -0
- package/dist/config.d.ts +323 -0
- package/dist/config.js +593 -0
- package/dist/connection.d.ts +7 -0
- package/dist/connection.js +46 -0
- package/dist/constants.d.ts +50 -0
- package/dist/constants.js +74 -0
- package/dist/copilot-bridge.d.ts +22 -0
- package/dist/copilot-bridge.js +565 -0
- package/dist/daemon-adapter-versions.d.ts +52 -0
- package/dist/daemon-adapter-versions.js +170 -0
- package/dist/daemon.d.ts +275 -0
- package/dist/daemon.js +989 -0
- package/dist/ensemble/agent-types.d.ts +23 -0
- package/dist/ensemble/agent-types.js +132 -0
- package/dist/ensemble/loader.d.ts +14 -0
- package/dist/ensemble/loader.js +140 -0
- package/dist/ensemble/saver.d.ts +49 -0
- package/dist/ensemble/saver.js +201 -0
- package/dist/ensemble/schema.d.ts +71 -0
- package/dist/ensemble/schema.js +3 -0
- package/dist/git-info.d.ts +4 -0
- package/dist/git-info.js +29 -0
- package/dist/http/aggregate.d.ts +319 -0
- package/dist/http/aggregate.js +684 -0
- package/dist/http/auth.d.ts +67 -0
- package/dist/http/auth.js +177 -0
- package/dist/http/body.d.ts +71 -0
- package/dist/http/body.js +121 -0
- package/dist/http/catalog.d.ts +67 -0
- package/dist/http/catalog.js +209 -0
- package/dist/http/cors.d.ts +42 -0
- package/dist/http/cors.js +111 -0
- package/dist/http/dashboard-pair.d.ts +94 -0
- package/dist/http/dashboard-pair.js +148 -0
- package/dist/http/dashboard.d.ts +20 -0
- package/dist/http/dashboard.js +160 -0
- package/dist/http/event-bus.d.ts +217 -0
- package/dist/http/event-bus.js +365 -0
- package/dist/http/event-id.d.ts +77 -0
- package/dist/http/event-id.js +117 -0
- package/dist/http/event-types.d.ts +348 -0
- package/dist/http/event-types.js +36 -0
- package/dist/http/fixtures/chat-stress.d.ts +8 -0
- package/dist/http/fixtures/chat-stress.js +63 -0
- package/dist/http/fixtures/conductor-leaving.d.ts +8 -0
- package/dist/http/fixtures/conductor-leaving.js +80 -0
- package/dist/http/fixtures/constants.d.ts +10 -0
- package/dist/http/fixtures/constants.js +13 -0
- package/dist/http/fixtures/eight-player-broadcast.d.ts +10 -0
- package/dist/http/fixtures/eight-player-broadcast.js +81 -0
- package/dist/http/fixtures/empty-ensemble.d.ts +6 -0
- package/dist/http/fixtures/empty-ensemble.js +26 -0
- package/dist/http/fixtures/index.d.ts +55 -0
- package/dist/http/fixtures/index.js +110 -0
- package/dist/http/fixtures/single-conductor.d.ts +7 -0
- package/dist/http/fixtures/single-conductor.js +46 -0
- package/dist/http/fixtures/sse-reconnect.d.ts +8 -0
- package/dist/http/fixtures/sse-reconnect.js +77 -0
- package/dist/http/index.d.ts +21 -0
- package/dist/http/index.js +61 -0
- package/dist/http/port-file.d.ts +22 -0
- package/dist/http/port-file.js +132 -0
- package/dist/http/responses.d.ts +27 -0
- package/dist/http/responses.js +40 -0
- package/dist/http/ring-buffer.d.ts +41 -0
- package/dist/http/ring-buffer.js +80 -0
- package/dist/http/server.d.ts +122 -0
- package/dist/http/server.js +459 -0
- package/dist/http/snapshot.d.ts +85 -0
- package/dist/http/snapshot.js +180 -0
- package/dist/http/sse-handler.d.ts +87 -0
- package/dist/http/sse-handler.js +294 -0
- package/dist/http/writes.d.ts +55 -0
- package/dist/http/writes.js +240 -0
- package/dist/palette/index.d.ts +138 -0
- package/dist/palette/index.js +221 -0
- package/dist/reconcile/orphans.d.ts +255 -0
- package/dist/reconcile/orphans.js +340 -0
- package/dist/scripts/258-spotcheck.js +303 -0
- package/dist/scripts/check-components-css-sync.js +199 -0
- package/dist/scripts/run-shard.js +121 -0
- package/dist/scripts/verify-daemon-isolation-guard.js +128 -0
- package/dist/server-tools.d.ts +87 -0
- package/dist/server-tools.js +146 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +366 -0
- package/dist/spawn.d.ts +296 -0
- package/dist/spawn.js +747 -0
- package/dist/tools/agent-types.d.ts +2 -0
- package/dist/tools/agent-types.js +21 -0
- package/dist/tools/attachment-info.d.ts +4 -0
- package/dist/tools/attachment-info.js +48 -0
- package/dist/tools/broadcast.d.ts +4 -0
- package/dist/tools/broadcast.js +76 -0
- package/dist/tools/cancel-stage.d.ts +3 -0
- package/dist/tools/cancel-stage.js +20 -0
- package/dist/tools/clear-state.d.ts +3 -0
- package/dist/tools/clear-state.js +37 -0
- package/dist/tools/coat-check-evict.d.ts +4 -0
- package/dist/tools/coat-check-evict.js +43 -0
- package/dist/tools/coat-check-get.d.ts +4 -0
- package/dist/tools/coat-check-get.js +56 -0
- package/dist/tools/coat-check-list.d.ts +4 -0
- package/dist/tools/coat-check-list.js +60 -0
- package/dist/tools/coat-check-put.d.ts +4 -0
- package/dist/tools/coat-check-put.js +53 -0
- package/dist/tools/cue.d.ts +44 -0
- package/dist/tools/cue.js +201 -0
- package/dist/tools/destroy.d.ts +4 -0
- package/dist/tools/destroy.js +188 -0
- package/dist/tools/detach.d.ts +4 -0
- package/dist/tools/detach.js +45 -0
- package/dist/tools/encore.d.ts +4 -0
- package/dist/tools/encore.js +31 -0
- package/dist/tools/ensemble.d.ts +32 -0
- package/dist/tools/ensemble.js +198 -0
- package/dist/tools/evaluate-gate.d.ts +3 -0
- package/dist/tools/evaluate-gate.js +32 -0
- package/dist/tools/fetch-state.d.ts +13 -0
- package/dist/tools/fetch-state.js +78 -0
- package/dist/tools/gates.d.ts +3 -0
- package/dist/tools/gates.js +41 -0
- package/dist/tools/helpers.d.ts +21 -0
- package/dist/tools/helpers.js +25 -0
- package/dist/tools/hosts.d.ts +4 -0
- package/dist/tools/hosts.js +40 -0
- package/dist/tools/listen.d.ts +3 -0
- package/dist/tools/listen.js +22 -0
- package/dist/tools/load-lineup.d.ts +5 -0
- package/dist/tools/load-lineup.js +381 -0
- package/dist/tools/migrate.d.ts +4 -0
- package/dist/tools/migrate.js +60 -0
- package/dist/tools/pause-ensemble.d.ts +4 -0
- package/dist/tools/pause-ensemble.js +58 -0
- package/dist/tools/pause.d.ts +4 -0
- package/dist/tools/pause.js +36 -0
- package/dist/tools/play.d.ts +4 -0
- package/dist/tools/play.js +57 -0
- package/dist/tools/quality-gate.d.ts +3 -0
- package/dist/tools/quality-gate.js +26 -0
- package/dist/tools/recall.d.ts +3 -0
- package/dist/tools/recall.js +32 -0
- package/dist/tools/recruit.d.ts +38 -0
- package/dist/tools/recruit.js +447 -0
- package/dist/tools/release.d.ts +4 -0
- package/dist/tools/release.js +98 -0
- package/dist/tools/report.d.ts +3 -0
- package/dist/tools/report.js +29 -0
- package/dist/tools/resolve.d.ts +1 -0
- package/dist/tools/resolve.js +7 -0
- package/dist/tools/restart.d.ts +35 -0
- package/dist/tools/restart.js +131 -0
- package/dist/tools/restore.d.ts +4 -0
- package/dist/tools/restore.js +107 -0
- package/dist/tools/resume-ensemble.d.ts +4 -0
- package/dist/tools/resume-ensemble.js +79 -0
- package/dist/tools/save-lineup.d.ts +4 -0
- package/dist/tools/save-lineup.js +36 -0
- package/dist/tools/save-state.d.ts +3 -0
- package/dist/tools/save-state.js +57 -0
- package/dist/tools/schedule.d.ts +4 -0
- package/dist/tools/schedule.js +152 -0
- package/dist/tools/schedules.d.ts +4 -0
- package/dist/tools/schedules.js +54 -0
- package/dist/tools/set-ensemble-description.d.ts +4 -0
- package/dist/tools/set-ensemble-description.js +37 -0
- package/dist/tools/set-name.d.ts +4 -0
- package/dist/tools/set-name.js +45 -0
- package/dist/tools/set-part.d.ts +3 -0
- package/dist/tools/set-part.js +20 -0
- package/dist/tools/shutdown.d.ts +4 -0
- package/dist/tools/shutdown.js +54 -0
- package/dist/tools/stage.d.ts +3 -0
- package/dist/tools/stage.js +28 -0
- package/dist/tools/stages.d.ts +3 -0
- package/dist/tools/stages.js +35 -0
- package/dist/tools/stop.d.ts +4 -0
- package/dist/tools/stop.js +29 -0
- package/dist/tools/unschedule.d.ts +4 -0
- package/dist/tools/unschedule.js +35 -0
- package/dist/tools/who-am-i.d.ts +3 -0
- package/dist/tools/who-am-i.js +34 -0
- package/dist/tools/worktree.d.ts +4 -0
- package/dist/tools/worktree.js +181 -0
- package/dist/tui/App.d.ts +85 -0
- package/dist/tui/App.js +1791 -0
- package/dist/tui/bootstrap-types.d.ts +46 -0
- package/dist/tui/bootstrap-types.js +7 -0
- package/dist/tui/client.d.ts +6 -0
- package/dist/tui/client.js +9 -0
- package/dist/tui/commands.d.ts +71 -0
- package/dist/tui/commands.js +1375 -0
- package/dist/tui/components/ActivityLog.d.ts +16 -0
- package/dist/tui/components/ActivityLog.js +36 -0
- package/dist/tui/components/ChatView.d.ts +35 -0
- package/dist/tui/components/ChatView.js +54 -0
- package/dist/tui/components/CommandOverlay.d.ts +15 -0
- package/dist/tui/components/CommandOverlay.js +34 -0
- package/dist/tui/components/CommandPalette.d.ts +21 -0
- package/dist/tui/components/CommandPalette.js +67 -0
- package/dist/tui/components/ConductorChat.d.ts +16 -0
- package/dist/tui/components/ConductorChat.js +32 -0
- package/dist/tui/components/ConversationStream.d.ts +114 -0
- package/dist/tui/components/ConversationStream.js +307 -0
- package/dist/tui/components/CreateEnsembleWizard.d.ts +19 -0
- package/dist/tui/components/CreateEnsembleWizard.js +223 -0
- package/dist/tui/components/DestroyConfirmModal.d.ts +17 -0
- package/dist/tui/components/DestroyConfirmModal.js +62 -0
- package/dist/tui/components/EnsembleListView.d.ts +14 -0
- package/dist/tui/components/EnsembleListView.js +32 -0
- package/dist/tui/components/EnsemblePanel.d.ts +12 -0
- package/dist/tui/components/EnsemblePanel.js +40 -0
- package/dist/tui/components/ErrorView.d.ts +31 -0
- package/dist/tui/components/ErrorView.js +129 -0
- package/dist/tui/components/HomeView.d.ts +54 -0
- package/dist/tui/components/HomeView.js +306 -0
- package/dist/tui/components/InputBar.d.ts +13 -0
- package/dist/tui/components/InputBar.js +58 -0
- package/dist/tui/components/LoadLineupModal.d.ts +18 -0
- package/dist/tui/components/LoadLineupModal.js +79 -0
- package/dist/tui/components/MainView.d.ts +21 -0
- package/dist/tui/components/MainView.js +107 -0
- package/dist/tui/components/NewEnsembleModal.d.ts +9 -0
- package/dist/tui/components/NewEnsembleModal.js +73 -0
- package/dist/tui/components/Picker.d.ts +23 -0
- package/dist/tui/components/Picker.js +70 -0
- package/dist/tui/components/PlayerDetailView.d.ts +26 -0
- package/dist/tui/components/PlayerDetailView.js +118 -0
- package/dist/tui/components/PromptArea.d.ts +50 -0
- package/dist/tui/components/PromptArea.js +303 -0
- package/dist/tui/components/RecruitWizard.d.ts +17 -0
- package/dist/tui/components/RecruitWizard.js +221 -0
- package/dist/tui/components/RestoreConfirmModal.d.ts +18 -0
- package/dist/tui/components/RestoreConfirmModal.js +71 -0
- package/dist/tui/components/ScheduleOverlay.d.ts +13 -0
- package/dist/tui/components/ScheduleOverlay.js +113 -0
- package/dist/tui/components/ScheduleWizard.d.ts +19 -0
- package/dist/tui/components/ScheduleWizard.js +259 -0
- package/dist/tui/components/Splash.d.ts +23 -0
- package/dist/tui/components/Splash.js +221 -0
- package/dist/tui/components/StatusBar.d.ts +48 -0
- package/dist/tui/components/StatusBar.js +128 -0
- package/dist/tui/components/StatusOverlay.d.ts +15 -0
- package/dist/tui/components/StatusOverlay.js +76 -0
- package/dist/tui/components/TitleBar.d.ts +10 -0
- package/dist/tui/components/TitleBar.js +21 -0
- package/dist/tui/components/TopBar.d.ts +12 -0
- package/dist/tui/components/TopBar.js +15 -0
- package/dist/tui/core-api.d.ts +26 -0
- package/dist/tui/core-api.js +67 -0
- package/dist/tui/hooks/useEnsembleDiscovery.d.ts +3 -0
- package/dist/tui/hooks/useEnsembleDiscovery.js +30 -0
- package/dist/tui/hooks/useMaestroPoller.d.ts +3 -0
- package/dist/tui/hooks/useMaestroPoller.js +36 -0
- package/dist/tui/hooks/useSendCommand.d.ts +7 -0
- package/dist/tui/hooks/useSendCommand.js +29 -0
- package/dist/tui/index.d.ts +15 -0
- package/dist/tui/index.js +156 -0
- package/dist/tui/ink-context.d.ts +18 -0
- package/dist/tui/ink-context.js +59 -0
- package/dist/tui/ink-loader.d.ts +26 -0
- package/dist/tui/ink-loader.js +42 -0
- package/dist/tui/removed-commands.d.ts +9 -0
- package/dist/tui/removed-commands.js +22 -0
- package/dist/tui/sse-handler.d.ts +52 -0
- package/dist/tui/sse-handler.js +157 -0
- package/dist/tui/store.d.ts +598 -0
- package/dist/tui/store.js +753 -0
- package/dist/tui/utils/format.d.ts +56 -0
- package/dist/tui/utils/format.js +155 -0
- package/dist/tui/utils/fullscreen.d.ts +23 -0
- package/dist/tui/utils/fullscreen.js +71 -0
- package/dist/tui/utils/history.d.ts +10 -0
- package/dist/tui/utils/history.js +85 -0
- package/dist/tui/utils/platform.d.ts +45 -0
- package/dist/tui/utils/platform.js +258 -0
- package/dist/tui/utils/theme.d.ts +21 -0
- package/dist/tui/utils/theme.js +24 -0
- package/dist/types.d.ts +1020 -0
- package/dist/types.js +39 -0
- package/dist/utils/attachment-format.d.ts +22 -0
- package/dist/utils/attachment-format.js +32 -0
- package/dist/utils/default-part.d.ts +43 -0
- package/dist/utils/default-part.js +104 -0
- package/dist/utils/duration.d.ts +30 -0
- package/dist/utils/duration.js +69 -0
- package/dist/utils/ensemble-ops.d.ts +61 -0
- package/dist/utils/ensemble-ops.js +77 -0
- package/dist/utils/format-hosts.d.ts +21 -0
- package/dist/utils/format-hosts.js +73 -0
- package/dist/utils/hosts.d.ts +113 -0
- package/dist/utils/hosts.js +265 -0
- package/dist/utils/parent-death-watchdog.d.ts +1 -0
- package/dist/utils/parent-death-watchdog.js +47 -0
- package/dist/utils/query-timeout.d.ts +103 -0
- package/dist/utils/query-timeout.js +113 -0
- package/dist/utils/recall-format.d.ts +78 -0
- package/dist/utils/recall-format.js +105 -0
- package/dist/utils/restore-format.d.ts +49 -0
- package/dist/utils/restore-format.js +91 -0
- package/dist/utils/safe-path.d.ts +10 -0
- package/dist/utils/safe-path.js +43 -0
- package/dist/utils/sdk-probe.d.ts +9 -0
- package/dist/utils/sdk-probe.js +45 -0
- package/dist/utils/search-attributes.d.ts +76 -0
- package/dist/utils/search-attributes.js +86 -0
- package/dist/utils/validation.d.ts +113 -0
- package/dist/utils/validation.js +163 -0
- package/dist/utils/visibility-deadline.d.ts +186 -0
- package/dist/utils/visibility-deadline.js +158 -0
- package/dist/utils/worktree.d.ts +103 -0
- package/dist/utils/worktree.js +327 -0
- package/dist/worker.d.ts +14 -0
- package/dist/worker.js +146 -0
- package/dist/workflows/attachment-math.d.ts +56 -0
- package/dist/workflows/attachment-math.js +47 -0
- package/dist/workflows/index.d.ts +3 -0
- package/dist/workflows/index.js +11 -0
- package/dist/workflows/maestro-signals.d.ts +217 -0
- package/dist/workflows/maestro-signals.js +155 -0
- package/dist/workflows/maestro.d.ts +3 -0
- package/dist/workflows/maestro.js +812 -0
- package/dist/workflows/scheduler-signals.d.ts +10 -0
- package/dist/workflows/scheduler-signals.js +14 -0
- package/dist/workflows/scheduler.d.ts +17 -0
- package/dist/workflows/scheduler.js +143 -0
- package/dist/workflows/session.d.ts +2 -0
- package/dist/workflows/session.js +1638 -0
- package/dist/workflows/signals.d.ts +297 -0
- package/dist/workflows/signals.js +239 -0
- package/examples/agents/tempo-composer.md +56 -0
- package/examples/agents/tempo-conductor.md +117 -0
- package/examples/agents/tempo-critic.md +73 -0
- package/examples/agents/tempo-improv.md +74 -0
- package/examples/agents/tempo-liner.md +75 -0
- package/examples/agents/tempo-roadie.md +61 -0
- package/examples/agents/tempo-soloist.md +71 -0
- package/examples/agents/tempo-tuner.md +94 -0
- package/examples/ensembles/tempo-big-band.yaml +146 -0
- package/examples/ensembles/tempo-dev-team.yaml +58 -0
- package/examples/ensembles/tempo-headless-jam.yaml +77 -0
- package/examples/ensembles/tempo-jam-session.yaml +41 -0
- package/examples/ensembles/tempo-mock-jam.yaml +79 -0
- package/examples/ensembles/tempo-review-squad.yaml +32 -0
- package/package.json +172 -0
- package/packaging/launchd/com.agent.tempo.plist +46 -0
- package/packaging/systemd/agent-tempo.service +32 -0
- package/packaging/windows/install-task.ps1 +71 -0
- package/scenarios/conductor-recruit-mock.yaml +33 -0
- package/scenarios/echo-roundtrip.yaml +15 -0
- package/scenarios/multi-player-handoff.yaml +38 -0
- package/scenarios/recruit-cascade.yaml +38 -0
- package/scenarios/two-player-conversation.yaml +33 -0
- package/workflow-bundle.js +14146 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DASHBOARD_DIST = void 0;
|
|
4
|
+
exports.handleDashboardStatic = handleDashboardStatic;
|
|
5
|
+
exports.__setDashboardDistRootForTests = __setDashboardDistRootForTests;
|
|
6
|
+
/**
|
|
7
|
+
* Static-asset handler for the packaged web dashboard (PR-1 of #340).
|
|
8
|
+
*
|
|
9
|
+
* Serves the prebuilt SPA at `/dashboard/*` from `dashboard/dist/`. Wiring
|
|
10
|
+
* lives in {@link ../http/server.ts}; this module is intentionally thin so
|
|
11
|
+
* the routing decisions (pre-auth carve-out vs post-auth dispatch) stay
|
|
12
|
+
* visible at the call site.
|
|
13
|
+
*
|
|
14
|
+
* **Contract**
|
|
15
|
+
*
|
|
16
|
+
* | Path | Behaviour |
|
|
17
|
+
* |-------------------------------------|-------------------------------------------------------------|
|
|
18
|
+
* | `/dashboard` or `/dashboard/` | Serve `dashboard/dist/index.html`, `Cache-Control: no-cache` |
|
|
19
|
+
* | `/dashboard/<file-with-extension>` | Serve the file with its MIME type, `immutable` cache; 404 if missing |
|
|
20
|
+
* | `/dashboard/<extensionless-route>` | SPA fallback to `index.html` (React Router 7 client-side routing) |
|
|
21
|
+
* | `/dashboard/api/*` | 404 (reserved for daemon-side dashboard API; pair stub matched earlier) |
|
|
22
|
+
* | `/dashboard/<traversal>` (`..`) | 404 — `assertSafePath` rejects anything outside `dashboard/dist` |
|
|
23
|
+
*
|
|
24
|
+
* **Cache headers** match the design doc (`docs/design/340-web-dashboard.md` §4.2):
|
|
25
|
+
* - `index.html` → `Cache-Control: no-cache` so dashboard updates ship immediately
|
|
26
|
+
* - hashed assets (`.js`, `.css`, fonts, images) → `Cache-Control: public, max-age=31536000, immutable`
|
|
27
|
+
*
|
|
28
|
+
* The pre-auth `GET /dashboard/api/pair/:token` carve-out (architect §4.1)
|
|
29
|
+
* is matched in `server.ts` before the bearer-auth gate; for PR-1 it returns
|
|
30
|
+
* 501 via {@link handlePairTokenStub}. PR-8 wires the real pair flow.
|
|
31
|
+
*/
|
|
32
|
+
const fs_1 = require("fs");
|
|
33
|
+
const path_1 = require("path");
|
|
34
|
+
const safe_path_1 = require("../utils/safe-path");
|
|
35
|
+
const responses_1 = require("./responses");
|
|
36
|
+
/** Repo-relative path from the compiled `dist/` output — the production default. */
|
|
37
|
+
exports.DASHBOARD_DIST = (0, path_1.resolve)(__dirname, '..', '..', 'dashboard', 'dist');
|
|
38
|
+
/**
|
|
39
|
+
* Mutable dist root used by {@link handleDashboardStatic}. Tests reset
|
|
40
|
+
* this via the `__setDashboardDistRootForTests` hook below; production
|
|
41
|
+
* code never touches it.
|
|
42
|
+
*/
|
|
43
|
+
let activeDistRoot = exports.DASHBOARD_DIST;
|
|
44
|
+
/** Long-cache header for hashed Vite output. */
|
|
45
|
+
const IMMUTABLE_CACHE = 'public, max-age=31536000, immutable';
|
|
46
|
+
/** Short-cache header for `index.html` so SPA updates roll out immediately. */
|
|
47
|
+
const HTML_CACHE = 'no-cache';
|
|
48
|
+
const MIME = {
|
|
49
|
+
'.html': 'text/html; charset=utf-8',
|
|
50
|
+
'.js': 'application/javascript; charset=utf-8',
|
|
51
|
+
'.mjs': 'application/javascript; charset=utf-8',
|
|
52
|
+
'.css': 'text/css; charset=utf-8',
|
|
53
|
+
'.json': 'application/json; charset=utf-8',
|
|
54
|
+
'.map': 'application/json; charset=utf-8',
|
|
55
|
+
'.svg': 'image/svg+xml',
|
|
56
|
+
'.png': 'image/png',
|
|
57
|
+
'.jpg': 'image/jpeg',
|
|
58
|
+
'.jpeg': 'image/jpeg',
|
|
59
|
+
'.gif': 'image/gif',
|
|
60
|
+
'.webp': 'image/webp',
|
|
61
|
+
'.ico': 'image/x-icon',
|
|
62
|
+
'.woff': 'font/woff',
|
|
63
|
+
'.woff2': 'font/woff2',
|
|
64
|
+
'.ttf': 'font/ttf',
|
|
65
|
+
'.txt': 'text/plain; charset=utf-8',
|
|
66
|
+
};
|
|
67
|
+
/** Extensions that count as "asset-shaped" — missing files 404 instead of SPA-falling-back. */
|
|
68
|
+
const ASSET_EXTENSIONS = new Set(Object.keys(MIME));
|
|
69
|
+
/**
|
|
70
|
+
* Serve a request under `/dashboard/*`. The caller in `server.ts` has
|
|
71
|
+
* already URL-parsed the request and gated by prefix, and passes the
|
|
72
|
+
* normalised `pathname` in to avoid a second parse on the hot path.
|
|
73
|
+
*/
|
|
74
|
+
function handleDashboardStatic(req, res, pathname) {
|
|
75
|
+
const distRoot = activeDistRoot;
|
|
76
|
+
// Strip the `/dashboard` prefix. `/dashboard` or `/dashboard/` ⇒ index.html.
|
|
77
|
+
const relative = pathname.slice('/dashboard'.length);
|
|
78
|
+
if (relative === '' || relative === '/') {
|
|
79
|
+
return serveIndexHtml(res, distRoot);
|
|
80
|
+
}
|
|
81
|
+
// `/dashboard/api/*` is reserved for daemon dashboard API endpoints. The
|
|
82
|
+
// pair-token carve-out is matched earlier in server.ts; anything else
|
|
83
|
+
// under `/api/` is a 404 — never SPA-fall-back, never serve a static
|
|
84
|
+
// file.
|
|
85
|
+
if (relative === '/api' || relative.startsWith('/api/')) {
|
|
86
|
+
return (0, responses_1.errorResponse)(res, 404, { error: 'not-found' });
|
|
87
|
+
}
|
|
88
|
+
// Resolve under `distRoot` and reject any path that escapes the root.
|
|
89
|
+
// The URL parser already normalised `..`, but `assertSafePath` is the
|
|
90
|
+
// canonical traversal guard used elsewhere in the codebase.
|
|
91
|
+
const candidate = (0, path_1.resolve)(distRoot, '.' + relative);
|
|
92
|
+
try {
|
|
93
|
+
(0, safe_path_1.assertSafePath)(candidate, [distRoot]);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return (0, responses_1.errorResponse)(res, 404, { error: 'not-found' });
|
|
97
|
+
}
|
|
98
|
+
const ext = (0, path_1.extname)(relative).toLowerCase();
|
|
99
|
+
const stat = safeStat(candidate);
|
|
100
|
+
if (stat?.isFile()) {
|
|
101
|
+
return streamFile(res, candidate, ext);
|
|
102
|
+
}
|
|
103
|
+
// No file at that path:
|
|
104
|
+
// - asset-shaped (has a known extension) ⇒ real 404; never SPA-fall-back
|
|
105
|
+
// for missing assets, otherwise a missing CSS file silently returns
|
|
106
|
+
// index.html with content-type text/html and the browser logs MIME
|
|
107
|
+
// errors.
|
|
108
|
+
// - extensionless ⇒ SPA fallback to index.html so React Router 7 owns
|
|
109
|
+
// client-side routing.
|
|
110
|
+
if (ext !== '' && ASSET_EXTENSIONS.has(ext)) {
|
|
111
|
+
return (0, responses_1.errorResponse)(res, 404, { error: 'not-found' });
|
|
112
|
+
}
|
|
113
|
+
return serveIndexHtml(res, distRoot);
|
|
114
|
+
}
|
|
115
|
+
function serveIndexHtml(res, distRoot) {
|
|
116
|
+
const indexPath = (0, path_1.join)(distRoot, 'index.html');
|
|
117
|
+
const stat = safeStat(indexPath);
|
|
118
|
+
if (!stat?.isFile()) {
|
|
119
|
+
return (0, responses_1.errorResponse)(res, 404, { error: 'dashboard-not-built' });
|
|
120
|
+
}
|
|
121
|
+
return streamFile(res, indexPath, '.html');
|
|
122
|
+
}
|
|
123
|
+
function streamFile(res, filePath, ext) {
|
|
124
|
+
const mime = MIME[ext] ?? 'application/octet-stream';
|
|
125
|
+
const cache = ext === '.html' ? HTML_CACHE : IMMUTABLE_CACHE;
|
|
126
|
+
res.writeHead(200, {
|
|
127
|
+
'Content-Type': mime,
|
|
128
|
+
'Cache-Control': cache,
|
|
129
|
+
});
|
|
130
|
+
const stream = (0, fs_1.createReadStream)(filePath);
|
|
131
|
+
stream.on('error', () => {
|
|
132
|
+
// Headers already written — best we can do is end the response.
|
|
133
|
+
try {
|
|
134
|
+
res.end();
|
|
135
|
+
}
|
|
136
|
+
catch { /* socket gone */ }
|
|
137
|
+
});
|
|
138
|
+
stream.pipe(res);
|
|
139
|
+
}
|
|
140
|
+
function safeStat(p) {
|
|
141
|
+
try {
|
|
142
|
+
return (0, fs_1.statSync)(p);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Test escape hatch — override the dist root used by
|
|
150
|
+
* {@link handleDashboardStatic}. Pass `null` to restore the production
|
|
151
|
+
* default.
|
|
152
|
+
*
|
|
153
|
+
* **Do not call from production code.** The double-underscore prefix
|
|
154
|
+
* marks this as a test-only hook (see ADR 0006). Used by
|
|
155
|
+
* `tests/http/dashboard-handler.test.ts` to point the handler at a
|
|
156
|
+
* fixture directory without modifying the real `dashboard/dist/`.
|
|
157
|
+
*/
|
|
158
|
+
function __setDashboardDistRootForTests(override) {
|
|
159
|
+
activeDistRoot = override ?? exports.DASHBOARD_DIST;
|
|
160
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { SeqAllocator, type EventIdTuple } from './event-id';
|
|
2
|
+
import type { SseEventKind } from './event-types';
|
|
3
|
+
/** Default heartbeat cadence — locked in by §6 / §8. */
|
|
4
|
+
export declare const DEFAULT_HEARTBEAT_MS = 10000;
|
|
5
|
+
/** Default heartbeat suppression window — §6. */
|
|
6
|
+
export declare const DEFAULT_HEARTBEAT_SUPPRESS_MS = 8000;
|
|
7
|
+
/** Ensemble-wide rate ceiling — §8. */
|
|
8
|
+
export declare const DEFAULT_ENSEMBLE_RATE_LIMIT = 50;
|
|
9
|
+
/** Chat-only rate ceiling — §8. */
|
|
10
|
+
export declare const DEFAULT_CHAT_RATE_LIMIT = 100;
|
|
11
|
+
/** Window over which both rate caps are evaluated. */
|
|
12
|
+
export declare const RATE_LIMIT_WINDOW_MS = 1000;
|
|
13
|
+
/** How long to suppress non-essential streams after `throttled` fires. */
|
|
14
|
+
export declare const THROTTLE_SUPPRESS_MS = 1000;
|
|
15
|
+
/**
|
|
16
|
+
* Internal wire shape for an event traveling the bus. The SSE handler
|
|
17
|
+
* formats this into the `id:` / `event:` / `data:` lines on the wire.
|
|
18
|
+
*/
|
|
19
|
+
export interface BusEvent {
|
|
20
|
+
eventId: string;
|
|
21
|
+
/** Tuple form of `eventId`, for ring-buffer indexing + comparison. */
|
|
22
|
+
tuple: EventIdTuple;
|
|
23
|
+
type: SseEventKind;
|
|
24
|
+
payload: unknown;
|
|
25
|
+
emittedAt: number;
|
|
26
|
+
/**
|
|
27
|
+
* `true` when the event lives in the ring (`Last-Event-ID` replay
|
|
28
|
+
* sees it). Heartbeats are connection-local and excluded per §7.1.
|
|
29
|
+
*/
|
|
30
|
+
bufferable: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface SubscribeOpts {
|
|
33
|
+
/**
|
|
34
|
+
* Replay events with `seq > afterSeq` from the ring before live tail.
|
|
35
|
+
* Caller must have already verified epoch-match and that
|
|
36
|
+
* `afterSeq >= ringStart - 1` (otherwise the caller should drive a
|
|
37
|
+
* `gap` event).
|
|
38
|
+
*/
|
|
39
|
+
afterSeq?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Server-side topic filter. Setup events
|
|
42
|
+
* (`snapshot`, `gap`, `throttled`, `*.added`, `*.removed`,
|
|
43
|
+
* `*.created`, `*.destroyed`, `host_profile.changed`) always pass
|
|
44
|
+
* regardless of this filter.
|
|
45
|
+
*/
|
|
46
|
+
topics?: ReadonlySet<TopicCategory>;
|
|
47
|
+
}
|
|
48
|
+
/** Maps to `?topics=...` query string per spec §6.1. */
|
|
49
|
+
export type TopicCategory = 'phase' | 'chat' | 'flags' | 'schedules' | 'heartbeat';
|
|
50
|
+
/** Maps a `SseEventKind` to its filterable topic, or null when essential. */
|
|
51
|
+
export declare function topicOf(kind: SseEventKind): TopicCategory | null;
|
|
52
|
+
/**
|
|
53
|
+
* One open SSE connection's view of the bus. Async iterator yields
|
|
54
|
+
* events in the order the bus emitted them. `close()` is idempotent
|
|
55
|
+
* and must be called when the underlying socket goes away.
|
|
56
|
+
*/
|
|
57
|
+
export declare class Subscription implements AsyncIterableIterator<BusEvent> {
|
|
58
|
+
readonly opts: SubscribeOpts;
|
|
59
|
+
private queue;
|
|
60
|
+
private resolveNext;
|
|
61
|
+
private closed;
|
|
62
|
+
/** Caller's hook — bus calls this on close so the parent can drop us from its set. */
|
|
63
|
+
onClose: (() => void) | null;
|
|
64
|
+
constructor(opts: SubscribeOpts);
|
|
65
|
+
/** Push an event onto the consumer queue. Bus → subscription. */
|
|
66
|
+
push(e: BusEvent): void;
|
|
67
|
+
next(): Promise<IteratorResult<BusEvent>>;
|
|
68
|
+
return(): Promise<IteratorResult<BusEvent>>;
|
|
69
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<BusEvent>;
|
|
70
|
+
close(): void;
|
|
71
|
+
/** True when `close()` has been called. */
|
|
72
|
+
get isClosed(): boolean;
|
|
73
|
+
/** Snapshot of unread items — exposed for tests + diagnostics only. */
|
|
74
|
+
get pending(): readonly BusEvent[];
|
|
75
|
+
private passesTopicFilter;
|
|
76
|
+
}
|
|
77
|
+
export interface EventBusOptions {
|
|
78
|
+
/** Free-form scope label for log lines (`'ensemble:demo'`, `'global'`). */
|
|
79
|
+
scope: string;
|
|
80
|
+
allocator: SeqAllocator;
|
|
81
|
+
/** Ring capacity. Defaults to {@link RING_BUFFER_CAPACITY}. */
|
|
82
|
+
bufferCapacity?: number;
|
|
83
|
+
/** Test seam — defaults to `Date.now`. */
|
|
84
|
+
now?: () => number;
|
|
85
|
+
/** Override §8 limits — used by tests; production keeps defaults. */
|
|
86
|
+
ensembleRateLimit?: number;
|
|
87
|
+
chatRateLimit?: number;
|
|
88
|
+
heartbeatMs?: number;
|
|
89
|
+
heartbeatSuppressMs?: number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The bus interface — `EnsembleEventBus` and the global cluster bus
|
|
93
|
+
* share this surface. The aggregate poll loop is a strict consumer
|
|
94
|
+
* (only calls `emit`); the SSE handler reads `oldestSeq` /
|
|
95
|
+
* `replayFrom` / `subscribe`.
|
|
96
|
+
*/
|
|
97
|
+
export interface EventBus {
|
|
98
|
+
readonly scope: string;
|
|
99
|
+
readonly bootEpoch: number;
|
|
100
|
+
/** Ring's oldest seq, or `null` when empty. */
|
|
101
|
+
oldestSeq(): number | null;
|
|
102
|
+
/** Ring's newest seq, or `null` when empty. */
|
|
103
|
+
newestSeq(): number | null;
|
|
104
|
+
/** The next seq the allocator will use — useful for `lastEventId` math even when the ring is empty. */
|
|
105
|
+
nextSeq(): number;
|
|
106
|
+
/**
|
|
107
|
+
* Emit a typed event. Returns the assigned eventId, or `null` when
|
|
108
|
+
* the event was suppressed by §8 caps. Heartbeats with §6
|
|
109
|
+
* suppression also return `null`.
|
|
110
|
+
*/
|
|
111
|
+
emit(type: SseEventKind, payload: unknown): {
|
|
112
|
+
eventId: string;
|
|
113
|
+
} | null;
|
|
114
|
+
/** Replay events with `seq > afterSeq` from the ring buffer. */
|
|
115
|
+
replayFrom(afterSeq: number): BusEvent[];
|
|
116
|
+
/** Open a new subscription. Caller drives snapshot/gap upstream. */
|
|
117
|
+
subscribe(opts?: SubscribeOpts): Subscription;
|
|
118
|
+
/**
|
|
119
|
+
* Tick the heartbeat — emits `heartbeat` only if the §6 suppression
|
|
120
|
+
* gate is open. Production schedules this on a timer; tests call it
|
|
121
|
+
* directly. Returns the heartbeat's eventId, or `null` if suppressed.
|
|
122
|
+
*/
|
|
123
|
+
tickHeartbeat(): {
|
|
124
|
+
eventId: string;
|
|
125
|
+
} | null;
|
|
126
|
+
/** Drain subscribers and stop emitting. Idempotent. */
|
|
127
|
+
close(): void;
|
|
128
|
+
/** Live subscriber count — used by `/v1/health.subscriberCount`. */
|
|
129
|
+
subscriberCount(): number;
|
|
130
|
+
}
|
|
131
|
+
/** Concrete implementation. Same class powers per-ensemble + global buses. */
|
|
132
|
+
export declare class EnsembleEventBus implements EventBus {
|
|
133
|
+
readonly scope: string;
|
|
134
|
+
readonly bootEpoch: number;
|
|
135
|
+
private readonly allocator;
|
|
136
|
+
private readonly ring;
|
|
137
|
+
private readonly now;
|
|
138
|
+
private readonly subs;
|
|
139
|
+
private readonly ensembleRateLimit;
|
|
140
|
+
private readonly chatRateLimit;
|
|
141
|
+
private readonly heartbeatMs;
|
|
142
|
+
private readonly heartbeatSuppressMs;
|
|
143
|
+
private closed;
|
|
144
|
+
/** Sliding window of recent emit timestamps for the ensemble-wide cap. */
|
|
145
|
+
private readonly recentEmits;
|
|
146
|
+
/** Sliding window of recent chat emit timestamps. */
|
|
147
|
+
private readonly recentChat;
|
|
148
|
+
/** Last time *any* non-heartbeat event was emitted — drives §6 heartbeat suppression. */
|
|
149
|
+
private lastNonHeartbeatAt;
|
|
150
|
+
/** When set, suppress `heartbeat` and `flags.changed` until this timestamp (post-`throttled` window). */
|
|
151
|
+
private nonEssentialSuppressUntil;
|
|
152
|
+
/** Last time `throttled` was emitted — at most once per `THROTTLE_SUPPRESS_MS` window. */
|
|
153
|
+
private lastThrottledAt;
|
|
154
|
+
/**
|
|
155
|
+
* `chat.compressed` deferred-emission state (PR #324 review followup).
|
|
156
|
+
*
|
|
157
|
+
* **Why deferred**: §6 says "excess collapses into a single
|
|
158
|
+
* `chat.compressed` event" — singular. If we emitted on the first
|
|
159
|
+
* drop, the `dropped` field would always read `1` even when 50+
|
|
160
|
+
* messages got dropped in the same burst. Misleading metadata —
|
|
161
|
+
* eng-4's PR-3 wrapper might surface the count as "N messages
|
|
162
|
+
* dropped" or use it for retry logic.
|
|
163
|
+
*
|
|
164
|
+
* **Resolution**: track every drop in `chatDropCount`; on first
|
|
165
|
+
* drop schedule a `chat.compressed` emission `RATE_LIMIT_WINDOW_MS`
|
|
166
|
+
* later. Subsequent drops in the same burst just increment the
|
|
167
|
+
* counter — no second timer, no second event. When the timer
|
|
168
|
+
* fires, emit `chat.compressed { dropped: <total>, since: <iso> }`
|
|
169
|
+
* and reset. A 150-message burst at rate 1/s now yields one
|
|
170
|
+
* `chat.compressed { dropped: 149 }` event, matching the spec
|
|
171
|
+
* intent.
|
|
172
|
+
*
|
|
173
|
+
* Note: "compression event fired" (timer ran, message went on the
|
|
174
|
+
* wire) is separate from "drop count accumulated" (drops have
|
|
175
|
+
* happened but the timer is still pending). Tests differentiate
|
|
176
|
+
* the two by advancing the fake timer and re-draining.
|
|
177
|
+
*/
|
|
178
|
+
private chatDropCount;
|
|
179
|
+
private chatCompressedTimer;
|
|
180
|
+
constructor(opts: EventBusOptions);
|
|
181
|
+
oldestSeq(): number | null;
|
|
182
|
+
newestSeq(): number | null;
|
|
183
|
+
nextSeq(): number;
|
|
184
|
+
subscriberCount(): number;
|
|
185
|
+
emit(type: SseEventKind, payload: unknown): {
|
|
186
|
+
eventId: string;
|
|
187
|
+
} | null;
|
|
188
|
+
/**
|
|
189
|
+
* Internal emit — bypasses the §8 gates so the bus can self-emit
|
|
190
|
+
* `throttled` and `chat.compressed` while the gate is denying their
|
|
191
|
+
* trigger. Caller has already updated the rate-limit windows.
|
|
192
|
+
*/
|
|
193
|
+
private emitInternal;
|
|
194
|
+
/**
|
|
195
|
+
* Emit the deferred `chat.compressed` event with the accumulated
|
|
196
|
+
* drop count, then reset. Called by the `setTimeout` scheduled in
|
|
197
|
+
* the chat-rate-cap path; tests may invoke it directly to bypass
|
|
198
|
+
* `vi.advanceTimersByTime` plumbing.
|
|
199
|
+
*/
|
|
200
|
+
private flushChatCompressed;
|
|
201
|
+
/** Test seam — force a deferred `chat.compressed` to flush synchronously. */
|
|
202
|
+
_flushChatCompressedForTest(): void;
|
|
203
|
+
replayFrom(afterSeq: number): BusEvent[];
|
|
204
|
+
subscribe(opts?: SubscribeOpts): Subscription;
|
|
205
|
+
tickHeartbeat(): {
|
|
206
|
+
eventId: string;
|
|
207
|
+
} | null;
|
|
208
|
+
close(): void;
|
|
209
|
+
/** Drop entries older than `now - RATE_LIMIT_WINDOW_MS` from a sliding window. */
|
|
210
|
+
private trimWindow;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Drive the heartbeat on a real timer. Returns a stop function. Call
|
|
214
|
+
* sites pass the bus's own `tickHeartbeat` so test wiring can stay
|
|
215
|
+
* synchronous.
|
|
216
|
+
*/
|
|
217
|
+
export declare function startHeartbeatTimer(bus: Pick<EventBus, 'tickHeartbeat'>, intervalMs?: number): () => void;
|