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,433 @@
1
+ import type {
2
+ ProductNotificationFacts,
3
+ ProductNotificationTrigger,
4
+ } from './configuration';
5
+ import type {
6
+ ProductNotificationObservation,
7
+ ProductNotificationOutcomeFact,
8
+ } from './evaluation';
9
+
10
+ export const PRODUCT_NOTIFICATION_EVENT_SCHEMA_VERSION = 1 as const;
11
+ export const PRODUCT_NOTIFICATION_MAX_EVENT_BYTES = 16_000;
12
+ export const PRODUCT_NOTIFICATION_MAX_EVENT_FACTS = 20;
13
+ export const PRODUCT_NOTIFICATION_MAX_EVENT_AGE_MS = 30 * 24 * 60 * 60 * 1_000;
14
+ export const PRODUCT_NOTIFICATION_MAX_SOURCE_CLOCK_SKEW_MS = 5 * 60 * 1_000;
15
+
16
+ export const ProductNotificationEvent = {
17
+ CreditsBalanceChanged: 'credits.balance.changed',
18
+ CreditsUsageRecorded: 'credits.usage.recorded',
19
+ MonitorLifecycleChanged: 'monitor.lifecycle.changed',
20
+ PlayLifecycleChanged: 'play.lifecycle.changed',
21
+ PlayRunCompleted: 'play.run.completed',
22
+ WebhookDeliveryCompleted: 'webhook.delivery.completed',
23
+ PlayCronSucceeded: 'play.cron.succeeded',
24
+ PlayCronFailed: 'play.cron.failed',
25
+ PlayWebhookSucceeded: 'play.webhook.succeeded',
26
+ PlayWebhookFailed: 'play.webhook.failed',
27
+ } as const;
28
+
29
+ export type ProductNotificationEvent =
30
+ (typeof ProductNotificationEvent)[keyof typeof ProductNotificationEvent];
31
+
32
+ export const ProductNotificationProducerKey = {
33
+ BillingCredits: 'billing.credits',
34
+ BillingUsage: 'billing.usage',
35
+ MonitorsLifecycle: 'monitors.lifecycle',
36
+ PlaysLifecycle: 'plays.lifecycle',
37
+ PlaysRuns: 'plays.runs',
38
+ WebhooksDelivery: 'webhooks.delivery',
39
+ LegacyProductNotifications: 'legacy.product_notifications',
40
+ } as const;
41
+
42
+ export type ProductNotificationProducerKey =
43
+ (typeof ProductNotificationProducerKey)[keyof typeof ProductNotificationProducerKey];
44
+
45
+ export const ProductNotificationTargetPath = {
46
+ Billing: '/dashboard/billing',
47
+ } as const;
48
+
49
+ export const PRODUCT_NOTIFICATION_EVENT_NAMES = [
50
+ ProductNotificationEvent.CreditsBalanceChanged,
51
+ ProductNotificationEvent.MonitorLifecycleChanged,
52
+ ProductNotificationEvent.PlayLifecycleChanged,
53
+ ProductNotificationEvent.PlayRunCompleted,
54
+ ProductNotificationEvent.WebhookDeliveryCompleted,
55
+ ProductNotificationEvent.CreditsUsageRecorded,
56
+ ] as const;
57
+
58
+ export const PRODUCT_NOTIFICATION_COMPATIBILITY_EVENT_NAMES = [
59
+ ProductNotificationEvent.PlayCronSucceeded,
60
+ ProductNotificationEvent.PlayCronFailed,
61
+ ProductNotificationEvent.PlayWebhookSucceeded,
62
+ ProductNotificationEvent.PlayWebhookFailed,
63
+ ] as const;
64
+
65
+ export type ProductNotificationEventName =
66
+ | (typeof PRODUCT_NOTIFICATION_EVENT_NAMES)[number]
67
+ | (typeof PRODUCT_NOTIFICATION_COMPATIBILITY_EVENT_NAMES)[number];
68
+
69
+ export type ProductNotificationCanonicalEvent = {
70
+ orgId: string;
71
+ producerKey: ProductNotificationProducerKey;
72
+ sourceEventId: string;
73
+ eventName: ProductNotificationEventName;
74
+ eventSchemaVersion: typeof PRODUCT_NOTIFICATION_EVENT_SCHEMA_VERSION;
75
+ occurredAt: number;
76
+ admittedAt: number;
77
+ payload: ProductNotificationFacts;
78
+ };
79
+
80
+ type FactType = 'string' | 'number' | 'boolean';
81
+ export type ProductNotificationEventDefinition = {
82
+ eventName: ProductNotificationEventName;
83
+ producerKey: ProductNotificationProducerKey;
84
+ requiredFacts: Record<string, FactType>;
85
+ optionalFacts?: Record<string, FactType>;
86
+ orderingSubjectFact: string;
87
+ allowedTriggers: ProductNotificationTrigger['kind'][];
88
+ allowedThresholdUnits?: string[];
89
+ };
90
+
91
+ export const PRODUCT_NOTIFICATION_EVENT_DEFINITIONS: readonly ProductNotificationEventDefinition[] =
92
+ [
93
+ {
94
+ eventName: ProductNotificationEvent.CreditsBalanceChanged,
95
+ producerKey: ProductNotificationProducerKey.BillingCredits,
96
+ requiredFacts: {
97
+ accountId: 'string',
98
+ previousCredits: 'number',
99
+ currentCredits: 'number',
100
+ targetUrl: 'string',
101
+ },
102
+ orderingSubjectFact: 'accountId',
103
+ allowedTriggers: ['threshold_crossing'],
104
+ allowedThresholdUnits: ['credits'],
105
+ },
106
+ {
107
+ eventName: ProductNotificationEvent.MonitorLifecycleChanged,
108
+ producerKey: ProductNotificationProducerKey.MonitorsLifecycle,
109
+ requiredFacts: {
110
+ monitorId: 'string',
111
+ monitorName: 'string',
112
+ previousState: 'string',
113
+ currentState: 'string',
114
+ reasonCode: 'string',
115
+ targetUrl: 'string',
116
+ },
117
+ orderingSubjectFact: 'monitorId',
118
+ optionalFacts: { previousReasonCode: 'string' },
119
+ allowedTriggers: ['state_transition'],
120
+ },
121
+ {
122
+ eventName: ProductNotificationEvent.PlayLifecycleChanged,
123
+ producerKey: ProductNotificationProducerKey.PlaysLifecycle,
124
+ requiredFacts: {
125
+ playId: 'string',
126
+ playName: 'string',
127
+ previousState: 'string',
128
+ currentState: 'string',
129
+ reasonCode: 'string',
130
+ targetUrl: 'string',
131
+ },
132
+ orderingSubjectFact: 'playId',
133
+ optionalFacts: { previousReasonCode: 'string' },
134
+ allowedTriggers: ['state_transition'],
135
+ },
136
+ {
137
+ eventName: ProductNotificationEvent.PlayRunCompleted,
138
+ producerKey: ProductNotificationProducerKey.PlaysRuns,
139
+ requiredFacts: {
140
+ playId: 'string',
141
+ playName: 'string',
142
+ runId: 'string',
143
+ outcome: 'string',
144
+ targetUrl: 'string',
145
+ },
146
+ optionalFacts: {
147
+ triggerKind: 'string',
148
+ },
149
+ orderingSubjectFact: 'playId',
150
+ allowedTriggers: ['each_match', 'consecutive_outcomes'],
151
+ },
152
+ {
153
+ eventName: ProductNotificationEvent.WebhookDeliveryCompleted,
154
+ producerKey: ProductNotificationProducerKey.WebhooksDelivery,
155
+ requiredFacts: {
156
+ endpointId: 'string',
157
+ endpointName: 'string',
158
+ deliveryId: 'string',
159
+ outcome: 'string',
160
+ targetUrl: 'string',
161
+ },
162
+ orderingSubjectFact: 'endpointId',
163
+ allowedTriggers: ['each_match', 'consecutive_outcomes'],
164
+ },
165
+ {
166
+ eventName: ProductNotificationEvent.CreditsUsageRecorded,
167
+ producerKey: ProductNotificationProducerKey.BillingUsage,
168
+ requiredFacts: {
169
+ accountId: 'string',
170
+ creditsUsed: 'number',
171
+ limitDenied: 'boolean',
172
+ targetUrl: 'string',
173
+ },
174
+ orderingSubjectFact: 'accountId',
175
+ allowedTriggers: ['threshold_crossing'],
176
+ allowedThresholdUnits: ['percent', 'usage'],
177
+ },
178
+ ...PRODUCT_NOTIFICATION_COMPATIBILITY_EVENT_NAMES.map((eventName) => ({
179
+ eventName,
180
+ producerKey: ProductNotificationProducerKey.LegacyProductNotifications,
181
+ requiredFacts: {
182
+ playId: 'string' as const,
183
+ playName: 'string' as const,
184
+ targetUrl: 'string' as const,
185
+ },
186
+ optionalFacts: {
187
+ runId: 'string' as const,
188
+ reasonCode: 'string' as const,
189
+ reason: 'string' as const,
190
+ },
191
+ orderingSubjectFact: 'playId',
192
+ allowedTriggers: ['each_match' as const],
193
+ })),
194
+ ];
195
+
196
+ export function getProductNotificationEventDefinition(
197
+ eventName: string,
198
+ ): ProductNotificationEventDefinition {
199
+ const definition = PRODUCT_NOTIFICATION_EVENT_DEFINITIONS.find(
200
+ (candidate) => candidate.eventName === eventName,
201
+ );
202
+ if (!definition) throw new Error(`Unknown notification event ${eventName}.`);
203
+ return definition;
204
+ }
205
+
206
+ function requiredString(value: unknown, field: string) {
207
+ if (typeof value !== 'string' || !value.trim()) {
208
+ throw new Error(`${field} must be a non-empty string.`);
209
+ }
210
+ if (value.length > 512) throw new Error(`${field} is too long.`);
211
+ }
212
+
213
+ function requireInternalTargetPath(value: unknown) {
214
+ requiredString(value, 'targetUrl');
215
+ if (
216
+ typeof value !== 'string' ||
217
+ !value.startsWith('/') ||
218
+ value.startsWith('//') ||
219
+ value.includes('\\') ||
220
+ /[\u0000-\u001f\u007f]/.test(value)
221
+ ) {
222
+ throw new Error('targetUrl must be a safe internal path.');
223
+ }
224
+ }
225
+
226
+ /** Validate the semantic event contract after the producer transaction commits. */
227
+ export function validateProductNotificationEvent(
228
+ event: ProductNotificationCanonicalEvent,
229
+ now: number,
230
+ ) {
231
+ const definition = getProductNotificationEventDefinition(event.eventName);
232
+ requiredString(event.orgId, 'orgId');
233
+ requiredString(event.producerKey, 'producerKey');
234
+ requiredString(event.sourceEventId, 'sourceEventId');
235
+ if (event.producerKey !== definition.producerKey) {
236
+ throw new Error(`${event.producerKey} cannot produce ${event.eventName}.`);
237
+ }
238
+ if (event.eventSchemaVersion !== PRODUCT_NOTIFICATION_EVENT_SCHEMA_VERSION) {
239
+ throw new Error(
240
+ `Unsupported ${event.eventName} schema version ${event.eventSchemaVersion}.`,
241
+ );
242
+ }
243
+ if (
244
+ !Number.isFinite(event.occurredAt) ||
245
+ !Number.isFinite(event.admittedAt) ||
246
+ !Number.isFinite(now)
247
+ ) {
248
+ throw new Error('Event timestamps must be finite.');
249
+ }
250
+ if (event.occurredAt < now - PRODUCT_NOTIFICATION_MAX_EVENT_AGE_MS) {
251
+ throw new Error('Notification event is older than 30 days.');
252
+ }
253
+ if (event.admittedAt > now) {
254
+ throw new Error('Notification admission time is in the future.');
255
+ }
256
+ if (
257
+ event.occurredAt >
258
+ event.admittedAt + PRODUCT_NOTIFICATION_MAX_SOURCE_CLOCK_SKEW_MS
259
+ ) {
260
+ throw new Error(
261
+ 'Notification event exceeds the allowed source clock skew.',
262
+ );
263
+ }
264
+ const allowedFacts = {
265
+ ...definition.requiredFacts,
266
+ ...definition.optionalFacts,
267
+ };
268
+ const entries = Object.entries(event.payload);
269
+ if (entries.length > PRODUCT_NOTIFICATION_MAX_EVENT_FACTS) {
270
+ throw new Error('Notification event contains too many facts.');
271
+ }
272
+ for (const [fact, expectedType] of Object.entries(definition.requiredFacts)) {
273
+ const value = event.payload[fact];
274
+ if (typeof value !== expectedType) {
275
+ throw new Error(`${event.eventName}.${fact} must be ${expectedType}.`);
276
+ }
277
+ if (expectedType === 'string') requiredString(value, fact);
278
+ if (expectedType === 'number' && !Number.isFinite(value)) {
279
+ throw new Error(`${event.eventName}.${fact} must be finite.`);
280
+ }
281
+ }
282
+ for (const [fact, value] of entries) {
283
+ const expectedType = allowedFacts[fact];
284
+ if (!expectedType) {
285
+ throw new Error(`${event.eventName} does not accept fact ${fact}.`);
286
+ }
287
+ if (typeof value !== expectedType) {
288
+ throw new Error(`${event.eventName}.${fact} must be ${expectedType}.`);
289
+ }
290
+ if (expectedType === 'string') requiredString(value, fact);
291
+ if (expectedType === 'number' && !Number.isFinite(value)) {
292
+ throw new Error(`${event.eventName}.${fact} must be finite.`);
293
+ }
294
+ }
295
+ requireInternalTargetPath(event.payload.targetUrl);
296
+ if (
297
+ new TextEncoder().encode(JSON.stringify(event)).byteLength >
298
+ PRODUCT_NOTIFICATION_MAX_EVENT_BYTES
299
+ ) {
300
+ throw new Error('Notification event exceeds its byte bound.');
301
+ }
302
+ return definition;
303
+ }
304
+
305
+ export function productNotificationOrderingKey(
306
+ event: ProductNotificationCanonicalEvent,
307
+ ) {
308
+ const definition = getProductNotificationEventDefinition(event.eventName);
309
+ return `${event.eventName}/${String(
310
+ event.payload[definition.orderingSubjectFact],
311
+ )}`;
312
+ }
313
+
314
+ export function compareProductNotificationOrder(
315
+ left: { occurredAt: number; sourceEventId: string },
316
+ right: { occurredAt: number; sourceEventId: string },
317
+ ) {
318
+ return (
319
+ left.occurredAt - right.occurredAt ||
320
+ left.sourceEventId.localeCompare(right.sourceEventId)
321
+ );
322
+ }
323
+
324
+ export function productNotificationCanonicalOrder(
325
+ event: Pick<
326
+ ProductNotificationCanonicalEvent,
327
+ 'occurredAt' | 'sourceEventId'
328
+ >,
329
+ ) {
330
+ return [event.occurredAt, event.sourceEventId] as const;
331
+ }
332
+
333
+ export function productNotificationTriggerIsAllowed(
334
+ eventName: ProductNotificationEventName,
335
+ trigger: ProductNotificationTrigger,
336
+ ) {
337
+ const definition = getProductNotificationEventDefinition(eventName);
338
+ if (!definition.allowedTriggers.includes(trigger.kind)) return false;
339
+ return (
340
+ trigger.kind !== 'threshold_crossing' ||
341
+ trigger.unit === undefined ||
342
+ definition.allowedThresholdUnits?.includes(trigger.unit) === true
343
+ );
344
+ }
345
+
346
+ /** Convert a registered event into the generic observation a trigger consumes. */
347
+ export function adaptProductNotificationObservation(input: {
348
+ event: ProductNotificationCanonicalEvent;
349
+ trigger: ProductNotificationTrigger;
350
+ outcomeHistory?: ProductNotificationOutcomeFact[];
351
+ }): ProductNotificationObservation {
352
+ const { event, trigger } = input;
353
+ if (!productNotificationTriggerIsAllowed(event.eventName, trigger)) {
354
+ throw new Error(`${trigger.kind} is not allowed for ${event.eventName}.`);
355
+ }
356
+ if (trigger.kind === 'each_match') return { kind: 'match' };
357
+ if (trigger.kind === 'state_transition') {
358
+ return {
359
+ kind: 'state_transition',
360
+ previousState: String(event.payload.previousState),
361
+ currentState: String(event.payload.currentState),
362
+ previousReasonCode:
363
+ typeof event.payload.previousReasonCode === 'string'
364
+ ? event.payload.previousReasonCode
365
+ : undefined,
366
+ currentReasonCode: String(event.payload.reasonCode),
367
+ reasonCode: String(event.payload.reasonCode),
368
+ };
369
+ }
370
+ if (trigger.kind === 'consecutive_outcomes') {
371
+ if (!input.outcomeHistory) {
372
+ throw new Error(`${event.eventName} requires bounded outcome history.`);
373
+ }
374
+ const current = input.outcomeHistory[0];
375
+ const orderingKey = productNotificationOrderingKey(event);
376
+ if (
377
+ !current ||
378
+ input.outcomeHistory.some(
379
+ (outcome) => outcome.orderingKey !== orderingKey,
380
+ ) ||
381
+ current.sourceEventId !== event.sourceEventId ||
382
+ current.occurredAt !== event.occurredAt ||
383
+ current.outcome !== event.payload.outcome
384
+ ) {
385
+ throw new Error(
386
+ `${event.eventName} outcome history must begin with the current event.`,
387
+ );
388
+ }
389
+ return { kind: 'outcome_history', outcomes: input.outcomeHistory };
390
+ }
391
+ if (event.eventName === ProductNotificationEvent.CreditsBalanceChanged) {
392
+ return {
393
+ kind: 'threshold_crossing',
394
+ previousValue: Number(event.payload.previousCredits),
395
+ currentValue: Number(event.payload.currentCredits),
396
+ unit: 'credits',
397
+ };
398
+ }
399
+ const limit = Number(event.payload.limit);
400
+ if (event.eventName === ProductNotificationEvent.CreditsUsageRecorded) {
401
+ if (!(limit > 0)) throw new Error('Monthly usage limit must be positive.');
402
+ return {
403
+ kind: 'threshold_state',
404
+ currentValue: (Number(event.payload.currentUsage) / limit) * 100,
405
+ unit: 'percent',
406
+ };
407
+ }
408
+ throw new Error(`${event.eventName} has no threshold observation adapter.`);
409
+ }
410
+
411
+ /** Fingerprint identity excludes admission time so forwarding retries are equal. */
412
+ export async function productNotificationEventFingerprint(
413
+ event: ProductNotificationCanonicalEvent,
414
+ ) {
415
+ const canonical = JSON.stringify({
416
+ orgId: event.orgId,
417
+ producerKey: event.producerKey,
418
+ sourceEventId: event.sourceEventId,
419
+ eventName: event.eventName,
420
+ eventSchemaVersion: event.eventSchemaVersion,
421
+ occurredAt: event.occurredAt,
422
+ payload: Object.fromEntries(
423
+ Object.entries(event.payload).sort(([left], [right]) =>
424
+ left.localeCompare(right),
425
+ ),
426
+ ),
427
+ });
428
+ const bytes = new TextEncoder().encode(canonical);
429
+ const digest = await crypto.subtle.digest('SHA-256', bytes);
430
+ return [...new Uint8Array(digest)]
431
+ .map((value) => value.toString(16).padStart(2, '0'))
432
+ .join('');
433
+ }
@@ -0,0 +1,80 @@
1
+ import type {
2
+ ProductNotificationDefaultGroup,
3
+ ProductNotificationDefaultRule,
4
+ } from './configuration';
5
+ import {
6
+ PRODUCT_NOTIFICATION_EVENT_CATALOG,
7
+ type ProductNotificationEventType,
8
+ } from './contract';
9
+
10
+ const TYPE_BY_LEGACY_EVENT = {
11
+ 'play.cron.succeeded': 'compat.play.cron.succeeded',
12
+ 'play.cron.failed': 'compat.play.cron.failed',
13
+ 'play.webhook.succeeded': 'compat.play.webhook.succeeded',
14
+ 'play.webhook.failed': 'compat.play.webhook.failed',
15
+ } as const;
16
+
17
+ export function legacySlackNotificationType(
18
+ eventType: ProductNotificationEventType,
19
+ ) {
20
+ return TYPE_BY_LEGACY_EVENT[eventType];
21
+ }
22
+
23
+ export function legacySlackNotificationTypeMetadata(notificationType: string) {
24
+ const event = PRODUCT_NOTIFICATION_EVENT_CATALOG.find(
25
+ ({ id }) => TYPE_BY_LEGACY_EVENT[id] === notificationType,
26
+ );
27
+ return event
28
+ ? { name: event.label, description: event.description }
29
+ : undefined;
30
+ }
31
+
32
+ function legacyPrefix(destinationId: string) {
33
+ if (!destinationId)
34
+ throw new Error('Legacy Slack destination ID is required.');
35
+ return `legacy.slack.${destinationId}`;
36
+ }
37
+
38
+ export function isLegacySlackCompatibilityKey(value: string) {
39
+ return value.startsWith('legacy.slack.');
40
+ }
41
+
42
+ export function legacySlackGroupKey(destinationId: string) {
43
+ return `${legacyPrefix(destinationId)}.group`;
44
+ }
45
+
46
+ export function legacySlackTargetConfiguration(input: {
47
+ destinationId: string;
48
+ destinationName: string;
49
+ subscriptions: readonly {
50
+ eventType: ProductNotificationEventType;
51
+ enabled: boolean;
52
+ }[];
53
+ }): {
54
+ group: ProductNotificationDefaultGroup;
55
+ rules: ProductNotificationDefaultRule[];
56
+ } {
57
+ const prefix = legacyPrefix(input.destinationId);
58
+ return {
59
+ group: {
60
+ groupKey: legacySlackGroupKey(input.destinationId),
61
+ name: input.destinationName,
62
+ enabled: true,
63
+ deliveryTiming: { mode: 'immediate' },
64
+ },
65
+ rules: input.subscriptions.map((subscription) => ({
66
+ ruleKey: `${prefix}.${subscription.eventType}`,
67
+ groupKey: legacySlackGroupKey(input.destinationId),
68
+ enabled: subscription.enabled,
69
+ notificationType: legacySlackNotificationType(subscription.eventType),
70
+ eventName: subscription.eventType,
71
+ eventFilter: {},
72
+ trigger: { kind: 'each_match' },
73
+ repeatMode: 'every_match',
74
+ })),
75
+ };
76
+ }
77
+
78
+ export function legacySlackDestinationKey(destinationId: string) {
79
+ return `${legacyPrefix(destinationId)}.destination`;
80
+ }
@@ -0,0 +1,18 @@
1
+ export const NOTIFICATION_GROUP_WINDOW_MS = 60 * 60_000;
2
+ export const NOTIFICATION_GROUP_HOURLY_LIMIT = 10;
3
+ const DIGEST_ITEM_LIMIT = 100;
4
+ // Bound the whole preview so 100 entries fit within a Convex document.
5
+ const DIGEST_PREVIEW_CHARACTERS = 1_000;
6
+
7
+ type OverflowItem = { ruleKey: string; summary: string };
8
+
9
+ export function appendGroupOverflowItem(
10
+ previous: readonly OverflowItem[],
11
+ item: OverflowItem,
12
+ ): OverflowItem[] {
13
+ const summary =
14
+ item.summary.length <= DIGEST_PREVIEW_CHARACTERS
15
+ ? item.summary
16
+ : `${item.summary.slice(0, DIGEST_PREVIEW_CHARACTERS - 1)}…`;
17
+ return [...previous, { ...item, summary }].slice(-DIGEST_ITEM_LIMIT);
18
+ }
@@ -0,0 +1,24 @@
1
+ export const NOTIFICATION_RULE_IMMEDIATE_LIMIT = 10;
2
+
3
+ /** Admit below the rolling limit; otherwise anchor the digest to its oldest admission. */
4
+ export function admitRollingNotification(
5
+ admittedAt: readonly number[],
6
+ now: number,
7
+ windowMs: number,
8
+ limit: number,
9
+ ): { admittedAt: number[]; digestAt: number | null } {
10
+ const history = [...admittedAt].sort((left, right) => left - right);
11
+ const inWindow = history.filter((time) => time > now - windowMs);
12
+ if (inWindow.length >= limit) {
13
+ return {
14
+ admittedAt: history,
15
+ digestAt: inWindow[inWindow.length - limit]! + windowMs,
16
+ };
17
+ }
18
+ return {
19
+ admittedAt: [...history, now]
20
+ .sort((left, right) => left - right)
21
+ .slice(-limit),
22
+ digestAt: null,
23
+ };
24
+ }