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,348 @@
1
+ /**
2
+ * SSE event-source wire types — shared by the daemon (server, PR-1/PR-2) and
3
+ * the TempoClient subscribe wrapper (PR-3). The drift detector at
4
+ * `test/sse/wire-protocol.test.ts` (PR-2 deliverable) cross-checks
5
+ * `SSE_EVENT_KINDS` against the §6 table in `docs/SSE-PROTOCOL.md`.
6
+ *
7
+ * **Reference**: [`docs/SSE-PROTOCOL.md`](../../docs/SSE-PROTOCOL.md).
8
+ *
9
+ * **Stability**: every name and field shape here is part of the v1 wire
10
+ * contract. Renaming or removing requires a major version bump (path prefix
11
+ * `/v1/` → `/v2/`). Adding new event types or additive payload fields is
12
+ * non-breaking.
13
+ *
14
+ * **PR-1 scope**: the snapshot endpoints (`/v1/health`, `/v1/state/:ensemble`,
15
+ * `/v1/ensembles`, `/v1/hosts`) consume `HealthV1`, `EnsembleStateV1`, and
16
+ * `PlayerSummaryV1`. The SSE event union and `TempoClient.subscribe`
17
+ * interface are defined here for PR-2/PR-3 to import without duplication.
18
+ */
19
+ import type { AttachmentPhase, EnsembleChatMessage, HostProfile, HostInfo, ScheduleEntry } from '../types';
20
+ import type { EnsembleSummary } from '../client/interface';
21
+ /** §4.1 — `/v1/health` — never authenticated. */
22
+ export interface HealthV1 {
23
+ ok: true;
24
+ /** Temporal namespace the daemon is connected to. */
25
+ namespace: string;
26
+ /**
27
+ * Shared task queue the daemon's workers poll. Mirrors `config.taskQueue`
28
+ * (e.g. `agent-tempo` in production, `agent-tempo-dev` in dev mode).
29
+ * Surfaced for the dashboard's Settings → Connection panel so the displayed
30
+ * value reflects the live runtime instead of a hard-coded default. (#444)
31
+ */
32
+ taskQueue: string;
33
+ /** Daemon package version. */
34
+ version: string;
35
+ uptimeMs: number;
36
+ /** Count of distinct ensembles known to the daemon at request time. */
37
+ ensembleCount: number;
38
+ /**
39
+ * Open SSE connections (`/v1/events*`). Always `0` in PR-1 — the daemon
40
+ * has no streaming endpoints yet. PR-2 wires this to the live subscriber set.
41
+ */
42
+ subscriberCount: number;
43
+ /**
44
+ * #336 memory diagnostics — exposes `process.memoryUsage()` at request
45
+ * time so external monitors and `agent-tempo daemon stats` can spot
46
+ * leaks without attaching a debugger. Bytes; see Node docs for field
47
+ * semantics. Optional so legacy clients ignoring the field don't break.
48
+ */
49
+ memory?: MemoryUsageV1;
50
+ }
51
+ /** Snapshot of `process.memoryUsage()` at request time. All values in bytes. */
52
+ export interface MemoryUsageV1 {
53
+ /** Resident Set Size — the total memory the OS has allocated for the process. */
54
+ rss: number;
55
+ /** V8 heap total. */
56
+ heapTotal: number;
57
+ /** V8 heap used. */
58
+ heapUsed: number;
59
+ /** Memory used by native C++ objects bound to JS (e.g. Temporal SDK). */
60
+ external: number;
61
+ /** Memory allocated for ArrayBuffers + SharedArrayBuffers. */
62
+ arrayBuffers: number;
63
+ }
64
+ /**
65
+ * §4.3 — `/v1/state/:ensemble` — single-ensemble snapshot.
66
+ *
67
+ * `lastEventId` is the snapshot/stream bridge token. PR-1 returns the
68
+ * sentinel `"0:0"`; PR-2 pairs this with the live aggregate so consumers
69
+ * passing it back as `Last-Event-ID` to `/v1/events/:ensemble` resume from
70
+ * the exact tick the snapshot reflects.
71
+ */
72
+ export interface EnsembleStateV1 {
73
+ v: 1;
74
+ ensemble: string;
75
+ /** ISO timestamp recorded when the snapshot was assembled. */
76
+ capturedAt: string;
77
+ /**
78
+ * Opaque event-id token of the form `"<bootEpoch>:<seq>"` (see §5).
79
+ *
80
+ * **Atomicity contract**: the snapshot reflects state as of this id.
81
+ * Every event with a `(bootEpoch, seq)` lexicographically greater than
82
+ * `lastEventId` is NOT yet reflected in `players`, `chat`, `schedules`,
83
+ * `flags`, or `hostProfiles`.
84
+ *
85
+ * **PR-1 sentinel**: the snapshot endpoints ship before any event source
86
+ * exists, so PR-1 returns `"0:0"`. PR-2 subscribers passing this back
87
+ * see an `epoch-mismatch` `gap` event and re-fetch — correct behavior.
88
+ */
89
+ lastEventId: string;
90
+ state: 'online' | 'paused' | 'offline';
91
+ hasConductor: boolean;
92
+ flags: {
93
+ paused: boolean;
94
+ held: boolean;
95
+ };
96
+ players: PlayerSummaryV1[];
97
+ schedules: ScheduleEntry[];
98
+ /**
99
+ * Bounded slice of the maestro hub's chat ring (most-recent-first per
100
+ * the hub's `maestroEnsembleChat` query). Consumers paging older
101
+ * messages drop down to `recall` / `getEnsembleChat` direct.
102
+ */
103
+ chat: {
104
+ messages: EnsembleChatMessage[];
105
+ total: number;
106
+ hasMore: boolean;
107
+ };
108
+ /**
109
+ * Snapshot of the global hostname → `HostProfile` map. Embedded so a
110
+ * consumer rendering one ensemble doesn't need a parallel `/v1/hosts`
111
+ * call to label players by host capabilities. Same shape as the global
112
+ * map; daemons do not partition by ensemble.
113
+ */
114
+ hostProfiles: Record<string, HostProfile>;
115
+ /**
116
+ * Issue #399 W1 wire extensions — projected from the per-ensemble maestro
117
+ * hub's `getEnsembleDescriptionQuery` / `getEnsembleStartTimeQuery` /
118
+ * `getCurrentBpmQuery` / `getTempoSeriesQuery`. Consumers (Hosts/Workspace
119
+ * dashboard) render these without further round-trips.
120
+ */
121
+ /** Free-form description of what the ensemble is working on. `''` when the
122
+ * conductor hasn't set one. */
123
+ description: string;
124
+ /** ISO timestamp of when the maestro hub workflow first started. Used by
125
+ * the dashboard to compute uptime client-side. `''` when the hub isn't
126
+ * reachable. */
127
+ startedAt: string;
128
+ /** Current beats-per-minute (msgs/min activity rate). `0` baseline when
129
+ * activity hasn't accrued yet or the hub is unreachable. */
130
+ currentBpm: number;
131
+ /** 60-element ring of recent activity counts (one per minute, most recent
132
+ * last). Powers the `<TempoStrip>` sparkline. Empty array when the hub
133
+ * isn't reachable. */
134
+ tempoSeries: number[];
135
+ }
136
+ /**
137
+ * §4.3 — per-player projection used inside `EnsembleStateV1.players` and
138
+ * the `player.added` event payload (§6).
139
+ */
140
+ export interface PlayerSummaryV1 {
141
+ playerId: string;
142
+ ensemble: string;
143
+ hostname: string;
144
+ isConductor: boolean;
145
+ /**
146
+ * Adapter family the player runs on. Mirrors {@link AgentType} from
147
+ * `src/types.ts` — every shipped adapter is exposed verbatim so dashboards
148
+ * can render the actual backend instead of coercing headless adapters into
149
+ * `'claude'`. `'mock'` is dev-mode-only (recruit gate rejects it in
150
+ * production); the headless adapters (`'claude-api'`, `'opencode'`,
151
+ * `'claude-code-headless'`) ship as additive `/v1/` extensions per the
152
+ * stability rule at §6 — adding new adapters in future versions remains
153
+ * non-breaking, removing one requires `/v2/`. See #535.
154
+ */
155
+ agentType: 'claude' | 'copilot' | 'mock' | 'claude-api' | 'opencode' | 'claude-code-headless';
156
+ playerType?: string;
157
+ /** Authoritative attachment phase (post-v0.26 — see WIRE-PROTOCOL.md). */
158
+ phase?: AttachmentPhase;
159
+ part: string;
160
+ workDir: string;
161
+ gitBranch?: string;
162
+ /** Absent on `detached` / `gone` phases. ISO timestamp. */
163
+ lastHeartbeatAt?: string;
164
+ /** Present only when `phase === 'processing'`. ISO timestamp. */
165
+ processingSince?: string;
166
+ /**
167
+ * Issue #399 W2 wire extensions — projected from per-session queries
168
+ * (`getRunIdQuery` / `getMessagingStateQuery` / `getLeaseStateQuery`)
169
+ * during snapshot fan-out. Optional everywhere — when the session
170
+ * workflow is unreachable or a query soft-fails the field is absent
171
+ * (or set to a sentinel for objects), and the dashboard renders `—`.
172
+ */
173
+ /** Q5.2 — current execution's runId. UUID; dashboard truncates client-side. */
174
+ runId?: string;
175
+ /** Q5.5 — messaging counters + outbox status string. */
176
+ messaging?: {
177
+ received: number;
178
+ sent: number;
179
+ /** `'empty'` / `'N pending'` / `'N pending (oldest 2m)'`. Server-rendered. */
180
+ outbox: string;
181
+ };
182
+ /** Q5.7 — current attachment lease window. `null` when no active lease
183
+ * (phase ∈ booting / detached / gone). */
184
+ lease?: {
185
+ /** Epoch ms when the lease expires, or `null` when no active lease. */
186
+ expiresAt: number | null;
187
+ /** Lease window length in ms, or `null` when no active lease. */
188
+ leaseMs: number | null;
189
+ };
190
+ /** Q5.6 — monotonic activity counter (cue + outbox push + report + recruit
191
+ * + restart + destroy + migrate). Already on `MaestroPlayerInfo`; passed
192
+ * through verbatim by `toPlayerSummaryV1`. */
193
+ activityCount?: number;
194
+ /** Q5.6 — ISO timestamp of the most recent activity. Already on
195
+ * `MaestroPlayerInfo`; passed through verbatim by `toPlayerSummaryV1`. */
196
+ lastActivityAt?: string;
197
+ }
198
+ /**
199
+ * The eventId token used in the `id:` line of the SSE frame and as the
200
+ * `Last-Event-ID` header round-trip. Format `"<bootEpoch>:<seq>"`:
201
+ *
202
+ * - `bootEpoch` — daemon process boot time as Unix epoch milliseconds,
203
+ * frozen for the process lifetime. A daemon restart advances the epoch;
204
+ * a worker restart (e.g. Temporal connection reset) does NOT.
205
+ * - `seq` — uint64 monotonic counter starting at 0, incrementing once per
206
+ * event emitted to the bus.
207
+ *
208
+ * Comparison rule: server compares the client-supplied `Last-Event-ID` to
209
+ * the live `(bootEpoch, seq)` pair as a numeric tuple — `clientEpoch`
210
+ * first, then `clientSeq`. Mismatched epoch → `gap` event with reason
211
+ * `epoch-mismatch`. Matched epoch with `seq < ringStart` → `gap` with
212
+ * reason `overflow`.
213
+ */
214
+ export type EventIdToken = string;
215
+ /**
216
+ * The PR-1 sentinel `lastEventId` value — emitted on `/v1/state/:ensemble`
217
+ * before PR-2 lights up the aggregate poll loop. Subscribers passing this
218
+ * back as `Last-Event-ID` once PR-2 ships will see an `epoch-mismatch`
219
+ * gap event (because the live daemon's `bootEpoch` is non-zero) and
220
+ * re-fetch — correct behavior.
221
+ */
222
+ export declare const PR1_SENTINEL_EVENT_ID: EventIdToken;
223
+ /**
224
+ * Canonical list of every SSE event `type` the daemon emits. The drift
225
+ * detector (PR-2) reads this array and asserts every `## row` in
226
+ * `docs/SSE-PROTOCOL.md` §6 has a matching entry — and vice versa.
227
+ *
228
+ * **Append-only**. Do not remove. New event types ship as additive `/v1/`
229
+ * additions; removals require `/v2/`.
230
+ */
231
+ export declare const SSE_EVENT_KINDS: readonly ["snapshot", "gap", "throttled", "heartbeat", "ensemble.created", "ensemble.destroyed", "player.added", "player.removed", "player.phase_changed", "chat.appended", "chat.compressed", "flags.changed", "schedules.changed", "host_profile.changed"];
232
+ export type SseEventKind = (typeof SSE_EVENT_KINDS)[number];
233
+ /** Common envelope for every event. */
234
+ export interface SseEventBase {
235
+ v: 1;
236
+ /** §5 — `"<bootEpoch>:<seq>"`. */
237
+ eventId: EventIdToken;
238
+ }
239
+ /**
240
+ * Discriminated union of every event payload exposed by the daemon's
241
+ * `/v1/events*` endpoints. PR-3's `TempoClient.subscribe` returns
242
+ * `AsyncIterable<TempoEvent>`.
243
+ */
244
+ export type TempoEvent = (SseEventBase & {
245
+ type: 'snapshot';
246
+ payload: EnsembleStateV1;
247
+ }) | (SseEventBase & {
248
+ type: 'gap';
249
+ payload: {
250
+ from: string;
251
+ to: string;
252
+ reason: 'epoch-mismatch' | 'overflow';
253
+ };
254
+ }) | (SseEventBase & {
255
+ type: 'throttled';
256
+ payload: {
257
+ droppedSince: string;
258
+ count: number;
259
+ };
260
+ }) | (SseEventBase & {
261
+ type: 'heartbeat';
262
+ payload: {
263
+ at: string;
264
+ };
265
+ }) | (SseEventBase & {
266
+ type: 'ensemble.created';
267
+ payload: {
268
+ ensemble: string;
269
+ createdAt: string;
270
+ hasConductor: boolean;
271
+ };
272
+ }) | (SseEventBase & {
273
+ type: 'ensemble.destroyed';
274
+ payload: {
275
+ ensemble: string;
276
+ destroyedAt: string;
277
+ };
278
+ }) | (SseEventBase & {
279
+ type: 'player.added';
280
+ payload: PlayerSummaryV1;
281
+ }) | (SseEventBase & {
282
+ type: 'player.removed';
283
+ payload: {
284
+ playerId: string;
285
+ ensemble: string;
286
+ removedAt: string;
287
+ reason: 'destroyed' | 'gone';
288
+ };
289
+ }) | (SseEventBase & {
290
+ type: 'player.phase_changed';
291
+ payload: {
292
+ playerId: string;
293
+ ensemble: string;
294
+ phase: AttachmentPhase;
295
+ lastHeartbeatAt?: string;
296
+ processingSince?: string;
297
+ at: string;
298
+ };
299
+ }) | (SseEventBase & {
300
+ type: 'chat.appended';
301
+ payload: EnsembleChatMessage;
302
+ }) | (SseEventBase & {
303
+ type: 'chat.compressed';
304
+ payload: {
305
+ dropped: number;
306
+ since: string;
307
+ };
308
+ }) | (SseEventBase & {
309
+ type: 'flags.changed';
310
+ payload: {
311
+ ensemble: string;
312
+ paused: boolean;
313
+ held: boolean;
314
+ at: string;
315
+ };
316
+ }) | (SseEventBase & {
317
+ type: 'schedules.changed';
318
+ payload: {
319
+ ensemble: string;
320
+ schedules: ScheduleEntry[];
321
+ at: string;
322
+ };
323
+ }) | (SseEventBase & {
324
+ type: 'host_profile.changed';
325
+ payload: HostProfile;
326
+ });
327
+ /**
328
+ * Subset of event categories the server can pre-filter on `?topics=...`.
329
+ * Maps roughly to `phase → player.phase_changed`, `chat → chat.*`,
330
+ * `flags → flags.changed`, `schedules → schedules.changed`,
331
+ * `heartbeat → heartbeat`. Setup events (`snapshot`, `gap`, `throttled`,
332
+ * `player.added`, `player.removed`, ensemble lifecycle, `host_profile.*`)
333
+ * are always included — they're the bare minimum for correctness.
334
+ */
335
+ export type SubscribeTopic = 'phase' | 'chat' | 'flags' | 'schedules' | 'heartbeat';
336
+ export interface SubscribeOptions {
337
+ /**
338
+ * Aborts the iterator and tears down the underlying transport. See
339
+ * SSE-PROTOCOL.md §7.4.
340
+ */
341
+ signal?: AbortSignal;
342
+ /**
343
+ * Server-side topic filter. Server drops other event kinds before they
344
+ * hit the wire. Setup/correctness events are always emitted regardless.
345
+ */
346
+ topics?: SubscribeTopic[];
347
+ }
348
+ export type { EnsembleSummary, HostInfo, AttachmentPhase, HostProfile, EnsembleChatMessage, ScheduleEntry };
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SSE_EVENT_KINDS = exports.PR1_SENTINEL_EVENT_ID = void 0;
4
+ /**
5
+ * The PR-1 sentinel `lastEventId` value — emitted on `/v1/state/:ensemble`
6
+ * before PR-2 lights up the aggregate poll loop. Subscribers passing this
7
+ * back as `Last-Event-ID` once PR-2 ships will see an `epoch-mismatch`
8
+ * gap event (because the live daemon's `bootEpoch` is non-zero) and
9
+ * re-fetch — correct behavior.
10
+ */
11
+ exports.PR1_SENTINEL_EVENT_ID = '0:0';
12
+ // ── §6. Event types — drift-detector contract ────────────────────────────
13
+ /**
14
+ * Canonical list of every SSE event `type` the daemon emits. The drift
15
+ * detector (PR-2) reads this array and asserts every `## row` in
16
+ * `docs/SSE-PROTOCOL.md` §6 has a matching entry — and vice versa.
17
+ *
18
+ * **Append-only**. Do not remove. New event types ship as additive `/v1/`
19
+ * additions; removals require `/v2/`.
20
+ */
21
+ exports.SSE_EVENT_KINDS = [
22
+ 'snapshot',
23
+ 'gap',
24
+ 'throttled',
25
+ 'heartbeat',
26
+ 'ensemble.created',
27
+ 'ensemble.destroyed',
28
+ 'player.added',
29
+ 'player.removed',
30
+ 'player.phase_changed',
31
+ 'chat.appended',
32
+ 'chat.compressed',
33
+ 'flags.changed',
34
+ 'schedules.changed',
35
+ 'host_profile.changed',
36
+ ];
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Fixture: 100 `chat.appended` events in rapid succession followed by
3
+ * a `chat.compressed` event. Exercises the dashboard's chat-window
4
+ * virtualisation / scroll behaviour and the "older messages dropped"
5
+ * banner the maestro hub emits when its in-memory ring overflows.
6
+ */
7
+ import type { FixtureScenario } from './index';
8
+ export declare const chatStress: FixtureScenario;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.chatStress = void 0;
4
+ const constants_1 = require("./constants");
5
+ const ENSEMBLE = 'demo-chat-stress';
6
+ const STRESS_COUNT = 100;
7
+ const COMPRESS_DROP = 50;
8
+ const BASE_MS = Number(constants_1.FIXTURE_BOOT_EPOCH);
9
+ const stressEvents = Array.from({ length: STRESS_COUNT }, (_, i) => ({
10
+ v: 1,
11
+ type: 'chat.appended',
12
+ eventId: `${constants_1.FIXTURE_BOOT_EPOCH}:${i + 1}`,
13
+ payload: {
14
+ id: `msg-stress-${i + 1}`,
15
+ from: i % 2 === 0 ? 'maestro' : 'conductor',
16
+ to: i % 2 === 0 ? 'conductor' : 'maestro',
17
+ text: `Stress message ${i + 1}/${STRESS_COUNT}`,
18
+ timestamp: new Date(BASE_MS + i * 10).toISOString(),
19
+ role: i % 2 === 0 ? 'maestro-out' : 'conductor-in',
20
+ },
21
+ }));
22
+ const compressedEvent = {
23
+ v: 1,
24
+ type: 'chat.compressed',
25
+ eventId: `${constants_1.FIXTURE_BOOT_EPOCH}:${STRESS_COUNT + 1}`,
26
+ payload: {
27
+ dropped: COMPRESS_DROP,
28
+ since: new Date(BASE_MS).toISOString(),
29
+ },
30
+ };
31
+ exports.chatStress = {
32
+ name: 'chat-stress',
33
+ description: `${STRESS_COUNT} chat.appended in rapid succession, then chat.compressed (${COMPRESS_DROP} dropped). Tests dashboard chat virtualisation + ring-overflow banner.`,
34
+ snapshot: {
35
+ v: 1,
36
+ ensemble: ENSEMBLE,
37
+ capturedAt: '2026-04-27T00:00:00.000Z',
38
+ lastEventId: `${constants_1.FIXTURE_BOOT_EPOCH}:0`,
39
+ state: 'online',
40
+ hasConductor: true,
41
+ flags: { paused: false, held: false },
42
+ players: [{
43
+ playerId: 'conductor',
44
+ ensemble: ENSEMBLE,
45
+ hostname: 'demo-host',
46
+ isConductor: true,
47
+ agentType: 'claude',
48
+ phase: 'attached',
49
+ part: 'Chat stress demo',
50
+ workDir: '/repo/demo',
51
+ }],
52
+ schedules: [],
53
+ chat: { messages: [], total: 0, hasMore: false },
54
+ hostProfiles: {},
55
+ description: '',
56
+ startedAt: '',
57
+ currentBpm: 0,
58
+ tempoSeries: [],
59
+ },
60
+ events: [...stressEvents, compressedEvent],
61
+ // Tight cadence to actually stress the consumer; not zero so timing is observable.
62
+ eventCadenceMs: 5,
63
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Fixture: an ensemble with a conductor + one soloist; the conductor
3
+ * detaches mid-stream. Exercises the dashboard's "conductor left" UI
4
+ * (#358 analog) — the ensemble continues to exist, but `hasConductor`
5
+ * flips to false after the `player.removed` event lands.
6
+ */
7
+ import type { FixtureScenario } from './index';
8
+ export declare const conductorLeaving: FixtureScenario;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.conductorLeaving = void 0;
4
+ const constants_1 = require("./constants");
5
+ const ENSEMBLE = 'demo-conductor-leaving';
6
+ exports.conductorLeaving = {
7
+ name: 'conductor-leaving',
8
+ description: 'Conductor + 1 soloist; conductor leaves mid-stream (player.phase_changed → player.removed).',
9
+ snapshot: {
10
+ v: 1,
11
+ ensemble: ENSEMBLE,
12
+ capturedAt: '2026-04-27T00:00:00.000Z',
13
+ lastEventId: `${constants_1.FIXTURE_BOOT_EPOCH}:0`,
14
+ state: 'online',
15
+ hasConductor: true,
16
+ flags: { paused: false, held: false },
17
+ players: [
18
+ {
19
+ playerId: 'conductor',
20
+ ensemble: ENSEMBLE,
21
+ hostname: 'demo-host',
22
+ isConductor: true,
23
+ agentType: 'claude',
24
+ playerType: 'tempo-conductor',
25
+ phase: 'attached',
26
+ part: 'About to leave',
27
+ workDir: '/repo/demo',
28
+ },
29
+ {
30
+ playerId: 'tempo-eng',
31
+ ensemble: ENSEMBLE,
32
+ hostname: 'demo-host',
33
+ isConductor: false,
34
+ agentType: 'claude',
35
+ playerType: 'tempo-engineer',
36
+ phase: 'processing',
37
+ part: 'Implementing PR-3',
38
+ workDir: '/repo/demo',
39
+ processingSince: '2026-04-26T23:55:00.000Z',
40
+ },
41
+ ],
42
+ schedules: [],
43
+ chat: { messages: [], total: 0, hasMore: false },
44
+ hostProfiles: {
45
+ 'demo-host': {
46
+ hostname: 'demo-host', version: '0.28.0',
47
+ defaultAgent: 'claude', platform: 'linux', capabilities: [],
48
+ },
49
+ },
50
+ description: '',
51
+ startedAt: '',
52
+ currentBpm: 0,
53
+ tempoSeries: [],
54
+ },
55
+ events: [
56
+ {
57
+ v: 1,
58
+ type: 'player.phase_changed',
59
+ eventId: `${constants_1.FIXTURE_BOOT_EPOCH}:1`,
60
+ payload: {
61
+ playerId: 'conductor',
62
+ ensemble: ENSEMBLE,
63
+ phase: 'detached',
64
+ at: '2026-04-27T00:00:01.000Z',
65
+ },
66
+ },
67
+ {
68
+ v: 1,
69
+ type: 'player.removed',
70
+ eventId: `${constants_1.FIXTURE_BOOT_EPOCH}:2`,
71
+ payload: {
72
+ playerId: 'conductor',
73
+ ensemble: ENSEMBLE,
74
+ removedAt: '2026-04-27T00:00:02.000Z',
75
+ reason: 'gone',
76
+ },
77
+ },
78
+ ],
79
+ eventCadenceMs: 500,
80
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared constants used by every fixture file. Kept separate so a single
3
+ * boot-epoch change updates the whole registry atomically.
4
+ */
5
+ /**
6
+ * Synthetic boot epoch — the `<bootEpoch>` half of every fixture's
7
+ * `<bootEpoch>:<seq>` event-id token. Picked once and frozen so every
8
+ * fixture's events sort consistently.
9
+ */
10
+ export declare const FIXTURE_BOOT_EPOCH = "1735000000000";
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * Shared constants used by every fixture file. Kept separate so a single
4
+ * boot-epoch change updates the whole registry atomically.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.FIXTURE_BOOT_EPOCH = void 0;
8
+ /**
9
+ * Synthetic boot epoch — the `<bootEpoch>` half of every fixture's
10
+ * `<bootEpoch>:<seq>` event-id token. Picked once and frozen so every
11
+ * fixture's events sort consistently.
12
+ */
13
+ exports.FIXTURE_BOOT_EPOCH = '1735000000000';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Fixture: a conductor plus 8 receivers, simulating a single
3
+ * `broadcast` invocation that fans out to all players. All eight
4
+ * `chat.appended` events share the same `broadcastId` so dashboard UI
5
+ * can verify the #357 collapse — the TUI's `ConversationStream` (and
6
+ * the dashboard's analogue) renders consecutive chat entries with the
7
+ * same non-null `broadcastId` as a single row.
8
+ */
9
+ import type { FixtureScenario } from './index';
10
+ export declare const eightPlayerBroadcast: FixtureScenario;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.eightPlayerBroadcast = void 0;
4
+ const constants_1 = require("./constants");
5
+ const ENSEMBLE = 'demo-broadcast';
6
+ const BROADCAST_ID = 'bcast-87654321';
7
+ const AT = '2026-04-27T00:00:01.000Z';
8
+ const RECEIVERS = [
9
+ 'soloist-1', 'soloist-2', 'soloist-3', 'soloist-4',
10
+ 'soloist-5', 'soloist-6', 'soloist-7', 'soloist-8',
11
+ ];
12
+ const players = [
13
+ {
14
+ playerId: 'conductor',
15
+ ensemble: ENSEMBLE,
16
+ hostname: 'demo-host',
17
+ isConductor: true,
18
+ agentType: 'claude',
19
+ playerType: 'tempo-conductor',
20
+ phase: 'attached',
21
+ part: 'Orchestrating the broadcast',
22
+ workDir: '/repo/demo',
23
+ },
24
+ ...RECEIVERS.map((id) => ({
25
+ playerId: id,
26
+ ensemble: ENSEMBLE,
27
+ hostname: 'demo-host',
28
+ isConductor: false,
29
+ agentType: 'claude',
30
+ playerType: 'tempo-soloist',
31
+ phase: 'attached',
32
+ part: 'Soloing',
33
+ workDir: '/repo/demo',
34
+ })),
35
+ ];
36
+ const broadcastChatEvents = RECEIVERS.map((id, i) => ({
37
+ id: `msg-bcast-${i + 1}`,
38
+ from: 'conductor',
39
+ to: id,
40
+ text: 'Beta-3 release rehearsal: please run /smoke and report blockers.',
41
+ timestamp: AT,
42
+ role: 'conductor-out',
43
+ broadcastId: BROADCAST_ID,
44
+ }));
45
+ exports.eightPlayerBroadcast = {
46
+ name: 'eight-player-broadcast',
47
+ description: 'Conductor + 8 receivers; one broadcast fan-out (8 chat.appended share broadcastId). Verifies #357 collapse.',
48
+ snapshot: {
49
+ v: 1,
50
+ ensemble: ENSEMBLE,
51
+ capturedAt: '2026-04-27T00:00:00.000Z',
52
+ lastEventId: `${constants_1.FIXTURE_BOOT_EPOCH}:0`,
53
+ state: 'online',
54
+ hasConductor: true,
55
+ flags: { paused: false, held: false },
56
+ players,
57
+ schedules: [],
58
+ chat: { messages: [], total: 0, hasMore: false },
59
+ hostProfiles: {
60
+ 'demo-host': {
61
+ hostname: 'demo-host',
62
+ version: '0.28.0',
63
+ defaultAgent: 'claude',
64
+ platform: 'linux',
65
+ capabilities: [],
66
+ },
67
+ },
68
+ description: '',
69
+ startedAt: '',
70
+ currentBpm: 0,
71
+ tempoSeries: [],
72
+ },
73
+ events: broadcastChatEvents.map((msg, i) => ({
74
+ v: 1,
75
+ type: 'chat.appended',
76
+ eventId: `${constants_1.FIXTURE_BOOT_EPOCH}:${i + 1}`,
77
+ payload: msg,
78
+ })),
79
+ // Mild cadence so the dashboard can render the collapse animation if any.
80
+ eventCadenceMs: 25,
81
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Fixture: an ensemble with no players, no chat, no schedules. Useful
3
+ * for verifying empty-state UI rendering.
4
+ */
5
+ import type { FixtureScenario } from './index';
6
+ export declare const emptyEnsemble: FixtureScenario;