@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,537 @@
1
+ /**
2
+ * CLI command: ap supervisor start|stop|status
3
+ *
4
+ * Manages per-project supervisor agent lifecycle. The supervisor is a persistent
5
+ * agent that runs at the project root (NOT in a worktree), assigned to a specific
6
+ * task, and operates at depth 1 (between coordinator and leaf workers).
7
+ *
8
+ * Unlike the coordinator:
9
+ * - Has a task assignment (required via --task flag)
10
+ * - Has a parent agent (typically "coordinator")
11
+ * - Has depth 1 (default)
12
+ * - Multiple supervisors can run concurrently (distinguished by --name)
13
+ */
14
+
15
+ import { mkdir } from "node:fs/promises";
16
+ import { join } from "node:path";
17
+ import { Command } from "commander";
18
+ import { createIdentity, loadIdentity } from "../agents/identity.ts";
19
+ import { createManifestLoader, resolveModel } from "../agents/manifest.ts";
20
+ import { loadConfig } from "../config.ts";
21
+ import { AgentError, ValidationError } from "../errors.ts";
22
+ import { jsonOutput } from "../json.ts";
23
+ import { printHint, printSuccess } from "../logging/color.ts";
24
+ import { getRuntime } from "../runtimes/registry.ts";
25
+ import { openSessionStore } from "../sessions/compat.ts";
26
+ import { createTrackerClient, resolveBackend, trackerCliName } from "../tracker/factory.ts";
27
+ import type { AgentSession } from "../types.ts";
28
+ import {
29
+ createSession,
30
+ isSessionAlive,
31
+ killSession,
32
+ sanitizeTmuxName,
33
+ sendKeys,
34
+ waitForTuiReady,
35
+ } from "../worktree/tmux.ts";
36
+ import { isRunningAsRoot } from "./sling.ts";
37
+
38
+ /**
39
+ * Build the supervisor startup beacon.
40
+ *
41
+ * @param opts.name - Supervisor agent name
42
+ * @param opts.taskId - Bead task ID
43
+ * @param opts.depth - Hierarchy depth (default 1)
44
+ * @param opts.parent - Parent agent name (default "coordinator")
45
+ */
46
+ export function buildSupervisorBeacon(opts: {
47
+ name: string;
48
+ taskId: string;
49
+ depth: number;
50
+ parent: string;
51
+ trackerCli?: string;
52
+ }): string {
53
+ const cli = opts.trackerCli ?? "bd";
54
+ const timestamp = new Date().toISOString();
55
+ const parts = [
56
+ `[AGENTPLATE] ${opts.name} (supervisor) ${timestamp} task:${opts.taskId}`,
57
+ `Depth: ${opts.depth} | Parent: ${opts.parent} | Role: per-project supervisor`,
58
+ `Startup: run loam prime, check mail (ap mail check --agent ${opts.name}), read task (${cli} show ${opts.taskId}), then begin supervising`,
59
+ ];
60
+ return parts.join(" — ");
61
+ }
62
+
63
+ /**
64
+ * Start a supervisor agent.
65
+ *
66
+ * 1. Parse flags (--task required, --name required)
67
+ * 2. Load config
68
+ * 3. Validate: name is unique in sessions, bead exists and is workable
69
+ * 4. Check no supervisor with same name is already running
70
+ * 5. Deploy hooks with capability "supervisor"
71
+ * 6. Create identity if first run
72
+ * 7. Spawn tmux session at project root with Claude Code
73
+ * 8. Send startup beacon
74
+ * 9. Record session in SessionStore (sessions.db)
75
+ */
76
+ async function startSupervisor(opts: {
77
+ task: string;
78
+ name: string;
79
+ parent: string;
80
+ depth: number;
81
+ json: boolean;
82
+ }): Promise<void> {
83
+ if (!opts.task) {
84
+ throw new ValidationError("--task <task-id> is required", {
85
+ field: "task",
86
+ value: opts.task,
87
+ });
88
+ }
89
+ if (!opts.name) {
90
+ throw new ValidationError("--name <name> is required", {
91
+ field: "name",
92
+ value: opts.name,
93
+ });
94
+ }
95
+
96
+ if (isRunningAsRoot()) {
97
+ throw new AgentError(
98
+ "Cannot spawn agents as root (UID 0). The claude CLI rejects --permission-mode bypassPermissions when run as root, causing the tmux session to die immediately. Run agentplate as a non-root user.",
99
+ );
100
+ }
101
+
102
+ const cwd = process.cwd();
103
+ const config = await loadConfig(cwd);
104
+ const projectRoot = config.project.root;
105
+
106
+ // Validate task exists and is workable (open or in_progress)
107
+ const resolvedBackend = await resolveBackend(config.taskTracker.backend, projectRoot);
108
+ const tracker = createTrackerClient(resolvedBackend, projectRoot);
109
+ const issue = await tracker.show(opts.task);
110
+ if (issue.status !== "open" && issue.status !== "in_progress") {
111
+ throw new ValidationError(`Task ${opts.task} is not workable (status: ${issue.status})`, {
112
+ field: "task",
113
+ value: opts.task,
114
+ });
115
+ }
116
+
117
+ // Check for existing supervisor with same name
118
+ const agentplateDir = join(projectRoot, ".agentplate");
119
+ const { store } = openSessionStore(agentplateDir);
120
+ try {
121
+ const existing = store.getByName(opts.name);
122
+
123
+ if (
124
+ existing &&
125
+ existing.capability === "supervisor" &&
126
+ existing.state !== "completed" &&
127
+ existing.state !== "zombie"
128
+ ) {
129
+ const alive = await isSessionAlive(existing.tmuxSession);
130
+ if (alive) {
131
+ throw new AgentError(
132
+ `Supervisor '${opts.name}' is already running (tmux: ${existing.tmuxSession}, since: ${existing.startedAt})`,
133
+ { agentName: opts.name },
134
+ );
135
+ }
136
+ // Session recorded but tmux is dead — mark as completed and continue
137
+ store.updateState(opts.name, "completed");
138
+ }
139
+
140
+ // Resolve model and runtime early (needed for deployConfig and spawn)
141
+ const manifestLoader = createManifestLoader(
142
+ join(projectRoot, config.agents.manifestPath),
143
+ join(projectRoot, config.agents.baseDir),
144
+ );
145
+ const manifest = await manifestLoader.load();
146
+ const resolvedModel = resolveModel(config, manifest, "supervisor", "opus");
147
+ const runtime = getRuntime(undefined, config, "supervisor");
148
+
149
+ // Deploy supervisor-specific hooks to the project root's .claude/ directory.
150
+ await runtime.deployConfig(projectRoot, undefined, {
151
+ agentName: opts.name,
152
+ capability: "supervisor",
153
+ worktreePath: projectRoot,
154
+ });
155
+
156
+ // Create supervisor identity if first run
157
+ const identityBaseDir = join(projectRoot, ".agentplate", "agents");
158
+ await mkdir(identityBaseDir, { recursive: true });
159
+ const existingIdentity = await loadIdentity(identityBaseDir, opts.name);
160
+ if (!existingIdentity) {
161
+ await createIdentity(identityBaseDir, {
162
+ name: opts.name,
163
+ capability: "supervisor",
164
+ created: new Date().toISOString(),
165
+ sessionsCompleted: 0,
166
+ expertiseDomains: config.loam.enabled ? config.loam.domains : [],
167
+ recentTasks: [],
168
+ });
169
+ }
170
+
171
+ // Spawn tmux session at project root with Claude Code (interactive mode).
172
+ // Inject the supervisor base definition via --append-system-prompt.
173
+ // Pass file path (not content) to avoid tmux "command too long" (agentplate#45).
174
+ const tmuxSession = `agentplate-${sanitizeTmuxName(config.project.name)}-supervisor-${opts.name}`;
175
+ const agentDefPath = join(projectRoot, ".agentplate", "agent-defs", "supervisor.md");
176
+ const agentDefFile = Bun.file(agentDefPath);
177
+ let appendSystemPromptFile: string | undefined;
178
+ if (await agentDefFile.exists()) {
179
+ appendSystemPromptFile = agentDefPath;
180
+ }
181
+ const spawnCmd = runtime.buildSpawnCommand({
182
+ model: resolvedModel.model,
183
+ permissionMode: "bypass",
184
+ cwd: projectRoot,
185
+ appendSystemPromptFile,
186
+ env: {
187
+ ...runtime.buildEnv(resolvedModel),
188
+ AGENTPLATE_AGENT_NAME: opts.name,
189
+ AGENTPLATE_TASK_ID: opts.task,
190
+ },
191
+ });
192
+ const pid = await createSession(tmuxSession, projectRoot, spawnCmd, {
193
+ ...runtime.buildEnv(resolvedModel),
194
+ AGENTPLATE_AGENT_NAME: opts.name,
195
+ AGENTPLATE_TASK_ID: opts.task,
196
+ });
197
+
198
+ // Wait for Claude Code TUI to render before sending input
199
+ await waitForTuiReady(tmuxSession, (content) => runtime.detectReady(content));
200
+ await Bun.sleep(1_000);
201
+
202
+ const beacon = buildSupervisorBeacon({
203
+ name: opts.name,
204
+ taskId: opts.task,
205
+ depth: opts.depth,
206
+ parent: opts.parent,
207
+ trackerCli: trackerCliName(resolvedBackend),
208
+ });
209
+ await sendKeys(tmuxSession, beacon);
210
+
211
+ // Follow-up Enters with increasing delays to ensure submission
212
+ for (const delay of [1_000, 2_000, 3_000, 5_000]) {
213
+ await Bun.sleep(delay);
214
+ await sendKeys(tmuxSession, "");
215
+ }
216
+
217
+ // Record session
218
+ const session: AgentSession = {
219
+ id: `session-${Date.now()}-${opts.name}`,
220
+ agentName: opts.name,
221
+ capability: "supervisor",
222
+ worktreePath: projectRoot, // Supervisor uses project root, not a worktree
223
+ branchName: config.project.canonicalBranch, // Operates on canonical branch
224
+ taskId: opts.task,
225
+ tmuxSession,
226
+ state: "booting",
227
+ pid,
228
+ parentAgent: opts.parent,
229
+ depth: opts.depth,
230
+ runId: null,
231
+ startedAt: new Date().toISOString(),
232
+ lastActivity: new Date().toISOString(),
233
+ escalationLevel: 0,
234
+ stalledSince: null,
235
+ transcriptPath: null,
236
+ };
237
+
238
+ store.upsert(session);
239
+
240
+ const output = {
241
+ agentName: opts.name,
242
+ capability: "supervisor",
243
+ tmuxSession,
244
+ projectRoot,
245
+ taskId: opts.task,
246
+ parent: opts.parent,
247
+ depth: opts.depth,
248
+ pid,
249
+ };
250
+
251
+ if (opts.json) {
252
+ jsonOutput("supervisor start", output);
253
+ } else {
254
+ printSuccess("Supervisor started", opts.name);
255
+ process.stdout.write(` Tmux: ${tmuxSession}\n`);
256
+ process.stdout.write(` Root: ${projectRoot}\n`);
257
+ process.stdout.write(` Task: ${opts.task}\n`);
258
+ process.stdout.write(` Parent: ${opts.parent}\n`);
259
+ process.stdout.write(` Depth: ${opts.depth}\n`);
260
+ process.stdout.write(` PID: ${pid}\n`);
261
+ }
262
+ } finally {
263
+ store.close();
264
+ }
265
+ }
266
+
267
+ /**
268
+ * Stop a supervisor agent.
269
+ *
270
+ * 1. Find the active supervisor session by name
271
+ * 2. Kill the tmux session (with process tree cleanup)
272
+ * 3. Mark session as completed in SessionStore
273
+ */
274
+ async function stopSupervisor(opts: { name: string; json: boolean }): Promise<void> {
275
+ if (!opts.name) {
276
+ throw new ValidationError("--name <name> is required", {
277
+ field: "name",
278
+ value: opts.name,
279
+ });
280
+ }
281
+
282
+ const cwd = process.cwd();
283
+ const config = await loadConfig(cwd);
284
+ const projectRoot = config.project.root;
285
+
286
+ const agentplateDir = join(projectRoot, ".agentplate");
287
+ const { store } = openSessionStore(agentplateDir);
288
+ try {
289
+ const session = store.getByName(opts.name);
290
+
291
+ if (
292
+ !session ||
293
+ session.capability !== "supervisor" ||
294
+ session.state === "completed" ||
295
+ session.state === "zombie"
296
+ ) {
297
+ throw new AgentError(`No active supervisor session found for '${opts.name}'`, {
298
+ agentName: opts.name,
299
+ });
300
+ }
301
+
302
+ // Kill tmux session with process tree cleanup
303
+ const alive = await isSessionAlive(session.tmuxSession);
304
+ if (alive) {
305
+ await killSession(session.tmuxSession);
306
+ }
307
+
308
+ // Update session state
309
+ store.updateState(opts.name, "completed");
310
+ store.updateLastActivity(opts.name);
311
+
312
+ if (opts.json) {
313
+ jsonOutput("supervisor stop", { stopped: true, sessionId: session.id });
314
+ } else {
315
+ printSuccess("Supervisor stopped", opts.name);
316
+ }
317
+ } finally {
318
+ store.close();
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Show supervisor status.
324
+ *
325
+ * If --name is provided, show status for that specific supervisor.
326
+ * Otherwise, list all supervisors.
327
+ */
328
+ async function statusSupervisor(opts: { name?: string; json: boolean }): Promise<void> {
329
+ const cwd = process.cwd();
330
+ const config = await loadConfig(cwd);
331
+ const projectRoot = config.project.root;
332
+
333
+ const agentplateDir = join(projectRoot, ".agentplate");
334
+ const { store } = openSessionStore(agentplateDir);
335
+ try {
336
+ if (opts.name) {
337
+ // Show specific supervisor
338
+ const session = store.getByName(opts.name);
339
+
340
+ if (
341
+ !session ||
342
+ session.capability !== "supervisor" ||
343
+ session.state === "completed" ||
344
+ session.state === "zombie"
345
+ ) {
346
+ if (opts.json) {
347
+ jsonOutput("supervisor status", { running: false });
348
+ } else {
349
+ printHint("Supervisor not running");
350
+ }
351
+ return;
352
+ }
353
+
354
+ const alive = await isSessionAlive(session.tmuxSession);
355
+
356
+ // Reconcile state: we already filtered out completed/zombie above,
357
+ // so if tmux is dead this session needs to be marked as zombie.
358
+ if (!alive) {
359
+ store.updateState(opts.name, "zombie");
360
+ store.updateLastActivity(opts.name);
361
+ session.state = "zombie";
362
+ }
363
+
364
+ const status = {
365
+ running: alive,
366
+ sessionId: session.id,
367
+ agentName: session.agentName,
368
+ state: session.state,
369
+ tmuxSession: session.tmuxSession,
370
+ taskId: session.taskId,
371
+ parentAgent: session.parentAgent,
372
+ depth: session.depth,
373
+ pid: session.pid,
374
+ startedAt: session.startedAt,
375
+ lastActivity: session.lastActivity,
376
+ };
377
+
378
+ if (opts.json) {
379
+ jsonOutput("supervisor status", status);
380
+ } else {
381
+ const stateLabel = alive ? "running" : session.state;
382
+ process.stdout.write(`Supervisor '${opts.name}': ${stateLabel}\n`);
383
+ process.stdout.write(` Session: ${session.id}\n`);
384
+ process.stdout.write(` Tmux: ${session.tmuxSession}\n`);
385
+ process.stdout.write(` Task: ${session.taskId}\n`);
386
+ process.stdout.write(` Parent: ${session.parentAgent}\n`);
387
+ process.stdout.write(` Depth: ${session.depth}\n`);
388
+ process.stdout.write(` PID: ${session.pid}\n`);
389
+ process.stdout.write(` Started: ${session.startedAt}\n`);
390
+ process.stdout.write(` Activity: ${session.lastActivity}\n`);
391
+ }
392
+ } else {
393
+ // List all supervisors
394
+ const allSessions = store.getAll();
395
+ const supervisors = allSessions.filter((s) => s.capability === "supervisor");
396
+
397
+ if (supervisors.length === 0) {
398
+ if (opts.json) {
399
+ jsonOutput("supervisor status", { supervisors: [] });
400
+ } else {
401
+ printHint("No supervisor sessions found");
402
+ }
403
+ return;
404
+ }
405
+
406
+ const statuses = await Promise.all(
407
+ supervisors.map(async (session) => {
408
+ const alive = await isSessionAlive(session.tmuxSession);
409
+
410
+ // Reconcile state
411
+ if (!alive && session.state !== "completed" && session.state !== "zombie") {
412
+ store.updateState(session.agentName, "zombie");
413
+ store.updateLastActivity(session.agentName);
414
+ }
415
+
416
+ return {
417
+ agentName: session.agentName,
418
+ running: alive,
419
+ state:
420
+ !alive && session.state !== "completed" && session.state !== "zombie"
421
+ ? ("zombie" as const)
422
+ : session.state,
423
+ tmuxSession: session.tmuxSession,
424
+ taskId: session.taskId,
425
+ parentAgent: session.parentAgent,
426
+ depth: session.depth,
427
+ startedAt: session.startedAt,
428
+ };
429
+ }),
430
+ );
431
+
432
+ if (opts.json) {
433
+ jsonOutput("supervisor status", { supervisors: statuses });
434
+ } else {
435
+ process.stdout.write("Supervisor sessions:\n");
436
+ for (const status of statuses) {
437
+ const stateLabel = status.running ? "running" : status.state;
438
+ process.stdout.write(
439
+ ` ${status.agentName}: ${stateLabel} (task: ${status.taskId}, parent: ${status.parentAgent})\n`,
440
+ );
441
+ }
442
+ }
443
+ }
444
+ } finally {
445
+ store.close();
446
+ }
447
+ }
448
+
449
+ /**
450
+ * Create the Commander command for `ap supervisor`.
451
+ */
452
+ export function createSupervisorCommand(): Command {
453
+ const cmd = new Command("supervisor").description("[DEPRECATED] Per-project supervisor agent");
454
+
455
+ cmd
456
+ .command("start")
457
+ .description("Start a supervisor (spawns Claude Code at project root)")
458
+ .requiredOption("--task <task-id>", "Task ID (required)")
459
+ .requiredOption("--name <name>", "Unique supervisor name (required)")
460
+ .option("--parent <agent>", "Parent agent name", "coordinator")
461
+ .option("--depth <n>", "Hierarchy depth", "1")
462
+ .option("--json", "Output as JSON")
463
+ .action(
464
+ async (opts: {
465
+ task: string;
466
+ name: string;
467
+ parent: string;
468
+ depth: string;
469
+ json?: boolean;
470
+ }) => {
471
+ console.error(
472
+ "[DEPRECATED] ap supervisor is deprecated. Use 'ap sling --capability lead' instead.",
473
+ );
474
+ await startSupervisor({
475
+ task: opts.task,
476
+ name: opts.name,
477
+ parent: opts.parent,
478
+ depth: Number.parseInt(opts.depth, 10),
479
+ json: opts.json ?? false,
480
+ });
481
+ },
482
+ );
483
+
484
+ cmd
485
+ .command("stop")
486
+ .description("Stop a supervisor (kills tmux session)")
487
+ .requiredOption("--name <name>", "Supervisor name to stop (required)")
488
+ .option("--json", "Output as JSON")
489
+ .action(async (opts: { name: string; json?: boolean }) => {
490
+ await stopSupervisor({ name: opts.name, json: opts.json ?? false });
491
+ });
492
+
493
+ cmd
494
+ .command("status")
495
+ .description("Show supervisor state")
496
+ .option("--name <name>", "Show specific supervisor (optional, lists all if omitted)")
497
+ .option("--json", "Output as JSON")
498
+ .action(async (opts: { name?: string; json?: boolean }) => {
499
+ await statusSupervisor({ name: opts.name, json: opts.json ?? false });
500
+ });
501
+
502
+ return cmd;
503
+ }
504
+
505
+ /**
506
+ * Entry point for `ap supervisor <subcommand>`.
507
+ */
508
+ export async function supervisorCommand(args: string[]): Promise<void> {
509
+ const cmd = createSupervisorCommand();
510
+ cmd.exitOverride();
511
+ cmd.configureOutput({ writeErr: () => {} });
512
+ for (const sub of cmd.commands) {
513
+ sub.exitOverride();
514
+ sub.configureOutput({ writeErr: () => {} });
515
+ }
516
+
517
+ if (args.length === 0) {
518
+ process.stdout.write(cmd.helpInformation());
519
+ return;
520
+ }
521
+
522
+ try {
523
+ await cmd.parseAsync(args, { from: "user" });
524
+ } catch (err: unknown) {
525
+ if (err && typeof err === "object" && "code" in err) {
526
+ const code = (err as { code: string }).code;
527
+ if (code === "commander.helpDisplayed" || code === "commander.version") {
528
+ return;
529
+ }
530
+ if (code === "commander.unknownCommand") {
531
+ const message = err instanceof Error ? err.message : String(err);
532
+ throw new ValidationError(message, { field: "subcommand" });
533
+ }
534
+ }
535
+ throw err;
536
+ }
537
+ }