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,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerScheduleTool = registerScheduleTool;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const croner_1 = require("croner");
|
|
6
|
+
const client_1 = require("@temporalio/client");
|
|
7
|
+
const config_1 = require("../config");
|
|
8
|
+
const duration_1 = require("../utils/duration");
|
|
9
|
+
const resolve_1 = require("./resolve");
|
|
10
|
+
const helpers_1 = require("./helpers");
|
|
11
|
+
const validation_1 = require("../utils/validation");
|
|
12
|
+
const log = (...args) => console.error('[agent-tempo:schedule]', ...args);
|
|
13
|
+
function registerScheduleTool(server, client, config, getPlayerId) {
|
|
14
|
+
(0, helpers_1.defineTool)(server, 'schedule', 'Schedule a message to be sent to a player at a specific time, after a delay, on a recurring interval, or via cron expression.', {
|
|
15
|
+
name: zod_1.z.string().max(validation_1.SCHEDULE_NAME_MAX).describe('Unique name for this schedule'),
|
|
16
|
+
message: zod_1.z.string().max(validation_1.SCHEDULE_MESSAGE_MAX).describe('The message to deliver'),
|
|
17
|
+
target: zod_1.z.string().max(validation_1.PLAYER_NAME_MAX).describe('Player name to deliver to ("self" = this session)'),
|
|
18
|
+
at: zod_1.z.string().optional().describe('ISO datetime for one-shot delivery (e.g. "2026-04-03T20:00:00Z")'),
|
|
19
|
+
delay: zod_1.z.string().optional().describe('Duration until first delivery (e.g. "10m", "2h", "1d")'),
|
|
20
|
+
every: zod_1.z.string().optional().describe('Recurring interval (e.g. "5m", "1h")'),
|
|
21
|
+
cron: zod_1.z.string().max(validation_1.CRON_EXPRESSION_MAX).optional().describe('Cron expression for recurring delivery (e.g. "0 9 * * 1-5" = weekdays at 9am). Mutually exclusive with at/delay/every.'),
|
|
22
|
+
timezone: zod_1.z.string().optional().describe('IANA timezone for cron evaluation (e.g. "America/New_York"). Defaults to UTC. Only used with cron.'),
|
|
23
|
+
until: zod_1.z.string().optional().describe('ISO datetime — stop recurring after this time'),
|
|
24
|
+
count: zod_1.z.number().optional().describe('Max number of deliveries for recurring schedules'),
|
|
25
|
+
}, async (args) => {
|
|
26
|
+
const { name, message, at, delay, every, cron, timezone, until, count } = args;
|
|
27
|
+
let target = args.target;
|
|
28
|
+
// Resolve "self" to the current player name
|
|
29
|
+
if (target === 'self') {
|
|
30
|
+
target = getPlayerId();
|
|
31
|
+
}
|
|
32
|
+
// Validate target player exists (warn, don't block)
|
|
33
|
+
let targetWarning;
|
|
34
|
+
if (target !== 'all' && target !== 'conductor') {
|
|
35
|
+
try {
|
|
36
|
+
const targetHandle = await (0, resolve_1.resolveSession)(client, config.ensemble, target);
|
|
37
|
+
if (!targetHandle) {
|
|
38
|
+
targetWarning = `Warning: player "${target}" is not currently active. The schedule will be created but may fail to deliver until the player joins.`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Resolution failed — don't block schedule creation
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Validate exactly one timing option
|
|
46
|
+
const timingCount = [at, delay, every, cron].filter(Boolean).length;
|
|
47
|
+
if (timingCount !== 1) {
|
|
48
|
+
return (0, helpers_1.fail)('Provide exactly one timing option: `at`, `delay`, `every`, or `cron`.');
|
|
49
|
+
}
|
|
50
|
+
// timezone only valid with cron
|
|
51
|
+
if (timezone && !cron) {
|
|
52
|
+
return (0, helpers_1.fail)('`timezone` can only be used with `cron`.');
|
|
53
|
+
}
|
|
54
|
+
const now = Date.now();
|
|
55
|
+
let nextFireAt;
|
|
56
|
+
let interval;
|
|
57
|
+
if (at) {
|
|
58
|
+
const ts = Date.parse(at);
|
|
59
|
+
if (isNaN(ts)) {
|
|
60
|
+
return (0, helpers_1.fail)(`Invalid ISO datetime for "at": ${at}`);
|
|
61
|
+
}
|
|
62
|
+
nextFireAt = ts;
|
|
63
|
+
}
|
|
64
|
+
else if (delay) {
|
|
65
|
+
const ms = (0, duration_1.parseDuration)(delay);
|
|
66
|
+
if (ms === null) {
|
|
67
|
+
return (0, helpers_1.fail)(`Invalid duration for "delay": ${delay}. Use e.g. "30s", "10m", "2h", "1d".`);
|
|
68
|
+
}
|
|
69
|
+
nextFireAt = now + ms;
|
|
70
|
+
}
|
|
71
|
+
else if (every) {
|
|
72
|
+
// every (recurring interval)
|
|
73
|
+
const ms = (0, duration_1.parseDuration)(every);
|
|
74
|
+
if (ms === null || ms < 10_000) {
|
|
75
|
+
return (0, helpers_1.fail)(`Invalid or too-short interval for "every": ${every}. Minimum is 10s.`);
|
|
76
|
+
}
|
|
77
|
+
nextFireAt = now + ms;
|
|
78
|
+
interval = ms;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// cron (recurring via cron expression)
|
|
82
|
+
try {
|
|
83
|
+
const job = new croner_1.Cron(cron, { timezone: timezone || 'UTC' });
|
|
84
|
+
const next = job.nextRun();
|
|
85
|
+
if (!next) {
|
|
86
|
+
return (0, helpers_1.fail)(`Cron expression "${cron}" has no upcoming fire time.`);
|
|
87
|
+
}
|
|
88
|
+
nextFireAt = next.getTime();
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
return (0, helpers_1.fail)(`Invalid cron expression "${cron}": ${(0, helpers_1.formatError)(err)}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Parse optional until
|
|
95
|
+
let untilMs;
|
|
96
|
+
if (until) {
|
|
97
|
+
const ts = Date.parse(until);
|
|
98
|
+
if (isNaN(ts)) {
|
|
99
|
+
return (0, helpers_1.fail)(`Invalid ISO datetime for "until": ${until}`);
|
|
100
|
+
}
|
|
101
|
+
untilMs = ts;
|
|
102
|
+
}
|
|
103
|
+
const type = cron ? 'cron' : every ? 'interval' : 'once';
|
|
104
|
+
const scheduleEntry = {
|
|
105
|
+
name,
|
|
106
|
+
message,
|
|
107
|
+
target,
|
|
108
|
+
type,
|
|
109
|
+
nextFireAt: new Date(nextFireAt).toISOString(),
|
|
110
|
+
interval,
|
|
111
|
+
cronExpression: cron,
|
|
112
|
+
timezone: cron ? (timezone || 'UTC') : undefined,
|
|
113
|
+
until: untilMs ? new Date(untilMs).toISOString() : undefined,
|
|
114
|
+
remainingCount: count,
|
|
115
|
+
firedCount: 0,
|
|
116
|
+
createdBy: getPlayerId(),
|
|
117
|
+
};
|
|
118
|
+
try {
|
|
119
|
+
const wfId = (0, config_1.schedulerWorkflowId)(config.ensemble);
|
|
120
|
+
// Try to signal the existing scheduler workflow
|
|
121
|
+
try {
|
|
122
|
+
const handle = client.workflow.getHandle(wfId);
|
|
123
|
+
await handle.describe(); // throws if not running
|
|
124
|
+
await handle.signal('addSchedule', scheduleEntry);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Scheduler not running — start it with this schedule as seed
|
|
128
|
+
await client.workflow.start('agentSchedulerWorkflow', {
|
|
129
|
+
workflowId: wfId,
|
|
130
|
+
taskQueue: config.taskQueue,
|
|
131
|
+
args: [{ ensemble: config.ensemble, entries: [scheduleEntry] }],
|
|
132
|
+
workflowIdConflictPolicy: client_1.WorkflowIdConflictPolicy.USE_EXISTING,
|
|
133
|
+
searchAttributes: {
|
|
134
|
+
AgentTempoEnsemble: [config.ensemble],
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
log(`Started scheduler workflow ${wfId}`);
|
|
138
|
+
}
|
|
139
|
+
const fireDate = new Date(nextFireAt).toISOString();
|
|
140
|
+
const recur = cron
|
|
141
|
+
? ` (cron: ${cron}, tz: ${timezone || 'UTC'})`
|
|
142
|
+
: interval
|
|
143
|
+
? ` (repeating every ${every})`
|
|
144
|
+
: ' (one-shot)';
|
|
145
|
+
const msg = `Schedule **${name}** created. Next fire: ${fireDate}${recur}. Target: ${target}.`;
|
|
146
|
+
return (0, helpers_1.ok)(targetWarning ? `${msg}\n\n⚠ ${targetWarning}` : msg);
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
return (0, helpers_1.fail)(`Failed to create schedule: ${(0, helpers_1.formatError)(err)}`);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSchedulesTool = registerSchedulesTool;
|
|
4
|
+
const client_1 = require("@temporalio/client");
|
|
5
|
+
const config_1 = require("../config");
|
|
6
|
+
const helpers_1 = require("./helpers");
|
|
7
|
+
function formatDuration(ms) {
|
|
8
|
+
if (ms >= 86_400_000)
|
|
9
|
+
return `${ms / 86_400_000}d`;
|
|
10
|
+
if (ms >= 3_600_000)
|
|
11
|
+
return `${ms / 3_600_000}h`;
|
|
12
|
+
if (ms >= 60_000)
|
|
13
|
+
return `${ms / 60_000}m`;
|
|
14
|
+
return `${ms / 1000}s`;
|
|
15
|
+
}
|
|
16
|
+
function registerSchedulesTool(server, client, config) {
|
|
17
|
+
(0, helpers_1.defineTool)(server, 'schedules', 'List all active schedules in this ensemble.', {}, async () => {
|
|
18
|
+
try {
|
|
19
|
+
const wfId = (0, config_1.schedulerWorkflowId)(config.ensemble);
|
|
20
|
+
const handle = client.workflow.getHandle(wfId);
|
|
21
|
+
let schedules;
|
|
22
|
+
try {
|
|
23
|
+
schedules = await handle.query('getSchedules');
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
if (err instanceof client_1.WorkflowNotFoundError) {
|
|
27
|
+
return (0, helpers_1.ok)('No scheduler running — no schedules exist yet.');
|
|
28
|
+
}
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
if (schedules.length === 0) {
|
|
32
|
+
return (0, helpers_1.ok)('No active schedules.');
|
|
33
|
+
}
|
|
34
|
+
const lines = schedules.map((s) => {
|
|
35
|
+
const next = s.nextFireAt; // already ISO string
|
|
36
|
+
const recur = s.cronExpression
|
|
37
|
+
? `cron: ${s.cronExpression} (${s.timezone || 'UTC'})`
|
|
38
|
+
: s.interval ? `every ${formatDuration(s.interval)}` : 'one-shot';
|
|
39
|
+
const bounds = [];
|
|
40
|
+
if (s.until)
|
|
41
|
+
bounds.push(`until ${s.until}`);
|
|
42
|
+
if (s.remainingCount != null)
|
|
43
|
+
bounds.push(`${s.firedCount}/${s.firedCount + s.remainingCount} fired`);
|
|
44
|
+
const boundsStr = bounds.length ? ` (${bounds.join(', ')})` : '';
|
|
45
|
+
const msgPreview = s.message.length > 60 ? s.message.slice(0, 57) + '...' : s.message;
|
|
46
|
+
return `• **${s.name}** → ${s.target} | ${recur}${boundsStr} | next: ${next}\n msg: ${msgPreview}`;
|
|
47
|
+
});
|
|
48
|
+
return (0, helpers_1.ok)(lines.join('\n'));
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
return (0, helpers_1.fail)(`Failed to query schedules: ${(0, helpers_1.formatError)(err)}`);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSetEnsembleDescriptionTool = registerSetEnsembleDescriptionTool;
|
|
4
|
+
/**
|
|
5
|
+
* `set_ensemble_description` MCP tool — #399 W1 (Q5.1).
|
|
6
|
+
*
|
|
7
|
+
* Updates the per-ensemble maestro's mission-flavor description string,
|
|
8
|
+
* surfaced on the dashboard EnsembleCard. Conductors are encouraged to
|
|
9
|
+
* keep updates milestone-flavored (~80 chars) — see
|
|
10
|
+
* `examples/agents/tempo-conductor.md`.
|
|
11
|
+
*/
|
|
12
|
+
const zod_1 = require("zod");
|
|
13
|
+
const config_1 = require("../config");
|
|
14
|
+
const maestro_signals_1 = require("../workflows/maestro-signals");
|
|
15
|
+
const helpers_1 = require("./helpers");
|
|
16
|
+
const validation_1 = require("../utils/validation");
|
|
17
|
+
function registerSetEnsembleDescriptionTool(server, client, config) {
|
|
18
|
+
(0, helpers_1.defineTool)(server, 'set_ensemble_description', "Update the ensemble's mission-flavor description (≤100 chars). Surfaces on the dashboard EnsembleCard. Empty string clears it. Refresh at milestone boundaries — don't update for trivial changes.", {
|
|
19
|
+
description: zod_1.z
|
|
20
|
+
.string()
|
|
21
|
+
.max(validation_1.ENSEMBLE_DESCRIPTION_MAX)
|
|
22
|
+
.describe('Short summary of what the ensemble is currently working on (≤100 chars).'),
|
|
23
|
+
}, async (args) => {
|
|
24
|
+
const { description } = args;
|
|
25
|
+
try {
|
|
26
|
+
const handle = client.workflow.getHandle((0, config_1.maestroWorkflowId)(config.ensemble));
|
|
27
|
+
await handle.signal(maestro_signals_1.setEnsembleDescriptionSignal.name, description);
|
|
28
|
+
if (description.trim().length === 0) {
|
|
29
|
+
return (0, helpers_1.ok)(`Ensemble **${config.ensemble}** description cleared.`);
|
|
30
|
+
}
|
|
31
|
+
return (0, helpers_1.ok)(`Ensemble **${config.ensemble}** description updated: "${description}"`);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
return (0, helpers_1.fail)(`Failed to set ensemble description: ${(0, helpers_1.formatError)(err)}`);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { WorkflowHandle, Client } from '@temporalio/client';
|
|
3
|
+
import { Config } from '../config';
|
|
4
|
+
export declare function registerSetNameTool(server: McpServer, client: Client, config: Config, handle: WorkflowHandle, getPlayerId: () => string, setPlayerId: (id: string) => void): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSetNameTool = registerSetNameTool;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const config_1 = require("../config");
|
|
6
|
+
const scheduler_signals_1 = require("../workflows/scheduler-signals");
|
|
7
|
+
const resolve_1 = require("./resolve");
|
|
8
|
+
const helpers_1 = require("./helpers");
|
|
9
|
+
const validation_1 = require("../utils/validation");
|
|
10
|
+
const log = (...args) => console.error('[agent-tempo:set-name]', ...args);
|
|
11
|
+
function registerSetNameTool(server, client, config, handle, getPlayerId, setPlayerId) {
|
|
12
|
+
(0, helpers_1.defineTool)(server, 'set_name', 'Set a human-readable name for this session. Visible to other players in the ensemble.', {
|
|
13
|
+
name: zod_1.z.string().max(validation_1.PLAYER_NAME_MAX).describe('The name for this session (e.g., "UX", "API", "test-runner")'),
|
|
14
|
+
}, async (args) => {
|
|
15
|
+
const { name } = args;
|
|
16
|
+
// Validate name to prevent search attribute query injection
|
|
17
|
+
const nameError = (0, validation_1.validatePlayerName)(name);
|
|
18
|
+
if (nameError) {
|
|
19
|
+
return (0, helpers_1.fail)(nameError);
|
|
20
|
+
}
|
|
21
|
+
// Check if the name is already taken
|
|
22
|
+
const existing = await (0, resolve_1.resolveSession)(client, config.ensemble, name);
|
|
23
|
+
if (existing && existing.workflowId !== handle.workflowId) {
|
|
24
|
+
return (0, helpers_1.fail)(`Name **${name}** is already taken by another session. Choose a different name.`);
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const oldName = getPlayerId();
|
|
28
|
+
await handle.signal('setName', name);
|
|
29
|
+
setPlayerId(name);
|
|
30
|
+
// Notify the scheduler to rewrite schedule targets from old name to new name
|
|
31
|
+
try {
|
|
32
|
+
const schedulerHandle = client.workflow.getHandle((0, config_1.schedulerWorkflowId)(config.ensemble));
|
|
33
|
+
await schedulerHandle.signal(scheduler_signals_1.updateScheduleTargetSignal, oldName, name);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Scheduler may not be running — that's fine, no schedules to update
|
|
37
|
+
log(`No scheduler to notify about rename ${oldName} → ${name}`);
|
|
38
|
+
}
|
|
39
|
+
return (0, helpers_1.ok)(`Session name set to **${name}**. Run \`/rename ${name}\` to match your Claude Code session name.`);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
return (0, helpers_1.fail)(`Failed to set name: ${(0, helpers_1.formatError)(err)}`);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSetPartTool = registerSetPartTool;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const helpers_1 = require("./helpers");
|
|
6
|
+
const validation_1 = require("../utils/validation");
|
|
7
|
+
function registerSetPartTool(server, handle) {
|
|
8
|
+
(0, helpers_1.defineTool)(server, 'set_part', 'Update your description of what you are currently working on. Visible to other sessions via ensemble.', {
|
|
9
|
+
part: zod_1.z.string().max(validation_1.PART_MAX).describe('A short description of your current work'),
|
|
10
|
+
}, async (args) => {
|
|
11
|
+
const { part } = args;
|
|
12
|
+
try {
|
|
13
|
+
await handle.signal('setPart', part);
|
|
14
|
+
return (0, helpers_1.ok)(`Part updated: "${part}"`);
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
return (0, helpers_1.fail)(`Failed to update part: ${(0, helpers_1.formatError)(err)}`);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { Client } from '@temporalio/client';
|
|
3
|
+
import { Config } from '../config';
|
|
4
|
+
export declare function registerShutdownTool(server: McpServer, client: Client, config: Config, getPlayerId: () => string): void;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerShutdownTool = registerShutdownTool;
|
|
4
|
+
/**
|
|
5
|
+
* `shutdown` — graceful ensemble-wide teardown (#287).
|
|
6
|
+
*
|
|
7
|
+
* Fan-out peer to `pause` / `play`: walks every session in the ensemble and
|
|
8
|
+
* requests a graceful detach, then pauses the scheduler + maestro so no new
|
|
9
|
+
* work fires while the adapters drain. Workflows survive — pair with
|
|
10
|
+
* `restore` to reattach, or `destroy` (ensemble-scope) for terminal teardown.
|
|
11
|
+
*
|
|
12
|
+
* The per-session fan-out uses `signalAllSessions` so every detach runs in
|
|
13
|
+
* parallel; a slow / dead session can't block peers from draining.
|
|
14
|
+
*/
|
|
15
|
+
const zod_1 = require("zod");
|
|
16
|
+
const signals_1 = require("../workflows/signals");
|
|
17
|
+
const helpers_1 = require("./helpers");
|
|
18
|
+
const validation_1 = require("../utils/validation");
|
|
19
|
+
const ensemble_ops_1 = require("../utils/ensemble-ops");
|
|
20
|
+
const log = (...args) => console.error('[agent-tempo:shutdown]', ...args);
|
|
21
|
+
function registerShutdownTool(server, client, config, getPlayerId) {
|
|
22
|
+
(0, helpers_1.defineTool)(server, 'shutdown', 'Gracefully shut down the ensemble: request detach on every session, pause the scheduler, and pause the maestro. Workflows survive in `detached` phase. Pair with `restore` to come back up, or `destroy` (no player arg) to terminate. Does not touch your own session.', {
|
|
23
|
+
deadlineMs: zod_1.z.number().min(0).max(validation_1.MAX_DETACH_DEADLINE_MS).optional().describe(`Max drain time per session before force-detach (default ${validation_1.DEFAULT_RESTART_DETACH_DEADLINE_MS}, max ${validation_1.MAX_DETACH_DEADLINE_MS}).`),
|
|
24
|
+
}, async (args) => {
|
|
25
|
+
const { deadlineMs = validation_1.DEFAULT_RESTART_DETACH_DEADLINE_MS } = args;
|
|
26
|
+
const callerId = getPlayerId();
|
|
27
|
+
try {
|
|
28
|
+
// Pause maestro + scheduler in parallel with the session fan-out —
|
|
29
|
+
// they're independent and draining adapters won't mind if the
|
|
30
|
+
// scheduler keeps firing for a few ms longer.
|
|
31
|
+
const [toggle, fanout] = await Promise.all([
|
|
32
|
+
(0, ensemble_ops_1.pauseMaestroAndScheduler)(client, config.ensemble),
|
|
33
|
+
(0, ensemble_ops_1.signalAllSessions)(client, config.ensemble, signals_1.requestDetachSignal.name, { reason: 'user-stop', deadlineMs }, { skip: (playerId) => playerId === callerId }),
|
|
34
|
+
]);
|
|
35
|
+
const summaryLine = `${fanout.sent} detaching, ${fanout.skipped} skipped, ${fanout.failed} failed`;
|
|
36
|
+
const bits = [`Ensemble **${config.ensemble}** shutting down.`, summaryLine];
|
|
37
|
+
if (toggle.maestro)
|
|
38
|
+
bits.push('maestro paused');
|
|
39
|
+
if (toggle.scheduler)
|
|
40
|
+
bits.push('scheduler paused');
|
|
41
|
+
if (fanout.failed > 0) {
|
|
42
|
+
const errs = fanout.perSession
|
|
43
|
+
.filter((p) => p.outcome === 'failed')
|
|
44
|
+
.map((p) => ` - ${p.playerId}: ${'error' in p ? p.error : ''}`);
|
|
45
|
+
bits.push(`Errors:\n${errs.join('\n')}`);
|
|
46
|
+
}
|
|
47
|
+
log(`Shutdown requested by ${callerId} in "${config.ensemble}": ${summaryLine}`);
|
|
48
|
+
return (0, helpers_1.ok)(bits.join('\n'));
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
return (0, helpers_1.fail)(`Failed to shut down ensemble: ${(0, helpers_1.formatError)(err)}`);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerStageTool = registerStageTool;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const helpers_1 = require("./helpers");
|
|
6
|
+
const validation_1 = require("../utils/validation");
|
|
7
|
+
function registerStageTool(server, handle, getPlayerId) {
|
|
8
|
+
(0, helpers_1.defineTool)(server, 'stage', 'Create a pipeline stage tracking N players. When all players report, a completion message is auto-injected. Conductor only.', {
|
|
9
|
+
name: zod_1.z.string().max(validation_1.STAGE_NAME_MAX).describe('Unique stage name (e.g. "code-review", "testing")'),
|
|
10
|
+
players: zod_1.z.array(zod_1.z.string().regex(validation_1.PLAYER_NAME_REGEX)).min(1).max(validation_1.STAGE_PLAYERS_MAX).describe('Player names to track in this stage'),
|
|
11
|
+
failurePolicy: zod_1.z.enum(['halt', 'continue']).optional().describe('What to do when a player reports a blocker. "halt" (default) fails the stage immediately; "continue" waits for all players.'),
|
|
12
|
+
}, async (args) => {
|
|
13
|
+
const { name, players, failurePolicy } = args;
|
|
14
|
+
try {
|
|
15
|
+
await handle.signal('setStage', {
|
|
16
|
+
name,
|
|
17
|
+
players,
|
|
18
|
+
failurePolicy,
|
|
19
|
+
createdBy: getPlayerId(),
|
|
20
|
+
});
|
|
21
|
+
const playerList = players.map((p) => ` - ${p}`).join('\n');
|
|
22
|
+
return (0, helpers_1.ok)(`Stage **${name}** created tracking ${players.length} player(s) [policy: ${failurePolicy || 'halt'}]:\n${playerList}`);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
return (0, helpers_1.fail)(`Failed to create stage: ${(0, helpers_1.formatError)(err)}`);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerStagesTool = registerStagesTool;
|
|
4
|
+
const helpers_1 = require("./helpers");
|
|
5
|
+
function registerStagesTool(server, handle) {
|
|
6
|
+
(0, helpers_1.defineTool)(server, 'stages', 'List all pipeline stages and their status. Shows which players have reported, who is still waiting, and stage completion status. Conductor only.', {}, async () => {
|
|
7
|
+
try {
|
|
8
|
+
const stages = await handle.query('stages');
|
|
9
|
+
if (stages.length === 0) {
|
|
10
|
+
return (0, helpers_1.ok)('No stages defined.');
|
|
11
|
+
}
|
|
12
|
+
const lines = stages.map((s) => {
|
|
13
|
+
const statusIcon = s.status === 'complete' ? '\u2714'
|
|
14
|
+
: s.status === 'failed' ? '\u2718'
|
|
15
|
+
: s.status === 'cancelled' ? '\u2212'
|
|
16
|
+
: '\u25CB';
|
|
17
|
+
const playerLines = s.players.map((p) => {
|
|
18
|
+
const pIcon = p.status === 'reported' ? '\u2714'
|
|
19
|
+
: p.status === 'blocked' ? '\u2718'
|
|
20
|
+
: '\u25CB';
|
|
21
|
+
const detail = p.reportedAt ? ` (${p.reportType})` : '';
|
|
22
|
+
return ` ${pIcon} ${p.playerId}${detail}`;
|
|
23
|
+
});
|
|
24
|
+
return [
|
|
25
|
+
`${statusIcon} **${s.name}** [${s.status}] (policy: ${s.failurePolicy})`,
|
|
26
|
+
...playerLines,
|
|
27
|
+
].join('\n');
|
|
28
|
+
});
|
|
29
|
+
return (0, helpers_1.ok)(lines.join('\n\n'));
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
return (0, helpers_1.fail)(`Failed to query stages: ${(0, helpers_1.formatError)(err)}`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { Client, WorkflowHandle } from '@temporalio/client';
|
|
3
|
+
import type { Config } from '../config';
|
|
4
|
+
export declare function registerStopTool(_server: McpServer, _client: Client, _config: Config, _getPlayerId: () => string, _handle: WorkflowHandle): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerStopTool = registerStopTool;
|
|
4
|
+
/**
|
|
5
|
+
* `stop` — deprecation shim (PR-D).
|
|
6
|
+
*
|
|
7
|
+
* The `stop` verb is retired in v0.25 per design §8.1 "three verbs". Its two
|
|
8
|
+
* distinct semantics are now separate tools:
|
|
9
|
+
* - graceful reap of the adapter, workflow survives → `detach`
|
|
10
|
+
* - terminal teardown of the workflow → `destroy`
|
|
11
|
+
*
|
|
12
|
+
* The MCP tool remains registered (so existing clients discover it via
|
|
13
|
+
* ListTools) but returns an `isError` result pointing to the replacement.
|
|
14
|
+
* The CLI-level `claude-tempo stop` command is unchanged — it's still useful
|
|
15
|
+
* for bulk cleanup (ensemble-wide or `--all`).
|
|
16
|
+
*/
|
|
17
|
+
const zod_1 = require("zod");
|
|
18
|
+
const helpers_1 = require("./helpers");
|
|
19
|
+
function registerStopTool(_server, _client, _config, _getPlayerId, _handle) {
|
|
20
|
+
(0, helpers_1.defineTool)(_server, 'stop', '[deprecated in v0.25] The `stop` verb was split into `detach` (graceful adapter reap, workflow survives) and `destroy` (terminal teardown). This tool now returns an error pointing you to the right one.', {
|
|
21
|
+
playerId: zod_1.z.string().describe('The player name to stop'),
|
|
22
|
+
force: zod_1.z.boolean().optional().describe('Legacy force flag — no longer honored'),
|
|
23
|
+
}, async () => {
|
|
24
|
+
return (0, helpers_1.fail)('The `stop` tool is deprecated. Use:\n' +
|
|
25
|
+
' • `detach` — gracefully reap the adapter; workflow survives (use this for most cases)\n' +
|
|
26
|
+
' • `destroy` — terminally end the workflow; abandons in-flight outbox\n' +
|
|
27
|
+
' • `restart` — reap + claim a fresh adapter with context replay');
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerUnscheduleTool = registerUnscheduleTool;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const common_1 = require("@temporalio/common");
|
|
6
|
+
const config_1 = require("../config");
|
|
7
|
+
const helpers_1 = require("./helpers");
|
|
8
|
+
function registerUnscheduleTool(server, client, config) {
|
|
9
|
+
(0, helpers_1.defineTool)(server, 'unschedule', 'Remove a named schedule. The schedule stops firing immediately.', {
|
|
10
|
+
name: zod_1.z.string().describe('Name of the schedule to remove'),
|
|
11
|
+
}, async (args) => {
|
|
12
|
+
const { name } = args;
|
|
13
|
+
try {
|
|
14
|
+
const wfId = (0, config_1.schedulerWorkflowId)(config.ensemble);
|
|
15
|
+
const handle = client.workflow.getHandle(wfId);
|
|
16
|
+
// Check if the scheduler workflow is running before signaling.
|
|
17
|
+
// Only treat WorkflowNotFoundError as "no scheduler" — other errors (network, etc.)
|
|
18
|
+
// should propagate so callers get an accurate error message.
|
|
19
|
+
try {
|
|
20
|
+
await handle.describe();
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
if (err instanceof common_1.WorkflowNotFoundError) {
|
|
24
|
+
return (0, helpers_1.ok)('No scheduler is running — there are no schedules to remove.');
|
|
25
|
+
}
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
await handle.signal('removeSchedule', name);
|
|
29
|
+
return (0, helpers_1.ok)(`Schedule **${name}** removed.`);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
return (0, helpers_1.fail)(`Failed to remove schedule: ${(0, helpers_1.formatError)(err)}`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerWhoAmITool = registerWhoAmITool;
|
|
4
|
+
const helpers_1 = require("./helpers");
|
|
5
|
+
function registerWhoAmITool(server, handle, getPlayerId) {
|
|
6
|
+
(0, helpers_1.defineTool)(server, 'who_am_i', 'Get your identity, role, and session details', {}, async () => {
|
|
7
|
+
const metadata = await handle.query('getMetadata');
|
|
8
|
+
const part = await handle.query('getPart');
|
|
9
|
+
// Attachment phase is authoritative post-#175/#176 (replaced legacy status).
|
|
10
|
+
let phase;
|
|
11
|
+
try {
|
|
12
|
+
const info = await handle.query('attachmentInfo');
|
|
13
|
+
phase = info.phase;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// Older workflows pre-dating the attachment lifecycle may not support this query.
|
|
17
|
+
phase = undefined;
|
|
18
|
+
}
|
|
19
|
+
const lines = [
|
|
20
|
+
`**Name:** ${metadata.playerId}`,
|
|
21
|
+
metadata.playerType ? `**Type:** ${metadata.playerType}` : null,
|
|
22
|
+
metadata.playerTypeDescription ? `**Description:** ${metadata.playerTypeDescription}` : null,
|
|
23
|
+
`**Ensemble:** ${metadata.ensemble}`,
|
|
24
|
+
`**Role:** ${metadata.isConductor ? 'Conductor' : 'Player'}`,
|
|
25
|
+
metadata.recruitedBy ? `**Recruited by:** ${metadata.recruitedBy}` : null,
|
|
26
|
+
`**Part:** ${part}`,
|
|
27
|
+
`**Directory:** ${metadata.workDir}`,
|
|
28
|
+
`**Host:** ${metadata.hostname}`,
|
|
29
|
+
metadata.gitBranch ? `**Branch:** ${metadata.gitBranch}` : null,
|
|
30
|
+
`**Phase:** ${phase ?? 'unknown'}`,
|
|
31
|
+
].filter(Boolean);
|
|
32
|
+
return (0, helpers_1.ok)(lines.join('\n'));
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { Client, WorkflowHandle } from '@temporalio/client';
|
|
3
|
+
import { Config } from '../config';
|
|
4
|
+
export declare function registerWorktreeTool(server: McpServer, client: Client, config: Config, handle: WorkflowHandle, getPlayerId: () => string): void;
|