deepline 0.1.149 → 0.1.151

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +157 -140
  2. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/csv-rows.ts +2 -19
  3. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/row-isolation.ts +5 -53
  4. package/dist/bundling-sources/sdk/src/client.ts +5 -0
  5. package/dist/bundling-sources/sdk/src/config.ts +2 -2
  6. package/dist/bundling-sources/sdk/src/release.ts +2 -2
  7. package/dist/bundling-sources/sdk/src/tool-output.ts +63 -17
  8. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +100 -158
  9. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +3 -0
  10. package/dist/bundling-sources/shared_libs/play-runtime/durability-store.ts +54 -0
  11. package/dist/bundling-sources/shared_libs/play-runtime/map-row-outcome.ts +167 -0
  12. package/dist/bundling-sources/shared_libs/play-runtime/pacing.ts +79 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/row-isolation.ts +39 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +19 -86
  15. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-transition.ts +90 -0
  16. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-session.ts +43 -0
  17. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +142 -11
  18. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +3 -2
  19. package/dist/bundling-sources/shared_libs/play-runtime/tool-result-types.ts +17 -4
  20. package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +343 -26
  21. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +20 -23
  22. package/dist/cli/index.js +186 -105
  23. package/dist/cli/index.mjs +193 -106
  24. package/dist/index.d.mts +12 -9
  25. package/dist/index.d.ts +12 -9
  26. package/dist/index.js +33 -20
  27. package/dist/index.mjs +40 -21
  28. package/dist/plays/bundle-play-file.mjs +22 -19
  29. package/package.json +1 -1
@@ -1513,18 +1513,28 @@ async function computeWorkersHarnessFingerprintWithAdapter(
1513
1513
  hash: sha256(contents),
1514
1514
  });
1515
1515
  };
1516
- const collectTopLevelTsFiles = async (
1516
+ const collectTsFilesRecursive = async (
1517
1517
  rootDir: string,
1518
1518
  parts: Array<{ name: string; hash: string }>,
1519
1519
  ) => {
1520
1520
  if (!(await fileExists(rootDir))) return;
1521
- const entries = await readdir(rootDir, { withFileTypes: true });
1522
- const tsFiles = entries
1523
- .filter((entry) => entry.isFile() && /\.[cm]?ts$/.test(entry.name))
1524
- .map((entry) => entry.name)
1525
- .sort();
1526
- for (const name of tsFiles) {
1527
- await addFilePart(parts, rootDir, join(rootDir, name));
1521
+ const filePaths: string[] = [];
1522
+ const visitDir = async (dir: string) => {
1523
+ const entries = await readdir(dir, { withFileTypes: true });
1524
+ for (const entry of entries) {
1525
+ const childPath = join(dir, entry.name);
1526
+ if (entry.isDirectory()) {
1527
+ await visitDir(childPath);
1528
+ continue;
1529
+ }
1530
+ if (entry.isFile() && /\.[cm]?ts$/.test(entry.name)) {
1531
+ filePaths.push(childPath);
1532
+ }
1533
+ }
1534
+ };
1535
+ await visitDir(rootDir);
1536
+ for (const filePath of filePaths.sort()) {
1537
+ await addFilePart(parts, rootDir, filePath);
1528
1538
  }
1529
1539
  };
1530
1540
  const collectIntegrationBatchingFiles = async (
@@ -1554,26 +1564,13 @@ async function computeWorkersHarnessFingerprintWithAdapter(
1554
1564
  }
1555
1565
  };
1556
1566
 
1557
- const entries = await readdir(adapter.workersHarnessFilesDir, {
1558
- withFileTypes: true,
1559
- });
1560
- const tsFiles = entries
1561
- .filter((e) => e.isFile() && /\.[cm]?ts$/.test(e.name))
1562
- .map((e) => e.name)
1563
- .sort();
1564
1567
  const parts: Array<{ name: string; hash: string }> = [];
1565
- for (const name of tsFiles) {
1566
- await addFilePart(
1567
- parts,
1568
- adapter.workersHarnessFilesDir,
1569
- join(adapter.workersHarnessFilesDir, name),
1570
- );
1571
- }
1568
+ await collectTsFilesRecursive(adapter.workersHarnessFilesDir, parts);
1572
1569
  for (const dir of adapter.workersRuntimeFingerprintDirs ?? []) {
1573
1570
  if (basename(dir) === 'integrations') {
1574
1571
  await collectIntegrationBatchingFiles(dir, parts);
1575
1572
  } else {
1576
- await collectTopLevelTsFiles(dir, parts);
1573
+ await collectTsFilesRecursive(dir, parts);
1577
1574
  }
1578
1575
  }
1579
1576
  return sha256(JSON.stringify(parts));
package/dist/cli/index.js CHANGED
@@ -420,7 +420,7 @@ function loadProjectEnvCandidates(startDir = process.cwd()) {
420
420
  }));
