deepline 0.3.89 → 0.3.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/contracts/install-commands.json +29 -0
  2. package/dist/bundling-sources/sdk/src/client.ts +221 -43
  3. package/dist/bundling-sources/sdk/src/index.ts +4 -0
  4. package/dist/bundling-sources/sdk/src/monitor-fleet-contract.ts +2 -556
  5. package/dist/bundling-sources/sdk/src/monitor-fleets.ts +2 -2
  6. package/dist/bundling-sources/sdk/src/pagination.ts +25 -0
  7. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
  8. package/dist/bundling-sources/sdk/src/release.ts +11 -9
  9. package/dist/bundling-sources/sdk/src/types.ts +29 -1
  10. package/dist/bundling-sources/shared_libs/integration-contracts/monitor-fleet-contract.ts +549 -0
  11. package/dist/bundling-sources/shared_libs/monitors/analytics-public.ts +10 -0
  12. package/dist/bundling-sources/shared_libs/monitors/fleets/errors.ts +96 -0
  13. package/dist/bundling-sources/shared_libs/monitors/fleets/limits.ts +8 -0
  14. package/dist/bundling-sources/shared_libs/monitors/fleets/plan.ts +320 -0
  15. package/dist/bundling-sources/shared_libs/monitors/fleets/verdict.ts +106 -0
  16. package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +8 -1
  17. package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +4 -4
  18. package/dist/bundling-sources/shared_libs/monitors/inventory-reconciliation.ts +59 -0
  19. package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +7 -9
  20. package/dist/bundling-sources/shared_libs/monitors/monitor-fleet-limits.ts +2 -12
  21. package/dist/bundling-sources/shared_libs/monitors/package.json +113 -4
  22. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +56 -9
  23. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +2 -2
  24. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +2 -2
  25. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +1 -1
  26. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +245 -0
  27. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-message.ts +38 -0
  28. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-ack-probe.ts +94 -0
  29. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-delivery.ts +60 -0
  30. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue.ts +60 -0
  31. package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +1 -1
  32. package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +2 -2
  33. package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +1 -1
  34. package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +1 -1
  35. package/dist/bundling-sources/shared_libs/observability/build-context.ts +13 -0
  36. package/dist/bundling-sources/shared_libs/observability/log-metadata.ts +160 -0
  37. package/dist/bundling-sources/shared_libs/observability/request-context.ts +68 -0
  38. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +690 -0
  39. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +35 -0
  40. package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +5 -0
  41. package/dist/bundling-sources/shared_libs/play-data-plane/neon-constants.ts +9 -0
  42. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +272 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +46 -1
  44. package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +66 -1
  45. package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +0 -1
  46. package/dist/bundling-sources/shared_libs/play-runtime/bounceban-batching.ts +137 -0
  47. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +779 -140
  48. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +46 -0
  49. package/dist/bundling-sources/shared_libs/play-runtime/daytona-payload-contract.ts +68 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +103 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +725 -0
  52. package/dist/bundling-sources/shared_libs/play-runtime/db-session-lease-store.ts +578 -0
  53. package/dist/bundling-sources/shared_libs/play-runtime/deployment/commands/roll-execution-relay.ts +521 -0
  54. package/dist/bundling-sources/shared_libs/play-runtime/deployment/commands/roll-receipt-gateway.ts +1378 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/deployment/commands/runtime-topology.ts +1024 -0
  56. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-gateway-route-probe.ts +193 -0
  57. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machine-lifecycle.ts +104 -0
  58. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +1844 -0
  59. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +21 -0
  60. package/dist/bundling-sources/shared_libs/play-runtime/deployment/process-tree.ts +40 -0
  61. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-gateway-drain.ts +262 -0
  62. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-surface.ts +98 -0
  63. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-topology.ts +303 -0
  64. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-tuple-publication-guardian.ts +70 -0
  65. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-tuple-recovery.ts +519 -0
  66. package/dist/bundling-sources/shared_libs/play-runtime/deployment/vercel-fly-rollback-alignment.ts +280 -0
  67. package/dist/bundling-sources/shared_libs/play-runtime/deployment/vercel-production-gate.ts +159 -0
  68. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +29 -0
  69. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +23 -0
  70. package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-invocation-fence.ts +442 -0
  71. package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +3 -3
  72. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +18 -0
  73. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +9 -0
  74. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +1 -1
  75. package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +1 -1
  76. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/contracts.ts +66 -0
  77. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/job.ts +145 -0
  78. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/memory-store.ts +114 -0
  79. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/ports.ts +21 -0
  80. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/postgres-store.ts +170 -0
  81. package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +1322 -0
  82. package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +2 -2
  83. package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +1 -1
  84. package/dist/bundling-sources/shared_libs/play-runtime/launch-source-policy.ts +112 -0
  85. package/dist/bundling-sources/shared_libs/play-runtime/map-execution-frame.ts +8 -0
  86. package/dist/bundling-sources/shared_libs/play-runtime/perf-trace.ts +127 -0
  87. package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +5 -0
  88. package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +24 -1
  89. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/contracts.ts +56 -0
  90. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/index.ts +13 -0
  91. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/job.ts +41 -0
  92. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/ports.ts +17 -0
  93. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts +54 -0
  94. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/contracts.ts +114 -0
  95. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/engine-suspension.ts +108 -0
  96. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/index.ts +36 -0
  97. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/job.ts +97 -0
  98. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/ports.ts +104 -0
  99. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/postgres-fence-adapter.ts +263 -0
  100. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/worker-terminal-projection.ts +64 -0
  101. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/contracts.ts +29 -0
  102. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts +56 -0
  103. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/index.ts +15 -0
  104. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/job.ts +65 -0
  105. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/ports.ts +17 -0
  106. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +42 -0
  107. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/index.ts +17 -0
  108. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +142 -0
  109. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/ports.ts +42 -0
  110. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/postgres-adapter.ts +102 -0
  111. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/contracts.ts +60 -0
  112. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/index.ts +16 -0
  113. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/job.ts +78 -0
  114. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/ports.ts +54 -0
  115. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/postgres-adapter.ts +71 -0
  116. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +4 -0
  117. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
  118. package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +5 -8
  119. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +3 -5
  120. package/dist/bundling-sources/shared_libs/play-runtime/run-identity.ts +168 -0
  121. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +44 -5
  122. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/child-play-resolver.ts +26 -0
  123. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +3662 -0
  124. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/progress-sidecar.ts +47 -0
  125. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-deadline.ts +84 -0
  126. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-gateway-transport.ts +91 -0
  127. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-heartbeat.ts +424 -0
  128. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-progress-push.ts +321 -0
  129. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-sheet-persistence-retry.ts +110 -0
  130. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +625 -0
  131. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +72 -9
  132. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +6 -12
  133. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +19 -0
  134. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/bundle.ts +0 -1
  135. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +14 -44
  136. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +103 -208
  137. package/dist/bundling-sources/shared_libs/play-runtime/runtime-authority.ts +201 -0
  138. package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +6 -0
  139. package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +67 -0
  140. package/dist/bundling-sources/shared_libs/play-runtime/runtime-release-environment.ts +2 -0
  141. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sandbox-contract.ts +68 -0
  142. package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +14 -2
  143. package/dist/bundling-sources/shared_libs/play-runtime/runtime-telemetry.ts +108 -0
  144. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +4 -0
  145. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +3 -0
  146. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +7 -0
  147. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-deadline-reconciliation.ts +88 -0
  148. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-deploy-task.ts +124 -0
  149. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-run-task.ts +68 -0
  150. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +193 -0
  151. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-lifecycle.ts +269 -0
  152. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-suffix.ts +73 -0
  153. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +6642 -0
  154. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +897 -0
  155. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-metrics.ts +120 -0
  156. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +76 -0
  157. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +476 -0
  158. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-heavy-request-admission.ts +47 -0
  159. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-progress-registry.ts +147 -0
  160. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/index.ts +27 -0
  161. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/lazy.ts +50 -0
  162. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/play-run-recovery.ts +98 -0
  163. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-budget-state.ts +260 -0
  164. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +1416 -0
  165. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +1255 -0
  166. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +942 -0
  167. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +14636 -0
  168. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +888 -0
  169. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +355 -0
  170. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-terminal-transition.ts +46 -0
  171. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runner-push.ts +60 -0
  172. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-api-origin.ts +33 -0
  173. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-gateway-health.ts +64 -0
  174. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +835 -0
  175. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +1218 -0
  176. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-operation.ts +207 -0
  177. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-scheduler-schema.ts +10 -0
  178. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-capacity.ts +123 -0
  179. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-launch-read-observability.ts +78 -0
  180. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/submit-admission.ts +169 -0
  181. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/terminal-contract.ts +20 -0
  182. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-queue-metrics.ts +34 -0
  183. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-resource-metrics.ts +249 -0
  184. package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +7 -0
  185. package/dist/bundling-sources/shared_libs/play-runtime/step-progress.ts +296 -0
  186. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/native-batch.ts +3 -3
  187. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/runtime-step-receipts-adapter.ts +20 -1
  188. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +60 -15
  189. package/dist/bundling-sources/shared_libs/play-runtime/tool-execution-outcome.ts +20 -0
  190. package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +12 -0
  191. package/dist/bundling-sources/shared_libs/play-runtime/vercel-protection.ts +14 -1
  192. package/dist/bundling-sources/shared_libs/play-runtime/webhook-receipt-retry.ts +50 -0
  193. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +165 -0
  194. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +15 -23
  195. package/dist/bundling-sources/shared_libs/play-runtime/workflow-executor-auth.ts +169 -0
  196. package/dist/bundling-sources/shared_libs/play-runtime/zerobounce-batching.ts +122 -0
  197. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +2 -0
  198. package/dist/bundling-sources/shared_libs/plays/bundling/repository-adapter.ts +24 -0
  199. package/dist/bundling-sources/shared_libs/plays/child-run-projection.ts +174 -0
  200. package/dist/bundling-sources/shared_libs/plays/contracts.ts +2 -0
  201. package/dist/bundling-sources/shared_libs/plays/deploy/api-client.ts +267 -0
  202. package/dist/bundling-sources/shared_libs/plays/deploy/control-plane-types.ts +73 -0
  203. package/dist/bundling-sources/shared_libs/plays/deploy/manifest.ts +162 -0
  204. package/dist/bundling-sources/shared_libs/plays/deploy/project-serializer.ts +87 -0
  205. package/dist/bundling-sources/shared_libs/plays/deploy/source-file-path.ts +26 -0
  206. package/dist/bundling-sources/shared_libs/plays/deploy/target-paths.ts +36 -0
  207. package/dist/bundling-sources/shared_libs/plays/deployment-status.ts +1 -1
  208. package/dist/bundling-sources/shared_libs/plays/docflow.ts +1 -1
  209. package/dist/bundling-sources/shared_libs/plays/launch/input-contract.ts +400 -0
  210. package/dist/bundling-sources/shared_libs/plays/launch/prepare.ts +96 -0
  211. package/dist/bundling-sources/shared_libs/plays/local-file-discovery.ts +385 -0
  212. package/dist/bundling-sources/shared_libs/plays/play-grep-search.ts +112 -0
  213. package/dist/bundling-sources/shared_libs/plays/play-reference.ts +117 -0
  214. package/dist/bundling-sources/shared_libs/plays/run-input-summary.ts +260 -0
  215. package/dist/bundling-sources/shared_libs/plays/run-summary-types.ts +49 -0
  216. package/dist/bundling-sources/shared_libs/plays/secrets/errors.ts +19 -0
  217. package/dist/bundling-sources/shared_libs/plays/share/copy.ts +271 -0
  218. package/dist/bundling-sources/shared_libs/plays/share/metrics.ts +140 -0
  219. package/dist/bundling-sources/shared_libs/plays/share/public-read-model.ts +86 -0
  220. package/dist/bundling-sources/shared_libs/plays/share/seo-quality.ts +181 -0
  221. package/dist/bundling-sources/shared_libs/plays/share/static-pipeline-summary.ts +658 -0
  222. package/dist/bundling-sources/shared_libs/plays/share/types.ts +197 -0
  223. package/dist/bundling-sources/shared_libs/plays/sheet-filter.ts +347 -0
  224. package/dist/bundling-sources/shared_libs/plays/slack-hitl-timeout-error.ts +37 -0
  225. package/dist/bundling-sources/shared_libs/plays/standard-webhooks.ts +117 -0
  226. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +6 -1
  227. package/dist/bundling-sources/shared_libs/plays/status-result.ts +388 -0
  228. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
  229. package/dist/bundling-sources/shared_libs/plays/transform-factor-structure.ts +377 -0
  230. package/dist/bundling-sources/shared_libs/plays/webhook-payload.ts +113 -0
  231. package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +7 -1
  232. package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +3 -2
  233. package/dist/bundling-sources/shared_libs/product-notifications/overflow.ts +18 -0
  234. package/dist/bundling-sources/shared_libs/product-notifications/rolling-limit.ts +24 -0
  235. package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +624 -0
  236. package/dist/bundling-sources/shared_libs/product-notifications/slack-payload.ts +140 -0
  237. package/dist/bundling-sources/shared_libs/product-notifications/slack-transport.ts +75 -0
  238. package/dist/bundling-sources/shared_libs/runtime-env.ts +6 -0
  239. package/dist/bundling-sources/shared_libs/security/email-blacklist.ts +42 -0
  240. package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +10 -3
  241. package/dist/bundling-sources/shared_libs/security/slack-sanitize.ts +133 -0
  242. package/dist/cli/getting-started.d.mts +52 -0
  243. package/dist/cli/getting-started.d.ts +52 -0
  244. package/dist/cli/getting-started.js +65 -0
  245. package/dist/cli/getting-started.mjs +36 -0
  246. package/dist/cli/index.d.mts +9 -0
  247. package/dist/cli/index.d.ts +9 -0
  248. package/dist/cli/index.js +895 -407
  249. package/dist/cli/index.mjs +893 -414
  250. package/dist/{compiler-manifest-DsLbQaew.d.mts → compiler-manifest-x14KL83E.d.mts} +4 -2
  251. package/dist/{compiler-manifest-DsLbQaew.d.ts → compiler-manifest-x14KL83E.d.ts} +4 -2
  252. package/dist/index.d.mts +124 -154
  253. package/dist/index.d.ts +124 -154
  254. package/dist/index.js +132 -28
  255. package/dist/index.mjs +132 -28
  256. package/dist/install-integrity.json +182 -2
  257. package/dist/monitor-fleet-contract.d.mts +131 -0
  258. package/dist/monitor-fleet-contract.d.ts +131 -0
  259. package/dist/monitor-fleet-contract.js +406 -0
  260. package/dist/monitor-fleet-contract.mjs +367 -0
  261. package/dist/plays/bundle-play-file.d.mts +2 -2
  262. package/dist/plays/bundle-play-file.d.ts +2 -2
  263. package/dist/release.d.mts +255 -0
  264. package/dist/release.d.ts +255 -0
  265. package/dist/release.js +210 -0
  266. package/dist/release.mjs +183 -0
  267. package/package.json +21 -4
