@ybotok/loam 0.2.0-alpha.1 → 0.2.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3448 -0
- package/COMPARISON.md +91 -3
- package/CONTRIBUTING.md +37 -0
- package/MIGRATING-from-OpenSpec.md +47 -23
- package/QUICKSTART.md +189 -12
- package/README.md +274 -65
- package/ROADMAP.md +572 -31
- package/SCHEMA.md +1709 -155
- package/WORKFLOW.md +298 -72
- 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/adopt/render.js +50 -9
- package/dist/commands/adopt/render.js.map +1 -1
- package/dist/commands/archive/archive.js +16 -19
- package/dist/commands/archive/archive.js.map +1 -1
- package/dist/commands/archive/closing.js +42 -0
- package/dist/commands/archive/closing.js.map +1 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js +36 -42
- 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 +77 -43
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -1
- package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
- package/dist/commands/archive/plan/document/head.js +151 -0
- package/dist/commands/archive/plan/document/head.js.map +1 -0
- package/dist/commands/archive/plan/document/links.js +284 -0
- package/dist/commands/archive/plan/document/links.js.map +1 -0
- package/dist/commands/archive/plan/document/run.js +136 -0
- package/dist/commands/archive/plan/document/run.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +21 -19
- package/dist/commands/archive/plan/gate.js.map +1 -1
- package/dist/commands/archive/plan/landscape.js +167 -30
- package/dist/commands/archive/plan/landscape.js.map +1 -1
- package/dist/commands/archive/plan/model/extending.js +85 -0
- package/dist/commands/archive/plan/model/extending.js.map +1 -0
- package/dist/commands/archive/plan/refusal.js +14 -19
- package/dist/commands/archive/plan/refusal.js.map +1 -1
- package/dist/commands/archive/plan/specs.js +137 -56
- package/dist/commands/archive/plan/specs.js.map +1 -1
- package/dist/commands/archive/plan/state.js +3 -0
- package/dist/commands/archive/plan/state.js.map +1 -1
- package/dist/commands/archive/run.js +134 -30
- 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 +85 -18
- package/dist/commands/context/context.js.map +1 -1
- package/dist/commands/context/print.js +29 -7
- package/dist/commands/context/print.js.map +1 -1
- package/dist/commands/delta/delta.js +102 -14
- package/dist/commands/delta/delta.js.map +1 -1
- package/dist/commands/delta/print.js +17 -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/doctor.js +60 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain/explain.js +89 -13
- package/dist/commands/explain/explain.js.map +1 -1
- package/dist/commands/explore.js +16 -10
- 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 +5 -7
- package/dist/commands/list/json.js.map +1 -1
- package/dist/commands/list/list.js +44 -29
- package/dist/commands/list/list.js.map +1 -1
- package/dist/commands/list/print.js +52 -9
- 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 +37 -34
- 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 +158 -13
- package/dist/commands/seed/plan.js.map +1 -1
- package/dist/commands/seed/seed.js +13 -11
- package/dist/commands/seed/seed.js.map +1 -1
- package/dist/commands/show/feature.js +9 -5
- package/dist/commands/show/feature.js.map +1 -1
- package/dist/commands/show/introduced.js +157 -0
- package/dist/commands/show/introduced.js.map +1 -0
- package/dist/commands/show/marks.js +35 -6
- package/dist/commands/show/marks.js.map +1 -1
- package/dist/commands/show/service.js +41 -33
- package/dist/commands/show/service.js.map +1 -1
- package/dist/commands/show/show.js +17 -7
- package/dist/commands/show/show.js.map +1 -1
- package/dist/commands/status/fleet-next.js +90 -0
- package/dist/commands/status/fleet-next.js.map +1 -0
- package/dist/commands/status/json.js +2 -0
- package/dist/commands/status/json.js.map +1 -1
- package/dist/commands/status/print.js +89 -37
- 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 +103 -23
- 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 +106 -46
- 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 +289 -74
- package/dist/commands/subsystem/sync.js.map +1 -1
- package/dist/commands/subsystem/txn/exclude.js +132 -0
- package/dist/commands/subsystem/txn/exclude.js.map +1 -0
- package/dist/commands/subsystem/txn/links.js +128 -0
- package/dist/commands/subsystem/txn/links.js.map +1 -0
- package/dist/commands/subsystem/txn/report.js +174 -0
- package/dist/commands/subsystem/txn/report.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +147 -45
- package/dist/commands/subsystem/txn/txn.js.map +1 -1
- package/dist/commands/subsystem/txn/views.js +200 -21
- package/dist/commands/subsystem/txn/views.js.map +1 -1
- package/dist/commands/tasks/actions.js +107 -0
- package/dist/commands/tasks/actions.js.map +1 -0
- package/dist/commands/tasks/render.js +253 -0
- package/dist/commands/tasks/render.js.map +1 -0
- package/dist/commands/tasks/tasks.js +119 -0
- package/dist/commands/tasks/tasks.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +42 -26
- package/dist/commands/unarchive/manifest.js.map +1 -1
- package/dist/commands/unarchive/restore.js +83 -33
- 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 +78 -27
- package/dist/commands/validate/arch-coverage.js.map +1 -1
- package/dist/commands/validate/checks/fleet-shape.js +34 -126
- 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/introduced.js +102 -0
- package/dist/commands/validate/checks/introduced.js.map +1 -0
- 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 +11 -2
- package/dist/commands/validate/checks/sources.js.map +1 -1
- package/dist/commands/validate/coverage/covers-after.js +105 -0
- package/dist/commands/validate/coverage/covers-after.js.map +1 -0
- package/dist/commands/validate/feature.js +26 -20
- package/dist/commands/validate/feature.js.map +1 -1
- package/dist/commands/validate/fleet/census.js +37 -13
- package/dist/commands/validate/fleet/census.js.map +1 -1
- package/dist/commands/validate/fleet/landscape.js +144 -126
- package/dist/commands/validate/fleet/landscape.js.map +1 -1
- package/dist/commands/validate/fleet/load.js +66 -0
- package/dist/commands/validate/fleet/load.js.map +1 -1
- package/dist/commands/validate/fleet/map/attest.js +98 -0
- package/dist/commands/validate/fleet/map/attest.js.map +1 -0
- package/dist/commands/validate/fleet/map/bindings.js +107 -0
- package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
- package/dist/commands/validate/fleet/map/consumers.js +244 -0
- package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
- package/dist/commands/validate/fleet/map/isolation.js +116 -0
- package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
- package/dist/commands/validate/fleet/map/usecases.js +54 -0
- package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/obligations.js +44 -14
- package/dist/commands/validate/fleet/obligations.js.map +1 -1
- package/dist/commands/validate/fleet/scorecard/print.js +10 -2
- 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/place.js.map +1 -1
- package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
- package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +50 -15
- package/dist/commands/validate/fleet/views/ids.js.map +1 -1
- package/dist/commands/validate/fleet/views/projects.js +278 -0
- package/dist/commands/validate/fleet/views/projects.js.map +1 -0
- package/dist/commands/validate/fleet/views/root-documents.js +83 -0
- package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +40 -47
- 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/render/repeats.js +63 -0
- package/dist/commands/validate/render/repeats.js.map +1 -0
- package/dist/commands/validate/render/rollups.js +115 -0
- package/dist/commands/validate/render/rollups.js.map +1 -0
- package/dist/commands/validate/render/text.js +199 -0
- package/dist/commands/validate/render/text.js.map +1 -0
- package/dist/commands/validate/report.js +36 -160
- 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 +21 -107
- 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 +36 -14
- 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/model/diverged.js +226 -0
- package/dist/commands/validate/service/model/diverged.js.map +1 -0
- package/dist/commands/validate/service/model/grade.js +163 -0
- package/dist/commands/validate/service/model/grade.js.map +1 -0
- package/dist/commands/validate/service/service.js +121 -61
- package/dist/commands/validate/service/service.js.map +1 -1
- package/dist/commands/validate/service/specs.js +88 -28
- package/dist/commands/validate/service/specs.js.map +1 -1
- package/dist/commands/validate/service/spine.js +38 -3
- package/dist/commands/validate/service/spine.js.map +1 -1
- package/dist/commands/validate/service/usecases/tags.js +113 -0
- package/dist/commands/validate/service/usecases/tags.js.map +1 -0
- package/dist/commands/validate/service/usecases/usecases.js +209 -0
- package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/validate.js +85 -60
- 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 +55 -52
- 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 +81 -106
- package/dist/core/agent/agents-md/command-map.js.map +1 -1
- package/dist/core/agent/agents-md/map/explain.js +21 -9
- package/dist/core/agent/agents-md/map/explain.js.map +1 -1
- package/dist/core/agent/agents-md/map/lenses/context.js +17 -8
- 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 +24 -8
- package/dist/core/agent/agents-md/map/status.js.map +1 -1
- package/dist/core/agent/agents-md/map/subsystem.js +80 -8
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -1
- package/dist/core/agent/agents-md/map/usecases.js +88 -10
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -1
- package/dist/core/agent/agents-md/refusals.js +49 -22
- package/dist/core/agent/agents-md/refusals.js.map +1 -1
- package/dist/core/agent/agents-md.js +39 -6
- 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/protocol.js +1 -1
- package/dist/core/agent/protocol.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/support/report.js +46 -5
- package/dist/core/agent/support/report.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 +158 -11
- package/dist/core/agent/workflows/adopt.js.map +1 -1
- package/dist/core/agent/workflows/check.js +78 -39
- package/dist/core/agent/workflows/check.js.map +1 -1
- package/dist/core/agent/workflows/closing.js +88 -27
- package/dist/core/agent/workflows/closing.js.map +1 -1
- package/dist/core/agent/workflows/feature.js +128 -13
- package/dist/core/agent/workflows/feature.js.map +1 -1
- package/dist/core/agent/workflows/implement.js +96 -13
- package/dist/core/agent/workflows/implement.js.map +1 -1
- package/dist/core/agent/workflows/reference/authoring.js +106 -4
- 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/drawing/drawing.js +253 -0
- package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
- package/dist/core/agent/workflows/reference/reference.js +6 -3
- package/dist/core/agent/workflows/reference/reference.js.map +1 -1
- package/dist/core/agent/workflows/reference/spine.js +68 -27
- 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 +32 -50
- package/dist/core/asyncapi/merge/markers.js.map +1 -1
- package/dist/core/asyncapi/merge/merge.js +33 -53
- package/dist/core/asyncapi/merge/merge.js.map +1 -1
- package/dist/core/asyncapi/merge/pin.js +12 -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 +96 -36
- package/dist/core/brief/brief.js.map +1 -1
- package/dist/core/brief/checks.js +138 -3
- package/dist/core/brief/checks.js.map +1 -1
- package/dist/core/brief/landscape.js +209 -130
- package/dist/core/brief/landscape.js.map +1 -1
- package/dist/core/brief/map/extend.js +84 -0
- package/dist/core/brief/map/extend.js.map +1 -0
- package/dist/core/brief/map/owed.js +266 -0
- package/dist/core/brief/map/owed.js.map +1 -0
- package/dist/core/brief/targets.js +109 -31
- package/dist/core/brief/targets.js.map +1 -1
- package/dist/core/brief/unchecked.js +14 -3
- package/dist/core/brief/unchecked.js.map +1 -1
- package/dist/core/c4/arch.js +90 -182
- package/dist/core/c4/arch.js.map +1 -1
- package/dist/core/c4/direction/direction.js +114 -0
- package/dist/core/c4/direction/direction.js.map +1 -0
- package/dist/core/c4/likec4.js +169 -14
- 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/deployment.js +160 -0
- package/dist/core/c4/parsed/deployment.js.map +1 -0
- package/dist/core/c4/parsed/dynamic-views.js.map +1 -1
- package/dist/core/c4/parsed/values.js +54 -1
- package/dist/core/c4/parsed/values.js.map +1 -1
- package/dist/core/c4/parsed/view-ids.js +39 -1
- package/dist/core/c4/parsed/view-ids.js.map +1 -1
- package/dist/core/c4/prefetch/fleet.js +134 -0
- package/dist/core/c4/prefetch/fleet.js.map +1 -0
- package/dist/core/c4/project/architecture.js +123 -7
- package/dist/core/c4/project/architecture.js.map +1 -1
- package/dist/core/c4/project/batch.js +140 -0
- package/dist/core/c4/project/batch.js.map +1 -0
- package/dist/core/c4/project/documents.js +43 -12
- package/dist/core/c4/project/documents.js.map +1 -1
- package/dist/core/c4/project/load.js +79 -43
- package/dist/core/c4/project/load.js.map +1 -1
- package/dist/core/c4/project/staged.js +277 -0
- package/dist/core/c4/project/staged.js.map +1 -0
- package/dist/core/c4/resolve/attested.js +0 -0
- package/dist/core/c4/resolve/attested.js.map +1 -0
- package/dist/core/c4/resolve/external.js +51 -0
- package/dist/core/c4/resolve/external.js.map +1 -0
- package/dist/core/c4/resolve/service.js +78 -17
- package/dist/core/c4/resolve/service.js.map +1 -1
- package/dist/core/c4/resolve/steps.js +290 -0
- package/dist/core/c4/resolve/steps.js.map +1 -0
- package/dist/core/c4/resolve/systems.js +154 -0
- package/dist/core/c4/resolve/systems.js.map +1 -0
- package/dist/core/c4/root-project/exclude.js +352 -0
- package/dist/core/c4/root-project/exclude.js.map +1 -0
- package/dist/core/c4/seed/template.js +65 -1
- package/dist/core/c4/seed/template.js.map +1 -1
- package/dist/core/c4/service-model/created/models.js +96 -0
- package/dist/core/c4/service-model/created/models.js.map +1 -0
- package/dist/core/c4/service-model/documents.js +47 -0
- package/dist/core/c4/service-model/documents.js.map +1 -0
- package/dist/core/c4/service-model/fleet/extending.js +82 -0
- package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
- package/dist/core/c4/service-model/load.js +165 -0
- package/dist/core/c4/service-model/load.js.map +1 -0
- package/dist/core/c4/service-model/renderer.js +128 -0
- package/dist/core/c4/service-model/renderer.js.map +1 -0
- package/dist/core/c4/service-model/shape.js +106 -0
- package/dist/core/c4/service-model/shape.js.map +1 -0
- package/dist/core/c4/service-model/slice.js +188 -0
- package/dist/core/c4/service-model/slice.js.map +1 -0
- package/dist/core/c4/source-mask.js +297 -10
- package/dist/core/c4/source-mask.js.map +1 -1
- package/dist/core/c4/source-scan.js +222 -141
- package/dist/core/c4/source-scan.js.map +1 -1
- package/dist/core/c4/splice/authored-source.js +79 -13
- package/dist/core/c4/splice/authored-source.js.map +1 -1
- package/dist/core/c4/splice/contract.js +20 -0
- package/dist/core/c4/splice/contract.js.map +1 -1
- package/dist/core/c4/splice/delta-blocks.js +20 -20
- package/dist/core/c4/splice/delta-blocks.js.map +1 -1
- package/dist/core/c4/splice/identity/declared.js +87 -0
- package/dist/core/c4/splice/identity/declared.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +37 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -1
- package/dist/core/c4/splice/identity/existing.js +80 -0
- package/dist/core/c4/splice/identity/existing.js.map +1 -0
- package/dist/core/c4/splice/identity/interior.js +80 -0
- package/dist/core/c4/splice/identity/interior.js.map +1 -0
- package/dist/core/c4/splice/identity/owner.js +50 -0
- package/dist/core/c4/splice/identity/owner.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +182 -114
- package/dist/core/c4/splice/landscape-merge.js.map +1 -1
- package/dist/core/c4/splice/model/merge.js +151 -0
- package/dist/core/c4/splice/model/merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +160 -56
- package/dist/core/c4/splice/placement.js.map +1 -1
- package/dist/core/c4/splice/text/spot.js +131 -0
- package/dist/core/c4/splice/text/spot.js.map +1 -0
- package/dist/core/c4/workspace.js +13 -19
- 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/delta/uncovered.js +2 -2
- package/dist/core/capabilities/delta/uncovered.js.map +1 -1
- package/dist/core/capabilities/findings.js +18 -22
- 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/calls/called.js +52 -0
- package/dist/core/coherence/calls/called.js.map +1 -0
- package/dist/core/coherence/coherence.js +103 -22
- 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/covers/health.js +85 -0
- package/dist/core/coherence/covers/health.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 +147 -16
- 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 +28 -87
- package/dist/core/coherence/events/lookups.js.map +1 -1
- package/dist/core/coherence/events/produced.js +100 -0
- package/dist/core/coherence/events/produced.js.map +1 -0
- 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 +51 -6
- package/dist/core/delta/delta.js.map +1 -1
- package/dist/core/dependencies/fanin.js +2 -2
- package/dist/core/dependencies/fanin.js.map +1 -1
- package/dist/core/deployment/delta.js +191 -0
- package/dist/core/deployment/delta.js.map +1 -0
- package/dist/core/deployment/objects.js +145 -0
- package/dist/core/deployment/objects.js.map +1 -0
- package/dist/core/diff/base-git.js +94 -12
- package/dist/core/diff/base-git.js.map +1 -1
- package/dist/core/diff/base-state.js +49 -21
- 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/docs.js +31 -22
- package/dist/core/docs.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/config.js +7 -3
- package/dist/core/doctor/config.js.map +1 -1
- package/dist/core/doctor/doctor.js +91 -11
- package/dist/core/doctor/doctor.js.map +1 -1
- package/dist/core/doctor/report.js.map +1 -1
- package/dist/core/doctor/reports/scan.js +242 -0
- package/dist/core/doctor/reports/scan.js.map +1 -0
- package/dist/core/document/apply.js +158 -11
- 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 +26 -21
- package/dist/core/explain/families.js.map +1 -1
- package/dist/core/explain/lookup.js +14 -1
- package/dist/core/explain/lookup.js.map +1 -1
- package/dist/core/explain/refusals.js +5 -5
- package/dist/core/explain/refusals.js.map +1 -1
- package/dist/core/explain/terms/documents.js +227 -0
- package/dist/core/explain/terms/documents.js.map +1 -0
- package/dist/core/explain/terms/done-check.js +144 -0
- package/dist/core/explain/terms/done-check.js.map +1 -0
- package/dist/core/explain/terms/entry.js +14 -0
- package/dist/core/explain/terms/entry.js.map +1 -0
- package/dist/core/explain/terms/stages.js +71 -0
- package/dist/core/explain/terms/stages.js.map +1 -0
- package/dist/core/explain/terms/tasks.js +97 -0
- package/dist/core/explain/terms/tasks.js.map +1 -0
- package/dist/core/explain/terms.js +68 -109
- package/dist/core/explain/terms.js.map +1 -1
- package/dist/core/explore/explore.js +40 -10
- package/dist/core/explore/explore.js.map +1 -1
- package/dist/core/fleet-context.js +81 -95
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +11 -4
- package/dist/core/gate/checks.js.map +1 -1
- package/dist/core/gate/partners.js +69 -28
- 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/delta.js +10 -7
- package/dist/core/glossary/delta.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/ids/fqn/ancestors.js +65 -0
- package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
- package/dist/core/kernel/path-safety.js +38 -0
- package/dist/core/kernel/path-safety.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 +51 -37
- package/dist/core/links/corpus.js.map +1 -1
- package/dist/core/links/findings.js.map +1 -1
- package/dist/core/links/parse.js +38 -9
- package/dist/core/links/parse.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 +40 -10
- 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 +301 -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 +28 -52
- package/dist/core/openapi/merge/merge.js.map +1 -1
- package/dist/core/openapi/merge/pin.js +17 -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 +43 -4
- package/dist/core/pack/living.js.map +1 -1
- package/dist/core/pack/pack.js +50 -6
- package/dist/core/pack/pack.js.map +1 -1
- package/dist/core/projection/arch-slice.js +2 -2
- package/dist/core/projection/arch-slice.js.map +1 -1
- package/dist/core/projection/introduced.js +14 -0
- package/dist/core/projection/introduced.js.map +1 -0
- 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/authored/paths.js +18 -0
- package/dist/core/repo/authored/paths.js.map +1 -1
- package/dist/core/repo/entries.js.map +1 -1
- package/dist/core/repo/paths.js +92 -6
- package/dist/core/repo/paths.js.map +1 -1
- package/dist/core/repo/repo.js +74 -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 +258 -0
- package/dist/core/repo/tree/render/body.js.map +1 -0
- package/dist/core/repo/tree/render/projects.js +182 -0
- package/dist/core/repo/tree/render/projects.js.map +1 -0
- package/dist/core/repo/tree/render/service/header.js +125 -0
- package/dist/core/repo/tree/render/service/header.js.map +1 -0
- package/dist/core/repo/tree/render/service/peers.js +28 -0
- package/dist/core/repo/tree/render/service/peers.js.map +1 -0
- package/dist/core/repo/tree/render/service/view-id.js +67 -0
- package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
- package/dist/core/repo/tree/render/service/views.js +78 -0
- package/dist/core/repo/tree/render/service/views.js.map +1 -0
- package/dist/core/repo/tree/render/stale.js +42 -0
- package/dist/core/repo/tree/render/stale.js.map +1 -0
- package/dist/core/repo/tree/render/text.js +84 -0
- package/dist/core/repo/tree/render/text.js.map +1 -0
- package/dist/core/repo/tree/render/views.js +293 -0
- package/dist/core/repo/tree/render/views.js.map +1 -0
- package/dist/core/repo/tree/walk.js +53 -32
- 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/scaffold/landscape.js +121 -13
- package/dist/core/scaffold/landscape.js.map +1 -1
- package/dist/core/scaffold/legacy.js +271 -0
- package/dist/core/scaffold/legacy.js.map +1 -0
- package/dist/core/staging/commit.js +26 -15
- 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 +84 -6
- package/dist/core/staging/recovery/recover.js.map +1 -1
- package/dist/core/staging/snapshot/manifest.js +188 -0
- package/dist/core/staging/snapshot/manifest.js.map +1 -0
- package/dist/core/staging/{snapshot.js → snapshot/snapshot.js} +39 -45
- package/dist/core/staging/snapshot/snapshot.js.map +1 -0
- package/dist/core/staging/txn/forward.js +24 -14
- package/dist/core/staging/txn/forward.js.map +1 -1
- package/dist/core/staging/writes.js.map +1 -1
- package/dist/core/status/actions/execution.js +11 -0
- package/dist/core/status/actions/execution.js.map +1 -1
- package/dist/core/status/contracts.js +39 -15
- package/dist/core/status/contracts.js.map +1 -1
- package/dist/core/status/feature/artifacts.js +33 -8
- package/dist/core/status/feature/artifacts.js.map +1 -1
- package/dist/core/status/feature/feature.js +24 -17
- package/dist/core/status/feature/feature.js.map +1 -1
- package/dist/core/status/feature/next.js +20 -7
- package/dist/core/status/feature/next.js.map +1 -1
- package/dist/core/status/feature/words.js +96 -0
- package/dist/core/status/feature/words.js.map +1 -0
- package/dist/core/status/fleet/fleet.js +43 -14
- package/dist/core/status/fleet/fleet.js.map +1 -1
- package/dist/core/status/fleet/next.js +153 -58
- package/dist/core/status/fleet/next.js.map +1 -1
- package/dist/core/status/report.js.map +1 -1
- package/dist/core/status/scan.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 +199 -0
- package/dist/core/tasks/packet.js.map +1 -0
- package/dist/core/tasks/record.js +43 -0
- package/dist/core/tasks/record.js.map +1 -0
- package/dist/core/tasks/sources.js +181 -0
- package/dist/core/tasks/sources.js.map +1 -0
- package/dist/core/tasks/stamps.js +76 -0
- package/dist/core/tasks/stamps.js.map +1 -0
- package/dist/core/tasks/unit.js +0 -0
- package/dist/core/tasks/unit.js.map +1 -0
- package/dist/core/usecases/capability.js +11 -14
- package/dist/core/usecases/capability.js.map +1 -1
- package/dist/core/usecases/delta/claims.js +31 -7
- package/dist/core/usecases/delta/claims.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/delta/modified.js +315 -0
- package/dist/core/usecases/delta/modified.js.map +1 -0
- package/dist/core/usecases/delta/overlay.js +32 -191
- package/dist/core/usecases/delta/overlay.js.map +1 -1
- package/dist/core/usecases/fleet.js +195 -36
- package/dist/core/usecases/fleet.js.map +1 -1
- package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/capability-tag.js +8 -9
- package/dist/core/usecases/grade/capability-tag.js.map +1 -0
- package/dist/core/usecases/grade/feature.js +88 -0
- package/dist/core/usecases/grade/feature.js.map +1 -0
- package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/requirement-tag.js +3 -4
- package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
- package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/steps.js +102 -33
- package/dist/core/usecases/grade/steps.js.map +1 -0
- package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/usecases.js +23 -10
- package/dist/core/usecases/grade/usecases.js.map +1 -0
- package/dist/core/usecases/operations.js +26 -14
- package/dist/core/usecases/operations.js.map +1 -1
- package/dist/core/usecases/place.js.map +1 -1
- package/dist/core/usecases/service/exclude.js +119 -0
- package/dist/core/usecases/service/exclude.js.map +1 -0
- package/dist/core/usecases/service/flows.js +164 -0
- package/dist/core/usecases/service/flows.js.map +1 -0
- package/dist/core/usecases/suites/participants.js +83 -0
- package/dist/core/usecases/suites/participants.js.map +1 -0
- package/dist/core/usecases/suites/suites.js +45 -0
- package/dist/core/usecases/suites/suites.js.map +1 -0
- package/dist/core/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 +70 -12
- 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 +4 -0
- package/dist/core/vocabulary/issue.js.map +1 -1
- package/dist/core/vocabulary/maturity.js +75 -4
- package/dist/core/vocabulary/maturity.js.map +1 -1
- package/dist/core/vocabulary/report.js +16 -1
- package/dist/core/vocabulary/report.js.map +1 -1
- package/examples/README.md +54 -11
- package/examples/docs/architecture/landscape.likec4 +62 -6
- package/examples/docs/architecture/services.likec4 +70 -0
- package/examples/docs/architecture/subsystems.likec4 +7 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +16 -7
- 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/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +4 -1
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +13 -10
- package/examples/docs/likec4.config.json +0 -1
- package/examples/docs/services/checkout-web/model.likec4 +39 -56
- package/examples/docs/services/order-service/arch.spec.md +13 -6
- package/examples/docs/services/order-service/asyncapi.yaml +3 -2
- package/examples/docs/services/order-service/model.likec4 +58 -70
- package/examples/docs/services/payment-service/arch.spec.md +7 -4
- package/examples/docs/services/payment-service/model.likec4 +38 -37
- package/examples/docs/services/platform/identity-service/arch.spec.md +7 -4
- package/examples/docs/services/platform/identity-service/model.likec4 +35 -37
- package/examples/docs/services/platform/notification-service/asyncapi.yaml +2 -1
- package/examples/docs/services/platform/notification-service/health.yaml +8 -3
- package/examples/docs/services/platform/notification-service/model.likec4 +43 -64
- package/package.json +1 -1
- package/dist/commands/validate/checks/vocabulary.js +0 -31
- package/dist/commands/validate/checks/vocabulary.js.map +0 -1
- package/dist/commands/validate/fleet/usecases/capability-tag.js.map +0 -1
- package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +0 -1
- package/dist/commands/validate/fleet/usecases/steps.js.map +0 -1
- package/dist/commands/validate/fleet/usecases/usecases.js.map +0 -1
- package/dist/core/agent/agents-md/artifacts.js +0 -220
- package/dist/core/agent/agents-md/artifacts.js.map +0 -1
- package/dist/core/agent/agents-md/cycle.js +0 -165
- 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 -247
- package/dist/core/diff/victims.js.map +0 -1
- package/dist/core/repo/tree/views.js +0 -172
- package/dist/core/repo/tree/views.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":"list.js","sourceRoot":"","sources":["../../../src/commands/list/list.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Command } from \"commander\";\nimport { loadConfig } from \"../../core/envelope/config.js\";\nimport { emitJson, fail, repoPath, reportNoConfig } from \"../../core/envelope/json.js\";\nimport { maturityRollup } from \"../../core/vocabulary/maturity.js\";\nimport { FleetContext } from \"../../core/fleet-context.js\";\nimport { DocsRepoUnavailableError } from \"../../core/repo/state.js\";\nimport { capabilityRollup, type CapabilityRow } from \"../../core/capabilities/rollup.js\";\nimport { invalidVocabularyFinding } from \"../../core/capabilities/findings.js\";\nimport { promisesKeptByFlows } from \"../../core/usecases/capability.js\";\nimport { fleetAdrCount, listFeatures, listFleetTree, listServices } from \"../../core/repo/repo.js\";\nimport { readGlossary } from \"../../core/glossary/tree.js\";\nimport { backlinkIndex } from \"../../core/links/backlinks.js\";\nimport { glossaryDir } from \"../../core/repo/authored/paths.js\";\nimport { docsRepoReady, reportDocsRepoError, reportRepositoryUnavailable } from \"../policy/gate.js\";\nimport { featureVerification, serviceViews, type ServiceView } from \"./views.js\";\nimport { capabilityJson, featureJson, glossaryJson, ownersJson, serviceRows, subsystemsJson } from \"./json.js\";\nimport {\n printCapabilities,\n printFeatures,\n printGlossary,\n printOwners,\n printServices,\n printWorklist,\n} from \"./print.js\";\nimport { fanInByService, reviewLandscape, reviewOrder } from \"./review.js\";\nimport { resolveSubsystemSlice } from \"./campaign/campaign.js\";\nimport { ownersJoin, type OwnersJoin } from \"./campaign/owners.js\";\n\ntype Section = \"services\" | \"features\" | \"capabilities\" | \"glossary\";\nconst SECTIONS: Section[] = [\"services\", \"features\", \"capabilities\", \"glossary\"];\n/**\n * What a bare `loam list` shows. `capabilities` is explicit-only, NEVER part\n * of this default: the no-argument output and its `--json` payload are a\n * frozen contract, byte-identical whether or not a fleet declares capabilities.\n */\nconst DEFAULT_SECTIONS: Section[] = [\"services\", \"features\"];\n\ninterface ListOptions {\n json?: boolean;\n archived?: boolean;\n needsWork?: boolean;\n reviewOrder?: boolean;\n subsystem?: string;\n owners?: string;\n}\n\nexport function registerList(program: Command): void {\n program\n .command(\"list\")\n .argument(\"[section]\", \"services | features | capabilities | glossary (default: services + features)\")\n .description(\"List the services and features in the docs repo\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .option(\"--archived\", \"include archived features\")\n .option(\n \"--needs-work\",\n \"services only: the adoption worklist — every service below `vouched`, with what it is missing\",\n )\n .option(\n \"--review-order\",\n \"with --needs-work: order the worklist by blast radius — services the most other services depend on first\",\n )\n .option(\n \"--subsystem <name>\",\n \"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)\",\n )\n .option(\n \"--owners <path>\",\n \"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)\",\n )\n .action(async (section: string | undefined, opts: ListOptions) => {\n const json = opts.json === true;\n // The campaign flags grade services, so — exactly like --needs-work —\n // they narrow a bare `loam list` to the services section instead of\n // printing a features table the filter silently does not apply to.\n const campaign = opts.subsystem !== undefined || opts.owners !== undefined;\n const wanted =\n opts.needsWork || campaign\n ? DEFAULT_SECTIONS.filter((s) => s === \"services\")\n : section\n ? SECTIONS.filter((s) => s === section)\n : DEFAULT_SECTIONS;\n if (section && !SECTIONS.includes(section as Section)) {\n // `invalid-option`, same as show's bad --type: one mistake class, one code.\n fail(json, \"invalid-option\", `Unknown section '${section}'. Expected: ${SECTIONS.join(\" | \")}.`);\n return;\n }\n if (opts.needsWork && section === \"features\") {\n fail(json, \"invalid-option\", \"--needs-work is the service adoption worklist; drop the 'features' section.\");\n return;\n }\n if (campaign && section !== undefined && section !== \"services\") {\n fail(json, \"invalid-option\", `--subsystem and --owners grade the services section; drop the '${section}' section.`);\n return;\n }\n // The flag ORDERS the worklist, so it requires the worklist explicitly:\n // silently implying --needs-work would make one flag change which rows\n // exist, not only their order.\n if (opts.reviewOrder && !opts.needsWork) {\n fail(json, \"invalid-option\", \"--review-order sorts the adoption worklist; add --needs-work.\");\n return;\n }\n\n const loaded = await loadConfig();\n if (loaded.kind !== \"loaded\") {\n reportNoConfig(json, loaded);\n return;\n }\n const config = loaded.config;\n const { docsDir } = config;\n // A docsDir that is not a docs repo is refused, never rendered as an empty\n // fleet — the whole point of the gate (see docs-repo-gate.ts).\n // `list features` alone does not need services/, so it asks for less;\n // the capability rollup walks every service's spec files, so it asks for them.\n const needsServices =\n wanted.includes(\"services\") || wanted.includes(\"capabilities\") || wanted.includes(\"glossary\");\n if (!docsRepoReady(json, docsDir, needsServices ? \"services\" : \"docs\")) return;\n\n try {\n // One context, one walk: the tree memo answers both the service\n // entries and the subsystem/unfiled counts beside them.\n const fleet = new FleetContext();\n const tree = wanted.includes(\"services\") ? await listFleetTree(docsDir, fleet) : undefined;\n const services = wanted.includes(\"services\") ? await listServices(docsDir, fleet) : undefined;\n // --review-order parses the landscape ONCE for both of its consumers —\n // serviceViews' `called` set (handed in as `preloaded`) and the fan-in\n // joins below. Without the flag, `undefined` keeps serviceViews' own\n // load-if-exists behaviour and the run byte-identical to today's.\n const land =\n opts.reviewOrder === true && services !== undefined\n ? await reviewLandscape(docsDir, fleet)\n : undefined;\n const views = services ? await serviceViews(docsDir, services, config.service, land) : undefined;\n // The slice is resolved AFTER the full-fleet views, and rows are\n // filtered rather than re-derived: fan-in, apiExpected and the missing\n // lists are fleet facts, and a slice-first derivation would recompute\n // them against a fleet with the callers outside the slice erased. The\n // composition is pinned as filter-first-then-rank — ranks stay\n // contiguous within the filtered set (test/list-campaign.test.ts).\n // `tree !== undefined` is a type NARROWING, not a branch: a campaign\n // flag forces the services section, so the tree always exists here.\n const slice =\n opts.subsystem !== undefined && tree !== undefined\n ? resolveSubsystemSlice(tree, opts.subsystem, json)\n : undefined;\n if (slice === null) return;\n // Membership is by DIRECTORY: leaf ids can collide across a broken\n // tree (`subsystem.name-collision`), and the directory is the row's\n // actual identity — campaign.ts's SubsystemSlice says why.\n const shown = slice === undefined ? views : views?.filter((v) => slice.members.has(v.entry.dir));\n // The fleet's own decision records. Read unconditionally — it is one\n // existsSync over `architecture/adrs/` and it belongs to the docs repo\n // rather than to any section, so `loam list features --json` reports it\n // as truthfully as `loam list services --json` does. Nothing grades it:\n // an absent directory is 0 and 0 is a fine, permanent answer.\n const fleetAdrs = await fleetAdrCount(docsDir);\n const features = wanted.includes(\"features\")\n ? await listFeatures(docsDir, { includeArchived: opts.archived }, fleet)\n : undefined;\n const verification = features\n ? await Promise.all(features.map((f) => featureVerification(docsDir, f)))\n : undefined;\n\n // The capability section: the vocabulary's own verdict decides the shape.\n // An INVALID file refuses with `repository-unavailable` — an\n // empty-looking success over a broken file is the silent hole this\n // command already refuses elsewhere — while an ABSENT one is an honest\n // empty answer, because the file is the axis's opt-in. The message is\n // `capability.invalid`'s own sentence, not the fs-error helper's: the\n // file WAS read, it just is not a vocabulary, and one diagnosis should\n // have one spelling wherever it surfaces.\n const capabilityVocab = wanted.includes(\"capabilities\")\n ? await fleet.capabilities(docsDir)\n : undefined;\n const brokenVocab = capabilityVocab === undefined ? null : invalidVocabularyFinding(capabilityVocab);\n if (brokenVocab !== null) {\n fail(json, \"repository-unavailable\", brokenVocab.message);\n return;\n }\n // The SECOND corpus behind a capability's promises: the `#cap-`/`#req-`\n // tagged flows. Read only under `loam list capabilities`, and\n // `promisesKeptByFlows` carries `readUseCases`' byte gate, so a fleet\n // whose architecture/ never mentions the reserved tag prefix pays a\n // readdir here rather than a LikeC4 workspace.\n //\n // AN UNREADABLE architecture/ DEGRADES, it does not refuse — the\n // opposite of the invalid vocabulary above, and the difference is which\n // corpus broke. `architecture/capabilities.yaml` is what the ROWS are\n // built from: unreadable, there is no listing to print, so refusing is\n // the only honest answer. The flows are a second corpus over rows that\n // are already true, and refusing the whole listing because a use-case\n // document has a syntax error would take `loam list capabilities` away\n // during exactly the minutes somebody is fixing that document, while\n // `validate` already reports it as `landscape.invalid`. So the join is\n // withheld instead — every `keptBy` absent rather than `[]` — and the\n // reason is stated, which is `core/pack/joins.ts`' holes idiom: carry\n // what is true, name what could not be looked at, never let the two read\n // the same.\n const entries = capabilityVocab === undefined ? undefined : await listServices(docsDir, fleet);\n const promises =\n capabilityVocab === undefined || entries === undefined\n ? undefined\n : await promisesKeptByFlows({\n docsDir,\n vocab: capabilityVocab,\n known: new Set(entries.map((e) => e.id)),\n read: (p) => fleet.readRequirements(p),\n });\n const capabilities: CapabilityRow[] | undefined =\n capabilityVocab === undefined || entries === undefined\n ? undefined\n : await capabilityRollup({\n services: entries,\n vocab: capabilityVocab,\n read: (p) => fleet.readRequirements(p),\n ...(promises?.kind === \"read\" ? { keptByFlows: promises.kept } : {}),\n });\n\n // The glossary section: the tree, and who cites each term. The\n // citation index is the expensive half — it reads every authored\n // document in the repository — so it is built only when the section is\n // asked for, and not at all when `glossary/` does not exist. The\n // directory's existence is the axis's opt-in, exactly as it is for\n // `capabilities/`, so a fleet without one prints an empty section\n // rather than paying for a fleet-wide walk to say so.\n const glossary = wanted.includes(\"glossary\") ? await readGlossary(glossaryDir(docsDir)) : undefined;\n const citations =\n glossary !== undefined && glossary.terms.length > 0 ? await backlinkIndex(docsDir, fleet) : undefined;\n const terms = glossary?.terms.map((term) => ({\n term,\n linkedBy: citations === undefined ? [] : citations.linkersOf(term.path),\n }));\n\n const worklist = (shown ?? []).filter((v) => v.maturity !== \"vouched\");\n // The ranked review queue, derived never stored: fan-in is computed\n // FLEET-WIDE (the joins need every service's slice anyway — and a\n // --subsystem filter must never change a service's count, only which\n // rows appear) while ranks are assigned over the WORKLIST only — a\n // vouched service needs no review, and ranking it would put gaps in\n // the queue. The worklist is already sliced, so under --subsystem the\n // ranks are contiguous within the filtered set.\n let ranked: { queue: ServiceView[]; fanIn: ReadonlyMap<string, number> } | undefined;\n if (opts.reviewOrder === true && services !== undefined) {\n const fanIn = await fanInByService(services, fleet, land ?? null);\n ranked = { queue: reviewOrder(worklist, fanIn), fanIn };\n }\n\n // THE row set of this listing, spelled once: the owners join, the\n // `services[]` payload and the text view must all be about the same\n // rows — `owners.teams[]` is only \"that team's campaign worklist\"\n // while it was computed over the rows `services[]` lists — and three\n // copies of this expression is how they would drift apart.\n const rows = shown === undefined ? undefined : (ranked?.queue ?? (opts.needsWork ? worklist : shown));\n\n let owned: OwnersJoin | undefined;\n if (opts.owners !== undefined && rows !== undefined) {\n const join = await ownersJoin({\n path: opts.owners,\n rows: rows.map((v) => ({ id: v.entry.id, repoDir: repoPath(docsDir, v.entry.dir) })),\n json,\n });\n if (join === null) return;\n owned = join;\n }\n\n if (json) {\n emitJson({\n command: \"list\",\n docsDir,\n // Additive, unconditional and flat, mirroring the per-service\n // `adrs` key one row down rather than inventing a second shape for\n // the same number. Not nested under the services section: the fleet\n // has decision records whether or not this run listed services.\n fleetAdrs,\n ...(rows && shown\n ? {\n services: serviceRows(docsDir, ranked ?? rows),\n // Under --subsystem the dial is the SLICE's — the filter's\n // whole answer — while unfiltered runs keep the full fleet's\n // rollup, byte-identical to before the flag existed.\n maturity: maturityRollup(shown),\n // The tree beside the table — additive keys, wave 3 of the\n // subsystem item: the groups, and how many services sit\n // unfiled (a permanent, normal state, so a count, never a\n // finding). Under --subsystem the rows narrow to the named\n // group and its descendants; memberCount stays transitive\n // because the full tree's services back the modified copy.\n subsystems: subsystemsJson(\n docsDir,\n slice === undefined ? tree! : { ...tree!, subsystems: slice.subsystems },\n ),\n // `unfiledServices` is a fleet-root fact: under a filter it\n // is omitted rather than reported as 0, which would lie.\n ...(slice === undefined\n ? { unfiledServices: tree!.services.filter((s) => s.subsystem.length === 0).length }\n : {}),\n }\n : {}),\n ...(owned !== undefined ? { owners: ownersJson(owned) } : {}),\n ...(features\n ? { features: features.map((f, i) => featureJson(docsDir, f, verification![i] ?? null)) }\n : {}),\n ...(capabilities ? { capabilities: capabilities.map(capabilityJson) } : {}),\n ...(terms ? { glossary: terms.map((t) => glossaryJson(t.term, t.linkedBy, docsDir)) } : {}),\n // What the citation walk could not read, beside the rows it\n // decorates — `useCases` below is the same shape for the same\n // reason. An empty `linkedBy` means loam read every authored\n // document and none cites the term; this key is how a reader tells\n // that from \"one of them would not decode\".\n ...(citations ? { links: { unreadable: citations.unreadable } } : {}),\n // The use-case corpus's own health, beside the rows it decorates —\n // `status --json` and `delta --json` already spell this key this\n // way. It is what makes an absent `keptBy` legible: `unreadable:\n // false` with no `keptBy` on a row means the document declares that\n // promise and no flow keeps it, while `unreadable: true` means\n // nobody could look. Emitted only with the capabilities section, so\n // bare `loam list --json` is untouched.\n ...(promises === undefined\n ? {}\n : {\n useCases: {\n unreadable: promises.kind === \"unreadable\",\n ...(promises.kind === \"unreadable\" && promises.errors[0] !== undefined\n ? { error: promises.errors[0] }\n : {}),\n },\n }),\n });\n return;\n }\n\n if (slice !== undefined && shown !== undefined) {\n console.log(`filtered to ${slice.label}: ${shown.length} of ${views!.length} service(s)`);\n }\n if (owned !== undefined && rows !== undefined && shown !== undefined) {\n if (opts.needsWork && rows.length === 0) {\n // printWorklist's own affordance, kept under the grouping flag:\n // empty owner groups would answer \"who owns the work\" without\n // saying there is none.\n console.log(`nothing to do — all ${shown.length} service(s) are vouched`);\n return;\n }\n const kind = opts.needsWork\n ? `${rows.length} of ${shown.length} service(s) need work`\n : `services (${rows.length})`;\n const ordered =\n ranked === undefined ? \"\" : \" — review order (fan-in: services depending on each)\";\n console.log(`${kind} — by owner (${owned.path})${ordered}`);\n printOwners(owned, new Map(rows.map((v) => [repoPath(docsDir, v.entry.dir), v])), ranked?.fanIn);\n return;\n }\n if (opts.needsWork) {\n printWorklist(ranked === undefined ? worklist : ranked.queue, shown!.length, ranked?.fanIn);\n return;\n }\n // Under --subsystem the tree dial (subsystem and unfiled counts) is a\n // fleet-root fact the filtered table must not claim, so no tree. The\n // fleet's ADR count is not derived from the rows at all and stays.\n if (shown) printServices(shown, { tree: slice === undefined ? tree : undefined, adrs: fleetAdrs });\n if (views && features) console.log(\"\");\n if (features) printFeatures(features, verification!);\n if (capabilities) {\n if (capabilityVocab!.present) printCapabilities(capabilities, promises!);\n else console.log(\"no architecture/capabilities.yaml — the fleet declares no capabilities\");\n }\n if (terms && glossary) {\n if (glossary.present) {\n printGlossary(\n terms.map((t) => ({ id: t.term.id, linkedBy: t.linkedBy })),\n citations?.unreadable ?? [],\n );\n } else {\n console.log(\"no glossary/ — the fleet defines no domain terms\");\n }\n }\n } catch (err) {\n if (err instanceof DocsRepoUnavailableError) {\n reportDocsRepoError(json, err);\n return;\n }\n // One unreadable file used to escape as a stack trace (`internal` in\n // --json), naming nothing. The enumeration is all-or-nothing — it reads\n // every service's frontmatter to build one table — so the honest answer\n // is a refusal that says WHICH path could not be read.\n reportRepositoryUnavailable(json, err, \"the listing would be missing a service\", docsDir);\n }\n });\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/list/list.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Command } from \"commander\";\nimport { configOrRefuse, emitJson, fail, repoPath } from \"../../core/envelope/json.js\";\nimport { maturityRollup } from \"../../core/vocabulary/maturity.js\";\nimport { FleetContext } from \"../../core/fleet-context.js\";\nimport { DocsRepoUnavailableError } from \"../../core/repo/state.js\";\nimport { capabilityRollup, type CapabilityRow } from \"../../core/capabilities/rollup.js\";\nimport { invalidVocabularyFinding } from \"../../core/capabilities/findings.js\";\nimport { promisesKeptByFlows } from \"../../core/usecases/capability.js\";\nimport { fleetAdrCount, listFeatures, listFleetTree, listServices } from \"../../core/repo/repo.js\";\nimport { readGlossary } from \"../../core/glossary/tree.js\";\nimport { backlinkIndex } from \"../../core/links/backlinks.js\";\nimport { glossaryDir } from \"../../core/repo/authored/paths.js\";\nimport { docsRepoReady, reportDocsRepoError, reportRepositoryUnavailable } from \"../policy/gate.js\";\nimport { featureRow, serviceViews, type ServiceView } from \"./views.js\";\nimport { capabilityJson, featureJson, glossaryJson, ownersJson, serviceRows, subsystemsJson } from \"./json.js\";\nimport {\n printCapabilities,\n printFeatures,\n printGlossary,\n printOwners,\n printServices,\n printWorklist,\n} from \"./print.js\";\nimport { fanInByService, reviewLandscape, reviewOrder } from \"./review.js\";\nimport { resolveSubsystemSlice } from \"./campaign/campaign.js\";\nimport { ownersJoin, type OwnersJoin } from \"./campaign/owners.js\";\nimport { suitesSection } from \"./suites/suites.js\";\n\ntype Section = \"services\" | \"features\" | \"capabilities\" | \"glossary\" | \"suites\";\nconst SECTIONS: Section[] = [\"services\", \"features\", \"capabilities\", \"glossary\", \"suites\"];\n/**\n * What a bare `loam list` shows. `capabilities` is explicit-only, NEVER part\n * of this default: the no-argument output and its `--json` payload are a\n * frozen contract, byte-identical whether or not a fleet declares capabilities.\n */\nconst DEFAULT_SECTIONS: Section[] = [\"services\", \"features\"];\n\ninterface ListOptions {\n json?: boolean;\n archived?: boolean;\n needsWork?: boolean;\n reviewOrder?: boolean;\n subsystem?: string;\n owners?: string;\n}\n\nexport function registerList(program: Command): void {\n program\n .command(\"list\")\n .argument(\"[section]\", \"services | features | capabilities | glossary | suites (default: services + features)\")\n .argument(\"[name]\", \"suites only: the one suite to show\")\n .description(\"List the services and features in the docs repo\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .option(\"--archived\", \"include archived features\")\n .option(\n \"--needs-work\",\n \"services only: the adoption worklist — every service below `vouched`, with what it is missing\",\n )\n .option(\n \"--review-order\",\n \"with --needs-work: order the worklist by blast radius — services the most other services depend on first\",\n )\n .option(\n \"--subsystem <name>\",\n \"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)\",\n )\n .option(\n \"--owners <path>\",\n \"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)\",\n )\n .action(async (section: string | undefined, name: string | undefined, opts: ListOptions) => {\n const json = opts.json === true;\n // The campaign flags grade services, so — exactly like --needs-work —\n // they narrow a bare `loam list` to the services section instead of\n // printing a features table the filter silently does not apply to.\n const campaign = opts.subsystem !== undefined || opts.owners !== undefined;\n const wanted =\n opts.needsWork || campaign\n ? DEFAULT_SECTIONS.filter((s) => s === \"services\")\n : section\n ? SECTIONS.filter((s) => s === section)\n : DEFAULT_SECTIONS;\n if (section && !SECTIONS.includes(section as Section)) {\n // `invalid-option`, same as show's bad --type: one mistake class, one code.\n fail(json, \"invalid-option\", `Unknown section '${section}'. Expected: ${SECTIONS.join(\" | \")}.`);\n return;\n }\n // Anywhere but suites a name would be silently ignored: refused, as commander's excess-argument error was.\n if (name !== undefined && section !== \"suites\") {\n fail(json, \"invalid-option\", `Only the suites section takes a name; drop '${name}'.`);\n return;\n }\n if (opts.needsWork && (section === \"features\" || section === \"suites\")) {\n fail(json, \"invalid-option\", `--needs-work is the service adoption worklist; drop the '${section}' section.`);\n return;\n }\n if (campaign && section !== undefined && section !== \"services\") {\n fail(json, \"invalid-option\", `--subsystem and --owners grade the services section; drop the '${section}' section.`);\n return;\n }\n // The flag ORDERS the worklist, so it requires the worklist explicitly:\n // silently implying --needs-work would make one flag change which rows\n // exist, not only their order.\n if (opts.reviewOrder && !opts.needsWork) {\n fail(json, \"invalid-option\", \"--review-order sorts the adoption worklist; add --needs-work.\");\n return;\n }\n\n const config = await configOrRefuse(json);\n if (config === null) return;\n const { docsDir } = config;\n // A docsDir that is not a docs repo is refused, never rendered as an empty\n // fleet — the whole point of the gate (see docs-repo-gate.ts).\n // `list features` alone does not need services/, so it asks for less;\n // the capability rollup walks every service's spec files, so it asks for\n // them, and a suite resolves its participants against them.\n const needsServices = wanted.some((s) => s !== \"features\");\n if (!docsRepoReady(json, docsDir, needsServices ? \"services\" : \"docs\")) return;\n\n try {\n // One context, one walk: the tree memo answers both the service\n // entries and the subsystem/unfiled counts beside them.\n const fleet = new FleetContext();\n const tree = wanted.includes(\"services\") ? await listFleetTree(docsDir, fleet) : undefined;\n const services = wanted.includes(\"services\") ? await listServices(docsDir, fleet) : undefined;\n // --review-order parses the landscape ONCE for both of its consumers —\n // serviceViews' `called` set (handed in as `preloaded`) and the fan-in\n // joins below. Without the flag, `undefined` keeps serviceViews' own\n // load-if-exists behaviour and the run byte-identical to today's.\n const land =\n opts.reviewOrder === true && services !== undefined\n ? await reviewLandscape(docsDir, fleet)\n : undefined;\n const views = services ? await serviceViews(docsDir, services, config.service, land) : undefined;\n // The slice is resolved AFTER the full-fleet views, and rows are\n // filtered rather than re-derived: fan-in, apiExpected and the missing\n // lists are fleet facts, and a slice-first derivation would recompute\n // them against a fleet with the callers outside the slice erased. The\n // composition is pinned as filter-first-then-rank — ranks stay\n // contiguous within the filtered set (test/list-campaign.test.ts).\n // `tree !== undefined` is a type NARROWING, not a branch: a campaign\n // flag forces the services section, so the tree always exists here.\n const slice =\n opts.subsystem !== undefined && tree !== undefined\n ? resolveSubsystemSlice(tree, opts.subsystem, json)\n : undefined;\n if (slice === null) return;\n // Membership is by DIRECTORY: leaf ids can collide across a broken\n // tree (`subsystem.name-collision`), and the directory is the row's\n // actual identity — campaign.ts's SubsystemSlice says why.\n const shown = slice === undefined ? views : views?.filter((v) => slice.members.has(v.entry.dir));\n // The fleet's own decision records. Read unconditionally — it is one\n // existsSync over `architecture/adrs/` and it belongs to the docs repo\n // rather than to any section, so `loam list features --json` reports it\n // as truthfully as `loam list services --json` does. Nothing grades it:\n // an absent directory is 0 and 0 is a fine, permanent answer.\n const fleetAdrs = await fleetAdrCount(docsDir);\n const features = wanted.includes(\"features\")\n ? await listFeatures(docsDir, { includeArchived: opts.archived }, fleet)\n : undefined;\n const featureRows = features\n ? await Promise.all(features.map((f) => featureRow(docsDir, f, fleet)))\n : undefined;\n\n // The capability section: the vocabulary's own verdict decides the shape.\n // An INVALID file refuses with `repository-unavailable` — an\n // empty-looking success over a broken file is the silent hole this\n // command already refuses elsewhere — while an ABSENT one is an honest\n // empty answer, because the file is the axis's opt-in. The message is\n // `capability.invalid`'s own sentence, not the fs-error helper's: the\n // file WAS read, it just is not a vocabulary, and one diagnosis should\n // have one spelling wherever it surfaces.\n const capabilityVocab = wanted.includes(\"capabilities\")\n ? await fleet.capabilities(docsDir)\n : undefined;\n const brokenVocab = capabilityVocab === undefined ? null : invalidVocabularyFinding(capabilityVocab);\n if (brokenVocab !== null) {\n fail(json, \"repository-unavailable\", brokenVocab.message);\n return;\n }\n // The SECOND corpus behind a capability's promises: the `#cap-`/`#req-`\n // tagged flows. Read only under `loam list capabilities`, and\n // `promisesKeptByFlows` carries `readUseCases`' byte gate, so a fleet\n // whose architecture/ never mentions the reserved tag prefix pays a\n // readdir here rather than a LikeC4 workspace.\n //\n // AN UNREADABLE architecture/ DEGRADES, it does not refuse — the\n // opposite of the invalid vocabulary above, and the difference is which\n // corpus broke. `architecture/capabilities.yaml` is what the ROWS are\n // built from: unreadable, there is no listing to print, so refusing is\n // the only honest answer. The flows are a second corpus over rows that\n // are already true, and refusing the whole listing because a use-case\n // document has a syntax error would take `loam list capabilities` away\n // during exactly the minutes somebody is fixing that document, while\n // `validate` already reports it as `landscape.invalid`. So the join is\n // withheld instead — every `keptBy` absent rather than `[]` — and the\n // reason is stated, which is `core/pack/joins.ts`' holes idiom: carry\n // what is true, name what could not be looked at, never let the two read\n // the same.\n const entries = capabilityVocab === undefined ? undefined : await listServices(docsDir, fleet);\n const promises =\n capabilityVocab === undefined || entries === undefined\n ? undefined\n : await promisesKeptByFlows({\n docsDir,\n vocab: capabilityVocab,\n known: new Set(entries.map((e) => e.id)),\n read: (p) => fleet.readRequirements(p),\n });\n const capabilities: CapabilityRow[] | undefined =\n capabilityVocab === undefined || entries === undefined\n ? undefined\n : await capabilityRollup({\n services: entries,\n vocab: capabilityVocab,\n read: (p) => fleet.readRequirements(p),\n ...(promises?.kind === \"read\" ? { keptByFlows: promises.kept } : {}),\n });\n\n // The glossary section: the tree, and who cites each term. The\n // citation index is the expensive half — it reads every authored\n // document in the repository — so it is built only when the section is\n // asked for, and not at all when `glossary/` does not exist. The\n // directory's existence is the axis's opt-in, exactly as it is for\n // `capabilities/`, so a fleet without one prints an empty section\n // rather than paying for a fleet-wide walk to say so.\n const glossary = wanted.includes(\"glossary\") ? await readGlossary(glossaryDir(docsDir)) : undefined;\n const citations =\n glossary !== undefined && glossary.terms.length > 0 ? await backlinkIndex(docsDir, fleet) : undefined;\n const terms = glossary?.terms.map((term) => ({\n term,\n linkedBy: citations === undefined ? [] : citations.linkersOf(term.path),\n }));\n // Use cases by `#suite-` tag and what each suite needs up; `null` = already refused.\n const suites = wanted.includes(\"suites\") ? await suitesSection({ docsDir, name, json, fleet }) : undefined;\n if (suites === null) return;\n\n // Every row that still owes something — `missing` is non-empty below\n // `vouched` by construction, and at `vouched` exactly when a stamped\n // document moved under its vouch. The test used to be the rung alone,\n // so a service whose spec was edited after the person read it dropped\n // off the worklist and the footer said \"nothing to do\".\n const worklist = (shown ?? []).filter((v) => v.missing.length > 0);\n // The ranked review queue, derived never stored: fan-in is computed\n // FLEET-WIDE (the joins need every service's slice anyway — and a\n // --subsystem filter must never change a service's count, only which\n // rows appear) while ranks are assigned over the WORKLIST only — a\n // service that owes nothing needs no review, and ranking it would put\n // gaps in the queue. The worklist is already sliced, so under\n // --subsystem the ranks are contiguous within the filtered set.\n let ranked: { queue: ServiceView[]; fanIn: ReadonlyMap<string, number> } | undefined;\n if (opts.reviewOrder === true && services !== undefined) {\n const fanIn = await fanInByService(services, fleet, land ?? null);\n ranked = { queue: reviewOrder(worklist, fanIn), fanIn };\n }\n\n // THE row set of this listing, spelled once: the owners join, the\n // `services[]` payload and the text view must all be about the same\n // rows — `owners.teams[]` is only \"that team's campaign worklist\"\n // while it was computed over the rows `services[]` lists — and three\n // copies of this expression is how they would drift apart.\n const rows = shown === undefined ? undefined : (ranked?.queue ?? (opts.needsWork ? worklist : shown));\n\n let owned: OwnersJoin | undefined;\n if (opts.owners !== undefined && rows !== undefined) {\n const join = await ownersJoin({\n path: opts.owners,\n rows: rows.map((v) => ({ id: v.entry.id, repoDir: repoPath(docsDir, v.entry.dir) })),\n json,\n });\n if (join === null) return;\n owned = join;\n }\n\n if (json) {\n emitJson({\n command: \"list\",\n docsDir,\n // Additive, unconditional and flat, mirroring the per-service\n // `adrs` key one row down rather than inventing a second shape for\n // the same number. Not nested under the services section: the fleet\n // has decision records whether or not this run listed services.\n fleetAdrs,\n ...(rows && shown\n ? {\n services: serviceRows(docsDir, ranked ?? rows),\n // Under --subsystem the dial is the SLICE's — the filter's\n // whole answer — while unfiltered runs keep the full fleet's\n // rollup, byte-identical to before the flag existed.\n maturity: maturityRollup(shown),\n // The tree beside the table — additive keys, wave 3 of the\n // subsystem item: the groups, and how many services sit\n // unfiled (a permanent, normal state, so a count, never a\n // finding). Under --subsystem the rows narrow to the named\n // group and its descendants; memberCount stays transitive\n // because the full tree's services back the modified copy.\n subsystems: subsystemsJson(\n docsDir,\n slice === undefined ? tree! : { ...tree!, subsystems: slice.subsystems },\n ),\n // `unfiledServices` is a fleet-root fact: under a filter it\n // is omitted rather than reported as 0, which would lie.\n ...(slice === undefined\n ? { unfiledServices: tree!.services.filter((s) => s.subsystem.length === 0).length }\n : {}),\n }\n : {}),\n ...(owned !== undefined ? { owners: ownersJson(owned) } : {}),\n ...(featureRows\n ? { features: featureRows.map((row) => featureJson(docsDir, row)) }\n : {}),\n ...(capabilities ? { capabilities: capabilities.map(capabilityJson) } : {}),\n ...(terms ? { glossary: terms.map((t) => glossaryJson(t.term, t.linkedBy, docsDir)) } : {}),\n // What the citation walk could not read, beside the rows it\n // decorates — `useCases` below is the same shape for the same\n // reason. An empty `linkedBy` means loam read every authored\n // document and none cites the term; this key is how a reader tells\n // that from \"one of them would not decode\".\n ...(citations ? { links: { unreadable: citations.unreadable } } : {}),\n ...suites?.payload,\n // The use-case corpus's own health, beside the rows it decorates —\n // `status --json` and `delta --json` already spell this key this\n // way. It is what makes an absent `keptBy` legible: `unreadable:\n // false` with no `keptBy` on a row means the document declares that\n // promise and no flow keeps it, while `unreadable: true` means\n // nobody could look. Emitted only with the capabilities section, so\n // bare `loam list --json` is untouched.\n ...(promises === undefined\n ? {}\n : {\n useCases: {\n unreadable: promises.kind === \"unreadable\",\n ...(promises.kind === \"unreadable\" && promises.errors[0] !== undefined\n ? { error: promises.errors[0] }\n : {}),\n },\n }),\n });\n return;\n }\n\n if (slice !== undefined && shown !== undefined) {\n console.log(`filtered to ${slice.label}: ${shown.length} of ${views!.length} service(s)`);\n }\n if (owned !== undefined && rows !== undefined && shown !== undefined) {\n if (opts.needsWork && rows.length === 0) {\n // printWorklist's own affordance — called rather than respelled —\n // kept under the grouping flag: empty owner groups would answer\n // \"who owns the work\" without saying there is none.\n printWorklist([], shown.length);\n return;\n }\n const kind = opts.needsWork\n ? `${rows.length} of ${shown.length} service(s) need work`\n : `services (${rows.length})`;\n const ordered =\n ranked === undefined ? \"\" : \" — review order (fan-in: services depending on each)\";\n console.log(`${kind} — by owner (${owned.path})${ordered}`);\n printOwners(owned, new Map(rows.map((v) => [repoPath(docsDir, v.entry.dir), v])), ranked?.fanIn);\n return;\n }\n if (opts.needsWork) {\n printWorklist(ranked === undefined ? worklist : ranked.queue, shown!.length, ranked?.fanIn);\n return;\n }\n // Under --subsystem the tree dial (subsystem and unfiled counts) is a\n // fleet-root fact the filtered table must not claim, so no tree. The\n // fleet's ADR count is not derived from the rows at all and stays.\n if (shown) printServices(shown, { tree: slice === undefined ? tree : undefined, adrs: fleetAdrs });\n if (views && features) console.log(\"\");\n if (featureRows) printFeatures(featureRows);\n if (capabilities) {\n if (capabilityVocab!.present) printCapabilities(capabilities, promises!);\n else console.log(\"no architecture/capabilities.yaml — the fleet declares no capabilities\");\n }\n if (terms && glossary) {\n if (glossary.present) {\n printGlossary(\n terms.map((t) => ({ id: t.term.id, linkedBy: t.linkedBy })),\n citations?.unreadable ?? [],\n );\n } else {\n console.log(\"no glossary/ — the fleet defines no domain terms\");\n }\n }\n suites?.print();\n } catch (err) {\n if (err instanceof DocsRepoUnavailableError) {\n reportDocsRepoError(json, err);\n return;\n }\n // One unreadable file used to escape as a stack trace (`internal` in\n // --json), naming nothing. The enumeration is all-or-nothing — it reads\n // every service's frontmatter to build one table — so the honest answer\n // is a refusal that says WHICH path could not be read.\n reportRepositoryUnavailable(json, err, \"the listing would be missing a service\", docsDir);\n }\n });\n}\n\n"]}
|
|
@@ -8,7 +8,13 @@
|
|
|
8
8
|
import { MATURITY_LADDER, maturityRollup } from "../../core/vocabulary/maturity.js";
|
|
9
9
|
import {} from "../../core/capabilities/rollup.js";
|
|
10
10
|
import { compareIds } from "../../core/repo/entries.js";
|
|
11
|
+
import { answeredSplit } from "../../core/verify/record.js";
|
|
11
12
|
import {} from "./views.js";
|
|
13
|
+
/**
|
|
14
|
+
* Fixed-width presence flags. `a` and `A` are deliberately the same letter in
|
|
15
|
+
* two cases: the arch spec and the API are the two things a reader most often
|
|
16
|
+
* mistakes for each other, and one is lowercase because it is optional.
|
|
17
|
+
*/
|
|
12
18
|
function serviceFlags(v) {
|
|
13
19
|
const s = v.entry;
|
|
14
20
|
return [
|
|
@@ -36,12 +42,30 @@ function serviceFlags(v) {
|
|
|
36
42
|
*
|
|
37
43
|
* Only on `vouched`: a lower rung already says less than "a person vouched",
|
|
38
44
|
* and hanging a scope note on it would explain a claim nothing is making.
|
|
45
|
+
*
|
|
46
|
+
* `vouched (stale)` is the same kind of string for the other thing a stamp can
|
|
47
|
+
* hide: the document's words moved after the person read them, and `loam
|
|
48
|
+
* validate` reports `content.stale` until somebody re-vouches. Both can hold at
|
|
49
|
+
* once — `vouched (sampled, stale)` — because they are different gaps.
|
|
39
50
|
*/
|
|
40
51
|
function rungLabel(v) {
|
|
41
|
-
|
|
52
|
+
const qualifiers = vouchQualifiers(v);
|
|
53
|
+
return qualifiers.length === 0 ? v.maturity : `${v.maturity} (${qualifiers.join(", ")})`;
|
|
54
|
+
}
|
|
55
|
+
/** What a `vouched` row's stamp does not cover: a sample, and words moved since. Empty below the rung. */
|
|
56
|
+
function vouchQualifiers(v) {
|
|
57
|
+
if (v.maturity !== "vouched")
|
|
58
|
+
return [];
|
|
59
|
+
return [
|
|
60
|
+
...(v.entry.vouchScope === "sampled" ? ["sampled"] : []),
|
|
61
|
+
...(v.entry.contentStale.length > 0 ? ["stale"] : []),
|
|
62
|
+
];
|
|
42
63
|
}
|
|
43
64
|
export function printServices(views, fleet) {
|
|
44
|
-
console.log(
|
|
65
|
+
console.log(
|
|
66
|
+
// One key per column serviceFlags prints, in its order — the `e` column
|
|
67
|
+
// shipped without one, so the legend explained six of seven.
|
|
68
|
+
`services (${views.length}) [M]odel [S]pec [a]rch-spec [A]pi [e]vents [R]unbook [H]ealth`);
|
|
45
69
|
const width = Math.max(0, ...views.map((v) => v.entry.id.length));
|
|
46
70
|
// Measured over the DISPLAY strings, so the column does not shear the first
|
|
47
71
|
// time a sampled row appears in a fleet.
|
|
@@ -75,9 +99,11 @@ export function printServices(views, fleet) {
|
|
|
75
99
|
// line adds is the qualifier the per-row suffix already carries, because
|
|
76
100
|
// this is the line a fleet lead reads for the trust answer, and recovering
|
|
77
101
|
// "how many of those 118 did anybody read in full" by scanning 118 rows is
|
|
78
|
-
// not an answer. Same layout as the validate scorecard's provenance row
|
|
79
|
-
|
|
80
|
-
const
|
|
102
|
+
// not an answer. Same layout as the validate scorecard's provenance row,
|
|
103
|
+
// and the same two qualifiers the per-row suffix carries, each counted.
|
|
104
|
+
const qualified = (q) => views.filter((v) => vouchQualifiers(v).includes(q)).length;
|
|
105
|
+
const notes = ["sampled", "stale"].filter((q) => qualified(q) > 0).map((q) => `${qualified(q)} ${q}`);
|
|
106
|
+
const rungs = MATURITY_LADDER.filter((m) => rollup[m] > 0).map((m) => `${rollup[m]} ${m}${m === "vouched" && notes.length > 0 ? ` (${notes.join(", ")})` : ""}`);
|
|
81
107
|
console.log(` maturity: ${rungs.join(" · ")}`);
|
|
82
108
|
// The tree dial, only once a tree exists: unfiled is permanent and normal
|
|
83
109
|
// (a count, never a finding), and a flat fleet has nothing to say here —
|
|
@@ -256,9 +282,18 @@ function verificationMark(v) {
|
|
|
256
282
|
// digest-matched green run, the second is somebody's word about one. Without
|
|
257
283
|
// the suffix a complete count is the same glyph either way, which is exactly
|
|
258
284
|
// the reading `verify`, `status` and the JSON envelope stopped giving.
|
|
259
|
-
|
|
285
|
+
//
|
|
286
|
+
// And who answered the confirmed ones, beside it. The verdict turns on the
|
|
287
|
+
// scenario claims alone, so `7/7` under a verified record still read as seven
|
|
288
|
+
// runs where two were an agent's word about a permission or an edge — the
|
|
289
|
+
// split `--json` carried in `answered` and this column did not.
|
|
290
|
+
const split = v.confirmed > 0 ? ` (${answeredSplit(v.answered)})` : "";
|
|
291
|
+
return `${v.confirmed}/${v.claims}${v.verdict === "attested" ? " attested" : ""}${split}`;
|
|
260
292
|
}
|
|
261
|
-
|
|
293
|
+
/** How wide the title column may grow before a title is cut with an ellipsis. */
|
|
294
|
+
const TITLE_WIDTH = 40;
|
|
295
|
+
export function printFeatures(rows) {
|
|
296
|
+
const features = rows.map((r) => r.feature);
|
|
262
297
|
const active = features.filter((f) => !f.archived).length;
|
|
263
298
|
const archived = features.length - active;
|
|
264
299
|
const counts = `${active} active${archived > 0 ? `, ${archived} archived` : ""}`;
|
|
@@ -267,13 +302,21 @@ export function printFeatures(features, verification) {
|
|
|
267
302
|
// read as it.
|
|
268
303
|
console.log(`features (${counts}) [I]ntent [D]elta verification`);
|
|
269
304
|
const width = Math.max(0, ...features.map((f) => f.id.length));
|
|
270
|
-
|
|
305
|
+
// The title beside the id: an id is a key, and a table of keys told a
|
|
306
|
+
// newcomer which rows existed but not which change any of them was.
|
|
307
|
+
const titles = rows.map((r) => {
|
|
308
|
+
const t = r.title ?? "";
|
|
309
|
+
return t.length > TITLE_WIDTH ? `${t.slice(0, TITLE_WIDTH - 1)}…` : t;
|
|
310
|
+
});
|
|
311
|
+
const titleWidth = Math.max(0, ...titles.map((t) => t.length));
|
|
312
|
+
const cells = rows.map((r) => verificationMark(r.cell));
|
|
271
313
|
const cellWidth = Math.max(0, ...cells.map((c) => c.length));
|
|
272
314
|
for (const [i, f] of features.entries()) {
|
|
273
315
|
const flags = `${f.has.intent ? "I" : "-"} ${f.has.delta ? "D" : "-"}`;
|
|
274
316
|
const svcs = f.services.length > 0 ? f.services.join(", ") : "—";
|
|
275
317
|
const tag = f.archived ? " (archived)" : "";
|
|
276
|
-
|
|
318
|
+
const title = titleWidth === 0 ? "" : `${titles[i].padEnd(titleWidth)} `;
|
|
319
|
+
console.log(` ${flags} ${f.id.padEnd(width)} ${title}${cells[i].padEnd(cellWidth)} ${svcs}${tag}`);
|
|
277
320
|
}
|
|
278
321
|
}
|
|
279
322
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print.js","sourceRoot":"","sources":["../../../src/commands/list/print.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The columns a person reads, and the worklist under them.\n *\n * The worklist is the point of the command rather than a summary: a fleet list\n * that only listed would leave the reader to work out which services are\n * behind, which is the question they opened it with.\n */\nimport { MATURITY_LADDER, maturityRollup } from \"../../core/vocabulary/maturity.js\";\nimport { type CapabilityRow } from \"../../core/capabilities/rollup.js\";\nimport { compareIds, type FeatureEntry } from \"../../core/repo/entries.js\";\nimport type { PromisesKept } from \"../../core/usecases/capability.js\";\nimport type { FleetTree } from \"../../core/repo/tree/walk.js\";\nimport type { OwnedRow, OwnersJoin } from \"./campaign/owners.js\";\nimport { type ServiceView, type VerificationCell } from \"./views.js\";\n\nfunction serviceFlags(v: ServiceView): string {\n const s = v.entry;\n return [\n s.has.model ? \"M\" : \"-\",\n s.has.spec ? \"S\" : \"-\",\n v.archSpec ? \"a\" : \"-\",\n s.has.openapi ? \"A\" : \"-\",\n // The async contract, lowercase like the arch spec and for the same reason:\n // it is optional. A fleet where most services own no topic must not read as\n // a fleet with a column of gaps in it.\n s.has.asyncapi ? \"e\" : \"-\",\n s.has.runbook ? \"R\" : \"-\",\n s.has.health ? \"H\" : \"-\",\n ].join(\" \");\n}\n\n/**\n * The rung as a person reads it. `vouched (sampled)` is a DISPLAY string, not\n * a rung: the ladder, the rollup below and `--needs-work` all still see\n * `vouched`, because that string is a published contract and the document\n * really is stamped by a person. What the suffix says is what the stamp says\n * — they read a recorded sample of it, and `loam validate` will report\n * `sources.sampled-vouch` until somebody reads the rest. Without it, the one\n * line a fleet lead scans for trust would show a sampled vouch and a full one\n * as the same word.\n *\n * Only on `vouched`: a lower rung already says less than \"a person vouched\",\n * and hanging a scope note on it would explain a claim nothing is making.\n */\nfunction rungLabel(v: ServiceView): string {\n return v.maturity === \"vouched\" && v.entry.vouchScope === \"sampled\" ? \"vouched (sampled)\" : v.maturity;\n}\n\n/**\n * The two facts printed under the table that are not about any row — and they\n * are withheld differently, which is the whole reason to name the record\n * instead of passing two arguments and hoping the next caller notices.\n */\nexport interface FleetFacts {\n /**\n * The subsystem tree, or undefined under `--subsystem`. A slice's own\n * \"unfiled: 0\" would be read as a fact about the slice, and it is not one.\n */\n tree: FleetTree | undefined;\n /**\n * Markdown files in `architecture/adrs/`. NEVER withheld: unlike the tree\n * dial it is not derived from the rows at all — the same fleet documents are\n * there whichever services this run listed — and the line names the directory\n * so it cannot be misread as a subsystem's own decisions. 0 prints nothing.\n */\n adrs: number;\n}\n\nexport function printServices(views: ServiceView[], fleet: FleetFacts): void {\n console.log(\n `services (${views.length}) [M]odel [S]pec [a]rch-spec [A]pi [R]unbook [H]ealth`,\n );\n const width = Math.max(0, ...views.map((v) => v.entry.id.length));\n // Measured over the DISPLAY strings, so the column does not shear the first\n // time a sampled row appears in a fleet.\n const rungWidth = Math.max(0, ...views.map((v) => rungLabel(v).length));\n for (const v of views) {\n const s = v.entry;\n const adrs = s.adrs > 0 ? ` (${s.adrs} adr${s.adrs === 1 ? \"\" : \"s\"})` : \"\";\n // The rung per service, not only in the rollup: \"12 partial\" tells a reader\n // the fleet is unfinished and nothing about which twelve, which is the one\n // question the line is read to answer.\n console.log(\n ` ${serviceFlags(v)} ${s.id.padEnd(width)} ${rungLabel(v).padEnd(rungWidth)}${adrs}`.trimEnd(),\n );\n }\n // How much of the fleet anyone has actually vouched for. On 100+ services this\n // is the number that says whether the docs can be trusted at all.\n if (views.length > 0) {\n const counted = new Map<string, number>();\n for (const v of views) {\n const key = v.entry.status ?? \"unmarked\";\n counted.set(key, (counted.get(key) ?? 0) + 1);\n }\n const parts = [...counted.entries()]\n .sort((a, b) => compareIds(a[0], b[0]))\n .map(([status, n]) => `${n} ${status}`);\n console.log(` status: ${parts.join(\" · \")}`);\n // The campaign dial next to the trust dial: rungs in ladder order, so the\n // line reads as progress left to right. Presence and provenance state only\n // — completeness is unchecked, so this line never says \"adopted\".\n const rollup = maturityRollup(views);\n // The rollup itself is untouched — the rung IS `vouched`, and both the\n // `--json` payload and `--needs-work` are computed from it. What the TEXT\n // line adds is the qualifier the per-row suffix already carries, because\n // this is the line a fleet lead reads for the trust answer, and recovering\n // \"how many of those 118 did anybody read in full\" by scanning 118 rows is\n // not an answer. Same layout as the validate scorecard's provenance row.\n const sampled = views.filter((v) => v.maturity === \"vouched\" && v.entry.vouchScope === \"sampled\").length;\n const rungs = MATURITY_LADDER.filter((m) => rollup[m] > 0).map(\n (m) => `${rollup[m]} ${m}${m === \"vouched\" && sampled > 0 ? ` (${sampled} sampled)` : \"\"}`,\n );\n console.log(` maturity: ${rungs.join(\" · \")}`);\n // The tree dial, only once a tree exists: unfiled is permanent and normal\n // (a count, never a finding), and a flat fleet has nothing to say here —\n // printing \"5 unfiled\" over a fleet nobody groups would read as work.\n if (fleet.tree !== undefined && fleet.tree.subsystems.length > 0) {\n const unfiled = fleet.tree.services.filter((s) => s.subsystem.length === 0).length;\n console.log(` subsystems: ${fleet.tree.subsystems.length} · unfiled: ${unfiled}`);\n }\n }\n // OUTSIDE the rollup block above, which only runs when the fleet has\n // services: a fleet can record a decision about how it will build services\n // before it holds one, and that count would otherwise be printed by nothing.\n // Silent at zero, exactly like the per-service `(3 adrs)` column: no fleet\n // owes any fleet-level ADR, so \"adrs: 0\" would read as a gap.\n if (fleet.adrs > 0) {\n console.log(` adrs: ${fleet.adrs} fleet decision${fleet.adrs === 1 ? \"\" : \"s\"} (architecture/adrs/)`);\n }\n}\n\n/**\n * The one-shot adoption worklist. Onboarding ten legacy services means asking\n * \"what is left\" once a day for a month, and the answer used to require reading\n * a presence table and a rollup and joining them by eye. A service whose\n * provenance cannot be judged from here is LISTED, tagged, never dropped:\n * omitting it would read as done.\n */\nexport function printWorklist(\n views: ServiceView[],\n total: number,\n fanIn?: ReadonlyMap<string, number>,\n): void {\n if (views.length === 0) {\n console.log(`nothing to do — all ${total} service(s) are vouched`);\n return;\n }\n // Under --review-order the caller hands the rows pre-sorted; the header\n // names the derivation as a caller count, never a priority judgement — the\n // number is who depends on the service, not how important it is.\n const ordered = fanIn === undefined ? \"\" : \" — review order (fan-in: services depending on each)\";\n console.log(`${views.length} of ${total} service(s) need work${ordered}`);\n const width = Math.max(0, ...views.map((v) => v.entry.id.length));\n const rungWidth = Math.max(0, ...views.map((v) => rungLabel(v).length));\n const cells = fanIn === undefined ? undefined : views.map((v) => `fan-in: ${fanIn.get(v.entry.id) ?? 0}`);\n const cellWidth = cells === undefined ? 0 : Math.max(0, ...cells.map((c) => c.length));\n for (const [i, v] of views.entries()) {\n const note = v.unverifiableFromHere ? \" (provenance: unverifiable-from-here)\" : \"\";\n // Indexing the same array the loop walks, like printFeatures' cells below.\n const cell = cells === undefined ? \"\" : ` ${cells[i]!.padEnd(cellWidth)}`;\n console.log(\n ` ${v.entry.id.padEnd(width)} ${rungLabel(v).padEnd(rungWidth)}${cell} missing: ${v.missing.join(\", \")}${note}`,\n );\n }\n}\n\n/**\n * The owner-grouped view under `--owners`: every row of the current listing\n * filed under the team CODEOWNERS names for its directory, unowned last —\n * the per-team campaign queues, each in the exact order the ungrouped\n * listing would print. Text side only; the ids-per-team contract is\n * json.ts's `ownersJson`.\n */\nexport function printOwners(\n join: OwnersJoin,\n byDir: ReadonlyMap<string, ServiceView>,\n fanIn?: ReadonlyMap<string, number>,\n): void {\n const row = (r: OwnedRow): void => {\n // Joined back by DIRECTORY, the row's identity — ids can collide across\n // a broken tree, and an id-keyed map would print one twin's cells under\n // the other twin's team. The join was computed from these same rows so a\n // miss is unreachable, but it is a key join on purpose (docs/CODE-STYLE.md:\n // never join two arrays by position) — and a miss prints the bare id\n // LOUDLY rather than vanishing, so a future row-set drift shows itself.\n const v = byDir.get(r.repoDir);\n if (v === undefined) {\n console.log(` ${r.id}`);\n return;\n }\n const cell = fanIn === undefined ? \"\" : ` fan-in: ${fanIn.get(r.id) ?? 0}`;\n const missing = v.missing.length > 0 ? ` missing: ${v.missing.join(\", \")}` : \"\";\n console.log(` ${r.id} ${rungLabel(v)}${cell}${missing}`);\n };\n for (const team of join.teams) {\n console.log(` ${team.owner} (${team.services.length})`);\n for (const r of team.services) row(r);\n }\n // Explicit even in a heading: an unmatched service silently absent from\n // every team's queue would read as somebody else's work.\n if (join.unowned.length > 0) {\n console.log(` unowned (${join.unowned.length})`);\n for (const r of join.unowned) row(r);\n }\n if (join.skipped.length > 0) {\n // Line AND pattern: `* @org/all` is the most common CODEOWNERS opener,\n // and a note naming only \"line 1\" would leave the reader unable to tell\n // the fleet-wide default was skipped rather than some docs rule.\n console.log(\n ` note: ${join.skipped.length} rule(s) outside the supported CODEOWNERS subset skipped: ${join.skipped\n .map((rule) => `line ${rule.line} (${rule.pattern})`)\n .join(\", \")}`,\n );\n }\n}\n\n/**\n * The capability table: what the fleet promises, and how much of each promise\n * anything claims to implement. The `0 — unrealized` marker is the row's whole\n * point — a declared capability nothing realizes is the drift this section\n * exists to make visible — and the draft/verified split says how much of a\n * realized one rests on vouched documents rather than drafts.\n *\n * `promises` is the use-case corpus's health, and it is a REQUIRED argument\n * rather than an optional decoration: the two states it separates are \"no flow\n * keeps this promise\" and \"loam could not read the flows\", and a default would\n * silently pick the first. A caller with nothing to say here has no business\n * printing a promises column at all.\n */\nexport function printCapabilities(rows: CapabilityRow[], promises: PromisesKept): void {\n console.log(`capabilities (${rows.length})`);\n if (rows.length === 0) return;\n const width = Math.max(0, ...rows.map((row) => row.id.length));\n for (const row of rows) {\n const count = row.realizedBy.length;\n const cells =\n count === 0\n ? [\"0 — unrealized\"]\n : [\n `${count} requirement${count === 1 ? \"\" : \"s\"}`,\n row.services.join(\", \"),\n Object.entries(row.statuses)\n .map(([status, n]) => `${n} ${status}`)\n .join(\" · \"),\n ];\n cells.push(...promiseCells(row, promises.kind === \"read\"));\n const owner = row.owner === undefined ? \"\" : ` (owner: ${row.owner})`;\n console.log(` ${row.id.padEnd(width)} ${cells.join(\" · \")}${owner}`);\n }\n // ONE note for the table, not one per row: every row is equally unanswered,\n // and the reader needs to be told the column is missing rather than empty.\n // The wording says UNKNOWN rather than none deliberately — this is the same\n // refusal `capability.requirement-unrealized` makes under `validate` when the\n // project did not parse, and the two surfaces must not read differently. The\n // parser's own message goes on its own line, exactly as `loam context` and\n // `loam delta` print theirs: a LikeC4 error is several lines of expected-token\n // list, and inlining it would push the sentence off the reader's screen.\n if (promises.kind === \"unreadable\") {\n console.log(\n \" note: architecture/ did not parse, so no business flow could be read — \" +\n \"which promises a use case keeps is UNKNOWN here, not none\",\n );\n if (promises.errors[0] !== undefined) console.log(` ${promises.errors[0]}`);\n }\n}\n\n/**\n * The promises cell(s) for one row: how many of a capability document's own\n * requirements anything keeps, and which flows keep any of them.\n *\n * Only for a capability that HAS a document — `requirements` absent means there\n * is no document to promise anything, and a `0 of 0` on such a row would read as\n * a gap where there is not even a claim.\n *\n * `flowsRead` false marks the count as PARTIAL in the cell itself and not only\n * in the note below the table. Without the suffix, a fleet whose promises are\n * all kept by flows prints `0 of 4 promises kept` over an unreadable\n * `architecture/` — a number a reader would act on before reaching the note,\n * and the exact false negative this axis exists to refuse.\n */\nfunction promiseCells(row: CapabilityRow, flowsRead: boolean): string[] {\n if (row.requirements === undefined) return [];\n const total = row.requirements.length;\n if (total === 0) return [];\n const kept = row.requirements.filter(\n (req) => req.realizedBy.length > 0 || (req.keptBy?.length ?? 0) > 0,\n ).length;\n // Distinct flows across the whole capability, sorted: the per-requirement\n // lists are already sorted, and a reader scanning this column wants the\n // documents to open, not the pairing (the `--json` rows carry that).\n const flows = [...new Set(row.requirements.flatMap((req) => req.keptBy ?? []))].sort(compareIds);\n const partial = flowsRead ? \"\" : \" (flows unread)\";\n return [`${kept} of ${total} promise${total === 1 ? \"\" : \"s\"} kept${partial}`]\n .concat(flows.length === 0 ? [] : [`flows: ${flows.join(\", \")}`]);\n}\n\n/** Narrow verification cell: confirmed/claims when a record answers, one word when it does not. */\nfunction verificationMark(v: VerificationCell | null): string {\n if (v === null) return \"-\";\n if (v.state === \"stale\") return \"stale\";\n // `11/11` and `11/11 attested` are different facts — the first is a\n // digest-matched green run, the second is somebody's word about one. Without\n // the suffix a complete count is the same glyph either way, which is exactly\n // the reading `verify`, `status` and the JSON envelope stopped giving.\n return `${v.confirmed}/${v.claims}${v.verdict === \"attested\" ? \" attested\" : \"\"}`;\n}\n\nexport function printFeatures(features: FeatureEntry[], verification: (VerificationCell | null)[]): void {\n const active = features.filter((f) => !f.archived).length;\n const archived = features.length - active;\n const counts = `${active} active${archived > 0 ? `, ${archived} archived` : \"\"}`;\n // Not `verified`: the column reports three verdicts and only one of them is\n // that one. A heading that names the strong verdict makes every other cell\n // read as it.\n console.log(`features (${counts}) [I]ntent [D]elta verification`);\n const width = Math.max(0, ...features.map((f) => f.id.length));\n const cells = verification.map(verificationMark);\n const cellWidth = Math.max(0, ...cells.map((c) => c.length));\n for (const [i, f] of features.entries()) {\n const flags = `${f.has.intent ? \"I\" : \"-\"} ${f.has.delta ? \"D\" : \"-\"}`;\n const svcs = f.services.length > 0 ? f.services.join(\", \") : \"—\";\n const tag = f.archived ? \" (archived)\" : \"\";\n console.log(` ${flags} ${f.id.padEnd(width)} ${cells[i]!.padEnd(cellWidth)} ${svcs}${tag}`);\n }\n}\n\n/**\n * The glossary table: what the domain's words are, and who actually uses each.\n *\n * The citation count is the column that matters — a definition nothing cites is\n * the drift `glossary.unlinked` warns about, and this is where a reader sees it\n * before the gate does. `unreadable` is printed as a note rather than folded\n * into the counts for `printCapabilities`' reason one section over: \"cited by\n * nobody\" and \"loam could not read everybody\" are different answers, and a\n * table that let them look alike would be the more comfortable of the two.\n */\nexport function printGlossary(\n rows: Array<{ id: string; linkedBy: string[] }>,\n unreadable: string[],\n): void {\n console.log(`glossary (${rows.length} term${rows.length === 1 ? \"\" : \"s\"})`);\n const width = Math.max(0, ...rows.map((row) => row.id.length));\n for (const row of rows) {\n const n = row.linkedBy.length;\n console.log(` ${row.id.padEnd(width)} ${n === 0 ? \"cited by nothing\" : `${n} document${n === 1 ? \"\" : \"s\"}`}`);\n }\n if (unreadable.length > 0) {\n console.log(\n ` note: ${unreadable.length} document(s) could not be read, so a citation from one of them is not counted here — ` +\n `\\`loam validate --all\\` names each as link.unreadable`,\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"print.js","sourceRoot":"","sources":["../../../src/commands/list/print.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,EAAsB,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAG5D,OAAO,EAA4D,MAAM,YAAY,CAAC;AAEtF;;;;GAIG;AACH,SAAS,YAAY,CAAC,CAAc;IAClC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;IAClB,OAAO;QACL,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;QACvB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;QACtB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;QACtB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;QACzB,4EAA4E;QAC5E,4EAA4E;QAC5E,uCAAuC;QACvC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;QAC1B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;QACzB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;KACzB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAS,SAAS,CAAC,CAAc;IAC/B,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IACtC,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3F,CAAC;AAED,0GAA0G;AAC1G,SAAS,eAAe,CAAC,CAAc;IACrC,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACxC,OAAO;QACL,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC;AACJ,CAAC;AAsBD,MAAM,UAAU,aAAa,CAAC,KAAoB,EAAE,KAAiB;IACnE,OAAO,CAAC,GAAG;IACT,wEAAwE;IACxE,6DAA6D;IAC7D,aAAa,KAAK,CAAC,MAAM,iEAAiE,CAC3F,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAClE,4EAA4E;IAC5E,yCAAyC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACxE,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;QAClB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,4EAA4E;QAC5E,2EAA2E;QAC3E,uCAAuC;QACvC,OAAO,CAAC,GAAG,CACT,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,CAAC,OAAO,EAAE,CAClG,CAAC;IACJ,CAAC;IACD,+EAA+E;IAC/E,kEAAkE;IAClE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC1C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,UAAU,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;aACjC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9C,0EAA0E;QAC1E,2EAA2E;QAC3E,kEAAkE;QAClE,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACrC,uEAAuE;QACvE,0EAA0E;QAC1E,yEAAyE;QACzE,2EAA2E;QAC3E,2EAA2E;QAC3E,yEAAyE;QACzE,wEAAwE;QACxE,MAAM,SAAS,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACpG,MAAM,KAAK,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtG,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAC5D,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACjG,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAChD,0EAA0E;QAC1E,yEAAyE;QACzE,sEAAsE;QACtE,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjE,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;YACnF,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,eAAe,OAAO,EAAE,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IACD,qEAAqE;IACrE,2EAA2E;IAC3E,6EAA6E;IAC7E,2EAA2E;IAC3E,8DAA8D;IAC9D,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,kBAAkB,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,wBAAwB,CAAC,CAAC;IAC1G,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAoB,EACpB,KAAa,EACb,KAAmC;IAEnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,yBAAyB,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IACD,wEAAwE;IACxE,2EAA2E;IAC3E,iEAAiE;IACjE,MAAM,OAAO,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sDAAsD,CAAC;IAClG,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,OAAO,KAAK,wBAAwB,OAAO,EAAE,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1G,MAAM,SAAS,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACvF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,wCAAwC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,2EAA2E;QAC3E,MAAM,IAAI,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3E,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,cAAc,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CACnH,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,IAAgB,EAChB,KAAuC,EACvC,KAAmC;IAEnC,MAAM,GAAG,GAAG,CAAC,CAAW,EAAQ,EAAE;QAChC,wEAAwE;QACxE,wEAAwE;QACxE,yEAAyE;QACzE,4EAA4E;QAC5E,qEAAqE;QACrE,wEAAwE;QACxE,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3B,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5E,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,OAAO,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACzD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ;YAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,wEAAwE;IACxE,yDAAyD;IACzD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAClD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO;YAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,uEAAuE;QACvE,wEAAwE;QACxE,iEAAiE;QACjE,OAAO,CAAC,GAAG,CACT,WAAW,IAAI,CAAC,OAAO,CAAC,MAAM,6DAA6D,IAAI,CAAC,OAAO;aACpG,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,GAAG,CAAC;aACpD,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAqB,EAAE,QAAsB;IAC7E,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QACpC,MAAM,KAAK,GACT,KAAK,KAAK,CAAC;YACT,CAAC,CAAC,CAAC,gBAAgB,CAAC;YACpB,CAAC,CAAC;gBACE,GAAG,KAAK,eAAe,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE;gBAC/C,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;gBACvB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;qBACzB,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;qBACtC,IAAI,CAAC,KAAK,CAAC;aACf,CAAC;QACR,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,KAAK,GAAG,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,4EAA4E;IAC5E,2EAA2E;IAC3E,4EAA4E;IAC5E,8EAA8E;IAC9E,6EAA6E;IAC7E,2EAA2E;IAC3E,+EAA+E;IAC/E,yEAAyE;IACzE,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACnC,OAAO,CAAC,GAAG,CACT,2EAA2E;YACzE,2DAA2D,CAC9D,CAAC;QACF,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,YAAY,CAAC,GAAkB,EAAE,SAAkB;IAC1D,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAC9C,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC;IACtC,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAClC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CACpE,CAAC,MAAM,CAAC;IACT,0EAA0E;IAC1E,wEAAwE;IACxE,qEAAqE;IACrE,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjG,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACnD,OAAO,CAAC,GAAG,IAAI,OAAO,KAAK,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,OAAO,EAAE,CAAC;SAC3E,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,mGAAmG;AACnG,SAAS,gBAAgB,CAAC,CAA0B;IAClD,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC3B,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IACxC,oEAAoE;IACpE,6EAA6E;IAC7E,6EAA6E;IAC7E,uEAAuE;IACvE,EAAE;IACF,2EAA2E;IAC3E,8EAA8E;IAC9E,0EAA0E;IAC1E,gEAAgE;IAChE,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,OAAO,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;AAC5F,CAAC;AAED,iFAAiF;AACjF,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,MAAM,UAAU,aAAa,CAAC,IAAkB;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IAC1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IAC1C,MAAM,MAAM,GAAG,GAAG,MAAM,UAAU,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACjF,4EAA4E;IAC5E,2EAA2E;IAC3E,cAAc;IACd,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,mCAAmC,CAAC,CAAC;IACpE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,sEAAsE;IACtE,oEAAoE;IACpE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACvE,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACjE,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC;IAC1G,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,IAA+C,EAC/C,UAAoB;IAEpB,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,MAAM,QAAQ,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnH,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CACT,WAAW,UAAU,CAAC,MAAM,uFAAuF;YACjH,uDAAuD,CAC1D,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["/**\n * The columns a person reads, and the worklist under them.\n *\n * The worklist is the point of the command rather than a summary: a fleet list\n * that only listed would leave the reader to work out which services are\n * behind, which is the question they opened it with.\n */\nimport { MATURITY_LADDER, maturityRollup } from \"../../core/vocabulary/maturity.js\";\nimport { type CapabilityRow } from \"../../core/capabilities/rollup.js\";\nimport { compareIds } from \"../../core/repo/entries.js\";\nimport type { PromisesKept } from \"../../core/usecases/capability.js\";\nimport { answeredSplit } from \"../../core/verify/record.js\";\nimport type { FleetTree } from \"../../core/repo/tree/walk.js\";\nimport type { OwnedRow, OwnersJoin } from \"./campaign/owners.js\";\nimport { type FeatureRow, type ServiceView, type VerificationCell } from \"./views.js\";\n\n/**\n * Fixed-width presence flags. `a` and `A` are deliberately the same letter in\n * two cases: the arch spec and the API are the two things a reader most often\n * mistakes for each other, and one is lowercase because it is optional.\n */\nfunction serviceFlags(v: ServiceView): string {\n const s = v.entry;\n return [\n s.has.model ? \"M\" : \"-\",\n s.has.spec ? \"S\" : \"-\",\n v.archSpec ? \"a\" : \"-\",\n s.has.openapi ? \"A\" : \"-\",\n // The async contract, lowercase like the arch spec and for the same reason:\n // it is optional. A fleet where most services own no topic must not read as\n // a fleet with a column of gaps in it.\n s.has.asyncapi ? \"e\" : \"-\",\n s.has.runbook ? \"R\" : \"-\",\n s.has.health ? \"H\" : \"-\",\n ].join(\" \");\n}\n\n/**\n * The rung as a person reads it. `vouched (sampled)` is a DISPLAY string, not\n * a rung: the ladder, the rollup below and `--needs-work` all still see\n * `vouched`, because that string is a published contract and the document\n * really is stamped by a person. What the suffix says is what the stamp says\n * — they read a recorded sample of it, and `loam validate` will report\n * `sources.sampled-vouch` until somebody reads the rest. Without it, the one\n * line a fleet lead scans for trust would show a sampled vouch and a full one\n * as the same word.\n *\n * Only on `vouched`: a lower rung already says less than \"a person vouched\",\n * and hanging a scope note on it would explain a claim nothing is making.\n *\n * `vouched (stale)` is the same kind of string for the other thing a stamp can\n * hide: the document's words moved after the person read them, and `loam\n * validate` reports `content.stale` until somebody re-vouches. Both can hold at\n * once — `vouched (sampled, stale)` — because they are different gaps.\n */\nfunction rungLabel(v: ServiceView): string {\n const qualifiers = vouchQualifiers(v);\n return qualifiers.length === 0 ? v.maturity : `${v.maturity} (${qualifiers.join(\", \")})`;\n}\n\n/** What a `vouched` row's stamp does not cover: a sample, and words moved since. Empty below the rung. */\nfunction vouchQualifiers(v: ServiceView): string[] {\n if (v.maturity !== \"vouched\") return [];\n return [\n ...(v.entry.vouchScope === \"sampled\" ? [\"sampled\"] : []),\n ...(v.entry.contentStale.length > 0 ? [\"stale\"] : []),\n ];\n}\n\n/**\n * The two facts printed under the table that are not about any row — and they\n * are withheld differently, which is the whole reason to name the record\n * instead of passing two arguments and hoping the next caller notices.\n */\nexport interface FleetFacts {\n /**\n * The subsystem tree, or undefined under `--subsystem`. A slice's own\n * \"unfiled: 0\" would be read as a fact about the slice, and it is not one.\n */\n tree: FleetTree | undefined;\n /**\n * Markdown files in `architecture/adrs/`. NEVER withheld: unlike the tree\n * dial it is not derived from the rows at all — the same fleet documents are\n * there whichever services this run listed — and the line names the directory\n * so it cannot be misread as a subsystem's own decisions. 0 prints nothing.\n */\n adrs: number;\n}\n\nexport function printServices(views: ServiceView[], fleet: FleetFacts): void {\n console.log(\n // One key per column serviceFlags prints, in its order — the `e` column\n // shipped without one, so the legend explained six of seven.\n `services (${views.length}) [M]odel [S]pec [a]rch-spec [A]pi [e]vents [R]unbook [H]ealth`,\n );\n const width = Math.max(0, ...views.map((v) => v.entry.id.length));\n // Measured over the DISPLAY strings, so the column does not shear the first\n // time a sampled row appears in a fleet.\n const rungWidth = Math.max(0, ...views.map((v) => rungLabel(v).length));\n for (const v of views) {\n const s = v.entry;\n const adrs = s.adrs > 0 ? ` (${s.adrs} adr${s.adrs === 1 ? \"\" : \"s\"})` : \"\";\n // The rung per service, not only in the rollup: \"12 partial\" tells a reader\n // the fleet is unfinished and nothing about which twelve, which is the one\n // question the line is read to answer.\n console.log(\n ` ${serviceFlags(v)} ${s.id.padEnd(width)} ${rungLabel(v).padEnd(rungWidth)}${adrs}`.trimEnd(),\n );\n }\n // How much of the fleet anyone has actually vouched for. On 100+ services this\n // is the number that says whether the docs can be trusted at all.\n if (views.length > 0) {\n const counted = new Map<string, number>();\n for (const v of views) {\n const key = v.entry.status ?? \"unmarked\";\n counted.set(key, (counted.get(key) ?? 0) + 1);\n }\n const parts = [...counted.entries()]\n .sort((a, b) => compareIds(a[0], b[0]))\n .map(([status, n]) => `${n} ${status}`);\n console.log(` status: ${parts.join(\" · \")}`);\n // The campaign dial next to the trust dial: rungs in ladder order, so the\n // line reads as progress left to right. Presence and provenance state only\n // — completeness is unchecked, so this line never says \"adopted\".\n const rollup = maturityRollup(views);\n // The rollup itself is untouched — the rung IS `vouched`, and both the\n // `--json` payload and `--needs-work` are computed from it. What the TEXT\n // line adds is the qualifier the per-row suffix already carries, because\n // this is the line a fleet lead reads for the trust answer, and recovering\n // \"how many of those 118 did anybody read in full\" by scanning 118 rows is\n // not an answer. Same layout as the validate scorecard's provenance row,\n // and the same two qualifiers the per-row suffix carries, each counted.\n const qualified = (q: string): number => views.filter((v) => vouchQualifiers(v).includes(q)).length;\n const notes = [\"sampled\", \"stale\"].filter((q) => qualified(q) > 0).map((q) => `${qualified(q)} ${q}`);\n const rungs = MATURITY_LADDER.filter((m) => rollup[m] > 0).map(\n (m) => `${rollup[m]} ${m}${m === \"vouched\" && notes.length > 0 ? ` (${notes.join(\", \")})` : \"\"}`,\n );\n console.log(` maturity: ${rungs.join(\" · \")}`);\n // The tree dial, only once a tree exists: unfiled is permanent and normal\n // (a count, never a finding), and a flat fleet has nothing to say here —\n // printing \"5 unfiled\" over a fleet nobody groups would read as work.\n if (fleet.tree !== undefined && fleet.tree.subsystems.length > 0) {\n const unfiled = fleet.tree.services.filter((s) => s.subsystem.length === 0).length;\n console.log(` subsystems: ${fleet.tree.subsystems.length} · unfiled: ${unfiled}`);\n }\n }\n // OUTSIDE the rollup block above, which only runs when the fleet has\n // services: a fleet can record a decision about how it will build services\n // before it holds one, and that count would otherwise be printed by nothing.\n // Silent at zero, exactly like the per-service `(3 adrs)` column: no fleet\n // owes any fleet-level ADR, so \"adrs: 0\" would read as a gap.\n if (fleet.adrs > 0) {\n console.log(` adrs: ${fleet.adrs} fleet decision${fleet.adrs === 1 ? \"\" : \"s\"} (architecture/adrs/)`);\n }\n}\n\n/**\n * The one-shot adoption worklist. Onboarding ten legacy services means asking\n * \"what is left\" once a day for a month, and the answer used to require reading\n * a presence table and a rollup and joining them by eye. A service whose\n * provenance cannot be judged from here is LISTED, tagged, never dropped:\n * omitting it would read as done.\n */\nexport function printWorklist(\n views: ServiceView[],\n total: number,\n fanIn?: ReadonlyMap<string, number>,\n): void {\n if (views.length === 0) {\n console.log(`nothing to do — all ${total} service(s) are vouched`);\n return;\n }\n // Under --review-order the caller hands the rows pre-sorted; the header\n // names the derivation as a caller count, never a priority judgement — the\n // number is who depends on the service, not how important it is.\n const ordered = fanIn === undefined ? \"\" : \" — review order (fan-in: services depending on each)\";\n console.log(`${views.length} of ${total} service(s) need work${ordered}`);\n const width = Math.max(0, ...views.map((v) => v.entry.id.length));\n const rungWidth = Math.max(0, ...views.map((v) => rungLabel(v).length));\n const cells = fanIn === undefined ? undefined : views.map((v) => `fan-in: ${fanIn.get(v.entry.id) ?? 0}`);\n const cellWidth = cells === undefined ? 0 : Math.max(0, ...cells.map((c) => c.length));\n for (const [i, v] of views.entries()) {\n const note = v.unverifiableFromHere ? \" (provenance: unverifiable-from-here)\" : \"\";\n // Indexing the same array the loop walks, like printFeatures' cells below.\n const cell = cells === undefined ? \"\" : ` ${cells[i]!.padEnd(cellWidth)}`;\n console.log(\n ` ${v.entry.id.padEnd(width)} ${rungLabel(v).padEnd(rungWidth)}${cell} missing: ${v.missing.join(\", \")}${note}`,\n );\n }\n}\n\n/**\n * The owner-grouped view under `--owners`: every row of the current listing\n * filed under the team CODEOWNERS names for its directory, unowned last —\n * the per-team campaign queues, each in the exact order the ungrouped\n * listing would print. Text side only; the ids-per-team contract is\n * json.ts's `ownersJson`.\n */\nexport function printOwners(\n join: OwnersJoin,\n byDir: ReadonlyMap<string, ServiceView>,\n fanIn?: ReadonlyMap<string, number>,\n): void {\n const row = (r: OwnedRow): void => {\n // Joined back by DIRECTORY, the row's identity — ids can collide across\n // a broken tree, and an id-keyed map would print one twin's cells under\n // the other twin's team. The join was computed from these same rows so a\n // miss is unreachable, but it is a key join on purpose (docs/CODE-STYLE.md:\n // never join two arrays by position) — and a miss prints the bare id\n // LOUDLY rather than vanishing, so a future row-set drift shows itself.\n const v = byDir.get(r.repoDir);\n if (v === undefined) {\n console.log(` ${r.id}`);\n return;\n }\n const cell = fanIn === undefined ? \"\" : ` fan-in: ${fanIn.get(r.id) ?? 0}`;\n const missing = v.missing.length > 0 ? ` missing: ${v.missing.join(\", \")}` : \"\";\n console.log(` ${r.id} ${rungLabel(v)}${cell}${missing}`);\n };\n for (const team of join.teams) {\n console.log(` ${team.owner} (${team.services.length})`);\n for (const r of team.services) row(r);\n }\n // Explicit even in a heading: an unmatched service silently absent from\n // every team's queue would read as somebody else's work.\n if (join.unowned.length > 0) {\n console.log(` unowned (${join.unowned.length})`);\n for (const r of join.unowned) row(r);\n }\n if (join.skipped.length > 0) {\n // Line AND pattern: `* @org/all` is the most common CODEOWNERS opener,\n // and a note naming only \"line 1\" would leave the reader unable to tell\n // the fleet-wide default was skipped rather than some docs rule.\n console.log(\n ` note: ${join.skipped.length} rule(s) outside the supported CODEOWNERS subset skipped: ${join.skipped\n .map((rule) => `line ${rule.line} (${rule.pattern})`)\n .join(\", \")}`,\n );\n }\n}\n\n/**\n * The capability table: what the fleet promises, and how much of each promise\n * anything claims to implement. The `0 — unrealized` marker is the row's whole\n * point — a declared capability nothing realizes is the drift this section\n * exists to make visible — and the draft/verified split says how much of a\n * realized one rests on vouched documents rather than drafts.\n *\n * `promises` is the use-case corpus's health, and it is a REQUIRED argument\n * rather than an optional decoration: the two states it separates are \"no flow\n * keeps this promise\" and \"loam could not read the flows\", and a default would\n * silently pick the first. A caller with nothing to say here has no business\n * printing a promises column at all.\n */\nexport function printCapabilities(rows: CapabilityRow[], promises: PromisesKept): void {\n console.log(`capabilities (${rows.length})`);\n if (rows.length === 0) return;\n const width = Math.max(0, ...rows.map((row) => row.id.length));\n for (const row of rows) {\n const count = row.realizedBy.length;\n const cells =\n count === 0\n ? [\"0 — unrealized\"]\n : [\n `${count} requirement${count === 1 ? \"\" : \"s\"}`,\n row.services.join(\", \"),\n Object.entries(row.statuses)\n .map(([status, n]) => `${n} ${status}`)\n .join(\" · \"),\n ];\n cells.push(...promiseCells(row, promises.kind === \"read\"));\n const owner = row.owner === undefined ? \"\" : ` (owner: ${row.owner})`;\n console.log(` ${row.id.padEnd(width)} ${cells.join(\" · \")}${owner}`);\n }\n // ONE note for the table, not one per row: every row is equally unanswered,\n // and the reader needs to be told the column is missing rather than empty.\n // The wording says UNKNOWN rather than none deliberately — this is the same\n // refusal `capability.requirement-unrealized` makes under `validate` when the\n // project did not parse, and the two surfaces must not read differently. The\n // parser's own message goes on its own line, exactly as `loam context` and\n // `loam delta` print theirs: a LikeC4 error is several lines of expected-token\n // list, and inlining it would push the sentence off the reader's screen.\n if (promises.kind === \"unreadable\") {\n console.log(\n \" note: architecture/ did not parse, so no business flow could be read — \" +\n \"which promises a use case keeps is UNKNOWN here, not none\",\n );\n if (promises.errors[0] !== undefined) console.log(` ${promises.errors[0]}`);\n }\n}\n\n/**\n * The promises cell(s) for one row: how many of a capability document's own\n * requirements anything keeps, and which flows keep any of them.\n *\n * Only for a capability that HAS a document — `requirements` absent means there\n * is no document to promise anything, and a `0 of 0` on such a row would read as\n * a gap where there is not even a claim.\n *\n * `flowsRead` false marks the count as PARTIAL in the cell itself and not only\n * in the note below the table. Without the suffix, a fleet whose promises are\n * all kept by flows prints `0 of 4 promises kept` over an unreadable\n * `architecture/` — a number a reader would act on before reaching the note,\n * and the exact false negative this axis exists to refuse.\n */\nfunction promiseCells(row: CapabilityRow, flowsRead: boolean): string[] {\n if (row.requirements === undefined) return [];\n const total = row.requirements.length;\n if (total === 0) return [];\n const kept = row.requirements.filter(\n (req) => req.realizedBy.length > 0 || (req.keptBy?.length ?? 0) > 0,\n ).length;\n // Distinct flows across the whole capability, sorted: the per-requirement\n // lists are already sorted, and a reader scanning this column wants the\n // documents to open, not the pairing (the `--json` rows carry that).\n const flows = [...new Set(row.requirements.flatMap((req) => req.keptBy ?? []))].sort(compareIds);\n const partial = flowsRead ? \"\" : \" (flows unread)\";\n return [`${kept} of ${total} promise${total === 1 ? \"\" : \"s\"} kept${partial}`]\n .concat(flows.length === 0 ? [] : [`flows: ${flows.join(\", \")}`]);\n}\n\n/** Narrow verification cell: confirmed/claims when a record answers, one word when it does not. */\nfunction verificationMark(v: VerificationCell | null): string {\n if (v === null) return \"-\";\n if (v.state === \"stale\") return \"stale\";\n // `11/11` and `11/11 attested` are different facts — the first is a\n // digest-matched green run, the second is somebody's word about one. Without\n // the suffix a complete count is the same glyph either way, which is exactly\n // the reading `verify`, `status` and the JSON envelope stopped giving.\n //\n // And who answered the confirmed ones, beside it. The verdict turns on the\n // scenario claims alone, so `7/7` under a verified record still read as seven\n // runs where two were an agent's word about a permission or an edge — the\n // split `--json` carried in `answered` and this column did not.\n const split = v.confirmed > 0 ? ` (${answeredSplit(v.answered)})` : \"\";\n return `${v.confirmed}/${v.claims}${v.verdict === \"attested\" ? \" attested\" : \"\"}${split}`;\n}\n\n/** How wide the title column may grow before a title is cut with an ellipsis. */\nconst TITLE_WIDTH = 40;\n\nexport function printFeatures(rows: FeatureRow[]): void {\n const features = rows.map((r) => r.feature);\n const active = features.filter((f) => !f.archived).length;\n const archived = features.length - active;\n const counts = `${active} active${archived > 0 ? `, ${archived} archived` : \"\"}`;\n // Not `verified`: the column reports three verdicts and only one of them is\n // that one. A heading that names the strong verdict makes every other cell\n // read as it.\n console.log(`features (${counts}) [I]ntent [D]elta verification`);\n const width = Math.max(0, ...features.map((f) => f.id.length));\n // The title beside the id: an id is a key, and a table of keys told a\n // newcomer which rows existed but not which change any of them was.\n const titles = rows.map((r) => {\n const t = r.title ?? \"\";\n return t.length > TITLE_WIDTH ? `${t.slice(0, TITLE_WIDTH - 1)}…` : t;\n });\n const titleWidth = Math.max(0, ...titles.map((t) => t.length));\n const cells = rows.map((r) => verificationMark(r.cell));\n const cellWidth = Math.max(0, ...cells.map((c) => c.length));\n for (const [i, f] of features.entries()) {\n const flags = `${f.has.intent ? \"I\" : \"-\"} ${f.has.delta ? \"D\" : \"-\"}`;\n const svcs = f.services.length > 0 ? f.services.join(\", \") : \"—\";\n const tag = f.archived ? \" (archived)\" : \"\";\n const title = titleWidth === 0 ? \"\" : `${titles[i]!.padEnd(titleWidth)} `;\n console.log(` ${flags} ${f.id.padEnd(width)} ${title}${cells[i]!.padEnd(cellWidth)} ${svcs}${tag}`);\n }\n}\n\n/**\n * The glossary table: what the domain's words are, and who actually uses each.\n *\n * The citation count is the column that matters — a definition nothing cites is\n * the drift `glossary.unlinked` warns about, and this is where a reader sees it\n * before the gate does. `unreadable` is printed as a note rather than folded\n * into the counts for `printCapabilities`' reason one section over: \"cited by\n * nobody\" and \"loam could not read everybody\" are different answers, and a\n * table that let them look alike would be the more comfortable of the two.\n */\nexport function printGlossary(\n rows: Array<{ id: string; linkedBy: string[] }>,\n unreadable: string[],\n): void {\n console.log(`glossary (${rows.length} term${rows.length === 1 ? \"\" : \"s\"})`);\n const width = Math.max(0, ...rows.map((row) => row.id.length));\n for (const row of rows) {\n const n = row.linkedBy.length;\n console.log(` ${row.id.padEnd(width)} ${n === 0 ? \"cited by nothing\" : `${n} document${n === 1 ? \"\" : \"s\"}`}`);\n }\n if (unreadable.length > 0) {\n console.log(\n ` note: ${unreadable.length} document(s) could not be read, so a citation from one of them is not counted here — ` +\n `\\`loam validate --all\\` names each as link.unreadable`,\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `loam list suites [<name>]` — which use cases run together, and WHICH
|
|
3
|
+
* SERVICES MUST BE UP for a suite's journeys to run.
|
|
4
|
+
*
|
|
5
|
+
* That answer is maintained by hand in most fleets — a compose file, a CI
|
|
6
|
+
* matrix, a paragraph in a runbook — and it is derivable, because a journey
|
|
7
|
+
* already names every participant it touches and the fleet map already says
|
|
8
|
+
* which `services/<id>/` each of those elements stands for. Deriving it means it
|
|
9
|
+
* cannot drift from the journeys: add a hop to a flow and the environment its
|
|
10
|
+
* suites need changes in the same commit. The grouping and the union are
|
|
11
|
+
* `core/usecases/suites/`; this module turns them into the section's payload
|
|
12
|
+
* and its text.
|
|
13
|
+
*
|
|
14
|
+
* A sub-package of list/ for `./campaign/`'s reason: the list package stands at
|
|
15
|
+
* its five-file limit. The direction is list → list/suites, never back.
|
|
16
|
+
*
|
|
17
|
+
* ONE SHAPE whether or not a suite was named. Naming one is a filter over the
|
|
18
|
+
* same answer, not a different question, so `suites[]` narrows and nothing else
|
|
19
|
+
* does — `ungrouped[]` in particular stays the fleet's, because which journeys
|
|
20
|
+
* reached no suite is not a fact about the suite being asked after.
|
|
21
|
+
*
|
|
22
|
+
* The use-case corpus's health travels as `useCases`, spelled as `list
|
|
23
|
+
* capabilities`, `status` and `delta` spell it (`unreadable`, `error`), plus a
|
|
24
|
+
* `state` this section needs and they do not: here the corpus IS the rows, so
|
|
25
|
+
* "the fleet declares no use case" (`absent`) and "loam read them" (`ok`) are
|
|
26
|
+
* two answers a reader has to be able to tell apart from one empty list. Over an
|
|
27
|
+
* unreadable `architecture/` the section DEGRADES rather than refusing, exactly
|
|
28
|
+
* as `list capabilities` does: `suites` and `ungrouped` are ABSENT keys — `[]`
|
|
29
|
+
* would be "loam looked and found none", said about a project nobody read — and
|
|
30
|
+
* a named suite is not refused as unknown, because that refusal would be a
|
|
31
|
+
* claim about suites loam never saw.
|
|
32
|
+
*/
|
|
33
|
+
import { fail } from "../../../core/envelope/json.js";
|
|
34
|
+
import { listServices } from "../../../core/repo/repo.js";
|
|
35
|
+
import { closeNamesHint } from "../../../core/repo/tree/find.js";
|
|
36
|
+
import { readUseCases } from "../../../core/usecases/fleet.js";
|
|
37
|
+
import { viewFile } from "../../../core/usecases/place.js";
|
|
38
|
+
import { suiteListing } from "../../../core/usecases/suites/suites.js";
|
|
39
|
+
/**
|
|
40
|
+
* Read the fleet's use cases and group them, or refuse an unknown suite name.
|
|
41
|
+
*
|
|
42
|
+
* Returns `null` when it has already refused — the caller's cue to stop, the
|
|
43
|
+
* `resolveSubsystemSlice` convention one package over.
|
|
44
|
+
*
|
|
45
|
+
* The services are enumerated for the RESOLVER, not for the rows: the
|
|
46
|
+
* element→service join needs the fleet set for the reason every edge join does
|
|
47
|
+
* (`readUseCases`' `UseCaseRequest.known`), and without it a step into
|
|
48
|
+
* `orders.api` would resolve to a service called "api".
|
|
49
|
+
*/
|
|
50
|
+
export async function suitesSection(req) {
|
|
51
|
+
const entries = await listServices(req.docsDir, req.fleet);
|
|
52
|
+
const scan = await readUseCases({ docsDir: req.docsDir, known: new Set(entries.map((e) => e.id)) });
|
|
53
|
+
if (scan.kind === "unreadable") {
|
|
54
|
+
const error = scan.errors[0];
|
|
55
|
+
return {
|
|
56
|
+
payload: { useCases: { state: "unreadable", unreadable: true, ...(error === undefined ? {} : { error }) } },
|
|
57
|
+
print: () => printUnreadable(error),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const listing = suiteListing(scan);
|
|
61
|
+
const state = scan.views.length === 0 ? "absent" : "ok";
|
|
62
|
+
const shown = req.name === undefined ? listing.suites : listing.suites.filter((s) => s.name === req.name);
|
|
63
|
+
if (req.name !== undefined && shown.length === 0) {
|
|
64
|
+
const names = listing.suites.map((s) => s.name);
|
|
65
|
+
// `unknown-target`, the code `--subsystem` and `show` use for a name that
|
|
66
|
+
// resolves to nothing, with the same close-name hint — an empty environment
|
|
67
|
+
// for a typo would read as a suite that needs nothing started.
|
|
68
|
+
fail(req.json, "unknown-target", `No suite '${req.name}'.` +
|
|
69
|
+
closeNamesHint(req.name, names, names.length === 0
|
|
70
|
+
? " No use case under architecture/ carries a `#suite-` tag."
|
|
71
|
+
: ` Declared suites: ${names.join(", ")}.`));
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
payload: {
|
|
76
|
+
suites: shown.map(suiteJson),
|
|
77
|
+
ungrouped: listing.ungrouped.map(viewJson),
|
|
78
|
+
useCases: { state, unreadable: false },
|
|
79
|
+
},
|
|
80
|
+
print: () => printSuites(shown, listing.ungrouped, state === "absent"),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/** A use case as the payload names it: enough to open the document it is written in. */
|
|
84
|
+
function viewJson(view) {
|
|
85
|
+
return { id: view.id, file: viewFile(view) };
|
|
86
|
+
}
|
|
87
|
+
function suiteJson(suite) {
|
|
88
|
+
return {
|
|
89
|
+
name: suite.name,
|
|
90
|
+
views: suite.views.map(viewJson),
|
|
91
|
+
services: suite.services,
|
|
92
|
+
unresolved: suite.unresolved,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* One block per suite — its services, then the participants a stand cannot
|
|
97
|
+
* start — then the journeys in no suite.
|
|
98
|
+
*
|
|
99
|
+
* An unresolved participant gets a line of its own with a marker rather than
|
|
100
|
+
* being folded into the service list: it is not a service anybody can start,
|
|
101
|
+
* and reading it as one is how an environment comes up short.
|
|
102
|
+
*/
|
|
103
|
+
function printSuites(suites, ungrouped, absent) {
|
|
104
|
+
if (absent) {
|
|
105
|
+
console.log("no use cases — no dynamic view under architecture/ carries #cap-, #req- or #suite-, so there are no suites");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (suites.length === 0)
|
|
109
|
+
console.log("no suites — no use case under architecture/ carries a #suite- tag");
|
|
110
|
+
for (const [i, suite] of suites.entries()) {
|
|
111
|
+
if (i > 0)
|
|
112
|
+
console.log("");
|
|
113
|
+
console.log(`suite ${suite.name} — ${suite.views.length} use case(s), ${suite.services.length} service(s) must be up`);
|
|
114
|
+
for (const service of suite.services)
|
|
115
|
+
console.log(` ${service}`);
|
|
116
|
+
for (const missing of suite.unresolved) {
|
|
117
|
+
console.log(` ! ${missing.element} — resolves to no service in services/` +
|
|
118
|
+
(missing.external ? " (#external: bring a double)" : ""));
|
|
119
|
+
}
|
|
120
|
+
console.log(` use cases: ${suite.views.map((v) => v.id).join(", ")}`);
|
|
121
|
+
}
|
|
122
|
+
console.log("");
|
|
123
|
+
console.log(`use cases in no suite (${ungrouped.length})`);
|
|
124
|
+
const width = Math.max(0, ...ungrouped.map((v) => v.id.length));
|
|
125
|
+
for (const view of ungrouped)
|
|
126
|
+
console.log(` ${view.id.padEnd(width)} ${viewFile(view)}`);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The `list capabilities` note, in this section's words: UNKNOWN rather than
|
|
130
|
+
* none, and the parser's own message on its own line, because a LikeC4 error is
|
|
131
|
+
* several lines of expected-token list and inlining it would push the sentence
|
|
132
|
+
* off the reader's screen.
|
|
133
|
+
*/
|
|
134
|
+
function printUnreadable(error) {
|
|
135
|
+
console.log("note: architecture/ did not parse, so no use case could be read — " +
|
|
136
|
+
"which suites exist, and what each needs up, is UNKNOWN here, not none");
|
|
137
|
+
if (error !== undefined)
|
|
138
|
+
console.log(` ${error}`);
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=suites.js.map
|