deepline 0.3.88 → 0.3.90

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.
Files changed (280) hide show
  1. package/contracts/install-commands.json +29 -0
  2. package/dist/bundling-sources/sdk/src/client.ts +652 -39
  3. package/dist/bundling-sources/sdk/src/config.ts +77 -0
  4. package/dist/bundling-sources/sdk/src/http.ts +76 -30
  5. package/dist/bundling-sources/sdk/src/index.ts +10 -0
  6. package/dist/bundling-sources/sdk/src/monitor-fleet-contract.ts +1 -1
  7. package/dist/bundling-sources/sdk/src/pagination.ts +25 -0
  8. package/dist/bundling-sources/sdk/src/play.ts +15 -1
  9. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +3 -3
  10. package/dist/bundling-sources/sdk/src/release.ts +16 -9
  11. package/dist/bundling-sources/sdk/src/types.ts +106 -4
  12. package/dist/bundling-sources/shared_libs/integration-contracts/AGENTS.md +9 -0
  13. package/dist/bundling-sources/shared_libs/integration-contracts/README.md +3 -0
  14. package/dist/bundling-sources/shared_libs/integration-contracts/index.ts +2 -0
  15. package/dist/bundling-sources/shared_libs/monitors/analytics-install-guides.ts +77 -0
  16. package/dist/bundling-sources/shared_libs/monitors/analytics-public.ts +10 -0
  17. package/dist/bundling-sources/shared_libs/monitors/billing/charges.ts +125 -0
  18. package/dist/bundling-sources/shared_libs/monitors/billing/policy-builders.ts +686 -0
  19. package/dist/bundling-sources/shared_libs/monitors/billing/pricing.ts +54 -0
  20. package/dist/bundling-sources/shared_libs/monitors/billing/public-pricing.ts +72 -0
  21. package/dist/bundling-sources/shared_libs/monitors/billing/session.ts +45 -0
  22. package/dist/bundling-sources/shared_libs/monitors/billing/state.ts +454 -0
  23. package/dist/bundling-sources/shared_libs/monitors/billing/tamradar.ts +260 -0
  24. package/dist/bundling-sources/shared_libs/monitors/billing/types.ts +215 -0
  25. package/dist/bundling-sources/shared_libs/monitors/callback-security.ts +333 -0
  26. package/dist/bundling-sources/shared_libs/monitors/cursor-page.ts +42 -0
  27. package/dist/bundling-sources/shared_libs/monitors/deactivation-reasons.ts +16 -0
  28. package/dist/bundling-sources/shared_libs/monitors/framework-managed-payload-fields.ts +71 -0
  29. package/dist/bundling-sources/shared_libs/monitors/generated/provider-monitor-callback-admission-targets.ts +16 -0
  30. package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +270 -0
  31. package/dist/bundling-sources/shared_libs/monitors/inbound-publish-key.ts +39 -0
  32. package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +82 -0
  33. package/dist/bundling-sources/shared_libs/monitors/inventory-reconciliation.ts +59 -0
  34. package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +471 -0
  35. package/dist/bundling-sources/shared_libs/monitors/org-monitor-limits.ts +1 -1
  36. package/dist/bundling-sources/shared_libs/monitors/package.json +36 -0
  37. package/dist/bundling-sources/shared_libs/monitors/provider-callback-verification.ts +1125 -0
  38. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +305 -0
  39. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-capability.ts +964 -0
  40. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +56 -0
  41. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-errors.ts +131 -0
  42. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +535 -0
  43. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-legacy-aliases.ts +16 -0
  44. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-priority-execution.ts +56 -0
  45. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +28 -0
  46. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-runtime-read-eligibility.ts +38 -0
  47. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-state.ts +122 -0
  48. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-status.ts +10 -0
  49. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-upstream-identity.ts +112 -0
  50. package/dist/bundling-sources/shared_libs/monitors/provider-webhook-monitor-runtime.ts +300 -0
  51. package/dist/bundling-sources/shared_libs/monitors/quickstart-prompts.ts +22 -0
  52. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +245 -0
  53. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-message.ts +38 -0
  54. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-ack-probe.ts +94 -0
  55. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-delivery.ts +60 -0
  56. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue.ts +60 -0
  57. package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +93 -0
  58. package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +332 -0
  59. package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +221 -0
  60. package/dist/bundling-sources/shared_libs/monitors/starter-templates.ts +105 -0
  61. package/dist/bundling-sources/shared_libs/monitors/tracking-provider-guidance.ts +73 -0
  62. package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +81 -0
  63. package/dist/bundling-sources/shared_libs/monitors/tsconfig.json +10 -0
  64. package/dist/bundling-sources/shared_libs/observability/build-context.ts +13 -0
  65. package/dist/bundling-sources/shared_libs/observability/log-metadata.ts +160 -0
  66. package/dist/bundling-sources/shared_libs/observability/request-context.ts +68 -0
  67. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +654 -0
  68. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +35 -0
  69. package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +5 -0
  70. package/dist/bundling-sources/shared_libs/play-data-plane/neon-constants.ts +9 -0
  71. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +272 -0
  72. package/dist/bundling-sources/shared_libs/play-runtime/activity-observation.ts +6 -11
  73. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +135 -12
  74. package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +66 -1
  75. package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +77 -0
  76. package/dist/bundling-sources/shared_libs/play-runtime/bounceban-batching.ts +137 -0
  77. package/dist/bundling-sources/shared_libs/play-runtime/checkpoint-boundaries.ts +70 -0
  78. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1159 -166
  79. package/dist/bundling-sources/shared_libs/play-runtime/coordinator-headers.ts +1 -32
  80. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +103 -0
  81. package/dist/bundling-sources/shared_libs/play-runtime/daytona-payload-contract.ts +68 -0
  82. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +103 -0
  83. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +725 -0
  84. package/dist/bundling-sources/shared_libs/play-runtime/default-batch-strategies.ts +20 -1
  85. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +29 -0
  86. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +29 -0
  87. package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-invocation-fence.ts +442 -0
  88. package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +7 -1
  89. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +18 -0
  90. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +9 -0
  91. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +1 -1
  92. package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +1 -1
  93. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/contracts.ts +66 -0
  94. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/job.ts +145 -0
  95. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/ports.ts +21 -0
  96. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/postgres-store.ts +170 -0
  97. package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +1322 -0
  98. package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +2 -2
  99. package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +189 -0
  100. package/dist/bundling-sources/shared_libs/play-runtime/launch-source-policy.ts +112 -0
  101. package/dist/bundling-sources/shared_libs/play-runtime/map-execution-frame.ts +8 -0
  102. package/dist/bundling-sources/shared_libs/play-runtime/perf-trace.ts +127 -0
  103. package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +5 -0
  104. package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +24 -1
  105. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/contracts.ts +56 -0
  106. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/index.ts +13 -0
  107. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/job.ts +41 -0
  108. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/ports.ts +17 -0
  109. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts +54 -0
  110. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/contracts.ts +114 -0
  111. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/engine-suspension.ts +108 -0
  112. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/index.ts +36 -0
  113. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/job.ts +97 -0
  114. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/ports.ts +104 -0
  115. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/postgres-fence-adapter.ts +263 -0
  116. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/worker-terminal-projection.ts +64 -0
  117. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/contracts.ts +29 -0
  118. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts +56 -0
  119. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/index.ts +15 -0
  120. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/job.ts +65 -0
  121. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/ports.ts +17 -0
  122. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +42 -0
  123. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/index.ts +17 -0
  124. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +142 -0
  125. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/ports.ts +42 -0
  126. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/postgres-adapter.ts +102 -0
  127. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/contracts.ts +60 -0
  128. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/index.ts +16 -0
  129. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/job.ts +78 -0
  130. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/ports.ts +54 -0
  131. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/postgres-adapter.ts +71 -0
  132. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +4 -0
  133. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-semantics.ts +28 -0
  134. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +4 -0
  135. package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +5 -8
  136. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +23 -2
  137. package/dist/bundling-sources/shared_libs/play-runtime/run-identity.ts +168 -0
  138. package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +1 -1
  139. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +90 -13
  140. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +6 -12
  141. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-start-admission.ts +68 -0
  142. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +21 -0
  143. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/bundle.ts +0 -1
  144. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +14 -43
  145. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +67 -213
  146. package/dist/bundling-sources/shared_libs/play-runtime/runtime-authority.ts +201 -0
  147. package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +20 -0
  148. package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +6 -0
  149. package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +12 -0
  150. package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +67 -0
  151. package/dist/bundling-sources/shared_libs/play-runtime/runtime-release-environment.ts +2 -0
  152. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sandbox-contract.ts +68 -0
  153. package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +38 -2
  154. package/dist/bundling-sources/shared_libs/play-runtime/runtime-telemetry.ts +108 -0
  155. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +4 -0
  156. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +3 -0
  157. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +37 -1
  158. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-deadline-reconciliation.ts +88 -0
  159. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-deploy-task.ts +124 -0
  160. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-run-task.ts +68 -0
  161. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +193 -0
  162. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-lifecycle.ts +269 -0
  163. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-suffix.ts +73 -0
  164. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +6642 -0
  165. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +897 -0
  166. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-metrics.ts +120 -0
  167. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +76 -0
  168. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +476 -0
  169. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-heavy-request-admission.ts +47 -0
  170. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-progress-registry.ts +147 -0
  171. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/index.ts +27 -0
  172. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/lazy.ts +50 -0
  173. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/play-run-recovery.ts +98 -0
  174. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-budget-state.ts +260 -0
  175. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +1416 -0
  176. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +1255 -0
  177. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +942 -0
  178. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +14636 -0
  179. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +888 -0
  180. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +355 -0
  181. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-terminal-transition.ts +46 -0
  182. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runner-push.ts +60 -0
  183. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-api-origin.ts +33 -0
  184. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-gateway-health.ts +64 -0
  185. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +835 -0
  186. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +1218 -0
  187. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-operation.ts +207 -0
  188. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-scheduler-schema.ts +10 -0
  189. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-capacity.ts +123 -0
  190. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-launch-read-observability.ts +78 -0
  191. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/submit-admission.ts +169 -0
  192. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/terminal-contract.ts +20 -0
  193. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-queue-metrics.ts +34 -0
  194. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-resource-metrics.ts +249 -0
  195. package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +7 -0
  196. package/dist/bundling-sources/shared_libs/play-runtime/step-progress.ts +296 -0
  197. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/native-batch.ts +3 -3
  198. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/runtime-step-receipts-adapter.ts +20 -1
  199. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +60 -15
  200. package/dist/bundling-sources/shared_libs/play-runtime/tool-execution-outcome.ts +20 -0
  201. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +1 -1
  202. package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +1 -1
  203. package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +12 -0
  204. package/dist/bundling-sources/shared_libs/play-runtime/vercel-protection.ts +14 -1
  205. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +165 -0
  206. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +15 -23
  207. package/dist/bundling-sources/shared_libs/play-runtime/workflow-executor-auth.ts +169 -0
  208. package/dist/bundling-sources/shared_libs/play-runtime/zerobounce-batching.ts +122 -0
  209. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +8 -3
  210. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +454 -17
  211. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +19 -4
  212. package/dist/bundling-sources/shared_libs/plays/contracts.ts +8 -14
  213. package/dist/bundling-sources/shared_libs/plays/core.ts +11 -6
  214. package/dist/bundling-sources/shared_libs/plays/deployment-status.ts +1 -1
  215. package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +16 -11
  216. package/dist/bundling-sources/shared_libs/plays/docflow.ts +1 -1
  217. package/dist/bundling-sources/shared_libs/plays/email-status.ts +1 -1
  218. package/dist/bundling-sources/shared_libs/plays/play-grep-search.ts +39 -0
  219. package/dist/bundling-sources/shared_libs/plays/resolve-static-pipeline.ts +1 -1
  220. package/dist/bundling-sources/shared_libs/plays/share/copy.ts +271 -0
  221. package/dist/bundling-sources/shared_libs/plays/share/metrics.ts +140 -0
  222. package/dist/bundling-sources/shared_libs/plays/share/public-read-model.ts +86 -0
  223. package/dist/bundling-sources/shared_libs/plays/share/seo-quality.ts +181 -0
  224. package/dist/bundling-sources/shared_libs/plays/share/static-pipeline-summary.ts +658 -0
  225. package/dist/bundling-sources/shared_libs/plays/share/types.ts +197 -0
  226. package/dist/bundling-sources/shared_libs/plays/slack-hitl-timeout-error.ts +37 -0
  227. package/dist/bundling-sources/shared_libs/plays/slug.ts +115 -0
  228. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +50 -15
  229. package/dist/bundling-sources/shared_libs/plays/tool-category-descriptions.ts +2 -2
  230. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
  231. package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +877 -0
  232. package/dist/bundling-sources/shared_libs/product-notifications/configuration-draft.ts +456 -0
  233. package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +566 -0
  234. package/dist/bundling-sources/shared_libs/product-notifications/content.ts +28 -0
  235. package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +60 -0
  236. package/dist/bundling-sources/shared_libs/product-notifications/email.ts +246 -0
  237. package/dist/bundling-sources/shared_libs/product-notifications/evaluation.ts +280 -0
  238. package/dist/bundling-sources/shared_libs/product-notifications/events.ts +433 -0
  239. package/dist/bundling-sources/shared_libs/product-notifications/legacy-slack.ts +80 -0
  240. package/dist/bundling-sources/shared_libs/product-notifications/overflow.ts +18 -0
  241. package/dist/bundling-sources/shared_libs/product-notifications/rolling-limit.ts +24 -0
  242. package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +624 -0
  243. package/dist/bundling-sources/shared_libs/product-notifications/slack-payload.ts +140 -0
  244. package/dist/bundling-sources/shared_libs/product-notifications/slack-transport.ts +75 -0
  245. package/dist/bundling-sources/shared_libs/product-notifications/workspace.ts +38 -0
  246. package/dist/bundling-sources/shared_libs/runtime-env.ts +12 -0
  247. package/dist/bundling-sources/shared_libs/security/email-blacklist.ts +42 -0
  248. package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +35 -0
  249. package/dist/bundling-sources/shared_libs/security/internal-actor.ts +50 -0
  250. package/dist/bundling-sources/shared_libs/security/secret-redaction.ts +267 -0
  251. package/dist/bundling-sources/shared_libs/security/slack-sanitize.ts +133 -0
  252. package/dist/cli/getting-started.d.mts +52 -0
  253. package/dist/cli/getting-started.d.ts +52 -0
  254. package/dist/cli/getting-started.js +65 -0
  255. package/dist/cli/getting-started.mjs +36 -0
  256. package/dist/cli/index.d.mts +9 -0
  257. package/dist/cli/index.d.ts +9 -0
  258. package/dist/cli/index.js +1611 -453
  259. package/dist/cli/index.mjs +1596 -447
  260. package/dist/{compiler-manifest-Dbov16F7.d.mts → compiler-manifest-BaJfE-5H.d.mts} +136 -10
  261. package/dist/{compiler-manifest-Dbov16F7.d.ts → compiler-manifest-BaJfE-5H.d.ts} +136 -10
  262. package/dist/index.d.mts +910 -155
  263. package/dist/index.d.ts +910 -155
  264. package/dist/index.js +550 -64
  265. package/dist/index.mjs +550 -64
  266. package/dist/install-integrity.json +193 -4
  267. package/dist/monitor-fleet-contract.d.mts +138 -0
  268. package/dist/monitor-fleet-contract.d.ts +138 -0
  269. package/dist/monitor-fleet-contract.js +404 -0
  270. package/dist/monitor-fleet-contract.mjs +367 -0
  271. package/dist/plays/bundle-play-file.d.mts +8 -3
  272. package/dist/plays/bundle-play-file.d.ts +8 -3
  273. package/dist/plays/bundle-play-file.mjs +100 -20
  274. package/dist/release.d.mts +255 -0
  275. package/dist/release.d.ts +255 -0
  276. package/dist/release.js +215 -0
  277. package/dist/release.mjs +188 -0
  278. package/package.json +23 -4
  279. /package/dist/bundling-sources/shared_libs/{integrations/bettercontact-execution-policy.ts → integration-contracts/bettercontact/execution-policy.ts} +0 -0
  280. /package/dist/bundling-sources/shared_libs/{integrations/theirstack-execution-policy.ts → integration-contracts/theirstack/execution-policy.ts} +0 -0
