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,641 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.readCache = readCache;
|
|
37
|
+
exports.writeCache = writeCache;
|
|
38
|
+
exports.isCacheFresh = isCacheFresh;
|
|
39
|
+
exports.classifyVersion = classifyVersion;
|
|
40
|
+
exports.bootstrap = bootstrap;
|
|
41
|
+
/**
|
|
42
|
+
* Auto-provisioning bootstrap state machine (#289 / S7 of #285).
|
|
43
|
+
*
|
|
44
|
+
* Bare `agent-tempo` invocation runs this on the way to the TUI. Six steps
|
|
45
|
+
* get the user from "nothing installed" → "ready for the TUI home view";
|
|
46
|
+
* each step is idempotent and cached where safe so a warm system completes
|
|
47
|
+
* in <50ms (steps 1–5) and a cold system stays under ~200ms.
|
|
48
|
+
*
|
|
49
|
+
* Step 7 is the caller's TUI handoff (`src/cli.ts` default path) — this
|
|
50
|
+
* module only produces the `BootstrapResult` that the TUI consumes as
|
|
51
|
+
* initial props.
|
|
52
|
+
*
|
|
53
|
+
* Per-step caching (`~/.agent-tempo/.bootstrap-cache.json`) is keyed by
|
|
54
|
+
* `schemaVersion` + `binaryVersion` so an upgrade wipes the cache and the
|
|
55
|
+
* new binary re-validates everything. Steps with volatile state (daemon
|
|
56
|
+
* liveness, orphan count) are never cached.
|
|
57
|
+
*
|
|
58
|
+
* No auto-resume on bare invocation (#289 pin item 1) — the home view is
|
|
59
|
+
* responsible for letting the user pick a parked ensemble to restore. Step
|
|
60
|
+
* 6 prefetches the ensemble list so the TUI renders instantly.
|
|
61
|
+
*/
|
|
62
|
+
const perf_hooks_1 = require("perf_hooks");
|
|
63
|
+
const child_process_1 = require("child_process");
|
|
64
|
+
const fs = __importStar(require("fs"));
|
|
65
|
+
const path = __importStar(require("path"));
|
|
66
|
+
const semver = __importStar(require("semver"));
|
|
67
|
+
const client_1 = require("@temporalio/client");
|
|
68
|
+
const config_1 = require("../config");
|
|
69
|
+
const connection_1 = require("../connection");
|
|
70
|
+
const mcp_1 = require("./mcp");
|
|
71
|
+
const daemon_1 = require("./daemon");
|
|
72
|
+
const orphans_1 = require("../reconcile/orphans");
|
|
73
|
+
const client_2 = require("../client");
|
|
74
|
+
const os_1 = require("os");
|
|
75
|
+
const git_info_1 = require("../git-info");
|
|
76
|
+
const legacy_migration_1 = require("./legacy-migration");
|
|
77
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
78
|
+
// Cache (schema v1)
|
|
79
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
80
|
+
const CACHE_SCHEMA_VERSION = 1;
|
|
81
|
+
const CACHE_FILENAME = '.bootstrap-cache.json';
|
|
82
|
+
function defaultCache(binaryVersion) {
|
|
83
|
+
return { schemaVersion: CACHE_SCHEMA_VERSION, binaryVersion, steps: {} };
|
|
84
|
+
}
|
|
85
|
+
/** Read the cache, validating schema + binary version. Any failure returns
|
|
86
|
+
* a fresh empty cache — malformed / upgrade-mismatched files are treated
|
|
87
|
+
* as a cache miss, the caller just does a cold bootstrap. */
|
|
88
|
+
function readCache(cacheDir, binaryVersion) {
|
|
89
|
+
const cachePath = path.join(cacheDir, CACHE_FILENAME);
|
|
90
|
+
try {
|
|
91
|
+
const raw = fs.readFileSync(cachePath, 'utf8');
|
|
92
|
+
const parsed = JSON.parse(raw);
|
|
93
|
+
if (parsed.schemaVersion !== CACHE_SCHEMA_VERSION)
|
|
94
|
+
return defaultCache(binaryVersion);
|
|
95
|
+
if (parsed.binaryVersion !== binaryVersion)
|
|
96
|
+
return defaultCache(binaryVersion);
|
|
97
|
+
if (!parsed.steps || typeof parsed.steps !== 'object')
|
|
98
|
+
return defaultCache(binaryVersion);
|
|
99
|
+
return {
|
|
100
|
+
schemaVersion: CACHE_SCHEMA_VERSION,
|
|
101
|
+
binaryVersion,
|
|
102
|
+
steps: parsed.steps,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Missing / unreadable / malformed — treat as cold.
|
|
107
|
+
return defaultCache(binaryVersion);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Best-effort cache write; never throws (a cache failure must not break bootstrap). */
|
|
111
|
+
function writeCache(cacheDir, cache) {
|
|
112
|
+
const cachePath = path.join(cacheDir, CACHE_FILENAME);
|
|
113
|
+
try {
|
|
114
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
115
|
+
fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2));
|
|
116
|
+
}
|
|
117
|
+
catch { /* non-fatal — next run will re-fill */ }
|
|
118
|
+
}
|
|
119
|
+
/** Decide if a cached step is fresh enough to skip. `undefined` entry or
|
|
120
|
+
* `lastSuccess` older than `ttlMs` → stale. */
|
|
121
|
+
function isCacheFresh(entry, ttlMs, now) {
|
|
122
|
+
if (!entry?.lastSuccess)
|
|
123
|
+
return false;
|
|
124
|
+
const last = Date.parse(entry.lastSuccess);
|
|
125
|
+
if (!Number.isFinite(last))
|
|
126
|
+
return false;
|
|
127
|
+
return now - last < ttlMs;
|
|
128
|
+
}
|
|
129
|
+
const TTL_24H = 24 * 60 * 60 * 1000;
|
|
130
|
+
const TTL_60S = 60 * 1000;
|
|
131
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
132
|
+
// Search-attribute list — imported from sa-preflight.ts so commands.ts,
|
|
133
|
+
// startup.ts, and the daemon-boot preflight all share one source of truth
|
|
134
|
+
// (#605 consolidated the two duplicated literals).
|
|
135
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
136
|
+
const sa_preflight_1 = require("./sa-preflight");
|
|
137
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
138
|
+
// Semver-aware outdated-version badge rendering (#289 pin item 4)
|
|
139
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
140
|
+
/** Decide the outdated-version badge shape per the policy table:
|
|
141
|
+
* - major/minor behind → badge with severity
|
|
142
|
+
* - patch-only → silent
|
|
143
|
+
* - prerelease vs stable mismatches → silent (respect release channel)
|
|
144
|
+
*/
|
|
145
|
+
function classifyVersion(installed, latest) {
|
|
146
|
+
const i = semver.parse(installed);
|
|
147
|
+
const l = semver.parse(latest);
|
|
148
|
+
if (!i || !l)
|
|
149
|
+
return undefined;
|
|
150
|
+
if (semver.gte(i, l))
|
|
151
|
+
return undefined;
|
|
152
|
+
const iPrerelease = i.prerelease.length > 0;
|
|
153
|
+
const lPrerelease = l.prerelease.length > 0;
|
|
154
|
+
// Channel respect: never nudge prerelease→stable downgrade or stable→prerelease.
|
|
155
|
+
if (iPrerelease && !lPrerelease)
|
|
156
|
+
return undefined;
|
|
157
|
+
if (!iPrerelease && lPrerelease)
|
|
158
|
+
return undefined;
|
|
159
|
+
// Prerelease iteration of the same minor — beta iteration is expected.
|
|
160
|
+
if (iPrerelease && lPrerelease && i.major === l.major && i.minor === l.minor) {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
const diff = semver.diff(installed, latest);
|
|
164
|
+
if (diff === 'major' || diff === 'premajor')
|
|
165
|
+
return { latest, severity: 'major' };
|
|
166
|
+
if (diff === 'minor' || diff === 'preminor')
|
|
167
|
+
return { latest, severity: 'minor' };
|
|
168
|
+
// 'patch', 'prepatch', 'prerelease' → silent
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
172
|
+
// Step helpers
|
|
173
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
174
|
+
async function timed(fn) {
|
|
175
|
+
const start = perf_hooks_1.performance.now();
|
|
176
|
+
const result = await fn();
|
|
177
|
+
return { result, durationMs: perf_hooks_1.performance.now() - start };
|
|
178
|
+
}
|
|
179
|
+
/** Fetch the latest published version from npm with a hard timeout. Never
|
|
180
|
+
* throws — returns `null` on any network / timeout / parse error so the
|
|
181
|
+
* caller can silently proceed (spec pin item 3). */
|
|
182
|
+
async function defaultFetchLatestVersion(pkgName, timeoutMs) {
|
|
183
|
+
const controller = new AbortController();
|
|
184
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
185
|
+
try {
|
|
186
|
+
const res = await fetch(`https://registry.npmjs.org/${pkgName}/latest`, {
|
|
187
|
+
signal: controller.signal,
|
|
188
|
+
});
|
|
189
|
+
if (!res.ok)
|
|
190
|
+
return null;
|
|
191
|
+
const body = await res.json();
|
|
192
|
+
return typeof body.version === 'string' ? body.version : null;
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
clearTimeout(timer);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/** Bounded tail-read budget. Long-running daemons can accumulate multi-MB
|
|
202
|
+
* logs; reading the entire file on every bootstrap is wasteful. Seek back
|
|
203
|
+
* from EOF by at most this many bytes — 32 KiB comfortably covers the last
|
|
204
|
+
* few hundred log lines without loading the full file. */
|
|
205
|
+
const DAEMON_LOG_TAIL_BYTES = 32 * 1024;
|
|
206
|
+
/** Read the last ~200 ERROR-tagged lines from the daemon log. Returns at
|
|
207
|
+
* most 3 samples. Bounded-tail read (see {@link DAEMON_LOG_TAIL_BYTES}). */
|
|
208
|
+
function daemonLogErrorTail(logPath) {
|
|
209
|
+
let fd;
|
|
210
|
+
try {
|
|
211
|
+
const stat = fs.statSync(logPath);
|
|
212
|
+
const size = stat.size;
|
|
213
|
+
if (size === 0)
|
|
214
|
+
return undefined;
|
|
215
|
+
const start = Math.max(0, size - DAEMON_LOG_TAIL_BYTES);
|
|
216
|
+
const length = size - start;
|
|
217
|
+
const buf = Buffer.alloc(length);
|
|
218
|
+
fd = fs.openSync(logPath, 'r');
|
|
219
|
+
fs.readSync(fd, buf, 0, length, start);
|
|
220
|
+
const content = buf.toString('utf8');
|
|
221
|
+
const lines = content.split(/\r?\n/);
|
|
222
|
+
// If we seeked mid-file, the first line may be a partial — discard it.
|
|
223
|
+
const tail = start > 0 ? lines.slice(1) : lines;
|
|
224
|
+
const errors = tail.filter((l) => /\bERROR\b/i.test(l));
|
|
225
|
+
if (errors.length === 0)
|
|
226
|
+
return undefined;
|
|
227
|
+
return { count: errors.length, sample: errors.slice(-3), logPath };
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
finally {
|
|
233
|
+
if (fd !== undefined)
|
|
234
|
+
try {
|
|
235
|
+
fs.closeSync(fd);
|
|
236
|
+
}
|
|
237
|
+
catch { /* ignore */ }
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
241
|
+
// Individual steps
|
|
242
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
243
|
+
/**
|
|
244
|
+
* Default step-0 implementation — invokes the one-shot legacy home migration
|
|
245
|
+
* (`~/.agent-tempo/` → `~/.agent-tempo/`). Idempotent: re-runs are
|
|
246
|
+
* `'skipped'` once the marker is in place. Failure is recorded but never
|
|
247
|
+
* blocks bootstrap (PR-2 brief).
|
|
248
|
+
*/
|
|
249
|
+
async function defaultLegacyHomeMigrationStep() {
|
|
250
|
+
const t0 = perf_hooks_1.performance.now();
|
|
251
|
+
try {
|
|
252
|
+
const result = await (0, legacy_migration_1.migrateLegacyHome)();
|
|
253
|
+
const durationMs = perf_hooks_1.performance.now() - t0;
|
|
254
|
+
const detail = (0, legacy_migration_1.formatMigrationResult)(result);
|
|
255
|
+
switch (result.status) {
|
|
256
|
+
case 'no-legacy':
|
|
257
|
+
case 'already-migrated':
|
|
258
|
+
return { status: 'skipped', durationMs, detail };
|
|
259
|
+
case 'migrated':
|
|
260
|
+
return { status: 'action-taken', durationMs, detail };
|
|
261
|
+
case 'skipped':
|
|
262
|
+
return { status: 'skipped', durationMs, detail };
|
|
263
|
+
case 'failed':
|
|
264
|
+
return { status: 'failed', durationMs, detail };
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
catch (err) {
|
|
268
|
+
return {
|
|
269
|
+
status: 'failed',
|
|
270
|
+
durationMs: perf_hooks_1.performance.now() - t0,
|
|
271
|
+
detail: `legacy-migration crashed: ${err.message}`,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
async function stepPreflight(cache, now) {
|
|
276
|
+
if (isCacheFresh(cache.steps.preflight, TTL_24H, now)) {
|
|
277
|
+
return { status: 'skipped', durationMs: 0 };
|
|
278
|
+
}
|
|
279
|
+
const { result, durationMs } = await timed(() => {
|
|
280
|
+
const errors = [];
|
|
281
|
+
const major = parseInt(process.version.slice(1), 10);
|
|
282
|
+
if (major < 20)
|
|
283
|
+
errors.push(`Node.js 20+ required, found ${process.version}`);
|
|
284
|
+
// No `claude` binary probe here: the user's default agent may be
|
|
285
|
+
// `copilot`, and spawn-time errors are more actionable than a startup
|
|
286
|
+
// preflight block. CI environments without claude installed also need
|
|
287
|
+
// bootstrap to succeed so the TUI can render diagnostics. A future
|
|
288
|
+
// TUI badge can surface "claude not found" when the agent requires it.
|
|
289
|
+
try {
|
|
290
|
+
fs.mkdirSync(config_1.AGENT_TEMPO_HOME, { recursive: true });
|
|
291
|
+
fs.accessSync(config_1.AGENT_TEMPO_HOME, fs.constants.W_OK);
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
errors.push(`${config_1.AGENT_TEMPO_HOME} is not writable. Check permissions or set $HOME.`);
|
|
295
|
+
}
|
|
296
|
+
return errors;
|
|
297
|
+
});
|
|
298
|
+
if (result.length > 0) {
|
|
299
|
+
return { status: 'failed', durationMs, detail: result.join('; ') };
|
|
300
|
+
}
|
|
301
|
+
cache.steps.preflight = { lastSuccess: new Date(now).toISOString() };
|
|
302
|
+
return { status: 'ok', durationMs };
|
|
303
|
+
}
|
|
304
|
+
async function stepMcpConfig(cache, cwd, now) {
|
|
305
|
+
const cached = cache.steps.mcpConfig;
|
|
306
|
+
let configMtime;
|
|
307
|
+
try {
|
|
308
|
+
const projectMcp = path.join(cwd, '.mcp.json');
|
|
309
|
+
if (fs.existsSync(projectMcp)) {
|
|
310
|
+
configMtime = fs.statSync(projectMcp).mtime.toISOString();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch { /* ignore — no-mtime path */ }
|
|
314
|
+
if (isCacheFresh(cached, TTL_24H, now) &&
|
|
315
|
+
cached?.configMtime === configMtime) {
|
|
316
|
+
return { status: 'skipped', durationMs: 0 };
|
|
317
|
+
}
|
|
318
|
+
const { result: outcome, durationMs } = await timed(() => {
|
|
319
|
+
if ((0, mcp_1.isMcpConfigured)(cwd)) {
|
|
320
|
+
return { status: 'ok', durationMs: 0 };
|
|
321
|
+
}
|
|
322
|
+
// Install into global user scope (matches current `init` behavior).
|
|
323
|
+
if (!(0, mcp_1.isGlobalMcpRegistered)() && (0, mcp_1.addGlobalMcp)()) {
|
|
324
|
+
return { status: 'action-taken', durationMs: 0, detail: 'registered agent-tempo in user MCP scope' };
|
|
325
|
+
}
|
|
326
|
+
return { status: 'failed', durationMs: 0, detail: 'Could not register agent-tempo MCP. Run `agent-tempo init` manually.' };
|
|
327
|
+
});
|
|
328
|
+
if (outcome.status !== 'failed') {
|
|
329
|
+
cache.steps.mcpConfig = {
|
|
330
|
+
lastSuccess: new Date(now).toISOString(),
|
|
331
|
+
...(configMtime !== undefined ? { configMtime } : {}),
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
return { ...outcome, durationMs };
|
|
335
|
+
}
|
|
336
|
+
async function stepTemporalReach(cache, config, now, reachableProbe) {
|
|
337
|
+
if (isCacheFresh(cache.steps.temporalReach, TTL_60S, now)) {
|
|
338
|
+
return { status: 'skipped', durationMs: 0 };
|
|
339
|
+
}
|
|
340
|
+
const { result: outcome, durationMs } = await timed(async () => {
|
|
341
|
+
const reachable = await reachableProbe(config);
|
|
342
|
+
if (reachable)
|
|
343
|
+
return { status: 'ok', durationMs: 0 };
|
|
344
|
+
// Auto-start only when the address is local. Remote failures surface
|
|
345
|
+
// an actionable error; we don't try to spawn a remote server.
|
|
346
|
+
if (!isLocalAddress(config.temporalAddress)) {
|
|
347
|
+
return {
|
|
348
|
+
status: 'failed',
|
|
349
|
+
durationMs: 0,
|
|
350
|
+
detail: `Cannot reach remote Temporal at ${config.temporalAddress}. Check TEMPORAL_ADDRESS + network.`,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
if (!hasTemporalCli()) {
|
|
354
|
+
return {
|
|
355
|
+
status: 'failed',
|
|
356
|
+
durationMs: 0,
|
|
357
|
+
detail: 'temporal CLI not found on PATH. Install from https://docs.temporal.io/cli and re-run.',
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
const started = await startTemporalDevServer(config, reachableProbe);
|
|
361
|
+
if (started) {
|
|
362
|
+
return { status: 'action-taken', durationMs: 0, detail: `started temporal dev server at ${config.temporalAddress}` };
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
status: 'failed',
|
|
366
|
+
durationMs: 0,
|
|
367
|
+
detail: `temporal dev server did not become reachable at ${config.temporalAddress}`,
|
|
368
|
+
};
|
|
369
|
+
});
|
|
370
|
+
if (outcome.status !== 'failed') {
|
|
371
|
+
cache.steps.temporalReach = { lastSuccess: new Date(now).toISOString() };
|
|
372
|
+
}
|
|
373
|
+
return { ...outcome, durationMs };
|
|
374
|
+
}
|
|
375
|
+
async function stepSearchAttrs(cache, config, now) {
|
|
376
|
+
if (isCacheFresh(cache.steps.searchAttrs, TTL_24H, now)) {
|
|
377
|
+
return { status: 'skipped', durationMs: 0 };
|
|
378
|
+
}
|
|
379
|
+
const { result: outcome, durationMs } = await timed(() => {
|
|
380
|
+
// Per-attr classification via `registerSearchAttribute` (#605) —
|
|
381
|
+
// distinguishes `already-exists` (idempotent expected case) from real
|
|
382
|
+
// failures. Pre-#605 every non-zero exit was swallowed as "already
|
|
383
|
+
// registered", masking the SQLite dev-server's 10-Keyword-per-namespace
|
|
384
|
+
// cap and other genuine errors until a downstream workflow start failed
|
|
385
|
+
// with the confusing `INVALID_ARGUMENT: search attribute ... is not
|
|
386
|
+
// defined`.
|
|
387
|
+
const failures = [];
|
|
388
|
+
for (const attr of sa_preflight_1.REQUIRED_SEARCH_ATTRIBUTES) {
|
|
389
|
+
const r = (0, sa_preflight_1.registerSearchAttribute)(attr, config.temporalAddress, config.temporalNamespace);
|
|
390
|
+
if (r.status === 'failed') {
|
|
391
|
+
failures.push(`${attr.name}: ${r.detail ?? 'unknown error'}`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
if (failures.length > 0) {
|
|
395
|
+
return {
|
|
396
|
+
status: 'failed',
|
|
397
|
+
durationMs: 0,
|
|
398
|
+
detail: `Failed to register ${failures.length} search attribute(s):\n ${failures.join('\n ')}`,
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
return { status: 'ok', durationMs: 0 };
|
|
402
|
+
});
|
|
403
|
+
if (outcome.status !== 'failed') {
|
|
404
|
+
cache.steps.searchAttrs = { lastSuccess: new Date(now).toISOString() };
|
|
405
|
+
}
|
|
406
|
+
return { ...outcome, durationMs };
|
|
407
|
+
}
|
|
408
|
+
async function stepDaemonBootAsync(config) {
|
|
409
|
+
const start = perf_hooks_1.performance.now();
|
|
410
|
+
if ((0, daemon_1.isDaemonRunning)()) {
|
|
411
|
+
// Cheap authoritative check: heartbeat file mtime must be within 2×
|
|
412
|
+
// the interval — otherwise the daemon is hung.
|
|
413
|
+
try {
|
|
414
|
+
const age = Date.now() - fs.statSync(daemon_1.DAEMON_HEARTBEAT_PATH).mtimeMs;
|
|
415
|
+
if (age > daemon_1.HEARTBEAT_INTERVAL_MS * daemon_1.HEARTBEAT_STALE_MULTIPLIER) {
|
|
416
|
+
return {
|
|
417
|
+
status: 'failed',
|
|
418
|
+
durationMs: perf_hooks_1.performance.now() - start,
|
|
419
|
+
detail: `daemon heartbeat stale (${Math.round(age / 1000)}s). Check ${daemon_1.DAEMON_LOG_PATH}.`,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
catch { /* no heartbeat file yet — daemon is fresh, treat as ok */ }
|
|
424
|
+
return { status: 'skipped', durationMs: perf_hooks_1.performance.now() - start };
|
|
425
|
+
}
|
|
426
|
+
try {
|
|
427
|
+
const pid = await (0, daemon_1.startDaemon)(config);
|
|
428
|
+
return {
|
|
429
|
+
status: 'action-taken',
|
|
430
|
+
durationMs: perf_hooks_1.performance.now() - start,
|
|
431
|
+
detail: `started daemon (pid ${pid})`,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
catch (err) {
|
|
435
|
+
return {
|
|
436
|
+
status: 'failed',
|
|
437
|
+
durationMs: perf_hooks_1.performance.now() - start,
|
|
438
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
async function stepBadgeCollection(config, cache, now, binaryVersion, fetchLatest, reachableProbe) {
|
|
443
|
+
const start = perf_hooks_1.performance.now();
|
|
444
|
+
let orphanCount = 0;
|
|
445
|
+
let ensembles = [];
|
|
446
|
+
let outdatedVersion;
|
|
447
|
+
const hostname = (0, os_1.hostname)();
|
|
448
|
+
// Sub-A: orphan count + ensembles list — Temporal connect runs through the
|
|
449
|
+
// injected `reachableProbe` first so a stale `temporalAddress` can't block
|
|
450
|
+
// the TUI. Hard 3s wall-clock budget on the actual connect + queries.
|
|
451
|
+
let connection;
|
|
452
|
+
try {
|
|
453
|
+
if (!(await reachableProbe(config)))
|
|
454
|
+
throw new Error('unreachable');
|
|
455
|
+
connection = await Promise.race([
|
|
456
|
+
(0, connection_1.createTemporalConnection)(config),
|
|
457
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 3000)),
|
|
458
|
+
]);
|
|
459
|
+
const client = new client_1.Client({ connection, namespace: config.temporalNamespace });
|
|
460
|
+
const tempo = (0, client_2.createTempoClient)(client);
|
|
461
|
+
const [orphans, summaries] = await Promise.all([
|
|
462
|
+
(0, orphans_1.queryOrphanedSessions)(client, { hostname }).catch(() => []),
|
|
463
|
+
tempo.discoverEnsembles().catch(() => []),
|
|
464
|
+
]);
|
|
465
|
+
orphanCount = orphans.length;
|
|
466
|
+
ensembles = summaries;
|
|
467
|
+
}
|
|
468
|
+
catch { /* degraded — bootstrap still returns, TUI shows connection error */ }
|
|
469
|
+
finally {
|
|
470
|
+
if (connection)
|
|
471
|
+
try {
|
|
472
|
+
await connection.close();
|
|
473
|
+
}
|
|
474
|
+
catch { /* ignore */ }
|
|
475
|
+
}
|
|
476
|
+
// Sub-B: npm-version check — 24h cached, 500ms AbortController timeout,
|
|
477
|
+
// silent fallback on network failure (pin items 2 + 3).
|
|
478
|
+
const cachedNpm = cache.steps.npmVersionCheck;
|
|
479
|
+
let latest = null;
|
|
480
|
+
if (isCacheFresh(cachedNpm, TTL_24H, now) && cachedNpm?.result) {
|
|
481
|
+
latest = cachedNpm.result.latest;
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
latest = await fetchLatest('agent-tempo', 500);
|
|
485
|
+
if (latest) {
|
|
486
|
+
cache.steps.npmVersionCheck = {
|
|
487
|
+
lastSuccess: new Date(now).toISOString(),
|
|
488
|
+
result: { latest },
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
// If fetch returned null (timeout / offline), do NOT update the cache —
|
|
492
|
+
// next bootstrap will try again immediately.
|
|
493
|
+
}
|
|
494
|
+
if (latest) {
|
|
495
|
+
outdatedVersion = classifyVersion(binaryVersion, latest);
|
|
496
|
+
}
|
|
497
|
+
// Sub-C: daemon log error tail. Cheap, always runs.
|
|
498
|
+
const daemonLogErrors = daemonLogErrorTail(daemon_1.DAEMON_LOG_PATH);
|
|
499
|
+
return {
|
|
500
|
+
badges: {
|
|
501
|
+
orphanCount,
|
|
502
|
+
...(outdatedVersion ? { outdatedVersion } : {}),
|
|
503
|
+
...(daemonLogErrors ? { daemonLogErrors } : {}),
|
|
504
|
+
},
|
|
505
|
+
ensembles,
|
|
506
|
+
outcome: { status: 'ok', durationMs: perf_hooks_1.performance.now() - start },
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
510
|
+
// Plumbing helpers (Temporal reachability probe + dev-server spawn)
|
|
511
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
512
|
+
async function isTemporalReachable(config, timeoutMs = 3000) {
|
|
513
|
+
try {
|
|
514
|
+
const conn = await Promise.race([
|
|
515
|
+
(0, connection_1.createTemporalConnection)(config),
|
|
516
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeoutMs)),
|
|
517
|
+
]);
|
|
518
|
+
try {
|
|
519
|
+
const client = new client_1.Client({ connection: conn, namespace: config.temporalNamespace });
|
|
520
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
521
|
+
for await (const _ of client.workflow.list({ query: 'WorkflowId = "__readiness_probe__"' })) {
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
finally {
|
|
526
|
+
await conn.close();
|
|
527
|
+
}
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
catch {
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function isLocalAddress(address) {
|
|
535
|
+
const host = address.split(':')[0] || '';
|
|
536
|
+
return host === 'localhost' || host === '127.0.0.1' || host === '::1' || host === '';
|
|
537
|
+
}
|
|
538
|
+
function hasTemporalCli() {
|
|
539
|
+
const cmd = process.platform === 'win32' ? 'where' : 'which';
|
|
540
|
+
try {
|
|
541
|
+
(0, child_process_1.execFileSync)(cmd, ['temporal'], { stdio: 'ignore' });
|
|
542
|
+
return true;
|
|
543
|
+
}
|
|
544
|
+
catch {
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
async function startTemporalDevServer(config, reachableProbe) {
|
|
549
|
+
fs.mkdirSync(config_1.AGENT_TEMPO_HOME, { recursive: true });
|
|
550
|
+
const port = config.temporalAddress.split(':')[1] || '7233';
|
|
551
|
+
const dbPath = path.join(config_1.AGENT_TEMPO_HOME, 'temporal-data.db');
|
|
552
|
+
const child = (0, child_process_1.spawn)('temporal', ['server', 'start-dev', '--port', port, '--db-filename', dbPath], {
|
|
553
|
+
detached: true,
|
|
554
|
+
stdio: 'ignore',
|
|
555
|
+
});
|
|
556
|
+
child.unref();
|
|
557
|
+
for (let i = 0; i < 20; i++) {
|
|
558
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
559
|
+
if (await reachableProbe(config))
|
|
560
|
+
return true;
|
|
561
|
+
}
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
565
|
+
// Public entry point
|
|
566
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
567
|
+
/** Read the installed package version. Cached behind a function so tests
|
|
568
|
+
* can override via `BootstrapArgs.binaryVersion`. */
|
|
569
|
+
function readBinaryVersion() {
|
|
570
|
+
try {
|
|
571
|
+
const pkg = require('../../package.json');
|
|
572
|
+
return pkg.version;
|
|
573
|
+
}
|
|
574
|
+
catch {
|
|
575
|
+
return '0.0.0';
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Run the 7-step auto-provisioning sequence. Returns a `BootstrapResult`
|
|
580
|
+
* the caller feeds to the TUI; step 7 (TUI launch) is the caller's
|
|
581
|
+
* handoff — this function does NOT spawn UI processes.
|
|
582
|
+
*/
|
|
583
|
+
async function bootstrap(args) {
|
|
584
|
+
const start = perf_hooks_1.performance.now();
|
|
585
|
+
const cwd = args.cwd ?? process.cwd();
|
|
586
|
+
const now = (args.now ?? (() => Date.now()))();
|
|
587
|
+
const cacheDir = args.cacheDir ?? config_1.AGENT_TEMPO_HOME;
|
|
588
|
+
const binaryVersion = args.binaryVersion ?? readBinaryVersion();
|
|
589
|
+
const fetchLatest = args.fetchLatestVersion ?? defaultFetchLatestVersion;
|
|
590
|
+
const cache = readCache(cacheDir, binaryVersion);
|
|
591
|
+
const reachableProbe = args.isTemporalReachable ?? ((c) => isTemporalReachable(c, 3000));
|
|
592
|
+
// Step 0: legacy home migration (`~/.agent-tempo/` → `~/.agent-tempo/`)
|
|
593
|
+
// — PR-2 of the v1.0 rebrand. Runs before preflight so subsequent steps
|
|
594
|
+
// (cache read, MCP config write, daemon boot) all see the new home.
|
|
595
|
+
// MUST NOT block bootstrap — failure becomes a `'failed'` step with
|
|
596
|
+
// `detail`, and we keep going.
|
|
597
|
+
const legacyHomeMigration = await (args.legacyHomeMigration ?? defaultLegacyHomeMigrationStep)();
|
|
598
|
+
// Steps 1–5: fail-fast on step 1 so we don't try to register MCP on an
|
|
599
|
+
// incompatible Node. Each step mutates the cache in-place.
|
|
600
|
+
const preflight = await stepPreflight(cache, now);
|
|
601
|
+
// Steps 2 + 3 are independent (MCP config is local fs/shell; Temporal
|
|
602
|
+
// reachability is network), so run them in parallel — up to ~300ms
|
|
603
|
+
// cold-path savings when the claude-mcp-list shell-out is slow.
|
|
604
|
+
const [mcpConfig, temporalReach] = preflight.status === 'failed'
|
|
605
|
+
? [
|
|
606
|
+
{ status: 'skipped', durationMs: 0 },
|
|
607
|
+
{ status: 'skipped', durationMs: 0 },
|
|
608
|
+
]
|
|
609
|
+
: await Promise.all([
|
|
610
|
+
stepMcpConfig(cache, cwd, now),
|
|
611
|
+
stepTemporalReach(cache, args.config, now, reachableProbe),
|
|
612
|
+
]);
|
|
613
|
+
const searchAttrs = temporalReach.status === 'failed'
|
|
614
|
+
? { status: 'skipped', durationMs: 0, detail: 'skipped — temporal unreachable' }
|
|
615
|
+
: await stepSearchAttrs(cache, args.config, now);
|
|
616
|
+
const daemonBoot = preflight.status === 'failed'
|
|
617
|
+
? { status: 'skipped', durationMs: 0 }
|
|
618
|
+
: await (args.daemonBoot ?? stepDaemonBootAsync)(args.config);
|
|
619
|
+
// Step 6: badges + ensembles prefetch. Runs even on partial-failure paths
|
|
620
|
+
// so the TUI can render something meaningful; Temporal-connect failure
|
|
621
|
+
// degrades to zeros / empty lists rather than throwing.
|
|
622
|
+
const badgeStep = await stepBadgeCollection(args.config, cache, now, binaryVersion, fetchLatest, reachableProbe);
|
|
623
|
+
// Persist cache after all steps — one write per bootstrap.
|
|
624
|
+
writeCache(cacheDir, cache);
|
|
625
|
+
return {
|
|
626
|
+
durationMs: perf_hooks_1.performance.now() - start,
|
|
627
|
+
steps: {
|
|
628
|
+
legacyHomeMigration,
|
|
629
|
+
preflight,
|
|
630
|
+
mcpConfig,
|
|
631
|
+
temporalReach,
|
|
632
|
+
searchAttrs,
|
|
633
|
+
daemonBoot,
|
|
634
|
+
badgeCollection: badgeStep.outcome,
|
|
635
|
+
},
|
|
636
|
+
badges: badgeStep.badges,
|
|
637
|
+
ensembles: badgeStep.ensembles,
|
|
638
|
+
cwd,
|
|
639
|
+
cwdGitRoot: (0, git_info_1.getGitInfo)(cwd).gitRoot ?? null,
|
|
640
|
+
};
|
|
641
|
+
}
|