@mannyc1/ts-release 0.0.7 → 0.3.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/ARCHITECTURE.md +184 -92
- package/CHANGELOG.md +197 -0
- package/LICENSE +21 -0
- package/README.md +404 -327
- package/SPEC.md +257 -310
- package/apps/release-ts/README.md +39 -0
- package/apps/release-ts/src/cli/command.ts +164 -0
- package/apps/release-ts/src/cli/commands.ts +351 -0
- package/apps/release-ts/src/cli/main.ts +43 -0
- package/apps/release-ts/src/cli/node-main.ts +49 -0
- package/apps/ts-release-agents/LICENSE +21 -0
- package/apps/ts-release-agents/README.md +21 -0
- package/apps/ts-release-agents/evals/cases.json +11 -0
- package/apps/ts-release-agents/manifests/claude.json +5 -0
- package/apps/ts-release-agents/manifests/codex.json +5 -0
- package/apps/ts-release-agents/package.json +11 -0
- package/apps/ts-release-agents/skills/release/SKILL.md +48 -0
- package/apps/ts-release-agents/skills/release/references/configuration.md +18 -0
- package/apps/ts-release-agents/skills/release/references/recovery.md +10 -0
- package/apps/ts-release-agents/skills/release/references/staged-workflow.md +12 -0
- package/apps/ts-release-agents/skills/release/references/target-selection.md +13 -0
- package/apps/ts-release-agents/skills/release/references/verification.md +14 -0
- package/apps/ts-release-agents/src/build.ts +105 -0
- package/apps/ts-release-agents/src/check.ts +122 -0
- package/apps/ts-release-agents/src/install.ts +121 -0
- package/apps/ts-release-agents/test/contract.test.ts +56 -0
- package/apps/ts-release-agents/tsconfig.json +5 -0
- package/dist/api/api.d.ts +15 -0
- package/dist/api/api.d.ts.map +1 -0
- package/dist/api/api.js +244 -0
- package/dist/api/api.js.map +1 -0
- package/dist/api/errors.d.ts +39 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +32 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/input.d.ts +10 -0
- package/dist/api/input.d.ts.map +1 -0
- package/dist/api/input.js +73 -0
- package/dist/api/input.js.map +1 -0
- package/dist/api/runtime.d.ts +18 -0
- package/dist/api/runtime.d.ts.map +1 -0
- package/dist/api/runtime.js +7 -0
- package/dist/api/runtime.js.map +1 -0
- package/dist/api/types.d.ts +76 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +17 -0
- package/dist/api/types.js.map +1 -0
- package/dist/bin/ts-release.js +39346 -0
- package/dist/capabilities/bun-targets.d.ts +3 -0
- package/dist/capabilities/bun-targets.d.ts.map +1 -0
- package/dist/capabilities/bun-targets.js +3 -0
- package/dist/capabilities/bun-targets.js.map +1 -0
- package/dist/capabilities/field-ownership.d.ts +17 -0
- package/dist/capabilities/field-ownership.d.ts.map +1 -0
- package/dist/capabilities/field-ownership.js +40 -0
- package/dist/capabilities/field-ownership.js.map +1 -0
- package/dist/capabilities/module.d.ts +91 -0
- package/dist/capabilities/module.d.ts.map +1 -0
- package/dist/capabilities/module.js +2 -0
- package/dist/capabilities/module.js.map +1 -0
- package/dist/capabilities/registry.d.ts +829 -0
- package/dist/capabilities/registry.d.ts.map +1 -0
- package/dist/capabilities/registry.js +291 -0
- package/dist/capabilities/registry.js.map +1 -0
- package/dist/config/config.d.ts +6 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +42 -0
- package/dist/config/config.js.map +1 -0
- package/dist/correction/coordinator.d.ts +248 -0
- package/dist/correction/coordinator.d.ts.map +1 -0
- package/dist/correction/coordinator.js +274 -0
- package/dist/correction/coordinator.js.map +1 -0
- package/dist/correction/index.d.ts +3 -0
- package/dist/correction/index.d.ts.map +1 -0
- package/dist/correction/index.js +3 -0
- package/dist/correction/index.js.map +1 -0
- package/dist/correction/intent.d.ts +111 -0
- package/dist/correction/intent.d.ts.map +1 -0
- package/dist/correction/intent.js +146 -0
- package/dist/correction/intent.js.map +1 -0
- package/dist/drivers/archive.d.ts +9 -0
- package/dist/drivers/archive.d.ts.map +1 -0
- package/dist/drivers/archive.js +105 -0
- package/dist/drivers/archive.js.map +1 -0
- package/dist/drivers/contain.d.ts +6 -0
- package/dist/drivers/contain.d.ts.map +1 -0
- package/dist/drivers/contain.js +17 -0
- package/dist/drivers/contain.js.map +1 -0
- package/dist/drivers/environment.d.ts +4 -0
- package/dist/drivers/environment.d.ts.map +1 -0
- package/dist/drivers/environment.js +18 -0
- package/dist/drivers/environment.js.map +1 -0
- package/dist/drivers/errors.d.ts +9 -0
- package/dist/drivers/errors.d.ts.map +1 -0
- package/dist/drivers/errors.js +6 -0
- package/dist/drivers/errors.js.map +1 -0
- package/dist/drivers/glob.d.ts +2 -0
- package/dist/drivers/glob.d.ts.map +1 -0
- package/dist/drivers/glob.js +162 -0
- package/dist/drivers/glob.js.map +1 -0
- package/dist/drivers/process.d.ts +48 -0
- package/dist/drivers/process.d.ts.map +1 -0
- package/dist/drivers/process.js +257 -0
- package/dist/drivers/process.js.map +1 -0
- package/dist/drivers/python-wheel.d.ts +21 -0
- package/dist/drivers/python-wheel.d.ts.map +1 -0
- package/dist/drivers/python-wheel.js +109 -0
- package/dist/drivers/python-wheel.js.map +1 -0
- package/dist/drivers/redact.d.ts +4 -0
- package/dist/drivers/redact.d.ts.map +1 -0
- package/dist/drivers/redact.js +24 -0
- package/dist/drivers/redact.js.map +1 -0
- package/dist/drivers/seccomp-helper-source.d.ts +7 -0
- package/dist/drivers/seccomp-helper-source.d.ts.map +1 -0
- package/dist/drivers/seccomp-helper-source.js +121 -0
- package/dist/drivers/seccomp-helper-source.js.map +1 -0
- package/dist/drivers/utils.d.ts +4 -0
- package/dist/drivers/utils.d.ts.map +1 -0
- package/dist/drivers/utils.js +5 -0
- package/dist/drivers/utils.js.map +1 -0
- package/dist/drivers/workspace.d.ts +9 -0
- package/dist/drivers/workspace.d.ts.map +1 -0
- package/dist/drivers/workspace.js +53 -0
- package/dist/drivers/workspace.js.map +1 -0
- package/dist/extensions/provider-adapter.d.ts +48 -0
- package/dist/extensions/provider-adapter.d.ts.map +1 -0
- package/dist/extensions/provider-adapter.js +64 -0
- package/dist/extensions/provider-adapter.js.map +1 -0
- package/dist/host.d.ts +33 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +20 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +19 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/model/artifact-collection.d.ts +84 -0
- package/dist/model/artifact-collection.d.ts.map +1 -0
- package/dist/model/artifact-collection.js +185 -0
- package/dist/model/artifact-collection.js.map +1 -0
- package/dist/model/authority.d.ts +89 -0
- package/dist/model/authority.d.ts.map +1 -0
- package/dist/model/authority.js +80 -0
- package/dist/model/authority.js.map +1 -0
- package/dist/model/bun-targets.d.ts +34 -0
- package/dist/model/bun-targets.d.ts.map +1 -0
- package/dist/model/bun-targets.js +17 -0
- package/dist/model/bun-targets.js.map +1 -0
- package/dist/model/canonical.d.ts +8 -0
- package/dist/model/canonical.d.ts.map +1 -0
- package/dist/model/canonical.js +205 -0
- package/dist/model/canonical.js.map +1 -0
- package/dist/model/catalog.d.ts +76 -0
- package/dist/model/catalog.d.ts.map +1 -0
- package/dist/model/catalog.js +174 -0
- package/dist/model/catalog.js.map +1 -0
- package/dist/model/digest.d.ts +53 -0
- package/dist/model/digest.d.ts.map +1 -0
- package/dist/model/digest.js +127 -0
- package/dist/model/digest.js.map +1 -0
- package/dist/model/errors.d.ts +14 -0
- package/dist/model/errors.d.ts.map +1 -0
- package/dist/model/errors.js +8 -0
- package/dist/model/errors.js.map +1 -0
- package/dist/model/primitives.d.ts +19 -0
- package/dist/model/primitives.d.ts.map +1 -0
- package/dist/model/primitives.js +18 -0
- package/dist/model/primitives.js.map +1 -0
- package/dist/model/pypi.d.ts +12 -0
- package/dist/model/pypi.d.ts.map +1 -0
- package/dist/model/pypi.js +20 -0
- package/dist/model/pypi.js.map +1 -0
- package/dist/model/python-distribution.d.ts +33 -0
- package/dist/model/python-distribution.d.ts.map +1 -0
- package/dist/model/python-distribution.js +367 -0
- package/dist/model/python-distribution.js.map +1 -0
- package/dist/model/secret-patterns.d.ts +2 -0
- package/dist/model/secret-patterns.d.ts.map +1 -0
- package/dist/model/secret-patterns.js +12 -0
- package/dist/model/secret-patterns.js.map +1 -0
- package/dist/operation-journal/authority.d.ts +3 -0
- package/dist/operation-journal/authority.d.ts.map +1 -0
- package/dist/operation-journal/authority.js +147 -0
- package/dist/operation-journal/authority.js.map +1 -0
- package/dist/operation-journal/aws/deadline.d.ts +12 -0
- package/dist/operation-journal/aws/deadline.d.ts.map +1 -0
- package/dist/operation-journal/aws/deadline.js +38 -0
- package/dist/operation-journal/aws/deadline.js.map +1 -0
- package/dist/operation-journal/aws/oidc.d.ts +27 -0
- package/dist/operation-journal/aws/oidc.d.ts.map +1 -0
- package/dist/operation-journal/aws/oidc.js +361 -0
- package/dist/operation-journal/aws/oidc.js.map +1 -0
- package/dist/operation-journal/aws/policy.d.ts +42 -0
- package/dist/operation-journal/aws/policy.d.ts.map +1 -0
- package/dist/operation-journal/aws/policy.js +404 -0
- package/dist/operation-journal/aws/policy.js.map +1 -0
- package/dist/operation-journal/aws/s3-boundary.d.ts +17 -0
- package/dist/operation-journal/aws/s3-boundary.d.ts.map +1 -0
- package/dist/operation-journal/aws/s3-boundary.js +417 -0
- package/dist/operation-journal/aws/s3-boundary.js.map +1 -0
- package/dist/operation-journal/aws.d.ts +11 -0
- package/dist/operation-journal/aws.d.ts.map +1 -0
- package/dist/operation-journal/aws.js +50 -0
- package/dist/operation-journal/aws.js.map +1 -0
- package/dist/operation-journal/canonical.d.ts +52 -0
- package/dist/operation-journal/canonical.d.ts.map +1 -0
- package/dist/operation-journal/canonical.js +282 -0
- package/dist/operation-journal/canonical.js.map +1 -0
- package/dist/operation-journal/model.d.ts +251 -0
- package/dist/operation-journal/model.d.ts.map +1 -0
- package/dist/operation-journal/model.js +56 -0
- package/dist/operation-journal/model.js.map +1 -0
- package/dist/operation-journal/reducer.d.ts +28 -0
- package/dist/operation-journal/reducer.d.ts.map +1 -0
- package/dist/operation-journal/reducer.js +73 -0
- package/dist/operation-journal/reducer.js.map +1 -0
- package/dist/operation-journal/s3.d.ts +7 -0
- package/dist/operation-journal/s3.d.ts.map +1 -0
- package/dist/operation-journal/s3.js +667 -0
- package/dist/operation-journal/s3.js.map +1 -0
- package/dist/operation-journal.d.ts +14 -0
- package/dist/operation-journal.d.ts.map +1 -0
- package/dist/operation-journal.js +12 -0
- package/dist/operation-journal.js.map +1 -0
- package/dist/platform/bun.d.ts +7 -0
- package/dist/platform/bun.d.ts.map +1 -0
- package/dist/platform/bun.js +15 -0
- package/dist/platform/bun.js.map +1 -0
- package/dist/platform/credentials.d.ts +32 -0
- package/dist/platform/credentials.d.ts.map +1 -0
- package/dist/platform/credentials.js +834 -0
- package/dist/platform/credentials.js.map +1 -0
- package/dist/platform/host-support.d.ts +2 -0
- package/dist/platform/host-support.d.ts.map +1 -0
- package/dist/platform/host-support.js +4 -0
- package/dist/platform/host-support.js.map +1 -0
- package/dist/platform/node.d.ts +7 -0
- package/dist/platform/node.d.ts.map +1 -0
- package/dist/platform/node.js +15 -0
- package/dist/platform/node.js.map +1 -0
- package/dist/platform/release-runtime.d.ts +11 -0
- package/dist/platform/release-runtime.d.ts.map +1 -0
- package/dist/platform/release-runtime.js +34 -0
- package/dist/platform/release-runtime.js.map +1 -0
- package/dist/platform/services.d.ts +15 -0
- package/dist/platform/services.d.ts.map +1 -0
- package/dist/platform/services.js +30 -0
- package/dist/platform/services.js.map +1 -0
- package/dist/platform/source-observer.d.ts +5 -0
- package/dist/platform/source-observer.d.ts.map +1 -0
- package/dist/platform/source-observer.js +159 -0
- package/dist/platform/source-observer.js.map +1 -0
- package/dist/provider-sdk.d.ts +14 -0
- package/dist/provider-sdk.d.ts.map +1 -0
- package/dist/provider-sdk.js +10 -0
- package/dist/provider-sdk.js.map +1 -0
- package/dist/publication/adapter.d.ts +212 -0
- package/dist/publication/adapter.d.ts.map +1 -0
- package/dist/publication/adapter.js +83 -0
- package/dist/publication/adapter.js.map +1 -0
- package/dist/publication/authority.d.ts +137 -0
- package/dist/publication/authority.d.ts.map +1 -0
- package/dist/publication/authority.js +233 -0
- package/dist/publication/authority.js.map +1 -0
- package/dist/publication/catalog-git.d.ts +37 -0
- package/dist/publication/catalog-git.d.ts.map +1 -0
- package/dist/publication/catalog-git.js +451 -0
- package/dist/publication/catalog-git.js.map +1 -0
- package/dist/publication/claim.d.ts +39 -0
- package/dist/publication/claim.d.ts.map +1 -0
- package/dist/publication/claim.js +31 -0
- package/dist/publication/claim.js.map +1 -0
- package/dist/publication/coordinator.d.ts +246 -0
- package/dist/publication/coordinator.d.ts.map +1 -0
- package/dist/publication/coordinator.js +370 -0
- package/dist/publication/coordinator.js.map +1 -0
- package/dist/publication/github.d.ts +36 -0
- package/dist/publication/github.d.ts.map +1 -0
- package/dist/publication/github.js +695 -0
- package/dist/publication/github.js.map +1 -0
- package/dist/publication/http.d.ts +69 -0
- package/dist/publication/http.d.ts.map +1 -0
- package/dist/publication/http.js +29 -0
- package/dist/publication/http.js.map +1 -0
- package/dist/publication/index.d.ts +5 -0
- package/dist/publication/index.d.ts.map +1 -0
- package/dist/publication/index.js +5 -0
- package/dist/publication/index.js.map +1 -0
- package/dist/publication/npm.d.ts +40 -0
- package/dist/publication/npm.d.ts.map +1 -0
- package/dist/publication/npm.js +359 -0
- package/dist/publication/npm.js.map +1 -0
- package/dist/publication/profiles.d.ts +136 -0
- package/dist/publication/profiles.d.ts.map +1 -0
- package/dist/publication/profiles.js +90 -0
- package/dist/publication/profiles.js.map +1 -0
- package/dist/publication/publisher.d.ts +82 -0
- package/dist/publication/publisher.d.ts.map +1 -0
- package/dist/publication/publisher.js +53 -0
- package/dist/publication/publisher.js.map +1 -0
- package/dist/publication/pypi.d.ts +45 -0
- package/dist/publication/pypi.d.ts.map +1 -0
- package/dist/publication/pypi.js +369 -0
- package/dist/publication/pypi.js.map +1 -0
- package/dist/publication/recovery.d.ts +663 -0
- package/dist/publication/recovery.d.ts.map +1 -0
- package/dist/publication/recovery.js +252 -0
- package/dist/publication/recovery.js.map +1 -0
- package/dist/publication/report.d.ts +1061 -0
- package/dist/publication/report.d.ts.map +1 -0
- package/dist/publication/report.js +441 -0
- package/dist/publication/report.js.map +1 -0
- package/dist/recipes/config.d.ts +296 -0
- package/dist/recipes/config.d.ts.map +1 -0
- package/dist/recipes/config.js +325 -0
- package/dist/recipes/config.js.map +1 -0
- package/dist/release/capabilities.d.ts +12 -0
- package/dist/release/capabilities.d.ts.map +1 -0
- package/dist/release/capabilities.js +395 -0
- package/dist/release/capabilities.js.map +1 -0
- package/dist/release/compiler.d.ts +5 -0
- package/dist/release/compiler.d.ts.map +1 -0
- package/dist/release/compiler.js +19 -0
- package/dist/release/compiler.js.map +1 -0
- package/dist/release/config.d.ts +5 -0
- package/dist/release/config.d.ts.map +1 -0
- package/dist/release/config.js +10 -0
- package/dist/release/config.js.map +1 -0
- package/dist/release/context.d.ts +96 -0
- package/dist/release/context.d.ts.map +1 -0
- package/dist/release/context.js +168 -0
- package/dist/release/context.js.map +1 -0
- package/dist/release/graph.d.ts +271 -0
- package/dist/release/graph.d.ts.map +1 -0
- package/dist/release/graph.js +766 -0
- package/dist/release/graph.js.map +1 -0
- package/dist/release/inspect.d.ts +88 -0
- package/dist/release/inspect.d.ts.map +1 -0
- package/dist/release/inspect.js +75 -0
- package/dist/release/inspect.js.map +1 -0
- package/dist/release/prepare.d.ts +24 -0
- package/dist/release/prepare.d.ts.map +1 -0
- package/dist/release/prepare.js +1115 -0
- package/dist/release/prepare.js.map +1 -0
- package/dist/release/prepared-ref.d.ts +60 -0
- package/dist/release/prepared-ref.d.ts.map +1 -0
- package/dist/release/prepared-ref.js +131 -0
- package/dist/release/prepared-ref.js.map +1 -0
- package/dist/release/prepared-store.d.ts +90 -0
- package/dist/release/prepared-store.d.ts.map +1 -0
- package/dist/release/prepared-store.js +339 -0
- package/dist/release/prepared-store.js.map +1 -0
- package/dist/release/prepared.d.ts +172 -0
- package/dist/release/prepared.d.ts.map +1 -0
- package/dist/release/prepared.js +268 -0
- package/dist/release/prepared.js.map +1 -0
- package/dist/release/staging.d.ts +31 -0
- package/dist/release/staging.d.ts.map +1 -0
- package/dist/release/staging.js +218 -0
- package/dist/release/staging.js.map +1 -0
- package/dist/resolve/authored.d.ts +53 -0
- package/dist/resolve/authored.d.ts.map +1 -0
- package/dist/resolve/authored.js +55 -0
- package/dist/resolve/authored.js.map +1 -0
- package/dist/resolve/encode.d.ts +3 -0
- package/dist/resolve/encode.d.ts.map +1 -0
- package/dist/resolve/encode.js +21 -0
- package/dist/resolve/encode.js.map +1 -0
- package/dist/resolve/errors.d.ts +7 -0
- package/dist/resolve/errors.d.ts.map +1 -0
- package/dist/resolve/errors.js +17 -0
- package/dist/resolve/errors.js.map +1 -0
- package/dist/resolve/facts.d.ts +12 -0
- package/dist/resolve/facts.d.ts.map +1 -0
- package/dist/resolve/facts.js +18 -0
- package/dist/resolve/facts.js.map +1 -0
- package/dist/resolve/resolve.d.ts +10 -0
- package/dist/resolve/resolve.d.ts.map +1 -0
- package/dist/resolve/resolve.js +242 -0
- package/dist/resolve/resolve.js.map +1 -0
- package/dist/store.d.ts +11 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +9 -0
- package/dist/store.js.map +1 -0
- package/examples/README.md +20 -30
- package/examples/github-release/release.config.json +11 -18
- package/examples/homebrew-tap/README.md +11 -0
- package/examples/homebrew-tap/release.config.json +40 -28
- package/examples/multi-target/release.config.json +28 -53
- package/examples/npm-first-publish/release.config.json +23 -25
- package/examples/npm-only/release.config.json +22 -30
- package/examples/portable-cli/README.md +17 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-arm64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-darwin-x64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-arm64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-linux-x64 +1 -0
- package/examples/portable-cli/artifacts/portable-example-0.1.0-windows-x64.exe +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_10_15_x86_64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-macosx_11_0_arm64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_aarch64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-manylinux2014_x86_64.whl +1 -0
- package/examples/portable-cli/artifacts/portable_example-0.1.0-py3-none-win_amd64.whl +1 -0
- package/examples/portable-cli/package.json +9 -0
- package/examples/portable-cli/release.config.json +53 -0
- package/examples/portable-cli/src/cli.ts +3 -0
- package/examples/pypi-registry/README.md +8 -0
- package/examples/scoop-bucket/README.md +10 -0
- package/examples/scoop-bucket/release.config.json +40 -30
- package/package.json +73 -154
- package/src/api/api.ts +365 -0
- package/src/api/errors.ts +36 -0
- package/src/api/input.ts +92 -0
- package/src/api/runtime.ts +14 -0
- package/src/api/types.ts +103 -0
- package/src/capabilities/bun-targets.ts +2 -0
- package/src/capabilities/field-ownership.ts +60 -0
- package/src/capabilities/module.ts +158 -0
- package/src/capabilities/registry.ts +333 -0
- package/src/config/config.ts +48 -0
- package/src/correction/coordinator.ts +336 -0
- package/src/correction/index.ts +2 -0
- package/src/correction/intent.ts +172 -0
- package/src/drivers/archive.ts +111 -0
- package/src/drivers/contain.ts +20 -0
- package/src/drivers/environment.ts +28 -0
- package/src/drivers/errors.ts +6 -0
- package/src/drivers/glob.ts +137 -0
- package/src/drivers/process.ts +339 -0
- package/src/drivers/python-wheel.ts +145 -0
- package/src/drivers/redact.ts +31 -0
- package/src/drivers/seccomp-helper-source.ts +121 -0
- package/src/drivers/utils.ts +10 -0
- package/src/drivers/workspace.ts +46 -0
- package/src/extensions/provider-adapter.ts +99 -0
- package/src/host.ts +140 -0
- package/src/index.ts +64 -0
- package/src/model/artifact-collection.ts +237 -0
- package/src/model/authority.ts +116 -0
- package/src/model/bun-targets.ts +34 -0
- package/src/model/canonical.ts +205 -0
- package/src/model/catalog.ts +220 -0
- package/src/model/digest.ts +172 -0
- package/src/model/errors.ts +6 -0
- package/src/model/primitives.ts +37 -0
- package/src/model/pypi.ts +30 -0
- package/src/model/python-distribution.ts +360 -0
- package/src/model/secret-patterns.ts +11 -0
- package/src/operation-journal/authority.ts +162 -0
- package/src/operation-journal/aws/deadline.ts +41 -0
- package/src/operation-journal/aws/oidc.ts +439 -0
- package/src/operation-journal/aws/policy.ts +491 -0
- package/src/operation-journal/aws/s3-boundary.ts +562 -0
- package/src/operation-journal/aws.ts +60 -0
- package/src/operation-journal/canonical.ts +373 -0
- package/src/operation-journal/model.ts +301 -0
- package/src/operation-journal/reducer.ts +112 -0
- package/src/operation-journal/s3.ts +884 -0
- package/src/operation-journal.ts +51 -0
- package/src/platform/bun.ts +38 -0
- package/src/platform/credentials.ts +1151 -0
- package/src/platform/host-support.ts +4 -0
- package/src/platform/node.ts +38 -0
- package/src/platform/release-runtime.ts +47 -0
- package/src/platform/services.ts +57 -0
- package/src/platform/source-observer.ts +193 -0
- package/src/provider-sdk.ts +48 -0
- package/src/publication/adapter.ts +132 -0
- package/src/publication/authority.ts +397 -0
- package/src/publication/catalog-git.ts +603 -0
- package/src/publication/claim.ts +51 -0
- package/src/publication/coordinator.ts +578 -0
- package/src/publication/github.ts +1022 -0
- package/src/publication/http.ts +101 -0
- package/src/publication/index.ts +4 -0
- package/src/publication/npm.ts +525 -0
- package/src/publication/profiles.ts +94 -0
- package/src/publication/publisher.ts +130 -0
- package/src/publication/pypi.ts +463 -0
- package/src/publication/recovery.ts +349 -0
- package/src/publication/report.ts +628 -0
- package/src/recipes/config.ts +395 -0
- package/src/release/capabilities.ts +460 -0
- package/src/release/compiler.ts +28 -0
- package/src/release/config.ts +12 -0
- package/src/release/context.ts +223 -0
- package/src/release/graph.ts +866 -0
- package/src/release/inspect.ts +83 -0
- package/src/release/prepare.ts +1329 -0
- package/src/release/prepared-ref.ts +193 -0
- package/src/release/prepared-store.ts +378 -0
- package/src/release/prepared.ts +299 -0
- package/src/release/staging.ts +257 -0
- package/src/resolve/authored.ts +64 -0
- package/src/resolve/encode.ts +22 -0
- package/src/resolve/errors.ts +15 -0
- package/src/resolve/facts.ts +18 -0
- package/src/resolve/resolve.ts +328 -0
- package/src/store.ts +28 -0
- package/templates/README.md +55 -72
- package/templates/bun-cli-github/README.md +7 -9
- package/templates/bun-cli-github/release.config.json +35 -73
- package/templates/github-actions/release.yml +74 -0
- package/templates/github-actions/reviewed-release.yml +115 -0
- package/templates/multi-target-homebrew/README.md +10 -0
- package/templates/multi-target-homebrew/release.config.json +43 -60
- package/templates/multi-target-scoop/README.md +10 -0
- package/templates/multi-target-scoop/release.config.json +43 -62
- package/templates/npm-github/release.config.json +25 -38
- package/templates/npm-github/reviewed-release.config.json +37 -0
- package/templates/npm-only/README.md +10 -0
- package/templates/npm-only/release.config.json +15 -30
- package/templates/portable-cli/README.md +13 -0
- package/templates/portable-cli/release.config.json +53 -0
- package/dist/artifacts/adapter.d.ts +0 -39
- package/dist/artifacts/adapter.d.ts.map +0 -1
- package/dist/artifacts/adapter.js +0 -23
- package/dist/artifacts/adapter.js.map +0 -1
- package/dist/artifacts/registry.d.ts +0 -21
- package/dist/artifacts/registry.d.ts.map +0 -1
- package/dist/artifacts/registry.js +0 -21
- package/dist/artifacts/registry.js.map +0 -1
- package/dist/config/errors.d.ts +0 -24
- package/dist/config/errors.d.ts.map +0 -1
- package/dist/config/errors.js +0 -19
- package/dist/config/errors.js.map +0 -1
- package/dist/config/load.d.ts +0 -9
- package/dist/config/load.d.ts.map +0 -1
- package/dist/config/load.js +0 -29
- package/dist/config/load.js.map +0 -1
- package/dist/config/schema.d.ts +0 -12
- package/dist/config/schema.d.ts.map +0 -1
- package/dist/config/schema.js +0 -19
- package/dist/config/schema.js.map +0 -1
- package/dist/domain/artifact.d.ts +0 -118
- package/dist/domain/artifact.d.ts.map +0 -1
- package/dist/domain/artifact.js +0 -197
- package/dist/domain/artifact.js.map +0 -1
- package/dist/domain/evidence.d.ts +0 -59
- package/dist/domain/evidence.d.ts.map +0 -1
- package/dist/domain/evidence.js +0 -51
- package/dist/domain/evidence.js.map +0 -1
- package/dist/domain/operation.d.ts +0 -143
- package/dist/domain/operation.d.ts.map +0 -1
- package/dist/domain/operation.js +0 -198
- package/dist/domain/operation.js.map +0 -1
- package/dist/domain/release.d.ts +0 -93
- package/dist/domain/release.d.ts.map +0 -1
- package/dist/domain/release.js +0 -82
- package/dist/domain/release.js.map +0 -1
- package/dist/domain/remote-state.d.ts +0 -58
- package/dist/domain/remote-state.d.ts.map +0 -1
- package/dist/domain/remote-state.js +0 -55
- package/dist/domain/remote-state.js.map +0 -1
- package/dist/domain/target.d.ts +0 -148
- package/dist/domain/target.d.ts.map +0 -1
- package/dist/domain/target.js +0 -151
- package/dist/domain/target.js.map +0 -1
- package/dist/host/host.d.ts +0 -32
- package/dist/host/host.d.ts.map +0 -1
- package/dist/host/host.js +0 -24
- package/dist/host/host.js.map +0 -1
- package/dist/host/http-live.d.ts +0 -6
- package/dist/host/http-live.d.ts.map +0 -1
- package/dist/host/http-live.js +0 -86
- package/dist/host/http-live.js.map +0 -1
- package/dist/host/http.d.ts +0 -43
- package/dist/host/http.d.ts.map +0 -1
- package/dist/host/http.js +0 -59
- package/dist/host/http.js.map +0 -1
- package/dist/host/platform.d.ts +0 -10
- package/dist/host/platform.d.ts.map +0 -1
- package/dist/host/platform.js +0 -114
- package/dist/host/platform.js.map +0 -1
- package/dist/host/test.d.ts +0 -23
- package/dist/host/test.d.ts.map +0 -1
- package/dist/host/test.js +0 -222
- package/dist/host/test.js.map +0 -1
- package/dist/internal/workspace-path.d.ts +0 -15
- package/dist/internal/workspace-path.d.ts.map +0 -1
- package/dist/internal/workspace-path.js +0 -36
- package/dist/internal/workspace-path.js.map +0 -1
- package/dist/planner/artifact-inventory.d.ts +0 -9
- package/dist/planner/artifact-inventory.d.ts.map +0 -1
- package/dist/planner/artifact-inventory.js +0 -86
- package/dist/planner/artifact-inventory.js.map +0 -1
- package/dist/planner/create-release-plan.d.ts +0 -5
- package/dist/planner/create-release-plan.d.ts.map +0 -1
- package/dist/planner/create-release-plan.js +0 -25
- package/dist/planner/create-release-plan.js.map +0 -1
- package/dist/planner/errors.d.ts +0 -67
- package/dist/planner/errors.d.ts.map +0 -1
- package/dist/planner/errors.js +0 -58
- package/dist/planner/errors.js.map +0 -1
- package/dist/planner/evidence-recorder.d.ts +0 -28
- package/dist/planner/evidence-recorder.d.ts.map +0 -1
- package/dist/planner/evidence-recorder.js +0 -362
- package/dist/planner/evidence-recorder.js.map +0 -1
- package/dist/planner/executor.d.ts +0 -58
- package/dist/planner/executor.d.ts.map +0 -1
- package/dist/planner/executor.js +0 -147
- package/dist/planner/executor.js.map +0 -1
- package/dist/planner/normalize-release.d.ts +0 -19
- package/dist/planner/normalize-release.d.ts.map +0 -1
- package/dist/planner/normalize-release.js +0 -342
- package/dist/planner/normalize-release.js.map +0 -1
- package/dist/planner/reconcile.d.ts +0 -17
- package/dist/planner/reconcile.d.ts.map +0 -1
- package/dist/planner/reconcile.js +0 -259
- package/dist/planner/reconcile.js.map +0 -1
- package/dist/planner/render-plan.d.ts +0 -15
- package/dist/planner/render-plan.d.ts.map +0 -1
- package/dist/planner/render-plan.js +0 -231
- package/dist/planner/render-plan.js.map +0 -1
- package/dist/targets/adapter-helpers.d.ts +0 -79
- package/dist/targets/adapter-helpers.d.ts.map +0 -1
- package/dist/targets/adapter-helpers.js +0 -194
- package/dist/targets/adapter-helpers.js.map +0 -1
- package/dist/targets/adapter.d.ts +0 -17
- package/dist/targets/adapter.d.ts.map +0 -1
- package/dist/targets/adapter.js +0 -2
- package/dist/targets/adapter.js.map +0 -1
- package/dist/targets/github-release.d.ts +0 -25
- package/dist/targets/github-release.d.ts.map +0 -1
- package/dist/targets/github-release.js +0 -82
- package/dist/targets/github-release.js.map +0 -1
- package/dist/targets/github.d.ts +0 -11
- package/dist/targets/github.d.ts.map +0 -1
- package/dist/targets/github.js +0 -117
- package/dist/targets/github.js.map +0 -1
- package/dist/targets/homebrew.d.ts +0 -11
- package/dist/targets/homebrew.d.ts.map +0 -1
- package/dist/targets/homebrew.js +0 -210
- package/dist/targets/homebrew.js.map +0 -1
- package/dist/targets/live.d.ts +0 -5
- package/dist/targets/live.d.ts.map +0 -1
- package/dist/targets/live.js +0 -50
- package/dist/targets/live.js.map +0 -1
- package/dist/targets/npm.d.ts +0 -10
- package/dist/targets/npm.d.ts.map +0 -1
- package/dist/targets/npm.js +0 -112
- package/dist/targets/npm.js.map +0 -1
- package/dist/targets/pypi.d.ts +0 -11
- package/dist/targets/pypi.d.ts.map +0 -1
- package/dist/targets/pypi.js +0 -141
- package/dist/targets/pypi.js.map +0 -1
- package/dist/targets/registry.d.ts +0 -25
- package/dist/targets/registry.d.ts.map +0 -1
- package/dist/targets/registry.js +0 -34
- package/dist/targets/registry.js.map +0 -1
- package/dist/targets/scoop.d.ts +0 -11
- package/dist/targets/scoop.d.ts.map +0 -1
- package/dist/targets/scoop.js +0 -88
- package/dist/targets/scoop.js.map +0 -1
- package/dist/types/effect-internal.d.ts +0 -5
- package/dist/types/effect-internal.d.ts.map +0 -1
- package/dist/types/effect-internal.js +0 -2
- package/dist/types/effect-internal.js.map +0 -1
- package/dist/workflows/config.d.ts +0 -202
- package/dist/workflows/config.d.ts.map +0 -1
- package/dist/workflows/config.js +0 -420
- package/dist/workflows/config.js.map +0 -1
- package/dist/workflows/diagnostics.d.ts +0 -62
- package/dist/workflows/diagnostics.d.ts.map +0 -1
- package/dist/workflows/diagnostics.js +0 -530
- package/dist/workflows/diagnostics.js.map +0 -1
- package/dist/workflows/distribution.d.ts +0 -25
- package/dist/workflows/distribution.d.ts.map +0 -1
- package/dist/workflows/distribution.js +0 -24
- package/dist/workflows/distribution.js.map +0 -1
- package/dist/workflows/evidence.d.ts +0 -17
- package/dist/workflows/evidence.d.ts.map +0 -1
- package/dist/workflows/evidence.js +0 -32
- package/dist/workflows/evidence.js.map +0 -1
- package/dist/workflows/index.d.ts +0 -8
- package/dist/workflows/index.d.ts.map +0 -1
- package/dist/workflows/index.js +0 -7
- package/dist/workflows/index.js.map +0 -1
- package/dist/workflows/init.d.ts +0 -84
- package/dist/workflows/init.d.ts.map +0 -1
- package/dist/workflows/init.js +0 -487
- package/dist/workflows/init.js.map +0 -1
- package/dist/workflows/live.d.ts +0 -9
- package/dist/workflows/live.d.ts.map +0 -1
- package/dist/workflows/live.js +0 -7
- package/dist/workflows/live.js.map +0 -1
- package/dist/workflows/options.d.ts +0 -30
- package/dist/workflows/options.d.ts.map +0 -1
- package/dist/workflows/options.js +0 -16
- package/dist/workflows/options.js.map +0 -1
- package/examples/non-strict-skips/artifacts/release-example-skips-0.1.0.tgz +0 -1
- package/examples/non-strict-skips/release.config.json +0 -31
- package/examples/pypi-registry/release.config.json +0 -31
- package/templates/github-actions/plan-and-approved-execute.yml +0 -58
- package/templates/github-actions/plan-only.yml +0 -33
- package/templates/github-actions/trusted-publishing.yml +0 -61
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// Portable matcher for the documented archive `files` grammar: `*` and `?`
|
|
2
|
+
// inside one segment, `**` as a whole segment spanning segments, `[...]`
|
|
3
|
+
// classes, and `{a,b}` alternation. Patterns reach here already slash
|
|
4
|
+
// normalized, so a backslash is only ever an explicit escape.
|
|
5
|
+
// A malformed pattern (unclosed `[` or `{`) matches nothing, so a typo fails
|
|
6
|
+
// loudly upstream as "patterns matched no workspace files".
|
|
7
|
+
const alternativeLimit = 1024
|
|
8
|
+
const metacharacters = new Set(["\\", "^", "$", ".", "*", "+", "?", "(", ")", "[", "]", "{", "}", "|", "/"])
|
|
9
|
+
const literal = (value: string): string => metacharacters.has(value) ? `\\${value}` : value
|
|
10
|
+
const classLiteral = (value: string): string => ["\\", "]", "^", "["].includes(value) ? `\\${value}` : value
|
|
11
|
+
const classEnd = (pattern: string, open: number): number | undefined => {
|
|
12
|
+
let index = open + 1
|
|
13
|
+
if (pattern[index] === "!" || pattern[index] === "^") index += 1
|
|
14
|
+
if (pattern[index] === "]") index += 1
|
|
15
|
+
while (index < pattern.length) {
|
|
16
|
+
if (pattern[index] === "\\") index += 2
|
|
17
|
+
else if (pattern[index] === "]") return index
|
|
18
|
+
else index += 1
|
|
19
|
+
}
|
|
20
|
+
return undefined
|
|
21
|
+
}
|
|
22
|
+
const characterClass = (body: string): string => {
|
|
23
|
+
const negated = body.startsWith("!") || body.startsWith("^")
|
|
24
|
+
const members = negated ? body.slice(1) : body
|
|
25
|
+
let source = ""
|
|
26
|
+
let index = 0
|
|
27
|
+
while (index < members.length) {
|
|
28
|
+
const value = members[index]!
|
|
29
|
+
if (value === "\\" && index + 1 < members.length) {
|
|
30
|
+
source += `\\${members[index + 1]!}`
|
|
31
|
+
index += 2
|
|
32
|
+
continue
|
|
33
|
+
}
|
|
34
|
+
source += value === "-" ? "-" : classLiteral(value)
|
|
35
|
+
index += 1
|
|
36
|
+
}
|
|
37
|
+
return `[${negated ? "^" : ""}${source}]`
|
|
38
|
+
}
|
|
39
|
+
// `{a,b}` expands to whole alternative patterns because a branch may contain
|
|
40
|
+
// separators (`{src/a,b}/x`); a class is copied verbatim so `,` inside it stays
|
|
41
|
+
// a class member.
|
|
42
|
+
const expand = (
|
|
43
|
+
pattern: string, start: number, depth: number
|
|
44
|
+
): { readonly alternatives: ReadonlyArray<string>, readonly next: number } | undefined => {
|
|
45
|
+
const completed: Array<string> = []
|
|
46
|
+
let current: ReadonlyArray<string> = [""]
|
|
47
|
+
let index = start
|
|
48
|
+
const append = (text: string) => { current = current.map((value) => value + text) }
|
|
49
|
+
const flush = () => { completed.push(...current); current = [""] }
|
|
50
|
+
while (index < pattern.length) {
|
|
51
|
+
const value = pattern[index]!
|
|
52
|
+
if (value === "\\") {
|
|
53
|
+
if (index + 1 >= pattern.length) return undefined
|
|
54
|
+
append(pattern.slice(index, index + 2))
|
|
55
|
+
index += 2
|
|
56
|
+
} else if (value === "[") {
|
|
57
|
+
const end = classEnd(pattern, index)
|
|
58
|
+
if (end === undefined) return undefined
|
|
59
|
+
append(pattern.slice(index, end + 1))
|
|
60
|
+
index = end + 1
|
|
61
|
+
} else if (value === "{") {
|
|
62
|
+
const group = expand(pattern, index + 1, depth + 1)
|
|
63
|
+
if (group === undefined) return undefined
|
|
64
|
+
current = current.flatMap((prefix) => group.alternatives.map((suffix) => prefix + suffix))
|
|
65
|
+
if (current.length > alternativeLimit) return undefined
|
|
66
|
+
index = group.next
|
|
67
|
+
} else if (depth > 0 && value === "}") {
|
|
68
|
+
flush()
|
|
69
|
+
return { alternatives: completed, next: index + 1 }
|
|
70
|
+
} else if (depth > 0 && value === ",") {
|
|
71
|
+
flush()
|
|
72
|
+
index += 1
|
|
73
|
+
} else {
|
|
74
|
+
append(value)
|
|
75
|
+
index += 1
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (depth > 0) return undefined
|
|
79
|
+
flush()
|
|
80
|
+
return { alternatives: completed, next: index }
|
|
81
|
+
}
|
|
82
|
+
const globstarAt = (pattern: string, index: number): boolean =>
|
|
83
|
+
pattern.startsWith("**", index) &&
|
|
84
|
+
(index + 2 === pattern.length || pattern[index + 2] === "/")
|
|
85
|
+
const compile = (pattern: string): RegExp | undefined => {
|
|
86
|
+
let source = "^"
|
|
87
|
+
let index = 0
|
|
88
|
+
while (index < pattern.length) {
|
|
89
|
+
const value = pattern[index]!
|
|
90
|
+
if (value === "\\") {
|
|
91
|
+
if (index + 1 >= pattern.length) return undefined
|
|
92
|
+
source += literal(pattern[index + 1]!)
|
|
93
|
+
index += 2
|
|
94
|
+
} else if (value === "[") {
|
|
95
|
+
const end = classEnd(pattern, index)
|
|
96
|
+
if (end === undefined) return undefined
|
|
97
|
+
source += characterClass(pattern.slice(index + 1, end))
|
|
98
|
+
index = end + 1
|
|
99
|
+
} else if (value === "*") {
|
|
100
|
+
let run = 1
|
|
101
|
+
while (pattern[index + run] === "*") run += 1
|
|
102
|
+
const whole = (index === 0 || pattern[index - 1] === "/") &&
|
|
103
|
+
(index + run === pattern.length || pattern[index + run] === "/")
|
|
104
|
+
const rest = index + run + 1
|
|
105
|
+
if (run === 2 && whole && index + run === pattern.length) source += ".*"
|
|
106
|
+
else if (run === 2 && whole) {
|
|
107
|
+
// `**/**` collapses; otherwise `**/` skips whole segments and whatever
|
|
108
|
+
// follows must still match at least one character, so `**/*` never
|
|
109
|
+
// matches a bare directory the way `a/*` does.
|
|
110
|
+
if (!globstarAt(pattern, rest)) {
|
|
111
|
+
source += rest === pattern.length ? "(?:[^/]*/)*" : "(?:[^/]*/)*(?=[\\s\\S])"
|
|
112
|
+
}
|
|
113
|
+
run += 1
|
|
114
|
+
} else source += "[^/]*"
|
|
115
|
+
index += run
|
|
116
|
+
} else if (value === "?") {
|
|
117
|
+
source += "[^/]"
|
|
118
|
+
index += 1
|
|
119
|
+
} else {
|
|
120
|
+
source += literal(value)
|
|
121
|
+
index += 1
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// A reversed class range like [z-a] is legal glob text but an invalid
|
|
125
|
+
// regular expression; it matches nothing, like every other malformed pattern.
|
|
126
|
+
try {
|
|
127
|
+
return new RegExp(`${source}$`)
|
|
128
|
+
} catch {
|
|
129
|
+
return undefined
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export const matchGlob = (pattern: string): (path: string) => boolean => {
|
|
133
|
+
const expanded = expand(pattern, 0, 0)
|
|
134
|
+
const compiled = expanded?.alternatives.map(compile)
|
|
135
|
+
if (compiled === undefined || compiled.some((item) => item === undefined)) return () => false
|
|
136
|
+
return (path) => compiled.some((item) => item!.test(path))
|
|
137
|
+
}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect"
|
|
2
|
+
import * as Stream from "effect/Stream"
|
|
3
|
+
import * as ChildProcess from "effect/unstable/process/ChildProcess"
|
|
4
|
+
import { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSpawner"
|
|
5
|
+
import { createHash } from "node:crypto"
|
|
6
|
+
import {
|
|
7
|
+
accessSync,
|
|
8
|
+
chmodSync,
|
|
9
|
+
constants,
|
|
10
|
+
copyFileSync,
|
|
11
|
+
lstatSync,
|
|
12
|
+
mkdirSync,
|
|
13
|
+
readFileSync,
|
|
14
|
+
readdirSync,
|
|
15
|
+
realpathSync,
|
|
16
|
+
rmSync,
|
|
17
|
+
statSync,
|
|
18
|
+
writeFileSync
|
|
19
|
+
} from "node:fs"
|
|
20
|
+
import { delimiter, isAbsolute, join, resolve } from "node:path"
|
|
21
|
+
import { readEnvironment, readOptionalEnv } from "./environment.js"
|
|
22
|
+
import { redactOutput, redactProtocolOutput } from "./redact.js"
|
|
23
|
+
import { networkIsolationHelperSource } from "./seccomp-helper-source.js"
|
|
24
|
+
import { failure } from "./utils.js"
|
|
25
|
+
import { DriverError } from "./errors.js"
|
|
26
|
+
import { makeCanonicalTemporaryDirectory } from "./workspace.js"
|
|
27
|
+
|
|
28
|
+
export interface NetworkIsolationIdentity {
|
|
29
|
+
readonly protocol: "ts-release-seccomp-network-deny/v1"
|
|
30
|
+
readonly helperSha256: string
|
|
31
|
+
readonly librarySha256: string
|
|
32
|
+
readonly bunVersion: string
|
|
33
|
+
readonly bunSha256: string
|
|
34
|
+
readonly kernel: string
|
|
35
|
+
readonly architecture: string
|
|
36
|
+
readonly deniedSyscalls: ReadonlyArray<string>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface ExecutableIdentity {
|
|
40
|
+
readonly protocol: "ts-release-executable/v1"
|
|
41
|
+
readonly command: string
|
|
42
|
+
readonly sha256: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface BunCompileRuntimeIdentity {
|
|
46
|
+
readonly protocol: "ts-release-bun-compile-runtime/v1"
|
|
47
|
+
readonly target: "bun-linux-x64" | "bun-linux-arm64" | "bun-darwin-x64" | "bun-darwin-arm64"
|
|
48
|
+
readonly bunVersion: string
|
|
49
|
+
readonly source: "executing-bun" | "host-cache-private-copy"
|
|
50
|
+
readonly cacheFile: string
|
|
51
|
+
readonly sha256: string
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const helperDigest = createHash("sha256").update(networkIsolationHelperSource).digest("hex")
|
|
55
|
+
|
|
56
|
+
export type CommandOutcome = {
|
|
57
|
+
readonly exitCode: number, readonly stdout: string, readonly stderr: string,
|
|
58
|
+
/** Present for the production process driver; protocol doubles may omit it. */
|
|
59
|
+
readonly tool?: ExecutableIdentity,
|
|
60
|
+
readonly networkIsolation?: NetworkIsolationIdentity,
|
|
61
|
+
readonly bunCompileRuntime?: BunCompileRuntimeIdentity
|
|
62
|
+
}
|
|
63
|
+
export type RunCommand = (command: {
|
|
64
|
+
readonly argv: ReadonlyArray<string>, readonly cwd: string,
|
|
65
|
+
readonly environmentNames: ReadonlyArray<string>,
|
|
66
|
+
/** Complete redacted stdout for an immediate machine-protocol decoder.
|
|
67
|
+
* The caller must not persist it as diagnostic output. */
|
|
68
|
+
readonly stdout?: "complete-protocol",
|
|
69
|
+
/** Generic commands require the fail-closed Linux/libseccomp filter;
|
|
70
|
+
* certified local-only tools additionally carry their own offline switch. */
|
|
71
|
+
readonly network: "deny" | "offline-cli"
|
|
72
|
+
}) => Effect.Effect<CommandOutcome, DriverError>
|
|
73
|
+
|
|
74
|
+
const collect = (stream: Stream.Stream<Uint8Array, unknown>) =>
|
|
75
|
+
Stream.mkString(Stream.decodeText(stream))
|
|
76
|
+
|
|
77
|
+
const executableIdentity = (command: string, cwd: string, path: string | undefined): ExecutableIdentity => {
|
|
78
|
+
const candidates = command.includes("/")
|
|
79
|
+
? [isAbsolute(command) ? command : resolve(cwd, command)]
|
|
80
|
+
: (path ?? "").split(delimiter).filter((entry) => entry.length > 0).map((entry) => resolve(entry, command))
|
|
81
|
+
const executable = candidates.find((candidate) => {
|
|
82
|
+
try {
|
|
83
|
+
accessSync(candidate, constants.X_OK)
|
|
84
|
+
return statSync(candidate).isFile()
|
|
85
|
+
} catch {
|
|
86
|
+
return false
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
if (executable === undefined) throw new Error(`Executable ${command} is unavailable in the closed PATH.`)
|
|
90
|
+
const canonical = realpathSync(executable)
|
|
91
|
+
return {
|
|
92
|
+
protocol: "ts-release-executable/v1",
|
|
93
|
+
command,
|
|
94
|
+
sha256: createHash("sha256").update(readFileSync(canonical)).digest("hex")
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const isDigest = (value: unknown): value is string => typeof value === "string" && /^[a-f0-9]{64}$/u.test(value)
|
|
99
|
+
const offlineBunInstallArgv = [
|
|
100
|
+
"bun",
|
|
101
|
+
"install",
|
|
102
|
+
"--offline",
|
|
103
|
+
"--frozen-lockfile",
|
|
104
|
+
"--ignore-scripts",
|
|
105
|
+
"--no-save",
|
|
106
|
+
"--linker=hoisted"
|
|
107
|
+
] as const
|
|
108
|
+
const isOfflineBunInstall = (command: Parameters<RunCommand>[0]): boolean =>
|
|
109
|
+
command.network === "offline-cli" && command.argv.length === offlineBunInstallArgv.length &&
|
|
110
|
+
command.argv.every((value, index) => value === offlineBunInstallArgv[index])
|
|
111
|
+
|
|
112
|
+
const readBunCacheDirectory = Effect.fn("readBunCacheDirectory")(function*() {
|
|
113
|
+
const configured = yield* readOptionalEnv("BUN_INSTALL_CACHE_DIR")
|
|
114
|
+
const home = configured === undefined ? yield* readOptionalEnv("HOME") : undefined
|
|
115
|
+
const candidate = configured ?? (home === undefined ? undefined : join(home, ".bun", "install", "cache"))
|
|
116
|
+
if (candidate === undefined || candidate.length === 0) {
|
|
117
|
+
return yield* Effect.fail(failure(
|
|
118
|
+
"Certified Bun cache access requires BUN_INSTALL_CACHE_DIR or HOME so the host cache can be located."
|
|
119
|
+
))
|
|
120
|
+
}
|
|
121
|
+
return yield* Effect.try({
|
|
122
|
+
try: () => {
|
|
123
|
+
if (!isAbsolute(candidate)) throw new Error("the cache path is not absolute")
|
|
124
|
+
const canonical = realpathSync(candidate)
|
|
125
|
+
if (!statSync(canonical).isDirectory()) throw new Error("the cache path is not a directory")
|
|
126
|
+
return canonical
|
|
127
|
+
},
|
|
128
|
+
catch: (cause) => failure(`The offline Bun install cache is unavailable: ${String(cause)}`)
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
const compileRuntimeFiles = {
|
|
133
|
+
"bun-linux-arm64": (version: string) => `bun-linux-aarch64-v${version}`,
|
|
134
|
+
"bun-darwin-x64": (version: string) => `bun-darwin-x64-v${version}`,
|
|
135
|
+
"bun-darwin-arm64": (version: string) => `bun-darwin-aarch64-v${version}`
|
|
136
|
+
} as const
|
|
137
|
+
|
|
138
|
+
type CertifiedBunCompileTarget = BunCompileRuntimeIdentity["target"]
|
|
139
|
+
const certifiedBunCompileTargets = new Set<CertifiedBunCompileTarget>([
|
|
140
|
+
"bun-linux-x64",
|
|
141
|
+
"bun-linux-arm64",
|
|
142
|
+
"bun-darwin-x64",
|
|
143
|
+
"bun-darwin-arm64"
|
|
144
|
+
])
|
|
145
|
+
|
|
146
|
+
const certifiedBunCompileTarget = (command: Parameters<RunCommand>[0]): CertifiedBunCompileTarget | undefined => {
|
|
147
|
+
const argv = command.argv
|
|
148
|
+
if (command.network !== "deny" || (argv.length !== 8 && argv.length !== 9) ||
|
|
149
|
+
argv[0] !== "bun" || argv[1] !== "build" || argv[2]?.startsWith("-") !== false ||
|
|
150
|
+
argv[3] !== "--compile" || argv[4] !== "--target" || argv[6] !== "--outfile" ||
|
|
151
|
+
argv[7]?.startsWith("-") !== false || (argv.length === 9 && argv[8] !== "--minify")) return undefined
|
|
152
|
+
return certifiedBunCompileTargets.has(argv[5] as CertifiedBunCompileTarget)
|
|
153
|
+
? argv[5] as CertifiedBunCompileTarget
|
|
154
|
+
: undefined
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const resolveBunCompileRuntime = Effect.fn("resolveBunCompileRuntime")(function*(
|
|
158
|
+
target: CertifiedBunCompileTarget,
|
|
159
|
+
tool: ExecutableIdentity
|
|
160
|
+
) {
|
|
161
|
+
const bunVersion = process.versions.bun
|
|
162
|
+
if (bunVersion === undefined || bunVersion.length === 0) {
|
|
163
|
+
return yield* Effect.fail(failure("Certified Bun compilation requires a Bun parent runtime."))
|
|
164
|
+
}
|
|
165
|
+
if (target === "bun-linux-x64") {
|
|
166
|
+
return {
|
|
167
|
+
sourcePath: undefined,
|
|
168
|
+
identity: {
|
|
169
|
+
protocol: "ts-release-bun-compile-runtime/v1",
|
|
170
|
+
target,
|
|
171
|
+
bunVersion,
|
|
172
|
+
source: "executing-bun",
|
|
173
|
+
cacheFile: "executing-bun",
|
|
174
|
+
sha256: tool.sha256
|
|
175
|
+
} satisfies BunCompileRuntimeIdentity
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const cache = yield* readBunCacheDirectory()
|
|
179
|
+
const cacheFile = compileRuntimeFiles[target](bunVersion)
|
|
180
|
+
return yield* Effect.try({
|
|
181
|
+
try: () => {
|
|
182
|
+
const sourcePath = join(cache, cacheFile)
|
|
183
|
+
if (lstatSync(sourcePath).isSymbolicLink() || !lstatSync(sourcePath).isFile() ||
|
|
184
|
+
realpathSync(sourcePath) !== sourcePath) {
|
|
185
|
+
throw new Error("the target runtime is not a canonical regular file")
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
sourcePath,
|
|
189
|
+
identity: {
|
|
190
|
+
protocol: "ts-release-bun-compile-runtime/v1",
|
|
191
|
+
target,
|
|
192
|
+
bunVersion,
|
|
193
|
+
source: "host-cache-private-copy",
|
|
194
|
+
cacheFile,
|
|
195
|
+
sha256: createHash("sha256").update(readFileSync(sourcePath)).digest("hex")
|
|
196
|
+
} satisfies BunCompileRuntimeIdentity
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
catch: (cause) => failure(`The certified Bun compile runtime is unavailable: ${String(cause)}`)
|
|
200
|
+
})
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
const parseIsolationIdentity = (path: string): NetworkIsolationIdentity => {
|
|
204
|
+
const value: unknown = JSON.parse(readFileSync(path, "utf8"))
|
|
205
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("isolation identity is not an object")
|
|
206
|
+
const item = value as Record<string, unknown>
|
|
207
|
+
if (item.protocol !== "ts-release-seccomp-network-deny/v1" || item.helperSha256 !== helperDigest ||
|
|
208
|
+
!isDigest(item.helperSha256) || !isDigest(item.librarySha256) || !isDigest(item.bunSha256) ||
|
|
209
|
+
typeof item.bunVersion !== "string" || item.bunVersion.length === 0 || typeof item.kernel !== "string" ||
|
|
210
|
+
item.kernel.length === 0 || typeof item.architecture !== "string" || item.architecture.length === 0 ||
|
|
211
|
+
!Array.isArray(item.deniedSyscalls) || item.deniedSyscalls.some((name) => typeof name !== "string")) {
|
|
212
|
+
throw new Error("isolation identity is malformed or disagrees with the embedded helper")
|
|
213
|
+
}
|
|
214
|
+
return item as unknown as NetworkIsolationIdentity
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Spawning is the capability that differs across hosts, so it arrives as a
|
|
218
|
+
// service. The runner is built once per live layer and closes over the
|
|
219
|
+
// spawner, keeping DriverCatalog method requirements at never.
|
|
220
|
+
export const makeRunCommand: Effect.Effect<RunCommand, never, ChildProcessSpawner> =
|
|
221
|
+
Effect.gen(function*() {
|
|
222
|
+
const spawner = yield* ChildProcessSpawner
|
|
223
|
+
return (command) => Effect.gen(function*() {
|
|
224
|
+
const baseEnvironment = yield* readEnvironment(command.environmentNames)
|
|
225
|
+
const env = isOfflineBunInstall(command)
|
|
226
|
+
? {
|
|
227
|
+
...Object.fromEntries(Object.entries(baseEnvironment).filter(([name]) => name !== "HOME")),
|
|
228
|
+
BUN_INSTALL_CACHE_DIR: yield* readBunCacheDirectory()
|
|
229
|
+
}
|
|
230
|
+
: baseEnvironment
|
|
231
|
+
const executable = command.network === "deny" ? "bun" : command.argv[0]!
|
|
232
|
+
const tool = yield* Effect.try({
|
|
233
|
+
try: () => executableIdentity(executable, command.cwd, env.PATH),
|
|
234
|
+
catch: (cause) => failure(String(cause))
|
|
235
|
+
})
|
|
236
|
+
const compileTarget = certifiedBunCompileTarget(command)
|
|
237
|
+
const compileRuntime = compileTarget === undefined
|
|
238
|
+
? undefined
|
|
239
|
+
: yield* resolveBunCompileRuntime(compileTarget, tool)
|
|
240
|
+
const compileResources = compileRuntime === undefined
|
|
241
|
+
? undefined
|
|
242
|
+
: yield* Effect.acquireRelease(
|
|
243
|
+
Effect.sync(() => {
|
|
244
|
+
const directory = makeCanonicalTemporaryDirectory("ts-release-bun-runtime-")
|
|
245
|
+
const cache = join(directory, "cache")
|
|
246
|
+
mkdirSync(cache, { mode: 0o700 })
|
|
247
|
+
if (compileRuntime.sourcePath !== undefined) {
|
|
248
|
+
copyFileSync(compileRuntime.sourcePath, join(cache, compileRuntime.identity.cacheFile))
|
|
249
|
+
chmodSync(join(cache, compileRuntime.identity.cacheFile), 0o500)
|
|
250
|
+
}
|
|
251
|
+
chmodSync(cache, 0o500)
|
|
252
|
+
return { directory, cache }
|
|
253
|
+
}),
|
|
254
|
+
({ cache, directory }) => Effect.sync(() => {
|
|
255
|
+
chmodSync(cache, 0o700)
|
|
256
|
+
rmSync(directory, { recursive: true, force: true })
|
|
257
|
+
})
|
|
258
|
+
)
|
|
259
|
+
const isolationResources = command.network === "deny"
|
|
260
|
+
? yield* Effect.acquireRelease(
|
|
261
|
+
Effect.sync(() => {
|
|
262
|
+
const directory = makeCanonicalTemporaryDirectory("ts-release-seccomp-")
|
|
263
|
+
const helper = join(directory, "network-deny.mjs")
|
|
264
|
+
const identity = join(directory, "identity.json")
|
|
265
|
+
writeFileSync(helper, networkIsolationHelperSource, { mode: 0o500 })
|
|
266
|
+
return { directory, helper, identity }
|
|
267
|
+
}),
|
|
268
|
+
({ directory }) => Effect.sync(() => rmSync(directory, { recursive: true, force: true }))
|
|
269
|
+
)
|
|
270
|
+
: undefined
|
|
271
|
+
const argv = command.network === "deny"
|
|
272
|
+
? ["--no-env-file", "--no-install", isolationResources!.helper, ...command.argv]
|
|
273
|
+
: [...command.argv.slice(1)]
|
|
274
|
+
const commandEnvironment = compileResources === undefined
|
|
275
|
+
? env
|
|
276
|
+
: { ...env, BUN_INSTALL_CACHE_DIR: compileResources.cache }
|
|
277
|
+
const handle = yield* spawner.spawn(ChildProcess.make(
|
|
278
|
+
executable,
|
|
279
|
+
argv,
|
|
280
|
+
{
|
|
281
|
+
cwd: command.cwd,
|
|
282
|
+
env: isolationResources === undefined ? commandEnvironment : {
|
|
283
|
+
...commandEnvironment,
|
|
284
|
+
TS_RELEASE_NETWORK_IDENTITY_FILE: isolationResources.identity,
|
|
285
|
+
TS_RELEASE_NETWORK_HELPER_SHA256: helperDigest,
|
|
286
|
+
TS_RELEASE_NETWORK_LIBRARY: "libseccomp.so.2"
|
|
287
|
+
},
|
|
288
|
+
stdin: "ignore", stdout: "pipe", stderr: "pipe"
|
|
289
|
+
}
|
|
290
|
+
))
|
|
291
|
+
const output = yield* Effect.all({
|
|
292
|
+
stdout: collect(handle.stdout),
|
|
293
|
+
stderr: collect(handle.stderr),
|
|
294
|
+
exitCode: handle.exitCode
|
|
295
|
+
}, { concurrency: "unbounded" })
|
|
296
|
+
// Redaction lives here, where the env values are in hand: every
|
|
297
|
+
// consumer of child output (Exec failures, publisher stdout/stderr)
|
|
298
|
+
// is covered at the source and no driver can forget.
|
|
299
|
+
const networkIsolation = isolationResources === undefined
|
|
300
|
+
? undefined
|
|
301
|
+
: yield* Effect.try({
|
|
302
|
+
try: () => parseIsolationIdentity(isolationResources.identity),
|
|
303
|
+
catch: (cause) => failure(String(cause))
|
|
304
|
+
})
|
|
305
|
+
if (networkIsolation !== undefined && networkIsolation.bunSha256 !== tool.sha256) {
|
|
306
|
+
return yield* Effect.fail(failure("The Bun executable changed between parent resolution and the isolation helper."))
|
|
307
|
+
}
|
|
308
|
+
if (compileResources !== undefined && compileRuntime !== undefined) yield* Effect.try({
|
|
309
|
+
try: () => {
|
|
310
|
+
const entries = readdirSync(compileResources.cache)
|
|
311
|
+
const expected = compileRuntime.sourcePath === undefined ? [] : [compileRuntime.identity.cacheFile]
|
|
312
|
+
if (entries.length !== expected.length || entries.some((entry, index) => entry !== expected[index])) {
|
|
313
|
+
throw new Error("the private runtime cache changed shape")
|
|
314
|
+
}
|
|
315
|
+
if (expected[0] !== undefined) {
|
|
316
|
+
const runtime = join(compileResources.cache, expected[0])
|
|
317
|
+
if (lstatSync(runtime).isSymbolicLink() || !lstatSync(runtime).isFile() ||
|
|
318
|
+
createHash("sha256").update(readFileSync(runtime)).digest("hex") !== compileRuntime.identity.sha256) {
|
|
319
|
+
throw new Error("the private runtime cache changed bytes or type")
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
catch: (cause) => failure(`Certified Bun compilation did not preserve its private runtime cache: ${String(cause)}`)
|
|
324
|
+
})
|
|
325
|
+
return {
|
|
326
|
+
stdout: command.stdout === "complete-protocol"
|
|
327
|
+
? redactProtocolOutput(output.stdout, commandEnvironment)
|
|
328
|
+
: redactOutput(output.stdout, commandEnvironment),
|
|
329
|
+
stderr: redactOutput(output.stderr, commandEnvironment),
|
|
330
|
+
exitCode: Number(output.exitCode),
|
|
331
|
+
tool,
|
|
332
|
+
...(networkIsolation === undefined ? {} : { networkIsolation }),
|
|
333
|
+
...(compileRuntime === undefined ? {} : { bunCompileRuntime: compileRuntime.identity })
|
|
334
|
+
}
|
|
335
|
+
}).pipe(
|
|
336
|
+
Effect.scoped,
|
|
337
|
+
Effect.mapError((cause) => cause instanceof DriverError ? cause : failure(String(cause)))
|
|
338
|
+
)
|
|
339
|
+
})
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { createHash } from "node:crypto"
|
|
2
|
+
import type { ArchiveEntry } from "./archive.js"
|
|
3
|
+
import { zip } from "./archive.js"
|
|
4
|
+
import {
|
|
5
|
+
bunArtifactTargets,
|
|
6
|
+
type BunArtifactTargetId
|
|
7
|
+
} from "../model/bun-targets.js"
|
|
8
|
+
|
|
9
|
+
export interface EmbeddedPythonWheelTarget {
|
|
10
|
+
readonly id: BunArtifactTargetId
|
|
11
|
+
readonly format: "elf" | "mach-o"
|
|
12
|
+
readonly architecture: "x86_64" | "aarch64"
|
|
13
|
+
readonly wheelTag: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const wheelTags = {
|
|
17
|
+
"linux-x64": "py3-none-manylinux_2_17_x86_64",
|
|
18
|
+
"linux-arm64": "py3-none-manylinux_2_17_aarch64",
|
|
19
|
+
"darwin-x64": "py3-none-macosx_13_0_x86_64",
|
|
20
|
+
"darwin-arm64": "py3-none-macosx_13_0_arm64"
|
|
21
|
+
} as const satisfies Readonly<Record<BunArtifactTargetId, string>>
|
|
22
|
+
|
|
23
|
+
export const embeddedPythonWheelTargets: ReadonlyArray<EmbeddedPythonWheelTarget> = Object.freeze(
|
|
24
|
+
bunArtifactTargets.map((target) => Object.freeze({
|
|
25
|
+
id: target.id,
|
|
26
|
+
format: target.format,
|
|
27
|
+
architecture: target.architecture,
|
|
28
|
+
wheelTag: wheelTags[target.id]
|
|
29
|
+
}))
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const encoder = new TextEncoder()
|
|
33
|
+
const bytes = (value: string): Uint8Array => encoder.encode(value)
|
|
34
|
+
const safeMetadata = (name: string, value: string): string => {
|
|
35
|
+
if (value.length === 0 || /[\r\n\0]/u.test(value)) {
|
|
36
|
+
throw new Error(`Python wheel ${name} must be a nonempty single-line value.`)
|
|
37
|
+
}
|
|
38
|
+
return value
|
|
39
|
+
}
|
|
40
|
+
const normalizedVersion = (version: string): string =>
|
|
41
|
+
safeMetadata("version", version).replaceAll("-", "_")
|
|
42
|
+
const distribution = "ts_release"
|
|
43
|
+
const moduleName = "ts_release"
|
|
44
|
+
const projectName = "ts-release"
|
|
45
|
+
const consoleScript = "ts-release"
|
|
46
|
+
|
|
47
|
+
export const embeddedPythonWheelFilename = (
|
|
48
|
+
target: EmbeddedPythonWheelTarget,
|
|
49
|
+
version: string
|
|
50
|
+
): string => `${distribution}-${normalizedVersion(version)}-${target.wheelTag}.whl`
|
|
51
|
+
|
|
52
|
+
const launcher = `"""Launch the platform-specific ts-release executable bundled in this wheel."""
|
|
53
|
+
|
|
54
|
+
from __future__ import annotations
|
|
55
|
+
|
|
56
|
+
import os
|
|
57
|
+
import stat
|
|
58
|
+
import sys
|
|
59
|
+
from importlib import resources
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def main() -> int:
|
|
63
|
+
try:
|
|
64
|
+
executable = resources.files("${moduleName}").joinpath("bin", "${consoleScript}")
|
|
65
|
+
with resources.as_file(executable) as binary:
|
|
66
|
+
if not binary.is_file():
|
|
67
|
+
raise RuntimeError(f"Bundled ${consoleScript} executable was not found: {binary}")
|
|
68
|
+
binary_path = os.fspath(binary)
|
|
69
|
+
os.chmod(binary_path, os.stat(binary_path).st_mode | stat.S_IXUSR)
|
|
70
|
+
os.execv(binary_path, [binary_path, *sys.argv[1:]])
|
|
71
|
+
except Exception as error:
|
|
72
|
+
print(f"${consoleScript} launcher error: {error}", file=sys.stderr)
|
|
73
|
+
return 1
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
raise SystemExit(main())
|
|
78
|
+
`
|
|
79
|
+
|
|
80
|
+
export interface EmbeddedPythonWheelInput {
|
|
81
|
+
readonly target: EmbeddedPythonWheelTarget
|
|
82
|
+
readonly version: string
|
|
83
|
+
readonly summary: string
|
|
84
|
+
readonly homepage: string
|
|
85
|
+
readonly license: string
|
|
86
|
+
readonly binary: Uint8Array
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const embeddedPythonWheelEntries = (
|
|
90
|
+
input: EmbeddedPythonWheelInput
|
|
91
|
+
): ReadonlyArray<ArchiveEntry> => {
|
|
92
|
+
const version = safeMetadata("version", input.version)
|
|
93
|
+
const summary = safeMetadata("summary", input.summary)
|
|
94
|
+
const homepage = safeMetadata("homepage", input.homepage)
|
|
95
|
+
const license = safeMetadata("license", input.license)
|
|
96
|
+
if (input.binary.length === 0) throw new Error("Python wheel executable cannot be empty.")
|
|
97
|
+
const distInfo = `${distribution}-${normalizedVersion(version)}.dist-info`
|
|
98
|
+
const metadata = [
|
|
99
|
+
"Metadata-Version: 2.4",
|
|
100
|
+
`Name: ${projectName}`,
|
|
101
|
+
`Version: ${version}`,
|
|
102
|
+
`Summary: ${summary}`,
|
|
103
|
+
`Home-page: ${homepage}`,
|
|
104
|
+
`License-Expression: ${license}`,
|
|
105
|
+
"Requires-Python: >=3.9",
|
|
106
|
+
"Description-Content-Type: text/plain",
|
|
107
|
+
"",
|
|
108
|
+
summary,
|
|
109
|
+
""
|
|
110
|
+
].join("\n")
|
|
111
|
+
const entries: ArchiveEntry[] = [
|
|
112
|
+
{ path: `${moduleName}/__init__.py`, data: bytes(`__version__ = ${JSON.stringify(version)}\n`), mode: 0o100644 },
|
|
113
|
+
{ path: `${moduleName}/cli.py`, data: bytes(launcher), mode: 0o100644 },
|
|
114
|
+
{ path: `${moduleName}/bin/${consoleScript}`, data: input.binary, mode: 0o100755 },
|
|
115
|
+
{ path: `${distInfo}/METADATA`, data: bytes(metadata), mode: 0o100644 },
|
|
116
|
+
{
|
|
117
|
+
path: `${distInfo}/WHEEL`,
|
|
118
|
+
data: bytes([
|
|
119
|
+
"Wheel-Version: 1.0",
|
|
120
|
+
"Generator: ts-release",
|
|
121
|
+
"Root-Is-Purelib: false",
|
|
122
|
+
`Tag: ${input.target.wheelTag}`,
|
|
123
|
+
""
|
|
124
|
+
].join("\n")),
|
|
125
|
+
mode: 0o100644
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
path: `${distInfo}/entry_points.txt`,
|
|
129
|
+
data: bytes(`[console_scripts]\n${consoleScript} = ${moduleName}.cli:main\n`),
|
|
130
|
+
mode: 0o100644
|
|
131
|
+
},
|
|
132
|
+
{ path: `${distInfo}/top_level.txt`, data: bytes(`${moduleName}\n`), mode: 0o100644 }
|
|
133
|
+
]
|
|
134
|
+
entries.sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0)
|
|
135
|
+
const recordPath = `${distInfo}/RECORD`
|
|
136
|
+
const record = entries.map((entry) =>
|
|
137
|
+
`${entry.path},sha256=${createHash("sha256").update(entry.data).digest("base64url")},${entry.data.length}`
|
|
138
|
+
)
|
|
139
|
+
record.push(`${recordPath},,`)
|
|
140
|
+
entries.push({ path: recordPath, data: bytes(`${record.join("\n")}\n`), mode: 0o100644 })
|
|
141
|
+
return entries
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export const buildEmbeddedPythonWheel = (input: EmbeddedPythonWheelInput): Uint8Array =>
|
|
145
|
+
zip(embeddedPythonWheelEntries(input), "deflate")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { secretPatterns } from "../model/secret-patterns.js"
|
|
2
|
+
|
|
3
|
+
const EXCERPT_LIMIT = 2000
|
|
4
|
+
|
|
5
|
+
const redact = (text: string, env: Readonly<Record<string, string>>): string => {
|
|
6
|
+
let out = text
|
|
7
|
+
for (const [name, value] of Object.entries(env)
|
|
8
|
+
.filter(([name, value]) => name !== "PATH" && value.length >= 6)
|
|
9
|
+
.sort((left, right) => right[1].length - left[1].length)) {
|
|
10
|
+
out = out.split(value).join(`[redacted:${name}]`)
|
|
11
|
+
}
|
|
12
|
+
for (const pattern of secretPatterns) {
|
|
13
|
+
out = out.replace(new RegExp(pattern.source, `${pattern.flags.replace("u", "")}gu`), "[redacted:token]")
|
|
14
|
+
}
|
|
15
|
+
return out
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Redacts KNOWN values (the exact env values the child received, longest
|
|
19
|
+
// first, except PATH) and known token shapes, then bounds the excerpt. Child
|
|
20
|
+
// output enters a durable diagnostic ledger only through this bounded form.
|
|
21
|
+
export const redactOutput = (
|
|
22
|
+
text: string, env: Readonly<Record<string, string>>
|
|
23
|
+
): string => {
|
|
24
|
+
const out = redact(text, env)
|
|
25
|
+
return out.length > EXCERPT_LIMIT ? `${out.slice(0, EXCERPT_LIMIT)}…[truncated]` : out
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Complete redacted machine-protocol output for immediate decoding only. */
|
|
29
|
+
export const redactProtocolOutput = (
|
|
30
|
+
text: string, env: Readonly<Record<string, string>>
|
|
31
|
+
): string => redact(text, env)
|