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,23 @@
1
+ import { AgentTypeInfo } from '../types';
2
+ import { EnsembleLineup } from './schema';
3
+ /**
4
+ * Parse YAML frontmatter from a markdown file.
5
+ * Expects `---` delimiters wrapping YAML at the top of the file.
6
+ */
7
+ export declare function parseFrontmatter(filePath: string): Record<string, any>;
8
+ /**
9
+ * List all available agent types across the three-tier lookup.
10
+ * Deduplicates by name: project > user > shipped.
11
+ */
12
+ export declare function listAgentTypes(cwd?: string): AgentTypeInfo[];
13
+ /**
14
+ * Resolve a single agent type by name across the three-tier lookup.
15
+ * Returns the first match (project > user > shipped) or null.
16
+ */
17
+ export declare function resolveAgentType(name: string, cwd?: string): AgentTypeInfo | null;
18
+ /**
19
+ * Load and resolve a lineup, validating and resolving `type` fields on each player.
20
+ * Players without `type` pass through unchanged.
21
+ * Throws if a referenced type is not found.
22
+ */
23
+ export declare function loadAndResolveLineup(filePath: string, cwd?: string): EnsembleLineup;
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseFrontmatter = parseFrontmatter;
4
+ exports.listAgentTypes = listAgentTypes;
5
+ exports.resolveAgentType = resolveAgentType;
6
+ exports.loadAndResolveLineup = loadAndResolveLineup;
7
+ const fs_1 = require("fs");
8
+ const path_1 = require("path");
9
+ const os_1 = require("os");
10
+ const yaml_1 = require("yaml");
11
+ const loader_1 = require("./loader");
12
+ /**
13
+ * Parse YAML frontmatter from a markdown file.
14
+ * Expects `---` delimiters wrapping YAML at the top of the file.
15
+ */
16
+ function parseFrontmatter(filePath) {
17
+ const content = (0, fs_1.readFileSync)(filePath, 'utf8');
18
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
19
+ if (!match)
20
+ return {};
21
+ try {
22
+ return (0, yaml_1.parse)(match[1]) ?? {};
23
+ }
24
+ catch {
25
+ return {};
26
+ }
27
+ }
28
+ /** Resolve the shipped examples/agents directory relative to package root. */
29
+ function shippedAgentsDir() {
30
+ // Walk up from __dirname until we find examples/agents/ or package.json
31
+ let dir = __dirname;
32
+ for (let i = 0; i < 5; i++) {
33
+ const candidate = (0, path_1.join)(dir, 'examples', 'agents');
34
+ if ((0, fs_1.existsSync)(candidate))
35
+ return candidate;
36
+ const parent = (0, path_1.resolve)(dir, '..');
37
+ if (parent === dir)
38
+ break; // filesystem root
39
+ dir = parent;
40
+ }
41
+ // Fallback: two levels up (src/ensemble → package root or dist/ensemble → package root)
42
+ return (0, path_1.join)((0, path_1.resolve)(__dirname, '..', '..'), 'examples', 'agents');
43
+ }
44
+ function agentDirs(cwd) {
45
+ return [
46
+ { dir: (0, path_1.join)(cwd || process.cwd(), '.claude', 'agents'), source: 'project', nativeResolvable: true },
47
+ { dir: (0, path_1.join)((0, os_1.homedir)(), '.claude', 'agents'), source: 'user', nativeResolvable: true },
48
+ { dir: shippedAgentsDir(), source: 'shipped', nativeResolvable: false },
49
+ ];
50
+ }
51
+ /**
52
+ * List all available agent types across the three-tier lookup.
53
+ * Deduplicates by name: project > user > shipped.
54
+ */
55
+ function listAgentTypes(cwd) {
56
+ const seen = new Map();
57
+ for (const { dir, source, nativeResolvable } of agentDirs(cwd)) {
58
+ if (!(0, fs_1.existsSync)(dir))
59
+ continue;
60
+ let files;
61
+ try {
62
+ files = (0, fs_1.readdirSync)(dir).filter(f => f.endsWith('.md'));
63
+ }
64
+ catch {
65
+ continue;
66
+ }
67
+ for (const file of files) {
68
+ const filePath = (0, path_1.join)(dir, file);
69
+ const fm = parseFrontmatter(filePath);
70
+ const name = fm.name || file.replace(/\.md$/, '');
71
+ // Higher-priority sources are scanned first — skip if already seen
72
+ if (seen.has(name))
73
+ continue;
74
+ seen.set(name, {
75
+ name,
76
+ description: fm.description,
77
+ source,
78
+ path: filePath,
79
+ nativeResolvable,
80
+ ...(Array.isArray(fm.allowedTools) ? { allowedTools: fm.allowedTools.map(String) } : {}),
81
+ });
82
+ }
83
+ }
84
+ return Array.from(seen.values());
85
+ }
86
+ /**
87
+ * Resolve a single agent type by name across the three-tier lookup.
88
+ * Returns the first match (project > user > shipped) or null.
89
+ */
90
+ function resolveAgentType(name, cwd) {
91
+ for (const { dir, source, nativeResolvable } of agentDirs(cwd)) {
92
+ const filePath = (0, path_1.join)(dir, `${name}.md`);
93
+ if (!(0, fs_1.existsSync)(filePath))
94
+ continue;
95
+ const fm = parseFrontmatter(filePath);
96
+ return {
97
+ name: fm.name || name,
98
+ description: fm.description,
99
+ source,
100
+ path: filePath,
101
+ nativeResolvable,
102
+ ...(Array.isArray(fm.allowedTools) ? { allowedTools: fm.allowedTools.map(String) } : {}),
103
+ };
104
+ }
105
+ return null;
106
+ }
107
+ /**
108
+ * Load and resolve a lineup, validating and resolving `type` fields on each player.
109
+ * Players without `type` pass through unchanged.
110
+ * Throws if a referenced type is not found.
111
+ */
112
+ function loadAndResolveLineup(filePath, cwd) {
113
+ const lineup = (0, loader_1.loadLineup)(filePath);
114
+ for (const player of lineup.players) {
115
+ if (!player.type)
116
+ continue;
117
+ const info = resolveAgentType(player.type, cwd);
118
+ if (!info) {
119
+ const available = listAgentTypes(cwd).map(t => t.name);
120
+ throw new Error(`Unknown agent type "${player.type}" for player "${player.name}". ` +
121
+ `Available types: ${available.length ? available.join(', ') : '(none)'}`);
122
+ }
123
+ player._agentDefinition = info.name;
124
+ player._agentDefinitionPath = info.path;
125
+ // Type's allowedTools is the security authority — overrides lineup-level setting
126
+ // Empty array means "not specified" (no restriction), so don't override
127
+ if (info.allowedTools && info.allowedTools.length > 0) {
128
+ player.allowedTools = info.allowedTools;
129
+ }
130
+ }
131
+ return lineup;
132
+ }
@@ -0,0 +1,14 @@
1
+ import { EnsembleLineup } from './schema';
2
+ export interface LineupResolution {
3
+ path: string;
4
+ source: 'saved' | 'shipped' | 'file';
5
+ }
6
+ /**
7
+ * Resolve a lineup name or file path to an absolute file path.
8
+ * Resolution order: saved lineups → shipped examples → direct file path → error.
9
+ */
10
+ export declare function resolveLineupPath(nameOrPath: string): LineupResolution;
11
+ /**
12
+ * Load and validate an ensemble lineup from a YAML file.
13
+ */
14
+ export declare function loadLineup(filePath: string): EnsembleLineup;
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveLineupPath = resolveLineupPath;
4
+ exports.loadLineup = loadLineup;
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ const yaml_1 = require("yaml");
8
+ const config_1 = require("../config");
9
+ /** Walk up from a directory to find the nearest package.json. */
10
+ function findPackageRoot(dir) {
11
+ if ((0, fs_1.existsSync)((0, path_1.join)(dir, 'package.json')))
12
+ return dir;
13
+ const parent = (0, path_1.resolve)(dir, '..');
14
+ return parent === dir ? dir : findPackageRoot(parent);
15
+ }
16
+ /** Package root — works from both dist/ (production) and dist-test/ (tests). */
17
+ const PACKAGE_ROOT = findPackageRoot((0, path_1.resolve)(__dirname));
18
+ /**
19
+ * Resolve a lineup name or file path to an absolute file path.
20
+ * Resolution order: saved lineups → shipped examples → direct file path → error.
21
+ */
22
+ function resolveLineupPath(nameOrPath) {
23
+ // 1. Saved lineups (~/.agent-tempo/ensembles/)
24
+ const ensemblesDir = (0, path_1.join)(config_1.AGENT_TEMPO_HOME, 'ensembles');
25
+ const savedYaml = (0, path_1.join)(ensemblesDir, `${nameOrPath}.yaml`);
26
+ const savedYml = (0, path_1.join)(ensemblesDir, `${nameOrPath}.yml`);
27
+ if ((0, fs_1.existsSync)(savedYaml))
28
+ return { path: savedYaml, source: 'saved' };
29
+ if ((0, fs_1.existsSync)(savedYml))
30
+ return { path: savedYml, source: 'saved' };
31
+ // 2. Shipped examples (<package-root>/examples/ensembles/)
32
+ const shippedYaml = (0, path_1.join)(PACKAGE_ROOT, 'examples', 'ensembles', `${nameOrPath}.yaml`);
33
+ const shippedYml = (0, path_1.join)(PACKAGE_ROOT, 'examples', 'ensembles', `${nameOrPath}.yml`);
34
+ if ((0, fs_1.existsSync)(shippedYaml))
35
+ return { path: shippedYaml, source: 'shipped' };
36
+ if ((0, fs_1.existsSync)(shippedYml))
37
+ return { path: shippedYml, source: 'shipped' };
38
+ // 3. Direct file path
39
+ const resolved = (0, path_1.resolve)(nameOrPath);
40
+ if ((0, fs_1.existsSync)(resolved))
41
+ return { path: resolved, source: 'file' };
42
+ // 4. Error with suggestions
43
+ const suggestions = [];
44
+ const saved = (0, fs_1.existsSync)(ensemblesDir) ? (0, fs_1.readdirSync)(ensemblesDir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml')).map(f => f.replace(/\.ya?ml$/, '')) : [];
45
+ if (saved.length)
46
+ suggestions.push(`Saved: ${saved.join(', ')}`);
47
+ const shippedDir = (0, path_1.join)(PACKAGE_ROOT, 'examples', 'ensembles');
48
+ if ((0, fs_1.existsSync)(shippedDir)) {
49
+ const shipped = (0, fs_1.readdirSync)(shippedDir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml')).map(f => f.replace(/\.ya?ml$/, ''));
50
+ if (shipped.length)
51
+ suggestions.push(`Shipped: ${shipped.join(', ')}`);
52
+ }
53
+ const msg = `Lineup "${nameOrPath}" not found as saved lineup, shipped example, or file path.`;
54
+ throw new Error(suggestions.length ? `${msg}\n ${suggestions.join('\n ')}` : msg);
55
+ }
56
+ /**
57
+ * Load and validate an ensemble lineup from a YAML file.
58
+ */
59
+ function loadLineup(filePath) {
60
+ const raw = (0, fs_1.readFileSync)(filePath, 'utf8');
61
+ const doc = (0, yaml_1.parse)(raw);
62
+ if (!doc || typeof doc !== 'object') {
63
+ throw new Error(`Invalid lineup: file does not contain a YAML object`);
64
+ }
65
+ // Required: name
66
+ if (typeof doc.name !== 'string' || !doc.name) {
67
+ throw new Error(`Invalid lineup: "name" is required and must be a non-empty string`);
68
+ }
69
+ // Every ensemble must define exactly one conductor — the default chat
70
+ // target and anchor for the maestro's `getEnsembleChat`.
71
+ const remediation = `Add a conductor block with 'name:' (default "conductor") and 'agent:' (default from AGENT_TEMPO_DEFAULT_AGENT config).`;
72
+ if (doc.conductor == null) {
73
+ throw new Error(`lineup "${doc.name}" is missing a conductor; every ensemble must define exactly one conductor. ${remediation}`);
74
+ }
75
+ if (typeof doc.conductor !== 'object' || Array.isArray(doc.conductor)) {
76
+ throw new Error(`lineup "${doc.name}" has a malformed conductor (expected a mapping, got ${Array.isArray(doc.conductor) ? 'array' : typeof doc.conductor}). ${remediation}`);
77
+ }
78
+ // Required: players array
79
+ if (!Array.isArray(doc.players)) {
80
+ throw new Error(`Invalid lineup: "players" must be an array`);
81
+ }
82
+ for (let i = 0; i < doc.players.length; i++) {
83
+ const p = doc.players[i];
84
+ if (typeof p.name !== 'string' || !p.name) {
85
+ throw new Error(`Invalid lineup: players[${i}].name is required`);
86
+ }
87
+ if (!/^[a-zA-Z0-9_-]+$/.test(p.name)) {
88
+ throw new Error(`Invalid lineup: players[${i}].name "${p.name}" contains invalid characters`);
89
+ }
90
+ }
91
+ // Validate schedules if present
92
+ if (doc.schedules != null) {
93
+ if (!Array.isArray(doc.schedules)) {
94
+ throw new Error(`Invalid lineup: "schedules" must be an array`);
95
+ }
96
+ for (let i = 0; i < doc.schedules.length; i++) {
97
+ const s = doc.schedules[i];
98
+ if (typeof s.name !== 'string' || !s.name) {
99
+ throw new Error(`Invalid lineup: schedules[${i}].name is required`);
100
+ }
101
+ if (typeof s.message !== 'string' || !s.message) {
102
+ throw new Error(`Invalid lineup: schedules[${i}].message is required`);
103
+ }
104
+ if (typeof s.target !== 'string' || !s.target) {
105
+ throw new Error(`Invalid lineup: schedules[${i}].target is required`);
106
+ }
107
+ if (!s.at && !s.delay && !s.every && !s.cron) {
108
+ throw new Error(`Invalid lineup: schedules[${i}] must have at least one of: at, delay, every, cron`);
109
+ }
110
+ }
111
+ }
112
+ // Validate conductor name if present
113
+ if (doc.conductor?.name != null) {
114
+ if (typeof doc.conductor.name !== 'string' || !doc.conductor.name) {
115
+ throw new Error(`Invalid lineup: conductor.name must be a non-empty string`);
116
+ }
117
+ if (!/^[a-zA-Z0-9_-]+$/.test(doc.conductor.name)) {
118
+ throw new Error(`Invalid lineup: conductor.name "${doc.conductor.name}" contains invalid characters`);
119
+ }
120
+ }
121
+ return {
122
+ name: doc.name,
123
+ description: doc.description,
124
+ conductor: doc.conductor,
125
+ players: doc.players.map((p) => ({
126
+ name: p.name,
127
+ ...(p.type != null && { type: p.type }),
128
+ ...(p.workDir != null && { workDir: p.workDir }),
129
+ ...(p.agent != null && { agent: p.agent }),
130
+ ...(p.instructions != null && { instructions: p.instructions }),
131
+ ...(Array.isArray(p.allowedTools) && { allowedTools: p.allowedTools.map(String) }),
132
+ // PR-3 mock fields. Pass through verbatim — schema validation is
133
+ // shape-only here; runtime rejection lives in `recruit.ts` (gates the
134
+ // dev-mode `agent: "mock"` requirement) and the spawn layer.
135
+ ...(p.mockMode != null && { mockMode: p.mockMode }),
136
+ ...(p.mockScenario != null && { mockScenario: p.mockScenario }),
137
+ })),
138
+ schedules: doc.schedules,
139
+ };
140
+ }
@@ -0,0 +1,49 @@
1
+ import { Client } from '@temporalio/client';
2
+ /**
3
+ * Save the current live ensemble state to a YAML lineup file.
4
+ * Queries all running sessions and active schedules from Temporal.
5
+ */
6
+ export declare function saveLineup(client: Client, ensemble: string, filePath?: string, name?: string): Promise<string>;
7
+ /**
8
+ * List all saved ensemble lineups in ~/.agent-tempo/ensembles/.
9
+ */
10
+ export declare function listLineups(): Array<{
11
+ name: string;
12
+ path: string;
13
+ }>;
14
+ /**
15
+ * Read a saved lineup by name from ~/.agent-tempo/ensembles/.
16
+ */
17
+ export declare function readSavedLineup(name: string): string | null;
18
+ /**
19
+ * Lineup catalog entry — each row in `listAllLineups()` output. Used by
20
+ * the TUI's CreateEnsembleWizard, the dashboard's `/v1/lineups`
21
+ * endpoint, and the `agent-tempo up --lineup` resolver.
22
+ *
23
+ * `players` and `description` come from a YAML parse — best-effort: a
24
+ * malformed lineup file silently degrades to `players: 0` /
25
+ * `description: undefined` rather than skipping the row entirely. The
26
+ * row stays clickable so the picker can still surface it; downstream
27
+ * `loadLineup()` runs strict validation at use time.
28
+ *
29
+ * `path` is the absolute on-disk path. Local callers use it to seed
30
+ * the resolver; HTTP catchments must NOT serve this field over the
31
+ * wire (privacy contract — strip in the route handler).
32
+ */
33
+ export interface LineupCatalogEntry {
34
+ name: string;
35
+ description?: string;
36
+ players: number;
37
+ source: 'saved' | 'shipped';
38
+ path: string;
39
+ }
40
+ /**
41
+ * List all available lineups — saved (`~/.agent-tempo/ensembles/`)
42
+ * plus shipped (`<package-root>/examples/ensembles/`). Saved takes
43
+ * precedence over shipped when names collide.
44
+ *
45
+ * Each row carries `description` + `players` count so pickers can
46
+ * render rich rows without re-parsing the YAML themselves. Parse
47
+ * failures are tolerated (zero count, no description).
48
+ */
49
+ export declare function listAllLineups(): LineupCatalogEntry[];
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.saveLineup = saveLineup;
4
+ exports.listLineups = listLineups;
5
+ exports.readSavedLineup = readSavedLineup;
6
+ exports.listAllLineups = listAllLineups;
7
+ const fs_1 = require("fs");
8
+ const path_1 = require("path");
9
+ const yaml_1 = require("yaml");
10
+ const config_1 = require("../config");
11
+ const loader_1 = require("./loader");
12
+ const ENSEMBLES_DIR = (0, path_1.join)(config_1.AGENT_TEMPO_HOME, 'ensembles');
13
+ function ensemblesDir() {
14
+ (0, fs_1.mkdirSync)(ENSEMBLES_DIR, { recursive: true });
15
+ return ENSEMBLES_DIR;
16
+ }
17
+ /**
18
+ * Save the current live ensemble state to a YAML lineup file.
19
+ * Queries all running sessions and active schedules from Temporal.
20
+ */
21
+ async function saveLineup(client, ensemble, filePath, name) {
22
+ const outputPath = filePath || (0, path_1.join)(ensemblesDir(), `${name || ensemble}.yaml`);
23
+ // Query all running session workflows
24
+ const query = 'WorkflowType = "agentSessionWorkflow" AND ExecutionStatus = "Running"';
25
+ const players = [];
26
+ let conductor;
27
+ for await (const wf of client.workflow.list({ query })) {
28
+ try {
29
+ const handle = client.workflow.getHandle(wf.workflowId);
30
+ const [metadata, part] = await Promise.all([
31
+ handle.query('getMetadata').catch(() => ({})),
32
+ handle.query('getPart').catch(() => ''),
33
+ ]);
34
+ const meta = metadata;
35
+ if (meta.ensemble !== ensemble)
36
+ continue;
37
+ const isConductor = meta.isConductor || false;
38
+ const agentType = meta.agentType || 'claude';
39
+ const workDir = meta.workDir || undefined;
40
+ if (isConductor) {
41
+ const conductorName = meta.playerId || undefined;
42
+ conductor = {
43
+ // Only save name if it's not the default 'conductor'
44
+ ...(conductorName && conductorName !== 'conductor' ? { name: conductorName } : {}),
45
+ agent: agentType === 'copilot' ? 'copilot' : undefined,
46
+ };
47
+ }
48
+ else {
49
+ const name = meta.playerId || wf.workflowId.split('-').pop() || 'unknown';
50
+ const playerType = meta.playerType || undefined;
51
+ players.push({
52
+ name,
53
+ type: playerType,
54
+ workDir,
55
+ agent: agentType === 'copilot' ? 'copilot' : undefined,
56
+ });
57
+ }
58
+ }
59
+ catch {
60
+ // workflow may have closed between list and query
61
+ }
62
+ }
63
+ // Query active schedules
64
+ const schedules = [];
65
+ try {
66
+ const schedulerWfId = (0, config_1.schedulerWorkflowId)(ensemble);
67
+ const handle = client.workflow.getHandle(schedulerWfId);
68
+ const entries = await handle.query('getSchedules');
69
+ for (const entry of entries) {
70
+ const sched = {
71
+ name: entry.name,
72
+ message: entry.message,
73
+ target: entry.target,
74
+ };
75
+ if (entry.cronExpression) {
76
+ sched.cron = entry.cronExpression;
77
+ if (entry.timezone)
78
+ sched.timezone = entry.timezone;
79
+ }
80
+ else if (entry.interval) {
81
+ sched.every = formatDurationMs(entry.interval);
82
+ }
83
+ if (entry.until) {
84
+ sched.until = entry.until;
85
+ }
86
+ if (entry.remainingCount != null) {
87
+ sched.count = entry.remainingCount;
88
+ }
89
+ schedules.push(sched);
90
+ }
91
+ }
92
+ catch {
93
+ // No scheduler running or no schedules
94
+ }
95
+ // An empty `{}` satisfies the schema when no conductor session is live;
96
+ // downstream consumers apply the field-level defaults.
97
+ const lineup = {
98
+ name: ensemble,
99
+ conductor: conductor ?? {},
100
+ players,
101
+ ...(schedules.length > 0 ? { schedules } : {}),
102
+ };
103
+ // Ensure parent directory exists
104
+ const parentDir = outputPath.substring(0, outputPath.lastIndexOf('/') >= 0 ? outputPath.lastIndexOf('/') : outputPath.lastIndexOf('\\'));
105
+ if (parentDir)
106
+ (0, fs_1.mkdirSync)(parentDir, { recursive: true });
107
+ (0, fs_1.writeFileSync)(outputPath, (0, yaml_1.stringify)(lineup));
108
+ return outputPath;
109
+ }
110
+ /**
111
+ * List all saved ensemble lineups in ~/.agent-tempo/ensembles/.
112
+ */
113
+ function listLineups() {
114
+ const dir = ensemblesDir();
115
+ if (!(0, fs_1.existsSync)(dir))
116
+ return [];
117
+ return (0, fs_1.readdirSync)(dir)
118
+ .filter(f => f.endsWith('.yaml') || f.endsWith('.yml'))
119
+ .map(f => ({
120
+ name: f.replace(/\.ya?ml$/, ''),
121
+ path: (0, path_1.join)(dir, f),
122
+ }));
123
+ }
124
+ /**
125
+ * Read a saved lineup by name from ~/.agent-tempo/ensembles/.
126
+ */
127
+ function readSavedLineup(name) {
128
+ const dir = ensemblesDir();
129
+ for (const ext of ['.yaml', '.yml']) {
130
+ const path = (0, path_1.join)(dir, name + ext);
131
+ if ((0, fs_1.existsSync)(path))
132
+ return (0, fs_1.readFileSync)(path, 'utf8');
133
+ }
134
+ return null;
135
+ }
136
+ /**
137
+ * Find the package root by walking up from a directory.
138
+ */
139
+ function findPackageRoot(dir) {
140
+ if ((0, fs_1.existsSync)((0, path_1.join)(dir, 'package.json')))
141
+ return dir;
142
+ const parent = (0, path_1.resolve)(dir, '..');
143
+ return parent === dir ? dir : findPackageRoot(parent);
144
+ }
145
+ /**
146
+ * List all available lineups — saved (`~/.agent-tempo/ensembles/`)
147
+ * plus shipped (`<package-root>/examples/ensembles/`). Saved takes
148
+ * precedence over shipped when names collide.
149
+ *
150
+ * Each row carries `description` + `players` count so pickers can
151
+ * render rich rows without re-parsing the YAML themselves. Parse
152
+ * failures are tolerated (zero count, no description).
153
+ */
154
+ function listAllLineups() {
155
+ const seen = new Map();
156
+ const append = (name, path, source) => {
157
+ if (seen.has(name))
158
+ return;
159
+ let description;
160
+ let players = 0;
161
+ try {
162
+ const lineup = (0, loader_1.loadLineup)(path);
163
+ description = lineup.description;
164
+ players = lineup.players.length;
165
+ }
166
+ catch {
167
+ // Malformed YAML — keep the row but with zero count.
168
+ }
169
+ seen.set(name, {
170
+ name,
171
+ ...(description !== undefined && { description }),
172
+ players,
173
+ source,
174
+ path,
175
+ });
176
+ };
177
+ // Saved (higher priority).
178
+ for (const l of listLineups())
179
+ append(l.name, l.path, 'saved');
180
+ // Shipped fallback.
181
+ const pkgRoot = findPackageRoot((0, path_1.resolve)(__dirname));
182
+ const shippedDir = (0, path_1.join)(pkgRoot, 'examples', 'ensembles');
183
+ if ((0, fs_1.existsSync)(shippedDir)) {
184
+ for (const f of (0, fs_1.readdirSync)(shippedDir)) {
185
+ if (!f.endsWith('.yaml') && !f.endsWith('.yml'))
186
+ continue;
187
+ const name = f.replace(/\.ya?ml$/, '');
188
+ append(name, (0, path_1.join)(shippedDir, f), 'shipped');
189
+ }
190
+ }
191
+ return Array.from(seen.values());
192
+ }
193
+ function formatDurationMs(ms) {
194
+ if (ms >= 86_400_000 && ms % 86_400_000 === 0)
195
+ return `${ms / 86_400_000}d`;
196
+ if (ms >= 3_600_000 && ms % 3_600_000 === 0)
197
+ return `${ms / 3_600_000}h`;
198
+ if (ms >= 60_000 && ms % 60_000 === 0)
199
+ return `${ms / 60_000}m`;
200
+ return `${ms / 1000}s`;
201
+ }
@@ -0,0 +1,71 @@
1
+ import type { MockMode } from '../types';
2
+ export interface EnsembleLineup {
3
+ name: string;
4
+ description?: string;
5
+ /**
6
+ * Every ensemble defines exactly one conductor — the default chat target,
7
+ * the home for system messages, and the anchor for `getEnsembleChat`.
8
+ * Inner fields remain optional: unset `name` defaults to `"conductor"` and
9
+ * unset `agent` falls back to `AGENT_TEMPO_DEFAULT_AGENT`.
10
+ */
11
+ conductor: {
12
+ name?: string;
13
+ type?: string;
14
+ /** "default", "copilot", "mock" (dev mode only), or path to agent .md file. */
15
+ agent?: string;
16
+ instructions?: string;
17
+ /**
18
+ * Mock-adapter mode — only consulted when `agent: "mock"`. Mirrors the
19
+ * same field on players. Defaults to `echo` when omitted.
20
+ */
21
+ mockMode?: MockMode;
22
+ /**
23
+ * Scenario reference for `agent: "mock"` + `mockMode: "scripted"`.
24
+ * Bare name (resolved against shipped `scenarios/`), absolute path,
25
+ * or relative path.
26
+ */
27
+ mockScenario?: string;
28
+ };
29
+ players: Array<{
30
+ name: string;
31
+ type?: string;
32
+ workDir?: string;
33
+ /**
34
+ * "default", "copilot", path to agent .md file, or "mock" (dev-mode
35
+ * only — ADR 0014 §4 / PR-2). Mock players are headless subprocesses
36
+ * with no terminal window, suitable for autonomous validation
37
+ * harnesses (e.g. the `tempo-mock-jam` lineup).
38
+ */
39
+ agent?: string;
40
+ instructions?: string;
41
+ allowedTools?: string[];
42
+ /**
43
+ * Mock-adapter mode (only consulted when `agent: "mock"`). One of
44
+ * `echo` / `scripted` / `silent` / `chaos`. ADR 0014 §4.2. Defaults
45
+ * to `echo` when omitted. PR-3 added `silent` + `chaos`.
46
+ */
47
+ mockMode?: MockMode;
48
+ /**
49
+ * Scenario reference for `agent: "mock"` + `mockMode: "scripted"` —
50
+ * bare name (resolved against shipped `scenarios/`), absolute path,
51
+ * or relative path. CLI `--scenario` flag overrides this when set.
52
+ */
53
+ mockScenario?: string;
54
+ /** Transient: resolved agent definition name (set by loadAndResolveLineup). */
55
+ _agentDefinition?: string;
56
+ /** Transient: resolved absolute path to .md file (set by loadAndResolveLineup). */
57
+ _agentDefinitionPath?: string;
58
+ }>;
59
+ schedules?: Array<{
60
+ name: string;
61
+ message: string;
62
+ target: string;
63
+ at?: string;
64
+ delay?: string;
65
+ every?: string;
66
+ cron?: string;
67
+ timezone?: string;
68
+ until?: string;
69
+ count?: number;
70
+ }>;
71
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // Ensemble lineup types — defines the structure of a saved/loaded ensemble configuration.
3
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export declare function getGitInfo(workDir: string): {
2
+ gitRoot?: string;
3
+ gitBranch?: string;
4
+ };
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getGitInfo = getGitInfo;
4
+ const child_process_1 = require("child_process");
5
+ function getGitInfo(workDir) {
6
+ try {
7
+ const gitRoot = (0, child_process_1.execSync)('git rev-parse --show-toplevel', {
8
+ cwd: workDir,
9
+ encoding: 'utf-8',
10
+ stdio: ['pipe', 'pipe', 'pipe'],
11
+ windowsHide: true,
12
+ }).trim();
13
+ let gitBranch;
14
+ try {
15
+ gitBranch = (0, child_process_1.execSync)('git rev-parse --abbrev-ref HEAD', {
16
+ cwd: workDir,
17
+ encoding: 'utf-8',
18
+ stdio: ['pipe', 'pipe', 'pipe'],
19
+ }).trim();
20
+ }
21
+ catch {
22
+ // not on a branch
23
+ }
24
+ return { gitRoot, gitBranch };
25
+ }
26
+ catch {
27
+ return {};
28
+ }
29
+ }