421
421
  }
422
422
  function normalizeBaseUrl(baseUrl) {
423
- const trimmed = baseUrl.trim().replace(/\/+$/, "");
423
+ const trimmed = baseUrl?.trim().replace(/\/+$/, "") ?? "";
424
424
  if (!trimmed) return "";
425
425
  try {
426
426
  const parsed = new URL(trimmed);
@@ -655,10 +655,10 @@ var SDK_RELEASE = {
655
655
  // the SDK enrich generator's one-second stale policy.
656
656
  // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
657
657
  // 0.1.111 ships dataset-native tool list getters and result row datasets.
658
- version: "0.1.149",
658
+ version: "0.1.151",
659
659
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
660
660
  supportPolicy: {
661
- latest: "0.1.149",
661
+ latest: "0.1.151",
662
662
  minimumSupported: "0.1.53",
663
663
  deprecatedBelow: "0.1.53",
664
664
  commandMinimumSupported: [
@@ -2122,6 +2122,7 @@ async function* observeRunEvents(options) {
2122
2122
  var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
2123
2123
  var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
2124
2124
  var EXECUTE_RESPONSE_CONTRACT_HEADER = "x-deepline-execute-response-contract";
2125
+ var EXECUTE_RESPONSE_INTENT_HEADER = "x-deepline-execute-response-intent";
2125
2126
  var V2_EXECUTE_RESPONSE_CONTRACT = "v2-tool-response";
2126
2127
  var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
2127
2128
  var REGISTER_PLAY_ARTIFACTS_COMPILE_CONCURRENCY = 3;
@@ -2606,7 +2607,8 @@ var DeeplineClient = class {
2606
2607
  async executeTool(toolId, input2, options) {
2607
2608
  const headers = {
2608
2609
  [EXECUTE_RESPONSE_CONTRACT_HEADER]: V2_EXECUTE_RESPONSE_CONTRACT,
2609
- ...options?.includeToolMetadata ? { [INCLUDE_TOOL_METADATA_HEADER]: "true" } : {}
2610
+ ...options?.includeToolMetadata ? { [INCLUDE_TOOL_METADATA_HEADER]: "true" } : {},
2611
+ ...options?.responseIntent ? { [EXECUTE_RESPONSE_INTENT_HEADER]: options.responseIntent } : {}
2610
2612
  };
2611
2613
  return this.http.post(
2612
2614
  `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
@@ -10788,6 +10790,23 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
10788
10790
  },
10789
10791
  Math.max(1, input2.waitTimeoutMs)
10790
10792
  );
10793
+ const fetchKnownTerminalStatus = async () => {
10794
+ if (!lastKnownWorkflowId) {
10795
+ return null;
10796
+ }
10797
+ let refreshed;
10798
+ try {
10799
+ refreshed = await input2.client.getPlayStatus(lastKnownWorkflowId, {
10800
+ billing: false
10801
+ });
10802
+ } catch (error) {
10803
+ if (isTransientPlayStreamError(error)) {
10804
+ return null;
10805
+ }
10806
+ throw error;
10807
+ }
10808
+ return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? { ...refreshed, dashboardUrl } : null;
10809
+ };
10791
10810
  try {
10792
10811
  for await (const event of input2.client.startPlayRunStream(input2.request, {
10793
10812
  signal: controller.signal
@@ -10883,6 +10902,21 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
10883
10902
  }
10884
10903
  } catch (error) {
10885
10904
  if (timedOut) {
10905
+ const terminal = await fetchKnownTerminalStatus();
10906
+ if (terminal) {
10907
+ recordCliTrace({
10908
+ phase: "cli.play_start_stream_timeout_status_reconcile",
10909
+ ms: Date.now() - startedAt,
10910
+ ok: true,
10911
+ playName: input2.playName,
10912
+ workflowId: lastKnownWorkflowId,
10913
+ eventCount,
10914
+ firstRunIdMs,
10915
+ lastPhase,
10916
+ status: terminal.status
10917
+ });
10918
+ return terminal;
10919
+ }
10886
10920
  assertPlayWaitNotTimedOut({
10887
10921
  workflowId: lastKnownWorkflowId,
10888
10922
  startedAt,
@@ -20554,6 +20588,19 @@ function normalizeRows(value) {
20554
20588
  return { value: entry };
20555
20589
  });
20556
20590
  }
20591
+ function columnsForRows(rows) {
20592
+ const seen = /* @__PURE__ */ new Set();
20593
+ const columns = [];
20594
+ for (const row of rows) {
20595
+ for (const key of Object.keys(row)) {
20596
+ if (!seen.has(key)) {
20597
+ seen.add(key);
20598
+ columns.push(key);
20599
+ }
20600
+ }
20601
+ }
20602
+ return columns;
20603
+ }
20557
20604
  function candidateRoots(payload) {
20558
20605
  const roots = [
20559
20606
  { path: null, value: payload }
@@ -20636,6 +20683,16 @@ function tryConvertToList(payload, options) {
20636
20683
  }
20637
20684
  return null;
20638
20685
  }
20686
+ function projectRowOutput(conversion) {
20687
+ return {
20688
+ rows: conversion.rows,
20689
+ rowCount: conversion.rows.length,
20690
+ columns: columnsForRows(conversion.rows),
20691
+ previewRows: conversion.rows.slice(0, 5),
20692
+ strategy: conversion.strategy,
20693
+ sourcePath: conversion.sourcePath
20694
+ };
20695
+ }
20639
20696
  function ensureOutputDir() {
20640
20697
  const outputDir = (0, import_node_path14.join)((0, import_node_os10.homedir)(), ".local", "share", "deepline", "data");
20641
20698
  (0, import_node_fs12.mkdirSync)(outputDir, { recursive: true });
@@ -20650,16 +20707,7 @@ function writeJsonOutputFile(payload, stem) {
20650
20707
  function writeCsvOutputFile(rows, stem, options) {
20651
20708
  const outputPath = options?.outPath ? options.outPath : (0, import_node_path14.join)(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
20652
20709
  (0, import_node_fs12.mkdirSync)((0, import_node_path14.dirname)(outputPath), { recursive: true });
20653
- const seen = /* @__PURE__ */ new Set();
20654
- const columns = [];
20655
- for (const row of rows) {
20656
- for (const key of Object.keys(row)) {
20657
- if (!seen.has(key)) {
20658
- seen.add(key);
20659
- columns.push(key);
20660
- }
20661
- }
20662
- }
20710
+ const columns = columnsForRows(rows);
20663
20711
  const escapeCell = (value) => {
20664
20712
  const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
20665
20713
  if (/[",\n]/.test(normalized)) {
@@ -20667,13 +20715,20 @@ function writeCsvOutputFile(rows, stem, options) {
20667
20715
  }
20668
20716
  return normalized;
20669
20717
  };
20670
- const lines = [];
20671
- lines.push(columns.map(escapeCell).join(","));
20672
- for (const row of rows) {
20673
- lines.push(columns.map((column) => escapeCell(row[column])).join(","));
20718
+ const fd = (0, import_node_fs12.openSync)(outputPath, "w");
20719
+ try {
20720
+ (0, import_node_fs12.writeSync)(fd, `${columns.map(escapeCell).join(",")}
20721
+ `);
20722
+ for (const row of rows) {
20723
+ (0, import_node_fs12.writeSync)(
20724
+ fd,
20725
+ `${columns.map((column) => escapeCell(row[column])).join(",")}
20726
+ `
20727
+ );
20728
+ }
20729
+ } finally {
20730
+ (0, import_node_fs12.closeSync)(fd);
20674
20731
  }
20675
- (0, import_node_fs12.writeFileSync)(outputPath, `${lines.join("\n")}
20676
- `, "utf-8");
20677
20732
  const previewRows = rows.slice(0, 5);
20678
20733
  const previewColumns = columns.slice(0, 5);
20679
20734
  const preview = [
@@ -21200,10 +21255,7 @@ Examples:
21200
21255
  ).option(
21201
21256
  "--output-format <format>",
21202
21257
  "Output format: auto, csv, csv_file, json, or json_file"
21203
- ).option(
21204
- "-o, --out <path>",
21205
- "Write row-shaped tool output to this CSV path"
21206
- ).option(
21258
+ ).option("-o, --out <path>", "Write row-shaped tool output to this CSV path").option(
21207
21259
  "--no-preview",
21208
21260
  "Only print the extracted output path when applicable"
21209
21261
  ).action(async (toolId, options) => {
@@ -22057,6 +22109,100 @@ function buildToolExecuteBaseEnvelope(input2) {
22057
22109
  }
22058
22110
  };
22059
22111
  }
22112
+ function buildToolExecuteRowArtifactEnvelope(input2) {
22113
+ const {
22114
+ toolResponse: _toolResponse,
22115
+ result: _result,
22116
+ output: _output,
22117
+ output_preview: _outputPreview,
22118
+ render: _render,
22119
+ next: _next,
22120
+ local: _local,
22121
+ ...base
22122
+ } = input2.baseEnvelope;
22123
+ void _toolResponse;
22124
+ void _result;
22125
+ void _output;
22126
+ void _outputPreview;
22127
+ void _render;
22128
+ void _next;
22129
+ void _local;
22130
+ return {
22131
+ ...base,
22132
+ status: typeof base.status === "string" ? base.status : "completed",
22133
+ output_preview: {
22134
+ kind: "list",
22135
+ rowCount: input2.rowOutput.rowCount,
22136
+ columns: input2.rowOutput.columns,
22137
+ preview: input2.rowOutput.previewRows,
22138
+ listStrategy: input2.rowOutput.strategy,
22139
+ listSourcePath: input2.rowOutput.sourcePath
22140
+ },
22141
+ csv_path: input2.csv.path,
22142
+ row_count: input2.csv.rowCount,
22143
+ row_count_returned: input2.csv.rowCount,
22144
+ columns: input2.csv.columns,
22145
+ extracted_csv: input2.csv.path,
22146
+ extracted_csv_rows: input2.csv.rowCount,
22147
+ extracted_csv_columns: input2.csv.columns,
22148
+ preview: input2.csv.preview,
22149
+ list_strategy: input2.rowOutput.strategy,
22150
+ list_source_path: input2.rowOutput.sourcePath,
22151
+ summary: input2.summary,
22152
+ local: {
22153
+ extracted_csv: input2.csv.path,
22154
+ extracted_csv_rows: input2.csv.rowCount,
22155
+ extracted_csv_columns: input2.csv.columns,
22156
+ preview: input2.csv.preview,
22157
+ starter_script: input2.seededScript.path,
22158
+ project_dir: input2.seededScript.projectDir,
22159
+ copy_to_project: {
22160
+ macos_linux: input2.seededScript.macCopyCommand,
22161
+ windows_powershell: input2.seededScript.windowsCopyCommand
22162
+ }
22163
+ },
22164
+ starter_script: input2.seededScript.path,
22165
+ project_dir: input2.seededScript.projectDir,
22166
+ copy_to_project: {
22167
+ macos_linux: input2.seededScript.macCopyCommand,
22168
+ windows_powershell: input2.seededScript.windowsCopyCommand
22169
+ },
22170
+ next: {
22171
+ inspect: "Re-run with --json only when you need the raw provider/tool response.",
22172
+ listSourcePath: input2.rowOutput.sourcePath,
22173
+ expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again."
22174
+ },
22175
+ render: {
22176
+ sections: [
22177
+ {
22178
+ title: `${input2.csv.path} (${input2.csv.rowCount} rows)`,
22179
+ lines: [
22180
+ ...input2.csv.columns.length > 0 ? [`columns: ${JSON.stringify(input2.csv.columns)}`] : [],
22181
+ ...Object.keys(input2.summary).length > 0 ? [
22182
+ `summary: ${Object.entries(input2.summary).map(([key, value]) => `${key}=${String(value)}`).join(", ")}`
22183
+ ] : [],
22184
+ `preview: ${JSON.stringify(input2.rowOutput.previewRows)}`,
22185
+ `starter script: ${input2.seededScript.path}`
22186
+ ]
22187
+ }
22188
+ ],
22189
+ actions: [
22190
+ {
22191
+ label: "next",
22192
+ command: "Move the script into a project folder and expand it into a Deepline play. Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again."
22193
+ },
22194
+ {
22195
+ label: "macOS/Linux",
22196
+ command: input2.seededScript.macCopyCommand
22197
+ },
22198
+ {
22199
+ label: "Windows PowerShell",
22200
+ command: input2.seededScript.windowsCopyCommand
22201
+ }
22202
+ ]
22203
+ }
22204
+ };
22205
+ }
22060
22206
  async function executeTool(args) {
22061
22207
  let parsed;
22062
22208
  try {
@@ -22108,7 +22254,9 @@ async function executeTool(args) {
22108
22254
  }
22109
22255
  return 2;
22110
22256
  }
22111
- const rawResponse = await client2.executeTool(parsed.toolId, parsed.params);
22257
+ const rawResponse = await client2.executeTool(parsed.toolId, parsed.params, {
22258
+ responseIntent: parsed.outPath || parsed.outputFormat === "csv" || parsed.outputFormat === "csv_file" ? "row_artifact" : "raw"
22259
+ });
22112
22260
  const listConversion = tryConvertToList(rawResponse, {
22113
22261
  listExtractorPaths: listExtractorPathsFromUsageGuidance(metadata)
22114
22262
  });
@@ -22172,6 +22320,7 @@ async function executeTool(args) {
22172
22320
  printCommandEnvelope(baseEnvelope, { json: false });
22173
22321
  return 0;
22174
22322
  }
22323
+ const rowOutput = projectRowOutput(listConversion);
22175
22324
  const csv = writeCsvOutputFile(
22176
22325
  listConversion.rows,
22177
22326
  `${parsed.toolId}_output`,
@@ -22182,91 +22331,23 @@ async function executeTool(args) {
22182
22331
  payload: parsed.params,
22183
22332
  rows: listConversion.rows
22184
22333
  });
22185
- const materializedEnvelope = {
22186
- ...baseEnvelope,
22187
- local: {
22188
- extracted_csv: csv.path,
22189
- extracted_csv_rows: csv.rowCount,
22190
- extracted_csv_columns: csv.columns,
22191
- preview: csv.preview,
22192
- starter_script: seededScript.path,
22193
- project_dir: seededScript.projectDir,
22194
- copy_to_project: {
22195
- macos_linux: seededScript.macCopyCommand,
22196
- windows_powershell: seededScript.windowsCopyCommand
22197
- }
22198
- },
22199
- render: {
22200
- sections: [
22201
- {
22202
- title: `${csv.path} (${csv.rowCount} rows)`,
22203
- lines: [
22204
- ...csv.columns.length > 0 ? [`columns: ${JSON.stringify(csv.columns)}`] : [],
22205
- ...Object.keys(summary).length > 0 ? [
22206
- `summary: ${Object.entries(summary).map(([key, value]) => `${key}=${String(value)}`).join(", ")}`
22207
- ] : [],
22208
- `preview: ${JSON.stringify(csv.preview)}`,
22209
- `starter script: ${seededScript.path}`
22210
- ]
22211
- }
22212
- ],
22213
- actions: [
22214
- {
22215
- label: "next",
22216
- command: "Move the script into a project folder and expand it into a Deepline play. Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again."
22217
- },
22218
- {
22219
- label: "macOS/Linux",
22220
- command: seededScript.macCopyCommand
22221
- },
22222
- {
22223
- label: "Windows PowerShell",
22224
- command: seededScript.windowsCopyCommand
22225
- }
22226
- ]
22227
- }
22228
- };
22334
+ const materializedEnvelope = buildToolExecuteRowArtifactEnvelope({
22335
+ baseEnvelope,
22336
+ csv,
22337
+ rowOutput,
22338
+ summary,
22339
+ seededScript
22340
+ });
22229
22341
  if (parsed.outputFormat === "csv_file") {
22230
- printCommandEnvelope(
22231
- {
22232
- ...materializedEnvelope,
22233
- extracted_csv: csv.path,
22234
- extracted_csv_rows: csv.rowCount,
22235
- extracted_csv_columns: csv.columns,
22236
- preview: csv.preview,
22237
- list_strategy: listConversion.strategy,
22238
- list_source_path: listConversion.sourcePath,
22239
- starter_script: seededScript.path,
22240
- project_dir: seededScript.projectDir,
22241
- copy_to_project: {
22242
- macos_linux: seededScript.macCopyCommand,
22243
- windows_powershell: seededScript.windowsCopyCommand
22244
- },
22245
- summary
22246
- },
22247
- { json: true }
22248
- );
22342
+ printCommandEnvelope(materializedEnvelope, { json: true });
22249
22343
  return 0;
22250
22344
  }
22251
22345
  if (parsed.outPath) {
22252
- printCommandEnvelope(
22253
- {
22254
- ...materializedEnvelope,
22255
- csv_path: csv.path,
22256
- row_count: csv.rowCount,
22257
- row_count_returned: csv.rowCount,
22258
- columns: csv.columns,
22259
- preview: csv.preview,
22260
- list_strategy: listConversion.strategy,
22261
- list_source_path: listConversion.sourcePath,
22262
- summary
22263
- },
22264
- {
22265
- json: argsWantJson(args) || shouldEmitJson(),
22266
- text: `Wrote ${csv.rowCount} row(s) to ${csv.path}
22346
+ printCommandEnvelope(materializedEnvelope, {
22347
+ json: argsWantJson(args) || shouldEmitJson(),
22348
+ text: `Wrote ${csv.rowCount} row(s) to ${csv.path}
22267
22349
  `
22268
- }
22269
- );
22350
+ });
22270
22351
  return 0;
22271
22352
  }
22272
22353
  if (parsed.noPreview) {