@ag-eco/agentplate-cli 0.13.0

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 (455) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +462 -0
  3. package/agents/ap-co-creation.md +90 -0
  4. package/agents/builder.md +144 -0
  5. package/agents/coordinator.md +377 -0
  6. package/agents/lead.md +435 -0
  7. package/agents/merger.md +164 -0
  8. package/agents/monitor.md +214 -0
  9. package/agents/orchestrator.md +239 -0
  10. package/agents/reviewer.md +140 -0
  11. package/agents/scout.md +125 -0
  12. package/agents/supervisor.md +427 -0
  13. package/package.json +66 -0
  14. package/src/agents/capabilities.test.ts +85 -0
  15. package/src/agents/capabilities.ts +125 -0
  16. package/src/agents/checkpoint.test.ts +88 -0
  17. package/src/agents/checkpoint.ts +101 -0
  18. package/src/agents/copilot-hooks-deployer.test.ts +162 -0
  19. package/src/agents/copilot-hooks-deployer.ts +93 -0
  20. package/src/agents/guard-rules.test.ts +372 -0
  21. package/src/agents/guard-rules.ts +97 -0
  22. package/src/agents/headless-mail-injector.test.ts +709 -0
  23. package/src/agents/headless-mail-injector.ts +377 -0
  24. package/src/agents/headless-prompt.test.ts +102 -0
  25. package/src/agents/headless-prompt.ts +68 -0
  26. package/src/agents/hooks-deployer.test.ts +3119 -0
  27. package/src/agents/hooks-deployer.ts +804 -0
  28. package/src/agents/identity.test.ts +604 -0
  29. package/src/agents/identity.ts +384 -0
  30. package/src/agents/lifecycle.test.ts +196 -0
  31. package/src/agents/lifecycle.ts +183 -0
  32. package/src/agents/mail-poll-detect.test.ts +153 -0
  33. package/src/agents/mail-poll-detect.ts +73 -0
  34. package/src/agents/manifest.test.ts +1026 -0
  35. package/src/agents/manifest.ts +376 -0
  36. package/src/agents/overlay.test.ts +1058 -0
  37. package/src/agents/overlay.ts +490 -0
  38. package/src/agents/scope-detect.test.ts +190 -0
  39. package/src/agents/scope-detect.ts +146 -0
  40. package/src/agents/turn-lock.test.ts +181 -0
  41. package/src/agents/turn-lock.ts +235 -0
  42. package/src/agents/turn-runner-dispatch.test.ts +182 -0
  43. package/src/agents/turn-runner-dispatch.ts +105 -0
  44. package/src/agents/turn-runner.test.ts +2312 -0
  45. package/src/agents/turn-runner.ts +1383 -0
  46. package/src/beads/client.test.ts +217 -0
  47. package/src/beads/client.ts +230 -0
  48. package/src/beads/molecules.test.ts +338 -0
  49. package/src/beads/molecules.ts +198 -0
  50. package/src/commands/agents.test.ts +328 -0
  51. package/src/commands/agents.ts +299 -0
  52. package/src/commands/clean.test.ts +797 -0
  53. package/src/commands/clean.ts +791 -0
  54. package/src/commands/completions.test.ts +348 -0
  55. package/src/commands/completions.ts +981 -0
  56. package/src/commands/coordinator.test.ts +2975 -0
  57. package/src/commands/coordinator.ts +1841 -0
  58. package/src/commands/costs.test.ts +1183 -0
  59. package/src/commands/costs.ts +599 -0
  60. package/src/commands/dashboard.test.ts +954 -0
  61. package/src/commands/dashboard.ts +1212 -0
  62. package/src/commands/discover.test.ts +288 -0
  63. package/src/commands/discover.ts +202 -0
  64. package/src/commands/doctor.test.ts +303 -0
  65. package/src/commands/doctor.ts +311 -0
  66. package/src/commands/ecosystem.test.ts +226 -0
  67. package/src/commands/ecosystem.ts +248 -0
  68. package/src/commands/errors.test.ts +654 -0
  69. package/src/commands/errors.ts +197 -0
  70. package/src/commands/feed.test.ts +709 -0
  71. package/src/commands/feed.ts +260 -0
  72. package/src/commands/group.test.ts +475 -0
  73. package/src/commands/group.ts +546 -0
  74. package/src/commands/hooks.test.ts +458 -0
  75. package/src/commands/hooks.ts +263 -0
  76. package/src/commands/init.test.ts +1011 -0
  77. package/src/commands/init.ts +967 -0
  78. package/src/commands/inspect.test.ts +1239 -0
  79. package/src/commands/inspect.ts +648 -0
  80. package/src/commands/log.test.ts +1913 -0
  81. package/src/commands/log.ts +958 -0
  82. package/src/commands/logs.test.ts +801 -0
  83. package/src/commands/logs.ts +483 -0
  84. package/src/commands/mail.test.ts +1501 -0
  85. package/src/commands/mail.ts +848 -0
  86. package/src/commands/merge.test.ts +864 -0
  87. package/src/commands/merge.ts +381 -0
  88. package/src/commands/metrics.test.ts +458 -0
  89. package/src/commands/metrics.ts +129 -0
  90. package/src/commands/monitor.test.ts +191 -0
  91. package/src/commands/monitor.ts +409 -0
  92. package/src/commands/nudge.test.ts +579 -0
  93. package/src/commands/nudge.ts +646 -0
  94. package/src/commands/orchestrator.ts +42 -0
  95. package/src/commands/prime.test.ts +612 -0
  96. package/src/commands/prime.ts +359 -0
  97. package/src/commands/replay.test.ts +757 -0
  98. package/src/commands/replay.ts +231 -0
  99. package/src/commands/run.test.ts +469 -0
  100. package/src/commands/run.ts +353 -0
  101. package/src/commands/serve/agent-actions.test.ts +210 -0
  102. package/src/commands/serve/agent-actions.ts +192 -0
  103. package/src/commands/serve/build.test.ts +202 -0
  104. package/src/commands/serve/build.ts +206 -0
  105. package/src/commands/serve/coordinator-actions.test.ts +339 -0
  106. package/src/commands/serve/coordinator-actions.ts +410 -0
  107. package/src/commands/serve/dev.test.ts +168 -0
  108. package/src/commands/serve/dev.ts +117 -0
  109. package/src/commands/serve/mail-actions.test.ts +312 -0
  110. package/src/commands/serve/mail-actions.ts +167 -0
  111. package/src/commands/serve/rest.test.ts +1680 -0
  112. package/src/commands/serve/rest.ts +1130 -0
  113. package/src/commands/serve/static.ts +51 -0
  114. package/src/commands/serve/ws.test.ts +361 -0
  115. package/src/commands/serve/ws.ts +332 -0
  116. package/src/commands/serve.test.ts +459 -0
  117. package/src/commands/serve.ts +654 -0
  118. package/src/commands/sling.test.ts +1583 -0
  119. package/src/commands/sling.ts +1351 -0
  120. package/src/commands/spec.test.ts +179 -0
  121. package/src/commands/spec.ts +105 -0
  122. package/src/commands/status.test.ts +614 -0
  123. package/src/commands/status.ts +403 -0
  124. package/src/commands/stop.test.ts +964 -0
  125. package/src/commands/stop.ts +319 -0
  126. package/src/commands/supervisor.test.ts +185 -0
  127. package/src/commands/supervisor.ts +537 -0
  128. package/src/commands/trace.test.ts +762 -0
  129. package/src/commands/trace.ts +205 -0
  130. package/src/commands/update.test.ts +466 -0
  131. package/src/commands/update.ts +263 -0
  132. package/src/commands/upgrade.test.ts +48 -0
  133. package/src/commands/upgrade.ts +240 -0
  134. package/src/commands/watch.test.ts +257 -0
  135. package/src/commands/watch.ts +308 -0
  136. package/src/commands/worktree.test.ts +1297 -0
  137. package/src/commands/worktree.ts +451 -0
  138. package/src/config.test.ts +1535 -0
  139. package/src/config.ts +1064 -0
  140. package/src/doctor/agents.test.ts +523 -0
  141. package/src/doctor/agents.ts +399 -0
  142. package/src/doctor/config-check.test.ts +191 -0
  143. package/src/doctor/config-check.ts +183 -0
  144. package/src/doctor/consistency.test.ts +807 -0
  145. package/src/doctor/consistency.ts +347 -0
  146. package/src/doctor/databases.test.ts +350 -0
  147. package/src/doctor/databases.ts +243 -0
  148. package/src/doctor/dependencies.test.ts +296 -0
  149. package/src/doctor/dependencies.ts +272 -0
  150. package/src/doctor/ecosystem.test.ts +308 -0
  151. package/src/doctor/ecosystem.ts +156 -0
  152. package/src/doctor/logs.test.ts +253 -0
  153. package/src/doctor/logs.ts +295 -0
  154. package/src/doctor/merge-queue.test.ts +315 -0
  155. package/src/doctor/merge-queue.ts +167 -0
  156. package/src/doctor/providers.test.ts +409 -0
  157. package/src/doctor/providers.ts +250 -0
  158. package/src/doctor/serve.test.ts +95 -0
  159. package/src/doctor/serve.ts +86 -0
  160. package/src/doctor/structure.test.ts +423 -0
  161. package/src/doctor/structure.ts +285 -0
  162. package/src/doctor/types.ts +43 -0
  163. package/src/doctor/version.test.ts +241 -0
  164. package/src/doctor/version.ts +132 -0
  165. package/src/doctor/watchdog.test.ts +167 -0
  166. package/src/doctor/watchdog.ts +214 -0
  167. package/src/e2e/init-sling-lifecycle.test.ts +283 -0
  168. package/src/errors.test.ts +350 -0
  169. package/src/errors.ts +217 -0
  170. package/src/events/store.test.ts +660 -0
  171. package/src/events/store.ts +369 -0
  172. package/src/events/tailer.test.ts +719 -0
  173. package/src/events/tailer.ts +332 -0
  174. package/src/events/tool-filter.test.ts +330 -0
  175. package/src/events/tool-filter.ts +126 -0
  176. package/src/index.ts +533 -0
  177. package/src/insights/analyzer.test.ts +466 -0
  178. package/src/insights/analyzer.ts +203 -0
  179. package/src/insights/quality-gates.test.ts +141 -0
  180. package/src/insights/quality-gates.ts +156 -0
  181. package/src/json.test.ts +72 -0
  182. package/src/json.ts +53 -0
  183. package/src/loam/client.test.ts +752 -0
  184. package/src/loam/client.ts +664 -0
  185. package/src/logging/color.test.ts +252 -0
  186. package/src/logging/color.ts +105 -0
  187. package/src/logging/format.test.ts +110 -0
  188. package/src/logging/format.ts +255 -0
  189. package/src/logging/logger.test.ts +814 -0
  190. package/src/logging/logger.ts +266 -0
  191. package/src/logging/reporter.test.ts +259 -0
  192. package/src/logging/reporter.ts +110 -0
  193. package/src/logging/sanitizer.test.ts +190 -0
  194. package/src/logging/sanitizer.ts +57 -0
  195. package/src/logging/theme.ts +140 -0
  196. package/src/mail/broadcast.test.ts +204 -0
  197. package/src/mail/broadcast.ts +92 -0
  198. package/src/mail/client.test.ts +774 -0
  199. package/src/mail/client.ts +236 -0
  200. package/src/mail/store.test.ts +898 -0
  201. package/src/mail/store.ts +425 -0
  202. package/src/merge/lock.test.ts +149 -0
  203. package/src/merge/lock.ts +140 -0
  204. package/src/merge/predict.test.ts +387 -0
  205. package/src/merge/predict.ts +249 -0
  206. package/src/merge/queue.test.ts +426 -0
  207. package/src/merge/queue.ts +246 -0
  208. package/src/merge/resolver.test.ts +1993 -0
  209. package/src/merge/resolver.ts +926 -0
  210. package/src/metrics/pricing.test.ts +258 -0
  211. package/src/metrics/pricing.ts +135 -0
  212. package/src/metrics/store.test.ts +978 -0
  213. package/src/metrics/store.ts +501 -0
  214. package/src/metrics/summary.test.ts +398 -0
  215. package/src/metrics/summary.ts +178 -0
  216. package/src/metrics/transcript.test.ts +483 -0
  217. package/src/metrics/transcript.ts +114 -0
  218. package/src/runtimes/__fixtures__/claude-stream-fixture.ts +22 -0
  219. package/src/runtimes/aider.test.ts +124 -0
  220. package/src/runtimes/aider.ts +147 -0
  221. package/src/runtimes/amp.test.ts +164 -0
  222. package/src/runtimes/amp.ts +154 -0
  223. package/src/runtimes/claude.test.ts +1474 -0
  224. package/src/runtimes/claude.ts +579 -0
  225. package/src/runtimes/codex.test.ts +805 -0
  226. package/src/runtimes/codex.ts +273 -0
  227. package/src/runtimes/connections.test.ts +214 -0
  228. package/src/runtimes/connections.ts +103 -0
  229. package/src/runtimes/copilot.test.ts +707 -0
  230. package/src/runtimes/copilot.ts +316 -0
  231. package/src/runtimes/cursor.test.ts +497 -0
  232. package/src/runtimes/cursor.ts +205 -0
  233. package/src/runtimes/gemini.test.ts +537 -0
  234. package/src/runtimes/gemini.ts +243 -0
  235. package/src/runtimes/goose.test.ts +133 -0
  236. package/src/runtimes/goose.ts +157 -0
  237. package/src/runtimes/headless-connection.test.ts +264 -0
  238. package/src/runtimes/headless-connection.ts +158 -0
  239. package/src/runtimes/opencode.test.ts +325 -0
  240. package/src/runtimes/opencode.ts +188 -0
  241. package/src/runtimes/pi-guards.test.ts +486 -0
  242. package/src/runtimes/pi-guards.ts +367 -0
  243. package/src/runtimes/pi.test.ts +789 -0
  244. package/src/runtimes/pi.ts +305 -0
  245. package/src/runtimes/registry.test.ts +196 -0
  246. package/src/runtimes/registry.ts +99 -0
  247. package/src/runtimes/sapling.test.ts +1267 -0
  248. package/src/runtimes/sapling.ts +710 -0
  249. package/src/runtimes/types.ts +266 -0
  250. package/src/schema-consistency.test.ts +246 -0
  251. package/src/sessions/compat.test.ts +281 -0
  252. package/src/sessions/compat.ts +105 -0
  253. package/src/sessions/store.test.ts +1748 -0
  254. package/src/sessions/store.ts +858 -0
  255. package/src/test-helpers.test.ts +124 -0
  256. package/src/test-helpers.ts +145 -0
  257. package/src/test-setup.test.ts +31 -0
  258. package/src/test-setup.ts +28 -0
  259. package/src/tools/loam/api.ts +368 -0
  260. package/src/tools/loam/cli.ts +278 -0
  261. package/src/tools/loam/commands/add.ts +52 -0
  262. package/src/tools/loam/commands/archive.ts +214 -0
  263. package/src/tools/loam/commands/audit.ts +276 -0
  264. package/src/tools/loam/commands/compact.ts +1062 -0
  265. package/src/tools/loam/commands/completions.ts +79 -0
  266. package/src/tools/loam/commands/config.ts +381 -0
  267. package/src/tools/loam/commands/delete-domain.ts +121 -0
  268. package/src/tools/loam/commands/delete.ts +316 -0
  269. package/src/tools/loam/commands/diff.ts +200 -0
  270. package/src/tools/loam/commands/doctor.ts +1113 -0
  271. package/src/tools/loam/commands/edit.ts +226 -0
  272. package/src/tools/loam/commands/init.ts +31 -0
  273. package/src/tools/loam/commands/learn.ts +179 -0
  274. package/src/tools/loam/commands/move.ts +323 -0
  275. package/src/tools/loam/commands/onboard.ts +374 -0
  276. package/src/tools/loam/commands/outcome.ts +185 -0
  277. package/src/tools/loam/commands/prime.ts +688 -0
  278. package/src/tools/loam/commands/prune.ts +614 -0
  279. package/src/tools/loam/commands/query.ts +218 -0
  280. package/src/tools/loam/commands/rank.ts +180 -0
  281. package/src/tools/loam/commands/ready.ts +189 -0
  282. package/src/tools/loam/commands/record.ts +1210 -0
  283. package/src/tools/loam/commands/restore.ts +166 -0
  284. package/src/tools/loam/commands/search.ts +327 -0
  285. package/src/tools/loam/commands/setup.ts +887 -0
  286. package/src/tools/loam/commands/status.ts +103 -0
  287. package/src/tools/loam/commands/sync.ts +298 -0
  288. package/src/tools/loam/commands/update.ts +19 -0
  289. package/src/tools/loam/commands/upgrade.ts +93 -0
  290. package/src/tools/loam/commands/validate.ts +190 -0
  291. package/src/tools/loam/index.ts +62 -0
  292. package/src/tools/loam/log.ts +127 -0
  293. package/src/tools/loam/registry/builtins.ts +409 -0
  294. package/src/tools/loam/registry/custom.ts +431 -0
  295. package/src/tools/loam/registry/init.ts +55 -0
  296. package/src/tools/loam/registry/template.ts +40 -0
  297. package/src/tools/loam/registry/type-registry.ts +113 -0
  298. package/src/tools/loam/schemas/config-schema.ts +489 -0
  299. package/src/tools/loam/schemas/config.ts +245 -0
  300. package/src/tools/loam/schemas/index.ts +18 -0
  301. package/src/tools/loam/schemas/record-schema.ts +191 -0
  302. package/src/tools/loam/schemas/record.ts +115 -0
  303. package/src/tools/loam/utils/active-work.ts +205 -0
  304. package/src/tools/loam/utils/anchor-validity.ts +80 -0
  305. package/src/tools/loam/utils/archive.ts +146 -0
  306. package/src/tools/loam/utils/audit.ts +667 -0
  307. package/src/tools/loam/utils/bm25.ts +238 -0
  308. package/src/tools/loam/utils/budget.ts +142 -0
  309. package/src/tools/loam/utils/config.ts +344 -0
  310. package/src/tools/loam/utils/dir-anchors.ts +62 -0
  311. package/src/tools/loam/utils/domain-rules.ts +114 -0
  312. package/src/tools/loam/utils/expertise.ts +393 -0
  313. package/src/tools/loam/utils/format-helpers.ts +96 -0
  314. package/src/tools/loam/utils/format.ts +1234 -0
  315. package/src/tools/loam/utils/git-context.ts +50 -0
  316. package/src/tools/loam/utils/git.ts +183 -0
  317. package/src/tools/loam/utils/hooks.ts +299 -0
  318. package/src/tools/loam/utils/index.ts +52 -0
  319. package/src/tools/loam/utils/json-output.ts +13 -0
  320. package/src/tools/loam/utils/lock.ts +76 -0
  321. package/src/tools/loam/utils/markers.ts +48 -0
  322. package/src/tools/loam/utils/numeric-flags.ts +20 -0
  323. package/src/tools/loam/utils/palette.ts +44 -0
  324. package/src/tools/loam/utils/prime-ranking.ts +135 -0
  325. package/src/tools/loam/utils/recipe-discovery.ts +195 -0
  326. package/src/tools/loam/utils/runtime-flags.ts +28 -0
  327. package/src/tools/loam/utils/scoring.ts +94 -0
  328. package/src/tools/loam/utils/version.ts +116 -0
  329. package/src/tools/sprout/commands/block.ts +64 -0
  330. package/src/tools/sprout/commands/blocked.ts +86 -0
  331. package/src/tools/sprout/commands/close.ts +129 -0
  332. package/src/tools/sprout/commands/completions.ts +198 -0
  333. package/src/tools/sprout/commands/config.ts +238 -0
  334. package/src/tools/sprout/commands/create.ts +164 -0
  335. package/src/tools/sprout/commands/dep.ts +148 -0
  336. package/src/tools/sprout/commands/doctor.ts +979 -0
  337. package/src/tools/sprout/commands/init.ts +83 -0
  338. package/src/tools/sprout/commands/label.ts +178 -0
  339. package/src/tools/sprout/commands/list.ts +210 -0
  340. package/src/tools/sprout/commands/migrate.ts +133 -0
  341. package/src/tools/sprout/commands/onboard.ts +207 -0
  342. package/src/tools/sprout/commands/plan-show.ts +278 -0
  343. package/src/tools/sprout/commands/plan.ts +2526 -0
  344. package/src/tools/sprout/commands/prime.ts +399 -0
  345. package/src/tools/sprout/commands/ready.ts +245 -0
  346. package/src/tools/sprout/commands/search.ts +221 -0
  347. package/src/tools/sprout/commands/show.ts +277 -0
  348. package/src/tools/sprout/commands/stats.ts +146 -0
  349. package/src/tools/sprout/commands/sync.ts +134 -0
  350. package/src/tools/sprout/commands/tpl.ts +364 -0
  351. package/src/tools/sprout/commands/unblock.ts +115 -0
  352. package/src/tools/sprout/commands/update.ts +257 -0
  353. package/src/tools/sprout/commands/upgrade.ts +91 -0
  354. package/src/tools/sprout/config-schema.ts +152 -0
  355. package/src/tools/sprout/config.ts +355 -0
  356. package/src/tools/sprout/filter.ts +107 -0
  357. package/src/tools/sprout/format.ts +43 -0
  358. package/src/tools/sprout/id.ts +22 -0
  359. package/src/tools/sprout/index.ts +204 -0
  360. package/src/tools/sprout/log.ts +76 -0
  361. package/src/tools/sprout/markers.ts +22 -0
  362. package/src/tools/sprout/output.ts +121 -0
  363. package/src/tools/sprout/plan-backref.ts +93 -0
  364. package/src/tools/sprout/plan-context.ts +81 -0
  365. package/src/tools/sprout/plan-domain.ts +139 -0
  366. package/src/tools/sprout/plan-lifecycle.ts +65 -0
  367. package/src/tools/sprout/plan-loam.ts +207 -0
  368. package/src/tools/sprout/plan-schema.ts +209 -0
  369. package/src/tools/sprout/sort.ts +31 -0
  370. package/src/tools/sprout/store.ts +172 -0
  371. package/src/tools/sprout/types.ts +118 -0
  372. package/src/tools/sprout/validation.ts +119 -0
  373. package/src/tools/sprout/version.ts +1 -0
  374. package/src/tools/sprout/yaml.ts +387 -0
  375. package/src/tools/trellis/commands/archive.ts +87 -0
  376. package/src/tools/trellis/commands/completions.ts +610 -0
  377. package/src/tools/trellis/commands/config.ts +382 -0
  378. package/src/tools/trellis/commands/create.ts +252 -0
  379. package/src/tools/trellis/commands/diff.ts +150 -0
  380. package/src/tools/trellis/commands/doctor.ts +771 -0
  381. package/src/tools/trellis/commands/emit.ts +365 -0
  382. package/src/tools/trellis/commands/history.ts +83 -0
  383. package/src/tools/trellis/commands/import.ts +198 -0
  384. package/src/tools/trellis/commands/init.ts +81 -0
  385. package/src/tools/trellis/commands/list.ts +103 -0
  386. package/src/tools/trellis/commands/onboard.ts +156 -0
  387. package/src/tools/trellis/commands/pin.ts +172 -0
  388. package/src/tools/trellis/commands/prime.ts +193 -0
  389. package/src/tools/trellis/commands/render.ts +122 -0
  390. package/src/tools/trellis/commands/schema.ts +353 -0
  391. package/src/tools/trellis/commands/show.ts +115 -0
  392. package/src/tools/trellis/commands/stats.ts +65 -0
  393. package/src/tools/trellis/commands/sync.ts +112 -0
  394. package/src/tools/trellis/commands/tree.ts +123 -0
  395. package/src/tools/trellis/commands/update.ts +330 -0
  396. package/src/tools/trellis/commands/upgrade.ts +95 -0
  397. package/src/tools/trellis/commands/validate.ts +166 -0
  398. package/src/tools/trellis/config-schema.ts +81 -0
  399. package/src/tools/trellis/config.ts +108 -0
  400. package/src/tools/trellis/frontmatter.ts +348 -0
  401. package/src/tools/trellis/id.ts +24 -0
  402. package/src/tools/trellis/index.ts +209 -0
  403. package/src/tools/trellis/markers.ts +28 -0
  404. package/src/tools/trellis/output.ts +84 -0
  405. package/src/tools/trellis/render.ts +212 -0
  406. package/src/tools/trellis/store.ts +144 -0
  407. package/src/tools/trellis/types.ts +82 -0
  408. package/src/tools/trellis/validate.ts +199 -0
  409. package/src/tools/trellis/yaml.ts +309 -0
  410. package/src/tracker/beads.test.ts +454 -0
  411. package/src/tracker/beads.ts +56 -0
  412. package/src/tracker/factory.test.ts +90 -0
  413. package/src/tracker/factory.ts +65 -0
  414. package/src/tracker/sprout.test.ts +461 -0
  415. package/src/tracker/sprout.ts +182 -0
  416. package/src/tracker/types.ts +52 -0
  417. package/src/trellis/client.test.ts +107 -0
  418. package/src/trellis/client.ts +179 -0
  419. package/src/types.ts +970 -0
  420. package/src/utils/bin.test.ts +10 -0
  421. package/src/utils/bin.ts +37 -0
  422. package/src/utils/browser.test.ts +49 -0
  423. package/src/utils/browser.ts +48 -0
  424. package/src/utils/fs.test.ts +119 -0
  425. package/src/utils/fs.ts +62 -0
  426. package/src/utils/pid.test.ts +152 -0
  427. package/src/utils/pid.ts +130 -0
  428. package/src/utils/process-scan.test.ts +53 -0
  429. package/src/utils/process-scan.ts +76 -0
  430. package/src/utils/time.test.ts +43 -0
  431. package/src/utils/time.ts +37 -0
  432. package/src/utils/version.test.ts +33 -0
  433. package/src/utils/version.ts +70 -0
  434. package/src/version.ts +5 -0
  435. package/src/watchdog/daemon.test.ts +3721 -0
  436. package/src/watchdog/daemon.ts +1257 -0
  437. package/src/watchdog/health.test.ts +830 -0
  438. package/src/watchdog/health.ts +434 -0
  439. package/src/watchdog/triage.test.ts +205 -0
  440. package/src/watchdog/triage.ts +205 -0
  441. package/src/worktree/manager.test.ts +720 -0
  442. package/src/worktree/manager.ts +405 -0
  443. package/src/worktree/process.test.ts +172 -0
  444. package/src/worktree/process.ts +131 -0
  445. package/src/worktree/tmux.test.ts +1616 -0
  446. package/src/worktree/tmux.ts +721 -0
  447. package/templates/CLAUDE.md.tmpl +100 -0
  448. package/templates/copilot-hooks.json.tmpl +13 -0
  449. package/templates/hooks.json.tmpl +109 -0
  450. package/templates/overlay.md.tmpl +88 -0
  451. package/ui/dist/apple-touch-icon-bdy6teep.png +0 -0
  452. package/ui/dist/chunk-8s31f05k.css +1 -0
  453. package/ui/dist/chunk-vm5rz679.js +300 -0
  454. package/ui/dist/favicon-nzb39vza.svg +4 -0
  455. package/ui/dist/index.html +17 -0
