@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
package/src/types.ts ADDED
@@ -0,0 +1,970 @@
1
+ // === Model & Provider Types ===
2
+
3
+ /** Backward-compatible model alias for Anthropic models. */
4
+ export type ModelAlias = "sonnet" | "opus" | "haiku";
5
+
6
+ /**
7
+ * A model reference: either a simple alias ('sonnet') or a provider-qualified
8
+ * string ('provider/model', e.g. 'openrouter/openai/gpt-5.3').
9
+ */
10
+ export type ModelRef = ModelAlias | (string & {});
11
+
12
+ /** Configuration for a model provider. */
13
+ export interface ProviderConfig {
14
+ type: "native" | "gateway";
15
+ baseUrl?: string;
16
+ authTokenEnv?: string;
17
+ }
18
+
19
+ /** Resolved model with optional provider environment variables. */
20
+ export interface ResolvedModel {
21
+ model: string;
22
+ env?: Record<string, string>;
23
+ /** True when the model was explicitly set via config.models[capability]. */
24
+ isExplicitOverride?: boolean;
25
+ }
26
+
27
+ /** Configuration for the Pi runtime's model alias expansion. */
28
+ export interface PiRuntimeConfig {
29
+ /** Provider prefix for unqualified model aliases (e.g., "anthropic", "amazon-bedrock"). */
30
+ provider: string;
31
+ /** Maps short aliases (e.g., "opus") to provider-qualified model IDs. */
32
+ modelMap: Record<string, string>;
33
+ }
34
+
35
+ // === Task Tracker ===
36
+
37
+ /** Backend for the task tracker. Defined here for use in AgentplateConfig. */
38
+ export type TaskTrackerBackend = "auto" | "sprout" | "beads";
39
+
40
+ // === Project Configuration ===
41
+
42
+ /**
43
+ * Conditions that trigger automatic coordinator shutdown.
44
+ * All triggers default to false for backward compatibility.
45
+ */
46
+ export interface CoordinatorExitTriggers {
47
+ /** Exit when all spawned agents have completed and their branches have been merged. */
48
+ allAgentsDone: boolean;
49
+ /** Exit when the task tracker reports no unblocked work (sr/bd ready returns empty). */
50
+ taskTrackerEmpty: boolean;
51
+ /** Exit when a typed shutdown mail is received from an external caller (e.g., greenhouse). */
52
+ onShutdownSignal: boolean;
53
+ }
54
+
55
+ /** A single quality gate command that agents must pass before reporting completion. */
56
+ export interface QualityGate {
57
+ /** Display name shown in the overlay (e.g., "Tests"). */
58
+ name: string;
59
+ /** Shell command to run (e.g., "bun test"). */
60
+ command: string;
61
+ /** Human-readable description of what passing means (e.g., "all tests must pass"). */
62
+ description: string;
63
+ }
64
+
65
+ export interface AgentplateConfig {
66
+ project: {
67
+ name: string;
68
+ root: string; // Absolute path to target repo
69
+ canonicalBranch: string; // "main" | "develop"
70
+ qualityGates?: QualityGate[];
71
+ /** Default trellis profile name. Used when --profile is not explicitly passed to sling/coordinator. */
72
+ defaultProfile?: string;
73
+ };
74
+ agents: {
75
+ manifestPath: string; // Path to agent-manifest.json
76
+ baseDir: string; // Path to base agent definitions
77
+ maxConcurrent: number; // Rate limit ceiling
78
+ staggerDelayMs: number; // Delay between spawns
79
+ maxDepth: number; // Hierarchy depth limit (default 2)
80
+ maxSessionsPerRun: number; // Max total sessions per run (0 = unlimited)
81
+ maxAgentsPerLead: number; // Max children a single lead can spawn (0 = unlimited)
82
+ };
83
+ worktrees: {
84
+ baseDir: string; // Where worktrees live
85
+ };
86
+ taskTracker: {
87
+ backend: TaskTrackerBackend; // "auto" | "sprout" | "beads"
88
+ enabled: boolean;
89
+ };
90
+ loam: {
91
+ enabled: boolean;
92
+ domains: string[]; // Domains to prime (empty = auto-detect)
93
+ primeFormat: "markdown" | "xml" | "json";
94
+ };
95
+ merge: {
96
+ aiResolveEnabled: boolean;
97
+ reimagineEnabled: boolean;
98
+ };
99
+ providers: Record<string, ProviderConfig>;
100
+ watchdog: {
101
+ tier0Enabled: boolean; // Tier 0: Mechanical daemon (heartbeat, tmux/pid liveness)
102
+ tier0IntervalMs: number; // Default 30_000
103
+ tier1Enabled: boolean; // Tier 1: Triage agent (ephemeral AI analysis)
104
+ tier2Enabled: boolean; // Tier 2: Monitor agent (continuous patrol)
105
+ staleThresholdMs: number; // When to consider agent stale
106
+ zombieThresholdMs: number; // When to kill
107
+ nudgeIntervalMs: number; // Time between progressive nudge stages (default 60_000)
108
+ rpcTimeoutMs?: number; // Timeout for RPC getState() calls (default 5_000)
109
+ triageTimeoutMs?: number; // Timeout for Tier 1 AI triage calls (default 30_000)
110
+ maxEscalationLevel?: number; // Maximum escalation level before termination (default 3)
111
+ notifyParentOnDeath?: boolean; // Send synthetic worker_died mail to parent on watchdog termination (default true)
112
+ };
113
+ models: Partial<Record<string, ModelRef>>;
114
+ logging: {
115
+ verbose: boolean;
116
+ redactSecrets: boolean;
117
+ };
118
+ coordinator?: {
119
+ /** Conditions that trigger automatic coordinator shutdown. */
120
+ exitTriggers: CoordinatorExitTriggers;
121
+ };
122
+ runtime?: {
123
+ /** Default runtime adapter name (default: "claude"). */
124
+ default: string;
125
+ /**
126
+ * Per-capability runtime overrides. Maps capability names (e.g. "coordinator", "builder")
127
+ * to runtime adapter names. Lookup chain: explicit --runtime flag > capabilities[cap] > default > "claude".
128
+ */
129
+ capabilities?: Partial<Record<string, string>>;
130
+ /**
131
+ * Runtime adapter for headless one-shot AI calls (--print mode).
132
+ * Used by merge/resolver.ts and watchdog/triage.ts.
133
+ * Falls back to runtime.default when omitted.
134
+ */
135
+ printCommand?: string;
136
+ /** Pi runtime configuration for model alias expansion. */
137
+ pi?: PiRuntimeConfig;
138
+ /**
139
+ * Delay in milliseconds between creating a tmux session and polling
140
+ * for TUI readiness. Gives slow shells (oh-my-zsh, starship, etc.)
141
+ * time to finish initializing before the agent command starts.
142
+ * Default: 0 (no delay).
143
+ */
144
+ shellInitDelayMs?: number;
145
+ /**
146
+ * Project-level default for spawning Claude Code agents in headless mode
147
+ * (Bun.spawn + stream-json) instead of the tmux interactive runtime.
148
+ * Per-spawn `--headless` / `--no-headless` flags on `ap sling` override this.
149
+ * Default: false (tmux).
150
+ */
151
+ claudeHeadlessByDefault?: boolean;
152
+ };
153
+ }
154
+
155
+ // === Agent Manifest ===
156
+
157
+ export interface AgentManifest {
158
+ version: string;
159
+ agents: Record<string, AgentDefinition>;
160
+ capabilityIndex: Record<string, string[]>;
161
+ }
162
+
163
+ export interface AgentDefinition {
164
+ file: string; // Path to base agent definition (.md)
165
+ model: ModelRef;
166
+ tools: string[]; // Allowed tools
167
+ capabilities: string[]; // What this agent can do
168
+ canSpawn: boolean; // Can this agent spawn sub-workers?
169
+ constraints: string[]; // Machine-readable restrictions
170
+ }
171
+
172
+ /** All valid agent capability types. Used for compile-time validation. */
173
+ export const SUPPORTED_CAPABILITIES = [
174
+ "scout",
175
+ "builder",
176
+ "reviewer",
177
+ "lead",
178
+ "merger",
179
+ "orchestrator",
180
+ "coordinator",
181
+ "supervisor",
182
+ "monitor",
183
+ ] as const;
184
+
185
+ /** Union type derived from the capabilities constant. */
186
+ export type Capability = (typeof SUPPORTED_CAPABILITIES)[number];
187
+
188
+ // === Agent Session ===
189
+
190
+ /**
191
+ * Agent lifecycle states.
192
+ *
193
+ * `in_turn` and `between_turns` are spawn-per-turn-specific substates that
194
+ * split the legacy `working` state so the UI can distinguish a worker actively
195
+ * executing a turn from one idling between mail batches (agentplate-3087):
196
+ *
197
+ * - `in_turn`: the turn-runner has observed at least one parser event from
198
+ * a live claude subprocess. The agent is mid-execution.
199
+ * - `between_turns`: the turn-runner finished a turn without a terminal
200
+ * mail; the agent is alive (process gone, session pinned) and waiting
201
+ * for the next mail batch to spawn a fresh turn.
202
+ *
203
+ * `working` remains the active state for tmux/long-lived headless agents
204
+ * (coordinator, orchestrator, monitor, sapling) which have no per-turn
205
+ * boundary. Spawn-per-turn workers (builder/scout/reviewer/lead/merger
206
+ * under the headless default) transition through in_turn ↔ between_turns
207
+ * instead.
208
+ */
209
+ export type AgentState =
210
+ | "booting"
211
+ | "working"
212
+ | "in_turn"
213
+ | "between_turns"
214
+ | "completed"
215
+ | "stalled"
216
+ | "zombie";
217
+
218
+ /**
219
+ * Result of a guarded state transition attempt (`SessionStore.tryTransitionState`).
220
+ *
221
+ * Discriminated by `ok`. When `ok` is false, `reason` distinguishes:
222
+ * - `not_found`: no session exists for the given name.
223
+ * - `illegal_transition`: a session exists but the matrix forbids prev → attempted.
224
+ *
225
+ * `prev` is always the state observed by the SQL CAS. For `illegal_transition` it
226
+ * is the state that blocked the write (which may differ from what the caller read,
227
+ * if another writer landed first).
228
+ */
229
+ export type TransitionOutcome =
230
+ | { ok: true; prev: AgentState; next: AgentState }
231
+ | { ok: false; reason: "not_found"; attempted: AgentState }
232
+ | { ok: false; reason: "illegal_transition"; prev: AgentState; attempted: AgentState };
233
+
234
+ export interface AgentSession {
235
+ id: string; // Unique session ID
236
+ agentName: string; // Unique per-session name
237
+ capability: string; // Which agent definition
238
+ worktreePath: string;
239
+ branchName: string;
240
+ taskId: string; // Task being worked
241
+ tmuxSession: string; // Tmux session name
242
+ state: AgentState;
243
+ pid: number | null; // Claude Code PID
244
+ parentAgent: string | null; // Who spawned this agent (null = orchestrator)
245
+ depth: number; // 0 = direct from orchestrator
246
+ runId: string | null; // Groups sessions in the same orchestrator run
247
+ startedAt: string;
248
+ lastActivity: string;
249
+ escalationLevel: number; // Progressive nudge stage: 0=warn, 1=nudge, 2=escalate, 3=terminate
250
+ stalledSince: string | null; // ISO timestamp when agent first entered stalled state
251
+ transcriptPath: string | null; // Runtime-provided transcript JSONL path (decoupled from ~/.claude/)
252
+ promptVersion?: string | null; // Trellis prompt version used at sling time (e.g. "builder@17")
253
+ claudeSessionId?: string | null; // Runtime-provided session_id (Claude stream-json), eagerly pinned on first event
254
+ }
255
+
256
+ // === Agent Identity ===
257
+
258
+ export interface AgentIdentity {
259
+ name: string;
260
+ capability: string;
261
+ created: string;
262
+ sessionsCompleted: number;
263
+ expertiseDomains: string[];
264
+ recentTasks: Array<{
265
+ taskId: string;
266
+ summary: string;
267
+ completedAt: string;
268
+ }>;
269
+ }
270
+
271
+ // === Mail (Custom SQLite) ===
272
+
273
+ /** Semantic message types (original, human-readable). */
274
+ export type MailSemanticType = "status" | "question" | "result" | "error";
275
+
276
+ /** Protocol message types for structured agent coordination. */
277
+ export type MailProtocolType =
278
+ | "worker_done"
279
+ | "worker_died"
280
+ | "merge_ready"
281
+ | "merged"
282
+ | "merge_failed"
283
+ | "escalation"
284
+ | "health_check"
285
+ | "dispatch"
286
+ | "assign"
287
+ | "decision_gate";
288
+
289
+ /** All valid mail message types. */
290
+ export type MailMessageType = MailSemanticType | MailProtocolType;
291
+
292
+ /** All protocol type strings as a runtime array for CHECK constraint generation. */
293
+ export const MAIL_MESSAGE_TYPES: readonly MailMessageType[] = [
294
+ "status",
295
+ "question",
296
+ "result",
297
+ "error",
298
+ "worker_done",
299
+ "worker_died",
300
+ "merge_ready",
301
+ "merged",
302
+ "merge_failed",
303
+ "escalation",
304
+ "health_check",
305
+ "dispatch",
306
+ "assign",
307
+ "decision_gate",
308
+ ] as const;
309
+
310
+ export interface MailMessage {
311
+ id: string; // "msg-" + nanoid(12)
312
+ from: string; // Agent name
313
+ to: string; // Agent name or "orchestrator"
314
+ subject: string;
315
+ body: string;
316
+ priority: "low" | "normal" | "high" | "urgent";
317
+ type: MailMessageType;
318
+ threadId: string | null; // Conversation threading
319
+ payload: string | null; // JSON-encoded structured data for protocol messages
320
+ read: boolean;
321
+ createdAt: string; // ISO timestamp
322
+ }
323
+
324
+ // === Mail Protocol Payloads ===
325
+
326
+ /** Worker signals task completion to supervisor. */
327
+ export interface WorkerDonePayload {
328
+ taskId: string;
329
+ branch: string;
330
+ exitCode: number;
331
+ filesModified: string[];
332
+ }
333
+
334
+ /**
335
+ * Watchdog signals the parent that one of its children was terminated.
336
+ *
337
+ * Synthetic mail injected by the Tier 0 daemon when it transitions a worker
338
+ * to `zombie` (agentplate-c111). Without this, the parent — typically a lead
339
+ * waiting for `worker_done` from this child — would block indefinitely on
340
+ * mail that will never arrive. The parent reads this on its next mail-injector
341
+ * tick and decides whether to retry, escalate, or report up.
342
+ */
343
+ export interface WorkerDiedPayload {
344
+ agentName: string;
345
+ capability: string;
346
+ taskId: string;
347
+ /** Reason the watchdog or runner terminated the child (e.g. "Process terminated"). */
348
+ reason: string;
349
+ /** ISO timestamp of the child's last observed activity. */
350
+ lastActivity: string;
351
+ /**
352
+ * Source that detected the failure.
353
+ * - `tier0`/`tier1`: watchdog daemon detected a dead/stuck process out-of-band.
354
+ * - `runner`: the per-turn runner observed an in-band failure — either an
355
+ * abort/stall that forced SIGTERM/SIGKILL, or a clean exit without the
356
+ * capability's terminal mail (silent-no-op, agentplate-4159 / agentplate-c772).
357
+ */
358
+ terminatedBy: "tier0" | "tier1" | "runner";
359
+ }
360
+
361
+ /** Supervisor signals branch is verified and ready for merge. */
362
+ export interface MergeReadyPayload {
363
+ branch: string;
364
+ taskId: string;
365
+ agentName: string;
366
+ filesModified: string[];
367
+ }
368
+
369
+ /** Merger signals branch was merged successfully. */
370
+ export interface MergedPayload {
371
+ branch: string;
372
+ taskId: string;
373
+ tier: ResolutionTier;
374
+ }
375
+
376
+ /** Merger signals merge failed, needs rework. */
377
+ export interface MergeFailedPayload {
378
+ branch: string;
379
+ taskId: string;
380
+ conflictFiles: string[];
381
+ errorMessage: string;
382
+ }
383
+
384
+ /** Any agent escalates an issue to a higher-level decision-maker. */
385
+ export interface EscalationPayload {
386
+ severity: "warning" | "error" | "critical";
387
+ taskId: string | null;
388
+ context: string;
389
+ }
390
+
391
+ /** Watchdog probes agent liveness. */
392
+ export interface HealthCheckPayload {
393
+ agentName: string;
394
+ checkType: "liveness" | "readiness";
395
+ }
396
+
397
+ /** Coordinator dispatches work to a supervisor. */
398
+ export interface DispatchPayload {
399
+ taskId: string;
400
+ specPath: string;
401
+ capability: Capability;
402
+ fileScope: string[];
403
+ /** Optional: skip scout phase for lead agents */
404
+ skipScouts?: boolean;
405
+ /** Optional: skip review phase for lead agents */
406
+ skipReview?: boolean;
407
+ /** Optional: per-lead max agent ceiling override */
408
+ maxAgents?: number;
409
+ }
410
+
411
+ /** Supervisor assigns work to a specific worker. */
412
+ export interface AssignPayload {
413
+ taskId: string;
414
+ specPath: string;
415
+ workerName: string;
416
+ branch: string;
417
+ }
418
+
419
+ /** Agent pauses for a human-in-the-loop decision before proceeding. */
420
+ export interface DecisionGatePayload {
421
+ /** Options for the human decision-maker to choose from. */
422
+ options: string[];
423
+ /** Context explaining why the decision is needed. */
424
+ context: string;
425
+ /** Optional deadline for the decision (ISO timestamp). */
426
+ deadline?: string;
427
+ }
428
+
429
+ /** Maps protocol message types to their payload interfaces. */
430
+ export interface MailPayloadMap {
431
+ worker_done: WorkerDonePayload;
432
+ worker_died: WorkerDiedPayload;
433
+ merge_ready: MergeReadyPayload;
434
+ merged: MergedPayload;
435
+ merge_failed: MergeFailedPayload;
436
+ escalation: EscalationPayload;
437
+ health_check: HealthCheckPayload;
438
+ dispatch: DispatchPayload;
439
+ assign: AssignPayload;
440
+ decision_gate: DecisionGatePayload;
441
+ }
442
+
443
+ // === Overlay ===
444
+
445
+ export interface OverlayConfig {
446
+ agentName: string;
447
+ taskId: string;
448
+ specPath: string | null;
449
+ branchName: string;
450
+ worktreePath: string;
451
+ fileScope: string[];
452
+ loamDomains: string[];
453
+ parentAgent: string | null;
454
+ depth: number;
455
+ canSpawn: boolean;
456
+ capability: string;
457
+ /** Full content of the base agent definition file (Layer 1: role-specific HOW). */
458
+ baseDefinition: string;
459
+ /** Rendered profile content from trellis (Layer 2: deployment-specific WHAT KIND). Inserted between base definition and assignment. */
460
+ profileContent?: string;
461
+ /** Pre-fetched loam expertise output to embed directly in the overlay. */
462
+ loamExpertise?: string;
463
+ /** When true, lead agents should skip Phase 1 (scout) and go straight to Phase 2 (build). */
464
+ skipScout?: boolean;
465
+ /** When true, lead agents should skip Phase 3 review and self-verify instead. */
466
+ skipReview?: boolean;
467
+ /** Per-lead max agents ceiling override from dispatch. Injected into overlay for lead visibility. */
468
+ maxAgentsOverride?: number;
469
+ trackerCli?: string; // "sr" or "bd"
470
+ trackerName?: string; // "sprout" or "beads"
471
+ /** Quality gate commands for the agent overlay. Falls back to defaults if undefined. */
472
+ qualityGates?: QualityGate[];
473
+ /** Relative path to the instruction file within the worktree (runtime-specific). Defaults to .claude/CLAUDE.md. */
474
+ instructionPath?: string;
475
+ /**
476
+ * Names of sibling agents dispatched in parallel that may share file scope
477
+ * with this agent. When set, the overlay renders a "Parallel Siblings"
478
+ * section with rebase-before-merge_ready guidance (agentplate-f76a). Empty
479
+ * or unset → no overlay section.
480
+ */
481
+ siblings?: string[];
482
+ }
483
+
484
+ // === Merge Queue ===
485
+
486
+ export type ResolutionTier = "clean-merge" | "auto-resolve" | "ai-resolve" | "reimagine";
487
+
488
+ export interface MergeEntry {
489
+ branchName: string;
490
+ taskId: string;
491
+ agentName: string;
492
+ filesModified: string[];
493
+ enqueuedAt: string;
494
+ status: "pending" | "merging" | "merged" | "conflict" | "failed";
495
+ resolvedTier: ResolutionTier | null;
496
+ }
497
+
498
+ export interface MergeResult {
499
+ entry: MergeEntry;
500
+ success: boolean;
501
+ tier: ResolutionTier;
502
+ conflictFiles: string[];
503
+ errorMessage: string | null;
504
+ /** Warnings about files where auto-resolve was skipped to prevent content loss. */
505
+ warnings: string[];
506
+ }
507
+
508
+ /** Parsed conflict pattern from a single loam record. */
509
+ export interface ParsedConflictPattern {
510
+ tier: ResolutionTier;
511
+ success: boolean;
512
+ files: string[];
513
+ agent: string;
514
+ branch: string;
515
+ }
516
+
517
+ /** Historical conflict data assembled from loam search results. */
518
+ export interface ConflictHistory {
519
+ /** Tiers to skip based on historical failure rates for these files. */
520
+ skipTiers: ResolutionTier[];
521
+ /** Descriptions of past successful resolutions for AI prompt enrichment. */
522
+ pastResolutions: string[];
523
+ /** Files predicted to conflict based on historical patterns. */
524
+ predictedConflictFiles: string[];
525
+ }
526
+
527
+ /**
528
+ * Side-effect-free prediction of how `ap merge` would resolve a branch.
529
+ * Produced by `predictConflicts` (src/merge/predict.ts) without touching HEAD,
530
+ * the working tree, or the merge lock — surfaced via `ap merge --dry-run` so a
531
+ * lead/operator/greenhouse can branch on `wouldRequireAgent`.
532
+ */
533
+ export interface ConflictPrediction {
534
+ /** The tier `ap merge` would land in if invoked now. */
535
+ predictedTier: ResolutionTier;
536
+ /** Files that would conflict — empty for clean-merge. */
537
+ conflictFiles: string[];
538
+ /** True iff predictedTier is "ai-resolve" or "reimagine" (Tier 3+). */
539
+ wouldRequireAgent: boolean;
540
+ /** Short, operator-readable explanation for the predicted tier. */
541
+ reason: string;
542
+ }
543
+
544
+ // === Watchdog ===
545
+
546
+ export interface HealthCheck {
547
+ agentName: string;
548
+ timestamp: string;
549
+ processAlive: boolean;
550
+ tmuxAlive: boolean;
551
+ pidAlive: boolean | null; // null when pid is unavailable
552
+ lastActivity: string;
553
+ state: AgentState;
554
+ action: "none" | "escalate" | "terminate" | "investigate" | "complete";
555
+ /** Describes any conflict between observable state and recorded state. */
556
+ reconciliationNote: string | null;
557
+ }
558
+
559
+ // === Logging ===
560
+
561
+ export interface LogEvent {
562
+ timestamp: string;
563
+ level: "debug" | "info" | "warn" | "error";
564
+ event: string;
565
+ agentName: string | null;
566
+ data: Record<string, unknown>;
567
+ }
568
+
569
+ // === Metrics ===
570
+
571
+ export interface SessionMetrics {
572
+ agentName: string;
573
+ taskId: string;
574
+ capability: string;
575
+ startedAt: string;
576
+ completedAt: string | null;
577
+ durationMs: number;
578
+ exitCode: number | null;
579
+ mergeResult: ResolutionTier | null;
580
+ parentAgent: string | null;
581
+ inputTokens: number;
582
+ outputTokens: number;
583
+ cacheReadTokens: number;
584
+ cacheCreationTokens: number;
585
+ estimatedCostUsd: number | null;
586
+ modelUsed: string | null;
587
+ runId: string | null;
588
+ }
589
+
590
+ /** A point-in-time token usage snapshot for a running agent session. */
591
+ export interface TokenSnapshot {
592
+ agentName: string;
593
+ inputTokens: number;
594
+ outputTokens: number;
595
+ cacheReadTokens: number;
596
+ cacheCreationTokens: number;
597
+ estimatedCostUsd: number | null;
598
+ modelUsed: string | null;
599
+ createdAt: string;
600
+ runId: string | null;
601
+ }
602
+
603
+ // === Task Groups (Batch Coordination) ===
604
+
605
+ export interface TaskGroup {
606
+ id: string; // "group-" + nanoid(8)
607
+ name: string;
608
+ memberIssueIds: string[]; // beads issue IDs tracked by this group
609
+ status: "active" | "completed";
610
+ createdAt: string; // ISO timestamp
611
+ completedAt: string | null; // ISO timestamp when all members closed
612
+ }
613
+
614
+ export interface TaskGroupProgress {
615
+ group: TaskGroup;
616
+ total: number;
617
+ completed: number;
618
+ inProgress: number;
619
+ blocked: number;
620
+ open: number;
621
+ }
622
+
623
+ // === Event Store (Observability) ===
624
+
625
+ /** Event types for agent activity tracking. */
626
+ export type EventType =
627
+ | "tool_start"
628
+ | "tool_end"
629
+ | "session_start"
630
+ | "session_end"
631
+ | "mail_sent"
632
+ | "mail_received"
633
+ | "spawn"
634
+ | "error"
635
+ | "custom"
636
+ | "turn_start"
637
+ | "turn_end"
638
+ | "progress"
639
+ | "result";
640
+
641
+ /** Severity levels for events. */
642
+ export type EventLevel = "debug" | "info" | "warn" | "error";
643
+
644
+ /** All valid event level strings as a runtime array for CHECK constraint generation. */
645
+ export const EVENT_LEVELS: readonly EventLevel[] = ["debug", "info", "warn", "error"] as const;
646
+
647
+ /** An event as stored in the SQLite events table. */
648
+ export interface StoredEvent {
649
+ id: number;
650
+ runId: string | null;
651
+ agentName: string;
652
+ sessionId: string | null;
653
+ eventType: EventType;
654
+ toolName: string | null;
655
+ toolArgs: string | null;
656
+ toolDurationMs: number | null;
657
+ level: EventLevel;
658
+ data: string | null;
659
+ createdAt: string;
660
+ }
661
+
662
+ /** Input for inserting a new event (id and createdAt are auto-generated). */
663
+ export type InsertEvent = Omit<StoredEvent, "id" | "createdAt">;
664
+
665
+ /** Options for filtering event queries. */
666
+ export interface EventQueryOptions {
667
+ limit?: number;
668
+ since?: string; // ISO timestamp
669
+ until?: string; // ISO timestamp
670
+ level?: EventLevel;
671
+ }
672
+
673
+ /** Tool usage statistics returned by getToolStats. */
674
+ export interface ToolStats {
675
+ toolName: string;
676
+ count: number;
677
+ avgDurationMs: number;
678
+ maxDurationMs: number;
679
+ }
680
+
681
+ /** Interface for the SQLite-backed event store. */
682
+ export interface EventStore {
683
+ /** Insert a new event. Returns the auto-generated row ID. */
684
+ insert(event: InsertEvent): number;
685
+ /** Find the most recent unmatched tool_start for correlation. Returns start ID and duration. */
686
+ correlateToolEnd(
687
+ agentName: string,
688
+ toolName: string,
689
+ ): { startId: number; durationMs: number } | null;
690
+ /** Get events for a specific agent. */
691
+ getByAgent(agentName: string, opts?: EventQueryOptions): StoredEvent[];
692
+ /** Get events for a specific run. */
693
+ getByRun(runId: string, opts?: EventQueryOptions): StoredEvent[];
694
+ /** Get error-level events. */
695
+ getErrors(opts?: EventQueryOptions): StoredEvent[];
696
+ /** Get a timeline of events with required options. */
697
+ getTimeline(opts: EventQueryOptions & { since: string }): StoredEvent[];
698
+ /** Get aggregated tool usage statistics. */
699
+ getToolStats(opts?: { agentName?: string; since?: string }): ToolStats[];
700
+ /** Delete events matching criteria. Returns number of rows deleted. */
701
+ purge(opts: { all?: boolean; olderThanMs?: number; agentName?: string }): number;
702
+ /** Close the database connection. */
703
+ close(): void;
704
+ }
705
+
706
+ // === Run (Coordinator Session Grouping) ===
707
+
708
+ /** Status of a run (coordinator session grouping agents). */
709
+ export type RunStatus = "active" | "completed" | "failed";
710
+
711
+ /** A run groups all agents spawned from one coordinator session. */
712
+ export interface Run {
713
+ id: string; // Format: run-{ISO timestamp}
714
+ startedAt: string;
715
+ completedAt: string | null;
716
+ agentCount: number;
717
+ coordinatorSessionId: string | null;
718
+ coordinatorName: string | null; // which coordinator owns this run
719
+ status: RunStatus;
720
+ }
721
+
722
+ /** Input for creating a new run. */
723
+ export type InsertRun = Omit<Run, "completedAt" | "agentCount" | "coordinatorName"> & {
724
+ agentCount?: number;
725
+ /** Which coordinator owns this run. Defaults to null when not provided. */
726
+ coordinatorName?: string | null;
727
+ };
728
+
729
+ /** Interface for run management operations. */
730
+ export interface RunStore {
731
+ /** Create a new run. */
732
+ createRun(run: InsertRun): void;
733
+ /** Get a run by ID, or null if not found. */
734
+ getRun(id: string): Run | null;
735
+ /** Get the most recently started active run. */
736
+ getActiveRun(): Run | null;
737
+ /** Get the most recently started active run for a specific coordinator. */
738
+ getActiveRunForCoordinator(coordinatorName: string): Run | null;
739
+ /** List runs, optionally limited. */
740
+ listRuns(opts?: { limit?: number; status?: RunStatus }): Run[];
741
+ /** Increment agent count for a run. */
742
+ incrementAgentCount(runId: string): void;
743
+ /** Complete a run (set status and completedAt). */
744
+ completeRun(runId: string, status: "completed" | "failed"): void;
745
+ /** Close the store (if standalone — in practice may share DB with SessionStore). */
746
+ close(): void;
747
+ }
748
+
749
+ // === Loam CLI Results ===
750
+
751
+ /** Loam status result (domain statistics). */
752
+ export interface LoamStatus {
753
+ domains: Array<{ name: string; recordCount: number; lastUpdated: string }>;
754
+ }
755
+
756
+ /** Result from loam diff command. */
757
+ export interface LoamDiffResult {
758
+ success: boolean;
759
+ command: string;
760
+ since: string;
761
+ domains: string[];
762
+ message: string;
763
+ }
764
+
765
+ /** Result from loam learn command. */
766
+ export interface LoamLearnResult {
767
+ success: boolean;
768
+ command: string;
769
+ changedFiles: string[];
770
+ suggestedDomains: string[];
771
+ unmatchedFiles: string[];
772
+ }
773
+
774
+ /** Result from loam prune command. */
775
+ export interface LoamPruneResult {
776
+ success: boolean;
777
+ command: string;
778
+ dryRun: boolean;
779
+ totalPruned: number;
780
+ results: Array<{
781
+ domain: string;
782
+ pruned: number;
783
+ records: string[];
784
+ }>;
785
+ }
786
+
787
+ /** Health check result from loam doctor. */
788
+ export interface LoamDoctorResult {
789
+ success: boolean;
790
+ command: string;
791
+ checks: Array<{
792
+ name: string;
793
+ status: "pass" | "warn" | "fail";
794
+ message: string;
795
+ fixable: boolean;
796
+ details: string[];
797
+ }>;
798
+ summary: {
799
+ pass: number;
800
+ warn: number;
801
+ fail: number;
802
+ };
803
+ }
804
+
805
+ /** Ready records result from loam ready. */
806
+ export interface LoamReadyResult {
807
+ success: boolean;
808
+ command: string;
809
+ count: number;
810
+ entries: Array<{
811
+ domain: string;
812
+ id: string;
813
+ type: string;
814
+ recorded_at: string;
815
+ summary: string;
816
+ record: Record<string, unknown>;
817
+ }>;
818
+ }
819
+
820
+ /** Result from loam compact command. */
821
+ export interface LoamCompactResult {
822
+ success: boolean;
823
+ command: string;
824
+ action: string;
825
+ candidates?: Array<{
826
+ domain: string;
827
+ type: string;
828
+ records: Array<{
829
+ id: string;
830
+ summary: string;
831
+ recorded_at: string;
832
+ }>;
833
+ }>;
834
+ compacted?: Array<{
835
+ domain: string;
836
+ type: string;
837
+ before: number;
838
+ after: number;
839
+ recordIds: string[];
840
+ }>;
841
+ message?: string;
842
+ }
843
+
844
+ // === Trellis CLI Results ===
845
+
846
+ /** A single section within a rendered trellis prompt. */
847
+ export interface TrellisPromptSection {
848
+ name: string;
849
+ body: string;
850
+ }
851
+
852
+ /** Summary of a trellis prompt as returned by list/show. */
853
+ export interface TrellisPromptSummary {
854
+ id: string;
855
+ name: string;
856
+ version: number;
857
+ sections: TrellisPromptSection[];
858
+ }
859
+
860
+ /** Result from tl render — resolved prompt with all inheritance applied. */
861
+ export interface TrellisRenderResult {
862
+ success: boolean;
863
+ name: string;
864
+ version: number;
865
+ sections: TrellisPromptSection[];
866
+ }
867
+
868
+ /** Result from tl validate — validation status and errors. */
869
+ export interface TrellisValidateResult {
870
+ success: boolean;
871
+ errors: string[];
872
+ }
873
+
874
+ /** Result from tl list — list of all prompts. */
875
+ export interface TrellisListResult {
876
+ success: boolean;
877
+ prompts: TrellisPromptSummary[];
878
+ }
879
+
880
+ /** Result from tl show — single prompt record. */
881
+ export interface TrellisShowResult {
882
+ success: boolean;
883
+ prompt: TrellisPromptSummary;
884
+ }
885
+
886
+ // === Session Lifecycle (Checkpoint / Handoff / Continuity) ===
887
+
888
+ /**
889
+ * Snapshot of agent progress, saved before compaction or handoff.
890
+ * Stored as JSON in .agentplate/agents/{name}/checkpoint.json.
891
+ */
892
+ export interface SessionCheckpoint {
893
+ agentName: string;
894
+ taskId: string;
895
+ sessionId: string; // The AgentSession.id that created this checkpoint
896
+ timestamp: string; // ISO
897
+ progressSummary: string; // Human-readable summary of work done so far
898
+ filesModified: string[]; // Paths modified since session start
899
+ currentBranch: string;
900
+ pendingWork: string; // What remains to be done
901
+ loamDomains: string[]; // Domains the agent has been working in
902
+ }
903
+
904
+ /**
905
+ * Record of a session handoff — when one session ends and another picks up.
906
+ */
907
+ export interface SessionHandoff {
908
+ fromSessionId: string;
909
+ toSessionId: string | null; // null until the new session starts
910
+ checkpoint: SessionCheckpoint;
911
+ reason: "compaction" | "crash" | "manual" | "timeout";
912
+ handoffAt: string; // ISO timestamp
913
+ }
914
+
915
+ /**
916
+ * Three-layer model for agent persistence.
917
+ * Session = ephemeral Claude runtime
918
+ * Sandbox = git worktree (persists across sessions)
919
+ * Identity = permanent agent record (persists across assignments)
920
+ */
921
+ export interface AgentLayers {
922
+ identity: AgentIdentity;
923
+ sandbox: {
924
+ worktreePath: string;
925
+ branchName: string;
926
+ taskId: string;
927
+ };
928
+ session: {
929
+ id: string;
930
+ pid: number | null;
931
+ tmuxSession: string;
932
+ startedAt: string;
933
+ checkpoint: SessionCheckpoint | null;
934
+ } | null; // null when sandbox exists but no active session
935
+ }
936
+
937
+ // === Session Insight Analysis ===
938
+
939
+ /** A single structured insight extracted from a completed session. */
940
+ export interface SessionInsight {
941
+ /** Loam record type for this insight. */
942
+ type: "pattern" | "convention" | "failure";
943
+ /** Loam domain this insight belongs to. */
944
+ domain: string;
945
+ /** Human-readable description of the insight. */
946
+ description: string;
947
+ /** Tags for loam record categorization. */
948
+ tags: string[];
949
+ }
950
+
951
+ /** Aggregated tool usage profile for a session. */
952
+ export interface ToolProfile {
953
+ topTools: Array<{ name: string; count: number; avgMs: number }>;
954
+ totalToolCalls: number;
955
+ errorCount: number;
956
+ }
957
+
958
+ /** File edit frequency profile for a session. */
959
+ export interface FileProfile {
960
+ /** Files edited more than once, sorted by edit count descending. */
961
+ hotFiles: Array<{ path: string; editCount: number }>;
962
+ totalEdits: number;
963
+ }
964
+
965
+ /** Complete insight analysis result for a completed session. */
966
+ export interface InsightAnalysis {
967
+ insights: SessionInsight[];
968
+ toolProfile: ToolProfile;
969
+ fileProfile: FileProfile;
970
+ }