@ybotok/loam 0.1.0-beta.3 → 0.2.0-alpha.13

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 (1256) hide show
  1. package/CHANGELOG.md +5992 -82
  2. package/COMPARISON.md +168 -63
  3. package/CONTRIBUTING.md +121 -0
  4. package/MIGRATING-from-OpenSpec.md +238 -55
  5. package/QUICKSTART.md +302 -0
  6. package/README.md +653 -144
  7. package/ROADMAP.md +1035 -0
  8. package/SCHEMA.md +3916 -263
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +927 -0
  11. package/dist/cli.js +133 -21
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +204 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +309 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +74 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/closing.js +42 -0
  20. package/dist/commands/archive/closing.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
  22. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  23. package/dist/commands/archive/plan/contracts/consumers.js +56 -0
  24. package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
  25. package/dist/commands/archive/plan/contracts/openapi.js +193 -0
  26. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  27. package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
  28. package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
  29. package/dist/commands/archive/plan/document/head.js +151 -0
  30. package/dist/commands/archive/plan/document/head.js.map +1 -0
  31. package/dist/commands/archive/plan/document/links.js +284 -0
  32. package/dist/commands/archive/plan/document/links.js.map +1 -0
  33. package/dist/commands/archive/plan/document/run.js +136 -0
  34. package/dist/commands/archive/plan/document/run.js.map +1 -0
  35. package/dist/commands/archive/plan/gate.js +319 -0
  36. package/dist/commands/archive/plan/gate.js.map +1 -0
  37. package/dist/commands/archive/plan/landscape.js +298 -0
  38. package/dist/commands/archive/plan/landscape.js.map +1 -0
  39. package/dist/commands/archive/plan/model/extending.js +85 -0
  40. package/dist/commands/archive/plan/model/extending.js.map +1 -0
  41. package/dist/commands/archive/plan/refusal.js +106 -0
  42. package/dist/commands/archive/plan/refusal.js.map +1 -0
  43. package/dist/commands/archive/plan/specs.js +318 -0
  44. package/dist/commands/archive/plan/specs.js.map +1 -0
  45. package/dist/commands/archive/plan/state.js +30 -0
  46. package/dist/commands/archive/plan/state.js.map +1 -0
  47. package/dist/commands/archive/run.js +355 -0
  48. package/dist/commands/archive/run.js.map +1 -0
  49. package/dist/commands/archive/shipped.js +49 -0
  50. package/dist/commands/archive/shipped.js.map +1 -0
  51. package/dist/commands/context/context.js +166 -0
  52. package/dist/commands/context/context.js.map +1 -0
  53. package/dist/commands/context/print.js +305 -0
  54. package/dist/commands/context/print.js.map +1 -0
  55. package/dist/commands/delta/delta.js +367 -0
  56. package/dist/commands/delta/delta.js.map +1 -0
  57. package/dist/commands/delta/print.js +221 -0
  58. package/dist/commands/delta/print.js.map +1 -0
  59. package/dist/commands/dependencies.js +6 -8
  60. package/dist/commands/dependencies.js.map +1 -1
  61. package/dist/commands/diff/diff.js +86 -0
  62. package/dist/commands/diff/diff.js.map +1 -0
  63. package/dist/commands/diff/print.js +38 -0
  64. package/dist/commands/diff/print.js.map +1 -0
  65. package/dist/commands/doctor.js +65 -5
  66. package/dist/commands/doctor.js.map +1 -1
  67. package/dist/commands/explain/explain.js +227 -0
  68. package/dist/commands/explain/explain.js.map +1 -0
  69. package/dist/commands/explore.js +39 -28
  70. package/dist/commands/explore.js.map +1 -1
  71. package/dist/commands/gate/gate.js +152 -0
  72. package/dist/commands/gate/gate.js.map +1 -0
  73. package/dist/commands/gate/print.js +66 -0
  74. package/dist/commands/gate/print.js.map +1 -0
  75. package/dist/commands/gherkin/commit.js +105 -0
  76. package/dist/commands/gherkin/commit.js.map +1 -0
  77. package/dist/commands/gherkin/gherkin.js +262 -0
  78. package/dist/commands/gherkin/gherkin.js.map +1 -0
  79. package/dist/commands/gherkin/reconcile.js +146 -0
  80. package/dist/commands/gherkin/reconcile.js.map +1 -0
  81. package/dist/commands/gherkin/render.js +77 -0
  82. package/dist/commands/gherkin/render.js.map +1 -0
  83. package/dist/commands/init/example.js +204 -0
  84. package/dist/commands/init/example.js.map +1 -0
  85. package/dist/commands/init/first-hour.js +72 -0
  86. package/dist/commands/init/first-hour.js.map +1 -0
  87. package/dist/commands/{init.js → init/init.js} +142 -71
  88. package/dist/commands/init/init.js.map +1 -0
  89. package/dist/commands/init/mcp.js +131 -0
  90. package/dist/commands/init/mcp.js.map +1 -0
  91. package/dist/commands/init/options.js +78 -0
  92. package/dist/commands/init/options.js.map +1 -0
  93. package/dist/commands/instructions.js +72 -14
  94. package/dist/commands/instructions.js.map +1 -1
  95. package/dist/commands/list/campaign/campaign.js +63 -0
  96. package/dist/commands/list/campaign/campaign.js.map +1 -0
  97. package/dist/commands/list/campaign/owners.js +65 -0
  98. package/dist/commands/list/campaign/owners.js.map +1 -0
  99. package/dist/commands/list/json.js +155 -0
  100. package/dist/commands/list/json.js.map +1 -0
  101. package/dist/commands/list/list.js +358 -0
  102. package/dist/commands/list/list.js.map +1 -0
  103. package/dist/commands/list/print.js +344 -0
  104. package/dist/commands/list/print.js.map +1 -0
  105. package/dist/commands/list/review.js +120 -0
  106. package/dist/commands/list/review.js.map +1 -0
  107. package/dist/commands/list/suites/suites.js +140 -0
  108. package/dist/commands/list/suites/suites.js.map +1 -0
  109. package/dist/commands/list/views.js +108 -0
  110. package/dist/commands/list/views.js.map +1 -0
  111. package/dist/commands/mcp/dispatch.js +238 -0
  112. package/dist/commands/mcp/dispatch.js.map +1 -0
  113. package/dist/commands/mcp/mcp.js +75 -0
  114. package/dist/commands/mcp/mcp.js.map +1 -0
  115. package/dist/commands/mcp/serve.js +55 -0
  116. package/dist/commands/mcp/serve.js.map +1 -0
  117. package/dist/commands/migrate-openspec/materialize/active.js +175 -0
  118. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  119. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  120. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  121. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  122. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  123. package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
  124. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  125. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  126. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  127. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  128. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  129. package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
  130. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  131. package/dist/commands/migrate-openspec/openspec/error.js +18 -0
  132. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  133. package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
  134. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  135. package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
  136. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  137. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  138. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  139. package/dist/commands/migrate-openspec/print.js +89 -0
  140. package/dist/commands/migrate-openspec/print.js.map +1 -0
  141. package/dist/commands/new/capability-template.js +118 -0
  142. package/dist/commands/new/capability-template.js.map +1 -0
  143. package/dist/commands/new/commit.js +62 -0
  144. package/dist/commands/new/commit.js.map +1 -0
  145. package/dist/commands/new/modifies.js +206 -0
  146. package/dist/commands/new/modifies.js.map +1 -0
  147. package/dist/commands/new/new.js +328 -0
  148. package/dist/commands/new/new.js.map +1 -0
  149. package/dist/commands/new/templates.js +279 -0
  150. package/dist/commands/new/templates.js.map +1 -0
  151. package/dist/commands/open.js +199 -0
  152. package/dist/commands/open.js.map +1 -0
  153. package/dist/commands/policy/format.js +152 -0
  154. package/dist/commands/policy/format.js.map +1 -0
  155. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
  156. package/dist/commands/policy/gate.js.map +1 -0
  157. package/dist/commands/rebase/edit.js +106 -0
  158. package/dist/commands/rebase/edit.js.map +1 -0
  159. package/dist/commands/rebase/living.js +185 -0
  160. package/dist/commands/rebase/living.js.map +1 -0
  161. package/dist/commands/rebase/plan.js +245 -0
  162. package/dist/commands/rebase/plan.js.map +1 -0
  163. package/dist/commands/rebase/rebase.js +300 -0
  164. package/dist/commands/rebase/rebase.js.map +1 -0
  165. package/dist/commands/seed/commit.js +221 -0
  166. package/dist/commands/seed/commit.js.map +1 -0
  167. package/dist/commands/seed/plan.js +278 -0
  168. package/dist/commands/seed/plan.js.map +1 -0
  169. package/dist/commands/seed/seed.js +174 -0
  170. package/dist/commands/seed/seed.js.map +1 -0
  171. package/dist/commands/show/feature.js +182 -0
  172. package/dist/commands/show/feature.js.map +1 -0
  173. package/dist/commands/show/introduced.js +157 -0
  174. package/dist/commands/show/introduced.js.map +1 -0
  175. package/dist/commands/show/marks.js +53 -0
  176. package/dist/commands/show/marks.js.map +1 -0
  177. package/dist/commands/show/service.js +239 -0
  178. package/dist/commands/show/service.js.map +1 -0
  179. package/dist/commands/show/show.js +87 -0
  180. package/dist/commands/show/show.js.map +1 -0
  181. package/dist/commands/status/fleet-next.js +90 -0
  182. package/dist/commands/status/fleet-next.js.map +1 -0
  183. package/dist/commands/status/json.js +47 -0
  184. package/dist/commands/status/json.js.map +1 -0
  185. package/dist/commands/status/print.js +209 -0
  186. package/dist/commands/status/print.js.map +1 -0
  187. package/dist/commands/status/status.js +115 -0
  188. package/dist/commands/status/status.js.map +1 -0
  189. package/dist/commands/steps/steps.js +269 -0
  190. package/dist/commands/steps/steps.js.map +1 -0
  191. package/dist/commands/subsystem/edit.js +192 -0
  192. package/dist/commands/subsystem/edit.js.map +1 -0
  193. package/dist/commands/subsystem/move.js +325 -0
  194. package/dist/commands/subsystem/move.js.map +1 -0
  195. package/dist/commands/subsystem/query.js +113 -0
  196. package/dist/commands/subsystem/query.js.map +1 -0
  197. package/dist/commands/subsystem/subsystem.js +98 -0
  198. package/dist/commands/subsystem/subsystem.js.map +1 -0
  199. package/dist/commands/subsystem/sync.js +318 -0
  200. package/dist/commands/subsystem/sync.js.map +1 -0
  201. package/dist/commands/subsystem/txn/exclude.js +132 -0
  202. package/dist/commands/subsystem/txn/exclude.js.map +1 -0
  203. package/dist/commands/subsystem/txn/links.js +128 -0
  204. package/dist/commands/subsystem/txn/links.js.map +1 -0
  205. package/dist/commands/subsystem/txn/report.js +174 -0
  206. package/dist/commands/subsystem/txn/report.js.map +1 -0
  207. package/dist/commands/subsystem/txn/txn.js +196 -0
  208. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  209. package/dist/commands/subsystem/txn/views.js +249 -0
  210. package/dist/commands/subsystem/txn/views.js.map +1 -0
  211. package/dist/commands/tasks/actions.js +107 -0
  212. package/dist/commands/tasks/actions.js.map +1 -0
  213. package/dist/commands/tasks/render.js +253 -0
  214. package/dist/commands/tasks/render.js.map +1 -0
  215. package/dist/commands/tasks/tasks.js +119 -0
  216. package/dist/commands/tasks/tasks.js.map +1 -0
  217. package/dist/commands/unarchive/manifest.js +176 -0
  218. package/dist/commands/unarchive/manifest.js.map +1 -0
  219. package/dist/commands/unarchive/restore.js +254 -0
  220. package/dist/commands/unarchive/restore.js.map +1 -0
  221. package/dist/commands/unarchive/unarchive.js +59 -0
  222. package/dist/commands/unarchive/unarchive.js.map +1 -0
  223. package/dist/commands/validate/arch-coverage.js +245 -0
  224. package/dist/commands/validate/arch-coverage.js.map +1 -0
  225. package/dist/commands/validate/checks/fleet-shape.js +204 -0
  226. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  227. package/dist/commands/validate/checks/health-deps.js +58 -0
  228. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  229. package/dist/commands/validate/checks/introduced.js +102 -0
  230. package/dist/commands/validate/checks/introduced.js.map +1 -0
  231. package/dist/commands/validate/checks/requirements.js +264 -0
  232. package/dist/commands/validate/checks/requirements.js.map +1 -0
  233. package/dist/commands/validate/checks/sources.js +85 -0
  234. package/dist/commands/validate/checks/sources.js.map +1 -0
  235. package/dist/commands/validate/coverage/covers-after.js +105 -0
  236. package/dist/commands/validate/coverage/covers-after.js.map +1 -0
  237. package/dist/commands/validate/feature.js +222 -0
  238. package/dist/commands/validate/feature.js.map +1 -0
  239. package/dist/commands/validate/fleet/census.js +93 -0
  240. package/dist/commands/validate/fleet/census.js.map +1 -0
  241. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  242. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  243. package/dist/commands/validate/fleet/landscape.js +371 -0
  244. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  245. package/dist/commands/validate/fleet/load.js +118 -0
  246. package/dist/commands/validate/fleet/load.js.map +1 -0
  247. package/dist/commands/validate/fleet/map/attest.js +98 -0
  248. package/dist/commands/validate/fleet/map/attest.js.map +1 -0
  249. package/dist/commands/validate/fleet/map/bindings.js +107 -0
  250. package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
  251. package/dist/commands/validate/fleet/map/consumers.js +244 -0
  252. package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
  253. package/dist/commands/validate/fleet/map/isolation.js +116 -0
  254. package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
  255. package/dist/commands/validate/fleet/map/usecases.js +54 -0
  256. package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
  257. package/dist/commands/validate/fleet/obligations.js +266 -0
  258. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  259. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  260. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  261. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  262. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  263. package/dist/commands/validate/fleet/scorecard/print.js +71 -0
  264. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  265. package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
  266. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  267. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  268. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  269. package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
  270. package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
  271. package/dist/commands/validate/fleet/views/ids.js +75 -0
  272. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  273. package/dist/commands/validate/fleet/views/projects.js +278 -0
  274. package/dist/commands/validate/fleet/views/projects.js.map +1 -0
  275. package/dist/commands/validate/fleet/views/root-documents.js +83 -0
  276. package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
  277. package/dist/commands/validate/fleet/views/stale.js +52 -0
  278. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  279. package/dist/commands/validate/links/corpus.js +89 -0
  280. package/dist/commands/validate/links/corpus.js.map +1 -0
  281. package/dist/commands/validate/links/glossary.js +75 -0
  282. package/dist/commands/validate/links/glossary.js.map +1 -0
  283. package/dist/commands/validate/render/repeats.js +63 -0
  284. package/dist/commands/validate/render/repeats.js.map +1 -0
  285. package/dist/commands/validate/render/rollups.js +115 -0
  286. package/dist/commands/validate/render/rollups.js.map +1 -0
  287. package/dist/commands/validate/render/text.js +199 -0
  288. package/dist/commands/validate/render/text.js.map +1 -0
  289. package/dist/commands/validate/report.js +145 -0
  290. package/dist/commands/validate/report.js.map +1 -0
  291. package/dist/commands/validate/scope.js +113 -0
  292. package/dist/commands/validate/scope.js.map +1 -0
  293. package/dist/commands/validate/service/api.js +252 -0
  294. package/dist/commands/validate/service/api.js.map +1 -0
  295. package/dist/commands/validate/service/contracts/generated.js +134 -0
  296. package/dist/commands/validate/service/contracts/generated.js.map +1 -0
  297. package/dist/commands/validate/service/events/events.js +241 -0
  298. package/dist/commands/validate/service/events/events.js.map +1 -0
  299. package/dist/commands/validate/service/events/message-producers.js +77 -0
  300. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  301. package/dist/commands/validate/service/evidence-pins.js +177 -0
  302. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  303. package/dist/commands/validate/service/model/diverged.js +226 -0
  304. package/dist/commands/validate/service/model/diverged.js.map +1 -0
  305. package/dist/commands/validate/service/model/grade.js +163 -0
  306. package/dist/commands/validate/service/model/grade.js.map +1 -0
  307. package/dist/commands/validate/service/service.js +310 -0
  308. package/dist/commands/validate/service/service.js.map +1 -0
  309. package/dist/commands/validate/service/specs.js +279 -0
  310. package/dist/commands/validate/service/specs.js.map +1 -0
  311. package/dist/commands/validate/service/spine.js +148 -0
  312. package/dist/commands/validate/service/spine.js.map +1 -0
  313. package/dist/commands/validate/service/usecases/tags.js +113 -0
  314. package/dist/commands/validate/service/usecases/tags.js.map +1 -0
  315. package/dist/commands/validate/service/usecases/usecases.js +209 -0
  316. package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
  317. package/dist/commands/validate/validate.js +363 -0
  318. package/dist/commands/validate/validate.js.map +1 -0
  319. package/dist/commands/verify/cross/diff.js +178 -0
  320. package/dist/commands/verify/cross/diff.js.map +1 -0
  321. package/dist/commands/verify/evidence/contract.js +32 -0
  322. package/dist/commands/verify/evidence/contract.js.map +1 -0
  323. package/dist/commands/verify/evidence/pins.js +52 -0
  324. package/dist/commands/verify/evidence/pins.js.map +1 -0
  325. package/dist/commands/verify/evidence/read.js +81 -0
  326. package/dist/commands/verify/evidence/read.js.map +1 -0
  327. package/dist/commands/verify/frozen.js +263 -0
  328. package/dist/commands/verify/frozen.js.map +1 -0
  329. package/dist/commands/verify/record.js +278 -0
  330. package/dist/commands/verify/record.js.map +1 -0
  331. package/dist/commands/verify/report.js +206 -0
  332. package/dist/commands/verify/report.js.map +1 -0
  333. package/dist/commands/verify/results.js +328 -0
  334. package/dist/commands/verify/results.js.map +1 -0
  335. package/dist/commands/verify/verify.js +220 -0
  336. package/dist/commands/verify/verify.js.map +1 -0
  337. package/dist/commands/vouch/contract.js +11 -0
  338. package/dist/commands/vouch/contract.js.map +1 -0
  339. package/dist/commands/vouch/pack/contract.js +2 -0
  340. package/dist/commands/vouch/pack/contract.js.map +1 -0
  341. package/dist/commands/vouch/pack/pack.js +266 -0
  342. package/dist/commands/vouch/pack/pack.js.map +1 -0
  343. package/dist/commands/vouch/pack/print.js +266 -0
  344. package/dist/commands/vouch/pack/print.js.map +1 -0
  345. package/dist/commands/vouch/pack/sections.js +141 -0
  346. package/dist/commands/vouch/pack/sections.js.map +1 -0
  347. package/dist/commands/vouch/prompt/confirm.js +46 -0
  348. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  349. package/dist/commands/vouch/report.js +101 -0
  350. package/dist/commands/vouch/report.js.map +1 -0
  351. package/dist/commands/vouch/run.js +230 -0
  352. package/dist/commands/vouch/run.js.map +1 -0
  353. package/dist/commands/vouch/sample/plan.js +111 -0
  354. package/dist/commands/vouch/sample/plan.js.map +1 -0
  355. package/dist/commands/vouch/sample/print.js +109 -0
  356. package/dist/commands/vouch/sample/print.js.map +1 -0
  357. package/dist/commands/vouch/vet/verify.js +155 -0
  358. package/dist/commands/vouch/vet/verify.js.map +1 -0
  359. package/dist/commands/vouch/vouch.js +169 -0
  360. package/dist/commands/vouch/vouch.js.map +1 -0
  361. package/dist/core/agent/agents-md/command-map.js +299 -0
  362. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  363. package/dist/core/agent/agents-md/map/explain.js +46 -0
  364. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  365. package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
  366. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  367. package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
  368. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  369. package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
  370. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  371. package/dist/core/agent/agents-md/map/mcp.js +44 -0
  372. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  373. package/dist/core/agent/agents-md/map/status.js +78 -0
  374. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  375. package/dist/core/agent/agents-md/map/subsystem.js +104 -0
  376. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  377. package/dist/core/agent/agents-md/map/usecases.js +138 -0
  378. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  379. package/dist/core/agent/agents-md/refusals.js +273 -0
  380. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  381. package/dist/core/agent/agents-md.js +203 -0
  382. package/dist/core/agent/agents-md.js.map +1 -0
  383. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
  384. package/dist/core/agent/agents-stamp.js.map +1 -0
  385. package/dist/core/agent/contract.js +2 -0
  386. package/dist/core/agent/contract.js.map +1 -0
  387. package/dist/core/agent/protocol.js +193 -0
  388. package/dist/core/agent/protocol.js.map +1 -0
  389. package/dist/core/agent/scaffold.js +254 -0
  390. package/dist/core/agent/scaffold.js.map +1 -0
  391. package/dist/core/agent/support/report.js +144 -0
  392. package/dist/core/agent/support/report.js.map +1 -0
  393. package/dist/core/agent/tools/dialects.js +151 -0
  394. package/dist/core/agent/tools/dialects.js.map +1 -0
  395. package/dist/core/agent/tools/registry.js +193 -0
  396. package/dist/core/agent/tools/registry.js.map +1 -0
  397. package/dist/core/agent/workflows/adopt.js +280 -0
  398. package/dist/core/agent/workflows/adopt.js.map +1 -0
  399. package/dist/core/agent/workflows/check.js +373 -0
  400. package/dist/core/agent/workflows/check.js.map +1 -0
  401. package/dist/core/agent/workflows/closing.js +323 -0
  402. package/dist/core/agent/workflows/closing.js.map +1 -0
  403. package/dist/core/agent/workflows/feature.js +220 -0
  404. package/dist/core/agent/workflows/feature.js.map +1 -0
  405. package/dist/core/agent/workflows/implement.js +188 -0
  406. package/dist/core/agent/workflows/implement.js.map +1 -0
  407. package/dist/core/agent/workflows/reference/authoring.js +311 -0
  408. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  409. package/dist/core/agent/workflows/reference/codes.js +67 -0
  410. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  411. package/dist/core/agent/workflows/reference/done-check.js +210 -0
  412. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  413. package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
  414. package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
  415. package/dist/core/agent/workflows/reference/reference.js +19 -0
  416. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  417. package/dist/core/agent/workflows/reference/spine.js +338 -0
  418. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  419. package/dist/core/asyncapi/baseline/plan.js +43 -0
  420. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  421. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  422. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  423. package/dist/core/asyncapi/depth.js +164 -0
  424. package/dist/core/asyncapi/depth.js.map +1 -0
  425. package/dist/core/asyncapi/digest.js +146 -0
  426. package/dist/core/asyncapi/digest.js.map +1 -0
  427. package/dist/core/asyncapi/merge/components.js +92 -0
  428. package/dist/core/asyncapi/merge/components.js.map +1 -0
  429. package/dist/core/asyncapi/merge/error.js +38 -0
  430. package/dist/core/asyncapi/merge/error.js.map +1 -0
  431. package/dist/core/asyncapi/merge/markers.js +290 -0
  432. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  433. package/dist/core/asyncapi/merge/merge.js +195 -0
  434. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  435. package/dist/core/asyncapi/merge/pin.js +83 -0
  436. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  437. package/dist/core/asyncapi/model.js +11 -0
  438. package/dist/core/asyncapi/model.js.map +1 -0
  439. package/dist/core/asyncapi/producers.js +50 -0
  440. package/dist/core/asyncapi/producers.js.map +1 -0
  441. package/dist/core/asyncapi/read.js +263 -0
  442. package/dist/core/asyncapi/read.js.map +1 -0
  443. package/dist/core/brief/brief.js +285 -0
  444. package/dist/core/brief/brief.js.map +1 -0
  445. package/dist/core/brief/checks.js +385 -0
  446. package/dist/core/brief/checks.js.map +1 -0
  447. package/dist/core/brief/landscape.js +273 -0
  448. package/dist/core/brief/landscape.js.map +1 -0
  449. package/dist/core/brief/map/extend.js +84 -0
  450. package/dist/core/brief/map/extend.js.map +1 -0
  451. package/dist/core/brief/map/owed.js +266 -0
  452. package/dist/core/brief/map/owed.js.map +1 -0
  453. package/dist/core/brief/targets.js +304 -0
  454. package/dist/core/brief/targets.js.map +1 -0
  455. package/dist/core/brief/unchecked.js +58 -0
  456. package/dist/core/brief/unchecked.js.map +1 -0
  457. package/dist/core/c4/arch.js +190 -0
  458. package/dist/core/c4/arch.js.map +1 -0
  459. package/dist/core/c4/direction/direction.js +114 -0
  460. package/dist/core/c4/direction/direction.js.map +1 -0
  461. package/dist/core/c4/likec4.js +243 -0
  462. package/dist/core/c4/likec4.js.map +1 -0
  463. package/dist/core/c4/locate/unlocated.js +150 -0
  464. package/dist/core/c4/locate/unlocated.js.map +1 -0
  465. package/dist/core/c4/parsed/deployment.js +160 -0
  466. package/dist/core/c4/parsed/deployment.js.map +1 -0
  467. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  468. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  469. package/dist/core/c4/parsed/specification.js +78 -0
  470. package/dist/core/c4/parsed/specification.js.map +1 -0
  471. package/dist/core/c4/parsed/values.js +110 -0
  472. package/dist/core/c4/parsed/values.js.map +1 -0
  473. package/dist/core/c4/parsed/view-ids.js +113 -0
  474. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  475. package/dist/core/c4/prefetch/fleet.js +134 -0
  476. package/dist/core/c4/prefetch/fleet.js.map +1 -0
  477. package/dist/core/c4/project/architecture.js +161 -0
  478. package/dist/core/c4/project/architecture.js.map +1 -0
  479. package/dist/core/c4/project/batch.js +140 -0
  480. package/dist/core/c4/project/batch.js.map +1 -0
  481. package/dist/core/c4/project/documents.js +89 -0
  482. package/dist/core/c4/project/documents.js.map +1 -0
  483. package/dist/core/c4/project/load.js +219 -0
  484. package/dist/core/c4/project/load.js.map +1 -0
  485. package/dist/core/c4/project/staged.js +277 -0
  486. package/dist/core/c4/project/staged.js.map +1 -0
  487. package/dist/core/c4/resolve/attested.js +0 -0
  488. package/dist/core/c4/resolve/attested.js.map +1 -0
  489. package/dist/core/c4/resolve/external.js +51 -0
  490. package/dist/core/c4/resolve/external.js.map +1 -0
  491. package/dist/core/c4/resolve/service.js +174 -0
  492. package/dist/core/c4/resolve/service.js.map +1 -0
  493. package/dist/core/c4/resolve/steps.js +290 -0
  494. package/dist/core/c4/resolve/steps.js.map +1 -0
  495. package/dist/core/c4/resolve/systems.js +154 -0
  496. package/dist/core/c4/resolve/systems.js.map +1 -0
  497. package/dist/core/c4/root-project/exclude.js +352 -0
  498. package/dist/core/c4/root-project/exclude.js.map +1 -0
  499. package/dist/core/c4/seed/fleet-file.js +201 -0
  500. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  501. package/dist/core/c4/seed/items.js +91 -0
  502. package/dist/core/c4/seed/items.js.map +1 -0
  503. package/dist/core/c4/seed/stamp.js +48 -0
  504. package/dist/core/c4/seed/stamp.js.map +1 -0
  505. package/dist/core/c4/seed/template.js +173 -0
  506. package/dist/core/c4/seed/template.js.map +1 -0
  507. package/dist/core/c4/service-model/created/models.js +96 -0
  508. package/dist/core/c4/service-model/created/models.js.map +1 -0
  509. package/dist/core/c4/service-model/documents.js +47 -0
  510. package/dist/core/c4/service-model/documents.js.map +1 -0
  511. package/dist/core/c4/service-model/fleet/extending.js +82 -0
  512. package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
  513. package/dist/core/c4/service-model/load.js +165 -0
  514. package/dist/core/c4/service-model/load.js.map +1 -0
  515. package/dist/core/c4/service-model/renderer.js +128 -0
  516. package/dist/core/c4/service-model/renderer.js.map +1 -0
  517. package/dist/core/c4/service-model/shape.js +106 -0
  518. package/dist/core/c4/service-model/shape.js.map +1 -0
  519. package/dist/core/c4/service-model/slice.js +188 -0
  520. package/dist/core/c4/service-model/slice.js.map +1 -0
  521. package/dist/core/c4/source-mask.js +369 -0
  522. package/dist/core/c4/source-mask.js.map +1 -0
  523. package/dist/core/c4/source-scan.js +308 -0
  524. package/dist/core/c4/source-scan.js.map +1 -0
  525. package/dist/core/c4/splice/authored-source.js +167 -0
  526. package/dist/core/c4/splice/authored-source.js.map +1 -0
  527. package/dist/core/c4/splice/contract.js +30 -0
  528. package/dist/core/c4/splice/contract.js.map +1 -0
  529. package/dist/core/c4/splice/delta-blocks.js +126 -0
  530. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  531. package/dist/core/c4/splice/identity/declared.js +87 -0
  532. package/dist/core/c4/splice/identity/declared.js.map +1 -0
  533. package/dist/core/c4/splice/identity/edges.js +73 -0
  534. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  535. package/dist/core/c4/splice/identity/existing.js +80 -0
  536. package/dist/core/c4/splice/identity/existing.js.map +1 -0
  537. package/dist/core/c4/splice/identity/interior.js +80 -0
  538. package/dist/core/c4/splice/identity/interior.js.map +1 -0
  539. package/dist/core/c4/splice/identity/owner.js +50 -0
  540. package/dist/core/c4/splice/identity/owner.js.map +1 -0
  541. package/dist/core/c4/splice/landscape-merge.js +337 -0
  542. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  543. package/dist/core/c4/splice/model/merge.js +151 -0
  544. package/dist/core/c4/splice/model/merge.js.map +1 -0
  545. package/dist/core/c4/splice/placement.js +298 -0
  546. package/dist/core/c4/splice/placement.js.map +1 -0
  547. package/dist/core/c4/splice/text/spot.js +131 -0
  548. package/dist/core/c4/splice/text/spot.js.map +1 -0
  549. package/dist/core/c4/workspace.js +166 -0
  550. package/dist/core/c4/workspace.js.map +1 -0
  551. package/dist/core/capabilities/authoring/notes.js +141 -0
  552. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  553. package/dist/core/capabilities/capabilities.js +124 -0
  554. package/dist/core/capabilities/capabilities.js.map +1 -0
  555. package/dist/core/capabilities/delta/doc.js +47 -0
  556. package/dist/core/capabilities/delta/doc.js.map +1 -0
  557. package/dist/core/capabilities/delta/overlay.js +129 -0
  558. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  559. package/dist/core/capabilities/delta/summary.js +57 -0
  560. package/dist/core/capabilities/delta/summary.js.map +1 -0
  561. package/dist/core/capabilities/delta/tree.js +43 -0
  562. package/dist/core/capabilities/delta/tree.js.map +1 -0
  563. package/dist/core/capabilities/delta/uncovered.js +222 -0
  564. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  565. package/dist/core/capabilities/findings.js +338 -0
  566. package/dist/core/capabilities/findings.js.map +1 -0
  567. package/dist/core/capabilities/realizes/findings.js +174 -0
  568. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  569. package/dist/core/capabilities/realizes/join.js +123 -0
  570. package/dist/core/capabilities/realizes/join.js.map +1 -0
  571. package/dist/core/capabilities/rollup.js +205 -0
  572. package/dist/core/capabilities/rollup.js.map +1 -0
  573. package/dist/core/capabilities/tree.js +104 -0
  574. package/dist/core/capabilities/tree.js.map +1 -0
  575. package/dist/core/capabilities/usecase-join.js +267 -0
  576. package/dist/core/capabilities/usecase-join.js.map +1 -0
  577. package/dist/core/coherence/authoring/scaffold.js +185 -0
  578. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  579. package/dist/core/coherence/authoring/sentinels.js +75 -0
  580. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  581. package/dist/core/coherence/calls/called.js +52 -0
  582. package/dist/core/coherence/calls/called.js.map +1 -0
  583. package/dist/core/coherence/coherence.js +332 -0
  584. package/dist/core/coherence/coherence.js.map +1 -0
  585. package/dist/core/coherence/consumed/operations.js +70 -0
  586. package/dist/core/coherence/consumed/operations.js.map +1 -0
  587. package/dist/core/coherence/consumed/refusal.js +38 -0
  588. package/dist/core/coherence/consumed/refusal.js.map +1 -0
  589. package/dist/core/coherence/covers/health.js +85 -0
  590. package/dist/core/coherence/covers/health.js.map +1 -0
  591. package/dist/core/coherence/declared.js +295 -0
  592. package/dist/core/coherence/declared.js.map +1 -0
  593. package/dist/core/coherence/events/declared.js +191 -0
  594. package/dist/core/coherence/events/declared.js.map +1 -0
  595. package/dist/core/coherence/events/events.js +335 -0
  596. package/dist/core/coherence/events/events.js.map +1 -0
  597. package/dist/core/coherence/events/grades.js +189 -0
  598. package/dist/core/coherence/events/grades.js.map +1 -0
  599. package/dist/core/coherence/events/lookups.js +63 -0
  600. package/dist/core/coherence/events/lookups.js.map +1 -0
  601. package/dist/core/coherence/events/produced.js +100 -0
  602. package/dist/core/coherence/events/produced.js.map +1 -0
  603. package/dist/core/coherence/living.js +198 -0
  604. package/dist/core/coherence/living.js.map +1 -0
  605. package/dist/core/coherence/lookups.js +95 -0
  606. package/dist/core/coherence/lookups.js.map +1 -0
  607. package/dist/core/coherence/pending.js +39 -0
  608. package/dist/core/coherence/pending.js.map +1 -0
  609. package/dist/core/coherence/retired/archived.js +285 -0
  610. package/dist/core/coherence/retired/archived.js.map +1 -0
  611. package/dist/core/coherence/retired/event-pair.js +62 -0
  612. package/dist/core/coherence/retired/event-pair.js.map +1 -0
  613. package/dist/core/coherence/retired/merged.js +79 -0
  614. package/dist/core/coherence/retired/merged.js.map +1 -0
  615. package/dist/core/coherence/retired/retirement.js +49 -0
  616. package/dist/core/coherence/retired/retirement.js.map +1 -0
  617. package/dist/core/coherence/retired/revival/arrivals.js +131 -0
  618. package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
  619. package/dist/core/coherence/retired/revival/revived.js +297 -0
  620. package/dist/core/coherence/retired/revival/revived.js.map +1 -0
  621. package/dist/core/conflict-markers.js +60 -0
  622. package/dist/core/conflict-markers.js.map +1 -0
  623. package/dist/core/consumers/after.js +113 -0
  624. package/dist/core/consumers/after.js.map +1 -0
  625. package/dist/core/consumers/consumers.js +296 -0
  626. package/dist/core/consumers/consumers.js.map +1 -0
  627. package/dist/core/consumers/current.js +211 -0
  628. package/dist/core/consumers/current.js.map +1 -0
  629. package/dist/core/consumers/scan.js +46 -0
  630. package/dist/core/consumers/scan.js.map +1 -0
  631. package/dist/core/consumers/state.js +27 -0
  632. package/dist/core/consumers/state.js.map +1 -0
  633. package/dist/core/delta/claims.js +73 -0
  634. package/dist/core/delta/claims.js.map +1 -0
  635. package/dist/core/delta/delta.js +341 -0
  636. package/dist/core/delta/delta.js.map +1 -0
  637. package/dist/core/delta/document.js +177 -0
  638. package/dist/core/delta/document.js.map +1 -0
  639. package/dist/core/delta/scope.js +48 -0
  640. package/dist/core/delta/scope.js.map +1 -0
  641. package/dist/core/delta/select.js +237 -0
  642. package/dist/core/delta/select.js.map +1 -0
  643. package/dist/core/dependencies/dependencies.js +141 -0
  644. package/dist/core/dependencies/dependencies.js.map +1 -0
  645. package/dist/core/dependencies/facts.js +165 -0
  646. package/dist/core/dependencies/facts.js.map +1 -0
  647. package/dist/core/dependencies/fanin.js +88 -0
  648. package/dist/core/dependencies/fanin.js.map +1 -0
  649. package/dist/core/dependencies/graph.js +106 -0
  650. package/dist/core/dependencies/graph.js.map +1 -0
  651. package/dist/core/deployment/delta.js +191 -0
  652. package/dist/core/deployment/delta.js.map +1 -0
  653. package/dist/core/deployment/objects.js +145 -0
  654. package/dist/core/deployment/objects.js.map +1 -0
  655. package/dist/core/diff/base-git.js +230 -0
  656. package/dist/core/diff/base-git.js.map +1 -0
  657. package/dist/core/diff/base-state.js +237 -0
  658. package/dist/core/diff/base-state.js.map +1 -0
  659. package/dist/core/diff/joins.js +136 -0
  660. package/dist/core/diff/joins.js.map +1 -0
  661. package/dist/core/diff/scope/changed-paths.js +204 -0
  662. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  663. package/dist/core/diff/scope/edges.js +82 -0
  664. package/dist/core/diff/scope/edges.js.map +1 -0
  665. package/dist/core/diff/semantic.js +312 -0
  666. package/dist/core/diff/semantic.js.map +1 -0
  667. package/dist/core/docs.js +37 -85
  668. package/dist/core/docs.js.map +1 -1
  669. package/dist/core/doctor/agents.js +238 -0
  670. package/dist/core/doctor/agents.js.map +1 -0
  671. package/dist/core/doctor/config.js +139 -0
  672. package/dist/core/doctor/config.js.map +1 -0
  673. package/dist/core/doctor/doctor.js +355 -0
  674. package/dist/core/doctor/doctor.js.map +1 -0
  675. package/dist/core/doctor/report.js +13 -0
  676. package/dist/core/doctor/report.js.map +1 -0
  677. package/dist/core/doctor/reports/scan.js +242 -0
  678. package/dist/core/doctor/reports/scan.js.map +1 -0
  679. package/dist/core/doctor/residue.js +110 -0
  680. package/dist/core/doctor/residue.js.map +1 -0
  681. package/dist/core/document/apply.js +224 -0
  682. package/dist/core/document/apply.js.map +1 -0
  683. package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
  684. package/dist/core/document/frontmatter.js.map +1 -0
  685. package/dist/core/document/grammar/directives.js +143 -0
  686. package/dist/core/document/grammar/directives.js.map +1 -0
  687. package/dist/core/document/parse.js +286 -0
  688. package/dist/core/document/parse.js.map +1 -0
  689. package/dist/core/document/scenarios.js +238 -0
  690. package/dist/core/document/scenarios.js.map +1 -0
  691. package/dist/core/document/spec.js +234 -0
  692. package/dist/core/document/spec.js.map +1 -0
  693. package/dist/core/{config.js → envelope/config.js} +89 -18
  694. package/dist/core/envelope/config.js.map +1 -0
  695. package/dist/core/envelope/json.js +209 -0
  696. package/dist/core/envelope/json.js.map +1 -0
  697. package/dist/core/{version.js → envelope/version.js} +3 -3
  698. package/dist/core/envelope/version.js.map +1 -0
  699. package/dist/core/explain/families.js +180 -0
  700. package/dist/core/explain/families.js.map +1 -0
  701. package/dist/core/explain/fix-tables.js +178 -0
  702. package/dist/core/explain/fix-tables.js.map +1 -0
  703. package/dist/core/explain/lookup.js +194 -0
  704. package/dist/core/explain/lookup.js.map +1 -0
  705. package/dist/core/explain/refusals.js +49 -0
  706. package/dist/core/explain/refusals.js.map +1 -0
  707. package/dist/core/explain/terms/documents.js +227 -0
  708. package/dist/core/explain/terms/documents.js.map +1 -0
  709. package/dist/core/explain/terms/done-check.js +144 -0
  710. package/dist/core/explain/terms/done-check.js.map +1 -0
  711. package/dist/core/explain/terms/entry.js +14 -0
  712. package/dist/core/explain/terms/entry.js.map +1 -0
  713. package/dist/core/explain/terms/stages.js +71 -0
  714. package/dist/core/explain/terms/stages.js.map +1 -0
  715. package/dist/core/explain/terms/tasks.js +97 -0
  716. package/dist/core/explain/terms/tasks.js.map +1 -0
  717. package/dist/core/explain/terms.js +103 -0
  718. package/dist/core/explain/terms.js.map +1 -0
  719. package/dist/core/explore/describe.js +105 -0
  720. package/dist/core/explore/describe.js.map +1 -0
  721. package/dist/core/explore/explore.js +204 -0
  722. package/dist/core/explore/explore.js.map +1 -0
  723. package/dist/core/fleet-context.js +174 -146
  724. package/dist/core/fleet-context.js.map +1 -1
  725. package/dist/core/gate/checks.js +208 -0
  726. package/dist/core/gate/checks.js.map +1 -0
  727. package/dist/core/gate/partners.js +246 -0
  728. package/dist/core/gate/partners.js.map +1 -0
  729. package/dist/core/gate/report.js +47 -0
  730. package/dist/core/gate/report.js.map +1 -0
  731. package/dist/core/gate/verification.js +176 -0
  732. package/dist/core/gate/verification.js.map +1 -0
  733. package/dist/core/gherkin/digest.js +60 -0
  734. package/dist/core/gherkin/digest.js.map +1 -0
  735. package/dist/core/gherkin/emit.js +177 -0
  736. package/dist/core/gherkin/emit.js.map +1 -0
  737. package/dist/core/gherkin/read.js +76 -0
  738. package/dist/core/gherkin/read.js.map +1 -0
  739. package/dist/core/gherkin/stale.js +210 -0
  740. package/dist/core/gherkin/stale.js.map +1 -0
  741. package/dist/core/gherkin/stamp.js +77 -0
  742. package/dist/core/gherkin/stamp.js.map +1 -0
  743. package/dist/core/gherkin/steps/catalogue.js +154 -0
  744. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  745. package/dist/core/gherkin/steps/inventory.js +98 -0
  746. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  747. package/dist/core/gherkin/steps/phrase.js +72 -0
  748. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  749. package/dist/core/glossary/delta.js +109 -0
  750. package/dist/core/glossary/delta.js.map +1 -0
  751. package/dist/core/glossary/tree.js +73 -0
  752. package/dist/core/glossary/tree.js.map +1 -0
  753. package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
  754. package/dist/core/kernel/concurrency.js.map +1 -0
  755. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  756. package/dist/core/kernel/document-bytes.js.map +1 -0
  757. package/dist/core/kernel/fences.js +42 -0
  758. package/dist/core/kernel/fences.js.map +1 -0
  759. package/dist/core/kernel/ids/capability.js +72 -0
  760. package/dist/core/kernel/ids/capability.js.map +1 -0
  761. package/dist/core/kernel/ids/dirs.js +33 -0
  762. package/dist/core/kernel/ids/dirs.js.map +1 -0
  763. package/dist/core/kernel/ids/feature.js +75 -0
  764. package/dist/core/kernel/ids/feature.js.map +1 -0
  765. package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
  766. package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
  767. package/dist/core/kernel/ids/service.js +156 -0
  768. package/dist/core/kernel/ids/service.js.map +1 -0
  769. package/dist/core/kernel/ids/subsystem.js +63 -0
  770. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  771. package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
  772. package/dist/core/kernel/path-safety.js.map +1 -0
  773. package/dist/core/{records.js → kernel/records.js} +11 -0
  774. package/dist/core/kernel/records.js.map +1 -0
  775. package/dist/core/links/backlinks.js +66 -0
  776. package/dist/core/links/backlinks.js.map +1 -0
  777. package/dist/core/links/case.js +74 -0
  778. package/dist/core/links/case.js.map +1 -0
  779. package/dist/core/links/corpus.js +118 -0
  780. package/dist/core/links/corpus.js.map +1 -0
  781. package/dist/core/links/findings.js +110 -0
  782. package/dist/core/links/findings.js.map +1 -0
  783. package/dist/core/links/parse.js +265 -0
  784. package/dist/core/links/parse.js.map +1 -0
  785. package/dist/core/mcp/argv.js +212 -0
  786. package/dist/core/mcp/argv.js.map +1 -0
  787. package/dist/core/mcp/author-tools.js +73 -0
  788. package/dist/core/mcp/author-tools.js.map +1 -0
  789. package/dist/core/mcp/framing.js +46 -0
  790. package/dist/core/mcp/framing.js.map +1 -0
  791. package/dist/core/mcp/protocol.js +280 -0
  792. package/dist/core/mcp/protocol.js.map +1 -0
  793. package/dist/core/mcp/tools.js +324 -0
  794. package/dist/core/mcp/tools.js.map +1 -0
  795. package/dist/core/obligations/obligations.js +106 -0
  796. package/dist/core/obligations/obligations.js.map +1 -0
  797. package/dist/core/openapi/baseline/gate.js +207 -0
  798. package/dist/core/openapi/baseline/gate.js.map +1 -0
  799. package/dist/core/openapi/baseline/plan.js +142 -0
  800. package/dist/core/openapi/baseline/plan.js.map +1 -0
  801. package/dist/core/openapi/baseline/record.js +174 -0
  802. package/dist/core/openapi/baseline/record.js.map +1 -0
  803. package/dist/core/openapi/contract-text.js +33 -0
  804. package/dist/core/openapi/contract-text.js.map +1 -0
  805. package/dist/core/openapi/contract-tree.js +301 -0
  806. package/dist/core/openapi/contract-tree.js.map +1 -0
  807. package/dist/core/openapi/depth.js +136 -0
  808. package/dist/core/openapi/depth.js.map +1 -0
  809. package/dist/core/openapi/digest.js +239 -0
  810. package/dist/core/openapi/digest.js.map +1 -0
  811. package/dist/core/{openapi.js → openapi/doc.js} +54 -108
  812. package/dist/core/openapi/doc.js.map +1 -0
  813. package/dist/core/openapi/merge/components.js +199 -0
  814. package/dist/core/openapi/merge/components.js.map +1 -0
  815. package/dist/core/openapi/merge/error.js +16 -0
  816. package/dist/core/openapi/merge/error.js.map +1 -0
  817. package/dist/core/openapi/merge/markers.js +204 -0
  818. package/dist/core/openapi/merge/markers.js.map +1 -0
  819. package/dist/core/openapi/merge/merge.js +232 -0
  820. package/dist/core/openapi/merge/merge.js.map +1 -0
  821. package/dist/core/openapi/merge/pin.js +110 -0
  822. package/dist/core/openapi/merge/pin.js.map +1 -0
  823. package/dist/core/openspec/decide/capabilities.js +244 -0
  824. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  825. package/dist/core/openspec/decide/dispositions.js +63 -0
  826. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  827. package/dist/core/openspec/decide/renames.js +179 -0
  828. package/dist/core/openspec/decide/renames.js.map +1 -0
  829. package/dist/core/openspec/decide/verdict.js +84 -0
  830. package/dist/core/openspec/decide/verdict.js.map +1 -0
  831. package/dist/core/openspec/inventory.js +220 -0
  832. package/dist/core/openspec/inventory.js.map +1 -0
  833. package/dist/core/openspec/model/mapping.js +78 -0
  834. package/dist/core/openspec/model/mapping.js.map +1 -0
  835. package/dist/core/openspec/model/model.js +70 -0
  836. package/dist/core/openspec/model/model.js.map +1 -0
  837. package/dist/core/openspec/scan/changes.js +241 -0
  838. package/dist/core/openspec/scan/changes.js.map +1 -0
  839. package/dist/core/openspec/scan/config.js +191 -0
  840. package/dist/core/openspec/scan/config.js.map +1 -0
  841. package/dist/core/openspec/scan/shape.js +304 -0
  842. package/dist/core/openspec/scan/shape.js.map +1 -0
  843. package/dist/core/openspec/scan/walk.js +116 -0
  844. package/dist/core/openspec/scan/walk.js.map +1 -0
  845. package/dist/core/openspec/scan/workspace.js +71 -0
  846. package/dist/core/openspec/scan/workspace.js.map +1 -0
  847. package/dist/core/owners/codeowners.js +141 -0
  848. package/dist/core/owners/codeowners.js.map +1 -0
  849. package/dist/core/pack/features.js +120 -0
  850. package/dist/core/pack/features.js.map +1 -0
  851. package/dist/core/pack/joins.js +112 -0
  852. package/dist/core/pack/joins.js.map +1 -0
  853. package/dist/core/pack/living.js +157 -0
  854. package/dist/core/pack/living.js.map +1 -0
  855. package/dist/core/pack/pack.js +120 -0
  856. package/dist/core/pack/pack.js.map +1 -0
  857. package/dist/core/permissions/permissions.js +87 -0
  858. package/dist/core/permissions/permissions.js.map +1 -0
  859. package/dist/core/projection/api.js +84 -0
  860. package/dist/core/projection/api.js.map +1 -0
  861. package/dist/core/projection/arch-slice.js +63 -0
  862. package/dist/core/projection/arch-slice.js.map +1 -0
  863. package/dist/core/projection/events.js +34 -0
  864. package/dist/core/projection/events.js.map +1 -0
  865. package/dist/core/projection/introduced.js +14 -0
  866. package/dist/core/projection/introduced.js.map +1 -0
  867. package/dist/core/provenance/findings.js +244 -0
  868. package/dist/core/provenance/findings.js.map +1 -0
  869. package/dist/core/provenance/git.js +201 -0
  870. package/dist/core/provenance/git.js.map +1 -0
  871. package/dist/core/provenance/gitq/moves.js +139 -0
  872. package/dist/core/provenance/gitq/moves.js.map +1 -0
  873. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  874. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  875. package/dist/core/provenance/sample/scope.js +238 -0
  876. package/dist/core/provenance/sample/scope.js.map +1 -0
  877. package/dist/core/provenance/sample/sections.js +61 -0
  878. package/dist/core/provenance/sample/sections.js.map +1 -0
  879. package/dist/core/provenance/sources.js +280 -0
  880. package/dist/core/provenance/sources.js.map +1 -0
  881. package/dist/core/provenance/stamp.js +220 -0
  882. package/dist/core/provenance/stamp.js.map +1 -0
  883. package/dist/core/provenance/walk.js +157 -0
  884. package/dist/core/provenance/walk.js.map +1 -0
  885. package/dist/core/repo/authored/paths.js +210 -0
  886. package/dist/core/repo/authored/paths.js.map +1 -0
  887. package/dist/core/repo/entries.js +126 -0
  888. package/dist/core/repo/entries.js.map +1 -0
  889. package/dist/core/repo/paths.js +322 -0
  890. package/dist/core/repo/paths.js.map +1 -0
  891. package/dist/core/repo/repo.js +308 -0
  892. package/dist/core/repo/repo.js.map +1 -0
  893. package/dist/core/repo/service-target.js +153 -0
  894. package/dist/core/repo/service-target.js.map +1 -0
  895. package/dist/core/repo/state.js +58 -0
  896. package/dist/core/repo/state.js.map +1 -0
  897. package/dist/core/repo/tree/find.js +61 -0
  898. package/dist/core/repo/tree/find.js.map +1 -0
  899. package/dist/core/repo/tree/fs.js +90 -0
  900. package/dist/core/repo/tree/fs.js.map +1 -0
  901. package/dist/core/repo/tree/marker.js +61 -0
  902. package/dist/core/repo/tree/marker.js.map +1 -0
  903. package/dist/core/repo/tree/render/body.js +258 -0
  904. package/dist/core/repo/tree/render/body.js.map +1 -0
  905. package/dist/core/repo/tree/render/projects.js +182 -0
  906. package/dist/core/repo/tree/render/projects.js.map +1 -0
  907. package/dist/core/repo/tree/render/service/header.js +125 -0
  908. package/dist/core/repo/tree/render/service/header.js.map +1 -0
  909. package/dist/core/repo/tree/render/service/peers.js +28 -0
  910. package/dist/core/repo/tree/render/service/peers.js.map +1 -0
  911. package/dist/core/repo/tree/render/service/view-id.js +67 -0
  912. package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
  913. package/dist/core/repo/tree/render/service/views.js +78 -0
  914. package/dist/core/repo/tree/render/service/views.js.map +1 -0
  915. package/dist/core/repo/tree/render/stale.js +42 -0
  916. package/dist/core/repo/tree/render/stale.js.map +1 -0
  917. package/dist/core/repo/tree/render/text.js +84 -0
  918. package/dist/core/repo/tree/render/text.js.map +1 -0
  919. package/dist/core/repo/tree/render/views.js +293 -0
  920. package/dist/core/repo/tree/render/views.js.map +1 -0
  921. package/dist/core/repo/tree/walk.js +255 -0
  922. package/dist/core/repo/tree/walk.js.map +1 -0
  923. package/dist/core/results.js +146 -14
  924. package/dist/core/results.js.map +1 -1
  925. package/dist/core/scaffold/landscape.js +239 -0
  926. package/dist/core/scaffold/landscape.js.map +1 -0
  927. package/dist/core/scaffold/legacy.js +271 -0
  928. package/dist/core/scaffold/legacy.js.map +1 -0
  929. package/dist/core/scaffold/readme.js +84 -0
  930. package/dist/core/scaffold/readme.js.map +1 -0
  931. package/dist/core/staging/commit.js +252 -0
  932. package/dist/core/staging/commit.js.map +1 -0
  933. package/dist/core/staging/interrupted.js +96 -0
  934. package/dist/core/staging/interrupted.js.map +1 -0
  935. package/dist/core/staging/lock.js +268 -0
  936. package/dist/core/staging/lock.js.map +1 -0
  937. package/dist/core/staging/recovery/finding.js +35 -0
  938. package/dist/core/staging/recovery/finding.js.map +1 -0
  939. package/dist/core/staging/recovery/intent.js +95 -0
  940. package/dist/core/staging/recovery/intent.js.map +1 -0
  941. package/dist/core/staging/recovery/recover.js +204 -0
  942. package/dist/core/staging/recovery/recover.js.map +1 -0
  943. package/dist/core/staging/recovery/residue.js +62 -0
  944. package/dist/core/staging/recovery/residue.js.map +1 -0
  945. package/dist/core/staging/snapshot/manifest.js +188 -0
  946. package/dist/core/staging/snapshot/manifest.js.map +1 -0
  947. package/dist/core/staging/snapshot/snapshot.js +196 -0
  948. package/dist/core/staging/snapshot/snapshot.js.map +1 -0
  949. package/dist/core/staging/txn/forward.js +181 -0
  950. package/dist/core/staging/txn/forward.js.map +1 -0
  951. package/dist/core/staging/txn/journal.js +139 -0
  952. package/dist/core/staging/txn/journal.js.map +1 -0
  953. package/dist/core/staging/txn/transaction.js +75 -0
  954. package/dist/core/staging/txn/transaction.js.map +1 -0
  955. package/dist/core/staging/writes.js +113 -0
  956. package/dist/core/staging/writes.js.map +1 -0
  957. package/dist/core/status/actions/execution.js +60 -0
  958. package/dist/core/status/actions/execution.js.map +1 -0
  959. package/dist/core/status/contracts.js +126 -0
  960. package/dist/core/status/contracts.js.map +1 -0
  961. package/dist/core/status/feature/artifacts.js +196 -0
  962. package/dist/core/status/feature/artifacts.js.map +1 -0
  963. package/dist/core/status/feature/feature.js +214 -0
  964. package/dist/core/status/feature/feature.js.map +1 -0
  965. package/dist/core/status/feature/next.js +163 -0
  966. package/dist/core/status/feature/next.js.map +1 -0
  967. package/dist/core/status/feature/state.js +21 -0
  968. package/dist/core/status/feature/state.js.map +1 -0
  969. package/dist/core/status/feature/words.js +96 -0
  970. package/dist/core/status/feature/words.js.map +1 -0
  971. package/dist/core/status/fleet/fleet.js +216 -0
  972. package/dist/core/status/fleet/fleet.js.map +1 -0
  973. package/dist/core/status/fleet/next.js +302 -0
  974. package/dist/core/status/fleet/next.js.map +1 -0
  975. package/dist/core/status/interrupted.js +97 -0
  976. package/dist/core/status/interrupted.js.map +1 -0
  977. package/dist/core/status/report.js +31 -0
  978. package/dist/core/status/report.js.map +1 -0
  979. package/dist/core/status/scan.js +41 -0
  980. package/dist/core/status/scan.js.map +1 -0
  981. package/dist/core/status/verification.js +216 -0
  982. package/dist/core/status/verification.js.map +1 -0
  983. package/dist/core/tasks/packet.js +199 -0
  984. package/dist/core/tasks/packet.js.map +1 -0
  985. package/dist/core/tasks/record.js +43 -0
  986. package/dist/core/tasks/record.js.map +1 -0
  987. package/dist/core/tasks/sources.js +181 -0
  988. package/dist/core/tasks/sources.js.map +1 -0
  989. package/dist/core/tasks/stamps.js +76 -0
  990. package/dist/core/tasks/stamps.js.map +1 -0
  991. package/dist/core/tasks/unit.js +0 -0
  992. package/dist/core/tasks/unit.js.map +1 -0
  993. package/dist/core/usecases/capability.js +166 -0
  994. package/dist/core/usecases/capability.js.map +1 -0
  995. package/dist/core/usecases/delta/claims.js +140 -0
  996. package/dist/core/usecases/delta/claims.js.map +1 -0
  997. package/dist/core/usecases/delta/flows.js +101 -0
  998. package/dist/core/usecases/delta/flows.js.map +1 -0
  999. package/dist/core/usecases/delta/modified.js +315 -0
  1000. package/dist/core/usecases/delta/modified.js.map +1 -0
  1001. package/dist/core/usecases/delta/overlay.js +76 -0
  1002. package/dist/core/usecases/delta/overlay.js.map +1 -0
  1003. package/dist/core/usecases/fleet.js +296 -0
  1004. package/dist/core/usecases/fleet.js.map +1 -0
  1005. package/dist/core/usecases/grade/capability-tag.js +93 -0
  1006. package/dist/core/usecases/grade/capability-tag.js.map +1 -0
  1007. package/dist/core/usecases/grade/feature.js +88 -0
  1008. package/dist/core/usecases/grade/feature.js.map +1 -0
  1009. package/dist/core/usecases/grade/requirement-tag.js +94 -0
  1010. package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
  1011. package/dist/core/usecases/grade/steps.js +266 -0
  1012. package/dist/core/usecases/grade/steps.js.map +1 -0
  1013. package/dist/core/usecases/grade/usecases.js +112 -0
  1014. package/dist/core/usecases/grade/usecases.js.map +1 -0
  1015. package/dist/core/usecases/operations.js +123 -0
  1016. package/dist/core/usecases/operations.js.map +1 -0
  1017. package/dist/core/usecases/place.js +44 -0
  1018. package/dist/core/usecases/place.js.map +1 -0
  1019. package/dist/core/usecases/service/exclude.js +119 -0
  1020. package/dist/core/usecases/service/exclude.js.map +1 -0
  1021. package/dist/core/usecases/service/flows.js +164 -0
  1022. package/dist/core/usecases/service/flows.js.map +1 -0
  1023. package/dist/core/usecases/suites/participants.js +83 -0
  1024. package/dist/core/usecases/suites/participants.js.map +1 -0
  1025. package/dist/core/usecases/suites/suites.js +45 -0
  1026. package/dist/core/usecases/suites/suites.js.map +1 -0
  1027. package/dist/core/usecases/touch.js +101 -0
  1028. package/dist/core/usecases/touch.js.map +1 -0
  1029. package/dist/core/verify/answers.js +180 -0
  1030. package/dist/core/verify/answers.js.map +1 -0
  1031. package/dist/core/verify/build.js +170 -0
  1032. package/dist/core/verify/build.js.map +1 -0
  1033. package/dist/core/verify/checklist.js +259 -0
  1034. package/dist/core/verify/checklist.js.map +1 -0
  1035. package/dist/core/verify/claims/identity.js +61 -0
  1036. package/dist/core/verify/claims/identity.js.map +1 -0
  1037. package/dist/core/verify/cross/diff.js +97 -0
  1038. package/dist/core/verify/cross/diff.js.map +1 -0
  1039. package/dist/core/verify/evidence/contract.js +169 -0
  1040. package/dist/core/verify/evidence/contract.js.map +1 -0
  1041. package/dist/core/verify/location.js +67 -0
  1042. package/dist/core/verify/location.js.map +1 -0
  1043. package/dist/core/verify/pins/lint.js +158 -0
  1044. package/dist/core/verify/pins/lint.js.map +1 -0
  1045. package/dist/core/verify/pins/pin.js +95 -0
  1046. package/dist/core/verify/pins/pin.js.map +1 -0
  1047. package/dist/core/verify/read/file.js +224 -0
  1048. package/dist/core/verify/read/file.js.map +1 -0
  1049. package/dist/core/verify/read/shape.js +169 -0
  1050. package/dist/core/verify/read/shape.js.map +1 -0
  1051. package/dist/core/verify/read/union.js +105 -0
  1052. package/dist/core/verify/read/union.js.map +1 -0
  1053. package/dist/core/verify/record.js +165 -0
  1054. package/dist/core/verify/record.js.map +1 -0
  1055. package/dist/core/verify/store/commit.js +99 -0
  1056. package/dist/core/verify/store/commit.js.map +1 -0
  1057. package/dist/core/verify/store/render.js +61 -0
  1058. package/dist/core/verify/store/render.js.map +1 -0
  1059. package/dist/core/vocabulary/health.js +91 -0
  1060. package/dist/core/vocabulary/health.js.map +1 -0
  1061. package/dist/core/vocabulary/issue.js +59 -0
  1062. package/dist/core/vocabulary/issue.js.map +1 -0
  1063. package/dist/core/vocabulary/maturity.js +216 -0
  1064. package/dist/core/vocabulary/maturity.js.map +1 -0
  1065. package/dist/core/vocabulary/report.js +90 -0
  1066. package/dist/core/vocabulary/report.js.map +1 -0
  1067. package/dist/core/vocabulary/steps.js +266 -0
  1068. package/dist/core/vocabulary/steps.js.map +1 -0
  1069. package/dist/core/workspace/discover.js +239 -0
  1070. package/dist/core/workspace/discover.js.map +1 -0
  1071. package/dist/core/workspace/render.js +52 -0
  1072. package/dist/core/workspace/render.js.map +1 -0
  1073. package/examples/README.md +232 -0
  1074. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  1075. package/examples/docs/architecture/capabilities.yaml +31 -0
  1076. package/examples/docs/architecture/landscape.likec4 +336 -0
  1077. package/examples/docs/architecture/obligations.yaml +23 -0
  1078. package/examples/docs/architecture/permissions.yaml +50 -0
  1079. package/examples/docs/architecture/services.likec4 +70 -0
  1080. package/examples/docs/architecture/subsystems.likec4 +18 -0
  1081. package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
  1082. package/examples/docs/capabilities/checkout/spec.md +55 -0
  1083. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  1084. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  1085. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  1086. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  1087. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  1088. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  1089. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
  1090. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  1091. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  1092. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  1093. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  1094. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  1095. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
  1096. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  1097. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  1098. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  1099. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  1100. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  1101. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  1102. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  1103. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  1104. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  1105. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  1106. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
  1107. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  1108. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  1109. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  1110. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  1111. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  1112. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  1113. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  1114. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  1115. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  1116. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  1117. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  1118. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  1119. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  1120. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  1121. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  1122. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  1123. package/examples/docs/glossary/order.md +15 -0
  1124. package/examples/docs/glossary/payments/authorization.md +14 -0
  1125. package/examples/docs/likec4.config.json +8 -0
  1126. package/examples/docs/loam.json +3 -0
  1127. package/examples/docs/services/checkout-web/model.likec4 +92 -0
  1128. package/examples/docs/services/checkout-web/spec.md +91 -0
  1129. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  1130. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  1131. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  1132. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  1133. package/examples/docs/services/order-service/arch.spec.md +134 -0
  1134. package/examples/docs/services/order-service/asyncapi.yaml +109 -0
  1135. package/examples/docs/services/order-service/health.yaml +57 -0
  1136. package/examples/docs/services/order-service/model.likec4 +126 -0
  1137. package/examples/docs/services/order-service/openapi.yaml +257 -0
  1138. package/examples/docs/services/order-service/runbook.md +62 -0
  1139. package/examples/docs/services/order-service/spec.md +134 -0
  1140. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  1141. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  1142. package/examples/docs/services/payment-service/arch.spec.md +76 -0
  1143. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  1144. package/examples/docs/services/payment-service/health.yaml +39 -0
  1145. package/examples/docs/services/payment-service/model.likec4 +68 -0
  1146. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  1147. package/examples/docs/services/payment-service/runbook.md +37 -0
  1148. package/examples/docs/services/payment-service/spec.md +88 -0
  1149. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  1150. package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
  1151. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  1152. package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
  1153. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  1154. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  1155. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  1156. package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
  1157. package/examples/docs/services/platform/notification-service/health.yaml +40 -0
  1158. package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
  1159. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  1160. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  1161. package/examples/docs/services/platform/subsystem.yaml +2 -0
  1162. package/examples/fleet.yaml +57 -0
  1163. package/package.json +19 -6
  1164. package/dist/commands/adopt.js +0 -240
  1165. package/dist/commands/adopt.js.map +0 -1
  1166. package/dist/commands/archive.js +0 -1313
  1167. package/dist/commands/archive.js.map +0 -1
  1168. package/dist/commands/delta.js +0 -388
  1169. package/dist/commands/delta.js.map +0 -1
  1170. package/dist/commands/docs-repo-gate.js.map +0 -1
  1171. package/dist/commands/format.js +0 -17
  1172. package/dist/commands/format.js.map +0 -1
  1173. package/dist/commands/gherkin.js +0 -309
  1174. package/dist/commands/gherkin.js.map +0 -1
  1175. package/dist/commands/init.js.map +0 -1
  1176. package/dist/commands/list.js +0 -295
  1177. package/dist/commands/list.js.map +0 -1
  1178. package/dist/commands/migrate-openspec.js +0 -950
  1179. package/dist/commands/migrate-openspec.js.map +0 -1
  1180. package/dist/commands/new.js +0 -413
  1181. package/dist/commands/new.js.map +0 -1
  1182. package/dist/commands/rebase.js +0 -356
  1183. package/dist/commands/rebase.js.map +0 -1
  1184. package/dist/commands/show.js +0 -320
  1185. package/dist/commands/show.js.map +0 -1
  1186. package/dist/commands/status.js +0 -262
  1187. package/dist/commands/status.js.map +0 -1
  1188. package/dist/commands/unarchive.js +0 -317
  1189. package/dist/commands/unarchive.js.map +0 -1
  1190. package/dist/commands/validate.js +0 -1773
  1191. package/dist/commands/validate.js.map +0 -1
  1192. package/dist/commands/verify.js +0 -775
  1193. package/dist/commands/verify.js.map +0 -1
  1194. package/dist/commands/vouch.js +0 -421
  1195. package/dist/commands/vouch.js.map +0 -1
  1196. package/dist/core/agent.js +0 -2173
  1197. package/dist/core/agent.js.map +0 -1
  1198. package/dist/core/agents-stamp.js.map +0 -1
  1199. package/dist/core/arch.js +0 -130
  1200. package/dist/core/arch.js.map +0 -1
  1201. package/dist/core/asyncapi.js +0 -253
  1202. package/dist/core/asyncapi.js.map +0 -1
  1203. package/dist/core/brief.js +0 -755
  1204. package/dist/core/brief.js.map +0 -1
  1205. package/dist/core/coherence.js +0 -577
  1206. package/dist/core/coherence.js.map +0 -1
  1207. package/dist/core/concurrency.js.map +0 -1
  1208. package/dist/core/config.js.map +0 -1
  1209. package/dist/core/delta.js +0 -476
  1210. package/dist/core/delta.js.map +0 -1
  1211. package/dist/core/dependencies.js +0 -356
  1212. package/dist/core/dependencies.js.map +0 -1
  1213. package/dist/core/doctor.js +0 -596
  1214. package/dist/core/doctor.js.map +0 -1
  1215. package/dist/core/document-bytes.js.map +0 -1
  1216. package/dist/core/explore.js +0 -225
  1217. package/dist/core/explore.js.map +0 -1
  1218. package/dist/core/frontmatter.js.map +0 -1
  1219. package/dist/core/gherkin.js +0 -463
  1220. package/dist/core/gherkin.js.map +0 -1
  1221. package/dist/core/health.js +0 -67
  1222. package/dist/core/health.js.map +0 -1
  1223. package/dist/core/ids.js +0 -122
  1224. package/dist/core/ids.js.map +0 -1
  1225. package/dist/core/issue.js +0 -9
  1226. package/dist/core/issue.js.map +0 -1
  1227. package/dist/core/json.js +0 -74
  1228. package/dist/core/json.js.map +0 -1
  1229. package/dist/core/likec4.js +0 -489
  1230. package/dist/core/likec4.js.map +0 -1
  1231. package/dist/core/maturity.js +0 -66
  1232. package/dist/core/maturity.js.map +0 -1
  1233. package/dist/core/openapi-merge.js +0 -552
  1234. package/dist/core/openapi-merge.js.map +0 -1
  1235. package/dist/core/openapi.js.map +0 -1
  1236. package/dist/core/openspec-inventory.js +0 -1440
  1237. package/dist/core/openspec-inventory.js.map +0 -1
  1238. package/dist/core/path-safety.js.map +0 -1
  1239. package/dist/core/provenance.js +0 -787
  1240. package/dist/core/provenance.js.map +0 -1
  1241. package/dist/core/records.js.map +0 -1
  1242. package/dist/core/repo.js +0 -438
  1243. package/dist/core/repo.js.map +0 -1
  1244. package/dist/core/report.js +0 -47
  1245. package/dist/core/report.js.map +0 -1
  1246. package/dist/core/spec.js +0 -505
  1247. package/dist/core/spec.js.map +0 -1
  1248. package/dist/core/staging.js +0 -890
  1249. package/dist/core/staging.js.map +0 -1
  1250. package/dist/core/status.js +0 -1132
  1251. package/dist/core/status.js.map +0 -1
  1252. package/dist/core/steps.js +0 -72
  1253. package/dist/core/steps.js.map +0 -1
  1254. package/dist/core/verify.js +0 -807
  1255. package/dist/core/verify.js.map +0 -1
  1256. package/dist/core/version.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/commands/list/review.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The review-order gathering and sort behind `loam list --needs-work\n * --review-order`: per-service contract reads (contained per read), the one\n * landscape load, and the deterministic ordering. The derivation itself is\n * pure and lives in core/dependencies/fanin.ts.\n *\n * Fifth and LAST file of the list package — the next module added here forces\n * a split along a named seam (docs/CODE-STYLE.md, the five-file limit).\n */\nimport { existsSync } from \"node:fs\";\nimport { readAsyncapi } from \"../../core/asyncapi/read.js\";\nimport { type LoadedDoc } from \"../../core/c4/likec4.js\";\nimport { serviceResolver } from \"../../core/c4/resolve/service.js\";\nimport { fleetFanIn, type FanInContracts } from \"../../core/dependencies/fanin.js\";\nimport { type FleetContext } from \"../../core/fleet-context.js\";\nimport { inOrder } from \"../../core/kernel/concurrency.js\";\nimport { compareIds, type ServiceEntry } from \"../../core/repo/entries.js\";\nimport { landscapePath, servicePathsAt } from \"../../core/repo/paths.js\";\nimport { type ServiceView } from \"./views.js\";\nimport type { DocsDir } from \"../../core/kernel/ids/dirs.js\";\n\n/**\n * The landscape for the review path, loaded ONCE through the run's memo and\n * handed both to serviceViews (as `preloaded`) and to the fan-in joins — a\n * second parse of a document the run already holds is the cost the shared\n * load exists to retire.\n *\n * Deliberately NOT `readLandscape` from commands/validate/fleet/load.ts: that\n * import would add a list→validate/fleet package edge while\n * validate/fleet/scorecard→list already exists, and the containment is four\n * lines.\n */\nexport async function reviewLandscape(docsDir: DocsDir, fleet: FleetContext): Promise<LoadedDoc | null> {\n const lp = landscapePath(docsDir);\n // Absent is `null` — the same \"there is none\" serviceViews' own load\n // spells. An UNREADABLE file is deliberately not contained here: bare\n // `loam list` refuses `repository-unavailable` when serviceViews' load\n // throws on it, and a rendering flag must never change what the run\n // refuses — a swallowed throw here answered ok over the exact file the\n // flagless run refuses on, with rows CHANGED by the silent null\n // (`proven: false` flips apiExpected and the missing lists). The throw\n // reaches list.ts's existing handler, so both paths refuse identically.\n if (!existsSync(lp)) return null;\n return fleet.loadLikeC4(lp);\n}\n\n/**\n * One service's contract slice for the message join, contained PER READ, not\n * per slice. The distinction is somebody else's rank: a slice is a caller's\n * evidence about OTHER services' fan-in, not only its own row, so a slice\n * that discarded its readable spec.md because its arch.spec.md is broken\n * would silently under-report every producer that spec subscribes to.\n */\nasync function contractSlice(entry: ServiceEntry, fleet: FleetContext): Promise<FanInContracts> {\n const paths = servicePathsAt(entry.dir);\n const [sent, specConsumes, archConsumes] = await Promise.all([\n readOr([], async () => {\n const events = await readAsyncapi(paths.asyncapi, fleet);\n // An unreadable contract declares nothing this join may count —\n // swallowing it into its parsed subset would grade a broken file as a\n // thin one (the scorecard's contracts.ts spells the same rule).\n return events.unreadable === true ? ([] as readonly string[]) : events.sent;\n }),\n readOr([], () => livingConsumes(paths.spec, fleet)),\n readOr([], () => livingConsumes(paths.archSpec, fleet)),\n ]);\n return { sent, consumed: [...specConsumes, ...archConsumes] };\n}\n\n/** `Consumes:` names of a spec file's living requirements; absent file, nothing. */\nasync function livingConsumes(path: string, fleet: FleetContext): Promise<readonly string[]> {\n if (!existsSync(path)) return [];\n // A REMOVED requirement is on its way out and subscribes to nothing, from\n // either spec namespace.\n return (await fleet.readRequirements(path)).filter((r) => r.kind !== \"REMOVED\").flatMap((r) => r.consumes);\n}\n\n/**\n * The containment: an unreadable artifact contributes nothing — and ONLY that\n * artifact's evidence, per the doctrine above. The catch also exists for a\n * mechanical reason (commands/validate/fleet/scorecard/contracts.ts): these\n * are memoized reads whose REJECTION rejects again on every await, so an\n * uncontained one would delete the whole queue from inside the pool.\n */\nasync function readOr<T>(fallback: T, read: () => Promise<T>): Promise<T> {\n try {\n return await read();\n } catch {\n // Unreadable reads as \"declares nothing\" — never as a refusal, and never\n // as its neighbours' silence.\n return fallback;\n }\n}\n\n/**\n * Fan-in per service id, FLEET-WIDE — the joins need every service's slice\n * anyway; the caller ranks only the worklist, so vouched services carry a\n * count without occupying a rank.\n */\nexport async function fanInByService(\n services: ServiceEntry[],\n fleet: FleetContext,\n land: LoadedDoc | null,\n): Promise<Map<string, number>> {\n const known = new Set<string>(services.map((s) => s.id));\n const slices = await inOrder(services, async (s) => [s.id, await contractSlice(s, fleet)] as const);\n const request = {\n services: services.map((s) => s.id),\n contracts: new Map<string, FanInContracts>(slices),\n };\n if (land !== null && land.errors.length === 0) {\n return fleetFanIn({\n ...request,\n landscape: { parses: true, relationships: land.relationships, svcOf: serviceResolver(land.elements, known) },\n });\n }\n return fleetFanIn({ ...request, landscape: { parses: false } });\n}\n\n/**\n * The queue: fan-in descending, ties broken by id — fully deterministic, no\n * clocks, no readdir order, so two runs over one repository are byte-identical\n * (fan-in is a set size and both joins are order-insensitive).\n */\nexport function reviewOrder(views: ServiceView[], fanIn: ReadonlyMap<string, number>): ServiceView[] {\n return [...views].sort(\n (a, b) =>\n (fanIn.get(b.entry.id) ?? 0) - (fanIn.get(a.entry.id) ?? 0) || compareIds(a.entry.id, b.entry.id),\n );\n}\n"]}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * `loam list suites [<name>]` — which use cases run together, and WHICH
3
+ * SERVICES MUST BE UP for a suite's journeys to run.
4
+ *
5
+ * That answer is maintained by hand in most fleets — a compose file, a CI
6
+ * matrix, a paragraph in a runbook — and it is derivable, because a journey
7
+ * already names every participant it touches and the fleet map already says
8
+ * which `services/<id>/` each of those elements stands for. Deriving it means it
9
+ * cannot drift from the journeys: add a hop to a flow and the environment its
10
+ * suites need changes in the same commit. The grouping and the union are
11
+ * `core/usecases/suites/`; this module turns them into the section's payload
12
+ * and its text.
13
+ *
14
+ * A sub-package of list/ for `./campaign/`'s reason: the list package stands at
15
+ * its five-file limit. The direction is list → list/suites, never back.
16
+ *
17
+ * ONE SHAPE whether or not a suite was named. Naming one is a filter over the
18
+ * same answer, not a different question, so `suites[]` narrows and nothing else
19
+ * does — `ungrouped[]` in particular stays the fleet's, because which journeys
20
+ * reached no suite is not a fact about the suite being asked after.
21
+ *
22
+ * The use-case corpus's health travels as `useCases`, spelled as `list
23
+ * capabilities`, `status` and `delta` spell it (`unreadable`, `error`), plus a
24
+ * `state` this section needs and they do not: here the corpus IS the rows, so
25
+ * "the fleet declares no use case" (`absent`) and "loam read them" (`ok`) are
26
+ * two answers a reader has to be able to tell apart from one empty list. Over an
27
+ * unreadable `architecture/` the section DEGRADES rather than refusing, exactly
28
+ * as `list capabilities` does: `suites` and `ungrouped` are ABSENT keys — `[]`
29
+ * would be "loam looked and found none", said about a project nobody read — and
30
+ * a named suite is not refused as unknown, because that refusal would be a
31
+ * claim about suites loam never saw.
32
+ */
33
+ import { fail } from "../../../core/envelope/json.js";
34
+ import { listServices } from "../../../core/repo/repo.js";
35
+ import { closeNamesHint } from "../../../core/repo/tree/find.js";
36
+ import { readUseCases } from "../../../core/usecases/fleet.js";
37
+ import { viewFile } from "../../../core/usecases/place.js";
38
+ import { suiteListing } from "../../../core/usecases/suites/suites.js";
39
+ /**
40
+ * Read the fleet's use cases and group them, or refuse an unknown suite name.
41
+ *
42
+ * Returns `null` when it has already refused — the caller's cue to stop, the
43
+ * `resolveSubsystemSlice` convention one package over.
44
+ *
45
+ * The services are enumerated for the RESOLVER, not for the rows: the
46
+ * element→service join needs the fleet set for the reason every edge join does
47
+ * (`readUseCases`' `UseCaseRequest.known`), and without it a step into
48
+ * `orders.api` would resolve to a service called "api".
49
+ */
50
+ export async function suitesSection(req) {
51
+ const entries = await listServices(req.docsDir, req.fleet);
52
+ const scan = await readUseCases({ docsDir: req.docsDir, known: new Set(entries.map((e) => e.id)) });
53
+ if (scan.kind === "unreadable") {
54
+ const error = scan.errors[0];
55
+ return {
56
+ payload: { useCases: { state: "unreadable", unreadable: true, ...(error === undefined ? {} : { error }) } },
57
+ print: () => printUnreadable(error),
58
+ };
59
+ }
60
+ const listing = suiteListing(scan);
61
+ const state = scan.views.length === 0 ? "absent" : "ok";
62
+ const shown = req.name === undefined ? listing.suites : listing.suites.filter((s) => s.name === req.name);
63
+ if (req.name !== undefined && shown.length === 0) {
64
+ const names = listing.suites.map((s) => s.name);
65
+ // `unknown-target`, the code `--subsystem` and `show` use for a name that
66
+ // resolves to nothing, with the same close-name hint — an empty environment
67
+ // for a typo would read as a suite that needs nothing started.
68
+ fail(req.json, "unknown-target", `No suite '${req.name}'.` +
69
+ closeNamesHint(req.name, names, names.length === 0
70
+ ? " No use case under architecture/ carries a `#suite-` tag."
71
+ : ` Declared suites: ${names.join(", ")}.`));
72
+ return null;
73
+ }
74
+ return {
75
+ payload: {
76
+ suites: shown.map(suiteJson),
77
+ ungrouped: listing.ungrouped.map(viewJson),
78
+ useCases: { state, unreadable: false },
79
+ },
80
+ print: () => printSuites(shown, listing.ungrouped, state === "absent"),
81
+ };
82
+ }
83
+ /** A use case as the payload names it: enough to open the document it is written in. */
84
+ function viewJson(view) {
85
+ return { id: view.id, file: viewFile(view) };
86
+ }
87
+ function suiteJson(suite) {
88
+ return {
89
+ name: suite.name,
90
+ views: suite.views.map(viewJson),
91
+ services: suite.services,
92
+ unresolved: suite.unresolved,
93
+ };
94
+ }
95
+ /**
96
+ * One block per suite — its services, then the participants a stand cannot
97
+ * start — then the journeys in no suite.
98
+ *
99
+ * An unresolved participant gets a line of its own with a marker rather than
100
+ * being folded into the service list: it is not a service anybody can start,
101
+ * and reading it as one is how an environment comes up short.
102
+ */
103
+ function printSuites(suites, ungrouped, absent) {
104
+ if (absent) {
105
+ console.log("no use cases — no dynamic view under architecture/ carries #cap-, #req- or #suite-, so there are no suites");
106
+ return;
107
+ }
108
+ if (suites.length === 0)
109
+ console.log("no suites — no use case under architecture/ carries a #suite- tag");
110
+ for (const [i, suite] of suites.entries()) {
111
+ if (i > 0)
112
+ console.log("");
113
+ console.log(`suite ${suite.name} — ${suite.views.length} use case(s), ${suite.services.length} service(s) must be up`);
114
+ for (const service of suite.services)
115
+ console.log(` ${service}`);
116
+ for (const missing of suite.unresolved) {
117
+ console.log(` ! ${missing.element} — resolves to no service in services/` +
118
+ (missing.external ? " (#external: bring a double)" : ""));
119
+ }
120
+ console.log(` use cases: ${suite.views.map((v) => v.id).join(", ")}`);
121
+ }
122
+ console.log("");
123
+ console.log(`use cases in no suite (${ungrouped.length})`);
124
+ const width = Math.max(0, ...ungrouped.map((v) => v.id.length));
125
+ for (const view of ungrouped)
126
+ console.log(` ${view.id.padEnd(width)} ${viewFile(view)}`);
127
+ }
128
+ /**
129
+ * The `list capabilities` note, in this section's words: UNKNOWN rather than
130
+ * none, and the parser's own message on its own line, because a LikeC4 error is
131
+ * several lines of expected-token list and inlining it would push the sentence
132
+ * off the reader's screen.
133
+ */
134
+ function printUnreadable(error) {
135
+ console.log("note: architecture/ did not parse, so no use case could be read — " +
136
+ "which suites exist, and what each needs up, is UNKNOWN here, not none");
137
+ if (error !== undefined)
138
+ console.log(` ${error}`);
139
+ }
140
+ //# sourceMappingURL=suites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suites.js","sourceRoot":"","sources":["../../../../src/commands/list/suites/suites.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loam list suites [<name>]` — which use cases run together, and WHICH\n * SERVICES MUST BE UP for a suite's journeys to run.\n *\n * That answer is maintained by hand in most fleets — a compose file, a CI\n * matrix, a paragraph in a runbook — and it is derivable, because a journey\n * already names every participant it touches and the fleet map already says\n * which `services/<id>/` each of those elements stands for. Deriving it means it\n * cannot drift from the journeys: add a hop to a flow and the environment its\n * suites need changes in the same commit. The grouping and the union are\n * `core/usecases/suites/`; this module turns them into the section's payload\n * and its text.\n *\n * A sub-package of list/ for `./campaign/`'s reason: the list package stands at\n * its five-file limit. The direction is list → list/suites, never back.\n *\n * ONE SHAPE whether or not a suite was named. Naming one is a filter over the\n * same answer, not a different question, so `suites[]` narrows and nothing else\n * does — `ungrouped[]` in particular stays the fleet's, because which journeys\n * reached no suite is not a fact about the suite being asked after.\n *\n * The use-case corpus's health travels as `useCases`, spelled as `list\n * capabilities`, `status` and `delta` spell it (`unreadable`, `error`), plus a\n * `state` this section needs and they do not: here the corpus IS the rows, so\n * \"the fleet declares no use case\" (`absent`) and \"loam read them\" (`ok`) are\n * two answers a reader has to be able to tell apart from one empty list. Over an\n * unreadable `architecture/` the section DEGRADES rather than refusing, exactly\n * as `list capabilities` does: `suites` and `ungrouped` are ABSENT keys — `[]`\n * would be \"loam looked and found none\", said about a project nobody read — and\n * a named suite is not refused as unknown, because that refusal would be a\n * claim about suites loam never saw.\n */\nimport { fail } from \"../../../core/envelope/json.js\";\nimport type { FleetContext } from \"../../../core/fleet-context.js\";\nimport type { DocsDir } from \"../../../core/kernel/ids/dirs.js\";\nimport { listServices } from \"../../../core/repo/repo.js\";\nimport { closeNamesHint } from \"../../../core/repo/tree/find.js\";\nimport type { ParsedView } from \"../../../core/c4/parsed/dynamic-views.js\";\nimport { readUseCases } from \"../../../core/usecases/fleet.js\";\nimport { viewFile } from \"../../../core/usecases/place.js\";\nimport { suiteListing, type Suite } from \"../../../core/usecases/suites/suites.js\";\n\nexport interface SuitesRequest {\n docsDir: DocsDir;\n /** The `[name]` argument: narrows `suites[]` to one suite, refusing a name no use case carries. */\n name: string | undefined;\n json: boolean;\n fleet: FleetContext;\n}\n\n/** The section, ready for whichever view the run prints. */\nexport interface SuitesSection {\n /** The additive payload keys, spread into the `list` envelope. */\n payload: Record<string, unknown>;\n /** The text view of the same answer. */\n print: () => void;\n}\n\n/**\n * Read the fleet's use cases and group them, or refuse an unknown suite name.\n *\n * Returns `null` when it has already refused — the caller's cue to stop, the\n * `resolveSubsystemSlice` convention one package over.\n *\n * The services are enumerated for the RESOLVER, not for the rows: the\n * element→service join needs the fleet set for the reason every edge join does\n * (`readUseCases`' `UseCaseRequest.known`), and without it a step into\n * `orders.api` would resolve to a service called \"api\".\n */\nexport async function suitesSection(req: SuitesRequest): Promise<SuitesSection | null> {\n const entries = await listServices(req.docsDir, req.fleet);\n const scan = await readUseCases({ docsDir: req.docsDir, known: new Set(entries.map((e) => e.id)) });\n if (scan.kind === \"unreadable\") {\n const error = scan.errors[0];\n return {\n payload: { useCases: { state: \"unreadable\", unreadable: true, ...(error === undefined ? {} : { error }) } },\n print: () => printUnreadable(error),\n };\n }\n const listing = suiteListing(scan);\n const state = scan.views.length === 0 ? \"absent\" : \"ok\";\n const shown = req.name === undefined ? listing.suites : listing.suites.filter((s) => s.name === req.name);\n if (req.name !== undefined && shown.length === 0) {\n const names = listing.suites.map((s) => s.name);\n // `unknown-target`, the code `--subsystem` and `show` use for a name that\n // resolves to nothing, with the same close-name hint — an empty environment\n // for a typo would read as a suite that needs nothing started.\n fail(\n req.json,\n \"unknown-target\",\n `No suite '${req.name}'.` +\n closeNamesHint(\n req.name,\n names,\n names.length === 0\n ? \" No use case under architecture/ carries a `#suite-` tag.\"\n : ` Declared suites: ${names.join(\", \")}.`,\n ),\n );\n return null;\n }\n return {\n payload: {\n suites: shown.map(suiteJson),\n ungrouped: listing.ungrouped.map(viewJson),\n useCases: { state, unreadable: false },\n },\n print: () => printSuites(shown, listing.ungrouped, state === \"absent\"),\n };\n}\n\n/** A use case as the payload names it: enough to open the document it is written in. */\nfunction viewJson(view: ParsedView): { id: string; file: string } {\n return { id: view.id, file: viewFile(view) };\n}\n\nfunction suiteJson(suite: Suite): Record<string, unknown> {\n return {\n name: suite.name,\n views: suite.views.map(viewJson),\n services: suite.services,\n unresolved: suite.unresolved,\n };\n}\n\n/**\n * One block per suite — its services, then the participants a stand cannot\n * start — then the journeys in no suite.\n *\n * An unresolved participant gets a line of its own with a marker rather than\n * being folded into the service list: it is not a service anybody can start,\n * and reading it as one is how an environment comes up short.\n */\nfunction printSuites(suites: readonly Suite[], ungrouped: readonly ParsedView[], absent: boolean): void {\n if (absent) {\n console.log(\n \"no use cases — no dynamic view under architecture/ carries #cap-, #req- or #suite-, so there are no suites\",\n );\n return;\n }\n if (suites.length === 0) console.log(\"no suites — no use case under architecture/ carries a #suite- tag\");\n for (const [i, suite] of suites.entries()) {\n if (i > 0) console.log(\"\");\n console.log(\n `suite ${suite.name} — ${suite.views.length} use case(s), ${suite.services.length} service(s) must be up`,\n );\n for (const service of suite.services) console.log(` ${service}`);\n for (const missing of suite.unresolved) {\n console.log(\n ` ! ${missing.element} — resolves to no service in services/` +\n (missing.external ? \" (#external: bring a double)\" : \"\"),\n );\n }\n console.log(` use cases: ${suite.views.map((v) => v.id).join(\", \")}`);\n }\n console.log(\"\");\n console.log(`use cases in no suite (${ungrouped.length})`);\n const width = Math.max(0, ...ungrouped.map((v) => v.id.length));\n for (const view of ungrouped) console.log(` ${view.id.padEnd(width)} ${viewFile(view)}`);\n}\n\n/**\n * The `list capabilities` note, in this section's words: UNKNOWN rather than\n * none, and the parser's own message on its own line, because a LikeC4 error is\n * several lines of expected-token list and inlining it would push the sentence\n * off the reader's screen.\n */\nfunction printUnreadable(error: string | undefined): void {\n console.log(\n \"note: architecture/ did not parse, so no use case could be read — \" +\n \"which suites exist, and what each needs up, is UNKNOWN here, not none\",\n );\n if (error !== undefined) console.log(` ${error}`);\n}\n"]}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * What the list actually reads: one row per service, one verification cell per
3
+ * feature.
4
+ *
5
+ * Both are gathered before anything is printed or serialized, because the same
6
+ * numbers appear in `--json` and in the worklist footer — a footer computed
7
+ * from a second read is a footer that can contradict the rows above it.
8
+ */
9
+ import { existsSync } from "node:fs";
10
+ import { loadFile } from "../../core/c4/likec4.js";
11
+ import { serviceResolver } from "../../core/c4/resolve/service.js";
12
+ import { maturityGaps, serviceMaturity, } from "../../core/vocabulary/maturity.js";
13
+ import {} from "../../core/repo/entries.js";
14
+ import { landscapePath, servicePathsAt } from "../../core/repo/paths.js";
15
+ import { featureTitle } from "../../core/repo/repo.js";
16
+ import { verificationState } from "../../core/status/verification.js";
17
+ import {} from "../../core/verify/answers.js";
18
+ import {} from "../../core/verify/record.js";
19
+ /**
20
+ * Read the living landscape ONCE and decide, per service, whether an API is
21
+ * expected of it. `serviceResolver` is handed the real service ids so an edge
22
+ * drawn into a modelled container (`paymentService.api`) counts for the service
23
+ * that owns it — the same resolution `validate` uses, so the two commands
24
+ * cannot disagree about who is called.
25
+ */
26
+ export async function serviceViews(docsDir, services, boundService, preloaded) {
27
+ const known = new Set(services.map((s) => s.id));
28
+ const lp = landscapePath(docsDir);
29
+ // `preloaded` is the landscape a caller already holds — `undefined` means
30
+ // "load it if it exists", null "there is none", the convention
31
+ // validateService's own `preloaded` follows. The fleet scorecard hands in
32
+ // the batch-parsed doc because a healthy `validate --all` must spin ZERO
33
+ // per-document workspaces (test/validate-batch-fallback.test.ts counts
34
+ // them), and a second parse of a document that run already holds was the
35
+ // exact per-path cost the batch loader exists to retire.
36
+ const land = preloaded !== undefined ? preloaded : existsSync(lp) ? await loadFile(lp) : null;
37
+ const called = new Set();
38
+ // Positive evidence only: with no landscape, or one that does not parse, we
39
+ // know nothing about who is called and every service is assumed to have an
40
+ // API — the conservative direction, because claiming a service needs no
41
+ // contract is how a real one goes undocumented. This is the SAME rule
42
+ // `landscapeEvidence` (core/vocabulary/maturity.ts) spells per service for
43
+ // explore and the context pack — derived fleet-wide here in one pass (one
44
+ // `called` set for every service) because calling the per-service partition
45
+ // from this loop would re-walk the whole relationship list once per
46
+ // service. If the rule moves, both spellings move.
47
+ const proven = land !== null && land.errors.length === 0;
48
+ if (proven) {
49
+ const svcOf = serviceResolver(land.elements, known);
50
+ for (const r of land.relationships) {
51
+ // …including its self-edge rule: an edge whose two endpoints resolve to
52
+ // one service is that service's own internal wiring, and counting it made
53
+ // a service nobody calls owe an OpenAPI contract — `partial` here while
54
+ // `loam context` (which reads the shared derivation) said `documented`.
55
+ if (r.op !== undefined && svcOf(r.source) !== svcOf(r.target))
56
+ called.add(svcOf(r.target));
57
+ }
58
+ }
59
+ return services.map((entry) => {
60
+ const archSpec = existsSync(servicePathsAt(entry.dir).archSpec);
61
+ const apiExpected = !proven || called.has(entry.id);
62
+ const view = {
63
+ entry,
64
+ archSpec,
65
+ apiExpected,
66
+ unverifiableFromHere: entry.sources.declared && boundService !== entry.id,
67
+ };
68
+ const missing = maturityGaps(view);
69
+ return { ...view, maturity: serviceMaturity(view), missing };
70
+ });
71
+ }
72
+ /**
73
+ * The verification column: `status`'s own record state (`verificationState`),
74
+ * projected onto the cell — the record read, the files added up against the
75
+ * checklist just derived, the archived record read as frozen history — so
76
+ * `list`, `status` and `gate` compute one cell, for the reasons that function
77
+ * records. Reading the record is cheap but no longer one file read — a
78
+ * directory listing and one small read per attesting service, plus the
79
+ * one-file `verification.yaml` — and the checklist is derived only when there
80
+ * is a record to judge: on a fleet-sized repo most features have none, and
81
+ * deriving N checklists to print N dashes is the cost that would get this
82
+ * column dropped. `fleet` is the invocation's read index, so each derivation's
83
+ * enumerations and delta parse are memo hits rather than a walk per feature.
84
+ *
85
+ * A record that cannot be read is one dash like an absent one: this column
86
+ * shows one glyph either way. That includes a record whose summary
87
+ * contradicts its own claims (`verify.record-miscounted`), so no count from it
88
+ * is printed as fact — reading it as absent is the safe half of the truth, and
89
+ * `status` and `verify`, which can say why, report it as unreadable instead.
90
+ */
91
+ export async function featureVerification(docsDir, f, fleet) {
92
+ const { state: s } = await verificationState(docsDir, f, { fleet });
93
+ if (s.state === "absent" || s.state === "unreadable" || s.recorded === null)
94
+ return null;
95
+ return {
96
+ state: s.state,
97
+ recorded: s.recorded,
98
+ verdict: s.verdict,
99
+ confirmed: s.confirmed,
100
+ claims: s.claims,
101
+ attested: s.attested,
102
+ answered: s.answered,
103
+ };
104
+ }
105
+ export async function featureRow(docsDir, f, fleet) {
106
+ return { feature: f, cell: await featureVerification(docsDir, f, fleet), title: await featureTitle(f) };
107
+ }
108
+ //# sourceMappingURL=views.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views.js","sourceRoot":"","sources":["../../../src/commands/list/views.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What the list actually reads: one row per service, one verification cell per\n * feature.\n *\n * Both are gathered before anything is printed or serialized, because the same\n * numbers appear in `--json` and in the worklist footer — a footer computed\n * from a second read is a footer that can contradict the rows above it.\n */\nimport { existsSync } from \"node:fs\";\nimport { loadFile, type LoadedDoc } from \"../../core/c4/likec4.js\";\nimport { serviceResolver } from \"../../core/c4/resolve/service.js\";\nimport {\n maturityGaps,\n serviceMaturity,\n type Maturity,\n type MaturityInput,\n} from \"../../core/vocabulary/maturity.js\";\nimport { type FeatureEntry, type ServiceEntry } from \"../../core/repo/entries.js\";\nimport { landscapePath, servicePathsAt } from \"../../core/repo/paths.js\";\nimport { featureTitle } from \"../../core/repo/repo.js\";\nimport type { FleetContext } from \"../../core/fleet-context.js\";\nimport { verificationState } from \"../../core/status/verification.js\";\nimport { type AnsweredBy } from \"../../core/verify/answers.js\";\nimport { type VerificationVerdict } from \"../../core/verify/record.js\";\nimport type { DocsDir } from \"../../core/kernel/ids/dirs.js\";\n\nexport interface ServiceView extends MaturityInput {\n /** True when this service's `sources` can only be resolved from its own repo. */\n unverifiableFromHere: boolean;\n maturity: Maturity;\n /**\n * What stands between this service and the next rung, in fix order — and at\n * `vouched`, the re-vouch a document that moved under its stamp owes\n * (`maturityGaps`). Empty exactly when nothing is owed, which is the\n * worklist's membership test.\n */\n missing: string[];\n}\n\n/**\n * Read the living landscape ONCE and decide, per service, whether an API is\n * expected of it. `serviceResolver` is handed the real service ids so an edge\n * drawn into a modelled container (`paymentService.api`) counts for the service\n * that owns it — the same resolution `validate` uses, so the two commands\n * cannot disagree about who is called.\n */\nexport async function serviceViews(\n docsDir: DocsDir,\n services: ServiceEntry[],\n boundService: string | undefined,\n preloaded?: LoadedDoc | null,\n): Promise<ServiceView[]> {\n const known = new Set(services.map((s) => s.id));\n const lp = landscapePath(docsDir);\n // `preloaded` is the landscape a caller already holds — `undefined` means\n // \"load it if it exists\", null \"there is none\", the convention\n // validateService's own `preloaded` follows. The fleet scorecard hands in\n // the batch-parsed doc because a healthy `validate --all` must spin ZERO\n // per-document workspaces (test/validate-batch-fallback.test.ts counts\n // them), and a second parse of a document that run already holds was the\n // exact per-path cost the batch loader exists to retire.\n const land = preloaded !== undefined ? preloaded : existsSync(lp) ? await loadFile(lp) : null;\n const called = new Set<string>();\n // Positive evidence only: with no landscape, or one that does not parse, we\n // know nothing about who is called and every service is assumed to have an\n // API — the conservative direction, because claiming a service needs no\n // contract is how a real one goes undocumented. This is the SAME rule\n // `landscapeEvidence` (core/vocabulary/maturity.ts) spells per service for\n // explore and the context pack — derived fleet-wide here in one pass (one\n // `called` set for every service) because calling the per-service partition\n // from this loop would re-walk the whole relationship list once per\n // service. If the rule moves, both spellings move.\n const proven = land !== null && land.errors.length === 0;\n if (proven) {\n const svcOf = serviceResolver(land.elements, known);\n for (const r of land.relationships) {\n // …including its self-edge rule: an edge whose two endpoints resolve to\n // one service is that service's own internal wiring, and counting it made\n // a service nobody calls owe an OpenAPI contract — `partial` here while\n // `loam context` (which reads the shared derivation) said `documented`.\n if (r.op !== undefined && svcOf(r.source) !== svcOf(r.target)) called.add(svcOf(r.target));\n }\n }\n\n return services.map((entry) => {\n const archSpec = existsSync(servicePathsAt(entry.dir).archSpec);\n const apiExpected = !proven || called.has(entry.id);\n const view = {\n entry,\n archSpec,\n apiExpected,\n unverifiableFromHere: entry.sources.declared && boundService !== entry.id,\n };\n const missing = maturityGaps(view);\n return { ...view, maturity: serviceMaturity(view), missing };\n });\n}\n\n/** What the features table says about verification without N `loam verify` runs. */\nexport interface VerificationCell {\n state: \"recorded\" | \"stale\";\n /** The day the record was written. */\n recorded: string;\n /**\n * `verify --json`'s own three-valued verdict, through `verificationVerdict` —\n * not a fourth opinion computed here. `attested` is the one this column got\n * wrong: a scenario confirmed on an agent's word printed as `11/11` under a\n * heading that said `verified`, and `list --json` is how the fleet is graded.\n */\n verdict: VerificationVerdict;\n /** Both counts are `tallyRecord`'s — the record's `claims[]`, never its `summary:` block. */\n confirmed: number;\n claims: number;\n /** Of the confirmed, the scenario claims on an agent's word (`attestedClaims`). */\n attested: number;\n /**\n * Of the confirmed, one count per `answered_by` value (`confirmedProvenance`), every key\n * present. A different question from `attested` above, which is why both are here: `attested`\n * asks only about `scenario.tested` because that is what the verdict turns on, while this asks\n * who answered EVERY kind — and reading the first as if it were the second is how the fleet\n * scorecard credited agent-answered permission and operation claims to a test runner.\n */\n answered: Record<AnsweredBy, number>;\n}\n\n/**\n * The verification column: `status`'s own record state (`verificationState`),\n * projected onto the cell — the record read, the files added up against the\n * checklist just derived, the archived record read as frozen history — so\n * `list`, `status` and `gate` compute one cell, for the reasons that function\n * records. Reading the record is cheap but no longer one file read — a\n * directory listing and one small read per attesting service, plus the\n * one-file `verification.yaml` — and the checklist is derived only when there\n * is a record to judge: on a fleet-sized repo most features have none, and\n * deriving N checklists to print N dashes is the cost that would get this\n * column dropped. `fleet` is the invocation's read index, so each derivation's\n * enumerations and delta parse are memo hits rather than a walk per feature.\n *\n * A record that cannot be read is one dash like an absent one: this column\n * shows one glyph either way. That includes a record whose summary\n * contradicts its own claims (`verify.record-miscounted`), so no count from it\n * is printed as fact — reading it as absent is the safe half of the truth, and\n * `status` and `verify`, which can say why, report it as unreadable instead.\n */\nexport async function featureVerification(\n docsDir: DocsDir,\n f: FeatureEntry,\n fleet: FleetContext,\n): Promise<VerificationCell | null> {\n const { state: s } = await verificationState(docsDir, f, { fleet });\n if (s.state === \"absent\" || s.state === \"unreadable\" || s.recorded === null) return null;\n return {\n state: s.state,\n recorded: s.recorded,\n verdict: s.verdict,\n confirmed: s.confirmed,\n claims: s.claims,\n attested: s.attested,\n answered: s.answered,\n };\n}\n\n/**\n * One features-table row: the feature, its verification cell, and what it is\n * called — carried together so the table and the payload iterate rows rather\n * than join two arrays by position.\n */\nexport interface FeatureRow {\n feature: FeatureEntry;\n cell: VerificationCell | null;\n /** intent.md's title (`featureTitle`) — the words a person recognises a change by; the id alone is a key. */\n title: string | null;\n}\n\nexport async function featureRow(docsDir: DocsDir, f: FeatureEntry, fleet: FleetContext): Promise<FeatureRow> {\n return { feature: f, cell: await featureVerification(docsDir, f, fleet), title: await featureTitle(f) };\n}\n"]}
@@ -0,0 +1,238 @@
1
+ /**
2
+ * In-process dispatch for one MCP tool call: build a fresh commander program
3
+ * holding only the commands the selected tool table exposes, run the argv through
4
+ * it, and hand back what the CLI would have printed.
5
+ *
6
+ * This is the proven harness pattern (test/helpers/harness.ts runLoamNow)
7
+ * moved to the commands layer, minus the chdir: the server's own cwd IS the
8
+ * workdir, so every call resolves loam.json exactly as the CLI would in that
9
+ * directory — the server serves ONE repository, the one it started in, and
10
+ * never changes directory. In-process rather than a child per call because a
11
+ * child re-pays LikeC4/Langium startup on every validate, and because in dev
12
+ * there is no built binary to exec.
13
+ *
14
+ * The capture is process-global (console, exitCode), which is safe under
15
+ * exactly one condition the serve loop guarantees: calls are strictly
16
+ * sequential — each one is awaited to completion before the next frame is
17
+ * read — and `parseAsync` resolves only after the action has fully run (the
18
+ * entire test suite rests on that same guarantee). Nothing here may be
19
+ * module-level state: two serve sessions in one process (the tests do this)
20
+ * must not see each other.
21
+ *
22
+ * NOTE for test/agents.test.ts's scan: registration happens through the
23
+ * imported register functions; this module must never contain the literal
24
+ * dot-command-paren call, comments included, or the CLI surface count breaks.
25
+ */
26
+ import { Command, CommanderError } from "commander";
27
+ import { format } from "node:util";
28
+ import { emitJsonError } from "../../core/envelope/json.js";
29
+ import { registerValidate } from "../validate/validate.js";
30
+ import { registerStatus } from "../status/status.js";
31
+ import { registerList } from "../list/list.js";
32
+ import { registerShow } from "../show/show.js";
33
+ import { registerDelta } from "../delta/delta.js";
34
+ import { registerTasks } from "../tasks/tasks.js";
35
+ import { registerDiff } from "../diff/diff.js";
36
+ import { registerExplore } from "../explore.js";
37
+ import { registerDependencies } from "../dependencies.js";
38
+ import { registerDoctor } from "../doctor.js";
39
+ import { registerContext } from "../context/context.js";
40
+ import { registerAdopt } from "../adopt/adopt.js";
41
+ import { registerGate } from "../gate/gate.js";
42
+ import { registerExplain } from "../explain/explain.js";
43
+ import { registerInstructions } from "../instructions.js";
44
+ import { registerSteps } from "../steps/steps.js";
45
+ import { registerNew } from "../new/new.js";
46
+ import { registerRebase } from "../rebase/rebase.js";
47
+ import { registerGherkin } from "../gherkin/gherkin.js";
48
+ import { registerArchive } from "../archive/archive.js";
49
+ import { MCP_TOOLS } from "../../core/mcp/tools.js";
50
+ /**
51
+ * Every console method Node's Console writes to STDOUT — the protocol stream,
52
+ * where one stray line corrupts the transport. Hooking only `log` was the
53
+ * reviewed defect here: a `console.info` in any command, or in a dependency a
54
+ * command loads, would have written straight into the client's frame stream
55
+ * with every suite green. `warn`/`error` go to stderr, captured for the
56
+ * server log rather than the wire.
57
+ */
58
+ const STDOUT_METHODS = [
59
+ "log", "info", "debug", "dir", "dirxml", "table",
60
+ "group", "groupCollapsed", "groupEnd", "count", "countReset", "timeLog", "timeEnd",
61
+ ];
62
+ const STDERR_METHODS = ["warn", "error"];
63
+ /**
64
+ * Replace the console methods named above with sink writers; the returned
65
+ * function restores every original. Captured output is `format(...)`ed, so
66
+ * `table`/`group` lose their layout — acceptable on purpose: the invariant
67
+ * bought here is that their BYTES stay off the protocol stream, not that
68
+ * their rendering survives.
69
+ */
70
+ export function captureConsole(sinks) {
71
+ const target = console;
72
+ const writer = (sink) => (...parts) => {
73
+ sink.push(format(...parts));
74
+ };
75
+ const toStdout = writer(sinks.stdout);
76
+ const toStderr = writer(sinks.stderr);
77
+ const original = new Map();
78
+ for (const [names, replacement] of [
79
+ [STDOUT_METHODS, toStdout],
80
+ [STDERR_METHODS, toStderr],
81
+ ]) {
82
+ for (const name of names) {
83
+ // A method absent on this Node build has nothing to capture — and
84
+ // nothing to restore, so it must not enter the map either.
85
+ if (typeof target[name] !== "function")
86
+ continue;
87
+ original.set(name, target[name]);
88
+ target[name] = replacement;
89
+ }
90
+ }
91
+ return () => {
92
+ for (const [name, method] of original)
93
+ target[name] = method;
94
+ };
95
+ }
96
+ /** Commander output codes whose printed output is the point, not a usage failure. */
97
+ const PASS_THROUGH = new Set(["commander.help", "commander.helpDisplayed", "commander.version"]);
98
+ /**
99
+ * Every command a tool table may name, keyed by the `command` its tool carries.
100
+ * A LOOKUP, not a roster: which of these a call's program registers is decided
101
+ * by the active tool table alone (`toolRunner`), so the authoring writers —
102
+ * new, rebase, gherkin, archive — exist in it only when `--author` put their
103
+ * tools in the table, and the table the read-only hints describe is the one
104
+ * place that gate is written.
105
+ *
106
+ * `instructions` and `steps` read no config at all, and are in MCP_TOOLS
107
+ * because an agent meets them BEFORE the repository is wired: every generated
108
+ * skill's first line points at `loam instructions <workflow>`. They are why
109
+ * registration follows the table. This list and MCP_TOOLS used to be two
110
+ * copies of one roster, and nothing counted them against each other until a
111
+ * tool advertised in `tools/list` and absent here answered a `tools/call` with
112
+ * `unknown command 'instructions'` — an envelope that reads as the caller's
113
+ * mistake. `test/mcp-serve.test.ts` calls every advertised tool, and checks
114
+ * this lookup against both tables directly.
115
+ */
116
+ const REGISTRARS = new Map([
117
+ ["validate", registerValidate],
118
+ ["status", registerStatus],
119
+ ["list", registerList],
120
+ ["show", registerShow],
121
+ ["delta", registerDelta],
122
+ ["tasks", registerTasks],
123
+ ["diff", registerDiff],
124
+ ["explore", registerExplore],
125
+ ["dependencies", registerDependencies],
126
+ ["doctor", registerDoctor],
127
+ ["context", registerContext],
128
+ ["adopt", registerAdopt],
129
+ ["gate", registerGate],
130
+ ["explain", registerExplain],
131
+ ["instructions", registerInstructions],
132
+ ["steps", registerSteps],
133
+ ["new", registerNew],
134
+ ["rebase", registerRebase],
135
+ ["gherkin", registerGherkin],
136
+ ["archive", registerArchive],
137
+ ]);
138
+ /**
139
+ * Resolve every command `tools` name to its registrar, or throw naming each
140
+ * one that has none. This is the server's STARTUP check, and it runs once per
141
+ * table: `toolRunner` calls it before the first frame is read, so a tool
142
+ * advertised with no registrar — the roster drift above, arriving again —
143
+ * stops `loam mcp` at launch, through cli.ts's catch like any other throw,
144
+ * before a client has been promised anything. It used to run inside every call's program build, where one
145
+ * missing entry turned EVERY `tools/call` into an `internal` envelope naming
146
+ * it, the tools that were wired correctly included: a call's outcome
147
+ * depended on a tool it never named.
148
+ */
149
+ export function resolveRegistrars(tools) {
150
+ const resolved = [];
151
+ const missing = [];
152
+ for (const command of new Set(tools.map((tool) => tool.command))) {
153
+ const register = REGISTRARS.get(command);
154
+ if (register === undefined)
155
+ missing.push(`'${command}'`);
156
+ else
157
+ resolved.push(register);
158
+ }
159
+ if (missing.length > 0) {
160
+ throw new Error(`loam mcp: no command registered for MCP tool command ${missing.join(", ")} — add it to REGISTRARS in src/commands/mcp/dispatch.ts`);
161
+ }
162
+ return resolved;
163
+ }
164
+ /**
165
+ * The scoped program, output routed into `sinks`, holding exactly the commands
166
+ * the resolved table names. configureOutput and exitOverride are set BEFORE the
167
+ * register calls on purpose: commander copies inherited settings onto a
168
+ * subcommand when it is created, so settings applied after registration would
169
+ * leave every subcommand writing to the real stdout — which for an MCP server
170
+ * is the protocol stream.
171
+ */
172
+ function readProgram(sinks, registrars) {
173
+ const program = new Command();
174
+ program.name("loam");
175
+ program.exitOverride();
176
+ program.configureOutput({
177
+ writeOut: (text) => sinks.stdout.push(text),
178
+ writeErr: (text) => sinks.stderr.push(text),
179
+ });
180
+ for (const register of registrars)
181
+ register(program);
182
+ return program;
183
+ }
184
+ /**
185
+ * The runner `loam mcp` serves `tools` with. Throws HERE, at construction, when
186
+ * the table names a command with no registrar (`resolveRegistrars`); the
187
+ * runner it returns never throws, and builds each call's program from the
188
+ * registrars resolved once — so no call can fail for the sake of a tool it
189
+ * did not name.
190
+ */
191
+ export function toolRunner(tools = MCP_TOOLS) {
192
+ const registrars = resolveRegistrars(tools);
193
+ return (argv) => runToolArgv(argv, registrars);
194
+ }
195
+ /**
196
+ * Run one tool argv. Never throws: whatever goes wrong becomes an envelope in
197
+ * `stdout` with `code` 1, so the serve loop's answer to THIS call is the only
198
+ * thing affected — one bad call must never take the server down, and a
199
+ * memoised rejection cannot exist because nothing here outlives the call.
200
+ */
201
+ async function runToolArgv(argv, registrars) {
202
+ const sinks = { stdout: [], stderr: [] };
203
+ const previousExitCode = process.exitCode;
204
+ const restoreConsole = captureConsole(sinks);
205
+ process.exitCode = undefined;
206
+ try {
207
+ await readProgram(sinks, registrars).parseAsync(["node", "loam", ...argv]);
208
+ }
209
+ catch (err) {
210
+ if (err instanceof CommanderError) {
211
+ if (PASS_THROUGH.has(err.code)) {
212
+ // Unreachable through the tool schemas (the argv builder refuses every
213
+ // '-'-prefixed string, so --help/--version cannot arrive), kept for the
214
+ // day it is not: the output already sits in the sinks; keep its code.
215
+ if (process.exitCode === undefined)
216
+ process.exitCode = err.exitCode;
217
+ }
218
+ else {
219
+ // The same envelope cli.ts's catch emits for a usage error, so an MCP
220
+ // caller still receives machine-readable JSON, not a bare exception.
221
+ emitJsonError("invalid-option", err.message.replace(/^error: /, ""));
222
+ }
223
+ }
224
+ else {
225
+ // An unexpected throw from a command action: the CLI's own catch-all
226
+ // (`internal`) — the one code with no stable meaning, carried so the
227
+ // caller gets an envelope rather than a dead call.
228
+ emitJsonError("internal", err instanceof Error ? err.message : String(err));
229
+ }
230
+ }
231
+ finally {
232
+ restoreConsole();
233
+ }
234
+ const code = typeof process.exitCode === "number" ? process.exitCode : 0;
235
+ process.exitCode = previousExitCode;
236
+ return { stdout: sinks.stdout.join("\n"), stderr: sinks.stderr.join("\n"), code };
237
+ }
238
+ //# sourceMappingURL=dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../../src/commands/mcp/dispatch.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * In-process dispatch for one MCP tool call: build a fresh commander program\n * holding only the commands the selected tool table exposes, run the argv through\n * it, and hand back what the CLI would have printed.\n *\n * This is the proven harness pattern (test/helpers/harness.ts runLoamNow)\n * moved to the commands layer, minus the chdir: the server's own cwd IS the\n * workdir, so every call resolves loam.json exactly as the CLI would in that\n * directory — the server serves ONE repository, the one it started in, and\n * never changes directory. In-process rather than a child per call because a\n * child re-pays LikeC4/Langium startup on every validate, and because in dev\n * there is no built binary to exec.\n *\n * The capture is process-global (console, exitCode), which is safe under\n * exactly one condition the serve loop guarantees: calls are strictly\n * sequential — each one is awaited to completion before the next frame is\n * read — and `parseAsync` resolves only after the action has fully run (the\n * entire test suite rests on that same guarantee). Nothing here may be\n * module-level state: two serve sessions in one process (the tests do this)\n * must not see each other.\n *\n * NOTE for test/agents.test.ts's scan: registration happens through the\n * imported register functions; this module must never contain the literal\n * dot-command-paren call, comments included, or the CLI surface count breaks.\n */\nimport { Command, CommanderError } from \"commander\";\nimport { format } from \"node:util\";\nimport { emitJsonError } from \"../../core/envelope/json.js\";\nimport { registerValidate } from \"../validate/validate.js\";\nimport { registerStatus } from \"../status/status.js\";\nimport { registerList } from \"../list/list.js\";\nimport { registerShow } from \"../show/show.js\";\nimport { registerDelta } from \"../delta/delta.js\";\nimport { registerTasks } from \"../tasks/tasks.js\";\nimport { registerDiff } from \"../diff/diff.js\";\nimport { registerExplore } from \"../explore.js\";\nimport { registerDependencies } from \"../dependencies.js\";\nimport { registerDoctor } from \"../doctor.js\";\nimport { registerContext } from \"../context/context.js\";\nimport { registerAdopt } from \"../adopt/adopt.js\";\nimport { registerGate } from \"../gate/gate.js\";\nimport { registerExplain } from \"../explain/explain.js\";\nimport { registerInstructions } from \"../instructions.js\";\nimport { registerSteps } from \"../steps/steps.js\";\nimport { registerNew } from \"../new/new.js\";\nimport { registerRebase } from \"../rebase/rebase.js\";\nimport { registerGherkin } from \"../gherkin/gherkin.js\";\nimport { registerArchive } from \"../archive/archive.js\";\nimport type { ToolRunOutcome } from \"../../core/mcp/protocol.js\";\nimport type { ToolRunner } from \"./serve.js\";\nimport { MCP_TOOLS, type McpTool } from \"../../core/mcp/tools.js\";\n\n/** Console sinks for one dispatch — a value, not module state, so calls cannot share buffers. */\nexport interface Sinks {\n readonly stdout: string[];\n readonly stderr: string[];\n}\n\n/**\n * Every console method Node's Console writes to STDOUT — the protocol stream,\n * where one stray line corrupts the transport. Hooking only `log` was the\n * reviewed defect here: a `console.info` in any command, or in a dependency a\n * command loads, would have written straight into the client's frame stream\n * with every suite green. `warn`/`error` go to stderr, captured for the\n * server log rather than the wire.\n */\nconst STDOUT_METHODS = [\n \"log\", \"info\", \"debug\", \"dir\", \"dirxml\", \"table\",\n \"group\", \"groupCollapsed\", \"groupEnd\", \"count\", \"countReset\", \"timeLog\", \"timeEnd\",\n] as const;\nconst STDERR_METHODS = [\"warn\", \"error\"] as const;\n\n/**\n * Replace the console methods named above with sink writers; the returned\n * function restores every original. Captured output is `format(...)`ed, so\n * `table`/`group` lose their layout — acceptable on purpose: the invariant\n * bought here is that their BYTES stay off the protocol stream, not that\n * their rendering survives.\n */\nexport function captureConsole(sinks: Sinks): () => void {\n const target = console as unknown as Record<string, unknown>;\n const writer = (sink: string[]) => (...parts: unknown[]): void => {\n sink.push(format(...parts));\n };\n const toStdout = writer(sinks.stdout);\n const toStderr = writer(sinks.stderr);\n const original = new Map<string, unknown>();\n for (const [names, replacement] of [\n [STDOUT_METHODS, toStdout],\n [STDERR_METHODS, toStderr],\n ] as const) {\n for (const name of names) {\n // A method absent on this Node build has nothing to capture — and\n // nothing to restore, so it must not enter the map either.\n if (typeof target[name] !== \"function\") continue;\n original.set(name, target[name]);\n target[name] = replacement;\n }\n }\n return () => {\n for (const [name, method] of original) target[name] = method;\n };\n}\n\n/** Commander output codes whose printed output is the point, not a usage failure. */\nconst PASS_THROUGH = new Set([\"commander.help\", \"commander.helpDisplayed\", \"commander.version\"]);\n\n/** One command's registration onto a program — the shape every `registerX` export has. */\ntype Registrar = (program: Command) => void;\n\n/**\n * Every command a tool table may name, keyed by the `command` its tool carries.\n * A LOOKUP, not a roster: which of these a call's program registers is decided\n * by the active tool table alone (`toolRunner`), so the authoring writers —\n * new, rebase, gherkin, archive — exist in it only when `--author` put their\n * tools in the table, and the table the read-only hints describe is the one\n * place that gate is written.\n *\n * `instructions` and `steps` read no config at all, and are in MCP_TOOLS\n * because an agent meets them BEFORE the repository is wired: every generated\n * skill's first line points at `loam instructions <workflow>`. They are why\n * registration follows the table. This list and MCP_TOOLS used to be two\n * copies of one roster, and nothing counted them against each other until a\n * tool advertised in `tools/list` and absent here answered a `tools/call` with\n * `unknown command 'instructions'` — an envelope that reads as the caller's\n * mistake. `test/mcp-serve.test.ts` calls every advertised tool, and checks\n * this lookup against both tables directly.\n */\nconst REGISTRARS = new Map<string, Registrar>([\n [\"validate\", registerValidate],\n [\"status\", registerStatus],\n [\"list\", registerList],\n [\"show\", registerShow],\n [\"delta\", registerDelta],\n [\"tasks\", registerTasks],\n [\"diff\", registerDiff],\n [\"explore\", registerExplore],\n [\"dependencies\", registerDependencies],\n [\"doctor\", registerDoctor],\n [\"context\", registerContext],\n [\"adopt\", registerAdopt],\n [\"gate\", registerGate],\n [\"explain\", registerExplain],\n [\"instructions\", registerInstructions],\n [\"steps\", registerSteps],\n [\"new\", registerNew],\n [\"rebase\", registerRebase],\n [\"gherkin\", registerGherkin],\n [\"archive\", registerArchive],\n]);\n\n/**\n * Resolve every command `tools` name to its registrar, or throw naming each\n * one that has none. This is the server's STARTUP check, and it runs once per\n * table: `toolRunner` calls it before the first frame is read, so a tool\n * advertised with no registrar — the roster drift above, arriving again —\n * stops `loam mcp` at launch, through cli.ts's catch like any other throw,\n * before a client has been promised anything. It used to run inside every call's program build, where one\n * missing entry turned EVERY `tools/call` into an `internal` envelope naming\n * it, the tools that were wired correctly included: a call's outcome\n * depended on a tool it never named.\n */\nexport function resolveRegistrars(tools: readonly McpTool[]): readonly Registrar[] {\n const resolved: Registrar[] = [];\n const missing: string[] = [];\n for (const command of new Set(tools.map((tool) => tool.command))) {\n const register = REGISTRARS.get(command);\n if (register === undefined) missing.push(`'${command}'`);\n else resolved.push(register);\n }\n if (missing.length > 0) {\n throw new Error(`loam mcp: no command registered for MCP tool command ${missing.join(\", \")} — add it to REGISTRARS in src/commands/mcp/dispatch.ts`);\n }\n return resolved;\n}\n\n/**\n * The scoped program, output routed into `sinks`, holding exactly the commands\n * the resolved table names. configureOutput and exitOverride are set BEFORE the\n * register calls on purpose: commander copies inherited settings onto a\n * subcommand when it is created, so settings applied after registration would\n * leave every subcommand writing to the real stdout — which for an MCP server\n * is the protocol stream.\n */\nfunction readProgram(sinks: Sinks, registrars: readonly Registrar[]): Command {\n const program = new Command();\n program.name(\"loam\");\n program.exitOverride();\n program.configureOutput({\n writeOut: (text) => sinks.stdout.push(text),\n writeErr: (text) => sinks.stderr.push(text),\n });\n for (const register of registrars) register(program);\n return program;\n}\n\n/**\n * The runner `loam mcp` serves `tools` with. Throws HERE, at construction, when\n * the table names a command with no registrar (`resolveRegistrars`); the\n * runner it returns never throws, and builds each call's program from the\n * registrars resolved once — so no call can fail for the sake of a tool it\n * did not name.\n */\nexport function toolRunner(tools: readonly McpTool[] = MCP_TOOLS): ToolRunner {\n const registrars = resolveRegistrars(tools);\n return (argv) => runToolArgv(argv, registrars);\n}\n\n/**\n * Run one tool argv. Never throws: whatever goes wrong becomes an envelope in\n * `stdout` with `code` 1, so the serve loop's answer to THIS call is the only\n * thing affected — one bad call must never take the server down, and a\n * memoised rejection cannot exist because nothing here outlives the call.\n */\nasync function runToolArgv(argv: readonly string[], registrars: readonly Registrar[]): Promise<ToolRunOutcome> {\n const sinks: Sinks = { stdout: [], stderr: [] };\n const previousExitCode = process.exitCode;\n const restoreConsole = captureConsole(sinks);\n process.exitCode = undefined;\n try {\n await readProgram(sinks, registrars).parseAsync([\"node\", \"loam\", ...argv]);\n } catch (err) {\n if (err instanceof CommanderError) {\n if (PASS_THROUGH.has(err.code)) {\n // Unreachable through the tool schemas (the argv builder refuses every\n // '-'-prefixed string, so --help/--version cannot arrive), kept for the\n // day it is not: the output already sits in the sinks; keep its code.\n if (process.exitCode === undefined) process.exitCode = err.exitCode;\n } else {\n // The same envelope cli.ts's catch emits for a usage error, so an MCP\n // caller still receives machine-readable JSON, not a bare exception.\n emitJsonError(\"invalid-option\", err.message.replace(/^error: /, \"\"));\n }\n } else {\n // An unexpected throw from a command action: the CLI's own catch-all\n // (`internal`) — the one code with no stable meaning, carried so the\n // caller gets an envelope rather than a dead call.\n emitJsonError(\"internal\", err instanceof Error ? err.message : String(err));\n }\n } finally {\n restoreConsole();\n }\n const code = typeof process.exitCode === \"number\" ? process.exitCode : 0;\n process.exitCode = previousExitCode;\n return { stdout: sinks.stdout.join(\"\\n\"), stderr: sinks.stderr.join(\"\\n\"), code };\n}\n"]}