@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,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every markdown link a document writes, as data.
|
|
3
|
+
*
|
|
4
|
+
* A link between documents in a docs repo is a JOIN, not decoration — a
|
|
5
|
+
* requirement that names a domain term points at that term's definition, and an
|
|
6
|
+
* ADR that supersedes another says which. `SCHEMA.md` and the generated
|
|
7
|
+
* `AGENTS.md` have stated the convention (standard markdown links, relative
|
|
8
|
+
* path targets) since the fleet-ADR work; this module is what finally reads
|
|
9
|
+
* one, so `./findings.ts` can answer the only question the convention was
|
|
10
|
+
* chosen for: does the target exist.
|
|
11
|
+
*
|
|
12
|
+
* WHY A PARSER RATHER THAN A REGEX AT THE CALL SITE. Two classes of false
|
|
13
|
+
* positive make the naive `\[.*\]\(.*\)` unusable on the documents loam owns,
|
|
14
|
+
* and both occur in loam's OWN generated prose. A fenced block is where a
|
|
15
|
+
* document SHOWS the convention — the `AGENTS.md` section that teaches the link
|
|
16
|
+
* format contains a link nobody wrote to be followed — and an inline code span
|
|
17
|
+
* is where prose quotes a path. Both must read as text. The fence rule is the
|
|
18
|
+
* one `core/document/parse.ts` already applies to headings, and it is imported
|
|
19
|
+
* rather than restated for the reason that module gives about its own sampler:
|
|
20
|
+
* two readers disagreeing about what a fence encloses prescribe a document no
|
|
21
|
+
* author can satisfy.
|
|
22
|
+
*/
|
|
23
|
+
import { relative, resolve, sep } from "node:path";
|
|
24
|
+
import { fenceTracker } from "../kernel/fences.js";
|
|
25
|
+
/**
|
|
26
|
+
* Inline links and images: `[text](target)`, ``,
|
|
27
|
+
* `[text](<target with spaces>)`, `[text](target "title")`.
|
|
28
|
+
*
|
|
29
|
+
* The target alternation takes `<...>` first so an angle-bracketed path
|
|
30
|
+
* containing spaces stays one token; the bare form stops at whitespace or `)`,
|
|
31
|
+
* which gives up on the balanced-parens spelling markdown also allows
|
|
32
|
+
* (`[x](a(1).md)`). That is a deliberate under-read: it costs a link nobody
|
|
33
|
+
* writes, where over-reading would swallow the rest of a sentence and report a
|
|
34
|
+
* target no author would recognise.
|
|
35
|
+
*/
|
|
36
|
+
const INLINE_RE = /!?\[([^\]]*)\]\(\s*(<[^>\n]*>|[^\s)]*)(?:\s+(?:"[^"]*"|'[^']*'|\([^)]*\)))?\s*\)/gd;
|
|
37
|
+
/**
|
|
38
|
+
* A reference DEFINITION — `[label]: target "title"` on its own line. Included
|
|
39
|
+
* because the target is the same join written in a different place: a document
|
|
40
|
+
* that collects its links at the bottom is following the convention, and a
|
|
41
|
+
* reader that only saw inline links would grade it as having none.
|
|
42
|
+
*/
|
|
43
|
+
const DEFINITION_RE = /^ {0,3}\[([^\]]+)\]:\s*(<[^>\n]*>|\S+)/d;
|
|
44
|
+
/**
|
|
45
|
+
* Code spans, blanked before matching. `\`[a](b)\`` is prose ABOUT a link and
|
|
46
|
+
* resolving it would convict a document for explaining the convention. Blanked
|
|
47
|
+
* to spaces rather than removed so every column after it — and therefore any
|
|
48
|
+
* real link later on the same line — keeps its position.
|
|
49
|
+
*/
|
|
50
|
+
const CODE_SPAN_RE = /(`+)(?:[^`]|(?!\1)`)*\1/g;
|
|
51
|
+
/**
|
|
52
|
+
* Every link in `md`, in document order.
|
|
53
|
+
*
|
|
54
|
+
* The whole document is scanned, frontmatter included: a YAML `see: [x](y.md)`
|
|
55
|
+
* is not a link loam wrote a field for, and the alternative — teaching this
|
|
56
|
+
* module where frontmatter ends — would make it read the one part of a document
|
|
57
|
+
* loam's own doctrine says is structured. A link that resolves is a link that
|
|
58
|
+
* resolves wherever it is written.
|
|
59
|
+
*/
|
|
60
|
+
export function documentLinks(md) {
|
|
61
|
+
const fenced = fenceTracker();
|
|
62
|
+
const out = [];
|
|
63
|
+
md.split(/\r?\n/).forEach((rawLine, i) => {
|
|
64
|
+
if (fenced(rawLine))
|
|
65
|
+
return;
|
|
66
|
+
const line = rawLine.replace(CODE_SPAN_RE, (m) => " ".repeat(m.length));
|
|
67
|
+
const definition = DEFINITION_RE.exec(line);
|
|
68
|
+
if (definition) {
|
|
69
|
+
push(out, definition[2], definition[1], i + 1);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
INLINE_RE.lastIndex = 0;
|
|
73
|
+
for (let m = INLINE_RE.exec(line); m !== null; m = INLINE_RE.exec(line)) {
|
|
74
|
+
push(out, m[2], m[1], i + 1);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Record one link, unless its target is not a path this repository can answer
|
|
81
|
+
* for. Four exclusions, each of them a question with no filesystem answer
|
|
82
|
+
* rather than a link loam declines to grade:
|
|
83
|
+
*
|
|
84
|
+
* - an EMPTY target (`[text]()`) addresses nothing;
|
|
85
|
+
* - a SCHEME (`https:`, `mailto:`, and a Windows `C:` drive with it) addresses
|
|
86
|
+
* something outside this repository;
|
|
87
|
+
* - a ROOT-relative or protocol-relative target (`/x`, `//host/x`) is resolved
|
|
88
|
+
* by whatever renders the document — a site root, not the file's directory —
|
|
89
|
+
* so loam does not know what it points at;
|
|
90
|
+
* - a PURE fragment (`#section`) addresses this same document, and grading it
|
|
91
|
+
* means resolving heading anchors, which is a different question from "does
|
|
92
|
+
* this file exist".
|
|
93
|
+
*
|
|
94
|
+
* The last two are DEFENSIVE rather than decisive, and a mutation run says so:
|
|
95
|
+
* removing either leaves every test green, because a pure fragment leaves an
|
|
96
|
+
* empty path and a site-root target resolves outside the docs repo, where
|
|
97
|
+
* `./findings.ts` declines to answer anyway. They are kept because the reason
|
|
98
|
+
* differs from that boundary's — loam is not silent about these because they
|
|
99
|
+
* are elsewhere, it is silent because it does not know where they are — and a
|
|
100
|
+
* later reader deleting them as dead would be removing an intention, not a
|
|
101
|
+
* branch.
|
|
102
|
+
*/
|
|
103
|
+
function push(out, target, text, line) {
|
|
104
|
+
const raw = target.startsWith("<") && target.endsWith(">") ? target.slice(1, -1) : target;
|
|
105
|
+
if (raw === "" || raw.startsWith("#") || raw.startsWith("/"))
|
|
106
|
+
return;
|
|
107
|
+
if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(raw))
|
|
108
|
+
return;
|
|
109
|
+
const path = decodePath(raw.split("#")[0]);
|
|
110
|
+
if (path === "")
|
|
111
|
+
return;
|
|
112
|
+
out.push({ raw, path, text, line });
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Percent-decode a link target, or keep it verbatim when it does not decode.
|
|
116
|
+
*
|
|
117
|
+
* `[Order line](order%20line.md)` is how every editor writes a path holding a
|
|
118
|
+
* space, so a resolver that skipped this step would report the one spelling
|
|
119
|
+
* authors do not type by hand. `decodeURIComponent` throws on a lone `%` — a
|
|
120
|
+
* literal percent in a filename is legal and rarer than the escape — and the
|
|
121
|
+
* honest answer there is the string as written, which then resolves or does not
|
|
122
|
+
* on its own terms.
|
|
123
|
+
*/
|
|
124
|
+
function decodePath(raw) {
|
|
125
|
+
try {
|
|
126
|
+
return decodeURIComponent(raw);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return raw;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Re-express every relative link in `md` from a new base directory — the merge's
|
|
134
|
+
* half of the link convention.
|
|
135
|
+
*
|
|
136
|
+
* THE DEFECT THIS CLOSES is structural and predates the glossary. A feature's
|
|
137
|
+
* `specs/<svc>/spec.md` sits four directories below the docs root; the living
|
|
138
|
+
* `services/<svc>/spec.md` it merges into sits two. `loam archive` copies a
|
|
139
|
+
* requirement's text verbatim, so `[Order](../../../../glossary/order.md)` —
|
|
140
|
+
* correct where it was written, and clickable in the pull request that reviewed
|
|
141
|
+
* it — lands in the living document pointing two directories above the
|
|
142
|
+
* repository. The same is true of a delta requirement citing an ADR, which has
|
|
143
|
+
* been possible since before this module existed.
|
|
144
|
+
*
|
|
145
|
+
* REWRITING IS THE ONLY ANSWER THAT KEEPS BOTH PROPERTIES. The alternative
|
|
146
|
+
* considered was to have authors write the link relative to where the text will
|
|
147
|
+
* END UP, leaving loam to touch nothing — but that link does not resolve in the
|
|
148
|
+
* delta, and "it renders as a link in pull-request review, which is where these
|
|
149
|
+
* documents are actually read" is the convention's own first argument. So the
|
|
150
|
+
* author writes what is true where they write it, and the merge makes it true
|
|
151
|
+
* where it lands. The target is unchanged: only the route to it is.
|
|
152
|
+
*
|
|
153
|
+
* It is a positional rewrite, never a re-render: the matched target's own span
|
|
154
|
+
* is replaced and every other byte of the line — the link text, the title, the
|
|
155
|
+
* prose around it — is left exactly as written.
|
|
156
|
+
*
|
|
157
|
+
* WHEN THE TARGET MOVES TOO, `retarget` says where to. The same archive that
|
|
158
|
+
* moves a requirement two directories up moves the rest of the feature as
|
|
159
|
+
* well: a term the feature defines is copied into `glossary/`, and the feature
|
|
160
|
+
* directory itself — its ADRs, its intent — goes to `features/archive/<FEAT>/`.
|
|
161
|
+
* A link into the feature re-expressed against the target's OLD place was
|
|
162
|
+
* therefore re-expressed correctly and still rotted on the commit that made it.
|
|
163
|
+
* And a document that does not move at all can still need rewriting, when the
|
|
164
|
+
* directory it links into does (`subsystem move`) — which is why `from === to`
|
|
165
|
+
* is no longer a reason to stop when a `retarget` is given.
|
|
166
|
+
*
|
|
167
|
+
* A LINK WHOSE TEXT STILL REACHES ITS TARGET FROM THE NEW PLACE KEEPS ITS
|
|
168
|
+
* SPELLING: a sibling that moves with its document, or a target nothing moved
|
|
169
|
+
* under a document that stays, comes out of the rewrite exactly as the author
|
|
170
|
+
* wrote it rather than normalised into `./` form by a commit that had no
|
|
171
|
+
* reason to touch it.
|
|
172
|
+
*/
|
|
173
|
+
export function rebaseLinks(md, move) {
|
|
174
|
+
const from = resolve(move.from);
|
|
175
|
+
const to = resolve(move.to);
|
|
176
|
+
if (from === to && move.retarget === undefined)
|
|
177
|
+
return md;
|
|
178
|
+
const route = { from, to, retarget: move.retarget ?? ((target) => target) };
|
|
179
|
+
const fenced = fenceTracker();
|
|
180
|
+
// `split` with a capturing group keeps the separators, so a document's own
|
|
181
|
+
// mixture of CRLF and LF survives a rewrite that touches neither.
|
|
182
|
+
const parts = md.split(/(\r?\n)/);
|
|
183
|
+
for (let i = 0; i < parts.length; i += 2) {
|
|
184
|
+
const rawLine = parts[i];
|
|
185
|
+
if (fenced(rawLine))
|
|
186
|
+
continue;
|
|
187
|
+
parts[i] = rebaseLine(rawLine, route);
|
|
188
|
+
}
|
|
189
|
+
return parts.join("");
|
|
190
|
+
}
|
|
191
|
+
/** One line's links re-expressed, right to left so earlier spans keep their offsets. */
|
|
192
|
+
function rebaseLine(rawLine, route) {
|
|
193
|
+
const blanked = rawLine.replace(CODE_SPAN_RE, (m) => " ".repeat(m.length));
|
|
194
|
+
const spans = [];
|
|
195
|
+
const collect = (m) => {
|
|
196
|
+
const at = m.indices?.[2];
|
|
197
|
+
if (at === undefined)
|
|
198
|
+
return;
|
|
199
|
+
const rebased = rebaseTarget(m[2], route);
|
|
200
|
+
if (rebased !== null)
|
|
201
|
+
spans.push([at[0], at[1], rebased]);
|
|
202
|
+
};
|
|
203
|
+
const definition = DEFINITION_RE.exec(blanked);
|
|
204
|
+
if (definition)
|
|
205
|
+
collect(definition);
|
|
206
|
+
else {
|
|
207
|
+
INLINE_RE.lastIndex = 0;
|
|
208
|
+
for (let m = INLINE_RE.exec(blanked); m !== null; m = INLINE_RE.exec(blanked))
|
|
209
|
+
collect(m);
|
|
210
|
+
}
|
|
211
|
+
let out = rawLine;
|
|
212
|
+
for (const [start, end, replacement] of spans.reverse()) {
|
|
213
|
+
out = out.slice(0, start) + replacement + out.slice(end);
|
|
214
|
+
}
|
|
215
|
+
return out;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* One target, re-expressed from `to` instead of `from` — and pointed at wherever
|
|
219
|
+
* `retarget` says the file itself will be — or null when there is nothing to
|
|
220
|
+
* re-express.
|
|
221
|
+
*
|
|
222
|
+
* The exclusions are `push`'s exactly — an absolute URL, a site-root path and a
|
|
223
|
+
* bare fragment mean the same thing from every directory — and the ANGLE-BRACKET
|
|
224
|
+
* and PERCENT-ESCAPE forms are preserved rather than normalised: a rewrite that
|
|
225
|
+
* silently changed `<a b.md>` into `a%20b.md` would be editing the author's
|
|
226
|
+
* spelling under cover of moving their file. A route that comes out unchanged
|
|
227
|
+
* is null for the same reason (`rebaseLinks` says when that happens).
|
|
228
|
+
*/
|
|
229
|
+
function rebaseTarget(target, route) {
|
|
230
|
+
const angled = target.startsWith("<") && target.endsWith(">");
|
|
231
|
+
const raw = angled ? target.slice(1, -1) : target;
|
|
232
|
+
if (raw === "" || raw.startsWith("#") || raw.startsWith("/"))
|
|
233
|
+
return null;
|
|
234
|
+
if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(raw))
|
|
235
|
+
return null;
|
|
236
|
+
const hash = raw.indexOf("#");
|
|
237
|
+
const pathPart = hash === -1 ? raw : raw.slice(0, hash);
|
|
238
|
+
const fragment = hash === -1 ? "" : raw.slice(hash);
|
|
239
|
+
if (pathPart === "")
|
|
240
|
+
return null;
|
|
241
|
+
const encoded = pathPart.includes("%");
|
|
242
|
+
const was = resolve(route.from, decodePath(pathPart));
|
|
243
|
+
const will = resolve(route.retarget(was));
|
|
244
|
+
// The author's TEXT, read from the new place, still reaching the target —
|
|
245
|
+
// not two computed routes compared. A link that climbs above a moved
|
|
246
|
+
// directory and comes back down through its old name
|
|
247
|
+
// (`../../../services/payment-service/spec.md` from inside that service)
|
|
248
|
+
// normalises to the same route either side of the move, and comparing
|
|
249
|
+
// routes kept a spelling that names a directory the move just removed.
|
|
250
|
+
if (resolve(route.to, decodePath(pathPart)) === will)
|
|
251
|
+
return null;
|
|
252
|
+
let rebased = relative(route.to, will).split(sep).join("/");
|
|
253
|
+
// `relative` returns a bare name for a sibling, which markdown reads as a
|
|
254
|
+
// path relative to the file anyway — but `./` is what an author writes and
|
|
255
|
+
// what keeps the link distinguishable from a reference label.
|
|
256
|
+
if (rebased !== "" && !rebased.startsWith("."))
|
|
257
|
+
rebased = `./${rebased}`;
|
|
258
|
+
if (rebased === "")
|
|
259
|
+
return null;
|
|
260
|
+
if (!angled && (encoded || rebased.includes(" ")))
|
|
261
|
+
rebased = rebased.split(" ").join("%20");
|
|
262
|
+
const rewritten = rebased + fragment;
|
|
263
|
+
return angled ? `<${rewritten}>` : rewritten;
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/core/links/parse.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Every markdown link a document writes, as data.\n *\n * A link between documents in a docs repo is a JOIN, not decoration — a\n * requirement that names a domain term points at that term's definition, and an\n * ADR that supersedes another says which. `SCHEMA.md` and the generated\n * `AGENTS.md` have stated the convention (standard markdown links, relative\n * path targets) since the fleet-ADR work; this module is what finally reads\n * one, so `./findings.ts` can answer the only question the convention was\n * chosen for: does the target exist.\n *\n * WHY A PARSER RATHER THAN A REGEX AT THE CALL SITE. Two classes of false\n * positive make the naive `\\[.*\\]\\(.*\\)` unusable on the documents loam owns,\n * and both occur in loam's OWN generated prose. A fenced block is where a\n * document SHOWS the convention — the `AGENTS.md` section that teaches the link\n * format contains a link nobody wrote to be followed — and an inline code span\n * is where prose quotes a path. Both must read as text. The fence rule is the\n * one `core/document/parse.ts` already applies to headings, and it is imported\n * rather than restated for the reason that module gives about its own sampler:\n * two readers disagreeing about what a fence encloses prescribe a document no\n * author can satisfy.\n */\nimport { relative, resolve, sep } from \"node:path\";\nimport { fenceTracker } from \"../kernel/fences.js\";\n\n/** One link written in a markdown document. */\nexport interface DocumentLink {\n /** The target exactly as written, angle brackets stripped, fragment included. */\n raw: string;\n /**\n * The FILE half — `raw` with any `#fragment` removed and percent-escapes\n * decoded. This is what resolves against the filesystem; `raw` is what the\n * finding quotes back, because that is the string the author has to find.\n */\n path: string;\n /** The link text, or the reference label for a definition. Quoted in the finding. */\n text: string;\n /** 1-based line the link was written on. */\n line: number;\n}\n\n/**\n * Inline links and images: `[text](target)`, ``,\n * `[text](<target with spaces>)`, `[text](target \"title\")`.\n *\n * The target alternation takes `<...>` first so an angle-bracketed path\n * containing spaces stays one token; the bare form stops at whitespace or `)`,\n * which gives up on the balanced-parens spelling markdown also allows\n * (`[x](a(1).md)`). That is a deliberate under-read: it costs a link nobody\n * writes, where over-reading would swallow the rest of a sentence and report a\n * target no author would recognise.\n */\nconst INLINE_RE = /!?\\[([^\\]]*)\\]\\(\\s*(<[^>\\n]*>|[^\\s)]*)(?:\\s+(?:\"[^\"]*\"|'[^']*'|\\([^)]*\\)))?\\s*\\)/gd;\n\n/**\n * A reference DEFINITION — `[label]: target \"title\"` on its own line. Included\n * because the target is the same join written in a different place: a document\n * that collects its links at the bottom is following the convention, and a\n * reader that only saw inline links would grade it as having none.\n */\nconst DEFINITION_RE = /^ {0,3}\\[([^\\]]+)\\]:\\s*(<[^>\\n]*>|\\S+)/d;\n\n/**\n * Code spans, blanked before matching. `\\`[a](b)\\`` is prose ABOUT a link and\n * resolving it would convict a document for explaining the convention. Blanked\n * to spaces rather than removed so every column after it — and therefore any\n * real link later on the same line — keeps its position.\n */\nconst CODE_SPAN_RE = /(`+)(?:[^`]|(?!\\1)`)*\\1/g;\n\n/**\n * Every link in `md`, in document order.\n *\n * The whole document is scanned, frontmatter included: a YAML `see: [x](y.md)`\n * is not a link loam wrote a field for, and the alternative — teaching this\n * module where frontmatter ends — would make it read the one part of a document\n * loam's own doctrine says is structured. A link that resolves is a link that\n * resolves wherever it is written.\n */\nexport function documentLinks(md: string): DocumentLink[] {\n const fenced = fenceTracker();\n const out: DocumentLink[] = [];\n md.split(/\\r?\\n/).forEach((rawLine, i) => {\n if (fenced(rawLine)) return;\n const line = rawLine.replace(CODE_SPAN_RE, (m) => \" \".repeat(m.length));\n const definition = DEFINITION_RE.exec(line);\n if (definition) {\n push(out, definition[2]!, definition[1]!, i + 1);\n return;\n }\n INLINE_RE.lastIndex = 0;\n for (let m = INLINE_RE.exec(line); m !== null; m = INLINE_RE.exec(line)) {\n push(out, m[2]!, m[1]!, i + 1);\n }\n });\n return out;\n}\n\n/**\n * Record one link, unless its target is not a path this repository can answer\n * for. Four exclusions, each of them a question with no filesystem answer\n * rather than a link loam declines to grade:\n *\n * - an EMPTY target (`[text]()`) addresses nothing;\n * - a SCHEME (`https:`, `mailto:`, and a Windows `C:` drive with it) addresses\n * something outside this repository;\n * - a ROOT-relative or protocol-relative target (`/x`, `//host/x`) is resolved\n * by whatever renders the document — a site root, not the file's directory —\n * so loam does not know what it points at;\n * - a PURE fragment (`#section`) addresses this same document, and grading it\n * means resolving heading anchors, which is a different question from \"does\n * this file exist\".\n *\n * The last two are DEFENSIVE rather than decisive, and a mutation run says so:\n * removing either leaves every test green, because a pure fragment leaves an\n * empty path and a site-root target resolves outside the docs repo, where\n * `./findings.ts` declines to answer anyway. They are kept because the reason\n * differs from that boundary's — loam is not silent about these because they\n * are elsewhere, it is silent because it does not know where they are — and a\n * later reader deleting them as dead would be removing an intention, not a\n * branch.\n */\nfunction push(out: DocumentLink[], target: string, text: string, line: number): void {\n const raw = target.startsWith(\"<\") && target.endsWith(\">\") ? target.slice(1, -1) : target;\n if (raw === \"\" || raw.startsWith(\"#\") || raw.startsWith(\"/\")) return;\n if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(raw)) return;\n const path = decodePath(raw.split(\"#\")[0]!);\n if (path === \"\") return;\n out.push({ raw, path, text, line });\n}\n\n/**\n * Percent-decode a link target, or keep it verbatim when it does not decode.\n *\n * `[Order line](order%20line.md)` is how every editor writes a path holding a\n * space, so a resolver that skipped this step would report the one spelling\n * authors do not type by hand. `decodeURIComponent` throws on a lone `%` — a\n * literal percent in a filename is legal and rarer than the escape — and the\n * honest answer there is the string as written, which then resolves or does not\n * on its own terms.\n */\nfunction decodePath(raw: string): string {\n try {\n return decodeURIComponent(raw);\n } catch {\n return raw;\n }\n}\n\n/**\n * Re-express every relative link in `md` from a new base directory — the merge's\n * half of the link convention.\n *\n * THE DEFECT THIS CLOSES is structural and predates the glossary. A feature's\n * `specs/<svc>/spec.md` sits four directories below the docs root; the living\n * `services/<svc>/spec.md` it merges into sits two. `loam archive` copies a\n * requirement's text verbatim, so `[Order](../../../../glossary/order.md)` —\n * correct where it was written, and clickable in the pull request that reviewed\n * it — lands in the living document pointing two directories above the\n * repository. The same is true of a delta requirement citing an ADR, which has\n * been possible since before this module existed.\n *\n * REWRITING IS THE ONLY ANSWER THAT KEEPS BOTH PROPERTIES. The alternative\n * considered was to have authors write the link relative to where the text will\n * END UP, leaving loam to touch nothing — but that link does not resolve in the\n * delta, and \"it renders as a link in pull-request review, which is where these\n * documents are actually read\" is the convention's own first argument. So the\n * author writes what is true where they write it, and the merge makes it true\n * where it lands. The target is unchanged: only the route to it is.\n *\n * It is a positional rewrite, never a re-render: the matched target's own span\n * is replaced and every other byte of the line — the link text, the title, the\n * prose around it — is left exactly as written.\n *\n * WHEN THE TARGET MOVES TOO, `retarget` says where to. The same archive that\n * moves a requirement two directories up moves the rest of the feature as\n * well: a term the feature defines is copied into `glossary/`, and the feature\n * directory itself — its ADRs, its intent — goes to `features/archive/<FEAT>/`.\n * A link into the feature re-expressed against the target's OLD place was\n * therefore re-expressed correctly and still rotted on the commit that made it.\n * And a document that does not move at all can still need rewriting, when the\n * directory it links into does (`subsystem move`) — which is why `from === to`\n * is no longer a reason to stop when a `retarget` is given.\n *\n * A LINK WHOSE TEXT STILL REACHES ITS TARGET FROM THE NEW PLACE KEEPS ITS\n * SPELLING: a sibling that moves with its document, or a target nothing moved\n * under a document that stays, comes out of the rewrite exactly as the author\n * wrote it rather than normalised into `./` form by a commit that had no\n * reason to touch it.\n */\nexport function rebaseLinks(md: string, move: LinkMove): string {\n const from = resolve(move.from);\n const to = resolve(move.to);\n if (from === to && move.retarget === undefined) return md;\n const route: Route = { from, to, retarget: move.retarget ?? ((target) => target) };\n const fenced = fenceTracker();\n // `split` with a capturing group keeps the separators, so a document's own\n // mixture of CRLF and LF survives a rewrite that touches neither.\n const parts = md.split(/(\\r?\\n)/);\n for (let i = 0; i < parts.length; i += 2) {\n const rawLine = parts[i]!;\n if (fenced(rawLine)) continue;\n parts[i] = rebaseLine(rawLine, route);\n }\n return parts.join(\"\");\n}\n\n/** Where a document's text is moving, and where each file it links to will be. */\nexport interface LinkMove {\n /** The directory the text was written in. */\n from: string;\n /** The directory the text will be read from. */\n to: string;\n /**\n * Where a link's target will be once the same change lands: an absolute path\n * in, an absolute path out, the input itself for a target that stays put.\n * Omitted, every target stays put — the requirement merge's original case.\n */\n retarget?: (target: string) => string;\n}\n\n/** `LinkMove` with both directories resolved and the retarget defaulted — what each line is rewritten against. */\ninterface Route {\n from: string;\n to: string;\n retarget: (target: string) => string;\n}\n\n/** One line's links re-expressed, right to left so earlier spans keep their offsets. */\nfunction rebaseLine(rawLine: string, route: Route): string {\n const blanked = rawLine.replace(CODE_SPAN_RE, (m) => \" \".repeat(m.length));\n const spans: Array<[number, number, string]> = [];\n const collect = (m: RegExpExecArray): void => {\n const at = m.indices?.[2];\n if (at === undefined) return;\n const rebased = rebaseTarget(m[2]!, route);\n if (rebased !== null) spans.push([at[0], at[1], rebased]);\n };\n const definition = DEFINITION_RE.exec(blanked);\n if (definition) collect(definition);\n else {\n INLINE_RE.lastIndex = 0;\n for (let m = INLINE_RE.exec(blanked); m !== null; m = INLINE_RE.exec(blanked)) collect(m);\n }\n let out = rawLine;\n for (const [start, end, replacement] of spans.reverse()) {\n out = out.slice(0, start) + replacement + out.slice(end);\n }\n return out;\n}\n\n/**\n * One target, re-expressed from `to` instead of `from` — and pointed at wherever\n * `retarget` says the file itself will be — or null when there is nothing to\n * re-express.\n *\n * The exclusions are `push`'s exactly — an absolute URL, a site-root path and a\n * bare fragment mean the same thing from every directory — and the ANGLE-BRACKET\n * and PERCENT-ESCAPE forms are preserved rather than normalised: a rewrite that\n * silently changed `<a b.md>` into `a%20b.md` would be editing the author's\n * spelling under cover of moving their file. A route that comes out unchanged\n * is null for the same reason (`rebaseLinks` says when that happens).\n */\nfunction rebaseTarget(target: string, route: Route): string | null {\n const angled = target.startsWith(\"<\") && target.endsWith(\">\");\n const raw = angled ? target.slice(1, -1) : target;\n if (raw === \"\" || raw.startsWith(\"#\") || raw.startsWith(\"/\")) return null;\n if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(raw)) return null;\n const hash = raw.indexOf(\"#\");\n const pathPart = hash === -1 ? raw : raw.slice(0, hash);\n const fragment = hash === -1 ? \"\" : raw.slice(hash);\n if (pathPart === \"\") return null;\n const encoded = pathPart.includes(\"%\");\n const was = resolve(route.from, decodePath(pathPart));\n const will = resolve(route.retarget(was));\n // The author's TEXT, read from the new place, still reaching the target —\n // not two computed routes compared. A link that climbs above a moved\n // directory and comes back down through its old name\n // (`../../../services/payment-service/spec.md` from inside that service)\n // normalises to the same route either side of the move, and comparing\n // routes kept a spelling that names a directory the move just removed.\n if (resolve(route.to, decodePath(pathPart)) === will) return null;\n let rebased = relative(route.to, will).split(sep).join(\"/\");\n // `relative` returns a bare name for a sibling, which markdown reads as a\n // path relative to the file anyway — but `./` is what an author writes and\n // what keeps the link distinguishable from a reference label.\n if (rebased !== \"\" && !rebased.startsWith(\".\")) rebased = `./${rebased}`;\n if (rebased === \"\") return null;\n if (!angled && (encoded || rebased.includes(\" \"))) rebased = rebased.split(\" \").join(\"%20\");\n const rewritten = rebased + fragment;\n return angled ? `<${rewritten}>` : rewritten;\n}\n"]}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The MCP inputSchema for one tool: a closed object, so a typo'd argument
|
|
3
|
+
* refuses instead of vanishing, with the required set and the positional order
|
|
4
|
+
* `toArgv` enforces declared beside it.
|
|
5
|
+
*/
|
|
6
|
+
export function toInputSchema(tool) {
|
|
7
|
+
const properties = {};
|
|
8
|
+
for (const positional of tool.positionals) {
|
|
9
|
+
properties[positional.property] = positional.variadic
|
|
10
|
+
? { type: "array", items: { type: "string" }, description: positional.description }
|
|
11
|
+
: { type: "string", description: positional.description };
|
|
12
|
+
}
|
|
13
|
+
for (const flag of tool.flags) {
|
|
14
|
+
properties[flag.property] =
|
|
15
|
+
flag.kind === "boolean"
|
|
16
|
+
? { type: "boolean", description: flag.description }
|
|
17
|
+
: flag.kind === "strings"
|
|
18
|
+
? { type: "array", items: { type: "string" }, description: flag.description }
|
|
19
|
+
: { type: "string", description: flag.description };
|
|
20
|
+
}
|
|
21
|
+
const required = [
|
|
22
|
+
...tool.positionals.filter((p) => p.required).map((p) => p.property),
|
|
23
|
+
...tool.flags.filter((f) => f.required === true).map((f) => f.property),
|
|
24
|
+
];
|
|
25
|
+
return {
|
|
26
|
+
type: "object",
|
|
27
|
+
properties,
|
|
28
|
+
...(required.length > 0 ? { required } : {}),
|
|
29
|
+
...orderRule(tool),
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The rule `positionalTokens` enforces, declared: a positional after an
|
|
35
|
+
* optional one needs it, because positionals reach argv by position and the
|
|
36
|
+
* later value would otherwise be read in the earlier one's slot. Without it a
|
|
37
|
+
* client that validated `{name: "smoke"}` for `loam_list` against the schema
|
|
38
|
+
* it was given passed, and was then refused `-32602` by the server.
|
|
39
|
+
*
|
|
40
|
+
* Read off the declaration order rather than spelled per tool, so a tool that
|
|
41
|
+
* gains a positional after an optional one is declared the day it is refused.
|
|
42
|
+
* Each later positional needs every earlier OPTIONAL one; an earlier required
|
|
43
|
+
* one is in `required` already.
|
|
44
|
+
*
|
|
45
|
+
* Two keywords, because presence means two things. A scalar that is present
|
|
46
|
+
* always yields a token, so presence is the whole condition and
|
|
47
|
+
* `dependentRequired` says exactly that. A variadic yields tokens only when it
|
|
48
|
+
* has members: an empty one moves nothing into anybody's slot, and
|
|
49
|
+
* `positionalTokens` serves it — `{args: []}` with no `workflow` is the
|
|
50
|
+
* workflow list. `dependentRequired` there would forbid a call the server
|
|
51
|
+
* answers, the same disagreement turned the other way, so the variadic's rule
|
|
52
|
+
* sits under `dependentSchemas`: once it is present, either the earlier ones
|
|
53
|
+
* are too or it is empty. `anyOf` rather than `if`/`then`, which says the same
|
|
54
|
+
* but puts a `then` key on an object, and a thenable literal is one `await`
|
|
55
|
+
* away from being called.
|
|
56
|
+
*/
|
|
57
|
+
function orderRule(tool) {
|
|
58
|
+
const dependentRequired = {};
|
|
59
|
+
const dependentSchemas = {};
|
|
60
|
+
const earlier = [];
|
|
61
|
+
for (const positional of tool.positionals) {
|
|
62
|
+
if (earlier.length > 0 && positional.variadic) {
|
|
63
|
+
dependentSchemas[positional.property] = {
|
|
64
|
+
anyOf: [{ required: [...earlier] }, { properties: { [positional.property]: { maxItems: 0 } } }],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
else if (earlier.length > 0) {
|
|
68
|
+
dependentRequired[positional.property] = [...earlier];
|
|
69
|
+
}
|
|
70
|
+
if (!positional.required)
|
|
71
|
+
earlier.push(positional.property);
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
...(Object.keys(dependentRequired).length > 0 ? { dependentRequired } : {}),
|
|
75
|
+
...(Object.keys(dependentSchemas).length > 0 ? { dependentSchemas } : {}),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A string value that argv would read as a flag is refused before any command
|
|
80
|
+
* sees it: {"target": "--type"} must not become a parsed option. Commander
|
|
81
|
+
* cannot make this distinction after the fact — by then the token IS a flag —
|
|
82
|
+
* so the boundary is here, on every string that crosses, array members
|
|
83
|
+
* included. No shell is ever involved, so this is the only smuggling path.
|
|
84
|
+
*/
|
|
85
|
+
function smuggled(property, value) {
|
|
86
|
+
return value.startsWith("-")
|
|
87
|
+
? `argument '${property}' value '${value}' begins with '-' — a value argv would read as a flag is refused`
|
|
88
|
+
: null;
|
|
89
|
+
}
|
|
90
|
+
/** One string value checked for type and smuggling. */
|
|
91
|
+
function checkedString(property, value) {
|
|
92
|
+
if (typeof value !== "string")
|
|
93
|
+
return { ok: false, problem: `argument '${property}' must be a string` };
|
|
94
|
+
const bad = smuggled(property, value);
|
|
95
|
+
return bad === null ? { ok: true, tokens: [value] } : { ok: false, problem: bad };
|
|
96
|
+
}
|
|
97
|
+
/** An array value checked member by member — rebuilt, not cast, so the claim is earned. */
|
|
98
|
+
function checkedStrings(property, value) {
|
|
99
|
+
if (!Array.isArray(value))
|
|
100
|
+
return { ok: false, problem: `argument '${property}' must be an array of strings` };
|
|
101
|
+
const tokens = [];
|
|
102
|
+
for (const entry of value) {
|
|
103
|
+
const checked = checkedString(property, entry);
|
|
104
|
+
if (!checked.ok)
|
|
105
|
+
return checked;
|
|
106
|
+
tokens.push(...checked.tokens);
|
|
107
|
+
}
|
|
108
|
+
return { ok: true, tokens };
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The positionals, in declaration order — and refused when one would land in
|
|
112
|
+
* another's slot.
|
|
113
|
+
*
|
|
114
|
+
* A positional reaches argv by POSITION, so an optional one left out leaves no
|
|
115
|
+
* gap: whatever follows it moves up into its place. `loam_list` with `{name:
|
|
116
|
+
* "services"}` built `list services` and answered ok:true with the services
|
|
117
|
+
* listing, a wrong answer with nothing in it saying so; `loam_instructions`
|
|
118
|
+
* with `{args: [...]}` and no `workflow` read the first arg as the workflow.
|
|
119
|
+
* Refused here instead, as the invalid-params problem a missing REQUIRED
|
|
120
|
+
* positional already is, naming the slot the caller left empty. A later
|
|
121
|
+
* positional that yields no token — an empty variadic — moves nothing up, so
|
|
122
|
+
* it passes. `orderRule` above declares the same rule in the advertised
|
|
123
|
+
* schema; the two change together.
|
|
124
|
+
*/
|
|
125
|
+
function positionalTokens(tool, args) {
|
|
126
|
+
const tokens = [];
|
|
127
|
+
let absent;
|
|
128
|
+
for (const positional of tool.positionals) {
|
|
129
|
+
const value = args[positional.property];
|
|
130
|
+
if (value === undefined) {
|
|
131
|
+
if (positional.required)
|
|
132
|
+
return { ok: false, problem: `required argument '${positional.property}' is missing` };
|
|
133
|
+
absent ??= positional.property;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const checked = positional.variadic
|
|
137
|
+
? checkedStrings(positional.property, value)
|
|
138
|
+
: checkedString(positional.property, value);
|
|
139
|
+
if (!checked.ok)
|
|
140
|
+
return checked;
|
|
141
|
+
if (absent !== undefined && checked.tokens.length > 0) {
|
|
142
|
+
return {
|
|
143
|
+
ok: false,
|
|
144
|
+
problem: `argument '${positional.property}' requires '${absent}' — positionals are read in order, ` +
|
|
145
|
+
`so without '${absent}' this value would be read as '${absent}'`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
tokens.push(...checked.tokens);
|
|
149
|
+
}
|
|
150
|
+
return { ok: true, tokens };
|
|
151
|
+
}
|
|
152
|
+
function flagTokens(tool, args) {
|
|
153
|
+
const tokens = [];
|
|
154
|
+
for (const flag of tool.flags) {
|
|
155
|
+
const value = args[flag.property];
|
|
156
|
+
if (value === undefined) {
|
|
157
|
+
// The same refusal absent required positionals get: the client learns
|
|
158
|
+
// "-32602 missing argument", not an invalid-option envelope after the
|
|
159
|
+
// command already refused.
|
|
160
|
+
if (flag.required === true)
|
|
161
|
+
return { ok: false, problem: `required argument '${flag.property}' is missing` };
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (flag.kind === "boolean") {
|
|
165
|
+
if (typeof value !== "boolean")
|
|
166
|
+
return { ok: false, problem: `argument '${flag.property}' must be a boolean` };
|
|
167
|
+
if (value)
|
|
168
|
+
tokens.push(flag.flag);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const checked = flag.kind === "strings"
|
|
172
|
+
? checkedStrings(flag.property, value)
|
|
173
|
+
: checkedString(flag.property, value);
|
|
174
|
+
if (!checked.ok)
|
|
175
|
+
return checked;
|
|
176
|
+
// A repeatable flag repeats per value; a single-valued one appears once.
|
|
177
|
+
for (const token of checked.tokens)
|
|
178
|
+
tokens.push(flag.flag, token);
|
|
179
|
+
}
|
|
180
|
+
return { ok: true, tokens };
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* The argv for one tool call — or the invalid-params problem that stops it.
|
|
184
|
+
* `--json` is always appended: the envelope is the tool-result contract, and
|
|
185
|
+
* a client cannot opt out of it into the human rendering. Unknown argument
|
|
186
|
+
* names refuse rather than vanish — the schema says additionalProperties
|
|
187
|
+
* false, and a server that enforced that only in the schema would silently
|
|
188
|
+
* drop the typo'd argument of any client that skipped validation.
|
|
189
|
+
*/
|
|
190
|
+
export function toArgv(tool, args) {
|
|
191
|
+
const known = new Set([
|
|
192
|
+
...tool.positionals.map((p) => p.property),
|
|
193
|
+
...tool.flags.map((f) => f.property),
|
|
194
|
+
]);
|
|
195
|
+
for (const property of Object.keys(args)) {
|
|
196
|
+
if (!known.has(property)) {
|
|
197
|
+
const allowed = known.size === 0 ? "no arguments" : [...known].join(", ");
|
|
198
|
+
return { ok: false, problem: `unknown argument '${property}' for ${tool.name} — expected ${allowed}` };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const positionals = positionalTokens(tool, args);
|
|
202
|
+
if (!positionals.ok)
|
|
203
|
+
return { ok: false, problem: positionals.problem };
|
|
204
|
+
const flags = flagTokens(tool, args);
|
|
205
|
+
if (!flags.ok)
|
|
206
|
+
return { ok: false, problem: flags.problem };
|
|
207
|
+
return {
|
|
208
|
+
ok: true,
|
|
209
|
+
argv: [tool.command, ...positionals.tokens, ...flags.tokens, ...(tool.fixed ?? []), "--json"],
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=argv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argv.js","sourceRoot":"","sources":["../../../src/core/mcp/argv.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * How one MCP tool call's JSON arguments become an argv the CLI already\n * trusts — the boundary where an argument value could otherwise smuggle a\n * flag. The tool TABLE (what the tools are) lives in `./tools.ts`; this\n * module owns the crossing, and the inputSchema that declares it: the schema\n * a client validates against and the argv builder that refuses what it\n * forbids are one contract written twice, so they sit in one module.\n */\nimport type { McpTool } from \"./tools.js\";\n\n/**\n * The MCP inputSchema for one tool: a closed object, so a typo'd argument\n * refuses instead of vanishing, with the required set and the positional order\n * `toArgv` enforces declared beside it.\n */\nexport function toInputSchema(tool: McpTool): Record<string, unknown> {\n const properties: Record<string, unknown> = {};\n for (const positional of tool.positionals) {\n properties[positional.property] = positional.variadic\n ? { type: \"array\", items: { type: \"string\" }, description: positional.description }\n : { type: \"string\", description: positional.description };\n }\n for (const flag of tool.flags) {\n properties[flag.property] =\n flag.kind === \"boolean\"\n ? { type: \"boolean\", description: flag.description }\n : flag.kind === \"strings\"\n ? { type: \"array\", items: { type: \"string\" }, description: flag.description }\n : { type: \"string\", description: flag.description };\n }\n const required = [\n ...tool.positionals.filter((p) => p.required).map((p) => p.property),\n ...tool.flags.filter((f) => f.required === true).map((f) => f.property),\n ];\n return {\n type: \"object\",\n properties,\n ...(required.length > 0 ? { required } : {}),\n ...orderRule(tool),\n additionalProperties: false,\n };\n}\n\n/**\n * The rule `positionalTokens` enforces, declared: a positional after an\n * optional one needs it, because positionals reach argv by position and the\n * later value would otherwise be read in the earlier one's slot. Without it a\n * client that validated `{name: \"smoke\"}` for `loam_list` against the schema\n * it was given passed, and was then refused `-32602` by the server.\n *\n * Read off the declaration order rather than spelled per tool, so a tool that\n * gains a positional after an optional one is declared the day it is refused.\n * Each later positional needs every earlier OPTIONAL one; an earlier required\n * one is in `required` already.\n *\n * Two keywords, because presence means two things. A scalar that is present\n * always yields a token, so presence is the whole condition and\n * `dependentRequired` says exactly that. A variadic yields tokens only when it\n * has members: an empty one moves nothing into anybody's slot, and\n * `positionalTokens` serves it — `{args: []}` with no `workflow` is the\n * workflow list. `dependentRequired` there would forbid a call the server\n * answers, the same disagreement turned the other way, so the variadic's rule\n * sits under `dependentSchemas`: once it is present, either the earlier ones\n * are too or it is empty. `anyOf` rather than `if`/`then`, which says the same\n * but puts a `then` key on an object, and a thenable literal is one `await`\n * away from being called.\n */\nfunction orderRule(tool: McpTool): Record<string, unknown> {\n const dependentRequired: Record<string, string[]> = {};\n const dependentSchemas: Record<string, unknown> = {};\n const earlier: string[] = [];\n for (const positional of tool.positionals) {\n if (earlier.length > 0 && positional.variadic) {\n dependentSchemas[positional.property] = {\n anyOf: [{ required: [...earlier] }, { properties: { [positional.property]: { maxItems: 0 } } }],\n };\n } else if (earlier.length > 0) {\n dependentRequired[positional.property] = [...earlier];\n }\n if (!positional.required) earlier.push(positional.property);\n }\n return {\n ...(Object.keys(dependentRequired).length > 0 ? { dependentRequired } : {}),\n ...(Object.keys(dependentSchemas).length > 0 ? { dependentSchemas } : {}),\n };\n}\n\n/** One checked step of argv construction: the tokens it yields, or the invalid-params problem. */\ntype Checked =\n | { readonly ok: true; readonly tokens: readonly string[] }\n | { readonly ok: false; readonly problem: string };\n\nexport type ArgvOutcome =\n | { readonly ok: true; readonly argv: readonly string[] }\n | { readonly ok: false; readonly problem: string };\n\n/**\n * A string value that argv would read as a flag is refused before any command\n * sees it: {\"target\": \"--type\"} must not become a parsed option. Commander\n * cannot make this distinction after the fact — by then the token IS a flag —\n * so the boundary is here, on every string that crosses, array members\n * included. No shell is ever involved, so this is the only smuggling path.\n */\nfunction smuggled(property: string, value: string): string | null {\n return value.startsWith(\"-\")\n ? `argument '${property}' value '${value}' begins with '-' — a value argv would read as a flag is refused`\n : null;\n}\n\n/** One string value checked for type and smuggling. */\nfunction checkedString(property: string, value: unknown): Checked {\n if (typeof value !== \"string\") return { ok: false, problem: `argument '${property}' must be a string` };\n const bad = smuggled(property, value);\n return bad === null ? { ok: true, tokens: [value] } : { ok: false, problem: bad };\n}\n\n/** An array value checked member by member — rebuilt, not cast, so the claim is earned. */\nfunction checkedStrings(property: string, value: unknown): Checked {\n if (!Array.isArray(value)) return { ok: false, problem: `argument '${property}' must be an array of strings` };\n const tokens: string[] = [];\n for (const entry of value) {\n const checked = checkedString(property, entry);\n if (!checked.ok) return checked;\n tokens.push(...checked.tokens);\n }\n return { ok: true, tokens };\n}\n\n/**\n * The positionals, in declaration order — and refused when one would land in\n * another's slot.\n *\n * A positional reaches argv by POSITION, so an optional one left out leaves no\n * gap: whatever follows it moves up into its place. `loam_list` with `{name:\n * \"services\"}` built `list services` and answered ok:true with the services\n * listing, a wrong answer with nothing in it saying so; `loam_instructions`\n * with `{args: [...]}` and no `workflow` read the first arg as the workflow.\n * Refused here instead, as the invalid-params problem a missing REQUIRED\n * positional already is, naming the slot the caller left empty. A later\n * positional that yields no token — an empty variadic — moves nothing up, so\n * it passes. `orderRule` above declares the same rule in the advertised\n * schema; the two change together.\n */\nfunction positionalTokens(tool: McpTool, args: Record<string, unknown>): Checked {\n const tokens: string[] = [];\n let absent: string | undefined;\n for (const positional of tool.positionals) {\n const value = args[positional.property];\n if (value === undefined) {\n if (positional.required) return { ok: false, problem: `required argument '${positional.property}' is missing` };\n absent ??= positional.property;\n continue;\n }\n const checked = positional.variadic\n ? checkedStrings(positional.property, value)\n : checkedString(positional.property, value);\n if (!checked.ok) return checked;\n if (absent !== undefined && checked.tokens.length > 0) {\n return {\n ok: false,\n problem:\n `argument '${positional.property}' requires '${absent}' — positionals are read in order, ` +\n `so without '${absent}' this value would be read as '${absent}'`,\n };\n }\n tokens.push(...checked.tokens);\n }\n return { ok: true, tokens };\n}\n\nfunction flagTokens(tool: McpTool, args: Record<string, unknown>): Checked {\n const tokens: string[] = [];\n for (const flag of tool.flags) {\n const value = args[flag.property];\n if (value === undefined) {\n // The same refusal absent required positionals get: the client learns\n // \"-32602 missing argument\", not an invalid-option envelope after the\n // command already refused.\n if (flag.required === true) return { ok: false, problem: `required argument '${flag.property}' is missing` };\n continue;\n }\n if (flag.kind === \"boolean\") {\n if (typeof value !== \"boolean\") return { ok: false, problem: `argument '${flag.property}' must be a boolean` };\n if (value) tokens.push(flag.flag);\n continue;\n }\n const checked = flag.kind === \"strings\"\n ? checkedStrings(flag.property, value)\n : checkedString(flag.property, value);\n if (!checked.ok) return checked;\n // A repeatable flag repeats per value; a single-valued one appears once.\n for (const token of checked.tokens) tokens.push(flag.flag, token);\n }\n return { ok: true, tokens };\n}\n\n/**\n * The argv for one tool call — or the invalid-params problem that stops it.\n * `--json` is always appended: the envelope is the tool-result contract, and\n * a client cannot opt out of it into the human rendering. Unknown argument\n * names refuse rather than vanish — the schema says additionalProperties\n * false, and a server that enforced that only in the schema would silently\n * drop the typo'd argument of any client that skipped validation.\n */\nexport function toArgv(tool: McpTool, args: Record<string, unknown>): ArgvOutcome {\n const known = new Set([\n ...tool.positionals.map((p) => p.property),\n ...tool.flags.map((f) => f.property),\n ]);\n for (const property of Object.keys(args)) {\n if (!known.has(property)) {\n const allowed = known.size === 0 ? \"no arguments\" : [...known].join(\", \");\n return { ok: false, problem: `unknown argument '${property}' for ${tool.name} — expected ${allowed}` };\n }\n }\n const positionals = positionalTokens(tool, args);\n if (!positionals.ok) return { ok: false, problem: positionals.problem };\n const flags = flagTokens(tool, args);\n if (!flags.ok) return { ok: false, problem: flags.problem };\n return {\n ok: true,\n argv: [tool.command, ...positionals.tokens, ...flags.tokens, ...(tool.fixed ?? []), \"--json\"],\n };\n}\n"]}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const WRITE_ANNOTATIONS = {
|
|
2
|
+
readOnlyHint: false,
|
|
3
|
+
destructiveHint: false,
|
|
4
|
+
idempotentHint: false,
|
|
5
|
+
openWorldHint: false,
|
|
6
|
+
};
|
|
7
|
+
const SAFE_WRITE_ANNOTATIONS = {
|
|
8
|
+
...WRITE_ANNOTATIONS,
|
|
9
|
+
idempotentHint: true,
|
|
10
|
+
};
|
|
11
|
+
export const MCP_AUTHOR_TOOLS = [
|
|
12
|
+
{
|
|
13
|
+
name: "loam_new",
|
|
14
|
+
command: "new",
|
|
15
|
+
description: "Scaffold a feature in the docs repo. Opt-in writer; refuses an existing feature. " +
|
|
16
|
+
"CLI equivalent: loam new <featureId> [--title <text>] [--touches <id>...] [--new-service <id>...] [--capability <id>...] [--modifies <Req-ID>...] --json",
|
|
17
|
+
positionals: [
|
|
18
|
+
{ property: "featureId", required: true, variadic: false, description: "new feature id, e.g. FEAT-101" },
|
|
19
|
+
],
|
|
20
|
+
flags: [
|
|
21
|
+
{ property: "title", flag: "--title", kind: "string", description: "human title and directory slug" },
|
|
22
|
+
{ property: "touches", flag: "--touches", kind: "strings", description: "existing services changed; repeatable" },
|
|
23
|
+
{ property: "newServices", flag: "--new-service", kind: "strings", description: "services introduced; repeatable" },
|
|
24
|
+
{ property: "capabilities", flag: "--capability", kind: "strings", description: "business capabilities changed; repeatable" },
|
|
25
|
+
{ property: "modifies", flag: "--modifies", kind: "strings", description: "living Requirement-IDs of touched services this feature rewrites, scaffolded as pinned MODIFIED blocks; repeatable" },
|
|
26
|
+
],
|
|
27
|
+
annotations: WRITE_ANNOTATIONS,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "loam_rebase",
|
|
31
|
+
command: "rebase",
|
|
32
|
+
description: "Pin a feature delta to the living baselines after the agent has reconciled them. Opt-in journaled writer. " +
|
|
33
|
+
"CLI equivalent: loam rebase [featureId] [--service <id>] --json",
|
|
34
|
+
// Optional because the REGISTERED argument is — `loam rebase` relaxed it
|
|
35
|
+
// for `--living`, which names no feature — and the schema mirrors the
|
|
36
|
+
// command it wraps rather than the subset this tool exposes. `--living` is
|
|
37
|
+
// not offered here, so an omitted id reaches the CLI's own refusal, which
|
|
38
|
+
// names the flag that makes the omission legal.
|
|
39
|
+
positionals: [
|
|
40
|
+
{ property: "featureId", required: false, variadic: false, description: "feature id whose baselines were reviewed" },
|
|
41
|
+
],
|
|
42
|
+
flags: [
|
|
43
|
+
{ property: "service", flag: "--service", kind: "string", description: "restrict to one touched service" },
|
|
44
|
+
],
|
|
45
|
+
annotations: SAFE_WRITE_ANNOTATIONS,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "loam_gherkin",
|
|
49
|
+
command: "gherkin",
|
|
50
|
+
description: "Generate loam-owned Gherkin files in the bound service repository. Opt-in journaled writer; refuses ownership conflicts. " +
|
|
51
|
+
"CLI equivalent: loam gherkin [featureId] [--service <id>] --json",
|
|
52
|
+
positionals: [
|
|
53
|
+
{ property: "featureId", required: false, variadic: false, description: "feature id; omit for the living suite" },
|
|
54
|
+
],
|
|
55
|
+
flags: [
|
|
56
|
+
{ property: "service", flag: "--service", kind: "string", description: "service to emit for" },
|
|
57
|
+
],
|
|
58
|
+
annotations: SAFE_WRITE_ANNOTATIONS,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "loam_archive_plan",
|
|
62
|
+
command: "archive",
|
|
63
|
+
description: "Compute the complete archive plan without writing. The server enforces --dry-run. " +
|
|
64
|
+
"CLI equivalent: loam archive <featureId> --dry-run --json",
|
|
65
|
+
positionals: [
|
|
66
|
+
{ property: "featureId", required: true, variadic: false, description: "feature id to review" },
|
|
67
|
+
],
|
|
68
|
+
flags: [],
|
|
69
|
+
fixed: ["--dry-run"],
|
|
70
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
//# sourceMappingURL=author-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"author-tools.js","sourceRoot":"","sources":["../../../src/core/mcp/author-tools.ts"],"names":[],"mappings":"AAGA,MAAM,iBAAiB,GAAG;IACxB,YAAY,EAAE,KAAK;IACnB,eAAe,EAAE,KAAK;IACtB,cAAc,EAAE,KAAK;IACrB,aAAa,EAAE,KAAK;CACZ,CAAC;AAEX,MAAM,sBAAsB,GAAG;IAC7B,GAAG,iBAAiB;IACpB,cAAc,EAAE,IAAI;CACZ,CAAC;AAEX,MAAM,CAAC,MAAM,gBAAgB,GAAuB;IAClD;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,KAAK;QACd,WAAW,EACT,mFAAmF;YACnF,0JAA0J;QAC5J,WAAW,EAAE;YACX,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,+BAA+B,EAAE;SACzG;QACD,KAAK,EAAE;YACL,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gCAAgC,EAAE;YACrG,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,uCAAuC,EAAE;YACjH,EAAE,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,iCAAiC,EAAE;YACnH,EAAE,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,2CAA2C,EAAE;YAC7H,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,oHAAoH,EAAE;SACjM;QACD,WAAW,EAAE,iBAAiB;KAC/B;IACD;QACE,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,QAAQ;QACjB,WAAW,EACT,4GAA4G;YAC5G,iEAAiE;QACnE,yEAAyE;QACzE,sEAAsE;QACtE,2EAA2E;QAC3E,0EAA0E;QAC1E,gDAAgD;QAChD,WAAW,EAAE;YACX,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,0CAA0C,EAAE;SACrH;QACD,KAAK,EAAE;YACL,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iCAAiC,EAAE;SAC3G;QACD,WAAW,EAAE,sBAAsB;KACpC;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,SAAS;QAClB,WAAW,EACT,2HAA2H;YAC3H,kEAAkE;QACpE,WAAW,EAAE;YACX,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,uCAAuC,EAAE;SAClH;QACD,KAAK,EAAE;YACL,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qBAAqB,EAAE;SAC/F;QACD,WAAW,EAAE,sBAAsB;KACpC;IACD;QACE,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,SAAS;QAClB,WAAW,EACT,oFAAoF;YACpF,2DAA2D;QAC7D,WAAW,EAAE;YACX,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,sBAAsB,EAAE;SAChG;QACD,KAAK,EAAE,EAAE;QACT,KAAK,EAAE,CAAC,WAAW,CAAC;QACpB,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;KAC1D;CACF,CAAC","sourcesContent":["/** Opt-in MCP writers. Vouch and a committing archive are never exposed. */\nimport type { McpTool } from \"./tools.js\";\n\nconst WRITE_ANNOTATIONS = {\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n} as const;\n\nconst SAFE_WRITE_ANNOTATIONS = {\n ...WRITE_ANNOTATIONS,\n idempotentHint: true,\n} as const;\n\nexport const MCP_AUTHOR_TOOLS: readonly McpTool[] = [\n {\n name: \"loam_new\",\n command: \"new\",\n description:\n \"Scaffold a feature in the docs repo. Opt-in writer; refuses an existing feature. \" +\n \"CLI equivalent: loam new <featureId> [--title <text>] [--touches <id>...] [--new-service <id>...] [--capability <id>...] [--modifies <Req-ID>...] --json\",\n positionals: [\n { property: \"featureId\", required: true, variadic: false, description: \"new feature id, e.g. FEAT-101\" },\n ],\n flags: [\n { property: \"title\", flag: \"--title\", kind: \"string\", description: \"human title and directory slug\" },\n { property: \"touches\", flag: \"--touches\", kind: \"strings\", description: \"existing services changed; repeatable\" },\n { property: \"newServices\", flag: \"--new-service\", kind: \"strings\", description: \"services introduced; repeatable\" },\n { property: \"capabilities\", flag: \"--capability\", kind: \"strings\", description: \"business capabilities changed; repeatable\" },\n { property: \"modifies\", flag: \"--modifies\", kind: \"strings\", description: \"living Requirement-IDs of touched services this feature rewrites, scaffolded as pinned MODIFIED blocks; repeatable\" },\n ],\n annotations: WRITE_ANNOTATIONS,\n },\n {\n name: \"loam_rebase\",\n command: \"rebase\",\n description:\n \"Pin a feature delta to the living baselines after the agent has reconciled them. Opt-in journaled writer. \" +\n \"CLI equivalent: loam rebase [featureId] [--service <id>] --json\",\n // Optional because the REGISTERED argument is — `loam rebase` relaxed it\n // for `--living`, which names no feature — and the schema mirrors the\n // command it wraps rather than the subset this tool exposes. `--living` is\n // not offered here, so an omitted id reaches the CLI's own refusal, which\n // names the flag that makes the omission legal.\n positionals: [\n { property: \"featureId\", required: false, variadic: false, description: \"feature id whose baselines were reviewed\" },\n ],\n flags: [\n { property: \"service\", flag: \"--service\", kind: \"string\", description: \"restrict to one touched service\" },\n ],\n annotations: SAFE_WRITE_ANNOTATIONS,\n },\n {\n name: \"loam_gherkin\",\n command: \"gherkin\",\n description:\n \"Generate loam-owned Gherkin files in the bound service repository. Opt-in journaled writer; refuses ownership conflicts. \" +\n \"CLI equivalent: loam gherkin [featureId] [--service <id>] --json\",\n positionals: [\n { property: \"featureId\", required: false, variadic: false, description: \"feature id; omit for the living suite\" },\n ],\n flags: [\n { property: \"service\", flag: \"--service\", kind: \"string\", description: \"service to emit for\" },\n ],\n annotations: SAFE_WRITE_ANNOTATIONS,\n },\n {\n name: \"loam_archive_plan\",\n command: \"archive\",\n description:\n \"Compute the complete archive plan without writing. The server enforces --dry-run. \" +\n \"CLI equivalent: loam archive <featureId> --dry-run --json\",\n positionals: [\n { property: \"featureId\", required: true, variadic: false, description: \"feature id to review\" },\n ],\n flags: [],\n fixed: [\"--dry-run\"],\n annotations: { readOnlyHint: true, openWorldHint: false },\n },\n];\n"]}
|