@ybotok/loam 0.1.0-beta.3 → 0.2.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5992 -82
- package/COMPARISON.md +168 -63
- package/CONTRIBUTING.md +121 -0
- package/MIGRATING-from-OpenSpec.md +238 -55
- package/QUICKSTART.md +302 -0
- package/README.md +653 -144
- package/ROADMAP.md +1035 -0
- package/SCHEMA.md +3916 -263
- package/SECURITY.md +21 -3
- package/WORKFLOW.md +927 -0
- package/dist/cli.js +133 -21
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt/adopt.js +204 -0
- package/dist/commands/adopt/adopt.js.map +1 -0
- package/dist/commands/adopt/render.js +309 -0
- package/dist/commands/adopt/render.js.map +1 -0
- package/dist/commands/archive/archive.js +74 -0
- package/dist/commands/archive/archive.js.map +1 -0
- package/dist/commands/archive/closing.js +42 -0
- package/dist/commands/archive/closing.js.map +1 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/consumers.js +56 -0
- package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
- package/dist/commands/archive/plan/contracts/openapi.js +193 -0
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
- package/dist/commands/archive/plan/document/head.js +151 -0
- package/dist/commands/archive/plan/document/head.js.map +1 -0
- package/dist/commands/archive/plan/document/links.js +284 -0
- package/dist/commands/archive/plan/document/links.js.map +1 -0
- package/dist/commands/archive/plan/document/run.js +136 -0
- package/dist/commands/archive/plan/document/run.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +319 -0
- package/dist/commands/archive/plan/gate.js.map +1 -0
- package/dist/commands/archive/plan/landscape.js +298 -0
- package/dist/commands/archive/plan/landscape.js.map +1 -0
- package/dist/commands/archive/plan/model/extending.js +85 -0
- package/dist/commands/archive/plan/model/extending.js.map +1 -0
- package/dist/commands/archive/plan/refusal.js +106 -0
- package/dist/commands/archive/plan/refusal.js.map +1 -0
- package/dist/commands/archive/plan/specs.js +318 -0
- package/dist/commands/archive/plan/specs.js.map +1 -0
- package/dist/commands/archive/plan/state.js +30 -0
- package/dist/commands/archive/plan/state.js.map +1 -0
- package/dist/commands/archive/run.js +355 -0
- package/dist/commands/archive/run.js.map +1 -0
- package/dist/commands/archive/shipped.js +49 -0
- package/dist/commands/archive/shipped.js.map +1 -0
- package/dist/commands/context/context.js +166 -0
- package/dist/commands/context/context.js.map +1 -0
- package/dist/commands/context/print.js +305 -0
- package/dist/commands/context/print.js.map +1 -0
- package/dist/commands/delta/delta.js +367 -0
- package/dist/commands/delta/delta.js.map +1 -0
- package/dist/commands/delta/print.js +221 -0
- package/dist/commands/delta/print.js.map +1 -0
- package/dist/commands/dependencies.js +6 -8
- package/dist/commands/dependencies.js.map +1 -1
- package/dist/commands/diff/diff.js +86 -0
- package/dist/commands/diff/diff.js.map +1 -0
- package/dist/commands/diff/print.js +38 -0
- package/dist/commands/diff/print.js.map +1 -0
- package/dist/commands/doctor.js +65 -5
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain/explain.js +227 -0
- package/dist/commands/explain/explain.js.map +1 -0
- package/dist/commands/explore.js +39 -28
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/gate/gate.js +152 -0
- package/dist/commands/gate/gate.js.map +1 -0
- package/dist/commands/gate/print.js +66 -0
- package/dist/commands/gate/print.js.map +1 -0
- package/dist/commands/gherkin/commit.js +105 -0
- package/dist/commands/gherkin/commit.js.map +1 -0
- package/dist/commands/gherkin/gherkin.js +262 -0
- package/dist/commands/gherkin/gherkin.js.map +1 -0
- package/dist/commands/gherkin/reconcile.js +146 -0
- package/dist/commands/gherkin/reconcile.js.map +1 -0
- package/dist/commands/gherkin/render.js +77 -0
- package/dist/commands/gherkin/render.js.map +1 -0
- package/dist/commands/init/example.js +204 -0
- package/dist/commands/init/example.js.map +1 -0
- package/dist/commands/init/first-hour.js +72 -0
- package/dist/commands/init/first-hour.js.map +1 -0
- package/dist/commands/{init.js → init/init.js} +142 -71
- package/dist/commands/init/init.js.map +1 -0
- package/dist/commands/init/mcp.js +131 -0
- package/dist/commands/init/mcp.js.map +1 -0
- package/dist/commands/init/options.js +78 -0
- package/dist/commands/init/options.js.map +1 -0
- package/dist/commands/instructions.js +72 -14
- package/dist/commands/instructions.js.map +1 -1
- package/dist/commands/list/campaign/campaign.js +63 -0
- package/dist/commands/list/campaign/campaign.js.map +1 -0
- package/dist/commands/list/campaign/owners.js +65 -0
- package/dist/commands/list/campaign/owners.js.map +1 -0
- package/dist/commands/list/json.js +155 -0
- package/dist/commands/list/json.js.map +1 -0
- package/dist/commands/list/list.js +358 -0
- package/dist/commands/list/list.js.map +1 -0
- package/dist/commands/list/print.js +344 -0
- package/dist/commands/list/print.js.map +1 -0
- package/dist/commands/list/review.js +120 -0
- package/dist/commands/list/review.js.map +1 -0
- package/dist/commands/list/suites/suites.js +140 -0
- package/dist/commands/list/suites/suites.js.map +1 -0
- package/dist/commands/list/views.js +108 -0
- package/dist/commands/list/views.js.map +1 -0
- package/dist/commands/mcp/dispatch.js +238 -0
- package/dist/commands/mcp/dispatch.js.map +1 -0
- package/dist/commands/mcp/mcp.js +75 -0
- package/dist/commands/mcp/mcp.js.map +1 -0
- package/dist/commands/mcp/serve.js +55 -0
- package/dist/commands/mcp/serve.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/active.js +175 -0
- package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
- package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/living.js +62 -0
- package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
- package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/target.js +219 -0
- package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/error.js +18 -0
- package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
- package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/read.js +49 -0
- package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
- package/dist/commands/migrate-openspec/print.js +89 -0
- package/dist/commands/migrate-openspec/print.js.map +1 -0
- package/dist/commands/new/capability-template.js +118 -0
- package/dist/commands/new/capability-template.js.map +1 -0
- package/dist/commands/new/commit.js +62 -0
- package/dist/commands/new/commit.js.map +1 -0
- package/dist/commands/new/modifies.js +206 -0
- package/dist/commands/new/modifies.js.map +1 -0
- package/dist/commands/new/new.js +328 -0
- package/dist/commands/new/new.js.map +1 -0
- package/dist/commands/new/templates.js +279 -0
- package/dist/commands/new/templates.js.map +1 -0
- package/dist/commands/open.js +199 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/policy/format.js +152 -0
- package/dist/commands/policy/format.js.map +1 -0
- package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
- package/dist/commands/policy/gate.js.map +1 -0
- package/dist/commands/rebase/edit.js +106 -0
- package/dist/commands/rebase/edit.js.map +1 -0
- package/dist/commands/rebase/living.js +185 -0
- package/dist/commands/rebase/living.js.map +1 -0
- package/dist/commands/rebase/plan.js +245 -0
- package/dist/commands/rebase/plan.js.map +1 -0
- package/dist/commands/rebase/rebase.js +300 -0
- package/dist/commands/rebase/rebase.js.map +1 -0
- package/dist/commands/seed/commit.js +221 -0
- package/dist/commands/seed/commit.js.map +1 -0
- package/dist/commands/seed/plan.js +278 -0
- package/dist/commands/seed/plan.js.map +1 -0
- package/dist/commands/seed/seed.js +174 -0
- package/dist/commands/seed/seed.js.map +1 -0
- package/dist/commands/show/feature.js +182 -0
- package/dist/commands/show/feature.js.map +1 -0
- package/dist/commands/show/introduced.js +157 -0
- package/dist/commands/show/introduced.js.map +1 -0
- package/dist/commands/show/marks.js +53 -0
- package/dist/commands/show/marks.js.map +1 -0
- package/dist/commands/show/service.js +239 -0
- package/dist/commands/show/service.js.map +1 -0
- package/dist/commands/show/show.js +87 -0
- package/dist/commands/show/show.js.map +1 -0
- package/dist/commands/status/fleet-next.js +90 -0
- package/dist/commands/status/fleet-next.js.map +1 -0
- package/dist/commands/status/json.js +47 -0
- package/dist/commands/status/json.js.map +1 -0
- package/dist/commands/status/print.js +209 -0
- package/dist/commands/status/print.js.map +1 -0
- package/dist/commands/status/status.js +115 -0
- package/dist/commands/status/status.js.map +1 -0
- package/dist/commands/steps/steps.js +269 -0
- package/dist/commands/steps/steps.js.map +1 -0
- package/dist/commands/subsystem/edit.js +192 -0
- package/dist/commands/subsystem/edit.js.map +1 -0
- package/dist/commands/subsystem/move.js +325 -0
- package/dist/commands/subsystem/move.js.map +1 -0
- package/dist/commands/subsystem/query.js +113 -0
- package/dist/commands/subsystem/query.js.map +1 -0
- package/dist/commands/subsystem/subsystem.js +98 -0
- package/dist/commands/subsystem/subsystem.js.map +1 -0
- package/dist/commands/subsystem/sync.js +318 -0
- package/dist/commands/subsystem/sync.js.map +1 -0
- package/dist/commands/subsystem/txn/exclude.js +132 -0
- package/dist/commands/subsystem/txn/exclude.js.map +1 -0
- package/dist/commands/subsystem/txn/links.js +128 -0
- package/dist/commands/subsystem/txn/links.js.map +1 -0
- package/dist/commands/subsystem/txn/report.js +174 -0
- package/dist/commands/subsystem/txn/report.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +196 -0
- package/dist/commands/subsystem/txn/txn.js.map +1 -0
- package/dist/commands/subsystem/txn/views.js +249 -0
- package/dist/commands/subsystem/txn/views.js.map +1 -0
- package/dist/commands/tasks/actions.js +107 -0
- package/dist/commands/tasks/actions.js.map +1 -0
- package/dist/commands/tasks/render.js +253 -0
- package/dist/commands/tasks/render.js.map +1 -0
- package/dist/commands/tasks/tasks.js +119 -0
- package/dist/commands/tasks/tasks.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +176 -0
- package/dist/commands/unarchive/manifest.js.map +1 -0
- package/dist/commands/unarchive/restore.js +254 -0
- package/dist/commands/unarchive/restore.js.map +1 -0
- package/dist/commands/unarchive/unarchive.js +59 -0
- package/dist/commands/unarchive/unarchive.js.map +1 -0
- package/dist/commands/validate/arch-coverage.js +245 -0
- package/dist/commands/validate/arch-coverage.js.map +1 -0
- package/dist/commands/validate/checks/fleet-shape.js +204 -0
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
- package/dist/commands/validate/checks/health-deps.js +58 -0
- package/dist/commands/validate/checks/health-deps.js.map +1 -0
- package/dist/commands/validate/checks/introduced.js +102 -0
- package/dist/commands/validate/checks/introduced.js.map +1 -0
- package/dist/commands/validate/checks/requirements.js +264 -0
- package/dist/commands/validate/checks/requirements.js.map +1 -0
- package/dist/commands/validate/checks/sources.js +85 -0
- package/dist/commands/validate/checks/sources.js.map +1 -0
- package/dist/commands/validate/coverage/covers-after.js +105 -0
- package/dist/commands/validate/coverage/covers-after.js.map +1 -0
- package/dist/commands/validate/feature.js +222 -0
- package/dist/commands/validate/feature.js.map +1 -0
- package/dist/commands/validate/fleet/census.js +93 -0
- package/dist/commands/validate/fleet/census.js.map +1 -0
- package/dist/commands/validate/fleet/kind-tags.js +39 -0
- package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
- package/dist/commands/validate/fleet/landscape.js +371 -0
- package/dist/commands/validate/fleet/landscape.js.map +1 -0
- package/dist/commands/validate/fleet/load.js +118 -0
- package/dist/commands/validate/fleet/load.js.map +1 -0
- package/dist/commands/validate/fleet/map/attest.js +98 -0
- package/dist/commands/validate/fleet/map/attest.js.map +1 -0
- package/dist/commands/validate/fleet/map/bindings.js +107 -0
- package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
- package/dist/commands/validate/fleet/map/consumers.js +244 -0
- package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
- package/dist/commands/validate/fleet/map/isolation.js +116 -0
- package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
- package/dist/commands/validate/fleet/map/usecases.js +54 -0
- package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/obligations.js +266 -0
- package/dist/commands/validate/fleet/obligations.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/print.js +71 -0
- package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/place.js +13 -0
- package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
- package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
- package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +75 -0
- package/dist/commands/validate/fleet/views/ids.js.map +1 -0
- package/dist/commands/validate/fleet/views/projects.js +278 -0
- package/dist/commands/validate/fleet/views/projects.js.map +1 -0
- package/dist/commands/validate/fleet/views/root-documents.js +83 -0
- package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +52 -0
- package/dist/commands/validate/fleet/views/stale.js.map +1 -0
- package/dist/commands/validate/links/corpus.js +89 -0
- package/dist/commands/validate/links/corpus.js.map +1 -0
- package/dist/commands/validate/links/glossary.js +75 -0
- package/dist/commands/validate/links/glossary.js.map +1 -0
- package/dist/commands/validate/render/repeats.js +63 -0
- package/dist/commands/validate/render/repeats.js.map +1 -0
- package/dist/commands/validate/render/rollups.js +115 -0
- package/dist/commands/validate/render/rollups.js.map +1 -0
- package/dist/commands/validate/render/text.js +199 -0
- package/dist/commands/validate/render/text.js.map +1 -0
- package/dist/commands/validate/report.js +145 -0
- package/dist/commands/validate/report.js.map +1 -0
- package/dist/commands/validate/scope.js +113 -0
- package/dist/commands/validate/scope.js.map +1 -0
- package/dist/commands/validate/service/api.js +252 -0
- package/dist/commands/validate/service/api.js.map +1 -0
- package/dist/commands/validate/service/contracts/generated.js +134 -0
- package/dist/commands/validate/service/contracts/generated.js.map +1 -0
- package/dist/commands/validate/service/events/events.js +241 -0
- package/dist/commands/validate/service/events/events.js.map +1 -0
- package/dist/commands/validate/service/events/message-producers.js +77 -0
- package/dist/commands/validate/service/events/message-producers.js.map +1 -0
- package/dist/commands/validate/service/evidence-pins.js +177 -0
- package/dist/commands/validate/service/evidence-pins.js.map +1 -0
- package/dist/commands/validate/service/model/diverged.js +226 -0
- package/dist/commands/validate/service/model/diverged.js.map +1 -0
- package/dist/commands/validate/service/model/grade.js +163 -0
- package/dist/commands/validate/service/model/grade.js.map +1 -0
- package/dist/commands/validate/service/service.js +310 -0
- package/dist/commands/validate/service/service.js.map +1 -0
- package/dist/commands/validate/service/specs.js +279 -0
- package/dist/commands/validate/service/specs.js.map +1 -0
- package/dist/commands/validate/service/spine.js +148 -0
- package/dist/commands/validate/service/spine.js.map +1 -0
- package/dist/commands/validate/service/usecases/tags.js +113 -0
- package/dist/commands/validate/service/usecases/tags.js.map +1 -0
- package/dist/commands/validate/service/usecases/usecases.js +209 -0
- package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/validate.js +363 -0
- package/dist/commands/validate/validate.js.map +1 -0
- package/dist/commands/verify/cross/diff.js +178 -0
- package/dist/commands/verify/cross/diff.js.map +1 -0
- package/dist/commands/verify/evidence/contract.js +32 -0
- package/dist/commands/verify/evidence/contract.js.map +1 -0
- package/dist/commands/verify/evidence/pins.js +52 -0
- package/dist/commands/verify/evidence/pins.js.map +1 -0
- package/dist/commands/verify/evidence/read.js +81 -0
- package/dist/commands/verify/evidence/read.js.map +1 -0
- package/dist/commands/verify/frozen.js +263 -0
- package/dist/commands/verify/frozen.js.map +1 -0
- package/dist/commands/verify/record.js +278 -0
- package/dist/commands/verify/record.js.map +1 -0
- package/dist/commands/verify/report.js +206 -0
- package/dist/commands/verify/report.js.map +1 -0
- package/dist/commands/verify/results.js +328 -0
- package/dist/commands/verify/results.js.map +1 -0
- package/dist/commands/verify/verify.js +220 -0
- package/dist/commands/verify/verify.js.map +1 -0
- package/dist/commands/vouch/contract.js +11 -0
- package/dist/commands/vouch/contract.js.map +1 -0
- package/dist/commands/vouch/pack/contract.js +2 -0
- package/dist/commands/vouch/pack/contract.js.map +1 -0
- package/dist/commands/vouch/pack/pack.js +266 -0
- package/dist/commands/vouch/pack/pack.js.map +1 -0
- package/dist/commands/vouch/pack/print.js +266 -0
- package/dist/commands/vouch/pack/print.js.map +1 -0
- package/dist/commands/vouch/pack/sections.js +141 -0
- package/dist/commands/vouch/pack/sections.js.map +1 -0
- package/dist/commands/vouch/prompt/confirm.js +46 -0
- package/dist/commands/vouch/prompt/confirm.js.map +1 -0
- package/dist/commands/vouch/report.js +101 -0
- package/dist/commands/vouch/report.js.map +1 -0
- package/dist/commands/vouch/run.js +230 -0
- package/dist/commands/vouch/run.js.map +1 -0
- package/dist/commands/vouch/sample/plan.js +111 -0
- package/dist/commands/vouch/sample/plan.js.map +1 -0
- package/dist/commands/vouch/sample/print.js +109 -0
- package/dist/commands/vouch/sample/print.js.map +1 -0
- package/dist/commands/vouch/vet/verify.js +155 -0
- package/dist/commands/vouch/vet/verify.js.map +1 -0
- package/dist/commands/vouch/vouch.js +169 -0
- package/dist/commands/vouch/vouch.js.map +1 -0
- package/dist/core/agent/agents-md/command-map.js +299 -0
- package/dist/core/agent/agents-md/command-map.js.map +1 -0
- package/dist/core/agent/agents-md/map/explain.js +46 -0
- package/dist/core/agent/agents-md/map/explain.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
- package/dist/core/agent/agents-md/map/mcp.js +44 -0
- package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
- package/dist/core/agent/agents-md/map/status.js +78 -0
- package/dist/core/agent/agents-md/map/status.js.map +1 -0
- package/dist/core/agent/agents-md/map/subsystem.js +104 -0
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
- package/dist/core/agent/agents-md/map/usecases.js +138 -0
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
- package/dist/core/agent/agents-md/refusals.js +273 -0
- package/dist/core/agent/agents-md/refusals.js.map +1 -0
- package/dist/core/agent/agents-md.js +203 -0
- package/dist/core/agent/agents-md.js.map +1 -0
- package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
- package/dist/core/agent/agents-stamp.js.map +1 -0
- package/dist/core/agent/contract.js +2 -0
- package/dist/core/agent/contract.js.map +1 -0
- package/dist/core/agent/protocol.js +193 -0
- package/dist/core/agent/protocol.js.map +1 -0
- package/dist/core/agent/scaffold.js +254 -0
- package/dist/core/agent/scaffold.js.map +1 -0
- package/dist/core/agent/support/report.js +144 -0
- package/dist/core/agent/support/report.js.map +1 -0
- package/dist/core/agent/tools/dialects.js +151 -0
- package/dist/core/agent/tools/dialects.js.map +1 -0
- package/dist/core/agent/tools/registry.js +193 -0
- package/dist/core/agent/tools/registry.js.map +1 -0
- package/dist/core/agent/workflows/adopt.js +280 -0
- package/dist/core/agent/workflows/adopt.js.map +1 -0
- package/dist/core/agent/workflows/check.js +373 -0
- package/dist/core/agent/workflows/check.js.map +1 -0
- package/dist/core/agent/workflows/closing.js +323 -0
- package/dist/core/agent/workflows/closing.js.map +1 -0
- package/dist/core/agent/workflows/feature.js +220 -0
- package/dist/core/agent/workflows/feature.js.map +1 -0
- package/dist/core/agent/workflows/implement.js +188 -0
- package/dist/core/agent/workflows/implement.js.map +1 -0
- package/dist/core/agent/workflows/reference/authoring.js +311 -0
- package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
- package/dist/core/agent/workflows/reference/codes.js +67 -0
- package/dist/core/agent/workflows/reference/codes.js.map +1 -0
- package/dist/core/agent/workflows/reference/done-check.js +210 -0
- package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
- package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
- package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
- package/dist/core/agent/workflows/reference/reference.js +19 -0
- package/dist/core/agent/workflows/reference/reference.js.map +1 -0
- package/dist/core/agent/workflows/reference/spine.js +338 -0
- package/dist/core/agent/workflows/reference/spine.js.map +1 -0
- package/dist/core/asyncapi/baseline/plan.js +43 -0
- package/dist/core/asyncapi/baseline/plan.js.map +1 -0
- package/dist/core/asyncapi/baseline/surfaces.js +54 -0
- package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
- package/dist/core/asyncapi/depth.js +164 -0
- package/dist/core/asyncapi/depth.js.map +1 -0
- package/dist/core/asyncapi/digest.js +146 -0
- package/dist/core/asyncapi/digest.js.map +1 -0
- package/dist/core/asyncapi/merge/components.js +92 -0
- package/dist/core/asyncapi/merge/components.js.map +1 -0
- package/dist/core/asyncapi/merge/error.js +38 -0
- package/dist/core/asyncapi/merge/error.js.map +1 -0
- package/dist/core/asyncapi/merge/markers.js +290 -0
- package/dist/core/asyncapi/merge/markers.js.map +1 -0
- package/dist/core/asyncapi/merge/merge.js +195 -0
- package/dist/core/asyncapi/merge/merge.js.map +1 -0
- package/dist/core/asyncapi/merge/pin.js +83 -0
- package/dist/core/asyncapi/merge/pin.js.map +1 -0
- package/dist/core/asyncapi/model.js +11 -0
- package/dist/core/asyncapi/model.js.map +1 -0
- package/dist/core/asyncapi/producers.js +50 -0
- package/dist/core/asyncapi/producers.js.map +1 -0
- package/dist/core/asyncapi/read.js +263 -0
- package/dist/core/asyncapi/read.js.map +1 -0
- package/dist/core/brief/brief.js +285 -0
- package/dist/core/brief/brief.js.map +1 -0
- package/dist/core/brief/checks.js +385 -0
- package/dist/core/brief/checks.js.map +1 -0
- package/dist/core/brief/landscape.js +273 -0
- package/dist/core/brief/landscape.js.map +1 -0
- package/dist/core/brief/map/extend.js +84 -0
- package/dist/core/brief/map/extend.js.map +1 -0
- package/dist/core/brief/map/owed.js +266 -0
- package/dist/core/brief/map/owed.js.map +1 -0
- package/dist/core/brief/targets.js +304 -0
- package/dist/core/brief/targets.js.map +1 -0
- package/dist/core/brief/unchecked.js +58 -0
- package/dist/core/brief/unchecked.js.map +1 -0
- package/dist/core/c4/arch.js +190 -0
- package/dist/core/c4/arch.js.map +1 -0
- package/dist/core/c4/direction/direction.js +114 -0
- package/dist/core/c4/direction/direction.js.map +1 -0
- package/dist/core/c4/likec4.js +243 -0
- package/dist/core/c4/likec4.js.map +1 -0
- package/dist/core/c4/locate/unlocated.js +150 -0
- package/dist/core/c4/locate/unlocated.js.map +1 -0
- package/dist/core/c4/parsed/deployment.js +160 -0
- package/dist/core/c4/parsed/deployment.js.map +1 -0
- package/dist/core/c4/parsed/dynamic-views.js +132 -0
- package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
- package/dist/core/c4/parsed/specification.js +78 -0
- package/dist/core/c4/parsed/specification.js.map +1 -0
- package/dist/core/c4/parsed/values.js +110 -0
- package/dist/core/c4/parsed/values.js.map +1 -0
- package/dist/core/c4/parsed/view-ids.js +113 -0
- package/dist/core/c4/parsed/view-ids.js.map +1 -0
- package/dist/core/c4/prefetch/fleet.js +134 -0
- package/dist/core/c4/prefetch/fleet.js.map +1 -0
- package/dist/core/c4/project/architecture.js +161 -0
- package/dist/core/c4/project/architecture.js.map +1 -0
- package/dist/core/c4/project/batch.js +140 -0
- package/dist/core/c4/project/batch.js.map +1 -0
- package/dist/core/c4/project/documents.js +89 -0
- package/dist/core/c4/project/documents.js.map +1 -0
- package/dist/core/c4/project/load.js +219 -0
- package/dist/core/c4/project/load.js.map +1 -0
- package/dist/core/c4/project/staged.js +277 -0
- package/dist/core/c4/project/staged.js.map +1 -0
- package/dist/core/c4/resolve/attested.js +0 -0
- package/dist/core/c4/resolve/attested.js.map +1 -0
- package/dist/core/c4/resolve/external.js +51 -0
- package/dist/core/c4/resolve/external.js.map +1 -0
- package/dist/core/c4/resolve/service.js +174 -0
- package/dist/core/c4/resolve/service.js.map +1 -0
- package/dist/core/c4/resolve/steps.js +290 -0
- package/dist/core/c4/resolve/steps.js.map +1 -0
- package/dist/core/c4/resolve/systems.js +154 -0
- package/dist/core/c4/resolve/systems.js.map +1 -0
- package/dist/core/c4/root-project/exclude.js +352 -0
- package/dist/core/c4/root-project/exclude.js.map +1 -0
- package/dist/core/c4/seed/fleet-file.js +201 -0
- package/dist/core/c4/seed/fleet-file.js.map +1 -0
- package/dist/core/c4/seed/items.js +91 -0
- package/dist/core/c4/seed/items.js.map +1 -0
- package/dist/core/c4/seed/stamp.js +48 -0
- package/dist/core/c4/seed/stamp.js.map +1 -0
- package/dist/core/c4/seed/template.js +173 -0
- package/dist/core/c4/seed/template.js.map +1 -0
- package/dist/core/c4/service-model/created/models.js +96 -0
- package/dist/core/c4/service-model/created/models.js.map +1 -0
- package/dist/core/c4/service-model/documents.js +47 -0
- package/dist/core/c4/service-model/documents.js.map +1 -0
- package/dist/core/c4/service-model/fleet/extending.js +82 -0
- package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
- package/dist/core/c4/service-model/load.js +165 -0
- package/dist/core/c4/service-model/load.js.map +1 -0
- package/dist/core/c4/service-model/renderer.js +128 -0
- package/dist/core/c4/service-model/renderer.js.map +1 -0
- package/dist/core/c4/service-model/shape.js +106 -0
- package/dist/core/c4/service-model/shape.js.map +1 -0
- package/dist/core/c4/service-model/slice.js +188 -0
- package/dist/core/c4/service-model/slice.js.map +1 -0
- package/dist/core/c4/source-mask.js +369 -0
- package/dist/core/c4/source-mask.js.map +1 -0
- package/dist/core/c4/source-scan.js +308 -0
- package/dist/core/c4/source-scan.js.map +1 -0
- package/dist/core/c4/splice/authored-source.js +167 -0
- package/dist/core/c4/splice/authored-source.js.map +1 -0
- package/dist/core/c4/splice/contract.js +30 -0
- package/dist/core/c4/splice/contract.js.map +1 -0
- package/dist/core/c4/splice/delta-blocks.js +126 -0
- package/dist/core/c4/splice/delta-blocks.js.map +1 -0
- package/dist/core/c4/splice/identity/declared.js +87 -0
- package/dist/core/c4/splice/identity/declared.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +73 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -0
- package/dist/core/c4/splice/identity/existing.js +80 -0
- package/dist/core/c4/splice/identity/existing.js.map +1 -0
- package/dist/core/c4/splice/identity/interior.js +80 -0
- package/dist/core/c4/splice/identity/interior.js.map +1 -0
- package/dist/core/c4/splice/identity/owner.js +50 -0
- package/dist/core/c4/splice/identity/owner.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +337 -0
- package/dist/core/c4/splice/landscape-merge.js.map +1 -0
- package/dist/core/c4/splice/model/merge.js +151 -0
- package/dist/core/c4/splice/model/merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +298 -0
- package/dist/core/c4/splice/placement.js.map +1 -0
- package/dist/core/c4/splice/text/spot.js +131 -0
- package/dist/core/c4/splice/text/spot.js.map +1 -0
- package/dist/core/c4/workspace.js +166 -0
- package/dist/core/c4/workspace.js.map +1 -0
- package/dist/core/capabilities/authoring/notes.js +141 -0
- package/dist/core/capabilities/authoring/notes.js.map +1 -0
- package/dist/core/capabilities/capabilities.js +124 -0
- package/dist/core/capabilities/capabilities.js.map +1 -0
- package/dist/core/capabilities/delta/doc.js +47 -0
- package/dist/core/capabilities/delta/doc.js.map +1 -0
- package/dist/core/capabilities/delta/overlay.js +129 -0
- package/dist/core/capabilities/delta/overlay.js.map +1 -0
- package/dist/core/capabilities/delta/summary.js +57 -0
- package/dist/core/capabilities/delta/summary.js.map +1 -0
- package/dist/core/capabilities/delta/tree.js +43 -0
- package/dist/core/capabilities/delta/tree.js.map +1 -0
- package/dist/core/capabilities/delta/uncovered.js +222 -0
- package/dist/core/capabilities/delta/uncovered.js.map +1 -0
- package/dist/core/capabilities/findings.js +338 -0
- package/dist/core/capabilities/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/findings.js +174 -0
- package/dist/core/capabilities/realizes/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/join.js +123 -0
- package/dist/core/capabilities/realizes/join.js.map +1 -0
- package/dist/core/capabilities/rollup.js +205 -0
- package/dist/core/capabilities/rollup.js.map +1 -0
- package/dist/core/capabilities/tree.js +104 -0
- package/dist/core/capabilities/tree.js.map +1 -0
- package/dist/core/capabilities/usecase-join.js +267 -0
- package/dist/core/capabilities/usecase-join.js.map +1 -0
- package/dist/core/coherence/authoring/scaffold.js +185 -0
- package/dist/core/coherence/authoring/scaffold.js.map +1 -0
- package/dist/core/coherence/authoring/sentinels.js +75 -0
- package/dist/core/coherence/authoring/sentinels.js.map +1 -0
- package/dist/core/coherence/calls/called.js +52 -0
- package/dist/core/coherence/calls/called.js.map +1 -0
- package/dist/core/coherence/coherence.js +332 -0
- package/dist/core/coherence/coherence.js.map +1 -0
- package/dist/core/coherence/consumed/operations.js +70 -0
- package/dist/core/coherence/consumed/operations.js.map +1 -0
- package/dist/core/coherence/consumed/refusal.js +38 -0
- package/dist/core/coherence/consumed/refusal.js.map +1 -0
- package/dist/core/coherence/covers/health.js +85 -0
- package/dist/core/coherence/covers/health.js.map +1 -0
- package/dist/core/coherence/declared.js +295 -0
- package/dist/core/coherence/declared.js.map +1 -0
- package/dist/core/coherence/events/declared.js +191 -0
- package/dist/core/coherence/events/declared.js.map +1 -0
- package/dist/core/coherence/events/events.js +335 -0
- package/dist/core/coherence/events/events.js.map +1 -0
- package/dist/core/coherence/events/grades.js +189 -0
- package/dist/core/coherence/events/grades.js.map +1 -0
- package/dist/core/coherence/events/lookups.js +63 -0
- package/dist/core/coherence/events/lookups.js.map +1 -0
- package/dist/core/coherence/events/produced.js +100 -0
- package/dist/core/coherence/events/produced.js.map +1 -0
- package/dist/core/coherence/living.js +198 -0
- package/dist/core/coherence/living.js.map +1 -0
- package/dist/core/coherence/lookups.js +95 -0
- package/dist/core/coherence/lookups.js.map +1 -0
- package/dist/core/coherence/pending.js +39 -0
- package/dist/core/coherence/pending.js.map +1 -0
- package/dist/core/coherence/retired/archived.js +285 -0
- package/dist/core/coherence/retired/archived.js.map +1 -0
- package/dist/core/coherence/retired/event-pair.js +62 -0
- package/dist/core/coherence/retired/event-pair.js.map +1 -0
- package/dist/core/coherence/retired/merged.js +79 -0
- package/dist/core/coherence/retired/merged.js.map +1 -0
- package/dist/core/coherence/retired/retirement.js +49 -0
- package/dist/core/coherence/retired/retirement.js.map +1 -0
- package/dist/core/coherence/retired/revival/arrivals.js +131 -0
- package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
- package/dist/core/coherence/retired/revival/revived.js +297 -0
- package/dist/core/coherence/retired/revival/revived.js.map +1 -0
- package/dist/core/conflict-markers.js +60 -0
- package/dist/core/conflict-markers.js.map +1 -0
- package/dist/core/consumers/after.js +113 -0
- package/dist/core/consumers/after.js.map +1 -0
- package/dist/core/consumers/consumers.js +296 -0
- package/dist/core/consumers/consumers.js.map +1 -0
- package/dist/core/consumers/current.js +211 -0
- package/dist/core/consumers/current.js.map +1 -0
- package/dist/core/consumers/scan.js +46 -0
- package/dist/core/consumers/scan.js.map +1 -0
- package/dist/core/consumers/state.js +27 -0
- package/dist/core/consumers/state.js.map +1 -0
- package/dist/core/delta/claims.js +73 -0
- package/dist/core/delta/claims.js.map +1 -0
- package/dist/core/delta/delta.js +341 -0
- package/dist/core/delta/delta.js.map +1 -0
- package/dist/core/delta/document.js +177 -0
- package/dist/core/delta/document.js.map +1 -0
- package/dist/core/delta/scope.js +48 -0
- package/dist/core/delta/scope.js.map +1 -0
- package/dist/core/delta/select.js +237 -0
- package/dist/core/delta/select.js.map +1 -0
- package/dist/core/dependencies/dependencies.js +141 -0
- package/dist/core/dependencies/dependencies.js.map +1 -0
- package/dist/core/dependencies/facts.js +165 -0
- package/dist/core/dependencies/facts.js.map +1 -0
- package/dist/core/dependencies/fanin.js +88 -0
- package/dist/core/dependencies/fanin.js.map +1 -0
- package/dist/core/dependencies/graph.js +106 -0
- package/dist/core/dependencies/graph.js.map +1 -0
- package/dist/core/deployment/delta.js +191 -0
- package/dist/core/deployment/delta.js.map +1 -0
- package/dist/core/deployment/objects.js +145 -0
- package/dist/core/deployment/objects.js.map +1 -0
- package/dist/core/diff/base-git.js +230 -0
- package/dist/core/diff/base-git.js.map +1 -0
- package/dist/core/diff/base-state.js +237 -0
- package/dist/core/diff/base-state.js.map +1 -0
- package/dist/core/diff/joins.js +136 -0
- package/dist/core/diff/joins.js.map +1 -0
- package/dist/core/diff/scope/changed-paths.js +204 -0
- package/dist/core/diff/scope/changed-paths.js.map +1 -0
- package/dist/core/diff/scope/edges.js +82 -0
- package/dist/core/diff/scope/edges.js.map +1 -0
- package/dist/core/diff/semantic.js +312 -0
- package/dist/core/diff/semantic.js.map +1 -0
- package/dist/core/docs.js +37 -85
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/agents.js +238 -0
- package/dist/core/doctor/agents.js.map +1 -0
- package/dist/core/doctor/config.js +139 -0
- package/dist/core/doctor/config.js.map +1 -0
- package/dist/core/doctor/doctor.js +355 -0
- package/dist/core/doctor/doctor.js.map +1 -0
- package/dist/core/doctor/report.js +13 -0
- package/dist/core/doctor/report.js.map +1 -0
- package/dist/core/doctor/reports/scan.js +242 -0
- package/dist/core/doctor/reports/scan.js.map +1 -0
- package/dist/core/doctor/residue.js +110 -0
- package/dist/core/doctor/residue.js.map +1 -0
- package/dist/core/document/apply.js +224 -0
- package/dist/core/document/apply.js.map +1 -0
- package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
- package/dist/core/document/frontmatter.js.map +1 -0
- package/dist/core/document/grammar/directives.js +143 -0
- package/dist/core/document/grammar/directives.js.map +1 -0
- package/dist/core/document/parse.js +286 -0
- package/dist/core/document/parse.js.map +1 -0
- package/dist/core/document/scenarios.js +238 -0
- package/dist/core/document/scenarios.js.map +1 -0
- package/dist/core/document/spec.js +234 -0
- package/dist/core/document/spec.js.map +1 -0
- package/dist/core/{config.js → envelope/config.js} +89 -18
- package/dist/core/envelope/config.js.map +1 -0
- package/dist/core/envelope/json.js +209 -0
- package/dist/core/envelope/json.js.map +1 -0
- package/dist/core/{version.js → envelope/version.js} +3 -3
- package/dist/core/envelope/version.js.map +1 -0
- package/dist/core/explain/families.js +180 -0
- package/dist/core/explain/families.js.map +1 -0
- package/dist/core/explain/fix-tables.js +178 -0
- package/dist/core/explain/fix-tables.js.map +1 -0
- package/dist/core/explain/lookup.js +194 -0
- package/dist/core/explain/lookup.js.map +1 -0
- package/dist/core/explain/refusals.js +49 -0
- package/dist/core/explain/refusals.js.map +1 -0
- package/dist/core/explain/terms/documents.js +227 -0
- package/dist/core/explain/terms/documents.js.map +1 -0
- package/dist/core/explain/terms/done-check.js +144 -0
- package/dist/core/explain/terms/done-check.js.map +1 -0
- package/dist/core/explain/terms/entry.js +14 -0
- package/dist/core/explain/terms/entry.js.map +1 -0
- package/dist/core/explain/terms/stages.js +71 -0
- package/dist/core/explain/terms/stages.js.map +1 -0
- package/dist/core/explain/terms/tasks.js +97 -0
- package/dist/core/explain/terms/tasks.js.map +1 -0
- package/dist/core/explain/terms.js +103 -0
- package/dist/core/explain/terms.js.map +1 -0
- package/dist/core/explore/describe.js +105 -0
- package/dist/core/explore/describe.js.map +1 -0
- package/dist/core/explore/explore.js +204 -0
- package/dist/core/explore/explore.js.map +1 -0
- package/dist/core/fleet-context.js +174 -146
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +208 -0
- package/dist/core/gate/checks.js.map +1 -0
- package/dist/core/gate/partners.js +246 -0
- package/dist/core/gate/partners.js.map +1 -0
- package/dist/core/gate/report.js +47 -0
- package/dist/core/gate/report.js.map +1 -0
- package/dist/core/gate/verification.js +176 -0
- package/dist/core/gate/verification.js.map +1 -0
- package/dist/core/gherkin/digest.js +60 -0
- package/dist/core/gherkin/digest.js.map +1 -0
- package/dist/core/gherkin/emit.js +177 -0
- package/dist/core/gherkin/emit.js.map +1 -0
- package/dist/core/gherkin/read.js +76 -0
- package/dist/core/gherkin/read.js.map +1 -0
- package/dist/core/gherkin/stale.js +210 -0
- package/dist/core/gherkin/stale.js.map +1 -0
- package/dist/core/gherkin/stamp.js +77 -0
- package/dist/core/gherkin/stamp.js.map +1 -0
- package/dist/core/gherkin/steps/catalogue.js +154 -0
- package/dist/core/gherkin/steps/catalogue.js.map +1 -0
- package/dist/core/gherkin/steps/inventory.js +98 -0
- package/dist/core/gherkin/steps/inventory.js.map +1 -0
- package/dist/core/gherkin/steps/phrase.js +72 -0
- package/dist/core/gherkin/steps/phrase.js.map +1 -0
- package/dist/core/glossary/delta.js +109 -0
- package/dist/core/glossary/delta.js.map +1 -0
- package/dist/core/glossary/tree.js +73 -0
- package/dist/core/glossary/tree.js.map +1 -0
- package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
- package/dist/core/kernel/concurrency.js.map +1 -0
- package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
- package/dist/core/kernel/document-bytes.js.map +1 -0
- package/dist/core/kernel/fences.js +42 -0
- package/dist/core/kernel/fences.js.map +1 -0
- package/dist/core/kernel/ids/capability.js +72 -0
- package/dist/core/kernel/ids/capability.js.map +1 -0
- package/dist/core/kernel/ids/dirs.js +33 -0
- package/dist/core/kernel/ids/dirs.js.map +1 -0
- package/dist/core/kernel/ids/feature.js +75 -0
- package/dist/core/kernel/ids/feature.js.map +1 -0
- package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
- package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
- package/dist/core/kernel/ids/service.js +156 -0
- package/dist/core/kernel/ids/service.js.map +1 -0
- package/dist/core/kernel/ids/subsystem.js +63 -0
- package/dist/core/kernel/ids/subsystem.js.map +1 -0
- package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
- package/dist/core/kernel/path-safety.js.map +1 -0
- package/dist/core/{records.js → kernel/records.js} +11 -0
- package/dist/core/kernel/records.js.map +1 -0
- package/dist/core/links/backlinks.js +66 -0
- package/dist/core/links/backlinks.js.map +1 -0
- package/dist/core/links/case.js +74 -0
- package/dist/core/links/case.js.map +1 -0
- package/dist/core/links/corpus.js +118 -0
- package/dist/core/links/corpus.js.map +1 -0
- package/dist/core/links/findings.js +110 -0
- package/dist/core/links/findings.js.map +1 -0
- package/dist/core/links/parse.js +265 -0
- package/dist/core/links/parse.js.map +1 -0
- package/dist/core/mcp/argv.js +212 -0
- package/dist/core/mcp/argv.js.map +1 -0
- package/dist/core/mcp/author-tools.js +73 -0
- package/dist/core/mcp/author-tools.js.map +1 -0
- package/dist/core/mcp/framing.js +46 -0
- package/dist/core/mcp/framing.js.map +1 -0
- package/dist/core/mcp/protocol.js +280 -0
- package/dist/core/mcp/protocol.js.map +1 -0
- package/dist/core/mcp/tools.js +324 -0
- package/dist/core/mcp/tools.js.map +1 -0
- package/dist/core/obligations/obligations.js +106 -0
- package/dist/core/obligations/obligations.js.map +1 -0
- package/dist/core/openapi/baseline/gate.js +207 -0
- package/dist/core/openapi/baseline/gate.js.map +1 -0
- package/dist/core/openapi/baseline/plan.js +142 -0
- package/dist/core/openapi/baseline/plan.js.map +1 -0
- package/dist/core/openapi/baseline/record.js +174 -0
- package/dist/core/openapi/baseline/record.js.map +1 -0
- package/dist/core/openapi/contract-text.js +33 -0
- package/dist/core/openapi/contract-text.js.map +1 -0
- package/dist/core/openapi/contract-tree.js +301 -0
- package/dist/core/openapi/contract-tree.js.map +1 -0
- package/dist/core/openapi/depth.js +136 -0
- package/dist/core/openapi/depth.js.map +1 -0
- package/dist/core/openapi/digest.js +239 -0
- package/dist/core/openapi/digest.js.map +1 -0
- package/dist/core/{openapi.js → openapi/doc.js} +54 -108
- package/dist/core/openapi/doc.js.map +1 -0
- package/dist/core/openapi/merge/components.js +199 -0
- package/dist/core/openapi/merge/components.js.map +1 -0
- package/dist/core/openapi/merge/error.js +16 -0
- package/dist/core/openapi/merge/error.js.map +1 -0
- package/dist/core/openapi/merge/markers.js +204 -0
- package/dist/core/openapi/merge/markers.js.map +1 -0
- package/dist/core/openapi/merge/merge.js +232 -0
- package/dist/core/openapi/merge/merge.js.map +1 -0
- package/dist/core/openapi/merge/pin.js +110 -0
- package/dist/core/openapi/merge/pin.js.map +1 -0
- package/dist/core/openspec/decide/capabilities.js +244 -0
- package/dist/core/openspec/decide/capabilities.js.map +1 -0
- package/dist/core/openspec/decide/dispositions.js +63 -0
- package/dist/core/openspec/decide/dispositions.js.map +1 -0
- package/dist/core/openspec/decide/renames.js +179 -0
- package/dist/core/openspec/decide/renames.js.map +1 -0
- package/dist/core/openspec/decide/verdict.js +84 -0
- package/dist/core/openspec/decide/verdict.js.map +1 -0
- package/dist/core/openspec/inventory.js +220 -0
- package/dist/core/openspec/inventory.js.map +1 -0
- package/dist/core/openspec/model/mapping.js +78 -0
- package/dist/core/openspec/model/mapping.js.map +1 -0
- package/dist/core/openspec/model/model.js +70 -0
- package/dist/core/openspec/model/model.js.map +1 -0
- package/dist/core/openspec/scan/changes.js +241 -0
- package/dist/core/openspec/scan/changes.js.map +1 -0
- package/dist/core/openspec/scan/config.js +191 -0
- package/dist/core/openspec/scan/config.js.map +1 -0
- package/dist/core/openspec/scan/shape.js +304 -0
- package/dist/core/openspec/scan/shape.js.map +1 -0
- package/dist/core/openspec/scan/walk.js +116 -0
- package/dist/core/openspec/scan/walk.js.map +1 -0
- package/dist/core/openspec/scan/workspace.js +71 -0
- package/dist/core/openspec/scan/workspace.js.map +1 -0
- package/dist/core/owners/codeowners.js +141 -0
- package/dist/core/owners/codeowners.js.map +1 -0
- package/dist/core/pack/features.js +120 -0
- package/dist/core/pack/features.js.map +1 -0
- package/dist/core/pack/joins.js +112 -0
- package/dist/core/pack/joins.js.map +1 -0
- package/dist/core/pack/living.js +157 -0
- package/dist/core/pack/living.js.map +1 -0
- package/dist/core/pack/pack.js +120 -0
- package/dist/core/pack/pack.js.map +1 -0
- package/dist/core/permissions/permissions.js +87 -0
- package/dist/core/permissions/permissions.js.map +1 -0
- package/dist/core/projection/api.js +84 -0
- package/dist/core/projection/api.js.map +1 -0
- package/dist/core/projection/arch-slice.js +63 -0
- package/dist/core/projection/arch-slice.js.map +1 -0
- package/dist/core/projection/events.js +34 -0
- package/dist/core/projection/events.js.map +1 -0
- package/dist/core/projection/introduced.js +14 -0
- package/dist/core/projection/introduced.js.map +1 -0
- package/dist/core/provenance/findings.js +244 -0
- package/dist/core/provenance/findings.js.map +1 -0
- package/dist/core/provenance/git.js +201 -0
- package/dist/core/provenance/git.js.map +1 -0
- package/dist/core/provenance/gitq/moves.js +139 -0
- package/dist/core/provenance/gitq/moves.js.map +1 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
- package/dist/core/provenance/sample/scope.js +238 -0
- package/dist/core/provenance/sample/scope.js.map +1 -0
- package/dist/core/provenance/sample/sections.js +61 -0
- package/dist/core/provenance/sample/sections.js.map +1 -0
- package/dist/core/provenance/sources.js +280 -0
- package/dist/core/provenance/sources.js.map +1 -0
- package/dist/core/provenance/stamp.js +220 -0
- package/dist/core/provenance/stamp.js.map +1 -0
- package/dist/core/provenance/walk.js +157 -0
- package/dist/core/provenance/walk.js.map +1 -0
- package/dist/core/repo/authored/paths.js +210 -0
- package/dist/core/repo/authored/paths.js.map +1 -0
- package/dist/core/repo/entries.js +126 -0
- package/dist/core/repo/entries.js.map +1 -0
- package/dist/core/repo/paths.js +322 -0
- package/dist/core/repo/paths.js.map +1 -0
- package/dist/core/repo/repo.js +308 -0
- package/dist/core/repo/repo.js.map +1 -0
- package/dist/core/repo/service-target.js +153 -0
- package/dist/core/repo/service-target.js.map +1 -0
- package/dist/core/repo/state.js +58 -0
- package/dist/core/repo/state.js.map +1 -0
- package/dist/core/repo/tree/find.js +61 -0
- package/dist/core/repo/tree/find.js.map +1 -0
- package/dist/core/repo/tree/fs.js +90 -0
- package/dist/core/repo/tree/fs.js.map +1 -0
- package/dist/core/repo/tree/marker.js +61 -0
- package/dist/core/repo/tree/marker.js.map +1 -0
- package/dist/core/repo/tree/render/body.js +258 -0
- package/dist/core/repo/tree/render/body.js.map +1 -0
- package/dist/core/repo/tree/render/projects.js +182 -0
- package/dist/core/repo/tree/render/projects.js.map +1 -0
- package/dist/core/repo/tree/render/service/header.js +125 -0
- package/dist/core/repo/tree/render/service/header.js.map +1 -0
- package/dist/core/repo/tree/render/service/peers.js +28 -0
- package/dist/core/repo/tree/render/service/peers.js.map +1 -0
- package/dist/core/repo/tree/render/service/view-id.js +67 -0
- package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
- package/dist/core/repo/tree/render/service/views.js +78 -0
- package/dist/core/repo/tree/render/service/views.js.map +1 -0
- package/dist/core/repo/tree/render/stale.js +42 -0
- package/dist/core/repo/tree/render/stale.js.map +1 -0
- package/dist/core/repo/tree/render/text.js +84 -0
- package/dist/core/repo/tree/render/text.js.map +1 -0
- package/dist/core/repo/tree/render/views.js +293 -0
- package/dist/core/repo/tree/render/views.js.map +1 -0
- package/dist/core/repo/tree/walk.js +255 -0
- package/dist/core/repo/tree/walk.js.map +1 -0
- package/dist/core/results.js +146 -14
- package/dist/core/results.js.map +1 -1
- package/dist/core/scaffold/landscape.js +239 -0
- package/dist/core/scaffold/landscape.js.map +1 -0
- package/dist/core/scaffold/legacy.js +271 -0
- package/dist/core/scaffold/legacy.js.map +1 -0
- package/dist/core/scaffold/readme.js +84 -0
- package/dist/core/scaffold/readme.js.map +1 -0
- package/dist/core/staging/commit.js +252 -0
- package/dist/core/staging/commit.js.map +1 -0
- package/dist/core/staging/interrupted.js +96 -0
- package/dist/core/staging/interrupted.js.map +1 -0
- package/dist/core/staging/lock.js +268 -0
- package/dist/core/staging/lock.js.map +1 -0
- package/dist/core/staging/recovery/finding.js +35 -0
- package/dist/core/staging/recovery/finding.js.map +1 -0
- package/dist/core/staging/recovery/intent.js +95 -0
- package/dist/core/staging/recovery/intent.js.map +1 -0
- package/dist/core/staging/recovery/recover.js +204 -0
- package/dist/core/staging/recovery/recover.js.map +1 -0
- package/dist/core/staging/recovery/residue.js +62 -0
- package/dist/core/staging/recovery/residue.js.map +1 -0
- package/dist/core/staging/snapshot/manifest.js +188 -0
- package/dist/core/staging/snapshot/manifest.js.map +1 -0
- package/dist/core/staging/snapshot/snapshot.js +196 -0
- package/dist/core/staging/snapshot/snapshot.js.map +1 -0
- package/dist/core/staging/txn/forward.js +181 -0
- package/dist/core/staging/txn/forward.js.map +1 -0
- package/dist/core/staging/txn/journal.js +139 -0
- package/dist/core/staging/txn/journal.js.map +1 -0
- package/dist/core/staging/txn/transaction.js +75 -0
- package/dist/core/staging/txn/transaction.js.map +1 -0
- package/dist/core/staging/writes.js +113 -0
- package/dist/core/staging/writes.js.map +1 -0
- package/dist/core/status/actions/execution.js +60 -0
- package/dist/core/status/actions/execution.js.map +1 -0
- package/dist/core/status/contracts.js +126 -0
- package/dist/core/status/contracts.js.map +1 -0
- package/dist/core/status/feature/artifacts.js +196 -0
- package/dist/core/status/feature/artifacts.js.map +1 -0
- package/dist/core/status/feature/feature.js +214 -0
- package/dist/core/status/feature/feature.js.map +1 -0
- package/dist/core/status/feature/next.js +163 -0
- package/dist/core/status/feature/next.js.map +1 -0
- package/dist/core/status/feature/state.js +21 -0
- package/dist/core/status/feature/state.js.map +1 -0
- package/dist/core/status/feature/words.js +96 -0
- package/dist/core/status/feature/words.js.map +1 -0
- package/dist/core/status/fleet/fleet.js +216 -0
- package/dist/core/status/fleet/fleet.js.map +1 -0
- package/dist/core/status/fleet/next.js +302 -0
- package/dist/core/status/fleet/next.js.map +1 -0
- package/dist/core/status/interrupted.js +97 -0
- package/dist/core/status/interrupted.js.map +1 -0
- package/dist/core/status/report.js +31 -0
- package/dist/core/status/report.js.map +1 -0
- package/dist/core/status/scan.js +41 -0
- package/dist/core/status/scan.js.map +1 -0
- package/dist/core/status/verification.js +216 -0
- package/dist/core/status/verification.js.map +1 -0
- package/dist/core/tasks/packet.js +199 -0
- package/dist/core/tasks/packet.js.map +1 -0
- package/dist/core/tasks/record.js +43 -0
- package/dist/core/tasks/record.js.map +1 -0
- package/dist/core/tasks/sources.js +181 -0
- package/dist/core/tasks/sources.js.map +1 -0
- package/dist/core/tasks/stamps.js +76 -0
- package/dist/core/tasks/stamps.js.map +1 -0
- package/dist/core/tasks/unit.js +0 -0
- package/dist/core/tasks/unit.js.map +1 -0
- package/dist/core/usecases/capability.js +166 -0
- package/dist/core/usecases/capability.js.map +1 -0
- package/dist/core/usecases/delta/claims.js +140 -0
- package/dist/core/usecases/delta/claims.js.map +1 -0
- package/dist/core/usecases/delta/flows.js +101 -0
- package/dist/core/usecases/delta/flows.js.map +1 -0
- package/dist/core/usecases/delta/modified.js +315 -0
- package/dist/core/usecases/delta/modified.js.map +1 -0
- package/dist/core/usecases/delta/overlay.js +76 -0
- package/dist/core/usecases/delta/overlay.js.map +1 -0
- package/dist/core/usecases/fleet.js +296 -0
- package/dist/core/usecases/fleet.js.map +1 -0
- package/dist/core/usecases/grade/capability-tag.js +93 -0
- package/dist/core/usecases/grade/capability-tag.js.map +1 -0
- package/dist/core/usecases/grade/feature.js +88 -0
- package/dist/core/usecases/grade/feature.js.map +1 -0
- package/dist/core/usecases/grade/requirement-tag.js +94 -0
- package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
- package/dist/core/usecases/grade/steps.js +266 -0
- package/dist/core/usecases/grade/steps.js.map +1 -0
- package/dist/core/usecases/grade/usecases.js +112 -0
- package/dist/core/usecases/grade/usecases.js.map +1 -0
- package/dist/core/usecases/operations.js +123 -0
- package/dist/core/usecases/operations.js.map +1 -0
- package/dist/core/usecases/place.js +44 -0
- package/dist/core/usecases/place.js.map +1 -0
- package/dist/core/usecases/service/exclude.js +119 -0
- package/dist/core/usecases/service/exclude.js.map +1 -0
- package/dist/core/usecases/service/flows.js +164 -0
- package/dist/core/usecases/service/flows.js.map +1 -0
- package/dist/core/usecases/suites/participants.js +83 -0
- package/dist/core/usecases/suites/participants.js.map +1 -0
- package/dist/core/usecases/suites/suites.js +45 -0
- package/dist/core/usecases/suites/suites.js.map +1 -0
- package/dist/core/usecases/touch.js +101 -0
- package/dist/core/usecases/touch.js.map +1 -0
- package/dist/core/verify/answers.js +180 -0
- package/dist/core/verify/answers.js.map +1 -0
- package/dist/core/verify/build.js +170 -0
- package/dist/core/verify/build.js.map +1 -0
- package/dist/core/verify/checklist.js +259 -0
- package/dist/core/verify/checklist.js.map +1 -0
- package/dist/core/verify/claims/identity.js +61 -0
- package/dist/core/verify/claims/identity.js.map +1 -0
- package/dist/core/verify/cross/diff.js +97 -0
- package/dist/core/verify/cross/diff.js.map +1 -0
- package/dist/core/verify/evidence/contract.js +169 -0
- package/dist/core/verify/evidence/contract.js.map +1 -0
- package/dist/core/verify/location.js +67 -0
- package/dist/core/verify/location.js.map +1 -0
- package/dist/core/verify/pins/lint.js +158 -0
- package/dist/core/verify/pins/lint.js.map +1 -0
- package/dist/core/verify/pins/pin.js +95 -0
- package/dist/core/verify/pins/pin.js.map +1 -0
- package/dist/core/verify/read/file.js +224 -0
- package/dist/core/verify/read/file.js.map +1 -0
- package/dist/core/verify/read/shape.js +169 -0
- package/dist/core/verify/read/shape.js.map +1 -0
- package/dist/core/verify/read/union.js +105 -0
- package/dist/core/verify/read/union.js.map +1 -0
- package/dist/core/verify/record.js +165 -0
- package/dist/core/verify/record.js.map +1 -0
- package/dist/core/verify/store/commit.js +99 -0
- package/dist/core/verify/store/commit.js.map +1 -0
- package/dist/core/verify/store/render.js +61 -0
- package/dist/core/verify/store/render.js.map +1 -0
- package/dist/core/vocabulary/health.js +91 -0
- package/dist/core/vocabulary/health.js.map +1 -0
- package/dist/core/vocabulary/issue.js +59 -0
- package/dist/core/vocabulary/issue.js.map +1 -0
- package/dist/core/vocabulary/maturity.js +216 -0
- package/dist/core/vocabulary/maturity.js.map +1 -0
- package/dist/core/vocabulary/report.js +90 -0
- package/dist/core/vocabulary/report.js.map +1 -0
- package/dist/core/vocabulary/steps.js +266 -0
- package/dist/core/vocabulary/steps.js.map +1 -0
- package/dist/core/workspace/discover.js +239 -0
- package/dist/core/workspace/discover.js.map +1 -0
- package/dist/core/workspace/render.js +52 -0
- package/dist/core/workspace/render.js.map +1 -0
- package/examples/README.md +232 -0
- package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
- package/examples/docs/architecture/capabilities.yaml +31 -0
- package/examples/docs/architecture/landscape.likec4 +336 -0
- package/examples/docs/architecture/obligations.yaml +23 -0
- package/examples/docs/architecture/permissions.yaml +50 -0
- package/examples/docs/architecture/services.likec4 +70 -0
- package/examples/docs/architecture/subsystems.likec4 +18 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
- package/examples/docs/capabilities/checkout/spec.md +55 -0
- package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
- package/examples/docs/capabilities/order-notifications/spec.md +43 -0
- package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
- package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
- package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
- package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
- package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
- package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
- package/examples/docs/glossary/order.md +15 -0
- package/examples/docs/glossary/payments/authorization.md +14 -0
- package/examples/docs/likec4.config.json +8 -0
- package/examples/docs/loam.json +3 -0
- package/examples/docs/services/checkout-web/model.likec4 +92 -0
- package/examples/docs/services/checkout-web/spec.md +91 -0
- package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
- package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
- package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
- package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
- package/examples/docs/services/order-service/arch.spec.md +134 -0
- package/examples/docs/services/order-service/asyncapi.yaml +109 -0
- package/examples/docs/services/order-service/health.yaml +57 -0
- package/examples/docs/services/order-service/model.likec4 +126 -0
- package/examples/docs/services/order-service/openapi.yaml +257 -0
- package/examples/docs/services/order-service/runbook.md +62 -0
- package/examples/docs/services/order-service/spec.md +134 -0
- package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
- package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
- package/examples/docs/services/payment-service/arch.spec.md +76 -0
- package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
- package/examples/docs/services/payment-service/health.yaml +39 -0
- package/examples/docs/services/payment-service/model.likec4 +68 -0
- package/examples/docs/services/payment-service/openapi.yaml +151 -0
- package/examples/docs/services/payment-service/runbook.md +37 -0
- package/examples/docs/services/payment-service/spec.md +88 -0
- package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
- package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
- package/examples/docs/services/platform/identity-service/health.yaml +70 -0
- package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
- package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
- package/examples/docs/services/platform/identity-service/runbook.md +95 -0
- package/examples/docs/services/platform/identity-service/spec.md +119 -0
- package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
- package/examples/docs/services/platform/notification-service/health.yaml +40 -0
- package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
- package/examples/docs/services/platform/notification-service/runbook.md +48 -0
- package/examples/docs/services/platform/notification-service/spec.md +112 -0
- package/examples/docs/services/platform/subsystem.yaml +2 -0
- package/examples/fleet.yaml +57 -0
- package/package.json +19 -6
- package/dist/commands/adopt.js +0 -240
- package/dist/commands/adopt.js.map +0 -1
- package/dist/commands/archive.js +0 -1313
- package/dist/commands/archive.js.map +0 -1
- package/dist/commands/delta.js +0 -388
- package/dist/commands/delta.js.map +0 -1
- package/dist/commands/docs-repo-gate.js.map +0 -1
- package/dist/commands/format.js +0 -17
- package/dist/commands/format.js.map +0 -1
- package/dist/commands/gherkin.js +0 -309
- package/dist/commands/gherkin.js.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list.js +0 -295
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/migrate-openspec.js +0 -950
- package/dist/commands/migrate-openspec.js.map +0 -1
- package/dist/commands/new.js +0 -413
- package/dist/commands/new.js.map +0 -1
- package/dist/commands/rebase.js +0 -356
- package/dist/commands/rebase.js.map +0 -1
- package/dist/commands/show.js +0 -320
- package/dist/commands/show.js.map +0 -1
- package/dist/commands/status.js +0 -262
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/unarchive.js +0 -317
- package/dist/commands/unarchive.js.map +0 -1
- package/dist/commands/validate.js +0 -1773
- package/dist/commands/validate.js.map +0 -1
- package/dist/commands/verify.js +0 -775
- package/dist/commands/verify.js.map +0 -1
- package/dist/commands/vouch.js +0 -421
- package/dist/commands/vouch.js.map +0 -1
- package/dist/core/agent.js +0 -2173
- package/dist/core/agent.js.map +0 -1
- package/dist/core/agents-stamp.js.map +0 -1
- package/dist/core/arch.js +0 -130
- package/dist/core/arch.js.map +0 -1
- package/dist/core/asyncapi.js +0 -253
- package/dist/core/asyncapi.js.map +0 -1
- package/dist/core/brief.js +0 -755
- package/dist/core/brief.js.map +0 -1
- package/dist/core/coherence.js +0 -577
- package/dist/core/coherence.js.map +0 -1
- package/dist/core/concurrency.js.map +0 -1
- package/dist/core/config.js.map +0 -1
- package/dist/core/delta.js +0 -476
- package/dist/core/delta.js.map +0 -1
- package/dist/core/dependencies.js +0 -356
- package/dist/core/dependencies.js.map +0 -1
- package/dist/core/doctor.js +0 -596
- package/dist/core/doctor.js.map +0 -1
- package/dist/core/document-bytes.js.map +0 -1
- package/dist/core/explore.js +0 -225
- package/dist/core/explore.js.map +0 -1
- package/dist/core/frontmatter.js.map +0 -1
- package/dist/core/gherkin.js +0 -463
- package/dist/core/gherkin.js.map +0 -1
- package/dist/core/health.js +0 -67
- package/dist/core/health.js.map +0 -1
- package/dist/core/ids.js +0 -122
- package/dist/core/ids.js.map +0 -1
- package/dist/core/issue.js +0 -9
- package/dist/core/issue.js.map +0 -1
- package/dist/core/json.js +0 -74
- package/dist/core/json.js.map +0 -1
- package/dist/core/likec4.js +0 -489
- package/dist/core/likec4.js.map +0 -1
- package/dist/core/maturity.js +0 -66
- package/dist/core/maturity.js.map +0 -1
- package/dist/core/openapi-merge.js +0 -552
- package/dist/core/openapi-merge.js.map +0 -1
- package/dist/core/openapi.js.map +0 -1
- package/dist/core/openspec-inventory.js +0 -1440
- package/dist/core/openspec-inventory.js.map +0 -1
- package/dist/core/path-safety.js.map +0 -1
- package/dist/core/provenance.js +0 -787
- package/dist/core/provenance.js.map +0 -1
- package/dist/core/records.js.map +0 -1
- package/dist/core/repo.js +0 -438
- package/dist/core/repo.js.map +0 -1
- package/dist/core/report.js +0 -47
- package/dist/core/report.js.map +0 -1
- package/dist/core/spec.js +0 -505
- package/dist/core/spec.js.map +0 -1
- package/dist/core/staging.js +0 -890
- package/dist/core/staging.js.map +0 -1
- package/dist/core/status.js +0 -1132
- package/dist/core/status.js.map +0 -1
- package/dist/core/steps.js +0 -72
- package/dist/core/steps.js.map +0 -1
- package/dist/core/verify.js +0 -807
- package/dist/core/verify.js.map +0 -1
- package/dist/core/version.js.map +0 -1
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { actionOf, groupOf } from "./actions.js";
|
|
2
|
+
/**
|
|
3
|
+
* How many units one service shows in the WHOLE-feature view before the rest
|
|
4
|
+
* are elided behind its own lens. Under a lens nothing is elided: the lens IS
|
|
5
|
+
* the full listing, and pointing a person who already asked for one service at
|
|
6
|
+
* `--json` to see the rest of it sent them to the one view not written for them.
|
|
7
|
+
*/
|
|
8
|
+
const PER_SERVICE_LIMIT = 12;
|
|
9
|
+
/** What each record state means for the list below it, in the words a reader acts on. */
|
|
10
|
+
const RECORD_MEANING = {
|
|
11
|
+
absent: "no verification record yet, so nothing counts as done",
|
|
12
|
+
recorded: "the verification record answers this checklist; what it confirmed is off this list, bar attested scenarios",
|
|
13
|
+
stale: "the verification record answers an older question set, so it closes nothing until it is re-recorded",
|
|
14
|
+
unreadable: "the verification record could not be read, so it closes nothing",
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* What the stamps reading means, which turns on WHERE loam is standing.
|
|
18
|
+
*
|
|
19
|
+
* The stamps are read from this repository's generated suite and nobody else's
|
|
20
|
+
* (core/tasks/stamps.ts). So a scenario owned by another service reads
|
|
21
|
+
* `implement` whatever its own repository holds — the packet's honest answer,
|
|
22
|
+
* because nothing here looked — and the header says so whenever such a unit is
|
|
23
|
+
* on screen, or a person reads "implement" as "the test exists".
|
|
24
|
+
*/
|
|
25
|
+
function stampsMeaning(packet, view) {
|
|
26
|
+
if (packet.stamps === "unknown") {
|
|
27
|
+
return view.bound === undefined
|
|
28
|
+
? "this is not a service repository bound with loam.json, so loam cannot see which tests were generated — " +
|
|
29
|
+
"run it in the service's repo to tell 'generate' from 'implement'"
|
|
30
|
+
: `this repository's generated suite (${view.bound}) could not be read — an unreadable directory, ` +
|
|
31
|
+
"or a gherkinDir outside the repository — so no scenario reads 'generate'";
|
|
32
|
+
}
|
|
33
|
+
const own = `from this repository's generated suite${view.bound === undefined ? "" : ` (${view.bound})`}`;
|
|
34
|
+
const elsewhere = [
|
|
35
|
+
...new Set(packet.units.filter((unit) => unit.kind === "scenario.tested" && unit.subject !== view.bound).map((u) => u.subject)),
|
|
36
|
+
];
|
|
37
|
+
if (elsewhere.length === 0)
|
|
38
|
+
return own;
|
|
39
|
+
const one = elsewhere.length === 1;
|
|
40
|
+
return (`${own}; ${elsewhere.join(", ")} ${one ? "keeps its tests in its own repository" : "keep their tests in their own repositories"}, ` +
|
|
41
|
+
`so ${one ? "its" : "their"} scenarios read 'implement' whatever is generated there — ` +
|
|
42
|
+
`run loam tasks in ${one ? "that repository" : "those repositories"}`);
|
|
43
|
+
}
|
|
44
|
+
/** Which slice of the feature this is, and how to get another. */
|
|
45
|
+
function lensLine(packet, view) {
|
|
46
|
+
const lens = packet.service;
|
|
47
|
+
if (lens !== null && view.explicitLens)
|
|
48
|
+
return `lens: ${lens} — its units only, every one listed`;
|
|
49
|
+
if (lens !== null)
|
|
50
|
+
return `lens: ${lens} — this repository's service (loam.json); pass --service <id> for another`;
|
|
51
|
+
const among = packet.services.length === 0 ? "" : ` (${packet.services.join(", ")})`;
|
|
52
|
+
return view.bound === undefined
|
|
53
|
+
? `view: the whole feature${among} — --service <id> narrows it to one service`
|
|
54
|
+
: `view: the whole feature${among} — this repository's service, ${view.bound}, is not one ${packet.feature} touches`;
|
|
55
|
+
}
|
|
56
|
+
/** The lines under the title both views share: what the record and the stamps MEAN, the lens, the blind spots. */
|
|
57
|
+
function header(packet, view) {
|
|
58
|
+
console.log(` record: ${packet.record} — ${RECORD_MEANING[packet.record]}`);
|
|
59
|
+
console.log(` stamps: ${packet.stamps} — ${stampsMeaning(packet, view)}`);
|
|
60
|
+
console.log(` ${lensLine(packet, view)}`);
|
|
61
|
+
// The blind spots straight after, and before any list: an empty packet over a
|
|
62
|
+
// document nobody could read is the one output an implementer must never take
|
|
63
|
+
// at face value, and a warning under fifty lines of units is one nobody reads.
|
|
64
|
+
for (const warning of blindSpots(packet))
|
|
65
|
+
console.log(` ⚠ ${warning}`);
|
|
66
|
+
}
|
|
67
|
+
/** The step tag, padded so the actions line up: `[implement]` is the widest. */
|
|
68
|
+
function tag(step) {
|
|
69
|
+
return `[${step}]`.padEnd("[implement]".length);
|
|
70
|
+
}
|
|
71
|
+
/** One row: the step, the action, the scenario's own line when it has one, and the id an agent hands on. */
|
|
72
|
+
function row(unit, feature) {
|
|
73
|
+
const source = unit.source;
|
|
74
|
+
const line = source !== undefined && "scenario" in source && source.line !== undefined ? ` · line ${source.line}` : "";
|
|
75
|
+
return ` ${tag(unit.at)} ${actionOf(unit, feature)}${line} · ${unit.id}`;
|
|
76
|
+
}
|
|
77
|
+
/** Units filed under their heading, in the order the packet already sorted them — first appearance wins. */
|
|
78
|
+
function grouped(units) {
|
|
79
|
+
const groups = new Map();
|
|
80
|
+
for (const unit of units) {
|
|
81
|
+
const group = groupOf(unit);
|
|
82
|
+
const existing = groups.get(group.key);
|
|
83
|
+
if (existing === undefined)
|
|
84
|
+
groups.set(group.key, { ...group, units: [unit] });
|
|
85
|
+
else
|
|
86
|
+
existing.units.push(unit);
|
|
87
|
+
}
|
|
88
|
+
return [...groups.values()];
|
|
89
|
+
}
|
|
90
|
+
/** `9 open`, plus the attested ones when there are any — those are listed, and are not work. */
|
|
91
|
+
function tally(units) {
|
|
92
|
+
const attested = units.filter((unit) => unit.at === "attested").length;
|
|
93
|
+
return `${units.length - attested} open${attested === 0 ? "" : ` · ${attested} attested`}`;
|
|
94
|
+
}
|
|
95
|
+
/** The `--next` invocation for this packet's own slice — the flag carried only when the reader typed it. */
|
|
96
|
+
function nextCommand(packet, view) {
|
|
97
|
+
const lens = view.explicitLens && packet.service !== null ? ` --service ${packet.service}` : "";
|
|
98
|
+
return `loam tasks ${packet.feature}${lens} --next`;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The frontier as a person reads it: the head's action first, then the ids.
|
|
102
|
+
* A bare list of ten hashes said what to do to nobody; the ids stay, because
|
|
103
|
+
* they are the order an orchestrator hands units out in.
|
|
104
|
+
*/
|
|
105
|
+
function frontierLines(packet, view) {
|
|
106
|
+
const headId = packet.frontier[0];
|
|
107
|
+
if (headId === undefined)
|
|
108
|
+
return [];
|
|
109
|
+
const head = packet.units.find((unit) => unit.id === headId);
|
|
110
|
+
const more = packet.frontierElided > 0 ? ` (+${packet.frontierElided} more open)` : "";
|
|
111
|
+
return [
|
|
112
|
+
head === undefined
|
|
113
|
+
? ` next up: ${headId}`
|
|
114
|
+
: ` next up (${head.subject}): ${actionOf(head, packet.feature)} · ${headId}`,
|
|
115
|
+
` ${nextCommand(packet, view)} prints it in full, with what closes it`,
|
|
116
|
+
` frontier, the order to take open units in: ${packet.frontier.join(", ")}${more}`,
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
export function renderPacket(packet, view) {
|
|
120
|
+
// Attested is the one count whose word misleads: it reads like "done", and
|
|
121
|
+
// it is the opposite — complete work resting on an assertion, still listed.
|
|
122
|
+
const attested = packet.counts.attested === 0 ? "" : " (confirmed on an agent's word, not a run — still listed)";
|
|
123
|
+
console.log(`${packet.feature} — ${packet.counts.open} open · ${packet.counts.done} done · ${packet.counts.attested} attested${attested}`);
|
|
124
|
+
header(packet, view);
|
|
125
|
+
console.log("");
|
|
126
|
+
if (packet.units.length === 0) {
|
|
127
|
+
console.log(packet.counts.attested > 0 || packet.counts.done > 0
|
|
128
|
+
? " Nothing open. Every unit is recorded confirmed, or attested and waiting on a run."
|
|
129
|
+
: " Nothing open — this feature's delta, specs and contracts promise nothing yet.");
|
|
130
|
+
}
|
|
131
|
+
const capped = packet.service === null;
|
|
132
|
+
for (const subject of new Set(packet.units.map((unit) => unit.subject))) {
|
|
133
|
+
const units = packet.units.filter((unit) => unit.subject === subject);
|
|
134
|
+
const shown = capped ? units.slice(0, PER_SERVICE_LIMIT) : units;
|
|
135
|
+
console.log(` ${subject} — ${tally(units)}`);
|
|
136
|
+
for (const group of grouped(shown)) {
|
|
137
|
+
console.log(` ${group.heading}`);
|
|
138
|
+
for (const unit of group.units)
|
|
139
|
+
console.log(row(unit, packet.feature));
|
|
140
|
+
}
|
|
141
|
+
if (shown.length < units.length) {
|
|
142
|
+
console.log(` +${units.length - shown.length} more — \`loam tasks ${packet.feature} --service ${subject}\` lists every one`);
|
|
143
|
+
}
|
|
144
|
+
console.log("");
|
|
145
|
+
}
|
|
146
|
+
for (const line of frontierLines(packet, view))
|
|
147
|
+
console.log(line);
|
|
148
|
+
for (const waiting of packet.waitingOn ?? []) {
|
|
149
|
+
console.log(` waiting on ${waiting.subject}: ${waiting.claim} · ${waiting.id}, still open there`);
|
|
150
|
+
}
|
|
151
|
+
if (packet.units.length > 0) {
|
|
152
|
+
console.log("\n [step] is where a unit waits: describe → generate → implement, or attested. " +
|
|
153
|
+
"`loam explain <word>` defines each of those, and frontier.");
|
|
154
|
+
}
|
|
155
|
+
console.log("\n Review:");
|
|
156
|
+
for (const note of packet.review)
|
|
157
|
+
console.log(` - ${note}`);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The leaf, in full. The follow-up command is literal rather than a shape to
|
|
161
|
+
* fill in, because the reader is usually a model cheap enough that "the
|
|
162
|
+
* appropriate verify invocation" is a guess it will get wrong.
|
|
163
|
+
*/
|
|
164
|
+
export function renderNext(packet, view) {
|
|
165
|
+
const unit = packet.units[0];
|
|
166
|
+
if (unit === undefined) {
|
|
167
|
+
console.log(`${packet.feature} — nothing open (${packet.counts.done} done · ${packet.counts.attested} attested)`);
|
|
168
|
+
header(packet, view);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
console.log(`${packet.feature} — next: ${unit.id}`);
|
|
172
|
+
console.log(` ${actionOf(unit, packet.feature)}`);
|
|
173
|
+
// The lens only when the binding chose it: a reader who typed --service knows
|
|
174
|
+
// which slice this is, and one who did not would otherwise be handed another
|
|
175
|
+
// service's head with no word on why it is this one.
|
|
176
|
+
if (packet.service !== null && !view.explicitLens)
|
|
177
|
+
console.log(` ${lensLine(packet, view)}`);
|
|
178
|
+
for (const warning of blindSpots(packet))
|
|
179
|
+
console.log(` ⚠ ${warning}`);
|
|
180
|
+
const ungraded = ungradedScenario(packet, view, unit);
|
|
181
|
+
if (ungraded !== undefined)
|
|
182
|
+
console.log(` ⚠ ${ungraded}`);
|
|
183
|
+
console.log("");
|
|
184
|
+
console.log(` [${unit.at}] ${unit.kind} [${unit.subject}]`);
|
|
185
|
+
console.log(` ${unit.claim}`);
|
|
186
|
+
const source = unit.source;
|
|
187
|
+
if (source !== undefined) {
|
|
188
|
+
console.log(` ${source.path}${source.line === undefined ? "" : `:${source.line}`}`);
|
|
189
|
+
// Verbatim, never reflowed: these are the bytes the scenario digest was
|
|
190
|
+
// taken over, and a test written from reworded criteria answers a claim
|
|
191
|
+
// nobody made.
|
|
192
|
+
if ("lines" in source)
|
|
193
|
+
for (const body of source.lines)
|
|
194
|
+
console.log(` ${body}`);
|
|
195
|
+
}
|
|
196
|
+
if (unit.dependsOn.length > 0)
|
|
197
|
+
console.log(` depends on: ${unit.dependsOn.join(", ")}`);
|
|
198
|
+
console.log(`\n done: ${unit.done.check}`);
|
|
199
|
+
console.log(`\n ${followUp(packet.feature, unit)}`);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* The caveat a scenario at `implement` needs when nobody looked for its
|
|
203
|
+
* generated test: `implement` is also what a scenario reads when the stamps
|
|
204
|
+
* could not be read, or belong to another repository, and handing a worker
|
|
205
|
+
* "make it pass" for a test that was never generated sends them to write one by
|
|
206
|
+
* hand — the paraphrase the generated suite exists to prevent.
|
|
207
|
+
*/
|
|
208
|
+
function ungradedScenario(packet, view, unit) {
|
|
209
|
+
if (unit.kind !== "scenario.tested" || unit.at !== "implement")
|
|
210
|
+
return undefined;
|
|
211
|
+
if (packet.stamps === "read" && unit.subject === view.bound)
|
|
212
|
+
return undefined;
|
|
213
|
+
if (unit.subject === view.bound) {
|
|
214
|
+
return ("whether this scenario's test was generated is unknown — this repository's generated suite could not be read; " +
|
|
215
|
+
`if loam gherkin ${packet.feature} has not run here, run it first`);
|
|
216
|
+
}
|
|
217
|
+
return (`whether this scenario's test was generated is unknown here — its suite lives in ${unit.subject}'s repository; ` +
|
|
218
|
+
`run loam tasks there, or loam gherkin ${packet.feature} there first if it has not run`);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* The command that closes this unit.
|
|
222
|
+
*
|
|
223
|
+
* A `describe` unit is the one arm that is NOT a `loam verify --record`: there
|
|
224
|
+
* is no claim to answer, because a requirement with no scenario asks no
|
|
225
|
+
* question — the work is writing the Given/When/Then into the file named above,
|
|
226
|
+
* and `loam validate --feature` is what grades that it landed. Pointing it at
|
|
227
|
+
* `--record` would invite an answer to a question the checklist does not carry.
|
|
228
|
+
*/
|
|
229
|
+
function followUp(feature, unit) {
|
|
230
|
+
if (unit.at === "describe")
|
|
231
|
+
return `loam validate --feature ${feature}`;
|
|
232
|
+
if (unit.at === "generate")
|
|
233
|
+
return `loam gherkin ${feature}`;
|
|
234
|
+
if (unit.kind === "scenario.tested") {
|
|
235
|
+
return `loam verify ${feature} --service ${unit.subject} --results report.json`;
|
|
236
|
+
}
|
|
237
|
+
return `loam verify ${feature} --record answers.json --service ${unit.subject}`;
|
|
238
|
+
}
|
|
239
|
+
/** What the packet could not look at — one sentence per document class. */
|
|
240
|
+
function blindSpots(packet) {
|
|
241
|
+
const out = [];
|
|
242
|
+
if (packet.unreadable.architecture !== undefined) {
|
|
243
|
+
out.push(`delta.likec4 does not parse (${packet.unreadable.architecture}) — no c4.calls unit could be derived, ` +
|
|
244
|
+
"so this list is short because loam could not look, not because the work is done");
|
|
245
|
+
}
|
|
246
|
+
const contracts = packet.unreadable.contracts;
|
|
247
|
+
if (contracts !== undefined) {
|
|
248
|
+
out.push(`contract delta unreadable for ${contracts.join(", ")} — operations and messages are missing from this packet, ` +
|
|
249
|
+
"not absent from the feature");
|
|
250
|
+
}
|
|
251
|
+
return out;
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/commands/tasks/render.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The terminal view of a work packet.\n *\n * Two shapes for two readers. The whole packet is a person's orientation — how\n * much is open, filed under which service and which requirement, what each unit\n * asks them to DO, and which unit leads — so every row is an action rather than\n * the claim it answers, and the requirement's file is printed once over its\n * scenarios rather than on each of them. `--next` is the opposite: a single\n * leaf, printed in full, including the scenario's Given/When/Then VERBATIM,\n * because that text is the acceptance criterion and the exact words the digest\n * was taken over. Paraphrasing it into a summary is the one thing the digest\n * chain exists to prevent.\n *\n * Every row keeps its unit id. The id is what an agent hands `loam verify`, and\n * a view that dropped it to read better would turn the human listing into one\n * nobody can act on without a second, `--json`, run.\n *\n * Every `loam …` line printed here parses against the real CLI —\n * `test/agent-commands-runnable.test.ts` is the consumer, and an instruction\n * loam prints that does not parse is a defect rather than a typo.\n */\nimport type { WorkPacket } from \"../../core/tasks/packet.js\";\nimport type { RecordState } from \"../../core/tasks/record.js\";\nimport type { TaskStep, TaskUnit } from \"../../core/tasks/unit.js\";\nimport { actionOf, groupOf, type UnitGroup } from \"./actions.js\";\n\n/** What the command knows and the packet does not: where the lens came from, and which repository this is. */\nexport interface TasksView {\n /** True when `--service` named the lens; false when it came from the binding, or there is none. */\n explicitLens: boolean;\n /** loam.json's `service` — set only when standing in a service repository. */\n bound: string | undefined;\n}\n\n/**\n * How many units one service shows in the WHOLE-feature view before the rest\n * are elided behind its own lens. Under a lens nothing is elided: the lens IS\n * the full listing, and pointing a person who already asked for one service at\n * `--json` to see the rest of it sent them to the one view not written for them.\n */\nconst PER_SERVICE_LIMIT = 12;\n\n/** What each record state means for the list below it, in the words a reader acts on. */\nconst RECORD_MEANING: Record<RecordState, string> = {\n absent: \"no verification record yet, so nothing counts as done\",\n recorded: \"the verification record answers this checklist; what it confirmed is off this list, bar attested scenarios\",\n stale: \"the verification record answers an older question set, so it closes nothing until it is re-recorded\",\n unreadable: \"the verification record could not be read, so it closes nothing\",\n};\n\n/**\n * What the stamps reading means, which turns on WHERE loam is standing.\n *\n * The stamps are read from this repository's generated suite and nobody else's\n * (core/tasks/stamps.ts). So a scenario owned by another service reads\n * `implement` whatever its own repository holds — the packet's honest answer,\n * because nothing here looked — and the header says so whenever such a unit is\n * on screen, or a person reads \"implement\" as \"the test exists\".\n */\nfunction stampsMeaning(packet: WorkPacket, view: TasksView): string {\n if (packet.stamps === \"unknown\") {\n return view.bound === undefined\n ? \"this is not a service repository bound with loam.json, so loam cannot see which tests were generated — \" +\n \"run it in the service's repo to tell 'generate' from 'implement'\"\n : `this repository's generated suite (${view.bound}) could not be read — an unreadable directory, ` +\n \"or a gherkinDir outside the repository — so no scenario reads 'generate'\";\n }\n const own = `from this repository's generated suite${view.bound === undefined ? \"\" : ` (${view.bound})`}`;\n const elsewhere = [\n ...new Set(packet.units.filter((unit) => unit.kind === \"scenario.tested\" && unit.subject !== view.bound).map((u) => u.subject)),\n ];\n if (elsewhere.length === 0) return own;\n const one = elsewhere.length === 1;\n return (\n `${own}; ${elsewhere.join(\", \")} ${one ? \"keeps its tests in its own repository\" : \"keep their tests in their own repositories\"}, ` +\n `so ${one ? \"its\" : \"their\"} scenarios read 'implement' whatever is generated there — ` +\n `run loam tasks in ${one ? \"that repository\" : \"those repositories\"}`\n );\n}\n\n/** Which slice of the feature this is, and how to get another. */\nfunction lensLine(packet: WorkPacket, view: TasksView): string {\n const lens = packet.service;\n if (lens !== null && view.explicitLens) return `lens: ${lens} — its units only, every one listed`;\n if (lens !== null) return `lens: ${lens} — this repository's service (loam.json); pass --service <id> for another`;\n const among = packet.services.length === 0 ? \"\" : ` (${packet.services.join(\", \")})`;\n return view.bound === undefined\n ? `view: the whole feature${among} — --service <id> narrows it to one service`\n : `view: the whole feature${among} — this repository's service, ${view.bound}, is not one ${packet.feature} touches`;\n}\n\n/** The lines under the title both views share: what the record and the stamps MEAN, the lens, the blind spots. */\nfunction header(packet: WorkPacket, view: TasksView): void {\n console.log(` record: ${packet.record} — ${RECORD_MEANING[packet.record]}`);\n console.log(` stamps: ${packet.stamps} — ${stampsMeaning(packet, view)}`);\n console.log(` ${lensLine(packet, view)}`);\n // The blind spots straight after, and before any list: an empty packet over a\n // document nobody could read is the one output an implementer must never take\n // at face value, and a warning under fifty lines of units is one nobody reads.\n for (const warning of blindSpots(packet)) console.log(` ⚠ ${warning}`);\n}\n\n/** The step tag, padded so the actions line up: `[implement]` is the widest. */\nfunction tag(step: TaskStep): string {\n return `[${step}]`.padEnd(\"[implement]\".length);\n}\n\n/** One row: the step, the action, the scenario's own line when it has one, and the id an agent hands on. */\nfunction row(unit: TaskUnit, feature: string): string {\n const source = unit.source;\n const line = source !== undefined && \"scenario\" in source && source.line !== undefined ? ` · line ${source.line}` : \"\";\n return ` ${tag(unit.at)} ${actionOf(unit, feature)}${line} · ${unit.id}`;\n}\n\n/** Units filed under their heading, in the order the packet already sorted them — first appearance wins. */\nfunction grouped(units: readonly TaskUnit[]): Array<UnitGroup & { units: TaskUnit[] }> {\n const groups = new Map<string, UnitGroup & { units: TaskUnit[] }>();\n for (const unit of units) {\n const group = groupOf(unit);\n const existing = groups.get(group.key);\n if (existing === undefined) groups.set(group.key, { ...group, units: [unit] });\n else existing.units.push(unit);\n }\n return [...groups.values()];\n}\n\n/** `9 open`, plus the attested ones when there are any — those are listed, and are not work. */\nfunction tally(units: readonly TaskUnit[]): string {\n const attested = units.filter((unit) => unit.at === \"attested\").length;\n return `${units.length - attested} open${attested === 0 ? \"\" : ` · ${attested} attested`}`;\n}\n\n/** The `--next` invocation for this packet's own slice — the flag carried only when the reader typed it. */\nfunction nextCommand(packet: WorkPacket, view: TasksView): string {\n const lens = view.explicitLens && packet.service !== null ? ` --service ${packet.service}` : \"\";\n return `loam tasks ${packet.feature}${lens} --next`;\n}\n\n/**\n * The frontier as a person reads it: the head's action first, then the ids.\n * A bare list of ten hashes said what to do to nobody; the ids stay, because\n * they are the order an orchestrator hands units out in.\n */\nfunction frontierLines(packet: WorkPacket, view: TasksView): string[] {\n const headId = packet.frontier[0];\n if (headId === undefined) return [];\n const head = packet.units.find((unit) => unit.id === headId);\n const more = packet.frontierElided > 0 ? ` (+${packet.frontierElided} more open)` : \"\";\n return [\n head === undefined\n ? ` next up: ${headId}`\n : ` next up (${head.subject}): ${actionOf(head, packet.feature)} · ${headId}`,\n ` ${nextCommand(packet, view)} prints it in full, with what closes it`,\n ` frontier, the order to take open units in: ${packet.frontier.join(\", \")}${more}`,\n ];\n}\n\nexport function renderPacket(packet: WorkPacket, view: TasksView): void {\n // Attested is the one count whose word misleads: it reads like \"done\", and\n // it is the opposite — complete work resting on an assertion, still listed.\n const attested = packet.counts.attested === 0 ? \"\" : \" (confirmed on an agent's word, not a run — still listed)\";\n console.log(\n `${packet.feature} — ${packet.counts.open} open · ${packet.counts.done} done · ${packet.counts.attested} attested${attested}`,\n );\n header(packet, view);\n console.log(\"\");\n\n if (packet.units.length === 0) {\n console.log(\n packet.counts.attested > 0 || packet.counts.done > 0\n ? \" Nothing open. Every unit is recorded confirmed, or attested and waiting on a run.\"\n : \" Nothing open — this feature's delta, specs and contracts promise nothing yet.\",\n );\n }\n const capped = packet.service === null;\n for (const subject of new Set(packet.units.map((unit) => unit.subject))) {\n const units = packet.units.filter((unit) => unit.subject === subject);\n const shown = capped ? units.slice(0, PER_SERVICE_LIMIT) : units;\n console.log(` ${subject} — ${tally(units)}`);\n for (const group of grouped(shown)) {\n console.log(` ${group.heading}`);\n for (const unit of group.units) console.log(row(unit, packet.feature));\n }\n if (shown.length < units.length) {\n console.log(\n ` +${units.length - shown.length} more — \\`loam tasks ${packet.feature} --service ${subject}\\` lists every one`,\n );\n }\n console.log(\"\");\n }\n\n for (const line of frontierLines(packet, view)) console.log(line);\n for (const waiting of packet.waitingOn ?? []) {\n console.log(` waiting on ${waiting.subject}: ${waiting.claim} · ${waiting.id}, still open there`);\n }\n if (packet.units.length > 0) {\n console.log(\n \"\\n [step] is where a unit waits: describe → generate → implement, or attested. \" +\n \"`loam explain <word>` defines each of those, and frontier.\",\n );\n }\n console.log(\"\\n Review:\");\n for (const note of packet.review) console.log(` - ${note}`);\n}\n\n/**\n * The leaf, in full. The follow-up command is literal rather than a shape to\n * fill in, because the reader is usually a model cheap enough that \"the\n * appropriate verify invocation\" is a guess it will get wrong.\n */\nexport function renderNext(packet: WorkPacket, view: TasksView): void {\n const unit = packet.units[0];\n if (unit === undefined) {\n console.log(`${packet.feature} — nothing open (${packet.counts.done} done · ${packet.counts.attested} attested)`);\n header(packet, view);\n return;\n }\n console.log(`${packet.feature} — next: ${unit.id}`);\n console.log(` ${actionOf(unit, packet.feature)}`);\n // The lens only when the binding chose it: a reader who typed --service knows\n // which slice this is, and one who did not would otherwise be handed another\n // service's head with no word on why it is this one.\n if (packet.service !== null && !view.explicitLens) console.log(` ${lensLine(packet, view)}`);\n for (const warning of blindSpots(packet)) console.log(` ⚠ ${warning}`);\n const ungraded = ungradedScenario(packet, view, unit);\n if (ungraded !== undefined) console.log(` ⚠ ${ungraded}`);\n console.log(\"\");\n console.log(` [${unit.at}] ${unit.kind} [${unit.subject}]`);\n console.log(` ${unit.claim}`);\n const source = unit.source;\n if (source !== undefined) {\n console.log(` ${source.path}${source.line === undefined ? \"\" : `:${source.line}`}`);\n // Verbatim, never reflowed: these are the bytes the scenario digest was\n // taken over, and a test written from reworded criteria answers a claim\n // nobody made.\n if (\"lines\" in source) for (const body of source.lines) console.log(` ${body}`);\n }\n if (unit.dependsOn.length > 0) console.log(` depends on: ${unit.dependsOn.join(\", \")}`);\n console.log(`\\n done: ${unit.done.check}`);\n console.log(`\\n ${followUp(packet.feature, unit)}`);\n}\n\n/**\n * The caveat a scenario at `implement` needs when nobody looked for its\n * generated test: `implement` is also what a scenario reads when the stamps\n * could not be read, or belong to another repository, and handing a worker\n * \"make it pass\" for a test that was never generated sends them to write one by\n * hand — the paraphrase the generated suite exists to prevent.\n */\nfunction ungradedScenario(packet: WorkPacket, view: TasksView, unit: TaskUnit): string | undefined {\n if (unit.kind !== \"scenario.tested\" || unit.at !== \"implement\") return undefined;\n if (packet.stamps === \"read\" && unit.subject === view.bound) return undefined;\n if (unit.subject === view.bound) {\n return (\n \"whether this scenario's test was generated is unknown — this repository's generated suite could not be read; \" +\n `if loam gherkin ${packet.feature} has not run here, run it first`\n );\n }\n return (\n `whether this scenario's test was generated is unknown here — its suite lives in ${unit.subject}'s repository; ` +\n `run loam tasks there, or loam gherkin ${packet.feature} there first if it has not run`\n );\n}\n\n/**\n * The command that closes this unit.\n *\n * A `describe` unit is the one arm that is NOT a `loam verify --record`: there\n * is no claim to answer, because a requirement with no scenario asks no\n * question — the work is writing the Given/When/Then into the file named above,\n * and `loam validate --feature` is what grades that it landed. Pointing it at\n * `--record` would invite an answer to a question the checklist does not carry.\n */\nfunction followUp(feature: string, unit: TaskUnit): string {\n if (unit.at === \"describe\") return `loam validate --feature ${feature}`;\n if (unit.at === \"generate\") return `loam gherkin ${feature}`;\n if (unit.kind === \"scenario.tested\") {\n return `loam verify ${feature} --service ${unit.subject} --results report.json`;\n }\n return `loam verify ${feature} --record answers.json --service ${unit.subject}`;\n}\n\n/** What the packet could not look at — one sentence per document class. */\nfunction blindSpots(packet: WorkPacket): string[] {\n const out: string[] = [];\n if (packet.unreadable.architecture !== undefined) {\n out.push(\n `delta.likec4 does not parse (${packet.unreadable.architecture}) — no c4.calls unit could be derived, ` +\n \"so this list is short because loam could not look, not because the work is done\",\n );\n }\n const contracts = packet.unreadable.contracts;\n if (contracts !== undefined) {\n out.push(\n `contract delta unreadable for ${contracts.join(\", \")} — operations and messages are missing from this packet, ` +\n \"not absent from the feature\",\n );\n }\n return out;\n}\n"]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { configOrRefuse, emitJson, fail } from "../../core/envelope/json.js";
|
|
2
|
+
import { InvalidIdError, assertServiceId } from "../../core/kernel/ids/service.js";
|
|
3
|
+
import { livingServices } from "../../core/projection/arch-slice.js";
|
|
4
|
+
import { nearestIds } from "../../core/repo/entries.js";
|
|
5
|
+
import { missingFeatureMessage, resolveFeature } from "../../core/repo/repo.js";
|
|
6
|
+
import { workPacket } from "../../core/tasks/packet.js";
|
|
7
|
+
import { renderNext, renderPacket } from "./render.js";
|
|
8
|
+
export function registerTasks(program) {
|
|
9
|
+
program
|
|
10
|
+
.command("tasks")
|
|
11
|
+
.argument("<featureId>", "feature id, e.g. FEAT-101")
|
|
12
|
+
.description("What is still open on a feature, at which step, and what closes each unit — read-only")
|
|
13
|
+
.option("--service <id>", "narrow the packet to the units one service owns (a lens: no binding needed)")
|
|
14
|
+
.option("--next", "the frontier head alone — the single leaf to hand to a worker")
|
|
15
|
+
.option("--json", "emit the machine contract instead of the human view")
|
|
16
|
+
.action(async (featureId, opts) => {
|
|
17
|
+
const json = opts.json === true;
|
|
18
|
+
const config = await configOrRefuse(json);
|
|
19
|
+
if (config === null)
|
|
20
|
+
return;
|
|
21
|
+
// The id grammar first, and on the RAW argument, exactly as `loam delta`
|
|
22
|
+
// does: `--service ../../etc` reaches `featureSpecPaths` and reads from
|
|
23
|
+
// outside the feature directory. One grammar for the whole tool.
|
|
24
|
+
if (opts.service !== undefined) {
|
|
25
|
+
try {
|
|
26
|
+
assertServiceId(opts.service, "--service");
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
if (!(err instanceof InvalidIdError))
|
|
30
|
+
throw err;
|
|
31
|
+
fail(json, "invalid-option", err.message);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// "exclude", so an ARCHIVED feature gets the shared missing-feature
|
|
36
|
+
// message rather than a packet. This is refusal by honesty: archive merges
|
|
37
|
+
// a feature's operations into the living contracts, so a re-derived
|
|
38
|
+
// checklist over an archived feature mismatches BY CONSTRUCTION — every
|
|
39
|
+
// api.exposes claim it once made now reads as already-living and is never
|
|
40
|
+
// minted. A packet over that is not a short list, it is an invented one.
|
|
41
|
+
// `loam verify <id>` still reads the frozen record, and the message says so.
|
|
42
|
+
const feature = await resolveFeature(config.docsDir, featureId, "exclude");
|
|
43
|
+
if (!feature) {
|
|
44
|
+
fail(json, "unknown-target", await missingFeatureMessage(config.docsDir, featureId));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
// Only the flag's lens is passed. Without one, the packet narrows itself to
|
|
48
|
+
// the bound service when the feature touches it (`lensOf` in
|
|
49
|
+
// core/tasks/packet.ts says why, and why it is decided there), and
|
|
50
|
+
// `packet.service` is what reports the lens actually applied.
|
|
51
|
+
const lens = opts.service ?? null;
|
|
52
|
+
const packet = await workPacket({
|
|
53
|
+
docsDir: config.docsDir,
|
|
54
|
+
feature,
|
|
55
|
+
lens,
|
|
56
|
+
// `config.root`, never the cwd: loam.json discovery walks upward, and a
|
|
57
|
+
// run from `src/deep/` must read the same generated suite as one from
|
|
58
|
+
// the root. The same reasoning `loam gherkin` records for its writes.
|
|
59
|
+
binding: {
|
|
60
|
+
repoDir: config.root ?? process.cwd(),
|
|
61
|
+
...(config.service === undefined ? {} : { service: config.service }),
|
|
62
|
+
...(config.gherkinDir === undefined ? {} : { gherkinDir: config.gherkinDir }),
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
// The lens is checked AFTER the derivation, and on the packet's own
|
|
66
|
+
// service list, because that list is the feature's claim subjects — which
|
|
67
|
+
// includes a service the C4 delta introduces and no `specs/` directory
|
|
68
|
+
// names. Checking first would need a second LikeC4 parse of the same
|
|
69
|
+
// delta to learn the same answer. A typo must never be indistinguishable
|
|
70
|
+
// from a finished service: `--service paymnt-service` produces a
|
|
71
|
+
// perfectly plausible EMPTY packet, and an agent reads that as "nothing
|
|
72
|
+
// to do here". Only an EXPLICIT lens is checked: the bound service is
|
|
73
|
+
// applied only when the packet already lists it, so it cannot be a typo.
|
|
74
|
+
if (lens !== null && !packet.services.includes(lens)) {
|
|
75
|
+
const living = await livingServices(config.docsDir);
|
|
76
|
+
if (!living.includes(lens)) {
|
|
77
|
+
const near = nearestIds(lens, [...new Set([...packet.services, ...living])]);
|
|
78
|
+
fail(json, "unknown-target", `No service '${lens}': it is neither a services/${lens}/ in the docs repo nor a service ${feature.id} touches` +
|
|
79
|
+
(packet.services.length === 0 ? "" : ` (${packet.services.join(", ")})`) +
|
|
80
|
+
(near.length === 0 ? "." : ` — did you mean ${near.map((n) => `'${n}'`).join(" or ")}?`));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// A feeder that could not be read empties the packet, and an agent
|
|
85
|
+
// consuming this as a task list reads an empty packet as "nothing to do":
|
|
86
|
+
// the vacuously-green pattern `loam delta` guards against on the same
|
|
87
|
+
// three documents. The payload stays as informative as ever and `ok`
|
|
88
|
+
// stays true under --json — the command ran — and the exit code is what
|
|
89
|
+
// stops a pipeline from building on it. Set BEFORE the format fork: the
|
|
90
|
+
// guard is about the documents, not about how they are rendered.
|
|
91
|
+
const blind = Object.keys(packet.unreadable).length > 0;
|
|
92
|
+
if (blind)
|
|
93
|
+
process.exitCode = 1;
|
|
94
|
+
const shown = opts.next === true ? leaf(packet) : packet;
|
|
95
|
+
if (json) {
|
|
96
|
+
emitJson({ command: "tasks", ...shown });
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const view = { explicitLens: opts.service !== undefined, bound: config.service };
|
|
100
|
+
if (opts.next === true)
|
|
101
|
+
renderNext(shown, view);
|
|
102
|
+
else
|
|
103
|
+
renderPacket(shown, view);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The leaf packet: the same payload with `units` narrowed to the frontier head.
|
|
108
|
+
*
|
|
109
|
+
* Everything else is left whole on purpose — the counts, the frontier and the
|
|
110
|
+
* review notes are the context that stops a cheap model handed one unit from
|
|
111
|
+
* believing it is the whole job. An empty `units` when nothing is open is the
|
|
112
|
+
* honest answer and not an error: the feature's open work is done, or the
|
|
113
|
+
* record says why the packet cannot see it.
|
|
114
|
+
*/
|
|
115
|
+
function leaf(packet) {
|
|
116
|
+
const head = packet.frontier[0];
|
|
117
|
+
return { ...packet, units: packet.units.filter((unit) => unit.id === head) };
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/commands/tasks/tasks.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,UAAU,EAAmB,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQvD,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,QAAQ,CAAC,aAAa,EAAE,2BAA2B,CAAC;SACpD,WAAW,CAAC,uFAAuF,CAAC;SACpG,MAAM,CAAC,gBAAgB,EAAE,6EAA6E,CAAC;SACvG,MAAM,CAAC,QAAQ,EAAE,+DAA+D,CAAC;SACjF,MAAM,CAAC,QAAQ,EAAE,qDAAqD,CAAC;SACvE,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,IAAkB,EAAE,EAAE;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO;QAE5B,yEAAyE;QACzE,wEAAwE;QACxE,iEAAiE;QACjE,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,CAAC,GAAG,YAAY,cAAc,CAAC;oBAAE,MAAM,GAAG,CAAC;gBAChD,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC1C,OAAO;YACT,CAAC;QACH,CAAC;QAED,oEAAoE;QACpE,2EAA2E;QAC3E,oEAAoE;QACpE,wEAAwE;QACxE,0EAA0E;QAC1E,yEAAyE;QACzE,6EAA6E;QAC7E,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC3E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;YACrF,OAAO;QACT,CAAC;QAED,4EAA4E;QAC5E,6DAA6D;QAC7D,mEAAmE;QACnE,8DAA8D;QAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;YAC9B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO;YACP,IAAI;YACJ,wEAAwE;YACxE,sEAAsE;YACtE,sEAAsE;YACtE,OAAO,EAAE;gBACP,OAAO,EAAE,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE;gBACrC,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpE,GAAG,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;aAC9E;SACF,CAAC,CAAC;QAEH,oEAAoE;QACpE,0EAA0E;QAC1E,uEAAuE;QACvE,qEAAqE;QACrE,yEAAyE;QACzE,iEAAiE;QACjE,wEAAwE;QACxE,sEAAsE;QACtE,yEAAyE;QACzE,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACpD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7E,IAAI,CACF,IAAI,EACJ,gBAAgB,EAChB,eAAe,IAAI,+BAA+B,IAAI,oCAAoC,OAAO,CAAC,EAAE,UAAU;oBAC5G,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;oBACxE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAC3F,CAAC;gBACF,OAAO;YACT,CAAC;QACH,CAAC;QAED,mEAAmE;QACnE,0EAA0E;QAC1E,sEAAsE;QACtE,qEAAqE;QACrE,wEAAwE;QACxE,wEAAwE;QACxE,iEAAiE;QACjE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACxD,IAAI,KAAK;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QAEhC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACzD,IAAI,IAAI,EAAE,CAAC;YACT,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QACjF,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;;YAC3C,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,IAAI,CAAC,MAAkB;IAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAChC,OAAO,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;AAC/E,CAAC","sourcesContent":["/**\n * `loam tasks` — the third rendering of one ledger, and a pure read.\n *\n * `loam verify` answers \"answered by whom\". `loam status` answers \"which\n * artifact is at which rung\". This answers the question an implementer actually\n * holds: what is still open, at which step, and what closes it. Nothing is\n * written, nothing is cached, and there is no state that says a unit is\n * finished — done is \"the unit no longer appears\", so the list cannot be\n * falsified by editing a checkbox. Everything in it re-derives from the tree, so\n * an orchestrator can ask again and compare rather than trusting a report.\n *\n * THE DOCS-REPO GATE IS DELIBERATELY ABSENT, following `loam delta` rather than\n * `loam verify`. This command is delta's sibling — a projection of ONE feature's\n * own documents — and its first act is `resolveFeature`, whose enumeration\n * carries the docs-repo precondition itself. Adding `docsRepoReady(json, …,\n * \"services\")` here would also refuse a features-only docs repo that `delta`\n * reads perfectly well today, which would be a new gate wearing the clothes of a\n * new command.\n */\nimport type { Command } from \"commander\";\nimport { configOrRefuse, emitJson, fail } from \"../../core/envelope/json.js\";\nimport { InvalidIdError, assertServiceId } from \"../../core/kernel/ids/service.js\";\nimport { livingServices } from \"../../core/projection/arch-slice.js\";\nimport { nearestIds } from \"../../core/repo/entries.js\";\nimport { missingFeatureMessage, resolveFeature } from \"../../core/repo/repo.js\";\nimport { workPacket, type WorkPacket } from \"../../core/tasks/packet.js\";\nimport { renderNext, renderPacket } from \"./render.js\";\n\ninterface TasksOptions {\n service?: string;\n next?: boolean;\n json?: boolean;\n}\n\nexport function registerTasks(program: Command): void {\n program\n .command(\"tasks\")\n .argument(\"<featureId>\", \"feature id, e.g. FEAT-101\")\n .description(\"What is still open on a feature, at which step, and what closes each unit — read-only\")\n .option(\"--service <id>\", \"narrow the packet to the units one service owns (a lens: no binding needed)\")\n .option(\"--next\", \"the frontier head alone — the single leaf to hand to a worker\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .action(async (featureId: string, opts: TasksOptions) => {\n const json = opts.json === true;\n const config = await configOrRefuse(json);\n if (config === null) return;\n\n // The id grammar first, and on the RAW argument, exactly as `loam delta`\n // does: `--service ../../etc` reaches `featureSpecPaths` and reads from\n // outside the feature directory. One grammar for the whole tool.\n if (opts.service !== undefined) {\n try {\n assertServiceId(opts.service, \"--service\");\n } catch (err) {\n if (!(err instanceof InvalidIdError)) throw err;\n fail(json, \"invalid-option\", err.message);\n return;\n }\n }\n\n // \"exclude\", so an ARCHIVED feature gets the shared missing-feature\n // message rather than a packet. This is refusal by honesty: archive merges\n // a feature's operations into the living contracts, so a re-derived\n // checklist over an archived feature mismatches BY CONSTRUCTION — every\n // api.exposes claim it once made now reads as already-living and is never\n // minted. A packet over that is not a short list, it is an invented one.\n // `loam verify <id>` still reads the frozen record, and the message says so.\n const feature = await resolveFeature(config.docsDir, featureId, \"exclude\");\n if (!feature) {\n fail(json, \"unknown-target\", await missingFeatureMessage(config.docsDir, featureId));\n return;\n }\n\n // Only the flag's lens is passed. Without one, the packet narrows itself to\n // the bound service when the feature touches it (`lensOf` in\n // core/tasks/packet.ts says why, and why it is decided there), and\n // `packet.service` is what reports the lens actually applied.\n const lens = opts.service ?? null;\n const packet = await workPacket({\n docsDir: config.docsDir,\n feature,\n lens,\n // `config.root`, never the cwd: loam.json discovery walks upward, and a\n // run from `src/deep/` must read the same generated suite as one from\n // the root. The same reasoning `loam gherkin` records for its writes.\n binding: {\n repoDir: config.root ?? process.cwd(),\n ...(config.service === undefined ? {} : { service: config.service }),\n ...(config.gherkinDir === undefined ? {} : { gherkinDir: config.gherkinDir }),\n },\n });\n\n // The lens is checked AFTER the derivation, and on the packet's own\n // service list, because that list is the feature's claim subjects — which\n // includes a service the C4 delta introduces and no `specs/` directory\n // names. Checking first would need a second LikeC4 parse of the same\n // delta to learn the same answer. A typo must never be indistinguishable\n // from a finished service: `--service paymnt-service` produces a\n // perfectly plausible EMPTY packet, and an agent reads that as \"nothing\n // to do here\". Only an EXPLICIT lens is checked: the bound service is\n // applied only when the packet already lists it, so it cannot be a typo.\n if (lens !== null && !packet.services.includes(lens)) {\n const living = await livingServices(config.docsDir);\n if (!living.includes(lens)) {\n const near = nearestIds(lens, [...new Set([...packet.services, ...living])]);\n fail(\n json,\n \"unknown-target\",\n `No service '${lens}': it is neither a services/${lens}/ in the docs repo nor a service ${feature.id} touches` +\n (packet.services.length === 0 ? \"\" : ` (${packet.services.join(\", \")})`) +\n (near.length === 0 ? \".\" : ` — did you mean ${near.map((n) => `'${n}'`).join(\" or \")}?`),\n );\n return;\n }\n }\n\n // A feeder that could not be read empties the packet, and an agent\n // consuming this as a task list reads an empty packet as \"nothing to do\":\n // the vacuously-green pattern `loam delta` guards against on the same\n // three documents. The payload stays as informative as ever and `ok`\n // stays true under --json — the command ran — and the exit code is what\n // stops a pipeline from building on it. Set BEFORE the format fork: the\n // guard is about the documents, not about how they are rendered.\n const blind = Object.keys(packet.unreadable).length > 0;\n if (blind) process.exitCode = 1;\n\n const shown = opts.next === true ? leaf(packet) : packet;\n if (json) {\n emitJson({ command: \"tasks\", ...shown });\n return;\n }\n const view = { explicitLens: opts.service !== undefined, bound: config.service };\n if (opts.next === true) renderNext(shown, view);\n else renderPacket(shown, view);\n });\n}\n\n/**\n * The leaf packet: the same payload with `units` narrowed to the frontier head.\n *\n * Everything else is left whole on purpose — the counts, the frontier and the\n * review notes are the context that stops a cheap model handed one unit from\n * believing it is the whole job. An empty `units` when nothing is open is the\n * honest answer and not an error: the feature's open work is done, or the\n * record says why the packet cannot see it.\n */\nfunction leaf(packet: WorkPacket): WorkPacket {\n const head = packet.frontier[0];\n return { ...packet, units: packet.units.filter((unit) => unit.id === head) };\n}\n"]}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The snapshot manifest, validated before a single byte is written back.
|
|
3
|
+
*
|
|
4
|
+
* `unarchive` says "I put your docs back", and that sentence must never be
|
|
5
|
+
* sayable over a pre-image edited in the archived feature directory since. Each
|
|
6
|
+
* entry carries the digest of what archive WROTE and the digest of what will be
|
|
7
|
+
* RESTORED, and this is where both are checked — version, timestamp, feature
|
|
8
|
+
* name, duplicate paths and all — so the restore below it can assume the file
|
|
9
|
+
* describes the archive it claims to.
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync, lstatSync } from "node:fs";
|
|
12
|
+
import { readFile } from "node:fs/promises";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { repoPath } from "../../core/envelope/json.js";
|
|
15
|
+
import { resolveInside, resolvePortableFileInside } from "../../core/kernel/path-safety.js";
|
|
16
|
+
import { isRecord } from "../../core/kernel/records.js";
|
|
17
|
+
import { isReadableSnapshotVersion, keysServiceRows, preImageRel, SNAPSHOT_DIR, SNAPSHOT_MANIFEST, } from "../../core/staging/snapshot/manifest.js";
|
|
18
|
+
/**
|
|
19
|
+
* The snapshot manifest, or null when there is nothing this command can honour —
|
|
20
|
+
* absent, unreadable, or a layout version it would have to guess at. All three are
|
|
21
|
+
* the same answer to the caller: this feature cannot be unarchived automatically.
|
|
22
|
+
*/
|
|
23
|
+
export async function readManifest(request) {
|
|
24
|
+
const { featureDir, docsDir, featureId, dirName } = request;
|
|
25
|
+
try {
|
|
26
|
+
const path = resolveInside(featureDir, join(SNAPSHOT_DIR, SNAPSHOT_MANIFEST), "snapshot manifest path");
|
|
27
|
+
if (!existsSync(path))
|
|
28
|
+
return null;
|
|
29
|
+
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
30
|
+
if (!isRecord(parsed))
|
|
31
|
+
return null;
|
|
32
|
+
// Version 4 is what archive writes; versions 3 and 2 are read forever under
|
|
33
|
+
// their own rules — 3 keyed but storing pre-images under their living
|
|
34
|
+
// names, 2 by literal path — because snapshots an older loam wrote already
|
|
35
|
+
// sit in archived features and travel with them across loam upgrades.
|
|
36
|
+
// Version 1 stays refused: it records nothing about its restore source.
|
|
37
|
+
const version = parsed.version;
|
|
38
|
+
if (!isReadableSnapshotVersion(version))
|
|
39
|
+
return null;
|
|
40
|
+
if (parsed.feature !== featureId || parsed.dirName !== dirName)
|
|
41
|
+
return null;
|
|
42
|
+
if (typeof parsed.archivedAt !== "string" || !isCanonicalIsoDate(parsed.archivedAt))
|
|
43
|
+
return null;
|
|
44
|
+
if (!Array.isArray(parsed.files))
|
|
45
|
+
return null;
|
|
46
|
+
const seen = new Set();
|
|
47
|
+
// Where the archived feature sits, as the rows spell paths (`repoPath`).
|
|
48
|
+
const featureRel = repoPath(docsDir, featureDir);
|
|
49
|
+
const files = [];
|
|
50
|
+
for (const raw of parsed.files) {
|
|
51
|
+
if (!isRecord(raw))
|
|
52
|
+
return null;
|
|
53
|
+
if (typeof raw.path !== "string" || typeof raw.existed !== "boolean")
|
|
54
|
+
return null;
|
|
55
|
+
if (typeof raw.after !== "string" || !/^[0-9a-f]{64}$/.test(raw.after))
|
|
56
|
+
return null;
|
|
57
|
+
// A manifest that claims a pre-image must say what it should hash to, and
|
|
58
|
+
// one that claims none must not. Either way it is a shape question, so it
|
|
59
|
+
// is answered here with the rest of them; whether the bytes MATCH is a
|
|
60
|
+
// different answer with its own code (`snapshot-corrupt`).
|
|
61
|
+
if (raw.existed ? typeof raw.before !== "string" || !/^[0-9a-f]{64}$/.test(raw.before) : raw.before !== null) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const before = raw.existed ? raw.before : null;
|
|
65
|
+
if (seen.has(raw.path))
|
|
66
|
+
return null;
|
|
67
|
+
seen.add(raw.path);
|
|
68
|
+
// The keyed shape rule (versions 3 and 4), exact in both directions: a
|
|
69
|
+
// `services/` row carries its (service, artifact) key — that key is what
|
|
70
|
+
// version 3 introduced, and a row without one is not a manifest this
|
|
71
|
+
// loam wrote — while a row anywhere else carries none, because nothing
|
|
72
|
+
// outside `services/` moves. Version-2 rows never carry the fields and
|
|
73
|
+
// are not asked to.
|
|
74
|
+
const key = readServiceKey(version, raw);
|
|
75
|
+
if (key === undefined)
|
|
76
|
+
return null;
|
|
77
|
+
// Where the file lives NOW. A re-keyed row resolves through the current
|
|
78
|
+
// enumeration — the whole point of the bump: the bytes land wherever the
|
|
79
|
+
// service lives today, not where it lived on the day of the archive. An
|
|
80
|
+
// id the enumeration does not answer falls back to the literal path
|
|
81
|
+
// (an absent service restores as a create, exactly as before).
|
|
82
|
+
let targetRel = raw.path;
|
|
83
|
+
if (key !== null) {
|
|
84
|
+
const current = request.serviceDirOf(key.service);
|
|
85
|
+
if (current !== null)
|
|
86
|
+
targetRel = `${current}/${key.artifact}`;
|
|
87
|
+
}
|
|
88
|
+
// The realpath test stays on this side, and it is not negotiable: this
|
|
89
|
+
// path is WRITTEN through. A symlink that leaves the repo is
|
|
90
|
+
// indistinguishable, lexically, from a service directory the operator
|
|
91
|
+
// mounted on purpose — `escape/owned.txt` and `services/<svc>/spec.md`
|
|
92
|
+
// are both "inside docsDir" until something resolves them — so the only
|
|
93
|
+
// check that can refuse the first is the one that also refuses the
|
|
94
|
+
// second. Restoring is the write; `staging.ts` only reads and compares a
|
|
95
|
+
// digest, which is why its resolution of this same field can be lexical
|
|
96
|
+
// and this one cannot.
|
|
97
|
+
//
|
|
98
|
+
// A row of the feature's OWN documents — the ones archive relinked for
|
|
99
|
+
// its move, recorded inside `features/archive/<FEAT>/` — is held to the
|
|
100
|
+
// same test with the feature directory as the root, which is where its
|
|
101
|
+
// pre-image below is anchored too: that directory is the thing this
|
|
102
|
+
// command restores and moves back. Anchored at the docs root instead, a
|
|
103
|
+
// feature mounted by symlink from outside the repo — a layout every walk
|
|
104
|
+
// follows — resolved outside it and was refused as `snapshot-missing`,
|
|
105
|
+
// over rows inside the very directory being restored. A row that leaves
|
|
106
|
+
// the feature is still refused.
|
|
107
|
+
const inFeature = raw.path.startsWith(`${featureRel}/`) ? raw.path.slice(featureRel.length + 1) : null;
|
|
108
|
+
const target = inFeature === null
|
|
109
|
+
? resolvePortableFileInside(docsDir, targetRel, `snapshot path '${raw.path}'`)
|
|
110
|
+
: resolvePortableFileInside(featureDir, inFeature, `snapshot path '${raw.path}'`);
|
|
111
|
+
let snapshot = null;
|
|
112
|
+
// Where THIS manifest's layout stores the pre-image — suffixed from
|
|
113
|
+
// version 4 on, under the living name before it (`preImageRel`).
|
|
114
|
+
const snapshotRel = `${SNAPSHOT_DIR}/files/${preImageRel(version, raw.path)}`;
|
|
115
|
+
if (raw.existed) {
|
|
116
|
+
// Resolve from the feature directory, which always exists. The `files/`
|
|
117
|
+
// directory legitimately does not exist when every archive write was a
|
|
118
|
+
// creation; anchoring here permits that case while still inspecting an
|
|
119
|
+
// existing `files` component for symlink escape.
|
|
120
|
+
snapshot = resolvePortableFileInside(featureDir, snapshotRel, `snapshot pre-image '${raw.path}'`);
|
|
121
|
+
// Archive writes plain files. A missing pre-image or a symlink (even an
|
|
122
|
+
// internally-contained one) is not the byte snapshot this manifest
|
|
123
|
+
// claims, so refuse before any destination is staged.
|
|
124
|
+
if (!existsSync(snapshot) || !lstatSync(snapshot).isFile())
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const unexpected = resolvePortableFileInside(featureDir, snapshotRel, `snapshot pre-image '${raw.path}'`);
|
|
129
|
+
if (existsSync(unexpected))
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
files.push({ path: raw.path, existed: raw.existed, after: raw.after, before, target, snapshot });
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
// The version as WRITTEN, not as preferred: a caller looking at a
|
|
136
|
+
// validated manifest deserves to know which rules it was read under.
|
|
137
|
+
version,
|
|
138
|
+
feature: featureId,
|
|
139
|
+
dirName,
|
|
140
|
+
archivedAt: parsed.archivedAt,
|
|
141
|
+
files,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The (service, artifact) key of one manifest row, under its version's shape
|
|
150
|
+
* rule. Three answers: the key; null when the row legitimately carries none (a
|
|
151
|
+
* non-`services/` row, or any version-2 row — the key postdates version 2);
|
|
152
|
+
* undefined when the row breaks the rule and the manifest must be refused
|
|
153
|
+
* whole, because a half-keyed or wrongly-keyed row is not a record this loam
|
|
154
|
+
* wrote and nothing can say what else in the file to distrust.
|
|
155
|
+
*/
|
|
156
|
+
function readServiceKey(version, raw) {
|
|
157
|
+
if (!keysServiceRows(version))
|
|
158
|
+
return null;
|
|
159
|
+
const under = typeof raw.path === "string" && raw.path.startsWith("services/");
|
|
160
|
+
if (!under)
|
|
161
|
+
return raw.service === undefined && raw.artifact === undefined ? null : undefined;
|
|
162
|
+
// The id is a lookup key into the enumeration and the artifact is joined
|
|
163
|
+
// under the resolved directory, so the id must be a single path segment; the
|
|
164
|
+
// artifact's own containment is `resolvePortableFileInside`'s question.
|
|
165
|
+
if (typeof raw.service !== "string" || raw.service.length === 0 || raw.service.includes("/"))
|
|
166
|
+
return undefined;
|
|
167
|
+
if (typeof raw.artifact !== "string" || raw.artifact.length === 0)
|
|
168
|
+
return undefined;
|
|
169
|
+
return { service: raw.service, artifact: raw.artifact };
|
|
170
|
+
}
|
|
171
|
+
export function isCanonicalIsoDate(value) {
|
|
172
|
+
const millis = Date.parse(value);
|
|
173
|
+
return Number.isFinite(millis) && new Date(millis).toISOString() === value;
|
|
174
|
+
}
|
|
175
|
+
/** Remove `dir` and each empty ancestor, stopping short of `stopAt`. Best effort. */
|
|
176
|
+
//# sourceMappingURL=manifest.js.map
|