deepline 0.3.274 → 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.
- package/dist/bundling-sources/sdk/src/client.ts +140 -11
- package/dist/bundling-sources/sdk/src/index.ts +3 -0
- package/dist/bundling-sources/sdk/src/play.ts +4 -10
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/runs/log-cursor.ts +35 -0
- package/dist/bundling-sources/sdk/src/types.ts +10 -3
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +12 -26
- package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +7 -3
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +15 -7
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +18 -18
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1 -0
- package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +7 -4
- package/dist/bundling-sources/shared_libs/plays/table-csv.ts +152 -0
- package/dist/cli/index.js +326 -59
- package/dist/cli/index.mjs +326 -59
- package/dist/{client-D6fRwhnE.d.ts → client-5zY7LsId.d.ts} +70 -5
- package/dist/{client-2rIHKJiq.d.mts → client-CbNvJLgV.d.mts} +70 -5
- package/dist/index.d.mts +6 -12
- package/dist/index.d.ts +6 -12
- package/dist/index.js +87 -9
- package/dist/index.mjs +87 -9
- package/dist/install-integrity.json +4 -2
- package/dist/plays/run-request.d.mts +1 -1
- package/dist/plays/run-request.d.ts +1 -1
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1998,18 +1998,18 @@ function playInputExampleArgs(schema) {
|
|
|
1998
1998
|
if (!schema) return " --input '@<input.json>'";
|
|
1999
1999
|
if (schema.$ref || schema.allOf) return " --input '@<input.json>'";
|
|
2000
2000
|
const csv = schema.csvInput;
|
|
2001
|
-
const
|
|
2001
|
+
const csvField2 = typeof csv?.inputField === "string" ? csv.inputField : null;
|
|
2002
2002
|
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
2003
|
-
const csvOnlyRequired = required.every((key) => key ===
|
|
2003
|
+
const csvOnlyRequired = required.every((key) => key === csvField2);
|
|
2004
2004
|
const alternatives = schema.oneOf ?? schema.anyOf;
|
|
2005
2005
|
const hasCsvAlternative = Array.isArray(alternatives) && alternatives.some((branch) => {
|
|
2006
2006
|
if (!branch || typeof branch !== "object") return false;
|
|
2007
2007
|
const keys = branch.required;
|
|
2008
|
-
return Array.isArray(keys) && keys.includes(
|
|
2008
|
+
return Array.isArray(keys) && keys.includes(csvField2) && keys.every((key) => key === csvField2);
|
|
2009
2009
|
});
|
|
2010
|
-
if (
|
|
2011
|
-
if (
|
|
2012
|
-
const value = JSON.stringify({ [
|
|
2010
|
+
if (csvField2 && csvOnlyRequired && (!alternatives || hasCsvAlternative)) {
|
|
2011
|
+
if (csvField2 === "csv") return " --csv '<contacts.csv>'";
|
|
2012
|
+
const value = JSON.stringify({ [csvField2]: "<contacts.csv>" });
|
|
2013
2013
|
return ` --input '${value.replace(/'/g, "'\\''")}'`;
|
|
2014
2014
|
}
|
|
2015
2015
|
if (Array.isArray(schema.required) && !required.length && !csv && !alternatives) {
|
|
@@ -3512,7 +3512,7 @@ var SDK_RELEASE = {
|
|
|
3512
3512
|
// getters keep their established compatibility behavior.
|
|
3513
3513
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
3514
3514
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
3515
|
-
version: "0.3.
|
|
3515
|
+
version: "0.3.275",
|
|
3516
3516
|
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.",
|
|
3517
3517
|
packageCapabilities: {
|
|
3518
3518
|
updatePreferences: 1
|
|
@@ -6215,6 +6215,28 @@ async function* watchRunEvents(options) {
|
|
|
6215
6215
|
}
|
|
6216
6216
|
}
|
|
6217
6217
|
|
|
6218
|
+
// src/runs/log-cursor.ts
|
|
6219
|
+
var RUN_LOGS_CURSOR_PREFIX = "before:";
|
|
6220
|
+
function encodeRunLogsCursor(beforeSequence) {
|
|
6221
|
+
return `${RUN_LOGS_CURSOR_PREFIX}${beforeSequence}`;
|
|
6222
|
+
}
|
|
6223
|
+
function isRunLogsCursor(value) {
|
|
6224
|
+
return value.startsWith(RUN_LOGS_CURSOR_PREFIX);
|
|
6225
|
+
}
|
|
6226
|
+
function parseRunLogsCursor(value) {
|
|
6227
|
+
const raw = isRunLogsCursor(value) ? value.slice(RUN_LOGS_CURSOR_PREFIX.length) : "";
|
|
6228
|
+
const parsed = /^[1-9]\d*$/.test(raw) ? Number(raw) : NaN;
|
|
6229
|
+
if (!Number.isSafeInteger(parsed)) {
|
|
6230
|
+
throw Object.assign(
|
|
6231
|
+
new Error(
|
|
6232
|
+
`Invalid run log cursor ${JSON.stringify(value)}. Pass the nextCursor value from a previous deepline runs logs result.`
|
|
6233
|
+
),
|
|
6234
|
+
{ exitCode: 2 }
|
|
6235
|
+
);
|
|
6236
|
+
}
|
|
6237
|
+
return parsed;
|
|
6238
|
+
}
|
|
6239
|
+
|
|
6218
6240
|
// src/types.ts
|
|
6219
6241
|
function isStopAllPlayRunsDryRunResult(result) {
|
|
6220
6242
|
return "dryRun" in result && result.dryRun === true;
|
|
@@ -7165,6 +7187,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
7165
7187
|
status: (runId) => this.getRunLifecycleStatus(runId),
|
|
7166
7188
|
list: (options2) => this.listRuns(options2),
|
|
7167
7189
|
listPage: (options2) => this.listRunsPage(options2),
|
|
7190
|
+
history: (options2) => this.getRunsHistory(options2),
|
|
7168
7191
|
watch: (runId, options2) => this.watchRunToTerminal(runId, options2),
|
|
7169
7192
|
tail: (runId, options2) => this.tailRun(runId, options2),
|
|
7170
7193
|
logs: (runId, options2) => this.getRunLogs(runId, options2),
|
|
@@ -8242,11 +8265,21 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8242
8265
|
if (options?.full === true) {
|
|
8243
8266
|
params.set("full", "true");
|
|
8244
8267
|
}
|
|
8268
|
+
if (options?.configuration === true) {
|
|
8269
|
+
params.set("include", "configuration");
|
|
8270
|
+
}
|
|
8245
8271
|
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
8246
8272
|
const response = await this.http.get(
|
|
8247
8273
|
`/api/v2/runs/${encodeURIComponent(runId)}${query}`,
|
|
8248
8274
|
{ headers: { "x-deepline-run-status": "1" } }
|
|
8249
8275
|
);
|
|
8276
|
+
if (options?.configuration === true && !Object.hasOwn(response, "contract")) {
|
|
8277
|
+
throw new DeeplineError(
|
|
8278
|
+
"This server does not support recorded configuration reads.",
|
|
8279
|
+
void 0,
|
|
8280
|
+
"RUN_CONFIGURATION_UNAVAILABLE"
|
|
8281
|
+
);
|
|
8282
|
+
}
|
|
8250
8283
|
const status = normalizePlayStatus(response);
|
|
8251
8284
|
if (options?.failedLogs !== true || status.status !== "failed") {
|
|
8252
8285
|
return status;
|
|
@@ -8334,6 +8367,33 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8334
8367
|
async listRuns(options) {
|
|
8335
8368
|
return (await this.listRunsPage(options)).runs;
|
|
8336
8369
|
}
|
|
8370
|
+
/** The same tenant-scoped run history searched by the dashboard and CLI. */
|
|
8371
|
+
async getRunsHistory(options = {}) {
|
|
8372
|
+
const params = new URLSearchParams();
|
|
8373
|
+
const search = options.search?.trim();
|
|
8374
|
+
if (search && search.length > 200) {
|
|
8375
|
+
throw new Error("Run search must be at most 200 characters.");
|
|
8376
|
+
}
|
|
8377
|
+
if (options.type && options.type !== "all" && !search) {
|
|
8378
|
+
throw new Error("runs.history options.type requires options.search.");
|
|
8379
|
+
}
|
|
8380
|
+
if (search) params.set("search", search);
|
|
8381
|
+
if (search && options.type) params.set("type", options.type);
|
|
8382
|
+
if (options.cursor) params.set("cursor", options.cursor);
|
|
8383
|
+
if (options.orgId) params.set("orgId", options.orgId);
|
|
8384
|
+
if (options.limit !== void 0) {
|
|
8385
|
+
if (!Number.isSafeInteger(options.limit) || options.limit < 1) {
|
|
8386
|
+
throw new Error(
|
|
8387
|
+
"runs.history options.limit must be a positive integer."
|
|
8388
|
+
);
|
|
8389
|
+
}
|
|
8390
|
+
params.set("limit", String(options.limit));
|
|
8391
|
+
}
|
|
8392
|
+
return this.http.get(
|
|
8393
|
+
`/api/v2/dashboard/runs-history?${params.toString()}`,
|
|
8394
|
+
{ signal: options.signal }
|
|
8395
|
+
);
|
|
8396
|
+
}
|
|
8337
8397
|
/** Read one run page without discarding server pagination metadata. */
|
|
8338
8398
|
async listRunsPage(options) {
|
|
8339
8399
|
const playName = options.play?.trim();
|
|
@@ -8440,6 +8500,13 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8440
8500
|
"INVALID_RUN_LOG_VIEW"
|
|
8441
8501
|
);
|
|
8442
8502
|
}
|
|
8503
|
+
if (options?.cursor !== void 0 && options.failed === true) {
|
|
8504
|
+
throw new DeeplineError(
|
|
8505
|
+
"runs.logs cannot combine failed with cursor.",
|
|
8506
|
+
void 0,
|
|
8507
|
+
"INVALID_RUN_LOG_VIEW"
|
|
8508
|
+
);
|
|
8509
|
+
}
|
|
8443
8510
|
if (options?.failed === true) {
|
|
8444
8511
|
const requestedLimit = typeof options.limit === "number" && Number.isFinite(options.limit) && options.limit > 0 ? Math.trunc(options.limit) : RUNS_FAILED_LOG_LIMIT;
|
|
8445
8512
|
const failedLimit = Math.min(RUNS_FAILED_LOG_LIMIT, requestedLimit);
|
|
@@ -8465,6 +8532,7 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8465
8532
|
...page.logsTruncated ? { logsTruncated: true } : {}
|
|
8466
8533
|
};
|
|
8467
8534
|
}
|
|
8535
|
+
const beforeSequence = options?.cursor !== void 0 ? parseRunLogsCursor(options.cursor) : null;
|
|
8468
8536
|
const limit = options?.all ? Number.MAX_SAFE_INTEGER : typeof options?.limit === "number" && Number.isFinite(options.limit) && options.limit > 0 ? Math.trunc(options.limit) : 200;
|
|
8469
8537
|
const fetchPage = (afterSeq2, pageLimit) => this.http.get(
|
|
8470
8538
|
`/api/v2/runs/${encodeURIComponent(runId)}/logs?afterSeq=${afterSeq2}&limit=${pageLimit}`,
|
|
@@ -8472,24 +8540,33 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8472
8540
|
);
|
|
8473
8541
|
const probe = await fetchPage(0, 1);
|
|
8474
8542
|
const lastStoredSeq = probe.lastStoredSeq;
|
|
8475
|
-
|
|
8543
|
+
const oldestStoredSeq = probe.entries[0]?.seq ?? null;
|
|
8544
|
+
const upperSeq = beforeSequence === null ? Number.POSITIVE_INFINITY : Math.min(beforeSequence - 1, lastStoredSeq);
|
|
8545
|
+
const windowEndSeq = Math.min(upperSeq, lastStoredSeq);
|
|
8546
|
+
let afterSeq = options?.all ? 0 : Math.max(0, windowEndSeq - limit);
|
|
8476
8547
|
const entries = [];
|
|
8477
|
-
while (entries.length < limit) {
|
|
8548
|
+
while (entries.length < limit && afterSeq < upperSeq) {
|
|
8478
8549
|
const page = await fetchPage(
|
|
8479
8550
|
afterSeq,
|
|
8480
|
-
Math.min(
|
|
8551
|
+
Math.min(
|
|
8552
|
+
RUN_LOGS_PAGE_LIMIT,
|
|
8553
|
+
limit - entries.length,
|
|
8554
|
+
upperSeq - afterSeq
|
|
8555
|
+
)
|
|
8481
8556
|
);
|
|
8482
|
-
|
|
8557
|
+
const inWindow = page.entries.filter((entry) => entry.seq <= upperSeq);
|
|
8558
|
+
if (inWindow.length === 0) {
|
|
8483
8559
|
break;
|
|
8484
8560
|
}
|
|
8485
|
-
entries.push(...
|
|
8486
|
-
afterSeq =
|
|
8487
|
-
if (!page.hasMore) {
|
|
8561
|
+
entries.push(...inWindow);
|
|
8562
|
+
afterSeq = inWindow[inWindow.length - 1].seq;
|
|
8563
|
+
if (!page.hasMore || inWindow.length < page.entries.length) {
|
|
8488
8564
|
break;
|
|
8489
8565
|
}
|
|
8490
8566
|
}
|
|
8491
8567
|
const firstSequence = entries.length > 0 ? entries[0].seq : null;
|
|
8492
8568
|
const lastSequence = entries.length > 0 ? entries[entries.length - 1].seq : null;
|
|
8569
|
+
const olderLinesExist = firstSequence !== null && oldestStoredSeq !== null && firstSequence > oldestStoredSeq;
|
|
8493
8570
|
return {
|
|
8494
8571
|
runId: probe.runId,
|
|
8495
8572
|
totalCount: probe.totalLogCount,
|
|
@@ -8497,7 +8574,8 @@ var DeeplineClient = class _DeeplineClient {
|
|
|
8497
8574
|
firstSequence,
|
|
8498
8575
|
lastSequence,
|
|
8499
8576
|
truncated: entries.length < probe.totalLogCount,
|
|
8500
|
-
hasMore:
|
|
8577
|
+
hasMore: olderLinesExist,
|
|
8578
|
+
nextCursor: olderLinesExist ? encodeRunLogsCursor(firstSequence) : null,
|
|
8501
8579
|
entries: entries.map((entry) => entry.line),
|
|
8502
8580
|
view: options?.all ? "all" : "tail",
|
|
8503
8581
|
...probe.logsTruncated ? { logsTruncated: true } : {}
|
|
@@ -10468,6 +10546,7 @@ var ROOTS = {
|
|
|
10468
10546
|
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",
|
|
10469
10547
|
run: "schemaVersion kind run datasets actions apiVersion dashboardUrl progress rowOutcomes steps errors error warnings result resultState execution command_context diagnostics",
|
|
10470
10548
|
get: "schemaVersion kind run runStatus steps failures errorDetails rowOutcomes warnings failedLogs datasets result resultState actions diagnostics command_context",
|
|
10549
|
+
config: "runId contract command_context",
|
|
10471
10550
|
export: "runId datasets csv_path json_path format source rowCount columns notice metadata_path actions command_context"
|
|
10472
10551
|
};
|
|
10473
10552
|
function parseJsonFields(args, surface) {
|
|
@@ -15788,12 +15867,12 @@ var SECTIONS = [
|
|
|
15788
15867
|
title: "Choose the read",
|
|
15789
15868
|
paragraphs: [
|
|
15790
15869
|
"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.",
|
|
15791
|
-
"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.",
|
|
15792
|
-
"Event search: omit the run ID, or add any of --since, --until, --play, --kind, --where, --payloads, --
|
|
15870
|
+
"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.",
|
|
15871
|
+
"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.",
|
|
15793
15872
|
"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."
|
|
15794
15873
|
],
|
|
15795
15874
|
commands: [
|
|
15796
|
-
"deepline runs logs <run-id> --json",
|
|
15875
|
+
"deepline runs logs <run-id> --cursor before:1201 --json",
|
|
15797
15876
|
"deepline runs logs <run-id> --out run.log --json",
|
|
15798
15877
|
"deepline runs logs --kind run.failed --json",
|
|
15799
15878
|
"deepline runs logs --kind step.failed --payloads --json",
|
|
@@ -18545,24 +18624,31 @@ includes nextCommand when another page is available.
|
|
|
18545
18624
|
|
|
18546
18625
|
// src/cli/commands/plays/run-history.ts
|
|
18547
18626
|
async function handleRunsHistory(options) {
|
|
18548
|
-
|
|
18549
|
-
if (options.
|
|
18550
|
-
|
|
18627
|
+
let limit;
|
|
18628
|
+
if (options.type && !["all", "plays", "monitors"].includes(options.type)) {
|
|
18629
|
+
throw new Error("--type must be all, plays or monitors.");
|
|
18630
|
+
}
|
|
18551
18631
|
if (options.limit !== void 0) {
|
|
18552
|
-
|
|
18632
|
+
limit = Number(options.limit);
|
|
18553
18633
|
if (!/^\d+$/.test(options.limit) || !Number.isSafeInteger(limit) || limit < 1) {
|
|
18554
18634
|
throw new Error("--limit must be a positive integer.");
|
|
18555
18635
|
}
|
|
18556
|
-
query.set("limit", String(limit));
|
|
18557
18636
|
}
|
|
18558
|
-
const
|
|
18559
|
-
|
|
18560
|
-
|
|
18561
|
-
|
|
18637
|
+
const page = await new DeeplineClient().runs.history({
|
|
18638
|
+
cursor: options.cursor,
|
|
18639
|
+
orgId: options.org,
|
|
18640
|
+
search: options.search,
|
|
18641
|
+
type: options.type,
|
|
18642
|
+
limit
|
|
18643
|
+
});
|
|
18562
18644
|
const lines = page.runs.map(
|
|
18563
18645
|
(run) => `${run.workflowName} \xB7 ${run.status} \xB7 ${run.runId}`
|
|
18564
18646
|
);
|
|
18565
|
-
if (lines.length === 0)
|
|
18647
|
+
if (lines.length === 0) {
|
|
18648
|
+
lines.push(
|
|
18649
|
+
options.search && page.hasMore ? "No matches in this page; continue searching with the next cursor." : "No runs found on this page."
|
|
18650
|
+
);
|
|
18651
|
+
}
|
|
18566
18652
|
if (page.hasMore) lines.push(`Next cursor: ${page.nextCursor}`);
|
|
18567
18653
|
printCommandEnvelope(
|
|
18568
18654
|
{ ...page, render: { sections: [{ title: "Run history", lines }] } },
|
|
@@ -18574,6 +18660,12 @@ function registerRunHistoryCommand(runs) {
|
|
|
18574
18660
|
"--cursor <cursor>",
|
|
18575
18661
|
"Opaque nextCursor returned by the previous page"
|
|
18576
18662
|
).option("--limit <count>", "Maximum runs on this page").option(
|
|
18663
|
+
"--search <text>",
|
|
18664
|
+
"Search Play/workflow names, run IDs and statuses"
|
|
18665
|
+
).option(
|
|
18666
|
+
"--type <type>",
|
|
18667
|
+
"Search all, plays or monitors (requires --search)"
|
|
18668
|
+
).option(
|
|
18577
18669
|
"--org <id>",
|
|
18578
18670
|
"Workspace ID (must match the authenticated workspace)"
|
|
18579
18671
|
).option("--json", "Emit JSON output. Also automatic when stdout is piped").addHelpText(
|
|
@@ -24284,6 +24376,63 @@ var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : (0, im
|
|
|
24284
24376
|
var import_node_fs11 = require("fs");
|
|
24285
24377
|
var import_node_path13 = require("path");
|
|
24286
24378
|
|
|
24379
|
+
// ../plays/table-csv.ts
|
|
24380
|
+
var TABLE_EXPORT_ERROR_COLUMN = "_error";
|
|
24381
|
+
var UNRECORDED_FAILURE_REASON = "Row failed without a recorded reason.";
|
|
24382
|
+
function tableCellText(value) {
|
|
24383
|
+
if (value === null || value === void 0) return "";
|
|
24384
|
+
if (typeof value === "string") return value;
|
|
24385
|
+
if (typeof value === "number" || typeof value === "bigint" || typeof value === "boolean")
|
|
24386
|
+
return String(value);
|
|
24387
|
+
if (value instanceof Date) return value.toISOString();
|
|
24388
|
+
if (typeof value === "symbol" || typeof value === "function") return "";
|
|
24389
|
+
try {
|
|
24390
|
+
return JSON.stringify(
|
|
24391
|
+
value,
|
|
24392
|
+
(_key, nested) => typeof nested === "bigint" ? nested.toString() : nested
|
|
24393
|
+
) ?? "";
|
|
24394
|
+
} catch {
|
|
24395
|
+
return String(value);
|
|
24396
|
+
}
|
|
24397
|
+
}
|
|
24398
|
+
function csvField(value) {
|
|
24399
|
+
const text = tableCellText(value);
|
|
24400
|
+
return /[",\r\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text;
|
|
24401
|
+
}
|
|
24402
|
+
function csvRecord(values) {
|
|
24403
|
+
return `${values.map(csvField).join(",")}
|
|
24404
|
+
`;
|
|
24405
|
+
}
|
|
24406
|
+
function isFailedRow(row) {
|
|
24407
|
+
return row.status === "failed";
|
|
24408
|
+
}
|
|
24409
|
+
function tableExportHasFailedRows(rows) {
|
|
24410
|
+
for (const row of rows) if (isFailedRow(row)) return true;
|
|
24411
|
+
return false;
|
|
24412
|
+
}
|
|
24413
|
+
function tableExportErrorCell(row) {
|
|
24414
|
+
if (!isFailedRow(row)) return "";
|
|
24415
|
+
const reason = typeof row.error === "string" ? row.error.trim() : "";
|
|
24416
|
+
return reason || UNRECORDED_FAILURE_REASON;
|
|
24417
|
+
}
|
|
24418
|
+
function tableExportColumns(columns, withError) {
|
|
24419
|
+
if (!withError) return [...columns];
|
|
24420
|
+
return [
|
|
24421
|
+
...columns.filter((column) => column !== TABLE_EXPORT_ERROR_COLUMN),
|
|
24422
|
+
TABLE_EXPORT_ERROR_COLUMN
|
|
24423
|
+
];
|
|
24424
|
+
}
|
|
24425
|
+
function tableExportCells(row, columns, withError) {
|
|
24426
|
+
return tableExportColumns(columns, withError).map(
|
|
24427
|
+
(column) => column === TABLE_EXPORT_ERROR_COLUMN && withError ? tableExportErrorCell(row) : Object.hasOwn(row.data, column) ? row.data[column] : void 0
|
|
24428
|
+
);
|
|
24429
|
+
}
|
|
24430
|
+
function tableCsvText(header, records) {
|
|
24431
|
+
let text = csvRecord(header);
|
|
24432
|
+
for (const record5 of records) text += csvRecord(record5);
|
|
24433
|
+
return text;
|
|
24434
|
+
}
|
|
24435
|
+
|
|
24287
24436
|
// src/cli/run-dataset-order.ts
|
|
24288
24437
|
function underscoreKeysLast(keys) {
|
|
24289
24438
|
return [...keys].sort(
|
|
@@ -24332,9 +24481,13 @@ var RunDatasetCsv = class _RunDatasetCsv {
|
|
|
24332
24481
|
}
|
|
24333
24482
|
write(outPath) {
|
|
24334
24483
|
const absolutePath = (0, import_node_path13.resolve)(outPath);
|
|
24484
|
+
const { rows, columns } = this.#projection;
|
|
24335
24485
|
(0, import_node_fs11.writeFileSync)(
|
|
24336
24486
|
absolutePath,
|
|
24337
|
-
|
|
24487
|
+
tableCsvText(
|
|
24488
|
+
columns,
|
|
24489
|
+
rows.map((data) => tableExportCells({ data }, columns, false))
|
|
24490
|
+
),
|
|
24338
24491
|
"utf-8"
|
|
24339
24492
|
);
|
|
24340
24493
|
return absolutePath;
|
|
@@ -31930,7 +32083,20 @@ async function fetchBackingDatasetRows(input2) {
|
|
|
31930
32083
|
}
|
|
31931
32084
|
offset += page.rows.length;
|
|
31932
32085
|
}
|
|
31933
|
-
const
|
|
32086
|
+
const withError = tableExportHasFailedRows(
|
|
32087
|
+
sheetRows.filter(
|
|
32088
|
+
(row) => Boolean(row) && typeof row === "object" && !Array.isArray(row)
|
|
32089
|
+
)
|
|
32090
|
+
);
|
|
32091
|
+
const rows = sheetRows.map((row) => {
|
|
32092
|
+
const data = exportableSheetRow(row);
|
|
32093
|
+
return data && withError ? {
|
|
32094
|
+
...data,
|
|
32095
|
+
[TABLE_EXPORT_ERROR_COLUMN]: tableExportErrorCell(
|
|
32096
|
+
row
|
|
32097
|
+
)
|
|
32098
|
+
} : data;
|
|
32099
|
+
}).filter((row) => Boolean(row));
|
|
31934
32100
|
const hasCompleteSettledPrefix = acceptsSettledRowsAsCompleteExport(input2.status) && settledTotal !== null && // A zero-row run-scoped read is not a settled export when the returned
|
|
31935
32101
|
// Dataset Handle advertised rows. That shape is the replay/reuse case:
|
|
31936
32102
|
// the rows belong to another writer (or the projection has not caught up)
|
|
@@ -33912,9 +34078,12 @@ function renderRunOverviewText(overview, extras = {}) {
|
|
|
33912
34078
|
${renderCommandEnvelopeText({ render: { sections, actions: actions2 } })}`;
|
|
33913
34079
|
}
|
|
33914
34080
|
async function handleRunGet(args) {
|
|
33915
|
-
const selection = parseJsonFields(
|
|
34081
|
+
const selection = parseJsonFields(
|
|
34082
|
+
args,
|
|
34083
|
+
args.includes("--config") ? "config" : "get"
|
|
34084
|
+
);
|
|
33916
34085
|
args = selection.args;
|
|
33917
|
-
const usage2 = "Usage: deepline runs get <run-id> [--json] [--full] [--input] [--log-failed]";
|
|
34086
|
+
const usage2 = "Usage: deepline runs get <run-id> [--json] [--full] [--input] [--config] [--log-failed]";
|
|
33918
34087
|
let runId;
|
|
33919
34088
|
try {
|
|
33920
34089
|
runId = parseRunIdPositional(args, usage2);
|
|
@@ -33923,6 +34092,25 @@ async function handleRunGet(args) {
|
|
|
33923
34092
|
return 1;
|
|
33924
34093
|
}
|
|
33925
34094
|
const client2 = new DeeplineClient();
|
|
34095
|
+
if (args.includes("--config")) {
|
|
34096
|
+
if (args.some((arg) => ["--input", "--full", "--log-failed"].includes(arg))) {
|
|
34097
|
+
console.error(
|
|
34098
|
+
"--config cannot be combined with --input, --full or --log-failed."
|
|
34099
|
+
);
|
|
34100
|
+
return 1;
|
|
34101
|
+
}
|
|
34102
|
+
const status2 = await client2.runs.get(runId, { configuration: true });
|
|
34103
|
+
if (!Object.hasOwn(status2, "contract")) {
|
|
34104
|
+
throw new Error(
|
|
34105
|
+
"This server does not support recorded configuration reads."
|
|
34106
|
+
);
|
|
34107
|
+
}
|
|
34108
|
+
printCommandEnvelope(
|
|
34109
|
+
{ runId, contract: status2.contract ?? null },
|
|
34110
|
+
{ json: true, fields: selection.fields }
|
|
34111
|
+
);
|
|
34112
|
+
return 0;
|
|
34113
|
+
}
|
|
33926
34114
|
if (args.includes("--input")) {
|
|
33927
34115
|
const input2 = await client2.getRunInput(runId);
|
|
33928
34116
|
printCommandEnvelope(input2, { json: true });
|
|
@@ -34428,15 +34616,17 @@ async function handleRunLogs(args) {
|
|
|
34428
34616
|
"--play",
|
|
34429
34617
|
"--kind",
|
|
34430
34618
|
"--where",
|
|
34431
|
-
"--cursor",
|
|
34432
34619
|
"--payloads",
|
|
34433
34620
|
"--runtime-namespace",
|
|
34434
34621
|
"--runtime-backend"
|
|
34435
34622
|
]);
|
|
34436
|
-
|
|
34623
|
+
const cursorIndex = args.indexOf("--cursor");
|
|
34624
|
+
const cursorValue = cursorIndex >= 0 ? args[cursorIndex + 1] : void 0;
|
|
34625
|
+
const continuesEventSearch = cursorIndex >= 0 && !(cursorValue && isRunLogsCursor(cursorValue));
|
|
34626
|
+
if (!args[0] || args[0].startsWith("--") || continuesEventSearch || args.some((arg) => searchFlags.has(arg))) {
|
|
34437
34627
|
return handleRunEventSearch(args);
|
|
34438
34628
|
}
|
|
34439
|
-
const usage2 = "Usage: deepline runs logs <run-id> [--limit 200] [--failed] [--out run.log] [--log-level debug|info|warn|error] [--json]";
|
|
34629
|
+
const usage2 = "Usage: deepline runs logs <run-id> [--limit 200] [--cursor before:<seq>] [--failed] [--out run.log] [--log-level debug|info|warn|error] [--json]";
|
|
34440
34630
|
let runId;
|
|
34441
34631
|
try {
|
|
34442
34632
|
runId = parseRunIdPositional(args, usage2);
|
|
@@ -34446,6 +34636,7 @@ async function handleRunLogs(args) {
|
|
|
34446
34636
|
}
|
|
34447
34637
|
let limit = 200;
|
|
34448
34638
|
let outPath = null;
|
|
34639
|
+
let cursor;
|
|
34449
34640
|
let logLevel = "debug";
|
|
34450
34641
|
let hasExplicitLogLevel = false;
|
|
34451
34642
|
let usesDebugAlias = false;
|
|
@@ -34484,6 +34675,10 @@ async function handleRunLogs(args) {
|
|
|
34484
34675
|
outPath = (0, import_node_path19.resolve)(args[++index]);
|
|
34485
34676
|
continue;
|
|
34486
34677
|
}
|
|
34678
|
+
if (arg === "--cursor" && args[index + 1]) {
|
|
34679
|
+
cursor = args[++index];
|
|
34680
|
+
continue;
|
|
34681
|
+
}
|
|
34487
34682
|
if (arg.startsWith("--")) {
|
|
34488
34683
|
console.error(`${arg} is not supported by deepline runs logs.`);
|
|
34489
34684
|
return 1;
|
|
@@ -34502,6 +34697,12 @@ async function handleRunLogs(args) {
|
|
|
34502
34697
|
);
|
|
34503
34698
|
return 1;
|
|
34504
34699
|
}
|
|
34700
|
+
if (cursor !== void 0 && (failed || outPath)) {
|
|
34701
|
+
console.error(
|
|
34702
|
+
"--cursor pages the bounded log tail; it cannot be combined with --failed or --out."
|
|
34703
|
+
);
|
|
34704
|
+
return 1;
|
|
34705
|
+
}
|
|
34505
34706
|
const client2 = new DeeplineClient();
|
|
34506
34707
|
if (outPath) {
|
|
34507
34708
|
const result2 = await client2.runs.logs(runId, { all: true });
|
|
@@ -34535,19 +34736,25 @@ async function handleRunLogs(args) {
|
|
|
34535
34736
|
return 0;
|
|
34536
34737
|
}
|
|
34537
34738
|
const result = await client2.runs.logs(runId, {
|
|
34538
|
-
...failed ? { limit, failed: true } : { all: logLevel !== "debug", limit }
|
|
34539
|
-
|
|
34540
|
-
|
|
34541
|
-
|
|
34542
|
-
|
|
34543
|
-
|
|
34544
|
-
|
|
34739
|
+
...failed ? { limit, failed: true } : { all: logLevel !== "debug", limit },
|
|
34740
|
+
...cursor !== void 0 ? { cursor } : {}
|
|
34741
|
+
});
|
|
34742
|
+
const page = failed ? {
|
|
34743
|
+
entries: result.entries,
|
|
34744
|
+
firstSequence: result.firstSequence,
|
|
34745
|
+
lastSequence: result.lastSequence,
|
|
34746
|
+
truncated: result.truncated,
|
|
34747
|
+
hasMore: result.hasMore,
|
|
34748
|
+
nextCursor: void 0
|
|
34749
|
+
} : selectRunLogTailPage(result, logLevel, limit);
|
|
34750
|
+
const entries = page.entries;
|
|
34751
|
+
const nextPage = page.nextCursor ? `deepline runs logs ${result.runId} --limit ${limit}${logLevel === "debug" ? "" : ` --log-level ${logLevel}`} --cursor ${page.nextCursor} --json` : null;
|
|
34545
34752
|
const filteredResult = {
|
|
34546
34753
|
...result,
|
|
34547
34754
|
entries,
|
|
34548
34755
|
returnedCount: entries.length,
|
|
34549
|
-
truncated:
|
|
34550
|
-
hasMore:
|
|
34756
|
+
truncated: page.truncated,
|
|
34757
|
+
hasMore: page.hasMore,
|
|
34551
34758
|
view: failed ? result.view : "tail",
|
|
34552
34759
|
next: {
|
|
34553
34760
|
...result.next ?? {},
|
|
@@ -34560,10 +34767,11 @@ async function handleRunLogs(args) {
|
|
|
34560
34767
|
runId: result.runId,
|
|
34561
34768
|
totalCount: result.totalCount,
|
|
34562
34769
|
returnedCount: entries.length,
|
|
34563
|
-
firstSequence:
|
|
34564
|
-
lastSequence:
|
|
34770
|
+
firstSequence: page.firstSequence,
|
|
34771
|
+
lastSequence: page.lastSequence,
|
|
34565
34772
|
truncated: filteredResult.truncated,
|
|
34566
34773
|
hasMore: filteredResult.hasMore,
|
|
34774
|
+
...page.nextCursor !== void 0 ? { nextCursor: page.nextCursor } : {},
|
|
34567
34775
|
logLevel,
|
|
34568
34776
|
...result.logsTruncated ? { logsTruncated: true } : {},
|
|
34569
34777
|
entries,
|
|
@@ -34572,6 +34780,7 @@ async function handleRunLogs(args) {
|
|
|
34572
34780
|
...result.warning ? { warning: result.warning } : {},
|
|
34573
34781
|
next: {
|
|
34574
34782
|
...result.next ?? {},
|
|
34783
|
+
...nextPage ? { page: nextPage } : {},
|
|
34575
34784
|
export: `deepline runs logs ${result.runId} --out run.log --log-level ${logLevel} --json`
|
|
34576
34785
|
},
|
|
34577
34786
|
render: { sections: [{ title: "run logs", lines: entries }] }
|
|
@@ -34583,6 +34792,37 @@ async function handleRunLogs(args) {
|
|
|
34583
34792
|
);
|
|
34584
34793
|
return 0;
|
|
34585
34794
|
}
|
|
34795
|
+
function selectRunLogTailPage(result, logLevel, limit) {
|
|
34796
|
+
if (logLevel === "debug") {
|
|
34797
|
+
return {
|
|
34798
|
+
entries: [...result.entries],
|
|
34799
|
+
firstSequence: result.firstSequence,
|
|
34800
|
+
lastSequence: result.lastSequence,
|
|
34801
|
+
truncated: result.truncated,
|
|
34802
|
+
hasMore: result.hasMore,
|
|
34803
|
+
nextCursor: result.nextCursor ?? null
|
|
34804
|
+
};
|
|
34805
|
+
}
|
|
34806
|
+
const first = result.firstSequence;
|
|
34807
|
+
if (result.entries.length > 0 && (first === null || result.lastSequence === null || result.lastSequence - first + 1 !== result.entries.length)) {
|
|
34808
|
+
throw new Error(
|
|
34809
|
+
`Run log window is not contiguous (sequences ${first}..${result.lastSequence} for ${result.entries.length} lines); cannot page by severity.`
|
|
34810
|
+
);
|
|
34811
|
+
}
|
|
34812
|
+
const matching = result.entries.map((line, index) => ({ line, seq: first + index })).filter(
|
|
34813
|
+
(entry) => logLevelReaches(classifyLogLine(entry.line).level, logLevel)
|
|
34814
|
+
);
|
|
34815
|
+
const selected = matching.slice(-limit);
|
|
34816
|
+
const olderMatchesExist = matching.length > selected.length;
|
|
34817
|
+
return {
|
|
34818
|
+
entries: selected.map((entry) => entry.line),
|
|
34819
|
+
firstSequence: selected[0]?.seq ?? null,
|
|
34820
|
+
lastSequence: selected.at(-1)?.seq ?? null,
|
|
34821
|
+
truncated: result.truncated || olderMatchesExist,
|
|
34822
|
+
hasMore: olderMatchesExist,
|
|
34823
|
+
nextCursor: olderMatchesExist ? encodeRunLogsCursor(selected[0].seq) : null
|
|
34824
|
+
};
|
|
34825
|
+
}
|
|
34586
34826
|
async function handleRunEventSearch(args) {
|
|
34587
34827
|
const usage2 = "Usage: deepline runs logs [run-id] [--since ISO] [--until ISO] [--play name] [--kind kind] [--where jsonpath] [--payloads] [--cursor token] [--limit 100] [--json]";
|
|
34588
34828
|
const values = {};
|
|
@@ -34748,6 +34988,14 @@ function buildRunLogsText(result) {
|
|
|
34748
34988
|
}
|
|
34749
34989
|
return `${lines.join("\n")}${lines.length > 0 ? "\n" : ""}`;
|
|
34750
34990
|
}
|
|
34991
|
+
function resolveRunStopState(result) {
|
|
34992
|
+
if (result.state) return result.state;
|
|
34993
|
+
if (result.cancelling === true) return "cancelling";
|
|
34994
|
+
if (result.stopped === false || result.staleSchedulerState === true) {
|
|
34995
|
+
return "failed";
|
|
34996
|
+
}
|
|
34997
|
+
return "stopped";
|
|
34998
|
+
}
|
|
34751
34999
|
async function handleRunStop(args) {
|
|
34752
35000
|
const usage2 = 'Usage: deepline runs stop <run-id> [--reason "text"] [--json]';
|
|
34753
35001
|
let runId;
|
|
@@ -34766,15 +35014,25 @@ async function handleRunStop(args) {
|
|
|
34766
35014
|
}
|
|
34767
35015
|
const client2 = new DeeplineClient();
|
|
34768
35016
|
const result = await client2.runs.stop(runId, { reason });
|
|
34769
|
-
|
|
35017
|
+
const state = resolveRunStopState(result);
|
|
35018
|
+
const hitlCleanupIncomplete = state === "cancelling" && result.hitlCancellationPending === true;
|
|
35019
|
+
if (state === "cancelling" && !hitlCleanupIncomplete) {
|
|
35020
|
+
const {
|
|
35021
|
+
error: _legacyError,
|
|
35022
|
+
staleSchedulerState: _legacyStale,
|
|
35023
|
+
...cancelling
|
|
35024
|
+
} = result;
|
|
34770
35025
|
const lines2 = [
|
|
34771
|
-
`
|
|
35026
|
+
`Cancelling run ${result.runId || runId}; sandbox cleanup and the final run update are pending.`,
|
|
34772
35027
|
...result.hitlCancelledCount > 0 ? [`cancelled HITL waits: ${result.hitlCancelledCount}`] : [],
|
|
34773
35028
|
`inspect: deepline runs get ${runId} --full --json`
|
|
34774
35029
|
];
|
|
34775
35030
|
printCommandEnvelope(
|
|
34776
35031
|
{
|
|
34777
|
-
...
|
|
35032
|
+
...cancelling,
|
|
35033
|
+
state,
|
|
35034
|
+
stopped: false,
|
|
35035
|
+
cancelling: true,
|
|
34778
35036
|
render: {
|
|
34779
35037
|
sections: [
|
|
34780
35038
|
{
|
|
@@ -34788,9 +35046,8 @@ async function handleRunStop(args) {
|
|
|
34788
35046
|
);
|
|
34789
35047
|
return 0;
|
|
34790
35048
|
}
|
|
34791
|
-
|
|
34792
|
-
|
|
34793
|
-
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";
|
|
35049
|
+
if (state === "failed" || hitlCleanupIncomplete) {
|
|
35050
|
+
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";
|
|
34794
35051
|
const lines2 = [
|
|
34795
35052
|
`Failed to stop run ${runId}: ${detail}.`,
|
|
34796
35053
|
...result.hitlCancelledCount > 0 ? [`cancelled HITL waits: ${result.hitlCancelledCount}`] : [],
|
|
@@ -36811,15 +37068,15 @@ Examples:
|
|
|
36811
37068
|
...options.json ? ["--json"] : []
|
|
36812
37069
|
]);
|
|
36813
37070
|
});
|
|
36814
|
-
const runs = program.command("runs").description("Inspect,
|
|
37071
|
+
const runs = program.command("runs").description("Inspect, watch, stop, and export play runs.").addHelpText(
|
|
36815
37072
|
"after",
|
|
36816
37073
|
`
|
|
36817
37074
|
Concepts:
|
|
36818
37075
|
A run is one execution instance of a play. It has status, progress, logs,
|
|
36819
37076
|
returned result, dataset previews, recovery metadata, and optional dataset export.
|
|
36820
37077
|
plays run starts NEW work and follows it by default; --no-wait returns immediately.
|
|
36821
|
-
runs
|
|
36822
|
-
Use
|
|
37078
|
+
runs watch attaches to EXISTING work and follows progress without starting a run.
|
|
37079
|
+
Use watch after a disconnect or --no-wait; do not launch again to reconnect.
|
|
36823
37080
|
get reads the current overview once. logs fetches persisted log history.
|
|
36824
37081
|
stop requests cancellation. rerun starts new work and may spend credits.
|
|
36825
37082
|
|
|
@@ -36833,14 +37090,15 @@ Retrieve results:
|
|
|
36833
37090
|
not JSON rows. For a JSON row file, use --format json --out results.json.
|
|
36834
37091
|
|
|
36835
37092
|
Follow existing work:
|
|
36836
|
-
deepline runs
|
|
36837
|
-
|
|
36838
|
-
|
|
37093
|
+
deepline runs watch <run-id>
|
|
37094
|
+
watch --json waits for one terminal JSON document; --jsonl streams live events.
|
|
37095
|
+
runs tail is an alias of runs watch.
|
|
36839
37096
|
|
|
36840
37097
|
More options:
|
|
36841
37098
|
deepline runs get -h
|
|
36842
37099
|
deepline runs children -h
|
|
36843
37100
|
deepline runs tail -h
|
|
37101
|
+
deepline runs watch -h
|
|
36844
37102
|
deepline runs export -h
|
|
36845
37103
|
deepline plays -h
|
|
36846
37104
|
|
|
@@ -36887,6 +37145,7 @@ Notes:
|
|
|
36887
37145
|
Run activity and status evidence retain provider cooldown and call progress.
|
|
36888
37146
|
Use --input only when you intentionally need the original payload; it can
|
|
36889
37147
|
contain customer data and is never included in ordinary status output.
|
|
37148
|
+
--config reads only the recorded graph and source; it never uses current Play code.
|
|
36890
37149
|
--json run.status,datasets.name,actions selects fields without flattening.
|
|
36891
37150
|
Selection changes stdout only, not the server query. Optional missing paths
|
|
36892
37151
|
are omitted; array positions are preserved. --json diagnostics needs --full.
|
|
@@ -36898,6 +37157,7 @@ Examples:
|
|
|
36898
37157
|
deepline runs get play/my-play/run/20260501t000000-000 --log-failed --json
|
|
36899
37158
|
deepline runs get play/my-play/run/20260501t000000-000 --full --json
|
|
36900
37159
|
deepline runs get play/my-play/run/20260501t000000-000 --input
|
|
37160
|
+
deepline runs get play/my-play/run/20260501t000000-000 --config --json
|
|
36901
37161
|
`
|
|
36902
37162
|
).option(
|
|
36903
37163
|
"--json [fields]",
|
|
@@ -36908,6 +37168,9 @@ Examples:
|
|
|
36908
37168
|
).option(
|
|
36909
37169
|
"--input",
|
|
36910
37170
|
"Explicitly print the original retained input JSON (may contain customer data)"
|
|
37171
|
+
).option(
|
|
37172
|
+
"--config",
|
|
37173
|
+
"Explicitly print the recorded configuration, without full results"
|
|
36911
37174
|
).option(
|
|
36912
37175
|
"--log-failed",
|
|
36913
37176
|
"Attach a bounded terminal-failure log window for failed runs"
|
|
@@ -36917,6 +37180,7 @@ Examples:
|
|
|
36917
37180
|
...jsonFieldArgs(options.json),
|
|
36918
37181
|
...options.full ? ["--full"] : [],
|
|
36919
37182
|
...options.input ? ["--input"] : [],
|
|
37183
|
+
...options.config ? ["--config"] : [],
|
|
36920
37184
|
...options.logFailed ? ["--log-failed"] : []
|
|
36921
37185
|
]);
|
|
36922
37186
|
});
|
|
@@ -37084,7 +37348,10 @@ Examples:
|
|
|
37084
37348
|
).option(
|
|
37085
37349
|
"--payloads",
|
|
37086
37350
|
"Search with canonical eventPayload or receipt payload; max 10 events, 16 MiB"
|
|
37087
|
-
).option(
|
|
37351
|
+
).option(
|
|
37352
|
+
"--cursor <token>",
|
|
37353
|
+
"Continue paging: older run-log lines (nextCursor) or a bounded event search"
|
|
37354
|
+
).option(
|
|
37088
37355
|
"--runtime-namespace <name>",
|
|
37089
37356
|
"Search an explicitly authorized Preview namespace"
|
|
37090
37357
|
).option("--runtime-backend <backend>", "Preview backend: daytona or modal").action(async (runId, options) => {
|