@ybotok/loam 0.2.0-alpha.6 → 0.2.0-alpha.9
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 +1477 -1
- package/COMPARISON.md +91 -3
- package/CONTRIBUTING.md +37 -0
- package/MIGRATING-from-OpenSpec.md +40 -22
- package/QUICKSTART.md +181 -9
- package/README.md +256 -57
- package/ROADMAP.md +108 -11
- package/SCHEMA.md +721 -130
- package/WORKFLOW.md +272 -62
- package/dist/cli.js +26 -8
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt/adopt.js +5 -10
- package/dist/commands/adopt/adopt.js.map +1 -1
- package/dist/commands/archive/archive.js +15 -18
- package/dist/commands/archive/archive.js.map +1 -1
- package/dist/commands/archive/plan/contracts/asyncapi.js +27 -41
- package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -1
- 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 +25 -42
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -1
- package/dist/commands/archive/plan/contracts/verdict-lines.js +41 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +3 -7
- package/dist/commands/archive/plan/gate.js.map +1 -1
- package/dist/commands/archive/plan/landscape.js +4 -4
- package/dist/commands/archive/plan/landscape.js.map +1 -1
- package/dist/commands/archive/plan/refusal.js +8 -18
- package/dist/commands/archive/plan/refusal.js.map +1 -1
- package/dist/commands/archive/plan/specs.js +134 -25
- package/dist/commands/archive/plan/specs.js.map +1 -1
- package/dist/commands/archive/plan/state.js +1 -0
- package/dist/commands/archive/plan/state.js.map +1 -1
- package/dist/commands/archive/run.js +82 -33
- package/dist/commands/archive/run.js.map +1 -1
- package/dist/commands/archive/shipped.js +49 -0
- package/dist/commands/archive/shipped.js.map +1 -0
- package/dist/commands/context/context.js +4 -7
- package/dist/commands/context/context.js.map +1 -1
- package/dist/commands/context/print.js +2 -2
- package/dist/commands/context/print.js.map +1 -1
- package/dist/commands/delta/delta.js +44 -12
- package/dist/commands/delta/delta.js.map +1 -1
- package/dist/commands/delta/print.js +1 -1
- package/dist/commands/delta/print.js.map +1 -1
- package/dist/commands/dependencies.js +3 -7
- package/dist/commands/dependencies.js.map +1 -1
- package/dist/commands/diff/diff.js +20 -27
- package/dist/commands/diff/diff.js.map +1 -1
- package/dist/commands/explore.js +4 -8
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/gate/gate.js +45 -8
- package/dist/commands/gate/gate.js.map +1 -1
- package/dist/commands/gate/print.js +15 -3
- package/dist/commands/gate/print.js.map +1 -1
- package/dist/commands/gherkin/commit.js +13 -54
- package/dist/commands/gherkin/commit.js.map +1 -1
- package/dist/commands/gherkin/gherkin.js +36 -20
- package/dist/commands/gherkin/gherkin.js.map +1 -1
- package/dist/commands/gherkin/reconcile.js +10 -13
- package/dist/commands/gherkin/reconcile.js.map +1 -1
- package/dist/commands/init/first-hour.js +44 -0
- package/dist/commands/init/first-hour.js.map +1 -1
- package/dist/commands/init/init.js +18 -22
- package/dist/commands/init/init.js.map +1 -1
- package/dist/commands/list/campaign/campaign.js +4 -6
- package/dist/commands/list/campaign/campaign.js.map +1 -1
- package/dist/commands/list/json.js +0 -4
- package/dist/commands/list/json.js.map +1 -1
- package/dist/commands/list/list.js +38 -23
- package/dist/commands/list/list.js.map +1 -1
- package/dist/commands/list/print.js +38 -6
- package/dist/commands/list/print.js.map +1 -1
- 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 +28 -33
- package/dist/commands/list/views.js.map +1 -1
- package/dist/commands/mcp/dispatch.js +91 -36
- package/dist/commands/mcp/dispatch.js.map +1 -1
- package/dist/commands/mcp/mcp.js +56 -15
- package/dist/commands/mcp/mcp.js.map +1 -1
- package/dist/commands/mcp/serve.js.map +1 -1
- package/dist/commands/migrate-openspec/materialize/active.js +27 -22
- package/dist/commands/migrate-openspec/materialize/active.js.map +1 -1
- package/dist/commands/migrate-openspec/materialize/stage.js +4 -3
- package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -1
- package/dist/commands/migrate-openspec/materialize/target.js +2 -2
- package/dist/commands/migrate-openspec/materialize/target.js.map +1 -1
- package/dist/commands/migrate-openspec/openspec/decisions.js +9 -14
- package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -1
- package/dist/commands/migrate-openspec/openspec/error.js +7 -8
- package/dist/commands/migrate-openspec/openspec/error.js.map +1 -1
- package/dist/commands/migrate-openspec/openspec/mapping.js +1 -9
- package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -1
- package/dist/commands/migrate-openspec/openspec/paths.js +3 -6
- package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -1
- 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 +8 -22
- package/dist/commands/new/commit.js.map +1 -1
- package/dist/commands/new/modifies.js +206 -0
- package/dist/commands/new/modifies.js.map +1 -0
- package/dist/commands/new/new.js +59 -14
- package/dist/commands/new/new.js.map +1 -1
- package/dist/commands/new/templates.js +48 -124
- package/dist/commands/new/templates.js.map +1 -1
- package/dist/commands/open.js +3 -7
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/policy/gate.js +27 -0
- package/dist/commands/policy/gate.js.map +1 -1
- package/dist/commands/rebase/plan.js +2 -2
- package/dist/commands/rebase/plan.js.map +1 -1
- package/dist/commands/rebase/rebase.js +60 -35
- package/dist/commands/rebase/rebase.js.map +1 -1
- package/dist/commands/seed/commit.js +55 -26
- package/dist/commands/seed/commit.js.map +1 -1
- package/dist/commands/seed/plan.js +64 -13
- package/dist/commands/seed/plan.js.map +1 -1
- package/dist/commands/seed/seed.js +6 -9
- package/dist/commands/seed/seed.js.map +1 -1
- package/dist/commands/show/show.js +3 -7
- package/dist/commands/show/show.js.map +1 -1
- package/dist/commands/status/print.js +13 -4
- package/dist/commands/status/print.js.map +1 -1
- package/dist/commands/status/status.js +3 -7
- package/dist/commands/status/status.js.map +1 -1
- package/dist/commands/steps/steps.js +3 -7
- package/dist/commands/steps/steps.js.map +1 -1
- package/dist/commands/subsystem/edit.js +7 -7
- package/dist/commands/subsystem/edit.js.map +1 -1
- package/dist/commands/subsystem/move.js +60 -25
- package/dist/commands/subsystem/move.js.map +1 -1
- package/dist/commands/subsystem/query.js +2 -4
- package/dist/commands/subsystem/query.js.map +1 -1
- package/dist/commands/subsystem/subsystem.js +4 -7
- package/dist/commands/subsystem/subsystem.js.map +1 -1
- package/dist/commands/subsystem/sync.js +141 -71
- package/dist/commands/subsystem/sync.js.map +1 -1
- package/dist/commands/subsystem/txn/report.js +55 -5
- package/dist/commands/subsystem/txn/report.js.map +1 -1
- package/dist/commands/subsystem/txn/txn.js +121 -45
- package/dist/commands/subsystem/txn/txn.js.map +1 -1
- package/dist/commands/subsystem/txn/views.js +82 -12
- package/dist/commands/subsystem/txn/views.js.map +1 -1
- package/dist/commands/tasks/render.js +116 -0
- package/dist/commands/tasks/render.js.map +1 -0
- package/dist/commands/tasks/tasks.js +113 -0
- package/dist/commands/tasks/tasks.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +6 -9
- package/dist/commands/unarchive/manifest.js.map +1 -1
- package/dist/commands/unarchive/restore.js +17 -28
- package/dist/commands/unarchive/restore.js.map +1 -1
- package/dist/commands/unarchive/unarchive.js +22 -30
- package/dist/commands/unarchive/unarchive.js.map +1 -1
- package/dist/commands/validate/arch-coverage.js +6 -15
- package/dist/commands/validate/arch-coverage.js.map +1 -1
- package/dist/commands/validate/checks/fleet-shape.js +4 -49
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -1
- package/dist/commands/validate/checks/health-deps.js +9 -6
- package/dist/commands/validate/checks/health-deps.js.map +1 -1
- package/dist/commands/validate/checks/requirements.js +18 -8
- package/dist/commands/validate/checks/requirements.js.map +1 -1
- package/dist/commands/validate/checks/sources.js +6 -2
- package/dist/commands/validate/checks/sources.js.map +1 -1
- package/dist/commands/validate/feature.js +23 -19
- package/dist/commands/validate/feature.js.map +1 -1
- package/dist/commands/validate/fleet/census.js +26 -3
- package/dist/commands/validate/fleet/census.js.map +1 -1
- package/dist/commands/validate/fleet/landscape.js +35 -32
- package/dist/commands/validate/fleet/landscape.js.map +1 -1
- package/dist/commands/validate/fleet/map/attest.js +7 -12
- package/dist/commands/validate/fleet/map/attest.js.map +1 -1
- package/dist/commands/validate/fleet/map/bindings.js +16 -5
- package/dist/commands/validate/fleet/map/bindings.js.map +1 -1
- package/dist/commands/validate/fleet/map/consumers.js +43 -122
- package/dist/commands/validate/fleet/map/consumers.js.map +1 -1
- package/dist/commands/validate/fleet/map/usecases.js +5 -11
- package/dist/commands/validate/fleet/map/usecases.js.map +1 -1
- package/dist/commands/validate/fleet/obligations.js +1 -5
- package/dist/commands/validate/fleet/obligations.js.map +1 -1
- package/dist/commands/validate/fleet/scorecard/print.js +5 -1
- package/dist/commands/validate/fleet/scorecard/print.js.map +1 -1
- package/dist/commands/validate/fleet/scorecard/scorecard.js +17 -11
- package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -1
- package/dist/commands/validate/fleet/usecases/usecases.js +6 -4
- package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -1
- package/dist/commands/validate/fleet/views/fleet-project.js +1 -1
- package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -1
- package/dist/commands/validate/fleet/views/ids.js +33 -7
- package/dist/commands/validate/fleet/views/ids.js.map +1 -1
- package/dist/commands/validate/fleet/views/root-documents.js +17 -35
- package/dist/commands/validate/fleet/views/root-documents.js.map +1 -1
- package/dist/commands/validate/fleet/views/stale.js +31 -14
- package/dist/commands/validate/fleet/views/stale.js.map +1 -1
- package/dist/commands/validate/links/corpus.js +1 -4
- package/dist/commands/validate/links/corpus.js.map +1 -1
- package/dist/commands/validate/links/glossary.js.map +1 -1
- package/dist/commands/validate/report.js +5 -4
- package/dist/commands/validate/report.js.map +1 -1
- package/dist/commands/validate/scope.js +113 -0
- package/dist/commands/validate/scope.js.map +1 -0
- package/dist/commands/validate/service/api.js +16 -104
- package/dist/commands/validate/service/api.js.map +1 -1
- 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 +1 -1
- package/dist/commands/validate/service/events/events.js.map +1 -1
- package/dist/commands/validate/service/events/message-producers.js +1 -1
- package/dist/commands/validate/service/events/message-producers.js.map +1 -1
- package/dist/commands/validate/service/evidence-pins.js +56 -10
- package/dist/commands/validate/service/evidence-pins.js.map +1 -1
- package/dist/commands/validate/service/service.js +16 -26
- package/dist/commands/validate/service/service.js.map +1 -1
- package/dist/commands/validate/service/specs.js +31 -38
- package/dist/commands/validate/service/specs.js.map +1 -1
- package/dist/commands/validate/service/spine.js +8 -11
- package/dist/commands/validate/service/spine.js.map +1 -1
- package/dist/commands/validate/service/usecases/usecases.js +3 -3
- package/dist/commands/validate/service/usecases/usecases.js.map +1 -1
- package/dist/commands/validate/validate.js +44 -26
- package/dist/commands/validate/validate.js.map +1 -1
- package/dist/commands/verify/cross/diff.js +2 -6
- package/dist/commands/verify/cross/diff.js.map +1 -1
- package/dist/commands/verify/evidence/contract.js +1 -1
- package/dist/commands/verify/evidence/contract.js.map +1 -1
- package/dist/commands/verify/evidence/read.js +12 -3
- package/dist/commands/verify/evidence/read.js.map +1 -1
- package/dist/commands/verify/frozen.js +45 -23
- package/dist/commands/verify/frozen.js.map +1 -1
- package/dist/commands/verify/record.js +69 -17
- package/dist/commands/verify/record.js.map +1 -1
- package/dist/commands/verify/report.js +27 -44
- package/dist/commands/verify/report.js.map +1 -1
- package/dist/commands/verify/results.js +112 -30
- package/dist/commands/verify/results.js.map +1 -1
- package/dist/commands/verify/verify.js +54 -51
- package/dist/commands/verify/verify.js.map +1 -1
- package/dist/commands/vouch/pack/pack.js +2 -2
- package/dist/commands/vouch/pack/pack.js.map +1 -1
- package/dist/commands/vouch/pack/print.js +1 -6
- package/dist/commands/vouch/pack/print.js.map +1 -1
- package/dist/commands/vouch/pack/sections.js +1 -2
- package/dist/commands/vouch/pack/sections.js.map +1 -1
- package/dist/commands/vouch/run.js +26 -81
- package/dist/commands/vouch/run.js.map +1 -1
- package/dist/commands/vouch/sample/plan.js +20 -34
- package/dist/commands/vouch/sample/plan.js.map +1 -1
- package/dist/commands/vouch/vet/verify.js +39 -7
- package/dist/commands/vouch/vet/verify.js.map +1 -1
- package/dist/commands/vouch/vouch.js +10 -17
- package/dist/commands/vouch/vouch.js.map +1 -1
- package/dist/core/agent/agents-md/command-map.js +57 -102
- package/dist/core/agent/agents-md/command-map.js.map +1 -1
- package/dist/core/agent/agents-md/map/explain.js +4 -3
- package/dist/core/agent/agents-md/map/explain.js.map +1 -1
- package/dist/core/agent/agents-md/map/lenses/context.js +4 -3
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -1
- package/dist/core/agent/agents-md/map/lenses/diff.js +33 -20
- package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -1
- package/dist/core/agent/agents-md/map/lenses/gate.js +13 -5
- package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -1
- package/dist/core/agent/agents-md/map/mcp.js +10 -7
- package/dist/core/agent/agents-md/map/mcp.js.map +1 -1
- package/dist/core/agent/agents-md/map/status.js +9 -3
- package/dist/core/agent/agents-md/map/status.js.map +1 -1
- package/dist/core/agent/agents-md/map/subsystem.js +31 -17
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -1
- package/dist/core/agent/agents-md/map/usecases.js +24 -6
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -1
- package/dist/core/agent/agents-md/refusals.js +37 -21
- package/dist/core/agent/agents-md/refusals.js.map +1 -1
- package/dist/core/agent/agents-md.js +25 -10
- package/dist/core/agent/agents-md.js.map +1 -1
- package/dist/core/agent/agents-stamp.js +10 -0
- package/dist/core/agent/agents-stamp.js.map +1 -1
- package/dist/core/agent/scaffold.js +10 -15
- package/dist/core/agent/scaffold.js.map +1 -1
- package/dist/core/agent/tools/dialects.js +1 -0
- package/dist/core/agent/tools/dialects.js.map +1 -1
- package/dist/core/agent/tools/registry.js +41 -76
- package/dist/core/agent/tools/registry.js.map +1 -1
- package/dist/core/agent/workflows/adopt.js +5 -3
- package/dist/core/agent/workflows/adopt.js.map +1 -1
- package/dist/core/agent/workflows/check.js +25 -22
- package/dist/core/agent/workflows/check.js.map +1 -1
- package/dist/core/agent/workflows/closing.js +54 -21
- package/dist/core/agent/workflows/closing.js.map +1 -1
- package/dist/core/agent/workflows/feature.js +79 -11
- package/dist/core/agent/workflows/feature.js.map +1 -1
- package/dist/core/agent/workflows/implement.js +91 -13
- package/dist/core/agent/workflows/implement.js.map +1 -1
- package/dist/core/agent/workflows/reference/authoring.js +3 -1
- package/dist/core/agent/workflows/reference/authoring.js.map +1 -1
- package/dist/core/agent/workflows/reference/codes.js +8 -6
- package/dist/core/agent/workflows/reference/codes.js.map +1 -1
- package/dist/core/agent/workflows/reference/done-check.js +37 -15
- package/dist/core/agent/workflows/reference/done-check.js.map +1 -1
- package/dist/core/agent/workflows/reference/reference.js.map +1 -1
- package/dist/core/agent/workflows/reference/spine.js +62 -24
- package/dist/core/agent/workflows/reference/spine.js.map +1 -1
- package/dist/core/asyncapi/baseline/plan.js +14 -81
- package/dist/core/asyncapi/baseline/plan.js.map +1 -1
- package/dist/core/asyncapi/digest.js +30 -25
- package/dist/core/asyncapi/digest.js.map +1 -1
- package/dist/core/asyncapi/merge/components.js +5 -4
- package/dist/core/asyncapi/merge/components.js.map +1 -1
- package/dist/core/asyncapi/merge/error.js +7 -2
- package/dist/core/asyncapi/merge/error.js.map +1 -1
- package/dist/core/asyncapi/merge/markers.js +30 -50
- package/dist/core/asyncapi/merge/markers.js.map +1 -1
- package/dist/core/asyncapi/merge/merge.js +31 -53
- package/dist/core/asyncapi/merge/merge.js.map +1 -1
- package/dist/core/asyncapi/merge/pin.js +10 -36
- package/dist/core/asyncapi/merge/pin.js.map +1 -1
- package/dist/core/asyncapi/model.js.map +1 -1
- package/dist/core/asyncapi/read.js +36 -12
- package/dist/core/asyncapi/read.js.map +1 -1
- package/dist/core/brief/brief.js +30 -25
- package/dist/core/brief/brief.js.map +1 -1
- package/dist/core/brief/landscape.js +8 -12
- package/dist/core/brief/landscape.js.map +1 -1
- package/dist/core/brief/map/extend.js +8 -5
- package/dist/core/brief/map/extend.js.map +1 -1
- package/dist/core/brief/map/owed.js +8 -26
- package/dist/core/brief/map/owed.js.map +1 -1
- package/dist/core/brief/targets.js +79 -5
- package/dist/core/brief/targets.js.map +1 -1
- package/dist/core/brief/unchecked.js +1 -1
- package/dist/core/brief/unchecked.js.map +1 -1
- package/dist/core/c4/likec4.js +147 -16
- package/dist/core/c4/likec4.js.map +1 -1
- package/dist/core/c4/locate/unlocated.js +150 -0
- package/dist/core/c4/locate/unlocated.js.map +1 -0
- package/dist/core/c4/parsed/values.js +54 -1
- package/dist/core/c4/parsed/values.js.map +1 -1
- package/dist/core/c4/prefetch/fleet.js +1 -9
- package/dist/core/c4/prefetch/fleet.js.map +1 -1
- package/dist/core/c4/project/architecture.js +31 -9
- package/dist/core/c4/project/architecture.js.map +1 -1
- package/dist/core/c4/project/documents.js +36 -10
- package/dist/core/c4/project/documents.js.map +1 -1
- package/dist/core/c4/project/load.js +14 -21
- package/dist/core/c4/project/load.js.map +1 -1
- package/dist/core/c4/project/staged.js +7 -3
- package/dist/core/c4/project/staged.js.map +1 -1
- 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 +25 -1
- package/dist/core/c4/resolve/service.js.map +1 -1
- package/dist/core/c4/seed/template.js +15 -1
- package/dist/core/c4/seed/template.js.map +1 -1
- package/dist/core/c4/service-model/shape.js +2 -22
- package/dist/core/c4/service-model/shape.js.map +1 -1
- package/dist/core/c4/source-mask.js +288 -4
- package/dist/core/c4/source-mask.js.map +1 -1
- package/dist/core/c4/source-scan.js +203 -147
- package/dist/core/c4/source-scan.js.map +1 -1
- package/dist/core/c4/splice/authored-source.js +19 -0
- package/dist/core/c4/splice/authored-source.js.map +1 -1
- package/dist/core/c4/splice/delta-blocks.js +5 -18
- package/dist/core/c4/splice/delta-blocks.js.map +1 -1
- package/dist/core/c4/splice/landscape-merge.js +13 -8
- package/dist/core/c4/splice/landscape-merge.js.map +1 -1
- package/dist/core/c4/splice/model/merge.js +10 -6
- package/dist/core/c4/splice/model/merge.js.map +1 -1
- package/dist/core/c4/splice/placement.js +108 -18
- package/dist/core/c4/splice/placement.js.map +1 -1
- package/dist/core/c4/workspace.js +13 -22
- package/dist/core/c4/workspace.js.map +1 -1
- package/dist/core/capabilities/capabilities.js +6 -6
- package/dist/core/capabilities/capabilities.js.map +1 -1
- package/dist/core/capabilities/delta/doc.js +7 -10
- package/dist/core/capabilities/delta/doc.js.map +1 -1
- package/dist/core/capabilities/findings.js +15 -20
- package/dist/core/capabilities/findings.js.map +1 -1
- package/dist/core/capabilities/realizes/findings.js +12 -19
- package/dist/core/capabilities/realizes/findings.js.map +1 -1
- package/dist/core/capabilities/realizes/join.js +0 -20
- package/dist/core/capabilities/realizes/join.js.map +1 -1
- package/dist/core/capabilities/rollup.js +6 -0
- package/dist/core/capabilities/rollup.js.map +1 -1
- package/dist/core/capabilities/tree.js +6 -28
- package/dist/core/capabilities/tree.js.map +1 -1
- package/dist/core/capabilities/usecase-join.js +3 -13
- package/dist/core/capabilities/usecase-join.js.map +1 -1
- package/dist/core/coherence/authoring/scaffold.js +11 -3
- package/dist/core/coherence/authoring/scaffold.js.map +1 -1
- package/dist/core/coherence/authoring/sentinels.js +2 -1
- package/dist/core/coherence/authoring/sentinels.js.map +1 -1
- package/dist/core/coherence/coherence.js +30 -16
- package/dist/core/coherence/coherence.js.map +1 -1
- 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/declared.js +60 -34
- package/dist/core/coherence/declared.js.map +1 -1
- package/dist/core/coherence/events/declared.js +44 -59
- package/dist/core/coherence/events/declared.js.map +1 -1
- package/dist/core/coherence/events/events.js +119 -8
- package/dist/core/coherence/events/events.js.map +1 -1
- package/dist/core/coherence/events/grades.js +31 -8
- package/dist/core/coherence/events/grades.js.map +1 -1
- package/dist/core/coherence/events/lookups.js +14 -82
- package/dist/core/coherence/events/lookups.js.map +1 -1
- package/dist/core/coherence/lookups.js +18 -78
- package/dist/core/coherence/lookups.js.map +1 -1
- 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/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/delta.js +1 -1
- package/dist/core/delta/delta.js.map +1 -1
- package/dist/core/deployment/delta.js +15 -16
- package/dist/core/deployment/delta.js.map +1 -1
- package/dist/core/diff/base-git.js +94 -12
- package/dist/core/diff/base-git.js.map +1 -1
- package/dist/core/diff/base-state.js +28 -16
- package/dist/core/diff/base-state.js.map +1 -1
- 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 +22 -6
- package/dist/core/diff/scope/changed-paths.js.map +1 -1
- 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 +100 -31
- package/dist/core/diff/semantic.js.map +1 -1
- package/dist/core/doctor/agents.js +34 -18
- package/dist/core/doctor/agents.js.map +1 -1
- package/dist/core/doctor/report.js.map +1 -1
- package/dist/core/document/apply.js +10 -2
- package/dist/core/document/apply.js.map +1 -1
- package/dist/core/document/frontmatter.js +55 -0
- package/dist/core/document/frontmatter.js.map +1 -1
- package/dist/core/document/parse.js +29 -6
- package/dist/core/document/parse.js.map +1 -1
- package/dist/core/document/scenarios.js +17 -0
- package/dist/core/document/scenarios.js.map +1 -1
- package/dist/core/document/spec.js +4 -11
- package/dist/core/document/spec.js.map +1 -1
- package/dist/core/envelope/config.js +10 -0
- package/dist/core/envelope/config.js.map +1 -1
- package/dist/core/envelope/json.js +34 -0
- package/dist/core/envelope/json.js.map +1 -1
- package/dist/core/explain/families.js +17 -12
- package/dist/core/explain/families.js.map +1 -1
- package/dist/core/explain/refusals.js +3 -3
- package/dist/core/explain/refusals.js.map +1 -1
- package/dist/core/explain/terms.js +18 -9
- package/dist/core/explain/terms.js.map +1 -1
- package/dist/core/explore/explore.js +2 -7
- package/dist/core/explore/explore.js.map +1 -1
- package/dist/core/fleet-context.js +34 -95
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +10 -3
- package/dist/core/gate/checks.js.map +1 -1
- package/dist/core/gate/partners.js +64 -19
- package/dist/core/gate/partners.js.map +1 -1
- package/dist/core/gate/report.js.map +1 -1
- package/dist/core/gate/verification.js +75 -12
- package/dist/core/gate/verification.js.map +1 -1
- package/dist/core/gherkin/stale.js +13 -37
- package/dist/core/gherkin/stale.js.map +1 -1
- package/dist/core/glossary/tree.js +6 -19
- package/dist/core/glossary/tree.js.map +1 -1
- package/dist/core/kernel/concurrency.js +19 -0
- package/dist/core/kernel/concurrency.js.map +1 -1
- package/dist/core/kernel/records.js +11 -0
- package/dist/core/kernel/records.js.map +1 -1
- package/dist/core/links/backlinks.js +1 -3
- package/dist/core/links/backlinks.js.map +1 -1
- package/dist/core/links/corpus.js +5 -36
- package/dist/core/links/corpus.js.map +1 -1
- package/dist/core/mcp/argv.js +101 -0
- package/dist/core/mcp/argv.js.map +1 -1
- package/dist/core/mcp/author-tools.js +2 -1
- package/dist/core/mcp/author-tools.js.map +1 -1
- package/dist/core/mcp/protocol.js +2 -2
- package/dist/core/mcp/protocol.js.map +1 -1
- package/dist/core/mcp/tools.js +43 -33
- package/dist/core/mcp/tools.js.map +1 -1
- package/dist/core/openapi/baseline/gate.js +53 -12
- package/dist/core/openapi/baseline/gate.js.map +1 -1
- package/dist/core/openapi/baseline/plan.js +22 -8
- package/dist/core/openapi/baseline/plan.js.map +1 -1
- package/dist/core/openapi/baseline/record.js +0 -1
- package/dist/core/openapi/baseline/record.js.map +1 -1
- 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 +56 -0
- package/dist/core/openapi/contract-tree.js.map +1 -0
- package/dist/core/openapi/depth.js +38 -24
- package/dist/core/openapi/depth.js.map +1 -1
- package/dist/core/openapi/digest.js +52 -2
- package/dist/core/openapi/digest.js.map +1 -1
- package/dist/core/openapi/doc.js +12 -4
- package/dist/core/openapi/doc.js.map +1 -1
- package/dist/core/openapi/merge/components.js +25 -60
- package/dist/core/openapi/merge/components.js.map +1 -1
- package/dist/core/openapi/merge/error.js +3 -13
- package/dist/core/openapi/merge/error.js.map +1 -1
- package/dist/core/openapi/merge/markers.js +26 -30
- package/dist/core/openapi/merge/markers.js.map +1 -1
- package/dist/core/openapi/merge/merge.js +26 -52
- package/dist/core/openapi/merge/merge.js.map +1 -1
- package/dist/core/openapi/merge/pin.js +15 -35
- package/dist/core/openapi/merge/pin.js.map +1 -1
- package/dist/core/openspec/decide/verdict.js.map +1 -1
- package/dist/core/openspec/inventory.js +4 -5
- package/dist/core/openspec/inventory.js.map +1 -1
- package/dist/core/openspec/model/mapping.js +30 -28
- package/dist/core/openspec/model/mapping.js.map +1 -1
- package/dist/core/openspec/model/model.js +12 -7
- package/dist/core/openspec/model/model.js.map +1 -1
- package/dist/core/openspec/scan/changes.js +10 -4
- package/dist/core/openspec/scan/changes.js.map +1 -1
- package/dist/core/openspec/scan/config.js +7 -16
- package/dist/core/openspec/scan/config.js.map +1 -1
- package/dist/core/openspec/scan/shape.js +63 -19
- package/dist/core/openspec/scan/shape.js.map +1 -1
- package/dist/core/openspec/scan/walk.js +21 -38
- package/dist/core/openspec/scan/walk.js.map +1 -1
- package/dist/core/pack/living.js +2 -16
- package/dist/core/pack/living.js.map +1 -1
- package/dist/core/provenance/findings.js +48 -12
- package/dist/core/provenance/findings.js.map +1 -1
- package/dist/core/provenance/git.js +33 -57
- package/dist/core/provenance/git.js.map +1 -1
- package/dist/core/provenance/gitq/moves.js +71 -114
- package/dist/core/provenance/gitq/moves.js.map +1 -1
- package/dist/core/provenance/gitq/vouched-ancestor.js +2 -2
- package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -1
- package/dist/core/provenance/sources.js +23 -6
- package/dist/core/provenance/sources.js.map +1 -1
- package/dist/core/provenance/stamp.js +5 -17
- package/dist/core/provenance/stamp.js.map +1 -1
- package/dist/core/repo/entries.js.map +1 -1
- package/dist/core/repo/paths.js +34 -29
- package/dist/core/repo/paths.js.map +1 -1
- package/dist/core/repo/repo.js +24 -14
- package/dist/core/repo/repo.js.map +1 -1
- package/dist/core/repo/tree/find.js +12 -3
- package/dist/core/repo/tree/find.js.map +1 -1
- package/dist/core/repo/tree/fs.js +27 -1
- package/dist/core/repo/tree/fs.js.map +1 -1
- package/dist/core/repo/tree/render/body.js +45 -6
- package/dist/core/repo/tree/render/body.js.map +1 -1
- 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 +19 -2
- package/dist/core/repo/tree/render/stale.js.map +1 -1
- package/dist/core/repo/tree/render/views.js +102 -33
- package/dist/core/repo/tree/render/views.js.map +1 -1
- package/dist/core/repo/tree/walk.js +8 -30
- package/dist/core/repo/tree/walk.js.map +1 -1
- package/dist/core/results.js +47 -12
- package/dist/core/results.js.map +1 -1
- package/dist/core/staging/commit.js +10 -12
- package/dist/core/staging/commit.js.map +1 -1
- package/dist/core/staging/lock.js +74 -12
- package/dist/core/staging/lock.js.map +1 -1
- package/dist/core/staging/recovery/intent.js +2 -5
- package/dist/core/staging/recovery/intent.js.map +1 -1
- package/dist/core/staging/recovery/recover.js +60 -1
- package/dist/core/staging/recovery/recover.js.map +1 -1
- package/dist/core/staging/snapshot/manifest.js +152 -0
- package/dist/core/staging/snapshot/manifest.js.map +1 -0
- package/dist/core/staging/{snapshot.js → snapshot/snapshot.js} +10 -34
- package/dist/core/staging/snapshot/snapshot.js.map +1 -0
- package/dist/core/status/actions/execution.js +11 -0
- package/dist/core/status/actions/execution.js.map +1 -1
- package/dist/core/status/feature/artifacts.js +2 -2
- package/dist/core/status/feature/artifacts.js.map +1 -1
- package/dist/core/status/feature/feature.js +5 -11
- package/dist/core/status/feature/feature.js.map +1 -1
- package/dist/core/status/fleet/fleet.js +6 -2
- package/dist/core/status/fleet/fleet.js.map +1 -1
- package/dist/core/status/fleet/next.js +26 -3
- package/dist/core/status/fleet/next.js.map +1 -1
- package/dist/core/status/report.js.map +1 -1
- package/dist/core/status/verification.js +30 -15
- package/dist/core/status/verification.js.map +1 -1
- package/dist/core/tasks/packet.js +174 -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 +11 -14
- package/dist/core/usecases/capability.js.map +1 -1
- package/dist/core/usecases/delta/flows.js +5 -7
- package/dist/core/usecases/delta/flows.js.map +1 -1
- package/dist/core/usecases/fleet.js +178 -31
- package/dist/core/usecases/fleet.js.map +1 -1
- package/dist/core/usecases/operations.js +5 -4
- package/dist/core/usecases/operations.js.map +1 -1
- package/dist/core/usecases/service/flows.js +9 -6
- package/dist/core/usecases/service/flows.js.map +1 -1
- 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/verify/answers.js +12 -5
- package/dist/core/verify/answers.js.map +1 -1
- package/dist/core/verify/build.js +102 -82
- package/dist/core/verify/build.js.map +1 -1
- package/dist/core/verify/checklist.js +45 -10
- package/dist/core/verify/checklist.js.map +1 -1
- package/dist/core/verify/location.js +67 -0
- package/dist/core/verify/location.js.map +1 -0
- package/dist/core/verify/pins/lint.js +3 -2
- package/dist/core/verify/pins/lint.js.map +1 -1
- package/dist/core/verify/pins/pin.js +1 -1
- package/dist/core/verify/pins/pin.js.map +1 -1
- package/dist/core/verify/read/file.js +224 -0
- package/dist/core/verify/read/file.js.map +1 -0
- package/dist/core/verify/{file.js → read/shape.js} +16 -104
- 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 +35 -12
- package/dist/core/verify/record.js.map +1 -1
- package/dist/core/verify/store/commit.js +40 -30
- package/dist/core/verify/store/commit.js.map +1 -1
- package/dist/core/verify/store/render.js +8 -4
- package/dist/core/verify/store/render.js.map +1 -1
- package/dist/core/vocabulary/issue.js +1 -0
- package/dist/core/vocabulary/issue.js.map +1 -1
- package/dist/core/vocabulary/maturity.js +53 -3
- package/dist/core/vocabulary/maturity.js.map +1 -1
- package/examples/README.md +28 -9
- package/examples/docs/architecture/landscape.likec4 +21 -7
- package/examples/docs/architecture/services.likec4 +70 -0
- package/examples/docs/architecture/subsystems.likec4 +3 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +6 -2
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +11 -8
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +6 -6
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +13 -10
- package/examples/docs/services/order-service/asyncapi.yaml +3 -2
- package/examples/docs/services/order-service/model.likec4 +10 -8
- package/examples/docs/services/payment-service/model.likec4 +6 -4
- package/examples/docs/services/platform/identity-service/model.likec4 +9 -7
- package/examples/docs/services/platform/notification-service/asyncapi.yaml +2 -1
- package/examples/docs/services/platform/notification-service/model.likec4 +4 -5
- package/package.json +1 -1
- package/dist/commands/validate/checks/vocabulary.js +0 -16
- package/dist/commands/validate/checks/vocabulary.js.map +0 -1
- package/dist/core/agent/agents-md/artifacts.js +0 -221
- package/dist/core/agent/agents-md/artifacts.js.map +0 -1
- package/dist/core/agent/agents-md/cycle.js +0 -180
- package/dist/core/agent/agents-md/cycle.js.map +0 -1
- package/dist/core/agent/agents-md/shipped/archive-gate.js +0 -98
- package/dist/core/agent/agents-md/shipped/archive-gate.js.map +0 -1
- package/dist/core/agent/agents-md/spine.js +0 -40
- package/dist/core/agent/agents-md/spine.js.map +0 -1
- package/dist/core/coherence/events/merged.js +0 -40
- package/dist/core/coherence/events/merged.js.map +0 -1
- package/dist/core/diff/current-state.js +0 -96
- package/dist/core/diff/current-state.js.map +0 -1
- package/dist/core/diff/victims.js +0 -256
- package/dist/core/diff/victims.js.map +0 -1
- package/dist/core/staging/snapshot.js.map +0 -1
- package/dist/core/verify/file.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init/init.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Command } from \"commander\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport {\n CONFIG_FILENAME,\n findConfigPath,\n loadConfig,\n localConfigPath,\n saveConfig,\n type StoredConfig,\n} from \"../../core/envelope/config.js\";\nimport { docsDirOf } from \"../../core/kernel/ids/dirs.js\";\nimport { emitJson, fail } from \"../../core/envelope/json.js\";\nimport { plannedDocsFiles, scaffoldDocs } from \"../../core/docs.js\";\nimport { docsRepoState } from \"../../core/repo/state.js\";\nimport { listServices } from \"../../core/repo/repo.js\";\nimport { InvalidIdError, assertServiceId } from \"../../core/kernel/ids/service.js\";\nimport {\n detectAgentTools,\n plannedCommandFiles,\n syncAgentCommands,\n updatedAgentFileManifest,\n type Delivery,\n} from \"../../core/agent/scaffold.js\";\nimport { AGENT_TOOLS } from \"../../core/agent/tools/registry.js\";\nimport { initExample } from \"./example.js\";\nimport { firstHour } from \"./first-hour.js\";\nimport { MCP_CONFIG_FILENAME, mcpConfigPath, mcpServerSnippet, writeMcpConfig } from \"./mcp.js\";\nimport { isDocsRepo, resolveAgentProfile, resolveTools, storedDocsDir } from \"./options.js\";\n\ninterface InitOptions {\n docs: string;\n service?: string;\n /** --create: make a new docs repo at --docs instead of joining an existing one. */\n create?: boolean;\n /** --force: write loam.json here even though one already governs a parent directory. */\n force?: boolean;\n /** commander's --no-commands: true unless the flag is passed. */\n commands: boolean;\n /** commander's --no-skills: true unless the flag is passed. */\n skills: boolean;\n /**\n * --mcp: also write the repo-root `.mcp.json`. Opt-in and default off — a\n * third delivery, independent of the two `--no-*` flags rather than a\n * variation on them, so it neither contradicts them nor is suppressed by\n * either. See ./mcp.ts for why the file is opt-in at all.\n */\n mcp?: boolean;\n mcpAuthor?: boolean;\n /** --tools: comma-separated AGENT_TOOLS ids, or \"all\". Absent = autodetect. */\n tools?: string;\n /** Workflow subset to scaffold. */\n agentProfile?: string;\n /** --example: copy the packaged example fleet to this directory and do nothing else. */\n example?: string;\n json?: boolean;\n}\n\nexport function registerInit(program: Command): void {\n program\n .command(\"init\")\n .description(\"Initialize loam: create/point at the shared docs repo and write local config\")\n .option(\"--docs <dir>\", \"path to the shared docs repo (the source of truth)\", \".loam-docs\")\n .option(\"--service <id>\", \"canonical id of the service in this repo\")\n .option(\"--create\", \"create a new docs repo at --docs instead of joining an existing one\")\n .option(\"--force\", `write ${CONFIG_FILENAME} here even though one governs a parent directory`)\n .option(\n \"--tools <ids>\",\n \"agent tools to generate for, overriding the scan of this directory: \" +\n `comma-separated (${Object.keys(AGENT_TOOLS).join(\", \")}) or \"all\"`,\n )\n .option(\"--agent-profile <profile>\", \"workflow set: full | service | docs\")\n .option(\n \"--example <dir>\",\n \"copy the packaged example fleet to <dir> and stop: no repository is bound, nothing is scaffolded\",\n )\n .option(\"--no-commands\", \"skip the slash commands for this repo entirely\")\n .option(\"--no-skills\", \"skip the agent skills for this repo entirely\")\n .option(\n \"--mcp\",\n `also write ${MCP_CONFIG_FILENAME} here, so an MCP host launches \\`loam mcp\\` for this repo`,\n )\n .option(\"--mcp-author\", `write ${MCP_CONFIG_FILENAME} with the opt-in authoring profile`)\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .action(async (opts: InitOptions, command: Command) => {\n const json = opts.json === true;\n const cwd = process.cwd();\n\n // FIRST, before every guard below including the governing-config one:\n // `--example` writes a fresh tree, it does not join a system. A\n // loam.json in an ancestor governs the directories a repository is bound\n // INTO, and this flag binds nothing — refusing here would be the tool\n // declining to show itself working because of a config that has no\n // bearing on the copy. Before the --service id check too, so a run\n // combining the two answers the contradiction rather than grading an id\n // it is about to refuse to use.\n if (opts.example !== undefined) {\n await initExample({\n dir: opts.example,\n conflicts: [\n // `--docs` carries a default, so only its SOURCE can say whether\n // anybody typed it — the same question the docsDir precedence\n // below asks, for the same reason.\n ...(command.getOptionValueSource(\"docs\") !== \"default\" ? [\"--docs\"] : []),\n ...(opts.service !== undefined ? [\"--service\"] : []),\n ...(opts.create === true ? [\"--create\"] : []),\n ...(opts.tools !== undefined ? [\"--tools\"] : []),\n ...(opts.agentProfile !== undefined ? [\"--agent-profile\"] : []),\n ...(opts.mcpAuthor === true ? [\"--mcp-author\"] : []),\n ],\n json,\n });\n return;\n }\n\n // The id becomes services/<id>/ in the shared repo, so it is validated\n // before anything is written — by the same rule adopt, vouch and gherkin\n // use, never by a guard invented here.\n if (opts.service !== undefined) {\n try {\n assertServiceId(opts.service);\n } catch (err) {\n if (!(err instanceof InvalidIdError)) throw err;\n fail(json, \"invalid-option\", err.message);\n return;\n }\n }\n\n // A loam.json in an ancestor already governs this directory: every command\n // run from here resolves to it. Writing a second one below it would shadow\n // the first for this subtree only — the kind of split-brain nobody\n // discovers until two commands disagree about which docs repo is the fleet.\n const governing = findConfigPath(cwd);\n if (governing !== null && governing !== localConfigPath(cwd) && opts.force !== true) {\n fail(\n json,\n \"already-exists\",\n `${governing} already governs this directory. ` +\n `Run loam from ${resolve(governing, \"..\")}, or pass --force to give this ` +\n `subdirectory its own ${CONFIG_FILENAME}.`,\n );\n return;\n }\n\n // Only THIS directory's config is spread forward. Under --force there is\n // a config in an ancestor too, and inheriting its `service` would bind\n // this repo to a service somebody else's repo declared.\n // `kind: \"invalid\"` reads as null on purpose: init REPAIRS a corrupt\n // loam.json by rewriting it, so a config nobody can read is treated\n // exactly like no config at all. The old stderr line about it was\n // core's side effect, promised nowhere.\n const load = existsSync(localConfigPath(cwd)) ? await loadConfig(cwd) : null;\n const existing = load?.kind === \"loaded\" ? load.config : null;\n\n // A re-run must not move a committed pointer. `--docs` has a default\n // (`.loam-docs`), so an init invoked for any OTHER reason — `--service`,\n // a new `--tools`, the fix `doctor.agent-files-missing` prints — used to\n // arrive here carrying a docsDir nobody typed: the default then named no\n // docs repo, the refusal steered the caller to `--create`, and `--create`\n // rewrote `docsDir` in the committed loam.json to a freshly scaffolded\n // empty one. `validate --all` went green over an empty fleet, which is\n // the exact outcome `--create` exists to prevent. So the flag wins only\n // when it was actually passed; otherwise the file this repo already\n // committed does.\n const committedDocs = existing?.docsDirAsWritten;\n const docsTyped = command.getOptionValueSource(\"docs\") !== \"default\";\n const docsSource: \"flag\" | \"config\" | \"default\" =\n docsTyped ? \"flag\" : committedDocs === undefined ? \"default\" : \"config\";\n const docsOption = !docsTyped && committedDocs !== undefined ? committedDocs : opts.docs;\n // Branded at the resolution, because the guards below are what validate\n // it — the brand's provenance is \"an explicit --docs a command\n // validated\", and this command is the one that does. The STORED spelling\n // (`storedDocsDir` below) deliberately stays a plain string.\n const docsDir = docsDirOf(resolve(cwd, docsOption));\n\n // The one predictable failure: --docs naming a file. Refused here so the\n // caller gets a clean envelope/message instead of mkdir's ENOTDIR throw.\n if (existsSync(docsDir) && !statSync(docsDir).isDirectory()) {\n fail(json, \"invalid-option\", `--docs points at a file, not a directory: ${docsDir}`);\n return;\n }\n\n // Joining an existing docs repo and creating a new one are different\n // intentions, and `init` used to perform the second one whenever the first\n // was misspelled: `--docs ../dcos` scaffolded a second, empty docs repo\n // beside the real one, and the fleet quietly split in two. Creation is now\n // something the caller asks for.\n const joining = isDocsRepo(docsDir);\n if (!joining && opts.create !== true) {\n fail(\n json,\n \"invalid-option\",\n docsRepoState(docsDir).kind === \"missing\"\n ? `--docs points at a directory that does not exist: ${docsDir}. ` +\n \"If that is a typo, fix it; to create a new docs repo there, pass --create.\"\n : `--docs points at ${docsDir}, which is not a docs repo ` +\n \"(a docs repo has services/ and AGENTS.md). \" +\n \"Point --docs at the shared docs repo, or pass --create to make a new one here.\",\n );\n return;\n }\n\n // --tools selects the files to write; --no-commands and --no-skills each\n // say write none of that kind. Together they contradict — refused, not\n // arbitrated, in either combination.\n const suppressed = [\n ...(opts.commands ? [] : [\"--no-commands\"]),\n ...(opts.skills ? [] : [\"--no-skills\"]),\n ];\n if (opts.tools !== undefined && suppressed.length > 0) {\n fail(\n json,\n \"invalid-option\",\n `--tools contradicts ${suppressed.join(\" and \")}: ` +\n \"one selects the files to generate, the other suppresses them.\",\n );\n return;\n }\n const delivery: Delivery[] = [\n ...(opts.commands ? ([\"commands\"] as const) : []),\n ...(opts.skills ? ([\"skills\"] as const) : []),\n ];\n\n // Without --tools the repo decides: whichever tools have left their own\n // dot-directories here. Falling back to claude keeps a bare repo behaving\n // exactly as it did before the scan existed. `detected` is reported either\n // way — what the scan saw is a fact about the repo, not about the flags.\n const detected = detectAgentTools(cwd);\n const scanned = detected.length > 0 ? detected : [\"claude\"];\n const tools = opts.tools === undefined ? scanned : resolveTools(opts.tools, json);\n if (tools === null) return;\n const profile = resolveAgentProfile(opts.agentProfile, existing?.agentProfile, json);\n if (profile === null) return;\n\n // Probe the pre-existing paths in planned order. Managed files refreshed\n // below are removed from `skipped`; custom and already-current files stay.\n const plannedAgentFiles = delivery.length > 0 ? plannedCommandFiles(cwd, tools, delivery, profile) : [];\n // `.mcp.json` joins the same list rather than being reported on the side:\n // it is a scaffolded path like any other, so it must appear in `created`\n // or in `skipped` by the one rule that governs both. Last, because it is\n // written last.\n const candidates = [\n ...plannedDocsFiles(docsDir),\n ...plannedAgentFiles.map((f) => f.path),\n ...(opts.mcp === true || opts.mcpAuthor === true ? [mcpConfigPath(cwd)] : []),\n ];\n let skipped = candidates.filter((p) => existsSync(p));\n\n // Joining touches the docs repo not at all: it is somebody's committed\n // repository, and \"point at it\" must never mean \"write to it\".\n const created = joining && opts.create !== true ? [] : (await scaffoldDocs(docsDir)).created;\n const generatedFor = delivery.length > 0 ? tools : [];\n let refreshed: string[] = [];\n let managedFiles: Record<string, string> = {};\n if (delivery.length > 0) {\n const synced = await syncAgentCommands({\n cwd,\n toolIds: tools,\n delivery,\n profile,\n known: existing?.agentFiles,\n });\n created.push(...synced.created);\n refreshed = synced.refreshed;\n managedFiles = synced.managed;\n skipped = skipped.filter((path) => !refreshed.includes(path));\n }\n\n // The third delivery, and the only machine-readable one. It refuses out\n // loud rather than being written best-effort: a `.mcp.json` half-landed\n // is a host that starts a broken server, and the caller asked for it by\n // name. Before saveConfig, so a run that cannot write this file has not\n // yet moved the committed pointer either.\n let mcpWritten = false;\n if (opts.mcp === true || opts.mcpAuthor === true) {\n const write = await writeMcpConfig(cwd, opts.mcpAuthor === true);\n if (write.kind === \"failed\") {\n fail(json, write.code, write.message);\n return;\n }\n mcpWritten = write.kind === \"created\";\n if (mcpWritten) created.push(mcpConfigPath(cwd));\n }\n\n const stored = storedDocsDir(docsOption);\n // Union, not replacement: this run's files join the ones earlier runs left\n // on disk, and `agentTools` is a record of what the repo HOLDS. A run that\n // generated nothing adds nothing and erases nothing.\n const recordedTools = [...new Set([...(existing?.agentTools ?? []), ...generatedFor])];\n const agentFileManifest = updatedAgentFileManifest(cwd, plannedAgentFiles, existing?.agentFiles, managedFiles);\n const config: StoredConfig = {\n ...existing,\n docsDir: stored,\n ...(opts.service ? { service: opts.service } : {}),\n ...(recordedTools.length > 0 ? { agentTools: recordedTools } : {}),\n agentProfile: profile,\n };\n if (Object.keys(agentFileManifest).length > 0) config.agentFiles = agentFileManifest;\n const configFile = await saveConfig(config, cwd);\n\n const serviceCount = (await listServices(docsDir)).length;\n\n if (json) {\n // `docsDir` stays the resolved absolute path — it is what a consumer\n // needs to find the repo. `docsDirStored` is what was written to\n // loam.json, which is the fact this command is now careful about.\n // `tools` names what files were generated FOR — empty when every\n // delivery was suppressed and none were. `detected` is the separate\n // question of what the scan SAW, which `--tools` overrides without\n // changing: an agent comparing the two learns whether its selection\n // matches the repo.\n emitJson({\n command: \"init\",\n docsDir,\n docsDirStored: stored,\n // Where the pointer came from: `flag` (a --docs somebody typed),\n // `config` (the one this repo already committed — a re-run cannot\n // move it), or `default` (nothing said, nothing committed).\n docsDirSource: docsSource,\n docsRepo: joining ? \"existing\" : \"created\",\n services: serviceCount,\n created,\n refreshed,\n skipped,\n tools: generatedFor,\n agentProfile: profile,\n detected,\n });\n return;\n }\n\n console.log(\"loam initialized.\");\n if (joining) {\n console.log(` docs repo: ${docsDir}`);\n console.log(` pointing at existing docs repo (${serviceCount} services)`);\n } else {\n console.log(` docs repo: ${docsDir} (created)`);\n }\n console.log(\n ` docsDir: ${stored} (as stored in ${CONFIG_FILENAME}`\n + (docsSource === \"config\" ? \" — kept; no --docs was passed\" : \"\") + \")\",\n );\n if (config.service) console.log(` service: ${config.service}`);\n console.log(` config: ${configFile}`);\n console.log(` commit ${CONFIG_FILENAME} — docsDir is resolved relative to it`);\n if (opts.tools === undefined && detected.length > 0) {\n console.log(` detected: ${detected.join(\", \")}`);\n }\n if (opts.commands) console.log(` commands: ${tools.join(\", \")}`);\n if (opts.skills) console.log(` skills: ${tools.join(\", \")}`);\n console.log(` profile: ${profile}`);\n if (created.length > 0) {\n console.log(\" scaffolded:\");\n for (const c of created) console.log(` + ${c}`);\n }\n if (refreshed.length > 0) {\n console.log(\" refreshed (unchanged since loam last wrote them):\");\n for (const path of refreshed) console.log(` ↻ ${path}`);\n }\n\n // The one skipped path that earns more than its line in `skipped`: loam\n // will not merge into a `.mcp.json` a human owns, and the caller asked\n // for this delivery by name — so they are handed the exact key to paste\n // into their own `mcpServers` object. Nothing was read out of their file\n // to produce it; the snippet is the same bytes a fresh write would have\n // used, which is also why it names the launch form this install shape\n // actually needs.\n if ((opts.mcp === true || opts.mcpAuthor === true) && !mcpWritten) {\n console.log(` mcp: ${MCP_CONFIG_FILENAME} is already here — left exactly as it is.`);\n console.log(` paste this into its \"mcpServers\" object:`);\n for (const line of mcpServerSnippet(cwd, opts.mcpAuthor === true)) console.log(` ${line}`);\n }\n\n // Printed ONLY for the single-repo trial composition: one run that both\n // created the docs repo and left a service bound (the binding may\n // predate the run — the config spread above carries an existing\n // loam.json's `service` forward). `loam status` is NOT mute here — its\n // first-hour ladder (core/status/fleet/next.ts) already answers\n // `next.adopt-bound` in exactly this state — but status has to be run\n // to say so, and no status rung ever names `loam vouch`, the one step\n // of this loop that is a person's; init's output is already on screen,\n // so it prints the whole hour once. A join stays silent on purpose: a\n // joined fleet has other repositories already through this loop, and\n // `loam status` in its docs repo is the working guide there. The --json\n // path returned above, so the envelope is byte-identical to before\n // this block existed.\n if (!joining && config.service !== undefined) {\n const steps = firstHour(config.service);\n const width = Math.max(...steps.map(([command]) => command.length));\n console.log(\" next — the first hour:\");\n for (const [command, why] of steps) {\n console.log(` ${command.padEnd(width)} # ${why}`);\n }\n }\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init/init.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Command } from \"commander\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport {\n CONFIG_FILENAME,\n findConfigPath,\n loadConfig,\n localConfigPath,\n saveConfig,\n type StoredConfig,\n} from \"../../core/envelope/config.js\";\nimport { docsDirOf } from \"../../core/kernel/ids/dirs.js\";\nimport { emitJson, fail } from \"../../core/envelope/json.js\";\nimport { plannedDocsFiles, scaffoldDocs } from \"../../core/docs.js\";\nimport { docsRepoState } from \"../../core/repo/state.js\";\nimport { listServices } from \"../../core/repo/repo.js\";\nimport { InvalidIdError, assertServiceId } from \"../../core/kernel/ids/service.js\";\nimport {\n detectAgentTools,\n plannedCommandFiles,\n syncAgentCommands,\n updatedAgentFileManifest,\n type Delivery,\n} from \"../../core/agent/scaffold.js\";\nimport { AGENT_TOOLS } from \"../../core/agent/tools/registry.js\";\nimport { initExample } from \"./example.js\";\nimport { firstHourLines } from \"./first-hour.js\";\nimport { MCP_CONFIG_FILENAME, mcpConfigPath, mcpServerSnippet, writeMcpConfig } from \"./mcp.js\";\nimport { isDocsRepo, resolveAgentProfile, resolveTools, storedDocsDir } from \"./options.js\";\n\ninterface InitOptions {\n docs: string;\n service?: string;\n /** --create: make a new docs repo at --docs instead of joining an existing one. */\n create?: boolean;\n /** --force: write loam.json here even though one already governs a parent directory. */\n force?: boolean;\n /** commander's --no-commands: true unless the flag is passed. */\n commands: boolean;\n /** commander's --no-skills: true unless the flag is passed. */\n skills: boolean;\n /**\n * --mcp: also write the repo-root `.mcp.json`. Opt-in and default off — a\n * third delivery, independent of the two `--no-*` flags rather than a\n * variation on them, so it neither contradicts them nor is suppressed by\n * either. See ./mcp.ts for why the file is opt-in at all.\n */\n mcp?: boolean;\n mcpAuthor?: boolean;\n /** --tools: comma-separated AGENT_TOOLS ids, or \"all\". Absent = autodetect. */\n tools?: string;\n /** Workflow subset to scaffold. */\n agentProfile?: string;\n /** --example: copy the packaged example fleet to this directory and do nothing else. */\n example?: string;\n json?: boolean;\n}\n\nexport function registerInit(program: Command): void {\n program\n .command(\"init\")\n .description(\"Initialize loam: create/point at the shared docs repo and write local config\")\n .option(\"--docs <dir>\", \"path to the shared docs repo (the source of truth)\", \".loam-docs\")\n .option(\"--service <id>\", \"canonical id of the service in this repo\")\n .option(\"--create\", \"create a new docs repo at --docs instead of joining an existing one\")\n .option(\"--force\", `write ${CONFIG_FILENAME} here even though one governs a parent directory`)\n .option(\n \"--tools <ids>\",\n \"agent tools to generate for, overriding the scan of this directory: \" +\n `comma-separated (${Object.keys(AGENT_TOOLS).join(\", \")}) or \"all\"`,\n )\n .option(\"--agent-profile <profile>\", \"workflow set: full | service | docs\")\n .option(\n \"--example <dir>\",\n \"copy the packaged example fleet to <dir> and stop: no repository is bound, nothing is scaffolded\",\n )\n .option(\"--no-commands\", \"skip the slash commands for this repo entirely\")\n .option(\"--no-skills\", \"skip the agent skills for this repo entirely\")\n .option(\n \"--mcp\",\n `also write ${MCP_CONFIG_FILENAME} here, so an MCP host launches \\`loam mcp\\` for this repo`,\n )\n .option(\"--mcp-author\", `write ${MCP_CONFIG_FILENAME} with the opt-in authoring profile`)\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .action(async (opts: InitOptions, command: Command) => {\n const json = opts.json === true;\n const cwd = process.cwd();\n\n // FIRST, before every guard below including the governing-config one:\n // `--example` writes a fresh tree, it does not join a system. A\n // loam.json in an ancestor governs the directories a repository is bound\n // INTO, and this flag binds nothing — refusing here would be the tool\n // declining to show itself working because of a config that has no\n // bearing on the copy. Before the --service id check too, so a run\n // combining the two answers the contradiction rather than grading an id\n // it is about to refuse to use.\n if (opts.example !== undefined) {\n await initExample({\n dir: opts.example,\n conflicts: [\n // `--docs` carries a default, so only its SOURCE can say whether\n // anybody typed it — the same question the docsDir precedence\n // below asks, for the same reason.\n ...(command.getOptionValueSource(\"docs\") !== \"default\" ? [\"--docs\"] : []),\n ...(opts.service !== undefined ? [\"--service\"] : []),\n ...(opts.create === true ? [\"--create\"] : []),\n ...(opts.tools !== undefined ? [\"--tools\"] : []),\n ...(opts.agentProfile !== undefined ? [\"--agent-profile\"] : []),\n ...(opts.mcpAuthor === true ? [\"--mcp-author\"] : []),\n ],\n json,\n });\n return;\n }\n\n // The id becomes services/<id>/ in the shared repo, so it is validated\n // before anything is written — by the same rule adopt, vouch and gherkin\n // use, never by a guard invented here.\n if (opts.service !== undefined) {\n try {\n assertServiceId(opts.service);\n } catch (err) {\n if (!(err instanceof InvalidIdError)) throw err;\n fail(json, \"invalid-option\", err.message);\n return;\n }\n }\n\n // A loam.json in an ancestor already governs this directory: every command\n // run from here resolves to it. Writing a second one below it would shadow\n // the first for this subtree only — the kind of split-brain nobody\n // discovers until two commands disagree about which docs repo is the fleet.\n const governing = findConfigPath(cwd);\n if (governing !== null && governing !== localConfigPath(cwd) && opts.force !== true) {\n fail(\n json,\n \"already-exists\",\n `${governing} already governs this directory. ` +\n `Run loam from ${resolve(governing, \"..\")}, or pass --force to give this ` +\n `subdirectory its own ${CONFIG_FILENAME}.`,\n );\n return;\n }\n\n // Only THIS directory's config is spread forward. Under --force there is\n // a config in an ancestor too, and inheriting its `service` would bind\n // this repo to a service somebody else's repo declared.\n // `kind: \"invalid\"` reads as null on purpose: init REPAIRS a corrupt\n // loam.json by rewriting it, so a config nobody can read is treated\n // exactly like no config at all. The old stderr line about it was\n // core's side effect, promised nowhere.\n const load = existsSync(localConfigPath(cwd)) ? await loadConfig(cwd) : null;\n const existing = load?.kind === \"loaded\" ? load.config : null;\n\n // A re-run must not move a committed pointer. `--docs` has a default\n // (`.loam-docs`), so an init invoked for any OTHER reason — `--service`,\n // a new `--tools`, the fix `doctor.agent-files-missing` prints — used to\n // arrive here carrying a docsDir nobody typed: the default then named no\n // docs repo, the refusal steered the caller to `--create`, and `--create`\n // rewrote `docsDir` in the committed loam.json to a freshly scaffolded\n // empty one. `validate --all` went green over an empty fleet, which is\n // the exact outcome `--create` exists to prevent. So the flag wins only\n // when it was actually passed; otherwise the file this repo already\n // committed does.\n const committedDocs = existing?.docsDirAsWritten;\n const docsTyped = command.getOptionValueSource(\"docs\") !== \"default\";\n const docsSource: \"flag\" | \"config\" | \"default\" =\n docsTyped ? \"flag\" : committedDocs === undefined ? \"default\" : \"config\";\n const docsOption = !docsTyped && committedDocs !== undefined ? committedDocs : opts.docs;\n // Branded at the resolution, because the guards below are what validate\n // it — the brand's provenance is \"an explicit --docs a command\n // validated\", and this command is the one that does. The STORED spelling\n // (`storedDocsDir` below) deliberately stays a plain string.\n const docsDir = docsDirOf(resolve(cwd, docsOption));\n\n // The one predictable failure: --docs naming a file. Refused here so the\n // caller gets a clean envelope/message instead of mkdir's ENOTDIR throw.\n if (existsSync(docsDir) && !statSync(docsDir).isDirectory()) {\n fail(json, \"invalid-option\", `--docs points at a file, not a directory: ${docsDir}`);\n return;\n }\n\n // Joining an existing docs repo and creating a new one are different\n // intentions, and `init` used to perform the second one whenever the first\n // was misspelled: `--docs ../dcos` scaffolded a second, empty docs repo\n // beside the real one, and the fleet quietly split in two. Creation is now\n // something the caller asks for.\n const joining = isDocsRepo(docsDir);\n if (!joining && opts.create !== true) {\n fail(\n json,\n \"invalid-option\",\n docsRepoState(docsDir).kind === \"missing\"\n ? `--docs points at a directory that does not exist: ${docsDir}. ` +\n \"If that is a typo, fix it; to create a new docs repo there, pass --create.\"\n : `--docs points at ${docsDir}, which is not a docs repo ` +\n \"(a docs repo has services/ and AGENTS.md). \" +\n \"Point --docs at the shared docs repo, or pass --create to make a new one here.\",\n );\n return;\n }\n\n // --tools selects the files to write; --no-commands and --no-skills each\n // say write none of that kind. Together they contradict — refused, not\n // arbitrated, in either combination.\n const suppressed = [\n ...(opts.commands ? [] : [\"--no-commands\"]),\n ...(opts.skills ? [] : [\"--no-skills\"]),\n ];\n if (opts.tools !== undefined && suppressed.length > 0) {\n fail(\n json,\n \"invalid-option\",\n `--tools contradicts ${suppressed.join(\" and \")}: ` +\n \"one selects the files to generate, the other suppresses them.\",\n );\n return;\n }\n const delivery: Delivery[] = [\n ...(opts.commands ? ([\"commands\"] as const) : []),\n ...(opts.skills ? ([\"skills\"] as const) : []),\n ];\n\n // Without --tools the repo decides: whichever tools have left their own\n // dot-directories here. Falling back to claude keeps a bare repo behaving\n // exactly as it did before the scan existed. `detected` is reported either\n // way — what the scan saw is a fact about the repo, not about the flags.\n const detected = detectAgentTools(cwd);\n const scanned = detected.length > 0 ? detected : [\"claude\"];\n const tools = opts.tools === undefined ? scanned : resolveTools(opts.tools, json);\n if (tools === null) return;\n const profile = resolveAgentProfile(opts.agentProfile, existing?.agentProfile, json);\n if (profile === null) return;\n\n // Probe the pre-existing paths in planned order. Managed files refreshed\n // below are removed from `skipped`; custom and already-current files stay.\n const plannedAgentFiles = delivery.length > 0 ? plannedCommandFiles(cwd, tools, delivery, profile) : [];\n // `.mcp.json` joins the same list rather than being reported on the side:\n // it is a scaffolded path like any other, so it must appear in `created`\n // or in `skipped` by the one rule that governs both. Last, because it is\n // written last.\n const candidates = [\n ...plannedDocsFiles(docsDir),\n ...plannedAgentFiles.map((f) => f.path),\n ...(opts.mcp === true || opts.mcpAuthor === true ? [mcpConfigPath(cwd)] : []),\n ];\n let skipped = candidates.filter((p) => existsSync(p));\n\n // Joining touches the docs repo not at all: it is somebody's committed\n // repository, and \"point at it\" must never mean \"write to it\".\n const created = joining && opts.create !== true ? [] : (await scaffoldDocs(docsDir)).created;\n const generatedFor = delivery.length > 0 ? tools : [];\n let refreshed: string[] = [];\n let managedFiles: Record<string, string> = {};\n if (delivery.length > 0) {\n const synced = await syncAgentCommands({\n cwd,\n toolIds: tools,\n delivery,\n profile,\n known: existing?.agentFiles,\n });\n created.push(...synced.created);\n refreshed = synced.refreshed;\n managedFiles = synced.managed;\n skipped = skipped.filter((path) => !refreshed.includes(path));\n }\n\n // The third delivery, and the only machine-readable one. It refuses out\n // loud rather than being written best-effort: a `.mcp.json` half-landed\n // is a host that starts a broken server, and the caller asked for it by\n // name. Before saveConfig, so a run that cannot write this file has not\n // yet moved the committed pointer either.\n let mcpWritten = false;\n if (opts.mcp === true || opts.mcpAuthor === true) {\n const write = await writeMcpConfig(cwd, opts.mcpAuthor === true);\n if (write.kind === \"failed\") {\n fail(json, write.code, write.message);\n return;\n }\n mcpWritten = write.kind === \"created\";\n if (mcpWritten) created.push(mcpConfigPath(cwd));\n }\n\n const stored = storedDocsDir(docsOption);\n // Union, not replacement: this run's files join the ones earlier runs left\n // on disk, and `agentTools` is a record of what the repo HOLDS. A run that\n // generated nothing adds nothing and erases nothing.\n const recordedTools = [...new Set([...(existing?.agentTools ?? []), ...generatedFor])];\n const agentFileManifest = updatedAgentFileManifest(cwd, plannedAgentFiles, existing?.agentFiles, managedFiles);\n const config: StoredConfig = {\n ...existing,\n docsDir: stored,\n ...(opts.service ? { service: opts.service } : {}),\n ...(recordedTools.length > 0 ? { agentTools: recordedTools } : {}),\n agentProfile: profile,\n };\n if (Object.keys(agentFileManifest).length > 0) config.agentFiles = agentFileManifest;\n const configFile = await saveConfig(config, cwd);\n\n const serviceCount = (await listServices(docsDir)).length;\n\n if (json) {\n // `docsDir` stays the resolved absolute path — it is what a consumer\n // needs to find the repo. `docsDirStored` is what was written to\n // loam.json, which is the fact this command is now careful about.\n // `tools` names what files were generated FOR — empty when every\n // delivery was suppressed and none were. `detected` is the separate\n // question of what the scan SAW, which `--tools` overrides without\n // changing: an agent comparing the two learns whether its selection\n // matches the repo.\n emitJson({\n command: \"init\",\n docsDir,\n docsDirStored: stored,\n // Where the pointer came from: `flag` (a --docs somebody typed),\n // `config` (the one this repo already committed — a re-run cannot\n // move it), or `default` (nothing said, nothing committed).\n docsDirSource: docsSource,\n docsRepo: joining ? \"existing\" : \"created\",\n services: serviceCount,\n created,\n refreshed,\n skipped,\n tools: generatedFor,\n agentProfile: profile,\n detected,\n });\n return;\n }\n\n console.log(\"loam initialized.\");\n if (joining) {\n console.log(` docs repo: ${docsDir}`);\n console.log(` pointing at existing docs repo (${serviceCount} services)`);\n } else {\n console.log(` docs repo: ${docsDir} (created)`);\n }\n console.log(\n ` docsDir: ${stored} (as stored in ${CONFIG_FILENAME}`\n + (docsSource === \"config\" ? \" — kept; no --docs was passed\" : \"\") + \")\",\n );\n if (config.service) console.log(` service: ${config.service}`);\n console.log(` config: ${configFile}`);\n console.log(` commit ${CONFIG_FILENAME} — docsDir is resolved relative to it`);\n if (opts.tools === undefined && detected.length > 0) {\n console.log(` detected: ${detected.join(\", \")}`);\n }\n if (opts.commands) console.log(` commands: ${tools.join(\", \")}`);\n if (opts.skills) console.log(` skills: ${tools.join(\", \")}`);\n console.log(` profile: ${profile}`);\n if (created.length > 0) {\n console.log(\" scaffolded:\");\n for (const c of created) console.log(` + ${c}`);\n }\n if (refreshed.length > 0) {\n console.log(\" refreshed (unchanged since loam last wrote them):\");\n for (const path of refreshed) console.log(` ↻ ${path}`);\n }\n\n // The one skipped path that earns more than its line in `skipped`: loam\n // will not merge into a `.mcp.json` a human owns, and the caller asked\n // for this delivery by name — so they are handed the exact key to paste\n // into their own `mcpServers` object. Nothing was read out of their file\n // to produce it; the snippet is the same bytes a fresh write would have\n // used, which is also why it names the launch form this install shape\n // actually needs.\n if ((opts.mcp === true || opts.mcpAuthor === true) && !mcpWritten) {\n console.log(` mcp: ${MCP_CONFIG_FILENAME} is already here — left exactly as it is.`);\n console.log(` paste this into its \"mcpServers\" object:`);\n for (const line of mcpServerSnippet(cwd, opts.mcpAuthor === true)) console.log(` ${line}`);\n }\n\n // Printed ONLY when this run created the docs repo. With a service bound\n // (the binding may predate the run — the config spread above carries an\n // existing loam.json's `service` forward) it is the single-repo trial's\n // hour. `loam status` is NOT mute here — its first-hour ladder\n // (core/status/fleet/next.ts) already answers `next.adopt-bound` in\n // exactly this state — but status has to be run to say so, and no status\n // rung ever names `loam vouch`, the one step of this loop that is a\n // person's; init's output is already on screen, so it prints the whole\n // hour once. With none bound it is the docs repo's own hour (map, bind,\n // adopt — first-hour.ts says why that used to be silence). A join stays\n // silent on purpose: a joined fleet has other repositories already\n // through this loop, and `loam status` in its docs repo is the working\n // guide there. The --json path returned above, so the envelope is\n // byte-identical to before this block existed: neither variant has a key.\n if (!joining) for (const line of firstHourLines(config.service)) console.log(line);\n });\n}\n"]}
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
* already keeps.
|
|
9
9
|
*
|
|
10
10
|
* Resolution reuses the tree machinery verbatim (`findInTree`,
|
|
11
|
-
* `servicesUnder`, `
|
|
11
|
+
* `servicesUnder`, `closeNamesHint`), so `list --subsystem` and every
|
|
12
12
|
* `loam subsystem` verb read the flat namespace the same way — two spellings
|
|
13
13
|
* of "what does this name mean" would drift.
|
|
14
14
|
*/
|
|
15
15
|
import { fail } from "../../../core/envelope/json.js";
|
|
16
|
-
import {
|
|
16
|
+
import { closeNamesHint, findInTree, servicesUnder, subsystemsUnder } from "../../../core/repo/tree/find.js";
|
|
17
17
|
/**
|
|
18
18
|
* Resolve `--subsystem <name>` against the flat namespace, or report the
|
|
19
19
|
* refusal and return null. The reserved name `unfiled` selects the services
|
|
@@ -38,11 +38,9 @@ export function resolveSubsystemSlice(tree, name, json) {
|
|
|
38
38
|
if (hit === null) {
|
|
39
39
|
// The Set: a real subsystem named 'unfiled' would otherwise sit in the
|
|
40
40
|
// hint pool twice and could be offered twice in one hint.
|
|
41
|
-
const
|
|
41
|
+
const pool = [...new Set([...tree.subsystems.map((s) => s.name), "unfiled"])];
|
|
42
42
|
fail(json, "unknown-target", `No subsystem '${name}' in the tree.` +
|
|
43
|
-
(
|
|
44
|
-
? ` Close names: ${close.join(", ")}.`
|
|
45
|
-
: " `loam subsystem list` shows what exists; `unfiled` selects the services filed under none."));
|
|
43
|
+
closeNamesHint(name, pool, " `loam subsystem list` shows what exists; `unfiled` selects the services filed under none."));
|
|
46
44
|
return null;
|
|
47
45
|
}
|
|
48
46
|
if (hit.kind === "service") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"campaign.js","sourceRoot":"","sources":["../../../../src/commands/list/campaign/campaign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"campaign.js","sourceRoot":"","sources":["../../../../src/commands/list/campaign/campaign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAqB7G;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAe,EAAE,IAAY,EAAE,IAAa;IAChF,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACnC,IAAI,GAAG,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvC,OAAO;YACL,OAAO,EAAE,IAAI,GAAG,CAAS,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACjG,UAAU,EAAE,EAAE;YACd,KAAK,EAAE,6CAA6C;SACrD,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,uEAAuE;QACvE,0DAA0D;QAC1D,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;QAC9E,IAAI,CACF,IAAI,EACJ,gBAAgB,EAChB,iBAAiB,IAAI,gBAAgB;YACnC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,4FAA4F,CAAC,CAC3H,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3B,yEAAyE;QACzE,wEAAwE;QACxE,0DAA0D;QAC1D,MAAM,QAAQ,GACZ,IAAI,KAAK,SAAS;YAChB,CAAC,CAAC,uHAAuH;YACzH,CAAC,CAAC,EAAE,CAAC;QACT,IAAI,CACF,IAAI,EACJ,gBAAgB,EAChB,kCAAkC,IAAI,+CAA+C,QAAQ,EAAE,CAChG,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC;IAC1B,OAAO;QACL,OAAO,EAAE,IAAI,GAAG,CAAS,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACpE,UAAU,EAAE,CAAC,GAAG,EAAE,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAChD,KAAK,EAAE,cAAc,GAAG,CAAC,IAAI,eAAe,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;KACnE,CAAC;AACJ,CAAC","sourcesContent":["/**\n * The `--subsystem` slice behind `loam list`: what the flag's name denotes,\n * and which services the filter keeps. A sub-package of list/ because the\n * list package proper stands at its five-file limit (review.ts records\n * that), and the adoption-campaign flag surface is its own subject beside\n * the section renderers. The dependency direction is list → list/campaign,\n * never back — this package imports core only, the same rule repo → repo/tree\n * already keeps.\n *\n * Resolution reuses the tree machinery verbatim (`findInTree`,\n * `servicesUnder`, `closeNamesHint`), so `list --subsystem` and every\n * `loam subsystem` verb read the flat namespace the same way — two spellings\n * of \"what does this name mean\" would drift.\n */\nimport { fail } from \"../../../core/envelope/json.js\";\nimport { closeNamesHint, findInTree, servicesUnder, subsystemsUnder } from \"../../../core/repo/tree/find.js\";\nimport type { FleetTree, SubsystemEntry } from \"../../../core/repo/tree/walk.js\";\n\nexport interface SubsystemSlice {\n /**\n * DIRECTORIES of the member services, at any depth beneath the filter\n * target — the directory, not the id, because the id is a leaf name the\n * fleet does not guarantee unique: a `subsystem.name-collision` tree still\n * enumerates both claimants on purpose, and an id-keyed slice would let\n * each of two disjoint slices claim the other's service.\n */\n readonly members: ReadonlySet<string>;\n /**\n * The subsystem rows the filtered payload shows — the named subsystem and\n * its descendants; `[]` for the unfiled slice, which sits under no group.\n */\n readonly subsystems: SubsystemEntry[];\n /** The human filter line's description of what the slice is. */\n readonly label: string;\n}\n\n/**\n * Resolve `--subsystem <name>` against the flat namespace, or report the\n * refusal and return null. The reserved name `unfiled` selects the services\n * filed under no subsystem — the tree's own concept, otherwise unreachable —\n * but only while nothing in the tree claims that name: a REAL subsystem or\n * service spelled `unfiled` wins, the same concrete-name-wins precedence\n * `findInTree` already applies to service/subsystem ties. An unknown name\n * refuses `unknown-target` with close-name hints rather than succeeding\n * emptily — an empty table over a typo would read as a finished campaign —\n * and a service name refuses `invalid-option` exactly as `loam adopt\n * --subsystem` does: a service never contains other services.\n */\nexport function resolveSubsystemSlice(tree: FleetTree, name: string, json: boolean): SubsystemSlice | null {\n const hit = findInTree(tree, name);\n if (hit === null && name === \"unfiled\") {\n return {\n members: new Set<string>(tree.services.filter((s) => s.subsystem.length === 0).map((s) => s.dir)),\n subsystems: [],\n label: \"unfiled services (directly under services/)\",\n };\n }\n if (hit === null) {\n // The Set: a real subsystem named 'unfiled' would otherwise sit in the\n // hint pool twice and could be offered twice in one hint.\n const pool = [...new Set([...tree.subsystems.map((s) => s.name), \"unfiled\"])];\n fail(\n json,\n \"unknown-target\",\n `No subsystem '${name}' in the tree.` +\n closeNamesHint(name, pool, \" `loam subsystem list` shows what exists; `unfiled` selects the services filed under none.\"),\n );\n return null;\n }\n if (hit.kind === \"service\") {\n // With a SERVICE claiming the name 'unfiled' the reserved reading has no\n // spelling at all, so the refusal must say what is shadowed — otherwise\n // the message reads as loam misunderstanding the request.\n const shadowed =\n name === \"unfiled\"\n ? \" While a service claims this name, the reserved unfiled-services reading is shadowed; rename the service to reach it.\"\n : \"\";\n fail(\n json,\n \"invalid-option\",\n `--subsystem names the service '${name}' — a service never contains other services.${shadowed}`,\n );\n return null;\n }\n const sub = hit.subsystem;\n return {\n members: new Set<string>(servicesUnder(tree, sub).map((s) => s.dir)),\n subsystems: [sub, ...subsystemsUnder(tree, sub)],\n label: `subsystem '${sub.name}' (services/${sub.path.join(\"/\")}/)`,\n };\n}\n"]}
|
|
@@ -137,10 +137,6 @@ export function featureJson(docsDir, f, verification) {
|
|
|
137
137
|
verification,
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
|
-
/* ------------------------------------------------------------------ */
|
|
141
|
-
/* Verification */
|
|
142
|
-
/* ------------------------------------------------------------------ */
|
|
143
|
-
/** What the features table says about verification without N `loam verify` runs. */
|
|
144
140
|
/**
|
|
145
141
|
* One `glossary[]` row — additive payload, explicit `loam list glossary` only.
|
|
146
142
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/commands/list/json.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The `--json` rows. Separate from `./print.ts` because only this side is a\n * contract: the payload keys are frozen, the columns beside them are not.\n */\nimport { repoPath } from \"../../core/envelope/json.js\";\nimport { type CapabilityRow } from \"../../core/capabilities/rollup.js\";\nimport { type FeatureEntry } from \"../../core/repo/entries.js\";\nimport { servicesUnder } from \"../../core/repo/tree/find.js\";\nimport type { FleetTree } from \"../../core/repo/tree/walk.js\";\nimport type { OwnersJoin } from \"./campaign/owners.js\";\nimport { type ServiceView, type VerificationCell } from \"./views.js\";\n\n/**\n * The `services[]` rows: ranked and decorated under `--review-order`, plain\n * otherwise — as a VARIANT, so a call carrying both a plain list and a ranked\n * queue is unrepresentable rather than resolved by precedence. `fanIn`/\n * `reviewRank` are ADDITIVE and appear ONLY under the flag — bare\n * `loam list --json` and `--needs-work --json` stay byte-identical and\n * cost-identical, the frozen-default doctrine the explicit-only capabilities\n * section also follows. The spread keeps serviceJson at its two-param\n * contract; `reviewRank` is 1-based and equals the row's position, so the\n * array order IS the queue.\n */\nexport function serviceRows(\n docsDir: string,\n rows: ServiceView[] | { queue: ServiceView[]; fanIn: ReadonlyMap<string, number> },\n): Record<string, unknown>[] {\n if (Array.isArray(rows)) return rows.map((v) => serviceJson(docsDir, v));\n return rows.queue.map((v, i) => ({\n ...serviceJson(docsDir, v),\n fanIn: rows.fanIn.get(v.entry.id) ?? 0,\n reviewRank: i + 1,\n }));\n}\n\nexport function serviceJson(docsDir: string, v: ServiceView): Record<string, unknown> {\n const s = v.entry;\n return {\n id: s.id,\n path: repoPath(docsDir, s.dir),\n // Names from services/ down, outermost first; [] = unfiled. `path` above\n // already truthfully reflects placement — this is the same fact as data\n // instead of a string to split.\n subsystem: s.subsystem,\n has: { ...s.has, archSpec: v.archSpec },\n adrs: s.adrs,\n status: s.status,\n maturity: v.maturity,\n missing: v.missing,\n apiExpected: v.apiExpected,\n // Never omitted when true: a consumer that filters this table into a\n // worklist has to be able to tell \"checked and fine\" from \"not checkable\n // from here\", and absence reads as the first one.\n ...(v.unverifiableFromHere ? { provenance: \"unverifiable-from-here\" } : {}),\n // Additive, and only when there IS a scope — omission is the fine case\n // here, exactly as it is for `provenance` above, and `maturity` stays the\n // frozen `vouched` beside it. A dashboard counting `maturity: \"vouched\"`\n // rows keeps counting them; one that cares whether a person read the\n // document subtracts these.\n ...(s.vouchScope === \"sampled\" ? { vouchScope: \"sampled\" } : {}),\n };\n}\n\n/**\n * The subsystem rows beside the service table, sorted by path. `memberCount`\n * is TRANSITIVE — every service beneath, at any depth — matching the\n * generated views file's membership, so the two numbers a consumer can\n * cross-check never disagree about what \"in this group\" means.\n */\nexport function subsystemsJson(docsDir: string, tree: FleetTree): Record<string, unknown>[] {\n return [...tree.subsystems]\n .sort((a, b) => (a.path.join(\"/\") < b.path.join(\"/\") ? -1 : 1))\n .map((sub) => ({\n name: sub.name,\n path: repoPath(docsDir, sub.dir),\n title: sub.meta.title ?? null,\n memberCount: servicesUnder(tree, sub).length,\n }));\n}\n\n/**\n * The additive `owners` payload key under `--owners` — the join result as a\n * contract: `path` (the file exactly as the user named it), `teams[]` (owner\n * plus that team's services, in the LISTING's own filtered-and-ordered row\n * order, so each array is that team's campaign worklist), `unowned[]` (rows\n * no rule matched — explicit, because absence would read as owned-somewhere),\n * and `skippedRules[]` (recognised rules outside the implemented CODEOWNERS\n * subset, each with its line — reported, never guessed at). Key spellings\n * frozen once shipped; the join itself lives in campaign/owners.ts.\n *\n * The service arrays carry IDS. On a `subsystem.name-collision` fleet —\n * already an error finding — two rows can share an id, so a consumer cannot\n * tell them apart here; if that ever needs disambiguating, the fix is a new\n * ADDITIVE key carrying paths, never a change to these.\n */\nexport function ownersJson(join: OwnersJoin): Record<string, unknown> {\n return {\n path: join.path,\n teams: join.teams.map((team) => ({ owner: team.owner, services: team.services.map((row) => row.id) })),\n unowned: join.unowned.map((row) => row.id),\n skippedRules: join.skipped.map((rule) => ({ line: rule.line, pattern: rule.pattern })),\n };\n}\n\n/**\n * One `capabilities[]` row — additive payload, explicit `loam list\n * capabilities` only, and diff-stable: the rollup already sorts rows,\n * realizedBy and statuses' keys deterministically, and this projection adds\n * nothing that could vary between machines. Optional keys are omitted rather\n * than nulled so a declaration that never carried a description does not grow\n * one in the diff.\n */\nexport function capabilityJson(row: CapabilityRow): Record<string, unknown> {\n return {\n id: row.id,\n ...(row.description !== undefined ? { description: row.description } : {}),\n ...(row.owner !== undefined ? { owner: row.owner } : {}),\n realizedBy: row.realizedBy,\n services: row.services,\n statuses: row.statuses,\n // Present only for a capability that HAS a document, and absent rather than\n // `[]` for one that does not — the same optional-key rule the two fields\n // above follow, and here it carries a distinction a reader needs: an empty\n // array means the document declares no requirements, while no key at all\n // means there is no document to declare any.\n //\n // Each row inside carries `realizedBy` (the service requirements whose\n // `Realizes:` line names it) and `keptBy` (the flows whose `#cap-`/`#req-`\n // tags resolve to it) — two independent corpora, NEITHER derived from the\n // other, because a cross-service promise can only be kept by a flow and a\n // per-service one is normally kept by a requirement. `keptBy` follows the\n // same three-state rule one level down and `rollup.ts` states it: absent\n // means nobody looked, `[]` means loam looked and no flow keeps it. The\n // payload's own `useCases.unreadable` says which of the two absences it is.\n ...(row.requirements === undefined ? {} : { requirements: row.requirements }),\n };\n}\n\nexport function featureJson(\n docsDir: string,\n f: FeatureEntry,\n verification: VerificationCell | null,\n): Record<string, unknown> {\n return {\n id: f.id,\n dirName: f.dirName,\n path: repoPath(docsDir, f.dir),\n archived: f.archived,\n services: f.services,\n has: f.has,\n verification,\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Verification */\n/* ------------------------------------------------------------------ */\n\n/** What the features table says about verification without N `loam verify` runs. */\n\n/**\n * One `glossary[]` row — additive payload, explicit `loam list glossary` only.\n *\n * `linkedBy` is the whole reason the section exists: \"which documents use this\n * term\" is a grep today and a join here, and it is the same answer\n * `glossary.unlinked` grades. Repo-relative and sorted by the index itself, so\n * the payload is diff-stable across machines. Empty means loam read every\n * authored document and none of them cites the term — never \"nobody looked\",\n * which is what the sibling `links.unreadable` list is for.\n */\nexport function glossaryJson(term: { id: string; path: string }, linkedBy: string[], docsDir: string): Record<string, unknown> {\n return { id: term.id, path: repoPath(docsDir, term.path), linkedBy };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/commands/list/json.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAsB,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAqB,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAG7D,OAAO,EAA2C,MAAM,YAAY,CAAC;AAErE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CACzB,OAAe,EACf,IAAkF;IAElF,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/B,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;QACtC,UAAU,EAAE,CAAC,GAAG,CAAC;KAClB,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,CAAc;IACzD,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;IAClB,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC;QAC9B,yEAAyE;QACzE,wEAAwE;QACxE,gCAAgC;QAChC,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;QACvC,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,qEAAqE;QACrE,yEAAyE;QACzE,kDAAkD;QAClD,GAAG,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,wBAAwB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,uEAAuE;QACvE,0EAA0E;QAC1E,yEAAyE;QACzE,qEAAqE;QACrE,4BAA4B;QAC5B,GAAG,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,IAAe;IAC7D,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;SACxB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SAC9D,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACb,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC;QAChC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI;QAC7B,WAAW,EAAE,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM;KAC7C,CAAC,CAAC,CAAC;AACR,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,UAAU,CAAC,IAAgB;IACzC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACtG,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;KACvF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,GAAkB;IAC/C,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,4EAA4E;QAC5E,yEAAyE;QACzE,2EAA2E;QAC3E,yEAAyE;QACzE,6CAA6C;QAC7C,EAAE;QACF,uEAAuE;QACvE,2EAA2E;QAC3E,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,yEAAyE;QACzE,wEAAwE;QACxE,4EAA4E;QAC5E,GAAG,CAAC,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC;KAC9E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,OAAe,EACf,CAAe,EACf,YAAqC;IAErC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC;QAC9B,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,YAAY;KACb,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,IAAkC,EAAE,QAAkB,EAAE,OAAe;IAClG,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC;AACvE,CAAC","sourcesContent":["/**\n * The `--json` rows. Separate from `./print.ts` because only this side is a\n * contract: the payload keys are frozen, the columns beside them are not.\n */\nimport { repoPath } from \"../../core/envelope/json.js\";\nimport { type CapabilityRow } from \"../../core/capabilities/rollup.js\";\nimport { type FeatureEntry } from \"../../core/repo/entries.js\";\nimport { servicesUnder } from \"../../core/repo/tree/find.js\";\nimport type { FleetTree } from \"../../core/repo/tree/walk.js\";\nimport type { OwnersJoin } from \"./campaign/owners.js\";\nimport { type ServiceView, type VerificationCell } from \"./views.js\";\n\n/**\n * The `services[]` rows: ranked and decorated under `--review-order`, plain\n * otherwise — as a VARIANT, so a call carrying both a plain list and a ranked\n * queue is unrepresentable rather than resolved by precedence. `fanIn`/\n * `reviewRank` are ADDITIVE and appear ONLY under the flag — bare\n * `loam list --json` and `--needs-work --json` stay byte-identical and\n * cost-identical, the frozen-default doctrine the explicit-only capabilities\n * section also follows. The spread keeps serviceJson at its two-param\n * contract; `reviewRank` is 1-based and equals the row's position, so the\n * array order IS the queue.\n */\nexport function serviceRows(\n docsDir: string,\n rows: ServiceView[] | { queue: ServiceView[]; fanIn: ReadonlyMap<string, number> },\n): Record<string, unknown>[] {\n if (Array.isArray(rows)) return rows.map((v) => serviceJson(docsDir, v));\n return rows.queue.map((v, i) => ({\n ...serviceJson(docsDir, v),\n fanIn: rows.fanIn.get(v.entry.id) ?? 0,\n reviewRank: i + 1,\n }));\n}\n\nexport function serviceJson(docsDir: string, v: ServiceView): Record<string, unknown> {\n const s = v.entry;\n return {\n id: s.id,\n path: repoPath(docsDir, s.dir),\n // Names from services/ down, outermost first; [] = unfiled. `path` above\n // already truthfully reflects placement — this is the same fact as data\n // instead of a string to split.\n subsystem: s.subsystem,\n has: { ...s.has, archSpec: v.archSpec },\n adrs: s.adrs,\n status: s.status,\n maturity: v.maturity,\n missing: v.missing,\n apiExpected: v.apiExpected,\n // Never omitted when true: a consumer that filters this table into a\n // worklist has to be able to tell \"checked and fine\" from \"not checkable\n // from here\", and absence reads as the first one.\n ...(v.unverifiableFromHere ? { provenance: \"unverifiable-from-here\" } : {}),\n // Additive, and only when there IS a scope — omission is the fine case\n // here, exactly as it is for `provenance` above, and `maturity` stays the\n // frozen `vouched` beside it. A dashboard counting `maturity: \"vouched\"`\n // rows keeps counting them; one that cares whether a person read the\n // document subtracts these.\n ...(s.vouchScope === \"sampled\" ? { vouchScope: \"sampled\" } : {}),\n };\n}\n\n/**\n * The subsystem rows beside the service table, sorted by path. `memberCount`\n * is TRANSITIVE — every service beneath, at any depth — matching the\n * generated views file's membership, so the two numbers a consumer can\n * cross-check never disagree about what \"in this group\" means.\n */\nexport function subsystemsJson(docsDir: string, tree: FleetTree): Record<string, unknown>[] {\n return [...tree.subsystems]\n .sort((a, b) => (a.path.join(\"/\") < b.path.join(\"/\") ? -1 : 1))\n .map((sub) => ({\n name: sub.name,\n path: repoPath(docsDir, sub.dir),\n title: sub.meta.title ?? null,\n memberCount: servicesUnder(tree, sub).length,\n }));\n}\n\n/**\n * The additive `owners` payload key under `--owners` — the join result as a\n * contract: `path` (the file exactly as the user named it), `teams[]` (owner\n * plus that team's services, in the LISTING's own filtered-and-ordered row\n * order, so each array is that team's campaign worklist), `unowned[]` (rows\n * no rule matched — explicit, because absence would read as owned-somewhere),\n * and `skippedRules[]` (recognised rules outside the implemented CODEOWNERS\n * subset, each with its line — reported, never guessed at). Key spellings\n * frozen once shipped; the join itself lives in campaign/owners.ts.\n *\n * The service arrays carry IDS. On a `subsystem.name-collision` fleet —\n * already an error finding — two rows can share an id, so a consumer cannot\n * tell them apart here; if that ever needs disambiguating, the fix is a new\n * ADDITIVE key carrying paths, never a change to these.\n */\nexport function ownersJson(join: OwnersJoin): Record<string, unknown> {\n return {\n path: join.path,\n teams: join.teams.map((team) => ({ owner: team.owner, services: team.services.map((row) => row.id) })),\n unowned: join.unowned.map((row) => row.id),\n skippedRules: join.skipped.map((rule) => ({ line: rule.line, pattern: rule.pattern })),\n };\n}\n\n/**\n * One `capabilities[]` row — additive payload, explicit `loam list\n * capabilities` only, and diff-stable: the rollup already sorts rows,\n * realizedBy and statuses' keys deterministically, and this projection adds\n * nothing that could vary between machines. Optional keys are omitted rather\n * than nulled so a declaration that never carried a description does not grow\n * one in the diff.\n */\nexport function capabilityJson(row: CapabilityRow): Record<string, unknown> {\n return {\n id: row.id,\n ...(row.description !== undefined ? { description: row.description } : {}),\n ...(row.owner !== undefined ? { owner: row.owner } : {}),\n realizedBy: row.realizedBy,\n services: row.services,\n statuses: row.statuses,\n // Present only for a capability that HAS a document, and absent rather than\n // `[]` for one that does not — the same optional-key rule the two fields\n // above follow, and here it carries a distinction a reader needs: an empty\n // array means the document declares no requirements, while no key at all\n // means there is no document to declare any.\n //\n // Each row inside carries `realizedBy` (the service requirements whose\n // `Realizes:` line names it) and `keptBy` (the flows whose `#cap-`/`#req-`\n // tags resolve to it) — two independent corpora, NEITHER derived from the\n // other, because a cross-service promise can only be kept by a flow and a\n // per-service one is normally kept by a requirement. `keptBy` follows the\n // same three-state rule one level down and `rollup.ts` states it: absent\n // means nobody looked, `[]` means loam looked and no flow keeps it. The\n // payload's own `useCases.unreadable` says which of the two absences it is.\n ...(row.requirements === undefined ? {} : { requirements: row.requirements }),\n };\n}\n\nexport function featureJson(\n docsDir: string,\n f: FeatureEntry,\n verification: VerificationCell | null,\n): Record<string, unknown> {\n return {\n id: f.id,\n dirName: f.dirName,\n path: repoPath(docsDir, f.dir),\n archived: f.archived,\n services: f.services,\n has: f.has,\n verification,\n };\n}\n\n/**\n * One `glossary[]` row — additive payload, explicit `loam list glossary` only.\n *\n * `linkedBy` is the whole reason the section exists: \"which documents use this\n * term\" is a grep today and a join here, and it is the same answer\n * `glossary.unlinked` grades. Repo-relative and sorted by the index itself, so\n * the payload is diff-stable across machines. Empty means loam read every\n * authored document and none of them cites the term — never \"nobody looked\",\n * which is what the sibling `links.unreadable` list is for.\n */\nexport function glossaryJson(term: { id: string; path: string }, linkedBy: string[], docsDir: string): Record<string, unknown> {\n return { id: term.id, path: repoPath(docsDir, term.path), linkedBy };\n}\n"]}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { emitJson, fail, repoPath, reportNoConfig } from "../../core/envelope/json.js";
|
|
1
|
+
import { configOrRefuse, emitJson, fail, repoPath } from "../../core/envelope/json.js";
|
|
3
2
|
import { maturityRollup } from "../../core/vocabulary/maturity.js";
|
|
4
3
|
import { FleetContext } from "../../core/fleet-context.js";
|
|
5
4
|
import { DocsRepoUnavailableError } from "../../core/repo/state.js";
|
|
@@ -17,7 +16,8 @@ import { printCapabilities, printFeatures, printGlossary, printOwners, printServ
|
|
|
17
16
|
import { fanInByService, reviewLandscape, reviewOrder } from "./review.js";
|
|
18
17
|
import { resolveSubsystemSlice } from "./campaign/campaign.js";
|
|
19
18
|
import { ownersJoin } from "./campaign/owners.js";
|
|
20
|
-
|
|
19
|
+
import { suitesSection } from "./suites/suites.js";
|
|
20
|
+
const SECTIONS = ["services", "features", "capabilities", "glossary", "suites"];
|
|
21
21
|
/**
|
|
22
22
|
* What a bare `loam list` shows. `capabilities` is explicit-only, NEVER part
|
|
23
23
|
* of this default: the no-argument output and its `--json` payload are a
|
|
@@ -27,7 +27,8 @@ const DEFAULT_SECTIONS = ["services", "features"];
|
|
|
27
27
|
export function registerList(program) {
|
|
28
28
|
program
|
|
29
29
|
.command("list")
|
|
30
|
-
.argument("[section]", "services | features | capabilities | glossary (default: services + features)")
|
|
30
|
+
.argument("[section]", "services | features | capabilities | glossary | suites (default: services + features)")
|
|
31
|
+
.argument("[name]", "suites only: the one suite to show")
|
|
31
32
|
.description("List the services and features in the docs repo")
|
|
32
33
|
.option("--json", "emit the machine contract instead of the human view")
|
|
33
34
|
.option("--archived", "include archived features")
|
|
@@ -35,7 +36,7 @@ export function registerList(program) {
|
|
|
35
36
|
.option("--review-order", "with --needs-work: order the worklist by blast radius — services the most other services depend on first")
|
|
36
37
|
.option("--subsystem <name>", "services only: limit the listing to services filed under this subsystem, at any depth ('unfiled' selects the ones filed under none, while nothing in the tree claims that name)")
|
|
37
38
|
.option("--owners <path>", "services only: group the listing by owning team from this CODEOWNERS file, resolved from the current directory (directory-pattern rules only; unsupported rules are listed as skipped, never guessed)")
|
|
38
|
-
.action(async (section, opts) => {
|
|
39
|
+
.action(async (section, name, opts) => {
|
|
39
40
|
const json = opts.json === true;
|
|
40
41
|
// The campaign flags grade services, so — exactly like --needs-work —
|
|
41
42
|
// they narrow a bare `loam list` to the services section instead of
|
|
@@ -51,8 +52,13 @@ export function registerList(program) {
|
|
|
51
52
|
fail(json, "invalid-option", `Unknown section '${section}'. Expected: ${SECTIONS.join(" | ")}.`);
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
// Anywhere but suites a name would be silently ignored: refused, as commander's excess-argument error was.
|
|
56
|
+
if (name !== undefined && section !== "suites") {
|
|
57
|
+
fail(json, "invalid-option", `Only the suites section takes a name; drop '${name}'.`);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (opts.needsWork && (section === "features" || section === "suites")) {
|
|
61
|
+
fail(json, "invalid-option", `--needs-work is the service adoption worklist; drop the '${section}' section.`);
|
|
56
62
|
return;
|
|
57
63
|
}
|
|
58
64
|
if (campaign && section !== undefined && section !== "services") {
|
|
@@ -66,18 +72,16 @@ export function registerList(program) {
|
|
|
66
72
|
fail(json, "invalid-option", "--review-order sorts the adoption worklist; add --needs-work.");
|
|
67
73
|
return;
|
|
68
74
|
}
|
|
69
|
-
const
|
|
70
|
-
if (
|
|
71
|
-
reportNoConfig(json, loaded);
|
|
75
|
+
const config = await configOrRefuse(json);
|
|
76
|
+
if (config === null)
|
|
72
77
|
return;
|
|
73
|
-
}
|
|
74
|
-
const config = loaded.config;
|
|
75
78
|
const { docsDir } = config;
|
|
76
79
|
// A docsDir that is not a docs repo is refused, never rendered as an empty
|
|
77
80
|
// fleet — the whole point of the gate (see docs-repo-gate.ts).
|
|
78
81
|
// `list features` alone does not need services/, so it asks for less;
|
|
79
|
-
// the capability rollup walks every service's spec files, so it asks for
|
|
80
|
-
|
|
82
|
+
// the capability rollup walks every service's spec files, so it asks for
|
|
83
|
+
// them, and a suite resolves its participants against them.
|
|
84
|
+
const needsServices = wanted.some((s) => s !== "features");
|
|
81
85
|
if (!docsRepoReady(json, docsDir, needsServices ? "services" : "docs"))
|
|
82
86
|
return;
|
|
83
87
|
try {
|
|
@@ -121,7 +125,7 @@ export function registerList(program) {
|
|
|
121
125
|
? await listFeatures(docsDir, { includeArchived: opts.archived }, fleet)
|
|
122
126
|
: undefined;
|
|
123
127
|
const verification = features
|
|
124
|
-
? await Promise.all(features.map((f) => featureVerification(docsDir, f)))
|
|
128
|
+
? await Promise.all(features.map((f) => featureVerification(docsDir, f, fleet)))
|
|
125
129
|
: undefined;
|
|
126
130
|
// The capability section: the vocabulary's own verdict decides the shape.
|
|
127
131
|
// An INVALID file refuses with `repository-unavailable` — an
|
|
@@ -188,14 +192,23 @@ export function registerList(program) {
|
|
|
188
192
|
term,
|
|
189
193
|
linkedBy: citations === undefined ? [] : citations.linkersOf(term.path),
|
|
190
194
|
}));
|
|
191
|
-
|
|
195
|
+
// Use cases by `#suite-` tag and what each suite needs up; `null` = already refused.
|
|
196
|
+
const suites = wanted.includes("suites") ? await suitesSection({ docsDir, name, json, fleet }) : undefined;
|
|
197
|
+
if (suites === null)
|
|
198
|
+
return;
|
|
199
|
+
// Every row that still owes something — `missing` is non-empty below
|
|
200
|
+
// `vouched` by construction, and at `vouched` exactly when a stamped
|
|
201
|
+
// document moved under its vouch. The test used to be the rung alone,
|
|
202
|
+
// so a service whose spec was edited after the person read it dropped
|
|
203
|
+
// off the worklist and the footer said "nothing to do".
|
|
204
|
+
const worklist = (shown ?? []).filter((v) => v.missing.length > 0);
|
|
192
205
|
// The ranked review queue, derived never stored: fan-in is computed
|
|
193
206
|
// FLEET-WIDE (the joins need every service's slice anyway — and a
|
|
194
207
|
// --subsystem filter must never change a service's count, only which
|
|
195
208
|
// rows appear) while ranks are assigned over the WORKLIST only — a
|
|
196
|
-
//
|
|
197
|
-
// the queue. The worklist is already sliced, so under
|
|
198
|
-
// ranks are contiguous within the filtered set.
|
|
209
|
+
// service that owes nothing needs no review, and ranking it would put
|
|
210
|
+
// gaps in the queue. The worklist is already sliced, so under
|
|
211
|
+
// --subsystem the ranks are contiguous within the filtered set.
|
|
199
212
|
let ranked;
|
|
200
213
|
if (opts.reviewOrder === true && services !== undefined) {
|
|
201
214
|
const fanIn = await fanInByService(services, fleet, land ?? null);
|
|
@@ -260,6 +273,7 @@ export function registerList(program) {
|
|
|
260
273
|
// document and none cites the term; this key is how a reader tells
|
|
261
274
|
// that from "one of them would not decode".
|
|
262
275
|
...(citations ? { links: { unreadable: citations.unreadable } } : {}),
|
|
276
|
+
...suites?.payload,
|
|
263
277
|
// The use-case corpus's own health, beside the rows it decorates —
|
|
264
278
|
// `status --json` and `delta --json` already spell this key this
|
|
265
279
|
// way. It is what makes an absent `keptBy` legible: `unreadable:
|
|
@@ -285,10 +299,10 @@ export function registerList(program) {
|
|
|
285
299
|
}
|
|
286
300
|
if (owned !== undefined && rows !== undefined && shown !== undefined) {
|
|
287
301
|
if (opts.needsWork && rows.length === 0) {
|
|
288
|
-
// printWorklist's own affordance
|
|
289
|
-
// empty owner groups would answer
|
|
290
|
-
// saying there is none.
|
|
291
|
-
|
|
302
|
+
// printWorklist's own affordance — called rather than respelled —
|
|
303
|
+
// kept under the grouping flag: empty owner groups would answer
|
|
304
|
+
// "who owns the work" without saying there is none.
|
|
305
|
+
printWorklist([], shown.length);
|
|
292
306
|
return;
|
|
293
307
|
}
|
|
294
308
|
const kind = opts.needsWork
|
|
@@ -326,6 +340,7 @@ export function registerList(program) {
|
|
|
326
340
|
console.log("no glossary/ — the fleet defines no domain terms");
|
|
327
341
|
}
|
|
328
342
|
}
|
|
343
|
+
suites?.print();
|
|
329
344
|
}
|
|
330
345
|
catch (err) {
|
|
331
346
|
if (err instanceof DocsRepoUnavailableError) {
|