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,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned types for Shareable Play Pages.
|
|
3
|
+
*
|
|
4
|
+
* These types are imported by Convex functions (`packages/convex/playSharePages.ts`),
|
|
5
|
+
* Next.js API routes, and the public landing page. They are the single,
|
|
6
|
+
* bounded contract for everything that crosses the public boundary.
|
|
7
|
+
*
|
|
8
|
+
* See docs/shareable-play-pages-plan.md.
|
|
9
|
+
*/
|
|
10
|
+
// This Module is bundled by Convex through its workspace dependency graph.
|
|
11
|
+
import type { PlayStaticSubstep } from '../static-pipeline';
|
|
12
|
+
|
|
13
|
+
/** SEO indexing posture for a share page or a specific version URL. */
|
|
14
|
+
export type PlayShareSeoIndexing = 'index' | 'noindex';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Generated landing-page copy, tied to one immutable Play Revision.
|
|
18
|
+
*
|
|
19
|
+
* Every field is plain human/agent-readable text. Nothing here may contain
|
|
20
|
+
* provider spend, secrets, raw runtime internals, or unpublished source.
|
|
21
|
+
*/
|
|
22
|
+
export type PlayShareGeneratedCopy = {
|
|
23
|
+
/** Concrete, job-focused landing title. */
|
|
24
|
+
title: string;
|
|
25
|
+
/** One paragraph, plain English. */
|
|
26
|
+
shortDescription: string;
|
|
27
|
+
/** The job the Play performs (jobs-to-be-done). */
|
|
28
|
+
jtbd: string;
|
|
29
|
+
/** 3-5 bullets describing when to reach for this Play. */
|
|
30
|
+
whenToUse: string[];
|
|
31
|
+
/** Concrete required inputs. */
|
|
32
|
+
inputs: string[];
|
|
33
|
+
/** Concrete produced outputs. */
|
|
34
|
+
outputs: string[];
|
|
35
|
+
/** Paste-ready Claude Code/Cursor/Codex instruction. */
|
|
36
|
+
agentPrompt: string;
|
|
37
|
+
/** Explicit, readable summary for LLM ingestion. */
|
|
38
|
+
llmSummary: string;
|
|
39
|
+
/** Search-result title. */
|
|
40
|
+
seoTitle: string;
|
|
41
|
+
/** Search-result description. */
|
|
42
|
+
seoDescription: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** Owner overrides merge over generated copy at read time. */
|
|
46
|
+
export type PlayShareCopyOverrides = Partial<PlayShareGeneratedCopy>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A single node in the bounded pipeline preview. Never includes source code,
|
|
50
|
+
* params, secrets, or provider spend — only a shape and a human label.
|
|
51
|
+
*/
|
|
52
|
+
export type PlaySharePreviewStep = {
|
|
53
|
+
/** Human-readable action, e.g. "search people by domain". */
|
|
54
|
+
label: string;
|
|
55
|
+
/** Provider name backing this step, when known. */
|
|
56
|
+
provider: string | null;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type PlaySharePreviewNode = {
|
|
60
|
+
type:
|
|
61
|
+
| 'csv'
|
|
62
|
+
| 'dataset'
|
|
63
|
+
| 'tool'
|
|
64
|
+
| 'waterfall'
|
|
65
|
+
| 'step_suite'
|
|
66
|
+
| 'control_flow'
|
|
67
|
+
| 'play_call'
|
|
68
|
+
| 'play_launch'
|
|
69
|
+
| 'run_javascript'
|
|
70
|
+
| 'code';
|
|
71
|
+
/** Human-readable label, e.g. "Apollo" or "Dataset rows". */
|
|
72
|
+
label: string;
|
|
73
|
+
/** Optional provider name when this node calls a provider. */
|
|
74
|
+
provider?: string | null;
|
|
75
|
+
/** Optional secondary line, e.g. an input field or step kind. */
|
|
76
|
+
detail?: string | null;
|
|
77
|
+
/** Ordered sub-steps for waterfall / step-suite nodes (bounded). */
|
|
78
|
+
steps?: PlaySharePreviewStep[];
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/** Bounded static-pipeline summary safe for public display. */
|
|
82
|
+
export type PlayShareStaticPipelineSummary = {
|
|
83
|
+
stepCount: number;
|
|
84
|
+
providerCount: number;
|
|
85
|
+
hasMap: boolean;
|
|
86
|
+
previewNodes: PlaySharePreviewNode[];
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/** Bounded, safe representation of the revision's input/output shape. */
|
|
90
|
+
export type PlayShareSchemaShape = {
|
|
91
|
+
fields: string[];
|
|
92
|
+
} | null;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The ONLY object consumed by the public page and the public share API.
|
|
96
|
+
* Everything here is safe to expose to anyone with the unlisted link.
|
|
97
|
+
*/
|
|
98
|
+
export type PublishedPlayPagePackage = {
|
|
99
|
+
page: {
|
|
100
|
+
/** Internal stable record id. Never a public URL — pages are namespaced. */
|
|
101
|
+
shareSlug: string;
|
|
102
|
+
/** Org URL handle; the public page lives at `/p/:orgSlug/:playName`. */
|
|
103
|
+
orgSlug: string;
|
|
104
|
+
visibility: 'unlisted';
|
|
105
|
+
seoIndexing: PlayShareSeoIndexing;
|
|
106
|
+
/** Canonical path, e.g. `/p/:orgSlug/:playName/v/:publishedVersion`. */
|
|
107
|
+
canonicalPath: string;
|
|
108
|
+
/** Whether the requested URL is the currently-published version. */
|
|
109
|
+
isPublishedVersion: boolean;
|
|
110
|
+
/** When this version's public page was last published/updated. */
|
|
111
|
+
publishedAt: number;
|
|
112
|
+
};
|
|
113
|
+
definition: {
|
|
114
|
+
name: string;
|
|
115
|
+
ownerDisplayName: string | null;
|
|
116
|
+
};
|
|
117
|
+
revision: {
|
|
118
|
+
id: string;
|
|
119
|
+
version: number;
|
|
120
|
+
graphHash: string | null;
|
|
121
|
+
staticPipelineSummary: PlayShareStaticPipelineSummary;
|
|
122
|
+
/** Sanitized top-level substeps for the real v2 step-graph render. */
|
|
123
|
+
substeps: PlayStaticSubstep[];
|
|
124
|
+
inputSchema: PlayShareSchemaShape;
|
|
125
|
+
outputSchema: PlayShareSchemaShape;
|
|
126
|
+
};
|
|
127
|
+
copy: PlayShareGeneratedCopy;
|
|
128
|
+
publicMetrics: PublishedPlayPageMetrics;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Which cost denominator is comparable across runs of different input sizes,
|
|
133
|
+
* derived from the play's map shape. See `classifyCostBasis`.
|
|
134
|
+
*/
|
|
135
|
+
export type PlayCostBasis = 'run' | 'row' | 'none';
|
|
136
|
+
|
|
137
|
+
/** Public, credit-only metrics. Provider spend is never present. */
|
|
138
|
+
export type PublishedPlayPageMetrics = {
|
|
139
|
+
averageDeeplineCostCredits: number | null;
|
|
140
|
+
averageCostPerInputRowCredits: number | null;
|
|
141
|
+
averageCostPerOutputLeadCredits: number | null;
|
|
142
|
+
averageLatencyMs: number | null;
|
|
143
|
+
sampleRunCount: number;
|
|
144
|
+
/**
|
|
145
|
+
* The only cost denominator that is comparable across runs of different input
|
|
146
|
+
* sizes, derived from the play's map shape: `'run'` (flat play), `'row'`
|
|
147
|
+
* (single dataset over input rows), or `'none'` (multiple/nested datasets — no honest
|
|
148
|
+
* denominator, so cost is suppressed). Drives which credit metric the page
|
|
149
|
+
* renders, if any.
|
|
150
|
+
*/
|
|
151
|
+
costBasis: PlayCostBasis;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Authenticated owner view of a share page (returned by GET/POST/PATCH
|
|
156
|
+
* `/api/v2/plays/:name/share`). Includes management metadata not exposed
|
|
157
|
+
* to the public read model.
|
|
158
|
+
*/
|
|
159
|
+
export type PlaySharePageOwnerView = {
|
|
160
|
+
shareSlug: string;
|
|
161
|
+
/** Org URL handle; the public page lives at `/p/:orgSlug/:playName`. */
|
|
162
|
+
orgSlug: string;
|
|
163
|
+
publishedRevisionId: string;
|
|
164
|
+
publishedVersion: number;
|
|
165
|
+
visibility: 'unlisted';
|
|
166
|
+
seoIndexing: PlayShareSeoIndexing;
|
|
167
|
+
showAverageDeeplineCost: boolean;
|
|
168
|
+
showAverageLatency: boolean;
|
|
169
|
+
publicPath: string;
|
|
170
|
+
canonicalPath: string;
|
|
171
|
+
createdAt: number;
|
|
172
|
+
updatedAt: number;
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* One row in the byte-bounded owner-facing version picker. The status response
|
|
177
|
+
* includes recent revisions plus any older working, live, public, or explicitly
|
|
178
|
+
* selected dashboard revision.
|
|
179
|
+
*/
|
|
180
|
+
export type PlaySharePageRevisionOption = {
|
|
181
|
+
revisionId: string;
|
|
182
|
+
version: number;
|
|
183
|
+
hasMap: boolean;
|
|
184
|
+
createdAt: number;
|
|
185
|
+
isLive: boolean;
|
|
186
|
+
isWorking: boolean;
|
|
187
|
+
isPublished: boolean;
|
|
188
|
+
hasCard: boolean;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/** Full payload for GET `/api/v2/plays/:name/share`. */
|
|
192
|
+
export type PlaySharePageStatusResponse = {
|
|
193
|
+
playName: string;
|
|
194
|
+
share: PlaySharePageOwnerView | null;
|
|
195
|
+
publishedCopy: PlayShareGeneratedCopy | null;
|
|
196
|
+
revisions: PlaySharePageRevisionOption[];
|
|
197
|
+
};
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
// Full-table view basic filters. A tiny, deliberately closed predicate model
|
|
2
|
+
// that compiles mechanically to a parameterized SQL WHERE clause against a
|
|
3
|
+
// runtime sheet's physical (jsonb) user-data columns.
|
|
4
|
+
//
|
|
5
|
+
// This is NOT free-text SQL: operators come from a closed enum, columns must
|
|
6
|
+
// be on a caller-supplied allowlist (the sheet's real columns), and every value
|
|
7
|
+
// is bound as a query parameter. Multiple filters AND together. No OR groups.
|
|
8
|
+
//
|
|
9
|
+
// Sheet user-data columns are stored one-per-column as `jsonb` (a JSON scalar
|
|
10
|
+
// like "completed", 19991, or an object). `col #>> '{}'` extracts the scalar as
|
|
11
|
+
// text; numeric comparisons cast that text to numeric.
|
|
12
|
+
|
|
13
|
+
// ── The operator set, and why it grew ────────────────────────────────────────
|
|
14
|
+
//
|
|
15
|
+
// The filter UI is `src/components/data-table-filter` — the repo's shadcn
|
|
16
|
+
// faceted filter, the same one the customer-db grid and the integrations run
|
|
17
|
+
// table use. Its operator vocabulary per column type is fixed by the package,
|
|
18
|
+
// so this enum has to cover it exactly or a filter the user can build is one
|
|
19
|
+
// the server cannot compile.
|
|
20
|
+
//
|
|
21
|
+
// Everything added here is a single clause with a NOT in it, which is precisely
|
|
22
|
+
// what could not be expressed by composing the operators that were already
|
|
23
|
+
// here: this model AND-joins and has no OR groups, so `is not between` cannot
|
|
24
|
+
// be decomposed into two filters. Where a package operator CAN be decomposed it
|
|
25
|
+
// still gets its own entry rather than a rewrite rule, so the payload on the
|
|
26
|
+
// wire reads the same as the chip the user built.
|
|
27
|
+
//
|
|
28
|
+
// `is_empty` / `not_empty` have no operator in the package and are therefore
|
|
29
|
+
// unreachable from the UI. They stay compilable — the API accepts them and an
|
|
30
|
+
// agent can send them — and adding them to the shared package is a deliberate
|
|
31
|
+
// change that has to update every consumer's compiler at the same time.
|
|
32
|
+
export const SHEET_FILTER_TEXT_OPS = [
|
|
33
|
+
'equals',
|
|
34
|
+
'not_equals',
|
|
35
|
+
'contains',
|
|
36
|
+
'not_contains',
|
|
37
|
+
'is_empty',
|
|
38
|
+
'not_empty',
|
|
39
|
+
] as const;
|
|
40
|
+
|
|
41
|
+
export const SHEET_FILTER_NUMERIC_OPS = [
|
|
42
|
+
'gt',
|
|
43
|
+
'lt',
|
|
44
|
+
'gte',
|
|
45
|
+
'lte',
|
|
46
|
+
'num_equals',
|
|
47
|
+
'num_not_equals',
|
|
48
|
+
'between',
|
|
49
|
+
'not_between',
|
|
50
|
+
] as const;
|
|
51
|
+
|
|
52
|
+
export const SHEET_FILTER_OPS = [
|
|
53
|
+
...SHEET_FILTER_TEXT_OPS,
|
|
54
|
+
...SHEET_FILTER_NUMERIC_OPS,
|
|
55
|
+
] as const;
|
|
56
|
+
|
|
57
|
+
export type SheetFilterOp = (typeof SHEET_FILTER_OPS)[number];
|
|
58
|
+
|
|
59
|
+
const SHEET_FILTER_OP_SET: ReadonlySet<string> = new Set(SHEET_FILTER_OPS);
|
|
60
|
+
const SHEET_FILTER_NUMERIC_OP_SET: ReadonlySet<string> = new Set(
|
|
61
|
+
SHEET_FILTER_NUMERIC_OPS,
|
|
62
|
+
);
|
|
63
|
+
// Ops that carry no value (the value input is hidden in the UI).
|
|
64
|
+
const SHEET_FILTER_VALUELESS_OP_SET: ReadonlySet<SheetFilterOp> = new Set([
|
|
65
|
+
'is_empty',
|
|
66
|
+
'not_empty',
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
/** Ops whose `value` is an inclusive `[min, max]` pair rather than a scalar. */
|
|
70
|
+
const SHEET_FILTER_RANGE_OP_SET: ReadonlySet<SheetFilterOp> = new Set([
|
|
71
|
+
'between',
|
|
72
|
+
'not_between',
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
export function isRangeSheetFilterOp(op: SheetFilterOp): boolean {
|
|
76
|
+
return SHEET_FILTER_RANGE_OP_SET.has(op);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type SheetFilter = {
|
|
80
|
+
column: string;
|
|
81
|
+
op: SheetFilterOp;
|
|
82
|
+
/** A scalar for most ops; an inclusive `[min, max]` pair for the range ops
|
|
83
|
+
* (`between`, `not_between`); absent for the valueless ops. */
|
|
84
|
+
value?: unknown;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export type CompiledSheetFilter = {
|
|
88
|
+
/** WHERE-clause body WITHOUT the leading `WHERE` (empty string when no
|
|
89
|
+
* filters). AND-joined; callers combine it with their own conditions. */
|
|
90
|
+
sql: string;
|
|
91
|
+
/** Parameters bound in `$n` order, starting at `startParamIndex`. */
|
|
92
|
+
params: unknown[];
|
|
93
|
+
/** Next free `$n` index after the compiled params. */
|
|
94
|
+
nextParamIndex: number;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export class SheetFilterError extends Error {
|
|
98
|
+
readonly code = 'invalid_sheet_filter';
|
|
99
|
+
constructor(message: string) {
|
|
100
|
+
super(message);
|
|
101
|
+
this.name = 'SheetFilterError';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function isSheetFilterOp(value: unknown): value is SheetFilterOp {
|
|
106
|
+
return typeof value === 'string' && SHEET_FILTER_OP_SET.has(value);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function isNumericSheetFilterOp(op: SheetFilterOp): boolean {
|
|
110
|
+
return SHEET_FILTER_NUMERIC_OP_SET.has(op);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Parse an untrusted `filters` payload (from a query param or request body)
|
|
115
|
+
* into a typed, validated filter list. Throws `SheetFilterError` (→ 400) on any
|
|
116
|
+
* malformed entry so the read path fails loudly rather than silently dropping a
|
|
117
|
+
* predicate.
|
|
118
|
+
*/
|
|
119
|
+
export function parseSheetFilters(raw: unknown): SheetFilter[] {
|
|
120
|
+
if (raw == null || raw === '') return [];
|
|
121
|
+
let value = raw;
|
|
122
|
+
if (typeof value === 'string') {
|
|
123
|
+
try {
|
|
124
|
+
value = JSON.parse(value);
|
|
125
|
+
} catch {
|
|
126
|
+
throw new SheetFilterError('filters must be a JSON array');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (!Array.isArray(value)) {
|
|
130
|
+
throw new SheetFilterError('filters must be a JSON array');
|
|
131
|
+
}
|
|
132
|
+
return value.map((entry, index) => parseSheetFilterEntry(entry, index));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function parseSheetFilterEntry(entry: unknown, index: number): SheetFilter {
|
|
136
|
+
if (entry == null || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
137
|
+
throw new SheetFilterError(`filters[${index}] must be an object`);
|
|
138
|
+
}
|
|
139
|
+
const record = entry as Record<string, unknown>;
|
|
140
|
+
const column = record.column;
|
|
141
|
+
if (typeof column !== 'string' || column.trim() === '') {
|
|
142
|
+
throw new SheetFilterError(
|
|
143
|
+
`filters[${index}].column must be a non-empty string`,
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
const op = record.op;
|
|
147
|
+
if (!isSheetFilterOp(op)) {
|
|
148
|
+
throw new SheetFilterError(
|
|
149
|
+
`filters[${index}].op "${String(op)}" is not a supported operator`,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
return { column: column.trim(), op, value: record.value };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function coerceFilterText(value: unknown, index: number): string {
|
|
156
|
+
if (typeof value === 'string') return value;
|
|
157
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
158
|
+
return String(value);
|
|
159
|
+
}
|
|
160
|
+
throw new SheetFilterError(
|
|
161
|
+
`filters[${index}].value must be a string, number, or boolean`,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const NUMERIC_SQL_OPERATOR: Record<string, string> = {
|
|
166
|
+
gt: '>',
|
|
167
|
+
lt: '<',
|
|
168
|
+
gte: '>=',
|
|
169
|
+
lte: '<=',
|
|
170
|
+
num_equals: '=',
|
|
171
|
+
num_not_equals: '<>',
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
function coerceFilterRange(value: unknown, index: number): [number, number] {
|
|
175
|
+
if (!Array.isArray(value) || value.length !== 2) {
|
|
176
|
+
throw new SheetFilterError(
|
|
177
|
+
`filters[${index}].value must be a [min, max] pair for a range operator`,
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
const min = coerceFilterNumber(value[0], index);
|
|
181
|
+
const max = coerceFilterNumber(value[1], index);
|
|
182
|
+
// Accept either order rather than rejecting it: the filter UI's two number
|
|
183
|
+
// inputs have no opinion about which the user fills first, and a silently
|
|
184
|
+
// empty result is the worse failure here.
|
|
185
|
+
return min <= max ? [min, max] : [max, min];
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function coerceFilterNumber(value: unknown, index: number): number {
|
|
189
|
+
const parsed =
|
|
190
|
+
typeof value === 'number'
|
|
191
|
+
? value
|
|
192
|
+
: typeof value === 'string' && value.trim() !== ''
|
|
193
|
+
? Number(value)
|
|
194
|
+
: NaN;
|
|
195
|
+
if (!Number.isFinite(parsed)) {
|
|
196
|
+
throw new SheetFilterError(
|
|
197
|
+
`filters[${index}].value must be a finite number for the "${'numeric'}" operator`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
return parsed;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Extract a jsonb column's scalar as text: `"completed"` → completed, `19991`
|
|
204
|
+
// → 19991, an object → its JSON text. The single-arg `#>> '{}'` path returns the
|
|
205
|
+
// whole value as text (Postgres jsonb → text).
|
|
206
|
+
function columnAsText(quotedColumn: string): string {
|
|
207
|
+
return `(${quotedColumn} #>> '{}')`;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function quoteIdentifier(value: string): string {
|
|
211
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Compile validated filters against an allowlist of real column names into a
|
|
216
|
+
* parameterized WHERE body. Unknown columns and numeric ops on non-numeric
|
|
217
|
+
* columns throw `SheetFilterError` (→ 400).
|
|
218
|
+
*
|
|
219
|
+
* @param numericColumns Columns whose UI type is numeric; numeric ops are only
|
|
220
|
+
* admitted on these. Text ops work on every allowed column.
|
|
221
|
+
*/
|
|
222
|
+
export function compileSheetFilterWhere(input: {
|
|
223
|
+
filters: readonly SheetFilter[];
|
|
224
|
+
allowedColumns: ReadonlySet<string>;
|
|
225
|
+
numericColumns?: ReadonlySet<string>;
|
|
226
|
+
startParamIndex?: number;
|
|
227
|
+
}): CompiledSheetFilter {
|
|
228
|
+
const startParamIndex = input.startParamIndex ?? 1;
|
|
229
|
+
const numericColumns = input.numericColumns ?? new Set<string>();
|
|
230
|
+
const clauses: string[] = [];
|
|
231
|
+
const params: unknown[] = [];
|
|
232
|
+
let paramIdx = startParamIndex;
|
|
233
|
+
|
|
234
|
+
input.filters.forEach((filter, index) => {
|
|
235
|
+
if (!input.allowedColumns.has(filter.column)) {
|
|
236
|
+
throw new SheetFilterError(
|
|
237
|
+
`filters[${index}].column "${filter.column}" is not a column of this table`,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
const quoted = quoteIdentifier(filter.column);
|
|
241
|
+
const asText = columnAsText(quoted);
|
|
242
|
+
|
|
243
|
+
if (
|
|
244
|
+
isNumericSheetFilterOp(filter.op) &&
|
|
245
|
+
!numericColumns.has(filter.column)
|
|
246
|
+
) {
|
|
247
|
+
throw new SheetFilterError(
|
|
248
|
+
`filters[${index}].op "${filter.op}" is only valid on numeric columns; "${filter.column}" is not numeric`,
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
switch (filter.op) {
|
|
253
|
+
case 'equals': {
|
|
254
|
+
const text = coerceFilterText(filter.value, index);
|
|
255
|
+
clauses.push(`${asText} = $${paramIdx}`);
|
|
256
|
+
params.push(text);
|
|
257
|
+
paramIdx += 1;
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
case 'not_equals': {
|
|
261
|
+
const text = coerceFilterText(filter.value, index);
|
|
262
|
+
// NULL-safe: a NULL/absent cell is "not equal" to a concrete value.
|
|
263
|
+
clauses.push(`(${asText} IS DISTINCT FROM $${paramIdx})`);
|
|
264
|
+
params.push(text);
|
|
265
|
+
paramIdx += 1;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
case 'contains': {
|
|
269
|
+
const text = coerceFilterText(filter.value, index);
|
|
270
|
+
clauses.push(`${asText} ILIKE $${paramIdx}`);
|
|
271
|
+
params.push(`%${escapeLikePattern(text)}%`);
|
|
272
|
+
paramIdx += 1;
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
case 'not_contains': {
|
|
276
|
+
const text = coerceFilterText(filter.value, index);
|
|
277
|
+
// NULL-safe, like `not_equals`: a cell with no value does not contain
|
|
278
|
+
// the needle, and `NOT (NULL ILIKE ...)` is NULL, which filters it out.
|
|
279
|
+
clauses.push(`(${asText} IS NULL OR ${asText} NOT ILIKE $${paramIdx})`);
|
|
280
|
+
params.push(`%${escapeLikePattern(text)}%`);
|
|
281
|
+
paramIdx += 1;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
case 'is_empty': {
|
|
285
|
+
clauses.push(
|
|
286
|
+
`(${quoted} IS NULL OR ${asText} IS NULL OR ${asText} = '')`,
|
|
287
|
+
);
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case 'not_empty': {
|
|
291
|
+
clauses.push(
|
|
292
|
+
`(${quoted} IS NOT NULL AND ${asText} IS NOT NULL AND ${asText} <> '')`,
|
|
293
|
+
);
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
case 'gt':
|
|
297
|
+
case 'lt':
|
|
298
|
+
case 'gte':
|
|
299
|
+
case 'lte':
|
|
300
|
+
case 'num_equals':
|
|
301
|
+
case 'num_not_equals': {
|
|
302
|
+
const num = coerceFilterNumber(filter.value, index);
|
|
303
|
+
const sqlOp = NUMERIC_SQL_OPERATOR[filter.op];
|
|
304
|
+
// Guard the numeric cast to jsonb numbers only, so a stray non-numeric
|
|
305
|
+
// cell can never abort the whole query with a cast error.
|
|
306
|
+
clauses.push(
|
|
307
|
+
`(jsonb_typeof(${quoted}) = 'number' AND ${asText}::numeric ${sqlOp} $${paramIdx})`,
|
|
308
|
+
);
|
|
309
|
+
params.push(num);
|
|
310
|
+
paramIdx += 1;
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
case 'between':
|
|
314
|
+
case 'not_between': {
|
|
315
|
+
const [min, max] = coerceFilterRange(filter.value, index);
|
|
316
|
+
// `BETWEEN` is inclusive on both ends, which is what the filter UI's
|
|
317
|
+
// range control means by it. The guard is the same one the scalar
|
|
318
|
+
// comparisons use: a non-numeric cell simply does not match, rather
|
|
319
|
+
// than aborting the query on a cast.
|
|
320
|
+
const body = `${asText}::numeric BETWEEN $${paramIdx} AND $${paramIdx + 1}`;
|
|
321
|
+
clauses.push(
|
|
322
|
+
`(jsonb_typeof(${quoted}) = 'number' AND ${
|
|
323
|
+
filter.op === 'between' ? body : `NOT (${body})`
|
|
324
|
+
})`,
|
|
325
|
+
);
|
|
326
|
+
params.push(min, max);
|
|
327
|
+
paramIdx += 2;
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
return {
|
|
334
|
+
sql: clauses.join(' AND '),
|
|
335
|
+
params,
|
|
336
|
+
nextParamIndex: paramIdx,
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Escape LIKE/ILIKE metacharacters so a `contains` value is matched literally.
|
|
341
|
+
function escapeLikePattern(value: string): string {
|
|
342
|
+
return value.replace(/([\\%_])/g, '\\$1');
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export function sheetFilterHasValue(op: SheetFilterOp): boolean {
|
|
346
|
+
return !SHEET_FILTER_VALUELESS_OP_SET.has(op);
|
|
347
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ToolExecutionError } from './tool-execution-error';
|
|
2
|
+
|
|
3
|
+
/** Stable code for an unanswered `slack_message_with_hitl` approval. */
|
|
4
|
+
export const SLACK_HITL_TIMEOUT_ERROR_CODE = 'SLACK_HITL_TIMEOUT' as const;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A Slack human-in-the-loop approval reached its deadline without a decision.
|
|
8
|
+
*
|
|
9
|
+
* Deepline first confirms that it replaced the Slack card with “Interaction
|
|
10
|
+
* timed out.” and removed its controls. The error is non-retryable and
|
|
11
|
+
* runner-fatal: an authored `try/catch` may observe it, but cannot settle the
|
|
12
|
+
* Play successfully or start another durable operation. Retry the Play only
|
|
13
|
+
* after changing its input or timeout policy.
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
export class SlackHitlTimeoutError extends ToolExecutionError {
|
|
17
|
+
constructor(message?: string) {
|
|
18
|
+
const detail =
|
|
19
|
+
message?.trim() ||
|
|
20
|
+
'Slack approval timed out before a human decision was received.';
|
|
21
|
+
super(`${SLACK_HITL_TIMEOUT_ERROR_CODE}: ${detail}`, {
|
|
22
|
+
toolId: 'slack_message_with_hitl',
|
|
23
|
+
provider: 'slack',
|
|
24
|
+
operation: 'slack_message_with_hitl',
|
|
25
|
+
code: SLACK_HITL_TIMEOUT_ERROR_CODE,
|
|
26
|
+
origin: 'deepline',
|
|
27
|
+
category: 'conflict',
|
|
28
|
+
retryable: false,
|
|
29
|
+
statusCode: 408,
|
|
30
|
+
requestId: null,
|
|
31
|
+
retryAfterMs: null,
|
|
32
|
+
networkKind: null,
|
|
33
|
+
networkScope: null,
|
|
34
|
+
});
|
|
35
|
+
this.name = 'SlackHitlTimeoutError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import type { PlayStandardWebhookHeaderFamily } from './/authoring-contract';
|
|
3
|
+
|
|
4
|
+
export const DEFAULT_STANDARD_WEBHOOK_TOLERANCE_SECONDS = 300;
|
|
5
|
+
|
|
6
|
+
export type StandardWebhookVerificationFailure =
|
|
7
|
+
| 'missing_headers'
|
|
8
|
+
| 'invalid_event_id'
|
|
9
|
+
| 'invalid_timestamp'
|
|
10
|
+
| 'timestamp_out_of_tolerance'
|
|
11
|
+
| 'invalid_signature'
|
|
12
|
+
| 'invalid_secret';
|
|
13
|
+
|
|
14
|
+
export type StandardWebhookVerification =
|
|
15
|
+
| { ok: true; eventId: string; timestamp: number }
|
|
16
|
+
| { ok: false; reason: StandardWebhookVerificationFailure };
|
|
17
|
+
|
|
18
|
+
function headerNames(headerFamily: PlayStandardWebhookHeaderFamily) {
|
|
19
|
+
return headerFamily === 'svix'
|
|
20
|
+
? {
|
|
21
|
+
id: 'svix-id',
|
|
22
|
+
timestamp: 'svix-timestamp',
|
|
23
|
+
signature: 'svix-signature',
|
|
24
|
+
}
|
|
25
|
+
: {
|
|
26
|
+
id: 'webhook-id',
|
|
27
|
+
timestamp: 'webhook-timestamp',
|
|
28
|
+
signature: 'webhook-signature',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function normalizedHeaders(headers: Record<string, string>) {
|
|
33
|
+
return Object.fromEntries(
|
|
34
|
+
Object.entries(headers).map(([name, value]) => [name.toLowerCase(), value]),
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Standard Webhooks symmetric secrets are base64; providers commonly prefix them with `whsec_`. */
|
|
39
|
+
function decodeSigningSecret(value: string): Buffer | null {
|
|
40
|
+
const serialized = value.trim();
|
|
41
|
+
const encoded = serialized.startsWith('whsec_')
|
|
42
|
+
? serialized.slice('whsec_'.length)
|
|
43
|
+
: serialized;
|
|
44
|
+
if (!encoded || !/^[A-Za-z0-9+/]+={0,2}$/.test(encoded)) return null;
|
|
45
|
+
const unpadded = encoded.replace(/=+$/, '');
|
|
46
|
+
if (unpadded.length % 4 === 1) return null;
|
|
47
|
+
const decoded = Buffer.from(encoded, 'base64');
|
|
48
|
+
return decoded.length > 0 &&
|
|
49
|
+
decoded.toString('base64').replace(/=+$/, '') === unpadded
|
|
50
|
+
? decoded
|
|
51
|
+
: null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function signatureMatches(expected: Buffer, supplied: string): boolean {
|
|
55
|
+
const candidates = supplied.trim().split(/\s+/);
|
|
56
|
+
for (const candidate of candidates) {
|
|
57
|
+
const [version, encoded, ...extra] = candidate.split(',');
|
|
58
|
+
if (version !== 'v1' || !encoded || extra.length > 0) continue;
|
|
59
|
+
if (!/^[A-Za-z0-9+/]+={0,2}$/.test(encoded)) continue;
|
|
60
|
+
const actual = Buffer.from(encoded, 'base64');
|
|
61
|
+
if (actual.length !== expected.length) continue;
|
|
62
|
+
if (timingSafeEqual(expected, actual)) return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Verifies the Standard Webhooks v1 symmetric scheme against the unmodified
|
|
69
|
+
* request body. Call this before admitting any Play Run.
|
|
70
|
+
*/
|
|
71
|
+
export function verifyStandardWebhook(input: {
|
|
72
|
+
headers: Record<string, string>;
|
|
73
|
+
rawBody: string;
|
|
74
|
+
signingSecrets: readonly string[];
|
|
75
|
+
headerFamily: PlayStandardWebhookHeaderFamily;
|
|
76
|
+
toleranceSeconds?: number;
|
|
77
|
+
now?: Date;
|
|
78
|
+
}): StandardWebhookVerification {
|
|
79
|
+
const names = headerNames(input.headerFamily);
|
|
80
|
+
const headers = normalizedHeaders(input.headers);
|
|
81
|
+
const eventId = headers[names.id]?.trim();
|
|
82
|
+
const timestampHeader = headers[names.timestamp]?.trim();
|
|
83
|
+
const signature = headers[names.signature];
|
|
84
|
+
if (!eventId || !timestampHeader || !signature) {
|
|
85
|
+
return { ok: false, reason: 'missing_headers' };
|
|
86
|
+
}
|
|
87
|
+
// A full stop is the signed-content delimiter, so the ID must be unambiguous.
|
|
88
|
+
if (eventId.includes('.')) return { ok: false, reason: 'invalid_event_id' };
|
|
89
|
+
if (!/^\d+$/.test(timestampHeader)) {
|
|
90
|
+
return { ok: false, reason: 'invalid_timestamp' };
|
|
91
|
+
}
|
|
92
|
+
const timestamp = Number(timestampHeader);
|
|
93
|
+
if (!Number.isSafeInteger(timestamp)) {
|
|
94
|
+
return { ok: false, reason: 'invalid_timestamp' };
|
|
95
|
+
}
|
|
96
|
+
const toleranceSeconds =
|
|
97
|
+
input.toleranceSeconds ?? DEFAULT_STANDARD_WEBHOOK_TOLERANCE_SECONDS;
|
|
98
|
+
const nowSeconds = Math.floor((input.now?.getTime() ?? Date.now()) / 1000);
|
|
99
|
+
if (Math.abs(nowSeconds - timestamp) > toleranceSeconds) {
|
|
100
|
+
return { ok: false, reason: 'timestamp_out_of_tolerance' };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const signedContent = `${eventId}.${timestampHeader}.${input.rawBody}`;
|
|
104
|
+
let usableSecret = false;
|
|
105
|
+
for (const secret of input.signingSecrets) {
|
|
106
|
+
const key = decodeSigningSecret(secret);
|
|
107
|
+
if (!key) continue;
|
|
108
|
+
usableSecret = true;
|
|
109
|
+
const expected = createHmac('sha256', key).update(signedContent).digest();
|
|
110
|
+
if (signatureMatches(expected, signature)) {
|
|
111
|
+
return { ok: true, eventId, timestamp };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return usableSecret
|
|
115
|
+
? { ok: false, reason: 'invalid_signature' }
|
|
116
|
+
: { ok: false, reason: 'invalid_secret' };
|
|
117
|
+
}
|