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,493 @@
|
|
|
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.evaluateStartPreflight = evaluateStartPreflight;
|
|
37
|
+
exports.daemon = daemon;
|
|
38
|
+
exports.formatBytesAsMb = formatBytesAsMb;
|
|
39
|
+
exports.formatUptime = formatUptime;
|
|
40
|
+
/**
|
|
41
|
+
* Daemon CLI command handler — `agent-tempo daemon <start|stop|status|logs|install|uninstall>`.
|
|
42
|
+
*
|
|
43
|
+
* **Critical constraint**: this module must NOT import from `@temporalio/*`,
|
|
44
|
+
* `../workflows/*`, `../adapters/*`, `../spawn`, `../client`, or any module
|
|
45
|
+
* that transitively pulls in the Temporal SDK or rxjs. The daemon CLI must
|
|
46
|
+
* remain operable even when the Temporal SDK itself is broken (e.g. a
|
|
47
|
+
* `@temporalio/core-bridge` native-module build failure on an unsupported
|
|
48
|
+
* Node version — see issue #157: users were stranded with orphan processes
|
|
49
|
+
* they couldn't stop because `daemon stop` crashed before executing).
|
|
50
|
+
*
|
|
51
|
+
* Keeping this module's dep graph minimal also avoids pulling ~250MB of
|
|
52
|
+
* Temporal SDK code + workflow bundle parsing into every CLI invocation.
|
|
53
|
+
*
|
|
54
|
+
* ## Test guarantee
|
|
55
|
+
*
|
|
56
|
+
* `test/daemon-command-isolation.test.ts` spawns a child Node process that
|
|
57
|
+
* requires the compiled `dist/cli/daemon-command.js` and asserts that
|
|
58
|
+
* `require.cache` contains zero entries matching `@temporalio|rxjs|@grpc`.
|
|
59
|
+
* If you add an import here that transitively leaks Temporal deps, that
|
|
60
|
+
* test will fail.
|
|
61
|
+
*/
|
|
62
|
+
const fs_1 = require("fs");
|
|
63
|
+
const path_1 = require("path");
|
|
64
|
+
const os_1 = require("os");
|
|
65
|
+
const child_process_1 = require("child_process");
|
|
66
|
+
const http = __importStar(require("http"));
|
|
67
|
+
const config_1 = require("../config");
|
|
68
|
+
const port_file_1 = require("../http/port-file");
|
|
69
|
+
const daemon_1 = require("./daemon");
|
|
70
|
+
const out = __importStar(require("./output"));
|
|
71
|
+
/**
|
|
72
|
+
* Pure decision function for `daemon start`. Given a scanner result and the
|
|
73
|
+
* current daemon status, computes whether to no-op, abort with orphans, or
|
|
74
|
+
* spawn. `force` bypasses the orphan check and signals that a stale pid file
|
|
75
|
+
* (if any) should be cleared before the spawn.
|
|
76
|
+
*
|
|
77
|
+
* `otherProfilePid` is the live PID (if any) of the opposite profile's
|
|
78
|
+
* daemon (dev's prod sibling, or prod's dev sibling). Including it in the
|
|
79
|
+
* known-PID set keeps cross-profile coexistence working (ADR 0014 §5.6) —
|
|
80
|
+
* starting the dev daemon must not flag the prod daemon as an orphan, and
|
|
81
|
+
* vice versa.
|
|
82
|
+
*
|
|
83
|
+
* @internal — exported for unit tests in test/daemon-start-orphan-check.test.ts.
|
|
84
|
+
*/
|
|
85
|
+
function evaluateStartPreflight(scanned, status, force, otherProfilePid) {
|
|
86
|
+
if (status.running && typeof status.pid === 'number') {
|
|
87
|
+
return { action: 'already-running', pid: status.pid };
|
|
88
|
+
}
|
|
89
|
+
if (!force) {
|
|
90
|
+
const orphans = (0, daemon_1.selectOrphans)(scanned, [status.pid, otherProfilePid]);
|
|
91
|
+
if (orphans.length > 0)
|
|
92
|
+
return { action: 'abort', orphans };
|
|
93
|
+
}
|
|
94
|
+
return { action: 'spawn', cleanupStalePid: force };
|
|
95
|
+
}
|
|
96
|
+
/** Package root is two levels up from dist/cli/ */
|
|
97
|
+
const PACKAGE_ROOT = (0, path_1.resolve)(__dirname, '..', '..');
|
|
98
|
+
function packagingFile(...segments) {
|
|
99
|
+
return (0, path_1.join)(PACKAGE_ROOT, 'packaging', ...segments);
|
|
100
|
+
}
|
|
101
|
+
async function daemon(opts) {
|
|
102
|
+
const config = (0, config_1.getConfig)(opts);
|
|
103
|
+
switch (opts.subcommand) {
|
|
104
|
+
case 'start': {
|
|
105
|
+
const status = (0, daemon_1.getDaemonStatus)();
|
|
106
|
+
// ADR 0014 §5.6 — if the OPPOSITE profile's daemon is running on this
|
|
107
|
+
// machine, exclude its PID from the orphan set. Dev + prod daemons
|
|
108
|
+
// are designed to coexist (different home dir / port / namespace).
|
|
109
|
+
// When the other profile shows weak evidence of running (port file
|
|
110
|
+
// exists but PID file doesn't / PID is unparseable), skip the orphan
|
|
111
|
+
// scan entirely — see also `stopDaemon`'s mirroring behavior.
|
|
112
|
+
const otherPid = (0, daemon_1.getOtherProfilePid)();
|
|
113
|
+
const skipOrphanScan = (0, daemon_1.isOtherProfileLikelyRunning)() && otherPid === undefined;
|
|
114
|
+
if (skipOrphanScan) {
|
|
115
|
+
out.warn('Skipping orphan-process scan — the other profile (dev/prod) appears to be running ' +
|
|
116
|
+
'without a PID file. Re-run with `daemon start --force` if you have already verified ' +
|
|
117
|
+
'no rogue daemon for THIS profile is present.');
|
|
118
|
+
}
|
|
119
|
+
const preflight = evaluateStartPreflight(
|
|
120
|
+
// Skip the actual OS scan when we're already-running, force is set,
|
|
121
|
+
// or we're suppressing for cross-profile safety.
|
|
122
|
+
status.running || opts.force || skipOrphanScan ? [] : (0, daemon_1.scanAgentTempoDaemons)(), status, Boolean(opts.force) || skipOrphanScan, otherPid);
|
|
123
|
+
switch (preflight.action) {
|
|
124
|
+
case 'already-running':
|
|
125
|
+
out.success(`Daemon already running (pid ${preflight.pid})`);
|
|
126
|
+
return;
|
|
127
|
+
case 'abort':
|
|
128
|
+
// Piling a new daemon on top of orphans is the original #157 user-pain
|
|
129
|
+
// scenario. User must clean up first — see troubleshooting docs.
|
|
130
|
+
out.error(`Found ${preflight.orphans.length} orphaned agent-tempo daemon process${preflight.orphans.length === 1 ? '' : 'es'} — daemon start aborted.`);
|
|
131
|
+
for (const p of preflight.orphans)
|
|
132
|
+
out.log(` pid ${p.pid}: ${p.commandLine}`);
|
|
133
|
+
out.log('');
|
|
134
|
+
out.log(` ${out.dim('Emergency cleanup: see docs/troubleshooting.md → "Orphaned daemon processes"')}`);
|
|
135
|
+
out.log(` ${out.dim('Override (use only after confirming): agent-tempo daemon start --force')}`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
break;
|
|
138
|
+
case 'spawn':
|
|
139
|
+
if (preflight.cleanupStalePid && (0, fs_1.existsSync)(daemon_1.DAEMON_PID_PATH)) {
|
|
140
|
+
// Force path — clean up a stale pid file if present.
|
|
141
|
+
// `getDaemonStatus` already unlinks the file when it detects a
|
|
142
|
+
// dead pid; this handles the rarer "file exists, contents
|
|
143
|
+
// unparseable OR fs error" branch.
|
|
144
|
+
try {
|
|
145
|
+
(0, fs_1.unlinkSync)(daemon_1.DAEMON_PID_PATH);
|
|
146
|
+
}
|
|
147
|
+
catch { /* ignore */ }
|
|
148
|
+
}
|
|
149
|
+
out.log('Starting daemon...');
|
|
150
|
+
try {
|
|
151
|
+
const pid = await (0, daemon_1.startDaemon)(config);
|
|
152
|
+
out.success(`Daemon started (pid ${pid})`);
|
|
153
|
+
out.log(` ${out.dim('Logs: ' + daemon_1.DAEMON_LOG_PATH)}`);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
out.error(err.message || String(err));
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case 'stop': {
|
|
164
|
+
if ((0, daemon_1.stopDaemon)()) {
|
|
165
|
+
out.success('Daemon stopped');
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
out.warn('Daemon is not running');
|
|
169
|
+
}
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
case 'status': {
|
|
173
|
+
const status = (0, daemon_1.getDaemonStatus)();
|
|
174
|
+
const scanned = (0, daemon_1.scanAgentTempoDaemons)();
|
|
175
|
+
if (status.running) {
|
|
176
|
+
out.success(`Daemon running (pid ${status.pid})`);
|
|
177
|
+
// Heartbeat diagnostic — distinguishes "pid alive AND main loop
|
|
178
|
+
// serving" from "pid alive but something hung" (#157 PR B).
|
|
179
|
+
const staleThresholdMs = daemon_1.HEARTBEAT_INTERVAL_MS * daemon_1.HEARTBEAT_STALE_MULTIPLIER;
|
|
180
|
+
if (status.heartbeatAge !== undefined && status.heartbeatAge !== null) {
|
|
181
|
+
const ageSec = Math.round(status.heartbeatAge / 1000);
|
|
182
|
+
if (status.heartbeatAge > staleThresholdMs) {
|
|
183
|
+
out.warn(` Last heartbeat: ${ageSec}s ago — STALE (threshold ${staleThresholdMs / 1000}s). The daemon's main loop may be hung.`);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
out.log(` ${out.dim(`Last heartbeat: ${ageSec}s ago`)}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else if (status.heartbeatAge === null) {
|
|
190
|
+
out.log(` ${out.dim('Last heartbeat: (not yet written — daemon just started or pre-heartbeat version)')}`);
|
|
191
|
+
}
|
|
192
|
+
// Warn if the scanner reports extras the pid file doesn't know about —
|
|
193
|
+
// orphans from a prior crashed run that never removed its pid file, or
|
|
194
|
+
// a second daemon started by a stale concurrent CLI invocation (#157).
|
|
195
|
+
// The opposite profile's daemon (if running) also gets excluded so
|
|
196
|
+
// prod doesn't flag dev as an orphan / vice versa (ADR 0014 §5.6).
|
|
197
|
+
const extras = (0, daemon_1.selectOrphans)(scanned, [status.pid, (0, daemon_1.getOtherProfilePid)()]);
|
|
198
|
+
if (extras.length > 0) {
|
|
199
|
+
out.warn(`Found ${extras.length} additional agent-tempo daemon process${extras.length === 1 ? '' : 'es'} not tracked by the pid file:`);
|
|
200
|
+
for (const p of extras)
|
|
201
|
+
out.log(` pid ${p.pid}: ${p.commandLine}`);
|
|
202
|
+
out.log(` ${out.dim('See `agent-tempo daemon --help` or docs/troubleshooting.md for emergency cleanup.')}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
out.log('Daemon is not running');
|
|
207
|
+
if (scanned.length > 0) {
|
|
208
|
+
out.warn(`Found ${scanned.length} orphaned agent-tempo daemon process${scanned.length === 1 ? '' : 'es'} (no pid file):`);
|
|
209
|
+
for (const p of scanned)
|
|
210
|
+
out.log(` pid ${p.pid}: ${p.commandLine}`);
|
|
211
|
+
out.log(` ${out.dim('These are untracked. See docs/troubleshooting.md → "Orphaned daemon processes" for emergency cleanup.')}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
case 'stats': {
|
|
217
|
+
await daemonStats();
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
case 'logs': {
|
|
221
|
+
if (!(0, fs_1.existsSync)(daemon_1.DAEMON_LOG_PATH)) {
|
|
222
|
+
out.warn('No daemon log file found');
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// Tail the log file
|
|
226
|
+
if (process.platform === 'win32') {
|
|
227
|
+
// On Windows, read the last 32KB of the log (size-capped to avoid OOM on large logs)
|
|
228
|
+
const MAX_TAIL_BYTES = 32 * 1024;
|
|
229
|
+
const stat = (0, fs_1.statSync)(daemon_1.DAEMON_LOG_PATH);
|
|
230
|
+
const fd = (0, fs_1.openSync)(daemon_1.DAEMON_LOG_PATH, 'r');
|
|
231
|
+
const readStart = Math.max(0, stat.size - MAX_TAIL_BYTES);
|
|
232
|
+
const buf = Buffer.alloc(Math.min(stat.size, MAX_TAIL_BYTES));
|
|
233
|
+
(0, fs_1.readSync)(fd, buf, 0, buf.length, readStart);
|
|
234
|
+
(0, fs_1.closeSync)(fd);
|
|
235
|
+
const chunk = buf.toString('utf8');
|
|
236
|
+
// Skip partial first line if we didn't read from the start
|
|
237
|
+
const lines = readStart > 0 ? chunk.split('\n').slice(1) : chunk.split('\n');
|
|
238
|
+
console.log(lines.slice(-50).join('\n'));
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// On Unix, use tail -f for live following
|
|
242
|
+
const child = (0, child_process_1.spawn)('tail', ['-f', '-n', '50', daemon_1.DAEMON_LOG_PATH], {
|
|
243
|
+
stdio: 'inherit',
|
|
244
|
+
});
|
|
245
|
+
child.on('error', () => {
|
|
246
|
+
// Fallback: just read the file
|
|
247
|
+
const content = (0, fs_1.readFileSync)(daemon_1.DAEMON_LOG_PATH, 'utf8');
|
|
248
|
+
const lines = content.split('\n');
|
|
249
|
+
console.log(lines.slice(-50).join('\n'));
|
|
250
|
+
});
|
|
251
|
+
// Keep running until user presses Ctrl+C
|
|
252
|
+
await new Promise((resolve) => {
|
|
253
|
+
child.on('exit', () => resolve());
|
|
254
|
+
process.on('SIGINT', () => { child.kill(); resolve(); });
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
case 'install':
|
|
260
|
+
await daemonInstall();
|
|
261
|
+
break;
|
|
262
|
+
case 'uninstall':
|
|
263
|
+
await daemonUninstall();
|
|
264
|
+
break;
|
|
265
|
+
default:
|
|
266
|
+
out.error('Usage: agent-tempo daemon <start|stop|status|stats|logs|install|uninstall>');
|
|
267
|
+
out.log(`\n ${out.dim('agent-tempo daemon start [--force]')} Start the worker daemon`);
|
|
268
|
+
out.log(` ${out.dim(' --force: skip orphan-process check + clear stale pid file')}`);
|
|
269
|
+
out.log(` ${out.dim('agent-tempo daemon stop')} Stop the worker daemon`);
|
|
270
|
+
out.log(` ${out.dim('agent-tempo daemon status')} Check daemon status + heartbeat + orphans`);
|
|
271
|
+
out.log(` ${out.dim('agent-tempo daemon stats')} Show memory + uptime + ensemble count`);
|
|
272
|
+
out.log(` ${out.dim('agent-tempo daemon logs')} Tail daemon log output`);
|
|
273
|
+
out.log(` ${out.dim('agent-tempo daemon install')} Install as a system service`);
|
|
274
|
+
out.log(` ${out.dim('agent-tempo daemon uninstall')} Uninstall the system service`);
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
// Used only to silence "config declared but never used" when a branch exits early.
|
|
278
|
+
void config;
|
|
279
|
+
}
|
|
280
|
+
async function daemonInstall() {
|
|
281
|
+
const platform = process.platform;
|
|
282
|
+
if (platform === 'linux') {
|
|
283
|
+
const src = packagingFile('systemd', 'agent-tempo.service');
|
|
284
|
+
const dstDir = (0, path_1.join)((0, os_1.homedir)(), '.config', 'systemd', 'user');
|
|
285
|
+
const dst = (0, path_1.join)(dstDir, 'agent-tempo.service');
|
|
286
|
+
(0, fs_1.mkdirSync)(dstDir, { recursive: true });
|
|
287
|
+
(0, fs_1.copyFileSync)(src, dst);
|
|
288
|
+
out.success(`Installed systemd --user unit: ${dst}`);
|
|
289
|
+
// Try to enable + start. User may still need `systemctl --user daemon-reload`.
|
|
290
|
+
try {
|
|
291
|
+
(0, child_process_1.execFileSync)('systemctl', ['--user', 'daemon-reload'], { stdio: 'ignore' });
|
|
292
|
+
(0, child_process_1.execFileSync)('systemctl', ['--user', 'enable', '--now', 'agent-tempo'], { stdio: 'ignore' });
|
|
293
|
+
out.log(' Enabled + started: systemctl --user enable --now agent-tempo');
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
out.warn(' systemctl invocation failed — run manually:');
|
|
297
|
+
out.log(` ${out.dim('systemctl --user daemon-reload')}`);
|
|
298
|
+
out.log(` ${out.dim('systemctl --user enable --now agent-tempo')}`);
|
|
299
|
+
}
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
if (platform === 'darwin') {
|
|
303
|
+
const src = packagingFile('launchd', 'com.agent.tempo.plist');
|
|
304
|
+
const dstDir = (0, path_1.join)((0, os_1.homedir)(), 'Library', 'LaunchAgents');
|
|
305
|
+
const dst = (0, path_1.join)(dstDir, 'com.agent.tempo.plist');
|
|
306
|
+
(0, fs_1.mkdirSync)(dstDir, { recursive: true });
|
|
307
|
+
(0, fs_1.copyFileSync)(src, dst);
|
|
308
|
+
out.success(`Installed launchd agent: ${dst}`);
|
|
309
|
+
out.warn(' NOTE: macOS launchd integration is best-effort — feedback welcome.');
|
|
310
|
+
try {
|
|
311
|
+
(0, child_process_1.execFileSync)('launchctl', ['load', dst], { stdio: 'ignore' });
|
|
312
|
+
out.log(' Loaded: launchctl load ' + dst);
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
out.warn(' launchctl invocation failed — run manually:');
|
|
316
|
+
out.log(` ${out.dim(`launchctl load ${dst}`)}`);
|
|
317
|
+
}
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (platform === 'win32') {
|
|
321
|
+
const script = packagingFile('windows', 'install-task.ps1');
|
|
322
|
+
try {
|
|
323
|
+
(0, child_process_1.execFileSync)('powershell', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', script], { stdio: 'inherit' });
|
|
324
|
+
}
|
|
325
|
+
catch (err) {
|
|
326
|
+
out.error(`Failed to register scheduled task: ${err?.message ?? err}`);
|
|
327
|
+
process.exit(1);
|
|
328
|
+
}
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
out.error(`Unsupported platform: ${platform}`);
|
|
332
|
+
out.log(' Supported: linux (systemd --user), darwin (launchd), win32 (Task Scheduler).');
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
async function daemonUninstall() {
|
|
336
|
+
const platform = process.platform;
|
|
337
|
+
if (platform === 'linux') {
|
|
338
|
+
// Backward-compat: clean up either the new (`agent-tempo.service`) or
|
|
339
|
+
// legacy (`agent-tempo.service`) unit so v0.x installs migrate cleanly.
|
|
340
|
+
const dirSystemd = (0, path_1.join)((0, os_1.homedir)(), '.config', 'systemd', 'user');
|
|
341
|
+
const dstNew = (0, path_1.join)(dirSystemd, 'agent-tempo.service');
|
|
342
|
+
const dstLegacy = (0, path_1.join)(dirSystemd, 'agent-tempo.service');
|
|
343
|
+
for (const svc of ['agent-tempo', 'agent-tempo']) {
|
|
344
|
+
try {
|
|
345
|
+
(0, child_process_1.execFileSync)('systemctl', ['--user', 'disable', '--now', svc], { stdio: 'ignore' });
|
|
346
|
+
}
|
|
347
|
+
catch { /* may not be running */ }
|
|
348
|
+
}
|
|
349
|
+
let removed = false;
|
|
350
|
+
try {
|
|
351
|
+
for (const dst of [dstNew, dstLegacy]) {
|
|
352
|
+
if ((0, fs_1.existsSync)(dst)) {
|
|
353
|
+
(0, fs_1.unlinkSync)(dst);
|
|
354
|
+
out.success(`Removed ${dst}`);
|
|
355
|
+
removed = true;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (!removed)
|
|
359
|
+
out.log('No systemd unit file found.');
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
out.error(`Failed to remove systemd unit: ${err?.message ?? err}`);
|
|
363
|
+
process.exit(1);
|
|
364
|
+
}
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
if (platform === 'darwin') {
|
|
368
|
+
// Backward-compat: clean up either the new (`com.agent.tempo.plist`) or
|
|
369
|
+
// legacy (`com.claude.tempo.plist`) plist so v0.x installs migrate cleanly.
|
|
370
|
+
const dstNew = (0, path_1.join)((0, os_1.homedir)(), 'Library', 'LaunchAgents', 'com.agent.tempo.plist');
|
|
371
|
+
const dstLegacy = (0, path_1.join)((0, os_1.homedir)(), 'Library', 'LaunchAgents', 'com.claude.tempo.plist');
|
|
372
|
+
let removed = false;
|
|
373
|
+
for (const dst of [dstNew, dstLegacy]) {
|
|
374
|
+
try {
|
|
375
|
+
(0, child_process_1.execFileSync)('launchctl', ['unload', dst], { stdio: 'ignore' });
|
|
376
|
+
}
|
|
377
|
+
catch { /* may not be loaded */ }
|
|
378
|
+
if ((0, fs_1.existsSync)(dst)) {
|
|
379
|
+
(0, fs_1.unlinkSync)(dst);
|
|
380
|
+
out.success(`Removed ${dst}`);
|
|
381
|
+
removed = true;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (!removed)
|
|
385
|
+
out.log('No launchd plist found.');
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (platform === 'win32') {
|
|
389
|
+
const script = packagingFile('windows', 'install-task.ps1');
|
|
390
|
+
try {
|
|
391
|
+
(0, child_process_1.execFileSync)('powershell', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', script, '-Uninstall'], { stdio: 'inherit' });
|
|
392
|
+
}
|
|
393
|
+
catch (err) {
|
|
394
|
+
out.error(`Failed to unregister scheduled task: ${err?.message ?? err}`);
|
|
395
|
+
process.exit(1);
|
|
396
|
+
}
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
out.error(`Unsupported platform: ${platform}`);
|
|
400
|
+
process.exit(1);
|
|
401
|
+
}
|
|
402
|
+
/** Pretty-print a byte count as MB (rounded). Pure helper, exported for tests. */
|
|
403
|
+
function formatBytesAsMb(n) {
|
|
404
|
+
if (typeof n !== 'number' || !Number.isFinite(n))
|
|
405
|
+
return 'n/a';
|
|
406
|
+
return `${Math.round(n / (1024 * 1024))} MB`;
|
|
407
|
+
}
|
|
408
|
+
/** Pretty-print a millisecond uptime as `Xh Ym Zs`. Pure helper, exported for tests. */
|
|
409
|
+
function formatUptime(ms) {
|
|
410
|
+
if (typeof ms !== 'number' || !Number.isFinite(ms) || ms < 0)
|
|
411
|
+
return 'n/a';
|
|
412
|
+
const totalSec = Math.floor(ms / 1000);
|
|
413
|
+
const hours = Math.floor(totalSec / 3600);
|
|
414
|
+
const minutes = Math.floor((totalSec % 3600) / 60);
|
|
415
|
+
const seconds = totalSec % 60;
|
|
416
|
+
if (hours > 0)
|
|
417
|
+
return `${hours}h ${minutes}m ${seconds}s`;
|
|
418
|
+
if (minutes > 0)
|
|
419
|
+
return `${minutes}m ${seconds}s`;
|
|
420
|
+
return `${seconds}s`;
|
|
421
|
+
}
|
|
422
|
+
/** GET `http://127.0.0.1:<port>/v1/health` and parse the JSON body. Used by `daemon stats`. */
|
|
423
|
+
function fetchHealth(port) {
|
|
424
|
+
return new Promise((resolve, reject) => {
|
|
425
|
+
const req = http.request({ hostname: '127.0.0.1', port, path: '/v1/health', method: 'GET', timeout: 3000 }, (res) => {
|
|
426
|
+
const chunks = [];
|
|
427
|
+
res.on('data', (c) => chunks.push(c));
|
|
428
|
+
res.on('end', () => {
|
|
429
|
+
if (res.statusCode !== 200) {
|
|
430
|
+
reject(new Error(`HTTP ${res.statusCode}`));
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
try {
|
|
434
|
+
resolve(JSON.parse(Buffer.concat(chunks).toString('utf8')));
|
|
435
|
+
}
|
|
436
|
+
catch (err) {
|
|
437
|
+
reject(err);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
req.on('error', reject);
|
|
442
|
+
req.on('timeout', () => {
|
|
443
|
+
req.destroy(new Error('request timed out after 3000ms'));
|
|
444
|
+
});
|
|
445
|
+
req.end();
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Render the `daemon stats` payload to stdout. Filed under #336 — gives
|
|
450
|
+
* operators a one-shot way to spot daemon memory growth without tailing
|
|
451
|
+
* logs or attaching a debugger.
|
|
452
|
+
*/
|
|
453
|
+
async function daemonStats() {
|
|
454
|
+
// First check the daemon is even running — surface a friendlier message
|
|
455
|
+
// than a raw ECONNREFUSED if not.
|
|
456
|
+
const status = (0, daemon_1.getDaemonStatus)();
|
|
457
|
+
if (!status.running) {
|
|
458
|
+
out.warn('Daemon is not running — start it with `agent-tempo daemon start`');
|
|
459
|
+
process.exit(1);
|
|
460
|
+
}
|
|
461
|
+
const port = (0, port_file_1.readPortFile)();
|
|
462
|
+
if (port === null) {
|
|
463
|
+
out.error('Daemon port file not found at ~/.agent-tempo/daemon.port');
|
|
464
|
+
out.log(` ${out.dim('The daemon may be from a pre-HTTP build. Restart it with `agent-tempo daemon stop && start`.')}`);
|
|
465
|
+
process.exit(1);
|
|
466
|
+
}
|
|
467
|
+
let body;
|
|
468
|
+
try {
|
|
469
|
+
body = await fetchHealth(port);
|
|
470
|
+
}
|
|
471
|
+
catch (err) {
|
|
472
|
+
out.error(`Failed to query daemon at http://127.0.0.1:${port}/v1/health: ${err instanceof Error ? err.message : err}`);
|
|
473
|
+
process.exit(1);
|
|
474
|
+
}
|
|
475
|
+
out.success(`Daemon stats (pid ${status.pid})`);
|
|
476
|
+
out.log(` ${out.dim('Version: ')}${typeof body.version === 'string' ? body.version : 'n/a'}`);
|
|
477
|
+
out.log(` ${out.dim('Namespace: ')}${typeof body.namespace === 'string' ? body.namespace : 'n/a'}`);
|
|
478
|
+
out.log(` ${out.dim('Uptime: ')}${formatUptime(body.uptimeMs)}`);
|
|
479
|
+
out.log(` ${out.dim('Ensembles: ')}${typeof body.ensembleCount === 'number' ? body.ensembleCount : 'n/a'}`);
|
|
480
|
+
out.log(` ${out.dim('SSE subscribers:')}${typeof body.subscriberCount === 'number' ? ` ${body.subscriberCount}` : ' n/a'}`);
|
|
481
|
+
out.log('');
|
|
482
|
+
if (body.memory) {
|
|
483
|
+
out.log(` ${out.dim('Memory (#336 diagnostic):')}`);
|
|
484
|
+
out.log(` ${out.dim('RSS: ')}${formatBytesAsMb(body.memory.rss)}`);
|
|
485
|
+
out.log(` ${out.dim('Heap used: ')}${formatBytesAsMb(body.memory.heapUsed)}`);
|
|
486
|
+
out.log(` ${out.dim('Heap total: ')}${formatBytesAsMb(body.memory.heapTotal)}`);
|
|
487
|
+
out.log(` ${out.dim('External: ')}${formatBytesAsMb(body.memory.external)}`);
|
|
488
|
+
out.log(` ${out.dim('Array buffers: ')}${formatBytesAsMb(body.memory.arrayBuffers)}`);
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
out.warn('Memory diagnostics not present in /v1/health response — daemon may be from a pre-#336 build.');
|
|
492
|
+
}
|
|
493
|
+
}
|