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,1020 @@
1
+ /**
2
+ * Agent runtime selector.
3
+ *
4
+ * - `'claude'` / `'copilot'` — production adapters; ship in the npm tarball.
5
+ * - `'mock'` — dev-mode-only adapter (ADR 0014 PR-2). Defense-in-depth gates
6
+ * (build-time exclusion, registry gate behind `isDevMode()`, recruit-time
7
+ * rejection, runtime banner) keep this off production paths. The string
8
+ * value lives in the type union so workflow / outbox / recruit code can
9
+ * discriminate without `any` casts even in production builds; the runtime
10
+ * gates are what actually prevent execution.
11
+ *
12
+ * Single source of truth: {@link AGENT_TYPES}. The CLI argv parser
13
+ * (`src/cli.ts`'s `--agent` validation) and the recruit MCP tool's
14
+ * `z.enum` import this tuple so adding a new adapter only requires
15
+ * editing one line — see #476 (the `claude-api` allowlist drift bug
16
+ * that motivated centralising this).
17
+ */
18
+ export declare const AGENT_TYPES: readonly ["claude", "copilot", "mock", "claude-api", "opencode", "claude-code-headless"];
19
+ export type AgentType = typeof AGENT_TYPES[number];
20
+ /**
21
+ * Mock-adapter mode (ADR 0014 §4.2). Single source of truth shared by the
22
+ * adapter, the recruit tool's zod enum (`z.enum(MOCK_MODES)`), the spawn
23
+ * options, the recruit outbox entry, the lineup schema, and the lineup
24
+ * dispatcher. `'echo' | 'scripted'` shipped in PR-2; `'silent' | 'chaos'`
25
+ * landed in PR-3.
26
+ *
27
+ * Declared here rather than in `src/adapters/mock/` so non-dev-mode modules
28
+ * (recruit, spawn, schema) can reference the type without pulling the
29
+ * adapter source unit into their dep graph.
30
+ */
31
+ export declare const MOCK_MODES: readonly ["echo", "scripted", "silent", "chaos"];
32
+ export type MockMode = typeof MOCK_MODES[number];
33
+ /**
34
+ * The seven phases of a session workflow's lifecycle.
35
+ *
36
+ * - `booting` — workflow exists, no adapter has claimed it yet
37
+ * - `attached` — an adapter holds a valid attachment and is idle-ready
38
+ * - `processing` — attached AND at least one message is in-flight in the adapter
39
+ * - `awaiting` — attached, idle, outbox empty (presentation refinement of `attached`)
40
+ * - `draining` — attachment requested detach; flushing outbox + awaiting `adapterExited`
41
+ * - `detached` — workflow RUNNING, no attachment; outbox dispatch paused (stop/destroy bypass)
42
+ * - `gone` — terminal; workflow COMPLETES after `destroy`
43
+ */
44
+ export type AttachmentPhase = 'booting' | 'attached' | 'processing' | 'awaiting' | 'draining' | 'detached' | 'gone';
45
+ /** Classes of adapter with different lifecycle requirements. */
46
+ export type AdapterClass = 'interactive' | 'sdk';
47
+ /**
48
+ * Descriptor registered by an adapter — declares class, identity, and required guarantees.
49
+ * Used by the workflow to size timers (heartbeat cadence) and by the adapter registry
50
+ * to route `recruit` to the right adapter implementation.
51
+ */
52
+ export interface AdapterDescriptor {
53
+ /** Adapter identifier, e.g. `'claude-code'`, `'copilot'`. */
54
+ adapterId: string;
55
+ adapterClass: AdapterClass;
56
+ /** True iff the adapter blocks on an LLM turn (SDK adapters). Drives `processingStart`/`End` expectations. */
57
+ blocksOnLLMTurn: boolean;
58
+ /** Heartbeat cadence in milliseconds. Interactive: 60_000; SDK: 30_000. */
59
+ heartbeatMs: number;
60
+ }
61
+ /**
62
+ * Reason an attachment detached or was detached. Used for audit and UX messaging.
63
+ *
64
+ * Canonical values per design §3.1 (`docs/design/session-lifecycle-rebuild-v2.md`):
65
+ * `user-stop` | `restart` | `heartbeat-timeout` | `superseded` | `agent-exited` | `spawn-failed` | `destroy`
66
+ *
67
+ * `force` is a PR-A implementation extension used by the main loop's `drainingDeadline`
68
+ * fire path (§9.5.c) when the adapter never sent `adapterExited` after `requestDetach`.
69
+ * Kept alongside the spec values so the workflow has a non-empty reason to record even
70
+ * when the graceful drain path never acked. Safe to merge into `heartbeat-timeout` in a
71
+ * future cleanup if the semantics converge.
72
+ *
73
+ * `reconnect-exhausted` is fired adapter-side by `BaseAttachment.runReconnectLoop` (#201)
74
+ * when the reconnect budget elapsed without recovering a live lease. Distinct from
75
+ * `heartbeat-timeout` so post-mortems can tell "lease expired once" from "poller tried
76
+ * to recover and gave up" — workflow-side reap accounting treats them identically.
77
+ *
78
+ * `continued-as-new` is fired adapter-side by `BaseAttachment.tickHeartbeat` /
79
+ * `tickPhaseWatcher` (#226) when the pinned runId returns
80
+ * `WorkflowExecutionAlreadyCompleted` AND the closed run's history carries a
81
+ * `WorkflowExecutionContinuedAsNewEvent` pointing at a successor runId. When the
82
+ * subclass opts in via `shouldReconnect`, the base class transparently rebinds the
83
+ * pinned handle to the successor (no re-claim — the workflow's §2.3 CAN-boundary
84
+ * lease extension keeps the lease alive across the transition) and resumes delivery.
85
+ * When not opted in, the base class fires the reason as terminal just like any
86
+ * other non-recoverable lease loss.
87
+ */
88
+ export type DetachReason = 'user-stop' | 'restart' | 'heartbeat-timeout' | 'superseded' | 'agent-exited' | 'spawn-failed' | 'destroy' | 'force' | 'reconnect-exhausted' | 'continued-as-new';
89
+ /**
90
+ * Workflow-emitted directive to the attached adapter. Delivered via {@link AttachmentInfo}
91
+ * polling (no reverse-RPC surface in Temporal).
92
+ */
93
+ export type AdapterDirective = 'detach-now' | 'heartbeat' | 'continue';
94
+ /**
95
+ * A live or expired lease. Exactly one (or none) lives on the workflow at any time.
96
+ * Lease-expiry enforcement happens in the main loop's deadline race (§9.5.a).
97
+ */
98
+ export interface Attachment {
99
+ attachmentId: string;
100
+ hostname: string;
101
+ adapterId: string;
102
+ adapterClass: AdapterClass;
103
+ /** ISO timestamp from `workflow.now()` at claim. */
104
+ claimedAt: string;
105
+ /** ISO timestamp of last heartbeat (signal or claimAttachment renewal). */
106
+ lastHeartbeatAt: string;
107
+ /** ISO timestamp; after this the main loop reaps the attachment → `detached`. */
108
+ expiresAt: string;
109
+ /**
110
+ * Lease duration negotiated at claim time (milliseconds). Heartbeats renew
111
+ * `expiresAt` by this amount — honours the caller's requested lease rather than a
112
+ * workflow-side hardcoded default. Added in PR-C commit 6 (#119a).
113
+ */
114
+ leaseMs: number;
115
+ /** Workflow runId captured at claim time — adapters must pin subsequent `getHandle` to this. */
116
+ runId: string;
117
+ }
118
+ /** Opaque token returned from `claimAttachment`; adapter carries it on every subsequent call. */
119
+ export interface AttachmentToken {
120
+ attachmentId: string;
121
+ runId: string;
122
+ /** ISO timestamp; adapter may use this to schedule early renewal before expiry. */
123
+ expiresAt: string;
124
+ leaseMs: number;
125
+ }
126
+ /**
127
+ * Snapshot returned by the `attachmentInfo` query.
128
+ * Adapters, tools, and the TUI poll this to drive UX.
129
+ */
130
+ export interface AttachmentInfo {
131
+ phase: AttachmentPhase;
132
+ currentAttachment?: Attachment;
133
+ preferredHost?: string;
134
+ inFlightCount: number;
135
+ /** ISO timestamp when the in-flight set became non-empty. */
136
+ processingSince?: string;
137
+ }
138
+ /**
139
+ * Returned by the `orphanSummary` query — shape matches what the daemon needs to render
140
+ * a detached-orphan card and decide whether to auto-restore per `restorePolicy`.
141
+ *
142
+ * `ensemble` and `playerId` carry the workflow's canonical metadata identity —
143
+ * sourced from `input.metadata` in the workflow handler, not parsed from the
144
+ * workflow id (see #143). Consumers like `reconcileOnBoot`, `cleanupLoop`, and
145
+ * `restoreOneOrphan` read these directly instead of regex-parsing the workflow
146
+ * id (which loses dashes from player names like `tempo-eng`).
147
+ */
148
+ export interface OrphanSummary {
149
+ ensemble: string;
150
+ playerId: string;
151
+ detachedSince?: string;
152
+ reason?: DetachReason;
153
+ preferredHost?: string;
154
+ lastAdapter?: {
155
+ hostname: string;
156
+ adapterId: string;
157
+ };
158
+ }
159
+ export interface SessionMetadata {
160
+ playerId: string;
161
+ ensemble: string;
162
+ hostname: string;
163
+ workDir: string;
164
+ gitRoot?: string;
165
+ gitBranch?: string;
166
+ isConductor: boolean;
167
+ agentType?: AgentType;
168
+ /**
169
+ * Adapter identifier resolved from the registry (`src/adapters/`). Populated on
170
+ * fresh recruits in PR-B (v0.25 step 2/7); pre-PR-B sessions leave this
171
+ * undefined and the dispatcher falls back to {@link agentType} → adapterId
172
+ * mapping via `AdapterRegistry.resolveFromAgentType`.
173
+ */
174
+ adapterId?: string;
175
+ /** Agent definition name (e.g., "tempo-soloist"). */
176
+ playerType?: string;
177
+ /** Short description from the agent definition. */
178
+ playerTypeDescription?: string;
179
+ /** Player ID of who recruited this player. */
180
+ recruitedBy?: string;
181
+ /** Worktree path if this session was spawned in an isolated worktree. */
182
+ worktreePath?: string;
183
+ /**
184
+ * Adapter-specific session identifier. Stashed via `updateMetadataSignal`
185
+ * by the adapter on first turn / first claim; read back on restart /
186
+ * encore for resume continuity. Three usage paths today:
187
+ *
188
+ * - **Copilot bridge** — Copilot SDK session id (UUIDv4-shaped).
189
+ * - **Claude Code interactive** (`agent: 'claude'`) — UUIDv4 used as
190
+ * `claude --session-id <id>` on spawn and `claude --resume <id>` on
191
+ * restart for deterministic session resume.
192
+ * - **Claude Code headless** (`agent: 'claude-code-headless'`, #520)
193
+ * — UUIDv4 used as `claude -p --session-id <id>` per turn and
194
+ * `--resume <id>` on subsequent turns. Shares the field with the
195
+ * interactive adapter so an interactive↔headless migrate within the
196
+ * same cwd preserves session continuity for free (Claude Code's
197
+ * session JSONL is per-cwd, not per-adapter).
198
+ * - **OpenCode** (`agent: 'opencode'`) — OpenCode-server session id.
199
+ * - **Mock** — `mock-<pid>` placeholder (dev mode only).
200
+ *
201
+ * **Treat as opaque**: consumers MUST NOT depend on a specific UUID
202
+ * format or origin — different adapters write different shapes through
203
+ * this field, and that's by design.
204
+ */
205
+ sessionId?: string;
206
+ /**
207
+ * #131 Phase C — model id for the claude-api adapter (e.g.
208
+ * `claude-opus-4-7`). Lives on durable session metadata so restart /
209
+ * encore / migrate of a claude-api player can recover the original
210
+ * model selection across `continueAsNew` boundaries (the recruit-arg
211
+ * lives only in `RecruitOutboxEntry` which is dropped after dispatch).
212
+ * Absent for non-claude-api sessions; absent for pre-#131 sessions
213
+ * (the spawn falls back to `AGENT_TEMPO_API_MODEL` env / pinned default).
214
+ */
215
+ model?: string;
216
+ }
217
+ export interface AgentTypeInfo {
218
+ name: string;
219
+ description?: string;
220
+ source: 'project' | 'user' | 'shipped';
221
+ path: string;
222
+ nativeResolvable: boolean;
223
+ allowedTools?: string[];
224
+ }
225
+ /**
226
+ * Capability snapshot advertised by a daemon at boot.
227
+ *
228
+ * Intentionally an OPEN schema: only `hostname` is required and validated
229
+ * at signal receipt. All other fields are optional and stored opaquely so
230
+ * the global maestro can accept payloads from daemons running newer or
231
+ * older versions without breaking. Per-field Zod validation happens at the
232
+ * `listHosts` join site, never at the workflow signal handler (see #274
233
+ * architect delta AC3c / M9).
234
+ *
235
+ * **Privacy contract (AC5c / M10 — HARD REQUIREMENT):** daemon-side scrub
236
+ * MUST strip absolute paths, env vars, and user-home directories before
237
+ * signaling. The global maestro is namespace-wide; a multi-tenant or
238
+ * multi-ensemble corporate setup would leak username-containing paths
239
+ * across ensembles if this is ever violated. `claudeBin` is basename only.
240
+ * `availableAgentTypes` is type names only.
241
+ */
242
+ export interface HostProfile {
243
+ /** Required. Validated against PLAYER_NAME_REGEX at signal receipt. */
244
+ hostname: string;
245
+ /** Daemon package version string (e.g. `0.26.0-beta.7`). Optional — legacy daemons may omit. */
246
+ version?: string;
247
+ defaultAgent?: AgentType;
248
+ /** Agent type NAMES only. Never file paths — see privacy contract above. */
249
+ availableAgentTypes?: string[];
250
+ availablePlayerTypes?: string[];
251
+ /** Basename only (e.g. `'claude'`). Never absolute — see privacy contract above. */
252
+ claudeBin?: string;
253
+ platform?: NodeJS.Platform;
254
+ capabilities?: string[];
255
+ /**
256
+ * Daemon process start time (epoch ms, `Date.now()` at module load).
257
+ * Resets on every daemon restart; semantics are
258
+ * **daemon-process uptime**, not host-first-seen. Issue #399 Q5.3b.
259
+ * The Hosts table renders `now - daemonStartedAt` client-side.
260
+ */
261
+ daemonStartedAt?: number;
262
+ /**
263
+ * Adapter name → upstream tool version (e.g.
264
+ * `{ "claude-code": "1.2.4", "copilot": "0.5.2" }`).
265
+ * Probed once at daemon boot in parallel with the global-maestro ensure;
266
+ * adapters whose probe fails or whose output can't be parsed are
267
+ * omitted entirely (the dashboard shows `—`). Issue #399 Q5.4.
268
+ */
269
+ adapterVersions?: Record<string, string>;
270
+ /**
271
+ * Open-schema escape hatch: unknown fields carried opaquely across
272
+ * daemon-version skew. Consumers MUST NOT rely on specific keys here
273
+ * without a Zod guard at read time.
274
+ */
275
+ [extraField: string]: unknown;
276
+ }
277
+ /**
278
+ * Single daemon-process instance observed by Temporal's poller registry.
279
+ * A `HostInfo` may carry ≥1 instance when multiple daemons run on the same
280
+ * hostname (e.g. different `AGENT_TEMPO_HOME` per user session).
281
+ */
282
+ export interface InstanceInfo {
283
+ pid: number;
284
+ /** Parsed from worker identity. `'unknown'` for legacy-format identities (`<pid>@<hostname>`). */
285
+ version: string;
286
+ /** Raw `poller.identity` as Temporal returned it. */
287
+ identity: string;
288
+ /** ISO 8601. */
289
+ lastAccessTime: string;
290
+ hasWorkflowWorker: boolean;
291
+ hasActivityWorker: boolean;
292
+ /** `true` when the per-host activity queue (`agent-tempo-<hostname>`) has a live poller. Controls `HostInfo.recruitReady`. */
293
+ hasHostQueueWorker: boolean;
294
+ /** Set only when identity was in the legacy `<pid>@<hostname>` form. */
295
+ legacy?: true;
296
+ }
297
+ /**
298
+ * Joined liveness + capability view returned by `src/utils/hosts.ts`.
299
+ * `freshness === 'live'` iff any instance's `lastAccessTime` is within the
300
+ * `HOST_FRESHNESS_THRESHOLD_MS` window. `recruitReady` is `true` iff some
301
+ * instance has BOTH shared-activity AND per-host-activity pollers live —
302
+ * the minimum a recruit dispatch needs.
303
+ */
304
+ export interface HostInfo {
305
+ hostname: string;
306
+ instances: InstanceInfo[];
307
+ recruitReady: boolean;
308
+ freshness: 'live' | 'stale';
309
+ profile?: HostProfile;
310
+ /**
311
+ * - `'fresh'` — profile present and the signaling daemon's parsed version matches a live identity
312
+ * - `'stale'` — profile present but identity/version disagrees (M13 reconciliation) or the signaling daemon is not currently polling
313
+ * - `'missing'` — daemon is live but no profile record exists (pre-HostProfile daemon, global maestro unreachable at boot, or global maestro absent)
314
+ */
315
+ profileStaleness: 'fresh' | 'stale' | 'missing';
316
+ }
317
+ /**
318
+ * One slot of player-saveable state (#334 PR-1, ADR 0011).
319
+ *
320
+ * Curated artifact written by the owning player itself via the `save_state`
321
+ * MCP tool — opaque string content with a markdown-template docstring nudge
322
+ * (no enforced schema). Read by any peer in the ensemble via `fetch_state`;
323
+ * cleared by the owner via `clear_state`.
324
+ *
325
+ * Sizing: per-key content max 32 KiB; up to 4 slots per player; aggregate
326
+ * structural max 128 KiB. See `src/utils/validation.ts` constants and
327
+ * `docs/design/334-player-saveable-state.md` §3 for the CAN-payload analysis.
328
+ *
329
+ * `savedAt` is an ISO timestamp produced via `workflow.now()` so replay stays
330
+ * deterministic. `savedBy` records the player id that wrote the slot — the
331
+ * audit identity for peer reads.
332
+ */
333
+ export interface PlayerStateEntry {
334
+ content: string;
335
+ savedAt: string;
336
+ savedBy: string;
337
+ }
338
+ export interface SessionInput {
339
+ metadata: SessionMetadata;
340
+ /** Restored from continue-as-new */
341
+ part?: string;
342
+ /** Restored from continue-as-new (undelivered only) */
343
+ messages?: Message[];
344
+ /** Restored from continue-as-new */
345
+ sentMessages?: SentMessage[];
346
+ /** Restored from continue-as-new (conductor only) */
347
+ commandHistory?: Command[];
348
+ /** Restored from continue-as-new (conductor only) */
349
+ reportHistory?: PlayerReport[];
350
+ /** Restored from continue-as-new (pending/processing entries only) */
351
+ outbox?: OutboxEntry[];
352
+ autoSummary?: string;
353
+ /** Disable stale session detection (for passive mailbox workflows like maestro) */
354
+ disableStaleDetection?: boolean;
355
+ /** Restored from continue-as-new: last inbound message with responseRequested=true */
356
+ lastInboundRRTime?: number;
357
+ /** Restored from continue-as-new: last outbound activity timestamp */
358
+ lastOutboundTime?: number;
359
+ /**
360
+ * #399 W2 — counters carried across continueAsNew. Each is monotonic
361
+ * across the workflow's lifetime; the dashboard surfaces them via
362
+ * `getMessagingStateQuery` and `getActivityStateQuery`.
363
+ *
364
+ * - `receivedCount`: bumped per inbound `receiveMessage` cue.
365
+ * - `sentCount`: bumped per `submitOutboxUpdate` (every entry the
366
+ * session pushes to its outbox). The dashboard's "Messages" KV
367
+ * row reads this as outbound volume.
368
+ * - `activityCount`: bumped at every "work" event — cue, outbox
369
+ * submit, schedule fire, report, recruit, restart, destroy,
370
+ * migrate. Mirrors the existing `lastActivityTime` mutation
371
+ * sites (~20 of them) and feeds W1's tempo bucket projection.
372
+ */
373
+ receivedCount?: number;
374
+ sentCount?: number;
375
+ activityCount?: number;
376
+ /** Restored from continue-as-new (conductor only) */
377
+ qualityGates?: QualityGate[];
378
+ /** Restored from continue-as-new (conductor only) */
379
+ worktrees?: WorktreeEntry[];
380
+ /** Restored from continue-as-new (conductor only) */
381
+ stages?: StageEntry[];
382
+ /** When true, outbox dispatch is paused until releaseHeld signal is received (warm hold). */
383
+ outboxLocked?: boolean;
384
+ /** Stored initial message to deliver when the hold is released. */
385
+ heldMessage?: string;
386
+ /** When true, outbox dispatch is paused ensemble-wide (pause/resume). */
387
+ paused?: boolean;
388
+ /** Restored from continue-as-new: message IDs currently being processed (blocks stale detection). */
389
+ inFlightMessageIds?: string[];
390
+ /** Restored from continue-as-new: timestamp when in-flight set became non-empty.
391
+ * v0.24 wrote a numeric Date.now() value; v0.25 writes ISO strings via `workflow.now()`. */
392
+ processingSince?: number | string;
393
+ /** Restored from continue-as-new: workflow has been destroyed (terminal). */
394
+ destroyed?: boolean;
395
+ /** Current lease, if any. Expiry checked against `workflow.now()` in the main-loop deadline race. */
396
+ currentAttachment?: Attachment;
397
+ /** Host last seen as preferred for spawn; daemon `reconcileOnBoot` uses this. */
398
+ preferredHost?: string;
399
+ /** Current phase — authoritative after v0.25 replaces the legacy `status` field. */
400
+ phase?: AttachmentPhase;
401
+ /** ISO timestamp of when the current `draining` phase started. Carried for drainingDeadline race. */
402
+ drainingSince?: string;
403
+ /** Caller-supplied grace window for the current `draining` phase, in ms. When absent the
404
+ * workflow falls back to `DEFAULT_DRAINING_DEADLINE_MS`. Carried across continueAsNew so a
405
+ * detach request with a non-default deadline isn't silently reset to 5s mid-drain. */
406
+ drainingDeadlineMs?: number;
407
+ /** Temporal config passed through for outbox activities (non-secret fields only). */
408
+ temporalConfig?: {
409
+ temporalAddress: string;
410
+ temporalNamespace: string;
411
+ taskQueue: string;
412
+ };
413
+ /**
414
+ * Restored from continue-as-new: per-player saveable-state slots
415
+ * (#334 PR-1 / ADR 0011). Map of `slotKey → PlayerStateEntry`. Carried
416
+ * forward only when at least one slot is populated — empty maps are
417
+ * omitted from the CAN payload to keep the wire small for the common
418
+ * no-state case (same idiom as `currentAttachment` / `preferredHost`).
419
+ * See `src/utils/validation.ts` for size + slot-count caps.
420
+ */
421
+ playerState?: Record<string, PlayerStateEntry>;
422
+ }
423
+ export interface Message {
424
+ id: string;
425
+ from: string;
426
+ text: string;
427
+ timestamp: string;
428
+ delivered: boolean;
429
+ /** True when sent from the Maestro dashboard by a human. */
430
+ isMaestro?: boolean;
431
+ /**
432
+ * #357: Stable id shared across every fan-out target of a single
433
+ * `broadcast` tool invocation. Generated once in the broadcaster's
434
+ * MCP-tool process and threaded through `CueOutboxEntry` →
435
+ * `receiveMessage` signal → this field. The TUI uses it to fold N
436
+ * identical broadcast deliveries into a single chat row. `undefined`
437
+ * for non-broadcast direct cues.
438
+ */
439
+ broadcastId?: string;
440
+ /**
441
+ * #318: Coat-check ticket id when the sender stashed content via
442
+ * `coat_check_put` and called `cue` with `attachmentTicket`. Receivers
443
+ * call `coat_check_get` with this value to pull the full content body.
444
+ * `undefined` for cues without an attachment.
445
+ */
446
+ attachmentTicket?: string;
447
+ }
448
+ export interface SentMessage {
449
+ id: string;
450
+ to: string;
451
+ text: string;
452
+ timestamp: string;
453
+ /** #357: Mirrors {@link Message.broadcastId} on the sender side. */
454
+ broadcastId?: string;
455
+ }
456
+ export interface Command {
457
+ text: string;
458
+ source: string;
459
+ replyTo?: string;
460
+ timestamp: string;
461
+ }
462
+ export interface PlayerReport {
463
+ playerId: string;
464
+ text: string;
465
+ type: 'result' | 'blocker' | 'question';
466
+ timestamp: string;
467
+ }
468
+ export interface HistoryEntry {
469
+ type: 'command' | 'report';
470
+ timestamp: string;
471
+ data: Command | PlayerReport;
472
+ }
473
+ export type OutboxEntryStatus = 'pending' | 'processing' | 'delivered' | 'failed';
474
+ interface OutboxEntryBase {
475
+ id: string;
476
+ createdAt: string;
477
+ status: OutboxEntryStatus;
478
+ error?: string;
479
+ deliveredAt?: string;
480
+ }
481
+ export interface CueOutboxEntry extends OutboxEntryBase {
482
+ type: 'cue';
483
+ targetPlayerId: string;
484
+ message: string;
485
+ /**
486
+ * #357: Stable id shared across every fan-out target of a single
487
+ * `broadcast` tool invocation. Generated once in the MCP-tool process
488
+ * (NOT inside the workflow — workflow determinism is preserved
489
+ * because the workflow only sees the id as an opaque string on
490
+ * `OutboxEntryInput`). Threaded through to the target's `Message`
491
+ * and the sender's `SentMessage` so the TUI can fold the fan-out
492
+ * into a single chat row. `undefined` for non-broadcast cues.
493
+ */
494
+ broadcastId?: string;
495
+ /**
496
+ * #318: Optional coat-check ticket id referencing content stashed on
497
+ * per-ensemble Maestro state via `coat_check_put`. Receivers see this
498
+ * field on their delivered `Message` and can call `coat_check_get` to
499
+ * pull the full content body. Backward-compatible — pre-#318 cues just
500
+ * don't have it.
501
+ */
502
+ attachmentTicket?: string;
503
+ }
504
+ export interface RecruitOutboxEntry extends OutboxEntryBase {
505
+ type: 'recruit';
506
+ targetName: string;
507
+ workDir: string;
508
+ isConductor: boolean;
509
+ initialMessage?: string;
510
+ agent: AgentType;
511
+ systemPrompt?: string;
512
+ targetHostname?: string;
513
+ /** Agent type name (e.g., "tempo-soloist"). */
514
+ agentDefinition?: string;
515
+ /** Resolved absolute path to .md file (for shipped fallback). */
516
+ agentDefinitionPath?: string;
517
+ /** Short description from the agent definition frontmatter. */
518
+ agentDefinitionDescription?: string;
519
+ /** Whether the agent definition is in a Claude Code-resolvable location. */
520
+ nativeResolvable?: boolean;
521
+ /** Tool restrictions from the agent definition frontmatter. */
522
+ allowedTools?: string[];
523
+ /** Custom claude binary path (from config.claudeBin). */
524
+ claudeBin?: string;
525
+ /** When true, spawn process but lock outbox and defer initial message until release (warm hold). */
526
+ held?: boolean;
527
+ /**
528
+ * Mock-adapter configuration (ADR 0014 §4.2). Only set when `agent === 'mock'`.
529
+ * `mockMode` defaults to `'echo'` if absent. `mockScenario` is required when
530
+ * `mockMode === 'scripted'` and accepts either a bare scenario name (resolved
531
+ * against the package's shipped `scenarios/` dir) or an absolute YAML path.
532
+ * Neither `silent` nor `chaos` consume `mockScenario`.
533
+ */
534
+ mockMode?: MockMode;
535
+ mockScenario?: string;
536
+ /**
537
+ * Optional model id for the claude-api adapter (#131 Phase C). Falls back
538
+ * to `AGENT_TEMPO_API_MODEL` env then a constants-pinned default at the
539
+ * adapter's spawn time. Ignored when `agent !== 'claude-api'`.
540
+ */
541
+ model?: string;
542
+ /**
543
+ * #520 — claude-code-headless permission mode. Forwarded to `claude -p
544
+ * --permission-mode`. Recruit-arg → `AGENT_TEMPO_PERMISSION_MODE` env →
545
+ * `'acceptEdits'` default. Mutually exclusive with
546
+ * {@link dangerouslySkipPermissions}. Ignored when
547
+ * `agent !== 'claude-code-headless'`.
548
+ *
549
+ * Type literal kept inline (not imported from
550
+ * {@link ClaudeCodeHeadlessPermissionMode}) because this file is the
551
+ * V8 workflow-sandbox-safe shared types module — importing from
552
+ * `src/adapters/` would invert the dependency direction and risk
553
+ * loading adapter code into the sandbox. The Zod enum, spawn helper,
554
+ * and outbox `SpawnProcessInput` re-derive from the canonical tuple at
555
+ * their consumer surfaces (where `src/adapters/claude-code-headless/types`
556
+ * is safe to import).
557
+ */
558
+ permissionMode?: 'acceptEdits' | 'auto' | 'bypassPermissions' | 'default' | 'dontAsk' | 'plan';
559
+ /**
560
+ * #520 — claude-code-headless dangerous-skip-permissions opt-in. When
561
+ * true, the adapter passes `--dangerously-skip-permissions` to `claude
562
+ * -p` instead of `--permission-mode`. Use only in trusted / sandboxed
563
+ * contexts. Mutually exclusive with {@link permissionMode}. Ignored
564
+ * when `agent !== 'claude-code-headless'`.
565
+ */
566
+ dangerouslySkipPermissions?: boolean;
567
+ }
568
+ export interface ReleaseOutboxEntry extends OutboxEntryBase {
569
+ type: 'release';
570
+ targetPlayerId: string;
571
+ }
572
+ export interface ReportOutboxEntry extends OutboxEntryBase {
573
+ type: 'report';
574
+ text: string;
575
+ reportType: 'result' | 'blocker' | 'question' | 'update';
576
+ }
577
+ export interface StopOutboxEntry extends OutboxEntryBase {
578
+ type: 'stop';
579
+ targetPlayerId: string;
580
+ }
581
+ /**
582
+ * Detach outbox entry (PR-D) — enqueued by the `detach` tool / TempoClient /
583
+ * CLI to gracefully reap the target's adapter. The dispatch `deliverDetach`
584
+ * activity signals `requestDetachSignal` on the target's workflow.
585
+ */
586
+ export interface DetachOutboxEntry extends OutboxEntryBase {
587
+ type: 'detach';
588
+ targetPlayerId: string;
589
+ reason?: DetachReason;
590
+ deadlineMs?: number;
591
+ }
592
+ /**
593
+ * Destroy outbox entry (PR-D) — enqueued by the `destroy` tool / TempoClient /
594
+ * CLI to terminally end the target's workflow. Dispatch `deliverDestroy`
595
+ * activity executes `destroyUpdate` on the target and optionally posts a
596
+ * system receiveMessage on the ensemble conductor.
597
+ */
598
+ export interface DestroyOutboxEntry extends OutboxEntryBase {
599
+ type: 'destroy';
600
+ targetPlayerId: string;
601
+ reason?: string;
602
+ /** When true (default), post a system message on the ensemble conductor. */
603
+ notifyConductor?: boolean;
604
+ }
605
+ /**
606
+ * Restart outbox entry (PR-D) — enqueued by the `restart` / `migrate` tools,
607
+ * the TempoClient, and the CLI. Dispatch `deliverRestart` activity owns the
608
+ * §8.2 algorithm on the target (graceful detach → optional force → claim →
609
+ * optional context replay → enqueueSpawn). Durable across the per-attempt
610
+ * retry window of the activity itself.
611
+ */
612
+ export interface RestartOutboxEntry extends OutboxEntryBase {
613
+ type: 'restart';
614
+ targetPlayerId: string;
615
+ /** When true, force-steal a live attachment via forceDetach. */
616
+ force?: boolean;
617
+ /** Target host for the new attachment; defaults to preferredHost/last-hostname. */
618
+ host?: string;
619
+ /** Skip context replay (equivalent to --fresh). */
620
+ fresh?: boolean;
621
+ /** Number of recent messages to include in context (when !fresh). */
622
+ contextMessages?: number;
623
+ /** Identifier of the invoker for audit messages (default: 'cli'). */
624
+ invokerPlayerId?: string;
625
+ /**
626
+ * #334 PR-2 — seed the restarted session with a saved-state slot instead of
627
+ * (or alongside) transcript replay. `true` resolves to `PLAYER_STATE_DEFAULT_KEY`
628
+ * (`'main'`); a string names a specific slot. Absent = current behaviour
629
+ * (transcript replay only). Backward compat is structural — old payloads
630
+ * omit this field and the new `wantsState` branch evaluates to `false`. See
631
+ * [docs/design/334-player-saveable-state.md](../../docs/design/334-player-saveable-state.md) §7.2.
632
+ */
633
+ loadFromState?: boolean | string;
634
+ /**
635
+ * #334 PR-2 — controls transcript-replay interaction when `loadFromState`
636
+ * is set:
637
+ * - `'suppress'` (default when `loadFromState` set): only the saved
638
+ * state seeds the new session.
639
+ * - `'replay'`: both saved state and transcript are seeded (saved
640
+ * state delivered first).
641
+ * - When `loadFromState` is absent: ignored — transcript replay always
642
+ * happens (governed by the existing `fresh` flag).
643
+ */
644
+ transcript?: 'suppress' | 'replay';
645
+ }
646
+ /**
647
+ * Spawn outbox entry — enqueued by the `enqueueSpawn` update so a host activity
648
+ * launches (or relaunches) an adapter process that will then claim the carried
649
+ * attachment. Distinguished from `RecruitOutboxEntry` because the target
650
+ * workflow already exists and an attachment has been pre-claimed; the dispatch
651
+ * side therefore skips workflow creation and drives the restart/resume path.
652
+ *
653
+ * PR-C commit 6 (#118): planted the discriminated union member. PR-D wires
654
+ * full end-to-end consumption of the 5 attachment-specific fields through the
655
+ * `startRecruitedSession` + `spawnProcess` activities.
656
+ */
657
+ export interface SpawnOutboxEntry extends OutboxEntryBase {
658
+ type: 'spawn';
659
+ /** The name of the player this spawn lands on (matches workflow metadata.playerId). */
660
+ targetName: string;
661
+ /** Working directory for the spawned adapter process. */
662
+ workDir: string;
663
+ /** True if the spawn is for the ensemble conductor session. */
664
+ isConductor: boolean;
665
+ /** Agent kind to spawn (claude | copilot | future SDK variants). */
666
+ agent: AgentType;
667
+ /** Host task queue the spawn activity should dispatch against. */
668
+ targetHostname: string;
669
+ /** Attachment pre-claimed for this spawn — adapter consumes it on boot. */
670
+ attachmentId: string;
671
+ /** RunId pinned during the pre-claim — adapter `getHandle`s against this. */
672
+ attachmentRunId: string;
673
+ /** Adapter class descriptor id (`'claude-code'`, `'copilot'`, …). */
674
+ adapterId: string;
675
+ /** True if the spawn should `claude --resume` into the prior `sessionId`. */
676
+ resumeAttachment: boolean;
677
+ /** Claude session id used for `--resume` and continuity. Optional — fresh spawns omit it. */
678
+ sessionId?: string;
679
+ /** Resolved agent-definition name (e.g. `my-tempo-engineer`). */
680
+ agentDefinition?: string;
681
+ /** Absolute path to the agent-definition `.md` on the invoker host. */
682
+ agentDefinitionPath?: string;
683
+ /** True when the agent-definition is resolvable by name on the target host
684
+ * (project/user tier) so the spawn can use `--agent <name>` instead of
685
+ * `--system-prompt <path>`. */
686
+ nativeResolvable?: boolean;
687
+ /**
688
+ * #131 Phase C — claude-api model id carried across restart / encore /
689
+ * migrate. Read from durable {@link SessionMetadata.model} by
690
+ * `deliverRestart` and forwarded into the spawn so the restarted
691
+ * subprocess runs the same model the original recruit chose.
692
+ */
693
+ model?: string;
694
+ }
695
+ export type OutboxEntry = CueOutboxEntry | RecruitOutboxEntry | ReportOutboxEntry | StopOutboxEntry | ReleaseOutboxEntry | SpawnOutboxEntry | DetachOutboxEntry | DestroyOutboxEntry | RestartOutboxEntry;
696
+ /** Distributive Omit that works correctly on union types. */
697
+ type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
698
+ /** Input type for submitting outbox entries — auto-fields (id, createdAt, status, error, deliveredAt) are added by the workflow. */
699
+ export type OutboxEntryInput = DistributiveOmit<OutboxEntry, 'id' | 'createdAt' | 'status' | 'error' | 'deliveredAt'>;
700
+ export interface QualityGateCriterion {
701
+ text: string;
702
+ status: 'pending' | 'passed' | 'failed';
703
+ evaluatedBy?: string;
704
+ evaluatedAt?: string;
705
+ notes?: string;
706
+ }
707
+ export interface QualityGate {
708
+ /** Unique key identifying the task this gate covers. */
709
+ task: string;
710
+ criteria: QualityGateCriterion[];
711
+ createdBy: string;
712
+ createdAt: string;
713
+ /** Derived: all passed → passed, any failed → failed, else open. */
714
+ status: 'open' | 'passed' | 'failed';
715
+ }
716
+ export interface WorktreeEntry {
717
+ /** Player name assigned to this worktree. */
718
+ player: string;
719
+ /** Absolute path to worktree directory. */
720
+ path: string;
721
+ /** Git branch for this worktree. */
722
+ branch: string;
723
+ /** Original git root (for git worktree remove). */
724
+ gitRoot: string;
725
+ /** ISO timestamp of creation. */
726
+ createdAt: string;
727
+ /** Player ID of creator. */
728
+ createdBy: string;
729
+ }
730
+ export interface StagePlayerStatus {
731
+ playerId: string;
732
+ status: 'waiting' | 'reported' | 'blocked';
733
+ reportType?: 'result' | 'blocker' | 'question' | 'update';
734
+ reportText?: string;
735
+ reportedAt?: string;
736
+ }
737
+ export interface StageEntry {
738
+ /** Unique name identifying this stage. */
739
+ name: string;
740
+ /** Players tracked in this stage. */
741
+ players: StagePlayerStatus[];
742
+ /** Aggregate status: active until all report or a blocker halts. */
743
+ status: 'active' | 'complete' | 'failed' | 'cancelled';
744
+ /** What happens when a player reports a blocker. */
745
+ failurePolicy: 'halt' | 'continue';
746
+ /** ISO timestamp of creation. */
747
+ createdAt: string;
748
+ /** Player ID of the conductor that created the stage. */
749
+ createdBy: string;
750
+ /** ISO timestamp of completion/failure/cancellation. */
751
+ completedAt?: string;
752
+ }
753
+ export interface ScheduleEntry {
754
+ /** Unique name for this schedule (used as key for add/replace/remove). */
755
+ name: string;
756
+ /** The message text to deliver when the schedule fires. */
757
+ message: string;
758
+ /** Target player name to deliver the cue to. */
759
+ target: string;
760
+ /** Player name of whoever created this schedule. */
761
+ createdBy: string;
762
+ /** ISO timestamp of the next fire time. */
763
+ nextFireAt: string;
764
+ /** Interval in milliseconds for repeating schedules. */
765
+ interval?: number;
766
+ /** ISO timestamp after which the schedule should be removed. */
767
+ until?: string;
768
+ /** Number of remaining fires (decremented each fire, removed at 0). */
769
+ remainingCount?: number;
770
+ /** Total number of times this schedule has fired. */
771
+ firedCount: number;
772
+ /** Schedule type for display purposes. */
773
+ type: 'once' | 'interval' | 'cron';
774
+ /** Cron expression string (e.g., "0 9 * * 1-5"). Stored for re-computing next fire. */
775
+ cronExpression?: string;
776
+ /** IANA timezone for cron evaluation (e.g., "America/New_York"). Defaults to UTC. */
777
+ timezone?: string;
778
+ }
779
+ /** Snapshot of a player as seen by the Maestro workflow. */
780
+ export interface MaestroPlayerInfo {
781
+ playerId: string;
782
+ ensemble: string;
783
+ part: string;
784
+ hostname: string;
785
+ workDir: string;
786
+ gitRoot?: string;
787
+ gitBranch?: string;
788
+ isConductor: boolean;
789
+ agentType: string;
790
+ playerType?: string;
791
+ /** Attachment phase (post-#177 — replaced legacy `status` field). */
792
+ phase?: AttachmentPhase;
793
+ /**
794
+ * #399 W1 (Q5.6 Flavor B) — monotonic message-activity counter from
795
+ * the session's `getActivityState` query. Maestro diffs the value
796
+ * across refreshes to compute per-player deltas for the tempo strip.
797
+ * Optional so older sessions (or query failures) degrade silently to
798
+ * zero contribution.
799
+ */
800
+ activityCount?: number;
801
+ /**
802
+ * #399 W1 (Q5.6 Flavor B) — ISO timestamp of the most recent
803
+ * activity-counter bump on the session. Currently unused by the tempo
804
+ * computation (count deltas are sufficient) but exposed for future
805
+ * surfaces that want to show "last active 12s ago" per player.
806
+ */
807
+ lastActivityAt?: string;
808
+ }
809
+ /** A message relayed through the global Maestro for dashboard visibility. */
810
+ export interface MaestroRelayMessage {
811
+ id: string;
812
+ ensemble: string;
813
+ from: string;
814
+ to: string;
815
+ text: string;
816
+ timestamp: string;
817
+ direction: 'inbound' | 'outbound';
818
+ }
819
+ /** Input for the global Maestro workflow. */
820
+ export interface GlobalMaestroInput {
821
+ /** Restored from continue-as-new. */
822
+ knownEnsembles?: string[];
823
+ /** Restored from continue-as-new. */
824
+ playersByEnsemble?: Record<string, MaestroPlayerInfo[]>;
825
+ /** Restored from continue-as-new (ring buffer, max 500). */
826
+ recentMessages?: MaestroRelayMessage[];
827
+ /** Restored from continue-as-new (ring buffer, max 500). */
828
+ events?: MaestroEvent[];
829
+ /** Restored from continue-as-new. */
830
+ pendingCommands?: MaestroPendingCommand[];
831
+ /** Refresh interval in milliseconds (default 10000). Lowered in tests. */
832
+ pollIntervalMs?: number;
833
+ /**
834
+ * #274 — `hostname → HostProfile` map maintained from daemon boot
835
+ * signals. Carried through continue-as-new alongside the other ring
836
+ * buffers. `Record` (not `Map`) so Temporal's default payload converter
837
+ * serializes it cleanly across the CAN boundary.
838
+ */
839
+ hostProfiles?: Record<string, HostProfile>;
840
+ }
841
+ /** An event generated by diffing consecutive Maestro snapshots. */
842
+ export interface MaestroEvent {
843
+ type: 'player_joined' | 'player_left' | 'status_changed' | 'part_changed';
844
+ playerId: string;
845
+ timestamp: string;
846
+ oldValue?: string;
847
+ newValue?: string;
848
+ }
849
+ /** A command queued via the maestroSendCommand update, awaiting relay. */
850
+ export interface MaestroPendingCommand {
851
+ id: string;
852
+ text: string;
853
+ source: string;
854
+ replyTo?: string;
855
+ createdAt: string;
856
+ status: 'pending' | 'delivered' | 'failed';
857
+ error?: string;
858
+ /** Ensemble to route to (used by global Maestro only). */
859
+ ensemble?: string;
860
+ }
861
+ /** A single message in the aggregated ensemble chat feed. */
862
+ export interface EnsembleChatMessage {
863
+ id: string;
864
+ from: string;
865
+ to: string;
866
+ /** Truncated to 500 chars max. Full text available via getPlayerMessages. */
867
+ text: string;
868
+ timestamp: string;
869
+ /**
870
+ * Message perspective:
871
+ * - 'maestro-out': maestro (you) sent to a player
872
+ * - 'maestro-in': a player sent to maestro (you)
873
+ * - 'conductor-out': conductor sent to a non-maestro player
874
+ * - 'conductor-in': a non-maestro player sent to conductor
875
+ */
876
+ role: 'maestro-out' | 'maestro-in' | 'conductor-out' | 'conductor-in';
877
+ /**
878
+ * #357: Mirrors {@link Message.broadcastId} / {@link SentMessage.broadcastId}.
879
+ * Same value on every fan-out target of a single `broadcast` invocation;
880
+ * the TUI's `ConversationStream` collapses consecutive entries sharing
881
+ * a non-null `broadcastId` into one row. `undefined` for non-broadcast cues.
882
+ */
883
+ broadcastId?: string;
884
+ }
885
+ /** Input for the maestroEnsembleChat query. */
886
+ export interface EnsembleChatQuery {
887
+ /** Messages to skip from the tail (default 0). */
888
+ offset?: number;
889
+ /** Max messages to return (default 50, max 200). */
890
+ limit?: number;
891
+ }
892
+ /** Result from the maestroEnsembleChat query. */
893
+ export interface EnsembleChatResult {
894
+ messages: EnsembleChatMessage[];
895
+ /** Total message count in cache. */
896
+ total: number;
897
+ /** True if messages exist beyond offset+limit. */
898
+ hasMore: boolean;
899
+ /** Whether a conductor was found during last refresh. */
900
+ hasConductor: boolean;
901
+ }
902
+ /** High-water marks for incremental chat fetch. */
903
+ export interface ChatHighWater {
904
+ maestroRecv: number;
905
+ maestroSent: number;
906
+ conductorRecv: number;
907
+ conductorSent: number;
908
+ }
909
+ /** Zero-value for ChatHighWater — use as default when no prior fetch. */
910
+ export declare const ZERO_CHAT_HIGH_WATER: ChatHighWater;
911
+ /** Input for the Maestro workflow. */
912
+ export interface MaestroInput {
913
+ ensemble: string;
914
+ /** Restored from continue-as-new. */
915
+ players?: MaestroPlayerInfo[];
916
+ /** Restored from continue-as-new (ring buffer, max 200). */
917
+ events?: MaestroEvent[];
918
+ /** Restored from continue-as-new. */
919
+ pendingCommands?: MaestroPendingCommand[];
920
+ /** Refresh interval in milliseconds (default 10000). Lowered in tests. */
921
+ pollIntervalMs?: number;
922
+ /** Restored from continue-as-new (ring buffer, max 500). */
923
+ cachedChat?: EnsembleChatMessage[];
924
+ /** Metadata about last chat refresh. */
925
+ cachedChatMeta?: {
926
+ hasConductor: boolean;
927
+ };
928
+ /** High-water marks for incremental chat fetch. */
929
+ chatHighWater?: ChatHighWater;
930
+ /** Restored from continue-as-new: ensemble-wide paused state. */
931
+ paused?: boolean;
932
+ /**
933
+ * #399 W1 (Q5.1) — ensemble description, restored across CAN.
934
+ * Empty string when unset. Updated via `setEnsembleDescriptionSignal`.
935
+ */
936
+ description?: string;
937
+ /**
938
+ * #399 W1 (Q5.3a) — ISO timestamp of the maestro's *original* first
939
+ * start. The first execution writes `workflowInfo().startTime`; every
940
+ * subsequent CAN forwards the same value so dashboard uptime stays
941
+ * monotonic across continue-as-new. Absent on the first execution.
942
+ */
943
+ startTimeIso?: string;
944
+ /**
945
+ * #399 W1 (Q5.6 Flavor B) — finished 30s activity buckets (oldest
946
+ * first, max 60). Restored across CAN so the sparkline doesn't reset
947
+ * on workflow boundary.
948
+ */
949
+ tempoHistoryBuckets?: number[];
950
+ /**
951
+ * #399 W1 (Q5.6 Flavor B) — current in-progress 30s bucket. Carried
952
+ * across CAN so a continue-as-new boundary mid-bucket doesn't lose
953
+ * accumulated activity.
954
+ */
955
+ tempoCurrentBucket?: {
956
+ startMs: number;
957
+ count: number;
958
+ };
959
+ /**
960
+ * #318 coat-check pattern — ticket-keyed stash for large content. Carried
961
+ * across CAN only when the map is non-empty (mirrors the `playerState`
962
+ * carry idiom in `src/workflows/session.ts:1617-1638`).
963
+ */
964
+ coatCheck?: Record<string, CoatCheckEntry>;
965
+ }
966
+ /**
967
+ * A single coat-check entry as stored on per-ensemble Maestro workflow
968
+ * state. `content` is opaque to the system — author-supplied markdown,
969
+ * JSON, or arbitrary text up to `COAT_CHECK_CONTENT_MAX`. All timestamps
970
+ * are ISO 8601 from `workflowNow()` for replay determinism.
971
+ *
972
+ * The `lastFetched*` / `fetchCount` triple is the fetch-audit surface
973
+ * vinceblank added on top of the architect's verdict — owners need to
974
+ * know if a recipient consumed their ticket. Default semantics: undefined
975
+ * `lastFetchedAt` + `fetchCount === 0` means "never fetched."
976
+ */
977
+ export interface CoatCheckEntry {
978
+ /** Short human-readable preamble (≤ `COAT_CHECK_SUMMARY_MAX`). */
979
+ summary: string;
980
+ /** Opaque body (≤ `COAT_CHECK_CONTENT_MAX` UTF-8 bytes). */
981
+ content: string;
982
+ /** Optional MIME-shaped hint (e.g. `'text/markdown'`); free-form. */
983
+ contentType?: string;
984
+ /** Audit identity — player who called `coat_check_put`. */
985
+ putBy: string;
986
+ /** When the entry was admitted, `workflowNow().toISOString()`. */
987
+ putAt: string;
988
+ /** When the entry expires under TTL inline-sweep, `workflowNow().toISOString()`. */
989
+ expiresAt: string;
990
+ /** UTF-8 byte length of `content` — pre-computed at put time for cheap listing. */
991
+ size: number;
992
+ /** Last successful `coat_check_get` timestamp, or undefined if never fetched. */
993
+ lastFetchedAt?: string;
994
+ /** Last `coat_check_get` caller's playerId, or undefined if never fetched. */
995
+ lastFetchedBy?: string;
996
+ /** Successful `coat_check_get` count. 0 until first fetch. */
997
+ fetchCount: number;
998
+ }
999
+ /**
1000
+ * Listing projection — `coat_check_list` and the put/evict update return
1001
+ * shapes that omit `content` so callers can survey without pulling the
1002
+ * whole body for every entry. `size` is preserved so dashboards can
1003
+ * present an at-a-glance "how big" without an extra fetch.
1004
+ */
1005
+ export interface CoatCheckEntryHeader {
1006
+ ticket: string;
1007
+ summary: string;
1008
+ contentType?: string;
1009
+ putBy: string;
1010
+ putAt: string;
1011
+ expiresAt: string;
1012
+ size: number;
1013
+ /** Mirrors `CoatCheckEntry.lastFetchedAt`. */
1014
+ lastFetchedAt?: string;
1015
+ /** Mirrors `CoatCheckEntry.lastFetchedBy`. */
1016
+ lastFetchedBy?: string;
1017
+ /** Mirrors `CoatCheckEntry.fetchCount`. */
1018
+ fetchCount: number;
1019
+ }
1020
+ export {};