deepline 0.1.113 → 0.1.115

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.
package/dist/cli/index.js CHANGED
@@ -403,10 +403,10 @@ var SDK_RELEASE = {
403
403
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
404
404
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
405
405
  // the SDK enrich generator's one-second stale policy.
406
- version: "0.1.113",
406
+ version: "0.1.115",
407
407
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
408
408
  supportPolicy: {
409
- latest: "0.1.113",
409
+ latest: "0.1.115",
410
410
  minimumSupported: "0.1.53",
411
411
  deprecatedBelow: "0.1.53",
412
412
  commandMinimumSupported: [
@@ -15016,11 +15016,11 @@ Concepts:
15016
15016
 
15017
15017
  Common commands:
15018
15018
  deepline plays search email --json
15019
- deepline plays describe person-linkedin-to-email --json
15019
+ deepline plays describe prebuilt/person-linkedin-to-email --json
15020
15020
  deepline plays check my.play.ts
15021
15021
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
15022
15022
  deepline plays set-live my.play.ts --json
15023
- deepline plays get person-linkedin-to-email --json
15023
+ deepline plays get prebuilt/person-linkedin-to-email --json
15024
15024
  `
15025
15025
  );
15026
15026
  play.command("check <target>").description("Check a local play file or named/prebuilt play contract.").addHelpText(
@@ -15089,7 +15089,7 @@ Idempotent execution:
15089
15089
  Examples:
15090
15090
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
15091
15091
  deepline plays run my.play.ts --input @input.json --json
15092
- deepline plays run person-linkedin-to-email --input '{"linkedin_url":"..."}'
15092
+ deepline plays run prebuilt/person-linkedin-to-email --input '{"linkedin_url":"..."}'
15093
15093
  deepline plays run cto-search.play.ts --limit 5
15094
15094
  deepline plays run long-background-play --no-wait
15095
15095
  deepline runs export <run-id> --out output.csv
@@ -15156,8 +15156,8 @@ Notes:
15156
15156
  contract and examples.
15157
15157
 
15158
15158
  Examples:
15159
- deepline plays get person-linkedin-to-email
15160
- deepline plays get person-linkedin-to-email --json | jq '.play.liveRevision'
15159
+ deepline plays get prebuilt/person-linkedin-to-email
15160
+ deepline plays get prebuilt/person-linkedin-to-email --json | jq '.play.liveRevision'
15161
15161
  deepline plays get prebuilt/name-and-domain-to-email-waterfall-batch --source > email-waterfall.play.ts
15162
15162
  deepline plays get prebuilt/name-and-domain-to-email-waterfall-batch --source --out ./email-waterfall.play.ts
15163
15163
  `
@@ -15209,7 +15209,7 @@ Examples:
15209
15209
  deepline plays search email
15210
15210
  deepline plays search email --all
15211
15211
  deepline plays grep "linkedin to email" --compact --json
15212
- deepline plays describe person-linkedin-to-email --json
15212
+ deepline plays describe prebuilt/person-linkedin-to-email --json
15213
15213
  `
15214
15214
  ).option("--compact", "Emit compact schemas").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
15215
15215
  process.exitCode = await handlePlaySearch([
@@ -15251,8 +15251,8 @@ Notes:
15251
15251
  Use \`get\` when you need full metadata, revisions, source fields, or latest runs.
15252
15252
 
15253
15253
  Examples:
15254
- deepline plays describe person-linkedin-to-email
15255
- deepline plays describe person-linkedin-to-email --json
15254
+ deepline plays describe prebuilt/person-linkedin-to-email
15255
+ deepline plays describe prebuilt/person-linkedin-to-email --json
15256
15256
  deepline plays get prebuilt/person-linkedin-to-email --source --out ./person-linkedin-to-email.play.ts
15257
15257
  `
15258
15258
  ).option("--compact", "Emit compact schemas").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
@@ -16031,6 +16031,8 @@ ${indent(renderJavascriptBody(command.run_if_js), 6)}
16031
16031
  force: true` : "";
16032
16032
  const legacyEnvelope = options.legacyEnvelope ? `,
16033
16033
  legacyEnvelope: true` : "";
16034
+ const waterfallSoftFail = options.waterfallSoftFail ? `,
16035
+ waterfallSoftFail: true` : "";
16034
16036
  return [
16035
16037
  `async (row, stepCtx) => {`,
16036
16038
  ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
@@ -16042,7 +16044,7 @@ ${indent(renderJavascriptBody(command.run_if_js), 6)}
16042
16044
  ` extract: ${extractJs},`,
16043
16045
  ` runIf: ${runIfJs},`,
16044
16046
  ` row,`,
16045
- ` stepCtx${description}${force}${legacyEnvelope}`,
16047
+ ` stepCtx${description}${force}${legacyEnvelope}${waterfallSoftFail}`,
16046
16048
  ` });`,
16047
16049
  `}`
16048
16050
  ].join("\n");
@@ -16066,34 +16068,22 @@ function renderIdiomaticExecuteStep(command, options) {
16066
16068
  `async (row, ctx) => {`,
16067
16069
  ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
16068
16070
  ...runIfLines,
16069
- ` const result: any = await ctx.tools.execute({`,
16070
- ` id: ${callId},`,
16071
- ` tool: ${tool},`,
16072
- ` input: ${input2} as any,`,
16073
- ` description: ${stringLiteral((command.description ?? "").trim() || `Run ${command.alias} via ${command.tool}.`)},`,
16074
- ...options.force ? [` force: true,`] : [],
16075
- ` });`,
16071
+ ` let result: any;`,
16072
+ ` try {`,
16073
+ ` result = await ctx.tools.execute({`,
16074
+ ` id: ${callId},`,
16075
+ ` tool: ${tool},`,
16076
+ ` input: ${input2} as any,`,
16077
+ ` description: ${stringLiteral((command.description ?? "").trim() || `Run ${command.alias} via ${command.tool}.`)},`,
16078
+ ...options.force ? [` force: true,`] : [],
16079
+ ` });`,
16080
+ ` } catch (error) {`,
16081
+ ...options.waterfallSoftFail ? [` return __dlWaterfallToolFailure(error);`] : [` throw error;`],
16082
+ ` }`,
16076
16083
  ` return ${extraction};`,
16077
16084
  `}`
16078
16085
  ].join("\n");
16079
16086
  }
16080
- function renderInlineJavascriptStep(command, options) {
16081
- const code = typeof command.payload?.code === "string" ? command.payload.code : "return null;";
16082
- const runIfLines = command.run_if_js ? [
16083
- ` if (!((row: Record<string, any>) => { const input = row; const context = row;`,
16084
- indent(renderJavascriptBody(command.run_if_js), 4),
16085
- ` })(row as Record<string, any>)) return null;`
16086
- ] : [];
16087
- return [
16088
- `async (row) => {`,
16089
- ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
16090
- ...runIfLines,
16091
- ` return ((row: Record<string, any>, input: Record<string, any>, context: Record<string, any>) => {`,
16092
- indent(renderJavascriptBody(code), 4),
16093
- ` })(row as Record<string, any>, row as Record<string, any>, row as Record<string, any>);`,
16094
- `}`
16095
- ].join("\n");
16096
- }
16097
16087
  function renderPlayStep(command, options) {
16098
16088
  const alias = stringLiteral(command.alias);
16099
16089
  const callId = stringLiteral(commandCallId(command));
@@ -16112,13 +16102,35 @@ ${indent(renderJavascriptBody(command.run_if_js), 6)}
16112
16102
  ` const templateRow = __dlPrepareEnrichRow(row, [${alias}]);`,
16113
16103
  ...runIfLines,
16114
16104
  ` const payload = __dlTemplate(${payload}, templateRow) as Record<string, unknown>;`,
16115
- ` const result = await stepCtx.runPlay(${callId}, ${playRef}, payload, {`,
16116
- ` description: ${stringLiteral(command.description ?? command.alias)}`,
16117
- ` });`,
16105
+ ` let result: unknown;`,
16106
+ ` try {`,
16107
+ ` result = await stepCtx.runPlay(${callId}, ${playRef}, payload, {`,
16108
+ ` description: ${stringLiteral(command.description ?? command.alias)}`,
16109
+ ` });`,
16110
+ ` } catch (error) {`,
16111
+ ...options.waterfallSoftFail ? [` return __dlWaterfallToolFailure(error);`] : [` throw error;`],
16112
+ ` }`,
16118
16113
  ` return __dlPlayResultValue(${alias}, result);`,
16119
16114
  `}`
16120
16115
  ].join("\n");
16121
16116
  }
16117
+ function renderInlineJavascriptStep(command, options) {
16118
+ const code = typeof command.payload?.code === "string" ? command.payload.code : "return null;";
16119
+ const runIfLines = command.run_if_js ? [
16120
+ ` if (!((row: Record<string, any>) => { const input = row; const context = row;`,
16121
+ indent(renderJavascriptBody(command.run_if_js), 4),
16122
+ ` })(row as Record<string, any>)) return null;`
16123
+ ] : [];
16124
+ return [
16125
+ `async (row) => {`,
16126
+ ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
16127
+ ...runIfLines,
16128
+ ` return ((row: Record<string, any>, input: Record<string, any>, context: Record<string, any>) => {`,
16129
+ indent(renderJavascriptBody(code), 4),
16130
+ ` })(row as Record<string, any>, row as Record<string, any>, row as Record<string, any>);`,
16131
+ `}`
16132
+ ].join("\n");
16133
+ }
16122
16134
  function renderJavascriptBody(source) {
16123
16135
  assertUserCodeIsSafe(source, "play step code");
16124
16136
  const trimmed = source.trim();
@@ -16245,7 +16257,8 @@ function renderWaterfallColumns(command, forceAliases, inlineRunJavascript, idio
16245
16257
  precheck: priorAliases.length > 0 ? `__dlWaterfallSatisfied(row, ${stableJson(priorAliases)}, ${minResults})` : void 0,
16246
16258
  legacyEnvelope: Boolean(nested.extract_js),
16247
16259
  inlineRunJavascript,
16248
- idiomaticGetters
16260
+ idiomaticGetters,
16261
+ waterfallSoftFail: true
16249
16262
  }),
16250
16263
  { recompute: force, recomputeOnError: true }
16251
16264
  );
@@ -16900,6 +16913,26 @@ function helperSource() {
16900
16913
  ` return 'Extractor failed';`,
16901
16914
  `}`,
16902
16915
  ``,
16916
+ `function __dlErrorDetail(error: unknown): string {`,
16917
+ ` const message = __dlErrorMessage(error);`,
16918
+ ` if (!__dlRecord(error)) return message;`,
16919
+ ` try {`,
16920
+ ` return message + ' ' + JSON.stringify(error);`,
16921
+ ` } catch {`,
16922
+ ` return message;`,
16923
+ ` }`,
16924
+ `}`,
16925
+ ``,
16926
+ `function __dlRecoverableWaterfallToolError(error: unknown): boolean {`,
16927
+ ` const detail = __dlErrorDetail(error).toLowerCase();`,
16928
+ ` return /\\b5\\d\\d\\b/.test(detail) || detail.includes('upstream_failure') || detail.includes('"error_category":"upstream"') || (detail.includes('"failure_origin":"provider"') && detail.includes('"status":5')) || detail.includes('bad gateway') || detail.includes('gateway time-out') || detail.includes('gateway timeout') || detail.includes('service unavailable');`,
16929
+ `}`,
16930
+ ``,
16931
+ `function __dlWaterfallToolFailure(error: unknown): unknown {`,
16932
+ ` if (__dlRecoverableWaterfallToolError(error)) return __dlExtractorFailure(error);`,
16933
+ ` throw error;`,
16934
+ `}`,
16935
+ ``,
16903
16936
  `function __dlExtractorFailure(error: unknown): unknown {`,
16904
16937
  ` const message = __dlErrorMessage(error);`,
16905
16938
  ` return { matched_result: null, result: { error: message, message } };`,
@@ -16996,19 +17029,25 @@ function helperSource() {
16996
17029
  ` return result;`,
16997
17030
  `}`,
16998
17031
  ``,
16999
- `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: { tools: { execute: (request: Record<string, unknown>) => Promise<unknown> } }; description?: string; force?: boolean; legacyEnvelope?: boolean }): Promise<unknown> {`,
17032
+ `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: { tools: { execute: (request: Record<string, unknown>) => Promise<unknown> } }; description?: string; force?: boolean; legacyEnvelope?: boolean; waterfallSoftFail?: boolean }): Promise<unknown> {`,
17000
17033
  ` if (input.runIf) {`,
17001
17034
  ` const shouldRun = input.runIf(input.row);`,
17002
17035
  ` if (!shouldRun) return null;`,
17003
17036
  ` }`,
17004
17037
  ` const payload = __dlRuntimePayload(input.tool, __dlTemplate(input.payload, input.row) as Record<string, unknown>, input.row);`,
17005
- ` const result = await input.stepCtx.tools.execute({`,
17006
- ` id: input.callId,`,
17007
- ` tool: input.tool,`,
17008
- ` input: payload,`,
17009
- ` ...(input.description ? { description: input.description } : {}),`,
17010
- ` ...(input.force ? { force: true } : {}),`,
17011
- ` });`,
17038
+ ` let result: unknown;`,
17039
+ ` try {`,
17040
+ ` result = await input.stepCtx.tools.execute({`,
17041
+ ` id: input.callId,`,
17042
+ ` tool: input.tool,`,
17043
+ ` input: payload,`,
17044
+ ` ...(input.description ? { description: input.description } : {}),`,
17045
+ ` ...(input.force ? { force: true } : {}),`,
17046
+ ` });`,
17047
+ ` } catch (error) {`,
17048
+ ` if (input.waterfallSoftFail) return __dlWaterfallToolFailure(error);`,
17049
+ ` throw error;`,
17050
+ ` }`,
17012
17051
  ` return __dlExtract(input.alias, result, input.row, input.extract, Boolean(input.legacyEnvelope));`,
17013
17052
  `}`
17014
17053
  ].join("\n");
@@ -23695,7 +23734,7 @@ Common commands:
23695
23734
  deepline auth status --json
23696
23735
  deepline sessions send --current-session --json
23697
23736
  deepline plays search email --json
23698
- deepline plays describe person-linkedin-to-email --json
23737
+ deepline plays describe prebuilt/person-linkedin-to-email --json
23699
23738
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
23700
23739
  deepline secrets check HUBSPOT_TOKEN
23701
23740
  deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
@@ -380,10 +380,10 @@ var SDK_RELEASE = {
380
380
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
381
381
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
382
382
  // the SDK enrich generator's one-second stale policy.
383
- version: "0.1.113",
383
+ version: "0.1.115",
384
384
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
385
385
  supportPolicy: {
386
- latest: "0.1.113",
386
+ latest: "0.1.115",
387
387
  minimumSupported: "0.1.53",
388
388
  deprecatedBelow: "0.1.53",
389
389
  commandMinimumSupported: [
@@ -15034,11 +15034,11 @@ Concepts:
15034
15034
 
15035
15035
  Common commands:
15036
15036
  deepline plays search email --json
15037
- deepline plays describe person-linkedin-to-email --json
15037
+ deepline plays describe prebuilt/person-linkedin-to-email --json
15038
15038
  deepline plays check my.play.ts
15039
15039
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
15040
15040
  deepline plays set-live my.play.ts --json
15041
- deepline plays get person-linkedin-to-email --json
15041
+ deepline plays get prebuilt/person-linkedin-to-email --json
15042
15042
  `