@@ -0,0 +1,266 @@
1
+ // Runtime abstraction types for multi-provider agent support.
2
+ // See docs/runtime-abstraction.md for design rationale and coupling inventory.
3
+
4
+ import type { QualityGate, ResolvedModel } from "../types.ts";
5
+
6
+ // === Spawn ===
7
+
8
+ /** Options for spawning an interactive agent process. */
9
+ export interface SpawnOpts {
10
+ /** Model ref (alias or provider-qualified, e.g. "sonnet" or "openrouter/gpt-5"). */
11
+ model: string;
12
+ /** Permission mode: bypass for trusted builders, ask for interactive agents. */
13
+ permissionMode: "bypass" | "ask";
14
+ /** Optional system prompt prefix injected before the agent's base instructions. */
15
+ systemPrompt?: string;
16
+ /** Optional system prompt suffix appended after the base instructions. */
17
+ appendSystemPrompt?: string;
18
+ /** Path to a file whose contents are appended as system prompt (avoids tmux command length limits). */
19
+ appendSystemPromptFile?: string;
20
+ /** Working directory for the spawned process. */
21
+ cwd: string;
22
+ /** Additional directories that the runtime may need to write outside cwd. */
23
+ sharedWritableDirs?: string[];
24
+ /** Additional environment variables to pass to the spawned process. */
25
+ env: Record<string, string>;
26
+ }
27
+
28
+ // === Readiness ===
29
+
30
+ /**
31
+ * Discrete phases of agent TUI readiness, detected from tmux pane content.
32
+ * Headless runtimes (codex exec, pi --mode rpc) always return { phase: "ready" }.
33
+ */
34
+ export type ReadyState =
35
+ | { phase: "loading" }
36
+ | { phase: "dialog"; action: string }
37
+ | { phase: "ready" };
38
+
39
+ // === Config Deployment ===
40
+
41
+ /** Runtime-agnostic overlay content to write into a worktree. */
42
+ export interface OverlayContent {
43
+ /** Full markdown text to write as the agent's instruction file. */
44
+ content: string;
45
+ }
46
+
47
+ /**
48
+ * Runtime-agnostic hook/guard configuration for deployment to a worktree.
49
+ * Each runtime adapter translates this into its native guard mechanism
50
+ * (e.g., settings.local.json hooks for Claude Code, guard extensions for Pi).
51
+ */
52
+ export interface HooksDef {
53
+ /** Agent name injected into hook commands. */
54
+ agentName: string;
55
+ /** Agent capability (builder, scout, reviewer, lead, etc.). */
56
+ capability: string;
57
+ /** Absolute path to the agent's worktree for path-boundary enforcement. */
58
+ worktreePath: string;
59
+ /** Quality gates agents must pass before reporting completion. */
60
+ qualityGates?: QualityGate[];
61
+ /** When true, skip hooks file deployment. Headless agents don't use settings.local.json. */
62
+ isHeadless?: boolean;
63
+ }
64
+
65
+ // === Transcripts ===
66
+
67
+ /** Normalized token usage extracted from any runtime's session transcript. */
68
+ export interface TranscriptSummary {
69
+ inputTokens: number;
70
+ outputTokens: number;
71
+ /** Model identifier as reported by the runtime (e.g. "claude-sonnet-4-6"). */
72
+ model: string;
73
+ }
74
+
75
+ // === RPC Connection ===
76
+
77
+ /**
78
+ * Reported state of a connected agent process.
79
+ * Used by RuntimeConnection.getState() to poll agent activity without tmux.
80
+ */
81
+ export type ConnectionState = {
82
+ status: "idle" | "working" | "error";
83
+ /** Tool currently executing, if status is "working". */
84
+ currentTool?: string;
85
+ };
86
+
87
+ /**
88
+ * Handle to spawned agent process I/O streams for RPC communication.
89
+ * Compatible with Bun.spawn output when configured with stdin/stdout pipe.
90
+ */
91
+ export interface RpcProcessHandle {
92
+ readonly stdin: {
93
+ write(data: string | Uint8Array): number | Promise<number>;
94
+ };
95
+ readonly stdout: ReadableStream<Uint8Array>;
96
+ }
97
+
98
+ /**
99
+ * Lifecycle interface for runtimes supporting direct RPC.
100
+ * When AgentRuntime.connect() exists, the orchestrator bypasses tmux for
101
+ * mail delivery (followUp), shutdown (abort), and health checks (getState).
102
+ * Pi implements via JSON-RPC 2.0 over stdin/stdout.
103
+ */
104
+ export interface RuntimeConnection {
105
+ /** Send initial prompt after spawn. */
106
+ sendPrompt(text: string): Promise<void>;
107
+ /** Send follow-up message — replaces tmux send-keys. */
108
+ followUp(text: string): Promise<void>;
109
+ /** Clean shutdown — replaces SIGTERM. */
110
+ abort(): Promise<void>;
111
+ /** Query current state — replaces tmux capture-pane. */
112
+ getState(): Promise<ConnectionState>;
113
+ /** Release connection resources. */
114
+ close(): void;
115
+ }
116
+
117
+ // === Headless Spawn ===
118
+
119
+ /** Options for spawning a headless (non-tmux) agent subprocess directly. */
120
+ export interface DirectSpawnOpts {
121
+ /** Working directory for the spawned process. */
122
+ cwd: string;
123
+ /** Environment variables for the subprocess. */
124
+ env: Record<string, string>;
125
+ /** Model ref (alias or provider-qualified). When undefined, the runtime omits --model and lets the agent use its own config. */
126
+ model?: string;
127
+ /** Path to the instruction/overlay file for this agent. */
128
+ instructionPath: string;
129
+ /**
130
+ * Runtime-provided session id to resume on follow-up spawns.
131
+ *
132
+ * Present only on follow-up spawns — when a non-empty string, the runtime
133
+ * adapter emits the runtime-specific resume flag in its argv (claude:
134
+ * `--resume <id>`). Absent, undefined, null, or empty string → no resume.
135
+ */
136
+ resumeSessionId?: string | null;
137
+ }
138
+
139
+ /** Structured event emitted by a headless agent on stdout (NDJSON). */
140
+ export interface AgentEvent {
141
+ /** Event type (e.g. 'tool_start', 'tool_end', 'result', 'error', 'ready'). */
142
+ type: string;
143
+ /** ISO 8601 timestamp. */
144
+ timestamp: string;
145
+ /** Event-specific payload. */
146
+ [key: string]: unknown;
147
+ }
148
+
149
+ // === Runtime Interface ===
150
+
151
+ /**
152
+ * Contract that all agent runtime adapters must implement.
153
+ *
154
+ * Each runtime (Claude Code, Codex, Pi, OpenCode, ...) provides a ~200-400 line
155
+ * adapter file implementing this interface. The orchestration engine calls only
156
+ * these methods — never the runtime's CLI directly.
157
+ */
158
+ export interface AgentRuntime {
159
+ /** Unique runtime identifier (e.g. "claude", "codex", "pi"). */
160
+ id: string;
161
+
162
+ /** Stability level of this runtime adapter. */
163
+ readonly stability: "stable" | "beta" | "experimental";
164
+
165
+ /** Relative path to the instruction file within a worktree (e.g. "AGENTS.md"). */
166
+ readonly instructionPath: string;
167
+
168
+ /** Build the shell command string to spawn an interactive agent in a tmux pane. */
169
+ buildSpawnCommand(opts: SpawnOpts): string;
170
+
171
+ /**
172
+ * Build the argv array for a headless one-shot AI call.
173
+ * Used by merge/resolver.ts and watchdog/triage.ts for AI-assisted operations.
174
+ */
175
+ buildPrintCommand(prompt: string, model?: string): string[];
176
+
177
+ /**
178
+ * Deploy per-agent instructions and guards to a worktree.
179
+ * Claude Code writes .claude/CLAUDE.md + settings.local.json hooks.
180
+ * Codex writes AGENTS.md (no hook deployment needed).
181
+ * Pi writes AGENTS.md + a guard extension in .pi/extensions/.
182
+ * When overlay is undefined, only hooks are deployed (no instruction file written).
183
+ */
184
+ deployConfig(
185
+ worktreePath: string,
186
+ overlay: OverlayContent | undefined,
187
+ hooks: HooksDef,
188
+ ): Promise<void>;
189
+
190
+ /**
191
+ * Detect agent readiness from tmux pane content.
192
+ * Headless runtimes that exit when done should return { phase: "ready" } unconditionally.
193
+ */
194
+ detectReady(paneContent: string): ReadyState;
195
+
196
+ /**
197
+ * Parse a session transcript file into normalized token usage.
198
+ * Returns null if the transcript does not exist or cannot be parsed.
199
+ */
200
+ parseTranscript(path: string): Promise<TranscriptSummary | null>;
201
+
202
+ /**
203
+ * Return the directory containing session transcript files for this runtime,
204
+ * or null if transcript discovery is not supported.
205
+ *
206
+ * @param projectRoot - Absolute path to the project root
207
+ * @returns Absolute path to the transcript directory, or null
208
+ */
209
+ getTranscriptDir(projectRoot: string): string | null;
210
+
211
+ /**
212
+ * Build runtime-specific environment variables for model/provider routing.
213
+ * Claude Code uses ANTHROPIC_API_KEY; Codex uses OPENAI_API_KEY; Pi passes
214
+ * the provider's authTokenEnv directly.
215
+ */
216
+ buildEnv(model: ResolvedModel): Record<string, string>;
217
+
218
+ /**
219
+ * Whether this runtime requires the beacon verification/resend loop after initial send.
220
+ *
221
+ * Claude Code's TUI sometimes swallows Enter during late initialization, so the
222
+ * orchestrator resends the beacon if the pane still appears idle (agentplate-3271).
223
+ * Pi's TUI does not exhibit this behavior AND its idle/processing states are
224
+ * indistinguishable via detectReady (both show the header and status bar), so
225
+ * the resend loop would spam Pi with duplicate startup messages.
226
+ *
227
+ * Runtimes that omit this method (or return true) get the resend loop.
228
+ * Pi returns false to skip it.
229
+ */
230
+ requiresBeaconVerification?(): boolean;
231
+
232
+ /**
233
+ * Establish direct RPC connection to running agent process.
234
+ * Runtimes without RPC (Claude, Codex) omit this method.
235
+ * Orchestrator checks `if (runtime.connect)` before calling, falls back to tmux when absent.
236
+ */
237
+ connect?(process: RpcProcessHandle): RuntimeConnection;
238
+
239
+ /**
240
+ * Whether this runtime is headless (no tmux, direct subprocess).
241
+ * Headless runtimes bypass all tmux session management and use Bun.spawn directly.
242
+ * Default: false (absent means interactive/tmux-based).
243
+ */
244
+ readonly headless?: boolean;
245
+
246
+ /**
247
+ * Build the argv array for Bun.spawn() to launch a headless agent subprocess.
248
+ * Only headless runtimes implement this method.
249
+ * The returned array is passed directly to Bun.spawn() — no shell interpolation.
250
+ */
251
+ buildDirectSpawn?(opts: DirectSpawnOpts): string[];
252
+
253
+ /**
254
+ * Parse NDJSON stdout from a headless agent subprocess into typed AgentEvent objects.
255
+ * Only headless runtimes implement this method.
256
+ * The caller provides the raw stdout ReadableStream from Bun.spawn().
257
+ */
258
+ parseEvents?(stream: ReadableStream<Uint8Array>): AsyncIterable<AgentEvent>;
259
+
260
+ /**
261
+ * Prepare a worktree path before spawning an agent.
262
+ * Called by sling.ts after worktree creation but before agent spawn.
263
+ * Used by runtimes that need environment setup (e.g., Copilot folder trust).
264
+ */
265
+ prepareWorktree?(worktreePath: string): Promise<void>;
266
+ }
@@ -0,0 +1,246 @@
1
+ /**
2
+ * SQL schema consistency tests.
3
+ *
4
+ * Verifies that SQL CREATE TABLE column names match the TypeScript row interfaces
5
+ * and row-to-object conversion functions across all four SQLite stores.
6
+ * Prevents regressions like the bead_id/task_id column rename that caused runtime failures.
7
+ *
8
+ * Strategy: create each store (which runs CREATE TABLE), then open a second
9
+ * read-only connection to the same temp file and query PRAGMA table_info().
10
+ * bun:sqlite with WAL mode allows concurrent readers.
11
+ */
12
+
13
+ import { Database } from "bun:sqlite";
14
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
15
+ import { mkdtemp } from "node:fs/promises";
16
+ import { tmpdir } from "node:os";
17
+ import { join } from "node:path";
18
+ import { createEventStore } from "./events/store.ts";
19
+ import { createMailStore } from "./mail/store.ts";
20
+ import { createMergeQueue } from "./merge/queue.ts";
21
+ import { createMetricsStore } from "./metrics/store.ts";
22
+ import { createSessionStore } from "./sessions/store.ts";
23
+
24
+ import { cleanupTempDir } from "./test-helpers.ts";
25
+
26
+ /** Extract sorted column names from a table via PRAGMA table_info(). */
27
+ function getTableColumns(db: Database, tableName: string): string[] {
28
+ const rows = db.prepare(`PRAGMA table_info(${tableName})`).all() as Array<{ name: string }>;
29
+ return rows.map((r) => r.name).sort();
30
+ }
31
+
32
+ describe("SQL schema consistency", () => {
33
+ let tmpDir: string;
34
+
35
+ beforeEach(async () => {
36
+ tmpDir = await mkdtemp(join(tmpdir(), "agentplate-schema-test-"));
37
+ });
38
+
39
+ afterEach(async () => {
40
+ await cleanupTempDir(tmpDir);
41
+ });
42
+
43
+ describe("SessionStore", () => {
44
+ test("sessions table columns match SessionRow interface", () => {
45
+ const dbPath = join(tmpDir, "sessions.db");
46
+ const store = createSessionStore(dbPath);
47
+
48
+ const db = new Database(dbPath, { readonly: true });
49
+ const actual = getTableColumns(db, "sessions");
50
+ db.close();
51
+ store.close();
52
+
53
+ // Columns from SessionRow interface in src/sessions/store.ts
54
+ const expected = [
55
+ "agent_name",
56
+ "branch_name",
57
+ "capability",
58
+ "claude_session_id",
59
+ "depth",
60
+ "escalation_level",
61
+ "id",
62
+ "last_activity",
63
+ "parent_agent",
64
+ "pid",
65
+ "run_id",
66
+ "prompt_version",
67
+ "stalled_since",
68
+ "started_at",
69
+ "state",
70
+ "task_id",
71
+ "tmux_session",
72
+ "transcript_path",
73
+ "worktree_path",
74
+ ].sort();
75
+
76
+ expect(actual).toEqual(expected);
77
+ });
78
+
79
+ test("runs table columns match RunRow interface", () => {
80
+ const dbPath = join(tmpDir, "sessions.db");
81
+ const store = createSessionStore(dbPath);
82
+
83
+ const db = new Database(dbPath, { readonly: true });
84
+ const actual = getTableColumns(db, "runs");
85
+ db.close();
86
+ store.close();
87
+
88
+ // Columns from RunRow interface in src/sessions/store.ts
89
+ const expected = [
90
+ "agent_count",
91
+ "completed_at",
92
+ "coordinator_name",
93
+ "coordinator_session_id",
94
+ "id",
95
+ "started_at",
96
+ "status",
97
+ ].sort();
98
+
99
+ expect(actual).toEqual(expected);
100
+ });
101
+ });
102
+
103
+ describe("EventStore", () => {
104
+ test("events table columns match EventRow interface", () => {
105
+ const dbPath = join(tmpDir, "events.db");
106
+ const store = createEventStore(dbPath);
107
+
108
+ const db = new Database(dbPath, { readonly: true });
109
+ const actual = getTableColumns(db, "events");
110
+ db.close();
111
+ store.close();
112
+
113
+ // Columns from EventRow interface in src/events/store.ts
114
+ const expected = [
115
+ "agent_name",
116
+ "created_at",
117
+ "data",
118
+ "event_type",
119
+ "id",
120
+ "level",
121
+ "run_id",
122
+ "session_id",
123
+ "tool_args",
124
+ "tool_duration_ms",
125
+ "tool_name",
126
+ ].sort();
127
+
128
+ expect(actual).toEqual(expected);
129
+ });
130
+ });
131
+
132
+ describe("MetricsStore", () => {
133
+ test("sessions table columns match metrics SessionRow interface", () => {
134
+ const dbPath = join(tmpDir, "metrics.db");
135
+ const store = createMetricsStore(dbPath);
136
+
137
+ const db = new Database(dbPath, { readonly: true });
138
+ const actual = getTableColumns(db, "sessions");
139
+ db.close();
140
+ store.close();
141
+
142
+ // Columns from SessionRow interface in src/metrics/store.ts
143
+ const expected = [
144
+ "agent_name",
145
+ "cache_creation_tokens",
146
+ "cache_read_tokens",
147
+ "capability",
148
+ "completed_at",
149
+ "duration_ms",
150
+ "estimated_cost_usd",
151
+ "exit_code",
152
+ "input_tokens",
153
+ "merge_result",
154
+ "model_used",
155
+ "output_tokens",
156
+ "parent_agent",
157
+ "run_id",
158
+ "started_at",
159
+ "task_id",
160
+ ].sort();
161
+
162
+ expect(actual).toEqual(expected);
163
+ });
164
+
165
+ test("token_snapshots table columns match SnapshotRow interface", () => {
166
+ const dbPath = join(tmpDir, "metrics.db");
167
+ const store = createMetricsStore(dbPath);
168
+
169
+ const db = new Database(dbPath, { readonly: true });
170
+ const actual = getTableColumns(db, "token_snapshots");
171
+ db.close();
172
+ store.close();
173
+
174
+ // Columns from SnapshotRow interface in src/metrics/store.ts
175
+ const expected = [
176
+ "agent_name",
177
+ "cache_creation_tokens",
178
+ "cache_read_tokens",
179
+ "created_at",
180
+ "estimated_cost_usd",
181
+ "id",
182
+ "input_tokens",
183
+ "model_used",
184
+ "output_tokens",
185
+ "run_id",
186
+ ].sort();
187
+
188
+ expect(actual).toEqual(expected);
189
+ });
190
+ });
191
+
192
+ describe("MailStore", () => {
193
+ test("messages table columns match MessageRow interface", () => {
194
+ const dbPath = join(tmpDir, "mail.db");
195
+ const store = createMailStore(dbPath);
196
+
197
+ const db = new Database(dbPath, { readonly: true });
198
+ const actual = getTableColumns(db, "messages");
199
+ db.close();
200
+ store.close();
201
+
202
+ // Columns from MessageRow interface in src/mail/store.ts
203
+ const expected = [
204
+ "body",
205
+ "created_at",
206
+ "from_agent",
207
+ "id",
208
+ "payload",
209
+ "priority",
210
+ "read",
211
+ "subject",
212
+ "thread_id",
213
+ "to_agent",
214
+ "type",
215
+ ].sort();
216
+
217
+ expect(actual).toEqual(expected);
218
+ });
219
+ });
220
+
221
+ describe("MergeQueue", () => {
222
+ test("merge_queue table columns match MergeQueueRow interface", () => {
223
+ const dbPath = join(tmpDir, "merge-queue.db");
224
+ const queue = createMergeQueue(dbPath);
225
+
226
+ const db = new Database(dbPath, { readonly: true });
227
+ const actual = getTableColumns(db, "merge_queue");
228
+ db.close();
229
+ queue.close();
230
+
231
+ // Columns from MergeQueueRow interface in src/merge/queue.ts
232
+ const expected = [
233
+ "agent_name",
234
+ "branch_name",
235
+ "enqueued_at",
236
+ "files_modified",
237
+ "id",
238
+ "resolved_tier",
239
+ "status",
240
+ "task_id",
241
+ ].sort();
242
+
243
+ expect(actual).toEqual(expected);
244
+ });
245
+ });
246
+ });