@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/commands/dependencies.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/commands/dependencies.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAA+C,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAM7E,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,cAAc,CAAC;SACvB,QAAQ,CAAC,aAAa,EAAE,uDAAuD,CAAC;SAChF,WAAW,CAAC,uEAAuE,CAAC;SACpF,MAAM,CAAC,QAAQ,EAAE,qDAAqD,CAAC;SACvE,MAAM,CAAC,KAAK,EAAE,UAA8B,EAAE,IAAyB,EAAE,EAAE;QAC1E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,MAAM,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,UAAU,KAAK,SAAS;YACtC,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,MAAM,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QACzE,IAAI,UAAU,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACjD,yEAAyE;YACzE,0EAA0E;YAC1E,yEAAyE;YACzE,wEAAwE;YACxE,oDAAoD;YACpD,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;YAC/F,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAC9E,IAAI,IAAI,EAAE,CAAC;YACT,QAAQ,CAAC;gBACP,OAAO,EAAE,cAAc;gBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,IAAI;gBAC5B,GAAG,KAAK;aACT,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,UAAU,CAAC,MAAwB;IAC1C,OAAO,MAAM,CAAC,IAAI,KAAK,WAAW;QAChC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,cAAc,MAAM,CAAC,WAAW,EAAE;QACrD,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC5D,CAAC;AAED,SAAS,UAAU,CAAC,KAAsB,EAAE,SAAkB;IAC5D,MAAM,KAAK,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,SAAS,oBAAoB,CAAC;IAC7F,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAEzF,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrF,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACjF,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YACzC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;gBAAE,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC7B,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,KAAK,aAAa;gBAC3C,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;gBACxC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;YACrB,uEAAuE;YACvE,wEAAwE;YACxE,yEAAyE;YACzE,0EAA0E;YAC1E,4DAA4D;YAC5D,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;YACpE,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,IAAI,QAAQ,CAAC,QAAQ,MAAM,GAAG,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC","sourcesContent":["import type { Command } from \"commander\";\nimport { loadConfig } from \"../core/envelope/config.js\";\nimport { analyzeDependencies } from \"../core/dependencies/dependencies.js\";\nimport { type DependencyGraph, type DependencyReason } from \"../core/dependencies/facts.js\";\nimport { FleetContext } from \"../core/fleet-context.js\";\nimport { emitJson, fail, reportNoConfig } from \"../core/envelope/json.js\";\nimport { missingFeatureMessage, resolveFeature } from \"../core/repo/repo.js\";\n\ninterface DependenciesOptions {\n json?: boolean;\n}\n\nexport function registerDependencies(program: Command): void {\n program\n .command(\"dependencies\")\n .argument(\"[featureId]\", \"active feature id; omit for the whole in-flight graph\")\n .description(\"Show dependencies and conflicts derived from active feature artifacts\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .action(async (featureArg: string | undefined, opts: DependenciesOptions) => {\n const json = opts.json === true;\n const loaded = await loadConfig();\n if (loaded.kind !== \"loaded\") {\n reportNoConfig(json, loaded);\n return;\n }\n const config = loaded.config;\n\n const context = new FleetContext();\n const feature = featureArg === undefined\n ? null\n : await resolveFeature(config.docsDir, featureArg, \"exclude\", context);\n if (featureArg !== undefined && feature === null) {\n // The shared miss message rather than a local one: this command resolves\n // in `exclude` mode, so the commonest miss is an id that HAS shipped, and\n // \"no active feature\" leaves the reader to discover that themselves. The\n // helper reuses the context already built above, so saying so costs one\n // enumeration this invocation has already paid for.\n fail(json, \"unknown-target\", await missingFeatureMessage(config.docsDir, featureArg, context));\n return;\n }\n\n const graph = await analyzeDependencies(config.docsDir, feature?.id, context);\n if (json) {\n emitJson({\n command: \"dependencies\",\n docsDir: config.docsDir,\n feature: feature?.id ?? null,\n ...graph,\n });\n return;\n }\n printGraph(graph, feature?.id);\n });\n}\n\nfunction reasonText(reason: DependencyReason): string {\n return reason.kind === \"operation\"\n ? `${reason.service} operation ${reason.operationId}`\n : `${reason.service}/${reason.axis} ${reason.identity}`;\n}\n\nfunction printGraph(graph: DependencyGraph, featureId?: string): void {\n const scope = featureId === undefined ? \"active features\" : `${featureId} and prerequisites`;\n console.log(`dependencies — ${scope} (${graph.nodes.length})`);\n console.log(` order: ${graph.order.length === 0 ? \"(none)\" : graph.order.join(\" → \")}`);\n\n for (const node of graph.nodes) {\n console.log(`\\n ${node.id}${node.dependsOn.length === 0 ? \" (independent)\" : \"\"}`);\n for (const edge of graph.edges.filter((candidate) => candidate.from === node.id)) {\n console.log(` depends on ${edge.to}`);\n for (const reason of edge.reasons) console.log(` - ${reasonText(reason)}`);\n }\n }\n\n if (graph.conflicts.length > 0) {\n console.log(\"\\n conflicts\");\n for (const conflict of graph.conflicts) {\n const where = conflict.kind === \"requirement\"\n ? `${conflict.service}/${conflict.axis}`\n : conflict.service;\n // \"added by\" vs \"changed by\": the two collisions want different fixes.\n // Two features ADDING the same identity is usually duplicated work that\n // should become one feature; two features CHANGING it is usually genuine\n // parallel work whose second archive would silently overwrite the first's\n // full text, so the losers need to be re-based, not merged.\n const how = conflict.change === \"added\" ? \"added by\" : \"changed by\";\n console.log(` ! ${where} ${conflict.identity} — ${how} ${conflict.features.join(\", \")}`);\n }\n }\n\n if (graph.cycles.length > 0) {\n console.log(\"\\n cycles\");\n for (const cycle of graph.cycles) console.log(` ! ${cycle.join(\" ↔ \")}`);\n }\n}\n"]}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { loadConfig } from "../../core/envelope/config.js";
|
|
2
|
+
import { emitJson, fail, reportNoConfig } from "../../core/envelope/json.js";
|
|
3
|
+
import { findingJson } from "../../core/vocabulary/report.js";
|
|
4
|
+
import { docsRepoReady, reportDocsRepoError, reportRepositoryUnavailable } from "../policy/gate.js";
|
|
5
|
+
import { DocsRepoUnavailableError } from "../../core/repo/state.js";
|
|
6
|
+
import { FleetContext } from "../../core/fleet-context.js";
|
|
7
|
+
import { resolveBase } from "../../core/diff/base-git.js";
|
|
8
|
+
import { readBaseFleet } from "../../core/diff/base-state.js";
|
|
9
|
+
import { readCurrentFleet } from "../../core/diff/current-state.js";
|
|
10
|
+
import { victimIndex } from "../../core/diff/victims.js";
|
|
11
|
+
import { computeDiff } from "../../core/diff/semantic.js";
|
|
12
|
+
import { printDiff } from "./print.js";
|
|
13
|
+
export function registerDiff(program) {
|
|
14
|
+
program
|
|
15
|
+
.command("diff")
|
|
16
|
+
.description("Semantic diff of the living docs against a base git ref of the docs repo — fleet-meaningful changes, with the joined victims of every removal named")
|
|
17
|
+
.requiredOption("--base <ref>", "base git ref of the docs repo (e.g. main, origin/main, a commit sha)")
|
|
18
|
+
.option("--json", "emit the machine contract instead of the human view")
|
|
19
|
+
.action(async (opts) => {
|
|
20
|
+
const json = opts.json === true;
|
|
21
|
+
const loaded = await loadConfig();
|
|
22
|
+
if (loaded.kind !== "loaded") {
|
|
23
|
+
reportNoConfig(json, loaded);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const { docsDir } = loaded.config;
|
|
27
|
+
// "services" on purpose: both sides of the diff are enumerations of the
|
|
28
|
+
// fleet, and a docsDir with no services/ has no fleet to diff.
|
|
29
|
+
if (!docsRepoReady(json, docsDir, "services"))
|
|
30
|
+
return;
|
|
31
|
+
const base = await resolveBase(docsDir, opts.base);
|
|
32
|
+
// Unlike provenance's "git will not say", diff REFUSES when git cannot
|
|
33
|
+
// answer: without the base there is no honest diff, and a silently
|
|
34
|
+
// empty base would report the whole fleet as added.
|
|
35
|
+
if (base.kind === "no-git") {
|
|
36
|
+
fail(json, "repository-unavailable", `The docs repo at ${docsDir} is not somewhere git can answer from (${base.detail}) — ` +
|
|
37
|
+
`loam diff reads the base state with read-only git questions (rev-parse/ls-tree/show), so it needs the docs repo ` +
|
|
38
|
+
`to be a git checkout with the base ref present. Clone the docs repo with its history, then re-run.`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (base.kind === "no-ref") {
|
|
42
|
+
fail(json, "unknown-target", `--base ${opts.base} does not resolve to a commit in the docs repo at ${docsDir}` +
|
|
43
|
+
`${base.detail === "" ? "" : ` (${base.detail})`}. ` +
|
|
44
|
+
`Pass a ref that exists there — main, origin/main, a tag or a commit sha — fetching first if it lives on the remote.`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const context = new FleetContext();
|
|
48
|
+
let diff;
|
|
49
|
+
try {
|
|
50
|
+
const baseFleet = await readBaseFleet({ docsDir, commit: base.commit, prefix: base.prefix });
|
|
51
|
+
if (baseFleet.kind === "failed") {
|
|
52
|
+
fail(json, "repository-unavailable", `git could not list services/ at ${opts.base} in the docs repo at ${docsDir} (${baseFleet.detail}) — ` +
|
|
53
|
+
`without the base tree there is no honest diff. Re-run once git can answer.`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const current = await readCurrentFleet(docsDir, context);
|
|
57
|
+
const victims = victimIndex({ docsDir, context, current: current.services, ambiguous: current.ambiguous });
|
|
58
|
+
diff = await computeDiff({ base: baseFleet.fleet, current, victims });
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
if (err instanceof DocsRepoUnavailableError) {
|
|
62
|
+
reportDocsRepoError(json, err);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
reportRepositoryUnavailable(json, err, "the fleet could not be diffed", docsDir);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// Error findings gate (the validate convention); suspended axes gate too,
|
|
69
|
+
// because an exit 0 over a diff nobody could fully read would be the
|
|
70
|
+
// "green over zero services" failure one step later.
|
|
71
|
+
if (diff.breaking || diff.summary.unreadable > 0)
|
|
72
|
+
process.exitCode = 1;
|
|
73
|
+
if (json) {
|
|
74
|
+
emitJson({
|
|
75
|
+
command: "diff",
|
|
76
|
+
docsDir,
|
|
77
|
+
base: { ref: opts.base, commit: base.commit },
|
|
78
|
+
services: diff.services.map((s) => ({
|
|
79
|
+
id: s.id,
|
|
80
|
+
change: s.change,
|
|
81
|
+
findings: s.findings.map((finding) => findingJson(finding, { path: `services/${s.id}`, role: "scope" })),
|
|
82
|
+
unreadable: s.unreadable,
|
|
83
|
+
...(s.ambiguous === undefined ? {} : { ambiguous: s.ambiguous }),
|
|
84
|
+
})),
|
|
85
|
+
breaking: diff.breaking,
|
|
86
|
+
summary: diff.summary,
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
printDiff(diff, { ref: opts.base, commit: base.commit });
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../src/commands/diff/diff.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loam diff --base <ref>` — the review lens over a docs-repo branch: what\n * changed in fleet-meaningful terms since a base git ref of the DOCS repo,\n * with the current consumers of every removal named. Read-only by\n * construction: the base state comes out of git's object store\n * (`core/diff/base-git.ts`), the current state off the working tree, and\n * nothing is written anywhere.\n *\n * Exit semantics: 0 when the diff was computed and nothing is breaking AND\n * every artifact on both sides could be read; 1 for a refusal, for any\n * error-severity finding (a removal the fleet still consumes — which is what\n * makes this a free gate on a docs-repo PR), and for a diff with suspended\n * axes — \"nobody could look\" must not exit as \"nothing changed\"\n * (`loam context` set that precedent for silent holes).\n */\nimport type { Command } from \"commander\";\nimport { loadConfig } from \"../../core/envelope/config.js\";\nimport { emitJson, fail, reportNoConfig } from \"../../core/envelope/json.js\";\nimport { findingJson } from \"../../core/vocabulary/report.js\";\nimport { docsRepoReady, reportDocsRepoError, reportRepositoryUnavailable } from \"../policy/gate.js\";\nimport { DocsRepoUnavailableError } from \"../../core/repo/state.js\";\nimport { FleetContext } from \"../../core/fleet-context.js\";\nimport { resolveBase } from \"../../core/diff/base-git.js\";\nimport { readBaseFleet } from \"../../core/diff/base-state.js\";\nimport { readCurrentFleet } from \"../../core/diff/current-state.js\";\nimport { victimIndex } from \"../../core/diff/victims.js\";\nimport { computeDiff, type FleetDiff } from \"../../core/diff/semantic.js\";\nimport { printDiff } from \"./print.js\";\n\ninterface DiffOptions {\n base: string;\n json?: boolean;\n}\n\nexport function registerDiff(program: Command): void {\n program\n .command(\"diff\")\n .description(\"Semantic diff of the living docs against a base git ref of the docs repo — fleet-meaningful changes, with the joined victims of every removal named\")\n .requiredOption(\"--base <ref>\", \"base git ref of the docs repo (e.g. main, origin/main, a commit sha)\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .action(async (opts: DiffOptions) => {\n const json = opts.json === true;\n const loaded = await loadConfig();\n if (loaded.kind !== \"loaded\") {\n reportNoConfig(json, loaded);\n return;\n }\n const { docsDir } = loaded.config;\n // \"services\" on purpose: both sides of the diff are enumerations of the\n // fleet, and a docsDir with no services/ has no fleet to diff.\n if (!docsRepoReady(json, docsDir, \"services\")) return;\n\n const base = await resolveBase(docsDir, opts.base);\n // Unlike provenance's \"git will not say\", diff REFUSES when git cannot\n // answer: without the base there is no honest diff, and a silently\n // empty base would report the whole fleet as added.\n if (base.kind === \"no-git\") {\n fail(\n json,\n \"repository-unavailable\",\n `The docs repo at ${docsDir} is not somewhere git can answer from (${base.detail}) — ` +\n `loam diff reads the base state with read-only git questions (rev-parse/ls-tree/show), so it needs the docs repo ` +\n `to be a git checkout with the base ref present. Clone the docs repo with its history, then re-run.`,\n );\n return;\n }\n if (base.kind === \"no-ref\") {\n fail(\n json,\n \"unknown-target\",\n `--base ${opts.base} does not resolve to a commit in the docs repo at ${docsDir}` +\n `${base.detail === \"\" ? \"\" : ` (${base.detail})`}. ` +\n `Pass a ref that exists there — main, origin/main, a tag or a commit sha — fetching first if it lives on the remote.`,\n );\n return;\n }\n\n const context = new FleetContext();\n let diff: FleetDiff;\n try {\n const baseFleet = await readBaseFleet({ docsDir, commit: base.commit, prefix: base.prefix });\n if (baseFleet.kind === \"failed\") {\n fail(\n json,\n \"repository-unavailable\",\n `git could not list services/ at ${opts.base} in the docs repo at ${docsDir} (${baseFleet.detail}) — ` +\n `without the base tree there is no honest diff. Re-run once git can answer.`,\n );\n return;\n }\n const current = await readCurrentFleet(docsDir, context);\n const victims = victimIndex({ docsDir, context, current: current.services, ambiguous: current.ambiguous });\n diff = await computeDiff({ base: baseFleet.fleet, current, victims });\n } catch (err) {\n if (err instanceof DocsRepoUnavailableError) {\n reportDocsRepoError(json, err);\n return;\n }\n reportRepositoryUnavailable(json, err, \"the fleet could not be diffed\", docsDir);\n return;\n }\n\n // Error findings gate (the validate convention); suspended axes gate too,\n // because an exit 0 over a diff nobody could fully read would be the\n // \"green over zero services\" failure one step later.\n if (diff.breaking || diff.summary.unreadable > 0) process.exitCode = 1;\n if (json) {\n emitJson({\n command: \"diff\",\n docsDir,\n base: { ref: opts.base, commit: base.commit },\n services: diff.services.map((s) => ({\n id: s.id,\n change: s.change,\n findings: s.findings.map((finding) =>\n findingJson(finding, { path: `services/${s.id}`, role: \"scope\" }),\n ),\n unreadable: s.unreadable,\n ...(s.ambiguous === undefined ? {} : { ambiguous: s.ambiguous }),\n })),\n breaking: diff.breaking,\n summary: diff.summary,\n });\n return;\n }\n printDiff(diff, { ref: opts.base, commit: base.commit });\n });\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human rendering for `loam diff` — per-service blocks with the shared
|
|
3
|
+
* severity glyphs, victims as detail lines, one summary line. The JSON side
|
|
4
|
+
* lives in `diff.ts` beside the envelope; this module owns only the text.
|
|
5
|
+
*/
|
|
6
|
+
import { SEVERITY_MARK } from "../../core/vocabulary/report.js";
|
|
7
|
+
function printService(s) {
|
|
8
|
+
console.log(`\n${s.id} — ${s.change}`);
|
|
9
|
+
if (s.ambiguous !== undefined) {
|
|
10
|
+
console.log(` ⚠ service identity ambiguous — claimed by ${s.ambiguous.join(" and ")}; ` +
|
|
11
|
+
`findings for this service are suspended, not empty`);
|
|
12
|
+
}
|
|
13
|
+
for (const u of s.unreadable) {
|
|
14
|
+
// Suspension is not silence: the reader must see that this axis was not
|
|
15
|
+
// graded, or an unreadable file reads as "nothing changed here".
|
|
16
|
+
console.log(` ⚠ ${u.side}: ${u.path} could not be read — ${u.error}; findings on this axis are suspended, not empty`);
|
|
17
|
+
}
|
|
18
|
+
for (const f of s.findings) {
|
|
19
|
+
console.log(` ${SEVERITY_MARK[f.severity]} ${f.code}: ${f.message}`);
|
|
20
|
+
for (const d of f.details ?? [])
|
|
21
|
+
console.log(` - ${d}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function printDiff(diff, base) {
|
|
25
|
+
console.log(`diff vs ${base.ref} (${base.commit.slice(0, 12)})`);
|
|
26
|
+
const changed = diff.services.filter((s) => s.change !== "unchanged");
|
|
27
|
+
if (changed.length === 0) {
|
|
28
|
+
console.log(" no fleet-meaningful changes");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
for (const s of changed)
|
|
32
|
+
printService(s);
|
|
33
|
+
const sum = diff.summary;
|
|
34
|
+
console.log(`\n${sum.added} added · ${sum.removed} removed · ${sum.modified} modified · ${sum.deprecated} deprecated` +
|
|
35
|
+
(sum.unreadable > 0 ? ` · ${sum.unreadable} unreadable` : "") +
|
|
36
|
+
(diff.breaking ? " · BREAKING" : ""));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=print.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"print.js","sourceRoot":"","sources":["../../../src/commands/diff/print.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAGhE,SAAS,YAAY,CAAC,CAAc;IAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CACT,+CAA+C,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI;YAC1E,oDAAoD,CACvD,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QAC7B,wEAAwE;QACxE,iEAAiE;QACjE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,wBAAwB,CAAC,CAAC,KAAK,kDAAkD,CAAC,CAAC;IACzH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE;YAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAe,EAAE,IAAqC;IAC9E,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;IACtE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;IACzB,OAAO,CAAC,GAAG,CACT,KAAK,GAAG,CAAC,KAAK,YAAY,GAAG,CAAC,OAAO,cAAc,GAAG,CAAC,QAAQ,eAAe,GAAG,CAAC,UAAU,aAAa;QACvG,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,UAAU,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CACvC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Human rendering for `loam diff` — per-service blocks with the shared\n * severity glyphs, victims as detail lines, one summary line. The JSON side\n * lives in `diff.ts` beside the envelope; this module owns only the text.\n */\nimport { SEVERITY_MARK } from \"../../core/vocabulary/report.js\";\nimport type { FleetDiff, ServiceDiff } from \"../../core/diff/semantic.js\";\n\nfunction printService(s: ServiceDiff): void {\n console.log(`\\n${s.id} — ${s.change}`);\n if (s.ambiguous !== undefined) {\n console.log(\n ` ⚠ service identity ambiguous — claimed by ${s.ambiguous.join(\" and \")}; ` +\n `findings for this service are suspended, not empty`,\n );\n }\n for (const u of s.unreadable) {\n // Suspension is not silence: the reader must see that this axis was not\n // graded, or an unreadable file reads as \"nothing changed here\".\n console.log(` ⚠ ${u.side}: ${u.path} could not be read — ${u.error}; findings on this axis are suspended, not empty`);\n }\n for (const f of s.findings) {\n console.log(` ${SEVERITY_MARK[f.severity]} ${f.code}: ${f.message}`);\n for (const d of f.details ?? []) console.log(` - ${d}`);\n }\n}\n\nexport function printDiff(diff: FleetDiff, base: { ref: string; commit: string }): void {\n console.log(`diff vs ${base.ref} (${base.commit.slice(0, 12)})`);\n const changed = diff.services.filter((s) => s.change !== \"unchanged\");\n if (changed.length === 0) {\n console.log(\" no fleet-meaningful changes\");\n return;\n }\n for (const s of changed) printService(s);\n const sum = diff.summary;\n console.log(\n `\\n${sum.added} added · ${sum.removed} removed · ${sum.modified} modified · ${sum.deprecated} deprecated` +\n (sum.unreadable > 0 ? ` · ${sum.unreadable} unreadable` : \"\") +\n (diff.breaking ? \" · BREAKING\" : \"\"),\n );\n}\n"]}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { diagnose } from "../core/doctor.js";
|
|
2
|
-
import {
|
|
1
|
+
import { diagnose } from "../core/doctor/doctor.js";
|
|
2
|
+
import {} from "../core/doctor/report.js";
|
|
3
|
+
import { emitJson } from "../core/envelope/json.js";
|
|
3
4
|
export function registerDoctor(program) {
|
|
4
5
|
program
|
|
5
6
|
.command("doctor")
|
|
@@ -44,7 +45,7 @@ function writePathLabel(residue) {
|
|
|
44
45
|
? ["interrupted commit (unreadable)"]
|
|
45
46
|
: residue.intent === null
|
|
46
47
|
? []
|
|
47
|
-
: [`interrupted ${residue.intent.command} of ${residue.intent.feature}`]),
|
|
48
|
+
: [`interrupted ${residue.intent.command} of ${"feature" in residue.intent ? residue.intent.feature : residue.intent.target}`]),
|
|
48
49
|
...(residue.temps.length === 0 ? [] : [`${residue.temps.length} orphaned temp file(s)`]),
|
|
49
50
|
];
|
|
50
51
|
return parts.length === 0 ? "clean" : parts.join(" · ");
|
|
@@ -64,7 +65,7 @@ function printDoctor(report) {
|
|
|
64
65
|
// line above it, this is state, not a complaint. Only the findings block is
|
|
65
66
|
// silent when there is nothing to say.
|
|
66
67
|
const agents = report.agents;
|
|
67
|
-
console.log(` agents ${agents.tools.length === 0 ? "(none)" : agents.tools.join(", ")}`
|
|
68
|
+
console.log(` agents ${agents.tools.length === 0 ? "(none)" : agents.tools.join(", ")} · ${agents.profile}`
|
|
68
69
|
+ ` (${agents.toolsSource}) · ${agents.plannedFiles} files · ${agents.missingFiles.length} missing`
|
|
69
70
|
+ ` · ${agents.staleFiles.length} stale · AGENTS.md ${stampLabel(agents.stamp)}`);
|
|
70
71
|
// The write path is state too, and its clean answer is the one worth printing
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAqB,MAAM,
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Command } from \"commander\";\nimport { diagnose } from \"../core/doctor/doctor.js\";\nimport { type DoctorReport } from \"../core/doctor/report.js\";\nimport { emitJson } from \"../core/envelope/json.js\";\n\ninterface DoctorOptions {\n json?: boolean;\n}\n\nexport function registerDoctor(program: Command): void {\n program\n .command(\"doctor\")\n .description(\"Diagnose local loam configuration and docs-repo accessibility without writing\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .action(async (opts: DoctorOptions) => {\n const report = await diagnose();\n if (opts.json === true) emitJson({ command: \"doctor\", ...report });\n else printDoctor(report);\n if (!report.healthy) process.exitCode = 1;\n });\n}\n\nfunction yesNo(value: boolean): string {\n return value ? \"yes\" : \"no\";\n}\n\n/**\n * The stamp as one readable token. \"absent\" and \"unstamped\" are kept apart\n * because they are different repos: the first has no AGENTS.md at all, the\n * second has one nobody has claimed a version for.\n */\nfunction stampLabel(stamp: DoctorReport[\"agents\"][\"stamp\"]): string {\n if (!stamp.present) return \"absent\";\n if (stamp.version === null) return \"unstamped\";\n return `v${stamp.version}${stamp.stale ? \" (stale)\" : \"\"}`;\n}\n\n/**\n * What a killed writer left in the docs repo, as one line. \"clean\" is the\n * answer on every healthy repo, and \"(unresolved)\" keeps it apart from clean:\n * a docsDir that never resolved was never looked at.\n */\nfunction writePathLabel(residue: DoctorReport[\"writePath\"]): string {\n if (residue === null) return \"(unresolved)\";\n const parts = [\n ...(residue.lock === null ? [] : [`lock held${residue.lock.stale ? \" (stale)\" : \"\"}`]),\n ...(residue.intentUnreadable\n ? [\"interrupted commit (unreadable)\"]\n : residue.intent === null\n ? []\n : [`interrupted ${residue.intent.command} of ${\"feature\" in residue.intent ? residue.intent.feature : residue.intent.target}`]),\n ...(residue.temps.length === 0 ? [] : [`${residue.temps.length} orphaned temp file(s)`]),\n ];\n return parts.length === 0 ? \"clean\" : parts.join(\" · \");\n}\n\nfunction printDoctor(report: DoctorReport): void {\n console.log(`loam doctor — ${report.healthy ? \"healthy\" : \"blocked\"}`);\n console.log(` runtime ${report.runtime.package}@${report.runtime.version}`);\n console.log(` node ${report.runtime.node} ${report.runtime.platform}/${report.runtime.arch}`);\n console.log(` config ${report.config.status} ${report.config.path}`);\n if (report.config.error !== null) console.log(` ${report.config.error}`);\n console.log(` docsDir ${report.docs.path ?? \"(unresolved)\"}`);\n console.log(\n ` access exists ${yesNo(report.docs.exists)} · read ${yesNo(report.docs.readable)} · write ${yesNo(report.docs.writable)}`,\n );\n console.log(\n ` fleet services/ ${yesNo(report.docs.servicesDir)} · landscape ${yesNo(report.docs.landscape)} · ${report.counts.services} services · ${report.counts.activeFeatures} active features`,\n );\n console.log(\n ` binding ${report.currentService.configured ?? \"(none)\"} · ${report.currentService.status}`,\n );\n // The agent surface is reported whether or not it has drifted — like every\n // line above it, this is state, not a complaint. Only the findings block is\n // silent when there is nothing to say.\n const agents = report.agents;\n console.log(\n ` agents ${agents.tools.length === 0 ? \"(none)\" : agents.tools.join(\", \")} · ${agents.profile}`\n + ` (${agents.toolsSource}) · ${agents.plannedFiles} files · ${agents.missingFiles.length} missing`\n + ` · ${agents.staleFiles.length} stale · AGENTS.md ${stampLabel(agents.stamp)}`,\n );\n // The write path is state too, and its clean answer is the one worth printing\n // most often: a reader who has just been told the docs are half-written needs\n // to see it go away.\n console.log(` write path ${writePathLabel(report.writePath)}`);\n if (report.findings.length > 0) {\n console.log(\"\\n findings\");\n for (const finding of report.findings) {\n console.log(` ${finding.severity === \"blocker\" ? \"✗\" : \"⚠\"} ${finding.code}: ${finding.message}`);\n // The fix is printed on its own indented line rather than appended to the\n // message: what is wrong and what to type are two different sentences,\n // and someone scanning a blocked repo reads down the `fix:` column.\n console.log(` fix: ${finding.fix}`);\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { emitJson, fail } from "../../core/envelope/json.js";
|
|
2
|
+
import { LOAM_VERSION } from "../../core/envelope/version.js";
|
|
3
|
+
import { explainSubject, firstSentence, knownSubjects, listCodes, listTerms, } from "../../core/explain/lookup.js";
|
|
4
|
+
import { nearestIds } from "../../core/repo/entries.js";
|
|
5
|
+
// Interpolated from the registry that owns the terms, never hand-listed: a
|
|
6
|
+
// copied list beside TERMS is a list that silently trails it.
|
|
7
|
+
const TERM_LIST = listTerms()
|
|
8
|
+
.map(({ term }) => term)
|
|
9
|
+
.join(", ");
|
|
10
|
+
/** The listing printed when no subject is asked for — also where codes are said to come from. */
|
|
11
|
+
function printTermListing(json) {
|
|
12
|
+
const terms = listTerms();
|
|
13
|
+
if (json) {
|
|
14
|
+
emitJson({ command: "explain", version: LOAM_VERSION, terms: terms.map(({ term, summary }) => ({ term, description: summary })) });
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
console.log(`loam ${LOAM_VERSION} — the vocabulary\n`);
|
|
18
|
+
const width = Math.max(...terms.map(({ term }) => term.length));
|
|
19
|
+
for (const { term, summary } of terms)
|
|
20
|
+
console.log(` ${term.padEnd(width)} ${summary}`);
|
|
21
|
+
console.log("\nFinding codes come from `loam validate` and `loam verify` output; refusal codes arrive as error.code" +
|
|
22
|
+
"\nin any --json envelope. `loam explain <subject>` explains one.");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* How much of a code's meaning the inventory shows before it stops.
|
|
26
|
+
*
|
|
27
|
+
* The term listing prints whole first sentences because there are six of them
|
|
28
|
+
* and each is under 200 characters. The code listing prints 270-odd rows whose
|
|
29
|
+
* first sentences run to 377 characters, and a row that wraps four times is a
|
|
30
|
+
* paragraph, not a line of a table — it destroys the one thing this listing is
|
|
31
|
+
* for, which is scanning names. Nothing is lost: the sentence is verbatim in
|
|
32
|
+
* `--json`, and `loam explain <code>` prints the whole entry.
|
|
33
|
+
*/
|
|
34
|
+
const SUMMARY_WIDTH = 72;
|
|
35
|
+
/** The listing's one-line gloss: the first sentence of the meaning, cut at a word boundary if it runs long. */
|
|
36
|
+
function summarize(listing) {
|
|
37
|
+
// A code graded in two tables is glossed by the FIRST table's meaning — the
|
|
38
|
+
// listing answers "what is this about", and the per-scope difference (which
|
|
39
|
+
// `explain <code>` prints in full, one block per table) is exactly the
|
|
40
|
+
// detail a one-line row cannot carry honestly.
|
|
41
|
+
const sentence = firstSentence(listing.kind === "finding" ? listing.entries[0].meaning : listing.meaning);
|
|
42
|
+
if (sentence.length <= SUMMARY_WIDTH)
|
|
43
|
+
return sentence;
|
|
44
|
+
const cut = sentence.lastIndexOf(" ", SUMMARY_WIDTH);
|
|
45
|
+
return `${sentence.slice(0, cut === -1 ? SUMMARY_WIDTH : cut)}…`;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* `--codes`: the whole code vocabulary, the inventory that was previously
|
|
49
|
+
* enumerable only out of TypeScript unions or the 83 KB /loam-check prose.
|
|
50
|
+
* The JSON rows are the per-code answers verbatim (core/explain/lookup.ts
|
|
51
|
+
* derives `CodeListing` from `Explanation`), so a consumer can build a
|
|
52
|
+
* code-to-fix cache from one call instead of one call per code.
|
|
53
|
+
*/
|
|
54
|
+
function printCodeListing(json) {
|
|
55
|
+
const codes = listCodes();
|
|
56
|
+
if (json) {
|
|
57
|
+
emitJson({ command: "explain", version: LOAM_VERSION, codes });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const findings = codes.filter((listing) => listing.kind === "finding");
|
|
61
|
+
const refusals = codes.filter((listing) => listing.kind === "refusal");
|
|
62
|
+
const width = Math.max(...codes.map(({ code }) => code.length));
|
|
63
|
+
const print = (group) => {
|
|
64
|
+
for (const listing of group)
|
|
65
|
+
console.log(` ${listing.code.padEnd(width)} ${summarize(listing)}`);
|
|
66
|
+
};
|
|
67
|
+
console.log(`loam ${LOAM_VERSION} — the code vocabulary (${findings.length} finding, ${refusals.length} refusal)\n`);
|
|
68
|
+
console.log("finding codes — graded by `loam validate` and `loam verify`, in their findings[]");
|
|
69
|
+
print(findings);
|
|
70
|
+
console.log("\nrefusal codes — the `error.code` of a --json envelope, exit 1");
|
|
71
|
+
print(refusals);
|
|
72
|
+
console.log("\n`loam explain <code>` prints one in full; `loam explain` with no argument lists the concept terms.");
|
|
73
|
+
}
|
|
74
|
+
function printText(subject, explanation) {
|
|
75
|
+
if (explanation.kind === "term") {
|
|
76
|
+
console.log(`${explanation.term}\n\n${explanation.paragraph}`);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (explanation.kind === "refusal") {
|
|
80
|
+
console.log(`${subject} — a refusal code (error.code in the --json envelope, exit 1)\n\n${explanation.meaning}`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// A finding: one block per table the code appears in, under the table's own
|
|
84
|
+
// column names, so the page reads as the /loam-check row it is. The
|
|
85
|
+
// severity note repeats on each scope block because it is a PER-TABLE fact:
|
|
86
|
+
// `openapi.ref-unresolved` is a warn under `--service` and an error at
|
|
87
|
+
// archive plan time, and a reader asking "does this block my archive?" must
|
|
88
|
+
// not have to guess which note belongs to which context.
|
|
89
|
+
const severities = [...new Set(explanation.entries.map((entry) => entry.severityNote))];
|
|
90
|
+
console.log(`${subject} (${severities.join("; ")})${explanation.via === undefined ? "" : ` — surfaced by \`${explanation.via}\``}`);
|
|
91
|
+
for (const entry of explanation.entries) {
|
|
92
|
+
console.log(`\n[${entry.scope}] (${entry.severityNote})`);
|
|
93
|
+
console.log(` what it means: ${entry.meaning}`);
|
|
94
|
+
if (entry.fix !== "")
|
|
95
|
+
console.log(` what to do: ${entry.fix}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
export function registerExplain(program) {
|
|
99
|
+
program
|
|
100
|
+
.command("explain")
|
|
101
|
+
.argument("[subject]", `a finding code (spine.op-undefined), a refusal code (docs-busy), or a concept term (${TERM_LIST}); omit to list the terms`)
|
|
102
|
+
.description("Explain a finding code, refusal code or concept term, version-matched to this binary")
|
|
103
|
+
.option("--json", "emit the machine contract instead of the human view")
|
|
104
|
+
.option("--codes", "list every finding and refusal code this binary can explain")
|
|
105
|
+
.action((subject, opts) => {
|
|
106
|
+
const json = opts.json === true;
|
|
107
|
+
if (opts.codes === true) {
|
|
108
|
+
// Refused rather than quietly preferring one: `loam explain
|
|
109
|
+
// spine.op-undefined --codes` asks two different questions, and a
|
|
110
|
+
// caller who typed both wanted whichever one this run did NOT pick.
|
|
111
|
+
if (subject !== undefined) {
|
|
112
|
+
fail(json, "invalid-option", `--codes lists the whole vocabulary and takes no subject — drop '${subject}' for the inventory, or drop --codes to explain that one.`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
printCodeListing(json);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (subject === undefined) {
|
|
119
|
+
printTermListing(json);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const explanation = explainSubject(subject);
|
|
123
|
+
if (explanation === null) {
|
|
124
|
+
// The same code `show` and `instructions` use for a name that resolves
|
|
125
|
+
// to nothing, with `nearestIds` suggestions because the known set here
|
|
126
|
+
// is ~200 strings — a caller one typo away should not have to diff the
|
|
127
|
+
// whole vocabulary to find it.
|
|
128
|
+
const near = nearestIds(subject, knownSubjects());
|
|
129
|
+
fail(json, "unknown-target", `Nothing named '${subject}' — not a finding code, a refusal code, or a concept term.` +
|
|
130
|
+
(near.length > 0 ? ` Close: ${near.join(", ")}.` : "") +
|
|
131
|
+
" Run `loam explain` with no argument for the concept list; finding codes appear in `loam validate` and `loam verify` output.");
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (json) {
|
|
135
|
+
emitJson({
|
|
136
|
+
command: "explain",
|
|
137
|
+
version: LOAM_VERSION,
|
|
138
|
+
subject,
|
|
139
|
+
kind: explanation.kind,
|
|
140
|
+
...(explanation.kind === "finding"
|
|
141
|
+
? { entries: explanation.entries, ...(explanation.via === undefined ? {} : { via: explanation.via }) }
|
|
142
|
+
: explanation.kind === "refusal"
|
|
143
|
+
? { meaning: explanation.meaning }
|
|
144
|
+
: { term: explanation.term, paragraph: explanation.paragraph }),
|
|
145
|
+
});
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
printText(subject, explanation);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=explain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../../../src/commands/explain/explain.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loam explain <code|term>` — what a finding code, a refusal code or a loam\n * concept means, from the binary that emits it.\n *\n * Like `loam instructions` — and for the same reason — this command reads\n * NOTHING: no `loam.json`, no docs repo, no service, and deliberately no\n * docs-repo gate (add-command invariant 3). The vocabulary wall is hit in the\n * first minute in an unfamiliar repository, before or without wiring, and an\n * explanation that refused with `no-config` would be unreachable exactly when\n * a code is first met. The content is version-matched by construction: the\n * finding prose is parsed at runtime out of the same workflow bodies this\n * binary ships (core/explain/fix-tables.ts), so what `explain` says and what\n * /loam-check teaches cannot disagree.\n *\n * `--codes` adds the missing half: per-code lookup was always cheap, but\n * nothing could discover WHICH codes exist — the ~230 finding codes and 46\n * refusal codes were enumerable only from erased TypeScript unions or by\n * parsing the 83 KB prose body of `loam instructions loam-check`. It is opt-in\n * and off by default precisely so the term listing and every per-code page\n * stay byte-for-byte what they were: this is an addition to the contract, not\n * a change to it, and the term listing's own footer is left alone for the same\n * reason.\n */\nimport type { Command } from \"commander\";\nimport { emitJson, fail } from \"../../core/envelope/json.js\";\nimport { LOAM_VERSION } from \"../../core/envelope/version.js\";\nimport {\n explainSubject,\n firstSentence,\n knownSubjects,\n listCodes,\n listTerms,\n type CodeListing,\n type Explanation,\n} from \"../../core/explain/lookup.js\";\nimport { nearestIds } from \"../../core/repo/entries.js\";\n\ninterface ExplainOptions {\n json?: boolean;\n codes?: boolean;\n}\n\n// Interpolated from the registry that owns the terms, never hand-listed: a\n// copied list beside TERMS is a list that silently trails it.\nconst TERM_LIST = listTerms()\n .map(({ term }) => term)\n .join(\", \");\n\n/** The listing printed when no subject is asked for — also where codes are said to come from. */\nfunction printTermListing(json: boolean): void {\n const terms = listTerms();\n if (json) {\n emitJson({ command: \"explain\", version: LOAM_VERSION, terms: terms.map(({ term, summary }) => ({ term, description: summary })) });\n return;\n }\n console.log(`loam ${LOAM_VERSION} — the vocabulary\\n`);\n const width = Math.max(...terms.map(({ term }) => term.length));\n for (const { term, summary } of terms) console.log(` ${term.padEnd(width)} ${summary}`);\n console.log(\n \"\\nFinding codes come from `loam validate` and `loam verify` output; refusal codes arrive as error.code\" +\n \"\\nin any --json envelope. `loam explain <subject>` explains one.\",\n );\n}\n\n/**\n * How much of a code's meaning the inventory shows before it stops.\n *\n * The term listing prints whole first sentences because there are six of them\n * and each is under 200 characters. The code listing prints 270-odd rows whose\n * first sentences run to 377 characters, and a row that wraps four times is a\n * paragraph, not a line of a table — it destroys the one thing this listing is\n * for, which is scanning names. Nothing is lost: the sentence is verbatim in\n * `--json`, and `loam explain <code>` prints the whole entry.\n */\nconst SUMMARY_WIDTH = 72;\n\n/** The listing's one-line gloss: the first sentence of the meaning, cut at a word boundary if it runs long. */\nfunction summarize(listing: CodeListing): string {\n // A code graded in two tables is glossed by the FIRST table's meaning — the\n // listing answers \"what is this about\", and the per-scope difference (which\n // `explain <code>` prints in full, one block per table) is exactly the\n // detail a one-line row cannot carry honestly.\n const sentence = firstSentence(listing.kind === \"finding\" ? listing.entries[0]!.meaning : listing.meaning);\n if (sentence.length <= SUMMARY_WIDTH) return sentence;\n const cut = sentence.lastIndexOf(\" \", SUMMARY_WIDTH);\n return `${sentence.slice(0, cut === -1 ? SUMMARY_WIDTH : cut)}…`;\n}\n\n/**\n * `--codes`: the whole code vocabulary, the inventory that was previously\n * enumerable only out of TypeScript unions or the 83 KB /loam-check prose.\n * The JSON rows are the per-code answers verbatim (core/explain/lookup.ts\n * derives `CodeListing` from `Explanation`), so a consumer can build a\n * code-to-fix cache from one call instead of one call per code.\n */\nfunction printCodeListing(json: boolean): void {\n const codes = listCodes();\n if (json) {\n emitJson({ command: \"explain\", version: LOAM_VERSION, codes });\n return;\n }\n const findings = codes.filter((listing) => listing.kind === \"finding\");\n const refusals = codes.filter((listing) => listing.kind === \"refusal\");\n const width = Math.max(...codes.map(({ code }) => code.length));\n const print = (group: CodeListing[]): void => {\n for (const listing of group) console.log(` ${listing.code.padEnd(width)} ${summarize(listing)}`);\n };\n console.log(`loam ${LOAM_VERSION} — the code vocabulary (${findings.length} finding, ${refusals.length} refusal)\\n`);\n console.log(\"finding codes — graded by `loam validate` and `loam verify`, in their findings[]\");\n print(findings);\n console.log(\"\\nrefusal codes — the `error.code` of a --json envelope, exit 1\");\n print(refusals);\n console.log(\"\\n`loam explain <code>` prints one in full; `loam explain` with no argument lists the concept terms.\");\n}\n\nfunction printText(subject: string, explanation: Explanation): void {\n if (explanation.kind === \"term\") {\n console.log(`${explanation.term}\\n\\n${explanation.paragraph}`);\n return;\n }\n if (explanation.kind === \"refusal\") {\n console.log(`${subject} — a refusal code (error.code in the --json envelope, exit 1)\\n\\n${explanation.meaning}`);\n return;\n }\n // A finding: one block per table the code appears in, under the table's own\n // column names, so the page reads as the /loam-check row it is. The\n // severity note repeats on each scope block because it is a PER-TABLE fact:\n // `openapi.ref-unresolved` is a warn under `--service` and an error at\n // archive plan time, and a reader asking \"does this block my archive?\" must\n // not have to guess which note belongs to which context.\n const severities = [...new Set(explanation.entries.map((entry) => entry.severityNote))];\n console.log(`${subject} (${severities.join(\"; \")})${explanation.via === undefined ? \"\" : ` — surfaced by \\`${explanation.via}\\``}`);\n for (const entry of explanation.entries) {\n console.log(`\\n[${entry.scope}] (${entry.severityNote})`);\n console.log(` what it means: ${entry.meaning}`);\n if (entry.fix !== \"\") console.log(` what to do: ${entry.fix}`);\n }\n}\n\nexport function registerExplain(program: Command): void {\n program\n .command(\"explain\")\n .argument(\n \"[subject]\",\n `a finding code (spine.op-undefined), a refusal code (docs-busy), or a concept term (${TERM_LIST}); omit to list the terms`,\n )\n .description(\"Explain a finding code, refusal code or concept term, version-matched to this binary\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .option(\"--codes\", \"list every finding and refusal code this binary can explain\")\n .action((subject: string | undefined, opts: ExplainOptions) => {\n const json = opts.json === true;\n if (opts.codes === true) {\n // Refused rather than quietly preferring one: `loam explain\n // spine.op-undefined --codes` asks two different questions, and a\n // caller who typed both wanted whichever one this run did NOT pick.\n if (subject !== undefined) {\n fail(\n json,\n \"invalid-option\",\n `--codes lists the whole vocabulary and takes no subject — drop '${subject}' for the inventory, or drop --codes to explain that one.`,\n );\n return;\n }\n printCodeListing(json);\n return;\n }\n if (subject === undefined) {\n printTermListing(json);\n return;\n }\n const explanation = explainSubject(subject);\n if (explanation === null) {\n // The same code `show` and `instructions` use for a name that resolves\n // to nothing, with `nearestIds` suggestions because the known set here\n // is ~200 strings — a caller one typo away should not have to diff the\n // whole vocabulary to find it.\n const near = nearestIds(subject, knownSubjects());\n fail(\n json,\n \"unknown-target\",\n `Nothing named '${subject}' — not a finding code, a refusal code, or a concept term.` +\n (near.length > 0 ? ` Close: ${near.join(\", \")}.` : \"\") +\n \" Run `loam explain` with no argument for the concept list; finding codes appear in `loam validate` and `loam verify` output.\",\n );\n return;\n }\n if (json) {\n emitJson({\n command: \"explain\",\n version: LOAM_VERSION,\n subject,\n kind: explanation.kind,\n ...(explanation.kind === \"finding\"\n ? { entries: explanation.entries, ...(explanation.via === undefined ? {} : { via: explanation.via }) }\n : explanation.kind === \"refusal\"\n ? { meaning: explanation.meaning }\n : { term: explanation.term, paragraph: explanation.paragraph }),\n });\n return;\n }\n printText(subject, explanation);\n });\n}\n"]}
|
package/dist/commands/explore.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { loadConfig } from "../core/config.js";
|
|
2
|
-
import { explore } from "../core/explore.js";
|
|
1
|
+
import { loadConfig } from "../core/envelope/config.js";
|
|
2
|
+
import { explore } from "../core/explore/explore.js";
|
|
3
3
|
import { FleetContext } from "../core/fleet-context.js";
|
|
4
|
-
import { emitJson, fail, reportNoConfig } from "../core/json.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import { emitJson, fail, reportNoConfig } from "../core/envelope/json.js";
|
|
5
|
+
import { featureIdProblem } from "../core/kernel/ids/feature.js";
|
|
6
|
+
import { parseServiceIds } from "../core/kernel/ids/service.js";
|
|
7
|
+
import { DocsRepoUnavailableError } from "../core/repo/state.js";
|
|
8
|
+
import { docsRepoReady, reportDocsRepoError, reportRepositoryUnavailable } from "./policy/gate.js";
|
|
9
|
+
import { plural } from "./policy/format.js";
|
|
9
10
|
/**
|
|
10
11
|
* The feature id in the suggested command line when `--as` did not say.
|
|
11
12
|
*
|
|
@@ -28,11 +29,13 @@ export function registerExplore(program) {
|
|
|
28
29
|
.description("Read the fleet around a change nobody has written down yet — writes nothing")
|
|
29
30
|
.option("--json", "emit the machine contract instead of the human view")
|
|
30
31
|
.option("--op <operationId>", "seed from an operation instead of a service; repeatable", (value, prev = []) => [...prev, value])
|
|
32
|
+
.option("--capability <id>", "seed from a declared capability's realizing services; repeatable", (value, prev = []) => [...prev, value])
|
|
31
33
|
.option("--as <FEAT>", `feature id for the suggested command line (default: ${PLACEHOLDER})`)
|
|
32
34
|
.action(async (serviceArgs, opts) => {
|
|
33
35
|
const json = opts.json === true;
|
|
34
36
|
const services = serviceArgs ?? [];
|
|
35
37
|
const operations = opts.op ?? [];
|
|
38
|
+
const capabilities = opts.capability ?? [];
|
|
36
39
|
// `--as` is interpolated into the `loam new` line this command prints
|
|
37
40
|
// under `next:` and returns as `scaffold`, and `loam-feature` teaches an
|
|
38
41
|
// agent to pass `$1` straight into it. Unchecked, `explore` hands back a
|
|
@@ -40,7 +43,7 @@ export function registerExplore(program) {
|
|
|
40
43
|
// something loam rejects, which is the one thing the printed-command
|
|
41
44
|
// guard exists to prevent and the one shape it cannot see, because it
|
|
42
45
|
// reads literal source strings and this line is assembled from argv.
|
|
43
|
-
// Same grammar as `new`'s, from core/ids.ts, so the two cannot disagree.
|
|
46
|
+
// Same grammar as `new`'s, from core/kernel/ids/feature.ts, so the two cannot disagree.
|
|
44
47
|
if (opts.as !== undefined) {
|
|
45
48
|
const problem = featureIdProblem(opts.as, "feature id for --as");
|
|
46
49
|
if (problem !== null) {
|
|
@@ -48,13 +51,14 @@ export function registerExplore(program) {
|
|
|
48
51
|
return;
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
|
-
if (services.length === 0 && operations.length === 0) {
|
|
52
|
-
fail(json, "invalid-option", "Nothing to explore from. Name at least one service, or pass --op <operationId>. " +
|
|
53
|
-
"`loam list services` is the fleet; `loam show <service>` is one of them
|
|
54
|
+
if (services.length === 0 && operations.length === 0 && capabilities.length === 0) {
|
|
55
|
+
fail(json, "invalid-option", "Nothing to explore from. Name at least one service, or pass --op <operationId> or --capability <id>. " +
|
|
56
|
+
"`loam list services` is the fleet; `loam show <service>` is one of them; " +
|
|
57
|
+
"`loam list capabilities` is what the fleet promises.");
|
|
54
58
|
return;
|
|
55
59
|
}
|
|
56
60
|
// Rule 6 in docs/DESIGN.md: a raw argv string that reaches a path join is
|
|
57
|
-
// guarded at the command boundary. Every id here reaches
|
|
61
|
+
// guarded at the command boundary. Every id here reaches the service path builders.
|
|
58
62
|
// Before `loadConfig`, exactly as `loam new` guards its `--touches` list:
|
|
59
63
|
// the grammar is a fact about the argument, not about the repository, so
|
|
60
64
|
// an unusable id should answer the same whether or not you are standing
|
|
@@ -63,21 +67,17 @@ export function registerExplore(program) {
|
|
|
63
67
|
// A seed naming a service that does not EXIST is fine and reported as
|
|
64
68
|
// `unknown` — the feature may be introducing it — but one that could not
|
|
65
69
|
// be a service directory at all is a typo, not an intention.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
if (!(err instanceof InvalidIdError))
|
|
72
|
-
throw err;
|
|
73
|
-
fail(json, "invalid-option", err.message);
|
|
70
|
+
const seeds = parseServiceIds(services, "service");
|
|
71
|
+
if (!seeds.ok) {
|
|
72
|
+
fail(json, "invalid-option", seeds.problem);
|
|
74
73
|
return;
|
|
75
74
|
}
|
|
76
|
-
const
|
|
77
|
-
if (
|
|
78
|
-
reportNoConfig(json);
|
|
75
|
+
const loaded = await loadConfig();
|
|
76
|
+
if (loaded.kind !== "loaded") {
|
|
77
|
+
reportNoConfig(json, loaded);
|
|
79
78
|
return;
|
|
80
79
|
}
|
|
80
|
+
const config = loaded.config;
|
|
81
81
|
const { docsDir } = config;
|
|
82
82
|
// `services`, not `docs`: every answer here is a statement about the
|
|
83
83
|
// fleet, and an empty ring read out of a directory that is not a docs
|
|
@@ -87,8 +87,9 @@ export function registerExplore(program) {
|
|
|
87
87
|
try {
|
|
88
88
|
const result = await explore({
|
|
89
89
|
docsDir,
|
|
90
|
-
services,
|
|
90
|
+
services: seeds.ids,
|
|
91
91
|
operations,
|
|
92
|
+
capabilities,
|
|
92
93
|
featureId: opts.as ?? PLACEHOLDER,
|
|
93
94
|
context: new FleetContext(),
|
|
94
95
|
});
|
|
@@ -164,6 +165,10 @@ function print(r) {
|
|
|
164
165
|
console.log(`! no living contract defines ${r.unresolvedOperations.join(", ")} — ` +
|
|
165
166
|
`the feature is adding ${r.unresolvedOperations.length === 1 ? "it" : "them"}, or the id is wrong\n`);
|
|
166
167
|
}
|
|
168
|
+
if (r.unresolvedCapabilities.length > 0) {
|
|
169
|
+
console.log(`! no realizing service seeds ${r.unresolvedCapabilities.join(", ")} — ` +
|
|
170
|
+
`not declared in architecture/capabilities.yaml, or declared and realized by nothing\n`);
|
|
171
|
+
}
|
|
167
172
|
if (r.neighbours.length > 0) {
|
|
168
173
|
// The whole point of the command, so it is stated as a question rather than
|
|
169
174
|
// a list: these are candidates for --touches, and loam does not know which
|