@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.
- package/CHANGELOG.md +5992 -82
- package/COMPARISON.md +168 -63
- package/CONTRIBUTING.md +121 -0
- package/MIGRATING-from-OpenSpec.md +238 -55
- package/QUICKSTART.md +302 -0
- package/README.md +653 -144
- package/ROADMAP.md +1035 -0
- package/SCHEMA.md +3916 -263
- package/SECURITY.md +21 -3
- package/WORKFLOW.md +927 -0
- package/dist/cli.js +133 -21
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt/adopt.js +204 -0
- package/dist/commands/adopt/adopt.js.map +1 -0
- package/dist/commands/adopt/render.js +309 -0
- package/dist/commands/adopt/render.js.map +1 -0
- package/dist/commands/archive/archive.js +74 -0
- package/dist/commands/archive/archive.js.map +1 -0
- package/dist/commands/archive/closing.js +42 -0
- package/dist/commands/archive/closing.js.map +1 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/consumers.js +56 -0
- package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
- package/dist/commands/archive/plan/contracts/openapi.js +193 -0
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
- package/dist/commands/archive/plan/document/head.js +151 -0
- package/dist/commands/archive/plan/document/head.js.map +1 -0
- package/dist/commands/archive/plan/document/links.js +284 -0
- package/dist/commands/archive/plan/document/links.js.map +1 -0
- package/dist/commands/archive/plan/document/run.js +136 -0
- package/dist/commands/archive/plan/document/run.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +319 -0
- package/dist/commands/archive/plan/gate.js.map +1 -0
- package/dist/commands/archive/plan/landscape.js +298 -0
- package/dist/commands/archive/plan/landscape.js.map +1 -0
- package/dist/commands/archive/plan/model/extending.js +85 -0
- package/dist/commands/archive/plan/model/extending.js.map +1 -0
- package/dist/commands/archive/plan/refusal.js +106 -0
- package/dist/commands/archive/plan/refusal.js.map +1 -0
- package/dist/commands/archive/plan/specs.js +318 -0
- package/dist/commands/archive/plan/specs.js.map +1 -0
- package/dist/commands/archive/plan/state.js +30 -0
- package/dist/commands/archive/plan/state.js.map +1 -0
- package/dist/commands/archive/run.js +355 -0
- package/dist/commands/archive/run.js.map +1 -0
- package/dist/commands/archive/shipped.js +49 -0
- package/dist/commands/archive/shipped.js.map +1 -0
- package/dist/commands/context/context.js +166 -0
- package/dist/commands/context/context.js.map +1 -0
- package/dist/commands/context/print.js +305 -0
- package/dist/commands/context/print.js.map +1 -0
- package/dist/commands/delta/delta.js +367 -0
- package/dist/commands/delta/delta.js.map +1 -0
- package/dist/commands/delta/print.js +221 -0
- package/dist/commands/delta/print.js.map +1 -0
- package/dist/commands/dependencies.js +6 -8
- package/dist/commands/dependencies.js.map +1 -1
- package/dist/commands/diff/diff.js +86 -0
- package/dist/commands/diff/diff.js.map +1 -0
- package/dist/commands/diff/print.js +38 -0
- package/dist/commands/diff/print.js.map +1 -0
- package/dist/commands/doctor.js +65 -5
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain/explain.js +227 -0
- package/dist/commands/explain/explain.js.map +1 -0
- package/dist/commands/explore.js +39 -28
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/gate/gate.js +152 -0
- package/dist/commands/gate/gate.js.map +1 -0
- package/dist/commands/gate/print.js +66 -0
- package/dist/commands/gate/print.js.map +1 -0
- package/dist/commands/gherkin/commit.js +105 -0
- package/dist/commands/gherkin/commit.js.map +1 -0
- package/dist/commands/gherkin/gherkin.js +262 -0
- package/dist/commands/gherkin/gherkin.js.map +1 -0
- package/dist/commands/gherkin/reconcile.js +146 -0
- package/dist/commands/gherkin/reconcile.js.map +1 -0
- package/dist/commands/gherkin/render.js +77 -0
- package/dist/commands/gherkin/render.js.map +1 -0
- package/dist/commands/init/example.js +204 -0
- package/dist/commands/init/example.js.map +1 -0
- package/dist/commands/init/first-hour.js +72 -0
- package/dist/commands/init/first-hour.js.map +1 -0
- package/dist/commands/{init.js → init/init.js} +142 -71
- package/dist/commands/init/init.js.map +1 -0
- package/dist/commands/init/mcp.js +131 -0
- package/dist/commands/init/mcp.js.map +1 -0
- package/dist/commands/init/options.js +78 -0
- package/dist/commands/init/options.js.map +1 -0
- package/dist/commands/instructions.js +72 -14
- package/dist/commands/instructions.js.map +1 -1
- package/dist/commands/list/campaign/campaign.js +63 -0
- package/dist/commands/list/campaign/campaign.js.map +1 -0
- package/dist/commands/list/campaign/owners.js +65 -0
- package/dist/commands/list/campaign/owners.js.map +1 -0
- package/dist/commands/list/json.js +155 -0
- package/dist/commands/list/json.js.map +1 -0
- package/dist/commands/list/list.js +358 -0
- package/dist/commands/list/list.js.map +1 -0
- package/dist/commands/list/print.js +344 -0
- package/dist/commands/list/print.js.map +1 -0
- package/dist/commands/list/review.js +120 -0
- package/dist/commands/list/review.js.map +1 -0
- package/dist/commands/list/suites/suites.js +140 -0
- package/dist/commands/list/suites/suites.js.map +1 -0
- package/dist/commands/list/views.js +108 -0
- package/dist/commands/list/views.js.map +1 -0
- package/dist/commands/mcp/dispatch.js +238 -0
- package/dist/commands/mcp/dispatch.js.map +1 -0
- package/dist/commands/mcp/mcp.js +75 -0
- package/dist/commands/mcp/mcp.js.map +1 -0
- package/dist/commands/mcp/serve.js +55 -0
- package/dist/commands/mcp/serve.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/active.js +175 -0
- package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
- package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/living.js +62 -0
- package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
- package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/target.js +219 -0
- package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/error.js +18 -0
- package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
- package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/read.js +49 -0
- package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
- package/dist/commands/migrate-openspec/print.js +89 -0
- package/dist/commands/migrate-openspec/print.js.map +1 -0
- package/dist/commands/new/capability-template.js +118 -0
- package/dist/commands/new/capability-template.js.map +1 -0
- package/dist/commands/new/commit.js +62 -0
- package/dist/commands/new/commit.js.map +1 -0
- package/dist/commands/new/modifies.js +206 -0
- package/dist/commands/new/modifies.js.map +1 -0
- package/dist/commands/new/new.js +328 -0
- package/dist/commands/new/new.js.map +1 -0
- package/dist/commands/new/templates.js +279 -0
- package/dist/commands/new/templates.js.map +1 -0
- package/dist/commands/open.js +199 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/policy/format.js +152 -0
- package/dist/commands/policy/format.js.map +1 -0
- package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
- package/dist/commands/policy/gate.js.map +1 -0
- package/dist/commands/rebase/edit.js +106 -0
- package/dist/commands/rebase/edit.js.map +1 -0
- package/dist/commands/rebase/living.js +185 -0
- package/dist/commands/rebase/living.js.map +1 -0
- package/dist/commands/rebase/plan.js +245 -0
- package/dist/commands/rebase/plan.js.map +1 -0
- package/dist/commands/rebase/rebase.js +300 -0
- package/dist/commands/rebase/rebase.js.map +1 -0
- package/dist/commands/seed/commit.js +221 -0
- package/dist/commands/seed/commit.js.map +1 -0
- package/dist/commands/seed/plan.js +278 -0
- package/dist/commands/seed/plan.js.map +1 -0
- package/dist/commands/seed/seed.js +174 -0
- package/dist/commands/seed/seed.js.map +1 -0
- package/dist/commands/show/feature.js +182 -0
- package/dist/commands/show/feature.js.map +1 -0
- package/dist/commands/show/introduced.js +157 -0
- package/dist/commands/show/introduced.js.map +1 -0
- package/dist/commands/show/marks.js +53 -0
- package/dist/commands/show/marks.js.map +1 -0
- package/dist/commands/show/service.js +239 -0
- package/dist/commands/show/service.js.map +1 -0
- package/dist/commands/show/show.js +87 -0
- package/dist/commands/show/show.js.map +1 -0
- package/dist/commands/status/fleet-next.js +90 -0
- package/dist/commands/status/fleet-next.js.map +1 -0
- package/dist/commands/status/json.js +47 -0
- package/dist/commands/status/json.js.map +1 -0
- package/dist/commands/status/print.js +209 -0
- package/dist/commands/status/print.js.map +1 -0
- package/dist/commands/status/status.js +115 -0
- package/dist/commands/status/status.js.map +1 -0
- package/dist/commands/steps/steps.js +269 -0
- package/dist/commands/steps/steps.js.map +1 -0
- package/dist/commands/subsystem/edit.js +192 -0
- package/dist/commands/subsystem/edit.js.map +1 -0
- package/dist/commands/subsystem/move.js +325 -0
- package/dist/commands/subsystem/move.js.map +1 -0
- package/dist/commands/subsystem/query.js +113 -0
- package/dist/commands/subsystem/query.js.map +1 -0
- package/dist/commands/subsystem/subsystem.js +98 -0
- package/dist/commands/subsystem/subsystem.js.map +1 -0
- package/dist/commands/subsystem/sync.js +318 -0
- package/dist/commands/subsystem/sync.js.map +1 -0
- package/dist/commands/subsystem/txn/exclude.js +132 -0
- package/dist/commands/subsystem/txn/exclude.js.map +1 -0
- package/dist/commands/subsystem/txn/links.js +128 -0
- package/dist/commands/subsystem/txn/links.js.map +1 -0
- package/dist/commands/subsystem/txn/report.js +174 -0
- package/dist/commands/subsystem/txn/report.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +196 -0
- package/dist/commands/subsystem/txn/txn.js.map +1 -0
- package/dist/commands/subsystem/txn/views.js +249 -0
- package/dist/commands/subsystem/txn/views.js.map +1 -0
- package/dist/commands/tasks/actions.js +107 -0
- package/dist/commands/tasks/actions.js.map +1 -0
- package/dist/commands/tasks/render.js +253 -0
- package/dist/commands/tasks/render.js.map +1 -0
- package/dist/commands/tasks/tasks.js +119 -0
- package/dist/commands/tasks/tasks.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +176 -0
- package/dist/commands/unarchive/manifest.js.map +1 -0
- package/dist/commands/unarchive/restore.js +254 -0
- package/dist/commands/unarchive/restore.js.map +1 -0
- package/dist/commands/unarchive/unarchive.js +59 -0
- package/dist/commands/unarchive/unarchive.js.map +1 -0
- package/dist/commands/validate/arch-coverage.js +245 -0
- package/dist/commands/validate/arch-coverage.js.map +1 -0
- package/dist/commands/validate/checks/fleet-shape.js +204 -0
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
- package/dist/commands/validate/checks/health-deps.js +58 -0
- package/dist/commands/validate/checks/health-deps.js.map +1 -0
- package/dist/commands/validate/checks/introduced.js +102 -0
- package/dist/commands/validate/checks/introduced.js.map +1 -0
- package/dist/commands/validate/checks/requirements.js +264 -0
- package/dist/commands/validate/checks/requirements.js.map +1 -0
- package/dist/commands/validate/checks/sources.js +85 -0
- package/dist/commands/validate/checks/sources.js.map +1 -0
- package/dist/commands/validate/coverage/covers-after.js +105 -0
- package/dist/commands/validate/coverage/covers-after.js.map +1 -0
- package/dist/commands/validate/feature.js +222 -0
- package/dist/commands/validate/feature.js.map +1 -0
- package/dist/commands/validate/fleet/census.js +93 -0
- package/dist/commands/validate/fleet/census.js.map +1 -0
- package/dist/commands/validate/fleet/kind-tags.js +39 -0
- package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
- package/dist/commands/validate/fleet/landscape.js +371 -0
- package/dist/commands/validate/fleet/landscape.js.map +1 -0
- package/dist/commands/validate/fleet/load.js +118 -0
- package/dist/commands/validate/fleet/load.js.map +1 -0
- package/dist/commands/validate/fleet/map/attest.js +98 -0
- package/dist/commands/validate/fleet/map/attest.js.map +1 -0
- package/dist/commands/validate/fleet/map/bindings.js +107 -0
- package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
- package/dist/commands/validate/fleet/map/consumers.js +244 -0
- package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
- package/dist/commands/validate/fleet/map/isolation.js +116 -0
- package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
- package/dist/commands/validate/fleet/map/usecases.js +54 -0
- package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/obligations.js +266 -0
- package/dist/commands/validate/fleet/obligations.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/print.js +71 -0
- package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/place.js +13 -0
- package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
- package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
- package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +75 -0
- package/dist/commands/validate/fleet/views/ids.js.map +1 -0
- package/dist/commands/validate/fleet/views/projects.js +278 -0
- package/dist/commands/validate/fleet/views/projects.js.map +1 -0
- package/dist/commands/validate/fleet/views/root-documents.js +83 -0
- package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +52 -0
- package/dist/commands/validate/fleet/views/stale.js.map +1 -0
- package/dist/commands/validate/links/corpus.js +89 -0
- package/dist/commands/validate/links/corpus.js.map +1 -0
- package/dist/commands/validate/links/glossary.js +75 -0
- package/dist/commands/validate/links/glossary.js.map +1 -0
- package/dist/commands/validate/render/repeats.js +63 -0
- package/dist/commands/validate/render/repeats.js.map +1 -0
- package/dist/commands/validate/render/rollups.js +115 -0
- package/dist/commands/validate/render/rollups.js.map +1 -0
- package/dist/commands/validate/render/text.js +199 -0
- package/dist/commands/validate/render/text.js.map +1 -0
- package/dist/commands/validate/report.js +145 -0
- package/dist/commands/validate/report.js.map +1 -0
- package/dist/commands/validate/scope.js +113 -0
- package/dist/commands/validate/scope.js.map +1 -0
- package/dist/commands/validate/service/api.js +252 -0
- package/dist/commands/validate/service/api.js.map +1 -0
- package/dist/commands/validate/service/contracts/generated.js +134 -0
- package/dist/commands/validate/service/contracts/generated.js.map +1 -0
- package/dist/commands/validate/service/events/events.js +241 -0
- package/dist/commands/validate/service/events/events.js.map +1 -0
- package/dist/commands/validate/service/events/message-producers.js +77 -0
- package/dist/commands/validate/service/events/message-producers.js.map +1 -0
- package/dist/commands/validate/service/evidence-pins.js +177 -0
- package/dist/commands/validate/service/evidence-pins.js.map +1 -0
- package/dist/commands/validate/service/model/diverged.js +226 -0
- package/dist/commands/validate/service/model/diverged.js.map +1 -0
- package/dist/commands/validate/service/model/grade.js +163 -0
- package/dist/commands/validate/service/model/grade.js.map +1 -0
- package/dist/commands/validate/service/service.js +310 -0
- package/dist/commands/validate/service/service.js.map +1 -0
- package/dist/commands/validate/service/specs.js +279 -0
- package/dist/commands/validate/service/specs.js.map +1 -0
- package/dist/commands/validate/service/spine.js +148 -0
- package/dist/commands/validate/service/spine.js.map +1 -0
- package/dist/commands/validate/service/usecases/tags.js +113 -0
- package/dist/commands/validate/service/usecases/tags.js.map +1 -0
- package/dist/commands/validate/service/usecases/usecases.js +209 -0
- package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/validate.js +363 -0
- package/dist/commands/validate/validate.js.map +1 -0
- package/dist/commands/verify/cross/diff.js +178 -0
- package/dist/commands/verify/cross/diff.js.map +1 -0
- package/dist/commands/verify/evidence/contract.js +32 -0
- package/dist/commands/verify/evidence/contract.js.map +1 -0
- package/dist/commands/verify/evidence/pins.js +52 -0
- package/dist/commands/verify/evidence/pins.js.map +1 -0
- package/dist/commands/verify/evidence/read.js +81 -0
- package/dist/commands/verify/evidence/read.js.map +1 -0
- package/dist/commands/verify/frozen.js +263 -0
- package/dist/commands/verify/frozen.js.map +1 -0
- package/dist/commands/verify/record.js +278 -0
- package/dist/commands/verify/record.js.map +1 -0
- package/dist/commands/verify/report.js +206 -0
- package/dist/commands/verify/report.js.map +1 -0
- package/dist/commands/verify/results.js +328 -0
- package/dist/commands/verify/results.js.map +1 -0
- package/dist/commands/verify/verify.js +220 -0
- package/dist/commands/verify/verify.js.map +1 -0
- package/dist/commands/vouch/contract.js +11 -0
- package/dist/commands/vouch/contract.js.map +1 -0
- package/dist/commands/vouch/pack/contract.js +2 -0
- package/dist/commands/vouch/pack/contract.js.map +1 -0
- package/dist/commands/vouch/pack/pack.js +266 -0
- package/dist/commands/vouch/pack/pack.js.map +1 -0
- package/dist/commands/vouch/pack/print.js +266 -0
- package/dist/commands/vouch/pack/print.js.map +1 -0
- package/dist/commands/vouch/pack/sections.js +141 -0
- package/dist/commands/vouch/pack/sections.js.map +1 -0
- package/dist/commands/vouch/prompt/confirm.js +46 -0
- package/dist/commands/vouch/prompt/confirm.js.map +1 -0
- package/dist/commands/vouch/report.js +101 -0
- package/dist/commands/vouch/report.js.map +1 -0
- package/dist/commands/vouch/run.js +230 -0
- package/dist/commands/vouch/run.js.map +1 -0
- package/dist/commands/vouch/sample/plan.js +111 -0
- package/dist/commands/vouch/sample/plan.js.map +1 -0
- package/dist/commands/vouch/sample/print.js +109 -0
- package/dist/commands/vouch/sample/print.js.map +1 -0
- package/dist/commands/vouch/vet/verify.js +155 -0
- package/dist/commands/vouch/vet/verify.js.map +1 -0
- package/dist/commands/vouch/vouch.js +169 -0
- package/dist/commands/vouch/vouch.js.map +1 -0
- package/dist/core/agent/agents-md/command-map.js +299 -0
- package/dist/core/agent/agents-md/command-map.js.map +1 -0
- package/dist/core/agent/agents-md/map/explain.js +46 -0
- package/dist/core/agent/agents-md/map/explain.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
- package/dist/core/agent/agents-md/map/mcp.js +44 -0
- package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
- package/dist/core/agent/agents-md/map/status.js +78 -0
- package/dist/core/agent/agents-md/map/status.js.map +1 -0
- package/dist/core/agent/agents-md/map/subsystem.js +104 -0
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
- package/dist/core/agent/agents-md/map/usecases.js +138 -0
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
- package/dist/core/agent/agents-md/refusals.js +273 -0
- package/dist/core/agent/agents-md/refusals.js.map +1 -0
- package/dist/core/agent/agents-md.js +203 -0
- package/dist/core/agent/agents-md.js.map +1 -0
- package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
- package/dist/core/agent/agents-stamp.js.map +1 -0
- package/dist/core/agent/contract.js +2 -0
- package/dist/core/agent/contract.js.map +1 -0
- package/dist/core/agent/protocol.js +193 -0
- package/dist/core/agent/protocol.js.map +1 -0
- package/dist/core/agent/scaffold.js +254 -0
- package/dist/core/agent/scaffold.js.map +1 -0
- package/dist/core/agent/support/report.js +144 -0
- package/dist/core/agent/support/report.js.map +1 -0
- package/dist/core/agent/tools/dialects.js +151 -0
- package/dist/core/agent/tools/dialects.js.map +1 -0
- package/dist/core/agent/tools/registry.js +193 -0
- package/dist/core/agent/tools/registry.js.map +1 -0
- package/dist/core/agent/workflows/adopt.js +280 -0
- package/dist/core/agent/workflows/adopt.js.map +1 -0
- package/dist/core/agent/workflows/check.js +373 -0
- package/dist/core/agent/workflows/check.js.map +1 -0
- package/dist/core/agent/workflows/closing.js +323 -0
- package/dist/core/agent/workflows/closing.js.map +1 -0
- package/dist/core/agent/workflows/feature.js +220 -0
- package/dist/core/agent/workflows/feature.js.map +1 -0
- package/dist/core/agent/workflows/implement.js +188 -0
- package/dist/core/agent/workflows/implement.js.map +1 -0
- package/dist/core/agent/workflows/reference/authoring.js +311 -0
- package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
- package/dist/core/agent/workflows/reference/codes.js +67 -0
- package/dist/core/agent/workflows/reference/codes.js.map +1 -0
- package/dist/core/agent/workflows/reference/done-check.js +210 -0
- package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
- package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
- package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
- package/dist/core/agent/workflows/reference/reference.js +19 -0
- package/dist/core/agent/workflows/reference/reference.js.map +1 -0
- package/dist/core/agent/workflows/reference/spine.js +338 -0
- package/dist/core/agent/workflows/reference/spine.js.map +1 -0
- package/dist/core/asyncapi/baseline/plan.js +43 -0
- package/dist/core/asyncapi/baseline/plan.js.map +1 -0
- package/dist/core/asyncapi/baseline/surfaces.js +54 -0
- package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
- package/dist/core/asyncapi/depth.js +164 -0
- package/dist/core/asyncapi/depth.js.map +1 -0
- package/dist/core/asyncapi/digest.js +146 -0
- package/dist/core/asyncapi/digest.js.map +1 -0
- package/dist/core/asyncapi/merge/components.js +92 -0
- package/dist/core/asyncapi/merge/components.js.map +1 -0
- package/dist/core/asyncapi/merge/error.js +38 -0
- package/dist/core/asyncapi/merge/error.js.map +1 -0
- package/dist/core/asyncapi/merge/markers.js +290 -0
- package/dist/core/asyncapi/merge/markers.js.map +1 -0
- package/dist/core/asyncapi/merge/merge.js +195 -0
- package/dist/core/asyncapi/merge/merge.js.map +1 -0
- package/dist/core/asyncapi/merge/pin.js +83 -0
- package/dist/core/asyncapi/merge/pin.js.map +1 -0
- package/dist/core/asyncapi/model.js +11 -0
- package/dist/core/asyncapi/model.js.map +1 -0
- package/dist/core/asyncapi/producers.js +50 -0
- package/dist/core/asyncapi/producers.js.map +1 -0
- package/dist/core/asyncapi/read.js +263 -0
- package/dist/core/asyncapi/read.js.map +1 -0
- package/dist/core/brief/brief.js +285 -0
- package/dist/core/brief/brief.js.map +1 -0
- package/dist/core/brief/checks.js +385 -0
- package/dist/core/brief/checks.js.map +1 -0
- package/dist/core/brief/landscape.js +273 -0
- package/dist/core/brief/landscape.js.map +1 -0
- package/dist/core/brief/map/extend.js +84 -0
- package/dist/core/brief/map/extend.js.map +1 -0
- package/dist/core/brief/map/owed.js +266 -0
- package/dist/core/brief/map/owed.js.map +1 -0
- package/dist/core/brief/targets.js +304 -0
- package/dist/core/brief/targets.js.map +1 -0
- package/dist/core/brief/unchecked.js +58 -0
- package/dist/core/brief/unchecked.js.map +1 -0
- package/dist/core/c4/arch.js +190 -0
- package/dist/core/c4/arch.js.map +1 -0
- package/dist/core/c4/direction/direction.js +114 -0
- package/dist/core/c4/direction/direction.js.map +1 -0
- package/dist/core/c4/likec4.js +243 -0
- package/dist/core/c4/likec4.js.map +1 -0
- package/dist/core/c4/locate/unlocated.js +150 -0
- package/dist/core/c4/locate/unlocated.js.map +1 -0
- package/dist/core/c4/parsed/deployment.js +160 -0
- package/dist/core/c4/parsed/deployment.js.map +1 -0
- package/dist/core/c4/parsed/dynamic-views.js +132 -0
- package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
- package/dist/core/c4/parsed/specification.js +78 -0
- package/dist/core/c4/parsed/specification.js.map +1 -0
- package/dist/core/c4/parsed/values.js +110 -0
- package/dist/core/c4/parsed/values.js.map +1 -0
- package/dist/core/c4/parsed/view-ids.js +113 -0
- package/dist/core/c4/parsed/view-ids.js.map +1 -0
- package/dist/core/c4/prefetch/fleet.js +134 -0
- package/dist/core/c4/prefetch/fleet.js.map +1 -0
- package/dist/core/c4/project/architecture.js +161 -0
- package/dist/core/c4/project/architecture.js.map +1 -0
- package/dist/core/c4/project/batch.js +140 -0
- package/dist/core/c4/project/batch.js.map +1 -0
- package/dist/core/c4/project/documents.js +89 -0
- package/dist/core/c4/project/documents.js.map +1 -0
- package/dist/core/c4/project/load.js +219 -0
- package/dist/core/c4/project/load.js.map +1 -0
- package/dist/core/c4/project/staged.js +277 -0
- package/dist/core/c4/project/staged.js.map +1 -0
- package/dist/core/c4/resolve/attested.js +0 -0
- package/dist/core/c4/resolve/attested.js.map +1 -0
- package/dist/core/c4/resolve/external.js +51 -0
- package/dist/core/c4/resolve/external.js.map +1 -0
- package/dist/core/c4/resolve/service.js +174 -0
- package/dist/core/c4/resolve/service.js.map +1 -0
- package/dist/core/c4/resolve/steps.js +290 -0
- package/dist/core/c4/resolve/steps.js.map +1 -0
- package/dist/core/c4/resolve/systems.js +154 -0
- package/dist/core/c4/resolve/systems.js.map +1 -0
- package/dist/core/c4/root-project/exclude.js +352 -0
- package/dist/core/c4/root-project/exclude.js.map +1 -0
- package/dist/core/c4/seed/fleet-file.js +201 -0
- package/dist/core/c4/seed/fleet-file.js.map +1 -0
- package/dist/core/c4/seed/items.js +91 -0
- package/dist/core/c4/seed/items.js.map +1 -0
- package/dist/core/c4/seed/stamp.js +48 -0
- package/dist/core/c4/seed/stamp.js.map +1 -0
- package/dist/core/c4/seed/template.js +173 -0
- package/dist/core/c4/seed/template.js.map +1 -0
- package/dist/core/c4/service-model/created/models.js +96 -0
- package/dist/core/c4/service-model/created/models.js.map +1 -0
- package/dist/core/c4/service-model/documents.js +47 -0
- package/dist/core/c4/service-model/documents.js.map +1 -0
- package/dist/core/c4/service-model/fleet/extending.js +82 -0
- package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
- package/dist/core/c4/service-model/load.js +165 -0
- package/dist/core/c4/service-model/load.js.map +1 -0
- package/dist/core/c4/service-model/renderer.js +128 -0
- package/dist/core/c4/service-model/renderer.js.map +1 -0
- package/dist/core/c4/service-model/shape.js +106 -0
- package/dist/core/c4/service-model/shape.js.map +1 -0
- package/dist/core/c4/service-model/slice.js +188 -0
- package/dist/core/c4/service-model/slice.js.map +1 -0
- package/dist/core/c4/source-mask.js +369 -0
- package/dist/core/c4/source-mask.js.map +1 -0
- package/dist/core/c4/source-scan.js +308 -0
- package/dist/core/c4/source-scan.js.map +1 -0
- package/dist/core/c4/splice/authored-source.js +167 -0
- package/dist/core/c4/splice/authored-source.js.map +1 -0
- package/dist/core/c4/splice/contract.js +30 -0
- package/dist/core/c4/splice/contract.js.map +1 -0
- package/dist/core/c4/splice/delta-blocks.js +126 -0
- package/dist/core/c4/splice/delta-blocks.js.map +1 -0
- package/dist/core/c4/splice/identity/declared.js +87 -0
- package/dist/core/c4/splice/identity/declared.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +73 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -0
- package/dist/core/c4/splice/identity/existing.js +80 -0
- package/dist/core/c4/splice/identity/existing.js.map +1 -0
- package/dist/core/c4/splice/identity/interior.js +80 -0
- package/dist/core/c4/splice/identity/interior.js.map +1 -0
- package/dist/core/c4/splice/identity/owner.js +50 -0
- package/dist/core/c4/splice/identity/owner.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +337 -0
- package/dist/core/c4/splice/landscape-merge.js.map +1 -0
- package/dist/core/c4/splice/model/merge.js +151 -0
- package/dist/core/c4/splice/model/merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +298 -0
- package/dist/core/c4/splice/placement.js.map +1 -0
- package/dist/core/c4/splice/text/spot.js +131 -0
- package/dist/core/c4/splice/text/spot.js.map +1 -0
- package/dist/core/c4/workspace.js +166 -0
- package/dist/core/c4/workspace.js.map +1 -0
- package/dist/core/capabilities/authoring/notes.js +141 -0
- package/dist/core/capabilities/authoring/notes.js.map +1 -0
- package/dist/core/capabilities/capabilities.js +124 -0
- package/dist/core/capabilities/capabilities.js.map +1 -0
- package/dist/core/capabilities/delta/doc.js +47 -0
- package/dist/core/capabilities/delta/doc.js.map +1 -0
- package/dist/core/capabilities/delta/overlay.js +129 -0
- package/dist/core/capabilities/delta/overlay.js.map +1 -0
- package/dist/core/capabilities/delta/summary.js +57 -0
- package/dist/core/capabilities/delta/summary.js.map +1 -0
- package/dist/core/capabilities/delta/tree.js +43 -0
- package/dist/core/capabilities/delta/tree.js.map +1 -0
- package/dist/core/capabilities/delta/uncovered.js +222 -0
- package/dist/core/capabilities/delta/uncovered.js.map +1 -0
- package/dist/core/capabilities/findings.js +338 -0
- package/dist/core/capabilities/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/findings.js +174 -0
- package/dist/core/capabilities/realizes/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/join.js +123 -0
- package/dist/core/capabilities/realizes/join.js.map +1 -0
- package/dist/core/capabilities/rollup.js +205 -0
- package/dist/core/capabilities/rollup.js.map +1 -0
- package/dist/core/capabilities/tree.js +104 -0
- package/dist/core/capabilities/tree.js.map +1 -0
- package/dist/core/capabilities/usecase-join.js +267 -0
- package/dist/core/capabilities/usecase-join.js.map +1 -0
- package/dist/core/coherence/authoring/scaffold.js +185 -0
- package/dist/core/coherence/authoring/scaffold.js.map +1 -0
- package/dist/core/coherence/authoring/sentinels.js +75 -0
- package/dist/core/coherence/authoring/sentinels.js.map +1 -0
- package/dist/core/coherence/calls/called.js +52 -0
- package/dist/core/coherence/calls/called.js.map +1 -0
- package/dist/core/coherence/coherence.js +332 -0
- package/dist/core/coherence/coherence.js.map +1 -0
- package/dist/core/coherence/consumed/operations.js +70 -0
- package/dist/core/coherence/consumed/operations.js.map +1 -0
- package/dist/core/coherence/consumed/refusal.js +38 -0
- package/dist/core/coherence/consumed/refusal.js.map +1 -0
- package/dist/core/coherence/covers/health.js +85 -0
- package/dist/core/coherence/covers/health.js.map +1 -0
- package/dist/core/coherence/declared.js +295 -0
- package/dist/core/coherence/declared.js.map +1 -0
- package/dist/core/coherence/events/declared.js +191 -0
- package/dist/core/coherence/events/declared.js.map +1 -0
- package/dist/core/coherence/events/events.js +335 -0
- package/dist/core/coherence/events/events.js.map +1 -0
- package/dist/core/coherence/events/grades.js +189 -0
- package/dist/core/coherence/events/grades.js.map +1 -0
- package/dist/core/coherence/events/lookups.js +63 -0
- package/dist/core/coherence/events/lookups.js.map +1 -0
- package/dist/core/coherence/events/produced.js +100 -0
- package/dist/core/coherence/events/produced.js.map +1 -0
- package/dist/core/coherence/living.js +198 -0
- package/dist/core/coherence/living.js.map +1 -0
- package/dist/core/coherence/lookups.js +95 -0
- package/dist/core/coherence/lookups.js.map +1 -0
- package/dist/core/coherence/pending.js +39 -0
- package/dist/core/coherence/pending.js.map +1 -0
- package/dist/core/coherence/retired/archived.js +285 -0
- package/dist/core/coherence/retired/archived.js.map +1 -0
- package/dist/core/coherence/retired/event-pair.js +62 -0
- package/dist/core/coherence/retired/event-pair.js.map +1 -0
- package/dist/core/coherence/retired/merged.js +79 -0
- package/dist/core/coherence/retired/merged.js.map +1 -0
- package/dist/core/coherence/retired/retirement.js +49 -0
- package/dist/core/coherence/retired/retirement.js.map +1 -0
- package/dist/core/coherence/retired/revival/arrivals.js +131 -0
- package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
- package/dist/core/coherence/retired/revival/revived.js +297 -0
- package/dist/core/coherence/retired/revival/revived.js.map +1 -0
- package/dist/core/conflict-markers.js +60 -0
- package/dist/core/conflict-markers.js.map +1 -0
- package/dist/core/consumers/after.js +113 -0
- package/dist/core/consumers/after.js.map +1 -0
- package/dist/core/consumers/consumers.js +296 -0
- package/dist/core/consumers/consumers.js.map +1 -0
- package/dist/core/consumers/current.js +211 -0
- package/dist/core/consumers/current.js.map +1 -0
- package/dist/core/consumers/scan.js +46 -0
- package/dist/core/consumers/scan.js.map +1 -0
- package/dist/core/consumers/state.js +27 -0
- package/dist/core/consumers/state.js.map +1 -0
- package/dist/core/delta/claims.js +73 -0
- package/dist/core/delta/claims.js.map +1 -0
- package/dist/core/delta/delta.js +341 -0
- package/dist/core/delta/delta.js.map +1 -0
- package/dist/core/delta/document.js +177 -0
- package/dist/core/delta/document.js.map +1 -0
- package/dist/core/delta/scope.js +48 -0
- package/dist/core/delta/scope.js.map +1 -0
- package/dist/core/delta/select.js +237 -0
- package/dist/core/delta/select.js.map +1 -0
- package/dist/core/dependencies/dependencies.js +141 -0
- package/dist/core/dependencies/dependencies.js.map +1 -0
- package/dist/core/dependencies/facts.js +165 -0
- package/dist/core/dependencies/facts.js.map +1 -0
- package/dist/core/dependencies/fanin.js +88 -0
- package/dist/core/dependencies/fanin.js.map +1 -0
- package/dist/core/dependencies/graph.js +106 -0
- package/dist/core/dependencies/graph.js.map +1 -0
- package/dist/core/deployment/delta.js +191 -0
- package/dist/core/deployment/delta.js.map +1 -0
- package/dist/core/deployment/objects.js +145 -0
- package/dist/core/deployment/objects.js.map +1 -0
- package/dist/core/diff/base-git.js +230 -0
- package/dist/core/diff/base-git.js.map +1 -0
- package/dist/core/diff/base-state.js +237 -0
- package/dist/core/diff/base-state.js.map +1 -0
- package/dist/core/diff/joins.js +136 -0
- package/dist/core/diff/joins.js.map +1 -0
- package/dist/core/diff/scope/changed-paths.js +204 -0
- package/dist/core/diff/scope/changed-paths.js.map +1 -0
- package/dist/core/diff/scope/edges.js +82 -0
- package/dist/core/diff/scope/edges.js.map +1 -0
- package/dist/core/diff/semantic.js +312 -0
- package/dist/core/diff/semantic.js.map +1 -0
- package/dist/core/docs.js +37 -85
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/agents.js +238 -0
- package/dist/core/doctor/agents.js.map +1 -0
- package/dist/core/doctor/config.js +139 -0
- package/dist/core/doctor/config.js.map +1 -0
- package/dist/core/doctor/doctor.js +355 -0
- package/dist/core/doctor/doctor.js.map +1 -0
- package/dist/core/doctor/report.js +13 -0
- package/dist/core/doctor/report.js.map +1 -0
- package/dist/core/doctor/reports/scan.js +242 -0
- package/dist/core/doctor/reports/scan.js.map +1 -0
- package/dist/core/doctor/residue.js +110 -0
- package/dist/core/doctor/residue.js.map +1 -0
- package/dist/core/document/apply.js +224 -0
- package/dist/core/document/apply.js.map +1 -0
- package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
- package/dist/core/document/frontmatter.js.map +1 -0
- package/dist/core/document/grammar/directives.js +143 -0
- package/dist/core/document/grammar/directives.js.map +1 -0
- package/dist/core/document/parse.js +286 -0
- package/dist/core/document/parse.js.map +1 -0
- package/dist/core/document/scenarios.js +238 -0
- package/dist/core/document/scenarios.js.map +1 -0
- package/dist/core/document/spec.js +234 -0
- package/dist/core/document/spec.js.map +1 -0
- package/dist/core/{config.js → envelope/config.js} +89 -18
- package/dist/core/envelope/config.js.map +1 -0
- package/dist/core/envelope/json.js +209 -0
- package/dist/core/envelope/json.js.map +1 -0
- package/dist/core/{version.js → envelope/version.js} +3 -3
- package/dist/core/envelope/version.js.map +1 -0
- package/dist/core/explain/families.js +180 -0
- package/dist/core/explain/families.js.map +1 -0
- package/dist/core/explain/fix-tables.js +178 -0
- package/dist/core/explain/fix-tables.js.map +1 -0
- package/dist/core/explain/lookup.js +194 -0
- package/dist/core/explain/lookup.js.map +1 -0
- package/dist/core/explain/refusals.js +49 -0
- package/dist/core/explain/refusals.js.map +1 -0
- package/dist/core/explain/terms/documents.js +227 -0
- package/dist/core/explain/terms/documents.js.map +1 -0
- package/dist/core/explain/terms/done-check.js +144 -0
- package/dist/core/explain/terms/done-check.js.map +1 -0
- package/dist/core/explain/terms/entry.js +14 -0
- package/dist/core/explain/terms/entry.js.map +1 -0
- package/dist/core/explain/terms/stages.js +71 -0
- package/dist/core/explain/terms/stages.js.map +1 -0
- package/dist/core/explain/terms/tasks.js +97 -0
- package/dist/core/explain/terms/tasks.js.map +1 -0
- package/dist/core/explain/terms.js +103 -0
- package/dist/core/explain/terms.js.map +1 -0
- package/dist/core/explore/describe.js +105 -0
- package/dist/core/explore/describe.js.map +1 -0
- package/dist/core/explore/explore.js +204 -0
- package/dist/core/explore/explore.js.map +1 -0
- package/dist/core/fleet-context.js +174 -146
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +208 -0
- package/dist/core/gate/checks.js.map +1 -0
- package/dist/core/gate/partners.js +246 -0
- package/dist/core/gate/partners.js.map +1 -0
- package/dist/core/gate/report.js +47 -0
- package/dist/core/gate/report.js.map +1 -0
- package/dist/core/gate/verification.js +176 -0
- package/dist/core/gate/verification.js.map +1 -0
- package/dist/core/gherkin/digest.js +60 -0
- package/dist/core/gherkin/digest.js.map +1 -0
- package/dist/core/gherkin/emit.js +177 -0
- package/dist/core/gherkin/emit.js.map +1 -0
- package/dist/core/gherkin/read.js +76 -0
- package/dist/core/gherkin/read.js.map +1 -0
- package/dist/core/gherkin/stale.js +210 -0
- package/dist/core/gherkin/stale.js.map +1 -0
- package/dist/core/gherkin/stamp.js +77 -0
- package/dist/core/gherkin/stamp.js.map +1 -0
- package/dist/core/gherkin/steps/catalogue.js +154 -0
- package/dist/core/gherkin/steps/catalogue.js.map +1 -0
- package/dist/core/gherkin/steps/inventory.js +98 -0
- package/dist/core/gherkin/steps/inventory.js.map +1 -0
- package/dist/core/gherkin/steps/phrase.js +72 -0
- package/dist/core/gherkin/steps/phrase.js.map +1 -0
- package/dist/core/glossary/delta.js +109 -0
- package/dist/core/glossary/delta.js.map +1 -0
- package/dist/core/glossary/tree.js +73 -0
- package/dist/core/glossary/tree.js.map +1 -0
- package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
- package/dist/core/kernel/concurrency.js.map +1 -0
- package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
- package/dist/core/kernel/document-bytes.js.map +1 -0
- package/dist/core/kernel/fences.js +42 -0
- package/dist/core/kernel/fences.js.map +1 -0
- package/dist/core/kernel/ids/capability.js +72 -0
- package/dist/core/kernel/ids/capability.js.map +1 -0
- package/dist/core/kernel/ids/dirs.js +33 -0
- package/dist/core/kernel/ids/dirs.js.map +1 -0
- package/dist/core/kernel/ids/feature.js +75 -0
- package/dist/core/kernel/ids/feature.js.map +1 -0
- package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
- package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
- package/dist/core/kernel/ids/service.js +156 -0
- package/dist/core/kernel/ids/service.js.map +1 -0
- package/dist/core/kernel/ids/subsystem.js +63 -0
- package/dist/core/kernel/ids/subsystem.js.map +1 -0
- package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
- package/dist/core/kernel/path-safety.js.map +1 -0
- package/dist/core/{records.js → kernel/records.js} +11 -0
- package/dist/core/kernel/records.js.map +1 -0
- package/dist/core/links/backlinks.js +66 -0
- package/dist/core/links/backlinks.js.map +1 -0
- package/dist/core/links/case.js +74 -0
- package/dist/core/links/case.js.map +1 -0
- package/dist/core/links/corpus.js +118 -0
- package/dist/core/links/corpus.js.map +1 -0
- package/dist/core/links/findings.js +110 -0
- package/dist/core/links/findings.js.map +1 -0
- package/dist/core/links/parse.js +265 -0
- package/dist/core/links/parse.js.map +1 -0
- package/dist/core/mcp/argv.js +212 -0
- package/dist/core/mcp/argv.js.map +1 -0
- package/dist/core/mcp/author-tools.js +73 -0
- package/dist/core/mcp/author-tools.js.map +1 -0
- package/dist/core/mcp/framing.js +46 -0
- package/dist/core/mcp/framing.js.map +1 -0
- package/dist/core/mcp/protocol.js +280 -0
- package/dist/core/mcp/protocol.js.map +1 -0
- package/dist/core/mcp/tools.js +324 -0
- package/dist/core/mcp/tools.js.map +1 -0
- package/dist/core/obligations/obligations.js +106 -0
- package/dist/core/obligations/obligations.js.map +1 -0
- package/dist/core/openapi/baseline/gate.js +207 -0
- package/dist/core/openapi/baseline/gate.js.map +1 -0
- package/dist/core/openapi/baseline/plan.js +142 -0
- package/dist/core/openapi/baseline/plan.js.map +1 -0
- package/dist/core/openapi/baseline/record.js +174 -0
- package/dist/core/openapi/baseline/record.js.map +1 -0
- package/dist/core/openapi/contract-text.js +33 -0
- package/dist/core/openapi/contract-text.js.map +1 -0
- package/dist/core/openapi/contract-tree.js +301 -0
- package/dist/core/openapi/contract-tree.js.map +1 -0
- package/dist/core/openapi/depth.js +136 -0
- package/dist/core/openapi/depth.js.map +1 -0
- package/dist/core/openapi/digest.js +239 -0
- package/dist/core/openapi/digest.js.map +1 -0
- package/dist/core/{openapi.js → openapi/doc.js} +54 -108
- package/dist/core/openapi/doc.js.map +1 -0
- package/dist/core/openapi/merge/components.js +199 -0
- package/dist/core/openapi/merge/components.js.map +1 -0
- package/dist/core/openapi/merge/error.js +16 -0
- package/dist/core/openapi/merge/error.js.map +1 -0
- package/dist/core/openapi/merge/markers.js +204 -0
- package/dist/core/openapi/merge/markers.js.map +1 -0
- package/dist/core/openapi/merge/merge.js +232 -0
- package/dist/core/openapi/merge/merge.js.map +1 -0
- package/dist/core/openapi/merge/pin.js +110 -0
- package/dist/core/openapi/merge/pin.js.map +1 -0
- package/dist/core/openspec/decide/capabilities.js +244 -0
- package/dist/core/openspec/decide/capabilities.js.map +1 -0
- package/dist/core/openspec/decide/dispositions.js +63 -0
- package/dist/core/openspec/decide/dispositions.js.map +1 -0
- package/dist/core/openspec/decide/renames.js +179 -0
- package/dist/core/openspec/decide/renames.js.map +1 -0
- package/dist/core/openspec/decide/verdict.js +84 -0
- package/dist/core/openspec/decide/verdict.js.map +1 -0
- package/dist/core/openspec/inventory.js +220 -0
- package/dist/core/openspec/inventory.js.map +1 -0
- package/dist/core/openspec/model/mapping.js +78 -0
- package/dist/core/openspec/model/mapping.js.map +1 -0
- package/dist/core/openspec/model/model.js +70 -0
- package/dist/core/openspec/model/model.js.map +1 -0
- package/dist/core/openspec/scan/changes.js +241 -0
- package/dist/core/openspec/scan/changes.js.map +1 -0
- package/dist/core/openspec/scan/config.js +191 -0
- package/dist/core/openspec/scan/config.js.map +1 -0
- package/dist/core/openspec/scan/shape.js +304 -0
- package/dist/core/openspec/scan/shape.js.map +1 -0
- package/dist/core/openspec/scan/walk.js +116 -0
- package/dist/core/openspec/scan/walk.js.map +1 -0
- package/dist/core/openspec/scan/workspace.js +71 -0
- package/dist/core/openspec/scan/workspace.js.map +1 -0
- package/dist/core/owners/codeowners.js +141 -0
- package/dist/core/owners/codeowners.js.map +1 -0
- package/dist/core/pack/features.js +120 -0
- package/dist/core/pack/features.js.map +1 -0
- package/dist/core/pack/joins.js +112 -0
- package/dist/core/pack/joins.js.map +1 -0
- package/dist/core/pack/living.js +157 -0
- package/dist/core/pack/living.js.map +1 -0
- package/dist/core/pack/pack.js +120 -0
- package/dist/core/pack/pack.js.map +1 -0
- package/dist/core/permissions/permissions.js +87 -0
- package/dist/core/permissions/permissions.js.map +1 -0
- package/dist/core/projection/api.js +84 -0
- package/dist/core/projection/api.js.map +1 -0
- package/dist/core/projection/arch-slice.js +63 -0
- package/dist/core/projection/arch-slice.js.map +1 -0
- package/dist/core/projection/events.js +34 -0
- package/dist/core/projection/events.js.map +1 -0
- package/dist/core/projection/introduced.js +14 -0
- package/dist/core/projection/introduced.js.map +1 -0
- package/dist/core/provenance/findings.js +244 -0
- package/dist/core/provenance/findings.js.map +1 -0
- package/dist/core/provenance/git.js +201 -0
- package/dist/core/provenance/git.js.map +1 -0
- package/dist/core/provenance/gitq/moves.js +139 -0
- package/dist/core/provenance/gitq/moves.js.map +1 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
- package/dist/core/provenance/sample/scope.js +238 -0
- package/dist/core/provenance/sample/scope.js.map +1 -0
- package/dist/core/provenance/sample/sections.js +61 -0
- package/dist/core/provenance/sample/sections.js.map +1 -0
- package/dist/core/provenance/sources.js +280 -0
- package/dist/core/provenance/sources.js.map +1 -0
- package/dist/core/provenance/stamp.js +220 -0
- package/dist/core/provenance/stamp.js.map +1 -0
- package/dist/core/provenance/walk.js +157 -0
- package/dist/core/provenance/walk.js.map +1 -0
- package/dist/core/repo/authored/paths.js +210 -0
- package/dist/core/repo/authored/paths.js.map +1 -0
- package/dist/core/repo/entries.js +126 -0
- package/dist/core/repo/entries.js.map +1 -0
- package/dist/core/repo/paths.js +322 -0
- package/dist/core/repo/paths.js.map +1 -0
- package/dist/core/repo/repo.js +308 -0
- package/dist/core/repo/repo.js.map +1 -0
- package/dist/core/repo/service-target.js +153 -0
- package/dist/core/repo/service-target.js.map +1 -0
- package/dist/core/repo/state.js +58 -0
- package/dist/core/repo/state.js.map +1 -0
- package/dist/core/repo/tree/find.js +61 -0
- package/dist/core/repo/tree/find.js.map +1 -0
- package/dist/core/repo/tree/fs.js +90 -0
- package/dist/core/repo/tree/fs.js.map +1 -0
- package/dist/core/repo/tree/marker.js +61 -0
- package/dist/core/repo/tree/marker.js.map +1 -0
- package/dist/core/repo/tree/render/body.js +258 -0
- package/dist/core/repo/tree/render/body.js.map +1 -0
- package/dist/core/repo/tree/render/projects.js +182 -0
- package/dist/core/repo/tree/render/projects.js.map +1 -0
- package/dist/core/repo/tree/render/service/header.js +125 -0
- package/dist/core/repo/tree/render/service/header.js.map +1 -0
- package/dist/core/repo/tree/render/service/peers.js +28 -0
- package/dist/core/repo/tree/render/service/peers.js.map +1 -0
- package/dist/core/repo/tree/render/service/view-id.js +67 -0
- package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
- package/dist/core/repo/tree/render/service/views.js +78 -0
- package/dist/core/repo/tree/render/service/views.js.map +1 -0
- package/dist/core/repo/tree/render/stale.js +42 -0
- package/dist/core/repo/tree/render/stale.js.map +1 -0
- package/dist/core/repo/tree/render/text.js +84 -0
- package/dist/core/repo/tree/render/text.js.map +1 -0
- package/dist/core/repo/tree/render/views.js +293 -0
- package/dist/core/repo/tree/render/views.js.map +1 -0
- package/dist/core/repo/tree/walk.js +255 -0
- package/dist/core/repo/tree/walk.js.map +1 -0
- package/dist/core/results.js +146 -14
- package/dist/core/results.js.map +1 -1
- package/dist/core/scaffold/landscape.js +239 -0
- package/dist/core/scaffold/landscape.js.map +1 -0
- package/dist/core/scaffold/legacy.js +271 -0
- package/dist/core/scaffold/legacy.js.map +1 -0
- package/dist/core/scaffold/readme.js +84 -0
- package/dist/core/scaffold/readme.js.map +1 -0
- package/dist/core/staging/commit.js +252 -0
- package/dist/core/staging/commit.js.map +1 -0
- package/dist/core/staging/interrupted.js +96 -0
- package/dist/core/staging/interrupted.js.map +1 -0
- package/dist/core/staging/lock.js +268 -0
- package/dist/core/staging/lock.js.map +1 -0
- package/dist/core/staging/recovery/finding.js +35 -0
- package/dist/core/staging/recovery/finding.js.map +1 -0
- package/dist/core/staging/recovery/intent.js +95 -0
- package/dist/core/staging/recovery/intent.js.map +1 -0
- package/dist/core/staging/recovery/recover.js +204 -0
- package/dist/core/staging/recovery/recover.js.map +1 -0
- package/dist/core/staging/recovery/residue.js +62 -0
- package/dist/core/staging/recovery/residue.js.map +1 -0
- package/dist/core/staging/snapshot/manifest.js +188 -0
- package/dist/core/staging/snapshot/manifest.js.map +1 -0
- package/dist/core/staging/snapshot/snapshot.js +196 -0
- package/dist/core/staging/snapshot/snapshot.js.map +1 -0
- package/dist/core/staging/txn/forward.js +181 -0
- package/dist/core/staging/txn/forward.js.map +1 -0
- package/dist/core/staging/txn/journal.js +139 -0
- package/dist/core/staging/txn/journal.js.map +1 -0
- package/dist/core/staging/txn/transaction.js +75 -0
- package/dist/core/staging/txn/transaction.js.map +1 -0
- package/dist/core/staging/writes.js +113 -0
- package/dist/core/staging/writes.js.map +1 -0
- package/dist/core/status/actions/execution.js +60 -0
- package/dist/core/status/actions/execution.js.map +1 -0
- package/dist/core/status/contracts.js +126 -0
- package/dist/core/status/contracts.js.map +1 -0
- package/dist/core/status/feature/artifacts.js +196 -0
- package/dist/core/status/feature/artifacts.js.map +1 -0
- package/dist/core/status/feature/feature.js +214 -0
- package/dist/core/status/feature/feature.js.map +1 -0
- package/dist/core/status/feature/next.js +163 -0
- package/dist/core/status/feature/next.js.map +1 -0
- package/dist/core/status/feature/state.js +21 -0
- package/dist/core/status/feature/state.js.map +1 -0
- package/dist/core/status/feature/words.js +96 -0
- package/dist/core/status/feature/words.js.map +1 -0
- package/dist/core/status/fleet/fleet.js +216 -0
- package/dist/core/status/fleet/fleet.js.map +1 -0
- package/dist/core/status/fleet/next.js +302 -0
- package/dist/core/status/fleet/next.js.map +1 -0
- package/dist/core/status/interrupted.js +97 -0
- package/dist/core/status/interrupted.js.map +1 -0
- package/dist/core/status/report.js +31 -0
- package/dist/core/status/report.js.map +1 -0
- package/dist/core/status/scan.js +41 -0
- package/dist/core/status/scan.js.map +1 -0
- package/dist/core/status/verification.js +216 -0
- package/dist/core/status/verification.js.map +1 -0
- package/dist/core/tasks/packet.js +199 -0
- package/dist/core/tasks/packet.js.map +1 -0
- package/dist/core/tasks/record.js +43 -0
- package/dist/core/tasks/record.js.map +1 -0
- package/dist/core/tasks/sources.js +181 -0
- package/dist/core/tasks/sources.js.map +1 -0
- package/dist/core/tasks/stamps.js +76 -0
- package/dist/core/tasks/stamps.js.map +1 -0
- package/dist/core/tasks/unit.js +0 -0
- package/dist/core/tasks/unit.js.map +1 -0
- package/dist/core/usecases/capability.js +166 -0
- package/dist/core/usecases/capability.js.map +1 -0
- package/dist/core/usecases/delta/claims.js +140 -0
- package/dist/core/usecases/delta/claims.js.map +1 -0
- package/dist/core/usecases/delta/flows.js +101 -0
- package/dist/core/usecases/delta/flows.js.map +1 -0
- package/dist/core/usecases/delta/modified.js +315 -0
- package/dist/core/usecases/delta/modified.js.map +1 -0
- package/dist/core/usecases/delta/overlay.js +76 -0
- package/dist/core/usecases/delta/overlay.js.map +1 -0
- package/dist/core/usecases/fleet.js +296 -0
- package/dist/core/usecases/fleet.js.map +1 -0
- package/dist/core/usecases/grade/capability-tag.js +93 -0
- package/dist/core/usecases/grade/capability-tag.js.map +1 -0
- package/dist/core/usecases/grade/feature.js +88 -0
- package/dist/core/usecases/grade/feature.js.map +1 -0
- package/dist/core/usecases/grade/requirement-tag.js +94 -0
- package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
- package/dist/core/usecases/grade/steps.js +266 -0
- package/dist/core/usecases/grade/steps.js.map +1 -0
- package/dist/core/usecases/grade/usecases.js +112 -0
- package/dist/core/usecases/grade/usecases.js.map +1 -0
- package/dist/core/usecases/operations.js +123 -0
- package/dist/core/usecases/operations.js.map +1 -0
- package/dist/core/usecases/place.js +44 -0
- package/dist/core/usecases/place.js.map +1 -0
- package/dist/core/usecases/service/exclude.js +119 -0
- package/dist/core/usecases/service/exclude.js.map +1 -0
- package/dist/core/usecases/service/flows.js +164 -0
- package/dist/core/usecases/service/flows.js.map +1 -0
- package/dist/core/usecases/suites/participants.js +83 -0
- package/dist/core/usecases/suites/participants.js.map +1 -0
- package/dist/core/usecases/suites/suites.js +45 -0
- package/dist/core/usecases/suites/suites.js.map +1 -0
- package/dist/core/usecases/touch.js +101 -0
- package/dist/core/usecases/touch.js.map +1 -0
- package/dist/core/verify/answers.js +180 -0
- package/dist/core/verify/answers.js.map +1 -0
- package/dist/core/verify/build.js +170 -0
- package/dist/core/verify/build.js.map +1 -0
- package/dist/core/verify/checklist.js +259 -0
- package/dist/core/verify/checklist.js.map +1 -0
- package/dist/core/verify/claims/identity.js +61 -0
- package/dist/core/verify/claims/identity.js.map +1 -0
- package/dist/core/verify/cross/diff.js +97 -0
- package/dist/core/verify/cross/diff.js.map +1 -0
- package/dist/core/verify/evidence/contract.js +169 -0
- package/dist/core/verify/evidence/contract.js.map +1 -0
- package/dist/core/verify/location.js +67 -0
- package/dist/core/verify/location.js.map +1 -0
- package/dist/core/verify/pins/lint.js +158 -0
- package/dist/core/verify/pins/lint.js.map +1 -0
- package/dist/core/verify/pins/pin.js +95 -0
- package/dist/core/verify/pins/pin.js.map +1 -0
- package/dist/core/verify/read/file.js +224 -0
- package/dist/core/verify/read/file.js.map +1 -0
- package/dist/core/verify/read/shape.js +169 -0
- package/dist/core/verify/read/shape.js.map +1 -0
- package/dist/core/verify/read/union.js +105 -0
- package/dist/core/verify/read/union.js.map +1 -0
- package/dist/core/verify/record.js +165 -0
- package/dist/core/verify/record.js.map +1 -0
- package/dist/core/verify/store/commit.js +99 -0
- package/dist/core/verify/store/commit.js.map +1 -0
- package/dist/core/verify/store/render.js +61 -0
- package/dist/core/verify/store/render.js.map +1 -0
- package/dist/core/vocabulary/health.js +91 -0
- package/dist/core/vocabulary/health.js.map +1 -0
- package/dist/core/vocabulary/issue.js +59 -0
- package/dist/core/vocabulary/issue.js.map +1 -0
- package/dist/core/vocabulary/maturity.js +216 -0
- package/dist/core/vocabulary/maturity.js.map +1 -0
- package/dist/core/vocabulary/report.js +90 -0
- package/dist/core/vocabulary/report.js.map +1 -0
- package/dist/core/vocabulary/steps.js +266 -0
- package/dist/core/vocabulary/steps.js.map +1 -0
- package/dist/core/workspace/discover.js +239 -0
- package/dist/core/workspace/discover.js.map +1 -0
- package/dist/core/workspace/render.js +52 -0
- package/dist/core/workspace/render.js.map +1 -0
- package/examples/README.md +232 -0
- package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
- package/examples/docs/architecture/capabilities.yaml +31 -0
- package/examples/docs/architecture/landscape.likec4 +336 -0
- package/examples/docs/architecture/obligations.yaml +23 -0
- package/examples/docs/architecture/permissions.yaml +50 -0
- package/examples/docs/architecture/services.likec4 +70 -0
- package/examples/docs/architecture/subsystems.likec4 +18 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
- package/examples/docs/capabilities/checkout/spec.md +55 -0
- package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
- package/examples/docs/capabilities/order-notifications/spec.md +43 -0
- package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
- package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
- package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
- package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
- package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
- package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
- package/examples/docs/glossary/order.md +15 -0
- package/examples/docs/glossary/payments/authorization.md +14 -0
- package/examples/docs/likec4.config.json +8 -0
- package/examples/docs/loam.json +3 -0
- package/examples/docs/services/checkout-web/model.likec4 +92 -0
- package/examples/docs/services/checkout-web/spec.md +91 -0
- package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
- package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
- package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
- package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
- package/examples/docs/services/order-service/arch.spec.md +134 -0
- package/examples/docs/services/order-service/asyncapi.yaml +109 -0
- package/examples/docs/services/order-service/health.yaml +57 -0
- package/examples/docs/services/order-service/model.likec4 +126 -0
- package/examples/docs/services/order-service/openapi.yaml +257 -0
- package/examples/docs/services/order-service/runbook.md +62 -0
- package/examples/docs/services/order-service/spec.md +134 -0
- package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
- package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
- package/examples/docs/services/payment-service/arch.spec.md +76 -0
- package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
- package/examples/docs/services/payment-service/health.yaml +39 -0
- package/examples/docs/services/payment-service/model.likec4 +68 -0
- package/examples/docs/services/payment-service/openapi.yaml +151 -0
- package/examples/docs/services/payment-service/runbook.md +37 -0
- package/examples/docs/services/payment-service/spec.md +88 -0
- package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
- package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
- package/examples/docs/services/platform/identity-service/health.yaml +70 -0
- package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
- package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
- package/examples/docs/services/platform/identity-service/runbook.md +95 -0
- package/examples/docs/services/platform/identity-service/spec.md +119 -0
- package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
- package/examples/docs/services/platform/notification-service/health.yaml +40 -0
- package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
- package/examples/docs/services/platform/notification-service/runbook.md +48 -0
- package/examples/docs/services/platform/notification-service/spec.md +112 -0
- package/examples/docs/services/platform/subsystem.yaml +2 -0
- package/examples/fleet.yaml +57 -0
- package/package.json +19 -6
- package/dist/commands/adopt.js +0 -240
- package/dist/commands/adopt.js.map +0 -1
- package/dist/commands/archive.js +0 -1313
- package/dist/commands/archive.js.map +0 -1
- package/dist/commands/delta.js +0 -388
- package/dist/commands/delta.js.map +0 -1
- package/dist/commands/docs-repo-gate.js.map +0 -1
- package/dist/commands/format.js +0 -17
- package/dist/commands/format.js.map +0 -1
- package/dist/commands/gherkin.js +0 -309
- package/dist/commands/gherkin.js.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list.js +0 -295
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/migrate-openspec.js +0 -950
- package/dist/commands/migrate-openspec.js.map +0 -1
- package/dist/commands/new.js +0 -413
- package/dist/commands/new.js.map +0 -1
- package/dist/commands/rebase.js +0 -356
- package/dist/commands/rebase.js.map +0 -1
- package/dist/commands/show.js +0 -320
- package/dist/commands/show.js.map +0 -1
- package/dist/commands/status.js +0 -262
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/unarchive.js +0 -317
- package/dist/commands/unarchive.js.map +0 -1
- package/dist/commands/validate.js +0 -1773
- package/dist/commands/validate.js.map +0 -1
- package/dist/commands/verify.js +0 -775
- package/dist/commands/verify.js.map +0 -1
- package/dist/commands/vouch.js +0 -421
- package/dist/commands/vouch.js.map +0 -1
- package/dist/core/agent.js +0 -2173
- package/dist/core/agent.js.map +0 -1
- package/dist/core/agents-stamp.js.map +0 -1
- package/dist/core/arch.js +0 -130
- package/dist/core/arch.js.map +0 -1
- package/dist/core/asyncapi.js +0 -253
- package/dist/core/asyncapi.js.map +0 -1
- package/dist/core/brief.js +0 -755
- package/dist/core/brief.js.map +0 -1
- package/dist/core/coherence.js +0 -577
- package/dist/core/coherence.js.map +0 -1
- package/dist/core/concurrency.js.map +0 -1
- package/dist/core/config.js.map +0 -1
- package/dist/core/delta.js +0 -476
- package/dist/core/delta.js.map +0 -1
- package/dist/core/dependencies.js +0 -356
- package/dist/core/dependencies.js.map +0 -1
- package/dist/core/doctor.js +0 -596
- package/dist/core/doctor.js.map +0 -1
- package/dist/core/document-bytes.js.map +0 -1
- package/dist/core/explore.js +0 -225
- package/dist/core/explore.js.map +0 -1
- package/dist/core/frontmatter.js.map +0 -1
- package/dist/core/gherkin.js +0 -463
- package/dist/core/gherkin.js.map +0 -1
- package/dist/core/health.js +0 -67
- package/dist/core/health.js.map +0 -1
- package/dist/core/ids.js +0 -122
- package/dist/core/ids.js.map +0 -1
- package/dist/core/issue.js +0 -9
- package/dist/core/issue.js.map +0 -1
- package/dist/core/json.js +0 -74
- package/dist/core/json.js.map +0 -1
- package/dist/core/likec4.js +0 -489
- package/dist/core/likec4.js.map +0 -1
- package/dist/core/maturity.js +0 -66
- package/dist/core/maturity.js.map +0 -1
- package/dist/core/openapi-merge.js +0 -552
- package/dist/core/openapi-merge.js.map +0 -1
- package/dist/core/openapi.js.map +0 -1
- package/dist/core/openspec-inventory.js +0 -1440
- package/dist/core/openspec-inventory.js.map +0 -1
- package/dist/core/path-safety.js.map +0 -1
- package/dist/core/provenance.js +0 -787
- package/dist/core/provenance.js.map +0 -1
- package/dist/core/records.js.map +0 -1
- package/dist/core/repo.js +0 -438
- package/dist/core/repo.js.map +0 -1
- package/dist/core/report.js +0 -47
- package/dist/core/report.js.map +0 -1
- package/dist/core/spec.js +0 -505
- package/dist/core/spec.js.map +0 -1
- package/dist/core/staging.js +0 -890
- package/dist/core/staging.js.map +0 -1
- package/dist/core/status.js +0 -1132
- package/dist/core/status.js.map +0 -1
- package/dist/core/steps.js +0 -72
- package/dist/core/steps.js.map +0 -1
- package/dist/core/verify.js +0 -807
- package/dist/core/verify.js.map +0 -1
- package/dist/core/version.js.map +0 -1
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The architecture spec axis — the grammar and resolution of `Covers:` — and
|
|
3
|
+
* the same endpoint join, reused, for the steps of a use case.
|
|
4
|
+
*
|
|
5
|
+
* A business spec will never mention the transactional outbox; that is
|
|
6
|
+
* architecture, and it lives in `arch.spec.md` — same requirement/scenario
|
|
7
|
+
* grammar as spec.md, same delta algebra, same merge. What is new is the
|
|
8
|
+
* `Covers:` line: where a business requirement declares the OPERATIONS it
|
|
9
|
+
* governs, an architecture requirement declares the MODEL OBJECTS its
|
|
10
|
+
* scenarios exercise, so coverage can be derived mechanically instead of
|
|
11
|
+
* trusted to an author who was never going to write the outbox down.
|
|
12
|
+
*
|
|
13
|
+
* Four entry forms, resolved against the documents loam already reads:
|
|
14
|
+
*
|
|
15
|
+
* paymentService.db a C4 element id — resolved against the
|
|
16
|
+
* in-scope elements the way every check joins
|
|
17
|
+
* them: the id itself, or the service the
|
|
18
|
+
* element stands for (binding, then title);
|
|
19
|
+
* paymentService -> kafka an edge — each side resolved the same way,
|
|
20
|
+
* against the declared relationships; the
|
|
21
|
+
* edge may carry the relationship's kind as
|
|
22
|
+
* LikeC4 writes it, `paymentService -[async]->
|
|
23
|
+
* kafka` or `paymentService .async kafka`,
|
|
24
|
+
* which is read past rather than compared;
|
|
25
|
+
* alert:<id> / sli:<id> a health signal — ids `health.yaml`
|
|
26
|
+
* declares (core/vocabulary/health.ts);
|
|
27
|
+
* node:<id>, node:a -> node:b a deployment object — a node or an instance
|
|
28
|
+
* in the landscape's `deployment { }` model,
|
|
29
|
+
* matched literally. This is the form that
|
|
30
|
+
* lets a requirement about replication name
|
|
31
|
+
* the two clusters it is written about
|
|
32
|
+
* (ROADMAP's deployment axis).
|
|
33
|
+
*
|
|
34
|
+
* Resolution never reads code. An entry that resolves to nothing is the typo
|
|
35
|
+
* guard (`covers.unknown`, warn); the emitters live with the other validate
|
|
36
|
+
* checks, this module owns only the grammar and the matching.
|
|
37
|
+
*
|
|
38
|
+
* `attributeStep` used to sit at the foot of this file and now lives in
|
|
39
|
+
* `./resolve/steps.ts`. It answers the same shape of question for a different
|
|
40
|
+
* axis — which declared relationship backs a `dynamic view`'s hop — over the
|
|
41
|
+
* same two tiers and the same cached resolver, and the seam was named here long
|
|
42
|
+
* before the line limit forced it. What the two still share is
|
|
43
|
+
* `./resolve/service.ts`'s `resolverFor`, which is where that cache moved with
|
|
44
|
+
* it: one id→service resolver per document, serving both axes.
|
|
45
|
+
*/
|
|
46
|
+
import {} from "./likec4.js";
|
|
47
|
+
import { elementService, resolverFor } from "./resolve/service.js";
|
|
48
|
+
/** Parse one comma-separated `Covers:` entry into its form. Never fails: an
|
|
49
|
+
* unclassifiable string is an element entry that will not resolve, and the
|
|
50
|
+
* covers.unknown message is a better diagnosis than a parse refusal. */
|
|
51
|
+
export function parseCoversEntry(raw) {
|
|
52
|
+
const alert = /^alert:\s*(.+)$/.exec(raw);
|
|
53
|
+
if (alert)
|
|
54
|
+
return { form: "alert", id: alert[1].trim(), raw };
|
|
55
|
+
const sli = /^sli:\s*(.+)$/.exec(raw);
|
|
56
|
+
if (sli)
|
|
57
|
+
return { form: "sli", id: sli[1].trim(), raw };
|
|
58
|
+
// An edge may be spelled with its relationship kind, the two ways LikeC4
|
|
59
|
+
// writes one — `a -[async]-> b`, and `a .async b` for a kind the
|
|
60
|
+
// specification declares — because that is how the edge itself is written
|
|
61
|
+
// and an author copies the edge line. The split used to stop at the first
|
|
62
|
+
// `->`, the one AFTER the `]`, so the bracket form became `a -[async]` ->
|
|
63
|
+
// `b`, and the dotted form, with no `->` at all, fell through to an element
|
|
64
|
+
// entry: both were `covers.unknown` while the kind-less spelling of the same
|
|
65
|
+
// edge resolved. The kind is read past, not compared: loam identifies an
|
|
66
|
+
// edge by its two endpoints (`flattenModel` keeps no kind), so either kinded
|
|
67
|
+
// spelling covers exactly what `a -> b` covers. The dotted form needs no
|
|
68
|
+
// specification to tell it from an element id: an id never holds a space,
|
|
69
|
+
// so `<id> .<kind> <id>` can be nothing else.
|
|
70
|
+
const edge = /^(.+?)\s*(?:-\[[^\]]*\])?->\s*(.+)$/.exec(raw) ?? /^(\S+)\s+\.[A-Za-z_][\w-]*\s+(\S+)$/.exec(raw);
|
|
71
|
+
if (edge) {
|
|
72
|
+
const source = edge[1].trim();
|
|
73
|
+
const target = edge[2].trim();
|
|
74
|
+
const from = nodeId(source);
|
|
75
|
+
const to = nodeId(target);
|
|
76
|
+
// BOTH sides, or neither. A mixed entry stays an ordinary edge whose
|
|
77
|
+
// prefixed side then resolves to nothing — which is the honest answer:
|
|
78
|
+
// there is no edge in any model with one endpoint in the logical map and
|
|
79
|
+
// one in the deployment map, so accepting a half-prefixed line would be
|
|
80
|
+
// inventing a join rather than reading one. The `->` split runs FIRST for
|
|
81
|
+
// the same reason the alert/sli tests do: `node:a -> node:b` read as a
|
|
82
|
+
// single id would be one entry that can never resolve.
|
|
83
|
+
if (from !== undefined && to !== undefined)
|
|
84
|
+
return { form: "node-edge", source: from, target: to, raw };
|
|
85
|
+
return { form: "edge", source, target, raw };
|
|
86
|
+
}
|
|
87
|
+
const node = nodeId(raw);
|
|
88
|
+
if (node !== undefined)
|
|
89
|
+
return { form: "node", id: node, raw };
|
|
90
|
+
return { form: "element", id: raw, raw };
|
|
91
|
+
}
|
|
92
|
+
/** The id behind a `node:` prefix, or nothing when the entry does not carry one. */
|
|
93
|
+
function nodeId(text) {
|
|
94
|
+
const m = /^node:\s*(.+)$/.exec(text);
|
|
95
|
+
return m === null ? undefined : m[1].trim();
|
|
96
|
+
}
|
|
97
|
+
/** Does an element entry name this element? Its id, or the service it stands for. */
|
|
98
|
+
function namesElement(name, e) {
|
|
99
|
+
return e.id === name || elementService(e) === name;
|
|
100
|
+
}
|
|
101
|
+
/** Does an edge entry's side name this relationship endpoint? */
|
|
102
|
+
function namesEndpoint(name, endpointId, elements, known) {
|
|
103
|
+
return endpointId === name || resolverFor(elements, known)(endpointId) === name;
|
|
104
|
+
}
|
|
105
|
+
/** Does a Covers entry match this element? (Only element entries can.) */
|
|
106
|
+
export function coversElement(entry, e) {
|
|
107
|
+
return entry.form === "element" && namesElement(entry.id, e);
|
|
108
|
+
}
|
|
109
|
+
/** Does a Covers entry match this relationship? Endpoints resolved within `elements`, through `known` where the caller has the fleet. */
|
|
110
|
+
export function coversEdge(entry, r, elements, known) {
|
|
111
|
+
return (entry.form === "edge" &&
|
|
112
|
+
namesEndpoint(entry.source, r.source, elements, known) &&
|
|
113
|
+
namesEndpoint(entry.target, r.target, elements, known));
|
|
114
|
+
}
|
|
115
|
+
/** Does a Covers entry name this deployment node or instance? Matched literally — see `entryResolves`. */
|
|
116
|
+
export function coversDeployNode(entry, id) {
|
|
117
|
+
return entry.form === "node" && entry.id === id;
|
|
118
|
+
}
|
|
119
|
+
/** Does a Covers entry name this deployment edge? Both endpoints, literally. */
|
|
120
|
+
export function coversDeployEdge(entry, source, target) {
|
|
121
|
+
return entry.form === "node-edge" && entry.source === source && entry.target === target;
|
|
122
|
+
}
|
|
123
|
+
/** Does the entry resolve to ANYTHING in scope? False is `covers.unknown`. */
|
|
124
|
+
export function entryResolves(entry, scope) {
|
|
125
|
+
switch (entry.form) {
|
|
126
|
+
case "alert":
|
|
127
|
+
return scope.health.alerts.includes(entry.id);
|
|
128
|
+
case "sli":
|
|
129
|
+
return scope.health.slis.includes(entry.id);
|
|
130
|
+
case "edge":
|
|
131
|
+
return scope.relationships.some((r) => coversEdge(entry, r, scope.elements, scope.known));
|
|
132
|
+
case "element":
|
|
133
|
+
return scope.elements.some((e) => coversElement(entry, e));
|
|
134
|
+
case "node":
|
|
135
|
+
return deployedIds(scope).includes(entry.id);
|
|
136
|
+
case "node-edge":
|
|
137
|
+
// Endpoints matched literally, and only literally. The logical forms
|
|
138
|
+
// resolve a name through `serviceResolver` because an author writes
|
|
139
|
+
// `checkout-web -> payment-service` about an edge the model draws between
|
|
140
|
+
// two containers; a deployment id is already the exact path to one place
|
|
141
|
+
// on the map, there is no coarser name for it, and inventing one would
|
|
142
|
+
// make `node:eu.dcA` silently match an edge between two clusters inside
|
|
143
|
+
// it.
|
|
144
|
+
return (scope.deployment?.relationships ?? []).some((r) => r.source === entry.source && r.target === entry.target);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** Every deployment object a `node:` entry may name: the nodes, and the instances in them. */
|
|
148
|
+
function deployedIds(scope) {
|
|
149
|
+
const d = scope.deployment;
|
|
150
|
+
if (d === undefined)
|
|
151
|
+
return [];
|
|
152
|
+
return [...d.nodes.map((n) => n.id), ...d.instances.map((i) => i.id)];
|
|
153
|
+
}
|
|
154
|
+
/** Ids a covers.unknown hint may offer for a mistyped entry — always real ones. */
|
|
155
|
+
export function coversCandidates(entry, scope) {
|
|
156
|
+
switch (entry.form) {
|
|
157
|
+
case "alert":
|
|
158
|
+
return closeIds(entry.id, scope.health.alerts).map((id) => `alert:${id}`);
|
|
159
|
+
case "sli":
|
|
160
|
+
return closeIds(entry.id, scope.health.slis).map((id) => `sli:${id}`);
|
|
161
|
+
case "edge":
|
|
162
|
+
case "node-edge":
|
|
163
|
+
// Cheap on purpose: no pairwise edge fuzzing — the sides are element
|
|
164
|
+
// names, so the element hint is the useful one.
|
|
165
|
+
return [];
|
|
166
|
+
case "element":
|
|
167
|
+
return closeIds(entry.id, [...new Set(scope.elements.map((e) => e.id))]);
|
|
168
|
+
case "node":
|
|
169
|
+
// Offered WITH the prefix, because that is the line the author has to
|
|
170
|
+
// type. A hint spelling an id the grammar would then read as an element
|
|
171
|
+
// entry is a hint that sends the reader round the loop a second time.
|
|
172
|
+
return closeIds(entry.id, [...new Set(deployedIds(scope))]).map((id) => `node:${id}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Existing ids near a misspelling — substring containment either way, else a
|
|
177
|
+
* shared 3-character prefix. Deliberately dumb: no fuzzy library for one hint,
|
|
178
|
+
* and every id offered is real, so the hint can never point at the typo itself.
|
|
179
|
+
* (Moved here from validate.ts once `covers.unknown` became its second user.)
|
|
180
|
+
*/
|
|
181
|
+
export function closeIds(typo, ids) {
|
|
182
|
+
const t = typo.toLowerCase();
|
|
183
|
+
return ids
|
|
184
|
+
.filter((id) => {
|
|
185
|
+
const i = id.toLowerCase();
|
|
186
|
+
return i.includes(t) || t.includes(i) || (t.length >= 3 && i.startsWith(t.slice(0, 3)));
|
|
187
|
+
})
|
|
188
|
+
.slice(0, 5);
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=arch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arch.js","sourceRoot":"","sources":["../../../src/core/c4/arch.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The architecture spec axis — the grammar and resolution of `Covers:` — and\n * the same endpoint join, reused, for the steps of a use case.\n *\n * A business spec will never mention the transactional outbox; that is\n * architecture, and it lives in `arch.spec.md` — same requirement/scenario\n * grammar as spec.md, same delta algebra, same merge. What is new is the\n * `Covers:` line: where a business requirement declares the OPERATIONS it\n * governs, an architecture requirement declares the MODEL OBJECTS its\n * scenarios exercise, so coverage can be derived mechanically instead of\n * trusted to an author who was never going to write the outbox down.\n *\n * Four entry forms, resolved against the documents loam already reads:\n *\n * paymentService.db a C4 element id — resolved against the\n * in-scope elements the way every check joins\n * them: the id itself, or the service the\n * element stands for (binding, then title);\n * paymentService -> kafka an edge — each side resolved the same way,\n * against the declared relationships; the\n * edge may carry the relationship's kind as\n * LikeC4 writes it, `paymentService -[async]->\n * kafka` or `paymentService .async kafka`,\n * which is read past rather than compared;\n * alert:<id> / sli:<id> a health signal — ids `health.yaml`\n * declares (core/vocabulary/health.ts);\n * node:<id>, node:a -> node:b a deployment object — a node or an instance\n * in the landscape's `deployment { }` model,\n * matched literally. This is the form that\n * lets a requirement about replication name\n * the two clusters it is written about\n * (ROADMAP's deployment axis).\n *\n * Resolution never reads code. An entry that resolves to nothing is the typo\n * guard (`covers.unknown`, warn); the emitters live with the other validate\n * checks, this module owns only the grammar and the matching.\n *\n * `attributeStep` used to sit at the foot of this file and now lives in\n * `./resolve/steps.ts`. It answers the same shape of question for a different\n * axis — which declared relationship backs a `dynamic view`'s hop — over the\n * same two tiers and the same cached resolver, and the seam was named here long\n * before the line limit forced it. What the two still share is\n * `./resolve/service.ts`'s `resolverFor`, which is where that cache moved with\n * it: one id→service resolver per document, serving both axes.\n */\nimport { type Elem, type Rel } from \"./likec4.js\";\nimport type { DeploymentModel } from \"./parsed/deployment.js\";\nimport { elementService, resolverFor } from \"./resolve/service.js\";\nimport type { HealthIds } from \"../vocabulary/health.js\";\n\nexport type CoversEntry =\n | { form: \"element\"; id: string; raw: string }\n | { form: \"edge\"; source: string; target: string; raw: string }\n | { form: \"alert\" | \"sli\"; id: string; raw: string }\n /**\n * A deployment object — `node:eu.dcA.k8sA`, and the edge form\n * `node:a -> node:b`. One prefix covers deployment NODES and the INSTANCES\n * inside them, because both are places on the same map and a requirement\n * about replication names an instance as readily as a datacenter. A second\n * prefix for the second kind would make an author pick between two spellings\n * for one question, and pick wrong.\n */\n | { form: \"node\"; id: string; raw: string }\n | { form: \"node-edge\"; source: string; target: string; raw: string };\n\n/** Parse one comma-separated `Covers:` entry into its form. Never fails: an\n * unclassifiable string is an element entry that will not resolve, and the\n * covers.unknown message is a better diagnosis than a parse refusal. */\nexport function parseCoversEntry(raw: string): CoversEntry {\n const alert = /^alert:\\s*(.+)$/.exec(raw);\n if (alert) return { form: \"alert\", id: alert[1]!.trim(), raw };\n const sli = /^sli:\\s*(.+)$/.exec(raw);\n if (sli) return { form: \"sli\", id: sli[1]!.trim(), raw };\n // An edge may be spelled with its relationship kind, the two ways LikeC4\n // writes one — `a -[async]-> b`, and `a .async b` for a kind the\n // specification declares — because that is how the edge itself is written\n // and an author copies the edge line. The split used to stop at the first\n // `->`, the one AFTER the `]`, so the bracket form became `a -[async]` ->\n // `b`, and the dotted form, with no `->` at all, fell through to an element\n // entry: both were `covers.unknown` while the kind-less spelling of the same\n // edge resolved. The kind is read past, not compared: loam identifies an\n // edge by its two endpoints (`flattenModel` keeps no kind), so either kinded\n // spelling covers exactly what `a -> b` covers. The dotted form needs no\n // specification to tell it from an element id: an id never holds a space,\n // so `<id> .<kind> <id>` can be nothing else.\n const edge =\n /^(.+?)\\s*(?:-\\[[^\\]]*\\])?->\\s*(.+)$/.exec(raw) ?? /^(\\S+)\\s+\\.[A-Za-z_][\\w-]*\\s+(\\S+)$/.exec(raw);\n if (edge) {\n const source = edge[1]!.trim();\n const target = edge[2]!.trim();\n const from = nodeId(source);\n const to = nodeId(target);\n // BOTH sides, or neither. A mixed entry stays an ordinary edge whose\n // prefixed side then resolves to nothing — which is the honest answer:\n // there is no edge in any model with one endpoint in the logical map and\n // one in the deployment map, so accepting a half-prefixed line would be\n // inventing a join rather than reading one. The `->` split runs FIRST for\n // the same reason the alert/sli tests do: `node:a -> node:b` read as a\n // single id would be one entry that can never resolve.\n if (from !== undefined && to !== undefined) return { form: \"node-edge\", source: from, target: to, raw };\n return { form: \"edge\", source, target, raw };\n }\n const node = nodeId(raw);\n if (node !== undefined) return { form: \"node\", id: node, raw };\n return { form: \"element\", id: raw, raw };\n}\n\n/** The id behind a `node:` prefix, or nothing when the entry does not carry one. */\nfunction nodeId(text: string): string | undefined {\n const m = /^node:\\s*(.+)$/.exec(text);\n return m === null ? undefined : m[1]!.trim();\n}\n\n/**\n * What `Covers:` entries resolve against: every element and relationship in\n * view (a service's own model plus the landscape; for a feature, the delta\n * plus both), and the health ids of the service whose spec is being read.\n */\nexport interface CoverageScope {\n elements: Elem[];\n relationships: Rel[];\n /**\n * The fleet's topology, for the `node:` forms — the LANDSCAPE's deployment\n * model and no other, even though a service's own `model.likec4` may legally\n * declare one. Topology is a fleet-level fact for the reason a cross-service\n * flow is: `architecture/` is the one place that already holds every edge\n * crossing two services, and a per-service deployment block would let two\n * documents disagree about where one container runs with nothing able to say\n * which is right. Absent for every fleet that draws none, which is what makes\n * a `node:` entry there resolve to nothing and report the typo.\n */\n deployment?: DeploymentModel;\n health: HealthIds;\n /**\n * The enumerated fleet (plus the feature's own `specs/` names, where the\n * caller has them). The Covers matcher resolves edge ENDPOINTS with it, and\n * it must be the SAME set the caller's own findings resolve with: the finding\n * says \"write `Covers: checkout-web -> payment-service`\" with the fleet in\n * hand, and a matcher resolving without it answered that exact line with\n * `covers.unknown` whenever the edge landed on a modelled container.\n */\n known?: ReadonlySet<string>;\n}\n\n/** Does an element entry name this element? Its id, or the service it stands for. */\nfunction namesElement(name: string, e: Elem): boolean {\n return e.id === name || elementService(e) === name;\n}\n\n/** Does an edge entry's side name this relationship endpoint? */\nfunction namesEndpoint(\n name: string,\n endpointId: string,\n elements: Elem[],\n known?: ReadonlySet<string>,\n): boolean {\n return endpointId === name || resolverFor(elements, known)(endpointId) === name;\n}\n\n/** Does a Covers entry match this element? (Only element entries can.) */\nexport function coversElement(entry: CoversEntry, e: Elem): boolean {\n return entry.form === \"element\" && namesElement(entry.id, e);\n}\n\n/** Does a Covers entry match this relationship? Endpoints resolved within `elements`, through `known` where the caller has the fleet. */\nexport function coversEdge(entry: CoversEntry, r: Rel, elements: Elem[], known?: ReadonlySet<string>): boolean {\n return (\n entry.form === \"edge\" &&\n namesEndpoint(entry.source, r.source, elements, known) &&\n namesEndpoint(entry.target, r.target, elements, known)\n );\n}\n\n/** Does a Covers entry name this deployment node or instance? Matched literally — see `entryResolves`. */\nexport function coversDeployNode(entry: CoversEntry, id: string): boolean {\n return entry.form === \"node\" && entry.id === id;\n}\n\n/** Does a Covers entry name this deployment edge? Both endpoints, literally. */\nexport function coversDeployEdge(entry: CoversEntry, source: string, target: string): boolean {\n return entry.form === \"node-edge\" && entry.source === source && entry.target === target;\n}\n\n/** Does the entry resolve to ANYTHING in scope? False is `covers.unknown`. */\nexport function entryResolves(entry: CoversEntry, scope: CoverageScope): boolean {\n switch (entry.form) {\n case \"alert\":\n return scope.health.alerts.includes(entry.id);\n case \"sli\":\n return scope.health.slis.includes(entry.id);\n case \"edge\":\n return scope.relationships.some((r) => coversEdge(entry, r, scope.elements, scope.known));\n case \"element\":\n return scope.elements.some((e) => coversElement(entry, e));\n case \"node\":\n return deployedIds(scope).includes(entry.id);\n case \"node-edge\":\n // Endpoints matched literally, and only literally. The logical forms\n // resolve a name through `serviceResolver` because an author writes\n // `checkout-web -> payment-service` about an edge the model draws between\n // two containers; a deployment id is already the exact path to one place\n // on the map, there is no coarser name for it, and inventing one would\n // make `node:eu.dcA` silently match an edge between two clusters inside\n // it.\n return (scope.deployment?.relationships ?? []).some(\n (r) => r.source === entry.source && r.target === entry.target,\n );\n }\n}\n\n/** Every deployment object a `node:` entry may name: the nodes, and the instances in them. */\nfunction deployedIds(scope: CoverageScope): string[] {\n const d = scope.deployment;\n if (d === undefined) return [];\n return [...d.nodes.map((n) => n.id), ...d.instances.map((i) => i.id)];\n}\n\n/** Ids a covers.unknown hint may offer for a mistyped entry — always real ones. */\nexport function coversCandidates(entry: CoversEntry, scope: CoverageScope): string[] {\n switch (entry.form) {\n case \"alert\":\n return closeIds(entry.id, scope.health.alerts).map((id) => `alert:${id}`);\n case \"sli\":\n return closeIds(entry.id, scope.health.slis).map((id) => `sli:${id}`);\n case \"edge\":\n case \"node-edge\":\n // Cheap on purpose: no pairwise edge fuzzing — the sides are element\n // names, so the element hint is the useful one.\n return [];\n case \"element\":\n return closeIds(entry.id, [...new Set(scope.elements.map((e) => e.id))]);\n case \"node\":\n // Offered WITH the prefix, because that is the line the author has to\n // type. A hint spelling an id the grammar would then read as an element\n // entry is a hint that sends the reader round the loop a second time.\n return closeIds(entry.id, [...new Set(deployedIds(scope))]).map((id) => `node:${id}`);\n }\n}\n\n/**\n * Existing ids near a misspelling — substring containment either way, else a\n * shared 3-character prefix. Deliberately dumb: no fuzzy library for one hint,\n * and every id offered is real, so the hint can never point at the typo itself.\n * (Moved here from validate.ts once `covers.unknown` became its second user.)\n */\nexport function closeIds(typo: string, ids: readonly string[]): string[] {\n const t = typo.toLowerCase();\n return ids\n .filter((id) => {\n const i = id.toLowerCase();\n return i.includes(t) || t.includes(i) || (t.length >= 3 && i.startsWith(t.slice(0, 3)));\n })\n .slice(0, 5);\n}\n\n"]}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How loam reads which way a relationship points: which end each event key
|
|
3
|
+
* binds, and which endpoints are infrastructure, whose direction carries no
|
|
4
|
+
* meaning. SCHEMA.md's "Which way an edge points" lists every reader; the two
|
|
5
|
+
* rules here are the ones more than one reader shares.
|
|
6
|
+
*
|
|
7
|
+
* `metadata { publishes }` binds the edge's SOURCE: a service produces what its
|
|
8
|
+
* own asyncapi.yaml declares an `action: send` for. `metadata { consumes }`
|
|
9
|
+
* binds its TARGET. THE ARROW FOLLOWS THE MESSAGE, producer to topic and topic
|
|
10
|
+
* to consumer, and the event spine is not the only reader of that arrow: review
|
|
11
|
+
* order's fan-in (`core/dependencies/fanin.ts`) and a use case's hop backing
|
|
12
|
+
* read the same drawing. That is why a key on the wrong end is REPORTED rather
|
|
13
|
+
* than re-bound to whichever end happens to be a service. Re-binding a reversed
|
|
14
|
+
* consume edge to its source would make the spine agree with a drawing every
|
|
15
|
+
* other reader still takes the opposite way, and on an edge between two fleet
|
|
16
|
+
* services nothing can tell which end the author meant.
|
|
17
|
+
*
|
|
18
|
+
* Through 0.2.0-alpha.10 a key on the wrong end was skipped without a word, at
|
|
19
|
+
* service scope and feature scope alike. The document validated, the metadata
|
|
20
|
+
* parsed, and the spine graded one link fewer; the `event.covered` count was
|
|
21
|
+
* the only trace. `spine.message-unbound` names that silence. Both scopes read
|
|
22
|
+
* the binding from `eventKeys` below, so the rule is written down once.
|
|
23
|
+
*
|
|
24
|
+
* It is a question about the resolved model (which endpoint of an edge a key
|
|
25
|
+
* belongs to, and what kind of thing that endpoint is), which is why it sat in
|
|
26
|
+
* `../resolve/` beside `external.ts` until that package reached six files. It
|
|
27
|
+
* was the one module there that resolves no service itself: the caller's
|
|
28
|
+
* `serviceResolver` (`../resolve/service.ts`) is what turns an endpoint into a
|
|
29
|
+
* service, so the edge reading stands as a package of its own.
|
|
30
|
+
*/
|
|
31
|
+
import { ancestorIds } from "../../kernel/ids/fqn/ancestors.js";
|
|
32
|
+
import { INFRA_KINDS } from "../../vocabulary/maturity.js";
|
|
33
|
+
import {} from "../likec4.js";
|
|
34
|
+
/**
|
|
35
|
+
* Every event key a relationship carries, each with the endpoint it binds. One
|
|
36
|
+
* edge may carry both keys: a producer drawn straight to its consumer, with no
|
|
37
|
+
* broker on the map, publishes from its source and is consumed at its target.
|
|
38
|
+
*/
|
|
39
|
+
export function eventKeys(r) {
|
|
40
|
+
const keys = [];
|
|
41
|
+
if (r.publishes !== undefined)
|
|
42
|
+
keys.push({ direction: "publishes", message: r.publishes, bound: r.source, other: r.target });
|
|
43
|
+
if (r.consumes !== undefined)
|
|
44
|
+
keys.push({ direction: "consumes", message: r.consumes, bound: r.target, other: r.source });
|
|
45
|
+
return keys;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The infrastructure kind an endpoint belongs to — its own, or the nearest
|
|
49
|
+
* ancestor's among `INFRA_KINDS` — or undefined for any other element. A table
|
|
50
|
+
* nested in a `database` is part of the database, so the ancestors count.
|
|
51
|
+
*
|
|
52
|
+
* Infrastructure never initiates and never decides anything: a database, a
|
|
53
|
+
* topic or a bucket neither calls nor publishes nor consumes. That one fact
|
|
54
|
+
* answers two readers. The consumer census reads an edge between a service and
|
|
55
|
+
* infrastructure as the service USING it, whichever way the arrow points. And
|
|
56
|
+
* an event key bound to infrastructure is a key on the wrong end of its edge,
|
|
57
|
+
* since a topic is the thing between a producer and a consumer and never
|
|
58
|
+
* either of them.
|
|
59
|
+
*
|
|
60
|
+
* The limitation is `INFRA_KINDS`'s own: the hook is a kind NAME, so a broker
|
|
61
|
+
* drawn as a plain `softwareSystem` is not infrastructure here, exactly as it
|
|
62
|
+
* is not for `landscape.service-undocumented`. Callers pass the elements that
|
|
63
|
+
* may count. The census leaves out an element that stands for a service, which
|
|
64
|
+
* is a service whatever its kind.
|
|
65
|
+
*/
|
|
66
|
+
export function infrastructureKind(elements) {
|
|
67
|
+
const kinds = new Map();
|
|
68
|
+
for (const e of elements) {
|
|
69
|
+
const kind = e.kind.toLowerCase();
|
|
70
|
+
if (INFRA_KINDS.has(kind))
|
|
71
|
+
kinds.set(e.id, kind);
|
|
72
|
+
}
|
|
73
|
+
return (id) => {
|
|
74
|
+
for (const a of ancestorIds(id)) {
|
|
75
|
+
const kind = kinds.get(a);
|
|
76
|
+
if (kind !== undefined)
|
|
77
|
+
return kind;
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Why a key binds nothing and how the edge is drawn so it does. A caller raises
|
|
84
|
+
* it only when the bound end is infrastructure (`infrastructureKind`) and the
|
|
85
|
+
* other end is a service of the fleet. Both halves of that test matter, and the
|
|
86
|
+
* first is deliberately narrower than "the bound end is no service". An
|
|
87
|
+
* `#external` system at the bound end is a party outside the fleet, and a key
|
|
88
|
+
* there says something true: `crm -> billingService` carrying `publishes` is an
|
|
89
|
+
* outside producer, which the producer question accepts
|
|
90
|
+
* (`./external.ts`, `spine.message-external`), and a `consumes` on an outside
|
|
91
|
+
* system is an outside consumer. Turning either round would be wrong. An edge
|
|
92
|
+
* whose bound end IS a service is graded against that service's contract, so a
|
|
93
|
+
* wrong drawing there already surfaces as `spine.message-undefined`.
|
|
94
|
+
*
|
|
95
|
+
* The fix is the same reversal for both keys: `consumes` wants the consumer at
|
|
96
|
+
* the target and `publishes` wants the producer at the source, so the edge as
|
|
97
|
+
* it should be drawn is the drawn edge turned round. Unless the edge carries
|
|
98
|
+
* BOTH keys: a service that publishes one message to a topic and consumes
|
|
99
|
+
* another from it, drawn as one arrow, always has one key on the topic, so
|
|
100
|
+
* turning the arrow round only moves the warning to the other key. The key at
|
|
101
|
+
* fault then goes onto an edge of its own, and the sentence says so.
|
|
102
|
+
*/
|
|
103
|
+
export function unboundSentence(r, key, kind) {
|
|
104
|
+
const end = key.direction === "publishes" ? "SOURCE" : "TARGET";
|
|
105
|
+
const both = r.publishes !== undefined && r.consumes !== undefined;
|
|
106
|
+
const fix = both
|
|
107
|
+
? `the edge carries both keys, so one arrow cannot serve them: move ${key.direction} '${key.message}' onto an ` +
|
|
108
|
+
`edge of its own, ${r.target} -> ${r.source}`
|
|
109
|
+
: `draw it ${r.target} -> ${r.source}`;
|
|
110
|
+
return (`edge ${r.source} -> ${r.target} carries ${key.direction} '${key.message}', but \`${key.direction}\` binds the ` +
|
|
111
|
+
`edge's ${end}, and ${key.bound} is a ${kind}, which neither publishes nor consumes. The key binds nothing, so ` +
|
|
112
|
+
`no contract is checked against it. The arrow follows the message (producer to topic, topic to consumer): ${fix}`);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=direction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direction.js","sourceRoot":"","sources":["../../../../src/core/c4/direction/direction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAuB,MAAM,cAAc,CAAC;AAYnD;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,CAAM;IAC9B,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7H,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1H,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAyB;IAC1D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAClC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,CAAC,EAAU,EAAsB,EAAE;QACxC,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;QACtC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,eAAe,CAAC,CAAM,EAAE,GAAa,EAAE,IAAY;IACjE,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IAChE,MAAM,IAAI,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC;IACnE,MAAM,GAAG,GAAG,IAAI;QACd,CAAC,CAAC,oEAAoE,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,OAAO,YAAY;YAC7G,oBAAoB,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE;QAC/C,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;IACzC,OAAO,CACL,QAAQ,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,MAAM,YAAY,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,OAAO,YAAY,GAAG,CAAC,SAAS,eAAe;QAChH,UAAU,GAAG,SAAS,GAAG,CAAC,KAAK,SAAS,IAAI,oEAAoE;QAChH,4GAA4G,GAAG,EAAE,CAClH,CAAC;AACJ,CAAC","sourcesContent":["/**\n * How loam reads which way a relationship points: which end each event key\n * binds, and which endpoints are infrastructure, whose direction carries no\n * meaning. SCHEMA.md's \"Which way an edge points\" lists every reader; the two\n * rules here are the ones more than one reader shares.\n *\n * `metadata { publishes }` binds the edge's SOURCE: a service produces what its\n * own asyncapi.yaml declares an `action: send` for. `metadata { consumes }`\n * binds its TARGET. THE ARROW FOLLOWS THE MESSAGE, producer to topic and topic\n * to consumer, and the event spine is not the only reader of that arrow: review\n * order's fan-in (`core/dependencies/fanin.ts`) and a use case's hop backing\n * read the same drawing. That is why a key on the wrong end is REPORTED rather\n * than re-bound to whichever end happens to be a service. Re-binding a reversed\n * consume edge to its source would make the spine agree with a drawing every\n * other reader still takes the opposite way, and on an edge between two fleet\n * services nothing can tell which end the author meant.\n *\n * Through 0.2.0-alpha.10 a key on the wrong end was skipped without a word, at\n * service scope and feature scope alike. The document validated, the metadata\n * parsed, and the spine graded one link fewer; the `event.covered` count was\n * the only trace. `spine.message-unbound` names that silence. Both scopes read\n * the binding from `eventKeys` below, so the rule is written down once.\n *\n * It is a question about the resolved model (which endpoint of an edge a key\n * belongs to, and what kind of thing that endpoint is), which is why it sat in\n * `../resolve/` beside `external.ts` until that package reached six files. It\n * was the one module there that resolves no service itself: the caller's\n * `serviceResolver` (`../resolve/service.ts`) is what turns an endpoint into a\n * service, so the edge reading stands as a package of its own.\n */\nimport { ancestorIds } from \"../../kernel/ids/fqn/ancestors.js\";\nimport { INFRA_KINDS } from \"../../vocabulary/maturity.js\";\nimport { type Elem, type Rel } from \"../likec4.js\";\n\n/** One event key on one edge, with the endpoint it binds and the one it does not. */\nexport interface EventKey {\n direction: \"publishes\" | \"consumes\";\n message: string;\n /** The endpoint the key binds: the source for `publishes`, the target for `consumes`. */\n bound: string;\n /** The other endpoint. */\n other: string;\n}\n\n/**\n * Every event key a relationship carries, each with the endpoint it binds. One\n * edge may carry both keys: a producer drawn straight to its consumer, with no\n * broker on the map, publishes from its source and is consumed at its target.\n */\nexport function eventKeys(r: Rel): EventKey[] {\n const keys: EventKey[] = [];\n if (r.publishes !== undefined) keys.push({ direction: \"publishes\", message: r.publishes, bound: r.source, other: r.target });\n if (r.consumes !== undefined) keys.push({ direction: \"consumes\", message: r.consumes, bound: r.target, other: r.source });\n return keys;\n}\n\n/**\n * The infrastructure kind an endpoint belongs to — its own, or the nearest\n * ancestor's among `INFRA_KINDS` — or undefined for any other element. A table\n * nested in a `database` is part of the database, so the ancestors count.\n *\n * Infrastructure never initiates and never decides anything: a database, a\n * topic or a bucket neither calls nor publishes nor consumes. That one fact\n * answers two readers. The consumer census reads an edge between a service and\n * infrastructure as the service USING it, whichever way the arrow points. And\n * an event key bound to infrastructure is a key on the wrong end of its edge,\n * since a topic is the thing between a producer and a consumer and never\n * either of them.\n *\n * The limitation is `INFRA_KINDS`'s own: the hook is a kind NAME, so a broker\n * drawn as a plain `softwareSystem` is not infrastructure here, exactly as it\n * is not for `landscape.service-undocumented`. Callers pass the elements that\n * may count. The census leaves out an element that stands for a service, which\n * is a service whatever its kind.\n */\nexport function infrastructureKind(elements: readonly Elem[]): (id: string) => string | undefined {\n const kinds = new Map<string, string>();\n for (const e of elements) {\n const kind = e.kind.toLowerCase();\n if (INFRA_KINDS.has(kind)) kinds.set(e.id, kind);\n }\n return (id: string): string | undefined => {\n for (const a of ancestorIds(id)) {\n const kind = kinds.get(a);\n if (kind !== undefined) return kind;\n }\n return undefined;\n };\n}\n\n/**\n * Why a key binds nothing and how the edge is drawn so it does. A caller raises\n * it only when the bound end is infrastructure (`infrastructureKind`) and the\n * other end is a service of the fleet. Both halves of that test matter, and the\n * first is deliberately narrower than \"the bound end is no service\". An\n * `#external` system at the bound end is a party outside the fleet, and a key\n * there says something true: `crm -> billingService` carrying `publishes` is an\n * outside producer, which the producer question accepts\n * (`./external.ts`, `spine.message-external`), and a `consumes` on an outside\n * system is an outside consumer. Turning either round would be wrong. An edge\n * whose bound end IS a service is graded against that service's contract, so a\n * wrong drawing there already surfaces as `spine.message-undefined`.\n *\n * The fix is the same reversal for both keys: `consumes` wants the consumer at\n * the target and `publishes` wants the producer at the source, so the edge as\n * it should be drawn is the drawn edge turned round. Unless the edge carries\n * BOTH keys: a service that publishes one message to a topic and consumes\n * another from it, drawn as one arrow, always has one key on the topic, so\n * turning the arrow round only moves the warning to the other key. The key at\n * fault then goes onto an edge of its own, and the sentence says so.\n */\nexport function unboundSentence(r: Rel, key: EventKey, kind: string): string {\n const end = key.direction === \"publishes\" ? \"SOURCE\" : \"TARGET\";\n const both = r.publishes !== undefined && r.consumes !== undefined;\n const fix = both\n ? `the edge carries both keys, so one arrow cannot serve them: move ${key.direction} '${key.message}' onto an ` +\n `edge of its own, ${r.target} -> ${r.source}`\n : `draw it ${r.target} -> ${r.source}`;\n return (\n `edge ${r.source} -> ${r.target} carries ${key.direction} '${key.message}', but \\`${key.direction}\\` binds the ` +\n `edge's ${end}, and ${key.bound} is a ${kind}, which neither publishes nor consumes. The key binds nothing, so ` +\n `no contract is checked against it. The arrow follows the message (producer to topic, topic to consumer): ${fix}`\n );\n}\n"]}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { relative } from "node:path";
|
|
3
|
+
import { LikeC4 } from "likec4";
|
|
4
|
+
import { declaredService } from "../kernel/ids/service.js";
|
|
5
|
+
import { readDynamicViews } from "./parsed/dynamic-views.js";
|
|
6
|
+
import { readGlobalStyleIds, readViewIds } from "./parsed/view-ids.js";
|
|
7
|
+
import { readSpecification } from "./parsed/specification.js";
|
|
8
|
+
import { readDeployment } from "./parsed/deployment.js";
|
|
9
|
+
import { compareRels, descText, metaKey } from "./parsed/values.js";
|
|
10
|
+
/**
|
|
11
|
+
* The one spelling of a diagnostic loam prints — `L<n>: <message>`, with the
|
|
12
|
+
* line 1-BASED: the number an editor's gutter shows, so an agent told to open
|
|
13
|
+
* it opens the line the fault is on. LikeC4's `getErrors()` copies the LSP
|
|
14
|
+
* range's start line, which counts from 0, and every message used to print that
|
|
15
|
+
* raw number: the named line landed one above the fault every time
|
|
16
|
+
* (verification 2026-09-04, W6).
|
|
17
|
+
*
|
|
18
|
+
* `likec4 validate` DOES NOT AGREE, and that is deliberate rather than
|
|
19
|
+
* unnoticed. Measured at the 1.59.2 pin on a document whose fault is on file
|
|
20
|
+
* line 10: the CLI prints `Line 9:` and loam prints `L10:` for the same
|
|
21
|
+
* diagnostic — it renders the LSP index raw. Copying that would make loam's
|
|
22
|
+
* output wrong in the way the fix above repaired, so the two spellings differ
|
|
23
|
+
* by exactly one and a reader comparing them should expect it.
|
|
24
|
+
*
|
|
25
|
+
* Four modules used to hand-roll this ternary; they all read this one now, so
|
|
26
|
+
* the base cannot drift between them again.
|
|
27
|
+
*
|
|
28
|
+
* The message itself is BOUNDED here too, and for the same reason it lives in
|
|
29
|
+
* one place: every surface that prints a LikeC4 diagnostic — validate, context,
|
|
30
|
+
* show, tasks, doctor, gate, archive — prints it through this function, so this
|
|
31
|
+
* is the one spelling that can keep all of them small. See `boundedMessage`.
|
|
32
|
+
*/
|
|
33
|
+
export function errorText(e) {
|
|
34
|
+
const message = boundedMessage(e.message);
|
|
35
|
+
return typeof e.line === "number" ? `L${e.line + 1}: ${message}` : message;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The documents a project's diagnostics name, docs-relative POSIX, deduped and
|
|
39
|
+
* sorted — the one spelling of "which files broke" behind `landscape.invalid`,
|
|
40
|
+
* `spine.landscape-invalid`, the brief's unparseable arm, the work packet and
|
|
41
|
+
* `loam explore`. Those surfaces are read one after another on the same tree,
|
|
42
|
+
* and an agent has to be able to tell that they name the same file. Given ONE
|
|
43
|
+
* error it spells that error's document: validate's detail-line prefix.
|
|
44
|
+
*/
|
|
45
|
+
export function brokenDocumentPaths(docsDir, errors) {
|
|
46
|
+
return [...new Set(errors.map((e) => e.sourceFsPath).filter((p) => p !== undefined))]
|
|
47
|
+
.map((abs) => relative(docsDir, abs).split(/[\\/]/).join("/"))
|
|
48
|
+
.sort();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* How many alternatives of a parser's "one of these possible Token sequences"
|
|
52
|
+
* list a printed diagnostic keeps — the number `likec4 validate` itself prints
|
|
53
|
+
* before its `...`.
|
|
54
|
+
*/
|
|
55
|
+
const TOKEN_ALTERNATIVES = 4;
|
|
56
|
+
/** The heading line of Chevrotain's no-viable-alternative message, whose numbered list follows it. */
|
|
57
|
+
const TOKEN_SEQUENCES = /possible Token sequences:$/;
|
|
58
|
+
/** One numbered alternative in that list: ` 12. [IdTerminal, Dot]`. */
|
|
59
|
+
const ALTERNATIVE = /^\s+\d+\. /;
|
|
60
|
+
/**
|
|
61
|
+
* A LikeC4 message, with Chevrotain's list of expected token sequences cut to
|
|
62
|
+
* its first few alternatives and a count of the rest.
|
|
63
|
+
*
|
|
64
|
+
* When the parser meets a token no rule can take, Chevrotain lists EVERY token
|
|
65
|
+
* sequence any rule could have accepted there — and inside a LikeC4 `model { }`
|
|
66
|
+
* block that is the whole grammar. Measured at the 1.59.2 pin: deleting the
|
|
67
|
+
* closing quote of one `technology '…'` makes three such messages of about
|
|
68
|
+
* 6,160 lines each, and `loam validate --service` printed 18,503 lines
|
|
69
|
+
* (434 KB; 458 KB as `--json`) for one keystroke. `capDetails` bounds how MANY
|
|
70
|
+
* details a finding prints, never how big one is, and `loam context` has no cap
|
|
71
|
+
* at all — so a broken feature delta turned a 24 KB briefing into 626 KB for
|
|
72
|
+
* every agent working on any service the feature touches. An agent in the
|
|
73
|
+
* check-fix loop gets nothing from alternative 4,000: what it acts on is the
|
|
74
|
+
* line number and the `but found: '…'` line, which is kept.
|
|
75
|
+
*
|
|
76
|
+
* Upstream `likec4 validate` keeps the first five lines of any message and
|
|
77
|
+
* prints `...`; this cuts the LIST only, so the `but found:` line after it
|
|
78
|
+
* survives, and says how many alternatives were dropped so nothing reads as
|
|
79
|
+
* complete when it is not (the convention `capDetails` uses). Any other
|
|
80
|
+
* message is returned exactly as LikeC4 wrote it.
|
|
81
|
+
*/
|
|
82
|
+
function boundedMessage(message) {
|
|
83
|
+
const lines = message.split("\n");
|
|
84
|
+
if (!TOKEN_SEQUENCES.test(lines[0] ?? ""))
|
|
85
|
+
return message;
|
|
86
|
+
const alternatives = lines.filter((line) => ALTERNATIVE.test(line)).length;
|
|
87
|
+
if (alternatives <= TOKEN_ALTERNATIVES)
|
|
88
|
+
return message;
|
|
89
|
+
const kept = [];
|
|
90
|
+
let seen = 0;
|
|
91
|
+
for (const line of lines) {
|
|
92
|
+
if (!ALTERNATIVE.test(line))
|
|
93
|
+
kept.push(line);
|
|
94
|
+
else if (++seen <= TOKEN_ALTERNATIVES)
|
|
95
|
+
kept.push(line);
|
|
96
|
+
else if (seen === TOKEN_ALTERNATIVES + 1)
|
|
97
|
+
kept.push(` … (+${alternatives - TOKEN_ALTERNATIVES} more)`);
|
|
98
|
+
}
|
|
99
|
+
return kept.join("\n");
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Diagnostics as loam keeps them: each one ONCE, in line order.
|
|
103
|
+
*
|
|
104
|
+
* LikeC4 can report one fault more than once: measured at the 1.59.2 pin, one
|
|
105
|
+
* dropped quote in a service model came back as two byte-identical messages at
|
|
106
|
+
* the same line — each of them the full token list `boundedMessage` cuts — and
|
|
107
|
+
* every `details` list printed both. The same message at the same line of the
|
|
108
|
+
* same file is one fault; the identity includes the file because LikeC4 blames
|
|
109
|
+
* a duplicate declaration on BOTH documents of a project, and those are two
|
|
110
|
+
* lines an author has to look at.
|
|
111
|
+
*
|
|
112
|
+
* In line order because LikeC4 hands its lexer's errors over before its
|
|
113
|
+
* parser's: the first location printed for that dropped quote was an
|
|
114
|
+
* "unexpected character" twelve lines BELOW it, where the runaway string ended,
|
|
115
|
+
* while the parser's errors two lines below it came after. The sort is stable,
|
|
116
|
+
* so diagnostics on one line keep LikeC4's order, and a list mixing documents
|
|
117
|
+
* stays in line order within each of them — every loader groups by document
|
|
118
|
+
* after this, which is why sorting by line alone is enough. A diagnostic with
|
|
119
|
+
* no line is about the document as a whole and leads.
|
|
120
|
+
*
|
|
121
|
+
* Applied where `getErrors()` is read (`loadSource`, `./workspace.ts`,
|
|
122
|
+
* `./project/load.ts`), so every loader hands every reader the same list and
|
|
123
|
+
* test/likec4-batch-parity.test.ts can keep asserting the two modes equal.
|
|
124
|
+
*/
|
|
125
|
+
export function distinctErrors(errors) {
|
|
126
|
+
const seen = new Set();
|
|
127
|
+
return errors
|
|
128
|
+
.filter((e) => {
|
|
129
|
+
const key = `${e.sourceFsPath ?? ""}\0${e.line ?? ""}\0${e.message}`;
|
|
130
|
+
if (seen.has(key))
|
|
131
|
+
return false;
|
|
132
|
+
seen.add(key);
|
|
133
|
+
return true;
|
|
134
|
+
})
|
|
135
|
+
.sort((a, b) => (a.line ?? -1) - (b.line ?? -1));
|
|
136
|
+
}
|
|
137
|
+
/** Flatten a LikeC4 model into loam's neutral `Elem`/`Rel` view. */
|
|
138
|
+
export function flattenModel(model) {
|
|
139
|
+
const elements = [...model.elements()].map((e) => {
|
|
140
|
+
// The one crossing between LikeC4's parse output and loam's type system:
|
|
141
|
+
// a `metadata { service '...' }` binding is text somebody wrote, and this
|
|
142
|
+
// is where it acquires a type that says so.
|
|
143
|
+
const bound = metaKey(e.metadata, "service");
|
|
144
|
+
return {
|
|
145
|
+
id: e.id,
|
|
146
|
+
kind: e.kind,
|
|
147
|
+
title: e.title,
|
|
148
|
+
description: descText(e.description),
|
|
149
|
+
...(bound === undefined ? {} : { service: declaredService(bound) }),
|
|
150
|
+
tags: [...(e.tags ?? [])],
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
const relationships = [...model.relationships()]
|
|
154
|
+
.map((r) => ({
|
|
155
|
+
source: r.source.id,
|
|
156
|
+
target: r.target.id,
|
|
157
|
+
// LikeC4 reports an untitled edge as title: null — normalize to the declared `title?: string`.
|
|
158
|
+
title: r.title ?? undefined,
|
|
159
|
+
op: metaKey(r.metadata, "op"),
|
|
160
|
+
publishes: metaKey(r.metadata, "publishes"),
|
|
161
|
+
consumes: metaKey(r.metadata, "consumes"),
|
|
162
|
+
tags: [...(r.tags ?? [])],
|
|
163
|
+
}))
|
|
164
|
+
// One order for every run and machine: `compareRels` (./parsed/values.ts) says why LikeC4 gives none.
|
|
165
|
+
.sort(compareRels);
|
|
166
|
+
return { elements, relationships };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Load and validate a single self-contained `.likec4` document, in-process
|
|
170
|
+
* (no external tool, no JVM). Returns validation errors and, if clean, the
|
|
171
|
+
* flattened elements + relationships.
|
|
172
|
+
*/
|
|
173
|
+
export async function loadFile(path) {
|
|
174
|
+
return loadSource(await readFile(path, "utf8"));
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* `loadFile` for text that is not (yet) on disk — what the archive merge uses
|
|
178
|
+
* to prove a computed landscape parses BEFORE anything is written.
|
|
179
|
+
*/
|
|
180
|
+
export async function loadSource(src) {
|
|
181
|
+
// LikeC4 owns a Langium workspace and registers a process-exit listener for
|
|
182
|
+
// it. Validation creates many short-lived instances, so every acquired
|
|
183
|
+
// instance must be disposed even on an invalid document or a failed model
|
|
184
|
+
// computation. Its logger is disabled because diagnostics are returned in
|
|
185
|
+
// LoadedDoc instead of being written out-of-band to stderr.
|
|
186
|
+
const likec4 = await LikeC4.fromSource(src, { logger: false });
|
|
187
|
+
try {
|
|
188
|
+
// Assigned, not cast: LikeC4 declares `getErrors()` as a non-nullable array
|
|
189
|
+
// whose element type is structurally wider than ours, so the compiler can
|
|
190
|
+
// check the shape here. The cast was the only thing standing between a
|
|
191
|
+
// dependency renaming `message` and a build that still succeeded — and the
|
|
192
|
+
// `?? []` it carried could never fire. Through `distinctErrors`, as every
|
|
193
|
+
// loader's diagnostics are, so this one agrees with the batch loader.
|
|
194
|
+
const errors = distinctErrors(likec4.getErrors());
|
|
195
|
+
if (errors.length > 0) {
|
|
196
|
+
return { errors, elements: [], relationships: [] };
|
|
197
|
+
}
|
|
198
|
+
// `parsedModel`, not `computedModel`: the computed stage RESOLVES every
|
|
199
|
+
// view — expanding its predicates against the model and deriving the
|
|
200
|
+
// ancestor edges a diagram needs (and computing a default view when the
|
|
201
|
+
// document declares none). loam reads what a view DECLARES and never what a
|
|
202
|
+
// view SHOWS (docs/DESIGN.md rule 26), so none of that resolution is ever
|
|
203
|
+
// wanted; it renders nothing. That work is superlinear in the number of
|
|
204
|
+
// RELATIONSHIPS, so a landscape at fleet shape turned `loam list` from under
|
|
205
|
+
// a second into minutes. The elements and relationships below are identical
|
|
206
|
+
// either way. The `await` is load-bearing for anything reading `$data`: it is
|
|
207
|
+
// undefined on the unresolved promise.
|
|
208
|
+
return cleanDoc((await likec4.parsedModel()));
|
|
209
|
+
}
|
|
210
|
+
finally {
|
|
211
|
+
await likec4.dispose();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Everything loam reads out of one document that parsed clean, from LikeC4's
|
|
216
|
+
* parsed stage. Shared with `./workspace.ts`'s batch loader, which used to
|
|
217
|
+
* spell the same six reads out again: an adapter wired into one loader and not
|
|
218
|
+
* the other reads as an absence rather than an error, the failure
|
|
219
|
+
* test/likec4-batch-parity.test.ts exists to catch. `./project/load.ts`'s
|
|
220
|
+
* `cleanProjectDoc` wraps the same reads in a project's record, whose error
|
|
221
|
+
* shape differs and which requires the fields `LoadedDoc` leaves optional.
|
|
222
|
+
*/
|
|
223
|
+
export function cleanDoc(model) {
|
|
224
|
+
return { errors: [], ...readParsedModel(model) };
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* The six reads themselves — one spelling under every loader (`cleanDoc`
|
|
228
|
+
* above, `./project/load.ts`'s `cleanProjectDoc`), so the parity test guards
|
|
229
|
+
* one function rather than a convention. The return type is inferred on
|
|
230
|
+
* purpose: it is `LoadedDoc` minus `errors` with every read PRESENT, which is
|
|
231
|
+
* what lets a project's record, whose fields are required, spread it.
|
|
232
|
+
*/
|
|
233
|
+
export function readParsedModel(model) {
|
|
234
|
+
return {
|
|
235
|
+
specification: readSpecification(model.specification),
|
|
236
|
+
views: readDynamicViews(model),
|
|
237
|
+
viewIds: readViewIds(model),
|
|
238
|
+
globalStyles: readGlobalStyleIds(model),
|
|
239
|
+
deployment: readDeployment(model),
|
|
240
|
+
...flattenModel(model),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=likec4.js.map
|