@mannyc1/ts-release 0.0.7 → 0.2.2
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 +124 -92
- package/CHANGELOG.md +115 -0
- package/LICENSE +21 -0
- package/README.md +278 -324
- package/SPEC.md +206 -310
- package/apps/release-ts/README.md +32 -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 +117 -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 +39239 -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 +8 -0
- package/dist/drivers/archive.d.ts.map +1 -0
- package/dist/drivers/archive.js +101 -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/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 +6 -0
- package/dist/drivers/workspace.d.ts.map +1 -0
- package/dist/drivers/workspace.js +49 -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/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 +772 -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 +644 -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 +1116 -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 +337 -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 +60 -156
- 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 +102 -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 +340 -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 +40 -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/platform/bun.ts +38 -0
- package/src/platform/credentials.ts +1083 -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 +954 -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 +459 -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 +1331 -0
- package/src/release/prepared-ref.ts +193 -0
- package/src/release/prepared-store.ts +377 -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 +57 -0
- package/templates/github-actions/reviewed-release.yml +80 -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,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release
|
|
3
|
+
description: Operate ts-release through its automatic inspect, prepare, publish, release, and correction APIs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ts-release release skill
|
|
7
|
+
|
|
8
|
+
Use the installed package and repository evidence as the authority. Read the
|
|
9
|
+
workspace package manifest and release configuration before suggesting edits.
|
|
10
|
+
|
|
11
|
+
## Lifecycle
|
|
12
|
+
|
|
13
|
+
- `inspect` reports authored configuration or an existing prepared bundle.
|
|
14
|
+
- `prepare` observes a clean source tree, runs only declared native
|
|
15
|
+
preparations, and stores exact `prepared-release/v1` bytes plus blobs.
|
|
16
|
+
- `publish` accepts only that prepared bundle and observes each destination
|
|
17
|
+
before and after provider mutation.
|
|
18
|
+
- `release` is the normal automatic path: it composes preparation and
|
|
19
|
+
publication in one process.
|
|
20
|
+
- `correct` consumes a prepared bundle and one canonical provider-specific
|
|
21
|
+
correction intent.
|
|
22
|
+
|
|
23
|
+
The derived graph is ephemeral. Exact prepared bytes are the cross-process
|
|
24
|
+
boundary. Never invent a second authority format, generic rollback, provider
|
|
25
|
+
hook, or host review protocol.
|
|
26
|
+
|
|
27
|
+
## Safety
|
|
28
|
+
|
|
29
|
+
Read the local schema before writing configuration. Keep paths relative and
|
|
30
|
+
contained. Credentials are environment names or Action inputs, never secret
|
|
31
|
+
values. Treat conflicts and inconclusive destination observations as blocked;
|
|
32
|
+
do not retry an unknown remote mutation blindly. Report typed errors and the
|
|
33
|
+
exact prepared bundle path.
|
|
34
|
+
|
|
35
|
+
## CLI
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
ts-release inspect --config release.config.json
|
|
39
|
+
ts-release prepare --config release.config.json
|
|
40
|
+
ts-release publish .release/ts-release/prepared/<manifest-digest>
|
|
41
|
+
ts-release release --config release.config.json
|
|
42
|
+
ts-release correct <prepared-bundle> <correction-intent.json>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Read `references/configuration.md`, `references/recovery.md`, and
|
|
46
|
+
`references/verification.md` when the task needs those details. A release
|
|
47
|
+
host may add review or environment protection outside the engine; do not place
|
|
48
|
+
that policy into configuration or prepared bytes.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
The authored JSON shape is validated strictly. Unknown keys, absolute paths,
|
|
4
|
+
parent traversal, non-JSON values, and raw secret values are rejected.
|
|
5
|
+
|
|
6
|
+
Minimal configuration:
|
|
7
|
+
|
|
8
|
+
```json
|
|
9
|
+
{
|
|
10
|
+
"project": { "name": "my-tool", "version": "1.2.3", "tag": "v1.2.3" },
|
|
11
|
+
"artifacts": [{ "id": "cli", "path": "dist/cli", "format": "executable" }]
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Use `builds` for Bun or configured native builders, `preparations` for typed
|
|
16
|
+
native command artifacts, `archives` and `checksum` for local outputs, and
|
|
17
|
+
`publish.npm` or `publish.github` for provider subjects. A preparation declares
|
|
18
|
+
every output and its argv; it is trusted local code, not a sandbox.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Recovery
|
|
2
|
+
|
|
3
|
+
The prepared bundle is the recovery boundary. Re-run `publish` with the same
|
|
4
|
+
bundle; it does not rebuild or reinterpret authored configuration. A lost
|
|
5
|
+
provider response is resolved only by observing the destination again.
|
|
6
|
+
|
|
7
|
+
Conflicts and inconclusive observations remain blocked. If a provider-specific
|
|
8
|
+
correction is needed, create a canonical correction intent bound to the bundle
|
|
9
|
+
digest and run `correct`. Corrections move forward through provider semantics;
|
|
10
|
+
they are not generic rollback.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Prepared workflow
|
|
2
|
+
|
|
3
|
+
The normal workflow is:
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
inspect → prepare → publish
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
`release` composes the last two steps automatically. Use `prepare` followed by
|
|
10
|
+
`publish` when a host deliberately transfers exact prepared bytes between
|
|
11
|
+
processes. The host may insert its own review or environment gate between those
|
|
12
|
+
steps without changing the bundle or adding a second lifecycle protocol.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Target selection
|
|
2
|
+
|
|
3
|
+
Choose only configuration supported by the installed schema:
|
|
4
|
+
|
|
5
|
+
- Bun-compiled executables use `builds[]` with `builder: "bun"`.
|
|
6
|
+
- Imported files use `artifacts[]`; archives and checksums are local
|
|
7
|
+
preparations.
|
|
8
|
+
- npm and GitHub Releases use their typed publication sections.
|
|
9
|
+
- Homebrew, Scoop, and generic catalog files are rendered as managed local
|
|
10
|
+
bytes; repository delivery requires its typed transport.
|
|
11
|
+
- Unsupported provider correction is reported as an explicit typed outcome.
|
|
12
|
+
|
|
13
|
+
Do not invent profiles, custom providers, hooks, or marketplace submissions.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Verification
|
|
2
|
+
|
|
3
|
+
Inside the ts-release repository run:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
bun run check
|
|
7
|
+
bun test
|
|
8
|
+
bun run check:portable
|
|
9
|
+
bun run check:agents
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
For a prepared boundary, inspect the bundle and verify that publication uses
|
|
13
|
+
the exact directory returned by `prepare`. Do not claim a provider write unless
|
|
14
|
+
the destination observation proves it.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"
|
|
2
|
+
import { dirname, join, resolve } from "node:path"
|
|
3
|
+
import { fileURLToPath } from "node:url"
|
|
4
|
+
|
|
5
|
+
type ArchiveEntry = { readonly path: string, readonly data: Uint8Array, readonly mode: number }
|
|
6
|
+
const encoder = new TextEncoder()
|
|
7
|
+
const text = (value: string): Uint8Array => encoder.encode(value)
|
|
8
|
+
const concat = (parts: ReadonlyArray<Uint8Array>): Uint8Array => {
|
|
9
|
+
const result = new Uint8Array(parts.reduce((size, part) => size + part.length, 0))
|
|
10
|
+
let offset = 0
|
|
11
|
+
for (const part of parts) { result.set(part, offset); offset += part.length }
|
|
12
|
+
return result
|
|
13
|
+
}
|
|
14
|
+
const integer = (bytes: number, value: number): Uint8Array => {
|
|
15
|
+
const result = new Uint8Array(bytes)
|
|
16
|
+
const view = new DataView(result.buffer)
|
|
17
|
+
if (bytes === 2) view.setUint16(0, value, true)
|
|
18
|
+
else view.setUint32(0, value, true)
|
|
19
|
+
return result
|
|
20
|
+
}
|
|
21
|
+
const crcTable = Array.from({ length: 256 }, (_, value) => {
|
|
22
|
+
let crc = value
|
|
23
|
+
for (let bit = 0; bit < 8; bit += 1) crc = (crc & 1) === 1 ? 0xedb88320 ^ (crc >>> 1) : crc >>> 1
|
|
24
|
+
return crc >>> 0
|
|
25
|
+
})
|
|
26
|
+
const crc32 = (data: Uint8Array): number => {
|
|
27
|
+
let crc = 0xffffffff
|
|
28
|
+
for (const byte of data) crc = (crc >>> 8) ^ crcTable[(crc ^ byte) & 0xff]!
|
|
29
|
+
return (crc ^ 0xffffffff) >>> 0
|
|
30
|
+
}
|
|
31
|
+
const zip = (entries: ReadonlyArray<ArchiveEntry>): Uint8Array => {
|
|
32
|
+
const bodies: Uint8Array[] = [], central: Uint8Array[] = []
|
|
33
|
+
let offset = 0
|
|
34
|
+
for (const entry of [...entries].sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0)) {
|
|
35
|
+
const name = text(entry.path), crc = crc32(entry.data)
|
|
36
|
+
const local = concat([integer(4, 0x04034b50), integer(2, 20), integer(2, 0x0800), integer(2, 0), integer(2, 0), integer(2, 0), integer(4, crc), integer(4, entry.data.length), integer(4, entry.data.length), integer(2, name.length), integer(2, 0), name])
|
|
37
|
+
bodies.push(local, entry.data)
|
|
38
|
+
central.push(concat([integer(4, 0x02014b50), integer(2, 0x0314), integer(2, 20), integer(2, 0x0800), integer(2, 0), integer(2, 0), integer(2, 0), integer(4, crc), integer(4, entry.data.length), integer(4, entry.data.length), integer(2, name.length), integer(2, 0), integer(2, 0), integer(2, 0), integer(2, 0), integer(4, entry.mode << 16), integer(4, offset), name]))
|
|
39
|
+
offset += local.length + entry.data.length
|
|
40
|
+
}
|
|
41
|
+
const directory = concat(central)
|
|
42
|
+
return concat([...bodies, directory, integer(4, 0x06054b50), integer(2, 0), integer(2, 0), integer(2, entries.length), integer(2, entries.length), integer(4, directory.length), integer(4, offset), integer(2, 0)])
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "../../..")
|
|
46
|
+
const app = join(root, "apps", "ts-release-agents")
|
|
47
|
+
const output = join(root, ".release", "agents")
|
|
48
|
+
const version = (): string => {
|
|
49
|
+
const value = JSON.parse(readFileSync(join(root, "package.json"), "utf8")) as { version?: unknown }
|
|
50
|
+
if (typeof value.version !== "string" || value.version.length === 0) throw new Error("Root package version is missing.")
|
|
51
|
+
return value.version
|
|
52
|
+
}
|
|
53
|
+
const write = (path: string, contents: string | Uint8Array): void => {
|
|
54
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o755 })
|
|
55
|
+
writeFileSync(path, contents, { mode: 0o644 })
|
|
56
|
+
}
|
|
57
|
+
const copyTree = (source: string, target: string, entries: ReadonlyArray<string>): void => {
|
|
58
|
+
for (const entry of entries) write(join(target, entry), readFileSync(join(source, entry)))
|
|
59
|
+
}
|
|
60
|
+
const filesUnder = (directory: string): string[] => readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
|
|
61
|
+
const path = join(directory, entry.name)
|
|
62
|
+
return entry.isDirectory() ? filesUnder(path).map((child) => join(entry.name, child)) : [entry.name]
|
|
63
|
+
})
|
|
64
|
+
const generatedManifest = (provider: "codex" | "claude", packageVersion: string): Record<string, unknown> => {
|
|
65
|
+
const authored = JSON.parse(readFileSync(join(app, "manifests", `${provider}.json`), "utf8")) as Record<string, unknown>
|
|
66
|
+
return provider === "codex"
|
|
67
|
+
? { ...authored, version: packageVersion }
|
|
68
|
+
: { ...authored, version: packageVersion, author: { name: "mannyc2", url: "https://github.com/mannyc2/ts-release" }, repository: "https://github.com/mannyc2/ts-release" }
|
|
69
|
+
}
|
|
70
|
+
const packageFiles = (provider: "codex" | "claude", packageRoot: string, packageVersion: string): void => {
|
|
71
|
+
const native = provider === "codex" ? ".codex-plugin" : ".claude-plugin"
|
|
72
|
+
write(join(packageRoot, native, "plugin.json"), `${JSON.stringify(generatedManifest(provider, packageVersion), null, 2)}\n`)
|
|
73
|
+
write(join(packageRoot, "README.md"), readFileSync(join(app, "README.md")))
|
|
74
|
+
write(join(packageRoot, "LICENSE"), readFileSync(join(app, "LICENSE")))
|
|
75
|
+
write(join(packageRoot, "evals", "cases.json"), readFileSync(join(app, "evals", "cases.json")))
|
|
76
|
+
copyTree(join(app, "skills"), join(packageRoot, "skills"), filesUnder(join(app, "skills")))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface BuildAgentsOptions {
|
|
80
|
+
/** Release preparation captures archives only; standalone checks retain installable layouts. */
|
|
81
|
+
readonly archivesOnly?: true
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const buildAgents = (options: BuildAgentsOptions = {}): ReadonlyArray<string> => {
|
|
85
|
+
const packageVersion = version()
|
|
86
|
+
rmSync(output, { recursive: true, force: true })
|
|
87
|
+
const created: string[] = []
|
|
88
|
+
for (const provider of ["codex", "claude"] as const) {
|
|
89
|
+
const packageRoot = join(output, provider, "ts-release")
|
|
90
|
+
packageFiles(provider, packageRoot, packageVersion)
|
|
91
|
+
const entries = filesUnder(packageRoot).map((path): ArchiveEntry => ({
|
|
92
|
+
path: join("ts-release", path).replaceAll("\\", "/"), data: new Uint8Array(readFileSync(join(packageRoot, path))), mode: 0o100644
|
|
93
|
+
}))
|
|
94
|
+
const archive = join(output, "archives", `ts-release-${provider}.zip`)
|
|
95
|
+
write(archive, zip(entries))
|
|
96
|
+
created.push(archive)
|
|
97
|
+
if (options.archivesOnly === true) rmSync(join(output, provider), { recursive: true, force: true })
|
|
98
|
+
}
|
|
99
|
+
return created
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (import.meta.main) {
|
|
103
|
+
const archivesOnly = process.argv.slice(2).includes("--archives-only")
|
|
104
|
+
for (const path of buildAgents(archivesOnly ? { archivesOnly: true } : {})) console.log(path.slice(root.length + 1))
|
|
105
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync } from "node:fs"
|
|
2
|
+
import { dirname, join, relative, resolve } from "node:path"
|
|
3
|
+
import { tmpdir } from "node:os"
|
|
4
|
+
import { fileURLToPath } from "node:url"
|
|
5
|
+
import { spawnSync } from "node:child_process"
|
|
6
|
+
import { buildAgents } from "./build.js"
|
|
7
|
+
import { installAgentArchive } from "./install.js"
|
|
8
|
+
|
|
9
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "../../..")
|
|
10
|
+
const output = join(root, ".release", "agents")
|
|
11
|
+
const app = join(root, "apps", "ts-release-agents")
|
|
12
|
+
const fail = (reason: string): never => { throw new Error(reason) }
|
|
13
|
+
const bytes = (path: string): Uint8Array => new Uint8Array(readFileSync(path))
|
|
14
|
+
const same = (left: Uint8Array, right: Uint8Array): boolean => left.length === right.length && left.every((byte, index) => byte === right[index])
|
|
15
|
+
const json = (path: string): Record<string, unknown> => {
|
|
16
|
+
const value: unknown = JSON.parse(readFileSync(path, "utf8"))
|
|
17
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) fail(`${path} must be an object.`)
|
|
18
|
+
return value as Record<string, unknown>
|
|
19
|
+
}
|
|
20
|
+
const rootVersion = String((json(join(root, "package.json")).version ?? ""))
|
|
21
|
+
const generatedFiles = (directory: string): string[] => readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
|
|
22
|
+
const path = join(directory, entry.name)
|
|
23
|
+
return entry.isDirectory() ? generatedFiles(path) : [path]
|
|
24
|
+
})
|
|
25
|
+
const containsFiles = (directory: string): boolean => readdirSync(directory, { withFileTypes: true }).some((entry) => {
|
|
26
|
+
return entry.isDirectory() ? containsFiles(join(directory, entry.name)) : true
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const firstPaths = buildAgents()
|
|
30
|
+
const first = firstPaths.map((path) => bytes(path))
|
|
31
|
+
const secondPaths = buildAgents()
|
|
32
|
+
const second = secondPaths.map((path) => bytes(path))
|
|
33
|
+
if (first.length !== second.length || first.some((value, index) => !same(value, second[index]!))) fail("Agent archives are not deterministic.")
|
|
34
|
+
for (const provider of ["codex", "claude"] as const) {
|
|
35
|
+
const packageRoot = join(output, provider, "ts-release")
|
|
36
|
+
const manifestPath = join(packageRoot, provider === "codex" ? ".codex-plugin" : ".claude-plugin", "plugin.json")
|
|
37
|
+
if (!existsSync(manifestPath)) fail(`Generated ${provider} manifest is missing.`)
|
|
38
|
+
if (json(manifestPath).version !== rootVersion) fail(`Generated ${provider} manifest version diverges from the root package.`)
|
|
39
|
+
if (!existsSync(join(packageRoot, "skills", "release", "SKILL.md"))) fail(`Generated ${provider} skill is missing.`)
|
|
40
|
+
}
|
|
41
|
+
const codex = json(join(output, "codex", "ts-release", ".codex-plugin", "plugin.json"))
|
|
42
|
+
if (codex.skills !== "./skills/") fail("Codex manifest must point to ./skills/.")
|
|
43
|
+
const evals = json(join(app, "evals", "cases.json"))
|
|
44
|
+
if (!Array.isArray(evals.cases) || evals.cases.length < 6) fail("Agent eval coverage is incomplete.")
|
|
45
|
+
for (const path of generatedFiles(join(output, "codex", "ts-release"))) {
|
|
46
|
+
const text = readFileSync(path, "utf8")
|
|
47
|
+
if (/npm_[A-Z0-9_]{6,}/u.test(text)) fail(`Generated agent content resembles a raw secret: ${path}`)
|
|
48
|
+
if (text.includes("../")) fail(`Generated agent content contains parent traversal: ${path}`)
|
|
49
|
+
}
|
|
50
|
+
for (const forbidden of [".agents", ".claude-plugin", ".codex-plugin", "ts-release-plugin"]) {
|
|
51
|
+
if (existsSync(join(root, forbidden)) && containsFiles(join(root, forbidden))) fail(`Obsolete root agent owner remains: ${forbidden}`)
|
|
52
|
+
}
|
|
53
|
+
for (const path of ["SKILL.md", join("skills", "release", "SKILL.md")]) {
|
|
54
|
+
if (existsSync(join(root, path))) fail(`Root canonical agent owner remains: ${path}`)
|
|
55
|
+
}
|
|
56
|
+
const tracked = spawnSync("git", ["ls-files", "-z"], { cwd: root, encoding: "utf8", stdio: "pipe" })
|
|
57
|
+
if (tracked.status !== 0) fail(`Could not inspect tracked agent owners: ${tracked.stderr.trim() || tracked.stdout.trim()}`)
|
|
58
|
+
const trackedFiles = tracked.stdout.split("\0").filter((path) => path.length > 0)
|
|
59
|
+
const canonicalRootOwners = trackedFiles.filter((path) =>
|
|
60
|
+
path === ".codex-plugin/plugin.json" ||
|
|
61
|
+
path === ".claude-plugin/plugin.json" ||
|
|
62
|
+
path === "skills/release/SKILL.md" ||
|
|
63
|
+
path === "SKILL.md" ||
|
|
64
|
+
path.startsWith("ts-release-plugin/"))
|
|
65
|
+
if (canonicalRootOwners.length !== 0) fail(`Tracked root canonical agent owners remain: ${canonicalRootOwners.join(", ")}`)
|
|
66
|
+
const skillOwners = trackedFiles.filter((path) => path.endsWith("/skills/release/SKILL.md"))
|
|
67
|
+
if (skillOwners.length !== 1 || skillOwners[0] !== "apps/ts-release-agents/skills/release/SKILL.md") {
|
|
68
|
+
fail(`Agent skill source ownership diverged: ${skillOwners.join(", ") || "none"}`)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const disposableRoot = mkdtempSync(join(tmpdir(), "ts-release-agent-installs-"))
|
|
72
|
+
let installed = 0
|
|
73
|
+
const providerLayouts: string[] = []
|
|
74
|
+
try {
|
|
75
|
+
for (const provider of ["codex", "claude"] as const) {
|
|
76
|
+
const archive = secondPaths.find((path) => path.endsWith(`ts-release-${provider}.zip`)) ??
|
|
77
|
+
fail(`Generated ${provider} archive is missing.`)
|
|
78
|
+
const installation = installAgentArchive(provider, archive, disposableRoot)
|
|
79
|
+
const native = provider === "codex" ? ".codex-plugin" : ".claude-plugin"
|
|
80
|
+
const manifest = join(installation.packageRoot, native, "plugin.json")
|
|
81
|
+
if (!existsSync(manifest)) fail(`Installed ${provider} native manifest is missing.`)
|
|
82
|
+
if (!existsSync(join(installation.packageRoot, "skills", "release", "SKILL.md"))) {
|
|
83
|
+
fail(`Installed ${provider} skill is missing.`)
|
|
84
|
+
}
|
|
85
|
+
if (provider === "codex" && json(manifest).skills !== "./skills/") {
|
|
86
|
+
fail("Installed Codex manifest must point to ./skills/.")
|
|
87
|
+
}
|
|
88
|
+
if (provider === "claude") {
|
|
89
|
+
const validated = spawnSync("claude", ["plugin", "validate", "--strict", installation.packageRoot], {
|
|
90
|
+
encoding: "utf8",
|
|
91
|
+
env: {
|
|
92
|
+
...process.env,
|
|
93
|
+
CLAUDE_CONFIG_DIR: join(disposableRoot, ".claude")
|
|
94
|
+
},
|
|
95
|
+
stdio: "pipe"
|
|
96
|
+
})
|
|
97
|
+
if (validated.status !== 0) {
|
|
98
|
+
fail(`Installed Claude plugin validator failed: ${validated.stderr.trim() || validated.stdout.trim()}`)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
providerLayouts.push(relative(disposableRoot, installation.packageRoot).replaceAll("\\", "/"))
|
|
102
|
+
installed += 1
|
|
103
|
+
}
|
|
104
|
+
} finally {
|
|
105
|
+
rmSync(disposableRoot, { recursive: true, force: true })
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log(JSON.stringify({
|
|
109
|
+
schemaVersion: "ts-release-agents-check/v2",
|
|
110
|
+
providers: 2,
|
|
111
|
+
archives: second.length,
|
|
112
|
+
disposableInstalls: installed,
|
|
113
|
+
providerLayouts,
|
|
114
|
+
claudeValidation: "strict",
|
|
115
|
+
rootCanonicalOwners: canonicalRootOwners.length,
|
|
116
|
+
status: "ready"
|
|
117
|
+
}))
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
lstatSync,
|
|
4
|
+
mkdirSync,
|
|
5
|
+
mkdtempSync,
|
|
6
|
+
readFileSync,
|
|
7
|
+
readdirSync,
|
|
8
|
+
realpathSync,
|
|
9
|
+
renameSync,
|
|
10
|
+
rmSync
|
|
11
|
+
} from "node:fs"
|
|
12
|
+
import { join, sep } from "node:path"
|
|
13
|
+
import { spawnSync } from "node:child_process"
|
|
14
|
+
|
|
15
|
+
export type AgentProvider = "codex" | "claude"
|
|
16
|
+
|
|
17
|
+
export interface InstalledAgentArchive {
|
|
18
|
+
readonly provider: AgentProvider
|
|
19
|
+
/** Disposable stand-in for the user's home directory. */
|
|
20
|
+
readonly userRoot: string
|
|
21
|
+
/** Provider-native cache owner below the disposable user root. */
|
|
22
|
+
readonly providerRoot: string
|
|
23
|
+
readonly packageRoot: string
|
|
24
|
+
readonly version: string
|
|
25
|
+
readonly entries: ReadonlyArray<string>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const fail = (reason: string): never => { throw new Error(reason) }
|
|
29
|
+
|
|
30
|
+
const archiveEntries = (archive: string): ReadonlyArray<string> => {
|
|
31
|
+
const listed = spawnSync("unzip", ["-Z1", archive], { encoding: "utf8", stdio: "pipe" })
|
|
32
|
+
if (listed.status !== 0) {
|
|
33
|
+
fail(`Could not inspect agent archive ${archive}: ${listed.stderr.trim() || listed.stdout.trim()}`)
|
|
34
|
+
}
|
|
35
|
+
const entries = listed.stdout.split("\n").filter((entry) => entry.length > 0)
|
|
36
|
+
if (entries.length === 0) fail(`Agent archive ${archive} is empty.`)
|
|
37
|
+
if (new Set(entries).size !== entries.length) fail(`Agent archive ${archive} contains duplicate paths.`)
|
|
38
|
+
for (const entry of entries) {
|
|
39
|
+
const segments = entry.split("/")
|
|
40
|
+
if (
|
|
41
|
+
!entry.startsWith("ts-release/") ||
|
|
42
|
+
entry.startsWith("/") ||
|
|
43
|
+
entry.includes("\\") ||
|
|
44
|
+
entry.includes("\0") ||
|
|
45
|
+
segments.some((segment) => segment === "" || segment === "." || segment === "..")
|
|
46
|
+
) fail(`Agent archive ${archive} contains unsafe path ${JSON.stringify(entry)}.`)
|
|
47
|
+
}
|
|
48
|
+
return entries
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const verifyContainedTree = (directory: string): void => {
|
|
52
|
+
const root = realpathSync(directory)
|
|
53
|
+
const prefix = `${root}${sep}`
|
|
54
|
+
const visit = (current: string): void => {
|
|
55
|
+
for (const entry of readdirSync(current)) {
|
|
56
|
+
const path = join(current, entry)
|
|
57
|
+
const status = lstatSync(path)
|
|
58
|
+
if (status.isSymbolicLink()) fail(`Installed agent package contains a symlink: ${path}`)
|
|
59
|
+
if (!status.isDirectory() && !status.isFile()) fail(`Installed agent package contains a special file: ${path}`)
|
|
60
|
+
const canonical = realpathSync(path)
|
|
61
|
+
if (canonical !== root && !canonical.startsWith(prefix)) fail(`Installed agent path escapes its package: ${path}`)
|
|
62
|
+
if (status.isDirectory()) visit(path)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
visit(directory)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Installs one generated archive into a disposable provider-owned plugin
|
|
70
|
+
* directory. This performs local ZIP inspection and extraction only.
|
|
71
|
+
*/
|
|
72
|
+
export const installAgentArchive = (
|
|
73
|
+
provider: AgentProvider,
|
|
74
|
+
archive: string,
|
|
75
|
+
userRoot: string
|
|
76
|
+
): InstalledAgentArchive => {
|
|
77
|
+
const entries = archiveEntries(archive)
|
|
78
|
+
mkdirSync(userRoot, { recursive: true, mode: 0o700 })
|
|
79
|
+
const stage = mkdtempSync(join(userRoot, `.ts-release-${provider}-stage-`))
|
|
80
|
+
try {
|
|
81
|
+
const extracted = spawnSync("unzip", ["-qq", archive, "-d", stage], {
|
|
82
|
+
encoding: "utf8",
|
|
83
|
+
stdio: "pipe"
|
|
84
|
+
})
|
|
85
|
+
if (extracted.status !== 0) {
|
|
86
|
+
fail(`Could not install ${provider} agent archive: ${extracted.stderr.trim() || extracted.stdout.trim()}`)
|
|
87
|
+
}
|
|
88
|
+
const stagedPackage = join(stage, "ts-release")
|
|
89
|
+
if (!existsSync(stagedPackage) || !lstatSync(stagedPackage).isDirectory()) {
|
|
90
|
+
fail(`Installed ${provider} package root is missing.`)
|
|
91
|
+
}
|
|
92
|
+
verifyContainedTree(stagedPackage)
|
|
93
|
+
const native = provider === "codex" ? ".codex-plugin" : ".claude-plugin"
|
|
94
|
+
const manifestPath = join(stagedPackage, native, "plugin.json")
|
|
95
|
+
if (!existsSync(manifestPath)) fail(`Installed ${provider} native manifest is missing.`)
|
|
96
|
+
const manifest: unknown = JSON.parse(readFileSync(manifestPath, "utf8"))
|
|
97
|
+
const version = typeof manifest === "object" && manifest !== null &&
|
|
98
|
+
"version" in manifest && typeof manifest.version === "string"
|
|
99
|
+
? manifest.version
|
|
100
|
+
: fail(`Installed ${provider} native manifest version is missing.`)
|
|
101
|
+
if (!/^[0-9A-Za-z][0-9A-Za-z._+-]*$/u.test(version)) {
|
|
102
|
+
fail(`Installed ${provider} native manifest version is not a safe cache key.`)
|
|
103
|
+
}
|
|
104
|
+
const providerRoot = join(
|
|
105
|
+
userRoot,
|
|
106
|
+
provider === "codex" ? ".codex" : ".claude",
|
|
107
|
+
"plugins",
|
|
108
|
+
"cache",
|
|
109
|
+
"local-archive",
|
|
110
|
+
"ts-release"
|
|
111
|
+
)
|
|
112
|
+
const packageRoot = join(providerRoot, version)
|
|
113
|
+
if (existsSync(packageRoot)) fail(`Disposable ${provider} package root already exists: ${packageRoot}`)
|
|
114
|
+
mkdirSync(providerRoot, { recursive: true, mode: 0o700 })
|
|
115
|
+
renameSync(stagedPackage, packageRoot)
|
|
116
|
+
verifyContainedTree(packageRoot)
|
|
117
|
+
return { provider, userRoot, providerRoot, packageRoot, version, entries }
|
|
118
|
+
} finally {
|
|
119
|
+
rmSync(stage, { recursive: true, force: true })
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test"
|
|
2
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs"
|
|
3
|
+
import { join } from "node:path"
|
|
4
|
+
import { tmpdir } from "node:os"
|
|
5
|
+
import { buildAgents } from "../src/build.js"
|
|
6
|
+
import { installAgentArchive } from "../src/install.js"
|
|
7
|
+
|
|
8
|
+
const root = process.cwd()
|
|
9
|
+
const equal = (left: Uint8Array, right: Uint8Array): boolean => left.length === right.length && left.every((byte, index) => byte === right[index])
|
|
10
|
+
|
|
11
|
+
describe("agent distribution contract", () => {
|
|
12
|
+
test("two identical projections are byte-identical", () => {
|
|
13
|
+
const first = buildAgents().map((path) => new Uint8Array(readFileSync(path)))
|
|
14
|
+
const second = buildAgents().map((path) => new Uint8Array(readFileSync(path)))
|
|
15
|
+
expect(first.length).toBe(2)
|
|
16
|
+
expect(first.every((value, index) => equal(value, second[index]!))).toBe(true)
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
test("provider-native generated layouts are contained and versioned", () => {
|
|
20
|
+
for (const provider of ["codex", "claude"]) {
|
|
21
|
+
const native = provider === "codex" ? ".codex-plugin" : ".claude-plugin"
|
|
22
|
+
const manifest = join(root, ".release", "agents", provider, "ts-release", native, "plugin.json")
|
|
23
|
+
expect(existsSync(manifest)).toBe(true)
|
|
24
|
+
expect(JSON.parse(readFileSync(manifest, "utf8")).version).toBe("0.2.2")
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test("archives install into disposable provider-owned layouts", () => {
|
|
29
|
+
const archives = buildAgents({ archivesOnly: true })
|
|
30
|
+
expect(existsSync(join(root, ".release", "agents", "codex"))).toBe(false)
|
|
31
|
+
expect(existsSync(join(root, ".release", "agents", "claude"))).toBe(false)
|
|
32
|
+
const disposableRoot = mkdtempSync(join(tmpdir(), "ts-release-agent-contract-"))
|
|
33
|
+
try {
|
|
34
|
+
for (const provider of ["codex", "claude"] as const) {
|
|
35
|
+
const archive = archives.find((path) => path.endsWith(`ts-release-${provider}.zip`))
|
|
36
|
+
expect(archive).toBeDefined()
|
|
37
|
+
const installed = installAgentArchive(provider, archive!, disposableRoot)
|
|
38
|
+
expect(installed.providerRoot).toBe(join(
|
|
39
|
+
disposableRoot,
|
|
40
|
+
provider === "codex" ? ".codex" : ".claude",
|
|
41
|
+
"plugins",
|
|
42
|
+
"cache",
|
|
43
|
+
"local-archive",
|
|
44
|
+
"ts-release"
|
|
45
|
+
))
|
|
46
|
+
expect(installed.version).toBe("0.2.2")
|
|
47
|
+
expect(installed.packageRoot).toBe(join(installed.providerRoot, installed.version))
|
|
48
|
+
expect(existsSync(join(installed.packageRoot, provider === "codex" ? ".codex-plugin" : ".claude-plugin", "plugin.json"))).toBe(true)
|
|
49
|
+
expect(existsSync(join(installed.packageRoot, "skills", "release", "SKILL.md"))).toBe(true)
|
|
50
|
+
expect(installed.entries.every((entry) => entry.startsWith("ts-release/"))).toBe(true)
|
|
51
|
+
}
|
|
52
|
+
} finally {
|
|
53
|
+
rmSync(disposableRoot, { recursive: true, force: true })
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CompletePreparedReleaseRef } from "../release/prepared-ref.js";
|
|
2
|
+
import { CorrectionReport, type CorrectInput, type InspectInput, type ObserveInput, type PrepareInput, type PublishInput, type ReleaseApi, type ReleaseApiLayer, type ReleaseApiOptions, type ReleaseInput } from "./types.js";
|
|
3
|
+
export type { CorrectInput, InspectInput, ObserveInput, PrepareInput, PublishInput, ReleaseApi, ReleaseApiLayer, ReleaseApiOptions, ReleaseInput } from "./types.js";
|
|
4
|
+
export { CorrectionReport } from "./types.js";
|
|
5
|
+
export { ReleaseInputError } from "./errors.js";
|
|
6
|
+
export { ReleaseRuntime } from "./runtime.js";
|
|
7
|
+
export declare const makeReleaseApi: (layer: ReleaseApiLayer, options?: ReleaseApiOptions) => ReleaseApi;
|
|
8
|
+
export declare const makeDefaultReleaseApi: (layer: ReleaseApiLayer) => ReleaseApi;
|
|
9
|
+
export declare const inspect: (input: InspectInput) => Promise<import("./types.js").InspectOutput>;
|
|
10
|
+
export declare const prepare: (input: PrepareInput) => Promise<CompletePreparedReleaseRef>;
|
|
11
|
+
export declare const observe: (input: ObserveInput) => Promise<import("../publication/report.js").ObservationReport>;
|
|
12
|
+
export declare const publish: (input: PublishInput) => Promise<import("../publication/report.js").ReleaseReport>;
|
|
13
|
+
export declare const release: (input: ReleaseInput) => Promise<import("./types.js").ReleaseResult>;
|
|
14
|
+
export declare const correct: (input: CorrectInput) => Promise<CorrectionReport>;
|
|
15
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api/api.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAA;AAsB5E,OAAO,EACL,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAEtB,KAAK,YAAY,EAClB,MAAM,YAAY,CAAA;AAEnB,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAmO7C,eAAO,MAAM,cAAc,GAAI,OAAO,eAAe,EAAE,UAAS,iBAAsB,KAAG,UAwDxF,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,OAAO,eAAe,KAAG,UACxC,CAAA;AAIvB,eAAO,MAAM,OAAO,sEAAqB,CAAA;AACzC,eAAO,MAAM,OAAO,8DAAqB,CAAA;AACzC,eAAO,MAAM,OAAO,wFAAqB,CAAA;AACzC,eAAO,MAAM,OAAO,oFAAqB,CAAA;AACzC,eAAO,MAAM,OAAO,sEAAqB,CAAA;AACzC,eAAO,MAAM,OAAO,oDAAqB,CAAA"}
|