deepline 0.3.273 → 0.3.275

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/sdk/src/client.ts +143 -14
  2. package/dist/bundling-sources/sdk/src/index.ts +4 -1
  3. package/dist/bundling-sources/sdk/src/play.ts +5 -11
  4. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  5. package/dist/bundling-sources/sdk/src/runs/log-cursor.ts +35 -0
  6. package/dist/bundling-sources/sdk/src/types.ts +10 -3
  7. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +12 -26
  8. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +7 -3
  9. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +15 -7
  10. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +18 -18
  11. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1 -0
  12. package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +7 -4
  13. package/dist/bundling-sources/shared_libs/plays/table-csv.ts +152 -0
  14. package/dist/cli/index.js +418 -103
  15. package/dist/cli/index.mjs +418 -103
  16. package/dist/{client-5xpuGpRn.d.ts → client-5zY7LsId.d.ts} +72 -7
  17. package/dist/{client-D9annc6K.d.mts → client-CbNvJLgV.d.mts} +72 -7
  18. package/dist/index.d.mts +6 -12
  19. package/dist/index.d.ts +6 -12
  20. package/dist/index.js +90 -12
  21. package/dist/index.mjs +90 -12
  22. package/dist/install-integrity.json +4 -2
  23. package/dist/plays/run-request.d.mts +1 -1
  24. package/dist/plays/run-request.d.ts +1 -1
  25. package/dist/release.d.mts +1 -1
  26. package/dist/release.d.ts +1 -1
  27. package/dist/release.js +1 -1
  28. package/dist/release.mjs +1 -1
  29. package/package.json +1 -1
@@ -1953,7 +1953,7 @@ configureProxyFromEnv();
1953
1953
  import { mkdtemp as mkdtemp4, rm as rm4, writeFile as writeFile7 } from "fs/promises";
1954
1954
  import { join as join29 } from "path";
1955
1955
  import { tmpdir as tmpdir7 } from "os";
1956
- import { Command as Command6 } from "commander";
1956
+ import { Command as Command7 } from "commander";
1957
1957
 
1958
1958
  // ../plays/trigger-config-route.ts
