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.
Files changed (484) hide show
  1. package/CLAUDE.md +213 -0
  2. package/LICENSE +21 -0
  3. package/README.md +289 -0
  4. package/assets/icon-32.png +0 -0
  5. package/assets/icon-512.png +0 -0
  6. package/assets/icon-64.png +0 -0
  7. package/assets/icon-dark-32.png +0 -0
  8. package/assets/icon-dark-64.png +0 -0
  9. package/assets/icon-dark.svg +9 -0
  10. package/assets/icon.svg +9 -0
  11. package/assets/logo-dark.svg +11 -0
  12. package/assets/logo-light.svg +11 -0
  13. package/dashboard/README.md +91 -0
  14. package/dashboard/dist/assets/index-CB78ToNE.css +2 -0
  15. package/dashboard/dist/assets/index-_5jV0Znu.js +62 -0
  16. package/dashboard/dist/assets/index-_5jV0Znu.js.map +1 -0
  17. package/dashboard/dist/index.html +21 -0
  18. package/dashboard/package.json +47 -0
  19. package/dist/activities/hard-terminate.d.ts +32 -0
  20. package/dist/activities/hard-terminate.js +460 -0
  21. package/dist/activities/maestro.d.ts +72 -0
  22. package/dist/activities/maestro.js +254 -0
  23. package/dist/activities/outbox.d.ts +188 -0
  24. package/dist/activities/outbox.js +849 -0
  25. package/dist/activities/resolve.d.ts +64 -0
  26. package/dist/activities/resolve.js +129 -0
  27. package/dist/activities/schedule-fire.d.ts +36 -0
  28. package/dist/activities/schedule-fire.js +147 -0
  29. package/dist/adapters/base.d.ts +426 -0
  30. package/dist/adapters/base.js +1270 -0
  31. package/dist/adapters/claude-api/adapter.d.ts +168 -0
  32. package/dist/adapters/claude-api/adapter.js +797 -0
  33. package/dist/adapters/claude-api/api-error.d.ts +96 -0
  34. package/dist/adapters/claude-api/api-error.js +191 -0
  35. package/dist/adapters/claude-api/index.d.ts +16 -0
  36. package/dist/adapters/claude-api/index.js +21 -0
  37. package/dist/adapters/claude-api/mcp-bridge.d.ts +50 -0
  38. package/dist/adapters/claude-api/mcp-bridge.js +157 -0
  39. package/dist/adapters/claude-code/adapter.d.ts +133 -0
  40. package/dist/adapters/claude-code/adapter.js +274 -0
  41. package/dist/adapters/claude-code/index.d.ts +15 -0
  42. package/dist/adapters/claude-code/index.js +20 -0
  43. package/dist/adapters/claude-code-headless/adapter.d.ts +131 -0
  44. package/dist/adapters/claude-code-headless/adapter.js +710 -0
  45. package/dist/adapters/claude-code-headless/error-mapper.d.ts +107 -0
  46. package/dist/adapters/claude-code-headless/error-mapper.js +281 -0
  47. package/dist/adapters/claude-code-headless/index.d.ts +17 -0
  48. package/dist/adapters/claude-code-headless/index.js +26 -0
  49. package/dist/adapters/claude-code-headless/pre-flight.d.ts +51 -0
  50. package/dist/adapters/claude-code-headless/pre-flight.js +207 -0
  51. package/dist/adapters/claude-code-headless/prompt.d.ts +93 -0
  52. package/dist/adapters/claude-code-headless/prompt.js +79 -0
  53. package/dist/adapters/claude-code-headless/stream-json.d.ts +242 -0
  54. package/dist/adapters/claude-code-headless/stream-json.js +208 -0
  55. package/dist/adapters/claude-code-headless/types.d.ts +28 -0
  56. package/dist/adapters/claude-code-headless/types.js +36 -0
  57. package/dist/adapters/copilot/adapter.d.ts +100 -0
  58. package/dist/adapters/copilot/adapter.js +730 -0
  59. package/dist/adapters/copilot/index.d.ts +15 -0
  60. package/dist/adapters/copilot/index.js +20 -0
  61. package/dist/adapters/index.d.ts +42 -0
  62. package/dist/adapters/index.js +115 -0
  63. package/dist/adapters/opencode/adapter.d.ts +82 -0
  64. package/dist/adapters/opencode/adapter.js +710 -0
  65. package/dist/adapters/opencode/config.d.ts +90 -0
  66. package/dist/adapters/opencode/config.js +137 -0
  67. package/dist/adapters/opencode/helpers.d.ts +40 -0
  68. package/dist/adapters/opencode/helpers.js +144 -0
  69. package/dist/adapters/opencode/index.d.ts +12 -0
  70. package/dist/adapters/opencode/index.js +17 -0
  71. package/dist/adapters/opencode/server-bridge.d.ts +124 -0
  72. package/dist/adapters/opencode/server-bridge.js +216 -0
  73. package/dist/adapters/sdk/base.d.ts +95 -0
  74. package/dist/adapters/sdk/base.js +134 -0
  75. package/dist/adapters/sdk/system-prompt.d.ts +64 -0
  76. package/dist/adapters/sdk/system-prompt.js +78 -0
  77. package/dist/adapters/terminal-error.d.ts +27 -0
  78. package/dist/adapters/terminal-error.js +39 -0
  79. package/dist/channel.d.ts +3 -0
  80. package/dist/channel.js +48 -0
  81. package/dist/cli/commands.d.ts +245 -0
  82. package/dist/cli/commands.js +2438 -0
  83. package/dist/cli/config-command.d.ts +8 -0
  84. package/dist/cli/config-command.js +254 -0
  85. package/dist/cli/daemon-command.d.ts +57 -0
  86. package/dist/cli/daemon-command.js +493 -0
  87. package/dist/cli/daemon.d.ts +217 -0
  88. package/dist/cli/daemon.js +632 -0
  89. package/dist/cli/dashboard-command.d.ts +20 -0
  90. package/dist/cli/dashboard-command.js +241 -0
  91. package/dist/cli/dev-banner.d.ts +107 -0
  92. package/dist/cli/dev-banner.js +190 -0
  93. package/dist/cli/dev-mode-bootstrap.d.ts +29 -0
  94. package/dist/cli/dev-mode-bootstrap.js +36 -0
  95. package/dist/cli/dev-verbs.d.ts +43 -0
  96. package/dist/cli/dev-verbs.js +254 -0
  97. package/dist/cli/help-text.d.ts +1 -0
  98. package/dist/cli/help-text.js +158 -0
  99. package/dist/cli/legacy-migration.d.ts +35 -0
  100. package/dist/cli/legacy-migration.js +335 -0
  101. package/dist/cli/mcp.d.ts +8 -0
  102. package/dist/cli/mcp.js +63 -0
  103. package/dist/cli/output.d.ts +12 -0
  104. package/dist/cli/output.js +37 -0
  105. package/dist/cli/preflight.d.ts +9 -0
  106. package/dist/cli/preflight.js +96 -0
  107. package/dist/cli/removed-verbs.d.ts +9 -0
  108. package/dist/cli/removed-verbs.js +78 -0
  109. package/dist/cli/sa-preflight.d.ts +99 -0
  110. package/dist/cli/sa-preflight.js +183 -0
  111. package/dist/cli/scenarios-command.d.ts +6 -0
  112. package/dist/cli/scenarios-command.js +167 -0
  113. package/dist/cli/startup.d.ts +112 -0
  114. package/dist/cli/startup.js +641 -0
  115. package/dist/cli/upgrade-command.d.ts +5 -0
  116. package/dist/cli/upgrade-command.js +240 -0
  117. package/dist/cli.d.ts +2 -0
  118. package/dist/cli.js +680 -0
  119. package/dist/client/core.d.ts +33 -0
  120. package/dist/client/core.js +1260 -0
  121. package/dist/client/ensure-conductor-spawned.d.ts +35 -0
  122. package/dist/client/ensure-conductor-spawned.js +48 -0
  123. package/dist/client/index.d.ts +32 -0
  124. package/dist/client/index.js +22 -0
  125. package/dist/client/interface.d.ts +461 -0
  126. package/dist/client/interface.js +2 -0
  127. package/dist/client/subscribe.d.ts +108 -0
  128. package/dist/client/subscribe.js +598 -0
  129. package/dist/client/with-spawn.d.ts +27 -0
  130. package/dist/client/with-spawn.js +87 -0
  131. package/dist/config.d.ts +323 -0
  132. package/dist/config.js +593 -0
  133. package/dist/connection.d.ts +7 -0
  134. package/dist/connection.js +46 -0
  135. package/dist/constants.d.ts +50 -0
  136. package/dist/constants.js +74 -0
  137. package/dist/copilot-bridge.d.ts +22 -0
  138. package/dist/copilot-bridge.js +565 -0
  139. package/dist/daemon-adapter-versions.d.ts +52 -0
  140. package/dist/daemon-adapter-versions.js +170 -0
  141. package/dist/daemon.d.ts +275 -0
  142. package/dist/daemon.js +989 -0
  143. package/dist/ensemble/agent-types.d.ts +23 -0
  144. package/dist/ensemble/agent-types.js +132 -0
  145. package/dist/ensemble/loader.d.ts +14 -0
  146. package/dist/ensemble/loader.js +140 -0
  147. package/dist/ensemble/saver.d.ts +49 -0
  148. package/dist/ensemble/saver.js +201 -0
  149. package/dist/ensemble/schema.d.ts +71 -0
  150. package/dist/ensemble/schema.js +3 -0
  151. package/dist/git-info.d.ts +4 -0
  152. package/dist/git-info.js +29 -0
  153. package/dist/http/aggregate.d.ts +319 -0
  154. package/dist/http/aggregate.js +684 -0
  155. package/dist/http/auth.d.ts +67 -0
  156. package/dist/http/auth.js +177 -0
  157. package/dist/http/body.d.ts +71 -0
  158. package/dist/http/body.js +121 -0
  159. package/dist/http/catalog.d.ts +67 -0
  160. package/dist/http/catalog.js +209 -0
  161. package/dist/http/cors.d.ts +42 -0
  162. package/dist/http/cors.js +111 -0
  163. package/dist/http/dashboard-pair.d.ts +94 -0
  164. package/dist/http/dashboard-pair.js +148 -0
  165. package/dist/http/dashboard.d.ts +20 -0
  166. package/dist/http/dashboard.js +160 -0
  167. package/dist/http/event-bus.d.ts +217 -0
  168. package/dist/http/event-bus.js +365 -0
  169. package/dist/http/event-id.d.ts +77 -0
  170. package/dist/http/event-id.js +117 -0
  171. package/dist/http/event-types.d.ts +348 -0
  172. package/dist/http/event-types.js +36 -0
  173. package/dist/http/fixtures/chat-stress.d.ts +8 -0
  174. package/dist/http/fixtures/chat-stress.js +63 -0
  175. package/dist/http/fixtures/conductor-leaving.d.ts +8 -0
  176. package/dist/http/fixtures/conductor-leaving.js +80 -0
  177. package/dist/http/fixtures/constants.d.ts +10 -0
  178. package/dist/http/fixtures/constants.js +13 -0
  179. package/dist/http/fixtures/eight-player-broadcast.d.ts +10 -0
  180. package/dist/http/fixtures/eight-player-broadcast.js +81 -0
  181. package/dist/http/fixtures/empty-ensemble.d.ts +6 -0
  182. package/dist/http/fixtures/empty-ensemble.js +26 -0
  183. package/dist/http/fixtures/index.d.ts +55 -0
  184. package/dist/http/fixtures/index.js +110 -0
  185. package/dist/http/fixtures/single-conductor.d.ts +7 -0
  186. package/dist/http/fixtures/single-conductor.js +46 -0
  187. package/dist/http/fixtures/sse-reconnect.d.ts +8 -0
  188. package/dist/http/fixtures/sse-reconnect.js +77 -0
  189. package/dist/http/index.d.ts +21 -0
  190. package/dist/http/index.js +61 -0
  191. package/dist/http/port-file.d.ts +22 -0
  192. package/dist/http/port-file.js +132 -0
  193. package/dist/http/responses.d.ts +27 -0
  194. package/dist/http/responses.js +40 -0
  195. package/dist/http/ring-buffer.d.ts +41 -0
  196. package/dist/http/ring-buffer.js +80 -0
  197. package/dist/http/server.d.ts +122 -0
  198. package/dist/http/server.js +459 -0
  199. package/dist/http/snapshot.d.ts +85 -0
  200. package/dist/http/snapshot.js +180 -0
  201. package/dist/http/sse-handler.d.ts +87 -0
  202. package/dist/http/sse-handler.js +294 -0
  203. package/dist/http/writes.d.ts +55 -0
  204. package/dist/http/writes.js +240 -0
  205. package/dist/palette/index.d.ts +138 -0
  206. package/dist/palette/index.js +221 -0
  207. package/dist/reconcile/orphans.d.ts +255 -0
  208. package/dist/reconcile/orphans.js +340 -0
  209. package/dist/scripts/258-spotcheck.js +303 -0
  210. package/dist/scripts/check-components-css-sync.js +199 -0
  211. package/dist/scripts/run-shard.js +121 -0
  212. package/dist/scripts/verify-daemon-isolation-guard.js +128 -0
  213. package/dist/server-tools.d.ts +87 -0
  214. package/dist/server-tools.js +146 -0
  215. package/dist/server.d.ts +2 -0
  216. package/dist/server.js +366 -0
  217. package/dist/spawn.d.ts +296 -0
  218. package/dist/spawn.js +747 -0
  219. package/dist/tools/agent-types.d.ts +2 -0
  220. package/dist/tools/agent-types.js +21 -0
  221. package/dist/tools/attachment-info.d.ts +4 -0
  222. package/dist/tools/attachment-info.js +48 -0
  223. package/dist/tools/broadcast.d.ts +4 -0
  224. package/dist/tools/broadcast.js +76 -0
  225. package/dist/tools/cancel-stage.d.ts +3 -0
  226. package/dist/tools/cancel-stage.js +20 -0
  227. package/dist/tools/clear-state.d.ts +3 -0
  228. package/dist/tools/clear-state.js +37 -0
  229. package/dist/tools/coat-check-evict.d.ts +4 -0
  230. package/dist/tools/coat-check-evict.js +43 -0
  231. package/dist/tools/coat-check-get.d.ts +4 -0
  232. package/dist/tools/coat-check-get.js +56 -0
  233. package/dist/tools/coat-check-list.d.ts +4 -0
  234. package/dist/tools/coat-check-list.js +60 -0
  235. package/dist/tools/coat-check-put.d.ts +4 -0
  236. package/dist/tools/coat-check-put.js +53 -0
  237. package/dist/tools/cue.d.ts +44 -0
  238. package/dist/tools/cue.js +201 -0
  239. package/dist/tools/destroy.d.ts +4 -0
  240. package/dist/tools/destroy.js +188 -0
  241. package/dist/tools/detach.d.ts +4 -0
  242. package/dist/tools/detach.js +45 -0
  243. package/dist/tools/encore.d.ts +4 -0
  244. package/dist/tools/encore.js +31 -0
  245. package/dist/tools/ensemble.d.ts +32 -0
  246. package/dist/tools/ensemble.js +198 -0
  247. package/dist/tools/evaluate-gate.d.ts +3 -0
  248. package/dist/tools/evaluate-gate.js +32 -0
  249. package/dist/tools/fetch-state.d.ts +13 -0
  250. package/dist/tools/fetch-state.js +78 -0
  251. package/dist/tools/gates.d.ts +3 -0
  252. package/dist/tools/gates.js +41 -0
  253. package/dist/tools/helpers.d.ts +21 -0
  254. package/dist/tools/helpers.js +25 -0
  255. package/dist/tools/hosts.d.ts +4 -0
  256. package/dist/tools/hosts.js +40 -0
  257. package/dist/tools/listen.d.ts +3 -0
  258. package/dist/tools/listen.js +22 -0
  259. package/dist/tools/load-lineup.d.ts +5 -0
  260. package/dist/tools/load-lineup.js +381 -0
  261. package/dist/tools/migrate.d.ts +4 -0
  262. package/dist/tools/migrate.js +60 -0
  263. package/dist/tools/pause-ensemble.d.ts +4 -0
  264. package/dist/tools/pause-ensemble.js +58 -0
  265. package/dist/tools/pause.d.ts +4 -0
  266. package/dist/tools/pause.js +36 -0
  267. package/dist/tools/play.d.ts +4 -0
  268. package/dist/tools/play.js +57 -0
  269. package/dist/tools/quality-gate.d.ts +3 -0
  270. package/dist/tools/quality-gate.js +26 -0
  271. package/dist/tools/recall.d.ts +3 -0
  272. package/dist/tools/recall.js +32 -0
  273. package/dist/tools/recruit.d.ts +38 -0
  274. package/dist/tools/recruit.js +447 -0
  275. package/dist/tools/release.d.ts +4 -0
  276. package/dist/tools/release.js +98 -0
  277. package/dist/tools/report.d.ts +3 -0
  278. package/dist/tools/report.js +29 -0
  279. package/dist/tools/resolve.d.ts +1 -0
  280. package/dist/tools/resolve.js +7 -0
  281. package/dist/tools/restart.d.ts +35 -0
  282. package/dist/tools/restart.js +131 -0
  283. package/dist/tools/restore.d.ts +4 -0
  284. package/dist/tools/restore.js +107 -0
  285. package/dist/tools/resume-ensemble.d.ts +4 -0
  286. package/dist/tools/resume-ensemble.js +79 -0
  287. package/dist/tools/save-lineup.d.ts +4 -0
  288. package/dist/tools/save-lineup.js +36 -0
  289. package/dist/tools/save-state.d.ts +3 -0
  290. package/dist/tools/save-state.js +57 -0
  291. package/dist/tools/schedule.d.ts +4 -0
  292. package/dist/tools/schedule.js +152 -0
  293. package/dist/tools/schedules.d.ts +4 -0
  294. package/dist/tools/schedules.js +54 -0
  295. package/dist/tools/set-ensemble-description.d.ts +4 -0
  296. package/dist/tools/set-ensemble-description.js +37 -0
  297. package/dist/tools/set-name.d.ts +4 -0
  298. package/dist/tools/set-name.js +45 -0
  299. package/dist/tools/set-part.d.ts +3 -0
  300. package/dist/tools/set-part.js +20 -0
  301. package/dist/tools/shutdown.d.ts +4 -0
  302. package/dist/tools/shutdown.js +54 -0
  303. package/dist/tools/stage.d.ts +3 -0
  304. package/dist/tools/stage.js +28 -0
  305. package/dist/tools/stages.d.ts +3 -0
  306. package/dist/tools/stages.js +35 -0
  307. package/dist/tools/stop.d.ts +4 -0
  308. package/dist/tools/stop.js +29 -0
  309. package/dist/tools/unschedule.d.ts +4 -0
  310. package/dist/tools/unschedule.js +35 -0
  311. package/dist/tools/who-am-i.d.ts +3 -0
  312. package/dist/tools/who-am-i.js +34 -0
  313. package/dist/tools/worktree.d.ts +4 -0
  314. package/dist/tools/worktree.js +181 -0
  315. package/dist/tui/App.d.ts +85 -0
  316. package/dist/tui/App.js +1791 -0
  317. package/dist/tui/bootstrap-types.d.ts +46 -0
  318. package/dist/tui/bootstrap-types.js +7 -0
  319. package/dist/tui/client.d.ts +6 -0
  320. package/dist/tui/client.js +9 -0
  321. package/dist/tui/commands.d.ts +71 -0
  322. package/dist/tui/commands.js +1375 -0
  323. package/dist/tui/components/ActivityLog.d.ts +16 -0
  324. package/dist/tui/components/ActivityLog.js +36 -0
  325. package/dist/tui/components/ChatView.d.ts +35 -0
  326. package/dist/tui/components/ChatView.js +54 -0
  327. package/dist/tui/components/CommandOverlay.d.ts +15 -0
  328. package/dist/tui/components/CommandOverlay.js +34 -0
  329. package/dist/tui/components/CommandPalette.d.ts +21 -0
  330. package/dist/tui/components/CommandPalette.js +67 -0
  331. package/dist/tui/components/ConductorChat.d.ts +16 -0
  332. package/dist/tui/components/ConductorChat.js +32 -0
  333. package/dist/tui/components/ConversationStream.d.ts +114 -0
  334. package/dist/tui/components/ConversationStream.js +307 -0
  335. package/dist/tui/components/CreateEnsembleWizard.d.ts +19 -0
  336. package/dist/tui/components/CreateEnsembleWizard.js +223 -0
  337. package/dist/tui/components/DestroyConfirmModal.d.ts +17 -0
  338. package/dist/tui/components/DestroyConfirmModal.js +62 -0
  339. package/dist/tui/components/EnsembleListView.d.ts +14 -0
  340. package/dist/tui/components/EnsembleListView.js +32 -0
  341. package/dist/tui/components/EnsemblePanel.d.ts +12 -0
  342. package/dist/tui/components/EnsemblePanel.js +40 -0
  343. package/dist/tui/components/ErrorView.d.ts +31 -0
  344. package/dist/tui/components/ErrorView.js +129 -0
  345. package/dist/tui/components/HomeView.d.ts +54 -0
  346. package/dist/tui/components/HomeView.js +306 -0
  347. package/dist/tui/components/InputBar.d.ts +13 -0
  348. package/dist/tui/components/InputBar.js +58 -0
  349. package/dist/tui/components/LoadLineupModal.d.ts +18 -0
  350. package/dist/tui/components/LoadLineupModal.js +79 -0
  351. package/dist/tui/components/MainView.d.ts +21 -0
  352. package/dist/tui/components/MainView.js +107 -0
  353. package/dist/tui/components/NewEnsembleModal.d.ts +9 -0
  354. package/dist/tui/components/NewEnsembleModal.js +73 -0
  355. package/dist/tui/components/Picker.d.ts +23 -0
  356. package/dist/tui/components/Picker.js +70 -0
  357. package/dist/tui/components/PlayerDetailView.d.ts +26 -0
  358. package/dist/tui/components/PlayerDetailView.js +118 -0
  359. package/dist/tui/components/PromptArea.d.ts +50 -0
  360. package/dist/tui/components/PromptArea.js +303 -0
  361. package/dist/tui/components/RecruitWizard.d.ts +17 -0
  362. package/dist/tui/components/RecruitWizard.js +221 -0
  363. package/dist/tui/components/RestoreConfirmModal.d.ts +18 -0
  364. package/dist/tui/components/RestoreConfirmModal.js +71 -0
  365. package/dist/tui/components/ScheduleOverlay.d.ts +13 -0
  366. package/dist/tui/components/ScheduleOverlay.js +113 -0
  367. package/dist/tui/components/ScheduleWizard.d.ts +19 -0
  368. package/dist/tui/components/ScheduleWizard.js +259 -0
  369. package/dist/tui/components/Splash.d.ts +23 -0
  370. package/dist/tui/components/Splash.js +221 -0
  371. package/dist/tui/components/StatusBar.d.ts +48 -0
  372. package/dist/tui/components/StatusBar.js +128 -0
  373. package/dist/tui/components/StatusOverlay.d.ts +15 -0
  374. package/dist/tui/components/StatusOverlay.js +76 -0
  375. package/dist/tui/components/TitleBar.d.ts +10 -0
  376. package/dist/tui/components/TitleBar.js +21 -0
  377. package/dist/tui/components/TopBar.d.ts +12 -0
  378. package/dist/tui/components/TopBar.js +15 -0
  379. package/dist/tui/core-api.d.ts +26 -0
  380. package/dist/tui/core-api.js +67 -0
  381. package/dist/tui/hooks/useEnsembleDiscovery.d.ts +3 -0
  382. package/dist/tui/hooks/useEnsembleDiscovery.js +30 -0
  383. package/dist/tui/hooks/useMaestroPoller.d.ts +3 -0
  384. package/dist/tui/hooks/useMaestroPoller.js +36 -0
  385. package/dist/tui/hooks/useSendCommand.d.ts +7 -0
  386. package/dist/tui/hooks/useSendCommand.js +29 -0
  387. package/dist/tui/index.d.ts +15 -0
  388. package/dist/tui/index.js +156 -0
  389. package/dist/tui/ink-context.d.ts +18 -0
  390. package/dist/tui/ink-context.js +59 -0
  391. package/dist/tui/ink-loader.d.ts +26 -0
  392. package/dist/tui/ink-loader.js +42 -0
  393. package/dist/tui/removed-commands.d.ts +9 -0
  394. package/dist/tui/removed-commands.js +22 -0
  395. package/dist/tui/sse-handler.d.ts +52 -0
  396. package/dist/tui/sse-handler.js +157 -0
  397. package/dist/tui/store.d.ts +598 -0
  398. package/dist/tui/store.js +753 -0
  399. package/dist/tui/utils/format.d.ts +56 -0
  400. package/dist/tui/utils/format.js +155 -0
  401. package/dist/tui/utils/fullscreen.d.ts +23 -0
  402. package/dist/tui/utils/fullscreen.js +71 -0
  403. package/dist/tui/utils/history.d.ts +10 -0
  404. package/dist/tui/utils/history.js +85 -0
  405. package/dist/tui/utils/platform.d.ts +45 -0
  406. package/dist/tui/utils/platform.js +258 -0
  407. package/dist/tui/utils/theme.d.ts +21 -0
  408. package/dist/tui/utils/theme.js +24 -0
  409. package/dist/types.d.ts +1020 -0
  410. package/dist/types.js +39 -0
  411. package/dist/utils/attachment-format.d.ts +22 -0
  412. package/dist/utils/attachment-format.js +32 -0
  413. package/dist/utils/default-part.d.ts +43 -0
  414. package/dist/utils/default-part.js +104 -0
  415. package/dist/utils/duration.d.ts +30 -0
  416. package/dist/utils/duration.js +69 -0
  417. package/dist/utils/ensemble-ops.d.ts +61 -0
  418. package/dist/utils/ensemble-ops.js +77 -0
  419. package/dist/utils/format-hosts.d.ts +21 -0
  420. package/dist/utils/format-hosts.js +73 -0
  421. package/dist/utils/hosts.d.ts +113 -0
  422. package/dist/utils/hosts.js +265 -0
  423. package/dist/utils/parent-death-watchdog.d.ts +1 -0
  424. package/dist/utils/parent-death-watchdog.js +47 -0
  425. package/dist/utils/query-timeout.d.ts +103 -0
  426. package/dist/utils/query-timeout.js +113 -0
  427. package/dist/utils/recall-format.d.ts +78 -0
  428. package/dist/utils/recall-format.js +105 -0
  429. package/dist/utils/restore-format.d.ts +49 -0
  430. package/dist/utils/restore-format.js +91 -0
  431. package/dist/utils/safe-path.d.ts +10 -0
  432. package/dist/utils/safe-path.js +43 -0
  433. package/dist/utils/sdk-probe.d.ts +9 -0
  434. package/dist/utils/sdk-probe.js +45 -0
  435. package/dist/utils/search-attributes.d.ts +76 -0
  436. package/dist/utils/search-attributes.js +86 -0
  437. package/dist/utils/validation.d.ts +113 -0
  438. package/dist/utils/validation.js +163 -0
  439. package/dist/utils/visibility-deadline.d.ts +186 -0
  440. package/dist/utils/visibility-deadline.js +158 -0
  441. package/dist/utils/worktree.d.ts +103 -0
  442. package/dist/utils/worktree.js +327 -0
  443. package/dist/worker.d.ts +14 -0
  444. package/dist/worker.js +146 -0
  445. package/dist/workflows/attachment-math.d.ts +56 -0
  446. package/dist/workflows/attachment-math.js +47 -0
  447. package/dist/workflows/index.d.ts +3 -0
  448. package/dist/workflows/index.js +11 -0
  449. package/dist/workflows/maestro-signals.d.ts +217 -0
  450. package/dist/workflows/maestro-signals.js +155 -0
  451. package/dist/workflows/maestro.d.ts +3 -0
  452. package/dist/workflows/maestro.js +812 -0
  453. package/dist/workflows/scheduler-signals.d.ts +10 -0
  454. package/dist/workflows/scheduler-signals.js +14 -0
  455. package/dist/workflows/scheduler.d.ts +17 -0
  456. package/dist/workflows/scheduler.js +143 -0
  457. package/dist/workflows/session.d.ts +2 -0
  458. package/dist/workflows/session.js +1638 -0
  459. package/dist/workflows/signals.d.ts +297 -0
  460. package/dist/workflows/signals.js +239 -0
  461. package/examples/agents/tempo-composer.md +56 -0
  462. package/examples/agents/tempo-conductor.md +117 -0
  463. package/examples/agents/tempo-critic.md +73 -0
  464. package/examples/agents/tempo-improv.md +74 -0
  465. package/examples/agents/tempo-liner.md +75 -0
  466. package/examples/agents/tempo-roadie.md +61 -0
  467. package/examples/agents/tempo-soloist.md +71 -0
  468. package/examples/agents/tempo-tuner.md +94 -0
  469. package/examples/ensembles/tempo-big-band.yaml +146 -0
  470. package/examples/ensembles/tempo-dev-team.yaml +58 -0
  471. package/examples/ensembles/tempo-headless-jam.yaml +77 -0
  472. package/examples/ensembles/tempo-jam-session.yaml +41 -0
  473. package/examples/ensembles/tempo-mock-jam.yaml +79 -0
  474. package/examples/ensembles/tempo-review-squad.yaml +32 -0
  475. package/package.json +172 -0
  476. package/packaging/launchd/com.agent.tempo.plist +46 -0
  477. package/packaging/systemd/agent-tempo.service +32 -0
  478. package/packaging/windows/install-task.ps1 +71 -0
  479. package/scenarios/conductor-recruit-mock.yaml +33 -0
  480. package/scenarios/echo-roundtrip.yaml +15 -0
  481. package/scenarios/multi-player-handoff.yaml +38 -0
  482. package/scenarios/recruit-cascade.yaml +38 -0
  483. package/scenarios/two-player-conversation.yaml +33 -0
  484. 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
+ }>;