@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,243 @@
1
+ import { Database } from "bun:sqlite";
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import type { DoctorCheck, DoctorCheckFn } from "./types.ts";
5
+
6
+ /**
7
+ * Database integrity checks.
8
+ * Validates SQLite databases (mail.db, metrics.db, sessions.db) exist and have correct schema.
9
+ */
10
+ export const checkDatabases: DoctorCheckFn = (_config, agentplateDir): DoctorCheck[] => {
11
+ const checks: DoctorCheck[] = [];
12
+
13
+ // Define expected databases and their required tables. `optional` databases
14
+ // are created lazily (e.g. merge-queue.db on first merge), so their absence
15
+ // is normal rather than a failure.
16
+ const databases: Array<{
17
+ name: string;
18
+ tables: string[];
19
+ requiredColumns: Record<string, string[]>;
20
+ optional?: boolean;
21
+ }> = [
22
+ {
23
+ name: "mail.db",
24
+ tables: ["messages"],
25
+ requiredColumns: {
26
+ messages: [
27
+ "id",
28
+ "from_agent",
29
+ "to_agent",
30
+ "subject",
31
+ "body",
32
+ "type",
33
+ "priority",
34
+ "thread_id",
35
+ "payload",
36
+ "read",
37
+ "created_at",
38
+ ],
39
+ },
40
+ },
41
+ {
42
+ name: "metrics.db",
43
+ tables: ["sessions"],
44
+ requiredColumns: {
45
+ sessions: [
46
+ "agent_name",
47
+ "task_id",
48
+ "capability",
49
+ "started_at",
50
+ "completed_at",
51
+ "duration_ms",
52
+ "exit_code",
53
+ "merge_result",
54
+ "parent_agent",
55
+ "input_tokens",
56
+ "output_tokens",
57
+ "cache_read_tokens",
58
+ "cache_creation_tokens",
59
+ "estimated_cost_usd",
60
+ "model_used",
61
+ ],
62
+ },
63
+ },
64
+ {
65
+ name: "sessions.db",
66
+ tables: ["sessions", "runs"],
67
+ requiredColumns: {
68
+ sessions: [
69
+ "id",
70
+ "agent_name",
71
+ "capability",
72
+ "worktree_path",
73
+ "branch_name",
74
+ "task_id",
75
+ "tmux_session",
76
+ "state",
77
+ "pid",
78
+ "parent_agent",
79
+ "depth",
80
+ "run_id",
81
+ "started_at",
82
+ "last_activity",
83
+ "escalation_level",
84
+ "stalled_since",
85
+ ],
86
+ runs: [
87
+ "id",
88
+ "started_at",
89
+ "completed_at",
90
+ "agent_count",
91
+ "coordinator_session_id",
92
+ "status",
93
+ ],
94
+ },
95
+ },
96
+ {
97
+ name: "merge-queue.db",
98
+ optional: true,
99
+ tables: ["merge_queue"],
100
+ requiredColumns: {
101
+ merge_queue: [
102
+ "id",
103
+ "branch_name",
104
+ "task_id",
105
+ "agent_name",
106
+ "files_modified",
107
+ "enqueued_at",
108
+ "status",
109
+ "resolved_tier",
110
+ ],
111
+ },
112
+ },
113
+ ];
114
+
115
+ for (const dbSpec of databases) {
116
+ const dbPath = join(agentplateDir, dbSpec.name);
117
+
118
+ // Check if database file exists
119
+ if (!existsSync(dbPath)) {
120
+ checks.push({
121
+ name: `${dbSpec.name} exists`,
122
+ category: "databases",
123
+ // Optional DBs are created on demand — a missing file is normal,
124
+ // not a failure (consistent with the `merge` category check).
125
+ status: dbSpec.optional ? "pass" : "fail",
126
+ message: dbSpec.optional
127
+ ? `${dbSpec.name} not yet created (normal — created on first use)`
128
+ : `Database file ${dbSpec.name} does not exist`,
129
+ details: [`Expected at: ${dbPath}`],
130
+ });
131
+ continue;
132
+ }
133
+
134
+ // Try to open the database
135
+ let db: Database | null = null;
136
+ try {
137
+ db = new Database(dbPath);
138
+
139
+ // Check WAL mode is enabled
140
+ const journalMode = db.prepare<{ journal_mode: string }, []>("PRAGMA journal_mode").get();
141
+ const walEnabled = journalMode?.journal_mode?.toLowerCase() === "wal";
142
+
143
+ // Check for required tables
144
+ const missingTables: string[] = [];
145
+ const schemaIssues: string[] = [];
146
+
147
+ for (const tableName of dbSpec.tables) {
148
+ const tableExists = db
149
+ .prepare<{ count: number }, [string]>(
150
+ "SELECT COUNT(*) as count FROM sqlite_master WHERE type='table' AND name=?",
151
+ )
152
+ .get(tableName);
153
+
154
+ if (!tableExists || tableExists.count === 0) {
155
+ missingTables.push(tableName);
156
+ continue;
157
+ }
158
+
159
+ // Check columns if table exists
160
+ const requiredCols =
161
+ dbSpec.requiredColumns[tableName as keyof typeof dbSpec.requiredColumns];
162
+ if (requiredCols) {
163
+ const columns = db.prepare<{ name: string }, []>(`PRAGMA table_info(${tableName})`).all();
164
+ const existingCols = new Set(columns.map((c) => c.name));
165
+
166
+ for (const reqCol of requiredCols) {
167
+ if (!existingCols.has(reqCol)) {
168
+ schemaIssues.push(`Table ${tableName} missing column: ${reqCol}`);
169
+ }
170
+ }
171
+ }
172
+ }
173
+
174
+ // Determine check status
175
+ if (missingTables.length > 0 || schemaIssues.length > 0) {
176
+ const details: string[] = [];
177
+ if (missingTables.length > 0) {
178
+ details.push(`Missing tables: ${missingTables.join(", ")}`);
179
+ }
180
+ if (schemaIssues.length > 0) {
181
+ details.push(...schemaIssues);
182
+ }
183
+ if (!walEnabled) {
184
+ details.push("WAL mode not enabled");
185
+ }
186
+
187
+ checks.push({
188
+ name: `${dbSpec.name} schema`,
189
+ category: "databases",
190
+ status: "fail",
191
+ message: `Database ${dbSpec.name} has schema issues`,
192
+ details,
193
+ fixable: true,
194
+ });
195
+ } else if (!walEnabled) {
196
+ checks.push({
197
+ name: `${dbSpec.name} WAL mode`,
198
+ category: "databases",
199
+ status: "warn",
200
+ message: `Database ${dbSpec.name} is not using WAL mode`,
201
+ details: ["WAL mode improves concurrent access performance"],
202
+ fixable: true,
203
+ fix: () => {
204
+ const fixDb = new Database(dbPath);
205
+ fixDb.exec("PRAGMA journal_mode=WAL");
206
+ fixDb.close();
207
+ return [`Enabled WAL mode on ${dbSpec.name}`];
208
+ },
209
+ });
210
+ } else {
211
+ checks.push({
212
+ name: `${dbSpec.name} health`,
213
+ category: "databases",
214
+ status: "pass",
215
+ message: `Database ${dbSpec.name} is healthy`,
216
+ });
217
+ }
218
+
219
+ db.close();
220
+ } catch (err) {
221
+ if (db) {
222
+ try {
223
+ db.close();
224
+ } catch {
225
+ // Ignore close errors
226
+ }
227
+ }
228
+
229
+ checks.push({
230
+ name: `${dbSpec.name} integrity`,
231
+ category: "databases",
232
+ status: "fail",
233
+ message: `Failed to open or validate ${dbSpec.name}`,
234
+ details: [
235
+ err instanceof Error ? err.message : String(err),
236
+ "Database may be corrupted or locked",
237
+ ],
238
+ });
239
+ }
240
+ }
241
+
242
+ return checks;
243
+ };
@@ -0,0 +1,296 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import type { AgentplateConfig } from "../types.ts";
3
+ import { checkAlias, checkDependencies, checkTool } from "./dependencies.ts";
4
+
5
+ // Minimal config for testing
6
+ const mockConfig: AgentplateConfig = {
7
+ project: {
8
+ name: "test-project",
9
+ root: "/tmp/test",
10
+ canonicalBranch: "main",
11
+ },
12
+ agents: {
13
+ manifestPath: "/tmp/.agentplate/agent-manifest.json",
14
+ baseDir: "/tmp/.agentplate/agents",
15
+ maxConcurrent: 5,
16
+ staggerDelayMs: 1000,
17
+ maxDepth: 2,
18
+ maxSessionsPerRun: 0,
19
+ maxAgentsPerLead: 5,
20
+ },
21
+ worktrees: {
22
+ baseDir: "/tmp/.agentplate/worktrees",
23
+ },
24
+ taskTracker: {
25
+ backend: "auto",
26
+ enabled: false,
27
+ },
28
+ loam: {
29
+ enabled: false,
30
+ domains: [],
31
+ primeFormat: "markdown",
32
+ },
33
+ merge: {
34
+ aiResolveEnabled: false,
35
+ reimagineEnabled: false,
36
+ },
37
+ providers: {
38
+ anthropic: { type: "native" },
39
+ },
40
+ watchdog: {
41
+ tier0Enabled: false,
42
+ tier0IntervalMs: 30000,
43
+ tier1Enabled: false,
44
+ tier2Enabled: false,
45
+ staleThresholdMs: 300000,
46
+ zombieThresholdMs: 600000,
47
+ nudgeIntervalMs: 60000,
48
+ },
49
+ models: {},
50
+ logging: {
51
+ verbose: false,
52
+ redactSecrets: true,
53
+ },
54
+ };
55
+
56
+ describe("checkDependencies", () => {
57
+ test("returns checks for all required tools", async () => {
58
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
59
+
60
+ expect(checks).toBeArray();
61
+ expect(checks.length).toBeGreaterThanOrEqual(7);
62
+
63
+ // Verify we have checks for each required tool
64
+ const toolNames = checks.map((c) => c.name);
65
+ expect(toolNames).toContain("git availability");
66
+ expect(toolNames).toContain("bun availability");
67
+ expect(toolNames).toContain("tmux availability");
68
+ expect(toolNames).toContain("sr availability");
69
+ expect(toolNames).toContain("loam availability");
70
+ expect(toolNames).toContain("ap availability");
71
+ expect(toolNames).toContain("tl availability");
72
+ });
73
+
74
+ test("includes bd CGO support check when bd is available", async () => {
75
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
76
+
77
+ const bdCheck = checks.find((c) => c.name === "bd availability");
78
+ if (bdCheck?.status === "pass") {
79
+ const cgoCheck = checks.find((c) => c.name === "bd CGO support");
80
+ expect(cgoCheck).toBeDefined();
81
+ expect(cgoCheck?.category).toBe("dependencies");
82
+ expect(["pass", "warn", "fail"]).toContain(cgoCheck?.status ?? "");
83
+ }
84
+ });
85
+
86
+ test("all checks have required DoctorCheck fields", async () => {
87
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
88
+
89
+ for (const check of checks) {
90
+ expect(check).toHaveProperty("name");
91
+ expect(check).toHaveProperty("category");
92
+ expect(check).toHaveProperty("status");
93
+ expect(check).toHaveProperty("message");
94
+
95
+ expect(check.category).toBe("dependencies");
96
+ expect(["pass", "warn", "fail"]).toContain(check.status);
97
+ expect(typeof check.name).toBe("string");
98
+ expect(typeof check.message).toBe("string");
99
+
100
+ if (check.details !== undefined) {
101
+ expect(check.details).toBeArray();
102
+ }
103
+
104
+ if (check.fixable !== undefined) {
105
+ expect(typeof check.fixable).toBe("boolean");
106
+ }
107
+ }
108
+ });
109
+
110
+ test("checks for commonly available tools should pass", async () => {
111
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
112
+
113
+ // git and bun should definitely be available in this environment
114
+ const gitCheck = checks.find((c) => c.name === "git availability");
115
+ const bunCheck = checks.find((c) => c.name === "bun availability");
116
+
117
+ expect(gitCheck).toBeDefined();
118
+ expect(bunCheck).toBeDefined();
119
+
120
+ // These should pass in a normal development environment
121
+ expect(gitCheck?.status).toBe("pass");
122
+ expect(bunCheck?.status).toBe("pass");
123
+
124
+ // Passing checks should include version info
125
+ if (gitCheck?.status === "pass") {
126
+ expect(gitCheck.details).toBeArray();
127
+ expect(gitCheck.details?.length).toBeGreaterThan(0);
128
+ }
129
+ });
130
+
131
+ test("checks include version details for available tools", async () => {
132
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
133
+
134
+ const passingChecks = checks.filter((c) => c.status === "pass");
135
+
136
+ for (const check of passingChecks) {
137
+ expect(check.details).toBeDefined();
138
+ expect(check.details).toBeArray();
139
+ expect(check.details?.length).toBeGreaterThan(0);
140
+
141
+ // Version string should not be empty
142
+ const version = check.details?.[0];
143
+ expect(version).toBeDefined();
144
+ expect(typeof version).toBe("string");
145
+ expect(version?.length).toBeGreaterThan(0);
146
+ }
147
+ });
148
+
149
+ test("failing checks are marked as fixable", async () => {
150
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
151
+
152
+ const failingChecks = checks.filter((c) => c.status === "fail" || c.status === "warn");
153
+
154
+ // If there are any failing checks, they should be marked fixable
155
+ for (const check of failingChecks) {
156
+ expect(check.fixable).toBe(true);
157
+ }
158
+ });
159
+
160
+ test("checks for sr when backend is sprout", async () => {
161
+ const sproutConfig: typeof mockConfig = {
162
+ ...mockConfig,
163
+ taskTracker: { backend: "sprout", enabled: true },
164
+ };
165
+ const checks = await checkDependencies(sproutConfig, "/tmp/.agentplate");
166
+ const toolNames = checks.map((c) => c.name);
167
+ expect(toolNames).toContain("sr availability");
168
+ expect(toolNames).not.toContain("bd availability");
169
+ });
170
+
171
+ test("checks for sr when backend is auto (sprout is default)", async () => {
172
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
173
+ const toolNames = checks.map((c) => c.name);
174
+ expect(toolNames).toContain("sr availability");
175
+ expect(toolNames).not.toContain("bd availability");
176
+ });
177
+
178
+ test("skips bd CGO check when backend is sprout", async () => {
179
+ const sproutConfig: typeof mockConfig = {
180
+ ...mockConfig,
181
+ taskTracker: { backend: "sprout", enabled: true },
182
+ };
183
+ const checks = await checkDependencies(sproutConfig, "/tmp/.agentplate");
184
+ const cgoCheck = checks.find((c) => c.name === "bd CGO support");
185
+ expect(cgoCheck).toBeUndefined();
186
+ });
187
+
188
+ test("tl check is warn (not fail) when missing", async () => {
189
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
190
+ const cnCheck = checks.find((c) => c.name === "tl availability");
191
+ expect(cnCheck).toBeDefined();
192
+ // tl is optional — should never be "fail", only "pass" or "warn"
193
+ expect(cnCheck?.status).not.toBe("fail");
194
+ });
195
+
196
+ test("checks short aliases for available tools", async () => {
197
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
198
+ const loamCheck = checks.find((c) => c.name === "loam availability");
199
+ if (loamCheck?.status === "pass") {
200
+ const mlAlias = checks.find((c) => c.name === "lm alias");
201
+ expect(mlAlias).toBeDefined();
202
+ expect(mlAlias?.category).toBe("dependencies");
203
+ expect(["pass", "warn"]).toContain(mlAlias?.status ?? "");
204
+ }
205
+ const ovCheck = checks.find((c) => c.name === "ap availability");
206
+ if (ovCheck?.status === "pass") {
207
+ const ovAlias = checks.find((c) => c.name === "agentplate alias");
208
+ expect(ovAlias).toBeDefined();
209
+ expect(["pass", "warn"]).toContain(ovAlias?.status ?? "");
210
+ }
211
+ });
212
+
213
+ test("alias checks are only run when primary tool passes", async () => {
214
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
215
+ // If loam failed, lm alias should NOT be present
216
+ const loamCheck = checks.find((c) => c.name === "loam availability");
217
+ const mlAlias = checks.find((c) => c.name === "lm alias");
218
+ if (loamCheck?.status !== "pass") {
219
+ expect(mlAlias).toBeUndefined();
220
+ }
221
+ });
222
+
223
+ test("install hints appear in details for missing tools", async () => {
224
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
225
+ // Check any failing/warning check with an installHint has npm install guidance
226
+ const cnCheck = checks.find((c) => c.name === "tl availability");
227
+ if (cnCheck?.status === "warn" || cnCheck?.status === "fail") {
228
+ const hasInstallHint = cnCheck.details?.some((d) => d.includes("npm install -g"));
229
+ expect(hasInstallHint).toBe(true);
230
+ }
231
+ });
232
+
233
+ test("includes ap availability check", async () => {
234
+ const checks = await checkDependencies(mockConfig, "/tmp/.agentplate");
235
+ const ovCheck = checks.find((c) => c.name === "ap availability");
236
+ expect(ovCheck).toBeDefined();
237
+ expect(ovCheck?.category).toBe("dependencies");
238
+ });
239
+ });
240
+
241
+ describe("checkTool", () => {
242
+ test("git with --version passes", async () => {
243
+ const check = await checkTool("git", "--version", true);
244
+ expect(check.name).toBe("git availability");
245
+ expect(check.category).toBe("dependencies");
246
+ expect(check.status).toBe("pass");
247
+ expect(check.message).toContain("git");
248
+ expect(check.details).toBeArray();
249
+ expect(check.details?.length).toBeGreaterThan(0);
250
+ });
251
+
252
+ test("nonexistent tool with required: true returns fail", async () => {
253
+ const check = await checkTool("nonexistent-tool-xyz-999", "--version", true);
254
+ expect(check.status).toBe("fail");
255
+ expect(check.message).toContain("nonexistent-tool-xyz-999");
256
+ expect(check.fixable).toBe(true);
257
+ });
258
+
259
+ test("nonexistent tool with required: false returns warn", async () => {
260
+ const check = await checkTool("nonexistent-tool-xyz-999", "--version", false);
261
+ expect(check.status).toBe("warn");
262
+ expect(check.fixable).toBe(true);
263
+ });
264
+
265
+ test("installHint appears in details for missing tool", async () => {
266
+ const check = await checkTool("nonexistent-tool-xyz-999", "--version", true, "@test/fake-pkg");
267
+ expect(check.status).toBe("fail");
268
+ const detailsText = check.details?.join(" ") ?? "";
269
+ expect(detailsText).toContain("npm install -g @test/fake-pkg");
270
+ });
271
+ });
272
+
273
+ describe("checkAlias", () => {
274
+ test("real tool alias passes", async () => {
275
+ // git is universally available — use it as a "real alias"
276
+ const check = await checkAlias("git-tool", "git");
277
+ expect(check.name).toBe("git alias");
278
+ expect(check.category).toBe("dependencies");
279
+ expect(check.status).toBe("pass");
280
+ expect(check.message).toContain("git");
281
+ });
282
+
283
+ test("nonexistent alias returns warn", async () => {
284
+ const check = await checkAlias("some-tool", "nonexistent-alias-xyz-999");
285
+ expect(check.status).toBe("warn");
286
+ expect(check.name).toBe("nonexistent-alias-xyz-999 alias");
287
+ expect(check.fixable).toBe(true);
288
+ });
289
+
290
+ test("nonexistent alias with installHint includes hint in details", async () => {
291
+ const check = await checkAlias("some-tool", "nonexistent-alias-xyz-999", "@test/fake-pkg");
292
+ expect(check.status).toBe("warn");
293
+ const detailsText = check.details?.join(" ") ?? "";
294
+ expect(detailsText).toContain("@test/fake-pkg");
295
+ });
296
+ });