deepline 0.3.89 → 0.3.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/contracts/install-commands.json +29 -0
  2. package/dist/bundling-sources/sdk/src/client.ts +120 -37
  3. package/dist/bundling-sources/sdk/src/index.ts +4 -0
  4. package/dist/bundling-sources/sdk/src/pagination.ts +25 -0
  5. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
  6. package/dist/bundling-sources/sdk/src/release.ts +16 -9
  7. package/dist/bundling-sources/sdk/src/types.ts +23 -0
  8. package/dist/bundling-sources/shared_libs/monitors/analytics-public.ts +10 -0
  9. package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +3 -0
  10. package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +4 -4
  11. package/dist/bundling-sources/shared_libs/monitors/inventory-reconciliation.ts +59 -0
  12. package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +7 -9
  13. package/dist/bundling-sources/shared_libs/monitors/package.json +7 -0
  14. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +44 -2
  15. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +2 -2
  16. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +2 -2
  17. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +1 -1
  18. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +245 -0
  19. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-message.ts +38 -0
  20. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-ack-probe.ts +94 -0
  21. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-delivery.ts +60 -0
  22. package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue.ts +60 -0
  23. package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +1 -1
  24. package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +2 -2
  25. package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +1 -1
  26. package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +1 -1
  27. package/dist/bundling-sources/shared_libs/observability/build-context.ts +13 -0
  28. package/dist/bundling-sources/shared_libs/observability/log-metadata.ts +160 -0
  29. package/dist/bundling-sources/shared_libs/observability/request-context.ts +68 -0
  30. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +654 -0
  31. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +35 -0
  32. package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +5 -0
  33. package/dist/bundling-sources/shared_libs/play-data-plane/neon-constants.ts +9 -0
  34. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +272 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +45 -0
  36. package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +66 -1
  37. package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +0 -1
  38. package/dist/bundling-sources/shared_libs/play-runtime/bounceban-batching.ts +137 -0
  39. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +779 -140
  40. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +46 -0
  41. package/dist/bundling-sources/shared_libs/play-runtime/daytona-payload-contract.ts +68 -0
  42. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +103 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +725 -0
  44. package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +29 -0
  45. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +23 -0
  46. package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-invocation-fence.ts +442 -0
  47. package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +3 -3
  48. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +18 -0
  49. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +9 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +1 -1
  51. package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +1 -1
  52. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/contracts.ts +66 -0
  53. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/job.ts +145 -0
  54. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/ports.ts +21 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/postgres-store.ts +170 -0
  56. package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +1322 -0
  57. package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +2 -2
  58. package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +1 -1
  59. package/dist/bundling-sources/shared_libs/play-runtime/launch-source-policy.ts +112 -0
  60. package/dist/bundling-sources/shared_libs/play-runtime/map-execution-frame.ts +8 -0
  61. package/dist/bundling-sources/shared_libs/play-runtime/perf-trace.ts +127 -0
  62. package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +5 -0
  63. package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +24 -1
  64. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/contracts.ts +56 -0
  65. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/index.ts +13 -0
  66. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/job.ts +41 -0
  67. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/ports.ts +17 -0
  68. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts +54 -0
  69. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/contracts.ts +114 -0
  70. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/engine-suspension.ts +108 -0
  71. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/index.ts +36 -0
  72. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/job.ts +97 -0
  73. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/ports.ts +104 -0
  74. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/postgres-fence-adapter.ts +263 -0
  75. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/worker-terminal-projection.ts +64 -0
  76. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/contracts.ts +29 -0
  77. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts +56 -0
  78. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/index.ts +15 -0
  79. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/job.ts +65 -0
  80. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/ports.ts +17 -0
  81. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +42 -0
  82. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/index.ts +17 -0
  83. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +142 -0
  84. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/ports.ts +42 -0
  85. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/postgres-adapter.ts +102 -0
  86. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/contracts.ts +60 -0
  87. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/index.ts +16 -0
  88. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/job.ts +78 -0
  89. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/ports.ts +54 -0
  90. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/postgres-adapter.ts +71 -0
  91. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +4 -0
  92. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
  93. package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +5 -8
  94. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +3 -5
  95. package/dist/bundling-sources/shared_libs/play-runtime/run-identity.ts +168 -0
  96. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +72 -9
  97. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +6 -12
  98. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +19 -0
  99. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/bundle.ts +0 -1
  100. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +14 -44
  101. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +57 -205
  102. package/dist/bundling-sources/shared_libs/play-runtime/runtime-authority.ts +201 -0
  103. package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +6 -0
  104. package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +67 -0
  105. package/dist/bundling-sources/shared_libs/play-runtime/runtime-release-environment.ts +2 -0
  106. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sandbox-contract.ts +68 -0
  107. package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +14 -2
  108. package/dist/bundling-sources/shared_libs/play-runtime/runtime-telemetry.ts +108 -0
  109. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +4 -0
  110. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +3 -0
  111. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +7 -0
  112. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-deadline-reconciliation.ts +88 -0
  113. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-deploy-task.ts +124 -0
  114. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-run-task.ts +68 -0
  115. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +193 -0
  116. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-lifecycle.ts +269 -0
  117. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-suffix.ts +73 -0
  118. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +6642 -0
  119. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +897 -0
  120. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-metrics.ts +120 -0
  121. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +76 -0
  122. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +476 -0
  123. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-heavy-request-admission.ts +47 -0
  124. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-progress-registry.ts +147 -0
  125. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/index.ts +27 -0
  126. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/lazy.ts +50 -0
  127. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/play-run-recovery.ts +98 -0
  128. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-budget-state.ts +260 -0
  129. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +1416 -0
  130. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +1255 -0
  131. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +942 -0
  132. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +14636 -0
  133. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +888 -0
  134. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +355 -0
  135. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-terminal-transition.ts +46 -0
  136. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runner-push.ts +60 -0
  137. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-api-origin.ts +33 -0
  138. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-gateway-health.ts +64 -0
  139. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +835 -0
  140. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +1218 -0
  141. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-operation.ts +207 -0
  142. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-scheduler-schema.ts +10 -0
  143. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-capacity.ts +123 -0
  144. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-launch-read-observability.ts +78 -0
  145. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/submit-admission.ts +169 -0
  146. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/terminal-contract.ts +20 -0
  147. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-queue-metrics.ts +34 -0
  148. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-resource-metrics.ts +249 -0
  149. package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +7 -0
  150. package/dist/bundling-sources/shared_libs/play-runtime/step-progress.ts +296 -0
  151. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/native-batch.ts +3 -3
  152. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/runtime-step-receipts-adapter.ts +20 -1
  153. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +60 -15
  154. package/dist/bundling-sources/shared_libs/play-runtime/tool-execution-outcome.ts +20 -0
  155. package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +12 -0
  156. package/dist/bundling-sources/shared_libs/play-runtime/vercel-protection.ts +14 -1
  157. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +165 -0
  158. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +15 -23
  159. package/dist/bundling-sources/shared_libs/play-runtime/workflow-executor-auth.ts +169 -0
  160. package/dist/bundling-sources/shared_libs/play-runtime/zerobounce-batching.ts +122 -0
  161. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +2 -0
  162. package/dist/bundling-sources/shared_libs/plays/contracts.ts +2 -0
  163. package/dist/bundling-sources/shared_libs/plays/deployment-status.ts +1 -1
  164. package/dist/bundling-sources/shared_libs/plays/docflow.ts +1 -1
  165. package/dist/bundling-sources/shared_libs/plays/play-grep-search.ts +39 -0
  166. package/dist/bundling-sources/shared_libs/plays/share/copy.ts +271 -0
  167. package/dist/bundling-sources/shared_libs/plays/share/metrics.ts +140 -0
  168. package/dist/bundling-sources/shared_libs/plays/share/public-read-model.ts +86 -0
  169. package/dist/bundling-sources/shared_libs/plays/share/seo-quality.ts +181 -0
  170. package/dist/bundling-sources/shared_libs/plays/share/static-pipeline-summary.ts +658 -0
  171. package/dist/bundling-sources/shared_libs/plays/share/types.ts +197 -0
  172. package/dist/bundling-sources/shared_libs/plays/slack-hitl-timeout-error.ts +37 -0
  173. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +6 -1
  174. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
  175. package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +7 -1
  176. package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +3 -2
  177. package/dist/bundling-sources/shared_libs/product-notifications/overflow.ts +18 -0
  178. package/dist/bundling-sources/shared_libs/product-notifications/rolling-limit.ts +24 -0
  179. package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +624 -0
  180. package/dist/bundling-sources/shared_libs/product-notifications/slack-payload.ts +140 -0
  181. package/dist/bundling-sources/shared_libs/product-notifications/slack-transport.ts +75 -0
  182. package/dist/bundling-sources/shared_libs/runtime-env.ts +6 -0
  183. package/dist/bundling-sources/shared_libs/security/email-blacklist.ts +42 -0
  184. package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +10 -3
  185. package/dist/bundling-sources/shared_libs/security/slack-sanitize.ts +133 -0
  186. package/dist/cli/getting-started.d.mts +52 -0
  187. package/dist/cli/getting-started.d.ts +52 -0
  188. package/dist/cli/getting-started.js +65 -0
  189. package/dist/cli/getting-started.mjs +36 -0
  190. package/dist/cli/index.d.mts +9 -0
  191. package/dist/cli/index.d.ts +9 -0
  192. package/dist/cli/index.js +545 -264
  193. package/dist/cli/index.mjs +543 -271
  194. package/dist/{compiler-manifest-DsLbQaew.d.mts → compiler-manifest-BaJfE-5H.d.mts} +5 -3
  195. package/dist/{compiler-manifest-DsLbQaew.d.ts → compiler-manifest-BaJfE-5H.d.ts} +5 -3
  196. package/dist/index.d.mts +81 -148
  197. package/dist/index.d.ts +81 -148
  198. package/dist/index.js +83 -26
  199. package/dist/index.mjs +83 -26
  200. package/dist/install-integrity.json +130 -2
  201. package/dist/monitor-fleet-contract.d.mts +138 -0
  202. package/dist/monitor-fleet-contract.d.ts +138 -0
  203. package/dist/monitor-fleet-contract.js +404 -0
  204. package/dist/monitor-fleet-contract.mjs +367 -0
  205. package/dist/plays/bundle-play-file.d.mts +2 -2
  206. package/dist/plays/bundle-play-file.d.ts +2 -2
  207. package/dist/release.d.mts +255 -0
  208. package/dist/release.d.ts +255 -0
  209. package/dist/release.js +215 -0
  210. package/dist/release.mjs +188 -0
  211. package/package.json +21 -4
@@ -0,0 +1,122 @@
1
+ import {
2
+ defineBatchStrategyMap,
3
+ type BatchOperationStrategy,
4
+ } from './batching-types';
5
+
6
+ type Single = { email?: string; ip_address?: string };
7
+ type Bulk = {
8
+ email_batch: Array<{ email_address: string; ip_address?: string }>;
9
+ };
10
+ type Verdict = Record<string, unknown> & { address: string; status: string };
11
+ type Results = { email_batch?: unknown[]; errors?: unknown[]; data?: Results };
12
+
13
+ function emailKey(email: string) {
14
+ return email.trim().toLowerCase();
15
+ }
16
+ function bucket(payload: Single) {
17
+ // The response identifies emails, but does not echo the supplied IP.
18
+ return JSON.stringify([
19
+ 'zerobounce_batch_validate',
20
+ payload.ip_address ?? null,
21
+ ]);
22
+ }
23
+
24
+ export const zerobounceValidateBatchStrategy: BatchOperationStrategy<
25
+ Single,
26
+ Bulk,
27
+ Results,
28
+ { data: Verdict }
29
+ > = {
30
+ sourceOperation: 'zerobounce_validate',
31
+ batchOperation: 'zerobounce_batch_validate',
32
+ kind: 'identifier_batch',
33
+ maxBatchSize: 100,
34
+ bucketKeyPayloadFields: ['ip_address'],
35
+ canBatchWith: (left, right) => bucket(left) === bucket(right),
36
+ toBucketKey: bucket,
37
+ toItemKey: (payload) =>
38
+ JSON.stringify([emailKey(payload.email ?? ''), payload.ip_address ?? null]),
39
+ compile(payloads) {
40
+ const first = payloads[0];
41
+ if (
42
+ !first ||
43
+ payloads.length > 100 ||
44
+ payloads.some((p) => !p.email?.trim() || bucket(p) !== bucket(first))
45
+ ) {
46
+ throw new Error(
47
+ 'ZeroBounce batch requires 1–100 emails with matching IP options.',
48
+ );
49
+ }
50
+ return {
51
+ // Receipt deduplication may leave one owned email. Keep the bulk operation.
52
+ batchOperation: 'zerobounce_batch_validate',
53
+ batchPayload: {
54
+ email_batch: [...new Set(payloads.map((p) => emailKey(p.email!)))].map(
55
+ (email_address) => ({
56
+ email_address,
57
+ ...(first.ip_address ? { ip_address: first.ip_address } : {}),
58
+ }),
59
+ ),
60
+ },
61
+ items: payloads.map((payload) => ({
62
+ itemKey: zerobounceValidateBatchStrategy.toItemKey(payload),
63
+ payload,
64
+ })),
65
+ };
66
+ },
67
+ splitResult(fullResult, compiled) {
68
+ const result = fullResult.data ?? fullResult;
69
+ if (
70
+ !Array.isArray(result.email_batch) ||
71
+ (result.errors !== undefined &&
72
+ (!Array.isArray(result.errors) || result.errors.length > 0))
73
+ ) {
74
+ throw new Error(
75
+ 'ZeroBounce bulk verification returned errors or no result list.',
76
+ );
77
+ }
78
+ const expected = new Set(
79
+ compiled.batchPayload.email_batch.map((p) => emailKey(p.email_address)),
80
+ );
81
+ const byEmail = new Map<string, Verdict>();
82
+ for (const value of result.email_batch) {
83
+ const row = value as Verdict | null;
84
+ if (
85
+ !row ||
86
+ typeof row.address !== 'string' ||
87
+ ![
88
+ 'valid',
89
+ 'invalid',
90
+ 'catch-all',
91
+ 'unknown',
92
+ 'spamtrap',
93
+ 'abuse',
94
+ 'do_not_mail',
95
+ ].includes(row.status)
96
+ ) {
97
+ throw new Error(
98
+ 'ZeroBounce bulk verification returned a malformed verdict.',
99
+ );
100
+ }
101
+ const key = emailKey(row.address);
102
+ if (!expected.has(key) || byEmail.has(key)) {
103
+ throw new Error(
104
+ 'ZeroBounce bulk verification returned unexpected or duplicate verdicts.',
105
+ );
106
+ }
107
+ byEmail.set(key, row);
108
+ }
109
+ return compiled.items.map((item) => {
110
+ const row = byEmail.get(emailKey(item.payload.email!));
111
+ if (!row)
112
+ throw new Error(
113
+ 'ZeroBounce bulk verification omitted a requested email result.',
114
+ );
115
+ return { itemKey: item.itemKey, result: { data: row }, rawResult: row };
116
+ });
117
+ },
118
+ };
119
+
120
+ export const zerobounceBatchStrategies = defineBatchStrategyMap({
121
+ zerobounce_validate: zerobounceValidateBatchStrategy,
122
+ });
@@ -36,6 +36,8 @@ export type PlayArtifactCompatibility = {
36
36
  toolResponseContract?: ToolResponseContract;
37
37
  /** Missing preserves the receipt namespace of artifacts created before this revision existed. */
38
38
  toolResponseReceiptRevision?: string;
39
+ /** Missing preserves Slack HITL's historical parked timeout behavior. */
40
+ slackHitlTimeoutOutcome?: 'error';
39
41
  };
