@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,381 @@
1
+ /**
2
+ * CLI command: ap merge
3
+ *
4
+ * Merges agent branches back to the canonical branch using
5
+ * the merge queue and tiered conflict resolver.
6
+ *
7
+ * Usage:
8
+ * ap merge --branch <name> Merge a specific branch
9
+ * ap merge --all Merge all pending branches
10
+ * ap merge --dry-run Check for conflicts without merging
11
+ * ap merge --json Output results as JSON
12
+ */
13
+
14
+ import { join } from "node:path";
15
+ import { loadConfig } from "../config.ts";
16
+ import { MergeError, ValidationError } from "../errors.ts";
17
+ import { jsonOutput } from "../json.ts";
18
+ import { createLoamClient } from "../loam/client.ts";
19
+ import { accent, printHint } from "../logging/color.ts";
20
+ import { acquireMergeLock } from "../merge/lock.ts";
21
+ import { predictConflicts } from "../merge/predict.ts";
22
+ import { createMergeQueue } from "../merge/queue.ts";
23
+ import { createMergeResolver } from "../merge/resolver.ts";
24
+ import type { ConflictPrediction, MergeEntry, MergeResult } from "../types.ts";
25
+
26
+ export interface MergeOptions {
27
+ branch?: string;
28
+ all?: boolean;
29
+ into?: string;
30
+ dryRun?: boolean;
31
+ json?: boolean;
32
+ }
33
+
34
+ /**
35
+ * Extract agent name from a branch following the agentplate naming convention.
36
+ * Pattern: agentplate/{agentName}/{taskId}
37
+ * Falls back to "unknown" if the pattern does not match.
38
+ */
39
+ function parseAgentName(branchName: string): string {
40
+ const parts = branchName.split("/");
41
+ if (parts[0] === "agentplate" && parts[1] !== undefined) {
42
+ return parts[1];
43
+ }
44
+ return "unknown";
45
+ }
46
+
47
+ /**
48
+ * Extract task ID from a branch following the agentplate naming convention.
49
+ * Pattern: agentplate/{agentName}/{taskId}
50
+ * Falls back to "unknown" if the pattern does not match.
51
+ */
52
+ function parseTaskId(branchName: string): string {
53
+ const parts = branchName.split("/");
54
+ if (parts[0] === "agentplate" && parts[2] !== undefined) {
55
+ return parts[2];
56
+ }
57
+ return "unknown";
58
+ }
59
+
60
+ /**
61
+ * Detect modified files between a branch and the canonical branch using git diff.
62
+ * Returns an array of file paths that differ.
63
+ */
64
+ async function detectModifiedFiles(
65
+ repoRoot: string,
66
+ canonicalBranch: string,
67
+ branchName: string,
68
+ ): Promise<string[]> {
69
+ const proc = Bun.spawn(["git", "diff", "--name-only", `${canonicalBranch}...${branchName}`], {
70
+ cwd: repoRoot,
71
+ stdout: "pipe",
72
+ stderr: "pipe",
73
+ });
74
+ const exitCode = await proc.exited;
75
+
76
+ if (exitCode !== 0) {
77
+ const stderr = await new Response(proc.stderr).text();
78
+ throw new MergeError(
79
+ `Failed to detect modified files for branch "${branchName}": ${stderr.trim()}`,
80
+ { branchName },
81
+ );
82
+ }
83
+
84
+ const stdout = await new Response(proc.stdout).text();
85
+ return stdout
86
+ .trim()
87
+ .split("\n")
88
+ .filter((line) => line.length > 0);
89
+ }
90
+
91
+ /** Format a single merge result for human-readable output. */
92
+ function formatResult(result: MergeResult): string {
93
+ const statusIcon = result.success ? "Merged" : "Failed";
94
+ const lines: string[] = [
95
+ `Merging branch: ${accent(result.entry.branchName)}`,
96
+ ` Agent: ${accent(result.entry.agentName)} | Task: ${accent(result.entry.taskId)}`,
97
+ ` Files: ${result.entry.filesModified.length} modified`,
98
+ ` Result: ${statusIcon} (tier: ${result.tier})`,
99
+ ];
100
+
101
+ if (result.conflictFiles.length > 0) {
102
+ lines.push(` Conflicts: ${result.conflictFiles.join(", ")}`);
103
+ }
104
+
105
+ if (result.errorMessage) {
106
+ lines.push(` Error: ${result.errorMessage}`);
107
+ }
108
+
109
+ return lines.join("\n");
110
+ }
111
+
112
+ /** Format a dry-run report for a merge entry. */
113
+ function formatDryRun(entry: MergeEntry, prediction?: ConflictPrediction): string {
114
+ const lines: string[] = [
115
+ `[dry-run] Branch: ${accent(entry.branchName)}`,
116
+ ` Agent: ${accent(entry.agentName)} | Task: ${accent(entry.taskId)}`,
117
+ ` Status: ${entry.status}`,
118
+ ` Files: ${entry.filesModified.length} modified`,
119
+ ];
120
+
121
+ if (entry.filesModified.length > 0) {
122
+ for (const f of entry.filesModified) {
123
+ lines.push(` - ${f}`);
124
+ }
125
+ }
126
+
127
+ if (prediction) {
128
+ const agentSuffix = prediction.wouldRequireAgent ? " (would require merger agent)" : "";
129
+ lines.push(` Prediction: ${prediction.predictedTier}${agentSuffix} — ${prediction.reason}`);
130
+ if (prediction.conflictFiles.length > 0) {
131
+ lines.push(` Conflict files: ${prediction.conflictFiles.join(", ")}`);
132
+ }
133
+ }
134
+
135
+ return lines.join("\n");
136
+ }
137
+
138
+ /**
139
+ * Predict the merge tier for a single entry, swallowing errors into a
140
+ * deterministic `ai-resolve` envelope so that `--all --dry-run` can keep
141
+ * going if one branch's prediction blows up.
142
+ */
143
+ async function safePredictForEntry(
144
+ entry: MergeEntry,
145
+ canonicalBranch: string,
146
+ repoRoot: string,
147
+ loamClient: ReturnType<typeof createLoamClient>,
148
+ ): Promise<ConflictPrediction> {
149
+ try {
150
+ return await predictConflicts(entry, canonicalBranch, repoRoot, loamClient);
151
+ } catch (err) {
152
+ const msg = err instanceof Error ? err.message : String(err);
153
+ return {
154
+ predictedTier: "ai-resolve",
155
+ conflictFiles: [],
156
+ wouldRequireAgent: true,
157
+ reason: `prediction-failed: ${msg}`,
158
+ };
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Entry point for `ap merge [flags]`.
164
+ *
165
+ * @param opts - Command options
166
+ */
167
+ export async function mergeCommand(opts: MergeOptions): Promise<void> {
168
+ const branchName = opts.branch;
169
+ const all = opts.all ?? false;
170
+ const into = opts.into;
171
+ const dryRun = opts.dryRun ?? false;
172
+ const json = opts.json ?? false;
173
+
174
+ if (!branchName && !all) {
175
+ throw new ValidationError("Either --branch <name> or --all is required for ap merge", {
176
+ field: "branch|all",
177
+ });
178
+ }
179
+
180
+ const cwd = process.cwd();
181
+ const config = await loadConfig(cwd);
182
+
183
+ // Resolution chain: --into flag > session-start branch > config canonicalBranch
184
+ let sessionBranch: string | null = null;
185
+ if (into === undefined) {
186
+ const sessionBranchPath = join(config.project.root, ".agentplate", "session-branch.txt");
187
+ const sessionBranchFile = Bun.file(sessionBranchPath);
188
+ if (await sessionBranchFile.exists()) {
189
+ const content = (await sessionBranchFile.text()).trim();
190
+ if (content) {
191
+ sessionBranch = content;
192
+ }
193
+ }
194
+ }
195
+ const targetBranch = into ?? sessionBranch ?? config.project.canonicalBranch;
196
+ const queuePath = join(config.project.root, ".agentplate", "merge-queue.db");
197
+ const queue = createMergeQueue(queuePath);
198
+ const loamClient = createLoamClient(config.project.root);
199
+ const resolver = createMergeResolver({
200
+ aiResolveEnabled: config.merge.aiResolveEnabled,
201
+ reimagineEnabled: config.merge.reimagineEnabled,
202
+ loamClient,
203
+ });
204
+
205
+ // Dry-run is read-only with respect to git state — no lock needed. The
206
+ // real merge path acquires a lock on the target branch so a parallel
207
+ // `ap merge` can't observe in-progress conflict markers and report a
208
+ // false failure (sprout: agentplate-9610).
209
+ const lock = dryRun
210
+ ? null
211
+ : acquireMergeLock(join(config.project.root, ".agentplate"), targetBranch);
212
+
213
+ try {
214
+ if (branchName) {
215
+ await handleBranch(branchName, queue, resolver, config, targetBranch, dryRun, json);
216
+ } else {
217
+ await handleAll(queue, resolver, config, targetBranch, dryRun, json);
218
+ }
219
+ } finally {
220
+ lock?.release();
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Handle merging a specific branch.
226
+ * If the branch is not in the queue, creates a new entry by detecting
227
+ * agent name, task ID, and modified files from git.
228
+ */
229
+ async function handleBranch(
230
+ branchName: string,
231
+ queue: ReturnType<typeof createMergeQueue>,
232
+ resolver: ReturnType<typeof createMergeResolver>,
233
+ config: Awaited<ReturnType<typeof loadConfig>>,
234
+ targetBranch: string,
235
+ dryRun: boolean,
236
+ json: boolean,
237
+ ): Promise<void> {
238
+ const canonicalBranch = targetBranch;
239
+ const repoRoot = config.project.root;
240
+
241
+ // Look for existing entry in the queue
242
+ const allEntries = queue.list();
243
+ let entry = allEntries.find((e) => e.branchName === branchName) ?? null;
244
+
245
+ // If not in queue, create one by detecting info from the branch
246
+ if (entry === null) {
247
+ // Validate that the branch exists before attempting any git operations
248
+ const verifyProc = Bun.spawn(["git", "rev-parse", "--verify", `refs/heads/${branchName}`], {
249
+ cwd: repoRoot,
250
+ stdout: "pipe",
251
+ stderr: "pipe",
252
+ });
253
+ const verifyExit = await verifyProc.exited;
254
+ if (verifyExit !== 0) {
255
+ throw new ValidationError(`Branch "${branchName}" not found`, {
256
+ field: "branch",
257
+ value: branchName,
258
+ });
259
+ }
260
+
261
+ const agentName = parseAgentName(branchName);
262
+ const taskId = parseTaskId(branchName);
263
+ const filesModified = await detectModifiedFiles(repoRoot, canonicalBranch, branchName);
264
+
265
+ entry = queue.enqueue({
266
+ branchName,
267
+ taskId,
268
+ agentName,
269
+ filesModified,
270
+ });
271
+ }
272
+
273
+ if (dryRun) {
274
+ const loamClient = createLoamClient(config.project.root);
275
+ const prediction = await safePredictForEntry(entry, canonicalBranch, repoRoot, loamClient);
276
+
277
+ if (json) {
278
+ jsonOutput("merge", { ...entry, prediction });
279
+ } else {
280
+ process.stdout.write(`${formatDryRun(entry, prediction)}\n`);
281
+ }
282
+ return;
283
+ }
284
+
285
+ // Perform the actual merge
286
+ const result = await resolver.resolve(entry, canonicalBranch, repoRoot);
287
+
288
+ // Update queue status based on result
289
+ queue.updateStatus(branchName, result.success ? "merged" : "conflict", result.tier);
290
+
291
+ if (json) {
292
+ jsonOutput("merge", { ...result });
293
+ } else {
294
+ process.stdout.write(`${formatResult(result)}\n`);
295
+ }
296
+
297
+ if (!result.success) {
298
+ throw new MergeError(result.errorMessage ?? `Merge failed for branch "${branchName}"`, {
299
+ branchName,
300
+ conflictFiles: result.conflictFiles,
301
+ });
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Handle merging all pending branches in the queue.
307
+ * Processes entries sequentially in FIFO order.
308
+ */
309
+ async function handleAll(
310
+ queue: ReturnType<typeof createMergeQueue>,
311
+ resolver: ReturnType<typeof createMergeResolver>,
312
+ config: Awaited<ReturnType<typeof loadConfig>>,
313
+ targetBranch: string,
314
+ dryRun: boolean,
315
+ json: boolean,
316
+ ): Promise<void> {
317
+ const canonicalBranch = targetBranch;
318
+ const repoRoot = config.project.root;
319
+
320
+ const pendingEntries = queue.list("pending");
321
+
322
+ if (pendingEntries.length === 0) {
323
+ if (json) {
324
+ jsonOutput("merge", { results: [], count: 0 });
325
+ } else {
326
+ printHint("No pending branches to merge");
327
+ }
328
+ return;
329
+ }
330
+
331
+ if (dryRun) {
332
+ const loamClient = createLoamClient(config.project.root);
333
+ const enrichedEntries: Array<MergeEntry & { prediction: ConflictPrediction }> = [];
334
+ for (const entry of pendingEntries) {
335
+ const prediction = await safePredictForEntry(entry, canonicalBranch, repoRoot, loamClient);
336
+ enrichedEntries.push({ ...entry, prediction });
337
+ }
338
+
339
+ if (json) {
340
+ jsonOutput("merge", { entries: enrichedEntries });
341
+ } else {
342
+ process.stdout.write(
343
+ `${enrichedEntries.length} pending branch${enrichedEntries.length === 1 ? "" : "es"}:\n\n`,
344
+ );
345
+ for (const entry of enrichedEntries) {
346
+ process.stdout.write(`${formatDryRun(entry, entry.prediction)}\n\n`);
347
+ }
348
+ }
349
+ return;
350
+ }
351
+
352
+ const results: MergeResult[] = [];
353
+ let successCount = 0;
354
+ let failCount = 0;
355
+
356
+ for (const entry of pendingEntries) {
357
+ const result = await resolver.resolve(entry, canonicalBranch, repoRoot);
358
+
359
+ queue.updateStatus(entry.branchName, result.success ? "merged" : "conflict", result.tier);
360
+
361
+ results.push(result);
362
+
363
+ if (result.success) {
364
+ successCount++;
365
+ } else {
366
+ failCount++;
367
+ }
368
+
369
+ if (!json) {
370
+ process.stdout.write(`${formatResult(result)}\n\n`);
371
+ }
372
+ }
373
+
374
+ if (json) {
375
+ jsonOutput("merge", { results, count: results.length, successCount, failCount });
376
+ } else {
377
+ process.stdout.write(
378
+ `Done: ${successCount} merged, ${failCount} failed out of ${results.length} total.\n`,
379
+ );
380
+ }
381
+ }