15043
15043
  );
15044
15044
  play.command("check <target>").description("Check a local play file or named/prebuilt play contract.").addHelpText(
@@ -15107,7 +15107,7 @@ Idempotent execution:
15107
15107
  Examples:
15108
15108
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
15109
15109
  deepline plays run my.play.ts --input @input.json --json
15110
- deepline plays run person-linkedin-to-email --input '{"linkedin_url":"..."}'
15110
+ deepline plays run prebuilt/person-linkedin-to-email --input '{"linkedin_url":"..."}'
15111
15111
  deepline plays run cto-search.play.ts --limit 5
15112
15112
  deepline plays run long-background-play --no-wait
15113
15113
  deepline runs export <run-id> --out output.csv
@@ -15174,8 +15174,8 @@ Notes:
15174
15174
  contract and examples.
15175
15175
 
15176
15176
  Examples:
15177
- deepline plays get person-linkedin-to-email
15178
- deepline plays get person-linkedin-to-email --json | jq '.play.liveRevision'
15177
+ deepline plays get prebuilt/person-linkedin-to-email
15178
+ deepline plays get prebuilt/person-linkedin-to-email --json | jq '.play.liveRevision'
15179
15179
  deepline plays get prebuilt/name-and-domain-to-email-waterfall-batch --source > email-waterfall.play.ts
15180
15180
  deepline plays get prebuilt/name-and-domain-to-email-waterfall-batch --source --out ./email-waterfall.play.ts
15181
15181
  `
@@ -15227,7 +15227,7 @@ Examples:
15227
15227
  deepline plays search email
15228
15228
  deepline plays search email --all
15229
15229
  deepline plays grep "linkedin to email" --compact --json
15230
- deepline plays describe person-linkedin-to-email --json
15230
+ deepline plays describe prebuilt/person-linkedin-to-email --json
15231
15231
  `
15232
15232
  ).option("--compact", "Emit compact schemas").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
