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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1256) hide show
  1. package/CHANGELOG.md +5992 -82
  2. package/COMPARISON.md +168 -63
  3. package/CONTRIBUTING.md +121 -0
  4. package/MIGRATING-from-OpenSpec.md +238 -55
  5. package/QUICKSTART.md +302 -0
  6. package/README.md +653 -144
  7. package/ROADMAP.md +1035 -0
  8. package/SCHEMA.md +3916 -263
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +927 -0
  11. package/dist/cli.js +133 -21
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +204 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +309 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +74 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/closing.js +42 -0
  20. package/dist/commands/archive/closing.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
  22. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  23. package/dist/commands/archive/plan/contracts/consumers.js +56 -0
  24. package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
  25. package/dist/commands/archive/plan/contracts/openapi.js +193 -0
  26. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  27. package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
  28. package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
  29. package/dist/commands/archive/plan/document/head.js +151 -0
  30. package/dist/commands/archive/plan/document/head.js.map +1 -0
  31. package/dist/commands/archive/plan/document/links.js +284 -0
  32. package/dist/commands/archive/plan/document/links.js.map +1 -0
  33. package/dist/commands/archive/plan/document/run.js +136 -0
  34. package/dist/commands/archive/plan/document/run.js.map +1 -0
  35. package/dist/commands/archive/plan/gate.js +319 -0
  36. package/dist/commands/archive/plan/gate.js.map +1 -0
  37. package/dist/commands/archive/plan/landscape.js +298 -0
  38. package/dist/commands/archive/plan/landscape.js.map +1 -0
  39. package/dist/commands/archive/plan/model/extending.js +85 -0
  40. package/dist/commands/archive/plan/model/extending.js.map +1 -0
  41. package/dist/commands/archive/plan/refusal.js +106 -0
  42. package/dist/commands/archive/plan/refusal.js.map +1 -0
  43. package/dist/commands/archive/plan/specs.js +318 -0
  44. package/dist/commands/archive/plan/specs.js.map +1 -0
  45. package/dist/commands/archive/plan/state.js +30 -0
  46. package/dist/commands/archive/plan/state.js.map +1 -0
  47. package/dist/commands/archive/run.js +355 -0
  48. package/dist/commands/archive/run.js.map +1 -0
  49. package/dist/commands/archive/shipped.js +49 -0
  50. package/dist/commands/archive/shipped.js.map +1 -0
  51. package/dist/commands/context/context.js +166 -0
  52. package/dist/commands/context/context.js.map +1 -0
  53. package/dist/commands/context/print.js +305 -0
  54. package/dist/commands/context/print.js.map +1 -0
  55. package/dist/commands/delta/delta.js +367 -0
  56. package/dist/commands/delta/delta.js.map +1 -0
  57. package/dist/commands/delta/print.js +221 -0
  58. package/dist/commands/delta/print.js.map +1 -0
  59. package/dist/commands/dependencies.js +6 -8
  60. package/dist/commands/dependencies.js.map +1 -1
  61. package/dist/commands/diff/diff.js +86 -0
  62. package/dist/commands/diff/diff.js.map +1 -0
  63. package/dist/commands/diff/print.js +38 -0
  64. package/dist/commands/diff/print.js.map +1 -0
  65. package/dist/commands/doctor.js +65 -5
  66. package/dist/commands/doctor.js.map +1 -1
  67. package/dist/commands/explain/explain.js +227 -0
  68. package/dist/commands/explain/explain.js.map +1 -0
  69. package/dist/commands/explore.js +39 -28
  70. package/dist/commands/explore.js.map +1 -1
  71. package/dist/commands/gate/gate.js +152 -0
  72. package/dist/commands/gate/gate.js.map +1 -0
  73. package/dist/commands/gate/print.js +66 -0
  74. package/dist/commands/gate/print.js.map +1 -0
  75. package/dist/commands/gherkin/commit.js +105 -0
  76. package/dist/commands/gherkin/commit.js.map +1 -0
  77. package/dist/commands/gherkin/gherkin.js +262 -0
  78. package/dist/commands/gherkin/gherkin.js.map +1 -0
  79. package/dist/commands/gherkin/reconcile.js +146 -0
  80. package/dist/commands/gherkin/reconcile.js.map +1 -0
  81. package/dist/commands/gherkin/render.js +77 -0
  82. package/dist/commands/gherkin/render.js.map +1 -0
  83. package/dist/commands/init/example.js +204 -0
  84. package/dist/commands/init/example.js.map +1 -0
  85. package/dist/commands/init/first-hour.js +72 -0
  86. package/dist/commands/init/first-hour.js.map +1 -0
  87. package/dist/commands/{init.js → init/init.js} +142 -71
  88. package/dist/commands/init/init.js.map +1 -0
  89. package/dist/commands/init/mcp.js +131 -0
  90. package/dist/commands/init/mcp.js.map +1 -0
  91. package/dist/commands/init/options.js +78 -0
  92. package/dist/commands/init/options.js.map +1 -0
  93. package/dist/commands/instructions.js +72 -14
  94. package/dist/commands/instructions.js.map +1 -1
  95. package/dist/commands/list/campaign/campaign.js +63 -0
  96. package/dist/commands/list/campaign/campaign.js.map +1 -0
  97. package/dist/commands/list/campaign/owners.js +65 -0
  98. package/dist/commands/list/campaign/owners.js.map +1 -0
  99. package/dist/commands/list/json.js +155 -0
  100. package/dist/commands/list/json.js.map +1 -0
  101. package/dist/commands/list/list.js +358 -0
  102. package/dist/commands/list/list.js.map +1 -0
  103. package/dist/commands/list/print.js +344 -0
  104. package/dist/commands/list/print.js.map +1 -0
  105. package/dist/commands/list/review.js +120 -0
  106. package/dist/commands/list/review.js.map +1 -0
  107. package/dist/commands/list/suites/suites.js +140 -0
  108. package/dist/commands/list/suites/suites.js.map +1 -0
  109. package/dist/commands/list/views.js +108 -0
  110. package/dist/commands/list/views.js.map +1 -0
  111. package/dist/commands/mcp/dispatch.js +238 -0
  112. package/dist/commands/mcp/dispatch.js.map +1 -0
  113. package/dist/commands/mcp/mcp.js +75 -0
  114. package/dist/commands/mcp/mcp.js.map +1 -0
  115. package/dist/commands/mcp/serve.js +55 -0
  116. package/dist/commands/mcp/serve.js.map +1 -0
  117. package/dist/commands/migrate-openspec/materialize/active.js +175 -0
  118. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  119. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  120. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  121. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  122. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  123. package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
  124. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  125. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  126. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  127. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  128. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  129. package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
  130. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  131. package/dist/commands/migrate-openspec/openspec/error.js +18 -0
  132. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  133. package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
  134. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  135. package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
  136. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  137. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  138. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  139. package/dist/commands/migrate-openspec/print.js +89 -0
  140. package/dist/commands/migrate-openspec/print.js.map +1 -0
  141. package/dist/commands/new/capability-template.js +118 -0
  142. package/dist/commands/new/capability-template.js.map +1 -0
  143. package/dist/commands/new/commit.js +62 -0
  144. package/dist/commands/new/commit.js.map +1 -0
  145. package/dist/commands/new/modifies.js +206 -0
  146. package/dist/commands/new/modifies.js.map +1 -0
  147. package/dist/commands/new/new.js +328 -0
  148. package/dist/commands/new/new.js.map +1 -0
  149. package/dist/commands/new/templates.js +279 -0
  150. package/dist/commands/new/templates.js.map +1 -0
  151. package/dist/commands/open.js +199 -0
  152. package/dist/commands/open.js.map +1 -0
  153. package/dist/commands/policy/format.js +152 -0
  154. package/dist/commands/policy/format.js.map +1 -0
  155. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
  156. package/dist/commands/policy/gate.js.map +1 -0
  157. package/dist/commands/rebase/edit.js +106 -0
  158. package/dist/commands/rebase/edit.js.map +1 -0
  159. package/dist/commands/rebase/living.js +185 -0
  160. package/dist/commands/rebase/living.js.map +1 -0
  161. package/dist/commands/rebase/plan.js +245 -0
  162. package/dist/commands/rebase/plan.js.map +1 -0
  163. package/dist/commands/rebase/rebase.js +300 -0
  164. package/dist/commands/rebase/rebase.js.map +1 -0
  165. package/dist/commands/seed/commit.js +221 -0
  166. package/dist/commands/seed/commit.js.map +1 -0
  167. package/dist/commands/seed/plan.js +278 -0
  168. package/dist/commands/seed/plan.js.map +1 -0
  169. package/dist/commands/seed/seed.js +174 -0
  170. package/dist/commands/seed/seed.js.map +1 -0
  171. package/dist/commands/show/feature.js +182 -0
  172. package/dist/commands/show/feature.js.map +1 -0
  173. package/dist/commands/show/introduced.js +157 -0
  174. package/dist/commands/show/introduced.js.map +1 -0
  175. package/dist/commands/show/marks.js +53 -0
  176. package/dist/commands/show/marks.js.map +1 -0
  177. package/dist/commands/show/service.js +239 -0
  178. package/dist/commands/show/service.js.map +1 -0
  179. package/dist/commands/show/show.js +87 -0
  180. package/dist/commands/show/show.js.map +1 -0
  181. package/dist/commands/status/fleet-next.js +90 -0
  182. package/dist/commands/status/fleet-next.js.map +1 -0
  183. package/dist/commands/status/json.js +47 -0
  184. package/dist/commands/status/json.js.map +1 -0
  185. package/dist/commands/status/print.js +209 -0
  186. package/dist/commands/status/print.js.map +1 -0
  187. package/dist/commands/status/status.js +115 -0
  188. package/dist/commands/status/status.js.map +1 -0
  189. package/dist/commands/steps/steps.js +269 -0
  190. package/dist/commands/steps/steps.js.map +1 -0
  191. package/dist/commands/subsystem/edit.js +192 -0
  192. package/dist/commands/subsystem/edit.js.map +1 -0
  193. package/dist/commands/subsystem/move.js +325 -0
  194. package/dist/commands/subsystem/move.js.map +1 -0
  195. package/dist/commands/subsystem/query.js +113 -0
  196. package/dist/commands/subsystem/query.js.map +1 -0
  197. package/dist/commands/subsystem/subsystem.js +98 -0
  198. package/dist/commands/subsystem/subsystem.js.map +1 -0
  199. package/dist/commands/subsystem/sync.js +318 -0
  200. package/dist/commands/subsystem/sync.js.map +1 -0
  201. package/dist/commands/subsystem/txn/exclude.js +132 -0
  202. package/dist/commands/subsystem/txn/exclude.js.map +1 -0
  203. package/dist/commands/subsystem/txn/links.js +128 -0
  204. package/dist/commands/subsystem/txn/links.js.map +1 -0
  205. package/dist/commands/subsystem/txn/report.js +174 -0
  206. package/dist/commands/subsystem/txn/report.js.map +1 -0
  207. package/dist/commands/subsystem/txn/txn.js +196 -0
  208. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  209. package/dist/commands/subsystem/txn/views.js +249 -0
  210. package/dist/commands/subsystem/txn/views.js.map +1 -0
  211. package/dist/commands/tasks/actions.js +107 -0
  212. package/dist/commands/tasks/actions.js.map +1 -0
  213. package/dist/commands/tasks/render.js +253 -0
  214. package/dist/commands/tasks/render.js.map +1 -0
  215. package/dist/commands/tasks/tasks.js +119 -0
  216. package/dist/commands/tasks/tasks.js.map +1 -0
  217. package/dist/commands/unarchive/manifest.js +176 -0
  218. package/dist/commands/unarchive/manifest.js.map +1 -0
  219. package/dist/commands/unarchive/restore.js +254 -0
  220. package/dist/commands/unarchive/restore.js.map +1 -0
  221. package/dist/commands/unarchive/unarchive.js +59 -0
  222. package/dist/commands/unarchive/unarchive.js.map +1 -0
  223. package/dist/commands/validate/arch-coverage.js +245 -0
  224. package/dist/commands/validate/arch-coverage.js.map +1 -0
  225. package/dist/commands/validate/checks/fleet-shape.js +204 -0
  226. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  227. package/dist/commands/validate/checks/health-deps.js +58 -0
  228. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  229. package/dist/commands/validate/checks/introduced.js +102 -0
  230. package/dist/commands/validate/checks/introduced.js.map +1 -0
  231. package/dist/commands/validate/checks/requirements.js +264 -0
  232. package/dist/commands/validate/checks/requirements.js.map +1 -0
  233. package/dist/commands/validate/checks/sources.js +85 -0
  234. package/dist/commands/validate/checks/sources.js.map +1 -0
  235. package/dist/commands/validate/coverage/covers-after.js +105 -0
  236. package/dist/commands/validate/coverage/covers-after.js.map +1 -0
  237. package/dist/commands/validate/feature.js +222 -0
  238. package/dist/commands/validate/feature.js.map +1 -0
  239. package/dist/commands/validate/fleet/census.js +93 -0
  240. package/dist/commands/validate/fleet/census.js.map +1 -0
  241. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  242. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  243. package/dist/commands/validate/fleet/landscape.js +371 -0
  244. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  245. package/dist/commands/validate/fleet/load.js +118 -0
  246. package/dist/commands/validate/fleet/load.js.map +1 -0
  247. package/dist/commands/validate/fleet/map/attest.js +98 -0
  248. package/dist/commands/validate/fleet/map/attest.js.map +1 -0
  249. package/dist/commands/validate/fleet/map/bindings.js +107 -0
  250. package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
  251. package/dist/commands/validate/fleet/map/consumers.js +244 -0
  252. package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
  253. package/dist/commands/validate/fleet/map/isolation.js +116 -0
  254. package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
  255. package/dist/commands/validate/fleet/map/usecases.js +54 -0
  256. package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
  257. package/dist/commands/validate/fleet/obligations.js +266 -0
  258. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  259. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  260. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  261. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  262. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  263. package/dist/commands/validate/fleet/scorecard/print.js +71 -0
  264. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  265. package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
  266. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  267. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  268. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  269. package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
  270. package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
  271. package/dist/commands/validate/fleet/views/ids.js +75 -0
  272. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  273. package/dist/commands/validate/fleet/views/projects.js +278 -0
  274. package/dist/commands/validate/fleet/views/projects.js.map +1 -0
  275. package/dist/commands/validate/fleet/views/root-documents.js +83 -0
  276. package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
  277. package/dist/commands/validate/fleet/views/stale.js +52 -0
  278. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  279. package/dist/commands/validate/links/corpus.js +89 -0
  280. package/dist/commands/validate/links/corpus.js.map +1 -0
  281. package/dist/commands/validate/links/glossary.js +75 -0
  282. package/dist/commands/validate/links/glossary.js.map +1 -0
  283. package/dist/commands/validate/render/repeats.js +63 -0
  284. package/dist/commands/validate/render/repeats.js.map +1 -0
  285. package/dist/commands/validate/render/rollups.js +115 -0
  286. package/dist/commands/validate/render/rollups.js.map +1 -0
  287. package/dist/commands/validate/render/text.js +199 -0
  288. package/dist/commands/validate/render/text.js.map +1 -0
  289. package/dist/commands/validate/report.js +145 -0
  290. package/dist/commands/validate/report.js.map +1 -0
  291. package/dist/commands/validate/scope.js +113 -0
  292. package/dist/commands/validate/scope.js.map +1 -0
  293. package/dist/commands/validate/service/api.js +252 -0
  294. package/dist/commands/validate/service/api.js.map +1 -0
  295. package/dist/commands/validate/service/contracts/generated.js +134 -0
  296. package/dist/commands/validate/service/contracts/generated.js.map +1 -0
  297. package/dist/commands/validate/service/events/events.js +241 -0
  298. package/dist/commands/validate/service/events/events.js.map +1 -0
  299. package/dist/commands/validate/service/events/message-producers.js +77 -0
  300. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  301. package/dist/commands/validate/service/evidence-pins.js +177 -0
  302. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  303. package/dist/commands/validate/service/model/diverged.js +226 -0
  304. package/dist/commands/validate/service/model/diverged.js.map +1 -0
  305. package/dist/commands/validate/service/model/grade.js +163 -0
  306. package/dist/commands/validate/service/model/grade.js.map +1 -0
  307. package/dist/commands/validate/service/service.js +310 -0
  308. package/dist/commands/validate/service/service.js.map +1 -0
  309. package/dist/commands/validate/service/specs.js +279 -0
  310. package/dist/commands/validate/service/specs.js.map +1 -0
  311. package/dist/commands/validate/service/spine.js +148 -0
  312. package/dist/commands/validate/service/spine.js.map +1 -0
  313. package/dist/commands/validate/service/usecases/tags.js +113 -0
  314. package/dist/commands/validate/service/usecases/tags.js.map +1 -0
  315. package/dist/commands/validate/service/usecases/usecases.js +209 -0
  316. package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
  317. package/dist/commands/validate/validate.js +363 -0
  318. package/dist/commands/validate/validate.js.map +1 -0
  319. package/dist/commands/verify/cross/diff.js +178 -0
  320. package/dist/commands/verify/cross/diff.js.map +1 -0
  321. package/dist/commands/verify/evidence/contract.js +32 -0
  322. package/dist/commands/verify/evidence/contract.js.map +1 -0
  323. package/dist/commands/verify/evidence/pins.js +52 -0
  324. package/dist/commands/verify/evidence/pins.js.map +1 -0
  325. package/dist/commands/verify/evidence/read.js +81 -0
  326. package/dist/commands/verify/evidence/read.js.map +1 -0
  327. package/dist/commands/verify/frozen.js +263 -0
  328. package/dist/commands/verify/frozen.js.map +1 -0
  329. package/dist/commands/verify/record.js +278 -0
  330. package/dist/commands/verify/record.js.map +1 -0
  331. package/dist/commands/verify/report.js +206 -0
  332. package/dist/commands/verify/report.js.map +1 -0
  333. package/dist/commands/verify/results.js +328 -0
  334. package/dist/commands/verify/results.js.map +1 -0
  335. package/dist/commands/verify/verify.js +220 -0
  336. package/dist/commands/verify/verify.js.map +1 -0
  337. package/dist/commands/vouch/contract.js +11 -0
  338. package/dist/commands/vouch/contract.js.map +1 -0
  339. package/dist/commands/vouch/pack/contract.js +2 -0
  340. package/dist/commands/vouch/pack/contract.js.map +1 -0
  341. package/dist/commands/vouch/pack/pack.js +266 -0
  342. package/dist/commands/vouch/pack/pack.js.map +1 -0
  343. package/dist/commands/vouch/pack/print.js +266 -0
  344. package/dist/commands/vouch/pack/print.js.map +1 -0
  345. package/dist/commands/vouch/pack/sections.js +141 -0
  346. package/dist/commands/vouch/pack/sections.js.map +1 -0
  347. package/dist/commands/vouch/prompt/confirm.js +46 -0
  348. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  349. package/dist/commands/vouch/report.js +101 -0
  350. package/dist/commands/vouch/report.js.map +1 -0
  351. package/dist/commands/vouch/run.js +230 -0
  352. package/dist/commands/vouch/run.js.map +1 -0
  353. package/dist/commands/vouch/sample/plan.js +111 -0
  354. package/dist/commands/vouch/sample/plan.js.map +1 -0
  355. package/dist/commands/vouch/sample/print.js +109 -0
  356. package/dist/commands/vouch/sample/print.js.map +1 -0
  357. package/dist/commands/vouch/vet/verify.js +155 -0
  358. package/dist/commands/vouch/vet/verify.js.map +1 -0
  359. package/dist/commands/vouch/vouch.js +169 -0
  360. package/dist/commands/vouch/vouch.js.map +1 -0
  361. package/dist/core/agent/agents-md/command-map.js +299 -0
  362. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  363. package/dist/core/agent/agents-md/map/explain.js +46 -0
  364. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  365. package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
  366. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  367. package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
  368. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  369. package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
  370. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  371. package/dist/core/agent/agents-md/map/mcp.js +44 -0
  372. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  373. package/dist/core/agent/agents-md/map/status.js +78 -0
  374. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  375. package/dist/core/agent/agents-md/map/subsystem.js +104 -0
  376. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  377. package/dist/core/agent/agents-md/map/usecases.js +138 -0
  378. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  379. package/dist/core/agent/agents-md/refusals.js +273 -0
  380. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  381. package/dist/core/agent/agents-md.js +203 -0
  382. package/dist/core/agent/agents-md.js.map +1 -0
  383. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
  384. package/dist/core/agent/agents-stamp.js.map +1 -0
  385. package/dist/core/agent/contract.js +2 -0
  386. package/dist/core/agent/contract.js.map +1 -0
  387. package/dist/core/agent/protocol.js +193 -0
  388. package/dist/core/agent/protocol.js.map +1 -0
  389. package/dist/core/agent/scaffold.js +254 -0
  390. package/dist/core/agent/scaffold.js.map +1 -0
  391. package/dist/core/agent/support/report.js +144 -0
  392. package/dist/core/agent/support/report.js.map +1 -0
  393. package/dist/core/agent/tools/dialects.js +151 -0
  394. package/dist/core/agent/tools/dialects.js.map +1 -0
  395. package/dist/core/agent/tools/registry.js +193 -0
  396. package/dist/core/agent/tools/registry.js.map +1 -0
  397. package/dist/core/agent/workflows/adopt.js +280 -0
  398. package/dist/core/agent/workflows/adopt.js.map +1 -0
  399. package/dist/core/agent/workflows/check.js +373 -0
  400. package/dist/core/agent/workflows/check.js.map +1 -0
  401. package/dist/core/agent/workflows/closing.js +323 -0
  402. package/dist/core/agent/workflows/closing.js.map +1 -0
  403. package/dist/core/agent/workflows/feature.js +220 -0
  404. package/dist/core/agent/workflows/feature.js.map +1 -0
  405. package/dist/core/agent/workflows/implement.js +188 -0
  406. package/dist/core/agent/workflows/implement.js.map +1 -0
  407. package/dist/core/agent/workflows/reference/authoring.js +311 -0
  408. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  409. package/dist/core/agent/workflows/reference/codes.js +67 -0
  410. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  411. package/dist/core/agent/workflows/reference/done-check.js +210 -0
  412. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  413. package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
  414. package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
  415. package/dist/core/agent/workflows/reference/reference.js +19 -0
  416. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  417. package/dist/core/agent/workflows/reference/spine.js +338 -0
  418. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  419. package/dist/core/asyncapi/baseline/plan.js +43 -0
  420. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  421. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  422. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  423. package/dist/core/asyncapi/depth.js +164 -0
  424. package/dist/core/asyncapi/depth.js.map +1 -0
  425. package/dist/core/asyncapi/digest.js +146 -0
  426. package/dist/core/asyncapi/digest.js.map +1 -0
  427. package/dist/core/asyncapi/merge/components.js +92 -0
  428. package/dist/core/asyncapi/merge/components.js.map +1 -0
  429. package/dist/core/asyncapi/merge/error.js +38 -0
  430. package/dist/core/asyncapi/merge/error.js.map +1 -0
  431. package/dist/core/asyncapi/merge/markers.js +290 -0
  432. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  433. package/dist/core/asyncapi/merge/merge.js +195 -0
  434. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  435. package/dist/core/asyncapi/merge/pin.js +83 -0
  436. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  437. package/dist/core/asyncapi/model.js +11 -0
  438. package/dist/core/asyncapi/model.js.map +1 -0
  439. package/dist/core/asyncapi/producers.js +50 -0
  440. package/dist/core/asyncapi/producers.js.map +1 -0
  441. package/dist/core/asyncapi/read.js +263 -0
  442. package/dist/core/asyncapi/read.js.map +1 -0
  443. package/dist/core/brief/brief.js +285 -0
  444. package/dist/core/brief/brief.js.map +1 -0
  445. package/dist/core/brief/checks.js +385 -0
  446. package/dist/core/brief/checks.js.map +1 -0
  447. package/dist/core/brief/landscape.js +273 -0
  448. package/dist/core/brief/landscape.js.map +1 -0
  449. package/dist/core/brief/map/extend.js +84 -0
  450. package/dist/core/brief/map/extend.js.map +1 -0
  451. package/dist/core/brief/map/owed.js +266 -0
  452. package/dist/core/brief/map/owed.js.map +1 -0
  453. package/dist/core/brief/targets.js +304 -0
  454. package/dist/core/brief/targets.js.map +1 -0
  455. package/dist/core/brief/unchecked.js +58 -0
  456. package/dist/core/brief/unchecked.js.map +1 -0
  457. package/dist/core/c4/arch.js +190 -0
  458. package/dist/core/c4/arch.js.map +1 -0
  459. package/dist/core/c4/direction/direction.js +114 -0
  460. package/dist/core/c4/direction/direction.js.map +1 -0
  461. package/dist/core/c4/likec4.js +243 -0
  462. package/dist/core/c4/likec4.js.map +1 -0
  463. package/dist/core/c4/locate/unlocated.js +150 -0
  464. package/dist/core/c4/locate/unlocated.js.map +1 -0
  465. package/dist/core/c4/parsed/deployment.js +160 -0
  466. package/dist/core/c4/parsed/deployment.js.map +1 -0
  467. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  468. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  469. package/dist/core/c4/parsed/specification.js +78 -0
  470. package/dist/core/c4/parsed/specification.js.map +1 -0
  471. package/dist/core/c4/parsed/values.js +110 -0
  472. package/dist/core/c4/parsed/values.js.map +1 -0
  473. package/dist/core/c4/parsed/view-ids.js +113 -0
  474. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  475. package/dist/core/c4/prefetch/fleet.js +134 -0
  476. package/dist/core/c4/prefetch/fleet.js.map +1 -0
  477. package/dist/core/c4/project/architecture.js +161 -0
  478. package/dist/core/c4/project/architecture.js.map +1 -0
  479. package/dist/core/c4/project/batch.js +140 -0
  480. package/dist/core/c4/project/batch.js.map +1 -0
  481. package/dist/core/c4/project/documents.js +89 -0
  482. package/dist/core/c4/project/documents.js.map +1 -0
  483. package/dist/core/c4/project/load.js +219 -0
  484. package/dist/core/c4/project/load.js.map +1 -0
  485. package/dist/core/c4/project/staged.js +277 -0
  486. package/dist/core/c4/project/staged.js.map +1 -0
  487. package/dist/core/c4/resolve/attested.js +0 -0
  488. package/dist/core/c4/resolve/attested.js.map +1 -0
  489. package/dist/core/c4/resolve/external.js +51 -0
  490. package/dist/core/c4/resolve/external.js.map +1 -0
  491. package/dist/core/c4/resolve/service.js +174 -0
  492. package/dist/core/c4/resolve/service.js.map +1 -0
  493. package/dist/core/c4/resolve/steps.js +290 -0
  494. package/dist/core/c4/resolve/steps.js.map +1 -0
  495. package/dist/core/c4/resolve/systems.js +154 -0
  496. package/dist/core/c4/resolve/systems.js.map +1 -0
  497. package/dist/core/c4/root-project/exclude.js +352 -0
  498. package/dist/core/c4/root-project/exclude.js.map +1 -0
  499. package/dist/core/c4/seed/fleet-file.js +201 -0
  500. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  501. package/dist/core/c4/seed/items.js +91 -0
  502. package/dist/core/c4/seed/items.js.map +1 -0
  503. package/dist/core/c4/seed/stamp.js +48 -0
  504. package/dist/core/c4/seed/stamp.js.map +1 -0
  505. package/dist/core/c4/seed/template.js +173 -0
  506. package/dist/core/c4/seed/template.js.map +1 -0
  507. package/dist/core/c4/service-model/created/models.js +96 -0
  508. package/dist/core/c4/service-model/created/models.js.map +1 -0
  509. package/dist/core/c4/service-model/documents.js +47 -0
  510. package/dist/core/c4/service-model/documents.js.map +1 -0
  511. package/dist/core/c4/service-model/fleet/extending.js +82 -0
  512. package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
  513. package/dist/core/c4/service-model/load.js +165 -0
  514. package/dist/core/c4/service-model/load.js.map +1 -0
  515. package/dist/core/c4/service-model/renderer.js +128 -0
  516. package/dist/core/c4/service-model/renderer.js.map +1 -0
  517. package/dist/core/c4/service-model/shape.js +106 -0
  518. package/dist/core/c4/service-model/shape.js.map +1 -0
  519. package/dist/core/c4/service-model/slice.js +188 -0
  520. package/dist/core/c4/service-model/slice.js.map +1 -0
  521. package/dist/core/c4/source-mask.js +369 -0
  522. package/dist/core/c4/source-mask.js.map +1 -0
  523. package/dist/core/c4/source-scan.js +308 -0
  524. package/dist/core/c4/source-scan.js.map +1 -0
  525. package/dist/core/c4/splice/authored-source.js +167 -0
  526. package/dist/core/c4/splice/authored-source.js.map +1 -0
  527. package/dist/core/c4/splice/contract.js +30 -0
  528. package/dist/core/c4/splice/contract.js.map +1 -0
  529. package/dist/core/c4/splice/delta-blocks.js +126 -0
  530. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  531. package/dist/core/c4/splice/identity/declared.js +87 -0
  532. package/dist/core/c4/splice/identity/declared.js.map +1 -0
  533. package/dist/core/c4/splice/identity/edges.js +73 -0
  534. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  535. package/dist/core/c4/splice/identity/existing.js +80 -0
  536. package/dist/core/c4/splice/identity/existing.js.map +1 -0
  537. package/dist/core/c4/splice/identity/interior.js +80 -0
  538. package/dist/core/c4/splice/identity/interior.js.map +1 -0
  539. package/dist/core/c4/splice/identity/owner.js +50 -0
  540. package/dist/core/c4/splice/identity/owner.js.map +1 -0
  541. package/dist/core/c4/splice/landscape-merge.js +337 -0
  542. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  543. package/dist/core/c4/splice/model/merge.js +151 -0
  544. package/dist/core/c4/splice/model/merge.js.map +1 -0
  545. package/dist/core/c4/splice/placement.js +298 -0
  546. package/dist/core/c4/splice/placement.js.map +1 -0
  547. package/dist/core/c4/splice/text/spot.js +131 -0
  548. package/dist/core/c4/splice/text/spot.js.map +1 -0
  549. package/dist/core/c4/workspace.js +166 -0
  550. package/dist/core/c4/workspace.js.map +1 -0
  551. package/dist/core/capabilities/authoring/notes.js +141 -0
  552. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  553. package/dist/core/capabilities/capabilities.js +124 -0
  554. package/dist/core/capabilities/capabilities.js.map +1 -0
  555. package/dist/core/capabilities/delta/doc.js +47 -0
  556. package/dist/core/capabilities/delta/doc.js.map +1 -0
  557. package/dist/core/capabilities/delta/overlay.js +129 -0
  558. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  559. package/dist/core/capabilities/delta/summary.js +57 -0
  560. package/dist/core/capabilities/delta/summary.js.map +1 -0
  561. package/dist/core/capabilities/delta/tree.js +43 -0
  562. package/dist/core/capabilities/delta/tree.js.map +1 -0
  563. package/dist/core/capabilities/delta/uncovered.js +222 -0
  564. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  565. package/dist/core/capabilities/findings.js +338 -0
  566. package/dist/core/capabilities/findings.js.map +1 -0
  567. package/dist/core/capabilities/realizes/findings.js +174 -0
  568. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  569. package/dist/core/capabilities/realizes/join.js +123 -0
  570. package/dist/core/capabilities/realizes/join.js.map +1 -0
  571. package/dist/core/capabilities/rollup.js +205 -0
  572. package/dist/core/capabilities/rollup.js.map +1 -0
  573. package/dist/core/capabilities/tree.js +104 -0
  574. package/dist/core/capabilities/tree.js.map +1 -0
  575. package/dist/core/capabilities/usecase-join.js +267 -0
  576. package/dist/core/capabilities/usecase-join.js.map +1 -0
  577. package/dist/core/coherence/authoring/scaffold.js +185 -0
  578. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  579. package/dist/core/coherence/authoring/sentinels.js +75 -0
  580. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  581. package/dist/core/coherence/calls/called.js +52 -0
  582. package/dist/core/coherence/calls/called.js.map +1 -0
  583. package/dist/core/coherence/coherence.js +332 -0
  584. package/dist/core/coherence/coherence.js.map +1 -0
  585. package/dist/core/coherence/consumed/operations.js +70 -0
  586. package/dist/core/coherence/consumed/operations.js.map +1 -0
  587. package/dist/core/coherence/consumed/refusal.js +38 -0
  588. package/dist/core/coherence/consumed/refusal.js.map +1 -0
  589. package/dist/core/coherence/covers/health.js +85 -0
  590. package/dist/core/coherence/covers/health.js.map +1 -0
  591. package/dist/core/coherence/declared.js +295 -0
  592. package/dist/core/coherence/declared.js.map +1 -0
  593. package/dist/core/coherence/events/declared.js +191 -0
  594. package/dist/core/coherence/events/declared.js.map +1 -0
  595. package/dist/core/coherence/events/events.js +335 -0
  596. package/dist/core/coherence/events/events.js.map +1 -0
  597. package/dist/core/coherence/events/grades.js +189 -0
  598. package/dist/core/coherence/events/grades.js.map +1 -0
  599. package/dist/core/coherence/events/lookups.js +63 -0
  600. package/dist/core/coherence/events/lookups.js.map +1 -0
  601. package/dist/core/coherence/events/produced.js +100 -0
  602. package/dist/core/coherence/events/produced.js.map +1 -0
  603. package/dist/core/coherence/living.js +198 -0
  604. package/dist/core/coherence/living.js.map +1 -0
  605. package/dist/core/coherence/lookups.js +95 -0
  606. package/dist/core/coherence/lookups.js.map +1 -0
  607. package/dist/core/coherence/pending.js +39 -0
  608. package/dist/core/coherence/pending.js.map +1 -0
  609. package/dist/core/coherence/retired/archived.js +285 -0
  610. package/dist/core/coherence/retired/archived.js.map +1 -0
  611. package/dist/core/coherence/retired/event-pair.js +62 -0
  612. package/dist/core/coherence/retired/event-pair.js.map +1 -0
  613. package/dist/core/coherence/retired/merged.js +79 -0
  614. package/dist/core/coherence/retired/merged.js.map +1 -0
  615. package/dist/core/coherence/retired/retirement.js +49 -0
  616. package/dist/core/coherence/retired/retirement.js.map +1 -0
  617. package/dist/core/coherence/retired/revival/arrivals.js +131 -0
  618. package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
  619. package/dist/core/coherence/retired/revival/revived.js +297 -0
  620. package/dist/core/coherence/retired/revival/revived.js.map +1 -0
  621. package/dist/core/conflict-markers.js +60 -0
  622. package/dist/core/conflict-markers.js.map +1 -0
  623. package/dist/core/consumers/after.js +113 -0
  624. package/dist/core/consumers/after.js.map +1 -0
  625. package/dist/core/consumers/consumers.js +296 -0
  626. package/dist/core/consumers/consumers.js.map +1 -0
  627. package/dist/core/consumers/current.js +211 -0
  628. package/dist/core/consumers/current.js.map +1 -0
  629. package/dist/core/consumers/scan.js +46 -0
  630. package/dist/core/consumers/scan.js.map +1 -0
  631. package/dist/core/consumers/state.js +27 -0
  632. package/dist/core/consumers/state.js.map +1 -0
  633. package/dist/core/delta/claims.js +73 -0
  634. package/dist/core/delta/claims.js.map +1 -0
  635. package/dist/core/delta/delta.js +341 -0
  636. package/dist/core/delta/delta.js.map +1 -0
  637. package/dist/core/delta/document.js +177 -0
  638. package/dist/core/delta/document.js.map +1 -0
  639. package/dist/core/delta/scope.js +48 -0
  640. package/dist/core/delta/scope.js.map +1 -0
  641. package/dist/core/delta/select.js +237 -0
  642. package/dist/core/delta/select.js.map +1 -0
  643. package/dist/core/dependencies/dependencies.js +141 -0
  644. package/dist/core/dependencies/dependencies.js.map +1 -0
  645. package/dist/core/dependencies/facts.js +165 -0
  646. package/dist/core/dependencies/facts.js.map +1 -0
  647. package/dist/core/dependencies/fanin.js +88 -0
  648. package/dist/core/dependencies/fanin.js.map +1 -0
  649. package/dist/core/dependencies/graph.js +106 -0
  650. package/dist/core/dependencies/graph.js.map +1 -0
  651. package/dist/core/deployment/delta.js +191 -0
  652. package/dist/core/deployment/delta.js.map +1 -0
  653. package/dist/core/deployment/objects.js +145 -0
  654. package/dist/core/deployment/objects.js.map +1 -0
  655. package/dist/core/diff/base-git.js +230 -0
  656. package/dist/core/diff/base-git.js.map +1 -0
  657. package/dist/core/diff/base-state.js +237 -0
  658. package/dist/core/diff/base-state.js.map +1 -0
  659. package/dist/core/diff/joins.js +136 -0
  660. package/dist/core/diff/joins.js.map +1 -0
  661. package/dist/core/diff/scope/changed-paths.js +204 -0
  662. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  663. package/dist/core/diff/scope/edges.js +82 -0
  664. package/dist/core/diff/scope/edges.js.map +1 -0
  665. package/dist/core/diff/semantic.js +312 -0
  666. package/dist/core/diff/semantic.js.map +1 -0
  667. package/dist/core/docs.js +37 -85
  668. package/dist/core/docs.js.map +1 -1
  669. package/dist/core/doctor/agents.js +238 -0
  670. package/dist/core/doctor/agents.js.map +1 -0
  671. package/dist/core/doctor/config.js +139 -0
  672. package/dist/core/doctor/config.js.map +1 -0
  673. package/dist/core/doctor/doctor.js +355 -0
  674. package/dist/core/doctor/doctor.js.map +1 -0
  675. package/dist/core/doctor/report.js +13 -0
  676. package/dist/core/doctor/report.js.map +1 -0
  677. package/dist/core/doctor/reports/scan.js +242 -0
  678. package/dist/core/doctor/reports/scan.js.map +1 -0
  679. package/dist/core/doctor/residue.js +110 -0
  680. package/dist/core/doctor/residue.js.map +1 -0
  681. package/dist/core/document/apply.js +224 -0
  682. package/dist/core/document/apply.js.map +1 -0
  683. package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
  684. package/dist/core/document/frontmatter.js.map +1 -0
  685. package/dist/core/document/grammar/directives.js +143 -0
  686. package/dist/core/document/grammar/directives.js.map +1 -0
  687. package/dist/core/document/parse.js +286 -0
  688. package/dist/core/document/parse.js.map +1 -0
  689. package/dist/core/document/scenarios.js +238 -0
  690. package/dist/core/document/scenarios.js.map +1 -0
  691. package/dist/core/document/spec.js +234 -0
  692. package/dist/core/document/spec.js.map +1 -0
  693. package/dist/core/{config.js → envelope/config.js} +89 -18
  694. package/dist/core/envelope/config.js.map +1 -0
  695. package/dist/core/envelope/json.js +209 -0
  696. package/dist/core/envelope/json.js.map +1 -0
  697. package/dist/core/{version.js → envelope/version.js} +3 -3
  698. package/dist/core/envelope/version.js.map +1 -0
  699. package/dist/core/explain/families.js +180 -0
  700. package/dist/core/explain/families.js.map +1 -0
  701. package/dist/core/explain/fix-tables.js +178 -0
  702. package/dist/core/explain/fix-tables.js.map +1 -0
  703. package/dist/core/explain/lookup.js +194 -0
  704. package/dist/core/explain/lookup.js.map +1 -0
  705. package/dist/core/explain/refusals.js +49 -0
  706. package/dist/core/explain/refusals.js.map +1 -0
  707. package/dist/core/explain/terms/documents.js +227 -0
  708. package/dist/core/explain/terms/documents.js.map +1 -0
  709. package/dist/core/explain/terms/done-check.js +144 -0
  710. package/dist/core/explain/terms/done-check.js.map +1 -0
  711. package/dist/core/explain/terms/entry.js +14 -0
  712. package/dist/core/explain/terms/entry.js.map +1 -0
  713. package/dist/core/explain/terms/stages.js +71 -0
  714. package/dist/core/explain/terms/stages.js.map +1 -0
  715. package/dist/core/explain/terms/tasks.js +97 -0
  716. package/dist/core/explain/terms/tasks.js.map +1 -0
  717. package/dist/core/explain/terms.js +103 -0
  718. package/dist/core/explain/terms.js.map +1 -0
  719. package/dist/core/explore/describe.js +105 -0
  720. package/dist/core/explore/describe.js.map +1 -0
  721. package/dist/core/explore/explore.js +204 -0
  722. package/dist/core/explore/explore.js.map +1 -0
  723. package/dist/core/fleet-context.js +174 -146
  724. package/dist/core/fleet-context.js.map +1 -1
  725. package/dist/core/gate/checks.js +208 -0
  726. package/dist/core/gate/checks.js.map +1 -0
  727. package/dist/core/gate/partners.js +246 -0
  728. package/dist/core/gate/partners.js.map +1 -0
  729. package/dist/core/gate/report.js +47 -0
  730. package/dist/core/gate/report.js.map +1 -0
  731. package/dist/core/gate/verification.js +176 -0
  732. package/dist/core/gate/verification.js.map +1 -0
  733. package/dist/core/gherkin/digest.js +60 -0
  734. package/dist/core/gherkin/digest.js.map +1 -0
  735. package/dist/core/gherkin/emit.js +177 -0
  736. package/dist/core/gherkin/emit.js.map +1 -0
  737. package/dist/core/gherkin/read.js +76 -0
  738. package/dist/core/gherkin/read.js.map +1 -0
  739. package/dist/core/gherkin/stale.js +210 -0
  740. package/dist/core/gherkin/stale.js.map +1 -0
  741. package/dist/core/gherkin/stamp.js +77 -0
  742. package/dist/core/gherkin/stamp.js.map +1 -0
  743. package/dist/core/gherkin/steps/catalogue.js +154 -0
  744. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  745. package/dist/core/gherkin/steps/inventory.js +98 -0
  746. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  747. package/dist/core/gherkin/steps/phrase.js +72 -0
  748. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  749. package/dist/core/glossary/delta.js +109 -0
  750. package/dist/core/glossary/delta.js.map +1 -0
  751. package/dist/core/glossary/tree.js +73 -0
  752. package/dist/core/glossary/tree.js.map +1 -0
  753. package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
  754. package/dist/core/kernel/concurrency.js.map +1 -0
  755. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  756. package/dist/core/kernel/document-bytes.js.map +1 -0
  757. package/dist/core/kernel/fences.js +42 -0
  758. package/dist/core/kernel/fences.js.map +1 -0
  759. package/dist/core/kernel/ids/capability.js +72 -0
  760. package/dist/core/kernel/ids/capability.js.map +1 -0
  761. package/dist/core/kernel/ids/dirs.js +33 -0
  762. package/dist/core/kernel/ids/dirs.js.map +1 -0
  763. package/dist/core/kernel/ids/feature.js +75 -0
  764. package/dist/core/kernel/ids/feature.js.map +1 -0
  765. package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
  766. package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
  767. package/dist/core/kernel/ids/service.js +156 -0
  768. package/dist/core/kernel/ids/service.js.map +1 -0
  769. package/dist/core/kernel/ids/subsystem.js +63 -0
  770. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  771. package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
  772. package/dist/core/kernel/path-safety.js.map +1 -0
  773. package/dist/core/{records.js → kernel/records.js} +11 -0
  774. package/dist/core/kernel/records.js.map +1 -0
  775. package/dist/core/links/backlinks.js +66 -0
  776. package/dist/core/links/backlinks.js.map +1 -0
  777. package/dist/core/links/case.js +74 -0
  778. package/dist/core/links/case.js.map +1 -0
  779. package/dist/core/links/corpus.js +118 -0
  780. package/dist/core/links/corpus.js.map +1 -0
  781. package/dist/core/links/findings.js +110 -0
  782. package/dist/core/links/findings.js.map +1 -0
  783. package/dist/core/links/parse.js +265 -0
  784. package/dist/core/links/parse.js.map +1 -0
  785. package/dist/core/mcp/argv.js +212 -0
  786. package/dist/core/mcp/argv.js.map +1 -0
  787. package/dist/core/mcp/author-tools.js +73 -0
  788. package/dist/core/mcp/author-tools.js.map +1 -0
  789. package/dist/core/mcp/framing.js +46 -0
  790. package/dist/core/mcp/framing.js.map +1 -0
  791. package/dist/core/mcp/protocol.js +280 -0
  792. package/dist/core/mcp/protocol.js.map +1 -0
  793. package/dist/core/mcp/tools.js +324 -0
  794. package/dist/core/mcp/tools.js.map +1 -0
  795. package/dist/core/obligations/obligations.js +106 -0
  796. package/dist/core/obligations/obligations.js.map +1 -0
  797. package/dist/core/openapi/baseline/gate.js +207 -0
  798. package/dist/core/openapi/baseline/gate.js.map +1 -0
  799. package/dist/core/openapi/baseline/plan.js +142 -0
  800. package/dist/core/openapi/baseline/plan.js.map +1 -0
  801. package/dist/core/openapi/baseline/record.js +174 -0
  802. package/dist/core/openapi/baseline/record.js.map +1 -0
  803. package/dist/core/openapi/contract-text.js +33 -0
  804. package/dist/core/openapi/contract-text.js.map +1 -0
  805. package/dist/core/openapi/contract-tree.js +301 -0
  806. package/dist/core/openapi/contract-tree.js.map +1 -0
  807. package/dist/core/openapi/depth.js +136 -0
  808. package/dist/core/openapi/depth.js.map +1 -0
  809. package/dist/core/openapi/digest.js +239 -0
  810. package/dist/core/openapi/digest.js.map +1 -0
  811. package/dist/core/{openapi.js → openapi/doc.js} +54 -108
  812. package/dist/core/openapi/doc.js.map +1 -0
  813. package/dist/core/openapi/merge/components.js +199 -0
  814. package/dist/core/openapi/merge/components.js.map +1 -0
  815. package/dist/core/openapi/merge/error.js +16 -0
  816. package/dist/core/openapi/merge/error.js.map +1 -0
  817. package/dist/core/openapi/merge/markers.js +204 -0
  818. package/dist/core/openapi/merge/markers.js.map +1 -0
  819. package/dist/core/openapi/merge/merge.js +232 -0
  820. package/dist/core/openapi/merge/merge.js.map +1 -0
  821. package/dist/core/openapi/merge/pin.js +110 -0
  822. package/dist/core/openapi/merge/pin.js.map +1 -0
  823. package/dist/core/openspec/decide/capabilities.js +244 -0
  824. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  825. package/dist/core/openspec/decide/dispositions.js +63 -0
  826. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  827. package/dist/core/openspec/decide/renames.js +179 -0
  828. package/dist/core/openspec/decide/renames.js.map +1 -0
  829. package/dist/core/openspec/decide/verdict.js +84 -0
  830. package/dist/core/openspec/decide/verdict.js.map +1 -0
  831. package/dist/core/openspec/inventory.js +220 -0
  832. package/dist/core/openspec/inventory.js.map +1 -0
  833. package/dist/core/openspec/model/mapping.js +78 -0
  834. package/dist/core/openspec/model/mapping.js.map +1 -0
  835. package/dist/core/openspec/model/model.js +70 -0
  836. package/dist/core/openspec/model/model.js.map +1 -0
  837. package/dist/core/openspec/scan/changes.js +241 -0
  838. package/dist/core/openspec/scan/changes.js.map +1 -0
  839. package/dist/core/openspec/scan/config.js +191 -0
  840. package/dist/core/openspec/scan/config.js.map +1 -0
  841. package/dist/core/openspec/scan/shape.js +304 -0
  842. package/dist/core/openspec/scan/shape.js.map +1 -0
  843. package/dist/core/openspec/scan/walk.js +116 -0
  844. package/dist/core/openspec/scan/walk.js.map +1 -0
  845. package/dist/core/openspec/scan/workspace.js +71 -0
  846. package/dist/core/openspec/scan/workspace.js.map +1 -0
  847. package/dist/core/owners/codeowners.js +141 -0
  848. package/dist/core/owners/codeowners.js.map +1 -0
  849. package/dist/core/pack/features.js +120 -0
  850. package/dist/core/pack/features.js.map +1 -0
  851. package/dist/core/pack/joins.js +112 -0
  852. package/dist/core/pack/joins.js.map +1 -0
  853. package/dist/core/pack/living.js +157 -0
  854. package/dist/core/pack/living.js.map +1 -0
  855. package/dist/core/pack/pack.js +120 -0
  856. package/dist/core/pack/pack.js.map +1 -0
  857. package/dist/core/permissions/permissions.js +87 -0
  858. package/dist/core/permissions/permissions.js.map +1 -0
  859. package/dist/core/projection/api.js +84 -0
  860. package/dist/core/projection/api.js.map +1 -0
  861. package/dist/core/projection/arch-slice.js +63 -0
  862. package/dist/core/projection/arch-slice.js.map +1 -0
  863. package/dist/core/projection/events.js +34 -0
  864. package/dist/core/projection/events.js.map +1 -0
  865. package/dist/core/projection/introduced.js +14 -0
  866. package/dist/core/projection/introduced.js.map +1 -0
  867. package/dist/core/provenance/findings.js +244 -0
  868. package/dist/core/provenance/findings.js.map +1 -0
  869. package/dist/core/provenance/git.js +201 -0
  870. package/dist/core/provenance/git.js.map +1 -0
  871. package/dist/core/provenance/gitq/moves.js +139 -0
  872. package/dist/core/provenance/gitq/moves.js.map +1 -0
  873. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  874. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  875. package/dist/core/provenance/sample/scope.js +238 -0
  876. package/dist/core/provenance/sample/scope.js.map +1 -0
  877. package/dist/core/provenance/sample/sections.js +61 -0
  878. package/dist/core/provenance/sample/sections.js.map +1 -0
  879. package/dist/core/provenance/sources.js +280 -0
  880. package/dist/core/provenance/sources.js.map +1 -0
  881. package/dist/core/provenance/stamp.js +220 -0
  882. package/dist/core/provenance/stamp.js.map +1 -0
  883. package/dist/core/provenance/walk.js +157 -0
  884. package/dist/core/provenance/walk.js.map +1 -0
  885. package/dist/core/repo/authored/paths.js +210 -0
  886. package/dist/core/repo/authored/paths.js.map +1 -0
  887. package/dist/core/repo/entries.js +126 -0
  888. package/dist/core/repo/entries.js.map +1 -0
  889. package/dist/core/repo/paths.js +322 -0
  890. package/dist/core/repo/paths.js.map +1 -0
  891. package/dist/core/repo/repo.js +308 -0
  892. package/dist/core/repo/repo.js.map +1 -0
  893. package/dist/core/repo/service-target.js +153 -0
  894. package/dist/core/repo/service-target.js.map +1 -0
  895. package/dist/core/repo/state.js +58 -0
  896. package/dist/core/repo/state.js.map +1 -0
  897. package/dist/core/repo/tree/find.js +61 -0
  898. package/dist/core/repo/tree/find.js.map +1 -0
  899. package/dist/core/repo/tree/fs.js +90 -0
  900. package/dist/core/repo/tree/fs.js.map +1 -0
  901. package/dist/core/repo/tree/marker.js +61 -0
  902. package/dist/core/repo/tree/marker.js.map +1 -0
  903. package/dist/core/repo/tree/render/body.js +258 -0
  904. package/dist/core/repo/tree/render/body.js.map +1 -0
  905. package/dist/core/repo/tree/render/projects.js +182 -0
  906. package/dist/core/repo/tree/render/projects.js.map +1 -0
  907. package/dist/core/repo/tree/render/service/header.js +125 -0
  908. package/dist/core/repo/tree/render/service/header.js.map +1 -0
  909. package/dist/core/repo/tree/render/service/peers.js +28 -0
  910. package/dist/core/repo/tree/render/service/peers.js.map +1 -0
  911. package/dist/core/repo/tree/render/service/view-id.js +67 -0
  912. package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
  913. package/dist/core/repo/tree/render/service/views.js +78 -0
  914. package/dist/core/repo/tree/render/service/views.js.map +1 -0
  915. package/dist/core/repo/tree/render/stale.js +42 -0
  916. package/dist/core/repo/tree/render/stale.js.map +1 -0
  917. package/dist/core/repo/tree/render/text.js +84 -0
  918. package/dist/core/repo/tree/render/text.js.map +1 -0
  919. package/dist/core/repo/tree/render/views.js +293 -0
  920. package/dist/core/repo/tree/render/views.js.map +1 -0
  921. package/dist/core/repo/tree/walk.js +255 -0
  922. package/dist/core/repo/tree/walk.js.map +1 -0
  923. package/dist/core/results.js +146 -14
  924. package/dist/core/results.js.map +1 -1
  925. package/dist/core/scaffold/landscape.js +239 -0
  926. package/dist/core/scaffold/landscape.js.map +1 -0
  927. package/dist/core/scaffold/legacy.js +271 -0
  928. package/dist/core/scaffold/legacy.js.map +1 -0
  929. package/dist/core/scaffold/readme.js +84 -0
  930. package/dist/core/scaffold/readme.js.map +1 -0
  931. package/dist/core/staging/commit.js +252 -0
  932. package/dist/core/staging/commit.js.map +1 -0
  933. package/dist/core/staging/interrupted.js +96 -0
  934. package/dist/core/staging/interrupted.js.map +1 -0
  935. package/dist/core/staging/lock.js +268 -0
  936. package/dist/core/staging/lock.js.map +1 -0
  937. package/dist/core/staging/recovery/finding.js +35 -0
  938. package/dist/core/staging/recovery/finding.js.map +1 -0
  939. package/dist/core/staging/recovery/intent.js +95 -0
  940. package/dist/core/staging/recovery/intent.js.map +1 -0
  941. package/dist/core/staging/recovery/recover.js +204 -0
  942. package/dist/core/staging/recovery/recover.js.map +1 -0
  943. package/dist/core/staging/recovery/residue.js +62 -0
  944. package/dist/core/staging/recovery/residue.js.map +1 -0
  945. package/dist/core/staging/snapshot/manifest.js +188 -0
  946. package/dist/core/staging/snapshot/manifest.js.map +1 -0
  947. package/dist/core/staging/snapshot/snapshot.js +196 -0
  948. package/dist/core/staging/snapshot/snapshot.js.map +1 -0
  949. package/dist/core/staging/txn/forward.js +181 -0
  950. package/dist/core/staging/txn/forward.js.map +1 -0
  951. package/dist/core/staging/txn/journal.js +139 -0
  952. package/dist/core/staging/txn/journal.js.map +1 -0
  953. package/dist/core/staging/txn/transaction.js +75 -0
  954. package/dist/core/staging/txn/transaction.js.map +1 -0
  955. package/dist/core/staging/writes.js +113 -0
  956. package/dist/core/staging/writes.js.map +1 -0
  957. package/dist/core/status/actions/execution.js +60 -0
  958. package/dist/core/status/actions/execution.js.map +1 -0
  959. package/dist/core/status/contracts.js +126 -0
  960. package/dist/core/status/contracts.js.map +1 -0
  961. package/dist/core/status/feature/artifacts.js +196 -0
  962. package/dist/core/status/feature/artifacts.js.map +1 -0
  963. package/dist/core/status/feature/feature.js +214 -0
  964. package/dist/core/status/feature/feature.js.map +1 -0
  965. package/dist/core/status/feature/next.js +163 -0
  966. package/dist/core/status/feature/next.js.map +1 -0
  967. package/dist/core/status/feature/state.js +21 -0
  968. package/dist/core/status/feature/state.js.map +1 -0
  969. package/dist/core/status/feature/words.js +96 -0
  970. package/dist/core/status/feature/words.js.map +1 -0
  971. package/dist/core/status/fleet/fleet.js +216 -0
  972. package/dist/core/status/fleet/fleet.js.map +1 -0
  973. package/dist/core/status/fleet/next.js +302 -0
  974. package/dist/core/status/fleet/next.js.map +1 -0
  975. package/dist/core/status/interrupted.js +97 -0
  976. package/dist/core/status/interrupted.js.map +1 -0
  977. package/dist/core/status/report.js +31 -0
  978. package/dist/core/status/report.js.map +1 -0
  979. package/dist/core/status/scan.js +41 -0
  980. package/dist/core/status/scan.js.map +1 -0
  981. package/dist/core/status/verification.js +216 -0
  982. package/dist/core/status/verification.js.map +1 -0
  983. package/dist/core/tasks/packet.js +199 -0
  984. package/dist/core/tasks/packet.js.map +1 -0
  985. package/dist/core/tasks/record.js +43 -0
  986. package/dist/core/tasks/record.js.map +1 -0
  987. package/dist/core/tasks/sources.js +181 -0
  988. package/dist/core/tasks/sources.js.map +1 -0
  989. package/dist/core/tasks/stamps.js +76 -0
  990. package/dist/core/tasks/stamps.js.map +1 -0
  991. package/dist/core/tasks/unit.js +0 -0
  992. package/dist/core/tasks/unit.js.map +1 -0
  993. package/dist/core/usecases/capability.js +166 -0
  994. package/dist/core/usecases/capability.js.map +1 -0
  995. package/dist/core/usecases/delta/claims.js +140 -0
  996. package/dist/core/usecases/delta/claims.js.map +1 -0
  997. package/dist/core/usecases/delta/flows.js +101 -0
  998. package/dist/core/usecases/delta/flows.js.map +1 -0
  999. package/dist/core/usecases/delta/modified.js +315 -0
  1000. package/dist/core/usecases/delta/modified.js.map +1 -0
  1001. package/dist/core/usecases/delta/overlay.js +76 -0
  1002. package/dist/core/usecases/delta/overlay.js.map +1 -0
  1003. package/dist/core/usecases/fleet.js +296 -0
  1004. package/dist/core/usecases/fleet.js.map +1 -0
  1005. package/dist/core/usecases/grade/capability-tag.js +93 -0
  1006. package/dist/core/usecases/grade/capability-tag.js.map +1 -0
  1007. package/dist/core/usecases/grade/feature.js +88 -0
  1008. package/dist/core/usecases/grade/feature.js.map +1 -0
  1009. package/dist/core/usecases/grade/requirement-tag.js +94 -0
  1010. package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
  1011. package/dist/core/usecases/grade/steps.js +266 -0
  1012. package/dist/core/usecases/grade/steps.js.map +1 -0
  1013. package/dist/core/usecases/grade/usecases.js +112 -0
  1014. package/dist/core/usecases/grade/usecases.js.map +1 -0
  1015. package/dist/core/usecases/operations.js +123 -0
  1016. package/dist/core/usecases/operations.js.map +1 -0
  1017. package/dist/core/usecases/place.js +44 -0
  1018. package/dist/core/usecases/place.js.map +1 -0
  1019. package/dist/core/usecases/service/exclude.js +119 -0
  1020. package/dist/core/usecases/service/exclude.js.map +1 -0
  1021. package/dist/core/usecases/service/flows.js +164 -0
  1022. package/dist/core/usecases/service/flows.js.map +1 -0
  1023. package/dist/core/usecases/suites/participants.js +83 -0
  1024. package/dist/core/usecases/suites/participants.js.map +1 -0
  1025. package/dist/core/usecases/suites/suites.js +45 -0
  1026. package/dist/core/usecases/suites/suites.js.map +1 -0
  1027. package/dist/core/usecases/touch.js +101 -0
  1028. package/dist/core/usecases/touch.js.map +1 -0
  1029. package/dist/core/verify/answers.js +180 -0
  1030. package/dist/core/verify/answers.js.map +1 -0
  1031. package/dist/core/verify/build.js +170 -0
  1032. package/dist/core/verify/build.js.map +1 -0
  1033. package/dist/core/verify/checklist.js +259 -0
  1034. package/dist/core/verify/checklist.js.map +1 -0
  1035. package/dist/core/verify/claims/identity.js +61 -0
  1036. package/dist/core/verify/claims/identity.js.map +1 -0
  1037. package/dist/core/verify/cross/diff.js +97 -0
  1038. package/dist/core/verify/cross/diff.js.map +1 -0
  1039. package/dist/core/verify/evidence/contract.js +169 -0
  1040. package/dist/core/verify/evidence/contract.js.map +1 -0
  1041. package/dist/core/verify/location.js +67 -0
  1042. package/dist/core/verify/location.js.map +1 -0
  1043. package/dist/core/verify/pins/lint.js +158 -0
  1044. package/dist/core/verify/pins/lint.js.map +1 -0
  1045. package/dist/core/verify/pins/pin.js +95 -0
  1046. package/dist/core/verify/pins/pin.js.map +1 -0
  1047. package/dist/core/verify/read/file.js +224 -0
  1048. package/dist/core/verify/read/file.js.map +1 -0
  1049. package/dist/core/verify/read/shape.js +169 -0
  1050. package/dist/core/verify/read/shape.js.map +1 -0
  1051. package/dist/core/verify/read/union.js +105 -0
  1052. package/dist/core/verify/read/union.js.map +1 -0
  1053. package/dist/core/verify/record.js +165 -0
  1054. package/dist/core/verify/record.js.map +1 -0
  1055. package/dist/core/verify/store/commit.js +99 -0
  1056. package/dist/core/verify/store/commit.js.map +1 -0
  1057. package/dist/core/verify/store/render.js +61 -0
  1058. package/dist/core/verify/store/render.js.map +1 -0
  1059. package/dist/core/vocabulary/health.js +91 -0
  1060. package/dist/core/vocabulary/health.js.map +1 -0
  1061. package/dist/core/vocabulary/issue.js +59 -0
  1062. package/dist/core/vocabulary/issue.js.map +1 -0
  1063. package/dist/core/vocabulary/maturity.js +216 -0
  1064. package/dist/core/vocabulary/maturity.js.map +1 -0
  1065. package/dist/core/vocabulary/report.js +90 -0
  1066. package/dist/core/vocabulary/report.js.map +1 -0
  1067. package/dist/core/vocabulary/steps.js +266 -0
  1068. package/dist/core/vocabulary/steps.js.map +1 -0
  1069. package/dist/core/workspace/discover.js +239 -0
  1070. package/dist/core/workspace/discover.js.map +1 -0
  1071. package/dist/core/workspace/render.js +52 -0
  1072. package/dist/core/workspace/render.js.map +1 -0
  1073. package/examples/README.md +232 -0
  1074. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  1075. package/examples/docs/architecture/capabilities.yaml +31 -0
  1076. package/examples/docs/architecture/landscape.likec4 +336 -0
  1077. package/examples/docs/architecture/obligations.yaml +23 -0
  1078. package/examples/docs/architecture/permissions.yaml +50 -0
  1079. package/examples/docs/architecture/services.likec4 +70 -0
  1080. package/examples/docs/architecture/subsystems.likec4 +18 -0
  1081. package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
  1082. package/examples/docs/capabilities/checkout/spec.md +55 -0
  1083. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  1084. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  1085. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  1086. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  1087. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  1088. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  1089. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
  1090. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  1091. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  1092. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  1093. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  1094. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  1095. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
  1096. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  1097. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  1098. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  1099. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  1100. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  1101. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  1102. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  1103. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  1104. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  1105. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  1106. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
  1107. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  1108. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  1109. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  1110. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  1111. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  1112. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  1113. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  1114. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  1115. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  1116. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  1117. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  1118. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  1119. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  1120. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  1121. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  1122. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  1123. package/examples/docs/glossary/order.md +15 -0
  1124. package/examples/docs/glossary/payments/authorization.md +14 -0
  1125. package/examples/docs/likec4.config.json +8 -0
  1126. package/examples/docs/loam.json +3 -0
  1127. package/examples/docs/services/checkout-web/model.likec4 +92 -0
  1128. package/examples/docs/services/checkout-web/spec.md +91 -0
  1129. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  1130. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  1131. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  1132. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  1133. package/examples/docs/services/order-service/arch.spec.md +134 -0
  1134. package/examples/docs/services/order-service/asyncapi.yaml +109 -0
  1135. package/examples/docs/services/order-service/health.yaml +57 -0
  1136. package/examples/docs/services/order-service/model.likec4 +126 -0
  1137. package/examples/docs/services/order-service/openapi.yaml +257 -0
  1138. package/examples/docs/services/order-service/runbook.md +62 -0
  1139. package/examples/docs/services/order-service/spec.md +134 -0
  1140. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  1141. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  1142. package/examples/docs/services/payment-service/arch.spec.md +76 -0
  1143. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  1144. package/examples/docs/services/payment-service/health.yaml +39 -0
  1145. package/examples/docs/services/payment-service/model.likec4 +68 -0
  1146. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  1147. package/examples/docs/services/payment-service/runbook.md +37 -0
  1148. package/examples/docs/services/payment-service/spec.md +88 -0
  1149. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  1150. package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
  1151. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  1152. package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
  1153. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  1154. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  1155. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  1156. package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
  1157. package/examples/docs/services/platform/notification-service/health.yaml +40 -0
  1158. package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
  1159. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  1160. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  1161. package/examples/docs/services/platform/subsystem.yaml +2 -0
  1162. package/examples/fleet.yaml +57 -0
  1163. package/package.json +19 -6
  1164. package/dist/commands/adopt.js +0 -240
  1165. package/dist/commands/adopt.js.map +0 -1
  1166. package/dist/commands/archive.js +0 -1313
  1167. package/dist/commands/archive.js.map +0 -1
  1168. package/dist/commands/delta.js +0 -388
  1169. package/dist/commands/delta.js.map +0 -1
  1170. package/dist/commands/docs-repo-gate.js.map +0 -1
  1171. package/dist/commands/format.js +0 -17
  1172. package/dist/commands/format.js.map +0 -1
  1173. package/dist/commands/gherkin.js +0 -309
  1174. package/dist/commands/gherkin.js.map +0 -1
  1175. package/dist/commands/init.js.map +0 -1
  1176. package/dist/commands/list.js +0 -295
  1177. package/dist/commands/list.js.map +0 -1
  1178. package/dist/commands/migrate-openspec.js +0 -950
  1179. package/dist/commands/migrate-openspec.js.map +0 -1
  1180. package/dist/commands/new.js +0 -413
  1181. package/dist/commands/new.js.map +0 -1
  1182. package/dist/commands/rebase.js +0 -356
  1183. package/dist/commands/rebase.js.map +0 -1
  1184. package/dist/commands/show.js +0 -320
  1185. package/dist/commands/show.js.map +0 -1
  1186. package/dist/commands/status.js +0 -262
  1187. package/dist/commands/status.js.map +0 -1
  1188. package/dist/commands/unarchive.js +0 -317
  1189. package/dist/commands/unarchive.js.map +0 -1
  1190. package/dist/commands/validate.js +0 -1773
  1191. package/dist/commands/validate.js.map +0 -1
  1192. package/dist/commands/verify.js +0 -775
  1193. package/dist/commands/verify.js.map +0 -1
  1194. package/dist/commands/vouch.js +0 -421
  1195. package/dist/commands/vouch.js.map +0 -1
  1196. package/dist/core/agent.js +0 -2173
  1197. package/dist/core/agent.js.map +0 -1
  1198. package/dist/core/agents-stamp.js.map +0 -1
  1199. package/dist/core/arch.js +0 -130
  1200. package/dist/core/arch.js.map +0 -1
  1201. package/dist/core/asyncapi.js +0 -253
  1202. package/dist/core/asyncapi.js.map +0 -1
  1203. package/dist/core/brief.js +0 -755
  1204. package/dist/core/brief.js.map +0 -1
  1205. package/dist/core/coherence.js +0 -577
  1206. package/dist/core/coherence.js.map +0 -1
  1207. package/dist/core/concurrency.js.map +0 -1
  1208. package/dist/core/config.js.map +0 -1
  1209. package/dist/core/delta.js +0 -476
  1210. package/dist/core/delta.js.map +0 -1
  1211. package/dist/core/dependencies.js +0 -356
  1212. package/dist/core/dependencies.js.map +0 -1
  1213. package/dist/core/doctor.js +0 -596
  1214. package/dist/core/doctor.js.map +0 -1
  1215. package/dist/core/document-bytes.js.map +0 -1
  1216. package/dist/core/explore.js +0 -225
  1217. package/dist/core/explore.js.map +0 -1
  1218. package/dist/core/frontmatter.js.map +0 -1
  1219. package/dist/core/gherkin.js +0 -463
  1220. package/dist/core/gherkin.js.map +0 -1
  1221. package/dist/core/health.js +0 -67
  1222. package/dist/core/health.js.map +0 -1
  1223. package/dist/core/ids.js +0 -122
  1224. package/dist/core/ids.js.map +0 -1
  1225. package/dist/core/issue.js +0 -9
  1226. package/dist/core/issue.js.map +0 -1
  1227. package/dist/core/json.js +0 -74
  1228. package/dist/core/json.js.map +0 -1
  1229. package/dist/core/likec4.js +0 -489
  1230. package/dist/core/likec4.js.map +0 -1
  1231. package/dist/core/maturity.js +0 -66
  1232. package/dist/core/maturity.js.map +0 -1
  1233. package/dist/core/openapi-merge.js +0 -552
  1234. package/dist/core/openapi-merge.js.map +0 -1
  1235. package/dist/core/openapi.js.map +0 -1
  1236. package/dist/core/openspec-inventory.js +0 -1440
  1237. package/dist/core/openspec-inventory.js.map +0 -1
  1238. package/dist/core/path-safety.js.map +0 -1
  1239. package/dist/core/provenance.js +0 -787
  1240. package/dist/core/provenance.js.map +0 -1
  1241. package/dist/core/records.js.map +0 -1
  1242. package/dist/core/repo.js +0 -438
  1243. package/dist/core/repo.js.map +0 -1
  1244. package/dist/core/report.js +0 -47
  1245. package/dist/core/report.js.map +0 -1
  1246. package/dist/core/spec.js +0 -505
  1247. package/dist/core/spec.js.map +0 -1
  1248. package/dist/core/staging.js +0 -890
  1249. package/dist/core/staging.js.map +0 -1
  1250. package/dist/core/status.js +0 -1132
  1251. package/dist/core/status.js.map +0 -1
  1252. package/dist/core/steps.js +0 -72
  1253. package/dist/core/steps.js.map +0 -1
  1254. package/dist/core/verify.js +0 -807
  1255. package/dist/core/verify.js.map +0 -1
  1256. package/dist/core/version.js.map +0 -1
