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

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 (1036) hide show
  1. package/CHANGELOG.md +2635 -86
  2. package/COMPARISON.md +80 -63
  3. package/CONTRIBUTING.md +84 -0
  4. package/MIGRATING-from-OpenSpec.md +213 -54
  5. package/QUICKSTART.md +125 -0
  6. package/README.md +450 -150
  7. package/ROADMAP.md +599 -0
  8. package/SCHEMA.md +2355 -256
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +701 -0
  11. package/dist/cli.js +113 -19
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +209 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +268 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +77 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/plan/contracts/asyncapi.js +178 -0
  20. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/openapi.js +159 -0
  22. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  23. package/dist/commands/archive/plan/gate.js +323 -0
  24. package/dist/commands/archive/plan/gate.js.map +1 -0
  25. package/dist/commands/archive/plan/landscape.js +180 -0
  26. package/dist/commands/archive/plan/landscape.js.map +1 -0
  27. package/dist/commands/archive/plan/refusal.js +111 -0
  28. package/dist/commands/archive/plan/refusal.js.map +1 -0
  29. package/dist/commands/archive/plan/specs.js +237 -0
  30. package/dist/commands/archive/plan/specs.js.map +1 -0
  31. package/dist/commands/archive/plan/state.js +27 -0
  32. package/dist/commands/archive/plan/state.js.map +1 -0
  33. package/dist/commands/archive/run.js +252 -0
  34. package/dist/commands/archive/run.js.map +1 -0
  35. package/dist/commands/context/context.js +99 -0
  36. package/dist/commands/context/context.js.map +1 -0
  37. package/dist/commands/context/print.js +283 -0
  38. package/dist/commands/context/print.js.map +1 -0
  39. package/dist/commands/delta/delta.js +279 -0
  40. package/dist/commands/delta/delta.js.map +1 -0
  41. package/dist/commands/delta/print.js +205 -0
  42. package/dist/commands/delta/print.js.map +1 -0
  43. package/dist/commands/dependencies.js +9 -7
  44. package/dist/commands/dependencies.js.map +1 -1
  45. package/dist/commands/diff/diff.js +93 -0
  46. package/dist/commands/diff/diff.js.map +1 -0
  47. package/dist/commands/diff/print.js +38 -0
  48. package/dist/commands/diff/print.js.map +1 -0
  49. package/dist/commands/doctor.js +5 -4
  50. package/dist/commands/doctor.js.map +1 -1
  51. package/dist/commands/explain/explain.js +151 -0
  52. package/dist/commands/explain/explain.js.map +1 -0
  53. package/dist/commands/explore.js +29 -24
  54. package/dist/commands/explore.js.map +1 -1
  55. package/dist/commands/gate/gate.js +115 -0
  56. package/dist/commands/gate/gate.js.map +1 -0
  57. package/dist/commands/gate/print.js +54 -0
  58. package/dist/commands/gate/print.js.map +1 -0
  59. package/dist/commands/gherkin/commit.js +146 -0
  60. package/dist/commands/gherkin/commit.js.map +1 -0
  61. package/dist/commands/gherkin/gherkin.js +246 -0
  62. package/dist/commands/gherkin/gherkin.js.map +1 -0
  63. package/dist/commands/gherkin/reconcile.js +149 -0
  64. package/dist/commands/gherkin/reconcile.js.map +1 -0
  65. package/dist/commands/gherkin/render.js +77 -0
  66. package/dist/commands/gherkin/render.js.map +1 -0
  67. package/dist/commands/init/example.js +204 -0
  68. package/dist/commands/init/example.js.map +1 -0
  69. package/dist/commands/init/first-hour.js +28 -0
  70. package/dist/commands/init/first-hour.js.map +1 -0
  71. package/dist/commands/{init.js → init/init.js} +146 -71
  72. package/dist/commands/init/init.js.map +1 -0
  73. package/dist/commands/init/mcp.js +131 -0
  74. package/dist/commands/init/mcp.js.map +1 -0
  75. package/dist/commands/init/options.js +78 -0
  76. package/dist/commands/init/options.js.map +1 -0
  77. package/dist/commands/instructions.js +72 -14
  78. package/dist/commands/instructions.js.map +1 -1
  79. package/dist/commands/list/campaign/campaign.js +65 -0
  80. package/dist/commands/list/campaign/campaign.js.map +1 -0
  81. package/dist/commands/list/campaign/owners.js +65 -0
  82. package/dist/commands/list/campaign/owners.js.map +1 -0
  83. package/dist/commands/list/json.js +157 -0
  84. package/dist/commands/list/json.js.map +1 -0
  85. package/dist/commands/list/list.js +343 -0
  86. package/dist/commands/list/list.js.map +1 -0
  87. package/dist/commands/list/print.js +301 -0
  88. package/dist/commands/list/print.js.map +1 -0
  89. package/dist/commands/list/review.js +120 -0
  90. package/dist/commands/list/review.js.map +1 -0
  91. package/dist/commands/list/views.js +105 -0
  92. package/dist/commands/list/views.js.map +1 -0
  93. package/dist/commands/mcp/dispatch.js +183 -0
  94. package/dist/commands/mcp/dispatch.js.map +1 -0
  95. package/dist/commands/mcp/mcp.js +34 -0
  96. package/dist/commands/mcp/mcp.js.map +1 -0
  97. package/dist/commands/mcp/serve.js +55 -0
  98. package/dist/commands/mcp/serve.js.map +1 -0
  99. package/dist/commands/migrate-openspec/materialize/active.js +170 -0
  100. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  101. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  102. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  103. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  104. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  105. package/dist/commands/migrate-openspec/materialize/stage.js +142 -0
  106. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  107. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  108. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  109. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  110. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  111. package/dist/commands/migrate-openspec/openspec/decisions.js +91 -0
  112. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  113. package/dist/commands/migrate-openspec/openspec/error.js +19 -0
  114. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  115. package/dist/commands/migrate-openspec/openspec/mapping.js +170 -0
  116. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  117. package/dist/commands/migrate-openspec/openspec/paths.js +43 -0
  118. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  119. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  120. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  121. package/dist/commands/migrate-openspec/print.js +89 -0
  122. package/dist/commands/migrate-openspec/print.js.map +1 -0
  123. package/dist/commands/new/commit.js +76 -0
  124. package/dist/commands/new/commit.js.map +1 -0
  125. package/dist/commands/new/new.js +283 -0
  126. package/dist/commands/new/new.js.map +1 -0
  127. package/dist/commands/new/templates.js +355 -0
  128. package/dist/commands/new/templates.js.map +1 -0
  129. package/dist/commands/open.js +203 -0
  130. package/dist/commands/open.js.map +1 -0
  131. package/dist/commands/policy/format.js +152 -0
  132. package/dist/commands/policy/format.js.map +1 -0
  133. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +11 -11
  134. package/dist/commands/policy/gate.js.map +1 -0
  135. package/dist/commands/rebase/edit.js +106 -0
  136. package/dist/commands/rebase/edit.js.map +1 -0
  137. package/dist/commands/rebase/living.js +185 -0
  138. package/dist/commands/rebase/living.js.map +1 -0
  139. package/dist/commands/rebase/plan.js +245 -0
  140. package/dist/commands/rebase/plan.js.map +1 -0
  141. package/dist/commands/rebase/rebase.js +275 -0
  142. package/dist/commands/rebase/rebase.js.map +1 -0
  143. package/dist/commands/seed/commit.js +192 -0
  144. package/dist/commands/seed/commit.js.map +1 -0
  145. package/dist/commands/seed/plan.js +133 -0
  146. package/dist/commands/seed/plan.js.map +1 -0
  147. package/dist/commands/seed/seed.js +172 -0
  148. package/dist/commands/seed/seed.js.map +1 -0
  149. package/dist/commands/show/feature.js +178 -0
  150. package/dist/commands/show/feature.js.map +1 -0
  151. package/dist/commands/show/marks.js +24 -0
  152. package/dist/commands/show/marks.js.map +1 -0
  153. package/dist/commands/{show.js → show/service.js} +63 -152
  154. package/dist/commands/show/service.js.map +1 -0
  155. package/dist/commands/show/show.js +77 -0
  156. package/dist/commands/show/show.js.map +1 -0
  157. package/dist/commands/status/json.js +45 -0
  158. package/dist/commands/status/json.js.map +1 -0
  159. package/dist/commands/status/print.js +157 -0
  160. package/dist/commands/status/print.js.map +1 -0
  161. package/dist/commands/status/status.js +119 -0
  162. package/dist/commands/status/status.js.map +1 -0
  163. package/dist/commands/steps/steps.js +189 -0
  164. package/dist/commands/steps/steps.js.map +1 -0
  165. package/dist/commands/subsystem/edit.js +192 -0
  166. package/dist/commands/subsystem/edit.js.map +1 -0
  167. package/dist/commands/subsystem/move.js +265 -0
  168. package/dist/commands/subsystem/move.js.map +1 -0
  169. package/dist/commands/subsystem/query.js +115 -0
  170. package/dist/commands/subsystem/query.js.map +1 -0
  171. package/dist/commands/subsystem/subsystem.js +101 -0
  172. package/dist/commands/subsystem/subsystem.js.map +1 -0
  173. package/dist/commands/subsystem/sync.js +103 -0
  174. package/dist/commands/subsystem/sync.js.map +1 -0
  175. package/dist/commands/subsystem/txn/txn.js +94 -0
  176. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  177. package/dist/commands/subsystem/txn/views.js +70 -0
  178. package/dist/commands/subsystem/txn/views.js.map +1 -0
  179. package/dist/commands/unarchive/manifest.js +160 -0
  180. package/dist/commands/unarchive/manifest.js.map +1 -0
  181. package/dist/commands/{unarchive.js → unarchive/restore.js} +47 -160
  182. package/dist/commands/unarchive/restore.js.map +1 -0
  183. package/dist/commands/unarchive/unarchive.js +67 -0
  184. package/dist/commands/unarchive/unarchive.js.map +1 -0
  185. package/dist/commands/validate/arch-coverage.js +204 -0
  186. package/dist/commands/validate/arch-coverage.js.map +1 -0
  187. package/dist/commands/validate/checks/fleet-shape.js +296 -0
  188. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  189. package/dist/commands/validate/checks/health-deps.js +55 -0
  190. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  191. package/dist/commands/validate/checks/requirements.js +254 -0
  192. package/dist/commands/validate/checks/requirements.js.map +1 -0
  193. package/dist/commands/validate/checks/sources.js +76 -0
  194. package/dist/commands/validate/checks/sources.js.map +1 -0
  195. package/dist/commands/validate/checks/vocabulary.js +31 -0
  196. package/dist/commands/validate/checks/vocabulary.js.map +1 -0
  197. package/dist/commands/validate/feature.js +216 -0
  198. package/dist/commands/validate/feature.js.map +1 -0
  199. package/dist/commands/validate/fleet/census.js +69 -0
  200. package/dist/commands/validate/fleet/census.js.map +1 -0
  201. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  202. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  203. package/dist/commands/validate/fleet/landscape.js +353 -0
  204. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  205. package/dist/commands/validate/fleet/load.js +52 -0
  206. package/dist/commands/validate/fleet/load.js.map +1 -0
  207. package/dist/commands/validate/fleet/obligations.js +270 -0
  208. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  209. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  210. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  211. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  212. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  213. package/dist/commands/validate/fleet/scorecard/print.js +63 -0
  214. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  215. package/dist/commands/validate/fleet/scorecard/scorecard.js +156 -0
  216. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  217. package/dist/commands/validate/fleet/usecases/capability-tag.js +94 -0
  218. package/dist/commands/validate/fleet/usecases/capability-tag.js.map +1 -0
  219. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  220. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  221. package/dist/commands/validate/fleet/usecases/requirement-tag.js +95 -0
  222. package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +1 -0
  223. package/dist/commands/validate/fleet/usecases/steps.js +197 -0
  224. package/dist/commands/validate/fleet/usecases/steps.js.map +1 -0
  225. package/dist/commands/validate/fleet/usecases/usecases.js +99 -0
  226. package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -0
  227. package/dist/commands/validate/fleet/views/ids.js +40 -0
  228. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  229. package/dist/commands/validate/fleet/views/stale.js +59 -0
  230. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  231. package/dist/commands/validate/links/corpus.js +92 -0
  232. package/dist/commands/validate/links/corpus.js.map +1 -0
  233. package/dist/commands/validate/links/glossary.js +75 -0
  234. package/dist/commands/validate/links/glossary.js.map +1 -0
  235. package/dist/commands/validate/report.js +269 -0
  236. package/dist/commands/validate/report.js.map +1 -0
  237. package/dist/commands/validate/service/api.js +338 -0
  238. package/dist/commands/validate/service/api.js.map +1 -0
  239. package/dist/commands/validate/service/events/events.js +219 -0
  240. package/dist/commands/validate/service/events/events.js.map +1 -0
  241. package/dist/commands/validate/service/events/message-producers.js +77 -0
  242. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  243. package/dist/commands/validate/service/evidence-pins.js +131 -0
  244. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  245. package/dist/commands/validate/service/service.js +251 -0
  246. package/dist/commands/validate/service/service.js.map +1 -0
  247. package/dist/commands/validate/service/specs.js +251 -0
  248. package/dist/commands/validate/service/specs.js.map +1 -0
  249. package/dist/commands/validate/service/spine.js +113 -0
  250. package/dist/commands/validate/service/spine.js.map +1 -0
  251. package/dist/commands/validate/validate.js +338 -0
  252. package/dist/commands/validate/validate.js.map +1 -0
  253. package/dist/commands/verify/cross/diff.js +182 -0
  254. package/dist/commands/verify/cross/diff.js.map +1 -0
  255. package/dist/commands/verify/evidence/contract.js +32 -0
  256. package/dist/commands/verify/evidence/contract.js.map +1 -0
  257. package/dist/commands/verify/evidence/pins.js +52 -0
  258. package/dist/commands/verify/evidence/pins.js.map +1 -0
  259. package/dist/commands/verify/evidence/read.js +72 -0
  260. package/dist/commands/verify/evidence/read.js.map +1 -0
  261. package/dist/commands/verify/frozen.js +241 -0
  262. package/dist/commands/verify/frozen.js.map +1 -0
  263. package/dist/commands/verify/record.js +226 -0
  264. package/dist/commands/verify/record.js.map +1 -0
  265. package/dist/commands/verify/report.js +223 -0
  266. package/dist/commands/verify/report.js.map +1 -0
  267. package/dist/commands/verify/results.js +246 -0
  268. package/dist/commands/verify/results.js.map +1 -0
  269. package/dist/commands/verify/verify.js +217 -0
  270. package/dist/commands/verify/verify.js.map +1 -0
  271. package/dist/commands/vouch/contract.js +11 -0
  272. package/dist/commands/vouch/contract.js.map +1 -0
  273. package/dist/commands/vouch/pack/contract.js +2 -0
  274. package/dist/commands/vouch/pack/contract.js.map +1 -0
  275. package/dist/commands/vouch/pack/pack.js +266 -0
  276. package/dist/commands/vouch/pack/pack.js.map +1 -0
  277. package/dist/commands/vouch/pack/print.js +271 -0
  278. package/dist/commands/vouch/pack/print.js.map +1 -0
  279. package/dist/commands/vouch/pack/sections.js +142 -0
  280. package/dist/commands/vouch/pack/sections.js.map +1 -0
  281. package/dist/commands/vouch/prompt/confirm.js +46 -0
  282. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  283. package/dist/commands/vouch/report.js +101 -0
  284. package/dist/commands/vouch/report.js.map +1 -0
  285. package/dist/commands/vouch/run.js +285 -0
  286. package/dist/commands/vouch/run.js.map +1 -0
  287. package/dist/commands/vouch/sample/plan.js +125 -0
  288. package/dist/commands/vouch/sample/plan.js.map +1 -0
  289. package/dist/commands/vouch/sample/print.js +109 -0
  290. package/dist/commands/vouch/sample/print.js.map +1 -0
  291. package/dist/commands/vouch/vet/verify.js +123 -0
  292. package/dist/commands/vouch/vet/verify.js.map +1 -0
  293. package/dist/commands/vouch/vouch.js +176 -0
  294. package/dist/commands/vouch/vouch.js.map +1 -0
  295. package/dist/core/agent/agents-md/artifacts.js +220 -0
  296. package/dist/core/agent/agents-md/artifacts.js.map +1 -0
  297. package/dist/core/agent/agents-md/command-map.js +324 -0
  298. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  299. package/dist/core/agent/agents-md/cycle.js +165 -0
  300. package/dist/core/agent/agents-md/cycle.js.map +1 -0
  301. package/dist/core/agent/agents-md/map/explain.js +34 -0
  302. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  303. package/dist/core/agent/agents-md/map/lenses/context.js +41 -0
  304. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  305. package/dist/core/agent/agents-md/map/lenses/diff.js +46 -0
  306. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  307. package/dist/core/agent/agents-md/map/lenses/gate.js +57 -0
  308. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  309. package/dist/core/agent/agents-md/map/mcp.js +41 -0
  310. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  311. package/dist/core/agent/agents-md/map/status.js +62 -0
  312. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  313. package/dist/core/agent/agents-md/map/subsystem.js +32 -0
  314. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  315. package/dist/core/agent/agents-md/map/usecases.js +60 -0
  316. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  317. package/dist/core/agent/agents-md/refusals.js +246 -0
  318. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  319. package/dist/core/agent/agents-md/shipped/archive-gate.js +98 -0
  320. package/dist/core/agent/agents-md/shipped/archive-gate.js.map +1 -0
  321. package/dist/core/agent/agents-md/spine.js +40 -0
  322. package/dist/core/agent/agents-md/spine.js.map +1 -0
  323. package/dist/core/agent/agents-md.js +170 -0
  324. package/dist/core/agent/agents-md.js.map +1 -0
  325. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +50 -0
  326. package/dist/core/agent/agents-stamp.js.map +1 -0
  327. package/dist/core/agent/contract.js +2 -0
  328. package/dist/core/agent/contract.js.map +1 -0
  329. package/dist/core/agent/protocol.js +193 -0
  330. package/dist/core/agent/protocol.js.map +1 -0
  331. package/dist/core/agent/scaffold.js +259 -0
  332. package/dist/core/agent/scaffold.js.map +1 -0
  333. package/dist/core/agent/support/report.js +103 -0
  334. package/dist/core/agent/support/report.js.map +1 -0
  335. package/dist/core/agent/tools/dialects.js +150 -0
  336. package/dist/core/agent/tools/dialects.js.map +1 -0
  337. package/dist/core/agent/tools/registry.js +228 -0
  338. package/dist/core/agent/tools/registry.js.map +1 -0
  339. package/dist/core/agent/workflows/adopt.js +133 -0
  340. package/dist/core/agent/workflows/adopt.js.map +1 -0
  341. package/dist/core/agent/workflows/check.js +337 -0
  342. package/dist/core/agent/workflows/check.js.map +1 -0
  343. package/dist/core/agent/workflows/closing.js +262 -0
  344. package/dist/core/agent/workflows/closing.js.map +1 -0
  345. package/dist/core/agent/workflows/feature.js +105 -0
  346. package/dist/core/agent/workflows/feature.js.map +1 -0
  347. package/dist/core/agent/workflows/implement.js +105 -0
  348. package/dist/core/agent/workflows/implement.js.map +1 -0
  349. package/dist/core/agent/workflows/reference/authoring.js +209 -0
  350. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  351. package/dist/core/agent/workflows/reference/codes.js +65 -0
  352. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  353. package/dist/core/agent/workflows/reference/done-check.js +188 -0
  354. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  355. package/dist/core/agent/workflows/reference/reference.js +16 -0
  356. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  357. package/dist/core/agent/workflows/reference/spine.js +297 -0
  358. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  359. package/dist/core/asyncapi/baseline/plan.js +110 -0
  360. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  361. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  362. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  363. package/dist/core/asyncapi/depth.js +164 -0
  364. package/dist/core/asyncapi/depth.js.map +1 -0
  365. package/dist/core/asyncapi/digest.js +141 -0
  366. package/dist/core/asyncapi/digest.js.map +1 -0
  367. package/dist/core/asyncapi/merge/components.js +91 -0
  368. package/dist/core/asyncapi/merge/components.js.map +1 -0
  369. package/dist/core/asyncapi/merge/error.js +33 -0
  370. package/dist/core/asyncapi/merge/error.js.map +1 -0
  371. package/dist/core/asyncapi/merge/markers.js +308 -0
  372. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  373. package/dist/core/asyncapi/merge/merge.js +215 -0
  374. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  375. package/dist/core/asyncapi/merge/pin.js +107 -0
  376. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  377. package/dist/core/asyncapi/model.js +11 -0
  378. package/dist/core/asyncapi/model.js.map +1 -0
  379. package/dist/core/asyncapi/producers.js +50 -0
  380. package/dist/core/asyncapi/producers.js.map +1 -0
  381. package/dist/core/{asyncapi.js → asyncapi/read.js} +95 -109
  382. package/dist/core/asyncapi/read.js.map +1 -0
  383. package/dist/core/brief/brief.js +225 -0
  384. package/dist/core/brief/brief.js.map +1 -0
  385. package/dist/core/brief/checks.js +250 -0
  386. package/dist/core/brief/checks.js.map +1 -0
  387. package/dist/core/brief/landscape.js +194 -0
  388. package/dist/core/brief/landscape.js.map +1 -0
  389. package/dist/core/brief/targets.js +226 -0
  390. package/dist/core/brief/targets.js.map +1 -0
  391. package/dist/core/brief/unchecked.js +48 -0
  392. package/dist/core/brief/unchecked.js.map +1 -0
  393. package/dist/core/c4/arch.js +174 -0
  394. package/dist/core/c4/arch.js.map +1 -0
  395. package/dist/core/c4/likec4.js +90 -0
  396. package/dist/core/c4/likec4.js.map +1 -0
  397. package/dist/core/c4/parsed/deployment.js +158 -0
  398. package/dist/core/c4/parsed/deployment.js.map +1 -0
  399. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  400. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  401. package/dist/core/c4/parsed/specification.js +78 -0
  402. package/dist/core/c4/parsed/specification.js.map +1 -0
  403. package/dist/core/c4/parsed/values.js +57 -0
  404. package/dist/core/c4/parsed/values.js.map +1 -0
  405. package/dist/core/c4/parsed/view-ids.js +75 -0
  406. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  407. package/dist/core/c4/project/architecture.js +45 -0
  408. package/dist/core/c4/project/architecture.js.map +1 -0
  409. package/dist/core/c4/project/documents.js +58 -0
  410. package/dist/core/c4/project/documents.js.map +1 -0
  411. package/dist/core/c4/project/load.js +187 -0
  412. package/dist/core/c4/project/load.js.map +1 -0
  413. package/dist/core/c4/project/staged.js +220 -0
  414. package/dist/core/c4/project/staged.js.map +1 -0
  415. package/dist/core/c4/resolve/service.js +159 -0
  416. package/dist/core/c4/resolve/service.js.map +1 -0
  417. package/dist/core/c4/resolve/steps.js +144 -0
  418. package/dist/core/c4/resolve/steps.js.map +1 -0
  419. package/dist/core/c4/seed/fleet-file.js +201 -0
  420. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  421. package/dist/core/c4/seed/items.js +91 -0
  422. package/dist/core/c4/seed/items.js.map +1 -0
  423. package/dist/core/c4/seed/stamp.js +48 -0
  424. package/dist/core/c4/seed/stamp.js.map +1 -0
  425. package/dist/core/c4/seed/template.js +109 -0
  426. package/dist/core/c4/seed/template.js.map +1 -0
  427. package/dist/core/c4/source-mask.js +82 -0
  428. package/dist/core/c4/source-mask.js.map +1 -0
  429. package/dist/core/c4/source-scan.js +227 -0
  430. package/dist/core/c4/source-scan.js.map +1 -0
  431. package/dist/core/c4/splice/authored-source.js +101 -0
  432. package/dist/core/c4/splice/authored-source.js.map +1 -0
  433. package/dist/core/c4/splice/contract.js +10 -0
  434. package/dist/core/c4/splice/contract.js.map +1 -0
  435. package/dist/core/c4/splice/delta-blocks.js +139 -0
  436. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  437. package/dist/core/c4/splice/identity/edges.js +36 -0
  438. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  439. package/dist/core/c4/splice/landscape-merge.js +269 -0
  440. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  441. package/dist/core/c4/splice/placement.js +194 -0
  442. package/dist/core/c4/splice/placement.js.map +1 -0
  443. package/dist/core/c4/workspace.js +174 -0
  444. package/dist/core/c4/workspace.js.map +1 -0
  445. package/dist/core/capabilities/authoring/notes.js +141 -0
  446. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  447. package/dist/core/capabilities/capabilities.js +124 -0
  448. package/dist/core/capabilities/capabilities.js.map +1 -0
  449. package/dist/core/capabilities/delta/doc.js +50 -0
  450. package/dist/core/capabilities/delta/doc.js.map +1 -0
  451. package/dist/core/capabilities/delta/overlay.js +129 -0
  452. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  453. package/dist/core/capabilities/delta/summary.js +57 -0
  454. package/dist/core/capabilities/delta/summary.js.map +1 -0
  455. package/dist/core/capabilities/delta/tree.js +43 -0
  456. package/dist/core/capabilities/delta/tree.js.map +1 -0
  457. package/dist/core/capabilities/delta/uncovered.js +222 -0
  458. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  459. package/dist/core/capabilities/findings.js +342 -0
  460. package/dist/core/capabilities/findings.js.map +1 -0
  461. package/dist/core/capabilities/realizes/findings.js +181 -0
  462. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  463. package/dist/core/capabilities/realizes/join.js +143 -0
  464. package/dist/core/capabilities/realizes/join.js.map +1 -0
  465. package/dist/core/capabilities/rollup.js +199 -0
  466. package/dist/core/capabilities/rollup.js.map +1 -0
  467. package/dist/core/capabilities/tree.js +126 -0
  468. package/dist/core/capabilities/tree.js.map +1 -0
  469. package/dist/core/capabilities/usecase-join.js +277 -0
  470. package/dist/core/capabilities/usecase-join.js.map +1 -0
  471. package/dist/core/coherence/authoring/scaffold.js +177 -0
  472. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  473. package/dist/core/coherence/authoring/sentinels.js +74 -0
  474. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  475. package/dist/core/coherence/coherence.js +287 -0
  476. package/dist/core/coherence/coherence.js.map +1 -0
  477. package/dist/core/coherence/declared.js +269 -0
  478. package/dist/core/coherence/declared.js.map +1 -0
  479. package/dist/core/coherence/events/declared.js +206 -0
  480. package/dist/core/coherence/events/declared.js.map +1 -0
  481. package/dist/core/coherence/events/events.js +204 -0
  482. package/dist/core/coherence/events/events.js.map +1 -0
  483. package/dist/core/coherence/events/grades.js +166 -0
  484. package/dist/core/coherence/events/grades.js.map +1 -0
  485. package/dist/core/coherence/events/lookups.js +122 -0
  486. package/dist/core/coherence/events/lookups.js.map +1 -0
  487. package/dist/core/coherence/events/merged.js +40 -0
  488. package/dist/core/coherence/events/merged.js.map +1 -0
  489. package/dist/core/coherence/living.js +198 -0
  490. package/dist/core/coherence/living.js.map +1 -0
  491. package/dist/core/coherence/lookups.js +155 -0
  492. package/dist/core/coherence/lookups.js.map +1 -0
  493. package/dist/core/coherence/pending.js +39 -0
  494. package/dist/core/coherence/pending.js.map +1 -0
  495. package/dist/core/conflict-markers.js +60 -0
  496. package/dist/core/conflict-markers.js.map +1 -0
  497. package/dist/core/delta/claims.js +73 -0
  498. package/dist/core/delta/claims.js.map +1 -0
  499. package/dist/core/delta/delta.js +296 -0
  500. package/dist/core/delta/delta.js.map +1 -0
  501. package/dist/core/delta/document.js +177 -0
  502. package/dist/core/delta/document.js.map +1 -0
  503. package/dist/core/delta/scope.js +48 -0
  504. package/dist/core/delta/scope.js.map +1 -0
  505. package/dist/core/delta/select.js +237 -0
  506. package/dist/core/delta/select.js.map +1 -0
  507. package/dist/core/dependencies/dependencies.js +141 -0
  508. package/dist/core/dependencies/dependencies.js.map +1 -0
  509. package/dist/core/dependencies/facts.js +165 -0
  510. package/dist/core/dependencies/facts.js.map +1 -0
  511. package/dist/core/dependencies/fanin.js +88 -0
  512. package/dist/core/dependencies/fanin.js.map +1 -0
  513. package/dist/core/dependencies/graph.js +106 -0
  514. package/dist/core/dependencies/graph.js.map +1 -0
  515. package/dist/core/deployment/delta.js +188 -0
  516. package/dist/core/deployment/delta.js.map +1 -0
  517. package/dist/core/deployment/objects.js +145 -0
  518. package/dist/core/deployment/objects.js.map +1 -0
  519. package/dist/core/diff/base-git.js +148 -0
  520. package/dist/core/diff/base-git.js.map +1 -0
  521. package/dist/core/diff/base-state.js +209 -0
  522. package/dist/core/diff/base-state.js.map +1 -0
  523. package/dist/core/diff/current-state.js +96 -0
  524. package/dist/core/diff/current-state.js.map +1 -0
  525. package/dist/core/diff/scope/changed-paths.js +188 -0
  526. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  527. package/dist/core/diff/semantic.js +243 -0
  528. package/dist/core/diff/semantic.js.map +1 -0
  529. package/dist/core/diff/victims.js +247 -0
  530. package/dist/core/diff/victims.js.map +1 -0
  531. package/dist/core/docs.js +7 -64
  532. package/dist/core/docs.js.map +1 -1
  533. package/dist/core/doctor/agents.js +222 -0
  534. package/dist/core/doctor/agents.js.map +1 -0
  535. package/dist/core/doctor/config.js +135 -0
  536. package/dist/core/doctor/config.js.map +1 -0
  537. package/dist/core/doctor/doctor.js +275 -0
  538. package/dist/core/doctor/doctor.js.map +1 -0
  539. package/dist/core/doctor/report.js +13 -0
  540. package/dist/core/doctor/report.js.map +1 -0
  541. package/dist/core/doctor/residue.js +110 -0
  542. package/dist/core/doctor/residue.js.map +1 -0
  543. package/dist/core/document/apply.js +77 -0
  544. package/dist/core/document/apply.js.map +1 -0
  545. package/dist/core/{frontmatter.js → document/frontmatter.js} +48 -2
  546. package/dist/core/document/frontmatter.js.map +1 -0
  547. package/dist/core/document/grammar/directives.js +143 -0
  548. package/dist/core/document/grammar/directives.js.map +1 -0
  549. package/dist/core/document/parse.js +263 -0
  550. package/dist/core/document/parse.js.map +1 -0
  551. package/dist/core/document/scenarios.js +221 -0
  552. package/dist/core/document/scenarios.js.map +1 -0
  553. package/dist/core/document/spec.js +241 -0
  554. package/dist/core/document/spec.js.map +1 -0
  555. package/dist/core/{config.js → envelope/config.js} +79 -18
  556. package/dist/core/envelope/config.js.map +1 -0
  557. package/dist/core/envelope/json.js +175 -0
  558. package/dist/core/envelope/json.js.map +1 -0
  559. package/dist/core/{version.js → envelope/version.js} +3 -3
  560. package/dist/core/envelope/version.js.map +1 -0
  561. package/dist/core/explain/families.js +175 -0
  562. package/dist/core/explain/families.js.map +1 -0
  563. package/dist/core/explain/fix-tables.js +178 -0
  564. package/dist/core/explain/fix-tables.js.map +1 -0
  565. package/dist/core/explain/lookup.js +181 -0
  566. package/dist/core/explain/lookup.js.map +1 -0
  567. package/dist/core/explain/refusals.js +49 -0
  568. package/dist/core/explain/refusals.js.map +1 -0
  569. package/dist/core/explain/terms.js +144 -0
  570. package/dist/core/explain/terms.js.map +1 -0
  571. package/dist/core/explore/describe.js +105 -0
  572. package/dist/core/explore/describe.js.map +1 -0
  573. package/dist/core/{explore.js → explore/explore.js} +50 -101
  574. package/dist/core/explore/explore.js.map +1 -0
  575. package/dist/core/fleet-context.js +120 -78
  576. package/dist/core/fleet-context.js.map +1 -1
  577. package/dist/core/gate/checks.js +201 -0
  578. package/dist/core/gate/checks.js.map +1 -0
  579. package/dist/core/gate/partners.js +205 -0
  580. package/dist/core/gate/partners.js.map +1 -0
  581. package/dist/core/gate/report.js +47 -0
  582. package/dist/core/gate/report.js.map +1 -0
  583. package/dist/core/gate/verification.js +113 -0
  584. package/dist/core/gate/verification.js.map +1 -0
  585. package/dist/core/gherkin/digest.js +60 -0
  586. package/dist/core/gherkin/digest.js.map +1 -0
  587. package/dist/core/gherkin/emit.js +177 -0
  588. package/dist/core/gherkin/emit.js.map +1 -0
  589. package/dist/core/gherkin/read.js +76 -0
  590. package/dist/core/gherkin/read.js.map +1 -0
  591. package/dist/core/gherkin/stale.js +234 -0
  592. package/dist/core/gherkin/stale.js.map +1 -0
  593. package/dist/core/gherkin/stamp.js +77 -0
  594. package/dist/core/gherkin/stamp.js.map +1 -0
  595. package/dist/core/gherkin/steps/catalogue.js +154 -0
  596. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  597. package/dist/core/gherkin/steps/inventory.js +98 -0
  598. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  599. package/dist/core/gherkin/steps/phrase.js +72 -0
  600. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  601. package/dist/core/glossary/delta.js +106 -0
  602. package/dist/core/glossary/delta.js.map +1 -0
  603. package/dist/core/glossary/tree.js +86 -0
  604. package/dist/core/glossary/tree.js.map +1 -0
  605. package/dist/core/kernel/concurrency.js.map +1 -0
  606. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  607. package/dist/core/kernel/document-bytes.js.map +1 -0
  608. package/dist/core/kernel/fences.js +42 -0
  609. package/dist/core/kernel/fences.js.map +1 -0
  610. package/dist/core/kernel/ids/capability.js +72 -0
  611. package/dist/core/kernel/ids/capability.js.map +1 -0
  612. package/dist/core/kernel/ids/dirs.js +33 -0
  613. package/dist/core/kernel/ids/dirs.js.map +1 -0
  614. package/dist/core/kernel/ids/feature.js +75 -0
  615. package/dist/core/kernel/ids/feature.js.map +1 -0
  616. package/dist/core/kernel/ids/service.js +156 -0
  617. package/dist/core/kernel/ids/service.js.map +1 -0
  618. package/dist/core/kernel/ids/subsystem.js +63 -0
  619. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  620. package/dist/core/{path-safety.js → kernel/path-safety.js} +18 -4
  621. package/dist/core/kernel/path-safety.js.map +1 -0
  622. package/dist/core/kernel/records.js.map +1 -0
  623. package/dist/core/links/backlinks.js +68 -0
  624. package/dist/core/links/backlinks.js.map +1 -0
  625. package/dist/core/links/case.js +74 -0
  626. package/dist/core/links/case.js.map +1 -0
  627. package/dist/core/links/corpus.js +104 -0
  628. package/dist/core/links/corpus.js.map +1 -0
  629. package/dist/core/links/findings.js +110 -0
  630. package/dist/core/links/findings.js.map +1 -0
  631. package/dist/core/links/parse.js +236 -0
  632. package/dist/core/links/parse.js.map +1 -0
  633. package/dist/core/mcp/argv.js +111 -0
  634. package/dist/core/mcp/argv.js.map +1 -0
  635. package/dist/core/mcp/author-tools.js +72 -0
  636. package/dist/core/mcp/author-tools.js.map +1 -0
  637. package/dist/core/mcp/framing.js +46 -0
  638. package/dist/core/mcp/framing.js.map +1 -0
  639. package/dist/core/mcp/protocol.js +280 -0
  640. package/dist/core/mcp/protocol.js.map +1 -0
  641. package/dist/core/mcp/tools.js +314 -0
  642. package/dist/core/mcp/tools.js.map +1 -0
  643. package/dist/core/obligations/obligations.js +106 -0
  644. package/dist/core/obligations/obligations.js.map +1 -0
  645. package/dist/core/openapi/baseline/gate.js +166 -0
  646. package/dist/core/openapi/baseline/gate.js.map +1 -0
  647. package/dist/core/openapi/baseline/plan.js +112 -0
  648. package/dist/core/openapi/baseline/plan.js.map +1 -0
  649. package/dist/core/openapi/baseline/record.js +175 -0
  650. package/dist/core/openapi/baseline/record.js.map +1 -0
  651. package/dist/core/openapi/depth.js +122 -0
  652. package/dist/core/openapi/depth.js.map +1 -0
  653. package/dist/core/openapi/digest.js +189 -0
  654. package/dist/core/openapi/digest.js.map +1 -0
  655. package/dist/core/{openapi.js → openapi/doc.js} +44 -106
  656. package/dist/core/openapi/doc.js.map +1 -0
  657. package/dist/core/openapi/merge/components.js +234 -0
  658. package/dist/core/openapi/merge/components.js.map +1 -0
  659. package/dist/core/openapi/merge/error.js +26 -0
  660. package/dist/core/openapi/merge/error.js.map +1 -0
  661. package/dist/core/openapi/merge/markers.js +208 -0
  662. package/dist/core/openapi/merge/markers.js.map +1 -0
  663. package/dist/core/openapi/merge/merge.js +256 -0
  664. package/dist/core/openapi/merge/merge.js.map +1 -0
  665. package/dist/core/openapi/merge/pin.js +128 -0
  666. package/dist/core/openapi/merge/pin.js.map +1 -0
  667. package/dist/core/openspec/decide/capabilities.js +244 -0
  668. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  669. package/dist/core/openspec/decide/dispositions.js +63 -0
  670. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  671. package/dist/core/openspec/decide/renames.js +179 -0
  672. package/dist/core/openspec/decide/renames.js.map +1 -0
  673. package/dist/core/openspec/decide/verdict.js +84 -0
  674. package/dist/core/openspec/decide/verdict.js.map +1 -0
  675. package/dist/core/openspec/inventory.js +221 -0
  676. package/dist/core/openspec/inventory.js.map +1 -0
  677. package/dist/core/openspec/model/mapping.js +76 -0
  678. package/dist/core/openspec/model/mapping.js.map +1 -0
  679. package/dist/core/openspec/model/model.js +65 -0
  680. package/dist/core/openspec/model/model.js.map +1 -0
  681. package/dist/core/openspec/scan/changes.js +235 -0
  682. package/dist/core/openspec/scan/changes.js.map +1 -0
  683. package/dist/core/openspec/scan/config.js +200 -0
  684. package/dist/core/openspec/scan/config.js.map +1 -0
  685. package/dist/core/openspec/scan/shape.js +260 -0
  686. package/dist/core/openspec/scan/shape.js.map +1 -0
  687. package/dist/core/openspec/scan/walk.js +133 -0
  688. package/dist/core/openspec/scan/walk.js.map +1 -0
  689. package/dist/core/openspec/scan/workspace.js +71 -0
  690. package/dist/core/openspec/scan/workspace.js.map +1 -0
  691. package/dist/core/owners/codeowners.js +141 -0
  692. package/dist/core/owners/codeowners.js.map +1 -0
  693. package/dist/core/pack/features.js +120 -0
  694. package/dist/core/pack/features.js.map +1 -0
  695. package/dist/core/pack/joins.js +112 -0
  696. package/dist/core/pack/joins.js.map +1 -0
  697. package/dist/core/pack/living.js +137 -0
  698. package/dist/core/pack/living.js.map +1 -0
  699. package/dist/core/pack/pack.js +76 -0
  700. package/dist/core/pack/pack.js.map +1 -0
  701. package/dist/core/permissions/permissions.js +87 -0
  702. package/dist/core/permissions/permissions.js.map +1 -0
  703. package/dist/core/projection/api.js +84 -0
  704. package/dist/core/projection/api.js.map +1 -0
  705. package/dist/core/projection/arch-slice.js +63 -0
  706. package/dist/core/projection/arch-slice.js.map +1 -0
  707. package/dist/core/projection/events.js +34 -0
  708. package/dist/core/projection/events.js.map +1 -0
  709. package/dist/core/provenance/findings.js +208 -0
  710. package/dist/core/provenance/findings.js.map +1 -0
  711. package/dist/core/provenance/git.js +225 -0
  712. package/dist/core/provenance/git.js.map +1 -0
  713. package/dist/core/provenance/gitq/moves.js +182 -0
  714. package/dist/core/provenance/gitq/moves.js.map +1 -0
  715. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  716. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  717. package/dist/core/provenance/sample/scope.js +238 -0
  718. package/dist/core/provenance/sample/scope.js.map +1 -0
  719. package/dist/core/provenance/sample/sections.js +61 -0
  720. package/dist/core/provenance/sample/sections.js.map +1 -0
  721. package/dist/core/provenance/sources.js +263 -0
  722. package/dist/core/provenance/sources.js.map +1 -0
  723. package/dist/core/provenance/stamp.js +232 -0
  724. package/dist/core/provenance/stamp.js.map +1 -0
  725. package/dist/core/provenance/walk.js +157 -0
  726. package/dist/core/provenance/walk.js.map +1 -0
  727. package/dist/core/repo/authored/paths.js +210 -0
  728. package/dist/core/repo/authored/paths.js.map +1 -0
  729. package/dist/core/repo/entries.js +126 -0
  730. package/dist/core/repo/entries.js.map +1 -0
  731. package/dist/core/repo/paths.js +277 -0
  732. package/dist/core/repo/paths.js.map +1 -0
  733. package/dist/core/repo/repo.js +248 -0
  734. package/dist/core/repo/repo.js.map +1 -0
  735. package/dist/core/repo/service-target.js +153 -0
  736. package/dist/core/repo/service-target.js.map +1 -0
  737. package/dist/core/repo/state.js +58 -0
  738. package/dist/core/repo/state.js.map +1 -0
  739. package/dist/core/repo/tree/find.js +52 -0
  740. package/dist/core/repo/tree/find.js.map +1 -0
  741. package/dist/core/repo/tree/fs.js +64 -0
  742. package/dist/core/repo/tree/fs.js.map +1 -0
  743. package/dist/core/repo/tree/marker.js +61 -0
  744. package/dist/core/repo/tree/marker.js.map +1 -0
  745. package/dist/core/repo/tree/views.js +172 -0
  746. package/dist/core/repo/tree/views.js.map +1 -0
  747. package/dist/core/repo/tree/walk.js +234 -0
  748. package/dist/core/repo/tree/walk.js.map +1 -0
  749. package/dist/core/results.js +99 -2
  750. package/dist/core/results.js.map +1 -1
  751. package/dist/core/scaffold/landscape.js +131 -0
  752. package/dist/core/scaffold/landscape.js.map +1 -0
  753. package/dist/core/scaffold/readme.js +84 -0
  754. package/dist/core/scaffold/readme.js.map +1 -0
  755. package/dist/core/staging/commit.js +241 -0
  756. package/dist/core/staging/commit.js.map +1 -0
  757. package/dist/core/staging/interrupted.js +96 -0
  758. package/dist/core/staging/interrupted.js.map +1 -0
  759. package/dist/core/staging/lock.js +206 -0
  760. package/dist/core/staging/lock.js.map +1 -0
  761. package/dist/core/staging/recovery/finding.js +35 -0
  762. package/dist/core/staging/recovery/finding.js.map +1 -0
  763. package/dist/core/staging/recovery/intent.js +98 -0
  764. package/dist/core/staging/recovery/intent.js.map +1 -0
  765. package/dist/core/staging/recovery/recover.js +126 -0
  766. package/dist/core/staging/recovery/recover.js.map +1 -0
  767. package/dist/core/staging/recovery/residue.js +62 -0
  768. package/dist/core/staging/recovery/residue.js.map +1 -0
  769. package/dist/core/staging/snapshot.js +202 -0
  770. package/dist/core/staging/snapshot.js.map +1 -0
  771. package/dist/core/staging/txn/forward.js +171 -0
  772. package/dist/core/staging/txn/forward.js.map +1 -0
  773. package/dist/core/staging/txn/journal.js +139 -0
  774. package/dist/core/staging/txn/journal.js.map +1 -0
  775. package/dist/core/staging/txn/transaction.js +75 -0
  776. package/dist/core/staging/txn/transaction.js.map +1 -0
  777. package/dist/core/staging/writes.js +113 -0
  778. package/dist/core/staging/writes.js.map +1 -0
  779. package/dist/core/status/actions/execution.js +49 -0
  780. package/dist/core/status/actions/execution.js.map +1 -0
  781. package/dist/core/status/contracts.js +102 -0
  782. package/dist/core/status/contracts.js.map +1 -0
  783. package/dist/core/status/feature/artifacts.js +196 -0
  784. package/dist/core/status/feature/artifacts.js.map +1 -0
  785. package/dist/core/status/feature/feature.js +207 -0
  786. package/dist/core/status/feature/feature.js.map +1 -0
  787. package/dist/core/status/feature/next.js +150 -0
  788. package/dist/core/status/feature/next.js.map +1 -0
  789. package/dist/core/status/feature/state.js +21 -0
  790. package/dist/core/status/feature/state.js.map +1 -0
  791. package/dist/core/status/fleet/fleet.js +197 -0
  792. package/dist/core/status/fleet/fleet.js.map +1 -0
  793. package/dist/core/status/fleet/next.js +207 -0
  794. package/dist/core/status/fleet/next.js.map +1 -0
  795. package/dist/core/status/interrupted.js +97 -0
  796. package/dist/core/status/interrupted.js.map +1 -0
  797. package/dist/core/status/report.js +31 -0
  798. package/dist/core/status/report.js.map +1 -0
  799. package/dist/core/status/scan.js +41 -0
  800. package/dist/core/status/scan.js.map +1 -0
  801. package/dist/core/status/verification.js +201 -0
  802. package/dist/core/status/verification.js.map +1 -0
  803. package/dist/core/usecases/capability.js +169 -0
  804. package/dist/core/usecases/capability.js.map +1 -0
  805. package/dist/core/usecases/delta/claims.js +116 -0
  806. package/dist/core/usecases/delta/claims.js.map +1 -0
  807. package/dist/core/usecases/delta/flows.js +103 -0
  808. package/dist/core/usecases/delta/flows.js.map +1 -0
  809. package/dist/core/usecases/delta/overlay.js +72 -0
  810. package/dist/core/usecases/delta/overlay.js.map +1 -0
  811. package/dist/core/usecases/fleet.js +137 -0
  812. package/dist/core/usecases/fleet.js.map +1 -0
  813. package/dist/core/usecases/operations.js +111 -0
  814. package/dist/core/usecases/operations.js.map +1 -0
  815. package/dist/core/usecases/place.js +44 -0
  816. package/dist/core/usecases/place.js.map +1 -0
  817. package/dist/core/usecases/touch.js +101 -0
  818. package/dist/core/usecases/touch.js.map +1 -0
  819. package/dist/core/verify/answers.js +173 -0
  820. package/dist/core/verify/answers.js.map +1 -0
  821. package/dist/core/verify/build.js +150 -0
  822. package/dist/core/verify/build.js.map +1 -0
  823. package/dist/core/verify/checklist.js +201 -0
  824. package/dist/core/verify/checklist.js.map +1 -0
  825. package/dist/core/verify/claims/identity.js +61 -0
  826. package/dist/core/verify/claims/identity.js.map +1 -0
  827. package/dist/core/verify/cross/diff.js +97 -0
  828. package/dist/core/verify/cross/diff.js.map +1 -0
  829. package/dist/core/verify/evidence/contract.js +169 -0
  830. package/dist/core/verify/evidence/contract.js.map +1 -0
  831. package/dist/core/verify/file.js +257 -0
  832. package/dist/core/verify/file.js.map +1 -0
  833. package/dist/core/verify/pins/lint.js +157 -0
  834. package/dist/core/verify/pins/lint.js.map +1 -0
  835. package/dist/core/verify/pins/pin.js +95 -0
  836. package/dist/core/verify/pins/pin.js.map +1 -0
  837. package/dist/core/verify/record.js +142 -0
  838. package/dist/core/verify/record.js.map +1 -0
  839. package/dist/core/verify/store/commit.js +89 -0
  840. package/dist/core/verify/store/commit.js.map +1 -0
  841. package/dist/core/verify/store/render.js +57 -0
  842. package/dist/core/verify/store/render.js.map +1 -0
  843. package/dist/core/vocabulary/health.js +91 -0
  844. package/dist/core/vocabulary/health.js.map +1 -0
  845. package/dist/core/vocabulary/issue.js +58 -0
  846. package/dist/core/vocabulary/issue.js.map +1 -0
  847. package/dist/core/vocabulary/maturity.js +145 -0
  848. package/dist/core/vocabulary/maturity.js.map +1 -0
  849. package/dist/core/{report.js → vocabulary/report.js} +30 -2
  850. package/dist/core/vocabulary/report.js.map +1 -0
  851. package/dist/core/vocabulary/steps.js +266 -0
  852. package/dist/core/vocabulary/steps.js.map +1 -0
  853. package/dist/core/workspace/discover.js +239 -0
  854. package/dist/core/workspace/discover.js.map +1 -0
  855. package/dist/core/workspace/render.js +52 -0
  856. package/dist/core/workspace/render.js.map +1 -0
  857. package/examples/README.md +189 -0
  858. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  859. package/examples/docs/architecture/capabilities.yaml +31 -0
  860. package/examples/docs/architecture/landscape.likec4 +280 -0
  861. package/examples/docs/architecture/obligations.yaml +23 -0
  862. package/examples/docs/architecture/permissions.yaml +50 -0
  863. package/examples/docs/architecture/subsystems.likec4 +11 -0
  864. package/examples/docs/architecture/usecases/order-notification.likec4 +65 -0
  865. package/examples/docs/capabilities/checkout/spec.md +55 -0
  866. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  867. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  868. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  869. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  870. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  871. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  872. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +129 -0
  873. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  874. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  875. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  876. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  877. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  878. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +28 -0
  879. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  880. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  881. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  882. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  883. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  884. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  885. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  886. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  887. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  888. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  889. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +70 -0
  890. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  891. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  892. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  893. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  894. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  895. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  896. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  897. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  898. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  899. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  900. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  901. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  902. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  903. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  904. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  905. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  906. package/examples/docs/glossary/order.md +15 -0
  907. package/examples/docs/glossary/payments/authorization.md +14 -0
  908. package/examples/docs/likec4.config.json +9 -0
  909. package/examples/docs/loam.json +3 -0
  910. package/examples/docs/services/checkout-web/model.likec4 +109 -0
  911. package/examples/docs/services/checkout-web/spec.md +91 -0
  912. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  913. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  914. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  915. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  916. package/examples/docs/services/order-service/arch.spec.md +127 -0
  917. package/examples/docs/services/order-service/asyncapi.yaml +108 -0
  918. package/examples/docs/services/order-service/health.yaml +57 -0
  919. package/examples/docs/services/order-service/model.likec4 +138 -0
  920. package/examples/docs/services/order-service/openapi.yaml +257 -0
  921. package/examples/docs/services/order-service/runbook.md +62 -0
  922. package/examples/docs/services/order-service/spec.md +134 -0
  923. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  924. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  925. package/examples/docs/services/payment-service/arch.spec.md +73 -0
  926. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  927. package/examples/docs/services/payment-service/health.yaml +39 -0
  928. package/examples/docs/services/payment-service/model.likec4 +67 -0
  929. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  930. package/examples/docs/services/payment-service/runbook.md +37 -0
  931. package/examples/docs/services/payment-service/spec.md +88 -0
  932. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  933. package/examples/docs/services/platform/identity-service/arch.spec.md +117 -0
  934. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  935. package/examples/docs/services/platform/identity-service/model.likec4 +83 -0
  936. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  937. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  938. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  939. package/examples/docs/services/platform/notification-service/asyncapi.yaml +199 -0
  940. package/examples/docs/services/platform/notification-service/health.yaml +35 -0
  941. package/examples/docs/services/platform/notification-service/model.likec4 +118 -0
  942. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  943. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  944. package/examples/docs/services/platform/subsystem.yaml +2 -0
  945. package/examples/fleet.yaml +57 -0
  946. package/package.json +19 -6
  947. package/dist/commands/adopt.js +0 -240
  948. package/dist/commands/adopt.js.map +0 -1
  949. package/dist/commands/archive.js +0 -1313
  950. package/dist/commands/archive.js.map +0 -1
  951. package/dist/commands/delta.js +0 -388
  952. package/dist/commands/delta.js.map +0 -1
  953. package/dist/commands/docs-repo-gate.js.map +0 -1
  954. package/dist/commands/format.js +0 -17
  955. package/dist/commands/format.js.map +0 -1
  956. package/dist/commands/gherkin.js +0 -309
  957. package/dist/commands/gherkin.js.map +0 -1
  958. package/dist/commands/init.js.map +0 -1
  959. package/dist/commands/list.js +0 -295
  960. package/dist/commands/list.js.map +0 -1
  961. package/dist/commands/migrate-openspec.js +0 -950
  962. package/dist/commands/migrate-openspec.js.map +0 -1
  963. package/dist/commands/new.js +0 -413
  964. package/dist/commands/new.js.map +0 -1
  965. package/dist/commands/rebase.js +0 -356
  966. package/dist/commands/rebase.js.map +0 -1
  967. package/dist/commands/show.js.map +0 -1
  968. package/dist/commands/status.js +0 -262
  969. package/dist/commands/status.js.map +0 -1
  970. package/dist/commands/unarchive.js.map +0 -1
  971. package/dist/commands/validate.js +0 -1773
  972. package/dist/commands/validate.js.map +0 -1
  973. package/dist/commands/verify.js +0 -775
  974. package/dist/commands/verify.js.map +0 -1
  975. package/dist/commands/vouch.js +0 -421
  976. package/dist/commands/vouch.js.map +0 -1
  977. package/dist/core/agent.js +0 -2173
  978. package/dist/core/agent.js.map +0 -1
  979. package/dist/core/agents-stamp.js.map +0 -1
  980. package/dist/core/arch.js +0 -130
  981. package/dist/core/arch.js.map +0 -1
  982. package/dist/core/asyncapi.js.map +0 -1
  983. package/dist/core/brief.js +0 -755
  984. package/dist/core/brief.js.map +0 -1
  985. package/dist/core/coherence.js +0 -577
  986. package/dist/core/coherence.js.map +0 -1
  987. package/dist/core/concurrency.js.map +0 -1
  988. package/dist/core/config.js.map +0 -1
  989. package/dist/core/delta.js +0 -476
  990. package/dist/core/delta.js.map +0 -1
  991. package/dist/core/dependencies.js +0 -356
  992. package/dist/core/dependencies.js.map +0 -1
  993. package/dist/core/doctor.js +0 -596
  994. package/dist/core/doctor.js.map +0 -1
  995. package/dist/core/document-bytes.js.map +0 -1
  996. package/dist/core/explore.js.map +0 -1
  997. package/dist/core/frontmatter.js.map +0 -1
  998. package/dist/core/gherkin.js +0 -463
  999. package/dist/core/gherkin.js.map +0 -1
  1000. package/dist/core/health.js +0 -67
  1001. package/dist/core/health.js.map +0 -1
  1002. package/dist/core/ids.js +0 -122
  1003. package/dist/core/ids.js.map +0 -1
  1004. package/dist/core/issue.js +0 -9
  1005. package/dist/core/issue.js.map +0 -1
  1006. package/dist/core/json.js +0 -74
  1007. package/dist/core/json.js.map +0 -1
  1008. package/dist/core/likec4.js +0 -489
  1009. package/dist/core/likec4.js.map +0 -1
  1010. package/dist/core/maturity.js +0 -66
  1011. package/dist/core/maturity.js.map +0 -1
  1012. package/dist/core/openapi-merge.js +0 -552
  1013. package/dist/core/openapi-merge.js.map +0 -1
  1014. package/dist/core/openapi.js.map +0 -1
  1015. package/dist/core/openspec-inventory.js +0 -1440
  1016. package/dist/core/openspec-inventory.js.map +0 -1
  1017. package/dist/core/path-safety.js.map +0 -1
  1018. package/dist/core/provenance.js +0 -787
  1019. package/dist/core/provenance.js.map +0 -1
  1020. package/dist/core/records.js.map +0 -1
  1021. package/dist/core/repo.js +0 -438
  1022. package/dist/core/repo.js.map +0 -1
  1023. package/dist/core/report.js.map +0 -1
  1024. package/dist/core/spec.js +0 -505
  1025. package/dist/core/spec.js.map +0 -1
  1026. package/dist/core/staging.js +0 -890
  1027. package/dist/core/staging.js.map +0 -1
  1028. package/dist/core/status.js +0 -1132
  1029. package/dist/core/status.js.map +0 -1
  1030. package/dist/core/steps.js +0 -72
  1031. package/dist/core/steps.js.map +0 -1
  1032. package/dist/core/verify.js +0 -807
  1033. package/dist/core/verify.js.map +0 -1
  1034. package/dist/core/version.js.map +0 -1
  1035. /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
  1036. /package/dist/core/{records.js → kernel/records.js} +0 -0
@@ -0,0 +1,109 @@
1
+ /**
2
+ * A LikeC4 identifier for a declared name, mechanically: `.` and `-` become
3
+ * `_`, and the result takes its kind's prefix — `svc_` for a service, `ext_`
4
+ * for an external.
5
+ *
6
+ * The prefix is not decoration, and not only about the digit-initial case
7
+ * (LikeC4 identifiers are letter/underscore-initial). LikeC4's KEYWORDS are
8
+ * bare lowercase words — `notes`, `tag`, `view`, `metadata`, `style`, `link`,
9
+ * `import`, `description`, `size`, `line`, `this` and some thirty more — and a
10
+ * service legally named `notes` emitted as a bare `notes = softwareSystem`
11
+ * does not parse. The self-check would catch that, but only to refuse a fleet
12
+ * whose fault it is not, under `internal`, with no fix to offer. No keyword
13
+ * contains `_`, so a prefixed identifier is PROVABLY not one — at this LikeC4
14
+ * version and at every later one. A reserved-word list here would be the same
15
+ * bug again, rotting the first time the language grew a word.
16
+ *
17
+ * The fold is not injective — `a-b` and `a.b` both give `a_b` — so residual
18
+ * collisions take a deterministic numeric suffix in sorted processing order.
19
+ * Aesthetics do not matter here: the binding metadata, not the element id, is
20
+ * the element's identity to loam.
21
+ */
22
+ function foldName(name, kind) {
23
+ return `${kind}_${name.replace(/[.-]/g, "_")}`;
24
+ }
25
+ /** Element ids for every declared name (services ∪ externals), collision-suffixed deterministically. */
26
+ function elementIds(seed) {
27
+ const ids = new Map();
28
+ const used = new Set();
29
+ const named = [
30
+ ...[...seed.services]
31
+ .map((s) => s.id)
32
+ .sort()
33
+ .map((n) => [n, "svc"]),
34
+ ...[...seed.externals].sort().map((n) => [n, "ext"]),
35
+ ];
36
+ for (const [name, kind] of named) {
37
+ let candidate = foldName(name, kind);
38
+ for (let n = 2; used.has(candidate); n += 1)
39
+ candidate = `${foldName(name, kind)}_${n}`;
40
+ used.add(candidate);
41
+ ids.set(name, candidate);
42
+ }
43
+ return ids;
44
+ }
45
+ /** Render the landscape body (unstamped — `sealLandscape` adds line 1). */
46
+ export function renderLandscape(seed) {
47
+ const ids = elementIds(seed);
48
+ // Every name reaching `el` was declared (calls are validated against
49
+ // services ∪ externals before rendering), so the fallback is unreachable —
50
+ // it exists so a future caller cannot get a silent `undefined` into the DSL.
51
+ const el = (name) => ids.get(name) ?? foldName(name, "svc");
52
+ const lines = [
53
+ "// Generated from fleet.yaml by `loam seed` — edit fleet.yaml and re-run to",
54
+ "// regenerate. Hand edits make this file yours: the stamp on line 1 is how",
55
+ "// seed tells, and it will then refuse to touch the file again.",
56
+ "//",
57
+ "// As contracts arrive, give each call the operationId it uses, so",
58
+ "// requirements, C4 and OpenAPI can be cross-checked:",
59
+ "//",
60
+ "// checkout -> paymentService 'Authorizes' {",
61
+ "// metadata { op 'authorizePayment' }",
62
+ "// }",
63
+ "",
64
+ "specification {",
65
+ " element person",
66
+ " element softwareSystem",
67
+ " element container",
68
+ " element database",
69
+ "",
70
+ " // #platform keeps ubiquitous infrastructure out of the fleet view;",
71
+ " // #external marks somebody else's system, so validate does not ask for a",
72
+ " // services/ directory nobody owes. A tag must be declared before it is",
73
+ " // used, so both are declared here whether or not this fleet uses them.",
74
+ " tag platform",
75
+ " tag external",
76
+ "}",
77
+ "",
78
+ "model {",
79
+ ];
80
+ const services = [...seed.services].sort((a, b) => (a.id < b.id ? -1 : 1));
81
+ for (const s of services) {
82
+ lines.push(` ${el(s.id)} = softwareSystem '${s.id}' {`);
83
+ lines.push(` metadata { service '${s.id}' }`);
84
+ lines.push(" }");
85
+ }
86
+ const externals = [...seed.externals].sort();
87
+ for (const x of externals) {
88
+ lines.push(` ${el(x)} = softwareSystem '${x}' {`);
89
+ lines.push(" #external");
90
+ lines.push(" }");
91
+ }
92
+ const calls = [...seed.calls].sort((a, b) => a.from === b.from ? (a.to < b.to ? -1 : 1) : a.from < b.from ? -1 : 1);
93
+ if (calls.length > 0)
94
+ lines.push("");
95
+ for (const c of calls)
96
+ lines.push(` ${el(c.from)} -> ${el(c.to)}`);
97
+ lines.push("}");
98
+ // The views block below is DUPLICATED from core/docs.ts's LANDSCAPE_STUB
99
+ // (two copies — extract on a third, per the house rule). The tripwire in
100
+ // test/seed.test.ts compares the two blocks BYTE FOR BYTE, comments and
101
+ // wrapping included, so whichever copy drifts fails the suite — a
102
+ // view-names-only compare let a corrected predicate land in one copy and
103
+ // leave every seeded fleet map rendering the old one.
104
+ // The emitted comment speaks to the docs repo's reader, not to loam's:
105
+ // internal paths mean nothing where this file lands.
106
+ lines.push("", "// The views are for LikeC4's own tooling — loam reads the model and never", "// a view. Render with `npx likec4 start` from the docs repo root. Tag", "// ubiquitous infrastructure #platform to keep the fleet view readable.", "views {", " view fleet {", " include *", " exclude element.tag = #platform", " }", " // The obvious spelling — `include element.tag = #platform` — draws the", " // platform boxes with NO edges and no consumers. The predicate that works is", " // the relationship form below.", " view platform {", " include * -> element.tag = #platform", " }", "}");
107
+ return lines.join("\n") + "\n";
108
+ }
109
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/core/c4/seed/template.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * FleetSeed → landscape DSL body: a pure, deterministic function — identical\n * fleet.yaml, identical bytes, on any machine — because the stamp\n * (`./stamp.ts`) digests the output and a nondeterministic templater would\n * read as hand-edited on the next run.\n *\n * The DSL shape is deliberately minimal: one bound `softwareSystem` per\n * service (the `metadata { service '<id>' }` binding is what every loam join\n * reads — element ids are cosmetic), `#external` systems for the externals,\n * and PLAIN edges. No operationIds: those arrive with contracts, and a\n * templated guess would be the extractor this command exists not to be.\n */\nimport type { FleetSeed } from \"./fleet-file.js\";\n\n/** Which kind of declared name an element id is being built for. */\ntype ElementKind = \"svc\" | \"ext\";\n\n/**\n * A LikeC4 identifier for a declared name, mechanically: `.` and `-` become\n * `_`, and the result takes its kind's prefix — `svc_` for a service, `ext_`\n * for an external.\n *\n * The prefix is not decoration, and not only about the digit-initial case\n * (LikeC4 identifiers are letter/underscore-initial). LikeC4's KEYWORDS are\n * bare lowercase words — `notes`, `tag`, `view`, `metadata`, `style`, `link`,\n * `import`, `description`, `size`, `line`, `this` and some thirty more — and a\n * service legally named `notes` emitted as a bare `notes = softwareSystem`\n * does not parse. The self-check would catch that, but only to refuse a fleet\n * whose fault it is not, under `internal`, with no fix to offer. No keyword\n * contains `_`, so a prefixed identifier is PROVABLY not one — at this LikeC4\n * version and at every later one. A reserved-word list here would be the same\n * bug again, rotting the first time the language grew a word.\n *\n * The fold is not injective — `a-b` and `a.b` both give `a_b` — so residual\n * collisions take a deterministic numeric suffix in sorted processing order.\n * Aesthetics do not matter here: the binding metadata, not the element id, is\n * the element's identity to loam.\n */\nfunction foldName(name: string, kind: ElementKind): string {\n return `${kind}_${name.replace(/[.-]/g, \"_\")}`;\n}\n\n/** Element ids for every declared name (services ∪ externals), collision-suffixed deterministically. */\nfunction elementIds(seed: FleetSeed): Map<string, string> {\n const ids = new Map<string, string>();\n const used = new Set<string>();\n const named: Array<readonly [string, ElementKind]> = [\n ...[...seed.services]\n .map((s) => s.id as string)\n .sort()\n .map((n) => [n, \"svc\"] as const),\n ...[...seed.externals].sort().map((n) => [n, \"ext\"] as const),\n ];\n for (const [name, kind] of named) {\n let candidate = foldName(name, kind);\n for (let n = 2; used.has(candidate); n += 1) candidate = `${foldName(name, kind)}_${n}`;\n used.add(candidate);\n ids.set(name, candidate);\n }\n return ids;\n}\n\n/** Render the landscape body (unstamped — `sealLandscape` adds line 1). */\nexport function renderLandscape(seed: FleetSeed): string {\n const ids = elementIds(seed);\n // Every name reaching `el` was declared (calls are validated against\n // services ∪ externals before rendering), so the fallback is unreachable —\n // it exists so a future caller cannot get a silent `undefined` into the DSL.\n const el = (name: string): string => ids.get(name) ?? foldName(name, \"svc\");\n\n const lines: string[] = [\n \"// Generated from fleet.yaml by `loam seed` — edit fleet.yaml and re-run to\",\n \"// regenerate. Hand edits make this file yours: the stamp on line 1 is how\",\n \"// seed tells, and it will then refuse to touch the file again.\",\n \"//\",\n \"// As contracts arrive, give each call the operationId it uses, so\",\n \"// requirements, C4 and OpenAPI can be cross-checked:\",\n \"//\",\n \"// checkout -> paymentService 'Authorizes' {\",\n \"// metadata { op 'authorizePayment' }\",\n \"// }\",\n \"\",\n \"specification {\",\n \" element person\",\n \" element softwareSystem\",\n \" element container\",\n \" element database\",\n \"\",\n \" // #platform keeps ubiquitous infrastructure out of the fleet view;\",\n \" // #external marks somebody else's system, so validate does not ask for a\",\n \" // services/ directory nobody owes. A tag must be declared before it is\",\n \" // used, so both are declared here whether or not this fleet uses them.\",\n \" tag platform\",\n \" tag external\",\n \"}\",\n \"\",\n \"model {\",\n ];\n\n const services = [...seed.services].sort((a, b) => (a.id < b.id ? -1 : 1));\n for (const s of services) {\n lines.push(` ${el(s.id)} = softwareSystem '${s.id}' {`);\n lines.push(` metadata { service '${s.id}' }`);\n lines.push(\" }\");\n }\n const externals = [...seed.externals].sort();\n for (const x of externals) {\n lines.push(` ${el(x)} = softwareSystem '${x}' {`);\n lines.push(\" #external\");\n lines.push(\" }\");\n }\n const calls = [...seed.calls].sort((a, b) =>\n a.from === b.from ? (a.to < b.to ? -1 : 1) : a.from < b.from ? -1 : 1,\n );\n if (calls.length > 0) lines.push(\"\");\n for (const c of calls) lines.push(` ${el(c.from)} -> ${el(c.to)}`);\n lines.push(\"}\");\n\n // The views block below is DUPLICATED from core/docs.ts's LANDSCAPE_STUB\n // (two copies — extract on a third, per the house rule). The tripwire in\n // test/seed.test.ts compares the two blocks BYTE FOR BYTE, comments and\n // wrapping included, so whichever copy drifts fails the suite — a\n // view-names-only compare let a corrected predicate land in one copy and\n // leave every seeded fleet map rendering the old one.\n // The emitted comment speaks to the docs repo's reader, not to loam's:\n // internal paths mean nothing where this file lands.\n lines.push(\n \"\",\n \"// The views are for LikeC4's own tooling — loam reads the model and never\",\n \"// a view. Render with `npx likec4 start` from the docs repo root. Tag\",\n \"// ubiquitous infrastructure #platform to keep the fleet view readable.\",\n \"views {\",\n \" view fleet {\",\n \" include *\",\n \" exclude element.tag = #platform\",\n \" }\",\n \" // The obvious spelling — `include element.tag = #platform` — draws the\",\n \" // platform boxes with NO edges and no consumers. The predicate that works is\",\n \" // the relationship form below.\",\n \" view platform {\",\n \" include * -> element.tag = #platform\",\n \" }\",\n \"}\",\n );\n return lines.join(\"\\n\") + \"\\n\";\n}\n"]}
@@ -0,0 +1,82 @@
1
+ export function maskSource(text) {
2
+ const out = text.split("");
3
+ const literals = [];
4
+ let state = "code";
5
+ let litStart = -1;
6
+ let lit = "";
7
+ for (let i = 0; i < text.length; i += 1) {
8
+ const ch = text[i];
9
+ const next = text[i + 1];
10
+ switch (state) {
11
+ case "code":
12
+ if (ch === "'" || ch === '"') {
13
+ state = ch === "'" ? "squote" : "dquote";
14
+ litStart = i;
15
+ lit = "";
16
+ out[i] = " ";
17
+ }
18
+ else if (ch === "/" && next === "/") {
19
+ state = "lineComment";
20
+ out[i] = " ";
21
+ }
22
+ else if (ch === "/" && next === "*") {
23
+ state = "blockComment";
24
+ out[i] = " ";
25
+ }
26
+ break;
27
+ case "squote":
28
+ case "dquote":
29
+ if (ch === "\\" && i + 1 < text.length) {
30
+ lit += text[i + 1];
31
+ out[i] = " ";
32
+ out[i + 1] = " ";
33
+ i += 1;
34
+ }
35
+ else if (ch === (state === "squote" ? "'" : '"')) {
36
+ literals.push({ start: litStart, end: i + 1, value: lit });
37
+ state = "code";
38
+ out[i] = " ";
39
+ }
40
+ else {
41
+ lit += ch;
42
+ if (ch !== "\n")
43
+ out[i] = " ";
44
+ }
45
+ break;
46
+ case "lineComment":
47
+ if (ch === "\n")
48
+ state = "code";
49
+ else
50
+ out[i] = " ";
51
+ break;
52
+ case "blockComment":
53
+ if (ch === "*" && next === "/") {
54
+ state = "code";
55
+ out[i] = " ";
56
+ out[i + 1] = " ";
57
+ i += 1;
58
+ }
59
+ else if (ch !== "\n") {
60
+ out[i] = " ";
61
+ }
62
+ break;
63
+ }
64
+ }
65
+ return { code: out.join(""), literals };
66
+ }
67
+ /** Index of the `}` matching the `{` at `open`, over MASKED code; -1 when unbalanced. */
68
+ export function matchBrace(code, open) {
69
+ let depth = 0;
70
+ for (let i = open; i < code.length; i += 1) {
71
+ if (code[i] === "{")
72
+ depth += 1;
73
+ else if (code[i] === "}") {
74
+ depth -= 1;
75
+ if (depth === 0)
76
+ return i;
77
+ }
78
+ }
79
+ return -1;
80
+ }
81
+ /** An element declaration located in source, under the id the computed model gives it. */
82
+ //# sourceMappingURL=source-mask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-mask.js","sourceRoot":"","sources":["../../../src/core/c4/source-mask.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Masking LikeC4 source, so a brace count can be trusted.\n *\n * Split from `likec4.ts` because it is the one half of the text-level view that\n * knows nothing about the model: it reads bytes and reports spans, and the\n * scanner above it turns those spans into declarations. `archive`'s splice\n * needs both, and needs them to agree — a mask that misses a literal makes\n * `matchBrace` close a block inside a string, and the merge writes into the\n * middle of somebody's description.\n */\nexport interface SourceLiteral {\n start: number;\n end: number;\n value: string;\n}\n\n/**\n * A LikeC4 source with everything that is not code blanked out: string\n * interiors and comments become spaces, newlines survive, and the result is\n * exactly as long as the input — so structure (braces, arrows, `#tags`) can be\n * read with plain string operations at offsets that are valid in the original.\n */\nexport interface MaskedSource {\n code: string;\n literals: SourceLiteral[];\n}\n\nexport function maskSource(text: string): MaskedSource {\n const out = text.split(\"\");\n const literals: SourceLiteral[] = [];\n type State = \"code\" | \"squote\" | \"dquote\" | \"lineComment\" | \"blockComment\";\n let state: State = \"code\";\n let litStart = -1;\n let lit = \"\";\n for (let i = 0; i < text.length; i += 1) {\n const ch = text[i]!;\n const next = text[i + 1];\n switch (state) {\n case \"code\":\n if (ch === \"'\" || ch === '\"') {\n state = ch === \"'\" ? \"squote\" : \"dquote\";\n litStart = i;\n lit = \"\";\n out[i] = \" \";\n } else if (ch === \"/\" && next === \"/\") {\n state = \"lineComment\";\n out[i] = \" \";\n } else if (ch === \"/\" && next === \"*\") {\n state = \"blockComment\";\n out[i] = \" \";\n }\n break;\n case \"squote\":\n case \"dquote\":\n if (ch === \"\\\\\" && i + 1 < text.length) {\n lit += text[i + 1]!;\n out[i] = \" \";\n out[i + 1] = \" \";\n i += 1;\n } else if (ch === (state === \"squote\" ? \"'\" : '\"')) {\n literals.push({ start: litStart, end: i + 1, value: lit });\n state = \"code\";\n out[i] = \" \";\n } else {\n lit += ch;\n if (ch !== \"\\n\") out[i] = \" \";\n }\n break;\n case \"lineComment\":\n if (ch === \"\\n\") state = \"code\";\n else out[i] = \" \";\n break;\n case \"blockComment\":\n if (ch === \"*\" && next === \"/\") {\n state = \"code\";\n out[i] = \" \";\n out[i + 1] = \" \";\n i += 1;\n } else if (ch !== \"\\n\") {\n out[i] = \" \";\n }\n break;\n }\n }\n return { code: out.join(\"\"), literals };\n}\n\n/** Index of the `}` matching the `{` at `open`, over MASKED code; -1 when unbalanced. */\nexport function matchBrace(code: string, open: number): number {\n let depth = 0;\n for (let i = open; i < code.length; i += 1) {\n if (code[i] === \"{\") depth += 1;\n else if (code[i] === \"}\") {\n depth -= 1;\n if (depth === 0) return i;\n }\n }\n return -1;\n}\n\n/** An element declaration located in source, under the id the computed model gives it. */\n"]}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * The text-level view of a LikeC4 document: which bytes each declaration owns.
3
+ *
4
+ * loam's archive merges the landscape by SPLICING authored text, not by
5
+ * re-rendering a parsed model — a re-render would reformat every line somebody
6
+ * wrote. So the merge needs both views of the same file: the parsed one
7
+ * (`likec4.ts`) for what the model MEANS, and this one for where each
8
+ * declaration physically is. A key only one of them reads is a key the merge
9
+ * silently drops, which is why `metadata` handling is spelled out in both.
10
+ */
11
+ import { maskSource, matchBrace } from "./source-mask.js";
12
+ /**
13
+ * Locate every element and relationship declaration inside the top-level
14
+ * `model { ... }` block of a LikeC4 source, with the byte range each one
15
+ * occupies. This is the splice map `loam archive` merges the landscape with:
16
+ * the parsed model says WHAT exists, this says WHERE its authored text is —
17
+ * verbatim, so nothing the parser does not model (technology, style, links)
18
+ * can be lost by rebuilding it.
19
+ *
20
+ * Both declaration forms are recognised — `name = kind ...` always, and
21
+ * `kind name ...` for any kind the document's own `specification` block
22
+ * declares. Relationship endpoints are resolved the way LikeC4 reads them:
23
+ * innermost enclosing scope outward, then the top level, then a unique leaf
24
+ * name anywhere; `it`/`this` (and an omitted source) mean the enclosing
25
+ * element. A name that resolves nowhere is left as written — the caller's
26
+ * match against the parsed model then fails loudly instead of guessing.
27
+ *
28
+ * Returns null when there is no model block. Callers only hand in documents
29
+ * LikeC4 has already parsed, so the scan can trust balanced braces.
30
+ */
31
+ export function scanModel(text) {
32
+ const { code, literals } = maskSource(text);
33
+ const m = /\bmodel\s*\{/.exec(code);
34
+ if (!m)
35
+ return null;
36
+ const open = m.index + m[0].length - 1;
37
+ const close = matchBrace(code, open);
38
+ if (close === -1)
39
+ return null;
40
+ // Element kinds from the specification block(s): the `<kind> <name>`
41
+ // declaration form is recognisable only by its first token being a kind.
42
+ const kinds = new Set();
43
+ for (const sm of code.matchAll(/\bspecification\s*\{/g)) {
44
+ const sClose = matchBrace(code, sm.index + sm[0].length - 1);
45
+ if (sClose === -1)
46
+ continue;
47
+ for (const em of code.slice(sm.index, sClose).matchAll(/\belement\s+([A-Za-z_][\w-]*)/g)) {
48
+ kinds.add(em[1]);
49
+ }
50
+ }
51
+ const indentOf = (at) => {
52
+ const nl = text.lastIndexOf("\n", at - 1);
53
+ const ws = text.slice(nl + 1, at);
54
+ return /^[ \t]*$/.test(ws) ? ws : "";
55
+ };
56
+ const literalIn = (from, to) => literals.find((l) => l.start >= from && l.end <= to);
57
+ const keyedLiteral = (key, from, to) => {
58
+ if (from === -1)
59
+ return undefined;
60
+ const re = new RegExp(`\\b${key}\\b`, "g");
61
+ re.lastIndex = from;
62
+ const km = re.exec(code);
63
+ if (km === null || km.index >= to)
64
+ return undefined;
65
+ return literalIn(km.index, to)?.value;
66
+ };
67
+ const trimmedEnd = (from, to) => {
68
+ let e = to;
69
+ while (e > from && /\s/.test(text[e - 1]))
70
+ e -= 1;
71
+ return e;
72
+ };
73
+ const elements = [];
74
+ const raw = [];
75
+ const stack = [];
76
+ let i = open + 1;
77
+ while (i < close) {
78
+ const ch = code[i];
79
+ if (/\s/.test(ch)) {
80
+ i += 1;
81
+ continue;
82
+ }
83
+ if (ch === "}") {
84
+ const frame = stack.pop();
85
+ if (frame !== undefined) {
86
+ frame.el.bodyClose = i;
87
+ frame.el.end = i + 1;
88
+ elements.push(frame.el);
89
+ }
90
+ i += 1;
91
+ continue;
92
+ }
93
+ // A statement's head: up to its own `{`, the end of the line, or the
94
+ // enclosing block's `}` on the same line — whichever comes first.
95
+ const stmtStart = i;
96
+ let headEnd = close;
97
+ let opener = -1;
98
+ for (let j = i; j < close; j += 1) {
99
+ const c = code[j];
100
+ if (c === "\n" || c === "}") {
101
+ headEnd = j;
102
+ break;
103
+ }
104
+ if (c === "{") {
105
+ opener = j;
106
+ headEnd = j;
107
+ break;
108
+ }
109
+ }
110
+ const head = code.slice(stmtStart, headEnd);
111
+ const parentId = stack.length > 0 ? stack[stack.length - 1].id : "";
112
+ // Classify: `name = kind` first, then a relationship (the arrow cannot hide
113
+ // in a string — the head is masked), then the `kind name` form, else a
114
+ // property/tag line that is consumed whole, nested block included.
115
+ let localName = null;
116
+ const assign = /^([A-Za-z_]\w*)\s*=\s*[A-Za-z_]/.exec(head);
117
+ if (assign !== null) {
118
+ localName = assign[1];
119
+ }
120
+ else if (!head.includes("->")) {
121
+ const toks = head.trim().split(/\s+/);
122
+ if (toks.length >= 2 && kinds.has(toks[0]) && /^[A-Za-z_]\w*$/.test(toks[1])) {
123
+ localName = toks[1];
124
+ }
125
+ }
126
+ if (localName !== null) {
127
+ const id = parentId === "" ? localName : `${parentId}.${localName}`;
128
+ const el = {
129
+ id,
130
+ start: stmtStart,
131
+ end: headEnd,
132
+ bodyOpen: opener,
133
+ bodyClose: -1,
134
+ indent: indentOf(stmtStart),
135
+ };
136
+ if (opener !== -1) {
137
+ stack.push({ id, el });
138
+ i = opener + 1;
139
+ }
140
+ else {
141
+ el.end = trimmedEnd(stmtStart, headEnd);
142
+ elements.push(el);
143
+ i = headEnd;
144
+ }
145
+ continue;
146
+ }
147
+ if (head.includes("->")) {
148
+ const bClose = opener === -1 ? -1 : matchBrace(code, opener);
149
+ const stmtEnd = opener === -1 ? trimmedEnd(stmtStart, headEnd) : bClose === -1 ? close : bClose + 1;
150
+ const am = /^([A-Za-z_][\w.]*)?\s*(?:-\[[^\]]*\])?->\s*([A-Za-z_][\w.]*)/.exec(head);
151
+ if (am !== null) {
152
+ const arrowEnd = stmtStart + am[0].length;
153
+ const bodyFrom = opener === -1 ? -1 : opener + 1;
154
+ const bodyTo = opener === -1 ? -1 : stmtEnd - 1;
155
+ const title = literalIn(arrowEnd, headEnd)?.value ?? keyedLiteral("title", bodyFrom, bodyTo);
156
+ const tags = [];
157
+ for (const tm of code.slice(stmtStart, stmtEnd).matchAll(/#([\w-]+)/g))
158
+ tags.push(tm[1]);
159
+ raw.push({
160
+ srcLit: am[1],
161
+ tgtLit: am[2],
162
+ parent: parentId,
163
+ start: stmtStart,
164
+ end: stmtEnd,
165
+ indent: indentOf(stmtStart),
166
+ title,
167
+ op: keyedLiteral("op", bodyFrom, bodyTo),
168
+ publishes: keyedLiteral("publishes", bodyFrom, bodyTo),
169
+ consumes: keyedLiteral("consumes", bodyFrom, bodyTo),
170
+ tags,
171
+ });
172
+ }
173
+ i = Math.max(stmtEnd, headEnd);
174
+ continue;
175
+ }
176
+ if (opener !== -1) {
177
+ const bClose = matchBrace(code, opener);
178
+ i = bClose === -1 ? close : bClose + 1;
179
+ }
180
+ else {
181
+ i = headEnd;
182
+ }
183
+ }
184
+ // Resolve relationship endpoints against everything declared anywhere in the
185
+ // model — LikeC4 resolution is not order-dependent, so neither is this.
186
+ const ids = new Set(elements.map((e) => e.id));
187
+ const byLeaf = new Map();
188
+ for (const e of elements) {
189
+ const leaf = e.id.slice(e.id.lastIndexOf(".") + 1);
190
+ byLeaf.set(leaf, [...(byLeaf.get(leaf) ?? []), e.id]);
191
+ }
192
+ const resolve = (lit, enclosing) => {
193
+ if (lit === undefined || lit === "it" || lit === "this")
194
+ return enclosing;
195
+ const segs = lit.split(".");
196
+ let base;
197
+ for (let scope = enclosing; scope !== "" && base === undefined;) {
198
+ if (ids.has(`${scope}.${segs[0]}`))
199
+ base = `${scope}.${segs[0]}`;
200
+ const dot = scope.lastIndexOf(".");
201
+ scope = dot === -1 ? "" : scope.slice(0, dot);
202
+ }
203
+ if (base === undefined && ids.has(segs[0]))
204
+ base = segs[0];
205
+ if (base === undefined) {
206
+ const leafed = byLeaf.get(segs[0]);
207
+ if (leafed !== undefined && leafed.length === 1)
208
+ base = leafed[0];
209
+ }
210
+ return [base ?? segs[0], ...segs.slice(1)].join(".");
211
+ };
212
+ const rels = raw.map((r) => ({
213
+ source: resolve(r.srcLit, r.parent),
214
+ target: resolve(r.tgtLit, r.parent),
215
+ title: r.title,
216
+ op: r.op,
217
+ publishes: r.publishes,
218
+ consumes: r.consumes,
219
+ tags: r.tags,
220
+ start: r.start,
221
+ end: r.end,
222
+ indent: r.indent,
223
+ }));
224
+ elements.sort((a, b) => a.start - b.start);
225
+ return { open, close, elements, rels };
226
+ }
227
+ //# sourceMappingURL=source-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-scan.js","sourceRoot":"","sources":["../../../src/core/c4/source-scan.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The text-level view of a LikeC4 document: which bytes each declaration owns.\n *\n * loam's archive merges the landscape by SPLICING authored text, not by\n * re-rendering a parsed model — a re-render would reformat every line somebody\n * wrote. So the merge needs both views of the same file: the parsed one\n * (`likec4.ts`) for what the model MEANS, and this one for where each\n * declaration physically is. A key only one of them reads is a key the merge\n * silently drops, which is why `metadata` handling is spelled out in both.\n */\nimport { maskSource, matchBrace, type SourceLiteral } from \"./source-mask.js\";\n\nexport interface ScannedElement {\n /** Full dotted id — `parent.child` for a nested declaration. */\n id: string;\n /** Span of the whole declaration: first head character to one past its end. */\n start: number;\n end: number;\n /** Its own body braces; -1 when the declaration has no body. */\n bodyOpen: number;\n bodyClose: number;\n /** Leading whitespace of the declaration's first line. */\n indent: string;\n}\n\n/** A relationship statement located in source, endpoints resolved to full ids (best effort). */\nexport interface ScannedRel {\n source: string;\n target: string;\n title?: string;\n op?: string;\n /** `metadata { publishes '...' }` — see `Rel.publishes`. */\n publishes?: string;\n /** `metadata { consumes '...' }` — see `Rel.consumes`. */\n consumes?: string;\n tags: string[];\n start: number;\n end: number;\n indent: string;\n}\n\nexport interface ScannedModel {\n /** The `model` block's own braces. */\n open: number;\n close: number;\n /** In document order. A nested declaration's span lies inside its parent's. */\n elements: ScannedElement[];\n rels: ScannedRel[];\n}\n\n/**\n * Locate every element and relationship declaration inside the top-level\n * `model { ... }` block of a LikeC4 source, with the byte range each one\n * occupies. This is the splice map `loam archive` merges the landscape with:\n * the parsed model says WHAT exists, this says WHERE its authored text is —\n * verbatim, so nothing the parser does not model (technology, style, links)\n * can be lost by rebuilding it.\n *\n * Both declaration forms are recognised — `name = kind ...` always, and\n * `kind name ...` for any kind the document's own `specification` block\n * declares. Relationship endpoints are resolved the way LikeC4 reads them:\n * innermost enclosing scope outward, then the top level, then a unique leaf\n * name anywhere; `it`/`this` (and an omitted source) mean the enclosing\n * element. A name that resolves nowhere is left as written — the caller's\n * match against the parsed model then fails loudly instead of guessing.\n *\n * Returns null when there is no model block. Callers only hand in documents\n * LikeC4 has already parsed, so the scan can trust balanced braces.\n */\nexport function scanModel(text: string): ScannedModel | null {\n const { code, literals } = maskSource(text);\n const m = /\\bmodel\\s*\\{/.exec(code);\n if (!m) return null;\n const open = m.index + m[0].length - 1;\n const close = matchBrace(code, open);\n if (close === -1) return null;\n\n // Element kinds from the specification block(s): the `<kind> <name>`\n // declaration form is recognisable only by its first token being a kind.\n const kinds = new Set<string>();\n for (const sm of code.matchAll(/\\bspecification\\s*\\{/g)) {\n const sClose = matchBrace(code, sm.index + sm[0].length - 1);\n if (sClose === -1) continue;\n for (const em of code.slice(sm.index, sClose).matchAll(/\\belement\\s+([A-Za-z_][\\w-]*)/g)) {\n kinds.add(em[1]!);\n }\n }\n\n const indentOf = (at: number): string => {\n const nl = text.lastIndexOf(\"\\n\", at - 1);\n const ws = text.slice(nl + 1, at);\n return /^[ \\t]*$/.test(ws) ? ws : \"\";\n };\n const literalIn = (from: number, to: number): SourceLiteral | undefined =>\n literals.find((l) => l.start >= from && l.end <= to);\n const keyedLiteral = (key: string, from: number, to: number): string | undefined => {\n if (from === -1) return undefined;\n const re = new RegExp(`\\\\b${key}\\\\b`, \"g\");\n re.lastIndex = from;\n const km = re.exec(code);\n if (km === null || km.index >= to) return undefined;\n return literalIn(km.index, to)?.value;\n };\n const trimmedEnd = (from: number, to: number): number => {\n let e = to;\n while (e > from && /\\s/.test(text[e - 1]!)) e -= 1;\n return e;\n };\n\n const elements: ScannedElement[] = [];\n interface RawRel {\n srcLit?: string;\n tgtLit: string;\n parent: string;\n start: number;\n end: number;\n indent: string;\n title?: string;\n op?: string;\n publishes?: string;\n consumes?: string;\n tags: string[];\n }\n const raw: RawRel[] = [];\n const stack: Array<{ id: string; el: ScannedElement }> = [];\n\n let i = open + 1;\n while (i < close) {\n const ch = code[i]!;\n if (/\\s/.test(ch)) {\n i += 1;\n continue;\n }\n if (ch === \"}\") {\n const frame = stack.pop();\n if (frame !== undefined) {\n frame.el.bodyClose = i;\n frame.el.end = i + 1;\n elements.push(frame.el);\n }\n i += 1;\n continue;\n }\n\n // A statement's head: up to its own `{`, the end of the line, or the\n // enclosing block's `}` on the same line — whichever comes first.\n const stmtStart = i;\n let headEnd = close;\n let opener = -1;\n for (let j = i; j < close; j += 1) {\n const c = code[j]!;\n if (c === \"\\n\" || c === \"}\") {\n headEnd = j;\n break;\n }\n if (c === \"{\") {\n opener = j;\n headEnd = j;\n break;\n }\n }\n const head = code.slice(stmtStart, headEnd);\n const parentId = stack.length > 0 ? stack[stack.length - 1]!.id : \"\";\n\n // Classify: `name = kind` first, then a relationship (the arrow cannot hide\n // in a string — the head is masked), then the `kind name` form, else a\n // property/tag line that is consumed whole, nested block included.\n let localName: string | null = null;\n const assign = /^([A-Za-z_]\\w*)\\s*=\\s*[A-Za-z_]/.exec(head);\n if (assign !== null) {\n localName = assign[1]!;\n } else if (!head.includes(\"->\")) {\n const toks = head.trim().split(/\\s+/);\n if (toks.length >= 2 && kinds.has(toks[0]!) && /^[A-Za-z_]\\w*$/.test(toks[1]!)) {\n localName = toks[1]!;\n }\n }\n\n if (localName !== null) {\n const id = parentId === \"\" ? localName : `${parentId}.${localName}`;\n const el: ScannedElement = {\n id,\n start: stmtStart,\n end: headEnd,\n bodyOpen: opener,\n bodyClose: -1,\n indent: indentOf(stmtStart),\n };\n if (opener !== -1) {\n stack.push({ id, el });\n i = opener + 1;\n } else {\n el.end = trimmedEnd(stmtStart, headEnd);\n elements.push(el);\n i = headEnd;\n }\n continue;\n }\n\n if (head.includes(\"->\")) {\n const bClose = opener === -1 ? -1 : matchBrace(code, opener);\n const stmtEnd = opener === -1 ? trimmedEnd(stmtStart, headEnd) : bClose === -1 ? close : bClose + 1;\n const am = /^([A-Za-z_][\\w.]*)?\\s*(?:-\\[[^\\]]*\\])?->\\s*([A-Za-z_][\\w.]*)/.exec(head);\n if (am !== null) {\n const arrowEnd = stmtStart + am[0].length;\n const bodyFrom = opener === -1 ? -1 : opener + 1;\n const bodyTo = opener === -1 ? -1 : stmtEnd - 1;\n const title = literalIn(arrowEnd, headEnd)?.value ?? keyedLiteral(\"title\", bodyFrom, bodyTo);\n const tags: string[] = [];\n for (const tm of code.slice(stmtStart, stmtEnd).matchAll(/#([\\w-]+)/g)) tags.push(tm[1]!);\n raw.push({\n srcLit: am[1],\n tgtLit: am[2]!,\n parent: parentId,\n start: stmtStart,\n end: stmtEnd,\n indent: indentOf(stmtStart),\n title,\n op: keyedLiteral(\"op\", bodyFrom, bodyTo),\n publishes: keyedLiteral(\"publishes\", bodyFrom, bodyTo),\n consumes: keyedLiteral(\"consumes\", bodyFrom, bodyTo),\n tags,\n });\n }\n i = Math.max(stmtEnd, headEnd);\n continue;\n }\n\n if (opener !== -1) {\n const bClose = matchBrace(code, opener);\n i = bClose === -1 ? close : bClose + 1;\n } else {\n i = headEnd;\n }\n }\n\n // Resolve relationship endpoints against everything declared anywhere in the\n // model — LikeC4 resolution is not order-dependent, so neither is this.\n const ids = new Set(elements.map((e) => e.id));\n const byLeaf = new Map<string, string[]>();\n for (const e of elements) {\n const leaf = e.id.slice(e.id.lastIndexOf(\".\") + 1);\n byLeaf.set(leaf, [...(byLeaf.get(leaf) ?? []), e.id]);\n }\n const resolve = (lit: string | undefined, enclosing: string): string => {\n if (lit === undefined || lit === \"it\" || lit === \"this\") return enclosing;\n const segs = lit.split(\".\");\n let base: string | undefined;\n for (let scope = enclosing; scope !== \"\" && base === undefined; ) {\n if (ids.has(`${scope}.${segs[0]!}`)) base = `${scope}.${segs[0]!}`;\n const dot = scope.lastIndexOf(\".\");\n scope = dot === -1 ? \"\" : scope.slice(0, dot);\n }\n if (base === undefined && ids.has(segs[0]!)) base = segs[0]!;\n if (base === undefined) {\n const leafed = byLeaf.get(segs[0]!);\n if (leafed !== undefined && leafed.length === 1) base = leafed[0]!;\n }\n return [base ?? segs[0]!, ...segs.slice(1)].join(\".\");\n };\n\n const rels: ScannedRel[] = raw.map((r) => ({\n source: resolve(r.srcLit, r.parent),\n target: resolve(r.tgtLit, r.parent),\n title: r.title,\n op: r.op,\n publishes: r.publishes,\n consumes: r.consumes,\n tags: r.tags,\n start: r.start,\n end: r.end,\n indent: r.indent,\n }));\n\n elements.sort((a, b) => a.start - b.start);\n return { open, close, elements, rels };\n}\n"]}
@@ -0,0 +1,101 @@
1
+ import { maskSource, matchBrace } from "../source-mask.js";
2
+ /**
3
+ * A declaration's authored source, ready to land in the living landscape:
4
+ * byte-verbatim except that the feature's own tag is stripped and the
5
+ * indentation is rebased from where the block sat in the delta to where it
6
+ * lands. A construct the strip leaves empty goes too — a line that held only
7
+ * the tag disappears whole, and `x = kind 'y' { #FEAT-1 }` lands as
8
+ * `x = kind 'y'`, not as a pair of empty braces.
9
+ */
10
+ export function spliceSource(deltaText, decl, featureId, targetIndent) {
11
+ const block = deltaText.slice(decl.start, decl.end);
12
+ return reindent(stripFeatureTag(block, featureId), decl.indent, targetIndent);
13
+ }
14
+ function stripFeatureTag(block, featureId) {
15
+ const { code } = maskSource(block);
16
+ const esc = featureId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
17
+ const removals = [];
18
+ for (const m of block.matchAll(new RegExp(`#${esc}(?![\\w-])`, "g"))) {
19
+ // Only tags in CODE count — a description quoting "#FEAT-1" is content.
20
+ if (code.slice(m.index, m.index + m[0].length) !== m[0])
21
+ continue;
22
+ let s = m.index;
23
+ let e = s + m[0].length;
24
+ // Take the whitespace on ONE side with the token — trailing first, so
25
+ // `#FEAT-1 #critical` leaves `#critical` at its own indent, and a token at
26
+ // the end of a line does not leave a trailing space behind.
27
+ if (block[e] === " " || block[e] === "\t") {
28
+ while (block[e] === " " || block[e] === "\t")
29
+ e += 1;
30
+ }
31
+ else {
32
+ while (s > 0 && (block[s - 1] === " " || block[s - 1] === "\t"))
33
+ s -= 1;
34
+ }
35
+ removals.push([s, e]);
36
+ }
37
+ if (removals.length === 0)
38
+ return block;
39
+ // A line the strip emptied disappears whole, newline included.
40
+ for (let lineStart = 0; lineStart < block.length;) {
41
+ const nl = block.indexOf("\n", lineStart);
42
+ const lineEnd = nl === -1 ? block.length : nl + 1;
43
+ if (removals.some(([s, e]) => s >= lineStart && e <= lineEnd) &&
44
+ /^\s*$/.test(residual(block, lineStart, nl === -1 ? block.length : nl, removals))) {
45
+ removals.push([lineStart, lineEnd]);
46
+ }
47
+ lineStart = lineEnd;
48
+ }
49
+ // A body the strip emptied goes too, braces and all — but only one the strip
50
+ // emptied: braces that were authored empty are authored bytes and survive.
51
+ for (let at = code.indexOf("{"); at !== -1; at = code.indexOf("{", at + 1)) {
52
+ const closeAt = matchBrace(code, at);
53
+ if (closeAt === -1)
54
+ continue;
55
+ if (!removals.some(([s, e]) => s > at && e <= closeAt))
56
+ continue;
57
+ if (!/^\s*$/.test(residual(block, at + 1, closeAt, removals)))
58
+ continue;
59
+ let s = at;
60
+ while (s > 0 && /\s/.test(block[s - 1]))
61
+ s -= 1;
62
+ removals.push([s, closeAt + 1]);
63
+ }
64
+ return applyRemovals(block, removals);
65
+ }
66
+ /** The text of [from, to) with the removal ranges cut out. */
67
+ function residual(text, from, to, removals) {
68
+ let out = "";
69
+ for (let i = from; i < to; i += 1) {
70
+ if (!removals.some(([s, e]) => i >= s && i < e))
71
+ out += text[i];
72
+ }
73
+ return out;
74
+ }
75
+ function applyRemovals(text, removals) {
76
+ const sorted = [...removals].sort((a, b) => a[0] - b[0] || b[1] - a[1]);
77
+ let out = "";
78
+ let i = 0;
79
+ for (const [s, e] of sorted) {
80
+ if (s > i)
81
+ out += text.slice(i, s);
82
+ if (e > i)
83
+ i = e;
84
+ }
85
+ return out + text.slice(i);
86
+ }
87
+ /**
88
+ * Rebase a block's indentation: the `base` its lines carried in the delta
89
+ * becomes `target`. The first line arrives with no leading whitespace (the
90
+ * scanner's span starts at the declaration itself), so it only gains `target`.
91
+ */
92
+ function reindent(block, base, target) {
93
+ return block
94
+ .split("\n")
95
+ .map((line, k) => {
96
+ const body = k === 0 ? line : line.startsWith(base) ? line.slice(base.length) : line;
97
+ return body.length === 0 ? "" : target + body;
98
+ })
99
+ .join("\n");
100
+ }
101
+ //# sourceMappingURL=authored-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authored-source.js","sourceRoot":"","sources":["../../../../src/core/c4/splice/authored-source.ts"],"names":[],"mappings":"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","sourcesContent":["import { maskSource, matchBrace } from \"../source-mask.js\";\n\n/**\n * A declaration's authored source, ready to land in the living landscape:\n * byte-verbatim except that the feature's own tag is stripped and the\n * indentation is rebased from where the block sat in the delta to where it\n * lands. A construct the strip leaves empty goes too — a line that held only\n * the tag disappears whole, and `x = kind 'y' { #FEAT-1 }` lands as\n * `x = kind 'y'`, not as a pair of empty braces.\n */\nexport function spliceSource(\n deltaText: string,\n decl: { start: number; end: number; indent: string },\n featureId: string,\n targetIndent: string,\n): string {\n const block = deltaText.slice(decl.start, decl.end);\n return reindent(stripFeatureTag(block, featureId), decl.indent, targetIndent);\n}\n\nfunction stripFeatureTag(block: string, featureId: string): string {\n const { code } = maskSource(block);\n const esc = featureId.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const removals: Array<[number, number]> = [];\n for (const m of block.matchAll(new RegExp(`#${esc}(?![\\\\w-])`, \"g\"))) {\n // Only tags in CODE count — a description quoting \"#FEAT-1\" is content.\n if (code.slice(m.index, m.index + m[0].length) !== m[0]) continue;\n let s = m.index;\n let e = s + m[0].length;\n // Take the whitespace on ONE side with the token — trailing first, so\n // `#FEAT-1 #critical` leaves `#critical` at its own indent, and a token at\n // the end of a line does not leave a trailing space behind.\n if (block[e] === \" \" || block[e] === \"\\t\") {\n while (block[e] === \" \" || block[e] === \"\\t\") e += 1;\n } else {\n while (s > 0 && (block[s - 1] === \" \" || block[s - 1] === \"\\t\")) s -= 1;\n }\n removals.push([s, e]);\n }\n if (removals.length === 0) return block;\n\n // A line the strip emptied disappears whole, newline included.\n for (let lineStart = 0; lineStart < block.length; ) {\n const nl = block.indexOf(\"\\n\", lineStart);\n const lineEnd = nl === -1 ? block.length : nl + 1;\n if (\n removals.some(([s, e]) => s >= lineStart && e <= lineEnd) &&\n /^\\s*$/.test(residual(block, lineStart, nl === -1 ? block.length : nl, removals))\n ) {\n removals.push([lineStart, lineEnd]);\n }\n lineStart = lineEnd;\n }\n\n // A body the strip emptied goes too, braces and all — but only one the strip\n // emptied: braces that were authored empty are authored bytes and survive.\n for (let at = code.indexOf(\"{\"); at !== -1; at = code.indexOf(\"{\", at + 1)) {\n const closeAt = matchBrace(code, at);\n if (closeAt === -1) continue;\n if (!removals.some(([s, e]) => s > at && e <= closeAt)) continue;\n if (!/^\\s*$/.test(residual(block, at + 1, closeAt, removals))) continue;\n let s = at;\n while (s > 0 && /\\s/.test(block[s - 1]!)) s -= 1;\n removals.push([s, closeAt + 1]);\n }\n return applyRemovals(block, removals);\n}\n\n/** The text of [from, to) with the removal ranges cut out. */\nfunction residual(text: string, from: number, to: number, removals: Array<[number, number]>): string {\n let out = \"\";\n for (let i = from; i < to; i += 1) {\n if (!removals.some(([s, e]) => i >= s && i < e)) out += text[i];\n }\n return out;\n}\n\nfunction applyRemovals(text: string, removals: Array<[number, number]>): string {\n const sorted = [...removals].sort((a, b) => a[0] - b[0] || b[1] - a[1]);\n let out = \"\";\n let i = 0;\n for (const [s, e] of sorted) {\n if (s > i) out += text.slice(i, s);\n if (e > i) i = e;\n }\n return out + text.slice(i);\n}\n\n/**\n * Rebase a block's indentation: the `base` its lines carried in the delta\n * becomes `target`. The first line arrives with no leading whitespace (the\n * scanner's span starts at the declaration itself), so it only gains `target`.\n */\nfunction reindent(block: string, base: string, target: string): string {\n return block\n .split(\"\\n\")\n .map((line, k) => {\n const body = k === 0 ? line : line.startsWith(base) ? line.slice(base.length) : line;\n return body.length === 0 ? \"\" : target + body;\n })\n .join(\"\\n\");\n}\n"]}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * A landscape merge the splicer could not compute. Every one is mechanical —
3
+ * the input cannot be spliced as authored, never a judgment `--approve` may
4
+ * override — and it is thrown at plan time, so nothing has been written.
5
+ * `archiveErrorCode` (commands/archive/archive.ts) owns the mapping to `merge-failed`;
6
+ * the splicer itself never names a CLI code.
7
+ */
8
+ export class LandscapeSpliceError extends Error {
9
+ }
10
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../../src/core/c4/splice/contract.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;CAAG","sourcesContent":["import type { Elem, Rel } from \"../likec4.js\";\n\n/**\n * A landscape merge the splicer could not compute. Every one is mechanical —\n * the input cannot be spliced as authored, never a judgment `--approve` may\n * override — and it is thrown at plan time, so nothing has been written.\n * `archiveErrorCode` (commands/archive/archive.ts) owns the mapping to `merge-failed`;\n * the splicer itself never names a CLI code.\n */\nexport class LandscapeSpliceError extends Error {}\n\nexport interface LandscapePlan {\n /** The merged landscape source, or null when everything was already there. */\n content: string | null;\n addedEls: Elem[];\n addedRels: Rel[];\n}\n\n/**\n * Everything the landscape splicer reads, as text and parsed views already in\n * hand. The merge is a pure text-to-text computation — reading the two files\n * (and deciding to write the result) stays with the caller, which is also what\n * keeps the splicer free of the staging layer.\n */\nexport interface LandscapeMergeRequest {\n /** The living landscape.likec4, decoded by the caller's readUtf8. */\n landscapeText: string;\n /** delta.likec4 as authored — the bytes the additions are spliced from. */\n deltaText: string;\n /** EVERY element the delta declares — the title join and the parent lookup read past the tagged ones. */\n deltaElements: Elem[];\n /** The delta's elements tagged with the feature: the candidate additions. */\n newEls: Elem[];\n /** The delta's relationships tagged with the feature. */\n newRels: Rel[];\n featureId: string;\n}\n"]}