deepline 0.3.290 → 0.3.291

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 (46) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +8 -6
  2. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  3. package/dist/bundling-sources/sdk/src/runs/overview.ts +16 -6
  4. package/dist/bundling-sources/sdk/src/types.ts +21 -2
  5. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +11 -1
  6. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +209 -51
  7. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +10 -2
  8. package/dist/bundling-sources/shared_libs/play-runtime/log-context.ts +36 -0
  9. package/dist/bundling-sources/shared_libs/play-runtime/log-provenance.ts +2 -1
  10. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +5 -1
  11. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts +54 -41
  12. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +50 -3
  13. package/dist/bundling-sources/shared_libs/play-runtime/run-log-buffer.ts +9 -2
  14. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +35 -7
  15. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +55 -9
  16. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +16 -4
  17. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +140 -4
  18. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +559 -313
  19. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +1 -1
  20. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +116 -24
  21. package/dist/bundling-sources/shared_libs/play-runtime/step-progress.ts +6 -1
  22. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/runtime-step-receipts-adapter.ts +22 -5
  23. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +35 -0
  24. package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +68 -8
  25. package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +2 -0
  26. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +2 -0
  27. package/dist/cli/index.js +193 -582
  28. package/dist/cli/index.mjs +193 -582
  29. package/dist/{client-FR_u0dxT.d.ts → client-Ct4jmvAg.d.ts} +29 -8
  30. package/dist/{client-phK1Ixcl.d.mts → client-Ct9GKrwu.d.mts} +29 -8
  31. package/dist/{compiler-manifest-9SQtUuKb.d.mts → compiler-manifest-qtTNYvBl.d.mts} +2 -0
  32. package/dist/{compiler-manifest-9SQtUuKb.d.ts → compiler-manifest-qtTNYvBl.d.ts} +2 -0
  33. package/dist/index.d.mts +4 -4
  34. package/dist/index.d.ts +4 -4
  35. package/dist/index.js +12 -5
  36. package/dist/index.mjs +12 -5
  37. package/dist/install-integrity.json +4 -4
  38. package/dist/plays/bundle-play-file.d.mts +2 -2
  39. package/dist/plays/bundle-play-file.d.ts +2 -2
  40. package/dist/plays/run-request.d.mts +2 -2
  41. package/dist/plays/run-request.d.ts +2 -2
  42. package/dist/release.d.mts +1 -1
  43. package/dist/release.d.ts +1 -1
  44. package/dist/release.js +1 -1
  45. package/dist/release.mjs +1 -1
  46. package/package.json +1 -1
