deepline 0.1.236 → 0.1.238

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.
@@ -106,20 +106,22 @@ export const SDK_RELEASE = {
106
106
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
107
107
  // fields shipped in 0.1.153.
108
108
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
109
+ // 0.1.230 propagates enrich extractor failures as failed rows rather than
110
+ // silently materializing them as unmatched results.
109
111
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
110
112
  // automatically without blocking their current command.
111
- version: '0.1.236',
113
+ version: '0.1.238',
112
114
  apiContract: '2026-06-dataset-handle-results-hard-cutover',
113
115
  supportPolicy: {
114
- latest: '0.1.236',
116
+ latest: '0.1.238',
115
117
  minimumSupported: '0.1.53',
116
118
  deprecatedBelow: '0.1.219',
117
119
  commandMinimumSupported: [
118
120
  {
119
121
  command: 'enrich',
120
- minimumSupported: '0.1.175',
122
+ minimumSupported: '0.1.238',
121
123
  reason:
122
- 'Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows.',
124
+ 'Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows; SDK CLI enrich before 0.1.230 could convert extractor failures into successful unmatched results; SDK CLI enrich before 0.1.238 could drop a nested provider email match during generic pick("email") extraction and materialize it as NO_MATCH.',
123
125
  },
124
126
  {
125
127
  command: 'plays',
package/dist/cli/index.js CHANGED
@@ -623,19 +623,21 @@ var SDK_RELEASE = {
623
623
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
624
624
  // fields shipped in 0.1.153.
625
625
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
626
+ // 0.1.230 propagates enrich extractor failures as failed rows rather than
627
+ // silently materializing them as unmatched results.
626
628
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
627
629
  // automatically without blocking their current command.
628
- version: "0.1.236",
630
+ version: "0.1.238",
629
631
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
630
632
  supportPolicy: {
631
- latest: "0.1.236",
633
+ latest: "0.1.238",
632
634
  minimumSupported: "0.1.53",
633
635
  deprecatedBelow: "0.1.219",
634
636
  commandMinimumSupported: [
635
637
  {
636
638
  command: "enrich",
637
- minimumSupported: "0.1.175",
638
- reason: "Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows."
639
+ minimumSupported: "0.1.238",
640
+ reason: 'Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows; SDK CLI enrich before 0.1.230 could convert extractor failures into successful unmatched results; SDK CLI enrich before 0.1.238 could drop a nested provider email match during generic pick("email") extraction and materialize it as NO_MATCH.'
639
641
  },
640
642
  {
641
643
  command: "plays",
@@ -18749,7 +18751,7 @@ function helperSource() {
18749
18751
  ``,
18750
18752
  `function __dlKeyPaths(key: string): string[] {`,
18751
18753
  ` const normalized = String(key || '').trim();`,
18752
- ` if (normalized === 'email') return ['email', 'email_address', 'person.email', 'contact.email', 'data.email', 'result.data.email'];`,
18754
+ ` 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'];`,
18753
18755
  ` if (normalized === 'personal_email') return ['personal_email', 'email', 'email_address', 'data.personal_email', 'data.email'];`,
18754
18756
  ` if (normalized === 'phone') return ['phone', 'phone_number', 'mobile_phone', 'mobile_phone_number', 'data.phone'];`,
18755
18757
  ` if (normalized === 'linkedin') return ['linkedin', 'linkedin_url', 'linkedin_profile', 'profile_url', 'person.linkedin', 'person.linkedin_url'];`,
@@ -18918,15 +18920,15 @@ function helperSource() {
18918
18920
  ` const raw = __dlRawToolOutput(result);`,
18919
18921
  ` if (!extractor) return raw;`,
18920
18922
  ` const pick = (paths: string[] | string) => {`,
18921
- ` const candidates = Array.isArray(paths) ? paths : [paths];`,
18922
- ` for (const path of candidates) {`,
18923
- ` if (typeof path === 'string') {`,
18923
+ ` const requestedPaths = Array.isArray(paths) ? paths : [paths];`,
18924
+ ` for (const requestedPath of requestedPaths) {`,
18925
+ ` for (const path of __dlKeyPaths(String(requestedPath))) {`,
18924
18926
  ` const extractedValue = __dlExtractedValue(result, path);`,
18925
18927
  ` if (__dlMeaningful(extractedValue)) return extractedValue;`,
18926
- ` }`,
18927
- ` for (const candidate of __dlRawToolCandidates(raw)) {`,
18928
- ` const value = __dlGetByPath(candidate, String(path));`,
18929
- ` if (__dlMeaningful(value)) return value;`,
18928
+ ` for (const candidate of __dlRawToolCandidates(raw)) {`,
18929
+ ` const value = __dlGetByPath(candidate, path);`,
18930
+ ` if (__dlMeaningful(value)) return value;`,
18931
+ ` }`,
18930
18932
  ` }`,
18931
18933
  ` }`,
18932
18934
  ` return null;`,
@@ -26363,7 +26365,9 @@ function printPlayLikeToolExecuteError(toolId, tool) {
26363
26365
  console.error(playLikeToolExecuteErrorMessage(toolId, tool));
26364
26366
  }
26365
26367
  function registerToolsCommands(program) {
26366
- const tools = program.command("tools").description("Search, describe, and execute atomic provider tools.").addHelpText(
26368
+ const tools = program.command("tools").description(
26369
+ "Search by intent or structured filters, describe, and execute atomic provider tools."
26370
+ ).addHelpText(
26367
26371
  "after",
26368
26372
  `
26369
26373
  Concepts:
@@ -26402,30 +26406,34 @@ Examples:
26402
26406
  ...options.json ? ["--json"] : []
26403
26407
  ]);
26404
26408
  });
26405
- const addToolSearchCommand = (command) => command.description("Search available tools.").addHelpText(
26409
+ const addToolSearchCommand = (command) => command.description(
26410
+ "Search available tools by intent query or structured filters."
26411
+ ).addHelpText(
26406
26412
  "after",
26407
26413
  `
26408
26414
  Notes:
26409
26415
  Ranked discovery for atomic provider/API operations. Results include tool ids
26410
26416
  that can be passed to deepline tools describe or deepline tools execute.
26417
+ Provide a query, or omit it only when --categories and/or --search_terms is
26418
+ supplied. Providing neither is a usage error. Both filters accept
26419
+ comma-separated values. Use a provider name in the query; --prefix is not a
26420
+ supported option.
26411
26421
  The grep alias is the same ranked retrieval surface with a more literal name
26412
26422
  for agents that are filtering a registry rather than choosing a workflow.
26413
26423
 
26414
26424
  Examples:
26415
26425
  deepline tools search email
26426
+ deepline tools search --categories company_search --search_terms "investors,funding"
26416
26427
  deepline tools grep "company enrichment" --categories enrichment --json
26417
26428
  deepline tools search verifier --search-mode v2 --json
26418
26429
  `
26419
26430
  ).option(
26420
26431
  "--categories <categories>",
26421
- "Comma-separated categories to filter ranked search"
26432
+ "Comma-separated categories; may be used without a query"
26422
26433
  ).option(
26423
26434
  "--search_terms <terms>",
26424
- "Structured search terms for ranked search"
26425
- ).option(
26426
- "--search-terms <terms>",
26427
- "Structured search terms for ranked search"
26428
- ).option("--search-mode <mode>", "Ranked search mode: v1 or v2").option("--include-search-debug", "Include ranked search debug metadata").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
26435
+ "Comma-separated structured search terms; may be used without a query"
26436
+ ).option("--search-terms <terms>", "Alias for --search_terms").option("--search-mode <mode>", "Ranked search mode: v1 or v2").option("--include-search-debug", "Include ranked search debug metadata").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
26429
26437
  process.exitCode = await searchTools(query, {
26430
26438
  json: options.json,
26431
26439
  compact: options.compact,
@@ -28372,6 +28380,9 @@ function sdkSkillsVersionPath(baseUrl) {
28372
28380
  function legacySdkSkillsVersionPath(baseUrl) {
28373
28381
  return (0, import_node_path18.join)((0, import_node_path18.dirname)(sdkCliStateDirPath(baseUrl)), "sdk-skills", ".version");
28374
28382
  }
28383
+ function unavailableSkillsNoticePath(baseUrl) {
28384
+ return (0, import_node_path18.join)(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
28385
+ }
28375
28386
  function readSdkSkillsLocalVersion(baseUrl) {
28376
28387
  const pluginVersion = readPluginSkillsVersion();
28377
28388
  if (pluginVersion) return pluginVersion;
@@ -28389,6 +28400,29 @@ function writeLocalSkillsVersion(baseUrl, version) {
28389
28400
  (0, import_node_fs16.writeFileSync)(path, `${version}
28390
28401
  `, "utf-8");
28391
28402
  }
28403
+ function writeUnavailableSkillsNotice(baseUrl, remoteVersion, skillNames) {
28404
+ const path = unavailableSkillsNoticePath(baseUrl);
28405
+ try {
28406
+ if ((0, import_node_fs16.existsSync)(path) && (0, import_node_fs16.readFileSync)(path, "utf-8").trim() === remoteVersion) {
28407
+ return;
28408
+ }
28409
+ (0, import_node_fs16.mkdirSync)((0, import_node_path18.dirname)(path), { recursive: true });
28410
+ (0, import_node_fs16.writeFileSync)(path, `${remoteVersion}
28411
+ `, "utf-8");
28412
+ } catch {
28413
+ }
28414
+ const manualCommand = `npx ${buildSkillsInstallArgs(baseUrl, skillNames).join(" ")}`;
28415
+ writeSdkSkillsStatusLine(
28416
+ `Deepline agent skills are out of date, but neither \`bunx\` nor \`npx\` is available. Install Node.js/npm or Bun, then run:
28417
+ ${manualCommand}`
28418
+ );
28419
+ }
28420
+ function clearUnavailableSkillsNotice(baseUrl) {
28421
+ try {
28422
+ (0, import_node_fs16.unlinkSync)(unavailableSkillsNoticePath(baseUrl));
28423
+ } catch {
28424
+ }
28425
+ }
28392
28426
  function sortedUniqueSkillNames(names) {
28393
28427
  return [...new Set(names.map((name) => name.trim()).filter(Boolean))].sort(
28394
28428
  (a, b) => a.localeCompare(b)
@@ -28464,24 +28498,24 @@ function shellQuote5(arg) {
28464
28498
  return `'${arg.replace(/'/g, `'\\''`)}'`;
28465
28499
  }
28466
28500
  function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
28467
- const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames);
28468
- const npxInstall = {
28469
- command: "npx",
28470
- args: npxArgs,
28471
- manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
28472
- };
28501
+ const commands = [];
28473
28502
  if (hasCommand("bunx")) {
28474
28503
  const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames);
28475
- return [
28476
- {
28477
- command: "bunx",
28478
- args: bunxArgs,
28479
- manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
28480
- },
28481
- npxInstall
28482
- ];
28504
+ commands.push({
28505
+ command: "bunx",
28506
+ args: bunxArgs,
28507
+ manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
28508
+ });
28509
+ }
28510
+ if (hasCommand("npx")) {
28511
+ const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames);
28512
+ commands.push({
28513
+ command: "npx",
28514
+ args: npxArgs,
28515
+ manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
28516
+ });
28483
28517
  }
28484
- return [npxInstall];
28518
+ return commands;
28485
28519
  }
28486
28520
  function runOneSkillsInstall(install) {
28487
28521
  return new Promise((resolve14) => {
@@ -28514,9 +28548,9 @@ function runOneSkillsInstall(install) {
28514
28548
  });
28515
28549
  });
28516
28550
  }
28517
- async function runSkillsInstall(baseUrl, skillNames) {
28551
+ async function runSkillsInstall(installs) {
28518
28552
  const failures = [];
28519
- for (const install of resolveSkillsInstallCommands(baseUrl, skillNames)) {
28553
+ for (const install of installs) {
28520
28554
  const result = await runOneSkillsInstall(install);
28521
28555
  if (result.ok) return true;
28522
28556
  failures.push(result);
@@ -28606,11 +28640,17 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
28606
28640
  remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
28607
28641
  );
28608
28642
  if (skillNames.length === 0) return;
28643
+ const installs = resolveSkillsInstallCommands(baseUrl, skillNames);
28644
+ if (installs.length === 0) {
28645
+ writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
28646
+ return;
28647
+ }
28609
28648
  writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
28610
- const installed = await runSkillsInstall(baseUrl, skillNames);
28649
+ const installed = await runSkillsInstall(installs);
28611
28650
  if (!installed) return;
28612
28651
  runLegacySkillsCleanup();
28613
28652
  writeLocalSkillsVersion(baseUrl, update.remoteVersion);
28653
+ clearUnavailableSkillsNotice(baseUrl);
28614
28654
  writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
28615
28655
  }
28616
28656
 
@@ -608,19 +608,21 @@ var SDK_RELEASE = {
608
608
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
609
609
  // fields shipped in 0.1.153.
610
610
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
611
+ // 0.1.230 propagates enrich extractor failures as failed rows rather than
612
+ // silently materializing them as unmatched results.
611
613
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
612
614
  // automatically without blocking their current command.
613
- version: "0.1.236",
615
+ version: "0.1.238",
614
616
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
615
617
  supportPolicy: {
616
- latest: "0.1.236",
618
+ latest: "0.1.238",
617
619
  minimumSupported: "0.1.53",
618
620
  deprecatedBelow: "0.1.219",
619
621
  commandMinimumSupported: [
620
622
  {
621
623
  command: "enrich",
622
- minimumSupported: "0.1.175",
623
- reason: "Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows."
624
+ minimumSupported: "0.1.238",
625
+ reason: 'Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows; SDK CLI enrich before 0.1.230 could convert extractor failures into successful unmatched results; SDK CLI enrich before 0.1.238 could drop a nested provider email match during generic pick("email") extraction and materialize it as NO_MATCH.'
624
626
  },
625
627
  {
626
628
  command: "plays",
@@ -18778,7 +18780,7 @@ function helperSource() {
18778
18780
  ``,
18779
18781
  `function __dlKeyPaths(key: string): string[] {`,
18780
18782
  ` const normalized = String(key || '').trim();`,
18781
- ` if (normalized === 'email') return ['email', 'email_address', 'person.email', 'contact.email', 'data.email', 'result.data.email'];`,
18783
+ ` 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'];`,
18782
18784
  ` if (normalized === 'personal_email') return ['personal_email', 'email', 'email_address', 'data.personal_email', 'data.email'];`,
18783
18785
  ` if (normalized === 'phone') return ['phone', 'phone_number', 'mobile_phone', 'mobile_phone_number', 'data.phone'];`,
18784
18786
  ` if (normalized === 'linkedin') return ['linkedin', 'linkedin_url', 'linkedin_profile', 'profile_url', 'person.linkedin', 'person.linkedin_url'];`,
@@ -18947,15 +18949,15 @@ function helperSource() {
18947
18949
  ` const raw = __dlRawToolOutput(result);`,
18948
18950
  ` if (!extractor) return raw;`,
18949
18951
  ` const pick = (paths: string[] | string) => {`,
18950
- ` const candidates = Array.isArray(paths) ? paths : [paths];`,
18951
- ` for (const path of candidates) {`,
18952
- ` if (typeof path === 'string') {`,
18952
+ ` const requestedPaths = Array.isArray(paths) ? paths : [paths];`,
18953
+ ` for (const requestedPath of requestedPaths) {`,
18954
+ ` for (const path of __dlKeyPaths(String(requestedPath))) {`,
18953
18955
  ` const extractedValue = __dlExtractedValue(result, path);`,
18954
18956
  ` if (__dlMeaningful(extractedValue)) return extractedValue;`,
18955
- ` }`,
18956
- ` for (const candidate of __dlRawToolCandidates(raw)) {`,
18957
- ` const value = __dlGetByPath(candidate, String(path));`,
18958
- ` if (__dlMeaningful(value)) return value;`,
18957
+ ` for (const candidate of __dlRawToolCandidates(raw)) {`,
18958
+ ` const value = __dlGetByPath(candidate, path);`,
18959
+ ` if (__dlMeaningful(value)) return value;`,
18960
+ ` }`,
18959
18961
  ` }`,
18960
18962
  ` }`,
18961
18963
  ` return null;`,
@@ -26411,7 +26413,9 @@ function printPlayLikeToolExecuteError(toolId, tool) {
26411
26413
  console.error(playLikeToolExecuteErrorMessage(toolId, tool));
26412
26414
  }
26413
26415
  function registerToolsCommands(program) {
26414
- const tools = program.command("tools").description("Search, describe, and execute atomic provider tools.").addHelpText(
26416
+ const tools = program.command("tools").description(
26417
+ "Search by intent or structured filters, describe, and execute atomic provider tools."
26418
+ ).addHelpText(
26415
26419
  "after",
26416
26420
  `
26417
26421
  Concepts:
@@ -26450,30 +26454,34 @@ Examples:
26450
26454
  ...options.json ? ["--json"] : []
26451
26455
  ]);
26452
26456
  });
26453
- const addToolSearchCommand = (command) => command.description("Search available tools.").addHelpText(
26457
+ const addToolSearchCommand = (command) => command.description(
26458
+ "Search available tools by intent query or structured filters."
26459
+ ).addHelpText(
26454
26460
  "after",
26455
26461
  `
26456
26462
  Notes:
26457
26463
  Ranked discovery for atomic provider/API operations. Results include tool ids
26458
26464
  that can be passed to deepline tools describe or deepline tools execute.
26465
+ Provide a query, or omit it only when --categories and/or --search_terms is
26466
+ supplied. Providing neither is a usage error. Both filters accept
26467
+ comma-separated values. Use a provider name in the query; --prefix is not a
26468
+ supported option.
26459
26469
  The grep alias is the same ranked retrieval surface with a more literal name
26460
26470
  for agents that are filtering a registry rather than choosing a workflow.
26461
26471
 
26462
26472
  Examples:
26463
26473
  deepline tools search email
26474
+ deepline tools search --categories company_search --search_terms "investors,funding"
26464
26475
  deepline tools grep "company enrichment" --categories enrichment --json
26465
26476
  deepline tools search verifier --search-mode v2 --json
26466
26477
  `
26467
26478
  ).option(
26468
26479
  "--categories <categories>",
26469
- "Comma-separated categories to filter ranked search"
26480
+ "Comma-separated categories; may be used without a query"
26470
26481
  ).option(
26471
26482
  "--search_terms <terms>",
26472
- "Structured search terms for ranked search"
26473
- ).option(
26474
- "--search-terms <terms>",
26475
- "Structured search terms for ranked search"
26476
- ).option("--search-mode <mode>", "Ranked search mode: v1 or v2").option("--include-search-debug", "Include ranked search debug metadata").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
26483
+ "Comma-separated structured search terms; may be used without a query"
26484
+ ).option("--search-terms <terms>", "Alias for --search_terms").option("--search-mode <mode>", "Ranked search mode: v1 or v2").option("--include-search-debug", "Include ranked search debug metadata").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (query, options) => {
26477
26485
  process.exitCode = await searchTools(query, {
26478
26486
  json: options.json,
26479
26487
  compact: options.compact,
@@ -28281,7 +28289,7 @@ import {
28281
28289
  readFileSync as readFileSync13,
28282
28290
  renameSync,
28283
28291
  rmSync as rmSync4,
28284
- unlinkSync,
28292
+ unlinkSync as unlinkSync2,
28285
28293
  writeFileSync as writeFileSync15
28286
28294
  } from "fs";
28287
28295
  import { homedir as homedir11 } from "os";
@@ -28289,7 +28297,13 @@ import { dirname as dirname13, isAbsolute as isAbsolute2, join as join14, relati
28289
28297
 
28290
28298
  // src/cli/skills-sync.ts
28291
28299
  import { spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
28292
- import { existsSync as existsSync11, mkdirSync as mkdirSync9, readFileSync as readFileSync12, writeFileSync as writeFileSync14 } from "fs";
28300
+ import {
28301
+ existsSync as existsSync11,
28302
+ mkdirSync as mkdirSync9,
28303
+ readFileSync as readFileSync12,
28304
+ unlinkSync,
28305
+ writeFileSync as writeFileSync14
28306
+ } from "fs";
28293
28307
  import { dirname as dirname12, join as join13 } from "path";
28294
28308
 
28295
28309
  // ../shared_libs/cli/install-commands.json
@@ -28429,6 +28443,9 @@ function sdkSkillsVersionPath(baseUrl) {
28429
28443
  function legacySdkSkillsVersionPath(baseUrl) {
28430
28444
  return join13(dirname12(sdkCliStateDirPath(baseUrl)), "sdk-skills", ".version");
28431
28445
  }
28446
+ function unavailableSkillsNoticePath(baseUrl) {
28447
+ return join13(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
28448
+ }
28432
28449
  function readSdkSkillsLocalVersion(baseUrl) {
28433
28450
  const pluginVersion = readPluginSkillsVersion();
28434
28451
  if (pluginVersion) return pluginVersion;
@@ -28446,6 +28463,29 @@ function writeLocalSkillsVersion(baseUrl, version) {
28446
28463
  writeFileSync14(path, `${version}
28447
28464
  `, "utf-8");
28448
28465
  }
28466
+ function writeUnavailableSkillsNotice(baseUrl, remoteVersion, skillNames) {
28467
+ const path = unavailableSkillsNoticePath(baseUrl);
28468
+ try {
28469
+ if (existsSync11(path) && readFileSync12(path, "utf-8").trim() === remoteVersion) {
28470
+ return;
28471
+ }
28472
+ mkdirSync9(dirname12(path), { recursive: true });
28473
+ writeFileSync14(path, `${remoteVersion}
28474
+ `, "utf-8");
28475
+ } catch {
28476
+ }
28477
+ const manualCommand = `npx ${buildSkillsInstallArgs(baseUrl, skillNames).join(" ")}`;
28478
+ writeSdkSkillsStatusLine(
28479
+ `Deepline agent skills are out of date, but neither \`bunx\` nor \`npx\` is available. Install Node.js/npm or Bun, then run:
28480
+ ${manualCommand}`
28481
+ );
28482
+ }
28483
+ function clearUnavailableSkillsNotice(baseUrl) {
28484
+ try {
28485
+ unlinkSync(unavailableSkillsNoticePath(baseUrl));
28486
+ } catch {
28487
+ }
28488
+ }
28449
28489
  function sortedUniqueSkillNames(names) {
28450
28490
  return [...new Set(names.map((name) => name.trim()).filter(Boolean))].sort(
28451
28491
  (a, b) => a.localeCompare(b)
@@ -28521,24 +28561,24 @@ function shellQuote5(arg) {
28521
28561
  return `'${arg.replace(/'/g, `'\\''`)}'`;
28522
28562
  }
28523
28563
  function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
28524
- const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames);
28525
- const npxInstall = {
28526
- command: "npx",
28527
- args: npxArgs,
28528
- manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
28529
- };
28564
+ const commands = [];
28530
28565
  if (hasCommand("bunx")) {
28531
28566
  const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames);
28532
- return [
28533
- {
28534
- command: "bunx",
28535
- args: bunxArgs,
28536
- manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
28537
- },
28538
- npxInstall
28539
- ];
28567
+ commands.push({
28568
+ command: "bunx",
28569
+ args: bunxArgs,
28570
+ manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
28571
+ });
28572
+ }
28573
+ if (hasCommand("npx")) {
28574
+ const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames);
28575
+ commands.push({
28576
+ command: "npx",
28577
+ args: npxArgs,
28578
+ manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
28579
+ });
28540
28580
  }
28541
- return [npxInstall];
28581
+ return commands;
28542
28582
  }
28543
28583
  function runOneSkillsInstall(install) {
28544
28584
  return new Promise((resolve14) => {
@@ -28571,9 +28611,9 @@ function runOneSkillsInstall(install) {
28571
28611
  });
28572
28612
  });
28573
28613
  }
28574
- async function runSkillsInstall(baseUrl, skillNames) {
28614
+ async function runSkillsInstall(installs) {
28575
28615
  const failures = [];
28576
- for (const install of resolveSkillsInstallCommands(baseUrl, skillNames)) {
28616
+ for (const install of installs) {
28577
28617
  const result = await runOneSkillsInstall(install);
28578
28618
  if (result.ok) return true;
28579
28619
  failures.push(result);
@@ -28663,11 +28703,17 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
28663
28703
  remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
28664
28704
  );
28665
28705
  if (skillNames.length === 0) return;
28706
+ const installs = resolveSkillsInstallCommands(baseUrl, skillNames);
28707
+ if (installs.length === 0) {
28708
+ writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
28709
+ return;
28710
+ }
28666
28711
  writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
28667
- const installed = await runSkillsInstall(baseUrl, skillNames);
28712
+ const installed = await runSkillsInstall(installs);
28668
28713
  if (!installed) return;
28669
28714
  runLegacySkillsCleanup();
28670
28715
  writeLocalSkillsVersion(baseUrl, update.remoteVersion);
28716
+ clearUnavailableSkillsNotice(baseUrl);
28671
28717
  writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
28672
28718
  }
28673
28719
 
@@ -28896,7 +28942,7 @@ function clearAutoUpdateFailure(plan) {
28896
28942
  const path = autoUpdateFailurePath(plan);
28897
28943
  if (!path) return;
28898
28944
  try {
28899
- unlinkSync(path);
28945
+ unlinkSync2(path);
28900
28946
  } catch {
28901
28947
  }
28902
28948
  }
package/dist/index.js CHANGED
@@ -422,19 +422,21 @@ var SDK_RELEASE = {
422
422
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
423
423
  // fields shipped in 0.1.153.
424
424
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
425
+ // 0.1.230 propagates enrich extractor failures as failed rows rather than
426
+ // silently materializing them as unmatched results.
425
427
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
426
428
  // automatically without blocking their current command.
427
- version: "0.1.236",
429
+ version: "0.1.238",
428
430
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
429
431
  supportPolicy: {
430
- latest: "0.1.236",
432
+ latest: "0.1.238",
431
433
  minimumSupported: "0.1.53",
432
434
  deprecatedBelow: "0.1.219",
433
435
  commandMinimumSupported: [
434
436
  {
435
437
  command: "enrich",
436
- minimumSupported: "0.1.175",
437
- reason: "Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows."
438
+ minimumSupported: "0.1.238",
439
+ reason: 'Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows; SDK CLI enrich before 0.1.230 could convert extractor failures into successful unmatched results; SDK CLI enrich before 0.1.238 could drop a nested provider email match during generic pick("email") extraction and materialize it as NO_MATCH.'
438
440
  },
439
441
  {
440
442
  command: "plays",
package/dist/index.mjs CHANGED
@@ -352,19 +352,21 @@ var SDK_RELEASE = {
352
352
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
353
353
  // fields shipped in 0.1.153.
354
354
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
355
+ // 0.1.230 propagates enrich extractor failures as failed rows rather than
356
+ // silently materializing them as unmatched results.
355
357
  // 0.1.220 deprecates SDK CLI versions below 0.1.219 and updates them
356
358
  // automatically without blocking their current command.
357
- version: "0.1.236",
359
+ version: "0.1.238",
358
360
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
359
361
  supportPolicy: {
360
- latest: "0.1.236",
362
+ latest: "0.1.238",
361
363
  minimumSupported: "0.1.53",
362
364
  deprecatedBelow: "0.1.219",
363
365
  commandMinimumSupported: [
364
366
  {
365
367
  command: "enrich",
366
- minimumSupported: "0.1.175",
367
- reason: "Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows."
368
+ minimumSupported: "0.1.238",
369
+ reason: 'Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows; SDK CLI enrich before 0.1.230 could convert extractor failures into successful unmatched results; SDK CLI enrich before 0.1.238 could drop a nested provider email match during generic pick("email") extraction and materialize it as NO_MATCH.'
368
370
  },
369
371
  {
370
372
  command: "plays",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.236",
3
+ "version": "0.1.238",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {