@intentius/chant 0.124.45 → 0.124.48
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/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-hold.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-pass.json +10 -0
- package/dist/__golden__/wave-loop/op-by-apply-skip.json +10 -0
- package/dist/__golden__/wave-loop/op-cost-member-clash.json +6 -0
- package/dist/__golden__/wave-loop/op-cost-member.json +13 -0
- package/dist/__golden__/wave-loop/op-denied-source.json +16 -0
- package/dist/__golden__/wave-loop/op-denied.json +16 -0
- package/dist/__golden__/wave-loop/op-discover-rest-short.json +6 -0
- package/dist/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
- package/dist/__golden__/wave-loop/op-discover-rest.json +26 -0
- package/dist/__golden__/wave-loop/op-discover-wide.json +26 -0
- package/dist/__golden__/wave-loop/op-held-on-again.json +16 -0
- package/dist/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
- package/dist/__golden__/wave-loop/op-held-on.json +16 -0
- package/dist/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-held.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-pass.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
- package/dist/__golden__/wave-loop/op-hooks-share.json +33 -0
- package/dist/__golden__/wave-loop/op-outcome-held.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-replan.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
- package/dist/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
- package/dist/__golden__/wave-loop/op-overridden.json +16 -0
- package/dist/__golden__/wave-loop/op-per-run.json +20 -0
- package/dist/__golden__/wave-loop/op-point.json +13 -0
- package/dist/__golden__/wave-loop/op-pr-review.json +10 -0
- package/dist/__golden__/wave-loop/op-sealed.json +10 -0
- package/dist/__golden__/wave-loop/op-spend-change-only.json +10 -0
- package/dist/__golden__/wave-loop/op-spend.json +10 -0
- package/dist/__golden__/wave-loop/op-wave-commands.json +55 -0
- package/dist/__golden__/wave-loop/op-wide-refused.json +26 -0
- package/dist/__golden__/wave-loop/op-wide-waiting.json +29 -0
- package/dist/__golden__/wave-loop/op-wide.json +39 -0
- package/dist/action-pins.d.ts +61 -0
- package/dist/action-pins.d.ts.map +1 -0
- package/dist/action-pins.js +77 -0
- package/dist/capabilities/aws.paths +148 -0
- package/dist/capabilities/base-mappings.json +122 -0
- package/dist/capabilities/catalog.d.ts +89 -0
- package/dist/capabilities/catalog.d.ts.map +1 -0
- package/dist/capabilities/catalog.js +204 -0
- package/dist/capabilities/language.d.ts +103 -0
- package/dist/capabilities/language.d.ts.map +1 -0
- package/dist/capabilities/language.js +335 -0
- package/dist/capabilities/matcher.d.ts +65 -0
- package/dist/capabilities/matcher.d.ts.map +1 -0
- package/dist/capabilities/matcher.js +299 -0
- package/dist/capabilities/view.d.ts +207 -0
- package/dist/capabilities/view.d.ts.map +1 -0
- package/dist/capabilities/view.js +484 -0
- package/dist/cli/commands/carve.d.ts +3 -0
- package/dist/cli/commands/carve.d.ts.map +1 -1
- package/dist/cli/commands/carve.js +36 -7
- package/dist/cli/commands/import-report.d.ts +26 -0
- package/dist/cli/commands/import-report.d.ts.map +1 -0
- package/dist/cli/commands/import-report.js +65 -0
- package/dist/cli/commands/import.d.ts +11 -1
- package/dist/cli/commands/import.d.ts.map +1 -1
- package/dist/cli/commands/import.js +22 -3
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +1 -0
- package/dist/cli/commands/migrate.d.ts +13 -1
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/migrate.js +134 -10
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +21 -2
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +6 -1
- package/dist/cli/handlers/declared-graph.d.ts +44 -0
- package/dist/cli/handlers/declared-graph.d.ts.map +1 -0
- package/dist/cli/handlers/declared-graph.js +87 -0
- package/dist/cli/handlers/graph.d.ts +25 -0
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/graph.js +93 -87
- package/dist/cli/handlers/ledger.d.ts +3 -0
- package/dist/cli/handlers/ledger.d.ts.map +1 -0
- package/dist/cli/handlers/ledger.js +55 -0
- package/dist/cli/handlers/migrate.d.ts.map +1 -1
- package/dist/cli/handlers/migrate.js +18 -11
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/misc.js +12 -1
- package/dist/cli/handlers/pr-env.d.ts.map +1 -1
- package/dist/cli/handlers/pr-env.js +4 -3
- package/dist/cli/handlers/pr.d.ts +15 -1
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +143 -39
- package/dist/cli/handlers/query.d.ts +7 -2
- package/dist/cli/handlers/query.d.ts.map +1 -1
- package/dist/cli/handlers/query.js +16 -4
- package/dist/cli/handlers/release.d.ts.map +1 -1
- package/dist/cli/handlers/release.js +6 -3
- package/dist/cli/handlers/search-count.d.ts +89 -0
- package/dist/cli/handlers/search-count.d.ts.map +1 -0
- package/dist/cli/handlers/search-count.js +132 -0
- package/dist/cli/handlers/search.d.ts +356 -6
- package/dist/cli/handlers/search.d.ts.map +1 -1
- package/dist/cli/handlers/search.js +1039 -155
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +88 -17
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/server.js +3 -0
- package/dist/cli/mcp/tools/capabilities.d.ts +7 -0
- package/dist/cli/mcp/tools/capabilities.d.ts.map +1 -0
- package/dist/cli/mcp/tools/capabilities.js +27 -0
- package/dist/cli/mcp/workspace-tools.d.ts +3 -1
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-tools.js +47 -2
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +100 -19
- package/dist/cli/registry.d.ts +36 -4
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/components/builders.d.ts +5 -1
- package/dist/components/builders.d.ts.map +1 -1
- package/dist/components/builders.js +5 -0
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.js +16 -1
- package/dist/components/capability-plugin.d.ts +14 -0
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/pr-env-ports.d.ts +29 -0
- package/dist/components/pr-env-ports.d.ts.map +1 -0
- package/dist/components/pr-env-ports.js +77 -0
- package/dist/components/pr-env-run.d.ts +5 -21
- package/dist/components/pr-env-run.d.ts.map +1 -1
- package/dist/components/pr-env-run.js +6 -70
- package/dist/components/pr-environment.d.ts +2 -1
- package/dist/components/pr-environment.d.ts.map +1 -1
- package/dist/components/pr-environment.js +1 -1
- package/dist/components/pr-hooks.d.ts +21 -1
- package/dist/components/pr-hooks.d.ts.map +1 -1
- package/dist/components/pr-hooks.js +72 -4
- package/dist/components/pr-pipeline.d.ts +45 -10
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +47 -14
- package/dist/components/pr-policy.d.ts +36 -0
- package/dist/components/pr-policy.d.ts.map +1 -1
- package/dist/components/pr-policy.js +36 -0
- package/dist/components/starter-plugin.d.ts +1 -0
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/starter-plugin.js +5 -1
- package/dist/components/verbs/index.d.ts +2 -0
- package/dist/components/verbs/index.d.ts.map +1 -1
- package/dist/components/verbs/index.js +2 -0
- package/dist/components/verbs/publish-artifact.d.ts +65 -0
- package/dist/components/verbs/publish-artifact.d.ts.map +1 -0
- package/dist/components/verbs/publish-artifact.js +74 -0
- package/dist/components/verbs/publish-image.d.ts +129 -0
- package/dist/components/verbs/publish-image.d.ts.map +1 -0
- package/dist/components/verbs/publish-image.js +145 -0
- package/dist/config-environments.d.ts +112 -0
- package/dist/config-environments.d.ts.map +1 -0
- package/dist/config-environments.js +114 -0
- package/dist/config.d.ts +32 -84
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -96
- package/dist/gate-decision.d.ts +11 -2
- package/dist/gate-decision.d.ts.map +1 -1
- package/dist/gate-decision.js +15 -3
- package/dist/graph-detail.d.ts.map +1 -1
- package/dist/graph-detail.js +15 -3
- package/dist/graph-effective.d.ts +33 -2
- package/dist/graph-effective.d.ts.map +1 -1
- package/dist/graph-effective.js +215 -68
- package/dist/graph-ir.d.ts +48 -0
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-ir.js +130 -0
- package/dist/graph-sub-template.d.ts +11 -0
- package/dist/graph-sub-template.d.ts.map +1 -0
- package/dist/graph-sub-template.js +19 -0
- package/dist/graph-walk.d.ts +66 -0
- package/dist/graph-walk.d.ts.map +1 -0
- package/dist/graph-walk.js +70 -0
- package/dist/import/parser.d.ts +19 -0
- package/dist/import/parser.d.ts.map +1 -1
- package/dist/lexicon.d.ts +80 -6
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +11 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +2 -5
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/ledger-read.d.ts +65 -0
- package/dist/lifecycle/ledger-read.d.ts.map +1 -0
- package/dist/lifecycle/ledger-read.js +160 -0
- package/dist/lifecycle/observe.d.ts +28 -0
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/observe.js +23 -1
- package/dist/lifecycle/release-workstation.d.ts +7 -0
- package/dist/lifecycle/release-workstation.d.ts.map +1 -1
- package/dist/lifecycle/release-workstation.js +25 -0
- package/dist/lifecycle/run-ledger.d.ts +4 -3
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +1 -0
- package/dist/lint/discover.js +3 -1
- package/dist/lint/post-synth.d.ts +127 -1
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/lint/post-synth.js +84 -2
- package/dist/lint/rule.d.ts +6 -0
- package/dist/lint/rule.d.ts.map +1 -1
- package/dist/lint/rules/op/index.d.ts +1 -0
- package/dist/lint/rules/op/index.d.ts.map +1 -1
- package/dist/lint/rules/op/index.js +2 -0
- package/dist/lint/rules/op/ops019-workspace-op-target.d.ts +32 -0
- package/dist/lint/rules/op/ops019-workspace-op-target.d.ts.map +1 -0
- package/dist/lint/rules/op/ops019-workspace-op-target.js +63 -0
- package/dist/live-endpoint.d.ts +1 -1
- package/dist/live-endpoint.d.ts.map +1 -1
- package/dist/live-endpoint.js +1 -1
- package/dist/observation.d.ts +48 -1
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +21 -5
- package/dist/op/activities/activity-contracts.d.ts +9 -6
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.js +5 -2
- package/dist/op/activities/index.d.ts +2 -2
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/index.js +1 -1
- package/dist/op/activities/review-agent.d.ts +90 -4
- package/dist/op/activities/review-agent.d.ts.map +1 -1
- package/dist/op/activities/review-agent.js +217 -19
- package/dist/op/activities/work-evidence.d.ts +8 -1
- package/dist/op/activities/work-evidence.d.ts.map +1 -1
- package/dist/op/activities/work-evidence.js +1 -0
- package/dist/op/builders.d.ts +9 -5
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +9 -5
- package/dist/op/composites/apply-op.d.ts +29 -2
- package/dist/op/composites/apply-op.d.ts.map +1 -1
- package/dist/op/composites/apply-op.js +20 -1
- package/dist/op/gate-approval.d.ts +11 -5
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-approval.js +11 -6
- package/dist/op/gate-quorum.d.ts +100 -3
- package/dist/op/gate-quorum.d.ts.map +1 -1
- package/dist/op/gate-quorum.js +108 -6
- package/dist/op/gate-review.d.ts +9 -0
- package/dist/op/gate-review.d.ts.map +1 -1
- package/dist/op/gate-review.js +13 -0
- package/dist/op/gate.d.ts +44 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/gate.js +25 -4
- package/dist/op/index.d.ts +3 -3
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/index.js +1 -1
- package/dist/op/local-executor.d.ts +38 -3
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +48 -6
- package/dist/op/op-waves-run.d.ts +26 -1
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +259 -13
- package/dist/op/op-waves.d.ts +72 -5
- package/dist/op/op-waves.d.ts.map +1 -1
- package/dist/op/op-waves.js +110 -15
- package/dist/op/runtime.d.ts +11 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/schedule-overdue.d.ts +16 -0
- package/dist/op/schedule-overdue.d.ts.map +1 -1
- package/dist/op/schedule-overdue.js +36 -0
- package/dist/op/stage-hooks.d.ts +9 -2
- package/dist/op/stage-hooks.d.ts.map +1 -1
- package/dist/op/stage-hooks.js +7 -5
- package/dist/op/workspace-run-env.d.ts +22 -0
- package/dist/op/workspace-run-env.d.ts.map +1 -0
- package/dist/op/workspace-run-env.js +21 -0
- package/dist/pr-forge.d.ts +24 -0
- package/dist/pr-forge.d.ts.map +1 -1
- package/dist/pr-forge.js +47 -0
- package/dist/pr-post.d.ts +42 -0
- package/dist/pr-post.d.ts.map +1 -1
- package/dist/pr-post.js +67 -1
- package/dist/read-filter.d.ts +65 -0
- package/dist/read-filter.d.ts.map +1 -0
- package/dist/read-filter.js +179 -0
- package/dist/run-event.d.ts +1 -1
- package/dist/run-event.d.ts.map +1 -1
- package/dist/terraform/carve.d.ts +24 -3
- package/dist/terraform/carve.d.ts.map +1 -1
- package/dist/terraform/carve.js +32 -14
- package/dist/terraform/cuts.d.ts +97 -0
- package/dist/terraform/cuts.d.ts.map +1 -0
- package/dist/terraform/cuts.js +138 -0
- package/dist/terraform/folds.d.ts +26 -0
- package/dist/terraform/folds.d.ts.map +1 -0
- package/dist/terraform/folds.js +38 -0
- package/dist/terraform/graph.d.ts.map +1 -1
- package/dist/terraform/graph.js +10 -0
- package/dist/terraform/reach.d.ts +140 -0
- package/dist/terraform/reach.d.ts.map +1 -0
- package/dist/terraform/reach.js +170 -0
- package/dist/terraform/score.d.ts +14 -0
- package/dist/terraform/score.d.ts.map +1 -1
- package/dist/terraform/score.js +14 -31
- package/dist/terraform/state.d.ts.map +1 -1
- package/dist/terraform/state.js +4 -2
- package/dist/terraform/types.d.ts +8 -0
- package/dist/terraform/types.d.ts.map +1 -1
- package/dist/wave-blocked.d.ts +10 -1
- package/dist/wave-blocked.d.ts.map +1 -1
- package/dist/wave-blocked.js +31 -3
- package/dist/wave-runtime.mjs +266 -256
- package/dist/workspace/capabilities-contract.d.ts +66 -0
- package/dist/workspace/capabilities-contract.d.ts.map +1 -0
- package/dist/workspace/capabilities-contract.js +107 -0
- package/dist/workspace/capabilities.schema.json +229 -0
- package/dist/workspace/check.schema.json +11 -2
- package/dist/workspace/checks/ci-branch.d.ts +44 -0
- package/dist/workspace/checks/ci-branch.d.ts.map +1 -0
- package/dist/workspace/checks/ci-branch.js +133 -0
- package/dist/workspace/checks/links.d.ts +3 -0
- package/dist/workspace/checks/links.d.ts.map +1 -1
- package/dist/workspace/checks/links.js +12 -1
- package/dist/workspace/checks/org.d.ts +48 -0
- package/dist/workspace/checks/org.d.ts.map +1 -0
- package/dist/workspace/checks/org.js +156 -0
- package/dist/workspace/checks.d.ts +11 -1
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/checks.js +59 -7
- package/dist/workspace/ci-branches.d.ts +16 -0
- package/dist/workspace/ci-branches.d.ts.map +1 -1
- package/dist/workspace/ci-branches.js +27 -0
- package/dist/workspace/ci-green-cli.js +7 -7
- package/dist/workspace/ci-green-workflow.d.ts +1 -1
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +13 -8
- package/dist/workspace/ci-green.d.ts +14 -0
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +44 -11
- package/dist/workspace/ci-run.d.ts +9 -1
- package/dist/workspace/ci-run.d.ts.map +1 -1
- package/dist/workspace/ci-run.js +67 -6
- package/dist/workspace/ci-serve.d.ts +9 -0
- package/dist/workspace/ci-serve.d.ts.map +1 -1
- package/dist/workspace/ci-serve.js +114 -76
- package/dist/workspace/compose-graph.d.ts +23 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/compose-graph.js +3 -1
- package/dist/workspace/composites.d.ts +4 -1
- package/dist/workspace/composites.d.ts.map +1 -1
- package/dist/workspace/composites.js +5 -2
- package/dist/workspace/composites.schema.json +22 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
- package/dist/workspace/conformance/index.d.ts +1 -1
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/index.js +39 -2
- package/dist/workspace/cross-root-lint.d.ts +56 -0
- package/dist/workspace/cross-root-lint.d.ts.map +1 -0
- package/dist/workspace/cross-root-lint.js +111 -0
- package/dist/workspace/dbt-models-reader.d.ts +44 -0
- package/dist/workspace/dbt-models-reader.d.ts.map +1 -0
- package/dist/workspace/dbt-models-reader.js +356 -0
- package/dist/workspace/dbt-project-common.d.ts +40 -0
- package/dist/workspace/dbt-project-common.d.ts.map +1 -0
- package/dist/workspace/dbt-project-common.js +106 -0
- package/dist/workspace/dbt-project-reader.d.ts +4 -3
- package/dist/workspace/dbt-project-reader.d.ts.map +1 -1
- package/dist/workspace/dbt-project-reader.js +14 -108
- package/dist/workspace/decision-rank.d.ts +26 -0
- package/dist/workspace/decision-rank.d.ts.map +1 -0
- package/dist/workspace/decision-rank.js +16 -0
- package/dist/workspace/declaration.d.ts +43 -2
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +45 -11
- package/dist/workspace/declaration.schema.json +133 -24
- package/dist/workspace/environments.d.ts +26 -2
- package/dist/workspace/environments.d.ts.map +1 -1
- package/dist/workspace/environments.js +26 -2
- package/dist/workspace/flyway-dir.d.ts +39 -0
- package/dist/workspace/flyway-dir.d.ts.map +1 -0
- package/dist/workspace/flyway-dir.js +104 -0
- package/dist/workspace/flyway-layout.d.ts +96 -0
- package/dist/workspace/flyway-layout.d.ts.map +1 -0
- package/dist/workspace/flyway-layout.js +308 -0
- package/dist/workspace/graph-cache.d.ts +8 -0
- package/dist/workspace/graph-cache.d.ts.map +1 -1
- package/dist/workspace/graph-cache.js +27 -3
- package/dist/workspace/graph-cli.d.ts +39 -2
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/graph-cli.js +92 -32
- package/dist/workspace/graph.schema.json +182 -0
- package/dist/workspace/intent.d.ts +2 -3
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +5 -9
- package/dist/workspace/kind-link-readers.d.ts +59 -2
- package/dist/workspace/kind-link-readers.d.ts.map +1 -1
- package/dist/workspace/kind-link-readers.js +17 -1
- package/dist/workspace/kind-readers.d.ts +3 -0
- package/dist/workspace/kind-readers.d.ts.map +1 -1
- package/dist/workspace/kind-readers.js +7 -1
- package/dist/workspace/kinds.d.ts +66 -2
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/kinds.js +98 -4
- package/dist/workspace/ledger.schema.json +158 -0
- package/dist/workspace/lexicon-outputs.d.ts +20 -1
- package/dist/workspace/lexicon-outputs.d.ts.map +1 -1
- package/dist/workspace/lexicon-outputs.js +102 -10
- package/dist/workspace/lineage-check.d.ts +3 -0
- package/dist/workspace/lineage-check.d.ts.map +1 -1
- package/dist/workspace/lineage-check.js +23 -4
- package/dist/workspace/links.d.ts +8 -1
- package/dist/workspace/links.d.ts.map +1 -1
- package/dist/workspace/links.js +25 -1
- package/dist/workspace/ls.d.ts +8 -0
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/ls.js +7 -1
- package/dist/workspace/ls.schema.json +7 -0
- package/dist/workspace/member-commands.d.ts +10 -1
- package/dist/workspace/member-commands.d.ts.map +1 -1
- package/dist/workspace/member-commands.js +71 -6
- package/dist/workspace/migrate-links.d.ts +45 -0
- package/dist/workspace/migrate-links.d.ts.map +1 -0
- package/dist/workspace/migrate-links.js +100 -0
- package/dist/workspace/migration-dirs.d.ts +74 -0
- package/dist/workspace/migration-dirs.d.ts.map +1 -0
- package/dist/workspace/migration-dirs.js +254 -0
- package/dist/workspace/nested-graph.d.ts +2 -0
- package/dist/workspace/nested-graph.d.ts.map +1 -1
- package/dist/workspace/nested-graph.js +32 -1
- package/dist/workspace/reason-codes.d.ts +18 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +23 -0
- package/dist/workspace/records-cli.d.ts +11 -0
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-cli.js +57 -5
- package/dist/workspace/records.schema.json +5 -0
- package/dist/workspace/release-candidates.d.ts +2 -0
- package/dist/workspace/release-candidates.d.ts.map +1 -1
- package/dist/workspace/release-candidates.js +5 -2
- package/dist/workspace/release-train.d.ts +53 -0
- package/dist/workspace/release-train.d.ts.map +1 -0
- package/dist/workspace/release-train.js +134 -0
- package/dist/workspace/release-workflow.d.ts.map +1 -1
- package/dist/workspace/release-workflow.js +4 -3
- package/dist/workspace/repo-ref.d.ts +45 -0
- package/dist/workspace/repo-ref.d.ts.map +1 -0
- package/dist/workspace/repo-ref.js +114 -0
- package/dist/workspace/run-event.schema.json +2 -2
- package/dist/workspace/runs-cli.d.ts +9 -0
- package/dist/workspace/runs-cli.d.ts.map +1 -1
- package/dist/workspace/runs-cli.js +48 -3
- package/dist/workspace/runs.schema.json +7 -0
- package/dist/workspace/search-cli.d.ts +204 -0
- package/dist/workspace/search-cli.d.ts.map +1 -0
- package/dist/workspace/search-cli.js +466 -0
- package/dist/workspace/search-contract.d.ts +56 -0
- package/dist/workspace/search-contract.d.ts.map +1 -0
- package/dist/workspace/search-contract.js +70 -0
- package/dist/workspace/search.schema.json +822 -0
- package/dist/workspace/status-decisions.d.ts +37 -0
- package/dist/workspace/status-decisions.d.ts.map +1 -0
- package/dist/workspace/status-decisions.js +147 -0
- package/dist/workspace/status-gates.d.ts +9 -0
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +4 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +14 -2
- package/dist/workspace/status.schema.json +6 -0
- package/dist/workspace/work-cli.d.ts.map +1 -1
- package/dist/workspace/work-cli.js +5 -3
- package/dist/workspace/work-evidence-ops.d.ts +83 -0
- package/dist/workspace/work-evidence-ops.d.ts.map +1 -0
- package/dist/workspace/work-evidence-ops.js +169 -0
- package/dist/workspace/work-evidence.d.ts +12 -2
- package/dist/workspace/work-evidence.d.ts.map +1 -1
- package/dist/workspace/work-evidence.js +21 -3
- package/dist/workspace/work-evidence.schema.json +49 -2
- package/dist/workspace/workspace-gates.d.ts +110 -0
- package/dist/workspace/workspace-gates.d.ts.map +1 -0
- package/dist/workspace/workspace-gates.js +140 -0
- package/dist/workspace/workspace-kinds.schema.json +58 -3
- package/dist/workspace/workspace-ledger.d.ts +76 -0
- package/dist/workspace/workspace-ledger.d.ts.map +1 -0
- package/dist/workspace/workspace-ledger.js +91 -0
- package/dist/workspace/workspace-run.d.ts +112 -0
- package/dist/workspace/workspace-run.d.ts.map +1 -0
- package/dist/workspace/workspace-run.js +432 -0
- package/package.json +1 -1
- package/src/__golden__/wave-loop/op-by-apply-after-fails.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-hold.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-ignored.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-pass.json +10 -0
- package/src/__golden__/wave-loop/op-by-apply-skip.json +10 -0
- package/src/__golden__/wave-loop/op-cost-member-clash.json +6 -0
- package/src/__golden__/wave-loop/op-cost-member.json +13 -0
- package/src/__golden__/wave-loop/op-denied-source.json +16 -0
- package/src/__golden__/wave-loop/op-denied.json +16 -0
- package/src/__golden__/wave-loop/op-discover-rest-short.json +6 -0
- package/src/__golden__/wave-loop/op-discover-rest-stops.json +13 -0
- package/src/__golden__/wave-loop/op-discover-rest.json +26 -0
- package/src/__golden__/wave-loop/op-discover-wide.json +26 -0
- package/src/__golden__/wave-loop/op-held-on-again.json +16 -0
- package/src/__golden__/wave-loop/op-held-on-before-apply.json +16 -0
- package/src/__golden__/wave-loop/op-held-on.json +16 -0
- package/src/__golden__/wave-loop/op-hooks-apply-fails.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-fail-after-apply.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-fail-before-apply.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-fail-before-plan.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-held.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-pass.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +13 -0
- package/src/__golden__/wave-loop/op-hooks-share.json +33 -0
- package/src/__golden__/wave-loop/op-outcome-held.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-replan-approved.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-replan-forever.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-replan.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-stood-down.json +10 -0
- package/src/__golden__/wave-loop/op-outcome-unreadable.json +10 -0
- package/src/__golden__/wave-loop/op-overridden.json +16 -0
- package/src/__golden__/wave-loop/op-per-run.json +20 -0
- package/src/__golden__/wave-loop/op-point.json +13 -0
- package/src/__golden__/wave-loop/op-pr-review.json +10 -0
- package/src/__golden__/wave-loop/op-sealed.json +10 -0
- package/src/__golden__/wave-loop/op-spend-change-only.json +10 -0
- package/src/__golden__/wave-loop/op-spend.json +10 -0
- package/src/__golden__/wave-loop/op-wave-commands.json +55 -0
- package/src/__golden__/wave-loop/op-wide-refused.json +26 -0
- package/src/__golden__/wave-loop/op-wide-waiting.json +29 -0
- package/src/__golden__/wave-loop/op-wide.json +39 -0
- package/src/__snapshots__/okf.test.ts.snap +10 -0
- package/src/action-pins.test.ts +78 -0
- package/src/action-pins.ts +92 -0
- package/src/capabilities/aws.paths +148 -0
- package/src/capabilities/base-mappings.json +122 -0
- package/src/capabilities/catalog.ts +230 -0
- package/src/capabilities/language.test.ts +191 -0
- package/src/capabilities/language.ts +373 -0
- package/src/capabilities/matcher.ts +315 -0
- package/src/capabilities/view-compose.test.ts +76 -0
- package/src/capabilities/view.ts +631 -0
- package/src/cli/commands/carve-score-once.test.ts +99 -0
- package/src/cli/commands/carve.ts +37 -6
- package/src/cli/commands/check-lexicon.test.ts +2 -2
- package/src/cli/commands/import-report.ts +71 -0
- package/src/cli/commands/import.ts +33 -3
- package/src/cli/commands/lint.ts +1 -0
- package/src/cli/commands/migrate-dialect.test.ts +145 -0
- package/src/cli/commands/migrate.ts +132 -11
- package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +4 -4
- package/src/cli/handlers/approve.ts +23 -2
- package/src/cli/handlers/build.ts +7 -1
- package/src/cli/handlers/declared-graph.ts +99 -0
- package/src/cli/handlers/graph.test.ts +94 -3
- package/src/cli/handlers/graph.ts +123 -96
- package/src/cli/handlers/ledger.ts +54 -0
- package/src/cli/handlers/migrate.ts +21 -12
- package/src/cli/handlers/misc.ts +10 -1
- package/src/cli/handlers/pr-env.ts +3 -4
- package/src/cli/handlers/pr.ts +138 -36
- package/src/cli/handlers/query.ts +16 -4
- package/src/cli/handlers/release.ts +6 -3
- package/src/cli/handlers/search-build-roots.test.ts +144 -0
- package/src/cli/handlers/search-count.test.ts +191 -0
- package/src/cli/handlers/search-count.ts +165 -0
- package/src/cli/handlers/search-json.test.ts +333 -0
- package/src/cli/handlers/search-live.test.ts +387 -0
- package/src/cli/handlers/search-paths.test.ts +235 -0
- package/src/cli/handlers/search.ts +1291 -166
- package/src/cli/main.test.ts +43 -3
- package/src/cli/main.ts +88 -17
- package/src/cli/mcp/server.test.ts +3 -3
- package/src/cli/mcp/server.ts +3 -0
- package/src/cli/mcp/tools/capabilities.ts +32 -0
- package/src/cli/mcp/workspace-tools.e2e.test.ts +21 -1
- package/src/cli/mcp/workspace-tools.ts +47 -2
- package/src/cli/parse-args.ts +79 -15
- package/src/cli/registry.ts +36 -4
- package/src/components/builders.ts +8 -0
- package/src/components/capability-plugin-loader.ts +13 -1
- package/src/components/capability-plugin.ts +16 -0
- package/src/components/pr-env-ports.ts +89 -0
- package/src/components/pr-env-run-bundle.test.ts +54 -0
- package/src/components/pr-env-run.ts +5 -76
- package/src/components/pr-environment.ts +2 -1
- package/src/components/pr-hooks.test.ts +73 -5
- package/src/components/pr-hooks.ts +95 -5
- package/src/components/pr-pipeline.ts +64 -16
- package/src/components/pr-policy.test.ts +64 -1
- package/src/components/pr-policy.ts +53 -0
- package/src/components/registry.test.ts +1 -1
- package/src/components/starter-plugin.ts +6 -0
- package/src/components/verbs/index.ts +2 -0
- package/src/components/verbs/publish-artifact.test.ts +60 -0
- package/src/components/verbs/publish-artifact.ts +122 -0
- package/src/components/verbs/publish-image.test.ts +101 -0
- package/src/components/verbs/publish-image.ts +265 -0
- package/src/config-environments.ts +160 -0
- package/src/config.ts +44 -124
- package/src/gate-decision-bundle.test.ts +1 -0
- package/src/gate-decision-identity.test.ts +9 -0
- package/src/gate-decision.ts +26 -3
- package/src/graph-detail.ts +15 -3
- package/src/graph-effective.ts +226 -75
- package/src/graph-ir.test.ts +163 -0
- package/src/graph-ir.ts +174 -0
- package/src/graph-sub-template.ts +22 -0
- package/src/graph-walk.test.ts +44 -0
- package/src/graph-walk.ts +102 -0
- package/src/import/parser.ts +20 -0
- package/src/lexicon.ts +84 -6
- package/src/lifecycle/gate-ledger.ts +8 -0
- package/src/lifecycle/git.ts +2 -2
- package/src/lifecycle/ledger-read.test.ts +107 -0
- package/src/lifecycle/ledger-read.ts +195 -0
- package/src/lifecycle/observe.test.ts +27 -1
- package/src/lifecycle/observe.ts +43 -1
- package/src/lifecycle/release-workstation.ts +24 -0
- package/src/lifecycle/run-ledger.ts +5 -2
- package/src/lint/cross-root.test.ts +122 -0
- package/src/lint/discover.ts +3 -1
- package/src/lint/post-synth.ts +212 -2
- package/src/lint/rule.ts +6 -0
- package/src/lint/rules/op/index.ts +2 -0
- package/src/lint/rules/op/ops019-workspace-op-target.ts +89 -0
- package/src/live-endpoint.ts +1 -1
- package/src/observation.test.ts +25 -0
- package/src/observation.ts +69 -5
- package/src/op/activities/activity-contracts.ts +5 -2
- package/src/op/activities/index.ts +2 -2
- package/src/op/activities/review-agent.test.ts +221 -4
- package/src/op/activities/review-agent.ts +265 -22
- package/src/op/activities/work-evidence.ts +9 -1
- package/src/op/builders.ts +9 -5
- package/src/op/composites/apply-op.test.ts +108 -0
- package/src/op/composites/apply-op.ts +37 -2
- package/src/op/gate-approval.test.ts +6 -1
- package/src/op/gate-approval.ts +12 -6
- package/src/op/gate-quorum-at-base.test.ts +211 -0
- package/src/op/gate-quorum.ts +156 -8
- package/src/op/gate-review.ts +14 -0
- package/src/op/gate.ts +67 -8
- package/src/op/index.ts +3 -2
- package/src/op/local-executor.ts +69 -9
- package/src/op/op-waves-depends-on.test.ts +81 -0
- package/src/op/op-waves-hook-targets.test.ts +4 -2
- package/src/op/op-waves-quorum-product.test.ts +158 -0
- package/src/op/op-waves-run.ts +288 -14
- package/src/op/op-waves.ts +143 -14
- package/src/op/runtime.ts +8 -0
- package/src/op/schedule-overdue.ts +33 -0
- package/src/op/stage-hooks.ts +13 -5
- package/src/op/workspace-run-env.ts +29 -0
- package/src/pr-forge-bundle.test.ts +2 -2
- package/src/pr-forge.test.ts +47 -0
- package/src/pr-forge.ts +68 -0
- package/src/pr-post-open.e2e.test.ts +36 -0
- package/src/pr-post.test.ts +102 -3
- package/src/pr-post.ts +89 -1
- package/src/read-filter.test.ts +54 -0
- package/src/read-filter.ts +193 -0
- package/src/run-event.ts +1 -1
- package/src/stage-hooks-bundle.test.ts +1 -0
- package/src/terraform/carve.ts +52 -15
- package/src/terraform/cuts.test.ts +173 -0
- package/src/terraform/cuts.ts +188 -0
- package/src/terraform/folds.ts +44 -0
- package/src/terraform/graph.ts +9 -0
- package/src/terraform/radius.test.ts +90 -0
- package/src/terraform/reach.test.ts +146 -0
- package/src/terraform/reach.ts +247 -0
- package/src/terraform/score.ts +27 -29
- package/src/terraform/state.ts +3 -1
- package/src/terraform/types.ts +8 -0
- package/src/wave-blocked.ts +28 -3
- package/src/wave-loop-golden.test.ts +4 -3
- package/src/workspace/behold-kinds.test.ts +1 -1
- package/src/workspace/capabilities-contract.test.ts +88 -0
- package/src/workspace/capabilities-contract.ts +132 -0
- package/src/workspace/capabilities.schema.json +229 -0
- package/src/workspace/check-contract.test.ts +7 -6
- package/src/workspace/check.schema.json +11 -2
- package/src/workspace/checks/ci-branch.test.ts +128 -0
- package/src/workspace/checks/ci-branch.ts +141 -0
- package/src/workspace/checks/links.ts +12 -1
- package/src/workspace/checks/org.ts +169 -0
- package/src/workspace/checks.ts +64 -7
- package/src/workspace/ci-branches.ts +31 -0
- package/src/workspace/ci-green-branches.test.ts +153 -0
- package/src/workspace/ci-green-cli.ts +7 -7
- package/src/workspace/ci-green-workflow.test.ts +4 -3
- package/src/workspace/ci-green-workflow.ts +13 -9
- package/src/workspace/ci-green.ts +49 -12
- package/src/workspace/ci-run.test.ts +72 -1
- package/src/workspace/ci-run.ts +68 -8
- package/src/workspace/ci-serve.test.ts +95 -0
- package/src/workspace/ci-serve.ts +106 -65
- package/src/workspace/component-environments.test.ts +25 -2
- package/src/workspace/compose-graph.ts +19 -3
- package/src/workspace/composites.schema.json +22 -0
- package/src/workspace/composites.test.ts +39 -8
- package/src/workspace/composites.ts +6 -2
- package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +105 -1
- package/src/workspace/conformance/conformance.e2e.test.ts +14 -1
- package/src/workspace/conformance/index.ts +31 -2
- package/src/workspace/cross-root-lint.test.ts +90 -0
- package/src/workspace/cross-root-lint.ts +126 -0
- package/src/workspace/dbt-kind.test.ts +3 -2
- package/src/workspace/dbt-models-reader.ts +362 -0
- package/src/workspace/dbt-models.test.ts +248 -0
- package/src/workspace/dbt-project-common.ts +113 -0
- package/src/workspace/dbt-project-reader.ts +29 -112
- package/src/workspace/decision-rank.ts +40 -0
- package/src/workspace/declaration.schema.json +133 -24
- package/src/workspace/declaration.ts +84 -15
- package/src/workspace/environments.ts +40 -4
- package/src/workspace/flyway-dir.ts +113 -0
- package/src/workspace/flyway-layout.ts +337 -0
- package/src/workspace/graph-cache.ts +27 -3
- package/src/workspace/graph-cli.ts +119 -32
- package/src/workspace/graph-contract.test.ts +4 -2
- package/src/workspace/graph.schema.json +182 -0
- package/src/workspace/identity.test.ts +14 -2
- package/src/workspace/intent.ts +6 -14
- package/src/workspace/kind-link-readers.ts +68 -3
- package/src/workspace/kind-readers.e2e.test.ts +28 -0
- package/src/workspace/kind-readers.test.ts +1 -1
- package/src/workspace/kind-readers.ts +7 -1
- package/src/workspace/kinds.test.ts +12 -7
- package/src/workspace/kinds.ts +132 -7
- package/src/workspace/ledger.schema.json +158 -0
- package/src/workspace/lexicon-outputs.ts +132 -13
- package/src/workspace/lineage-check.ts +30 -7
- package/src/workspace/links.ts +24 -1
- package/src/workspace/ls-contract.test.ts +1 -1
- package/src/workspace/ls.schema.json +7 -0
- package/src/workspace/ls.ts +10 -1
- package/src/workspace/member-commands.ts +82 -3
- package/src/workspace/member-file-schema.test.ts +124 -0
- package/src/workspace/migrate-links.test.ts +99 -0
- package/src/workspace/migrate-links.ts +108 -0
- package/src/workspace/migration-dirs.test.ts +272 -0
- package/src/workspace/migration-dirs.ts +267 -0
- package/src/workspace/nested-graph.ts +32 -1
- package/src/workspace/org-scope.test.ts +238 -0
- package/src/workspace/reason-codes.test.ts +13 -1
- package/src/workspace/reason-codes.ts +23 -0
- package/src/workspace/records-cli.ts +58 -5
- package/src/workspace/records.schema.json +5 -0
- package/src/workspace/release-candidates.ts +7 -2
- package/src/workspace/release-train.ts +157 -0
- package/src/workspace/release-workflow.ts +4 -3
- package/src/workspace/repo-ref.ts +113 -0
- package/src/workspace/run-event.schema.json +2 -2
- package/src/workspace/runs-cli.ts +48 -4
- package/src/workspace/runs.schema.json +7 -0
- package/src/workspace/search-cli.e2e.test.ts +305 -0
- package/src/workspace/search-cli.ts +591 -0
- package/src/workspace/search-contract.ts +95 -0
- package/src/workspace/search.schema.json +822 -0
- package/src/workspace/status-contract.test.ts +46 -1
- package/src/workspace/status-decisions.test.ts +100 -0
- package/src/workspace/status-decisions.ts +151 -0
- package/src/workspace/status-gates.ts +9 -0
- package/src/workspace/status.schema.json +6 -0
- package/src/workspace/status.ts +17 -3
- package/src/workspace/where-filters.test.ts +39 -0
- package/src/workspace/work-cli.ts +5 -3
- package/src/workspace/work-evidence-ops.test.ts +176 -0
- package/src/workspace/work-evidence-ops.ts +189 -0
- package/src/workspace/work-evidence.schema.json +49 -2
- package/src/workspace/work-evidence.ts +22 -3
- package/src/workspace/workspace-gates.ts +200 -0
- package/src/workspace/workspace-kinds.schema.json +58 -3
- package/src/workspace/workspace-ledger.ts +130 -0
- package/src/workspace/workspace-run.test.ts +322 -0
- package/src/workspace/workspace-run.ts +461 -0
package/src/cli/handlers/pr.ts
CHANGED
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
*/
|
|
66
66
|
|
|
67
67
|
import { spawnSync } from "node:child_process";
|
|
68
|
-
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
69
|
-
import { join, resolve } from "node:path";
|
|
68
|
+
import { mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
69
|
+
import { join, relative, resolve, sep } from "node:path";
|
|
70
70
|
import { loadChantConfig, resolveAutoReleaseDisabled, type ChantConfig } from "../../config";
|
|
71
71
|
import { resolveCommit, resolveMergeBase } from "../../components/changed-files";
|
|
72
72
|
import { deriveFanOut, fanOutRegistry } from "../../components/fan-out-support";
|
|
@@ -90,7 +90,8 @@ import { blockedMembers, blockedWords, settleEarlierWaves, type WaveMemberOutcom
|
|
|
90
90
|
import { readFanOutAttempt, writeFanOutAttempt, type FanOutAttempt, type PrApplyRecord } from "../../components/fan-out-record";
|
|
91
91
|
import { componentInputDigests, progressThatCarries } from "../../components/fan-out-inputs";
|
|
92
92
|
import { samePlanDigest } from "../../lifecycle/plan-digest";
|
|
93
|
-
import { gateIsSealed, gitGateLedgerPort, type GateCheck } from "../../op/gate";
|
|
93
|
+
import { evaluateGate, gateIsSealed, gitGateLedgerPort, type GateCheck, type GateLedgerPort } from "../../op/gate";
|
|
94
|
+
import type { OtherGateHold } from "../../op/stage-hooks";
|
|
94
95
|
import { emitGateStep, gateEventsOf, GATE_PHASE, type RunEventSink, type RunEventStream } from "../../run-event-stream";
|
|
95
96
|
import type { RunEventBody, RunEventComponentSettle, RunEventSettleStatus } from "../../run-event";
|
|
96
97
|
import { openCliRunEvents, refusesEventsWithJson } from "../run-events";
|
|
@@ -130,8 +131,8 @@ import type { ComponentChangeSignal, FanOutPlan } from "../../components/fan-out
|
|
|
130
131
|
import { failedRunExitCode, type DriverComponent } from "../../components/driver";
|
|
131
132
|
import type { CapabilityRegistry } from "../../components/capability";
|
|
132
133
|
import type { ComponentEnvironmentDeclaration } from "../../components/component";
|
|
133
|
-
import { prLoopHooksAt, runPrHooks, type PrHookPlace, type PrLoopHooks } from "../../components/pr-hooks";
|
|
134
|
-
import { decidePrPolicyOverride, prLoopPolicyAt, prPolicyReport, runPrPolicy, spendPrPolicyOverride, type PrLoopPolicy } from "../../components/pr-policy";
|
|
134
|
+
import { prLoopHooksAt, runPrHooks, type PrHoldSettled, type PrHookPlace, type PrLoopHooks } from "../../components/pr-hooks";
|
|
135
|
+
import { decidePrPolicyOverride, policyReviewOf, prLoopPolicyAt, prPolicyReport, runPrPolicy, spendPrPolicyOverride, type PrLoopPolicy } from "../../components/pr-policy";
|
|
135
136
|
import type { OpWaveHookMoment } from "../../op/op-waves";
|
|
136
137
|
import type { PrHookOutcome } from "../../pr-loop";
|
|
137
138
|
|
|
@@ -320,9 +321,19 @@ export function placeHooks(ctx: CommandContext, p: Prepared, stage: PrHookPlace[
|
|
|
320
321
|
* when no hook failed. A hold is logged: the pull request's gate already
|
|
321
322
|
* waits for a person's approval of the digest.
|
|
322
323
|
*/
|
|
323
|
-
export function runStageHook(
|
|
324
|
+
export async function runStageHook(
|
|
325
|
+
p: Prepared,
|
|
326
|
+
moment: OpWaveHookMoment,
|
|
327
|
+
components: readonly string[],
|
|
328
|
+
planned?: PrPlanSet,
|
|
329
|
+
what = "nothing was applied",
|
|
330
|
+
env?: Record<string, string>,
|
|
331
|
+
): Promise<string | undefined> {
|
|
324
332
|
if (!p.hookPlace || components.length === 0) return undefined;
|
|
325
|
-
const ran = runPrHooks(p.hooks, moment, p.hookPlace, components, planned ? { members: planned.members, plans: planned.plans } : undefined
|
|
333
|
+
const ran = await runPrHooks(p.hooks, moment, p.hookPlace, components, planned ? { members: planned.members, plans: planned.plans } : undefined, {
|
|
334
|
+
...(env ? { env } : {}),
|
|
335
|
+
settle: (hold) => settleHeldGate(p, hold),
|
|
336
|
+
});
|
|
326
337
|
p.hookOutcomes.push(...ran.outcomes);
|
|
327
338
|
for (const hold of ran.holds) console.error(formatInfo(`${hold} held, and the pull request's gate asks for an approval of the digest either way`));
|
|
328
339
|
if (!ran.failed) return undefined;
|
|
@@ -330,6 +341,46 @@ export function runStageHook(p: Prepared, moment: OpWaveHookMoment, components:
|
|
|
330
341
|
return p.hookFailed;
|
|
331
342
|
}
|
|
332
343
|
|
|
344
|
+
/**
|
|
345
|
+
* Settle a hook's hold on another gate (#4323), the way an Op waves job does:
|
|
346
|
+
* an approval of that gate and digest under its `identity.gates` rule read at
|
|
347
|
+
* base, else a pending fact for it. The plan stage writes nothing, so there
|
|
348
|
+
* it only reads.
|
|
349
|
+
*/
|
|
350
|
+
async function settleHeldGate(p: Prepared, hold: OtherGateHold): Promise<PrHoldSettled> {
|
|
351
|
+
const real = gitGateLedgerPort();
|
|
352
|
+
const ledger = p.hookPlace?.stage === "plan" ? readOnlyLedger(real) : real;
|
|
353
|
+
const port: GateLedgerPort = ledger.approvalRule ? { ...ledger, approvalRule: (g: string) => ledger.approvalRule!(g, { base: p.base }) } : ledger;
|
|
354
|
+
const op = hold.request.op ?? p.hookPlace?.op ?? "";
|
|
355
|
+
const check = await evaluateGate(port, {
|
|
356
|
+
op,
|
|
357
|
+
gate: hold.request.gate,
|
|
358
|
+
planDigest: hold.request.digest,
|
|
359
|
+
description: hold.request.description ?? `${hold.label} holds the pull request on it`,
|
|
360
|
+
fields: { ...hold.request.pending, approvalMode: "ledger", heldBy: { hook: hold.name, moment: hold.moment, ...(hold.target ? { target: hold.target } : {}) } },
|
|
361
|
+
});
|
|
362
|
+
if (check.satisfied) return { status: "approved", approvedBy: check.resolution.resolvedBy, approvedAt: check.resolution.timestamp };
|
|
363
|
+
for (const { resolution: r, reason } of check.refused ?? []) console.error(formatInfo(`${op} / ${hold.request.gate}: the approval by ${r.resolvedBy} at ${r.timestamp} does not count: ${reason}`));
|
|
364
|
+
return { status: "waiting" };
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Run the `after-gate` hooks once the pull request's gate decided (#4323),
|
|
369
|
+
* whatever it decided. `CHANT_GATE_STATUS` is `approved`, or `waiting` when no
|
|
370
|
+
* approval of the digest stands; `CHANT_GATE_OP`, `CHANT_GATE` and
|
|
371
|
+
* `CHANT_GATE_DIGEST` name the gate. Returns the failure message, as
|
|
372
|
+
* {@link runStageHook} does; the caller ignores it when the gate did not let
|
|
373
|
+
* the apply through, since the stage ends there anyway.
|
|
374
|
+
*/
|
|
375
|
+
export function runGateHook(p: Prepared, at: { op: string; digest: string; satisfied: boolean }, components: readonly string[]): Promise<string | undefined> {
|
|
376
|
+
return runStageHook(p, "after-gate", components, undefined, "nothing was applied", {
|
|
377
|
+
CHANT_GATE_STATUS: at.satisfied ? "approved" : "waiting",
|
|
378
|
+
CHANT_GATE_OP: at.op,
|
|
379
|
+
CHANT_GATE: p.gate,
|
|
380
|
+
CHANT_GATE_DIGEST: at.digest,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
|
|
333
384
|
const EMPTY_SET = (): PrPlanSet => ({ doc: composeChangeSet([]), members: [], plans: {}, outputs: {}, failed: true });
|
|
334
385
|
|
|
335
386
|
/**
|
|
@@ -338,11 +389,11 @@ const EMPTY_SET = (): PrPlanSet => ({ doc: composeChangeSet([]), members: [], pl
|
|
|
338
389
|
* set, so the stage reports `plan-failed` and nothing applies.
|
|
339
390
|
*/
|
|
340
391
|
async function hookedPlan(p: Prepared, components: readonly string[], plan: () => Promise<PrPlanSet>): Promise<PrPlanSet> {
|
|
341
|
-
if (runStageHook(p, "before-observe", components, undefined, "nothing was planned or applied")) return EMPTY_SET();
|
|
342
|
-
if (runStageHook(p, "before-plan", components, undefined, "nothing was planned or applied")) return EMPTY_SET();
|
|
392
|
+
if (await runStageHook(p, "before-observe", components, undefined, "nothing was planned or applied")) return EMPTY_SET();
|
|
393
|
+
if (await runStageHook(p, "before-plan", components, undefined, "nothing was planned or applied")) return EMPTY_SET();
|
|
343
394
|
const set = await plan();
|
|
344
395
|
if (set.failed) return set;
|
|
345
|
-
if (runStageHook(p, "after-plan", components, set)) return { ...set, failed: true };
|
|
396
|
+
if (await runStageHook(p, "after-plan", components, set)) return { ...set, failed: true };
|
|
346
397
|
return set;
|
|
347
398
|
}
|
|
348
399
|
|
|
@@ -570,7 +621,9 @@ interface PolicyJudged {
|
|
|
570
621
|
* read only at the plan stage, and recorded for an override at the apply.
|
|
571
622
|
*/
|
|
572
623
|
async function judgePolicy(p: Prepared, at: { stage: "plan" | "apply"; op: string; pr: number | null; set: PrPlanSet }): Promise<PolicyJudged> {
|
|
573
|
-
|
|
624
|
+
// The review is read only when a policy will run: a workspace with no policy makes no forge call for it.
|
|
625
|
+
const review = p.policy.settings ? await policyReviewOf(p.forge, at.pr) : undefined;
|
|
626
|
+
const verdict = runPrPolicy(p.policy, { version: 1, stage: at.stage, op: at.op, gate: p.gate, env: p.env, pr: at.pr, base: p.base, head: p.head, changeSet: at.set.doc, ...(review ? { review } : {}) });
|
|
574
627
|
if (!verdict) return { held: false };
|
|
575
628
|
const report = prPolicyReport(verdict, p.policy.base);
|
|
576
629
|
p.policyReport = report;
|
|
@@ -712,27 +765,8 @@ async function prPlan(ctx: CommandContext, stage: StageEvents): Promise<number>
|
|
|
712
765
|
* `pr-post` asks instead, reading the Ops at the target branch's commit.
|
|
713
766
|
*/
|
|
714
767
|
async function overdueOps(forge: PrForge | undefined, member: string | undefined): Promise<PrOverdue[]> {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
const { discoverOps } = await import("../../op/discover");
|
|
718
|
-
const { scheduledWatches, checkOverdueOps } = await import("../../op/schedule-overdue");
|
|
719
|
-
const discovered = await discoverOps({ cwd: resolve(".") });
|
|
720
|
-
const watches = scheduledWatches([...discovered.ops.values()].map((d) => d.config));
|
|
721
|
-
if (watches.length === 0) return [];
|
|
722
|
-
const top = spawnSync("git", ["rev-parse", "--show-toplevel"], { encoding: "utf-8" });
|
|
723
|
-
if (top.status !== 0) return [];
|
|
724
|
-
return await checkOverdueOps({
|
|
725
|
-
watches,
|
|
726
|
-
forge,
|
|
727
|
-
repoRoot: top.stdout.trim(),
|
|
728
|
-
...(member ? { member } : {}),
|
|
729
|
-
now: new Date(),
|
|
730
|
-
log: (line) => console.error(formatWarning({ message: line })),
|
|
731
|
-
});
|
|
732
|
-
} catch (err) {
|
|
733
|
-
console.error(formatWarning({ message: `could not check the scheduled Ops, so none is reported overdue: ${err instanceof Error ? err.message : String(err)}` }));
|
|
734
|
-
return [];
|
|
735
|
-
}
|
|
768
|
+
const { overdueOpsAt } = await import("../../op/schedule-overdue");
|
|
769
|
+
return overdueOpsAt({ forge, cwd: resolve("."), ...(member ? { member } : {}), log: (line) => console.error(formatWarning({ message: line })) });
|
|
736
770
|
}
|
|
737
771
|
|
|
738
772
|
/** chant components pr-apply --base <ref> [--pr <n>] [--env <env>] [--gate <name>] [--forge <kind>] [--require-review] [--output <dir>] [--json] [--events-json] [--report-url <url>] */
|
|
@@ -881,6 +915,9 @@ async function prApply(ctx: CommandContext, stage: StageEvents, beforeMerge?: Pr
|
|
|
881
915
|
if (judged.stop) return stop(prReport({ ...base, approval: { status: "pending" }, status: "refused", refusal: judged.stop.refusal, message: judged.stop.message }), judged.stop.code);
|
|
882
916
|
const decided = await decideApplyGate(p, { op, pr, set, events, held: judged.held, ...(green ? { green } : {}) });
|
|
883
917
|
approval = decided.approval;
|
|
918
|
+
// #4323: the after-gate hooks hear the decision, a refusal too; only a failure that would have applied changes the outcome.
|
|
919
|
+
const afterGate = await runGateHook(p, { op, digest: set.doc.digest, satisfied: decided.satisfied }, p.plan.order);
|
|
920
|
+
if (afterGate && decided.satisfied) return stop(prReport({ ...base, approval, status: "failed", message: afterGate }), 1);
|
|
884
921
|
if (!decided.satisfied) return stop(prReport({ ...base, approval, status: "refused", refusal: decided.refusal, message: decided.message }), GATED_EXIT_CODE);
|
|
885
922
|
via = decided.via;
|
|
886
923
|
}
|
|
@@ -935,7 +972,7 @@ async function prApply(ctx: CommandContext, stage: StageEvents, beforeMerge?: Pr
|
|
|
935
972
|
|
|
936
973
|
// #4288: the before-apply hooks, once the gate and the review let the apply through.
|
|
937
974
|
const toApply = (resumed?.plan ?? p.plan).order.filter((name) => !completedSoFar.has(name));
|
|
938
|
-
const beforeFailed = runStageHook(p, "before-apply", toApply);
|
|
975
|
+
const beforeFailed = await runStageHook(p, "before-apply", toApply);
|
|
939
976
|
if (beforeFailed) return stop(prReport({ ...base, approval, status: "failed", message: beforeFailed }), 1);
|
|
940
977
|
|
|
941
978
|
// #3999: a round planned after an upstream applied waits on a gate of its
|
|
@@ -994,7 +1031,7 @@ async function prApply(ctx: CommandContext, stage: StageEvents, beforeMerge?: Pr
|
|
|
994
1031
|
});
|
|
995
1032
|
recordAttempt();
|
|
996
1033
|
// #4288: the after-apply hooks, for the components that applied.
|
|
997
|
-
const afterFailed = runStageHook(p, "after-apply", toApply.filter((name) => applied.run.completed.includes(name)), undefined, "the apply counts as failed though its components applied");
|
|
1034
|
+
const afterFailed = await runStageHook(p, "after-apply", toApply.filter((name) => applied.run.completed.includes(name)), undefined, "the apply counts as failed though its components applied");
|
|
998
1035
|
await recordAutoReleasesForRun(applied.run.results, p.env, release.runId, resolveAutoReleaseDisabled(p.config, args.noReleaseRecord), release.runOrigin, undefined, undefined, prAppliedDigests(p, applied.members));
|
|
999
1036
|
const report = prReport({
|
|
1000
1037
|
...base,
|
|
@@ -1787,6 +1824,9 @@ async function prApplyWaves(
|
|
|
1787
1824
|
if (judged.stop) return stop(report({ status: "refused", refusal: judged.stop.refusal, message: judged.stop.message }), judged.stop.code);
|
|
1788
1825
|
const decided = await decideApplyGate(p, { op, pr, set, events, held: judged.held, ...(green ? { green } : {}) });
|
|
1789
1826
|
approval = decided.approval;
|
|
1827
|
+
// #4323: the after-gate hooks hear the decision, a refusal too.
|
|
1828
|
+
const afterGate = await runGateHook(p, { op, digest: set.doc.digest, satisfied: decided.satisfied }, p.plan.order);
|
|
1829
|
+
if (afterGate && decided.satisfied) return stop(report({ status: "failed", message: afterGate }), 1);
|
|
1790
1830
|
if (!decided.satisfied) return stop(report({ status: "refused", refusal: decided.refusal, message: decided.message }), GATED_EXIT_CODE);
|
|
1791
1831
|
via = decided.via;
|
|
1792
1832
|
planned = set;
|
|
@@ -1944,7 +1984,7 @@ async function prApplyWaves(
|
|
|
1944
1984
|
}
|
|
1945
1985
|
|
|
1946
1986
|
// #4288: the wave's apply-side hooks, around its apply.
|
|
1947
|
-
const waveBefore = runStageHook(p, "before-apply", wavePlan.order, undefined, `nothing in wave ${k} was applied`);
|
|
1987
|
+
const waveBefore = await runStageHook(p, "before-apply", wavePlan.order, undefined, `nothing in wave ${k} was applied`);
|
|
1948
1988
|
if (waveBefore) {
|
|
1949
1989
|
setWave({ ...entry, status: "failed" });
|
|
1950
1990
|
return stop(report({ status: "failed", message: waveBefore }), 1);
|
|
@@ -1979,7 +2019,7 @@ async function prApplyWaves(
|
|
|
1979
2019
|
const outputs = applied.run.componentOutputs[name];
|
|
1980
2020
|
if (outputs) outputsSoFar[name] = outputs;
|
|
1981
2021
|
}
|
|
1982
|
-
const waveAfter = runStageHook(p, "after-apply", wavePlan.order.filter((name) => applied.run.completed.includes(name)), undefined, `wave ${k} counts as failed though its components applied`);
|
|
2022
|
+
const waveAfter = await runStageHook(p, "after-apply", wavePlan.order.filter((name) => applied.run.completed.includes(name)), undefined, `wave ${k} counts as failed though its components applied`);
|
|
1983
2023
|
setWave({ ...entry, status: applied.status === "applied" && !waveAfter ? "applied" : "failed" });
|
|
1984
2024
|
await recordAutoReleasesForRun(applied.run.results, p.env, at.release.runId, resolveAutoReleaseDisabled(p.config, args.noReleaseRecord), at.release.runOrigin, undefined, undefined, prAppliedDigests(p, applied.members));
|
|
1985
2025
|
if (applied.status !== "applied") {
|
|
@@ -2023,6 +2063,7 @@ function writeWaveChangeSet(ctx: CommandContext, wave: number, doc: PrPlanSet["d
|
|
|
2023
2063
|
|
|
2024
2064
|
/**
|
|
2025
2065
|
* chant components pr-post --pr <n> --head <sha> --env <env> --forge <kind> [--member <name>] [--output <dir>] [--result <result>] (#4295)
|
|
2066
|
+
* chant components pr-post --open --env <env> --forge gitlab [--branch <branch>] [--member <name>] [--output <dir>] (#4328)
|
|
2026
2067
|
*
|
|
2027
2068
|
* Post the plan note and the `chant/plan` status from the report a plan job
|
|
2028
2069
|
* wrote with `pr-plan --no-status`, in a job that runs none of the change's
|
|
@@ -2033,6 +2074,7 @@ function writeWaveChangeSet(ctx: CommandContext, wave: number, doc: PrPlanSet["d
|
|
|
2033
2074
|
*/
|
|
2034
2075
|
export async function runComponentsPrPost(ctx: CommandContext): Promise<number> {
|
|
2035
2076
|
const { args } = ctx;
|
|
2077
|
+
if (args.open) return runComponentsPrPostOpen(ctx);
|
|
2036
2078
|
if (args.pr === undefined) return fail("pr-post needs the pull or merge request: --pr <n>");
|
|
2037
2079
|
if (!args.head || !/^[0-9a-f]{40}$/.test(args.head)) return fail("pr-post needs the full commit the plan job checked out: --head <sha>");
|
|
2038
2080
|
if (!args.env) return fail("pr-post needs the environment the plan was for: --env <env>");
|
|
@@ -2062,3 +2104,63 @@ export async function runComponentsPrPost(ctx: CommandContext): Promise<number>
|
|
|
2062
2104
|
console.error(formatInfo(`pr-post: ${prStatusContext("plan", member)} ${posted.state}: ${posted.description}${posted.noted ? "; note posted" : ""}`));
|
|
2063
2105
|
return 0;
|
|
2064
2106
|
}
|
|
2107
|
+
|
|
2108
|
+
/**
|
|
2109
|
+
* `pr-post --open` (#4328): in a pipeline of the target branch on GitLab,
|
|
2110
|
+
* post the plan note and status of every open merge request into it whose
|
|
2111
|
+
* plan job settled, reading each report from the plan job's artifacts
|
|
2112
|
+
* (`postOpenPlanReports`, ../../pr-post.ts). The branch is `--branch`, else
|
|
2113
|
+
* the pipeline's own (`CI_COMMIT_BRANCH`). The plan job is `plan`, or
|
|
2114
|
+
* `<member>-plan` with `--member`, as the gitlab lexicon names it, and the
|
|
2115
|
+
* artifact path is `--output` from the repository root. It exits 0 once it
|
|
2116
|
+
* has posted, as `pr-post` does.
|
|
2117
|
+
*/
|
|
2118
|
+
async function runComponentsPrPostOpen(ctx: CommandContext): Promise<number> {
|
|
2119
|
+
const { args } = ctx;
|
|
2120
|
+
if (args.pr !== undefined || args.head) return fail("pr-post --open finds each merge request and its head itself, so it takes no --pr or --head");
|
|
2121
|
+
if (!args.env) return fail("pr-post needs the environment the plan was for: --env <env>");
|
|
2122
|
+
if (args.forge !== "gitlab") return fail("pr-post --open is for a GitLab pipeline of the target branch: --forge gitlab");
|
|
2123
|
+
if (args.members && args.members.length > 1) return fail(`pr-post takes one --member, not ${args.members.join(", ")}`);
|
|
2124
|
+
const branch = args.branch ?? process.env.CI_COMMIT_BRANCH;
|
|
2125
|
+
if (!branch) return fail("pr-post --open posts for the merge requests into a branch: run it in a branch pipeline, or pass --branch <branch>");
|
|
2126
|
+
let forge: PrForge;
|
|
2127
|
+
try {
|
|
2128
|
+
forge = forgeFromEnv("gitlab");
|
|
2129
|
+
} catch (err) {
|
|
2130
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
2131
|
+
}
|
|
2132
|
+
const top = spawnSync("git", ["rev-parse", "--show-toplevel"], { encoding: "utf-8" });
|
|
2133
|
+
if (top.status !== 0) return fail("pr-post --open reads the plan report's path from the repository root, and this directory is not in a git repository");
|
|
2134
|
+
const member = args.members?.[0];
|
|
2135
|
+
const artifactDir = relative(realpathSync(top.stdout.trim()), resolve(args.output ?? PR_REPORT_DIR)).split(sep).join("/");
|
|
2136
|
+
const { postOpenPlanReports } = await import("../../pr-post");
|
|
2137
|
+
const { gitlabPlanJobName } = await import("../../components/pr-pipeline");
|
|
2138
|
+
let done: Awaited<ReturnType<typeof postOpenPlanReports>>;
|
|
2139
|
+
try {
|
|
2140
|
+
done = await postOpenPlanReports({
|
|
2141
|
+
forge,
|
|
2142
|
+
branch,
|
|
2143
|
+
job: gitlabPlanJobName(member),
|
|
2144
|
+
artifactDir,
|
|
2145
|
+
env: args.env,
|
|
2146
|
+
...(member ? { member } : {}),
|
|
2147
|
+
// #4289: the Ops at the commit this pipeline checked out, the target branch's.
|
|
2148
|
+
overdue: () => overdueOps(forge, member),
|
|
2149
|
+
});
|
|
2150
|
+
} catch (err) {
|
|
2151
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
2152
|
+
}
|
|
2153
|
+
for (const message of done.warnings) console.error(formatWarning({ message }));
|
|
2154
|
+
for (const p of done.posts) {
|
|
2155
|
+
if (p.skipped) {
|
|
2156
|
+
console.error(formatInfo(`pr-post: !${p.pr}: ${p.skipped}`));
|
|
2157
|
+
continue;
|
|
2158
|
+
}
|
|
2159
|
+
const posted = p.posted!;
|
|
2160
|
+
for (const message of posted.warnings) console.error(formatWarning({ message: `!${p.pr}: ${message}` }));
|
|
2161
|
+
if (posted.refused) console.error(formatWarning({ message: `!${p.pr}: the plan report was not used: ${posted.refused}` }));
|
|
2162
|
+
console.error(formatInfo(`pr-post: !${p.pr} ${prStatusContext("plan", member)} ${posted.state}: ${posted.description}${posted.noted ? "; note posted" : ""}`));
|
|
2163
|
+
}
|
|
2164
|
+
if (done.posts.length === 0) console.error(formatInfo(`pr-post: no open merge request into ${branch} has a ${gitlabPlanJobName(member)} job`));
|
|
2165
|
+
return 0;
|
|
2166
|
+
}
|
|
@@ -18,11 +18,23 @@ import { findWorkspaceRoot } from "../../project-root";
|
|
|
18
18
|
|
|
19
19
|
const USAGE = 'chant query "<sql>" [dir] [--member <name>] [--json]';
|
|
20
20
|
|
|
21
|
-
/**
|
|
22
|
-
|
|
21
|
+
/**
|
|
22
|
+
* The ledgers `chant query` and `chant ledger` read from `cwd`: every
|
|
23
|
+
* member's in a workspace, else the project's own. With `at`, a commit of
|
|
24
|
+
* `chant/lifecycle` (`chant ledger --at`, #4363), each is read as that commit
|
|
25
|
+
* held it rather than at the branch tip.
|
|
26
|
+
*/
|
|
27
|
+
export async function queryLedgers(cwd: string, members?: readonly string[], at?: string): Promise<QueryLedger[]> {
|
|
23
28
|
const { gitLedgerReadPort } = await import("../../lifecycle/git");
|
|
24
29
|
const found = findWorkspaceRoot(cwd);
|
|
25
|
-
|
|
30
|
+
const atPort = at === undefined ? undefined : await (async () => {
|
|
31
|
+
const { resolveLedgerRevision, revisionLedgerReadPort } = await import("../../lifecycle/ledger-read");
|
|
32
|
+
const { memberLedgerPrefix } = await import("../../lifecycle/member-ledger");
|
|
33
|
+
const repo = found?.dir ?? cwd;
|
|
34
|
+
const commit = resolveLedgerRevision(repo, at);
|
|
35
|
+
return (member: string | null) => revisionLedgerReadPort(repo, commit, member === null ? "" : memberLedgerPrefix([member]));
|
|
36
|
+
})();
|
|
37
|
+
if (!found) return [{ member: null, port: atPort ? atPort(null) : gitLedgerReadPort({ cwd }) }];
|
|
26
38
|
// Workspace code loads only when there is a workspace, so a level-0 project never pays for it.
|
|
27
39
|
const { readDeclaration, WorkspaceReadError } = await import("../../workspace/declaration");
|
|
28
40
|
const { workingTree } = await import("../../workspace/tree");
|
|
@@ -41,7 +53,7 @@ export async function queryLedgers(cwd: string, members?: readonly string[]): Pr
|
|
|
41
53
|
}
|
|
42
54
|
return declaration.members
|
|
43
55
|
.filter((m) => !wanted || wanted.has(m.name))
|
|
44
|
-
.map((m) => ({ member: m.name, port: gitLedgerReadPort({ cwd: found.dir, member: m.dir === "." ? "." : m.name }) }));
|
|
56
|
+
.map((m) => ({ member: m.name, port: atPort ? atPort(m.dir === "." ? null : m.name) : gitLedgerReadPort({ cwd: found.dir, member: m.dir === "." ? "." : m.name }) }));
|
|
45
57
|
}
|
|
46
58
|
|
|
47
59
|
export async function runQueryCommand(ctx: CommandContext): Promise<number> {
|
|
@@ -174,9 +174,12 @@ export async function runReleaseCut(ctx: CommandContext): Promise<number> {
|
|
|
174
174
|
const { scopeSource } = await import("../../workspace/write-scope");
|
|
175
175
|
const { releaseRuleFrom } = await import("../../workspace/identity");
|
|
176
176
|
const source = scopeSource(cwd);
|
|
177
|
-
|
|
177
|
+
const greenDecl = source.declaration?.ci?.green ?? null;
|
|
178
|
+
const primary = ws.resolveTrunk(top, greenDecl?.branch ?? null);
|
|
179
|
+
trunk = primary;
|
|
178
180
|
try {
|
|
179
|
-
|
|
181
|
+
// #4325: a commit of a branch ci.green also judges (one ci.branches routes members to) is cut like trunk's.
|
|
182
|
+
trunk = ws.checkOnGreenBranches(top, commit, primary, (greenDecl?.branches ?? []).slice(1));
|
|
180
183
|
} catch (err) {
|
|
181
184
|
// #4168 4.3: a commit of a pushed compose branch is cut too, and the cut records what it carries.
|
|
182
185
|
if (!(err instanceof ws.WorkstationCheckError) || err.code !== "release-commit-not-on-trunk") throw err;
|
|
@@ -552,7 +555,7 @@ export async function runReleaseVerify(ctx: CommandContext): Promise<number> {
|
|
|
552
555
|
*/
|
|
553
556
|
export async function runReleaseCandidates(ctx: CommandContext): Promise<number> {
|
|
554
557
|
const { releaseCandidatesDocument } = await import("../../workspace/release-candidates");
|
|
555
|
-
const doc = await releaseCandidatesDocument({ cwd: resolve("."), ...(ctx.args.env ? { env: ctx.args.env } : {}) });
|
|
558
|
+
const doc = await releaseCandidatesDocument({ cwd: resolve("."), ...(ctx.args.env ? { env: ctx.args.env } : {}), ...(ctx.args.branch ? { branch: ctx.args.branch } : {}) });
|
|
556
559
|
if (ctx.args.json) {
|
|
557
560
|
console.log(JSON.stringify(doc, null, 2));
|
|
558
561
|
return "error" in doc ? 1 : 0;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { describe, test, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
import type { ParsedArgs } from "../registry";
|
|
3
|
+
import { DECLARABLE_MARKER, type Declarable } from "../../declarable";
|
|
4
|
+
import type { LexiconPlugin } from "../../lexicon";
|
|
5
|
+
import { createMockPlugin } from "../../../../test-utils/src/mock-plugin";
|
|
6
|
+
|
|
7
|
+
// #4365 / #4368: search answers over the graph `chant graph` draws. That is
|
|
8
|
+
// discovery plus the build-root contributions (a terraform root, a kustomize
|
|
9
|
+
// root) plus the lexicons' `graphEdges`, on the declared path AND on the
|
|
10
|
+
// `--live`/`--at` canvas, and a contributor that throws fails the search
|
|
11
|
+
// instead of leaving it to answer `(no matches)` over a graph with a hole in it.
|
|
12
|
+
|
|
13
|
+
const discoverMock = vi.fn();
|
|
14
|
+
vi.mock("../../discovery/index", () => ({
|
|
15
|
+
discover: (...a: unknown[]) => discoverMock(...a),
|
|
16
|
+
}));
|
|
17
|
+
const loadPluginsMock = vi.fn();
|
|
18
|
+
const resolveLexMock = vi.fn();
|
|
19
|
+
vi.mock("../plugins", async () => {
|
|
20
|
+
const actual = await vi.importActual<typeof import("../plugins")>("../plugins");
|
|
21
|
+
return {
|
|
22
|
+
...actual,
|
|
23
|
+
loadPlugins: (...a: unknown[]) => loadPluginsMock(...a),
|
|
24
|
+
resolveProjectLexicons: (...a: unknown[]) => resolveLexMock(...a),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
const replaySnapshotsMock = vi.fn();
|
|
28
|
+
vi.mock("../../lifecycle/replay", () => ({
|
|
29
|
+
replaySnapshots: (...a: unknown[]) => replaySnapshotsMock(...a),
|
|
30
|
+
hasSnapshot: () => Promise.resolve(false),
|
|
31
|
+
}));
|
|
32
|
+
const loadChantConfigMock = vi.fn();
|
|
33
|
+
vi.mock("../../config", async () => {
|
|
34
|
+
const actual = await vi.importActual<typeof import("../../config")>("../../config");
|
|
35
|
+
return {
|
|
36
|
+
...actual,
|
|
37
|
+
loadChantConfig: (...a: unknown[]) => loadChantConfigMock(...a),
|
|
38
|
+
loadChantConfigUpward: (...a: unknown[]) => loadChantConfigMock(...a),
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
const buildResultMock = vi.fn();
|
|
42
|
+
vi.mock("../../build", async () => {
|
|
43
|
+
const actual = await vi.importActual<typeof import("../../build")>("../../build");
|
|
44
|
+
return { ...actual, build: (...a: unknown[]) => Promise.resolve(buildResultMock(...a)) };
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const { runSearch } = await import("./search");
|
|
48
|
+
|
|
49
|
+
function decl<T extends object>(base: T): Declarable & T {
|
|
50
|
+
return { [DECLARABLE_MARKER]: true, ...base } as Declarable & T;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** A lexicon whose only entities come from a build root, and whose only edge comes from `graphEdges`. */
|
|
54
|
+
function rootLexicon(overrides: Partial<LexiconPlugin> = {}): LexiconPlugin {
|
|
55
|
+
return {
|
|
56
|
+
...createMockPlugin({ name: "tf" }),
|
|
57
|
+
buildRoots: async () => ({
|
|
58
|
+
entities: new Map<string, Declarable>([
|
|
59
|
+
["net/aws_vpc.main", decl({ lexicon: "tf", entityType: "Tf::Resource", props: { address: "aws_vpc.main" } })],
|
|
60
|
+
["net/aws_subnet.a", decl({ lexicon: "tf", entityType: "Tf::Resource", props: { address: "aws_subnet.a" } })],
|
|
61
|
+
]),
|
|
62
|
+
warnings: [],
|
|
63
|
+
}),
|
|
64
|
+
graphEdges: () => ({ references: [{ from: "net/aws_subnet.a", to: "net/aws_vpc.main", kind: "ref", viaAttr: "vpc_id" }] }),
|
|
65
|
+
...overrides,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function makeArgs(overrides: Partial<ParsedArgs> = {}): ParsedArgs {
|
|
70
|
+
return {
|
|
71
|
+
command: "search", path: "attr:address=aws_subnet ->attr:address=aws_vpc",
|
|
72
|
+
format: "", fix: false, watch: false, verbose: false, help: false, live: false, json: true,
|
|
73
|
+
...overrides,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
describe("search over build-root entities and lexicon edges (#4365, #4368)", () => {
|
|
78
|
+
let out: string[];
|
|
79
|
+
let err: string[];
|
|
80
|
+
|
|
81
|
+
beforeEach(() => {
|
|
82
|
+
out = [];
|
|
83
|
+
err = [];
|
|
84
|
+
vi.spyOn(console, "log").mockImplementation((s: string) => { out.push(s); });
|
|
85
|
+
vi.spyOn(console, "error").mockImplementation((s: string) => { err.push(s); });
|
|
86
|
+
discoverMock.mockReset();
|
|
87
|
+
// A fresh map per call: the merge writes into it.
|
|
88
|
+
discoverMock.mockImplementation(async () => ({ entities: new Map(), errors: [], sourceFiles: [] }));
|
|
89
|
+
buildResultMock.mockReset();
|
|
90
|
+
buildResultMock.mockReturnValue({ errors: [], entities: new Map(), outputs: new Map(), warnings: [] });
|
|
91
|
+
loadChantConfigMock.mockReset();
|
|
92
|
+
loadChantConfigMock.mockResolvedValue({ config: {} });
|
|
93
|
+
resolveLexMock.mockReset();
|
|
94
|
+
resolveLexMock.mockResolvedValue(["tf"]);
|
|
95
|
+
replaySnapshotsMock.mockReset();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("declared: an edge term follows a lexicon edge between two build-root entities", async () => {
|
|
99
|
+
loadPluginsMock.mockResolvedValue([rootLexicon()]);
|
|
100
|
+
const exit = await runSearch({ args: makeArgs(), plugins: [], serializers: [] });
|
|
101
|
+
expect(exit).toBe(0);
|
|
102
|
+
const json = JSON.parse(out.join("\n"));
|
|
103
|
+
expect(json.matches.map((m: { id: string }) => m.id)).toEqual(["net/aws_subnet.a"]);
|
|
104
|
+
expect(json.matches[0].paths[0].hops).toEqual([{ from: "net/aws_subnet.a", to: "net/aws_vpc.main", fromAttr: "vpc_id" }]);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test("--at: the snapshot overlays onto a canvas that carries the build roots and their lexicon edges", async () => {
|
|
108
|
+
loadPluginsMock.mockResolvedValue([rootLexicon({ describeResources: async () => ({}) })]);
|
|
109
|
+
replaySnapshotsMock.mockResolvedValue({
|
|
110
|
+
observations: [{
|
|
111
|
+
lexicon: "tf",
|
|
112
|
+
resources: {
|
|
113
|
+
"net/aws_vpc.main": { type: "Tf::Resource", physicalId: "vpc-1", status: "OK" },
|
|
114
|
+
"net/aws_subnet.a": { type: "Tf::Resource", physicalId: "subnet-1", status: "OK" },
|
|
115
|
+
},
|
|
116
|
+
}],
|
|
117
|
+
commit: "a1b2c3d4e5f6", timestamp: "2026-10-01T00:00:00.000Z", depth: "identity",
|
|
118
|
+
});
|
|
119
|
+
const exit = await runSearch({ args: makeArgs({ at: "latest", env: "dev" }), plugins: [], serializers: [] });
|
|
120
|
+
expect(exit).toBe(0);
|
|
121
|
+
const json = JSON.parse(out.join("\n"));
|
|
122
|
+
expect(json.source.kind).toBe("snapshot");
|
|
123
|
+
expect(json.matches.map((m: { id: string; physicalId?: string }) => [m.id, m.physicalId])).toEqual([["net/aws_subnet.a", "subnet-1"]]);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("a contributor that throws fails the declared search with its error", async () => {
|
|
127
|
+
loadPluginsMock.mockResolvedValue([rootLexicon({ buildRoots: async () => { throw new Error("roots.net: main.tf does not parse"); } })]);
|
|
128
|
+
const exit = await runSearch({ args: makeArgs({ json: false }), plugins: [], serializers: [] });
|
|
129
|
+
expect(exit).toBe(1);
|
|
130
|
+
expect(out.join("\n")).not.toContain("(no matches)");
|
|
131
|
+
expect(err.join("\n")).toContain("roots.net: main.tf does not parse");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("a contributor that throws fails the --at search too", async () => {
|
|
135
|
+
loadPluginsMock.mockResolvedValue([rootLexicon({
|
|
136
|
+
describeResources: async () => ({}),
|
|
137
|
+
buildRoots: async () => { throw new Error("roots.net: main.tf does not parse"); },
|
|
138
|
+
})]);
|
|
139
|
+
replaySnapshotsMock.mockResolvedValue({ observations: [], commit: "a1b2c3d4e5f6", timestamp: "2026-10-01T00:00:00.000Z", depth: "identity" });
|
|
140
|
+
const exit = await runSearch({ args: makeArgs({ json: false, at: "latest", env: "dev" }), plugins: [], serializers: [] });
|
|
141
|
+
expect(exit).toBe(1);
|
|
142
|
+
expect(err.join("\n")).toContain("roots.net: main.tf does not parse");
|
|
143
|
+
});
|
|
144
|
+
});
|