@@ -1,890 +0,0 @@
1
- /**
2
- * The commit machinery `archive` and `unarchive` share: stage every new file
3
- * version beside its target, swap the staged versions in, roll back what
4
- * already went in when a later step fails — plus the undo snapshot `archive`
5
- * writes and `unarchive` honours. Moved here verbatim from archive.ts once
6
- * unarchive became its second consumer; the MERGE computations stay with
7
- * archive, which is still their only caller.
8
- */
9
- import { isUtf8 } from "node:buffer";
10
- import { createHash } from "node:crypto";
11
- import { existsSync } from "node:fs";
12
- import { link, mkdir, open, readdir, readFile, rename, rm, rmdir, unlink, writeFile } from "node:fs/promises";
13
- import { hostname } from "node:os";
14
- import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
15
- import { repoPath } from "./json.js";
16
- import { resolvePortableFileInsideLexically, UnsafePathError } from "./path-safety.js";
17
- // Every `isRecord` below guards a record loam itself wrote and is reading back
18
- // — the lock, the snapshot manifest — whose fields are asked for on the very
19
- // next line, inside a REFUSAL path. `JSON.parse` answers with any JSON value,
20
- // not with an object, and that is where a thrown `TypeError` costs the most: it
21
- // does not make the command fail safely, it replaces a designed refusal with
22
- // `internal`.
23
- import { isRecord } from "./records.js";
24
- /** The one place a planned write becomes bytes. */
25
- function toBytes(content) {
26
- return typeof content === "string" ? Buffer.from(content, "utf8") : content;
27
- }
28
- /**
29
- * The one place that decides whether a planned write is a CREATE.
30
- *
31
- * `exclusive` is a no-clobber create (link(2)), so it can only be asked of a
32
- * path that does not exist yet: asking it of an overwrite would fail EEXIST on
33
- * every single run. Deciding here — rather than at each of the dozen
34
- * `writes.push` sites in archive and unarchive — is what keeps the two commands
35
- * from disagreeing about which of their writes may safely lose a race. An
36
- * OVERWRITE is not left unguarded: `swapStaged` compares the target against the
37
- * pre-image immediately before the rename, so a file another writer changed
38
- * under us stops the commit instead of silently burying their bytes.
39
- */
40
- export function planWrite(path, content) {
41
- if (content !== null && !existsSync(path))
42
- return { path, content, exclusive: true };
43
- return { path, content };
44
- }
45
- /* ------------------------------------------------------------------ */
46
- /* Bytes in, text only where a parser needs it */
47
- /* ------------------------------------------------------------------ */
48
- /**
49
- * A file loam must PARSE that does not decode as the UTF-8 text loam owns.
50
- *
51
- * Commands map this to `merge-failed`: nothing was written, the file is named,
52
- * and re-saving it as UTF-8 makes the command work. The read-only migration
53
- * ingest already refuses non-UTF-8 input outright (openspec-inventory.ts) —
54
- * the destructive path has strictly more to lose, so it refuses the same way
55
- * rather than substituting U+FFFD and rewriting the file over the author.
56
- *
57
- * `reason` says what the bytes actually ARE, because the two ways a document
58
- * fails this test destroy different things: one substitutes bytes, the other
59
- * erases the whole document's meaning. A reader told the wrong one goes looking
60
- * in the wrong place. The advice that follows is the same either way, so it is
61
- * spelled once, here.
62
- */
63
- export class NotUtf8Error extends Error {
64
- path;
65
- name = "NotUtf8Error";
66
- constructor(path, reason) {
67
- super(`${path} ${reason} Nothing was written. Re-save it as UTF-8, then re-run.`);
68
- this.path = path;
69
- }
70
- }
71
- /**
72
- * Decode bytes a parser is about to be handed, or refuse naming the file.
73
- *
74
- * Two tests, the same two the read path makes (document-bytes.ts's
75
- * `decodeDocument`), because this side has strictly more to lose by missing
76
- * either. `isUtf8` catches the byte sequences that cannot be UTF-8 at all —
77
- * which is what a byte-order mark makes UTF-16 into. Without a BOM, UTF-16LE of
78
- * ASCII is a sequence of perfectly VALID UTF-8 bytes: every other byte is NUL,
79
- * so `isUtf8` says yes, the file decodes with a U+0000 between every character,
80
- * and every parser loam owns reads its requirements, frontmatter and headings
81
- * as absent rather than as unreadable. On the read path that is a document
82
- * graded green while nothing in it was checked; here it is worse, because
83
- * `archive` merges against that empty baseline and writes the result back — the
84
- * author's requirements are not mis-read, they are gone, and the undo snapshot
85
- * records the same emptiness as the pre-image.
86
- */
87
- function decodeUtf8(bytes, path) {
88
- if (!isUtf8(bytes)) {
89
- throw new NotUtf8Error(path, `is not valid UTF-8 — loam parses this file as text and writes it back, which would replace every ` +
90
- `undecodable byte with U+FFFD, in the living document AND in the undo snapshot.`);
91
- }
92
- const text = bytes.toString("utf8");
93
- if (text.includes("\u0000")) {
94
- throw new NotUtf8Error(path, `holds NUL characters, which no document loam owns does — almost always UTF-16 saved without a byte-order ` +
95
- `mark. Its bytes are valid UTF-8, so it decodes without complaint into text whose requirements, ` +
96
- `frontmatter and headings all parse as ABSENT: the merge would compute over an empty baseline and write ` +
97
- `that back, taking every requirement in the file with it.`);
98
- }
99
- return text;
100
- }
101
- /** Read a file loam is going to parse. The only supported way to turn a docs file into a string. */
102
- export async function readUtf8(path) {
103
- return decodeUtf8(await readFile(path), path);
104
- }
105
- /** Same bytes? Absence is its own value: a file that is gone is not a file that is empty. */
106
- function sameBytes(a, b) {
107
- return a === null || b === null ? a === b : a.equals(b);
108
- }
109
- /* ------------------------------------------------------------------ */
110
- /* Reading loam's own records back off the disk */
111
- /* ------------------------------------------------------------------ */
112
- /** The one spelling of a sha256 loam wrote, for reading one back out of a record. */
113
- function isDigest(value) {
114
- return typeof value === "string" && /^[0-9a-f]{64}$/.test(value);
115
- }
116
- /* ------------------------------------------------------------------ */
117
- /* The docs-repo advisory lock */
118
- /* ------------------------------------------------------------------ */
119
- /** The lock file, in the docs repo root — one writer at a time across the whole fleet. */
120
- export const DOCS_LOCK = ".loam-lock";
121
- /** Another writer holds the docs repo. Commands map this to the `docs-busy` envelope code. */
122
- export class DocsBusyError extends Error {
123
- lockPath;
124
- name = "DocsBusyError";
125
- constructor(lockPath, holder) {
126
- super(`another loam command is writing this docs repo (${holder}) — nothing was read or written. ` +
127
- `Wait for it to finish, or remove ${lockPath} if no such command is running.`);
128
- this.lockPath = lockPath;
129
- }
130
- }
131
- /**
132
- * The target changed between the pre-image staging read and the swap.
133
- *
134
- * The pre-image is what a rollback restores and what `unarchive` is handed, so
135
- * swapping over somebody else's newer bytes would both lose their work and
136
- * arm a rollback that writes a third version nobody wrote. Commands map this to
137
- * `merge-failed`: nothing of theirs went in, the docs are as the other writer
138
- * left them, and re-running can work.
139
- */
140
- export class StagingRaceError extends Error {
141
- path;
142
- name = "StagingRaceError";
143
- constructor(path) {
144
- super(`${path} changed while this command was planning its merge — nothing was written; re-run`);
145
- this.path = path;
146
- }
147
- }
148
- /**
149
- * Take the docs repo's advisory lock for the whole plan+commit window, and
150
- * return the release.
151
- *
152
- * Advisory, and deliberately coarse: the destructive commands write the SAME
153
- * three shared files (a service spec, a service contract, the one landscape),
154
- * so two of them overlapping is not a merge to be resolved but a merge one of
155
- * them computed against a snapshot that no longer exists. Two archives used to
156
- * plan against the same landscape bytes and the second's splice silently
157
- * dropped the first's additions — exit 0 on both, and a `validate` that stayed
158
- * green because the surviving document was perfectly coherent.
159
- *
160
- * O_EXCL create is the primitive: it is atomic on every filesystem loam runs
161
- * on, needs no daemon, and leaves a file a human can read and delete. A holder
162
- * that died without releasing would otherwise wedge the repo forever, so a lock
163
- * naming a pid on THIS host that no longer exists is broken once and retried —
164
- * two racers could both break the same stale lock, which is why the pre-image
165
- * check in `swapStaged` remains the second line of defence rather than an
166
- * optimisation.
167
- */
168
- export async function acquireDocsLock(docsDir) {
169
- const path = join(docsDir, DOCS_LOCK);
170
- const payload = `${JSON.stringify({ pid: process.pid, host: hostname(), at: new Date().toISOString() })}\n`;
171
- for (let attempt = 0;; attempt += 1) {
172
- try {
173
- await writeFile(path, payload, { flag: "wx" });
174
- }
175
- catch (err) {
176
- if (err.code !== "EEXIST")
177
- throw err;
178
- if (attempt === 0 && (await breakStaleLock(path)))
179
- continue;
180
- throw new DocsBusyError(path, await describeLock(path));
181
- }
182
- let released = false;
183
- return async () => {
184
- if (released)
185
- return;
186
- released = true;
187
- await quietRm(path);
188
- };
189
- }
190
- }
191
- /** Remove a lock whose holder is a dead process on this same host. Returns whether it did. */
192
- async function breakStaleLock(path) {
193
- let holder;
194
- try {
195
- holder = JSON.parse(await readFile(path, "utf8"));
196
- }
197
- catch {
198
- // Unreadable or not ours to interpret — treat it as held. A lock file we
199
- // cannot understand is the one case where guessing is worst.
200
- return false;
201
- }
202
- // A lock file holding `null` (or a bare string, or an array) is JSON this
203
- // parses and nothing else understands. Treat it as held, exactly as an
204
- // unparseable one is: the dereference below used to run outside the try and
205
- // threw out of `acquireDocsLock`, replacing the `docs-busy` refusal — the
206
- // designed answer — with an `internal` envelope.
207
- if (!isRecord(holder))
208
- return false;
209
- if (holder.host !== hostname() || typeof holder.pid !== "number")
210
- return false;
211
- try {
212
- // Signal 0 asks "does this pid exist" without delivering anything. EPERM
213
- // means it exists and belongs to somebody else — alive either way.
214
- process.kill(holder.pid, 0);
215
- return false;
216
- }
217
- catch (err) {
218
- if (err.code !== "ESRCH")
219
- return false;
220
- }
221
- try {
222
- await unlink(path);
223
- return true;
224
- }
225
- catch {
226
- return false;
227
- }
228
- }
229
- async function describeLock(path) {
230
- try {
231
- const raw = JSON.parse(await readFile(path, "utf8"));
232
- return `pid ${String(raw.pid)} on ${String(raw.host)} since ${String(raw.at)}`;
233
- }
234
- catch {
235
- return `see ${path}`;
236
- }
237
- }
238
- /**
239
- * Write every new version to a temp file beside its target, remembering what the
240
- * target said first. Nothing observable changes here: on failure the temp files
241
- * are removed and the docs are exactly as they were.
242
- *
243
- * The pre-image is read eagerly and deliberately: it is what a rollback restores
244
- * and what `unarchive` is given, so a file we cannot read is a file we cannot
245
- * safely rewrite, and the merge must stop before it starts.
246
- */
247
- export async function stageWrites(writes) {
248
- const staged = [];
249
- try {
250
- for (const [i, write] of writes.entries()) {
251
- // mkdir(recursive) reports the topmost directory it had to create — the
252
- // handle a rollback needs to put the tree back the way it found it.
253
- const createdDir = (await mkdir(dirname(write.path), { recursive: true })) ?? null;
254
- const before = existsSync(write.path) ? await readFile(write.path) : null;
255
- const content = toBytes(write.content);
256
- let tmp = null;
257
- if (content !== null) {
258
- tmp = tempPath(write.path, i);
259
- await writeFile(tmp, content);
260
- }
261
- staged.push({ write, content, tmp, before, createdDir, swapped: false });
262
- }
263
- }
264
- catch (err) {
265
- await discardStaged(staged);
266
- throw err;
267
- }
268
- return staged;
269
- }
270
- /**
271
- * Swap the staged versions in, one file at a time. Each swap is a rename(2)
272
- * within a single directory, so a concurrent reader sees either the old bytes or
273
- * the new ones — never a half-written file. Across files it is not atomic: the
274
- * caller rolls back what has already gone in.
275
- *
276
- * Every swap re-reads its target first and compares it with the pre-image the
277
- * plan was computed from — a compare-and-set on the file's whole content. It is
278
- * half a CAS on purpose: read and rename cannot be one syscall, so a writer
279
- * landing inside that window still wins. What it does buy is the window that
280
- * actually matters — the seconds a plan spends parsing LikeC4 and merging YAML
281
- * between the pre-image read and this swap — and it costs one read per file.
282
- */
283
- export async function swapStaged(staged) {
284
- for (const s of staged) {
285
- const now = existsSync(s.write.path) ? await readFile(s.write.path) : null;
286
- if (!sameBytes(now, s.before))
287
- throw new StagingRaceError(s.write.path);
288
- if (s.tmp === null) {
289
- if (s.before !== null)
290
- await unlink(s.write.path);
291
- }
292
- else if (s.write.exclusive === true) {
293
- // link(2) is the same-filesystem, atomic no-clobber counterpart to rename:
294
- // it fails with EEXIST instead of replacing a file created after planning.
295
- await link(s.tmp, s.write.path);
296
- s.swapped = true;
297
- await unlink(s.tmp);
298
- s.tmp = null;
299
- continue;
300
- }
301
- else {
302
- await rename(s.tmp, s.write.path);
303
- }
304
- s.swapped = true;
305
- }
306
- }
307
- /**
308
- * Put back every file that was already swapped, newest first, from the bytes read
309
- * before the swap. Returns the paths it could NOT restore — the caller must say so
310
- * out loud rather than report a clean failure over a half-merged repo.
311
- *
312
- * A rollback only ever un-does ITS OWN write: if the file no longer holds the
313
- * bytes this run put there, somebody else has written it since, and restoring
314
- * the pre-image would destroy their work while reporting a clean failure. That
315
- * file is left exactly as found and named in the failures, which is what turns
316
- * the caller's answer from `merge-failed` ("trust the repo") into
317
- * `rollback-incomplete` ("look at it by hand") — the honest answer, because the
318
- * repo now holds one run's writes half-reverted next to another's.
319
- */
320
- export async function rollbackStaged(staged) {
321
- const failures = [];
322
- for (const s of [...staged].reverse()) {
323
- if (!s.swapped)
324
- continue;
325
- try {
326
- const now = existsSync(s.write.path) ? await readFile(s.write.path) : null;
327
- if (!sameBytes(now, s.content)) {
328
- failures.push(`${s.write.path} (changed by another writer after this run wrote it — left as found)`);
329
- continue;
330
- }
331
- if (s.before === null)
332
- await rm(s.write.path, { force: true });
333
- else
334
- await atomicWrite(s.write.path, s.before);
335
- s.swapped = false;
336
- }
337
- catch (err) {
338
- failures.push(`${s.write.path} (${message(err)})`);
339
- }
340
- }
341
- await discardStaged(staged);
342
- return failures;
343
- }
344
- /** Write `content` to `path` through a temp file in the same directory. */
345
- async function atomicWrite(path, content) {
346
- const tmp = tempPath(path, 0);
347
- await writeFile(tmp, content);
348
- await rename(tmp, path);
349
- }
350
- /** A hidden sibling of `path`: same directory, so the rename never crosses a filesystem. */
351
- function tempPath(path, n) {
352
- return join(dirname(path), `.${basename(path)}.loam-${process.pid}-${n}-${Date.now()}.tmp`);
353
- }
354
- /** The shape `tempPath` writes — what a scan for leftovers of a killed run matches on. */
355
- const TEMP_FILE_RE = /^\..*\.loam-\d+-\d+-\d+\.tmp$/;
356
- /**
357
- * Everything staging left on disk: the temp files, and the directories it made
358
- * for them.
359
- *
360
- * Directories go by rmdir, never by recursive remove, and the walk stops the
361
- * moment one is not empty. The recursive form used to be reached for because
362
- * "we created this directory, so it is ours" — but a directory created at plan
363
- * time is shared by the time the rollback runs: a second archive can have put a
364
- * whole feature inside `features/archive/` in between, and `rm -r` on our own
365
- * created root took their work with it, silently, on OUR failure path.
366
- */
367
- async function discardStaged(staged) {
368
- for (const s of staged)
369
- if (s.tmp !== null)
370
- await quietRm(s.tmp);
371
- const roots = staged.filter((s) => s.createdDir !== null).map((s) => resolve(s.createdDir));
372
- for (const s of [...staged].reverse()) {
373
- const root = roots.find((candidate) => contains(candidate, s.write.path));
374
- if (root !== undefined)
375
- await quietPruneEmptyParents(dirname(s.write.path), root);
376
- }
377
- }
378
- function contains(parent, candidate) {
379
- const rel = relative(parent, resolve(candidate));
380
- return rel === "" || (!rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel));
381
- }
382
- /**
383
- * Undo the directories a write had to create, from `start` up to and including
384
- * `boundary`. Remove only directories that are still EMPTY: anything else in
385
- * there arrived after we made it, and belongs to whoever put it there.
386
- */
387
- export async function quietPruneEmptyParents(start, boundary) {
388
- let cursor = resolve(start);
389
- const root = resolve(boundary);
390
- while (contains(root, cursor)) {
391
- try {
392
- await rmdir(cursor);
393
- }
394
- catch {
395
- return;
396
- }
397
- if (cursor === root)
398
- return;
399
- const parent = dirname(cursor);
400
- if (parent === cursor)
401
- return;
402
- cursor = parent;
403
- }
404
- }
405
- export async function quietRm(path) {
406
- try {
407
- await rm(path, { recursive: true, force: true });
408
- }
409
- catch {
410
- // Best effort — a leftover temp file is noise, not corruption.
411
- }
412
- }
413
- /** Say what the failure cost: nothing, or a repo that needs looking at by hand. */
414
- export function rollbackError(err, failures) {
415
- if (failures.length === 0) {
416
- return new Error(`${message(err)} — the living docs were rolled back, nothing was merged`);
417
- }
418
- return new Error(`${message(err)} — ROLLBACK INCOMPLETE, these files may be half-merged and need checking by hand: ${failures.join(", ")}`);
419
- }
420
- export function message(err) {
421
- return err instanceof Error ? err.message : String(err);
422
- }
423
- /* ------------------------------------------------------------------ */
424
- /* The undo snapshot */
425
- /* ------------------------------------------------------------------ */
426
- /**
427
- * Where archive parks the bytes it is about to overwrite, inside the feature
428
- * directory so it travels with it into `features/archive/`.
429
- *
430
- * It exists because the merge is not invertible: a MODIFIED requirement's
431
- * previous text appears nowhere in the delta, and a landscape rewritten by hand
432
- * since cannot be un-rewritten by re-reading the delta either. `unarchive` puts
433
- * bytes back; it does not recompute them.
434
- */
435
- export const SNAPSHOT_DIR = ".loam-before";
436
- export const SNAPSHOT_MANIFEST = "manifest.json";
437
- /**
438
- * Bumped only when the layout changes in a way `unarchive` must refuse to guess
439
- * at. 2 added `before` — a version-1 snapshot records nothing about the bytes it
440
- * would RESTORE, so nothing can tell an intact pre-image from an edited one, and
441
- * "I put your docs back" over a silently altered pre-image is the one sentence
442
- * this command must never be able to say by accident.
443
- */
444
- export const SNAPSHOT_VERSION = 2;
445
- /** A snapshot directory that must not be replaced, because it is the only copy of the true pre-images. */
446
- export class SnapshotClobberError extends Error {
447
- dir;
448
- name = "SnapshotClobberError";
449
- constructor(dir, detail) {
450
- super(`${dir} already holds an undo snapshot that does NOT match the living docs (${detail}) — a previous archive of ` +
451
- `this feature wrote to the living docs and never took them back, and these are the only copies of what they ` +
452
- `said before. Overwriting them would make that merge permanent and unreportable. Run \`loam archive\` again ` +
453
- `after restoring the living docs from version control, or delete ${SNAPSHOT_DIR}/ if you know the merge never landed.`);
454
- this.dir = dir;
455
- }
456
- }
457
- export function snapshotDir(featureDir) {
458
- return join(featureDir, SNAPSHOT_DIR);
459
- }
460
- export function sha256(content) {
461
- return typeof content === "string"
462
- ? createHash("sha256").update(content, "utf8").digest("hex")
463
- : createHash("sha256").update(content).digest("hex");
464
- }
465
- export async function writeSnapshot(featureDir, docsDir, featureId, dirName, staged) {
466
- const dir = snapshotDir(featureDir);
467
- await assertSnapshotReplaceable(dir, docsDir);
468
- // A leftover from a rolled-back run would describe a merge that never happened.
469
- await quietRm(dir);
470
- const files = [];
471
- for (const s of staged) {
472
- const rel = repoPath(docsDir, s.write.path);
473
- files.push({
474
- path: rel,
475
- existed: s.before !== null,
476
- after: sha256(s.content ?? Buffer.alloc(0)),
477
- before: s.before === null ? null : sha256(s.before),
478
- });
479
- if (s.before !== null) {
480
- const dest = join(dir, "files", rel);
481
- await mkdir(dirname(dest), { recursive: true });
482
- await writeFile(dest, s.before);
483
- }
484
- }
485
- const manifest = {
486
- version: SNAPSHOT_VERSION,
487
- feature: featureId,
488
- dirName,
489
- archivedAt: new Date().toISOString(),
490
- files,
491
- };
492
- // Manifest last: its presence is what says the pre-images beside it are complete.
493
- await mkdir(dir, { recursive: true });
494
- await writeFile(join(dir, SNAPSHOT_MANIFEST), JSON.stringify(manifest, null, 2) + "\n", "utf8");
495
- }
496
- /**
497
- * Refuse to replace a snapshot whose pre-images are still the only record of
498
- * what the living docs said.
499
- *
500
- * A snapshot in an ACTIVE feature directory means a previous archive of this
501
- * same feature wrote it — and since a clean rollback deletes it, finding one
502
- * means that run either died mid-commit or reported `rollback-incomplete`. If
503
- * its pre-images still match the living docs, nothing of that run landed and
504
- * the snapshot is stale bookkeeping. If they do not, the living docs carry
505
- * that run's writes, these files are the only way back, and the unconditional
506
- * clear turned a repairable half-merge into a permanent one — after which
507
- * `unarchive` restored the half-merged text and said the docs were back.
508
- */
509
- async function assertSnapshotReplaceable(dir, docsDir) {
510
- const manifestPath = join(dir, SNAPSHOT_MANIFEST);
511
- // The manifest is written LAST, so a `files/` tree without one is a snapshot
512
- // whose run died before it could swap anything: it describes no merge.
513
- if (!existsSync(manifestPath))
514
- return;
515
- let manifest;
516
- try {
517
- manifest = JSON.parse(await readFile(manifestPath, "utf8"));
518
- }
519
- catch {
520
- throw new SnapshotClobberError(dir, `${SNAPSHOT_MANIFEST} cannot be read, so nothing can say whether it is stale`);
521
- }
522
- // The cast that used to stand here asserted the shape rather than checking
523
- // it: well-formed JSON that is not an object answered `undefined` to every
524
- // field below and slipped through as "a different loam", and a bare `null`
525
- // threw a TypeError out of the refusal itself. Both left this directory —
526
- // which may hold the only copies of what the living docs said — one step from
527
- // being replaced, without the staleness question ever having been asked.
528
- if (!isRecord(manifest)) {
529
- throw new SnapshotClobberError(dir, `${SNAPSHOT_MANIFEST} cannot be read, so nothing can say whether it is stale`);
530
- }
531
- if (manifest.version !== SNAPSHOT_VERSION || !Array.isArray(manifest.files)) {
532
- throw new SnapshotClobberError(dir, `it was written by a different loam and cannot be checked against the living docs`);
533
- }
534
- // `Array.isArray` narrows to `any[]`; naming the element type here is what
535
- // keeps that `any` from spreading past the one row being read.
536
- const rows = manifest.files;
537
- const landed = [];
538
- for (const row of rows) {
539
- const entry = readSnapshotClaim(row);
540
- if (entry === null) {
541
- throw new SnapshotClobberError(dir, `${SNAPSHOT_MANIFEST} is malformed, so nothing can say whether it is stale`);
542
- }
543
- let target;
544
- try {
545
- // These paths are data, and they are the ones this function goes and
546
- // reads. They name living documents, so containment is lexical: a docs
547
- // repo may legitimately mount a service directory through a symlink, and
548
- // `unarchive` resolves the same field the same way before it writes back.
549
- target = resolvePortableFileInsideLexically(docsDir, entry.path, `snapshot path '${entry.path}'`);
550
- }
551
- catch (err) {
552
- if (!(err instanceof UnsafePathError))
553
- throw err;
554
- throw new SnapshotClobberError(dir, `${message(err)}, so nothing can say whether it is stale`);
555
- }
556
- const now = existsSync(target) ? sha256(await readFile(target)) : null;
557
- // `existed: false` means archive created the file, so "nothing landed"
558
- // means it is still absent.
559
- const untouched = entry.existed ? now === entry.before : now === null;
560
- if (!untouched)
561
- landed.push(entry.path);
562
- }
563
- if (landed.length > 0)
564
- throw new SnapshotClobberError(dir, `${landed.length} file(s) already carry that merge: ${landed.join(", ")}`);
565
- }
566
- /**
567
- * One manifest row read back as the record `writeSnapshot` wrote, or null when
568
- * the file does not actually say.
569
- *
570
- * Only the three fields the staleness question consumes are checked, and every
571
- * one of them is checked, because an unchecked field does not read as missing
572
- * here — it reads as an ANSWER. An `existed` that is not a boolean is falsy, and
573
- * a `false` claim is graded by asking whether the file is ABSENT: a manifest
574
- * recording a pre-image for a file that has since been deleted therefore graded
575
- * as stale bookkeeping and was cleared, taking the only copy of that pre-image
576
- * with it. A `before` of the wrong type equals no digest at all, so the opposite
577
- * row accuses an untouched file of carrying a merge. Both are confident answers
578
- * to a question the manifest could not answer.
579
- *
580
- * `unarchive` asks a stricter version of the same question of the same file
581
- * (`after`, `archivedAt`, the feature name, no duplicates) because it is about
582
- * to write THROUGH it; that check stays where it is, with its own refusals.
583
- */
584
- function readSnapshotClaim(value) {
585
- if (!isRecord(value))
586
- return null;
587
- const { path, existed, before } = value;
588
- if (typeof path !== "string" || typeof existed !== "boolean")
589
- return null;
590
- if (existed)
591
- return isDigest(before) ? { path, existed, before } : null;
592
- return before === null ? { path, existed, before } : null;
593
- }
594
- /* ------------------------------------------------------------------ */
595
- /* The commit intent record */
596
- /* ------------------------------------------------------------------ */
597
- /**
598
- * The journal that makes an interrupted commit detectable.
599
- *
600
- * `swapStaged` is N renames, and only each ONE of them is atomic. A kill
601
- * between two of them leaves the living docs half-merged — and nothing could
602
- * see it: `doctor` and `status` called the repo healthy, `validate --all`
603
- * blamed the delta, and the next archive cleared the one snapshot that could
604
- * have repaired it. So the swap loop now runs inside a record written and
605
- * fsynced BEFORE the first rename and removed after the last step of the
606
- * commit: its mere presence says a commit was in flight, and its per-path
607
- * digests say, file by file, whether that file's rename landed.
608
- *
609
- * It is deliberately NOT a source of truth and never disagrees with the files:
610
- * every judgement it supports is made by re-reading the living bytes and
611
- * comparing digests, and every byte a repair writes comes from the snapshot
612
- * and is verified against the digest recorded before the crash. Outside the
613
- * commit window it does not exist.
614
- */
615
- export const COMMIT_INTENT = ".loam-commit";
616
- const COMMIT_INTENT_VERSION = 1;
617
- /** An interrupted commit this loam must not silently write over. */
618
- export class InterruptedCommitError extends Error {
619
- name = "InterruptedCommitError";
620
- }
621
- /**
622
- * Write the intent record and get it onto the disk before the first swap.
623
- *
624
- * fsync, not just write: the point of the record is to survive the crash that
625
- * interrupts the commit, and a record still sitting in the page cache when the
626
- * machine dies describes nothing. The directory entry is fsynced too where the
627
- * platform allows opening a directory — without that the file's bytes can be
628
- * durable while its name is not.
629
- */
630
- export async function writeCommitIntent(docsDir, spec, staged) {
631
- const intent = {
632
- version: COMMIT_INTENT_VERSION,
633
- command: spec.command,
634
- restore: spec.restore,
635
- pid: process.pid,
636
- host: hostname(),
637
- at: new Date().toISOString(),
638
- feature: spec.feature,
639
- moveFrom: repoPath(docsDir, spec.moveFrom),
640
- moveTo: repoPath(docsDir, spec.moveTo),
641
- files: staged.map((s) => ({
642
- path: repoPath(docsDir, s.write.path),
643
- before: s.before === null ? null : sha256(s.before),
644
- after: s.content === null ? null : sha256(s.content),
645
- })),
646
- };
647
- const path = join(docsDir, COMMIT_INTENT);
648
- const handle = await open(path, "w");
649
- try {
650
- await handle.writeFile(JSON.stringify(intent, null, 2) + "\n", "utf8");
651
- await handle.sync();
652
- }
653
- finally {
654
- await handle.close();
655
- }
656
- try {
657
- const dir = await open(docsDir, "r");
658
- try {
659
- await dir.sync();
660
- }
661
- finally {
662
- await dir.close();
663
- }
664
- }
665
- catch {
666
- // Not every platform lets a directory be opened; the record's own bytes are
667
- // flushed either way, which is the part that carries the digests.
668
- }
669
- }
670
- /** The commit finished (or was rolled back): there is nothing left to recover from. */
671
- export async function clearCommitIntent(docsDir) {
672
- await quietRm(join(docsDir, COMMIT_INTENT));
673
- }
674
- /** The intent record as written, or null when it is absent or unreadable. */
675
- export async function readCommitIntent(docsDir) {
676
- const path = join(docsDir, COMMIT_INTENT);
677
- if (!existsSync(path))
678
- return null;
679
- let parsed;
680
- try {
681
- parsed = JSON.parse(await readFile(path, "utf8"));
682
- }
683
- catch {
684
- return null;
685
- }
686
- const i = parsed;
687
- if (i === null || typeof i !== "object")
688
- return null;
689
- if (i.version !== COMMIT_INTENT_VERSION)
690
- return null;
691
- if (i.command !== "archive" && i.command !== "unarchive")
692
- return null;
693
- if (i.restore !== "before" && i.restore !== "after")
694
- return null;
695
- if (typeof i.feature !== "string" || typeof i.moveFrom !== "string" || typeof i.moveTo !== "string")
696
- return null;
697
- if (!Array.isArray(i.files))
698
- return null;
699
- for (const f of i.files) {
700
- if (typeof f?.path !== "string")
701
- return null;
702
- if (!isDigestOrNull(f.before) || !isDigestOrNull(f.after))
703
- return null;
704
- }
705
- return i;
706
- }
707
- function isDigestOrNull(value) {
708
- return value === null || isDigest(value);
709
- }
710
- /**
711
- * Refuse or repair before this run reads anything. Returns null when there is
712
- * nothing to recover.
713
- *
714
- * Repair is only ever the bytes the interrupted run already had on disk: each
715
- * file still in the wrong state is rewritten from the snapshot pre-image and
716
- * only after that pre-image's own sha256 matches the digest the record captured
717
- * before the crash. A file in NEITHER state was written by somebody else since,
718
- * so this refuses and names it rather than choosing which of two truths to
719
- * destroy — the same doctrine `rollbackStaged` follows when it leaves a file as
720
- * found.
721
- */
722
- export async function recoverInterruptedCommit(docsDir) {
723
- const path = join(docsDir, COMMIT_INTENT);
724
- if (!existsSync(path))
725
- return null;
726
- const intent = await readCommitIntent(docsDir);
727
- if (intent === null) {
728
- throw new InterruptedCommitError(`${repoPath(docsDir, path)} records a commit this loam cannot read, so it cannot tell a half-merged docs repo ` +
729
- `from a healthy one. Check the living docs against version control, delete ${COMMIT_INTENT}, then re-run.`);
730
- }
731
- const moveFrom = join(docsDir, ...intent.moveFrom.split("/"));
732
- const moveTo = join(docsDir, ...intent.moveTo.split("/"));
733
- // The move is the commit's LAST step. If it landed, every swap before it did
734
- // too, and only the record's own removal was lost.
735
- if (existsSync(moveTo) && !existsSync(moveFrom)) {
736
- await finishRecovery(docsDir, intent);
737
- return { command: intent.command, feature: intent.feature, outcome: "completed", repaired: [] };
738
- }
739
- const target = (rel) => join(docsDir, ...rel.split("/"));
740
- const wanted = (f) => (intent.restore === "before" ? f.before : f.after);
741
- const other = (f) => (intent.restore === "before" ? f.after : f.before);
742
- const pending = [];
743
- const unknown = [];
744
- for (const f of intent.files) {
745
- const file = target(f.path);
746
- const now = existsSync(file) ? sha256(await readFile(file)) : null;
747
- if (now === wanted(f))
748
- continue;
749
- if (now === other(f))
750
- pending.push(f);
751
- else
752
- unknown.push(f.path);
753
- }
754
- if (unknown.length > 0) {
755
- throw new InterruptedCommitError(`a \`loam ${intent.command} ${intent.feature}\` was interrupted mid-commit (pid ${intent.pid} on ${intent.host}, ` +
756
- `${intent.at}) and ${unknown.length} of the file(s) it was writing now hold bytes that are neither what it ` +
757
- `found nor what it wrote — somebody edited them since: ${unknown.join(", ")}. loam will not choose between ` +
758
- `those two truths. Reconcile them against version control, delete ${COMMIT_INTENT}, then re-run.`);
759
- }
760
- if (pending.length === 0) {
761
- await finishRecovery(docsDir, intent);
762
- return { command: intent.command, feature: intent.feature, outcome: "consistent", repaired: [] };
763
- }
764
- // The pre-images travel inside the feature directory, so they are at one of
765
- // the two ends of the move depending on how far the interrupted run got.
766
- const roots = [join(moveFrom, SNAPSHOT_DIR, "files"), join(moveTo, SNAPSHOT_DIR, "files")];
767
- const repaired = [];
768
- for (const f of pending) {
769
- const file = target(f.path);
770
- const want = wanted(f);
771
- if (want === null) {
772
- await rm(file, { force: true });
773
- await quietRmdir(dirname(file));
774
- repaired.push(f.path);
775
- continue;
776
- }
777
- const source = roots.map((r) => join(r, ...f.path.split("/"))).find((p) => existsSync(p));
778
- if (source === undefined) {
779
- throw new InterruptedCommitError(`a \`loam ${intent.command} ${intent.feature}\` was interrupted mid-commit and ${f.path} is half-written, but ` +
780
- `the pre-image that would repair it is gone. Restore ${f.path} from version control, delete ` +
781
- `${COMMIT_INTENT}, then re-run.`);
782
- }
783
- const bytes = await readFile(source);
784
- if (sha256(bytes) !== want) {
785
- throw new InterruptedCommitError(`a \`loam ${intent.command} ${intent.feature}\` was interrupted mid-commit and ${f.path} is half-written, but ` +
786
- `the pre-image that would repair it no longer matches the digest recorded before the commit — it has been ` +
787
- `edited since. Restore ${f.path} from version control, delete ${COMMIT_INTENT}, then re-run.`);
788
- }
789
- await atomicWrite(file, bytes);
790
- repaired.push(f.path);
791
- }
792
- await finishRecovery(docsDir, intent);
793
- return { command: intent.command, feature: intent.feature, outcome: "repaired", repaired };
794
- }
795
- /**
796
- * Drop the record, and the staged temp files the killed run could not remove.
797
- *
798
- * Scoped to that run's own pid and its own targets — the temp name carries both
799
- * — so a leftover belonging to anything else is left for `doctor` to name.
800
- * Without this a repair that put every byte back still left the docs repo
801
- * dirty, which is the one thing a caller checks to decide whether it worked.
802
- */
803
- async function finishRecovery(docsDir, intent) {
804
- const dirs = new Set(intent.files.map((f) => dirname(join(docsDir, ...f.path.split("/")))));
805
- for (const dir of dirs) {
806
- let entries;
807
- try {
808
- entries = await readdir(dir);
809
- }
810
- catch {
811
- continue;
812
- }
813
- for (const name of entries) {
814
- if (!TEMP_FILE_RE.test(name) || !name.includes(`.loam-${intent.pid}-`))
815
- continue;
816
- await quietRm(join(dir, name));
817
- }
818
- }
819
- await clearCommitIntent(docsDir);
820
- }
821
- /** Remove `dir` if it is empty. Best effort — a directory left standing is noise, not corruption. */
822
- async function quietRmdir(dir) {
823
- try {
824
- await rmdir(dir);
825
- }
826
- catch {
827
- // Not empty, or not ours.
828
- }
829
- }
830
- export async function scanWritePathResidue(docsDir) {
831
- const lockPath = join(docsDir, DOCS_LOCK);
832
- let lock = null;
833
- if (existsSync(lockPath)) {
834
- lock = { path: repoPath(docsDir, lockPath), holder: await describeLock(lockPath), stale: await lockIsStale(lockPath) };
835
- }
836
- const intent = await readCommitIntent(docsDir);
837
- return {
838
- lock,
839
- intent,
840
- intentUnreadable: intent === null && existsSync(join(docsDir, COMMIT_INTENT)),
841
- temps: (await tempLeftovers(docsDir)).map((p) => repoPath(docsDir, p)).sort(),
842
- };
843
- }
844
- /** Does the lock name a pid on THIS host that no longer exists? Read-only twin of breakStaleLock. */
845
- async function lockIsStale(path) {
846
- let holder;
847
- try {
848
- holder = JSON.parse(await readFile(path, "utf8"));
849
- }
850
- catch {
851
- return false;
852
- }
853
- // Same shape guard as `breakStaleLock`, for the same reason: this one is read
854
- // by `doctor`, which must be able to describe a broken repo without becoming
855
- // the next thing that breaks.
856
- if (!isRecord(holder))
857
- return false;
858
- if (holder.host !== hostname() || typeof holder.pid !== "number")
859
- return false;
860
- try {
861
- process.kill(holder.pid, 0);
862
- return false;
863
- }
864
- catch (err) {
865
- return err.code === "ESRCH";
866
- }
867
- }
868
- async function tempLeftovers(dir) {
869
- const out = [];
870
- let entries;
871
- try {
872
- entries = await readdir(dir, { withFileTypes: true });
873
- }
874
- catch {
875
- return out;
876
- }
877
- for (const entry of entries) {
878
- // `.git` alone can hold more files than the whole docs repo, and nothing
879
- // loam writes ever lands in it.
880
- if (entry.name === ".git" || entry.name === "node_modules")
881
- continue;
882
- const path = join(dir, entry.name);
883
- if (entry.isDirectory())
884
- out.push(...(await tempLeftovers(path)));
885
- else if (entry.isFile() && TEMP_FILE_RE.test(entry.name))
886
- out.push(path);
887
- }
888
- return out;
889
- }
890
- //# sourceMappingURL=staging.js.map