@ybotok/loam 0.1.0-beta.3 → 0.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2635 -86
- package/COMPARISON.md +80 -63
- package/CONTRIBUTING.md +84 -0
- package/MIGRATING-from-OpenSpec.md +213 -54
- package/QUICKSTART.md +125 -0
- package/README.md +450 -150
- package/ROADMAP.md +599 -0
- package/SCHEMA.md +2355 -256
- package/SECURITY.md +21 -3
- package/WORKFLOW.md +701 -0
- package/dist/cli.js +113 -19
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt/adopt.js +209 -0
- package/dist/commands/adopt/adopt.js.map +1 -0
- package/dist/commands/adopt/render.js +268 -0
- package/dist/commands/adopt/render.js.map +1 -0
- package/dist/commands/archive/archive.js +77 -0
- package/dist/commands/archive/archive.js.map +1 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js +178 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/openapi.js +159 -0
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +323 -0
- package/dist/commands/archive/plan/gate.js.map +1 -0
- package/dist/commands/archive/plan/landscape.js +180 -0
- package/dist/commands/archive/plan/landscape.js.map +1 -0
- package/dist/commands/archive/plan/refusal.js +111 -0
- package/dist/commands/archive/plan/refusal.js.map +1 -0
- package/dist/commands/archive/plan/specs.js +237 -0
- package/dist/commands/archive/plan/specs.js.map +1 -0
- package/dist/commands/archive/plan/state.js +27 -0
- package/dist/commands/archive/plan/state.js.map +1 -0
- package/dist/commands/archive/run.js +252 -0
- package/dist/commands/archive/run.js.map +1 -0
- package/dist/commands/context/context.js +99 -0
- package/dist/commands/context/context.js.map +1 -0
- package/dist/commands/context/print.js +283 -0
- package/dist/commands/context/print.js.map +1 -0
- package/dist/commands/delta/delta.js +279 -0
- package/dist/commands/delta/delta.js.map +1 -0
- package/dist/commands/delta/print.js +205 -0
- package/dist/commands/delta/print.js.map +1 -0
- package/dist/commands/dependencies.js +9 -7
- package/dist/commands/dependencies.js.map +1 -1
- package/dist/commands/diff/diff.js +93 -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 +5 -4
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain/explain.js +151 -0
- package/dist/commands/explain/explain.js.map +1 -0
- package/dist/commands/explore.js +29 -24
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/gate/gate.js +115 -0
- package/dist/commands/gate/gate.js.map +1 -0
- package/dist/commands/gate/print.js +54 -0
- package/dist/commands/gate/print.js.map +1 -0
- package/dist/commands/gherkin/commit.js +146 -0
- package/dist/commands/gherkin/commit.js.map +1 -0
- package/dist/commands/gherkin/gherkin.js +246 -0
- package/dist/commands/gherkin/gherkin.js.map +1 -0
- package/dist/commands/gherkin/reconcile.js +149 -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 +28 -0
- package/dist/commands/init/first-hour.js.map +1 -0
- package/dist/commands/{init.js → init/init.js} +146 -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 +65 -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 +157 -0
- package/dist/commands/list/json.js.map +1 -0
- package/dist/commands/list/list.js +343 -0
- package/dist/commands/list/list.js.map +1 -0
- package/dist/commands/list/print.js +301 -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/views.js +105 -0
- package/dist/commands/list/views.js.map +1 -0
- package/dist/commands/mcp/dispatch.js +183 -0
- package/dist/commands/mcp/dispatch.js.map +1 -0
- package/dist/commands/mcp/mcp.js +34 -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 +170 -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 +142 -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 +91 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/error.js +19 -0
- package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js +170 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/paths.js +43 -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/commit.js +76 -0
- package/dist/commands/new/commit.js.map +1 -0
- package/dist/commands/new/new.js +283 -0
- package/dist/commands/new/new.js.map +1 -0
- package/dist/commands/new/templates.js +355 -0
- package/dist/commands/new/templates.js.map +1 -0
- package/dist/commands/open.js +203 -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} +11 -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 +275 -0
- package/dist/commands/rebase/rebase.js.map +1 -0
- package/dist/commands/seed/commit.js +192 -0
- package/dist/commands/seed/commit.js.map +1 -0
- package/dist/commands/seed/plan.js +133 -0
- package/dist/commands/seed/plan.js.map +1 -0
- package/dist/commands/seed/seed.js +172 -0
- package/dist/commands/seed/seed.js.map +1 -0
- package/dist/commands/show/feature.js +178 -0
- package/dist/commands/show/feature.js.map +1 -0
- package/dist/commands/show/marks.js +24 -0
- package/dist/commands/show/marks.js.map +1 -0
- package/dist/commands/{show.js → show/service.js} +63 -152
- package/dist/commands/show/service.js.map +1 -0
- package/dist/commands/show/show.js +77 -0
- package/dist/commands/show/show.js.map +1 -0
- package/dist/commands/status/json.js +45 -0
- package/dist/commands/status/json.js.map +1 -0
- package/dist/commands/status/print.js +157 -0
- package/dist/commands/status/print.js.map +1 -0
- package/dist/commands/status/status.js +119 -0
- package/dist/commands/status/status.js.map +1 -0
- package/dist/commands/steps/steps.js +189 -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 +265 -0
- package/dist/commands/subsystem/move.js.map +1 -0
- package/dist/commands/subsystem/query.js +115 -0
- package/dist/commands/subsystem/query.js.map +1 -0
- package/dist/commands/subsystem/subsystem.js +101 -0
- package/dist/commands/subsystem/subsystem.js.map +1 -0
- package/dist/commands/subsystem/sync.js +103 -0
- package/dist/commands/subsystem/sync.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +94 -0
- package/dist/commands/subsystem/txn/txn.js.map +1 -0
- package/dist/commands/subsystem/txn/views.js +70 -0
- package/dist/commands/subsystem/txn/views.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +160 -0
- package/dist/commands/unarchive/manifest.js.map +1 -0
- package/dist/commands/{unarchive.js → unarchive/restore.js} +47 -160
- package/dist/commands/unarchive/restore.js.map +1 -0
- package/dist/commands/unarchive/unarchive.js +67 -0
- package/dist/commands/unarchive/unarchive.js.map +1 -0
- package/dist/commands/validate/arch-coverage.js +204 -0
- package/dist/commands/validate/arch-coverage.js.map +1 -0
- package/dist/commands/validate/checks/fleet-shape.js +296 -0
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
- package/dist/commands/validate/checks/health-deps.js +55 -0
- package/dist/commands/validate/checks/health-deps.js.map +1 -0
- package/dist/commands/validate/checks/requirements.js +254 -0
- package/dist/commands/validate/checks/requirements.js.map +1 -0
- package/dist/commands/validate/checks/sources.js +76 -0
- package/dist/commands/validate/checks/sources.js.map +1 -0
- package/dist/commands/validate/checks/vocabulary.js +31 -0
- package/dist/commands/validate/checks/vocabulary.js.map +1 -0
- package/dist/commands/validate/feature.js +216 -0
- package/dist/commands/validate/feature.js.map +1 -0
- package/dist/commands/validate/fleet/census.js +69 -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 +353 -0
- package/dist/commands/validate/fleet/landscape.js.map +1 -0
- package/dist/commands/validate/fleet/load.js +52 -0
- package/dist/commands/validate/fleet/load.js.map +1 -0
- package/dist/commands/validate/fleet/obligations.js +270 -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 +63 -0
- package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js +156 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/capability-tag.js +94 -0
- package/dist/commands/validate/fleet/usecases/capability-tag.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/usecases/requirement-tag.js +95 -0
- package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/steps.js +197 -0
- package/dist/commands/validate/fleet/usecases/steps.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/usecases.js +99 -0
- package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +40 -0
- package/dist/commands/validate/fleet/views/ids.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +59 -0
- package/dist/commands/validate/fleet/views/stale.js.map +1 -0
- package/dist/commands/validate/links/corpus.js +92 -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/report.js +269 -0
- package/dist/commands/validate/report.js.map +1 -0
- package/dist/commands/validate/service/api.js +338 -0
- package/dist/commands/validate/service/api.js.map +1 -0
- package/dist/commands/validate/service/events/events.js +219 -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 +131 -0
- package/dist/commands/validate/service/evidence-pins.js.map +1 -0
- package/dist/commands/validate/service/service.js +251 -0
- package/dist/commands/validate/service/service.js.map +1 -0
- package/dist/commands/validate/service/specs.js +251 -0
- package/dist/commands/validate/service/specs.js.map +1 -0
- package/dist/commands/validate/service/spine.js +113 -0
- package/dist/commands/validate/service/spine.js.map +1 -0
- package/dist/commands/validate/validate.js +338 -0
- package/dist/commands/validate/validate.js.map +1 -0
- package/dist/commands/verify/cross/diff.js +182 -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 +72 -0
- package/dist/commands/verify/evidence/read.js.map +1 -0
- package/dist/commands/verify/frozen.js +241 -0
- package/dist/commands/verify/frozen.js.map +1 -0
- package/dist/commands/verify/record.js +226 -0
- package/dist/commands/verify/record.js.map +1 -0
- package/dist/commands/verify/report.js +223 -0
- package/dist/commands/verify/report.js.map +1 -0
- package/dist/commands/verify/results.js +246 -0
- package/dist/commands/verify/results.js.map +1 -0
- package/dist/commands/verify/verify.js +217 -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 +271 -0
- package/dist/commands/vouch/pack/print.js.map +1 -0
- package/dist/commands/vouch/pack/sections.js +142 -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 +285 -0
- package/dist/commands/vouch/run.js.map +1 -0
- package/dist/commands/vouch/sample/plan.js +125 -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 +123 -0
- package/dist/commands/vouch/vet/verify.js.map +1 -0
- package/dist/commands/vouch/vouch.js +176 -0
- package/dist/commands/vouch/vouch.js.map +1 -0
- package/dist/core/agent/agents-md/artifacts.js +220 -0
- package/dist/core/agent/agents-md/artifacts.js.map +1 -0
- package/dist/core/agent/agents-md/command-map.js +324 -0
- package/dist/core/agent/agents-md/command-map.js.map +1 -0
- package/dist/core/agent/agents-md/cycle.js +165 -0
- package/dist/core/agent/agents-md/cycle.js.map +1 -0
- package/dist/core/agent/agents-md/map/explain.js +34 -0
- package/dist/core/agent/agents-md/map/explain.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/context.js +41 -0
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js +46 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js +57 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
- package/dist/core/agent/agents-md/map/mcp.js +41 -0
- package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
- package/dist/core/agent/agents-md/map/status.js +62 -0
- package/dist/core/agent/agents-md/map/status.js.map +1 -0
- package/dist/core/agent/agents-md/map/subsystem.js +32 -0
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
- package/dist/core/agent/agents-md/map/usecases.js +60 -0
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
- package/dist/core/agent/agents-md/refusals.js +246 -0
- package/dist/core/agent/agents-md/refusals.js.map +1 -0
- package/dist/core/agent/agents-md/shipped/archive-gate.js +98 -0
- package/dist/core/agent/agents-md/shipped/archive-gate.js.map +1 -0
- package/dist/core/agent/agents-md/spine.js +40 -0
- package/dist/core/agent/agents-md/spine.js.map +1 -0
- package/dist/core/agent/agents-md.js +170 -0
- package/dist/core/agent/agents-md.js.map +1 -0
- package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +50 -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 +259 -0
- package/dist/core/agent/scaffold.js.map +1 -0
- package/dist/core/agent/support/report.js +103 -0
- package/dist/core/agent/support/report.js.map +1 -0
- package/dist/core/agent/tools/dialects.js +150 -0
- package/dist/core/agent/tools/dialects.js.map +1 -0
- package/dist/core/agent/tools/registry.js +228 -0
- package/dist/core/agent/tools/registry.js.map +1 -0
- package/dist/core/agent/workflows/adopt.js +133 -0
- package/dist/core/agent/workflows/adopt.js.map +1 -0
- package/dist/core/agent/workflows/check.js +337 -0
- package/dist/core/agent/workflows/check.js.map +1 -0
- package/dist/core/agent/workflows/closing.js +262 -0
- package/dist/core/agent/workflows/closing.js.map +1 -0
- package/dist/core/agent/workflows/feature.js +105 -0
- package/dist/core/agent/workflows/feature.js.map +1 -0
- package/dist/core/agent/workflows/implement.js +105 -0
- package/dist/core/agent/workflows/implement.js.map +1 -0
- package/dist/core/agent/workflows/reference/authoring.js +209 -0
- package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
- package/dist/core/agent/workflows/reference/codes.js +65 -0
- package/dist/core/agent/workflows/reference/codes.js.map +1 -0
- package/dist/core/agent/workflows/reference/done-check.js +188 -0
- package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
- package/dist/core/agent/workflows/reference/reference.js +16 -0
- package/dist/core/agent/workflows/reference/reference.js.map +1 -0
- package/dist/core/agent/workflows/reference/spine.js +297 -0
- package/dist/core/agent/workflows/reference/spine.js.map +1 -0
- package/dist/core/asyncapi/baseline/plan.js +110 -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 +141 -0
- package/dist/core/asyncapi/digest.js.map +1 -0
- package/dist/core/asyncapi/merge/components.js +91 -0
- package/dist/core/asyncapi/merge/components.js.map +1 -0
- package/dist/core/asyncapi/merge/error.js +33 -0
- package/dist/core/asyncapi/merge/error.js.map +1 -0
- package/dist/core/asyncapi/merge/markers.js +308 -0
- package/dist/core/asyncapi/merge/markers.js.map +1 -0
- package/dist/core/asyncapi/merge/merge.js +215 -0
- package/dist/core/asyncapi/merge/merge.js.map +1 -0
- package/dist/core/asyncapi/merge/pin.js +107 -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.js → asyncapi/read.js} +95 -109
- package/dist/core/asyncapi/read.js.map +1 -0
- package/dist/core/brief/brief.js +225 -0
- package/dist/core/brief/brief.js.map +1 -0
- package/dist/core/brief/checks.js +250 -0
- package/dist/core/brief/checks.js.map +1 -0
- package/dist/core/brief/landscape.js +194 -0
- package/dist/core/brief/landscape.js.map +1 -0
- package/dist/core/brief/targets.js +226 -0
- package/dist/core/brief/targets.js.map +1 -0
- package/dist/core/brief/unchecked.js +48 -0
- package/dist/core/brief/unchecked.js.map +1 -0
- package/dist/core/c4/arch.js +174 -0
- package/dist/core/c4/arch.js.map +1 -0
- package/dist/core/c4/likec4.js +90 -0
- package/dist/core/c4/likec4.js.map +1 -0
- package/dist/core/c4/parsed/deployment.js +158 -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 +57 -0
- package/dist/core/c4/parsed/values.js.map +1 -0
- package/dist/core/c4/parsed/view-ids.js +75 -0
- package/dist/core/c4/parsed/view-ids.js.map +1 -0
- package/dist/core/c4/project/architecture.js +45 -0
- package/dist/core/c4/project/architecture.js.map +1 -0
- package/dist/core/c4/project/documents.js +58 -0
- package/dist/core/c4/project/documents.js.map +1 -0
- package/dist/core/c4/project/load.js +187 -0
- package/dist/core/c4/project/load.js.map +1 -0
- package/dist/core/c4/project/staged.js +220 -0
- package/dist/core/c4/project/staged.js.map +1 -0
- package/dist/core/c4/resolve/service.js +159 -0
- package/dist/core/c4/resolve/service.js.map +1 -0
- package/dist/core/c4/resolve/steps.js +144 -0
- package/dist/core/c4/resolve/steps.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 +109 -0
- package/dist/core/c4/seed/template.js.map +1 -0
- package/dist/core/c4/source-mask.js +82 -0
- package/dist/core/c4/source-mask.js.map +1 -0
- package/dist/core/c4/source-scan.js +227 -0
- package/dist/core/c4/source-scan.js.map +1 -0
- package/dist/core/c4/splice/authored-source.js +101 -0
- package/dist/core/c4/splice/authored-source.js.map +1 -0
- package/dist/core/c4/splice/contract.js +10 -0
- package/dist/core/c4/splice/contract.js.map +1 -0
- package/dist/core/c4/splice/delta-blocks.js +139 -0
- package/dist/core/c4/splice/delta-blocks.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +36 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +269 -0
- package/dist/core/c4/splice/landscape-merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +194 -0
- package/dist/core/c4/splice/placement.js.map +1 -0
- package/dist/core/c4/workspace.js +174 -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 +50 -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 +342 -0
- package/dist/core/capabilities/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/findings.js +181 -0
- package/dist/core/capabilities/realizes/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/join.js +143 -0
- package/dist/core/capabilities/realizes/join.js.map +1 -0
- package/dist/core/capabilities/rollup.js +199 -0
- package/dist/core/capabilities/rollup.js.map +1 -0
- package/dist/core/capabilities/tree.js +126 -0
- package/dist/core/capabilities/tree.js.map +1 -0
- package/dist/core/capabilities/usecase-join.js +277 -0
- package/dist/core/capabilities/usecase-join.js.map +1 -0
- package/dist/core/coherence/authoring/scaffold.js +177 -0
- package/dist/core/coherence/authoring/scaffold.js.map +1 -0
- package/dist/core/coherence/authoring/sentinels.js +74 -0
- package/dist/core/coherence/authoring/sentinels.js.map +1 -0
- package/dist/core/coherence/coherence.js +287 -0
- package/dist/core/coherence/coherence.js.map +1 -0
- package/dist/core/coherence/declared.js +269 -0
- package/dist/core/coherence/declared.js.map +1 -0
- package/dist/core/coherence/events/declared.js +206 -0
- package/dist/core/coherence/events/declared.js.map +1 -0
- package/dist/core/coherence/events/events.js +204 -0
- package/dist/core/coherence/events/events.js.map +1 -0
- package/dist/core/coherence/events/grades.js +166 -0
- package/dist/core/coherence/events/grades.js.map +1 -0
- package/dist/core/coherence/events/lookups.js +122 -0
- package/dist/core/coherence/events/lookups.js.map +1 -0
- package/dist/core/coherence/events/merged.js +40 -0
- package/dist/core/coherence/events/merged.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 +155 -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/conflict-markers.js +60 -0
- package/dist/core/conflict-markers.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 +296 -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 +188 -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 +148 -0
- package/dist/core/diff/base-git.js.map +1 -0
- package/dist/core/diff/base-state.js +209 -0
- package/dist/core/diff/base-state.js.map +1 -0
- package/dist/core/diff/current-state.js +96 -0
- package/dist/core/diff/current-state.js.map +1 -0
- package/dist/core/diff/scope/changed-paths.js +188 -0
- package/dist/core/diff/scope/changed-paths.js.map +1 -0
- package/dist/core/diff/semantic.js +243 -0
- package/dist/core/diff/semantic.js.map +1 -0
- package/dist/core/diff/victims.js +247 -0
- package/dist/core/diff/victims.js.map +1 -0
- package/dist/core/docs.js +7 -64
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/agents.js +222 -0
- package/dist/core/doctor/agents.js.map +1 -0
- package/dist/core/doctor/config.js +135 -0
- package/dist/core/doctor/config.js.map +1 -0
- package/dist/core/doctor/doctor.js +275 -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/residue.js +110 -0
- package/dist/core/doctor/residue.js.map +1 -0
- package/dist/core/document/apply.js +77 -0
- package/dist/core/document/apply.js.map +1 -0
- package/dist/core/{frontmatter.js → document/frontmatter.js} +48 -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 +263 -0
- package/dist/core/document/parse.js.map +1 -0
- package/dist/core/document/scenarios.js +221 -0
- package/dist/core/document/scenarios.js.map +1 -0
- package/dist/core/document/spec.js +241 -0
- package/dist/core/document/spec.js.map +1 -0
- package/dist/core/{config.js → envelope/config.js} +79 -18
- package/dist/core/envelope/config.js.map +1 -0
- package/dist/core/envelope/json.js +175 -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 +175 -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 +181 -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.js +144 -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.js → explore/explore.js} +50 -101
- package/dist/core/explore/explore.js.map +1 -0
- package/dist/core/fleet-context.js +120 -78
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +201 -0
- package/dist/core/gate/checks.js.map +1 -0
- package/dist/core/gate/partners.js +205 -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 +113 -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 +234 -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 +106 -0
- package/dist/core/glossary/delta.js.map +1 -0
- package/dist/core/glossary/tree.js +86 -0
- package/dist/core/glossary/tree.js.map +1 -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/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} +18 -4
- package/dist/core/kernel/path-safety.js.map +1 -0
- package/dist/core/kernel/records.js.map +1 -0
- package/dist/core/links/backlinks.js +68 -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 +104 -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 +236 -0
- package/dist/core/links/parse.js.map +1 -0
- package/dist/core/mcp/argv.js +111 -0
- package/dist/core/mcp/argv.js.map +1 -0
- package/dist/core/mcp/author-tools.js +72 -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 +314 -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 +166 -0
- package/dist/core/openapi/baseline/gate.js.map +1 -0
- package/dist/core/openapi/baseline/plan.js +112 -0
- package/dist/core/openapi/baseline/plan.js.map +1 -0
- package/dist/core/openapi/baseline/record.js +175 -0
- package/dist/core/openapi/baseline/record.js.map +1 -0
- package/dist/core/openapi/depth.js +122 -0
- package/dist/core/openapi/depth.js.map +1 -0
- package/dist/core/openapi/digest.js +189 -0
- package/dist/core/openapi/digest.js.map +1 -0
- package/dist/core/{openapi.js → openapi/doc.js} +44 -106
- package/dist/core/openapi/doc.js.map +1 -0
- package/dist/core/openapi/merge/components.js +234 -0
- package/dist/core/openapi/merge/components.js.map +1 -0
- package/dist/core/openapi/merge/error.js +26 -0
- package/dist/core/openapi/merge/error.js.map +1 -0
- package/dist/core/openapi/merge/markers.js +208 -0
- package/dist/core/openapi/merge/markers.js.map +1 -0
- package/dist/core/openapi/merge/merge.js +256 -0
- package/dist/core/openapi/merge/merge.js.map +1 -0
- package/dist/core/openapi/merge/pin.js +128 -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 +221 -0
- package/dist/core/openspec/inventory.js.map +1 -0
- package/dist/core/openspec/model/mapping.js +76 -0
- package/dist/core/openspec/model/mapping.js.map +1 -0
- package/dist/core/openspec/model/model.js +65 -0
- package/dist/core/openspec/model/model.js.map +1 -0
- package/dist/core/openspec/scan/changes.js +235 -0
- package/dist/core/openspec/scan/changes.js.map +1 -0
- package/dist/core/openspec/scan/config.js +200 -0
- package/dist/core/openspec/scan/config.js.map +1 -0
- package/dist/core/openspec/scan/shape.js +260 -0
- package/dist/core/openspec/scan/shape.js.map +1 -0
- package/dist/core/openspec/scan/walk.js +133 -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 +137 -0
- package/dist/core/pack/living.js.map +1 -0
- package/dist/core/pack/pack.js +76 -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/provenance/findings.js +208 -0
- package/dist/core/provenance/findings.js.map +1 -0
- package/dist/core/provenance/git.js +225 -0
- package/dist/core/provenance/git.js.map +1 -0
- package/dist/core/provenance/gitq/moves.js +182 -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 +263 -0
- package/dist/core/provenance/sources.js.map +1 -0
- package/dist/core/provenance/stamp.js +232 -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 +277 -0
- package/dist/core/repo/paths.js.map +1 -0
- package/dist/core/repo/repo.js +248 -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 +52 -0
- package/dist/core/repo/tree/find.js.map +1 -0
- package/dist/core/repo/tree/fs.js +64 -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/views.js +172 -0
- package/dist/core/repo/tree/views.js.map +1 -0
- package/dist/core/repo/tree/walk.js +234 -0
- package/dist/core/repo/tree/walk.js.map +1 -0
- package/dist/core/results.js +99 -2
- package/dist/core/results.js.map +1 -1
- package/dist/core/scaffold/landscape.js +131 -0
- package/dist/core/scaffold/landscape.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 +241 -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 +206 -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 +98 -0
- package/dist/core/staging/recovery/intent.js.map +1 -0
- package/dist/core/staging/recovery/recover.js +126 -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.js +202 -0
- package/dist/core/staging/snapshot.js.map +1 -0
- package/dist/core/staging/txn/forward.js +171 -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 +49 -0
- package/dist/core/status/actions/execution.js.map +1 -0
- package/dist/core/status/contracts.js +102 -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 +207 -0
- package/dist/core/status/feature/feature.js.map +1 -0
- package/dist/core/status/feature/next.js +150 -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/fleet/fleet.js +197 -0
- package/dist/core/status/fleet/fleet.js.map +1 -0
- package/dist/core/status/fleet/next.js +207 -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 +201 -0
- package/dist/core/status/verification.js.map +1 -0
- package/dist/core/usecases/capability.js +169 -0
- package/dist/core/usecases/capability.js.map +1 -0
- package/dist/core/usecases/delta/claims.js +116 -0
- package/dist/core/usecases/delta/claims.js.map +1 -0
- package/dist/core/usecases/delta/flows.js +103 -0
- package/dist/core/usecases/delta/flows.js.map +1 -0
- package/dist/core/usecases/delta/overlay.js +72 -0
- package/dist/core/usecases/delta/overlay.js.map +1 -0
- package/dist/core/usecases/fleet.js +137 -0
- package/dist/core/usecases/fleet.js.map +1 -0
- package/dist/core/usecases/operations.js +111 -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/touch.js +101 -0
- package/dist/core/usecases/touch.js.map +1 -0
- package/dist/core/verify/answers.js +173 -0
- package/dist/core/verify/answers.js.map +1 -0
- package/dist/core/verify/build.js +150 -0
- package/dist/core/verify/build.js.map +1 -0
- package/dist/core/verify/checklist.js +201 -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/file.js +257 -0
- package/dist/core/verify/file.js.map +1 -0
- package/dist/core/verify/pins/lint.js +157 -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/record.js +142 -0
- package/dist/core/verify/record.js.map +1 -0
- package/dist/core/verify/store/commit.js +89 -0
- package/dist/core/verify/store/commit.js.map +1 -0
- package/dist/core/verify/store/render.js +57 -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 +58 -0
- package/dist/core/vocabulary/issue.js.map +1 -0
- package/dist/core/vocabulary/maturity.js +145 -0
- package/dist/core/vocabulary/maturity.js.map +1 -0
- package/dist/core/{report.js → vocabulary/report.js} +30 -2
- 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 +189 -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 +280 -0
- package/examples/docs/architecture/obligations.yaml +23 -0
- package/examples/docs/architecture/permissions.yaml +50 -0
- package/examples/docs/architecture/subsystems.likec4 +11 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +65 -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 +129 -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 +28 -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 +70 -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 +9 -0
- package/examples/docs/loam.json +3 -0
- package/examples/docs/services/checkout-web/model.likec4 +109 -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 +127 -0
- package/examples/docs/services/order-service/asyncapi.yaml +108 -0
- package/examples/docs/services/order-service/health.yaml +57 -0
- package/examples/docs/services/order-service/model.likec4 +138 -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 +73 -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 +67 -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 +117 -0
- package/examples/docs/services/platform/identity-service/health.yaml +70 -0
- package/examples/docs/services/platform/identity-service/model.likec4 +83 -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 +199 -0
- package/examples/docs/services/platform/notification-service/health.yaml +35 -0
- package/examples/docs/services/platform/notification-service/model.likec4 +118 -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.map +0 -1
- package/dist/commands/status.js +0 -262
- package/dist/commands/status.js.map +0 -1
- 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.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.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.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
- /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
- /package/dist/core/{records.js → kernel/records.js} +0 -0
|
@@ -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.\n */\nimport type { McpTool } from \"./tools.js\";\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\nfunction positionalTokens(tool: McpTool, args: Record<string, unknown>): Checked {\n const tokens: string[] = [];\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 continue;\n }\n const checked = positional.variadic\n ? checkedStrings(positional.property, value)\n : checkedString(positional.property, value);\n if (!checked.ok) return checked;\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,72 @@
|
|
|
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>...] --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
|
+
],
|
|
26
|
+
annotations: WRITE_ANNOTATIONS,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: "loam_rebase",
|
|
30
|
+
command: "rebase",
|
|
31
|
+
description: "Pin a feature delta to the living baselines after the agent has reconciled them. Opt-in journaled writer. " +
|
|
32
|
+
"CLI equivalent: loam rebase [featureId] [--service <id>] --json",
|
|
33
|
+
// Optional because the REGISTERED argument is — `loam rebase` relaxed it
|
|
34
|
+
// for `--living`, which names no feature — and the schema mirrors the
|
|
35
|
+
// command it wraps rather than the subset this tool exposes. `--living` is
|
|
36
|
+
// not offered here, so an omitted id reaches the CLI's own refusal, which
|
|
37
|
+
// names the flag that makes the omission legal.
|
|
38
|
+
positionals: [
|
|
39
|
+
{ property: "featureId", required: false, variadic: false, description: "feature id whose baselines were reviewed" },
|
|
40
|
+
],
|
|
41
|
+
flags: [
|
|
42
|
+
{ property: "service", flag: "--service", kind: "string", description: "restrict to one touched service" },
|
|
43
|
+
],
|
|
44
|
+
annotations: SAFE_WRITE_ANNOTATIONS,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "loam_gherkin",
|
|
48
|
+
command: "gherkin",
|
|
49
|
+
description: "Generate loam-owned Gherkin files in the bound service repository. Opt-in journaled writer; refuses ownership conflicts. " +
|
|
50
|
+
"CLI equivalent: loam gherkin [featureId] [--service <id>] --json",
|
|
51
|
+
positionals: [
|
|
52
|
+
{ property: "featureId", required: false, variadic: false, description: "feature id; omit for the living suite" },
|
|
53
|
+
],
|
|
54
|
+
flags: [
|
|
55
|
+
{ property: "service", flag: "--service", kind: "string", description: "service to emit for" },
|
|
56
|
+
],
|
|
57
|
+
annotations: SAFE_WRITE_ANNOTATIONS,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "loam_archive_plan",
|
|
61
|
+
command: "archive",
|
|
62
|
+
description: "Compute the complete archive plan without writing. The server enforces --dry-run. " +
|
|
63
|
+
"CLI equivalent: loam archive <featureId> --dry-run --json",
|
|
64
|
+
positionals: [
|
|
65
|
+
{ property: "featureId", required: true, variadic: false, description: "feature id to review" },
|
|
66
|
+
],
|
|
67
|
+
flags: [],
|
|
68
|
+
fixed: ["--dry-run"],
|
|
69
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
//# 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,iIAAiI;QACnI,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;SAC9H;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>...] --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 ],\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"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP stdio framing — the ONE module that knows how protocol messages are
|
|
3
|
+
* delimited on the wire.
|
|
4
|
+
*
|
|
5
|
+
* Assumed spec revision: 2025-06-18 (unchanged on this point since
|
|
6
|
+
* 2024-11-05): the MCP stdio transport is newline-delimited JSON-RPC — one
|
|
7
|
+
* UTF-8 encoded message per line, and messages MUST NOT contain embedded
|
|
8
|
+
* newlines. It is NOT LSP's Content-Length header framing, which this facade
|
|
9
|
+
* was once at risk of assuming because both protocols are JSON-RPC over
|
|
10
|
+
* stdio. If a framing correction is ever needed, it is a change to this
|
|
11
|
+
* module alone: the serve loop consumes `splitFrames`/`frame` and never
|
|
12
|
+
* touches delimiter bytes itself.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Split buffered input into complete frames plus the unterminated tail.
|
|
16
|
+
* Stateless on purpose: the caller owns `rest` as a local, so no state can
|
|
17
|
+
* leak between serve sessions the way module-level buffering would.
|
|
18
|
+
*/
|
|
19
|
+
export function splitFrames(buffered) {
|
|
20
|
+
const parts = buffered.split("\n");
|
|
21
|
+
// split() never returns an empty array, so pop() always yields a string —
|
|
22
|
+
// the text after the final "\n", which is "" when the chunk ended on one.
|
|
23
|
+
const rest = parts.pop() ?? "";
|
|
24
|
+
return { lines: parts.map(bareFrame), rest };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* One frame stripped of transport debris: a trailing CR (Windows clients end
|
|
28
|
+
* lines with \r\n, and the frame is the JSON text, not the carriage return)
|
|
29
|
+
* and a leading U+FEFF. The BOM case was observed, not imagined: PowerShell's
|
|
30
|
+
* pipeline encoder prepends one when it feeds a native process, so a Windows
|
|
31
|
+
* client's very first `initialize` died with -32700 while every later frame
|
|
32
|
+
* worked. A BOM can never begin valid JSON, so stripping it drops no message.
|
|
33
|
+
*/
|
|
34
|
+
function bareFrame(line) {
|
|
35
|
+
const noBom = line.startsWith("") ? line.slice(1) : line;
|
|
36
|
+
return noBom.endsWith("\r") ? noBom.slice(0, -1) : noBom;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* One outbound frame. JSON.stringify escapes every newline inside string
|
|
40
|
+
* values, so the serialized form of a message object can never contain the
|
|
41
|
+
* delimiter — which is the invariant the transport rests on.
|
|
42
|
+
*/
|
|
43
|
+
export function frame(message) {
|
|
44
|
+
return JSON.stringify(message) + "\n";
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=framing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framing.js","sourceRoot":"","sources":["../../../src/core/mcp/framing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAC/B,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,OAAgC;IACpD,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;AACxC,CAAC","sourcesContent":["/**\n * MCP stdio framing — the ONE module that knows how protocol messages are\n * delimited on the wire.\n *\n * Assumed spec revision: 2025-06-18 (unchanged on this point since\n * 2024-11-05): the MCP stdio transport is newline-delimited JSON-RPC — one\n * UTF-8 encoded message per line, and messages MUST NOT contain embedded\n * newlines. It is NOT LSP's Content-Length header framing, which this facade\n * was once at risk of assuming because both protocols are JSON-RPC over\n * stdio. If a framing correction is ever needed, it is a change to this\n * module alone: the serve loop consumes `splitFrames`/`frame` and never\n * touches delimiter bytes itself.\n */\n\nexport interface FrameSplit {\n /** Complete frames, in arrival order, each with its delimiter (and any trailing CR) removed. */\n readonly lines: readonly string[];\n /** The bytes after the last delimiter — a frame still arriving. Feed it back in front of the next chunk. */\n readonly rest: string;\n}\n\n/**\n * Split buffered input into complete frames plus the unterminated tail.\n * Stateless on purpose: the caller owns `rest` as a local, so no state can\n * leak between serve sessions the way module-level buffering would.\n */\nexport function splitFrames(buffered: string): FrameSplit {\n const parts = buffered.split(\"\\n\");\n // split() never returns an empty array, so pop() always yields a string —\n // the text after the final \"\\n\", which is \"\" when the chunk ended on one.\n const rest = parts.pop() ?? \"\";\n return { lines: parts.map(bareFrame), rest };\n}\n\n/**\n * One frame stripped of transport debris: a trailing CR (Windows clients end\n * lines with \\r\\n, and the frame is the JSON text, not the carriage return)\n * and a leading U+FEFF. The BOM case was observed, not imagined: PowerShell's\n * pipeline encoder prepends one when it feeds a native process, so a Windows\n * client's very first `initialize` died with -32700 while every later frame\n * worked. A BOM can never begin valid JSON, so stripping it drops no message.\n */\nfunction bareFrame(line: string): string {\n const noBom = line.startsWith(\"\") ? line.slice(1) : line;\n return noBom.endsWith(\"\\r\") ? noBom.slice(0, -1) : noBom;\n}\n\n/**\n * One outbound frame. JSON.stringify escapes every newline inside string\n * values, so the serialized form of a message object can never contain the\n * delimiter — which is the invariant the transport rests on.\n */\nexport function frame(message: Record<string, unknown>): string {\n return JSON.stringify(message) + \"\\n\";\n}\n"]}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure JSON-RPC 2.0 + MCP routing for `loam mcp` — parse one inbound frame,
|
|
3
|
+
* decide the reply. Computes and returns only: the stream loop, the stdout
|
|
4
|
+
* writes and the dispatcher live in `src/commands/mcp/`, so every decision
|
|
5
|
+
* here is unit-testable without a stream in sight.
|
|
6
|
+
*
|
|
7
|
+
* Spec revision assumed: MCP 2025-06-18 (framing note in `./framing.ts`).
|
|
8
|
+
* The lifecycle is deliberately NOT policed: this server is a stateless
|
|
9
|
+
* facade over a stateless CLI, its capabilities never vary, and refusing a
|
|
10
|
+
* tools/call that arrives before `initialize` would protect nothing — so
|
|
11
|
+
* every request is answered on its own terms, whatever came first. What IS
|
|
12
|
+
* refused: JSON-RPC batch arrays (removed in 2025-06-18; the older revisions
|
|
13
|
+
* this server also negotiates allowed them, and that gap is deliberate — a
|
|
14
|
+
* clear -32600 with the reason beats a half-implemented batch path no real
|
|
15
|
+
* MCP client exercises).
|
|
16
|
+
*/
|
|
17
|
+
import { isRecord } from "../kernel/records.js";
|
|
18
|
+
import { LOAM_VERSION } from "../envelope/version.js";
|
|
19
|
+
import { toArgv } from "./argv.js";
|
|
20
|
+
import { MCP_TOOLS, READ_ONLY_ANNOTATIONS, toInputSchema, toolByName, } from "./tools.js";
|
|
21
|
+
import { AGENTS_MD } from "../agent/agents-md.js";
|
|
22
|
+
import { PROTOCOLS } from "../agent/protocol.js";
|
|
23
|
+
import { withoutFixTables } from "../explain/fix-tables.js";
|
|
24
|
+
/** JSON-RPC 2.0 error codes this server emits. */
|
|
25
|
+
export const PARSE_ERROR = -32700;
|
|
26
|
+
export const INVALID_REQUEST = -32600;
|
|
27
|
+
export const METHOD_NOT_FOUND = -32601;
|
|
28
|
+
export const INVALID_PARAMS = -32602;
|
|
29
|
+
export const INTERNAL_ERROR = -32603;
|
|
30
|
+
/**
|
|
31
|
+
* Newest first. `initialize` echoes the client's requested version when it is
|
|
32
|
+
* one of these, else answers the newest — the negotiation rule the 2025-06-18
|
|
33
|
+
* lifecycle spec states for servers. All three revisions are identical in
|
|
34
|
+
* everything this facade implements (stdio framing, tools/list, tools/call
|
|
35
|
+
* with text content) except batching, refused above.
|
|
36
|
+
*/
|
|
37
|
+
export const SUPPORTED_PROTOCOL_VERSIONS = ["2025-06-18", "2025-03-26", "2024-11-05"];
|
|
38
|
+
export const LATEST_PROTOCOL_VERSION = SUPPORTED_PROTOCOL_VERSIONS[0];
|
|
39
|
+
const TOOL_OUTPUT_SCHEMA = {
|
|
40
|
+
type: "object",
|
|
41
|
+
required: ["contractVersion", "version", "ok"],
|
|
42
|
+
properties: {
|
|
43
|
+
contractVersion: { const: "1.0" },
|
|
44
|
+
version: { type: "string" },
|
|
45
|
+
ok: { type: "boolean" },
|
|
46
|
+
error: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: { code: { type: "string" }, message: { type: "string" } },
|
|
49
|
+
required: ["code", "message"],
|
|
50
|
+
additionalProperties: true,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
additionalProperties: true,
|
|
54
|
+
};
|
|
55
|
+
const RESOURCE_TEXT = {
|
|
56
|
+
"loam://orientation": AGENTS_MD,
|
|
57
|
+
...Object.fromEntries(Object.entries(PROTOCOLS).map(([name, body]) => [`loam://instructions/${name}`, body])),
|
|
58
|
+
"loam://instructions/loam-check/compact": withoutFixTables(PROTOCOLS["loam-check"]),
|
|
59
|
+
};
|
|
60
|
+
export function resultResponse(id, result) {
|
|
61
|
+
return { jsonrpc: "2.0", id, result };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* `rpcCode`, not `code`: the stable-code drift collector
|
|
65
|
+
* (test/helpers/stable-codes.ts) treats every function with a parameter named
|
|
66
|
+
* `code` as an emitter of loam's stable code STRINGS and demands a literal at
|
|
67
|
+
* each call site. A JSON-RPC numeric code is a different vocabulary — naming
|
|
68
|
+
* the parameter into that scan would make the guard demand string literals
|
|
69
|
+
* where the protocol requires numbers.
|
|
70
|
+
*/
|
|
71
|
+
export function errorResponse(id, rpcCode, message) {
|
|
72
|
+
return { jsonrpc: "2.0", id, error: { code: rpcCode, message } };
|
|
73
|
+
}
|
|
74
|
+
const reply = (response) => ({ kind: "reply", response });
|
|
75
|
+
/** One line off the wire → what to do about it. Total: every input maps to an outcome, nothing throws. */
|
|
76
|
+
export function routeLine(line, tools = MCP_TOOLS) {
|
|
77
|
+
if (line.trim() === "")
|
|
78
|
+
return { kind: "ignore" };
|
|
79
|
+
let message;
|
|
80
|
+
try {
|
|
81
|
+
message = JSON.parse(line);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
85
|
+
return reply(errorResponse(null, PARSE_ERROR, `Parse error: ${detail}`));
|
|
86
|
+
}
|
|
87
|
+
if (Array.isArray(message)) {
|
|
88
|
+
// JSON-RPC batching was removed in MCP 2025-06-18; see the module comment
|
|
89
|
+
// for why the older negotiated revisions refuse it too instead of half-supporting it.
|
|
90
|
+
return reply(errorResponse(null, INVALID_REQUEST, "Invalid Request: JSON-RPC batch arrays are not supported"));
|
|
91
|
+
}
|
|
92
|
+
if (!isRecord(message)) {
|
|
93
|
+
return reply(errorResponse(null, INVALID_REQUEST, "Invalid Request: a message must be a JSON object"));
|
|
94
|
+
}
|
|
95
|
+
const rawId = message["id"];
|
|
96
|
+
// Three id states, kept apart because they demand opposite answers. ABSENT
|
|
97
|
+
// (or an explicit null, reserved for unanswerable errors) is a notification.
|
|
98
|
+
// A PRESENT id that is not a string or a finite number — an object, a bool,
|
|
99
|
+
// an array, a JSON `1e999` that parsed to Infinity — is a malformed REQUEST:
|
|
100
|
+
// the client is waiting on a reply, and folding it into the notification
|
|
101
|
+
// branch answers with silence, which for a request is a hang, not an error.
|
|
102
|
+
const validId = typeof rawId === "string" || (typeof rawId === "number" && Number.isFinite(rawId)) ? rawId : null;
|
|
103
|
+
if (message["jsonrpc"] !== "2.0") {
|
|
104
|
+
return reply(errorResponse(validId, INVALID_REQUEST, "Invalid Request: jsonrpc must be the string \"2.0\""));
|
|
105
|
+
}
|
|
106
|
+
const method = message["method"];
|
|
107
|
+
if (typeof method !== "string") {
|
|
108
|
+
return reply(errorResponse(validId, INVALID_REQUEST, "Invalid Request: method must be a string"));
|
|
109
|
+
}
|
|
110
|
+
if (!("id" in message) || rawId === null)
|
|
111
|
+
return { kind: "ignore" };
|
|
112
|
+
if (validId === null) {
|
|
113
|
+
// id null in the response: the request's own id is unusable, and null is
|
|
114
|
+
// exactly the id JSON-RPC reserves for that answer.
|
|
115
|
+
return reply(errorResponse(null, INVALID_REQUEST, "Invalid Request: id must be a string or a finite number"));
|
|
116
|
+
}
|
|
117
|
+
return routeRequest(validId, method, message["params"], tools);
|
|
118
|
+
}
|
|
119
|
+
function routeRequest(id, method, params, tools) {
|
|
120
|
+
switch (method) {
|
|
121
|
+
case "initialize":
|
|
122
|
+
return reply(resultResponse(id, initializeResult(params)));
|
|
123
|
+
case "ping":
|
|
124
|
+
return reply(resultResponse(id, {}));
|
|
125
|
+
case "tools/list":
|
|
126
|
+
// No pagination: the whole tool table fits in one page, so `nextCursor`
|
|
127
|
+
// is omitted rather than emitted empty — the spec reads an absent
|
|
128
|
+
// cursor as "done".
|
|
129
|
+
return reply(resultResponse(id, {
|
|
130
|
+
tools: tools.map((tool) => ({
|
|
131
|
+
name: tool.name,
|
|
132
|
+
description: tool.description,
|
|
133
|
+
inputSchema: toInputSchema(tool),
|
|
134
|
+
outputSchema: TOOL_OUTPUT_SCHEMA,
|
|
135
|
+
// Base tools share the read-only default; opt-in authoring tools
|
|
136
|
+
// carry their own mutation annotations in author-tools.ts.
|
|
137
|
+
annotations: tool.annotations ?? READ_ONLY_ANNOTATIONS,
|
|
138
|
+
})),
|
|
139
|
+
}));
|
|
140
|
+
case "resources/list":
|
|
141
|
+
return reply(resultResponse(id, {
|
|
142
|
+
resources: Object.keys(RESOURCE_TEXT).map((uri) => ({
|
|
143
|
+
uri,
|
|
144
|
+
name: uri === "loam://orientation" ? "loam orientation" : uri.slice("loam://instructions/".length),
|
|
145
|
+
description: uri === "loam://orientation"
|
|
146
|
+
? "Small always-loaded map of a loam repository"
|
|
147
|
+
: "Version-matched loam workflow, support protocol or reference page",
|
|
148
|
+
mimeType: "text/markdown",
|
|
149
|
+
})),
|
|
150
|
+
}));
|
|
151
|
+
case "resources/read":
|
|
152
|
+
return routeResourceRead(id, params);
|
|
153
|
+
case "tools/call":
|
|
154
|
+
return routeToolCall(id, params, tools);
|
|
155
|
+
default:
|
|
156
|
+
// Everything else — including a literal `shutdown`, which is LSP's
|
|
157
|
+
// lifecycle and not MCP's (the MCP stdio lifecycle ends at stdin EOF).
|
|
158
|
+
return reply(errorResponse(id, METHOD_NOT_FOUND, `Method not found: ${method}`));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function routeResourceRead(id, params) {
|
|
162
|
+
if (!isRecord(params) || typeof params["uri"] !== "string") {
|
|
163
|
+
return reply(errorResponse(id, INVALID_PARAMS, "resources/read requires params.uri"));
|
|
164
|
+
}
|
|
165
|
+
const uri = params["uri"];
|
|
166
|
+
const text = RESOURCE_TEXT[uri];
|
|
167
|
+
if (text === undefined) {
|
|
168
|
+
return reply(errorResponse(id, INVALID_PARAMS, `Unknown resource '${uri}'`));
|
|
169
|
+
}
|
|
170
|
+
return reply(resultResponse(id, { contents: [{ uri, mimeType: "text/markdown", text }] }));
|
|
171
|
+
}
|
|
172
|
+
function routeToolCall(id, params, tools) {
|
|
173
|
+
if (!isRecord(params) || typeof params["name"] !== "string") {
|
|
174
|
+
return reply(errorResponse(id, INVALID_PARAMS, "tools/call requires params.name naming a tool"));
|
|
175
|
+
}
|
|
176
|
+
const tool = toolByName(params["name"], tools);
|
|
177
|
+
if (tool === undefined) {
|
|
178
|
+
const names = tools.map((t) => t.name).join(", ");
|
|
179
|
+
return reply(errorResponse(id, INVALID_PARAMS, `Unknown tool '${params["name"]}' — this server offers: ${names}`));
|
|
180
|
+
}
|
|
181
|
+
const rawArgs = params["arguments"] ?? {};
|
|
182
|
+
if (!isRecord(rawArgs)) {
|
|
183
|
+
return reply(errorResponse(id, INVALID_PARAMS, "tools/call params.arguments must be an object when present"));
|
|
184
|
+
}
|
|
185
|
+
const built = toArgv(tool, rawArgs);
|
|
186
|
+
if (!built.ok)
|
|
187
|
+
return reply(errorResponse(id, INVALID_PARAMS, built.problem));
|
|
188
|
+
return { kind: "call", id, toolName: tool.name, argv: built.argv };
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* The `initialize` result. The version rule: echo the requested revision when
|
|
192
|
+
* this server supports it, otherwise answer the newest it does — the client
|
|
193
|
+
* then decides whether it can live with that (2025-06-18 lifecycle,
|
|
194
|
+
* "Version Negotiation").
|
|
195
|
+
*/
|
|
196
|
+
export function initializeResult(params) {
|
|
197
|
+
const requested = isRecord(params) ? params["protocolVersion"] : undefined;
|
|
198
|
+
const negotiated = typeof requested === "string" && SUPPORTED_PROTOCOL_VERSIONS.includes(requested)
|
|
199
|
+
? requested
|
|
200
|
+
: LATEST_PROTOCOL_VERSION;
|
|
201
|
+
return {
|
|
202
|
+
protocolVersion: negotiated,
|
|
203
|
+
capabilities: {
|
|
204
|
+
// The sets never change while the server lives, so no
|
|
205
|
+
// listChanged notification is declared — announcing one and never
|
|
206
|
+
// sending it would be a promise, not a capability.
|
|
207
|
+
tools: {},
|
|
208
|
+
resources: {},
|
|
209
|
+
},
|
|
210
|
+
serverInfo: { name: "loam", version: LOAM_VERSION },
|
|
211
|
+
instructions: "Every tool result is a loam --json envelope (contractVersion 1.0): branch on ok, " +
|
|
212
|
+
"and on error.code when ok is false — the same machine contract the CLI prints.",
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* One tool run wrapped as an MCP tool result. The envelope rides VERBATIM in
|
|
217
|
+
* content[0].text — one machine contract, not two — and again parsed as
|
|
218
|
+
* structuredContent for clients that read that field.
|
|
219
|
+
*
|
|
220
|
+
* `isError` follows the ENVELOPE's `ok`, and the exit code only when no
|
|
221
|
+
* envelope could be parsed. The two disagree on purpose for half the tool
|
|
222
|
+
* set: validate, doctor, gate, context and delta all have graded answers
|
|
223
|
+
* that exit 1 while reporting `ok: true` — an invalid fleet, a blocked
|
|
224
|
+
* doctor, a `verdict: "fail"` deploy gate. Those exits are CI levers, not
|
|
225
|
+
* call failures, and an MCP host renders `isError: true` as "the call
|
|
226
|
+
* failed" and may discard structuredContent — which for loam_gate would
|
|
227
|
+
* discard the exact verdict the caller asked for. `ok: false` is the one
|
|
228
|
+
* signal that means "loam refused to answer", so it is the one isError
|
|
229
|
+
* mirrors; the exit-code fallback exists only for stdout that parsed as no
|
|
230
|
+
* envelope at all.
|
|
231
|
+
*
|
|
232
|
+
* An EMPTY stdout is a protocol error, not a quiet result: with `--json` on
|
|
233
|
+
* every argv, a command that printed no envelope is a command whose answer
|
|
234
|
+
* was lost, and "nobody could look" must stay distinguishable from any
|
|
235
|
+
* genuine envelope — even a refusing one.
|
|
236
|
+
*/
|
|
237
|
+
export function toolReply(run) {
|
|
238
|
+
if (run.stdout.trim() === "") {
|
|
239
|
+
const hint = run.stderr.trim() === "" ? "" : ` stderr: ${run.stderr.trim()}`;
|
|
240
|
+
return {
|
|
241
|
+
kind: "error",
|
|
242
|
+
code: INTERNAL_ERROR,
|
|
243
|
+
message: `the command exited ${run.code} without printing a --json envelope, so there is no result to return.${hint}`,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
let structured;
|
|
247
|
+
try {
|
|
248
|
+
const parsed = JSON.parse(run.stdout);
|
|
249
|
+
// structuredContent must be an object; the envelope always is.
|
|
250
|
+
structured = isRecord(parsed) ? parsed : undefined;
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// The fallback below handles both invalid JSON and valid non-object JSON.
|
|
254
|
+
}
|
|
255
|
+
if (structured === undefined) {
|
|
256
|
+
// Preserve the bytes in content, but keep the declared output contract:
|
|
257
|
+
// an MCP client should never have to branch on the absence of
|
|
258
|
+
// structuredContent after tools/list promised a schema.
|
|
259
|
+
structured = {
|
|
260
|
+
contractVersion: "1.0",
|
|
261
|
+
version: LOAM_VERSION,
|
|
262
|
+
ok: false,
|
|
263
|
+
error: {
|
|
264
|
+
code: "internal",
|
|
265
|
+
message: "the command did not print a JSON object envelope",
|
|
266
|
+
},
|
|
267
|
+
raw: run.stdout,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
const envelopeOk = structured?.["ok"];
|
|
271
|
+
return {
|
|
272
|
+
kind: "result",
|
|
273
|
+
result: {
|
|
274
|
+
content: [{ type: "text", text: run.stdout }],
|
|
275
|
+
structuredContent: structured,
|
|
276
|
+
isError: typeof envelopeOk === "boolean" ? !envelopeOk : run.code !== 0,
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/core/mcp/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure JSON-RPC 2.0 + MCP routing for `loam mcp` — parse one inbound frame,\n * decide the reply. Computes and returns only: the stream loop, the stdout\n * writes and the dispatcher live in `src/commands/mcp/`, so every decision\n * here is unit-testable without a stream in sight.\n *\n * Spec revision assumed: MCP 2025-06-18 (framing note in `./framing.ts`).\n * The lifecycle is deliberately NOT policed: this server is a stateless\n * facade over a stateless CLI, its capabilities never vary, and refusing a\n * tools/call that arrives before `initialize` would protect nothing — so\n * every request is answered on its own terms, whatever came first. What IS\n * refused: JSON-RPC batch arrays (removed in 2025-06-18; the older revisions\n * this server also negotiates allowed them, and that gap is deliberate — a\n * clear -32600 with the reason beats a half-implemented batch path no real\n * MCP client exercises).\n */\nimport { isRecord } from \"../kernel/records.js\";\nimport { LOAM_VERSION } from \"../envelope/version.js\";\nimport { toArgv } from \"./argv.js\";\nimport {\n MCP_TOOLS,\n READ_ONLY_ANNOTATIONS,\n toInputSchema,\n toolByName,\n type McpTool,\n} from \"./tools.js\";\nimport { AGENTS_MD } from \"../agent/agents-md.js\";\nimport { PROTOCOLS } from \"../agent/protocol.js\";\nimport { withoutFixTables } from \"../explain/fix-tables.js\";\n\n/** JSON-RPC 2.0 error codes this server emits. */\nexport const PARSE_ERROR = -32700;\nexport const INVALID_REQUEST = -32600;\nexport const METHOD_NOT_FOUND = -32601;\nexport const INVALID_PARAMS = -32602;\nexport const INTERNAL_ERROR = -32603;\n\n/**\n * Newest first. `initialize` echoes the client's requested version when it is\n * one of these, else answers the newest — the negotiation rule the 2025-06-18\n * lifecycle spec states for servers. All three revisions are identical in\n * everything this facade implements (stdio framing, tools/list, tools/call\n * with text content) except batching, refused above.\n */\nexport const SUPPORTED_PROTOCOL_VERSIONS = [\"2025-06-18\", \"2025-03-26\", \"2024-11-05\"] as const;\nexport const LATEST_PROTOCOL_VERSION = SUPPORTED_PROTOCOL_VERSIONS[0];\n\nconst TOOL_OUTPUT_SCHEMA = {\n type: \"object\",\n required: [\"contractVersion\", \"version\", \"ok\"],\n properties: {\n contractVersion: { const: \"1.0\" },\n version: { type: \"string\" },\n ok: { type: \"boolean\" },\n error: {\n type: \"object\",\n properties: { code: { type: \"string\" }, message: { type: \"string\" } },\n required: [\"code\", \"message\"],\n additionalProperties: true,\n },\n },\n additionalProperties: true,\n} as const;\n\nconst RESOURCE_TEXT: Readonly<Record<string, string>> = {\n \"loam://orientation\": AGENTS_MD,\n ...Object.fromEntries(\n Object.entries(PROTOCOLS).map(([name, body]) => [`loam://instructions/${name}`, body]),\n ),\n \"loam://instructions/loam-check/compact\": withoutFixTables(PROTOCOLS[\"loam-check\"]!),\n};\n\n/** A response id: echoed from the request, or null when no id could be read (parse errors). */\nexport type JsonRpcId = string | number;\n\nexport interface JsonRpcResponse extends Record<string, unknown> {\n readonly jsonrpc: \"2.0\";\n readonly id: JsonRpcId | null;\n}\n\nexport function resultResponse(id: JsonRpcId | null, result: unknown): JsonRpcResponse {\n return { jsonrpc: \"2.0\", id, result };\n}\n\n/**\n * `rpcCode`, not `code`: the stable-code drift collector\n * (test/helpers/stable-codes.ts) treats every function with a parameter named\n * `code` as an emitter of loam's stable code STRINGS and demands a literal at\n * each call site. A JSON-RPC numeric code is a different vocabulary — naming\n * the parameter into that scan would make the guard demand string literals\n * where the protocol requires numbers.\n */\nexport function errorResponse(id: JsonRpcId | null, rpcCode: number, message: string): JsonRpcResponse {\n return { jsonrpc: \"2.0\", id, error: { code: rpcCode, message } };\n}\n\n/**\n * What one inbound frame asks of the serve loop:\n * - `ignore`: a blank line, or a notification — nothing goes back.\n * - `reply`: answered here, in pure code; write the response.\n * - `call`: a validated tools/call — run `argv` through the dispatcher and\n * wrap what comes back. The argv is fully built here so the loop never\n * interprets arguments.\n */\nexport type RouteOutcome =\n | { readonly kind: \"ignore\" }\n | { readonly kind: \"reply\"; readonly response: JsonRpcResponse }\n | { readonly kind: \"call\"; readonly id: JsonRpcId; readonly toolName: string; readonly argv: readonly string[] };\n\nconst reply = (response: JsonRpcResponse): RouteOutcome => ({ kind: \"reply\", response });\n\n/** One line off the wire → what to do about it. Total: every input maps to an outcome, nothing throws. */\nexport function routeLine(line: string, tools: readonly McpTool[] = MCP_TOOLS): RouteOutcome {\n if (line.trim() === \"\") return { kind: \"ignore\" };\n let message: unknown;\n try {\n message = JSON.parse(line);\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err);\n return reply(errorResponse(null, PARSE_ERROR, `Parse error: ${detail}`));\n }\n if (Array.isArray(message)) {\n // JSON-RPC batching was removed in MCP 2025-06-18; see the module comment\n // for why the older negotiated revisions refuse it too instead of half-supporting it.\n return reply(errorResponse(null, INVALID_REQUEST, \"Invalid Request: JSON-RPC batch arrays are not supported\"));\n }\n if (!isRecord(message)) {\n return reply(errorResponse(null, INVALID_REQUEST, \"Invalid Request: a message must be a JSON object\"));\n }\n const rawId = message[\"id\"];\n // Three id states, kept apart because they demand opposite answers. ABSENT\n // (or an explicit null, reserved for unanswerable errors) is a notification.\n // A PRESENT id that is not a string or a finite number — an object, a bool,\n // an array, a JSON `1e999` that parsed to Infinity — is a malformed REQUEST:\n // the client is waiting on a reply, and folding it into the notification\n // branch answers with silence, which for a request is a hang, not an error.\n const validId = typeof rawId === \"string\" || (typeof rawId === \"number\" && Number.isFinite(rawId)) ? rawId : null;\n if (message[\"jsonrpc\"] !== \"2.0\") {\n return reply(errorResponse(validId, INVALID_REQUEST, \"Invalid Request: jsonrpc must be the string \\\"2.0\\\"\"));\n }\n const method = message[\"method\"];\n if (typeof method !== \"string\") {\n return reply(errorResponse(validId, INVALID_REQUEST, \"Invalid Request: method must be a string\"));\n }\n if (!(\"id\" in message) || rawId === null) return { kind: \"ignore\" };\n if (validId === null) {\n // id null in the response: the request's own id is unusable, and null is\n // exactly the id JSON-RPC reserves for that answer.\n return reply(errorResponse(null, INVALID_REQUEST, \"Invalid Request: id must be a string or a finite number\"));\n }\n return routeRequest(validId, method, message[\"params\"], tools);\n}\n\nfunction routeRequest(\n id: JsonRpcId,\n method: string,\n params: unknown,\n tools: readonly McpTool[],\n): RouteOutcome {\n switch (method) {\n case \"initialize\":\n return reply(resultResponse(id, initializeResult(params)));\n case \"ping\":\n return reply(resultResponse(id, {}));\n case \"tools/list\":\n // No pagination: the whole tool table fits in one page, so `nextCursor`\n // is omitted rather than emitted empty — the spec reads an absent\n // cursor as \"done\".\n return reply(resultResponse(id, {\n tools: tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: toInputSchema(tool),\n outputSchema: TOOL_OUTPUT_SCHEMA,\n // Base tools share the read-only default; opt-in authoring tools\n // carry their own mutation annotations in author-tools.ts.\n annotations: tool.annotations ?? READ_ONLY_ANNOTATIONS,\n })),\n }));\n case \"resources/list\":\n return reply(resultResponse(id, {\n resources: Object.keys(RESOURCE_TEXT).map((uri) => ({\n uri,\n name: uri === \"loam://orientation\" ? \"loam orientation\" : uri.slice(\"loam://instructions/\".length),\n description:\n uri === \"loam://orientation\"\n ? \"Small always-loaded map of a loam repository\"\n : \"Version-matched loam workflow, support protocol or reference page\",\n mimeType: \"text/markdown\",\n })),\n }));\n case \"resources/read\":\n return routeResourceRead(id, params);\n case \"tools/call\":\n return routeToolCall(id, params, tools);\n default:\n // Everything else — including a literal `shutdown`, which is LSP's\n // lifecycle and not MCP's (the MCP stdio lifecycle ends at stdin EOF).\n return reply(errorResponse(id, METHOD_NOT_FOUND, `Method not found: ${method}`));\n }\n}\n\nfunction routeResourceRead(id: JsonRpcId, params: unknown): RouteOutcome {\n if (!isRecord(params) || typeof params[\"uri\"] !== \"string\") {\n return reply(errorResponse(id, INVALID_PARAMS, \"resources/read requires params.uri\"));\n }\n const uri = params[\"uri\"];\n const text = RESOURCE_TEXT[uri];\n if (text === undefined) {\n return reply(errorResponse(id, INVALID_PARAMS, `Unknown resource '${uri}'`));\n }\n return reply(resultResponse(id, { contents: [{ uri, mimeType: \"text/markdown\", text }] }));\n}\n\nfunction routeToolCall(\n id: JsonRpcId,\n params: unknown,\n tools: readonly McpTool[],\n): RouteOutcome {\n if (!isRecord(params) || typeof params[\"name\"] !== \"string\") {\n return reply(errorResponse(id, INVALID_PARAMS, \"tools/call requires params.name naming a tool\"));\n }\n const tool = toolByName(params[\"name\"], tools);\n if (tool === undefined) {\n const names = tools.map((t) => t.name).join(\", \");\n return reply(errorResponse(id, INVALID_PARAMS, `Unknown tool '${params[\"name\"]}' — this server offers: ${names}`));\n }\n const rawArgs = params[\"arguments\"] ?? {};\n if (!isRecord(rawArgs)) {\n return reply(errorResponse(id, INVALID_PARAMS, \"tools/call params.arguments must be an object when present\"));\n }\n const built = toArgv(tool, rawArgs);\n if (!built.ok) return reply(errorResponse(id, INVALID_PARAMS, built.problem));\n return { kind: \"call\", id, toolName: tool.name, argv: built.argv };\n}\n\n/**\n * The `initialize` result. The version rule: echo the requested revision when\n * this server supports it, otherwise answer the newest it does — the client\n * then decides whether it can live with that (2025-06-18 lifecycle,\n * \"Version Negotiation\").\n */\nexport function initializeResult(params: unknown): Record<string, unknown> {\n const requested = isRecord(params) ? params[\"protocolVersion\"] : undefined;\n const negotiated =\n typeof requested === \"string\" && (SUPPORTED_PROTOCOL_VERSIONS as readonly string[]).includes(requested)\n ? requested\n : LATEST_PROTOCOL_VERSION;\n return {\n protocolVersion: negotiated,\n capabilities: {\n // The sets never change while the server lives, so no\n // listChanged notification is declared — announcing one and never\n // sending it would be a promise, not a capability.\n tools: {},\n resources: {},\n },\n serverInfo: { name: \"loam\", version: LOAM_VERSION },\n instructions:\n \"Every tool result is a loam --json envelope (contractVersion 1.0): branch on ok, \" +\n \"and on error.code when ok is false — the same machine contract the CLI prints.\",\n };\n}\n\n/** What the dispatcher hands back from one tool call, before it becomes a protocol reply. */\nexport interface ToolRunOutcome {\n readonly stdout: string;\n readonly stderr: string;\n readonly code: number;\n}\n\nexport type ToolReply =\n | { readonly kind: \"result\"; readonly result: Record<string, unknown> }\n | { readonly kind: \"error\"; readonly code: number; readonly message: string };\n\n/**\n * One tool run wrapped as an MCP tool result. The envelope rides VERBATIM in\n * content[0].text — one machine contract, not two — and again parsed as\n * structuredContent for clients that read that field.\n *\n * `isError` follows the ENVELOPE's `ok`, and the exit code only when no\n * envelope could be parsed. The two disagree on purpose for half the tool\n * set: validate, doctor, gate, context and delta all have graded answers\n * that exit 1 while reporting `ok: true` — an invalid fleet, a blocked\n * doctor, a `verdict: \"fail\"` deploy gate. Those exits are CI levers, not\n * call failures, and an MCP host renders `isError: true` as \"the call\n * failed\" and may discard structuredContent — which for loam_gate would\n * discard the exact verdict the caller asked for. `ok: false` is the one\n * signal that means \"loam refused to answer\", so it is the one isError\n * mirrors; the exit-code fallback exists only for stdout that parsed as no\n * envelope at all.\n *\n * An EMPTY stdout is a protocol error, not a quiet result: with `--json` on\n * every argv, a command that printed no envelope is a command whose answer\n * was lost, and \"nobody could look\" must stay distinguishable from any\n * genuine envelope — even a refusing one.\n */\nexport function toolReply(run: ToolRunOutcome): ToolReply {\n if (run.stdout.trim() === \"\") {\n const hint = run.stderr.trim() === \"\" ? \"\" : ` stderr: ${run.stderr.trim()}`;\n return {\n kind: \"error\",\n code: INTERNAL_ERROR,\n message: `the command exited ${run.code} without printing a --json envelope, so there is no result to return.${hint}`,\n };\n }\n let structured: Record<string, unknown> | undefined;\n try {\n const parsed: unknown = JSON.parse(run.stdout);\n // structuredContent must be an object; the envelope always is.\n structured = isRecord(parsed) ? parsed : undefined;\n } catch {\n // The fallback below handles both invalid JSON and valid non-object JSON.\n }\n if (structured === undefined) {\n // Preserve the bytes in content, but keep the declared output contract:\n // an MCP client should never have to branch on the absence of\n // structuredContent after tools/list promised a schema.\n structured = {\n contractVersion: \"1.0\",\n version: LOAM_VERSION,\n ok: false,\n error: {\n code: \"internal\",\n message: \"the command did not print a JSON object envelope\",\n },\n raw: run.stdout,\n };\n }\n const envelopeOk = structured?.[\"ok\"];\n return {\n kind: \"result\",\n result: {\n content: [{ type: \"text\", text: run.stdout }],\n structuredContent: structured,\n isError: typeof envelopeOk === \"boolean\" ? !envelopeOk : run.code !== 0,\n },\n };\n}\n"]}
|