deepline 0.3.294 → 0.3.296

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 (138) hide show
  1. package/dist/bundling-sources/sdk/src/compat.ts +35 -7
  2. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  3. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +108 -35
  4. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-api-origin.ts +25 -0
  5. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +14 -1
  6. package/dist/cli/auth-JCGIDVDF.mjs +31 -0
  7. package/dist/cli/auth-QDWV3TXX.js +31 -0
  8. package/dist/cli/billing-OQBSIXRG.mjs +1749 -0
  9. package/dist/cli/billing-YBK3J4WP.js +1749 -0
  10. package/dist/cli/chunk-2C3AVPTY.js +5688 -0
  11. package/dist/cli/chunk-2MZ5EQZE.mjs +499 -0
  12. package/dist/cli/chunk-3KC45UVF.js +150 -0
  13. package/dist/cli/chunk-3XX5TEA4.js +15 -0
  14. package/dist/cli/chunk-4MBOJQPL.mjs +0 -0
  15. package/dist/cli/chunk-4Y6CG4GE.js +2240 -0
  16. package/dist/cli/chunk-4ZB3CJRD.js +1269 -0
  17. package/dist/cli/chunk-5JLQPVNX.js +3056 -0
  18. package/dist/cli/chunk-6A3TJUWC.js +76 -0
  19. package/dist/cli/chunk-6HPEDBSJ.js +1995 -0
  20. package/dist/cli/chunk-7D6QG5KF.js +890 -0
  21. package/dist/cli/chunk-7P5AA3SN.js +344 -0
  22. package/dist/cli/chunk-7UAO5MWV.mjs +190 -0
  23. package/dist/cli/chunk-A7427JJH.js +190 -0
  24. package/dist/cli/chunk-AQRTLPHZ.js +735 -0
  25. package/dist/cli/chunk-AYHLUHE5.js +52 -0
  26. package/dist/cli/chunk-BZ77OTRF.mjs +923 -0
  27. package/dist/cli/chunk-CBVIJSHF.mjs +560 -0
  28. package/dist/cli/chunk-COGTRVWW.js +30 -0
  29. package/dist/cli/chunk-DLIRSHV6.mjs +28 -0
  30. package/dist/cli/chunk-DYWHXO7O.mjs +34 -0
  31. package/dist/cli/chunk-EDWJY6T4.mjs +3056 -0
  32. package/dist/cli/chunk-EXMLR72R.mjs +0 -0
  33. package/dist/cli/chunk-G46HHFNB.mjs +1269 -0
  34. package/dist/cli/chunk-GAMFK2ZP.mjs +148 -0
  35. package/dist/cli/chunk-GLKUGBTP.mjs +2240 -0
  36. package/dist/cli/chunk-GONRLVV3.js +3440 -0
  37. package/dist/cli/chunk-GVUJJJ5G.mjs +76 -0
  38. package/dist/cli/chunk-H7HIDGZ7.mjs +150 -0
  39. package/dist/cli/chunk-HUZXWOSK.mjs +503 -0
  40. package/dist/cli/chunk-I5YZLGMG.js +1 -0
  41. package/dist/cli/chunk-ITOFSXIU.mjs +15 -0
  42. package/dist/cli/chunk-J2D3VDOU.mjs +5688 -0
  43. package/dist/cli/chunk-J5NA2TTX.js +503 -0
  44. package/dist/cli/chunk-JCS5TPNY.mjs +3440 -0
  45. package/dist/cli/chunk-JNNOCMQY.js +47 -0
  46. package/dist/cli/chunk-KRD6H754.mjs +30 -0
  47. package/dist/cli/chunk-L4HBNHFW.js +34 -0
  48. package/dist/cli/chunk-LA46MMTL.js +560 -0
  49. package/dist/cli/chunk-LIKFCE7Z.js +190 -0
  50. package/dist/cli/chunk-MIMASXO4.mjs +389 -0
  51. package/dist/cli/chunk-NPPJX3BL.mjs +1995 -0
  52. package/dist/cli/chunk-NTEZFZLE.mjs +890 -0
  53. package/dist/cli/chunk-NXDRDJ4K.js +389 -0
  54. package/dist/cli/chunk-NXGCO4JB.mjs +344 -0
  55. package/dist/cli/chunk-OG64RBAC.js +6 -0
  56. package/dist/cli/chunk-OWJZUE3Y.mjs +103 -0
  57. package/dist/cli/chunk-QSIO4TX2.mjs +190 -0
  58. package/dist/cli/chunk-RCUE5C5C.mjs +735 -0
  59. package/dist/cli/chunk-SDK3ZA2C.js +103 -0
  60. package/dist/cli/chunk-SFLARO4Y.mjs +47 -0
  61. package/dist/cli/chunk-TAC3JIFE.mjs +354 -0
  62. package/dist/cli/chunk-UC6GHEL4.js +499 -0
  63. package/dist/cli/chunk-UFS752TU.mjs +52 -0
  64. package/dist/cli/chunk-UNEMDKXN.js +1 -0
  65. package/dist/cli/chunk-WB6Z2Q44.mjs +1622 -0
  66. package/dist/cli/chunk-WJYPBHTE.js +148 -0
  67. package/dist/cli/chunk-WOHBA5PV.js +354 -0
  68. package/dist/cli/chunk-WZYKRD7T.mjs +6 -0
  69. package/dist/cli/chunk-XNYIZMNQ.js +28 -0
  70. package/dist/cli/chunk-ZDO3TO3M.js +1622 -0
  71. package/dist/cli/chunk-ZDOC4HFL.js +923 -0
  72. package/dist/cli/client-CZDA4JKO.mjs +20 -0
  73. package/dist/cli/client-IZGIN2ZA.js +20 -0
  74. package/dist/cli/csv-6KOMZA2H.mjs +585 -0
  75. package/dist/cli/csv-UTEQY3NA.js +585 -0
  76. package/dist/cli/db-D5EP6TKO.mjs +486 -0
  77. package/dist/cli/db-SIBLPIKC.js +486 -0
  78. package/dist/cli/executions-2PHT57IO.js +28 -0
  79. package/dist/cli/executions-DFWM2YYY.mjs +28 -0
  80. package/dist/cli/feedback-GZW37JMI.mjs +107 -0
  81. package/dist/cli/feedback-IQVWIJZ4.js +107 -0
  82. package/dist/cli/getting-started.js +18 -76
  83. package/dist/cli/getting-started.mjs +10 -37
  84. package/dist/cli/git-563GYLMA.js +23 -0
  85. package/dist/cli/git-B72Y4FFQ.mjs +23 -0
  86. package/dist/cli/index.js +291 -54294
  87. package/dist/cli/index.mjs +209 -54352
  88. package/dist/cli/legacy-noops-37F5MX2P.mjs +157 -0
  89. package/dist/cli/legacy-noops-IFGVDCOM.js +157 -0
  90. package/dist/cli/monitors-42H6LOVT.mjs +3251 -0
  91. package/dist/cli/monitors-GQCHXBXZ.js +3251 -0
  92. package/dist/cli/org-4GCPBTGR.js +849 -0
  93. package/dist/cli/org-JYZA3ZRJ.mjs +849 -0
  94. package/dist/cli/play-46ZJ4FMI.js +18439 -0
  95. package/dist/cli/play-Q2XV3FZZ.mjs +18439 -0
  96. package/dist/cli/providers-CTKQP45X.mjs +95 -0
  97. package/dist/cli/providers-PCNF5E3K.js +95 -0
  98. package/dist/cli/proxy-env-EBANZHPV.js +161 -0
  99. package/dist/cli/proxy-env-M4ZHXHRL.mjs +161 -0
  100. package/dist/cli/quickstart-FTHWRVWN.js +69 -0
  101. package/dist/cli/quickstart-X7EVVWRG.mjs +69 -0
  102. package/dist/cli/search-73YPOFDO.mjs +18 -0
  103. package/dist/cli/search-XA5UVC3G.js +18 -0
  104. package/dist/cli/secrets-OUMPT4FX.mjs +400 -0
  105. package/dist/cli/secrets-UOEVR73Q.js +400 -0
  106. package/dist/cli/sessions-CMKXCN5Y.js +15 -0
  107. package/dist/cli/sessions-ZIFGDZE7.mjs +15 -0
  108. package/dist/cli/settings-OO5R3G52.mjs +846 -0
  109. package/dist/cli/settings-ULZT2NIC.js +846 -0
  110. package/dist/cli/setup-6GZH52OZ.mjs +1257 -0
  111. package/dist/cli/setup-DHGERXPZ.js +1257 -0
  112. package/dist/cli/skills-Q7NUCS2W.js +28 -0
  113. package/dist/cli/skills-T3EY2656.mjs +28 -0
  114. package/dist/cli/tools-BIMOAOTX.mjs +2955 -0
  115. package/dist/cli/tools-ODXVCKO7.js +2955 -0
  116. package/dist/cli/update-UMB3ULBR.js +28 -0
  117. package/dist/cli/update-X4HX7Z3M.mjs +28 -0
  118. package/dist/cli/workflow-EAUFVPIP.mjs +1936 -0
  119. package/dist/cli/workflow-IVLCPFTG.js +1936 -0
  120. package/dist/helpers.js +6 -32
  121. package/dist/helpers.mjs +2 -0
  122. package/dist/index.js +1972 -12825
  123. package/dist/index.mjs +1910 -12672
  124. package/dist/install-integrity.json +110 -0
  125. package/dist/monitor-fleet-contract.js +31 -730
  126. package/dist/monitor-fleet-contract.mjs +18 -667
  127. package/dist/monitor-input-contract.js +10 -390
  128. package/dist/monitor-input-contract.mjs +7 -348
  129. package/dist/plays/bundle-play-file.mjs +13 -5178
  130. package/dist/plays/csv-data-input.js +5 -3132
  131. package/dist/plays/csv-data-input.mjs +5 -3105
  132. package/dist/plays/run-request.js +56 -664
  133. package/dist/plays/run-request.mjs +30 -588
  134. package/dist/release.d.mts +1 -1
  135. package/dist/release.d.ts +1 -1
  136. package/dist/release.js +5 -212
  137. package/dist/release.mjs +5 -185
  138. package/package.json +1 -1