40
42
 
41
43
  /** The only executable Play artifact contract. */
@@ -47,6 +47,8 @@ export type PlayContractCompatibilitySnapshot = {
47
47
  toolResponseContract?: ToolResponseContract;
48
48
  /** Legacy response metadata; it does not change completed-result caching. */
49
49
  toolResponseReceiptRevision?: string;
50
+ /** Missing preserves Slack HITL's historical parked timeout behavior. */
51
+ slackHitlTimeoutOutcome?: 'error';
50
52
  };
51
53
 
52
54
  export type NormalizedPlayContractCompatibilitySnapshot =
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The play deployment status machine, shared by the Convex control plane
3
- * (convex/playDeployments.ts), worker auth (src/lib/auth/play-deploy-auth.ts),
3
+ * (convex/playDeployments.ts), worker auth (apps/deepline-api/src/lib/auth/play-deploy-auth.ts),
4
4
  * and the deploy-worker API surface. One spelling of the union, the terminal
5
5
  * set, and the allowed transitions.
6
6
  */
@@ -78,7 +78,7 @@ export type PlayDocflowEdge = {
78
78
  *
79
79
  * ABSENT — never `null` — when unrecorded, and that is load-bearing rather
80
80
  * than stylistic. `docflow` is whole-object serialized into
81
- * `playStaticPipelineContractHash` (`src/lib/plays/artifact-storage.ts`),
81
+ * `playStaticPipelineContractHash` (`apps/deepline-api/src/lib/plays/artifact-storage.ts`),
82
82
  * which is part of the immutable artifact storage key, and the canonicalizer
83
83
  * there drops `undefined` but HASHES `null`. Emitting `arm: null` on an
84
84
  * unannotated edge would change the contract hash of every diagrammed play
@@ -0,0 +1,39 @@
1
+ // Convex limits its final prefix-search term to 32 UTF-8 bytes, so the public
2
+ // query must stay below that boundary. The corpus was already backfilled in
3
+ // Convex's lowercase representation, so do not rewrite terms here: changing
4
+ // its token boundaries would make historical rows require another data
5
+ // migration. Reject an unsupported query at the API boundary rather than
6
+ // silently returning an incomplete result or adding a second reader.
7
+ export const CONVEX_PLAY_GREP_SEARCH_TERM_MAX_BYTES = 31;
8
+ export const CONVEX_PLAY_GREP_SEARCH_MAX_TERMS = 16;
9
+
10
+ const CONVEX_PLAY_GREP_SEARCH_TERM_PATTERN = /[\p{L}\p{N}]+/gu;
11
+
12
+ /** Return searchable raw terms for the public response filter. */
13
+ export function extractPlayGrepSearchTerms(value: string): string[] {
14
+ return value.match(CONVEX_PLAY_GREP_SEARCH_TERM_PATTERN) ?? [];
15
+ }
16
+
17
+ /**
18
+ * Match the immutable representation of the completed grep-corpus backfill.
19
+ */
20
+ export function normalizePlayGrepSearchQuery(value: string): string {
21
+ return value.toLowerCase();
22
+ }
23
+
24
+ /**
25
+ * Count the terms the API will send to Convex. Request validation keeps an
26
+ * accepted query within Convex's 16-term full-text-search limit.
27
+ */
28
+ export function countNormalizedPlayGrepSearchTerms(value: string): number {
29
+ return extractPlayGrepSearchTerms(normalizePlayGrepSearchQuery(value)).length;
30
+ }
31
+
32
+ /** True when a query term exceeds Convex's usable full-text-search limit. */
33
+ export function hasOverlongPlayGrepSearchTerm(value: string): boolean {
34
+ const encoder = new TextEncoder();
35
+ return extractPlayGrepSearchTerms(normalizePlayGrepSearchQuery(value)).some(
36
+ (term) =>
37
+ encoder.encode(term).byteLength > CONVEX_PLAY_GREP_SEARCH_TERM_MAX_BYTES,
38
+ );
39
+ }
@@ -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
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Package-owned metric aggregation for the public read model.
3
+ *
4
+ * Hard rules (see docs/shareable-play-pages-plan.md + AGENTS.md):
5
+ * - Only Deepline credits are aggregated here. Provider spend (USD) is never
6
+ * passed into this module.
7
+ * - Cost is exposed only when the owner opted in.
8
+ * - Latency is exposed only when the owner opted in AND the revision has no map.
9
+ * - Denominator-specific metrics return null when row/contact counts are
10
+ * missing or ambiguous.
11
+ */
12
+ import type { PlayCostBasis, PublishedPlayPageMetrics } from './types';
13
+
14
+ /**
15
+ * One completed run, reduced to the only facts the public metrics need.
16
+ * `providerCostUsd` deliberately does not exist on this type.
17
+ */
18
+ export type ShareRunMetricSample = {
19
+ /** Total Deepline credits for the run (sum of usageEvents.credits). */
20
+ credits: number;
21
+ /** Number of input rows processed, when reliably known. */
22
+ inputRowCount: number | null;
23
+ /** Number of output leads/contacts produced, when reliably known. */
24
+ outputLeadCount: number | null;
25
+ /** Wall-clock run latency in ms, when valid timing exists. */
26
+ latencyMs: number | null;
27
+ };
28
+
29
+ export type ComputePublicMetricsOptions = {
30
+ showAverageDeeplineCost: boolean;
31
+ showAverageLatency: boolean;
32
+ /** Latency is meaningless for mapped (fan-out) revisions. */
33
+ hasMap: boolean;
34
+ /** Which credit denominator the page may render; see `classifyCostBasis`. */
35
+ costBasis: PlayCostBasis;
36
+ };
37
+
38
+ function mean(values: number[]): number | null {
39
+ if (values.length === 0) {
40
+ return null;
41
+ }
42
+ const total = values.reduce((sum, value) => sum + value, 0);
43
+ return total / values.length;
44
+ }
45
+
46
+ function roundTo(value: number, decimals: number): number {
47
+ const factor = 10 ** decimals;
48
+ return Math.round(value * factor) / factor;
49
+ }
50
+
51
+ /**
52
+ * Aggregate a bounded sample of completed runs into public, credit-only metrics.
53
+ */
54
+ export function computePublicMetrics(
55
+ samples: ShareRunMetricSample[],
56
+ options: ComputePublicMetricsOptions,
57
+ ): PublishedPlayPageMetrics {
58
+ const sampleRunCount = samples.length;
59
+
60
+ const empty: PublishedPlayPageMetrics = {
61
+ averageDeeplineCostCredits: null,
62
+ averageCostPerInputRowCredits: null,
63
+ averageCostPerOutputLeadCredits: null,
64
+ averageLatencyMs: null,
65
+ sampleRunCount,
66
+ costBasis: options.costBasis,
67
+ };
68
+
69
+ if (sampleRunCount === 0) {
70
+ return empty;
71
+ }
72
+
73
+ const metrics: PublishedPlayPageMetrics = { ...empty };
74
+
75
+ if (options.showAverageDeeplineCost) {
76
+ const creditValues = samples
77
+ .map((sample) => sample.credits)
78
+ .filter((value) => Number.isFinite(value) && value >= 0);
79
+ const avgCredits = mean(creditValues);
80
+ metrics.averageDeeplineCostCredits =
81
+ avgCredits === null ? null : roundTo(avgCredits, 2);
82
+
83
+ metrics.averageCostPerInputRowCredits = ratioOverDenominator(
84
+ samples,
85
+ (sample) => sample.inputRowCount,
86
+ );
87
+ metrics.averageCostPerOutputLeadCredits = ratioOverDenominator(
88
+ samples,
89
+ (sample) => sample.outputLeadCount,
90
+ );
91
+ }
92
+
93
+ if (options.showAverageLatency && !options.hasMap) {
94
+ const latencyValues = samples
95
+ .map((sample) => sample.latencyMs)
96
+ .filter(
97
+ (value): value is number =>
98
+ value !== null && Number.isFinite(value) && value >= 0,
99
+ );
100
+ const avgLatency = mean(latencyValues);
101
+ metrics.averageLatencyMs =
102
+ avgLatency === null ? null : Math.round(avgLatency);
103
+ }
104
+
105
+ return metrics;
106
+ }
107
+
108
+ /**
109
+ * total credits / total denominator, considering only runs where the
110
+ * denominator is a reliable positive number. Returns null if no such run.
111
+ */
112
+ function ratioOverDenominator(
113
+ samples: ShareRunMetricSample[],
114
+ pick: (sample: ShareRunMetricSample) => number | null,
115
+ ): number | null {
116
+ let creditSum = 0;
117
+ let denominatorSum = 0;
118
+ let usableRuns = 0;
119
+
120
+ for (const sample of samples) {
121
+ const denominator = pick(sample);
122
+ if (
123
+ denominator === null ||
124
+ !Number.isFinite(denominator) ||
125
+ denominator <= 0 ||
126
+ !Number.isFinite(sample.credits) ||
127
+ sample.credits < 0
128
+ ) {
129
+ continue;
130
+ }
131
+ creditSum += sample.credits;
132
+ denominatorSum += denominator;
133
+ usableRuns += 1;
134
+ }
135
+
136
+ if (usableRuns === 0 || denominatorSum <= 0) {
137
+ return null;
138
+ }
139
+ return roundTo(creditSum / denominatorSum, 4);
140
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Package-owned assembler for the bounded `PublishedPlayPagePackage`.
3
+ *
4
+ * This is the ONLY object the public page and public API expose. It is built
5
+ * from already-gathered, already-sanitized inputs — this function performs no
6
+ * I/O and makes no access decisions.
7
+ */
8
+ import {
9
+ buildInputSchemaShape,
10
+ buildOutputSchemaShape,
11
+ buildPublicSubsteps,
12
+ buildStaticPipelineSummary,
13
+ } from './static-pipeline-summary';
14
+ // This Module is bundled by Convex through its workspace dependency graph.
15
+ import { buildShareCanonicalPath } from '../slug';
16
+ import type {
17
+ PlayShareGeneratedCopy,
18
+ PlayShareSeoIndexing,
19
+ PublishedPlayPageMetrics,
20
+ PublishedPlayPagePackage,
21
+ } from './types';
22
+
23
+ export type BuildPublishedPlayPagePackageInput = {
24
+ shareSlug: string;
25
+ /** Org URL handle; the public page is namespaced `/p/:orgSlug/:playName`. */
26
+ orgSlug: string;
27
+ /** Page-level SEO posture; applied only to the published version. */
28
+ pageSeoIndexing: PlayShareSeoIndexing;
29
+ publishedVersion: number;
30
+ publishedAt: number;
31
+ definitionName: string;
32
+ ownerDisplayName: string | null;
33
+ revision: {
34
+ id: string;
35
+ version: number;
36
+ graphHash: string | null;
37
+ staticPipeline: unknown;
38
+ };
39
+ copy: PlayShareGeneratedCopy;
40
+ metrics: PublishedPlayPageMetrics;
41
+ };
42
+
43
+ export function buildPublishedPlayPagePackage(
44
+ input: BuildPublishedPlayPagePackageInput,
45
+ ): PublishedPlayPagePackage {
46
+ const isPublishedVersion = input.revision.version === input.publishedVersion;
47
+
48
+ // Non-published (historical) versions default to noindex regardless of the
49
+ // page setting, so old copies never compete with the canonical version.
50
+ const seoIndexing: PlayShareSeoIndexing = isPublishedVersion
51
+ ? input.pageSeoIndexing
52
+ : 'noindex';
53
+
54
+ return {
55
+ page: {
56
+ shareSlug: input.shareSlug,
57
+ orgSlug: input.orgSlug,
58
+ visibility: 'unlisted',
59
+ seoIndexing,
60
+ canonicalPath: buildShareCanonicalPath(
61
+ input.orgSlug,
62
+ input.definitionName,
63
+ input.publishedVersion,
64
+ ),
65
+ isPublishedVersion,
66
+ publishedAt: input.publishedAt,
67
+ },
68
+ definition: {
69
+ name: input.definitionName,
70
+ ownerDisplayName: input.ownerDisplayName,
71
+ },
72
+ revision: {
73
+ id: input.revision.id,
74
+ version: input.revision.version,
75
+ graphHash: input.revision.graphHash,
76
+ staticPipelineSummary: buildStaticPipelineSummary(
77
+ input.revision.staticPipeline,
78
+ ),
79
+ substeps: buildPublicSubsteps(input.revision.staticPipeline),
80
+ inputSchema: buildInputSchemaShape(input.revision.staticPipeline),
81
+ outputSchema: buildOutputSchemaShape(input.revision.staticPipeline),
82
+ },
83
+ copy: input.copy,
84
+ publicMetrics: input.metrics,
85
+ };
86
+ }