15233
15233
  process.exitCode = await handlePlaySearch([
@@ -15269,8 +15269,8 @@ Notes:
15269
15269
  Use \`get\` when you need full metadata, revisions, source fields, or latest runs.
15270
15270
 
15271
15271
  Examples:
15272
- deepline plays describe person-linkedin-to-email
15273
- deepline plays describe person-linkedin-to-email --json
15272
+ deepline plays describe prebuilt/person-linkedin-to-email
15273
+ deepline plays describe prebuilt/person-linkedin-to-email --json
15274
15274
  deepline plays get prebuilt/person-linkedin-to-email --source --out ./person-linkedin-to-email.play.ts
15275
15275
  `
15276
15276
  ).option("--compact", "Emit compact schemas").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
@@ -16049,6 +16049,8 @@ ${indent(renderJavascriptBody(command.run_if_js), 6)}
16049
16049
  force: true` : "";
16050
16050
  const legacyEnvelope = options.legacyEnvelope ? `,
16051
16051
  legacyEnvelope: true` : "";
16052
+ const waterfallSoftFail = options.waterfallSoftFail ? `,
16053
+ waterfallSoftFail: true` : "";
16052
16054
  return [
16053
16055
  `async (row, stepCtx) => {`,
16054
16056
  ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
@@ -16060,7 +16062,7 @@ ${indent(renderJavascriptBody(command.run_if_js), 6)}
16060
16062
  ` extract: ${extractJs},`,
16061
16063
  ` runIf: ${runIfJs},`,
16062
16064
  ` row,`,
16063
- ` stepCtx${description}${force}${legacyEnvelope}`,
16065
+ ` stepCtx${description}${force}${legacyEnvelope}${waterfallSoftFail}`,
16064
16066
  ` });`,
16065
16067
  `}`
16066
16068
  ].join("\n");
@@ -16084,34 +16086,22 @@ function renderIdiomaticExecuteStep(command, options) {
16084
16086
  `async (row, ctx) => {`,
16085
16087
  ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
16086
16088
  ...runIfLines,
16087
- ` const result: any = await ctx.tools.execute({`,
16088
- ` id: ${callId},`,
16089
- ` tool: ${tool},`,
16090
- ` input: ${input2} as any,`,
16091
- ` description: ${stringLiteral((command.description ?? "").trim() || `Run ${command.alias} via ${command.tool}.`)},`,
16092
- ...options.force ? [` force: true,`] : [],
16093
- ` });`,
16089
+ ` let result: any;`,
16090
+ ` try {`,
16091
+ ` result = await ctx.tools.execute({`,
16092
+ ` id: ${callId},`,
16093
+ ` tool: ${tool},`,
16094
+ ` input: ${input2} as any,`,
16095
+ ` description: ${stringLiteral((command.description ?? "").trim() || `Run ${command.alias} via ${command.tool}.`)},`,
16096
+ ...options.force ? [` force: true,`] : [],
16097
+ ` });`,
16098
+ ` } catch (error) {`,
16099
+ ...options.waterfallSoftFail ? [` return __dlWaterfallToolFailure(error);`] : [` throw error;`],
16100
+ ` }`,
16094
16101
  ` return ${extraction};`,
16095
16102
  `}`
16096
16103
  ].join("\n");
16097
16104
  }
16098
- function renderInlineJavascriptStep(command, options) {
16099
- const code = typeof command.payload?.code === "string" ? command.payload.code : "return null;";
16100
- const runIfLines = command.run_if_js ? [
16101
- ` if (!((row: Record<string, any>) => { const input = row; const context = row;`,
16102
- indent(renderJavascriptBody(command.run_if_js), 4),
16103
- ` })(row as Record<string, any>)) return null;`
16104
- ] : [];
16105
- return [
16106
- `async (row) => {`,
16107
- ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
16108
- ...runIfLines,
16109
- ` return ((row: Record<string, any>, input: Record<string, any>, context: Record<string, any>) => {`,
16110
- indent(renderJavascriptBody(code), 4),
16111
- ` })(row as Record<string, any>, row as Record<string, any>, row as Record<string, any>);`,
16112
- `}`
16113
- ].join("\n");
16114
- }
16115
16105
  function renderPlayStep(command, options) {
16116
16106
  const alias = stringLiteral(command.alias);
16117
16107
  const callId = stringLiteral(commandCallId(command));
@@ -16130,13 +16120,35 @@ ${indent(renderJavascriptBody(command.run_if_js), 6)}
16130
16120
  ` const templateRow = __dlPrepareEnrichRow(row, [${alias}]);`,
16131
16121
  ...runIfLines,
16132
16122
  ` const payload = __dlTemplate(${payload}, templateRow) as Record<string, unknown>;`,
16133
- ` const result = await stepCtx.runPlay(${callId}, ${playRef}, payload, {`,
16134
- ` description: ${stringLiteral(command.description ?? command.alias)}`,
16135
- ` });`,
16123
+ ` let result: unknown;`,
16124
+ ` try {`,
16125
+ ` result = await stepCtx.runPlay(${callId}, ${playRef}, payload, {`,
16126
+ ` description: ${stringLiteral(command.description ?? command.alias)}`,
16127
+ ` });`,
16128
+ ` } catch (error) {`,
16129
+ ...options.waterfallSoftFail ? [` return __dlWaterfallToolFailure(error);`] : [` throw error;`],
16130
+ ` }`,
16136
16131
  ` return __dlPlayResultValue(${alias}, result);`,
16137
16132
  `}`
16138
16133
  ].join("\n");
16139
16134
  }
16135
+ function renderInlineJavascriptStep(command, options) {
16136
+ const code = typeof command.payload?.code === "string" ? command.payload.code : "return null;";
16137
+ const runIfLines = command.run_if_js ? [
16138
+ ` if (!((row: Record<string, any>) => { const input = row; const context = row;`,
16139
+ indent(renderJavascriptBody(command.run_if_js), 4),
16140
+ ` })(row as Record<string, any>)) return null;`
16141
+ ] : [];
16142
+ return [
16143
+ `async (row) => {`,
16144
+ ...options.precheck ? [` if (${options.precheck}) return null;`] : [],
16145
+ ...runIfLines,
16146
+ ` return ((row: Record<string, any>, input: Record<string, any>, context: Record<string, any>) => {`,
16147
+ indent(renderJavascriptBody(code), 4),
16148
+ ` })(row as Record<string, any>, row as Record<string, any>, row as Record<string, any>);`,
16149
+ `}`
16150
+ ].join("\n");
16151
+ }
16140
16152
  function renderJavascriptBody(source) {
16141
16153
  assertUserCodeIsSafe(source, "play step code");
16142
16154
  const trimmed = source.trim();
@@ -16263,7 +16275,8 @@ function renderWaterfallColumns(command, forceAliases, inlineRunJavascript, idio
16263
16275
  precheck: priorAliases.length > 0 ? `__dlWaterfallSatisfied(row, ${stableJson(priorAliases)}, ${minResults})` : void 0,
16264
16276
  legacyEnvelope: Boolean(nested.extract_js),
16265
16277
  inlineRunJavascript,
16266
- idiomaticGetters
16278
+ idiomaticGetters,
16279
+ waterfallSoftFail: true
16267
16280
  }),
16268
16281
  { recompute: force, recomputeOnError: true }
16269
16282
  );
@@ -16918,6 +16931,26 @@ function helperSource() {
16918
16931
  ` return 'Extractor failed';`,
16919
16932
  `}`,
16920
16933
  ``,
16934
+ `function __dlErrorDetail(error: unknown): string {`,
16935
+ ` const message = __dlErrorMessage(error);`,
16936
+ ` if (!__dlRecord(error)) return message;`,
16937
+ ` try {`,
16938
+ ` return message + ' ' + JSON.stringify(error);`,
16939
+ ` } catch {`,
16940
+ ` return message;`,
16941
+ ` }`,
16942
+ `}`,
16943
+ ``,
16944
+ `function __dlRecoverableWaterfallToolError(error: unknown): boolean {`,
16945
+ ` const detail = __dlErrorDetail(error).toLowerCase();`,
16946
+ ` return /\\b5\\d\\d\\b/.test(detail) || detail.includes('upstream_failure') || detail.includes('"error_category":"upstream"') || (detail.includes('"failure_origin":"provider"') && detail.includes('"status":5')) || detail.includes('bad gateway') || detail.includes('gateway time-out') || detail.includes('gateway timeout') || detail.includes('service unavailable');`,
16947
+ `}`,
16948
+ ``,
16949
+ `function __dlWaterfallToolFailure(error: unknown): unknown {`,
16950
+ ` if (__dlRecoverableWaterfallToolError(error)) return __dlExtractorFailure(error);`,
16951
+ ` throw error;`,
16952
+ `}`,
16953
+ ``,
16921
16954
  `function __dlExtractorFailure(error: unknown): unknown {`,
16922
16955
  ` const message = __dlErrorMessage(error);`,
16923
16956
  ` return { matched_result: null, result: { error: message, message } };`,
@@ -17014,19 +17047,25 @@ function helperSource() {
17014
17047
  ` return result;`,
17015
17048
  `}`,
17016
17049
  ``,
17017
- `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: { tools: { execute: (request: Record<string, unknown>) => Promise<unknown> } }; description?: string; force?: boolean; legacyEnvelope?: boolean }): Promise<unknown> {`,
17050
+ `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: { tools: { execute: (request: Record<string, unknown>) => Promise<unknown> } }; description?: string; force?: boolean; legacyEnvelope?: boolean; waterfallSoftFail?: boolean }): Promise<unknown> {`,
17018
17051
  ` if (input.runIf) {`,
17019
17052
  ` const shouldRun = input.runIf(input.row);`,
17020
17053
  ` if (!shouldRun) return null;`,
17021
17054
  ` }`,
17022
17055
  ` const payload = __dlRuntimePayload(input.tool, __dlTemplate(input.payload, input.row) as Record<string, unknown>, input.row);`,
17023
- ` const result = await input.stepCtx.tools.execute({`,
17024
- ` id: input.callId,`,
17025
- ` tool: input.tool,`,
17026
- ` input: payload,`,
17027
- ` ...(input.description ? { description: input.description } : {}),`,
17028
- ` ...(input.force ? { force: true } : {}),`,
17029
- ` });`,
17056
+ ` let result: unknown;`,
17057
+ ` try {`,
17058
+ ` result = await input.stepCtx.tools.execute({`,
17059
+ ` id: input.callId,`,
17060
+ ` tool: input.tool,`,
17061
+ ` input: payload,`,
17062
+ ` ...(input.description ? { description: input.description } : {}),`,
17063
+ ` ...(input.force ? { force: true } : {}),`,
17064
+ ` });`,
17065
+ ` } catch (error) {`,
17066
+ ` if (input.waterfallSoftFail) return __dlWaterfallToolFailure(error);`,
17067
+ ` throw error;`,
17068
+ ` }`,
17030
17069
  ` return __dlExtract(input.alias, result, input.row, input.extract, Boolean(input.legacyEnvelope));`,
17031
17070
  `}`
17032
17071
  ].join("\n");
@@ -23733,7 +23772,7 @@ Common commands:
23733
23772
  deepline auth status --json
23734
23773
  deepline sessions send --current-session --json
23735
23774
  deepline plays search email --json
23736
- deepline plays describe person-linkedin-to-email --json
23775
+ deepline plays describe prebuilt/person-linkedin-to-email --json
23737
23776
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
23738
23777
  deepline secrets check HUBSPOT_TOKEN
23739
23778
  deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
package/dist/index.js CHANGED
@@ -274,10 +274,10 @@ var SDK_RELEASE = {
274
274
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
275
275
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
276
276
  // the SDK enrich generator's one-second stale policy.
277
- version: "0.1.113",
277
+ version: "0.1.115",
278
278
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
279
279
  supportPolicy: {
280
- latest: "0.1.113",
280
+ latest: "0.1.115",
281
281
  minimumSupported: "0.1.53",
282
282
  deprecatedBelow: "0.1.53",
283
283
  commandMinimumSupported: [
package/dist/index.mjs CHANGED
@@ -196,10 +196,10 @@ var SDK_RELEASE = {
196
196
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
197
197
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
198
198
  // the SDK enrich generator's one-second stale policy.
199
- version: "0.1.113",
199
+ version: "0.1.115",
200
200
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
201
201
  supportPolicy: {
202
- latest: "0.1.113",
202
+ latest: "0.1.115",
203
203
  minimumSupported: "0.1.53",
204
204
  deprecatedBelow: "0.1.53",
205
205
  commandMinimumSupported: [
@@ -99,10 +99,10 @@ export const SDK_RELEASE = {
99
99
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
100
100
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
101
101
  // the SDK enrich generator's one-second stale policy.
102
- version: '0.1.113',
102
+ version: '0.1.115',
103
103
  apiContract: '2026-06-dataset-column-cell-stale-hard-cutover',
104
104
  supportPolicy: {
105
- latest: '0.1.113',
105
+ latest: '0.1.115',
106
106
  minimumSupported: '0.1.53',
107
107
  deprecatedBelow: '0.1.53',
108
108
  commandMinimumSupported: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.113",
3
+ "version": "0.1.115",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {