@treeseed/sdk 0.11.0 → 0.12.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -4
- package/dist/agent-capacity.d.ts +916 -0
- package/dist/agent-capacity.js +1600 -0
- package/dist/agent-tools.d.ts +37 -0
- package/dist/agent-tools.js +301 -0
- package/dist/api/app.d.ts +1 -1
- package/dist/api/auth/d1-database.d.ts +2 -2
- package/dist/api/auth/d1-provider.d.ts +4 -4
- package/dist/api/auth/d1-store.d.ts +2 -2
- package/dist/api/auth/memory-provider.d.ts +1 -1
- package/dist/api/auth/tokens.d.ts +1 -1
- package/dist/api/config.d.ts +3 -1
- package/dist/api/config.js +34 -10
- package/dist/api/http.d.ts +2 -2
- package/dist/api/index.d.ts +10 -10
- package/dist/api/index.js +4 -2
- package/dist/api/operations-routes.d.ts +3 -3
- package/dist/api/operations.d.ts +1 -1
- package/dist/api/providers.d.ts +1 -1
- package/dist/api/providers.js +21 -4
- package/dist/api/railway.d.ts +3 -2
- package/dist/api/sdk-dispatch.d.ts +4 -4
- package/dist/api/sdk-routes.d.ts +2 -2
- package/dist/api/templates.d.ts +2 -2
- package/dist/api/types.d.ts +3 -2
- package/dist/capacity-provider.d.ts +117 -60
- package/dist/capacity-provider.js +215 -43
- package/dist/capacity.d.ts +2 -2
- package/dist/cli-tools.d.ts +1 -1
- package/dist/content-operations.d.ts +97 -0
- package/dist/content-operations.js +250 -0
- package/dist/content-store.d.ts +4 -4
- package/dist/control-plane-client.d.ts +13 -18
- package/dist/control-plane-client.js +8 -86
- package/dist/control-plane.d.ts +2 -2
- package/dist/copilot.d.ts +3 -0
- package/dist/copilot.js +16 -1
- package/dist/d1-http.d.ts +1 -1
- package/dist/d1-store.d.ts +32 -57
- package/dist/d1-store.js +115 -318
- package/dist/db/d1.d.ts +1 -232
- package/dist/db/index.d.ts +3 -3
- package/dist/db/market-schema.d.ts +49037 -11843
- package/dist/db/market-schema.js +1788 -50
- package/dist/db/node-sqlite.d.ts +1 -232
- package/dist/db/schema.d.ts +0 -462
- package/dist/db/schema.js +2 -22
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +0 -11
- package/dist/fixture-support.js +52 -4
- package/dist/governance.d.ts +133 -0
- package/dist/governance.js +285 -0
- package/dist/graph/build.d.ts +2 -2
- package/dist/graph/context-query-contracts.d.ts +1 -1
- package/dist/graph/dsl.d.ts +1 -1
- package/dist/graph/query.d.ts +4 -4
- package/dist/graph/ranking.d.ts +1 -1
- package/dist/graph/schema.d.ts +1 -1
- package/dist/graph.d.ts +11 -11
- package/dist/guarantees/index.d.ts +425 -0
- package/dist/guarantees/index.js +1146 -0
- package/dist/hosting/apps.d.ts +1 -1
- package/dist/hosting/builtins.d.ts +1 -1
- package/dist/hosting/builtins.js +9 -198
- package/dist/hosting/contracts.d.ts +3 -2
- package/dist/hosting/graph.d.ts +24 -21
- package/dist/hosting/graph.js +280 -294
- package/dist/hosting/index.d.ts +4 -4
- package/dist/index.d.ts +88 -74
- package/dist/index.js +81 -10
- package/dist/local-dev/managed-dev.d.ts +85 -0
- package/dist/local-dev/managed-dev.js +368 -0
- package/dist/managed-dependencies.d.ts +9 -0
- package/dist/managed-dependencies.js +10 -8
- package/dist/market-client.d.ts +265 -7
- package/dist/market-client.js +381 -9
- package/dist/model-registry.d.ts +1 -1
- package/dist/model-registry.js +19 -19
- package/dist/operations/agent-tools.d.ts +2 -11
- package/dist/operations/agent-tools.js +2 -14
- package/dist/operations/providers/default.d.ts +1 -1
- package/dist/operations/providers/default.js +20 -37
- package/dist/operations/repository-operations.d.ts +26 -2
- package/dist/operations/repository-operations.js +159 -1
- package/dist/operations/runtime.d.ts +3 -3
- package/dist/operations/services/bootstrap-runner.d.ts +1 -1
- package/dist/operations/services/build-warning-policy.d.ts +34 -0
- package/dist/operations/services/build-warning-policy.js +81 -82
- package/dist/operations/services/commit-message-provider.js +4 -4
- package/dist/operations/services/config-runtime.d.ts +73 -19
- package/dist/operations/services/config-runtime.js +276 -100
- package/dist/operations/services/deploy.d.ts +41 -622
- package/dist/operations/services/deploy.js +181 -213
- package/dist/operations/services/deployment-readiness.d.ts +1 -1
- package/dist/operations/services/deployment-readiness.js +38 -7
- package/dist/operations/services/git-remote-policy.js +12 -4
- package/dist/operations/services/git-runner.d.ts +66 -0
- package/dist/operations/services/git-runner.js +479 -0
- package/dist/operations/services/git-workflow.d.ts +43 -5
- package/dist/operations/services/git-workflow.js +242 -20
- package/dist/operations/services/github-actions-verification.d.ts +3 -1
- package/dist/operations/services/github-actions-verification.js +11 -3
- package/dist/operations/services/github-api.js +21 -5
- package/dist/operations/services/github-automation.d.ts +3 -3
- package/dist/operations/services/github-automation.js +15 -18
- package/dist/operations/services/github-credentials.js +2 -1
- package/dist/operations/services/hosted-service-checks.d.ts +19 -1
- package/dist/operations/services/hosted-service-checks.js +162 -11
- package/dist/operations/services/hosting-audit.d.ts +2 -2
- package/dist/operations/services/hosting-audit.js +7 -7
- package/dist/operations/services/hub-launch.d.ts +1 -1
- package/dist/operations/services/hub-provider-launch.d.ts +5 -5
- package/dist/operations/services/hub-provider-launch.js +19 -14
- package/dist/operations/services/live-hosted-service-checks.d.ts +2 -1
- package/dist/operations/services/live-hosted-service-checks.js +193 -80
- package/dist/operations/services/local-dev.js +0 -1
- package/dist/operations/services/managed-host-security.d.ts +1 -1
- package/dist/operations/services/managed-repositories.d.ts +37 -0
- package/dist/operations/services/managed-repositories.js +177 -0
- package/dist/operations/services/operations-runner-smoke.d.ts +3 -2
- package/dist/operations/services/operations-runner-smoke.js +22 -4
- package/dist/operations/services/package-adapters.d.ts +77 -2
- package/dist/operations/services/package-adapters.js +629 -56
- package/dist/operations/services/package-reference-policy.d.ts +12 -88
- package/dist/operations/services/package-reference-policy.js +81 -213
- package/dist/operations/services/project-host-operations.d.ts +4 -4
- package/dist/operations/services/project-platform.d.ts +19 -193
- package/dist/operations/services/project-platform.js +31 -103
- package/dist/operations/services/project-web-monitor.d.ts +2 -2
- package/dist/operations/services/project-web-monitor.js +97 -2
- package/dist/operations/services/railway-api.d.ts +36 -7
- package/dist/operations/services/railway-api.js +331 -100
- package/dist/operations/services/railway-deploy.d.ts +7 -95
- package/dist/operations/services/railway-deploy.js +334 -742
- package/dist/operations/services/release-history.js +3 -4
- package/dist/operations/services/release-proof-ledger.d.ts +13 -0
- package/dist/operations/services/release-proof-ledger.js +81 -0
- package/dist/operations/services/release-proof-planner.d.ts +48 -0
- package/dist/operations/services/release-proof-planner.js +195 -0
- package/dist/operations/services/release-proof-runner.d.ts +16 -0
- package/dist/operations/services/release-proof-runner.js +169 -0
- package/dist/operations/services/release-proof.d.ts +81 -0
- package/dist/operations/services/release-proof.js +79 -0
- package/dist/operations/services/repository-save-orchestrator.d.ts +6 -7
- package/dist/operations/services/repository-save-orchestrator.js +353 -174
- package/dist/operations/services/runtime-paths.d.ts +1 -3
- package/dist/operations/services/runtime-paths.js +0 -4
- package/dist/operations/services/runtime-tools.d.ts +1 -192
- package/dist/operations/services/runtime-tools.js +4 -444
- package/dist/operations/services/save-deploy-preflight.js +9 -1
- package/dist/operations/services/template-host-bindings.d.ts +2 -2
- package/dist/operations/services/template-host-bindings.js +3 -2
- package/dist/operations/services/template-registry.d.ts +6 -6
- package/dist/operations/services/template-registry.js +33 -14
- package/dist/operations/services/template-secret-sync.d.ts +3 -3
- package/dist/operations/services/workflow-timing.d.ts +25 -0
- package/dist/operations/services/workflow-timing.js +79 -0
- package/dist/operations/services/workspace-dependency-mode.js +41 -4
- package/dist/operations/services/workspace-preflight.js +8 -8
- package/dist/operations/services/workspace-save-script.d.ts +4 -4
- package/dist/operations/services/workspace-save.d.ts +1 -0
- package/dist/operations/services/workspace-save.js +41 -18
- package/dist/operations/services/workspace-tools.js +40 -6
- package/dist/operations-registry.d.ts +1 -1
- package/dist/operations-registry.js +5 -6
- package/dist/operations-types.d.ts +1 -1
- package/dist/operations.d.ts +17 -11
- package/dist/operations.js +57 -3
- package/dist/platform/book-export.js +2 -0
- package/dist/platform/books-data.d.ts +1 -1
- package/dist/platform/config.d.ts +27 -0
- package/dist/platform/config.js +100 -0
- package/dist/platform/content-runtime-source.d.ts +54 -0
- package/dist/platform/content-runtime-source.js +169 -0
- package/dist/platform/contracts.d.ts +6 -1
- package/dist/platform/deploy-config.d.ts +1 -1
- package/dist/platform/deploy-config.js +7 -1
- package/dist/platform/deploy-runtime.d.ts +1 -1
- package/dist/platform/desired-state.d.ts +66 -0
- package/dist/platform/desired-state.js +1052 -0
- package/dist/platform/env.yaml +414 -19
- package/dist/platform/environment.d.ts +2 -2
- package/dist/platform/environment.js +54 -22
- package/dist/platform/local-content-materialization.d.ts +9 -0
- package/dist/platform/local-content-materialization.js +212 -0
- package/dist/platform/plugin.d.ts +5 -5
- package/dist/platform/plugins/runtime.d.ts +3 -3
- package/dist/platform/plugins/runtime.js +62 -1
- package/dist/platform/plugins.d.ts +6 -6
- package/dist/platform/published-content-pipeline.d.ts +3 -3
- package/dist/platform/published-content-pipeline.js +5 -1
- package/dist/platform/published-content.d.ts +4 -3
- package/dist/platform/site-config-schema.d.ts +1 -0
- package/dist/platform/site-config-schema.js +4 -1
- package/dist/platform/tenant/runtime-config.d.ts +152 -2
- package/dist/platform/tenant-config.d.ts +1 -1
- package/dist/platform/utils/site-config-schema.d.ts +154 -0
- package/dist/platform/utils/site-config-schema.js +400 -461
- package/dist/platform-operation-store.d.ts +1 -1
- package/dist/plugin-default.d.ts +1 -1
- package/dist/plugin-default.js +27 -12
- package/dist/project-import.d.ts +91 -0
- package/dist/project-import.js +257 -0
- package/dist/project-workflow.d.ts +1 -1
- package/dist/reconcile/bootstrap-systems.d.ts +2 -2
- package/dist/reconcile/bootstrap-systems.js +3 -3
- package/dist/reconcile/builtin-adapters.d.ts +7 -1
- package/dist/reconcile/builtin-adapters.js +2924 -346
- package/dist/reconcile/contracts.d.ts +15 -2
- package/dist/reconcile/desired-state.d.ts +2 -193
- package/dist/reconcile/desired-state.js +24 -33
- package/dist/reconcile/engine.d.ts +60 -397
- package/dist/reconcile/engine.js +182 -18
- package/dist/reconcile/index.d.ts +10 -10
- package/dist/reconcile/live-acceptance.d.ts +22 -1
- package/dist/reconcile/live-acceptance.js +456 -44
- package/dist/reconcile/providers/docker-private.d.ts +54 -0
- package/dist/reconcile/providers/docker-private.js +101 -0
- package/dist/reconcile/providers/github-private.d.ts +65 -0
- package/dist/reconcile/providers/github-private.js +119 -0
- package/dist/reconcile/providers/local-private.d.ts +28 -0
- package/dist/reconcile/providers/local-private.js +75 -0
- package/dist/reconcile/providers/railway-iac.d.ts +66 -0
- package/dist/reconcile/providers/railway-iac.js +275 -0
- package/dist/reconcile/providers/release-private.d.ts +92 -0
- package/dist/reconcile/providers/release-private.js +152 -0
- package/dist/reconcile/registry.d.ts +2 -2
- package/dist/reconcile/registry.js +16 -1
- package/dist/reconcile/state.d.ts +1 -1
- package/dist/reconcile/state.js +3 -40
- package/dist/reconcile/units.d.ts +1 -1
- package/dist/reconcile/units.js +7 -1
- package/dist/remote.d.ts +6 -6
- package/dist/scenes/artifacts.d.ts +16 -0
- package/dist/scenes/artifacts.js +61 -0
- package/dist/scenes/auth.d.ts +2 -0
- package/dist/scenes/auth.js +28 -0
- package/dist/scenes/base-url.d.ts +12 -0
- package/dist/scenes/base-url.js +123 -0
- package/dist/scenes/builtin-plugins.d.ts +2 -0
- package/dist/scenes/builtin-plugins.js +447 -0
- package/dist/scenes/checkpoints.d.ts +14 -0
- package/dist/scenes/checkpoints.js +33 -0
- package/dist/scenes/device-matrix.d.ts +2 -0
- package/dist/scenes/device-matrix.js +97 -0
- package/dist/scenes/devices.d.ts +11 -0
- package/dist/scenes/devices.js +22 -0
- package/dist/scenes/diagnostics.d.ts +5 -0
- package/dist/scenes/diagnostics.js +22 -0
- package/dist/scenes/diagram-providers.d.ts +2 -0
- package/dist/scenes/diagram-providers.js +181 -0
- package/dist/scenes/diagram-validation.d.ts +22 -0
- package/dist/scenes/diagram-validation.js +74 -0
- package/dist/scenes/environment.d.ts +2 -0
- package/dist/scenes/environment.js +65 -0
- package/dist/scenes/evidence-bundle.d.ts +5 -0
- package/dist/scenes/evidence-bundle.js +42 -0
- package/dist/scenes/evidence-report.d.ts +10 -0
- package/dist/scenes/evidence-report.js +73 -0
- package/dist/scenes/evidence.d.ts +16 -0
- package/dist/scenes/evidence.js +277 -0
- package/dist/scenes/index.d.ts +48 -0
- package/dist/scenes/index.js +312 -0
- package/dist/scenes/inspect.d.ts +9 -0
- package/dist/scenes/inspect.js +64 -0
- package/dist/scenes/loader.d.ts +3 -0
- package/dist/scenes/loader.js +38 -0
- package/dist/scenes/logs.d.ts +2 -0
- package/dist/scenes/logs.js +47 -0
- package/dist/scenes/operations.d.ts +3 -0
- package/dist/scenes/operations.js +128 -0
- package/dist/scenes/phase0.d.ts +9 -0
- package/dist/scenes/phase0.js +637 -0
- package/dist/scenes/planner.d.ts +12 -0
- package/dist/scenes/planner.js +166 -0
- package/dist/scenes/playwright-adapter.d.ts +2 -0
- package/dist/scenes/playwright-adapter.js +63 -0
- package/dist/scenes/plugins.d.ts +5 -0
- package/dist/scenes/plugins.js +115 -0
- package/dist/scenes/progress.d.ts +17 -0
- package/dist/scenes/progress.js +24 -0
- package/dist/scenes/publish-destinations.d.ts +12 -0
- package/dist/scenes/publish-destinations.js +99 -0
- package/dist/scenes/publish-plan-report.d.ts +10 -0
- package/dist/scenes/publish-plan-report.js +70 -0
- package/dist/scenes/publish-plan.d.ts +15 -0
- package/dist/scenes/publish-plan.js +248 -0
- package/dist/scenes/publish-redaction.d.ts +16 -0
- package/dist/scenes/publish-redaction.js +148 -0
- package/dist/scenes/publish-release-record.d.ts +13 -0
- package/dist/scenes/publish-release-record.js +34 -0
- package/dist/scenes/publish-report.d.ts +10 -0
- package/dist/scenes/publish-report.js +67 -0
- package/dist/scenes/publish.d.ts +16 -0
- package/dist/scenes/publish.js +298 -0
- package/dist/scenes/registry.d.ts +12 -0
- package/dist/scenes/registry.js +65 -0
- package/dist/scenes/remotion-adapter.d.ts +3 -0
- package/dist/scenes/remotion-adapter.js +94 -0
- package/dist/scenes/remotion-composition-registry.d.ts +2 -0
- package/dist/scenes/remotion-composition-registry.js +12 -0
- package/dist/scenes/remotion-compositions.d.ts +15 -0
- package/dist/scenes/remotion-compositions.js +464 -0
- package/dist/scenes/remotion-diagrams.d.ts +9 -0
- package/dist/scenes/remotion-diagrams.js +188 -0
- package/dist/scenes/remotion-input.d.ts +13 -0
- package/dist/scenes/remotion-input.js +291 -0
- package/dist/scenes/remotion-visuals.d.ts +29 -0
- package/dist/scenes/remotion-visuals.js +198 -0
- package/dist/scenes/render-media-assets.d.ts +9 -0
- package/dist/scenes/render-media-assets.js +117 -0
- package/dist/scenes/render-report.d.ts +10 -0
- package/dist/scenes/render-report.js +27 -0
- package/dist/scenes/render.d.ts +2 -0
- package/dist/scenes/render.js +218 -0
- package/dist/scenes/reporter.d.ts +3 -0
- package/dist/scenes/reporter.js +101 -0
- package/dist/scenes/resume.d.ts +2 -0
- package/dist/scenes/resume.js +79 -0
- package/dist/scenes/runner.d.ts +2 -0
- package/dist/scenes/runner.js +674 -0
- package/dist/scenes/schema.d.ts +6 -0
- package/dist/scenes/schema.js +994 -0
- package/dist/scenes/seed.d.ts +2 -0
- package/dist/scenes/seed.js +83 -0
- package/dist/scenes/segments.d.ts +15 -0
- package/dist/scenes/segments.js +79 -0
- package/dist/scenes/selectors.d.ts +3 -0
- package/dist/scenes/selectors.js +21 -0
- package/dist/scenes/timeline.d.ts +11 -0
- package/dist/scenes/timeline.js +26 -0
- package/dist/scenes/timeouts.d.ts +6 -0
- package/dist/scenes/timeouts.js +17 -0
- package/dist/scenes/training-captions.d.ts +14 -0
- package/dist/scenes/training-captions.js +98 -0
- package/dist/scenes/training-report.d.ts +10 -0
- package/dist/scenes/training-report.js +78 -0
- package/dist/scenes/training-transcript.d.ts +24 -0
- package/dist/scenes/training-transcript.js +204 -0
- package/dist/scenes/training.d.ts +10 -0
- package/dist/scenes/training.js +134 -0
- package/dist/scenes/types.d.ts +1872 -0
- package/dist/scenes/types.js +8 -0
- package/dist/scenes/visual-audit-contact-sheets.d.ts +6 -0
- package/dist/scenes/visual-audit-contact-sheets.js +119 -0
- package/dist/scenes/visual-audit-fixtures.d.ts +25 -0
- package/dist/scenes/visual-audit-fixtures.js +210 -0
- package/dist/scenes/visual-audit-report.d.ts +11 -0
- package/dist/scenes/visual-audit-report.js +85 -0
- package/dist/scenes/visual-audit-review.d.ts +23 -0
- package/dist/scenes/visual-audit-review.js +829 -0
- package/dist/scenes/visual-audit-routes.d.ts +13 -0
- package/dist/scenes/visual-audit-routes.js +308 -0
- package/dist/scenes/visual-audit.d.ts +3 -0
- package/dist/scenes/visual-audit.js +596 -0
- package/dist/scripts/build-dist.js +154 -40
- package/dist/scripts/check-build-warnings.js +42 -53
- package/dist/scripts/cleanup-markdown.js +1 -1
- package/dist/scripts/cli-test-fixtures.js +24 -28
- package/dist/scripts/migrate-journey-csv-to-guarantees.js +140 -0
- package/dist/scripts/package-tools.js +12 -1
- package/dist/scripts/prepare.js +3 -7
- package/dist/scripts/release-verify.js +2 -5
- package/dist/scripts/run-fixture-astro-command.js +1 -1
- package/dist/scripts/template-catalog.test.js +68 -82
- package/dist/scripts/tenant-dev.js +0 -10
- package/dist/scripts/test-cloudflare-local.js +1 -1
- package/dist/scripts/test-scaffold.js +0 -1
- package/dist/scripts/test-smoke.js +3 -3
- package/dist/scripts/treeseed-build-dist.js +4 -7
- package/dist/scripts/treeseed-release-verify.js +1 -1
- package/dist/scripts/verify-driver.js +30 -21
- package/dist/scripts/workflow-commands.test.js +18 -27
- package/dist/scripts/workspace-command-e2e.js +1 -1
- package/dist/scripts/workspace-lint.js +6 -0
- package/dist/scripts/workspace-release-test.js +90 -1
- package/dist/scripts/workspace-test.js +6 -0
- package/dist/sdk-dispatch.d.ts +1 -1
- package/dist/sdk-dispatch.js +0 -16
- package/dist/sdk-fields.d.ts +1 -1
- package/dist/sdk-filters.d.ts +1 -1
- package/dist/sdk-types.d.ts +1184 -113
- package/dist/sdk-types.js +393 -0
- package/dist/sdk.d.ts +74 -79
- package/dist/sdk.js +27 -36
- package/dist/secrets-capability.d.ts +421 -0
- package/dist/secrets-capability.js +530 -0
- package/dist/seeds/normalize.js +1 -0
- package/dist/seeds/planner.js +38 -0
- package/dist/seeds/schema.js +293 -4
- package/dist/seeds/types.d.ts +60 -0
- package/dist/seeds/types.js +9 -1
- package/dist/service-credentials.d.ts +54 -0
- package/dist/service-credentials.js +112 -0
- package/dist/stores/cursor-store.d.ts +2 -2
- package/dist/stores/envelopes.d.ts +1 -1
- package/dist/stores/helpers.d.ts +1 -1
- package/dist/stores/lease-store.d.ts +2 -2
- package/dist/stores/message-store.d.ts +2 -2
- package/dist/stores/operational-store.d.ts +3 -26
- package/dist/stores/operational-store.js +0 -225
- package/dist/stores/project-workflow-store.d.ts +2 -2
- package/dist/stores/run-store.d.ts +2 -3
- package/dist/stores/run-store.js +0 -98
- package/dist/stores/subscription-store.d.ts +2 -3
- package/dist/stores/subscription-store.js +0 -100
- package/dist/template-catalog.d.ts +1 -1
- package/dist/template-launch-requirements.d.ts +2 -2
- package/dist/template-launch-ui.d.ts +2 -2
- package/dist/treedx/adapters.d.ts +6 -6
- package/dist/treedx/client.d.ts +1 -1
- package/dist/treedx/errors.d.ts +1 -1
- package/dist/treedx/federated-client.d.ts +3 -3
- package/dist/treedx/graph-adapter.d.ts +2 -2
- package/dist/treedx/index.d.ts +14 -14
- package/dist/treedx/market-integration.d.ts +1 -1
- package/dist/treedx/ports.d.ts +30 -30
- package/dist/treedx/query-adapter.d.ts +3 -3
- package/dist/treedx/registry-client.d.ts +2 -2
- package/dist/treedx/repository-adapter.d.ts +4 -4
- package/dist/treedx/repository-adapter.js +14 -3
- package/dist/treedx/sdk-integration.d.ts +3 -3
- package/dist/treedx/types.d.ts +2 -2
- package/dist/treedx/workspace-adapter.d.ts +2 -2
- package/dist/treedx-backends.d.ts +13 -11
- package/dist/treedx-backends.js +52 -50
- package/dist/treedx-client.d.ts +3 -0
- package/dist/treedx-client.js +10 -1
- package/dist/treeseed/services/compose.yml +2 -3
- package/dist/treeseed/template-catalog/catalog.fixture.json +4 -4
- package/dist/types/agents.d.ts +256 -0
- package/dist/types/agents.js +42 -1
- package/dist/verification.d.ts +1 -0
- package/dist/verification.js +143 -14
- package/dist/workflow/operations.d.ts +510 -559
- package/dist/workflow/operations.js +1891 -1342
- package/dist/workflow/policy.js +19 -7
- package/dist/workflow/runs.d.ts +9 -3
- package/dist/workflow/runs.js +66 -26
- package/dist/workflow/session.d.ts +4 -1
- package/dist/workflow/session.js +50 -10
- package/dist/workflow/worktrees.d.ts +6 -2
- package/dist/workflow/worktrees.js +98 -15
- package/dist/workflow-state.d.ts +5 -5
- package/dist/workflow-state.js +27 -17
- package/dist/workflow-support.d.ts +26 -25
- package/dist/workflow-support.js +27 -31
- package/dist/workflow.d.ts +46 -16
- package/dist/workflow.js +19 -7
- package/drizzle/d1/0000_treeseed_d1.sql +0 -18
- package/drizzle/market/0000_market_control_plane.sql +1793 -1499
- package/drizzle/market/0005_agent_capacity_coordination.sql +145 -0
- package/drizzle/market/0006_provider_assignment_lifecycle.sql +9 -0
- package/drizzle/market/0007_agent_architecture_gap_closure.sql +157 -0
- package/drizzle/market/0008_agent_capacity_operational_closure.sql +27 -0
- package/drizzle/market/0009_agent_capacity_runtime_hardening.sql +29 -0
- package/drizzle/market/0010_secrets_capability_persistence.sql +130 -0
- package/drizzle/market/0011_github_app_adapter.sql +47 -0
- package/drizzle/market/0012_workday_test_runs.sql +44 -0
- package/drizzle/market/0013_runtime_task_lifecycle.sql +39 -0
- package/drizzle/market/0014_governance_pipeline.sql +189 -0
- package/package.json +75 -18
- package/scripts/{verify-driver.mjs → verify-driver.ts} +19 -4
- package/templates/github/deploy-web.workflow.yml +12 -8
- package/dist/operations/services/mailpit-runtime.d.ts +0 -20
- package/dist/operations/services/mailpit-runtime.js +0 -67
- package/dist/operations/services/release-candidate.d.ts +0 -60
- package/dist/operations/services/release-candidate.js +0 -953
- package/dist/scripts/ensure-mailpit.js +0 -48
- package/dist/scripts/logs-mailpit.js +0 -2
- package/dist/scripts/run-ts.js +0 -45
- package/dist/scripts/stop-mailpit.js +0 -5
- package/dist/scripts/treeseed-run-ts.js +0 -45
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
2
|
import { createServer } from "node:net";
|
|
3
|
-
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import { readFileSync } from "node:fs";
|
|
5
|
-
import { tmpdir } from "node:os";
|
|
6
5
|
import { performance } from "node:perf_hooks";
|
|
7
|
-
import { join } from "node:path";
|
|
6
|
+
import { join, resolve } from "node:path";
|
|
8
7
|
import {
|
|
9
8
|
createTreeseedCanonicalReconcileReport
|
|
10
9
|
} from "./platform.js";
|
|
10
|
+
import { runTreeseedGit } from "../operations/services/git-runner.js";
|
|
11
11
|
import {
|
|
12
12
|
deleteRailwayProject,
|
|
13
13
|
ensureRailwayEnvironment,
|
|
@@ -26,12 +26,92 @@ import {
|
|
|
26
26
|
upsertRailwayVariables
|
|
27
27
|
} from "../operations/services/railway-api.js";
|
|
28
28
|
import { resolveGitHubCredentialForRepository } from "../operations/services/github-credentials.js";
|
|
29
|
+
import { MarketClient } from "../market-client.js";
|
|
30
|
+
import { MarketProviderClient } from "../capacity-provider.js";
|
|
29
31
|
const PROVIDER_CAPABILITIES = {
|
|
30
|
-
railway: ["project", "environment", "service", "image-service", "postgres", "volume", "domain", "variables", "deployment-health"],
|
|
32
|
+
railway: ["project", "environment", "service", "image-service", "postgres", "volume", "domain", "variables", "deployment-health", "capacity-provider-runtime-assignment-proof"],
|
|
31
33
|
cloudflare: ["pages", "worker", "d1", "r2", "kv", "queue", "dns", "turnstile", "secrets", "cache-rules"],
|
|
32
34
|
github: ["environment", "secret", "variable", "workflow-dispatch", "workflow-observation", "repository-scoped-token"],
|
|
33
|
-
local: ["process", "port", "local-db", "local-runner", "docker-compose-capacity-provider"]
|
|
35
|
+
local: ["process", "port", "local-db", "local-runner", "docker-compose-capacity-provider", "capacity-provider-assignment-proof"]
|
|
34
36
|
};
|
|
37
|
+
function isCapacityRuntimeProofCapability(capability) {
|
|
38
|
+
return capability === "capacity-provider-assignment-proof" || capability === "capacity-provider-runtime-assignment-proof";
|
|
39
|
+
}
|
|
40
|
+
function scenarioResourceKind(provider, capability) {
|
|
41
|
+
if (provider === "railway") return capability === "volume" ? "railway-volume" : "railway-service";
|
|
42
|
+
if (provider === "cloudflare") return "cloudflare-resource";
|
|
43
|
+
if (provider === "github") {
|
|
44
|
+
if (capability === "environment") return "github-environment";
|
|
45
|
+
if (capability === "secret") return "github-secret-binding";
|
|
46
|
+
if (capability === "variable") return "github-secret-binding";
|
|
47
|
+
return "package-workflow";
|
|
48
|
+
}
|
|
49
|
+
if (isCapacityRuntimeProofCapability(capability)) return "capacity-provider";
|
|
50
|
+
if (capability === "docker-compose-capacity-provider") return "local-docker-compose";
|
|
51
|
+
if (capability === "process") return "local-process";
|
|
52
|
+
if (capability === "local-runner") return "capacity-provider";
|
|
53
|
+
return "local-process";
|
|
54
|
+
}
|
|
55
|
+
function scenarioResourceProvider(provider, capability) {
|
|
56
|
+
if (provider === "cloudflare") return "cloudflare";
|
|
57
|
+
if (provider === "github") return "github";
|
|
58
|
+
if (provider === "local") return "local";
|
|
59
|
+
return "railway";
|
|
60
|
+
}
|
|
61
|
+
function liveAcceptanceDesiredResource(input) {
|
|
62
|
+
const id = `live-acceptance:${input.environment}:${input.provider}:${input.capability}:${input.runId}`;
|
|
63
|
+
const kind = scenarioResourceKind(input.provider, input.capability);
|
|
64
|
+
return {
|
|
65
|
+
id,
|
|
66
|
+
kind,
|
|
67
|
+
provider: scenarioResourceProvider(input.provider, input.capability),
|
|
68
|
+
environment: input.environment,
|
|
69
|
+
packageId: null,
|
|
70
|
+
serviceId: input.capability,
|
|
71
|
+
logicalName: input.capability,
|
|
72
|
+
spec: {
|
|
73
|
+
liveAcceptance: true,
|
|
74
|
+
provider: input.provider,
|
|
75
|
+
capability: input.capability,
|
|
76
|
+
runId: input.runId,
|
|
77
|
+
prefix: providerPrefix(input.environment, input.provider, input.runId),
|
|
78
|
+
tenantRoot: input.tenantRoot
|
|
79
|
+
},
|
|
80
|
+
dependencies: [],
|
|
81
|
+
source: { type: "package-adapter", id }
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function compileTreeseedLiveAcceptanceScenarios(input) {
|
|
85
|
+
const providers = input.provider === "all" ? ["railway", "cloudflare", "github", "local"] : [input.provider];
|
|
86
|
+
return providers.flatMap((provider) => PROVIDER_CAPABILITIES[provider].map((capability) => {
|
|
87
|
+
const probeOnly = input.mode === "smoke" || provider === "github" && ["workflow-observation", "repository-scoped-token"].includes(capability) || provider === "cloudflare" && capability === "cache-rules" || isCapacityRuntimeProofCapability(capability);
|
|
88
|
+
const desiredResources = probeOnly ? [] : [liveAcceptanceDesiredResource({
|
|
89
|
+
tenantRoot: input.tenantRoot,
|
|
90
|
+
environment: input.environment,
|
|
91
|
+
provider,
|
|
92
|
+
capability,
|
|
93
|
+
runId: input.runId
|
|
94
|
+
})];
|
|
95
|
+
const selector = {
|
|
96
|
+
environment: input.environment,
|
|
97
|
+
host: [provider],
|
|
98
|
+
resourceKind: desiredResources.map((resource) => resource.kind),
|
|
99
|
+
serviceType: [capability]
|
|
100
|
+
};
|
|
101
|
+
return {
|
|
102
|
+
id: `live-acceptance:${input.environment}:${provider}:${capability}:${input.runId}`,
|
|
103
|
+
provider,
|
|
104
|
+
capability,
|
|
105
|
+
desiredResources,
|
|
106
|
+
selector,
|
|
107
|
+
expectedActions: input.mode === "cleanup" ? ["delete", "noop"] : probeOnly ? ["noop"] : ["create", "update", "replace", "reattach", "noop"],
|
|
108
|
+
cleanupSelector: selector,
|
|
109
|
+
required: true,
|
|
110
|
+
probeOnly,
|
|
111
|
+
cleanupRequired: input.mode !== "smoke" && !probeOnly
|
|
112
|
+
};
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
35
115
|
function configuredValue(env, keys) {
|
|
36
116
|
for (const key of keys) {
|
|
37
117
|
const value = env[key];
|
|
@@ -39,6 +119,268 @@ function configuredValue(env, keys) {
|
|
|
39
119
|
}
|
|
40
120
|
return "";
|
|
41
121
|
}
|
|
122
|
+
function capacityAcceptanceConfig(env, environment) {
|
|
123
|
+
const local = environment === "local";
|
|
124
|
+
const apiUrl = configuredValue(env, [
|
|
125
|
+
"TREESEED_CAPACITY_ACCEPTANCE_API_URL",
|
|
126
|
+
"TREESEED_MARKET_URL",
|
|
127
|
+
"TREESEED_MANAGEMENT_API_URL",
|
|
128
|
+
"TREESEED_API_BASE_URL"
|
|
129
|
+
]) || (local ? "http://127.0.0.1:3000" : "");
|
|
130
|
+
const adminToken = configuredValue(env, ["TREESEED_CAPACITY_ACCEPTANCE_ADMIN_TOKEN"]) || (local ? "tsk_local_treeseed_acceptance_admin" : "");
|
|
131
|
+
const teamId = configuredValue(env, ["TREESEED_CAPACITY_ACCEPTANCE_TEAM_ID"]) || (local ? "d8a613c2-bbdb-4474-9c96-31e985beafd4" : "");
|
|
132
|
+
const projectId = configuredValue(env, ["TREESEED_CAPACITY_ACCEPTANCE_PROJECT_ID"]) || (local ? "90764af2-5a13-42b9-a2fa-fb3af5882323" : "");
|
|
133
|
+
const providerId = configuredValue(env, ["TREESEED_CAPACITY_ACCEPTANCE_PROVIDER_ID", "TREESEED_CAPACITY_PROVIDER_ID"]) || (local ? "ff48ce97-6959-46b5-be9f-9b7062161fe3" : "");
|
|
134
|
+
const agentClassId = configuredValue(env, ["TREESEED_CAPACITY_ACCEPTANCE_AGENT_CLASS_ID"]) || (local ? "planning" : "");
|
|
135
|
+
const providerApiKey = configuredValue(env, ["TREESEED_CAPACITY_PROVIDER_API_KEY"]) || (local ? "tsp_local_treeseed_demo_capacity_provider" : "");
|
|
136
|
+
const missing = [
|
|
137
|
+
["TREESEED_CAPACITY_ACCEPTANCE_API_URL or TREESEED_MARKET_URL", apiUrl],
|
|
138
|
+
["TREESEED_CAPACITY_ACCEPTANCE_ADMIN_TOKEN", adminToken],
|
|
139
|
+
["TREESEED_CAPACITY_ACCEPTANCE_TEAM_ID", teamId],
|
|
140
|
+
["TREESEED_CAPACITY_ACCEPTANCE_PROJECT_ID", projectId],
|
|
141
|
+
["TREESEED_CAPACITY_ACCEPTANCE_PROVIDER_ID or TREESEED_CAPACITY_PROVIDER_ID", providerId],
|
|
142
|
+
["TREESEED_CAPACITY_ACCEPTANCE_AGENT_CLASS_ID", agentClassId],
|
|
143
|
+
["TREESEED_CAPACITY_PROVIDER_API_KEY", providerApiKey]
|
|
144
|
+
].filter(([, value]) => !value).map(([key]) => String(key));
|
|
145
|
+
return {
|
|
146
|
+
apiUrl,
|
|
147
|
+
adminToken,
|
|
148
|
+
teamId,
|
|
149
|
+
projectId,
|
|
150
|
+
providerId,
|
|
151
|
+
agentClassId,
|
|
152
|
+
providerApiKey,
|
|
153
|
+
missing
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function capacityGrantForAcceptance(grants, config, environment) {
|
|
157
|
+
return grants.map((entry) => entry && typeof entry === "object" ? entry : null).find(
|
|
158
|
+
(grant) => grant && grant.id && grant.capacityProviderId === config.providerId && grant.projectId === config.projectId && (grant.teamId === config.teamId || !grant.teamId) && (grant.state === "active" || !grant.state) && (grant.environment === environment || !grant.environment)
|
|
159
|
+
) ?? null;
|
|
160
|
+
}
|
|
161
|
+
async function createTreeDxProxyAuditEvidence(input) {
|
|
162
|
+
const response = await input.fetchImpl(
|
|
163
|
+
`${input.apiUrl.replace(/\/$/u, "")}/v1/dx/projects/${encodeURIComponent(input.projectId)}/repos/${encodeURIComponent(`capacity-proof-${input.runId}`)}/files/read`,
|
|
164
|
+
{
|
|
165
|
+
method: "POST",
|
|
166
|
+
headers: {
|
|
167
|
+
accept: "application/json",
|
|
168
|
+
authorization: `Bearer ${input.providerApiKey}`,
|
|
169
|
+
"content-type": "application/json",
|
|
170
|
+
"x-treeseed-assignment-id": input.assignmentId
|
|
171
|
+
},
|
|
172
|
+
body: JSON.stringify({
|
|
173
|
+
paths: [`src/content/agent-platform-proof/${input.runId}.mdx`],
|
|
174
|
+
ref: "HEAD"
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
if (response.status !== 403) {
|
|
179
|
+
const text = await response.text().catch(() => "");
|
|
180
|
+
throw new Error(`Capacity acceptance TreeDX proxy audit probe expected 403 but received ${response.status}${text ? `: ${text}` : ""}.`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async function runCapacityProviderAssignmentProof(input) {
|
|
184
|
+
const config = capacityAcceptanceConfig(input.env, input.environment);
|
|
185
|
+
if (config.missing.length > 0) {
|
|
186
|
+
throw new Error(`Missing capacity acceptance configuration: ${config.missing.join(", ")}.`);
|
|
187
|
+
}
|
|
188
|
+
const runnerId = `${input.prefix}-runner`;
|
|
189
|
+
const assignmentId = `${input.prefix}-assignment`;
|
|
190
|
+
const mode = configuredValue(input.env, ["TREESEED_CAPACITY_ACCEPTANCE_MODE"]) || "planning";
|
|
191
|
+
const metadata = {
|
|
192
|
+
liveAcceptance: true,
|
|
193
|
+
runId: input.runId,
|
|
194
|
+
prefix: input.prefix,
|
|
195
|
+
provider: input.provider,
|
|
196
|
+
capability: input.provider === "railway" ? "capacity-provider-runtime-assignment-proof" : "capacity-provider-assignment-proof",
|
|
197
|
+
priority: 1e6
|
|
198
|
+
};
|
|
199
|
+
const adminClient = new MarketClient({
|
|
200
|
+
profile: {
|
|
201
|
+
id: "capacity-acceptance",
|
|
202
|
+
label: "Capacity Acceptance",
|
|
203
|
+
baseUrl: config.apiUrl,
|
|
204
|
+
kind: "specialized",
|
|
205
|
+
teamId: config.teamId
|
|
206
|
+
},
|
|
207
|
+
accessToken: config.adminToken,
|
|
208
|
+
fetchImpl: input.fetchImpl,
|
|
209
|
+
userAgent: `treeseed-live-acceptance/${input.runId}`
|
|
210
|
+
});
|
|
211
|
+
const providerClient = new MarketProviderClient({
|
|
212
|
+
marketUrl: config.apiUrl,
|
|
213
|
+
marketId: input.environment,
|
|
214
|
+
apiKey: config.providerApiKey,
|
|
215
|
+
fetchImpl: input.fetchImpl,
|
|
216
|
+
userAgent: `treeseed-live-acceptance/${input.runId}`
|
|
217
|
+
});
|
|
218
|
+
const existingClasses = await adminClient.projectAgentClasses(config.projectId).catch(() => ({ payload: [] }));
|
|
219
|
+
const hasAgentClass = Array.isArray(existingClasses.payload) && existingClasses.payload.some((entry) => {
|
|
220
|
+
const record = entry && typeof entry === "object" ? entry : {};
|
|
221
|
+
return record.id === config.agentClassId || record.slug === config.agentClassId;
|
|
222
|
+
});
|
|
223
|
+
if (!hasAgentClass) {
|
|
224
|
+
await adminClient.createProjectAgentClass(config.projectId, {
|
|
225
|
+
id: config.agentClassId,
|
|
226
|
+
slug: config.agentClassId,
|
|
227
|
+
name: "Planning",
|
|
228
|
+
status: "active",
|
|
229
|
+
allowedModes: ["planning"],
|
|
230
|
+
requiredCapabilities: ["agent_mode_run"],
|
|
231
|
+
metadata
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
const grants = await adminClient.capacityGrants(config.teamId).catch(() => ({ payload: [] }));
|
|
235
|
+
const acceptanceGrant = capacityGrantForAcceptance(Array.isArray(grants.payload) ? grants.payload : [], config, input.environment);
|
|
236
|
+
if (!acceptanceGrant) {
|
|
237
|
+
throw new Error(`Capacity acceptance did not find an active checked-in grant for project ${config.projectId} and provider ${config.providerId}.`);
|
|
238
|
+
}
|
|
239
|
+
const reservation = await adminClient.createCapacityReservation(config.projectId, {
|
|
240
|
+
id: `${input.prefix}-reservation`,
|
|
241
|
+
capacityProviderId: config.providerId,
|
|
242
|
+
laneId: typeof acceptanceGrant.laneId === "string" && acceptanceGrant.laneId ? acceptanceGrant.laneId : `${config.providerId}:agent-capacity`,
|
|
243
|
+
reservedCredits: 1,
|
|
244
|
+
nativeUnit: "request",
|
|
245
|
+
reservedNativeAmount: 1,
|
|
246
|
+
mode,
|
|
247
|
+
metadata
|
|
248
|
+
});
|
|
249
|
+
const reservationId = String(reservation.payload?.id ?? "");
|
|
250
|
+
if (!reservationId) throw new Error("Capacity acceptance reservation creation did not return an id.");
|
|
251
|
+
const checkIn = await providerClient.checkIn({
|
|
252
|
+
id: `${input.prefix}-session`,
|
|
253
|
+
environment: input.environment,
|
|
254
|
+
status: "open",
|
|
255
|
+
capabilities: ["repo_read", "agent_mode_run", "usage_report"],
|
|
256
|
+
grants: [{
|
|
257
|
+
grantId: String(acceptanceGrant.id),
|
|
258
|
+
projectId: config.projectId,
|
|
259
|
+
teamId: config.teamId,
|
|
260
|
+
grantScope: typeof acceptanceGrant.grantScope === "string" ? acceptanceGrant.grantScope : "project"
|
|
261
|
+
}],
|
|
262
|
+
nativeLimits: { wallMinutes: { session: 30 } },
|
|
263
|
+
runnerPressure: { activeRunners: 0, maxConcurrentRunners: 1 },
|
|
264
|
+
constraints: { liveAcceptance: true, outboundOnly: true },
|
|
265
|
+
metadata
|
|
266
|
+
});
|
|
267
|
+
const sessionId = String(checkIn.payload.id ?? "");
|
|
268
|
+
if (!sessionId) throw new Error("Capacity acceptance check-in did not return a session id.");
|
|
269
|
+
await adminClient.createProviderAssignment(config.teamId, {
|
|
270
|
+
id: assignmentId,
|
|
271
|
+
projectId: config.projectId,
|
|
272
|
+
capacityProviderId: config.providerId,
|
|
273
|
+
providerSessionId: sessionId,
|
|
274
|
+
projectAgentClassId: config.agentClassId,
|
|
275
|
+
reservationId,
|
|
276
|
+
mode,
|
|
277
|
+
capacityEnvelope: {
|
|
278
|
+
teamId: config.teamId,
|
|
279
|
+
projectId: config.projectId,
|
|
280
|
+
providerId: config.providerId,
|
|
281
|
+
laneId: typeof acceptanceGrant.laneId === "string" && acceptanceGrant.laneId ? acceptanceGrant.laneId : `${config.providerId}:agent-capacity`,
|
|
282
|
+
reservationId,
|
|
283
|
+
mode,
|
|
284
|
+
limits: { wallMinutes: 5 },
|
|
285
|
+
metadata
|
|
286
|
+
},
|
|
287
|
+
decisionInput: {
|
|
288
|
+
kind: "capacity_acceptance_diagnostic",
|
|
289
|
+
runId: input.runId,
|
|
290
|
+
mode,
|
|
291
|
+
instructions: "Execute the isolated capacity acceptance diagnostic without widening project or provider scope."
|
|
292
|
+
},
|
|
293
|
+
workspaceContext: {
|
|
294
|
+
liveAcceptance: true,
|
|
295
|
+
runId: input.runId
|
|
296
|
+
},
|
|
297
|
+
metadata
|
|
298
|
+
});
|
|
299
|
+
let leased = null;
|
|
300
|
+
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
301
|
+
leased = await providerClient.nextAssignment({
|
|
302
|
+
sessionId,
|
|
303
|
+
runnerId,
|
|
304
|
+
leaseSeconds: 120,
|
|
305
|
+
metadata
|
|
306
|
+
});
|
|
307
|
+
const leasedId = leased.payload?.id ? String(leased.payload.id) : "";
|
|
308
|
+
if (!leasedId) throw new Error("Capacity acceptance did not lease an assignment.");
|
|
309
|
+
if (leasedId === assignmentId) break;
|
|
310
|
+
const leasedMetadata = leased.payload?.metadata && typeof leased.payload.metadata === "object" ? leased.payload.metadata : {};
|
|
311
|
+
if (leasedMetadata.liveAcceptance !== true) {
|
|
312
|
+
throw new Error(`Capacity acceptance leased ${leasedId} instead of diagnostic assignment ${assignmentId}.`);
|
|
313
|
+
}
|
|
314
|
+
const staleLeaseToken = leased.leaseToken ?? leased.payload.leaseToken ?? null;
|
|
315
|
+
if (!staleLeaseToken) throw new Error(`Capacity acceptance leased stale diagnostic ${leasedId} without a lease token.`);
|
|
316
|
+
await providerClient.completeAssignment(leasedId, {
|
|
317
|
+
runnerId,
|
|
318
|
+
leaseToken: staleLeaseToken,
|
|
319
|
+
output: { summary: "Retired stale capacity acceptance diagnostic.", runId: input.runId },
|
|
320
|
+
summary: { runId: input.runId, retiredAssignmentId: leasedId },
|
|
321
|
+
metadata: {
|
|
322
|
+
...metadata,
|
|
323
|
+
retiredStaleAcceptanceAssignment: true,
|
|
324
|
+
retiredAssignmentId: leasedId
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
leased = null;
|
|
328
|
+
}
|
|
329
|
+
if (!leased?.payload?.id) throw new Error("Capacity acceptance did not lease an assignment.");
|
|
330
|
+
if (leased.payload.id !== assignmentId) {
|
|
331
|
+
throw new Error(`Capacity acceptance leased stale diagnostics but did not reach diagnostic assignment ${assignmentId}.`);
|
|
332
|
+
}
|
|
333
|
+
const leaseToken = leased.leaseToken ?? leased.payload.leaseToken ?? null;
|
|
334
|
+
if (!leaseToken) throw new Error("Capacity acceptance lease did not include a lease token.");
|
|
335
|
+
await createTreeDxProxyAuditEvidence({
|
|
336
|
+
fetchImpl: input.fetchImpl,
|
|
337
|
+
apiUrl: config.apiUrl,
|
|
338
|
+
providerApiKey: config.providerApiKey,
|
|
339
|
+
projectId: config.projectId,
|
|
340
|
+
assignmentId,
|
|
341
|
+
runId: input.runId
|
|
342
|
+
});
|
|
343
|
+
const modeRun = await providerClient.createAssignmentModeRun(assignmentId, {
|
|
344
|
+
status: "succeeded",
|
|
345
|
+
selectedInput: { kind: "capacity_acceptance_diagnostic", runId: input.runId, mode },
|
|
346
|
+
outputs: { summary: "Capacity acceptance diagnostic completed.", runId: input.runId },
|
|
347
|
+
usageActual: {
|
|
348
|
+
actualCredits: 0,
|
|
349
|
+
nativeUsage: { nativeUnit: "request", amount: 1, source: "capacity_acceptance" },
|
|
350
|
+
metadata
|
|
351
|
+
},
|
|
352
|
+
traceRefs: { liveAcceptanceRunId: input.runId },
|
|
353
|
+
metadata
|
|
354
|
+
});
|
|
355
|
+
const modeRunId = String(modeRun.payload.id ?? "");
|
|
356
|
+
if (!modeRunId) throw new Error("Capacity acceptance mode-run creation did not return an id.");
|
|
357
|
+
const completed = await providerClient.completeAssignment(assignmentId, {
|
|
358
|
+
runnerId,
|
|
359
|
+
leaseToken,
|
|
360
|
+
modeRunId,
|
|
361
|
+
actualCredits: 0.25,
|
|
362
|
+
nativeUsage: { nativeUnit: "request", amount: 1, source: "capacity_acceptance" },
|
|
363
|
+
output: { summary: "Capacity acceptance diagnostic completed.", runId: input.runId },
|
|
364
|
+
summary: { runId: input.runId, modeRunId },
|
|
365
|
+
metadata
|
|
366
|
+
});
|
|
367
|
+
const finalStatus = String(completed.payload?.status ?? "");
|
|
368
|
+
if (finalStatus !== "completed") {
|
|
369
|
+
throw new Error(`Capacity acceptance assignment finished with status "${finalStatus || "unknown"}".`);
|
|
370
|
+
}
|
|
371
|
+
const modeRuns = await adminClient.projectAgentModeRuns(config.projectId, { assignmentId });
|
|
372
|
+
const modeRunCount = Array.isArray(modeRuns.payload) ? modeRuns.payload.length : 0;
|
|
373
|
+
if (!modeRunCount) throw new Error("Capacity acceptance mode-run was not visible through project mode-run inspection.");
|
|
374
|
+
return {
|
|
375
|
+
sessionId,
|
|
376
|
+
assignmentId,
|
|
377
|
+
modeRunId,
|
|
378
|
+
finalStatus,
|
|
379
|
+
mode,
|
|
380
|
+
runnerId,
|
|
381
|
+
modeRunCount
|
|
382
|
+
};
|
|
383
|
+
}
|
|
42
384
|
function shortRunId(now = /* @__PURE__ */ new Date()) {
|
|
43
385
|
return now.toISOString().replace(/[^0-9]/gu, "").slice(0, 14);
|
|
44
386
|
}
|
|
@@ -62,7 +404,7 @@ function emitProgress(onProgress, event) {
|
|
|
62
404
|
});
|
|
63
405
|
}
|
|
64
406
|
function sleep(ms) {
|
|
65
|
-
return new Promise((
|
|
407
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
66
408
|
}
|
|
67
409
|
async function waitForLiveObservation(description, observe, isReady, options = {}) {
|
|
68
410
|
const attempts = Math.max(1, options.attempts ?? 8);
|
|
@@ -94,11 +436,10 @@ function parseGitHubRepository(value) {
|
|
|
94
436
|
function resolveCurrentGitHubRepository(cwd, env) {
|
|
95
437
|
const configured = configuredValue(env, ["TREESEED_REPOSITORY", "GITHUB_REPOSITORY"]);
|
|
96
438
|
if (configured) return parseGitHubRepository(configured);
|
|
97
|
-
const remote =
|
|
439
|
+
const remote = runTreeseedGit(["config", "--get", "remote.origin.url"], {
|
|
98
440
|
cwd,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}).trim();
|
|
441
|
+
mode: "read"
|
|
442
|
+
}).stdout.trim();
|
|
102
443
|
return parseGitHubRepository(remote);
|
|
103
444
|
}
|
|
104
445
|
function domainFromWorkspace(cwd) {
|
|
@@ -377,8 +718,8 @@ function reportForProvider({
|
|
|
377
718
|
};
|
|
378
719
|
}
|
|
379
720
|
async function cloudflareRequestPayload(path, env, fetchImpl, init = {}) {
|
|
380
|
-
const token = configuredValue(env, ["
|
|
381
|
-
if (!token) throw new Error("Missing
|
|
721
|
+
const token = configuredValue(env, ["TREESEED_CLOUDFLARE_API_TOKEN"]);
|
|
722
|
+
if (!token) throw new Error("Missing TREESEED_CLOUDFLARE_API_TOKEN.");
|
|
382
723
|
const response = await fetchImpl(`https://api.cloudflare.com/client/v4${path}`, {
|
|
383
724
|
...init,
|
|
384
725
|
headers: {
|
|
@@ -399,9 +740,28 @@ async function cloudflareRequest(path, env, fetchImpl, init = {}) {
|
|
|
399
740
|
const payload = await cloudflareRequestPayload(path, env, fetchImpl, init);
|
|
400
741
|
return payload.result;
|
|
401
742
|
}
|
|
743
|
+
function isTransientCloudflareError(error) {
|
|
744
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
745
|
+
return /\b(500|502|503|504|520|521|522|523|524)\b|internal server error|unknown error occurred|temporar(?:y|ily)|timeout|rate limit/iu.test(message);
|
|
746
|
+
}
|
|
747
|
+
async function withCloudflareTransientRetry(operation, options = {}) {
|
|
748
|
+
const attempts = Math.max(1, options.attempts ?? 4);
|
|
749
|
+
const delayMs = Math.max(0, options.delayMs ?? 1500);
|
|
750
|
+
let lastError;
|
|
751
|
+
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
752
|
+
try {
|
|
753
|
+
return await operation();
|
|
754
|
+
} catch (error) {
|
|
755
|
+
lastError = error;
|
|
756
|
+
if (!isTransientCloudflareError(error) || attempt >= attempts) break;
|
|
757
|
+
await sleep(delayMs * attempt);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
761
|
+
}
|
|
402
762
|
async function cloudflareRawRequest(path, env, fetchImpl, init = {}) {
|
|
403
|
-
const token = configuredValue(env, ["
|
|
404
|
-
if (!token) throw new Error("Missing
|
|
763
|
+
const token = configuredValue(env, ["TREESEED_CLOUDFLARE_API_TOKEN"]);
|
|
764
|
+
if (!token) throw new Error("Missing TREESEED_CLOUDFLARE_API_TOKEN.");
|
|
405
765
|
const response = await fetchImpl(`https://api.cloudflare.com/client/v4${path}`, {
|
|
406
766
|
...init,
|
|
407
767
|
headers: {
|
|
@@ -443,7 +803,7 @@ async function runSmokeProvider({
|
|
|
443
803
|
fetchImpl
|
|
444
804
|
}) {
|
|
445
805
|
if (provider === "railway") {
|
|
446
|
-
if (!configuredValue(env, ["
|
|
806
|
+
if (!configuredValue(env, ["TREESEED_RAILWAY_API_TOKEN"])) {
|
|
447
807
|
return PROVIDER_CAPABILITIES.railway.map((capability) => scenario({
|
|
448
808
|
provider,
|
|
449
809
|
mode,
|
|
@@ -452,7 +812,7 @@ async function runSmokeProvider({
|
|
|
452
812
|
ok: false,
|
|
453
813
|
phase: "blocked",
|
|
454
814
|
action: "blocked",
|
|
455
|
-
reason: "Missing
|
|
815
|
+
reason: "Missing TREESEED_RAILWAY_API_TOKEN for Railway live reconciliation tests."
|
|
456
816
|
}));
|
|
457
817
|
}
|
|
458
818
|
try {
|
|
@@ -479,7 +839,8 @@ async function runSmokeProvider({
|
|
|
479
839
|
scenario({ provider, mode, prefix, capability: "volume", ok: volumes.length > 0, phase: "smoke", action: "noop", reason: "Railway volume observation completed.", locators: base }),
|
|
480
840
|
scenario({ provider, mode, prefix, capability: "domain", ok: true, phase: "smoke", action: "noop", reason: "Railway domain API uses authenticated provider surface.", locators: base }),
|
|
481
841
|
scenario({ provider, mode, prefix, capability: "variables", ok: Boolean(selectedEnvironment), phase: "smoke", action: "noop", reason: `Railway variables API observed ${Object.keys(variables).length} variables.`, locators: base }),
|
|
482
|
-
scenario({ provider, mode, prefix, capability: "deployment-health", ok: services.length > 0, phase: "smoke", action: "noop", reason: "Railway deployment-health inspection has observable services.", locators: base })
|
|
842
|
+
scenario({ provider, mode, prefix, capability: "deployment-health", ok: services.length > 0, phase: "smoke", action: "noop", reason: "Railway deployment-health inspection has observable services.", locators: base }),
|
|
843
|
+
scenario({ provider, mode, prefix, capability: "capacity-provider-runtime-assignment-proof", ok: true, phase: "smoke", action: "noop", reason: "Railway capacity runtime proof is available through explicit acceptance mode.", locators: base })
|
|
483
844
|
];
|
|
484
845
|
} catch (error) {
|
|
485
846
|
const reason = error instanceof Error ? error.message : String(error);
|
|
@@ -487,8 +848,8 @@ async function runSmokeProvider({
|
|
|
487
848
|
}
|
|
488
849
|
}
|
|
489
850
|
if (provider === "cloudflare") {
|
|
490
|
-
const accountId = configuredValue(env, ["
|
|
491
|
-
if (!configuredValue(env, ["
|
|
851
|
+
const accountId = configuredValue(env, ["TREESEED_CLOUDFLARE_ACCOUNT_ID"]);
|
|
852
|
+
if (!configuredValue(env, ["TREESEED_CLOUDFLARE_API_TOKEN"]) || !accountId) {
|
|
492
853
|
return PROVIDER_CAPABILITIES.cloudflare.map((capability) => scenario({
|
|
493
854
|
provider,
|
|
494
855
|
mode,
|
|
@@ -497,7 +858,7 @@ async function runSmokeProvider({
|
|
|
497
858
|
ok: false,
|
|
498
859
|
phase: "blocked",
|
|
499
860
|
action: "blocked",
|
|
500
|
-
reason: "Missing
|
|
861
|
+
reason: "Missing TREESEED_CLOUDFLARE_API_TOKEN or TREESEED_CLOUDFLARE_ACCOUNT_ID for Cloudflare live reconciliation tests."
|
|
501
862
|
}));
|
|
502
863
|
}
|
|
503
864
|
const checks = [
|
|
@@ -527,7 +888,7 @@ async function runSmokeProvider({
|
|
|
527
888
|
repository = resolveCurrentGitHubRepository(cwd, env);
|
|
528
889
|
const credential = resolveGitHubCredentialForRepository(repository, { values: env, env });
|
|
529
890
|
if (!credential.token) {
|
|
530
|
-
throw new Error(`Missing GitHub credential for ${repository}; expected ${credential.envName} or
|
|
891
|
+
throw new Error(`Missing GitHub credential for ${repository}; expected ${credential.envName} or TREESEED_GITHUB_TOKEN fallback.`);
|
|
531
892
|
}
|
|
532
893
|
const [owner, repo] = credential.repository.split("/");
|
|
533
894
|
const checks = [
|
|
@@ -566,27 +927,28 @@ async function runSmokeProvider({
|
|
|
566
927
|
async function requireAcceptanceConfig(provider, cwd, env, fetchImpl) {
|
|
567
928
|
const missing = [];
|
|
568
929
|
if (provider === "railway") {
|
|
569
|
-
if (!configuredValue(env, ["
|
|
930
|
+
if (!configuredValue(env, ["TREESEED_RAILWAY_API_TOKEN"])) missing.push("TREESEED_RAILWAY_API_TOKEN");
|
|
570
931
|
if (!resolveLiveTestDomain(cwd, env)) missing.push("TREESEED_LIVE_TEST_DOMAIN or treeseed.site.yaml siteUrl");
|
|
932
|
+
missing.push(...capacityAcceptanceConfig(env).missing);
|
|
571
933
|
}
|
|
572
934
|
if (provider === "cloudflare") {
|
|
573
|
-
if (!configuredValue(env, ["
|
|
574
|
-
if (!configuredValue(env, ["
|
|
935
|
+
if (!configuredValue(env, ["TREESEED_CLOUDFLARE_API_TOKEN"])) missing.push("TREESEED_CLOUDFLARE_API_TOKEN");
|
|
936
|
+
if (!configuredValue(env, ["TREESEED_CLOUDFLARE_ACCOUNT_ID"])) missing.push("TREESEED_CLOUDFLARE_ACCOUNT_ID");
|
|
575
937
|
const domain = resolveLiveTestDomain(cwd, env);
|
|
576
938
|
if (!domain) {
|
|
577
939
|
missing.push("TREESEED_LIVE_TEST_DOMAIN or treeseed.site.yaml siteUrl");
|
|
578
|
-
} else if (configuredValue(env, ["
|
|
940
|
+
} else if (configuredValue(env, ["TREESEED_CLOUDFLARE_API_TOKEN"]) && !await resolveCloudflareZoneId(domain, env, fetchImpl)) {
|
|
579
941
|
missing.push("TREESEED_LIVE_TEST_CLOUDFLARE_ZONE_ID or visible Cloudflare zone for live-test domain");
|
|
580
942
|
}
|
|
581
943
|
}
|
|
582
944
|
if (provider === "github") {
|
|
583
|
-
if (!configuredValue(env, ["
|
|
945
|
+
if (!configuredValue(env, ["TREESEED_GITHUB_TOKEN"])) {
|
|
584
946
|
try {
|
|
585
947
|
const repository = configuredValue(env, ["TREESEED_REPOSITORY", "GITHUB_REPOSITORY"]);
|
|
586
948
|
const credential = repository ? resolveGitHubCredentialForRepository(repository, { values: env, env }) : null;
|
|
587
|
-
if (!credential?.token) missing.push("
|
|
949
|
+
if (!credential?.token) missing.push("TREESEED_GITHUB_TOKEN or repository-scoped TREESEED_GITHUB_TOKEN_*");
|
|
588
950
|
} catch {
|
|
589
|
-
missing.push("
|
|
951
|
+
missing.push("TREESEED_GITHUB_TOKEN or repository-scoped TREESEED_GITHUB_TOKEN_*");
|
|
590
952
|
}
|
|
591
953
|
}
|
|
592
954
|
}
|
|
@@ -923,6 +1285,30 @@ mutation TreeseedLiveRailwayCustomDomainCreate($input: CustomDomainCreateInput!)
|
|
|
923
1285
|
() => listRailwayServices({ projectId, env, fetchImpl }),
|
|
924
1286
|
(services) => services.some((candidate) => candidate.id === serviceId)
|
|
925
1287
|
)));
|
|
1288
|
+
results.push(await measuredScenario({
|
|
1289
|
+
provider: "railway",
|
|
1290
|
+
mode,
|
|
1291
|
+
environment,
|
|
1292
|
+
runId,
|
|
1293
|
+
prefix,
|
|
1294
|
+
capability: "capacity-provider-runtime-assignment-proof",
|
|
1295
|
+
phase: "verify",
|
|
1296
|
+
action: "noop",
|
|
1297
|
+
startMessage: "railway:capacity-provider-runtime-assignment-proof: running assignment lifecycle proof",
|
|
1298
|
+
successReason: "Railway capacity acceptance created a diagnostic assignment, leased it through the provider protocol, emitted mode-run telemetry, and completed it.",
|
|
1299
|
+
locators: { projectId, environmentId },
|
|
1300
|
+
retainedResources: (value) => {
|
|
1301
|
+
const proof = value;
|
|
1302
|
+
return [providerNode("railway", environment, "capacity-runtime-proof", proof.assignmentId, {
|
|
1303
|
+
sessionId: proof.sessionId,
|
|
1304
|
+
modeRunId: proof.modeRunId,
|
|
1305
|
+
finalStatus: proof.finalStatus,
|
|
1306
|
+
mode: proof.mode,
|
|
1307
|
+
modeRunCount: proof.modeRunCount
|
|
1308
|
+
})];
|
|
1309
|
+
},
|
|
1310
|
+
onProgress
|
|
1311
|
+
}, async () => runCapacityProviderAssignmentProof({ provider: "railway", environment, runId, prefix, env, fetchImpl })));
|
|
926
1312
|
} catch (error) {
|
|
927
1313
|
const reason = error instanceof Error ? error.message : String(error);
|
|
928
1314
|
for (const capability of PROVIDER_CAPABILITIES.railway) {
|
|
@@ -982,7 +1368,7 @@ function cloudflareListItems(value, keys = []) {
|
|
|
982
1368
|
return [];
|
|
983
1369
|
}
|
|
984
1370
|
async function runCloudflareCleanup(cwd, environment, prefix, mode, env, fetchImpl) {
|
|
985
|
-
const accountId = configuredValue(env, ["
|
|
1371
|
+
const accountId = configuredValue(env, ["TREESEED_CLOUDFLARE_ACCOUNT_ID"]);
|
|
986
1372
|
const domain = resolveLiveTestDomain(cwd, env);
|
|
987
1373
|
const zoneId = domain ? await resolveCloudflareZoneId(domain, env, fetchImpl) : configuredValue(env, ["TREESEED_LIVE_TEST_CLOUDFLARE_ZONE_ID", "CLOUDFLARE_ZONE_ID"]);
|
|
988
1374
|
const destroyed = [];
|
|
@@ -1024,10 +1410,10 @@ async function runCloudflareCleanup(cwd, environment, prefix, mode, env, fetchIm
|
|
|
1024
1410
|
}
|
|
1025
1411
|
return items;
|
|
1026
1412
|
};
|
|
1027
|
-
if (!configuredValue(env, ["
|
|
1028
|
-
cleanupDrift.push(blocking("cloudflare", "account", "Cloudflare cleanup requires
|
|
1413
|
+
if (!configuredValue(env, ["TREESEED_CLOUDFLARE_API_TOKEN"]) || !accountId) {
|
|
1414
|
+
cleanupDrift.push(blocking("cloudflare", "account", "Cloudflare cleanup requires TREESEED_CLOUDFLARE_API_TOKEN and TREESEED_CLOUDFLARE_ACCOUNT_ID."));
|
|
1029
1415
|
}
|
|
1030
|
-
if (accountId && configuredValue(env, ["
|
|
1416
|
+
if (accountId && configuredValue(env, ["TREESEED_CLOUDFLARE_API_TOKEN"])) {
|
|
1031
1417
|
if (mode === "acceptance") {
|
|
1032
1418
|
await attempt("worker", prefix, () => cloudflareRequest(`/accounts/${accountId}/workers/scripts/${prefix}`, env, fetchImpl, { method: "DELETE" }).catch((error) => {
|
|
1033
1419
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1068,7 +1454,7 @@ async function runCloudflareCleanup(cwd, environment, prefix, mode, env, fetchIm
|
|
|
1068
1454
|
if (name.startsWith(prefixRoot) && id) await attempt("turnstile", id, () => cloudflareRequest(`/accounts/${accountId}/challenges/widgets/${id}`, env, fetchImpl, { method: "DELETE" }));
|
|
1069
1455
|
}
|
|
1070
1456
|
}
|
|
1071
|
-
if (zoneId && configuredValue(env, ["
|
|
1457
|
+
if (zoneId && configuredValue(env, ["TREESEED_CLOUDFLARE_API_TOKEN"])) {
|
|
1072
1458
|
for (const record of await list("dns", `/zones/${zoneId}/dns_records?per_page=100`)) {
|
|
1073
1459
|
const name = cloudflareName(record);
|
|
1074
1460
|
const id = cloudflareId(record);
|
|
@@ -1099,7 +1485,7 @@ async function runCloudflareAcceptance(cwd, environment, runId, prefix, env, fet
|
|
|
1099
1485
|
}
|
|
1100
1486
|
emitProgress(onProgress, { provider: "cloudflare", mode, environment, runId, resourcePrefix: prefix, phase: "cleanup", message: `cloudflare: removing old live-test resources for ${prefix}` });
|
|
1101
1487
|
await runCloudflareCleanup(cwd, environment, prefix, mode, env, fetchImpl);
|
|
1102
|
-
const accountId = configuredValue(env, ["
|
|
1488
|
+
const accountId = configuredValue(env, ["TREESEED_CLOUDFLARE_ACCOUNT_ID"]);
|
|
1103
1489
|
const domain = resolveLiveTestDomain(cwd, env);
|
|
1104
1490
|
const zoneId = await resolveCloudflareZoneId(domain, env, fetchImpl);
|
|
1105
1491
|
const results = [];
|
|
@@ -1163,10 +1549,10 @@ async function runCloudflareAcceptance(cwd, environment, runId, prefix, env, fet
|
|
|
1163
1549
|
() => cloudflareRawRequest(`/accounts/${accountId}/workers/scripts/${prefix}`, env, fetchImpl),
|
|
1164
1550
|
(value) => typeof value === "string" && value.includes("treeseed-live-test-worker")
|
|
1165
1551
|
));
|
|
1166
|
-
await attempt("pages", "pages", () => cloudflareRequest(`/accounts/${accountId}/pages/projects`, env, fetchImpl, {
|
|
1552
|
+
await attempt("pages", "pages", () => withCloudflareTransientRetry(() => cloudflareRequest(`/accounts/${accountId}/pages/projects`, env, fetchImpl, {
|
|
1167
1553
|
method: "POST",
|
|
1168
1554
|
body: JSON.stringify({ name: prefix, production_branch: "main" })
|
|
1169
|
-
}), () => waitForLiveObservation(
|
|
1555
|
+
})), () => waitForLiveObservation(
|
|
1170
1556
|
`Cloudflare Pages project ${prefix}`,
|
|
1171
1557
|
() => cloudflareRequest(`/accounts/${accountId}/pages/projects/${prefix}`, env, fetchImpl),
|
|
1172
1558
|
(value) => Boolean(value && typeof value === "object")
|
|
@@ -1281,7 +1667,7 @@ async function runGitHubAcceptance(cwd, environment, runId, prefix, env, fetchIm
|
|
|
1281
1667
|
try {
|
|
1282
1668
|
repository = resolveCurrentGitHubRepository(cwd, env);
|
|
1283
1669
|
const credential = resolveGitHubCredentialForRepository(repository, { values: env, env });
|
|
1284
|
-
if (!credential.token) throw new Error(`Missing GitHub credential for ${repository}; expected ${credential.envName} or
|
|
1670
|
+
if (!credential.token) throw new Error(`Missing GitHub credential for ${repository}; expected ${credential.envName} or TREESEED_GITHUB_TOKEN fallback.`);
|
|
1285
1671
|
const [owner, repo] = credential.repository.split("/");
|
|
1286
1672
|
const environmentName = prefix;
|
|
1287
1673
|
const variableName = `TREESEED_LIVE_TEST_${prefix.toUpperCase().replace(/[^A-Z0-9]/gu, "_")}`;
|
|
@@ -1408,24 +1794,26 @@ async function runGitHubAcceptance(cwd, environment, runId, prefix, env, fetchIm
|
|
|
1408
1794
|
}
|
|
1409
1795
|
}
|
|
1410
1796
|
async function listenOnEphemeralPort(server) {
|
|
1411
|
-
return new Promise((
|
|
1797
|
+
return new Promise((resolve2, reject) => {
|
|
1412
1798
|
server.once("error", reject);
|
|
1413
1799
|
server.listen(0, "127.0.0.1", () => {
|
|
1414
1800
|
const address = server.address();
|
|
1415
|
-
if (address && typeof address === "object")
|
|
1801
|
+
if (address && typeof address === "object") resolve2(address.port);
|
|
1416
1802
|
else reject(new Error("Local server did not expose an address."));
|
|
1417
1803
|
});
|
|
1418
1804
|
});
|
|
1419
1805
|
}
|
|
1420
1806
|
async function closeServer(server) {
|
|
1421
|
-
return new Promise((
|
|
1422
|
-
server.close((error) => error ? reject(error) :
|
|
1807
|
+
return new Promise((resolve2, reject) => {
|
|
1808
|
+
server.close((error) => error ? reject(error) : resolve2());
|
|
1423
1809
|
});
|
|
1424
1810
|
}
|
|
1425
|
-
async function runLocalAcceptance(environment, prefix, mode, runId, onProgress) {
|
|
1811
|
+
async function runLocalAcceptance(environment, prefix, mode, runId, env, fetchImpl, onProgress) {
|
|
1426
1812
|
const created = [];
|
|
1427
1813
|
const destroyed = [];
|
|
1428
|
-
const
|
|
1814
|
+
const tempBase = resolve(process.cwd(), ".treeseed", "tmp", "live-acceptance");
|
|
1815
|
+
await mkdir(tempBase, { recursive: true });
|
|
1816
|
+
const dir = await mkdtemp(join(tempBase, `${prefix}-`));
|
|
1429
1817
|
const results = [];
|
|
1430
1818
|
let server = null;
|
|
1431
1819
|
try {
|
|
@@ -1520,6 +1908,29 @@ async function runLocalAcceptance(environment, prefix, mode, runId, onProgress)
|
|
|
1520
1908
|
return { docker: error instanceof Error ? error.message : String(error), available: false };
|
|
1521
1909
|
}
|
|
1522
1910
|
}));
|
|
1911
|
+
results.push(await measuredScenario({
|
|
1912
|
+
provider: "local",
|
|
1913
|
+
mode,
|
|
1914
|
+
environment,
|
|
1915
|
+
runId,
|
|
1916
|
+
prefix,
|
|
1917
|
+
capability: "capacity-provider-assignment-proof",
|
|
1918
|
+
phase: "verify",
|
|
1919
|
+
action: "noop",
|
|
1920
|
+
startMessage: "local:capacity-provider-assignment-proof: running assignment lifecycle proof",
|
|
1921
|
+
successReason: "Local capacity acceptance created a diagnostic assignment, leased it through the provider protocol, emitted mode-run telemetry, and completed it.",
|
|
1922
|
+
retainedResources: (value) => {
|
|
1923
|
+
const proof = value;
|
|
1924
|
+
return [providerNode("local", environment, "capacity-runtime-proof", proof.assignmentId, {
|
|
1925
|
+
sessionId: proof.sessionId,
|
|
1926
|
+
modeRunId: proof.modeRunId,
|
|
1927
|
+
finalStatus: proof.finalStatus,
|
|
1928
|
+
mode: proof.mode,
|
|
1929
|
+
modeRunCount: proof.modeRunCount
|
|
1930
|
+
})];
|
|
1931
|
+
},
|
|
1932
|
+
onProgress
|
|
1933
|
+
}, async () => runCapacityProviderAssignmentProof({ provider: "local", environment, runId, prefix, env, fetchImpl })));
|
|
1523
1934
|
} catch (error) {
|
|
1524
1935
|
const reason = error instanceof Error ? error.message : String(error);
|
|
1525
1936
|
for (const capability of PROVIDER_CAPABILITIES.local) {
|
|
@@ -1571,7 +1982,7 @@ async function runProvider({
|
|
|
1571
1982
|
emitProgress(onProgress, { provider, mode, environment, runId, resourcePrefix: prefix, phase: report2.ok ? "complete" : "blocked", elapsedMs: Date.now() - started, message: `${provider}: ${report2.ok ? "passed" : "blocked"} in ${Date.now() - started}ms` });
|
|
1572
1983
|
return report2;
|
|
1573
1984
|
}
|
|
1574
|
-
const { results, cleanupDrift } = await runLocalAcceptance(environment, prefix, mode, runId, onProgress);
|
|
1985
|
+
const { results, cleanupDrift } = await runLocalAcceptance(environment, prefix, mode, runId, env, fetchImpl, onProgress);
|
|
1575
1986
|
const report = reportForProvider({ provider, mode, runId, prefix, environment, results, cleanupDrift });
|
|
1576
1987
|
emitProgress(onProgress, { provider, mode, environment, runId, resourcePrefix: prefix, phase: report.ok ? "complete" : "blocked", elapsedMs: Date.now() - started, message: `${provider}: ${report.ok ? "passed" : "blocked"} in ${Date.now() - started}ms` });
|
|
1577
1988
|
return report;
|
|
@@ -1609,6 +2020,7 @@ async function runTreeseedLiveReconcileTests(options) {
|
|
|
1609
2020
|
};
|
|
1610
2021
|
}
|
|
1611
2022
|
export {
|
|
2023
|
+
compileTreeseedLiveAcceptanceScenarios,
|
|
1612
2024
|
runTreeseedLiveReconcileTests,
|
|
1613
2025
|
treeseedLiveReconcileProviderCapabilities,
|
|
1614
2026
|
treeseedLiveReconcileResourcePrefix
|