@@ -3510,7 +3510,7 @@ var SDK_RELEASE = {
3510
3510
  // getters keep their established compatibility behavior.
3511
3511
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3512
3512
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3513
- version: "0.3.290",
3513
+ version: "0.3.291",
3514
3514
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3515
3515
  packageCapabilities: {
3516
3516
  updatePreferences: 1
@@ -5977,7 +5977,7 @@ function classifyLegacyLogLine(line) {
5977
5977
  if (/^\[perf\] runtime receipt\b/i.test(message)) {
5978
5978
  return "receipt";
5979
5979
  }
5980
- if (/^\[perf\] runtime (?:map|state)\b/i.test(message) || /\[worker\] picked up run\b/.test(message) || /\[worker\] heartbeat\b/.test(message) || /\[worker\] progress completedRows=\d+ totalRows=\d+ rowUpdates=\d+/.test(
5980
+ if (/^\[perf\]/i.test(message) || /^\[runtime\.(?:phase_summary|logs|log_transport)\]/i.test(message) || /\[worker\] picked up run\b/.test(message) || /\[worker\] heartbeat\b/.test(message) || /\[worker\] progress completedRows=\d+ totalRows=\d+ rowUpdates=\d+/.test(
5981
5981
  message
5982
5982
  ) || /\[worker\] step started\b/.test(message) || /\[worker\] Preparing run files\b/.test(message) || /\[worker\] Run files ready\b/.test(message) || /\[worker\] Runtime ready\b/.test(message) || /\[worker\] Sandbox (?:starting|create start|create done|workspace ready|upload start|runner uploaded)\b/.test(
5983
5983
  message
@@ -7809,8 +7809,10 @@ var DeeplineClient = class _DeeplineClient {
7809
7809
  /**
7810
7810
  * Execute a tool and return the standard execution envelope.
7811
7811
  *
7812
- * The `toolResponse.rawV2` field contains the complete parsed and scrubbed tool response.
7813
- * `toolResponse.meta` contains tool/provider metadata.
7812
+ * The `toolResponse.rawV2` field contains the complete tool response,
7813
+ * preserving its original nesting. Inspect `getTool().examples` for a full
7814
+ * Deepline response example. Optional `toolResponse.responseMeta` contains
7815
+ * response metadata.
7814
7816
  * Top-level fields such as `status`, `job_id`, and `billing` describe the
7815
7817
  * Deepline execution envelope.
7816
7818
  */
@@ -8523,7 +8525,7 @@ var DeeplineClient = class _DeeplineClient {
8523
8525
  });
8524
8526
  } catch (error) {
8525
8527
  failedLogsLoaded = false;
8526
- const retryCommand = `deepline runs get ${runId} --log-failed --json`;
8528
+ const retryCommand = `deepline runs logs ${runId} --failed --json`;
8527
8529
  const reason = error instanceof Error && error.message.trim() ? ` (${error.message.trim().slice(0, 500)})` : "";
8528
8530
  failedLogs = {
8529
8531
  runId,
@@ -21763,7 +21765,7 @@ var KIND_DESCRIPTIONS = {
21763
21765
  "dataset.lifecycle": "Dataset registered, available or failed.",
21764
21766
  "activity.observed": "Provider or workflow activity.",
21765
21767
  "work.counters": "Call, request and rate-limit totals.",
21766
- "receipt.completed": "Saved work result: succeeded.",
21768
+ "receipt.completed": "Saved result or call details.",
21767
21769
  "receipt.failed": "Saved work result: failed.",
21768
21770
  "receipt.skipped": "Saved work result: skipped.",
21769
21771
  "runtime.event": "Other event."
@@ -21804,6 +21806,10 @@ var FILTER_EXAMPLES = [
21804
21806
  {
21805
21807
  label: "One run and step",
21806
21808
  command: `deepline runs logs '<run-id>' --where '$.stepId == "company-lookup"' --json`
21809
+ },
21810
+ {
21811
+ label: "Error logs for one step",
21812
+ command: `deepline runs logs --kind log.appended --where '$.level == "error" && $.stepId == "company-lookup"' --payloads --json`
21807
21813
  }
21808
21814
  ];
21809
21815
  function wrapParagraph(text) {
@@ -21824,10 +21830,14 @@ function renderRunLogsHelp() {
21824
21830
  "",
21825
21831
  "Examples:",
21826
21832
  ` ${READ_EXAMPLES[0]}`,
21833
+ ` deepline runs logs --where '$.eventId == "receipt:5a32ee1a-46cf-4853-b72b-5f1d782ffab4"' --payloads --json`,
21827
21834
  " deepline runs logs --kind run.failed --json",
21828
- ...[FILTER_EXAMPLES[1], FILTER_EXAMPLES[2], FILTER_EXAMPLES[5]].map(
21829
- ({ command }) => ` ${command}`
21830
- ),
21835
+ ...[
21836
+ FILTER_EXAMPLES[1],
21837
+ FILTER_EXAMPLES[2],
21838
+ FILTER_EXAMPLES[5],
21839
+ FILTER_EXAMPLES[7]
21840
+ ].map(({ command }) => ` ${command}`),
21831
21841
  "",
21832
21842
  "Event kinds:",
21833
21843
  ...RUN_LOGS_KIND_HELP.map(
@@ -21846,6 +21856,7 @@ function renderRunLogsHelp() {
21846
21856
  "A run ID alone reads text logs. Omit it or add a search flag to search events; a supplied run ID narrows the search.",
21847
21857
  "Defaults to the last hour; maximum lookback is seven days. Follow next.logs for events; use nextCursor with --cursor for older text logs.",
21848
21858
  "--payloads returns available details or saved results: up to 10 events and 16 MiB.",
21859
+ "To read one exact saved result, filter by its returned eventId and add --payloads.",
21849
21860
  "--out, --failed and --log-level apply to text logs and cannot be combined with event search."
21850
21861
  ].map((note) => wrapParagraph(note)),
21851
21862
  "",
@@ -22178,13 +22189,6 @@ var DATASET_EXECUTION_BUCKETS = [
22178
22189
  "skipped:missed",
22179
22190
  "failed"
22180
22191
  ];
22181
- function formatDatasetRowCountsLine(counts) {
22182
- const { persisted, succeeded, failed } = counts;
22183
- if (succeeded === persisted && failed === 0) {
22184
- return `${persisted} persisted`;
22185
- }
22186
- return `${persisted} persisted (${succeeded} succeeded, ${failed} failed)`;
22187
- }
22188
22192
 
22189
22193
  // src/runs/overview.ts
22190
22194
  var record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
@@ -22203,7 +22207,7 @@ function lifecycleActions(status, id, state) {
22203
22207
  return {
22204
22208
  ...["started", "queued", "running", "waiting"].includes(state ?? "") ? { stopRunCmd: `deepline runs stop ${id} --json` } : {},
22205
22209
  ...state === "failed" ? {
22206
- getFailedLogsCmd: `deepline runs get ${id} --log-failed --json`,
22210
+ getFailedLogsCmd: `deepline runs logs ${id} --failed --json`,
22207
22211
  ...status.rerunCommand ? { rerunCmd: status.rerunCommand } : {}
22208
22212
  } : {}
22209
22213
  };
@@ -22406,7 +22410,7 @@ function buildRunOverview(status, fullStatus) {
22406
22410
  );
22407
22411
  return {
22408
22412
  datasetId: dataset.datasetId,
22409
- name: dataset.tableNamespace,
22413
+ name: dataset.tableNamespace ?? (typeof stepOutput?.tableNamespace === "string" ? stepOutput.tableNamespace : dataset.path),
22410
22414
  stepId: step?.id ?? named[0]?.[1].stepId,
22411
22415
  rowCount: dataset.rowCount ?? null,
22412
22416
  ...dataset.lifecycle ? { lifecycle: dataset.lifecycle } : {},
@@ -22500,7 +22504,7 @@ function buildRunOverview(status, fullStatus) {
22500
22504
  function receiptAction(id) {
22501
22505
  const quotedId = `'${id.replace(/'/g, "'\\''")}'`;
22502
22506
  return {
22503
- getReceiptCmd: `deepline runs receipt ${quotedId} --key '<receipt-key>' --json`
22507
+ getReceiptCmd: `deepline runs logs ${quotedId} --kind receipt.completed --payloads --json`
22504
22508
  };
22505
22509
  }
22506
22510
  function buildRunNavigation(status) {
@@ -24387,7 +24391,7 @@ Examples:
24387
24391
  // src/cli/commands/run-receipt.ts
24388
24392
  import { readFile, writeFile as writeFile3 } from "fs/promises";
24389
24393
  function registerRunReceiptCommand(runs) {
24390
- runs.command("receipt <runId>").description(
24394
+ runs.command("receipt <runId>", { hidden: true }).description(
24391
24395
  "Read retained tool responses by receipt key. Never executes tools."
24392
24396
  ).option(
24393
24397
  "--key <key>",
@@ -24401,8 +24405,7 @@ function registerRunReceiptCommand(runs) {
24401
24405
  "after",
24402
24406
  `
24403
24407
  Examples:
24404
- deepline runs receipt <run-id> --key '<key-1>' --key '<key-2>'
24405
- jq -r '.[].receipt_key' rows.json | deepline runs receipt <run-id> --keys - --out responses.json
24408
+ deepline runs logs <run-id> --kind receipt.completed --payloads --json
24406
24409
 
24407
24410
  Returns one outcome per key, preserving order and duplicates. A missing or
24408
24411
  unavailable result is explicit; other keys are still returned. Exit 4 means
@@ -31672,7 +31675,7 @@ async function traceCliSpan(phase, fields2, run) {
31672
31675
  }
31673
31676
 
31674
31677
  // src/cli/play-check-hints.ts
31675
- var EXTRACTED_GETTER_ERROR_HINT = "Deepline hint: extractedValues/extractedLists .get() only works for declared Deepline getters listed by `deepline tools describe <tool> --json`. Use `toolExecutionResult.toolResponse.rawV2` for provider/tool-specific scalar fields after inspecting the observed response envelope, and `toolExecutionResult.extractedLists.<name>.get()` for declared row/list outputs.";
31678
+ var EXTRACTED_GETTER_ERROR_HINT = "Deepline hint: extractedValues/extractedLists .get() only works for declared Deepline getters listed by `deepline tools describe <tool> --json`. Read tool-specific fields from `toolExecutionResult.toolResponse.rawV2` using the nesting shown in the response example, and use `toolExecutionResult.extractedLists.<name>.get()` for declared row/list outputs.";
31676
31679
  var DATASET_API_HINT = "Deepline hint: PlayDataset is lazy, durable, and async-only. Use `.count()`, `.first()`, `.at(index)`, `.peek(n)`, `.materialize(limit)`, or async iteration; do not use `.length`, numeric indexing, spread, synchronous iteration, `.rows`, or `.toArray()`.";
31677
31680
  var ROW_PROPERTY_HINT = "Deepline hint: this row type only contains fields produced by the CSV/schema and previous map steps. Check source column casing and the exact output field names from earlier steps before scaling.";
31678
31681
  var TOOLS_EXECUTE_SIGNATURE_HINT = "Deepline hint: ctx.tools.execute requires a request object: `ctx.tools.execute({ id, tool, input, description })`. The stable `id` is required for logs, metadata, and result-cache identity; terminal cache reuse is based on play, tool, semantic input, auth scope, provider action version, and cache policy.";
@@ -36640,12 +36643,13 @@ function buildRunNextCommands(status) {
36640
36643
  };
36641
36644
  }
36642
36645
  const actions2 = buildRunNavigation(status).actions;
36646
+ const exportDatasetCmds = Array.isArray(actions2.exportDatasetCmds) ? actions2.exportDatasetCmds : !status.package && extractCanonicalRowsInfo(status) ? [`deepline runs export ${runId} --out output.csv`] : [];
36643
36647
  const commands = {
36644
36648
  get: String(actions2.getRunCmd ?? `deepline runs get ${runId} --json`),
36645
36649
  full: String(
36646
36650
  actions2.getFullRunCmd ?? `deepline runs get ${runId} --full --json`
36647
36651
  ),
36648
- ...Array.isArray(actions2.exportDatasetCmds) ? actions2.exportDatasetCmds.length === 1 ? { export: String(actions2.exportDatasetCmds[0]) } : {} : !status.package ? { export: `deepline runs export ${runId} --out output.csv` } : {},
36652
+ ...exportDatasetCmds.length === 1 ? { export: String(exportDatasetCmds[0]) } : {},
36649
36653
  logs: String(
36650
36654
  !status.package ? `deepline runs logs ${runId} --out run.log --json` : actions2.getLogsCmd ?? `deepline runs logs ${runId} --limit 100 --json`
36651
36655
  )
@@ -36654,7 +36658,7 @@ function buildRunNextCommands(status) {
36654
36658
  commands.stop = `deepline runs stop ${runId} --json`;
36655
36659
  }
36656
36660
  if (status.status === "failed") {
36657
- commands.failedLogs = `deepline runs get ${runId} --log-failed --json`;
36661
+ commands.failedLogs = `deepline runs logs ${runId} --failed --json`;
36658
36662
  if (status.rerunCommand) commands.run = status.rerunCommand;
36659
36663
  }
36660
36664
  if (status.dashboardUrl) {
@@ -37085,7 +37089,7 @@ function compactPlayStatus(status) {
37085
37089
  next: {
37086
37090
  ...readRecord(packaged.next) ?? {},
37087
37091
  ...status.failedLogs ? {
37088
- failedLogs: `deepline runs get ${status.runId} --log-failed --json`
37092
+ failedLogs: `deepline runs logs ${status.runId} --failed --json`
37089
37093
  } : {},
37090
37094
  ...status.rerunCommand ? { run: status.rerunCommand } : {}
37091
37095
  }
@@ -37098,14 +37102,14 @@ function compactPlayStatus(status) {
37098
37102
  ...status.failedLogs ? {
37099
37103
  next: {
37100
37104
  ...readRecord(packaged.next) ?? {},
37101
- failedLogs: `deepline runs get ${status.runId} --log-failed --json`
37105
+ failedLogs: `deepline runs logs ${status.runId} --failed --json`
37102
37106
  }
37103
37107
  } : {},
37104
37108
  ...status.rerunCommand ? {
37105
37109
  next: {
37106
37110
  ...readRecord(packaged.next) ?? {},
37107
37111
  ...status.failedLogs ? {
37108
- failedLogs: `deepline runs get ${status.runId} --log-failed --json`
37112
+ failedLogs: `deepline runs logs ${status.runId} --failed --json`
37109
37113
  } : {},
37110
37114
  run: status.rerunCommand
37111
37115
  }
@@ -37154,9 +37158,6 @@ function compactRunErrorForEnvelope(message, runId) {
37154
37158
  const headline = firstStackFrame >= 0 ? lines.slice(0, firstStackFrame).join("\n") : message;
37155
37159
  return truncateErrorForDisplay(headline, runId, 1e3);
37156
37160
  }
37157
- function readRunPackageRun(packaged) {
37158
- return packaged.run && typeof packaged.run === "object" && !Array.isArray(packaged.run) ? packaged.run : {};
37159
- }
37160
37161
  function readRecordArray(value) {
37161
37162
  return Array.isArray(value) ? value.filter(
37162
37163
  (item) => item !== null && typeof item === "object" && !Array.isArray(item)
@@ -37168,131 +37169,6 @@ function readRecord(value) {
37168
37169
  function readNonNegativeInteger(value) {
37169
37170
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.trunc(value) : null;
37170
37171
  }
37171
- function formatSummaryScalar(value) {
37172
- if (typeof value === "number") {
37173
- return Number.isFinite(value) ? formatInteger(Math.trunc(value)) : null;
37174
- }
37175
- if (typeof value === "string" || typeof value === "boolean") {
37176
- return String(value);
37177
- }
37178
- if (value === null) {
37179
- return "null";
37180
- }
37181
- return null;
37182
- }
37183
- function formatSummaryScalarParts(record5, skipKeys = /* @__PURE__ */ new Set()) {
37184
- const parts = [];
37185
- for (const [key, value] of Object.entries(record5)) {
37186
- if (skipKeys.has(key)) {
37187
- continue;
37188
- }
37189
- const formatted = formatSummaryScalar(value);
37190
- if (formatted !== null) {
37191
- parts.push(`${key}=${formatted}`);
37192
- }
37193
- }
37194
- return parts;
37195
- }
37196
- var DATASET_SUMMARY_TOP_VALUES_DISPLAY_LIMIT = 10;
37197
- function formatTopValuesPart(value) {
37198
- const topValues = readRecord(value);
37199
- if (!topValues) {
37200
- return null;
37201
- }
37202
- const entries = Object.entries(topValues).slice(
37203
- 0,
37204
- DATASET_SUMMARY_TOP_VALUES_DISPLAY_LIMIT
37205
- );
37206
- if (entries.length === 0) {
37207
- return null;
37208
- }
37209
- return `top_values=${entries.map(([topValue, count2]) => `${topValue}=${String(count2)}`).join(", ")}`;
37210
- }
37211
- function formatPackageDatasetSummaryLines(summary, indent2 = " ") {
37212
- const record5 = readRecord(summary);
37213
- const columnStats = readRecord(record5?.columnStats);
37214
- if (!record5 || !columnStats) {
37215
- return [];
37216
- }
37217
- const lines = [];
37218
- const rowCounts = readRecord(record5.rowCounts);
37219
- if (rowCounts) {
37220
- const persisted = readNonNegativeInteger(rowCounts.persisted);
37221
- const succeeded = readNonNegativeInteger(rowCounts.succeeded);
37222
- const failed = readNonNegativeInteger(rowCounts.failed);
37223
- if (persisted !== null) {
37224
- lines.push(
37225
- `${indent2}rows: ${formatDatasetRowCountsLine({
37226
- persisted,
37227
- succeeded: succeeded ?? persisted,
37228
- failed: failed ?? 0
37229
- })}`
37230
- );
37231
- }
37232
- }
37233
- const parts = formatSummaryScalarParts(
37234
- record5,
37235
- /* @__PURE__ */ new Set(["columnStats", "rowCounts"])
37236
- );
37237
- if (parts.length > 0) {
37238
- lines.push(`${indent2}summary: ${parts.join(" ")}`);
37239
- }
37240
- for (const [column, rawColumnSummary] of Object.entries(columnStats)) {
37241
- const columnSummary = readRecord(rawColumnSummary);
37242
- if (!columnSummary) continue;
37243
- const execution = readRecord(columnSummary.execution);
37244
- const executionText = execution ? Object.entries(execution).map(([bucket, value]) => `${bucket}=${String(value)}`).join(", ") : "";
37245
- const topValuesText = formatTopValuesPart(columnSummary.top_values);
37246
- const columnParts = [
37247
- ...formatSummaryScalarParts(
37248
- columnSummary,
37249
- /* @__PURE__ */ new Set(["execution", "top_values"])
37250
- ),
37251
- topValuesText,
37252
- executionText ? `execution=${executionText}` : null
37253
- ].filter(Boolean);
37254
- if (columnParts.length > 0) {
37255
- lines.push(`${indent2} ${column}: ${columnParts.join(" ")}`);
37256
- }
37257
- }
37258
- return lines;
37259
- }
37260
- function actionToCommand(action) {
37261
- if (!action || typeof action !== "object" || Array.isArray(action)) {
37262
- return null;
37263
- }
37264
- const record5 = action;
37265
- if (typeof record5.command === "string" && record5.command.trim()) {
37266
- return record5.command.trim();
37267
- }
37268
- if (record5.kind === "deepline_run_inspect" && typeof record5.runId === "string") {
37269
- return `deepline runs get ${record5.runId} --json`;
37270
- }
37271
- if (record5.kind === "deepline_run_full" && typeof record5.runId === "string") {
37272
- return `deepline runs get ${record5.runId} --full --json`;
37273
- }
37274
- if (record5.kind === "deepline_run_billing" && typeof record5.runId === "string") {
37275
- return `deepline runs get ${record5.runId} --full --json | jq '.billing'`;
37276
- }
37277
- if (record5.kind === "deepline_run_export" && typeof record5.runId === "string" && typeof record5.datasetPath === "string") {
37278
- return `deepline runs export ${record5.runId} --dataset ${shellSingleQuote(
37279
- record5.datasetPath
37280
- )} --out ${shellSingleQuote(`${record5.datasetPath.split(".").pop() || "dataset"}.csv`)}`;
37281
- }
37282
- if (record5.kind === "deepline_run_logs") {
37283
- if (typeof record5.command === "string" && record5.command.trim()) {
37284
- return record5.command;
37285
- }
37286
- if (typeof record5.runId === "string") {
37287
- return record5.view === "failed" ? `deepline runs get ${record5.runId} --log-failed --json` : `deepline runs logs ${record5.runId} --json`;
37288
- }
37289
- }
37290
- if (record5.kind === "deepline_db_query" && typeof record5.sql === "string") {
37291
- const maxRows = typeof record5.maxRows === "number" && Number.isFinite(record5.maxRows) ? Math.trunc(record5.maxRows) : 20;
37292
- return `deepline db query --sql ${shellSingleQuote(record5.sql)} --max-rows ${maxRows} --json`;
37293
- }
37294
- return null;
37295
- }
37296
37172
  function packageDatasetRecords(packaged) {
37297
37173
  const catalog = readRecordArray(packaged.datasets);
37298
37174
  if (catalog.length > 0) return catalog;
@@ -37301,24 +37177,6 @@ function packageDatasetRecords(packaged) {
37301
37177
  return output2?.kind === "dataset" ? [output2] : [];
37302
37178
  });
37303
37179
  }
37304
- function packageReturnedDatasetIdentity(packaged) {
37305
- const datasetIds = /* @__PURE__ */ new Set();
37306
- const paths = /* @__PURE__ */ new Set();
37307
- const outputs = readRecord(packaged.outputs) ?? {};
37308
- for (const outputValue of Object.values(outputs)) {
37309
- const output2 = readRecord(outputValue);
37310
- if (output2?.kind !== "dataset") continue;
37311
- if (typeof output2.datasetId === "string" && output2.datasetId.trim()) {
37312
- datasetIds.add(output2.datasetId.trim());
37313
- }
37314
- for (const candidate of [output2.dataset, output2.path]) {
37315
- if (typeof candidate === "string" && candidate.trim()) {
37316
- paths.add(candidate.trim());
37317
- }
37318
- }
37319
- }
37320
- return { datasetIds, paths };
37321
- }
37322
37180
  function formatRunStepProgress(progress, includeRowOutcomes = false) {
37323
37181
  const executed = readNonNegativeInteger(progress.executed);
37324
37182
  const total = readNonNegativeInteger(progress.total);
@@ -37341,205 +37199,6 @@ function formatRunStepProgress(progress, includeRowOutcomes = false) {
37341
37199
  }
37342
37200
  return parts.join(" \xB7 ");
37343
37201
  }
37344
- function formatPackageDatasetActionLines(packaged, options) {
37345
- const returned = packageReturnedDatasetIdentity(packaged);
37346
- const includeSummary = options?.includeSummary ?? true;
37347
- const lines = [];
37348
- const steps = readRecordArray(packaged.steps);
37349
- const stepsByDatasetId = /* @__PURE__ */ new Map();
37350
- const stepsByPath = /* @__PURE__ */ new Map();
37351
- const stepsByNamespace = /* @__PURE__ */ new Map();
37352
- for (const step of steps) {
37353
- if (step.kind !== "dataset") continue;
37354
- const output2 = readRecord(step.output);
37355
- if (typeof output2?.datasetId === "string") {
37356
- stepsByDatasetId.set(output2.datasetId, step);
37357
- }
37358
- if (typeof output2?.path === "string") {
37359
- stepsByPath.set(output2.path, step);
37360
- }
37361
- if (typeof step.id === "string") {
37362
- stepsByNamespace.set(step.id, step);
37363
- }
37364
- }
37365
- for (const dataset of packageDatasetRecords(packaged)) {
37366
- const path = typeof dataset.path === "string" && dataset.path.trim() ? dataset.path.trim() : "dataset";
37367
- const datasetId = typeof dataset.datasetId === "string" ? dataset.datasetId.trim() : "";
37368
- const isReturned = datasetId && returned.datasetIds.has(datasetId) || returned.paths.has(path);
37369
- const category = isReturned ? "returned" : dataset.recovered === true ? "recovered" : "persisted";
37370
- const rowCount = typeof dataset.rowCount === "number" && Number.isFinite(dataset.rowCount) ? Math.max(0, Math.trunc(dataset.rowCount)) : null;
37371
- const lifecycle = readRecord(dataset.lifecycle);
37372
- const countUnconfirmed = lifecycle?.complete === false;
37373
- const persistedLowerBound = typeof lifecycle?.persistedRowsAtLeast === "number" && Number.isFinite(lifecycle.persistedRowsAtLeast) ? Math.max(0, Math.trunc(lifecycle.persistedRowsAtLeast)) : 0;
37374
- const actions2 = readRecord(dataset.actions) ?? {};
37375
- if (countUnconfirmed) {
37376
- lines.push(
37377
- ` dataset ${path}: row count unconfirmed (at least ${formatInteger(persistedLowerBound)} persisted)`
37378
- );
37379
- } else if (includeSummary) {
37380
- if (category === "recovered" && Object.keys(actions2).length === 0) {
37381
- lines.push(
37382
- ` dataset ${path}: available, ${rowCount === null ? "persisted" : formatInteger(rowCount)} rows persisted; re-running reuses completed work`
37383
- );
37384
- } else {
37385
- lines.push(
37386
- ` ${category} dataset ${path}: ${rowCount === null ? "unknown rows" : `${formatInteger(rowCount)} ${rowCount === 1 ? "row" : "rows"}`}`
37387
- );
37388
- }
37389
- }
37390
- const step = (datasetId ? stepsByDatasetId.get(datasetId) : void 0) ?? stepsByPath.get(path) ?? (typeof dataset.tableNamespace === "string" ? stepsByNamespace.get(dataset.tableNamespace) : void 0);
37391
- const progress = readRecord(step?.progress);
37392
- if (progress) {
37393
- lines.push(` progress: ${formatRunStepProgress(progress)}`);
37394
- }
37395
- if (lifecycle) {
37396
- const succeeded = readNonNegativeInteger(lifecycle.succeededRowsAtLeast);
37397
- const failed = readNonNegativeInteger(lifecycle.failedRowsAtLeast);
37398
- const complete = lifecycle.complete === true;
37399
- lines.push(
37400
- ` saved: ${complete ? "" : "at least "}${formatInteger(persistedLowerBound)} persisted${succeeded === null ? "" : ` \xB7 ${complete ? "" : "at least "}${formatInteger(succeeded)} succeeded`}${failed === null ? "" : ` \xB7 ${complete ? "" : "at least "}${formatInteger(failed)} failed`}`
37401
- );
37402
- }
37403
- const exportAction = readRecord(actions2.exportCsv);
37404
- const exportCommand = actionToCommand(exportAction);
37405
- const exportScope = readRecord(exportAction?.scope);
37406
- const queryAction = readRecord(actions2.query);
37407
- const queryScope = readRecord(queryAction?.scope);
37408
- const runQueryCommand = queryScope?.kind === "run" ? actionToCommand(queryAction) : null;
37409
- const currentQueryCommand = actionToCommand(actions2.queryCurrentTable);
37410
- const legacyQueryCommand = actionToCommand(actions2.query);
37411
- if (runQueryCommand) {
37412
- lines.push(` query rows from this run: ${runQueryCommand}`);
37413
- } else if (currentQueryCommand) {
37414
- lines.push(` query current table: ${currentQueryCommand}`);
37415
- } else if (legacyQueryCommand) {
37416
- lines.push(` query run rows (legacy): ${legacyQueryCommand}`);
37417
- }
37418
- if (exportCommand) {
37419
- lines.push(
37420
- exportScope?.kind === "database" ? ` export current table (may include other runs): ${exportCommand}` : ` export this run: ${exportCommand}`
37421
- );
37422
- }
37423
- const unavailable = readRecord(dataset.exportUnavailable);
37424
- if (typeof unavailable?.reason === "string" && typeof unavailable.message === "string") {
37425
- lines.push(
37426
- ` export unavailable (${unavailable.reason}): ${unavailable.message}`
37427
- );
37428
- }
37429
- }
37430
- return lines;
37431
- }
37432
- function packageSavedRowCount(packaged) {
37433
- const rowCounts = packageDatasetRecords(packaged).map((dataset) => dataset.rowCount).filter(
37434
- (rowCount) => typeof rowCount === "number" && Number.isFinite(rowCount)
37435
- ).map((rowCount) => Math.max(0, Math.trunc(rowCount)));
37436
- if (rowCounts.length === 0) return null;
37437
- return rowCounts.reduce((total, rowCount) => total + rowCount, 0);
37438
- }
37439
- function runtimeLimitWindowLabel(runtimeLimitFailure) {
37440
- const message = getStringField(runtimeLimitFailure, "message") ?? "";
37441
- const configuredSeconds = /\bconfigured\s+(\d+)\s+second(?:s)?\s+runtime limit\b/i.exec(message)?.[1];
37442
- if (configuredSeconds) {
37443
- const seconds = Number(configuredSeconds);
37444
- if (Number.isSafeInteger(seconds) && seconds > 0) {
37445
- if (seconds % 3600 === 0) return `${seconds / 3600}-hour`;
37446
- if (seconds % 60 === 0) return `${seconds / 60}-minute`;
37447
- return `${seconds}-second`;
37448
- }
37449
- }
37450
- const match = /\b(\d+)\s+(hour|hours|minute|minutes|second|seconds)\b/i.exec(
37451
- message
37452
- );
37453
- if (!match) return "30-minute";
37454
- const unit = match[2].toLowerCase().replace(/s$/, "");
37455
- return `${match[1]}-${unit}`;
37456
- }
37457
- function runtimeLimitCheckpointLines(packaged, runId, runtimeLimitFailure) {
37458
- const savedRows = packageSavedRowCount(packaged);
37459
- const lines = [
37460
- `\u2713 progress saved ${runId}`,
37461
- "",
37462
- `The Play reached its ${runtimeLimitWindowLabel(runtimeLimitFailure)} runtime window.`
37463
- ];
37464
- if (savedRows === null) {
37465
- lines.push("Progress completed before the runtime window closed.");
37466
- } else {
37467
- lines.push(
37468
- `${formatInteger(savedRows)} ${savedRows === 1 ? "row was" : "rows were"} saved successfully.`
37469
- );
37470
- }
37471
- lines.push(
37472
- "",
37473
- "Run the same Play again to continue where you left off.",
37474
- "Completed work will be reused automatically."
37475
- );
37476
- return lines;
37477
- }
37478
- function formatInlinePackageValue(value) {
37479
- const compacted = compactReturnValue(value);
37480
- const json2 = JSON.stringify(compacted);
37481
- return clampJsonPreviewText(json2 ?? String(compacted), 500);
37482
- }
37483
- function formatPackageValueOutputLines(packaged) {
37484
- const outputs = packaged.outputs && typeof packaged.outputs === "object" && !Array.isArray(packaged.outputs) ? packaged.outputs : null;
37485
- if (!outputs) return [];
37486
- const returned = Object.entries(outputs).filter(([, output2]) => {
37487
- const record5 = readRecord(output2);
37488
- return record5?.kind === "dataset" || record5?.kind === "value" && Object.prototype.hasOwnProperty.call(record5, "value");
37489
- });
37490
- if (returned.length === 0) return [];
37491
- const datasets = packageDatasetRecords(packaged);
37492
- const datasetSteps = readRecordArray(packaged.steps).filter(
37493
- (step) => step.kind === "dataset"
37494
- );
37495
- const lines = [" result:"];
37496
- for (const [name, rawOutput] of returned.slice(0, 8)) {
37497
- const output2 = readRecord(rawOutput);
37498
- if (output2.kind === "dataset") {
37499
- const path = typeof output2.dataset === "string" ? output2.dataset : name;
37500
- const rowCount = readNonNegativeInteger(output2.rowCount);
37501
- lines.push(
37502
- ` ${name}: dataset ${path}${rowCount === null ? "" : ` (${formatInteger(rowCount)} persisted rows)`}`
37503
- );
37504
- const dataset = datasets.find(
37505
- (candidate) => typeof output2.datasetId === "string" && candidate.datasetId === output2.datasetId || candidate.path === path
37506
- );
37507
- const stepOutput = datasetSteps.map((step) => readRecord(step.output)).find(
37508
- (candidate) => typeof output2.datasetId === "string" && candidate?.datasetId === output2.datasetId || candidate?.path === path
37509
- );
37510
- const preview = readRecord(stepOutput?.preview ?? dataset?.preview);
37511
- const rows = Array.isArray(preview?.rows) ? preview.rows.slice(0, 2) : [];
37512
- if (rows.length > 0) {
37513
- lines.push(` sample rows (${rows.length}):`);
37514
- lines.push(
37515
- ...rows.map(
37516
- (row) => ` ${clampJsonPreviewText(JSON.stringify(row) ?? String(row), 350)}`
37517
- )
37518
- );
37519
- }
37520
- continue;
37521
- }
37522
- const value = output2.value;
37523
- const compacted = compactReturnValue(value);
37524
- if (compacted && typeof compacted === "object") {
37525
- lines.push(` ${name}:`);
37526
- lines.push(...formatJsonPreview(compacted).map((line) => ` ${line}`));
37527
- } else {
37528
- lines.push(` ${name}: ${formatInlinePackageValue(value)}`);
37529
- }
37530
- }
37531
- if (returned.length > 8) {
37532
- lines.push(` ... ${returned.length - 8} more output(s)`);
37533
- }
37534
- return lines;
37535
- }
37536
- function authoredPackageStackFrames(packaged) {
37537
- const stack = readRecordArray(packaged.errors).map((entry) => typeof entry.stack === "string" ? entry.stack : null).find((candidate) => Boolean(candidate?.trim()));
37538
- if (!stack) return [];
37539
- return stack.split("\n").map((line) => line.trim()).filter((line) => line.startsWith("at ")).filter(
37540
- (line) => !line.includes("/virtual/deepline-plays/") && !line.includes("/apps/play-runner/") && !line.includes("/shared_libs/play-runtime/") && !line.includes("node:internal")
37541
- ).slice(0, 5);
37542
- }
37543
37202
  function activityTargetLabel(target) {
37544
37203
  const kind = typeof target.kind === "string" ? target.kind : "target";
37545
37204
  const label = typeof target.label === "string" ? target.label.trim() : "";
@@ -37695,152 +37354,6 @@ function formatRunTimingTextLines(run) {
37695
37354
  ].join(" \xB7 ")}`
37696
37355
  ];
37697
37356
  }
37698
- function formatRecentRunLogLines(value) {
37699
- const logs = readRecord(value);
37700
- if (!logs || !Array.isArray(logs.tail)) return [];
37701
- const tail = logs.tail.filter(
37702
- (line) => typeof line === "string"
37703
- );
37704
- if (tail.length === 0) return [];
37705
- const shown = tail.map((line) => classifyLogLine(line)).filter(
37706
- (entry) => entry.level !== "debug" && !isProviderRowWaitLogLine(entry.line)
37707
- ).slice(-8);
37708
- const total = readNonNegativeInteger(logs.totalCount);
37709
- if (shown.length === 0) {
37710
- return [
37711
- ` recent logs: no non-debug lines in the retained preview (${total === null ? "total unknown" : `${formatInteger(total)} total`})`,
37712
- ...logs.truncated === true ? [" [older log bodies lost to retention limit]"] : []
37713
- ];
37714
- }
37715
- const lines = [
37716
- ` recent logs (${total === null ? "count unknown" : `${formatInteger(total)} total`}; showing ${shown.length}):`,
37717
- ...shown.map(
37718
- (entry) => ` ${clampJsonPreviewText(formatProviderCapacityWaitLogLine(entry.line) ?? formatMapProgressDiagnosticLogLine(entry.line) ?? entry.line, 350)}`
37719
- )
37720
- ];
37721
- if (logs.truncated === true) {
37722
- lines.push(" [older log bodies lost to retention limit]");
37723
- }
37724
- return lines;
37725
- }
37726
- function buildRunPackageTextLines(packaged) {
37727
- const run = readRunPackageRun(packaged);
37728
- const runId = typeof run.id === "string" ? run.id : "unknown";
37729
- const status = typeof run.status === "string" ? run.status : "unknown";
37730
- const playName = typeof run.playName === "string" ? run.playName : null;
37731
- const runtimeLimitFailure = readRecordArray(packaged.errors).find(
37732
- (entry) => entry.code === "RUNTIME_LIMIT_EXCEEDED"
37733
- );
37734
- const isRuntimeTimeout = status === "failed" && (runtimeLimitFailure !== void 0 || typeof run.error === "string" && /RUNTIME_LIMIT_EXCEEDED/.test(run.error));
37735
- const isRuntimeLimitCheckpoint = isRuntimeTimeout;
37736
- const checkpointFailure = runtimeLimitFailure ?? (typeof run.error === "string" ? { message: run.error } : { message: "The Play reached its runtime limit and was stopped." });
37737
- const lines = isRuntimeLimitCheckpoint ? runtimeLimitCheckpointLines(packaged, runId, checkpointFailure) : [
37738
- `${status === "completed" ? "\u2713" : status === "failed" ? "\u2717" : "\u2022"} ${status} ${runId}`
37739
- ];
37740
- const outcome = typeof run.outcome === "string" ? run.outcome : null;
37741
- if (outcome) lines.push(` outcome: ${outcome}`);
37742
- const recovery = readRecord(run.recovery);
37743
- if (recovery) {
37744
- const mode = typeof recovery.mode === "string" ? recovery.mode : "recovered";
37745
- const sourceRunId = typeof recovery.sourceRunId === "string" ? ` from ${recovery.sourceRunId}` : "";
37746
- lines.push(` recovery: ${mode}${sourceRunId}`);
37747
- }
37748
- const runError = typeof run.error === "string" && run.error.trim() ? run.error.trim() : null;
37749
- const structuredRuntimeLimitMessage = typeof runtimeLimitFailure?.message === "string" && runtimeLimitFailure.message.trim() ? `${typeof runtimeLimitFailure.code === "string" ? runtimeLimitFailure.code : "RUNTIME_LIMIT_EXCEEDED"}: ${runtimeLimitFailure.message.trim()}` : null;
37750
- const displayRunError = structuredRuntimeLimitMessage ?? runError;
37751
- if (!isRuntimeLimitCheckpoint && displayRunError && (status === "failed" || status === "cancelled")) {
37752
- lines.push(` error: ${truncateErrorForDisplay(displayRunError, runId)}`);
37753
- const stackFrames = authoredPackageStackFrames(packaged);
37754
- if (stackFrames.length > 0) {
37755
- lines.push(" stack:");
37756
- lines.push(...stackFrames.map((frame) => ` ${frame}`));
37757
- }
37758
- }
37759
- const failedLogs = readRecord(packaged.failedLogs);
37760
- const failedLogEntries = Array.isArray(failedLogs?.entries) ? failedLogs.entries.filter(
37761
- (entry) => typeof entry === "string"
37762
- ) : [];
37763
- const failedLogAssociation = typeof failedLogs?.association === "string" ? failedLogs.association : null;
37764
- const failedLogWarning = typeof failedLogs?.warning === "string" && failedLogs.warning.trim() ? failedLogs.warning.trim() : null;
37765
- if (failedLogEntries.length > 0) {
37766
- lines.push(" failed logs:");
37767
- lines.push(...failedLogEntries.map((entry) => ` ${entry}`));
37768
- }
37769
- if (failedLogAssociation === "retained_before_truncation") {
37770
- lines.push(" failed log context: last retained lines before truncation");
37771
- }
37772
- if (failedLogWarning) {
37773
- lines.push(` warning: ${failedLogWarning}`);
37774
- }
37775
- const packageWarnings = Array.isArray(packaged.warnings) ? Array.from(
37776
- new Set(
37777
- packaged.warnings.filter(
37778
- (warning) => typeof warning === "string" && warning.trim().length > 0
37779
- )
37780
- )
37781
- ).slice(0, 16) : [];
37782
- lines.push(...packageWarnings.map((warning) => ` warning: ${warning}`));
37783
- const failedLogNext = readRecord(failedLogs?.next);
37784
- if (failedLogWarning && typeof failedLogNext?.logs === "string") {
37785
- lines.push(
37786
- failedLogAssociation === "retained_before_truncation" ? ` retained logs: ${failedLogNext.logs}` : ` retry failed logs: ${failedLogNext.logs}`
37787
- );
37788
- }
37789
- if (playName && !isRuntimeLimitCheckpoint) {
37790
- lines.push(` play: ${playName}`);
37791
- }
37792
- lines.push(...formatRunTimingTextLines(run));
37793
- if (!isRuntimeLimitCheckpoint) {
37794
- lines.push(...buildRunActivityTextLines(run));
37795
- }
37796
- lines.push(...buildRunStatusEvidenceTextLines(packaged));
37797
- lines.push(...formatPackageValueOutputLines(packaged));
37798
- lines.push(
37799
- ...formatPackageDatasetActionLines(packaged, {
37800
- includeSummary: !isRuntimeLimitCheckpoint
37801
- })
37802
- );
37803
- lines.push(...formatRecentRunLogLines(packaged.logs));
37804
- const next = packaged.next && typeof packaged.next === "object" && !Array.isArray(packaged.next) ? packaged.next : {};
37805
- const logsCommand = actionToCommand(next.logs);
37806
- for (const step of isRuntimeLimitCheckpoint ? [] : readRecordArray(packaged.steps).slice(0, 8)) {
37807
- const id = typeof step.id === "string" ? step.id : "step";
37808
- const kind = typeof step.kind === "string" ? step.kind : "step";
37809
- const stepStatus = typeof step.status === "string" ? step.status : status;
37810
- const output2 = step.output && typeof step.output === "object" && !Array.isArray(step.output) ? step.output : null;
37811
- const rowCount = output2 && typeof output2.rowCount === "number" ? ` rows=${formatInteger(output2.rowCount)}` : "";
37812
- const preview = output2?.preview && typeof output2.preview === "object" && !Array.isArray(output2.preview) ? output2.preview : null;
37813
- const previewRows = Array.isArray(preview?.rows) ? preview.rows.length : null;
37814
- lines.push(` ${kind} ${id}: ${stepStatus}${rowCount}`);
37815
- lines.push(...formatPackageDatasetSummaryLines(output2?.summary));
37816
- if (previewRows !== null) {
37817
- lines.push(
37818
- ` preview=${previewRows}${preview?.truncated ? " truncated" : ""}`
37819
- );
37820
- }
37821
- }
37822
- const inspectCommand = actionToCommand(next.inspect);
37823
- const fullResultCommand = actionToCommand(next.full);
37824
- const hasCatalogExportAction = packageDatasetRecords(packaged).some(
37825
- (dataset) => Boolean(actionToCommand(readRecord(dataset.actions)?.exportCsv))
37826
- );
37827
- const legacyExportCommand = hasCatalogExportAction ? null : actionToCommand(next.export);
37828
- const runAgainCommand = typeof next.run === "string" && next.run.trim() ? next.run.trim() : null;
37829
- if (inspectCommand) lines.push(` inspect: ${inspectCommand}`);
37830
- if (fullResultCommand)
37831
- lines.push(
37832
- ` ${isRuntimeTimeout ? "full run details" : "full result"}: ${fullResultCommand}`
37833
- );
37834
- if (logsCommand) lines.push(` logs: ${logsCommand}`);
37835
- if (legacyExportCommand) {
37836
- lines.push(` export CSV: ${legacyExportCommand}`);
37837
- }
37838
- if (runAgainCommand && !isRuntimeLimitCheckpoint) {
37839
- lines.push(" run again (completed work is reused):");
37840
- lines.push(` ${runAgainCommand}`);
37841
- }
37842
- return lines;
37843
- }
37844
37357
  function buildOrdinaryPlayRunCommand(options, resolvedRevisionId) {
37845
37358
  const target = options.target.kind === "file" ? options.target.path : options.target.name;
37846
37359
  const parts = ["deepline", "plays", "run", shellSingleQuote(target)];
@@ -37926,6 +37439,57 @@ function buildRunLaunch(status) {
37926
37439
  )
37927
37440
  };
37928
37441
  }
37442
+ function buildPlayCompletionTextLines(status) {
37443
+ const overview = buildRunOverview(status);
37444
+ const { run } = overview;
37445
+ const failed = run.status === "failed";
37446
+ const label = run.status === "completed" ? overview.rowOutcomes?.hasRowFailures ? "Completed with row failures" : "Completed" : failed ? "Failed" : run.status;
37447
+ const lines = [
37448
+ `${label} ${run.playName ?? status.playName ?? "Play"}`,
37449
+ `Run: ${run.id}`
37450
+ ];
37451
+ for (const failure of overview.failures.steps) {
37452
+ lines.push(
37453
+ `Failed step: ${failure.stepId}${failure.message ? ` \u2014 ${failure.message}` : ""}`
37454
+ );
37455
+ }
37456
+ if (overview.errorDetails.run)
37457
+ lines.push(
37458
+ `Error: ${truncateErrorForDisplay(overview.errorDetails.run, run.id)}`
37459
+ );
37460
+ if (Object.hasOwn(overview, "result")) {
37461
+ lines.push(
37462
+ "Result:",
37463
+ ...formatJsonPreview(compactReturnValue(overview.result))
37464
+ );
37465
+ }
37466
+ if (overview.rowOutcomes?.hasRowFailures) {
37467
+ lines.push(
37468
+ `Rows: ${overview.rowOutcomes.completedRows} completed, ${overview.rowOutcomes.failedRows} failed`
37469
+ );
37470
+ }
37471
+ for (const dataset of overview.datasets) {
37472
+ lines.push(
37473
+ `Rows (${dataset.name ?? dataset.datasetId}): ${dataset.rowCount ?? "unknown"}`
37474
+ );
37475
+ if (dataset.exportUnavailable)
37476
+ lines.push(`Export unavailable: ${dataset.exportUnavailable.message}`);
37477
+ }
37478
+ for (const warning of overview.warnings) lines.push(`Warning: ${warning}`);
37479
+ const exports = overview.actions.exportDatasetCmds;
37480
+ if (Array.isArray(exports))
37481
+ for (const command of exports) lines.push(`Export CSV: ${command}`);
37482
+ lines.push(
37483
+ `Logs: ${failed ? String(
37484
+ overview.actions.getFailedLogsCmd ?? `deepline runs logs ${shellSingleQuote(run.id)} --failed`
37485
+ ) : String(
37486
+ overview.actions.getLogsCmd ?? `deepline runs logs ${shellSingleQuote(run.id)}`
37487
+ )}`
37488
+ );
37489
+ if (failed && status.rerunCommand)
37490
+ lines.push(`Retry: ${status.rerunCommand}`);
37491
+ return lines;
37492
+ }
37929
37493
  function writePlayResult(status, jsonOutput, options) {
37930
37494
  const packaged = getPlayRunPackage(status);
37931
37495
  const hits = options?.hits ?? null;
@@ -37944,10 +37508,7 @@ function writePlayResult(status, jsonOutput, options) {
37944
37508
  ...displayPackage
37945
37509
  } = compactPlayStatus(status);
37946
37510
  const lines2 = [
37947
- ...withRunNavigationLines(
37948
- buildRunPackageTextLines(displayPackage),
37949
- status
37950
- ),
37511
+ ...buildPlayCompletionTextLines(status),
37951
37512
  ...formatRunHitsLines(hits)
37952
37513
  ];
37953
37514
  printCommandEnvelope(displayPackage, {
@@ -37983,7 +37544,7 @@ function writePlayResult(status, jsonOutput, options) {
37983
37544
  )
37984
37545
  );
37985
37546
  if (status.status === "failed") {
37986
- lines.push(` failed logs: deepline runs get ${runId} --log-failed --json`);
37547
+ lines.push(` failed logs: deepline runs logs ${runId} --failed --json`);
37987
37548
  if (status.rerunCommand) {
37988
37549
  lines.push(" run again (completed work is reused):");
37989
37550
  lines.push(` ${status.rerunCommand}`);
@@ -38013,18 +37574,23 @@ function writePlayResult(status, jsonOutput, options) {
38013
37574
  );
38014
37575
  }
38015
37576
  function withRunNavigationLines(lines, status, actionCommands = buildRunNavigation(status).actions) {
38016
- const navigation = buildRunNavigation(status);
38017
37577
  const existing = lines.join("\n");
38018
- for (const dataset of navigation.datasets) {
38019
- if (dataset.storage.table)
38020
- lines.push(
38021
- ` dataset ${dataset.name}: ${dataset.storage.schema ? dataset.storage.schema + "." : ""}${dataset.storage.table}`
38022
- );
38023
- }
37578
+ const labels = {
37579
+ getRunCmd: "Inspect",
37580
+ getFullRunCmd: "Full run",
37581
+ getBillingCmd: "Billing",
37582
+ getLogsCmd: "Logs",
37583
+ getFailedLogsCmd: "Failure logs",
37584
+ getReceiptCmd: "Saved responses",
37585
+ exportDatasetCmds: "Export rows",
37586
+ queryTableSqlCmds: "Query rows",
37587
+ stopRunCmd: "Stop run",
37588
+ rerunCmd: "Retry"
37589
+ };
38024
37590
  for (const [name, value] of Object.entries(actionCommands)) {
38025
37591
  for (const command of Array.isArray(value) ? value : [value]) {
38026
37592
  if (typeof command === "string" && !existing.includes(command))
38027
- lines.push(` ${name}: ${command}`);
37593
+ lines.push(` ${labels[name] ?? name}: ${command}`);
38028
37594
  }
38029
37595
  }
38030
37596
  return lines;
@@ -38767,7 +38333,12 @@ function writeStartedPlayRun(input2) {
38767
38333
  failedLogs: _failedLogs,
38768
38334
  ...displayPackage
38769
38335
  } = input2.package;
38770
- const lines2 = buildRunPackageTextLines(displayPackage);
38336
+ const lines2 = buildPlayCompletionTextLines({
38337
+ runId: input2.runId,
38338
+ playName: input2.playName,
38339
+ status: input2.status,
38340
+ package: displayPackage
38341
+ });
38771
38342
  const output3 = lines2.join("\n");
38772
38343
  if (input2.progress) {
38773
38344
  input2.progress.writeLine(output3, process.stdout);
@@ -38795,17 +38366,11 @@ function writeStartedPlayRun(input2) {
38795
38366
  };
38796
38367
  const lines = [
38797
38368
  `Started ${input2.playName}`,
38798
- ` run id: ${input2.runId}`,
38799
- ` revision: ${input2.revisionLabel ?? "resolved by Deepline"}`,
38800
- ` input: ${input2.inputFieldCount ?? 0} top-level field(s) supplied`,
38801
- ` cache: ${input2.forceToolRefresh ? "completed provider receipts may be refreshed" : input2.force ? "fresh run graph; completed provider receipts may still be reused" : "completed provider receipts may be reused"}`,
38802
- ` inspect: deepline runs get ${input2.runId} --json`,
38803
- ` full debug: deepline runs get ${input2.runId} --full --json`,
38804
- ` logs: deepline runs logs ${input2.runId} --json`,
38805
- ` export after completion: deepline runs export ${input2.runId} --out output.csv`,
38369
+ `Run: ${input2.runId}`,
38370
+ `Logs: deepline runs logs ${shellSingleQuote(input2.runId)}`,
38806
38371
  ...["started", "queued", "running", "waiting"].includes(
38807
38372
  input2.status ?? "started"
38808
- ) ? [` stop run: deepline runs stop ${input2.runId} --json`] : []
38373
+ ) ? [`Stop: deepline runs stop ${shellSingleQuote(input2.runId)} --json`] : []
38809
38374
  ];
38810
38375
  if (input2.jsonOutput) {
38811
38376
  printCommandEnvelope(payload, { json: true, fields: input2.jsonFields });
@@ -40227,7 +39792,7 @@ function renderRunOverviewText(overview, extras = {}) {
40227
39792
  getBillingCmd: "Billing",
40228
39793
  getLogsCmd: "Logs",
40229
39794
  getFailedLogsCmd: "Failure logs",
40230
- getReceiptCmd: "Receipt",
39795
+ getReceiptCmd: "Saved responses",
40231
39796
  exportDatasetCmds: "Export rows",
40232
39797
  queryTableSqlCmds: "Query rows",
40233
39798
  stopRunCmd: "Stop run",
@@ -40249,7 +39814,7 @@ async function handleRunGet(args) {
40249
39814
  args.includes("--config") ? "config" : "get"
40250
39815
  );
40251
39816
  args = selection.args;
40252
- const usage2 = "Usage: deepline runs get <run-id> [--json] [--full] [--input] [--config] [--log-failed]";
39817
+ const usage2 = "Usage: deepline runs get <run-id> [--json] [--full] [--input] [--config]";
40253
39818
  let runId;
40254
39819
  try {
40255
39820
  runId = parseRunIdPositional(args, usage2);
@@ -43258,7 +42823,7 @@ Examples:
43258
42823
  deepline runs get play/my-play/run/20260501t000000-000
43259
42824
  deepline runs get play/my-play/run/20260501t000000-000 --json
43260
42825
  deepline runs get play/my-play/run/20260501t000000-000 --json run.status,run.durationMs
43261
- deepline runs get play/my-play/run/20260501t000000-000 --log-failed --json
42826
+ deepline runs logs play/my-play/run/20260501t000000-000 --failed --json
43262
42827
  deepline runs get play/my-play/run/20260501t000000-000 --full --json
43263
42828
  deepline runs get play/my-play/run/20260501t000000-000 --input
43264
42829
  deepline runs get play/my-play/run/20260501t000000-000 --config --json
@@ -43275,9 +42840,8 @@ Examples:
43275
42840
  ).option(
43276
42841
  "--config",
43277
42842
  "Explicitly print the recorded configuration, without full results"
43278
- ).option(
43279
- "--log-failed",
43280
- "Attach a bounded terminal-failure log window for failed runs"
42843
+ ).addOption(
42844
+ new Option4("--log-failed", "Attach terminal-failure logs").hideHelp()
43281
42845
  ).action(async (runId, options) => {
43282
42846
  process.exitCode = await handleRunGet([
43283
42847
  runId,
@@ -50728,7 +50292,10 @@ Examples:
50728
50292
  `
50729
50293
  Notes:
50730
50294
  Shows the compact agent contract by default: what the tool does, cost,
50731
- required inputs, play getters, and a runnable ctx.tools.execute snippet.
50295
+ required inputs, play getters, input and full Deepline response examples,
50296
+ and a ctx.tools.execute snippet. Tool responses live at toolResponse.rawV2;
50297
+ preserve the nesting shown in the tool's example. Schemas and examples are
50298
+ separate describe fields.
50732
50299
  get is accepted as a compatibility alias for describe.
50733
50300
 
50734
50301
  Examples:
@@ -50751,7 +50318,7 @@ Examples:
50751
50318
  "Quote an ai_evaluate, ai_inference, or deeplineagent JSON payload (inline or @file)"
50752
50319
  ).option("--pricing-only", "Only print pricing and billing semantics").option("--schema-only", "Only print input schema fields").option(
50753
50320
  "--examples-only",
50754
- "Only print runnable examples and sample payloads"
50321
+ "Only print input payload and full Deepline execution response examples"
50755
50322
  ).option("--getters-only", "Only print extracted list/value getters").addOption(
50756
50323
  new Option5(
50757
50324
  "--compact",
@@ -50928,6 +50495,30 @@ async function getTool(toolId, options = {}) {
50928
50495
  );
50929
50496
  return 0;
50930
50497
  }
50498
+ if ((options.schemaOnly || options.examplesOnly || options.gettersOnly) && !isMonitorTypeTool(tool) && !isPlayLikeTool(tool) && (options.json || options.contractJson)) {
50499
+ const contract = toolContractJsonForDescribe(tool, toolId);
50500
+ printCompactJson({
50501
+ toolId: contract.toolId,
50502
+ ...options.schemaOnly ? {
50503
+ inputSchema: contract.inputSchema,
50504
+ inputFields: contract.inputFields,
50505
+ outputSchema: contract.outputSchema,
50506
+ outputFields: contract.outputFields,
50507
+ responseSchema: contract.responseSchema
50508
+ } : options.examplesOnly ? {
50509
+ examples: contract.examples ?? [],
50510
+ responseAccess: contract.responseAccess,
50511
+ getters: contract.getters,
50512
+ executeCommand: contract.executeCommand
50513
+ } : {
50514
+ getters: contract.getters,
50515
+ responseAccess: contract.responseAccess
50516
+ },
50517
+ ...modelDescription ? { modelOptions: modelDescription } : {},
50518
+ ...inferenceQuote ? { inferenceQuote } : {}
50519
+ });
50520
+ return 0;
50521
+ }
50931
50522
  if (options.contractJson) {
50932
50523
  printCompactJson({
50933
50524
  ...toolContractJsonForDescribe(tool, toolId),
@@ -51069,6 +50660,9 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
51069
50660
  } : {},
51070
50661
  inputFields: inputFields.map(inputFieldJsonForDescribe),
51071
50662
  inputSchema,
50663
+ ...isRecord8(tool.responseSchema) ? { responseSchema: tool.responseSchema } : {},
50664
+ ...Array.isArray(tool.examples) ? { examples: tool.examples } : {},
50665
+ responseAccess: "result.toolResponse.rawV2",
51072
50666
  ...Object.keys(outputSchemaRecord).length > 0 ? {
51073
50667
  outputSchema: publicToolInputSchemaForDescribe(outputSchemaRecord),
51074
50668
  outputFields: outputFields.map(inputFieldJsonForDescribe)
@@ -51290,15 +50884,13 @@ function printCompactToolContract(tool, requestedToolId) {
51290
50884
  }
51291
50885
  }
51292
50886
  console.log("");
51293
- printToolExamplesOnly(tool, requestedToolId, { includeSamples: false });
50887
+ printToolExamplesOnly(tool, requestedToolId);
51294
50888
  const starterScript = isRecord8(contract.starterScript) ? contract.starterScript : {};
51295
50889
  const starterPath = stringField2(starterScript, "path");
51296
50890
  if (starterPath) {
51297
50891
  console.log("");
51298
50892
  console.log(`Starter script: ${starterPath}`);
51299
- console.log(
51300
- "Copy it into your project and replace the sample input with the proven probe payload."
51301
- );
50893
+ console.log("Copy it into your project and adapt the example input.");
51302
50894
  }
51303
50895
  if (listGetters.length || valueGetters.length) {
51304
50896
  console.log("");
@@ -51388,11 +50980,15 @@ function printToolSchemaOnly(tool, requestedToolId) {
51388
50980
  recordField(contract, "inputSchema")
51389
50981
  );
51390
50982
  if (declaredSchema) {
51391
- console.log("Declared JSON Schema:");
50983
+ console.log("Declared input JSON Schema:");
51392
50984
  console.log(JSON.stringify(declaredSchema, null, 2));
51393
50985
  }
50986
+ if (isRecord8(contract.responseSchema)) {
50987
+ console.log("Deepline execution response JSON Schema:");
50988
+ console.log(JSON.stringify(contract.responseSchema, null, 2));
50989
+ }
51394
50990
  }
51395
- function printToolExamplesOnly(tool, requestedToolId, options = {}) {
50991
+ function printToolExamplesOnly(tool, requestedToolId) {
51396
50992
  if (isMonitorTypeTool(tool)) {
51397
50993
  printMonitorTypeDeploy(tool);
51398
50994
  return;
@@ -51404,7 +51000,11 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
51404
51000
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
51405
51001
  const toolId = String(contract.toolId);
51406
51002
  const inputFields = Array.isArray(contract.inputFields) ? contract.inputFields : [];
51407
- const sampleInput = samplePayloadForInputFields(inputFields);
51003
+ const examples = arrayField2(tool, "examples").filter(isRecord8);
51004
+ const firstExample = examples[0];
51005
+ const sampleInput = firstExample && isRecord8(firstExample.input) ? firstExample.input : samplePayload(recordField(tool, "samples"), "request") ?? samplePayloadForInputFields(inputFields);
51006
+ console.log("Example input payload:");
51007
+ console.log(JSON.stringify(sampleInput, null, 2));
51408
51008
  console.log(`Use in a play:`);
51409
51009
  console.log("```ts");
51410
51010
  console.log("const result = await ctx.tools.execute({");
@@ -51414,6 +51014,7 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
51414
51014
  ` input: ${JSON.stringify(sampleInput || {}, null, 2).replace(/\n/g, "\n ")},`
51415
51015
  );
51416
51016
  console.log("});");
51017
+ console.log("const response = result.toolResponse.rawV2;");
51417
51018
  const getters = isRecord8(contract.getters) ? contract.getters : {};
51418
51019
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
51419
51020
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
@@ -51427,10 +51028,19 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
51427
51028
  );
51428
51029
  }
51429
51030
  console.log("```");
51430
- if (options.includeSamples !== false) {
51431
- const samples = recordField(tool, "samples");
51432
- printSamples(samples);
51031
+ for (const example of examples) {
51032
+ const description = stringField2(example, "description");
51033
+ if (description) console.log(description);
51034
+ console.log("Example Deepline execution response:");
51035
+ console.log(JSON.stringify(example.response, null, 2));
51433
51036
  }
51037
+ if (!examples.length)
51038
+ console.log(
51039
+ "No Deepline execution response example is published by this server."
51040
+ );
51041
+ console.log(
51042
+ "Read tool-specific fields from result.toolResponse.rawV2 using the nesting above. In a play, use the declared getters for extracted values and lists. Billing and execution metadata may also be returned."
51043
+ );
51434
51044
  }
51435
51045
  function printPlayLikeToolUsage(tool, requestedToolId) {
51436
51046
  const toolId = String(tool.toolId || requestedToolId);
@@ -51575,9 +51185,9 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
51575
51185
  inputFields: inputFields.map(inputFieldJsonForDescribe),
51576
51186
  usageGuidance,
51577
51187
  runtimeOutputHelp: {
51578
- contract: "tools describe shows declared schema and Deepline getters; it is not an observed provider response.",
51188
+ contract: "Schemas declare field shapes. Examples illustrate input payloads and full Deepline execution responses; they are not observed responses from this call.",
51579
51189
  getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
51580
- rawToolResponse: "Use toolExecutionResult.toolResponse.rawV2 for provider/tool-specific scalar fields, fields in outputSchema that are not declared getters, and debugging. Inspect the observed response envelope before selecting nested fields. For declared row/list outputs, use extractedLists.<name>.get().",
51190
+ rawToolResponse: "Use toolExecutionResult.toolResponse.rawV2 for the complete tool response. Preserve its nesting and sibling fields as shown in examples; use declared getters for extracted values and lists.",
51581
51191
  invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter.",
51582
51192
  observeActualShape: observedOutputCommand,
51583
51193
  observedOutput: observedOutputCommand,
@@ -51592,7 +51202,25 @@ function usageGuidanceWithAccessDefaults(usageGuidance) {
51592
51202
  const existingAccess = recordField(usageGuidance, "access");
51593
51203
  return {
51594
51204
  ...usageGuidance,
51205
+ prefer: [
51206
+ "Use only the declared extractedLists and extractedValues getters listed below.",
51207
+ "Use toolExecutionResult.toolResponse.rawV2 for the complete tool response, preserving the nesting shown in the response example.",
51208
+ "Schemas declare field shapes; examples illustrate input values and full Deepline execution responses."
51209
+ ],
51210
+ toolExecutionResult: {
51211
+ ...recordField(
51212
+ usageGuidance,
51213
+ "toolExecutionResult",
51214
+ "tool_execution_result"
51215
+ ),
51216
+ toolResponse: {
51217
+ rawV2: "toolResponse.rawV2",
51218
+ view: "toolResponse.view",
51219
+ responseMeta: "toolResponse.responseMeta"
51220
+ }
51221
+ },
51595
51222
  access: {
51223
+ ...existingAccess,
51596
51224
  extractedLists: {
51597
51225
  expression: "toolExecutionResult.extractedLists.<name>.get()",
51598
51226
  meaning: "Declared Deepline list extractors only."
@@ -51604,13 +51232,13 @@ function usageGuidanceWithAccessDefaults(usageGuidance) {
51604
51232
  ...existingAccess,
51605
51233
  rawToolResponse: {
51606
51234
  expression: "toolExecutionResult.toolResponse.rawV2",
51607
- meaning: "Complete parsed and scrubbed provider response for provider/tool-specific scalar fields and debugging. Inspect its envelope before selecting nested fields. Declared row/list outputs should use extractedLists.<name>.get()."
51235
+ meaning: "Complete tool response with its original nesting. Read tool-specific fields here; use declared getters for extracted values and lists."
51608
51236
  },
51609
51237
  canonicalToolResponse: {
51610
51238
  expression: "toolExecutionResult.toolResponse.rawV2",
51611
- meaning: "Complete parsed and scrubbed provider response, including envelope siblings, pagination, and metadata."
51239
+ meaning: "Complete tool response with its original nesting and sibling fields."
51612
51240
  },
51613
- invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter; inspect toolResponse.rawV2 for provider/tool-specific scalar fields, and use extractedLists.<name>.get() for declared row/list outputs."
51241
+ invalidGetterHint: "If TypeScript says an extractedValues/extractedLists property does not exist, that field is not a declared Deepline getter; read it from toolResponse.rawV2 using the nesting shown in the response example."
51614
51242
  }
51615
51243
  };
51616
51244
  }
@@ -51942,23 +51570,6 @@ function formatRateWindow(windowMs) {
51942
51570
  if (windowMs === 36e5) return "hour";
51943
51571
  return `${windowMs}ms`;
51944
51572
  }
51945
- function printSamples(samples) {
51946
- const requestPayload = samplePayload(samples, "request");
51947
- const responsePayload = samplePayload(samples, "response");
51948
- if (requestPayload === void 0 && responsePayload === void 0) return;
51949
- console.log(" Samples:");
51950
- if (requestPayload !== void 0)
51951
- printJsonPreview("Example payload", requestPayload);
51952
- if (responsePayload !== void 0)
51953
- printJsonPreview("Example response", responsePayload);
51954
- }
51955
- function printJsonPreview(label, payload) {
51956
- console.log(` ${label}:`);
51957
- const rendered = JSON.stringify(payload, null, 2);
51958
- for (const line of rendered.split("\n")) {
51959
- console.log(` ${line}`);
51960
- }
51961
- }
51962
51573
  function samplePayload(samples, key) {
51963
51574
  const entry = samples[key];
51964
51575
  if (!isRecord8(entry)) return void 0;