deepline 0.1.62 → 0.1.64

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 (27) hide show
  1. package/dist/cli/index.js +702 -339
  2. package/dist/cli/index.mjs +727 -348
  3. package/dist/index.d.mts +7 -1
  4. package/dist/index.d.ts +7 -1
  5. package/dist/index.js +77 -51
  6. package/dist/index.mjs +77 -51
  7. package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +9 -10
  8. package/dist/repo/apps/play-runner-workers/src/entry.ts +55 -0
  9. package/dist/repo/apps/play-runner-workers/src/runtime/dataset-handles.ts +36 -27
  10. package/dist/repo/apps/play-runner-workers/src/runtime/tool-http-errors.ts +5 -2
  11. package/dist/repo/sdk/src/client.ts +71 -63
  12. package/dist/repo/sdk/src/errors.ts +5 -1
  13. package/dist/repo/sdk/src/http.ts +25 -17
  14. package/dist/repo/sdk/src/plays/local-file-discovery.ts +93 -24
  15. package/dist/repo/sdk/src/release.ts +2 -2
  16. package/dist/repo/sdk/src/tool-output.ts +40 -20
  17. package/dist/repo/shared_libs/play-runtime/batch-runtime.ts +10 -3
  18. package/dist/repo/shared_libs/play-runtime/batching-types.ts +15 -4
  19. package/dist/repo/shared_libs/play-runtime/coordinator-headers.ts +2 -1
  20. package/dist/repo/shared_libs/play-runtime/dedup-backend.ts +0 -0
  21. package/dist/repo/shared_libs/play-runtime/default-batch-strategies.ts +3 -4
  22. package/dist/repo/shared_libs/play-runtime/run-failure.ts +1 -3
  23. package/dist/repo/shared_libs/play-runtime/step-lifecycle-tracker.ts +4 -1
  24. package/dist/repo/shared_libs/play-runtime/tool-batch-executor.ts +4 -1
  25. package/dist/repo/shared_libs/play-runtime/tool-result.ts +28 -15
  26. package/dist/repo/shared_libs/plays/dataset.ts +10 -11
  27. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -57,7 +57,11 @@ var RateLimitError = class extends DeeplineError {
57
57
  /** Milliseconds to wait before retrying, from the `Retry-After` response header. Defaults to 5000. */
58
58
  retryAfterMs;
59
59
  constructor(retryAfterMs = 5e3, message) {
60
- super(message ?? `Rate limited. Retry after ${retryAfterMs}ms.`, 429, "RATE_LIMIT");
60
+ super(
61
+ message ?? `Rate limited. Retry after ${retryAfterMs}ms.`,
62
+ 429,
63
+ "RATE_LIMIT"
64
+ );
61
65
  this.name = "RateLimitError";
62
66
  this.retryAfterMs = retryAfterMs;
63
67
  }
@@ -220,10 +224,10 @@ function resolveConfig(options) {
220
224
 
221
225
  // src/release.ts
222
226
  var SDK_RELEASE = {
223
- version: "0.1.62",
227
+ version: "0.1.64",
224
228
  apiContract: "2026-05-play-bootstrap-dataset-summary",
225
229
  supportPolicy: {
226
- latest: "0.1.62",
230
+ latest: "0.1.64",
227
231
  minimumSupported: "0.1.53",
228
232
  deprecatedBelow: "0.1.53"
229
233
  }
@@ -246,7 +250,7 @@ var HttpClient = class {
246
250
  config;
247
251
  authHeaders(extra) {
248
252
  const headers = {
249
- "Authorization": `Bearer ${this.config.apiKey}`,
253
+ Authorization: `Bearer ${this.config.apiKey}`,
250
254
  "User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
251
255
  "X-Deepline-SDK-Version": SDK_VERSION,
252
256
  "X-Deepline-API-Contract": SDK_API_CONTRACT,
@@ -929,31 +933,34 @@ var DeeplineClient = class {
929
933
  * artifactStorageKey: 'plays/v1/orgs/acme/plays/my-play/artifacts/playgraph_abc123.json',
930
934
  * });
931
935
  * ```
932
- */
936
+ */
933
937
  async startPlayRun(request) {
934
- const response = await this.http.post("/api/v2/plays/run", {
935
- ...request.name ? { name: request.name } : {},
936
- ...request.revisionId ? { revisionId: request.revisionId } : {},
937
- ...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
938
- ...request.sourceCode ? { sourceCode: request.sourceCode } : {},
939
- ...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
940
- ..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
941
- ...request.artifactHash ? { artifactHash: request.artifactHash } : {},
942
- ...request.graphHash ? { graphHash: request.graphHash } : {},
943
- ...request.runtimeArtifact ? { runtimeArtifact: request.runtimeArtifact } : {},
944
- ...request.compilerManifest ? { compilerManifest: request.compilerManifest } : {},
945
- ...request.inputFileUpload ? { inputFileUpload: request.inputFileUpload } : {},
946
- ...request.packagedFileUploads?.length ? { packagedFileUploads: request.packagedFileUploads } : {},
947
- ...request.input ? { input: request.input } : {},
948
- ...request.inputFile ? { inputFile: request.inputFile } : {},
949
- ...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
950
- ...request.force ? { force: true } : {},
951
- ...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
952
- // Profile selection is the API's job, not the CLI's. The server
953
- // hardcodes workers_edge as the default; tests that want a
954
- // different profile pass `request.profile` explicitly.
955
- ...request.profile ? { profile: request.profile } : {}
956
- });
938
+ const response = await this.http.post(
939
+ "/api/v2/plays/run",
940
+ {
941
+ ...request.name ? { name: request.name } : {},
942
+ ...request.revisionId ? { revisionId: request.revisionId } : {},
943
+ ...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
944
+ ...request.sourceCode ? { sourceCode: request.sourceCode } : {},
945
+ ...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
946
+ ..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
947
+ ...request.artifactHash ? { artifactHash: request.artifactHash } : {},
948
+ ...request.graphHash ? { graphHash: request.graphHash } : {},
949
+ ...request.runtimeArtifact ? { runtimeArtifact: request.runtimeArtifact } : {},
950
+ ...request.compilerManifest ? { compilerManifest: request.compilerManifest } : {},
951
+ ...request.inputFileUpload ? { inputFileUpload: request.inputFileUpload } : {},
952
+ ...request.packagedFileUploads?.length ? { packagedFileUploads: request.packagedFileUploads } : {},
953
+ ...request.input ? { input: request.input } : {},
954
+ ...request.inputFile ? { inputFile: request.inputFile } : {},
955
+ ...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
956
+ ...request.force ? { force: true } : {},
957
+ ...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
958
+ // Profile selection is the API's job, not the CLI's. The server
959
+ // hardcodes workers_edge as the default; tests that want a
960
+ // different profile pass `request.profile` explicitly.
961
+ ...request.profile ? { profile: request.profile } : {}
962
+ }
963
+ );
957
964
  return normalizePlayRunStart(response);
958
965
  }
959
966
  async *startPlayRunStream(request, options) {
@@ -1205,10 +1212,7 @@ var DeeplineClient = class {
1205
1212
  }
1206
1213
  return formData;
1207
1214
  };
1208
- const response = await this.http.postFormData(
1209
- "/api/v2/plays/files/stage",
1210
- buildFormData
1211
- );
1215
+ const response = await this.http.postFormData("/api/v2/plays/files/stage", buildFormData);
1212
1216
  return response.files;
1213
1217
  }
1214
1218
  async resolveStagedPlayFiles(files) {
@@ -1655,7 +1659,9 @@ var DeeplineClient = class {
1655
1659
  }
1656
1660
  options?.onProgress?.(status);
1657
1661
  if (TERMINAL_PLAY_STATUSES.has(status.status)) {
1658
- const finalStatus = await this.getPlayStatus(status.runId || workflowId).catch(() => status);
1662
+ const finalStatus = await this.getPlayStatus(
1663
+ status.runId || workflowId
1664
+ ).catch(() => status);
1659
1665
  return playRunResultFromStatus(finalStatus, start, workflowId);
1660
1666
  }
1661
1667
  }
@@ -1946,11 +1952,9 @@ function openUrlMacos(targetUrl, allowFocus, runner = defaultBrowserCommandRunne
1946
1952
  return true;
1947
1953
  }
1948
1954
  try {
1949
- runner.execFileSync(
1950
- "open",
1951
- [...allowFocus ? [] : ["-g"], targetUrl],
1952
- { stdio: "ignore" }
1953
- );
1955
+ runner.execFileSync("open", [...allowFocus ? [] : ["-g"], targetUrl], {
1956
+ stdio: "ignore"
1957
+ });
1954
1958
  return true;
1955
1959
  } catch {
1956
1960
  return false;
@@ -2144,7 +2148,10 @@ function createTimestampedName(prefix, extension) {
2144
2148
  return `${prefix}-${timestamp}.${extension}`;
2145
2149
  }
2146
2150
  async function writeCsvRowsFile(prefix, rows) {
2147
- const path = await writeOutputFile(createTimestampedName(prefix, "csv"), csvStringFromRows(rows));
2151
+ const path = await writeOutputFile(
2152
+ createTimestampedName(prefix, "csv"),
2153
+ csvStringFromRows(rows)
2154
+ );
2148
2155
  return path;
2149
2156
  }
2150
2157
  function clip(value, maxLength) {
@@ -2225,7 +2232,9 @@ function saveEnvValues(values, baseUrl) {
2225
2232
  saveHostEnvValues(baseUrl, filtered);
2226
2233
  }
2227
2234
  async function httpJson(method, url, apiKey, body) {
2228
- const headers = { "Content-Type": "application/json" };
2235
+ const headers = {
2236
+ "Content-Type": "application/json"
2237
+ };
2229
2238
  if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
2230
2239
  let response = null;
2231
2240
  let lastError = null;
@@ -2280,12 +2289,24 @@ function sleep3(ms) {
2280
2289
  }
2281
2290
  function printDeeplineLogo() {
2282
2291
  if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
2283
- console.log(" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557");
2284
- console.log(" \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D");
2285
- console.log(" \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557");
2286
- console.log(" \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D");
2287
- console.log(" \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557");
2288
- console.log(" \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
2292
+ console.log(
2293
+ " \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"
2294
+ );
2295
+ console.log(
2296
+ " \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D"
2297
+ );
2298
+ console.log(
2299
+ " \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557"
2300
+ );
2301
+ console.log(
2302
+ " \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D"
2303
+ );
2304
+ console.log(
2305
+ " \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"
2306
+ );
2307
+ console.log(
2308
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
2309
+ );
2289
2310
  console.log("");
2290
2311
  return;
2291
2312
  }
@@ -2319,7 +2340,12 @@ async function handleRegister(args) {
2319
2340
  const payload = {};
2320
2341
  if (orgName) payload.org_name = orgName;
2321
2342
  if (agentName) payload.agent_name = agentName;
2322
- const { status, data } = await httpJson("POST", `${baseUrl}/api/v2/auth/cli/register`, null, payload);
2343
+ const { status, data } = await httpJson(
2344
+ "POST",
2345
+ `${baseUrl}/api/v2/auth/cli/register`,
2346
+ null,
2347
+ payload
2348
+ );
2323
2349
  if (status >= 400) {
2324
2350
  console.error(`Auth register failed (status ${status}).`);
2325
2351
  if (data.error) console.error(String(data.error));
@@ -2329,9 +2355,12 @@ async function handleRegister(args) {
2329
2355
  const claimToken = String(data.claim_token || "");
2330
2356
  if (claimToken) {
2331
2357
  savePendingClaimToken(baseUrl, claimToken);
2332
- saveEnvValues({
2333
- [HOST_URL_ENV]: baseUrl
2334
- }, baseUrl);
2358
+ saveEnvValues(
2359
+ {
2360
+ [HOST_URL_ENV]: baseUrl
2361
+ },
2362
+ baseUrl
2363
+ );
2335
2364
  }
2336
2365
  if (claimUrl) {
2337
2366
  console.log(" Opening approval page in your browser.");
@@ -2370,10 +2399,13 @@ async function handleRegister(args) {
2370
2399
  if (state === "claimed") {
2371
2400
  const apiKey = String(statusData.api_key || "");
2372
2401
  if (apiKey) {
2373
- saveEnvValues({
2374
- [HOST_URL_ENV]: baseUrl,
2375
- [API_KEY_ENV]: apiKey
2376
- }, baseUrl);
2402
+ saveEnvValues(
2403
+ {
2404
+ [HOST_URL_ENV]: baseUrl,
2405
+ [API_KEY_ENV]: apiKey
2406
+ },
2407
+ baseUrl
2408
+ );
2377
2409
  clearPendingClaimToken(baseUrl);
2378
2410
  printClaimSuccessBanner(statusData);
2379
2411
  return EXIT_OK;
@@ -2381,7 +2413,9 @@ async function handleRegister(args) {
2381
2413
  }
2382
2414
  if (state === "expired") {
2383
2415
  clearPendingClaimToken(baseUrl);
2384
- console.log("That approval link expired. Please run: deepline auth register");
2416
+ console.log(
2417
+ "That approval link expired. Please run: deepline auth register"
2418
+ );
2385
2419
  return EXIT_AUTH;
2386
2420
  }
2387
2421
  await sleep3(2e3);
@@ -2432,10 +2466,13 @@ async function handleWait(args) {
2432
2466
  if (state === "claimed") {
2433
2467
  const apiKey = String(data.api_key || "");
2434
2468
  if (apiKey) {
2435
- saveEnvValues({
2436
- [HOST_URL_ENV]: baseUrl,
2437
- [API_KEY_ENV]: apiKey
2438
- }, baseUrl);
2469
+ saveEnvValues(
2470
+ {
2471
+ [HOST_URL_ENV]: baseUrl,
2472
+ [API_KEY_ENV]: apiKey
2473
+ },
2474
+ baseUrl
2475
+ );
2439
2476
  clearPendingClaimToken(baseUrl);
2440
2477
  printClaimSuccessBanner(data);
2441
2478
  return EXIT_OK;
@@ -2448,7 +2485,9 @@ async function handleWait(args) {
2448
2485
  }
2449
2486
  await sleep3(2e3);
2450
2487
  }
2451
- console.error("Still pending. Approve the browser link, then run: deepline auth wait");
2488
+ console.error(
2489
+ "Still pending. Approve the browser link, then run: deepline auth wait"
2490
+ );
2452
2491
  return EXIT_AUTH;
2453
2492
  }
2454
2493
  async function handleStatus(args) {
@@ -2458,7 +2497,11 @@ async function handleStatus(args) {
2458
2497
  let hostStatusPayload = null;
2459
2498
  const hostLines = [];
2460
2499
  try {
2461
- const { status: hStatus, data: hData } = await httpJson("GET", `${baseUrl}/api/v2/health`, null);
2500
+ const { status: hStatus, data: hData } = await httpJson(
2501
+ "GET",
2502
+ `${baseUrl}/api/v2/health`,
2503
+ null
2504
+ );
2462
2505
  if (hStatus === 200) {
2463
2506
  hostStatusPayload = {
2464
2507
  host: baseUrl,
@@ -2480,45 +2523,74 @@ async function handleStatus(args) {
2480
2523
  const apiKey = resolveApiKeyForBaseUrl(baseUrl);
2481
2524
  if (!apiKey) {
2482
2525
  if (readPendingClaimToken(baseUrl)) {
2483
- printCommandEnvelope({
2526
+ printCommandEnvelope(
2527
+ {
2528
+ ...hostStatusPayload ?? { host: baseUrl },
2529
+ status: "pending",
2530
+ connected: false,
2531
+ next: "deepline auth wait",
2532
+ render: {
2533
+ sections: [
2534
+ {
2535
+ title: "auth status",
2536
+ lines: [...hostLines, "Status: pending"]
2537
+ }
2538
+ ],
2539
+ actions: [{ label: "Run", command: "deepline auth wait" }]
2540
+ }
2541
+ },
2542
+ { json: jsonOutput }
2543
+ );
2544
+ return EXIT_OK;
2545
+ }
2546
+ printCommandEnvelope(
2547
+ {
2484
2548
  ...hostStatusPayload ?? { host: baseUrl },
2485
- status: "pending",
2549
+ status: "not connected",
2486
2550
  connected: false,
2487
- next: "deepline auth wait",
2551
+ next: "deepline auth register",
2488
2552
  render: {
2489
- sections: [{ title: "auth status", lines: [...hostLines, "Status: pending"] }],
2490
- actions: [{ label: "Run", command: "deepline auth wait" }]
2553
+ sections: [
2554
+ {
2555
+ title: "auth status",
2556
+ lines: [...hostLines, "Status: not connected"]
2557
+ }
2558
+ ],
2559
+ actions: [{ label: "Run", command: "deepline auth register" }]
2491
2560
  }
2492
- }, { json: jsonOutput });
2493
- return EXIT_OK;
2494
- }
2495
- printCommandEnvelope({
2496
- ...hostStatusPayload ?? { host: baseUrl },
2497
- status: "not connected",
2498
- connected: false,
2499
- next: "deepline auth register",
2500
- render: {
2501
- sections: [{ title: "auth status", lines: [...hostLines, "Status: not connected"] }],
2502
- actions: [{ label: "Run", command: "deepline auth register" }]
2503
- }
2504
- }, { json: jsonOutput });
2561
+ },
2562
+ { json: jsonOutput }
2563
+ );
2505
2564
  return EXIT_OK;
2506
2565
  }
2507
- const { status, data } = await httpJson("POST", `${baseUrl}/api/v2/auth/cli/status`, apiKey, {
2508
- api_key: apiKey,
2509
- reveal
2510
- });
2566
+ const { status, data } = await httpJson(
2567
+ "POST",
2568
+ `${baseUrl}/api/v2/auth/cli/status`,
2569
+ apiKey,
2570
+ {
2571
+ api_key: apiKey,
2572
+ reveal
2573
+ }
2574
+ );
2511
2575
  if (status === 401 || status === 403) {
2512
- printCommandEnvelope({
2513
- ...hostStatusPayload ?? { host: baseUrl },
2514
- status: "unauthorized",
2515
- connected: false,
2516
- next: "deepline auth register",
2517
- render: {
2518
- sections: [{ title: "auth status", lines: [...hostLines, "Status: unauthorized"] }],
2519
- actions: [{ label: "Run", command: "deepline auth register" }]
2520
- }
2521
- }, { json: jsonOutput });
2576
+ printCommandEnvelope(
2577
+ {
2578
+ ...hostStatusPayload ?? { host: baseUrl },
2579
+ status: "unauthorized",
2580
+ connected: false,
2581
+ next: "deepline auth register",
2582
+ render: {
2583
+ sections: [
2584
+ {
2585
+ title: "auth status",
2586
+ lines: [...hostLines, "Status: unauthorized"]
2587
+ }
2588
+ ],
2589
+ actions: [{ label: "Run", command: "deepline auth register" }]
2590
+ }
2591
+ },
2592
+ { json: jsonOutput }
2593
+ );
2522
2594
  return EXIT_AUTH;
2523
2595
  }
2524
2596
  if (status >= 400) {
@@ -2545,35 +2617,44 @@ async function handleStatus(args) {
2545
2617
  if (reveal) {
2546
2618
  const apiKeyResp = String(data.api_key || apiKey);
2547
2619
  if (apiKeyResp) {
2548
- saveEnvValues({
2549
- [HOST_URL_ENV]: baseUrl,
2550
- [API_KEY_ENV]: apiKeyResp
2551
- }, baseUrl);
2620
+ saveEnvValues(
2621
+ {
2622
+ [HOST_URL_ENV]: baseUrl,
2623
+ [API_KEY_ENV]: apiKeyResp
2624
+ },
2625
+ baseUrl
2626
+ );
2552
2627
  savedApiKeyPath = envFilePath(baseUrl);
2553
2628
  }
2554
2629
  }
2555
- printCommandEnvelope({
2556
- ...payload,
2557
- ...savedApiKeyPath ? { saved_api_key_path: savedApiKeyPath } : {},
2558
- render: {
2559
- sections: [
2560
- {
2561
- title: "auth status",
2562
- lines: [
2563
- ...hostLines,
2564
- `Status: ${payload.status}`,
2565
- `Rate limit tier: ${payload.rateLimitTier}`,
2566
- ...payload.workspace.name ? [`Workspace: ${payload.workspace.name}`] : [],
2567
- ...payload.workspace.slug ? [`Workspace slug: ${payload.workspace.slug}`] : [],
2568
- ...payload.workspace.id != null ? [`Org ID: ${payload.workspace.id}`] : [],
2569
- ...payload.user.id != null ? [`User ID: ${payload.user.id}`] : [],
2570
- ...payload.examples.length > 0 ? ["Examples:", ...payload.examples.slice(0, 3).map((example) => ` ${String(example)}`)] : [],
2571
- ...savedApiKeyPath ? [`Saved API key to ${savedApiKeyPath}`] : []
2572
- ]
2573
- }
2574
- ]
2575
- }
2576
- }, { json: jsonOutput });
2630
+ printCommandEnvelope(
2631
+ {
2632
+ ...payload,
2633
+ ...savedApiKeyPath ? { saved_api_key_path: savedApiKeyPath } : {},
2634
+ render: {
2635
+ sections: [
2636
+ {
2637
+ title: "auth status",
2638
+ lines: [
2639
+ ...hostLines,
2640
+ `Status: ${payload.status}`,
2641
+ `Rate limit tier: ${payload.rateLimitTier}`,
2642
+ ...payload.workspace.name ? [`Workspace: ${payload.workspace.name}`] : [],
2643
+ ...payload.workspace.slug ? [`Workspace slug: ${payload.workspace.slug}`] : [],
2644
+ ...payload.workspace.id != null ? [`Org ID: ${payload.workspace.id}`] : [],
2645
+ ...payload.user.id != null ? [`User ID: ${payload.user.id}`] : [],
2646
+ ...payload.examples.length > 0 ? [
2647
+ "Examples:",
2648
+ ...payload.examples.slice(0, 3).map((example) => ` ${String(example)}`)
2649
+ ] : [],
2650
+ ...savedApiKeyPath ? [`Saved API key to ${savedApiKeyPath}`] : []
2651
+ ]
2652
+ }
2653
+ ]
2654
+ }
2655
+ },
2656
+ { json: jsonOutput }
2657
+ );
2577
2658
  return EXIT_OK;
2578
2659
  }
2579
2660
  function registerAuthCommands(program) {
@@ -2593,7 +2674,9 @@ Notes:
2593
2674
  Auth status shows the target host and active workspace without printing secrets.
2594
2675
  `
2595
2676
  );
2596
- auth.command("register").description("Register this device and open the approval page in your browser.").addHelpText(
2677
+ auth.command("register").description(
2678
+ "Register this device and open the approval page in your browser."
2679
+ ).addHelpText(
2597
2680
  "after",
2598
2681
  `
2599
2682
  Notes:
@@ -2640,7 +2723,10 @@ Examples:
2640
2723
  deepline auth status
2641
2724
  deepline auth status --json
2642
2725
  `
2643
- ).option("--reveal", "Persist the revealed API key back to the host auth file").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
2726
+ ).option(
2727
+ "--reveal",
2728
+ "Persist the revealed API key back to the host auth file"
2729
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
2644
2730
  process.exitCode = await handleStatus([
2645
2731
  ...options.reveal ? ["--reveal"] : [],
2646
2732
  ...options.json ? ["--json"] : []
@@ -2665,7 +2751,9 @@ function recentUsageLines(entries) {
2665
2751
  const op = `${humanize(entry.provider)} ${humanize(entry.operation)}`.trim();
2666
2752
  const charge = entry.billing_mode === "no_bill" ? "free" : `${entry.credits ?? 0} cr`;
2667
2753
  const status = entry.status || "completed";
2668
- lines.push(`${op} | ${charge} | ${status} | ${entry.created_at || "unknown"}`);
2754
+ lines.push(
2755
+ `${op} | ${charge} | ${status} | ${entry.created_at || "unknown"}`
2756
+ );
2669
2757
  }
2670
2758
  return lines;
2671
2759
  }
@@ -2719,16 +2807,21 @@ function defaultLedgerExportPath() {
2719
2807
  }
2720
2808
  async function handleBalance(options) {
2721
2809
  const { http } = getAuthedHttpClient();
2722
- const payload = await http.get("/api/v2/billing/balance");
2810
+ const payload = await http.get(
2811
+ "/api/v2/billing/balance"
2812
+ );
2723
2813
  const status = String(payload.balance_status || "");
2724
2814
  const lines = status === "no_billing" ? [
2725
2815
  "Balance: 0 credits",
2726
2816
  "Billing: No billing account or payment method set up for this workspace."
2727
2817
  ] : [`Balance: ${payload.balance ?? "(unknown)"} credits`];
2728
- printCommandEnvelope({
2729
- ...payload,
2730
- render: { sections: [{ title: "billing balance", lines }] }
2731
- }, { json: options.json });
2818
+ printCommandEnvelope(
2819
+ {
2820
+ ...payload,
2821
+ render: { sections: [{ title: "billing balance", lines }] }
2822
+ },
2823
+ { json: options.json }
2824
+ );
2732
2825
  return;
2733
2826
  }
2734
2827
  async function handleUsage(options) {
@@ -2737,7 +2830,9 @@ async function handleUsage(options) {
2737
2830
  if (options.limit) params.set("recent_limit", options.limit);
2738
2831
  if (options.offset) params.set("recent_offset", options.offset);
2739
2832
  const suffix = Array.from(params).length > 0 ? `?${params.toString()}` : "";
2740
- const payload = await http.get(`/api/v2/billing/usage${suffix}`);
2833
+ const payload = await http.get(
2834
+ `/api/v2/billing/usage${suffix}`
2835
+ );
2741
2836
  const usage = payload.usage ?? {};
2742
2837
  const quota = payload.quota ?? {};
2743
2838
  const recent = payload.recent ?? {};
@@ -2745,24 +2840,34 @@ async function handleUsage(options) {
2745
2840
  `Balance: ${payload.balance ?? "(unknown)"}`,
2746
2841
  `Last 30 days spent: ${usage.month_spent_credits ?? "(unknown)"}`,
2747
2842
  `Monthly limit: ${quota.enabled ? quota.monthly_credits_limit ?? "(unknown)" : "off"}`,
2748
- ...recentUsageLines(Array.isArray(recent.entries) ? recent.entries : [])
2843
+ ...recentUsageLines(
2844
+ Array.isArray(recent.entries) ? recent.entries : []
2845
+ )
2749
2846
  ];
2750
- printCommandEnvelope({
2751
- ...payload,
2752
- render: { sections: [{ title: "billing usage", lines }] }
2753
- }, { json: options.json });
2847
+ printCommandEnvelope(
2848
+ {
2849
+ ...payload,
2850
+ render: { sections: [{ title: "billing usage", lines }] }
2851
+ },
2852
+ { json: options.json }
2853
+ );
2754
2854
  }
2755
2855
  async function handleLimit(options) {
2756
2856
  const { http } = getAuthedHttpClient();
2757
- const payload = await http.get("/api/v2/billing/limit");
2857
+ const payload = await http.get(
2858
+ "/api/v2/billing/limit"
2859
+ );
2758
2860
  const lines = payload.enabled ? [
2759
2861
  `Monthly limit: ${payload.monthly_credits_limit ?? "(unknown)"}`,
2760
2862
  `Remaining before cap: ${payload.remaining_credits ?? "(unknown)"}`
2761
2863
  ] : ["Monthly limit: off"];
2762
- printCommandEnvelope({
2763
- ...payload,
2764
- render: { sections: [{ title: "billing limit", lines }] }
2765
- }, { json: options.json });
2864
+ printCommandEnvelope(
2865
+ {
2866
+ ...payload,
2867
+ render: { sections: [{ title: "billing limit", lines }] }
2868
+ },
2869
+ { json: options.json }
2870
+ );
2766
2871
  }
2767
2872
  async function handleSetLimit(credits, options) {
2768
2873
  const { http } = getAuthedHttpClient();
@@ -2770,26 +2875,53 @@ async function handleSetLimit(credits, options) {
2770
2875
  method: "PUT",
2771
2876
  body: { monthly_credits_limit: Number.parseInt(credits, 10) }
2772
2877
  });
2773
- printCommandEnvelope({
2774
- ...payload,
2775
- render: {
2776
- sections: [{ title: "billing limit", lines: [`Monthly billing limit set to ${credits} credits.`] }]
2777
- }
2778
- }, { json: options.json });
2878
+ printCommandEnvelope(
2879
+ {
2880
+ ...payload,
2881
+ render: {
2882
+ sections: [
2883
+ {
2884
+ title: "billing limit",
2885
+ lines: [`Monthly billing limit set to ${credits} credits.`]
2886
+ }
2887
+ ]
2888
+ }
2889
+ },
2890
+ { json: options.json }
2891
+ );
2779
2892
  }
2780
2893
  async function handleLimitOff(options) {
2781
2894
  const { http } = getAuthedHttpClient();
2782
- const payload = await http.request("/api/v2/billing/limit", { method: "DELETE" });
2783
- printCommandEnvelope({
2784
- ...payload,
2785
- render: { sections: [{ title: "billing limit", lines: ["Monthly billing limit is now off."] }] }
2786
- }, { json: options.json });
2895
+ const payload = await http.request("/api/v2/billing/limit", {
2896
+ method: "DELETE"
2897
+ });
2898
+ printCommandEnvelope(
2899
+ {
2900
+ ...payload,
2901
+ render: {
2902
+ sections: [
2903
+ {
2904
+ title: "billing limit",
2905
+ lines: ["Monthly billing limit is now off."]
2906
+ }
2907
+ ]
2908
+ }
2909
+ },
2910
+ { json: options.json }
2911
+ );
2787
2912
  }
2788
2913
  async function handleHistory(options) {
2789
2914
  const { http } = getAuthedHttpClient();
2790
- const windows = { "1d": 86400, "1w": 604800, "1m": 2592e3, "1y": 31536e3 };
2915
+ const windows = {
2916
+ "1d": 86400,
2917
+ "1w": 604800,
2918
+ "1m": 2592e3,
2919
+ "1y": 31536e3
2920
+ };
2791
2921
  const sinceAt = Math.max(0, Math.floor(Date.now() / 1e3) - windows[options.time]) * 1e3;
2792
- const payload = await http.get(`/api/v2/billing/ledger?since_at=${sinceAt}&limit=5000`);
2922
+ const payload = await http.get(
2923
+ `/api/v2/billing/ledger?since_at=${sinceAt}&limit=5000`
2924
+ );
2793
2925
  const entries = Array.isArray(payload.entries) ? payload.entries : [];
2794
2926
  const rows = entries.map((entry) => {
2795
2927
  const metadata = entry.metadata ?? {};
@@ -2801,21 +2933,30 @@ async function handleHistory(options) {
2801
2933
  operation: metadata.operation ?? ""
2802
2934
  };
2803
2935
  });
2804
- const outputPath = await writeCsvRowsFile(`billing-history-${options.time}`, rows);
2805
- printCommandEnvelope({
2806
- output_path: outputPath,
2807
- row_count: rows.length,
2808
- time_window: options.time,
2809
- render: {
2810
- sections: [
2811
- {
2812
- title: "billing history",
2813
- lines: [`Billing history written to ${outputPath}`, `${rows.length} row(s) exported.`]
2814
- }
2815
- ]
2936
+ const outputPath = await writeCsvRowsFile(
2937
+ `billing-history-${options.time}`,
2938
+ rows
2939
+ );
2940
+ printCommandEnvelope(
2941
+ {
2942
+ output_path: outputPath,
2943
+ row_count: rows.length,
2944
+ time_window: options.time,
2945
+ render: {
2946
+ sections: [
2947
+ {
2948
+ title: "billing history",
2949
+ lines: [
2950
+ `Billing history written to ${outputPath}`,
2951
+ `${rows.length} row(s) exported.`
2952
+ ]
2953
+ }
2954
+ ]
2955
+ },
2956
+ local: { output_path: outputPath }
2816
2957
  },
2817
- local: { output_path: outputPath }
2818
- }, { json: options.json });
2958
+ { json: options.json }
2959
+ );
2819
2960
  }
2820
2961
  async function handleLedgerExportAll(options) {
2821
2962
  const { http } = getAuthedHttpClient();
@@ -2847,51 +2988,75 @@ async function handleLedgerExportAll(options) {
2847
2988
  if (nextCursor === cursor) break;
2848
2989
  cursor = nextCursor;
2849
2990
  }
2850
- printCommandEnvelope({
2851
- output_path: outputPath,
2852
- row_count: summary.row_count,
2853
- net_delta_credits: summary.net_delta_credits,
2854
- scope: "current_auth_context",
2855
- render: {
2856
- sections: [
2857
- {
2858
- title: "billing ledger",
2859
- lines: [
2860
- `Billing ledger written to ${outputPath}`,
2861
- `${summary.row_count} row(s) exported for the current auth context.`,
2862
- `Net ledger delta: ${summary.net_delta_credits} Deepline Credits`
2863
- ]
2864
- }
2865
- ]
2991
+ printCommandEnvelope(
2992
+ {
2993
+ output_path: outputPath,
2994
+ row_count: summary.row_count,
2995
+ net_delta_credits: summary.net_delta_credits,
2996
+ scope: "current_auth_context",
2997
+ render: {
2998
+ sections: [
2999
+ {
3000
+ title: "billing ledger",
3001
+ lines: [
3002
+ `Billing ledger written to ${outputPath}`,
3003
+ `${summary.row_count} row(s) exported for the current auth context.`,
3004
+ `Net ledger delta: ${summary.net_delta_credits} Deepline Credits`
3005
+ ]
3006
+ }
3007
+ ]
3008
+ },
3009
+ local: { output_path: outputPath }
2866
3010
  },
2867
- local: { output_path: outputPath }
2868
- }, { json: options.json });
3011
+ { json: options.json }
3012
+ );
2869
3013
  }
2870
3014
  async function handleCheckout(options) {
2871
3015
  const { http } = getAuthedHttpClient();
2872
- const payload = await http.post("/api/v2/billing/checkout", {
2873
- ...options.tier ? { tierId: options.tier } : {},
2874
- ...options.credits ? { credits: Number.parseInt(options.credits, 10) } : {},
2875
- ...options.discountCode ? { discountCode: options.discountCode } : {}
2876
- });
3016
+ const payload = await http.post(
3017
+ "/api/v2/billing/checkout",
3018
+ {
3019
+ ...options.tier ? { tierId: options.tier } : {},
3020
+ ...options.credits ? { credits: Number.parseInt(options.credits, 10) } : {},
3021
+ ...options.discountCode ? { discountCode: options.discountCode } : {}
3022
+ }
3023
+ );
2877
3024
  const url = String(payload.url || payload.checkout_url || "");
2878
3025
  if (!options.json && !options.noOpen && url) openInBrowser(url);
2879
- printCommandEnvelope({
2880
- ...payload,
2881
- render: { sections: [{ title: "billing checkout", lines: [url || "Checkout session created."] }] }
2882
- }, { json: options.json });
3026
+ printCommandEnvelope(
3027
+ {
3028
+ ...payload,
3029
+ render: {
3030
+ sections: [
3031
+ {
3032
+ title: "billing checkout",
3033
+ lines: [url || "Checkout session created."]
3034
+ }
3035
+ ]
3036
+ }
3037
+ },
3038
+ { json: options.json }
3039
+ );
2883
3040
  }
2884
3041
  async function handleRedeemCode(code, options) {
2885
3042
  const { http } = getAuthedHttpClient();
2886
- const payload = await http.post("/api/v2/billing/checkout", {
2887
- discountCode: code
2888
- });
3043
+ const payload = await http.post(
3044
+ "/api/v2/billing/checkout",
3045
+ {
3046
+ discountCode: code
3047
+ }
3048
+ );
2889
3049
  const url = String(payload.url || payload.checkout_url || "");
2890
3050
  if (!options.json && !options.noOpen && url) openInBrowser(url);
2891
- printCommandEnvelope({
2892
- ...payload,
2893
- render: { sections: [{ title: "billing code", lines: [url || "Code redeemed."] }] }
2894
- }, { json: options.json });
3051
+ printCommandEnvelope(
3052
+ {
3053
+ ...payload,
3054
+ render: {
3055
+ sections: [{ title: "billing code", lines: [url || "Code redeemed."] }]
3056
+ }
3057
+ },
3058
+ { json: options.json }
3059
+ );
2895
3060
  }
2896
3061
  function registerBillingCommands(program) {
2897
3062
  const billing = program.command("billing").description("Inspect balance, usage, limits, and checkout flows.").addHelpText(
@@ -2999,7 +3164,10 @@ Examples:
2999
3164
  deepline billing ledger export all
3000
3165
  deepline billing ledger export all --json
3001
3166
  `
3002
- ).option("--output <path>", "Write CSV to an explicit path").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLedgerExportAll)
3167
+ ).option("--output <path>", "Write CSV to an explicit path").option(
3168
+ "--json",
3169
+ "Emit JSON output. Also automatic when stdout is piped"
3170
+ ).action(handleLedgerExportAll)
3003
3171
  )
3004
3172
  );
3005
3173
  billing.command("history").description("Export billing ledger history to CSV.").addHelpText(
@@ -3014,7 +3182,9 @@ Examples:
3014
3182
  deepline billing history --time 1y --json
3015
3183
  `
3016
3184
  ).requiredOption("--time <window>", "Rolling time window: 1d, 1w, 1m, or 1y").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleHistory);
3017
- billing.command("checkout").description("Create a checkout session and optionally open it in your browser.").addHelpText(
3185
+ billing.command("checkout").description(
3186
+ "Create a checkout session and optionally open it in your browser."
3187
+ ).addHelpText(
3018
3188
  "after",
3019
3189
  `
3020
3190
  Notes:
@@ -3060,12 +3230,18 @@ function formatDatasetExecutionStats(raw, denominator) {
3060
3230
  readCount(raw.completed),
3061
3231
  denominator
3062
3232
  ),
3063
- "completed:reused": datasetSummaryPercentText(readCount(raw.cached), denominator),
3233
+ "completed:reused": datasetSummaryPercentText(
3234
+ readCount(raw.cached),
3235
+ denominator
3236
+ ),
3064
3237
  "skipped:condition": datasetSummaryPercentText(
3065
3238
  readCount(raw.skipped),
3066
3239
  denominator
3067
3240
  ),
3068
- "skipped:missed": datasetSummaryPercentText(readCount(raw.missed), denominator),
3241
+ "skipped:missed": datasetSummaryPercentText(
3242
+ readCount(raw.missed),
3243
+ denominator
3244
+ ),
3069
3245
  failed: datasetSummaryPercentText(readCount(raw.failed), denominator)
3070
3246
  };
3071
3247
  }
@@ -3246,19 +3422,51 @@ function collectCanonicalRowsInfos(statusOrResult) {
3246
3422
  const metadata = isRecord2(result._metadata) ? result._metadata : null;
3247
3423
  const totalFromMetadata = metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count;
3248
3424
  const candidates = [
3249
- { source: "result.contacts", value: result.contacts, total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count },
3250
- { source: "result.previewRows", value: result.previewRows, total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count },
3251
- { source: "result.rows", value: result.rows, total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count },
3252
- { source: "result.results", value: result.results, total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count }
3425
+ {
3426
+ source: "result.contacts",
3427
+ value: result.contacts,
3428
+ total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
3429
+ },
3430
+ {
3431
+ source: "result.previewRows",
3432
+ value: result.previewRows,
3433
+ total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
3434
+ },
3435
+ {
3436
+ source: "result.rows",
3437
+ value: result.rows,
3438
+ total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
3439
+ },
3440
+ {
3441
+ source: "result.results",
3442
+ value: result.results,
3443
+ total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
3444
+ }
3253
3445
  ];
3254
3446
  if (isRecord2(result.output)) {
3255
3447
  const outputMetadata = isRecord2(result.output._metadata) ? result.output._metadata : null;
3256
3448
  const outputTotalFromMetadata = outputMetadata?.totalRows ?? outputMetadata?.rowCount ?? outputMetadata?.count;
3257
3449
  candidates.push(
3258
- { source: "result.output.contacts", value: result.output.contacts, total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count },
3259
- { source: "result.output.previewRows", value: result.output.previewRows, total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count },
3260
- { source: "result.output.rows", value: result.output.rows, total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count },
3261
- { source: "result.output.results", value: result.output.results, total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count }
3450
+ {
3451
+ source: "result.output.contacts",
3452
+ value: result.output.contacts,
3453
+ total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count
3454
+ },
3455
+ {
3456
+ source: "result.output.previewRows",
3457
+ value: result.output.previewRows,
3458
+ total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count
3459
+ },
3460
+ {
3461
+ source: "result.output.rows",
3462
+ value: result.output.rows,
3463
+ total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count
3464
+ },
3465
+ {
3466
+ source: "result.output.results",
3467
+ value: result.output.results,
3468
+ total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count
3469
+ }
3262
3470
  );
3263
3471
  }
3264
3472
  collectDatasetCandidates({
@@ -3396,7 +3604,8 @@ function compactCell(value) {
3396
3604
  const parsed = parseJsonLike(value);
3397
3605
  if (parsed === null || parsed === void 0) return "";
3398
3606
  if (typeof parsed === "string") return compactScalar(parsed, 120);
3399
- if (typeof parsed === "number" || typeof parsed === "boolean") return String(parsed);
3607
+ if (typeof parsed === "number" || typeof parsed === "boolean")
3608
+ return String(parsed);
3400
3609
  if (Array.isArray(parsed)) {
3401
3610
  if (parsed.length === 0) return "";
3402
3611
  if (parsed.slice(0, 3).every((item) => ["string", "number", "boolean"].includes(typeof item))) {
@@ -3410,7 +3619,15 @@ function compactCell(value) {
3410
3619
  return compactCell(parsed[key]);
3411
3620
  }
3412
3621
  }
3413
- const preferred = ["email", "status", "name", "full_name", "title", "domain", "linkedin_url"];
3622
+ const preferred = [
3623
+ "email",
3624
+ "status",
3625
+ "name",
3626
+ "full_name",
3627
+ "title",
3628
+ "domain",
3629
+ "linkedin_url"
3630
+ ];
3414
3631
  const parts = [];
3415
3632
  for (const key of preferred) {
3416
3633
  if (parsed[key] !== null && parsed[key] !== void 0 && parsed[key] !== "") {
@@ -3452,7 +3669,10 @@ function buildDatasetStats(rows, totalRows = rows.length, columns = inferColumns
3452
3669
  };
3453
3670
  const rawExecutionStats = executionStats?.columnStats[column];
3454
3671
  if (rawExecutionStats) {
3455
- stat3.execution = formatDatasetExecutionStats(rawExecutionStats, totalRows);
3672
+ stat3.execution = formatDatasetExecutionStats(
3673
+ rawExecutionStats,
3674
+ totalRows
3675
+ );
3456
3676
  }
3457
3677
  if (sampleValue !== void 0 && sampleValueType) {
3458
3678
  stat3.sample_value = sampleValue;
@@ -3494,11 +3714,7 @@ function writeCanonicalRowsCsv(rowsInfo, outPath) {
3494
3714
  const rows = dataExportRows(sanitized.rows);
3495
3715
  const columns = dataExportColumns(rows, sanitized.columns);
3496
3716
  const resolved = (0, import_node_path5.resolve)(outPath);
3497
- (0, import_node_fs4.writeFileSync)(
3498
- resolved,
3499
- csvStringFromRows(rows, columns),
3500
- "utf-8"
3501
- );
3717
+ (0, import_node_fs4.writeFileSync)(resolved, csvStringFromRows(rows, columns), "utf-8");
3502
3718
  return resolved;
3503
3719
  }
3504
3720
 
@@ -3509,7 +3725,9 @@ function parseRowRange(raw) {
3509
3725
  const start = Number.parseInt(startRaw ?? "", 10);
3510
3726
  const end = Number.parseInt(endRaw ?? "", 10);
3511
3727
  if (!Number.isFinite(start) || !Number.isFinite(end) || start < 0 || end < start) {
3512
- throw new Error(`Invalid --rows value: ${source} (expected start:end, e.g. 0:19).`);
3728
+ throw new Error(
3729
+ `Invalid --rows value: ${source} (expected start:end, e.g. 0:19).`
3730
+ );
3513
3731
  }
3514
3732
  return [start, end];
3515
3733
  }
@@ -3520,7 +3738,9 @@ function selectColumns(rows, rawColumns) {
3520
3738
  if (!rawColumns?.trim()) return rows;
3521
3739
  const requested = rawColumns.split(",").map((part) => part.trim()).filter(Boolean);
3522
3740
  if (requested.length === 0) {
3523
- throw new Error("Invalid --columns value: provide at least one column name.");
3741
+ throw new Error(
3742
+ "Invalid --columns value: provide at least one column name."
3743
+ );
3524
3744
  }
3525
3745
  const available = new Set(Object.keys(rows[0] ?? {}));
3526
3746
  const missing = requested.filter((column) => !available.has(column));
@@ -3557,13 +3777,22 @@ function renderTable(rows, totalRows, verbose) {
3557
3777
  return display.padEnd(widths[column]);
3558
3778
  }).join(" | ")
3559
3779
  );
3560
- return [header, divider, ...body, "", `showing ${rows.length} row(s) of ${totalRows}`].join("\n");
3780
+ return [
3781
+ header,
3782
+ divider,
3783
+ ...body,
3784
+ "",
3785
+ `showing ${rows.length} row(s) of ${totalRows}`
3786
+ ].join("\n");
3561
3787
  }
3562
3788
  async function handleCsvShow(options) {
3563
3789
  const csvPath = options.csv;
3564
3790
  const [rowStart, rowEnd] = parseRowRange(options.rows);
3565
3791
  const allRows = readCsvRows(csvPath);
3566
- const selected = selectColumns(selectRows(allRows, rowStart, rowEnd), options.columns);
3792
+ const selected = selectColumns(
3793
+ selectRows(allRows, rowStart, rowEnd),
3794
+ options.columns
3795
+ );
3567
3796
  const format = options.format ?? "json";
3568
3797
  if (options.summary) {
3569
3798
  printJson(buildDatasetStats(selected, allRows.length));
@@ -3580,13 +3809,17 @@ async function handleCsvShow(options) {
3580
3809
  process.stdout.write(`${columns.join(",")}
3581
3810
  `);
3582
3811
  for (const row of selected) {
3583
- process.stdout.write(`${columns.map((column) => JSON.stringify(row[column] ?? "")).join(",")}
3584
- `);
3812
+ process.stdout.write(
3813
+ `${columns.map((column) => JSON.stringify(row[column] ?? "")).join(",")}
3814
+ `
3815
+ );
3585
3816
  }
3586
3817
  return;
3587
3818
  }
3588
- process.stdout.write(`${renderTable(selected, allRows.length, Boolean(options.verbose))}
3589
- `);
3819
+ process.stdout.write(
3820
+ `${renderTable(selected, allRows.length, Boolean(options.verbose))}
3821
+ `
3822
+ );
3590
3823
  }
3591
3824
  function registerCsvCommands(program) {
3592
3825
  const csv = program.command("csv").description("Inspect local CSV files.").addHelpText(
@@ -3619,12 +3852,7 @@ Examples:
3619
3852
  // src/cli/commands/db.ts
3620
3853
  var import_node_fs5 = require("fs");
3621
3854
  var import_node_path6 = require("path");
3622
- var CUSTOMER_DB_QUERY_FORMATS = /* @__PURE__ */ new Set([
3623
- "table",
3624
- "json",
3625
- "csv",
3626
- "markdown"
3627
- ]);
3855
+ var CUSTOMER_DB_QUERY_FORMATS = /* @__PURE__ */ new Set(["table", "json", "csv", "markdown"]);
3628
3856
  function parsePositiveInteger(value, flagName) {
3629
3857
  const parsed = Number.parseInt(value, 10);
3630
3858
  if (!Number.isFinite(parsed) || parsed <= 0) {
@@ -3639,10 +3867,17 @@ function formatCell(value) {
3639
3867
  }
3640
3868
  function tableLines(result) {
3641
3869
  const rows = dataExportRows(customerDbRows(result));
3642
- const responseColumns = dataExportColumns(rows, customerDbColumnNames(result));
3643
- const businessColumns = responseColumns.filter((column) => !column.startsWith("_"));
3870
+ const responseColumns = dataExportColumns(
3871
+ rows,
3872
+ customerDbColumnNames(result)
3873
+ );
3874
+ const businessColumns = responseColumns.filter(
3875
+ (column) => !column.startsWith("_")
3876
+ );
3644
3877
  const columns = businessColumns.length > 0 ? businessColumns : responseColumns;
3645
- const hiddenColumns = responseColumns.filter((column) => !columns.includes(column));
3878
+ const hiddenColumns = responseColumns.filter(
3879
+ (column) => !columns.includes(column)
3880
+ );
3646
3881
  const lines = [
3647
3882
  `${result.command} returned ${result.row_count_returned} row(s)` + (result.truncated ? " (truncated)" : "")
3648
3883
  ];
@@ -3650,7 +3885,9 @@ function tableLines(result) {
3650
3885
  lines.push(
3651
3886
  `Showing ${columns.length}/${responseColumns.length} columns; hidden metadata: ${hiddenColumns.join(", ")}`
3652
3887
  );
3653
- lines.push("Use --json or select metadata columns explicitly when you need run ids/errors/stages.");
3888
+ lines.push(
3889
+ "Use --json or select metadata columns explicitly when you need run ids/errors/stages."
3890
+ );
3654
3891
  }
3655
3892
  if (rows.length === 0) {
3656
3893
  return lines;
@@ -3664,7 +3901,9 @@ function tableLines(result) {
3664
3901
  )
3665
3902
  )
3666
3903
  );
3667
- lines.push(columns.map((column, index) => column.padEnd(widths[index])).join(" "));
3904
+ lines.push(
3905
+ columns.map((column, index) => column.padEnd(widths[index])).join(" ")
3906
+ );
3668
3907
  lines.push(widths.map((width) => "-".repeat(width)).join(" "));
3669
3908
  for (const row of rows) {
3670
3909
  lines.push(
@@ -3740,10 +3979,12 @@ async function handleDbQuery(args) {
3740
3979
  const explicitJsonOutput = args.includes("--json");
3741
3980
  const client = new DeeplineClient();
3742
3981
  const result = await client.queryCustomerDb({ sql, maxRows });
3743
- const toolCommand = `deepline tools execute query_customer_db --payload ${JSON.stringify({
3744
- sql,
3745
- ...maxRows ? { max_rows: maxRows } : {}
3746
- })} --json`;
3982
+ const toolCommand = `deepline tools execute query_customer_db --payload ${JSON.stringify(
3983
+ {
3984
+ sql,
3985
+ ...maxRows ? { max_rows: maxRows } : {}
3986
+ }
3987
+ )} --json`;
3747
3988
  if (format === "csv") {
3748
3989
  if (outPath) {
3749
3990
  const exportedPath = writeCustomerDbCsv(result, outPath);
@@ -3771,7 +4012,10 @@ async function handleDbQuery(args) {
3771
4012
  }),
3772
4013
  {
3773
4014
  json: explicitJsonOutput,
3774
- text: dataExportCsvString(customerDbRows(result), customerDbColumnNames(result))
4015
+ text: dataExportCsvString(
4016
+ customerDbRows(result),
4017
+ customerDbColumnNames(result)
4018
+ )
3775
4019
  }
3776
4020
  );
3777
4021
  return 0;
@@ -3813,14 +4057,17 @@ async function handleDbQuery(args) {
3813
4057
  );
3814
4058
  return 0;
3815
4059
  }
3816
- printCommandEnvelope({
3817
- ...result,
3818
- next: { toolEquivalent: toolCommand },
3819
- render: {
3820
- sections: [{ title: "customer db query", lines: tableLines(result) }],
3821
- actions: [{ label: "Tool equivalent", command: toolCommand }]
3822
- }
3823
- }, { json: jsonOutput || format === "json" });
4060
+ printCommandEnvelope(
4061
+ {
4062
+ ...result,
4063
+ next: { toolEquivalent: toolCommand },
4064
+ render: {
4065
+ sections: [{ title: "customer db query", lines: tableLines(result) }],
4066
+ actions: [{ label: "Tool equivalent", command: toolCommand }]
4067
+ }
4068
+ },
4069
+ { json: jsonOutput || format === "json" }
4070
+ );
3824
4071
  return 0;
3825
4072
  }
3826
4073
  function registerDbCommands(program) {
@@ -3856,7 +4103,10 @@ Examples:
3856
4103
  deepline db query --sql "select * from contacts limit 20" --format csv --out contacts.csv
3857
4104
  deepline db query --sql "select domain, name from companies limit 20" --format markdown
3858
4105
  `
3859
- ).requiredOption("--sql <sql>", "SQL statement").option("--max-rows <n>", "Maximum returned rows").option("--format <format>", "Output format: table, json, csv, or markdown").option("--out <path>", "Write csv or markdown output to a file").option("--json", "Emit raw JSON response. Also automatic when stdout is piped").action(async (options) => {
4106
+ ).requiredOption("--sql <sql>", "SQL statement").option("--max-rows <n>", "Maximum returned rows").option("--format <format>", "Output format: table, json, csv, or markdown").option("--out <path>", "Write csv or markdown output to a file").option(
4107
+ "--json",
4108
+ "Emit raw JSON response. Also automatic when stdout is piped"
4109
+ ).action(async (options) => {
3860
4110
  process.exitCode = await handleDbQuery([
3861
4111
  "--sql",
3862
4112
  options.sql,
@@ -3877,12 +4127,17 @@ async function handleFeedback(text, options) {
3877
4127
  ...options.command ? { command: options.command } : {},
3878
4128
  ...options.payload ? { payload: options.payload } : {}
3879
4129
  });
3880
- printCommandEnvelope({
3881
- ...response,
3882
- render: {
3883
- sections: [{ title: "feedback", lines: ["Feedback submitted. Thank you."] }]
3884
- }
3885
- }, { json: options.json });
4130
+ printCommandEnvelope(
4131
+ {
4132
+ ...response,
4133
+ render: {
4134
+ sections: [
4135
+ { title: "feedback", lines: ["Feedback submitted. Thank you."] }
4136
+ ]
4137
+ }
4138
+ },
4139
+ { json: options.json }
4140
+ );
3886
4141
  }
3887
4142
  function registerFeedbackCommands(program) {
3888
4143
  const feedback = program.command("feedback").description("Submit CLI feedback to Deepline.").addHelpText(
@@ -3925,76 +4180,106 @@ async function handleOrgList(options) {
3925
4180
  const config = resolveConfig();
3926
4181
  const http = new HttpClient(config);
3927
4182
  const payload = await fetchOrganizations(http, config.apiKey);
3928
- printCommandEnvelope({
3929
- ...payload,
3930
- render: {
3931
- sections: [{ title: "Your organizations:", lines: orgListLines(payload.organizations) }]
3932
- }
3933
- }, { json: options.json });
4183
+ printCommandEnvelope(
4184
+ {
4185
+ ...payload,
4186
+ render: {
4187
+ sections: [
4188
+ {
4189
+ title: "Your organizations:",
4190
+ lines: orgListLines(payload.organizations)
4191
+ }
4192
+ ]
4193
+ }
4194
+ },
4195
+ { json: options.json }
4196
+ );
3934
4197
  }
3935
4198
  async function handleOrgSwitch(selection, options) {
3936
4199
  const config = resolveConfig();
3937
4200
  const http = new HttpClient(config);
3938
4201
  const payload = await fetchOrganizations(http, config.apiKey);
3939
4202
  if (!selection && !options.orgId) {
3940
- printCommandEnvelope({
3941
- ...payload,
3942
- next: { switch: "deepline org switch <number>" },
3943
- render: {
3944
- sections: [{ title: "Your organizations:", lines: orgListLines(payload.organizations) }],
3945
- actions: [{ label: "Run", command: "deepline org switch <number>" }]
3946
- }
3947
- }, { json: options.json });
4203
+ printCommandEnvelope(
4204
+ {
4205
+ ...payload,
4206
+ next: { switch: "deepline org switch <number>" },
4207
+ render: {
4208
+ sections: [
4209
+ {
4210
+ title: "Your organizations:",
4211
+ lines: orgListLines(payload.organizations)
4212
+ }
4213
+ ],
4214
+ actions: [{ label: "Run", command: "deepline org switch <number>" }]
4215
+ }
4216
+ },
4217
+ { json: options.json }
4218
+ );
3948
4219
  return;
3949
4220
  }
3950
- let target = payload.organizations.find((org) => org.org_id === options.orgId);
4221
+ let target = payload.organizations.find(
4222
+ (org) => org.org_id === options.orgId
4223
+ );
3951
4224
  if (!target && selection) {
3952
4225
  const index = Number.parseInt(selection, 10);
3953
4226
  if (Number.isFinite(index) && index >= 1 && index <= payload.organizations.length) {
3954
4227
  target = payload.organizations[index - 1];
3955
4228
  } else {
3956
- target = payload.organizations.find((org) => org.name === selection || org.org_id === selection);
4229
+ target = payload.organizations.find(
4230
+ (org) => org.name === selection || org.org_id === selection
4231
+ );
3957
4232
  }
3958
4233
  }
3959
4234
  if (!target) {
3960
4235
  throw new Error("Could not resolve the selected organization.");
3961
4236
  }
3962
4237
  if (target.is_current) {
3963
- printCommandEnvelope({
3964
- ok: true,
3965
- unchanged: true,
3966
- organization: target,
3967
- render: { sections: [{ title: "org switch", lines: [`Already on ${target.name}.`] }] }
3968
- }, { json: options.json });
4238
+ printCommandEnvelope(
4239
+ {
4240
+ ok: true,
4241
+ unchanged: true,
4242
+ organization: target,
4243
+ render: {
4244
+ sections: [
4245
+ { title: "org switch", lines: [`Already on ${target.name}.`] }
4246
+ ]
4247
+ }
4248
+ },
4249
+ { json: options.json }
4250
+ );
3969
4251
  return;
3970
4252
  }
3971
- const switched = await http.post(
3972
- "/api/v2/auth/cli/switch",
3973
- { api_key: config.apiKey, org_id: target.org_id }
3974
- );
4253
+ const switched = await http.post("/api/v2/auth/cli/switch", {
4254
+ api_key: config.apiKey,
4255
+ org_id: target.org_id
4256
+ });
3975
4257
  saveHostEnvValues(config.baseUrl, {
3976
4258
  DEEPLINE_API_KEY: switched.api_key,
3977
4259
  DEEPLINE_ACTIVE_ORG_ID: switched.org_id,
3978
4260
  DEEPLINE_ACTIVE_ORG_NAME: switched.org_name
3979
4261
  });
3980
4262
  const { api_key: _apiKey, ...publicSwitched } = switched;
3981
- printCommandEnvelope({
3982
- ok: true,
3983
- host_env_path: hostEnvFilePath(config.baseUrl),
3984
- ...publicSwitched,
3985
- api_key_saved: true,
3986
- render: {
3987
- sections: [
3988
- {
3989
- title: "org switch",
3990
- lines: [
3991
- `Switched to ${switched.org_name}.`,
3992
- `Saved host auth in ${hostEnvFilePath(config.baseUrl)}`
3993
- ]
3994
- }
3995
- ]
3996
- }
3997
- }, { json: options.json });
4263
+ printCommandEnvelope(
4264
+ {
4265
+ ok: true,
4266
+ host_env_path: hostEnvFilePath(config.baseUrl),
4267
+ ...publicSwitched,
4268
+ api_key_saved: true,
4269
+ render: {
4270
+ sections: [
4271
+ {
4272
+ title: "org switch",
4273
+ lines: [
4274
+ `Switched to ${switched.org_name}.`,
4275
+ `Saved host auth in ${hostEnvFilePath(config.baseUrl)}`
4276
+ ]
4277
+ }
4278
+ ]
4279
+ }
4280
+ },
4281
+ { json: options.json }
4282
+ );
3998
4283
  }
3999
4284
  function registerOrgCommands(program) {
4000
4285
  const org = program.command("org").description("List and switch organizations.").addHelpText(
@@ -4021,7 +4306,9 @@ Examples:
4021
4306
  deepline org list --json
4022
4307
  `
4023
4308
  ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgList);
4024
- org.command("switch [selection]").description("Switch to another organization and save the new API key in the host auth file.").addHelpText(
4309
+ org.command("switch [selection]").description(
4310
+ "Switch to another organization and save the new API key in the host auth file."
4311
+ ).addHelpText(
4025
4312
  "after",
4026
4313
  `
4027
4314
  Notes:
@@ -5234,7 +5521,17 @@ function resolveExecutionProfile(override) {
5234
5521
  var import_node_crypto2 = require("crypto");
5235
5522
  var import_promises4 = require("fs/promises");
5236
5523
  var import_node_path8 = require("path");
5237
- var SOURCE_EXTENSIONS2 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"];
5524
+ var SOURCE_EXTENSIONS2 = [
5525
+ ".ts",
5526
+ ".tsx",
5527
+ ".mts",
5528
+ ".cts",
5529
+ ".js",
5530
+ ".jsx",
5531
+ ".mjs",
5532
+ ".cjs",
5533
+ ".json"
5534
+ ];
5238
5535
  function sha2562(buffer) {
5239
5536
  return (0, import_node_crypto2.createHash)("sha256").update(buffer).digest("hex");
5240
5537
  }
@@ -5258,7 +5555,9 @@ function unquoteStringLiteral2(literal) {
5258
5555
  return null;
5259
5556
  }
5260
5557
  try {
5261
- return JSON.parse(quote === '"' ? trimmed : `"${trimmed.slice(1, -1).replace(/"/g, '\\"')}"`);
5558
+ return JSON.parse(
5559
+ quote === '"' ? trimmed : `"${trimmed.slice(1, -1).replace(/"/g, '\\"')}"`
5560
+ );
5262
5561
  } catch {
5263
5562
  return trimmed.slice(1, -1);
5264
5563
  }
@@ -5319,7 +5618,9 @@ function resolveStringExpression(expression, constants) {
5319
5618
  }
5320
5619
  const parts = splitTopLevelPlus(value);
5321
5620
  if (parts) {
5322
- const resolved = parts.map((part) => resolveStringExpression(part, constants));
5621
+ const resolved = parts.map(
5622
+ (part) => resolveStringExpression(part, constants)
5623
+ );
5323
5624
  return resolved.every((part) => part != null) ? resolved.join("") : null;
5324
5625
  }
5325
5626
  return null;
@@ -5327,7 +5628,9 @@ function resolveStringExpression(expression, constants) {
5327
5628
  function collectTopLevelStringConstants(sourceCode) {
5328
5629
  const constants = /* @__PURE__ */ new Map();
5329
5630
  const source = stripCommentsToSpaces2(sourceCode);
5330
- for (const match of source.matchAll(/(?:^|\n)\s*const\s+([A-Za-z_$][\w$]*)\s*=\s*([^;\n]+)/g)) {
5631
+ for (const match of source.matchAll(
5632
+ /(?:^|\n)\s*const\s+([A-Za-z_$][\w$]*)\s*=\s*([^;\n]+)/g
5633
+ )) {
5331
5634
  const resolved = resolveStringExpression(match[2], constants);
5332
5635
  if (resolved != null) {
5333
5636
  constants.set(match[1], resolved);
@@ -5416,7 +5719,9 @@ function localImportSpecifiers(sourceCode) {
5416
5719
  )) {
5417
5720
  if (match[1]?.startsWith(".")) specifiers.push(match[1]);
5418
5721
  }
5419
- for (const match of source.matchAll(/\brequire\s*\(\s*(['"])(\.[^'"]*)\1\s*\)/g)) {
5722
+ for (const match of source.matchAll(
5723
+ /\brequire\s*\(\s*(['"])(\.[^'"]*)\1\s*\)/g
5724
+ )) {
5420
5725
  specifiers.push(match[2]);
5421
5726
  }
5422
5727
  return specifiers;
@@ -5438,18 +5743,26 @@ async function resolveLocalImport2(fromFile, specifier) {
5438
5743
  const candidates = [base];
5439
5744
  const explicitExtension = (0, import_node_path8.extname)(base).toLowerCase();
5440
5745
  if (!explicitExtension) {
5441
- candidates.push(...SOURCE_EXTENSIONS2.map((extension) => `${base}${extension}`));
5442
- candidates.push(...SOURCE_EXTENSIONS2.map((extension) => (0, import_node_path8.join)(base, `index${extension}`)));
5746
+ candidates.push(
5747
+ ...SOURCE_EXTENSIONS2.map((extension) => `${base}${extension}`)
5748
+ );
5749
+ candidates.push(
5750
+ ...SOURCE_EXTENSIONS2.map((extension) => (0, import_node_path8.join)(base, `index${extension}`))
5751
+ );
5443
5752
  } else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
5444
5753
  const stem = base.slice(0, -explicitExtension.length);
5445
- candidates.push(...SOURCE_EXTENSIONS2.map((extension) => `${stem}${extension}`));
5754
+ candidates.push(
5755
+ ...SOURCE_EXTENSIONS2.map((extension) => `${stem}${extension}`)
5756
+ );
5446
5757
  }
5447
5758
  for (const candidate of candidates) {
5448
5759
  if (await fileExists2(candidate)) {
5449
5760
  return candidate;
5450
5761
  }
5451
5762
  }
5452
- throw new Error(`Could not resolve local import "${specifier}" from ${fromFile}`);
5763
+ throw new Error(
5764
+ `Could not resolve local import "${specifier}" from ${fromFile}`
5765
+ );
5453
5766
  }
5454
5767
  async function discoverPackagedLocalFiles(entryFile) {
5455
5768
  const absoluteEntryFile = (0, import_node_path8.resolve)(entryFile);
@@ -5467,12 +5780,17 @@ async function discoverPackagedLocalFiles(entryFile) {
5467
5780
  const scanSource = stripCommentsToSpaces2(sourceCode);
5468
5781
  const constants = collectTopLevelStringConstants(sourceCode);
5469
5782
  const childVisits = [];
5470
- for (const match of scanSource.matchAll(/\b([A-Za-z_$][\w$]*)\s*\.\s*csv\b/g)) {
5783
+ for (const match of scanSource.matchAll(
5784
+ /\b([A-Za-z_$][\w$]*)\s*\.\s*csv\b/g
5785
+ )) {
5471
5786
  const target = match[1];
5472
5787
  if (target !== "ctx" && !target.endsWith("Ctx")) {
5473
5788
  continue;
5474
5789
  }
5475
- const openParen = findCallOpenParen(scanSource, match.index + match[0].length);
5790
+ const openParen = findCallOpenParen(
5791
+ scanSource,
5792
+ match.index + match[0].length
5793
+ );
5476
5794
  if (openParen < 0) {
5477
5795
  continue;
5478
5796
  }
@@ -9264,7 +9582,9 @@ function buildRunPackageTextLines(packaged) {
9264
9582
  lines.push(` ${kind} ${id}: ${stepStatus}${rowCount}`);
9265
9583
  lines.push(...formatPackageDatasetSummaryLines(output?.summary));
9266
9584
  if (previewRows !== null) {
9267
- lines.push(` preview=${previewRows}${preview?.truncated ? " truncated" : ""}`);
9585
+ lines.push(
9586
+ ` preview=${previewRows}${preview?.truncated ? " truncated" : ""}`
9587
+ );
9268
9588
  }
9269
9589
  }
9270
9590
  const next = packaged.next && typeof packaged.next === "object" && !Array.isArray(packaged.next) ? packaged.next : {};
@@ -11066,7 +11386,9 @@ function matchesPlayGrepQuery(value, query, mode) {
11066
11386
  async function handlePlayGrep(args) {
11067
11387
  const query = args[0]?.trim();
11068
11388
  if (!query) {
11069
- console.error("Usage: deepline plays grep <query> [--mode all|any|phrase] [--compact] [--json]");
11389
+ console.error(
11390
+ "Usage: deepline plays grep <query> [--mode all|any|phrase] [--compact] [--json]"
11391
+ );
11070
11392
  return 1;
11071
11393
  }
11072
11394
  let mode = "all";
@@ -11099,13 +11421,15 @@ async function handlePlayGrep(args) {
11099
11421
  )
11100
11422
  ).map((play) => summarizePlayListItemForCli(play, { compact }));
11101
11423
  if (argsWantJson(args)) {
11102
- process.stdout.write(`${JSON.stringify({
11103
- plays,
11104
- count: plays.length,
11105
- query,
11106
- grep: { mode, terms: parsePlayGrepTerms(query, mode) }
11107
- })}
11108
- `);
11424
+ process.stdout.write(
11425
+ `${JSON.stringify({
11426
+ plays,
11427
+ count: plays.length,
11428
+ query,
11429
+ grep: { mode, terms: parsePlayGrepTerms(query, mode) }
11430
+ })}
11431
+ `
11432
+ );
11109
11433
  return 0;
11110
11434
  }
11111
11435
  process.stdout.write(`${plays.length} plays found:
@@ -11768,7 +12092,9 @@ function normalizeRows(value) {
11768
12092
  });
11769
12093
  }
11770
12094
  function candidateRoots(payload) {
11771
- const roots = [{ path: null, value: payload }];
12095
+ const roots = [
12096
+ { path: null, value: payload }
12097
+ ];
11772
12098
  if (isPlainObject(payload) && isPlainObject(payload.toolResponse)) {
11773
12099
  roots.push({ path: "toolResponse", value: payload.toolResponse });
11774
12100
  if (Object.prototype.hasOwnProperty.call(payload.toolResponse, "raw")) {
@@ -11795,7 +12121,9 @@ function candidateRoots(payload) {
11795
12121
  function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
11796
12122
  if (depth > 5) return null;
11797
12123
  const directRows = normalizeRows(value);
11798
- const hasObjectRow = directRows?.some((row) => Object.keys(row).some((key) => key !== "value")) ?? false;
12124
+ const hasObjectRow = directRows?.some(
12125
+ (row) => Object.keys(row).some((key) => key !== "value")
12126
+ ) ?? false;
11799
12127
  let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
11800
12128
  if (!isPlainObject(value)) {
11801
12129
  return best;
@@ -11811,7 +12139,9 @@ function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
11811
12139
  return best;
11812
12140
  }
11813
12141
  function tryConvertToList(payload, options) {
11814
- const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
12142
+ const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter(
12143
+ (entry) => typeof entry === "string" && entry.trim().length > 0
12144
+ ) : [];
11815
12145
  if (listExtractorPaths.length > 0) {
11816
12146
  for (const root of candidateRoots(payload)) {
11817
12147
  for (const extractorPath of listExtractorPaths) {
@@ -11877,7 +12207,9 @@ function writeCsvOutputFile(rows, stem) {
11877
12207
  const previewColumns = columns.slice(0, 5);
11878
12208
  const preview = [
11879
12209
  previewColumns.join(","),
11880
- ...previewRows.map((row) => previewColumns.map((column) => escapeCell(row[column])).join(","))
12210
+ ...previewRows.map(
12211
+ (row) => previewColumns.map((column) => escapeCell(row[column])).join(",")
12212
+ )
11881
12213
  ].join("\n");
11882
12214
  return {
11883
12215
  path: outputPath,
@@ -11890,9 +12222,11 @@ function extractSummaryFields(payload) {
11890
12222
  const candidates = candidateRoots(payload);
11891
12223
  for (const candidate of candidates) {
11892
12224
  if (!isPlainObject(candidate.value)) continue;
11893
- const summaryEntries = Object.entries(candidate.value).filter(([, value]) => {
11894
- return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
11895
- });
12225
+ const summaryEntries = Object.entries(candidate.value).filter(
12226
+ ([, value]) => {
12227
+ return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
12228
+ }
12229
+ );
11896
12230
  if (summaryEntries.length === 0) continue;
11897
12231
  return Object.fromEntries(summaryEntries);
11898
12232
  }
@@ -12422,8 +12756,16 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
12422
12756
  arrayField(toolExecutionResult, "extractedValues", "extracted_values")
12423
12757
  );
12424
12758
  const cost = recordField(tool, "cost");
12425
- const deeplineCredits = numberField(tool, "deeplineCreditsPerPricingUnit", "deepline_credits_per_pricing_unit");
12426
- const deeplineUsdPerPricingUnit = numberField(tool, "deeplineUsdPerPricingUnit", "deepline_usd_per_pricing_unit");
12759
+ const deeplineCredits = numberField(
12760
+ tool,
12761
+ "deeplineCreditsPerPricingUnit",
12762
+ "deepline_credits_per_pricing_unit"
12763
+ );
12764
+ const deeplineUsdPerPricingUnit = numberField(
12765
+ tool,
12766
+ "deeplineUsdPerPricingUnit",
12767
+ "deepline_usd_per_pricing_unit"
12768
+ );
12427
12769
  const starterScript = seedToolListScript({
12428
12770
  toolId,
12429
12771
  payload: samplePayloadForInputFields(inputFields),
@@ -12511,7 +12853,9 @@ function printCompactToolContract(tool, requestedToolId) {
12511
12853
  if (starterPath) {
12512
12854
  console.log("");
12513
12855
  console.log(`Starter script: ${starterPath}`);
12514
- console.log("Copy it into your project and replace the sample input with the proven probe payload.");
12856
+ console.log(
12857
+ "Copy it into your project and replace the sample input with the proven probe payload."
12858
+ );
12515
12859
  }
12516
12860
  if (listGetters.length || valueGetters.length) {
12517
12861
  console.log("");
@@ -12674,7 +13018,9 @@ function playResultExpression(entry) {
12674
13018
  }
12675
13019
  function toolMetadataJsonForDescribe(tool, requestedToolId) {
12676
13020
  const toolId = String(tool.toolId || requestedToolId);
12677
- const inputFields = toolInputFieldsForDisplay(recordField(tool, "inputSchema", "input_schema"));
13021
+ const inputFields = toolInputFieldsForDisplay(
13022
+ recordField(tool, "inputSchema", "input_schema")
13023
+ );
12678
13024
  const starterScript = seedToolListScript({
12679
13025
  toolId,
12680
13026
  payload: samplePayloadForInputFields(inputFields),
@@ -12699,7 +13045,9 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
12699
13045
  toolId,
12700
13046
  provider: tool.provider,
12701
13047
  displayName: tool.displayName,
12702
- usageGuidance: usageGuidanceWithAccessDefaults(recordField(tool, "usageGuidance", "usage_guidance")),
13048
+ usageGuidance: usageGuidanceWithAccessDefaults(
13049
+ recordField(tool, "usageGuidance", "usage_guidance")
13050
+ ),
12703
13051
  runtimeOutputHelp: {
12704
13052
  contract: "tools describe shows declared schema and Deepline getters; it is not an observed provider response.",
12705
13053
  getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
@@ -13314,8 +13662,10 @@ async function handleUpdate(options) {
13314
13662
  printCommandEnvelope({ ...plan, render }, { json: false });
13315
13663
  return 0;
13316
13664
  }
13317
- process.stderr.write(`Updating Deepline SDK/CLI with: ${plan.manualCommand}
13318
- `);
13665
+ process.stderr.write(
13666
+ `Updating Deepline SDK/CLI with: ${plan.manualCommand}
13667
+ `
13668
+ );
13319
13669
  return runCommand(plan.command, plan.args);
13320
13670
  }
13321
13671
  function registerUpdateCommand(program) {
@@ -13352,7 +13702,14 @@ function shouldSkipSkillsSync() {
13352
13702
  }
13353
13703
  function sdkSkillsVersionPath(baseUrl) {
13354
13704
  const home = process.env.HOME?.trim() || (0, import_node_os8.homedir)();
13355
- return (0, import_node_path15.join)(home, ".local", "deepline", baseUrlSlug(baseUrl), "sdk-skills", ".version");
13705
+ return (0, import_node_path15.join)(
13706
+ home,
13707
+ ".local",
13708
+ "deepline",
13709
+ baseUrlSlug(baseUrl),
13710
+ "sdk-skills",
13711
+ ".version"
13712
+ );
13356
13713
  }
13357
13714
  function readLocalSkillsVersion(baseUrl) {
13358
13715
  const path = sdkSkillsVersionPath(baseUrl);
@@ -13434,7 +13791,10 @@ async function fetchSkillsUpdate(baseUrl, localVersion) {
13434
13791
  }
13435
13792
  }
13436
13793
  function buildSkillsInstallArgs(baseUrl) {
13437
- const packageUrl = new URL("/.well-known/skills/index.json", baseUrl).toString();
13794
+ const packageUrl = new URL(
13795
+ "/.well-known/skills/index.json",
13796
+ baseUrl
13797
+ ).toString();
13438
13798
  return [
13439
13799
  "--yes",
13440
13800
  "skills",
@@ -13450,7 +13810,10 @@ function buildSkillsInstallArgs(baseUrl) {
13450
13810
  ];
13451
13811
  }
13452
13812
  function buildBunxSkillsInstallArgs(baseUrl) {
13453
- const packageUrl = new URL("/.well-known/skills/index.json", baseUrl).toString();
13813
+ const packageUrl = new URL(
13814
+ "/.well-known/skills/index.json",
13815
+ baseUrl
13816
+ ).toString();
13454
13817
  return [
13455
13818
  "--bun",
13456
13819
  "skills",