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
package/dist/config.js ADDED
@@ -0,0 +1,593 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GLOBAL_MAESTRO_WORKFLOW_ID = exports.DaemonConfigSchema = exports.CleanupPolicySchema = exports.CONFIG_FILE_PATH = exports.AGENT_TEMPO_HOME = exports.PROD_DAEMON_PORT = exports.DEV_DAEMON_PORT = exports.PROD_TASK_QUEUE = exports.DEV_TASK_QUEUE = exports.PROD_TEMPORAL_NAMESPACE = exports.DEV_TEMPORAL_NAMESPACE = exports.PROD_HOME_DIR_NAME = exports.DEV_HOME_DIR_NAME = exports.ENV = void 0;
4
+ exports.isDevMode = isDevMode;
5
+ exports.resolveTempoHome = resolveTempoHome;
6
+ exports.loadDaemonConfig = loadDaemonConfig;
7
+ exports.matchEnsembleGlob = matchEnsembleGlob;
8
+ exports.isEnsembleAllowed = isEnsembleAllowed;
9
+ exports.loadConfigFile = loadConfigFile;
10
+ exports.saveConfigFile = saveConfigFile;
11
+ exports.loadTemporalCliConfig = loadTemporalCliConfig;
12
+ exports.parseTemporalYaml = parseTemporalYaml;
13
+ exports.parseAgent = parseAgent;
14
+ exports.getConfig = getConfig;
15
+ exports.getConfigWithSources = getConfigWithSources;
16
+ exports.hostTaskQueue = hostTaskQueue;
17
+ exports.sessionWorkflowId = sessionWorkflowId;
18
+ exports.conductorWorkflowId = conductorWorkflowId;
19
+ exports.schedulerWorkflowId = schedulerWorkflowId;
20
+ exports.maestroWorkflowId = maestroWorkflowId;
21
+ const fs_1 = require("fs");
22
+ const path_1 = require("path");
23
+ const os_1 = require("os");
24
+ const zod_1 = require("zod");
25
+ const validation_1 = require("./utils/validation");
26
+ // `'mock'` is a valid `AgentType` value but intentionally NOT in the resolved
27
+ // `defaultAgent` set — recruit pre-flight rejects it outside dev mode anyway,
28
+ // and it's never a sensible *default* (each mock spawn is configured per call
29
+ // via the `agent: 'mock'` flag, not via the resolved chain). Listing it here
30
+ // would only enable users to set `defaultAgent=mock` in `~/.agent-tempo/config.json`,
31
+ // which the recruit gate would then turn around and reject in production.
32
+ const VALID_AGENTS = ['claude', 'copilot'];
33
+ /** Environment variable name constants — use these instead of string literals. */
34
+ exports.ENV = {
35
+ ENSEMBLE: 'AGENT_TEMPO_ENSEMBLE',
36
+ CONDUCTOR: 'AGENT_TEMPO_CONDUCTOR',
37
+ PLAYER_NAME: 'AGENT_TEMPO_PLAYER_NAME',
38
+ TASK_QUEUE: 'AGENT_TEMPO_TASK_QUEUE',
39
+ BRIDGE_NAME: 'COPILOT_BRIDGE_NAME',
40
+ BRIDGE_MODE: 'AGENT_TEMPO_BRIDGE_MODE',
41
+ BRIDGE_MODEL: 'COPILOT_BRIDGE_MODEL',
42
+ BRIDGE_SESSION_ID: 'COPILOT_BRIDGE_SESSION_ID',
43
+ TEMPORAL_ADDRESS: 'TEMPORAL_ADDRESS',
44
+ TEMPORAL_NAMESPACE: 'TEMPORAL_NAMESPACE',
45
+ TEMPORAL_API_KEY: 'TEMPORAL_API_KEY',
46
+ TEMPORAL_TLS_CERT_PATH: 'TEMPORAL_TLS_CERT_PATH',
47
+ TEMPORAL_TLS_KEY_PATH: 'TEMPORAL_TLS_KEY_PATH',
48
+ DEFAULT_AGENT: 'AGENT_TEMPO_DEFAULT_AGENT',
49
+ PLAYER_TYPE: 'AGENT_TEMPO_PLAYER_TYPE',
50
+ CLAUDE_BIN: 'AGENT_TEMPO_CLAUDE_BIN',
51
+ /**
52
+ * #131 Phase C — claude-api adapter model override. Recruit-arg takes
53
+ * precedence; this env var is the next fallback before the constants-pinned
54
+ * default (`claude-opus-4-7`). Ignored by other adapters.
55
+ */
56
+ API_MODEL: 'AGENT_TEMPO_API_MODEL',
57
+ /**
58
+ * #449 Phase C — opencode adapter model override. Distinct from
59
+ * `API_MODEL` to keep namespaces clean: claude-api is Anthropic-only
60
+ * with bare model ids (`claude-opus-4-7`); opencode takes combined
61
+ * `provider/model` strings (`anthropic/claude-opus-4-7`,
62
+ * `openai/gpt-4o`, `ollama/llama3`, …). Recruit-arg precedence:
63
+ * recruit `model` arg → this env var → `DEFAULT_MODEL` constant.
64
+ */
65
+ OPENCODE_MODEL: 'AGENT_TEMPO_OPENCODE_MODEL',
66
+ /**
67
+ * #520 — claude-code-headless permission mode. Forwarded to `claude -p
68
+ * --permission-mode <mode>`. Recruit-arg `permissionMode` takes precedence;
69
+ * this env var is the fallback before the constants-pinned default
70
+ * (`'acceptEdits'`). Mutually exclusive with
71
+ * {@link DANGEROUSLY_SKIP_PERMISSIONS}.
72
+ */
73
+ PERMISSION_MODE: 'AGENT_TEMPO_PERMISSION_MODE',
74
+ /**
75
+ * #520 — claude-code-headless dangerous-skip-permissions opt-in. When set
76
+ * to `'1'`, the adapter passes `--dangerously-skip-permissions` to
77
+ * `claude -p` instead of `--permission-mode`. Use only in trusted /
78
+ * sandboxed contexts. Mutually exclusive with {@link PERMISSION_MODE}.
79
+ */
80
+ DANGEROUSLY_SKIP_PERMISSIONS: 'AGENT_TEMPO_DANGEROUSLY_SKIP_PERMISSIONS',
81
+ /**
82
+ * v0.25 PR-D attachment resume plumbing. When `restart` / `migrate`
83
+ * enqueues a spawn outbox entry, the workflow passes the pre-claimed
84
+ * `attachmentId` + pinned `runId` + resolved `adapterId` through the spawn
85
+ * activity into the child process env. The child's adapter reads these in
86
+ * `startV2Lifecycle` to renew (rather than freshly claim) the existing lease,
87
+ * so there is no race window between the workflow's claim and the adapter
88
+ * boot. Absent on first-recruit spawn (fresh claim path).
89
+ */
90
+ ATTACHMENT_ID: 'AGENT_TEMPO_ATTACHMENT_ID',
91
+ ATTACHMENT_RUN_ID: 'AGENT_TEMPO_ATTACHMENT_RUN_ID',
92
+ ADAPTER_ID: 'AGENT_TEMPO_ADAPTER_ID',
93
+ /**
94
+ * Daemon HTTP/SSE event source (#94, #95). See SSE-PROTOCOL.md §1, §3.
95
+ * `HTTP_BIND` defaults to `127.0.0.1`. Setting to `0.0.0.0` forces
96
+ * bearer mode. `DAEMON_PORT` defaults to `8473` (the `t-e-m-p-o`
97
+ * mnemonic; not IANA-registered). `CORS_ORIGINS` is a comma-separated
98
+ * explicit allowlist (no wildcards) — only consulted in bearer mode.
99
+ * `SSE_MAX_CONNECTIONS` caps live SSE subscribers (PR-2; defaults 100).
100
+ */
101
+ HTTP_BIND: 'AGENT_TEMPO_HTTP_BIND',
102
+ DAEMON_PORT: 'AGENT_TEMPO_DAEMON_PORT',
103
+ CORS_ORIGINS: 'AGENT_TEMPO_CORS_ORIGINS',
104
+ SSE_MAX_CONNECTIONS: 'AGENT_TEMPO_SSE_MAX_CONNECTIONS',
105
+ /**
106
+ * Dev profile gate (ADR 0014 §5.2). One source of truth — every layer
107
+ * (paths, namespace, port, task queue, banner, registry gating) consults
108
+ * `isDevMode()` rather than reading the env var directly. The `--dev`
109
+ * top-level CLI flag in `src/cli.ts` sets this to `'1'` before any other
110
+ * module loads (see `src/cli/dev-mode-bootstrap.ts`).
111
+ */
112
+ DEV_MODE: 'AGENT_TEMPO_DEV_MODE',
113
+ /**
114
+ * Escape hatch for triple-isolated environments (ADR 0014 §5.3). When
115
+ * set, `resolveTempoHome()` returns this path verbatim — bypassing both
116
+ * the production default and the dev-mode default. Lets a power user
117
+ * coordinate three or more parallel agent-tempo profiles on one box.
118
+ */
119
+ DEV_HOME_OVERRIDE: 'AGENT_TEMPO_HOME_OVERRIDE',
120
+ };
121
+ // ── Dev profile (ADR 0014 §5) ──
122
+ /**
123
+ * Dev profile defaults — one switch (`--dev` top-level flag, or
124
+ * `AGENT_TEMPO_DEV_MODE=1` env var) flips four isolation axes at once
125
+ * (ADR 0014 §5.1). Production stays on the existing defaults.
126
+ */
127
+ exports.DEV_HOME_DIR_NAME = '.agent-tempo-dev';
128
+ exports.PROD_HOME_DIR_NAME = '.agent-tempo';
129
+ exports.DEV_TEMPORAL_NAMESPACE = 'agent-tempo-dev';
130
+ exports.PROD_TEMPORAL_NAMESPACE = 'default';
131
+ exports.DEV_TASK_QUEUE = 'agent-tempo-dev';
132
+ exports.PROD_TASK_QUEUE = 'agent-tempo';
133
+ exports.DEV_DAEMON_PORT = 8474;
134
+ exports.PROD_DAEMON_PORT = 8473;
135
+ /**
136
+ * Single source of truth for the dev profile gate (ADR 0014 §5.2).
137
+ * Every layer that needs to switch behaviour consults this helper; future
138
+ * staging/ci/demo profiles would follow the same `isStagingMode()` pattern.
139
+ *
140
+ * Recognises `'1'` and `'true'` (case-insensitive) so users can write
141
+ * either `AGENT_TEMPO_DEV_MODE=1` or `AGENT_TEMPO_DEV_MODE=true`. Any
142
+ * other value (including the empty string) is treated as production.
143
+ *
144
+ * **Important**: when the `--dev` CLI flag is used, the env var must be
145
+ * set BEFORE `src/config.ts` is first imported (see
146
+ * `src/cli/dev-mode-bootstrap.ts`) so the module-load-time `AGENT_TEMPO_HOME`
147
+ * constant resolves to the dev profile.
148
+ */
149
+ function isDevMode() {
150
+ const v = process.env[exports.ENV.DEV_MODE];
151
+ if (!v)
152
+ return false;
153
+ return v === '1' || v.toLowerCase() === 'true';
154
+ }
155
+ /**
156
+ * Resolve the agent-tempo home directory. Three-tier precedence:
157
+ * 1. `AGENT_TEMPO_HOME_OVERRIDE` env — explicit override (multi-isolation
158
+ * escape hatch; ADR 0014 §5.3).
159
+ * 2. Dev mode (`AGENT_TEMPO_DEV_MODE=1`): `~/.agent-tempo-dev/`.
160
+ * 3. Production default: `~/.agent-tempo/`.
161
+ *
162
+ * Evaluated once at module load time; downstream callers consume the
163
+ * exported `AGENT_TEMPO_HOME` constant. The bootstrap module guarantees
164
+ * the env var is set before this function first runs.
165
+ *
166
+ * Exported (rather than file-private) so unit tests can exercise the
167
+ * three-tier precedence directly without resorting to `vi.resetModules()`
168
+ * gymnastics. Production code should consume {@link AGENT_TEMPO_HOME}
169
+ * — calling this helper per-request would re-read env on every call.
170
+ */
171
+ function resolveTempoHome() {
172
+ const override = process.env[exports.ENV.DEV_HOME_OVERRIDE];
173
+ if (override)
174
+ return override;
175
+ return isDevMode()
176
+ ? (0, path_1.join)((0, os_1.homedir)(), exports.DEV_HOME_DIR_NAME)
177
+ : (0, path_1.join)((0, os_1.homedir)(), exports.PROD_HOME_DIR_NAME);
178
+ }
179
+ exports.AGENT_TEMPO_HOME = resolveTempoHome();
180
+ exports.CONFIG_FILE_PATH = (0, path_1.join)(exports.AGENT_TEMPO_HOME, 'config.json');
181
+ // ── Daemon config (PR-E design §10.2) ──
182
+ /**
183
+ * Daemon-level configuration persisted in `~/.agent-tempo/config.json`
184
+ * alongside the existing `PersistedConfig` fields.
185
+ *
186
+ * `restorePolicy` is the effective off-switch for daemon reconcile-on-boot
187
+ * auto-restore — there is no feature flag. `"never"` disables all automatic
188
+ * restoration and leaves the CLI `restore` command as the sole revive path.
189
+ */
190
+ exports.CleanupPolicySchema = zod_1.z.object({
191
+ detachedMaxAgeDays: zod_1.z.number().int().positive().default(7),
192
+ destroyedMaxAgeDays: zod_1.z.number().int().positive().default(30),
193
+ }).default({ detachedMaxAgeDays: 7, destroyedMaxAgeDays: 30 });
194
+ exports.DaemonConfigSchema = zod_1.z.object({
195
+ restorePolicy: zod_1.z.enum(['auto', 'prompt', 'never']).default('prompt'),
196
+ autoRestoreMaxAgeHours: zod_1.z.number().positive().default(24),
197
+ /**
198
+ * Ensemble allowlist for `auto` restore. Empty array means "all ensembles
199
+ * allowed". Each entry is a simple prefix match: trailing `*` is stripped
200
+ * and the remaining string is compared with `String.startsWith()`. Entries
201
+ * without trailing `*` are exact matches. See {@link matchEnsembleGlob}.
202
+ */
203
+ autoRestoreEnsembles: zod_1.z.array(zod_1.z.string()).default([]),
204
+ cleanupPolicy: exports.CleanupPolicySchema,
205
+ }).default({
206
+ restorePolicy: 'prompt',
207
+ autoRestoreMaxAgeHours: 24,
208
+ autoRestoreEnsembles: [],
209
+ cleanupPolicy: { detachedMaxAgeDays: 7, destroyedMaxAgeDays: 30 },
210
+ });
211
+ /**
212
+ * Load `~/.agent-tempo/config.json` and extract the daemon-level fields.
213
+ * Returns fully-defaulted `DaemonConfig` if the file is missing, unreadable,
214
+ * or contains no daemon fields. Partial configs (user sets one field only)
215
+ * merge with defaults via Zod's `.default()` per-field behaviour.
216
+ *
217
+ * Invalid JSON logs a warning and falls back to defaults rather than
218
+ * crashing — the daemon must boot even if the user has a mangled config.
219
+ */
220
+ function loadDaemonConfig() {
221
+ try {
222
+ if (!(0, fs_1.existsSync)(exports.CONFIG_FILE_PATH)) {
223
+ return exports.DaemonConfigSchema.parse({});
224
+ }
225
+ const raw = JSON.parse((0, fs_1.readFileSync)(exports.CONFIG_FILE_PATH, 'utf8'));
226
+ // The file may contain unrelated `PersistedConfig` fields — pick only
227
+ // the daemon-relevant ones. Unknown fields are ignored by Zod's default
228
+ // `.object()` schema (strip mode), which is what we want.
229
+ const result = exports.DaemonConfigSchema.safeParse(raw);
230
+ if (result.success)
231
+ return result.data;
232
+ console.error('[agent-tempo] Invalid daemon config; using defaults.', result.error.format());
233
+ return exports.DaemonConfigSchema.parse({});
234
+ }
235
+ catch (err) {
236
+ console.error('[agent-tempo] Could not read daemon config; using defaults:', err instanceof Error ? err.message : String(err));
237
+ return exports.DaemonConfigSchema.parse({});
238
+ }
239
+ }
240
+ /**
241
+ * Simple-prefix ensemble match — PR-E §8 answer 5. No glob library dep.
242
+ *
243
+ * - Pattern ends with `*` → strip the `*`, match by `ensemble.startsWith(prefix)`.
244
+ * - Pattern without trailing `*` → exact equality.
245
+ * - Empty pattern list → allow all (caller decides; this helper returns `false`).
246
+ */
247
+ function matchEnsembleGlob(ensemble, pattern) {
248
+ if (pattern.endsWith('*')) {
249
+ const prefix = pattern.slice(0, -1);
250
+ return ensemble.startsWith(prefix);
251
+ }
252
+ return ensemble === pattern;
253
+ }
254
+ /**
255
+ * Check an ensemble name against a list of patterns.
256
+ * Empty list → allow all (returns `true`).
257
+ * Any matching pattern → allow (returns `true`).
258
+ * No matches → deny (returns `false`).
259
+ */
260
+ function isEnsembleAllowed(ensemble, allowlist) {
261
+ if (allowlist.length === 0)
262
+ return true;
263
+ return allowlist.some((p) => matchEnsembleGlob(ensemble, p));
264
+ }
265
+ /** Load ~/.agent-tempo/config.json if it exists. */
266
+ function loadConfigFile() {
267
+ try {
268
+ if ((0, fs_1.existsSync)(exports.CONFIG_FILE_PATH)) {
269
+ return JSON.parse((0, fs_1.readFileSync)(exports.CONFIG_FILE_PATH, 'utf8'));
270
+ }
271
+ }
272
+ catch {
273
+ // Corrupt file — warn but don't crash
274
+ console.error(`[agent-tempo] Warning: could not parse ${exports.CONFIG_FILE_PATH} — ignoring config file`);
275
+ }
276
+ return {};
277
+ }
278
+ /** Save config to ~/.agent-tempo/config.json with restrictive permissions. */
279
+ function saveConfigFile(config) {
280
+ const { writeFileSync, chmodSync } = require('fs');
281
+ (0, fs_1.mkdirSync)(exports.AGENT_TEMPO_HOME, { recursive: true });
282
+ writeFileSync(exports.CONFIG_FILE_PATH, JSON.stringify(config, null, 2) + '\n');
283
+ // Restrict permissions to owner-only (like aws credentials, gh hosts.yml)
284
+ if (process.platform !== 'win32') {
285
+ try {
286
+ chmodSync(exports.CONFIG_FILE_PATH, 0o600);
287
+ }
288
+ catch { /* best effort */ }
289
+ }
290
+ }
291
+ /**
292
+ * Load Temporal CLI config from ~/.config/temporalio/temporal.yaml as a fallback.
293
+ * The Temporal CLI stores named environments there. We read the active environment
294
+ * or the first one we find.
295
+ *
296
+ * Format is simple YAML — we parse it with basic string operations.
297
+ */
298
+ function loadTemporalCliConfig() {
299
+ const candidates = [
300
+ (0, path_1.join)((0, os_1.homedir)(), '.config', 'temporalio', 'temporal.yaml'),
301
+ (0, path_1.join)((0, os_1.homedir)(), '.config', 'temporalio', 'temporal.yml'),
302
+ ];
303
+ for (const filePath of candidates) {
304
+ try {
305
+ if (!(0, fs_1.existsSync)(filePath))
306
+ continue;
307
+ const content = (0, fs_1.readFileSync)(filePath, 'utf8');
308
+ return parseTemporalYaml(content);
309
+ }
310
+ catch {
311
+ // ignore
312
+ }
313
+ }
314
+ return {};
315
+ }
316
+ /**
317
+ * Minimal YAML parser for Temporal CLI config files.
318
+ * Handles the subset of YAML used by the Temporal CLI:
319
+ * active-env: local
320
+ * env:
321
+ * local:
322
+ * address: localhost:7233
323
+ * namespace: default
324
+ * api-key: ...
325
+ * tls-cert-path: ...
326
+ * tls-key-path: ...
327
+ */
328
+ function parseTemporalYaml(content) {
329
+ // Normalize CRLF to LF and tabs to spaces for consistent parsing
330
+ const lines = content.replace(/\r\n/g, '\n').replace(/\t/g, ' ').split('\n');
331
+ const result = {};
332
+ // Find the active environment name
333
+ let activeEnv = '';
334
+ for (const line of lines) {
335
+ const match = line.match(/^active-env:\s*(.+)/);
336
+ if (match) {
337
+ activeEnv = match[1].trim();
338
+ break;
339
+ }
340
+ }
341
+ // Find the env block and the active (or first) environment
342
+ let inEnv = false;
343
+ let targetEnvName = activeEnv;
344
+ let inTargetEnv = false;
345
+ for (const line of lines) {
346
+ const stripped = line.trimEnd();
347
+ // Top-level "env:" key
348
+ if (/^env:\s*$/.test(stripped)) {
349
+ inEnv = true;
350
+ continue;
351
+ }
352
+ if (!inEnv)
353
+ continue;
354
+ // Back to top-level (non-indented, non-empty line that isn't part of env block)
355
+ if (stripped.length > 0 && !stripped.startsWith(' ')) {
356
+ break;
357
+ }
358
+ // Environment name (2-space indent, may contain dots like "my-ns.abc123")
359
+ const envMatch = stripped.match(/^ ([a-zA-Z0-9_.:-]+):\s*$/);
360
+ if (envMatch) {
361
+ const currentEnvName = envMatch[1];
362
+ // If no active env specified, use the first one
363
+ if (!targetEnvName)
364
+ targetEnvName = currentEnvName;
365
+ inTargetEnv = currentEnvName === targetEnvName;
366
+ continue;
367
+ }
368
+ if (!inTargetEnv)
369
+ continue;
370
+ // Key-value pairs (4+ space indent)
371
+ const kvMatch = stripped.match(/^\s{4,}([a-z-]+):\s*(.+)/);
372
+ if (kvMatch) {
373
+ const [, key, value] = kvMatch;
374
+ const val = value.trim().replace(/^['"]|['"]$/g, ''); // strip quotes
375
+ switch (key) {
376
+ case 'address':
377
+ result.temporalAddress = val;
378
+ break;
379
+ case 'namespace':
380
+ result.temporalNamespace = val;
381
+ break;
382
+ case 'api-key':
383
+ result.temporalApiKey = val;
384
+ break;
385
+ case 'tls-cert-path':
386
+ result.temporalTlsCertPath = val;
387
+ break;
388
+ case 'tls-key-path':
389
+ result.temporalTlsKeyPath = val;
390
+ break;
391
+ }
392
+ }
393
+ }
394
+ return result;
395
+ }
396
+ /**
397
+ * Human-readable source labels for `defaultAgent` validation errors.
398
+ * Single source of truth shared by {@link parseAgent} callers; keeps the
399
+ * "invalid value" error message and the `config show` source column aligned.
400
+ */
401
+ const AGENT_SOURCE_LABELS = {
402
+ flag: '--agent CLI flag',
403
+ env: `${exports.ENV.DEFAULT_AGENT} env var`,
404
+ config: `defaultAgent in ${exports.CONFIG_FILE_PATH}`,
405
+ 'temporal-cli': 'Temporal CLI config',
406
+ default: 'default',
407
+ none: 'none',
408
+ };
409
+ /**
410
+ * Parse an agent value against the {@link AgentType} union.
411
+ * Throws when `value` is present but not a valid agent; returns `'claude'`
412
+ * for empty/unset values so callers can use it as a source-aware default.
413
+ */
414
+ function parseAgent(value, source) {
415
+ if (value == null || value === '')
416
+ return 'claude';
417
+ if (!VALID_AGENTS.includes(value)) {
418
+ throw new Error(`Invalid agent "${value}" from ${AGENT_SOURCE_LABELS[source]}. ` +
419
+ `Valid values: ${VALID_AGENTS.join(', ')}.`);
420
+ }
421
+ return value;
422
+ }
423
+ /**
424
+ * Resolve `defaultAgent` through the standard precedence chain and validate
425
+ * against the {@link AgentType} union. Each step passes its own source tag
426
+ * so `parseAgent` error messages point at the offending origin.
427
+ */
428
+ function resolveDefaultAgent(cliVal, configFileVal) {
429
+ if (cliVal)
430
+ return parseAgent(cliVal, 'flag');
431
+ const envVal = process.env[exports.ENV.DEFAULT_AGENT];
432
+ if (envVal)
433
+ return parseAgent(envVal, 'env');
434
+ if (configFileVal)
435
+ return parseAgent(configFileVal, 'config');
436
+ return 'claude';
437
+ }
438
+ /**
439
+ * Env vars that bleed a user's shell-wide Temporal config into the dev
440
+ * profile, defeating its isolation guarantee. In dev mode, reads of these
441
+ * keys via {@link readEnvWithDevCarveOut} return `undefined` — same shape
442
+ * the existing temporal-cli yaml drop already uses for namespace.
443
+ *
444
+ * Carve-out is per architect Q1 in `docs/design/dev-mode-isolation-fix-423.md`:
445
+ * NAMESPACE + ADDRESS are leaks; `TEMPORAL_API_KEY` + `TEMPORAL_TLS_*`
446
+ * are per-credential and stay honored in both modes.
447
+ *
448
+ * Module-level constant so neither `getConfig` nor `getConfigWithSources`
449
+ * allocates a Set on every call.
450
+ */
451
+ const DEV_ENV_CARVE_OUT = new Set([
452
+ exports.ENV.TEMPORAL_NAMESPACE,
453
+ exports.ENV.TEMPORAL_ADDRESS,
454
+ ]);
455
+ /**
456
+ * Read `process.env[key]` honoring the dev-mode carve-out. Returns
457
+ * `undefined` for carved-out keys when dev mode is active so the
458
+ * resolution chain falls through to the next source.
459
+ */
460
+ function readEnvWithDevCarveOut(key) {
461
+ if (isDevMode() && DEV_ENV_CARVE_OUT.has(key))
462
+ return undefined;
463
+ return process.env[key];
464
+ }
465
+ /**
466
+ * Build a resolved Config using the priority chain:
467
+ * CLI flag > env var > agent-tempo config file > temporal CLI config > defaults
468
+ *
469
+ * In dev mode, `TEMPORAL_NAMESPACE` and `TEMPORAL_ADDRESS` env vars are
470
+ * dropped from the chain — see {@link DEV_ENV_CARVE_OUT}.
471
+ */
472
+ function getConfig(overrides = {}) {
473
+ const temporalCli = loadTemporalCliConfig();
474
+ const configFile = loadConfigFile();
475
+ const resolve = (cliVal, envKey, fileVal, temporalCliVal, defaultVal) => {
476
+ return cliVal || readEnvWithDevCarveOut(envKey) || fileVal || temporalCliVal || defaultVal;
477
+ };
478
+ const resolveOpt = (cliVal, envKey, fileVal, temporalCliVal) => {
479
+ return cliVal || readEnvWithDevCarveOut(envKey) || fileVal || temporalCliVal || undefined;
480
+ };
481
+ const config = {
482
+ temporalAddress: resolve(overrides.temporalAddress, exports.ENV.TEMPORAL_ADDRESS, configFile.temporalAddress, temporalCli.temporalAddress, 'localhost:7233'),
483
+ temporalNamespace: resolve(overrides.temporalNamespace, exports.ENV.TEMPORAL_NAMESPACE, configFile.temporalNamespace,
484
+ // ADR 0014 §5.1: dev profile flips the namespace default. CLI flag and
485
+ // the dev profile's own agent-tempo config file
486
+ // (`~/.agent-tempo-dev/config.json`) still win — but the
487
+ // `TEMPORAL_NAMESPACE` env var (carved out above) and
488
+ // `~/.config/temporalio/temporal.yaml` are intentionally ignored in
489
+ // dev mode. Both capture the user's *default* Temporal environment
490
+ // for ad-hoc CLI work; letting either bleed through would defeat the
491
+ // dev profile's isolation guarantee (a user with `namespace: default`
492
+ // would see the dev daemon connect to prod). Explicit per-invocation
493
+ // overrides (CLI flag, dev config.json) remain available.
494
+ isDevMode() ? undefined : temporalCli.temporalNamespace, isDevMode() ? exports.DEV_TEMPORAL_NAMESPACE : exports.PROD_TEMPORAL_NAMESPACE),
495
+ temporalApiKey: resolveOpt(overrides.temporalApiKey, exports.ENV.TEMPORAL_API_KEY, configFile.temporalApiKey, temporalCli.temporalApiKey),
496
+ temporalTlsCertPath: resolveOpt(overrides.temporalTlsCertPath, exports.ENV.TEMPORAL_TLS_CERT_PATH, configFile.temporalTlsCertPath, temporalCli.temporalTlsCertPath),
497
+ temporalTlsKeyPath: resolveOpt(overrides.temporalTlsKeyPath, exports.ENV.TEMPORAL_TLS_KEY_PATH, configFile.temporalTlsKeyPath, temporalCli.temporalTlsKeyPath),
498
+ defaultAgent: resolveDefaultAgent(overrides.defaultAgent, configFile.defaultAgent),
499
+ claudeBin: process.env[exports.ENV.CLAUDE_BIN] || configFile.claudeBin || undefined,
500
+ // ADR 0014 §5.1: dev profile shifts the default task queue. Explicit
501
+ // env-var override still wins.
502
+ taskQueue: process.env[exports.ENV.TASK_QUEUE] ?? (isDevMode() ? exports.DEV_TASK_QUEUE : exports.PROD_TASK_QUEUE),
503
+ ensemble: process.env[exports.ENV.ENSEMBLE] ?? 'default',
504
+ };
505
+ const ensembleError = (0, validation_1.validateEnsembleName)(config.ensemble);
506
+ if (ensembleError) {
507
+ throw new Error(ensembleError);
508
+ }
509
+ return config;
510
+ }
511
+ /**
512
+ * Like getConfig(), but also returns which source each value came from.
513
+ * Used by `agent-tempo config show` to help users debug.
514
+ *
515
+ * Mirrors {@link getConfig}'s dev-mode env-var carve-out — without this
516
+ * parity the user would see `env: TEMPORAL_NAMESPACE=default` in
517
+ * `config show` while the daemon happily ignores it.
518
+ */
519
+ function getConfigWithSources(overrides = {}) {
520
+ const temporalCli = loadTemporalCliConfig();
521
+ const configFile = loadConfigFile();
522
+ function resolveWithSource(
523
+ // Documentation-only label preserved at call sites for readability;
524
+ // not used inside the body. Prefixed `_` to signal intentional non-use.
525
+ _key, cliVal, envKey, fileVal, temporalCliVal, defaultVal) {
526
+ if (cliVal)
527
+ return { value: cliVal, source: 'flag' };
528
+ const envVal = readEnvWithDevCarveOut(envKey);
529
+ if (envVal)
530
+ return { value: envVal, source: 'env' };
531
+ if (fileVal)
532
+ return { value: fileVal, source: 'config' };
533
+ if (temporalCliVal)
534
+ return { value: temporalCliVal, source: 'temporal-cli' };
535
+ if (defaultVal)
536
+ return { value: defaultVal, source: 'default' };
537
+ return { value: undefined, source: 'none' };
538
+ }
539
+ const address = resolveWithSource('temporalAddress', overrides.temporalAddress, exports.ENV.TEMPORAL_ADDRESS, configFile.temporalAddress, temporalCli.temporalAddress, 'localhost:7233');
540
+ const namespace = resolveWithSource('temporalNamespace', overrides.temporalNamespace, exports.ENV.TEMPORAL_NAMESPACE, configFile.temporalNamespace,
541
+ // ADR 0014 §5.1 — temporal-cli fallback is dropped in dev mode for the
542
+ // same isolation reason documented in `getConfig` above.
543
+ isDevMode() ? undefined : temporalCli.temporalNamespace, isDevMode() ? exports.DEV_TEMPORAL_NAMESPACE : exports.PROD_TEMPORAL_NAMESPACE);
544
+ const apiKey = resolveWithSource('temporalApiKey', overrides.temporalApiKey, exports.ENV.TEMPORAL_API_KEY, configFile.temporalApiKey, temporalCli.temporalApiKey);
545
+ const tlsCert = resolveWithSource('temporalTlsCertPath', overrides.temporalTlsCertPath, exports.ENV.TEMPORAL_TLS_CERT_PATH, configFile.temporalTlsCertPath, temporalCli.temporalTlsCertPath);
546
+ const tlsKey = resolveWithSource('temporalTlsKeyPath', overrides.temporalTlsKeyPath, exports.ENV.TEMPORAL_TLS_KEY_PATH, configFile.temporalTlsKeyPath, temporalCli.temporalTlsKeyPath);
547
+ const defaultAgent = resolveWithSource('defaultAgent', overrides.defaultAgent, exports.ENV.DEFAULT_AGENT, configFile.defaultAgent, undefined, 'claude');
548
+ const claudeBin = resolveWithSource('claudeBin', undefined, exports.ENV.CLAUDE_BIN, configFile.claudeBin, undefined);
549
+ return {
550
+ config: {
551
+ temporalAddress: address.value,
552
+ temporalNamespace: namespace.value,
553
+ temporalApiKey: apiKey.value,
554
+ temporalTlsCertPath: tlsCert.value,
555
+ temporalTlsKeyPath: tlsKey.value,
556
+ defaultAgent: parseAgent(defaultAgent.value, defaultAgent.source),
557
+ claudeBin: claudeBin.value,
558
+ taskQueue: process.env[exports.ENV.TASK_QUEUE] ?? (isDevMode() ? exports.DEV_TASK_QUEUE : exports.PROD_TASK_QUEUE),
559
+ ensemble: process.env[exports.ENV.ENSEMBLE] ?? 'default',
560
+ },
561
+ sources: {
562
+ temporalAddress: address.source,
563
+ temporalNamespace: namespace.source,
564
+ temporalApiKey: apiKey.source,
565
+ temporalTlsCertPath: tlsCert.source,
566
+ temporalTlsKeyPath: tlsKey.source,
567
+ defaultAgent: defaultAgent.source,
568
+ claudeBin: claudeBin.source,
569
+ },
570
+ };
571
+ }
572
+ /** Build a per-host task queue name for cross-machine activities: {taskQueue}-{hostname} */
573
+ function hostTaskQueue(taskQueue, hostname) {
574
+ return `${taskQueue}-${hostname}`;
575
+ }
576
+ /** Build a workflow ID for a player session: agent-session-{ensemble}-{playerId} */
577
+ function sessionWorkflowId(ensemble, playerId) {
578
+ return `agent-session-${ensemble}-${playerId}`;
579
+ }
580
+ /** Build a workflow ID for a conductor: agent-session-{ensemble}-conductor */
581
+ function conductorWorkflowId(ensemble) {
582
+ return `agent-session-${ensemble}-conductor`;
583
+ }
584
+ /** Build a workflow ID for the scheduler: agent-scheduler-{ensemble} */
585
+ function schedulerWorkflowId(ensemble) {
586
+ return `agent-scheduler-${ensemble}`;
587
+ }
588
+ /** Build a workflow ID for the Maestro: agent-maestro-{ensemble} */
589
+ function maestroWorkflowId(ensemble) {
590
+ return `agent-maestro-${ensemble}`;
591
+ }
592
+ /** Workflow ID for the single global Maestro instance. */
593
+ exports.GLOBAL_MAESTRO_WORKFLOW_ID = 'agent-maestro-global';
@@ -0,0 +1,7 @@
1
+ import { Connection } from '@temporalio/client';
2
+ import { NativeConnection } from '@temporalio/worker';
3
+ import { Config } from './config';
4
+ /** Create a Temporal Client connection (for Client use in tools, CLI commands, etc.). */
5
+ export declare function createTemporalConnection(config: Config): Promise<Connection>;
6
+ /** Create a Temporal NativeConnection (for Worker use). */
7
+ export declare function createTemporalNativeConnection(config: Config): Promise<NativeConnection>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTemporalConnection = createTemporalConnection;
4
+ exports.createTemporalNativeConnection = createTemporalNativeConnection;
5
+ const fs_1 = require("fs");
6
+ const client_1 = require("@temporalio/client");
7
+ const worker_1 = require("@temporalio/worker");
8
+ /** Build TLS + metadata options from config for Temporal connections. */
9
+ function buildConnectionOptions(config) {
10
+ const opts = {
11
+ address: config.temporalAddress,
12
+ };
13
+ // mTLS certificate pair
14
+ if (config.temporalTlsCertPath && config.temporalTlsKeyPath) {
15
+ // Validate cert/key files exist before attempting to read
16
+ if (!(0, fs_1.existsSync)(config.temporalTlsCertPath)) {
17
+ throw new Error(`TLS certificate file not found: ${config.temporalTlsCertPath} (TEMPORAL_TLS_CERT_PATH)`);
18
+ }
19
+ if (!(0, fs_1.existsSync)(config.temporalTlsKeyPath)) {
20
+ throw new Error(`TLS key file not found: ${config.temporalTlsKeyPath} (TEMPORAL_TLS_KEY_PATH)`);
21
+ }
22
+ opts.tls = {
23
+ clientCertPair: {
24
+ crt: (0, fs_1.readFileSync)(config.temporalTlsCertPath),
25
+ key: (0, fs_1.readFileSync)(config.temporalTlsKeyPath),
26
+ },
27
+ };
28
+ }
29
+ // API key auth (Temporal Cloud)
30
+ if (config.temporalApiKey) {
31
+ opts.apiKey = config.temporalApiKey;
32
+ // API key requires TLS — if no client cert pair, enable server-only TLS
33
+ if (!opts.tls) {
34
+ opts.tls = true;
35
+ }
36
+ }
37
+ return opts;
38
+ }
39
+ /** Create a Temporal Client connection (for Client use in tools, CLI commands, etc.). */
40
+ async function createTemporalConnection(config) {
41
+ return client_1.Connection.connect(buildConnectionOptions(config));
42
+ }
43
+ /** Create a Temporal NativeConnection (for Worker use). */
44
+ async function createTemporalNativeConnection(config) {
45
+ return worker_1.NativeConnection.connect(buildConnectionOptions(config));
46
+ }