@intentius/chant 0.102.0 → 0.104.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/core.d.ts +2 -0
- package/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/change-set.d.ts +232 -0
- package/dist/change-set.d.ts.map +1 -0
- package/dist/cli/commands/audit.d.ts +7 -0
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/change-set.d.ts +11 -0
- package/dist/cli/handlers/change-set.d.ts.map +1 -0
- package/dist/cli/handlers/fan-out.d.ts +33 -0
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +7 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/pr.d.ts +31 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -0
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/op-tools.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-tools.d.ts +3 -2
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +63 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/components/auto-release.d.ts +16 -0
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/capability.d.ts +53 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/changed-files.d.ts +31 -0
- package/dist/components/changed-files.d.ts.map +1 -0
- package/dist/components/cli-support.d.ts +9 -1
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/component.d.ts +24 -0
- package/dist/components/component.d.ts.map +1 -1
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/driver.d.ts +13 -0
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/fan-out-output.d.ts +6 -0
- package/dist/components/fan-out-output.d.ts.map +1 -1
- package/dist/components/fan-out-record.d.ts +41 -0
- package/dist/components/fan-out-record.d.ts.map +1 -0
- package/dist/components/fan-out-run.d.ts +65 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-support.d.ts +2 -0
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/fan-out.d.ts +6 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/gated-wave-pipeline.d.ts +50 -0
- package/dist/components/gated-wave-pipeline.d.ts.map +1 -0
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/layers.d.ts +25 -0
- package/dist/components/layers.d.ts.map +1 -0
- package/dist/components/pr-pipeline.d.ts +61 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -0
- package/dist/components/pr-run.d.ts +119 -0
- package/dist/components/pr-run.d.ts.map +1 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/verbs/shell.d.ts.map +1 -1
- package/dist/components/wave-plan.d.ts +49 -0
- package/dist/components/wave-plan.d.ts.map +1 -0
- package/dist/gated-waves.d.ts +147 -0
- package/dist/gated-waves.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lexicon.d.ts +48 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +7 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +46 -1
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lint/post-synth.d.ts +18 -0
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.d.ts +126 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/change-set.d.ts +62 -0
- package/dist/op/activities/change-set.d.ts.map +1 -0
- package/dist/op/activities/decide.d.ts +2 -0
- package/dist/op/activities/decide.d.ts.map +1 -1
- package/dist/op/activities/factory.d.ts +137 -0
- package/dist/op/activities/factory.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +4 -0
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activity-contract.d.ts.map +1 -1
- package/dist/op/builders.d.ts +11 -0
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/decide-backend.d.ts +5 -1
- package/dist/op/decide-backend.d.ts.map +1 -1
- package/dist/op/decide-read-inputs.d.ts +4 -2
- package/dist/op/decide-read-inputs.d.ts.map +1 -1
- package/dist/op/factory.d.ts +83 -0
- package/dist/op/factory.d.ts.map +1 -0
- package/dist/op/index.d.ts +4 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/op-ir.d.ts +2 -0
- package/dist/op/op-ir.d.ts.map +1 -1
- package/dist/op/op-verb-class.d.ts.map +1 -1
- package/dist/op/types.d.ts +8 -0
- package/dist/op/types.d.ts.map +1 -1
- package/dist/op/work-lease-run.d.ts.map +1 -1
- package/dist/plan-summary.d.ts +207 -0
- package/dist/plan-summary.d.ts.map +1 -0
- package/dist/pr-forge.d.ts +105 -0
- package/dist/pr-forge.d.ts.map +1 -0
- package/dist/pr-loop.d.ts +178 -0
- package/dist/pr-loop.d.ts.map +1 -0
- package/dist/telemetry-attribution.d.ts +31 -0
- package/dist/telemetry-attribution.d.ts.map +1 -1
- package/dist/terraform/hcl2json.d.ts +45 -0
- package/dist/terraform/hcl2json.d.ts.map +1 -0
- package/dist/terraform/parse.d.ts +4 -40
- package/dist/terraform/parse.d.ts.map +1 -1
- package/dist/vendor/js-yaml-load.d.ts +56 -0
- package/dist/vendor/js-yaml-load.d.ts.map +1 -0
- package/dist/workspace/box-cli.d.ts +12 -0
- package/dist/workspace/box-cli.d.ts.map +1 -0
- package/dist/workspace/box-factory.d.ts +27 -3
- package/dist/workspace/box-factory.d.ts.map +1 -1
- package/dist/workspace/box-listing.d.ts +85 -0
- package/dist/workspace/box-listing.d.ts.map +1 -0
- package/dist/workspace/box-publish.d.ts +147 -0
- package/dist/workspace/box-publish.d.ts.map +1 -0
- package/dist/workspace/broker-protocol.d.ts +190 -0
- package/dist/workspace/broker-protocol.d.ts.map +1 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/composites.d.ts +2 -2
- package/dist/workspace/composites.d.ts.map +1 -1
- package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts +17 -0
- package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts.map +1 -0
- package/dist/workspace/conformance/broker.d.ts +202 -0
- package/dist/workspace/conformance/broker.d.ts.map +1 -0
- package/dist/workspace/conformance/index.d.ts +2 -1
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/vitest.d.ts +9 -2
- package/dist/workspace/conformance/vitest.d.ts.map +1 -1
- package/dist/workspace/conformance/writer.d.ts +108 -14
- package/dist/workspace/conformance/writer.d.ts.map +1 -1
- package/dist/workspace/decide.d.ts +126 -12
- package/dist/workspace/decide.d.ts.map +1 -1
- package/dist/workspace/decision-points.schema.json +11 -4
- package/dist/workspace/declaration.d.ts +65 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.schema.json +153 -4
- package/dist/workspace/environments.d.ts +36 -10
- package/dist/workspace/environments.d.ts.map +1 -1
- package/dist/workspace/factory-rules.d.ts +180 -0
- package/dist/workspace/factory-rules.d.ts.map +1 -0
- package/dist/workspace/init.d.ts +21 -0
- package/dist/workspace/init.d.ts.map +1 -1
- package/dist/workspace/intent-cli.d.ts +1 -1
- package/dist/workspace/intent-cli.d.ts.map +1 -1
- package/dist/workspace/intent-record.d.ts +28 -1
- package/dist/workspace/intent-record.d.ts.map +1 -1
- package/dist/workspace/intent.d.ts +102 -5
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/json-edit.d.ts +24 -0
- package/dist/workspace/json-edit.d.ts.map +1 -0
- package/dist/workspace/jsonc.d.ts +11 -0
- package/dist/workspace/jsonc.d.ts.map +1 -1
- package/dist/workspace/kinds.d.ts +48 -0
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/lexicon-symbols.d.ts +29 -0
- package/dist/workspace/lexicon-symbols.d.ts.map +1 -0
- package/dist/workspace/lineage-upgrade.d.ts +31 -2
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
- package/dist/workspace/point-answer.schema.json +42 -2
- package/dist/workspace/points-cli.d.ts +10 -3
- package/dist/workspace/points-cli.d.ts.map +1 -1
- package/dist/workspace/points.d.ts +66 -5
- package/dist/workspace/points.d.ts.map +1 -1
- package/dist/workspace/reason-codes.d.ts +33 -4
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/record-sessions.d.ts +5 -7
- package/dist/workspace/record-sessions.d.ts.map +1 -1
- package/dist/workspace/records-cli.d.ts +7 -0
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-close.d.ts +7 -3
- package/dist/workspace/records-close.d.ts.map +1 -1
- package/dist/workspace/records-write.d.ts +66 -6
- package/dist/workspace/records-write.d.ts.map +1 -1
- package/dist/workspace/records.d.ts +28 -9
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/runs-cli.d.ts +138 -6
- package/dist/workspace/runs-cli.d.ts.map +1 -1
- package/dist/workspace/runs.d.ts +132 -11
- package/dist/workspace/runs.d.ts.map +1 -1
- package/dist/workspace/session-kinds.d.ts +1 -1
- package/dist/workspace/session-kinds.d.ts.map +1 -1
- package/dist/workspace/squash.d.ts +80 -0
- package/dist/workspace/squash.d.ts.map +1 -0
- package/dist/workspace/status-gates.d.ts +2 -0
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +54 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/symbols.d.ts +16 -5
- package/dist/workspace/symbols.d.ts.map +1 -1
- package/dist/workspace/trust/run-commits.d.ts +46 -0
- package/dist/workspace/trust/run-commits.d.ts.map +1 -0
- package/dist/workspace/trust/run-statement.d.ts +128 -0
- package/dist/workspace/trust/run-statement.d.ts.map +1 -0
- package/dist/workspace/trust/seal.d.ts +6 -1
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/verify-cli.d.ts +1 -1
- package/dist/workspace/trust/verify.d.ts +16 -2
- package/dist/workspace/trust/verify.d.ts.map +1 -1
- package/dist/workspace/wip-cli.d.ts +21 -0
- package/dist/workspace/wip-cli.d.ts.map +1 -0
- package/dist/workspace/wip.d.ts +268 -0
- package/dist/workspace/wip.d.ts.map +1 -0
- package/dist/workspace/work-cli.d.ts.map +1 -1
- package/dist/workspace/work-evidence.d.ts +1 -1
- package/dist/workspace/work-evidence.d.ts.map +1 -1
- package/dist/workspace/work-size.d.ts +55 -0
- package/dist/workspace/work-size.d.ts.map +1 -0
- package/dist/workspace/workspace-kinds.schema.json +122 -0
- package/dist/workspace/write-lock-cli.d.ts +60 -0
- package/dist/workspace/write-lock-cli.d.ts.map +1 -0
- package/dist/workspace/write-lock.d.ts +152 -0
- package/dist/workspace/write-lock.d.ts.map +1 -0
- package/dist/workspace/write-scope.d.ts +6 -2
- package/dist/workspace/write-scope.d.ts.map +1 -1
- package/dist/yaml.d.ts +1 -1
- package/dist/yaml.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/__fixtures__/change-set/lifecycle-plan.floci.json +59 -0
- package/src/__fixtures__/change-set/lifecycle-v1.ts.txt +4 -0
- package/src/__fixtures__/change-set/lifecycle-v2.ts.txt +4 -0
- package/src/__fixtures__/change-set/lifecycle.change-set.golden.json +95 -0
- package/src/__fixtures__/change-set/warden.change-set.golden.json +106 -0
- package/src/__fixtures__/change-set/warden.plan.json +44 -0
- package/src/__fixtures__/plan-summary/normalization-vectors.json +1593 -0
- package/src/__fixtures__/pr-loop/pr-apply-applied.note.golden.md +31 -0
- package/src/__fixtures__/pr-loop/pr-apply-refused.note.golden.md +31 -0
- package/src/__fixtures__/pr-loop/pr-plan.golden.json +127 -0
- package/src/__fixtures__/pr-loop/pr-plan.note.golden.md +37 -0
- package/src/audit/core.test.ts +15 -0
- package/src/audit/core.ts +8 -2
- package/src/audit/discover.test.ts +11 -0
- package/src/audit/discover.ts +7 -2
- package/src/change-set-bundle.test.ts +57 -0
- package/src/change-set.test.ts +215 -0
- package/src/change-set.ts +445 -0
- package/src/cli/commands/audit-opt-in.test.ts +54 -0
- package/src/cli/commands/audit.ts +29 -2
- package/src/cli/commands/build.test.ts +19 -0
- package/src/cli/commands/build.ts +3 -2
- package/src/cli/handlers/build.ts +13 -1
- package/src/cli/handlers/change-set.test.ts +56 -0
- package/src/cli/handlers/change-set.ts +44 -0
- package/src/cli/handlers/fan-out.test.ts +221 -2
- package/src/cli/handlers/fan-out.ts +165 -75
- package/src/cli/handlers/graph.ts +3 -0
- package/src/cli/handlers/operator.test.ts +21 -0
- package/src/cli/handlers/operator.ts +34 -3
- package/src/cli/handlers/pr.ts +373 -0
- package/src/cli/handlers/run.ts +1 -0
- package/src/cli/main.test.ts +20 -0
- package/src/cli/main.ts +185 -23
- package/src/cli/mcp/never-over-mcp.test.ts +101 -0
- package/src/cli/mcp/op-tools.ts +24 -2
- package/src/cli/mcp/workspace-tools.test.ts +1 -1
- package/src/cli/mcp/workspace-tools.ts +34 -6
- package/src/cli/registry.ts +63 -1
- package/src/components/auto-release.ts +1 -1
- package/src/components/capability.ts +55 -0
- package/src/components/changed-files.ts +66 -0
- package/src/components/cli-support.ts +28 -5
- package/src/components/component.schema.json +17 -0
- package/src/components/component.ts +25 -0
- package/src/components/deploy-units.ts +3 -0
- package/src/components/driver.test.ts +52 -0
- package/src/components/driver.ts +31 -13
- package/src/components/fan-out-output.ts +42 -1
- package/src/components/fan-out-record.ts +69 -0
- package/src/components/fan-out-run.test.ts +17 -0
- package/src/components/fan-out-run.ts +304 -1
- package/src/components/fan-out-support.ts +3 -0
- package/src/components/fan-out-waves.test.ts +375 -0
- package/src/components/fan-out.ts +18 -17
- package/src/components/gated-wave-pipeline.ts +82 -0
- package/src/components/index.ts +1 -0
- package/src/components/layers.ts +30 -0
- package/src/components/pr-pipeline.ts +91 -0
- package/src/components/pr-run.test.ts +205 -0
- package/src/components/pr-run.ts +280 -0
- package/src/components/promote.ts +5 -0
- package/src/components/verbs/shell.test.ts +11 -0
- package/src/components/verbs/shell.ts +7 -3
- package/src/components/wave-plan.ts +124 -0
- package/src/discovery/sandbox/bundle.ts +1 -1
- package/src/gated-waves-bundle.test.ts +62 -0
- package/src/gated-waves.test.ts +118 -0
- package/src/gated-waves.ts +240 -0
- package/src/index.ts +1 -0
- package/src/lexicon.ts +51 -0
- package/src/lifecycle/gate-ledger.ts +7 -0
- package/src/lifecycle/git.ts +102 -16
- package/src/lint/post-synth.test.ts +19 -0
- package/src/lint/post-synth.ts +19 -1
- package/src/meta/declared-imports.test.ts +1 -1
- package/src/op/activities/activity-contracts.ts +84 -0
- package/src/op/activities/change-set.ts +114 -0
- package/src/op/activities/decide.ts +3 -0
- package/src/op/activities/factory.ts +675 -0
- package/src/op/activities/index.ts +6 -0
- package/src/op/activity-contract.test.ts +21 -1
- package/src/op/activity-contract.ts +19 -9
- package/src/op/builders.ts +23 -0
- package/src/op/decide-backend.ts +5 -1
- package/src/op/decide-read-inputs.ts +33 -5
- package/src/op/factory.e2e.test.ts +232 -0
- package/src/op/factory.ts +118 -0
- package/src/op/index.ts +9 -1
- package/src/op/op-ir.test.ts +9 -0
- package/src/op/op-ir.ts +4 -0
- package/src/op/op-verb-class.ts +3 -0
- package/src/op/types.ts +8 -0
- package/src/op/work-lease-run.ts +3 -0
- package/src/plan-summary.test.ts +263 -0
- package/src/plan-summary.ts +845 -0
- package/src/pr-forge.test.ts +237 -0
- package/src/pr-forge.ts +332 -0
- package/src/pr-loop-bundle.test.ts +46 -0
- package/src/pr-loop.test.ts +171 -0
- package/src/pr-loop.ts +324 -0
- package/src/telemetry-attribution.test.ts +23 -1
- package/src/telemetry-attribution.ts +51 -0
- package/src/terraform/hcl2json.test.ts +21 -0
- package/src/terraform/hcl2json.ts +81 -0
- package/src/terraform/parse.ts +11 -74
- package/src/vendor/js-yaml-load.test.ts +115 -0
- package/src/vendor/js-yaml-load.ts +1939 -0
- package/src/workspace/__fixtures__/studio-template-84c8b21.json +1 -1
- package/src/workspace/app-kind.test.ts +196 -0
- package/src/workspace/box-cli.ts +113 -0
- package/src/workspace/box-factory.test.ts +4 -1
- package/src/workspace/box-factory.ts +37 -4
- package/src/workspace/box-listing-write.schema.json +204 -0
- package/src/workspace/box-listing.test.ts +234 -0
- package/src/workspace/box-listing.ts +324 -0
- package/src/workspace/box-publish.schema.json +498 -0
- package/src/workspace/box-publish.test.ts +204 -0
- package/src/workspace/box-publish.ts +420 -0
- package/src/workspace/box-ship.test.ts +96 -0
- package/src/workspace/broker-protocol.schema.json +186 -0
- package/src/workspace/broker-protocol.test.ts +122 -0
- package/src/workspace/broker-protocol.ts +317 -0
- package/src/workspace/builder-tiers.test.ts +146 -0
- package/src/workspace/change-set.schema.json +460 -0
- package/src/workspace/chant-migrations.e2e.test.ts +17 -5
- package/src/workspace/checks/boxes.test.ts +3 -0
- package/src/workspace/checks.ts +10 -3
- package/src/workspace/component-environments.test.ts +105 -0
- package/src/workspace/composites.schema.json +23 -4
- package/src/workspace/composites.test.ts +8 -8
- package/src/workspace/composites.ts +13 -2
- package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +2 -2
- package/src/workspace/conformance/__fixtures__/reference-broker.ts +207 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +7 -2
- package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +42 -2
- package/src/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
- package/src/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
- package/src/workspace/conformance/__writer_fixture__/decisions/points.json +96 -0
- package/src/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
- package/src/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +14 -8
- package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +187 -6
- package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +25 -0
- package/src/workspace/conformance/broker.test.ts +122 -0
- package/src/workspace/conformance/broker.ts +792 -0
- package/src/workspace/conformance/conformance.e2e.test.ts +2 -1
- package/src/workspace/conformance/index.mjs +22 -1
- package/src/workspace/conformance/index.ts +5 -1
- package/src/workspace/conformance/vitest.ts +33 -1
- package/src/workspace/conformance/writer-conformance.e2e.test.ts +49 -3
- package/src/workspace/conformance/writer.test.ts +32 -2
- package/src/workspace/conformance/writer.ts +339 -28
- package/src/workspace/decide.test.ts +208 -4
- package/src/workspace/decide.ts +427 -73
- package/src/workspace/decision-points.schema.json +11 -4
- package/src/workspace/declaration.schema.json +153 -4
- package/src/workspace/declaration.ts +141 -0
- package/src/workspace/environments.ts +66 -14
- package/src/workspace/factory-rules.test.ts +62 -0
- package/src/workspace/factory-rules.ts +218 -0
- package/src/workspace/graph-cli.ts +2 -2
- package/src/workspace/graph.schema.json +67 -0
- package/src/workspace/identity.test.ts +23 -0
- package/src/workspace/init.ts +82 -2
- package/src/workspace/intent-cli.ts +26 -9
- package/src/workspace/intent-patch-id.test.ts +162 -0
- package/src/workspace/intent-record.schema.json +130 -3
- package/src/workspace/intent-record.ts +74 -28
- package/src/workspace/intent-reviews.test.ts +76 -0
- package/src/workspace/intent-squash.test.ts +213 -0
- package/src/workspace/intent-why.test.ts +5 -5
- package/src/workspace/intent.schema.json +234 -4
- package/src/workspace/intent.ts +260 -66
- package/src/workspace/json-edit.test.ts +121 -0
- package/src/workspace/json-edit.ts +142 -0
- package/src/workspace/jsonc.ts +20 -0
- package/src/workspace/kinds.ts +157 -2
- package/src/workspace/lexicon-symbols.test.ts +148 -0
- package/src/workspace/lexicon-symbols.ts +125 -0
- package/src/workspace/lineage-upgrade.test.ts +63 -0
- package/src/workspace/lineage-upgrade.ts +146 -5
- package/src/workspace/plan-summary.schema.json +155 -0
- package/src/workspace/point-answer.schema.json +42 -2
- package/src/workspace/points-cli.ts +42 -16
- package/src/workspace/points-write.schema.json +162 -4
- package/src/workspace/points.schema.json +157 -2
- package/src/workspace/points.test.ts +13 -1
- package/src/workspace/points.ts +118 -12
- package/src/workspace/pr-report.schema.json +95 -0
- package/src/workspace/profiles.test.ts +159 -0
- package/src/workspace/read-contract.test.ts +2 -2
- package/src/workspace/reason-codes.test.ts +13 -1
- package/src/workspace/reason-codes.ts +38 -4
- package/src/workspace/record-sessions.ts +9 -8
- package/src/workspace/records-amend.schema.json +78 -0
- package/src/workspace/records-cli.ts +20 -6
- package/src/workspace/records-close.schema.json +78 -0
- package/src/workspace/records-close.ts +31 -7
- package/src/workspace/records-concurrent.e2e.test.ts +135 -0
- package/src/workspace/records-concurrent.test.ts +145 -0
- package/src/workspace/records-formats.test.ts +46 -10
- package/src/workspace/records-new.schema.json +7 -0
- package/src/workspace/records-review.schema.json +78 -0
- package/src/workspace/records-sessions-write.test.ts +69 -0
- package/src/workspace/records-sessions.test.ts +22 -0
- package/src/workspace/records-write.ts +192 -25
- package/src/workspace/records.schema.json +16 -0
- package/src/workspace/records.ts +50 -9
- package/src/workspace/reference-kinds/app/package.json +10 -0
- package/src/workspace/reference-kinds/app/workspace-kinds.json +45 -0
- package/src/workspace/run-statement.schema.json +622 -0
- package/src/workspace/runs-cli.ts +343 -14
- package/src/workspace/runs-statement.test.ts +239 -0
- package/src/workspace/runs-write.schema.json +416 -5
- package/src/workspace/runs.schema.json +451 -4
- package/src/workspace/runs.test.ts +39 -0
- package/src/workspace/runs.ts +296 -35
- package/src/workspace/session-kinds.ts +3 -3
- package/src/workspace/squash.ts +198 -0
- package/src/workspace/status-contract.test.ts +5 -2
- package/src/workspace/status-gates.ts +3 -1
- package/src/workspace/status.schema.json +126 -3
- package/src/workspace/status.ts +90 -1
- package/src/workspace/symbols.ts +20 -9
- package/src/workspace/trust/run-commits.ts +115 -0
- package/src/workspace/trust/run-statement.ts +226 -0
- package/src/workspace/trust/seal.ts +8 -2
- package/src/workspace/trust/verify-cli.ts +6 -5
- package/src/workspace/trust/verify.ts +39 -6
- package/src/workspace/wip-cli.ts +97 -0
- package/src/workspace/wip-write.schema.json +504 -0
- package/src/workspace/wip.schema.json +334 -0
- package/src/workspace/wip.test.ts +294 -0
- package/src/workspace/wip.ts +753 -0
- package/src/workspace/work-cli.ts +3 -0
- package/src/workspace/work-evidence.schema.json +3 -0
- package/src/workspace/work-size.test.ts +77 -0
- package/src/workspace/work-size.ts +93 -0
- package/src/workspace/workspace-kinds.schema.json +122 -0
- package/src/workspace/write-lock-cli.ts +131 -0
- package/src/workspace/write-lock.schema.json +172 -0
- package/src/workspace/write-lock.test.ts +189 -0
- package/src/workspace/write-lock.ts +474 -0
- package/src/workspace/write-scope.test.ts +16 -1
- package/src/workspace/write-scope.ts +33 -11
- package/src/yaml.ts +31 -21
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant components pr-plan` and `chant components pr-apply` (#3183): the
|
|
3
|
+
* pull-request loop the generated CI runs.
|
|
4
|
+
*
|
|
5
|
+
* ```
|
|
6
|
+
* chant components pr-plan --base <ref> --pr <n> --env <env> [--forge github|gitlab|forgejo]
|
|
7
|
+
* chant approve pr-<n> pr-apply --plan <digest> --approver github:<login> --sign
|
|
8
|
+
* chant components pr-apply --base <ref> --env <env> [--pr <n>] [--forge <kind>] [--require-review]
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* Both measure the change from the merge base of `--base` and `HEAD`, select
|
|
12
|
+
* the components it reaches and the ones that depend on them (the fan-out's
|
|
13
|
+
* derivation, #2417), and plan every member before anything applies
|
|
14
|
+
* (`../../components/pr-run.ts`). pr-plan writes the report and the note and
|
|
15
|
+
* applies nothing; it reads the gate ledger and writes nothing to it, since
|
|
16
|
+
* it runs the pull request's own code. pr-apply plans the same members on
|
|
17
|
+
* the merged commit, decides the gate against the digest it gets, and
|
|
18
|
+
* applies only when an approval stands for that digest. A moved plan stops
|
|
19
|
+
* it with both digests named and nothing applied (exit 3).
|
|
20
|
+
*
|
|
21
|
+
* Every run writes `pr-plan.json` or `pr-apply.json` (`pr-report.schema.json`),
|
|
22
|
+
* `change-set.json` and `pr-note.md` under `--output` (default `.chant/pr`).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
26
|
+
import { join, resolve } from "node:path";
|
|
27
|
+
import { loadChantConfig, resolveAutoReleaseDisabled, type ChantConfig } from "../../config";
|
|
28
|
+
import { resolveCommit, resolveMergeBase } from "../../components/changed-files";
|
|
29
|
+
import { deriveFanOut, fanOutRegistry } from "../../components/fan-out-support";
|
|
30
|
+
import {
|
|
31
|
+
applyPrSet,
|
|
32
|
+
approvalOf,
|
|
33
|
+
approversWithoutReview,
|
|
34
|
+
decidePrGate,
|
|
35
|
+
planPrSet,
|
|
36
|
+
prReport,
|
|
37
|
+
readOnlyLedger,
|
|
38
|
+
type PrPlanSet,
|
|
39
|
+
} from "../../components/pr-run";
|
|
40
|
+
import { gitGateLedgerPort } from "../../op/gate";
|
|
41
|
+
import {
|
|
42
|
+
describePlanChanged,
|
|
43
|
+
PR_APPLY_GATE,
|
|
44
|
+
PR_STATUS_CONTEXTS,
|
|
45
|
+
prApproveCommand,
|
|
46
|
+
prNoteMarker,
|
|
47
|
+
prOp,
|
|
48
|
+
prStatusDescription,
|
|
49
|
+
prStatusState,
|
|
50
|
+
renderPrNote,
|
|
51
|
+
type PrApproval,
|
|
52
|
+
type PrReport,
|
|
53
|
+
} from "../../pr-loop";
|
|
54
|
+
import { FORGE_KINDS, forgeFromEnv, forgePrincipalOf, type ForgeKind, type PrForge } from "../../pr-forge";
|
|
55
|
+
import { GITHUB_COMMENT_LIMIT, GITLAB_NOTE_LIMIT } from "../../plan-summary";
|
|
56
|
+
import { resolveCliBuildParams, parseParamFlags } from "../build-params-cli";
|
|
57
|
+
import { formatError, formatInfo, formatSuccess, formatWarning } from "../format";
|
|
58
|
+
import { resolveChangedUnits } from "./fan-out";
|
|
59
|
+
import { GATED_EXIT_CODE, recordAutoReleasesForRun } from "./run";
|
|
60
|
+
import type { CommandContext } from "../registry";
|
|
61
|
+
import type { ComponentChangeSignal, FanOutPlan } from "../../components/fan-out";
|
|
62
|
+
import type { DriverComponent } from "../../components/driver";
|
|
63
|
+
import type { CapabilityRegistry } from "../../components/capability";
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
/** Where the reports land unless `--output` says. */
|
|
67
|
+
export const PR_REPORT_DIR = ".chant/pr";
|
|
68
|
+
|
|
69
|
+
interface Prepared {
|
|
70
|
+
config: ChantConfig;
|
|
71
|
+
env: string;
|
|
72
|
+
base: string;
|
|
73
|
+
head: string;
|
|
74
|
+
gate: string;
|
|
75
|
+
forge?: PrForge;
|
|
76
|
+
components: DriverComponent[];
|
|
77
|
+
plan: FanOutPlan;
|
|
78
|
+
signal: ComponentChangeSignal;
|
|
79
|
+
registry: CapabilityRegistry;
|
|
80
|
+
set: PrPlanSet;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const fail = (message: string, hint?: string): number => {
|
|
84
|
+
console.error(formatError({ message, ...(hint ? { hint } : {}) }));
|
|
85
|
+
return 1;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/** Everything both stages share: the change, the derivation and the plan of every member. */
|
|
89
|
+
async function prepare(ctx: CommandContext, stage: "plan" | "apply"): Promise<Prepared | number> {
|
|
90
|
+
const { args } = ctx;
|
|
91
|
+
const projectPath = resolve(".");
|
|
92
|
+
const { config } = await loadChantConfig(projectPath).catch(() => ({ config: {} as ChantConfig }));
|
|
93
|
+
const paramsResolution = resolveCliBuildParams(config.buildParams, {
|
|
94
|
+
cli: parseParamFlags(args.param),
|
|
95
|
+
paramsFile: args.paramsFile,
|
|
96
|
+
verbose: args.verbose,
|
|
97
|
+
});
|
|
98
|
+
if (!paramsResolution.success) {
|
|
99
|
+
for (const message of paramsResolution.errors) console.error(message);
|
|
100
|
+
return 1;
|
|
101
|
+
}
|
|
102
|
+
if (!args.base) {
|
|
103
|
+
return fail(
|
|
104
|
+
`pr-${stage} needs the commit the change is measured from: --base <ref>`,
|
|
105
|
+
stage === "plan" ? "On a pull request, the target branch's commit." : "On a push, the commit before it.",
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
if (args.fromAffected) return fail(`pr-${stage} derives the change itself; drop --from-affected`);
|
|
109
|
+
if (args.forge !== undefined && !(FORGE_KINDS as readonly string[]).includes(args.forge)) {
|
|
110
|
+
return fail(`--forge ${args.forge} is not one of ${FORGE_KINDS.join(", ")}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let forge: PrForge | undefined;
|
|
114
|
+
if (args.forge) {
|
|
115
|
+
try {
|
|
116
|
+
forge = forgeFromEnv(args.forge as ForgeKind);
|
|
117
|
+
} catch (err) {
|
|
118
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let base: string;
|
|
123
|
+
let head: string;
|
|
124
|
+
try {
|
|
125
|
+
head = await resolveCommit(projectPath, args.head ?? "HEAD");
|
|
126
|
+
base = await resolveMergeBase(projectPath, args.base, head);
|
|
127
|
+
} catch (err) {
|
|
128
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const signal = await resolveChangedUnits(ctx, config, { base, stacksOnly: true });
|
|
132
|
+
if ("error" in signal) return fail(signal.error, signal.hint);
|
|
133
|
+
|
|
134
|
+
let derived;
|
|
135
|
+
try {
|
|
136
|
+
derived = await deriveFanOut({
|
|
137
|
+
path: projectPath,
|
|
138
|
+
units: signal.units,
|
|
139
|
+
sandbox: args.sandbox,
|
|
140
|
+
buildParams: paramsResolution.provenance,
|
|
141
|
+
config,
|
|
142
|
+
});
|
|
143
|
+
} catch (err) {
|
|
144
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
145
|
+
}
|
|
146
|
+
if (!derived.success) return fail(derived.error ?? "Could not discover components");
|
|
147
|
+
|
|
148
|
+
const seededOutputs: Record<string, Record<string, unknown>> = {};
|
|
149
|
+
for (const file of args.seedOutputs ?? []) {
|
|
150
|
+
try {
|
|
151
|
+
Object.assign(seededOutputs, JSON.parse(readFileSync(resolve(file), "utf8")));
|
|
152
|
+
} catch (err) {
|
|
153
|
+
return fail(`--seed-outputs: could not read "${file}": ${err instanceof Error ? err.message : String(err)}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const env = args.env ?? "local";
|
|
158
|
+
const registry = await fanOutRegistry(projectPath, config);
|
|
159
|
+
const set = await planPrSet({ components: derived.components, plan: derived.plan, registry, env, seededOutputs });
|
|
160
|
+
return {
|
|
161
|
+
config,
|
|
162
|
+
env,
|
|
163
|
+
base,
|
|
164
|
+
head,
|
|
165
|
+
gate: args.gate ?? PR_APPLY_GATE,
|
|
166
|
+
...(forge ? { forge } : {}),
|
|
167
|
+
components: derived.components,
|
|
168
|
+
plan: derived.plan,
|
|
169
|
+
signal: derived.signal,
|
|
170
|
+
registry,
|
|
171
|
+
set,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Write the report, the change set and the note; print the note's path. */
|
|
176
|
+
function writeOutputs(ctx: CommandContext, report: PrReport, note: string): void {
|
|
177
|
+
const dir = resolve(ctx.args.output ?? PR_REPORT_DIR);
|
|
178
|
+
mkdirSync(dir, { recursive: true });
|
|
179
|
+
writeFileSync(join(dir, `pr-${report.stage}.json`), JSON.stringify(report, null, 2) + "\n");
|
|
180
|
+
writeFileSync(join(dir, "change-set.json"), JSON.stringify(report.changeSet, null, 2) + "\n");
|
|
181
|
+
writeFileSync(join(dir, "pr-note.md"), note);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** Post the note and the stage's status. A forge that refuses is a warning: the stage's outcome stands. */
|
|
185
|
+
async function publish(forge: PrForge | undefined, report: PrReport, note: string): Promise<void> {
|
|
186
|
+
if (!forge) return;
|
|
187
|
+
const status = {
|
|
188
|
+
context: PR_STATUS_CONTEXTS[report.stage],
|
|
189
|
+
state: prStatusState(report),
|
|
190
|
+
description: prStatusDescription(report),
|
|
191
|
+
...(forge.runUrl ? { url: forge.runUrl } : {}),
|
|
192
|
+
};
|
|
193
|
+
try {
|
|
194
|
+
await forge.setStatus(report.head, status);
|
|
195
|
+
} catch (err) {
|
|
196
|
+
console.error(formatWarning({ message: `could not set the ${status.context} status: ${err instanceof Error ? err.message : String(err)}` }));
|
|
197
|
+
}
|
|
198
|
+
if (report.pr === null) return;
|
|
199
|
+
try {
|
|
200
|
+
await forge.upsertNote(report.pr, prNoteMarker(report.env), note);
|
|
201
|
+
} catch (err) {
|
|
202
|
+
console.error(formatWarning({ message: `could not post the note on #${report.pr}: ${err instanceof Error ? err.message : String(err)}` }));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function noteFor(report: PrReport, forge: PrForge | undefined): string {
|
|
207
|
+
return renderPrNote(report, {
|
|
208
|
+
limit: forge?.kind === "gitlab" ? GITLAB_NOTE_LIMIT : GITHUB_COMMENT_LIMIT,
|
|
209
|
+
approver: forge ? forgePrincipalOf(forge.kind, forge.host, "<your-login>") : "<you>",
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function printMembers(report: PrReport): void {
|
|
214
|
+
for (const m of report.members) {
|
|
215
|
+
const c = m.counts;
|
|
216
|
+
console.error(` ${m.member.padEnd(20)} ${m.status.padEnd(12)} create ${c.create} update ${c.update} replace ${c.replace} delete ${c.delete}${m.error ? ` ${m.error}` : ""}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async function finish(ctx: CommandContext, p: Prepared, report: PrReport): Promise<void> {
|
|
221
|
+
const note = noteFor(report, p.forge);
|
|
222
|
+
writeOutputs(ctx, report, note);
|
|
223
|
+
await publish(p.forge, report, note);
|
|
224
|
+
if (ctx.args.json) console.log(JSON.stringify(report, null, 2));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** chant components pr-plan --base <ref> --pr <n> [--env <env>] [--gate <name>] [--forge <kind>] [--output <dir>] [--json] */
|
|
228
|
+
export async function runComponentsPrPlan(ctx: CommandContext): Promise<number> {
|
|
229
|
+
if (ctx.args.pr === undefined) {
|
|
230
|
+
return fail("pr-plan needs the pull or merge request: --pr <n>", "Its approval is recorded under op pr-<n>, so one pull request's approval never answers another's.");
|
|
231
|
+
}
|
|
232
|
+
const p = await prepare(ctx, "plan");
|
|
233
|
+
if (typeof p === "number") return p;
|
|
234
|
+
const op = prOp(ctx.args.pr);
|
|
235
|
+
|
|
236
|
+
let approval: PrApproval = { status: "pending" };
|
|
237
|
+
if (p.plan.order.length > 0) {
|
|
238
|
+
try {
|
|
239
|
+
approval = approvalOf(await decidePrGate(readOnlyLedger(gitGateLedgerPort()), { op, gate: p.gate, digest: p.set.doc.digest }));
|
|
240
|
+
} catch (err) {
|
|
241
|
+
console.error(formatWarning({ message: `could not read the gate ledger, so the approval reads as pending: ${err instanceof Error ? err.message : String(err)}` }));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const status = p.plan.order.length === 0 ? "nothing" : p.set.failed ? "plan-failed" : "planned";
|
|
245
|
+
const report = prReport({
|
|
246
|
+
stage: "plan",
|
|
247
|
+
pr: ctx.args.pr,
|
|
248
|
+
env: p.env,
|
|
249
|
+
base: p.base,
|
|
250
|
+
head: p.head,
|
|
251
|
+
op,
|
|
252
|
+
gate: p.gate,
|
|
253
|
+
plan: p.plan,
|
|
254
|
+
signal: p.signal,
|
|
255
|
+
set: p.set,
|
|
256
|
+
approval,
|
|
257
|
+
status,
|
|
258
|
+
});
|
|
259
|
+
await finish(ctx, p, report);
|
|
260
|
+
|
|
261
|
+
console.error(formatInfo(`pr-plan: ${report.members.length} member(s), ${status}`));
|
|
262
|
+
printMembers(report);
|
|
263
|
+
if (status === "planned") {
|
|
264
|
+
console.error(formatInfo(`plan : ${report.digest}`));
|
|
265
|
+
console.error(formatInfo(approval.status === "approved" ? `approved by ${(approval.approvedBy ?? []).join(", ")}` : `approve : ${prApproveCommand(report)}`));
|
|
266
|
+
}
|
|
267
|
+
return status === "plan-failed" ? 1 : 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** chant components pr-apply --base <ref> [--pr <n>] [--env <env>] [--gate <name>] [--forge <kind>] [--require-review] [--output <dir>] [--json] */
|
|
271
|
+
export async function runComponentsPrApply(ctx: CommandContext): Promise<number> {
|
|
272
|
+
const { args } = ctx;
|
|
273
|
+
if (args.requireReview && !args.forge) return fail("--require-review reads the pull request's reviews, so it needs --forge <kind>");
|
|
274
|
+
const p = await prepare(ctx, "apply");
|
|
275
|
+
if (typeof p === "number") return p;
|
|
276
|
+
|
|
277
|
+
let pr: number | null = args.pr ?? null;
|
|
278
|
+
if (pr === null && p.forge && p.plan.order.length > 0) {
|
|
279
|
+
try {
|
|
280
|
+
pr = await p.forge.pullRequestFor(p.head);
|
|
281
|
+
} catch (err) {
|
|
282
|
+
return fail(`could not ask ${p.forge.kind} which pull request merged ${p.head}: ${err instanceof Error ? err.message : String(err)}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
const op = pr === null ? "pr-unknown" : prOp(pr);
|
|
286
|
+
const base = { stage: "apply" as const, pr, env: p.env, base: p.base, head: p.head, op, gate: p.gate, plan: p.plan, signal: p.signal, set: p.set };
|
|
287
|
+
|
|
288
|
+
const stop = async (report: PrReport, code: number): Promise<number> => {
|
|
289
|
+
await finish(ctx, p, report);
|
|
290
|
+
console.error((code === 0 ? formatInfo : (m: string) => formatWarning({ message: m }))(`pr-apply: ${report.status}${report.refusal ? ` (${report.refusal})` : ""}`));
|
|
291
|
+
if (report.message) console.error(report.message);
|
|
292
|
+
printMembers(report);
|
|
293
|
+
return code;
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
if (p.plan.order.length === 0) {
|
|
297
|
+
return stop(prReport({ ...base, approval: { status: "pending" }, status: "nothing" }), 0);
|
|
298
|
+
}
|
|
299
|
+
if (pr === null) {
|
|
300
|
+
return stop(
|
|
301
|
+
prReport({
|
|
302
|
+
...base,
|
|
303
|
+
approval: { status: "pending" },
|
|
304
|
+
status: "refused",
|
|
305
|
+
refusal: "no-pull-request",
|
|
306
|
+
message: `No pull request merged ${p.head}, so no approval answers for this change. Nothing was applied. Pass --pr <n>, or land the change through a pull request.`,
|
|
307
|
+
}),
|
|
308
|
+
GATED_EXIT_CODE,
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
if (p.set.failed) {
|
|
312
|
+
return stop(
|
|
313
|
+
prReport({
|
|
314
|
+
...base,
|
|
315
|
+
approval: { status: "pending" },
|
|
316
|
+
status: "plan-failed",
|
|
317
|
+
message: "A member failed to plan, so there is no plan to compare with the approved one. Nothing was applied.",
|
|
318
|
+
}),
|
|
319
|
+
1,
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const check = await decidePrGate(gitGateLedgerPort(), {
|
|
324
|
+
op,
|
|
325
|
+
gate: p.gate,
|
|
326
|
+
digest: p.set.doc.digest,
|
|
327
|
+
description: `pull request #${pr}: ${p.plan.order.join(", ")}`,
|
|
328
|
+
});
|
|
329
|
+
const approval = approvalOf(check);
|
|
330
|
+
if (!check.satisfied) {
|
|
331
|
+
const partial = { ...base, approval, status: "refused" as const };
|
|
332
|
+
const report = approval.status === "changed"
|
|
333
|
+
? prReport({ ...partial, refusal: "plan-changed", message: describePlanChanged({ op, gate: p.gate, digest: p.set.doc.digest, approval }) })
|
|
334
|
+
: prReport({
|
|
335
|
+
...partial,
|
|
336
|
+
refusal: "not-approved",
|
|
337
|
+
message: `No approval stands for this plan, so nothing was applied. Approve it: ${prApproveCommand({ op, gate: p.gate, digest: p.set.doc.digest })}; then run the apply again.`,
|
|
338
|
+
});
|
|
339
|
+
return stop(report, GATED_EXIT_CODE);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (args.requireReview && p.forge) {
|
|
343
|
+
let reviewers: string[];
|
|
344
|
+
try {
|
|
345
|
+
reviewers = (await p.forge.approvers(pr)).map((login) => p.forge!.principalOf(login));
|
|
346
|
+
} catch (err) {
|
|
347
|
+
return fail(`could not read the reviews of #${pr}: ${err instanceof Error ? err.message : String(err)}`);
|
|
348
|
+
}
|
|
349
|
+
const strangers = approversWithoutReview(approval.approvedBy ?? [], reviewers);
|
|
350
|
+
if (strangers.length > 0) {
|
|
351
|
+
return stop(
|
|
352
|
+
prReport({
|
|
353
|
+
...base,
|
|
354
|
+
approval,
|
|
355
|
+
status: "refused",
|
|
356
|
+
refusal: "not-a-reviewer",
|
|
357
|
+
message:
|
|
358
|
+
`The plan is approved by ${strangers.join(", ")}, who ${strangers.length === 1 ? "has" : "have"} no approving review on #${pr}` +
|
|
359
|
+
` (approving reviews: ${reviewers.join(", ") || "none"}). Nothing was applied. ` +
|
|
360
|
+
`An approval counts when it names the reviewer the way the forge does: ${p.forge.principalOf("<login>")}.`,
|
|
361
|
+
}),
|
|
362
|
+
GATED_EXIT_CODE,
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const applied = await applyPrSet({ components: p.components, plan: p.plan, registry: p.registry, env: p.env, set: p.set });
|
|
368
|
+
await recordAutoReleasesForRun(applied.run.results, p.env, `${op}-${Date.now()}`, resolveAutoReleaseDisabled(p.config, args.noReleaseRecord));
|
|
369
|
+
const report = prReport({ ...base, approval, status: applied.status, members: applied.members });
|
|
370
|
+
const code = await stop(report, applied.status === "applied" ? 0 : 1);
|
|
371
|
+
if (applied.status === "applied") console.error(formatSuccess(`applied the plan ${report.digest} approved by ${(approval.approvedBy ?? []).join(", ")}`));
|
|
372
|
+
return code;
|
|
373
|
+
}
|
package/src/cli/handlers/run.ts
CHANGED
|
@@ -454,6 +454,7 @@ export async function runOpApprove(ctx: CommandContext): Promise<number> {
|
|
|
454
454
|
url: ctx.args.url,
|
|
455
455
|
plan: ctx.args.plan,
|
|
456
456
|
...(ctx.args.sign !== undefined ? { sign: ctx.args.sign } : {}),
|
|
457
|
+
...(ctx.args.relayedBy !== undefined ? { relayedBy: ctx.args.relayedBy } : {}),
|
|
457
458
|
});
|
|
458
459
|
if (!outcome.ok) return 1;
|
|
459
460
|
|
package/src/cli/main.test.ts
CHANGED
|
@@ -255,6 +255,23 @@ describe("parseArgs", () => {
|
|
|
255
255
|
expect(result.extraPositional2).toBe(undefined);
|
|
256
256
|
});
|
|
257
257
|
|
|
258
|
+
test("positionals keeps every positional after the command, for workspace box listing set <member> (#3308)", () => {
|
|
259
|
+
const result = parseArgs(["workspace", "box", "listing", "set", "app", "--from", "-", "--cover", "c.png", "--cover-path", "app/c.png"]);
|
|
260
|
+
expect(result.positionals).toEqual(["box", "listing", "set", "app"]);
|
|
261
|
+
expect(result).toMatchObject({ path: "box", extraPositional: "listing", migrateFrom: "-", cover: "c.png", coverPath: "app/c.png" });
|
|
262
|
+
expect(() => parseArgs(["workspace", "box", "listing", "set", "app", "--cover"])).toThrow(/--cover needs/);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
test("workspace wip takes --label and --branch, with its verb and snapshot as positionals (#3172)", () => {
|
|
266
|
+
const save = parseArgs(["workspace", "wip", "save", "--label", "turn:3", "--by", "github:alex", "--json"]);
|
|
267
|
+
expect(save).toMatchObject({ positionals: ["wip", "save"], label: "turn:3", by: "github:alex", json: true });
|
|
268
|
+
expect(resolveCommand(save, commandRegistry)?.def.name).toBe("workspace wip");
|
|
269
|
+
expect(parseArgs(["workspace", "wip", "restore", "abc123"]).positionals).toEqual(["wip", "restore", "abc123"]);
|
|
270
|
+
expect(parseArgs(["workspace", "wip", "--branch", "chant/work/W-1", "--json"])).toMatchObject({ branch: "chant/work/W-1", json: true });
|
|
271
|
+
expect(() => parseArgs(["workspace", "wip", "save", "--label"])).toThrow(/--label needs/);
|
|
272
|
+
expect(() => parseArgs(["workspace", "wip", "--branch"])).toThrow(/--branch needs/);
|
|
273
|
+
});
|
|
274
|
+
|
|
258
275
|
// ── components release/status flags (#568) ──────────────────────────────
|
|
259
276
|
|
|
260
277
|
test("parses --component, --digest, --git-sha, --run-id, --actor for components release", () => {
|
|
@@ -751,6 +768,7 @@ describe("workspace init and ls (#2534)", () => {
|
|
|
751
768
|
"workspace adopt-lineage",
|
|
752
769
|
"workspace agent",
|
|
753
770
|
"workspace audit",
|
|
771
|
+
"workspace box",
|
|
754
772
|
"workspace build",
|
|
755
773
|
"workspace check",
|
|
756
774
|
"workspace evidence",
|
|
@@ -761,6 +779,7 @@ describe("workspace init and ls (#2534)", () => {
|
|
|
761
779
|
"workspace init",
|
|
762
780
|
"workspace lineage",
|
|
763
781
|
"workspace lint",
|
|
782
|
+
"workspace lock",
|
|
764
783
|
"workspace ls",
|
|
765
784
|
"workspace member-run",
|
|
766
785
|
"workspace patch",
|
|
@@ -773,6 +792,7 @@ describe("workspace init and ls (#2534)", () => {
|
|
|
773
792
|
"workspace upgrade",
|
|
774
793
|
"workspace verify",
|
|
775
794
|
"workspace versions",
|
|
795
|
+
"workspace wip",
|
|
776
796
|
"workspace work",
|
|
777
797
|
]);
|
|
778
798
|
});
|