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,307 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildFormattedMessages = buildFormattedMessages;
|
|
7
|
+
exports.ConversationStream = ConversationStream;
|
|
8
|
+
/**
|
|
9
|
+
* ConversationStream — live message area showing ensemble conversation.
|
|
10
|
+
*
|
|
11
|
+
* Merges server conversation with local echo (optimistic sent messages),
|
|
12
|
+
* formats messages with header/body layout and word-wrap, and renders
|
|
13
|
+
* the most recent that fit in the viewport.
|
|
14
|
+
*
|
|
15
|
+
* Performance: Single <Text> root with nested virtual-text children.
|
|
16
|
+
* Zero Yoga <Box> nodes.
|
|
17
|
+
*/
|
|
18
|
+
const react_1 = __importDefault(require("react"));
|
|
19
|
+
const ink_context_1 = require("../ink-context");
|
|
20
|
+
const theme_1 = require("../utils/theme");
|
|
21
|
+
const format_1 = require("../utils/format");
|
|
22
|
+
function formatTime(timestamp) {
|
|
23
|
+
try {
|
|
24
|
+
const d = new Date(timestamp);
|
|
25
|
+
return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return '??:??';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const INDENT = ' '; // 3-space indent for message body (aligns with input area)
|
|
32
|
+
const MAX_DISPLAY_LINES_THIRD_PARTY = 4; // Cap visible body lines for third-party (conductor) traffic
|
|
33
|
+
/** Direct messages (maestro-in/out) show in full; third-party traffic is capped. */
|
|
34
|
+
function maxLines(msg) {
|
|
35
|
+
return msg.thirdParty ? MAX_DISPLAY_LINES_THIRD_PARTY : Infinity;
|
|
36
|
+
}
|
|
37
|
+
/** Maximum recipient names listed inline in the broadcast badge text. */
|
|
38
|
+
const BROADCAST_BADGE_NAME_CAP = 3;
|
|
39
|
+
/**
|
|
40
|
+
* Render the broadcast-badge inline text (#357). Format:
|
|
41
|
+
* `📡 broadcast → 3 players (alice, bob, carol) `
|
|
42
|
+
* `📡 broadcast → 8 players (alice, bob, carol +5 more) `
|
|
43
|
+
* Trailing space is intentional — the body text follows on the same line.
|
|
44
|
+
*/
|
|
45
|
+
function broadcastBadgeText(badge) {
|
|
46
|
+
const head = `\u{1F4E1} broadcast → ${badge.count} player${badge.count === 1 ? '' : 's'}`;
|
|
47
|
+
const named = badge.recipients.slice(0, BROADCAST_BADGE_NAME_CAP);
|
|
48
|
+
const remainder = Math.max(0, badge.count - named.length);
|
|
49
|
+
if (named.length === 0)
|
|
50
|
+
return `${head} `;
|
|
51
|
+
const list = remainder > 0 ? `${named.join(', ')} +${remainder} more` : named.join(', ');
|
|
52
|
+
return `${head} (${list}) `;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build the inline first-line prefix string added to outbound messages:
|
|
56
|
+
* either the broadcast badge (#357) — which dominates when present —
|
|
57
|
+
* or the directed-recipient prefix (#360). Empty string when neither
|
|
58
|
+
* applies. Used by both `buildFormattedMessages` (precomputes once on
|
|
59
|
+
* `FormattedMsg.firstLinePrefix`) and as a fallback in `estimateLines`.
|
|
60
|
+
*/
|
|
61
|
+
function makeFirstLinePrefix(msg) {
|
|
62
|
+
if (msg.broadcastBadge)
|
|
63
|
+
return broadcastBadgeText(msg.broadcastBadge);
|
|
64
|
+
// `→ @<label> ` — arrow + space + @ + label + trailing space.
|
|
65
|
+
if (msg.recipientLabel)
|
|
66
|
+
return `→ @${msg.recipientLabel} `;
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
function estimateLines(msg, termCols) {
|
|
70
|
+
const bodyWidth = Math.max(20, termCols - 4);
|
|
71
|
+
const originalLines = msg.body.split('\n');
|
|
72
|
+
const cap = maxLines(msg);
|
|
73
|
+
// When a first-line prefix (broadcast badge / `→ @<to>`) is shown,
|
|
74
|
+
// wrap the FIRST source line at a narrower width. Continuation source
|
|
75
|
+
// lines (and continuation wraps) use the full bodyWidth.
|
|
76
|
+
const prefixLen = msg.firstLinePrefix?.length ?? 0;
|
|
77
|
+
const firstLineWidth = Math.max(20, bodyWidth - prefixLen);
|
|
78
|
+
// Wrap ALL lines, then cap — matches rendering logic exactly
|
|
79
|
+
let wrappedCount = 0;
|
|
80
|
+
for (let li = 0; li < originalLines.length; li++) {
|
|
81
|
+
const w = li === 0 ? firstLineWidth : bodyWidth;
|
|
82
|
+
wrappedCount += (0, format_1.wordWrap)(originalLines[li], w).length;
|
|
83
|
+
}
|
|
84
|
+
let total = msg.direction === 'out' ? 0 : 1; // header line for inbound
|
|
85
|
+
total += Math.min(wrappedCount, cap); // body (capped by WRAPPED count)
|
|
86
|
+
if (wrappedCount > cap)
|
|
87
|
+
total += 1; // overflow indicator "… (N more lines)"
|
|
88
|
+
total += 1; // separator (\n or \n\n)
|
|
89
|
+
return total;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* #357: Fold consecutive `ConversationMessage`s sharing the same
|
|
93
|
+
* non-null `broadcastId` into a single group. Runs BEFORE per-message
|
|
94
|
+
* line estimation so `usedLines` doesn't over-count an unfolded
|
|
95
|
+
* fan-out and shrink the viewport.
|
|
96
|
+
*
|
|
97
|
+
* Fold key is `broadcastId + direction` only \u2014 role is excluded so
|
|
98
|
+
* local-echo entries (`from: 'you'`, undefined role) fold with their
|
|
99
|
+
* server-projected counterparts (`role: 'maestro-out'`) sharing the
|
|
100
|
+
* same id while the broadcast is in flight. Direction split keeps the
|
|
101
|
+
* inbound/outbound perspective intact.
|
|
102
|
+
*/
|
|
103
|
+
function foldByBroadcastId(sorted) {
|
|
104
|
+
const groups = [];
|
|
105
|
+
for (const m of sorted) {
|
|
106
|
+
const last = groups[groups.length - 1];
|
|
107
|
+
if (m.broadcastId &&
|
|
108
|
+
last &&
|
|
109
|
+
last[0].broadcastId === m.broadcastId &&
|
|
110
|
+
last[0].direction === m.direction) {
|
|
111
|
+
last.push(m);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
groups.push([m]);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return groups;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Pure projection: merge server conversation with local-echo sent
|
|
121
|
+
* messages, sort by timestamp, fold broadcast fan-out groups, and
|
|
122
|
+
* format each entry into the render-ready `FormattedMsg` shape.
|
|
123
|
+
* Exported so tests can assert on `recipientLabel` / `broadcastBadge`
|
|
124
|
+
* / `routeLabel` derivation without mounting Ink.
|
|
125
|
+
*
|
|
126
|
+
* `conductorPlayerId` is the active ensemble's conductor id. Used to
|
|
127
|
+
* suppress the `recipientLabel` on conductor-bound `maestro-out` rows
|
|
128
|
+
* so the `\u2192 @<conductor>` prefix doesn't dominate every message.
|
|
129
|
+
*/
|
|
130
|
+
function buildFormattedMessages(conversation, sentMessages, conductorPlayerId) {
|
|
131
|
+
// Merge server conversation with local echo (optimistic sent not yet on server)
|
|
132
|
+
const allConvoMsgs = [...conversation];
|
|
133
|
+
for (const m of sentMessages) {
|
|
134
|
+
const ts = new Date(m.timestamp).getTime();
|
|
135
|
+
// Strip @player prefix from sent text for comparison (server doesn't have it)
|
|
136
|
+
const sentBody = m.text.replace(/^@\S+\s+/, '');
|
|
137
|
+
const alreadyOnServer = conversation.some(c => c.direction === 'out' &&
|
|
138
|
+
Math.abs(new Date(c.timestamp).getTime() - ts) < 30000 &&
|
|
139
|
+
c.text.slice(0, 60) === sentBody.slice(0, 60));
|
|
140
|
+
if (!alreadyOnServer) {
|
|
141
|
+
allConvoMsgs.push({
|
|
142
|
+
id: `local-${m.timestamp}`,
|
|
143
|
+
from: 'you',
|
|
144
|
+
to: m.to,
|
|
145
|
+
text: m.text,
|
|
146
|
+
timestamp: m.timestamp,
|
|
147
|
+
direction: 'out',
|
|
148
|
+
// Forward broadcastId from the local-echo SentMessage so a
|
|
149
|
+
// freshly-sent broadcast still folds before the server projection
|
|
150
|
+
// catches up. (#357)
|
|
151
|
+
...(m.broadcastId !== undefined ? { broadcastId: m.broadcastId } : {}),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const sorted = allConvoMsgs.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
156
|
+
// #357: fold consecutive same-broadcastId entries into groups, then
|
|
157
|
+
// project each group as one FormattedMsg. The badge enumerates
|
|
158
|
+
// recipients; the first message's body/timestamp/sender stand in for
|
|
159
|
+
// the group's display fields.
|
|
160
|
+
const groups = foldByBroadcastId(sorted);
|
|
161
|
+
return groups.map(group => {
|
|
162
|
+
const m = group[0];
|
|
163
|
+
const role = m.role;
|
|
164
|
+
const thirdParty = m.thirdParty;
|
|
165
|
+
let routeLabel;
|
|
166
|
+
if (role === 'conductor-out')
|
|
167
|
+
routeLabel = `${m.from} \u2192 ${m.to}`;
|
|
168
|
+
else if (role === 'conductor-in')
|
|
169
|
+
routeLabel = `${m.from} \u2192 ${m.to}`;
|
|
170
|
+
// #357: badge wins over recipientLabel \u2014 when the row represents a
|
|
171
|
+
// folded broadcast, recipients are already enumerated inside the
|
|
172
|
+
// badge text and the single-recipient prefix would duplicate that.
|
|
173
|
+
let broadcastBadge;
|
|
174
|
+
if (m.broadcastId) {
|
|
175
|
+
broadcastBadge = {
|
|
176
|
+
count: group.length,
|
|
177
|
+
recipients: group.map(g => g.to),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// #360: only set recipientLabel for `maestro-out` messages where
|
|
181
|
+
// the recipient is neither the active conductor (whose role is the
|
|
182
|
+
// implicit default for bare-text input) nor the legacy `'conductor'`
|
|
183
|
+
// literal. `to` of `'maestro'` is also excluded \u2014 outbound to maestro
|
|
184
|
+
// is meaningless (the maestro is the user's own session). Suppressed
|
|
185
|
+
// when `broadcastBadge` is set (#357 \u2194 #360 composition).
|
|
186
|
+
let recipientLabel;
|
|
187
|
+
if (!broadcastBadge &&
|
|
188
|
+
role === 'maestro-out' &&
|
|
189
|
+
m.to && m.to !== 'maestro' && m.to !== 'conductor' && m.to !== conductorPlayerId) {
|
|
190
|
+
recipientLabel = m.to;
|
|
191
|
+
}
|
|
192
|
+
// Pre-render the inline first-line prefix once so `estimateLines`
|
|
193
|
+
// and the renderer don't each call `broadcastBadgeText` separately.
|
|
194
|
+
const firstLinePrefix = makeFirstLinePrefix({ broadcastBadge, recipientLabel });
|
|
195
|
+
return {
|
|
196
|
+
sender: m.from,
|
|
197
|
+
time: formatTime(m.timestamp),
|
|
198
|
+
body: m.text,
|
|
199
|
+
direction: m.direction,
|
|
200
|
+
role,
|
|
201
|
+
thirdParty,
|
|
202
|
+
routeLabel,
|
|
203
|
+
recipientLabel,
|
|
204
|
+
broadcastBadge,
|
|
205
|
+
...(firstLinePrefix ? { firstLinePrefix } : {}),
|
|
206
|
+
};
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
function ConversationStream({ conversation, sentMessages, contentHeight, overflowRef, conductorPlayerId }) {
|
|
210
|
+
const { Text } = (0, ink_context_1.useInk)();
|
|
211
|
+
const termCols = process.stdout.columns || 80;
|
|
212
|
+
const bodyWidth = Math.max(20, termCols - 4);
|
|
213
|
+
const formatted = buildFormattedMessages(conversation, sentMessages, conductorPlayerId);
|
|
214
|
+
// Work backwards from newest — include as many as fit in viewport
|
|
215
|
+
let usedLines = 0;
|
|
216
|
+
let startIdx = formatted.length;
|
|
217
|
+
for (let i = formatted.length - 1; i >= 0; i--) {
|
|
218
|
+
const needed = estimateLines(formatted[i], termCols);
|
|
219
|
+
if (usedLines + needed > contentHeight - 1)
|
|
220
|
+
break;
|
|
221
|
+
usedLines += needed;
|
|
222
|
+
startIdx = i;
|
|
223
|
+
}
|
|
224
|
+
// Store overflow data for parent to commit to Static scrollback
|
|
225
|
+
overflowRef.current = { formatted, startIdx };
|
|
226
|
+
const visibleMsgs = formatted.slice(startIdx);
|
|
227
|
+
const children = [];
|
|
228
|
+
if (visibleMsgs.length === 0) {
|
|
229
|
+
children.push('\n');
|
|
230
|
+
children.push(react_1.default.createElement(Text, { key: 'empty', color: theme_1.THEME.dim }, ' No messages yet. Type to send.'));
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
for (let i = 0; i < visibleMsgs.length; i++) {
|
|
234
|
+
const msg = visibleMsgs[i];
|
|
235
|
+
children.push(i === 0 ? '\n' : '\n\n');
|
|
236
|
+
const isOut = msg.direction === 'out';
|
|
237
|
+
const bg = isOut ? theme_1.THEME.inputBg : undefined;
|
|
238
|
+
// Word-wrap body. #360: when a recipientLabel prefix is rendered
|
|
239
|
+
// inline on the first line, wrap the FIRST source line at a
|
|
240
|
+
// narrower width to leave room. Continuation source lines (and
|
|
241
|
+
// their wraps) use the full bodyWidth.
|
|
242
|
+
const prefixLen = msg.firstLinePrefix?.length ?? 0;
|
|
243
|
+
const firstLineWidth = Math.max(20, bodyWidth - prefixLen);
|
|
244
|
+
const originalLines = msg.body.split('\n');
|
|
245
|
+
const wrappedLines = [];
|
|
246
|
+
for (let li = 0; li < originalLines.length; li++) {
|
|
247
|
+
const w = li === 0 ? firstLineWidth : bodyWidth;
|
|
248
|
+
wrappedLines.push(...(0, format_1.wordWrap)(originalLines[li], w));
|
|
249
|
+
}
|
|
250
|
+
const cap = maxLines(msg);
|
|
251
|
+
const displayLines = wrappedLines.slice(0, cap);
|
|
252
|
+
if (isOut) {
|
|
253
|
+
// Outbound: inline — ♩ first line, then wrapped continuation lines (no timestamp).
|
|
254
|
+
// The first-line prefix string is precomputed in
|
|
255
|
+
// `buildFormattedMessages` (#357 broadcast badge / #360 directed
|
|
256
|
+
// recipient — mutually exclusive). Color picks are local: badge
|
|
257
|
+
// accent vs recipient dim.
|
|
258
|
+
const prefixEl = msg.firstLinePrefix
|
|
259
|
+
? react_1.default.createElement(Text, { key: `pre-${i}`, backgroundColor: bg, color: msg.broadcastBadge ? theme_1.THEME.accent : theme_1.THEME.dim }, msg.firstLinePrefix)
|
|
260
|
+
: null;
|
|
261
|
+
for (let j = 0; j < displayLines.length; j++) {
|
|
262
|
+
if (j > 0)
|
|
263
|
+
children.push('\n');
|
|
264
|
+
if (j === 0) {
|
|
265
|
+
const firstText = displayLines[0];
|
|
266
|
+
const pad = ' '.repeat(Math.max(0, termCols - 2 - 3 - prefixLen - firstText.length));
|
|
267
|
+
children.push(react_1.default.createElement(react_1.default.Fragment, { key: `bl-${i}-0` }, react_1.default.createElement(Text, { backgroundColor: bg, color: theme_1.THEME.accent, bold: true }, ' \u2669 '), ...(prefixEl ? [prefixEl] : []), react_1.default.createElement(Text, { backgroundColor: bg, color: theme_1.THEME.text }, firstText), react_1.default.createElement(Text, { backgroundColor: bg, color: theme_1.THEME.dim }, pad)));
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
const contLine = `${INDENT}${displayLines[j]}`;
|
|
271
|
+
children.push(react_1.default.createElement(Text, { key: `bl-${i}-${j}`, backgroundColor: bg, color: theme_1.THEME.text }, contLine.padEnd(termCols - 2)));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (wrappedLines.length > cap) {
|
|
275
|
+
const moreLine = `${INDENT}\u2026 (${wrappedLines.length - cap} more lines)`;
|
|
276
|
+
children.push('\n');
|
|
277
|
+
children.push(react_1.default.createElement(Text, { key: `mt-${i}`, backgroundColor: bg, color: theme_1.THEME.dim }, moreLine.padEnd(termCols - 2)));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
// Inbound: header line + body lines
|
|
282
|
+
const headerLabel = msg.routeLabel || msg.sender;
|
|
283
|
+
const headerColor = msg.thirdParty ? theme_1.THEME.dim : theme_1.THEME.accent;
|
|
284
|
+
const bodyColor = msg.thirdParty ? theme_1.THEME.textMuted : theme_1.THEME.text;
|
|
285
|
+
const headerPrefix = msg.thirdParty ? ' ' : ' \u2190 ';
|
|
286
|
+
children.push(react_1.default.createElement(react_1.default.Fragment, { key: `hdr-${i}` }, react_1.default.createElement(Text, { color: theme_1.THEME.dim }, headerPrefix), react_1.default.createElement(Text, { color: headerColor }, headerLabel), react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ` ${msg.time}`)));
|
|
287
|
+
for (let j = 0; j < displayLines.length; j++) {
|
|
288
|
+
children.push('\n');
|
|
289
|
+
children.push(react_1.default.createElement(Text, { key: `bl-${i}-${j}`, color: bodyColor }, `${INDENT}${displayLines[j]}`));
|
|
290
|
+
}
|
|
291
|
+
if (wrappedLines.length > cap) {
|
|
292
|
+
children.push('\n');
|
|
293
|
+
children.push(react_1.default.createElement(Text, { key: `mt-${i}`, color: theme_1.THEME.dim }, `${INDENT}\u2026 (${wrappedLines.length - cap} more lines)`));
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Explicit padding: fill remaining space so content = exactly contentHeight lines
|
|
299
|
+
// usedLines = exact terminal lines for messages (from fitting loop)
|
|
300
|
+
// 1 line reserved for footer margin
|
|
301
|
+
const paddingLines = Math.max(0, contentHeight - usedLines - 1);
|
|
302
|
+
if (paddingLines > 0) {
|
|
303
|
+
children.push('\n'.repeat(paddingLines));
|
|
304
|
+
}
|
|
305
|
+
children.push('\n'); // exactly 1-line footer margin
|
|
306
|
+
return react_1.default.createElement(Text, null, ...children);
|
|
307
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CreateEnsembleWizard — step-by-step flow for creating a new ensemble.
|
|
3
|
+
*
|
|
4
|
+
* Steps: name → workDir → lineup (optional) → confirm
|
|
5
|
+
*
|
|
6
|
+
* Minimal-Box pattern: single <Text> root for static content,
|
|
7
|
+
* one <Box> for Ink's TextInput on text-input steps.
|
|
8
|
+
*/
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import type { CreateEnsembleState, CreateEnsembleAnswers } from '../store';
|
|
11
|
+
export interface CreateEnsembleWizardProps {
|
|
12
|
+
state: CreateEnsembleState;
|
|
13
|
+
onAnswer: (answer: Partial<CreateEnsembleAnswers>) => void;
|
|
14
|
+
onBack: () => void;
|
|
15
|
+
onConfirm: () => void;
|
|
16
|
+
onCancel: () => void;
|
|
17
|
+
onDone: () => void;
|
|
18
|
+
}
|
|
19
|
+
export declare function CreateEnsembleWizard({ state, onAnswer, onBack, onConfirm, onCancel, onDone }: CreateEnsembleWizardProps): React.FunctionComponentElement<React.FragmentProps> | React.CElement<{}, React.Component<{}, any, any>>;
|
|
@@ -0,0 +1,223 @@
|
|
|
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.CreateEnsembleWizard = CreateEnsembleWizard;
|
|
37
|
+
/**
|
|
38
|
+
* CreateEnsembleWizard — step-by-step flow for creating a new ensemble.
|
|
39
|
+
*
|
|
40
|
+
* Steps: name → workDir → lineup (optional) → confirm
|
|
41
|
+
*
|
|
42
|
+
* Minimal-Box pattern: single <Text> root for static content,
|
|
43
|
+
* one <Box> for Ink's TextInput on text-input steps.
|
|
44
|
+
*/
|
|
45
|
+
const react_1 = __importStar(require("react"));
|
|
46
|
+
const ink_context_1 = require("../ink-context");
|
|
47
|
+
const theme_1 = require("../utils/theme");
|
|
48
|
+
const saver_1 = require("../../ensemble/saver");
|
|
49
|
+
const STEP_LABELS = {
|
|
50
|
+
name: 'Ensemble name',
|
|
51
|
+
workDir: 'Working directory',
|
|
52
|
+
lineup: 'Lineup (optional)',
|
|
53
|
+
confirm: 'Confirm',
|
|
54
|
+
done: 'Done',
|
|
55
|
+
};
|
|
56
|
+
const TEXT_INPUT_STEPS = new Set(['name', 'workDir']);
|
|
57
|
+
function CreateEnsembleWizard({ state, onAnswer, onBack, onConfirm, onCancel, onDone }) {
|
|
58
|
+
const { Box, Text, TextInput, useInput } = (0, ink_context_1.useInk)();
|
|
59
|
+
const [inputValue, setInputValue] = (0, react_1.useState)('');
|
|
60
|
+
const [lineupIdx, setLineupIdx] = (0, react_1.useState)(0);
|
|
61
|
+
const [lineupCustom, setLineupCustom] = (0, react_1.useState)(false);
|
|
62
|
+
// Build lineup options: (none) + saved/shipped + custom path
|
|
63
|
+
const lineupOptions = (0, react_1.useMemo)(() => {
|
|
64
|
+
const options = [
|
|
65
|
+
{ label: '(none) \u2014 start with no lineup', value: '' },
|
|
66
|
+
];
|
|
67
|
+
try {
|
|
68
|
+
for (const l of (0, saver_1.listAllLineups)()) {
|
|
69
|
+
options.push({ label: `${l.name} (${l.source})`, value: l.name, source: l.source });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch { /* ignore */ }
|
|
73
|
+
options.push({ label: '[custom path...]', value: '__custom__' });
|
|
74
|
+
return options;
|
|
75
|
+
}, []);
|
|
76
|
+
useInput((0, react_1.useCallback)((_input, key) => {
|
|
77
|
+
if (key.escape) {
|
|
78
|
+
onCancel();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (key.backspace && state.step !== 'name' && state.step !== 'done' && !inputValue) {
|
|
82
|
+
if (state.step === 'lineup' && lineupCustom) {
|
|
83
|
+
setLineupCustom(false);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
onBack();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (state.step === 'confirm' && key.return)
|
|
90
|
+
onConfirm();
|
|
91
|
+
if (state.step === 'done' && key.return)
|
|
92
|
+
onDone();
|
|
93
|
+
// Lineup list navigation
|
|
94
|
+
if (state.step === 'lineup' && !lineupCustom) {
|
|
95
|
+
if (key.upArrow) {
|
|
96
|
+
setLineupIdx(i => (i - 1 + lineupOptions.length) % lineupOptions.length);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (key.downArrow) {
|
|
100
|
+
setLineupIdx(i => (i + 1) % lineupOptions.length);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (key.return) {
|
|
104
|
+
const selected = lineupOptions[lineupIdx];
|
|
105
|
+
if (selected.value === '__custom__') {
|
|
106
|
+
setLineupCustom(true);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
onAnswer({ lineup: selected.value });
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}, [state.step, inputValue, lineupCustom, lineupIdx, lineupOptions, onBack, onCancel, onConfirm, onDone, onAnswer]));
|
|
115
|
+
const handleTextSubmit = (0, react_1.useCallback)((value) => {
|
|
116
|
+
const trimmed = value.trim();
|
|
117
|
+
switch (state.step) {
|
|
118
|
+
case 'name':
|
|
119
|
+
if (!trimmed)
|
|
120
|
+
return;
|
|
121
|
+
onAnswer({ name: trimmed });
|
|
122
|
+
break;
|
|
123
|
+
case 'workDir':
|
|
124
|
+
onAnswer({ workDir: trimmed || state.answers.workDir });
|
|
125
|
+
break;
|
|
126
|
+
case 'lineup':
|
|
127
|
+
// Custom path mode
|
|
128
|
+
onAnswer({ lineup: trimmed });
|
|
129
|
+
setLineupCustom(false);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
setInputValue('');
|
|
133
|
+
}, [state.step, state.answers.workDir, onAnswer]);
|
|
134
|
+
const children = [];
|
|
135
|
+
// Header
|
|
136
|
+
children.push(react_1.default.createElement(react_1.default.Fragment, { key: 'hdr' }, react_1.default.createElement(Text, { bold: true, color: theme_1.THEME.accent }, ' Create New Ensemble'), react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ' (Esc to cancel, Backspace to go back)')));
|
|
137
|
+
// Completed steps
|
|
138
|
+
const steps = ['name', 'workDir', 'lineup'];
|
|
139
|
+
for (const s of steps) {
|
|
140
|
+
if (s === state.step)
|
|
141
|
+
break;
|
|
142
|
+
const value = getAnswerDisplay(s, state.answers);
|
|
143
|
+
children.push('\n');
|
|
144
|
+
children.push(react_1.default.createElement(react_1.default.Fragment, { key: `done-${s}` }, react_1.default.createElement(Text, { color: theme_1.THEME.success }, ' \u2714 '), react_1.default.createElement(Text, { color: theme_1.THEME.dim }, `${STEP_LABELS[s]}: `), react_1.default.createElement(Text, { color: theme_1.THEME.text }, value)));
|
|
145
|
+
}
|
|
146
|
+
// Current step
|
|
147
|
+
if (state.step === 'confirm') {
|
|
148
|
+
const a = state.answers;
|
|
149
|
+
children.push('\n\n');
|
|
150
|
+
children.push(react_1.default.createElement(Text, { key: 'sum-h', bold: true, color: theme_1.THEME.accent }, ' Create Ensemble:'));
|
|
151
|
+
children.push('\n');
|
|
152
|
+
children.push(react_1.default.createElement(Text, { key: 'sum-n', color: theme_1.THEME.text }, ` Name: ${a.name}`));
|
|
153
|
+
children.push('\n');
|
|
154
|
+
children.push(react_1.default.createElement(Text, { key: 'sum-d', color: theme_1.THEME.text }, ` Directory: ${a.workDir}`));
|
|
155
|
+
children.push('\n');
|
|
156
|
+
children.push(react_1.default.createElement(Text, { key: 'sum-l', color: theme_1.THEME.text }, ` Lineup: ${a.lineup || '(none — bare ensemble)'}`));
|
|
157
|
+
children.push('\n\n');
|
|
158
|
+
children.push(react_1.default.createElement(Text, { key: 'sum-hint', color: theme_1.THEME.dim }, ' Press Enter to create, Esc to cancel'));
|
|
159
|
+
}
|
|
160
|
+
else if (state.step === 'done') {
|
|
161
|
+
children.push('\n\n');
|
|
162
|
+
if (state.error) {
|
|
163
|
+
children.push(react_1.default.createElement(Text, { key: 'err', color: theme_1.THEME.error, bold: true }, ` \u2717 Failed: ${state.error}`));
|
|
164
|
+
children.push('\n');
|
|
165
|
+
children.push(react_1.default.createElement(Text, { key: 'err-h', color: theme_1.THEME.dim }, ' Press Enter to return'));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else if (state.submitting) {
|
|
169
|
+
children.push('\n\n');
|
|
170
|
+
children.push(react_1.default.createElement(Text, { key: 'sub', color: theme_1.THEME.warning }, ` \u2026 Creating ensemble "${state.answers.name}"...`));
|
|
171
|
+
}
|
|
172
|
+
else if (state.step === 'lineup') {
|
|
173
|
+
children.push('\n\n');
|
|
174
|
+
children.push(react_1.default.createElement(react_1.default.Fragment, { key: 'inp-q' }, react_1.default.createElement(Text, { color: theme_1.THEME.accent }, ' ? '), react_1.default.createElement(Text, { bold: true, color: theme_1.THEME.text }, 'Select a lineup:')));
|
|
175
|
+
if (!lineupCustom) {
|
|
176
|
+
for (let i = 0; i < lineupOptions.length; i++) {
|
|
177
|
+
const opt = lineupOptions[i];
|
|
178
|
+
const selected = i === lineupIdx;
|
|
179
|
+
children.push('\n');
|
|
180
|
+
children.push(react_1.default.createElement(Text, { key: `lo-${i}`, color: selected ? theme_1.THEME.text : theme_1.THEME.dim, bold: selected }, ` ${selected ? '\u276F' : ' '} ${opt.label}`));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else if (TEXT_INPUT_STEPS.has(state.step)) {
|
|
185
|
+
const defaultHint = getDefaultHint(state.step, state.answers);
|
|
186
|
+
children.push('\n\n');
|
|
187
|
+
children.push(react_1.default.createElement(react_1.default.Fragment, { key: 'inp-q' }, react_1.default.createElement(Text, { color: theme_1.THEME.accent }, ' ? '), react_1.default.createElement(Text, { bold: true, color: theme_1.THEME.text }, `${STEP_LABELS[state.step]}:`), defaultHint
|
|
188
|
+
? react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ` (${defaultHint})`)
|
|
189
|
+
: null));
|
|
190
|
+
}
|
|
191
|
+
// Lineup custom path mode: show text input
|
|
192
|
+
if (state.step === 'lineup' && lineupCustom && !state.submitting) {
|
|
193
|
+
return react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement(Text, null, ...children), react_1.default.createElement(Box, { marginLeft: 3 }, react_1.default.createElement(Text, { color: theme_1.THEME.accent }, '> '), react_1.default.createElement(TextInput, {
|
|
194
|
+
value: inputValue,
|
|
195
|
+
onChange: setInputValue,
|
|
196
|
+
onSubmit: handleTextSubmit,
|
|
197
|
+
})));
|
|
198
|
+
}
|
|
199
|
+
// Text input steps: Text + Box(TextInput)
|
|
200
|
+
if (TEXT_INPUT_STEPS.has(state.step) && !state.submitting) {
|
|
201
|
+
return react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement(Text, null, ...children), react_1.default.createElement(Box, { marginLeft: 3 }, react_1.default.createElement(Text, { color: theme_1.THEME.accent }, '> '), react_1.default.createElement(TextInput, {
|
|
202
|
+
value: inputValue,
|
|
203
|
+
onChange: setInputValue,
|
|
204
|
+
onSubmit: handleTextSubmit,
|
|
205
|
+
})));
|
|
206
|
+
}
|
|
207
|
+
return react_1.default.createElement(Text, null, ...children);
|
|
208
|
+
}
|
|
209
|
+
function getAnswerDisplay(step, answers) {
|
|
210
|
+
switch (step) {
|
|
211
|
+
case 'name': return answers.name;
|
|
212
|
+
case 'workDir': return answers.workDir;
|
|
213
|
+
case 'lineup': return answers.lineup || '(none)';
|
|
214
|
+
default: return '';
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function getDefaultHint(step, answers) {
|
|
218
|
+
switch (step) {
|
|
219
|
+
case 'workDir': return answers.workDir;
|
|
220
|
+
case 'lineup': return 'press Enter to skip';
|
|
221
|
+
default: return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed-name confirmation for `/destroy <ensemble>`. User must type the
|
|
3
|
+
* ensemble name character-for-character before Enter fires the destroy
|
|
4
|
+
* call. Mismatch preserves the input + surfaces an inline error; Esc
|
|
5
|
+
* cancels.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
export interface DestroyConfirmModalProps {
|
|
9
|
+
ensemble: string;
|
|
10
|
+
input: string;
|
|
11
|
+
error?: string;
|
|
12
|
+
submitting?: boolean;
|
|
13
|
+
onInput: (next: string) => void;
|
|
14
|
+
onSubmit: () => void;
|
|
15
|
+
onCancel: () => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function DestroyConfirmModal(props: DestroyConfirmModalProps): React.ReactElement;
|
|
@@ -0,0 +1,62 @@
|
|
|
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.DestroyConfirmModal = DestroyConfirmModal;
|
|
37
|
+
/**
|
|
38
|
+
* Typed-name confirmation for `/destroy <ensemble>`. User must type the
|
|
39
|
+
* ensemble name character-for-character before Enter fires the destroy
|
|
40
|
+
* call. Mismatch preserves the input + surfaces an inline error; Esc
|
|
41
|
+
* cancels.
|
|
42
|
+
*/
|
|
43
|
+
const react_1 = __importStar(require("react"));
|
|
44
|
+
const ink_context_1 = require("../ink-context");
|
|
45
|
+
const theme_1 = require("../utils/theme");
|
|
46
|
+
function DestroyConfirmModal(props) {
|
|
47
|
+
const { ensemble, input, error, submitting, onInput, onSubmit, onCancel } = props;
|
|
48
|
+
const { Box, Text, TextInput, useInput } = (0, ink_context_1.useInk)();
|
|
49
|
+
useInput((0, react_1.useCallback)((_input, key) => {
|
|
50
|
+
if (!submitting && key.escape)
|
|
51
|
+
onCancel();
|
|
52
|
+
}, [submitting, onCancel]));
|
|
53
|
+
return react_1.default.createElement(Box, { flexDirection: 'column' }, react_1.default.createElement(Text, { bold: true, color: theme_1.THEME.error }, ' Destroy ensemble'), react_1.default.createElement(Box, { marginTop: 1, flexDirection: 'column' }, react_1.default.createElement(Text, { color: theme_1.THEME.text }, ` Destroying "${ensemble}" will terminate all sessions, the scheduler, and the maestro.`), react_1.default.createElement(Text, { color: theme_1.THEME.text }, ` Type the ensemble name (${ensemble}) to confirm, or Esc to cancel:`)), submitting
|
|
54
|
+
? react_1.default.createElement(Box, { marginLeft: 3, marginTop: 1 }, react_1.default.createElement(Text, { color: theme_1.THEME.warning }, `\u2026 Destroying "${ensemble}"\u2026`))
|
|
55
|
+
: react_1.default.createElement(Box, { marginLeft: 3, marginTop: 1 }, react_1.default.createElement(Text, { color: theme_1.THEME.error }, '> '), react_1.default.createElement(TextInput, {
|
|
56
|
+
value: input,
|
|
57
|
+
onChange: onInput,
|
|
58
|
+
onSubmit,
|
|
59
|
+
})), error
|
|
60
|
+
? react_1.default.createElement(Text, { color: theme_1.THEME.error }, ` \u2717 ${error}`)
|
|
61
|
+
: null);
|
|
62
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensemble list view — landing screen showing all ensembles.
|
|
3
|
+
* Arrow keys to navigate, Enter to drill in, q to quit.
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import type { EnsembleSummary } from '../store';
|
|
7
|
+
export interface EnsembleListViewProps {
|
|
8
|
+
ensembles: EnsembleSummary[];
|
|
9
|
+
selectedIndex: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function EnsembleListView({ ensembles, selectedIndex }: EnsembleListViewProps): React.FunctionComponentElement<{
|
|
12
|
+
flexDirection: string;
|
|
13
|
+
padding: number;
|
|
14
|
+
}>;
|