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,56 @@
1
+ /**
2
+ * Formatting utilities for the TUI.
3
+ * Timestamp formatting, text truncation, duration display,
4
+ * attachment-phase → label/color/icon mapping (post-#177).
5
+ */
6
+ import type { MaestroPlayerInfo } from '../../types';
7
+ /**
8
+ * The maestro session is the TUI's own dashboard attachment — a synthetic
9
+ * "player" the human operator drives directly, not a peer agent. It shows up
10
+ * in the maestro's player list (so `/players` is an honest representation of
11
+ * internal state), but headline counts in the status bar / context string
12
+ * should exclude it. Otherwise a fresh ensemble with one real player reads
13
+ * confusingly as "2 players (1 active, 1 pending)".
14
+ */
15
+ export declare function isMaestroPlayer(p: {
16
+ playerId?: string;
17
+ playerType?: string;
18
+ }): boolean;
19
+ /** Filter the maestro out of a list of players for headline counts. */
20
+ export declare function filterRealPlayers<T extends {
21
+ playerId?: string;
22
+ playerType?: string;
23
+ }>(players: readonly T[]): T[];
24
+ export type { MaestroPlayerInfo };
25
+ /** Format an ISO timestamp as a short time string (HH:MM:SS). */
26
+ export declare function formatTime(iso: string): string;
27
+ /** Format an ISO timestamp as relative time (e.g., "2m ago"). */
28
+ export declare function formatRelativeTime(iso: string): string;
29
+ /** Truncate text to maxLen, appending ellipsis if truncated. */
30
+ export declare function truncate(text: string, maxLen: number, ellipsis?: string): string;
31
+ /** User-facing phase labels shown in the TUI. */
32
+ export type PhaseLabel = 'active' | 'idle' | 'disconnected' | 'pending' | 'gone' | 'unknown';
33
+ /** Icon-bucket name used to key into `statusIcons()` (src/tui/utils/platform.ts). */
34
+ export type PhaseIconName = 'active' | 'stale' | 'pending' | 'blocked' | 'terminated';
35
+ /** Collapse an attachment phase into its user-facing label. */
36
+ export declare function phaseToLabel(phase?: string): PhaseLabel;
37
+ /** Theme color (hex string or undefined under NO_COLOR) for a phase. */
38
+ export declare function phaseToColor(phase?: string): string;
39
+ /** Icon-bucket key for `statusIcons()` for a phase. */
40
+ export declare function phaseToIconName(phase?: string): PhaseIconName;
41
+ /**
42
+ * Word-wrap text to fit within maxWidth, breaking at word boundaries.
43
+ * Each original newline starts a new line. Returns at least one line.
44
+ */
45
+ export declare function wordWrap(text: string, maxWidth: number): string[];
46
+ /**
47
+ * Format the "↑ N earlier message(s)" indicator shown above a truncated
48
+ * message list. Returns null when no indicator should render.
49
+ *
50
+ * - count <= 0 → null (no indicator)
51
+ * - count === 1 → "↑ 1 earlier message" (singular)
52
+ * - count >= 2 → "↑ N earlier messages" (plural)
53
+ */
54
+ export declare function formatEarlierIndicator(count: number): string | null;
55
+ /** Format an event type for display. */
56
+ export declare function formatEventType(type: string): string;
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ /**
3
+ * Formatting utilities for the TUI.
4
+ * Timestamp formatting, text truncation, duration display,
5
+ * attachment-phase → label/color/icon mapping (post-#177).
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.isMaestroPlayer = isMaestroPlayer;
9
+ exports.filterRealPlayers = filterRealPlayers;
10
+ exports.formatTime = formatTime;
11
+ exports.formatRelativeTime = formatRelativeTime;
12
+ exports.truncate = truncate;
13
+ exports.phaseToLabel = phaseToLabel;
14
+ exports.phaseToColor = phaseToColor;
15
+ exports.phaseToIconName = phaseToIconName;
16
+ exports.wordWrap = wordWrap;
17
+ exports.formatEarlierIndicator = formatEarlierIndicator;
18
+ exports.formatEventType = formatEventType;
19
+ const theme_1 = require("./theme");
20
+ /**
21
+ * The maestro session is the TUI's own dashboard attachment — a synthetic
22
+ * "player" the human operator drives directly, not a peer agent. It shows up
23
+ * in the maestro's player list (so `/players` is an honest representation of
24
+ * internal state), but headline counts in the status bar / context string
25
+ * should exclude it. Otherwise a fresh ensemble with one real player reads
26
+ * confusingly as "2 players (1 active, 1 pending)".
27
+ */
28
+ function isMaestroPlayer(p) {
29
+ return p.playerId === 'maestro' || p.playerType === 'maestro';
30
+ }
31
+ /** Filter the maestro out of a list of players for headline counts. */
32
+ function filterRealPlayers(players) {
33
+ return players.filter((p) => !isMaestroPlayer(p));
34
+ }
35
+ /** Format an ISO timestamp as a short time string (HH:MM:SS). */
36
+ function formatTime(iso) {
37
+ try {
38
+ const d = new Date(iso);
39
+ return d.toLocaleTimeString('en-US', { hour12: false });
40
+ }
41
+ catch {
42
+ return iso;
43
+ }
44
+ }
45
+ /** Format an ISO timestamp as relative time (e.g., "2m ago"). */
46
+ function formatRelativeTime(iso) {
47
+ try {
48
+ const ms = Date.now() - new Date(iso).getTime();
49
+ if (ms < 0)
50
+ return 'just now';
51
+ if (ms < 60_000)
52
+ return `${Math.floor(ms / 1000)}s ago`;
53
+ if (ms < 3_600_000)
54
+ return `${Math.floor(ms / 60_000)}m ago`;
55
+ if (ms < 86_400_000)
56
+ return `${Math.floor(ms / 3_600_000)}h ago`;
57
+ return `${Math.floor(ms / 86_400_000)}d ago`;
58
+ }
59
+ catch {
60
+ return iso;
61
+ }
62
+ }
63
+ /** Truncate text to maxLen, appending ellipsis if truncated. */
64
+ function truncate(text, maxLen, ellipsis = '...') {
65
+ if (text.length <= maxLen)
66
+ return text;
67
+ return text.slice(0, maxLen - ellipsis.length) + ellipsis;
68
+ }
69
+ const PHASE_TO_LABEL = Object.freeze({
70
+ attached: 'active',
71
+ processing: 'active',
72
+ awaiting: 'idle',
73
+ draining: 'disconnected',
74
+ detached: 'disconnected',
75
+ booting: 'pending',
76
+ gone: 'gone',
77
+ });
78
+ const LABEL_TO_COLOR = Object.freeze({
79
+ active: theme_1.THEME.success,
80
+ idle: theme_1.THEME.text,
81
+ disconnected: theme_1.THEME.warning,
82
+ pending: theme_1.THEME.dim,
83
+ gone: theme_1.THEME.dim,
84
+ unknown: theme_1.THEME.text,
85
+ });
86
+ const LABEL_TO_ICON_NAME = Object.freeze({
87
+ active: 'active', // ● (filled)
88
+ idle: 'stale', // ○ (hollow, neutral)
89
+ disconnected: 'blocked', // ◐ (half, yellow)
90
+ pending: 'pending', // ◔ (quarter, dim)
91
+ gone: 'terminated', // ✕
92
+ unknown: 'blocked', // ? → cautionary
93
+ });
94
+ /** Collapse an attachment phase into its user-facing label. */
95
+ function phaseToLabel(phase) {
96
+ if (!phase)
97
+ return 'unknown';
98
+ return PHASE_TO_LABEL[phase] ?? 'unknown';
99
+ }
100
+ /** Theme color (hex string or undefined under NO_COLOR) for a phase. */
101
+ function phaseToColor(phase) {
102
+ return LABEL_TO_COLOR[phaseToLabel(phase)];
103
+ }
104
+ /** Icon-bucket key for `statusIcons()` for a phase. */
105
+ function phaseToIconName(phase) {
106
+ return LABEL_TO_ICON_NAME[phaseToLabel(phase)];
107
+ }
108
+ /**
109
+ * Word-wrap text to fit within maxWidth, breaking at word boundaries.
110
+ * Each original newline starts a new line. Returns at least one line.
111
+ */
112
+ function wordWrap(text, maxWidth) {
113
+ if (maxWidth < 1)
114
+ return [text];
115
+ const result = [];
116
+ for (const raw of text.split('\n')) {
117
+ const words = raw.split(' ');
118
+ let current = '';
119
+ for (const word of words) {
120
+ if (current && current.length + 1 + word.length > maxWidth) {
121
+ result.push(current);
122
+ current = word;
123
+ }
124
+ else {
125
+ current = current ? current + ' ' + word : word;
126
+ }
127
+ }
128
+ result.push(current);
129
+ }
130
+ return result.length > 0 ? result : [''];
131
+ }
132
+ /**
133
+ * Format the "↑ N earlier message(s)" indicator shown above a truncated
134
+ * message list. Returns null when no indicator should render.
135
+ *
136
+ * - count <= 0 → null (no indicator)
137
+ * - count === 1 → "↑ 1 earlier message" (singular)
138
+ * - count >= 2 → "↑ N earlier messages" (plural)
139
+ */
140
+ function formatEarlierIndicator(count) {
141
+ if (!Number.isFinite(count) || count <= 0)
142
+ return null;
143
+ const label = count === 1 ? 'earlier message' : 'earlier messages';
144
+ return `\u2191 ${count} ${label}`;
145
+ }
146
+ /** Format an event type for display. */
147
+ function formatEventType(type) {
148
+ switch (type) {
149
+ case 'player_joined': return 'joined';
150
+ case 'player_left': return 'left';
151
+ case 'status_changed': return 'status';
152
+ case 'part_changed': return 'part';
153
+ default: return type;
154
+ }
155
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Fullscreen utilities for the TUI.
3
+ *
4
+ * Clears the screen and hides the cursor on entry, shows cursor on exit.
5
+ * Stays on the primary screen buffer so <Static> items become native
6
+ * terminal scrollback that persists after exit.
7
+ */
8
+ /** Whether fullscreen mode is supported and enabled. */
9
+ export declare function fullscreenSupported(): boolean;
10
+ /**
11
+ * Enter fullscreen mode — clears the screen and hides the cursor.
12
+ * Stays on the primary buffer so Static items persist as scrollback.
13
+ * No-op if fullscreen is not supported.
14
+ * @returns true if fullscreen was entered, false if skipped.
15
+ */
16
+ export declare function enterFullscreen(): boolean;
17
+ /**
18
+ * Exit fullscreen mode — shows the cursor.
19
+ * No buffer restore needed since we stay on the primary buffer.
20
+ * Safe to call even if fullscreen was never entered.
21
+ */
22
+ export declare function exitFullscreen(): void;
23
+ export declare function registerFullscreenCleanup(): void;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ /**
3
+ * Fullscreen utilities for the TUI.
4
+ *
5
+ * Clears the screen and hides the cursor on entry, shows cursor on exit.
6
+ * Stays on the primary screen buffer so <Static> items become native
7
+ * terminal scrollback that persists after exit.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.fullscreenSupported = fullscreenSupported;
11
+ exports.enterFullscreen = enterFullscreen;
12
+ exports.exitFullscreen = exitFullscreen;
13
+ exports.registerFullscreenCleanup = registerFullscreenCleanup;
14
+ /** Whether fullscreen mode is supported and enabled. */
15
+ function fullscreenSupported() {
16
+ // User opt-out
17
+ if (process.env.AGENT_TEMPO_NO_FULLSCREEN === '1')
18
+ return false;
19
+ // Legacy cmd.exe on Windows doesn't support alternate buffer.
20
+ // Windows Terminal sets WT_SESSION; if absent on win32, skip.
21
+ if (process.platform === 'win32' && !process.env.WT_SESSION)
22
+ return false;
23
+ // Need a writable stdout
24
+ if (!process.stdout.isTTY)
25
+ return false;
26
+ return true;
27
+ }
28
+ /**
29
+ * Enter fullscreen mode — clears the screen and hides the cursor.
30
+ * Stays on the primary buffer so Static items persist as scrollback.
31
+ * No-op if fullscreen is not supported.
32
+ * @returns true if fullscreen was entered, false if skipped.
33
+ */
34
+ function enterFullscreen() {
35
+ if (!fullscreenSupported())
36
+ return false;
37
+ // Clear screen + cursor home + hide cursor (no alternate buffer)
38
+ process.stdout.write('\x1b[2J\x1b[H\x1b[?25l');
39
+ return true;
40
+ }
41
+ /**
42
+ * Exit fullscreen mode — shows the cursor.
43
+ * No buffer restore needed since we stay on the primary buffer.
44
+ * Safe to call even if fullscreen was never entered.
45
+ */
46
+ function exitFullscreen() {
47
+ // Show cursor (no buffer restore — primary buffer preserved)
48
+ process.stdout.write('\x1b[?25h');
49
+ }
50
+ /**
51
+ * Register cleanup handlers to exit fullscreen on process termination.
52
+ * Call once after enterFullscreen(). Idempotent — guards against double-registration.
53
+ */
54
+ let cleanupRegistered = false;
55
+ function registerFullscreenCleanup() {
56
+ if (cleanupRegistered)
57
+ return;
58
+ cleanupRegistered = true;
59
+ const cleanup = () => {
60
+ exitFullscreen();
61
+ };
62
+ process.on('exit', cleanup);
63
+ process.on('SIGINT', () => {
64
+ cleanup();
65
+ process.exit(0);
66
+ });
67
+ process.on('SIGTERM', () => {
68
+ cleanup();
69
+ process.exit(0);
70
+ });
71
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Load command history from disk.
3
+ * Returns empty array if file doesn't exist or is corrupted.
4
+ */
5
+ export declare function loadHistory(): string[];
6
+ /**
7
+ * Save command history to disk.
8
+ * Creates ~/.agent-tempo/ if it doesn't exist.
9
+ */
10
+ export declare function saveHistory(entries: string[]): void;
@@ -0,0 +1,85 @@
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.loadHistory = loadHistory;
37
+ exports.saveHistory = saveHistory;
38
+ /**
39
+ * Persistent command history for the TUI.
40
+ * Saves to ~/.agent-tempo/tui-history.json.
41
+ */
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ const os = __importStar(require("os"));
45
+ const HISTORY_DIR = path.join(os.homedir(), '.agent-tempo');
46
+ const HISTORY_FILE = path.join(HISTORY_DIR, 'tui-history.json');
47
+ const MAX_ENTRIES = 500;
48
+ const CURRENT_VERSION = 1;
49
+ /**
50
+ * Load command history from disk.
51
+ * Returns empty array if file doesn't exist or is corrupted.
52
+ */
53
+ function loadHistory() {
54
+ try {
55
+ if (!fs.existsSync(HISTORY_FILE))
56
+ return [];
57
+ const raw = fs.readFileSync(HISTORY_FILE, 'utf-8');
58
+ const data = JSON.parse(raw);
59
+ if (data.version !== CURRENT_VERSION || !Array.isArray(data.entries))
60
+ return [];
61
+ return data.entries.slice(-MAX_ENTRIES);
62
+ }
63
+ catch {
64
+ return [];
65
+ }
66
+ }
67
+ /**
68
+ * Save command history to disk.
69
+ * Creates ~/.agent-tempo/ if it doesn't exist.
70
+ */
71
+ function saveHistory(entries) {
72
+ try {
73
+ if (!fs.existsSync(HISTORY_DIR)) {
74
+ fs.mkdirSync(HISTORY_DIR, { recursive: true });
75
+ }
76
+ const data = {
77
+ version: CURRENT_VERSION,
78
+ entries: entries.slice(-MAX_ENTRIES),
79
+ };
80
+ fs.writeFileSync(HISTORY_FILE, JSON.stringify(data, null, 2), 'utf-8');
81
+ }
82
+ catch {
83
+ // Silently fail — history is non-critical
84
+ }
85
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Platform detection utilities for the TUI.
3
+ * Determines Unicode support, SSH sessions, and terminal capabilities.
4
+ */
5
+ /** Whether the terminal supports Unicode box-drawing and status icons. */
6
+ export declare function supportsUnicode(): boolean;
7
+ /** Whether we're running inside an SSH session. */
8
+ export declare function isSSH(): boolean;
9
+ /** Get terminal dimensions, with minimum fallback. */
10
+ export declare function getTerminalSize(): {
11
+ columns: number;
12
+ rows: number;
13
+ };
14
+ /** Minimum terminal size for the TUI. */
15
+ export declare const MIN_COLUMNS = 80;
16
+ export declare const MIN_ROWS = 24;
17
+ /** Check if terminal meets minimum size requirements. */
18
+ export declare function isTerminalLargeEnough(): boolean;
19
+ /** Status icons — Unicode by default, ASCII fallback. */
20
+ export declare function statusIcons(unicode?: boolean): {
21
+ active: string;
22
+ stale: string;
23
+ pending: string;
24
+ blocked: string;
25
+ terminated: string;
26
+ conductor: string;
27
+ player: string;
28
+ arrow: string;
29
+ check: string;
30
+ cross: string;
31
+ ellipsis: string;
32
+ };
33
+ /** A colored text segment for braille rendering. */
34
+ export interface BrailleSegment {
35
+ char: string;
36
+ color: string;
37
+ }
38
+ /** A row of braille segments (may have mixed colors). */
39
+ export type BrailleLine = BrailleSegment[];
40
+ /**
41
+ * Braille metronome — 3 frames (left, center, right).
42
+ * Renders at 60×48 dot resolution (30 cols × 12 rows of braille characters).
43
+ * Thin hairline triangle outline with thin pendulum arm and small pivot dot.
44
+ */
45
+ export declare function metronomeBrailleFrames(): BrailleLine[][];