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,641 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.readCache = readCache;
37
+ exports.writeCache = writeCache;
38
+ exports.isCacheFresh = isCacheFresh;
39
+ exports.classifyVersion = classifyVersion;
40
+ exports.bootstrap = bootstrap;
41
+ /**
42
+ * Auto-provisioning bootstrap state machine (#289 / S7 of #285).
43
+ *
44
+ * Bare `agent-tempo` invocation runs this on the way to the TUI. Six steps
45
+ * get the user from "nothing installed" → "ready for the TUI home view";
46
+ * each step is idempotent and cached where safe so a warm system completes
47
+ * in <50ms (steps 1–5) and a cold system stays under ~200ms.
48
+ *
49
+ * Step 7 is the caller's TUI handoff (`src/cli.ts` default path) — this
50
+ * module only produces the `BootstrapResult` that the TUI consumes as
51
+ * initial props.
52
+ *
53
+ * Per-step caching (`~/.agent-tempo/.bootstrap-cache.json`) is keyed by
54
+ * `schemaVersion` + `binaryVersion` so an upgrade wipes the cache and the
55
+ * new binary re-validates everything. Steps with volatile state (daemon
56
+ * liveness, orphan count) are never cached.
57
+ *
58
+ * No auto-resume on bare invocation (#289 pin item 1) — the home view is
59
+ * responsible for letting the user pick a parked ensemble to restore. Step
60
+ * 6 prefetches the ensemble list so the TUI renders instantly.
61
+ */
62
+ const perf_hooks_1 = require("perf_hooks");
63
+ const child_process_1 = require("child_process");
64
+ const fs = __importStar(require("fs"));
65
+ const path = __importStar(require("path"));
66
+ const semver = __importStar(require("semver"));
67
+ const client_1 = require("@temporalio/client");
68
+ const config_1 = require("../config");
69
+ const connection_1 = require("../connection");
70
+ const mcp_1 = require("./mcp");
71
+ const daemon_1 = require("./daemon");
72
+ const orphans_1 = require("../reconcile/orphans");
73
+ const client_2 = require("../client");
74
+ const os_1 = require("os");
75
+ const git_info_1 = require("../git-info");
76
+ const legacy_migration_1 = require("./legacy-migration");
77
+ // ─────────────────────────────────────────────────────────────────────────
78
+ // Cache (schema v1)
79
+ // ─────────────────────────────────────────────────────────────────────────
80
+ const CACHE_SCHEMA_VERSION = 1;
81
+ const CACHE_FILENAME = '.bootstrap-cache.json';
82
+ function defaultCache(binaryVersion) {
83
+ return { schemaVersion: CACHE_SCHEMA_VERSION, binaryVersion, steps: {} };
84
+ }
85
+ /** Read the cache, validating schema + binary version. Any failure returns
86
+ * a fresh empty cache — malformed / upgrade-mismatched files are treated
87
+ * as a cache miss, the caller just does a cold bootstrap. */
88
+ function readCache(cacheDir, binaryVersion) {
89
+ const cachePath = path.join(cacheDir, CACHE_FILENAME);
90
+ try {
91
+ const raw = fs.readFileSync(cachePath, 'utf8');
92
+ const parsed = JSON.parse(raw);
93
+ if (parsed.schemaVersion !== CACHE_SCHEMA_VERSION)
94
+ return defaultCache(binaryVersion);
95
+ if (parsed.binaryVersion !== binaryVersion)
96
+ return defaultCache(binaryVersion);
97
+ if (!parsed.steps || typeof parsed.steps !== 'object')
98
+ return defaultCache(binaryVersion);
99
+ return {
100
+ schemaVersion: CACHE_SCHEMA_VERSION,
101
+ binaryVersion,
102
+ steps: parsed.steps,
103
+ };
104
+ }
105
+ catch {
106
+ // Missing / unreadable / malformed — treat as cold.
107
+ return defaultCache(binaryVersion);
108
+ }
109
+ }
110
+ /** Best-effort cache write; never throws (a cache failure must not break bootstrap). */
111
+ function writeCache(cacheDir, cache) {
112
+ const cachePath = path.join(cacheDir, CACHE_FILENAME);
113
+ try {
114
+ fs.mkdirSync(cacheDir, { recursive: true });
115
+ fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2));
116
+ }
117
+ catch { /* non-fatal — next run will re-fill */ }
118
+ }
119
+ /** Decide if a cached step is fresh enough to skip. `undefined` entry or
120
+ * `lastSuccess` older than `ttlMs` → stale. */
121
+ function isCacheFresh(entry, ttlMs, now) {
122
+ if (!entry?.lastSuccess)
123
+ return false;
124
+ const last = Date.parse(entry.lastSuccess);
125
+ if (!Number.isFinite(last))
126
+ return false;
127
+ return now - last < ttlMs;
128
+ }
129
+ const TTL_24H = 24 * 60 * 60 * 1000;
130
+ const TTL_60S = 60 * 1000;
131
+ // ─────────────────────────────────────────────────────────────────────────
132
+ // Search-attribute list — imported from sa-preflight.ts so commands.ts,
133
+ // startup.ts, and the daemon-boot preflight all share one source of truth
134
+ // (#605 consolidated the two duplicated literals).
135
+ // ─────────────────────────────────────────────────────────────────────────
136
+ const sa_preflight_1 = require("./sa-preflight");
137
+ // ─────────────────────────────────────────────────────────────────────────
138
+ // Semver-aware outdated-version badge rendering (#289 pin item 4)
139
+ // ─────────────────────────────────────────────────────────────────────────
140
+ /** Decide the outdated-version badge shape per the policy table:
141
+ * - major/minor behind → badge with severity
142
+ * - patch-only → silent
143
+ * - prerelease vs stable mismatches → silent (respect release channel)
144
+ */
145
+ function classifyVersion(installed, latest) {
146
+ const i = semver.parse(installed);
147
+ const l = semver.parse(latest);
148
+ if (!i || !l)
149
+ return undefined;
150
+ if (semver.gte(i, l))
151
+ return undefined;
152
+ const iPrerelease = i.prerelease.length > 0;
153
+ const lPrerelease = l.prerelease.length > 0;
154
+ // Channel respect: never nudge prerelease→stable downgrade or stable→prerelease.
155
+ if (iPrerelease && !lPrerelease)
156
+ return undefined;
157
+ if (!iPrerelease && lPrerelease)
158
+ return undefined;
159
+ // Prerelease iteration of the same minor — beta iteration is expected.
160
+ if (iPrerelease && lPrerelease && i.major === l.major && i.minor === l.minor) {
161
+ return undefined;
162
+ }
163
+ const diff = semver.diff(installed, latest);
164
+ if (diff === 'major' || diff === 'premajor')
165
+ return { latest, severity: 'major' };
166
+ if (diff === 'minor' || diff === 'preminor')
167
+ return { latest, severity: 'minor' };
168
+ // 'patch', 'prepatch', 'prerelease' → silent
169
+ return undefined;
170
+ }
171
+ // ─────────────────────────────────────────────────────────────────────────
172
+ // Step helpers
173
+ // ─────────────────────────────────────────────────────────────────────────
174
+ async function timed(fn) {
175
+ const start = perf_hooks_1.performance.now();
176
+ const result = await fn();
177
+ return { result, durationMs: perf_hooks_1.performance.now() - start };
178
+ }
179
+ /** Fetch the latest published version from npm with a hard timeout. Never
180
+ * throws — returns `null` on any network / timeout / parse error so the
181
+ * caller can silently proceed (spec pin item 3). */
182
+ async function defaultFetchLatestVersion(pkgName, timeoutMs) {
183
+ const controller = new AbortController();
184
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
185
+ try {
186
+ const res = await fetch(`https://registry.npmjs.org/${pkgName}/latest`, {
187
+ signal: controller.signal,
188
+ });
189
+ if (!res.ok)
190
+ return null;
191
+ const body = await res.json();
192
+ return typeof body.version === 'string' ? body.version : null;
193
+ }
194
+ catch {
195
+ return null;
196
+ }
197
+ finally {
198
+ clearTimeout(timer);
199
+ }
200
+ }
201
+ /** Bounded tail-read budget. Long-running daemons can accumulate multi-MB
202
+ * logs; reading the entire file on every bootstrap is wasteful. Seek back
203
+ * from EOF by at most this many bytes — 32 KiB comfortably covers the last
204
+ * few hundred log lines without loading the full file. */
205
+ const DAEMON_LOG_TAIL_BYTES = 32 * 1024;
206
+ /** Read the last ~200 ERROR-tagged lines from the daemon log. Returns at
207
+ * most 3 samples. Bounded-tail read (see {@link DAEMON_LOG_TAIL_BYTES}). */
208
+ function daemonLogErrorTail(logPath) {
209
+ let fd;
210
+ try {
211
+ const stat = fs.statSync(logPath);
212
+ const size = stat.size;
213
+ if (size === 0)
214
+ return undefined;
215
+ const start = Math.max(0, size - DAEMON_LOG_TAIL_BYTES);
216
+ const length = size - start;
217
+ const buf = Buffer.alloc(length);
218
+ fd = fs.openSync(logPath, 'r');
219
+ fs.readSync(fd, buf, 0, length, start);
220
+ const content = buf.toString('utf8');
221
+ const lines = content.split(/\r?\n/);
222
+ // If we seeked mid-file, the first line may be a partial — discard it.
223
+ const tail = start > 0 ? lines.slice(1) : lines;
224
+ const errors = tail.filter((l) => /\bERROR\b/i.test(l));
225
+ if (errors.length === 0)
226
+ return undefined;
227
+ return { count: errors.length, sample: errors.slice(-3), logPath };
228
+ }
229
+ catch {
230
+ return undefined;
231
+ }
232
+ finally {
233
+ if (fd !== undefined)
234
+ try {
235
+ fs.closeSync(fd);
236
+ }
237
+ catch { /* ignore */ }
238
+ }
239
+ }
240
+ // ─────────────────────────────────────────────────────────────────────────
241
+ // Individual steps
242
+ // ─────────────────────────────────────────────────────────────────────────
243
+ /**
244
+ * Default step-0 implementation — invokes the one-shot legacy home migration
245
+ * (`~/.agent-tempo/` → `~/.agent-tempo/`). Idempotent: re-runs are
246
+ * `'skipped'` once the marker is in place. Failure is recorded but never
247
+ * blocks bootstrap (PR-2 brief).
248
+ */
249
+ async function defaultLegacyHomeMigrationStep() {
250
+ const t0 = perf_hooks_1.performance.now();
251
+ try {
252
+ const result = await (0, legacy_migration_1.migrateLegacyHome)();
253
+ const durationMs = perf_hooks_1.performance.now() - t0;
254
+ const detail = (0, legacy_migration_1.formatMigrationResult)(result);
255
+ switch (result.status) {
256
+ case 'no-legacy':
257
+ case 'already-migrated':
258
+ return { status: 'skipped', durationMs, detail };
259
+ case 'migrated':
260
+ return { status: 'action-taken', durationMs, detail };
261
+ case 'skipped':
262
+ return { status: 'skipped', durationMs, detail };
263
+ case 'failed':
264
+ return { status: 'failed', durationMs, detail };
265
+ }
266
+ }
267
+ catch (err) {
268
+ return {
269
+ status: 'failed',
270
+ durationMs: perf_hooks_1.performance.now() - t0,
271
+ detail: `legacy-migration crashed: ${err.message}`,
272
+ };
273
+ }
274
+ }
275
+ async function stepPreflight(cache, now) {
276
+ if (isCacheFresh(cache.steps.preflight, TTL_24H, now)) {
277
+ return { status: 'skipped', durationMs: 0 };
278
+ }
279
+ const { result, durationMs } = await timed(() => {
280
+ const errors = [];
281
+ const major = parseInt(process.version.slice(1), 10);
282
+ if (major < 20)
283
+ errors.push(`Node.js 20+ required, found ${process.version}`);
284
+ // No `claude` binary probe here: the user's default agent may be
285
+ // `copilot`, and spawn-time errors are more actionable than a startup
286
+ // preflight block. CI environments without claude installed also need
287
+ // bootstrap to succeed so the TUI can render diagnostics. A future
288
+ // TUI badge can surface "claude not found" when the agent requires it.
289
+ try {
290
+ fs.mkdirSync(config_1.AGENT_TEMPO_HOME, { recursive: true });
291
+ fs.accessSync(config_1.AGENT_TEMPO_HOME, fs.constants.W_OK);
292
+ }
293
+ catch {
294
+ errors.push(`${config_1.AGENT_TEMPO_HOME} is not writable. Check permissions or set $HOME.`);
295
+ }
296
+ return errors;
297
+ });
298
+ if (result.length > 0) {
299
+ return { status: 'failed', durationMs, detail: result.join('; ') };
300
+ }
301
+ cache.steps.preflight = { lastSuccess: new Date(now).toISOString() };
302
+ return { status: 'ok', durationMs };
303
+ }
304
+ async function stepMcpConfig(cache, cwd, now) {
305
+ const cached = cache.steps.mcpConfig;
306
+ let configMtime;
307
+ try {
308
+ const projectMcp = path.join(cwd, '.mcp.json');
309
+ if (fs.existsSync(projectMcp)) {
310
+ configMtime = fs.statSync(projectMcp).mtime.toISOString();
311
+ }
312
+ }
313
+ catch { /* ignore — no-mtime path */ }
314
+ if (isCacheFresh(cached, TTL_24H, now) &&
315
+ cached?.configMtime === configMtime) {
316
+ return { status: 'skipped', durationMs: 0 };
317
+ }
318
+ const { result: outcome, durationMs } = await timed(() => {
319
+ if ((0, mcp_1.isMcpConfigured)(cwd)) {
320
+ return { status: 'ok', durationMs: 0 };
321
+ }
322
+ // Install into global user scope (matches current `init` behavior).
323
+ if (!(0, mcp_1.isGlobalMcpRegistered)() && (0, mcp_1.addGlobalMcp)()) {
324
+ return { status: 'action-taken', durationMs: 0, detail: 'registered agent-tempo in user MCP scope' };
325
+ }
326
+ return { status: 'failed', durationMs: 0, detail: 'Could not register agent-tempo MCP. Run `agent-tempo init` manually.' };
327
+ });
328
+ if (outcome.status !== 'failed') {
329
+ cache.steps.mcpConfig = {
330
+ lastSuccess: new Date(now).toISOString(),
331
+ ...(configMtime !== undefined ? { configMtime } : {}),
332
+ };
333
+ }
334
+ return { ...outcome, durationMs };
335
+ }
336
+ async function stepTemporalReach(cache, config, now, reachableProbe) {
337
+ if (isCacheFresh(cache.steps.temporalReach, TTL_60S, now)) {
338
+ return { status: 'skipped', durationMs: 0 };
339
+ }
340
+ const { result: outcome, durationMs } = await timed(async () => {
341
+ const reachable = await reachableProbe(config);
342
+ if (reachable)
343
+ return { status: 'ok', durationMs: 0 };
344
+ // Auto-start only when the address is local. Remote failures surface
345
+ // an actionable error; we don't try to spawn a remote server.
346
+ if (!isLocalAddress(config.temporalAddress)) {
347
+ return {
348
+ status: 'failed',
349
+ durationMs: 0,
350
+ detail: `Cannot reach remote Temporal at ${config.temporalAddress}. Check TEMPORAL_ADDRESS + network.`,
351
+ };
352
+ }
353
+ if (!hasTemporalCli()) {
354
+ return {
355
+ status: 'failed',
356
+ durationMs: 0,
357
+ detail: 'temporal CLI not found on PATH. Install from https://docs.temporal.io/cli and re-run.',
358
+ };
359
+ }
360
+ const started = await startTemporalDevServer(config, reachableProbe);
361
+ if (started) {
362
+ return { status: 'action-taken', durationMs: 0, detail: `started temporal dev server at ${config.temporalAddress}` };
363
+ }
364
+ return {
365
+ status: 'failed',
366
+ durationMs: 0,
367
+ detail: `temporal dev server did not become reachable at ${config.temporalAddress}`,
368
+ };
369
+ });
370
+ if (outcome.status !== 'failed') {
371
+ cache.steps.temporalReach = { lastSuccess: new Date(now).toISOString() };
372
+ }
373
+ return { ...outcome, durationMs };
374
+ }
375
+ async function stepSearchAttrs(cache, config, now) {
376
+ if (isCacheFresh(cache.steps.searchAttrs, TTL_24H, now)) {
377
+ return { status: 'skipped', durationMs: 0 };
378
+ }
379
+ const { result: outcome, durationMs } = await timed(() => {
380
+ // Per-attr classification via `registerSearchAttribute` (#605) —
381
+ // distinguishes `already-exists` (idempotent expected case) from real
382
+ // failures. Pre-#605 every non-zero exit was swallowed as "already
383
+ // registered", masking the SQLite dev-server's 10-Keyword-per-namespace
384
+ // cap and other genuine errors until a downstream workflow start failed
385
+ // with the confusing `INVALID_ARGUMENT: search attribute ... is not
386
+ // defined`.
387
+ const failures = [];
388
+ for (const attr of sa_preflight_1.REQUIRED_SEARCH_ATTRIBUTES) {
389
+ const r = (0, sa_preflight_1.registerSearchAttribute)(attr, config.temporalAddress, config.temporalNamespace);
390
+ if (r.status === 'failed') {
391
+ failures.push(`${attr.name}: ${r.detail ?? 'unknown error'}`);
392
+ }
393
+ }
394
+ if (failures.length > 0) {
395
+ return {
396
+ status: 'failed',
397
+ durationMs: 0,
398
+ detail: `Failed to register ${failures.length} search attribute(s):\n ${failures.join('\n ')}`,
399
+ };
400
+ }
401
+ return { status: 'ok', durationMs: 0 };
402
+ });
403
+ if (outcome.status !== 'failed') {
404
+ cache.steps.searchAttrs = { lastSuccess: new Date(now).toISOString() };
405
+ }
406
+ return { ...outcome, durationMs };
407
+ }
408
+ async function stepDaemonBootAsync(config) {
409
+ const start = perf_hooks_1.performance.now();
410
+ if ((0, daemon_1.isDaemonRunning)()) {
411
+ // Cheap authoritative check: heartbeat file mtime must be within 2×
412
+ // the interval — otherwise the daemon is hung.
413
+ try {
414
+ const age = Date.now() - fs.statSync(daemon_1.DAEMON_HEARTBEAT_PATH).mtimeMs;
415
+ if (age > daemon_1.HEARTBEAT_INTERVAL_MS * daemon_1.HEARTBEAT_STALE_MULTIPLIER) {
416
+ return {
417
+ status: 'failed',
418
+ durationMs: perf_hooks_1.performance.now() - start,
419
+ detail: `daemon heartbeat stale (${Math.round(age / 1000)}s). Check ${daemon_1.DAEMON_LOG_PATH}.`,
420
+ };
421
+ }
422
+ }
423
+ catch { /* no heartbeat file yet — daemon is fresh, treat as ok */ }
424
+ return { status: 'skipped', durationMs: perf_hooks_1.performance.now() - start };
425
+ }
426
+ try {
427
+ const pid = await (0, daemon_1.startDaemon)(config);
428
+ return {
429
+ status: 'action-taken',
430
+ durationMs: perf_hooks_1.performance.now() - start,
431
+ detail: `started daemon (pid ${pid})`,
432
+ };
433
+ }
434
+ catch (err) {
435
+ return {
436
+ status: 'failed',
437
+ durationMs: perf_hooks_1.performance.now() - start,
438
+ detail: err instanceof Error ? err.message : String(err),
439
+ };
440
+ }
441
+ }
442
+ async function stepBadgeCollection(config, cache, now, binaryVersion, fetchLatest, reachableProbe) {
443
+ const start = perf_hooks_1.performance.now();
444
+ let orphanCount = 0;
445
+ let ensembles = [];
446
+ let outdatedVersion;
447
+ const hostname = (0, os_1.hostname)();
448
+ // Sub-A: orphan count + ensembles list — Temporal connect runs through the
449
+ // injected `reachableProbe` first so a stale `temporalAddress` can't block
450
+ // the TUI. Hard 3s wall-clock budget on the actual connect + queries.
451
+ let connection;
452
+ try {
453
+ if (!(await reachableProbe(config)))
454
+ throw new Error('unreachable');
455
+ connection = await Promise.race([
456
+ (0, connection_1.createTemporalConnection)(config),
457
+ new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), 3000)),
458
+ ]);
459
+ const client = new client_1.Client({ connection, namespace: config.temporalNamespace });
460
+ const tempo = (0, client_2.createTempoClient)(client);
461
+ const [orphans, summaries] = await Promise.all([
462
+ (0, orphans_1.queryOrphanedSessions)(client, { hostname }).catch(() => []),
463
+ tempo.discoverEnsembles().catch(() => []),
464
+ ]);
465
+ orphanCount = orphans.length;
466
+ ensembles = summaries;
467
+ }
468
+ catch { /* degraded — bootstrap still returns, TUI shows connection error */ }
469
+ finally {
470
+ if (connection)
471
+ try {
472
+ await connection.close();
473
+ }
474
+ catch { /* ignore */ }
475
+ }
476
+ // Sub-B: npm-version check — 24h cached, 500ms AbortController timeout,
477
+ // silent fallback on network failure (pin items 2 + 3).
478
+ const cachedNpm = cache.steps.npmVersionCheck;
479
+ let latest = null;
480
+ if (isCacheFresh(cachedNpm, TTL_24H, now) && cachedNpm?.result) {
481
+ latest = cachedNpm.result.latest;
482
+ }
483
+ else {
484
+ latest = await fetchLatest('agent-tempo', 500);
485
+ if (latest) {
486
+ cache.steps.npmVersionCheck = {
487
+ lastSuccess: new Date(now).toISOString(),
488
+ result: { latest },
489
+ };
490
+ }
491
+ // If fetch returned null (timeout / offline), do NOT update the cache —
492
+ // next bootstrap will try again immediately.
493
+ }
494
+ if (latest) {
495
+ outdatedVersion = classifyVersion(binaryVersion, latest);
496
+ }
497
+ // Sub-C: daemon log error tail. Cheap, always runs.
498
+ const daemonLogErrors = daemonLogErrorTail(daemon_1.DAEMON_LOG_PATH);
499
+ return {
500
+ badges: {
501
+ orphanCount,
502
+ ...(outdatedVersion ? { outdatedVersion } : {}),
503
+ ...(daemonLogErrors ? { daemonLogErrors } : {}),
504
+ },
505
+ ensembles,
506
+ outcome: { status: 'ok', durationMs: perf_hooks_1.performance.now() - start },
507
+ };
508
+ }
509
+ // ─────────────────────────────────────────────────────────────────────────
510
+ // Plumbing helpers (Temporal reachability probe + dev-server spawn)
511
+ // ─────────────────────────────────────────────────────────────────────────
512
+ async function isTemporalReachable(config, timeoutMs = 3000) {
513
+ try {
514
+ const conn = await Promise.race([
515
+ (0, connection_1.createTemporalConnection)(config),
516
+ new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeoutMs)),
517
+ ]);
518
+ try {
519
+ const client = new client_1.Client({ connection: conn, namespace: config.temporalNamespace });
520
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
521
+ for await (const _ of client.workflow.list({ query: 'WorkflowId = "__readiness_probe__"' })) {
522
+ break;
523
+ }
524
+ }
525
+ finally {
526
+ await conn.close();
527
+ }
528
+ return true;
529
+ }
530
+ catch {
531
+ return false;
532
+ }
533
+ }
534
+ function isLocalAddress(address) {
535
+ const host = address.split(':')[0] || '';
536
+ return host === 'localhost' || host === '127.0.0.1' || host === '::1' || host === '';
537
+ }
538
+ function hasTemporalCli() {
539
+ const cmd = process.platform === 'win32' ? 'where' : 'which';
540
+ try {
541
+ (0, child_process_1.execFileSync)(cmd, ['temporal'], { stdio: 'ignore' });
542
+ return true;
543
+ }
544
+ catch {
545
+ return false;
546
+ }
547
+ }
548
+ async function startTemporalDevServer(config, reachableProbe) {
549
+ fs.mkdirSync(config_1.AGENT_TEMPO_HOME, { recursive: true });
550
+ const port = config.temporalAddress.split(':')[1] || '7233';
551
+ const dbPath = path.join(config_1.AGENT_TEMPO_HOME, 'temporal-data.db');
552
+ const child = (0, child_process_1.spawn)('temporal', ['server', 'start-dev', '--port', port, '--db-filename', dbPath], {
553
+ detached: true,
554
+ stdio: 'ignore',
555
+ });
556
+ child.unref();
557
+ for (let i = 0; i < 20; i++) {
558
+ await new Promise((r) => setTimeout(r, 500));
559
+ if (await reachableProbe(config))
560
+ return true;
561
+ }
562
+ return false;
563
+ }
564
+ // ─────────────────────────────────────────────────────────────────────────
565
+ // Public entry point
566
+ // ─────────────────────────────────────────────────────────────────────────
567
+ /** Read the installed package version. Cached behind a function so tests
568
+ * can override via `BootstrapArgs.binaryVersion`. */
569
+ function readBinaryVersion() {
570
+ try {
571
+ const pkg = require('../../package.json');
572
+ return pkg.version;
573
+ }
574
+ catch {
575
+ return '0.0.0';
576
+ }
577
+ }
578
+ /**
579
+ * Run the 7-step auto-provisioning sequence. Returns a `BootstrapResult`
580
+ * the caller feeds to the TUI; step 7 (TUI launch) is the caller's
581
+ * handoff — this function does NOT spawn UI processes.
582
+ */
583
+ async function bootstrap(args) {
584
+ const start = perf_hooks_1.performance.now();
585
+ const cwd = args.cwd ?? process.cwd();
586
+ const now = (args.now ?? (() => Date.now()))();
587
+ const cacheDir = args.cacheDir ?? config_1.AGENT_TEMPO_HOME;
588
+ const binaryVersion = args.binaryVersion ?? readBinaryVersion();
589
+ const fetchLatest = args.fetchLatestVersion ?? defaultFetchLatestVersion;
590
+ const cache = readCache(cacheDir, binaryVersion);
591
+ const reachableProbe = args.isTemporalReachable ?? ((c) => isTemporalReachable(c, 3000));
592
+ // Step 0: legacy home migration (`~/.agent-tempo/` → `~/.agent-tempo/`)
593
+ // — PR-2 of the v1.0 rebrand. Runs before preflight so subsequent steps
594
+ // (cache read, MCP config write, daemon boot) all see the new home.
595
+ // MUST NOT block bootstrap — failure becomes a `'failed'` step with
596
+ // `detail`, and we keep going.
597
+ const legacyHomeMigration = await (args.legacyHomeMigration ?? defaultLegacyHomeMigrationStep)();
598
+ // Steps 1–5: fail-fast on step 1 so we don't try to register MCP on an
599
+ // incompatible Node. Each step mutates the cache in-place.
600
+ const preflight = await stepPreflight(cache, now);
601
+ // Steps 2 + 3 are independent (MCP config is local fs/shell; Temporal
602
+ // reachability is network), so run them in parallel — up to ~300ms
603
+ // cold-path savings when the claude-mcp-list shell-out is slow.
604
+ const [mcpConfig, temporalReach] = preflight.status === 'failed'
605
+ ? [
606
+ { status: 'skipped', durationMs: 0 },
607
+ { status: 'skipped', durationMs: 0 },
608
+ ]
609
+ : await Promise.all([
610
+ stepMcpConfig(cache, cwd, now),
611
+ stepTemporalReach(cache, args.config, now, reachableProbe),
612
+ ]);
613
+ const searchAttrs = temporalReach.status === 'failed'
614
+ ? { status: 'skipped', durationMs: 0, detail: 'skipped — temporal unreachable' }
615
+ : await stepSearchAttrs(cache, args.config, now);
616
+ const daemonBoot = preflight.status === 'failed'
617
+ ? { status: 'skipped', durationMs: 0 }
618
+ : await (args.daemonBoot ?? stepDaemonBootAsync)(args.config);
619
+ // Step 6: badges + ensembles prefetch. Runs even on partial-failure paths
620
+ // so the TUI can render something meaningful; Temporal-connect failure
621
+ // degrades to zeros / empty lists rather than throwing.
622
+ const badgeStep = await stepBadgeCollection(args.config, cache, now, binaryVersion, fetchLatest, reachableProbe);
623
+ // Persist cache after all steps — one write per bootstrap.
624
+ writeCache(cacheDir, cache);
625
+ return {
626
+ durationMs: perf_hooks_1.performance.now() - start,
627
+ steps: {
628
+ legacyHomeMigration,
629
+ preflight,
630
+ mcpConfig,
631
+ temporalReach,
632
+ searchAttrs,
633
+ daemonBoot,
634
+ badgeCollection: badgeStep.outcome,
635
+ },
636
+ badges: badgeStep.badges,
637
+ ensembles: badgeStep.ensembles,
638
+ cwd,
639
+ cwdGitRoot: (0, git_info_1.getGitInfo)(cwd).gitRoot ?? null,
640
+ };
641
+ }
@@ -0,0 +1,5 @@
1
+ import { CliOverrides } from '../config';
2
+ export interface UpgradeOpts extends CliOverrides {
3
+ version?: string;
4
+ }
5
+ export declare function upgrade(opts: UpgradeOpts): Promise<void>;