deepline 0.1.122 → 0.1.123

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.
@@ -1655,6 +1655,8 @@ async function registerInlineChildRunWithRuntime(input: {
1655
1655
  action: 'start_inline_child_run',
1656
1656
  playName: input.childPlayName,
1657
1657
  runId: input.childRunId,
1658
+ parentRunId: input.governance.parentRunId,
1659
+ rootRunId: input.governance.rootRunId,
1658
1660
  workflowFamilyKey:
1659
1661
  input.governance.rootRunId ??
1660
1662
  input.governance.parentRunId ??
@@ -1762,6 +1764,7 @@ async function prepareInlineChildRunWithRuntime(input: {
1762
1764
  body: {
1763
1765
  action: 'prepare_inline_child_run',
1764
1766
  parentRunId: input.parentRunId,
1767
+ rootRunId: input.governance.rootRunId,
1765
1768
  parentPlayName: input.parentPlayName,
1766
1769
  childRunId: input.childRunId,
1767
1770
  childPlayName: input.childPlayName,
@@ -5567,6 +5567,8 @@ async function registerInlineChildRun(req: RunRequest): Promise<void> {
5567
5567
  action: 'start_inline_child_run',
5568
5568
  playName: req.playName,
5569
5569
  runId: req.runId,
5570
+ parentRunId: governance?.parentRunId,
5571
+ rootRunId: governance?.rootRunId,
5570
5572
  workflowFamilyKey:
5571
5573
  governance?.rootRunId ?? governance?.parentRunId ?? req.runId,
5572
5574
  artifactStorageKey:
@@ -60,6 +60,7 @@ import type {
60
60
  PlayListItem,
61
61
  PlayDescription,
62
62
  StopPlayRunResult,
63
+ StopAllPlayRunsResult,
63
64
  ClearPlayHistoryRequest,
64
65
  ClearPlayHistoryResult,
65
66
  PublishPlayVersionRequest,
@@ -186,8 +187,9 @@ export type ToolExecution<TData = unknown, TMeta = Record<string, unknown>> = {
186
187
 
187
188
  /** Filters for `client.runs.list(...)`. */
188
189
  export type RunsListOptions = {
189
- play: string;
190
+ play?: string;
190
191
  status?: string;
192
+ limit?: number;
191
193
  };
192
194
 
193
195
  /** Streaming options for `client.runs.tail(...)`. */
@@ -323,6 +325,8 @@ export type RunsNamespace = {
323
325
  runId: string,
324
326
  options?: { reason?: string },
325
327
  ) => Promise<StopPlayRunResult>;
328
+ /** Stop active runs across the current workspace. */
329
+ stopAll: (options?: { reason?: string }) => Promise<StopAllPlayRunsResult>;
326
330
  };
327
331
 
328
332
  /** One credit grant pool reported by the billing subscription status endpoint. */
@@ -822,6 +826,7 @@ export class DeeplineClient {
822
826
  logs: (runId, options) => this.getRunLogs(runId, options),
823
827
  exportDatasetRows: (input) => this.getPlaySheetRows(input),
824
828
  stop: (runId, options) => this.stopRun(runId, options),
829
+ stopAll: (options) => this.stopAllRuns(options),
825
830
  };
826
831
  this.billing = {
827
832
  plans: () => this.getBillingPlans(),
@@ -2034,15 +2039,21 @@ export class DeeplineClient {
2034
2039
  * ```
2035
2040
  */
2036
2041
  async listRuns(options: RunsListOptions): Promise<PlayRunListItem[]> {
2037
- const playName = options.play.trim();
2038
- if (!playName) {
2039
- throw new Error('runs.list requires options.play.');
2042
+ const playName = options.play?.trim();
2043
+ const params = new URLSearchParams();
2044
+ if (playName) {
2045
+ params.set('play', playName);
2040
2046
  }
2041
- const params = new URLSearchParams({ play: playName });
2042
2047
  const status = options.status?.trim();
2043
2048
  if (status) {
2044
2049
  params.set('status', status);
2045
2050
  }
2051
+ if (typeof options.limit === 'number' && Number.isFinite(options.limit)) {
2052
+ params.set('limit', String(Math.max(1, Math.floor(options.limit))));
2053
+ }
2054
+ if (!playName && !status) {
2055
+ throw new Error('runs.list requires options.play or options.status.');
2056
+ }
2046
2057
  params.set('compact', 'true');
2047
2058
  const response = await this.http.get<{ runs: PlayRunListItem[] }>(
2048
2059
  `/api/v2/runs?${params.toString()}`,
@@ -2415,6 +2426,27 @@ export class DeeplineClient {
2415
2426
  );
2416
2427
  }
2417
2428
 
2429
+ /**
2430
+ * Stop every active run visible to the current workspace.
2431
+ *
2432
+ * This is the SDK equivalent of:
2433
+ *
2434
+ * ```bash
2435
+ * deepline runs stop-all --reason "stale lock" --json
2436
+ * ```
2437
+ *
2438
+ * Use this when a failed parent run left child or waiting runs active and you
2439
+ * need to clear the workspace run-slot state without knowing each run id.
2440
+ */
2441
+ async stopAllRuns(options?: {
2442
+ reason?: string;
2443
+ }): Promise<StopAllPlayRunsResult> {
2444
+ return this.http.post<StopAllPlayRunsResult>(
2445
+ '/api/v2/runs/stop-all',
2446
+ options?.reason ? { reason: options.reason } : {},
2447
+ );
2448
+ }
2449
+
2418
2450
  /**
2419
2451
  * List callable plays visible to the workspace.
2420
2452
  *
@@ -99,10 +99,10 @@ export const SDK_RELEASE = {
99
99
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
100
100
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
101
101
  // the SDK enrich generator's one-second stale policy.
102
- version: '0.1.122',
102
+ version: '0.1.123',
103
103
  apiContract: '2026-06-dataset-column-cell-stale-hard-cutover',
104
104
  supportPolicy: {
105
- latest: '0.1.122',
105
+ latest: '0.1.123',
106
106
  minimumSupported: '0.1.53',
107
107
  deprecatedBelow: '0.1.53',
108
108
  commandMinimumSupported: [
@@ -557,22 +557,40 @@ export interface StopPlayRunResult {
557
557
  error?: string;
558
558
  }
559
559
 
560
+ export interface StopAllPlayRunsResult {
561
+ stopped: number;
562
+ failed: number;
563
+ skipped: number;
564
+ partial?: boolean;
565
+ runs: Array<StopPlayRunResult & { status?: string | null }>;
566
+ }
567
+
560
568
  /**
561
569
  * Summary of a single play run, returned by {@link DeeplineClient.listPlayRuns}.
562
570
  */
563
571
  export interface PlayRunListItem {
564
572
  /** Public Deepline play-run id. */
565
573
  workflowId: string;
574
+ /** Saved play name for this run, when available. */
575
+ playName?: string | null;
566
576
  /** Backend run attempt id, when exposed. */
567
577
  runId: string;
578
+ /** Parent play-run id when this run was launched through ctx.runPlay. */
579
+ parentRunId?: string | null;
580
+ /** Root play-run id for nested ctx.runPlay descendants. */
581
+ rootRunId?: string | null;
568
582
  /** Workflow type (typically `'Workflow'`). */
569
583
  type: string;
570
584
  /** Human-readable status (e.g. `'Completed'`, `'Failed'`). */
571
585
  status: string;
572
586
  /** ISO 8601 timestamp when the run started. */
573
- startTime: string | null;
587
+ startTime?: string | null;
588
+ /** Unix epoch milliseconds when the run started, returned by normalized V2 run summaries. */
589
+ startedAt?: number | string | null;
574
590
  /** ISO 8601 timestamp when the run finished. */
575
- closeTime: string | null;
591
+ closeTime?: string | null;
592
+ /** Unix epoch milliseconds when the run finished, returned by normalized V2 run summaries. */
593
+ finishedAt?: number | string | null;
576
594
  /** Duration string (e.g. `'2.5s'`). */
577
595
  executionTime: string | null;
578
596
  /** Total Deepline credits charged for the run, when available. */
@@ -101,6 +101,8 @@ type RuntimeApiRequest =
101
101
  action: 'start_inline_child_run';
102
102
  playName: string;
103
103
  runId: string;
104
+ parentRunId?: string | null;
105
+ rootRunId?: string | null;
104
106
  workflowFamilyKey?: string | null;
105
107
  artifactStorageKey?: string | null;
106
108
  artifactHash?: string | null;
@@ -678,6 +680,8 @@ export async function startRunViaAppRuntime(
678
680
  input: {
679
681
  playName: string;
680
682
  runId: string;
683
+ parentRunId?: string | null;
684
+ rootRunId?: string | null;
681
685
  workflowFamilyKey?: string | null;
682
686
  artifactStorageKey?: string | null;
683
687
  artifactHash?: string | null;
package/dist/cli/index.js CHANGED
@@ -403,10 +403,10 @@ var SDK_RELEASE = {
403
403
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
404
404
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
405
405
  // the SDK enrich generator's one-second stale policy.
406
- version: "0.1.122",
406
+ version: "0.1.123",
407
407
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
408
408
  supportPolicy: {
409
- latest: "0.1.122",
409
+ latest: "0.1.123",
410
410
  minimumSupported: "0.1.53",
411
411
  deprecatedBelow: "0.1.53",
412
412
  commandMinimumSupported: [
@@ -2020,7 +2020,8 @@ var DeeplineClient = class {
2020
2020
  tail: (runId, options2) => this.tailRun(runId, options2),
2021
2021
  logs: (runId, options2) => this.getRunLogs(runId, options2),
2022
2022
  exportDatasetRows: (input2) => this.getPlaySheetRows(input2),
2023
- stop: (runId, options2) => this.stopRun(runId, options2)
2023
+ stop: (runId, options2) => this.stopRun(runId, options2),
2024
+ stopAll: (options2) => this.stopAllRuns(options2)
2024
2025
  };
2025
2026
  this.billing = {
2026
2027
  plans: () => this.getBillingPlans(),
@@ -2884,15 +2885,21 @@ var DeeplineClient = class {
2884
2885
  * ```
2885
2886
  */
2886
2887
  async listRuns(options) {
2887
- const playName = options.play.trim();
2888
- if (!playName) {
2889
- throw new Error("runs.list requires options.play.");
2888
+ const playName = options.play?.trim();
2889
+ const params = new URLSearchParams();
2890
+ if (playName) {
2891
+ params.set("play", playName);
2890
2892
  }
2891
- const params = new URLSearchParams({ play: playName });
2892
2893
  const status = options.status?.trim();
2893
2894
  if (status) {
2894
2895
  params.set("status", status);
2895
2896
  }
2897
+ if (typeof options.limit === "number" && Number.isFinite(options.limit)) {
2898
+ params.set("limit", String(Math.max(1, Math.floor(options.limit))));
2899
+ }
2900
+ if (!playName && !status) {
2901
+ throw new Error("runs.list requires options.play or options.status.");
2902
+ }
2896
2903
  params.set("compact", "true");
2897
2904
  const response = await this.http.get(
2898
2905
  `/api/v2/runs?${params.toString()}`
@@ -3199,6 +3206,24 @@ var DeeplineClient = class {
3199
3206
  options?.reason ? { reason: options.reason } : {}
3200
3207
  );
3201
3208
  }
3209
+ /**
3210
+ * Stop every active run visible to the current workspace.
3211
+ *
3212
+ * This is the SDK equivalent of:
3213
+ *
3214
+ * ```bash
3215
+ * deepline runs stop-all --reason "stale lock" --json
3216
+ * ```
3217
+ *
3218
+ * Use this when a failed parent run left child or waiting runs active and you
3219
+ * need to clear the workspace run-slot state without knowing each run id.
3220
+ */
3221
+ async stopAllRuns(options) {
3222
+ return this.http.post(
3223
+ "/api/v2/runs/stop-all",
3224
+ options?.reason ? { reason: options.reason } : {}
3225
+ );
3226
+ }
3202
3227
  /**
3203
3228
  * List callable plays visible to the workspace.
3204
3229
  *
@@ -12675,7 +12700,7 @@ async function handleRunGet(args) {
12675
12700
  return 0;
12676
12701
  }
12677
12702
  async function handleRunsList(args) {
12678
- const usage = "Usage: deepline runs list --play <play-name> [--status <status>] [--json]";
12703
+ const usage = "Usage: deepline runs list [--play <play-name>] [--status <status>] [--json]";
12679
12704
  let playName = null;
12680
12705
  let statusFilter = null;
12681
12706
  for (let index = 0; index < args.length; index += 1) {
@@ -12692,28 +12717,32 @@ async function handleRunsList(args) {
12692
12717
  continue;
12693
12718
  }
12694
12719
  }
12695
- if (!playName) {
12720
+ if (!playName && !statusFilter) {
12696
12721
  console.error(usage);
12697
12722
  return 1;
12698
12723
  }
12699
12724
  const client2 = new DeeplineClient();
12700
12725
  const runs = (await client2.runs.list({
12701
- play: playName,
12726
+ ...playName ? { play: playName } : {},
12702
12727
  ...statusFilter ? { status: statusFilter } : {}
12703
12728
  })).map((run) => ({
12704
12729
  runId: run.workflowId,
12705
12730
  workflowId: run.workflowId,
12706
12731
  temporalRunId: run.runId,
12732
+ parentRunId: run.parentRunId ?? null,
12733
+ rootRunId: run.rootRunId ?? null,
12707
12734
  status: String(run.status ?? "").toLowerCase(),
12708
- startedAt: run.startTime,
12709
- finishedAt: run.closeTime,
12735
+ startedAt: run.startTime ?? run.startedAt ?? null,
12736
+ finishedAt: run.closeTime ?? run.finishedAt ?? null,
12710
12737
  executionTime: run.executionTime,
12711
12738
  billingTotalCredits: run.billingTotalCredits,
12712
12739
  billingMaxCreditsPerRun: run.billingMaxCreditsPerRun,
12713
- playName: run.memo?.playName ?? playName
12740
+ playName: run.playName ?? run.memo?.playName ?? playName ?? null
12714
12741
  }));
12715
- const lines = runs.length === 0 ? [`No runs found for ${playName}.`] : runs.map(
12716
- (run) => `${run.runId} ${run.status} ${formatTimestamp(run.startedAt)} ${typeof run.billingTotalCredits === "number" && Number.isFinite(run.billingTotalCredits) ? `${formatCreditAmount(run.billingTotalCredits)} credits` : "\u2014"}`
12742
+ const lines = runs.length === 0 ? [
12743
+ playName ? `No runs found for ${playName}.` : `No runs found for status ${statusFilter}.`
12744
+ ] : runs.map(
12745
+ (run) => `${run.runId} ${run.status} ${formatTimestamp(run.startedAt)} ${typeof run.billingTotalCredits === "number" && Number.isFinite(run.billingTotalCredits) ? `${formatCreditAmount(run.billingTotalCredits)} credits` : "\u2014"}${run.parentRunId ? ` parent=${run.parentRunId}` : ""}`
12717
12746
  );
12718
12747
  printCommandEnvelope(
12719
12748
  {
@@ -12899,6 +12928,31 @@ async function handleRunStop(args) {
12899
12928
  );
12900
12929
  return 0;
12901
12930
  }
12931
+ async function handleRunStopAll(args) {
12932
+ let reason;
12933
+ for (let index = 0; index < args.length; index += 1) {
12934
+ const arg = args[index];
12935
+ if (arg === "--reason" && args[index + 1]) {
12936
+ reason = args[++index];
12937
+ }
12938
+ }
12939
+ const client2 = new DeeplineClient();
12940
+ const result = await client2.runs.stopAll({ reason });
12941
+ const lines = [
12942
+ `Stopped ${result.stopped} active run${result.stopped === 1 ? "" : "s"}`,
12943
+ ...result.partial ? ["partial: active runs may remain; rerun stop-all"] : [],
12944
+ ...result.failed > 0 ? [`failed stops: ${result.failed}`] : [],
12945
+ ...result.skipped > 0 ? [`skipped: ${result.skipped}`] : []
12946
+ ];
12947
+ printCommandEnvelope(
12948
+ {
12949
+ ...result,
12950
+ render: { sections: [{ title: "workspace stop-all", lines }] }
12951
+ },
12952
+ { json: argsWantJson(args) }
12953
+ );
12954
+ return result.failed > 0 || result.partial ? 1 : 0;
12955
+ }
12902
12956
  async function handleRunExport(args) {
12903
12957
  const usage = "Usage: deepline runs export <run-id> [--dataset result.rows] --out output.csv [--metadata-out export.json] [--json]";
12904
12958
  let runId;
@@ -13927,7 +13981,9 @@ Examples:
13927
13981
  `
13928
13982
  );
13929
13983
  addPublishHelp(
13930
- play.command("publish <target>").description("Promote a saved play revision or publish a local play file.")
13984
+ play.command("publish <target>").description(
13985
+ "Promote a saved play revision or publish a local play file."
13986
+ )
13931
13987
  ).option("--latest", "Promote the newest saved revision").option("--revision-id <id>", "Revision to promote").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
13932
13988
  process.exitCode = await handlePlayPublish([
13933
13989
  target,
@@ -13937,9 +13993,7 @@ Examples:
13937
13993
  ]);
13938
13994
  });
13939
13995
  addPublishHelp(
13940
- play.command("set-live <target>").description(
13941
- "Promote a saved revision or publish a local play file."
13942
- )
13996
+ play.command("set-live <target>").description("Promote a saved revision or publish a local play file.")
13943
13997
  ).option("--latest", "Promote the newest saved revision").option("--revision-id <id>", "Revision to promote").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
13944
13998
  process.exitCode = await handlePlayPublish([
13945
13999
  target,
@@ -13980,7 +14034,9 @@ Examples:
13980
14034
  deepline runs tail play/my-play/run/20260501t000000-000
13981
14035
  deepline runs logs play/my-play/run/20260501t000000-000 --out run.log --json
13982
14036
  deepline runs list --play my-play --status failed --json
14037
+ deepline runs list --status running --json
13983
14038
  deepline runs stop play/my-play/run/20260501t000000-000 --reason "stale lock" --json
14039
+ deepline runs stop-all --reason "unjam workspace" --json
13984
14040
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
13985
14041
  `
13986
14042
  );
@@ -14014,16 +14070,32 @@ Notes:
14014
14070
  Examples:
14015
14071
  deepline runs list --play my-play
14016
14072
  deepline runs list --play my-play --status failed --compact --json
14073
+ deepline runs list --status running --compact --json
14017
14074
  `
14018
- ).requiredOption("--play <name>", "Play name to filter runs").option("--status <status>", "Filter by run status").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
14075
+ ).option("--play <name>", "Play name to filter runs").option("--status <status>", "Filter by run status").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
14019
14076
  process.exitCode = await handleRunsList([
14020
- "--play",
14021
- options.play,
14077
+ ...options.play ? ["--play", options.play] : [],
14022
14078
  ...options.status ? ["--status", options.status] : [],
14023
14079
  ...options.compact ? ["--compact"] : [],
14024
14080
  ...options.json ? ["--json"] : []
14025
14081
  ]);
14026
14082
  });
14083
+ runs.command("stop-all").description("Stop active play runs in the current workspace.").addHelpText(
14084
+ "after",
14085
+ `
14086
+ Notes:
14087
+ Stops all active runs visible to this workspace, including child runs created by ctx.runPlay.
14088
+
14089
+ Examples:
14090
+ deepline runs stop-all --reason "unjam workspace"
14091
+ deepline runs stop-all --json
14092
+ `
14093
+ ).option("--reason <text>", "Reason to include with each stop request").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
14094
+ process.exitCode = await handleRunStopAll([
14095
+ ...options.reason ? ["--reason", options.reason] : [],
14096
+ ...options.json ? ["--json"] : []
14097
+ ]);
14098
+ });
14027
14099
  runs.command("tail <runId>").description("Read the canonical live stream for a play run.").addHelpText(
14028
14100
  "after",
14029
14101
  `
@@ -380,10 +380,10 @@ var SDK_RELEASE = {
380
380
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
381
381
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
382
382
  // the SDK enrich generator's one-second stale policy.
383
- version: "0.1.122",
383
+ version: "0.1.123",
384
384
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
385
385
  supportPolicy: {
386
- latest: "0.1.122",
386
+ latest: "0.1.123",
387
387
  minimumSupported: "0.1.53",
388
388
  deprecatedBelow: "0.1.53",
389
389
  commandMinimumSupported: [
@@ -1997,7 +1997,8 @@ var DeeplineClient = class {
1997
1997
  tail: (runId, options2) => this.tailRun(runId, options2),
1998
1998
  logs: (runId, options2) => this.getRunLogs(runId, options2),
1999
1999
  exportDatasetRows: (input2) => this.getPlaySheetRows(input2),
2000
- stop: (runId, options2) => this.stopRun(runId, options2)
2000
+ stop: (runId, options2) => this.stopRun(runId, options2),
2001
+ stopAll: (options2) => this.stopAllRuns(options2)
2001
2002
  };
2002
2003
  this.billing = {
2003
2004
  plans: () => this.getBillingPlans(),
@@ -2861,15 +2862,21 @@ var DeeplineClient = class {
2861
2862
  * ```
2862
2863
  */
2863
2864
  async listRuns(options) {
2864
- const playName = options.play.trim();
2865
- if (!playName) {
2866
- throw new Error("runs.list requires options.play.");
2865
+ const playName = options.play?.trim();
2866
+ const params = new URLSearchParams();
2867
+ if (playName) {
2868
+ params.set("play", playName);
2867
2869
  }
2868
- const params = new URLSearchParams({ play: playName });
2869
2870
  const status = options.status?.trim();
2870
2871
  if (status) {
2871
2872
  params.set("status", status);
2872
2873
  }
2874
+ if (typeof options.limit === "number" && Number.isFinite(options.limit)) {
2875
+ params.set("limit", String(Math.max(1, Math.floor(options.limit))));
2876
+ }
2877
+ if (!playName && !status) {
2878
+ throw new Error("runs.list requires options.play or options.status.");
2879
+ }
2873
2880
  params.set("compact", "true");
2874
2881
  const response = await this.http.get(
2875
2882
  `/api/v2/runs?${params.toString()}`
@@ -3176,6 +3183,24 @@ var DeeplineClient = class {
3176
3183
  options?.reason ? { reason: options.reason } : {}
3177
3184
  );
3178
3185
  }
3186
+ /**
3187
+ * Stop every active run visible to the current workspace.
3188
+ *
3189
+ * This is the SDK equivalent of:
3190
+ *
3191
+ * ```bash
3192
+ * deepline runs stop-all --reason "stale lock" --json
3193
+ * ```
3194
+ *
3195
+ * Use this when a failed parent run left child or waiting runs active and you
3196
+ * need to clear the workspace run-slot state without knowing each run id.
3197
+ */
3198
+ async stopAllRuns(options) {
3199
+ return this.http.post(
3200
+ "/api/v2/runs/stop-all",
3201
+ options?.reason ? { reason: options.reason } : {}
3202
+ );
3203
+ }
3179
3204
  /**
3180
3205
  * List callable plays visible to the workspace.
3181
3206
  *
@@ -12678,7 +12703,7 @@ async function handleRunGet(args) {
12678
12703
  return 0;
12679
12704
  }
12680
12705
  async function handleRunsList(args) {
12681
- const usage = "Usage: deepline runs list --play <play-name> [--status <status>] [--json]";
12706
+ const usage = "Usage: deepline runs list [--play <play-name>] [--status <status>] [--json]";
12682
12707
  let playName = null;
12683
12708
  let statusFilter = null;
12684
12709
  for (let index = 0; index < args.length; index += 1) {
@@ -12695,28 +12720,32 @@ async function handleRunsList(args) {
12695
12720
  continue;
12696
12721
  }
12697
12722
  }
12698
- if (!playName) {
12723
+ if (!playName && !statusFilter) {
12699
12724
  console.error(usage);
12700
12725
  return 1;
12701
12726
  }
12702
12727
  const client2 = new DeeplineClient();
12703
12728
  const runs = (await client2.runs.list({
12704
- play: playName,
12729
+ ...playName ? { play: playName } : {},
12705
12730
  ...statusFilter ? { status: statusFilter } : {}
12706
12731
  })).map((run) => ({
12707
12732
  runId: run.workflowId,
12708
12733
  workflowId: run.workflowId,
12709
12734
  temporalRunId: run.runId,
12735
+ parentRunId: run.parentRunId ?? null,
12736
+ rootRunId: run.rootRunId ?? null,
12710
12737
  status: String(run.status ?? "").toLowerCase(),
12711
- startedAt: run.startTime,
12712
- finishedAt: run.closeTime,
12738
+ startedAt: run.startTime ?? run.startedAt ?? null,
12739
+ finishedAt: run.closeTime ?? run.finishedAt ?? null,
12713
12740
  executionTime: run.executionTime,
12714
12741
  billingTotalCredits: run.billingTotalCredits,
12715
12742
  billingMaxCreditsPerRun: run.billingMaxCreditsPerRun,
12716
- playName: run.memo?.playName ?? playName
12743
+ playName: run.playName ?? run.memo?.playName ?? playName ?? null
12717
12744
  }));
12718
- const lines = runs.length === 0 ? [`No runs found for ${playName}.`] : runs.map(
12719
- (run) => `${run.runId} ${run.status} ${formatTimestamp(run.startedAt)} ${typeof run.billingTotalCredits === "number" && Number.isFinite(run.billingTotalCredits) ? `${formatCreditAmount(run.billingTotalCredits)} credits` : "\u2014"}`
12745
+ const lines = runs.length === 0 ? [
12746
+ playName ? `No runs found for ${playName}.` : `No runs found for status ${statusFilter}.`
12747
+ ] : runs.map(
12748
+ (run) => `${run.runId} ${run.status} ${formatTimestamp(run.startedAt)} ${typeof run.billingTotalCredits === "number" && Number.isFinite(run.billingTotalCredits) ? `${formatCreditAmount(run.billingTotalCredits)} credits` : "\u2014"}${run.parentRunId ? ` parent=${run.parentRunId}` : ""}`
12720
12749
  );
12721
12750
  printCommandEnvelope(
12722
12751
  {
@@ -12902,6 +12931,31 @@ async function handleRunStop(args) {
12902
12931
  );
12903
12932
  return 0;
12904
12933
  }
12934
+ async function handleRunStopAll(args) {
12935
+ let reason;
12936
+ for (let index = 0; index < args.length; index += 1) {
12937
+ const arg = args[index];
12938
+ if (arg === "--reason" && args[index + 1]) {
12939
+ reason = args[++index];
12940
+ }
12941
+ }
12942
+ const client2 = new DeeplineClient();
12943
+ const result = await client2.runs.stopAll({ reason });
12944
+ const lines = [
12945
+ `Stopped ${result.stopped} active run${result.stopped === 1 ? "" : "s"}`,
12946
+ ...result.partial ? ["partial: active runs may remain; rerun stop-all"] : [],
12947
+ ...result.failed > 0 ? [`failed stops: ${result.failed}`] : [],
12948
+ ...result.skipped > 0 ? [`skipped: ${result.skipped}`] : []
12949
+ ];
12950
+ printCommandEnvelope(
12951
+ {
12952
+ ...result,
12953
+ render: { sections: [{ title: "workspace stop-all", lines }] }
12954
+ },
12955
+ { json: argsWantJson(args) }
12956
+ );
12957
+ return result.failed > 0 || result.partial ? 1 : 0;
12958
+ }
12905
12959
  async function handleRunExport(args) {
12906
12960
  const usage = "Usage: deepline runs export <run-id> [--dataset result.rows] --out output.csv [--metadata-out export.json] [--json]";
12907
12961
  let runId;
@@ -13930,7 +13984,9 @@ Examples:
13930
13984
  `
13931
13985
  );
13932
13986
  addPublishHelp(
13933
- play.command("publish <target>").description("Promote a saved play revision or publish a local play file.")
13987
+ play.command("publish <target>").description(
13988
+ "Promote a saved play revision or publish a local play file."
13989
+ )
13934
13990
  ).option("--latest", "Promote the newest saved revision").option("--revision-id <id>", "Revision to promote").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
13935
13991
  process.exitCode = await handlePlayPublish([
13936
13992
  target,
@@ -13940,9 +13996,7 @@ Examples:
13940
13996
  ]);
13941
13997
  });
13942
13998
  addPublishHelp(
13943
- play.command("set-live <target>").description(
13944
- "Promote a saved revision or publish a local play file."
13945
- )
13999
+ play.command("set-live <target>").description("Promote a saved revision or publish a local play file.")
13946
14000
  ).option("--latest", "Promote the newest saved revision").option("--revision-id <id>", "Revision to promote").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (target, options) => {
13947
14001
  process.exitCode = await handlePlayPublish([
13948
14002
  target,
@@ -13983,7 +14037,9 @@ Examples:
13983
14037
  deepline runs tail play/my-play/run/20260501t000000-000
13984
14038
  deepline runs logs play/my-play/run/20260501t000000-000 --out run.log --json
13985
14039
  deepline runs list --play my-play --status failed --json
14040
+ deepline runs list --status running --json
13986
14041
  deepline runs stop play/my-play/run/20260501t000000-000 --reason "stale lock" --json
14042
+ deepline runs stop-all --reason "unjam workspace" --json
13987
14043
  deepline runs export play/my-play/run/20260501t000000-000 --out output.csv
13988
14044
  `
13989
14045
  );
@@ -14017,16 +14073,32 @@ Notes:
14017
14073
  Examples:
14018
14074
  deepline runs list --play my-play
14019
14075
  deepline runs list --play my-play --status failed --compact --json
14076
+ deepline runs list --status running --compact --json
14020
14077
  `
14021
- ).requiredOption("--play <name>", "Play name to filter runs").option("--status <status>", "Filter by run status").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
14078
+ ).option("--play <name>", "Play name to filter runs").option("--status <status>", "Filter by run status").option("--compact", "Drop verbose fields from JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
14022
14079
  process.exitCode = await handleRunsList([
14023
- "--play",
14024
- options.play,
14080
+ ...options.play ? ["--play", options.play] : [],
14025
14081
  ...options.status ? ["--status", options.status] : [],
14026
14082
  ...options.compact ? ["--compact"] : [],
14027
14083
  ...options.json ? ["--json"] : []
14028
14084
  ]);
14029
14085
  });
14086
+ runs.command("stop-all").description("Stop active play runs in the current workspace.").addHelpText(
14087
+ "after",
14088
+ `
14089
+ Notes:
14090
+ Stops all active runs visible to this workspace, including child runs created by ctx.runPlay.
14091
+
14092
+ Examples:
14093
+ deepline runs stop-all --reason "unjam workspace"
14094
+ deepline runs stop-all --json
14095
+ `
14096
+ ).option("--reason <text>", "Reason to include with each stop request").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
14097
+ process.exitCode = await handleRunStopAll([
14098
+ ...options.reason ? ["--reason", options.reason] : [],
14099
+ ...options.json ? ["--json"] : []
14100
+ ]);
14101
+ });
14030
14102
  runs.command("tail <runId>").description("Read the canonical live stream for a play run.").addHelpText(
14031
14103
  "after",
14032
14104
  `
package/dist/index.d.mts CHANGED
@@ -515,22 +515,41 @@ interface StopPlayRunResult {
515
515
  /** Server-side error detail when the stop was not confirmed. */
516
516
  error?: string;
517
517
  }
518
+ interface StopAllPlayRunsResult {
519
+ stopped: number;
520
+ failed: number;
521
+ skipped: number;
522
+ partial?: boolean;
523
+ runs: Array<StopPlayRunResult & {
524
+ status?: string | null;
525
+ }>;
526
+ }
518
527
  /**
519
528
  * Summary of a single play run, returned by {@link DeeplineClient.listPlayRuns}.
520
529
  */
521
530
  interface PlayRunListItem {
522
531
  /** Public Deepline play-run id. */
523
532
  workflowId: string;
533
+ /** Saved play name for this run, when available. */
534
+ playName?: string | null;
524
535
  /** Backend run attempt id, when exposed. */
525
536
  runId: string;
537
+ /** Parent play-run id when this run was launched through ctx.runPlay. */
538
+ parentRunId?: string | null;
539
+ /** Root play-run id for nested ctx.runPlay descendants. */
540
+ rootRunId?: string | null;
526
541
  /** Workflow type (typically `'Workflow'`). */
527
542
  type: string;
528
543
  /** Human-readable status (e.g. `'Completed'`, `'Failed'`). */
529
544
  status: string;
530
545
  /** ISO 8601 timestamp when the run started. */
531
- startTime: string | null;
546
+ startTime?: string | null;
547
+ /** Unix epoch milliseconds when the run started, returned by normalized V2 run summaries. */
548
+ startedAt?: number | string | null;
532
549
  /** ISO 8601 timestamp when the run finished. */
533
- closeTime: string | null;
550
+ closeTime?: string | null;
551
+ /** Unix epoch milliseconds when the run finished, returned by normalized V2 run summaries. */
552
+ finishedAt?: number | string | null;
534
553
  /** Duration string (e.g. `'2.5s'`). */
535
554
  executionTime: string | null;
536
555
  /** Total Deepline credits charged for the run, when available. */
@@ -1041,8 +1060,9 @@ type ToolExecution<TData = unknown, TMeta = Record<string, unknown>> = {
1041
1060
  };
1042
1061
  /** Filters for `client.runs.list(...)`. */
1043
1062
  type RunsListOptions = {
1044
- play: string;
1063
+ play?: string;
1045
1064
  status?: string;
1065
+ limit?: number;
1046
1066
  };
1047
1067
  /** Streaming options for `client.runs.tail(...)`. */
1048
1068
  type RunsTailOptions = {
@@ -1155,6 +1175,10 @@ type RunsNamespace = {
1155
1175
  stop: (runId: string, options?: {
1156
1176
  reason?: string;
1157
1177
  }) => Promise<StopPlayRunResult>;
1178
+ /** Stop active runs across the current workspace. */
1179
+ stopAll: (options?: {
1180
+ reason?: string;
1181
+ }) => Promise<StopAllPlayRunsResult>;
1158
1182
  };
1159
1183
  /** One credit grant pool reported by the billing subscription status endpoint. */
1160
1184
  type BillingCreditPool = {
@@ -1890,6 +1914,21 @@ declare class DeeplineClient {
1890
1914
  stopRun(runId: string, options?: {
1891
1915
  reason?: string;
1892
1916
  }): Promise<StopPlayRunResult>;
1917
+ /**
1918
+ * Stop every active run visible to the current workspace.
1919
+ *
1920
+ * This is the SDK equivalent of:
1921
+ *
1922
+ * ```bash
1923
+ * deepline runs stop-all --reason "stale lock" --json
1924
+ * ```
1925
+ *
1926
+ * Use this when a failed parent run left child or waiting runs active and you
1927
+ * need to clear the workspace run-slot state without knowing each run id.
1928
+ */
1929
+ stopAllRuns(options?: {
1930
+ reason?: string;
1931
+ }): Promise<StopAllPlayRunsResult>;
1893
1932
  /**
1894
1933
  * List callable plays visible to the workspace.
1895
1934
  *
package/dist/index.d.ts CHANGED
@@ -515,22 +515,41 @@ interface StopPlayRunResult {
515
515
  /** Server-side error detail when the stop was not confirmed. */
516
516
  error?: string;
517
517
  }
518
+ interface StopAllPlayRunsResult {
519
+ stopped: number;
520
+ failed: number;
521
+ skipped: number;
522
+ partial?: boolean;
523
+ runs: Array<StopPlayRunResult & {
524
+ status?: string | null;
525
+ }>;
526
+ }
518
527
  /**
519
528
  * Summary of a single play run, returned by {@link DeeplineClient.listPlayRuns}.
520
529
  */
521
530
  interface PlayRunListItem {
522
531
  /** Public Deepline play-run id. */
523
532
  workflowId: string;
533
+ /** Saved play name for this run, when available. */
534
+ playName?: string | null;
524
535
  /** Backend run attempt id, when exposed. */
525
536
  runId: string;
537
+ /** Parent play-run id when this run was launched through ctx.runPlay. */
538
+ parentRunId?: string | null;
539
+ /** Root play-run id for nested ctx.runPlay descendants. */
540
+ rootRunId?: string | null;
526
541
  /** Workflow type (typically `'Workflow'`). */
527
542
  type: string;
528
543
  /** Human-readable status (e.g. `'Completed'`, `'Failed'`). */
529
544
  status: string;
530
545
  /** ISO 8601 timestamp when the run started. */
531
- startTime: string | null;
546
+ startTime?: string | null;
547
+ /** Unix epoch milliseconds when the run started, returned by normalized V2 run summaries. */
548
+ startedAt?: number | string | null;
532
549
  /** ISO 8601 timestamp when the run finished. */
533
- closeTime: string | null;
550
+ closeTime?: string | null;
551
+ /** Unix epoch milliseconds when the run finished, returned by normalized V2 run summaries. */
552
+ finishedAt?: number | string | null;
534
553
  /** Duration string (e.g. `'2.5s'`). */
535
554
  executionTime: string | null;
536
555
  /** Total Deepline credits charged for the run, when available. */
@@ -1041,8 +1060,9 @@ type ToolExecution<TData = unknown, TMeta = Record<string, unknown>> = {
1041
1060
  };
1042
1061
  /** Filters for `client.runs.list(...)`. */
1043
1062
  type RunsListOptions = {
1044
- play: string;
1063
+ play?: string;
1045
1064
  status?: string;
1065
+ limit?: number;
1046
1066
  };
1047
1067
  /** Streaming options for `client.runs.tail(...)`. */
1048
1068
  type RunsTailOptions = {
@@ -1155,6 +1175,10 @@ type RunsNamespace = {
1155
1175
  stop: (runId: string, options?: {
1156
1176
  reason?: string;
1157
1177
  }) => Promise<StopPlayRunResult>;
1178
+ /** Stop active runs across the current workspace. */
1179
+ stopAll: (options?: {
1180
+ reason?: string;
1181
+ }) => Promise<StopAllPlayRunsResult>;
1158
1182
  };
1159
1183
  /** One credit grant pool reported by the billing subscription status endpoint. */
1160
1184
  type BillingCreditPool = {
@@ -1890,6 +1914,21 @@ declare class DeeplineClient {
1890
1914
  stopRun(runId: string, options?: {
1891
1915
  reason?: string;
1892
1916
  }): Promise<StopPlayRunResult>;
1917
+ /**
1918
+ * Stop every active run visible to the current workspace.
1919
+ *
1920
+ * This is the SDK equivalent of:
1921
+ *
1922
+ * ```bash
1923
+ * deepline runs stop-all --reason "stale lock" --json
1924
+ * ```
1925
+ *
1926
+ * Use this when a failed parent run left child or waiting runs active and you
1927
+ * need to clear the workspace run-slot state without knowing each run id.
1928
+ */
1929
+ stopAllRuns(options?: {
1930
+ reason?: string;
1931
+ }): Promise<StopAllPlayRunsResult>;
1893
1932
  /**
1894
1933
  * List callable plays visible to the workspace.
1895
1934
  *
package/dist/index.js CHANGED
@@ -274,10 +274,10 @@ var SDK_RELEASE = {
274
274
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
275
275
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
276
276
  // the SDK enrich generator's one-second stale policy.
277
- version: "0.1.122",
277
+ version: "0.1.123",
278
278
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
279
279
  supportPolicy: {
280
- latest: "0.1.122",
280
+ latest: "0.1.123",
281
281
  minimumSupported: "0.1.53",
282
282
  deprecatedBelow: "0.1.53",
283
283
  commandMinimumSupported: [
@@ -1891,7 +1891,8 @@ var DeeplineClient = class {
1891
1891
  tail: (runId, options2) => this.tailRun(runId, options2),
1892
1892
  logs: (runId, options2) => this.getRunLogs(runId, options2),
1893
1893
  exportDatasetRows: (input) => this.getPlaySheetRows(input),
1894
- stop: (runId, options2) => this.stopRun(runId, options2)
1894
+ stop: (runId, options2) => this.stopRun(runId, options2),
1895
+ stopAll: (options2) => this.stopAllRuns(options2)
1895
1896
  };
1896
1897
  this.billing = {
1897
1898
  plans: () => this.getBillingPlans(),
@@ -2755,15 +2756,21 @@ var DeeplineClient = class {
2755
2756
  * ```
2756
2757
  */
2757
2758
  async listRuns(options) {
2758
- const playName = options.play.trim();
2759
- if (!playName) {
2760
- throw new Error("runs.list requires options.play.");
2759
+ const playName = options.play?.trim();
2760
+ const params = new URLSearchParams();
2761
+ if (playName) {
2762
+ params.set("play", playName);
2761
2763
  }
2762
- const params = new URLSearchParams({ play: playName });
2763
2764
  const status = options.status?.trim();
2764
2765
  if (status) {
2765
2766
  params.set("status", status);
2766
2767
  }
2768
+ if (typeof options.limit === "number" && Number.isFinite(options.limit)) {
2769
+ params.set("limit", String(Math.max(1, Math.floor(options.limit))));
2770
+ }
2771
+ if (!playName && !status) {
2772
+ throw new Error("runs.list requires options.play or options.status.");
2773
+ }
2767
2774
  params.set("compact", "true");
2768
2775
  const response = await this.http.get(
2769
2776
  `/api/v2/runs?${params.toString()}`
@@ -3070,6 +3077,24 @@ var DeeplineClient = class {
3070
3077
  options?.reason ? { reason: options.reason } : {}
3071
3078
  );
3072
3079
  }
3080
+ /**
3081
+ * Stop every active run visible to the current workspace.
3082
+ *
3083
+ * This is the SDK equivalent of:
3084
+ *
3085
+ * ```bash
3086
+ * deepline runs stop-all --reason "stale lock" --json
3087
+ * ```
3088
+ *
3089
+ * Use this when a failed parent run left child or waiting runs active and you
3090
+ * need to clear the workspace run-slot state without knowing each run id.
3091
+ */
3092
+ async stopAllRuns(options) {
3093
+ return this.http.post(
3094
+ "/api/v2/runs/stop-all",
3095
+ options?.reason ? { reason: options.reason } : {}
3096
+ );
3097
+ }
3073
3098
  /**
3074
3099
  * List callable plays visible to the workspace.
3075
3100
  *
package/dist/index.mjs CHANGED
@@ -196,10 +196,10 @@ var SDK_RELEASE = {
196
196
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
197
197
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
198
198
  // the SDK enrich generator's one-second stale policy.
199
- version: "0.1.122",
199
+ version: "0.1.123",
200
200
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
201
201
  supportPolicy: {
202
- latest: "0.1.122",
202
+ latest: "0.1.123",
203
203
  minimumSupported: "0.1.53",
204
204
  deprecatedBelow: "0.1.53",
205
205
  commandMinimumSupported: [
@@ -1813,7 +1813,8 @@ var DeeplineClient = class {
1813
1813
  tail: (runId, options2) => this.tailRun(runId, options2),
1814
1814
  logs: (runId, options2) => this.getRunLogs(runId, options2),
1815
1815
  exportDatasetRows: (input) => this.getPlaySheetRows(input),
1816
- stop: (runId, options2) => this.stopRun(runId, options2)
1816
+ stop: (runId, options2) => this.stopRun(runId, options2),
1817
+ stopAll: (options2) => this.stopAllRuns(options2)
1817
1818
  };
1818
1819
  this.billing = {
1819
1820
  plans: () => this.getBillingPlans(),
@@ -2677,15 +2678,21 @@ var DeeplineClient = class {
2677
2678
  * ```
2678
2679
  */
2679
2680
  async listRuns(options) {
2680
- const playName = options.play.trim();
2681
- if (!playName) {
2682
- throw new Error("runs.list requires options.play.");
2681
+ const playName = options.play?.trim();
2682
+ const params = new URLSearchParams();
2683
+ if (playName) {
2684
+ params.set("play", playName);
2683
2685
  }
2684
- const params = new URLSearchParams({ play: playName });
2685
2686
  const status = options.status?.trim();
2686
2687
  if (status) {
2687
2688
  params.set("status", status);
2688
2689
  }
2690
+ if (typeof options.limit === "number" && Number.isFinite(options.limit)) {
2691
+ params.set("limit", String(Math.max(1, Math.floor(options.limit))));
2692
+ }
2693
+ if (!playName && !status) {
2694
+ throw new Error("runs.list requires options.play or options.status.");
2695
+ }
2689
2696
  params.set("compact", "true");
2690
2697
  const response = await this.http.get(
2691
2698
  `/api/v2/runs?${params.toString()}`
@@ -2992,6 +2999,24 @@ var DeeplineClient = class {
2992
2999
  options?.reason ? { reason: options.reason } : {}
2993
3000
  );
2994
3001
  }
3002
+ /**
3003
+ * Stop every active run visible to the current workspace.
3004
+ *
3005
+ * This is the SDK equivalent of:
3006
+ *
3007
+ * ```bash
3008
+ * deepline runs stop-all --reason "stale lock" --json
3009
+ * ```
3010
+ *
3011
+ * Use this when a failed parent run left child or waiting runs active and you
3012
+ * need to clear the workspace run-slot state without knowing each run id.
3013
+ */
3014
+ async stopAllRuns(options) {
3015
+ return this.http.post(
3016
+ "/api/v2/runs/stop-all",
3017
+ options?.reason ? { reason: options.reason } : {}
3018
+ );
3019
+ }
2995
3020
  /**
2996
3021
  * List callable plays visible to the workspace.
2997
3022
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.122",
3
+ "version": "0.1.123",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {