@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,257 @@
1
+ import type { Command } from "commander";
2
+ import { findSproutDir } from "../config.ts";
3
+ import { outputJson, printSuccess } from "../output.ts";
4
+ import { affectedPlanIds, applyPlanTransitions } from "../plan-lifecycle.ts";
5
+ import {
6
+ issuesPath,
7
+ plansPath,
8
+ readIssues,
9
+ readPlans,
10
+ withLock,
11
+ writeIssues,
12
+ writePlans,
13
+ } from "../store.ts";
14
+ import type { Issue } from "../types.ts";
15
+ import { VALID_STATUSES, VALID_TYPES } from "../types.ts";
16
+
17
+ function parseArgs(args: string[]) {
18
+ const flags: Record<string, string | boolean> = {};
19
+ let i = 0;
20
+ while (i < args.length) {
21
+ const arg = args[i];
22
+ if (!arg) {
23
+ i++;
24
+ continue;
25
+ }
26
+ if (arg.startsWith("--")) {
27
+ const key = arg.slice(2);
28
+ const eqIdx = key.indexOf("=");
29
+ if (eqIdx !== -1) {
30
+ flags[key.slice(0, eqIdx)] = key.slice(eqIdx + 1);
31
+ i++;
32
+ } else {
33
+ const next = args[i + 1];
34
+ if (next !== undefined && !next.startsWith("--")) {
35
+ flags[key] = next;
36
+ i += 2;
37
+ } else {
38
+ flags[key] = true;
39
+ i++;
40
+ }
41
+ }
42
+ } else {
43
+ i++;
44
+ }
45
+ }
46
+ return flags;
47
+ }
48
+
49
+ function parsePriority(val: string): number {
50
+ if (val.toUpperCase().startsWith("P")) return Number.parseInt(val.slice(1), 10);
51
+ return Number.parseInt(val, 10);
52
+ }
53
+
54
+ // Accept only a JSON object literal (not array, scalar, or null) — extensions
55
+ // is a Record<string, unknown> by contract. See plan pl-c195 risk #5.
56
+ function parseExtensionsPatch(raw: string): Record<string, unknown> {
57
+ let parsed: unknown;
58
+ try {
59
+ parsed = JSON.parse(raw);
60
+ } catch (e) {
61
+ const msg = e instanceof Error ? e.message : String(e);
62
+ throw new Error(`--extensions must be valid JSON: ${msg}`);
63
+ }
64
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
65
+ throw new Error("--extensions must be a JSON object (not array, null, or scalar)");
66
+ }
67
+ return parsed as Record<string, unknown>;
68
+ }
69
+
70
+ export async function run(args: string[], sproutDir?: string): Promise<void> {
71
+ const jsonMode = args.includes("--json");
72
+ const id = args.find((a) => !a.startsWith("--"));
73
+ if (!id) throw new Error("Usage: sr update <id> [flags]");
74
+
75
+ const flags = parseArgs(args);
76
+
77
+ const dir = sproutDir ?? (await findSproutDir());
78
+ let updated: Issue | undefined;
79
+
80
+ const statusChanging = typeof flags.status === "string";
81
+ const inner = async () => {
82
+ const issues = await readIssues(dir);
83
+ const idx = issues.findIndex((i) => i.id === id);
84
+ const issue = issues[idx];
85
+ if (!issue) throw new Error(`Issue not found: ${id}`);
86
+ const now = new Date().toISOString();
87
+ const patch: Partial<Issue> = { updatedAt: now };
88
+
89
+ if (typeof flags.status === "string") {
90
+ const s = flags.status;
91
+ if (!(VALID_STATUSES as readonly string[]).includes(s)) {
92
+ throw new Error(`--status must be one of: ${VALID_STATUSES.join(", ")}`);
93
+ }
94
+ patch.status = s as Issue["status"];
95
+ // Reopening (status moving away from "closed"): drop stale close metadata
96
+ // so `sr show` doesn't display a phantom closedAt/closeReason on an open
97
+ // issue. JSON.stringify omits keys with `undefined` values, so the spread
98
+ // `{...issue, ...patch}` followed by writeIssues clears them on disk.
99
+ if (patch.status !== "closed") {
100
+ patch.closedAt = undefined;
101
+ patch.closeReason = undefined;
102
+ }
103
+ }
104
+ if (typeof flags.title === "string") {
105
+ if (flags.title.trim() === "") {
106
+ throw new Error("--title must not be empty");
107
+ }
108
+ patch.title = flags.title;
109
+ }
110
+ if (typeof flags.assignee === "string") patch.assignee = flags.assignee;
111
+ const desc =
112
+ typeof flags.description === "string"
113
+ ? flags.description
114
+ : typeof flags.desc === "string"
115
+ ? flags.desc
116
+ : flags.body;
117
+ if (typeof desc === "string") patch.description = desc;
118
+ if (typeof flags.type === "string") {
119
+ const t = flags.type;
120
+ if (!(VALID_TYPES as readonly string[]).includes(t)) {
121
+ throw new Error(`--type must be one of: ${VALID_TYPES.join(", ")}`);
122
+ }
123
+ patch.type = t as Issue["type"];
124
+ }
125
+ if (typeof flags.priority === "string") {
126
+ const p = parsePriority(flags.priority);
127
+ if (Number.isNaN(p) || p < 0 || p > 4) throw new Error("--priority must be 0-4 or P0-P4");
128
+ patch.priority = p;
129
+ }
130
+
131
+ const extPatchProvided = typeof flags.extensions === "string";
132
+ const clearExt = flags["clear-extensions"] === true;
133
+ if (extPatchProvided && clearExt) {
134
+ throw new Error("--extensions and --clear-extensions are mutually exclusive");
135
+ }
136
+ if (clearExt) {
137
+ patch.extensions = undefined;
138
+ } else if (extPatchProvided) {
139
+ const incoming = parseExtensionsPatch(flags.extensions as string);
140
+ const merged: Record<string, unknown> = { ...(issue.extensions ?? {}), ...incoming };
141
+ patch.extensions = Object.keys(merged).length > 0 ? merged : undefined;
142
+ }
143
+
144
+ if (typeof flags["set-labels"] === "string") {
145
+ const val = flags["set-labels"];
146
+ if (val === "") {
147
+ patch.labels = undefined;
148
+ } else {
149
+ const parsed = val
150
+ .split(",")
151
+ .map((l) => l.trim().toLowerCase())
152
+ .filter(Boolean);
153
+ patch.labels = parsed.length > 0 ? parsed : undefined;
154
+ }
155
+ }
156
+ if (typeof flags["add-label"] === "string") {
157
+ const toAdd = flags["add-label"]
158
+ .split(",")
159
+ .map((l) => l.trim().toLowerCase())
160
+ .filter(Boolean);
161
+ const base = patch.labels ?? issue.labels ?? [];
162
+ const merged = Array.from(new Set([...base, ...toAdd]));
163
+ patch.labels = merged.length > 0 ? merged : undefined;
164
+ }
165
+ if (typeof flags["remove-label"] === "string") {
166
+ const toRemove = new Set(flags["remove-label"].split(",").map((l) => l.trim().toLowerCase()));
167
+ const base = patch.labels ?? issue.labels ?? [];
168
+ const remaining = base.filter((l) => !toRemove.has(l));
169
+ patch.labels = remaining.length > 0 ? remaining : undefined;
170
+ }
171
+
172
+ issues[idx] = { ...issue, ...patch };
173
+ updated = issues[idx];
174
+ await writeIssues(dir, issues);
175
+
176
+ // Plan lifecycle: if a child seed's status changed, recompute owning plan(s).
177
+ if (statusChanging && patch.status !== undefined && patch.status !== issue.status) {
178
+ const plans = await readPlans(dir);
179
+ const affected = affectedPlanIds(plans, [id]);
180
+ if (affected.length > 0) {
181
+ const changedCount = applyPlanTransitions(plans, issues, affected, now);
182
+ if (changedCount > 0) await writePlans(dir, plans);
183
+ }
184
+ }
185
+ };
186
+
187
+ if (statusChanging) {
188
+ // Lock order matches plan-submit: plans (outer) → issues (inner).
189
+ await withLock(plansPath(dir), () => withLock(issuesPath(dir), inner));
190
+ } else {
191
+ await withLock(issuesPath(dir), inner);
192
+ }
193
+
194
+ if (jsonMode) {
195
+ await outputJson({ success: true, command: "update", issue: updated });
196
+ } else {
197
+ printSuccess(`Updated ${id}`);
198
+ }
199
+ }
200
+
201
+ export function register(program: Command): void {
202
+ program
203
+ .command("update <id>")
204
+ .description("Update issue fields")
205
+ .option("--status <status>", "New status (open|in_progress|closed)")
206
+ .option("--title <text>", "New title")
207
+ .option("--assignee <name>", "New assignee")
208
+ .option("--description <text>", "New description")
209
+ .option("--desc <text>", "New description (alias for --description)")
210
+ .option("--body <text>", "New description (alias for --description)")
211
+ .option("--type <type>", "New type (task|bug|feature|epic)")
212
+ .option("--priority <n>", "New priority 0-4 or P0-P4")
213
+ .option("--add-label <labels>", "Add label(s) (comma-separated)")
214
+ .option("--remove-label <labels>", "Remove label(s) (comma-separated)")
215
+ .option("--set-labels <labels>", "Set labels (comma-separated, empty to clear)")
216
+ .option("--extensions <json>", "Shallow-merge JSON object into Issue.extensions")
217
+ .option("--clear-extensions", "Remove the extensions field")
218
+ .option("--json", "Output as JSON")
219
+ .action(
220
+ async (
221
+ id: string,
222
+ opts: {
223
+ status?: string;
224
+ title?: string;
225
+ assignee?: string;
226
+ description?: string;
227
+ desc?: string;
228
+ body?: string;
229
+ type?: string;
230
+ priority?: string;
231
+ addLabel?: string;
232
+ removeLabel?: string;
233
+ setLabels?: string;
234
+ extensions?: string;
235
+ clearExtensions?: boolean;
236
+ json?: boolean;
237
+ },
238
+ ) => {
239
+ const args: string[] = [id];
240
+ if (opts.status) args.push("--status", opts.status);
241
+ if (opts.title !== undefined) args.push("--title", opts.title);
242
+ if (opts.assignee) args.push("--assignee", opts.assignee);
243
+ if (opts.description) args.push("--description", opts.description);
244
+ if (opts.desc) args.push("--desc", opts.desc);
245
+ if (opts.body) args.push("--body", opts.body);
246
+ if (opts.type) args.push("--type", opts.type);
247
+ if (opts.priority) args.push("--priority", opts.priority);
248
+ if (opts.addLabel) args.push("--add-label", opts.addLabel);
249
+ if (opts.removeLabel) args.push("--remove-label", opts.removeLabel);
250
+ if (opts.setLabels !== undefined) args.push("--set-labels", opts.setLabels);
251
+ if (opts.extensions !== undefined) args.push("--extensions", opts.extensions);
252
+ if (opts.clearExtensions) args.push("--clear-extensions");
253
+ if (opts.json) args.push("--json");
254
+ await run(args);
255
+ },
256
+ );
257
+ }
@@ -0,0 +1,91 @@
1
+ import type { Command } from "commander";
2
+ import { brand, outputJson, printSuccess, printWarning } from "../output.ts";
3
+ import { VERSION } from "../version.ts";
4
+
5
+ const PACKAGE_NAME = "@ag-eco/sprout-cli";
6
+
7
+ async function fetchLatestVersion(): Promise<string> {
8
+ const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`);
9
+ if (!res.ok) throw new Error(`Failed to fetch npm registry: ${res.status} ${res.statusText}`);
10
+ const data = (await res.json()) as { version: string };
11
+ return data.version;
12
+ }
13
+
14
+ export async function run(args: string[]): Promise<void> {
15
+ const jsonMode = args.includes("--json");
16
+ const checkOnly = args.includes("--check");
17
+
18
+ const current = VERSION;
19
+ const latest = await fetchLatestVersion();
20
+ const upToDate = current === latest;
21
+
22
+ if (checkOnly) {
23
+ if (jsonMode) {
24
+ await outputJson({ success: true, command: "upgrade", current, latest, upToDate });
25
+ } else {
26
+ if (upToDate) {
27
+ printSuccess(`Already up to date (${current})`);
28
+ } else {
29
+ printWarning(`Update available: ${current} → ${latest}`);
30
+ process.exitCode = 1;
31
+ }
32
+ }
33
+ return;
34
+ }
35
+
36
+ if (upToDate) {
37
+ if (jsonMode) {
38
+ await outputJson({
39
+ success: true,
40
+ command: "upgrade",
41
+ current,
42
+ latest,
43
+ upToDate: true,
44
+ updated: false,
45
+ });
46
+ } else {
47
+ printSuccess(`Already up to date (${current})`);
48
+ }
49
+ return;
50
+ }
51
+
52
+ if (!jsonMode) {
53
+ console.log(`Upgrading ${brand(PACKAGE_NAME)} from ${current} to ${latest}...`);
54
+ }
55
+
56
+ const result = Bun.spawnSync(["bun", "install", "-g", `${PACKAGE_NAME}@latest`], {
57
+ stdout: "inherit",
58
+ stderr: "inherit",
59
+ });
60
+
61
+ if (result.exitCode !== 0) {
62
+ throw new Error(`bun install failed with exit code ${result.exitCode}`);
63
+ }
64
+
65
+ if (jsonMode) {
66
+ await outputJson({
67
+ success: true,
68
+ command: "upgrade",
69
+ current,
70
+ latest,
71
+ upToDate: false,
72
+ updated: true,
73
+ });
74
+ } else {
75
+ printSuccess(`Upgraded to ${latest}`);
76
+ }
77
+ }
78
+
79
+ export function register(program: Command): void {
80
+ program
81
+ .command("upgrade")
82
+ .description("Upgrade sprout to the latest version from npm")
83
+ .option("--check", "Check for updates without installing")
84
+ .option("--json", "Output as JSON")
85
+ .action(async (opts: { check?: boolean; json?: boolean }) => {
86
+ const args: string[] = [];
87
+ if (opts.check) args.push("--check");
88
+ if (opts.json) args.push("--json");
89
+ await run(args);
90
+ });
91
+ }
@@ -0,0 +1,152 @@
1
+ // JSON Schema for `.sprout/config.yaml`. Wire-format contract for warren V2's
2
+ // schema-driven config UI (warren ROADMAP R-10): warren reads this schema,
3
+ // renders a form, and writes back via `sr config set <path> <value>`. Locked
4
+ // with a golden test (config.test.ts) so any shape change is intentional.
5
+ //
6
+ // Mirrors the ground-truth shape produced by readConfig + loadPlanTemplates in
7
+ // src/config.ts. Built-in plan templates appear in `examples` so warren's UI
8
+ // can offer a "copy a built-in to start" affordance.
9
+
10
+ import {
11
+ BUILTIN_BUG_TEMPLATE,
12
+ BUILTIN_FEATURE_TEMPLATE,
13
+ BUILTIN_REFACTOR_TEMPLATE,
14
+ } from "./config.ts";
15
+ import { DEFAULT_MAX_PLAN_DEPTH, type PlanTemplate } from "./types.ts";
16
+
17
+ type JSONSchema = Record<string, unknown>;
18
+
19
+ function templateExample(t: PlanTemplate): Record<string, unknown> {
20
+ const out: Record<string, unknown> = { sections: t.sections };
21
+ if (t.description) out.description = t.description;
22
+ return out;
23
+ }
24
+
25
+ export function configSchema(): JSONSchema {
26
+ return {
27
+ $schema: "https://json-schema.org/draft/2020-12/schema",
28
+ $id: "https://github.com/jayminwest/sprout/config.schema.json",
29
+ title: "Sprout project config",
30
+ description:
31
+ "Schema for .sprout/config.yaml. Consumed by warren's schema-driven UI; emit via `sr config schema`.",
32
+ type: "object",
33
+ required: ["project", "version"],
34
+ additionalProperties: false,
35
+ properties: {
36
+ project: {
37
+ type: "string",
38
+ minLength: 1,
39
+ title: "Project name",
40
+ description: "Used as the prefix for issue IDs (e.g. `<project>-a1b2`).",
41
+ },
42
+ version: {
43
+ type: "string",
44
+ title: "Config schema version",
45
+ description: "Internal version tag for the config layout. Bumped when the schema breaks.",
46
+ default: "1",
47
+ },
48
+ max_plan_depth: {
49
+ type: "integer",
50
+ minimum: 1,
51
+ title: "Max plan depth",
52
+ description:
53
+ "Display-only depth limit for `sr plan show` recursion through nested sub-plans.",
54
+ default: DEFAULT_MAX_PLAN_DEPTH,
55
+ },
56
+ plan_templates: {
57
+ type: "object",
58
+ title: "Custom plan templates",
59
+ description:
60
+ "Map of template name → template definition. Overrides the built-in `feature`, `bug`, and `refactor` templates when names collide.",
61
+ additionalProperties: { $ref: "#/$defs/PlanTemplate" },
62
+ examples: [
63
+ {
64
+ feature: templateExample(BUILTIN_FEATURE_TEMPLATE),
65
+ bug: templateExample(BUILTIN_BUG_TEMPLATE),
66
+ refactor: templateExample(BUILTIN_REFACTOR_TEMPLATE),
67
+ },
68
+ ],
69
+ },
70
+ },
71
+ $defs: {
72
+ PlanTemplate: {
73
+ type: "object",
74
+ required: ["sections"],
75
+ additionalProperties: false,
76
+ properties: {
77
+ description: {
78
+ type: "string",
79
+ title: "Description",
80
+ description: "Human-readable summary shown in `sr plan templates`.",
81
+ },
82
+ sections: {
83
+ type: "object",
84
+ title: "Sections",
85
+ description:
86
+ "Map of section name → spec. Each section becomes a field in the plan submission.",
87
+ additionalProperties: { $ref: "#/$defs/SectionSpec" },
88
+ },
89
+ },
90
+ },
91
+ SectionSpec: {
92
+ type: "object",
93
+ required: ["required", "kind", "prompt"],
94
+ additionalProperties: false,
95
+ properties: {
96
+ required: {
97
+ type: "boolean",
98
+ title: "Required",
99
+ description: "Whether this section must be present in the plan submission.",
100
+ },
101
+ kind: {
102
+ title: "Kind",
103
+ description:
104
+ "`text` for free text, `list` for an array, `steps` for an ordered step list, or an object describing nested sub-fields.",
105
+ oneOf: [
106
+ { type: "string", enum: ["text", "list", "steps"] },
107
+ {
108
+ type: "object",
109
+ additionalProperties: { $ref: "#/$defs/SectionSpec" },
110
+ },
111
+ ],
112
+ },
113
+ prompt: {
114
+ type: "string",
115
+ title: "Prompt",
116
+ description: "Question or instruction shown to the LLM when filling this section.",
117
+ },
118
+ min_length: {
119
+ type: "integer",
120
+ minimum: 0,
121
+ title: "Minimum length",
122
+ description: "Minimum character count when `kind` is `text`.",
123
+ },
124
+ min: {
125
+ type: "integer",
126
+ minimum: 0,
127
+ title: "Minimum items",
128
+ description: "Minimum item count when `kind` is `list` or `steps`.",
129
+ },
130
+ item: {
131
+ title: "Item shape",
132
+ description:
133
+ "When `kind` is `list`, the per-item shape: `text` for strings or an object spec for structured items.",
134
+ oneOf: [
135
+ { type: "string", const: "text" },
136
+ {
137
+ type: "object",
138
+ additionalProperties: { $ref: "#/$defs/SectionSpec" },
139
+ },
140
+ ],
141
+ },
142
+ loam_source: {
143
+ type: "string",
144
+ title: "Loam source",
145
+ description:
146
+ "Optional record type (e.g. `failure`, `decision`) seeded into `prior_art` when emitting a plan prompt.",
147
+ },
148
+ },
149
+ },
150
+ },
151
+ };
152
+ }