1959
1959
  function playTriggerConfigPath(playName) {
@@ -1985,18 +1985,18 @@ function playInputExampleArgs(schema) {
1985
1985
  if (!schema) return " --input '@<input.json>'";
1986
1986
  if (schema.$ref || schema.allOf) return " --input '@<input.json>'";
1987
1987
  const csv = schema.csvInput;
1988
- const csvField = typeof csv?.inputField === "string" ? csv.inputField : null;
1988
+ const csvField2 = typeof csv?.inputField === "string" ? csv.inputField : null;
1989
1989
  const required = Array.isArray(schema.required) ? schema.required : [];
1990
- const csvOnlyRequired = required.every((key) => key === csvField);
1990
+ const csvOnlyRequired = required.every((key) => key === csvField2);
1991
1991
  const alternatives = schema.oneOf ?? schema.anyOf;
1992
1992
  const hasCsvAlternative = Array.isArray(alternatives) && alternatives.some((branch) => {
1993
1993
  if (!branch || typeof branch !== "object") return false;
1994
1994
  const keys = branch.required;
1995
- return Array.isArray(keys) && keys.includes(csvField) && keys.every((key) => key === csvField);
1995
+ return Array.isArray(keys) && keys.includes(csvField2) && keys.every((key) => key === csvField2);
1996
1996
  });
1997
- if (csvField && csvOnlyRequired && (!alternatives || hasCsvAlternative)) {
1998
- if (csvField === "csv") return " --csv '<contacts.csv>'";
1999
- const value = JSON.stringify({ [csvField]: "<contacts.csv>" });
1997
+ if (csvField2 && csvOnlyRequired && (!alternatives || hasCsvAlternative)) {
1998
+ if (csvField2 === "csv") return " --csv '<contacts.csv>'";
1999
+ const value = JSON.stringify({ [csvField2]: "<contacts.csv>" });
2000
2000
  return ` --input '${value.replace(/'/g, "'\\''")}'`;
2001
2001
  }
2002
2002
  if (Array.isArray(schema.required) && !required.length && !csv && !alternatives) {
@@ -3507,7 +3507,7 @@ var SDK_RELEASE = {
3507
3507
  // getters keep their established compatibility behavior.
3508
3508
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3509
3509
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3510
- version: "0.3.273",
3510
+ version: "0.3.275",
3511
3511
  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.",
3512
3512
  packageCapabilities: {
3513
3513
  updatePreferences: 1
@@ -6210,6 +6210,28 @@ async function* watchRunEvents(options) {
6210
6210
  }
6211
6211
  }
6212
6212
 
6213
+ // src/runs/log-cursor.ts
6214
+ var RUN_LOGS_CURSOR_PREFIX = "before:";
6215
+ function encodeRunLogsCursor(beforeSequence) {
6216
+ return `${RUN_LOGS_CURSOR_PREFIX}${beforeSequence}`;
6217
+ }
6218
+ function isRunLogsCursor(value) {
6219
+ return value.startsWith(RUN_LOGS_CURSOR_PREFIX);
6220
+ }
6221
+ function parseRunLogsCursor(value) {
6222
+ const raw = isRunLogsCursor(value) ? value.slice(RUN_LOGS_CURSOR_PREFIX.length) : "";
6223
+ const parsed = /^[1-9]\d*$/.test(raw) ? Number(raw) : NaN;
6224
+ if (!Number.isSafeInteger(parsed)) {
6225
+ throw Object.assign(
6226
+ new Error(
6227
+ `Invalid run log cursor ${JSON.stringify(value)}. Pass the nextCursor value from a previous deepline runs logs result.`
6228
+ ),
6229
+ { exitCode: 2 }
6230
+ );
6231
+ }
6232
+ return parsed;
6233
+ }
6234
+
6213
6235
  // src/types.ts
6214
6236
  function isStopAllPlayRunsDryRunResult(result) {
6215
6237
  return "dryRun" in result && result.dryRun === true;
@@ -7160,6 +7182,7 @@ var DeeplineClient = class _DeeplineClient {
7160
7182
  status: (runId) => this.getRunLifecycleStatus(runId),
7161
7183
  list: (options2) => this.listRuns(options2),
7162
7184
  listPage: (options2) => this.listRunsPage(options2),
7185
+ history: (options2) => this.getRunsHistory(options2),
7163
7186
  watch: (runId, options2) => this.watchRunToTerminal(runId, options2),
7164
7187
  tail: (runId, options2) => this.tailRun(runId, options2),
7165
7188
  logs: (runId, options2) => this.getRunLogs(runId, options2),
@@ -7290,7 +7313,7 @@ var DeeplineClient = class _DeeplineClient {
7290
7313
  }
7291
7314
  playRunCommand(play) {
7292
7315
  const target = play.reference || play.name;
7293
- return `deepline plays run ${target}${playInputExampleArgs(play.inputSchema)} --watch`;
7316
+ return `deepline plays run ${target}${playInputExampleArgs(play.inputSchema)}`;
7294
7317
  }
7295
7318
  starterPlayPath(play) {
7296
7319
  const target = play.reference || play.name;
@@ -7851,7 +7874,7 @@ var DeeplineClient = class _DeeplineClient {
7851
7874
  * Convenience wrapper around {@link registerPlayArtifact} plus
7852
7875
  * {@link startPlayRun}. This is the canonical file-backed path used by wrappers.
7853
7876
  * The returned id can be passed to {@link getPlayStatus} to retrieve the same
7854
- * durable `{ result }` object that the CLI prints after `--watch` completes.
7877
+ * durable `{ result }` object that the CLI prints after `plays run` completes.
7855
7878
  *
7856
7879
  * @param code - Source string fallback; the bundled artifact should be passed in `options.artifact`
7857
7880
  * @param csvPath - Path to input CSV file, or `null`
@@ -7972,7 +7995,7 @@ var DeeplineClient = class _DeeplineClient {
7972
7995
  * Get the current status of a play execution.
7973
7996
  *
7974
7997
  * Internal/advanced primitive. Public callers should usually prefer
7975
- * {@link runPlay}, {@link PlayJob.get}, or `deepline plays run --watch`.
7998
+ * {@link runPlay}, {@link PlayJob.get}, or `deepline plays run`.
7976
7999
  *
7977
8000
  * @param workflowId - Play-run id from {@link startPlayRun}
7978
8001
  * @returns Current status with progress logs and partial results
@@ -8237,11 +8260,21 @@ var DeeplineClient = class _DeeplineClient {
8237
8260
  if (options?.full === true) {
8238
8261
  params.set("full", "true");
8239
8262
  }
8263
+ if (options?.configuration === true) {
8264
+ params.set("include", "configuration");
8265
+ }
8240
8266
  const query = params.size > 0 ? `?${params.toString()}` : "";
8241
8267
  const response = await this.http.get(
8242
8268
  `/api/v2/runs/${encodeURIComponent(runId)}${query}`,
8243
8269
  { headers: { "x-deepline-run-status": "1" } }
8244
8270
  );
8271
+ if (options?.configuration === true && !Object.hasOwn(response, "contract")) {
8272
+ throw new DeeplineError(
8273
+ "This server does not support recorded configuration reads.",
8274
+ void 0,
8275
+ "RUN_CONFIGURATION_UNAVAILABLE"
8276
+ );
8277
+ }
8245
8278
  const status = normalizePlayStatus(response);
8246
8279
  if (options?.failedLogs !== true || status.status !== "failed") {
8247
8280
  return status;
@@ -8329,6 +8362,33 @@ var DeeplineClient = class _DeeplineClient {
8329
8362
  async listRuns(options) {
8330
8363
  return (await this.listRunsPage(options)).runs;
8331
8364
  }
8365
+ /** The same tenant-scoped run history searched by the dashboard and CLI. */
8366
+ async getRunsHistory(options = {}) {
8367
+ const params = new URLSearchParams();
8368
+ const search = options.search?.trim();
8369
+ if (search && search.length > 200) {
8370
+ throw new Error("Run search must be at most 200 characters.");
8371
+ }
8372
+ if (options.type && options.type !== "all" && !search) {
8373
+ throw new Error("runs.history options.type requires options.search.");
8374
+ }
8375
+ if (search) params.set("search", search);
8376
+ if (search && options.type) params.set("type", options.type);
8377
+ if (options.cursor) params.set("cursor", options.cursor);
8378
+ if (options.orgId) params.set("orgId", options.orgId);
8379
+ if (options.limit !== void 0) {
8380
+ if (!Number.isSafeInteger(options.limit) || options.limit < 1) {
8381
+ throw new Error(
8382
+ "runs.history options.limit must be a positive integer."
8383
+ );
8384
+ }
8385
+ params.set("limit", String(options.limit));
8386
+ }
8387
+ return this.http.get(
8388
+ `/api/v2/dashboard/runs-history?${params.toString()}`,
8389
+ { signal: options.signal }
8390
+ );
8391
+ }
8332
8392
  /** Read one run page without discarding server pagination metadata. */
8333
8393
  async listRunsPage(options) {
8334
8394
  const playName = options.play?.trim();
@@ -8435,6 +8495,13 @@ var DeeplineClient = class _DeeplineClient {
8435
8495
  "INVALID_RUN_LOG_VIEW"
8436
8496
  );
8437
8497
  }
8498
+ if (options?.cursor !== void 0 && options.failed === true) {
8499
+ throw new DeeplineError(
8500
+ "runs.logs cannot combine failed with cursor.",
8501
+ void 0,
8502
+ "INVALID_RUN_LOG_VIEW"
8503
+ );
8504
+ }
8438
8505
  if (options?.failed === true) {
8439
8506
  const requestedLimit = typeof options.limit === "number" && Number.isFinite(options.limit) && options.limit > 0 ? Math.trunc(options.limit) : RUNS_FAILED_LOG_LIMIT;
8440
8507
  const failedLimit = Math.min(RUNS_FAILED_LOG_LIMIT, requestedLimit);
@@ -8460,6 +8527,7 @@ var DeeplineClient = class _DeeplineClient {
8460
8527
  ...page.logsTruncated ? { logsTruncated: true } : {}
8461
8528
  };
8462
8529
  }
8530
+ const beforeSequence = options?.cursor !== void 0 ? parseRunLogsCursor(options.cursor) : null;
8463
8531
  const limit = options?.all ? Number.MAX_SAFE_INTEGER : typeof options?.limit === "number" && Number.isFinite(options.limit) && options.limit > 0 ? Math.trunc(options.limit) : 200;
8464
8532
  const fetchPage = (afterSeq2, pageLimit) => this.http.get(
8465
8533
  `/api/v2/runs/${encodeURIComponent(runId)}/logs?afterSeq=${afterSeq2}&limit=${pageLimit}`,
@@ -8467,24 +8535,33 @@ var DeeplineClient = class _DeeplineClient {
8467
8535
  );
8468
8536
  const probe = await fetchPage(0, 1);
8469
8537
  const lastStoredSeq = probe.lastStoredSeq;
8470
- let afterSeq = options?.all ? 0 : Math.max(0, lastStoredSeq - limit);
8538
+ const oldestStoredSeq = probe.entries[0]?.seq ?? null;
8539
+ const upperSeq = beforeSequence === null ? Number.POSITIVE_INFINITY : Math.min(beforeSequence - 1, lastStoredSeq);
8540
+ const windowEndSeq = Math.min(upperSeq, lastStoredSeq);
8541
+ let afterSeq = options?.all ? 0 : Math.max(0, windowEndSeq - limit);
8471
8542
  const entries = [];
8472
- while (entries.length < limit) {
8543
+ while (entries.length < limit && afterSeq < upperSeq) {
8473
8544
  const page = await fetchPage(
8474
8545
  afterSeq,
8475
- Math.min(RUN_LOGS_PAGE_LIMIT, limit - entries.length)
8546
+ Math.min(
8547
+ RUN_LOGS_PAGE_LIMIT,
8548
+ limit - entries.length,
8549
+ upperSeq - afterSeq
8550
+ )
8476
8551
  );
8477
- if (page.entries.length === 0) {
8552
+ const inWindow = page.entries.filter((entry) => entry.seq <= upperSeq);
8553
+ if (inWindow.length === 0) {
8478
8554
  break;
8479
8555
  }
8480
- entries.push(...page.entries);
8481
- afterSeq = page.entries[page.entries.length - 1].seq;
8482
- if (!page.hasMore) {
8556
+ entries.push(...inWindow);
8557
+ afterSeq = inWindow[inWindow.length - 1].seq;
8558
+ if (!page.hasMore || inWindow.length < page.entries.length) {
8483
8559
  break;
8484
8560
  }
8485
8561
  }
8486
8562
  const firstSequence = entries.length > 0 ? entries[0].seq : null;
8487
8563
  const lastSequence = entries.length > 0 ? entries[entries.length - 1].seq : null;
8564
+ const olderLinesExist = firstSequence !== null && oldestStoredSeq !== null && firstSequence > oldestStoredSeq;
8488
8565
  return {
8489
8566
  runId: probe.runId,
8490
8567
  totalCount: probe.totalLogCount,
@@ -8492,7 +8569,8 @@ var DeeplineClient = class _DeeplineClient {
8492
8569
  firstSequence,
8493
8570
  lastSequence,
8494
8571
  truncated: entries.length < probe.totalLogCount,
8495
- hasMore: lastSequence !== null && lastSequence < lastStoredSeq,
8572
+ hasMore: olderLinesExist,
8573
+ nextCursor: olderLinesExist ? encodeRunLogsCursor(firstSequence) : null,
8496
8574
  entries: entries.map((entry) => entry.line),
8497
8575
  view: options?.all ? "all" : "tail",
8498
8576
  ...probe.logsTruncated ? { logsTruncated: true } : {}
@@ -10469,6 +10547,7 @@ var ROOTS = {
10469
10547
  check: "kind target checked scope name exportName valid stage issues inputSchema outputSchema recognized triggers runtimeLimit limits featureFlags sourceHash artifactHash graphHash toolGetterHints exports actions diagnostics reference origin ownerType activeScheduledPlays command_context",
10470
10548
  run: "schemaVersion kind run datasets actions apiVersion dashboardUrl progress rowOutcomes steps errors error warnings result resultState execution command_context diagnostics",
10471
10549
  get: "schemaVersion kind run runStatus steps failures errorDetails rowOutcomes warnings failedLogs datasets result resultState actions diagnostics command_context",
10550
+ config: "runId contract command_context",
10472
10551
  export: "runId datasets csv_path json_path format source rowCount columns notice metadata_path actions command_context"
10473
10552
  };
10474
10553
  function parseJsonFields(args, surface) {
@@ -14911,7 +14990,7 @@ import {
14911
14990
  } from "fs/promises";
14912
14991
  import { homedir as homedir6, tmpdir as tmpdir5 } from "os";
14913
14992
  import { basename as basename4, dirname as dirname11, extname as extname3, join as join15, resolve as resolve14 } from "path";
14914
- import { Option as Option3 } from "commander";
14993
+ import { Option as Option4 } from "commander";
14915
14994
 
14916
14995
  // ../plays/settings-contract.ts
14917
14996
  import { z } from "zod";
@@ -15814,12 +15893,12 @@ var SECTIONS = [
15814
15893
  title: "Choose the read",
15815
15894
  paragraphs: [
15816
15895
  "These commands read existing evidence; they do not start a run or execute a provider. Replace <run-id>, <play-name> and other angle-bracket values with identifiers returned by the CLI.",
15817
- "Text logs: runs logs <run-id> returns the last 200 retained lines by default. --out writes the full retained stream to a local file. --log-level filters text severity; debug includes all retained levels. --failed reads only a terminal-failed run\u2019s last 20 retained lines and reports retention limitations.",
15818
- "Event search: omit the run ID, or add any of --since, --until, --play, --kind, --where, --payloads, --cursor, --runtime-namespace or --runtime-backend. A supplied run ID then narrows the search. --limit and --json alone do not switch a run\u2019s text logs to event search. Text-only flags --out, --failed, --log-level, --logs and --debug cannot be combined with event search.",
15896
+ "Text logs: runs logs <run-id> returns the last 200 retained lines by default. When older lines exist, hasMore is true and nextCursor continues the next older page with --cursor. --out writes the full retained stream to a local file. --log-level filters text severity; debug includes all retained levels. --failed reads only a terminal-failed run\u2019s last 20 retained lines and reports retention limitations.",
15897
+ "Event search: omit the run ID, or add any of --since, --until, --play, --kind, --where, --payloads, --runtime-namespace or --runtime-backend. A supplied run ID then narrows the search. --cursor continues event search unless it is a returned before:<sequence> text-log cursor. --limit and --json alone do not switch a run\u2019s text logs to event search. Text-only flags --out, --failed and --log-level cannot be combined with event search.",
15819
15898
  "Current status and returned output selectors: runs get <run-id> --json. Live observation: runs watch <run-id>. Dataset rows: runs export <run-id> --dataset <returned-selector> --out rows.csv. A referenced tool response: runs receipt <run-id> --key <returned-receipt-key> --json. Read each command\u2019s --help for its options."
15820
15899
  ],
15821
15900
  commands: [
15822
- "deepline runs logs <run-id> --json",
15901
+ "deepline runs logs <run-id> --cursor before:1201 --json",
15823
15902
  "deepline runs logs <run-id> --out run.log --json",
15824
15903
  "deepline runs logs --kind run.failed --json",
15825
15904
  "deepline runs logs --kind step.failed --payloads --json",
@@ -15843,13 +15922,24 @@ var SECTIONS = [
15843
15922
  "Identity strings: orgId, runId, playName, runtimeScope. These come from authenticated execution state; filters only narrow your authorized organization/runtime. Preview reads require the existing runtime credential and an authorized --runtime-namespace; --runtime-backend selects daytona or modal.",
15844
15923
  "Event string: kind. Optional strings: source, stepId, stepKind, status, datasetId, phase, provider, operation. Optional positive integer: producerAttempt. These fields exist only when recorded; inspect a returned event before filtering on an optional field.",
15845
15924
  'stepId/stepKind describe recorded step work; datasetId/phase describe dataset lifecycle (registered, available, failed). provider/operation appear on typed provider activity.observed events, not every receipt or provider call. status is the recorded status or activity state when present: run.completed and step.completed do not imply status == "completed". Select lifecycle outcomes with --kind.',
15846
- "context.<key> matches an authored flat scalar log field: string, number or boolean. Context cannot override event identity. Missing fields do not match. --where supports only $.field == literal predicates joined with &&, at most eight predicates and 512 bytes. No OR, ranges, wildcards, nested payload paths or text search. Time uses --since/--until; level and message are not --where fields."
15925
+ "context.<key> matches an authored flat scalar log field: string, number or boolean. Context cannot override event identity. Missing fields do not match. --where supports only $.field == literal predicates joined with &&, at most eight predicates and 512 bytes. No OR, ranges, wildcards, nested payload paths or text search. Time uses --since/--until; level and message are not --where fields.",
15926
+ 'Wrap the entire predicate in single shell quotes so $ and && reach the CLI unchanged. Inside it, strings use double quotes; numbers and booleans are unquoted. Types must match: 2 differs from "2", false differs from "false". Examples use illustrative recorded values; use your own step IDs, dataset IDs, provider/operation names and authored context. The context examples assume ctx.log recorded companyId: "acme_123", attempt: 2 and cached: false.'
15847
15927
  ],
15848
15928
  commands: [
15929
+ "# Failed retained work with its stored error/result",
15849
15930
  `deepline runs logs --kind receipt.failed --where '$.status == "failed"' --payloads --json`,
15850
- `deepline runs logs <run-id> --where '$.source == "worker" && $.producerAttempt == 1' --json`,
15851
- `deepline runs logs --kind activity.observed --where '$.provider == "<returned-provider>" && $.operation == "<returned-operation>"' --json`,
15852
- `deepline runs logs --kind log.appended --where '$.context.<authored-key> == "<recorded-value>"' --json`
15931
+ "# Failure details for one named step",
15932
+ `deepline runs logs --kind step.failed --where '$.stepId == "company-lookup"' --payloads --json`,
15933
+ "# Typed provider observations matching both fields",
15934
+ `deepline runs logs --kind activity.observed --where '$.provider == "apollo" && $.operation == "company_lookup"' --json`,
15935
+ "# Failed lifecycle transitions for one dataset",
15936
+ `deepline runs logs --kind dataset.lifecycle --where '$.datasetId == "companies" && $.phase == "failed"' --payloads --json`,
15937
+ "# Authored string context on log lines",
15938
+ `deepline runs logs --kind log.appended --where '$.context.companyId == "acme_123"' --json`,
15939
+ "# Authored number and boolean context, both required to match",
15940
+ "deepline runs logs --kind log.appended --where '$.context.attempt == 2 && $.context.cached == false' --json",
15941
+ "# Known producer identity within one run",
15942
+ `deepline runs logs <run-id> --where '$.source == "worker" && $.producerAttempt == 1' --json`
15853
15943
  ]
15854
15944
  },
15855
15945
  {
@@ -16741,6 +16831,7 @@ import {
16741
16831
  relative as relative5,
16742
16832
  resolve as resolve13
16743
16833
  } from "path";
16834
+ import { Option as Option3 } from "commander";
16744
16835
 
16745
16836
  // src/cli/commands/plays/bootstrap.ts
16746
16837
  import {
@@ -17101,7 +17192,7 @@ Example: deepline plays bootstrap people-email --from csv:data/leads.csv --using
17101
17192
  `Unknown plays bootstrap template: ${rawTemplate}
17102
17193
  Supported templates: ${formatPlayBootstrapTemplates()}|${MONITOR_BOOTSTRAP_TEMPLATE}` + (looksLikePlayReference ? `
17103
17194
 
17104
- "${rawTemplate}" looks like an existing play reference or file, not a bootstrap template. Do not run plays bootstrap on prebuilt/<play-name>. Use "deepline plays run ${rawTemplate} --input '{...}' --watch" to run it directly, "deepline plays describe ${rawTemplate} --json" to inspect its contract, or "deepline plays get ${rawTemplate} --source --out scratchpad.play.ts" to clone/edit it.` : "")
17195
+ "${rawTemplate}" looks like an existing play reference or file, not a bootstrap template. Do not run plays bootstrap on prebuilt/<play-name>. Use "deepline plays run ${rawTemplate} --input '{...}'" to run it directly, "deepline plays describe ${rawTemplate} --json" to inspect its contract, or "deepline plays get ${rawTemplate} --source --out scratchpad.play.ts" to clone/edit it.` : "")
17105
17196
  );
17106
17197
  }
17107
17198
  return rawTemplate;
@@ -17870,7 +17961,7 @@ function playUsesMapBackedRuntime(play) {
17870
17961
  }
17871
17962
  function assertComposablePlayRoute(input2) {
17872
17963
  if (!input2.playRef || !playUsesMapBackedRuntime(input2.play)) return;
17873
- const runCommand2 = input2.play?.runCommand?.trim() || `deepline plays run ${input2.playRef} --input '{...}' --watch`;
17964
+ const runCommand2 = input2.play?.runCommand?.trim() || `deepline plays run ${input2.playRef} --input '{...}'`;
17874
17965
  throw new PlayBootstrapValidationError(
17875
17966
  `Cannot use ${input2.stageLabel} play:${input2.playRef} in plays bootstrap composition: the selected play is dataset-backed/direct-run-only. Child plays that use ctx.dataset() own durable table state and must be run directly, exported, or validated as their own play instead of wrapped with ctx.runPlay. Run it directly first: ${runCommand2}`
17876
17967
  );
@@ -17912,14 +18003,14 @@ function generatePlaySourceRowsBlock(input2) {
17912
18003
  sourcePlay: input2.sourcePlay
17913
18004
  })) {
17914
18005
  const sourcePlay = input2.sourcePlay;
17915
- const runCommand2 = sourcePlay?.runCommand?.trim() || `deepline plays run ${input2.source.value} --input '{...}' --watch`;
18006
+ const runCommand2 = sourcePlay?.runCommand?.trim() || `deepline plays run ${input2.source.value} --input '{...}'`;
17916
18007
  return `// Source play ${input2.source.value} is dataset-backed/direct-run-only, so this generated play is stage 2.
17917
18008
  // Stage 1:
17918
18009
  // ${runCommand2}
17919
18010
  // Stage 2:
17920
18011
  // deepline runs export <stage-1-run-id> --dataset 'result.rows' --out source-export.csv
17921
18012
  // Stage 3:
17922
- // deepline plays run <this-file.play.ts> --input '{"sourceCsv":"source-export.csv","limit":${input2.sourcePlay ? "5" : "5"}}' --watch
18013
+ // deepline plays run <this-file.play.ts> --input '{"sourceCsv":"source-export.csv","limit":${input2.sourcePlay ? "5" : "5"}}'
17923
18014
  const sourceDataset = await ctx.csv<${input2.collectionType}>(input.sourceCsv ?? './source-export.csv');
17924
18015
  const ${input2.collection}: ${input2.collectionType}[] = await sourceDataset.peek(limit);`;
17925
18016
  }
@@ -18399,7 +18490,7 @@ Notes:
18399
18490
  Examples:
18400
18491
  deepline plays bootstrap people-email --from csv:data/leads.csv --using play:prebuilt/name-and-domain-to-email-waterfall --limit 5 --out email-flow.play.ts
18401
18492
  deepline plays check email-flow.play.ts
18402
- deepline plays run email-flow.play.ts --input '{"limit":5}' --watch
18493
+ deepline plays run email-flow.play.ts --input '{"limit":5}'
18403
18494
 
18404
18495
  deepline plays bootstrap people-email --from provider:dropleads_search_people --using providers:hunter_email_finder,leadmagic_email_finder --limit 5 --out prospecting.play.ts
18405
18496
  deepline plays bootstrap company-people-email --from provider:crustdata_companydb_search --people play:prebuilt/company-to-contact --email play:prebuilt/name-and-domain-to-email-waterfall --limit 5 --out account-contacts.play.ts
@@ -18587,24 +18678,31 @@ includes nextCommand when another page is available.
18587
18678
 
18588
18679
  // src/cli/commands/plays/run-history.ts
18589
18680
  async function handleRunsHistory(options) {
18590
- const query = new URLSearchParams();
18591
- if (options.cursor) query.set("cursor", options.cursor);
18592
- if (options.org) query.set("orgId", options.org);
18681
+ let limit;
18682
+ if (options.type && !["all", "plays", "monitors"].includes(options.type)) {
18683
+ throw new Error("--type must be all, plays or monitors.");
18684
+ }
18593
18685
  if (options.limit !== void 0) {
18594
- const limit = Number(options.limit);
18686
+ limit = Number(options.limit);
18595
18687
  if (!/^\d+$/.test(options.limit) || !Number.isSafeInteger(limit) || limit < 1) {
18596
18688
  throw new Error("--limit must be a positive integer.");
18597
18689
  }
18598
- query.set("limit", String(limit));
18599
18690
  }
18600
- const search = query.toString();
18601
- const page = await new HttpClient(resolveConfig()).get(
18602
- `/api/v2/dashboard/runs-history${search ? `?${search}` : ""}`
18603
- );
18691
+ const page = await new DeeplineClient().runs.history({
18692
+ cursor: options.cursor,
18693
+ orgId: options.org,
18694
+ search: options.search,
18695
+ type: options.type,
18696
+ limit
18697
+ });
18604
18698
  const lines = page.runs.map(
18605
18699
  (run) => `${run.workflowName} \xB7 ${run.status} \xB7 ${run.runId}`
18606
18700
  );
18607
- if (lines.length === 0) lines.push("No runs found on this page.");
18701
+ if (lines.length === 0) {
18702
+ lines.push(
18703
+ options.search && page.hasMore ? "No matches in this page; continue searching with the next cursor." : "No runs found on this page."
18704
+ );
18705
+ }
18608
18706
  if (page.hasMore) lines.push(`Next cursor: ${page.nextCursor}`);
18609
18707
  printCommandEnvelope(
18610
18708
  { ...page, render: { sections: [{ title: "Run history", lines }] } },
@@ -18616,6 +18714,12 @@ function registerRunHistoryCommand(runs) {
18616
18714
  "--cursor <cursor>",
18617
18715
  "Opaque nextCursor returned by the previous page"
18618
18716
  ).option("--limit <count>", "Maximum runs on this page").option(
18717
+ "--search <text>",
18718
+ "Search Play/workflow names, run IDs and statuses"
18719
+ ).option(
18720
+ "--type <type>",
18721
+ "Search all, plays or monitors (requires --search)"
18722
+ ).option(
18619
18723
  "--org <id>",
18620
18724
  "Workspace ID (must match the authenticated workspace)"
18621
18725
  ).option("--json", "Emit JSON output. Also automatic when stdout is piped").addHelpText(
@@ -24345,6 +24449,63 @@ var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : resolv
24345
24449
  import { writeFileSync as writeFileSync9 } from "fs";
24346
24450
  import { resolve as resolve10 } from "path";
24347
24451
 
24452
+ // ../plays/table-csv.ts
24453
+ var TABLE_EXPORT_ERROR_COLUMN = "_error";
24454
+ var UNRECORDED_FAILURE_REASON = "Row failed without a recorded reason.";
24455
+ function tableCellText(value) {
24456
+ if (value === null || value === void 0) return "";
24457
+ if (typeof value === "string") return value;
24458
+ if (typeof value === "number" || typeof value === "bigint" || typeof value === "boolean")
24459
+ return String(value);
24460
+ if (value instanceof Date) return value.toISOString();
24461
+ if (typeof value === "symbol" || typeof value === "function") return "";
24462
+ try {
24463
+ return JSON.stringify(
24464
+ value,
24465
+ (_key, nested) => typeof nested === "bigint" ? nested.toString() : nested
24466
+ ) ?? "";
24467
+ } catch {
24468
+ return String(value);
24469
+ }
24470
+ }
24471
+ function csvField(value) {
24472
+ const text = tableCellText(value);
24473
+ return /[",\r\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text;
24474
+ }
24475
+ function csvRecord(values) {
24476
+ return `${values.map(csvField).join(",")}
24477
+ `;
24478
+ }
24479
+ function isFailedRow(row) {
24480
+ return row.status === "failed";
24481
+ }
24482
+ function tableExportHasFailedRows(rows) {
24483
+ for (const row of rows) if (isFailedRow(row)) return true;
24484
+ return false;
24485
+ }
24486
+ function tableExportErrorCell(row) {
24487
+ if (!isFailedRow(row)) return "";
24488
+ const reason = typeof row.error === "string" ? row.error.trim() : "";
24489
+ return reason || UNRECORDED_FAILURE_REASON;
24490
+ }
24491
+ function tableExportColumns(columns, withError) {
24492
+ if (!withError) return [...columns];
24493
+ return [
24494
+ ...columns.filter((column) => column !== TABLE_EXPORT_ERROR_COLUMN),
24495
+ TABLE_EXPORT_ERROR_COLUMN
24496
+ ];
24497
+ }
24498
+ function tableExportCells(row, columns, withError) {
24499
+ return tableExportColumns(columns, withError).map(
24500
+ (column) => column === TABLE_EXPORT_ERROR_COLUMN && withError ? tableExportErrorCell(row) : Object.hasOwn(row.data, column) ? row.data[column] : void 0
24501
+ );
24502
+ }
24503
+ function tableCsvText(header, records) {
24504
+ let text = csvRecord(header);
24505
+ for (const record5 of records) text += csvRecord(record5);
24506
+ return text;
24507
+ }
24508
+
24348
24509
  // src/cli/run-dataset-order.ts
24349
24510
  function underscoreKeysLast(keys) {
24350
24511
  return [...keys].sort(
@@ -24393,9 +24554,13 @@ var RunDatasetCsv = class _RunDatasetCsv {
24393
24554
  }
24394
24555
  write(outPath) {
24395
24556
  const absolutePath = resolve10(outPath);
24557
+ const { rows, columns } = this.#projection;
24396
24558
  writeFileSync9(
24397
24559
  absolutePath,
24398
- csvStringFromRows(this.#projection.rows, this.#projection.columns),
24560
+ tableCsvText(
24561
+ columns,
24562
+ rows.map((data) => tableExportCells({ data }, columns, false))
24563
+ ),
24399
24564
  "utf-8"
24400
24565
  );
24401
24566
  return absolutePath;
@@ -28353,7 +28518,7 @@ function buildPlayReferenceNotFoundMessage(input2) {
28353
28518
  lines.push("", ` ${suggestion.reference}`);
28354
28519
  if (input2.command === "run") {
28355
28520
  lines.push(
28356
- ` deepline plays run ${suggestion.reference} --input '{...}' --watch`
28521
+ ` deepline plays run ${suggestion.reference} --input '{...}'`
28357
28522
  );
28358
28523
  } else if (input2.command === "get") {
28359
28524
  lines.push(` deepline plays get ${suggestion.reference} --json`);
@@ -31677,7 +31842,9 @@ function buildOrdinaryPlayRunCommand(options, resolvedRevisionId) {
31677
31842
  }
31678
31843
  if (options.open) parts.push("--open");
31679
31844
  if (options.fullJson) parts.push("--full");
31680
- if (options.jsonOutput && options.emitLogs) parts.push("--logs");
31845
+ if (options.jsonOutput && options.emitLogs) {
31846
+ parts.push("--log-level", "debug");
31847
+ }
31681
31848
  if (options.jsonOutput) parts.push("--json");
31682
31849
  return parts.join(" ");
31683
31850
  }
@@ -31989,7 +32156,20 @@ async function fetchBackingDatasetRows(input2) {
31989
32156
  }
31990
32157
  offset += page.rows.length;
31991
32158
  }
31992
- const rows = sheetRows.map(exportableSheetRow).filter((row) => Boolean(row));
32159
+ const withError = tableExportHasFailedRows(
32160
+ sheetRows.filter(
32161
+ (row) => Boolean(row) && typeof row === "object" && !Array.isArray(row)
32162
+ )
32163
+ );
32164
+ const rows = sheetRows.map((row) => {
32165
+ const data = exportableSheetRow(row);
32166
+ return data && withError ? {
32167
+ ...data,
32168
+ [TABLE_EXPORT_ERROR_COLUMN]: tableExportErrorCell(
32169
+ row
32170
+ )
32171
+ } : data;
32172
+ }).filter((row) => Boolean(row));
31993
32173
  const hasCompleteSettledPrefix = acceptsSettledRowsAsCompleteExport(input2.status) && settledTotal !== null && // A zero-row run-scoped read is not a settled export when the returned
31994
32174
  // Dataset Handle advertised rows. That shape is the replay/reuse case:
31995
32175
  // the rows belong to another writer (or the projection has not caught up)
@@ -32761,7 +32941,7 @@ function parsePlayRunOptions(args) {
32761
32941
  }
32762
32942
  if (arg === "--tail") {
32763
32943
  throw new Error(
32764
- "--tail is removed for `plays run`; use `--watch` to stream completion output."
32944
+ "--tail is removed for `plays run`; run waits and streams completion output by default."
32765
32945
  );
32766
32946
  }
32767
32947
  continue;
@@ -33971,9 +34151,12 @@ function renderRunOverviewText(overview, extras = {}) {
33971
34151
  ${renderCommandEnvelopeText({ render: { sections, actions: actions2 } })}`;
33972
34152
  }
33973
34153
  async function handleRunGet(args) {
33974
- const selection = parseJsonFields(args, "get");
34154
+ const selection = parseJsonFields(
34155
+ args,
34156
+ args.includes("--config") ? "config" : "get"
34157
+ );
33975
34158
  args = selection.args;
33976
- const usage2 = "Usage: deepline runs get <run-id> [--json] [--full] [--input] [--log-failed]";
34159
+ const usage2 = "Usage: deepline runs get <run-id> [--json] [--full] [--input] [--config] [--log-failed]";
33977
34160
  let runId;
33978
34161
  try {
33979
34162
  runId = parseRunIdPositional(args, usage2);
@@ -33982,6 +34165,25 @@ async function handleRunGet(args) {
33982
34165
  return 1;
33983
34166
  }
33984
34167
  const client2 = new DeeplineClient();
34168
+ if (args.includes("--config")) {
34169
+ if (args.some((arg) => ["--input", "--full", "--log-failed"].includes(arg))) {
34170
+ console.error(
34171
+ "--config cannot be combined with --input, --full or --log-failed."
34172
+ );
34173
+ return 1;
34174
+ }
34175
+ const status2 = await client2.runs.get(runId, { configuration: true });
34176
+ if (!Object.hasOwn(status2, "contract")) {
34177
+ throw new Error(
34178
+ "This server does not support recorded configuration reads."
34179
+ );
34180
+ }
34181
+ printCommandEnvelope(
34182
+ { runId, contract: status2.contract ?? null },
34183
+ { json: true, fields: selection.fields }
34184
+ );
34185
+ return 0;
34186
+ }
33985
34187
  if (args.includes("--input")) {
33986
34188
  const input2 = await client2.getRunInput(runId);
33987
34189
  printCommandEnvelope(input2, { json: true });
@@ -34487,15 +34689,17 @@ async function handleRunLogs(args) {
34487
34689
  "--play",
34488
34690
  "--kind",
34489
34691
  "--where",
34490
- "--cursor",
34491
34692
  "--payloads",
34492
34693
  "--runtime-namespace",
34493
34694
  "--runtime-backend"
34494
34695
  ]);
34495
- if (!args[0] || args[0].startsWith("--") || args.some((arg) => searchFlags.has(arg))) {
34696
+ const cursorIndex = args.indexOf("--cursor");
34697
+ const cursorValue = cursorIndex >= 0 ? args[cursorIndex + 1] : void 0;
34698
+ const continuesEventSearch = cursorIndex >= 0 && !(cursorValue && isRunLogsCursor(cursorValue));
34699
+ if (!args[0] || args[0].startsWith("--") || continuesEventSearch || args.some((arg) => searchFlags.has(arg))) {
34496
34700
  return handleRunEventSearch(args);
34497
34701
  }
34498
- const usage2 = "Usage: deepline runs logs <run-id> [--limit 200] [--failed] [--out run.log] [--log-level debug|info|warn|error] [--json]";
34702
+ const usage2 = "Usage: deepline runs logs <run-id> [--limit 200] [--cursor before:<seq>] [--failed] [--out run.log] [--log-level debug|info|warn|error] [--json]";
34499
34703
  let runId;
34500
34704
  try {
34501
34705
  runId = parseRunIdPositional(args, usage2);
@@ -34505,6 +34709,7 @@ async function handleRunLogs(args) {
34505
34709
  }
34506
34710
  let limit = 200;
34507
34711
  let outPath = null;
34712
+ let cursor;
34508
34713
  let logLevel = "debug";
34509
34714
  let hasExplicitLogLevel = false;
34510
34715
  let usesDebugAlias = false;
@@ -34543,6 +34748,10 @@ async function handleRunLogs(args) {
34543
34748
  outPath = resolve13(args[++index]);
34544
34749
  continue;
34545
34750
  }
34751
+ if (arg === "--cursor" && args[index + 1]) {
34752
+ cursor = args[++index];
34753
+ continue;
34754
+ }
34546
34755
  if (arg.startsWith("--")) {
34547
34756
  console.error(`${arg} is not supported by deepline runs logs.`);
34548
34757
  return 1;
@@ -34561,6 +34770,12 @@ async function handleRunLogs(args) {
34561
34770
  );
34562
34771
  return 1;
34563
34772
  }
34773
+ if (cursor !== void 0 && (failed || outPath)) {
34774
+ console.error(
34775
+ "--cursor pages the bounded log tail; it cannot be combined with --failed or --out."
34776
+ );
34777
+ return 1;
34778
+ }
34564
34779
  const client2 = new DeeplineClient();
34565
34780
  if (outPath) {
34566
34781
  const result2 = await client2.runs.logs(runId, { all: true });
@@ -34594,19 +34809,25 @@ async function handleRunLogs(args) {
34594
34809
  return 0;
34595
34810
  }
34596
34811
  const result = await client2.runs.logs(runId, {
34597
- ...failed ? { limit, failed: true } : { all: logLevel !== "debug", limit }
34598
- });
34599
- const matchingEntries = result.entries.filter(
34600
- (line) => logLevelReaches(classifyLogLine(line).level, logLevel)
34601
- );
34602
- const entries = failed ? matchingEntries : matchingEntries.slice(-limit);
34603
- const matchingEntriesTruncated = !failed && matchingEntries.length > limit;
34812
+ ...failed ? { limit, failed: true } : { all: logLevel !== "debug", limit },
34813
+ ...cursor !== void 0 ? { cursor } : {}
34814
+ });
34815
+ const page = failed ? {
34816
+ entries: result.entries,
34817
+ firstSequence: result.firstSequence,
34818
+ lastSequence: result.lastSequence,
34819
+ truncated: result.truncated,
34820
+ hasMore: result.hasMore,
34821
+ nextCursor: void 0
34822
+ } : selectRunLogTailPage(result, logLevel, limit);
34823
+ const entries = page.entries;
34824
+ const nextPage = page.nextCursor ? `deepline runs logs ${result.runId} --limit ${limit}${logLevel === "debug" ? "" : ` --log-level ${logLevel}`} --cursor ${page.nextCursor} --json` : null;
34604
34825
  const filteredResult = {
34605
34826
  ...result,
34606
34827
  entries,
34607
34828
  returnedCount: entries.length,
34608
- truncated: result.truncated || matchingEntriesTruncated,
34609
- hasMore: result.hasMore || matchingEntriesTruncated,
34829
+ truncated: page.truncated,
34830
+ hasMore: page.hasMore,
34610
34831
  view: failed ? result.view : "tail",
34611
34832
  next: {
34612
34833
  ...result.next ?? {},
@@ -34619,10 +34840,11 @@ async function handleRunLogs(args) {
34619
34840
  runId: result.runId,
34620
34841
  totalCount: result.totalCount,
34621
34842
  returnedCount: entries.length,
34622
- firstSequence: result.firstSequence,
34623
- lastSequence: result.lastSequence,
34843
+ firstSequence: page.firstSequence,
34844
+ lastSequence: page.lastSequence,
34624
34845
  truncated: filteredResult.truncated,
34625
34846
  hasMore: filteredResult.hasMore,
34847
+ ...page.nextCursor !== void 0 ? { nextCursor: page.nextCursor } : {},
34626
34848
  logLevel,
34627
34849
  ...result.logsTruncated ? { logsTruncated: true } : {},
34628
34850
  entries,
@@ -34631,6 +34853,7 @@ async function handleRunLogs(args) {
34631
34853
  ...result.warning ? { warning: result.warning } : {},
34632
34854
  next: {
34633
34855
  ...result.next ?? {},
34856
+ ...nextPage ? { page: nextPage } : {},
34634
34857
  export: `deepline runs logs ${result.runId} --out run.log --log-level ${logLevel} --json`
34635
34858
  },
34636
34859
  render: { sections: [{ title: "run logs", lines: entries }] }
@@ -34642,6 +34865,37 @@ async function handleRunLogs(args) {
34642
34865
  );
34643
34866
  return 0;
34644
34867
  }
34868
+ function selectRunLogTailPage(result, logLevel, limit) {
34869
+ if (logLevel === "debug") {
34870
+ return {
34871
+ entries: [...result.entries],
34872
+ firstSequence: result.firstSequence,
34873
+ lastSequence: result.lastSequence,
34874
+ truncated: result.truncated,
34875
+ hasMore: result.hasMore,
34876
+ nextCursor: result.nextCursor ?? null
34877
+ };
34878
+ }
34879
+ const first = result.firstSequence;
34880
+ if (result.entries.length > 0 && (first === null || result.lastSequence === null || result.lastSequence - first + 1 !== result.entries.length)) {
34881
+ throw new Error(
34882
+ `Run log window is not contiguous (sequences ${first}..${result.lastSequence} for ${result.entries.length} lines); cannot page by severity.`
34883
+ );
34884
+ }
34885
+ const matching = result.entries.map((line, index) => ({ line, seq: first + index })).filter(
34886
+ (entry) => logLevelReaches(classifyLogLine(entry.line).level, logLevel)
34887
+ );
34888
+ const selected = matching.slice(-limit);
34889
+ const olderMatchesExist = matching.length > selected.length;
34890
+ return {
34891
+ entries: selected.map((entry) => entry.line),
34892
+ firstSequence: selected[0]?.seq ?? null,
34893
+ lastSequence: selected.at(-1)?.seq ?? null,
34894
+ truncated: result.truncated || olderMatchesExist,
34895
+ hasMore: olderMatchesExist,
34896
+ nextCursor: olderMatchesExist ? encodeRunLogsCursor(selected[0].seq) : null
34897
+ };
34898
+ }
34645
34899
  async function handleRunEventSearch(args) {
34646
34900
  const usage2 = "Usage: deepline runs logs [run-id] [--since ISO] [--until ISO] [--play name] [--kind kind] [--where jsonpath] [--payloads] [--cursor token] [--limit 100] [--json]";
34647
34901
  const values = {};
@@ -34807,6 +35061,14 @@ function buildRunLogsText(result) {
34807
35061
  }
34808
35062
  return `${lines.join("\n")}${lines.length > 0 ? "\n" : ""}`;
34809
35063
  }
35064
+ function resolveRunStopState(result) {
35065
+ if (result.state) return result.state;
35066
+ if (result.cancelling === true) return "cancelling";
35067
+ if (result.stopped === false || result.staleSchedulerState === true) {
35068
+ return "failed";
35069
+ }
35070
+ return "stopped";
35071
+ }
34810
35072
  async function handleRunStop(args) {
34811
35073
  const usage2 = 'Usage: deepline runs stop <run-id> [--reason "text"] [--json]';
34812
35074
  let runId;
@@ -34825,15 +35087,25 @@ async function handleRunStop(args) {
34825
35087
  }
34826
35088
  const client2 = new DeeplineClient();
34827
35089
  const result = await client2.runs.stop(runId, { reason });
34828
- if (result.cancelling === true && result.hitlCancellationPending !== true) {
35090
+ const state = resolveRunStopState(result);
35091
+ const hitlCleanupIncomplete = state === "cancelling" && result.hitlCancellationPending === true;
35092
+ if (state === "cancelling" && !hitlCleanupIncomplete) {
35093
+ const {
35094
+ error: _legacyError,
35095
+ staleSchedulerState: _legacyStale,
35096
+ ...cancelling
35097
+ } = result;
34829
35098
  const lines2 = [
34830
- `Cancellation queued for ${result.runId || runId}; sandbox cleanup is pending`,
35099
+ `Cancelling run ${result.runId || runId}; sandbox cleanup and the final run update are pending.`,
34831
35100
  ...result.hitlCancelledCount > 0 ? [`cancelled HITL waits: ${result.hitlCancelledCount}`] : [],
34832
35101
  `inspect: deepline runs get ${runId} --full --json`
34833
35102
  ];
34834
35103
  printCommandEnvelope(
34835
35104
  {
34836
- ...result,
35105
+ ...cancelling,
35106
+ state,
35107
+ stopped: false,
35108
+ cancelling: true,
34837
35109
  render: {
34838
35110
  sections: [
34839
35111
  {
@@ -34847,9 +35119,8 @@ async function handleRunStop(args) {
34847
35119
  );
34848
35120
  return 0;
34849
35121
  }
34850
- const stopNotConfirmed = result.stopped === false || result.staleSchedulerState === true;
34851
- if (stopNotConfirmed) {
34852
- const detail = typeof result.error === "string" && result.error.trim() ? result.error.trim() : result.staleSchedulerState === true ? "scheduler state for the run is stale" : "the server did not confirm the stop";
35122
+ if (state === "failed" || hitlCleanupIncomplete) {
35123
+ const detail = typeof result.error === "string" && result.error.trim() ? result.error.trim() : hitlCleanupIncomplete ? "cancellation is queued, but HITL cleanup is still pending" : result.staleSchedulerState === true ? "scheduler state for the run is stale" : "the server did not confirm the stop";
34853
35124
  const lines2 = [
34854
35125
  `Failed to stop run ${runId}: ${detail}.`,
34855
35126
  ...result.hitlCancelledCount > 0 ? [`cancelled HITL waits: ${result.hitlCancelledCount}`] : [],
@@ -35391,7 +35662,7 @@ async function handlePlayList(args) {
35391
35662
  ` cost estimate: ${formatPlayCostEstimate(play.costEstimate)}`
35392
35663
  );
35393
35664
  }
35394
- lines.push(` run: deepline plays run ${reference} --watch`);
35665
+ lines.push(` run: deepline plays run ${reference}`);
35395
35666
  }
35396
35667
  if (page.hasMore) {
35397
35668
  lines.push("List truncated \u2014 more plays are available.");
@@ -36213,7 +36484,6 @@ Run and retrieve results:
36213
36484
  2. Start and follow a new run: deepline plays run workflow.play.ts --csv contacts.csv
36214
36485
  This example requires input.csv. Use the selected Play's actual input fields.
36215
36486
  Run waits and shows progress by default; --no-wait returns immediately.
36216
- --watch and --wait are redundant compatibility aliases for the default.
36217
36487
  3. Read its overview: deepline runs get <run-id> --json
36218
36488
  4. Export complete rows: deepline runs export <run-id> --dataset <returned-selector> --out results.csv
36219
36489
  If disconnected, attach to the SAME run with deepline runs tail <run-id>.
@@ -36302,8 +36572,7 @@ Notes:
36302
36572
  Named plays run the live saved revision.
36303
36573
  File args accept local paths; the CLI stages files before submit.
36304
36574
  By default, run waits for completion and prints logs, previews, stats, and
36305
- next commands. --watch and --wait are accepted compatibility aliases for the
36306
- default behavior. Use --no-wait only when you intentionally want
36575
+ next commands. Use --no-wait only when you intentionally want
36307
36576
  a fire-and-forget run id.
36308
36577
  --run-id-file writes the durable run id to a versioned JSON file as soon as
36309
36578
  the server accepts the run. The destination must not already exist.
@@ -36373,12 +36642,29 @@ Examples:
36373
36642
  ).option(
36374
36643
  "--fixture-behavior <json>",
36375
36644
  "Internal/testing: fixture response behavior JSON object or @file path"
36376
- ).option("--watch", "Compatibility alias; run waits by default").option("--wait", "Compatibility alias; run waits by default").option("--no-wait", "Start the run and return immediately").option(
36645
+ ).addOption(
36646
+ new Option3(
36647
+ "--watch",
36648
+ "Compatibility alias; run waits by default"
36649
+ ).hideHelp()
36650
+ ).addOption(
36651
+ new Option3(
36652
+ "--wait",
36653
+ "Compatibility alias; run waits by default"
36654
+ ).hideHelp()
36655
+ ).option("--no-wait", "Start the run and return immediately").option(
36377
36656
  "--run-id-file <path>",
36378
36657
  "Atomically write the accepted run id to a new JSON file"
36379
- ).option("--logs", "Compatibility alias for --log-level debug").option(
36380
- "--debug [value]",
36381
- "Compatibility alias for --log-level debug when bare; --debug <value> remains legacy Play input.debug"
36658
+ ).addOption(
36659
+ new Option3(
36660
+ "--logs",
36661
+ "Compatibility alias for --log-level debug"
36662
+ ).hideHelp()
36663
+ ).addOption(
36664
+ new Option3(
36665
+ "--debug [value]",
36666
+ "Compatibility alias for --log-level debug when bare; --debug <value> remains legacy Play input.debug"
36667
+ ).hideHelp()
36382
36668
  ).option(
36383
36669
  "--log-level <level>",
36384
36670
  "Minimum live log severity: debug, info (default), warn, or error"
@@ -36855,15 +37141,15 @@ Examples:
36855
37141
  ...options.json ? ["--json"] : []
36856
37142
  ]);
36857
37143
  });
36858
- const runs = program.command("runs").description("Inspect, tail, stop, and export play runs.").addHelpText(
37144
+ const runs = program.command("runs").description("Inspect, watch, stop, and export play runs.").addHelpText(
36859
37145
  "after",
36860
37146
  `
36861
37147
  Concepts:
36862
37148
  A run is one execution instance of a play. It has status, progress, logs,
36863
37149
  returned result, dataset previews, recovery metadata, and optional dataset export.
36864
37150
  plays run starts NEW work and follows it by default; --no-wait returns immediately.
36865
- runs tail attaches to EXISTING work and follows progress without starting a run.
36866
- Use tail after a disconnect or --no-wait; do not launch again to reconnect.
37151
+ runs watch attaches to EXISTING work and follows progress without starting a run.
37152
+ Use watch after a disconnect or --no-wait; do not launch again to reconnect.
36867
37153
  get reads the current overview once. logs fetches persisted log history.
36868
37154
  stop requests cancellation. rerun starts new work and may spend credits.
36869
37155
 
@@ -36877,14 +37163,15 @@ Retrieve results:
36877
37163
  not JSON rows. For a JSON row file, use --format json --out results.json.
36878
37164
 
36879
37165
  Follow existing work:
36880
- deepline runs tail <run-id>
36881
- tail --json waits for one terminal JSON document; --jsonl streams live events.
36882
- There is no runs watch command; tail is the live-follow command.
37166
+ deepline runs watch <run-id>
37167
+ watch --json waits for one terminal JSON document; --jsonl streams live events.
37168
+ runs tail is an alias of runs watch.
36883
37169
 
36884
37170
  More options:
36885
37171
  deepline runs get -h
36886
37172
  deepline runs children -h
36887
37173
  deepline runs tail -h
37174
+ deepline runs watch -h
36888
37175
  deepline runs export -h
36889
37176
  deepline plays -h
36890
37177
 
@@ -36931,6 +37218,7 @@ Notes:
36931
37218
  Run activity and status evidence retain provider cooldown and call progress.
36932
37219
  Use --input only when you intentionally need the original payload; it can
36933
37220
  contain customer data and is never included in ordinary status output.
37221
+ --config reads only the recorded graph and source; it never uses current Play code.
36934
37222
  --json run.status,datasets.name,actions selects fields without flattening.
36935
37223
  Selection changes stdout only, not the server query. Optional missing paths
36936
37224
  are omitted; array positions are preserved. --json diagnostics needs --full.
@@ -36942,6 +37230,7 @@ Examples:
36942
37230
  deepline runs get play/my-play/run/20260501t000000-000 --log-failed --json
36943
37231
  deepline runs get play/my-play/run/20260501t000000-000 --full --json
36944
37232
  deepline runs get play/my-play/run/20260501t000000-000 --input
37233
+ deepline runs get play/my-play/run/20260501t000000-000 --config --json
36945
37234
  `
36946
37235
  ).option(
36947
37236
  "--json [fields]",
@@ -36952,6 +37241,9 @@ Examples:
36952
37241
  ).option(
36953
37242
  "--input",
36954
37243
  "Explicitly print the original retained input JSON (may contain customer data)"
37244
+ ).option(
37245
+ "--config",
37246
+ "Explicitly print the recorded configuration, without full results"
36955
37247
  ).option(
36956
37248
  "--log-failed",
36957
37249
  "Attach a bounded terminal-failure log window for failed runs"
@@ -36961,6 +37253,7 @@ Examples:
36961
37253
  ...jsonFieldArgs(options.json),
36962
37254
  ...options.full ? ["--full"] : [],
36963
37255
  ...options.input ? ["--input"] : [],
37256
+ ...options.config ? ["--config"] : [],
36964
37257
  ...options.logFailed ? ["--log-failed"] : []
36965
37258
  ]);
36966
37259
  });
@@ -37060,9 +37353,8 @@ Notes:
37060
37353
  logs for persisted log history. In human output, --compact prints
37061
37354
  deduplicated step transitions and progress. --json emits one terminal
37062
37355
  package. --jsonl emits canonical watched events as JSON Lines and ends with
37063
- the same compact package shape as runs get --json. The tail command remains
37064
- an alias. --log-level
37065
- filters the rendered customer-safe runtime log lines; debug includes runtime
37356
+ the same compact package shape as runs get --json. --log-level filters the
37357
+ rendered customer-safe runtime log lines; debug includes runtime
37066
37358
  and receipt diagnostics and writes them to stderr alongside JSON output.
37067
37359
 
37068
37360
  Examples:
@@ -37078,7 +37370,17 @@ Examples:
37078
37370
  ).option(
37079
37371
  "--compact",
37080
37372
  "Show deduplicated human step transitions and progress"
37081
- ).option("--logs", "Compatibility alias for --log-level debug").option("--debug", "Compatibility alias for --log-level debug").option(
37373
+ ).addOption(
37374
+ new Option3(
37375
+ "--logs",
37376
+ "Compatibility alias for --log-level debug"
37377
+ ).hideHelp()
37378
+ ).addOption(
37379
+ new Option3(
37380
+ "--debug",
37381
+ "Compatibility alias for --log-level debug"
37382
+ ).hideHelp()
37383
+ ).option(
37082
37384
  "--log-level <level>",
37083
37385
  "Minimum severity: debug, info (default), warn, or error"
37084
37386
  ).action(async (runId, options) => {
@@ -37100,7 +37402,17 @@ Examples:
37100
37402
  ).option("--out <path>", "Write the full retained log stream to a file").option("--failed", "Show the bounded terminal-failure log window").option(
37101
37403
  "--log-level <level>",
37102
37404
  "Minimum severity: debug (default), info, warn, or error"
37103
- ).option("--logs", "Compatibility alias for --log-level debug").option("--debug", "Compatibility alias for --log-level debug").option("--json", "Emit JSON output. Also automatic when stdout is piped").option("--since <timestamp>", "Search events since this UTC timestamp").option("--until <timestamp>", "Search events before this UTC timestamp").option("--play <name>", "Filter events by Play name").option(
37405
+ ).addOption(
37406
+ new Option3(
37407
+ "--logs",
37408
+ "Compatibility alias for --log-level debug"
37409
+ ).hideHelp()
37410
+ ).addOption(
37411
+ new Option3(
37412
+ "--debug",
37413
+ "Compatibility alias for --log-level debug"
37414
+ ).hideHelp()
37415
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").option("--since <timestamp>", "Search events since this UTC timestamp").option("--until <timestamp>", "Search events before this UTC timestamp").option("--play <name>", "Filter events by Play name").option(
37104
37416
  "--kind <kind>",
37105
37417
  "Search one exact event kind; complete catalog below"
37106
37418
  ).option(
@@ -37109,7 +37421,10 @@ Examples:
37109
37421
  ).option(
37110
37422
  "--payloads",
37111
37423
  "Search with canonical eventPayload or receipt payload; max 10 events, 16 MiB"
37112
- ).option("--cursor <token>", "Continue a bounded event search").option(
37424
+ ).option(
37425
+ "--cursor <token>",
37426
+ "Continue paging: older run-log lines (nextCursor) or a bounded event search"
37427
+ ).option(
37113
37428
  "--runtime-namespace <name>",
37114
37429
  "Search an explicitly authorized Preview namespace"
37115
37430
  ).option("--runtime-backend <backend>", "Preview backend: daytona or modal").action(async (runId, options) => {
@@ -37432,11 +37747,11 @@ async function handlePlaySharePublish(args) {
37432
37747
  ok: false,
37433
37748
  code: "NO_SUCCESSFUL_RUN",
37434
37749
  message,
37435
- next: `deepline plays run ${name} --wait`
37750
+ next: `deepline plays run ${name}`
37436
37751
  });
37437
37752
  } else {
37438
37753
  console.error(message);
37439
- console.error(` deepline plays run ${name} --wait`);
37754
+ console.error(` deepline plays run ${name}`);
37440
37755
  }
37441
37756
  return 7;
37442
37757
  }
@@ -42422,7 +42737,7 @@ function registerEnrichCommand(program) {
42422
42737
  "--open",
42423
42738
  "Open the generated play page in a browser after the run starts."
42424
42739
  ).addOption(
42425
- new Option3(
42740
+ new Option4(
42426
42741
  "--no-open [legacy-value]",
42427
42742
  "Removed legacy option"
42428
42743
  ).hideHelp()
@@ -42812,7 +43127,7 @@ function registerExecutionsCommands(program) {
42812
43127
  }
42813
43128
 
42814
43129
  // src/cli/commands/feedback.ts
42815
- import { Option as Option4 } from "commander";
43130
+ import { Option as Option5 } from "commander";
42816
43131
  import { readFileSync as readFileSync10 } from "fs";
42817
43132
  async function handleFeedback(text, options) {
42818
43133
  const message = resolveFeedbackText(text, options.file);
@@ -42878,7 +43193,7 @@ Notes:
42878
43193
  to submit the report.
42879
43194
 
42880
43195
  Examples:
42881
- deepline feedback send "plays run failed after upload" --command "deepline plays run my.play.ts --watch" --error-outcome terminal
43196
+ deepline feedback send "plays run failed after upload" --command "deepline plays run my.play.ts" --error-outcome terminal
42882
43197
  deepline feedback send "unexpected billing output" --payload '{"command":"billing usage"}' --json
42883
43198
  `
42884
43199
  );
@@ -42890,10 +43205,10 @@ Examples:
42890
43205
  deepline feedback send --file incident.md --requested --json
42891
43206
  cat incident.md | deepline feedback send --requested --json
42892
43207
  deepline feedback send "tools search returned stale results" --requested --json
42893
- deepline feedback send "plays run failed after upload" --command "deepline plays run my.play.ts --watch" --error-outcome terminal
43208
+ deepline feedback send "plays run failed after upload" --command "deepline plays run my.play.ts" --error-outcome terminal
42894
43209
  `
42895
43210
  ).argument("[text]", "Feedback text").option("--file <path>", "Read feedback text from a file, or - for stdin").option("--command <command>", "Command that reproduced the issue").option("--payload <payload>", "JSON or plain-text payload for the repro").addOption(
42896
- new Option4(
43211
+ new Option5(
42897
43212
  "--error-outcome <outcome>",
42898
43213
  "Error impact on the task: terminal or continued"
42899
43214
  ).choices(["terminal", "continued"])
@@ -54198,7 +54513,7 @@ Examples:
54198
54513
  }
54199
54514
 
54200
54515
  // src/cli/commands/tools.ts
54201
- import { Option as Option5 } from "commander";
54516
+ import { Option as Option6 } from "commander";
54202
54517
  import {
54203
54518
  chmodSync,
54204
54519
  existsSync as existsSync20,
@@ -55228,7 +55543,7 @@ function isMissingToolMetadataError(error) {
55228
55543
  function playAliasToolErrorMessage(toolId, play) {
55229
55544
  const playName = play.reference ?? play.name;
55230
55545
  return `${toolId} is a play, not a tool.
55231
- Use: deepline plays run ${playName} --input '{...}' --watch
55546
+ Use: deepline plays run ${playName} --input '{...}'
55232
55547
  Inspect its schema with: deepline plays describe ${playName} --json`;
55233
55548
  }
55234
55549
  function printPlayAliasToolError(toolId, play) {
@@ -55260,11 +55575,11 @@ function playRunCommandForTool(tool, toolId, input2) {
55260
55575
  const playReference = playReferenceForTool(tool);
55261
55576
  if (!playReference) return playSearchCommandForToolId(toolId);
55262
55577
  const inputArg = input2 === void 0 ? "'{...}'" : `'${JSON.stringify(input2)}'`;
55263
- return `deepline plays run ${playReference} --input ${inputArg} --watch`;
55578
+ return `deepline plays run ${playReference} --input ${inputArg}`;
55264
55579
  }
55265
55580
  function playLikeToolExecuteErrorMessage(toolId, tool) {
55266
55581
  const playReference = tool ? playReferenceForTool(tool) : null;
55267
- const nextStep = playReference ? `Use: deepline plays run ${playReference} --input '{...}' --watch` : `Find the maintained workflow with: ${playSearchCommandForToolId(toolId)}`;
55582
+ const nextStep = playReference ? `Use: deepline plays run ${playReference} --input '{...}'` : `Find the maintained workflow with: ${playSearchCommandForToolId(toolId)}`;
55268
55583
  return [
55269
55584
  `${toolId} is a workflow/play entry, not an atomic provider tool.`,
55270
55585
  nextStep,
@@ -55440,12 +55755,12 @@ Examples:
55440
55755
  "--examples-only",
55441
55756
  "Only print runnable examples and sample payloads"
55442
55757
  ).option("--getters-only", "Only print extracted list/value getters").addOption(
55443
- new Option5(
55758
+ new Option6(
55444
55759
  "--compact",
55445
55760
  "Compatibility alias for the default compact view"
55446
55761
  ).hideHelp()
55447
55762
  ).addOption(
55448
- new Option5(
55763
+ new Option6(
55449
55764
  "--contract-json",
55450
55765
  "Compatibility alias for compact contract JSON"
55451
55766
  ).hideHelp()
@@ -58460,7 +58775,7 @@ async function main() {
58460
58775
  if (printStartupPhase) {
58461
58776
  progress?.phase("loading deepline cli");
58462
58777
  }
58463
- const program = new Command6();
58778
+ const program = new Command7();
58464
58779
  program.name("deepline").description(
58465
58780
  "Deepline CLI \u2014 GTM enrichment tools, plays, and runs from your terminal."
58466
58781
  ).version(SDK_VERSION, "-v, --version", "Show version").exitOverride().showHelpAfterError().showSuggestionAfterError(true).addHelpText(