@@ -0,0 +1,1936 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;
2
+
3
+ var _chunk3XX5TEA4js = require('./chunk-3XX5TEA4.js');
4
+
5
+
6
+ var _chunk2C3AVPTYjs = require('./chunk-2C3AVPTY.js');
7
+ require('./chunk-LA46MMTL.js');
8
+
9
+
10
+
11
+
12
+
13
+ var _chunk7D6QG5KFjs = require('./chunk-7D6QG5KF.js');
14
+ require('./chunk-6HPEDBSJ.js');
15
+ require('./chunk-XNYIZMNQ.js');
16
+ require('./chunk-LIKFCE7Z.js');
17
+
18
+
19
+ var _chunk3KC45UVFjs = require('./chunk-3KC45UVF.js');
20
+ require('./chunk-6A3TJUWC.js');
21
+ require('./chunk-7P5AA3SN.js');
22
+ require('./chunk-OG64RBAC.js');
23
+ require('./chunk-COGTRVWW.js');
24
+
25
+ // src/cli/commands/workflow.ts
26
+ var _promises = require('fs/promises');
27
+ var _path = require('path');
28
+
29
+ // src/cli/workflow-to-play.ts
30
+ var _crypto = require('crypto');
31
+
32
+ // ../plays/tool-codegen.ts
33
+ var KNOWN_GETTER_NAMES = /* @__PURE__ */ new Set([
34
+ "company_domain",
35
+ "company_linkedin_url",
36
+ "company_name",
37
+ "domain",
38
+ "email",
39
+ "email_status",
40
+ "first_name",
41
+ "full_name",
42
+ "job_change",
43
+ "job_change_status",
44
+ "job_changed",
45
+ "last_name",
46
+ "linkedin",
47
+ "personal_email",
48
+ "phone",
49
+ "phone_status",
50
+ "status",
51
+ "title"
52
+ ]);
53
+ function renderToolCodegenString(value) {
54
+ return JSON.stringify(value);
55
+ }
56
+ function renderToolRowPathExpression(path, rowName = "row") {
57
+ const parts = String(path || "").replace(/\[(\d+)\]/g, ".$1").split(".").map((part) => part.trim()).filter(Boolean);
58
+ if (parts.length === 0) return rowName;
59
+ return parts.reduce((expr, part, index) => {
60
+ if (index === 0) return `${rowName}[${renderToolCodegenString(part)}]`;
61
+ return `(${expr} as Record<string, unknown> | null | undefined)?.[${renderToolCodegenString(part)}]`;
62
+ }, rowName);
63
+ }
64
+ function renderToolPayloadExpression(value, rowName = "row") {
65
+ if (Array.isArray(value)) {
66
+ return `[${value.map((entry) => renderToolPayloadExpression(entry, rowName)).join(", ")}]`;
67
+ }
68
+ if (value && typeof value === "object") {
69
+ const entries = Object.entries(value).sort(
70
+ ([left], [right]) => left.localeCompare(right)
71
+ );
72
+ return `{ ${entries.map(
73
+ ([key, entry]) => `${renderToolCodegenString(key)}: ${renderToolPayloadExpression(entry, rowName)}`
74
+ ).join(", ")} }`;
75
+ }
76
+ if (typeof value !== "string") return JSON.stringify(value);
77
+ const exact = value.match(/^\{\{\s*([^{}]+?)\s*\}\}$/);
78
+ if (exact) return renderToolRowPathExpression(_nullishCoalesce(exact[1], () => ( "")), rowName);
79
+ const pieces = [];
80
+ let cursor = 0;
81
+ for (const match of value.matchAll(/\{\{\s*([^{}]+?)\s*\}\}/g)) {
82
+ const index = _nullishCoalesce(match.index, () => ( 0));
83
+ if (index > cursor) {
84
+ pieces.push(renderToolCodegenString(value.slice(cursor, index)));
85
+ }
86
+ pieces.push(
87
+ `String(${renderToolRowPathExpression(_nullishCoalesce(match[1], () => ( "")), rowName)} ?? '')`
88
+ );
89
+ cursor = index + match[0].length;
90
+ }
91
+ if (pieces.length === 0) return renderToolCodegenString(value);
92
+ if (cursor < value.length) {
93
+ pieces.push(renderToolCodegenString(value.slice(cursor)));
94
+ }
95
+ return pieces.join(" + ");
96
+ }
97
+ function renderExtractedValueGetterExpression(toolResultVar, targetKey) {
98
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(targetKey) ? `${toolResultVar}.extractedValues.${targetKey}?.get()` : `${toolResultVar}.extractedValues[${renderToolCodegenString(targetKey)}]?.get()`;
99
+ }
100
+ function getterFromLegacyPath(path) {
101
+ const last = String(path || "").replace(/\[(\d+)\]/g, ".$1").split(".").map((part) => part.trim()).filter(Boolean).at(-1);
102
+ if (!last) return null;
103
+ const normalized = last.replace(/[^A-Za-z0-9_]/g, "_");
104
+ return KNOWN_GETTER_NAMES.has(normalized) ? normalized : null;
105
+ }
106
+ function getterFromLegacyExtractJs(extractJs, fallbackAlias) {
107
+ const source = _optionalChain([extractJs, 'optionalAccess', _ => _.trim, 'call', _2 => _2()]);
108
+ if (!source) {
109
+ const aliasGetter = _optionalChain([fallbackAlias, 'optionalAccess', _3 => _3.replace, 'call', _4 => _4(/[^A-Za-z0-9_]/g, "_")]);
110
+ return aliasGetter && KNOWN_GETTER_NAMES.has(aliasGetter) ? aliasGetter : null;
111
+ }
112
+ const directExtract = source.match(
113
+ /\bextract\(\s*["'][^"']+["']\s*,\s*output_data\s*,\s*["']([^"']+)["']\s*\)/
114
+ );
115
+ if (_optionalChain([directExtract, 'optionalAccess', _5 => _5[1]])) {
116
+ return getterFromLegacyPath(
117
+ directExtract[1] === "linkedin_url" ? "linkedin" : directExtract[1]
118
+ );
119
+ }
120
+ const pick = source.match(
121
+ /\b(?:pick|extract|target)\(\s*(\[[\s\S]*?\]|["'][^"']+["'])\s*\)/
122
+ );
123
+ if (!_optionalChain([pick, 'optionalAccess', _6 => _6[1]])) return null;
124
+ try {
125
+ const parsed = JSON.parse(pick[1].replace(/'/g, '"'));
126
+ const paths = Array.isArray(parsed) ? parsed : [parsed];
127
+ for (const path of paths) {
128
+ if (typeof path !== "string") continue;
129
+ const getter = getterFromLegacyPath(path);
130
+ if (getter) return getter;
131
+ }
132
+ } catch (e) {
133
+ return null;
134
+ }
135
+ return null;
136
+ }
137
+
138
+ // ../plays/user-code-safety.ts
139
+ var FORBIDDEN = [
140
+ // Non-deterministic — breaks replay.
141
+ { pattern: /\bMath\s*\.\s*random\b/, reason: "Math.random()" },
142
+ { pattern: /\bDate\s*\.\s*now\b/, reason: "Date.now()" },
143
+ { pattern: /\bnew\s+Date\s*\(\s*\)/, reason: "new Date() with no argument" },
144
+ { pattern: /\bperformance\s*\.\s*now\b/, reason: "performance.now()" },
145
+ {
146
+ pattern: /\bcrypto\s*\.\s*(?:randomUUID|getRandomValues)\b/,
147
+ reason: "crypto random"
148
+ },
149
+ // Sandbox escape / I/O.
150
+ { pattern: /(?<!\.)\bfetch\s*\(/, reason: "fetch()" },
151
+ { pattern: /(?<!\.)\bimport\s*\(/, reason: "dynamic import()" },
152
+ { pattern: /(?<!\.)\brequire\s*\(/, reason: "require()" },
153
+ { pattern: /(?<!\.)\beval\s*\(/, reason: "eval()" },
154
+ {
155
+ pattern: /(?<!\.)\bnew\s+Function\b|(?<!\.)\bFunction\s*\(/,
156
+ reason: "the Function constructor"
157
+ },
158
+ { pattern: /(?<!\.)\bprocess\b/, reason: "process" },
159
+ { pattern: /(?<!\.)\bglobalThis\b/, reason: "globalThis" },
160
+ { pattern: /(?<!\.)\b(?:window|self)\b/, reason: "window/self" },
161
+ { pattern: /(?<!\.)\bXMLHttpRequest\b/, reason: "XMLHttpRequest" },
162
+ { pattern: /(?<!\.)\bWebAssembly\b/, reason: "WebAssembly" }
163
+ ];
164
+ function assertUserCodeIsSafe(code, label) {
165
+ if (typeof code !== "string" || !code.trim()) return;
166
+ for (const { pattern, reason } of FORBIDDEN) {
167
+ if (pattern.test(code)) {
168
+ throw new Error(
169
+ `${label} uses ${reason}, which is not allowed in play code: it breaks deterministic replay or escapes the sandbox. Remove it and compute the value from the row/result instead.`
170
+ );
171
+ }
172
+ }
173
+ }
174
+
175
+ // ../plays/enrich-play-compiler.ts
176
+ function isWaterfall(command) {
177
+ return "with_waterfall" in command;
178
+ }
179
+ function configHasRunJavascript(config) {
180
+ const walk = (commands) => commands.some(
181
+ (command) => isWaterfall(command) ? walk(command.commands) : command.tool === "run_javascript"
182
+ );
183
+ return walk(_nullishCoalesce(config.commands, () => ( [])));
184
+ }
185
+ function stringLiteral(value) {
186
+ return JSON.stringify(value);
187
+ }
188
+ function stableJson(value) {
189
+ if (Array.isArray(value)) {
190
+ return `[${value.map(stableJson).join(",")}]`;
191
+ }
192
+ if (value && typeof value === "object") {
193
+ const entries = Object.entries(value).sort(
194
+ ([left], [right]) => left.localeCompare(right)
195
+ );
196
+ return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${stableJson(entry)}`).join(",")}}`;
197
+ }
198
+ return JSON.stringify(value);
199
+ }
200
+ function indent(source, spaces) {
201
+ const pad = " ".repeat(spaces);
202
+ return source.split("\n").map((line) => line ? `${pad}${line}` : line).join("\n");
203
+ }
204
+ function commandCallId(command) {
205
+ return `${command.alias}__${command.tool}`;
206
+ }
207
+ function normalizeAlias(value) {
208
+ return value.toLowerCase().replace(/[^a-z0-9]/g, "");
209
+ }
210
+ function renderExecuteStep(command, options = {
211
+ force: false
212
+ }) {
213
+ if (command.tool === "run_javascript" && options.inlineRunJavascript && canInlineRunJavascript(command)) {
214
+ return renderInlineJavascriptStep(command, options);
215
+ }
216
+ if (command.play) {
217
+ return renderPlayStep(command, options);
218
+ }
219
+ if (options.idiomaticGetters) {
220
+ return renderIdiomaticExecuteStep(command, options);
221
+ }
222
+ const alias = stringLiteral(command.alias);
223
+ const callId = stringLiteral(commandCallId(command));
224
+ const tool = stringLiteral(command.tool);
225
+ const payload = stableJson(_nullishCoalesce(command.payload, () => ( {})));
226
+ const extractJs = renderExtractFunction(command, 6);
227
+ const runIfJs = options.nativeRunIf ? "null" : _nullishCoalesce(renderRunIfFunction(command), () => ( "null"));
228
+ const description = command.description ? `,
229
+ description: ${stringLiteral(command.description)}` : "";
230
+ const force = options.force ? `,
231
+ force: true` : "";
232
+ const legacyEnvelope = options.legacyEnvelope ? `,
233
+ legacyEnvelope: true` : "";
234
+ return [
235
+ `async (row, stepCtx) => {`,
236
+ ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
237
+ ` return __dlRunCommand({`,
238
+ ` alias: ${alias},`,
239
+ ` callId: ${callId},`,
240
+ ` tool: ${tool},`,
241
+ ` payload: ${payload},`,
242
+ ` extract: ${extractJs},`,
243
+ ` runIf: ${runIfJs},`,
244
+ ` row,`,
245
+ ` stepCtx${description}${force}${legacyEnvelope}`,
246
+ ` });`,
247
+ `}`
248
+ ].join("\n");
249
+ }
250
+ function canInlineRunJavascript(command) {
251
+ const code = typeof _optionalChain([command, 'access', _7 => _7.payload, 'optionalAccess', _8 => _8.code]) === "string" ? command.payload.code : "";
252
+ if (/\btriggerWorkflow\b/.test(code)) {
253
+ return false;
254
+ }
255
+ try {
256
+ assertUserCodeIsSafe(code, `run_javascript step "${command.alias}"`);
257
+ } catch (e2) {
258
+ return false;
259
+ }
260
+ return true;
261
+ }
262
+ function renderExtractFunction(command, indentSpaces) {
263
+ return command.extract_js ? `({ row, result, data, raw, pick, extract, extractList, target, get }) => { const input = row; const context = row; const output_data = __dlLegacyOutputData(result, raw);
264
+ ${indent(renderJavascriptBody(command.extract_js), indentSpaces)}
265
+ }` : "null";
266
+ }
267
+ function renderRunIfFunction(command) {
268
+ return command.run_if_js ? `(row) => { const input = row; const context = row;
269
+ ${indent(renderJavascriptBody(command.run_if_js), 6)}
270
+ }` : null;
271
+ }
272
+ function renderColumnRunIfFunction(command) {
273
+ if (!command.run_if_js) {
274
+ return null;
275
+ }
276
+ return `(__dlRawRow) => { const row = __dlPrepareEnrichRow(__dlRawRow, [${stringLiteral(command.alias)}]); const input = row; const context = row;
277
+ ${indent(renderJavascriptBody(command.run_if_js), 6)}
278
+ }`;
279
+ }
280
+ function renderCombinedRunIfFunction(precheck, runIfSource) {
281
+ if (!runIfSource) {
282
+ return null;
283
+ }
284
+ return precheck ? `(row) => { if (${precheck}) return false; return (${runIfSource})(row); }` : runIfSource;
285
+ }
286
+ function renderIdiomaticExecuteStep(command, options) {
287
+ const callId = stringLiteral(commandCallId(command));
288
+ const tool = stringLiteral(command.tool);
289
+ const input = renderToolPayloadExpression(_nullishCoalesce(command.payload, () => ( {})));
290
+ const getter = getterFromLegacyExtractJs(command.extract_js, command.alias);
291
+ const extraction = getter ? `${renderExtractedValueGetterExpression("result", getter)} ?? null` : "result";
292
+ const runIfLines = command.run_if_js && !options.nativeRunIf ? [
293
+ ` if (`,
294
+ ` !((row: Record<string, any>) => {`,
295
+ ` const input = row;`,
296
+ ` const context = row;`,
297
+ indent(renderJavascriptBody(command.run_if_js), 6),
298
+ ` })(row as Record<string, any>)`,
299
+ ` ) return null;`
300
+ ] : [];
301
+ return [
302
+ `async (row, ctx) => {`,
303
+ ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
304
+ ...runIfLines,
305
+ ` const result: any = await ctx.tools.execute({`,
306
+ ` id: ${callId},`,
307
+ ` tool: ${tool},`,
308
+ ` input: ${input} as any,`,
309
+ ` description: ${stringLiteral((_nullishCoalesce(command.description, () => ( ""))).trim() || `Run ${command.alias} via ${command.tool}.`)},`,
310
+ ...options.force ? [` force: true,`] : [],
311
+ ` });`,
312
+ ` __dlAssertSuccessfulToolResult(result);`,
313
+ ` return ${extraction};`,
314
+ `}`
315
+ ].join("\n");
316
+ }
317
+ function renderPlayStep(command, options) {
318
+ const alias = stringLiteral(command.alias);
319
+ const callId = stringLiteral(commandCallId(command));
320
+ const playRef = stringLiteral(_nullishCoalesce(_optionalChain([command, 'access', _9 => _9.play, 'optionalAccess', _10 => _10.ref]), () => ( command.tool)));
321
+ const payload = stableJson(_nullishCoalesce(command.payload, () => ( {})));
322
+ const runIfJs = _nullishCoalesce(renderRunIfFunction(command), () => ( "null"));
323
+ const runIfLines = command.run_if_js && !options.nativeRunIf ? [
324
+ ` const __dlRunIf = ${runIfJs};`,
325
+ ` if (!__dlRunIf(templateRow)) return null;`
326
+ ] : [];
327
+ const inline = _optionalChain([command, 'access', _11 => _11.play, 'optionalAccess', _12 => _12.inline]);
328
+ const inlineHandler = inline ? `__dlInlinePlay_${inline.sourceHash.slice(0, 16)}` : null;
329
+ return [
330
+ `async (row, stepCtx) => {`,
331
+ ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
332
+ ` const templateRow = __dlPrepareEnrichRow(row, [${alias}]);`,
333
+ ...runIfLines,
334
+ ` const payload = __dlTemplate(${payload}, templateRow) as Record<string, unknown>;`,
335
+ ` if (__dlShouldSkipBlankPlayPayload(payload)) return null;`,
336
+ ` const result: unknown = `,
337
+ ...inlineHandler ? [
338
+ // Enrich validates and normalizes this payload against the certified
339
+ // prebuilt contract before code generation. The attachment retains
340
+ // its concrete input type, while generated payloads are records.
341
+ ` await __dlRunInlinePlay(${inlineHandler}, stepCtx, payload as never, ${options.force});`
342
+ ] : [
343
+ ` await stepCtx.runPlay(${callId}, ${playRef}, payload, {`,
344
+ ` description: ${stringLiteral(_nullishCoalesce(command.description, () => ( command.alias)))}`,
345
+ ` });`
346
+ ],
347
+ ``,
348
+ ` __dlAssertSuccessfulToolResult(result);`,
349
+ ` return __dlPlayResultValue(${alias}, result);`,
350
+ `}`
351
+ ].join("\n");
352
+ }
353
+ function collectInlinePlayHandlers(commands) {
354
+ const handlers = /* @__PURE__ */ new Map();
355
+ const visit = (command) => {
356
+ if (isWaterfall(command)) {
357
+ command.commands.forEach(visit);
358
+ return;
359
+ }
360
+ const inline = _optionalChain([command, 'access', _13 => _13.play, 'optionalAccess', _14 => _14.inline]);
361
+ if (inline) handlers.set(inline.sourceHash, inline);
362
+ };
363
+ commands.forEach(visit);
364
+ return [...handlers.values()];
365
+ }
366
+ function renderInlineJavascriptStep(command, options) {
367
+ const alias = stringLiteral(command.alias);
368
+ const extractJs = renderExtractFunction(command, 4);
369
+ const legacyEnvelope = options.legacyEnvelope ? "true" : "false";
370
+ const resultExpression = command.extract_js ? `__dlExtract(${alias}, result, row as Record<string, unknown>, ${extractJs}, ${legacyEnvelope})` : "result";
371
+ const payload = stableJson(_nullishCoalesce(command.payload, () => ( {})));
372
+ const code = typeof _optionalChain([command, 'access', _15 => _15.payload, 'optionalAccess', _16 => _16.code]) === "string" ? command.payload.code : "return null;";
373
+ const runIfLines = command.run_if_js && !options.nativeRunIf ? [
374
+ ` if (!((row: Record<string, any>) => { const input = row; const context = row;`,
375
+ indent(renderJavascriptBody(command.run_if_js), 4),
376
+ ` })(row as Record<string, any>)) return null;`
377
+ ] : [];
378
+ return [
379
+ `async (row) => {`,
380
+ ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
381
+ ...runIfLines,
382
+ ` const __dlPayload = __dlRuntimePayload('run_javascript', __dlTemplate(${payload}, row as Record<string, unknown>) as Record<string, unknown>, row as Record<string, unknown>);`,
383
+ ` const rawResult = ((row: Record<string, any>, input: Record<string, any>, context: Record<string, any>) => {`,
384
+ ` const payload = __dlPayload as Record<string, any>;`,
385
+ ` const extract = __dlInlineExtract;`,
386
+ ` const extractList = __dlInlineExtractList;`,
387
+ ` return (() => {`,
388
+ indent(renderJavascriptBody(code), 4),
389
+ ` })();`,
390
+ ` })(row as Record<string, any>, row as Record<string, any>, row as Record<string, any>);`,
391
+ ` const result = await Promise.resolve(rawResult);`,
392
+ ` return ${resultExpression};`,
393
+ `}`
394
+ ].join("\n");
395
+ }
396
+ function renderJavascriptBody(source) {
397
+ assertUserCodeIsSafe(source, "play step code");
398
+ const trimmed = source.trim();
399
+ if (/^(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>/.test(trimmed)) {
400
+ return `return (${trimmed});`;
401
+ }
402
+ if (trimmed && !trimmed.includes("\n") && !trimmed.includes(";") && !/\breturn\b/.test(trimmed) && !/^(?:throw|if|for|while|switch|try|catch|const|let|var|class|function)\b/.test(
403
+ trimmed
404
+ )) {
405
+ return `return (${trimmed});`;
406
+ }
407
+ return source;
408
+ }
409
+ function renderColumnStep(alias, resolverSource, options = {}) {
410
+ const resolver = indent(resolverSource, 8);
411
+ const optionFields = options.runIfSource ? [`runIf: ${options.runIfSource}`] : [];
412
+ const optionSource = optionFields.length > 0 ? `{ ${optionFields.join(", ")} }` : null;
413
+ return [
414
+ ` .withColumn(${stringLiteral(alias)},`,
415
+ `${resolver}${optionSource ? "," : ""}`,
416
+ ...optionSource ? [` ${optionSource},`] : [],
417
+ ` )`
418
+ ].join("\n");
419
+ }
420
+ function metadataMode(command) {
421
+ return /\bextractList\s*\(/.test(_nullishCoalesce(command.extract_js, () => ( ""))) ? "list" : "scalar";
422
+ }
423
+ function metadataEntryForCommand(command, waterfallGroupId) {
424
+ const entry = {
425
+ tool_id: command.tool
426
+ };
427
+ if (_optionalChain([command, 'access', _17 => _17.play, 'optionalAccess', _18 => _18.ref])) {
428
+ entry.play_ref = command.play.ref;
429
+ entry.kind = "play_call";
430
+ }
431
+ if (command.operation) {
432
+ entry.operation = command.operation;
433
+ }
434
+ if (_optionalChain([command, 'access', _19 => _19.extract_js, 'optionalAccess', _20 => _20.trim, 'call', _21 => _21()])) {
435
+ entry.extract_js = command.extract_js.trim();
436
+ }
437
+ if (waterfallGroupId) {
438
+ entry.waterfall = {
439
+ group_id: waterfallGroupId,
440
+ mode: metadataMode(command)
441
+ };
442
+ }
443
+ return entry;
444
+ }
445
+ function collectMetadataColumns(commands, waterfallGroupId) {
446
+ const columns = {};
447
+ for (const command of commands) {
448
+ if (isWaterfall(command)) {
449
+ Object.assign(
450
+ columns,
451
+ collectMetadataColumns(command.commands, command.with_waterfall)
452
+ );
453
+ continue;
454
+ }
455
+ if (command.disabled) {
456
+ continue;
457
+ }
458
+ columns[normalizeAlias(command.alias)] = metadataEntryForCommand(
459
+ command,
460
+ waterfallGroupId
461
+ );
462
+ }
463
+ return columns;
464
+ }
465
+ function collectGeneratedAliases(commands) {
466
+ const aliases = [];
467
+ const addAlias = (alias) => {
468
+ if (alias && !aliases.includes(alias)) {
469
+ aliases.push(alias);
470
+ }
471
+ };
472
+ for (const command of commands) {
473
+ if (isWaterfall(command)) {
474
+ const before = aliases.length;
475
+ collectGeneratedAliases(command.commands).forEach(addAlias);
476
+ if (aliases.length > before) {
477
+ addAlias(command.with_waterfall);
478
+ addAlias(`${command.with_waterfall}_source`);
479
+ }
480
+ continue;
481
+ }
482
+ if (!command.disabled) {
483
+ addAlias(command.alias);
484
+ }
485
+ }
486
+ return aliases;
487
+ }
488
+ function renderMetadataColumnStep(config) {
489
+ const columns = collectMetadataColumns(config.commands);
490
+ if (Object.keys(columns).length === 0) {
491
+ return "";
492
+ }
493
+ return [
494
+ ` .withColumn('_metadata',`,
495
+ ` (row) => __dlMergeMetadata(__dlMetadataFromRow(row), ${stableJson({ columns })}),`,
496
+ ` )`
497
+ ].join("\n");
498
+ }
499
+ function renderWaterfallColumns(command, forceAliases, inlineRunJavascript, idiomaticGetters) {
500
+ const activeChildren = command.commands.filter(
501
+ (nested) => !isWaterfall(nested) && !nested.disabled
502
+ );
503
+ const minResults = typeof command.min_results === "number" ? Math.max(1, Math.trunc(command.min_results)) : 1;
504
+ const columnSteps = activeChildren.map((nested, stepIndex) => {
505
+ if (isWaterfall(nested)) {
506
+ throw new Error("Nested with_waterfall blocks are not supported.");
507
+ }
508
+ if (nested.disabled) {
509
+ return null;
510
+ }
511
+ const priorAliases = activeChildren.slice(0, stepIndex).map((prior) => prior.alias);
512
+ const force = forceAliases.has(normalizeAlias(nested.alias));
513
+ const precheck = priorAliases.length > 0 ? `__dlWaterfallSatisfied(row, ${stableJson(priorAliases)}, ${minResults})` : void 0;
514
+ const runIfSource = renderCombinedRunIfFunction(
515
+ precheck,
516
+ renderColumnRunIfFunction(nested)
517
+ );
518
+ return renderColumnStep(
519
+ nested.alias,
520
+ renderExecuteStep(nested, {
521
+ force,
522
+ precheck,
523
+ legacyEnvelope: Boolean(nested.extract_js),
524
+ inlineRunJavascript,
525
+ idiomaticGetters,
526
+ nativeRunIf: Boolean(runIfSource)
527
+ }),
528
+ {
529
+ runIfSource
530
+ }
531
+ );
532
+ }).filter((line) => line !== null);
533
+ const aliases = activeChildren.map((nested) => nested.alias);
534
+ const returnExpr = typeof command.min_results === "number" ? `__dlFirstMinResults(row, ${stableJson(aliases)}, ${Math.max(
535
+ 1,
536
+ Math.trunc(command.min_results)
537
+ )})` : `__dlFirstMeaningful(row, ${stableJson(aliases)})`;
538
+ if (columnSteps.length === 0) {
539
+ return [];
540
+ }
541
+ return [
542
+ ...columnSteps,
543
+ renderColumnStep(command.with_waterfall, `(row) => ${returnExpr}`),
544
+ renderColumnStep(
545
+ `${command.with_waterfall}_source`,
546
+ typeof command.min_results === "number" ? `(row) => __dlContributingAliases(row, ${stableJson(aliases)})` : `(row) => __dlFirstMeaningfulAlias(row, ${stableJson(aliases)})`
547
+ )
548
+ ];
549
+ }
550
+ function compileEnrichConfigToPlaySource(config, options = {}) {
551
+ if (options.maxCreditsPerRun !== void 0 && (!Number.isFinite(options.maxCreditsPerRun) || options.maxCreditsPerRun <= 0)) {
552
+ throw new Error("maxCreditsPerRun must be a number greater than 0.");
553
+ }
554
+ const compatibility = _chunk3XX5TEA4js.buildEnrichCompatibilityPlan.call(void 0, options);
555
+ const { playName, mapName } = compatibility;
556
+ const inlineRunJavascript = _nullishCoalesce(options.inlineRunJavascript, () => ( false));
557
+ const idiomaticGetters = _nullishCoalesce(options.idiomaticGetters, () => ( false));
558
+ const forceAliases = new Set(
559
+ [..._nullishCoalesce(options.forceAliases, () => ( []))].map((alias) => normalizeAlias(alias))
560
+ );
561
+ const columnSteps = [];
562
+ const inlineHandlers = collectInlinePlayHandlers(config.commands);
563
+ const inlineTypeImports = [
564
+ ...new Set(inlineHandlers.flatMap((inline) => _nullishCoalesce(inline.typeImports, () => ( []))))
565
+ ].sort();
566
+ const inlineRuntimeImports = [
567
+ ...new Set(inlineHandlers.flatMap((inline) => _nullishCoalesce(inline.runtimeImports, () => ( []))))
568
+ ].sort();
569
+ config.commands.forEach((command) => {
570
+ if (isWaterfall(command)) {
571
+ columnSteps.push(
572
+ ...renderWaterfallColumns(
573
+ command,
574
+ forceAliases,
575
+ inlineRunJavascript,
576
+ idiomaticGetters
577
+ )
578
+ );
579
+ return;
580
+ }
581
+ if (command.disabled) {
582
+ return;
583
+ }
584
+ const force = forceAliases.has(normalizeAlias(command.alias));
585
+ const runIfSource = renderColumnRunIfFunction(command);
586
+ columnSteps.push(
587
+ renderColumnStep(
588
+ command.alias,
589
+ renderExecuteStep(command, {
590
+ force,
591
+ inlineRunJavascript,
592
+ idiomaticGetters,
593
+ nativeRunIf: Boolean(runIfSource)
594
+ }),
595
+ {
596
+ runIfSource
597
+ }
598
+ )
599
+ );
600
+ });
601
+ const columnStepSource = columnSteps.length > 0 ? columnSteps.join("\n") : ` .withColumn('noop', () => null)`;
602
+ const metadataColumnSource = renderMetadataColumnStep(config);
603
+ const generatedAliases = collectGeneratedAliases(config.commands);
604
+ const runOptionsSource = options.failFast ? `{ key: (row, index) => __dlEnrichRowKey(row, index + rowStart), onRowError: 'fail' as const }` : `{ key: (row, index) => __dlEnrichRowKey(row, index + rowStart) }`;
605
+ const describedColumns = config.commands.filter((command) => isWaterfall(command) || !command.disabled).map(
606
+ (command) => (isWaterfall(command) ? command.with_waterfall : command.alias).replace(/[_-]+/g, " ").trim()
607
+ ).filter(Boolean).slice(0, 3);
608
+ const generatedDescription = describedColumns.length ? `Enrich CSV rows with ${describedColumns.join(", ")}.` : "Prepare CSV rows for enrichment.";
609
+ const playOptionsSource = [
610
+ `description: ${stringLiteral(generatedDescription)}`,
611
+ ...options.maxCreditsPerRun === void 0 ? [] : [`billing: { maxCreditsPerRun: ${String(options.maxCreditsPerRun)} }`]
612
+ ].join(", ");
613
+ const body = [
614
+ `function __dlRunInlinePlay<TContext, TInput, TOutput>(handler: (ctx: TContext, input: TInput) => Promise<TOutput>, scope: TContext, payload: TInput, force: boolean): Promise<TOutput> {`,
615
+ ` if (!force) return handler(scope, payload);`,
616
+ ` const runtimeScope = scope as TContext & { __deeplineRunWithForcedTools?: <T>(run: () => Promise<T>) => Promise<T> };`,
617
+ ` if (typeof runtimeScope.__deeplineRunWithForcedTools !== 'function') {`,
618
+ ` throw new Error('This runtime does not support forced certified inline play execution.');`,
619
+ ` }`,
620
+ ` return runtimeScope.__deeplineRunWithForcedTools(() => handler(scope, payload));`,
621
+ `}`,
622
+ ``,
623
+ ...inlineHandlers.flatMap((inline) => [
624
+ `const __dlInlinePlay_${inline.sourceHash.slice(0, 16)} = ${inline.functionExpressionSource};`,
625
+ ``
626
+ ]),
627
+ `export default definePlay(${stringLiteral(playName)}, async (ctx, input: EnrichInput) => {`,
628
+ ` const sourceRows = await ctx.csv<Record<string, unknown>>(input.file);`,
629
+ ` const rowStart = __dlNonNegativeInteger(input.rowStart, 0);`,
630
+ ` const rowEndExclusive = Number.isFinite(input.rowEnd) ? Math.max(rowStart, __dlWholeNumber(input.rowEnd, rowStart) + 1) : undefined;`,
631
+ ` const rows: Array<Record<string, unknown>> = [];`,
632
+ ` let sourceRowIndex = 0;`,
633
+ ` for await (const row of sourceRows) {`,
634
+ ` if (rowEndExclusive !== undefined && sourceRowIndex >= rowEndExclusive) break;`,
635
+ ` if (sourceRowIndex >= rowStart) {`,
636
+ ` rows.push(__dlPrepareEnrichRow(row, ${stableJson(generatedAliases)}, sourceRowIndex));`,
637
+ ` }`,
638
+ ` sourceRowIndex += 1;`,
639
+ ` }`,
640
+ ` const enriched = await ctx`,
641
+ ` .dataset(${stringLiteral(mapName)}, rows)`,
642
+ columnStepSource,
643
+ ...metadataColumnSource ? [metadataColumnSource] : [],
644
+ ` .run(${runOptionsSource});`,
645
+ ` return { rows: enriched, count: await enriched.count() };`,
646
+ `}, { ${playOptionsSource} });`
647
+ ];
648
+ const helpers = idiomaticGetters ? selectUsedHelpers(helperSource(), body.join("\n")) : helperSource();
649
+ const typeImports = idiomaticGetters ? inlineTypeImports : [.../* @__PURE__ */ new Set([...inlineTypeImports, "DeeplinePlayRuntimeContext"])].sort();
650
+ return [
651
+ ...inlineRunJavascript && configHasRunJavascript(config) ? ["// @ts-nocheck", "/* eslint-disable */", ""] : [],
652
+ `import { ${["definePlay", "steps", ...inlineRuntimeImports].join(", ")} } from 'deepline';`,
653
+ ...typeImports.length > 0 ? [`import type { ${typeImports.join(", ")} } from 'deepline';`] : [],
654
+ ``,
655
+ `type EnrichInput = { file: string; rowStart?: number | null; rowEnd?: number | null };`,
656
+ ``,
657
+ helpers,
658
+ ``,
659
+ ...body,
660
+ ``
661
+ ].join("\n");
662
+ }
663
+ function selectUsedHelpers(helperBlock, referenceSource) {
664
+ const referencesSymbol = (source, symbol) => new RegExp(`\\b${symbol}\\b`).test(source);
665
+ const blocks = helperBlock.split("\n\n").map((source) => source.trim()).filter(Boolean).map((source) => ({
666
+ name: _nullishCoalesce(_optionalChain([source, 'access', _22 => _22.match, 'call', _23 => _23(/(?:function|type|const)\s+(__[A-Za-z]\w*)/), 'optionalAccess', _24 => _24[1]]), () => ( "")),
667
+ source
668
+ }));
669
+ const used = /* @__PURE__ */ new Set();
670
+ for (const { name } of blocks) {
671
+ if (name && referencesSymbol(referenceSource, name)) used.add(name);
672
+ }
673
+ let changed = true;
674
+ while (changed) {
675
+ changed = false;
676
+ const usedSource = blocks.filter((block) => used.has(block.name)).map((block) => block.source).join("\n");
677
+ for (const { name } of blocks) {
678
+ if (!name || used.has(name)) continue;
679
+ if (referencesSymbol(usedSource, name)) {
680
+ used.add(name);
681
+ changed = true;
682
+ }
683
+ }
684
+ }
685
+ return blocks.filter((block) => used.has(block.name)).map((block) => block.source).join("\n\n");
686
+ }
687
+ function helperSource() {
688
+ return [
689
+ `function __dlWholeNumber(value: unknown, fallback: number): number {`,
690
+ ` const numeric = Number(value);`,
691
+ ` if (!Number.isFinite(numeric)) return fallback;`,
692
+ ` return Math.floor(numeric);`,
693
+ `}`,
694
+ ``,
695
+ `function __dlNonNegativeInteger(value: unknown, fallback: number): number {`,
696
+ ` return Math.max(0, __dlWholeNumber(value, fallback));`,
697
+ `}`,
698
+ ``,
699
+ `function __dlAtLeastOneInteger(value: number): number {`,
700
+ ` return Math.max(1, Math.floor(Number(value)));`,
701
+ `}`,
702
+ ``,
703
+ `function __dlRecord(value: unknown): value is Record<string, unknown> {`,
704
+ ` return Boolean(value && typeof value === 'object' && !Array.isArray(value));`,
705
+ `}`,
706
+ ``,
707
+ `function __dlParseMetadata(value: unknown): Record<string, unknown> | null {`,
708
+ ` if (__dlRecord(value)) return value;`,
709
+ ` if (typeof value !== 'string') return null;`,
710
+ ` const trimmed = value.trim();`,
711
+ ` if (!trimmed) return null;`,
712
+ ` const candidates = [trimmed];`,
713
+ ` if (trimmed.includes('\\\\"')) candidates.push(trimmed.replace(/\\\\"/g, '"'));`,
714
+ ` for (const candidate of candidates) {`,
715
+ ` try {`,
716
+ ` const parsed = JSON.parse(candidate);`,
717
+ ` if (__dlRecord(parsed)) return parsed;`,
718
+ ` if (typeof parsed === 'string') {`,
719
+ ` const nested = JSON.parse(parsed);`,
720
+ ` if (__dlRecord(nested)) return nested;`,
721
+ ` }`,
722
+ ` } catch {}`,
723
+ ` }`,
724
+ ` return null;`,
725
+ `}`,
726
+ ``,
727
+ `function __dlMetadataFromRow(row: Record<string, unknown>): unknown {`,
728
+ ` const direct = __dlParseMetadata(row._metadata);`,
729
+ ` if (direct) return direct;`,
730
+ ` const relocated = __dlParseMetadata(row.metadata);`,
731
+ ` if (relocated) return relocated;`,
732
+ ` const dotted = __dlParseMetadata(row['metadata.columns']);`,
733
+ ` if (dotted) return { columns: dotted };`,
734
+ ` const underscored = __dlParseMetadata(row.metadata__columns);`,
735
+ ` if (underscored) return { columns: underscored };`,
736
+ ` return row._metadata;`,
737
+ `}`,
738
+ ``,
739
+ `function __dlMergeMetadata(existing: unknown, patch: Record<string, unknown>): Record<string, unknown> {`,
740
+ ` const base = __dlParseMetadata(existing) ?? {};`,
741
+ ` const baseColumns = __dlRecord(base.columns) ? base.columns : {};`,
742
+ ` const patchColumns = __dlRecord(patch.columns) ? patch.columns : {};`,
743
+ ` return {`,
744
+ ` ...base,`,
745
+ ` ...patch,`,
746
+ ` columns: {`,
747
+ ` ...baseColumns,`,
748
+ ` ...patchColumns,`,
749
+ ` },`,
750
+ ` };`,
751
+ `}`,
752
+ ``,
753
+ `function __dlPathParts(path: string): string[] {`,
754
+ ` const source = String(path || '');`,
755
+ ` const parts: string[] = [];`,
756
+ ` let current = '';`,
757
+ ` for (let index = 0; index < source.length; index += 1) {`,
758
+ ` const char = source.slice(index, index + 1);`,
759
+ ` if (char === '.' || char === '[' || char === ']') {`,
760
+ ` const trimmed = current.trim();`,
761
+ ` if (trimmed) parts.push(trimmed);`,
762
+ ` current = '';`,
763
+ ` continue;`,
764
+ ` }`,
765
+ ` current += char;`,
766
+ ` }`,
767
+ ` const trimmed = current.trim();`,
768
+ ` if (trimmed) parts.push(trimmed);`,
769
+ ` return parts;`,
770
+ `}`,
771
+ ``,
772
+ `function __dlNormalizeHeader(value: string): string {`,
773
+ ` return value.trim().replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '');`,
774
+ `}`,
775
+ ``,
776
+ `function __dlOwnStringKeys(record: Record<string, unknown>): string[] {`,
777
+ ` return Object.keys(record);`,
778
+ `}`,
779
+ ``,
780
+ `function __dlReadOwnField(record: Record<string, unknown>, key: string): unknown {`,
781
+ ` return record[key];`,
782
+ `}`,
783
+ ``,
784
+ `function __dlGetNormalizedKey(record: Record<string, unknown>, part: string): string | null {`,
785
+ ` const normalized = __dlNormalizeHeader(part);`,
786
+ ` for (const key of __dlOwnStringKeys(record)) {`,
787
+ ` if (__dlNormalizeHeader(key) === normalized) return key;`,
788
+ ` }`,
789
+ ` return null;`,
790
+ `}`,
791
+ ``,
792
+ `function __dlGetRecordField(record: Record<string, unknown>, part: string): { found: boolean; value: unknown } {`,
793
+ ` if (part in record) return { found: true, value: record[part] };`,
794
+ ` const normalizedKey = __dlGetNormalizedKey(record, part);`,
795
+ ` if (normalizedKey) return { found: true, value: __dlReadOwnField(record, normalizedKey) };`,
796
+ ` const projectedValues = record.__deeplineCsvProjectedValues;`,
797
+ ` if (projectedValues && typeof projectedValues === 'object' && !Array.isArray(projectedValues)) {`,
798
+ ` const projectedRecord = projectedValues as Record<string, unknown>;`,
799
+ ` if (part in projectedRecord) return { found: true, value: projectedRecord[part] };`,
800
+ ` const projectedKey = __dlGetNormalizedKey(projectedRecord, part);`,
801
+ ` if (projectedKey) return { found: true, value: __dlReadOwnField(projectedRecord, projectedKey) };`,
802
+ ` }`,
803
+ ` const data = record.data;`,
804
+ ` if (data && typeof data === 'object' && !Array.isArray(data)) {`,
805
+ ` const dataRecord = data as Record<string, unknown>;`,
806
+ ` if (part in dataRecord) return { found: true, value: dataRecord[part] };`,
807
+ ` const dataKey = __dlGetNormalizedKey(dataRecord, part);`,
808
+ ` if (dataKey) return { found: true, value: __dlReadOwnField(dataRecord, dataKey) };`,
809
+ ` }`,
810
+ ` return { found: false, value: undefined };`,
811
+ `}`,
812
+ ``,
813
+ `function __dlGetByPath(root: unknown, path: string): unknown {`,
814
+ ` let cursor = root;`,
815
+ ` const parts = __dlPathParts(path);`,
816
+ ` for (let index = 0; index < parts.length; index += 1) {`,
817
+ ` const part = parts[index] || '';`,
818
+ ` cursor = __dlParseJsonContainer(cursor);`,
819
+ ` if (!cursor || typeof cursor !== 'object') return undefined;`,
820
+ ` const record = cursor as Record<string, unknown>;`,
821
+ ` let field = { found: false, value: undefined as unknown };`,
822
+ ` for (let end = parts.length; end > index + 1; end -= 1) {`,
823
+ ` const dottedPart = parts.slice(index, end).join('.');`,
824
+ ` field = __dlGetRecordField(record, dottedPart);`,
825
+ ` if (field.found) {`,
826
+ ` index = end - 1;`,
827
+ ` break;`,
828
+ ` }`,
829
+ ` }`,
830
+ ` if (!field.found) field = __dlGetRecordField(record, part);`,
831
+ ` if (!field.found) return undefined;`,
832
+ ` cursor = field.value;`,
833
+ ` }`,
834
+ ` return cursor;`,
835
+ `}`,
836
+ ``,
837
+ `function __dlParseJsonContainer(value: unknown): unknown {`,
838
+ ` if (typeof value !== 'string') return value;`,
839
+ ` const trimmed = value.trim();`,
840
+ ` if ((!trimmed.startsWith('{') || !trimmed.endsWith('}')) && (!trimmed.startsWith('[') || !trimmed.endsWith(']'))) return value;`,
841
+ ` try {`,
842
+ ` return JSON.parse(trimmed);`,
843
+ ` } catch {`,
844
+ ` return value;`,
845
+ ` }`,
846
+ `}`,
847
+ ``,
848
+ `function __dlMeaningful(value: unknown): boolean {`,
849
+ ` if (value && typeof value === 'object' && !Array.isArray(value)) {`,
850
+ ` const record = value as Record<string, unknown>;`,
851
+ ` const status = typeof record.status === 'string' ? record.status.toLowerCase() : '';`,
852
+ ` if (status === 'error' || status === 'failed') return false;`,
853
+ ` if (typeof record.error === 'string' && record.error.trim()) return false;`,
854
+ ` const result = record.result;`,
855
+ ` if (result && typeof result === 'object' && !Array.isArray(result)) {`,
856
+ ` const resultRecord = result as Record<string, unknown>;`,
857
+ ` if (typeof resultRecord.error === 'string' && resultRecord.error.trim()) return false;`,
858
+ ` if (typeof resultRecord.message === 'string' && resultRecord.message.trim()) return false;`,
859
+ ` }`,
860
+ ` if ('matched_result' in record) return __dlMeaningful(record.matched_result);`,
861
+ ` }`,
862
+ ` return value !== null && value !== undefined && !(typeof value === 'string' && value.trim() === '') && !(Array.isArray(value) && value.length === 0);`,
863
+ `}`,
864
+ ``,
865
+ `function __dlErrorPayload(value: unknown): boolean {`,
866
+ ` if (!value || typeof value !== 'object' || Array.isArray(value)) return false;`,
867
+ ` const record = value as Record<string, unknown>;`,
868
+ ` const status = typeof record.status === 'string' ? record.status.toLowerCase() : '';`,
869
+ ` const result = record.result;`,
870
+ ` const resultError = result && typeof result === 'object' && !Array.isArray(result) ? (result as Record<string, unknown>).error : null;`,
871
+ ` return status === 'error' || status === 'failed' || (typeof record.error === 'string' && record.error.trim() !== '') || (typeof resultError === 'string' && resultError.trim() !== '');`,
872
+ `}`,
873
+ ``,
874
+ `function __dlAssertSuccessfulToolResult(value: unknown): void {`,
875
+ ` if (!__dlErrorPayload(value)) return;`,
876
+ ` const record = value as Record<string, unknown>;`,
877
+ ` const result = record.result && typeof record.result === 'object' && !Array.isArray(record.result) ? record.result as Record<string, unknown> : null;`,
878
+ ` const message = typeof record.error === 'string' ? record.error : typeof result?.error === 'string' ? result.error : typeof result?.message === 'string' ? result.message : 'Tool returned an error-shaped result.';`,
879
+ ` throw new Error(message);`,
880
+ `}`,
881
+ ``,
882
+ `function __dlGeneratedCellError(value: unknown): boolean {`,
883
+ ` if (typeof value === 'string') {`,
884
+ ` const lower = value.trim().toLowerCase();`,
885
+ ` if (!lower) return false;`,
886
+ ` if (/^column\\s+.+\\s+failed\\b/.test(lower)) return true;`,
887
+ ` if (lower.startsWith('error:') || lower.includes(': error:') || lower.includes('"error"')) return true;`,
888
+ ` try {`,
889
+ ` return __dlGeneratedCellError(JSON.parse(value));`,
890
+ ` } catch {`,
891
+ ` return false;`,
892
+ ` }`,
893
+ ` }`,
894
+ ` if (!__dlRecord(value)) return false;`,
895
+ ` const status = typeof value.status === 'string' ? value.status.toLowerCase() : '';`,
896
+ ` if (status === 'error' || status === 'failed') return true;`,
897
+ ` if (typeof value.error === 'string' && value.error.trim() !== '') return true;`,
898
+ ` const raw = __dlGetByPath(value, 'toolResponse.raw') ?? __dlGetByPath(value, 'toolOutput.raw');`,
899
+ ` if (raw !== undefined && raw !== value && __dlGeneratedCellError(raw)) return true;`,
900
+ ` const result = value.result;`,
901
+ ` return result !== undefined && result !== value && __dlGeneratedCellError(result);`,
902
+ `}`,
903
+ ``,
904
+ `function __dlStripErroredGeneratedColumns(row: Record<string, unknown>, aliases: string[]): Record<string, unknown> {`,
905
+ ` let next: Record<string, unknown> | null = null;`,
906
+ ` for (const alias of aliases) {`,
907
+ ` for (const key of __dlAliasCandidates(alias)) {`,
908
+ ` if (key in row && __dlGeneratedCellError(row[key])) {`,
909
+ ` if (next === null) next = { ...row };`,
910
+ ` delete next[key];`,
911
+ ` }`,
912
+ ` }`,
913
+ ` }`,
914
+ ` return next ?? row;`,
915
+ `}`,
916
+ ``,
917
+ `function __dlTemplateContext(row: Record<string, unknown>): Record<string, unknown> {`,
918
+ ` const context: Record<string, unknown> = {};`,
919
+ ` const projectedValues = row.__deeplineCsvProjectedValues;`,
920
+ ` if (__dlRecord(projectedValues)) {`,
921
+ ` for (const [key, value] of Object.entries(projectedValues)) context[key] = value;`,
922
+ ` }`,
923
+ ` for (const [key, value] of Object.entries(row)) {`,
924
+ ` if (key.startsWith('__deepline')) continue;`,
925
+ ` context[key] = value;`,
926
+ ` }`,
927
+ ` return context;`,
928
+ `}`,
929
+ ``,
930
+ `function __dlPrepareEnrichRow(row: Record<string, unknown>, aliases: string[], sourceRowIndex?: number): Record<string, unknown> {`,
931
+ ` const cleaned = __dlStripErroredGeneratedColumns(row, aliases);`,
932
+ ` const templateContext = __dlTemplateContext(cleaned);`,
933
+ ` return {`,
934
+ ` ...templateContext,`,
935
+ ` ...cleaned,`,
936
+ ` ...(typeof sourceRowIndex === 'number' && '__deeplineSourceRowIndex' in cleaned ? { __deeplineOriginalSourceRowIndex: cleaned.__deeplineSourceRowIndex } : {}),`,
937
+ ` ...(typeof sourceRowIndex === 'number' ? { __deeplineSourceRowIndex: sourceRowIndex } : {}),`,
938
+ ` __deeplineCsvProjectedFields: Object.keys(templateContext),`,
939
+ ` __deeplineCsvProjectedValues: templateContext,`,
940
+ ` };`,
941
+ `}`,
942
+ ``,
943
+ `function __dlRawToolOutput(result: unknown): unknown {`,
944
+ ` if (!result || typeof result !== 'object') return result;`,
945
+ ` const record = result as Record<string, unknown>;`,
946
+ ` return __dlGetByPath(record, 'toolOutput.raw') ?? __dlGetByPath(record, 'toolResponse.raw') ?? record.result ?? record.output ?? result;`,
947
+ `}`,
948
+ ``,
949
+ `function __dlPushCandidate(candidates: unknown[], value: unknown): void {`,
950
+ ` if (value === null || value === undefined) return;`,
951
+ ` if (!candidates.includes(value)) candidates.push(value);`,
952
+ `}`,
953
+ ``,
954
+ `function __dlRawToolCandidates(raw: unknown): unknown[] {`,
955
+ ` const candidates: unknown[] = [raw];`,
956
+ ` if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return candidates;`,
957
+ ` const record = raw as Record<string, unknown>;`,
958
+ ` __dlPushCandidate(candidates, record.data);`,
959
+ ` __dlPushCandidate(candidates, record.result);`,
960
+ ` __dlPushCandidate(candidates, record.output);`,
961
+ ` __dlPushCandidate(candidates, __dlGetByPath(record, 'data.data'));`,
962
+ ` __dlPushCandidate(candidates, __dlGetByPath(record, 'result.data'));`,
963
+ ` __dlPushCandidate(candidates, __dlGetByPath(record, 'result.data.data'));`,
964
+ ` __dlPushCandidate(candidates, __dlGetByPath(record, 'output.data'));`,
965
+ ` __dlPushCandidate(candidates, __dlGetByPath(record, 'output.data.data'));`,
966
+ ` __dlPushCandidate(candidates, __dlGetByPath(record, 'output.body'));`,
967
+ ` __dlPushCandidate(candidates, __dlGetByPath(record, 'output.body.data'));`,
968
+ ` __dlPushCandidate(candidates, __dlGetByPath(record, 'toolResponse.raw'));`,
969
+ ` __dlPushCandidate(candidates, __dlGetByPath(record, 'toolOutput.raw'));`,
970
+ ` return candidates;`,
971
+ `}`,
972
+ ``,
973
+ `function __dlLegacyResultData(value: unknown): unknown {`,
974
+ ` if (!value || typeof value !== 'object' || Array.isArray(value)) return value;`,
975
+ ` const record = value as Record<string, unknown>;`,
976
+ ` return 'data' in record ? record.data : value;`,
977
+ `}`,
978
+ ``,
979
+ `function __dlLegacyOutputData(result: unknown, raw: unknown): unknown {`,
980
+ ` const rawRecord = raw && typeof raw === 'object' && !Array.isArray(raw) ? (raw as Record<string, unknown>) : null;`,
981
+ ` const data = rawRecord && 'data' in rawRecord ? rawRecord.data : raw;`,
982
+ ` const existingResult = rawRecord && rawRecord.result && typeof rawRecord.result === 'object' && !Array.isArray(rawRecord.result) ? (rawRecord.result as Record<string, unknown>) : null;`,
983
+ ` const resultData = existingResult && 'data' in existingResult ? __dlLegacyResultData(existingResult.data) : __dlLegacyResultData(data);`,
984
+ ` const resultObject = resultData && typeof resultData === 'object' && !Array.isArray(resultData) ? (resultData as Record<string, unknown>) : {};`,
985
+ ` return {`,
986
+ ` ...(rawRecord ?? {}),`,
987
+ ` data,`,
988
+ ` result: { ...resultObject, ...(existingResult ?? {}), data: resultData },`,
989
+ ` raw,`,
990
+ ` toolResponse: { raw },`,
991
+ ` originalResult: result,`,
992
+ ` };`,
993
+ `}`,
994
+ ``,
995
+ `function __dlTemplate(value: unknown, row: Record<string, unknown>): unknown {`,
996
+ ` if (Array.isArray(value)) return value.map((entry) => __dlTemplate(entry, row));`,
997
+ ` if (value && typeof value === 'object') {`,
998
+ ` return Object.fromEntries(Object.entries(value as Record<string, unknown>).map(([key, entry]) => [key, __dlTemplate(entry, row)]));`,
999
+ ` }`,
1000
+ ` if (typeof value !== 'string') return value;`,
1001
+ ` const exact = value.match(/^\\{\\{\\s*([^{}]+?)\\s*\\}\\}$/);`,
1002
+ ` if (exact) return __dlGetByPath(row, exact[1] || '');`,
1003
+ ` let rendered = '';`,
1004
+ ` let cursor = 0;`,
1005
+ ` while (cursor < value.length) {`,
1006
+ ` const open = value.indexOf('{{', cursor);`,
1007
+ ` if (open < 0) {`,
1008
+ ` rendered += value.slice(cursor);`,
1009
+ ` break;`,
1010
+ ` }`,
1011
+ ` const close = value.indexOf('}}', open + 2);`,
1012
+ ` if (close < 0) {`,
1013
+ ` rendered += value.slice(cursor);`,
1014
+ ` break;`,
1015
+ ` }`,
1016
+ ` rendered += value.slice(cursor, open);`,
1017
+ ` const path = value.slice(open + 2, close).trim();`,
1018
+ ` const replacement = __dlGetByPath(row, path);`,
1019
+ ` rendered += replacement === null || replacement === undefined ? '' : String(replacement);`,
1020
+ ` cursor = close + 2;`,
1021
+ ` }`,
1022
+ ` return rendered;`,
1023
+ `}`,
1024
+ ``,
1025
+ `function __dlStableRowKey(row: Record<string, unknown>, index: number): string {`,
1026
+ ` for (const key of ['id', 'ID', 'row_key', 'ROW_KEY', 'email', 'Email', 'linkedin_url', 'LINKEDIN_URL', 'domain', 'DOMAIN', 'name', 'Name']) {`,
1027
+ ` const value = row[key];`,
1028
+ ` if (__dlMeaningful(value)) return String(value);`,
1029
+ ` }`,
1030
+ ` return String(index);`,
1031
+ `}`,
1032
+ ``,
1033
+ `function __dlEnrichRowKey(row: Record<string, unknown>, index: number): string {`,
1034
+ " return `${__dlStableRowKey(row, index)}:${index}`;",
1035
+ `}`,
1036
+ ``,
1037
+ `function __dlScalarValue(value: unknown): unknown {`,
1038
+ ` if (value && typeof value === 'object' && !Array.isArray(value)) {`,
1039
+ ` const record = value as Record<string, unknown>;`,
1040
+ ` if ('matched_result' in record) return __dlScalarValue(record.matched_result);`,
1041
+ ` for (const key of ['value', 'email', 'output', 'result', 'data']) {`,
1042
+ ` const nested = record[key];`,
1043
+ ` if (__dlMeaningful(nested)) return __dlScalarValue(nested);`,
1044
+ ` }`,
1045
+ ` }`,
1046
+ ` return value;`,
1047
+ `}`,
1048
+ ``,
1049
+ `function __dlFirstMeaningful(row: Record<string, unknown>, aliases: string[]): unknown {`,
1050
+ ` for (const alias of aliases) {`,
1051
+ ` const value = row[alias];`,
1052
+ ` if (__dlMeaningful(value)) return __dlScalarValue(value);`,
1053
+ ` }`,
1054
+ ` return null;`,
1055
+ `}`,
1056
+ ``,
1057
+ `function __dlFirstMeaningfulAlias(row: Record<string, unknown>, aliases: string[]): string | null {`,
1058
+ ` for (const alias of aliases) {`,
1059
+ ` if (__dlMeaningful(row[alias])) return alias;`,
1060
+ ` }`,
1061
+ ` return null;`,
1062
+ `}`,
1063
+ ``,
1064
+ `function __dlListValue(value: unknown): unknown[] {`,
1065
+ ` if (Array.isArray(value)) return value.filter(__dlMeaningful);`,
1066
+ ` if (value && typeof value === 'object') {`,
1067
+ ` const record = value as Record<string, unknown>;`,
1068
+ ` if ('matched_result' in record) return __dlListValue(record.matched_result);`,
1069
+ ` for (const key of ['result', 'value', 'data']) {`,
1070
+ ` const nested = record[key];`,
1071
+ ` const nestedList = __dlListValue(nested);`,
1072
+ ` if (nestedList.length > 0) return nestedList;`,
1073
+ ` }`,
1074
+ ` return __dlMeaningful(value) ? [value] : [];`,
1075
+ ` }`,
1076
+ ` return __dlMeaningful(value) ? [value] : [];`,
1077
+ `}`,
1078
+ ``,
1079
+ `function __dlFirstMinResults(row: Record<string, unknown>, aliases: string[], minResults: number): unknown {`,
1080
+ ` const values: unknown[] = [];`,
1081
+ ` for (const alias of aliases) {`,
1082
+ ` values.push(...__dlListValue(row[alias]));`,
1083
+ ` if (values.length >= minResults) return values;`,
1084
+ ` }`,
1085
+ ` return values.length > 0 ? values : null;`,
1086
+ `}`,
1087
+ ``,
1088
+ `function __dlContributingAliases(row: Record<string, unknown>, aliases: string[]): string[] | null {`,
1089
+ ` const sources: string[] = [];`,
1090
+ ` for (const alias of aliases) {`,
1091
+ ` if (__dlListValue(row[alias]).length > 0) sources.push(alias);`,
1092
+ ` }`,
1093
+ ` return sources.length > 0 ? sources : null;`,
1094
+ `}`,
1095
+ ``,
1096
+ `function __dlWaterfallSatisfied(row: Record<string, unknown>, aliases: string[], minResults: number): boolean {`,
1097
+ ` let count = 0;`,
1098
+ ` for (const alias of aliases) {`,
1099
+ ` count += __dlListValue(row[alias]).length;`,
1100
+ ` if (count >= __dlAtLeastOneInteger(minResults)) return true;`,
1101
+ ` }`,
1102
+ ` return false;`,
1103
+ `}`,
1104
+ ``,
1105
+ `function __dlKeyPaths(key: string): string[] {`,
1106
+ ` const normalized = String(key || '').trim();`,
1107
+ ` if (normalized === 'email') return ['email', 'email_address', 'person.email.email', 'data.person.email.email', 'result.person.email.email', 'result.data.person.email.email', 'person.email', 'contact.email', 'data.email', 'result.data.email'];`,
1108
+ ` if (normalized === 'personal_email') return ['personal_email', 'email', 'email_address', 'data.personal_email', 'data.email'];`,
1109
+ ` if (normalized === 'phone') return ['phone', 'phone_number', 'mobile_phone', 'mobile_phone_number', 'data.phone'];`,
1110
+ ` if (normalized === 'linkedin') return ['linkedin', 'linkedin_url', 'linkedin_profile', 'profile_url', 'person.linkedin', 'person.linkedin_url'];`,
1111
+ ` if (normalized === 'full_name') return ['full_name', 'name', 'person.full_name', 'person.name'];`,
1112
+ ` if (normalized === 'first_name') return ['first_name', 'person.first_name'];`,
1113
+ ` if (normalized === 'last_name') return ['last_name', 'person.last_name'];`,
1114
+ ` if (normalized === 'title') return ['title', 'job_title', 'current_title', 'headline', 'person.title'];`,
1115
+ ` if (normalized === 'company_name') return ['company_name', 'company.name', 'organization.name'];`,
1116
+ ` if (normalized === 'company_domain') return ['company_domain', 'domain', 'company.domain', 'organization.domain'];`,
1117
+ ` if (normalized === 'status') return ['status', 'verdict', 'state'];`,
1118
+ ` if (normalized === 'email_status') return ['email_status', 'status', 'verdict', 'data.email_status'];`,
1119
+ ` return [normalized];`,
1120
+ `}`,
1121
+ ``,
1122
+ `function __dlSelectorKeys(selector: unknown): string[] | null {`,
1123
+ ` if (!selector || typeof selector !== 'object' || Array.isArray(selector)) return null;`,
1124
+ ` const keys = (selector as { keys?: unknown }).keys;`,
1125
+ ` if (!Array.isArray(keys) || keys.length === 0) return null;`,
1126
+ ` const out: string[] = [];`,
1127
+ ` for (const key of keys) {`,
1128
+ ` if (typeof key === 'string' && key.trim()) out.push(key.trim());`,
1129
+ ` }`,
1130
+ ` return out.length > 0 ? out : null;`,
1131
+ `}`,
1132
+ ``,
1133
+ `function __dlFirstByPaths(payload: unknown, paths: string[] | string): unknown {`,
1134
+ ` const candidates = Array.isArray(paths) ? paths : [paths];`,
1135
+ ` for (const path of candidates) {`,
1136
+ ` for (const candidate of __dlRawToolCandidates(payload)) {`,
1137
+ ` const value = __dlGetByPath(candidate, String(path));`,
1138
+ ` if (__dlMeaningful(value)) return value;`,
1139
+ ` }`,
1140
+ ` }`,
1141
+ ` return null;`,
1142
+ `}`,
1143
+ ``,
1144
+ `function __dlExtractTarget(payload: unknown, key: string): unknown {`,
1145
+ ` return __dlFirstByPaths(payload, __dlKeyPaths(key));`,
1146
+ `}`,
1147
+ ``,
1148
+ `function __dlExtractedValue(result: unknown, key: string): unknown {`,
1149
+ ` if (!result || typeof result !== 'object' || Array.isArray(result)) return undefined;`,
1150
+ ` const extractedValues = (result as Record<string, unknown>).extractedValues;`,
1151
+ ` if (!extractedValues || typeof extractedValues !== 'object' || Array.isArray(extractedValues)) return undefined;`,
1152
+ ` const accessor = (extractedValues as Record<string, unknown>)[key];`,
1153
+ ` if (!accessor || typeof accessor !== 'object' || Array.isArray(accessor)) return undefined;`,
1154
+ ` const record = accessor as Record<string, unknown>;`,
1155
+ ` const get = record.get;`,
1156
+ ` if (typeof get === 'function') {`,
1157
+ ` try {`,
1158
+ ` return (get as () => unknown)();`,
1159
+ ` } catch {`,
1160
+ ` return undefined;`,
1161
+ ` }`,
1162
+ ` }`,
1163
+ ` return record.value;`,
1164
+ `}`,
1165
+ ``,
1166
+ `function __dlLegacyExtractorPayload(payload: unknown, raw: unknown): unknown {`,
1167
+ ` if (payload === undefined || payload === null) return raw;`,
1168
+ ` if (payload && typeof payload === 'object' && !Array.isArray(payload) && Object.keys(payload as Record<string, unknown>).length === 0) return raw;`,
1169
+ ` return payload;`,
1170
+ `}`,
1171
+ ``,
1172
+ `function __dlLegacyMatchedEnvelope(value: unknown, raw: unknown): unknown {`,
1173
+ ` if (value && typeof value === 'object' && !Array.isArray(value) && 'matched_result' in (value as Record<string, unknown>)) return value;`,
1174
+ ` const legacyOutput = __dlLegacyOutputData(undefined, raw) as Record<string, unknown>;`,
1175
+ ` const legacyResult = legacyOutput.result && typeof legacyOutput.result === 'object' && !Array.isArray(legacyOutput.result) ? legacyOutput.result : raw;`,
1176
+ ` return { matched_result: value, result: legacyResult };`,
1177
+ `}`,
1178
+ ``,
1179
+ `function __dlString(value: unknown): string | null {`,
1180
+ ` return typeof value === 'string' && value.trim() ? value.trim() : null;`,
1181
+ `}`,
1182
+ ``,
1183
+ `// NOTE: email_status is NOT normalized here. It is materialized once by the`,
1184
+ `// provider's emailStatus({...}) contract via buildEmailStatus and read back`,
1185
+ `// through __dlExtractedValue(result, 'email_status') below. There is no`,
1186
+ `// legacy string coarsening \u2014 see CONTEXT.md "Provider Email Status Contract".`,
1187
+ ``,
1188
+ `function __dlListPathCandidates(selector: unknown): string[] {`,
1189
+ ` const paths: string[] = [];`,
1190
+ ` const push = (path: string) => { if (path && !paths.includes(path)) paths.push(path); };`,
1191
+ ` if (Array.isArray(selector)) {`,
1192
+ ` for (const path of selector) push(String(path));`,
1193
+ ` } else if (typeof selector === 'string') {`,
1194
+ ` push(selector);`,
1195
+ ` }`,
1196
+ ` for (const path of ['data', 'data.people', 'data.persons', 'data.contacts', 'data.results', 'data.leads', 'data.items', 'result.data', 'result.people', 'result.persons', 'result.contacts', 'result.results', 'result.leads', 'result.items', 'people', 'persons', 'contacts', 'results', 'leads', 'items', 'output.body', 'body']) push(path);`,
1197
+ ` return paths;`,
1198
+ `}`,
1199
+ ``,
1200
+ `function __dlFindList(payload: unknown, selector: unknown): unknown[] {`,
1201
+ ` if (Array.isArray(payload)) return payload;`,
1202
+ ` for (const path of __dlListPathCandidates(selector)) {`,
1203
+ ` for (const candidate of __dlRawToolCandidates(payload)) {`,
1204
+ ` const value = __dlGetByPath(candidate, path);`,
1205
+ ` if (Array.isArray(value)) return value;`,
1206
+ ` }`,
1207
+ ` }`,
1208
+ ` const queue = __dlRawToolCandidates(payload);`,
1209
+ ` const seen: unknown[] = [];`,
1210
+ ` for (let index = 0; index < queue.length; index += 1) {`,
1211
+ ` const current = queue[index];`,
1212
+ ` if (!current || typeof current !== 'object' || seen.includes(current)) continue;`,
1213
+ ` seen.push(current);`,
1214
+ ` for (const value of Object.values(current as Record<string, unknown>)) {`,
1215
+ ` if (Array.isArray(value)) return value;`,
1216
+ ` if (value && typeof value === 'object') queue.push(value);`,
1217
+ ` }`,
1218
+ ` }`,
1219
+ ` return [];`,
1220
+ `}`,
1221
+ ``,
1222
+ `function __dlDeriveFullName(row: Record<string, unknown>): string | null {`,
1223
+ ` const existing = __dlFirstByPaths(row, ['full_name', 'name']);`,
1224
+ ` if (typeof existing === 'string' && existing.trim()) return existing.trim();`,
1225
+ ` const first = __dlFirstByPaths(row, ['first_name', 'firstName']);`,
1226
+ ` const last = __dlFirstByPaths(row, ['last_name', 'lastName']);`,
1227
+ ` const parts = [first, last].filter((part): part is string => typeof part === 'string').map((part) => part.trim()).filter(Boolean);`,
1228
+ ` return parts.length > 0 ? parts.join(' ') : null;`,
1229
+ `}`,
1230
+ ``,
1231
+ `function __dlProjectListRows(rows: unknown[], keys: string[], payload: unknown): Array<Record<string, unknown>> {`,
1232
+ ` const projected: Array<Record<string, unknown>> = [];`,
1233
+ ` for (const row of rows) {`,
1234
+ ` const record = row && typeof row === 'object' && !Array.isArray(row) ? (row as Record<string, unknown>) : { value: row };`,
1235
+ ` const out: Record<string, unknown> = {};`,
1236
+ ` for (const key of keys) {`,
1237
+ ` let value = __dlExtractTarget(record, key);`,
1238
+ ` if (!__dlMeaningful(value) && key === 'full_name') value = __dlDeriveFullName(record);`,
1239
+ ` if (!__dlMeaningful(value)) value = __dlExtractTarget(payload, key);`,
1240
+ ` out[key] = value === undefined ? null : value;`,
1241
+ ` }`,
1242
+ ` if (Object.values(out).some(__dlMeaningful)) projected.push(out);`,
1243
+ ` }`,
1244
+ ` return projected;`,
1245
+ `}`,
1246
+ ``,
1247
+ `type __DlExtractorHelpers = { row: Record<string, unknown>; result: unknown; data: unknown; raw: unknown; pick: (paths: string[] | string) => unknown; extract: (...args: unknown[]) => unknown; extractList: (...args: unknown[]) => unknown[]; target: (paths: string[] | string) => unknown; get: (path: string) => unknown };`,
1248
+ ``,
1249
+ `function __dlInlineExtractorArgs(args: unknown[]): { payload: unknown; selector: unknown } {`,
1250
+ ` if (args.length >= 3) return { payload: args[1], selector: args[2] };`,
1251
+ ` if (args.length >= 2) return { payload: args[0], selector: args[1] };`,
1252
+ ` return { payload: args[0], selector: undefined };`,
1253
+ `}`,
1254
+ ``,
1255
+ `function __dlInlineExtract(...args: unknown[]): unknown {`,
1256
+ ` const { payload, selector } = __dlInlineExtractorArgs(args);`,
1257
+ ` if (selector === undefined) return payload;`,
1258
+ ` const keys = __dlSelectorKeys(selector);`,
1259
+ ` if (keys) return Object.fromEntries(keys.map((key) => [key, __dlExtractTarget(payload, key) ?? null]));`,
1260
+ ` if (Array.isArray(selector)) return __dlFirstByPaths(payload, selector.map(String));`,
1261
+ ` if (typeof selector === 'string') return __dlExtractTarget(payload, selector) ?? __dlFirstByPaths(payload, selector);`,
1262
+ ` return selector;`,
1263
+ `}`,
1264
+ ``,
1265
+ `function __dlInlineExtractList(...args: unknown[]): unknown[] {`,
1266
+ ` const { payload, selector } = __dlInlineExtractorArgs(args);`,
1267
+ ` const rows = __dlFindList(payload, selector);`,
1268
+ ` const keys = __dlSelectorKeys(selector);`,
1269
+ ` return keys ? __dlProjectListRows(rows, keys, payload) : rows;`,
1270
+ `}`,
1271
+ ``,
1272
+ `function __dlExtract(alias: string, result: unknown, row: Record<string, unknown>, extractor: ((args: __DlExtractorHelpers) => unknown) | null, legacyEnvelope = false): unknown {`,
1273
+ ` const raw = __dlRawToolOutput(result);`,
1274
+ ` if (!extractor) return raw;`,
1275
+ ` const pick = (paths: string[] | string) => {`,
1276
+ ` const requestedPaths = Array.isArray(paths) ? paths : [paths];`,
1277
+ ` for (const requestedPath of requestedPaths) {`,
1278
+ ` for (const path of __dlKeyPaths(String(requestedPath))) {`,
1279
+ ` const extractedValue = __dlExtractedValue(result, path);`,
1280
+ ` if (__dlMeaningful(extractedValue)) return extractedValue;`,
1281
+ ` for (const candidate of __dlRawToolCandidates(raw)) {`,
1282
+ ` const value = __dlGetByPath(candidate, path);`,
1283
+ ` if (__dlMeaningful(value)) return value;`,
1284
+ ` }`,
1285
+ ` }`,
1286
+ ` }`,
1287
+ ` return null;`,
1288
+ ` };`,
1289
+ ` const extract = (...args: unknown[]): unknown => {`,
1290
+ ` const payload = args.length >= 3 ? __dlLegacyExtractorPayload(args[1], raw) : raw;`,
1291
+ ` const selector = args.length >= 3 ? args[2] : args[0];`,
1292
+ ` if (selector === undefined) return payload;`,
1293
+ ` const keys = __dlSelectorKeys(selector);`,
1294
+ ` if (keys) return Object.fromEntries(keys.map((key) => [key, __dlExtractTarget(payload, key) ?? null]));`,
1295
+ ` if (Array.isArray(selector)) return __dlFirstByPaths(payload, selector.map(String));`,
1296
+ ` if (typeof selector === 'string') {`,
1297
+ ` const extractedValue = __dlExtractedValue(result, selector);`,
1298
+ ` if (__dlMeaningful(extractedValue)) return __dlLegacyMatchedEnvelope(extractedValue, payload);`,
1299
+ ` return __dlExtractTarget(payload, selector) ?? __dlFirstByPaths(payload, selector);`,
1300
+ ` }`,
1301
+ ` return selector;`,
1302
+ ` };`,
1303
+ ` const extractList = (...args: unknown[]): unknown[] => {`,
1304
+ ` const payload = args.length >= 3 ? __dlLegacyExtractorPayload(args[1], raw) : raw;`,
1305
+ ` const selector = args.length >= 3 ? args[2] : args[0];`,
1306
+ ` const rows = __dlFindList(payload, selector);`,
1307
+ ` const keys = __dlSelectorKeys(selector);`,
1308
+ ` return keys ? __dlProjectListRows(rows, keys, payload) : rows;`,
1309
+ ` };`,
1310
+ ` const get = (path: string): unknown => __dlExtractedValue(result, path) ?? __dlFirstByPaths(raw, path);`,
1311
+ ` let resolved: unknown;`,
1312
+ ` const extracted = extractor({ row, result, data: raw, raw, pick, extract, extractList, target: pick, get });`,
1313
+ ` resolved = typeof extracted === 'function' ? (extracted as (outputData: unknown) => unknown)(__dlLegacyOutputData(result, raw)) : extracted;`,
1314
+ ` if (resolved && typeof resolved === 'object' && !Array.isArray(resolved) && alias in (resolved as Record<string, unknown>)) {`,
1315
+ ` const aliasValue = (resolved as Record<string, unknown>)[alias];`,
1316
+ ` return legacyEnvelope && __dlMeaningful(aliasValue) ? __dlLegacyMatchedEnvelope(aliasValue, raw) : aliasValue;`,
1317
+ ` }`,
1318
+ ` if (Array.isArray(resolved)) return __dlLegacyMatchedEnvelope(resolved, raw);`,
1319
+ ` if ((resolved === null || resolved === undefined) && __dlErrorPayload(raw)) return raw;`,
1320
+ ` if (legacyEnvelope && __dlMeaningful(resolved)) return __dlLegacyMatchedEnvelope(resolved, raw);`,
1321
+ ` return resolved === undefined ? raw : resolved;`,
1322
+ `}`,
1323
+ ``,
1324
+ `function __dlMergeContextRecord(existing: unknown, defaults: Record<string, unknown>): Record<string, unknown> {`,
1325
+ ` if (!existing || typeof existing !== 'object' || Array.isArray(existing)) return { ...defaults };`,
1326
+ ` return { ...defaults, ...(existing as Record<string, unknown>) };`,
1327
+ `}`,
1328
+ ``,
1329
+ `function __dlCompactJavascriptContext(value: unknown, depth = 0): unknown {`,
1330
+ ` if (depth > 8) return '[Object]';`,
1331
+ ` if (typeof value === 'string') return value.length > 20000 ? value.slice(0, 20000) + '...[truncated]' : value;`,
1332
+ ` if (!value || typeof value !== 'object') return value;`,
1333
+ ` if (Array.isArray(value)) {`,
1334
+ ` const limit = depth <= 2 ? 25 : 10;`,
1335
+ ` const items = value.slice(0, limit).map((entry) => __dlCompactJavascriptContext(entry, depth + 1));`,
1336
+ ` if (value.length > limit) items.push({ __deepline_truncated_items: value.length - limit });`,
1337
+ ` return items;`,
1338
+ ` }`,
1339
+ ` const out: Record<string, unknown> = {};`,
1340
+ ` let count = 0;`,
1341
+ ` for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {`,
1342
+ ` count += 1;`,
1343
+ ` if (count > 80) {`,
1344
+ ` out.__deepline_truncated_fields = count - 80;`,
1345
+ ` break;`,
1346
+ ` }`,
1347
+ ` out[key] = __dlCompactJavascriptContext(entry, depth + 1);`,
1348
+ ` }`,
1349
+ ` return out;`,
1350
+ `}`,
1351
+ ``,
1352
+ `function __dlRuntimePayload(tool: string, payload: Record<string, unknown>, row: Record<string, unknown>): Record<string, unknown> {`,
1353
+ ` if (tool !== 'run_javascript') return payload;`,
1354
+ ` const compactRow = __dlCompactJavascriptContext(row) as Record<string, unknown>;`,
1355
+ ` return {`,
1356
+ ` ...payload,`,
1357
+ ` row: __dlMergeContextRecord(payload.row, compactRow),`,
1358
+ ` input: __dlMergeContextRecord(payload.input, compactRow),`,
1359
+ ` context: __dlMergeContextRecord(payload.context, compactRow),`,
1360
+ ` };`,
1361
+ `}`,
1362
+ ``,
1363
+ `function __dlBlankPayloadValue(value: unknown): boolean {`,
1364
+ ` return value === null || value === undefined || (typeof value === 'string' && value.trim() === '');`,
1365
+ `}`,
1366
+ ``,
1367
+ `function __dlShouldSkipEmptyPayload(tool: string, payload: Record<string, unknown>): boolean {`,
1368
+ ` if (tool === 'leadmagic_email_validation') return __dlBlankPayloadValue(payload.email);`,
1369
+ ` return false;`,
1370
+ `}`,
1371
+ ``,
1372
+ `function __dlPayloadHasMeaningfulValue(value: unknown): boolean {`,
1373
+ ` if (__dlBlankPayloadValue(value)) return false;`,
1374
+ ` if (Array.isArray(value)) return value.some(__dlPayloadHasMeaningfulValue);`,
1375
+ ` if (value && typeof value === 'object') return Object.values(value as Record<string, unknown>).some(__dlPayloadHasMeaningfulValue);`,
1376
+ ` return true;`,
1377
+ `}`,
1378
+ ``,
1379
+ `function __dlShouldSkipBlankPlayPayload(payload: Record<string, unknown>): boolean {`,
1380
+ ` return Object.keys(payload).length > 0 && !__dlPayloadHasMeaningfulValue(payload);`,
1381
+ `}`,
1382
+ ``,
1383
+ `function __dlAliasCandidates(alias: string): string[] {`,
1384
+ ` const aliases: string[] = [];`,
1385
+ ` for (const candidate of [alias, alias.replace(/-/g, '_'), alias.replace(/_/g, '-')]) {`,
1386
+ ` if (candidate && !aliases.includes(candidate)) aliases.push(candidate);`,
1387
+ ` }`,
1388
+ ` return aliases;`,
1389
+ `}`,
1390
+ ``,
1391
+ `function __dlPlayResultValue(alias: string, result: unknown): unknown {`,
1392
+ ` if (!result || typeof result !== 'object' || Array.isArray(result)) return result;`,
1393
+ ` const record = result as Record<string, unknown>;`,
1394
+ ` const aliases = __dlAliasCandidates(alias);`,
1395
+ ` for (const key of aliases) {`,
1396
+ ` if (key in record && __dlMeaningful(record[key])) return __dlScalarValue(record[key]);`,
1397
+ ` }`,
1398
+ ` const values = Object.values(record).filter(__dlMeaningful);`,
1399
+ ` if (values.length === 1) return __dlScalarValue(values[0]);`,
1400
+ ` return result;`,
1401
+ `}`,
1402
+ ``,
1403
+ `async function __dlRunCommand(input: { alias: string; callId: string; tool: string; payload: Record<string, unknown>; extract: ((args: __DlExtractorHelpers) => unknown) | null; runIf: ((row: Record<string, unknown>) => unknown) | null; row: Record<string, unknown>; stepCtx: DeeplinePlayRuntimeContext; description?: string; force?: boolean; legacyEnvelope?: boolean }): Promise<unknown> {`,
1404
+ ` if (input.runIf) {`,
1405
+ ` const shouldRun = input.runIf(input.row);`,
1406
+ ` if (!shouldRun) return null;`,
1407
+ ` }`,
1408
+ ` const payload = __dlRuntimePayload(input.tool, __dlTemplate(input.payload, input.row) as Record<string, unknown>, input.row);`,
1409
+ ` if (__dlShouldSkipEmptyPayload(input.tool, payload)) return null;`,
1410
+ ` const result = await input.stepCtx.tools.execute({`,
1411
+ ` id: input.callId,`,
1412
+ ` tool: input.tool,`,
1413
+ ` input: payload,`,
1414
+ ` ...(input.description ? { description: input.description } : {}),`,
1415
+ ` ...(input.force ? { force: true } : {}),`,
1416
+ ` });`,
1417
+ ` __dlAssertSuccessfulToolResult(result);`,
1418
+ ` return __dlExtract(input.alias, result, input.row, input.extract, Boolean(input.legacyEnvelope));`,
1419
+ `}`
1420
+ ].join("\n");
1421
+ }
1422
+
1423
+ // src/cli/workflow-to-play.ts
1424
+ var HITL_WAIT_FOR_SIGNAL_TOOL = "deepline_workflow_wait_for_signal";
1425
+ var HITL_SLACK_TOOL = "slack_message_with_hitl";
1426
+ var SUB_WORKFLOW_TOOL_PREFIX = "deepline_workflow_";
1427
+ var UNSUPPORTED_REASON_HINT = {
1428
+ unsafe_user_code: "a step's JavaScript (extract_js / run_if_js / run_javascript) uses non-deterministic or sandbox-escaping code (e.g. new Date(), Date.now(), Math.random(), fetch, require). Plays replay deterministically inside a sandbox, so the compiler rejects it \u2014 rewrite it to compute from the row/result before migrating.",
1429
+ hitl: "human-in-the-loop / wait-for-signal steps have no play-runtime equivalent yet.",
1430
+ sub_workflow: "sub-workflow calls have no play-runtime equivalent yet (a future ctx.runPlay bridge).",
1431
+ nested_waterfall: "nested with_waterfall blocks are not supported by the play compiler.",
1432
+ inline_secret: 'a step inlines a hardcoded secret (API key / token / private key). Plays forbid inline secrets \u2014 move it to a dashboard secret and read it with ctx.secrets.get("NAME") before migrating.'
1433
+ };
1434
+ var UnsupportedWorkflowCommandError = (_class = class extends Error {
1435
+ __init() {this.status = 400}
1436
+
1437
+ constructor(unsupported) {
1438
+ super(
1439
+ `Workflow uses ${unsupported.length} command${unsupported.length === 1 ? "" : "s"} that cannot run as a play yet: ${unsupported.map((entry) => `${entry.alias} (${entry.reason})`).join(", ")}.`
1440
+ );_class.prototype.__init.call(this);;
1441
+ this.name = "UnsupportedWorkflowCommandError";
1442
+ this.unsupported = unsupported;
1443
+ }
1444
+ }, _class);
1445
+ function isWaterfall2(command) {
1446
+ return "with_waterfall" in command;
1447
+ }
1448
+ function stepInlinedText(command) {
1449
+ return [
1450
+ JSON.stringify(_nullishCoalesce(command.payload, () => ( {}))),
1451
+ _nullishCoalesce(command.extract_js, () => ( "")),
1452
+ _nullishCoalesce(command.run_if_js, () => ( ""))
1453
+ ].join("\n");
1454
+ }
1455
+ function stepUserCode(command) {
1456
+ const code = [];
1457
+ if (command.extract_js) code.push(command.extract_js);
1458
+ if (command.run_if_js) code.push(command.run_if_js);
1459
+ if (command.tool === "run_javascript" && typeof _optionalChain([command, 'access', _25 => _25.payload, 'optionalAccess', _26 => _26.code]) === "string") {
1460
+ code.push(command.payload.code);
1461
+ }
1462
+ return code;
1463
+ }
1464
+ function hasUnsafeUserCode(command) {
1465
+ return stepUserCode(command).some((code) => {
1466
+ try {
1467
+ assertUserCodeIsSafe(code, "play step code");
1468
+ return false;
1469
+ } catch (e3) {
1470
+ return true;
1471
+ }
1472
+ });
1473
+ }
1474
+ function classifyUnsupportedCommand(command) {
1475
+ const { tool } = command;
1476
+ if (tool === HITL_SLACK_TOOL || tool === HITL_WAIT_FOR_SIGNAL_TOOL) {
1477
+ return "hitl";
1478
+ }
1479
+ if (tool.startsWith(SUB_WORKFLOW_TOOL_PREFIX)) return "sub_workflow";
1480
+ if (_chunk3KC45UVFjs.collectInlineSecretFindings.call(void 0, stepInlinedText(command)).length > 0) {
1481
+ return "inline_secret";
1482
+ }
1483
+ if (hasUnsafeUserCode(command)) return "unsafe_user_code";
1484
+ return null;
1485
+ }
1486
+ function collectStepOffenders(command, offenders) {
1487
+ if (command.disabled) return;
1488
+ const reason = classifyUnsupportedCommand(command);
1489
+ if (reason) {
1490
+ offenders.push({ alias: command.alias, tool: command.tool, reason });
1491
+ }
1492
+ }
1493
+ function findUnsupportedWorkflowCommands(config) {
1494
+ const offenders = [];
1495
+ for (const command of _nullishCoalesce(config.commands, () => ( []))) {
1496
+ if (!isWaterfall2(command)) {
1497
+ collectStepOffenders(command, offenders);
1498
+ continue;
1499
+ }
1500
+ for (const child of _nullishCoalesce(command.commands, () => ( []))) {
1501
+ if (isWaterfall2(child)) {
1502
+ offenders.push({
1503
+ alias: command.with_waterfall,
1504
+ tool: "with_waterfall",
1505
+ reason: "nested_waterfall"
1506
+ });
1507
+ continue;
1508
+ }
1509
+ collectStepOffenders(child, offenders);
1510
+ }
1511
+ }
1512
+ return offenders;
1513
+ }
1514
+ function validateWorkflowConfigForPlay(config) {
1515
+ const offenders = findUnsupportedWorkflowCommands(config);
1516
+ if (offenders.length > 0) {
1517
+ throw new UnsupportedWorkflowCommandError(offenders);
1518
+ }
1519
+ }
1520
+ function describeUnsupportedReason(reason) {
1521
+ return UNSUPPORTED_REASON_HINT[reason];
1522
+ }
1523
+ var MAX_PLAY_NAME_LENGTH = 39;
1524
+ function sanitizePlayNameSegment(value) {
1525
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
1526
+ }
1527
+ function deriveWorkflowPlayName(workflowName) {
1528
+ const base = sanitizePlayNameSegment(workflowName) || "workflow";
1529
+ const suffix = _crypto.createHash.call(void 0, "sha256").update(workflowName).digest("hex").slice(0, 8);
1530
+ const reserved = suffix.length + 1;
1531
+ const allowedBase = Math.max(1, MAX_PLAY_NAME_LENGTH - reserved);
1532
+ let name = `${base.slice(0, allowedBase)}_${suffix}`;
1533
+ if (name.startsWith("prebuilt")) {
1534
+ name = `wf_${name}`.slice(0, MAX_PLAY_NAME_LENGTH);
1535
+ }
1536
+ return name;
1537
+ }
1538
+ function compileWorkflowConfigToPlay(config, options) {
1539
+ validateWorkflowConfigForPlay(config);
1540
+ const playName = deriveWorkflowPlayName(options.workflowName);
1541
+ const sourceCode = compileEnrichConfigToPlaySource(config, {
1542
+ playName,
1543
+ inlineRunJavascript: true,
1544
+ idiomaticGetters: true
1545
+ });
1546
+ const warnings = [];
1547
+ if (typeof config.cost_cap_usd_per_run === "number") {
1548
+ warnings.push(
1549
+ `cost_cap_usd_per_run ($${config.cost_cap_usd_per_run}) was not carried into the play \u2014 credits are not USD. Set billing.maxCreditsPerRun manually after checking your credit conversion.`
1550
+ );
1551
+ }
1552
+ return { playName, sourceCode, warnings };
1553
+ }
1554
+
1555
+ // src/cli/commands/workflow.ts
1556
+ var PLAY_EQUIVALENT = {
1557
+ list: "deepline plays list",
1558
+ get: "deepline plays get <name>",
1559
+ call: "deepline plays run <name>",
1560
+ apply: "deepline plays publish <file>",
1561
+ lint: "deepline plays check <file>",
1562
+ schema: "deepline plays describe <name>",
1563
+ runs: "deepline runs list --play <name>",
1564
+ run: "deepline runs get <run-id>",
1565
+ tail: "deepline runs watch <run-id>",
1566
+ cancel: "deepline runs stop <run-id>",
1567
+ delete: "deepline plays delete <name>"
1568
+ };
1569
+ var MIGRATE_HINT = "deepline workflows transform <id>";
1570
+ var TRIGGER_REDIRECT = "Looking to trigger a play automatically? Use a trigger binding in definePlay \u2014 `cron`/`webhook`, or `sqlListeners` to run on a monitor\u2019s output (see `deepline monitors available <id>` for a monitor\u2019s streams and the deepline-monitors skill). `workflows` only manages prebuilt plays and is deprecated in favor of `plays`.";
1571
+ var JSON_OPTION_DESCRIPTION = "Emit JSON output. Also automatic when stdout is piped";
1572
+ function withJsonOption(command) {
1573
+ return command.option("--json", JSON_OPTION_DESCRIPTION);
1574
+ }
1575
+ var TERMINAL_RUN_STATUSES = /* @__PURE__ */ new Set([
1576
+ "completed",
1577
+ "succeeded",
1578
+ "success",
1579
+ "failed",
1580
+ "error",
1581
+ "errored",
1582
+ "cancelled",
1583
+ "canceled",
1584
+ "done"
1585
+ ]);
1586
+ function migrationDeprecation(command) {
1587
+ const use = PLAY_EQUIVALENT[command];
1588
+ if (!use) return null;
1589
+ return { use, migrate: MIGRATE_HINT };
1590
+ }
1591
+ function noticeToStderr(command) {
1592
+ const deprecation = migrationDeprecation(command);
1593
+ if (!deprecation) return;
1594
+ process.stderr.write(
1595
+ `note: \`deepline workflows ${command}\` is a legacy surface \u2014 workflows are becoming plays.
1596
+ equivalent: \`${deprecation.use}\`
1597
+ migrate this workflow: \`${MIGRATE_HINT}\`
1598
+ ${TRIGGER_REDIRECT}
1599
+ `
1600
+ );
1601
+ }
1602
+ function emitPassThrough(command, payload, options) {
1603
+ const json = _chunk7D6QG5KFjs.shouldEmitJson.call(void 0, options.json);
1604
+ const deprecation = migrationDeprecation(command);
1605
+ if (json) {
1606
+ const enriched = payload && typeof payload === "object" && !Array.isArray(payload) ? { ...payload, deprecation } : { result: payload, deprecation };
1607
+ _chunk7D6QG5KFjs.printJson.call(void 0, enriched);
1608
+ return;
1609
+ }
1610
+ _chunk7D6QG5KFjs.printJson.call(void 0, payload);
1611
+ noticeToStderr(command);
1612
+ }
1613
+ function client() {
1614
+ return new (0, _chunk2C3AVPTYjs.DeeplineClient)();
1615
+ }
1616
+ function clientWithTimeout(timeoutSeconds) {
1617
+ if (!timeoutSeconds) return client();
1618
+ const seconds = Number(timeoutSeconds);
1619
+ if (!Number.isFinite(seconds) || seconds <= 0) {
1620
+ throw new Error("--timeout must be a positive number of seconds.");
1621
+ }
1622
+ return new (0, _chunk2C3AVPTYjs.DeeplineClient)({ timeout: seconds * 1e3 });
1623
+ }
1624
+ function readStatus(payload) {
1625
+ if (!payload || typeof payload !== "object") return null;
1626
+ const record = payload;
1627
+ if (typeof record.status === "string") return record.status;
1628
+ const run = record.run;
1629
+ if (run && typeof run === "object") {
1630
+ const status = run.status;
1631
+ if (typeof status === "string") return status;
1632
+ }
1633
+ return null;
1634
+ }
1635
+ async function readJsonOption(payload, file) {
1636
+ if (file) {
1637
+ const raw = await _promises.readFile.call(void 0, _path.resolve.call(void 0, file), "utf8");
1638
+ return JSON.parse(raw);
1639
+ }
1640
+ if (payload) {
1641
+ return JSON.parse(payload);
1642
+ }
1643
+ throw new Error("Provide --payload <json> or --file <path>.");
1644
+ }
1645
+ async function transformOne(api, workflowId, outDir, publish) {
1646
+ const { workflow } = await api.getWorkflow(workflowId);
1647
+ if (!workflow) {
1648
+ return {
1649
+ ok: false,
1650
+ workflowId,
1651
+ workflowName: workflowId,
1652
+ reason: "Workflow not found."
1653
+ };
1654
+ }
1655
+ const revision = workflow.current_published_revision;
1656
+ if (!revision) {
1657
+ return {
1658
+ ok: false,
1659
+ workflowId,
1660
+ workflowName: workflow.name,
1661
+ reason: "Workflow has no published revision to transform."
1662
+ };
1663
+ }
1664
+ try {
1665
+ const compiled = compileWorkflowConfigToPlay(
1666
+ // The API returns the config as `unknown`; it is structurally the
1667
+ // EnrichCompiledConfig the compiler expects. Cast at this single boundary.
1668
+ revision.config,
1669
+ { workflowName: workflow.name, version: revision.version }
1670
+ );
1671
+ const file = _path.join.call(void 0, _path.resolve.call(void 0, outDir), `${compiled.playName}.play.ts`);
1672
+ await _promises.mkdir.call(void 0, _path.dirname.call(void 0, file), { recursive: true });
1673
+ await _promises.writeFile.call(void 0, file, compiled.sourceCode, "utf8");
1674
+ let published = false;
1675
+ if (publish) {
1676
+ const { handlePlayPublish } = await Promise.resolve().then(() => _interopRequireWildcard(require("./play-46ZJ4FMI.js")));
1677
+ const code = await handlePlayPublish([file]);
1678
+ if (code !== 0) {
1679
+ return {
1680
+ ok: false,
1681
+ workflowId,
1682
+ workflowName: workflow.name,
1683
+ reason: `Wrote ${file} but publish failed (exit ${code}).`
1684
+ };
1685
+ }
1686
+ published = true;
1687
+ }
1688
+ return {
1689
+ ok: true,
1690
+ workflowId,
1691
+ workflowName: workflow.name,
1692
+ playName: compiled.playName,
1693
+ file,
1694
+ warnings: compiled.warnings,
1695
+ published
1696
+ };
1697
+ } catch (error) {
1698
+ if (error instanceof UnsupportedWorkflowCommandError) {
1699
+ return {
1700
+ ok: false,
1701
+ workflowId,
1702
+ workflowName: workflow.name,
1703
+ reason: error.unsupported.map((u) => `${u.alias} (${describeUnsupportedReason(u.reason)})`).join("; "),
1704
+ unsupported: error.unsupported
1705
+ };
1706
+ }
1707
+ throw error;
1708
+ }
1709
+ }
1710
+ function renderTransformReport(outcomes) {
1711
+ const lines = [];
1712
+ for (const outcome of outcomes) {
1713
+ if (outcome.ok) {
1714
+ lines.push(
1715
+ `\u2705 ${outcome.workflowName} \u2192 ${outcome.file}` + (outcome.published ? " (published)" : ` (next: deepline plays publish ${outcome.file})`)
1716
+ );
1717
+ for (const warning of outcome.warnings) {
1718
+ lines.push(` \u26A0\uFE0F ${warning}`);
1719
+ }
1720
+ } else {
1721
+ lines.push(`\u26A0\uFE0F ${outcome.workflowName} \u2014 skipped: ${outcome.reason}`);
1722
+ }
1723
+ }
1724
+ const ok = outcomes.filter((o) => o.ok).length;
1725
+ const total = outcomes.length;
1726
+ const manual = total - ok;
1727
+ lines.push("");
1728
+ lines.push(
1729
+ `${ok}/${total} transformed` + (manual > 0 ? `, ${manual} need manual attention` : "")
1730
+ );
1731
+ return `${lines.join("\n")}
1732
+ `;
1733
+ }
1734
+ async function handleTransform(id, options) {
1735
+ const api = client();
1736
+ const outDir = _nullishCoalesce(options.out, () => ( "./plays"));
1737
+ const publish = options.publish === true;
1738
+ let ids;
1739
+ if (options.all) {
1740
+ const { workflows } = await api.listWorkflows();
1741
+ ids = workflows.map((w) => w.id);
1742
+ } else if (id) {
1743
+ ids = [id];
1744
+ } else {
1745
+ throw new Error("Provide a workflow <id> or --all.");
1746
+ }
1747
+ const outcomes = [];
1748
+ for (const workflowId of ids) {
1749
+ outcomes.push(await transformOne(api, workflowId, outDir, publish));
1750
+ }
1751
+ _chunk7D6QG5KFjs.printCommandEnvelope.call(void 0,
1752
+ { outcomes, deprecation: null },
1753
+ {
1754
+ json: _chunk7D6QG5KFjs.shouldEmitJson.call(void 0, options.json),
1755
+ text: renderTransformReport(outcomes)
1756
+ }
1757
+ );
1758
+ return outcomes.every((o) => o.ok) ? 0 : 1;
1759
+ }
1760
+ async function handleList(options) {
1761
+ const limit = options.limit ? Number(options.limit) : void 0;
1762
+ const result = await client().listWorkflows({
1763
+ limit: Number.isFinite(limit) ? limit : void 0
1764
+ });
1765
+ emitPassThrough("list", result, options);
1766
+ }
1767
+ async function handleGet(id, options) {
1768
+ emitPassThrough("get", await client().getWorkflow(id), options);
1769
+ }
1770
+ async function handleDelete(id, options) {
1771
+ emitPassThrough("delete", await client().deleteWorkflow(id), options);
1772
+ }
1773
+ async function handleDisable(id, options) {
1774
+ const result = await client().disableWorkflow(id);
1775
+ _chunk7D6QG5KFjs.printJson.call(void 0, result);
1776
+ }
1777
+ async function handleEnable(id, options) {
1778
+ const result = await client().enableWorkflow(id);
1779
+ _chunk7D6QG5KFjs.printJson.call(void 0, result);
1780
+ }
1781
+ async function handleApply(options) {
1782
+ const body = await readJsonOption(options.payload, options.file);
1783
+ emitPassThrough(
1784
+ "apply",
1785
+ await clientWithTimeout(options.timeout).applyWorkflow(body),
1786
+ options
1787
+ );
1788
+ }
1789
+ async function handleLint(options) {
1790
+ const body = await readJsonOption(options.payload, options.file);
1791
+ emitPassThrough("lint", await client().lintWorkflow(body), options);
1792
+ }
1793
+ async function handleSchema(options) {
1794
+ emitPassThrough(
1795
+ "schema",
1796
+ await client().getWorkflowSchema(options.subject),
1797
+ options
1798
+ );
1799
+ }
1800
+ async function handleCall(options) {
1801
+ const body = {};
1802
+ if (options.workflowId) body.workflow_id = options.workflowId;
1803
+ if (options.workflowName) body.workflow_name = options.workflowName;
1804
+ const input = options.payload ? JSON.parse(options.payload) : {};
1805
+ if (options.mode) input.__execution_mode = options.mode;
1806
+ body.input = input;
1807
+ emitPassThrough(
1808
+ "call",
1809
+ await clientWithTimeout(options.timeout).callWorkflow(body),
1810
+ options
1811
+ );
1812
+ }
1813
+ async function handleRuns(id, options) {
1814
+ const limit = options.limit ? Number(options.limit) : void 0;
1815
+ emitPassThrough(
1816
+ "runs",
1817
+ await client().listWorkflowRuns(id, {
1818
+ limit: Number.isFinite(limit) ? limit : void 0
1819
+ }),
1820
+ options
1821
+ );
1822
+ }
1823
+ async function handleRun(id, runId, options) {
1824
+ emitPassThrough("run", await client().getWorkflowRun(id, runId), options);
1825
+ }
1826
+ async function handleCancel(id, runId, options) {
1827
+ emitPassThrough(
1828
+ "cancel",
1829
+ await client().cancelWorkflowRun(id, runId),
1830
+ options
1831
+ );
1832
+ }
1833
+ async function handleTail(id, runId, options) {
1834
+ const api = client();
1835
+ const intervalMs = Math.max(500, Number(_nullishCoalesce(options.intervalMs, () => ( 2e3))) || 2e3);
1836
+ const deadline = Date.now() + 10 * 6e4;
1837
+ for (; ; ) {
1838
+ const run = await api.getWorkflowRun(id, runId);
1839
+ emitPassThrough("tail", run, options);
1840
+ const status = readStatus(run);
1841
+ if (status && TERMINAL_RUN_STATUSES.has(status) || Date.now() > deadline) {
1842
+ return;
1843
+ }
1844
+ await _chunk7D6QG5KFjs.sleep.call(void 0, intervalMs);
1845
+ }
1846
+ }
1847
+ function registerWorkflowCommands(program) {
1848
+ const workflows = program.command("workflows", { hidden: true }).description(
1849
+ "Legacy cloud workflows (now becoming plays). Commands still work; use `workflows transform` to migrate one to a play. " + TRIGGER_REDIRECT
1850
+ ).addHelpText(
1851
+ "after",
1852
+ `
1853
+ Workflows are a legacy surface. They still run in the cloud and these commands
1854
+ keep working, but new work belongs in plays. Migrate a workflow with:
1855
+
1856
+ deepline workflows transform <id> # write a reviewable .play.ts
1857
+ deepline workflows transform --all --publish # migrate + publish them all
1858
+
1859
+ Equivalents: list\u2192plays list \xB7 call\u2192plays run \xB7 apply\u2192plays publish \xB7
1860
+ lint\u2192plays check \xB7 runs\u2192runs list.
1861
+
1862
+ ${TRIGGER_REDIRECT}
1863
+ Add the binding as the third arg to definePlay in your .play.ts; the
1864
+ deepline-monitors skill has a monitor-triggered example.
1865
+ `
1866
+ );
1867
+ withJsonOption(
1868
+ workflows.command("transform [id]").description("Compile a workflow into a reviewable V2 play (.play.ts).").option("--all", "Transform every workflow in the workspace").option("--out <dir>", "Output directory for generated plays", "./plays").option("--publish", "Publish each clean play immediately")
1869
+ ).addHelpText(
1870
+ "after",
1871
+ `
1872
+ Examples:
1873
+ deepline workflows transform wf_123 --out ./plays
1874
+ deepline workflows transform --all
1875
+ deepline workflows transform --all --publish --json
1876
+
1877
+ Notes:
1878
+ HITL, run_javascript steps, and sub-workflow calls cannot run as a play yet;
1879
+ those workflows are reported as needing manual attention and skipped.
1880
+ `
1881
+ ).action(async (id, options) => {
1882
+ process.exitCode = await handleTransform(id, options);
1883
+ });
1884
+ withJsonOption(
1885
+ workflows.command("list").description("List workspace workflows.").option("--limit <n>", "Max workflows to return")
1886
+ ).action(handleList);
1887
+ withJsonOption(
1888
+ workflows.command("get <id>").description(
1889
+ "Fetch a workflow, including its published-revision config."
1890
+ )
1891
+ ).action(handleGet);
1892
+ withJsonOption(
1893
+ workflows.command("disable <id>").description("Turn a workflow off.")
1894
+ ).action(handleDisable);
1895
+ withJsonOption(
1896
+ workflows.command("enable <id>").description("Turn a workflow back on.")
1897
+ ).action(handleEnable);
1898
+ withJsonOption(
1899
+ workflows.command("delete <id>").description("Delete a workflow and its revisions/runs.")
1900
+ ).action(handleDelete);
1901
+ withJsonOption(
1902
+ workflows.command("apply").description("Create or update a workflow from config.").option("--payload <json>", "Inline config JSON").option("--file <path>", "Path to a config JSON file").option("--timeout <seconds>", "API read timeout in seconds.")
1903
+ ).action(handleApply);
1904
+ withJsonOption(
1905
+ workflows.command("lint").description("Validate a workflow config without saving.").option("--payload <json>", "Inline config JSON").option("--file <path>", "Path to a config JSON file")
1906
+ ).action(handleLint);
1907
+ withJsonOption(
1908
+ workflows.command("schema").description("Fetch live workflow request schemas.").option(
1909
+ "--subject <subject>",
1910
+ "Schema subject (apply|call|trigger|all|\u2026)"
1911
+ )
1912
+ ).action(handleSchema);
1913
+ withJsonOption(
1914
+ workflows.command("call").description("Queue a workflow run.").option("--workflow-id <id>", "Workflow id").option("--workflow-name <name>", "Workflow name").option("--payload <json>", "Run input JSON").option("--mode <mode>", "live | dry_run | smoke_test").option("--timeout <seconds>", "API read timeout in seconds.")
1915
+ ).action(handleCall);
1916
+ withJsonOption(
1917
+ workflows.command("runs <id>").description("List a workflow\u2019s runs.").option("--limit <n>", "Max runs to return")
1918
+ ).action(handleRuns);
1919
+ withJsonOption(
1920
+ workflows.command("run <id> <runId>").description("Fetch a single workflow run.")
1921
+ ).action(handleRun);
1922
+ withJsonOption(
1923
+ workflows.command("tail <id> <runId>").description("Poll a workflow run until it reaches a terminal status.").option("--interval-ms <n>", "Poll interval in ms (default 2000)")
1924
+ ).action(handleTail);
1925
+ withJsonOption(
1926
+ workflows.command("cancel <id> <runId>").description("Cancel a running workflow run.")
1927
+ ).action(handleCancel);
1928
+ }
1929
+
1930
+
1931
+
1932
+
1933
+
1934
+
1935
+
1936
+ exports.emitPassThrough = emitPassThrough; exports.migrationDeprecation = migrationDeprecation; exports.noticeToStderr = noticeToStderr; exports.registerWorkflowCommands = registerWorkflowCommands; exports.renderTransformReport = renderTransformReport; exports.transformOne = transformOne;