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,303 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * scripts/258-spotcheck.ts — automated #258 "one-delivery-then-silence" probe
5
+ *
6
+ * Ops tooling for the v0.26.0-beta.4 burn-in window (issue #258). Replaces
7
+ * the manual 4-step analysis performed by tempo-researcher on 2026-04-19
8
+ * at ~T+2h into the burn-in (dump at C:\tmp\wf-conductor-burnin.json). Run
9
+ * this whenever you want a fresh read on whether the #249 fix is still
10
+ * holding under real ensemble traffic.
11
+ *
12
+ * NOT committed. NOT production code. No tests, no docs. If this script
13
+ * stops working because the wire protocol evolves, delete and rewrite.
14
+ *
15
+ * ── Usage ─────────────────────────────────────────────────────────────
16
+ *
17
+ * npx ts-node --project scripts/tsconfig.json scripts/258-spotcheck.ts
18
+ *
19
+ * Flags (all optional):
20
+ * --ensemble <name> Override ensemble (default: $CLAUDE_TEMPO_ENSEMBLE or 'tempo-impl')
21
+ * --conductor <name> Override conductor player name (default: 'conductor')
22
+ * --json Emit JSON instead of the human table
23
+ * --save <path> Write full report JSON to <path>
24
+ *
25
+ * ── Exit codes ────────────────────────────────────────────────────────
26
+ * 0 pattern-not-detected (healthy)
27
+ * 1 unexpected error (Temporal unreachable, workflow missing, etc.)
28
+ * 2 pattern-recurring (hypothesis A or B) — HIGH PRIORITY
29
+ * 3 inconclusive-too-early (< 30 min window)
30
+ *
31
+ * ── Assumptions ───────────────────────────────────────────────────────
32
+ * • Temporal server reachable via the canonical getConfig() chain
33
+ * (localhost:7233 default; overridable via TEMPORAL_ADDRESS,
34
+ * ~/.claude-tempo/config.json, or ~/.config/temporalio/temporal.yaml).
35
+ * • Conductor workflow ID = `claude-session-{ensemble}-conductor`
36
+ * (src/config.ts::conductorWorkflowId). For non-default ensembles,
37
+ * set CLAUDE_TEMPO_ENSEMBLE or pass --ensemble.
38
+ * • Reads the *current* run via handle-without-runId. If a CAN has
39
+ * occurred, the SDK returns the latest run — which is exactly what
40
+ * we want for post-CAN health.
41
+ * • Signal / update names are per docs/WIRE-PROTOCOL.md (stable):
42
+ * Signals: 'heartbeat', 'markDelivered', 'receiveMessage',
43
+ * 'playerReport', 'setPaused', 'setPart', 'releaseHeld', ...
44
+ * Updates: 'claimAttachment', 'submitOutbox', ...
45
+ *
46
+ * ── #258 pattern definitions (from C:\tmp\spike-0d17dc0f-verdict.md) ──
47
+ *
48
+ * • Hypothesis A — adapter process death:
49
+ * heartbeats stop mid-window, markDelivered goes silent while
50
+ * receiveMessage continues arriving, NO reclaim attempts.
51
+ *
52
+ * • Hypothesis B — delayed fireTerminal('destroy') via reconnect loop:
53
+ * same silence signature, PLUS at least one claimAttachment reclaim
54
+ * fired after the silence started (adapter tried to recover, then
55
+ * a terminal-class error on the pre-check killed the poller).
56
+ *
57
+ * Thresholds used here (conservative; tune if we recalibrate):
58
+ * – Heartbeat staleness: > 180 s since last (3× expected 60 s cadence)
59
+ * – Silence skew: receiveMessage last-ts > markDelivered last-ts + 60 s
60
+ * – Too-early window: total history span < 30 min
61
+ */
62
+ Object.defineProperty(exports, "__esModule", { value: true });
63
+ const client_1 = require("@temporalio/client");
64
+ const fs_1 = require("fs");
65
+ const config_1 = require("../src/config");
66
+ const connection_1 = require("../src/connection");
67
+ // ─── CLI ──────────────────────────────────────────────────────────────
68
+ const args = process.argv.slice(2);
69
+ function argVal(flag) {
70
+ const i = args.indexOf(flag);
71
+ return i >= 0 && i + 1 < args.length ? args[i + 1] : undefined;
72
+ }
73
+ const emitJson = args.includes('--json');
74
+ const savePath = argVal('--save');
75
+ const ensembleOverride = argVal('--ensemble');
76
+ const conductorNameOverride = argVal('--conductor') ?? 'conductor';
77
+ // ─── Helpers ──────────────────────────────────────────────────────────
78
+ function tsIso(t) {
79
+ // Temporal SDK decodes protobuf Timestamp to { seconds: Long|number|bigint, nanos: number }.
80
+ // Fall back through a few shapes defensively; the SDK's Long type has .toNumber().
81
+ if (!t)
82
+ return '';
83
+ if (typeof t === 'string')
84
+ return t;
85
+ const rawSeconds = t.seconds;
86
+ let seconds;
87
+ if (typeof rawSeconds === 'bigint')
88
+ seconds = Number(rawSeconds);
89
+ else if (typeof rawSeconds === 'number')
90
+ seconds = rawSeconds;
91
+ else if (rawSeconds && typeof rawSeconds.toNumber === 'function')
92
+ seconds = rawSeconds.toNumber();
93
+ else
94
+ seconds = 0;
95
+ const nanos = typeof t.nanos === 'number' ? t.nanos : 0;
96
+ return new Date(seconds * 1000 + nanos / 1e6).toISOString();
97
+ }
98
+ function addStat(map, name, ts) {
99
+ const s = map.get(name) ?? { count: 0 };
100
+ s.count++;
101
+ if (!s.first)
102
+ s.first = ts;
103
+ s.last = ts;
104
+ map.set(name, s);
105
+ }
106
+ function isoToMs(iso) {
107
+ return iso ? new Date(iso).getTime() : 0;
108
+ }
109
+ function fmtDur(ms) {
110
+ const s = Math.max(0, Math.floor(ms / 1000));
111
+ const h = Math.floor(s / 3600);
112
+ const m = Math.floor((s % 3600) / 60);
113
+ const ss = s % 60;
114
+ return h ? `${h}h ${m}m ${ss}s` : `${m}m ${ss}s`;
115
+ }
116
+ function fmtSec(ms) {
117
+ return ms === null ? 'n/a' : `${(ms / 1000).toFixed(1)}s`;
118
+ }
119
+ // ─── Main ─────────────────────────────────────────────────────────────
120
+ async function run() {
121
+ const config = (0, config_1.getConfig)();
122
+ const ensemble = ensembleOverride ?? config.ensemble ?? 'tempo-impl';
123
+ const workflowId = conductorNameOverride === 'conductor'
124
+ ? (0, config_1.conductorWorkflowId)(ensemble)
125
+ : `claude-session-${ensemble}-${conductorNameOverride}`;
126
+ const connection = await (0, connection_1.createTemporalConnection)(config);
127
+ try {
128
+ const client = new client_1.Client({ connection, namespace: config.temporalNamespace });
129
+ const handle = client.workflow.getHandle(workflowId);
130
+ const history = await handle.fetchHistory();
131
+ const events = history.events ?? [];
132
+ if (events.length === 0) {
133
+ throw new Error(`Workflow "${workflowId}" returned no events — is it running? (ensemble="${ensemble}", ns="${config.temporalNamespace}", addr="${config.temporalAddress}")`);
134
+ }
135
+ // Run identity (first event is EXECUTION_STARTED; capture its runId).
136
+ let runId = '(unknown)';
137
+ const startedAttrs = events[0].workflowExecutionStartedEventAttributes;
138
+ if (startedAttrs?.originalExecutionRunId)
139
+ runId = startedAttrs.originalExecutionRunId;
140
+ const signals = new Map();
141
+ const updates = new Map();
142
+ const hbTimes = [];
143
+ for (const e of events) {
144
+ const ts = tsIso(e.eventTime);
145
+ // Presence-of-attribute pattern — matches how src/adapters/base.ts
146
+ // detects CAN events. Avoids coupling to the numeric eventType enum.
147
+ if (e.workflowExecutionSignaledEventAttributes) {
148
+ const name = e.workflowExecutionSignaledEventAttributes.signalName ?? '<unknown>';
149
+ addStat(signals, name, ts);
150
+ if (name === 'heartbeat')
151
+ hbTimes.push(isoToMs(ts));
152
+ continue;
153
+ }
154
+ if (e.workflowExecutionUpdateAcceptedEventAttributes) {
155
+ const req = e.workflowExecutionUpdateAcceptedEventAttributes.acceptedRequest;
156
+ const name = req?.input?.name ?? '<unknown>';
157
+ addStat(updates, name, ts);
158
+ continue;
159
+ }
160
+ }
161
+ // Window = first event -> last event
162
+ const windowStart = tsIso(events[0].eventTime);
163
+ const windowEnd = tsIso(events[events.length - 1].eventTime);
164
+ const windowMs = isoToMs(windowEnd) - isoToMs(windowStart);
165
+ // Heartbeat cadence stats
166
+ let minGap = null;
167
+ let maxGap = null;
168
+ let meanGap = null;
169
+ if (hbTimes.length >= 2) {
170
+ const gaps = [];
171
+ for (let i = 1; i < hbTimes.length; i++)
172
+ gaps.push(hbTimes[i] - hbTimes[i - 1]);
173
+ minGap = Math.min(...gaps);
174
+ maxGap = Math.max(...gaps);
175
+ meanGap = gaps.reduce((a, b) => a + b, 0) / gaps.length;
176
+ }
177
+ const nowMs = Date.now();
178
+ const STALE_MS = 180000; // 3× 60 s expected cadence
179
+ const msSinceLast = hbTimes.length ? nowMs - hbTimes[hbTimes.length - 1] : null;
180
+ const stalled = msSinceLast !== null && msSinceLast > STALE_MS;
181
+ // Silence-skew detector: markDelivered silent while receiveMessage continues.
182
+ const receiveLast = signals.get('receiveMessage')?.last;
183
+ const markLast = signals.get('markDelivered')?.last;
184
+ const skew = !!receiveLast &&
185
+ !!markLast &&
186
+ isoToMs(receiveLast) > isoToMs(markLast) + 60000;
187
+ // Reclaim-after-silence detector (hypothesis B): a claimAttachment
188
+ // update fired AFTER markDelivered went quiet.
189
+ const claimLast = updates.get('claimAttachment')?.last;
190
+ const reclaimAfterSilence = !!claimLast && !!markLast && isoToMs(claimLast) > isoToMs(markLast) + 60000;
191
+ // ── Verdict ─────────────────────────────────────────────────────────
192
+ const TOO_EARLY_MS = 30 * 60 * 1000;
193
+ let verdict;
194
+ let verdictReason;
195
+ if (windowMs < TOO_EARLY_MS) {
196
+ verdict = 'inconclusive-too-early';
197
+ verdictReason = `window ${fmtDur(windowMs)} < 30 min minimum — re-run later.`;
198
+ }
199
+ else if (stalled && skew && reclaimAfterSilence) {
200
+ verdict = 'pattern-recurring-hypothesis-B';
201
+ verdictReason = `heartbeats stale (${fmtSec(msSinceLast)}); markDelivered silent while receiveMessage continued; claimAttachment reclaim fired after silence — consistent with delayed fireTerminal('destroy').`;
202
+ }
203
+ else if (stalled && skew) {
204
+ verdict = 'pattern-recurring-hypothesis-A';
205
+ verdictReason = `heartbeats stale (${fmtSec(msSinceLast)}); markDelivered silent while receiveMessage continued; no reclaim — consistent with adapter process death.`;
206
+ }
207
+ else if (stalled) {
208
+ verdict = 'pattern-recurring-hypothesis-A';
209
+ verdictReason = `heartbeats stale (${fmtSec(msSinceLast)} > ${STALE_MS / 1000}s threshold); no inbound-vs-outbound skew detected but cadence is broken.`;
210
+ }
211
+ else {
212
+ verdict = 'pattern-not-detected';
213
+ const lastPart = msSinceLast !== null ? `last tick ${fmtSec(msSinceLast)} ago` : 'no heartbeats';
214
+ const maxPart = maxGap !== null ? `max gap ${fmtSec(maxGap)}` : '';
215
+ verdictReason = `heartbeat cadence healthy (${lastPart}${maxPart ? `, ${maxPart}` : ''}); no signal-flow anomaly.`;
216
+ }
217
+ return {
218
+ workflowId,
219
+ runId,
220
+ windowStart,
221
+ windowEnd,
222
+ windowMs,
223
+ eventCount: events.length,
224
+ signals: Object.fromEntries(signals),
225
+ updates: Object.fromEntries(updates),
226
+ heartbeat: {
227
+ count: hbTimes.length,
228
+ minGapMs: minGap,
229
+ maxGapMs: maxGap,
230
+ meanGapMs: meanGap,
231
+ staleThresholdMs: STALE_MS,
232
+ msSinceLast,
233
+ stalled,
234
+ },
235
+ verdict,
236
+ verdictReason,
237
+ capturedAt: new Date().toISOString(),
238
+ };
239
+ }
240
+ finally {
241
+ await connection.close();
242
+ }
243
+ }
244
+ function printHuman(r) {
245
+ const sep = '─'.repeat(74);
246
+ console.log(`\n${sep}`);
247
+ console.log(`#258 spot-check — ${r.workflowId}`);
248
+ console.log(sep);
249
+ console.log(`Run: ${r.runId}`);
250
+ console.log(`Window: ${r.windowStart} → ${r.windowEnd}`);
251
+ console.log(` ${fmtDur(r.windowMs)}, ${r.eventCount} events`);
252
+ console.log(`Captured: ${r.capturedAt}`);
253
+ console.log();
254
+ console.log('Signal counts:');
255
+ const sigRows = Object.entries(r.signals).sort((a, b) => b[1].count - a[1].count);
256
+ if (sigRows.length === 0)
257
+ console.log(' (none)');
258
+ for (const [name, s] of sigRows) {
259
+ console.log(` ${name.padEnd(22)} ${String(s.count).padStart(4)} first=${s.first} last=${s.last}`);
260
+ }
261
+ console.log('\nAccepted-update counts:');
262
+ const updRows = Object.entries(r.updates).sort((a, b) => b[1].count - a[1].count);
263
+ if (updRows.length === 0)
264
+ console.log(' (none)');
265
+ for (const [name, s] of updRows) {
266
+ console.log(` ${name.padEnd(22)} ${String(s.count).padStart(4)} first=${s.first} last=${s.last}`);
267
+ }
268
+ console.log('\nHeartbeat cadence:');
269
+ const hb = r.heartbeat;
270
+ console.log(` count=${hb.count} min=${fmtSec(hb.minGapMs)} max=${fmtSec(hb.maxGapMs)} mean=${fmtSec(hb.meanGapMs)}`);
271
+ console.log(` since last heartbeat: ${fmtSec(hb.msSinceLast)} stale threshold: ${hb.staleThresholdMs / 1000}s stalled=${hb.stalled ? 'YES' : 'no'}`);
272
+ console.log(`\nVerdict: ${r.verdict}`);
273
+ console.log(` ${r.verdictReason}`);
274
+ console.log();
275
+ }
276
+ run()
277
+ .then((r) => {
278
+ if (emitJson) {
279
+ console.log(JSON.stringify(r, null, 2));
280
+ }
281
+ else {
282
+ printHuman(r);
283
+ }
284
+ if (savePath) {
285
+ (0, fs_1.writeFileSync)(savePath, JSON.stringify(r, null, 2));
286
+ if (!emitJson)
287
+ console.log(`(saved report JSON to ${savePath})`);
288
+ }
289
+ switch (r.verdict) {
290
+ case 'pattern-not-detected':
291
+ process.exit(0);
292
+ case 'inconclusive-too-early':
293
+ process.exit(3);
294
+ default:
295
+ process.exit(2); // hypothesis-A or hypothesis-B — escalate
296
+ }
297
+ })
298
+ .catch((err) => {
299
+ console.error('\n[258-spotcheck] error:', err instanceof Error ? err.message : err);
300
+ if (err instanceof Error && err.stack)
301
+ console.error(err.stack);
302
+ process.exit(1);
303
+ });
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ /**
38
+ * Drift report for `dashboard/src/styles/components.css` — F-LEAD-1
39
+ * follow-up (PR-B of #454).
40
+ *
41
+ * The dashboard's `components.css` is a SELECTIVE port of the canonical
42
+ * hand-off bundle at `docs/design/dashboard-handoff/project/styles.css`.
43
+ * The port is re-synced manually each minor release until shadcn lands
44
+ * (see `docs/design/components-css-port-procedure.md`). This script
45
+ * surfaces how stale the port is — reads the LAST-SYNC commit out of
46
+ * the file's header and compares it against the most recent canonical
47
+ * commit. The number you see is the *line count of canonical drift*,
48
+ * not the number of impl-side edits required to absorb it.
49
+ *
50
+ * Output:
51
+ * - 0 added/deleted lines → exit 0, "in sync"
52
+ * - 1..49 lines → exit 0, "minor drift"
53
+ * - 50..150 lines → exit 0, prints WARN banner
54
+ * (CI may treat as warning)
55
+ * - 151+ lines → exit 1, prints FAIL banner
56
+ * (CI hard-fails, PR-B-style
57
+ * re-sync needed)
58
+ *
59
+ * Usage:
60
+ * npm run build:scripts
61
+ * node dist/scripts/check-components-css-sync.js
62
+ *
63
+ * Or one-shot via ts-node:
64
+ * npx ts-node scripts/check-components-css-sync.ts
65
+ *
66
+ * CI integration:
67
+ * The `dashboard-build` job in `.github/workflows/...` runs the
68
+ * compiled `dist/scripts/check-components-css-sync.js` after the
69
+ * dashboard build. Failure mode (>150 lines) blocks merge.
70
+ */
71
+ const fs = __importStar(require("fs"));
72
+ const path = __importStar(require("path"));
73
+ const child_process_1 = require("child_process");
74
+ const REPO_ROOT = path.resolve(__dirname, '..', '..');
75
+ const COMPONENTS_CSS = path.join(REPO_ROOT, 'dashboard', 'src', 'styles', 'components.css');
76
+ const CANONICAL_CSS_REPO = path.join('docs', 'design', 'dashboard-handoff', 'project', 'styles.css');
77
+ const CANONICAL_CSS_FS = path.join(REPO_ROOT, CANONICAL_CSS_REPO);
78
+ const WARN_THRESHOLD = 50;
79
+ const FAIL_THRESHOLD = 150;
80
+ const EXIT_OK = 0;
81
+ const EXIT_FAIL = 1;
82
+ const EXIT_USAGE = 2;
83
+ function fail(msg) {
84
+ console.error(`[check-components-css-sync] ${msg}`);
85
+ process.exit(EXIT_USAGE);
86
+ }
87
+ function readLastSyncCommit() {
88
+ if (!fs.existsSync(COMPONENTS_CSS)) {
89
+ fail(`components.css not found at ${COMPONENTS_CSS}`);
90
+ }
91
+ const head = fs.readFileSync(COMPONENTS_CSS, 'utf8').slice(0, 4000);
92
+ const match = head.match(/LAST-SYNC COMMIT:\s+([0-9a-f]{7,40})/i);
93
+ if (!match) {
94
+ fail('components.css header is missing the "LAST-SYNC COMMIT: <sha>" line. ' +
95
+ 'The drift detector cannot run without a baseline. Re-add the marker per ' +
96
+ 'docs/design/components-css-port-procedure.md.');
97
+ }
98
+ return match[1];
99
+ }
100
+ function git(...args) {
101
+ return (0, child_process_1.execFileSync)('git', args, { cwd: REPO_ROOT, encoding: 'utf8' }).trim();
102
+ }
103
+ function commitExists(sha) {
104
+ try {
105
+ git('cat-file', '-e', `${sha}^{commit}`);
106
+ return true;
107
+ }
108
+ catch {
109
+ return false;
110
+ }
111
+ }
112
+ /**
113
+ * If the LAST-SYNC commit isn't in the local object DB (typical of
114
+ * GitHub Actions' default shallow checkout), try to fetch it directly.
115
+ * Belt-and-braces with the workflow-level `fetch-depth: 0` — if a future
116
+ * job copies the script without copying that checkout option, the script
117
+ * still self-heals instead of hard-failing.
118
+ *
119
+ * Returns true if the commit is reachable after the attempted fetch.
120
+ * Stays silent on success; logs the fetch attempt on failure for diagnostics.
121
+ */
122
+ function tryFetchCommit(sha) {
123
+ try {
124
+ // `--no-tags --depth=1` is enough — we only need the commit object
125
+ // for `git diff`, not its ancestry.
126
+ (0, child_process_1.execFileSync)('git', ['fetch', '--no-tags', '--depth=1', 'origin', sha], {
127
+ cwd: REPO_ROOT,
128
+ encoding: 'utf8',
129
+ stdio: 'pipe',
130
+ });
131
+ return commitExists(sha);
132
+ }
133
+ catch (err) {
134
+ console.error(`[check-components-css-sync] git fetch origin ${sha.slice(0, 12)} failed:`);
135
+ console.error(' ' + (err instanceof Error ? err.message : String(err)).split('\n').join('\n '));
136
+ return false;
137
+ }
138
+ }
139
+ function latestCanonicalCommit() {
140
+ const sha = git('log', '-1', '--format=%H', '--', CANONICAL_CSS_REPO);
141
+ if (!sha) {
142
+ fail(`git log returned no commits for ${CANONICAL_CSS_REPO}. ` +
143
+ 'Either the file path is wrong or the repo has no history yet.');
144
+ }
145
+ return sha;
146
+ }
147
+ function diffLineCount(fromSha, toSha) {
148
+ if (fromSha === toSha)
149
+ return 0;
150
+ // `git diff --shortstat` gives "1 file changed, X insertions(+), Y deletions(-)".
151
+ const out = git('diff', '--shortstat', `${fromSha}..${toSha}`, '--', CANONICAL_CSS_REPO);
152
+ if (!out)
153
+ return 0;
154
+ const ins = /(\d+) insertion/.exec(out);
155
+ const del = /(\d+) deletion/.exec(out);
156
+ return (ins ? parseInt(ins[1], 10) : 0) + (del ? parseInt(del[1], 10) : 0);
157
+ }
158
+ function main() {
159
+ if (!fs.existsSync(CANONICAL_CSS_FS)) {
160
+ fail(`canonical CSS not found at ${CANONICAL_CSS_FS}`);
161
+ }
162
+ const lastSync = readLastSyncCommit();
163
+ if (!commitExists(lastSync) && !tryFetchCommit(lastSync)) {
164
+ fail(`LAST-SYNC commit ${lastSync} is not in the local git history and could ` +
165
+ 'not be fetched from origin. Run `git fetch --unshallow` locally, or — ' +
166
+ 'if the commit was rewritten/force-pushed away — update the LAST-SYNC ' +
167
+ 'marker to a reachable commit per ' +
168
+ 'docs/design/components-css-port-procedure.md.');
169
+ }
170
+ const head = latestCanonicalCommit();
171
+ const drift = diffLineCount(lastSync, head);
172
+ console.log('────────────────────────────────────────────────────');
173
+ console.log(' components.css canonical-port drift report');
174
+ console.log('────────────────────────────────────────────────────');
175
+ console.log(` LAST-SYNC : ${lastSync}`);
176
+ console.log(` HEAD : ${head}`);
177
+ console.log(` drift : ${drift} lines (insertions + deletions)`);
178
+ console.log(` canonical : ${CANONICAL_CSS_REPO}`);
179
+ console.log('────────────────────────────────────────────────────');
180
+ if (drift === 0) {
181
+ console.log(' status : IN SYNC');
182
+ return EXIT_OK;
183
+ }
184
+ if (drift < WARN_THRESHOLD) {
185
+ console.log(` status : minor drift (<${WARN_THRESHOLD} lines)`);
186
+ return EXIT_OK;
187
+ }
188
+ if (drift <= FAIL_THRESHOLD) {
189
+ console.log(` status : WARN — ${drift} lines drift (>=${WARN_THRESHOLD})`);
190
+ console.log(' action : schedule a re-sync PR per');
191
+ console.log(' docs/design/components-css-port-procedure.md');
192
+ return EXIT_OK;
193
+ }
194
+ console.log(` status : FAIL — ${drift} lines drift (>${FAIL_THRESHOLD})`);
195
+ console.log(' action : re-sync REQUIRED before merge — see');
196
+ console.log(' docs/design/components-css-port-procedure.md');
197
+ return EXIT_FAIL;
198
+ }
199
+ process.exit(main());
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ /**
38
+ * Run a Mocha shard per `test/shard-config.json` (#231, design
39
+ * `docs/design/191-test-parallelization.md` §2).
40
+ *
41
+ * Usage:
42
+ * node dist/scripts/run-shard.js <1|2>
43
+ *
44
+ * shard-1 — run only the files listed in `shard-config.json` under
45
+ * `"shard-1"`. Runs Mocha with `--no-config` so positional args are the
46
+ * complete spec; the `require: root-hooks.js` + `timeout` + `exit`
47
+ * options from `.mocharc.yml` are forwarded as CLI flags to preserve the
48
+ * shared-env teardown hook and the existing 30s-per-test cap.
49
+ * Mocha 11's default spec from mocharc unions with CLI args rather than
50
+ * replacing, which is why we can't just pass positional args against the
51
+ * default config — that would silently run the full suite.
52
+ *
53
+ * shard-2 — run the default `.mocharc.yml` spec minus the shard-1 files,
54
+ * via Mocha's `--ignore` flag. Mocharc config stays in charge so
55
+ * `root-hooks.js` etc. land via its `require:` key, no CLI duplication.
56
+ *
57
+ * The JSON is the single source of truth. Moving a file between shards is a
58
+ * one-line edit; the rebalance rule lives in `test/README.md` (20% drift
59
+ * bound). Build/clean is handled by `pretest:shard-*` hooks in
60
+ * `package.json`, so this script only needs to fan args into Mocha.
61
+ *
62
+ * Exits with Mocha's own exit code (0 on success, non-zero on test failure
63
+ * or spawn error) so `npm run test:shard-*` and CI see identical semantics
64
+ * to a direct `mocha` invocation.
65
+ */
66
+ const path = __importStar(require("path"));
67
+ const fs = __importStar(require("fs"));
68
+ const child_process_1 = require("child_process");
69
+ const shard = process.argv[2];
70
+ if (shard !== '1' && shard !== '2') {
71
+ console.error('Usage: node dist/scripts/run-shard.js <1|2>');
72
+ process.exit(2);
73
+ }
74
+ const configPath = path.join(__dirname, '..', '..', 'test', 'shard-config.json');
75
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
76
+ const shard1Sources = Array.isArray(config['shard-1']) ? config['shard-1'] : [];
77
+ if (shard1Sources.length === 0) {
78
+ console.error('test/shard-config.json is missing or empty under "shard-1".');
79
+ process.exit(2);
80
+ }
81
+ // Map each source path to its compiled .js under dist-test. The helper stays
82
+ // here (rather than in the JSON) so the JSON reads as a plain file list — no
83
+ // build-path leakage into a config that engineers edit during rebalance.
84
+ function toCompiled(sourcePath) {
85
+ return sourcePath
86
+ .replace(/^test\//, 'dist-test/test/')
87
+ .replace(/\.ts$/, '.js');
88
+ }
89
+ const shard1Compiled = shard1Sources.map(toCompiled);
90
+ // For shard-1 we bypass `.mocharc.yml` entirely (`--no-config`) because
91
+ // Mocha 11 unions the mocharc `spec:` glob with CLI args rather than
92
+ // letting CLI args override, so a positional-args-only approach would also
93
+ // pull in every file in the default glob. Forwarding `require` + `timeout`
94
+ // + `exit` by hand keeps the shared TestWorkflowEnvironment teardown hook
95
+ // wired up and the per-test timeout identical to a full-suite run.
96
+ const shard1CliMirrorOfMocharc = [
97
+ '--no-config',
98
+ '--require',
99
+ 'dist-test/test/root-hooks.js',
100
+ '--timeout',
101
+ '30000',
102
+ '--exit',
103
+ ];
104
+ const mochaArgs = shard === '1'
105
+ ? [...shard1CliMirrorOfMocharc, ...shard1Compiled]
106
+ : shard1Compiled.flatMap((f) => ['--ignore', f]);
107
+ // Resolve the local `mocha` binary directly rather than relying on PATH / npx
108
+ // wrapping — avoids an extra process on CI and keeps Windows + POSIX behaviour
109
+ // identical. `npm_execpath`-style lookup isn't worth the complexity for one
110
+ // dev-only script.
111
+ const mochaBin = path.join(__dirname, '..', '..', 'node_modules', '.bin', process.platform === 'win32' ? 'mocha.cmd' : 'mocha');
112
+ console.log(`[run-shard] shard-${shard}: ${shard === '1' ? shard1Compiled.length + ' explicit files' : 'full spec minus ' + shard1Compiled.length + ' shard-1 files'}`);
113
+ const result = (0, child_process_1.spawnSync)(mochaBin, mochaArgs, {
114
+ stdio: 'inherit',
115
+ shell: process.platform === 'win32', // .cmd on Windows needs a shell
116
+ });
117
+ if (result.error) {
118
+ console.error('[run-shard] failed to spawn mocha:', result.error.message);
119
+ process.exit(1);
120
+ }
121
+ process.exit(result.status ?? 1);