deepline 0.1.63 → 0.1.65

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/cli/index.ts
4
4
  import { mkdtemp, rm, writeFile as writeFile4 } from "fs/promises";
5
- import { join as join11 } from "path";
5
+ import { join as join12 } from "path";
6
6
  import { tmpdir as tmpdir4 } from "os";
7
7
  import { Command as Command3 } from "commander";
8
8
 
@@ -34,7 +34,11 @@ var RateLimitError = class extends DeeplineError {
34
34
  /** Milliseconds to wait before retrying, from the `Retry-After` response header. Defaults to 5000. */
35
35
  retryAfterMs;
36
36
  constructor(retryAfterMs = 5e3, message) {
37
- super(message ?? `Rate limited. Retry after ${retryAfterMs}ms.`, 429, "RATE_LIMIT");
37
+ super(
38
+ message ?? `Rate limited. Retry after ${retryAfterMs}ms.`,
39
+ 429,
40
+ "RATE_LIMIT"
41
+ );
38
42
  this.name = "RateLimitError";
39
43
  this.retryAfterMs = retryAfterMs;
40
44
  }
@@ -195,12 +199,17 @@ function resolveConfig(options) {
195
199
  };
196
200
  }
197
201
 
202
+ // src/http.ts
203
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
204
+ import { homedir as homedir2 } from "os";
205
+ import { join as join2 } from "path";
206
+
198
207
  // src/release.ts
