@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,62 @@
1
+ // Type exports
2
+
3
+ export type {
4
+ AppendOutcomeResult,
5
+ EditOptions,
6
+ OutcomeOptions,
7
+ QueryOptions,
8
+ RecordOptions,
9
+ RecordResult,
10
+ RecordUpdates,
11
+ SearchOptions,
12
+ SearchResult,
13
+ } from "./api.ts";
14
+ // Programmatic API
15
+ export {
16
+ appendOutcome,
17
+ editRecord,
18
+ queryDomain,
19
+ recordExpertise,
20
+ searchExpertise,
21
+ } from "./api.ts";
22
+ // Schema exports
23
+ export { configSchema } from "./schemas/config-schema.ts";
24
+ export type {
25
+ Classification,
26
+ ConventionRecord,
27
+ DecisionRecord,
28
+ Evidence,
29
+ ExpertiseRecord,
30
+ FailureRecord,
31
+ GuideRecord,
32
+ LoamConfig,
33
+ Outcome,
34
+ PatternRecord,
35
+ RecordType,
36
+ ReferenceRecord,
37
+ } from "./schemas/index.ts";
38
+ export { DEFAULT_CONFIG } from "./schemas/index.ts";
39
+ export { recordSchema } from "./schemas/record-schema.ts";
40
+ // Config utilities
41
+ export { getExpertisePath, readConfig } from "./utils/config.ts";
42
+ // Expertise utilities
43
+ export {
44
+ appendRecord,
45
+ findDuplicate,
46
+ generateRecordId,
47
+ readExpertiseFile,
48
+ searchRecords,
49
+ writeExpertiseFile,
50
+ } from "./utils/expertise.ts";
51
+
52
+ // Scoring utilities
53
+ export type { ScoredRecord } from "./utils/scoring.ts";
54
+ export {
55
+ applyConfirmationBoost,
56
+ computeConfirmationScore,
57
+ getFailureCount,
58
+ getSuccessCount,
59
+ getSuccessRate,
60
+ getTotalApplications,
61
+ sortByConfirmationScore,
62
+ } from "./utils/scoring.ts";
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Structured logger for loam's diagnostic / operational channel.
3
+ *
4
+ * IMPORTANT: this is NOT the product-output channel. Loam's user-facing
5
+ * output (the markdown `lm prime` emits, status tables, `--json` results,
6
+ * hints) intentionally goes straight to stdout via `console.log` /
7
+ * `outputJson`. Routing that through pino would wrap the product output in
8
+ * log envelopes and corrupt machine-readable `--json` consumers.
9
+ *
10
+ * This logger is for *diagnostics* — hook execution, unexpected internal
11
+ * errors, anything an operator (not the end user) wants when debugging.
12
+ * For that reason it writes to **stderr** (fd 2), never stdout, so it can
13
+ * never collide with the CLI result on stdout. It is silent at `info` for
14
+ * routine internals (those log at `debug`, gated behind `LOAM_DEBUG`).
15
+ *
16
+ * Level: `LOAM_LOG_LEVEL` wins; otherwise `debug` when `LOAM_DEBUG` is
17
+ * set, else `info`. In a dev TTY we render with `pino-pretty` (a devDep);
18
+ * in CI / non-TTY / production we emit newline-delimited JSON. `pino-pretty`
19
+ * is intentionally not a runtime dependency — published consumers of
20
+ * `@ag-eco/loam-cli` get JSON logs and never need the pretty transport.
21
+ */
22
+
23
+ import pino, { type Logger } from "pino";
24
+
25
+ /**
26
+ * Resolve the effective log level from the environment. `LOAM_LOG_LEVEL`
27
+ * is authoritative; `LOAM_DEBUG` is the ergonomic shortcut to `debug`.
28
+ */
29
+ export function resolveLogLevel(env: NodeJS.ProcessEnv = process.env): string {
30
+ return env.LOAM_LOG_LEVEL ?? (env.LOAM_DEBUG ? "debug" : "info");
31
+ }
32
+
33
+ /**
34
+ * Redaction paths use pino/fast-redact syntax, where `*` is a *full key
35
+ * segment* wildcard (`*.password` = a `password` key one level under any
36
+ * key). We list both the bare key (`password`) and the wildcard form
37
+ * (`*.password`) so a secret is masked whether it appears at the top level
38
+ * or nested. `remove: true` drops the key entirely rather than printing a
39
+ * `[Redacted]` placeholder.
40
+ *
41
+ * Note on `env.*KEY*` / `env.*TOKEN*`: fast-redact wildcards match a whole
42
+ * segment, so these only catch a literally-matching nested key — they do
43
+ * NOT pattern-match arbitrary `*_API_KEY` env names. They are kept because
44
+ * the L5 governance spec lists them and they are harmless, but the real
45
+ * defence for connection strings is `redactDbUrl()` below, applied inline
46
+ * before the value ever reaches a log call.
47
+ */
48
+ export const REDACT_PATHS = [
49
+ "password",
50
+ "*.password",
51
+ "token",
52
+ "*.token",
53
+ "apiKey",
54
+ "*.apiKey",
55
+ "secret",
56
+ "*.secret",
57
+ "headers.authorization",
58
+ "headers.cookie",
59
+ "env.*KEY*",
60
+ "env.*TOKEN*",
61
+ ] as const;
62
+
63
+ /**
64
+ * Build a pino logger. Exposed (in addition to the default `log` instance)
65
+ * so tests can inject a capturing destination and a fixed env without
66
+ * mutating `process.env` — mirrors loam's no-mocks, real-stream testing
67
+ * convention.
68
+ */
69
+ export function createLogger(
70
+ opts: { level?: string; destination?: pino.DestinationStream; pretty?: boolean } = {},
71
+ ): Logger {
72
+ const level = opts.level ?? resolveLogLevel();
73
+ const redact = { paths: [...REDACT_PATHS], remove: true };
74
+
75
+ // Pretty transport and an explicit destination stream are mutually
76
+ // exclusive in pino — passing both throws. When a test hands us a
77
+ // destination we always take the plain-JSON path so output is captured
78
+ // verbatim.
79
+ if (opts.destination) {
80
+ return pino({ name: "loam", level, redact }, opts.destination);
81
+ }
82
+
83
+ const usePretty =
84
+ opts.pretty ?? (process.stderr.isTTY === true && process.env.LOAM_LOG_JSON !== "1");
85
+
86
+ if (usePretty) {
87
+ return pino({
88
+ name: "loam",
89
+ level,
90
+ redact,
91
+ transport: {
92
+ target: "pino-pretty",
93
+ options: { destination: 2, colorize: true, translateTime: "SYS:HH:MM:ss.l" },
94
+ },
95
+ });
96
+ }
97
+
98
+ // CI / non-TTY / production: newline-delimited JSON straight to stderr.
99
+ return pino({ name: "loam", level, redact }, pino.destination(2));
100
+ }
101
+
102
+ /**
103
+ * Strip credentials (`user:password@`) from a URL before logging it.
104
+ * Mirrors warren's helper: non-URL sentinels (`:memory:`, bare sqlite
105
+ * paths) and credential-free URLs pass through unchanged; an unparseable
106
+ * URL collapses to a safe placeholder so a malformed value can never leak.
107
+ */
108
+ export function redactDbUrl(url: string): string {
109
+ // Bare sqlite / sentinel values have no userinfo to strip.
110
+ if (url === ":memory:" || url.startsWith("sqlite:") || !url.includes("@")) {
111
+ return url;
112
+ }
113
+ try {
114
+ const u = new URL(url);
115
+ if (u.username !== "" || u.password !== "") {
116
+ u.username = "";
117
+ u.password = "";
118
+ return u.toString();
119
+ }
120
+ return url;
121
+ } catch {
122
+ return "<redacted-url>";
123
+ }
124
+ }
125
+
126
+ /** Default process-wide logger. Diagnostics only — see file header. */
127
+ export const log = createLogger();
@@ -0,0 +1,409 @@
1
+ import type {
2
+ ConventionRecord,
3
+ DecisionRecord,
4
+ ExpertiseRecord,
5
+ FailureRecord,
6
+ GuideRecord,
7
+ PatternRecord,
8
+ ReferenceRecord,
9
+ } from "../schemas/record.ts";
10
+ import {
11
+ compactMeta,
12
+ formatLinks,
13
+ formatOutcome,
14
+ formatRecordMeta,
15
+ idTag,
16
+ truncate,
17
+ xmlEscape,
18
+ } from "../utils/format-helpers.ts";
19
+ import { type SharedDefinitions, type TypeDefinition, TypeRegistry } from "./type-registry.ts";
20
+
21
+ const linkArray = {
22
+ type: "array",
23
+ items: { type: "string", pattern: "^([a-z0-9-]+:)?mx-[0-9a-f]{4,8}$" },
24
+ } as const;
25
+
26
+ const SHARED_DEFINITIONS: SharedDefinitions = {
27
+ classification: {
28
+ type: "string",
29
+ enum: ["foundational", "tactical", "observational"],
30
+ },
31
+ evidence: {
32
+ type: "object",
33
+ properties: {
34
+ commit: { type: "string" },
35
+ date: { type: "string" },
36
+ issue: { type: "string" },
37
+ file: { type: "string" },
38
+ bead: { type: "string" },
39
+ sprout: { type: "string" },
40
+ gh: { type: "string" },
41
+ linear: { type: "string" },
42
+ },
43
+ additionalProperties: false,
44
+ },
45
+ outcome: {
46
+ type: "object",
47
+ properties: {
48
+ status: { type: "string", enum: ["success", "failure", "partial"] },
49
+ duration: { type: "number" },
50
+ test_results: { type: "string" },
51
+ agent: { type: "string" },
52
+ notes: { type: "string" },
53
+ recorded_at: { type: "string" },
54
+ },
55
+ required: ["status"],
56
+ additionalProperties: false,
57
+ },
58
+ };
59
+
60
+ const baseSchemaProps = {
61
+ id: { type: "string", pattern: "^mx-[0-9a-f]{4,8}$" },
62
+ classification: { $ref: "#/definitions/classification" },
63
+ recorded_at: { type: "string" },
64
+ evidence: { $ref: "#/definitions/evidence" },
65
+ tags: { type: "array", items: { type: "string" } },
66
+ relates_to: linkArray,
67
+ supersedes: linkArray,
68
+ outcomes: { type: "array", items: { $ref: "#/definitions/outcome" } },
69
+ dir_anchors: { type: "array", items: { type: "string" } },
70
+ supersession_demoted_at: { type: "string" },
71
+ anchor_decay_demoted_at: { type: "string" },
72
+ owner: { type: "string" },
73
+ // "archived" is intentionally absent — soft-archived records bypass AJV
74
+ // (they live under .loam/archive/) and live records may not carry it.
75
+ status: { type: "string", enum: ["draft", "active", "deprecated"] },
76
+ } as const;
77
+
78
+ // --- convention ---
79
+
80
+ const conventionDef: TypeDefinition = {
81
+ name: "convention",
82
+ kind: "builtin",
83
+ required: ["content"],
84
+ optional: [],
85
+ dedupKey: "content",
86
+ idKey: "content",
87
+ summary: (r) => truncate((r as ConventionRecord).content, 60),
88
+ extractsFiles: false,
89
+ filesField: "files",
90
+ compact: "concat",
91
+ sectionTitle: "Conventions",
92
+ ajvSchema: {
93
+ type: "object",
94
+ properties: {
95
+ ...baseSchemaProps,
96
+ type: { type: "string", const: "convention" },
97
+ content: { type: "string" },
98
+ },
99
+ required: ["type", "content", "classification", "recorded_at"],
100
+ additionalProperties: false,
101
+ },
102
+ formatMarkdown: (records, full) => {
103
+ if (records.length === 0) return "";
104
+ const lines = ["### Conventions"];
105
+ for (const rec of records as ConventionRecord[]) {
106
+ lines.push(`- ${idTag(rec)}${rec.content}${formatRecordMeta(rec, full)}`);
107
+ }
108
+ return lines.join("\n");
109
+ },
110
+ formatCompactLine: (record) => {
111
+ const r = record as ConventionRecord;
112
+ const links = formatLinks(r);
113
+ const meta = compactMeta(r);
114
+ const outcome = formatOutcome(r.outcomes);
115
+ return `- [convention] ${truncate(r.content)}${meta}${outcome}${links}`;
116
+ },
117
+ formatXml: (record) => {
118
+ const r = record as ConventionRecord;
119
+ return [` ${xmlEscape(r.content)}`];
120
+ },
121
+ };
122
+
123
+ // --- pattern ---
124
+
125
+ const patternDef: TypeDefinition = {
126
+ name: "pattern",
127
+ kind: "builtin",
128
+ required: ["name", "description"],
129
+ optional: ["files"],
130
+ dedupKey: "name",
131
+ idKey: "name",
132
+ summary: (r) => (r as PatternRecord).name,
133
+ extractsFiles: true,
134
+ filesField: "files",
135
+ compact: "concat",
136
+ sectionTitle: "Patterns",
137
+ ajvSchema: {
138
+ type: "object",
139
+ properties: {
140
+ ...baseSchemaProps,
141
+ type: { type: "string", const: "pattern" },
142
+ name: { type: "string" },
143
+ description: { type: "string" },
144
+ files: { type: "array", items: { type: "string" } },
145
+ },
146
+ required: ["type", "name", "description", "classification", "recorded_at"],
147
+ additionalProperties: false,
148
+ },
149
+ formatMarkdown: (records, full) => {
150
+ if (records.length === 0) return "";
151
+ const lines = ["### Patterns"];
152
+ for (const rec of records as PatternRecord[]) {
153
+ let line = `- ${idTag(rec)}**${rec.name}**: ${rec.description}`;
154
+ if (rec.files && rec.files.length > 0) {
155
+ line += ` (${rec.files.join(", ")})`;
156
+ }
157
+ line += formatRecordMeta(rec, full);
158
+ lines.push(line);
159
+ }
160
+ return lines.join("\n");
161
+ },
162
+ formatCompactLine: (record) => {
163
+ const r = record as PatternRecord;
164
+ const links = formatLinks(r);
165
+ const meta = compactMeta(r);
166
+ const outcome = formatOutcome(r.outcomes);
167
+ const files = r.files && r.files.length > 0 ? ` (${r.files.join(", ")})` : "";
168
+ return `- [pattern] ${r.name}: ${truncate(r.description)}${files}${meta}${outcome}${links}`;
169
+ },
170
+ formatXml: (record) => {
171
+ const r = record as PatternRecord;
172
+ const lines: string[] = [];
173
+ lines.push(` <name>${xmlEscape(r.name)}</name>`);
174
+ lines.push(` <description>${xmlEscape(r.description)}</description>`);
175
+ if (r.files && r.files.length > 0) {
176
+ lines.push(` <files>${r.files.map(xmlEscape).join(", ")}</files>`);
177
+ }
178
+ return lines;
179
+ },
180
+ };
181
+
182
+ // --- failure ---
183
+
184
+ const failureDef: TypeDefinition = {
185
+ name: "failure",
186
+ kind: "builtin",
187
+ required: ["description", "resolution"],
188
+ optional: [],
189
+ dedupKey: "description",
190
+ idKey: "description",
191
+ summary: (r) => truncate((r as FailureRecord).description, 60),
192
+ extractsFiles: false,
193
+ filesField: "files",
194
+ compact: "concat",
195
+ sectionTitle: "Known Failures",
196
+ ajvSchema: {
197
+ type: "object",
198
+ properties: {
199
+ ...baseSchemaProps,
200
+ type: { type: "string", const: "failure" },
201
+ description: { type: "string" },
202
+ resolution: { type: "string" },
203
+ },
204
+ required: ["type", "description", "resolution", "classification", "recorded_at"],
205
+ additionalProperties: false,
206
+ },
207
+ formatMarkdown: (records, full) => {
208
+ if (records.length === 0) return "";
209
+ const lines = ["### Known Failures"];
210
+ for (const rec of records as FailureRecord[]) {
211
+ lines.push(`- ${idTag(rec)}${rec.description}${formatRecordMeta(rec, full)}`);
212
+ lines.push(` → ${rec.resolution}`);
213
+ }
214
+ return lines.join("\n");
215
+ },
216
+ formatCompactLine: (record) => {
217
+ const r = record as FailureRecord;
218
+ const links = formatLinks(r);
219
+ const meta = compactMeta(r);
220
+ const outcome = formatOutcome(r.outcomes);
221
+ return `- [failure] ${truncate(r.description)} → ${truncate(r.resolution)}${meta}${outcome}${links}`;
222
+ },
223
+ formatXml: (record) => {
224
+ const r = record as FailureRecord;
225
+ return [
226
+ ` <description>${xmlEscape(r.description)}</description>`,
227
+ ` <resolution>${xmlEscape(r.resolution)}</resolution>`,
228
+ ];
229
+ },
230
+ };
231
+
232
+ // --- decision ---
233
+
234
+ const decisionDef: TypeDefinition = {
235
+ name: "decision",
236
+ kind: "builtin",
237
+ required: ["title", "rationale"],
238
+ optional: ["date"],
239
+ dedupKey: "title",
240
+ idKey: "title",
241
+ summary: (r) => (r as DecisionRecord).title,
242
+ extractsFiles: false,
243
+ filesField: "files",
244
+ compact: "concat",
245
+ sectionTitle: "Decisions",
246
+ ajvSchema: {
247
+ type: "object",
248
+ properties: {
249
+ ...baseSchemaProps,
250
+ type: { type: "string", const: "decision" },
251
+ title: { type: "string" },
252
+ rationale: { type: "string" },
253
+ date: { type: "string" },
254
+ },
255
+ required: ["type", "title", "rationale", "classification", "recorded_at"],
256
+ additionalProperties: false,
257
+ },
258
+ formatMarkdown: (records, full) => {
259
+ if (records.length === 0) return "";
260
+ const lines = ["### Decisions"];
261
+ for (const rec of records as DecisionRecord[]) {
262
+ lines.push(`- ${idTag(rec)}**${rec.title}**: ${rec.rationale}${formatRecordMeta(rec, full)}`);
263
+ }
264
+ return lines.join("\n");
265
+ },
266
+ formatCompactLine: (record) => {
267
+ const r = record as DecisionRecord;
268
+ const links = formatLinks(r);
269
+ const meta = compactMeta(r);
270
+ const outcome = formatOutcome(r.outcomes);
271
+ return `- [decision] ${r.title}: ${truncate(r.rationale)}${meta}${outcome}${links}`;
272
+ },
273
+ formatXml: (record) => {
274
+ const r = record as DecisionRecord;
275
+ return [
276
+ ` <title>${xmlEscape(r.title)}</title>`,
277
+ ` <rationale>${xmlEscape(r.rationale)}</rationale>`,
278
+ ];
279
+ },
280
+ };
281
+
282
+ // --- reference ---
283
+
284
+ const referenceDef: TypeDefinition = {
285
+ name: "reference",
286
+ kind: "builtin",
287
+ required: ["name", "description"],
288
+ optional: ["files"],
289
+ dedupKey: "name",
290
+ idKey: "name",
291
+ summary: (r) => (r as ReferenceRecord).name,
292
+ extractsFiles: true,
293
+ filesField: "files",
294
+ compact: "concat",
295
+ sectionTitle: "References",
296
+ ajvSchema: {
297
+ type: "object",
298
+ properties: {
299
+ ...baseSchemaProps,
300
+ type: { type: "string", const: "reference" },
301
+ name: { type: "string" },
302
+ description: { type: "string" },
303
+ files: { type: "array", items: { type: "string" } },
304
+ },
305
+ required: ["type", "name", "description", "classification", "recorded_at"],
306
+ additionalProperties: false,
307
+ },
308
+ formatMarkdown: (records, full) => {
309
+ if (records.length === 0) return "";
310
+ const lines = ["### References"];
311
+ for (const rec of records as ReferenceRecord[]) {
312
+ let line = `- ${idTag(rec)}**${rec.name}**: ${rec.description}`;
313
+ if (rec.files && rec.files.length > 0) {
314
+ line += ` (${rec.files.join(", ")})`;
315
+ }
316
+ line += formatRecordMeta(rec, full);
317
+ lines.push(line);
318
+ }
319
+ return lines.join("\n");
320
+ },
321
+ formatCompactLine: (record) => {
322
+ const r = record as ReferenceRecord;
323
+ const links = formatLinks(r);
324
+ const meta = compactMeta(r);
325
+ const outcome = formatOutcome(r.outcomes);
326
+ const refFiles =
327
+ r.files && r.files.length > 0 ? `: ${r.files.join(", ")}` : `: ${truncate(r.description)}`;
328
+ return `- [reference] ${r.name}${refFiles}${meta}${outcome}${links}`;
329
+ },
330
+ formatXml: (record) => {
331
+ const r = record as ReferenceRecord;
332
+ const lines: string[] = [];
333
+ lines.push(` <name>${xmlEscape(r.name)}</name>`);
334
+ lines.push(` <description>${xmlEscape(r.description)}</description>`);
335
+ if (r.files && r.files.length > 0) {
336
+ lines.push(` <files>${r.files.map(xmlEscape).join(", ")}</files>`);
337
+ }
338
+ return lines;
339
+ },
340
+ };
341
+
342
+ // --- guide ---
343
+
344
+ const guideDef: TypeDefinition = {
345
+ name: "guide",
346
+ kind: "builtin",
347
+ required: ["name", "description"],
348
+ optional: [],
349
+ dedupKey: "name",
350
+ idKey: "name",
351
+ summary: (r) => (r as GuideRecord).name,
352
+ extractsFiles: false,
353
+ filesField: "files",
354
+ compact: "concat",
355
+ sectionTitle: "Guides",
356
+ ajvSchema: {
357
+ type: "object",
358
+ properties: {
359
+ ...baseSchemaProps,
360
+ type: { type: "string", const: "guide" },
361
+ name: { type: "string" },
362
+ description: { type: "string" },
363
+ },
364
+ required: ["type", "name", "description", "classification", "recorded_at"],
365
+ additionalProperties: false,
366
+ },
367
+ formatMarkdown: (records, full) => {
368
+ if (records.length === 0) return "";
369
+ const lines = ["### Guides"];
370
+ for (const rec of records as GuideRecord[]) {
371
+ lines.push(
372
+ `- ${idTag(rec)}**${rec.name}**: ${rec.description}${formatRecordMeta(rec, full)}`,
373
+ );
374
+ }
375
+ return lines.join("\n");
376
+ },
377
+ formatCompactLine: (record) => {
378
+ const r = record as GuideRecord;
379
+ const links = formatLinks(r);
380
+ const meta = compactMeta(r);
381
+ const outcome = formatOutcome(r.outcomes);
382
+ return `- [guide] ${r.name}: ${truncate(r.description)}${meta}${outcome}${links}`;
383
+ },
384
+ formatXml: (record) => {
385
+ const r = record as GuideRecord;
386
+ return [
387
+ ` <name>${xmlEscape(r.name)}</name>`,
388
+ ` <description>${xmlEscape(r.description)}</description>`,
389
+ ];
390
+ },
391
+ };
392
+
393
+ // Section enumeration order for markdown rendering. Matches the historical
394
+ // order in formatDomainExpertise so output stays byte-identical.
395
+ export const BUILTIN_DEFS: readonly TypeDefinition[] = [
396
+ conventionDef,
397
+ patternDef,
398
+ failureDef,
399
+ decisionDef,
400
+ referenceDef,
401
+ guideDef,
402
+ ] as const;
403
+
404
+ export function buildBuiltinRegistry(): TypeRegistry {
405
+ return new TypeRegistry([...BUILTIN_DEFS], SHARED_DEFINITIONS);
406
+ }
407
+
408
+ // Re-export helper for downstream cast-assertion sites:
409
+ export type AnyRecord = ExpertiseRecord;