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,260 @@
1
+ /**
2
+ * Display-only, size-bounded projection of a play run's input payload.
3
+ *
4
+ * The full input is intentionally NOT persisted in Convex: it can be up to
5
+ * `PLAY_SUBMIT_INPUT_MAX_BYTES` (1MB) and would bloat the hot-path run-start
6
+ * write (and risk the ~1MB Convex document limit). This builds a tiny summary —
7
+ * top-level keys with scalar values truncated and non-scalar values elided to a
8
+ * compact placeholder — purely so the runs UI can show "what was this called
9
+ * with". It is bounded hard so it only adds negligible bytes to the existing
10
+ * start-row write and never touches latency.
11
+ *
12
+ * Scalar values are passed through the shared secret redaction (key-aware, plus
13
+ * value-pattern/high-entropy heuristics) before truncation, mirroring the run
14
+ * *output* preview path — so an input field like `api_key`/`token`/`password`,
15
+ * or a secret-looking value, is never persisted or rendered back in the UI.
16
+ */
17
+
18
+ import { redactSecretsInCustomerValue } from '../security/secret-redaction';
19
+
20
+ const MAX_KEYS = 24;
21
+ const MAX_STRING_CHARS = 120;
22
+ const MAX_NESTED_VALUE_CHARS = 52;
23
+ const MAX_OBJECT_PARTS = 4;
24
+ const MAX_ARRAY_PARTS = 3;
25
+ const MAX_TOTAL_BYTES = 2_000;
26
+
27
+ const OBJECT_PREVIEW_KEYS = [
28
+ 'full_name',
29
+ 'fullName',
30
+ 'name',
31
+ 'first_name',
32
+ 'firstName',
33
+ 'last_name',
34
+ 'lastName',
35
+ 'title',
36
+ 'role',
37
+ 'company_name',
38
+ 'companyName',
39
+ 'company',
40
+ 'domain',
41
+ 'company_domain',
42
+ 'companyDomain',
43
+ 'email',
44
+ 'work_email',
45
+ 'workEmail',
46
+ 'personal_email',
47
+ 'personalEmail',
48
+ 'linkedin_url',
49
+ 'linkedinUrl',
50
+ 'url',
51
+ 'website',
52
+ 'operation',
53
+ 'changedAt',
54
+ 'changed_at',
55
+ 'createdAt',
56
+ 'created_at',
57
+ ] as const;
58
+
59
+ const LOW_SIGNAL_PREVIEW_KEYS = new Set([
60
+ 'id',
61
+ '_id',
62
+ 'key',
63
+ 'metadata',
64
+ 'raw',
65
+ 'debug',
66
+ 'payload',
67
+ 'headers',
68
+ ]);
69
+
70
+ function truncateString(value: string, maxChars: number): string {
71
+ return value.length > maxChars ? `${value.slice(0, maxChars)}…` : value;
72
+ }
73
+
74
+ function formatPreviewKey(key: string): string {
75
+ return key
76
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
77
+ .replace(/[_-]+/g, ' ')
78
+ .trim()
79
+ .toLowerCase();
80
+ }
81
+
82
+ function scalarSummaryValue(
83
+ value: unknown,
84
+ key: string,
85
+ maxChars: number,
86
+ ): string | number | boolean | null | undefined {
87
+ if (value === null) return null;
88
+ switch (typeof value) {
89
+ case 'string': {
90
+ // Key-aware + value-pattern redaction before truncation, so secrets never
91
+ // land in the persisted summary even when the value is short.
92
+ // Customer-aware redaction: key-aware + explicit credential patterns,
93
+ // WITHOUT the high-entropy heuristic — a long opaque customer id
94
+ // (campaign ids, CRM record ids) must survive the summary.
95
+ const safe = redactSecretsInCustomerValue(value, key);
96
+ return truncateString(safe, maxChars);
97
+ }
98
+ case 'number':
99
+ case 'boolean':
100
+ return value;
101
+ case 'bigint':
102
+ return truncateString(value.toString(), maxChars);
103
+ default:
104
+ return undefined;
105
+ }
106
+ }
107
+
108
+ function formatScalarPreview(value: unknown, key: string): string | null {
109
+ const summarized = scalarSummaryValue(value, key, MAX_NESTED_VALUE_CHARS);
110
+ if (summarized === undefined || summarized === null || summarized === '') {
111
+ return null;
112
+ }
113
+ return String(summarized);
114
+ }
115
+
116
+ function isRecord(value: unknown): value is Record<string, unknown> {
117
+ return Boolean(value && typeof value === 'object' && !Array.isArray(value));
118
+ }
119
+
120
+ function summarizeArrayValue(value: unknown[], key: string): string {
121
+ if (value.length === 0) return '[0 items]';
122
+
123
+ const parts: string[] = [];
124
+ for (const item of value.slice(0, MAX_ARRAY_PARTS)) {
125
+ const preview = isRecord(item)
126
+ ? summarizeObjectValue(item)
127
+ : Array.isArray(item)
128
+ ? `[${item.length} item${item.length === 1 ? '' : 's'}]`
129
+ : formatScalarPreview(item, key);
130
+ if (preview) parts.push(preview);
131
+ }
132
+
133
+ const suffixCount = value.length - parts.length;
134
+ const suffix =
135
+ suffixCount > 0
136
+ ? ` +${suffixCount} item${suffixCount === 1 ? '' : 's'}`
137
+ : '';
138
+ return parts.length > 0
139
+ ? truncateString(`${parts.join(', ')}${suffix}`, MAX_STRING_CHARS)
140
+ : `[${value.length} item${value.length === 1 ? '' : 's'}]`;
141
+ }
142
+
143
+ function summarizeObjectValue(record: Record<string, unknown>): string {
144
+ const entries = Object.entries(record);
145
+ const fieldCount = entries.length;
146
+ if (fieldCount === 0) return '{}';
147
+
148
+ const parts: string[] = [];
149
+ const usedRootKeys = new Set<string>();
150
+
151
+ const addPart = (path: string, rootKey: string, value: unknown): boolean => {
152
+ if (parts.length >= MAX_OBJECT_PARTS) return false;
153
+ const preview = formatScalarPreview(value, path);
154
+ if (!preview) return false;
155
+ parts.push(`${formatPreviewKey(path)}: ${preview}`);
156
+ usedRootKeys.add(rootKey);
157
+ return true;
158
+ };
159
+
160
+ const addPreferredFromRecord = (
161
+ source: Record<string, unknown>,
162
+ rootKey: string,
163
+ prefix = '',
164
+ ) => {
165
+ for (const preferredKey of OBJECT_PREVIEW_KEYS) {
166
+ if (preferredKey in source) {
167
+ addPart(
168
+ prefix ? `${prefix}.${preferredKey}` : preferredKey,
169
+ rootKey || preferredKey,
170
+ source[preferredKey],
171
+ );
172
+ }
173
+ if (parts.length >= MAX_OBJECT_PARTS) return;
174
+ }
175
+ };
176
+
177
+ addPreferredFromRecord(record, '');
178
+
179
+ for (const [rootKey, value] of entries) {
180
+ if (parts.length >= MAX_OBJECT_PARTS) break;
181
+ if (usedRootKeys.has(rootKey) || rootKey.startsWith('_')) continue;
182
+ if (isRecord(value)) {
183
+ addPreferredFromRecord(value, rootKey, rootKey);
184
+ }
185
+ }
186
+
187
+ for (const [rootKey, value] of entries) {
188
+ if (parts.length >= MAX_OBJECT_PARTS) break;
189
+ if (
190
+ usedRootKeys.has(rootKey) ||
191
+ rootKey.startsWith('_') ||
192
+ LOW_SIGNAL_PREVIEW_KEYS.has(rootKey)
193
+ ) {
194
+ continue;
195
+ }
196
+ if (Array.isArray(value)) {
197
+ const preview = summarizeArrayValue(value, rootKey);
198
+ if (preview) {
199
+ parts.push(`${formatPreviewKey(rootKey)}: ${preview}`);
200
+ usedRootKeys.add(rootKey);
201
+ }
202
+ continue;
203
+ }
204
+ addPart(rootKey, rootKey, value);
205
+ }
206
+
207
+ if (parts.length === 0) {
208
+ return `{${fieldCount} field${fieldCount === 1 ? '' : 's'}}`;
209
+ }
210
+
211
+ const remaining = Math.max(0, fieldCount - usedRootKeys.size);
212
+ const suffix =
213
+ remaining > 0 ? ` +${remaining} field${remaining === 1 ? '' : 's'}` : '';
214
+ return truncateString(`${parts.join(' · ')}${suffix}`, MAX_STRING_CHARS);
215
+ }
216
+
217
+ function summarizeValue(value: unknown, key: string): unknown {
218
+ const scalar = scalarSummaryValue(value, key, MAX_STRING_CHARS);
219
+ if (scalar !== undefined) {
220
+ return scalar;
221
+ }
222
+ if (Array.isArray(value)) {
223
+ return summarizeArrayValue(value, key);
224
+ }
225
+ if (isRecord(value)) {
226
+ return summarizeObjectValue(value);
227
+ }
228
+ // functions, symbols, undefined: not displayable
229
+ return undefined;
230
+ }
231
+
232
+ export function buildPlayRunInputSummary(
233
+ input: unknown,
234
+ ): Record<string, unknown> | undefined {
235
+ if (!input || typeof input !== 'object' || Array.isArray(input)) {
236
+ return undefined;
237
+ }
238
+ const entries = Object.entries(input as Record<string, unknown>);
239
+ if (entries.length === 0) return undefined;
240
+
241
+ const summary: Record<string, unknown> = {};
242
+ let count = 0;
243
+ for (const [key, value] of entries) {
244
+ if (count >= MAX_KEYS) {
245
+ const remaining = entries.length - count;
246
+ summary['…'] = `+${remaining} more field${remaining === 1 ? '' : 's'}`;
247
+ break;
248
+ }
249
+ const summarized = summarizeValue(value, key);
250
+ if (summarized === undefined) continue;
251
+ summary[key] = summarized;
252
+ count += 1;
253
+ if (JSON.stringify(summary).length > MAX_TOTAL_BYTES) {
254
+ delete summary[key];
255
+ summary['…'] = 'truncated';
256
+ break;
257
+ }
258
+ }
259
+ return Object.keys(summary).length > 0 ? summary : undefined;
260
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Compact, truncated output preview attached to terminal runs by the runs-list
3
+ * endpoints. Lets the runs drawer render an output table without a blocking
4
+ * per-run detail fetch. Not the full sheet — capped rows/columns.
5
+ */
6
+ export type PlayRunSummaryResultPreview = {
7
+ rows: Record<string, unknown>[];
8
+ stats: Record<string, unknown>;
9
+ tableNamespace: string;
10
+ };
11
+
12
+ export type PlayRunSummaryRecord = {
13
+ _id: string;
14
+ playId: string;
15
+ workflowId: string;
16
+ /** Backend runtime attempt identifier, when the scheduler exposes one. */
17
+ runId?: string;
18
+ playName?: string | null;
19
+ parentRunId?: string | null;
20
+ rootRunId?: string | null;
21
+ status: string;
22
+ createdAt: number;
23
+ startedAt?: number;
24
+ finishedAt?: number;
25
+ updatedAt: number;
26
+ artifactTableNamespace?: string;
27
+ artifactTableNamespaces?: string[];
28
+ error?: string;
29
+ outputPreview?: string;
30
+ billingTotalCredits?: number;
31
+ billingMaxCreditsPerRun?: number | null;
32
+ result?: PlayRunSummaryResultPreview;
33
+ /**
34
+ * Size-bounded projection of the play function's normalized return value.
35
+ * It drives run-list columns without fetching the full terminal result for
36
+ * every polling response. Use the explicit full-run endpoint for the exact
37
+ * return value.
38
+ */
39
+ output?: Record<string, unknown>;
40
+ /** The compact `output` projection omitted values or fields. */
41
+ outputPreviewTruncated?: true;
42
+ /**
43
+ * Display-only, size-bounded projection of the run's launch input (see
44
+ * packages/plays/run-input-summary.ts). Top-level keys with scalar values;
45
+ * large/nested values elided to placeholders. Undefined when the run had no
46
+ * input. NOT the full input payload.
47
+ */
48
+ inputSummary?: Record<string, unknown>;
49
+ };
@@ -0,0 +1,19 @@
1
+ export const PLAY_SECRET_UNAVAILABLE = 'PLAY_SECRET_UNAVAILABLE' as const;
2
+
3
+ export class PlaySecretUnavailableError extends Error {
4
+ readonly code = PLAY_SECRET_UNAVAILABLE;
5
+
6
+ constructor(readonly secretName: string) {
7
+ super(`Secret ${secretName} is not active or does not exist.`);
8
+ this.name = 'PlaySecretUnavailableError';
9
+ }
10
+ }
11
+
12
+ export function playSecretUnavailableErrorFrom(
13
+ error: unknown,
14
+ ): PlaySecretUnavailableError | null {
15
+ const message = error instanceof Error ? error.message : String(error);
16
+ const match =
17
+ /Secret ([A-Z][A-Z0-9_]*) is not active or does not exist\./.exec(message);
18
+ return match ? new PlaySecretUnavailableError(match[1]) : null;
19
+ }
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Package-owned helpers for share-page copy: the generation input shape, a deterministic
3
+ * (no-LLM) fallback builder, override merging, and validation of model output.
4
+ *
5
+ * Nothing here performs network I/O — see generate-card.ts for the LLM call.
6
+ */
7
+ import type {
8
+ PlayShareCopyOverrides,
9
+ PlayShareGeneratedCopy,
10
+ PlayShareSchemaShape,
11
+ PlayShareStaticPipelineSummary,
12
+ } from './types';
13
+
14
+ /** A single safe, bounded sample of a successful run. */
15
+ export type ShareRunSummarySample = {
16
+ rowCount: number | null;
17
+ outputLeadCount: number | null;
18
+ columns: string[];
19
+ };
20
+
21
+ /**
22
+ * Everything the copy generators are allowed to see about a revision. This is
23
+ * assembled server-side and contains no provider spend, secrets, or source.
24
+ */
25
+ export type ShareCardGenerationInput = {
26
+ playName: string;
27
+ displayName?: string | null;
28
+ ownerDisplayName: string | null;
29
+ version: number;
30
+ graphHash: string | null;
31
+ sourceHash: string;
32
+ summary: PlayShareStaticPipelineSummary;
33
+ inputSchema: PlayShareSchemaShape;
34
+ outputSchema: PlayShareSchemaShape;
35
+ providerNames: string[];
36
+ existingDescription: string | null;
37
+ sampleRunSummaries: ShareRunSummarySample[];
38
+ };
39
+
40
+ const COPY_FIELDS: Array<keyof PlayShareGeneratedCopy> = [
41
+ 'title',
42
+ 'shortDescription',
43
+ 'jtbd',
44
+ 'whenToUse',
45
+ 'inputs',
46
+ 'outputs',
47
+ 'agentPrompt',
48
+ 'llmSummary',
49
+ 'seoTitle',
50
+ 'seoDescription',
51
+ ];
52
+
53
+ function humanizePlayName(name: string): string {
54
+ const cleaned = name
55
+ .split('/')
56
+ .pop()!
57
+ .replace(/[._-]+/g, ' ')
58
+ .trim();
59
+ if (!cleaned) {
60
+ return 'Play';
61
+ }
62
+ return cleaned
63
+ .split(/\s+/)
64
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
65
+ .join(' ');
66
+ }
67
+
68
+ function firstSentence(text: string): string {
69
+ const trimmed = text.trim();
70
+ const match = trimmed.match(/^.*?[.!?](\s|$)/);
71
+ return (match ? match[0] : trimmed).trim();
72
+ }
73
+
74
+ function joinList(items: string[], fallback: string): string {
75
+ const cleaned = items.filter(Boolean);
76
+ if (cleaned.length === 0) {
77
+ return fallback;
78
+ }
79
+ if (cleaned.length === 1) {
80
+ return cleaned[0];
81
+ }
82
+ return `${cleaned.slice(0, -1).join(', ')} and ${cleaned[cleaned.length - 1]}`;
83
+ }
84
+
85
+ /**
86
+ * Build a conservative card from structured facts, no model required. Used as a
87
+ * deterministic fallback and as the seed for the LLM prompt. Uncertain parts are
88
+ * intentionally generic rather than invented.
89
+ */
90
+ export function buildDeterministicShareCard(
91
+ input: ShareCardGenerationInput,
92
+ ): PlayShareGeneratedCopy {
93
+ const human = input.displayName?.trim() || humanizePlayName(input.playName);
94
+ const providers = input.providerNames.filter(Boolean);
95
+ const providerPhrase =
96
+ providers.length > 0
97
+ ? ` using ${joinList(providers, 'GTM providers')}`
98
+ : '';
99
+ const inputFields = input.inputSchema?.fields ?? [];
100
+ const outputFields = input.outputSchema?.fields ?? [];
101
+
102
+ const existing = input.existingDescription?.trim() || '';
103
+ const shortDescription = existing
104
+ ? firstSentence(existing)
105
+ : `${human} is a Deepline play that automates a ${input.summary.stepCount}-step GTM pipeline${providerPhrase}.`;
106
+
107
+ const jtbd = existing
108
+ ? existing
109
+ : `Run a repeatable, multi-step GTM workflow${providerPhrase} without wiring providers together by hand.`;
110
+
111
+ const whenToUse =
112
+ providers.length > 0
113
+ ? [
114
+ `You need data from ${joinList(providers, 'multiple providers')} in one pass.`,
115
+ 'You want a repeatable pipeline instead of one-off lookups.',
116
+ 'You want an agent or teammate to run the same workflow on demand.',
117
+ ]
118
+ : [
119
+ 'You need a repeatable, multi-step GTM workflow.',
120
+ 'You want an agent or teammate to run it on demand.',
121
+ 'You want consistent output columns every run.',
122
+ ];
123
+
124
+ const inputs =
125
+ inputFields.length > 0
126
+ ? inputFields
127
+ : input.summary.hasMap
128
+ ? ['A list of rows to process (CSV or table).']
129
+ : ['Run parameters for the workflow.'];
130
+
131
+ const outputs =
132
+ outputFields.length > 0
133
+ ? outputFields
134
+ : ['An enriched output table with one row per processed record.'];
135
+
136
+ const agentPrompt = `Use the Deepline "${input.playName}" play to ${jtbd
137
+ .charAt(0)
138
+ .toLowerCase()}${jtbd.slice(1)}`;
139
+
140
+ const llmSummary = [
141
+ `${human} (Deepline play "${input.playName}", version ${input.version}).`,
142
+ shortDescription,
143
+ `Pipeline: ${input.summary.stepCount} steps, ${input.summary.providerCount} provider${input.summary.providerCount === 1 ? '' : 's'}${input.summary.hasMap ? ', processes input rows as a dataset' : ''}.`,
144
+ inputFields.length > 0 ? `Inputs: ${inputFields.join(', ')}.` : null,
145
+ outputFields.length > 0 ? `Outputs: ${outputFields.join(', ')}.` : null,
146
+ ]
147
+ .filter(Boolean)
148
+ .join(' ');
149
+
150
+ const primaryInput = inputs[0]?.replace(/\.$/, '') ?? 'GTM inputs';
151
+ const primaryOutput = outputs[0]?.replace(/\.$/, '') ?? 'workflow output';
152
+ const providerCount = input.summary.providerCount;
153
+ const seoTitle = `${human}: Inputs, Outputs & CLI Setup`;
154
+ const seoDescription = [
155
+ `Run or fork this Deepline play from ${primaryInput} to ${primaryOutput}.`,
156
+ `See steps, ${providerCount} provider${providerCount === 1 ? '' : 's'}, setup, and CLI commands.`,
157
+ ].join(' ');
158
+
159
+ return {
160
+ title: human,
161
+ shortDescription,
162
+ jtbd,
163
+ whenToUse,
164
+ inputs,
165
+ outputs,
166
+ agentPrompt,
167
+ llmSummary,
168
+ seoTitle,
169
+ seoDescription,
170
+ };
171
+ }
172
+
173
+ function nonEmptyString(value: unknown): value is string {
174
+ return typeof value === 'string' && value.trim().length > 0;
175
+ }
176
+
177
+ function nonEmptyStringArray(value: unknown): value is string[] {
178
+ return (
179
+ Array.isArray(value) &&
180
+ value.length > 0 &&
181
+ value.every((item) => nonEmptyString(item))
182
+ );
183
+ }
184
+
185
+ /**
186
+ * Validate an arbitrary object as `PlayShareGeneratedCopy`. Returns the typed
187
+ * copy or throws (loud failure) so model output can never silently degrade.
188
+ */
189
+ export function parseGeneratedCopy(value: unknown): PlayShareGeneratedCopy {
190
+ if (!value || typeof value !== 'object') {
191
+ throw new Error('Generated copy must be an object.');
192
+ }
193
+ const record = value as Record<string, unknown>;
194
+ const stringFields: Array<keyof PlayShareGeneratedCopy> = [
195
+ 'title',
196
+ 'shortDescription',
197
+ 'jtbd',
198
+ 'agentPrompt',
199
+ 'llmSummary',
200
+ 'seoTitle',
201
+ 'seoDescription',
202
+ ];
203
+ for (const field of stringFields) {
204
+ if (!nonEmptyString(record[field])) {
205
+ throw new Error(
206
+ `Generated copy field "${field}" must be a non-empty string.`,
207
+ );
208
+ }
209
+ }
210
+ const arrayFields: Array<keyof PlayShareGeneratedCopy> = [
211
+ 'whenToUse',
212
+ 'inputs',
213
+ 'outputs',
214
+ ];
215
+ for (const field of arrayFields) {
216
+ if (!nonEmptyStringArray(record[field])) {
217
+ throw new Error(
218
+ `Generated copy field "${field}" must be a non-empty array of strings.`,
219
+ );
220
+ }
221
+ }
222
+
223
+ return {
224
+ title: (record.title as string).trim(),
225
+ shortDescription: (record.shortDescription as string).trim(),
226
+ jtbd: (record.jtbd as string).trim(),
227
+ whenToUse: (record.whenToUse as string[]).map((item) => item.trim()),
228
+ inputs: (record.inputs as string[]).map((item) => item.trim()),
229
+ outputs: (record.outputs as string[]).map((item) => item.trim()),
230
+ agentPrompt: (record.agentPrompt as string).trim(),
231
+ llmSummary: (record.llmSummary as string).trim(),
232
+ seoTitle: (record.seoTitle as string).trim(),
233
+ seoDescription: (record.seoDescription as string).trim(),
234
+ };
235
+ }
236
+
237
+ function isMeaningfulOverride(value: unknown): boolean {
238
+ if (nonEmptyString(value)) {
239
+ return true;
240
+ }
241
+ if (Array.isArray(value)) {
242
+ return value.some((item) => nonEmptyString(item));
243
+ }
244
+ return false;
245
+ }
246
+
247
+ /**
248
+ * Merge owner overrides over generated copy at read time. Only non-empty
249
+ * overrides win; everything else falls through to the generated value.
250
+ */
251
+ export function mergeShareCopy(
252
+ generated: PlayShareGeneratedCopy,
253
+ overrides: PlayShareCopyOverrides | null | undefined,
254
+ ): PlayShareGeneratedCopy {
255
+ if (!overrides) {
256
+ return generated;
257
+ }
258
+ const merged: PlayShareGeneratedCopy = { ...generated };
259
+ for (const field of COPY_FIELDS) {
260
+ const override = overrides[field];
261
+ if (isMeaningfulOverride(override)) {
262
+ // Field types are homogeneous per key; cast is safe after the check.
263
+ (merged[field] as unknown) = Array.isArray(override)
264
+ ? override
265
+ .filter((item) => nonEmptyString(item))
266
+ .map((item) => item.trim())
267
+ : (override as string).trim();
268
+ }
269
+ }
270
+ return merged;
271
+ }