deepline 0.1.197 → 0.1.199

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,10 +106,10 @@ 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
- version: '0.1.197',
109
+ version: '0.1.199',
110
110
  apiContract: '2026-06-dataset-handle-results-hard-cutover',
111
111
  supportPolicy: {
112
- latest: '0.1.197',
112
+ latest: '0.1.199',
113
113
  minimumSupported: '0.1.53',
114
114
  deprecatedBelow: '0.1.53',
115
115
  commandMinimumSupported: [
package/dist/cli/index.js CHANGED
@@ -623,10 +623,10 @@ 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
- version: "0.1.197",
626
+ version: "0.1.199",
627
627
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
628
628
  supportPolicy: {
629
- latest: "0.1.197",
629
+ latest: "0.1.199",
630
630
  minimumSupported: "0.1.53",
631
631
  deprecatedBelow: "0.1.53",
632
632
  commandMinimumSupported: [
@@ -6135,16 +6135,7 @@ async function handleHistory(options) {
6135
6135
  `/api/v2/billing/ledger?since_at=${sinceAt}&limit=5000`
6136
6136
  );
6137
6137
  const entries = Array.isArray(payload.entries) ? payload.entries : [];
6138
- const rows = entries.map((entry) => {
6139
- const metadata = entry.metadata ?? {};
6140
- return {
6141
- created_at: entry.created_at ?? "",
6142
- delta_credits: entry.delta ?? "",
6143
- reason: entry.reason ?? "",
6144
- provider: metadata.provider ?? "",
6145
- operation: metadata.operation ?? ""
6146
- };
6147
- });
6138
+ const rows = entries.map(ledgerApiEntryToRow);
6148
6139
  const outputPath = await writeCsvRowsFile(
6149
6140
  `billing-history-${options.time}`,
6150
6141
  rows
@@ -10725,14 +10716,219 @@ function parseReferencedPlayTarget2(target) {
10725
10716
  function isPrebuiltReferenceTarget(target) {
10726
10717
  return target.trim().toLowerCase().startsWith("prebuilt/");
10727
10718
  }
10719
+ function buildBarePrebuiltReferenceMessage(input2) {
10720
+ return `Prebuilt play "${input2.requested}" must be referenced as "${input2.reference}". Use the prebuilt/ namespace anywhere you run, describe, get, or link to Deepline-managed plays.`;
10721
+ }
10728
10722
  function buildBarePrebuiltReferenceError(input2) {
10729
- return new Error(
10730
- `Prebuilt play "${input2.requested}" must be referenced as "${input2.reference}". Use the prebuilt/ namespace anywhere you run, describe, get, or link to Deepline-managed plays.`
10723
+ return new Error(buildBarePrebuiltReferenceMessage(input2));
10724
+ }
10725
+ function isPlayNotFoundError(error) {
10726
+ return error instanceof DeeplineError && (error.statusCode === 404 || error.code === "PLAY_NOT_FOUND" || error.code === "NOT_FOUND");
10727
+ }
10728
+ function isExplicitMissingPlayReferenceError(error) {
10729
+ if (!(error instanceof DeeplineError)) {
10730
+ return false;
10731
+ }
10732
+ if (error.statusCode !== 404 && error.code !== "PLAY_NOT_FOUND") {
10733
+ return false;
10734
+ }
10735
+ return /^play not found\b/i.test(error.message.trim());
10736
+ }
10737
+ function normalizePlayReferenceForMatch(value) {
10738
+ return value.trim().toLowerCase().replace(/^prebuilt\//, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
10739
+ }
10740
+ function playReferenceMatchTokens(value) {
10741
+ return normalizePlayReferenceForMatch(value).split("-").filter((token) => token.length > 1 && token !== "to" && token !== "and");
10742
+ }
10743
+ function playSuggestionReference(play) {
10744
+ if (play.reference?.trim()) {
10745
+ return play.reference.trim();
10746
+ }
10747
+ const ownerSlug = play.ownerSlug?.trim();
10748
+ return ownerSlug ? `${ownerSlug}/${play.name}` : play.name;
10749
+ }
10750
+ function scorePlayReferenceSuggestion(requested, play) {
10751
+ const parsed = parseReferencedPlayTarget2(requested);
10752
+ const requestedTrimmed = requested.trim();
10753
+ const requestedRef = requestedTrimmed.toLowerCase();
10754
+ const requestedName = parsed.unqualifiedPlayName;
10755
+ const requestedNorm = normalizePlayReferenceForMatch(requestedTrimmed);
10756
+ const requestedNameNorm = normalizePlayReferenceForMatch(requestedName);
10757
+ if (!requestedNorm && !requestedNameNorm) {
10758
+ return null;
10759
+ }
10760
+ const reference = playSuggestionReference(play);
10761
+ const referenceNorm = normalizePlayReferenceForMatch(reference);
10762
+ const nameNorm = normalizePlayReferenceForMatch(play.name);
10763
+ const candidateNamespace = reference.includes("/") ? reference.split("/")[0]?.toLowerCase() : null;
10764
+ const requestedNamespace = parsed.ownerSlug?.toLowerCase() ?? null;
10765
+ const aliases = (play.aliases ?? []).map(normalizePlayReferenceForMatch);
10766
+ const searchable = [referenceNorm, nameNorm, ...aliases].filter(Boolean);
10767
+ const requestedTokens = playReferenceMatchTokens(requestedName);
10768
+ const candidateTokens = [
10769
+ ...new Set(
10770
+ [reference, play.name, ...play.aliases ?? []].flatMap(
10771
+ playReferenceMatchTokens
10772
+ )
10773
+ )
10774
+ ];
10775
+ const hasTokenContainment = requestedTokens.length > 0 && requestedTokens.every((token) => candidateTokens.includes(token));
10776
+ let score = 0;
10777
+ if (reference.toLowerCase() === requestedRef) {
10778
+ score = 120;
10779
+ } else if (requestedNamespace && candidateNamespace === requestedNamespace && nameNorm === requestedNameNorm) {
10780
+ score = 110;
10781
+ } else if (nameNorm === requestedNameNorm || aliases.includes(requestedNameNorm)) {
10782
+ score = play.origin === "prebuilt" ? 100 : 95;
10783
+ } else if (requestedNamespace && candidateNamespace === requestedNamespace && searchable.some(
10784
+ (value) => value.includes(requestedNameNorm) || requestedNameNorm.includes(value)
10785
+ )) {
10786
+ score = 85;
10787
+ } else if (searchable.some(
10788
+ (value) => value.includes(requestedNorm) || requestedNorm.includes(value)
10789
+ )) {
10790
+ score = 70;
10791
+ } else if (requestedNameNorm && searchable.some(
10792
+ (value) => value.includes(requestedNameNorm) || requestedNameNorm.includes(value)
10793
+ )) {
10794
+ score = 60;
10795
+ } else if (hasTokenContainment) {
10796
+ score = requestedNamespace && candidateNamespace === requestedNamespace ? 58 : 50;
10797
+ }
10798
+ if (score <= 0) {
10799
+ return null;
10800
+ }
10801
+ if (play.origin === "prebuilt") {
10802
+ score += 3;
10803
+ }
10804
+ return {
10805
+ reference,
10806
+ name: play.name,
10807
+ origin: play.origin ?? null,
10808
+ score
10809
+ };
10810
+ }
10811
+ function rankPlayReferenceSuggestions(input2) {
10812
+ const byReference = /* @__PURE__ */ new Map();
10813
+ for (const play of input2.plays) {
10814
+ const suggestion = scorePlayReferenceSuggestion(input2.requested, play);
10815
+ if (!suggestion) continue;
10816
+ const existing = byReference.get(suggestion.reference);
10817
+ if (!existing || suggestion.score > existing.score) {
10818
+ byReference.set(suggestion.reference, suggestion);
10819
+ }
10820
+ }
10821
+ return [...byReference.values()].sort((left, right) => {
10822
+ if (right.score !== left.score) return right.score - left.score;
10823
+ if (left.origin === "prebuilt" && right.origin !== "prebuilt") return -1;
10824
+ if (right.origin === "prebuilt" && left.origin !== "prebuilt") return 1;
10825
+ return left.reference.localeCompare(right.reference);
10826
+ }).slice(0, input2.limit ?? 5);
10827
+ }
10828
+ function searchQueryForMissingPlayReference(target) {
10829
+ return parseReferencedPlayTarget2(target).unqualifiedPlayName.replace(/[-_./]+/g, " ").replace(/\s+/g, " ").trim();
10830
+ }
10831
+ function shellQuote2(value) {
10832
+ return `'${value.replace(/'/g, `'\\''`)}'`;
10833
+ }
10834
+ function buildPlayReferenceNotFoundMessage(input2) {
10835
+ const lines = [`Play not found: ${input2.requested}`];
10836
+ if (input2.suggestions.length > 0) {
10837
+ lines.push("", "Did you mean one of these?");
10838
+ for (const suggestion of input2.suggestions) {
10839
+ lines.push("", ` ${suggestion.reference}`);
10840
+ if (input2.command === "run") {
10841
+ lines.push(
10842
+ ` deepline plays run ${suggestion.reference} --input '{...}' --watch`
10843
+ );
10844
+ } else if (input2.command === "get") {
10845
+ lines.push(` deepline plays get ${suggestion.reference} --json`);
10846
+ } else if (input2.command === "check") {
10847
+ lines.push(` deepline plays check ${suggestion.reference} --json`);
10848
+ } else if (input2.command === "versions") {
10849
+ lines.push(
10850
+ ` deepline plays versions --name ${suggestion.reference} --json`
10851
+ );
10852
+ } else {
10853
+ lines.push(
10854
+ ` deepline plays describe ${suggestion.reference} --json`
10855
+ );
10856
+ }
10857
+ }
10858
+ }
10859
+ const searchQuery = searchQueryForMissingPlayReference(input2.requested);
10860
+ if (searchQuery) {
10861
+ lines.push(
10862
+ "",
10863
+ "Search visible plays:",
10864
+ ` deepline plays search ${shellQuote2(searchQuery)} --all --json`
10865
+ );
10866
+ }
10867
+ return lines.join("\n");
10868
+ }
10869
+ async function buildPlayReferenceNotFoundError(input2) {
10870
+ let suggestions = [];
10871
+ try {
10872
+ const searchQuery = searchQueryForMissingPlayReference(input2.target);
10873
+ const searchMatches = searchQuery ? await input2.client.searchPlays({
10874
+ query: searchQuery,
10875
+ scope: "all",
10876
+ compact: true
10877
+ }) : [];
10878
+ const plays = searchMatches.length > 0 ? searchMatches : await input2.client.listPlays();
10879
+ suggestions = rankPlayReferenceSuggestions({
10880
+ requested: input2.target,
10881
+ plays,
10882
+ limit: 5
10883
+ });
10884
+ } catch {
10885
+ suggestions = [];
10886
+ }
10887
+ const sourceError = input2.sourceError instanceof DeeplineError ? input2.sourceError : null;
10888
+ const code = sourceError?.code && sourceError.code !== "API_ERROR" ? sourceError.code : "PLAY_NOT_FOUND";
10889
+ return new DeeplineError(
10890
+ buildPlayReferenceNotFoundMessage({
10891
+ requested: input2.target,
10892
+ command: input2.command,
10893
+ suggestions
10894
+ }),
10895
+ sourceError?.statusCode ?? 404,
10896
+ code,
10897
+ sourceError?.details
10731
10898
  );
10732
10899
  }
10733
- async function assertCanonicalNamedPlayReference(client2, target) {
10900
+ async function isMissingRunPlayReferenceError(input2) {
10901
+ if (isExplicitMissingPlayReferenceError(input2.error)) {
10902
+ return true;
10903
+ }
10904
+ if (!(input2.error instanceof DeeplineError) || input2.error.statusCode !== 404 || !/^no artifact-backed revision found for play:/i.test(
10905
+ input2.error.message.trim()
10906
+ )) {
10907
+ return false;
10908
+ }
10909
+ try {
10910
+ await input2.client.getPlay(parseReferencedPlayTarget2(input2.playName).playName);
10911
+ return false;
10912
+ } catch (lookupError) {
10913
+ return isPlayNotFoundError(lookupError);
10914
+ }
10915
+ }
10916
+ async function assertCanonicalNamedPlayReference(client2, target, options = {}) {
10734
10917
  const parsed = parseReferencedPlayTarget2(target);
10735
- const detail = await client2.getPlay(parsed.playName);
10918
+ let detail;
10919
+ try {
10920
+ detail = await client2.getPlay(parsed.playName);
10921
+ } catch (error) {
10922
+ if (isPlayNotFoundError(error)) {
10923
+ throw await buildPlayReferenceNotFoundError({
10924
+ client: client2,
10925
+ target,
10926
+ command: options.command ?? "describe",
10927
+ sourceError: error
10928
+ });
10929
+ }
10930
+ throw error;
10931
+ }
10736
10932
  if (detail.play.ownerType === "deepline" && !isPrebuiltReferenceTarget(target)) {
10737
10933
  throw buildBarePrebuiltReferenceError({
10738
10934
  requested: target,
@@ -13468,10 +13664,7 @@ async function exportPlayStatusRows(client2, status, outPath, options = {}) {
13468
13664
  availableRows,
13469
13665
  datasetPath: options.datasetPath
13470
13666
  });
13471
- return {
13472
- path: writeCanonicalRowsCsv(guarded2, outPath),
13473
- rowsInfo: guarded2
13474
- };
13667
+ return { path: writeCanonicalRowsCsv(guarded2, outPath), rowsInfo: guarded2 };
13475
13668
  }
13476
13669
  if (rowsInfo.complete) {
13477
13670
  const guarded2 = assertDatasetHasExportableRows({
@@ -13480,7 +13673,10 @@ async function exportPlayStatusRows(client2, status, outPath, options = {}) {
13480
13673
  availableRows,
13481
13674
  datasetPath: options.datasetPath
13482
13675
  });
13483
- return { path: writeCanonicalRowsCsv(guarded2, outPath), rowsInfo: guarded2 };
13676
+ return {
13677
+ path: writeCanonicalRowsCsv(guarded2, outPath),
13678
+ rowsInfo: guarded2
13679
+ };
13484
13680
  }
13485
13681
  if (attempt < attempts && retryDelayMs > 0) {
13486
13682
  await sleep5(retryDelayMs);
@@ -13614,17 +13810,25 @@ function normalizePlayValidationError(error) {
13614
13810
  error instanceof DeeplineError ? error.details : void 0
13615
13811
  );
13616
13812
  }
13617
- function normalizePlayStartError(error, playName) {
13813
+ async function normalizePlayStartError(client2, error, playName, options = {}) {
13618
13814
  const activeRuns = extractActiveRunsFromError(error);
13619
- if (activeRuns.length === 0) {
13620
- return normalizePlayValidationError(error);
13815
+ if (activeRuns.length > 0) {
13816
+ return new DeeplineError(
13817
+ formatActiveRunConflictError({ playName, activeRuns }),
13818
+ error instanceof DeeplineError ? error.statusCode : 409,
13819
+ "ACTIVE_RUN_EXISTS",
13820
+ error instanceof DeeplineError ? error.details : void 0
13821
+ );
13621
13822
  }
13622
- return new DeeplineError(
13623
- formatActiveRunConflictError({ playName, activeRuns }),
13624
- error instanceof DeeplineError ? error.statusCode : 409,
13625
- "ACTIVE_RUN_EXISTS",
13626
- error instanceof DeeplineError ? error.details : void 0
13627
- );
13823
+ if (options.suggestMissingPlay && await isMissingRunPlayReferenceError({ client: client2, error, playName })) {
13824
+ return buildPlayReferenceNotFoundError({
13825
+ client: client2,
13826
+ target: playName,
13827
+ command: "run",
13828
+ sourceError: error
13829
+ });
13830
+ }
13831
+ return normalizePlayValidationError(error);
13628
13832
  }
13629
13833
  function renderServerResultView(value) {
13630
13834
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -14137,7 +14341,9 @@ async function handlePlayCheck(args) {
14137
14341
  if (!isFileTarget(options.target)) {
14138
14342
  const client3 = new DeeplineClient();
14139
14343
  try {
14140
- await assertCanonicalNamedPlayReference(client3, options.target);
14344
+ await assertCanonicalNamedPlayReference(client3, options.target, {
14345
+ command: "check"
14346
+ });
14141
14347
  const play = await client3.describePlay(
14142
14348
  parseReferencedPlayTarget2(options.target).playName,
14143
14349
  { compact: true }
@@ -14407,8 +14613,8 @@ async function handleFileBackedRun(options) {
14407
14613
  waitTimeoutMs: options.waitTimeoutMs,
14408
14614
  noOpen: options.noOpen,
14409
14615
  progress
14410
- }).catch((error) => {
14411
- throw normalizePlayStartError(error, playName);
14616
+ }).catch(async (error) => {
14617
+ throw await normalizePlayStartError(client2, error, playName);
14412
14618
  })
14413
14619
  );
14414
14620
  if (finalStatus.status === "completed") {
@@ -14438,8 +14644,8 @@ async function handleFileBackedRun(options) {
14438
14644
  const started = await traceCliSpan(
14439
14645
  "cli.play_start_unwatched",
14440
14646
  { targetKind: "file", playName },
14441
- () => client2.startPlayRun(startRequest).catch((error) => {
14442
- throw normalizePlayStartError(error, playName);
14647
+ () => client2.startPlayRun(startRequest).catch(async (error) => {
14648
+ throw await normalizePlayStartError(client2, error, playName);
14443
14649
  })
14444
14650
  );
14445
14651
  const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
@@ -14497,7 +14703,9 @@ async function handleNamedRun(options) {
14497
14703
  return traceCliSpan(
14498
14704
  "cli.play_load_definition",
14499
14705
  { targetKind: "name", playName, skipped: false },
14500
- () => assertCanonicalNamedPlayReference(client2, playName)
14706
+ () => assertCanonicalNamedPlayReference(client2, playName, {
14707
+ command: "run"
14708
+ })
14501
14709
  );
14502
14710
  })() : (recordCliTrace({
14503
14711
  phase: "cli.play_load_definition",
@@ -14566,8 +14774,10 @@ async function handleNamedRun(options) {
14566
14774
  waitTimeoutMs: options.waitTimeoutMs,
14567
14775
  noOpen: options.noOpen,
14568
14776
  progress
14569
- }).catch((error) => {
14570
- throw normalizePlayStartError(error, playName);
14777
+ }).catch(async (error) => {
14778
+ throw await normalizePlayStartError(client2, error, playName, {
14779
+ suggestMissingPlay: true
14780
+ });
14571
14781
  })
14572
14782
  );
14573
14783
  if (finalStatus.status === "completed") {
@@ -14597,8 +14807,10 @@ async function handleNamedRun(options) {
14597
14807
  const started = await traceCliSpan(
14598
14808
  "cli.play_start_unwatched",
14599
14809
  { targetKind: "name", playName },
14600
- () => client2.startPlayRun(startRequest).catch((error) => {
14601
- throw normalizePlayStartError(error, playName);
14810
+ () => client2.startPlayRun(startRequest).catch(async (error) => {
14811
+ throw await normalizePlayStartError(client2, error, playName, {
14812
+ suggestMissingPlay: true
14813
+ });
14602
14814
  })
14603
14815
  );
14604
14816
  const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
@@ -15037,7 +15249,9 @@ async function handlePlayGet(args) {
15037
15249
  }
15038
15250
  }
15039
15251
  const playName = isFileTarget(target) ? extractPlayName((0, import_node_fs10.readFileSync)((0, import_node_path11.resolve)(target), "utf-8"), (0, import_node_path11.resolve)(target)) : parseReferencedPlayTarget2(target).playName;
15040
- const detail = isFileTarget(target) ? await client2.getPlay(playName) : await assertCanonicalNamedPlayReference(client2, target);
15252
+ const detail = isFileTarget(target) ? await client2.getPlay(playName) : await assertCanonicalNamedPlayReference(client2, target, {
15253
+ command: "get"
15254
+ });
15041
15255
  const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
15042
15256
  const materializedFile = outPath ? materializeRemotePlaySource({
15043
15257
  target,
@@ -15119,7 +15333,9 @@ async function handlePlayVersions(args) {
15119
15333
  }
15120
15334
  const client2 = new DeeplineClient();
15121
15335
  const jsonOutput = argsWantJson(args);
15122
- await assertCanonicalNamedPlayReference(client2, playName);
15336
+ await assertCanonicalNamedPlayReference(client2, playName, {
15337
+ command: "versions"
15338
+ });
15123
15339
  const versions = await client2.listPlayVersions(
15124
15340
  parseReferencedPlayTarget2(playName).playName
15125
15341
  );
@@ -15515,7 +15731,9 @@ async function handlePlayDescribe(args) {
15515
15731
  return 2;
15516
15732
  }
15517
15733
  const client2 = new DeeplineClient();
15518
- await assertCanonicalNamedPlayReference(client2, playName);
15734
+ await assertCanonicalNamedPlayReference(client2, playName, {
15735
+ command: "describe"
15736
+ });
15519
15737
  const play = await client2.describePlay(
15520
15738
  parseReferencedPlayTarget2(playName).playName,
15521
15739
  {
@@ -24023,7 +24241,7 @@ var EXIT_AUTH2 = 1;
24023
24241
  var EXIT_SERVER3 = 2;
24024
24242
  var MAX_PROMPT_LENGTH = 8e3;
24025
24243
  var MAX_BODY_BYTES = 64 * 1024;
24026
- function shellQuote2(arg) {
24244
+ function shellQuote3(arg) {
24027
24245
  return `'${arg.replace(/'/g, `'\\''`)}'`;
24028
24246
  }
24029
24247
  function hasClaudeBinary() {
@@ -24196,7 +24414,7 @@ async function handleQuickstart(options) {
24196
24414
  }
24197
24415
  progress.complete();
24198
24416
  const { prompt, workflowId } = outcome;
24199
- const claudeCommand = `claude ${shellQuote2(prompt)}`;
24417
+ const claudeCommand = `claude ${shellQuote3(prompt)}`;
24200
24418
  const claudeAvailable = hasClaudeBinary();
24201
24419
  const willLaunch = options.launch !== false && !jsonOutput && interactive && claudeAvailable;
24202
24420
  printCommandEnvelope(
@@ -26118,7 +26336,7 @@ function parseExecuteOptions(args) {
26118
26336
  function safeFileStem(value) {
26119
26337
  return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
26120
26338
  }
26121
- function shellQuote3(value) {
26339
+ function shellQuote4(value) {
26122
26340
  return `'${value.replace(/'/g, `'\\''`)}'`;
26123
26341
  }
26124
26342
  function powerShellQuote(value) {
@@ -26188,7 +26406,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
26188
26406
  path: scriptPath,
26189
26407
  sourceCode: script,
26190
26408
  projectDir,
26191
- macCopyCommand: `mkdir -p ${shellQuote3(projectDir)} && cp ${shellQuote3(scriptPath)} ${shellQuote3(`${projectDir}/${fileName}`)}`,
26409
+ macCopyCommand: `mkdir -p ${shellQuote4(projectDir)} && cp ${shellQuote4(scriptPath)} ${shellQuote4(`${projectDir}/${fileName}`)}`,
26192
26410
  windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
26193
26411
  };
26194
26412
  }
@@ -26211,7 +26429,7 @@ function buildToolExecuteBaseEnvelope(input2) {
26211
26429
  envelope,
26212
26430
  "output"
26213
26431
  );
26214
- const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote3(JSON.stringify(input2.params))} --json`;
26432
+ const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote4(JSON.stringify(input2.params))} --json`;
26215
26433
  const actions = input2.listConversion ? [
26216
26434
  {
26217
26435
  label: "next",
@@ -27280,7 +27498,7 @@ function hasCommand(command) {
27280
27498
  });
27281
27499
  return result.status === 0;
27282
27500
  }
27283
- function shellQuote4(arg) {
27501
+ function shellQuote5(arg) {
27284
27502
  return `'${arg.replace(/'/g, `'\\''`)}'`;
27285
27503
  }
27286
27504
  function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
@@ -27288,7 +27506,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
27288
27506
  const npxInstall = {
27289
27507
  command: "npx",
27290
27508
  args: npxArgs,
27291
- manualCommand: `npx ${npxArgs.map(shellQuote4).join(" ")}`
27509
+ manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
27292
27510
  };
27293
27511
  if (hasCommand("bunx")) {
27294
27512
  const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames);
@@ -27296,7 +27514,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
27296
27514
  {
27297
27515
  command: "bunx",
27298
27516
  args: bunxArgs,
27299
- manualCommand: `bunx ${bunxArgs.map(shellQuote4).join(" ")}`
27517
+ manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
27300
27518
  },
27301
27519
  npxInstall
27302
27520
  ];
@@ -27463,14 +27681,14 @@ function posixShellQuote(value) {
27463
27681
  function windowsCmdQuote(value) {
27464
27682
  return `"${value.replace(/"/g, '""')}"`;
27465
27683
  }
27466
- function shellQuote5(value) {
27684
+ function shellQuote6(value) {
27467
27685
  if (process.platform === "win32") {
27468
27686
  return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
27469
27687
  }
27470
27688
  return posixShellQuote(value);
27471
27689
  }
27472
27690
  function buildSourceUpdateCommand(sourceRoot) {
27473
- const quotedRoot = shellQuote5(sourceRoot);
27691
+ const quotedRoot = shellQuote6(sourceRoot);
27474
27692
  const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
27475
27693
  return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
27476
27694
  }
@@ -27482,7 +27700,7 @@ function buildSidecarProjectConfigCommand(versionDir, nodeBin) {
27482
27700
  "fs.mkdirSync(dir,{recursive:true});",
27483
27701
  `fs.writeFileSync(path.join(dir,'package.json'),${JSON.stringify(NPM_SDK_SIDECAR_PACKAGE_JSON)});`
27484
27702
  ].join("");
27485
- return `${shellQuote5(nodeBin)} -e ${shellQuote5(script)} ${shellQuote5(versionDir)}`;
27703
+ return `${shellQuote6(nodeBin)} -e ${shellQuote6(script)} ${shellQuote6(versionDir)}`;
27486
27704
  }
27487
27705
  function sidecarStateDir(input2) {
27488
27706
  const scope = input2.env.DEEPLINE_CONFIG_SCOPE?.trim();
@@ -27521,7 +27739,7 @@ function resolvePythonSidecarUpdatePlan(options) {
27521
27739
  const packageSpec = options.packageSpec || "deepline@latest";
27522
27740
  const npmCommand = "npm";
27523
27741
  const versionDir = (0, import_node_path19.join)(stateDir, "versions", "<version>");
27524
- const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote5(versionDir)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote5).join(" ")} ${shellQuote5(packageSpec)}`;
27742
+ const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote6(versionDir)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote6).join(" ")} ${shellQuote6(packageSpec)}`;
27525
27743
  return {
27526
27744
  kind: "python-sidecar",
27527
27745
  stateDir,
@@ -27601,7 +27819,7 @@ function resolveUpdatePlan(options = {}) {
27601
27819
  command,
27602
27820
  args,
27603
27821
  ...installPrefix ? { installPrefix } : {},
27604
- manualCommand: `${command} ${args.map(shellQuote5).join(" ")}`
27822
+ manualCommand: `${command} ${args.map(shellQuote6).join(" ")}`
27605
27823
  };
27606
27824
  }
27607
27825
  var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
@@ -27762,9 +27980,9 @@ function writeSidecarLauncher(input2) {
27762
27980
  input2.path,
27763
27981
  [
27764
27982
  "#!/usr/bin/env sh",
27765
- `export DEEPLINE_HOST_URL=${shellQuote5(input2.hostUrl)}`,
27766
- `export DEEPLINE_CONFIG_SCOPE=${shellQuote5(input2.scope)}`,
27767
- `exec ${shellQuote5(input2.nodeBin)} ${shellQuote5(input2.entryPath)} "$@"`,
27983
+ `export DEEPLINE_HOST_URL=${shellQuote6(input2.hostUrl)}`,
27984
+ `export DEEPLINE_CONFIG_SCOPE=${shellQuote6(input2.scope)}`,
27985
+ `exec ${shellQuote6(input2.nodeBin)} ${shellQuote6(input2.entryPath)} "$@"`,
27768
27986
  ""
27769
27987
  ].join("\n"),
27770
27988
  { encoding: "utf8", mode: 493 }
@@ -608,10 +608,10 @@ 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
- version: "0.1.197",
611
+ version: "0.1.199",
612
612
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
613
613
  supportPolicy: {
614
- latest: "0.1.197",
614
+ latest: "0.1.199",
615
615
  minimumSupported: "0.1.53",
616
616
  deprecatedBelow: "0.1.53",
617
617
  commandMinimumSupported: [
@@ -6132,16 +6132,7 @@ async function handleHistory(options) {
6132
6132
  `/api/v2/billing/ledger?since_at=${sinceAt}&limit=5000`
6133
6133
  );
6134
6134
  const entries = Array.isArray(payload.entries) ? payload.entries : [];
6135
- const rows = entries.map((entry) => {
6136
- const metadata = entry.metadata ?? {};
6137
- return {
6138
- created_at: entry.created_at ?? "",
6139
- delta_credits: entry.delta ?? "",
6140
- reason: entry.reason ?? "",
6141
- provider: metadata.provider ?? "",
6142
- operation: metadata.operation ?? ""
6143
- };
6144
- });
6135
+ const rows = entries.map(ledgerApiEntryToRow);
6145
6136
  const outputPath = await writeCsvRowsFile(
6146
6137
  `billing-history-${options.time}`,
6147
6138
  rows
@@ -10754,14 +10745,219 @@ function parseReferencedPlayTarget2(target) {
10754
10745
  function isPrebuiltReferenceTarget(target) {
10755
10746
  return target.trim().toLowerCase().startsWith("prebuilt/");
10756
10747
  }
10748
+ function buildBarePrebuiltReferenceMessage(input2) {
10749
+ return `Prebuilt play "${input2.requested}" must be referenced as "${input2.reference}". Use the prebuilt/ namespace anywhere you run, describe, get, or link to Deepline-managed plays.`;
10750
+ }
10757
10751
  function buildBarePrebuiltReferenceError(input2) {
10758
- return new Error(
10759
- `Prebuilt play "${input2.requested}" must be referenced as "${input2.reference}". Use the prebuilt/ namespace anywhere you run, describe, get, or link to Deepline-managed plays.`
10752
+ return new Error(buildBarePrebuiltReferenceMessage(input2));
10753
+ }
10754
+ function isPlayNotFoundError(error) {
10755
+ return error instanceof DeeplineError && (error.statusCode === 404 || error.code === "PLAY_NOT_FOUND" || error.code === "NOT_FOUND");
10756
+ }
10757
+ function isExplicitMissingPlayReferenceError(error) {
10758
+ if (!(error instanceof DeeplineError)) {
10759
+ return false;
10760
+ }
10761
+ if (error.statusCode !== 404 && error.code !== "PLAY_NOT_FOUND") {
10762
+ return false;
10763
+ }
10764
+ return /^play not found\b/i.test(error.message.trim());
10765
+ }
10766
+ function normalizePlayReferenceForMatch(value) {
10767
+ return value.trim().toLowerCase().replace(/^prebuilt\//, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
10768
+ }
10769
+ function playReferenceMatchTokens(value) {
10770
+ return normalizePlayReferenceForMatch(value).split("-").filter((token) => token.length > 1 && token !== "to" && token !== "and");
10771
+ }
10772
+ function playSuggestionReference(play) {
10773
+ if (play.reference?.trim()) {
10774
+ return play.reference.trim();
10775
+ }
10776
+ const ownerSlug = play.ownerSlug?.trim();
10777
+ return ownerSlug ? `${ownerSlug}/${play.name}` : play.name;
10778
+ }
10779
+ function scorePlayReferenceSuggestion(requested, play) {
10780
+ const parsed = parseReferencedPlayTarget2(requested);
10781
+ const requestedTrimmed = requested.trim();
10782
+ const requestedRef = requestedTrimmed.toLowerCase();
10783
+ const requestedName = parsed.unqualifiedPlayName;
10784
+ const requestedNorm = normalizePlayReferenceForMatch(requestedTrimmed);
10785
+ const requestedNameNorm = normalizePlayReferenceForMatch(requestedName);
10786
+ if (!requestedNorm && !requestedNameNorm) {
10787
+ return null;
10788
+ }
10789
+ const reference = playSuggestionReference(play);
10790
+ const referenceNorm = normalizePlayReferenceForMatch(reference);
10791
+ const nameNorm = normalizePlayReferenceForMatch(play.name);
10792
+ const candidateNamespace = reference.includes("/") ? reference.split("/")[0]?.toLowerCase() : null;
10793
+ const requestedNamespace = parsed.ownerSlug?.toLowerCase() ?? null;
10794
+ const aliases = (play.aliases ?? []).map(normalizePlayReferenceForMatch);
10795
+ const searchable = [referenceNorm, nameNorm, ...aliases].filter(Boolean);
10796
+ const requestedTokens = playReferenceMatchTokens(requestedName);
10797
+ const candidateTokens = [
10798
+ ...new Set(
10799
+ [reference, play.name, ...play.aliases ?? []].flatMap(
10800
+ playReferenceMatchTokens
10801
+ )
10802
+ )
10803
+ ];
10804
+ const hasTokenContainment = requestedTokens.length > 0 && requestedTokens.every((token) => candidateTokens.includes(token));
10805
+ let score = 0;
10806
+ if (reference.toLowerCase() === requestedRef) {
10807
+ score = 120;
10808
+ } else if (requestedNamespace && candidateNamespace === requestedNamespace && nameNorm === requestedNameNorm) {
10809
+ score = 110;
10810
+ } else if (nameNorm === requestedNameNorm || aliases.includes(requestedNameNorm)) {
10811
+ score = play.origin === "prebuilt" ? 100 : 95;
10812
+ } else if (requestedNamespace && candidateNamespace === requestedNamespace && searchable.some(
10813
+ (value) => value.includes(requestedNameNorm) || requestedNameNorm.includes(value)
10814
+ )) {
10815
+ score = 85;
10816
+ } else if (searchable.some(
10817
+ (value) => value.includes(requestedNorm) || requestedNorm.includes(value)
10818
+ )) {
10819
+ score = 70;
10820
+ } else if (requestedNameNorm && searchable.some(
10821
+ (value) => value.includes(requestedNameNorm) || requestedNameNorm.includes(value)
10822
+ )) {
10823
+ score = 60;
10824
+ } else if (hasTokenContainment) {
10825
+ score = requestedNamespace && candidateNamespace === requestedNamespace ? 58 : 50;
10826
+ }
10827
+ if (score <= 0) {
10828
+ return null;
10829
+ }
10830
+ if (play.origin === "prebuilt") {
10831
+ score += 3;
10832
+ }
10833
+ return {
10834
+ reference,
10835
+ name: play.name,
10836
+ origin: play.origin ?? null,
10837
+ score
10838
+ };
10839
+ }
10840
+ function rankPlayReferenceSuggestions(input2) {
10841
+ const byReference = /* @__PURE__ */ new Map();
10842
+ for (const play of input2.plays) {
10843
+ const suggestion = scorePlayReferenceSuggestion(input2.requested, play);
10844
+ if (!suggestion) continue;
10845
+ const existing = byReference.get(suggestion.reference);
10846
+ if (!existing || suggestion.score > existing.score) {
10847
+ byReference.set(suggestion.reference, suggestion);
10848
+ }
10849
+ }
10850
+ return [...byReference.values()].sort((left, right) => {
10851
+ if (right.score !== left.score) return right.score - left.score;
10852
+ if (left.origin === "prebuilt" && right.origin !== "prebuilt") return -1;
10853
+ if (right.origin === "prebuilt" && left.origin !== "prebuilt") return 1;
10854
+ return left.reference.localeCompare(right.reference);
10855
+ }).slice(0, input2.limit ?? 5);
10856
+ }
10857
+ function searchQueryForMissingPlayReference(target) {
10858
+ return parseReferencedPlayTarget2(target).unqualifiedPlayName.replace(/[-_./]+/g, " ").replace(/\s+/g, " ").trim();
10859
+ }
10860
+ function shellQuote2(value) {
10861
+ return `'${value.replace(/'/g, `'\\''`)}'`;
10862
+ }
10863
+ function buildPlayReferenceNotFoundMessage(input2) {
10864
+ const lines = [`Play not found: ${input2.requested}`];
10865
+ if (input2.suggestions.length > 0) {
10866
+ lines.push("", "Did you mean one of these?");
10867
+ for (const suggestion of input2.suggestions) {
10868
+ lines.push("", ` ${suggestion.reference}`);
10869
+ if (input2.command === "run") {
10870
+ lines.push(
10871
+ ` deepline plays run ${suggestion.reference} --input '{...}' --watch`
10872
+ );
10873
+ } else if (input2.command === "get") {
10874
+ lines.push(` deepline plays get ${suggestion.reference} --json`);
10875
+ } else if (input2.command === "check") {
10876
+ lines.push(` deepline plays check ${suggestion.reference} --json`);
10877
+ } else if (input2.command === "versions") {
10878
+ lines.push(
10879
+ ` deepline plays versions --name ${suggestion.reference} --json`
10880
+ );
10881
+ } else {
10882
+ lines.push(
10883
+ ` deepline plays describe ${suggestion.reference} --json`
10884
+ );
10885
+ }
10886
+ }
10887
+ }
10888
+ const searchQuery = searchQueryForMissingPlayReference(input2.requested);
10889
+ if (searchQuery) {
10890
+ lines.push(
10891
+ "",
10892
+ "Search visible plays:",
10893
+ ` deepline plays search ${shellQuote2(searchQuery)} --all --json`
10894
+ );
10895
+ }
10896
+ return lines.join("\n");
10897
+ }
10898
+ async function buildPlayReferenceNotFoundError(input2) {
10899
+ let suggestions = [];
10900
+ try {
10901
+ const searchQuery = searchQueryForMissingPlayReference(input2.target);
10902
+ const searchMatches = searchQuery ? await input2.client.searchPlays({
10903
+ query: searchQuery,
10904
+ scope: "all",
10905
+ compact: true
10906
+ }) : [];
10907
+ const plays = searchMatches.length > 0 ? searchMatches : await input2.client.listPlays();
10908
+ suggestions = rankPlayReferenceSuggestions({
10909
+ requested: input2.target,
10910
+ plays,
10911
+ limit: 5
10912
+ });
10913
+ } catch {
10914
+ suggestions = [];
10915
+ }
10916
+ const sourceError = input2.sourceError instanceof DeeplineError ? input2.sourceError : null;
10917
+ const code = sourceError?.code && sourceError.code !== "API_ERROR" ? sourceError.code : "PLAY_NOT_FOUND";
10918
+ return new DeeplineError(
10919
+ buildPlayReferenceNotFoundMessage({
10920
+ requested: input2.target,
10921
+ command: input2.command,
10922
+ suggestions
10923
+ }),
10924
+ sourceError?.statusCode ?? 404,
10925
+ code,
10926
+ sourceError?.details
10760
10927
  );
10761
10928
  }
10762
- async function assertCanonicalNamedPlayReference(client2, target) {
10929
+ async function isMissingRunPlayReferenceError(input2) {
10930
+ if (isExplicitMissingPlayReferenceError(input2.error)) {
10931
+ return true;
10932
+ }
10933
+ if (!(input2.error instanceof DeeplineError) || input2.error.statusCode !== 404 || !/^no artifact-backed revision found for play:/i.test(
10934
+ input2.error.message.trim()
10935
+ )) {
10936
+ return false;
10937
+ }
10938
+ try {
10939
+ await input2.client.getPlay(parseReferencedPlayTarget2(input2.playName).playName);
10940
+ return false;
10941
+ } catch (lookupError) {
10942
+ return isPlayNotFoundError(lookupError);
10943
+ }
10944
+ }
10945
+ async function assertCanonicalNamedPlayReference(client2, target, options = {}) {
10763
10946
  const parsed = parseReferencedPlayTarget2(target);
10764
- const detail = await client2.getPlay(parsed.playName);
10947
+ let detail;
10948
+ try {
10949
+ detail = await client2.getPlay(parsed.playName);
10950
+ } catch (error) {
10951
+ if (isPlayNotFoundError(error)) {
10952
+ throw await buildPlayReferenceNotFoundError({
10953
+ client: client2,
10954
+ target,
10955
+ command: options.command ?? "describe",
10956
+ sourceError: error
10957
+ });
10958
+ }
10959
+ throw error;
10960
+ }
10765
10961
  if (detail.play.ownerType === "deepline" && !isPrebuiltReferenceTarget(target)) {
10766
10962
  throw buildBarePrebuiltReferenceError({
10767
10963
  requested: target,
@@ -13497,10 +13693,7 @@ async function exportPlayStatusRows(client2, status, outPath, options = {}) {
13497
13693
  availableRows,
13498
13694
  datasetPath: options.datasetPath
13499
13695
  });
13500
- return {
13501
- path: writeCanonicalRowsCsv(guarded2, outPath),
13502
- rowsInfo: guarded2
13503
- };
13696
+ return { path: writeCanonicalRowsCsv(guarded2, outPath), rowsInfo: guarded2 };
13504
13697
  }
13505
13698
  if (rowsInfo.complete) {
13506
13699
  const guarded2 = assertDatasetHasExportableRows({
@@ -13509,7 +13702,10 @@ async function exportPlayStatusRows(client2, status, outPath, options = {}) {
13509
13702
  availableRows,
13510
13703
  datasetPath: options.datasetPath
13511
13704
  });
13512
- return { path: writeCanonicalRowsCsv(guarded2, outPath), rowsInfo: guarded2 };
13705
+ return {
13706
+ path: writeCanonicalRowsCsv(guarded2, outPath),
13707
+ rowsInfo: guarded2
13708
+ };
13513
13709
  }
13514
13710
  if (attempt < attempts && retryDelayMs > 0) {
13515
13711
  await sleep5(retryDelayMs);
@@ -13643,17 +13839,25 @@ function normalizePlayValidationError(error) {
13643
13839
  error instanceof DeeplineError ? error.details : void 0
13644
13840
  );
13645
13841
  }
13646
- function normalizePlayStartError(error, playName) {
13842
+ async function normalizePlayStartError(client2, error, playName, options = {}) {
13647
13843
  const activeRuns = extractActiveRunsFromError(error);
13648
- if (activeRuns.length === 0) {
13649
- return normalizePlayValidationError(error);
13844
+ if (activeRuns.length > 0) {
13845
+ return new DeeplineError(
13846
+ formatActiveRunConflictError({ playName, activeRuns }),
13847
+ error instanceof DeeplineError ? error.statusCode : 409,
13848
+ "ACTIVE_RUN_EXISTS",
13849
+ error instanceof DeeplineError ? error.details : void 0
13850
+ );
13650
13851
  }
13651
- return new DeeplineError(
13652
- formatActiveRunConflictError({ playName, activeRuns }),
13653
- error instanceof DeeplineError ? error.statusCode : 409,
13654
- "ACTIVE_RUN_EXISTS",
13655
- error instanceof DeeplineError ? error.details : void 0
13656
- );
13852
+ if (options.suggestMissingPlay && await isMissingRunPlayReferenceError({ client: client2, error, playName })) {
13853
+ return buildPlayReferenceNotFoundError({
13854
+ client: client2,
13855
+ target: playName,
13856
+ command: "run",
13857
+ sourceError: error
13858
+ });
13859
+ }
13860
+ return normalizePlayValidationError(error);
13657
13861
  }
13658
13862
  function renderServerResultView(value) {
13659
13863
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -14166,7 +14370,9 @@ async function handlePlayCheck(args) {
14166
14370
  if (!isFileTarget(options.target)) {
14167
14371
  const client3 = new DeeplineClient();
14168
14372
  try {
14169
- await assertCanonicalNamedPlayReference(client3, options.target);
14373
+ await assertCanonicalNamedPlayReference(client3, options.target, {
14374
+ command: "check"
14375
+ });
14170
14376
  const play = await client3.describePlay(
14171
14377
  parseReferencedPlayTarget2(options.target).playName,
14172
14378
  { compact: true }
@@ -14436,8 +14642,8 @@ async function handleFileBackedRun(options) {
14436
14642
  waitTimeoutMs: options.waitTimeoutMs,
14437
14643
  noOpen: options.noOpen,
14438
14644
  progress
14439
- }).catch((error) => {
14440
- throw normalizePlayStartError(error, playName);
14645
+ }).catch(async (error) => {
14646
+ throw await normalizePlayStartError(client2, error, playName);
14441
14647
  })
14442
14648
  );
14443
14649
  if (finalStatus.status === "completed") {
@@ -14467,8 +14673,8 @@ async function handleFileBackedRun(options) {
14467
14673
  const started = await traceCliSpan(
14468
14674
  "cli.play_start_unwatched",
14469
14675
  { targetKind: "file", playName },
14470
- () => client2.startPlayRun(startRequest).catch((error) => {
14471
- throw normalizePlayStartError(error, playName);
14676
+ () => client2.startPlayRun(startRequest).catch(async (error) => {
14677
+ throw await normalizePlayStartError(client2, error, playName);
14472
14678
  })
14473
14679
  );
14474
14680
  const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
@@ -14526,7 +14732,9 @@ async function handleNamedRun(options) {
14526
14732
  return traceCliSpan(
14527
14733
  "cli.play_load_definition",
14528
14734
  { targetKind: "name", playName, skipped: false },
14529
- () => assertCanonicalNamedPlayReference(client2, playName)
14735
+ () => assertCanonicalNamedPlayReference(client2, playName, {
14736
+ command: "run"
14737
+ })
14530
14738
  );
14531
14739
  })() : (recordCliTrace({
14532
14740
  phase: "cli.play_load_definition",
@@ -14595,8 +14803,10 @@ async function handleNamedRun(options) {
14595
14803
  waitTimeoutMs: options.waitTimeoutMs,
14596
14804
  noOpen: options.noOpen,
14597
14805
  progress
14598
- }).catch((error) => {
14599
- throw normalizePlayStartError(error, playName);
14806
+ }).catch(async (error) => {
14807
+ throw await normalizePlayStartError(client2, error, playName, {
14808
+ suggestMissingPlay: true
14809
+ });
14600
14810
  })
14601
14811
  );
14602
14812
  if (finalStatus.status === "completed") {
@@ -14626,8 +14836,10 @@ async function handleNamedRun(options) {
14626
14836
  const started = await traceCliSpan(
14627
14837
  "cli.play_start_unwatched",
14628
14838
  { targetKind: "name", playName },
14629
- () => client2.startPlayRun(startRequest).catch((error) => {
14630
- throw normalizePlayStartError(error, playName);
14839
+ () => client2.startPlayRun(startRequest).catch(async (error) => {
14840
+ throw await normalizePlayStartError(client2, error, playName, {
14841
+ suggestMissingPlay: true
14842
+ });
14631
14843
  })
14632
14844
  );
14633
14845
  const resolvedDashboardUrl = buildPlayDashboardUrl(client2.baseUrl, playName);
@@ -15066,7 +15278,9 @@ async function handlePlayGet(args) {
15066
15278
  }
15067
15279
  }
15068
15280
  const playName = isFileTarget(target) ? extractPlayName(readFileSync7(resolve8(target), "utf-8"), resolve8(target)) : parseReferencedPlayTarget2(target).playName;
15069
- const detail = isFileTarget(target) ? await client2.getPlay(playName) : await assertCanonicalNamedPlayReference(client2, target);
15281
+ const detail = isFileTarget(target) ? await client2.getPlay(playName) : await assertCanonicalNamedPlayReference(client2, target, {
15282
+ command: "get"
15283
+ });
15070
15284
  const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
15071
15285
  const materializedFile = outPath ? materializeRemotePlaySource({
15072
15286
  target,
@@ -15148,7 +15362,9 @@ async function handlePlayVersions(args) {
15148
15362
  }
15149
15363
  const client2 = new DeeplineClient();
15150
15364
  const jsonOutput = argsWantJson(args);
15151
- await assertCanonicalNamedPlayReference(client2, playName);
15365
+ await assertCanonicalNamedPlayReference(client2, playName, {
15366
+ command: "versions"
15367
+ });
15152
15368
  const versions = await client2.listPlayVersions(
15153
15369
  parseReferencedPlayTarget2(playName).playName
15154
15370
  );
@@ -15544,7 +15760,9 @@ async function handlePlayDescribe(args) {
15544
15760
  return 2;
15545
15761
  }
15546
15762
  const client2 = new DeeplineClient();
15547
- await assertCanonicalNamedPlayReference(client2, playName);
15763
+ await assertCanonicalNamedPlayReference(client2, playName, {
15764
+ command: "describe"
15765
+ });
15548
15766
  const play = await client2.describePlay(
15549
15767
  parseReferencedPlayTarget2(playName).playName,
15550
15768
  {
@@ -24059,7 +24277,7 @@ var EXIT_AUTH2 = 1;
24059
24277
  var EXIT_SERVER3 = 2;
24060
24278
  var MAX_PROMPT_LENGTH = 8e3;
24061
24279
  var MAX_BODY_BYTES = 64 * 1024;
24062
- function shellQuote2(arg) {
24280
+ function shellQuote3(arg) {
24063
24281
  return `'${arg.replace(/'/g, `'\\''`)}'`;
24064
24282
  }
24065
24283
  function hasClaudeBinary() {
@@ -24232,7 +24450,7 @@ async function handleQuickstart(options) {
24232
24450
  }
24233
24451
  progress.complete();
24234
24452
  const { prompt, workflowId } = outcome;
24235
- const claudeCommand = `claude ${shellQuote2(prompt)}`;
24453
+ const claudeCommand = `claude ${shellQuote3(prompt)}`;
24236
24454
  const claudeAvailable = hasClaudeBinary();
24237
24455
  const willLaunch = options.launch !== false && !jsonOutput && interactive && claudeAvailable;
24238
24456
  printCommandEnvelope(
@@ -26166,7 +26384,7 @@ function parseExecuteOptions(args) {
26166
26384
  function safeFileStem(value) {
26167
26385
  return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
26168
26386
  }
26169
- function shellQuote3(value) {
26387
+ function shellQuote4(value) {
26170
26388
  return `'${value.replace(/'/g, `'\\''`)}'`;
26171
26389
  }
26172
26390
  function powerShellQuote(value) {
@@ -26236,7 +26454,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
26236
26454
  path: scriptPath,
26237
26455
  sourceCode: script,
26238
26456
  projectDir,
26239
- macCopyCommand: `mkdir -p ${shellQuote3(projectDir)} && cp ${shellQuote3(scriptPath)} ${shellQuote3(`${projectDir}/${fileName}`)}`,
26457
+ macCopyCommand: `mkdir -p ${shellQuote4(projectDir)} && cp ${shellQuote4(scriptPath)} ${shellQuote4(`${projectDir}/${fileName}`)}`,
26240
26458
  windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
26241
26459
  };
26242
26460
  }
@@ -26259,7 +26477,7 @@ function buildToolExecuteBaseEnvelope(input2) {
26259
26477
  envelope,
26260
26478
  "output"
26261
26479
  );
26262
- const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote3(JSON.stringify(input2.params))} --json`;
26480
+ const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote4(JSON.stringify(input2.params))} --json`;
26263
26481
  const actions = input2.listConversion ? [
26264
26482
  {
26265
26483
  label: "next",
@@ -27337,7 +27555,7 @@ function hasCommand(command) {
27337
27555
  });
27338
27556
  return result.status === 0;
27339
27557
  }
27340
- function shellQuote4(arg) {
27558
+ function shellQuote5(arg) {
27341
27559
  return `'${arg.replace(/'/g, `'\\''`)}'`;
27342
27560
  }
27343
27561
  function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
@@ -27345,7 +27563,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
27345
27563
  const npxInstall = {
27346
27564
  command: "npx",
27347
27565
  args: npxArgs,
27348
- manualCommand: `npx ${npxArgs.map(shellQuote4).join(" ")}`
27566
+ manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
27349
27567
  };
27350
27568
  if (hasCommand("bunx")) {
27351
27569
  const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames);
@@ -27353,7 +27571,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
27353
27571
  {
27354
27572
  command: "bunx",
27355
27573
  args: bunxArgs,
27356
- manualCommand: `bunx ${bunxArgs.map(shellQuote4).join(" ")}`
27574
+ manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
27357
27575
  },
27358
27576
  npxInstall
27359
27577
  ];
@@ -27520,14 +27738,14 @@ function posixShellQuote(value) {
27520
27738
  function windowsCmdQuote(value) {
27521
27739
  return `"${value.replace(/"/g, '""')}"`;
27522
27740
  }
27523
- function shellQuote5(value) {
27741
+ function shellQuote6(value) {
27524
27742
  if (process.platform === "win32") {
27525
27743
  return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
27526
27744
  }
27527
27745
  return posixShellQuote(value);
27528
27746
  }
27529
27747
  function buildSourceUpdateCommand(sourceRoot) {
27530
- const quotedRoot = shellQuote5(sourceRoot);
27748
+ const quotedRoot = shellQuote6(sourceRoot);
27531
27749
  const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
27532
27750
  return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
27533
27751
  }
@@ -27539,7 +27757,7 @@ function buildSidecarProjectConfigCommand(versionDir, nodeBin) {
27539
27757
  "fs.mkdirSync(dir,{recursive:true});",
27540
27758
  `fs.writeFileSync(path.join(dir,'package.json'),${JSON.stringify(NPM_SDK_SIDECAR_PACKAGE_JSON)});`
27541
27759
  ].join("");
27542
- return `${shellQuote5(nodeBin)} -e ${shellQuote5(script)} ${shellQuote5(versionDir)}`;
27760
+ return `${shellQuote6(nodeBin)} -e ${shellQuote6(script)} ${shellQuote6(versionDir)}`;
27543
27761
  }
27544
27762
  function sidecarStateDir(input2) {
27545
27763
  const scope = input2.env.DEEPLINE_CONFIG_SCOPE?.trim();
@@ -27578,7 +27796,7 @@ function resolvePythonSidecarUpdatePlan(options) {
27578
27796
  const packageSpec = options.packageSpec || "deepline@latest";
27579
27797
  const npmCommand = "npm";
27580
27798
  const versionDir = join14(stateDir, "versions", "<version>");
27581
- const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote5(versionDir)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote5).join(" ")} ${shellQuote5(packageSpec)}`;
27799
+ const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote6(versionDir)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote6).join(" ")} ${shellQuote6(packageSpec)}`;
27582
27800
  return {
27583
27801
  kind: "python-sidecar",
27584
27802
  stateDir,
@@ -27658,7 +27876,7 @@ function resolveUpdatePlan(options = {}) {
27658
27876
  command,
27659
27877
  args,
27660
27878
  ...installPrefix ? { installPrefix } : {},
27661
- manualCommand: `${command} ${args.map(shellQuote5).join(" ")}`
27879
+ manualCommand: `${command} ${args.map(shellQuote6).join(" ")}`
27662
27880
  };
27663
27881
  }
27664
27882
  var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
@@ -27819,9 +28037,9 @@ function writeSidecarLauncher(input2) {
27819
28037
  input2.path,
27820
28038
  [
27821
28039
  "#!/usr/bin/env sh",
27822
- `export DEEPLINE_HOST_URL=${shellQuote5(input2.hostUrl)}`,
27823
- `export DEEPLINE_CONFIG_SCOPE=${shellQuote5(input2.scope)}`,
27824
- `exec ${shellQuote5(input2.nodeBin)} ${shellQuote5(input2.entryPath)} "$@"`,
28040
+ `export DEEPLINE_HOST_URL=${shellQuote6(input2.hostUrl)}`,
28041
+ `export DEEPLINE_CONFIG_SCOPE=${shellQuote6(input2.scope)}`,
28042
+ `exec ${shellQuote6(input2.nodeBin)} ${shellQuote6(input2.entryPath)} "$@"`,
27825
28043
  ""
27826
28044
  ].join("\n"),
27827
28045
  { encoding: "utf8", mode: 493 }
package/dist/index.js CHANGED
@@ -422,10 +422,10 @@ 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
- version: "0.1.197",
425
+ version: "0.1.199",
426
426
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
427
427
  supportPolicy: {
428
- latest: "0.1.197",
428
+ latest: "0.1.199",
429
429
  minimumSupported: "0.1.53",
430
430
  deprecatedBelow: "0.1.53",
431
431
  commandMinimumSupported: [
package/dist/index.mjs CHANGED
@@ -352,10 +352,10 @@ 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
- version: "0.1.197",
355
+ version: "0.1.199",
356
356
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
357
357
  supportPolicy: {
358
- latest: "0.1.197",
358
+ latest: "0.1.199",
359
359
  minimumSupported: "0.1.53",
360
360
  deprecatedBelow: "0.1.53",
361
361
  commandMinimumSupported: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.197",
3
+ "version": "0.1.199",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {