@intentius/chant 0.100.0 → 0.102.0
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/dist/agents/checks.d.ts.map +1 -1
- package/dist/attrref.d.ts.map +1 -1
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/nginx.d.ts.map +1 -1
- package/dist/audit/prior-art.d.ts +48 -0
- package/dist/audit/prior-art.d.ts.map +1 -1
- package/dist/behaviour-kinds.d.ts.map +1 -1
- package/dist/build.d.ts +6 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/cli/build-options.d.ts +2 -0
- package/dist/cli/build-options.d.ts.map +1 -1
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/carve-emit.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.d.ts +16 -0
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/import.d.ts +8 -0
- package/dist/cli/commands/import.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts +19 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/onboard.d.ts +9 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/commands/pinned-upgrade.d.ts +19 -5
- package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -1
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +9 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/lsp/server.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/tools/build.d.ts.map +1 -1
- package/dist/cli/mcp/tools/composites.d.ts.map +1 -1
- package/dist/cli/mcp/tools/explain.d.ts.map +1 -1
- package/dist/cli/mcp/tools/import.d.ts.map +1 -1
- package/dist/cli/mcp/tools/lint.d.ts.map +1 -1
- package/dist/cli/mcp/tools/scaffold.d.ts.map +1 -1
- package/dist/cli/mcp/tools/search.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-tools.d.ts +9 -1
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +33 -2
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/fetch.d.ts.map +1 -1
- package/dist/codegen/naming.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.d.ts +67 -3
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
- package/dist/codegen/registry.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/verbs/process-runner.d.ts.map +1 -1
- package/dist/components/verbs/r2-sync.d.ts.map +1 -1
- package/dist/components/verbs/run-agent.d.ts.map +1 -1
- package/dist/components/verbs/sbom-generator.d.ts.map +1 -1
- package/dist/components/verbs/sign.d.ts.map +1 -1
- package/dist/components/verbs/verify.d.ts.map +1 -1
- package/dist/components/verbs/vuln-gate.d.ts.map +1 -1
- package/dist/components/verbs/vuln-scan.d.ts.map +1 -1
- package/dist/components/verbs/wrangler.d.ts.map +1 -1
- package/dist/composite.d.ts.map +1 -1
- package/dist/config.d.ts +30 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/declarable.d.ts +16 -0
- package/dist/declarable.d.ts.map +1 -1
- package/dist/discovery/cache.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +15 -5
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/param-deps.d.ts +16 -0
- package/dist/discovery/param-deps.d.ts.map +1 -1
- package/dist/discovery/sandbox/policy-wire.d.ts.map +1 -1
- package/dist/discovery/specifier-resolve.d.ts +37 -0
- package/dist/discovery/specifier-resolve.d.ts.map +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/fold/fold.d.ts +3 -1
- package/dist/fold/fold.d.ts.map +1 -1
- package/dist/graph-detail.d.ts.map +1 -1
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-layout.d.ts.map +1 -1
- package/dist/import/base-parser.d.ts.map +1 -1
- package/dist/import/embedded.d.ts +7 -0
- package/dist/import/embedded.d.ts.map +1 -1
- package/dist/import/parser-options.d.ts +14 -0
- package/dist/import/parser-options.d.ts.map +1 -0
- package/dist/import/parser.d.ts +17 -0
- package/dist/import/parser.d.ts.map +1 -1
- package/dist/kubectl-context.d.ts.map +1 -1
- package/dist/lexicon-output.d.ts.map +1 -1
- package/dist/lexicon-schema.d.ts +3 -3
- package/dist/lexicon.d.ts +78 -3
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/assert-live.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +15 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/member-ledger.d.ts.map +1 -1
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/plan-digest.d.ts +26 -5
- package/dist/lifecycle/plan-digest.d.ts.map +1 -1
- package/dist/lifecycle/plan-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/scenario.d.ts.map +1 -1
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lifecycle/work-lease.d.ts +61 -2
- package/dist/lifecycle/work-lease.d.ts.map +1 -1
- package/dist/lint/config.d.ts +4 -4
- package/dist/lint/engine.d.ts +6 -0
- package/dist/lint/engine.d.ts.map +1 -1
- package/dist/lsp/lexicon-providers.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.d.ts +12 -11
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/apply.d.ts +79 -9
- package/dist/op/activities/apply.d.ts.map +1 -1
- package/dist/op/activities/decide.d.ts.map +1 -1
- package/dist/op/activities/index.d.ts +1 -1
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/lexicon-upgrade.d.ts +44 -12
- package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -1
- package/dist/op/activities/propose-upgrade.d.ts +2 -0
- package/dist/op/activities/propose-upgrade.d.ts.map +1 -1
- package/dist/op/activity-contract.d.ts +1 -1
- package/dist/op/activity-failure.d.ts.map +1 -1
- package/dist/op/activity-profiles.d.ts.map +1 -1
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/composites/apply-op.d.ts +12 -5
- package/dist/op/composites/apply-op.d.ts.map +1 -1
- package/dist/op/composites/lexicon-upgrade-op.d.ts +22 -6
- package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -1
- package/dist/op/decide-backend.d.ts.map +1 -1
- package/dist/op/decide-read-inputs.d.ts.map +1 -1
- package/dist/op/emulator-lifecycle.d.ts +21 -2
- package/dist/op/emulator-lifecycle.d.ts.map +1 -1
- package/dist/op/gate-approval.d.ts +5 -1
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-wait.d.ts.map +1 -1
- package/dist/op/gate.d.ts +19 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/index.d.ts +3 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/local-executor.d.ts +6 -0
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/operator.d.ts.map +1 -1
- package/dist/op/run-context.d.ts +39 -0
- package/dist/op/run-context.d.ts.map +1 -0
- package/dist/op/run-live.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/source-archive.d.ts.map +1 -1
- package/dist/op/steward-beside.d.ts.map +1 -1
- package/dist/op/steward-points.d.ts.map +1 -1
- package/dist/op/steward.d.ts.map +1 -1
- package/dist/op/types.d.ts +8 -3
- package/dist/op/types.d.ts.map +1 -1
- package/dist/op/work-lease-run.d.ts +24 -4
- package/dist/op/work-lease-run.d.ts.map +1 -1
- package/dist/project-root.d.ts.map +1 -1
- package/dist/provenance.d.ts +21 -0
- package/dist/provenance.d.ts.map +1 -1
- package/dist/pseudo-parameter.d.ts.map +1 -1
- package/dist/reconcile.d.ts.map +1 -1
- package/dist/secret-materialization.d.ts.map +1 -1
- package/dist/serializer.d.ts +8 -0
- package/dist/serializer.d.ts.map +1 -1
- package/dist/telemetry-attribution.d.ts +77 -0
- package/dist/telemetry-attribution.d.ts.map +1 -0
- package/dist/terraform/emit-source.d.ts.map +1 -1
- package/dist/terraform/parse.d.ts.map +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/decide-workspace.d.ts +1 -1
- package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -1
- package/dist/workspace/agent-cli.d.ts +88 -0
- package/dist/workspace/agent-cli.d.ts.map +1 -0
- package/dist/workspace/box-factory.d.ts +73 -0
- package/dist/workspace/box-factory.d.ts.map +1 -0
- package/dist/workspace/changes-cli.d.ts.map +1 -1
- package/dist/workspace/changes.d.ts +8 -1
- package/dist/workspace/changes.d.ts.map +1 -1
- package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -1
- package/dist/workspace/checks/boxes.d.ts.map +1 -1
- package/dist/workspace/checks/links.d.ts +1 -0
- package/dist/workspace/checks/links.d.ts.map +1 -1
- package/dist/workspace/checks/live.d.ts +40 -0
- package/dist/workspace/checks/live.d.ts.map +1 -0
- package/dist/workspace/checks.d.ts +26 -2
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/compose-graph.d.ts +73 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/conformance/index.d.ts +67 -6
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/vitest.d.ts +12 -3
- package/dist/workspace/conformance/vitest.d.ts.map +1 -1
- package/dist/workspace/conformance/writer.d.ts +368 -0
- package/dist/workspace/conformance/writer.d.ts.map +1 -0
- package/dist/workspace/decide.d.ts +1 -1
- package/dist/workspace/decide.d.ts.map +1 -1
- package/dist/workspace/declaration.d.ts +119 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.schema.json +368 -4
- package/dist/workspace/export-cli.d.ts +12 -0
- package/dist/workspace/export-cli.d.ts.map +1 -0
- package/dist/workspace/export.d.ts +145 -0
- package/dist/workspace/export.d.ts.map +1 -0
- package/dist/workspace/generated-files.d.ts.map +1 -1
- package/dist/workspace/graph-cache.d.ts.map +1 -1
- package/dist/workspace/graph-cli.d.ts +2 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/identity.d.ts +111 -0
- package/dist/workspace/identity.d.ts.map +1 -0
- package/dist/workspace/import.d.ts +73 -0
- package/dist/workspace/import.d.ts.map +1 -0
- package/dist/workspace/intent-cli.d.ts +7 -4
- package/dist/workspace/intent-cli.d.ts.map +1 -1
- package/dist/workspace/intent-record.d.ts +8 -1
- package/dist/workspace/intent-record.d.ts.map +1 -1
- package/dist/workspace/intent.d.ts +149 -5
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/kinds.d.ts +24 -6
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/lineage-adopt-cli.d.ts +15 -0
- package/dist/workspace/lineage-adopt-cli.d.ts.map +1 -0
- package/dist/workspace/lineage-adopt.d.ts +106 -0
- package/dist/workspace/lineage-adopt.d.ts.map +1 -0
- package/dist/workspace/lineage-check.d.ts +9 -2
- package/dist/workspace/lineage-check.d.ts.map +1 -1
- package/dist/workspace/lineage-cli.d.ts +6 -1
- package/dist/workspace/lineage-cli.d.ts.map +1 -1
- package/dist/workspace/lineage-hash-index.d.ts +110 -0
- package/dist/workspace/lineage-hash-index.d.ts.map +1 -0
- package/dist/workspace/lineage-init.d.ts +10 -0
- package/dist/workspace/lineage-init.d.ts.map +1 -1
- package/dist/workspace/lineage-lock.d.ts +149 -2
- package/dist/workspace/lineage-lock.d.ts.map +1 -1
- package/dist/workspace/lineage-migrations.d.ts +15 -3
- package/dist/workspace/lineage-migrations.d.ts.map +1 -1
- package/dist/workspace/lineage-provenance.d.ts +18 -0
- package/dist/workspace/lineage-provenance.d.ts.map +1 -0
- package/dist/workspace/lineage-upgrade-cli.d.ts +2 -0
- package/dist/workspace/lineage-upgrade-cli.d.ts.map +1 -1
- package/dist/workspace/lineage-upgrade.d.ts +30 -1
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
- package/dist/workspace/lineage-versions.d.ts +116 -0
- package/dist/workspace/lineage-versions.d.ts.map +1 -0
- package/dist/workspace/links.d.ts +31 -5
- package/dist/workspace/links.d.ts.map +1 -1
- package/dist/workspace/ls-generated.d.ts +37 -0
- package/dist/workspace/ls-generated.d.ts.map +1 -0
- package/dist/workspace/ls.d.ts +4 -0
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/member-commands.d.ts.map +1 -1
- package/dist/workspace/nested-graph.d.ts +56 -0
- package/dist/workspace/nested-graph.d.ts.map +1 -0
- package/dist/workspace/nesting.d.ts +21 -0
- package/dist/workspace/nesting.d.ts.map +1 -0
- package/dist/workspace/pin-cli.d.ts +10 -0
- package/dist/workspace/pin-cli.d.ts.map +1 -0
- package/dist/workspace/pin-integrity.d.ts +51 -0
- package/dist/workspace/pin-integrity.d.ts.map +1 -0
- package/dist/workspace/points.d.ts.map +1 -1
- package/dist/workspace/principal-classes.d.ts +114 -0
- package/dist/workspace/principal-classes.d.ts.map +1 -0
- package/dist/workspace/reason-codes.d.ts +47 -3
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/record-assets.d.ts.map +1 -1
- package/dist/workspace/record-sessions.d.ts +7 -11
- package/dist/workspace/record-sessions.d.ts.map +1 -1
- package/dist/workspace/records-checkout.d.ts +54 -0
- package/dist/workspace/records-checkout.d.ts.map +1 -0
- package/dist/workspace/records-cli.d.ts +57 -2
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-close.d.ts +5 -2
- package/dist/workspace/records-close.d.ts.map +1 -1
- package/dist/workspace/records-since.d.ts.map +1 -1
- package/dist/workspace/records-write.d.ts +23 -4
- package/dist/workspace/records-write.d.ts.map +1 -1
- package/dist/workspace/records.d.ts +58 -5
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/returns.d.ts +129 -0
- package/dist/workspace/returns.d.ts.map +1 -0
- package/dist/workspace/runs-cli.d.ts +164 -0
- package/dist/workspace/runs-cli.d.ts.map +1 -0
- package/dist/workspace/runs.d.ts +423 -0
- package/dist/workspace/runs.d.ts.map +1 -0
- package/dist/workspace/source-block.d.ts +1 -1
- package/dist/workspace/source-block.d.ts.map +1 -1
- package/dist/workspace/status-gates.d.ts +15 -3
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +10 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/symbols.d.ts +52 -0
- package/dist/workspace/symbols.d.ts.map +1 -0
- package/dist/workspace/template-manifest.d.ts +11 -3
- package/dist/workspace/template-manifest.d.ts.map +1 -1
- package/dist/workspace/trailer-joins.d.ts +46 -0
- package/dist/workspace/trailer-joins.d.ts.map +1 -0
- package/dist/workspace/trailers.d.ts +89 -0
- package/dist/workspace/trailers.d.ts.map +1 -0
- package/dist/workspace/trust/attestor.d.ts +8 -0
- package/dist/workspace/trust/attestor.d.ts.map +1 -1
- package/dist/workspace/trust/dsse.d.ts +58 -0
- package/dist/workspace/trust/dsse.d.ts.map +1 -0
- package/dist/workspace/trust/evidence-cli.d.ts +66 -0
- package/dist/workspace/trust/evidence-cli.d.ts.map +1 -0
- package/dist/workspace/trust/evidence.d.ts +93 -0
- package/dist/workspace/trust/evidence.d.ts.map +1 -0
- package/dist/workspace/trust/policy.d.ts +54 -1
- package/dist/workspace/trust/policy.d.ts.map +1 -1
- package/dist/workspace/trust/provenance.d.ts +21 -1
- package/dist/workspace/trust/provenance.d.ts.map +1 -1
- package/dist/workspace/trust/rotation.d.ts +132 -0
- package/dist/workspace/trust/rotation.d.ts.map +1 -0
- package/dist/workspace/trust/seal.d.ts +33 -0
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/signers-cli.d.ts +49 -0
- package/dist/workspace/trust/signers-cli.d.ts.map +1 -0
- package/dist/workspace/trust/ssh-commit.d.ts +12 -0
- package/dist/workspace/trust/ssh-commit.d.ts.map +1 -1
- package/dist/workspace/trust/test-repo.d.ts +13 -0
- package/dist/workspace/trust/test-repo.d.ts.map +1 -1
- package/dist/workspace/trust/verify.d.ts +15 -0
- package/dist/workspace/trust/verify.d.ts.map +1 -1
- package/dist/workspace/work-cli.d.ts +39 -3
- package/dist/workspace/work-cli.d.ts.map +1 -1
- package/dist/workspace/work-evidence.d.ts +1 -1
- package/dist/workspace/work-evidence.d.ts.map +1 -1
- package/dist/workspace/work.d.ts +26 -1
- package/dist/workspace/work.d.ts.map +1 -1
- package/dist/workspace/workspace-principals.schema.json +60 -0
- package/dist/workspace/write-scope.d.ts +259 -0
- package/dist/workspace/write-scope.d.ts.map +1 -0
- package/dist/yaml.d.ts +21 -39
- package/dist/yaml.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/audit/prior-art.ts +15 -0
- package/src/build.ts +8 -0
- package/src/cli/build-options.ts +4 -1
- package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +1 -1
- package/src/cli/commands/build.ts +2 -0
- package/src/cli/commands/carve-emit-state.test.ts +4 -0
- package/src/cli/commands/carve-emit.ts +5 -19
- package/src/cli/commands/check-lexicon.test.ts +62 -1
- package/src/cli/commands/check-lexicon.ts +36 -6
- package/src/cli/commands/import-live.test.ts +87 -1
- package/src/cli/commands/import-parser-options.test.ts +133 -0
- package/src/cli/commands/import.ts +69 -25
- package/src/cli/commands/init-lexicon/templates/project.ts +1 -1
- package/src/cli/commands/init.test.ts +8 -1
- package/src/cli/commands/init.ts +23 -8
- package/src/cli/commands/lint.test.ts +37 -0
- package/src/cli/commands/onboard.test.ts +53 -3
- package/src/cli/commands/onboard.ts +52 -4
- package/src/cli/commands/pinned-upgrade.ts +73 -33
- package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +2 -2
- package/src/cli/handlers/components.ts +2 -2
- package/src/cli/handlers/dev.ts +8 -6
- package/src/cli/handlers/fan-out.test.ts +6 -6
- package/src/cli/handlers/fan-out.ts +2 -1
- package/src/cli/handlers/graph.test.ts +42 -0
- package/src/cli/handlers/graph.ts +22 -0
- package/src/cli/handlers/lifecycle.test.ts +67 -0
- package/src/cli/handlers/lifecycle.ts +6 -5
- package/src/cli/handlers/misc.ts +2 -0
- package/src/cli/handlers/operator.ts +88 -4
- package/src/cli/handlers/run.test.ts +111 -0
- package/src/cli/handlers/run.ts +85 -24
- package/src/cli/handlers/scenario.ts +2 -2
- package/src/cli/main.test.ts +33 -0
- package/src/cli/main.ts +168 -17
- package/src/cli/mcp/workspace-tools.test.ts +5 -2
- package/src/cli/mcp/workspace-tools.ts +62 -4
- package/src/cli/registry.ts +33 -2
- package/src/cli/serve-mcp-workspace.test.ts +1 -1
- package/src/codegen/pinned-upgrade-multi.test.ts +157 -0
- package/src/codegen/pinned-upgrade-tags.test.ts +112 -0
- package/src/codegen/pinned-upgrade.test.ts +104 -0
- package/src/codegen/pinned-upgrade.ts +250 -56
- package/src/codegen/release-wiring.test.ts +5 -1
- package/src/codegen/testdata/postgres-tags.json +242 -0
- package/src/components/fan-out-output.test.ts +1 -1
- package/src/components/fan-out.test.ts +1 -1
- package/src/components/promote.test.ts +1 -1
- package/src/config.test.ts +21 -0
- package/src/config.ts +27 -0
- package/src/content-digest.test.ts +2 -2
- package/src/declarable.test.ts +21 -0
- package/src/declarable.ts +19 -0
- package/src/discovery/fold-composite.test.ts +41 -5
- package/src/discovery/fold-import.test.ts +129 -0
- package/src/discovery/fold-import.ts +643 -131
- package/src/discovery/fold-package-composite.test.ts +264 -0
- package/src/discovery/fold-specifiers.test.ts +191 -0
- package/src/discovery/param-deps.test.ts +66 -1
- package/src/discovery/param-deps.ts +45 -0
- package/src/discovery/specifier-resolve.ts +344 -0
- package/src/fold/fold.test.ts +39 -1
- package/src/fold/fold.ts +83 -9
- package/src/fold-provenance.test.ts +140 -0
- package/src/graph-ir.test.ts +83 -0
- package/src/graph-ir.ts +29 -0
- package/src/import/embedded.test.ts +20 -0
- package/src/import/embedded.ts +13 -0
- package/src/import/parser-options.ts +46 -0
- package/src/import/parser.ts +20 -0
- package/src/lexicon.ts +79 -3
- package/src/lifecycle/gate-ledger.test.ts +14 -0
- package/src/lifecycle/gate-ledger.ts +18 -1
- package/src/lifecycle/observe.test.ts +18 -0
- package/src/lifecycle/observe.ts +6 -4
- package/src/lifecycle/plan-digest.test.ts +54 -3
- package/src/lifecycle/plan-digest.ts +38 -8
- package/src/lifecycle/snapshot.ts +2 -2
- package/src/lifecycle/work-lease.test.ts +1 -1
- package/src/lifecycle/work-lease.ts +93 -2
- package/src/lint/engine.test.ts +55 -0
- package/src/lint/engine.ts +30 -4
- package/src/lint/output-docs.test.ts +59 -56
- package/src/op/activities/activity-contracts.ts +1 -0
- package/src/op/activities/apply.test.ts +189 -5
- package/src/op/activities/apply.ts +230 -8
- package/src/op/activities/index.ts +3 -0
- package/src/op/activities/lexicon-upgrade.test.ts +160 -6
- package/src/op/activities/lexicon-upgrade.ts +154 -51
- package/src/op/activities/propose-upgrade.ts +8 -5
- package/src/op/composites/apply-op.ts +12 -5
- package/src/op/composites/composites.test.ts +30 -3
- package/src/op/composites/lexicon-upgrade-op.test.ts +7 -2
- package/src/op/composites/lexicon-upgrade-op.ts +29 -8
- package/src/op/emulator-lifecycle.test.ts +23 -0
- package/src/op/emulator-lifecycle.ts +52 -14
- package/src/op/gate-approval.test.ts +91 -0
- package/src/op/gate-approval.ts +5 -1
- package/src/op/gate.ts +34 -8
- package/src/op/index.ts +3 -1
- package/src/op/local-executor.test.ts +15 -0
- package/src/op/local-executor.ts +40 -12
- package/src/op/local-output.ts +1 -1
- package/src/op/operator.ts +4 -0
- package/src/op/run-context.test.ts +141 -0
- package/src/op/run-context.ts +51 -0
- package/src/op/runtimes/local.test.ts +14 -0
- package/src/op/runtimes/local.ts +2 -0
- package/src/op/steward-beside.ts +2 -0
- package/src/op/types.ts +8 -3
- package/src/op/work-lease-run.test.ts +47 -0
- package/src/op/work-lease-run.ts +73 -11
- package/src/provenance.ts +35 -0
- package/src/serializer.ts +9 -0
- package/src/telemetry-attribution.test.ts +91 -0
- package/src/telemetry-attribution.ts +145 -0
- package/src/workspace/__fixtures__/studio-template-84c8b21.json +1 -1
- package/src/workspace/agent-cli.ts +138 -0
- package/src/workspace/agent.schema.json +378 -0
- package/src/workspace/behold-kinds.test.ts +1 -1
- package/src/workspace/box-factory.test.ts +320 -0
- package/src/workspace/box-factory.ts +103 -0
- package/src/workspace/changes-cli.ts +5 -0
- package/src/workspace/changes.schema.json +171 -1
- package/src/workspace/changes.ts +61 -4
- package/src/workspace/check-live.test.ts +192 -0
- package/src/workspace/check.schema.json +64 -0
- package/src/workspace/checks/boxes.test.ts +2 -0
- package/src/workspace/checks/links.ts +23 -2
- package/src/workspace/checks/live.ts +113 -0
- package/src/workspace/checks.test.ts +2 -2
- package/src/workspace/checks.ts +49 -8
- package/src/workspace/compose-graph.test.ts +47 -0
- package/src/workspace/compose-graph.ts +127 -3
- package/src/workspace/conformance/__fixture__/decisions/decision.kind.mjs +7 -1
- package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +5 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +27 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +95 -0
- package/src/workspace/conformance/__writer_fixture__/decisions/points.json +132 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +48 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +108 -0
- package/src/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
- package/src/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
- package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +578 -0
- package/src/workspace/conformance/conformance.e2e.test.ts +35 -3
- package/src/workspace/conformance/index.mjs +30 -3
- package/src/workspace/conformance/index.ts +103 -15
- package/src/workspace/conformance/vitest.ts +44 -2
- package/src/workspace/conformance/writer-conformance.e2e.test.ts +131 -0
- package/src/workspace/conformance/writer.test.ts +156 -0
- package/src/workspace/conformance/writer.ts +880 -0
- package/src/workspace/decide.ts +7 -1
- package/src/workspace/declaration.schema.json +368 -4
- package/src/workspace/declaration.ts +270 -1
- package/src/workspace/declared-kinds.test.ts +33 -0
- package/src/workspace/evidence.schema.json +279 -0
- package/src/workspace/export-cli.ts +180 -0
- package/src/workspace/export-import.test.ts +282 -0
- package/src/workspace/export.ts +486 -0
- package/src/workspace/graph-cli.ts +51 -2
- package/src/workspace/graph-contract.test.ts +89 -4
- package/src/workspace/graph.schema.json +453 -1
- package/src/workspace/identity.test.ts +196 -0
- package/src/workspace/identity.ts +186 -0
- package/src/workspace/import.ts +325 -0
- package/src/workspace/intent-cli.ts +64 -10
- package/src/workspace/intent-record.schema.json +208 -0
- package/src/workspace/intent-record.ts +35 -1
- package/src/workspace/intent-why.test.ts +274 -0
- package/src/workspace/intent.schema.json +718 -7
- package/src/workspace/intent.test.ts +11 -2
- package/src/workspace/intent.ts +495 -32
- package/src/workspace/kinds.test.ts +5 -5
- package/src/workspace/kinds.ts +62 -33
- package/src/workspace/lineage-adopt-cli.ts +103 -0
- package/src/workspace/lineage-adopt.test.ts +552 -0
- package/src/workspace/lineage-adopt.ts +452 -0
- package/src/workspace/lineage-check.ts +26 -5
- package/src/workspace/lineage-cli.ts +12 -2
- package/src/workspace/lineage-hash-index.ts +305 -0
- package/src/workspace/lineage-init.test.ts +9 -0
- package/src/workspace/lineage-init.ts +29 -9
- package/src/workspace/lineage-lock.ts +54 -0
- package/src/workspace/lineage-migrations.test.ts +27 -0
- package/src/workspace/lineage-migrations.ts +44 -14
- package/src/workspace/lineage-provenance.ts +40 -0
- package/src/workspace/lineage-upgrade-cli.ts +9 -5
- package/src/workspace/lineage-upgrade.test.ts +92 -1
- package/src/workspace/lineage-upgrade.ts +111 -16
- package/src/workspace/lineage-versions.ts +348 -0
- package/src/workspace/links.test.ts +121 -2
- package/src/workspace/links.ts +97 -6
- package/src/workspace/ls-contract.test.ts +84 -1
- package/src/workspace/ls-generated.ts +111 -0
- package/src/workspace/ls.schema.json +19 -0
- package/src/workspace/ls.ts +8 -1
- package/src/workspace/member-commands.ts +3 -1
- package/src/workspace/nested-graph.test.ts +176 -0
- package/src/workspace/nested-graph.ts +169 -0
- package/src/workspace/nesting.ts +37 -0
- package/src/workspace/pin-cli.test.ts +71 -0
- package/src/workspace/pin-cli.ts +57 -0
- package/src/workspace/pin-integrity.test.ts +121 -0
- package/src/workspace/pin-integrity.ts +104 -0
- package/src/workspace/points-write.schema.json +2 -0
- package/src/workspace/principal-classes.test.ts +175 -0
- package/src/workspace/principal-classes.ts +307 -0
- package/src/workspace/read-contract.test.ts +24 -0
- package/src/workspace/reason-codes.test.ts +20 -2
- package/src/workspace/reason-codes.ts +53 -3
- package/src/workspace/record-sessions.ts +12 -14
- package/src/workspace/records-amend.schema.json +6 -0
- package/src/workspace/records-checkout.ts +106 -0
- package/src/workspace/records-cli.ts +195 -22
- package/src/workspace/records-close.schema.json +7 -2
- package/src/workspace/records-close.ts +10 -2
- package/src/workspace/records-formats.test.ts +13 -5
- package/src/workspace/records-new.schema.json +6 -0
- package/src/workspace/records-review.schema.json +6 -0
- package/src/workspace/records-sessions.test.ts +23 -6
- package/src/workspace/records-uncommitted.test.ts +171 -0
- package/src/workspace/records-write.test.ts +65 -8
- package/src/workspace/records-write.ts +92 -6
- package/src/workspace/records.schema.json +127 -4
- package/src/workspace/records.ts +123 -5
- package/src/workspace/returns.ts +328 -0
- package/src/workspace/runs-cli.ts +381 -0
- package/src/workspace/runs-write.schema.json +583 -0
- package/src/workspace/runs.schema.json +810 -0
- package/src/workspace/runs.test.ts +242 -0
- package/src/workspace/runs.ts +709 -0
- package/src/workspace/signers.schema.json +206 -0
- package/src/workspace/status-contract.test.ts +5 -0
- package/src/workspace/status-gates.ts +24 -9
- package/src/workspace/status.schema.json +127 -2
- package/src/workspace/status.ts +21 -1
- package/src/workspace/symbols.ts +180 -0
- package/src/workspace/template-manifest.ts +22 -4
- package/src/workspace/trailer-joins.test.ts +171 -0
- package/src/workspace/trailer-joins.ts +82 -0
- package/src/workspace/trailers.ts +148 -0
- package/src/workspace/trust/attestor.ts +15 -0
- package/src/workspace/trust/dsse.ts +134 -0
- package/src/workspace/trust/evidence-cli.ts +195 -0
- package/src/workspace/trust/evidence.test.ts +241 -0
- package/src/workspace/trust/evidence.ts +207 -0
- package/src/workspace/trust/policy.ts +110 -3
- package/src/workspace/trust/provenance.ts +41 -4
- package/src/workspace/trust/record-seal.test.ts +1 -1
- package/src/workspace/trust/rotation.test.ts +258 -0
- package/src/workspace/trust/rotation.ts +336 -0
- package/src/workspace/trust/seal.ts +63 -1
- package/src/workspace/trust/signers-cli.ts +178 -0
- package/src/workspace/trust/ssh-commit.ts +53 -4
- package/src/workspace/trust/test-repo.ts +18 -0
- package/src/workspace/trust/trust.test.ts +8 -2
- package/src/workspace/trust/verify-cli.ts +1 -0
- package/src/workspace/trust/verify.ts +22 -0
- package/src/workspace/work-cli.e2e.test.ts +28 -1
- package/src/workspace/work-cli.ts +133 -8
- package/src/workspace/work-evidence.schema.json +6 -0
- package/src/workspace/work-history.schema.json +73 -1
- package/src/workspace/work-history.test.ts +48 -5
- package/src/workspace/work-kind-fields.test.ts +154 -0
- package/src/workspace/work-lease.schema.json +14 -1
- package/src/workspace/work.ts +82 -0
- package/src/workspace/workspace-principals.schema.json +60 -0
- package/src/workspace/write-scope.test.ts +466 -0
- package/src/workspace/write-scope.ts +573 -0
- package/src/yaml.test.ts +111 -1
- package/src/yaml.ts +141 -549
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
patchDockerfile,
|
|
8
8
|
patchRootTsconfigPaths,
|
|
9
9
|
insertPrepackAfterEach,
|
|
10
|
+
patchLexiconList,
|
|
10
11
|
} from "./onboard";
|
|
11
12
|
|
|
12
13
|
function makeTempDir(): string {
|
|
@@ -184,6 +185,8 @@ function writeFixtureRepo(root: string): void {
|
|
|
184
185
|
writeFileSync(join(root, ".github/workflows/publish.yml"), publishContent);
|
|
185
186
|
writeFileSync(join(root, "test/Dockerfile.smoke"), dockerLoopContent);
|
|
186
187
|
writeFileSync(join(root, "test/Dockerfile.smoke-npm"), dockerNpmContent);
|
|
188
|
+
writeFileSync(join(root, "test/smoke-npm-lexicons.txt"), "aws\ngitlab\nk8s\n");
|
|
189
|
+
writeFileSync(join(root, "test/smoke-e2e-lexicons.txt"), "aws\nk8s\n");
|
|
187
190
|
}
|
|
188
191
|
|
|
189
192
|
const TRACKED = [
|
|
@@ -193,6 +196,8 @@ const TRACKED = [
|
|
|
193
196
|
".github/workflows/publish.yml",
|
|
194
197
|
"test/Dockerfile.smoke",
|
|
195
198
|
"test/Dockerfile.smoke-npm",
|
|
199
|
+
"test/smoke-npm-lexicons.txt",
|
|
200
|
+
"test/smoke-e2e-lexicons.txt",
|
|
196
201
|
];
|
|
197
202
|
|
|
198
203
|
function snapshot(root: string): Record<string, string> {
|
|
@@ -223,8 +228,12 @@ describe("onboardCommand", () => {
|
|
|
223
228
|
"publish.yml (prepack)",
|
|
224
229
|
"Dockerfile.smoke (lexicon list)",
|
|
225
230
|
"Dockerfile.smoke-npm (lexicon list)",
|
|
231
|
+
"smoke-npm-lexicons.txt (lexicon list)",
|
|
226
232
|
]);
|
|
227
|
-
expect(result.skipped).
|
|
233
|
+
expect(result.skipped).toHaveLength(1);
|
|
234
|
+
expect(result.skipped[0]).toContain("smoke-e2e-lexicons.txt: not patched");
|
|
235
|
+
expect(readFileSync(join(root, "test/smoke-npm-lexicons.txt"), "utf-8")).toBe("aws\ngitlab\nk8s\nterraform\n");
|
|
236
|
+
expect(readFileSync(join(root, "test/smoke-e2e-lexicons.txt"), "utf-8")).toBe("aws\nk8s\n");
|
|
228
237
|
|
|
229
238
|
const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf-8"));
|
|
230
239
|
expect(pkg.dependencies["@intentius/chant-lexicon-terraform"]).toBe("workspace:*");
|
|
@@ -254,6 +263,8 @@ describe("onboardCommand", () => {
|
|
|
254
263
|
"publish.yml: prepack for terraform already present",
|
|
255
264
|
"Dockerfile.smoke: already covers terraform",
|
|
256
265
|
"Dockerfile.smoke-npm: already covers terraform",
|
|
266
|
+
"smoke-npm-lexicons.txt: terraform already in test/smoke-npm-lexicons.txt",
|
|
267
|
+
expect.stringContaining("smoke-e2e-lexicons.txt: not patched"),
|
|
257
268
|
]);
|
|
258
269
|
});
|
|
259
270
|
|
|
@@ -312,9 +323,9 @@ describe("root tsconfig.json paths (#1614)", () => {
|
|
|
312
323
|
|
|
313
324
|
const cfg = JSON.parse(readFileSync(join(root, "tsconfig.json"), "utf-8"));
|
|
314
325
|
expect(cfg.compilerOptions.paths["@intentius/chant-lexicon-terraform"]).toEqual([
|
|
315
|
-
"lexicons/terraform/src/index.ts",
|
|
326
|
+
"./lexicons/terraform/src/index.ts",
|
|
316
327
|
]);
|
|
317
|
-
expect(cfg.compilerOptions.paths["@intentius/chant-lexicon-terraform/*"]).toEqual(["lexicons/terraform/src/*"]);
|
|
328
|
+
expect(cfg.compilerOptions.paths["@intentius/chant-lexicon-terraform/*"]).toEqual(["./lexicons/terraform/src/*"]);
|
|
318
329
|
// Existing entries untouched
|
|
319
330
|
expect(cfg.compilerOptions.paths["@intentius/chant-lexicon-aws"]).toEqual(["lexicons/aws/src/index.ts"]);
|
|
320
331
|
expect(cfg.compilerOptions.moduleResolution).toBe("node");
|
|
@@ -462,3 +473,42 @@ describe("insertPrepackAfterEach", () => {
|
|
|
462
473
|
]);
|
|
463
474
|
});
|
|
464
475
|
});
|
|
476
|
+
|
|
477
|
+
describe("smoke lists and publish.yml reporting (#3227)", () => {
|
|
478
|
+
let root: string;
|
|
479
|
+
|
|
480
|
+
beforeEach(() => {
|
|
481
|
+
root = makeTempDir();
|
|
482
|
+
writeFixtureRepo(root);
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
afterEach(() => {
|
|
486
|
+
rmSync(root, { recursive: true, force: true });
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
test("patchLexiconList appends once and keeps the trailing newline", () => {
|
|
490
|
+
const file = join(root, "test/smoke-npm-lexicons.txt");
|
|
491
|
+
writeFileSync(file, "aws\nk8s");
|
|
492
|
+
expect(patchLexiconList(file, "sql").patched).toBe(true);
|
|
493
|
+
expect(readFileSync(file, "utf-8")).toBe("aws\nk8s\nsql\n");
|
|
494
|
+
expect(patchLexiconList(file, "sql").patched).toBe(false);
|
|
495
|
+
expect(readFileSync(file, "utf-8")).toBe("aws\nk8s\nsql\n");
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
test("a Dockerfile that reads the list file points at it instead of claiming coverage", () => {
|
|
499
|
+
const file = join(root, "test/Dockerfile.smoke-npm");
|
|
500
|
+
writeFileSync(file, "RUN LEXICONS=$(cat /app/test/smoke-npm-lexicons.txt) && \\\n for lex in $LEXICONS; do :; done\n");
|
|
501
|
+
const result = patchDockerfile(file, "sql");
|
|
502
|
+
expect(result.patched).toBe(false);
|
|
503
|
+
expect(result.reason).toContain("test/smoke-npm-lexicons.txt");
|
|
504
|
+
expect(result.reason).not.toContain("already covers");
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
test("publish.yml with no per-lexicon prepack lines says nothing needs patching", () => {
|
|
508
|
+
writeFileSync(join(root, ".github/workflows/publish.yml"), "name: publish\njobs:\n test:\n steps:\n - run: bash scripts/publish-verify-ci.sh\n");
|
|
509
|
+
const result = onboardCommand({ name: "sql", root });
|
|
510
|
+
const line = result.skipped.find((s) => s.startsWith("publish.yml:"));
|
|
511
|
+
expect(line).toContain("nothing to patch");
|
|
512
|
+
expect(line).toContain("scripts/ci-lexicon-artifacts.sh");
|
|
513
|
+
});
|
|
514
|
+
});
|
|
@@ -117,6 +117,10 @@ function patchRootPackageJson(root: string, name: string): PatchResult {
|
|
|
117
117
|
* The whole-repo typecheck runs with `moduleResolution: node`, which never
|
|
118
118
|
* reads package exports maps, so every lexicon needs a bare + subpath
|
|
119
119
|
* mapping here or an example importing the package fails to resolve.
|
|
120
|
+
*
|
|
121
|
+
* Entries are `./`-prefixed like every other entry (#3227): with no `baseUrl`
|
|
122
|
+
* (removed in #3205) a bare `lexicons/...` path is invalid and tsx's tsconfig
|
|
123
|
+
* loader throws on it for every run in the repo.
|
|
120
124
|
*/
|
|
121
125
|
export function patchRootTsconfigPaths(root: string, name: string): PatchResult {
|
|
122
126
|
const tsconfigPath = join(root, "tsconfig.json");
|
|
@@ -128,8 +132,8 @@ export function patchRootTsconfigPaths(root: string, name: string): PatchResult
|
|
|
128
132
|
|
|
129
133
|
const bare = `@intentius/chant-lexicon-${name}`;
|
|
130
134
|
const wanted: Record<string, string[]> = {
|
|
131
|
-
[bare]: [
|
|
132
|
-
[`${bare}/*`]: [
|
|
135
|
+
[bare]: [`./lexicons/${name}/src/index.ts`],
|
|
136
|
+
[`${bare}/*`]: [`./lexicons/${name}/src/*`],
|
|
133
137
|
};
|
|
134
138
|
|
|
135
139
|
let changed = false;
|
|
@@ -297,7 +301,15 @@ function patchPublishWorkflow(root: string, name: string): PatchResult {
|
|
|
297
301
|
}
|
|
298
302
|
|
|
299
303
|
if (!insertPrepackAfterEach(lines, name)) {
|
|
300
|
-
|
|
304
|
+
// #3227 — not a failure and not "covered by a prepack line": publish.yml
|
|
305
|
+
// carries no per-lexicon lines. The run builds every lexicon through
|
|
306
|
+
// scripts/ci-lexicon-artifacts.sh and publishes through
|
|
307
|
+
// scripts/publish-packages.sh, both of which enumerate the workspace.
|
|
308
|
+
return {
|
|
309
|
+
patched: false,
|
|
310
|
+
reason:
|
|
311
|
+
"nothing to patch: it has no per-lexicon prepack lines; scripts/ci-lexicon-artifacts.sh and scripts/publish-packages.sh enumerate the workspace",
|
|
312
|
+
};
|
|
301
313
|
}
|
|
302
314
|
writeFileSync(filePath, lines.join("\n"));
|
|
303
315
|
return { patched: true };
|
|
@@ -321,6 +333,12 @@ export function patchDockerfile(filePath: string, name: string): PatchResult {
|
|
|
321
333
|
|
|
322
334
|
const changed = addToLexiconLoops(lines, name) || insertPrepackAfterEach(lines, name);
|
|
323
335
|
if (!changed) {
|
|
336
|
+
// #3227 — the smoke-npm and smoke-e2e images read their lexicon list from
|
|
337
|
+
// a file. Point at it instead of reporting a missing anchor.
|
|
338
|
+
const listFile = lines.join("\n").match(/test\/(smoke-[\w-]+-lexicons\.txt)/)?.[1];
|
|
339
|
+
if (listFile) {
|
|
340
|
+
return { patched: false, reason: `reads its lexicon list from test/${listFile}, not from the Dockerfile` };
|
|
341
|
+
}
|
|
324
342
|
return { patched: false, reason: "no lexicon loop or prepack line found to anchor on" };
|
|
325
343
|
}
|
|
326
344
|
|
|
@@ -328,6 +346,22 @@ export function patchDockerfile(filePath: string, name: string): PatchResult {
|
|
|
328
346
|
return { patched: true };
|
|
329
347
|
}
|
|
330
348
|
|
|
349
|
+
/**
|
|
350
|
+
* Append a lexicon to a one-name-per-line list file (test/smoke-npm-lexicons.txt).
|
|
351
|
+
* Idempotent; keeps the file's trailing newline.
|
|
352
|
+
*/
|
|
353
|
+
export function patchLexiconList(filePath: string, name: string): PatchResult {
|
|
354
|
+
const rel = filePath.split("/").slice(-2).join("/");
|
|
355
|
+
if (!existsSync(filePath)) return { patched: false, reason: `${rel} not found` };
|
|
356
|
+
const content = readFileSync(filePath, "utf-8");
|
|
357
|
+
if (content.split("\n").some((l) => l.trim() === name)) {
|
|
358
|
+
return { patched: false, reason: `${name} already in ${rel}` };
|
|
359
|
+
}
|
|
360
|
+
const sep = content === "" || content.endsWith("\n") ? "" : "\n";
|
|
361
|
+
writeFileSync(filePath, `${content}${sep}${name}\n`);
|
|
362
|
+
return { patched: true };
|
|
363
|
+
}
|
|
364
|
+
|
|
331
365
|
/**
|
|
332
366
|
* Execute the onboard command — patches monorepo infrastructure for a new lexicon.
|
|
333
367
|
*/
|
|
@@ -375,6 +409,20 @@ export function onboardCommand(options: OnboardOptions): OnboardResult {
|
|
|
375
409
|
patchDockerfile(join(root, "test/Dockerfile.smoke-npm"), options.name),
|
|
376
410
|
);
|
|
377
411
|
|
|
412
|
+
// 6. Smoke image lexicon lists (#3227). The npm smoke packs every lexicon.
|
|
413
|
+
// The e2e list is opt-in: it names the lexicons an example uses plus
|
|
414
|
+
// their dependencies, so onboard leaves it alone and says so.
|
|
415
|
+
record(
|
|
416
|
+
"smoke-npm-lexicons.txt",
|
|
417
|
+
"lexicon list",
|
|
418
|
+
patchLexiconList(join(root, "test/smoke-npm-lexicons.txt"), options.name),
|
|
419
|
+
);
|
|
420
|
+
if (existsSync(join(root, "test/smoke-e2e-lexicons.txt"))) {
|
|
421
|
+
skipped.push(
|
|
422
|
+
`smoke-e2e-lexicons.txt: not patched; it lists only lexicons an e2e example uses (and their dependencies). Add ${options.name} to test/smoke-e2e-lexicons.txt when an example needs it`,
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
378
426
|
return { success: true, patched, skipped, verbose: options.verbose };
|
|
379
427
|
}
|
|
380
428
|
|
|
@@ -396,7 +444,7 @@ export async function printOnboardResult(result: OnboardResult, name: string): P
|
|
|
396
444
|
|
|
397
445
|
if (result.skipped.length > 0) {
|
|
398
446
|
console.log("");
|
|
399
|
-
console.log("
|
|
447
|
+
console.log("Not patched (already covered, or nothing to patch):");
|
|
400
448
|
for (const s of result.skipped) {
|
|
401
449
|
console.log(` ${s}`);
|
|
402
450
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `chant dev pinned-upgrade <lexicon-dir>` command implementation.
|
|
3
3
|
*
|
|
4
|
-
* Detects whether a
|
|
4
|
+
* Detects whether a lexicon that declares `upstreamPin` has a
|
|
5
5
|
* newer stable upstream release. When it does, it dry-run bumps the pinned
|
|
6
6
|
* version constant, regenerates + surface-diffs (via #524's regenLexicon), then
|
|
7
7
|
* reverts the bump — leaving the working tree unchanged.
|
|
@@ -10,20 +10,21 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { existsSync } from "fs";
|
|
13
|
-
import {
|
|
13
|
+
import { resolve } from "path";
|
|
14
14
|
import {
|
|
15
|
-
|
|
15
|
+
checkPinnedUpgrades,
|
|
16
|
+
lexiconNameOf,
|
|
16
17
|
type LexiconId,
|
|
17
18
|
type UpgradeCheckResult,
|
|
18
19
|
} from "../../codegen/pinned-upgrade";
|
|
19
20
|
|
|
20
|
-
const PINNED_LEXICONS: readonly LexiconId[] = ["k8s", "gcp", "docker", "gitlab"];
|
|
21
|
-
|
|
22
21
|
export interface PinnedUpgradeOptions {
|
|
23
22
|
/** Resolved path to the lexicon directory. */
|
|
24
23
|
lexiconDir: string;
|
|
25
24
|
/** Explicit lexicon id; inferred from the directory name when omitted. */
|
|
26
25
|
lexicon?: LexiconId;
|
|
26
|
+
/** Label of one pin to check, for a lexicon that declares several. Omitted: all of them. */
|
|
27
|
+
pin?: string;
|
|
27
28
|
/** Force re-fetch of the upstream spec during regen. */
|
|
28
29
|
force?: boolean;
|
|
29
30
|
/** Print subprocess output while running. */
|
|
@@ -31,12 +32,13 @@ export interface PinnedUpgradeOptions {
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
|
-
* Infer the lexicon id from a directory
|
|
35
|
-
*
|
|
35
|
+
* Infer the lexicon id from a directory: its package name
|
|
36
|
+
* (`@intentius/chant-lexicon-<name>`), else the directory name. Whether the
|
|
37
|
+
* lexicon is pinned is the plugin's `upstreamPin`, checked by
|
|
38
|
+
* `checkPinnedUpgrade`, not a list here.
|
|
36
39
|
*/
|
|
37
|
-
export function inferLexicon(lexiconDir: string): LexiconId
|
|
38
|
-
|
|
39
|
-
return (PINNED_LEXICONS as readonly string[]).includes(name) ? (name as LexiconId) : null;
|
|
40
|
+
export function inferLexicon(lexiconDir: string): LexiconId {
|
|
41
|
+
return lexiconNameOf(lexiconDir);
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
/**
|
|
@@ -52,37 +54,38 @@ export function semverLabel(result: UpgradeCheckResult): "minor" | "major" | "no
|
|
|
52
54
|
|
|
53
55
|
/**
|
|
54
56
|
* Run the pinned-upgrade check and return the structured result.
|
|
55
|
-
* Never throws — a missing dir or
|
|
57
|
+
* Never throws — a missing dir or a lexicon with no `upstreamPin` becomes a fetchError.
|
|
56
58
|
*/
|
|
57
59
|
export async function runPinnedUpgrade(opts: PinnedUpgradeOptions): Promise<UpgradeCheckResult> {
|
|
60
|
+
return (await runPinnedUpgrades(opts))[0]!;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Run the check for every pin the plugin declares (or the one in `opts.pin`),
|
|
65
|
+
* one result each. A lexicon with one pin gives one result.
|
|
66
|
+
*/
|
|
67
|
+
export async function runPinnedUpgrades(opts: PinnedUpgradeOptions): Promise<UpgradeCheckResult[]> {
|
|
58
68
|
const dir = resolve(opts.lexiconDir);
|
|
59
69
|
|
|
60
70
|
const lexicon = opts.lexicon ?? inferLexicon(dir);
|
|
61
|
-
if (!lexicon) {
|
|
62
|
-
return {
|
|
63
|
-
lexicon: "k8s",
|
|
64
|
-
hasUpgrade: false,
|
|
65
|
-
from: "(unknown)",
|
|
66
|
-
to: null,
|
|
67
|
-
validation: null,
|
|
68
|
-
fetchError: `Not a pinned lexicon directory: ${dir}. Expected one of: ${PINNED_LEXICONS.join(", ")}.`,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
71
|
|
|
72
72
|
if (!existsSync(dir)) {
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
return [
|
|
74
|
+
{
|
|
75
|
+
lexicon,
|
|
76
|
+
hasUpgrade: false,
|
|
77
|
+
from: "(unknown)",
|
|
78
|
+
to: null,
|
|
79
|
+
validation: null,
|
|
80
|
+
fetchError: `Lexicon directory not found: ${dir}`,
|
|
81
|
+
},
|
|
82
|
+
];
|
|
81
83
|
}
|
|
82
84
|
|
|
83
|
-
return
|
|
85
|
+
return checkPinnedUpgrades({
|
|
84
86
|
lexiconDir: dir,
|
|
85
87
|
lexicon,
|
|
88
|
+
pin: opts.pin,
|
|
86
89
|
force: opts.force,
|
|
87
90
|
verbose: opts.verbose,
|
|
88
91
|
});
|
|
@@ -112,12 +115,14 @@ function c(text: string, code: string): string {
|
|
|
112
115
|
*/
|
|
113
116
|
export function printPinnedUpgradeResult(result: UpgradeCheckResult, json: boolean): void {
|
|
114
117
|
const label = semverLabel(result);
|
|
118
|
+
const name = result.pin ? `${result.lexicon}/${result.pin}` : result.lexicon;
|
|
115
119
|
|
|
116
120
|
if (json) {
|
|
117
121
|
console.log(
|
|
118
122
|
JSON.stringify(
|
|
119
123
|
{
|
|
120
124
|
lexicon: result.lexicon,
|
|
125
|
+
...(result.pin ? { pin: result.pin } : {}),
|
|
121
126
|
hasUpgrade: result.hasUpgrade,
|
|
122
127
|
from: result.from,
|
|
123
128
|
to: result.to,
|
|
@@ -128,6 +133,7 @@ export function printPinnedUpgradeResult(result: UpgradeCheckResult, json: boole
|
|
|
128
133
|
validationOk: result.validation?.ok ?? null,
|
|
129
134
|
failures: result.validation?.failures ?? [],
|
|
130
135
|
fetchError: result.fetchError,
|
|
136
|
+
manualPin: result.manualPin ?? null,
|
|
131
137
|
},
|
|
132
138
|
null,
|
|
133
139
|
2,
|
|
@@ -137,22 +143,31 @@ export function printPinnedUpgradeResult(result: UpgradeCheckResult, json: boole
|
|
|
137
143
|
}
|
|
138
144
|
|
|
139
145
|
if (result.fetchError) {
|
|
140
|
-
console.log(c(`[${
|
|
146
|
+
console.log(c(`[${name}] error: ${result.fetchError}`, COLORS.red));
|
|
141
147
|
return;
|
|
142
148
|
}
|
|
143
149
|
|
|
144
150
|
if (!result.hasUpgrade) {
|
|
145
151
|
console.log(
|
|
146
|
-
c(`[${
|
|
152
|
+
c(`[${name}] up to date`, COLORS.green) +
|
|
147
153
|
` pinned=${result.from}` +
|
|
148
154
|
(result.to ? ` latest=${result.to}` : ""),
|
|
149
155
|
);
|
|
150
156
|
return;
|
|
151
157
|
}
|
|
152
158
|
|
|
159
|
+
if (result.manualPin) {
|
|
160
|
+
console.log(
|
|
161
|
+
c(`[${name}] upgrade available`, COLORS.bold) + ` ${result.from} -> ${result.to}`,
|
|
162
|
+
);
|
|
163
|
+
console.log(` The pin in ${result.manualPin.file} cannot be rewritten generically, so nothing was edited or regenerated.`);
|
|
164
|
+
console.log(` ${result.manualPin.instructions}`);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
153
168
|
// Upgrade available
|
|
154
169
|
console.log(
|
|
155
|
-
c(`[${
|
|
170
|
+
c(`[${name}] upgrade available`, COLORS.bold) +
|
|
156
171
|
` ${result.from} -> ${result.to}`,
|
|
157
172
|
);
|
|
158
173
|
|
|
@@ -202,3 +217,28 @@ export function printPinnedUpgradeResult(result: UpgradeCheckResult, json: boole
|
|
|
202
217
|
`Validation: ${validationLabel} Semver: ${c(label, labelColor)} ${result.from} -> ${result.to}`,
|
|
203
218
|
);
|
|
204
219
|
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Print one result per pin. One result prints exactly as `printPinnedUpgradeResult`;
|
|
223
|
+
* several print in turn, and `json` emits an array of the same objects.
|
|
224
|
+
*/
|
|
225
|
+
export function printPinnedUpgradeResults(results: UpgradeCheckResult[], json: boolean): void {
|
|
226
|
+
if (results.length === 1) {
|
|
227
|
+
printPinnedUpgradeResult(results[0]!, json);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (json) {
|
|
231
|
+
// Each result prints as its own JSON object; collect them into one array.
|
|
232
|
+
const lines: string[] = [];
|
|
233
|
+
const log = console.log;
|
|
234
|
+
console.log = (...a: unknown[]) => void lines.push(a.join(" "));
|
|
235
|
+
try {
|
|
236
|
+
for (const r of results) printPinnedUpgradeResult(r, true);
|
|
237
|
+
} finally {
|
|
238
|
+
console.log = log;
|
|
239
|
+
}
|
|
240
|
+
console.log(`[${lines.join(",\n")}]`);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
for (const r of results) printPinnedUpgradeResult(r, false);
|
|
244
|
+
}
|
|
@@ -14,7 +14,7 @@ jobs:
|
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
15
|
container: node:22-slim
|
|
16
16
|
steps:
|
|
17
|
-
- uses: actions/checkout@
|
|
17
|
+
- uses: actions/checkout@v7
|
|
18
18
|
- run: chant run --components shared-alb --env staging --dump-outputs shared-alb.outputs.json
|
|
19
19
|
- name: Upload shared-alb outputs
|
|
20
20
|
uses: actions/upload-artifact@v4
|
|
@@ -27,7 +27,7 @@ jobs:
|
|
|
27
27
|
- shared-alb
|
|
28
28
|
container: node:22-slim
|
|
29
29
|
steps:
|
|
30
|
-
- uses: actions/checkout@
|
|
30
|
+
- uses: actions/checkout@v7
|
|
31
31
|
- name: Download shared-alb outputs
|
|
32
32
|
uses: actions/download-artifact@v4
|
|
33
33
|
with:
|
|
@@ -48,7 +48,7 @@ import type { ComponentBomSummary } from "../../lifecycle/build-ledger";
|
|
|
48
48
|
import type { BuildArchiveManifest } from "../../components/verbs/build-archive";
|
|
49
49
|
import { loadChantConfig } from "../../config";
|
|
50
50
|
import { applyLiveEndpoint } from "../../live-endpoint";
|
|
51
|
-
import {
|
|
51
|
+
import { isObservableDeclarable } from "../../declarable";
|
|
52
52
|
import { build } from "../../build";
|
|
53
53
|
import { discoverComponents } from "../../components/discover";
|
|
54
54
|
import { formatError, formatWarning, formatSuccess, formatBold } from "../format";
|
|
@@ -643,7 +643,7 @@ export async function runComponentsStatus(ctx: CommandContext): Promise<number>
|
|
|
643
643
|
const entities = new Map<string, { entityType: string; props: Record<string, unknown> }>();
|
|
644
644
|
for (const [name, entity] of buildResult.entities) {
|
|
645
645
|
// Resource declarables only (see lifecycle/observe.ts).
|
|
646
|
-
if (entity.lexicon === plugin.name &&
|
|
646
|
+
if (entity.lexicon === plugin.name && isObservableDeclarable(entity)) {
|
|
647
647
|
declared.add(name);
|
|
648
648
|
entities.set(name, {
|
|
649
649
|
entityType: entity.entityType,
|
package/src/cli/handlers/dev.ts
CHANGED
|
@@ -85,16 +85,18 @@ export async function runDevSurfaceDiff(ctx: CommandContext): Promise<number> {
|
|
|
85
85
|
|
|
86
86
|
export async function runDevPinnedUpgrade(ctx: CommandContext): Promise<number> {
|
|
87
87
|
const dir = ctx.args.extraPositional ?? ".";
|
|
88
|
-
const {
|
|
89
|
-
|
|
88
|
+
const { runPinnedUpgrades, printPinnedUpgradeResults } = await import("../commands/pinned-upgrade");
|
|
89
|
+
// The optional second positional is a pin label, for a lexicon that declares several pins.
|
|
90
|
+
const results = await runPinnedUpgrades({
|
|
90
91
|
lexiconDir: resolve(dir),
|
|
92
|
+
pin: ctx.args.extraPositional2,
|
|
91
93
|
force: ctx.args.force,
|
|
92
94
|
verbose: ctx.args.verbose,
|
|
93
95
|
});
|
|
94
|
-
|
|
95
|
-
// Exit non-zero when
|
|
96
|
-
if (
|
|
97
|
-
if (
|
|
96
|
+
printPinnedUpgradeResults(results, ctx.args.format === "json");
|
|
97
|
+
// Exit non-zero when an upstream query failed or a regen validation broke.
|
|
98
|
+
if (results.some((r) => r.fetchError)) return 1;
|
|
99
|
+
if (results.some((r) => r.validation && !r.validation.ok)) return 1;
|
|
98
100
|
return 0;
|
|
99
101
|
}
|
|
100
102
|
|
|
@@ -204,8 +204,8 @@ describe("proof: a plan-only invocation prints the derivation and dispatches not
|
|
|
204
204
|
expect(out).toContain("wave 1: cluster-a");
|
|
205
205
|
expect(out).toContain("seeded from an earlier run: net");
|
|
206
206
|
expect(out).toMatch(/billing +unaffected/);
|
|
207
|
-
expect(out).toMatch(/plan: sha256:[0-9a-f]{64}/);
|
|
208
|
-
expect(out).toMatch(/approve: chant approve fan-out release --plan sha256:[0-9a-f]{64}/);
|
|
207
|
+
expect(out).toMatch(/plan: jcs1-sha256:[0-9a-f]{64}/);
|
|
208
|
+
expect(out).toMatch(/approve: chant approve fan-out release --plan jcs1-sha256:[0-9a-f]{64}/);
|
|
209
209
|
});
|
|
210
210
|
|
|
211
211
|
test("--dry-run with --resume shows what is left, at the digest that approves it", async () => {
|
|
@@ -214,7 +214,7 @@ describe("proof: a plan-only invocation prints the derivation and dispatches not
|
|
|
214
214
|
const resume = join(dir, "attempt.json");
|
|
215
215
|
failing = ["cluster-a"];
|
|
216
216
|
await runComponentsFanOut(ctx({ base: "main", env: "test", resume }));
|
|
217
|
-
const digest = /plan: (sha256:[0-9a-f]{64})/.exec(stderr())?.[1];
|
|
217
|
+
const digest = /plan: (jcs1-sha256:[0-9a-f]{64})/.exec(stderr())?.[1];
|
|
218
218
|
|
|
219
219
|
ran = [];
|
|
220
220
|
stderrLines = [];
|
|
@@ -236,7 +236,7 @@ describe("proof: a plan-only invocation prints the derivation and dispatches not
|
|
|
236
236
|
expect(exit).toBe(0);
|
|
237
237
|
const parsed = JSON.parse(stdout());
|
|
238
238
|
expect(parsed.order).toEqual(["net", "cluster-a", "cluster-b", "app-one", "app-three", "app-two"]);
|
|
239
|
-
expect(parsed.digest).toMatch(/^sha256:[0-9a-f]{64}$/);
|
|
239
|
+
expect(parsed.digest).toMatch(/^jcs1-sha256:[0-9a-f]{64}$/);
|
|
240
240
|
});
|
|
241
241
|
});
|
|
242
242
|
|
|
@@ -334,10 +334,10 @@ describe("proof: one approval covers the set, and the printed digest is what app
|
|
|
334
334
|
expect(ran).toEqual([]);
|
|
335
335
|
const out = stderr();
|
|
336
336
|
expect(out).toContain("gated: nothing ran.");
|
|
337
|
-
expect(out).toMatch(/approve : chant approve fan-out release --plan sha256:[0-9a-f]{64}/);
|
|
337
|
+
expect(out).toMatch(/approve : chant approve fan-out release --plan jcs1-sha256:[0-9a-f]{64}/);
|
|
338
338
|
// One pending fact for the whole set, not one per component.
|
|
339
339
|
expect(gateLedger.appended).toHaveLength(1);
|
|
340
|
-
expect(gateLedger.appended[0].planDigest).toBe(/plan: (sha256:[0-9a-f]{64})/.exec(out)?.[1]);
|
|
340
|
+
expect(gateLedger.appended[0].planDigest).toBe(/plan: (jcs1-sha256:[0-9a-f]{64})/.exec(out)?.[1]);
|
|
341
341
|
});
|
|
342
342
|
|
|
343
343
|
test("the resolution for that digest lets the whole set through", async () => {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
import { resolve, dirname } from "node:path";
|
|
39
39
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
40
40
|
import { loadChantConfig, resolveAutoReleaseDisabled, type ChantConfig } from "../../config";
|
|
41
|
+
import { samePlanDigest } from "../../lifecycle/plan-digest";
|
|
41
42
|
import { affectedStacks } from "../../lifecycle/affected";
|
|
42
43
|
import { deriveFanOut, fanOutRegistry } from "../../components/fan-out-support";
|
|
43
44
|
import { runFanOut } from "../../components/fan-out-run";
|
|
@@ -242,7 +243,7 @@ export async function runComponentsFanOut(ctx: CommandContext): Promise<number>
|
|
|
242
243
|
console.error(formatError({ message: `--resume: could not read "${args.resume}": ${err instanceof Error ? err.message : String(err)}` }));
|
|
243
244
|
return 1;
|
|
244
245
|
}
|
|
245
|
-
if (attempt && attempt.digest
|
|
246
|
+
if (attempt && !samePlanDigest(attempt.digest, derived.plan.digest)) {
|
|
246
247
|
console.error(formatWarning({
|
|
247
248
|
message: `--resume: "${args.resume}" records a different fan-out (${attempt.digest || "no digest"}), so its progress does not apply here`,
|
|
248
249
|
hint: "The derivation changed, which makes this a different change. Everything selected will run.",
|
|
@@ -161,6 +161,7 @@ describe("runGraph", () => {
|
|
|
161
161
|
observeMock.mockReset();
|
|
162
162
|
buildMock.mockReset();
|
|
163
163
|
loadPluginsMock.mockReset();
|
|
164
|
+
loadPluginsMock.mockResolvedValue([]);
|
|
164
165
|
resolveLexMock.mockReset();
|
|
165
166
|
loadChantConfigMock.mockReset();
|
|
166
167
|
loadChantConfigMock.mockResolvedValue({ config: {} });
|
|
@@ -228,6 +229,47 @@ describe("runGraph", () => {
|
|
|
228
229
|
expect(ir.edges).toContainEqual({ from: "subnet", to: "vpc", kind: "ref", viaAttr: "network" });
|
|
229
230
|
});
|
|
230
231
|
|
|
232
|
+
// #2559 — a lexicon's graphMeta answer lands in the IR meta, so the
|
|
233
|
+
// workspace graph can list collector pipelines without core importing otel.
|
|
234
|
+
test("--format ir carries what a lexicon's graphMeta reports under meta", async () => {
|
|
235
|
+
lintClean(); discovered();
|
|
236
|
+
const seen: string[][] = [];
|
|
237
|
+
loadPluginsMock.mockResolvedValue([{
|
|
238
|
+
name: "gcp",
|
|
239
|
+
serializer: {},
|
|
240
|
+
graphMeta: (entities: Map<string, unknown>) => {
|
|
241
|
+
seen.push([...entities.keys()].sort());
|
|
242
|
+
return { collector: { pipelines: [] } };
|
|
243
|
+
},
|
|
244
|
+
}]);
|
|
245
|
+
resolveLexMock.mockResolvedValue(["gcp"]);
|
|
246
|
+
const exit = await runGraph({ args: makeArgs({ format: "ir" }), plugins: [], serializers: [] });
|
|
247
|
+
expect(exit).toBe(0);
|
|
248
|
+
expect(seen).toEqual([["pod", "subnet", "vpc"]]);
|
|
249
|
+
expect(JSON.parse(stdoutBuf.join("\n")).meta).toEqual({ collector: { pipelines: [] } });
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
test("--format ir has no meta when no lexicon reports anything", async () => {
|
|
253
|
+
lintClean(); discovered();
|
|
254
|
+
loadPluginsMock.mockResolvedValue([{ name: "gcp", serializer: {}, graphMeta: () => undefined }, { name: "k8s", serializer: {} }]);
|
|
255
|
+
resolveLexMock.mockResolvedValue(["gcp", "k8s"]);
|
|
256
|
+
const exit = await runGraph({ args: makeArgs({ format: "ir" }), plugins: [], serializers: [] });
|
|
257
|
+
expect(exit).toBe(0);
|
|
258
|
+
expect("meta" in JSON.parse(stdoutBuf.join("\n"))).toBe(false);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test("--format ir keeps the first answer when two lexicons report one key", async () => {
|
|
262
|
+
lintClean(); discovered();
|
|
263
|
+
loadPluginsMock.mockResolvedValue([
|
|
264
|
+
{ name: "a", serializer: {}, graphMeta: () => ({ collector: 1 }) },
|
|
265
|
+
{ name: "b", serializer: {}, graphMeta: () => ({ collector: 2 }) },
|
|
266
|
+
]);
|
|
267
|
+
resolveLexMock.mockResolvedValue(["a", "b"]);
|
|
268
|
+
const exit = await runGraph({ args: makeArgs({ format: "ir" }), plugins: [], serializers: [] });
|
|
269
|
+
expect(exit).toBe(0);
|
|
270
|
+
expect(JSON.parse(stdoutBuf.join("\n")).meta).toEqual({ collector: 1 });
|
|
271
|
+
});
|
|
272
|
+
|
|
231
273
|
// #2529 — the IR carries its version, as the first key, so a reader can
|
|
232
274
|
// decide how to read the rest before it reads anything else.
|
|
233
275
|
test("--format ir leads with the IR version", async () => {
|
|
@@ -702,6 +702,27 @@ async function buildPipelineProjection(
|
|
|
702
702
|
* Lint-gated: the IR represents valid infra, so we refuse to emit for source that
|
|
703
703
|
* does not pass lint. Non-zero on discovery errors or a layout-engine failure.
|
|
704
704
|
*/
|
|
705
|
+
/**
|
|
706
|
+
* Add what the lexicons' `graphMeta` hooks report to `ir.meta` (#2559). A
|
|
707
|
+
* lexicon with nothing to report leaves the IR as it was, so a project that
|
|
708
|
+
* declares none of their entities prints what it did before. Two lexicons
|
|
709
|
+
* that answer the same key keep the first and say so on stderr.
|
|
710
|
+
*/
|
|
711
|
+
function withGraphMeta(ir: GraphIR, plugins: LexiconPlugin[], entities: Map<string, import("../../declarable").Declarable>): GraphIR {
|
|
712
|
+
const added: Record<string, unknown> = {};
|
|
713
|
+
for (const p of plugins) {
|
|
714
|
+
if (!p.graphMeta) continue;
|
|
715
|
+
for (const [key, value] of Object.entries(p.graphMeta(entities) ?? {})) {
|
|
716
|
+
if (key in added || (ir.meta && key in ir.meta)) {
|
|
717
|
+
console.error(formatWarning({ message: `the ${p.name} lexicon reports graph meta "${key}", which another source already set; its value is dropped` }));
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
added[key] = value;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
return Object.keys(added).length === 0 ? ir : { ...ir, meta: { ...(ir.meta ?? {}), ...added } };
|
|
724
|
+
}
|
|
725
|
+
|
|
705
726
|
/** Returned instead of a graph when the prediction cannot be attempted honestly. */
|
|
706
727
|
const REFUSED = Symbol("behaviour-refused");
|
|
707
728
|
|
|
@@ -855,6 +876,7 @@ async function runGraphView(
|
|
|
855
876
|
});
|
|
856
877
|
if (predicted === REFUSED) return 1;
|
|
857
878
|
ir = predicted;
|
|
879
|
+
ir = withGraphMeta(ir, plugins as LexiconPlugin[], result.entities);
|
|
858
880
|
}
|
|
859
881
|
|
|
860
882
|
if (ctx.args.lens) {
|