@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,403 @@
1
+ /**
2
+ * CLI command: agentplate status [--json] [--watch]
3
+ *
4
+ * Shows active agents, worktree status, task summary, mail queue depth,
5
+ * and merge queue state. --watch mode uses polling for live updates.
6
+ */
7
+
8
+ import { join } from "node:path";
9
+ import { Command } from "commander";
10
+ import { loadConfig } from "../config.ts";
11
+ import { ValidationError } from "../errors.ts";
12
+ import { jsonOutput } from "../json.ts";
13
+ import { accent, color } from "../logging/color.ts";
14
+ import { formatDuration } from "../logging/format.ts";
15
+ import { renderHeader } from "../logging/theme.ts";
16
+ import { createMailStore } from "../mail/store.ts";
17
+ import { createMergeQueue } from "../merge/queue.ts";
18
+ import { createMetricsStore } from "../metrics/store.ts";
19
+ import { openSessionStore } from "../sessions/compat.ts";
20
+ import type { AgentSession } from "../types.ts";
21
+ import { evaluateHealth } from "../watchdog/health.ts";
22
+ import { listWorktrees } from "../worktree/manager.ts";
23
+ import { isProcessAlive, listSessions } from "../worktree/tmux.ts";
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Subprocess result cache (TTL-based, module-level)
27
+ // ---------------------------------------------------------------------------
28
+
29
+ interface CacheEntry<T> {
30
+ data: T;
31
+ timestamp: number;
32
+ }
33
+
34
+ let worktreeCache: CacheEntry<Array<{ path: string; branch: string; head: string }>> | null = null;
35
+ let tmuxCache: CacheEntry<Array<{ name: string; pid: number }>> | null = null;
36
+
37
+ const DEFAULT_CACHE_TTL_MS = 10_000; // 10 seconds
38
+
39
+ export function invalidateStatusCache(): void {
40
+ worktreeCache = null;
41
+ tmuxCache = null;
42
+ }
43
+
44
+ export async function getCachedWorktrees(
45
+ root: string,
46
+ ttlMs: number = DEFAULT_CACHE_TTL_MS,
47
+ ): Promise<Array<{ path: string; branch: string; head: string }>> {
48
+ const now = Date.now();
49
+ if (worktreeCache && now - worktreeCache.timestamp < ttlMs) {
50
+ return worktreeCache.data;
51
+ }
52
+ const data = await listWorktrees(root);
53
+ worktreeCache = { data, timestamp: now };
54
+ return data;
55
+ }
56
+
57
+ export async function getCachedTmuxSessions(
58
+ ttlMs: number = DEFAULT_CACHE_TTL_MS,
59
+ ): Promise<Array<{ name: string; pid: number }>> {
60
+ const now = Date.now();
61
+ if (tmuxCache && now - tmuxCache.timestamp < ttlMs) {
62
+ return tmuxCache.data;
63
+ }
64
+ try {
65
+ const data = await listSessions();
66
+ tmuxCache = { data, timestamp: now };
67
+ return data;
68
+ } catch {
69
+ return tmuxCache?.data ?? [];
70
+ }
71
+ }
72
+
73
+ export interface VerboseAgentDetail {
74
+ worktreePath: string;
75
+ logsDir: string;
76
+ lastMailSent: string | null;
77
+ lastMailReceived: string | null;
78
+ capability: string;
79
+ }
80
+
81
+ export interface StatusData {
82
+ currentRunId?: string | null;
83
+ agents: AgentSession[];
84
+ worktrees: Array<{ path: string; branch: string; head: string }>;
85
+ tmuxSessions: Array<{ name: string; pid: number }>;
86
+ unreadMailCount: number;
87
+ unreadMailScope: string;
88
+ mergeQueueCount: number;
89
+ recentMetricsCount: number;
90
+ verboseDetails?: Record<string, VerboseAgentDetail>;
91
+ }
92
+
93
+ async function readCurrentRunId(agentplateDir: string): Promise<string | null> {
94
+ const path = join(agentplateDir, "current-run.txt");
95
+ const file = Bun.file(path);
96
+ if (!(await file.exists())) {
97
+ return null;
98
+ }
99
+ const text = await file.text();
100
+ const trimmed = text.trim();
101
+ return trimmed.length > 0 ? trimmed : null;
102
+ }
103
+
104
+ /**
105
+ * Gather all status data.
106
+ * @param agentName - Which agent's perspective for unread mail count (default "orchestrator")
107
+ * @param verbose - When true, collect extra per-agent detail (worktree path, logs dir, last mail)
108
+ * @param runId - When provided, only sessions for that run are returned; null/undefined shows all
109
+ */
110
+ export async function gatherStatus(
111
+ root: string,
112
+ agentName = "orchestrator",
113
+ verbose = false,
114
+ runId?: string | null,
115
+ ): Promise<StatusData> {
116
+ const agentplateDir = join(root, ".agentplate");
117
+ const { store } = openSessionStore(agentplateDir);
118
+
119
+ let sessions: AgentSession[];
120
+ try {
121
+ // When run-scoped, also include sessions with null runId (e.g. coordinator)
122
+ // because SQL WHERE run_id = $run_id never matches NULL rows.
123
+ sessions = runId
124
+ ? [...store.getByRun(runId), ...store.getAll().filter((s) => s.runId === null)]
125
+ : store.getAll();
126
+
127
+ const worktrees = await getCachedWorktrees(root);
128
+
129
+ const tmuxSessions = await getCachedTmuxSessions();
130
+
131
+ // Reconcile agent states using the same health evaluation as the
132
+ // dashboard and watchdog. This handles:
133
+ // 1. tmux dead -> zombie (regardless of recorded state)
134
+ // 2. persistent capabilities (coordinator, monitor) booting -> working when tmux alive
135
+ // 3. time-based stale/zombie detection for non-persistent agents
136
+ const tmuxSessionNames = new Set(tmuxSessions.map((s) => s.name));
137
+ const healthThresholds = { staleMs: 300_000, zombieMs: 600_000 };
138
+ for (const session of sessions) {
139
+ if (session.state === "completed") continue;
140
+ const tmuxAlive = tmuxSessionNames.has(session.tmuxSession);
141
+ const check = evaluateHealth(session, tmuxAlive, healthThresholds);
142
+ if (check.state !== session.state) {
143
+ try {
144
+ store.updateState(session.agentName, check.state);
145
+ session.state = check.state;
146
+ } catch {
147
+ // Best effort: don't fail status display if update fails
148
+ }
149
+ }
150
+ }
151
+
152
+ let unreadMailCount = 0;
153
+ let mailStore: ReturnType<typeof createMailStore> | null = null;
154
+ try {
155
+ const mailDbPath = join(root, ".agentplate", "mail.db");
156
+ const mailFile = Bun.file(mailDbPath);
157
+ if (await mailFile.exists()) {
158
+ mailStore = createMailStore(mailDbPath);
159
+ const unread = mailStore.getAll({ to: agentName, unread: true });
160
+ unreadMailCount = unread.length;
161
+ }
162
+ } catch {
163
+ // mail db might not exist
164
+ }
165
+
166
+ let mergeQueueCount = 0;
167
+ try {
168
+ const queuePath = join(root, ".agentplate", "merge-queue.db");
169
+ const queue = createMergeQueue(queuePath);
170
+ mergeQueueCount = queue.list("pending").length;
171
+ queue.close();
172
+ } catch {
173
+ // queue might not exist
174
+ }
175
+
176
+ let recentMetricsCount = 0;
177
+ try {
178
+ const metricsDbPath = join(root, ".agentplate", "metrics.db");
179
+ const metricsFile = Bun.file(metricsDbPath);
180
+ if (await metricsFile.exists()) {
181
+ const metricsStore = createMetricsStore(metricsDbPath);
182
+ recentMetricsCount = metricsStore.countSessions();
183
+ metricsStore.close();
184
+ }
185
+ } catch {
186
+ // metrics db might not exist
187
+ }
188
+
189
+ let verboseDetails: Record<string, VerboseAgentDetail> | undefined;
190
+ if (verbose && sessions.length > 0) {
191
+ verboseDetails = {};
192
+ for (const session of sessions) {
193
+ const logsDir = join(root, ".agentplate", "logs", session.agentName);
194
+
195
+ let lastMailSent: string | null = null;
196
+ let lastMailReceived: string | null = null;
197
+ if (mailStore) {
198
+ try {
199
+ const sent = mailStore.getAll({ from: session.agentName });
200
+ if (sent.length > 0 && sent[0]) {
201
+ lastMailSent = sent[0].createdAt;
202
+ }
203
+ const received = mailStore.getAll({ to: session.agentName });
204
+ if (received.length > 0 && received[0]) {
205
+ lastMailReceived = received[0].createdAt;
206
+ }
207
+ } catch {
208
+ // Best effort
209
+ }
210
+ }
211
+
212
+ verboseDetails[session.agentName] = {
213
+ worktreePath: session.worktreePath,
214
+ logsDir,
215
+ lastMailSent,
216
+ lastMailReceived,
217
+ capability: session.capability,
218
+ };
219
+ }
220
+ }
221
+
222
+ if (mailStore) {
223
+ mailStore.close();
224
+ }
225
+
226
+ return {
227
+ currentRunId: runId,
228
+ agents: sessions,
229
+ worktrees,
230
+ tmuxSessions,
231
+ unreadMailCount,
232
+ unreadMailScope: agentName,
233
+ mergeQueueCount,
234
+ recentMetricsCount,
235
+ verboseDetails,
236
+ };
237
+ } finally {
238
+ store.close();
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Print status in human-readable format.
244
+ */
245
+ export function printStatus(data: StatusData): void {
246
+ const now = Date.now();
247
+ const w = process.stdout.write.bind(process.stdout);
248
+
249
+ w(`${renderHeader("Agentplate Status")}\n\n`);
250
+ if (data.currentRunId) {
251
+ w(`Run: ${accent(data.currentRunId)}\n`);
252
+ }
253
+
254
+ // Active agents
255
+ const active = data.agents.filter((a) => a.state !== "zombie" && a.state !== "completed");
256
+ w(`Agents: ${active.length} active\n`);
257
+ if (active.length > 0) {
258
+ const tmuxSessionNames = new Set(data.tmuxSessions.map((s) => s.name));
259
+ for (const agent of active) {
260
+ const endTime =
261
+ agent.state === "completed" || agent.state === "zombie"
262
+ ? new Date(agent.lastActivity).getTime()
263
+ : now;
264
+ const duration = formatDuration(endTime - new Date(agent.startedAt).getTime());
265
+ // See dashboard.ts for the three-topology liveness rationale (agentplate-7a34).
266
+ const isHeadless = agent.tmuxSession === "" && agent.pid !== null;
267
+ const isSpawnPerTurn = agent.tmuxSession === "" && agent.pid === null;
268
+ const alive = isSpawnPerTurn
269
+ ? agent.state !== "zombie" && agent.state !== "completed"
270
+ : isHeadless
271
+ ? agent.pid !== null && isProcessAlive(agent.pid)
272
+ : tmuxSessionNames.has(agent.tmuxSession);
273
+ const aliveMarker = alive ? color.green(">") : color.red("x");
274
+ w(` ${aliveMarker} ${accent(agent.agentName)} [${agent.capability}] `);
275
+ w(`${agent.state} | ${accent(agent.taskId)} | ${duration}\n`);
276
+
277
+ const detail = data.verboseDetails?.[agent.agentName];
278
+ if (detail) {
279
+ w(` Worktree: ${detail.worktreePath}\n`);
280
+ w(` Logs: ${detail.logsDir}\n`);
281
+ w(` Mail sent: ${detail.lastMailSent ?? "none"}`);
282
+ w(` | received: ${detail.lastMailReceived ?? "none"}\n`);
283
+ }
284
+ }
285
+ } else {
286
+ w(" No active agents\n");
287
+ }
288
+ w("\n");
289
+
290
+ // Worktrees
291
+ const agentplateWts = data.worktrees.filter((wt) => wt.branch.startsWith("agentplate/"));
292
+ w(`Worktrees: ${agentplateWts.length}\n`);
293
+ for (const wt of agentplateWts) {
294
+ w(` ${wt.branch}\n`);
295
+ }
296
+ if (agentplateWts.length === 0) {
297
+ w(" No agent worktrees\n");
298
+ }
299
+ w("\n");
300
+
301
+ // Mail
302
+ // Scope is per-agent (the orchestrator by default). Differs from `ap mail list
303
+ // --unread` (system-wide) and `ap mail check` (per-agent, marks as read).
304
+ w(`Mail: ${data.unreadMailCount} unread (to ${data.unreadMailScope})\n`);
305
+
306
+ // Merge queue
307
+ w(`Merge queue: ${data.mergeQueueCount} pending\n`);
308
+
309
+ // Metrics
310
+ w(`Sessions recorded: ${data.recentMetricsCount}\n`);
311
+ }
312
+
313
+ interface StatusOpts {
314
+ json?: boolean;
315
+ watch?: boolean;
316
+ verbose?: boolean;
317
+ all?: boolean;
318
+ interval?: string;
319
+ agent?: string;
320
+ }
321
+
322
+ async function executeStatus(opts: StatusOpts): Promise<void> {
323
+ const json = opts.json ?? false;
324
+ const watch = opts.watch ?? false;
325
+ const verbose = opts.verbose ?? false;
326
+ const all = opts.all ?? false;
327
+ const intervalStr = opts.interval;
328
+ const interval = intervalStr ? Number.parseInt(intervalStr, 10) : 3000;
329
+
330
+ if (Number.isNaN(interval) || interval < 500) {
331
+ throw new ValidationError("--interval must be a number >= 500 (milliseconds)", {
332
+ field: "interval",
333
+ value: intervalStr,
334
+ });
335
+ }
336
+
337
+ const agentName = opts.agent ?? "orchestrator";
338
+
339
+ const cwd = process.cwd();
340
+ const config = await loadConfig(cwd);
341
+ const root = config.project.root;
342
+
343
+ let runId: string | null | undefined;
344
+ if (!all) {
345
+ const agentplateDir = join(root, ".agentplate");
346
+ runId = await readCurrentRunId(agentplateDir);
347
+ }
348
+
349
+ if (watch) {
350
+ process.stderr.write(
351
+ "Warning: --watch is deprecated. Use 'ap dashboard' for live monitoring.\n\n",
352
+ );
353
+ // Polling loop (kept for one release cycle)
354
+ while (true) {
355
+ // Clear screen
356
+ process.stdout.write("\x1b[2J\x1b[H");
357
+ const data = await gatherStatus(root, agentName, verbose, runId);
358
+ if (json) {
359
+ jsonOutput("status", data as unknown as Record<string, unknown>);
360
+ } else {
361
+ printStatus(data);
362
+ }
363
+ await Bun.sleep(interval);
364
+ }
365
+ } else {
366
+ const data = await gatherStatus(root, agentName, verbose, runId);
367
+ if (json) {
368
+ jsonOutput("status", data as unknown as Record<string, unknown>);
369
+ } else {
370
+ printStatus(data);
371
+ }
372
+ }
373
+ }
374
+
375
+ export function createStatusCommand(): Command {
376
+ return new Command("status")
377
+ .description("Show all active agents and project state")
378
+ .option("--json", "Output as JSON")
379
+ .option("--verbose", "Show extra detail per agent (worktree, logs, mail timestamps)")
380
+ .option("--agent <name>", "Show unread mail for this agent (default: orchestrator)")
381
+ .option("--all", "Show sessions from all runs (default: current run only)")
382
+ .option("--watch", "(deprecated) Use 'ap dashboard' for live monitoring")
383
+ .option("--interval <ms>", "Poll interval for --watch in milliseconds (default: 3000)")
384
+ .action(async (opts: StatusOpts) => {
385
+ await executeStatus(opts);
386
+ });
387
+ }
388
+
389
+ export async function statusCommand(args: string[]): Promise<void> {
390
+ const cmd = createStatusCommand();
391
+ cmd.exitOverride();
392
+ try {
393
+ await cmd.parseAsync(args, { from: "user" });
394
+ } catch (err: unknown) {
395
+ if (err && typeof err === "object" && "code" in err) {
396
+ const code = (err as { code: string }).code;
397
+ if (code === "commander.helpDisplayed" || code === "commander.version") {
398
+ return;
399
+ }
400
+ }
401
+ throw err;
402
+ }
403
+ }