deepline 0.3.89 → 0.3.91
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/contracts/install-commands.json +29 -0
- package/dist/bundling-sources/sdk/src/client.ts +221 -43
- package/dist/bundling-sources/sdk/src/index.ts +4 -0
- package/dist/bundling-sources/sdk/src/monitor-fleet-contract.ts +2 -556
- package/dist/bundling-sources/sdk/src/monitor-fleets.ts +2 -2
- package/dist/bundling-sources/sdk/src/pagination.ts +25 -0
- package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
- package/dist/bundling-sources/sdk/src/release.ts +11 -9
- package/dist/bundling-sources/sdk/src/types.ts +29 -1
- package/dist/bundling-sources/shared_libs/integration-contracts/monitor-fleet-contract.ts +549 -0
- package/dist/bundling-sources/shared_libs/monitors/analytics-public.ts +10 -0
- package/dist/bundling-sources/shared_libs/monitors/fleets/errors.ts +96 -0
- package/dist/bundling-sources/shared_libs/monitors/fleets/limits.ts +8 -0
- package/dist/bundling-sources/shared_libs/monitors/fleets/plan.ts +320 -0
- package/dist/bundling-sources/shared_libs/monitors/fleets/verdict.ts +106 -0
- package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +8 -1
- package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +4 -4
- package/dist/bundling-sources/shared_libs/monitors/inventory-reconciliation.ts +59 -0
- package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +7 -9
- package/dist/bundling-sources/shared_libs/monitors/monitor-fleet-limits.ts +2 -12
- package/dist/bundling-sources/shared_libs/monitors/package.json +113 -4
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +56 -9
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +2 -2
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +2 -2
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +245 -0
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-message.ts +38 -0
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-ack-probe.ts +94 -0
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-delivery.ts +60 -0
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue.ts +60 -0
- package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +2 -2
- package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +1 -1
- package/dist/bundling-sources/shared_libs/observability/build-context.ts +13 -0
- package/dist/bundling-sources/shared_libs/observability/log-metadata.ts +160 -0
- package/dist/bundling-sources/shared_libs/observability/request-context.ts +68 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +690 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +35 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +5 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/neon-constants.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +272 -0
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +46 -1
- package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +66 -1
- package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +0 -1
- package/dist/bundling-sources/shared_libs/play-runtime/bounceban-batching.ts +137 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +779 -140
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +46 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-payload-contract.ts +68 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +103 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +725 -0
- package/dist/bundling-sources/shared_libs/play-runtime/db-session-lease-store.ts +578 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/commands/roll-execution-relay.ts +521 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/commands/roll-receipt-gateway.ts +1378 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/commands/runtime-topology.ts +1024 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-gateway-route-probe.ts +193 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machine-lifecycle.ts +104 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +1844 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +21 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/process-tree.ts +40 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-gateway-drain.ts +262 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-surface.ts +98 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-topology.ts +303 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-tuple-publication-guardian.ts +70 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-tuple-recovery.ts +519 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/vercel-fly-rollback-alignment.ts +280 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/vercel-production-gate.ts +159 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +29 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +23 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-invocation-fence.ts +442 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +3 -3
- package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +18 -0
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/contracts.ts +66 -0
- package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/job.ts +145 -0
- package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/memory-store.ts +114 -0
- package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/ports.ts +21 -0
- package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/postgres-store.ts +170 -0
- package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +1322 -0
- package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/launch-source-policy.ts +112 -0
- package/dist/bundling-sources/shared_libs/play-runtime/map-execution-frame.ts +8 -0
- package/dist/bundling-sources/shared_libs/play-runtime/perf-trace.ts +127 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +5 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +24 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/contracts.ts +56 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/index.ts +13 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/job.ts +41 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/ports.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts +54 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/contracts.ts +114 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/engine-suspension.ts +108 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/index.ts +36 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/job.ts +97 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/ports.ts +104 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/postgres-fence-adapter.ts +263 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/worker-terminal-projection.ts +64 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/contracts.ts +29 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts +56 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/index.ts +15 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/job.ts +65 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/ports.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +42 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/index.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +142 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/ports.ts +42 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/postgres-adapter.ts +102 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/contracts.ts +60 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/index.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/job.ts +78 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/ports.ts +54 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/postgres-adapter.ts +71 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +5 -8
- package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +3 -5
- package/dist/bundling-sources/shared_libs/play-runtime/run-identity.ts +168 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +44 -5
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/child-play-resolver.ts +26 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +3662 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/progress-sidecar.ts +47 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-deadline.ts +84 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-gateway-transport.ts +91 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-heartbeat.ts +424 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-progress-push.ts +321 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-sheet-persistence-retry.ts +110 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +625 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +72 -9
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +6 -12
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +19 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/bundle.ts +0 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +14 -44
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +103 -208
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-authority.ts +201 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +67 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-release-environment.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sandbox-contract.ts +68 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +14 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-telemetry.ts +108 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-deadline-reconciliation.ts +88 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-deploy-task.ts +124 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-run-task.ts +68 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +193 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-lifecycle.ts +269 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-suffix.ts +73 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +6642 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +897 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-metrics.ts +120 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +76 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +476 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-heavy-request-admission.ts +47 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-progress-registry.ts +147 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/index.ts +27 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/lazy.ts +50 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/play-run-recovery.ts +98 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-budget-state.ts +260 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +1416 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +1255 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +942 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +14636 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +888 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +355 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-terminal-transition.ts +46 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runner-push.ts +60 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-api-origin.ts +33 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-gateway-health.ts +64 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +835 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +1218 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-operation.ts +207 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-scheduler-schema.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-capacity.ts +123 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-launch-read-observability.ts +78 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/submit-admission.ts +169 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/terminal-contract.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-queue-metrics.ts +34 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-resource-metrics.ts +249 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/step-progress.ts +296 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/native-batch.ts +3 -3
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/runtime-step-receipts-adapter.ts +20 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +60 -15
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execution-outcome.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +12 -0
- package/dist/bundling-sources/shared_libs/play-runtime/vercel-protection.ts +14 -1
- package/dist/bundling-sources/shared_libs/play-runtime/webhook-receipt-retry.ts +50 -0
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +165 -0
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +15 -23
- package/dist/bundling-sources/shared_libs/play-runtime/workflow-executor-auth.ts +169 -0
- package/dist/bundling-sources/shared_libs/play-runtime/zerobounce-batching.ts +122 -0
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +2 -0
- package/dist/bundling-sources/shared_libs/plays/bundling/repository-adapter.ts +24 -0
- package/dist/bundling-sources/shared_libs/plays/child-run-projection.ts +174 -0
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +2 -0
- package/dist/bundling-sources/shared_libs/plays/deploy/api-client.ts +267 -0
- package/dist/bundling-sources/shared_libs/plays/deploy/control-plane-types.ts +73 -0
- package/dist/bundling-sources/shared_libs/plays/deploy/manifest.ts +162 -0
- package/dist/bundling-sources/shared_libs/plays/deploy/project-serializer.ts +87 -0
- package/dist/bundling-sources/shared_libs/plays/deploy/source-file-path.ts +26 -0
- package/dist/bundling-sources/shared_libs/plays/deploy/target-paths.ts +36 -0
- package/dist/bundling-sources/shared_libs/plays/deployment-status.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/docflow.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/launch/input-contract.ts +400 -0
- package/dist/bundling-sources/shared_libs/plays/launch/prepare.ts +96 -0
- package/dist/bundling-sources/shared_libs/plays/local-file-discovery.ts +385 -0
- package/dist/bundling-sources/shared_libs/plays/play-grep-search.ts +112 -0
- package/dist/bundling-sources/shared_libs/plays/play-reference.ts +117 -0
- package/dist/bundling-sources/shared_libs/plays/run-input-summary.ts +260 -0
- package/dist/bundling-sources/shared_libs/plays/run-summary-types.ts +49 -0
- package/dist/bundling-sources/shared_libs/plays/secrets/errors.ts +19 -0
- package/dist/bundling-sources/shared_libs/plays/share/copy.ts +271 -0
- package/dist/bundling-sources/shared_libs/plays/share/metrics.ts +140 -0
- package/dist/bundling-sources/shared_libs/plays/share/public-read-model.ts +86 -0
- package/dist/bundling-sources/shared_libs/plays/share/seo-quality.ts +181 -0
- package/dist/bundling-sources/shared_libs/plays/share/static-pipeline-summary.ts +658 -0
- package/dist/bundling-sources/shared_libs/plays/share/types.ts +197 -0
- package/dist/bundling-sources/shared_libs/plays/sheet-filter.ts +347 -0
- package/dist/bundling-sources/shared_libs/plays/slack-hitl-timeout-error.ts +37 -0
- package/dist/bundling-sources/shared_libs/plays/standard-webhooks.ts +117 -0
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +6 -1
- package/dist/bundling-sources/shared_libs/plays/status-result.ts +388 -0
- package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/transform-factor-structure.ts +377 -0
- package/dist/bundling-sources/shared_libs/plays/webhook-payload.ts +113 -0
- package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +7 -1
- package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +3 -2
- package/dist/bundling-sources/shared_libs/product-notifications/overflow.ts +18 -0
- package/dist/bundling-sources/shared_libs/product-notifications/rolling-limit.ts +24 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +624 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-payload.ts +140 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-transport.ts +75 -0
- package/dist/bundling-sources/shared_libs/runtime-env.ts +6 -0
- package/dist/bundling-sources/shared_libs/security/email-blacklist.ts +42 -0
- package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +10 -3
- package/dist/bundling-sources/shared_libs/security/slack-sanitize.ts +133 -0
- package/dist/cli/getting-started.d.mts +52 -0
- package/dist/cli/getting-started.d.ts +52 -0
- package/dist/cli/getting-started.js +65 -0
- package/dist/cli/getting-started.mjs +36 -0
- package/dist/cli/index.d.mts +9 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +895 -407
- package/dist/cli/index.mjs +893 -414
- package/dist/{compiler-manifest-DsLbQaew.d.mts → compiler-manifest-x14KL83E.d.mts} +4 -2
- package/dist/{compiler-manifest-DsLbQaew.d.ts → compiler-manifest-x14KL83E.d.ts} +4 -2
- package/dist/index.d.mts +124 -154
- package/dist/index.d.ts +124 -154
- package/dist/index.js +132 -28
- package/dist/index.mjs +132 -28
- package/dist/install-integrity.json +182 -2
- package/dist/monitor-fleet-contract.d.mts +131 -0
- package/dist/monitor-fleet-contract.d.ts +131 -0
- package/dist/monitor-fleet-contract.js +406 -0
- package/dist/monitor-fleet-contract.mjs +367 -0
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/dist/release.d.mts +255 -0
- package/dist/release.d.ts +255 -0
- package/dist/release.js +210 -0
- package/dist/release.mjs +183 -0
- package/package.json +21 -4
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Convex cron roots that an authenticated platform operator may run on
|
|
3
|
+
* demand. Keep this list aligned with `packages/convex/crons.ts`; the catalog
|
|
4
|
+
* check makes a newly added Convex cron fail closed until it joins here.
|
|
5
|
+
*
|
|
6
|
+
* Other scheduler types deliberately are not listed. They need their own
|
|
7
|
+
* narrowly-scoped execution authority (rather than letting a Convex deploy
|
|
8
|
+
* key impersonate GitHub, Vercel, or Inngest).
|
|
9
|
+
*/
|
|
10
|
+
export const MANUALLY_RUNNABLE_CONVEX_CRON_JOB_IDS = [
|
|
11
|
+
'convex.fold-usage-rollups',
|
|
12
|
+
'convex.record-neon-managed-project-usage',
|
|
13
|
+
'convex.cleanup-expired-mcp-oauth-codes',
|
|
14
|
+
'convex.cleanup-expired-analytics-ip2company-cache',
|
|
15
|
+
'convex.cleanup-expired-domain-health-cache',
|
|
16
|
+
'convex.salesforce-oauth-refresh-maintenance',
|
|
17
|
+
'convex.monitor-fleet-convergence-tick',
|
|
18
|
+
'convex.provider-monitor-global-audit-daily',
|
|
19
|
+
'convex.recover-notification-delivery-work',
|
|
20
|
+
'convex.cleanup-expired-notification-audit-records',
|
|
21
|
+
'convex.fail-stale-play-deployments',
|
|
22
|
+
] as const;
|
|
23
|
+
|
|
24
|
+
export type ManuallyRunnableConvexCronJobId =
|
|
25
|
+
(typeof MANUALLY_RUNNABLE_CONVEX_CRON_JOB_IDS)[number];
|
|
26
|
+
|
|
27
|
+
const manuallyRunnableConvexCronJobIds = new Set<string>(
|
|
28
|
+
MANUALLY_RUNNABLE_CONVEX_CRON_JOB_IDS,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
export function isManuallyRunnableConvexCronJob(
|
|
32
|
+
jobId: string,
|
|
33
|
+
): jobId is ManuallyRunnableConvexCronJobId {
|
|
34
|
+
return manuallyRunnableConvexCronJobIds.has(jobId);
|
|
35
|
+
}
|
|
@@ -10,6 +10,7 @@ export type ScheduledWorkScheduler =
|
|
|
10
10
|
| 'vercel_cron';
|
|
11
11
|
|
|
12
12
|
export type ScheduledWorkOutcome = 'running' | 'succeeded' | 'failed';
|
|
13
|
+
export type ScheduledWorkTrigger = 'scheduled' | 'manual';
|
|
13
14
|
|
|
14
15
|
export type ScheduledWorkVolume = {
|
|
15
16
|
unit: string;
|
|
@@ -34,6 +35,7 @@ export type ScheduledWorkObservation = {
|
|
|
34
35
|
occurredAt: number;
|
|
35
36
|
outcome: ScheduledWorkOutcome;
|
|
36
37
|
expectedWithinMs: number;
|
|
38
|
+
trigger?: ScheduledWorkTrigger;
|
|
37
39
|
durationMs?: number;
|
|
38
40
|
errorSummary?: string;
|
|
39
41
|
runUrl?: string;
|
|
@@ -53,6 +55,9 @@ export function scheduledWorkTelemetryFields(
|
|
|
53
55
|
scheduledWorkOutcome: observation.outcome,
|
|
54
56
|
scheduledWorkInvocationId: observation.invocationId,
|
|
55
57
|
scheduledWorkExpectedWithinMs: observation.expectedWithinMs,
|
|
58
|
+
...(observation.trigger === undefined
|
|
59
|
+
? {}
|
|
60
|
+
: { scheduledWorkTrigger: observation.trigger }),
|
|
56
61
|
...(observation.durationMs === undefined
|
|
57
62
|
? {}
|
|
58
63
|
: { scheduledWorkDurationMs: observation.durationMs }),
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Shared tenant data-plane topology and database role names. */
|
|
2
|
+
export const TENANT_DATA_PLANE_TOPOLOGY = 'project_per_org';
|
|
3
|
+
|
|
4
|
+
export const TENANT_OWNER_ROLE_NAME = 'dl_platform_owner';
|
|
5
|
+
export const TENANT_RUNTIME_ROLE_NAME = 'dl_platform_runtime';
|
|
6
|
+
export const TENANT_READ_ROLE_NAME = 'dl_tenant_read';
|
|
7
|
+
export const TENANT_OVERRIDE_ROLE_NAME = 'dl_tenant_override';
|
|
8
|
+
|
|
9
|
+
export const TENANT_BASELINE_SCHEMA_VERSION = 1;
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import {
|
|
2
|
+
S3Client,
|
|
3
|
+
PutObjectCommand,
|
|
4
|
+
GetObjectCommand,
|
|
5
|
+
HeadObjectCommand,
|
|
6
|
+
} from '@aws-sdk/client-s3';
|
|
7
|
+
import { NodeHttpHandler } from '@smithy/node-http-handler';
|
|
8
|
+
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
9
|
+
import { Agent as HttpsAgent } from 'node:https';
|
|
10
|
+
import { isBuildContext } from '../observability/build-context';
|
|
11
|
+
|
|
12
|
+
type R2PresignerClient = Parameters<typeof getSignedUrl>[0];
|
|
13
|
+
type R2PresignerCommand = Parameters<typeof getSignedUrl>[1];
|
|
14
|
+
|
|
15
|
+
export type R2BucketKind = 'default' | 'playArtifacts';
|
|
16
|
+
|
|
17
|
+
const PLAY_ARTIFACT_BUCKETS = {
|
|
18
|
+
dev: 'plays-artifacts-v1-dev',
|
|
19
|
+
prod: 'plays-artifacts-v1-prod',
|
|
20
|
+
} as const;
|
|
21
|
+
|
|
22
|
+
function requireEnv(name: string): string {
|
|
23
|
+
const value = process.env[name]?.trim();
|
|
24
|
+
if (!value) {
|
|
25
|
+
throw new Error(`Missing ${name}`);
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function getRuntimeEnv(): keyof typeof PLAY_ARTIFACT_BUCKETS {
|
|
31
|
+
const candidates = [
|
|
32
|
+
process.env.DEEPLINE_ENV,
|
|
33
|
+
process.env.VERCEL_ENV,
|
|
34
|
+
process.env.NODE_ENV,
|
|
35
|
+
]
|
|
36
|
+
.filter(Boolean)
|
|
37
|
+
.map((value) => String(value).trim().toLowerCase());
|
|
38
|
+
|
|
39
|
+
for (const value of candidates) {
|
|
40
|
+
if (value === 'production' || value === 'prod' || value === 'live') {
|
|
41
|
+
return 'prod';
|
|
42
|
+
}
|
|
43
|
+
if (
|
|
44
|
+
value === 'development' ||
|
|
45
|
+
value === 'dev' ||
|
|
46
|
+
value === 'preview' ||
|
|
47
|
+
value === 'staging' ||
|
|
48
|
+
value === 'stage' ||
|
|
49
|
+
value === 'test'
|
|
50
|
+
) {
|
|
51
|
+
return 'dev';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return 'dev';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function resolveBucket(kind: R2BucketKind): string {
|
|
59
|
+
if (kind === 'playArtifacts') {
|
|
60
|
+
return PLAY_ARTIFACT_BUCKETS[getRuntimeEnv()];
|
|
61
|
+
}
|
|
62
|
+
return requireEnv('CLOUDFLARE_R2_BUCKET_NAME');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function getR2Config(kind: R2BucketKind = 'default') {
|
|
66
|
+
return {
|
|
67
|
+
endpoint: requireEnv('CLOUDFLARE_R2_ENDPOINT'),
|
|
68
|
+
accessKeyId: requireEnv('CLOUDFLARE_R2_ACCESS_KEY_ID'),
|
|
69
|
+
secretAccessKey: requireEnv('CLOUDFLARE_R2_SECRET_ACCESS_KEY'),
|
|
70
|
+
bucket: resolveBucket(kind),
|
|
71
|
+
publicUrl: requireEnv('CLOUDFLARE_R2_PUBLIC_URL'),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function createR2Client(
|
|
76
|
+
config: ReturnType<typeof getR2Config>,
|
|
77
|
+
): S3Client {
|
|
78
|
+
return new S3Client({
|
|
79
|
+
region: 'auto',
|
|
80
|
+
endpoint: config.endpoint,
|
|
81
|
+
credentials: {
|
|
82
|
+
accessKeyId: config.accessKeyId,
|
|
83
|
+
secretAccessKey: config.secretAccessKey,
|
|
84
|
+
},
|
|
85
|
+
requestHandler: new NodeHttpHandler({
|
|
86
|
+
httpsAgent: new HttpsAgent({
|
|
87
|
+
keepAlive: true,
|
|
88
|
+
maxSockets: 64,
|
|
89
|
+
}),
|
|
90
|
+
}),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const r2ClientMemo = new Map<string, S3Client>();
|
|
95
|
+
|
|
96
|
+
function getR2Client(config: ReturnType<typeof getR2Config>): S3Client {
|
|
97
|
+
const key = `${config.endpoint}|${config.bucket}|${config.accessKeyId}`;
|
|
98
|
+
const existing = r2ClientMemo.get(key);
|
|
99
|
+
if (existing) {
|
|
100
|
+
return existing;
|
|
101
|
+
}
|
|
102
|
+
const client = createR2Client(config);
|
|
103
|
+
r2ClientMemo.set(key, client);
|
|
104
|
+
return client;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function logR2Perf(
|
|
108
|
+
operation: string,
|
|
109
|
+
key: string,
|
|
110
|
+
startedAt: number,
|
|
111
|
+
extra: Record<string, unknown> = {},
|
|
112
|
+
) {
|
|
113
|
+
// `[perf][r2]` fires on every object op; during the prebuilt-artifact build it
|
|
114
|
+
// floods the log. Keep it at runtime (Axiom) but silence it in the build.
|
|
115
|
+
if (isBuildContext()) return;
|
|
116
|
+
console.info('[perf][r2]', {
|
|
117
|
+
operation,
|
|
118
|
+
key,
|
|
119
|
+
ms: Date.now() - startedAt,
|
|
120
|
+
...extra,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export async function r2ObjectExists(
|
|
125
|
+
key: string,
|
|
126
|
+
kind: R2BucketKind = 'default',
|
|
127
|
+
): Promise<boolean> {
|
|
128
|
+
const startedAt = Date.now();
|
|
129
|
+
const config = getR2Config(kind);
|
|
130
|
+
const client = getR2Client(config);
|
|
131
|
+
try {
|
|
132
|
+
await client.send(
|
|
133
|
+
new HeadObjectCommand({
|
|
134
|
+
Bucket: config.bucket,
|
|
135
|
+
Key: key,
|
|
136
|
+
}),
|
|
137
|
+
);
|
|
138
|
+
logR2Perf('head', key, startedAt, { kind, exists: true });
|
|
139
|
+
return true;
|
|
140
|
+
} catch {
|
|
141
|
+
logR2Perf('head', key, startedAt, { kind, exists: false });
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export async function uploadBufferToR2(input: {
|
|
147
|
+
key: string;
|
|
148
|
+
body: Buffer | Uint8Array;
|
|
149
|
+
contentType: string;
|
|
150
|
+
bucketKind?: R2BucketKind;
|
|
151
|
+
}): Promise<string> {
|
|
152
|
+
const startedAt = Date.now();
|
|
153
|
+
const bucketKind = input.bucketKind ?? 'default';
|
|
154
|
+
const configStartedAt = Date.now();
|
|
155
|
+
const config = getR2Config(bucketKind);
|
|
156
|
+
logR2Perf('config', input.key, configStartedAt, { kind: bucketKind });
|
|
157
|
+
const clientStartedAt = Date.now();
|
|
158
|
+
const client = getR2Client(config);
|
|
159
|
+
logR2Perf('client', input.key, clientStartedAt, { kind: bucketKind });
|
|
160
|
+
|
|
161
|
+
const sendStartedAt = Date.now();
|
|
162
|
+
await client.send(
|
|
163
|
+
new PutObjectCommand({
|
|
164
|
+
Bucket: config.bucket,
|
|
165
|
+
Key: input.key,
|
|
166
|
+
Body:
|
|
167
|
+
input.body instanceof Buffer ? new Uint8Array(input.body) : input.body,
|
|
168
|
+
ContentType: input.contentType,
|
|
169
|
+
}),
|
|
170
|
+
);
|
|
171
|
+
logR2Perf('put-send', input.key, sendStartedAt, {
|
|
172
|
+
kind: bucketKind,
|
|
173
|
+
bytes: input.body.byteLength,
|
|
174
|
+
});
|
|
175
|
+
logR2Perf('put', input.key, startedAt, {
|
|
176
|
+
kind: bucketKind,
|
|
177
|
+
bytes: input.body.byteLength,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
if (bucketKind === 'playArtifacts') {
|
|
181
|
+
return `r2://${config.bucket}/${input.key}`;
|
|
182
|
+
}
|
|
183
|
+
return `${config.publicUrl.replace(/\/+$/, '')}/${input.key}`;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export async function getBufferFromR2(
|
|
187
|
+
key: string,
|
|
188
|
+
kind: R2BucketKind = 'default',
|
|
189
|
+
): Promise<Buffer> {
|
|
190
|
+
const startedAt = Date.now();
|
|
191
|
+
const config = getR2Config(kind);
|
|
192
|
+
const client = getR2Client(config);
|
|
193
|
+
|
|
194
|
+
const response = await client.send(
|
|
195
|
+
new GetObjectCommand({
|
|
196
|
+
Bucket: config.bucket,
|
|
197
|
+
Key: key,
|
|
198
|
+
}),
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const bytes = await response.Body!.transformToByteArray();
|
|
202
|
+
logR2Perf('get', key, startedAt, { kind, bytes: bytes.byteLength });
|
|
203
|
+
return Buffer.from(bytes);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export async function createSignedR2ReadUrl(input: {
|
|
207
|
+
key: string;
|
|
208
|
+
kind?: R2BucketKind;
|
|
209
|
+
expiresInSeconds: number;
|
|
210
|
+
}): Promise<{ url: string; expiresAt: string }> {
|
|
211
|
+
const startedAt = Date.now();
|
|
212
|
+
const kind = input.kind ?? 'default';
|
|
213
|
+
const config = getR2Config(kind);
|
|
214
|
+
const client = createR2Client(config);
|
|
215
|
+
const expiresInSeconds = Math.max(1, Math.floor(input.expiresInSeconds));
|
|
216
|
+
const command = new GetObjectCommand({
|
|
217
|
+
Bucket: config.bucket,
|
|
218
|
+
Key: input.key,
|
|
219
|
+
});
|
|
220
|
+
const url = await getSignedUrl(
|
|
221
|
+
client as R2PresignerClient,
|
|
222
|
+
command as R2PresignerCommand,
|
|
223
|
+
{ expiresIn: expiresInSeconds },
|
|
224
|
+
);
|
|
225
|
+
logR2Perf('sign-get', input.key, startedAt, {
|
|
226
|
+
kind,
|
|
227
|
+
expiresInSeconds,
|
|
228
|
+
});
|
|
229
|
+
return {
|
|
230
|
+
url,
|
|
231
|
+
expiresAt: new Date(Date.now() + expiresInSeconds * 1000).toISOString(),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Mint a short-lived presigned PUT URL so a client can upload an object body
|
|
237
|
+
* straight to R2, bypassing the serverless request-body ceiling that a proxied
|
|
238
|
+
* upload through the Next.js route would hit.
|
|
239
|
+
*
|
|
240
|
+
* The URL signs `ContentType`, so the caller MUST send a matching
|
|
241
|
+
* `Content-Type` header on the PUT for the signature to validate.
|
|
242
|
+
*/
|
|
243
|
+
export async function createSignedR2WriteUrl(input: {
|
|
244
|
+
key: string;
|
|
245
|
+
kind?: R2BucketKind;
|
|
246
|
+
contentType: string;
|
|
247
|
+
expiresInSeconds: number;
|
|
248
|
+
}): Promise<{ url: string; expiresAt: string }> {
|
|
249
|
+
const startedAt = Date.now();
|
|
250
|
+
const kind = input.kind ?? 'default';
|
|
251
|
+
const config = getR2Config(kind);
|
|
252
|
+
const client = createR2Client(config);
|
|
253
|
+
const expiresInSeconds = Math.max(1, Math.floor(input.expiresInSeconds));
|
|
254
|
+
const command = new PutObjectCommand({
|
|
255
|
+
Bucket: config.bucket,
|
|
256
|
+
Key: input.key,
|
|
257
|
+
ContentType: input.contentType,
|
|
258
|
+
});
|
|
259
|
+
const url = await getSignedUrl(
|
|
260
|
+
client as R2PresignerClient,
|
|
261
|
+
command as R2PresignerCommand,
|
|
262
|
+
{ expiresIn: expiresInSeconds },
|
|
263
|
+
);
|
|
264
|
+
logR2Perf('sign-put', input.key, startedAt, {
|
|
265
|
+
kind,
|
|
266
|
+
expiresInSeconds,
|
|
267
|
+
});
|
|
268
|
+
return {
|
|
269
|
+
url,
|
|
270
|
+
expiresAt: new Date(Date.now() + expiresInSeconds * 1000).toISOString(),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
@@ -198,6 +198,13 @@ type RuntimeApiRequest =
|
|
|
198
198
|
workflowId: string;
|
|
199
199
|
runId: string;
|
|
200
200
|
workflowFamilyKey: string;
|
|
201
|
+
/** Optional for root and older durable admission envelopes. */
|
|
202
|
+
parentRunId?: string | null;
|
|
203
|
+
rootRunId?: string | null;
|
|
204
|
+
asyncLaunchKey?: string | null;
|
|
205
|
+
asyncInvocationKey?: string | null;
|
|
206
|
+
asyncRequestFingerprint?: string | null;
|
|
207
|
+
asyncAncestryPlayIds?: string[] | null;
|
|
201
208
|
definitionScope?: 'org' | 'system';
|
|
202
209
|
revisionId?: string | null;
|
|
203
210
|
artifactStorageKey?: string | null;
|
|
@@ -235,7 +242,7 @@ type RuntimeApiRequest =
|
|
|
235
242
|
sheetContract?: PlaySheetContract | null;
|
|
236
243
|
contractSnapshot?: unknown;
|
|
237
244
|
runId: string;
|
|
238
|
-
userEmail
|
|
245
|
+
userEmail?: string | null;
|
|
239
246
|
updates: Array<Omit<PlayRowUpdate, 'rowId'> & { runId?: string }>;
|
|
240
247
|
}
|
|
241
248
|
| {
|
|
@@ -592,6 +599,17 @@ function isRetryableAppRuntimeResponse(input: {
|
|
|
592
599
|
) {
|
|
593
600
|
return true;
|
|
594
601
|
}
|
|
602
|
+
// Convex can deploy the projector before the Vercel app knows this action.
|
|
603
|
+
// That old app returns this exact unstructured 403. The projection is
|
|
604
|
+
// idempotent and the outbox keeps its delivery receipt, so retrying bridges
|
|
605
|
+
// the release skew without classifying real executor authorization failures
|
|
606
|
+
// as transient.
|
|
607
|
+
if (
|
|
608
|
+
input.action === 'project_run_created' &&
|
|
609
|
+
isLegacyProjectRunCreatedUnsupportedActionResponse(input)
|
|
610
|
+
) {
|
|
611
|
+
return true;
|
|
612
|
+
}
|
|
595
613
|
// The app runtime may explicitly classify an otherwise-client-error status
|
|
596
614
|
// as transient. Keep the structured delivery contract authoritative rather
|
|
597
615
|
// than reducing every 4xx to permanent at the worker boundary.
|
|
@@ -610,6 +628,32 @@ function isRetryableAppRuntimeResponse(input: {
|
|
|
610
628
|
return isRetryableAppRuntimeResponseStatus(input.status);
|
|
611
629
|
}
|
|
612
630
|
|
|
631
|
+
/**
|
|
632
|
+
* The pre-reader app returns this one precise response for an action it does
|
|
633
|
+
* not yet know. Do not use a substring match here: an authorization failure
|
|
634
|
+
* that merely repeats the phrase must remain terminal and reach an operator.
|
|
635
|
+
*/
|
|
636
|
+
function isLegacyProjectRunCreatedUnsupportedActionResponse(input: {
|
|
637
|
+
status: number;
|
|
638
|
+
body: string;
|
|
639
|
+
}): boolean {
|
|
640
|
+
if (input.status !== 403) return false;
|
|
641
|
+
const expected = 'Unsupported runtime action capability scope.';
|
|
642
|
+
try {
|
|
643
|
+
const parsed = JSON.parse(input.body) as unknown;
|
|
644
|
+
return (
|
|
645
|
+
!!parsed &&
|
|
646
|
+
typeof parsed === 'object' &&
|
|
647
|
+
!Array.isArray(parsed) &&
|
|
648
|
+
(parsed as { error?: unknown }).error === expected
|
|
649
|
+
);
|
|
650
|
+
} catch {
|
|
651
|
+
// The oldest route can return the bare legacy message. Retain that bridge
|
|
652
|
+
// while keeping it exact rather than accepting an arbitrary 403 body.
|
|
653
|
+
return input.body.trim() === expected;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
613
657
|
function appRuntimeExplicitRetryable(body: string): boolean | null {
|
|
614
658
|
try {
|
|
615
659
|
const parsed = JSON.parse(body) as unknown;
|
|
@@ -762,6 +806,7 @@ function isRetryableAppRuntimeAction(
|
|
|
762
806
|
action === 'rate_state_release' ||
|
|
763
807
|
action === 'rate_state_penalize' ||
|
|
764
808
|
action === 'record_first_claim_latency' ||
|
|
809
|
+
action === 'project_run_created' ||
|
|
765
810
|
action === 'release_runtime_step_receipt' ||
|
|
766
811
|
action === 'save_results' ||
|
|
767
812
|
action === 'skip_runtime_step_receipt' ||
|
|
@@ -95,11 +95,26 @@ export type AsyncOperationContractWire = {
|
|
|
95
95
|
* status. This rule applies only to that launch response; unknown poll
|
|
96
96
|
* responses still use terminal.defaultOutcome.
|
|
97
97
|
*/
|
|
98
|
-
launch?: {
|
|
98
|
+
launch?: {
|
|
99
|
+
unclassifiedJobOutcome: 'running';
|
|
100
|
+
/** Ask this start action for its handle instead of its legacy sync result. */
|
|
101
|
+
preferAsync?: boolean;
|
|
102
|
+
};
|
|
99
103
|
job: { idPaths: readonly string[] };
|
|
100
104
|
polling: {
|
|
101
105
|
initialDelayMs: number;
|
|
102
106
|
intervalMs: number;
|
|
107
|
+
/**
|
|
108
|
+
* The longest one provider status/result read may wait when the caller
|
|
109
|
+
* owns the lifecycle. This is deliberately separate from the complete
|
|
110
|
+
* job timeout: a Play fan-out must release its transport slot promptly
|
|
111
|
+
* and let the next invocation perform the next check.
|
|
112
|
+
*
|
|
113
|
+
* Provider adapters translate this generic budget into their native
|
|
114
|
+
* long-poll parameter when they have one. Omit it when a poll endpoint
|
|
115
|
+
* already returns immediately.
|
|
116
|
+
*/
|
|
117
|
+
checkTimeoutMs?: number;
|
|
103
118
|
/** Optional public start-input field that overrides intervalMs for this call. */
|
|
104
119
|
intervalInputField?: string;
|
|
105
120
|
backoffMultiplier?: number;
|
|
@@ -128,6 +143,14 @@ export type AsyncOperationContractWire = {
|
|
|
128
143
|
};
|
|
129
144
|
|
|
130
145
|
export type AsyncOperationContract = AsyncOperationContractWire;
|
|
146
|
+
/**
|
|
147
|
+
* Runtime projection for one lifecycle companion action. This is the single
|
|
148
|
+
* cadence fact a provider adapter receives; it does not expose a provider
|
|
149
|
+
* handle or make a result receipt into provider-job state.
|
|
150
|
+
*/
|
|
151
|
+
export type AsyncOperationPollExecution = {
|
|
152
|
+
checkTimeoutMs: number;
|
|
153
|
+
};
|
|
131
154
|
export type AsyncActionFlowCompatibilityProjection = {
|
|
132
155
|
pollActions: readonly string[];
|
|
133
156
|
finishAction?: string;
|
|
@@ -261,6 +284,12 @@ export function defineAsyncOperation(
|
|
|
261
284
|
nonNegativeInteger(contract.polling.initialDelayMs, 'polling.initialDelayMs');
|
|
262
285
|
positiveInteger(contract.polling.intervalMs, 'polling.intervalMs');
|
|
263
286
|
positiveInteger(contract.polling.timeoutMs, 'polling.timeoutMs');
|
|
287
|
+
if (contract.polling.checkTimeoutMs !== undefined) {
|
|
288
|
+
positiveInteger(
|
|
289
|
+
contract.polling.checkTimeoutMs,
|
|
290
|
+
'polling.checkTimeoutMs',
|
|
291
|
+
);
|
|
292
|
+
}
|
|
264
293
|
if (contract.polling.intervalInputField !== undefined) {
|
|
265
294
|
required(contract.polling.intervalInputField, 'polling.intervalInputField');
|
|
266
295
|
}
|
|
@@ -406,6 +435,17 @@ export function defineCallerManagedAsyncOperation(input: {
|
|
|
406
435
|
pollActions: readonly string[];
|
|
407
436
|
finishAction?: string;
|
|
408
437
|
jobIdPaths?: readonly string[];
|
|
438
|
+
/**
|
|
439
|
+
* The provider has an explicit asynchronous launch path. A Play will receive
|
|
440
|
+
* its job handle immediately and own subsequent polling.
|
|
441
|
+
*/
|
|
442
|
+
preferAsyncStart?: boolean;
|
|
443
|
+
/**
|
|
444
|
+
* Bound one provider-side status/result check for Plays. The default keeps
|
|
445
|
+
* large fan-outs nonblocking while direct SDK and CLI calls retain their
|
|
446
|
+
* provider-specific behavior.
|
|
447
|
+
*/
|
|
448
|
+
checkTimeoutMs?: number;
|
|
409
449
|
/**
|
|
410
450
|
* Preserve an existing public asyncGetAction, or pass null when the legacy
|
|
411
451
|
* action exposed only asyncFlow metadata.
|
|
@@ -431,6 +471,14 @@ export function defineCallerManagedAsyncOperation(input: {
|
|
|
431
471
|
? { finishAction: companion(input.finishAction) }
|
|
432
472
|
: {}),
|
|
433
473
|
},
|
|
474
|
+
...(input.preferAsyncStart
|
|
475
|
+
? {
|
|
476
|
+
launch: {
|
|
477
|
+
unclassifiedJobOutcome: 'running' as const,
|
|
478
|
+
preferAsync: true,
|
|
479
|
+
},
|
|
480
|
+
}
|
|
481
|
+
: {}),
|
|
434
482
|
job: {
|
|
435
483
|
idPaths: input.jobIdPaths ?? [
|
|
436
484
|
'job_id',
|
|
@@ -446,6 +494,7 @@ export function defineCallerManagedAsyncOperation(input: {
|
|
|
446
494
|
polling: {
|
|
447
495
|
initialDelayMs: 0,
|
|
448
496
|
intervalMs: 1_000,
|
|
497
|
+
checkTimeoutMs: input.checkTimeoutMs ?? 1_000,
|
|
449
498
|
timeoutMs: 15 * 60_000,
|
|
450
499
|
},
|
|
451
500
|
terminal: {
|
|
@@ -462,6 +511,22 @@ export function defineCallerManagedAsyncOperation(input: {
|
|
|
462
511
|
});
|
|
463
512
|
}
|
|
464
513
|
|
|
514
|
+
/**
|
|
515
|
+
* Project the generic caller-managed cadence onto each polling companion.
|
|
516
|
+
* `always` and `input_flag` operations execute their complete lifecycle at
|
|
517
|
+
* the API boundary, so exposing a bounded companion policy for them would be
|
|
518
|
+
* misleading.
|
|
519
|
+
*/
|
|
520
|
+
export function projectAsyncOperationPollExecution(
|
|
521
|
+
contract: AsyncOperationContractWire,
|
|
522
|
+
): AsyncOperationPollExecution | null {
|
|
523
|
+
if (contract.wait.kind !== 'caller_managed') return null;
|
|
524
|
+
return {
|
|
525
|
+
checkTimeoutMs:
|
|
526
|
+
contract.polling.checkTimeoutMs ?? contract.polling.intervalMs,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
|
|
465
530
|
export function asyncOperationCompanionActions(
|
|
466
531
|
contract: AsyncOperationContract,
|
|
467
532
|
): string[] {
|
|
@@ -42,7 +42,6 @@ export function assertAsyncPlayInvocation(input: {
|
|
|
42
42
|
`${CTX_RUN_PLAY_ASYNC_DATASET_UNSUPPORTED}: ctx.runPlayAsync("${childPlayName}") launches one independent scalar or HITL Play Run, but the target owns ctx.dataset(), ctx.csv(), or a Runtime Sheet. Keep batch work in its top-level Play or extract a scalar per-record child.`,
|
|
43
43
|
);
|
|
44
44
|
}
|
|
45
|
-
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
/** Admit a child against the persisted root-to-parent Play lineage. */
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineBatchStrategyMap,
|
|
3
|
+
type BatchOperationStrategy,
|
|
4
|
+
} from './batching-types';
|
|
5
|
+
|
|
6
|
+
type Single = {
|
|
7
|
+
email: string;
|
|
8
|
+
mode?: 'regular' | 'deepverify';
|
|
9
|
+
disable_catchall_verify?: '0' | '1';
|
|
10
|
+
url?: string;
|
|
11
|
+
};
|
|
12
|
+
type Bulk = Omit<Single, 'email'> & { emails: string[] };
|
|
13
|
+
type Verdict = Record<string, unknown> & { email: string; status?: string };
|
|
14
|
+
type Results = { items?: Verdict[]; data?: { items?: Verdict[] } };
|
|
15
|
+
|
|
16
|
+
function options(payload: Single) {
|
|
17
|
+
return {
|
|
18
|
+
mode: payload.mode ?? 'regular',
|
|
19
|
+
disable_catchall_verify: payload.disable_catchall_verify ?? '0',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function bucket(payload: Single) {
|
|
23
|
+
// Single and bulk webhook payloads differ. Do not batch webhook callers.
|
|
24
|
+
return JSON.stringify([options(payload), payload.url ?? null]);
|
|
25
|
+
}
|
|
26
|
+
function emailKey(email: string) {
|
|
27
|
+
return email.trim().toLowerCase();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const bouncebanVerifyBatchStrategy: BatchOperationStrategy<
|
|
31
|
+
Single,
|
|
32
|
+
Bulk | Single,
|
|
33
|
+
Results,
|
|
34
|
+
{ data: Verdict }
|
|
35
|
+
> = {
|
|
36
|
+
sourceOperation: 'bounceban_verify_single',
|
|
37
|
+
batchOperation: 'bounceban_verify_bulk',
|
|
38
|
+
kind: 'async_dataset_job',
|
|
39
|
+
// The async finish action retrieves at most 100 emails per request.
|
|
40
|
+
maxBatchSize: 100,
|
|
41
|
+
bucketKeyPayloadFields: ['mode', 'disable_catchall_verify', 'url'],
|
|
42
|
+
canBatchWith(left, right) {
|
|
43
|
+
return !left.url && !right.url && bucket(left) === bucket(right);
|
|
44
|
+
},
|
|
45
|
+
toBucketKey: bucket,
|
|
46
|
+
toItemKey: (payload) => emailKey(payload.email),
|
|
47
|
+
compile(payloads) {
|
|
48
|
+
const first = payloads[0];
|
|
49
|
+
if (payloads.length === 1 && first) {
|
|
50
|
+
return {
|
|
51
|
+
batchOperation: 'bounceban_verify_single',
|
|
52
|
+
batchPayload: first,
|
|
53
|
+
items: [{ itemKey: emailKey(first.email), payload: first }],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (
|
|
57
|
+
!first ||
|
|
58
|
+
payloads.length > 100 ||
|
|
59
|
+
payloads.some((p) => p.url || bucket(p) !== bucket(first))
|
|
60
|
+
) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
'BounceBan batch requires 1–100 emails with matching verification options and no webhooks.',
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
batchOperation: 'bounceban_verify_bulk',
|
|
67
|
+
batchPayload: {
|
|
68
|
+
emails: [...new Set(payloads.map((p) => emailKey(p.email)))],
|
|
69
|
+
...options(first),
|
|
70
|
+
},
|
|
71
|
+
items: payloads.map((payload) => ({
|
|
72
|
+
itemKey: emailKey(payload.email),
|
|
73
|
+
payload,
|
|
74
|
+
})),
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
splitResult(fullResult, compiled) {
|
|
78
|
+
if (compiled.batchOperation === 'bounceban_verify_single') {
|
|
79
|
+
const row = (fullResult.data ?? fullResult) as Verdict;
|
|
80
|
+
if (
|
|
81
|
+
row.status !== 'success' ||
|
|
82
|
+
typeof row.email !== 'string' ||
|
|
83
|
+
emailKey(row.email) !== compiled.items[0]?.itemKey ||
|
|
84
|
+
!['deliverable', 'undeliverable', 'risky', 'unknown'].includes(
|
|
85
|
+
String(row.result),
|
|
86
|
+
)
|
|
87
|
+
) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
'BounceBan single verification returned an unfinished or malformed verdict.',
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
return [
|
|
93
|
+
{
|
|
94
|
+
itemKey: compiled.items[0]!.itemKey,
|
|
95
|
+
result: { data: row },
|
|
96
|
+
rawResult: row,
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
const rows = fullResult.items ?? fullResult.data?.items;
|
|
101
|
+
if (!Array.isArray(rows))
|
|
102
|
+
throw new Error('BounceBan bulk verification returned no result list.');
|
|
103
|
+
const byEmail = new Map<string, Verdict>();
|
|
104
|
+
for (const row of rows) {
|
|
105
|
+
if (
|
|
106
|
+
!row ||
|
|
107
|
+
typeof row.email !== 'string' ||
|
|
108
|
+
(row.status !== undefined && row.status !== 'success') ||
|
|
109
|
+
!['deliverable', 'undeliverable', 'risky', 'unknown'].includes(
|
|
110
|
+
String(row.result),
|
|
111
|
+
)
|
|
112
|
+
) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
'BounceBan bulk verification returned an unfinished or malformed verdict.',
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
const key = emailKey(row.email);
|
|
118
|
+
if (byEmail.has(key))
|
|
119
|
+
throw new Error(
|
|
120
|
+
'BounceBan bulk verification returned duplicate verdicts.',
|
|
121
|
+
);
|
|
122
|
+
byEmail.set(key, row);
|
|
123
|
+
}
|
|
124
|
+
return compiled.items.map((item) => {
|
|
125
|
+
const row = byEmail.get(item.itemKey);
|
|
126
|
+
if (!row)
|
|
127
|
+
throw new Error(
|
|
128
|
+
`BounceBan bulk verification omitted a requested email result.`,
|
|
129
|
+
);
|
|
130
|
+
return { itemKey: item.itemKey, result: { data: row }, rawResult: row };
|
|
131
|
+
});
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export const bouncebanBatchStrategies = defineBatchStrategyMap({
|
|
136
|
+
bounceban_verify_single: bouncebanVerifyBatchStrategy,
|
|
137
|
+
});
|