@@ -0,0 +1,245 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { isRepairableTenantDataPlaneError } from '@deepline/ingestion-v2/tenant-data-plane-errors';
3
+ import type { SignalRadarInboundMessage } from '@deepline/monitors/signal-radars/inbound-message';
4
+
5
+ // Minimal pg client seam shared with the ingestion stack: a `query(sql, args)`
6
+ // that returns `{ rows }`. Deliberately structural so PGlite (tests) and the
7
+ // Neon pooled client (prod) both satisfy it without adapters.
8
+ export type InboundPgClient = {
9
+ query: (
10
+ sql: string,
11
+ args?: unknown[],
12
+ ) => Promise<{ rows?: unknown[]; rowCount?: number }>;
13
+ };
14
+
15
+ export type InboundFailureClass = 'transient' | 'permanent';
16
+
17
+ function errorMessage(error: unknown): string {
18
+ if (error instanceof Error && error.message.trim()) return error.message;
19
+ if (typeof error === 'string' && error.trim()) return error;
20
+ return String(error ?? 'unknown error');
21
+ }
22
+
23
+ // A TRANSIENT failure is an infra outage the event can survive: keep retrying
24
+ // via backoff so a long Neon/Convex flap drains on recovery instead of being
25
+ // dead-lettered (which would drop a real customer signal). A PERMANENT failure
26
+ // is a poison message — an unrecognized/invalid payload shape that will never
27
+ // succeed no matter how many times we redeliver — so it must give up + record.
28
+ //
29
+ // The transient side reuses the SAME classification the rest of the ingestion
30
+ // stack already treats as repairable (permission-denied / role drift / conn
31
+ // resets), so the worker never disagrees with the route on "transient".
32
+ export function classifyInboundFailure(error: unknown): InboundFailureClass {
33
+ if (isRepairableTenantDataPlaneError(error)) return 'transient';
34
+
35
+ const code =
36
+ error && typeof error === 'object'
37
+ ? String((error as { code?: unknown }).code ?? '')
38
+ : '';
39
+ const transientCodes = new Set([
40
+ 'tenant_data_plane_repair_required',
41
+ 'provider_monitor_convex_sync_pending',
42
+ // The worker emits this after capture-first receipt persistence cannot be
43
+ // completed. The event has not entered durable storage, so it must remain
44
+ // retryable even after the ordinary poison-message delivery budget.
45
+ 'provider_callback_raw_capture_unavailable',
46
+ // A concurrent worker still owns the durable receipt. Acknowledging this
47
+ // redelivery as poison could dead-letter a live callback and clear the
48
+ // owner's receipt before its lease completes.
49
+ 'provider_callback_raw_receipt_in_progress',
50
+ 'ECONNRESET',
51
+ 'ECONNREFUSED',
52
+ 'ETIMEDOUT',
53
+ 'EPIPE',
54
+ 'ENOTFOUND',
55
+ 'EAI_AGAIN',
56
+ 'snitcher_ip2company_retryable',
57
+ '57P01', // admin shutdown
58
+ '57P02', // crash shutdown
59
+ '57P03', // cannot connect now
60
+ '08000', // connection exception
61
+ '08003', // connection does not exist
62
+ '08006', // connection failure
63
+ '53300', // too many connections
64
+ ]);
65
+ if (code && transientCodes.has(code)) return 'transient';
66
+
67
+ const message = errorMessage(error);
68
+ const transientPatterns = [
69
+ /connection (?:terminated|refused|reset|closed|failure)/i,
70
+ /could not connect to server/i,
71
+ /connection to server .* failed/i,
72
+ /the database system is (?:starting up|shutting down|in recovery)/i,
73
+ /timeout(?: exceeded)?(?: when trying)? to connect/i,
74
+ /connect(?:ion)? timeout/i,
75
+ /terminating connection due to/i,
76
+ /too many connections/i,
77
+ /ECONNRESET|ECONNREFUSED|ETIMEDOUT/i,
78
+ /convex.*(?:unavailable|timeout|network)/i,
79
+ /fetch failed/i,
80
+ /socket hang up/i,
81
+ ];
82
+ if (transientPatterns.some((pattern) => pattern.test(message))) {
83
+ return 'transient';
84
+ }
85
+
86
+ // Default to permanent: an unclassified failure is treated as poison so it is
87
+ // recorded for human review rather than retried forever. Transient outages are
88
+ // the ones we can positively identify (above); everything else is give-up-able.
89
+ return 'permanent';
90
+ }
91
+
92
+ type DeadLetterMessageInput = Pick<
93
+ SignalRadarInboundMessage,
94
+ 'provider' | 'orgId' | 'token' | 'headers' | 'receivedAt'
95
+ > & {
96
+ admission?: SignalRadarInboundMessage['admission'];
97
+ radarKey?: string | null;
98
+ eventIdempotencyKey?: string | null;
99
+ rawBody?: string;
100
+ };
101
+
102
+ async function markCapturedRawWriteFailed(
103
+ client: InboundPgClient,
104
+ eventIdempotencyKey: string,
105
+ lastError: string,
106
+ ) {
107
+ // The capture-first raw row (dl_meta.monitor_inbound_raw) may already exist for
108
+ // this event. Flip it to write_failed so on-call sees "captured, dead-lettered,
109
+ // replayable" in one place. Best-effort: a missing table/row must not block the
110
+ // dead-letter record itself.
111
+ try {
112
+ await client.query(
113
+ `UPDATE dl_meta.monitor_inbound_raw
114
+ SET status = 'write_failed', error = $2, updated_at = now()
115
+ WHERE event_idempotency_key = $1`,
116
+ [eventIdempotencyKey, lastError.slice(0, 4000)],
117
+ );
118
+ } catch (error) {
119
+ console.warn('[signal-radar.dead_letter.raw_mark_failed]', {
120
+ event_idempotency_key: eventIdempotencyKey,
121
+ error: error instanceof Error ? error.message : String(error),
122
+ });
123
+ }
124
+ }
125
+
126
+ // Idempotent dead-letter writer. Keyed on the provider event idempotency key via
127
+ // the partial-unique index, so the SAME poison event redelivered N times yields
128
+ // exactly ONE dead letter (attempts/last_error bumped), while two distinct
129
+ // null-keyed poison events stay distinct (the partial index only enforces
130
+ // uniqueness WHERE event_idempotency_key IS NOT NULL). Also marks the captured
131
+ // raw row write_failed when one exists for the key.
132
+ export async function recordSignalRadarDeadLetter(input: {
133
+ client: InboundPgClient;
134
+ message: DeadLetterMessageInput;
135
+ error: unknown;
136
+ attempts: number;
137
+ }): Promise<void> {
138
+ const { client, message } = input;
139
+ const lastError = errorMessage(input.error);
140
+ const eventIdempotencyKey = message.eventIdempotencyKey ?? null;
141
+ const payload = {
142
+ provider: message.provider,
143
+ orgId: message.orgId,
144
+ token: message.token,
145
+ radarKey: message.radarKey ?? null,
146
+ eventIdempotencyKey,
147
+ rawBody: message.rawBody ?? null,
148
+ headers: message.headers ?? {},
149
+ receivedAt: message.receivedAt,
150
+ admission: message.admission ?? null,
151
+ };
152
+
153
+ if (eventIdempotencyKey) {
154
+ await client.query(
155
+ `INSERT INTO dl_meta.signal_radar_inbound_dead_letter
156
+ (dead_letter_id, provider, radar_key, org_id, event_idempotency_key,
157
+ payload, headers, attempts, last_error, status)
158
+ VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7::jsonb, $8, $9, 'open')
159
+ ON CONFLICT (event_idempotency_key)
160
+ WHERE event_idempotency_key IS NOT NULL
161
+ DO UPDATE SET
162
+ attempts = EXCLUDED.attempts,
163
+ last_error = EXCLUDED.last_error,
164
+ payload = EXCLUDED.payload,
165
+ headers = EXCLUDED.headers,
166
+ updated_at = now()`,
167
+ [
168
+ randomUUID(),
169
+ message.provider,
170
+ message.radarKey ?? null,
171
+ message.orgId ?? null,
172
+ eventIdempotencyKey,
173
+ JSON.stringify(payload),
174
+ JSON.stringify(message.headers ?? {}),
175
+ input.attempts,
176
+ lastError.slice(0, 8000),
177
+ ],
178
+ );
179
+ await markCapturedRawWriteFailed(client, eventIdempotencyKey, lastError);
180
+ return;
181
+ }
182
+
183
+ // No idempotency key -> the partial index does not apply, so each null-keyed
184
+ // poison event is its own dead letter (never merged).
185
+ await client.query(
186
+ `INSERT INTO dl_meta.signal_radar_inbound_dead_letter
187
+ (dead_letter_id, provider, radar_key, org_id, event_idempotency_key,
188
+ payload, headers, attempts, last_error, status)
189
+ VALUES ($1, $2, $3, $4, NULL, $5::jsonb, $6::jsonb, $7, $8, 'open')`,
190
+ [
191
+ randomUUID(),
192
+ message.provider,
193
+ message.radarKey ?? null,
194
+ message.orgId ?? null,
195
+ JSON.stringify(payload),
196
+ JSON.stringify(message.headers ?? {}),
197
+ input.attempts,
198
+ lastError.slice(0, 8000),
199
+ ],
200
+ );
201
+ }
202
+
203
+ // The load-bearing retry-callback decision (plan §4a). Runs on every handler
204
+ // throw:
205
+ // - transient -> back off + redeliver, NEVER acknowledge, regardless of how
206
+ // far past maxDeliveries we are. A long Neon outage must drain on recovery.
207
+ // - permanent, still within maxDeliveries -> back off (give it its allotted
208
+ // retries; a "permanent" verdict can be a transient mislabel early on).
209
+ // - permanent, past maxDeliveries -> record the dead letter + acknowledge
210
+ // (stop retrying; it is now durably captured for human review + replay).
211
+ export type InboundRetryDecision =
212
+ | { afterSeconds: number }
213
+ | { acknowledge: true };
214
+
215
+ export function inboundBackoffSeconds(deliveryCount: number): number {
216
+ // Mirror the plan's bounded exponential backoff: 2^n * 5, capped at 300s.
217
+ const exponent = Math.max(1, deliveryCount);
218
+ return Math.min(300, 2 ** exponent * 5);
219
+ }
220
+
221
+ export async function resolveInboundRetryDecision(input: {
222
+ client: InboundPgClient;
223
+ message: DeadLetterMessageInput;
224
+ error: unknown;
225
+ deliveryCount: number;
226
+ maxDeliveries: number;
227
+ }): Promise<InboundRetryDecision> {
228
+ const failureClass = classifyInboundFailure(input.error);
229
+
230
+ if (failureClass === 'transient') {
231
+ return { afterSeconds: inboundBackoffSeconds(input.deliveryCount) };
232
+ }
233
+
234
+ if (input.deliveryCount <= input.maxDeliveries) {
235
+ return { afterSeconds: inboundBackoffSeconds(input.deliveryCount) };
236
+ }
237
+
238
+ await recordSignalRadarDeadLetter({
239
+ client: input.client,
240
+ message: input.message,
241
+ error: input.error,
242
+ attempts: input.deliveryCount,
243
+ });
244
+ return { acknowledge: true };
245
+ }
@@ -0,0 +1,38 @@
1
+ // The durable message the thin Monitor inbound receiver enqueues onto the
2
+ // Vercel Queues front-queue. It carries ONLY what the worker needs that is not
3
+ // derivable without the provider's HTTP request — nothing Neon-derived. The
4
+ // worker re-runs the full ingestion machinery from this envelope alone (resolve
5
+ // the radar binding from Neon, capture-first raw, typed write, inline dispatch),
6
+ // so the receiver never has to touch Neon before returning 200.
7
+
8
+ export type SignalRadarInboundMessage = {
9
+ provider: string;
10
+ orgId: string;
11
+ token: string;
12
+ rawBody: string;
13
+ headers: Record<string, string>;
14
+ receivedAt: string;
15
+ admission: {
16
+ id: string;
17
+ bindingVersion: number;
18
+ /** A batch callback is resolved by its provider resource ID in Tier 2. */
19
+ routingMode?: 'single_monitor' | 'batch_by_upstream_resource';
20
+ verificationMode:
21
+ | 'hmac_signature'
22
+ | 'shared_secret_body'
23
+ | 'secret_header'
24
+ | 'callback_token_only';
25
+ };
26
+ // The Neon-free provider-event publish idempotency key, computed by the
27
+ // receiver from what is on the wire. Carried so the worker and dead-letter
28
+ // writer can key on the same grain the publish deduped on.
29
+ eventIdempotencyKey?: string | null;
30
+ // A preview monitor callback is received by Vercel but its run executes on
31
+ // an isolated scheduler lane. Preserve that request-scoped context across
32
+ // the durable queue boundary.
33
+ postgresSchedulerSchema?: string | null;
34
+ runtimeApiBaseUrl?: string | null;
35
+ // Optional radar hint the worker resolves durably from Neon; present only on
36
+ // dead-letter/replay envelopes where it was already known.
37
+ radarKey?: string | null;
38
+ };
@@ -0,0 +1,94 @@
1
+ import { getVercelOidcToken } from '@vercel/oidc';
2
+
3
+ import { SIGNAL_RADAR_INBOUND_TOPIC } from '@deepline/monitors/signal-radars/inbound-queue';
4
+
5
+ // Must match the function key in apps/deepline-api/vercel.json. Vercel Queue's push-trigger
6
+ // adapter derives the consumer group from this path. Deriving rather than
7
+ // copying the encoded value makes the transformation reviewable and testable.
8
+ export const SIGNAL_RADAR_INBOUND_TRIGGER_PATH =
9
+ 'src/app/api/queues/signal-radar-inbound/route.ts';
10
+
11
+ const DEEPLINE_API_PROJECT_ROOT = 'apps/deepline-api/';
12
+
13
+ export function vercelQueueConsumerGroupForFunctionPath(functionPath: string) {
14
+ return functionPath
15
+ .replaceAll('_', '__')
16
+ .replaceAll('/', '_S')
17
+ .replaceAll('.', '_D');
18
+ }
19
+
20
+ export const SIGNAL_RADAR_INBOUND_CONSUMER_GROUP =
21
+ vercelQueueConsumerGroupForFunctionPath(
22
+ SIGNAL_RADAR_INBOUND_TRIGGER_PATH.replace(DEEPLINE_API_PROJECT_ROOT, ''),
23
+ );
24
+
25
+ export type SignalRadarInboundQueueMessageState =
26
+ | 'acknowledged'
27
+ | 'available'
28
+ | 'in_flight'
29
+ | 'not_found';
30
+
31
+ type ProbeDependencies = {
32
+ fetch?: typeof fetch;
33
+ getOidcToken?: () => Promise<string>;
34
+ };
35
+
36
+ type ProbeInput = {
37
+ messageId: string;
38
+ region: string | undefined;
39
+ deploymentId: string | undefined;
40
+ };
41
+
42
+ function requiredRuntimeValue(name: string, value: string | undefined) {
43
+ if (value?.trim()) return value.trim();
44
+ throw new Error(
45
+ `${name} is required for the Vercel Queue acknowledgement probe.`,
46
+ );
47
+ }
48
+
49
+ /**
50
+ * Peeks at the exact message in Vercel's push-consumer group without leasing,
51
+ * acknowledging, or otherwise changing it. A 410 is the direct proof that
52
+ * the consumer successfully acknowledged this message.
53
+ */
54
+ export async function signalRadarInboundQueueMessageState(
55
+ input: ProbeInput,
56
+ dependencies: ProbeDependencies = {},
57
+ ): Promise<SignalRadarInboundQueueMessageState> {
58
+ const region = requiredRuntimeValue('VERCEL_REGION', input.region);
59
+ const deploymentId = requiredRuntimeValue(
60
+ 'VERCEL_DEPLOYMENT_ID',
61
+ input.deploymentId,
62
+ );
63
+ const requestFetch = dependencies.fetch ?? fetch;
64
+ const getToken = dependencies.getOidcToken ?? getVercelOidcToken;
65
+ const response = await requestFetch(
66
+ `https://${region}.vercel-queue.com/api/v3/topic/${encodeURIComponent(
67
+ SIGNAL_RADAR_INBOUND_TOPIC,
68
+ )}/consumer/${encodeURIComponent(
69
+ SIGNAL_RADAR_INBOUND_CONSUMER_GROUP,
70
+ )}/id/${encodeURIComponent(input.messageId)}`,
71
+ {
72
+ method: 'POST',
73
+ headers: {
74
+ authorization: `Bearer ${await getToken()}`,
75
+ accept: 'multipart/mixed',
76
+ // Vercel documents zero as a non-leasing peek. This probe must never
77
+ // become a competing consumer or acknowledge an unprocessed message.
78
+ 'vqs-visibility-timeout-seconds': '0',
79
+ 'vqs-deployment-id': deploymentId,
80
+ },
81
+ },
82
+ );
83
+
84
+ if (response.status === 410) return 'acknowledged';
85
+ if (response.status === 409) return 'in_flight';
86
+ if (response.status === 404) return 'not_found';
87
+ if (response.status === 200) return 'available';
88
+
89
+ throw new Error(
90
+ `Vercel Queue acknowledgement probe failed with HTTP ${response.status}: ${(
91
+ await response.text()
92
+ ).slice(0, 500)}`,
93
+ );
94
+ }
@@ -0,0 +1,60 @@
1
+ import {
2
+ classifyInboundFailure,
3
+ inboundBackoffSeconds,
4
+ } from '@deepline/monitors/signal-radars/inbound-dead-letter';
5
+ import type { SignalRadarInboundMessage } from '@deepline/monitors/signal-radars/inbound-message';
6
+
7
+ export class SignalRadarInboundDeliveryError extends Error {
8
+ readonly cause_error: unknown;
9
+
10
+ constructor(cause: unknown) {
11
+ super(cause instanceof Error ? cause.message : String(cause));
12
+ this.name = 'SignalRadarInboundDeliveryError';
13
+ this.cause_error = cause;
14
+ }
15
+ }
16
+
17
+ export async function handleSignalRadarInboundDelivery(input: {
18
+ message: SignalRadarInboundMessage;
19
+ metadata: { deliveryCount: number; messageId?: string };
20
+ maxDeliveries: number;
21
+ runWorker: (
22
+ message: SignalRadarInboundMessage,
23
+ metadata: { deliveryCount: number; messageId?: string },
24
+ ) => Promise<unknown>;
25
+ recordDeadLetter: (input: {
26
+ message: SignalRadarInboundMessage;
27
+ error: unknown;
28
+ deliveryCount: number;
29
+ }) => Promise<void>;
30
+ }) {
31
+ try {
32
+ await input.runWorker(input.message, input.metadata);
33
+ } catch (error) {
34
+ if (
35
+ classifyInboundFailure(error) === 'permanent' &&
36
+ input.metadata.deliveryCount > input.maxDeliveries
37
+ ) {
38
+ try {
39
+ await input.recordDeadLetter({
40
+ message: input.message,
41
+ error,
42
+ deliveryCount: input.metadata.deliveryCount,
43
+ });
44
+ return;
45
+ } catch (recordError) {
46
+ throw new SignalRadarInboundDeliveryError(recordError);
47
+ }
48
+ }
49
+ throw new SignalRadarInboundDeliveryError(error);
50
+ }
51
+ }
52
+
53
+ export function signalRadarInboundRetry(input: {
54
+ error: unknown;
55
+ deliveryCount: number;
56
+ }) {
57
+ // This function intentionally does no I/O. Vercel's retry callback is
58
+ // synchronous; terminal persistence belongs in the awaited handler above.
59
+ return { afterSeconds: inboundBackoffSeconds(input.deliveryCount) };
60
+ }
@@ -0,0 +1,60 @@
1
+ import { send as vercelQueueSend } from '@vercel/queue';
2
+ import type { SignalRadarInboundMessage } from '@deepline/monitors/signal-radars/inbound-message';
3
+ import { isTestOnlyRuntime } from '../../play-runtime/runtime-env';
4
+
5
+ // Durable Vercel Queues front-queue for Monitor inbound webhook events.
6
+ // The receiver produces onto this topic (auth -> enqueue -> 200); the air-gapped
7
+ // worker at apps/deepline-api/src/app/api/queues/signal-radar-inbound/route.ts consumes it and runs
8
+ // the full ingestion machinery. See docs/provider-monitor-playbook.md.
9
+ export const SIGNAL_RADAR_INBOUND_TOPIC = 'signal-radar-inbound';
10
+
11
+ // Retention set to the Vercel Queues maximum (7 days). This is the ceiling on
12
+ // the worst Neon/Convex outage the buffer can survive: while downstream is down,
13
+ // the receiver still returns 200 and the message sits here, redelivering until it
14
+ // drains or expires. Sized to exceed any tolerable Neon outage window.
15
+ export const SIGNAL_RADAR_INBOUND_RETENTION_SECONDS = 604_800;
16
+
17
+ export type SignalRadarInboundSendOptions = {
18
+ idempotencyKey?: string;
19
+ /**
20
+ * Test-runtime delivery driver. The public receiver may set this only after
21
+ * proving the request is synthetic and test-authorized. It exercises the
22
+ * same queue worker locally, where Vercel Queues cannot mint its OIDC token.
23
+ */
24
+ inlineTestWorker?: boolean;
25
+ runInlineTestWorker?: (message: SignalRadarInboundMessage) => Promise<unknown>;
26
+ };
27
+
28
+ // Publish onto the inbound topic. `idempotencyKey` is the Neon-free provider
29
+ // event key (belt-and-suspenders publish-side dedupe within the message TTL;
30
+ // the real guarantee is the worker's consumer-side dedupe on the same grain).
31
+ export async function send(
32
+ message: SignalRadarInboundMessage,
33
+ options?: SignalRadarInboundSendOptions,
34
+ ) {
35
+ if (options?.inlineTestWorker) {
36
+ if (!isTestOnlyRuntime()) {
37
+ throw new Error(
38
+ 'The synthetic inbound queue driver is unavailable outside a test runtime.',
39
+ );
40
+ }
41
+ // The owning app supplies its real worker; packages cannot import app routes.
42
+ if (!options.runInlineTestWorker) {
43
+ throw new Error('The synthetic inbound queue driver requires an app worker.');
44
+ }
45
+ const result = await options.runInlineTestWorker(message);
46
+ return {
47
+ messageId: `test-inline:${options.idempotencyKey ?? crypto.randomUUID()}`,
48
+ // The test-only driver executes Tier 2 synchronously. Preserve its
49
+ // outcome for the synthetic receiver so a Gauntlet can assert a billing
50
+ // suspension without changing the real provider-facing queue contract.
51
+ result,
52
+ };
53
+ }
54
+ return vercelQueueSend(SIGNAL_RADAR_INBOUND_TOPIC, message, {
55
+ retentionSeconds: SIGNAL_RADAR_INBOUND_RETENTION_SECONDS,
56
+ ...(options?.idempotencyKey
57
+ ? { idempotencyKey: options.idempotencyKey }
58
+ : {}),
59
+ });
60
+ }
@@ -0,0 +1,93 @@
1
+ import { lookup } from 'node:dns/promises';
2
+ import { isIP } from 'node:net';
3
+ import { DEEPLINE_ANALYTICS_BROWSER_OBJECT } from '@deepline/monitors/analytics-public';
4
+
5
+ export type SnitcherInstallationCheck = {
6
+ domain: string;
7
+ status: 'installed' | 'not_found' | 'unreachable';
8
+ message: string;
9
+ };
10
+
11
+ export async function validateSnitcherInstallation(input: {
12
+ domains: string[];
13
+ trackingScriptId: string;
14
+ }) {
15
+ return await Promise.all(
16
+ input.domains.map(async (domain): Promise<SnitcherInstallationCheck> => {
17
+ // Domains were validated and stored during setup. Never accept arbitrary URLs here.
18
+ if (isIP(domain) || domain === 'localhost')
19
+ return {
20
+ domain,
21
+ status: 'unreachable',
22
+ message: 'This domain cannot be checked.',
23
+ };
24
+ try {
25
+ const addresses = await lookup(domain, { all: true });
26
+ if (
27
+ !addresses.length ||
28
+ addresses.some(({ address }) => {
29
+ if (isIP(address) === 6) {
30
+ const lower = address.toLowerCase();
31
+ return (
32
+ lower === '::1' ||
33
+ lower.startsWith('fc') ||
34
+ lower.startsWith('fd') ||
35
+ lower.startsWith('fe80:')
36
+ );
37
+ }
38
+ const [a, b] = address.split('.').map(Number);
39
+ return (
40
+ a === 0 ||
41
+ a === 10 ||
42
+ a === 127 ||
43
+ (a === 169 && b === 254) ||
44
+ (a === 172 && b >= 16 && b <= 31) ||
45
+ (a === 192 && b === 168) ||
46
+ (a === 100 && b >= 64 && b <= 127)
47
+ );
48
+ })
49
+ )
50
+ return {
51
+ domain,
52
+ status: 'unreachable',
53
+ message: 'This domain cannot be checked.',
54
+ };
55
+ const response = await fetch(`https://${domain}`, {
56
+ redirect: 'error',
57
+ signal: AbortSignal.timeout(10_000),
58
+ headers: {
59
+ Accept: 'text/html',
60
+ 'User-Agent': 'DeeplineTrackerValidator/1.0',
61
+ },
62
+ });
63
+ if (!response.ok)
64
+ return {
65
+ domain,
66
+ status: 'unreachable',
67
+ message: `The site returned HTTP ${response.status}.`,
68
+ };
69
+ const body = (await response.text()).slice(0, 500_000);
70
+ const installed =
71
+ body.includes(input.trackingScriptId) &&
72
+ body.includes(DEEPLINE_ANALYTICS_BROWSER_OBJECT);
73
+ return installed
74
+ ? {
75
+ domain,
76
+ status: 'installed',
77
+ message: 'Tracker found in the page source.',
78
+ }
79
+ : {
80
+ domain,
81
+ status: 'not_found',
82
+ message: 'Tracker was not found in the page source yet.',
83
+ };
84
+ } catch {
85
+ return {
86
+ domain,
87
+ status: 'unreachable',
88
+ message: 'Could not reach this site over HTTPS.',
89
+ };
90
+ }
91
+ }),
92
+ );
93
+ }