@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,298 @@
|
|
|
1
|
+
import {} from "../likec4.js";
|
|
2
|
+
import { elementService, serviceOf } from "../resolve/service.js";
|
|
3
|
+
import { relSortKey } from "./identity/edges.js";
|
|
4
|
+
import { aboveComments, closeSpot, lineStartAt, spotAfter } from "./text/spot.js";
|
|
5
|
+
/* ------------------------------------------------------------------ */
|
|
6
|
+
/* Landscape placement — where a top-level addition lands */
|
|
7
|
+
/* ------------------------------------------------------------------ */
|
|
8
|
+
/**
|
|
9
|
+
* The placement scheme, in full. It never moves an authored byte — placement
|
|
10
|
+
* only chooses where NEW spliced blocks go — and it is deterministic in a
|
|
11
|
+
* stronger sense: archiving feature A then feature B (touching different
|
|
12
|
+
* services) yields the SAME final bytes as B then A, which is what lets two
|
|
13
|
+
* concurrent archive PRs merge in git instead of colliding on one shared
|
|
14
|
+
* append point.
|
|
15
|
+
*
|
|
16
|
+
* - An ELEMENT whose service already has top-level elements in the model
|
|
17
|
+
* (the elementService join — binding first, title as the fallback) lands
|
|
18
|
+
* immediately after the last of them: it joins its service's neighborhood.
|
|
19
|
+
* Two features touching the SAME service therefore land adjacently, and
|
|
20
|
+
* their concurrent PRs still conflict — expected, and documented
|
|
21
|
+
* (SCHEMA.md sends that conflict to the PR flow).
|
|
22
|
+
* - An element opening a NEW service lands in the trailing region before the
|
|
23
|
+
* model's closing brace: skip the trailing relationship run, then walk left
|
|
24
|
+
* per same-service RUN, past every run whose leading id is
|
|
25
|
+
* lexicographically greater — an insertion sort of neighborhood heads
|
|
26
|
+
* against whatever is already there, which is what makes the region's
|
|
27
|
+
* final order independent of archive order (see the note on elementSpot:
|
|
28
|
+
* per-statement comparison was order-dependent).
|
|
29
|
+
* - A RELATIONSHIP lands after the last top-level relationship touching its
|
|
30
|
+
* SOURCE's service (either endpoint counts), then past the anchor's own
|
|
31
|
+
* CLUSTER members with a smaller sort key — two edges anchored to the same
|
|
32
|
+
* statement must order by key, not by which archived first. With no such
|
|
33
|
+
* neighborhood it falls to the trailing region, cluster-head-key-sorted
|
|
34
|
+
* the same insertion-sort way, after the trailing elements.
|
|
35
|
+
* - The relationship walk sorts only within the region's ASCENDING TAIL — the
|
|
36
|
+
* run loam's own insertions keep sorted — and stops where the existing order
|
|
37
|
+
* descends (`relSpot` has the case and the order-independence argument). A
|
|
38
|
+
* hand-written region is sorted by nobody, so walking into it made the spot
|
|
39
|
+
* depend on how unrelated edges happened to be drawn. The element walk is
|
|
40
|
+
* left unbounded: the map's top-level elements are few, a new service among
|
|
41
|
+
* them misfiles nothing, and its bytes are pinned as they always were.
|
|
42
|
+
* - A walk that stops BEFORE a statement, or at the closing brace, lands above
|
|
43
|
+
* the comment written directly over it (`aboveComments` in `./text/spot.ts`):
|
|
44
|
+
* a comment is about what follows it, and an addition between the two
|
|
45
|
+
* misfiles under it.
|
|
46
|
+
*
|
|
47
|
+
* A landscape may hold SEVERAL top-level `model { }` blocks, and LikeC4 reads
|
|
48
|
+
* them as one model. Placement keeps every rule above and adds one: an
|
|
49
|
+
* ANCHORED addition lands in its anchor's block (after the neighbor, clamped
|
|
50
|
+
* to that block's closing brace), and an UNANCHORED one — the trailing-region
|
|
51
|
+
* walks — lands in `HOME_BLOCK`, never crossing a block boundary. A same-service
|
|
52
|
+
* run and a relationship cluster are contiguous statements of ONE block: the
|
|
53
|
+
* views or the specification between two blocks are not a neighborhood.
|
|
54
|
+
*
|
|
55
|
+
* LikeC4 reference resolution is not order-dependent, so a relationship
|
|
56
|
+
* placed before an element it names still parses; the in-memory parse net in
|
|
57
|
+
* landscape-merge.ts's planLandscapeMerge stays as the backstop regardless.
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* The block an addition with no anchor lands in: the document's FIRST
|
|
61
|
+
* `model { }` block.
|
|
62
|
+
*
|
|
63
|
+
* First, because it is the block every unanchored addition already landed in
|
|
64
|
+
* before the scan could see a second one — the scan stopped at the first
|
|
65
|
+
* match — so a single-block map places byte-identically, and a map that grew
|
|
66
|
+
* a second block keeps receiving new services where its older ones went. It
|
|
67
|
+
* is also invariant under every addition this merge can make (an archive never
|
|
68
|
+
* creates or reorders a block), which is what order-independence needs of it:
|
|
69
|
+
* a block chosen by size or content would move as the archives landed, and the
|
|
70
|
+
* same two features would compose to different bytes by archive order. The
|
|
71
|
+
* service-model splice (`./model/merge.ts`) uses the same block for the same
|
|
72
|
+
* reasons.
|
|
73
|
+
*/
|
|
74
|
+
export const HOME_BLOCK = 0;
|
|
75
|
+
/** The statements of one block, in document order — what a trailing walk may step over. */
|
|
76
|
+
function inBlock(stmts, block) {
|
|
77
|
+
return stmts.filter((s) => s.block === block);
|
|
78
|
+
}
|
|
79
|
+
/** The model's top-level statements in document order, joined to the parsed elements for services. */
|
|
80
|
+
export function topStatements(scan, els) {
|
|
81
|
+
// An `extend <fqn>` frame is never a top-level declaration of THIS document —
|
|
82
|
+
// it reopens one another document owns — so it anchors nothing and displaces
|
|
83
|
+
// nothing. Undotted fqns are the reason the tag is checked rather than the
|
|
84
|
+
// dot: `extend paymentService { }` would otherwise read as a declaration of
|
|
85
|
+
// `paymentService` here.
|
|
86
|
+
const topEls = scan.elements.filter((e) => e.extend !== true && !e.id.includes("."));
|
|
87
|
+
const bound = new Map(els.map((e) => [e.id, elementService(e)]));
|
|
88
|
+
const stmts = topEls.map((e) => ({
|
|
89
|
+
kind: "element",
|
|
90
|
+
id: e.id,
|
|
91
|
+
key: "",
|
|
92
|
+
services: [bound.get(e.id) ?? e.id],
|
|
93
|
+
start: e.start,
|
|
94
|
+
end: e.end,
|
|
95
|
+
block: e.block,
|
|
96
|
+
}));
|
|
97
|
+
// Every top-level FRAME a statement can sit inside: the elements, and the
|
|
98
|
+
// `extend` frames, which hold edges as well as children.
|
|
99
|
+
const frames = scan.elements.filter((e) => e.extend === true || !e.id.includes("."));
|
|
100
|
+
for (const r of scan.rels) {
|
|
101
|
+
// A rel declared inside an element's body is not a top-level statement —
|
|
102
|
+
// anchoring after it would splice into the parent's block. Inside an
|
|
103
|
+
// `extend` frame it is worse than misplaced: the frame is a SCOPE, so an
|
|
104
|
+
// edge spliced in after it re-resolves there, and the delta's `zulu ->
|
|
105
|
+
// beta` landed inside `extend alpha { beta = … }` as an edge into
|
|
106
|
+
// `alpha.beta` — a merge that parses, written at exit 0 (probed
|
|
107
|
+
// 2026-10-20). Only the extend frames' edges are new to this filter.
|
|
108
|
+
if (frames.some((e) => r.start > e.start && r.start < e.end))
|
|
109
|
+
continue;
|
|
110
|
+
stmts.push({
|
|
111
|
+
kind: "rel",
|
|
112
|
+
id: "",
|
|
113
|
+
key: relSortKey(els, r),
|
|
114
|
+
// Deliberately no `known` fleet set here: this resolution only decides
|
|
115
|
+
// WHERE in the file a statement anchors, both sides of every comparison
|
|
116
|
+
// resolve through the same call, and the merged document is re-parsed
|
|
117
|
+
// before anything is written — a wrong grouping is cosmetic, never a
|
|
118
|
+
// wrong merge.
|
|
119
|
+
services: [serviceOf(els, r.source), serviceOf(els, r.target)],
|
|
120
|
+
start: r.start,
|
|
121
|
+
end: r.end,
|
|
122
|
+
block: r.block,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return stmts.sort((a, b) => a.start - b.start);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The trailing walks move in PLACEMENT UNITS, never single statements. A unit
|
|
129
|
+
* is a service neighborhood: a contiguous run of top-level elements resolving
|
|
130
|
+
* to one service, or a contiguous cluster of relationships grown around the
|
|
131
|
+
* statements touching one — keyed by its LEADING statement's id/key. Anchored
|
|
132
|
+
* inserts extend a neighborhood without changing its head, so the insertion
|
|
133
|
+
* sort the trailing region maintains is over neighborhood heads, which
|
|
134
|
+
* archive order cannot reshuffle. Comparing per statement instead let an
|
|
135
|
+
* anchored insert legally sit a LOWER id/key after a higher one (its anchor
|
|
136
|
+
* decides where it lives, not its own sort key), and a later trailing walk
|
|
137
|
+
* then stopped at different statements depending on which archive had run
|
|
138
|
+
* first — order-DEPENDENT bytes for features touching disjoint services, the
|
|
139
|
+
* exact regime the scheme guarantees.
|
|
140
|
+
*/
|
|
141
|
+
export function elementSpot(region, id, service) {
|
|
142
|
+
const { text, blocks } = region;
|
|
143
|
+
let anchor;
|
|
144
|
+
for (const s of region.stmts) {
|
|
145
|
+
if (s.kind === "element" && s.services.includes(service))
|
|
146
|
+
anchor = s;
|
|
147
|
+
}
|
|
148
|
+
if (anchor !== undefined)
|
|
149
|
+
return spotAfter(text, blocks[anchor.block].close, anchor.end);
|
|
150
|
+
const stmts = inBlock(region.stmts, HOME_BLOCK);
|
|
151
|
+
const close = blocks[HOME_BLOCK].close;
|
|
152
|
+
let i = stmts.length - 1;
|
|
153
|
+
let before;
|
|
154
|
+
while (i >= 0 && stmts[i].kind === "rel") {
|
|
155
|
+
before = stmts[i];
|
|
156
|
+
i -= 1;
|
|
157
|
+
}
|
|
158
|
+
while (i >= 0 && stmts[i].kind === "element") {
|
|
159
|
+
// The same-service run ending here is one unit: skip it whole or stop
|
|
160
|
+
// before it whole — an anchored member may carry any id, the run's
|
|
161
|
+
// LEADING id is its sort key.
|
|
162
|
+
let j = i;
|
|
163
|
+
while (j > 0 && stmts[j - 1].kind === "element" && stmts[j - 1].services[0] === stmts[i].services[0])
|
|
164
|
+
j -= 1;
|
|
165
|
+
if (!(stmts[j].id > id))
|
|
166
|
+
break;
|
|
167
|
+
before = stmts[j];
|
|
168
|
+
i = j - 1;
|
|
169
|
+
}
|
|
170
|
+
return before !== undefined ? beforeSpot(text, before) : closeSpot(text, close);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Each top-level statement's cluster, as the index of the cluster's leading
|
|
174
|
+
* statement. A relationship whose SOURCE's service some earlier relationship
|
|
175
|
+
* in the same contiguous stretch already touches is an anchored join — it
|
|
176
|
+
* belongs to that neighborhood wherever its own key would sort. One whose
|
|
177
|
+
* source's service nothing before it touches opens a new cluster; sharing
|
|
178
|
+
* only a TARGET does not join (every trailing edge into a busy hub would
|
|
179
|
+
* otherwise dissolve into one giant cluster, and the trailing sort with it).
|
|
180
|
+
* Recomputed from bytes alone, so the next archive sees the same units this
|
|
181
|
+
* one placed.
|
|
182
|
+
*/
|
|
183
|
+
function relClusterHeads(stmts) {
|
|
184
|
+
const heads = stmts.map((_, i) => i);
|
|
185
|
+
let head = -1;
|
|
186
|
+
let services = null;
|
|
187
|
+
for (let i = 0; i < stmts.length; i += 1) {
|
|
188
|
+
const s = stmts[i];
|
|
189
|
+
// A block boundary ends a cluster exactly as an element does: the first
|
|
190
|
+
// edge of the next block is not contiguous with the last of this one.
|
|
191
|
+
if (i > 0 && stmts[i - 1].block !== s.block) {
|
|
192
|
+
head = -1;
|
|
193
|
+
services = null;
|
|
194
|
+
}
|
|
195
|
+
if (s.kind !== "rel") {
|
|
196
|
+
head = -1;
|
|
197
|
+
services = null;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (services !== null && services.has(s.services[0])) {
|
|
201
|
+
for (const svc of s.services)
|
|
202
|
+
services.add(svc);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
head = i;
|
|
206
|
+
services = new Set(s.services);
|
|
207
|
+
}
|
|
208
|
+
heads[i] = head;
|
|
209
|
+
}
|
|
210
|
+
return heads;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Where a relationship lands: after its source's neighborhood, or — with none —
|
|
214
|
+
* in the trailing region, insertion-sorted among the cluster heads.
|
|
215
|
+
*
|
|
216
|
+
* The trailing walk sorts only within the region's ASCENDING TAIL: it steps left
|
|
217
|
+
* past a cluster whose head sorts above the new key only while that head also
|
|
218
|
+
* sorts at or below the head of the cluster after it. The insertions loam makes
|
|
219
|
+
* keep that tail sorted, so on a region loam wrote the walk is the plain
|
|
220
|
+
* insertion sort it always was; a hand-written region is sorted by nobody, and
|
|
221
|
+
* walking into it made the landing spot a function of unrelated edges — an edge
|
|
222
|
+
* drawn `svc -> kafka` let a new edge walk past it, the same edge turned round
|
|
223
|
+
* (`kafka -[delivers]-> svc`, a head that sorts lower) stopped the walk, and the
|
|
224
|
+
* addition landed sixty lines away under a comment about something else
|
|
225
|
+
* (2026-10). Order-independence survives the bound: the statements before the
|
|
226
|
+
* tail never change, because an addition sorting below the tail's first head
|
|
227
|
+
* becomes its new first head, and that still sorts below the statement the tail
|
|
228
|
+
* broke from — so every archive inserts into the same sorted run, whatever
|
|
229
|
+
* order they land in.
|
|
230
|
+
*/
|
|
231
|
+
export function relSpot(region, sourceService, key) {
|
|
232
|
+
const anchored = anchoredRelSpot(region, sourceService, key);
|
|
233
|
+
if (anchored !== null)
|
|
234
|
+
return anchored;
|
|
235
|
+
const { text, blocks } = region;
|
|
236
|
+
const stmts = inBlock(region.stmts, HOME_BLOCK);
|
|
237
|
+
const close = blocks[HOME_BLOCK].close;
|
|
238
|
+
const heads = relClusterHeads(stmts);
|
|
239
|
+
let i = stmts.length - 1;
|
|
240
|
+
let before;
|
|
241
|
+
while (i >= 0 && stmts[i].kind === "rel") {
|
|
242
|
+
const j = heads[i];
|
|
243
|
+
if (!(stmts[j].key > key))
|
|
244
|
+
break;
|
|
245
|
+
if (before !== undefined && stmts[j].key > before.key)
|
|
246
|
+
break;
|
|
247
|
+
before = stmts[j];
|
|
248
|
+
i = j - 1;
|
|
249
|
+
}
|
|
250
|
+
return before !== undefined ? beforeSpot(text, before) : closeSpot(text, close);
|
|
251
|
+
}
|
|
252
|
+
/** After the last relationship touching the source's service, in that relationship's block — null when none does. */
|
|
253
|
+
function anchoredRelSpot(region, sourceService, key) {
|
|
254
|
+
const { text, stmts, blocks } = region;
|
|
255
|
+
const heads = relClusterHeads(stmts);
|
|
256
|
+
let anchorAt = -1;
|
|
257
|
+
for (let i = 0; i < stmts.length; i += 1) {
|
|
258
|
+
const s = stmts[i];
|
|
259
|
+
if (s.kind === "rel" && s.services.includes(sourceService))
|
|
260
|
+
anchorAt = i;
|
|
261
|
+
}
|
|
262
|
+
if (anchorAt !== -1) {
|
|
263
|
+
// Past the anchor, order among the cluster's OWN members is by key — two
|
|
264
|
+
// edges anchored to the same statement must order by key, not by which
|
|
265
|
+
// archived first — but the walk never leaves the cluster: the next
|
|
266
|
+
// cluster is another neighborhood's, and stepping over it would depend
|
|
267
|
+
// on which archive put it there.
|
|
268
|
+
let last = stmts[anchorAt];
|
|
269
|
+
for (let j = anchorAt + 1; j < stmts.length; j += 1) {
|
|
270
|
+
const s = stmts[j];
|
|
271
|
+
if (s.kind !== "rel" || heads[j] !== heads[anchorAt] || s.key >= key)
|
|
272
|
+
break;
|
|
273
|
+
last = s;
|
|
274
|
+
}
|
|
275
|
+
return spotAfter(text, blocks[last.block].close, last.end);
|
|
276
|
+
}
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Insertion before an existing statement: above the comment written directly
|
|
281
|
+
* over it when only whitespace precedes it on its line, at the statement itself
|
|
282
|
+
* — bare, displacing it onto a fresh line — when other text shares the line (a
|
|
283
|
+
* statement written on the `model {` line, say). The unguarded line start
|
|
284
|
+
* spliced the block BEFORE the model keyword, and the parse net refused a
|
|
285
|
+
* perfectly legal landscape.
|
|
286
|
+
*
|
|
287
|
+
* Above the comment, because a comment written over a statement is about that
|
|
288
|
+
* statement, or heads the section it opens: inserted at the statement's own
|
|
289
|
+
* line, an addition landed between a six-line explanation and the edge it
|
|
290
|
+
* explains (2026-10). `aboveComments` says which lines count.
|
|
291
|
+
*/
|
|
292
|
+
function beforeSpot(text, before) {
|
|
293
|
+
const ls = lineStartAt(text, before.start);
|
|
294
|
+
if (/^[ \t]*$/.test(text.slice(ls, before.start)))
|
|
295
|
+
return { at: aboveComments(text, ls), bare: false };
|
|
296
|
+
return { at: before.start, bare: true };
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=placement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placement.js","sourceRoot":"","sources":["../../../../src/core/c4/splice/placement.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Elem } from \"../likec4.js\";\nimport { elementService, serviceOf } from \"../resolve/service.js\";\nimport type { ScannedBlock, ScannedModel } from \"../source-scan.js\";\nimport { relSortKey } from \"./identity/edges.js\";\nimport { aboveComments, closeSpot, lineStartAt, spotAfter, type Spot } from \"./text/spot.js\";\n\n/* ------------------------------------------------------------------ */\n/* Landscape placement — where a top-level addition lands */\n/* ------------------------------------------------------------------ */\n\n/**\n * The placement scheme, in full. It never moves an authored byte — placement\n * only chooses where NEW spliced blocks go — and it is deterministic in a\n * stronger sense: archiving feature A then feature B (touching different\n * services) yields the SAME final bytes as B then A, which is what lets two\n * concurrent archive PRs merge in git instead of colliding on one shared\n * append point.\n *\n * - An ELEMENT whose service already has top-level elements in the model\n * (the elementService join — binding first, title as the fallback) lands\n * immediately after the last of them: it joins its service's neighborhood.\n * Two features touching the SAME service therefore land adjacently, and\n * their concurrent PRs still conflict — expected, and documented\n * (SCHEMA.md sends that conflict to the PR flow).\n * - An element opening a NEW service lands in the trailing region before the\n * model's closing brace: skip the trailing relationship run, then walk left\n * per same-service RUN, past every run whose leading id is\n * lexicographically greater — an insertion sort of neighborhood heads\n * against whatever is already there, which is what makes the region's\n * final order independent of archive order (see the note on elementSpot:\n * per-statement comparison was order-dependent).\n * - A RELATIONSHIP lands after the last top-level relationship touching its\n * SOURCE's service (either endpoint counts), then past the anchor's own\n * CLUSTER members with a smaller sort key — two edges anchored to the same\n * statement must order by key, not by which archived first. With no such\n * neighborhood it falls to the trailing region, cluster-head-key-sorted\n * the same insertion-sort way, after the trailing elements.\n * - The relationship walk sorts only within the region's ASCENDING TAIL — the\n * run loam's own insertions keep sorted — and stops where the existing order\n * descends (`relSpot` has the case and the order-independence argument). A\n * hand-written region is sorted by nobody, so walking into it made the spot\n * depend on how unrelated edges happened to be drawn. The element walk is\n * left unbounded: the map's top-level elements are few, a new service among\n * them misfiles nothing, and its bytes are pinned as they always were.\n * - A walk that stops BEFORE a statement, or at the closing brace, lands above\n * the comment written directly over it (`aboveComments` in `./text/spot.ts`):\n * a comment is about what follows it, and an addition between the two\n * misfiles under it.\n *\n * A landscape may hold SEVERAL top-level `model { }` blocks, and LikeC4 reads\n * them as one model. Placement keeps every rule above and adds one: an\n * ANCHORED addition lands in its anchor's block (after the neighbor, clamped\n * to that block's closing brace), and an UNANCHORED one — the trailing-region\n * walks — lands in `HOME_BLOCK`, never crossing a block boundary. A same-service\n * run and a relationship cluster are contiguous statements of ONE block: the\n * views or the specification between two blocks are not a neighborhood.\n *\n * LikeC4 reference resolution is not order-dependent, so a relationship\n * placed before an element it names still parses; the in-memory parse net in\n * landscape-merge.ts's planLandscapeMerge stays as the backstop regardless.\n */\n\n/**\n * The block an addition with no anchor lands in: the document's FIRST\n * `model { }` block.\n *\n * First, because it is the block every unanchored addition already landed in\n * before the scan could see a second one — the scan stopped at the first\n * match — so a single-block map places byte-identically, and a map that grew\n * a second block keeps receiving new services where its older ones went. It\n * is also invariant under every addition this merge can make (an archive never\n * creates or reorders a block), which is what order-independence needs of it:\n * a block chosen by size or content would move as the archives landed, and the\n * same two features would compose to different bytes by archive order. The\n * service-model splice (`./model/merge.ts`) uses the same block for the same\n * reasons.\n */\nexport const HOME_BLOCK = 0;\n\n/** A top-level statement of the living model, with everything placement asks of it. */\nexport interface TopStmt {\n kind: \"element\" | \"rel\";\n /** Element: its id. */\n id: string;\n /** Relationship: its placement sort key (relSortKey). */\n key: string;\n /** The service(s) this statement resolves to — one for an element, both endpoints for a rel. */\n services: string[];\n start: number;\n end: number;\n /** The `model { }` block it is written in, as `ScannedModel.blocks` indexes it. */\n block: number;\n}\n\n/**\n * The living model as placement reads it: the text being spliced into, its\n * top-level statement layout, and the model blocks' braces. One value\n * because every spot is computed against all three at the same instant — a\n * layout paired with text a splice has since moved would place against a\n * document that no longer exists (see `modelRegion` in landscape-merge.ts's\n * planLandscapeMerge).\n */\nexport interface ModelRegion {\n text: string;\n stmts: TopStmt[];\n /** Every top-level `model { }` block, by the index `TopStmt.block` names. */\n blocks: readonly ScannedBlock[];\n}\n\n/** The statements of one block, in document order — what a trailing walk may step over. */\nfunction inBlock(stmts: TopStmt[], block: number): TopStmt[] {\n return stmts.filter((s) => s.block === block);\n}\n\n/** The model's top-level statements in document order, joined to the parsed elements for services. */\nexport function topStatements(scan: ScannedModel, els: Elem[]): TopStmt[] {\n // An `extend <fqn>` frame is never a top-level declaration of THIS document —\n // it reopens one another document owns — so it anchors nothing and displaces\n // nothing. Undotted fqns are the reason the tag is checked rather than the\n // dot: `extend paymentService { }` would otherwise read as a declaration of\n // `paymentService` here.\n const topEls = scan.elements.filter((e) => e.extend !== true && !e.id.includes(\".\"));\n const bound = new Map(els.map((e) => [e.id, elementService(e)]));\n const stmts: TopStmt[] = topEls.map((e) => ({\n kind: \"element\" as const,\n id: e.id,\n key: \"\",\n services: [bound.get(e.id) ?? e.id],\n start: e.start,\n end: e.end,\n block: e.block,\n }));\n // Every top-level FRAME a statement can sit inside: the elements, and the\n // `extend` frames, which hold edges as well as children.\n const frames = scan.elements.filter((e) => e.extend === true || !e.id.includes(\".\"));\n for (const r of scan.rels) {\n // A rel declared inside an element's body is not a top-level statement —\n // anchoring after it would splice into the parent's block. Inside an\n // `extend` frame it is worse than misplaced: the frame is a SCOPE, so an\n // edge spliced in after it re-resolves there, and the delta's `zulu ->\n // beta` landed inside `extend alpha { beta = … }` as an edge into\n // `alpha.beta` — a merge that parses, written at exit 0 (probed\n // 2026-10-20). Only the extend frames' edges are new to this filter.\n if (frames.some((e) => r.start > e.start && r.start < e.end)) continue;\n stmts.push({\n kind: \"rel\",\n id: \"\",\n key: relSortKey(els, r),\n // Deliberately no `known` fleet set here: this resolution only decides\n // WHERE in the file a statement anchors, both sides of every comparison\n // resolve through the same call, and the merged document is re-parsed\n // before anything is written — a wrong grouping is cosmetic, never a\n // wrong merge.\n services: [serviceOf(els, r.source), serviceOf(els, r.target)],\n start: r.start,\n end: r.end,\n block: r.block,\n });\n }\n return stmts.sort((a, b) => a.start - b.start);\n}\n\n\n/**\n * The trailing walks move in PLACEMENT UNITS, never single statements. A unit\n * is a service neighborhood: a contiguous run of top-level elements resolving\n * to one service, or a contiguous cluster of relationships grown around the\n * statements touching one — keyed by its LEADING statement's id/key. Anchored\n * inserts extend a neighborhood without changing its head, so the insertion\n * sort the trailing region maintains is over neighborhood heads, which\n * archive order cannot reshuffle. Comparing per statement instead let an\n * anchored insert legally sit a LOWER id/key after a higher one (its anchor\n * decides where it lives, not its own sort key), and a later trailing walk\n * then stopped at different statements depending on which archive had run\n * first — order-DEPENDENT bytes for features touching disjoint services, the\n * exact regime the scheme guarantees.\n */\nexport function elementSpot(region: ModelRegion, id: string, service: string): Spot {\n const { text, blocks } = region;\n let anchor: TopStmt | undefined;\n for (const s of region.stmts) {\n if (s.kind === \"element\" && s.services.includes(service)) anchor = s;\n }\n if (anchor !== undefined) return spotAfter(text, blocks[anchor.block]!.close, anchor.end);\n const stmts = inBlock(region.stmts, HOME_BLOCK);\n const close = blocks[HOME_BLOCK]!.close;\n let i = stmts.length - 1;\n let before: TopStmt | undefined;\n while (i >= 0 && stmts[i]!.kind === \"rel\") {\n before = stmts[i];\n i -= 1;\n }\n while (i >= 0 && stmts[i]!.kind === \"element\") {\n // The same-service run ending here is one unit: skip it whole or stop\n // before it whole — an anchored member may carry any id, the run's\n // LEADING id is its sort key.\n let j = i;\n while (j > 0 && stmts[j - 1]!.kind === \"element\" && stmts[j - 1]!.services[0] === stmts[i]!.services[0]) j -= 1;\n if (!(stmts[j]!.id > id)) break;\n before = stmts[j];\n i = j - 1;\n }\n return before !== undefined ? beforeSpot(text, before) : closeSpot(text, close);\n}\n\n/**\n * Each top-level statement's cluster, as the index of the cluster's leading\n * statement. A relationship whose SOURCE's service some earlier relationship\n * in the same contiguous stretch already touches is an anchored join — it\n * belongs to that neighborhood wherever its own key would sort. One whose\n * source's service nothing before it touches opens a new cluster; sharing\n * only a TARGET does not join (every trailing edge into a busy hub would\n * otherwise dissolve into one giant cluster, and the trailing sort with it).\n * Recomputed from bytes alone, so the next archive sees the same units this\n * one placed.\n */\nfunction relClusterHeads(stmts: TopStmt[]): number[] {\n const heads = stmts.map((_, i) => i);\n let head = -1;\n let services: Set<string> | null = null;\n for (let i = 0; i < stmts.length; i += 1) {\n const s = stmts[i]!;\n // A block boundary ends a cluster exactly as an element does: the first\n // edge of the next block is not contiguous with the last of this one.\n if (i > 0 && stmts[i - 1]!.block !== s.block) {\n head = -1;\n services = null;\n }\n if (s.kind !== \"rel\") {\n head = -1;\n services = null;\n continue;\n }\n if (services !== null && services.has(s.services[0]!)) {\n for (const svc of s.services) services.add(svc);\n } else {\n head = i;\n services = new Set(s.services);\n }\n heads[i] = head;\n }\n return heads;\n}\n\n/**\n * Where a relationship lands: after its source's neighborhood, or — with none —\n * in the trailing region, insertion-sorted among the cluster heads.\n *\n * The trailing walk sorts only within the region's ASCENDING TAIL: it steps left\n * past a cluster whose head sorts above the new key only while that head also\n * sorts at or below the head of the cluster after it. The insertions loam makes\n * keep that tail sorted, so on a region loam wrote the walk is the plain\n * insertion sort it always was; a hand-written region is sorted by nobody, and\n * walking into it made the landing spot a function of unrelated edges — an edge\n * drawn `svc -> kafka` let a new edge walk past it, the same edge turned round\n * (`kafka -[delivers]-> svc`, a head that sorts lower) stopped the walk, and the\n * addition landed sixty lines away under a comment about something else\n * (2026-10). Order-independence survives the bound: the statements before the\n * tail never change, because an addition sorting below the tail's first head\n * becomes its new first head, and that still sorts below the statement the tail\n * broke from — so every archive inserts into the same sorted run, whatever\n * order they land in.\n */\nexport function relSpot(region: ModelRegion, sourceService: string, key: string): Spot {\n const anchored = anchoredRelSpot(region, sourceService, key);\n if (anchored !== null) return anchored;\n const { text, blocks } = region;\n const stmts = inBlock(region.stmts, HOME_BLOCK);\n const close = blocks[HOME_BLOCK]!.close;\n const heads = relClusterHeads(stmts);\n let i = stmts.length - 1;\n let before: TopStmt | undefined;\n while (i >= 0 && stmts[i]!.kind === \"rel\") {\n const j = heads[i]!;\n if (!(stmts[j]!.key > key)) break;\n if (before !== undefined && stmts[j]!.key > before.key) break;\n before = stmts[j];\n i = j - 1;\n }\n return before !== undefined ? beforeSpot(text, before) : closeSpot(text, close);\n}\n\n/** After the last relationship touching the source's service, in that relationship's block — null when none does. */\nfunction anchoredRelSpot(region: ModelRegion, sourceService: string, key: string): Spot | null {\n const { text, stmts, blocks } = region;\n const heads = relClusterHeads(stmts);\n let anchorAt = -1;\n for (let i = 0; i < stmts.length; i += 1) {\n const s = stmts[i]!;\n if (s.kind === \"rel\" && s.services.includes(sourceService)) anchorAt = i;\n }\n if (anchorAt !== -1) {\n // Past the anchor, order among the cluster's OWN members is by key — two\n // edges anchored to the same statement must order by key, not by which\n // archived first — but the walk never leaves the cluster: the next\n // cluster is another neighborhood's, and stepping over it would depend\n // on which archive put it there.\n let last = stmts[anchorAt]!;\n for (let j = anchorAt + 1; j < stmts.length; j += 1) {\n const s = stmts[j]!;\n if (s.kind !== \"rel\" || heads[j] !== heads[anchorAt] || s.key >= key) break;\n last = s;\n }\n return spotAfter(text, blocks[last.block]!.close, last.end);\n }\n return null;\n}\n\n/**\n * Insertion before an existing statement: above the comment written directly\n * over it when only whitespace precedes it on its line, at the statement itself\n * — bare, displacing it onto a fresh line — when other text shares the line (a\n * statement written on the `model {` line, say). The unguarded line start\n * spliced the block BEFORE the model keyword, and the parse net refused a\n * perfectly legal landscape.\n *\n * Above the comment, because a comment written over a statement is about that\n * statement, or heads the section it opens: inserted at the statement's own\n * line, an addition landed between a six-line explanation and the edge it\n * explains (2026-10). `aboveComments` says which lines count.\n */\nfunction beforeSpot(text: string, before: TopStmt): Spot {\n const ls = lineStartAt(text, before.start);\n if (/^[ \\t]*$/.test(text.slice(ls, before.start))) return { at: aboveComments(text, ls), bare: false };\n return { at: before.start, bare: true };\n}\n"]}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a block enters a LikeC4 document, in byte offsets — the text half of
|
|
3
|
+
* the splice's placement. `../placement.ts` decides which statement an addition
|
|
4
|
+
* lands beside, by service and by sort key; everything here answers how that
|
|
5
|
+
* decision becomes an offset in the authored bytes without cutting into a
|
|
6
|
+
* comment, a body or the line another statement shares. The service-model
|
|
7
|
+
* splice (`../model/merge.ts`) asks the same questions of a document it does
|
|
8
|
+
* not group by service, and reads them from here for that reason.
|
|
9
|
+
*/
|
|
10
|
+
import { maskSource, pastComments, tokenEnd } from "../../source-mask.js";
|
|
11
|
+
/**
|
|
12
|
+
* The line following the statement that ends at `end` — clamped to the closing
|
|
13
|
+
* brace's own spot. Exported for the service-model splice (`../model/merge.ts`),
|
|
14
|
+
* which asks the same two questions of a `model { }` block it does not group by
|
|
15
|
+
* service: after this statement, or last thing in the block.
|
|
16
|
+
*
|
|
17
|
+
* Unless code follows `end` on its line: then the spot is `end` itself, bare.
|
|
18
|
+
* The next line belongs to whatever is written there, and when that is a
|
|
19
|
+
* declaration whose body opens on the same line — `alpha = … { … } beta = … {`
|
|
20
|
+
* — the line after is INSIDE beta: an addition anchored to alpha's service
|
|
21
|
+
* landed as `beta.kiwi`, in a merge that parsed and was written (exit 0,
|
|
22
|
+
* probed on main at 171555d). Right after the anchor is also what keeps two
|
|
23
|
+
* archives order-free when both anchor on that line: one anchored to alpha and
|
|
24
|
+
* one to beta used to share the next line's start, and whichever ran second
|
|
25
|
+
* landed above the other. A comment trailing the anchor is not code — the
|
|
26
|
+
* next line stays the spot, byte for byte as before — but a block comment
|
|
27
|
+
* it does not close is: its next line is inside the comment.
|
|
28
|
+
*
|
|
29
|
+
* A line comment ends where LikeC4's NL does, at `\r` as well as `\n` — the
|
|
30
|
+
* source mask agrees since the bare-CR fix — so `// note\r beta = … {` is a
|
|
31
|
+
* comment and then code on the anchor's `\n`-line, and the spot after that
|
|
32
|
+
* line is inside beta: the same `beta.kiwi` merge, written at exit 0, which
|
|
33
|
+
* 171555d refused because it could not locate beta at all. A CRLF ending
|
|
34
|
+
* leaves nothing after the comment and keeps the next line, byte for byte.
|
|
35
|
+
*/
|
|
36
|
+
export function spotAfter(text, close, end) {
|
|
37
|
+
const nl = text.indexOf("\n", end);
|
|
38
|
+
const at = nl === -1 ? text.length : nl + 1;
|
|
39
|
+
let rest = pastComments(text.slice(end, Math.min(at, close)));
|
|
40
|
+
while (rest.startsWith("//")) {
|
|
41
|
+
const eol = rest.search(/[\r\n]/);
|
|
42
|
+
rest = eol === -1 ? "" : pastComments(rest.slice(eol));
|
|
43
|
+
}
|
|
44
|
+
if (rest !== "")
|
|
45
|
+
return { at: end, bare: true };
|
|
46
|
+
return at > close ? closeSpot(text, close) : { at, bare: false };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The last resort: directly before the model's closing brace — above a comment
|
|
50
|
+
* written directly over the brace, for the reason `aboveComments` gives.
|
|
51
|
+
*/
|
|
52
|
+
export function closeSpot(text, close) {
|
|
53
|
+
const ls = lineStartAt(text, close);
|
|
54
|
+
if (/^[ \t]*$/.test(text.slice(ls, close)))
|
|
55
|
+
return { at: aboveComments(text, ls), bare: false };
|
|
56
|
+
return { at: close, bare: true };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The start of the run of comment lines written directly above the line that
|
|
60
|
+
* starts at `at` — `at` itself when there is none. A blank line ends the run: a
|
|
61
|
+
* comment separated from what follows it by a blank line stands alone, and
|
|
62
|
+
* stays where it is. So does a line that is not comment from its first
|
|
63
|
+
* character to `at` — code, the `model {` line — and a line that starts INSIDE
|
|
64
|
+
* a block comment or a string opened above it, whatever it looks like: the last
|
|
65
|
+
* line of `/* retired … // old edge *\/` reads as a line comment on its own,
|
|
66
|
+
* and splicing at its start put the addition inside the block comment, where
|
|
67
|
+
* the map parsed clean and the edge was gone at exit 0 (review, 2026-10-22).
|
|
68
|
+
* Which lines are inside what is read off one pass over the whole text, never
|
|
69
|
+
* off the line.
|
|
70
|
+
*
|
|
71
|
+
* Every walk in `../placement.ts` that stops before a statement or at the
|
|
72
|
+
* closing brace lands here, and the rule has to be the same at both for
|
|
73
|
+
* placement to stay order-independent: each splits the lines between two
|
|
74
|
+
* statements at the same point, so an addition landing there first and one
|
|
75
|
+
* landing beside it second compose to the bytes the opposite order writes.
|
|
76
|
+
*/
|
|
77
|
+
export function aboveComments(text, at) {
|
|
78
|
+
const { comments, literals } = maskSource(text);
|
|
79
|
+
const inside = (p) => [...comments, ...literals].some((s) => s.start < p && p < s.end);
|
|
80
|
+
let top = at;
|
|
81
|
+
while (top > 0) {
|
|
82
|
+
const above = lineStartAt(text, top - 1);
|
|
83
|
+
if (text.slice(above, top).trim() === "" || inside(above) || !onlyComments(text.slice(above, at)))
|
|
84
|
+
break;
|
|
85
|
+
top = above;
|
|
86
|
+
}
|
|
87
|
+
return top;
|
|
88
|
+
}
|
|
89
|
+
/** Whether `text` holds nothing but whitespace and complete comments. */
|
|
90
|
+
function onlyComments(text) {
|
|
91
|
+
let rest = pastComments(text);
|
|
92
|
+
while (rest.startsWith("//")) {
|
|
93
|
+
const eol = rest.search(/[\r\n]/);
|
|
94
|
+
rest = eol === -1 ? "" : pastComments(rest.slice(eol));
|
|
95
|
+
}
|
|
96
|
+
return rest === "";
|
|
97
|
+
}
|
|
98
|
+
export function lineStartAt(text, at) {
|
|
99
|
+
return text.lastIndexOf("\n", at - 1) + 1;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Where a child block enters an existing living parent: before the closing
|
|
103
|
+
* brace of the parent's body, on its own line at the parent's inner indent —
|
|
104
|
+
* and a parent that never had a body gains one around the child.
|
|
105
|
+
*/
|
|
106
|
+
export function nestedInsert(text, parent, block) {
|
|
107
|
+
if (parent.bodyOpen === -1) {
|
|
108
|
+
return { at: bodyAt(text, parent), insert: ` {\n${block}\n${parent.indent}}` };
|
|
109
|
+
}
|
|
110
|
+
const lineStart = text.lastIndexOf("\n", parent.bodyClose - 1) + 1;
|
|
111
|
+
if (/^[ \t]*$/.test(text.slice(lineStart, parent.bodyClose))) {
|
|
112
|
+
return { at: lineStart, insert: `${block}\n` };
|
|
113
|
+
}
|
|
114
|
+
// `{ ... }` on one line — break the brace onto its own line to make room.
|
|
115
|
+
return { at: parent.bodyClose, insert: `\n${block}\n${parent.indent}` };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Where a bodyless parent's new body opens: where its span ends, unless a line
|
|
119
|
+
* comment trails its last token there. The span carries that comment — it is
|
|
120
|
+
* the declaration's own authored text (`statementEnd`) — so the `{` landed
|
|
121
|
+
* INSIDE `// the api`, everything after it on the line was comment, and the
|
|
122
|
+
* parse net refused a valid map ("Expecting end of file"). It opens before the
|
|
123
|
+
* comment now, which then trails the new closing brace. A closed block comment
|
|
124
|
+
* is no such trap, and keeps the bytes it always had.
|
|
125
|
+
*/
|
|
126
|
+
function bodyAt(text, parent) {
|
|
127
|
+
const span = text.slice(parent.start, parent.end);
|
|
128
|
+
const last = parent.start + tokenEnd(maskSource(span), 0, span.length);
|
|
129
|
+
return pastComments(text.slice(last, parent.end)) === "" ? parent.end : last;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=spot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spot.js","sourceRoot":"","sources":["../../../../../src/core/c4/splice/text/spot.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Where a block enters a LikeC4 document, in byte offsets — the text half of\n * the splice's placement. `../placement.ts` decides which statement an addition\n * lands beside, by service and by sort key; everything here answers how that\n * decision becomes an offset in the authored bytes without cutting into a\n * comment, a body or the line another statement shares. The service-model\n * splice (`../model/merge.ts`) asks the same questions of a document it does\n * not group by service, and reads them from here for that reason.\n */\nimport { maskSource, pastComments, tokenEnd } from \"../../source-mask.js\";\nimport type { ScannedElement } from \"../../source-scan.js\";\n\n/** A splice point the placement rules chose. */\nexport interface Spot {\n /** Offset into the living text: a line start, or a point inside a shared line. */\n at: number;\n /** True when `at` shares its line with other text (the closing brace, or a displaced statement) — the block must bring its own newlines. */\n bare: boolean;\n}\n\n/**\n * The line following the statement that ends at `end` — clamped to the closing\n * brace's own spot. Exported for the service-model splice (`../model/merge.ts`),\n * which asks the same two questions of a `model { }` block it does not group by\n * service: after this statement, or last thing in the block.\n *\n * Unless code follows `end` on its line: then the spot is `end` itself, bare.\n * The next line belongs to whatever is written there, and when that is a\n * declaration whose body opens on the same line — `alpha = … { … } beta = … {`\n * — the line after is INSIDE beta: an addition anchored to alpha's service\n * landed as `beta.kiwi`, in a merge that parsed and was written (exit 0,\n * probed on main at 171555d). Right after the anchor is also what keeps two\n * archives order-free when both anchor on that line: one anchored to alpha and\n * one to beta used to share the next line's start, and whichever ran second\n * landed above the other. A comment trailing the anchor is not code — the\n * next line stays the spot, byte for byte as before — but a block comment\n * it does not close is: its next line is inside the comment.\n *\n * A line comment ends where LikeC4's NL does, at `\\r` as well as `\\n` — the\n * source mask agrees since the bare-CR fix — so `// note\\r beta = … {` is a\n * comment and then code on the anchor's `\\n`-line, and the spot after that\n * line is inside beta: the same `beta.kiwi` merge, written at exit 0, which\n * 171555d refused because it could not locate beta at all. A CRLF ending\n * leaves nothing after the comment and keeps the next line, byte for byte.\n */\nexport function spotAfter(text: string, close: number, end: number): Spot {\n const nl = text.indexOf(\"\\n\", end);\n const at = nl === -1 ? text.length : nl + 1;\n let rest = pastComments(text.slice(end, Math.min(at, close)));\n while (rest.startsWith(\"//\")) {\n const eol = rest.search(/[\\r\\n]/);\n rest = eol === -1 ? \"\" : pastComments(rest.slice(eol));\n }\n if (rest !== \"\") return { at: end, bare: true };\n return at > close ? closeSpot(text, close) : { at, bare: false };\n}\n\n/**\n * The last resort: directly before the model's closing brace — above a comment\n * written directly over the brace, for the reason `aboveComments` gives.\n */\nexport function closeSpot(text: string, close: number): Spot {\n const ls = lineStartAt(text, close);\n if (/^[ \\t]*$/.test(text.slice(ls, close))) return { at: aboveComments(text, ls), bare: false };\n return { at: close, bare: true };\n}\n\n/**\n * The start of the run of comment lines written directly above the line that\n * starts at `at` — `at` itself when there is none. A blank line ends the run: a\n * comment separated from what follows it by a blank line stands alone, and\n * stays where it is. So does a line that is not comment from its first\n * character to `at` — code, the `model {` line — and a line that starts INSIDE\n * a block comment or a string opened above it, whatever it looks like: the last\n * line of `/* retired … // old edge *\\/` reads as a line comment on its own,\n * and splicing at its start put the addition inside the block comment, where\n * the map parsed clean and the edge was gone at exit 0 (review, 2026-10-22).\n * Which lines are inside what is read off one pass over the whole text, never\n * off the line.\n *\n * Every walk in `../placement.ts` that stops before a statement or at the\n * closing brace lands here, and the rule has to be the same at both for\n * placement to stay order-independent: each splits the lines between two\n * statements at the same point, so an addition landing there first and one\n * landing beside it second compose to the bytes the opposite order writes.\n */\nexport function aboveComments(text: string, at: number): number {\n const { comments, literals } = maskSource(text);\n const inside = (p: number): boolean => [...comments, ...literals].some((s) => s.start < p && p < s.end);\n let top = at;\n while (top > 0) {\n const above = lineStartAt(text, top - 1);\n if (text.slice(above, top).trim() === \"\" || inside(above) || !onlyComments(text.slice(above, at))) break;\n top = above;\n }\n return top;\n}\n\n/** Whether `text` holds nothing but whitespace and complete comments. */\nfunction onlyComments(text: string): boolean {\n let rest = pastComments(text);\n while (rest.startsWith(\"//\")) {\n const eol = rest.search(/[\\r\\n]/);\n rest = eol === -1 ? \"\" : pastComments(rest.slice(eol));\n }\n return rest === \"\";\n}\n\nexport function lineStartAt(text: string, at: number): number {\n return text.lastIndexOf(\"\\n\", at - 1) + 1;\n}\n\n/**\n * Where a child block enters an existing living parent: before the closing\n * brace of the parent's body, on its own line at the parent's inner indent —\n * and a parent that never had a body gains one around the child.\n */\nexport function nestedInsert(text: string, parent: ScannedElement, block: string): { at: number; insert: string } {\n if (parent.bodyOpen === -1) {\n return { at: bodyAt(text, parent), insert: ` {\\n${block}\\n${parent.indent}}` };\n }\n const lineStart = text.lastIndexOf(\"\\n\", parent.bodyClose - 1) + 1;\n if (/^[ \\t]*$/.test(text.slice(lineStart, parent.bodyClose))) {\n return { at: lineStart, insert: `${block}\\n` };\n }\n // `{ ... }` on one line — break the brace onto its own line to make room.\n return { at: parent.bodyClose, insert: `\\n${block}\\n${parent.indent}` };\n}\n\n/**\n * Where a bodyless parent's new body opens: where its span ends, unless a line\n * comment trails its last token there. The span carries that comment — it is\n * the declaration's own authored text (`statementEnd`) — so the `{` landed\n * INSIDE `// the api`, everything after it on the line was comment, and the\n * parse net refused a valid map (\"Expecting end of file\"). It opens before the\n * comment now, which then trails the new closing brace. A closed block comment\n * is no such trap, and keeps the bytes it always had.\n */\nfunction bodyAt(text: string, parent: ScannedElement): number {\n const span = text.slice(parent.start, parent.end);\n const last = parent.start + tokenEnd(maskSource(span), 0, span.length);\n return pastComments(text.slice(last, parent.end)) === \"\" ? parent.end : last;\n}\n"]}
|