@@ -0,0 +1,625 @@
1
+ import {
2
+ RUNNER_TERMINAL_CHECKPOINT_DISPOSITION,
3
+ type PlayRunnerEvent,
4
+ type PlayRunnerResult,
5
+ } from '../protocol';
6
+ import { parseCtxFetchHttpFailureDiagnostic } from '../log-provenance';
7
+ import {
8
+ RUNNER_TERMINAL_PUSH_MAX_BODY_BYTES,
9
+ TERMINAL_RUN_RESULT_MAX_BYTES,
10
+ jsonByteLength,
11
+ jsonByteLengthUpTo,
12
+ } from '../output-size-limits';
13
+ import {
14
+ PLAY_RUNTIME_TRANSPORT_ATTEMPT_HEADER,
15
+ } from '../runtime-contract';
16
+ import {
17
+ createRunnerGatewayTransportAttemptId,
18
+ runnerGatewayTransportErrorCode,
19
+ type RunnerGatewayTransportEvent,
20
+ } from './runtime-gateway-transport';
21
+ import { RUNTIME_RELIABILITY_POLICY } from '../runtime-reliability-policy';
22
+
23
+ /**
24
+ * Push-execution terminal push (runs INSIDE the Daytona sandbox, B2-final).
25
+ *
26
+ * The worker parks after the detached start; the runner's pushed terminal is
27
+ * what wakes it. This POSTs the final status-aware terminal projection to the
28
+ * receipt gateway's `runner_terminal` action, which persists it on the attempt
29
+ * row (first-write-wins) and emits the attempt-scoped absurd wake event.
30
+ * Completed and failed projections omit replay payloads; suspended projections
31
+ * retain the checkpoint required for resume.
32
+ *
33
+ * Retries are bounded and loud. A push that ultimately fails does NOT fail the
34
+ * play by itself: the structured `result` event still lands in the captured
35
+ * output file, and the parked attempt's ceiling-timeout salvage reads it from
36
+ * there — slower, but no outcome is lost.
37
+ */
38
+
39
+ const TERMINAL_PUSH_MAX_ATTEMPTS =
40
+ RUNTIME_RELIABILITY_POLICY.gateway.terminalPushMaxAttempts;
41
+ const TERMINAL_PUSH_RETRY_DELAYS_MS = [500, 1_000, 2_000, 4_000] as const;
42
+ const TERMINAL_PUSH_REQUEST_TIMEOUT_MS =
43
+ RUNTIME_RELIABILITY_POLICY.gateway.terminalPushRequestTimeoutMs;
44
+ const APP_RUNTIME_COMPAT_PATH = '/api/v2/plays/runtime';
45
+
46
+ /**
47
+ * A terminal result reserves its 5 MiB customer budget for the authored
48
+ * `output`. Runner diagnostics are useful, but they must never make a valid
49
+ * customer return too large to settle or to recover from Daytona stdout.
50
+ *
51
+ * These caps total well below the 1 MiB terminal-envelope headroom. They apply
52
+ * only to runner-owned diagnostics; returned rows and output values are never
53
+ * sliced here.
54
+ */
55
+ const TERMINAL_TRANSPORT_LOG_TAIL_MAX_BYTES = 128 * 1024;
56
+ const TERMINAL_TRANSPORT_STATS_MAX_BYTES = 96 * 1024;
57
+ const TERMINAL_TRANSPORT_STEPS_MAX_BYTES = 160 * 1024;
58
+ const TERMINAL_TRANSPORT_FAILURE_DETAILS_MAX_BYTES = 96 * 1024;
59
+ const TERMINAL_TRANSPORT_OUTPUT_WARNINGS_MAX_BYTES = 32 * 1024;
60
+ const TERMINAL_TRANSPORT_RUNTIME_DIAGNOSTICS_MAX_BYTES = 16 * 1024;
61
+ const TERMINAL_TRANSPORT_ERROR_MAX_BYTES = 64 * 1024;
62
+ const TERMINAL_TRANSPORT_TABLE_NAMESPACE_MAX_BYTES = 8 * 1024;
63
+
64
+ type CompletedRunnerResult = Extract<PlayRunnerResult, { status: 'completed' }>;
65
+ type SuspendedRunnerResult = Extract<PlayRunnerResult, { status: 'suspended' }>;
66
+ type FailedRunnerResult = Extract<PlayRunnerResult, { status: 'failed' }>;
67
+
68
+ /**
69
+ * Settlement payload carried by a detached runner's gateway POST and stdout
70
+ * salvage line. Completed and failed executions cannot resume, so their replay
71
+ * checkpoint is redundant with durable receipts and must not cross the
72
+ * gateway's bounded request-body transport. Suspended executions still need
73
+ * the exact checkpoint to resume and remain unchanged.
74
+ */
75
+ type OmittedTerminalCheckpoint = {
76
+ checkpointDisposition: typeof RUNNER_TERMINAL_CHECKPOINT_DISPOSITION.OMITTED_TERMINAL_REPLAY;
77
+ checkpointBytes: number;
78
+ };
79
+
80
+ type IncludedResumeCheckpoint = {
81
+ checkpointDisposition: typeof RUNNER_TERMINAL_CHECKPOINT_DISPOSITION.INCLUDED_RESUME_REQUIRED;
82
+ checkpointBytes: number;
83
+ };
84
+
85
+ type AbsentCheckpoint = {
86
+ checkpointDisposition: typeof RUNNER_TERMINAL_CHECKPOINT_DISPOSITION.ABSENT;
87
+ checkpointBytes: 0;
88
+ };
89
+
90
+ export type PlayRunnerTerminalTransportResult =
91
+ | (Omit<CompletedRunnerResult, 'checkpoint'> &
92
+ (OmittedTerminalCheckpoint | AbsentCheckpoint))
93
+ | (SuspendedRunnerResult & IncludedResumeCheckpoint)
94
+ | (Omit<FailedRunnerResult, 'checkpoint'> &
95
+ (OmittedTerminalCheckpoint | AbsentCheckpoint));
96
+
97
+ type SettledRunnerTerminalTransportResult = Exclude<
98
+ PlayRunnerTerminalTransportResult,
99
+ SuspendedRunnerResult & IncludedResumeCheckpoint
100
+ >;
101
+
102
+ function isTerminalTransportResult(
103
+ result: PlayRunnerResult | PlayRunnerTerminalTransportResult,
104
+ ): result is PlayRunnerTerminalTransportResult {
105
+ const disposition = (result as Partial<PlayRunnerTerminalTransportResult>)
106
+ .checkpointDisposition;
107
+ return (
108
+ disposition ===
109
+ RUNNER_TERMINAL_CHECKPOINT_DISPOSITION.OMITTED_TERMINAL_REPLAY ||
110
+ disposition ===
111
+ RUNNER_TERMINAL_CHECKPOINT_DISPOSITION.INCLUDED_RESUME_REQUIRED ||
112
+ disposition === RUNNER_TERMINAL_CHECKPOINT_DISPOSITION.ABSENT
113
+ );
114
+ }
115
+
116
+ function fitsJsonByteLimit(value: unknown, limitBytes: number): boolean {
117
+ return !jsonByteLengthUpTo(value, limitBytes).exceeded;
118
+ }
119
+
120
+ function truncateStringForJsonValue(
121
+ value: string,
122
+ limitBytes: number,
123
+ ): { value: string; truncated: boolean } {
124
+ if (fitsJsonByteLimit(value, limitBytes)) {
125
+ return { value, truncated: false };
126
+ }
127
+
128
+ const suffix = '\u2026 [truncated]';
129
+ let low = 0;
130
+ let high = value.length;
131
+ let best = suffix;
132
+ while (low <= high) {
133
+ const middle = Math.floor((low + high) / 2);
134
+ const candidate = `${value.slice(0, middle)}${suffix}`;
135
+ if (fitsJsonByteLimit(candidate, limitBytes)) {
136
+ best = candidate;
137
+ low = middle + 1;
138
+ } else {
139
+ high = middle - 1;
140
+ }
141
+ }
142
+ return { value: best, truncated: true };
143
+ }
144
+
145
+ function retainArrayWithinJsonByteLimit<T>(
146
+ values: readonly T[],
147
+ limitBytes: number,
148
+ direction: 'head' | 'tail',
149
+ ): { values: T[]; truncated: boolean } {
150
+ const retained: T[] = [];
151
+ const ordered = direction === 'tail' ? [...values].reverse() : values;
152
+ for (const value of ordered) {
153
+ const candidate =
154
+ direction === 'tail' ? [value, ...retained] : [...retained, value];
155
+ if (!fitsJsonByteLimit(candidate, limitBytes)) {
156
+ return { values: retained, truncated: true };
157
+ }
158
+ if (direction === 'tail') {
159
+ retained.unshift(value);
160
+ } else {
161
+ retained.push(value);
162
+ }
163
+ }
164
+ return { values: retained, truncated: false };
165
+ }
166
+
167
+ /**
168
+ * Retain the normal newest log tail, but reserve space for the canonical
169
+ * ctx.fetch failure diagnostics first. `runtimeDiagnostics` powers the final
170
+ * warning, while the matching raw log line is the durable evidence customers
171
+ * see through `runs logs --debug` after progress events could not be pushed.
172
+ */
173
+ function retainTerminalLogTailWithRuntimeDiagnostics(logs: readonly string[]): {
174
+ values: string[];
175
+ truncated: boolean;
176
+ } {
177
+ const retainedIndexes = new Set<number>();
178
+ let retainedBytes = 2; // JSON array brackets.
179
+ const retainIfWithinLimit = (index: number): void => {
180
+ // String encodings and separators contribute independently to a JSON
181
+ // array. Re-serializing the retained 128 KiB tail for every historical
182
+ // line made large completed runs exhaust their terminal-flush deadline.
183
+ const separatorBytes = retainedIndexes.size ? 1 : 0;
184
+ const measurement = jsonByteLengthUpTo(
185
+ logs[index]!,
186
+ TERMINAL_TRANSPORT_LOG_TAIL_MAX_BYTES - retainedBytes - separatorBytes,
187
+ );
188
+ if (measurement.exceeded) return;
189
+ retainedBytes += measurement.bytes + separatorBytes;
190
+ retainedIndexes.add(index);
191
+ };
192
+
193
+ // The newest diagnostics are the most relevant if malformed external output
194
+ // somehow exceeds the terminal transport's bounded diagnostic allowance.
195
+ for (let index = logs.length - 1; index >= 0; index -= 1) {
196
+ const line = logs[index]!;
197
+ if (!parseCtxFetchHttpFailureDiagnostic(line)) continue;
198
+ retainIfWithinLimit(index);
199
+ }
200
+
201
+ for (let index = logs.length - 1; index >= 0; index -= 1) {
202
+ if (retainedIndexes.has(index)) continue;
203
+ retainIfWithinLimit(index);
204
+ }
205
+
206
+ const indexes = [...retainedIndexes].sort((left, right) => left - right);
207
+ return {
208
+ values: indexes.map((index) => logs[index]!),
209
+ truncated: indexes.length !== logs.length,
210
+ };
211
+ }
212
+
213
+ function retainRecordWithinJsonByteLimit(
214
+ value: Record<string, unknown>,
215
+ limitBytes: number,
216
+ ): { value: Record<string, unknown>; truncated: boolean } {
217
+ if (fitsJsonByteLimit(value, limitBytes)) {
218
+ return { value, truncated: false };
219
+ }
220
+ const retained: Record<string, unknown> = {};
221
+ let truncated = false;
222
+ for (const [key, entry] of Object.entries(value)) {
223
+ const candidate = { ...retained, [key]: entry };
224
+ if (fitsJsonByteLimit(candidate, limitBytes)) {
225
+ retained[key] = entry;
226
+ } else {
227
+ truncated = true;
228
+ }
229
+ }
230
+ return { value: retained, truncated };
231
+ }
232
+
233
+ function appendTerminalDiagnosticsMarker(
234
+ logs: string[],
235
+ truncatedFields: string[],
236
+ ): string[] {
237
+ const marker =
238
+ `[deepline] terminal diagnostic metadata was bounded (${truncatedFields.join(', ')}); ` +
239
+ 'the authored play output is complete.';
240
+ const marked = [marker, ...logs];
241
+ while (
242
+ marked.length > 1 &&
243
+ !fitsJsonByteLimit(marked, TERMINAL_TRANSPORT_LOG_TAIL_MAX_BYTES)
244
+ ) {
245
+ // Preserve canonical ctx.fetch evidence when a marker itself needs room.
246
+ // Other tail lines are diagnostic context, but this line is the durable
247
+ // proof behind the final run warning and `runs logs --debug` explanation.
248
+ const removableIndex = marked.findIndex(
249
+ (line, index) =>
250
+ index > 0 && parseCtxFetchHttpFailureDiagnostic(line) === null,
251
+ );
252
+ marked.splice(removableIndex === -1 ? 1 : removableIndex, 1);
253
+ }
254
+ return fitsJsonByteLimit(marked, TERMINAL_TRANSPORT_LOG_TAIL_MAX_BYTES)
255
+ ? marked
256
+ : [marker];
257
+ }
258
+
259
+ /**
260
+ * `logs`, `stats`, and rendered `steps` are runner diagnostics. Unlike
261
+ * `output`, they have no customer-return contract and can grow with every map
262
+ * row. Project them before stdout and gateway settlement so a complete 5 MiB
263
+ * result is always recoverable after a primary Daytona push failure.
264
+ */
265
+ function boundSettledTerminalTransportDiagnostics(
266
+ result: SettledRunnerTerminalTransportResult,
267
+ ): SettledRunnerTerminalTransportResult {
268
+ const logProjection = retainTerminalLogTailWithRuntimeDiagnostics(
269
+ result.logs,
270
+ );
271
+ const statsProjection = retainRecordWithinJsonByteLimit(
272
+ result.stats,
273
+ TERMINAL_TRANSPORT_STATS_MAX_BYTES,
274
+ );
275
+ const stepsProjection = retainArrayWithinJsonByteLimit(
276
+ result.steps,
277
+ TERMINAL_TRANSPORT_STEPS_MAX_BYTES,
278
+ 'head',
279
+ );
280
+ const tableNamespace =
281
+ typeof result.tableNamespace === 'string'
282
+ ? truncateStringForJsonValue(
283
+ result.tableNamespace,
284
+ TERMINAL_TRANSPORT_TABLE_NAMESPACE_MAX_BYTES,
285
+ )
286
+ : { value: result.tableNamespace, truncated: false };
287
+ const runtimeDiagnosticsProjection = retainArrayWithinJsonByteLimit(
288
+ result.status === 'completed' ? (result.runtimeDiagnostics ?? []) : [],
289
+ TERMINAL_TRANSPORT_RUNTIME_DIAGNOSTICS_MAX_BYTES,
290
+ 'head',
291
+ );
292
+
293
+ const truncatedFields = [
294
+ ...(logProjection.truncated ? ['logs'] : []),
295
+ ...(statsProjection.truncated ? ['stats'] : []),
296
+ ...(stepsProjection.truncated ? ['steps'] : []),
297
+ ...(tableNamespace.truncated ? ['tableNamespace'] : []),
298
+ ...(runtimeDiagnosticsProjection.truncated ? ['runtimeDiagnostics'] : []),
299
+ ];
300
+
301
+ if (result.status === 'completed') {
302
+ const warningsProjection = retainArrayWithinJsonByteLimit(
303
+ result.outputWarnings ?? [],
304
+ TERMINAL_TRANSPORT_OUTPUT_WARNINGS_MAX_BYTES,
305
+ 'head',
306
+ );
307
+ if (warningsProjection.truncated) truncatedFields.push('outputWarnings');
308
+ return {
309
+ ...result,
310
+ logs:
311
+ truncatedFields.length > 0
312
+ ? appendTerminalDiagnosticsMarker(
313
+ logProjection.values,
314
+ truncatedFields,
315
+ )
316
+ : logProjection.values,
317
+ stats: statsProjection.value,
318
+ steps: stepsProjection.values,
319
+ ...(result.outputWarnings
320
+ ? { outputWarnings: warningsProjection.values }
321
+ : {}),
322
+ ...(result.runtimeDiagnostics
323
+ ? { runtimeDiagnostics: runtimeDiagnosticsProjection.values }
324
+ : {}),
325
+ ...(typeof tableNamespace.value === 'string'
326
+ ? { tableNamespace: tableNamespace.value }
327
+ : {}),
328
+ };
329
+ }
330
+
331
+ const error = truncateStringForJsonValue(
332
+ result.error,
333
+ TERMINAL_TRANSPORT_ERROR_MAX_BYTES,
334
+ );
335
+ const errorsProjection = retainArrayWithinJsonByteLimit(
336
+ result.errors ?? [],
337
+ TERMINAL_TRANSPORT_FAILURE_DETAILS_MAX_BYTES,
338
+ 'head',
339
+ );
340
+ if (error.truncated) truncatedFields.push('error');
341
+ if (errorsProjection.truncated) truncatedFields.push('errors');
342
+ return {
343
+ ...result,
344
+ error: error.value,
345
+ logs:
346
+ truncatedFields.length > 0
347
+ ? appendTerminalDiagnosticsMarker(logProjection.values, truncatedFields)
348
+ : logProjection.values,
349
+ stats: statsProjection.value,
350
+ steps: stepsProjection.values,
351
+ ...(result.errors ? { errors: errorsProjection.values } : {}),
352
+ ...(typeof tableNamespace.value === 'string'
353
+ ? { tableNamespace: tableNamespace.value }
354
+ : {}),
355
+ };
356
+ }
357
+
358
+ export function runnerTerminalResultForTransport(
359
+ result: PlayRunnerResult | PlayRunnerTerminalTransportResult,
360
+ ): PlayRunnerTerminalTransportResult {
361
+ let transportResult: PlayRunnerTerminalTransportResult;
362
+ if (isTerminalTransportResult(result)) {
363
+ transportResult = result;
364
+ } else {
365
+ // `isTerminalTransportResult` separates the optional transport shape from
366
+ // the runner's canonical result. Keep the raw result type here so a
367
+ // completed checkpoint remains required by that canonical contract.
368
+ const rawResult = result as PlayRunnerResult;
369
+ if (rawResult.status === 'suspended') {
370
+ transportResult = {
371
+ ...rawResult,
372
+ checkpointDisposition:
373
+ RUNNER_TERMINAL_CHECKPOINT_DISPOSITION.INCLUDED_RESUME_REQUIRED,
374
+ checkpointBytes: jsonByteLength(rawResult.checkpoint),
375
+ };
376
+ } else {
377
+ const { checkpoint, ...terminal } = rawResult;
378
+ transportResult =
379
+ checkpoint === null || checkpoint === undefined
380
+ ? {
381
+ ...terminal,
382
+ checkpointDisposition:
383
+ RUNNER_TERMINAL_CHECKPOINT_DISPOSITION.ABSENT,
384
+ checkpointBytes: 0,
385
+ }
386
+ : {
387
+ ...terminal,
388
+ checkpointDisposition:
389
+ RUNNER_TERMINAL_CHECKPOINT_DISPOSITION.OMITTED_TERMINAL_REPLAY,
390
+ checkpointBytes: jsonByteLength(checkpoint),
391
+ };
392
+ }
393
+ }
394
+ if (transportResult.status === 'suspended') {
395
+ // A suspended result retains its exact checkpoint because it is needed to
396
+ // resume. Its checkpoint follows the dedicated receipt transport contract.
397
+ return transportResult;
398
+ }
399
+ const bounded = boundSettledTerminalTransportDiagnostics(transportResult);
400
+ if (!fitsJsonByteLimit(bounded, TERMINAL_RUN_RESULT_MAX_BYTES)) {
401
+ throw new Error(
402
+ 'Terminal result exceeded its durable envelope after runner diagnostics were bounded.',
403
+ );
404
+ }
405
+ return bounded;
406
+ }
407
+
408
+ export interface PushRunnerTerminalOptions {
409
+ gatewayBaseUrl: string;
410
+ executorToken: string;
411
+ runId: string;
412
+ result: PlayRunnerResult | PlayRunnerTerminalTransportResult;
413
+ finalProgressEvents?: PlayRunnerEvent[];
414
+ finalProgressLogOffset?: number;
415
+ /** Injectable for tests. Defaults to a bearer POST to the gateway. */
416
+ fetchImpl?: typeof fetch;
417
+ sleepImpl?: (ms: number) => Promise<void>;
418
+ nowImpl?: () => number;
419
+ createTransportAttemptId?: () => string;
420
+ /** Per-attempt HTTP deadline. A hung gateway request must not suppress the
421
+ * remaining bounded retries. */
422
+ requestTimeoutMs?: number;
423
+ warn?: (message: string, detail: Record<string, unknown>) => void;
424
+ onTransport?: (event: RunnerGatewayTransportEvent) => void;
425
+ }
426
+
427
+ type RunnerTerminalRequestBody = {
428
+ action: 'runner_terminal';
429
+ runId: string;
430
+ result: PlayRunnerTerminalTransportResult;
431
+ finalProgressLogOffset?: number;
432
+ finalProgressEvents?: PlayRunnerEvent[];
433
+ };
434
+
435
+ function durableProgressLogCount(events: readonly PlayRunnerEvent[]): number {
436
+ return events.reduce(
437
+ (count, event) =>
438
+ event.type === 'log' && event.source !== 'worker' && event.line.length > 0
439
+ ? count + 1
440
+ : count,
441
+ 0,
442
+ );
443
+ }
444
+
445
+ /** Keep the newest recovery observations without ever exceeding the gateway. */
446
+ function terminalRequestBody(input: {
447
+ runId: string;
448
+ result: PlayRunnerTerminalTransportResult;
449
+ finalProgressEvents?: PlayRunnerEvent[];
450
+ finalProgressLogOffset?: number;
451
+ }): { body: RunnerTerminalRequestBody; droppedProgressEvents: number } {
452
+ const events = input.finalProgressEvents ?? [];
453
+ const bodyFor = (
454
+ droppedProgressEvents: number,
455
+ ): RunnerTerminalRequestBody => {
456
+ const retainedEvents = events.slice(droppedProgressEvents);
457
+ return {
458
+ action: 'runner_terminal',
459
+ runId: input.runId,
460
+ result: input.result,
461
+ ...(input.finalProgressLogOffset !== undefined
462
+ ? {
463
+ finalProgressLogOffset:
464
+ input.finalProgressLogOffset +
465
+ durableProgressLogCount(events.slice(0, droppedProgressEvents)),
466
+ }
467
+ : {}),
468
+ ...(retainedEvents.length ? { finalProgressEvents: retainedEvents } : {}),
469
+ };
470
+ };
471
+
472
+ if (
473
+ !jsonByteLengthUpTo(bodyFor(0), RUNNER_TERMINAL_PUSH_MAX_BODY_BYTES)
474
+ .exceeded
475
+ ) {
476
+ return { body: bodyFor(0), droppedProgressEvents: 0 };
477
+ }
478
+
479
+ // Dropping a prefix is monotonic for ordinary PlayRunnerEvent JSON. Binary
480
+ // search avoids repeatedly serializing a potentially multi-megabyte tail.
481
+ let low = 1;
482
+ let high = events.length;
483
+ let retained = bodyFor(events.length);
484
+ let droppedProgressEvents = events.length;
485
+ while (low <= high) {
486
+ const middle = Math.floor((low + high) / 2);
487
+ const candidate = bodyFor(middle);
488
+ if (
489
+ jsonByteLengthUpTo(candidate, RUNNER_TERMINAL_PUSH_MAX_BODY_BYTES)
490
+ .exceeded
491
+ ) {
492
+ low = middle + 1;
493
+ } else {
494
+ retained = candidate;
495
+ droppedProgressEvents = middle;
496
+ high = middle - 1;
497
+ }
498
+ }
499
+ return { body: retained, droppedProgressEvents };
500
+ }
501
+
502
+ export async function pushRunnerTerminal(
503
+ options: PushRunnerTerminalOptions,
504
+ ): Promise<boolean> {
505
+ const fetchImpl = options.fetchImpl ?? fetch;
506
+ const now = options.nowImpl ?? Date.now;
507
+ const sleepImpl =
508
+ options.sleepImpl ??
509
+ ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)));
510
+ const warn =
511
+ options.warn ??
512
+ ((message, detail) =>
513
+ console.warn(`[play-runner.terminal-push] ${message}`, detail));
514
+ const url = `${options.gatewayBaseUrl.replace(/\/$/, '')}${APP_RUNTIME_COMPAT_PATH}`;
515
+ const result = runnerTerminalResultForTransport(options.result);
516
+ const request = terminalRequestBody({
517
+ runId: options.runId,
518
+ result,
519
+ finalProgressEvents: options.finalProgressEvents,
520
+ finalProgressLogOffset: options.finalProgressLogOffset,
521
+ });
522
+ if (request.droppedProgressEvents > 0) {
523
+ warn('terminal_progress_truncated', {
524
+ runId: options.runId,
525
+ retainedEvents: request.body.finalProgressEvents?.length ?? 0,
526
+ droppedEvents: request.droppedProgressEvents,
527
+ requestBytes: jsonByteLength(request.body),
528
+ });
529
+ }
530
+ const requestBody = JSON.stringify(request.body);
531
+ let lastError = '';
532
+ for (let attempt = 1; attempt <= TERMINAL_PUSH_MAX_ATTEMPTS; attempt += 1) {
533
+ const startedAt = now();
534
+ const transportAttemptId =
535
+ options.createTransportAttemptId?.() ??
536
+ createRunnerGatewayTransportAttemptId();
537
+ const reportTransport = (
538
+ outcome: RunnerGatewayTransportEvent['outcome'],
539
+ detail: Pick<RunnerGatewayTransportEvent, 'status' | 'errorCode'> = {},
540
+ ) => {
541
+ const event: RunnerGatewayTransportEvent = {
542
+ operation: 'runner_terminal',
543
+ attempt,
544
+ transportAttemptId,
545
+ durationMs: Math.max(0, now() - startedAt),
546
+ outcome,
547
+ ...detail,
548
+ };
549
+ if (outcome !== 'ok') {
550
+ warn('gateway_transport', { runId: options.runId, ...event });
551
+ }
552
+ try {
553
+ options.onTransport?.(event);
554
+ } catch {
555
+ // Diagnostics must not interfere with terminal persistence or salvage.
556
+ }
557
+ };
558
+ const requestController = new AbortController();
559
+ const requestTimeout = setTimeout(
560
+ () =>
561
+ requestController.abort(
562
+ new Error(
563
+ `runner_terminal request exceeded ${
564
+ options.requestTimeoutMs ?? TERMINAL_PUSH_REQUEST_TIMEOUT_MS
565
+ }ms`,
566
+ ),
567
+ ),
568
+ options.requestTimeoutMs ?? TERMINAL_PUSH_REQUEST_TIMEOUT_MS,
569
+ );
570
+ requestTimeout.unref?.();
571
+ try {
572
+ const response = await fetchImpl(url, {
573
+ method: 'POST',
574
+ headers: {
575
+ 'content-type': 'application/json',
576
+ authorization: `Bearer ${options.executorToken}`,
577
+ [PLAY_RUNTIME_TRANSPORT_ATTEMPT_HEADER]: transportAttemptId,
578
+ },
579
+ body: requestBody,
580
+ redirect: 'manual',
581
+ signal: requestController.signal,
582
+ });
583
+ if (response.ok) {
584
+ await response.text().catch(() => '');
585
+ reportTransport('ok', { status: response.status });
586
+ return true;
587
+ }
588
+ const body = await response.text().catch(() => '');
589
+ lastError = `runner_terminal failed (${response.status}): ${body}`;
590
+ reportTransport(
591
+ response.status >= 500
592
+ ? 'gateway_5xx'
593
+ : response.status >= 400
594
+ ? 'gateway_4xx'
595
+ : 'redirect',
596
+ { status: response.status },
597
+ );
598
+ // 4xx (scope/fence rejections) are deterministic — retrying cannot help.
599
+ if (response.status >= 400 && response.status < 500) {
600
+ warn('terminal_push_rejected', {
601
+ runId: options.runId,
602
+ status: response.status,
603
+ body,
604
+ });
605
+ return false;
606
+ }
607
+ } catch (error) {
608
+ lastError = error instanceof Error ? error.message : String(error);
609
+ reportTransport('network_error', {
610
+ errorCode: runnerGatewayTransportErrorCode(error),
611
+ });
612
+ } finally {
613
+ clearTimeout(requestTimeout);
614
+ }
615
+ if (attempt < TERMINAL_PUSH_MAX_ATTEMPTS) {
616
+ await sleepImpl(TERMINAL_PUSH_RETRY_DELAYS_MS[attempt - 1] ?? 4_000);
617
+ }
618
+ }
619
+ warn('terminal_push_exhausted', {
620
+ runId: options.runId,
621
+ attempts: TERMINAL_PUSH_MAX_ATTEMPTS,
622
+ lastError,
623
+ });
624
+ return false;
625
+ }