199
208
  var SDK_RELEASE = {
200
- version: "0.1.63",
209
+ version: "0.1.65",
201
210
  apiContract: "2026-05-play-bootstrap-dataset-summary",
202
211
  supportPolicy: {
203
- latest: "0.1.63",
212
+ latest: "0.1.65",
204
213
  minimumSupported: "0.1.53",
205
214
  deprecatedBelow: "0.1.53"
206
215
  }
@@ -216,19 +225,51 @@ var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
216
225
  var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
217
226
 
218
227
  // src/http.ts
228
+ var MAX_DIAGNOSTIC_HEADER_LENGTH = 120;
219
229
  var HttpClient = class {
220
230
  constructor(config) {
221
231
  this.config = config;
222
232
  }
223
233
  config;
234
+ cleanDiagnosticHeader(value) {
235
+ const normalized = String(value ?? "").replace(/[\u0000-\u001f\u007f]/g, " ").trim().slice(0, MAX_DIAGNOSTIC_HEADER_LENGTH);
236
+ return normalized || null;
237
+ }
238
+ readSkillsVersionHeader() {
239
+ const explicit = this.cleanDiagnosticHeader(
240
+ process.env.DEEPLINE_SKILLS_VERSION
241
+ );
242
+ if (explicit) return explicit;
243
+ try {
244
+ const versionPath = join2(
245
+ process.env.HOME?.trim() || homedir2(),
246
+ ".local",
247
+ "deepline",
248
+ baseUrlSlug(this.config.baseUrl),
249
+ "sdk-skills",
250
+ ".version"
251
+ );
252
+ if (!existsSync2(versionPath)) return null;
253
+ return this.cleanDiagnosticHeader(readFileSync2(versionPath, "utf-8"));
254
+ } catch {
255
+ return null;
256
+ }
257
+ }
224
258
  authHeaders(extra) {
225
259
  const headers = {
226
- "Authorization": `Bearer ${this.config.apiKey}`,
260
+ Authorization: `Bearer ${this.config.apiKey}`,
227
261
  "User-Agent": `deepline-ts-sdk/${SDK_VERSION}`,
262
+ "X-Deepline-Client-Family": "sdk",
263
+ "X-Deepline-CLI-Family": "sdk",
264
+ "X-Deepline-CLI-Version": SDK_VERSION,
228
265
  "X-Deepline-SDK-Version": SDK_VERSION,
229
266
  "X-Deepline-API-Contract": SDK_API_CONTRACT,
230
267
  ...extra
231
268
  };
269
+ const skillsVersion = this.readSkillsVersionHeader();
270
+ if (skillsVersion) {
271
+ headers["X-Deepline-Skills-Version"] = skillsVersion;
272
+ }
232
273
  const bypassToken = typeof process !== "undefined" ? process.env?.VERCEL_PROTECTION_BYPASS_TOKEN : void 0;
233
274
  if (bypassToken) {
234
275
  headers["x-vercel-protection-bypass"] = bypassToken;
@@ -906,31 +947,34 @@ var DeeplineClient = class {
906
947
  * artifactStorageKey: 'plays/v1/orgs/acme/plays/my-play/artifacts/playgraph_abc123.json',
907
948
  * });
908
949
  * ```
909
- */
950
+ */
910
951
  async startPlayRun(request) {
911
- const response = await this.http.post("/api/v2/plays/run", {
912
- ...request.name ? { name: request.name } : {},
913
- ...request.revisionId ? { revisionId: request.revisionId } : {},
914
- ...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
915
- ...request.sourceCode ? { sourceCode: request.sourceCode } : {},
916
- ...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
917
- ..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
918
- ...request.artifactHash ? { artifactHash: request.artifactHash } : {},
919
- ...request.graphHash ? { graphHash: request.graphHash } : {},
920
- ...request.runtimeArtifact ? { runtimeArtifact: request.runtimeArtifact } : {},
921
- ...request.compilerManifest ? { compilerManifest: request.compilerManifest } : {},
922
- ...request.inputFileUpload ? { inputFileUpload: request.inputFileUpload } : {},
923
- ...request.packagedFileUploads?.length ? { packagedFileUploads: request.packagedFileUploads } : {},
924
- ...request.input ? { input: request.input } : {},
925
- ...request.inputFile ? { inputFile: request.inputFile } : {},
926
- ...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
927
- ...request.force ? { force: true } : {},
928
- ...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
929
- // Profile selection is the API's job, not the CLI's. The server
930
- // hardcodes workers_edge as the default; tests that want a
931
- // different profile pass `request.profile` explicitly.
932
- ...request.profile ? { profile: request.profile } : {}
933
- });
952
+ const response = await this.http.post(
953
+ "/api/v2/plays/run",
954
+ {
955
+ ...request.name ? { name: request.name } : {},
956
+ ...request.revisionId ? { revisionId: request.revisionId } : {},
957
+ ...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
958
+ ...request.sourceCode ? { sourceCode: request.sourceCode } : {},
959
+ ...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
960
+ ..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
961
+ ...request.artifactHash ? { artifactHash: request.artifactHash } : {},
962
+ ...request.graphHash ? { graphHash: request.graphHash } : {},
963
+ ...request.runtimeArtifact ? { runtimeArtifact: request.runtimeArtifact } : {},
964
+ ...request.compilerManifest ? { compilerManifest: request.compilerManifest } : {},
965
+ ...request.inputFileUpload ? { inputFileUpload: request.inputFileUpload } : {},
966
+ ...request.packagedFileUploads?.length ? { packagedFileUploads: request.packagedFileUploads } : {},
967
+ ...request.input ? { input: request.input } : {},
968
+ ...request.inputFile ? { inputFile: request.inputFile } : {},
969
+ ...request.packagedFiles?.length ? { packagedFiles: request.packagedFiles } : {},
970
+ ...request.force ? { force: true } : {},
971
+ ...typeof request.waitForCompletionMs === "number" ? { waitForCompletionMs: request.waitForCompletionMs } : {},
972
+ // Profile selection is the API's job, not the CLI's. The server
973
+ // hardcodes workers_edge as the default; tests that want a
974
+ // different profile pass `request.profile` explicitly.
975
+ ...request.profile ? { profile: request.profile } : {}
976
+ }
977
+ );
934
978
  return normalizePlayRunStart(response);
935
979
  }
936
980
  async *startPlayRunStream(request, options) {
@@ -1182,10 +1226,7 @@ var DeeplineClient = class {
1182
1226
  }
1183
1227
  return formData;
1184
1228
  };
1185
- const response = await this.http.postFormData(
1186
- "/api/v2/plays/files/stage",
1187
- buildFormData
1188
- );
1229
+ const response = await this.http.postFormData("/api/v2/plays/files/stage", buildFormData);
1189
1230
  return response.files;
1190
1231
  }
1191
1232
  async resolveStagedPlayFiles(files) {
@@ -1632,7 +1673,9 @@ var DeeplineClient = class {
1632
1673
  }
1633
1674
  options?.onProgress?.(status);
1634
1675
  if (TERMINAL_PLAY_STATUSES.has(status.status)) {
1635
- const finalStatus = await this.getPlayStatus(status.runId || workflowId).catch(() => status);
1676
+ const finalStatus = await this.getPlayStatus(
1677
+ status.runId || workflowId
1678
+ ).catch(() => status);
1636
1679
  return playRunResultFromStatus(finalStatus, start, workflowId);
1637
1680
  }
1638
1681
  }
@@ -1715,20 +1758,21 @@ async function enforceSdkCompatibility(baseUrl) {
1715
1758
  }
1716
1759
 
1717
1760
  // src/cli/commands/auth.ts
1718
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync, writeFileSync as writeFileSync3 } from "fs";
1761
+ import {
1762
+ existsSync as existsSync4,
1763
+ mkdirSync as mkdirSync3,
1764
+ readFileSync as readFileSync4,
1765
+ rmSync,
1766
+ writeFileSync as writeFileSync3
1767
+ } from "fs";
1719
1768
  import { hostname } from "os";
1720
1769
  import { dirname as dirname3 } from "path";
1721
1770
 
1722
1771
  // src/cli/utils.ts
1723
- import {
1724
- existsSync as existsSync2,
1725
- mkdirSync as mkdirSync2,
1726
- readFileSync as readFileSync2,
1727
- writeFileSync as writeFileSync2
1728
- } from "fs";
1772
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
1729
1773
  import { mkdir, writeFile } from "fs/promises";
1730
- import { homedir as homedir2 } from "os";
1731
- import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
1774
+ import { homedir as homedir3 } from "os";
1775
+ import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
1732
1776
  import * as childProcess from "child_process";
1733
1777
  import { parse } from "csv-parse/sync";
1734
1778
  import { stringify } from "csv-stringify/sync";
@@ -1741,13 +1785,13 @@ function getAuthedHttpClient() {
1741
1785
  async function writeOutputFile(filename, content) {
1742
1786
  const outputDir = resolve2(process.cwd(), "deepline", "data");
1743
1787
  await mkdir(outputDir, { recursive: true });
1744
- const fullPath = join2(outputDir, filename);
1788
+ const fullPath = join3(outputDir, filename);
1745
1789
  await writeFile(fullPath, content, "utf-8");
1746
1790
  return fullPath;
1747
1791
  }
1748
1792
  function browserFocusStateFile() {
1749
- const homeDir = process.env.HOME || homedir2();
1750
- return join2(
1793
+ const homeDir = process.env.HOME || homedir3();
1794
+ return join3(
1751
1795
  homeDir,
1752
1796
  ".local",
1753
1797
  "deepline",
@@ -1761,8 +1805,8 @@ function claimBrowserFocus(now = Date.now()) {
1761
1805
  try {
1762
1806
  mkdirSync2(dirname2(statePath), { recursive: true });
1763
1807
  let lastFocusedAt = 0;
1764
- if (existsSync2(statePath)) {
1765
- const payload = JSON.parse(readFileSync2(statePath, "utf-8"));
1808
+ if (existsSync3(statePath)) {
1809
+ const payload = JSON.parse(readFileSync3(statePath, "utf-8"));
1766
1810
  const value = payload.lastFocusedAt ?? payload.last_focused_at;
1767
1811
  if (typeof value === "number" && Number.isFinite(value)) {
1768
1812
  lastFocusedAt = value;
@@ -1808,7 +1852,7 @@ function readDefaultMacBrowserBundleId(runner = defaultBrowserCommandRunner) {
1808
1852
  "/usr/bin/defaults",
1809
1853
  [
1810
1854
  "read",
1811
- `${homedir2()}/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist`,
1855
+ `${homedir3()}/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist`,
1812
1856
  "LSHandlers"
1813
1857
  ],
1814
1858
  { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }
@@ -1928,11 +1972,9 @@ function openUrlMacos(targetUrl, allowFocus, runner = defaultBrowserCommandRunne
1928
1972
  return true;
1929
1973
  }
1930
1974
  try {
1931
- runner.execFileSync(
1932
- "open",
1933
- [...allowFocus ? [] : ["-g"], targetUrl],
1934
- { stdio: "ignore" }
1935
- );
1975
+ runner.execFileSync("open", [...allowFocus ? [] : ["-g"], targetUrl], {
1976
+ stdio: "ignore"
1977
+ });
1936
1978
  return true;
1937
1979
  } catch {
1938
1980
  return false;
@@ -1969,11 +2011,11 @@ function collectLocalEnvInfo() {
1969
2011
  return {
1970
2012
  os: `${process.platform} ${process.arch}`,
1971
2013
  node_version: process.version,
1972
- home_dir: homedir2()
2014
+ home_dir: homedir3()
1973
2015
  };
1974
2016
  }
1975
2017
  function readCsvRows(csvPath) {
1976
- const raw = readFileSync2(resolve2(csvPath), "utf-8");
2018
+ const raw = readFileSync3(resolve2(csvPath), "utf-8");
1977
2019
  return parse(raw, {
1978
2020
  columns: true,
1979
2021
  skip_empty_lines: true
@@ -2126,7 +2168,10 @@ function createTimestampedName(prefix, extension) {
2126
2168
  return `${prefix}-${timestamp}.${extension}`;
2127
2169
  }
2128
2170
  async function writeCsvRowsFile(prefix, rows) {
2129
- const path = await writeOutputFile(createTimestampedName(prefix, "csv"), csvStringFromRows(rows));
2171
+ const path = await writeOutputFile(
2172
+ createTimestampedName(prefix, "csv"),
2173
+ csvStringFromRows(rows)
2174
+ );
2130
2175
  return path;
2131
2176
  }
2132
2177
  function clip(value, maxLength) {
@@ -2178,7 +2223,7 @@ function pendingClaimTokenPath(baseUrl) {
2178
2223
  function savePendingClaimToken(baseUrl, claimToken) {
2179
2224
  const filePath = pendingClaimTokenPath(baseUrl);
2180
2225
  const dir = dirname3(filePath);
2181
- if (!existsSync3(dir)) {
2226
+ if (!existsSync4(dir)) {
2182
2227
  mkdirSync3(dir, { recursive: true });
2183
2228
  }
2184
2229
  writeFileSync3(filePath, `${claimToken}
@@ -2186,9 +2231,9 @@ function savePendingClaimToken(baseUrl, claimToken) {
2186
2231
  }
2187
2232
  function readPendingClaimToken(baseUrl) {
2188
2233
  const filePath = pendingClaimTokenPath(baseUrl);
2189
- if (!existsSync3(filePath)) return "";
2234
+ if (!existsSync4(filePath)) return "";
2190
2235
  try {
2191
- return readFileSync3(filePath, "utf-8").trim();
2236
+ return readFileSync4(filePath, "utf-8").trim();
2192
2237
  } catch {
2193
2238
  return "";
2194
2239
  }
@@ -2207,7 +2252,9 @@ function saveEnvValues(values, baseUrl) {
2207
2252
  saveHostEnvValues(baseUrl, filtered);
2208
2253
  }
2209
2254
  async function httpJson(method, url, apiKey, body) {
2210
- const headers = { "Content-Type": "application/json" };
2255
+ const headers = {
2256
+ "Content-Type": "application/json"
2257
+ };
2211
2258
  if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
2212
2259
  let response = null;
2213
2260
  let lastError = null;
@@ -2262,12 +2309,24 @@ function sleep3(ms) {
2262
2309
  }
2263
2310
  function printDeeplineLogo() {
2264
2311
  if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
2265
- 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");
2266
- 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");
2267
- 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");
2268
- 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");
2269
- 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");
2270
- 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");
2312
+ console.log(
2313
+ " \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"
2314
+ );
2315
+ console.log(
2316
+ " \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"
2317
+ );
2318
+ console.log(
2319
+ " \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"
2320
+ );
2321
+ console.log(
2322
+ " \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"
2323
+ );
2324
+ console.log(
2325
+ " \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"
2326
+ );
2327
+ console.log(
2328
+ " \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"
2329
+ );
2271
2330
  console.log("");
2272
2331
  return;
2273
2332
  }
@@ -2301,7 +2360,12 @@ async function handleRegister(args) {
2301
2360
  const payload = {};
2302
2361
  if (orgName) payload.org_name = orgName;
2303
2362
  if (agentName) payload.agent_name = agentName;
2304
- const { status, data } = await httpJson("POST", `${baseUrl}/api/v2/auth/cli/register`, null, payload);
2363
+ const { status, data } = await httpJson(
2364
+ "POST",
2365
+ `${baseUrl}/api/v2/auth/cli/register`,
2366
+ null,
2367
+ payload
2368
+ );
2305
2369
  if (status >= 400) {
2306
2370
  console.error(`Auth register failed (status ${status}).`);
2307
2371
  if (data.error) console.error(String(data.error));
@@ -2311,9 +2375,12 @@ async function handleRegister(args) {
2311
2375
  const claimToken = String(data.claim_token || "");
2312
2376
  if (claimToken) {
2313
2377
  savePendingClaimToken(baseUrl, claimToken);
2314
- saveEnvValues({
2315
- [HOST_URL_ENV]: baseUrl
2316
- }, baseUrl);
2378
+ saveEnvValues(
2379
+ {
2380
+ [HOST_URL_ENV]: baseUrl
2381
+ },
2382
+ baseUrl
2383
+ );
2317
2384
  }
2318
2385
  if (claimUrl) {
2319
2386
  console.log(" Opening approval page in your browser.");
@@ -2352,10 +2419,13 @@ async function handleRegister(args) {
2352
2419
  if (state === "claimed") {
2353
2420
  const apiKey = String(statusData.api_key || "");
2354
2421
  if (apiKey) {
2355
- saveEnvValues({
2356
- [HOST_URL_ENV]: baseUrl,
2357
- [API_KEY_ENV]: apiKey
2358
- }, baseUrl);
2422
+ saveEnvValues(
2423
+ {
2424
+ [HOST_URL_ENV]: baseUrl,
2425
+ [API_KEY_ENV]: apiKey
2426
+ },
2427
+ baseUrl
2428
+ );
2359
2429
  clearPendingClaimToken(baseUrl);
2360
2430
  printClaimSuccessBanner(statusData);
2361
2431
  return EXIT_OK;
@@ -2363,7 +2433,9 @@ async function handleRegister(args) {
2363
2433
  }
2364
2434
  if (state === "expired") {
2365
2435
  clearPendingClaimToken(baseUrl);
2366
- console.log("That approval link expired. Please run: deepline auth register");
2436
+ console.log(
2437
+ "That approval link expired. Please run: deepline auth register"
2438
+ );
2367
2439
  return EXIT_AUTH;
2368
2440
  }
2369
2441
  await sleep3(2e3);
@@ -2414,10 +2486,13 @@ async function handleWait(args) {
2414
2486
  if (state === "claimed") {
2415
2487
  const apiKey = String(data.api_key || "");
2416
2488
  if (apiKey) {
2417
- saveEnvValues({
2418
- [HOST_URL_ENV]: baseUrl,
2419
- [API_KEY_ENV]: apiKey
2420
- }, baseUrl);
2489
+ saveEnvValues(
2490
+ {
2491
+ [HOST_URL_ENV]: baseUrl,
2492
+ [API_KEY_ENV]: apiKey
2493
+ },
2494
+ baseUrl
2495
+ );
2421
2496
  clearPendingClaimToken(baseUrl);
2422
2497
  printClaimSuccessBanner(data);
2423
2498
  return EXIT_OK;
@@ -2430,7 +2505,9 @@ async function handleWait(args) {
2430
2505
  }
2431
2506
  await sleep3(2e3);
2432
2507
  }
2433
- console.error("Still pending. Approve the browser link, then run: deepline auth wait");
2508
+ console.error(
2509
+ "Still pending. Approve the browser link, then run: deepline auth wait"
2510
+ );
2434
2511
  return EXIT_AUTH;
2435
2512
  }
2436
2513
  async function handleStatus(args) {
@@ -2440,7 +2517,11 @@ async function handleStatus(args) {
2440
2517
  let hostStatusPayload = null;
2441
2518
  const hostLines = [];
2442
2519
  try {
2443
- const { status: hStatus, data: hData } = await httpJson("GET", `${baseUrl}/api/v2/health`, null);
2520
+ const { status: hStatus, data: hData } = await httpJson(
2521
+ "GET",
2522
+ `${baseUrl}/api/v2/health`,
2523
+ null
2524
+ );
2444
2525
  if (hStatus === 200) {
2445
2526
  hostStatusPayload = {
2446
2527
  host: baseUrl,
@@ -2462,45 +2543,74 @@ async function handleStatus(args) {
2462
2543
  const apiKey = resolveApiKeyForBaseUrl(baseUrl);
2463
2544
  if (!apiKey) {
2464
2545
  if (readPendingClaimToken(baseUrl)) {
2465
- printCommandEnvelope({
2546
+ printCommandEnvelope(
2547
+ {
2548
+ ...hostStatusPayload ?? { host: baseUrl },
2549
+ status: "pending",
2550
+ connected: false,
2551
+ next: "deepline auth wait",
2552
+ render: {
2553
+ sections: [
2554
+ {
2555
+ title: "auth status",
2556
+ lines: [...hostLines, "Status: pending"]
2557
+ }
2558
+ ],
2559
+ actions: [{ label: "Run", command: "deepline auth wait" }]
2560
+ }
2561
+ },
2562
+ { json: jsonOutput }
2563
+ );
2564
+ return EXIT_OK;
2565
+ }
2566
+ printCommandEnvelope(
2567
+ {
2466
2568
  ...hostStatusPayload ?? { host: baseUrl },
2467
- status: "pending",
2569
+ status: "not connected",
2468
2570
  connected: false,
2469
- next: "deepline auth wait",
2571
+ next: "deepline auth register",
2470
2572
  render: {
2471
- sections: [{ title: "auth status", lines: [...hostLines, "Status: pending"] }],
2472
- actions: [{ label: "Run", command: "deepline auth wait" }]
2573
+ sections: [
2574
+ {
2575
+ title: "auth status",
2576
+ lines: [...hostLines, "Status: not connected"]
2577
+ }
2578
+ ],
2579
+ actions: [{ label: "Run", command: "deepline auth register" }]
2473
2580
  }
2474
- }, { json: jsonOutput });
2475
- return EXIT_OK;
2476
- }
2477
- printCommandEnvelope({
2478
- ...hostStatusPayload ?? { host: baseUrl },
2479
- status: "not connected",
2480
- connected: false,
2481
- next: "deepline auth register",
2482
- render: {
2483
- sections: [{ title: "auth status", lines: [...hostLines, "Status: not connected"] }],
2484
- actions: [{ label: "Run", command: "deepline auth register" }]
2485
- }
2486
- }, { json: jsonOutput });
2581
+ },
2582
+ { json: jsonOutput }
2583
+ );
2487
2584
  return EXIT_OK;
2488
2585
  }
2489
- const { status, data } = await httpJson("POST", `${baseUrl}/api/v2/auth/cli/status`, apiKey, {
2490
- api_key: apiKey,
2491
- reveal
2492
- });
2586
+ const { status, data } = await httpJson(
2587
+ "POST",
2588
+ `${baseUrl}/api/v2/auth/cli/status`,
2589
+ apiKey,
2590
+ {
2591
+ api_key: apiKey,
2592
+ reveal
2593
+ }
2594
+ );
2493
2595
  if (status === 401 || status === 403) {
2494
- printCommandEnvelope({
2495
- ...hostStatusPayload ?? { host: baseUrl },
2496
- status: "unauthorized",
2497
- connected: false,
2498
- next: "deepline auth register",
2499
- render: {
2500
- sections: [{ title: "auth status", lines: [...hostLines, "Status: unauthorized"] }],
2501
- actions: [{ label: "Run", command: "deepline auth register" }]
2502
- }
2503
- }, { json: jsonOutput });
2596
+ printCommandEnvelope(
2597
+ {
2598
+ ...hostStatusPayload ?? { host: baseUrl },
2599
+ status: "unauthorized",
2600
+ connected: false,
2601
+ next: "deepline auth register",
2602
+ render: {
2603
+ sections: [
2604
+ {
2605
+ title: "auth status",
2606
+ lines: [...hostLines, "Status: unauthorized"]
2607
+ }
2608
+ ],
2609
+ actions: [{ label: "Run", command: "deepline auth register" }]
2610
+ }
2611
+ },
2612
+ { json: jsonOutput }
2613
+ );
2504
2614
  return EXIT_AUTH;
2505
2615
  }
2506
2616
  if (status >= 400) {
@@ -2527,35 +2637,44 @@ async function handleStatus(args) {
2527
2637
  if (reveal) {
2528
2638
  const apiKeyResp = String(data.api_key || apiKey);
2529
2639
  if (apiKeyResp) {
2530
- saveEnvValues({
2531
- [HOST_URL_ENV]: baseUrl,
2532
- [API_KEY_ENV]: apiKeyResp
2533
- }, baseUrl);
2640
+ saveEnvValues(
2641
+ {
2642
+ [HOST_URL_ENV]: baseUrl,
2643
+ [API_KEY_ENV]: apiKeyResp
2644
+ },
2645
+ baseUrl
2646
+ );
2534
2647
  savedApiKeyPath = envFilePath(baseUrl);
2535
2648
  }
2536
2649
  }
2537
- printCommandEnvelope({
2538
- ...payload,
2539
- ...savedApiKeyPath ? { saved_api_key_path: savedApiKeyPath } : {},
2540
- render: {
2541
- sections: [
2542
- {
2543
- title: "auth status",
2544
- lines: [
2545
- ...hostLines,
2546
- `Status: ${payload.status}`,
2547
- `Rate limit tier: ${payload.rateLimitTier}`,
2548
- ...payload.workspace.name ? [`Workspace: ${payload.workspace.name}`] : [],
2549
- ...payload.workspace.slug ? [`Workspace slug: ${payload.workspace.slug}`] : [],
2550
- ...payload.workspace.id != null ? [`Org ID: ${payload.workspace.id}`] : [],
2551
- ...payload.user.id != null ? [`User ID: ${payload.user.id}`] : [],
2552
- ...payload.examples.length > 0 ? ["Examples:", ...payload.examples.slice(0, 3).map((example) => ` ${String(example)}`)] : [],
2553
- ...savedApiKeyPath ? [`Saved API key to ${savedApiKeyPath}`] : []
2554
- ]
2555
- }
2556
- ]
2557
- }
2558
- }, { json: jsonOutput });
2650
+ printCommandEnvelope(
2651
+ {
2652
+ ...payload,
2653
+ ...savedApiKeyPath ? { saved_api_key_path: savedApiKeyPath } : {},
2654
+ render: {
2655
+ sections: [
2656
+ {
2657
+ title: "auth status",
2658
+ lines: [
2659
+ ...hostLines,
2660
+ `Status: ${payload.status}`,
2661
+ `Rate limit tier: ${payload.rateLimitTier}`,
2662
+ ...payload.workspace.name ? [`Workspace: ${payload.workspace.name}`] : [],
2663
+ ...payload.workspace.slug ? [`Workspace slug: ${payload.workspace.slug}`] : [],
2664
+ ...payload.workspace.id != null ? [`Org ID: ${payload.workspace.id}`] : [],
2665
+ ...payload.user.id != null ? [`User ID: ${payload.user.id}`] : [],
2666
+ ...payload.examples.length > 0 ? [
2667
+ "Examples:",
2668
+ ...payload.examples.slice(0, 3).map((example) => ` ${String(example)}`)
2669
+ ] : [],
2670
+ ...savedApiKeyPath ? [`Saved API key to ${savedApiKeyPath}`] : []
2671
+ ]
2672
+ }
2673
+ ]
2674
+ }
2675
+ },
2676
+ { json: jsonOutput }
2677
+ );
2559
2678
  return EXIT_OK;
2560
2679
  }
2561
2680
  function registerAuthCommands(program) {
@@ -2575,7 +2694,9 @@ Notes:
2575
2694
  Auth status shows the target host and active workspace without printing secrets.
2576
2695
  `
2577
2696
  );
2578
- auth.command("register").description("Register this device and open the approval page in your browser.").addHelpText(
2697
+ auth.command("register").description(
2698
+ "Register this device and open the approval page in your browser."
2699
+ ).addHelpText(
2579
2700
  "after",
2580
2701
  `
2581
2702
  Notes:
@@ -2622,7 +2743,10 @@ Examples:
2622
2743
  deepline auth status
2623
2744
  deepline auth status --json
2624
2745
  `
2625
- ).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) => {
2746
+ ).option(
2747
+ "--reveal",
2748
+ "Persist the revealed API key back to the host auth file"
2749
+ ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(async (options) => {
2626
2750
  process.exitCode = await handleStatus([
2627
2751
  ...options.reveal ? ["--reveal"] : [],
2628
2752
  ...options.json ? ["--json"] : []
@@ -2647,7 +2771,9 @@ function recentUsageLines(entries) {
2647
2771
  const op = `${humanize(entry.provider)} ${humanize(entry.operation)}`.trim();
2648
2772
  const charge = entry.billing_mode === "no_bill" ? "free" : `${entry.credits ?? 0} cr`;
2649
2773
  const status = entry.status || "completed";
2650
- lines.push(`${op} | ${charge} | ${status} | ${entry.created_at || "unknown"}`);
2774
+ lines.push(
2775
+ `${op} | ${charge} | ${status} | ${entry.created_at || "unknown"}`
2776
+ );
2651
2777
  }
2652
2778
  return lines;
2653
2779
  }
@@ -2701,16 +2827,21 @@ function defaultLedgerExportPath() {
2701
2827
  }
2702
2828
  async function handleBalance(options) {
2703
2829
  const { http } = getAuthedHttpClient();
2704
- const payload = await http.get("/api/v2/billing/balance");
2830
+ const payload = await http.get(
2831
+ "/api/v2/billing/balance"
2832
+ );
2705
2833
  const status = String(payload.balance_status || "");
2706
2834
  const lines = status === "no_billing" ? [
2707
2835
  "Balance: 0 credits",
2708
2836
  "Billing: No billing account or payment method set up for this workspace."
2709
2837
  ] : [`Balance: ${payload.balance ?? "(unknown)"} credits`];
2710
- printCommandEnvelope({
2711
- ...payload,
2712
- render: { sections: [{ title: "billing balance", lines }] }
2713
- }, { json: options.json });
2838
+ printCommandEnvelope(
2839
+ {
2840
+ ...payload,
2841
+ render: { sections: [{ title: "billing balance", lines }] }
2842
+ },
2843
+ { json: options.json }
2844
+ );
2714
2845
  return;
2715
2846
  }
2716
2847
  async function handleUsage(options) {
@@ -2719,7 +2850,9 @@ async function handleUsage(options) {
2719
2850
  if (options.limit) params.set("recent_limit", options.limit);
2720
2851
  if (options.offset) params.set("recent_offset", options.offset);
2721
2852
  const suffix = Array.from(params).length > 0 ? `?${params.toString()}` : "";
2722
- const payload = await http.get(`/api/v2/billing/usage${suffix}`);
2853
+ const payload = await http.get(
2854
+ `/api/v2/billing/usage${suffix}`
2855
+ );
2723
2856
  const usage = payload.usage ?? {};
2724
2857
  const quota = payload.quota ?? {};
2725
2858
  const recent = payload.recent ?? {};
@@ -2727,24 +2860,34 @@ async function handleUsage(options) {
2727
2860
  `Balance: ${payload.balance ?? "(unknown)"}`,
2728
2861
  `Last 30 days spent: ${usage.month_spent_credits ?? "(unknown)"}`,
2729
2862
  `Monthly limit: ${quota.enabled ? quota.monthly_credits_limit ?? "(unknown)" : "off"}`,
2730
- ...recentUsageLines(Array.isArray(recent.entries) ? recent.entries : [])
2863
+ ...recentUsageLines(
2864
+ Array.isArray(recent.entries) ? recent.entries : []
2865
+ )
2731
2866
  ];
2732
- printCommandEnvelope({
2733
- ...payload,
2734
- render: { sections: [{ title: "billing usage", lines }] }
2735
- }, { json: options.json });
2867
+ printCommandEnvelope(
2868
+ {
2869
+ ...payload,
2870
+ render: { sections: [{ title: "billing usage", lines }] }
2871
+ },
2872
+ { json: options.json }
2873
+ );
2736
2874
  }
2737
2875
  async function handleLimit(options) {
2738
2876
  const { http } = getAuthedHttpClient();
2739
- const payload = await http.get("/api/v2/billing/limit");
2877
+ const payload = await http.get(
2878
+ "/api/v2/billing/limit"
2879
+ );
2740
2880
  const lines = payload.enabled ? [
2741
2881
  `Monthly limit: ${payload.monthly_credits_limit ?? "(unknown)"}`,
2742
2882
  `Remaining before cap: ${payload.remaining_credits ?? "(unknown)"}`
2743
2883
  ] : ["Monthly limit: off"];
2744
- printCommandEnvelope({
2745
- ...payload,
2746
- render: { sections: [{ title: "billing limit", lines }] }
2747
- }, { json: options.json });
2884
+ printCommandEnvelope(
2885
+ {
2886
+ ...payload,
2887
+ render: { sections: [{ title: "billing limit", lines }] }
2888
+ },
2889
+ { json: options.json }
2890
+ );
2748
2891
  }
2749
2892
  async function handleSetLimit(credits, options) {
2750
2893
  const { http } = getAuthedHttpClient();
@@ -2752,26 +2895,53 @@ async function handleSetLimit(credits, options) {
2752
2895
  method: "PUT",
2753
2896
  body: { monthly_credits_limit: Number.parseInt(credits, 10) }
2754
2897
  });
2755
- printCommandEnvelope({
2756
- ...payload,
2757
- render: {
2758
- sections: [{ title: "billing limit", lines: [`Monthly billing limit set to ${credits} credits.`] }]
2759
- }
2760
- }, { json: options.json });
2898
+ printCommandEnvelope(
2899
+ {
2900
+ ...payload,
2901
+ render: {
2902
+ sections: [
2903
+ {
2904
+ title: "billing limit",
2905
+ lines: [`Monthly billing limit set to ${credits} credits.`]
2906
+ }
2907
+ ]
2908
+ }
2909
+ },
2910
+ { json: options.json }
2911
+ );
2761
2912
  }
2762
2913
  async function handleLimitOff(options) {
2763
2914
  const { http } = getAuthedHttpClient();
2764
- const payload = await http.request("/api/v2/billing/limit", { method: "DELETE" });
2765
- printCommandEnvelope({
2766
- ...payload,
2767
- render: { sections: [{ title: "billing limit", lines: ["Monthly billing limit is now off."] }] }
2768
- }, { json: options.json });
2915
+ const payload = await http.request("/api/v2/billing/limit", {
2916
+ method: "DELETE"
2917
+ });
2918
+ printCommandEnvelope(
2919
+ {
2920
+ ...payload,
2921
+ render: {
2922
+ sections: [
2923
+ {
2924
+ title: "billing limit",
2925
+ lines: ["Monthly billing limit is now off."]
2926
+ }
2927
+ ]
2928
+ }
2929
+ },
2930
+ { json: options.json }
2931
+ );
2769
2932
  }
2770
2933
  async function handleHistory(options) {
2771
2934
  const { http } = getAuthedHttpClient();
2772
- const windows = { "1d": 86400, "1w": 604800, "1m": 2592e3, "1y": 31536e3 };
2935
+ const windows = {
2936
+ "1d": 86400,
2937
+ "1w": 604800,
2938
+ "1m": 2592e3,
2939
+ "1y": 31536e3
2940
+ };
2773
2941
  const sinceAt = Math.max(0, Math.floor(Date.now() / 1e3) - windows[options.time]) * 1e3;
2774
- const payload = await http.get(`/api/v2/billing/ledger?since_at=${sinceAt}&limit=5000`);
2942
+ const payload = await http.get(
2943
+ `/api/v2/billing/ledger?since_at=${sinceAt}&limit=5000`
2944
+ );
2775
2945
  const entries = Array.isArray(payload.entries) ? payload.entries : [];
2776
2946
  const rows = entries.map((entry) => {
2777
2947
  const metadata = entry.metadata ?? {};
@@ -2783,21 +2953,30 @@ async function handleHistory(options) {
2783
2953
  operation: metadata.operation ?? ""
2784
2954
  };
2785
2955
  });
2786
- const outputPath = await writeCsvRowsFile(`billing-history-${options.time}`, rows);
2787
- printCommandEnvelope({
2788
- output_path: outputPath,
2789
- row_count: rows.length,
2790
- time_window: options.time,
2791
- render: {
2792
- sections: [
2793
- {
2794
- title: "billing history",
2795
- lines: [`Billing history written to ${outputPath}`, `${rows.length} row(s) exported.`]
2796
- }
2797
- ]
2956
+ const outputPath = await writeCsvRowsFile(
2957
+ `billing-history-${options.time}`,
2958
+ rows
2959
+ );
2960
+ printCommandEnvelope(
2961
+ {
2962
+ output_path: outputPath,
2963
+ row_count: rows.length,
2964
+ time_window: options.time,
2965
+ render: {
2966
+ sections: [
2967
+ {
2968
+ title: "billing history",
2969
+ lines: [
2970
+ `Billing history written to ${outputPath}`,
2971
+ `${rows.length} row(s) exported.`
2972
+ ]
2973
+ }
2974
+ ]
2975
+ },
2976
+ local: { output_path: outputPath }
2798
2977
  },
2799
- local: { output_path: outputPath }
2800
- }, { json: options.json });
2978
+ { json: options.json }
2979
+ );
2801
2980
  }
2802
2981
  async function handleLedgerExportAll(options) {
2803
2982
  const { http } = getAuthedHttpClient();
@@ -2829,51 +3008,75 @@ async function handleLedgerExportAll(options) {
2829
3008
  if (nextCursor === cursor) break;
2830
3009
  cursor = nextCursor;
2831
3010
  }
2832
- printCommandEnvelope({
2833
- output_path: outputPath,
2834
- row_count: summary.row_count,
2835
- net_delta_credits: summary.net_delta_credits,
2836
- scope: "current_auth_context",
2837
- render: {
2838
- sections: [
2839
- {
2840
- title: "billing ledger",
2841
- lines: [
2842
- `Billing ledger written to ${outputPath}`,
2843
- `${summary.row_count} row(s) exported for the current auth context.`,
2844
- `Net ledger delta: ${summary.net_delta_credits} Deepline Credits`
2845
- ]
2846
- }
2847
- ]
3011
+ printCommandEnvelope(
3012
+ {
3013
+ output_path: outputPath,
3014
+ row_count: summary.row_count,
3015
+ net_delta_credits: summary.net_delta_credits,
3016
+ scope: "current_auth_context",
3017
+ render: {
3018
+ sections: [
3019
+ {
3020
+ title: "billing ledger",
3021
+ lines: [
3022
+ `Billing ledger written to ${outputPath}`,
3023
+ `${summary.row_count} row(s) exported for the current auth context.`,
3024
+ `Net ledger delta: ${summary.net_delta_credits} Deepline Credits`
3025
+ ]
3026
+ }
3027
+ ]
3028
+ },
3029
+ local: { output_path: outputPath }
2848
3030
  },
2849
- local: { output_path: outputPath }
2850
- }, { json: options.json });
3031
+ { json: options.json }
3032
+ );
2851
3033
  }
2852
3034
  async function handleCheckout(options) {
2853
3035
  const { http } = getAuthedHttpClient();
2854
- const payload = await http.post("/api/v2/billing/checkout", {
2855
- ...options.tier ? { tierId: options.tier } : {},
2856
- ...options.credits ? { credits: Number.parseInt(options.credits, 10) } : {},
2857
- ...options.discountCode ? { discountCode: options.discountCode } : {}
2858
- });
3036
+ const payload = await http.post(
3037
+ "/api/v2/billing/checkout",
3038
+ {
3039
+ ...options.tier ? { tierId: options.tier } : {},
3040
+ ...options.credits ? { credits: Number.parseInt(options.credits, 10) } : {},
3041
+ ...options.discountCode ? { discountCode: options.discountCode } : {}
3042
+ }
3043
+ );
2859
3044
  const url = String(payload.url || payload.checkout_url || "");
2860
3045
  if (!options.json && !options.noOpen && url) openInBrowser(url);
2861
- printCommandEnvelope({
2862
- ...payload,
2863
- render: { sections: [{ title: "billing checkout", lines: [url || "Checkout session created."] }] }
2864
- }, { json: options.json });
3046
+ printCommandEnvelope(
3047
+ {
3048
+ ...payload,
3049
+ render: {
3050
+ sections: [
3051
+ {
3052
+ title: "billing checkout",
3053
+ lines: [url || "Checkout session created."]
3054
+ }
3055
+ ]
3056
+ }
3057
+ },
3058
+ { json: options.json }
3059
+ );
2865
3060
  }
2866
3061
  async function handleRedeemCode(code, options) {
2867
3062
  const { http } = getAuthedHttpClient();
2868
- const payload = await http.post("/api/v2/billing/checkout", {
2869
- discountCode: code
2870
- });
3063
+ const payload = await http.post(
3064
+ "/api/v2/billing/checkout",
3065
+ {
3066
+ discountCode: code
3067
+ }
3068
+ );
2871
3069
  const url = String(payload.url || payload.checkout_url || "");
2872
3070
  if (!options.json && !options.noOpen && url) openInBrowser(url);
2873
- printCommandEnvelope({
2874
- ...payload,
2875
- render: { sections: [{ title: "billing code", lines: [url || "Code redeemed."] }] }
2876
- }, { json: options.json });
3071
+ printCommandEnvelope(
3072
+ {
3073
+ ...payload,
3074
+ render: {
3075
+ sections: [{ title: "billing code", lines: [url || "Code redeemed."] }]
3076
+ }
3077
+ },
3078
+ { json: options.json }
3079
+ );
2877
3080
  }
2878
3081
  function registerBillingCommands(program) {
2879
3082
  const billing = program.command("billing").description("Inspect balance, usage, limits, and checkout flows.").addHelpText(
@@ -2981,7 +3184,10 @@ Examples:
2981
3184
  deepline billing ledger export all
2982
3185
  deepline billing ledger export all --json
2983
3186
  `
2984
- ).option("--output <path>", "Write CSV to an explicit path").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLedgerExportAll)
3187
+ ).option("--output <path>", "Write CSV to an explicit path").option(
3188
+ "--json",
3189
+ "Emit JSON output. Also automatic when stdout is piped"
3190
+ ).action(handleLedgerExportAll)
2985
3191
  )
2986
3192
  );
2987
3193
  billing.command("history").description("Export billing ledger history to CSV.").addHelpText(
@@ -2996,7 +3202,9 @@ Examples:
2996
3202
  deepline billing history --time 1y --json
2997
3203
  `
2998
3204
  ).requiredOption("--time <window>", "Rolling time window: 1d, 1w, 1m, or 1y").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleHistory);
2999
- billing.command("checkout").description("Create a checkout session and optionally open it in your browser.").addHelpText(
3205
+ billing.command("checkout").description(
3206
+ "Create a checkout session and optionally open it in your browser."
3207
+ ).addHelpText(
3000
3208
  "after",
3001
3209
  `
3002
3210
  Notes:
@@ -3042,12 +3250,18 @@ function formatDatasetExecutionStats(raw, denominator) {
3042
3250
  readCount(raw.completed),
3043
3251
  denominator
3044
3252
  ),
3045
- "completed:reused": datasetSummaryPercentText(readCount(raw.cached), denominator),
3253
+ "completed:reused": datasetSummaryPercentText(
3254
+ readCount(raw.cached),
3255
+ denominator
3256
+ ),
3046
3257
  "skipped:condition": datasetSummaryPercentText(
3047
3258
  readCount(raw.skipped),
3048
3259
  denominator
3049
3260
  ),
3050
- "skipped:missed": datasetSummaryPercentText(readCount(raw.missed), denominator),
3261
+ "skipped:missed": datasetSummaryPercentText(
3262
+ readCount(raw.missed),
3263
+ denominator
3264
+ ),
3051
3265
  failed: datasetSummaryPercentText(readCount(raw.failed), denominator)
3052
3266
  };
3053
3267
  }
@@ -3228,19 +3442,51 @@ function collectCanonicalRowsInfos(statusOrResult) {
3228
3442
  const metadata = isRecord2(result._metadata) ? result._metadata : null;
3229
3443
  const totalFromMetadata = metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count;
3230
3444
  const candidates = [
3231
- { source: "result.contacts", value: result.contacts, total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count },
3232
- { source: "result.previewRows", value: result.previewRows, total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count },
3233
- { source: "result.rows", value: result.rows, total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count },
3234
- { source: "result.results", value: result.results, total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count }
3445
+ {
3446
+ source: "result.contacts",
3447
+ value: result.contacts,
3448
+ total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
3449
+ },
3450
+ {
3451
+ source: "result.previewRows",
3452
+ value: result.previewRows,
3453
+ total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
3454
+ },
3455
+ {
3456
+ source: "result.rows",
3457
+ value: result.rows,
3458
+ total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
3459
+ },
3460
+ {
3461
+ source: "result.results",
3462
+ value: result.results,
3463
+ total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
3464
+ }
3235
3465
  ];
3236
3466
  if (isRecord2(result.output)) {
3237
3467
  const outputMetadata = isRecord2(result.output._metadata) ? result.output._metadata : null;
3238
3468
  const outputTotalFromMetadata = outputMetadata?.totalRows ?? outputMetadata?.rowCount ?? outputMetadata?.count;
3239
3469
  candidates.push(
3240
- { source: "result.output.contacts", value: result.output.contacts, total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count },
3241
- { source: "result.output.previewRows", value: result.output.previewRows, total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count },
3242
- { source: "result.output.rows", value: result.output.rows, total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count },
3243
- { source: "result.output.results", value: result.output.results, total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count }
3470
+ {
3471
+ source: "result.output.contacts",
3472
+ value: result.output.contacts,
3473
+ total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count
3474
+ },
3475
+ {
3476
+ source: "result.output.previewRows",
3477
+ value: result.output.previewRows,
3478
+ total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count
3479
+ },
3480
+ {
3481
+ source: "result.output.rows",
3482
+ value: result.output.rows,
3483
+ total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count
3484
+ },
3485
+ {
3486
+ source: "result.output.results",
3487
+ value: result.output.results,
3488
+ total: outputTotalFromMetadata ?? result.output.totalRows ?? result.output.rowCount ?? result.output.count
3489
+ }
3244
3490
  );
3245
3491
  }
3246
3492
  collectDatasetCandidates({
@@ -3378,7 +3624,8 @@ function compactCell(value) {
3378
3624
  const parsed = parseJsonLike(value);
3379
3625
  if (parsed === null || parsed === void 0) return "";
3380
3626
  if (typeof parsed === "string") return compactScalar(parsed, 120);
3381
- if (typeof parsed === "number" || typeof parsed === "boolean") return String(parsed);
3627
+ if (typeof parsed === "number" || typeof parsed === "boolean")
3628
+ return String(parsed);
3382
3629
  if (Array.isArray(parsed)) {
3383
3630
  if (parsed.length === 0) return "";
3384
3631
  if (parsed.slice(0, 3).every((item) => ["string", "number", "boolean"].includes(typeof item))) {
@@ -3392,7 +3639,15 @@ function compactCell(value) {
3392
3639
  return compactCell(parsed[key]);
3393
3640
  }
3394
3641
  }
3395
- const preferred = ["email", "status", "name", "full_name", "title", "domain", "linkedin_url"];
3642
+ const preferred = [
3643
+ "email",
3644
+ "status",
3645
+ "name",
3646
+ "full_name",
3647
+ "title",
3648
+ "domain",
3649
+ "linkedin_url"
3650
+ ];
3396
3651
  const parts = [];
3397
3652
  for (const key of preferred) {
3398
3653
  if (parsed[key] !== null && parsed[key] !== void 0 && parsed[key] !== "") {
@@ -3434,7 +3689,10 @@ function buildDatasetStats(rows, totalRows = rows.length, columns = inferColumns
3434
3689
  };
3435
3690
  const rawExecutionStats = executionStats?.columnStats[column];
3436
3691
  if (rawExecutionStats) {
3437
- stat3.execution = formatDatasetExecutionStats(rawExecutionStats, totalRows);
3692
+ stat3.execution = formatDatasetExecutionStats(
3693
+ rawExecutionStats,
3694
+ totalRows
3695
+ );
3438
3696
  }
3439
3697
  if (sampleValue !== void 0 && sampleValueType) {
3440
3698
  stat3.sample_value = sampleValue;
@@ -3476,11 +3734,7 @@ function writeCanonicalRowsCsv(rowsInfo, outPath) {
3476
3734
  const rows = dataExportRows(sanitized.rows);
3477
3735
  const columns = dataExportColumns(rows, sanitized.columns);
3478
3736
  const resolved = resolve4(outPath);
3479
- writeFileSync4(
3480
- resolved,
3481
- csvStringFromRows(rows, columns),
3482
- "utf-8"
3483
- );
3737
+ writeFileSync4(resolved, csvStringFromRows(rows, columns), "utf-8");
3484
3738
  return resolved;
3485
3739
  }
3486
3740
 
@@ -3491,7 +3745,9 @@ function parseRowRange(raw) {
3491
3745
  const start = Number.parseInt(startRaw ?? "", 10);
3492
3746
  const end = Number.parseInt(endRaw ?? "", 10);
3493
3747
  if (!Number.isFinite(start) || !Number.isFinite(end) || start < 0 || end < start) {
3494
- throw new Error(`Invalid --rows value: ${source} (expected start:end, e.g. 0:19).`);
3748
+ throw new Error(
3749
+ `Invalid --rows value: ${source} (expected start:end, e.g. 0:19).`
3750
+ );
3495
3751
  }
3496
3752
  return [start, end];
3497
3753
  }
@@ -3502,7 +3758,9 @@ function selectColumns(rows, rawColumns) {
3502
3758
  if (!rawColumns?.trim()) return rows;
3503
3759
  const requested = rawColumns.split(",").map((part) => part.trim()).filter(Boolean);
3504
3760
  if (requested.length === 0) {
3505
- throw new Error("Invalid --columns value: provide at least one column name.");
3761
+ throw new Error(
3762
+ "Invalid --columns value: provide at least one column name."
3763
+ );
3506
3764
  }
3507
3765
  const available = new Set(Object.keys(rows[0] ?? {}));
3508
3766
  const missing = requested.filter((column) => !available.has(column));
@@ -3539,13 +3797,22 @@ function renderTable(rows, totalRows, verbose) {
3539
3797
  return display.padEnd(widths[column]);
3540
3798
  }).join(" | ")
3541
3799
  );
3542
- return [header, divider, ...body, "", `showing ${rows.length} row(s) of ${totalRows}`].join("\n");
3800
+ return [
3801
+ header,
3802
+ divider,
3803
+ ...body,
3804
+ "",
3805
+ `showing ${rows.length} row(s) of ${totalRows}`
3806
+ ].join("\n");
3543
3807
  }
3544
3808
  async function handleCsvShow(options) {
3545
3809
  const csvPath = options.csv;
3546
3810
  const [rowStart, rowEnd] = parseRowRange(options.rows);
3547
3811
  const allRows = readCsvRows(csvPath);
3548
- const selected = selectColumns(selectRows(allRows, rowStart, rowEnd), options.columns);
3812
+ const selected = selectColumns(
3813
+ selectRows(allRows, rowStart, rowEnd),
3814
+ options.columns
3815
+ );
3549
3816
  const format = options.format ?? "json";
3550
3817
  if (options.summary) {
3551
3818
  printJson(buildDatasetStats(selected, allRows.length));
@@ -3562,13 +3829,17 @@ async function handleCsvShow(options) {
3562
3829
  process.stdout.write(`${columns.join(",")}
3563
3830
  `);
3564
3831
  for (const row of selected) {
3565
- process.stdout.write(`${columns.map((column) => JSON.stringify(row[column] ?? "")).join(",")}
3566
- `);
3832
+ process.stdout.write(
3833
+ `${columns.map((column) => JSON.stringify(row[column] ?? "")).join(",")}
3834
+ `
3835
+ );
3567
3836
  }
3568
3837
  return;
3569
3838
  }
3570
- process.stdout.write(`${renderTable(selected, allRows.length, Boolean(options.verbose))}
3571
- `);
3839
+ process.stdout.write(
3840
+ `${renderTable(selected, allRows.length, Boolean(options.verbose))}
3841
+ `
3842
+ );
3572
3843
  }
3573
3844
  function registerCsvCommands(program) {
3574
3845
  const csv = program.command("csv").description("Inspect local CSV files.").addHelpText(
@@ -3601,12 +3872,7 @@ Examples:
3601
3872
  // src/cli/commands/db.ts
3602
3873
  import { writeFileSync as writeFileSync5 } from "fs";
3603
3874
  import { resolve as resolve5 } from "path";
3604
- var CUSTOMER_DB_QUERY_FORMATS = /* @__PURE__ */ new Set([
3605
- "table",
3606
- "json",
3607
- "csv",
3608
- "markdown"
3609
- ]);
3875
+ var CUSTOMER_DB_QUERY_FORMATS = /* @__PURE__ */ new Set(["table", "json", "csv", "markdown"]);
3610
3876
  function parsePositiveInteger(value, flagName) {
3611
3877
  const parsed = Number.parseInt(value, 10);
3612
3878
  if (!Number.isFinite(parsed) || parsed <= 0) {
@@ -3621,10 +3887,17 @@ function formatCell(value) {
3621
3887
  }
3622
3888
  function tableLines(result) {
3623
3889
  const rows = dataExportRows(customerDbRows(result));
3624
- const responseColumns = dataExportColumns(rows, customerDbColumnNames(result));
3625
- const businessColumns = responseColumns.filter((column) => !column.startsWith("_"));
3890
+ const responseColumns = dataExportColumns(
3891
+ rows,
3892
+ customerDbColumnNames(result)
3893
+ );
3894
+ const businessColumns = responseColumns.filter(
3895
+ (column) => !column.startsWith("_")
3896
+ );
3626
3897
  const columns = businessColumns.length > 0 ? businessColumns : responseColumns;
3627
- const hiddenColumns = responseColumns.filter((column) => !columns.includes(column));
3898
+ const hiddenColumns = responseColumns.filter(
3899
+ (column) => !columns.includes(column)
3900
+ );
3628
3901
  const lines = [
3629
3902
  `${result.command} returned ${result.row_count_returned} row(s)` + (result.truncated ? " (truncated)" : "")
3630
3903
  ];
@@ -3632,7 +3905,9 @@ function tableLines(result) {
3632
3905
  lines.push(
3633
3906
  `Showing ${columns.length}/${responseColumns.length} columns; hidden metadata: ${hiddenColumns.join(", ")}`
3634
3907
  );
3635
- lines.push("Use --json or select metadata columns explicitly when you need run ids/errors/stages.");
3908
+ lines.push(
3909
+ "Use --json or select metadata columns explicitly when you need run ids/errors/stages."
3910
+ );
3636
3911
  }
3637
3912
  if (rows.length === 0) {
3638
3913
  return lines;
@@ -3646,7 +3921,9 @@ function tableLines(result) {
3646
3921
  )
3647
3922
  )
3648
3923
  );
3649
- lines.push(columns.map((column, index) => column.padEnd(widths[index])).join(" "));
3924
+ lines.push(
3925
+ columns.map((column, index) => column.padEnd(widths[index])).join(" ")
3926
+ );
3650
3927
  lines.push(widths.map((width) => "-".repeat(width)).join(" "));
3651
3928
  for (const row of rows) {
3652
3929
  lines.push(
@@ -3722,10 +3999,12 @@ async function handleDbQuery(args) {
3722
3999
  const explicitJsonOutput = args.includes("--json");
3723
4000
  const client = new DeeplineClient();
3724
4001
  const result = await client.queryCustomerDb({ sql, maxRows });
3725
- const toolCommand = `deepline tools execute query_customer_db --payload ${JSON.stringify({
3726
- sql,
3727
- ...maxRows ? { max_rows: maxRows } : {}
3728
- })} --json`;
4002
+ const toolCommand = `deepline tools execute query_customer_db --payload ${JSON.stringify(
4003
+ {
4004
+ sql,
4005
+ ...maxRows ? { max_rows: maxRows } : {}
4006
+ }
4007
+ )} --json`;
3729
4008
  if (format === "csv") {
3730
4009
  if (outPath) {
3731
4010
  const exportedPath = writeCustomerDbCsv(result, outPath);
@@ -3753,7 +4032,10 @@ async function handleDbQuery(args) {
3753
4032
  }),
3754
4033
  {
3755
4034
  json: explicitJsonOutput,
3756
- text: dataExportCsvString(customerDbRows(result), customerDbColumnNames(result))
4035
+ text: dataExportCsvString(
4036
+ customerDbRows(result),
4037
+ customerDbColumnNames(result)
4038
+ )
3757
4039
  }
3758
4040
  );
3759
4041
  return 0;
@@ -3795,14 +4077,17 @@ async function handleDbQuery(args) {
3795
4077
  );
3796
4078
  return 0;
3797
4079
  }
3798
- printCommandEnvelope({
3799
- ...result,
3800
- next: { toolEquivalent: toolCommand },
3801
- render: {
3802
- sections: [{ title: "customer db query", lines: tableLines(result) }],
3803
- actions: [{ label: "Tool equivalent", command: toolCommand }]
3804
- }
3805
- }, { json: jsonOutput || format === "json" });
4080
+ printCommandEnvelope(
4081
+ {
4082
+ ...result,
4083
+ next: { toolEquivalent: toolCommand },
4084
+ render: {
4085
+ sections: [{ title: "customer db query", lines: tableLines(result) }],
4086
+ actions: [{ label: "Tool equivalent", command: toolCommand }]
4087
+ }
4088
+ },
4089
+ { json: jsonOutput || format === "json" }
4090
+ );
3806
4091
  return 0;
3807
4092
  }
3808
4093
  function registerDbCommands(program) {
@@ -3838,7 +4123,10 @@ Examples:
3838
4123
  deepline db query --sql "select * from contacts limit 20" --format csv --out contacts.csv
3839
4124
  deepline db query --sql "select domain, name from companies limit 20" --format markdown
3840
4125
  `
3841
- ).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) => {
4126
+ ).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(
4127
+ "--json",
4128
+ "Emit raw JSON response. Also automatic when stdout is piped"
4129
+ ).action(async (options) => {
3842
4130
  process.exitCode = await handleDbQuery([
3843
4131
  "--sql",
3844
4132
  options.sql,
@@ -3859,12 +4147,17 @@ async function handleFeedback(text, options) {
3859
4147
  ...options.command ? { command: options.command } : {},
3860
4148
  ...options.payload ? { payload: options.payload } : {}
3861
4149
  });
3862
- printCommandEnvelope({
3863
- ...response,
3864
- render: {
3865
- sections: [{ title: "feedback", lines: ["Feedback submitted. Thank you."] }]
3866
- }
3867
- }, { json: options.json });
4150
+ printCommandEnvelope(
4151
+ {
4152
+ ...response,
4153
+ render: {
4154
+ sections: [
4155
+ { title: "feedback", lines: ["Feedback submitted. Thank you."] }
4156
+ ]
4157
+ }
4158
+ },
4159
+ { json: options.json }
4160
+ );
3868
4161
  }
3869
4162
  function registerFeedbackCommands(program) {
3870
4163
  const feedback = program.command("feedback").description("Submit CLI feedback to Deepline.").addHelpText(
@@ -3907,76 +4200,106 @@ async function handleOrgList(options) {
3907
4200
  const config = resolveConfig();
3908
4201
  const http = new HttpClient(config);
3909
4202
  const payload = await fetchOrganizations(http, config.apiKey);
3910
- printCommandEnvelope({
3911
- ...payload,
3912
- render: {
3913
- sections: [{ title: "Your organizations:", lines: orgListLines(payload.organizations) }]
3914
- }
3915
- }, { json: options.json });
4203
+ printCommandEnvelope(
4204
+ {
4205
+ ...payload,
4206
+ render: {
4207
+ sections: [
4208
+ {
4209
+ title: "Your organizations:",
4210
+ lines: orgListLines(payload.organizations)
4211
+ }
4212
+ ]
4213
+ }
4214
+ },
4215
+ { json: options.json }
4216
+ );
3916
4217
  }
3917
4218
  async function handleOrgSwitch(selection, options) {
3918
4219
  const config = resolveConfig();
3919
4220
  const http = new HttpClient(config);
3920
4221
  const payload = await fetchOrganizations(http, config.apiKey);
3921
4222
  if (!selection && !options.orgId) {
3922
- printCommandEnvelope({
3923
- ...payload,
3924
- next: { switch: "deepline org switch <number>" },
3925
- render: {
3926
- sections: [{ title: "Your organizations:", lines: orgListLines(payload.organizations) }],
3927
- actions: [{ label: "Run", command: "deepline org switch <number>" }]
3928
- }
3929
- }, { json: options.json });
4223
+ printCommandEnvelope(
4224
+ {
4225
+ ...payload,
4226
+ next: { switch: "deepline org switch <number>" },
4227
+ render: {
4228
+ sections: [
4229
+ {
4230
+ title: "Your organizations:",
4231
+ lines: orgListLines(payload.organizations)
4232
+ }
4233
+ ],
4234
+ actions: [{ label: "Run", command: "deepline org switch <number>" }]
4235
+ }
4236
+ },
4237
+ { json: options.json }
4238
+ );
3930
4239
  return;
3931
4240
  }
3932
- let target = payload.organizations.find((org) => org.org_id === options.orgId);
4241
+ let target = payload.organizations.find(
4242
+ (org) => org.org_id === options.orgId
4243
+ );
3933
4244
  if (!target && selection) {
3934
4245
  const index = Number.parseInt(selection, 10);
3935
4246
  if (Number.isFinite(index) && index >= 1 && index <= payload.organizations.length) {
3936
4247
  target = payload.organizations[index - 1];
3937
4248
  } else {
3938
- target = payload.organizations.find((org) => org.name === selection || org.org_id === selection);
4249
+ target = payload.organizations.find(
4250
+ (org) => org.name === selection || org.org_id === selection
4251
+ );
3939
4252
  }
3940
4253
  }
3941
4254
  if (!target) {
3942
4255
  throw new Error("Could not resolve the selected organization.");
3943
4256
  }
3944
4257
  if (target.is_current) {
3945
- printCommandEnvelope({
3946
- ok: true,
3947
- unchanged: true,
3948
- organization: target,
3949
- render: { sections: [{ title: "org switch", lines: [`Already on ${target.name}.`] }] }
3950
- }, { json: options.json });
4258
+ printCommandEnvelope(
4259
+ {
4260
+ ok: true,
4261
+ unchanged: true,
4262
+ organization: target,
4263
+ render: {
4264
+ sections: [
4265
+ { title: "org switch", lines: [`Already on ${target.name}.`] }
4266
+ ]
4267
+ }
4268
+ },
4269
+ { json: options.json }
4270
+ );
3951
4271
  return;
3952
4272
  }
3953
- const switched = await http.post(
3954
- "/api/v2/auth/cli/switch",
3955
- { api_key: config.apiKey, org_id: target.org_id }
3956
- );
4273
+ const switched = await http.post("/api/v2/auth/cli/switch", {
4274
+ api_key: config.apiKey,
4275
+ org_id: target.org_id
4276
+ });
3957
4277
  saveHostEnvValues(config.baseUrl, {
3958
4278
  DEEPLINE_API_KEY: switched.api_key,
3959
4279
  DEEPLINE_ACTIVE_ORG_ID: switched.org_id,
3960
4280
  DEEPLINE_ACTIVE_ORG_NAME: switched.org_name
3961
4281
  });
3962
4282
  const { api_key: _apiKey, ...publicSwitched } = switched;
3963
- printCommandEnvelope({
3964
- ok: true,
3965
- host_env_path: hostEnvFilePath(config.baseUrl),
3966
- ...publicSwitched,
3967
- api_key_saved: true,
3968
- render: {
3969
- sections: [
3970
- {
3971
- title: "org switch",
3972
- lines: [
3973
- `Switched to ${switched.org_name}.`,
3974
- `Saved host auth in ${hostEnvFilePath(config.baseUrl)}`
3975
- ]
3976
- }
3977
- ]
3978
- }
3979
- }, { json: options.json });
4283
+ printCommandEnvelope(
4284
+ {
4285
+ ok: true,
4286
+ host_env_path: hostEnvFilePath(config.baseUrl),
4287
+ ...publicSwitched,
4288
+ api_key_saved: true,
4289
+ render: {
4290
+ sections: [
4291
+ {
4292
+ title: "org switch",
4293
+ lines: [
4294
+ `Switched to ${switched.org_name}.`,
4295
+ `Saved host auth in ${hostEnvFilePath(config.baseUrl)}`
4296
+ ]
4297
+ }
4298
+ ]
4299
+ }
4300
+ },
4301
+ { json: options.json }
4302
+ );
3980
4303
  }
3981
4304
  function registerOrgCommands(program) {
3982
4305
  const org = program.command("org").description("List and switch organizations.").addHelpText(
@@ -4003,7 +4326,9 @@ Examples:
4003
4326
  deepline org list --json
4004
4327
  `
4005
4328
  ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleOrgList);
4006
- org.command("switch [selection]").description("Switch to another organization and save the new API key in the host auth file.").addHelpText(
4329
+ org.command("switch [selection]").description(
4330
+ "Switch to another organization and save the new API key in the host auth file."
4331
+ ).addHelpText(
4007
4332
  "after",
4008
4333
  `
4009
4334
  Notes:
@@ -4021,23 +4346,23 @@ Examples:
4021
4346
  // src/cli/commands/play.ts
4022
4347
  import { createHash as createHash3 } from "crypto";
4023
4348
  import {
4024
- existsSync as existsSync6,
4025
- readFileSync as readFileSync5,
4349
+ existsSync as existsSync7,
4350
+ readFileSync as readFileSync6,
4026
4351
  readdirSync,
4027
4352
  realpathSync,
4028
4353
  writeFileSync as writeFileSync6
4029
4354
  } from "fs";
4030
- import { basename as basename3, dirname as dirname8, join as join6, resolve as resolve10 } from "path";
4355
+ import { basename as basename3, dirname as dirname8, join as join7, resolve as resolve10 } from "path";
4031
4356
 
4032
4357
  // src/plays/bundle-play-file.ts
4033
4358
  import { tmpdir as tmpdir2 } from "os";
4034
- import { dirname as dirname7, join as join5, resolve as resolve8 } from "path";
4359
+ import { dirname as dirname7, join as join6, resolve as resolve8 } from "path";
4035
4360
  import { fileURLToPath } from "url";
4036
- import { existsSync as existsSync5 } from "fs";
4361
+ import { existsSync as existsSync6 } from "fs";
4037
4362
 
4038
4363
  // ../shared_libs/plays/bundling/index.ts
4039
4364
  import { createHash } from "crypto";
4040
- import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
4365
+ import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
4041
4366
  import { mkdir as mkdir3, readFile, realpath, stat, writeFile as writeFile3 } from "fs/promises";
4042
4367
  import { tmpdir } from "os";
4043
4368
  import {
@@ -4045,7 +4370,7 @@ import {
4045
4370
  dirname as dirname5,
4046
4371
  extname,
4047
4372
  isAbsolute,
4048
- join as join3,
4373
+ join as join4,
4049
4374
  resolve as resolve6
4050
4375
  } from "path";
4051
4376
  import { builtinModules } from "module";
@@ -4106,7 +4431,7 @@ function buildPlayContractCompatibility(input) {
4106
4431
  var PLAY_BUNDLE_CACHE_VERSION = 24;
4107
4432
  var MAX_PLAY_BUNDLE_BYTES = 30 * 1024 * 1024;
4108
4433
  var MAX_ESM_WORKERS_BUNDLE_BYTES = 115e4;
4109
- var PLAY_ARTIFACT_CACHE_DIR = join3(
4434
+ var PLAY_ARTIFACT_CACHE_DIR = join4(
4110
4435
  tmpdir(),
4111
4436
  `deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION}`
4112
4437
  );
@@ -4326,7 +4651,7 @@ function extractDefinedPlayName(sourceCode) {
4326
4651
  }
4327
4652
  function readPackageVersionFromPackageJson(packageJsonPath, packageName) {
4328
4653
  try {
4329
- const packageJson = JSON.parse(readFileSync4(packageJsonPath, "utf-8"));
4654
+ const packageJson = JSON.parse(readFileSync5(packageJsonPath, "utf-8"));
4330
4655
  if (packageJson.name === packageName && typeof packageJson.version === "string") {
4331
4656
  return packageJson.version;
4332
4657
  }
@@ -4338,13 +4663,13 @@ function readPackageVersionFromPackageJson(packageJsonPath, packageName) {
4338
4663
  function findPackageJsonPathFrom(startDir, packageName) {
4339
4664
  let current = resolve6(startDir);
4340
4665
  while (true) {
4341
- const packageJsonPath = join3(
4666
+ const packageJsonPath = join4(
4342
4667
  current,
4343
4668
  "node_modules",
4344
4669
  packageName,
4345
4670
  "package.json"
4346
4671
  );
4347
- if (existsSync4(packageJsonPath)) {
4672
+ if (existsSync5(packageJsonPath)) {
4348
4673
  return packageJsonPath;
4349
4674
  }
4350
4675
  const parent = dirname5(current);
@@ -4369,16 +4694,16 @@ function findPackageJsonPath(packageName, fromFile, adapter) {
4369
4694
  const packageJsonPath = findPackageJsonPathFrom(normalized, packageName);
4370
4695
  if (packageJsonPath) return packageJsonPath;
4371
4696
  }
4372
- const adapterNodeModulesPackageJson = join3(
4697
+ const adapterNodeModulesPackageJson = join4(
4373
4698
  adapter.nodeModulesDir,
4374
4699
  packageName,
4375
4700
  "package.json"
4376
4701
  );
4377
- return existsSync4(adapterNodeModulesPackageJson) ? adapterNodeModulesPackageJson : null;
4702
+ return existsSync5(adapterNodeModulesPackageJson) ? adapterNodeModulesPackageJson : null;
4378
4703
  }
4379
4704
  function localSdkAliasPlugin(adapter, options) {
4380
4705
  const entryFile = options?.workersRuntime ? adapter.sdkWorkersEntryFile : adapter.sdkEntryFile;
4381
- if (!existsSync4(entryFile)) {
4706
+ if (!existsSync5(entryFile)) {
4382
4707
  return null;
4383
4708
  }
4384
4709
  return {
@@ -4388,7 +4713,7 @@ function localSdkAliasPlugin(adapter, options) {
4388
4713
  path: entryFile
4389
4714
  }));
4390
4715
  buildContext.onResolve({ filter: /^deepline\/helpers$/ }, () => ({
4391
- path: join3(adapter.sdkSourceRoot, "helpers.ts")
4716
+ path: join4(adapter.sdkSourceRoot, "helpers.ts")
4392
4717
  }));
4393
4718
  }
4394
4719
  };
@@ -4619,7 +4944,7 @@ async function resolveLocalImport(fromFile, specifier) {
4619
4944
  ...SOURCE_EXTENSIONS.map((extension) => `${base}${extension}`)
4620
4945
  );
4621
4946
  candidates.push(
4622
- ...SOURCE_EXTENSIONS.map((extension) => join3(base, `index${extension}`))
4947
+ ...SOURCE_EXTENSIONS.map((extension) => join4(base, `index${extension}`))
4623
4948
  );
4624
4949
  } else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
4625
4950
  const stem = base.slice(0, -explicitExtension.length);
@@ -4638,9 +4963,9 @@ async function resolveLocalImport(fromFile, specifier) {
4638
4963
  }
4639
4964
  function resolvePackageImport(specifier, fromFile, adapter) {
4640
4965
  const packageName = getPackageName(specifier);
4641
- if (packageName === "deepline" && existsSync4(adapter.sdkPackageJson)) {
4966
+ if (packageName === "deepline" && existsSync5(adapter.sdkPackageJson)) {
4642
4967
  const packageJson = JSON.parse(
4643
- readFileSync4(adapter.sdkPackageJson, "utf-8")
4968
+ readFileSync5(adapter.sdkPackageJson, "utf-8")
4644
4969
  );
4645
4970
  return {
4646
4971
  name: "deepline",
@@ -4787,7 +5112,7 @@ async function computeWorkersHarnessFingerprintWithAdapter(adapter) {
4787
5112
  const parts = [];
4788
5113
  for (const name of tsFiles) {
4789
5114
  const contents = await readFile(
4790
- join3(adapter.workersHarnessFilesDir, name),
5115
+ join4(adapter.workersHarnessFilesDir, name),
4791
5116
  "utf-8"
4792
5117
  );
4793
5118
  parts.push({ name, hash: sha256(contents) });
@@ -4795,7 +5120,7 @@ async function computeWorkersHarnessFingerprintWithAdapter(adapter) {
4795
5120
  return sha256(JSON.stringify(parts));
4796
5121
  }
4797
5122
  function artifactCachePath(graphHash, artifactKind, adapter) {
4798
- return join3(
5123
+ return join4(
4799
5124
  adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR,
4800
5125
  `${graphHash}.${artifactKind}.json`
4801
5126
  );
@@ -5228,8 +5553,26 @@ function resolveExecutionProfile(override) {
5228
5553
  // src/plays/local-file-discovery.ts
5229
5554
  import { createHash as createHash2 } from "crypto";
5230
5555
  import { readFile as readFile2, stat as stat2 } from "fs/promises";
5231
- import { basename as basename2, dirname as dirname6, extname as extname2, isAbsolute as isAbsolute2, join as join4, relative, resolve as resolve7 } from "path";
5232
- var SOURCE_EXTENSIONS2 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"];
5556
+ import {
5557
+ basename as basename2,
5558
+ dirname as dirname6,
5559
+ extname as extname2,
5560
+ isAbsolute as isAbsolute2,
5561
+ join as join5,
5562
+ relative,
5563
+ resolve as resolve7
5564
+ } from "path";
5565
+ var SOURCE_EXTENSIONS2 = [
5566
+ ".ts",
5567
+ ".tsx",
5568
+ ".mts",
5569
+ ".cts",
5570
+ ".js",
5571
+ ".jsx",
5572
+ ".mjs",
5573
+ ".cjs",
5574
+ ".json"
5575
+ ];
5233
5576
  function sha2562(buffer) {
5234
5577
  return createHash2("sha256").update(buffer).digest("hex");
5235
5578
  }
@@ -5253,7 +5596,9 @@ function unquoteStringLiteral2(literal) {
5253
5596
  return null;
5254
5597
  }
5255
5598
  try {
5256
- return JSON.parse(quote === '"' ? trimmed : `"${trimmed.slice(1, -1).replace(/"/g, '\\"')}"`);
5599
+ return JSON.parse(
5600
+ quote === '"' ? trimmed : `"${trimmed.slice(1, -1).replace(/"/g, '\\"')}"`
5601
+ );
5257
5602
  } catch {
5258
5603
  return trimmed.slice(1, -1);
5259
5604
  }
@@ -5314,7 +5659,9 @@ function resolveStringExpression(expression, constants) {
5314
5659
  }
5315
5660
  const parts = splitTopLevelPlus(value);
5316
5661
  if (parts) {
5317
- const resolved = parts.map((part) => resolveStringExpression(part, constants));
5662
+ const resolved = parts.map(
5663
+ (part) => resolveStringExpression(part, constants)
5664
+ );
5318
5665
  return resolved.every((part) => part != null) ? resolved.join("") : null;
5319
5666
  }
5320
5667
  return null;
@@ -5322,7 +5669,9 @@ function resolveStringExpression(expression, constants) {
5322
5669
  function collectTopLevelStringConstants(sourceCode) {
5323
5670
  const constants = /* @__PURE__ */ new Map();
5324
5671
  const source = stripCommentsToSpaces2(sourceCode);
5325
- for (const match of source.matchAll(/(?:^|\n)\s*const\s+([A-Za-z_$][\w$]*)\s*=\s*([^;\n]+)/g)) {
5672
+ for (const match of source.matchAll(
5673
+ /(?:^|\n)\s*const\s+([A-Za-z_$][\w$]*)\s*=\s*([^;\n]+)/g
5674
+ )) {
5326
5675
  const resolved = resolveStringExpression(match[2], constants);
5327
5676
  if (resolved != null) {
5328
5677
  constants.set(match[1], resolved);
@@ -5411,7 +5760,9 @@ function localImportSpecifiers(sourceCode) {
5411
5760
  )) {
5412
5761
  if (match[1]?.startsWith(".")) specifiers.push(match[1]);
5413
5762
  }
5414
- for (const match of source.matchAll(/\brequire\s*\(\s*(['"])(\.[^'"]*)\1\s*\)/g)) {
5763
+ for (const match of source.matchAll(
5764
+ /\brequire\s*\(\s*(['"])(\.[^'"]*)\1\s*\)/g
5765
+ )) {
5415
5766
  specifiers.push(match[2]);
5416
5767
  }
5417
5768
  return specifiers;
@@ -5433,18 +5784,26 @@ async function resolveLocalImport2(fromFile, specifier) {
5433
5784
  const candidates = [base];
5434
5785
  const explicitExtension = extname2(base).toLowerCase();
5435
5786
  if (!explicitExtension) {
5436
- candidates.push(...SOURCE_EXTENSIONS2.map((extension) => `${base}${extension}`));
5437
- candidates.push(...SOURCE_EXTENSIONS2.map((extension) => join4(base, `index${extension}`)));
5787
+ candidates.push(
5788
+ ...SOURCE_EXTENSIONS2.map((extension) => `${base}${extension}`)
5789
+ );
5790
+ candidates.push(
5791
+ ...SOURCE_EXTENSIONS2.map((extension) => join5(base, `index${extension}`))
5792
+ );
5438
5793
  } else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
5439
5794
  const stem = base.slice(0, -explicitExtension.length);
5440
- candidates.push(...SOURCE_EXTENSIONS2.map((extension) => `${stem}${extension}`));
5795
+ candidates.push(
5796
+ ...SOURCE_EXTENSIONS2.map((extension) => `${stem}${extension}`)
5797
+ );
5441
5798
  }
5442
5799
  for (const candidate of candidates) {
5443
5800
  if (await fileExists2(candidate)) {
5444
5801
  return candidate;
5445
5802
  }
5446
5803
  }
5447
- throw new Error(`Could not resolve local import "${specifier}" from ${fromFile}`);
5804
+ throw new Error(
5805
+ `Could not resolve local import "${specifier}" from ${fromFile}`
5806
+ );
5448
5807
  }
5449
5808
  async function discoverPackagedLocalFiles(entryFile) {
5450
5809
  const absoluteEntryFile = resolve7(entryFile);
@@ -5462,12 +5821,17 @@ async function discoverPackagedLocalFiles(entryFile) {
5462
5821
  const scanSource = stripCommentsToSpaces2(sourceCode);
5463
5822
  const constants = collectTopLevelStringConstants(sourceCode);
5464
5823
  const childVisits = [];
5465
- for (const match of scanSource.matchAll(/\b([A-Za-z_$][\w$]*)\s*\.\s*csv\b/g)) {
5824
+ for (const match of scanSource.matchAll(
5825
+ /\b([A-Za-z_$][\w$]*)\s*\.\s*csv\b/g
5826
+ )) {
5466
5827
  const target = match[1];
5467
5828
  if (target !== "ctx" && !target.endsWith("Ctx")) {
5468
5829
  continue;
5469
5830
  }
5470
- const openParen = findCallOpenParen(scanSource, match.index + match[0].length);
5831
+ const openParen = findCallOpenParen(
5832
+ scanSource,
5833
+ match.index + match[0].length
5834
+ );
5471
5835
  if (openParen < 0) {
5472
5836
  continue;
5473
5837
  }
@@ -5527,11 +5891,11 @@ var PLAY_BUNDLE_CACHE_VERSION2 = 30;
5527
5891
  var MODULE_DIR = dirname7(fileURLToPath(import.meta.url));
5528
5892
  var SDK_PACKAGE_ROOT = resolve8(MODULE_DIR, "..", "..");
5529
5893
  var SOURCE_REPO_ROOT = resolve8(SDK_PACKAGE_ROOT, "..");
5530
- var HAS_SOURCE_BUNDLING_SOURCES = existsSync5(
5894
+ var HAS_SOURCE_BUNDLING_SOURCES = existsSync6(
5531
5895
  resolve8(SOURCE_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
5532
5896
  );
5533
5897
  var PACKAGED_REPO_ROOT = resolve8(SDK_PACKAGE_ROOT, "dist", "repo");
5534
- var HAS_PACKAGED_BUNDLING_SOURCES = existsSync5(
5898
+ var HAS_PACKAGED_BUNDLING_SOURCES = existsSync6(
5535
5899
  resolve8(PACKAGED_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
5536
5900
  );
5537
5901
  var PROJECT_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? SOURCE_REPO_ROOT : HAS_PACKAGED_BUNDLING_SOURCES ? PACKAGED_REPO_ROOT : resolve8(SDK_PACKAGE_ROOT, "..");
@@ -5577,14 +5941,14 @@ function createSdkPlayBundlingAdapter() {
5577
5941
  return {
5578
5942
  projectRoot: PROJECT_ROOT,
5579
5943
  nodeModulesDir: resolve8(PROJECT_ROOT, "node_modules"),
5580
- cacheDir: join5(
5944
+ cacheDir: join6(
5581
5945
  tmpdir2(),
5582
5946
  `deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION2}`
5583
5947
  ),
5584
5948
  sdkSourceRoot: SDK_SOURCE_ROOT,
5585
5949
  sdkPackageJson: SDK_PACKAGE_JSON,
5586
5950
  sdkEntryFile: SDK_ENTRY_FILE,
5587
- sdkTypesEntryFile: HAS_SOURCE_BUNDLING_SOURCES || !existsSync5(SDK_TYPES_ENTRY_FILE) ? SDK_ENTRY_FILE : SDK_TYPES_ENTRY_FILE,
5951
+ sdkTypesEntryFile: HAS_SOURCE_BUNDLING_SOURCES || !existsSync6(SDK_TYPES_ENTRY_FILE) ? SDK_ENTRY_FILE : SDK_TYPES_ENTRY_FILE,
5588
5952
  sdkWorkersEntryFile: SDK_WORKERS_ENTRY_FILE,
5589
5953
  workersHarnessEntryFile: WORKERS_HARNESS_ENTRY_FILE,
5590
5954
  workersHarnessFilesDir: WORKERS_HARNESS_FILES_DIR,
@@ -7558,8 +7922,8 @@ function materializeRemotePlaySource(input) {
7558
7922
  return null;
7559
7923
  }
7560
7924
  const outputPath = input.outPath ?? defaultMaterializedPlayPath(input.playName);
7561
- if (existsSync6(outputPath)) {
7562
- const existingSource = readFileSync5(outputPath, "utf-8");
7925
+ if (existsSync7(outputPath)) {
7926
+ const existingSource = readFileSync6(outputPath, "utf-8");
7563
7927
  if (existingSource === input.sourceCode) {
7564
7928
  return { path: outputPath, status: "unchanged", created: false };
7565
7929
  }
@@ -7611,7 +7975,7 @@ function extractPlayName(code, filePath) {
7611
7975
  throw buildMissingDefinePlayError(filePath);
7612
7976
  }
7613
7977
  function isFileTarget(target) {
7614
- return existsSync6(resolve10(target));
7978
+ return existsSync7(resolve10(target));
7615
7979
  }
7616
7980
  function looksLikeRunId(target) {
7617
7981
  return /^play\/[^/]+\/run\/[^/]+/.test(target.trim());
@@ -7640,7 +8004,7 @@ function parsePositiveInteger3(value, flagName) {
7640
8004
  return parsed;
7641
8005
  }
7642
8006
  function parseJsonInput(raw) {
7643
- const source = raw.startsWith("@") ? readFileSync5(resolve10(raw.slice(1)), "utf-8") : raw;
8007
+ const source = raw.startsWith("@") ? readFileSync6(resolve10(raw.slice(1)), "utf-8") : raw;
7644
8008
  const parsed = JSON.parse(source);
7645
8009
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
7646
8010
  throw new Error("--input must be a JSON object.");
@@ -7742,7 +8106,7 @@ function fileInputBindingsFromStaticPipeline(staticPipeline) {
7742
8106
  function isLocalFilePathValue(value) {
7743
8107
  if (typeof value !== "string" || !value.trim()) return false;
7744
8108
  if (/^[a-z][a-z0-9+.-]*:\/\//i.test(value.trim())) return false;
7745
- return existsSync6(resolve10(value));
8109
+ return existsSync7(resolve10(value));
7746
8110
  }
7747
8111
  function inputContainsLocalFilePath(value) {
7748
8112
  if (isLocalFilePathValue(value)) {
@@ -7803,7 +8167,7 @@ async function stageFileInputArgs(input) {
7803
8167
  };
7804
8168
  }
7805
8169
  function stageFile(logicalPath, absolutePath) {
7806
- const buffer = readFileSync5(absolutePath);
8170
+ const buffer = readFileSync6(absolutePath);
7807
8171
  return {
7808
8172
  logicalPath,
7809
8173
  contentBase64: buffer.toString("base64"),
@@ -9258,7 +9622,9 @@ function buildRunPackageTextLines(packaged) {
9258
9622
  lines.push(` ${kind} ${id}: ${stepStatus}${rowCount}`);
9259
9623
  lines.push(...formatPackageDatasetSummaryLines(output?.summary));
9260
9624
  if (previewRows !== null) {
9261
- lines.push(` preview=${previewRows}${preview?.truncated ? " truncated" : ""}`);
9625
+ lines.push(
9626
+ ` preview=${previewRows}${preview?.truncated ? " truncated" : ""}`
9627
+ );
9262
9628
  }
9263
9629
  }
9264
9630
  const next = packaged.next && typeof packaged.next === "object" && !Array.isArray(packaged.next) ? packaged.next : {};
@@ -10037,7 +10403,7 @@ async function handlePlayCheck(args) {
10037
10403
  return 1;
10038
10404
  }
10039
10405
  const absolutePlayPath = resolve10(options.target);
10040
- const sourceCode = readFileSync5(absolutePlayPath, "utf-8");
10406
+ const sourceCode = readFileSync6(absolutePlayPath, "utf-8");
10041
10407
  let graph;
10042
10408
  try {
10043
10409
  graph = await collectBundledPlayGraph(absolutePlayPath);
@@ -10121,7 +10487,7 @@ async function handleFileBackedRun(options) {
10121
10487
  const sourceCode = traceCliSync(
10122
10488
  "cli.play_file_read_source",
10123
10489
  { targetKind: "file" },
10124
- () => readFileSync5(absolutePlayPath, "utf-8")
10490
+ () => readFileSync6(absolutePlayPath, "utf-8")
10125
10491
  );
10126
10492
  const runtimeInput = options.input ? { ...options.input } : {};
10127
10493
  let graph;
@@ -10408,7 +10774,7 @@ async function handlePlayRun(args) {
10408
10774
  const resolved = resolve10(options.target.path);
10409
10775
  console.error(`File not found: ${resolved}`);
10410
10776
  const dir = dirname8(resolved);
10411
- if (existsSync6(dir)) {
10777
+ if (existsSync7(dir)) {
10412
10778
  const base = basename3(resolved);
10413
10779
  try {
10414
10780
  const siblings = readdirSync(dir).filter(
@@ -10417,7 +10783,7 @@ async function handlePlayRun(args) {
10417
10783
  if (siblings.length > 0) {
10418
10784
  console.error(`Did you mean one of these?`);
10419
10785
  for (const s of siblings.slice(0, 5)) {
10420
- console.error(` ${join6(dir, s)}`);
10786
+ console.error(` ${join7(dir, s)}`);
10421
10787
  }
10422
10788
  }
10423
10789
  } catch {
@@ -10755,7 +11121,7 @@ async function handlePlayGet(args) {
10755
11121
  outPath = resolve10(args[++index]);
10756
11122
  }
10757
11123
  }
10758
- const playName = isFileTarget(target) ? extractPlayName(readFileSync5(resolve10(target), "utf-8"), resolve10(target)) : parseReferencedPlayTarget2(target).playName;
11124
+ const playName = isFileTarget(target) ? extractPlayName(readFileSync6(resolve10(target), "utf-8"), resolve10(target)) : parseReferencedPlayTarget2(target).playName;
10759
11125
  const detail = isFileTarget(target) ? await client.getPlay(playName) : await assertCanonicalNamedPlayReference(client, target);
10760
11126
  const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
10761
11127
  const materializedFile = outPath ? materializeRemotePlaySource({
@@ -11060,7 +11426,9 @@ function matchesPlayGrepQuery(value, query, mode) {
11060
11426
  async function handlePlayGrep(args) {
11061
11427
  const query = args[0]?.trim();
11062
11428
  if (!query) {
11063
- console.error("Usage: deepline plays grep <query> [--mode all|any|phrase] [--compact] [--json]");
11429
+ console.error(
11430
+ "Usage: deepline plays grep <query> [--mode all|any|phrase] [--compact] [--json]"
11431
+ );
11064
11432
  return 1;
11065
11433
  }
11066
11434
  let mode = "all";
@@ -11093,13 +11461,15 @@ async function handlePlayGrep(args) {
11093
11461
  )
11094
11462
  ).map((play) => summarizePlayListItemForCli(play, { compact }));
11095
11463
  if (argsWantJson(args)) {
11096
- process.stdout.write(`${JSON.stringify({
11097
- plays,
11098
- count: plays.length,
11099
- query,
11100
- grep: { mode, terms: parsePlayGrepTerms(query, mode) }
11101
- })}
11102
- `);
11464
+ process.stdout.write(
11465
+ `${JSON.stringify({
11466
+ plays,
11467
+ count: plays.length,
11468
+ query,
11469
+ grep: { mode, terms: parsePlayGrepTerms(query, mode) }
11470
+ })}
11471
+ `
11472
+ );
11103
11473
  return 0;
11104
11474
  }
11105
11475
  process.stdout.write(`${plays.length} plays found:
@@ -11735,12 +12105,12 @@ Examples:
11735
12105
  import { Option } from "commander";
11736
12106
  import { chmodSync, mkdtempSync, writeFileSync as writeFileSync8 } from "fs";
11737
12107
  import { tmpdir as tmpdir3 } from "os";
11738
- import { join as join8 } from "path";
12108
+ import { join as join9 } from "path";
11739
12109
 
11740
12110
  // src/tool-output.ts
11741
12111
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync7 } from "fs";
11742
- import { homedir as homedir3 } from "os";
11743
- import { join as join7 } from "path";
12112
+ import { homedir as homedir4 } from "os";
12113
+ import { join as join8 } from "path";
11744
12114
  function isPlainObject(value) {
11745
12115
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
11746
12116
  }
@@ -11762,7 +12132,9 @@ function normalizeRows(value) {
11762
12132
  });
11763
12133
  }
11764
12134
  function candidateRoots(payload) {
11765
- const roots = [{ path: null, value: payload }];
12135
+ const roots = [
12136
+ { path: null, value: payload }
12137
+ ];
11766
12138
  if (isPlainObject(payload) && isPlainObject(payload.toolResponse)) {
11767
12139
  roots.push({ path: "toolResponse", value: payload.toolResponse });
11768
12140
  if (Object.prototype.hasOwnProperty.call(payload.toolResponse, "raw")) {
@@ -11789,7 +12161,9 @@ function candidateRoots(payload) {
11789
12161
  function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
11790
12162
  if (depth > 5) return null;
11791
12163
  const directRows = normalizeRows(value);
11792
- const hasObjectRow = directRows?.some((row) => Object.keys(row).some((key) => key !== "value")) ?? false;
12164
+ const hasObjectRow = directRows?.some(
12165
+ (row) => Object.keys(row).some((key) => key !== "value")
12166
+ ) ?? false;
11793
12167
  let best = directRows && directRows.length > 0 && hasObjectRow ? { path: pathPrefix, rows: directRows } : null;
11794
12168
  if (!isPlainObject(value)) {
11795
12169
  return best;
@@ -11805,7 +12179,9 @@ function findBestArrayCandidate(value, pathPrefix = "", depth = 0) {
11805
12179
  return best;
11806
12180
  }
11807
12181
  function tryConvertToList(payload, options) {
11808
- const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
12182
+ const listExtractorPaths = Array.isArray(options?.listExtractorPaths) ? options?.listExtractorPaths.filter(
12183
+ (entry) => typeof entry === "string" && entry.trim().length > 0
12184
+ ) : [];
11809
12185
  if (listExtractorPaths.length > 0) {
11810
12186
  for (const root of candidateRoots(payload)) {
11811
12187
  for (const extractorPath of listExtractorPaths) {
@@ -11830,19 +12206,19 @@ function tryConvertToList(payload, options) {
11830
12206
  return null;
11831
12207
  }
11832
12208
  function ensureOutputDir() {
11833
- const outputDir = join7(homedir3(), ".local", "share", "deepline", "data");
12209
+ const outputDir = join8(homedir4(), ".local", "share", "deepline", "data");
11834
12210
  mkdirSync4(outputDir, { recursive: true });
11835
12211
  return outputDir;
11836
12212
  }
11837
12213
  function writeJsonOutputFile(payload, stem) {
11838
12214
  const outputDir = ensureOutputDir();
11839
- const outputPath = join7(outputDir, `${stem}_${Date.now()}.json`);
12215
+ const outputPath = join8(outputDir, `${stem}_${Date.now()}.json`);
11840
12216
  writeFileSync7(outputPath, JSON.stringify(payload, null, 2), "utf-8");
11841
12217
  return outputPath;
11842
12218
  }
11843
12219
  function writeCsvOutputFile(rows, stem) {
11844
12220
  const outputDir = ensureOutputDir();
11845
- const outputPath = join7(outputDir, `${stem}_${Date.now()}.csv`);
12221
+ const outputPath = join8(outputDir, `${stem}_${Date.now()}.csv`);
11846
12222
  const seen = /* @__PURE__ */ new Set();
11847
12223
  const columns = [];
11848
12224
  for (const row of rows) {
@@ -11871,7 +12247,9 @@ function writeCsvOutputFile(rows, stem) {
11871
12247
  const previewColumns = columns.slice(0, 5);
11872
12248
  const preview = [
11873
12249
  previewColumns.join(","),
11874
- ...previewRows.map((row) => previewColumns.map((column) => escapeCell(row[column])).join(","))
12250
+ ...previewRows.map(
12251
+ (row) => previewColumns.map((column) => escapeCell(row[column])).join(",")
12252
+ )
11875
12253
  ].join("\n");
11876
12254
  return {
11877
12255
  path: outputPath,
@@ -11884,9 +12262,11 @@ function extractSummaryFields(payload) {
11884
12262
  const candidates = candidateRoots(payload);
11885
12263
  for (const candidate of candidates) {
11886
12264
  if (!isPlainObject(candidate.value)) continue;
11887
- const summaryEntries = Object.entries(candidate.value).filter(([, value]) => {
11888
- return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
11889
- });
12265
+ const summaryEntries = Object.entries(candidate.value).filter(
12266
+ ([, value]) => {
12267
+ return value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
12268
+ }
12269
+ );
11890
12270
  if (summaryEntries.length === 0) continue;
11891
12271
  return Object.fromEntries(summaryEntries);
11892
12272
  }
@@ -12416,8 +12796,16 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
12416
12796
  arrayField(toolExecutionResult, "extractedValues", "extracted_values")
12417
12797
  );
12418
12798
  const cost = recordField(tool, "cost");
12419
- const deeplineCredits = numberField(tool, "deeplineCreditsPerPricingUnit", "deepline_credits_per_pricing_unit");
12420
- const deeplineUsdPerPricingUnit = numberField(tool, "deeplineUsdPerPricingUnit", "deepline_usd_per_pricing_unit");
12799
+ const deeplineCredits = numberField(
12800
+ tool,
12801
+ "deeplineCreditsPerPricingUnit",
12802
+ "deepline_credits_per_pricing_unit"
12803
+ );
12804
+ const deeplineUsdPerPricingUnit = numberField(
12805
+ tool,
12806
+ "deeplineUsdPerPricingUnit",
12807
+ "deepline_usd_per_pricing_unit"
12808
+ );
12421
12809
  const starterScript = seedToolListScript({
12422
12810
  toolId,
12423
12811
  payload: samplePayloadForInputFields(inputFields),
@@ -12505,7 +12893,9 @@ function printCompactToolContract(tool, requestedToolId) {
12505
12893
  if (starterPath) {
12506
12894
  console.log("");
12507
12895
  console.log(`Starter script: ${starterPath}`);
12508
- console.log("Copy it into your project and replace the sample input with the proven probe payload.");
12896
+ console.log(
12897
+ "Copy it into your project and replace the sample input with the proven probe payload."
12898
+ );
12509
12899
  }
12510
12900
  if (listGetters.length || valueGetters.length) {
12511
12901
  console.log("");
@@ -12668,7 +13058,9 @@ function playResultExpression(entry) {
12668
13058
  }
12669
13059
  function toolMetadataJsonForDescribe(tool, requestedToolId) {
12670
13060
  const toolId = String(tool.toolId || requestedToolId);
12671
- const inputFields = toolInputFieldsForDisplay(recordField(tool, "inputSchema", "input_schema"));
13061
+ const inputFields = toolInputFieldsForDisplay(
13062
+ recordField(tool, "inputSchema", "input_schema")
13063
+ );
12672
13064
  const starterScript = seedToolListScript({
12673
13065
  toolId,
12674
13066
  payload: samplePayloadForInputFields(inputFields),
@@ -12693,7 +13085,9 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
12693
13085
  toolId,
12694
13086
  provider: tool.provider,
12695
13087
  displayName: tool.displayName,
12696
- usageGuidance: usageGuidanceWithAccessDefaults(recordField(tool, "usageGuidance", "usage_guidance")),
13088
+ usageGuidance: usageGuidanceWithAccessDefaults(
13089
+ recordField(tool, "usageGuidance", "usage_guidance")
13090
+ ),
12697
13091
  runtimeOutputHelp: {
12698
13092
  contract: "tools describe shows declared schema and Deepline getters; it is not an observed provider response.",
12699
13093
  getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
@@ -12915,9 +13309,9 @@ function powerShellQuote(value) {
12915
13309
  function seedToolListScript(input) {
12916
13310
  const stem = safeFileStem(input.toolId);
12917
13311
  const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
12918
- const scriptDir = mkdtempSync(join8(tmpdir3(), "deepline-workflow-seed-"));
13312
+ const scriptDir = mkdtempSync(join9(tmpdir3(), "deepline-workflow-seed-"));
12919
13313
  chmodSync(scriptDir, 448);
12920
- const scriptPath = join8(scriptDir, fileName);
13314
+ const scriptPath = join9(scriptDir, fileName);
12921
13315
  const projectDir = `deepline/projects/${stem}-workflow`;
12922
13316
  const playName = `${stem}-workflow`;
12923
13317
  const sampleRows = input.rows.length > 0 ? `${JSON.stringify(input.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
@@ -13208,8 +13602,8 @@ async function executeTool(args) {
13208
13602
 
13209
13603
  // src/cli/commands/update.ts
13210
13604
  import { spawn } from "child_process";
13211
- import { existsSync as existsSync7 } from "fs";
13212
- import { dirname as dirname9, join as join9, resolve as resolve11 } from "path";
13605
+ import { existsSync as existsSync8 } from "fs";
13606
+ import { dirname as dirname9, join as join10, resolve as resolve11 } from "path";
13213
13607
  function posixShellQuote(value) {
13214
13608
  return `'${value.replace(/'/g, `'\\''`)}'`;
13215
13609
  }
@@ -13230,7 +13624,7 @@ function buildSourceUpdateCommand(sourceRoot) {
13230
13624
  function findRepoBackedSdkRoot(startPath) {
13231
13625
  let current = resolve11(startPath);
13232
13626
  while (true) {
13233
- if (existsSync7(join9(current, "sdk", "package.json")) && existsSync7(join9(current, "sdk", "bin", "deepline-dev.ts"))) {
13627
+ if (existsSync8(join10(current, "sdk", "package.json")) && existsSync8(join10(current, "sdk", "bin", "deepline-dev.ts"))) {
13234
13628
  return current;
13235
13629
  }
13236
13630
  const parent = dirname9(current);
@@ -13308,8 +13702,10 @@ async function handleUpdate(options) {
13308
13702
  printCommandEnvelope({ ...plan, render }, { json: false });
13309
13703
  return 0;
13310
13704
  }
13311
- process.stderr.write(`Updating Deepline SDK/CLI with: ${plan.manualCommand}
13312
- `);
13705
+ process.stderr.write(
13706
+ `Updating Deepline SDK/CLI with: ${plan.manualCommand}
13707
+ `
13708
+ );
13313
13709
  return runCommand(plan.command, plan.args);
13314
13710
  }
13315
13711
  function registerUpdateCommand(program) {
@@ -13333,9 +13729,16 @@ Examples:
13333
13729
 
13334
13730
  // src/cli/skills-sync.ts
13335
13731
  import { spawn as spawn2, spawnSync } from "child_process";
13336
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync2, writeFileSync as writeFileSync9 } from "fs";
13337
- import { homedir as homedir4 } from "os";
13338
- import { dirname as dirname10, join as join10 } from "path";
13732
+ import {
13733
+ existsSync as existsSync9,
13734
+ mkdirSync as mkdirSync5,
13735
+ readdirSync as readdirSync2,
13736
+ readFileSync as readFileSync7,
13737
+ statSync as statSync2,
13738
+ writeFileSync as writeFileSync9
13739
+ } from "fs";
13740
+ import { homedir as homedir5 } from "os";
13741
+ import { dirname as dirname10, join as join11 } from "path";
13339
13742
  var CHECK_TIMEOUT_MS2 = 3e3;
13340
13743
  var SDK_SKILL_NAME = "deepline-sdk";
13341
13744
  var SKILL_AGENTS = ["codex", "claude-code", "cursor"];
@@ -13345,14 +13748,21 @@ function shouldSkipSkillsSync() {
13345
13748
  return value === "1" || value === "true" || value === "yes" || value === "on";
13346
13749
  }
13347
13750
  function sdkSkillsVersionPath(baseUrl) {
13348
- const home = process.env.HOME?.trim() || homedir4();
13349
- return join10(home, ".local", "deepline", baseUrlSlug(baseUrl), "sdk-skills", ".version");
13751
+ const home = process.env.HOME?.trim() || homedir5();
13752
+ return join11(
13753
+ home,
13754
+ ".local",
13755
+ "deepline",
13756
+ baseUrlSlug(baseUrl),
13757
+ "sdk-skills",
13758
+ ".version"
13759
+ );
13350
13760
  }
13351
13761
  function readLocalSkillsVersion(baseUrl) {
13352
13762
  const path = sdkSkillsVersionPath(baseUrl);
13353
- if (!existsSync8(path)) return "";
13763
+ if (!existsSync9(path)) return "";
13354
13764
  try {
13355
- return readFileSync6(path, "utf-8").trim();
13765
+ return readFileSync7(path, "utf-8").trim();
13356
13766
  } catch {
13357
13767
  return "";
13358
13768
  }
@@ -13364,10 +13774,10 @@ function writeLocalSkillsVersion(baseUrl, version) {
13364
13774
  `, "utf-8");
13365
13775
  }
13366
13776
  function installedSdkSkillHasStalePositionalExecuteExamples() {
13367
- const home = process.env.HOME?.trim() || homedir4();
13777
+ const home = process.env.HOME?.trim() || homedir5();
13368
13778
  const roots = [
13369
- join10(home, ".claude", "skills", SDK_SKILL_NAME),
13370
- join10(home, ".agents", "skills", SDK_SKILL_NAME)
13779
+ join11(home, ".claude", "skills", SDK_SKILL_NAME),
13780
+ join11(home, ".agents", "skills", SDK_SKILL_NAME)
13371
13781
  ];
13372
13782
  const staleMarkers = [
13373
13783
  "ctx.tools.execute(key",
@@ -13378,21 +13788,21 @@ function installedSdkSkillHasStalePositionalExecuteExamples() {
13378
13788
  ];
13379
13789
  const scan = (dir) => {
13380
13790
  for (const entry of readdirSync2(dir)) {
13381
- const path = join10(dir, entry);
13791
+ const path = join11(dir, entry);
13382
13792
  const stat3 = statSync2(path);
13383
13793
  if (stat3.isDirectory()) {
13384
13794
  if (scan(path)) return true;
13385
13795
  continue;
13386
13796
  }
13387
13797
  if (!entry.endsWith(".md")) continue;
13388
- const text = readFileSync6(path, "utf-8");
13798
+ const text = readFileSync7(path, "utf-8");
13389
13799
  if (staleMarkers.some((marker) => text.includes(marker))) return true;
13390
13800
  }
13391
13801
  return false;
13392
13802
  };
13393
13803
  for (const root of roots) {
13394
13804
  try {
13395
- if (existsSync8(root) && scan(root)) return true;
13805
+ if (existsSync9(root) && scan(root)) return true;
13396
13806
  } catch {
13397
13807
  continue;
13398
13808
  }
@@ -13428,7 +13838,10 @@ async function fetchSkillsUpdate(baseUrl, localVersion) {
13428
13838
  }
13429
13839
  }
13430
13840
  function buildSkillsInstallArgs(baseUrl) {
13431
- const packageUrl = new URL("/.well-known/skills/index.json", baseUrl).toString();
13841
+ const packageUrl = new URL(
13842
+ "/.well-known/skills/index.json",
13843
+ baseUrl
13844
+ ).toString();
13432
13845
  return [
13433
13846
  "--yes",
13434
13847
  "skills",
@@ -13444,7 +13857,10 @@ function buildSkillsInstallArgs(baseUrl) {
13444
13857
  ];
13445
13858
  }
13446
13859
  function buildBunxSkillsInstallArgs(baseUrl) {
13447
- const packageUrl = new URL("/.well-known/skills/index.json", baseUrl).toString();
13860
+ const packageUrl = new URL(
13861
+ "/.well-known/skills/index.json",
13862
+ baseUrl
13863
+ ).toString();
13448
13864
  return [
13449
13865
  "--bun",
13450
13866
  "skills",
@@ -13588,8 +14004,8 @@ function shouldDeferSkillsSyncForCommand() {
13588
14004
  return (command === "play" || command === "plays") && subcommand === "run" && args.includes("--json");
13589
14005
  }
13590
14006
  async function runPlayRunnerHealthCheck() {
13591
- const dir = await mkdtemp(join11(tmpdir4(), "deepline-health-play-"));
13592
- const file = join11(dir, "health-check.play.ts");
14007
+ const dir = await mkdtemp(join12(tmpdir4(), "deepline-health-play-"));
14008
+ const file = join12(dir, "health-check.play.ts");
13593
14009
  try {
13594
14010
  await writeFile4(
13595
14011
  file,