@intentius/chant 0.124.27 → 0.124.29
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/README.md +1 -1
- package/dist/__golden__/wave-loop/fan-out-gated.json +8 -0
- package/dist/__golden__/wave-loop/fan-out-no-members.json +4 -0
- package/dist/__golden__/wave-loop/fan-out-only.json +6 -0
- package/dist/__golden__/wave-loop/op-by-apply-hold.json +2 -0
- package/dist/__golden__/wave-loop/op-cost-member.json +3 -0
- package/dist/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
- package/dist/__golden__/wave-loop/op-held-on.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-held.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
- package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
- package/dist/__golden__/wave-loop/op-hooks-share.json +3 -0
- package/dist/__golden__/wave-loop/op-per-run.json +7 -0
- package/dist/__golden__/wave-loop/op-pr-review.json +7 -0
- package/dist/__golden__/wave-loop/op-sealed.json +3 -0
- package/dist/__golden__/wave-loop/op-spend.json +3 -0
- package/dist/__golden__/wave-loop/op-wave-commands.json +7 -0
- package/dist/__golden__/wave-loop/op-wide-waiting.json +4 -0
- package/dist/build-params.d.ts +34 -1
- package/dist/build-params.d.ts.map +1 -1
- package/dist/build-params.js +31 -1
- package/dist/change-set-graph.d.ts +63 -0
- package/dist/change-set-graph.d.ts.map +1 -0
- package/dist/change-set-graph.js +130 -0
- package/dist/change-set.d.ts +62 -3
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +36 -4
- package/dist/chant-version.d.ts +9 -0
- package/dist/chant-version.d.ts.map +1 -0
- package/dist/chant-version.js +16 -0
- package/dist/cli/build-params-cli.d.ts +7 -1
- package/dist/cli/build-params-cli.d.ts.map +1 -1
- package/dist/cli/build-params-cli.js +17 -8
- package/dist/cli/commands/build.d.ts +8 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +15 -11
- package/dist/cli/commands/check-lexicon-docs.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-docs.js +30 -2
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.js +13 -2
- package/dist/cli/commands/init-lexicon/templates/docs.d.ts +4 -1
- package/dist/cli/commands/init-lexicon/templates/docs.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon/templates/docs.js +6 -6
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.js +17 -8
- package/dist/cli/handlers/approve.d.ts.map +1 -1
- package/dist/cli/handlers/approve.js +64 -4
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +43 -4
- package/dist/cli/handlers/change-set.d.ts +10 -0
- package/dist/cli/handlers/change-set.d.ts.map +1 -1
- package/dist/cli/handlers/change-set.js +51 -1
- package/dist/cli/handlers/fan-out.d.ts +10 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +54 -6
- package/dist/cli/handlers/lifecycle-gc.d.ts +19 -0
- package/dist/cli/handlers/lifecycle-gc.d.ts.map +1 -0
- package/dist/cli/handlers/lifecycle-gc.js +143 -0
- package/dist/cli/handlers/pr.d.ts +16 -2
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +269 -37
- package/dist/cli/handlers/promote.d.ts +7 -0
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +440 -28
- package/dist/cli/handlers/release.d.ts +91 -0
- package/dist/cli/handlers/release.d.ts.map +1 -0
- package/dist/cli/handlers/release.js +589 -0
- package/dist/cli/handlers/run.d.ts +38 -2
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/run.js +234 -16
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +143 -17
- package/dist/cli/mcp/workspace-tools.js +1 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +73 -5
- package/dist/cli/registry.d.ts +43 -5
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/run-events.d.ts +30 -0
- package/dist/cli/run-events.d.ts.map +1 -0
- package/dist/cli/run-events.js +49 -0
- package/dist/cli/version.d.ts +3 -5
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +3 -13
- package/dist/codegen/docs-in-site.d.ts +71 -0
- package/dist/codegen/docs-in-site.d.ts.map +1 -0
- package/dist/codegen/docs-in-site.js +177 -0
- package/dist/codegen/docs-types.d.ts +14 -1
- package/dist/codegen/docs-types.d.ts.map +1 -1
- package/dist/codegen/docs.d.ts +18 -1
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/docs.js +40 -7
- package/dist/codegen/rehype-base-url.mjs +15 -9
- package/dist/components/auto-release.d.ts +6 -1
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/auto-release.js +3 -0
- package/dist/components/capability.d.ts +9 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +6 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +10 -9
- package/dist/components/driver.d.ts +50 -9
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +116 -54
- package/dist/components/fan-out-inputs.d.ts +69 -0
- package/dist/components/fan-out-inputs.d.ts.map +1 -0
- package/dist/components/fan-out-inputs.js +169 -0
- package/dist/components/fan-out-record.d.ts +13 -0
- package/dist/components/fan-out-record.d.ts.map +1 -1
- package/dist/components/fan-out-record.js +16 -0
- package/dist/components/fan-out-run.d.ts +7 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +85 -26
- package/dist/components/fan-out.d.ts +4 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/pr-pipeline.d.ts +25 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +22 -4
- package/dist/components/pr-run.d.ts +11 -0
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +20 -1
- package/dist/components/promote-order.d.ts +38 -0
- package/dist/components/promote-order.d.ts.map +1 -0
- package/dist/components/promote-order.js +62 -0
- package/dist/components/promote.d.ts +38 -2
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +77 -2
- package/dist/components/release-compile.d.ts +142 -0
- package/dist/components/release-compile.d.ts.map +1 -0
- package/dist/components/release-compile.js +382 -0
- package/dist/components/release-gate.d.ts +135 -0
- package/dist/components/release-gate.d.ts.map +1 -0
- package/dist/components/release-gate.js +288 -0
- package/dist/components/release-promote.d.ts +96 -0
- package/dist/components/release-promote.d.ts.map +1 -0
- package/dist/components/release-promote.js +204 -0
- package/dist/components/run-progress.d.ts +7 -0
- package/dist/components/run-progress.d.ts.map +1 -1
- package/dist/components/wave-plan.d.ts +8 -1
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +11 -3
- package/dist/config.d.ts +45 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -0
- package/dist/flag-params.d.ts +54 -0
- package/dist/flag-params.d.ts.map +1 -0
- package/dist/flag-params.js +130 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.d.ts +120 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.d.ts.map +1 -0
- package/dist/lifecycle/__fixtures__/publish-fakes.js +304 -0
- package/dist/lifecycle/change-set-store.d.ts +68 -0
- package/dist/lifecycle/change-set-store.d.ts.map +1 -0
- package/dist/lifecycle/change-set-store.js +97 -0
- package/dist/lifecycle/commit-sha.d.ts +13 -0
- package/dist/lifecycle/commit-sha.d.ts.map +1 -0
- package/dist/lifecycle/commit-sha.js +21 -0
- package/dist/lifecycle/delivery-metrics.d.ts +139 -0
- package/dist/lifecycle/delivery-metrics.d.ts.map +1 -0
- package/dist/lifecycle/delivery-metrics.js +145 -0
- package/dist/lifecycle/deploy-outcome.d.ts +81 -0
- package/dist/lifecycle/deploy-outcome.d.ts.map +1 -0
- package/dist/lifecycle/deploy-outcome.js +101 -0
- package/dist/lifecycle/gate-change-set.d.ts +78 -0
- package/dist/lifecycle/gate-change-set.d.ts.map +1 -0
- package/dist/lifecycle/gate-change-set.js +138 -0
- package/dist/lifecycle/gate-ledger.d.ts +51 -4
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.js +18 -0
- package/dist/lifecycle/git.d.ts +30 -1
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/git.js +31 -5
- package/dist/lifecycle/index.d.ts +4 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +4 -0
- package/dist/lifecycle/mixed-environment.d.ts +95 -0
- package/dist/lifecycle/mixed-environment.d.ts.map +1 -0
- package/dist/lifecycle/mixed-environment.js +154 -0
- package/dist/lifecycle/publish-attachments.d.ts +79 -0
- package/dist/lifecycle/publish-attachments.d.ts.map +1 -0
- package/dist/lifecycle/publish-attachments.js +179 -0
- package/dist/lifecycle/publish-credentials.d.ts +37 -0
- package/dist/lifecycle/publish-credentials.d.ts.map +1 -0
- package/dist/lifecycle/publish-credentials.js +69 -0
- package/dist/lifecycle/publish-declaration.d.ts +97 -0
- package/dist/lifecycle/publish-declaration.d.ts.map +1 -0
- package/dist/lifecycle/publish-declaration.js +83 -0
- package/dist/lifecycle/publish-forge.d.ts +53 -0
- package/dist/lifecycle/publish-forge.d.ts.map +1 -0
- package/dist/lifecycle/publish-forge.js +298 -0
- package/dist/lifecycle/publish-npm.d.ts +61 -0
- package/dist/lifecycle/publish-npm.d.ts.map +1 -0
- package/dist/lifecycle/publish-npm.js +242 -0
- package/dist/lifecycle/publish-oci.d.ts +64 -0
- package/dist/lifecycle/publish-oci.d.ts.map +1 -0
- package/dist/lifecycle/publish-oci.js +383 -0
- package/dist/lifecycle/publish-record.d.ts +66 -0
- package/dist/lifecycle/publish-record.d.ts.map +1 -0
- package/dist/lifecycle/publish-record.js +84 -0
- package/dist/lifecycle/publish-targets.d.ts +45 -0
- package/dist/lifecycle/publish-targets.d.ts.map +1 -0
- package/dist/lifecycle/publish-targets.js +85 -0
- package/dist/lifecycle/release-cut.d.ts +154 -0
- package/dist/lifecycle/release-cut.d.ts.map +1 -0
- package/dist/lifecycle/release-cut.js +366 -0
- package/dist/lifecycle/release-join.d.ts +95 -0
- package/dist/lifecycle/release-join.d.ts.map +1 -0
- package/dist/lifecycle/release-join.js +139 -0
- package/dist/lifecycle/release-ledger.d.ts +54 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.js +53 -20
- package/dist/lifecycle/release-publish.d.ts +312 -0
- package/dist/lifecycle/release-publish.d.ts.map +1 -0
- package/dist/lifecycle/release-publish.js +335 -0
- package/dist/lifecycle/release-revocation.d.ts +80 -0
- package/dist/lifecycle/release-revocation.d.ts.map +1 -0
- package/dist/lifecycle/release-revocation.js +123 -0
- package/dist/lifecycle/release-store.d.ts +200 -0
- package/dist/lifecycle/release-store.d.ts.map +1 -0
- package/dist/lifecycle/release-store.js +320 -0
- package/dist/lifecycle/release-verify.d.ts +61 -0
- package/dist/lifecycle/release-verify.d.ts.map +1 -0
- package/dist/lifecycle/release-verify.js +92 -0
- package/dist/lifecycle/release-workstation.d.ts +91 -0
- package/dist/lifecycle/release-workstation.d.ts.map +1 -0
- package/dist/lifecycle/release-workstation.js +180 -0
- package/dist/lifecycle/retention-policy.d.ts +45 -0
- package/dist/lifecycle/retention-policy.d.ts.map +1 -0
- package/dist/lifecycle/retention-policy.js +43 -0
- package/dist/lifecycle/retention.d.ts +185 -0
- package/dist/lifecycle/retention.d.ts.map +1 -0
- package/dist/lifecycle/retention.js +400 -0
- package/dist/lifecycle/run-ledger.d.ts +4 -0
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +2 -0
- package/dist/op/activities/change-coverage.d.ts.map +1 -1
- package/dist/op/activities/change-coverage.js +4 -2
- package/dist/op/activities/source-release.d.ts.map +1 -1
- package/dist/op/activities/source-release.js +7 -3
- package/dist/op/activities/source-rollback.d.ts.map +1 -1
- package/dist/op/activities/source-rollback.js +7 -3
- package/dist/op/gate-name.d.ts +11 -2
- package/dist/op/gate-name.d.ts.map +1 -1
- package/dist/op/gate-name.js +12 -3
- package/dist/op/gate-run-locator.d.ts +22 -0
- package/dist/op/gate-run-locator.d.ts.map +1 -1
- package/dist/op/gate-run-locator.js +31 -0
- package/dist/op/gate.d.ts +27 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/gate.js +57 -3
- package/dist/op/local-executor.d.ts +36 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +158 -52
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +4 -0
- package/dist/op/run-live.d.ts +2 -0
- package/dist/op/run-live.d.ts.map +1 -1
- package/dist/op/run-live.js +1 -1
- package/dist/op/runtime.d.ts +46 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/runtimes/local.js +8 -0
- package/dist/plan-summary.d.ts.map +1 -1
- package/dist/plan-summary.js +8 -2
- package/dist/point-decision.d.ts +2 -0
- package/dist/point-decision.d.ts.map +1 -1
- package/dist/point-decision.js +9 -2
- package/dist/pr-loop.d.ts +7 -0
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +23 -4
- package/dist/pr-report-url.d.ts +82 -0
- package/dist/pr-report-url.d.ts.map +1 -0
- package/dist/pr-report-url.js +174 -0
- package/dist/provenance.d.ts +2 -2
- package/dist/provenance.d.ts.map +1 -1
- package/dist/run-event-store.d.ts +104 -0
- package/dist/run-event-store.d.ts.map +1 -0
- package/dist/run-event-store.js +251 -0
- package/dist/run-event-stream.d.ts +133 -0
- package/dist/run-event-stream.d.ts.map +1 -0
- package/dist/run-event-stream.js +242 -0
- package/dist/run-event.d.ts +285 -0
- package/dist/run-event.d.ts.map +1 -0
- package/dist/run-event.js +209 -0
- package/dist/wave-runtime.mjs +262 -226
- package/dist/workspace/__fixtures__/flag-workspace.d.ts +31 -0
- package/dist/workspace/__fixtures__/flag-workspace.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/flag-workspace.js +114 -0
- package/dist/workspace/__fixtures__/run-event-check.d.ts +19 -0
- package/dist/workspace/__fixtures__/run-event-check.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/run-event-check.js +59 -0
- package/dist/workspace/change-set-show.d.ts +56 -0
- package/dist/workspace/change-set-show.d.ts.map +1 -0
- package/dist/workspace/change-set-show.js +54 -0
- package/dist/workspace/change-set-show.schema.json +102 -0
- package/dist/workspace/change-set.schema.json +32 -1
- package/dist/workspace/changes-cli.d.ts.map +1 -1
- package/dist/workspace/changes-cli.js +10 -1
- package/dist/workspace/changes.d.ts +37 -0
- package/dist/workspace/changes.d.ts.map +1 -1
- package/dist/workspace/changes.js +49 -2
- package/dist/workspace/changes.schema.json +135 -0
- package/dist/workspace/check.schema.json +4 -2
- package/dist/workspace/checks/records.d.ts +9 -1
- package/dist/workspace/checks/records.d.ts.map +1 -1
- package/dist/workspace/checks/records.js +35 -1
- package/dist/workspace/checks.d.ts +1 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/checks.js +2 -1
- package/dist/workspace/ci-green-cli.d.ts +19 -4
- package/dist/workspace/ci-green-cli.d.ts.map +1 -1
- package/dist/workspace/ci-green-cli.js +75 -12
- package/dist/workspace/ci-green-forge.d.ts +20 -3
- package/dist/workspace/ci-green-forge.d.ts.map +1 -1
- package/dist/workspace/ci-green-forge.js +6 -4
- package/dist/workspace/ci-green-workflow.d.ts +11 -0
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +6 -0
- package/dist/workspace/ci-green.d.ts +281 -13
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +456 -38
- package/dist/workspace/ci-last-green.schema.json +32 -2
- package/dist/workspace/ci-list.schema.json +525 -0
- package/dist/workspace/commit-links.d.ts +85 -0
- package/dist/workspace/commit-links.d.ts.map +1 -0
- package/dist/workspace/commit-links.js +163 -0
- package/dist/workspace/declaration.d.ts +35 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +27 -1
- package/dist/workspace/declaration.schema.json +76 -0
- package/dist/workspace/declared-kinds.d.ts +16 -0
- package/dist/workspace/declared-kinds.d.ts.map +1 -1
- package/dist/workspace/declared-kinds.js +25 -0
- package/dist/workspace/delivery-metrics.d.ts +91 -0
- package/dist/workspace/delivery-metrics.d.ts.map +1 -0
- package/dist/workspace/delivery-metrics.js +217 -0
- package/dist/workspace/delivery-metrics.schema.json +519 -0
- package/dist/workspace/flags-read.d.ts +37 -0
- package/dist/workspace/flags-read.d.ts.map +1 -0
- package/dist/workspace/flags-read.js +103 -0
- package/dist/workspace/flags.d.ts +100 -0
- package/dist/workspace/flags.d.ts.map +1 -0
- package/dist/workspace/flags.js +98 -0
- package/dist/workspace/graph-cli.js +1 -1
- package/dist/workspace/identity-gate-rule.d.ts +37 -0
- package/dist/workspace/identity-gate-rule.d.ts.map +1 -1
- package/dist/workspace/identity-gate-rule.js +72 -7
- package/dist/workspace/identity.d.ts +12 -0
- package/dist/workspace/identity.d.ts.map +1 -1
- package/dist/workspace/identity.js +13 -1
- package/dist/workspace/intent-cli.d.ts +11 -2
- package/dist/workspace/intent-cli.d.ts.map +1 -1
- package/dist/workspace/intent-cli.js +54 -5
- package/dist/workspace/intent-trace.d.ts +219 -0
- package/dist/workspace/intent-trace.d.ts.map +1 -0
- package/dist/workspace/intent-trace.js +314 -0
- package/dist/workspace/intent.d.ts +36 -7
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +192 -22
- package/dist/workspace/intent.schema.json +702 -6
- package/dist/workspace/ls.d.ts +4 -0
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/ls.js +2 -0
- package/dist/workspace/ls.schema.json +3 -1
- package/dist/workspace/member-pipeline.d.ts +6 -0
- package/dist/workspace/member-pipeline.d.ts.map +1 -1
- package/dist/workspace/member-pipeline.js +6 -0
- package/dist/workspace/overlap.d.ts +146 -0
- package/dist/workspace/overlap.d.ts.map +1 -0
- package/dist/workspace/overlap.js +276 -0
- package/dist/workspace/promotion-order.d.ts +41 -0
- package/dist/workspace/promotion-order.d.ts.map +1 -0
- package/dist/workspace/promotion-order.js +95 -0
- package/dist/workspace/reason-codes.d.ts +4 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +7 -1
- package/dist/workspace/records.d.ts +15 -2
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/records.js +32 -0
- package/dist/workspace/records.schema.json +21 -2
- package/dist/workspace/reference-kinds/flag/flag.kind.mjs +32 -0
- package/dist/workspace/reference-kinds/flag/flag.schema.json +53 -0
- package/dist/workspace/releases.d.ts +81 -0
- package/dist/workspace/releases.d.ts.map +1 -0
- package/dist/workspace/releases.js +103 -0
- package/dist/workspace/releases.schema.json +513 -0
- package/dist/workspace/run-event.schema.json +295 -0
- package/dist/workspace/status-gates.d.ts +34 -1
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status-gates.js +31 -2
- package/dist/workspace/status-stewards.d.ts +4 -0
- package/dist/workspace/status-stewards.d.ts.map +1 -1
- package/dist/workspace/status-stewards.js +2 -0
- package/dist/workspace/status.d.ts +117 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +218 -4
- package/dist/workspace/status.schema.json +268 -2
- package/dist/workspace/trust/ci-tag-statement.d.ts +102 -0
- package/dist/workspace/trust/ci-tag-statement.d.ts.map +1 -0
- package/dist/workspace/trust/ci-tag-statement.js +123 -0
- package/dist/workspace/trust/op-run-statement.d.ts +91 -0
- package/dist/workspace/trust/op-run-statement.d.ts.map +1 -0
- package/dist/workspace/trust/op-run-statement.js +143 -0
- package/dist/workspace/trust/rotation.d.ts +18 -2
- package/dist/workspace/trust/rotation.d.ts.map +1 -1
- package/dist/workspace/trust/rotation.js +65 -16
- package/dist/workspace/trust/seal.d.ts +11 -0
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/seal.js +9 -0
- package/dist/workspace/trust/ssh-commit.d.ts.map +1 -1
- package/dist/workspace/trust/ssh-commit.js +10 -10
- package/dist/workspace/wip.d.ts.map +1 -1
- package/dist/workspace/wip.js +11 -3
- package/package.json +1 -1
- package/src/__golden__/wave-loop/fan-out-gated.json +8 -0
- package/src/__golden__/wave-loop/fan-out-no-members.json +4 -0
- package/src/__golden__/wave-loop/fan-out-only.json +6 -0
- package/src/__golden__/wave-loop/op-by-apply-hold.json +2 -0
- package/src/__golden__/wave-loop/op-cost-member.json +3 -0
- package/src/__golden__/wave-loop/op-held-on-before-apply.json +1 -0
- package/src/__golden__/wave-loop/op-held-on.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-held.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +2 -0
- package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +3 -0
- package/src/__golden__/wave-loop/op-hooks-share.json +3 -0
- package/src/__golden__/wave-loop/op-per-run.json +7 -0
- package/src/__golden__/wave-loop/op-pr-review.json +7 -0
- package/src/__golden__/wave-loop/op-sealed.json +3 -0
- package/src/__golden__/wave-loop/op-spend.json +3 -0
- package/src/__golden__/wave-loop/op-wave-commands.json +7 -0
- package/src/__golden__/wave-loop/op-wide-waiting.json +4 -0
- package/src/build-params.test.ts +46 -0
- package/src/build-params.ts +55 -1
- package/src/change-set-graph.test.ts +72 -0
- package/src/change-set-graph.ts +141 -0
- package/src/change-set.ts +87 -6
- package/src/chant-version.ts +16 -0
- package/src/cli/build-params-cli.ts +22 -9
- package/src/cli/commands/build.ts +25 -11
- package/src/cli/commands/check-lexicon-docs.test.ts +51 -0
- package/src/cli/commands/check-lexicon-docs.ts +39 -2
- package/src/cli/commands/check-lexicon.ts +14 -2
- package/src/cli/commands/init-lexicon/templates/docs.ts +7 -6
- package/src/cli/commands/init-lexicon.test.ts +25 -0
- package/src/cli/commands/init-lexicon.ts +18 -8
- package/src/cli/handlers/approve-release.test.ts +84 -0
- package/src/cli/handlers/approve-revoked.test.ts +155 -0
- package/src/cli/handlers/approve.ts +65 -2
- package/src/cli/handlers/build.test.ts +67 -0
- package/src/cli/handlers/build.ts +46 -4
- package/src/cli/handlers/change-set.ts +49 -1
- package/src/cli/handlers/fan-out.test.ts +228 -1
- package/src/cli/handlers/fan-out.ts +53 -6
- package/src/cli/handlers/intent-trace.e2e.test.ts +201 -0
- package/src/cli/handlers/lifecycle-gc.test.ts +126 -0
- package/src/cli/handlers/lifecycle-gc.ts +146 -0
- package/src/cli/handlers/operator.test.ts +37 -0
- package/src/cli/handlers/pr.test.ts +341 -0
- package/src/cli/handlers/pr.ts +292 -47
- package/src/cli/handlers/promote.test.ts +669 -7
- package/src/cli/handlers/promote.ts +464 -29
- package/src/cli/handlers/release-implicit.e2e.test.ts +161 -0
- package/src/cli/handlers/release-join.e2e.test.ts +185 -0
- package/src/cli/handlers/release-publish-targets.e2e.test.ts +295 -0
- package/src/cli/handlers/release-verify.e2e.test.ts +117 -0
- package/src/cli/handlers/release-workstation-ci.e2e.test.ts +135 -0
- package/src/cli/handlers/release.e2e.test.ts +199 -0
- package/src/cli/handlers/release.ts +593 -0
- package/src/cli/handlers/run-auto-release.test.ts +80 -0
- package/src/cli/handlers/run-events-cmd.test.ts +92 -0
- package/src/cli/handlers/run-release.test.ts +55 -0
- package/src/cli/handlers/run.test.ts +30 -0
- package/src/cli/handlers/run.ts +243 -18
- package/src/cli/main.test.ts +8 -0
- package/src/cli/main.ts +143 -17
- package/src/cli/mcp/never-over-mcp.test.ts +2 -0
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/cli/parse-args.ts +56 -5
- package/src/cli/registry.ts +43 -5
- package/src/cli/run-events.ts +57 -0
- package/src/cli/version.ts +3 -13
- package/src/codegen/docs-in-site.test.ts +166 -0
- package/src/codegen/docs-in-site.ts +182 -0
- package/src/codegen/docs-site/AgentPrompt.astro +26 -1
- package/src/codegen/docs-types.ts +14 -1
- package/src/codegen/docs.ts +60 -7
- package/src/codegen/rehype-base-url.d.mts +3 -1
- package/src/codegen/rehype-base-url.mjs +15 -9
- package/src/codegen/rehype-base-url.test.ts +34 -0
- package/src/components/auto-release.test.ts +30 -0
- package/src/components/auto-release.ts +9 -1
- package/src/components/capability.ts +9 -0
- package/src/components/cli-support.test.ts +82 -0
- package/src/components/cli-support.ts +16 -9
- package/src/components/driver.test.ts +24 -0
- package/src/components/driver.ts +165 -56
- package/src/components/fan-out-inputs.test.ts +85 -0
- package/src/components/fan-out-inputs.ts +192 -0
- package/src/components/fan-out-record.test.ts +10 -0
- package/src/components/fan-out-record.ts +19 -0
- package/src/components/fan-out-run.ts +104 -35
- package/src/components/fan-out.ts +4 -0
- package/src/components/pr-pipeline.ts +35 -4
- package/src/components/pr-run.ts +30 -1
- package/src/components/promote-order.test.ts +90 -0
- package/src/components/promote-order.ts +75 -0
- package/src/components/promote.test.ts +10 -1
- package/src/components/promote.ts +94 -3
- package/src/components/release-compile.test.ts +147 -0
- package/src/components/release-compile.ts +459 -0
- package/src/components/release-gate.test.ts +215 -0
- package/src/components/release-gate.ts +355 -0
- package/src/components/release-promote.test.ts +159 -0
- package/src/components/release-promote.ts +232 -0
- package/src/components/run-progress.ts +7 -0
- package/src/components/wave-plan.ts +16 -3
- package/src/config.ts +15 -1
- package/src/flag-params.test.ts +144 -0
- package/src/flag-params.ts +134 -0
- package/src/index.ts +2 -0
- package/src/lifecycle/__fixtures__/publish-fakes.ts +351 -0
- package/src/lifecycle/change-set-store.test.ts +217 -0
- package/src/lifecycle/change-set-store.ts +113 -0
- package/src/lifecycle/commit-sha.ts +23 -0
- package/src/lifecycle/delivery-metrics.ts +263 -0
- package/src/lifecycle/deploy-outcome.ts +147 -0
- package/src/lifecycle/gate-change-set.e2e.test.ts +122 -0
- package/src/lifecycle/gate-change-set.ts +164 -0
- package/src/lifecycle/gate-ledger.test.ts +33 -0
- package/src/lifecycle/gate-ledger.ts +68 -3
- package/src/lifecycle/git.ts +61 -8
- package/src/lifecycle/index.ts +4 -0
- package/src/lifecycle/mixed-environment.test.ts +97 -0
- package/src/lifecycle/mixed-environment.ts +204 -0
- package/src/lifecycle/publish-attachments.ts +196 -0
- package/src/lifecycle/publish-credentials.ts +84 -0
- package/src/lifecycle/publish-declaration.ts +95 -0
- package/src/lifecycle/publish-forge.ts +325 -0
- package/src/lifecycle/publish-npm.ts +259 -0
- package/src/lifecycle/publish-oci.ts +396 -0
- package/src/lifecycle/publish-record.ts +113 -0
- package/src/lifecycle/publish-resume.test.ts +168 -0
- package/src/lifecycle/publish-targets.test.ts +494 -0
- package/src/lifecycle/publish-targets.ts +100 -0
- package/src/lifecycle/release-cut-signed.test.ts +180 -0
- package/src/lifecycle/release-cut.test.ts +483 -0
- package/src/lifecycle/release-cut.ts +503 -0
- package/src/lifecycle/release-flag.test.ts +112 -0
- package/src/lifecycle/release-join.test.ts +68 -0
- package/src/lifecycle/release-join.ts +182 -0
- package/src/lifecycle/release-ledger.test.ts +14 -0
- package/src/lifecycle/release-ledger.ts +85 -17
- package/src/lifecycle/release-publish.test.ts +225 -0
- package/src/lifecycle/release-publish.ts +568 -0
- package/src/lifecycle/release-revocation.ts +147 -0
- package/src/lifecycle/release-store.ts +434 -0
- package/src/lifecycle/release-verify.test.ts +110 -0
- package/src/lifecycle/release-verify.ts +120 -0
- package/src/lifecycle/release-workstation.test.ts +204 -0
- package/src/lifecycle/release-workstation.ts +216 -0
- package/src/lifecycle/retention-growth.e2e.test.ts +279 -0
- package/src/lifecycle/retention-policy.ts +63 -0
- package/src/lifecycle/retention.test.ts +363 -0
- package/src/lifecycle/retention.ts +508 -0
- package/src/lifecycle/run-ledger.test.ts +10 -0
- package/src/lifecycle/run-ledger.ts +6 -0
- package/src/op/activities/change-coverage.ts +4 -1
- package/src/op/activities/source-release.ts +8 -3
- package/src/op/activities/source-rollback.ts +8 -4
- package/src/op/commit-run-gate-deploy-join.test.ts +117 -0
- package/src/op/gate-name.ts +13 -3
- package/src/op/gate-release.test.ts +126 -0
- package/src/op/gate-run-locator.test.ts +110 -0
- package/src/op/gate-run-locator.ts +35 -0
- package/src/op/gate.ts +88 -6
- package/src/op/local-executor.ts +207 -52
- package/src/op/op-waves-run.ts +4 -0
- package/src/op/run-events.test.ts +166 -0
- package/src/op/run-live.ts +1 -1
- package/src/op/runtime.ts +39 -0
- package/src/op/runtimes/local.test.ts +16 -0
- package/src/op/runtimes/local.ts +9 -0
- package/src/plan-summary.test.ts +20 -0
- package/src/plan-summary.ts +8 -1
- package/src/point-decision.ts +12 -2
- package/src/pr-loop.ts +25 -4
- package/src/pr-report-url.test.ts +131 -0
- package/src/pr-report-url.ts +209 -0
- package/src/provenance.ts +2 -2
- package/src/run-event-store.test.ts +144 -0
- package/src/run-event-store.ts +273 -0
- package/src/run-event-stream.test.ts +175 -0
- package/src/run-event-stream.ts +309 -0
- package/src/run-event.test.ts +277 -0
- package/src/run-event.ts +471 -0
- package/src/wave-loop-golden.test.ts +9 -0
- package/src/workspace/__fixtures__/flag-workspace.ts +132 -0
- package/src/workspace/__fixtures__/older-records/change-set-984534ea9.json +100 -0
- package/src/workspace/__fixtures__/older-records/older-records.json +326 -0
- package/src/workspace/__fixtures__/run-event-check.ts +58 -0
- package/src/workspace/ancestry-index.test.ts +93 -0
- package/src/workspace/change-set-show.schema.json +102 -0
- package/src/workspace/change-set-show.ts +72 -0
- package/src/workspace/change-set.schema.json +32 -1
- package/src/workspace/changes-cli.ts +10 -1
- package/src/workspace/changes.schema.json +135 -0
- package/src/workspace/changes.test.ts +1 -1
- package/src/workspace/changes.ts +84 -2
- package/src/workspace/check.schema.json +4 -2
- package/src/workspace/checks/records.ts +35 -1
- package/src/workspace/checks.ts +2 -1
- package/src/workspace/ci-green-cli.ts +75 -13
- package/src/workspace/ci-green-forge.ts +24 -4
- package/src/workspace/ci-green-runs.test.ts +242 -0
- package/src/workspace/ci-green-signed.test.ts +302 -0
- package/src/workspace/ci-green-workflow.test.ts +16 -0
- package/src/workspace/ci-green-workflow.ts +12 -0
- package/src/workspace/ci-green.test.ts +131 -2
- package/src/workspace/ci-green.ts +635 -42
- package/src/workspace/ci-last-green.schema.json +32 -2
- package/src/workspace/ci-list.schema.json +525 -0
- package/src/workspace/commit-links.test.ts +279 -0
- package/src/workspace/commit-links.ts +183 -0
- package/src/workspace/declaration.schema.json +76 -0
- package/src/workspace/declaration.test.ts +28 -0
- package/src/workspace/declaration.ts +60 -2
- package/src/workspace/declared-kinds.ts +40 -1
- package/src/workspace/delivery-metrics.schema.json +519 -0
- package/src/workspace/delivery-metrics.test.ts +236 -0
- package/src/workspace/delivery-metrics.ts +286 -0
- package/src/workspace/flags-read.ts +121 -0
- package/src/workspace/flags.test.ts +141 -0
- package/src/workspace/flags.ts +157 -0
- package/src/workspace/graph-cli.ts +1 -1
- package/src/workspace/identity-gate-rule.ts +91 -7
- package/src/workspace/identity.ts +14 -1
- package/src/workspace/intent-cli.ts +46 -5
- package/src/workspace/intent-trace.test.ts +173 -0
- package/src/workspace/intent-trace.ts +484 -0
- package/src/workspace/intent.schema.json +702 -6
- package/src/workspace/intent.ts +196 -26
- package/src/workspace/ls.schema.json +3 -1
- package/src/workspace/ls.ts +6 -0
- package/src/workspace/member-pipeline.test.ts +17 -0
- package/src/workspace/member-pipeline.ts +9 -0
- package/src/workspace/older-records.test.ts +412 -0
- package/src/workspace/overlap.test.ts +165 -0
- package/src/workspace/overlap.ts +340 -0
- package/src/workspace/promotion-order.ts +97 -0
- package/src/workspace/read-contract.e2e.test.ts +5 -1
- package/src/workspace/reason-codes.test.ts +7 -1
- package/src/workspace/reason-codes.ts +7 -1
- package/src/workspace/record-assets.test.ts +2 -1
- package/src/workspace/records-contract.e2e.test.ts +2 -1
- package/src/workspace/records.schema.json +21 -2
- package/src/workspace/records.ts +36 -2
- package/src/workspace/reference-kinds/flag/flag.kind.mjs +32 -0
- package/src/workspace/reference-kinds/flag/flag.schema.json +53 -0
- package/src/workspace/releases.schema.json +513 -0
- package/src/workspace/releases.test.ts +108 -0
- package/src/workspace/releases.ts +133 -0
- package/src/workspace/run-event.schema.json +295 -0
- package/src/workspace/status-contract.test.ts +81 -1
- package/src/workspace/status-gates.ts +64 -1
- package/src/workspace/status-mixed.test.ts +152 -0
- package/src/workspace/status-revoked.test.ts +153 -0
- package/src/workspace/status-stewards.ts +6 -0
- package/src/workspace/status.schema.json +268 -2
- package/src/workspace/status.ts +334 -4
- package/src/workspace/trust/ci-tag-statement.ts +151 -0
- package/src/workspace/trust/op-run-statement.ts +148 -0
- package/src/workspace/trust/rotation.ts +61 -14
- package/src/workspace/trust/seal.ts +10 -0
- package/src/workspace/trust/ssh-commit.ts +10 -9
- package/src/workspace/wip.ts +11 -2
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/astro.config.mjs +0 -14
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/package.json +0 -16
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content/docs/index.mdx +0 -8
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content.config.ts +0 -15
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/tsconfig.json +0 -10
package/src/workspace/intent.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The intent graph over one region: `chant workspace graph --intent
|
|
3
|
-
* <path[:start-end]|path#symbol>` (#2651; #2650 sections B and C1; #2524 D8,
|
|
3
|
+
* <path[:start-end]|path#symbol|member/node|sha>` (#2651; #2650 sections B and C1; #2524 D8,
|
|
4
4
|
* D15; #3034).
|
|
5
5
|
*
|
|
6
6
|
* A person points at some code and asks how it got this way and who decided
|
|
@@ -77,6 +77,7 @@ import { followSquashes, squashLineOrigins, type Forge, type SquashFollow } from
|
|
|
77
77
|
import { memberDirOnDisk, memberSymbolResolvers, type SymbolPluginLoader } from "./lexicon-symbols";
|
|
78
78
|
import { resolveSymbol, symbolResolverFor, type SymbolResolver } from "./symbols";
|
|
79
79
|
import { readTrailerJoins, type CommitTrailerJoins } from "./trailer-joins";
|
|
80
|
+
import { buildTrace, type IntentTrace } from "./intent-trace";
|
|
80
81
|
import { joinPath, skippedDir, workingTree, type WorkspaceTree } from "./tree";
|
|
81
82
|
import { activeAttestors, type ProvenanceLevel } from "./trust/attestor";
|
|
82
83
|
import { commitProvenance, policyAtBase, resolveBase } from "./trust/provenance";
|
|
@@ -204,9 +205,12 @@ export interface RegionNode {
|
|
|
204
205
|
/** The member whose directory holds the path, or null. */
|
|
205
206
|
member: string | null;
|
|
206
207
|
at: string | null;
|
|
207
|
-
|
|
208
|
-
|
|
208
|
+
/** `commit` for a region given as a commit sha (#4023): the files that commit changed. */
|
|
209
|
+
type: "file" | "dir" | "commit";
|
|
210
|
+
/** For a file region, whether the file is generated (#2524 D14); null for a directory or a commit. */
|
|
209
211
|
generated: boolean | null;
|
|
212
|
+
/** Set when the region was given as a commit sha (#4023): its full sha. `path` is then `.`. */
|
|
213
|
+
commit?: string;
|
|
210
214
|
/** Set when the region was given as a graph node id. */
|
|
211
215
|
node: string | null;
|
|
212
216
|
/** Set when the region was given as `path#symbol` (#3034): the symbol as given, the declaration it resolved to, and its kind. `lines` holds its current lines. */
|
|
@@ -444,6 +448,16 @@ export interface WorkNode {
|
|
|
444
448
|
* to the review through it. Empty when none does. Added within contract 1.
|
|
445
449
|
*/
|
|
446
450
|
reviews?: WorkReview[];
|
|
451
|
+
/**
|
|
452
|
+
* The other in-flight work items whose linked commits touch a file this
|
|
453
|
+
* item's linked commits touch (#4025), as `workspace status --json` reports
|
|
454
|
+
* in `overlap`, each with the shared files. Empty when none does, or when
|
|
455
|
+
* this item is not in flight. Absent on a read with `--at` and when the
|
|
456
|
+
* overlap can't be read. The change-set entries two items share are in
|
|
457
|
+
* `status`, which reads the gates. Added within contract 1 by chant
|
|
458
|
+
* 0.124.29.
|
|
459
|
+
*/
|
|
460
|
+
overlaps?: { with: string; files: string[] }[];
|
|
447
461
|
}
|
|
448
462
|
|
|
449
463
|
/**
|
|
@@ -582,20 +596,22 @@ export type IntentDocument =
|
|
|
582
596
|
at: string | null;
|
|
583
597
|
workspace: { name: string; root: string };
|
|
584
598
|
region: string;
|
|
585
|
-
history: { rev: string | null; follows: "line-range" | "file" | "directory"; shallow: boolean };
|
|
599
|
+
history: { rev: string | null; follows: "line-range" | "file" | "directory" | "commit"; shallow: boolean };
|
|
586
600
|
kinds: { file: string; name: string; records: string | null; joins: "function" | "data" | null }[];
|
|
587
601
|
nodes: IntentNode[];
|
|
588
602
|
edges: IntentEdge[];
|
|
589
603
|
reasons: IntentReason[];
|
|
590
604
|
summary: { commits: number; decisions: number; artifacts: number; findings: number };
|
|
591
605
|
why: WhyAnswer;
|
|
606
|
+
/** The why chain (#4023): each commit's work item, ci tag, release, gate resolutions and deploys. Added within contract 1 by chant 0.124.29. */
|
|
607
|
+
trace?: IntentTrace;
|
|
592
608
|
})
|
|
593
609
|
| (Head & { error: { code: IntentErrorCode; message: string } });
|
|
594
610
|
|
|
595
611
|
export interface IntentQuery {
|
|
596
612
|
/** Where the walk up to the declaration starts, and what the region path is relative to. */
|
|
597
613
|
cwd: string;
|
|
598
|
-
/** `path`, `path:line`, `path:start-end` or `path#symbol`,
|
|
614
|
+
/** `path`, `path:line`, `path:start-end` or `path#symbol`, a graph node id `<member>/<id>`, or a commit sha (#4023). */
|
|
599
615
|
region: string;
|
|
600
616
|
at?: string;
|
|
601
617
|
/** Follow squash merges to their pull requests' original commits, fetching a missing pull request ref from `origin` (#3035). */
|
|
@@ -767,14 +783,77 @@ export function closingCommit(top: string, rev: string, path: string, stateField
|
|
|
767
783
|
return closing;
|
|
768
784
|
}
|
|
769
785
|
|
|
786
|
+
/**
|
|
787
|
+
* The files a commit changed, from the workspace root (#4023): against its
|
|
788
|
+
* first parent, or every file for a root commit. Files outside the workspace
|
|
789
|
+
* are left out.
|
|
790
|
+
*/
|
|
791
|
+
export function changedFiles(top: string, sha: string, workspacePrefix: string): string[] {
|
|
792
|
+
const out = tryGit(top, ["diff-tree", "--no-commit-id", "-r", "--name-only", "--root", "-m", "--first-parent", "-z", sha]) ?? "";
|
|
793
|
+
const files = new Set<string>();
|
|
794
|
+
for (const f of out.split("\0")) {
|
|
795
|
+
if (!f) continue;
|
|
796
|
+
if (workspacePrefix === "") files.add(f);
|
|
797
|
+
else if (f.startsWith(`${workspacePrefix}/`)) files.add(f.slice(workspacePrefix.length + 1));
|
|
798
|
+
}
|
|
799
|
+
return [...files].sort();
|
|
800
|
+
}
|
|
801
|
+
|
|
770
802
|
/** The commit a decision record's window opens at: the one that decided it, or, when it is not approved, the one that added it. */
|
|
771
803
|
export function windowOpening(top: string, rev: string, view: Pick<RecordView, "path" | "decidedIn">): string | null {
|
|
772
804
|
return view.decidedIn?.sha ?? addingCommit(top, rev, view.path);
|
|
773
805
|
}
|
|
774
806
|
|
|
775
|
-
/**
|
|
807
|
+
/** A full commit id, as git prints it: lowercase hex, sha1 or sha256. */
|
|
808
|
+
const FULL_COMMIT_ID = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/;
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* The children of every commit `rev` reaches, from one `git rev-list
|
|
812
|
+
* --parents` walk (#4032). Kept in memory for the last repository and commit
|
|
813
|
+
* read, since a walk asks for the windows of many records at one revision. A
|
|
814
|
+
* commit id names the same history for good, so the entry never goes stale.
|
|
815
|
+
*/
|
|
816
|
+
let childIndex: { key: string; children: Map<string, string[]> } | undefined;
|
|
817
|
+
|
|
818
|
+
function childrenWithin(top: string, rev: string): Map<string, string[]> | undefined {
|
|
819
|
+
const key = `${top}\0${rev}`;
|
|
820
|
+
if (childIndex?.key === key) return childIndex.children;
|
|
821
|
+
const text = tryGit(top, ["rev-list", "--parents", rev]);
|
|
822
|
+
if (text === undefined) return undefined;
|
|
823
|
+
const children = new Map<string, string[]>();
|
|
824
|
+
for (const row of text.split("\n")) {
|
|
825
|
+
const [commit, ...parents] = row.trim().split(" ");
|
|
826
|
+
if (!commit) continue;
|
|
827
|
+
for (const p of parents) {
|
|
828
|
+
const list = children.get(p);
|
|
829
|
+
if (list) list.push(commit);
|
|
830
|
+
else children.set(p, [commit]);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
childIndex = { key, children };
|
|
834
|
+
return children;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* `commit` and every commit between it and `rev` that has it as an ancestor:
|
|
839
|
+
* what `git rev-list --ancestry-path <commit>..<rev>` lists, plus `commit`.
|
|
840
|
+
* With full commit ids it is read from the children of what `rev` reaches,
|
|
841
|
+
* walked once per revision, instead of one `git rev-list` per record (#4032).
|
|
842
|
+
*/
|
|
776
843
|
export function descendants(top: string, commit: string, rev: string): Set<string> {
|
|
777
844
|
const out = new Set<string>([commit]);
|
|
845
|
+
const children = FULL_COMMIT_ID.test(commit) && FULL_COMMIT_ID.test(rev) ? childrenWithin(top, rev) : undefined;
|
|
846
|
+
if (children) {
|
|
847
|
+
const stack = [commit];
|
|
848
|
+
while (stack.length > 0) {
|
|
849
|
+
for (const c of children.get(stack.pop()!) ?? []) {
|
|
850
|
+
if (out.has(c)) continue;
|
|
851
|
+
out.add(c);
|
|
852
|
+
stack.push(c);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
return out;
|
|
856
|
+
}
|
|
778
857
|
const text = tryGit(top, ["rev-list", "--ancestry-path", `${commit}..${rev}`]);
|
|
779
858
|
for (const line of (text ?? "").split("\n")) if (line.trim()) out.add(line.trim());
|
|
780
859
|
return out;
|
|
@@ -926,8 +1005,13 @@ interface ResolvedRegion {
|
|
|
926
1005
|
lines: LineRange | null;
|
|
927
1006
|
node: string | null;
|
|
928
1007
|
symbol: { name: string; qualified: string; kind: string } | null;
|
|
1008
|
+
/** The full sha, for a region given as a commit (#4023). */
|
|
1009
|
+
commit?: string;
|
|
929
1010
|
}
|
|
930
1011
|
|
|
1012
|
+
/** A commit sha as a region may give it: 7 to 64 hex digits. */
|
|
1013
|
+
const COMMIT_REGION = /^[0-9a-fA-F]{7,64}$/;
|
|
1014
|
+
|
|
931
1015
|
async function resolveRegion(query: IntentQuery, located: LocatedWorkspace, declaration: Declaration): Promise<ResolvedRegion> {
|
|
932
1016
|
const parsed = parseRegion(query.region);
|
|
933
1017
|
if ("error" in parsed) throw new IntentError("intent-region-invalid", parsed.error);
|
|
@@ -972,10 +1056,38 @@ async function resolveRegion(query: IntentQuery, located: LocatedWorkspace, decl
|
|
|
972
1056
|
return { path: file === "" ? "." : file, lines: loc.line ? { start: loc.line, end: loc.line } : null, node: query.region, symbol: null };
|
|
973
1057
|
}
|
|
974
1058
|
}
|
|
975
|
-
|
|
1059
|
+
// A commit sha, when no path or node has the name (#4023): the commit and the files it changed.
|
|
1060
|
+
if (COMMIT_REGION.test(query.region) && located.top) {
|
|
1061
|
+
const sha = tryGit(located.top, ["rev-parse", "--verify", "--quiet", `${query.region}^{commit}`])?.trim();
|
|
1062
|
+
if (sha) return { path: ".", lines: null, node: null, symbol: null, commit: sha };
|
|
1063
|
+
}
|
|
1064
|
+
throw new IntentError("intent-region-invalid", `${query.region} is not a path in the workspace${located.tree.label}, a path#symbol, a graph node id or a commit`);
|
|
976
1065
|
}
|
|
977
1066
|
|
|
978
1067
|
/** Build the intent document. Never throws an {@link IntentError}, {@link WorkspaceReadError} or {@link RecordReadError}. */
|
|
1068
|
+
/**
|
|
1069
|
+
* Give each work node the in-flight items it overlaps by file (#4025). Only a
|
|
1070
|
+
* working-tree read, since the overlap is about the branches as they are now;
|
|
1071
|
+
* a read that fails leaves the field off.
|
|
1072
|
+
*/
|
|
1073
|
+
async function addOverlaps(work: WorkNode[], declaration: Declaration, root: string, top: string, at: string | null): Promise<void> {
|
|
1074
|
+
if (work.length === 0 || at !== null) return;
|
|
1075
|
+
let report: import("./overlap").OverlapReport | null;
|
|
1076
|
+
try {
|
|
1077
|
+
const { readOverlap } = await import("./overlap");
|
|
1078
|
+
report = await readOverlap({ declaration, root, top, changeSets: [] });
|
|
1079
|
+
} catch {
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
if (report === null) return;
|
|
1083
|
+
for (const n of work) {
|
|
1084
|
+
const self = `${n.recordKind}:${n.record}`;
|
|
1085
|
+
n.overlaps = report.pairs
|
|
1086
|
+
.filter((p) => p.items.includes(self) && p.files.length > 0)
|
|
1087
|
+
.map((p) => ({ with: p.items[0] === self ? p.items[1] : p.items[0], files: p.files }));
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
979
1091
|
export async function intentGraph(query: IntentQuery): Promise<IntentResult> {
|
|
980
1092
|
const head: Head = { $schema: INTENT_OUTPUT_SCHEMA_ID, contract: INTENT_CONTRACT_VERSION, chant: readerVersion() };
|
|
981
1093
|
try {
|
|
@@ -994,7 +1106,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
994
1106
|
if (!top) throw new IntentError("not-a-git-repository", "the intent graph reads git history, and this directory is not in a git repository");
|
|
995
1107
|
const declaration = readDeclaration(located.tree, "", { rootChant: true });
|
|
996
1108
|
const region = await resolveRegion(query, located, declaration);
|
|
997
|
-
const type = region.path === "." ? "dir" : located.tree.stat(region.path);
|
|
1109
|
+
const type: "file" | "dir" | "commit" | undefined = region.commit ? "commit" : region.path === "." ? "dir" : located.tree.stat(region.path);
|
|
998
1110
|
if (!type) throw new IntentError("intent-region-invalid", `${region.path} does not exist${located.tree.label}`);
|
|
999
1111
|
if (region.lines) {
|
|
1000
1112
|
if (type !== "file") throw new IntentError("intent-region-invalid", `${region.path} is a directory, and a line range needs a file`);
|
|
@@ -1018,8 +1130,21 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1018
1130
|
};
|
|
1019
1131
|
|
|
1020
1132
|
// The region, its files and its member.
|
|
1021
|
-
|
|
1022
|
-
const
|
|
1133
|
+
// A commit region (#4023) covers the files the commit changed, from the workspace root, and the members holding them.
|
|
1134
|
+
const workspacePrefix = located.root === "." ? "" : located.root;
|
|
1135
|
+
const changed = region.commit ? changedFiles(top, region.commit, workspacePrefix) : [];
|
|
1136
|
+
const changedMembers = [...new Set(changed.map((f) => memberHolding(f, declaration.members)).filter((m): m is string => m !== null))];
|
|
1137
|
+
const member = region.commit
|
|
1138
|
+
? changedMembers.length === 1
|
|
1139
|
+
? changedMembers[0]
|
|
1140
|
+
: null
|
|
1141
|
+
: region.path === "."
|
|
1142
|
+
? (declaration.members.find((m) => m.dir === ".")?.name ?? null)
|
|
1143
|
+
: memberHolding(region.path, declaration.members);
|
|
1144
|
+
const regionMembers = region.commit ? changedMembers : member ? [member] : [];
|
|
1145
|
+
const rid = region.commit ? `region:commit:${region.commit}` : regionId(region.path, region.lines, region.symbol?.name);
|
|
1146
|
+
/** How messages name the region: its path, or the commit. */
|
|
1147
|
+
const regionLabel = region.commit ? `commit ${region.commit.slice(0, 8)}` : region.path;
|
|
1023
1148
|
add<RegionNode>({
|
|
1024
1149
|
id: rid,
|
|
1025
1150
|
kind: "region",
|
|
@@ -1031,6 +1156,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1031
1156
|
generated: type === "file" ? isGeneratedPath(declaration, region.path) : null,
|
|
1032
1157
|
node: region.node,
|
|
1033
1158
|
symbol: region.symbol,
|
|
1159
|
+
...(region.commit ? { commit: region.commit } : {}),
|
|
1034
1160
|
});
|
|
1035
1161
|
const files = type === "dir" ? filesUnder(located.tree, region.path) : [];
|
|
1036
1162
|
for (const f of files) add<FileNode>({ id: `file:${f}`, kind: "file", path: f, member: memberHolding(f, declaration.members), generated: isGeneratedPath(declaration, f) });
|
|
@@ -1044,9 +1170,8 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1044
1170
|
const rev = located.at ?? (tryGit(top, ["rev-parse", "--verify", "--quiet", "HEAD^{commit}"])?.trim() || null);
|
|
1045
1171
|
const shallow = tryGit(top, ["rev-parse", "--is-shallow-repository"])?.trim() === "true";
|
|
1046
1172
|
if (shallow) reasons.push({ code: "intent-history-shallow", message: "this is a shallow clone, so the history stops at its boundary and the oldest commit listed may stand for many" });
|
|
1047
|
-
const workspacePrefix = located.root === "." ? "" : located.root;
|
|
1048
1173
|
const gitPath = joinPath(workspacePrefix, region.path);
|
|
1049
|
-
const touched = rev ? regionHistory(top, rev, gitPath, type, region.lines) : [];
|
|
1174
|
+
const touched = region.commit ? [{ sha: region.commit, lines: null }] : rev && type !== "commit" ? regionHistory(top, rev, gitPath, type, region.lines) : [];
|
|
1050
1175
|
// Who last wrote each current line of a file region (#3034). A commit blame
|
|
1051
1176
|
// names and the history walk missed, as when a move confuses git log -L,
|
|
1052
1177
|
// joins the commits that touched the region.
|
|
@@ -1262,14 +1387,16 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1262
1387
|
const p = entry.slice("path:".length);
|
|
1263
1388
|
if (!isWorkspacePath(p)) continue;
|
|
1264
1389
|
const full = joinPath(kindPrefix, p);
|
|
1265
|
-
if (
|
|
1390
|
+
if (type === "commit") {
|
|
1391
|
+
if (changed.some((f) => constraintCovers(full, joinPath(workspacePrefix, f)))) matched.push({ entry, granularity: "path", to: rid });
|
|
1392
|
+
} else if (regionFull !== "" && constraintCovers(full, regionFull)) {
|
|
1266
1393
|
matched.push({ entry, granularity: "path", to: rid });
|
|
1267
1394
|
} else if (type === "dir" && full !== regionFull && (regionFull === "" || full.startsWith(`${regionFull}/`))) {
|
|
1268
1395
|
// A path below a directory region constrains the files under it, not the whole region.
|
|
1269
1396
|
for (const f of fileNodesUnder(full)) matched.push({ entry, granularity: "path", to: `file:${f}` });
|
|
1270
1397
|
}
|
|
1271
1398
|
} else if (entry.startsWith("member:")) {
|
|
1272
|
-
if (
|
|
1399
|
+
if (regionMembers.includes(entry.slice("member:".length))) matched.push({ entry, granularity: "member", to: rid });
|
|
1273
1400
|
} else {
|
|
1274
1401
|
const issue = entry.match(ISSUE);
|
|
1275
1402
|
if (issue && origin !== null && issue[1].toLowerCase() === origin && commitRefs.has(issue[2])) matched.push({ entry, granularity: "issue", to: rid });
|
|
@@ -1644,7 +1771,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1644
1771
|
if (h.node!.constrains.some((x) => x.granularity === "path") && inWorkWindow(h, t.sha)) edges.push({ kind: "within", from: c.id, to: h.node!.id, state: "worked" });
|
|
1645
1772
|
}
|
|
1646
1773
|
if (readsRecords && c.state === "undecided") {
|
|
1647
|
-
find("intent-commit-undecided", `${t.sha.slice(0, 8)} changed the region when no decision constrained ${
|
|
1774
|
+
find("intent-commit-undecided", `${t.sha.slice(0, 8)} changed the region when no decision constrained ${regionLabel} by path`, [c.id, rid]);
|
|
1648
1775
|
}
|
|
1649
1776
|
if (readsRecords && !j.unit && j.carries.length === 0 && c.pullRequest === null && coveredAt(t.sha, ["path", "member", "contract", "issue"]).length === 0) {
|
|
1650
1777
|
find("intent-commit-bare", `${t.sha.slice(0, 8)} names no unit, no record, no pull request and no decision`, [c.id]);
|
|
@@ -1659,11 +1786,11 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1659
1786
|
if (readsRecords) {
|
|
1660
1787
|
const current = covering.filter((c) => c.node.supersededBy === null);
|
|
1661
1788
|
if (covering.length === 0) {
|
|
1662
|
-
find("intent-region-unconstrained", `no decision constrains ${
|
|
1789
|
+
find("intent-region-unconstrained", `no decision constrains ${regionLabel}`, [rid]);
|
|
1663
1790
|
} else if (current.length === 0) {
|
|
1664
|
-
find("intent-decision-superseded-live", `every decision constraining ${
|
|
1791
|
+
find("intent-decision-superseded-live", `every decision constraining ${regionLabel} is superseded: ${covering.map((c) => `${c.node.record} by ${c.node.supersededBy}`).join(", ")}`, [rid, ...covering.map((c) => c.node.id)]);
|
|
1665
1792
|
} else if (current.every((c) => !c.node.closed)) {
|
|
1666
|
-
find("intent-decision-provisional", `the decisions constraining ${
|
|
1793
|
+
find("intent-decision-provisional", `the decisions constraining ${regionLabel} are ${[...new Set(current.map((c) => c.node.state ?? "stateless"))].join(" or ")}, and none is in a closed state`, [rid, ...current.map((c) => c.node.id)]);
|
|
1667
1794
|
}
|
|
1668
1795
|
// A current decision with a dissent nobody addressed or withdrew (#2686), from its quorum.
|
|
1669
1796
|
for (const c of current) {
|
|
@@ -1674,14 +1801,14 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1674
1801
|
id: `finding:intent-decision-contested:${findings.filter((f) => f.code === "intent-decision-contested").length + 1}`,
|
|
1675
1802
|
kind: "finding",
|
|
1676
1803
|
code: "intent-decision-contested",
|
|
1677
|
-
message: `${c.node.record} constrains ${
|
|
1804
|
+
message: `${c.node.record} constrains ${regionLabel} and has ${open.length} open ${open.length === 1 ? "concern" : "concerns"}, from ${open.map((o) => o.reviewer).join(", ")}: a dissent neither addressed nor withdrawn`,
|
|
1678
1805
|
concerns: [c.node.id, rid],
|
|
1679
1806
|
openConcerns: { count: open.length, principals },
|
|
1680
1807
|
});
|
|
1681
1808
|
}
|
|
1682
1809
|
const granularities = new Set(covering.flatMap((c) => c.node.constrains.map((x) => x.granularity)));
|
|
1683
1810
|
if (covering.length > 0 && !granularities.has("path") && granularities.has("member")) {
|
|
1684
|
-
find("intent-constraint-coarse", `${
|
|
1811
|
+
find("intent-constraint-coarse", `${regionLabel} is constrained only through its member, ${regionMembers.join(", ")}`, [rid, ...covering.map((c) => c.node.id)]);
|
|
1685
1812
|
}
|
|
1686
1813
|
}
|
|
1687
1814
|
|
|
@@ -1692,7 +1819,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1692
1819
|
if (implementersOf(c.node).length > 0) continue;
|
|
1693
1820
|
const w = windows.get(c.node.id);
|
|
1694
1821
|
if (w && touched.some((t) => w.from.has(t.sha) && !w.until?.has(t.sha))) continue;
|
|
1695
|
-
find("intent-decision-unimplemented", `${c.node.record} is ${c.node.state} and constrains ${
|
|
1822
|
+
find("intent-decision-unimplemented", `${c.node.record} is ${c.node.state} and constrains ${regionLabel}, and no work item that is not dropped implements it, and no commit changed the region in its window`, [c.node.id, rid]);
|
|
1696
1823
|
}
|
|
1697
1824
|
for (const h of workCovering) {
|
|
1698
1825
|
const node = h.node!;
|
|
@@ -1710,7 +1837,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1710
1837
|
if (impl.length === 0 || impl.some((h) => h.view.state === workSpec(h).done)) continue;
|
|
1711
1838
|
find(
|
|
1712
1839
|
"intent-work-open-decided-code",
|
|
1713
|
-
`${own.length} ${own.length === 1 ? "commit" : "commits"} in ${
|
|
1840
|
+
`${own.length} ${own.length === 1 ? "commit" : "commits"} in ${regionLabel} ${own.length === 1 ? "is" : "are"} ${d.record}'s own work, and ${impl.map((h) => `${h.view.id} is ${h.view.state ?? "stateless"}`).join(", ")}: the code says done and the queue says not`,
|
|
1714
1841
|
[d.id, ...own, ...impl.map((h) => workNode(h).id)],
|
|
1715
1842
|
);
|
|
1716
1843
|
}
|
|
@@ -1780,6 +1907,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1780
1907
|
const kindPrefix = h.kind.records!.workspaceRoot === "." ? "" : h.kind.records!.workspaceRoot;
|
|
1781
1908
|
const full = joinPath(kindPrefix, parsed.path);
|
|
1782
1909
|
const contains = (a: string, b: string) => a === b || a === "" || b.startsWith(`${a}/`);
|
|
1910
|
+
if (type === "commit") return changed.some((f) => contains(full, joinPath(workspacePrefix, f)) || contains(joinPath(workspacePrefix, f), full));
|
|
1783
1911
|
if (!contains(full, regionFull) && !contains(regionFull, full)) return false;
|
|
1784
1912
|
if (full === regionFull && parsed.lines && region.lines) return parsed.lines.start <= region.lines.end && region.lines.start <= parsed.lines.end;
|
|
1785
1913
|
return true;
|
|
@@ -1793,7 +1921,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1793
1921
|
if (gap && h.view.state === workSpec(h).done) {
|
|
1794
1922
|
const node = workNode(h);
|
|
1795
1923
|
if (!node.warnings.some((w) => w.code === "work-done-gap-open")) {
|
|
1796
|
-
node.warnings.push({ code: "work-done-gap-open", message: `${node.record} is ${h.view.state}, and ${f.code}, the gap it came from, still fires on ${
|
|
1924
|
+
node.warnings.push({ code: "work-done-gap-open", message: `${node.record} is ${h.view.state}, and ${f.code}, the gap it came from, still fires on ${regionLabel}` });
|
|
1797
1925
|
}
|
|
1798
1926
|
}
|
|
1799
1927
|
}
|
|
@@ -1832,15 +1960,56 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1832
1960
|
}
|
|
1833
1961
|
}
|
|
1834
1962
|
for (const f of findings) nodes.set(f.id, f);
|
|
1963
|
+
await addOverlaps([...nodes.values()].filter((n): n is WorkNode => n.kind === "work"), declaration, located.rootOnDisk, top, located.at);
|
|
1835
1964
|
const why = explain();
|
|
1836
1965
|
const all = [...nodes.values()];
|
|
1966
|
+
|
|
1967
|
+
// The why chain (#4023): each commit's work item, ci tag, release, gate resolutions and deploys.
|
|
1968
|
+
const workIds = new Map<string, Set<string>>();
|
|
1969
|
+
const workNodeIds = new Map<string, string>();
|
|
1970
|
+
for (const h of workAll) {
|
|
1971
|
+
const name = h.kind.records!.loaded.kind.name;
|
|
1972
|
+
(workIds.get(name) ?? workIds.set(name, new Set()).get(name)!).add(h.view.id!);
|
|
1973
|
+
if (h.node) workNodeIds.set(`${name}:${h.view.id}`, h.node.id);
|
|
1974
|
+
}
|
|
1975
|
+
for (const k of workKinds) if (!workIds.has(k.records!.loaded.kind.name)) workIds.set(k.records!.loaded.kind.name, new Set());
|
|
1976
|
+
const windowsOf = new Map<string, { id: string; node: string; path: string }[]>();
|
|
1977
|
+
for (const e of edges) {
|
|
1978
|
+
if (e.kind !== "within" || e.state !== "worked") continue;
|
|
1979
|
+
const w = nodes.get(e.to) as WorkNode | undefined;
|
|
1980
|
+
if (!w) continue;
|
|
1981
|
+
const sha = e.from.slice("commit:".length);
|
|
1982
|
+
(windowsOf.get(sha) ?? windowsOf.set(sha, []).get(sha)!).push({ id: `${w.recordKind}:${w.record}`, node: w.id, path: w.path });
|
|
1983
|
+
}
|
|
1984
|
+
const later = new Map<string, Set<string>>();
|
|
1985
|
+
const trace = await buildTrace({
|
|
1986
|
+
top,
|
|
1987
|
+
commits: all.filter((n): n is CommitNode => n.kind === "commit").map((c) => ({ id: c.id, sha: c.sha, trailers: c.trailers, joins: c.joins })),
|
|
1988
|
+
work: readsWork ? { index: { kinds: workIds }, nodes: workNodeIds } : null,
|
|
1989
|
+
windows: windowsOf,
|
|
1990
|
+
// The region's member's ledger; for a region in no member, every member's and the workspace's own.
|
|
1991
|
+
ledgers: (regionMembers.length > 0 ? regionMembers : declaration.members.map((m) => m.name))
|
|
1992
|
+
.map((name) => {
|
|
1993
|
+
const dir = declaration.members.find((m) => m.name === name)!.dir;
|
|
1994
|
+
return { member: name as string | null, cwd: memberDirOnDisk(located.rootOnDisk, dir), within: dir === "." ? null : `_members/${name}/` };
|
|
1995
|
+
})
|
|
1996
|
+
.concat(regionMembers.length > 0 ? [] : [{ member: null, cwd: located.rootOnDisk, within: null }]),
|
|
1997
|
+
green: declaration.ci?.green ?? null,
|
|
1998
|
+
contains: (sha, commit) => {
|
|
1999
|
+
if (commit === sha) return true;
|
|
2000
|
+
if (!rev || !FULL_COMMIT_ID.test(commit)) return false;
|
|
2001
|
+
let set = later.get(sha);
|
|
2002
|
+
if (!set) later.set(sha, (set = descendants(top, sha, rev)));
|
|
2003
|
+
return set.has(commit);
|
|
2004
|
+
},
|
|
2005
|
+
});
|
|
1837
2006
|
return {
|
|
1838
2007
|
doc: {
|
|
1839
2008
|
...head,
|
|
1840
2009
|
at: located.at,
|
|
1841
2010
|
workspace: { name: declaration.name, root: located.root },
|
|
1842
2011
|
region: rid,
|
|
1843
|
-
history: { rev, follows: region.lines ? "line-range" : type === "file" ? "file" : "directory", shallow },
|
|
2012
|
+
history: { rev, follows: region.commit ? "commit" : region.lines ? "line-range" : type === "file" ? "file" : "directory", shallow },
|
|
1844
2013
|
kinds: kinds.map((k) => ({ file: k.display, name: k.name, records: k.records?.loaded.kind.name ?? null, joins: k.joins?.form ?? null })),
|
|
1845
2014
|
nodes: all,
|
|
1846
2015
|
edges,
|
|
@@ -1852,6 +2021,7 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1852
2021
|
findings: findings.length,
|
|
1853
2022
|
},
|
|
1854
2023
|
why,
|
|
2024
|
+
trace,
|
|
1855
2025
|
},
|
|
1856
2026
|
failed: reasons.some((r) => r.code === "intent-plugin-failed"),
|
|
1857
2027
|
};
|
|
@@ -1972,12 +2142,12 @@ async function walk(query: IntentQuery, head: Head): Promise<IntentResult> {
|
|
|
1972
2142
|
if (!explained) {
|
|
1973
2143
|
gaps.push({
|
|
1974
2144
|
code: "intent-why-no-decision",
|
|
1975
|
-
message: readsRecords ? `no current decision governs ${
|
|
2145
|
+
message: readsRecords ? `no current decision governs ${regionLabel}, and none is carried out by what made its lines` : `no record kind was read, so no decision can account for ${regionLabel}`,
|
|
1976
2146
|
});
|
|
1977
2147
|
}
|
|
1978
2148
|
const committed = who.filter((w) => w.sha !== null);
|
|
1979
2149
|
if (fileLines !== null ? committed.length > 0 && committed.every((w) => w.runs.length === 0) : touched.length > 0 && runNodes.length === 0) {
|
|
1980
|
-
gaps.push({ code: "intent-why-no-run", message: `no agent run is joined to the commits that made ${fileLines !== null ? "the current lines of " : ""}${
|
|
2150
|
+
gaps.push({ code: "intent-why-no-run", message: `no agent run is joined to the commits that made ${fileLines !== null ? "the current lines of " : ""}${regionLabel}` });
|
|
1981
2151
|
}
|
|
1982
2152
|
const uncommitted = who.filter((w) => w.sha === null).map((w) => w.line);
|
|
1983
2153
|
if (uncommitted.length > 0) gaps.push({ code: "intent-why-uncommitted", message: `${uncommitted.length} ${uncommitted.length === 1 ? "line is" : "lines are"} not committed yet`, lines: ranges(uncommitted) });
|
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
|
-
"require": { "type": "array", "items": { "type": "string" } }
|
|
28
|
+
"require": { "type": "array", "items": { "type": "string" } },
|
|
29
|
+
"signedSince": { "type": "string", "description": "Added in contract 1 by #4031, written by chant 0.124.28 and newer, and only when the declaration sets it: the full sha of the first commit whose ci tags count only with a statement signed by a runner key. Tags on its strict first-parent ancestors count unsigned." },
|
|
30
|
+
"source": { "const": "runs", "description": "Added in contract 1 by #4044, written by chant 0.124.28 and newer, and only when the declaration sets ci.green.source to runs: ci tick reads each phase's results from chant's own Op runs on chant/lifecycle, each signed by a runner key, in place of the forge's check runs. Absent means check runs." }
|
|
29
31
|
}
|
|
30
32
|
},
|
|
31
33
|
"result": {
|
package/src/workspace/ls.ts
CHANGED
|
@@ -144,6 +144,10 @@ export interface LsCiGreen {
|
|
|
144
144
|
window: string;
|
|
145
145
|
phases: { name: string; runs: string[]; skipped: "pass" | "fail" }[];
|
|
146
146
|
require: string[];
|
|
147
|
+
/** The first commit whose ci tags need a signed statement (#4031). Present only when the declaration sets it. */
|
|
148
|
+
signedSince?: string;
|
|
149
|
+
/** Where the tick reads phase results (#4044). Present only when it is `runs`; absent means the forge's check runs. */
|
|
150
|
+
source?: "runs";
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
export interface LsGroup {
|
|
@@ -322,6 +326,8 @@ function readListing(query: LsQuery): { doc: LsDocument; declaration?: Declarati
|
|
|
322
326
|
window: declaration.ci.green.window,
|
|
323
327
|
phases: declaration.ci.green.phases.map((p) => ({ name: p.name, runs: p.runs, skipped: p.skipped })),
|
|
324
328
|
require: declaration.ci.green.require,
|
|
329
|
+
...(declaration.ci.green.signedSince !== null ? { signedSince: declaration.ci.green.signedSince } : {}),
|
|
330
|
+
...(declaration.ci.green.source === "runs" ? { source: "runs" as const } : {}),
|
|
325
331
|
}
|
|
326
332
|
: null,
|
|
327
333
|
}
|
|
@@ -95,6 +95,23 @@ describe("the component pipeline's file and command", () => {
|
|
|
95
95
|
expect(plan.command).toBe("chant build --components --generate github --env staging --pr-loop --gate infra-apply --branch trunk");
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
+
test("the recorded command keeps --image and each --before-script, in order (#4002)", () => {
|
|
99
|
+
const dir = join(repo, "services/api");
|
|
100
|
+
const plan = planMemberComponentPipeline({
|
|
101
|
+
projectDir: dir,
|
|
102
|
+
found: findWorkspaceRoot(dir)!,
|
|
103
|
+
lexicon: "forgejo",
|
|
104
|
+
env: "staging",
|
|
105
|
+
output: join(dir, "pr.yml"),
|
|
106
|
+
prLoop: {},
|
|
107
|
+
image: "node:22-bookworm",
|
|
108
|
+
beforeScript: ["npm ci", 'echo "$PWD/node_modules/.bin" >> "$GITHUB_PATH"'],
|
|
109
|
+
})!;
|
|
110
|
+
expect(plan.command).toBe(
|
|
111
|
+
`chant build --components --generate forgejo --env staging --pr-loop --image node:22-bookworm --before-script 'npm ci' --before-script 'echo "$PWD/node_modules/.bin" >> "$GITHUB_PATH"' --output pr.yml`,
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
|
|
98
115
|
test("the recorded command keeps --wave-gate, --canary and --base (#3049)", () => {
|
|
99
116
|
const dir = join(repo, "services/api");
|
|
100
117
|
const plan = planMemberComponentPipeline({
|
|
@@ -205,6 +205,8 @@ export interface ComponentPlanInput {
|
|
|
205
205
|
/** `--env`, or undefined for the generator's default. */
|
|
206
206
|
env?: string;
|
|
207
207
|
promoteTo?: string;
|
|
208
|
+
/** `--allow-skip` (#4030): the generated promote job may skip a step of the promotion order. */
|
|
209
|
+
allowSkip?: boolean;
|
|
208
210
|
/** `--output`, relative to the current directory. */
|
|
209
211
|
output?: string;
|
|
210
212
|
params?: string[];
|
|
@@ -213,6 +215,10 @@ export interface ComponentPlanInput {
|
|
|
213
215
|
prLoop?: { gate?: string; branch?: string };
|
|
214
216
|
/** `--wave-gate` with its `--canary` and `--base` (#3049). */
|
|
215
217
|
waveGate?: { gate: string; canary?: string[]; base?: string };
|
|
218
|
+
/** `--image` (#4002). */
|
|
219
|
+
image?: string;
|
|
220
|
+
/** `--before-script`, in order (#4002). */
|
|
221
|
+
beforeScript?: string[];
|
|
216
222
|
}
|
|
217
223
|
|
|
218
224
|
/** The generators' own default environment when `--env` is not given. */
|
|
@@ -242,6 +248,7 @@ export function planMemberComponentPipeline(input: ComponentPlanInput): MemberCo
|
|
|
242
248
|
|
|
243
249
|
const parts = ["chant", "build", "--components", "--generate", input.lexicon, "--env", env];
|
|
244
250
|
if (input.promoteTo) parts.push("--promote-to", input.promoteTo);
|
|
251
|
+
if (input.promoteTo && input.allowSkip) parts.push("--allow-skip");
|
|
245
252
|
if (input.waveGate) {
|
|
246
253
|
parts.push("--wave-gate", input.waveGate.gate);
|
|
247
254
|
if (input.waveGate.canary?.length) parts.push("--canary", input.waveGate.canary.join(","));
|
|
@@ -252,6 +259,8 @@ export function planMemberComponentPipeline(input: ComponentPlanInput): MemberCo
|
|
|
252
259
|
if (input.prLoop.gate) parts.push("--gate", input.prLoop.gate);
|
|
253
260
|
if (input.prLoop.branch) parts.push("--branch", input.prLoop.branch);
|
|
254
261
|
}
|
|
262
|
+
if (input.image) parts.push("--image", input.image);
|
|
263
|
+
for (const line of input.beforeScript ?? []) parts.push("--before-script", line);
|
|
255
264
|
for (const p of input.params ?? []) parts.push("--param", p);
|
|
256
265
|
if (input.paramsFile) parts.push("--params-file", relPath(ctx.memberRoot, resolve(input.paramsFile)));
|
|
257
266
|
if (input.output) parts.push("--output", relPath(ctx.memberRoot, target));
|