@intentius/chant 0.101.0 → 0.104.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/core.d.ts +2 -0
- package/dist/audit/core.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/builder.d.ts.map +1 -1
- package/dist/change-set.d.ts +232 -0
- package/dist/change-set.d.ts.map +1 -0
- package/dist/cli/commands/audit.d.ts +7 -0
- package/dist/cli/commands/audit.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/build.d.ts.map +1 -1
- package/dist/cli/handlers/change-set.d.ts +11 -0
- package/dist/cli/handlers/change-set.d.ts.map +1 -0
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.d.ts +33 -0
- 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 +16 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/pr.d.ts +31 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -0
- 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/op-tools.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 +4 -3
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +74 -3
- 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/auto-release.d.ts +16 -0
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability.d.ts +53 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/changed-files.d.ts +31 -0
- package/dist/components/changed-files.d.ts.map +1 -0
- package/dist/components/cli-support.d.ts +9 -1
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/component.d.ts +24 -0
- package/dist/components/component.d.ts.map +1 -1
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/driver.d.ts +13 -0
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/fan-out-output.d.ts +6 -0
- package/dist/components/fan-out-output.d.ts.map +1 -1
- package/dist/components/fan-out-record.d.ts +41 -0
- package/dist/components/fan-out-record.d.ts.map +1 -0
- package/dist/components/fan-out-run.d.ts +65 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-support.d.ts +2 -0
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/fan-out.d.ts +6 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/gated-wave-pipeline.d.ts +50 -0
- package/dist/components/gated-wave-pipeline.d.ts.map +1 -0
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/layers.d.ts +25 -0
- package/dist/components/layers.d.ts.map +1 -0
- package/dist/components/pr-pipeline.d.ts +61 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -0
- package/dist/components/pr-run.d.ts +119 -0
- package/dist/components/pr-run.d.ts.map +1 -0
- package/dist/components/promote.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/shell.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/components/wave-plan.d.ts +49 -0
- package/dist/components/wave-plan.d.ts.map +1 -0
- package/dist/composite.d.ts.map +1 -1
- package/dist/config.d.ts +19 -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/gated-waves.d.ts +147 -0
- package/dist/gated-waves.d.ts.map +1 -0
- 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/index.d.ts +1 -0
- package/dist/index.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 +103 -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 +22 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +46 -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-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 +8 -8
- package/dist/lint/engine.d.ts +6 -0
- package/dist/lint/engine.d.ts.map +1 -1
- package/dist/lint/post-synth.d.ts +18 -0
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/lsp/lexicon-providers.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.d.ts +137 -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/change-set.d.ts +62 -0
- package/dist/op/activities/change-set.d.ts.map +1 -0
- package/dist/op/activities/decide.d.ts +2 -0
- package/dist/op/activities/decide.d.ts.map +1 -1
- package/dist/op/activities/factory.d.ts +137 -0
- package/dist/op/activities/factory.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +5 -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/activity-contract.d.ts +1 -1
- package/dist/op/activity-contract.d.ts.map +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 +11 -0
- 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 +5 -1
- package/dist/op/decide-backend.d.ts.map +1 -1
- package/dist/op/decide-read-inputs.d.ts +4 -2
- 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/factory.d.ts +83 -0
- package/dist/op/factory.d.ts.map +1 -0
- 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 +6 -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/op-ir.d.ts +2 -0
- package/dist/op/op-ir.d.ts.map +1 -1
- package/dist/op/op-verb-class.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 +16 -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/plan-summary.d.ts +207 -0
- package/dist/plan-summary.d.ts.map +1 -0
- package/dist/pr-forge.d.ts +105 -0
- package/dist/pr-forge.d.ts.map +1 -0
- package/dist/pr-loop.d.ts +178 -0
- package/dist/pr-loop.d.ts.map +1 -0
- 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/telemetry-attribution.d.ts +31 -0
- package/dist/telemetry-attribution.d.ts.map +1 -1
- package/dist/terraform/emit-source.d.ts.map +1 -1
- package/dist/terraform/hcl2json.d.ts +45 -0
- package/dist/terraform/hcl2json.d.ts.map +1 -0
- package/dist/terraform/parse.d.ts +4 -40
- 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 +5 -0
- package/dist/workspace/agent-cli.d.ts.map +1 -1
- package/dist/workspace/box-cli.d.ts +12 -0
- package/dist/workspace/box-cli.d.ts.map +1 -0
- package/dist/workspace/box-factory.d.ts +97 -0
- package/dist/workspace/box-factory.d.ts.map +1 -0
- package/dist/workspace/box-listing.d.ts +85 -0
- package/dist/workspace/box-listing.d.ts.map +1 -0
- package/dist/workspace/box-publish.d.ts +147 -0
- package/dist/workspace/box-publish.d.ts.map +1 -0
- package/dist/workspace/broker-protocol.d.ts +190 -0
- package/dist/workspace/broker-protocol.d.ts.map +1 -0
- 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.d.ts +5 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/compose-graph.d.ts +10 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/composites.d.ts +2 -2
- package/dist/workspace/composites.d.ts.map +1 -1
- package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts +17 -0
- package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts.map +1 -0
- package/dist/workspace/conformance/broker.d.ts +202 -0
- package/dist/workspace/conformance/broker.d.ts.map +1 -0
- package/dist/workspace/conformance/index.d.ts +68 -6
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/vitest.d.ts +19 -3
- package/dist/workspace/conformance/vitest.d.ts.map +1 -1
- package/dist/workspace/conformance/writer.d.ts +462 -0
- package/dist/workspace/conformance/writer.d.ts.map +1 -0
- package/dist/workspace/decide.d.ts +126 -12
- package/dist/workspace/decide.d.ts.map +1 -1
- package/dist/workspace/decision-points.schema.json +11 -4
- package/dist/workspace/declaration.d.ts +156 -4
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.schema.json +383 -5
- package/dist/workspace/environments.d.ts +36 -10
- package/dist/workspace/environments.d.ts.map +1 -1
- package/dist/workspace/factory-rules.d.ts +180 -0
- package/dist/workspace/factory-rules.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/init.d.ts +21 -0
- package/dist/workspace/init.d.ts.map +1 -1
- 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 +36 -2
- package/dist/workspace/intent-record.d.ts.map +1 -1
- package/dist/workspace/intent.d.ts +249 -8
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/json-edit.d.ts +24 -0
- package/dist/workspace/json-edit.d.ts.map +1 -0
- package/dist/workspace/jsonc.d.ts +11 -0
- package/dist/workspace/jsonc.d.ts.map +1 -1
- package/dist/workspace/kinds.d.ts +66 -4
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/lexicon-symbols.d.ts +29 -0
- package/dist/workspace/lexicon-symbols.d.ts.map +1 -0
- package/dist/workspace/lineage-hash-index.d.ts.map +1 -1
- package/dist/workspace/lineage-lock.d.ts +2 -2
- package/dist/workspace/lineage-lock.d.ts.map +1 -1
- package/dist/workspace/lineage-upgrade.d.ts +31 -2
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
- package/dist/workspace/links.d.ts.map +1 -1
- package/dist/workspace/point-answer.schema.json +42 -2
- package/dist/workspace/points-cli.d.ts +10 -3
- package/dist/workspace/points-cli.d.ts.map +1 -1
- package/dist/workspace/points.d.ts +66 -5
- 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 +53 -4
- 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 +5 -7
- 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 +34 -1
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-close.d.ts +7 -3
- 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 +68 -7
- package/dist/workspace/records-write.d.ts.map +1 -1
- package/dist/workspace/records.d.ts +43 -9
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/runs-cli.d.ts +296 -0
- package/dist/workspace/runs-cli.d.ts.map +1 -0
- package/dist/workspace/runs.d.ts +544 -0
- package/dist/workspace/runs.d.ts.map +1 -0
- package/dist/workspace/session-kinds.d.ts +1 -1
- package/dist/workspace/session-kinds.d.ts.map +1 -1
- package/dist/workspace/source-block.d.ts +1 -1
- package/dist/workspace/source-block.d.ts.map +1 -1
- package/dist/workspace/squash.d.ts +80 -0
- package/dist/workspace/squash.d.ts.map +1 -0
- package/dist/workspace/status-gates.d.ts +17 -3
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +64 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/symbols.d.ts +63 -0
- package/dist/workspace/symbols.d.ts.map +1 -0
- 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.map +1 -1
- package/dist/workspace/trust/rotation.d.ts.map +1 -1
- package/dist/workspace/trust/run-commits.d.ts +46 -0
- package/dist/workspace/trust/run-commits.d.ts.map +1 -0
- package/dist/workspace/trust/run-statement.d.ts +128 -0
- package/dist/workspace/trust/run-statement.d.ts.map +1 -0
- package/dist/workspace/trust/seal.d.ts +38 -0
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/test-repo.d.ts.map +1 -1
- package/dist/workspace/trust/verify-cli.d.ts +1 -1
- package/dist/workspace/trust/verify.d.ts +16 -2
- package/dist/workspace/trust/verify.d.ts.map +1 -1
- package/dist/workspace/wip-cli.d.ts +21 -0
- package/dist/workspace/wip-cli.d.ts.map +1 -0
- package/dist/workspace/wip.d.ts +268 -0
- package/dist/workspace/wip.d.ts.map +1 -0
- 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-size.d.ts +55 -0
- package/dist/workspace/work-size.d.ts.map +1 -0
- package/dist/workspace/work.d.ts +26 -1
- package/dist/workspace/work.d.ts.map +1 -1
- package/dist/workspace/workspace-kinds.schema.json +122 -0
- package/dist/workspace/workspace-principals.schema.json +60 -0
- package/dist/workspace/write-lock-cli.d.ts +60 -0
- package/dist/workspace/write-lock-cli.d.ts.map +1 -0
- package/dist/workspace/write-lock.d.ts +152 -0
- package/dist/workspace/write-lock.d.ts.map +1 -0
- package/dist/workspace/write-scope.d.ts +83 -19
- package/dist/workspace/write-scope.d.ts.map +1 -1
- package/dist/yaml.d.ts +21 -39
- package/dist/yaml.d.ts.map +1 -1
- package/package.json +7 -2
- package/src/__fixtures__/change-set/lifecycle-plan.floci.json +59 -0
- package/src/__fixtures__/change-set/lifecycle-v1.ts.txt +4 -0
- package/src/__fixtures__/change-set/lifecycle-v2.ts.txt +4 -0
- package/src/__fixtures__/change-set/lifecycle.change-set.golden.json +95 -0
- package/src/__fixtures__/change-set/warden.change-set.golden.json +106 -0
- package/src/__fixtures__/change-set/warden.plan.json +44 -0
- package/src/__fixtures__/plan-summary/normalization-vectors.json +1593 -0
- package/src/__fixtures__/pr-loop/pr-apply-applied.note.golden.md +31 -0
- package/src/__fixtures__/pr-loop/pr-apply-refused.note.golden.md +31 -0
- package/src/__fixtures__/pr-loop/pr-plan.golden.json +127 -0
- package/src/__fixtures__/pr-loop/pr-plan.note.golden.md +37 -0
- package/src/audit/core.test.ts +15 -0
- package/src/audit/core.ts +8 -2
- package/src/audit/discover.test.ts +11 -0
- package/src/audit/discover.ts +7 -2
- package/src/audit/prior-art.ts +15 -0
- package/src/change-set-bundle.test.ts +57 -0
- package/src/change-set.test.ts +215 -0
- package/src/change-set.ts +445 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +1 -1
- package/src/cli/commands/audit-opt-in.test.ts +54 -0
- package/src/cli/commands/audit.ts +29 -2
- package/src/cli/commands/build.test.ts +19 -0
- package/src/cli/commands/build.ts +3 -2
- 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 +18 -0
- package/src/cli/commands/import-parser-options.test.ts +133 -0
- package/src/cli/commands/import.ts +21 -3
- 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/build.ts +13 -1
- package/src/cli/handlers/change-set.test.ts +56 -0
- package/src/cli/handlers/change-set.ts +44 -0
- package/src/cli/handlers/components.ts +2 -2
- package/src/cli/handlers/dev.ts +8 -6
- package/src/cli/handlers/fan-out.test.ts +221 -2
- package/src/cli/handlers/fan-out.ts +165 -75
- package/src/cli/handlers/graph.ts +3 -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.test.ts +21 -0
- package/src/cli/handlers/operator.ts +121 -6
- package/src/cli/handlers/pr.ts +373 -0
- package/src/cli/handlers/run.test.ts +111 -0
- package/src/cli/handlers/run.ts +86 -24
- package/src/cli/handlers/scenario.ts +2 -2
- package/src/cli/main.test.ts +21 -0
- package/src/cli/main.ts +246 -30
- package/src/cli/mcp/never-over-mcp.test.ts +101 -0
- package/src/cli/mcp/op-tools.ts +24 -2
- package/src/cli/mcp/workspace-tools.test.ts +5 -2
- package/src/cli/mcp/workspace-tools.ts +62 -7
- package/src/cli/registry.ts +74 -3
- 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/testdata/postgres-tags.json +242 -0
- package/src/components/auto-release.ts +1 -1
- package/src/components/capability.ts +55 -0
- package/src/components/changed-files.ts +66 -0
- package/src/components/cli-support.ts +28 -5
- package/src/components/component.schema.json +17 -0
- package/src/components/component.ts +25 -0
- package/src/components/deploy-units.ts +3 -0
- package/src/components/driver.test.ts +52 -0
- package/src/components/driver.ts +31 -13
- package/src/components/fan-out-output.ts +42 -1
- package/src/components/fan-out-record.ts +69 -0
- package/src/components/fan-out-run.test.ts +17 -0
- package/src/components/fan-out-run.ts +304 -1
- package/src/components/fan-out-support.ts +3 -0
- package/src/components/fan-out-waves.test.ts +375 -0
- package/src/components/fan-out.ts +18 -17
- package/src/components/gated-wave-pipeline.ts +82 -0
- package/src/components/index.ts +1 -0
- package/src/components/layers.ts +30 -0
- package/src/components/pr-pipeline.ts +91 -0
- package/src/components/pr-run.test.ts +205 -0
- package/src/components/pr-run.ts +280 -0
- package/src/components/promote.ts +5 -0
- package/src/components/verbs/shell.test.ts +11 -0
- package/src/components/verbs/shell.ts +7 -3
- package/src/components/wave-plan.ts +124 -0
- package/src/config.test.ts +21 -0
- package/src/config.ts +15 -0
- 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/sandbox/bundle.ts +1 -1
- 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/gated-waves-bundle.test.ts +62 -0
- package/src/gated-waves.test.ts +118 -0
- package/src/gated-waves.ts +240 -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/index.ts +1 -0
- package/src/lexicon.ts +106 -3
- package/src/lifecycle/gate-ledger.ts +23 -0
- package/src/lifecycle/git.ts +102 -16
- package/src/lifecycle/observe.test.ts +18 -0
- package/src/lifecycle/observe.ts +6 -4
- 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/lint/post-synth.test.ts +19 -0
- package/src/lint/post-synth.ts +19 -1
- package/src/meta/declared-imports.test.ts +1 -1
- package/src/op/activities/activity-contracts.ts +84 -0
- package/src/op/activities/apply.test.ts +189 -5
- package/src/op/activities/apply.ts +230 -8
- package/src/op/activities/change-set.ts +114 -0
- package/src/op/activities/decide.ts +3 -0
- package/src/op/activities/factory.ts +675 -0
- package/src/op/activities/index.ts +9 -0
- package/src/op/activities/lexicon-upgrade.test.ts +160 -6
- package/src/op/activities/lexicon-upgrade.ts +154 -51
- package/src/op/activity-contract.test.ts +21 -1
- package/src/op/activity-contract.ts +19 -9
- package/src/op/builders.ts +23 -0
- 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/decide-backend.ts +5 -1
- package/src/op/decide-read-inputs.ts +33 -5
- package/src/op/emulator-lifecycle.test.ts +23 -0
- package/src/op/emulator-lifecycle.ts +52 -14
- package/src/op/factory.e2e.test.ts +232 -0
- package/src/op/factory.ts +118 -0
- package/src/op/gate-approval.test.ts +74 -0
- package/src/op/gate-approval.ts +5 -1
- package/src/op/gate.ts +31 -5
- package/src/op/index.ts +11 -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/op-ir.test.ts +9 -0
- package/src/op/op-ir.ts +4 -0
- package/src/op/op-verb-class.ts +3 -0
- 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 +16 -3
- package/src/op/work-lease-run.test.ts +47 -0
- package/src/op/work-lease-run.ts +76 -11
- package/src/plan-summary.test.ts +263 -0
- package/src/plan-summary.ts +845 -0
- package/src/pr-forge.test.ts +237 -0
- package/src/pr-forge.ts +332 -0
- package/src/pr-loop-bundle.test.ts +46 -0
- package/src/pr-loop.test.ts +171 -0
- package/src/pr-loop.ts +324 -0
- package/src/provenance.ts +35 -0
- package/src/telemetry-attribution.test.ts +23 -1
- package/src/telemetry-attribution.ts +51 -0
- package/src/terraform/hcl2json.test.ts +21 -0
- package/src/terraform/hcl2json.ts +81 -0
- package/src/terraform/parse.ts +11 -74
- package/src/workspace/agent-cli.ts +7 -3
- package/src/workspace/agent.schema.json +22 -0
- package/src/workspace/app-kind.test.ts +196 -0
- package/src/workspace/box-cli.ts +113 -0
- package/src/workspace/box-factory.test.ts +323 -0
- package/src/workspace/box-factory.ts +136 -0
- package/src/workspace/box-listing-write.schema.json +204 -0
- package/src/workspace/box-listing.test.ts +234 -0
- package/src/workspace/box-listing.ts +324 -0
- package/src/workspace/box-publish.schema.json +498 -0
- package/src/workspace/box-publish.test.ts +204 -0
- package/src/workspace/box-publish.ts +420 -0
- package/src/workspace/box-ship.test.ts +96 -0
- package/src/workspace/broker-protocol.schema.json +186 -0
- package/src/workspace/broker-protocol.test.ts +122 -0
- package/src/workspace/broker-protocol.ts +317 -0
- package/src/workspace/builder-tiers.test.ts +146 -0
- package/src/workspace/change-set.schema.json +460 -0
- package/src/workspace/changes.schema.json +12 -20
- package/src/workspace/changes.ts +4 -1
- package/src/workspace/chant-migrations.e2e.test.ts +17 -5
- package/src/workspace/checks/boxes.test.ts +5 -0
- package/src/workspace/checks.ts +39 -8
- package/src/workspace/component-environments.test.ts +105 -0
- package/src/workspace/compose-graph.ts +7 -0
- package/src/workspace/composites.schema.json +23 -4
- package/src/workspace/composites.test.ts +8 -8
- package/src/workspace/composites.ts +13 -2
- package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +2 -2
- package/src/workspace/conformance/__fixtures__/reference-broker.ts +207 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
- package/src/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
- package/src/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
- package/src/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
- package/src/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
- package/src/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -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 +603 -0
- package/src/workspace/conformance/broker.test.ts +122 -0
- package/src/workspace/conformance/broker.ts +792 -0
- package/src/workspace/conformance/conformance.e2e.test.ts +36 -3
- package/src/workspace/conformance/index.mjs +51 -3
- package/src/workspace/conformance/index.ts +107 -15
- package/src/workspace/conformance/vitest.ts +76 -2
- package/src/workspace/conformance/writer-conformance.e2e.test.ts +177 -0
- package/src/workspace/conformance/writer.test.ts +186 -0
- package/src/workspace/conformance/writer.ts +1191 -0
- package/src/workspace/decide.test.ts +208 -4
- package/src/workspace/decide.ts +433 -73
- package/src/workspace/decision-points.schema.json +11 -4
- package/src/workspace/declaration.schema.json +383 -5
- package/src/workspace/declaration.ts +315 -10
- package/src/workspace/environments.ts +66 -14
- package/src/workspace/factory-rules.test.ts +62 -0
- package/src/workspace/factory-rules.ts +218 -0
- package/src/workspace/graph-cli.ts +6 -3
- package/src/workspace/graph.schema.json +314 -0
- package/src/workspace/identity.test.ts +219 -0
- package/src/workspace/identity.ts +186 -0
- package/src/workspace/init.ts +82 -2
- package/src/workspace/intent-cli.ts +84 -13
- package/src/workspace/intent-patch-id.test.ts +162 -0
- package/src/workspace/intent-record.schema.json +336 -1
- package/src/workspace/intent-record.ts +96 -16
- package/src/workspace/intent-reviews.test.ts +76 -0
- package/src/workspace/intent-squash.test.ts +213 -0
- package/src/workspace/intent-why.test.ts +274 -0
- package/src/workspace/intent.schema.json +950 -9
- package/src/workspace/intent.test.ts +11 -2
- package/src/workspace/intent.ts +722 -65
- package/src/workspace/json-edit.test.ts +121 -0
- package/src/workspace/json-edit.ts +142 -0
- package/src/workspace/jsonc.ts +20 -0
- package/src/workspace/kinds.ts +201 -39
- package/src/workspace/lexicon-symbols.test.ts +148 -0
- package/src/workspace/lexicon-symbols.ts +125 -0
- package/src/workspace/lineage-upgrade.test.ts +63 -0
- package/src/workspace/lineage-upgrade.ts +146 -5
- package/src/workspace/plan-summary.schema.json +155 -0
- package/src/workspace/point-answer.schema.json +42 -2
- package/src/workspace/points-cli.ts +42 -16
- package/src/workspace/points-write.schema.json +163 -4
- package/src/workspace/points.schema.json +157 -2
- package/src/workspace/points.test.ts +13 -1
- package/src/workspace/points.ts +118 -12
- package/src/workspace/pr-report.schema.json +95 -0
- package/src/workspace/principal-classes.test.ts +175 -0
- package/src/workspace/principal-classes.ts +307 -0
- package/src/workspace/profiles.test.ts +159 -0
- package/src/workspace/read-contract.test.ts +2 -2
- package/src/workspace/reason-codes.test.ts +23 -3
- package/src/workspace/reason-codes.ts +61 -4
- package/src/workspace/record-sessions.ts +9 -8
- package/src/workspace/records-amend.schema.json +80 -0
- package/src/workspace/records-checkout.ts +106 -0
- package/src/workspace/records-cli.ts +123 -17
- package/src/workspace/records-close.schema.json +79 -0
- package/src/workspace/records-close.ts +31 -7
- package/src/workspace/records-concurrent.e2e.test.ts +135 -0
- package/src/workspace/records-concurrent.test.ts +145 -0
- package/src/workspace/records-formats.test.ts +46 -10
- package/src/workspace/records-new.schema.json +9 -0
- package/src/workspace/records-review.schema.json +80 -0
- package/src/workspace/records-sessions-write.test.ts +69 -0
- package/src/workspace/records-sessions.test.ts +22 -0
- package/src/workspace/records-uncommitted.test.ts +171 -0
- package/src/workspace/records-write.ts +219 -30
- package/src/workspace/records.schema.json +88 -1
- package/src/workspace/records.ts +76 -8
- package/src/workspace/reference-kinds/app/package.json +10 -0
- package/src/workspace/reference-kinds/app/workspace-kinds.json +45 -0
- package/src/workspace/run-statement.schema.json +622 -0
- package/src/workspace/runs-cli.ts +710 -0
- package/src/workspace/runs-statement.test.ts +239 -0
- package/src/workspace/runs-write.schema.json +994 -0
- package/src/workspace/runs.schema.json +1257 -0
- package/src/workspace/runs.test.ts +281 -0
- package/src/workspace/runs.ts +970 -0
- package/src/workspace/session-kinds.ts +3 -3
- package/src/workspace/squash.ts +198 -0
- package/src/workspace/status-contract.test.ts +10 -2
- package/src/workspace/status-gates.ts +25 -9
- package/src/workspace/status.schema.json +252 -4
- package/src/workspace/status.ts +110 -1
- package/src/workspace/symbols.ts +191 -0
- 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/run-commits.ts +115 -0
- package/src/workspace/trust/run-statement.ts +226 -0
- package/src/workspace/trust/seal.ts +58 -1
- package/src/workspace/trust/verify-cli.ts +6 -5
- package/src/workspace/trust/verify.ts +39 -6
- package/src/workspace/wip-cli.ts +97 -0
- package/src/workspace/wip-write.schema.json +504 -0
- package/src/workspace/wip.schema.json +334 -0
- package/src/workspace/wip.test.ts +294 -0
- package/src/workspace/wip.ts +753 -0
- package/src/workspace/work-cli.e2e.test.ts +28 -1
- package/src/workspace/work-cli.ts +136 -8
- package/src/workspace/work-evidence.schema.json +5 -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-size.test.ts +77 -0
- package/src/workspace/work-size.ts +93 -0
- package/src/workspace/work.ts +82 -0
- package/src/workspace/workspace-kinds.schema.json +122 -0
- package/src/workspace/workspace-principals.schema.json +60 -0
- package/src/workspace/write-lock-cli.ts +131 -0
- package/src/workspace/write-lock.schema.json +172 -0
- package/src/workspace/write-lock.test.ts +189 -0
- package/src/workspace/write-lock.ts +474 -0
- package/src/workspace/write-scope.test.ts +144 -3
- package/src/workspace/write-scope.ts +192 -45
- package/src/yaml.test.ts +111 -1
- package/src/yaml.ts +141 -549
package/src/graph-ir.ts
CHANGED
|
@@ -384,6 +384,23 @@ function refTarget(ref: AttrRef, reverse: Map<object, string>): string | undefin
|
|
|
384
384
|
return ref.getLogicalName() ?? (parent ? reverse.get(parent) : undefined);
|
|
385
385
|
}
|
|
386
386
|
|
|
387
|
+
/**
|
|
388
|
+
* The node id a whole declarable held in a config bag stands for, or undefined
|
|
389
|
+
* when it is not a node of this graph (an inlined property-kind resource, say,
|
|
390
|
+
* which is config of the holder and gets walked instead). An entity can name
|
|
391
|
+
* another entity directly rather than through an AttrRef, as the sql lexicon's
|
|
392
|
+
* enumerable `dependsOn` does with the tables, views and databases a statement
|
|
393
|
+
* mentions (#3257); that is a reference to the node, not a nested bag.
|
|
394
|
+
*/
|
|
395
|
+
function nodeReference(
|
|
396
|
+
value: unknown,
|
|
397
|
+
reverse: Map<object, string>,
|
|
398
|
+
nodeIds: Set<string>,
|
|
399
|
+
): string | undefined {
|
|
400
|
+
const id = reverse.get(value as object);
|
|
401
|
+
return id !== undefined && nodeIds.has(id) ? id : undefined;
|
|
402
|
+
}
|
|
403
|
+
|
|
387
404
|
/** Project a value into a JSON-safe, scrubbed form. References become `{ $ref }`. */
|
|
388
405
|
function project(value: unknown, seen: Set<unknown>, reverse: Map<object, string>, nodeIds: Set<string>): unknown {
|
|
389
406
|
if (value === null) return null;
|
|
@@ -414,6 +431,9 @@ function project(value: unknown, seen: Set<unknown>, reverse: Map<object, string
|
|
|
414
431
|
// Nested declarables (e.g. an inlined property-kind resource) keep their
|
|
415
432
|
// config in a non-enumerable `props` bag, like top-level nodes — project that.
|
|
416
433
|
if (isDeclarable(value)) {
|
|
434
|
+
// Another node held whole is a reference to it, not config to inline.
|
|
435
|
+
const to = nodeReference(value, reverse, nodeIds);
|
|
436
|
+
if (to) return { $ref: to } satisfies AttrRefEnvelope;
|
|
417
437
|
const out = projectConfig(value, seen, reverse, nodeIds);
|
|
418
438
|
seen.delete(value);
|
|
419
439
|
return out;
|
|
@@ -518,6 +538,15 @@ function collectEdges(
|
|
|
518
538
|
if (to && to !== from && nodeIds.has(to)) edges.push({ from, to, kind: "ref", viaAttr });
|
|
519
539
|
return;
|
|
520
540
|
}
|
|
541
|
+
// A whole node held in props or an enumerable field (the sql lexicon's
|
|
542
|
+
// `dependsOn`) is a reference to it: draw the edge, and do not walk its
|
|
543
|
+
// config, whose refs belong to that node's own edges (#3257). Checked
|
|
544
|
+
// before `seen` so the same node under two attributes yields both edges.
|
|
545
|
+
const held = nodeReference(value, reverse, nodeIds);
|
|
546
|
+
if (held) {
|
|
547
|
+
if (held !== from) edges.push({ from, to: held, kind: "ref", viaAttr });
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
521
550
|
if (seen.has(value)) return;
|
|
522
551
|
seen.add(value);
|
|
523
552
|
// A nested declarable (an inlined property-kind resource, e.g. a listener's
|
|
@@ -85,6 +85,26 @@ describe("EmbeddedImports", () => {
|
|
|
85
85
|
]);
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
+
test("an importer that keeps matched content as written is not asked to import it, and its reason is the warning", () => {
|
|
89
|
+
let imported = 0;
|
|
90
|
+
const resolver = new EmbeddedImports([
|
|
91
|
+
{
|
|
92
|
+
lexicon: "acme",
|
|
93
|
+
importer: {
|
|
94
|
+
...widgets,
|
|
95
|
+
keepsAsWritten: (c) => ((c.document as { size?: number }).size === 3 ? "a size-3 widget builds back as size 4" : undefined),
|
|
96
|
+
import: (c) => (imported++, widgets.import(c)),
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
]);
|
|
100
|
+
expect(resolver.resolve(site())).toBeUndefined();
|
|
101
|
+
expect(imported).toBe(0);
|
|
102
|
+
expect(resolver.files).toEqual([]);
|
|
103
|
+
expect(resolver.warnings).toEqual(['ConfigMap agent data["config.yaml"] is a widget, kept as written: a size-3 widget builds back as size 4']);
|
|
104
|
+
expect(isEmbeddedReference(resolver.resolve(site({ text: "kind: widget\nsize: 2\n" })))).toBe(true);
|
|
105
|
+
expect(imported).toBe(1);
|
|
106
|
+
});
|
|
107
|
+
|
|
88
108
|
test("when two lexicons match, the first imports it and the other is named", () => {
|
|
89
109
|
const resolver = new EmbeddedImports([
|
|
90
110
|
{ lexicon: "acme", importer: widgets },
|
package/src/import/embedded.ts
CHANGED
|
@@ -102,6 +102,13 @@ export interface EmbeddedContentImporter {
|
|
|
102
102
|
readonly what: string;
|
|
103
103
|
/** Whether this content is one it imports. Must not throw on content that is not. */
|
|
104
104
|
matches(content: EmbeddedContent): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Why content it matches is kept as written instead of imported, or
|
|
107
|
+
* `undefined` to import it. Asked before `import`; the reason is the
|
|
108
|
+
* warning's. grafana keeps a v2 dashboard, which it reads but would build
|
|
109
|
+
* back as v1 JSON (#3031).
|
|
110
|
+
*/
|
|
111
|
+
keepsAsWritten?(content: EmbeddedContent): string | undefined;
|
|
105
112
|
/** Import it. A throw keeps the content as written, with a warning. */
|
|
106
113
|
import(content: EmbeddedContent): EmbeddedImport;
|
|
107
114
|
}
|
|
@@ -233,6 +240,12 @@ export class EmbeddedImports implements EmbeddedContentResolver {
|
|
|
233
240
|
);
|
|
234
241
|
}
|
|
235
242
|
|
|
243
|
+
const kept = chosen.importer.keepsAsWritten?.(content);
|
|
244
|
+
if (kept !== undefined) {
|
|
245
|
+
this.warnings.push(`${content.location} is ${chosen.importer.what}, kept as written: ${kept}`);
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
|
|
236
249
|
let result: EmbeddedImport;
|
|
237
250
|
try {
|
|
238
251
|
result = chosen.importer.import(content);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { LexiconPlugin } from "../lexicon";
|
|
2
|
+
import type { ParserOptions, ParserOptionSpec } from "./parser";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Check `--parser-option` entries (`key` or `key=value`) against what the
|
|
6
|
+
* lexicon declares in `parserOptions()` and convert each value to its declared
|
|
7
|
+
* type (#2994). Returns the options, or an error message naming what is wrong
|
|
8
|
+
* and what the lexicon accepts. An empty list is always valid.
|
|
9
|
+
*/
|
|
10
|
+
export function resolveParserOptions(
|
|
11
|
+
plugin: Pick<LexiconPlugin, "name" | "parserOptions">,
|
|
12
|
+
entries: readonly string[] | undefined,
|
|
13
|
+
): { options: ParserOptions } | { error: string } {
|
|
14
|
+
const options: ParserOptions = {};
|
|
15
|
+
if (!entries || entries.length === 0) return { options };
|
|
16
|
+
|
|
17
|
+
const specs: ParserOptionSpec[] = plugin.parserOptions?.() ?? [];
|
|
18
|
+
const accepted =
|
|
19
|
+
specs.length === 0
|
|
20
|
+
? `lexicon "${plugin.name}" declares no parser options`
|
|
21
|
+
: `${plugin.name} accepts: ${specs.map((s) => `${s.name} (${s.type}): ${s.description}`).join("; ")}`;
|
|
22
|
+
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
const eq = entry.indexOf("=");
|
|
25
|
+
const name = eq === -1 ? entry : entry.slice(0, eq);
|
|
26
|
+
const raw = eq === -1 ? undefined : entry.slice(eq + 1);
|
|
27
|
+
const spec = specs.find((s) => s.name === name);
|
|
28
|
+
if (!spec) {
|
|
29
|
+
return { error: `Unknown parser option "${name}" for lexicon "${plugin.name}"; ${accepted}.` };
|
|
30
|
+
}
|
|
31
|
+
if (spec.type === "boolean") {
|
|
32
|
+
if (raw === undefined || raw === "true") options[name] = true;
|
|
33
|
+
else if (raw === "false") options[name] = false;
|
|
34
|
+
else return { error: `Parser option "${name}" is a boolean: use ${name}, ${name}=true or ${name}=false, got "${raw}".` };
|
|
35
|
+
} else if (raw === undefined) {
|
|
36
|
+
return { error: `Parser option "${name}" needs a value: --parser-option ${name}=<${spec.type}>.` };
|
|
37
|
+
} else if (spec.type === "number") {
|
|
38
|
+
const n = Number(raw);
|
|
39
|
+
if (raw.trim() === "" || !Number.isFinite(n)) return { error: `Parser option "${name}" is a number, got "${raw}".` };
|
|
40
|
+
options[name] = n;
|
|
41
|
+
} else {
|
|
42
|
+
options[name] = raw;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { options };
|
|
46
|
+
}
|
package/src/import/parser.ts
CHANGED
|
@@ -78,6 +78,26 @@ export interface ParseContext {
|
|
|
78
78
|
readonly embedded?: EmbeddedContentResolver;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/** A value a parser option takes. */
|
|
82
|
+
export type ParserOptionValue = string | number | boolean;
|
|
83
|
+
|
|
84
|
+
/** The options `chant import --parser-option` hands a lexicon's parser, by name. */
|
|
85
|
+
export type ParserOptions = Record<string, ParserOptionValue>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* One option a lexicon's parser accepts, declared by `LexiconPlugin.parserOptions()`.
|
|
89
|
+
* `chant import --parser-option <name>[=<value>]` is checked against this list and
|
|
90
|
+
* the value is converted to `type` before `templateParser(options)` sees it.
|
|
91
|
+
*/
|
|
92
|
+
export interface ParserOptionSpec {
|
|
93
|
+
/** The key after `--parser-option`, e.g. "acceptLossyV1". */
|
|
94
|
+
name: string;
|
|
95
|
+
/** `boolean` takes `true`/`false`, and a bare `--parser-option name` means true. */
|
|
96
|
+
type: "boolean" | "string" | "number";
|
|
97
|
+
/** One line, shown when the option is refused and in the docs. */
|
|
98
|
+
description: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
81
101
|
/**
|
|
82
102
|
* Interface for template parsers that convert external formats to IR
|
|
83
103
|
*/
|
package/src/index.ts
CHANGED
|
@@ -149,6 +149,7 @@ export * from "./resource-attributes";
|
|
|
149
149
|
export * from "./stack-output";
|
|
150
150
|
export * from "./child-project";
|
|
151
151
|
export * from "./lsp/types";
|
|
152
|
+
export type { SymbolDeclaration, SymbolResolver } from "./workspace/symbols";
|
|
152
153
|
export * from "./lsp/lexicon-providers";
|
|
153
154
|
export * from "./mcp/types";
|
|
154
155
|
export * from "./lifecycle/index";
|
package/src/lexicon.ts
CHANGED
|
@@ -3,11 +3,13 @@ import type { Declarable } from "./declarable";
|
|
|
3
3
|
import type { LintRule } from "./lint/rule";
|
|
4
4
|
import type { RuleSpec } from "./lint/declarative";
|
|
5
5
|
import type { PostSynthCheck } from "./lint/post-synth";
|
|
6
|
-
import type { TemplateParser, TemplateIR, ParseContext } from "./import/parser";
|
|
6
|
+
import type { TemplateParser, TemplateIR, ParseContext, ParserOptions, ParserOptionSpec } from "./import/parser";
|
|
7
7
|
import type { TypeScriptGenerator } from "./import/generator";
|
|
8
8
|
import type { EmbeddedContentImporter } from "./import/embedded";
|
|
9
9
|
import type { AgentConfigImporter } from "./agents/importer";
|
|
10
10
|
import type { ArtifactIntegrity } from "./lexicon-integrity";
|
|
11
|
+
import type { GatedWavePipelineOptions } from "./components/gated-wave-pipeline";
|
|
12
|
+
import type { PrLoopPipelineOptions } from "./components/pr-pipeline";
|
|
11
13
|
import type { OkfFile } from "./okf";
|
|
12
14
|
import type { CompletionContext, CompletionItem, HoverContext, HoverInfo, CodeActionContext, CodeAction } from "./lsp/types";
|
|
13
15
|
import type { McpToolContribution, McpResourceContribution } from "./mcp/types";
|
|
@@ -26,6 +28,7 @@ import type { DescribeIdentityOptions, DescribeIdentityResult } from "./identity
|
|
|
26
28
|
import type { DeepNormalizationHooks, DeepObservationResult } from "./deep-observation";
|
|
27
29
|
import type { BehaviourResult, PredictBehaviourOptions } from "./behaviour";
|
|
28
30
|
import type { BehaviourKinds } from "./behaviour-kinds";
|
|
31
|
+
import type { SymbolResolver } from "./workspace/symbols";
|
|
29
32
|
import type { DisruptionQuery, DisruptionVerdict } from "./lifecycle/disruption";
|
|
30
33
|
import type { OwnerChainVerdict } from "./owner-chain";
|
|
31
34
|
import type { CommandGroup } from "./cli/command-group";
|
|
@@ -426,12 +429,26 @@ export interface InitTemplateSet {
|
|
|
426
429
|
* repos or version-constant locations. See ./codegen/pinned-upgrade.ts.
|
|
427
430
|
*/
|
|
428
431
|
export interface UpstreamPin {
|
|
432
|
+
/**
|
|
433
|
+
* Short name for this pin (`clickhouse`, `postgres-17`), used to pick one
|
|
434
|
+
* pin of a plugin that declares several (`chant dev pinned-upgrade <dir>
|
|
435
|
+
* <label>`). Optional on a lone `upstreamPin`, where it defaults to the
|
|
436
|
+
* lexicon's name; required on every entry of `upstreamPins`.
|
|
437
|
+
*/
|
|
438
|
+
readonly label?: string;
|
|
429
439
|
/** Source file (relative to the lexicon package root) holding the pinned version constant. */
|
|
430
440
|
readonly file: string;
|
|
431
441
|
/** Regex whose first capture group is the current pinned version in `file`. */
|
|
432
442
|
readonly pattern: RegExp;
|
|
433
443
|
/** Rebuild a line that matched `pattern`, substituting the new version. */
|
|
434
444
|
replace(newVersion: string, line: string): string;
|
|
445
|
+
/**
|
|
446
|
+
* Set when the version line is not the whole pin: other constants (an image
|
|
447
|
+
* digest, a checksum) move with it and `replace` cannot compute them. The
|
|
448
|
+
* upgrade tooling then reports the newer version and this text, and edits
|
|
449
|
+
* nothing. Say what to move and how.
|
|
450
|
+
*/
|
|
451
|
+
readonly alsoMoves?: string;
|
|
435
452
|
/** Where to query for the latest stable upstream tag. */
|
|
436
453
|
readonly upstream: {
|
|
437
454
|
readonly owner: string;
|
|
@@ -440,6 +457,25 @@ export interface UpstreamPin {
|
|
|
440
457
|
readonly kind: "releases" | "tags";
|
|
441
458
|
/** Only consider tags ending with this suffix (e.g. "-ee" for GitLab). */
|
|
442
459
|
readonly tagSuffix?: string;
|
|
460
|
+
/**
|
|
461
|
+
* Map a raw tag to the version string the pin stores, or null to skip the
|
|
462
|
+
* tag. For upstreams whose tags are not versions: postgres/postgres tags
|
|
463
|
+
* are `REL_18_6`, `REL_18_BETA1`, `REL9_6_24`, so
|
|
464
|
+
* `(t) => /^REL_(\d+)_(\d+)$/.exec(t)?.slice(1).join(".") ?? null` gives
|
|
465
|
+
* `18.6` and drops betas, release candidates and the old spelling.
|
|
466
|
+
*
|
|
467
|
+
* When set, the tool reads every page of the tag list (not just the first
|
|
468
|
+
* 50), because such lists are not ordered by version, and the version this
|
|
469
|
+
* returns is what `replace` receives and what the report shows. The pinned
|
|
470
|
+
* constant may hold either the mapped version or the raw tag.
|
|
471
|
+
*/
|
|
472
|
+
readonly tagVersion?: (tag: string) => string | null;
|
|
473
|
+
/**
|
|
474
|
+
* Only consider versions whose first numeric segment equals the pinned
|
|
475
|
+
* version's, so a pin on `17.9` reports `17.11` and never `18.6`. For
|
|
476
|
+
* lexicons that pin one snapshot per major line. Default false.
|
|
477
|
+
*/
|
|
478
|
+
readonly trackMajor?: boolean;
|
|
443
479
|
};
|
|
444
480
|
}
|
|
445
481
|
|
|
@@ -503,6 +539,20 @@ export interface ComponentPipelineOptions {
|
|
|
503
539
|
* `["chant", "components", "promote", "--from", <env>, "--to", <promoteTo>]`.
|
|
504
540
|
*/
|
|
505
541
|
promoteCommand?: string[];
|
|
542
|
+
/**
|
|
543
|
+
* Gated waves (#3049): one job per wave instead of one per component. Job
|
|
544
|
+
* `wave-<k>` runs `chant components fan-out --wave-gate <gate> --wave <k>`
|
|
545
|
+
* and hands the attempt record to the next job. See
|
|
546
|
+
* `components/gated-wave-pipeline.ts`. Unset, the pipeline is unchanged.
|
|
547
|
+
*/
|
|
548
|
+
gatedWaves?: GatedWavePipelineOptions;
|
|
549
|
+
/**
|
|
550
|
+
* The pull-request loop (#3183): a plan job on each pull request and an
|
|
551
|
+
* apply job on each push to the target branch, bound to the digest a
|
|
552
|
+
* reviewer approved, instead of one job per component. See
|
|
553
|
+
* `components/pr-pipeline.ts`. Unset, the pipeline is unchanged.
|
|
554
|
+
*/
|
|
555
|
+
prLoop?: PrLoopPipelineOptions;
|
|
506
556
|
/**
|
|
507
557
|
* The workspace member this pipeline belongs to (#2542, #2524 D19). Core
|
|
508
558
|
* sets it when the project sits in a member of a `chant.workspace.json`;
|
|
@@ -857,6 +907,16 @@ export interface StackStatusObservation {
|
|
|
857
907
|
/**
|
|
858
908
|
* Context for a lexicon's {@link LexiconPlugin.buildRoots} hook (#1548).
|
|
859
909
|
*/
|
|
910
|
+
/** What {@link LexiconPlugin.changedUnits} reads (#3183). */
|
|
911
|
+
export interface ChangedUnitsContext {
|
|
912
|
+
/** The directory `chant.config.*` lives in. Config paths resolve against it. */
|
|
913
|
+
projectRoot: string;
|
|
914
|
+
/** The resolved project configuration, for the lexicon's own namespace. */
|
|
915
|
+
config: Record<string, unknown>;
|
|
916
|
+
/** Files the change added, modified or deleted, relative to `projectRoot`, with `/` separators. */
|
|
917
|
+
changedFiles: string[];
|
|
918
|
+
}
|
|
919
|
+
|
|
860
920
|
export interface BuildRootContext {
|
|
861
921
|
/**
|
|
862
922
|
* The directory the project configuration was loaded from (where
|
|
@@ -1160,8 +1220,19 @@ export interface LexiconPlugin {
|
|
|
1160
1220
|
*/
|
|
1161
1221
|
detectTemplate?(data: unknown): boolean;
|
|
1162
1222
|
|
|
1163
|
-
/**
|
|
1164
|
-
|
|
1223
|
+
/**
|
|
1224
|
+
* Return a parser for importing external templates into IR. `options` holds
|
|
1225
|
+
* the `chant import --parser-option` values, already checked against
|
|
1226
|
+
* `parserOptions()` and converted to their declared types; it is empty when
|
|
1227
|
+
* none were given.
|
|
1228
|
+
*/
|
|
1229
|
+
templateParser?(options?: ParserOptions): TemplateParser;
|
|
1230
|
+
|
|
1231
|
+
/**
|
|
1232
|
+
* The options `templateParser` accepts. `chant import --parser-option` refuses
|
|
1233
|
+
* any name not listed here, so a lexicon with no options leaves this out.
|
|
1234
|
+
*/
|
|
1235
|
+
parserOptions?(): ParserOptionSpec[];
|
|
1165
1236
|
|
|
1166
1237
|
/** Return a generator for converting IR to TypeScript */
|
|
1167
1238
|
templateGenerator?(): TypeScriptGenerator;
|
|
@@ -1200,6 +1271,14 @@ export interface LexiconPlugin {
|
|
|
1200
1271
|
/** How this lexicon pins its upstream schema version + where to check for a newer one (self-upgrade tooling — see ./codegen/pinned-upgrade.ts). Omit for lexicons with no pinned upstream. */
|
|
1201
1272
|
readonly upstreamPin?: UpstreamPin;
|
|
1202
1273
|
|
|
1274
|
+
/**
|
|
1275
|
+
* Further pins, for a lexicon that pins more than one upstream (sql: the
|
|
1276
|
+
* ClickHouse pin in `upstreamPin` plus one Postgres server per major). Each
|
|
1277
|
+
* entry needs a unique `label`. The upgrade tooling checks `upstreamPin` and
|
|
1278
|
+
* every entry here, one report per pin. Omit when there is one pin.
|
|
1279
|
+
*/
|
|
1280
|
+
readonly upstreamPins?: readonly (UpstreamPin & { readonly label: string })[];
|
|
1281
|
+
|
|
1203
1282
|
/**
|
|
1204
1283
|
* Generate a CI pipeline from the discovered component graph — the
|
|
1205
1284
|
* `chant build --components --generate <name>` seam. Only CI-provider
|
|
@@ -1259,6 +1338,18 @@ export interface LexiconPlugin {
|
|
|
1259
1338
|
*/
|
|
1260
1339
|
buildRoots?(ctx: BuildRootContext): Promise<BuildRootContribution>;
|
|
1261
1340
|
|
|
1341
|
+
/**
|
|
1342
|
+
* The units this lexicon owns that a change touched, judged from the
|
|
1343
|
+
* changed files alone (#3183). A unit is a name a component's deploy step
|
|
1344
|
+
* targets (`deploy-units.ts`): the terraform lexicon answers with the
|
|
1345
|
+
* `terraform.roots` entries whose directory, local modules or var files a
|
|
1346
|
+
* changed file sits in. `chant components fan-out --base` and `chant
|
|
1347
|
+
* components pr-plan` add these to the stacks `lifecycle affected` finds,
|
|
1348
|
+
* since a root that is not chant source never shows in an artifact diff.
|
|
1349
|
+
* Omit for lexicons whose units are chant source.
|
|
1350
|
+
*/
|
|
1351
|
+
changedUnits?(ctx: ChangedUnitsContext): Promise<string[]>;
|
|
1352
|
+
|
|
1262
1353
|
/**
|
|
1263
1354
|
* Facts about the whole read that this lexicon's entities imply, for the
|
|
1264
1355
|
* graph IR's `meta` bag (#2559). The otel lexicon answers
|
|
@@ -1285,6 +1376,18 @@ export interface LexiconPlugin {
|
|
|
1285
1376
|
/** Provide code actions for LSP */
|
|
1286
1377
|
codeActionProvider?(ctx: CodeActionContext): CodeAction[];
|
|
1287
1378
|
|
|
1379
|
+
/**
|
|
1380
|
+
* Symbol resolvers for the languages this lexicon's members are written in
|
|
1381
|
+
* (#3313), so `chant workspace graph --intent <path>#<symbol>` names a
|
|
1382
|
+
* declaration in such a file: a table in a `.sql` file, a resource in a
|
|
1383
|
+
* manifest. Each is `{ language, extensions, declarations(path, text) }`,
|
|
1384
|
+
* returning every declaration's dotted name, kind and 1-based line range.
|
|
1385
|
+
* The intent walk asks the lexicons a file's member configures, after
|
|
1386
|
+
* core's TypeScript and JavaScript resolver, which keeps `.ts` and `.js`.
|
|
1387
|
+
* Pure: no I/O, no network. Omit for a lexicon with no such language.
|
|
1388
|
+
*/
|
|
1389
|
+
symbolResolvers?(): SymbolResolver[];
|
|
1390
|
+
|
|
1288
1391
|
// Docs
|
|
1289
1392
|
/** Generate documentation pages */
|
|
1290
1393
|
docs?(options?: { verbose?: boolean }): Promise<void>;
|
|
@@ -117,6 +117,13 @@ export interface GateResolutionRecord {
|
|
|
117
117
|
gate: string;
|
|
118
118
|
/** Who resolved it — an actor name, the same convention `components release --actor` and `run approve --approver` use. */
|
|
119
119
|
resolvedBy: string;
|
|
120
|
+
/**
|
|
121
|
+
* Who carried this approval to chant for `resolvedBy` (#3402): `chant
|
|
122
|
+
* approve --relayed-by`, such as a follower program relaying a person's
|
|
123
|
+
* approval. The approver is still `resolvedBy`; a seal covers this field
|
|
124
|
+
* too. Absent when the approver recorded it themselves.
|
|
125
|
+
*/
|
|
126
|
+
relayedBy?: string;
|
|
120
127
|
/** ISO-8601 timestamp, caller-supplied (library code never calls `Date.now()` internally). */
|
|
121
128
|
timestamp: string;
|
|
122
129
|
/** Optional free-text context. Before #2028 this was also where a PR link went by convention; put the link in {@link GateResolutionRecord.url} instead and leave this for prose. */
|
|
@@ -187,6 +194,22 @@ export interface GateResolutionRecord {
|
|
|
187
194
|
* was recorded. Present only when the gate declared a policy.
|
|
188
195
|
*/
|
|
189
196
|
policyDecision?: GatePolicyDecision;
|
|
197
|
+
/**
|
|
198
|
+
* An ssh signature over this approval by `resolvedBy` (#3163, ws-080):
|
|
199
|
+
* `chant approve --sign`, in the `chant-gate` namespace over the op, gate,
|
|
200
|
+
* environment, plan digest, approver and timestamp. It attests the approver
|
|
201
|
+
* only when the signers file at base lists a key for them. A gate the
|
|
202
|
+
* declaration's `identity.gates` names counts only approvals whose seal
|
|
203
|
+
* verifies. Absent on an unsigned approval.
|
|
204
|
+
*/
|
|
205
|
+
seal?: GateApprovalSeal;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** A gate approval's seal (#3163): who signed, the key's fingerprint (reported, never trusted), and the armored signature. */
|
|
209
|
+
export interface GateApprovalSeal {
|
|
210
|
+
signer: string;
|
|
211
|
+
key: string;
|
|
212
|
+
signature: string;
|
|
190
213
|
}
|
|
191
214
|
|
|
192
215
|
export type GateResolutionInput = Omit<GateResolutionRecord, "version" | "kind">;
|
package/src/lifecycle/git.ts
CHANGED
|
@@ -660,44 +660,120 @@ export async function getRemoteLifecycleBranchSha(
|
|
|
660
660
|
}
|
|
661
661
|
|
|
662
662
|
/**
|
|
663
|
-
*
|
|
663
|
+
* Why a push of the state branch did or did not reach the remote.
|
|
664
664
|
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
667
|
-
*
|
|
665
|
+
* - `pushed` — the remote now holds the local tip.
|
|
666
|
+
* - `no-remote` — nothing to push to; local is the whole ledger.
|
|
667
|
+
* - `stale` — the remote moved past the tip this checkout last saw (another
|
|
668
|
+
* writer pushed); fetch, re-apply and retry.
|
|
669
|
+
* - `failed` — git refused for another reason (no network, no credentials,
|
|
670
|
+
* a protected branch); `stderr` is git's first words on it.
|
|
671
|
+
*/
|
|
672
|
+
export type LifecyclePushStatus =
|
|
673
|
+
| { status: "pushed"; remote: string; commit: string }
|
|
674
|
+
| { status: "no-remote" }
|
|
675
|
+
| { status: "stale"; remote: string; expected: string | null; stderr: string }
|
|
676
|
+
| { status: "failed"; remote: string; stderr: string };
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Point `refs/remotes/<remote>/chant/lifecycle` at `sha`, the remote tip this
|
|
680
|
+
* checkout has just seen (#3391).
|
|
668
681
|
*
|
|
669
|
-
*
|
|
682
|
+
* The push's lease is that ref, and git only keeps it up to date when the
|
|
683
|
+
* remote's configured fetch refspec covers `chant/lifecycle`. A single-branch
|
|
684
|
+
* clone (`git clone --single-branch`, a CI checkout of one ref, a shallow
|
|
685
|
+
* clone) has a refspec for its one branch only, so neither the explicit
|
|
686
|
+
* `chant/lifecycle:chant/lifecycle` fetch nor a successful push touches the
|
|
687
|
+
* tracking ref. The first push of a new branch then succeeds against an empty
|
|
688
|
+
* lease, and every later one is refused as stale against a remote that holds
|
|
689
|
+
* exactly what this checkout last pushed. Recording the tip ourselves, only at
|
|
690
|
+
* the two moments it is known (a fetch that fast-forwarded or found the local
|
|
691
|
+
* branch ahead, and a push that landed), keeps the lease honest without
|
|
692
|
+
* widening the clone's refspec. It is never set from a diverged fetch: that is
|
|
693
|
+
* the case the lease exists to refuse.
|
|
670
694
|
*/
|
|
671
|
-
|
|
695
|
+
async function trackRemoteLifecycle(remote: string, sha: string, cwd?: string): Promise<void> {
|
|
672
696
|
const rt = getRuntime();
|
|
673
|
-
|
|
674
|
-
|
|
697
|
+
await rt.spawn(["git", "update-ref", `refs/remotes/${remote}/${STATE_BRANCH}`, sha], { cwd, env: C_LOCALE_ENV });
|
|
698
|
+
}
|
|
675
699
|
|
|
676
|
-
|
|
700
|
+
/**
|
|
701
|
+
* Push the state branch to the ledger remote with --force-with-lease and say
|
|
702
|
+
* what happened (#3391). Never throws for a git refusal; {@link pushLifecycle}
|
|
703
|
+
* is the throwing form most callers use.
|
|
704
|
+
*/
|
|
705
|
+
export async function pushLifecycleStatus(opts?: { cwd?: string }): Promise<LifecyclePushStatus> {
|
|
706
|
+
const rt = getRuntime();
|
|
707
|
+
const cwd = opts?.cwd;
|
|
708
|
+
const found = await ledgerRemote(cwd);
|
|
709
|
+
if (found === null) return { status: "no-remote" };
|
|
710
|
+
if ("failed" in found) return { status: "failed", remote: "(unknown)", stderr: found.stderr };
|
|
711
|
+
const { remote } = found;
|
|
677
712
|
|
|
678
713
|
// Capture the lease SHA — if null, the remote ref doesn't exist yet
|
|
679
714
|
// (first-time push) and we send `--force-with-lease=ref:` (empty SHA),
|
|
680
715
|
// which git interprets as "ref does not exist on remote".
|
|
681
716
|
const expected = await getRemoteLifecycleBranchSha(remote, opts);
|
|
682
717
|
const lease = `refs/heads/${STATE_BRANCH}:${expected ?? ""}`;
|
|
718
|
+
const tip = await getStateBranchTip(cwd);
|
|
683
719
|
|
|
684
720
|
const pushResult = await rt.spawn(
|
|
685
721
|
["git", "push", `--force-with-lease=${lease}`, remote, `${STATE_BRANCH}:${STATE_BRANCH}`],
|
|
686
|
-
{ cwd:
|
|
722
|
+
{ cwd, env: C_LOCALE_ENV },
|
|
687
723
|
);
|
|
688
724
|
|
|
689
725
|
if (pushResult.exitCode !== 0) {
|
|
690
|
-
const stderr = pushResult.stderr ?? "";
|
|
726
|
+
const stderr = (pushResult.stderr ?? "").trim();
|
|
691
727
|
if (
|
|
692
728
|
stderr.includes("stale info") ||
|
|
693
729
|
stderr.includes("rejected") ||
|
|
694
730
|
stderr.includes("non-fast-forward")
|
|
695
731
|
) {
|
|
696
|
-
|
|
732
|
+
return { status: "stale", remote, expected, stderr };
|
|
697
733
|
}
|
|
698
|
-
return
|
|
734
|
+
return { status: "failed", remote, stderr };
|
|
735
|
+
}
|
|
736
|
+
if (tip) await trackRemoteLifecycle(remote, tip, cwd);
|
|
737
|
+
return { status: "pushed", remote, commit: tip ?? "" };
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Push the state branch to remote with --force-with-lease.
|
|
742
|
+
*
|
|
743
|
+
* If the remote chant/lifecycle ref has advanced past the local remote-tracking
|
|
744
|
+
* SHA captured at the start of this push, the push is rejected and we throw
|
|
745
|
+
* StaleLifecycleBranchError so the caller can surface a recovery hint.
|
|
746
|
+
*
|
|
747
|
+
* Returns false (without throwing) when no remote is configured, or when git
|
|
748
|
+
* refused the push for a reason other than a stale lease.
|
|
749
|
+
*
|
|
750
|
+
* The remote is the ledger's ({@link ledgerRemote}: `origin` when there is one),
|
|
751
|
+
* the same one {@link fetchLifecycleStatus} reads, and a push that lands
|
|
752
|
+
* records the tip it pushed as the remote-tracking ref, so the next push's
|
|
753
|
+
* lease is right in a single-branch clone too (#3391).
|
|
754
|
+
*/
|
|
755
|
+
export async function pushLifecycle(opts?: { cwd?: string }): Promise<boolean> {
|
|
756
|
+
const result = await pushLifecycleStatus(opts);
|
|
757
|
+
if (result.status === "stale") throw new StaleLifecycleBranchError(result.expected, result.stderr);
|
|
758
|
+
return result.status === "pushed";
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* One line on why a push did not land, for a write document's `notPushed`
|
|
763
|
+
* (#3391), or null when it did.
|
|
764
|
+
*/
|
|
765
|
+
export function describeLifecyclePush(result: LifecyclePushStatus): string | null {
|
|
766
|
+
const said = (stderr: string) => (stderr ? `; git said: ${stderr.split("\n").find((l) => l.trim()) ?? stderr}` : "");
|
|
767
|
+
switch (result.status) {
|
|
768
|
+
case "pushed":
|
|
769
|
+
return null;
|
|
770
|
+
case "no-remote":
|
|
771
|
+
return `this repository has no remote, so ${STATE_BRANCH} stays local`;
|
|
772
|
+
case "stale":
|
|
773
|
+
return `"${result.remote}" holds ${STATE_BRANCH} commits this checkout has not fetched, so the push was refused; fetch ${STATE_BRANCH} and write again${said(result.stderr)}`;
|
|
774
|
+
case "failed":
|
|
775
|
+
return `the push of ${STATE_BRANCH} to "${result.remote}" failed${said(result.stderr)}`;
|
|
699
776
|
}
|
|
700
|
-
return true;
|
|
701
777
|
}
|
|
702
778
|
|
|
703
779
|
/**
|
|
@@ -814,7 +890,12 @@ export async function fetchLifecycleStatus(opts?: { cwd?: string }): Promise<Lif
|
|
|
814
890
|
["git", "fetch", remote, `${STATE_BRANCH}:${STATE_BRANCH}`],
|
|
815
891
|
{ cwd, env: C_LOCALE_ENV },
|
|
816
892
|
);
|
|
817
|
-
if (fetchResult.exitCode === 0)
|
|
893
|
+
if (fetchResult.exitCode === 0) {
|
|
894
|
+
// The local branch is now the remote's tip; record it for the push's lease (#3391).
|
|
895
|
+
const tip = await getStateBranchTip(cwd);
|
|
896
|
+
if (tip) await trackRemoteLifecycle(remote, tip, cwd);
|
|
897
|
+
return { status: "fetched" };
|
|
898
|
+
}
|
|
818
899
|
|
|
819
900
|
const stderr = (fetchResult.stderr ?? "").trim();
|
|
820
901
|
if (NO_SUCH_REMOTE_REF_RE.test(stderr)) return { status: "absent", remote };
|
|
@@ -834,8 +915,13 @@ export async function fetchLifecycleStatus(opts?: { cwd?: string }): Promise<Lif
|
|
|
834
915
|
["git", "merge-base", "--is-ancestor", PROBE_REF, `refs/heads/${STATE_BRANCH}`],
|
|
835
916
|
{ cwd, env: C_LOCALE_ENV },
|
|
836
917
|
);
|
|
918
|
+
const remoteTip = contains.exitCode === 0 ? (await rt.spawn(["git", "rev-parse", "--verify", PROBE_REF], { cwd, env: C_LOCALE_ENV })).stdout.trim() : "";
|
|
837
919
|
await rt.spawn(["git", "update-ref", "-d", PROBE_REF], { cwd, env: C_LOCALE_ENV });
|
|
838
|
-
if (contains.exitCode === 0)
|
|
920
|
+
if (contains.exitCode === 0) {
|
|
921
|
+
// Ahead of the remote: its tip is in our history, so it is the right lease (#3391).
|
|
922
|
+
if (remoteTip) await trackRemoteLifecycle(remote, remoteTip, cwd);
|
|
923
|
+
return { status: "ahead", remote };
|
|
924
|
+
}
|
|
839
925
|
return { status: "diverged", remote, stderr };
|
|
840
926
|
}
|
|
841
927
|
|
|
@@ -97,6 +97,24 @@ describe("observeResources", () => {
|
|
|
97
97
|
expect(names).toEqual(["web-vpc"]);
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
+
it("keeps property-kind declarables out of the observation universe (#3001)", async () => {
|
|
101
|
+
// A property-kind declarable (a grafana panel, an aws SecurityGroup_Ingress
|
|
102
|
+
// const) carries props but lives only inside the resource holding it.
|
|
103
|
+
// Asked about on its own, a reader can only say "absent" or "not observed".
|
|
104
|
+
const buildResult = {
|
|
105
|
+
outputs: new Map<string, string>([["aws", "{}"]]),
|
|
106
|
+
entities: new Map<string, unknown>([
|
|
107
|
+
["web-sg", { lexicon: "aws", entityType: "AWS::EC2::SecurityGroup", kind: "resource", props: {} }],
|
|
108
|
+
["ingress", { lexicon: "aws", entityType: "AWS::EC2::SecurityGroup.Ingress", kind: "property", props: { FromPort: 443 } }],
|
|
109
|
+
]),
|
|
110
|
+
errors: [],
|
|
111
|
+
} as unknown as BuildResult;
|
|
112
|
+
let names: string[] = [];
|
|
113
|
+
const plugins = [awsPlugin(({ entityNames }) => { names = entityNames; return {}; })];
|
|
114
|
+
await observeResources("prod", plugins, buildResult);
|
|
115
|
+
expect(names).toEqual(["web-sg"]);
|
|
116
|
+
});
|
|
117
|
+
|
|
100
118
|
it("collects a throwing plugin into errors instead of failing the whole graph, and reports its entities unobserved (#1089)", async () => {
|
|
101
119
|
const plugins = [
|
|
102
120
|
awsPlugin(() => { throw new Error("access denied"); }),
|
package/src/lifecycle/observe.ts
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "../observation";
|
|
26
26
|
import { zeroResourcesWarning } from "../live-endpoint";
|
|
27
27
|
import { unqualifiedKey } from "./identity";
|
|
28
|
-
import {
|
|
28
|
+
import { isObservableDeclarable } from "../declarable";
|
|
29
29
|
|
|
30
30
|
export interface ObserveResult {
|
|
31
31
|
observations: LiveObservation[];
|
|
@@ -150,8 +150,10 @@ export async function observeResources(
|
|
|
150
150
|
// parameters and serializer directives (gcp's `defaultAnnotations`) are
|
|
151
151
|
// build-time inputs — declared, but with nothing in any cloud to compare
|
|
152
152
|
// against, so keeping them in the universe makes every diff report a
|
|
153
|
-
// hole (or worse, a deletion) for a resource that cannot exist.
|
|
154
|
-
|
|
153
|
+
// hole (or worse, a deletion) for a resource that cannot exist. A
|
|
154
|
+
// property-kind declarable is read as part of the resource holding it,
|
|
155
|
+
// never on its own (#3001).
|
|
156
|
+
if (!isObservableDeclarable(entity)) continue;
|
|
155
157
|
entityNames.push(name);
|
|
156
158
|
entities.set(name, {
|
|
157
159
|
entityType: entity.entityType,
|
|
@@ -174,7 +176,7 @@ export async function observeResources(
|
|
|
174
176
|
stackEntityNames = [];
|
|
175
177
|
stackEntities = new Map();
|
|
176
178
|
for (const [name, entity] of sb.entities) {
|
|
177
|
-
if (entity.lexicon !== plugin.name || !
|
|
179
|
+
if (entity.lexicon !== plugin.name || !isObservableDeclarable(entity)) continue;
|
|
178
180
|
stackEntityNames.push(name);
|
|
179
181
|
stackEntities.set(name, {
|
|
180
182
|
entityType: entity.entityType,
|
|
@@ -18,7 +18,7 @@ import { formatUnobserved, normalizeObservation, unobservedAll, type UnobservedE
|
|
|
18
18
|
// property tree is ever rendered or committed. Two lists would eventually
|
|
19
19
|
// disagree about what counts as a secret.
|
|
20
20
|
import { isSensitiveKey } from "../deep-observation";
|
|
21
|
-
import {
|
|
21
|
+
import { isObservableDeclarable } from "../declarable";
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Check for potential sensitive data in resource attributes and return warnings.
|
|
@@ -128,7 +128,7 @@ export async function takeSnapshot(
|
|
|
128
128
|
for (const [name, entity] of buildResult.entities) {
|
|
129
129
|
// Resource declarables only — outputs, parameters and serializer
|
|
130
130
|
// directives have no live counterpart (see lifecycle/observe.ts).
|
|
131
|
-
if (entity.lexicon === plugin.name &&
|
|
131
|
+
if (entity.lexicon === plugin.name && isObservableDeclarable(entity)) {
|
|
132
132
|
entityNames.push(name);
|
|
133
133
|
entities.set(name, {
|
|
134
134
|
entityType: entity.entityType,
|