@intentius/chant 0.124.27 → 0.124.28
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/change-set-graph.d.ts +56 -0
- package/dist/change-set-graph.d.ts.map +1 -0
- package/dist/change-set-graph.js +128 -0
- package/dist/change-set.d.ts +52 -3
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +35 -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/commands/build.d.ts +8 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +9 -8
- 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 +19 -4
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +28 -0
- 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 +1 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +14 -3
- package/dist/cli/handlers/pr.d.ts +8 -2
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +148 -24
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +256 -21
- package/dist/cli/handlers/release.d.ts +34 -0
- package/dist/cli/handlers/release.d.ts.map +1 -0
- package/dist/cli/handlers/release.js +203 -0
- package/dist/cli/handlers/run.d.ts +28 -2
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/run.js +170 -13
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +88 -13
- 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 +49 -3
- package/dist/cli/registry.d.ts +29 -3
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/run-events.d.ts +29 -0
- package/dist/cli/run-events.d.ts.map +1 -0
- package/dist/cli/run-events.js +47 -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 +4 -1
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/auto-release.js +2 -0
- 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 +42 -9
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +81 -54
- 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 +35 -26
- 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 +15 -2
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +17 -0
- package/dist/components/release-compile.d.ts +133 -0
- package/dist/components/release-compile.d.ts.map +1 -0
- package/dist/components/release-compile.js +376 -0
- package/dist/components/release-gate.d.ts +125 -0
- package/dist/components/release-gate.d.ts.map +1 -0
- package/dist/components/release-gate.js +282 -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 +3 -1
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +1 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -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/change-set-store.d.ts +67 -0
- package/dist/lifecycle/change-set-store.d.ts.map +1 -0
- package/dist/lifecycle/change-set-store.js +96 -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/gate-change-set.d.ts +69 -0
- package/dist/lifecycle/gate-change-set.d.ts.map +1 -0
- package/dist/lifecycle/gate-change-set.js +106 -0
- package/dist/lifecycle/gate-ledger.d.ts +49 -1
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.js +18 -0
- package/dist/lifecycle/release-cut.d.ts +107 -0
- package/dist/lifecycle/release-cut.d.ts.map +1 -0
- package/dist/lifecycle/release-cut.js +273 -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-store.d.ts +190 -0
- package/dist/lifecycle/release-store.d.ts.map +1 -0
- package/dist/lifecycle/release-store.js +318 -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/point-decision.d.ts +2 -0
- package/dist/point-decision.d.ts.map +1 -1
- package/dist/point-decision.js +9 -2
- package/dist/run-event-store.d.ts +77 -0
- package/dist/run-event-store.d.ts.map +1 -0
- package/dist/run-event-store.js +204 -0
- package/dist/run-event-stream.d.ts +132 -0
- package/dist/run-event-stream.d.ts.map +1 -0
- package/dist/run-event-stream.js +238 -0
- package/dist/run-event.d.ts +267 -0
- package/dist/run-event.d.ts.map +1 -0
- package/dist/run-event.js +207 -0
- package/dist/wave-runtime.mjs +204 -199
- 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 +28 -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/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 +273 -13
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +449 -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 +19 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +1 -1
- package/dist/workspace/declaration.schema.json +12 -0
- 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.d.ts +6 -1
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/intent.js +51 -1
- 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/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 +2 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +4 -1
- package/dist/workspace/releases.d.ts +72 -0
- package/dist/workspace/releases.d.ts.map +1 -0
- package/dist/workspace/releases.js +94 -0
- package/dist/workspace/releases.schema.json +391 -0
- package/dist/workspace/run-event.schema.json +288 -0
- package/dist/workspace/status-gates.d.ts +26 -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 +39 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +48 -1
- package/dist/workspace/status.schema.json +70 -1
- 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/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/change-set-graph.test.ts +72 -0
- package/src/change-set-graph.ts +133 -0
- package/src/change-set.ts +76 -6
- package/src/chant-version.ts +16 -0
- package/src/cli/commands/build.ts +19 -8
- 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 +80 -0
- package/src/cli/handlers/approve.ts +18 -2
- package/src/cli/handlers/build.test.ts +52 -0
- package/src/cli/handlers/build.ts +29 -0
- package/src/cli/handlers/change-set.ts +49 -1
- package/src/cli/handlers/fan-out.test.ts +48 -0
- package/src/cli/handlers/fan-out.ts +15 -3
- package/src/cli/handlers/operator.test.ts +37 -0
- package/src/cli/handlers/pr.test.ts +194 -0
- package/src/cli/handlers/pr.ts +168 -34
- package/src/cli/handlers/promote.test.ts +389 -5
- package/src/cli/handlers/promote.ts +279 -20
- package/src/cli/handlers/release-implicit.e2e.test.ts +153 -0
- package/src/cli/handlers/release.e2e.test.ts +85 -0
- package/src/cli/handlers/release.ts +206 -0
- package/src/cli/handlers/run-auto-release.test.ts +71 -0
- package/src/cli/handlers/run-events-cmd.test.ts +92 -0
- package/src/cli/handlers/run.test.ts +30 -0
- package/src/cli/handlers/run.ts +176 -15
- package/src/cli/main.test.ts +7 -0
- package/src/cli/main.ts +88 -13
- 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 +37 -3
- package/src/cli/registry.ts +29 -3
- package/src/cli/run-events.ts +54 -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 +21 -0
- package/src/components/auto-release.ts +6 -1
- package/src/components/cli-support.test.ts +82 -0
- package/src/components/cli-support.ts +16 -9
- package/src/components/driver.ts +129 -56
- package/src/components/fan-out-run.ts +56 -35
- 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 +26 -1
- package/src/components/release-compile.test.ts +147 -0
- package/src/components/release-compile.ts +445 -0
- package/src/components/release-gate.test.ts +215 -0
- package/src/components/release-gate.ts +341 -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 +1 -1
- package/src/config.ts +7 -1
- package/src/index.ts +2 -0
- package/src/lifecycle/change-set-store.test.ts +217 -0
- package/src/lifecycle/change-set-store.ts +112 -0
- package/src/lifecycle/commit-sha.ts +23 -0
- package/src/lifecycle/gate-change-set.e2e.test.ts +122 -0
- package/src/lifecycle/gate-change-set.ts +133 -0
- package/src/lifecycle/gate-ledger.test.ts +33 -0
- package/src/lifecycle/gate-ledger.ts +66 -1
- package/src/lifecycle/release-cut-signed.test.ts +180 -0
- package/src/lifecycle/release-cut.test.ts +411 -0
- package/src/lifecycle/release-cut.ts +367 -0
- package/src/lifecycle/release-ledger.test.ts +14 -0
- package/src/lifecycle/release-ledger.ts +85 -17
- package/src/lifecycle/release-store.ts +423 -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/point-decision.ts +12 -2
- package/src/run-event-store.test.ts +144 -0
- package/src/run-event-store.ts +213 -0
- package/src/run-event-stream.test.ts +175 -0
- package/src/run-event-stream.ts +306 -0
- package/src/run-event.test.ts +277 -0
- package/src/run-event.ts +451 -0
- package/src/wave-loop-golden.test.ts +9 -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 +28 -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/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 +624 -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 +12 -0
- package/src/workspace/declaration.ts +22 -2
- package/src/workspace/identity-gate-rule.ts +91 -7
- package/src/workspace/identity.ts +14 -1
- package/src/workspace/intent.ts +48 -1
- 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/promotion-order.ts +97 -0
- package/src/workspace/read-contract.e2e.test.ts +4 -1
- package/src/workspace/reason-codes.test.ts +2 -1
- package/src/workspace/reason-codes.ts +4 -1
- package/src/workspace/releases.schema.json +391 -0
- package/src/workspace/releases.test.ts +108 -0
- package/src/workspace/releases.ts +122 -0
- package/src/workspace/run-event.schema.json +288 -0
- package/src/workspace/status-contract.test.ts +52 -1
- package/src/workspace/status-gates.ts +56 -1
- package/src/workspace/status-stewards.ts +6 -0
- package/src/workspace/status.schema.json +70 -1
- package/src/workspace/status.ts +80 -1
- 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/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/cli/handlers/run.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { runOpLocally, findPolicyGateStep, OpRunFailure, type StepRecord } from
|
|
|
10
10
|
import { approveCommand, describeGateMismatch, gateIsSealed } from "../../op/gate";
|
|
11
11
|
import { summaryLedgerPrefix, writeGatedRunSummary, type GatedRunSummary } from "../../op/gate-summary";
|
|
12
12
|
import { createLocalOpRuntime } from "../../op/runtimes/local";
|
|
13
|
-
import type { OpRuntimeProvider, OpRunStatus } from "../../op/runtime";
|
|
13
|
+
import type { OpRuntimeProvider, OpRunRecord, OpRunStatus } from "../../op/runtime";
|
|
14
14
|
import { pointAnswerCommand, renderHuman, renderJson } from "../../op/local-output";
|
|
15
15
|
import { loadPlugins } from "../plugins";
|
|
16
16
|
import { recordGateApproval } from "./operator";
|
|
@@ -26,11 +26,15 @@ import { LIFECYCLE_LOCAL_NOTE, isLifecycleLocalNote } from "../../lifecycle/loca
|
|
|
26
26
|
import { ledgerRecordingOff, noRecordEndNote, noRecordStartNote, resetNoRecordLedger, NO_RECORD_ENV } from "../../lifecycle/no-record";
|
|
27
27
|
import { renderDriverHuman, renderDriverJson } from "../../components/driver-output";
|
|
28
28
|
import { ndjsonProgressSink } from "../../components/run-progress";
|
|
29
|
+
import { findStoredRun, readRunEvents } from "../../run-event-store";
|
|
30
|
+
import type { RunEvent } from "../../run-event";
|
|
31
|
+
import { openCliRunEvents, refusesBothStreams, stdoutLine } from "../run-events";
|
|
29
32
|
import { maybeRecordAutoRelease } from "../../components/auto-release";
|
|
30
33
|
import { maybePersistBuildManifest } from "../../components/manifest-persistence";
|
|
31
34
|
import type { DriverComponentResult } from "../../components/driver";
|
|
32
|
-
import { isComponentList, type ComponentRunPlan } from "../../components/cli-support";
|
|
33
|
-
import type
|
|
35
|
+
import { isComponentList, type ComponentRunPlan, type RunComponentsResult } from "../../components/cli-support";
|
|
36
|
+
import { resolveCiRun, type ReleaseRecord, type RunOrigin } from "../../lifecycle/release-ledger";
|
|
37
|
+
import { gateAdmission, gateApprover } from "../../components/promote";
|
|
34
38
|
import { runOpGenerate } from "./run-generate";
|
|
35
39
|
|
|
36
40
|
/**
|
|
@@ -460,6 +464,85 @@ async function runOpLogOnRuntime(ctx: CommandContext, name: string): Promise<num
|
|
|
460
464
|
return 0;
|
|
461
465
|
}
|
|
462
466
|
|
|
467
|
+
// ── chant run events <run> ───────────────────────────────────────────────────
|
|
468
|
+
|
|
469
|
+
/** One event as a line for a person: its time, its type, where it is and how it ended. */
|
|
470
|
+
export function humanRunEventLine(e: RunEvent): string {
|
|
471
|
+
const x = e as unknown as Record<string, unknown>;
|
|
472
|
+
const where = [x.component, x.phase, x.step].filter((v): v is string => typeof v === "string").join("/");
|
|
473
|
+
const detail = [where, typeof x.status === "string" ? x.status : "", typeof x.error === "string" ? x.error : ""].filter(Boolean).join(" ");
|
|
474
|
+
return `${String(x.at ?? "")} ${String(x.type).padEnd(16)}${detail}`.trimEnd();
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/** The exit code a run's verdict maps to: `chant run`'s own (0 ok, 1 failed, 3 waiting on a person). */
|
|
478
|
+
function exitOfSettle(status: unknown): number {
|
|
479
|
+
return status === "ok" ? 0 : status === "gated" || status === "waiting" ? 3 : 1;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* `chant run events <run> [--json] [--follow]` (#4042): the events a run on
|
|
484
|
+
* this host kept, replayed. `<run>` is a run id, or the name of an Op or a
|
|
485
|
+
* component selection, for which the newest stored run stands. A settled run
|
|
486
|
+
* and a run in progress both replay what is in the file; `--follow` goes on
|
|
487
|
+
* from there until the run settles. `--json` prints the stored lines as they
|
|
488
|
+
* were written; without it each event is one line for a person.
|
|
489
|
+
*
|
|
490
|
+
* The exit code is the replayed run's verdict (0, 1, or 3 for a run waiting
|
|
491
|
+
* on a person). A replay of a run still going, and a follow cut short by
|
|
492
|
+
* Ctrl-C, exit 0.
|
|
493
|
+
*/
|
|
494
|
+
export async function runOpEvents(ctx: CommandContext): Promise<number> {
|
|
495
|
+
const ref = ctx.args.extraPositional;
|
|
496
|
+
if (!ref) {
|
|
497
|
+
console.error(formatError({ message: "A run id or an Op name is required: chant run events <run>" }));
|
|
498
|
+
return 1;
|
|
499
|
+
}
|
|
500
|
+
if (ctx.args.on !== undefined && ctx.args.on !== "local") {
|
|
501
|
+
console.error(formatError({
|
|
502
|
+
message: `run events reads the events kept on this host, so --on ${ctx.args.on} has none to read`,
|
|
503
|
+
hint: "A run hosted off this host is read once its in-flight state is off-host (#3990).",
|
|
504
|
+
}));
|
|
505
|
+
return 1;
|
|
506
|
+
}
|
|
507
|
+
const cwd = resolve(".");
|
|
508
|
+
let stored = await findStoredRun(cwd, ref);
|
|
509
|
+
if (!stored && ctx.args.follow) {
|
|
510
|
+
// The run may be starting: give it a moment to open its file.
|
|
511
|
+
const deadline = Date.now() + RUN_EVENTS_WAIT_MS;
|
|
512
|
+
while (!stored && Date.now() < deadline) {
|
|
513
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
514
|
+
stored = await findStoredRun(cwd, ref);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if (!stored) {
|
|
518
|
+
console.error(formatError({
|
|
519
|
+
message: `No events are kept for "${ref}" on this host`,
|
|
520
|
+
hint: "A run keeps its events when it records to the ledger (not under --no-record), and a command other than `chant run <op>` keeps them under --events-json. Chant 0.124.28 and newer write them.",
|
|
521
|
+
}));
|
|
522
|
+
return 1;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
const controller = new AbortController();
|
|
526
|
+
const onSigint = () => controller.abort();
|
|
527
|
+
process.on("SIGINT", onSigint);
|
|
528
|
+
try {
|
|
529
|
+
const settle = await readRunEvents(
|
|
530
|
+
stored.file,
|
|
531
|
+
(event, line) => {
|
|
532
|
+
if (ctx.args.json) process.stdout.write(line);
|
|
533
|
+
else console.log(humanRunEventLine(event));
|
|
534
|
+
},
|
|
535
|
+
{ follow: ctx.args.follow === true, signal: controller.signal },
|
|
536
|
+
);
|
|
537
|
+
return settle ? exitOfSettle((settle as unknown as { status?: unknown }).status) : 0;
|
|
538
|
+
} finally {
|
|
539
|
+
process.removeListener("SIGINT", onSigint);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/** How long `--follow` waits for a run's file to appear. */
|
|
544
|
+
const RUN_EVENTS_WAIT_MS = 5000;
|
|
545
|
+
|
|
463
546
|
// ── chant run approve <op> <gate> ────────────────────────────────────────────
|
|
464
547
|
|
|
465
548
|
/**
|
|
@@ -778,6 +861,7 @@ export async function runOp(ctx: CommandContext): Promise<number> {
|
|
|
778
861
|
}));
|
|
779
862
|
return 1;
|
|
780
863
|
}
|
|
864
|
+
if (refusesBothStreams(ctx.args)) return 1;
|
|
781
865
|
if (ctx.args.components) return runOpComponents(ctx);
|
|
782
866
|
if (ctx.args.report) {
|
|
783
867
|
console.error(formatError({
|
|
@@ -791,6 +875,16 @@ export async function runOp(ctx: CommandContext): Promise<number> {
|
|
|
791
875
|
|
|
792
876
|
// ── Auto-release recording post-run (#597) ──────────────────────────────────
|
|
793
877
|
|
|
878
|
+
/**
|
|
879
|
+
* The run id and origin an auto-recorded release names (#4020): the CI run
|
|
880
|
+
* when the process is in CI, so the release and the gate it passed (which
|
|
881
|
+
* records the CI run id) name the same run, else `localId` with the `local`
|
|
882
|
+
* origin.
|
|
883
|
+
*/
|
|
884
|
+
export function autoReleaseRun(localId: string): { runId: string; runOrigin: RunOrigin } {
|
|
885
|
+
return resolveCiRun() ?? { runId: localId, runOrigin: { forge: "local" } };
|
|
886
|
+
}
|
|
887
|
+
|
|
794
888
|
/**
|
|
795
889
|
* After a successful `chant run --components` (local executor), auto-emit
|
|
796
890
|
* one release record per successfully deployed component that published a
|
|
@@ -831,6 +925,7 @@ export async function recordAutoReleasesForRun(
|
|
|
831
925
|
env: string,
|
|
832
926
|
runId: string,
|
|
833
927
|
disabled: boolean,
|
|
928
|
+
runOrigin: RunOrigin = { forge: "local" },
|
|
834
929
|
): Promise<ReleaseRecord[]> {
|
|
835
930
|
const recorded: ReleaseRecord[] = [];
|
|
836
931
|
for (const componentResult of results) {
|
|
@@ -842,8 +937,11 @@ export async function recordAutoReleasesForRun(
|
|
|
842
937
|
success: true,
|
|
843
938
|
records: componentResult.records,
|
|
844
939
|
runId,
|
|
845
|
-
// A local-executor id resolves nowhere
|
|
846
|
-
runOrigin
|
|
940
|
+
// A local-executor id resolves nowhere, and says so in a field (#2045). A run in CI names the CI run.
|
|
941
|
+
runOrigin,
|
|
942
|
+
// #1035, #4020: who approved at the gate and which resolution admitted the deploy.
|
|
943
|
+
...(gateApprover(componentResult) ? { approver: gateApprover(componentResult) } : {}),
|
|
944
|
+
...(gateAdmission(componentResult) ? { admission: gateAdmission(componentResult) } : {}),
|
|
847
945
|
},
|
|
848
946
|
{ disabled },
|
|
849
947
|
);
|
|
@@ -1011,6 +1109,10 @@ async function runComponentSelection(ctx: CommandContext): Promise<number> {
|
|
|
1011
1109
|
// `undefined` and every `onProgress?.(...)` call in the driver is a no-op —
|
|
1012
1110
|
// behavior is byte-for-byte unchanged from before this flag existed.
|
|
1013
1111
|
const onProgress = ctx.args.progressJson ? ndjsonProgressSink() : undefined;
|
|
1112
|
+
// `--events-json` (#4041): the run-event stream instead. The run is named by
|
|
1113
|
+
// the id its release records carry, so the two join.
|
|
1114
|
+
const release = autoReleaseRun(`local-${Date.now()}`);
|
|
1115
|
+
const events = await openCliRunEvents(ctx.args, { kind: "component", name: selector, runId: release.runId, cwd: projectPath });
|
|
1014
1116
|
// A list (#3950) pulls in what its components depend on; say which ones and
|
|
1015
1117
|
// in what order before the first one runs. stderr, so --json and
|
|
1016
1118
|
// --progress-json keep stdout to themselves.
|
|
@@ -1020,14 +1122,25 @@ async function runComponentSelection(ctx: CommandContext): Promise<number> {
|
|
|
1020
1122
|
if (plan.added.length > 0) console.error(formatInfo(`added as dependencies: ${plan.added.join(", ")}`));
|
|
1021
1123
|
}
|
|
1022
1124
|
: undefined;
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1125
|
+
let result: RunComponentsResult;
|
|
1126
|
+
try {
|
|
1127
|
+
result = await runtime.runComponents(projectPath, selector, {
|
|
1128
|
+
env: ctx.args.env,
|
|
1129
|
+
componentOutputs: seededOutputs,
|
|
1130
|
+
onProgress,
|
|
1131
|
+
...(events ? { onRunEvent: events.emit } : {}),
|
|
1132
|
+
sandbox: ctx.args.sandbox,
|
|
1133
|
+
buildParams: paramsResolution.provenance,
|
|
1134
|
+
...(onPlan ? { onPlan } : {}),
|
|
1135
|
+
});
|
|
1136
|
+
} catch (err) {
|
|
1137
|
+
events?.settle("failed", err instanceof Error ? err.message : String(err));
|
|
1138
|
+
throw err;
|
|
1139
|
+
}
|
|
1140
|
+
// A run that never reached its components (a bad selector, a cycle) still ends its stream.
|
|
1141
|
+
if (result.success) events?.settle("ok");
|
|
1142
|
+
else if (result.gated) events?.settle("gated");
|
|
1143
|
+
else events?.settle("failed", result.error);
|
|
1031
1144
|
|
|
1032
1145
|
// Dump the accumulated outputs for a downstream job to seed from. Written
|
|
1033
1146
|
// even on failure (partial outputs) so a resumed run still has what completed.
|
|
@@ -1094,7 +1207,7 @@ async function runComponentSelection(ctx: CommandContext): Promise<number> {
|
|
|
1094
1207
|
if (result.success && result.run) {
|
|
1095
1208
|
// #3955: a run that records nothing has no release to report either.
|
|
1096
1209
|
const disabled = resolveAutoReleaseDisabled(config, ctx.args.noReleaseRecord) || ledgerRecordingOff();
|
|
1097
|
-
const recorded = await recordAutoReleasesForRun(result.run.results, env,
|
|
1210
|
+
const recorded = await recordAutoReleasesForRun(result.run.results, env, release.runId, disabled, release.runOrigin);
|
|
1098
1211
|
// `--digest-file` (#2602): the releases this run recorded, one
|
|
1099
1212
|
// `<component>=<digest>` line each, the form `chant components promote
|
|
1100
1213
|
// --digest` takes. A generated promote job reads it to promote exactly
|
|
@@ -1182,6 +1295,15 @@ async function runOpOnResolvedRuntime(ctx: CommandContext): Promise<number> {
|
|
|
1182
1295
|
return 1;
|
|
1183
1296
|
}
|
|
1184
1297
|
|
|
1298
|
+
// #4044: a runner key signs the run's record as it settles, so `ci tick`
|
|
1299
|
+
// can count the run. `--key` must be a runner key; the PEM in
|
|
1300
|
+
// CHANT_RUNNER_KEY that is not one leaves the run unsigned, with a warning.
|
|
1301
|
+
const signRecord = await runSignerFor(ctx);
|
|
1302
|
+
if (signRecord === null) {
|
|
1303
|
+
await stewardGate?.release?.();
|
|
1304
|
+
return 1;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1185
1307
|
// `--progress-json` streams one NDJSON StepRecord per settled step, fed by
|
|
1186
1308
|
// whatever the runtime reports through `progress`.
|
|
1187
1309
|
const progress = ctx.args.progressJson ? ndjsonProgressSink<StepRecord>() : undefined;
|
|
@@ -1217,6 +1339,10 @@ async function runOpOnResolvedRuntime(ctx: CommandContext): Promise<number> {
|
|
|
1217
1339
|
...(params ? { params } : {}),
|
|
1218
1340
|
...(ctx.args.profile !== undefined ? { profile: ctx.args.profile } : {}),
|
|
1219
1341
|
progress,
|
|
1342
|
+
// `--events-json` (#4041): the runtime writes the run's events itself,
|
|
1343
|
+
// since it is the one that knows the run's id and where it ran.
|
|
1344
|
+
...(ctx.args.eventsJson ? { runEvents: stdoutLine } : {}),
|
|
1345
|
+
...(signRecord ? { signRecord } : {}),
|
|
1220
1346
|
signal: controller.signal,
|
|
1221
1347
|
...(work ? { work } : {}),
|
|
1222
1348
|
});
|
|
@@ -1362,7 +1488,42 @@ async function resolveRunWork(
|
|
|
1362
1488
|
export function runOpUnknown(ctx: CommandContext): Promise<number> {
|
|
1363
1489
|
console.error(formatError({
|
|
1364
1490
|
message: `Unknown run subcommand: ${ctx.args.extraPositional ?? ctx.args.path}`,
|
|
1365
|
-
hint: "Available: chant run <name>, run list, run status, run approve, run cancel, run log",
|
|
1491
|
+
hint: "Available: chant run <name>, run list, run status, run approve, run cancel, run log, run events",
|
|
1366
1492
|
}));
|
|
1367
1493
|
return Promise.resolve(1);
|
|
1368
1494
|
}
|
|
1495
|
+
|
|
1496
|
+
/** The variable a runner key is read from, as PEM, as `chant ci tick` reads it (`RUNNER_KEY_ENV` in ../../workspace/ci-green.ts). */
|
|
1497
|
+
const RUNNER_KEY_ENV = "CHANT_RUNNER_KEY";
|
|
1498
|
+
|
|
1499
|
+
/**
|
|
1500
|
+
* What signs the run's record (#4044): the runner key `--key` names, or the
|
|
1501
|
+
* PEM in `CHANT_RUNNER_KEY`, checked against `.chant/trust.json` at `HEAD`.
|
|
1502
|
+
* Undefined when neither is given. Null, after printing why, when `--key`
|
|
1503
|
+
* is not a runner key; an unusable `CHANT_RUNNER_KEY` only warns, since the
|
|
1504
|
+
* variable may be set for `ci tick` in a job that also runs Ops.
|
|
1505
|
+
*/
|
|
1506
|
+
async function runSignerFor(ctx: CommandContext): Promise<((record: OpRunRecord) => NonNullable<OpRunRecord["statement"]>) | undefined | null> {
|
|
1507
|
+
const fromFlag = ctx.args.key !== undefined;
|
|
1508
|
+
let pem: string | undefined;
|
|
1509
|
+
try {
|
|
1510
|
+
pem = fromFlag ? readFileSync(resolve(ctx.args.key!), "utf-8") : process.env[RUNNER_KEY_ENV] || undefined;
|
|
1511
|
+
} catch (err) {
|
|
1512
|
+
console.error(formatError({ message: `--key ${ctx.args.key}: ${err instanceof Error ? err.message : String(err)}` }));
|
|
1513
|
+
return null;
|
|
1514
|
+
}
|
|
1515
|
+
if (pem === undefined) return undefined;
|
|
1516
|
+
try {
|
|
1517
|
+
// Loaded only when a key is given, so a run without one loads no workspace code (level 0, #2525).
|
|
1518
|
+
const { opRunSigner } = await import("../../workspace/ci-green");
|
|
1519
|
+
return opRunSigner(process.cwd(), pem);
|
|
1520
|
+
} catch (err) {
|
|
1521
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1522
|
+
if (fromFlag) {
|
|
1523
|
+
console.error(formatError({ message: `the run would not be signed: ${message}` }));
|
|
1524
|
+
return null;
|
|
1525
|
+
}
|
|
1526
|
+
console.error(formatWarning({ message: `${RUNNER_KEY_ENV} is set, and the run will not be signed: ${message}` }));
|
|
1527
|
+
return undefined;
|
|
1528
|
+
}
|
|
1529
|
+
}
|
package/src/cli/main.test.ts
CHANGED
|
@@ -16,6 +16,13 @@ describe("parseArgs", () => {
|
|
|
16
16
|
expect(() => parseArgs(["graph", "--traffic"])).toThrow(/--traffic needs a level/);
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
test("--before-script is repeatable and keeps its order; --image takes a reference (#4002)", () => {
|
|
20
|
+
const args = parseArgs(["build", "--components", "--generate", "forgejo", "--image", "node:22-bookworm", "--before-script", "npm ci", "--before-script", "-x"]);
|
|
21
|
+
expect(args.image).toBe("node:22-bookworm");
|
|
22
|
+
expect(args.beforeScript).toEqual(["npm ci", "-x"]);
|
|
23
|
+
expect(() => parseArgs(["build", "--before-script"])).toThrow(/--before-script needs a shell line/);
|
|
24
|
+
});
|
|
25
|
+
|
|
19
26
|
test("--skip-undeclarable reaches live import (#3911)", () => {
|
|
20
27
|
expect(parseArgs(["import", "--from", "prod"]).skipUndeclarable).toBeUndefined();
|
|
21
28
|
expect(parseArgs(["import", "--from", "prod", "--skip-undeclarable"]).skipUndeclarable).toBe(true);
|
package/src/cli/main.ts
CHANGED
|
@@ -114,6 +114,7 @@ const runOpApprove = lazyHandler(runHandlers, (m) => m.runOpApprove);
|
|
|
114
114
|
const runOpSignalRenamed = lazyHandler(runHandlers, (m) => m.runOpSignalRenamed);
|
|
115
115
|
const runOpCancel = lazyHandler(runHandlers, (m) => m.runOpCancel);
|
|
116
116
|
const runOpLog = lazyHandler(runHandlers, (m) => m.runOpLog);
|
|
117
|
+
const runOpEvents = lazyHandler(runHandlers, (m) => m.runOpEvents);
|
|
117
118
|
const runWaveHandlers = () => import("./handlers/run-wave");
|
|
118
119
|
const runOpWaveCommand = lazyHandler(runWaveHandlers, (m) => m.runOpWaveCommand);
|
|
119
120
|
const operatorHandlers = () => import("./handlers/operator");
|
|
@@ -227,22 +228,61 @@ Commands:
|
|
|
227
228
|
applied) and path. Read-only.
|
|
228
229
|
|
|
229
230
|
CI:
|
|
230
|
-
ci last-green [--json] The newest first-parent commit of
|
|
231
|
-
|
|
232
|
-
tags only; fetch
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
231
|
+
ci last-green [--json] [--from <rev>] The newest first-parent commit of
|
|
232
|
+
ci.green's branch, or of --from, with a ci/green tag
|
|
233
|
+
and no ci/revoked tag. Reads local tags only; fetch
|
|
234
|
+
them first. With ci.green.signedSince, a tag without a
|
|
235
|
+
valid runner statement is ignored and reported.
|
|
236
|
+
ci list [--json] [--limit <n>] [--since <rev>] [--forge github] [--source checks|runs]
|
|
237
|
+
The first-parent commits of ci.green's branch within
|
|
238
|
+
its window, newest first, each green, revoked or
|
|
239
|
+
undecided with its required phases' results. Reads
|
|
240
|
+
local tags; --forge reads check runs for undecided
|
|
241
|
+
commits, and source runs reads the signed Op runs on
|
|
242
|
+
the local chant/lifecycle. --since replaces the window.
|
|
243
|
+
ci tick [--dry-run] [--forge github] [--source checks|runs] [--key <runner key.pem>]
|
|
244
|
+
Tag each commit within ci.green's window whose
|
|
245
|
+
required phases all passed ci/green/<sha>, and revoke
|
|
246
|
+
a green one that now fails ci/revoked/<sha>. Reads
|
|
247
|
+
check runs from the forge, or with source runs
|
|
248
|
+
(ci.green.source or --source) the Op runs on
|
|
249
|
+
chant/lifecycle that a runner key signed. Pushes the
|
|
250
|
+
tags. --key, or the PEM in CHANT_RUNNER_KEY, signs
|
|
251
|
+
each tag with a runner key.
|
|
237
252
|
ci workflow [--workflow <name>]... [--output <file>] Write
|
|
238
253
|
[--chant <command>] [--install <command>]
|
|
239
254
|
[--token-secret <NAME> | --app-id-var <VAR> --app-key-secret <NAME>]
|
|
255
|
+
[--runner-key-secret <NAME>]
|
|
240
256
|
.github/workflows/chant-ci-green.yml, which runs the
|
|
241
257
|
tick when a required workflow completes and every 15m.
|
|
242
258
|
--chant replaces the npx @intentius/chant pin the tick
|
|
243
259
|
runs; --install adds a step before it. --token-secret,
|
|
244
260
|
or a GitHub App's id and key, pushes the tags with a
|
|
245
261
|
token that may tag commits changing workflow files.
|
|
262
|
+
--runner-key-secret hands the tick the runner key it
|
|
263
|
+
signs its tags with.
|
|
264
|
+
|
|
265
|
+
Releases:
|
|
266
|
+
release cut [<label>] [--build <command>] [--param <k=v>] [--params-file <file>]
|
|
267
|
+
[--src <dir>] [-o <file>] [--lexicon <name>] [--sign [<key file>]]
|
|
268
|
+
Cut a release of this member from HEAD, which must
|
|
269
|
+
carry a ci/green tag: compile every environment in
|
|
270
|
+
the config's environments, build the artifacts once,
|
|
271
|
+
and store it on chant/lifecycle under its digest.
|
|
272
|
+
--build runs before each environment's templates are
|
|
273
|
+
read, with CHANT_ENV set; {env} in --params-file is
|
|
274
|
+
replaced by the environment. --sign signs the cut with
|
|
275
|
+
the actor's ssh key; an identity.gates release entry
|
|
276
|
+
requires it. A project with no components releases
|
|
277
|
+
what chant build --env <env> writes: --src <dir> is
|
|
278
|
+
the build root, -o <file> the output (dist/build.yaml),
|
|
279
|
+
--lexicon narrows it.
|
|
280
|
+
release list [--json] Every release of this member with its targets, its
|
|
281
|
+
cuts and the environments that run it.
|
|
282
|
+
release export <label|digest> --env <env> [-o <dir>] [--json]
|
|
283
|
+
Write the files the release recorded for <env>, each
|
|
284
|
+
checked against its digest, at their recorded paths
|
|
285
|
+
under <dir> (default: here), for a deploy to read.
|
|
246
286
|
|
|
247
287
|
Change sets:
|
|
248
288
|
change-set summary <file> The grouped plan summary of a change-set
|
|
@@ -251,6 +291,10 @@ Change sets:
|
|
|
251
291
|
replacement, failure and hole named.
|
|
252
292
|
markdown fits an MR/PR note of --limit
|
|
253
293
|
characters (default 65536). Read-only.
|
|
294
|
+
change-set show <digest> The change set a pull-request or release gate
|
|
295
|
+
[--member <name>] [--json] bound, stored on
|
|
296
|
+
chant/lifecycle under its digest, each
|
|
297
|
+
entry with its graph node. Read-only.
|
|
254
298
|
|
|
255
299
|
Ops:
|
|
256
300
|
run <name> Run an Op on the resolved runtime (--on; local by default)
|
|
@@ -260,11 +304,18 @@ Ops:
|
|
|
260
304
|
its Drift outcome is true (WatchOp failOn: "drift")
|
|
261
305
|
--no-record: a test run that records nothing on
|
|
262
306
|
chant/lifecycle and pushes nothing (local runtime)
|
|
307
|
+
--key <runner key.pem>, or the PEM in
|
|
308
|
+
CHANT_RUNNER_KEY: sign the run's record with a runner
|
|
309
|
+
key, so ci tick from runs counts it (#4044)
|
|
263
310
|
run list List all Ops with the runtime's state for each
|
|
264
311
|
run status <name> Show the runtime's state for one Op's latest run
|
|
265
312
|
run approve <op> <gate> Record a gate's resolution and wake the runtime
|
|
266
313
|
run cancel <name> Cancel the active run (requires --force)
|
|
267
314
|
run log <name> Show run history for an Op
|
|
315
|
+
run events <run> Replay a run's events kept on this host (a run id, or
|
|
316
|
+
an Op or component name for its newest run). --json
|
|
317
|
+
prints the run-event lines; --follow streams a run in
|
|
318
|
+
progress until run-settle (#4042)
|
|
268
319
|
run wave --spec <file> --wave <k> Plan, gate and apply wave k of an Op
|
|
269
320
|
waves spec (#3679): the job a generated waves
|
|
270
321
|
pipeline runs. --decide plans and decides only;
|
|
@@ -299,6 +350,11 @@ Ops:
|
|
|
299
350
|
consumer to render live wave/component/phase/step
|
|
300
351
|
progress instead of tailing raw logs (additive; run
|
|
301
352
|
semantics/exit code unchanged)
|
|
353
|
+
--events-json: stream the run's events instead, one
|
|
354
|
+
run-event.schema.json line each, with the run id,
|
|
355
|
+
commit and runtime on every line (#4041). Also on
|
|
356
|
+
run <op>, components promote|rollback|redeploy,
|
|
357
|
+
fan-out, pr-plan and pr-apply
|
|
302
358
|
operator Run scheduled ticks for discovered ConvergeOps
|
|
303
359
|
locally (#1485): acquire/renew a per-op
|
|
304
360
|
lease (git ref CAS), tick on --interval, record every
|
|
@@ -664,7 +720,13 @@ Workspace (level 1, #2524):
|
|
|
664
720
|
the severity (warn by default) and ignore globs. When
|
|
665
721
|
the declaration at base has writeScope or agents, each
|
|
666
722
|
commit that writes outside its writer's scope fails
|
|
667
|
-
the check (write-scope-member, write-scope-kind)
|
|
723
|
+
the check (write-scope-member, write-scope-kind). Each
|
|
724
|
+
first-parent commit of the range should name its work
|
|
725
|
+
item in a Chant-Record: <work kind>:<id> or a
|
|
726
|
+
Chant-Lease trailer. commit-unlinked is a commit that
|
|
727
|
+
names none, commit-wrongly-linked one whose trailers
|
|
728
|
+
name no work item that exists; both follow the
|
|
729
|
+
severity
|
|
668
730
|
workspace patch <base>..<head>|<base>...<head>|<commit> [--path <p>...] [--max-bytes <n>] [--json]
|
|
669
731
|
workspace patch [<commit>] --worktree [--path <p>...] [--max-bytes <n>] [--json]
|
|
670
732
|
The hunks of a diff, file by file: a range, a work
|
|
@@ -787,9 +849,12 @@ Component release ledger + status:
|
|
|
787
849
|
byte-for-byte plus a self-describing manifest.json
|
|
788
850
|
components promote Deploy the digests one environment's release
|
|
789
851
|
ledger records to another, without a build
|
|
790
|
-
(--
|
|
791
|
-
[--
|
|
792
|
-
|
|
852
|
+
(--to <env> [--from <env>] [--allow-skip]
|
|
853
|
+
[--release <label|digest>]
|
|
854
|
+
[--component <name> [--digest <sha256:...>]];
|
|
855
|
+
--from defaults to the environment before --to
|
|
856
|
+
in the config's environments; --dry-run prints
|
|
857
|
+
the plan; the target's gates still apply)
|
|
793
858
|
components rollback <env> Redeploy an earlier release of an environment
|
|
794
859
|
from its recorded digest (--component <name>
|
|
795
860
|
[--digest <sha256:...>]; defaults to the release
|
|
@@ -934,7 +999,7 @@ Options:
|
|
|
934
999
|
chant.config.ts's build.sandbox: true; #1045)
|
|
935
1000
|
--param <name=value> (build, graph, run --components, components fan-out,
|
|
936
1001
|
components promote, components rollback,
|
|
937
|
-
components redeploy) Bind a
|
|
1002
|
+
components redeploy, release cut) Bind a
|
|
938
1003
|
declared build-time parameter (chant.config.ts's buildParams)
|
|
939
1004
|
to a value, for source to read as params.<name>
|
|
940
1005
|
(#1064) instead of process.env — repeatable.
|
|
@@ -946,7 +1011,7 @@ Options:
|
|
|
946
1011
|
chant.template.json declares instead (#2627).
|
|
947
1012
|
--params-file <path> (build, graph, run --components, components fan-out,
|
|
948
1013
|
components promote, components rollback,
|
|
949
|
-
components redeploy) JSON file
|
|
1014
|
+
components redeploy, release cut) JSON file
|
|
950
1015
|
of { "name": value } build-time parameter values
|
|
951
1016
|
(#1064). Second precedence, after --param.
|
|
952
1017
|
init --from refuses it: pass --param instead.
|
|
@@ -1195,10 +1260,18 @@ export const commandRegistry: CommandDef[] = [
|
|
|
1195
1260
|
{ name: "carve status", handler: runCarveStatus },
|
|
1196
1261
|
// #3573 — which commits passed CI, kept as ci/green and ci/revoked tags (ws-103). Imported on first use.
|
|
1197
1262
|
{ name: "ci last-green", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/ci-green-cli")).runCiLastGreen(ctx) },
|
|
1263
|
+
{ name: "ci list", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/ci-green-cli")).runCiList(ctx) },
|
|
1198
1264
|
{ name: "ci tick", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/ci-green-cli")).runCiTick(ctx) },
|
|
1199
1265
|
{ name: "ci workflow", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/ci-green-cli")).runCiWorkflow(ctx) },
|
|
1266
|
+
// #4026: the release cut from a green commit (ws-104). Imported on first use.
|
|
1267
|
+
{ name: "release cut", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/release")).runReleaseCut(ctx) },
|
|
1268
|
+
{ name: "release list", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/release")).runReleaseList(ctx) },
|
|
1269
|
+
{ name: "release export", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/release")).runReleaseExport(ctx) },
|
|
1270
|
+
{ name: "release compile", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/release")).runReleaseCompile(ctx) },
|
|
1200
1271
|
// #3188 — the grouped plan summary of a change-set document. Reads one file; imported on first use.
|
|
1201
1272
|
{ name: "change-set summary", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/change-set")).runChangeSetSummary(ctx) },
|
|
1273
|
+
// #4022: the change set a gate bound, read from chant/lifecycle by its digest.
|
|
1274
|
+
{ name: "change-set show", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/change-set")).runChangeSetShow(ctx) },
|
|
1202
1275
|
{ name: "init", handler: runInit, runsNoConfig: true },
|
|
1203
1276
|
{ name: "init lexicon", handler: runInitLexicon },
|
|
1204
1277
|
{ name: "update", handler: runUpdate },
|
|
@@ -1220,6 +1293,7 @@ export const commandRegistry: CommandDef[] = [
|
|
|
1220
1293
|
{ name: "run signal", handler: runOpSignalRenamed },
|
|
1221
1294
|
{ name: "run cancel", handler: runOpCancel },
|
|
1222
1295
|
{ name: "run log", handler: runOpLog },
|
|
1296
|
+
{ name: "run events", handler: runOpEvents },
|
|
1223
1297
|
{ name: "run wave", handler: runOpWaveCommand },
|
|
1224
1298
|
// #3683 — start the CI jobs that wait at gates whose approval arrived. Imported on first use.
|
|
1225
1299
|
{ name: "run resume", handler: async (ctx) => (await import("./handlers/gate-resume")).runResumeCommand(ctx) },
|
|
@@ -1335,6 +1409,7 @@ export const commandRegistry: CommandDef[] = [
|
|
|
1335
1409
|
{ name: "dev", handler: runDevUnknown },
|
|
1336
1410
|
{ name: "serve", handler: runServeUnknown },
|
|
1337
1411
|
{ name: "components", handler: runComponentsUnknown },
|
|
1412
|
+
{ name: "release", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/release")).runReleaseUnknown(ctx) },
|
|
1338
1413
|
{ name: "workspace", handler: async (ctx) => (await import("../workspace/records-cli")).runWorkspaceUnknown(ctx) },
|
|
1339
1414
|
];
|
|
1340
1415
|
|
|
@@ -217,6 +217,8 @@ describe("neverOverMcp (chant#3447)", () => {
|
|
|
217
217
|
const gateOnlyOps: Array<{ op: string; gate: string }> = [
|
|
218
218
|
{ op: "workspace-upgrade", gate: "." },
|
|
219
219
|
{ op: "pr-12", gate: "pr-apply" },
|
|
220
|
+
// #4045: a release gate approves a change to an environment, as a pull request's does.
|
|
221
|
+
{ op: "release", gate: "prod-release" },
|
|
220
222
|
];
|
|
221
223
|
|
|
222
224
|
for (const { op, gate } of gateOnlyOps) {
|
|
@@ -126,7 +126,7 @@ export const workspaceReadTools: ToolDefinition[] = [
|
|
|
126
126
|
{
|
|
127
127
|
name: "workspace-changes",
|
|
128
128
|
description:
|
|
129
|
-
"The forward coverage check over a diff: chant workspace check --changes <range> --json (changes.schema.json, #2773). Each changed path with the current records whose constrains cover it, and a change-uncovered or change-out-of-scope finding for each gap, at the severity the declaration's changes block sets. Returns the document unchanged.",
|
|
129
|
+
"The forward coverage check over a diff: chant workspace check --changes <range> --json (changes.schema.json, #2773). Each changed path with the current records whose constrains cover it, and a change-uncovered or change-out-of-scope finding for each gap, at the severity the declaration's changes block sets. links says whether each trunk commit of the range names its work item, with commit-unlinked and commit-wrongly-linked findings at the same severity. Returns the document unchanged.",
|
|
130
130
|
inputSchema: {
|
|
131
131
|
type: "object",
|
|
132
132
|
properties: {
|
package/src/cli/parse-args.ts
CHANGED
|
@@ -48,6 +48,8 @@ const BOOLEAN_FLAGS = new Set([
|
|
|
48
48
|
"--local",
|
|
49
49
|
"--json",
|
|
50
50
|
"--progress-json",
|
|
51
|
+
"--events-json",
|
|
52
|
+
"--follow",
|
|
51
53
|
"--update-snapshot",
|
|
52
54
|
"--update-baseline",
|
|
53
55
|
"--run-examples",
|
|
@@ -71,11 +73,13 @@ const BOOLEAN_FLAGS = new Set([
|
|
|
71
73
|
"--current",
|
|
72
74
|
"--uncommitted",
|
|
73
75
|
"--allow-code",
|
|
76
|
+
"--allow-skip",
|
|
74
77
|
"--root-only",
|
|
75
78
|
"--generated",
|
|
76
79
|
"--decide",
|
|
77
80
|
"--record-plans",
|
|
78
81
|
"--loopback",
|
|
82
|
+
"--artifacts",
|
|
79
83
|
]);
|
|
80
84
|
|
|
81
85
|
/**
|
|
@@ -191,8 +195,9 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
191
195
|
result.overlayAnchor = v;
|
|
192
196
|
} else if (arg === "--from") {
|
|
193
197
|
// Shared by `migrate --from <lexicon>`, `import --from <env>`,
|
|
194
|
-
// `components promote --from <env
|
|
195
|
-
//
|
|
198
|
+
// `components promote --from <env>`, `init --from <repo>@<ref>` and
|
|
199
|
+
// `ci last-green --from <rev>` (#4031); the commands never run
|
|
200
|
+
// together, so one field carries all five.
|
|
196
201
|
result.migrateFrom = args[++i];
|
|
197
202
|
} else if (arg === "--kustomize") {
|
|
198
203
|
// `chant import --kustomize <dir>` (#1548): render the overlay, import
|
|
@@ -372,6 +377,10 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
372
377
|
result.requireReview = true;
|
|
373
378
|
} else if (arg === "--pr-loop") {
|
|
374
379
|
result.prLoop = true;
|
|
380
|
+
} else if (arg === "--before-script") {
|
|
381
|
+
const line = args[++i];
|
|
382
|
+
if (line === undefined || line === "") throw new Error("--before-script needs a shell line: --before-script '<line>'");
|
|
383
|
+
(result.beforeScript ??= []).push(line);
|
|
375
384
|
} else if (arg === "--resume") {
|
|
376
385
|
// `chant approve <op> <gate> --resume` (#3683) takes no value; the
|
|
377
386
|
// fan-out and pull-request apply take the attempt file they resume.
|
|
@@ -384,6 +393,11 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
384
393
|
result.json = true;
|
|
385
394
|
} else if (arg === "--progress-json") {
|
|
386
395
|
result.progressJson = true;
|
|
396
|
+
} else if (arg === "--events-json") {
|
|
397
|
+
result.eventsJson = true;
|
|
398
|
+
} else if (arg === "--follow") {
|
|
399
|
+
// `chant run events <run> --follow` (#4042): tail a run in progress on this host.
|
|
400
|
+
result.follow = true;
|
|
387
401
|
} else if (arg === "--gated-exit") {
|
|
388
402
|
// `chant run <op> --gated-exit <code>` (#2243) — remap only the gated
|
|
389
403
|
// outcome's exit code. Parsed as a number here and range-checked in the
|
|
@@ -502,6 +516,10 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
502
516
|
} else if (arg === "--app-key-secret") {
|
|
503
517
|
result.ciAppKeySecret = args[++i];
|
|
504
518
|
if (!result.ciAppKeySecret || result.ciAppKeySecret.startsWith("-")) throw new Error("--app-key-secret needs the secret holding the App's private key: --app-key-secret <NAME>");
|
|
519
|
+
} else if (arg === "--runner-key-secret") {
|
|
520
|
+
// `chant ci workflow --runner-key-secret <NAME>` (#4031): the secret holding the runner key the tick signs its tags with.
|
|
521
|
+
result.ciRunnerKeySecret = args[++i];
|
|
522
|
+
if (!result.ciRunnerKeySecret || result.ciRunnerKeySecret.startsWith("-")) throw new Error("--runner-key-secret needs the repository secret holding the runner key, such as CHANT_RUNNER_KEY: --runner-key-secret <NAME>");
|
|
505
523
|
} else if (arg === "--verdict") {
|
|
506
524
|
// `chant workspace records review <id> --verdict agree|dissent|abstain` (#2670)
|
|
507
525
|
result.verdict = args[++i];
|
|
@@ -588,6 +606,17 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
588
606
|
if (result.digest !== undefined) (result.digests ??= []).push(result.digest);
|
|
589
607
|
} else if (arg === "--release-plan") {
|
|
590
608
|
result.releasePlanFile = args[++i];
|
|
609
|
+
} else if (arg === "--release") {
|
|
610
|
+
// `chant components promote --release <label|digest>` (#4026)
|
|
611
|
+
result.release = args[++i];
|
|
612
|
+
if (!result.release || result.release.startsWith("-")) throw new Error("--release needs a release's label or digest: --release <label|digest>");
|
|
613
|
+
} else if (arg === "--build") {
|
|
614
|
+
// `chant release cut --build <command>` (#4026)
|
|
615
|
+
result.buildCommand = args[++i];
|
|
616
|
+
if (!result.buildCommand) throw new Error("--build needs a shell command: --build '<command>'");
|
|
617
|
+
} else if (arg === "--artifacts") {
|
|
618
|
+
// `chant release compile --artifacts` (#4026, internal)
|
|
619
|
+
result.artifacts = true;
|
|
591
620
|
} else if (arg === "--git-sha") {
|
|
592
621
|
result.gitSha = args[++i];
|
|
593
622
|
} else if (arg === "--run-id") {
|
|
@@ -712,10 +741,15 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
712
741
|
// #2550 — `chant workspace upgrade` runs a template's code migrations
|
|
713
742
|
// only when asked to.
|
|
714
743
|
result.allowCode = true;
|
|
744
|
+
} else if (arg === "--allow-skip") {
|
|
745
|
+
// #4030 — `chant components promote` skips a step of the member's
|
|
746
|
+
// declared promotion order only when asked to.
|
|
747
|
+
result.allowSkip = true;
|
|
715
748
|
} else if (arg === "--source") {
|
|
716
749
|
// #2551 — `chant workspace upgrade --source <repo>[#<member>]`.
|
|
717
750
|
result.source = args[++i];
|
|
718
|
-
|
|
751
|
+
// #4044: also `chant ci tick|list --source checks|runs`.
|
|
752
|
+
if (!result.source || result.source.startsWith("-")) throw new Error("--source needs a template: --source <repo>[#<member>] for workspace upgrade, or a source for ci tick and ci list: --source checks|runs");
|
|
719
753
|
} else if (arg === "--tags") {
|
|
720
754
|
// #2551 — `chant workspace adopt-lineage --tags <glob>`, also hash-index and versions.
|
|
721
755
|
result.tags = args[++i];
|