gate-evm-tools 1.0.28 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -18
- package/bin/cli.js +6 -0
- package/bin/delivery.cjs +52 -0
- package/bin/manifest-bootstrap.js +4 -15
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +26 -2
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/plan/file-store.d.ts.map +1 -0
- package/dist/commands/plan/generate-deployment.d.ts +48 -0
- package/dist/commands/plan/generate-deployment.d.ts.map +1 -0
- package/dist/commands/plan/generate-deployment.js +211 -0
- package/dist/commands/plan/generate-deployment.js.map +1 -0
- package/dist/commands/plan/helpers.d.ts.map +1 -0
- package/dist/commands/plan/index.d.ts +3 -0
- package/dist/commands/plan/index.d.ts.map +1 -0
- package/dist/commands/plan/index.js +88 -0
- package/dist/commands/plan/index.js.map +1 -0
- package/dist/commands/sync.js +1 -1
- package/dist/commands/sync.js.map +1 -1
- package/dist/core/BytecodeChecker.d.ts.map +1 -1
- package/dist/core/BytecodeChecker.js +27 -8
- package/dist/core/BytecodeChecker.js.map +1 -1
- package/dist/core/preparation/artifacts.d.ts +2 -0
- package/dist/core/preparation/artifacts.d.ts.map +1 -1
- package/dist/core/preparation/artifacts.js +9 -3
- package/dist/core/preparation/artifacts.js.map +1 -1
- package/dist/core/preparation/batch.d.ts +26 -0
- package/dist/core/preparation/batch.d.ts.map +1 -0
- package/dist/core/preparation/batch.js +72 -0
- package/dist/core/preparation/batch.js.map +1 -0
- package/dist/core/preparation/evm.d.ts +61 -6
- package/dist/core/preparation/evm.d.ts.map +1 -1
- package/dist/core/preparation/evm.js +122 -34
- package/dist/core/preparation/evm.js.map +1 -1
- package/dist/core/preparation/evmManifestSync.d.ts +68 -0
- package/dist/core/preparation/evmManifestSync.d.ts.map +1 -0
- package/dist/core/preparation/evmManifestSync.js +154 -0
- package/dist/core/preparation/evmManifestSync.js.map +1 -0
- package/dist/core/preparation/index.d.ts +40 -2
- package/dist/core/preparation/index.d.ts.map +1 -1
- package/dist/core/preparation/index.js +3 -3
- package/dist/core/preparation/index.js.map +1 -1
- package/dist/core/preparation/manifest.d.ts +17 -3
- package/dist/core/preparation/manifest.d.ts.map +1 -1
- package/dist/core/preparation/manifest.js +23 -28
- package/dist/core/preparation/manifest.js.map +1 -1
- package/dist/core/preparation/normalize.d.ts.map +1 -1
- package/dist/core/preparation/normalize.js +67 -20
- package/dist/core/preparation/normalize.js.map +1 -1
- package/dist/core/preparation/transparent.d.ts +23 -0
- package/dist/core/preparation/transparent.d.ts.map +1 -0
- package/dist/core/preparation/transparent.js +103 -0
- package/dist/core/preparation/transparent.js.map +1 -0
- package/dist/core/preparation/types.d.ts +54 -7
- package/dist/core/preparation/types.d.ts.map +1 -1
- package/dist/core/preparation/zksync.d.ts.map +1 -1
- package/dist/core/preparation/zksync.js +2 -0
- package/dist/core/preparation/zksync.js.map +1 -1
- package/dist/custody/credential.d.ts.map +1 -1
- package/dist/custody/credential.js +1 -6
- package/dist/custody/credential.js.map +1 -1
- package/dist/custody/hardhat-runtime.d.ts.map +1 -1
- package/dist/custody/hardhat-runtime.js +2 -0
- package/dist/custody/hardhat-runtime.js.map +1 -1
- package/dist/custody/hardhat.d.ts +1 -0
- package/dist/custody/hardhat.d.ts.map +1 -1
- package/dist/custody/hardhat.js +1 -0
- package/dist/custody/hardhat.js.map +1 -1
- package/dist/custody/index.d.ts +1 -0
- package/dist/custody/index.d.ts.map +1 -1
- package/dist/custody/index.js +1 -0
- package/dist/custody/index.js.map +1 -1
- package/dist/custody/provider-wait.d.ts +13 -0
- package/dist/custody/provider-wait.d.ts.map +1 -0
- package/dist/custody/provider-wait.js +78 -0
- package/dist/custody/provider-wait.js.map +1 -0
- package/dist/delivery/policy.d.ts +6 -0
- package/dist/delivery/policy.d.ts.map +1 -0
- package/dist/delivery/policy.js +24 -0
- package/dist/delivery/policy.js.map +1 -0
- package/dist/deployment-evm/index.d.ts +4 -0
- package/dist/deployment-evm/index.d.ts.map +1 -0
- package/dist/deployment-evm/index.js +3 -0
- package/dist/deployment-evm/index.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/sync/index.d.ts +15 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +13 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/workflow/index.d.ts +10 -2
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +6 -0
- package/dist/workflow/index.js.map +1 -1
- package/dist-cjs/core/BytecodeChecker.js +526 -0
- package/dist-cjs/core/BytecodeChecker.js.map +1 -0
- package/dist-cjs/core/legacyProxyArtifact.js +42 -0
- package/dist-cjs/core/legacyProxyArtifact.js.map +1 -0
- package/dist-cjs/core/preparation/artifacts.js +11 -4
- package/dist-cjs/core/preparation/artifacts.js.map +1 -1
- package/dist-cjs/core/preparation/batch.js +76 -0
- package/dist-cjs/core/preparation/batch.js.map +1 -0
- package/dist-cjs/core/preparation/evm.js +128 -37
- package/dist-cjs/core/preparation/evm.js.map +1 -1
- package/dist-cjs/core/preparation/evmManifestSync.js +163 -0
- package/dist-cjs/core/preparation/evmManifestSync.js.map +1 -0
- package/dist-cjs/core/preparation/index.js +3 -3
- package/dist-cjs/core/preparation/index.js.map +1 -1
- package/dist-cjs/core/preparation/manifest.js +25 -30
- package/dist-cjs/core/preparation/manifest.js.map +1 -1
- package/dist-cjs/core/preparation/normalize.js +67 -20
- package/dist-cjs/core/preparation/normalize.js.map +1 -1
- package/dist-cjs/core/preparation/transparent.js +110 -0
- package/dist-cjs/core/preparation/transparent.js.map +1 -0
- package/dist-cjs/core/preparation/zksync.js +2 -0
- package/dist-cjs/core/preparation/zksync.js.map +1 -1
- package/dist-cjs/custody/credential.js +1 -6
- package/dist-cjs/custody/credential.js.map +1 -1
- package/dist-cjs/custody/hardhat-runtime.js +2 -0
- package/dist-cjs/custody/hardhat-runtime.js.map +1 -1
- package/dist-cjs/custody/hardhat.js +3 -1
- package/dist-cjs/custody/hardhat.js.map +1 -1
- package/dist-cjs/custody/index.js +3 -1
- package/dist-cjs/custody/index.js.map +1 -1
- package/dist-cjs/custody/provider-wait.js +81 -0
- package/dist-cjs/custody/provider-wait.js.map +1 -0
- package/dist-cjs/delivery/policy.js +29 -0
- package/dist-cjs/delivery/policy.js.map +1 -0
- package/dist-cjs/deployment-evm/index.js +10 -0
- package/dist-cjs/deployment-evm/index.js.map +1 -0
- package/dist-cjs/sync/index.js +13 -0
- package/dist-cjs/sync/index.js.map +1 -1
- package/dist-cjs/workflow/index.js +22 -1
- package/dist-cjs/workflow/index.js.map +1 -1
- package/dist-runtime/config/hardhatAdapters.js +2 -1
- package/dist-runtime/config/hardhatAdapters.js.map +1 -1
- package/dist-runtime/config/openzeppelin.d.ts +2 -1
- package/dist-runtime/config/openzeppelin.js +2 -19
- package/dist-runtime/config/openzeppelin.js.map +1 -1
- package/dist-runtime/delivery/abi.d.ts +14 -0
- package/dist-runtime/delivery/abi.js +161 -0
- package/dist-runtime/delivery/abi.js.map +1 -0
- package/dist-runtime/delivery/aggregate-bootstrap.d.ts +12 -0
- package/dist-runtime/delivery/aggregate-bootstrap.js +42 -0
- package/dist-runtime/delivery/aggregate-bootstrap.js.map +1 -0
- package/dist-runtime/delivery/aggregate-channel.d.ts +28 -0
- package/dist-runtime/delivery/aggregate-channel.js +159 -0
- package/dist-runtime/delivery/aggregate-channel.js.map +1 -0
- package/dist-runtime/delivery/aggregate-diagnostics.d.ts +14 -0
- package/dist-runtime/delivery/aggregate-diagnostics.js +73 -0
- package/dist-runtime/delivery/aggregate-diagnostics.js.map +1 -0
- package/dist-runtime/delivery/aggregate-inputs.d.ts +172 -0
- package/dist-runtime/delivery/aggregate-inputs.js +57 -0
- package/dist-runtime/delivery/aggregate-inputs.js.map +1 -0
- package/dist-runtime/delivery/aggregate-source.d.ts +25 -0
- package/dist-runtime/delivery/aggregate-source.js +87 -0
- package/dist-runtime/delivery/aggregate-source.js.map +1 -0
- package/dist-runtime/delivery/aggregate-worker.d.ts +1 -0
- package/dist-runtime/delivery/aggregate-worker.js +199 -0
- package/dist-runtime/delivery/aggregate-worker.js.map +1 -0
- package/dist-runtime/delivery/aggregate.d.ts +51 -0
- package/dist-runtime/delivery/aggregate.js +190 -0
- package/dist-runtime/delivery/aggregate.js.map +1 -0
- package/dist-runtime/delivery/bindings.d.ts +21 -0
- package/dist-runtime/delivery/bindings.js +53 -0
- package/dist-runtime/delivery/bindings.js.map +1 -0
- package/dist-runtime/delivery/business-extension.d.ts +10 -0
- package/dist-runtime/delivery/business-extension.js +38 -0
- package/dist-runtime/delivery/business-extension.js.map +1 -0
- package/dist-runtime/delivery/calldata-archive.d.ts +18 -0
- package/dist-runtime/delivery/calldata-archive.js +31 -0
- package/dist-runtime/delivery/calldata-archive.js.map +1 -0
- package/dist-runtime/delivery/calldata-details.d.ts +47 -0
- package/dist-runtime/delivery/calldata-details.js +94 -0
- package/dist-runtime/delivery/calldata-details.js.map +1 -0
- package/dist-runtime/delivery/calldata-format.d.ts +4 -0
- package/dist-runtime/delivery/calldata-format.js +17 -0
- package/dist-runtime/delivery/calldata-format.js.map +1 -0
- package/dist-runtime/delivery/calldata-preparations.d.ts +13 -0
- package/dist-runtime/delivery/calldata-preparations.js +85 -0
- package/dist-runtime/delivery/calldata-preparations.js.map +1 -0
- package/dist-runtime/delivery/calldata-review.d.ts +44 -0
- package/dist-runtime/delivery/calldata-review.js +131 -0
- package/dist-runtime/delivery/calldata-review.js.map +1 -0
- package/dist-runtime/delivery/check-code.d.ts +19 -0
- package/dist-runtime/delivery/check-code.js +63 -0
- package/dist-runtime/delivery/check-code.js.map +1 -0
- package/dist-runtime/delivery/closure-format.d.ts +77 -0
- package/dist-runtime/delivery/closure-format.js +225 -0
- package/dist-runtime/delivery/closure-format.js.map +1 -0
- package/dist-runtime/delivery/codec-pin.d.ts +2 -0
- package/dist-runtime/delivery/codec-pin.js +7 -0
- package/dist-runtime/delivery/codec-pin.js.map +1 -0
- package/dist-runtime/delivery/codec.d.ts +19 -0
- package/dist-runtime/delivery/codec.js +73 -0
- package/dist-runtime/delivery/codec.js.map +1 -0
- package/dist-runtime/delivery/compiler-dependency-pins.d.ts +7 -0
- package/dist-runtime/delivery/compiler-dependency-pins.js +1689 -0
- package/dist-runtime/delivery/compiler-dependency-pins.js.map +1 -0
- package/dist-runtime/delivery/compiler-files.d.ts +40 -0
- package/dist-runtime/delivery/compiler-files.js +222 -0
- package/dist-runtime/delivery/compiler-files.js.map +1 -0
- package/dist-runtime/delivery/compiler-io.d.ts +2 -0
- package/dist-runtime/delivery/compiler-io.js +13 -0
- package/dist-runtime/delivery/compiler-io.js.map +1 -0
- package/dist-runtime/delivery/compiler-pins.d.ts +10 -0
- package/dist-runtime/delivery/compiler-pins.js +147 -0
- package/dist-runtime/delivery/compiler-pins.js.map +1 -0
- package/dist-runtime/delivery/compiler.d.ts +188 -0
- package/dist-runtime/delivery/compiler.js +851 -0
- package/dist-runtime/delivery/compiler.js.map +1 -0
- package/dist-runtime/delivery/config.d.ts +48 -0
- package/dist-runtime/delivery/config.js +124 -0
- package/dist-runtime/delivery/config.js.map +1 -0
- package/dist-runtime/delivery/configuration-definition.d.ts +31 -0
- package/dist-runtime/delivery/configuration-definition.js +343 -0
- package/dist-runtime/delivery/configuration-definition.js.map +1 -0
- package/dist-runtime/delivery/configuration-hre.d.ts +17 -0
- package/dist-runtime/delivery/configuration-hre.js +198 -0
- package/dist-runtime/delivery/configuration-hre.js.map +1 -0
- package/dist-runtime/delivery/configuration-runtime.d.ts +36 -0
- package/dist-runtime/delivery/configuration-runtime.js +248 -0
- package/dist-runtime/delivery/configuration-runtime.js.map +1 -0
- package/dist-runtime/delivery/configuration.d.ts +35 -0
- package/dist-runtime/delivery/configuration.js +86 -0
- package/dist-runtime/delivery/configuration.js.map +1 -0
- package/dist-runtime/delivery/contract-source.d.ts +14 -0
- package/dist-runtime/delivery/contract-source.js +138 -0
- package/dist-runtime/delivery/contract-source.js.map +1 -0
- package/dist-runtime/delivery/create2.d.ts +3 -0
- package/dist-runtime/delivery/create2.js +48 -0
- package/dist-runtime/delivery/create2.js.map +1 -0
- package/dist-runtime/delivery/custom-closure.d.ts +27 -0
- package/dist-runtime/delivery/custom-closure.js +818 -0
- package/dist-runtime/delivery/custom-closure.js.map +1 -0
- package/dist-runtime/delivery/custom-format.d.ts +35 -0
- package/dist-runtime/delivery/custom-format.js +410 -0
- package/dist-runtime/delivery/custom-format.js.map +1 -0
- package/dist-runtime/delivery/custom.d.ts +32 -0
- package/dist-runtime/delivery/custom.js +158 -0
- package/dist-runtime/delivery/custom.js.map +1 -0
- package/dist-runtime/delivery/data.d.ts +7 -0
- package/dist-runtime/delivery/data.js +86 -0
- package/dist-runtime/delivery/data.js.map +1 -0
- package/dist-runtime/delivery/development.d.ts +92 -0
- package/dist-runtime/delivery/development.js +406 -0
- package/dist-runtime/delivery/development.js.map +1 -0
- package/dist-runtime/delivery/engine.d.ts +9 -0
- package/dist-runtime/delivery/engine.js +23 -0
- package/dist-runtime/delivery/engine.js.map +1 -0
- package/dist-runtime/delivery/eoa-observation.d.ts +43 -0
- package/dist-runtime/delivery/eoa-observation.js +145 -0
- package/dist-runtime/delivery/eoa-observation.js.map +1 -0
- package/dist-runtime/delivery/eoa-signed.d.ts +2 -0
- package/dist-runtime/delivery/eoa-signed.js +74 -0
- package/dist-runtime/delivery/eoa-signed.js.map +1 -0
- package/dist-runtime/delivery/eoa.d.ts +82 -0
- package/dist-runtime/delivery/eoa.js +274 -0
- package/dist-runtime/delivery/eoa.js.map +1 -0
- package/dist-runtime/delivery/execution-db.d.ts +20 -0
- package/dist-runtime/delivery/execution-db.js +153 -0
- package/dist-runtime/delivery/execution-db.js.map +1 -0
- package/dist-runtime/delivery/execution-files.d.ts +9 -0
- package/dist-runtime/delivery/execution-files.js +138 -0
- package/dist-runtime/delivery/execution-files.js.map +1 -0
- package/dist-runtime/delivery/execution-identity.d.ts +15 -0
- package/dist-runtime/delivery/execution-identity.js +33 -0
- package/dist-runtime/delivery/execution-identity.js.map +1 -0
- package/dist-runtime/delivery/execution-model.d.ts +56 -0
- package/dist-runtime/delivery/execution-model.js +66 -0
- package/dist-runtime/delivery/execution-model.js.map +1 -0
- package/dist-runtime/delivery/execution-store.d.ts +48 -0
- package/dist-runtime/delivery/execution-store.js +361 -0
- package/dist-runtime/delivery/execution-store.js.map +1 -0
- package/dist-runtime/delivery/existing-code.d.ts +37 -0
- package/dist-runtime/delivery/existing-code.js +83 -0
- package/dist-runtime/delivery/existing-code.js.map +1 -0
- package/dist-runtime/delivery/export.d.ts +51 -0
- package/dist-runtime/delivery/export.js +69 -0
- package/dist-runtime/delivery/export.js.map +1 -0
- package/dist-runtime/delivery/forkAudit.d.ts +119 -0
- package/dist-runtime/delivery/forkAudit.js +473 -0
- package/dist-runtime/delivery/forkAudit.js.map +1 -0
- package/dist-runtime/delivery/hardhat.d.ts +3 -0
- package/dist-runtime/delivery/hardhat.js +45 -0
- package/dist-runtime/delivery/hardhat.js.map +1 -0
- package/dist-runtime/delivery/history-registration.d.ts +2 -0
- package/dist-runtime/delivery/history-registration.js +17 -0
- package/dist-runtime/delivery/history-registration.js.map +1 -0
- package/dist-runtime/delivery/identities.d.ts +22 -0
- package/dist-runtime/delivery/identities.js +97 -0
- package/dist-runtime/delivery/identities.js.map +1 -0
- package/dist-runtime/delivery/input-files.d.ts +5 -0
- package/dist-runtime/delivery/input-files.js +70 -0
- package/dist-runtime/delivery/input-files.js.map +1 -0
- package/dist-runtime/delivery/inputs.d.ts +62 -0
- package/dist-runtime/delivery/inputs.js +194 -0
- package/dist-runtime/delivery/inputs.js.map +1 -0
- package/dist-runtime/delivery/journal.d.ts +35 -0
- package/dist-runtime/delivery/journal.js +278 -0
- package/dist-runtime/delivery/journal.js.map +1 -0
- package/dist-runtime/delivery/manifest.d.ts +14 -0
- package/dist-runtime/delivery/manifest.js +68 -0
- package/dist-runtime/delivery/manifest.js.map +1 -0
- package/dist-runtime/delivery/materialization.d.ts +20 -0
- package/dist-runtime/delivery/materialization.js +138 -0
- package/dist-runtime/delivery/materialization.js.map +1 -0
- package/dist-runtime/delivery/observations.d.ts +31 -0
- package/dist-runtime/delivery/observations.js +38 -0
- package/dist-runtime/delivery/observations.js.map +1 -0
- package/dist-runtime/delivery/parameter-defaults.d.ts +10 -0
- package/dist-runtime/delivery/parameter-defaults.js +86 -0
- package/dist-runtime/delivery/parameter-defaults.js.map +1 -0
- package/dist-runtime/delivery/parameters.d.ts +55 -0
- package/dist-runtime/delivery/parameters.js +279 -0
- package/dist-runtime/delivery/parameters.js.map +1 -0
- package/dist-runtime/delivery/pending.d.ts +70 -0
- package/dist-runtime/delivery/pending.js +99 -0
- package/dist-runtime/delivery/pending.js.map +1 -0
- package/dist-runtime/delivery/plan.d.ts +50 -0
- package/dist-runtime/delivery/plan.js +209 -0
- package/dist-runtime/delivery/plan.js.map +1 -0
- package/dist-runtime/delivery/planning.d.ts +84 -0
- package/dist-runtime/delivery/planning.js +318 -0
- package/dist-runtime/delivery/planning.js.map +1 -0
- package/dist-runtime/delivery/policy.d.ts +4 -0
- package/dist-runtime/delivery/policy.js +9 -0
- package/dist-runtime/delivery/policy.js.map +1 -0
- package/dist-runtime/delivery/preparation.d.ts +6 -0
- package/dist-runtime/delivery/preparation.js +178 -0
- package/dist-runtime/delivery/preparation.js.map +1 -0
- package/dist-runtime/delivery/production-environment.d.ts +2 -0
- package/dist-runtime/delivery/production-environment.js +13 -0
- package/dist-runtime/delivery/production-environment.js.map +1 -0
- package/dist-runtime/delivery/production-finalization.d.ts +86 -0
- package/dist-runtime/delivery/production-finalization.js +292 -0
- package/dist-runtime/delivery/production-finalization.js.map +1 -0
- package/dist-runtime/delivery/production-intent.d.ts +2 -0
- package/dist-runtime/delivery/production-intent.js +16 -0
- package/dist-runtime/delivery/production-intent.js.map +1 -0
- package/dist-runtime/delivery/production.d.ts +582 -0
- package/dist-runtime/delivery/production.js +445 -0
- package/dist-runtime/delivery/production.js.map +1 -0
- package/dist-runtime/delivery/project-files.d.ts +8 -0
- package/dist-runtime/delivery/project-files.js +87 -0
- package/dist-runtime/delivery/project-files.js.map +1 -0
- package/dist-runtime/delivery/project-rpc.d.ts +19 -0
- package/dist-runtime/delivery/project-rpc.js +138 -0
- package/dist-runtime/delivery/project-rpc.js.map +1 -0
- package/dist-runtime/delivery/project.d.ts +17 -0
- package/dist-runtime/delivery/project.js +170 -0
- package/dist-runtime/delivery/project.js.map +1 -0
- package/dist-runtime/delivery/protocol.d.ts +49 -0
- package/dist-runtime/delivery/protocol.js +112 -0
- package/dist-runtime/delivery/protocol.js.map +1 -0
- package/dist-runtime/delivery/public-calldata.d.ts +25 -0
- package/dist-runtime/delivery/public-calldata.js +97 -0
- package/dist-runtime/delivery/public-calldata.js.map +1 -0
- package/dist-runtime/delivery/references.d.ts +19 -0
- package/dist-runtime/delivery/references.js +84 -0
- package/dist-runtime/delivery/references.js.map +1 -0
- package/dist-runtime/delivery/release-graph.d.ts +97 -0
- package/dist-runtime/delivery/release-graph.js +139 -0
- package/dist-runtime/delivery/release-graph.js.map +1 -0
- package/dist-runtime/delivery/release-history-capture.d.ts +7 -0
- package/dist-runtime/delivery/release-history-capture.js +76 -0
- package/dist-runtime/delivery/release-history-capture.js.map +1 -0
- package/dist-runtime/delivery/release-history.d.ts +43 -0
- package/dist-runtime/delivery/release-history.js +322 -0
- package/dist-runtime/delivery/release-history.js.map +1 -0
- package/dist-runtime/delivery/release-inputs.d.ts +33 -0
- package/dist-runtime/delivery/release-inputs.js +129 -0
- package/dist-runtime/delivery/release-inputs.js.map +1 -0
- package/dist-runtime/delivery/release.d.ts +196 -0
- package/dist-runtime/delivery/release.js +261 -0
- package/dist-runtime/delivery/release.js.map +1 -0
- package/dist-runtime/delivery/safe-manifest.d.ts +9 -0
- package/dist-runtime/delivery/safe-manifest.js +13 -0
- package/dist-runtime/delivery/safe-manifest.js.map +1 -0
- package/dist-runtime/delivery/safe-observation.d.ts +30 -0
- package/dist-runtime/delivery/safe-observation.js +487 -0
- package/dist-runtime/delivery/safe-observation.js.map +1 -0
- package/dist-runtime/delivery/safe-prepare.d.ts +13 -0
- package/dist-runtime/delivery/safe-prepare.js +81 -0
- package/dist-runtime/delivery/safe-prepare.js.map +1 -0
- package/dist-runtime/delivery/safe.d.ts +92 -0
- package/dist-runtime/delivery/safe.js +254 -0
- package/dist-runtime/delivery/safe.js.map +1 -0
- package/dist-runtime/delivery/same-fork-baseline.d.ts +8 -0
- package/dist-runtime/delivery/same-fork-baseline.js +21 -0
- package/dist-runtime/delivery/same-fork-baseline.js.map +1 -0
- package/dist-runtime/delivery/setup.d.ts +31 -0
- package/dist-runtime/delivery/setup.js +230 -0
- package/dist-runtime/delivery/setup.js.map +1 -0
- package/dist-runtime/delivery/source.d.ts +42 -0
- package/dist-runtime/delivery/source.js +139 -0
- package/dist-runtime/delivery/source.js.map +1 -0
- package/dist-runtime/delivery/target-fields.d.ts +2 -0
- package/dist-runtime/delivery/target-fields.js +11 -0
- package/dist-runtime/delivery/target-fields.js.map +1 -0
- package/dist-runtime/delivery/task-identity.d.ts +23 -0
- package/dist-runtime/delivery/task-identity.js +109 -0
- package/dist-runtime/delivery/task-identity.js.map +1 -0
- package/dist-runtime/delivery/toolchain.d.ts +3 -0
- package/dist-runtime/delivery/toolchain.js +52 -0
- package/dist-runtime/delivery/toolchain.js.map +1 -0
- package/dist-runtime/delivery/validation.d.ts +9 -0
- package/dist-runtime/delivery/validation.js +155 -0
- package/dist-runtime/delivery/validation.js.map +1 -0
- package/dist-runtime/delivery/verification.d.ts +16 -0
- package/dist-runtime/delivery/verification.js +65 -0
- package/dist-runtime/delivery/verification.js.map +1 -0
- package/dist-runtime/migrate.js +1 -0
- package/dist-runtime/migrate.js.map +1 -1
- package/dist-runtime/miner/binary.d.ts +2 -0
- package/dist-runtime/miner/binary.js +54 -0
- package/dist-runtime/miner/binary.js.map +1 -0
- package/dist-runtime/miner/cli.d.ts +1 -0
- package/dist-runtime/miner/cli.js +131 -0
- package/dist-runtime/miner/cli.js.map +1 -0
- package/dist-runtime/miner/index.d.ts +5 -0
- package/dist-runtime/miner/index.js +13 -0
- package/dist-runtime/miner/index.js.map +1 -0
- package/dist-runtime/miner/request.d.ts +7 -0
- package/dist-runtime/miner/request.js +73 -0
- package/dist-runtime/miner/request.js.map +1 -0
- package/dist-runtime/miner/runner.d.ts +2 -0
- package/dist-runtime/miner/runner.js +131 -0
- package/dist-runtime/miner/runner.js.map +1 -0
- package/dist-runtime/miner/types.d.ts +89 -0
- package/dist-runtime/miner/types.js +3 -0
- package/dist-runtime/miner/types.js.map +1 -0
- package/dist-runtime/miner/verify.d.ts +2 -0
- package/dist-runtime/miner/verify.js +75 -0
- package/dist-runtime/miner/verify.js.map +1 -0
- package/dist-runtime/runtime-identity.json +2 -2
- package/dist-runtime/vendor/plan-codec/index.cjs +897 -0
- package/dist-runtime/vendor/plan-codec/index.d.cts +38 -0
- package/dist-runtime/vendor/plan-codec/provenance.json +25 -0
- package/dist-runtime/workflow/engine.d.ts +14 -0
- package/dist-runtime/workflow/engine.js +160 -0
- package/dist-runtime/workflow/engine.js.map +1 -0
- package/dist-runtime/workflow/lib/authority.d.ts +6 -3
- package/dist-runtime/workflow/lib/authority.js.map +1 -1
- package/dist-runtime/workflow/lib/calls.d.ts +1 -1
- package/dist-runtime/workflow/lib/calls.js +44 -34
- package/dist-runtime/workflow/lib/calls.js.map +1 -1
- package/dist-runtime/workflow/lib/canonicalData.d.ts +8 -0
- package/dist-runtime/workflow/lib/canonicalData.js +68 -0
- package/dist-runtime/workflow/lib/canonicalData.js.map +1 -0
- package/dist-runtime/workflow/lib/checkCodeRunner.js +7 -4
- package/dist-runtime/workflow/lib/checkCodeRunner.js.map +1 -1
- package/dist-runtime/workflow/lib/config.d.ts +3 -1
- package/dist-runtime/workflow/lib/config.js.map +1 -1
- package/dist-runtime/workflow/lib/context.d.ts +77 -0
- package/dist-runtime/workflow/lib/context.js +3 -0
- package/dist-runtime/workflow/lib/context.js.map +1 -0
- package/dist-runtime/workflow/lib/create2.d.ts +5 -27
- package/dist-runtime/workflow/lib/create2.js +11 -79
- package/dist-runtime/workflow/lib/create2.js.map +1 -1
- package/dist-runtime/workflow/lib/deploymentInfo.d.ts +2 -0
- package/dist-runtime/workflow/lib/deploymentInfo.js +6 -0
- package/dist-runtime/workflow/lib/deploymentInfo.js.map +1 -1
- package/dist-runtime/workflow/lib/deploymentRecords.d.ts +2 -0
- package/dist-runtime/workflow/lib/deploymentRecords.js +1 -1
- package/dist-runtime/workflow/lib/deploymentRecords.js.map +1 -1
- package/dist-runtime/workflow/lib/deployments.d.ts +5 -5
- package/dist-runtime/workflow/lib/deployments.js +5 -13
- package/dist-runtime/workflow/lib/deployments.js.map +1 -1
- package/dist-runtime/workflow/lib/evidencePorts.d.ts +55 -0
- package/dist-runtime/workflow/lib/evidencePorts.js +3 -0
- package/dist-runtime/workflow/lib/evidencePorts.js.map +1 -0
- package/dist-runtime/workflow/lib/executionPlan.d.ts +4 -42
- package/dist-runtime/workflow/lib/executionPlan.js +15 -210
- package/dist-runtime/workflow/lib/executionPlan.js.map +1 -1
- package/dist-runtime/workflow/lib/externalExecutionScanner.js +2 -1
- package/dist-runtime/workflow/lib/externalExecutionScanner.js.map +1 -1
- package/dist-runtime/workflow/lib/gateTool.d.ts +6 -2
- package/dist-runtime/workflow/lib/gateTool.js +22 -12
- package/dist-runtime/workflow/lib/gateTool.js.map +1 -1
- package/dist-runtime/workflow/lib/gateToolSync.d.ts +4 -1
- package/dist-runtime/workflow/lib/gateToolSync.js +8 -2
- package/dist-runtime/workflow/lib/gateToolSync.js.map +1 -1
- package/dist-runtime/workflow/lib/operationNames.d.ts +3 -0
- package/dist-runtime/workflow/lib/operationNames.js +34 -0
- package/dist-runtime/workflow/lib/operationNames.js.map +1 -0
- package/dist-runtime/workflow/lib/parameters.d.ts +1 -1
- package/dist-runtime/workflow/lib/parameters.js +11 -22
- package/dist-runtime/workflow/lib/parameters.js.map +1 -1
- package/dist-runtime/workflow/lib/pendingDeploymentReuse.js +18 -52
- package/dist-runtime/workflow/lib/pendingDeploymentReuse.js.map +1 -1
- package/dist-runtime/workflow/lib/pendingUupsBinding.d.ts +42 -0
- package/dist-runtime/workflow/lib/pendingUupsBinding.js +39 -0
- package/dist-runtime/workflow/lib/pendingUupsBinding.js.map +1 -0
- package/dist-runtime/workflow/lib/plan.d.ts +55 -0
- package/dist-runtime/workflow/lib/plan.js +324 -0
- package/dist-runtime/workflow/lib/plan.js.map +1 -0
- package/dist-runtime/workflow/lib/planCli.d.ts +14 -0
- package/dist-runtime/workflow/lib/planCli.js +279 -0
- package/dist-runtime/workflow/lib/planCli.js.map +1 -0
- package/dist-runtime/workflow/lib/preparationEvidence.d.ts +4 -0
- package/dist-runtime/workflow/lib/preparationEvidence.js +19 -0
- package/dist-runtime/workflow/lib/preparationEvidence.js.map +1 -0
- package/dist-runtime/workflow/lib/proxy.d.ts +4 -2
- package/dist-runtime/workflow/lib/proxy.js +3 -4
- package/dist-runtime/workflow/lib/proxy.js.map +1 -1
- package/dist-runtime/workflow/lib/runtime.d.ts +6 -0
- package/dist-runtime/workflow/lib/runtime.js +48 -0
- package/dist-runtime/workflow/lib/runtime.js.map +1 -0
- package/dist-runtime/workflow/lib/signer.d.ts +3 -2
- package/dist-runtime/workflow/lib/signer.js +18 -18
- package/dist-runtime/workflow/lib/signer.js.map +1 -1
- package/dist-runtime/workflow/lib/simulation.d.ts +13 -6
- package/dist-runtime/workflow/lib/simulation.js +39 -31
- package/dist-runtime/workflow/lib/simulation.js.map +1 -1
- package/dist-runtime/workflow/lib/state.js +3 -3
- package/dist-runtime/workflow/lib/state.js.map +1 -1
- package/dist-runtime/workflow/lib/staticValidation.d.ts +28 -0
- package/dist-runtime/workflow/lib/staticValidation.js +54 -10
- package/dist-runtime/workflow/lib/staticValidation.js.map +1 -1
- package/dist-runtime/workflow/lib/transactionPlanner.d.ts +62 -0
- package/dist-runtime/workflow/lib/transactionPlanner.js +258 -0
- package/dist-runtime/workflow/lib/transactionPlanner.js.map +1 -0
- package/dist-runtime/workflow/lib/typedValue.d.ts +3 -0
- package/dist-runtime/workflow/lib/typedValue.js +76 -0
- package/dist-runtime/workflow/lib/typedValue.js.map +1 -0
- package/dist-runtime/workflow/lib/validation.d.ts +23 -0
- package/dist-runtime/workflow/lib/validation.js +15 -0
- package/dist-runtime/workflow/lib/validation.js.map +1 -0
- package/dist-runtime/workflow/planAdd.d.ts +1 -0
- package/dist-runtime/workflow/planAdd.js +11 -0
- package/dist-runtime/workflow/planAdd.js.map +1 -0
- package/dist-runtime/workflow/planRead.d.ts +1 -0
- package/dist-runtime/workflow/planRead.js +11 -0
- package/dist-runtime/workflow/planRead.js.map +1 -0
- package/dist-runtime/workflow/planStatus.d.ts +1 -0
- package/dist-runtime/workflow/planStatus.js +11 -0
- package/dist-runtime/workflow/planStatus.js.map +1 -0
- package/dist-runtime/workflow/planWrite.d.ts +1 -0
- package/dist-runtime/workflow/planWrite.js +11 -0
- package/dist-runtime/workflow/planWrite.js.map +1 -0
- package/dist-runtime/workflow/run.d.ts +1 -40
- package/dist-runtime/workflow/run.js +69 -139
- package/dist-runtime/workflow/run.js.map +1 -1
- package/dist-runtime/workflow/staticValidate.js +8 -3
- package/dist-runtime/workflow/staticValidate.js.map +1 -1
- package/dist-runtime/workflow/steps/call.d.ts +1 -1
- package/dist-runtime/workflow/steps/check.d.ts +1 -1
- package/dist-runtime/workflow/steps/custom.d.ts +1 -1
- package/dist-runtime/workflow/steps/deploy.d.ts +1 -1
- package/dist-runtime/workflow/steps/deploy.js +110 -55
- package/dist-runtime/workflow/steps/deploy.js.map +1 -1
- package/dist-runtime/workflow/steps/upgrade.d.ts +1 -1
- package/dist-runtime/workflow/steps/upgrade.js +84 -49
- package/dist-runtime/workflow/steps/upgrade.js.map +1 -1
- package/dist-runtime/workflow/steps/view.d.ts +1 -1
- package/docs/compiler-qualification.md +38 -0
- package/docs/configuration-runtime-observation.md +29 -0
- package/docs/create2-miner.md +100 -0
- package/docs/delivery-aggregate.md +29 -0
- package/docs/delivery-calldata.md +27 -0
- package/docs/delivery-custom-input-closure.md +51 -0
- package/docs/delivery-development.md +38 -0
- package/docs/delivery-eoa.md +46 -0
- package/docs/delivery-evm-manifest.md +20 -0
- package/docs/delivery-execution-store.md +33 -0
- package/docs/delivery-inputs.md +95 -0
- package/docs/delivery-parameters.md +65 -0
- package/docs/delivery-planning.md +140 -0
- package/docs/delivery-release.md +119 -0
- package/docs/delivery-safe.md +75 -0
- package/docs/delivery-setup.md +198 -0
- package/docs/delivery-source.md +67 -0
- package/docs/direct-package-acceptance.md +2 -0
- package/docs/openzeppelin-acceptance.md +86 -0
- package/docs/openzeppelin-baseline.json +27 -0
- package/docs/openzeppelin-integration.md +115 -0
- package/docs/plans/2026-10-28-openzeppelin-toolkit-consolidation.md +396 -0
- package/docs/plans/2026-11-02-transparent-proxy-delivery.md +78 -0
- package/docs/superpowers/plans/2026-08-17-custody-hardhat-signers.md +1 -1
- package/docs/superpowers/plans/2026-09-24-scheme-aware-static-validation.md +193 -0
- package/docs/superpowers/plans/2026-10-28-create2-miner.md +82 -0
- package/docs/workflow-reference.md +12 -4
- package/docs/workflow-runtime.md +6 -0
- package/package.json +148 -10
- package/resources/create2/LICENSE +21 -0
- package/resources/create2/README.md +9 -0
- package/resources/create2/darwin-arm64/smartflow_miner +0 -0
- package/resources/create2/darwin-x64/smartflow_miner +0 -0
- package/resources/create2/manifest.json +27 -0
- package/runtime/config/hardhatAdapters.ts +2 -1
- package/runtime/config/openzeppelin.ts +3 -21
- package/runtime/delivery/abi.ts +225 -0
- package/runtime/delivery/aggregate-bootstrap.ts +31 -0
- package/runtime/delivery/aggregate-channel.ts +88 -0
- package/runtime/delivery/aggregate-diagnostics.ts +63 -0
- package/runtime/delivery/aggregate-inputs.ts +39 -0
- package/runtime/delivery/aggregate-source.ts +57 -0
- package/runtime/delivery/aggregate-worker.ts +143 -0
- package/runtime/delivery/aggregate.ts +139 -0
- package/runtime/delivery/bindings.ts +37 -0
- package/runtime/delivery/business-extension.ts +33 -0
- package/runtime/delivery/calldata-archive.ts +25 -0
- package/runtime/delivery/calldata-details.ts +90 -0
- package/runtime/delivery/calldata-format.ts +14 -0
- package/runtime/delivery/calldata-preparations.ts +76 -0
- package/runtime/delivery/calldata-review.ts +126 -0
- package/runtime/delivery/check-code.ts +38 -0
- package/runtime/delivery/closure-format.ts +350 -0
- package/runtime/delivery/codec-pin.ts +3 -0
- package/runtime/delivery/codec.ts +50 -0
- package/runtime/delivery/compiler-dependency-pins.ts +1685 -0
- package/runtime/delivery/compiler-files.ts +181 -0
- package/runtime/delivery/compiler-io.ts +10 -0
- package/runtime/delivery/compiler-pins.ts +143 -0
- package/runtime/delivery/compiler.ts +701 -0
- package/runtime/delivery/config.ts +116 -0
- package/runtime/delivery/configuration-definition.ts +160 -0
- package/runtime/delivery/configuration-hre.ts +130 -0
- package/runtime/delivery/configuration-runtime.ts +163 -0
- package/runtime/delivery/configuration.ts +67 -0
- package/runtime/delivery/contract-source.ts +112 -0
- package/runtime/delivery/create2.ts +57 -0
- package/runtime/delivery/custom-closure.ts +993 -0
- package/runtime/delivery/custom-format.ts +479 -0
- package/runtime/delivery/custom.ts +219 -0
- package/runtime/delivery/data.ts +94 -0
- package/runtime/delivery/development.ts +264 -0
- package/runtime/delivery/engine.ts +29 -0
- package/runtime/delivery/eoa-observation.ts +106 -0
- package/runtime/delivery/eoa-signed.ts +55 -0
- package/runtime/delivery/eoa.ts +288 -0
- package/runtime/delivery/execution-db.ts +131 -0
- package/runtime/delivery/execution-files.ts +135 -0
- package/runtime/delivery/execution-identity.ts +32 -0
- package/runtime/delivery/execution-model.ts +102 -0
- package/runtime/delivery/execution-store.ts +411 -0
- package/runtime/delivery/existing-code.ts +45 -0
- package/runtime/delivery/export.ts +99 -0
- package/runtime/delivery/forkAudit.ts +620 -0
- package/runtime/delivery/hardhat.ts +38 -0
- package/runtime/delivery/history-registration.ts +10 -0
- package/runtime/delivery/identities.ts +132 -0
- package/runtime/delivery/input-files.ts +46 -0
- package/runtime/delivery/inputs.ts +204 -0
- package/runtime/delivery/journal.ts +205 -0
- package/runtime/delivery/manifest.ts +54 -0
- package/runtime/delivery/materialization.ts +53 -0
- package/runtime/delivery/observations.ts +60 -0
- package/runtime/delivery/parameter-defaults.ts +75 -0
- package/runtime/delivery/parameters.ts +367 -0
- package/runtime/delivery/pending.ts +98 -0
- package/runtime/delivery/plan.ts +337 -0
- package/runtime/delivery/planning.ts +411 -0
- package/runtime/delivery/policy.ts +9 -0
- package/runtime/delivery/preparation.ts +240 -0
- package/runtime/delivery/production-environment.ts +7 -0
- package/runtime/delivery/production-finalization.ts +181 -0
- package/runtime/delivery/production-intent.ts +14 -0
- package/runtime/delivery/production.ts +415 -0
- package/runtime/delivery/project-files.ts +63 -0
- package/runtime/delivery/project-rpc.ts +116 -0
- package/runtime/delivery/project.ts +129 -0
- package/runtime/delivery/protocol.ts +94 -0
- package/runtime/delivery/public-calldata.ts +74 -0
- package/runtime/delivery/references.ts +106 -0
- package/runtime/delivery/release-graph.ts +79 -0
- package/runtime/delivery/release-history-capture.ts +32 -0
- package/runtime/delivery/release-history.ts +178 -0
- package/runtime/delivery/release-inputs.ts +107 -0
- package/runtime/delivery/release.ts +166 -0
- package/runtime/delivery/safe-manifest.ts +11 -0
- package/runtime/delivery/safe-observation.ts +626 -0
- package/runtime/delivery/safe-prepare.ts +101 -0
- package/runtime/delivery/safe.ts +355 -0
- package/runtime/delivery/same-fork-baseline.ts +17 -0
- package/runtime/delivery/setup.ts +184 -0
- package/runtime/delivery/source.ts +130 -0
- package/runtime/delivery/target-fields.ts +7 -0
- package/runtime/delivery/task-identity.ts +85 -0
- package/runtime/delivery/toolchain.ts +48 -0
- package/runtime/delivery/validation.ts +252 -0
- package/runtime/delivery/verification.ts +47 -0
- package/runtime/migrate.ts +1 -0
- package/runtime/miner/binary.ts +41 -0
- package/runtime/miner/cli.ts +87 -0
- package/runtime/miner/index.ts +5 -0
- package/runtime/miner/request.ts +54 -0
- package/runtime/miner/runner.ts +90 -0
- package/runtime/miner/types.ts +71 -0
- package/runtime/miner/verify.ts +61 -0
- package/runtime/vendor/plan-codec/index.cjs +897 -0
- package/runtime/vendor/plan-codec/index.d.cts +38 -0
- package/runtime/vendor/plan-codec/provenance.json +25 -0
- package/runtime/workflow/engine.ts +174 -0
- package/runtime/workflow/lib/authority.ts +3 -3
- package/runtime/workflow/lib/calls.ts +47 -37
- package/runtime/workflow/lib/canonicalData.ts +45 -0
- package/runtime/workflow/lib/checkCodeRunner.ts +7 -3
- package/runtime/workflow/lib/config.ts +1 -1
- package/runtime/workflow/lib/context.ts +77 -0
- package/runtime/workflow/lib/create2.ts +18 -121
- package/runtime/workflow/lib/deploymentInfo.ts +8 -0
- package/runtime/workflow/lib/deploymentRecords.ts +3 -1
- package/runtime/workflow/lib/deployments.ts +6 -14
- package/runtime/workflow/lib/evidencePorts.ts +20 -0
- package/runtime/workflow/lib/executionPlan.ts +17 -268
- package/runtime/workflow/lib/externalExecutionScanner.ts +2 -1
- package/runtime/workflow/lib/gateTool.ts +22 -10
- package/runtime/workflow/lib/gateToolSync.ts +11 -3
- package/runtime/workflow/lib/operationNames.ts +32 -0
- package/runtime/workflow/lib/parameters.ts +8 -21
- package/runtime/workflow/lib/pendingDeploymentReuse.ts +4 -56
- package/runtime/workflow/lib/pendingUupsBinding.ts +43 -0
- package/runtime/workflow/lib/plan.ts +334 -0
- package/runtime/workflow/lib/planCli.ts +279 -0
- package/runtime/workflow/lib/preparationEvidence.ts +14 -0
- package/runtime/workflow/lib/proxy.ts +6 -3
- package/runtime/workflow/lib/runtime.ts +46 -0
- package/runtime/workflow/lib/signer.ts +8 -5
- package/runtime/workflow/lib/simulation.ts +41 -17
- package/runtime/workflow/lib/state.ts +3 -3
- package/runtime/workflow/lib/staticValidation.ts +92 -11
- package/runtime/workflow/lib/transactionPlanner.ts +314 -0
- package/runtime/workflow/lib/typedValue.ts +46 -0
- package/runtime/workflow/lib/validation.ts +50 -0
- package/runtime/workflow/planAdd.ts +8 -0
- package/runtime/workflow/planRead.ts +8 -0
- package/runtime/workflow/planStatus.ts +8 -0
- package/runtime/workflow/planWrite.ts +8 -0
- package/runtime/workflow/run.ts +42 -176
- package/runtime/workflow/staticValidate.ts +8 -3
- package/runtime/workflow/steps/call.ts +1 -1
- package/runtime/workflow/steps/check.ts +1 -1
- package/runtime/workflow/steps/custom.ts +1 -1
- package/runtime/workflow/steps/deploy.ts +99 -58
- package/runtime/workflow/steps/upgrade.ts +88 -57
- package/runtime/workflow/steps/view.ts +1 -1
- package/bin/workflow.cjs +0 -19
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import YAML from "yaml";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Read and write `handoff.md`, the plan-level carrier shared by the GateFlow
|
|
7
|
+
* entry point and the Codex command line.
|
|
8
|
+
*
|
|
9
|
+
* This is deliberately NOT the execution-level `handoff.json`: that one records
|
|
10
|
+
* deployment evidence and is validated byte for byte by the deployment gates.
|
|
11
|
+
* The plan layer says what is to be done; the execution layer proves what was.
|
|
12
|
+
* Keeping them in separate files is the point -- neither should have to carry
|
|
13
|
+
* the other's fields.
|
|
14
|
+
*
|
|
15
|
+
* Nothing here trusts the file. A plan that moves between two runtimes is
|
|
16
|
+
* exactly where a crafted document would be worth writing, so the parse is
|
|
17
|
+
* strict, the forbidden-field list is checked recursively, and the writer is
|
|
18
|
+
* the only sanctioned producer of the deterministic parts.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export const PLAN_SCHEMA = "gateflow-plan/v1";
|
|
22
|
+
export const PLAN_FILE = "handoff.md";
|
|
23
|
+
export const SECTIONS = ["development", "audit", "deployment"] as const;
|
|
24
|
+
export type PlanSection = (typeof SECTIONS)[number];
|
|
25
|
+
|
|
26
|
+
export const TASK_STATUSES = ["pending", "ready", "running", "completed", "failed", "cancelled"] as const;
|
|
27
|
+
export type TaskStatus = (typeof TASK_STATUSES)[number];
|
|
28
|
+
|
|
29
|
+
/** Local bindings. A plan changes entry point, so none of these can travel. */
|
|
30
|
+
const FORBIDDEN_FIELDS = [
|
|
31
|
+
"sessionid", "runtimerunid", "stageid", "attemptid", "workspacepath",
|
|
32
|
+
"authorizationid", "executionlock", "localstate", "planid", "workspacerelativepath",
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
export interface PlanTask {
|
|
36
|
+
planKey: string;
|
|
37
|
+
title: string;
|
|
38
|
+
objective: string;
|
|
39
|
+
acceptance: string[];
|
|
40
|
+
dependsOn: string[];
|
|
41
|
+
status: TaskStatus;
|
|
42
|
+
scope?: Record<string, unknown>;
|
|
43
|
+
parameters?: unknown[];
|
|
44
|
+
expectedArtifacts?: string[];
|
|
45
|
+
allowedChanges?: string[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface Plan {
|
|
49
|
+
schema: string;
|
|
50
|
+
taskId: string;
|
|
51
|
+
revision: number;
|
|
52
|
+
title: string;
|
|
53
|
+
sections: Record<PlanSection, "enabled" | "disabled">;
|
|
54
|
+
updatedAt: string;
|
|
55
|
+
tasks: Record<PlanSection, PlanTask[]>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const SAFE_KEY = /^[a-z0-9][a-z0-9-]{0,199}$/;
|
|
59
|
+
|
|
60
|
+
function fail(message: string): never {
|
|
61
|
+
throw new Error(`handoff.md: ${message}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function normalizeFieldName(key: string): string {
|
|
65
|
+
return key.replace(/[_-]/g, "").toLowerCase();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Recursive, because a forbidden name is just as bad nested as at the top. */
|
|
69
|
+
function assertNoForbiddenFields(value: unknown, where: string): void {
|
|
70
|
+
if (Array.isArray(value)) {
|
|
71
|
+
value.forEach((item, index) => assertNoForbiddenFields(item, `${where}[${index}]`));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (!value || typeof value !== "object") return;
|
|
75
|
+
for (const [key, child] of Object.entries(value)) {
|
|
76
|
+
if (FORBIDDEN_FIELDS.includes(normalizeFieldName(key))) {
|
|
77
|
+
fail(`${where}.${key} is a local binding and cannot travel between entry points`);
|
|
78
|
+
}
|
|
79
|
+
assertNoForbiddenFields(child, `${where}.${key}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const ABSOLUTE = /^(?:\/|\\|[A-Za-z]:[\\/]|~\/)/;
|
|
84
|
+
|
|
85
|
+
function assertNoSecretsOrPaths(value: unknown, where: string): void {
|
|
86
|
+
if (typeof value === "string") {
|
|
87
|
+
if (ABSOLUTE.test(value)) fail(`${where} must not be an absolute path`);
|
|
88
|
+
if (/-----BEGIN .*PRIVATE KEY-----/.test(value)) fail(`${where} must not contain a private key`);
|
|
89
|
+
if (/\bBearer\s+\S+/.test(value)) fail(`${where} must not contain a bearer token`);
|
|
90
|
+
if (/[?&](?:api[_-]?key|token|secret)=\S+/i.test(value)) fail(`${where} must not contain a credentialed URL`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (Array.isArray(value)) {
|
|
94
|
+
value.forEach((item, index) => assertNoSecretsOrPaths(item, `${where}[${index}]`));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (!value || typeof value !== "object") return;
|
|
98
|
+
for (const [key, child] of Object.entries(value)) assertNoSecretsOrPaths(child, `${where}.${key}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Check caller input before it is reduced to known fields. The CLI builds
|
|
103
|
+
* tasks from a whitelist, so a forbidden name dropped there would never reach
|
|
104
|
+
* the parser's check -- it would vanish silently instead of being refused.
|
|
105
|
+
*/
|
|
106
|
+
export function assertPortableInput(value: unknown, where: string): void {
|
|
107
|
+
assertNoForbiddenFields(value, where);
|
|
108
|
+
assertNoSecretsOrPaths(value, where);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function nonEmptyString(value: unknown, where: string): string {
|
|
112
|
+
if (typeof value !== "string" || !value.trim()) fail(`${where} must be a non-empty string`);
|
|
113
|
+
return value;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function stringArray(value: unknown, where: string, options: { min?: number } = {}): string[] {
|
|
117
|
+
if (!Array.isArray(value)) fail(`${where} must be an array`);
|
|
118
|
+
const items = value.map((item, index) => nonEmptyString(item, `${where}[${index}]`));
|
|
119
|
+
if (options.min !== undefined && items.length < options.min) {
|
|
120
|
+
fail(`${where} must contain at least ${options.min} item(s)`);
|
|
121
|
+
}
|
|
122
|
+
return items;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function parseTask(raw: unknown, where: string): PlanTask {
|
|
126
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) fail(`${where} must be an object`);
|
|
127
|
+
const value = raw as Record<string, unknown>;
|
|
128
|
+
const planKey = nonEmptyString(value.planKey, `${where}.planKey`);
|
|
129
|
+
if (!SAFE_KEY.test(planKey)) {
|
|
130
|
+
fail(`${where}.planKey must be lower-case alphanumeric with hyphens: "${planKey}"`);
|
|
131
|
+
}
|
|
132
|
+
const status = nonEmptyString(value.status ?? "pending", `${where}.status`);
|
|
133
|
+
if (!(TASK_STATUSES as readonly string[]).includes(status)) {
|
|
134
|
+
fail(`${where}.status must be one of ${TASK_STATUSES.join(", ")}`);
|
|
135
|
+
}
|
|
136
|
+
const task: PlanTask = {
|
|
137
|
+
planKey,
|
|
138
|
+
title: nonEmptyString(value.title, `${where}.title`),
|
|
139
|
+
objective: nonEmptyString(value.objective, `${where}.objective`),
|
|
140
|
+
acceptance: stringArray(value.acceptance, `${where}.acceptance`, { min: 1 }),
|
|
141
|
+
dependsOn: value.dependsOn === undefined ? [] : stringArray(value.dependsOn, `${where}.dependsOn`),
|
|
142
|
+
status: status as TaskStatus,
|
|
143
|
+
};
|
|
144
|
+
if (value.scope !== undefined) task.scope = value.scope as Record<string, unknown>;
|
|
145
|
+
if (value.parameters !== undefined) {
|
|
146
|
+
if (!Array.isArray(value.parameters)) fail(`${where}.parameters must be an array`);
|
|
147
|
+
task.parameters = value.parameters;
|
|
148
|
+
}
|
|
149
|
+
if (value.expectedArtifacts !== undefined) {
|
|
150
|
+
task.expectedArtifacts = stringArray(value.expectedArtifacts, `${where}.expectedArtifacts`);
|
|
151
|
+
}
|
|
152
|
+
if (value.allowedChanges !== undefined) {
|
|
153
|
+
task.allowedChanges = stringArray(value.allowedChanges, `${where}.allowedChanges`);
|
|
154
|
+
}
|
|
155
|
+
assertNoForbiddenFields(task, where);
|
|
156
|
+
assertNoSecretsOrPaths(task, where);
|
|
157
|
+
return task;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Dependency rules are enforced across the whole plan, not per task. */
|
|
161
|
+
function assertDependencyGraph(tasks: PlanTask[]): void {
|
|
162
|
+
const byKey = new Map(tasks.map((task) => [task.planKey, task]));
|
|
163
|
+
if (byKey.size !== tasks.length) {
|
|
164
|
+
const seen = new Set<string>();
|
|
165
|
+
for (const task of tasks) {
|
|
166
|
+
if (seen.has(task.planKey)) fail(`duplicate planKey "${task.planKey}"`);
|
|
167
|
+
seen.add(task.planKey);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
for (const task of tasks) {
|
|
171
|
+
if (task.dependsOn.includes(task.planKey)) fail(`task "${task.planKey}" depends on itself`);
|
|
172
|
+
for (const dependency of task.dependsOn) {
|
|
173
|
+
if (!byKey.has(dependency)) {
|
|
174
|
+
fail(`task "${task.planKey}" depends on unknown task "${dependency}"`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Iterative colouring; a cycle here means the plan must be re-cut, not patched.
|
|
179
|
+
const state = new Map<string, "visiting" | "done">();
|
|
180
|
+
const visit = (key: string, trail: string[]): void => {
|
|
181
|
+
const current = state.get(key);
|
|
182
|
+
if (current === "done") return;
|
|
183
|
+
if (current === "visiting") fail(`dependency cycle: ${[...trail, key].join(" -> ")}`);
|
|
184
|
+
state.set(key, "visiting");
|
|
185
|
+
for (const dependency of byKey.get(key)!.dependsOn) visit(dependency, [...trail, key]);
|
|
186
|
+
state.set(key, "done");
|
|
187
|
+
};
|
|
188
|
+
for (const task of tasks) visit(task.planKey, []);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const FRONTMATTER = /^---\n([\s\S]*?)\n---/;
|
|
192
|
+
const TASK_BLOCK = /```gateflow-task\n([\s\S]*?)\n```/g;
|
|
193
|
+
|
|
194
|
+
export function parsePlan(text: string): Plan {
|
|
195
|
+
const match = text.match(FRONTMATTER);
|
|
196
|
+
if (!match) fail("missing YAML frontmatter");
|
|
197
|
+
let meta: Record<string, unknown>;
|
|
198
|
+
try {
|
|
199
|
+
meta = YAML.parse(match[1]) as Record<string, unknown>;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
fail(`frontmatter is not valid YAML: ${(error as Error).message}`);
|
|
202
|
+
}
|
|
203
|
+
if (!meta || typeof meta !== "object") fail("frontmatter must be a mapping");
|
|
204
|
+
assertNoForbiddenFields(meta, "frontmatter");
|
|
205
|
+
assertNoSecretsOrPaths(meta, "frontmatter");
|
|
206
|
+
|
|
207
|
+
if (meta.schema !== PLAN_SCHEMA) fail(`schema must be "${PLAN_SCHEMA}"`);
|
|
208
|
+
const taskId = nonEmptyString(meta.taskId, "frontmatter.taskId");
|
|
209
|
+
if (!SAFE_KEY.test(taskId)) fail("frontmatter.taskId must be lower-case alphanumeric with hyphens");
|
|
210
|
+
const revision = meta.revision;
|
|
211
|
+
if (!Number.isInteger(revision) || (revision as number) < 1) fail("frontmatter.revision must be a positive integer");
|
|
212
|
+
const title = nonEmptyString(meta.title, "frontmatter.title");
|
|
213
|
+
|
|
214
|
+
// Each heading exactly once, in the fixed order.
|
|
215
|
+
const body = text.slice(match[0].length);
|
|
216
|
+
const headings = [...body.matchAll(/^## (.+)$/gm)].map((item) => item[1].trim());
|
|
217
|
+
if (headings.length !== SECTIONS.length || SECTIONS.some((section, index) => headings[index] !== section)) {
|
|
218
|
+
fail(`body must contain exactly these headings in order: ${SECTIONS.map((s) => `## ${s}`).join(", ")}`);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const tasks = {} as Record<PlanSection, PlanTask[]>;
|
|
222
|
+
const sections = {} as Record<PlanSection, "enabled" | "disabled">;
|
|
223
|
+
SECTIONS.forEach((section, index) => {
|
|
224
|
+
const start = body.indexOf(`## ${section}`) + `## ${section}`.length;
|
|
225
|
+
const end = index + 1 < SECTIONS.length ? body.indexOf(`## ${SECTIONS[index + 1]}`) : body.length;
|
|
226
|
+
const chunk = body.slice(start, end);
|
|
227
|
+
const declared = meta.sections;
|
|
228
|
+
const fromFrontmatter = declared && typeof declared === "object" && !Array.isArray(declared)
|
|
229
|
+
? (declared as Record<string, unknown>)[section]
|
|
230
|
+
: undefined;
|
|
231
|
+
const inline = chunk.match(/^\s*(enabled|disabled)\s*$/m)?.[1];
|
|
232
|
+
const state = (fromFrontmatter ?? inline) as string | undefined;
|
|
233
|
+
if (state !== "enabled" && state !== "disabled") {
|
|
234
|
+
fail(`section "${section}" must declare "enabled" or "disabled"`);
|
|
235
|
+
}
|
|
236
|
+
sections[section] = state;
|
|
237
|
+
const parsed = [...chunk.matchAll(TASK_BLOCK)].map((block, order) => {
|
|
238
|
+
let value: unknown;
|
|
239
|
+
try {
|
|
240
|
+
value = JSON.parse(block[1]);
|
|
241
|
+
} catch (error) {
|
|
242
|
+
fail(`section "${section}" task ${order + 1} is not valid JSON: ${(error as Error).message}`);
|
|
243
|
+
}
|
|
244
|
+
return parseTask(value, `section "${section}" task ${order + 1}`);
|
|
245
|
+
});
|
|
246
|
+
if (state === "disabled" && parsed.length > 0) {
|
|
247
|
+
fail(`section "${section}" is disabled but carries ${parsed.length} task(s)`);
|
|
248
|
+
}
|
|
249
|
+
tasks[section] = parsed;
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
const all = SECTIONS.flatMap((section) => tasks[section]);
|
|
253
|
+
if (all.length === 0) fail("plan contains no tasks in any enabled section");
|
|
254
|
+
assertDependencyGraph(all);
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
schema: PLAN_SCHEMA,
|
|
258
|
+
taskId,
|
|
259
|
+
revision: revision as number,
|
|
260
|
+
title,
|
|
261
|
+
sections,
|
|
262
|
+
updatedAt: nonEmptyString(meta.updatedAt ?? new Date(0).toISOString(), "frontmatter.updatedAt"),
|
|
263
|
+
tasks,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export function renderPlan(plan: Plan): string {
|
|
268
|
+
const frontmatter = YAML.stringify({
|
|
269
|
+
schema: PLAN_SCHEMA,
|
|
270
|
+
taskId: plan.taskId,
|
|
271
|
+
revision: plan.revision,
|
|
272
|
+
title: plan.title,
|
|
273
|
+
sections: plan.sections,
|
|
274
|
+
updatedAt: plan.updatedAt,
|
|
275
|
+
}).trimEnd();
|
|
276
|
+
const body = SECTIONS.map((section) => {
|
|
277
|
+
const blocks = plan.tasks[section]
|
|
278
|
+
.map((task) => `\n\`\`\`gateflow-task\n${JSON.stringify(task, null, 2)}\n\`\`\``)
|
|
279
|
+
.join("\n");
|
|
280
|
+
return `## ${section}\n\n${plan.sections[section]}${blocks}`;
|
|
281
|
+
}).join("\n\n");
|
|
282
|
+
return `---\n${frontmatter}\n---\n\n${body}\n`;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export function readPlanFile(root: string, relative: string = PLAN_FILE): Plan {
|
|
286
|
+
const file = path.join(root, relative);
|
|
287
|
+
if (!fs.existsSync(file)) fail(`not found at ${relative}`);
|
|
288
|
+
return parsePlan(fs.readFileSync(file, "utf8"));
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function writeAtomic(file: string, contents: string): void {
|
|
292
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
293
|
+
const temporary = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
294
|
+
try {
|
|
295
|
+
fs.writeFileSync(temporary, contents);
|
|
296
|
+
fs.renameSync(temporary, file);
|
|
297
|
+
} catch (error) {
|
|
298
|
+
if (fs.existsSync(temporary)) fs.unlinkSync(temporary);
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export function writePlanFile(root: string, plan: Plan, relative: string = PLAN_FILE): string {
|
|
304
|
+
const file = path.join(root, relative);
|
|
305
|
+
writeAtomic(file, renderPlan(plan));
|
|
306
|
+
return file;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export const emptyPlan = (taskId: string, title: string, sections: Record<PlanSection, "enabled" | "disabled">): Plan => ({
|
|
310
|
+
schema: PLAN_SCHEMA,
|
|
311
|
+
taskId,
|
|
312
|
+
revision: 1,
|
|
313
|
+
title,
|
|
314
|
+
sections,
|
|
315
|
+
updatedAt: new Date().toISOString(),
|
|
316
|
+
tasks: { development: [], audit: [], deployment: [] },
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
/** Deterministic summary for callers that only need to report what changed. */
|
|
320
|
+
export function planSummary(plan: Plan): Record<string, unknown> {
|
|
321
|
+
const all = SECTIONS.flatMap((section) => plan.tasks[section]);
|
|
322
|
+
return {
|
|
323
|
+
taskId: plan.taskId,
|
|
324
|
+
revision: plan.revision,
|
|
325
|
+
sections: plan.sections,
|
|
326
|
+
taskCount: all.length,
|
|
327
|
+
tasks: SECTIONS.flatMap((section) => plan.tasks[section].map((task) => ({
|
|
328
|
+
planKey: task.planKey,
|
|
329
|
+
section,
|
|
330
|
+
status: task.status,
|
|
331
|
+
dependsOn: task.dependsOn,
|
|
332
|
+
}))),
|
|
333
|
+
};
|
|
334
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import {
|
|
4
|
+
PLAN_FILE,
|
|
5
|
+
assertPortableInput,
|
|
6
|
+
emptyPlan,
|
|
7
|
+
parsePlan,
|
|
8
|
+
planSummary,
|
|
9
|
+
readPlanFile,
|
|
10
|
+
renderPlan,
|
|
11
|
+
type Plan,
|
|
12
|
+
type PlanSection,
|
|
13
|
+
type PlanTask,
|
|
14
|
+
} from "./plan";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* `plan-read` / `plan-write` / `plan-add`.
|
|
18
|
+
*
|
|
19
|
+
* The three exist so the plan never has to be hand-written. In a document that
|
|
20
|
+
* two runtimes both produce and consume, the fields most likely to be wrong are
|
|
21
|
+
* exactly the mechanical ones -- revision accounting, the section headings, the
|
|
22
|
+
* block syntax, the forbidden-field rules -- and those are the ones a command
|
|
23
|
+
* can own outright. The LLM's job is the objective and the acceptance criteria;
|
|
24
|
+
* the file's shape is not its job.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
const parseArgs = (argv: string[]): Map<string, string> => {
|
|
28
|
+
const values = new Map<string, string>();
|
|
29
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
30
|
+
const item = argv[index];
|
|
31
|
+
if (!item.startsWith("--")) continue;
|
|
32
|
+
const equalAt = item.indexOf("=");
|
|
33
|
+
const key = item.slice(2, equalAt > 2 ? equalAt : undefined);
|
|
34
|
+
const next = argv[index + 1];
|
|
35
|
+
// A trailing flag with no value is a switch, not a malformed option.
|
|
36
|
+
if (equalAt < 0 && (!next || next.startsWith("--"))) {
|
|
37
|
+
values.set(key, "true");
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const value = equalAt > 2 ? item.slice(equalAt + 1) : next;
|
|
41
|
+
if (!value || value.startsWith("--")) throw new Error(`--${key} requires a value`);
|
|
42
|
+
if (values.has(key)) throw new Error(`--${key} may be provided only once`);
|
|
43
|
+
values.set(key, value.trim());
|
|
44
|
+
if (equalAt < 0) index += 1;
|
|
45
|
+
}
|
|
46
|
+
return values;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const readJsonInput = (values: Map<string, string>, root: string): unknown => {
|
|
50
|
+
const inline = values.get("input");
|
|
51
|
+
const file = values.get("inputFile");
|
|
52
|
+
if (inline && file) throw new Error("--input and --inputFile are mutually exclusive");
|
|
53
|
+
if (file) {
|
|
54
|
+
const absolute = path.isAbsolute(file) ? file : path.join(root, file);
|
|
55
|
+
if (!fs.existsSync(absolute)) throw new Error(`--inputFile not found: ${file}`);
|
|
56
|
+
return JSON.parse(fs.readFileSync(absolute, "utf8"));
|
|
57
|
+
}
|
|
58
|
+
if (inline) return JSON.parse(inline);
|
|
59
|
+
throw new Error("--input or --inputFile is required");
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const asRecord = (value: unknown, label: string): Record<string, unknown> => {
|
|
63
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
64
|
+
throw new Error(`${label} must be a JSON object`);
|
|
65
|
+
}
|
|
66
|
+
return value as Record<string, unknown>;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const parseSections = (value: unknown): Record<PlanSection, "enabled" | "disabled"> => {
|
|
70
|
+
const record = value === undefined ? {} : asRecord(value, "sections");
|
|
71
|
+
const read = (key: PlanSection, fallback: "enabled" | "disabled") => {
|
|
72
|
+
const raw = record[key] ?? fallback;
|
|
73
|
+
if (raw !== "enabled" && raw !== "disabled") {
|
|
74
|
+
throw new Error(`sections.${key} must be "enabled" or "disabled"`);
|
|
75
|
+
}
|
|
76
|
+
return raw;
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
development: read("development", "enabled"),
|
|
80
|
+
audit: read("audit", "enabled"),
|
|
81
|
+
deployment: read("deployment", "enabled"),
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/** A task from the caller, without the fields the writer owns. */
|
|
86
|
+
const toTask = (value: unknown, where: string): PlanTask => {
|
|
87
|
+
const record = asRecord(value, where);
|
|
88
|
+
return {
|
|
89
|
+
planKey: String(record.planKey ?? ""),
|
|
90
|
+
title: String(record.title ?? ""),
|
|
91
|
+
objective: String(record.objective ?? ""),
|
|
92
|
+
acceptance: Array.isArray(record.acceptance) ? record.acceptance.map(String) : [],
|
|
93
|
+
dependsOn: Array.isArray(record.dependsOn) ? record.dependsOn.map(String) : [],
|
|
94
|
+
status: (record.status ?? "pending") as PlanTask["status"],
|
|
95
|
+
...(record.scope !== undefined ? { scope: asRecord(record.scope, `${where}.scope`) } : {}),
|
|
96
|
+
...(record.parameters !== undefined
|
|
97
|
+
? { parameters: (() => {
|
|
98
|
+
if (!Array.isArray(record.parameters)) throw new Error(`${where}.parameters must be an array`);
|
|
99
|
+
return record.parameters;
|
|
100
|
+
})() }
|
|
101
|
+
: {}),
|
|
102
|
+
...(record.expectedArtifacts !== undefined
|
|
103
|
+
? { expectedArtifacts: (record.expectedArtifacts as unknown[]).map(String) }
|
|
104
|
+
: {}),
|
|
105
|
+
...(record.allowedChanges !== undefined
|
|
106
|
+
? { allowedChanges: (record.allowedChanges as unknown[]).map(String) }
|
|
107
|
+
: {}),
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const sectionOf = (value: unknown): PlanSection => {
|
|
112
|
+
const section = String(value ?? "development");
|
|
113
|
+
if (section !== "development" && section !== "audit" && section !== "deployment") {
|
|
114
|
+
throw new Error(`--section must be development, audit or deployment (got "${section}")`);
|
|
115
|
+
}
|
|
116
|
+
return section;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const runPlanReadCli = (argv: string[], root: string = process.cwd()): Record<string, unknown> => {
|
|
120
|
+
const values = parseArgs(argv);
|
|
121
|
+
const plan = readPlanFile(root, values.get("path") || PLAN_FILE);
|
|
122
|
+
return values.has("full")
|
|
123
|
+
? { ...planSummary(plan), plan: renderPlan(plan) }
|
|
124
|
+
: planSummary(plan);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Replace the plan. `revision` is not taken from the caller: the writer owns it,
|
|
129
|
+
* because it is the one number every consumer depends on and the one easiest to
|
|
130
|
+
* get wrong by hand. It advances only when the execution contract changes.
|
|
131
|
+
*/
|
|
132
|
+
export const runPlanWriteCli = (argv: string[], root: string = process.cwd()): Record<string, unknown> => {
|
|
133
|
+
const values = parseArgs(argv);
|
|
134
|
+
const input = asRecord(readJsonInput(values, root), "--input");
|
|
135
|
+
assertPortableInput(input, "--input");
|
|
136
|
+
const relative = values.get("path") || PLAN_FILE;
|
|
137
|
+
const sections = parseSections(input.sections);
|
|
138
|
+
const tasksInput = input.tasks;
|
|
139
|
+
const tasks: Record<PlanSection, PlanTask[]> = { development: [], audit: [], deployment: [] };
|
|
140
|
+
if (tasksInput !== undefined) {
|
|
141
|
+
const record = asRecord(tasksInput, "tasks");
|
|
142
|
+
for (const section of ["development", "audit", "deployment"] as const) {
|
|
143
|
+
const list = record[section];
|
|
144
|
+
if (list === undefined) continue;
|
|
145
|
+
if (!Array.isArray(list)) throw new Error(`tasks.${section} must be an array`);
|
|
146
|
+
tasks[section] = list.map((item, index) => toTask(item, `tasks.${section}[${index}]`));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const existing = fs.existsSync(path.join(root, relative)) ? readPlanFile(root, relative) : undefined;
|
|
151
|
+
|
|
152
|
+
const previousContracts = existing
|
|
153
|
+
? new Map((["development", "audit", "deployment"] as const)
|
|
154
|
+
.flatMap((section) => existing.tasks[section])
|
|
155
|
+
.map((task) => [task.planKey, contractOf(task)]))
|
|
156
|
+
: new Map<string, string>();
|
|
157
|
+
const nextAll = (["development", "audit", "deployment"] as const).flatMap((section) => tasks[section]);
|
|
158
|
+
let revision = existing ? existing.revision : 1;
|
|
159
|
+
if (existing) {
|
|
160
|
+
const changed = nextAll.length !== previousContracts.size
|
|
161
|
+
|| nextAll.some((task) => previousContracts.get(task.planKey) !== contractOf(task))
|
|
162
|
+
|| JSON.stringify(existing.sections) !== JSON.stringify(sections);
|
|
163
|
+
if (changed) revision = existing.revision + 1;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const plan: Plan = {
|
|
167
|
+
schema: "gateflow-plan/v1",
|
|
168
|
+
taskId: String(input.taskId ?? existing?.taskId ?? ""),
|
|
169
|
+
revision,
|
|
170
|
+
title: String(input.title ?? existing?.title ?? ""),
|
|
171
|
+
sections,
|
|
172
|
+
updatedAt: new Date().toISOString(),
|
|
173
|
+
tasks,
|
|
174
|
+
};
|
|
175
|
+
// The writer is the one place the document is produced, so the whole plan is
|
|
176
|
+
// validated on the way out -- same checks an import would run.
|
|
177
|
+
const text = renderPlan(plan);
|
|
178
|
+
const validated = parsePlan(text);
|
|
179
|
+
fs.mkdirSync(path.dirname(path.join(root, relative)), { recursive: true });
|
|
180
|
+
fs.writeFileSync(path.join(root, relative), text);
|
|
181
|
+
|
|
182
|
+
const added = nextAll.filter((task) => !previousContracts.has(task.planKey)).map((task) => task.planKey);
|
|
183
|
+
const removed = [...previousContracts.keys()].filter((key) => !nextAll.some((task) => task.planKey === key));
|
|
184
|
+
return {
|
|
185
|
+
...planSummary(validated),
|
|
186
|
+
path: relative,
|
|
187
|
+
revisionBumped: !existing || revision !== existing.revision,
|
|
188
|
+
added,
|
|
189
|
+
// Reported, never silently applied: dropping a task from the file makes it
|
|
190
|
+
// look like it never existed to the other entry point.
|
|
191
|
+
removed,
|
|
192
|
+
...(removed.length > 0
|
|
193
|
+
? { warning: `tasks were dropped from the plan: ${removed.join(", ")}. Cancelling (status=cancelled) is usually what you want instead.` }
|
|
194
|
+
: {}),
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/** Append one task, advancing the revision. The common case, so it gets a verb. */
|
|
199
|
+
export const runPlanAddCli = (argv: string[], root: string = process.cwd()): Record<string, unknown> => {
|
|
200
|
+
const values = parseArgs(argv);
|
|
201
|
+
const input = asRecord(readJsonInput(values, root), "--input");
|
|
202
|
+
assertPortableInput(input, "--input");
|
|
203
|
+
const relative = values.get("path") || PLAN_FILE;
|
|
204
|
+
const plan = readPlanFile(root, relative);
|
|
205
|
+
const section = sectionOf(input.section);
|
|
206
|
+
const task = toTask(input.task ?? input, "task");
|
|
207
|
+
if (plan.sections[section] === "disabled") {
|
|
208
|
+
throw new Error(`section "${section}" is disabled; enable it before adding tasks`);
|
|
209
|
+
}
|
|
210
|
+
const existingKeys = (["development", "audit", "deployment"] as const)
|
|
211
|
+
.flatMap((item) => plan.tasks[item])
|
|
212
|
+
.map((item) => item.planKey);
|
|
213
|
+
if (existingKeys.includes(task.planKey)) {
|
|
214
|
+
throw new Error(`planKey "${task.planKey}" already exists; plan keys are stable identities, not labels`);
|
|
215
|
+
}
|
|
216
|
+
const next: Plan = {
|
|
217
|
+
...plan,
|
|
218
|
+
revision: plan.revision + 1,
|
|
219
|
+
updatedAt: new Date().toISOString(),
|
|
220
|
+
tasks: { ...plan.tasks, [section]: [...plan.tasks[section], task] },
|
|
221
|
+
};
|
|
222
|
+
const text = renderPlan(next);
|
|
223
|
+
parsePlan(text);
|
|
224
|
+
fs.writeFileSync(path.join(root, relative), text);
|
|
225
|
+
return { ...planSummary(next), path: relative, section, added: task.planKey };
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export const contractOf = (task: PlanTask): string => JSON.stringify({
|
|
229
|
+
objective: task.objective,
|
|
230
|
+
acceptance: task.acceptance,
|
|
231
|
+
dependsOn: task.dependsOn,
|
|
232
|
+
scope: task.scope ?? null,
|
|
233
|
+
parameters: task.parameters ?? null,
|
|
234
|
+
expectedArtifacts: task.expectedArtifacts ?? null,
|
|
235
|
+
allowedChanges: task.allowedChanges ?? null,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Status moves the protocol allows. Progress is not a contract change, so it
|
|
240
|
+
* never advances the revision -- otherwise every completed task would look
|
|
241
|
+
* like a re-plan to the other entry point.
|
|
242
|
+
*/
|
|
243
|
+
const STATUS_MOVES: Record<PlanTask["status"], readonly PlanTask["status"][]> = {
|
|
244
|
+
pending: ["ready", "running", "cancelled"],
|
|
245
|
+
ready: ["running", "cancelled"],
|
|
246
|
+
running: ["completed", "failed"],
|
|
247
|
+
failed: ["ready", "running", "cancelled"],
|
|
248
|
+
completed: ["pending"],
|
|
249
|
+
cancelled: [],
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
/** Move one task's status: `--task <planKey> --to <status>`. */
|
|
253
|
+
export const runPlanStatusCli = (argv: string[], root: string = process.cwd()): Record<string, unknown> => {
|
|
254
|
+
const values = parseArgs(argv);
|
|
255
|
+
const relative = values.get("path") || PLAN_FILE;
|
|
256
|
+
const planKey = values.get("task");
|
|
257
|
+
const to = values.get("to") as PlanTask["status"] | undefined;
|
|
258
|
+
if (!planKey) throw new Error("--task <planKey> is required");
|
|
259
|
+
if (!to || !(to in STATUS_MOVES)) throw new Error(`--to must be one of ${Object.keys(STATUS_MOVES).join(", ")}`);
|
|
260
|
+
const plan = readPlanFile(root, relative);
|
|
261
|
+
const all = (["development", "audit", "deployment"] as const).flatMap((section) => plan.tasks[section]);
|
|
262
|
+
const task = all.find((item) => item.planKey === planKey);
|
|
263
|
+
if (!task) throw new Error(`task "${planKey}" not found`);
|
|
264
|
+
const from = task.status;
|
|
265
|
+
if (from === to) return { ...planSummary(plan), path: relative, planKey, from, to, changed: false };
|
|
266
|
+
if (!STATUS_MOVES[from].includes(to)) throw new Error(`task "${planKey}" cannot move from ${from} to ${to}`);
|
|
267
|
+
if (to === "running") {
|
|
268
|
+
const blocked = task.dependsOn.filter((key) => all.find((item) => item.planKey === key)?.status !== "completed");
|
|
269
|
+
if (blocked.length > 0) throw new Error(`task "${planKey}" depends on unfinished task(s): ${blocked.join(", ")}`);
|
|
270
|
+
}
|
|
271
|
+
task.status = to;
|
|
272
|
+
const next: Plan = { ...plan, updatedAt: new Date().toISOString() };
|
|
273
|
+
const text = renderPlan(next);
|
|
274
|
+
parsePlan(text);
|
|
275
|
+
fs.writeFileSync(path.join(root, relative), text);
|
|
276
|
+
return { ...planSummary(next), path: relative, planKey, from, to, changed: true };
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export { emptyPlan };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import type { WorkflowContext } from './context';
|
|
3
|
+
import type { DeploymentChange } from './deploymentRecords';
|
|
4
|
+
import type { PreparedGateToolWorkflow } from './gateTool';
|
|
5
|
+
export function recordPreparedDeployment(context: WorkflowContext, change: DeploymentChange, prepared: PreparedGateToolWorkflow, derivedKeys: string[]): void {
|
|
6
|
+
if (!context.preparations) return;
|
|
7
|
+
const ref = (file: string) => path.isAbsolute(file) ? path.relative(context.root, file).split(path.sep).join('/') : file;
|
|
8
|
+
const planPath = ref(prepared.planPath);
|
|
9
|
+
// Step structs use optional undefined properties; immutable journal input is explicit JSON data.
|
|
10
|
+
const clean = Object.fromEntries(Object.entries(change).filter(([, value]) => value !== undefined));
|
|
11
|
+
clean.gateTool = { outputPath: planPath, data: prepared.plan };
|
|
12
|
+
context.preparations.prepare({ stepId: change.stepId, change: clean as unknown as DeploymentChange,
|
|
13
|
+
prepared: { ...prepared, requestPath: ref(prepared.requestPath), planPath }, derivedKeys });
|
|
14
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { keccak256, toUtf8Bytes } from "ethers";
|
|
2
|
-
import {
|
|
2
|
+
import type { Provider } from "ethers";
|
|
3
3
|
import {
|
|
4
4
|
getERC1967Admin,
|
|
5
5
|
getERC1967Implementation,
|
|
@@ -10,6 +10,7 @@ export interface ProxyOptions {
|
|
|
10
10
|
initializer?: string | false;
|
|
11
11
|
unsafeAllow?: string[];
|
|
12
12
|
constructorArgs?: unknown[];
|
|
13
|
+
adminOwner?: string;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export interface FirstUpgradeOptions {
|
|
@@ -31,9 +32,10 @@ export const deriveImplementationSalt = (
|
|
|
31
32
|
);
|
|
32
33
|
|
|
33
34
|
export const getImplementationAddress = async (
|
|
35
|
+
provider: Pick<Provider, "getStorage">,
|
|
34
36
|
proxyAddress: string,
|
|
35
37
|
): Promise<string> => {
|
|
36
|
-
const implementation = await getERC1967Implementation(
|
|
38
|
+
const implementation = await getERC1967Implementation(provider, proxyAddress);
|
|
37
39
|
if (!implementation) {
|
|
38
40
|
throw new Error(`Proxy ${proxyAddress} has no ERC-1967 implementation`);
|
|
39
41
|
}
|
|
@@ -41,5 +43,6 @@ export const getImplementationAddress = async (
|
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
export const getProxyAdminAddress = async (
|
|
46
|
+
provider: Pick<Provider, "getStorage">,
|
|
44
47
|
proxyAddress: string,
|
|
45
|
-
): Promise<string | undefined> => getERC1967Admin(
|
|
48
|
+
): Promise<string | undefined> => getERC1967Admin(provider, proxyAddress);
|