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,58 @@
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.InputBar = InputBar;
37
+ /**
38
+ * Input bar — text input for sending commands to the conductor.
39
+ */
40
+ const react_1 = __importStar(require("react"));
41
+ const ink_context_1 = require("../ink-context");
42
+ function InputBar({ onSubmit, sending, error, placeholder = 'Send command to conductor...' }) {
43
+ const { Box, Text } = (0, ink_context_1.useInk)();
44
+ const [value, setValue] = (0, react_1.useState)('');
45
+ const handleSubmit = (0, react_1.useCallback)(() => {
46
+ if (value.trim() && !sending) {
47
+ onSubmit(value.trim());
48
+ setValue('');
49
+ }
50
+ }, [value, sending, onSubmit]);
51
+ // Simple text display — actual text input requires ink-text-input which is also ESM.
52
+ // For now, show the prompt. Full text input will be added when ink-text-input is integrated.
53
+ return react_1.default.createElement(Box, { flexDirection: 'column' }, react_1.default.createElement(Box, null, react_1.default.createElement(Text, { color: 'cyan', bold: true }, '> '), sending
54
+ ? react_1.default.createElement(Text, { dimColor: true }, 'Sending...')
55
+ : react_1.default.createElement(Text, { dimColor: true }, placeholder)), error
56
+ ? react_1.default.createElement(Text, { color: 'red' }, `Error: ${error}`)
57
+ : null);
58
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Lineup picker — text input for a lineup name or path. Validation runs
3
+ * through `resolveLineupPath` → `loadLineup` so schema errors (e.g.
4
+ * missing conductor) render inline with the CLI error text.
5
+ */
6
+ import React from 'react';
7
+ export interface LoadLineupModalProps {
8
+ /** Called with the inferred ensemble name + resolved lineup path after a successful validate. */
9
+ onSubmit: (args: {
10
+ ensemble: string;
11
+ lineupPath: string;
12
+ }) => void;
13
+ onCancel: () => void;
14
+ submitting?: boolean;
15
+ /** Error surfaced by the caller's submit handler (e.g. spawn failure). */
16
+ error?: string | null;
17
+ }
18
+ export declare function LoadLineupModal({ onSubmit, onCancel, submitting, error }: LoadLineupModalProps): React.ReactElement;
@@ -0,0 +1,79 @@
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.LoadLineupModal = LoadLineupModal;
37
+ /**
38
+ * Lineup picker — text input for a lineup name or path. Validation runs
39
+ * through `resolveLineupPath` → `loadLineup` so schema errors (e.g.
40
+ * missing conductor) render inline with the CLI error text.
41
+ */
42
+ const react_1 = __importStar(require("react"));
43
+ const ink_context_1 = require("../ink-context");
44
+ const theme_1 = require("../utils/theme");
45
+ const loader_1 = require("../../ensemble/loader");
46
+ function LoadLineupModal({ onSubmit, onCancel, submitting, error }) {
47
+ const { Box, Text, TextInput, useInput } = (0, ink_context_1.useInk)();
48
+ const [value, setValue] = (0, react_1.useState)('');
49
+ const [validationError, setValidationError] = (0, react_1.useState)(null);
50
+ useInput((0, react_1.useCallback)((_input, key) => {
51
+ if (key.escape)
52
+ onCancel();
53
+ }, [onCancel]));
54
+ const handleSubmit = (0, react_1.useCallback)((raw) => {
55
+ const input = raw.trim();
56
+ if (!input)
57
+ return;
58
+ try {
59
+ const resolved = (0, loader_1.resolveLineupPath)(input);
60
+ const lineup = (0, loader_1.loadLineup)(resolved.path);
61
+ setValidationError(null);
62
+ onSubmit({ ensemble: lineup.name, lineupPath: resolved.path });
63
+ }
64
+ catch (err) {
65
+ setValidationError(err instanceof Error ? err.message : String(err));
66
+ }
67
+ }, [onSubmit]);
68
+ const currentError = error ?? validationError;
69
+ return react_1.default.createElement(Box, { flexDirection: 'column' }, react_1.default.createElement(Text, { bold: true, color: theme_1.THEME.accent }, ' Load lineup'), react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ' Name (saved or shipped) or path to a .yaml file.'), react_1.default.createElement(Box, { marginTop: 1 }, react_1.default.createElement(Text, { color: theme_1.THEME.accent }, ' ? '), react_1.default.createElement(Text, { bold: true, color: theme_1.THEME.text }, 'Lineup:')), submitting
70
+ ? react_1.default.createElement(Box, { marginLeft: 3, marginTop: 1 }, react_1.default.createElement(Text, { color: theme_1.THEME.warning }, `\u2026 Starting ensemble from "${value.trim()}"\u2026`))
71
+ : react_1.default.createElement(Box, { marginLeft: 3, marginTop: 1 }, react_1.default.createElement(Text, { color: theme_1.THEME.accent }, '> '), react_1.default.createElement(TextInput, {
72
+ value,
73
+ onChange: (next) => { setValue(next); if (validationError)
74
+ setValidationError(null); },
75
+ onSubmit: handleSubmit,
76
+ })), currentError
77
+ ? react_1.default.createElement(Box, { flexDirection: 'column', marginTop: 1 }, ...currentError.split('\n').map((line, i) => react_1.default.createElement(Text, { key: `err-${i}`, color: theme_1.THEME.error }, ` \u2717 ${line}`)))
78
+ : null, react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ' Enter to load \u00B7 Esc to cancel'));
79
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * MainView — single-column ensemble dashboard.
3
+ * Renders as a SINGLE Text element (1 Yoga node) with newlines for rows.
4
+ * All nested Text = ink-virtual-text (0 Yoga nodes).
5
+ */
6
+ import React from 'react';
7
+ import type { MaestroPlayerInfo, MaestroRelayMessage } from '../../types';
8
+ export interface ScheduleInfo {
9
+ name: string;
10
+ spec: string;
11
+ target: string;
12
+ }
13
+ export interface MainViewProps {
14
+ ensemble: string;
15
+ players: MaestroPlayerInfo[];
16
+ messages: MaestroRelayMessage[];
17
+ schedules?: ScheduleInfo[];
18
+ /** Total number of static items in scrollback (for indicator). */
19
+ staticItemCount?: number;
20
+ }
21
+ export declare function MainView({ ensemble, players, messages, schedules, staticItemCount }: MainViewProps): React.CElement<{}, React.Component<{}, any, any>>;
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MainView = MainView;
7
+ /**
8
+ * MainView — single-column ensemble dashboard.
9
+ * Renders as a SINGLE Text element (1 Yoga node) with newlines for rows.
10
+ * All nested Text = ink-virtual-text (0 Yoga nodes).
11
+ */
12
+ const react_1 = __importDefault(require("react"));
13
+ const ink_context_1 = require("../ink-context");
14
+ const platform_1 = require("../utils/platform");
15
+ const theme_1 = require("../utils/theme");
16
+ const format_1 = require("../utils/format");
17
+ /** Pad or truncate with ellipsis to exactly `len` chars. */
18
+ function pad(s, len) {
19
+ if (s.length > len)
20
+ return s.slice(0, len - 1) + '\u2026';
21
+ return s + ' '.repeat(len - s.length);
22
+ }
23
+ /** Format a timestamp to HH:MM. */
24
+ function formatTime(ts) {
25
+ try {
26
+ const d = new Date(ts);
27
+ return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
28
+ }
29
+ catch {
30
+ return '??:??';
31
+ }
32
+ }
33
+ /** Truncate text with ellipsis. */
34
+ function truncate(text, max) {
35
+ if (text.length <= max)
36
+ return text;
37
+ return text.slice(0, max - 1) + '\u2026';
38
+ }
39
+ function MainView({ ensemble, players, messages, schedules, staticItemCount }) {
40
+ const { Text } = (0, ink_context_1.useInk)();
41
+ const unicode = (0, platform_1.supportsUnicode)();
42
+ const icons = (0, platform_1.statusIcons)(unicode);
43
+ const children = [];
44
+ // ── Players section ──
45
+ children.push('\n');
46
+ children.push(react_1.default.createElement(Text, { key: 'ph', bold: true, color: theme_1.THEME.accent }, ' Players'));
47
+ children.push('\n');
48
+ if (players.length === 0) {
49
+ children.push(react_1.default.createElement(Text, { key: 'np', color: theme_1.THEME.dim }, ' No players'));
50
+ }
51
+ else {
52
+ for (let i = 0; i < players.length; i++) {
53
+ const p = players[i];
54
+ // Collapse the attachment phase via the Option-B helpers in utils/format.
55
+ const icon = p.isConductor ? icons.conductor : icons[(0, format_1.phaseToIconName)(p.phase)];
56
+ const color = (0, format_1.phaseToColor)(p.phase);
57
+ const typeName = p.playerType || p.agentType || '';
58
+ const part = p.part || '';
59
+ if (i > 0)
60
+ children.push('\n');
61
+ children.push(react_1.default.createElement(Text, { key: p.playerId, color }, ` ${icon} ${pad(p.playerId, 20)} ${pad(typeName, 22)} ${truncate(part, 35)}`));
62
+ }
63
+ }
64
+ // ── Separator ──
65
+ children.push('\n');
66
+ children.push(react_1.default.createElement(Text, { key: 'sep1', color: theme_1.THEME.border }, ' ' + '\u2500'.repeat(50)));
67
+ // ── Recent Activity section ──
68
+ children.push('\n');
69
+ children.push(react_1.default.createElement(Text, { key: 'ah', bold: true, color: theme_1.THEME.accent }, ' Recent Activity'));
70
+ children.push('\n');
71
+ const recentMessages = messages.slice(-3);
72
+ if (recentMessages.length === 0 && !staticItemCount) {
73
+ children.push(react_1.default.createElement(Text, { key: 'na', color: theme_1.THEME.dim }, ' No activity yet'));
74
+ }
75
+ else {
76
+ // Scrollback indicator
77
+ if (staticItemCount && staticItemCount > 0) {
78
+ children.push(react_1.default.createElement(Text, { key: 'scrollback', color: theme_1.THEME.dim }, ` \u2191 ${staticItemCount} messages in scrollback (scroll up in terminal)`));
79
+ children.push('\n');
80
+ }
81
+ // Latest 3 messages as preview
82
+ for (let i = 0; i < recentMessages.length; i++) {
83
+ const m = recentMessages[i];
84
+ const time = formatTime(m.timestamp);
85
+ const msgText = truncate(m.text.replace(/\n/g, ' '), 60);
86
+ if (i > 0)
87
+ children.push('\n');
88
+ children.push(react_1.default.createElement(Text, { key: m.id || `msg-${i}`, color: theme_1.THEME.dim }, ` ${time} ${m.from} ${icons.arrow} ${m.to}: ${msgText}`));
89
+ }
90
+ }
91
+ // ── Schedules section (only if there are schedules) ──
92
+ if (schedules && schedules.length > 0) {
93
+ children.push('\n');
94
+ children.push(react_1.default.createElement(Text, { key: 'sep2', color: theme_1.THEME.border }, ' ' + '\u2500'.repeat(50)));
95
+ children.push('\n');
96
+ children.push(react_1.default.createElement(Text, { key: 'sh', bold: true, color: theme_1.THEME.accent }, ` Schedules (${schedules.length} active)`));
97
+ children.push('\n');
98
+ for (let i = 0; i < schedules.length; i++) {
99
+ const s = schedules[i];
100
+ if (i > 0)
101
+ children.push('\n');
102
+ children.push(react_1.default.createElement(Text, { key: `sched-${i}`, color: theme_1.THEME.textMuted }, ` \u21BB ${pad(s.name, 20)}${pad(s.spec, 18)}${icons.arrow} ${s.target}`));
103
+ }
104
+ }
105
+ // Single Text element — all children are ink-virtual-text (0 Yoga nodes)
106
+ return react_1.default.createElement(Text, null, ...children);
107
+ }
@@ -0,0 +1,9 @@
1
+ /** Single-prompt blank-ensemble creation. Enter submits, Esc cancels. */
2
+ import React from 'react';
3
+ export interface NewEnsembleModalProps {
4
+ onSubmit: (name: string) => void;
5
+ onCancel: () => void;
6
+ submitting?: boolean;
7
+ error?: string | null;
8
+ }
9
+ export declare function NewEnsembleModal({ onSubmit, onCancel, submitting, error }: NewEnsembleModalProps): React.ReactElement;
@@ -0,0 +1,73 @@
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.NewEnsembleModal = NewEnsembleModal;
37
+ /** Single-prompt blank-ensemble creation. Enter submits, Esc cancels. */
38
+ const react_1 = __importStar(require("react"));
39
+ const ink_context_1 = require("../ink-context");
40
+ const theme_1 = require("../utils/theme");
41
+ const validation_1 = require("../../utils/validation");
42
+ function NewEnsembleModal({ onSubmit, onCancel, submitting, error }) {
43
+ const { Box, Text, TextInput, useInput } = (0, ink_context_1.useInk)();
44
+ const [value, setValue] = (0, react_1.useState)('');
45
+ const [validationError, setValidationError] = (0, react_1.useState)(null);
46
+ useInput((0, react_1.useCallback)((_input, key) => {
47
+ if (key.escape)
48
+ onCancel();
49
+ }, [onCancel]));
50
+ const handleSubmit = (0, react_1.useCallback)((raw) => {
51
+ const name = raw.trim();
52
+ if (!name)
53
+ return;
54
+ const nameError = (0, validation_1.validateEnsembleName)(name);
55
+ if (nameError) {
56
+ setValidationError(nameError);
57
+ return;
58
+ }
59
+ setValidationError(null);
60
+ onSubmit(name);
61
+ }, [onSubmit]);
62
+ const currentError = error ?? validationError;
63
+ return react_1.default.createElement(Box, { flexDirection: 'column' }, react_1.default.createElement(Text, { bold: true, color: theme_1.THEME.accent }, ' New ensemble'), react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ' Conductor defaults: name "conductor", agent AGENT_TEMPO_DEFAULT_AGENT.'), react_1.default.createElement(Box, { marginTop: 1 }, react_1.default.createElement(Text, { color: theme_1.THEME.accent }, ' ? '), react_1.default.createElement(Text, { bold: true, color: theme_1.THEME.text }, 'Ensemble name:')), submitting
64
+ ? react_1.default.createElement(Box, { marginLeft: 3, marginTop: 1 }, react_1.default.createElement(Text, { color: theme_1.THEME.warning }, `\u2026 Creating "${value.trim()}"\u2026`))
65
+ : react_1.default.createElement(Box, { marginLeft: 3, marginTop: 1 }, react_1.default.createElement(Text, { color: theme_1.THEME.accent }, '> '), react_1.default.createElement(TextInput, {
66
+ value,
67
+ onChange: (next) => { setValue(next); if (validationError)
68
+ setValidationError(null); },
69
+ onSubmit: handleSubmit,
70
+ })), currentError
71
+ ? react_1.default.createElement(Text, { color: theme_1.THEME.error }, ` \u2717 ${currentError}`)
72
+ : null, react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ' Enter to create \u00B7 Esc to cancel'));
73
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Picker — generic interactive list overlay.
3
+ * Renders as a SINGLE Text element (1 Yoga node) with newlines for rows.
4
+ */
5
+ import React from 'react';
6
+ export interface PickerItem {
7
+ id: string;
8
+ label: string;
9
+ detail: string;
10
+ meta?: string;
11
+ color?: string;
12
+ icon?: string;
13
+ current?: boolean;
14
+ /** Group header — items with the same group are rendered under a shared header. */
15
+ group?: string;
16
+ }
17
+ export interface PickerProps {
18
+ title: string;
19
+ items: PickerItem[];
20
+ selectedIndex: number;
21
+ hint?: string;
22
+ }
23
+ export declare function Picker({ title, items, selectedIndex, hint }: PickerProps): React.DetailedReactHTMLElement<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> | React.CElement<{}, React.Component<{}, any, any>>;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Picker = Picker;
7
+ /**
8
+ * Picker — generic interactive list overlay.
9
+ * Renders as a SINGLE Text element (1 Yoga node) with newlines for rows.
10
+ */
11
+ const react_1 = __importDefault(require("react"));
12
+ const ink_context_1 = require("../ink-context");
13
+ const theme_1 = require("../utils/theme");
14
+ const MAX_VISIBLE = 10;
15
+ function Picker({ title, items, selectedIndex, hint }) {
16
+ const { Text } = (0, ink_context_1.useInk)();
17
+ if (items.length === 0) {
18
+ return react_1.default.createElement(Text, null, react_1.default.createElement(Text, { bold: true, color: theme_1.THEME.accent }, ` ${title}`), '\n', react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ' (none)'));
19
+ }
20
+ // Window around selected index
21
+ let startIdx = 0;
22
+ if (items.length > MAX_VISIBLE) {
23
+ startIdx = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE / 2), items.length - MAX_VISIBLE));
24
+ }
25
+ const visible = items.slice(startIdx, startIdx + MAX_VISIBLE);
26
+ const hasAbove = startIdx > 0;
27
+ const hasBelow = startIdx + MAX_VISIBLE < items.length;
28
+ const children = [];
29
+ // Title
30
+ children.push(react_1.default.createElement(Text, { key: 'title', bold: true, color: theme_1.THEME.accent }, ` ${title}`));
31
+ children.push('\n');
32
+ // Scroll-up
33
+ if (hasAbove) {
34
+ children.push(react_1.default.createElement(Text, { key: 'above', color: theme_1.THEME.dim }, ` \u2191 ${startIdx} more above`));
35
+ children.push('\n');
36
+ }
37
+ // Items (with optional group headers)
38
+ let lastGroup;
39
+ for (let i = 0; i < visible.length; i++) {
40
+ const item = visible[i];
41
+ const actualIdx = startIdx + i;
42
+ const isSelected = actualIdx === selectedIndex;
43
+ const indicator = isSelected ? '\u25B8 ' : ' ';
44
+ const currentMark = item.current ? ' \u25C0' : '';
45
+ const labelColor = isSelected ? theme_1.THEME.accent : (item.color || theme_1.THEME.text);
46
+ const icon = item.icon ? `${item.icon} ` : '';
47
+ // Group header
48
+ if (item.group && item.group !== lastGroup) {
49
+ if (i > 0 || lastGroup !== undefined)
50
+ children.push('\n');
51
+ children.push('\n');
52
+ children.push(react_1.default.createElement(Text, { key: `grp-${item.group}`, color: theme_1.THEME.dim }, ` \u2500\u2500 ${item.group} \u2500\u2500`));
53
+ lastGroup = item.group;
54
+ }
55
+ if (i > 0 || lastGroup !== undefined)
56
+ children.push('\n');
57
+ children.push(react_1.default.createElement(react_1.default.Fragment, { key: item.id }, react_1.default.createElement(Text, { color: isSelected ? theme_1.THEME.accent : theme_1.THEME.dim }, indicator), react_1.default.createElement(Text, { color: labelColor, bold: isSelected }, `${icon}${item.label}`), react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ` ${item.detail}`), item.meta ? react_1.default.createElement(Text, { color: theme_1.THEME.muted }, ` ${item.meta}`) : null, currentMark ? react_1.default.createElement(Text, { color: theme_1.THEME.warning }, currentMark) : null));
58
+ }
59
+ // Scroll-down
60
+ if (hasBelow) {
61
+ children.push('\n');
62
+ children.push(react_1.default.createElement(Text, { key: 'below', color: theme_1.THEME.dim }, ` \u2193 ${items.length - startIdx - MAX_VISIBLE} more below`));
63
+ }
64
+ // Hint
65
+ if (hint) {
66
+ children.push('\n');
67
+ children.push(react_1.default.createElement(Text, { key: 'hint', color: theme_1.THEME.dim }, ` ${hint}`));
68
+ }
69
+ return react_1.default.createElement(Text, null, ...children);
70
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * PlayerDetailView — shows player metadata + scrollable message history.
3
+ * Single <Text> pattern, zero Yoga nodes — all content pre-formatted as strings.
4
+ *
5
+ * PR-F cross-host indicator (design §16, brief §8 answer 3 — Option 3):
6
+ * - Local session (`player.hostname === localHost`) → omit "Host:" field
7
+ * from the metadata line (reduces noise; local is the common case).
8
+ * - Remote session → show `Host: {hostname}` in `THEME.accent` (amber).
9
+ * Zero new Yoga nodes: the host segment goes into the same `<Text>` children
10
+ * tree as an additional nested `<Text>` (virtual text node, not a Box).
11
+ */
12
+ import React from 'react';
13
+ import type { MaestroPlayerInfo, SessionMetadata, Message, SentMessage } from '../../types';
14
+ export interface PlayerDetailViewProps {
15
+ playerId: string;
16
+ ensemble: string;
17
+ player: MaestroPlayerInfo | null;
18
+ metadata: SessionMetadata | null;
19
+ messages: Array<Message | (SentMessage & {
20
+ direction: 'sent';
21
+ })>;
22
+ scrollOffset: number;
23
+ /** Local TUI process hostname. When equal to the player's hostname, the Host field is omitted. */
24
+ localHost?: string;
25
+ }
26
+ export declare function PlayerDetailView({ playerId, player, metadata, messages, scrollOffset, localHost, }: PlayerDetailViewProps): React.CElement<{}, React.Component<{}, any, any>>;
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PlayerDetailView = PlayerDetailView;
7
+ /**
8
+ * PlayerDetailView — shows player metadata + scrollable message history.
9
+ * Single <Text> pattern, zero Yoga nodes — all content pre-formatted as strings.
10
+ *
11
+ * PR-F cross-host indicator (design §16, brief §8 answer 3 — Option 3):
12
+ * - Local session (`player.hostname === localHost`) → omit "Host:" field
13
+ * from the metadata line (reduces noise; local is the common case).
14
+ * - Remote session → show `Host: {hostname}` in `THEME.accent` (amber).
15
+ * Zero new Yoga nodes: the host segment goes into the same `<Text>` children
16
+ * tree as an additional nested `<Text>` (virtual text node, not a Box).
17
+ */
18
+ const react_1 = __importDefault(require("react"));
19
+ const ink_context_1 = require("../ink-context");
20
+ const theme_1 = require("../utils/theme");
21
+ const format_1 = require("../utils/format");
22
+ const platform_1 = require("../utils/platform");
23
+ const MAX_VISIBLE = 20;
24
+ function isSent(m) {
25
+ return 'direction' in m && m.direction === 'sent';
26
+ }
27
+ function formatTime(ts) {
28
+ try {
29
+ const d = new Date(ts);
30
+ return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
31
+ }
32
+ catch {
33
+ return '??:??';
34
+ }
35
+ }
36
+ function PlayerDetailView({ playerId, player, metadata, messages, scrollOffset, localHost, }) {
37
+ const { Text } = (0, ink_context_1.useInk)();
38
+ const children = [];
39
+ // Header — player identity
40
+ const icon = player?.isConductor ? '\u2605 ' : ' ';
41
+ children.push(react_1.default.createElement(Text, { key: 'name', bold: true, color: theme_1.THEME.accent }, `${icon}${playerId}`));
42
+ // Metadata line 1: Type · Status [· Host when remote]
43
+ // Collapse the attachment phase via the Option-B helpers in utils/format.
44
+ const type = player?.playerType || player?.agentType || '(default)';
45
+ const status = (0, format_1.phaseToLabel)(player?.phase);
46
+ const phaseIcons = (0, platform_1.statusIcons)((0, platform_1.supportsUnicode)());
47
+ const statusDot = phaseIcons[(0, format_1.phaseToIconName)(player?.phase)];
48
+ const host = player?.hostname || metadata?.hostname || '';
49
+ const showRemoteHost = Boolean(host && localHost && host !== localHost);
50
+ children.push('\n');
51
+ if (showRemoteHost) {
52
+ // Remote — Host segment rendered in amber, same Text tree (zero Yoga nodes).
53
+ children.push(react_1.default.createElement(Text, { key: 'meta1', color: theme_1.THEME.dim }, ` Type: ${type} \u00B7 Status: ${statusDot} ${status} \u00B7 Host: `, react_1.default.createElement(Text, { color: theme_1.THEME.accent }, host)));
54
+ }
55
+ else {
56
+ // Local (or unknown) — omit Host entirely.
57
+ children.push(react_1.default.createElement(Text, { key: 'meta1', color: theme_1.THEME.dim }, ` Type: ${type} \u00B7 Status: ${statusDot} ${status}`));
58
+ }
59
+ // Metadata line 2: Branch · Dir
60
+ const branch = player?.gitBranch || metadata?.gitBranch || '';
61
+ const dir = metadata?.workDir || player?.workDir || '';
62
+ if (branch || dir) {
63
+ children.push('\n');
64
+ const parts = [];
65
+ if (branch)
66
+ parts.push(`Branch: ${branch}`);
67
+ if (dir)
68
+ parts.push(`Dir: ${dir}`);
69
+ children.push(react_1.default.createElement(Text, { key: 'meta2', color: theme_1.THEME.dim }, ` ${parts.join(' \u00B7 ')}`));
70
+ }
71
+ // Part
72
+ if (player?.part) {
73
+ children.push('\n');
74
+ children.push(react_1.default.createElement(Text, { key: 'part', color: theme_1.THEME.textMuted }, ` Part: ${player.part}`));
75
+ }
76
+ // Divider
77
+ children.push('\n\n');
78
+ children.push(react_1.default.createElement(Text, { key: 'div', color: theme_1.THEME.border }, ' ' + '\u2500'.repeat(55)));
79
+ // Messages header
80
+ const total = messages.length;
81
+ const windowStart = Math.min(scrollOffset, Math.max(0, total - MAX_VISIBLE));
82
+ const visible = messages.slice(windowStart, windowStart + MAX_VISIBLE);
83
+ const earlierCount = windowStart;
84
+ children.push('\n');
85
+ if (total === 0) {
86
+ children.push(react_1.default.createElement(Text, { key: 'nomsg', color: theme_1.THEME.dim }, ' No messages yet.'));
87
+ }
88
+ else {
89
+ children.push(react_1.default.createElement(Text, { key: 'mhdr', color: theme_1.THEME.dim }, ` Messages (${total} total \u00B7 showing ${visible.length})`));
90
+ // #110: use the plural-aware helper instead of hardcoded "earlier messages".
91
+ // The helper returns null for count ≤ 0 / non-finite, subsuming the prior
92
+ // `if (earlierCount > 0)` guard. Singular/plural split is covered by the
93
+ // helper's unit tests in `tests/tui/chat-cap.test.ts`.
94
+ const earlierIndicator = (0, format_1.formatEarlierIndicator)(earlierCount);
95
+ if (earlierIndicator) {
96
+ children.push('\n');
97
+ children.push(react_1.default.createElement(Text, { key: 'earlier', color: theme_1.THEME.dim }, ` ${earlierIndicator}`));
98
+ }
99
+ for (let i = 0; i < visible.length; i++) {
100
+ const m = visible[i];
101
+ const time = formatTime(m.timestamp);
102
+ children.push('\n');
103
+ if (isSent(m)) {
104
+ const preview = m.text.length > 80 ? m.text.slice(0, 77).replace(/\n/g, ' ') + '...' : m.text.replace(/\n/g, ' ');
105
+ children.push(react_1.default.createElement(react_1.default.Fragment, { key: `m-${i}` }, react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ` ${time} `), react_1.default.createElement(Text, { color: theme_1.THEME.accent, bold: true }, '\u276F '), react_1.default.createElement(Text, { color: theme_1.THEME.text }, preview)));
106
+ }
107
+ else {
108
+ const msg = m;
109
+ const preview = msg.text.length > 80 ? msg.text.slice(0, 77).replace(/\n/g, ' ') + '...' : msg.text.replace(/\n/g, ' ');
110
+ children.push(react_1.default.createElement(react_1.default.Fragment, { key: `m-${i}` }, react_1.default.createElement(Text, { color: theme_1.THEME.dim }, ` ${time} \u2190 `), react_1.default.createElement(Text, { color: theme_1.THEME.accent }, `${msg.from}: `), react_1.default.createElement(Text, { color: theme_1.THEME.text }, preview)));
111
+ }
112
+ }
113
+ }
114
+ // Footer hint
115
+ children.push('\n\n');
116
+ children.push(react_1.default.createElement(Text, { key: 'hint', color: theme_1.THEME.dim }, ' \u2191\u2193 scroll \u00B7 Esc back \u00B7 /cue to chat'));
117
+ return react_1.default.createElement(Text, null, ...children);
118
+ }