deepline 0.3.23 → 0.3.24

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.
@@ -164,7 +164,7 @@ configureProxyFromEnv();
164
164
 
165
165
  // src/cli/index.ts
166
166
  import { mkdtemp as mkdtemp2, rm as rm2, writeFile as writeFile6 } from "fs/promises";
167
- import { join as join22 } from "path";
167
+ import { join as join21 } from "path";
168
168
  import { tmpdir as tmpdir6 } from "os";
169
169
  import { Command as Command4 } from "commander";
170
170
 
@@ -980,11 +980,6 @@ function getActiveProjectAuthSource(startDir = process.cwd()) {
980
980
  return loadProjectEnvCandidates(startDir)[0] ?? null;
981
981
  }
982
982
 
983
- // src/http.ts
984
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
985
- import { homedir as homedir3 } from "os";
986
- import { join as join2 } from "path";
987
-
988
983
  // ../shared_libs/plays/artifact-contract-version.ts
989
984
  var CURRENT_PLAY_ARTIFACT_CONTRACT_VERSION = 2;
990
985
 
@@ -1033,7 +1028,7 @@ var SDK_RELEASE = {
1033
1028
  // 0.3.0 introduces raw-v2: complete scrubbed provider responses are
1034
1029
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
1035
1030
  // getters keep their established compatibility behavior.
1036
- version: "0.3.23",
1031
+ version: "0.3.24",
1037
1032
  updateSummary: "New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.",
1038
1033
  contracts: {
1039
1034
  api: {
@@ -1222,6 +1217,88 @@ function detectAgentRuntime(options = {}) {
1222
1217
  return options.defaultRuntime ?? "unknown";
1223
1218
  }
1224
1219
 
1220
+ // src/skills-version.ts
1221
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
1222
+ import { dirname as dirname2, join as join2 } from "path";
1223
+ function activePluginSkillsDir() {
1224
+ const pluginMode = process.env.DEEPLINE_PLUGIN_MODE?.trim().toLowerCase();
1225
+ if (pluginMode !== "true" && pluginMode !== "1" && pluginMode !== "yes" && pluginMode !== "on") {
1226
+ return "";
1227
+ }
1228
+ const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
1229
+ return dir && existsSync2(dir) ? dir : "";
1230
+ }
1231
+ function hasActivePluginSkills() {
1232
+ return Boolean(activePluginSkillsDir());
1233
+ }
1234
+ function readPluginSkillsVersion() {
1235
+ const dir = activePluginSkillsDir();
1236
+ if (!dir) return "";
1237
+ try {
1238
+ return readFileSync2(join2(dir, ".version"), "utf-8").trim();
1239
+ } catch {
1240
+ return "";
1241
+ }
1242
+ }
1243
+ function sdkSkillsVersionPath(baseUrl, agents = []) {
1244
+ const suffix = agents.length > 0 ? `-${agents.join("-")}` : "";
1245
+ return join2(sdkCliStateDirPath(baseUrl), `skills${suffix}-version`);
1246
+ }
1247
+ function legacySdkSkillsVersionPath(baseUrl) {
1248
+ return join2(dirname2(sdkCliStateDirPath(baseUrl)), "sdk-skills", ".version");
1249
+ }
1250
+ function resolveAutoSyncSkillAgents() {
1251
+ switch (detectAgentRuntime()) {
1252
+ case "codex":
1253
+ return ["codex"];
1254
+ case "claude_code":
1255
+ return ["claude-code"];
1256
+ case "cursor":
1257
+ return ["cursor"];
1258
+ case "gemini":
1259
+ return ["gemini-cli"];
1260
+ case "antigravity":
1261
+ return ["antigravity"];
1262
+ default:
1263
+ return [];
1264
+ }
1265
+ }
1266
+ function readSdkSkillsLocalVersion(baseUrl) {
1267
+ const pluginVersion = readPluginSkillsVersion();
1268
+ if (pluginVersion) return pluginVersion;
1269
+ const agents = resolveAutoSyncSkillAgents();
1270
+ const scopedPath = sdkSkillsVersionPath(baseUrl, agents);
1271
+ if (agents.length > 0 && existsSync2(scopedPath)) {
1272
+ try {
1273
+ return readFileSync2(scopedPath, "utf-8").trim();
1274
+ } catch {
1275
+ return "";
1276
+ }
1277
+ }
1278
+ if (agents.length > 0) {
1279
+ const legacyPath = legacySdkSkillsVersionPath(baseUrl);
1280
+ if (!existsSync2(legacyPath)) return "";
1281
+ try {
1282
+ return readFileSync2(legacyPath, "utf-8").trim();
1283
+ } catch {
1284
+ return "";
1285
+ }
1286
+ }
1287
+ const path = existsSync2(sdkSkillsVersionPath(baseUrl)) ? sdkSkillsVersionPath(baseUrl) : legacySdkSkillsVersionPath(baseUrl);
1288
+ if (!existsSync2(path)) return "";
1289
+ try {
1290
+ return readFileSync2(path, "utf-8").trim();
1291
+ } catch {
1292
+ return "";
1293
+ }
1294
+ }
1295
+ function writeSdkSkillsLocalVersion(baseUrl, version, agents) {
1296
+ const path = sdkSkillsVersionPath(baseUrl, agents);
1297
+ mkdirSync2(dirname2(path), { recursive: true });
1298
+ writeFileSync2(path, `${version}
1299
+ `, "utf-8");
1300
+ }
1301
+
1225
1302
  // ../shared_libs/play-runtime/coordinator-headers.ts
1226
1303
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
1227
1304
  var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
@@ -1558,21 +1635,9 @@ var HttpClient = class {
1558
1635
  );
1559
1636
  if (explicit) return explicit;
1560
1637
  try {
1561
- const versionPath = join2(
1562
- sdkCliStateDirPath(this.config.baseUrl),
1563
- "skills-version"
1564
- );
1565
- const legacyVersionPath = join2(
1566
- process.env.HOME?.trim() || homedir3(),
1567
- ".local",
1568
- "deepline",
1569
- baseUrlSlug(this.config.baseUrl),
1570
- "sdk-skills",
1571
- ".version"
1638
+ return this.cleanDiagnosticHeader(
1639
+ readSdkSkillsLocalVersion(this.config.baseUrl)
1572
1640
  );
1573
- const resolvedPath = existsSync2(versionPath) ? versionPath : legacyVersionPath;
1574
- if (!existsSync2(resolvedPath)) return null;
1575
- return this.cleanDiagnosticHeader(readFileSync2(resolvedPath, "utf-8"));
1576
1641
  } catch {
1577
1642
  return null;
1578
1643
  }
@@ -6977,19 +7042,19 @@ var DeeplineClient = class {
6977
7042
  };
6978
7043
 
6979
7044
  // src/compat.ts
6980
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
6981
- import { homedir as homedir4 } from "os";
6982
- import { dirname as dirname2, join as join3 } from "path";
7045
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
7046
+ import { homedir as homedir3 } from "os";
7047
+ import { dirname as dirname3, join as join3 } from "path";
6983
7048
  var CHECK_TIMEOUT_MS = 2e3;
6984
7049
  var SDK_COMPATIBILITY_CACHE_TTL_MS = 5 * 60 * 1e3;
6985
7050
  function shouldSkipCompatibilityCheck() {
6986
7051
  const value = process.env.DEEPLINE_SKIP_SDK_COMPAT_CHECK?.trim().toLowerCase();
6987
7052
  return value === "1" || value === "true" || value === "yes";
6988
7053
  }
6989
- function sdkCompatibilityCachePath(baseUrl, homeDir2 = homedir4()) {
7054
+ function sdkCompatibilityCachePath(baseUrl, homeDir2 = homedir3()) {
6990
7055
  return join3(sdkCliStateDirPath(baseUrl, homeDir2), "compat-cache.json");
6991
7056
  }
6992
- function legacySdkCompatibilityCachePath(homeDir2 = homedir4()) {
7057
+ function legacySdkCompatibilityCachePath(homeDir2 = homedir3()) {
6993
7058
  return join3(homeDir2, ".cache", "deepline", "sdk-compat-cache.json");
6994
7059
  }
6995
7060
  function compatibilityCacheKey(baseUrl, command, skillsVersion) {
@@ -7040,8 +7105,8 @@ function writeCachedCompatibility(baseUrl, command, skillsVersion, response) {
7040
7105
  savedAt: Date.now(),
7041
7106
  response
7042
7107
  };
7043
- mkdirSync2(dirname2(path), { recursive: true });
7044
- writeFileSync2(path, `${JSON.stringify({ entries }, null, 2)}
7108
+ mkdirSync3(dirname3(path), { recursive: true });
7109
+ writeFileSync3(path, `${JSON.stringify({ entries }, null, 2)}
7045
7110
  `);
7046
7111
  } catch {
7047
7112
  }
@@ -7114,26 +7179,26 @@ function enforceSdkCompatibilityResponse(response) {
7114
7179
  // src/cli/commands/auth.ts
7115
7180
  import {
7116
7181
  existsSync as existsSync5,
7117
- mkdirSync as mkdirSync4,
7182
+ mkdirSync as mkdirSync5,
7118
7183
  readFileSync as readFileSync5,
7119
7184
  rmSync as rmSync2,
7120
- writeFileSync as writeFileSync4
7185
+ writeFileSync as writeFileSync5
7121
7186
  } from "fs";
7122
7187
  import { hostname } from "os";
7123
- import { dirname as dirname4, join as join5 } from "path";
7188
+ import { dirname as dirname5, join as join5 } from "path";
7124
7189
 
7125
7190
  // src/cli/utils.ts
7126
7191
  import { createHash } from "crypto";
7127
7192
  import {
7128
7193
  existsSync as existsSync4,
7129
- mkdirSync as mkdirSync3,
7194
+ mkdirSync as mkdirSync4,
7130
7195
  readFileSync as readFileSync4,
7131
7196
  rmSync,
7132
- writeFileSync as writeFileSync3
7197
+ writeFileSync as writeFileSync4
7133
7198
  } from "fs";
7134
7199
  import { mkdir, writeFile } from "fs/promises";
7135
- import { homedir as homedir5, tmpdir, userInfo } from "os";
7136
- import { dirname as dirname3, join as join4, resolve as resolve2 } from "path";
7200
+ import { homedir as homedir4, tmpdir, userInfo } from "os";
7201
+ import { dirname as dirname4, join as join4, resolve as resolve2 } from "path";
7137
7202
  import * as childProcess from "child_process";
7138
7203
  import { parse } from "csv-parse/sync";
7139
7204
  import { stringify } from "csv-stringify/sync";
@@ -7179,9 +7244,9 @@ function claimBrowserOpen(now = Date.now(), stateDir, targetUrl) {
7179
7244
  const targetKey = browserOpenTargetKey(targetUrl);
7180
7245
  let locked = false;
7181
7246
  try {
7182
- mkdirSync3(dirname3(statePath), { recursive: true, mode: 448 });
7247
+ mkdirSync4(dirname4(statePath), { recursive: true, mode: 448 });
7183
7248
  try {
7184
- mkdirSync3(lockPath, { mode: 448 });
7249
+ mkdirSync4(lockPath, { mode: 448 });
7185
7250
  locked = true;
7186
7251
  } catch {
7187
7252
  return false;
@@ -7203,7 +7268,7 @@ function claimBrowserOpen(now = Date.now(), stateDir, targetUrl) {
7203
7268
  return false;
7204
7269
  }
7205
7270
  }
7206
- writeFileSync3(
7271
+ writeFileSync4(
7207
7272
  statePath,
7208
7273
  JSON.stringify({
7209
7274
  lastOpenedAt: now,
@@ -7264,7 +7329,7 @@ function readMacosUserHome(runner = defaultBrowserCommandRunner) {
7264
7329
  } catch {
7265
7330
  }
7266
7331
  }
7267
- return homedir5();
7332
+ return homedir4();
7268
7333
  }
7269
7334
  function readDefaultMacBrowserBundleId(runner = defaultBrowserCommandRunner) {
7270
7335
  try {
@@ -7452,9 +7517,7 @@ function openUrlMacos(targetUrl, allowFocus, runner = defaultBrowserCommandRunne
7452
7517
  }
7453
7518
  }
7454
7519
  function browserOpeningDisabled() {
7455
- const value = String(
7456
- process.env.DEEPLINE_NO_BROWSER ?? process.env.PLAYGROUND_HEADLESS ?? ""
7457
- ).trim().toLowerCase();
7520
+ const value = String(process.env.DEEPLINE_NO_BROWSER ?? "").trim().toLowerCase();
7458
7521
  return value === "1" || value === "true" || value === "yes" || value === "on";
7459
7522
  }
7460
7523
  function openInBrowser(url, options = {}) {
@@ -7486,7 +7549,7 @@ function sleep3(ms) {
7486
7549
  return new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
7487
7550
  }
7488
7551
  function collectLocalEnvInfo() {
7489
- const homeDir2 = process.env.HOME?.trim() || homedir5();
7552
+ const homeDir2 = process.env.HOME?.trim() || homedir4();
7490
7553
  const info = {
7491
7554
  os: `${process.platform} ${process.arch}`,
7492
7555
  node_version: process.version,
@@ -7864,11 +7927,11 @@ function legacyPendingClaimTokenPath(baseUrl) {
7864
7927
  }
7865
7928
  function savePendingClaim(baseUrl, claim) {
7866
7929
  const filePath = pendingClaimPath(baseUrl, claim.scope);
7867
- const dir = dirname4(filePath);
7930
+ const dir = dirname5(filePath);
7868
7931
  if (!existsSync5(dir)) {
7869
- mkdirSync4(dir, { recursive: true });
7932
+ mkdirSync5(dir, { recursive: true });
7870
7933
  }
7871
- writeFileSync4(filePath, `${JSON.stringify(claim, null, 2)}
7934
+ writeFileSync5(filePath, `${JSON.stringify(claim, null, 2)}
7872
7935
  `, {
7873
7936
  encoding: "utf-8",
7874
7937
  mode: 384
@@ -8580,7 +8643,7 @@ Examples:
8580
8643
  import { Command } from "commander";
8581
8644
  import { randomUUID } from "crypto";
8582
8645
  import { appendFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
8583
- import { dirname as dirname5, resolve as resolve3 } from "path";
8646
+ import { dirname as dirname6, resolve as resolve3 } from "path";
8584
8647
  import { stringify as stringify2 } from "csv-stringify/sync";
8585
8648
  var SUBSCRIPTION_STATUS_NEXT_COMMAND = "deepline billing subscription status --json";
8586
8649
  var SUBSCRIPTION_CANCEL_PATH = "/api/v2/billing/subscription/cancel";
@@ -9039,7 +9102,7 @@ async function handleLedgerExportAll(options) {
9039
9102
  const entries = Array.isArray(payload.entries) ? payload.entries : [];
9040
9103
  const rows = entries.map(ledgerApiEntryToRow);
9041
9104
  if (!initializedOutput) {
9042
- await mkdir2(dirname5(outputPath), { recursive: true });
9105
+ await mkdir2(dirname6(outputPath), { recursive: true });
9043
9106
  await writeFile2(outputPath, ledgerRowsToCsv([], true), "utf-8");
9044
9107
  initializedOutput = true;
9045
9108
  }
@@ -9991,17 +10054,17 @@ import { randomUUID as randomUUID2 } from "crypto";
9991
10054
  import {
9992
10055
  closeSync,
9993
10056
  existsSync as existsSync6,
9994
- mkdirSync as mkdirSync5,
10057
+ mkdirSync as mkdirSync6,
9995
10058
  openSync,
9996
10059
  readFileSync as readFileSync6,
9997
10060
  rmSync as rmSync3,
9998
- writeFileSync as writeFileSync6
10061
+ writeFileSync as writeFileSync7
9999
10062
  } from "fs";
10000
- import { homedir as homedir6 } from "os";
10063
+ import { homedir as homedir5 } from "os";
10001
10064
  import { join as join6, resolve as resolve5 } from "path";
10002
10065
 
10003
10066
  // src/cli/dataset-stats.ts
10004
- import { writeFileSync as writeFileSync5 } from "fs";
10067
+ import { writeFileSync as writeFileSync6 } from "fs";
10005
10068
  import { resolve as resolve4 } from "path";
10006
10069
 
10007
10070
  // ../shared_libs/plays/dataset-summary.ts
@@ -10656,7 +10719,7 @@ function writeCanonicalRowsCsv(rowsInfo, outPath) {
10656
10719
  const rows = dataExportRows(sanitized.rows);
10657
10720
  const columns = dataExportColumns(rows, sanitized.columns);
10658
10721
  const resolved = resolve4(outPath);
10659
- writeFileSync5(resolved, csvStringFromRows(rows, columns), "utf-8");
10722
+ writeFileSync6(resolved, csvStringFromRows(rows, columns), "utf-8");
10660
10723
  return resolved;
10661
10724
  }
10662
10725
 
@@ -10764,13 +10827,13 @@ async function handleCsvShow(options) {
10764
10827
  );
10765
10828
  }
10766
10829
  function csvRenderStatePath() {
10767
- return join6(homedir6(), ".local", "deepline", "runtime", "csv-render.json");
10830
+ return join6(homedir5(), ".local", "deepline", "runtime", "csv-render.json");
10768
10831
  }
10769
10832
  function csvRenderLogPath() {
10770
- return join6(homedir6(), ".local", "deepline", "runtime", "csv-render.log");
10833
+ return join6(homedir5(), ".local", "deepline", "runtime", "csv-render.log");
10771
10834
  }
10772
10835
  function ensureCsvRenderStateDir() {
10773
- mkdirSync5(join6(homedir6(), ".local", "deepline", "runtime"), {
10836
+ mkdirSync6(join6(homedir5(), ".local", "deepline", "runtime"), {
10774
10837
  recursive: true
10775
10838
  });
10776
10839
  }
@@ -10784,7 +10847,7 @@ function readCsvRenderState() {
10784
10847
  }
10785
10848
  function writeCsvRenderState(state) {
10786
10849
  ensureCsvRenderStateDir();
10787
- writeFileSync6(csvRenderStatePath(), `${JSON.stringify(state, null, 2)}
10850
+ writeFileSync7(csvRenderStatePath(), `${JSON.stringify(state, null, 2)}
10788
10851
  `);
10789
10852
  }
10790
10853
  function parseCsvRenderPort(raw) {
@@ -10936,7 +10999,7 @@ async function handleCsvRenderStart(options) {
10936
10999
  rmSync3(csvRenderStatePath(), { force: true });
10937
11000
  } else if (existingOwned) {
10938
11001
  process.stdout.write(
10939
- "Playground render is already running; reusing current process.\n"
11002
+ "CSV render is already running; reusing current process.\n"
10940
11003
  );
10941
11004
  process.stdout.write(`Render URL: ${existing.url}
10942
11005
  `);
@@ -10952,20 +11015,16 @@ async function handleCsvRenderStart(options) {
10952
11015
  const logPath = csvRenderLogPath();
10953
11016
  const logFd = openSync(logPath, "w");
10954
11017
  const token = randomUUID2();
10955
- const child = spawn(
10956
- process.execPath,
10957
- ["-e", CSV_RENDER_SERVER_SOURCE],
10958
- {
10959
- detached: true,
10960
- stdio: ["ignore", logFd, logFd],
10961
- env: {
10962
- ...process.env,
10963
- DEEPLINE_CSV_RENDER_PORT: String(port),
10964
- DEEPLINE_CSV_RENDER_CSV: csvPath,
10965
- DEEPLINE_CSV_RENDER_TOKEN: token
10966
- }
11018
+ const child = spawn(process.execPath, ["-e", CSV_RENDER_SERVER_SOURCE], {
11019
+ detached: true,
11020
+ stdio: ["ignore", logFd, logFd],
11021
+ env: {
11022
+ ...process.env,
11023
+ DEEPLINE_CSV_RENDER_PORT: String(port),
11024
+ DEEPLINE_CSV_RENDER_CSV: csvPath,
11025
+ DEEPLINE_CSV_RENDER_TOKEN: token
10967
11026
  }
10968
- );
11027
+ });
10969
11028
  closeSync(logFd);
10970
11029
  child.unref();
10971
11030
  const state = {
@@ -10997,12 +11056,12 @@ ${clip(log, 2e3)}`;
10997
11056
  );
10998
11057
  }
10999
11058
  writeCsvRenderState(state);
11000
- writeFileSync6(
11059
+ writeFileSync7(
11001
11060
  logPath,
11002
11061
  `CSV render started at ${state.startedAt} on ${url}
11003
11062
  `
11004
11063
  );
11005
- process.stdout.write("Playground render is running.\n");
11064
+ process.stdout.write("CSV render is running.\n");
11006
11065
  process.stdout.write(`Render PID: ${child.pid}
11007
11066
  `);
11008
11067
  process.stdout.write(`Render URL: ${url}
@@ -11073,8 +11132,8 @@ async function handleCsvRenderStop(options) {
11073
11132
  stopped_pids: stopped,
11074
11133
  failed_pids: failed
11075
11134
  };
11076
- const text = stopped.length > 0 ? `Stopped playground render process(es): ${stopped.join(" ")}
11077
- ` : "No running playground render process found.\n";
11135
+ const text = stopped.length > 0 ? `Stopped CSV render process(es): ${stopped.join(" ")}
11136
+ ` : "No running CSV render process found.\n";
11078
11137
  printCommandEnvelope(payload, { json: options.json, text });
11079
11138
  }
11080
11139
  async function handleCsvRender(action, options) {
@@ -11124,7 +11183,7 @@ Examples:
11124
11183
  }
11125
11184
 
11126
11185
  // src/cli/commands/db.ts
11127
- import { writeFileSync as writeFileSync7 } from "fs";
11186
+ import { writeFileSync as writeFileSync8 } from "fs";
11128
11187
  import { resolve as resolve6 } from "path";
11129
11188
  var CUSTOMER_DB_QUERY_FORMATS = /* @__PURE__ */ new Set(["table", "json", "csv", "markdown"]);
11130
11189
  var CUSTOMER_DB_QUERY_MAX_ROWS = 1e3;
@@ -11271,7 +11330,7 @@ function dbRepairPlainText(result) {
11271
11330
  }
11272
11331
  function writeCustomerDbCsv(result, outPath) {
11273
11332
  const resolved = resolve6(outPath);
11274
- writeFileSync7(
11333
+ writeFileSync8(
11275
11334
  resolved,
11276
11335
  dataExportCsvString(customerDbRows(result), customerDbColumnNames(result)),
11277
11336
  "utf-8"
@@ -11384,7 +11443,7 @@ async function handleDbQuery(args) {
11384
11443
  );
11385
11444
  if (outPath) {
11386
11445
  const exportedPath = resolve6(outPath);
11387
- writeFileSync7(exportedPath, content, "utf-8");
11446
+ writeFileSync8(exportedPath, content, "utf-8");
11388
11447
  printCommandEnvelope(
11389
11448
  dbQueryExportEnvelope({
11390
11449
  result,
@@ -11567,20 +11626,20 @@ import {
11567
11626
  stat as stat3,
11568
11627
  writeFile as writeFile4
11569
11628
  } from "fs/promises";
11570
- import { homedir as homedir7, tmpdir as tmpdir4 } from "os";
11571
- import { basename as basename4, dirname as dirname10, extname as extname3, join as join11, resolve as resolve12 } from "path";
11629
+ import { homedir as homedir6, tmpdir as tmpdir4 } from "os";
11630
+ import { basename as basename4, dirname as dirname11, extname as extname3, join as join11, resolve as resolve12 } from "path";
11572
11631
  import { Option } from "commander";
11573
11632
 
11574
11633
  // src/cli/commands/play.ts
11575
11634
  import { createHash as createHash4, randomUUID as randomUUID3 } from "crypto";
11576
11635
  import {
11577
11636
  existsSync as existsSync9,
11578
- mkdirSync as mkdirSync6,
11637
+ mkdirSync as mkdirSync7,
11579
11638
  readFileSync as readFileSync8,
11580
11639
  readdirSync as readdirSync2,
11581
11640
  realpathSync as realpathSync2,
11582
11641
  statSync as statSync3,
11583
- writeFileSync as writeFileSync9
11642
+ writeFileSync as writeFileSync10
11584
11643
  } from "fs";
11585
11644
  import {
11586
11645
  lstat,
@@ -11591,7 +11650,7 @@ import {
11591
11650
  } from "fs/promises";
11592
11651
  import {
11593
11652
  basename as basename3,
11594
- dirname as dirname9,
11653
+ dirname as dirname10,
11595
11654
  isAbsolute as isAbsolute5,
11596
11655
  join as join10,
11597
11656
  relative as relative4,
@@ -11605,7 +11664,7 @@ import {
11605
11664
  openSync as openSync2,
11606
11665
  readSync,
11607
11666
  statSync as statSync2,
11608
- writeFileSync as writeFileSync8
11667
+ writeFileSync as writeFileSync9
11609
11668
  } from "fs";
11610
11669
  import { isAbsolute as isAbsolute2, relative, resolve as resolve7 } from "path";
11611
11670
  import { parse as parseCsvSync } from "csv-parse/sync";
@@ -13167,7 +13226,7 @@ function renderPlayBootstrapError(error) {
13167
13226
  }
13168
13227
  function writeBootstrapSource(source, out) {
13169
13228
  if (out) {
13170
- writeFileSync8(resolve7(out), source, "utf-8");
13229
+ writeFileSync9(resolve7(out), source, "utf-8");
13171
13230
  process.stdout.write(`Wrote ${resolve7(out)}
13172
13231
  `);
13173
13232
  return 0;
@@ -13305,7 +13364,7 @@ Examples:
13305
13364
 
13306
13365
  // src/plays/bundle-play-file.ts
13307
13366
  import { tmpdir as tmpdir3 } from "os";
13308
- import { dirname as dirname8, join as join9, resolve as resolve10 } from "path";
13367
+ import { dirname as dirname9, join as join9, resolve as resolve10 } from "path";
13309
13368
  import { fileURLToPath } from "url";
13310
13369
  import { existsSync as existsSync8 } from "fs";
13311
13370
  import { realpath as realpath2 } from "fs/promises";
@@ -13317,7 +13376,7 @@ import { mkdir as mkdir3, readFile, realpath, stat, writeFile as writeFile3 } fr
13317
13376
  import { tmpdir as tmpdir2 } from "os";
13318
13377
  import {
13319
13378
  basename,
13320
- dirname as dirname6,
13379
+ dirname as dirname7,
13321
13380
  extname,
13322
13381
  isAbsolute as isAbsolute3,
13323
13382
  join as join7,
@@ -18165,7 +18224,7 @@ import { createHash as createHash3 } from "crypto";
18165
18224
  import { readFile as readFile2, stat as stat2 } from "fs/promises";
18166
18225
  import {
18167
18226
  basename as basename2,
18168
- dirname as dirname7,
18227
+ dirname as dirname8,
18169
18228
  extname as extname2,
18170
18229
  isAbsolute as isAbsolute4,
18171
18230
  join as join8,
@@ -18174,7 +18233,7 @@ import {
18174
18233
  } from "path";
18175
18234
 
18176
18235
  // src/plays/bundle-play-file.ts
18177
- var MODULE_DIR = dirname8(fileURLToPath(import.meta.url));
18236
+ var MODULE_DIR = dirname9(fileURLToPath(import.meta.url));
18178
18237
  var SDK_PACKAGE_ROOT = resolve10(MODULE_DIR, "..", "..");
18179
18238
  var SOURCE_REPO_ROOT = resolve10(SDK_PACKAGE_ROOT, "..");
18180
18239
  var HAS_SOURCE_BUNDLING_SOURCES = existsSync8(
@@ -19027,7 +19086,7 @@ async function pathExistsIncludingSymlink(path) {
19027
19086
  }
19028
19087
  function runIdFileTempPath(destination) {
19029
19088
  return join10(
19030
- dirname9(destination),
19089
+ dirname10(destination),
19031
19090
  `.${basename3(destination)}.${process.pid}.${randomUUID3()}.tmp`
19032
19091
  );
19033
19092
  }
@@ -19104,7 +19163,7 @@ async function writePlayRunIdFile(destination, runId) {
19104
19163
  try {
19105
19164
  await link(tempPath, destination);
19106
19165
  if (process.platform !== "win32") {
19107
- const directory = await open(dirname9(destination), "r");
19166
+ const directory = await open(dirname10(destination), "r");
19108
19167
  try {
19109
19168
  await directory.sync();
19110
19169
  } finally {
@@ -19445,12 +19504,12 @@ function materializeRemotePlaySource(input2) {
19445
19504
  `Refusing to materialize unsafe Play source path ${JSON.stringify(logicalPath)}.`
19446
19505
  );
19447
19506
  }
19448
- mkdirSync6(dirname9(outputPath2), { recursive: true });
19507
+ mkdirSync7(dirname10(outputPath2), { recursive: true });
19449
19508
  if (!existsSync9(outputPath2)) {
19450
- writeFileSync9(outputPath2, sourceCode, "utf-8");
19509
+ writeFileSync10(outputPath2, sourceCode, "utf-8");
19451
19510
  created += 1;
19452
19511
  } else if (readFileSync8(outputPath2, "utf-8") !== sourceCode) {
19453
- writeFileSync9(outputPath2, sourceCode, "utf-8");
19512
+ writeFileSync10(outputPath2, sourceCode, "utf-8");
19454
19513
  updated += 1;
19455
19514
  }
19456
19515
  }
@@ -19467,10 +19526,10 @@ function materializeRemotePlaySource(input2) {
19467
19526
  if (existingSource === entrySource) {
19468
19527
  return { path: outputPath, status: "unchanged", created: false };
19469
19528
  }
19470
- writeFileSync9(outputPath, entrySource, "utf-8");
19529
+ writeFileSync10(outputPath, entrySource, "utf-8");
19471
19530
  return { path: outputPath, status: "updated", created: false };
19472
19531
  }
19473
- writeFileSync9(outputPath, entrySource, "utf-8");
19532
+ writeFileSync10(outputPath, entrySource, "utf-8");
19474
19533
  return { path: outputPath, status: "created", created: true };
19475
19534
  }
19476
19535
  function formatLoadedPlayMessage(materializedFile) {
@@ -19622,7 +19681,9 @@ function stringMetadata(metadata, key) {
19622
19681
  }
19623
19682
  function inputFieldFromCsvArg(csvArg) {
19624
19683
  if (typeof csvArg !== "string") return null;
19625
- const match = /^input\.([A-Za-z_$][\w$]*)$/.exec(csvArg.trim());
19684
+ const match = /^\(?\s*input\.([A-Za-z_$][\w$]*)\s*\)?(?:\s*\?\?[\s\S]+)?$/.exec(
19685
+ csvArg.trim()
19686
+ );
19626
19687
  return match?.[1] ?? null;
19627
19688
  }
19628
19689
  function fileInputBindingsFromPlaySchema(inputSchema) {
@@ -23395,6 +23456,21 @@ function printPlayCheckLimits(limits) {
23395
23456
  console.log(
23396
23457
  ` bundle: ${formatByteBudget(limits.bundle.usedBytes, limits.bundle.limitBytes)}`
23397
23458
  );
23459
+ if (limits.activeScheduledPlays) {
23460
+ const { used, limit, remaining } = limits.activeScheduledPlays;
23461
+ console.log(
23462
+ ` scheduled plays: ${used} / ${limit} active (${remaining} available)`
23463
+ );
23464
+ }
23465
+ }
23466
+ function formatPlayRuntimeLimit(runtimeLimit) {
23467
+ if (!runtimeLimit || !Number.isFinite(runtimeLimit.timeoutSeconds)) {
23468
+ return null;
23469
+ }
23470
+ const seconds = runtimeLimit.timeoutSeconds;
23471
+ if (seconds % 3600 === 0) return `${seconds / 3600}h`;
23472
+ if (seconds % 60 === 0) return `${seconds / 60}m`;
23473
+ return `${seconds}s`;
23398
23474
  }
23399
23475
  function isRecord10(value) {
23400
23476
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -23889,6 +23965,8 @@ function printPlayCheckOutcome(outcome, target, prefix) {
23889
23965
  if (result.sourceHash) {
23890
23966
  console.log(` source: ${result.sourceHash.slice(0, 12)}`);
23891
23967
  }
23968
+ const runtimeLimit = formatPlayRuntimeLimit(result.runtimeLimit);
23969
+ if (runtimeLimit) console.log(` runtime limit: ${runtimeLimit}`);
23892
23970
  printPlayCheckLimits(result.limits);
23893
23971
  if (result.artifactHash && outcome.exportName === PLAY_DEFAULT_EXPORT) {
23894
23972
  console.log(
@@ -24328,7 +24406,7 @@ async function handlePlayRun(args, hooks) {
24328
24406
  }
24329
24407
  const resolved = resolve11(options.target.path);
24330
24408
  console.error(`File not found: ${resolved}`);
24331
- const dir = dirname9(resolved);
24409
+ const dir = dirname10(resolved);
24332
24410
  if (existsSync9(dir)) {
24333
24411
  const base = basename3(resolved);
24334
24412
  try {
@@ -24615,7 +24693,7 @@ async function handleRunLogs(args) {
24615
24693
  if (outPath) {
24616
24694
  const result2 = await client2.runs.logs(runId, { all: true });
24617
24695
  const logs = result2.entries;
24618
- writeFileSync9(outPath, `${logs.join("\n")}${logs.length > 0 ? "\n" : ""}`);
24696
+ writeFileSync10(outPath, `${logs.join("\n")}${logs.length > 0 ? "\n" : ""}`);
24619
24697
  printCommandEnvelope(
24620
24698
  {
24621
24699
  runId: result2.runId,
@@ -24829,7 +24907,7 @@ async function handleRunExport(args) {
24829
24907
  }
24830
24908
  };
24831
24909
  if (metadataOutPath) {
24832
- writeFileSync9(
24910
+ writeFileSync10(
24833
24911
  metadataOutPath,
24834
24912
  `${JSON.stringify(payload, null, 2)}
24835
24913
  `,
@@ -28587,10 +28665,10 @@ function expandAtFilePath(rawPath) {
28587
28665
  (_match, bareName, bracedName) => process.env[bareName ?? bracedName ?? ""] ?? ""
28588
28666
  );
28589
28667
  if (expanded === "~") {
28590
- return homedir7();
28668
+ return homedir6();
28591
28669
  }
28592
28670
  if (expanded.startsWith("~/") || expanded.startsWith("~\\")) {
28593
- return join11(homedir7(), expanded.slice(2));
28671
+ return join11(homedir6(), expanded.slice(2));
28594
28672
  }
28595
28673
  return expanded;
28596
28674
  }
@@ -30972,7 +31050,7 @@ function sidecarEnrichRowsExportPath(outputPath) {
30972
31050
  const resolved = resolve12(outputPath);
30973
31051
  const ext = extname3(resolved) || ".csv";
30974
31052
  const stem = basename4(resolved, ext);
30975
- return join11(dirname10(resolved), `${stem}.deepline-enrich-rows${ext}`);
31053
+ return join11(dirname11(resolved), `${stem}.deepline-enrich-rows${ext}`);
30976
31054
  }
30977
31055
  function collectDatasetFollowUpCommands(value, state) {
30978
31056
  if (state.depth > 12 || !value || typeof value !== "object" || state.commands.length >= 8) {
@@ -31053,7 +31131,7 @@ async function persistEnrichFailureReport(input2) {
31053
31131
  if (input2.jobs.length === 0 && input2.issues.length === 0) {
31054
31132
  return null;
31055
31133
  }
31056
- const stateDir = join11(homedir7(), ".local", "deepline", "runtime", "state");
31134
+ const stateDir = join11(homedir6(), ".local", "deepline", "runtime", "state");
31057
31135
  const reportPrefix = input2.jobs.length > 0 ? "run-block-failures" : "enrich-issues";
31058
31136
  await mkdir4(stateDir, { recursive: true });
31059
31137
  const reportPath = join11(
@@ -32016,7 +32094,7 @@ function registerEnrichCommand(program) {
32016
32094
  }
32017
32095
  inPlaceTempDir = await mkdtemp(
32018
32096
  join11(
32019
- dirname10(inPlaceCommitOutputPath ?? resolve12(inputCsv)),
32097
+ dirname11(inPlaceCommitOutputPath ?? resolve12(inputCsv)),
32020
32098
  ".deepline-enrich-in-place-"
32021
32099
  )
32022
32100
  );
@@ -32297,14 +32375,14 @@ Examples:
32297
32375
  // src/cli/commands/sessions.ts
32298
32376
  import {
32299
32377
  existsSync as existsSync10,
32300
- mkdirSync as mkdirSync7,
32378
+ mkdirSync as mkdirSync8,
32301
32379
  readdirSync as readdirSync3,
32302
32380
  readFileSync as readFileSync9,
32303
32381
  statSync as statSync4,
32304
- writeFileSync as writeFileSync10
32382
+ writeFileSync as writeFileSync11
32305
32383
  } from "fs";
32306
- import { homedir as homedir8, platform } from "os";
32307
- import { basename as basename5, dirname as dirname11, join as join12, resolve as resolve13 } from "path";
32384
+ import { homedir as homedir7, platform } from "os";
32385
+ import { basename as basename5, dirname as dirname12, join as join12, resolve as resolve13 } from "path";
32308
32386
  import { gzipSync } from "zlib";
32309
32387
  import { randomUUID as randomUUID4 } from "crypto";
32310
32388
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -32318,7 +32396,7 @@ var MAX_EVENT_OBJECT_KEYS = 80;
32318
32396
  var TRUNCATION_MARKER = "...[truncated]";
32319
32397
  var NOISE_EVENT_TYPES = /* @__PURE__ */ new Set(["progress", "file-history-snapshot"]);
32320
32398
  function homeDir() {
32321
- return process.env.HOME?.trim() || homedir8();
32399
+ return process.env.HOME?.trim() || homedir7();
32322
32400
  }
32323
32401
  function detectShellContext() {
32324
32402
  const shellPath = process.env.SHELL?.trim() || process.env.ComSpec?.trim() || process.env.COMSPEC?.trim() || "";
@@ -32853,9 +32931,9 @@ function loadViewerAssets() {
32853
32931
  const cliEntry = process.argv[1]?.trim() ? resolve13(process.argv[1]) : null;
32854
32932
  const candidateRoots2 = [
32855
32933
  ...cliEntry ? [
32856
- join12(dirname11(dirname11(cliEntry)), "viewer"),
32934
+ join12(dirname12(dirname12(cliEntry)), "viewer"),
32857
32935
  join12(
32858
- dirname11(dirname11(dirname11(cliEntry))),
32936
+ dirname12(dirname12(dirname12(cliEntry))),
32859
32937
  "src",
32860
32938
  "lib",
32861
32939
  "cli",
@@ -32898,13 +32976,13 @@ async function handleSessionsRender(options) {
32898
32976
  let outputPath = options.output ? resolve13(options.output) : "";
32899
32977
  if (!outputPath) {
32900
32978
  const outputDir = join12(process.cwd(), "deepline", "data");
32901
- mkdirSync7(outputDir, { recursive: true });
32979
+ mkdirSync8(outputDir, { recursive: true });
32902
32980
  outputPath = join12(
32903
32981
  outputDir,
32904
32982
  targets.length > 1 ? "session-viewer.html" : `session-${targets[0]?.sessionId}.html`
32905
32983
  );
32906
32984
  } else {
32907
- mkdirSync7(dirname11(outputPath), { recursive: true });
32985
+ mkdirSync8(dirname12(outputPath), { recursive: true });
32908
32986
  }
32909
32987
  const sessions = targets.map((target) => ({
32910
32988
  label: target.label,
@@ -32934,7 +33012,7 @@ ${refreshMeta}
32934
33012
  <script>${js}</script>
32935
33013
  </body>
32936
33014
  </html>`;
32937
- writeFileSync10(outputPath, html, "utf8");
33015
+ writeFileSync11(outputPath, html, "utf8");
32938
33016
  printCommandEnvelope(
32939
33017
  {
32940
33018
  ok: true,
@@ -33041,30 +33119,31 @@ var BACKEND_SUBCOMMANDS = [
33041
33119
  "refresh-runtime",
33042
33120
  "sync-runtime"
33043
33121
  ];
33044
- function legacyNoopEnvelope(input2) {
33122
+ function deprecatedCommandEnvelope(input2) {
33045
33123
  const command = ["deepline", input2.family, input2.subcommand].filter(Boolean).join(" ");
33046
- const subject = input2.family === "session" ? "Legacy Session UI/playground command" : "Legacy local playground backend command";
33047
- const note = input2.family === "session" ? "The SDK CLI does not manage the legacy Python Session UI. This command is accepted for backwards compatibility and intentionally does nothing." : "The SDK CLI does not start or stop the legacy Python local playground backend. This command is accepted for backwards compatibility and intentionally does nothing.";
33124
+ const commandLabel = input2.family === "session" ? "Legacy session command" : "Legacy backend command";
33125
+ const note = input2.family === "session" ? "This command was retired with the legacy Python Session UI. Use `deepline sessions send` or `deepline sessions render`." : "This command was retired with the legacy local backend. Use `deepline-admin dev start`, `deepline-admin dev status`, or `deepline-admin dev stop`.";
33048
33126
  return {
33049
- ok: true,
33050
- noop: true,
33127
+ ok: false,
33051
33128
  command,
33052
- compatibility: {
33053
- family: "legacy_python_cli",
33054
- sdk_behavior: "noop"
33055
- },
33129
+ code: "DEPRECATED_COMMAND",
33130
+ error: `${commandLabel} is deprecated. ${note}`,
33131
+ next: input2.family === "session" ? "deepline sessions send --current-session --json" : "deepline-admin dev status --json",
33056
33132
  render: {
33057
33133
  sections: [
33058
33134
  {
33059
- title: subject,
33135
+ title: `${commandLabel} deprecated`,
33060
33136
  lines: [note]
33061
33137
  }
33062
33138
  ]
33063
33139
  }
33064
33140
  };
33065
33141
  }
33066
- function printLegacyNoop(input2) {
33067
- printCommandEnvelope(legacyNoopEnvelope(input2), { json: input2.options.json });
33142
+ function printDeprecatedCommand(input2) {
33143
+ printCommandEnvelope(deprecatedCommandEnvelope(input2), {
33144
+ json: input2.options.json
33145
+ });
33146
+ process.exitCode = 2;
33068
33147
  }
33069
33148
  function legacySubcommandFromArgv(family) {
33070
33149
  const args = process.argv.slice(2);
@@ -33072,18 +33151,18 @@ function legacySubcommandFromArgv(family) {
33072
33151
  const nextToken = familyIndex >= 0 ? args[familyIndex + 1] : void 0;
33073
33152
  return nextToken && !nextToken.startsWith("-") ? nextToken : void 0;
33074
33153
  }
33075
- function addLegacyNoopSubcommand(parent, family, subcommand, description) {
33154
+ function addDeprecatedSubcommand(parent, family, subcommand, description) {
33076
33155
  parent.command(subcommand).description(description).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").action((_args, options) => {
33077
- printLegacyNoop({ family, subcommand, options });
33156
+ printDeprecatedCommand({ family, subcommand, options });
33078
33157
  });
33079
33158
  }
33080
- function registerLegacyNoopCommands(program) {
33081
- const session = program.command("session").description("Compatibility no-ops for legacy Python Session UI commands.").allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
33159
+ function registerDeprecatedCommands(program) {
33160
+ const session = program.command("session").description("Deprecated legacy session command namespace.").allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
33082
33161
  "after",
33083
33162
  `
33084
33163
  Notes:
33085
- The SDK CLI accepts singular session commands from older agent skills so they
33086
- do not fail, but it does not manage the legacy Python Session UI.
33164
+ The legacy Python Session UI was retired. Legacy session commands now fail
33165
+ with a migration instruction; they no longer report a successful no-op.
33087
33166
  Use "deepline sessions send" or "deepline sessions render" for real SDK
33088
33167
  transcript workflows. "deepline session send" and "deepline session render"
33089
33168
  are accepted aliases for those real SDK workflows.
@@ -33095,7 +33174,7 @@ Examples:
33095
33174
  `
33096
33175
  ).action((args, options) => {
33097
33176
  void args;
33098
- printLegacyNoop({
33177
+ printDeprecatedCommand({
33099
33178
  family: "session",
33100
33179
  subcommand: legacySubcommandFromArgv("session"),
33101
33180
  options
@@ -33103,21 +33182,19 @@ Examples:
33103
33182
  });
33104
33183
  registerSessionSendRenderCommands(session, "session");
33105
33184
  for (const subcommand of SESSION_SUBCOMMANDS) {
33106
- addLegacyNoopSubcommand(
33185
+ addDeprecatedSubcommand(
33107
33186
  session,
33108
33187
  "session",
33109
33188
  subcommand,
33110
- `Accept legacy "deepline session ${subcommand}" as an SDK no-op.`
33189
+ `Deprecated legacy "deepline session ${subcommand}" command.`
33111
33190
  );
33112
33191
  }
33113
- const backend = program.command("backend").description(
33114
- "Compatibility no-ops for legacy Python local backend commands."
33115
- ).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
33192
+ const backend = program.command("backend").description("Deprecated legacy local backend command namespace.").allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
33116
33193
  "after",
33117
33194
  `
33118
33195
  Notes:
33119
- The SDK CLI uses the configured Deepline host and V2 play runtime. It does not
33120
- start, stop, or refresh the legacy Python local playground backend.
33196
+ The legacy local backend was retired. Use deepline-admin for local runtime
33197
+ lifecycle operations.
33121
33198
 
33122
33199
  Examples:
33123
33200
  deepline backend start
@@ -33126,18 +33203,18 @@ Examples:
33126
33203
  `
33127
33204
  ).action((args, options) => {
33128
33205
  void args;
33129
- printLegacyNoop({
33206
+ printDeprecatedCommand({
33130
33207
  family: "backend",
33131
33208
  subcommand: legacySubcommandFromArgv("backend"),
33132
33209
  options
33133
33210
  });
33134
33211
  });
33135
33212
  for (const subcommand of BACKEND_SUBCOMMANDS) {
33136
- addLegacyNoopSubcommand(
33213
+ addDeprecatedSubcommand(
33137
33214
  backend,
33138
33215
  "backend",
33139
33216
  subcommand,
33140
- `Accept legacy "deepline backend ${subcommand}" as an SDK no-op.`
33217
+ `Deprecated legacy "deepline backend ${subcommand}" command.`
33141
33218
  );
33142
33219
  }
33143
33220
  }
@@ -34205,6 +34282,11 @@ Notes:
34205
34282
  Deploy is a full desired definition for its key: omitting a previously stored
34206
34283
  field removes it and can replace the upstream resource. Use \`monitors update\`
34207
34284
  for a patch-style change.
34285
+ Repeating the exact saved definition resumes an incomplete deploy cleanup:
34286
+ Deepline keeps the replacement, removes only the stored previous binding after
34287
+ provider confirmation, and never creates or charges another monitor. Deepline
34288
+ also retries eligible incomplete deploy cleanups automatically in bounded
34289
+ background passes; no separate repair command is required.
34208
34290
  For a bounded urgent Deepline Native preview, set
34209
34291
  controls.execution_type="priority". Deepline injects the provider custom
34210
34292
  field and enforces a ten-slot per-org cap; do not use it for regular or bulk
@@ -35176,24 +35258,24 @@ Examples:
35176
35258
  }
35177
35259
 
35178
35260
  // src/cli/commands/setup.ts
35179
- import { spawnSync } from "child_process";
35261
+ import { spawnSync as spawnSync2 } from "child_process";
35180
35262
  import {
35181
- existsSync as existsSync12,
35263
+ existsSync as existsSync13,
35182
35264
  lstatSync,
35183
- mkdirSync as mkdirSync9,
35184
- readFileSync as readFileSync12,
35265
+ mkdirSync as mkdirSync11,
35266
+ readFileSync as readFileSync13,
35185
35267
  realpathSync as realpathSync3,
35186
35268
  rmSync as rmSync4,
35187
- writeFileSync as writeFileSync12
35269
+ writeFileSync as writeFileSync14
35188
35270
  } from "fs";
35189
- import { homedir as homedir10 } from "os";
35190
- import { basename as basename6, dirname as dirname13, join as join14, relative as relative5, resolve as resolve14 } from "path";
35271
+ import { homedir as homedir9 } from "os";
35272
+ import { basename as basename6, dirname as dirname15, join as join15, relative as relative5, resolve as resolve14 } from "path";
35191
35273
 
35192
35274
  // src/cli/commands/skills.ts
35193
- import { spawn as spawn2 } from "child_process";
35194
- import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync11 } from "fs";
35195
- import { homedir as homedir9 } from "os";
35196
- import { dirname as dirname12, join as join13 } from "path";
35275
+ import { spawn as spawn3 } from "child_process";
35276
+ import { existsSync as existsSync12, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync13 } from "fs";
35277
+ import { homedir as homedir8 } from "os";
35278
+ import { dirname as dirname14, join as join14 } from "path";
35197
35279
 
35198
35280
  // ../shared_libs/cli/install-commands.json
35199
35281
  var install_commands_default = {
@@ -35222,7 +35304,6 @@ var install_commands_default = {
35222
35304
  ]
35223
35305
  },
35224
35306
  cli: {
35225
- legacy_python_shell_template: "curl -s {base_url}/api/v2/cli/install | bash",
35226
35307
  sdk_npm_global: "npm install -g deepline@latest"
35227
35308
  }
35228
35309
  };
@@ -35261,9 +35342,6 @@ function renderTemplate(template, values) {
35261
35342
  return values[key] ?? match;
35262
35343
  });
35263
35344
  }
35264
- function shellJoin(args) {
35265
- return args.join(" ");
35266
- }
35267
35345
  function skillsIndexUrl(baseUrl) {
35268
35346
  return `${normalizeBaseUrl2(baseUrl)}${INSTALL_COMMANDS.skills.index_path}`;
35269
35347
  }
@@ -35298,19 +35376,17 @@ function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
35298
35376
  );
35299
35377
  return rendered;
35300
35378
  }
35301
- function skillsInstallCommand(baseUrl, skillName) {
35302
- return `${INSTALL_COMMANDS.skills.npx_binary} ${shellJoin(
35303
- buildSkillsAddArgs(baseUrl, skillName)
35304
- )}`;
35305
- }
35306
- function legacyPythonInstallCommand(baseUrl) {
35307
- return renderTemplate(INSTALL_COMMANDS.cli.legacy_python_shell_template, {
35308
- base_url: normalizeBaseUrl2(baseUrl)
35309
- });
35310
- }
35311
- function sdkNpmGlobalInstallCommand() {
35312
- return INSTALL_COMMANDS.cli.sdk_npm_global;
35313
- }
35379
+
35380
+ // src/cli/skills-sync.ts
35381
+ import { spawn as spawn2, spawnSync } from "child_process";
35382
+ import {
35383
+ existsSync as existsSync11,
35384
+ mkdirSync as mkdirSync9,
35385
+ readFileSync as readFileSync11,
35386
+ unlinkSync,
35387
+ writeFileSync as writeFileSync12
35388
+ } from "fs";
35389
+ import { dirname as dirname13, join as join13 } from "path";
35314
35390
 
35315
35391
  // src/cli/windows-arg-escape.ts
35316
35392
  var CMD_META_CHARS = /([()\][%!^"`<>&|;, *?])/g;
@@ -35335,6 +35411,351 @@ function resolveShellSpawn(command, args, platform3 = process.platform) {
35335
35411
  };
35336
35412
  }
35337
35413
 
35414
+ // src/cli/skills-sync.ts
35415
+ var CHECK_TIMEOUT_MS2 = 3e3;
35416
+ function shouldSkipSkillsSync() {
35417
+ if (detectAgentRuntime() === "claude_cowork") {
35418
+ return true;
35419
+ }
35420
+ const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
35421
+ return value === "1" || value === "true" || value === "yes" || value === "on";
35422
+ }
35423
+ function unavailableSkillsNoticePath(baseUrl) {
35424
+ return join13(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
35425
+ }
35426
+ function failedSkillsSyncPath(baseUrl, agents) {
35427
+ return join13(
35428
+ sdkCliStateDirPath(baseUrl),
35429
+ `skills-sync-failed-${agents.join("-")}-version`
35430
+ );
35431
+ }
35432
+ function hasMarkedSkillsSyncVersion(path, version) {
35433
+ return Boolean(version) && readMarkedSkillsSyncVersion(path) === version;
35434
+ }
35435
+ function readMarkedSkillsSyncVersion(path) {
35436
+ try {
35437
+ return existsSync11(path) ? readFileSync11(path, "utf-8").trim() : "";
35438
+ } catch {
35439
+ return "";
35440
+ }
35441
+ }
35442
+ function writeMarkedSkillsSyncVersion(path, version) {
35443
+ try {
35444
+ mkdirSync9(dirname13(path), { recursive: true });
35445
+ writeFileSync12(path, `${version}
35446
+ `, "utf-8");
35447
+ } catch {
35448
+ }
35449
+ }
35450
+ function writeUnavailableSkillsNotice(baseUrl, remoteVersion, skillNames) {
35451
+ const path = unavailableSkillsNoticePath(baseUrl);
35452
+ if (hasMarkedSkillsSyncVersion(path, remoteVersion)) return;
35453
+ writeMarkedSkillsSyncVersion(path, remoteVersion);
35454
+ const manualCommand = `npx ${buildSkillsInstallArgs(baseUrl, skillNames).join(" ")}`;
35455
+ writeSdkSkillsStatusLine(
35456
+ `Deepline agent skills are out of date, but neither \`bunx\` nor \`npx\` is available. Install Node.js/npm or Bun, then run:
35457
+ ${manualCommand}`
35458
+ );
35459
+ }
35460
+ function clearUnavailableSkillsNotice(baseUrl) {
35461
+ try {
35462
+ unlinkSync(unavailableSkillsNoticePath(baseUrl));
35463
+ } catch {
35464
+ }
35465
+ }
35466
+ function hasFailedSkillsSync(baseUrl, remoteVersion, agents) {
35467
+ return hasMarkedSkillsSyncVersion(
35468
+ failedSkillsSyncPath(baseUrl, agents),
35469
+ remoteVersion
35470
+ );
35471
+ }
35472
+ function hasFailedAutomaticSkillsSync(baseUrl, agents) {
35473
+ return existsSync11(failedSkillsSyncPath(baseUrl, agents));
35474
+ }
35475
+ function markFailedSkillsSync(baseUrl, remoteVersion, agents) {
35476
+ writeMarkedSkillsSyncVersion(
35477
+ failedSkillsSyncPath(baseUrl, agents),
35478
+ remoteVersion
35479
+ );
35480
+ }
35481
+ function clearFailedSkillsSync(baseUrl, agents) {
35482
+ try {
35483
+ unlinkSync(failedSkillsSyncPath(baseUrl, agents));
35484
+ } catch {
35485
+ }
35486
+ }
35487
+ function clearFailedAutomaticSkillsSync(baseUrl, agents) {
35488
+ clearFailedSkillsSync(baseUrl, agents);
35489
+ }
35490
+ function sortedUniqueSkillNames(names) {
35491
+ return [...new Set(names.map((name) => name.trim()).filter(Boolean))].sort(
35492
+ (a, b) => a.localeCompare(b)
35493
+ );
35494
+ }
35495
+ async function fetchV1SkillNames(baseUrl) {
35496
+ const controller = new AbortController();
35497
+ const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
35498
+ try {
35499
+ const response = await fetch(
35500
+ new URL("/.well-known/skills/index.json", baseUrl),
35501
+ { signal: controller.signal }
35502
+ );
35503
+ if (!response.ok) return [];
35504
+ const data = await response.json().catch(() => null);
35505
+ const names = (data?.skills ?? []).filter((skill) => skill.install_surface === "v1").map((skill) => skill.name).filter(
35506
+ (name) => typeof name === "string" && name.length > 0
35507
+ );
35508
+ return sortedUniqueSkillNames(names);
35509
+ } catch {
35510
+ return [];
35511
+ } finally {
35512
+ clearTimeout(timeout);
35513
+ }
35514
+ }
35515
+ function buildSdkSkillNames(v1SkillNames) {
35516
+ return sortedUniqueSkillNames(v1SkillNames);
35517
+ }
35518
+ async function fetchSkillsUpdate(baseUrl, localVersion) {
35519
+ const controller = new AbortController();
35520
+ const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
35521
+ try {
35522
+ const response = await fetch(new URL("/api/v2/cli/update-check", baseUrl), {
35523
+ method: "POST",
35524
+ headers: { "Content-Type": "application/json" },
35525
+ body: JSON.stringify({
35526
+ skills: {
35527
+ version: localVersion
35528
+ }
35529
+ }),
35530
+ signal: controller.signal
35531
+ });
35532
+ if (!response.ok) return null;
35533
+ const data = await response.json().catch(() => null);
35534
+ const skills = data?.skills;
35535
+ if (!skills) return null;
35536
+ return {
35537
+ needsUpdate: skills.needs_update === true,
35538
+ remoteVersion: typeof skills.remote?.version === "string" ? skills.remote.version.trim() : ""
35539
+ };
35540
+ } catch {
35541
+ return null;
35542
+ } finally {
35543
+ clearTimeout(timeout);
35544
+ }
35545
+ }
35546
+ function buildSkillsInstallArgs(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES, agents) {
35547
+ return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
35548
+ agents
35549
+ });
35550
+ }
35551
+ function buildBunxSkillsInstallArgs(baseUrl, skillNames, agents) {
35552
+ return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
35553
+ firstArg: "--bun",
35554
+ agents
35555
+ });
35556
+ }
35557
+ function hasCommand(command) {
35558
+ const plan = resolveShellSpawn(command, ["--version"]);
35559
+ const result = spawnSync(plan.command, plan.args, {
35560
+ stdio: "ignore",
35561
+ shell: plan.shell
35562
+ });
35563
+ return result.status === 0;
35564
+ }
35565
+ function shellQuote3(arg) {
35566
+ return `'${arg.replace(/'/g, `'\\''`)}'`;
35567
+ }
35568
+ function temporarySkillsSyncSkipCommand() {
35569
+ if (process.platform === "win32") {
35570
+ return "set DEEPLINE_SKIP_SKILLS_SYNC=1 && deepline <command> (cmd), or $env:DEEPLINE_SKIP_SKILLS_SYNC='1'; deepline <command> (PowerShell)";
35571
+ }
35572
+ return "DEEPLINE_SKIP_SKILLS_SYNC=1 deepline <command>";
35573
+ }
35574
+ function resolveSkillsInstallSpawn(install, platform3 = process.platform) {
35575
+ return resolveShellSpawn(install.command, install.args, platform3);
35576
+ }
35577
+ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES, agents = DEFAULT_SKILL_AGENTS) {
35578
+ const commands = [];
35579
+ if (hasCommand("bunx")) {
35580
+ const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames, agents);
35581
+ commands.push({
35582
+ command: "bunx",
35583
+ args: bunxArgs,
35584
+ manualCommand: `bunx ${bunxArgs.map(shellQuote3).join(" ")}`
35585
+ });
35586
+ }
35587
+ if (hasCommand("npx")) {
35588
+ const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames, agents);
35589
+ commands.push({
35590
+ command: "npx",
35591
+ args: npxArgs,
35592
+ manualCommand: `npx ${npxArgs.map(shellQuote3).join(" ")}`
35593
+ });
35594
+ }
35595
+ return commands;
35596
+ }
35597
+ function runOneSkillsInstall(install) {
35598
+ return new Promise((resolve19) => {
35599
+ const plan = resolveSkillsInstallSpawn(install);
35600
+ const child = spawn2(plan.command, plan.args, {
35601
+ stdio: ["ignore", "ignore", "pipe"],
35602
+ env: process.env,
35603
+ shell: plan.shell
35604
+ });
35605
+ let stderr = "";
35606
+ child.stderr.on("data", (chunk) => {
35607
+ stderr += chunk.toString("utf-8");
35608
+ });
35609
+ child.on("error", (error) => {
35610
+ resolve19({
35611
+ ok: false,
35612
+ detail: `failed to start ${install.command}: ${error.message}`,
35613
+ manualCommand: install.manualCommand
35614
+ });
35615
+ });
35616
+ child.on("close", (code) => {
35617
+ if (code === 0) {
35618
+ resolve19({ ok: true, detail: "", manualCommand: install.manualCommand });
35619
+ return;
35620
+ }
35621
+ const detail = stderr.trim();
35622
+ resolve19({
35623
+ ok: false,
35624
+ detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
35625
+ manualCommand: install.manualCommand
35626
+ });
35627
+ });
35628
+ });
35629
+ }
35630
+ async function runSkillsInstall(installs, agents) {
35631
+ const failures = [];
35632
+ for (const install of installs) {
35633
+ const result = await runOneSkillsInstall(install);
35634
+ if (result.ok) return true;
35635
+ failures.push(result);
35636
+ }
35637
+ const details = failures.map((failure) => failure.detail).filter(Boolean).join("\n");
35638
+ const attemptedCommands = failures.map((failure) => ` ${failure.manualCommand}`).join("\n");
35639
+ const retryAgent = agents.at(0);
35640
+ process.stderr.write(
35641
+ `Deepline agent-skills refresh failed for ${agents.join(", ")}. The Deepline command will continue; this only affects optional local agent instructions, not authentication, data, or billing.
35642
+ ` + (attemptedCommands ? `Attempted installer command${failures.length === 1 ? "" : "s"}:
35643
+ ${attemptedCommands}
35644
+ ` : "") + (details ? `Installer output:
35645
+ ${details}
35646
+ ` : "") + (retryAgent ? `To retry with full installer output: deepline skills --agent ${retryAgent} --json
35647
+ ` : "") + `To temporarily suppress automatic skills sync: ${temporarySkillsSyncSkipCommand()}
35648
+ `
35649
+ );
35650
+ return false;
35651
+ }
35652
+ function runLegacySkillsCleanup(agents) {
35653
+ const candidates = hasCommand("bunx") ? [
35654
+ {
35655
+ command: "bunx",
35656
+ args: [
35657
+ "--bun",
35658
+ "skills",
35659
+ "remove",
35660
+ "--global",
35661
+ "--agent",
35662
+ ...agents,
35663
+ "-y",
35664
+ ...LEGACY_SKILL_NAMES_TO_REMOVE
35665
+ ]
35666
+ },
35667
+ {
35668
+ command: "npx",
35669
+ args: [
35670
+ "--yes",
35671
+ "skills",
35672
+ "remove",
35673
+ "--global",
35674
+ "--agent",
35675
+ ...agents,
35676
+ "-y",
35677
+ ...LEGACY_SKILL_NAMES_TO_REMOVE
35678
+ ]
35679
+ }
35680
+ ] : [
35681
+ {
35682
+ command: "npx",
35683
+ args: [
35684
+ "--yes",
35685
+ "skills",
35686
+ "remove",
35687
+ "--global",
35688
+ "--agent",
35689
+ ...agents,
35690
+ "-y",
35691
+ ...LEGACY_SKILL_NAMES_TO_REMOVE
35692
+ ]
35693
+ }
35694
+ ];
35695
+ for (const candidate of candidates) {
35696
+ const plan = resolveShellSpawn(candidate.command, candidate.args);
35697
+ const result = spawnSync(plan.command, plan.args, {
35698
+ stdio: "ignore",
35699
+ env: process.env,
35700
+ shell: plan.shell
35701
+ });
35702
+ if (result.status === 0) return;
35703
+ }
35704
+ }
35705
+ function writeSdkSkillsStatusLine(line) {
35706
+ const progress = getActiveCliProgress();
35707
+ if (progress) {
35708
+ progress.writeLine(line);
35709
+ return;
35710
+ }
35711
+ process.stderr.write(`${line}
35712
+ `);
35713
+ }
35714
+ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
35715
+ if (shouldSkipSkillsSync()) return;
35716
+ const usingPluginSkills = hasActivePluginSkills();
35717
+ if (usingPluginSkills) {
35718
+ return;
35719
+ }
35720
+ const localVersion = readSdkSkillsLocalVersion(baseUrl);
35721
+ const update = options.update === void 0 ? await fetchSkillsUpdate(baseUrl, localVersion) : options.update ? {
35722
+ needsUpdate: options.update.needs_update,
35723
+ remoteVersion: options.update.remote.version
35724
+ } : null;
35725
+ if (!update?.needsUpdate || !update.remoteVersion) {
35726
+ return;
35727
+ }
35728
+ const agents = resolveAutoSyncSkillAgents();
35729
+ if (agents.length > 0 && hasFailedSkillsSync(baseUrl, update.remoteVersion, agents)) {
35730
+ return;
35731
+ }
35732
+ const remoteSkillNames = await fetchV1SkillNames(baseUrl);
35733
+ const skillNames = buildSdkSkillNames(
35734
+ remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
35735
+ );
35736
+ if (skillNames.length === 0) return;
35737
+ if (agents.length === 0) {
35738
+ writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
35739
+ return;
35740
+ }
35741
+ const installs = resolveSkillsInstallCommands(baseUrl, skillNames, agents);
35742
+ if (installs.length === 0) {
35743
+ writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
35744
+ return;
35745
+ }
35746
+ writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
35747
+ const installed = await runSkillsInstall(installs, agents);
35748
+ if (!installed) {
35749
+ markFailedSkillsSync(baseUrl, update.remoteVersion, agents);
35750
+ return;
35751
+ }
35752
+ runLegacySkillsCleanup(agents);
35753
+ writeSdkSkillsLocalVersion(baseUrl, update.remoteVersion, agents);
35754
+ clearUnavailableSkillsNotice(baseUrl);
35755
+ clearFailedSkillsSync(baseUrl, agents);
35756
+ writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
35757
+ }
35758
+
35338
35759
  // src/cli/commands/skills.ts
35339
35760
  var RUNTIME_TO_SKILLS_AGENT = {
35340
35761
  antigravity: "antigravity",
@@ -35396,17 +35817,17 @@ function detectSkillsAgents(input2) {
35396
35817
  if (knownAgent) return [knownAgent];
35397
35818
  const roots = [
35398
35819
  ...input2.scope === "local" && input2.root ? [input2.root] : [],
35399
- input2.homeDir ?? homedir9()
35820
+ input2.homeDir ?? homedir8()
35400
35821
  ];
35401
35822
  const detected = AGENT_MARKERS.filter(
35402
35823
  (marker) => roots.some(
35403
- (root) => marker.paths.some((path) => existsSync11(join13(root, path)))
35824
+ (root) => marker.paths.some((path) => existsSync12(join14(root, path)))
35404
35825
  )
35405
35826
  ).map((marker) => marker.agent);
35406
35827
  return detected.length > 0 ? detected : ["*"];
35407
35828
  }
35408
35829
  function skillsStatePathForScope(baseUrl, scope, root) {
35409
- return scope === "local" && root ? join13(root, ".deepline", "setup", "skills.json") : join13(sdkCliStateDirPath(baseUrl), "skills-install.json");
35830
+ return scope === "local" && root ? join14(root, ".deepline", "setup", "skills.json") : join14(sdkCliStateDirPath(baseUrl), "skills-install.json");
35410
35831
  }
35411
35832
  function buildSkillsPlan(input2) {
35412
35833
  const scopeArgs = input2.scope === "global" ? ["--global"] : [];
@@ -35473,7 +35894,7 @@ function isSkillsPlanCurrent(plan, state) {
35473
35894
  }
35474
35895
  function readSkillsInstallState(path) {
35475
35896
  try {
35476
- const parsed = JSON.parse(readFileSync11(path, "utf8"));
35897
+ const parsed = JSON.parse(readFileSync12(path, "utf8"));
35477
35898
  return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
35478
35899
  } catch {
35479
35900
  return null;
@@ -35482,7 +35903,7 @@ function readSkillsInstallState(path) {
35482
35903
  function runProcess(command, args, cwd) {
35483
35904
  return new Promise((resolve19, reject) => {
35484
35905
  const plan = resolveShellSpawn(command, args);
35485
- const child = spawn2(plan.command, plan.args, {
35906
+ const child = spawn3(plan.command, plan.args, {
35486
35907
  cwd,
35487
35908
  env: process.env,
35488
35909
  stdio: ["ignore", "ignore", "pipe"],
@@ -35536,7 +35957,7 @@ async function runSkillsCommand(options, dependencies = {}) {
35536
35957
  );
35537
35958
  return 0;
35538
35959
  }
35539
- if (isSkillsPlanCurrent(plan, readSkillsInstallState(plan.statePath))) {
35960
+ if (isSkillsPlanCurrent(plan, readSkillsInstallState(plan.statePath)) && !hasFailedAutomaticSkillsSync(baseUrl, agents)) {
35540
35961
  printCommandEnvelope(
35541
35962
  {
35542
35963
  ok: true,
@@ -35617,8 +36038,8 @@ async function runSkillsCommand(options, dependencies = {}) {
35617
36038
  );
35618
36039
  return 5;
35619
36040
  }
35620
- mkdirSync8(dirname12(plan.statePath), { recursive: true });
35621
- writeFileSync11(
36041
+ mkdirSync10(dirname14(plan.statePath), { recursive: true });
36042
+ writeFileSync13(
35622
36043
  plan.statePath,
35623
36044
  `${JSON.stringify(
35624
36045
  {
@@ -35636,6 +36057,9 @@ async function runSkillsCommand(options, dependencies = {}) {
35636
36057
  `,
35637
36058
  "utf8"
35638
36059
  );
36060
+ if (scope === "global") {
36061
+ clearFailedAutomaticSkillsSync(baseUrl, agents);
36062
+ }
35639
36063
  printCommandEnvelope(
35640
36064
  {
35641
36065
  ok: true,
@@ -35752,7 +36176,7 @@ function phasesFromLegacyStatus(status) {
35752
36176
  function readSetupState(input2) {
35753
36177
  try {
35754
36178
  const parsed = JSON.parse(
35755
- readFileSync12(
36179
+ readFileSync13(
35756
36180
  setupStatePath(input2.baseUrl, input2.scope, input2.root),
35757
36181
  "utf8"
35758
36182
  )
@@ -35828,7 +36252,7 @@ function buildPendingAuthorizationOutput(input2) {
35828
36252
  };
35829
36253
  }
35830
36254
  function setupStatePath(baseUrl, scope, root) {
35831
- return scope === "local" && root ? join14(root, ".deepline", "setup", "state.json") : join14(sdkCliStateDirPath(baseUrl), "setup.json");
36255
+ return scope === "local" && root ? join15(root, ".deepline", "setup", "state.json") : join15(sdkCliStateDirPath(baseUrl), "setup.json");
35832
36256
  }
35833
36257
  async function captureStdout2(run) {
35834
36258
  let stdout = "";
@@ -35857,14 +36281,14 @@ function asRecord3(value) {
35857
36281
  }
35858
36282
  function safeRead(path) {
35859
36283
  try {
35860
- return readFileSync12(path, "utf8");
36284
+ return readFileSync13(path, "utf8");
35861
36285
  } catch {
35862
36286
  return "";
35863
36287
  }
35864
36288
  }
35865
36289
  function isNpmManagedDeeplinePath(path) {
35866
36290
  try {
35867
- return realpathSync3(path).includes(`${join14("node_modules", "deepline")}`);
36291
+ return realpathSync3(path).includes(`${join15("node_modules", "deepline")}`);
35868
36292
  } catch {
35869
36293
  return false;
35870
36294
  }
@@ -35874,11 +36298,11 @@ function isInstallerManagedLegacyLauncher(path) {
35874
36298
  return content.includes("DEEPLINE_REAL_BINARY") && content.includes("DEEPLINE_ACTIVE_FILE");
35875
36299
  }
35876
36300
  function removeKnownLegacyPaths(baseUrl) {
35877
- const home = homedir10();
35878
- const hostDir = join14(home, ".local", "deepline", baseUrlSlug(baseUrl));
35879
- const legacyLauncherPath = join14(home, ".local", "bin", "deepline");
36301
+ const home = homedir9();
36302
+ const hostDir = join15(home, ".local", "deepline", baseUrlSlug(baseUrl));
36303
+ const legacyLauncherPath = join15(home, ".local", "bin", "deepline");
35880
36304
  const installerCommandPath = safeRead(
35881
- join14(hostDir, "sdk", ".command-path")
36305
+ join15(hostDir, "sdk", ".command-path")
35882
36306
  ).trim();
35883
36307
  const relativeInstallerCommandPath = installerCommandPath ? relative5(resolve14(hostDir), resolve14(installerCommandPath)) : "";
35884
36308
  const isOwnedInstallerCommand = Boolean(installerCommandPath) && relativeInstallerCommandPath !== "" && !relativeInstallerCommandPath.startsWith(
@@ -35886,21 +36310,21 @@ function removeKnownLegacyPaths(baseUrl) {
35886
36310
  ) && relativeInstallerCommandPath !== ".." && basename6(installerCommandPath) === "deepline";
35887
36311
  const candidates = [
35888
36312
  ...isInstallerManagedLegacyLauncher(legacyLauncherPath) ? [legacyLauncherPath] : [],
35889
- join14(home, ".local", "bin", "deepline-real"),
35890
- join14(hostDir, "bin", "deepline"),
35891
- join14(hostDir, "bin", "deepline-real"),
35892
- join14(hostDir, "cli", ".install-method"),
35893
- join14(hostDir, "cli", ".version"),
35894
- join14(hostDir, "sdk", ".install-method"),
35895
- join14(hostDir, "sdk", ".command-path"),
36313
+ join15(home, ".local", "bin", "deepline-real"),
36314
+ join15(hostDir, "bin", "deepline"),
36315
+ join15(hostDir, "bin", "deepline-real"),
36316
+ join15(hostDir, "cli", ".install-method"),
36317
+ join15(hostDir, "cli", ".version"),
36318
+ join15(hostDir, "sdk", ".install-method"),
36319
+ join15(hostDir, "sdk", ".command-path"),
35896
36320
  ...isOwnedInstallerCommand ? [
35897
36321
  installerCommandPath,
35898
- join14(dirname13(installerCommandPath), "deepline-sdk")
36322
+ join15(dirname15(installerCommandPath), "deepline-sdk")
35899
36323
  ] : []
35900
36324
  ];
35901
36325
  const removed = [];
35902
36326
  for (const path of candidates) {
35903
- if (!existsSync12(path)) continue;
36327
+ if (!existsSync13(path)) continue;
35904
36328
  if (path === installerCommandPath && isNpmManagedDeeplinePath(path)) {
35905
36329
  continue;
35906
36330
  }
@@ -35910,7 +36334,7 @@ function removeKnownLegacyPaths(baseUrl) {
35910
36334
  return removed;
35911
36335
  }
35912
36336
  function resolvePathCommands(command) {
35913
- const lookup = spawnSync(
36337
+ const lookup = spawnSync2(
35914
36338
  process.platform === "win32" ? "where" : "which",
35915
36339
  process.platform === "win32" ? [command] : ["-a", command],
35916
36340
  { encoding: "utf8", shell: process.platform === "win32" }
@@ -35937,8 +36361,8 @@ function isHomebrewFormulaCommand(path) {
35937
36361
  }
35938
36362
  function resolvePersistentGlobalCommand(dependencies = {}) {
35939
36363
  const platform3 = dependencies.platform ?? process.platform;
35940
- const run = dependencies.spawn ?? spawnSync;
35941
- const pathExists = dependencies.exists ?? existsSync12;
36364
+ const run = dependencies.spawn ?? spawnSync2;
36365
+ const pathExists = dependencies.exists ?? existsSync13;
35942
36366
  const pathClis = dependencies.pathClis ?? resolvePathCommands("deepline");
35943
36367
  const homebrewCommand = pathClis.find(isHomebrewFormulaCommand);
35944
36368
  if (homebrewCommand) return homebrewCommand;
@@ -35950,7 +36374,7 @@ function resolvePersistentGlobalCommand(dependencies = {}) {
35950
36374
  if (prefix.status !== 0) return null;
35951
36375
  const root = String(prefix.stdout ?? "").trim();
35952
36376
  if (!root) return null;
35953
- const candidates = platform3 === "win32" ? [join14(root, "deepline.cmd"), join14(root, "deepline")] : [join14(root, "bin", "deepline")];
36377
+ const candidates = platform3 === "win32" ? [join15(root, "deepline.cmd"), join15(root, "deepline")] : [join15(root, "bin", "deepline")];
35954
36378
  return candidates.find((candidate) => pathExists(candidate)) ?? null;
35955
36379
  }
35956
36380
  function inspectGlobalCliAvailability(input2) {
@@ -35976,7 +36400,7 @@ function isKnownDeeplineCommand(path) {
35976
36400
  } catch {
35977
36401
  }
35978
36402
  if (entrypoint && resolvedPath === entrypoint) return true;
35979
- if (resolvedPath.includes(`${join14("node_modules", "deepline")}`)) return true;
36403
+ if (resolvedPath.includes(`${join15("node_modules", "deepline")}`)) return true;
35980
36404
  const content = safeRead(path);
35981
36405
  return content.includes("node_modules/deepline") || content.includes("node_modules\\deepline") || content.includes("DEEPLINE_CONFIG_SCOPE") || content.includes("deepline-real");
35982
36406
  }
@@ -35986,7 +36410,7 @@ function inspectPathConflict() {
35986
36410
  try {
35987
36411
  if (lstatSync(commandPath).isSymbolicLink()) {
35988
36412
  const target = realpathSync3(commandPath);
35989
- if (target.includes(`${join14("node_modules", "deepline")}`)) return null;
36413
+ if (target.includes(`${join15("node_modules", "deepline")}`)) return null;
35990
36414
  }
35991
36415
  } catch {
35992
36416
  }
@@ -35994,8 +36418,8 @@ function inspectPathConflict() {
35994
36418
  }
35995
36419
  function writeSetupState(input2) {
35996
36420
  const path = setupStatePath(input2.baseUrl, input2.scope, input2.root);
35997
- mkdirSync9(dirname13(path), { recursive: true });
35998
- writeFileSync12(
36421
+ mkdirSync11(dirname15(path), { recursive: true });
36422
+ writeFileSync14(
35999
36423
  path,
36000
36424
  `${JSON.stringify(
36001
36425
  {
@@ -36035,7 +36459,7 @@ function failSetupPhase(phases, phase, code) {
36035
36459
  phases[phase] = { status: "failed", code };
36036
36460
  }
36037
36461
  function rollbackCommand(scope, root) {
36038
- const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify(join14(root, ".deepline", "runtime"))}` : "";
36462
+ const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify(join15(root, ".deepline", "runtime"))}` : "";
36039
36463
  return `npm install -g${prefix} --no-audit --no-fund --include=optional --allow-scripts=esbuild deepline@${SDK_VERSION}`;
36040
36464
  }
36041
36465
  function setupResumeCommand(baseUrl, scope) {
@@ -36127,7 +36551,7 @@ function buildDoctorAssessment(input2) {
36127
36551
  const pathGlobalCli = globalCli?.path ?? null;
36128
36552
  const cliPath = input2.scope === "global" ? pathGlobalCli : runningCliPath;
36129
36553
  const cliScopeOk = input2.scope === "global" ? Boolean(pathGlobalCli) : Boolean(
36130
- input2.root && runningCliPath?.includes(join14(input2.root, ".deepline", "runtime"))
36554
+ input2.root && runningCliPath?.includes(join15(input2.root, ".deepline", "runtime"))
36131
36555
  );
36132
36556
  const checks = {
36133
36557
  cli: {
@@ -37282,165 +37706,6 @@ chooses the connected Slack channel or member and the events it receives.
37282
37706
  });
37283
37707
  }
37284
37708
 
37285
- // src/cli/commands/switch.ts
37286
- import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
37287
- import { homedir as homedir11 } from "os";
37288
- import { dirname as dirname14, join as join15 } from "path";
37289
- function hostSlugFromBaseUrl(baseUrl) {
37290
- try {
37291
- const url = new URL(baseUrl);
37292
- const port = url.port ? Number.parseInt(url.port, 10) : null;
37293
- let slug = (url.hostname || "unknown").replace(/[^a-zA-Z0-9]/g, "-");
37294
- if (port && port !== 80 && port !== 443) {
37295
- slug = `${slug}-${port}`;
37296
- }
37297
- return slug.toLowerCase().replace(/^-+|-+$/g, "") || "unknown";
37298
- } catch {
37299
- return "unknown";
37300
- }
37301
- }
37302
- function resolveConfigScope() {
37303
- const explicit = (process.env.DEEPLINE_CONFIG_SCOPE || "").trim();
37304
- if (explicit) return explicit;
37305
- return hostSlugFromBaseUrl(autoDetectBaseUrl());
37306
- }
37307
- function activeFamilyPath() {
37308
- const home = process.env.HOME || process.env.USERPROFILE || homedir11();
37309
- return join15(
37310
- home,
37311
- ".local",
37312
- "deepline",
37313
- resolveConfigScope(),
37314
- "cli",
37315
- ".active-family"
37316
- );
37317
- }
37318
- function readActiveFamily() {
37319
- const path = activeFamilyPath();
37320
- try {
37321
- return readFileSync13(path, "utf-8").trim() || "sdk";
37322
- } catch {
37323
- return "sdk";
37324
- }
37325
- }
37326
- function writeActiveFamily(family) {
37327
- const path = activeFamilyPath();
37328
- mkdirSync10(dirname14(path), { recursive: true });
37329
- writeFileSync13(path, `${family}
37330
- `, "utf-8");
37331
- return path;
37332
- }
37333
- function forcePythonCliFamily() {
37334
- return writeActiveFamily("python");
37335
- }
37336
- function handleSwitch(action, options) {
37337
- const normalized = (action || "status").trim().toLowerCase();
37338
- if (normalized === "status") {
37339
- const path = activeFamilyPath();
37340
- const activeFamily = readActiveFamily();
37341
- printCommandEnvelope(
37342
- {
37343
- ok: true,
37344
- active_family: activeFamily,
37345
- active_family_path: path,
37346
- active_family_file_exists: existsSync13(path),
37347
- render: {
37348
- sections: [
37349
- {
37350
- title: "cli switch",
37351
- lines: [
37352
- `Active CLI family: ${activeFamily}`,
37353
- `Active family file: ${path}`
37354
- ]
37355
- }
37356
- ]
37357
- }
37358
- },
37359
- { json: options.json }
37360
- );
37361
- return 0;
37362
- }
37363
- if (normalized === "python" || normalized === "rollback") {
37364
- const path = writeActiveFamily("python");
37365
- printCommandEnvelope(
37366
- {
37367
- ok: true,
37368
- active_family: "python",
37369
- active_family_path: path,
37370
- render: {
37371
- sections: [
37372
- {
37373
- title: "cli switch",
37374
- lines: [
37375
- "Switched installer-managed `deepline` to the Python CLI."
37376
- ]
37377
- }
37378
- ]
37379
- }
37380
- },
37381
- { json: options.json }
37382
- );
37383
- return 0;
37384
- }
37385
- if (normalized === "sdk") {
37386
- const path = writeActiveFamily("sdk");
37387
- printCommandEnvelope(
37388
- {
37389
- ok: true,
37390
- active_family: "sdk",
37391
- active_family_path: path,
37392
- render: {
37393
- sections: [
37394
- {
37395
- title: "cli switch",
37396
- lines: ["Switched installer-managed `deepline` to the SDK CLI."]
37397
- }
37398
- ]
37399
- }
37400
- },
37401
- { json: options.json }
37402
- );
37403
- return 0;
37404
- }
37405
- const message = `Unknown switch target: ${action}. Use one of: status, sdk, python, rollback.`;
37406
- const envelope = {
37407
- ok: false,
37408
- error: message,
37409
- code: "usage_error",
37410
- render: {
37411
- sections: [{ title: "cli switch", lines: [message] }]
37412
- }
37413
- };
37414
- const wantsJson = options.json === true;
37415
- if (wantsJson) {
37416
- printCommandEnvelope(envelope, { json: true });
37417
- } else {
37418
- process.stderr.write(`${message}
37419
- `);
37420
- }
37421
- return 2;
37422
- }
37423
- function registerSwitchCommands(program) {
37424
- program.command("switch [target]").description(
37425
- "Switch the installer-managed Deepline CLI between SDK and Python families."
37426
- ).option("--json", "Emit JSON output").addHelpText(
37427
- "after",
37428
- `
37429
- Notes:
37430
- This command changes only the local installer-managed wrapper state. It does
37431
- not re-authenticate, reinstall packages, or contact Deepline servers.
37432
-
37433
- Examples:
37434
- deepline switch status
37435
- deepline switch python
37436
- deepline switch rollback
37437
- deepline switch sdk
37438
- `
37439
- ).action((target, options) => {
37440
- process.exitCode = handleSwitch(target, options);
37441
- });
37442
- }
37443
-
37444
37709
  // src/cli/commands/tools.ts
37445
37710
  import { Option as Option2 } from "commander";
37446
37711
  import {
@@ -37448,7 +37713,7 @@ import {
37448
37713
  existsSync as existsSync14,
37449
37714
  mkdtempSync,
37450
37715
  readFileSync as readFileSync14,
37451
- writeFileSync as writeFileSync15
37716
+ writeFileSync as writeFileSync16
37452
37717
  } from "fs";
37453
37718
  import { tmpdir as tmpdir5 } from "os";
37454
37719
  import { join as join17, resolve as resolve15 } from "path";
@@ -37456,13 +37721,13 @@ import { join as join17, resolve as resolve15 } from "path";
37456
37721
  // src/tool-output.ts
37457
37722
  import {
37458
37723
  closeSync as closeSync3,
37459
- mkdirSync as mkdirSync11,
37724
+ mkdirSync as mkdirSync12,
37460
37725
  openSync as openSync3,
37461
- writeFileSync as writeFileSync14,
37726
+ writeFileSync as writeFileSync15,
37462
37727
  writeSync
37463
37728
  } from "fs";
37464
- import { homedir as homedir12 } from "os";
37465
- import { dirname as dirname15, join as join16 } from "path";
37729
+ import { homedir as homedir10 } from "os";
37730
+ import { dirname as dirname16, join as join16 } from "path";
37466
37731
  function isPlainObject(value) {
37467
37732
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
37468
37733
  }
@@ -37589,19 +37854,19 @@ function projectRowOutput(conversion) {
37589
37854
  };
37590
37855
  }
37591
37856
  function ensureOutputDir() {
37592
- const outputDir = join16(homedir12(), ".local", "share", "deepline", "data");
37593
- mkdirSync11(outputDir, { recursive: true });
37857
+ const outputDir = join16(homedir10(), ".local", "share", "deepline", "data");
37858
+ mkdirSync12(outputDir, { recursive: true });
37594
37859
  return outputDir;
37595
37860
  }
37596
37861
  function writeJsonOutputFile(payload, stem) {
37597
37862
  const outputDir = ensureOutputDir();
37598
37863
  const outputPath = join16(outputDir, `${stem}_${Date.now()}.json`);
37599
- writeFileSync14(outputPath, JSON.stringify(payload, null, 2), "utf-8");
37864
+ writeFileSync15(outputPath, JSON.stringify(payload, null, 2), "utf-8");
37600
37865
  return outputPath;
37601
37866
  }
37602
37867
  function writeCsvOutputFile(rows, stem, options) {
37603
37868
  const outputPath = options?.outPath ? options.outPath : join16(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
37604
- mkdirSync11(dirname15(outputPath), { recursive: true });
37869
+ mkdirSync12(dirname16(outputPath), { recursive: true });
37605
37870
  const columns = columnsForRows(rows);
37606
37871
  const escapeCell = (value) => {
37607
37872
  const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
@@ -37677,6 +37942,9 @@ var TOOL_CATEGORY_DESCRIPTIONS = {
37677
37942
  premium: "Higher-cost tools with premium provider coverage.",
37678
37943
  free: "Free tools that do not spend Deepline credits."
37679
37944
  };
37945
+ var WELL_KNOWN_TOOL_CATEGORIES = Object.freeze(
37946
+ Object.keys(TOOL_CATEGORY_DESCRIPTIONS)
37947
+ );
37680
37948
  function describeToolCategory(category) {
37681
37949
  return TOOL_CATEGORY_DESCRIPTIONS[category] ?? null;
37682
37950
  }
@@ -38661,17 +38929,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
38661
38929
  const extractedValues = extractionContractEntries(
38662
38930
  arrayField2(toolExecutionResult, "extractedValues", "extracted_values")
38663
38931
  );
38664
- const cost = recordField2(tool, "cost");
38665
- const deeplineCredits = numberField2(
38666
- tool,
38667
- "deeplineCreditsPerPricingUnit",
38668
- "deepline_credits_per_pricing_unit"
38669
- );
38670
- const deeplineUsdPerPricingUnit = numberField2(
38671
- tool,
38672
- "deeplineUsdPerPricingUnit",
38673
- "deepline_usd_per_pricing_unit"
38674
- );
38932
+ const pricing = toolPricingContractForDescribe(tool);
38675
38933
  const deprecation = recordField2(tool, "deprecation");
38676
38934
  const replacementToolId = stringField2(
38677
38935
  deprecation,
@@ -38713,12 +38971,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
38713
38971
  ...Object.prototype.hasOwnProperty.call(field, "default") ? { default: field.default } : {}
38714
38972
  })),
38715
38973
  inputSchema,
38716
- cost: {
38717
- pricingModel: stringField2(cost, "pricingModel", "pricing_model") || null,
38718
- billingMode: stringField2(cost, "billingMode", "billing_mode") || null,
38719
- deeplineCreditsPerPricingUnit: deeplineCredits,
38720
- deeplineUsdPerPricingUnit
38721
- },
38974
+ cost: pricing,
38722
38975
  getters: {
38723
38976
  extractedLists,
38724
38977
  extractedValues
@@ -38727,6 +38980,38 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
38727
38980
  ...starterScript ? { starterScript } : {}
38728
38981
  };
38729
38982
  }
38983
+ function toolPricingContractForDescribe(tool) {
38984
+ const legacyCost = recordField2(tool, "cost");
38985
+ const pricingValue = tool.pricing;
38986
+ const hasCanonicalPricing = isRecord12(pricingValue);
38987
+ const canonicalPricing = hasCanonicalPricing ? pricingValue : {};
38988
+ const unit = stringField2(canonicalPricing, "unit");
38989
+ const legacyPricingModel = stringField2(
38990
+ legacyCost,
38991
+ "pricingModel",
38992
+ "pricing_model"
38993
+ );
38994
+ const pricingModel = unit === "call" ? "fixed" : unit === "result" || unit === "page" ? `per_${unit}` : unit === "usage" ? "provider_usage" : legacyPricingModel;
38995
+ return {
38996
+ pricingModel: pricingModel || null,
38997
+ unit: unit || null,
38998
+ displayText: stringField2(canonicalPricing, "displayText", "display_text") || null,
38999
+ summary: stringField2(canonicalPricing, "summary") || null,
39000
+ billingMode: stringField2(legacyCost, "billingMode", "billing_mode") || null,
39001
+ billingSource: stringField2(tool, "billingSource", "billing_source") || null,
39002
+ billingSourceLabel: stringField2(tool, "billingSourceLabel", "billing_source_label") || null,
39003
+ deeplineCreditsPerPricingUnit: hasCanonicalPricing ? numberField2(canonicalPricing, "creditsPerUnit", "credits_per_unit") : numberField2(
39004
+ tool,
39005
+ "deeplineCreditsPerPricingUnit",
39006
+ "deepline_credits_per_pricing_unit"
39007
+ ),
39008
+ deeplineUsdPerPricingUnit: hasCanonicalPricing ? numberField2(canonicalPricing, "usdPerUnit", "usd_per_unit") : numberField2(
39009
+ tool,
39010
+ "deeplineUsdPerPricingUnit",
39011
+ "deepline_usd_per_pricing_unit"
39012
+ )
39013
+ };
39014
+ }
38730
39015
  function extractionContractEntries(entries) {
38731
39016
  return entries.flatMap((entry) => {
38732
39017
  if (!isRecord12(entry)) return [];
@@ -38956,13 +39241,16 @@ function printToolPricingOnly(tool, requestedToolId, options = {}) {
38956
39241
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
38957
39242
  const cost = isRecord12(contract.cost) ? contract.cost : {};
38958
39243
  const pricingModel = stringField2(cost, "pricingModel") || "unknown";
38959
- const billingMode = stringField2(cost, "billingMode") || "unknown";
38960
- const unit = pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit";
39244
+ const billing = stringField2(cost, "billingMode") || stringField2(cost, "billingSourceLabel") || stringField2(cost, "billingSource") || "unknown";
39245
+ const explicitUnit = stringField2(cost, "unit");
39246
+ const unit = explicitUnit || (pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit");
38961
39247
  const credits = numberField2(cost, "deeplineCreditsPerPricingUnit");
38962
39248
  const usd = numberField2(cost, "deeplineUsdPerPricingUnit");
38963
- const price = credits !== null ? `${formatDecimal(credits)} Deepline credits${usd !== null ? ` / ${formatUsd(usd)}` : ""} per ${unit}` : "pricing unavailable";
39249
+ const displayText = stringField2(cost, "displayText");
39250
+ const summary = stringField2(cost, "summary");
39251
+ const price = displayText || summary || (credits !== null ? `${formatDecimal(credits)} Deepline credits${usd !== null ? ` / ${formatUsd(usd)}` : ""} per ${unit}` : "pricing unavailable");
38964
39252
  console.log(`${options.heading ?? `Pricing: ${contract.toolId}`}: ${price}`);
38965
- console.log(`Billing: ${billingMode}`);
39253
+ console.log(`Billing: ${billing}`);
38966
39254
  }
38967
39255
  function printToolSchemaOnly(tool, requestedToolId) {
38968
39256
  if (isMonitorTypeTool(tool)) {
@@ -39433,9 +39721,9 @@ function apifySyncRecoveryNext(rawResponse) {
39433
39721
  const getDatasetItemsTool = stringField2(getDatasetItems, "tool");
39434
39722
  const getDatasetItemsPayload = recordField2(getDatasetItems, "payload");
39435
39723
  return {
39436
- getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote3(JSON.stringify(getActorRunPayload))} --json`,
39724
+ getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote4(JSON.stringify(getActorRunPayload))} --json`,
39437
39725
  ...getDatasetItemsTool && Object.keys(getDatasetItemsPayload).length > 0 ? {
39438
- getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote3(JSON.stringify(getDatasetItemsPayload))} --json`
39726
+ getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote4(JSON.stringify(getDatasetItemsPayload))} --json`
39439
39727
  } : {}
39440
39728
  };
39441
39729
  }
@@ -39608,7 +39896,7 @@ function parseExecuteOptions(args) {
39608
39896
  function safeFileStem(value) {
39609
39897
  return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
39610
39898
  }
39611
- function shellQuote3(value) {
39899
+ function shellQuote4(value) {
39612
39900
  return `'${value.replace(/'/g, `'\\''`)}'`;
39613
39901
  }
39614
39902
  function powerShellQuote(value) {
@@ -39673,12 +39961,12 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
39673
39961
  description: ${JSON.stringify(`Seed ${input2.toolId} rows into a Deepline workflow-ready dataset.`)},
39674
39962
  });
39675
39963
  `;
39676
- writeFileSync15(scriptPath, script, { encoding: "utf-8", mode: 384 });
39964
+ writeFileSync16(scriptPath, script, { encoding: "utf-8", mode: 384 });
39677
39965
  return {
39678
39966
  path: scriptPath,
39679
39967
  sourceCode: script,
39680
39968
  projectDir,
39681
- macCopyCommand: `mkdir -p ${shellQuote3(projectDir)} && cp ${shellQuote3(scriptPath)} ${shellQuote3(`${projectDir}/${fileName}`)}`,
39969
+ macCopyCommand: `mkdir -p ${shellQuote4(projectDir)} && cp ${shellQuote4(scriptPath)} ${shellQuote4(`${projectDir}/${fileName}`)}`,
39682
39970
  windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
39683
39971
  };
39684
39972
  }
@@ -39705,7 +39993,7 @@ function buildToolExecuteBaseEnvelope(input2) {
39705
39993
  envelope,
39706
39994
  "output"
39707
39995
  );
39708
- const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote3(JSON.stringify(input2.params))} --json`;
39996
+ const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote4(JSON.stringify(input2.params))} --json`;
39709
39997
  const actions = input2.listConversion ? [
39710
39998
  {
39711
39999
  label: "next",
@@ -40098,19 +40386,19 @@ Examples:
40098
40386
  }
40099
40387
 
40100
40388
  // src/cli/commands/update.ts
40101
- import { spawn as spawn3 } from "child_process";
40389
+ import { spawn as spawn4 } from "child_process";
40102
40390
  import {
40103
40391
  existsSync as existsSync16,
40104
- mkdirSync as mkdirSync12,
40392
+ mkdirSync as mkdirSync13,
40105
40393
  realpathSync as realpathSync4,
40106
40394
  readFileSync as readFileSync16,
40107
40395
  renameSync,
40108
40396
  rmSync as rmSync5,
40109
- unlinkSync,
40110
- writeFileSync as writeFileSync16
40397
+ unlinkSync as unlinkSync2,
40398
+ writeFileSync as writeFileSync17
40111
40399
  } from "fs";
40112
- import { homedir as homedir13 } from "os";
40113
- import { dirname as dirname16, isAbsolute as isAbsolute7, join as join19, relative as relative7, resolve as resolve17 } from "path";
40400
+ import { homedir as homedir11 } from "os";
40401
+ import { dirname as dirname17, isAbsolute as isAbsolute7, join as join19, relative as relative7, resolve as resolve17 } from "path";
40114
40402
 
40115
40403
  // src/cli/install-integrity.ts
40116
40404
  import { createRequire } from "module";
@@ -40302,14 +40590,14 @@ function posixShellQuote(value) {
40302
40590
  function windowsCmdQuote(value) {
40303
40591
  return `"${value.replace(/"/g, '""')}"`;
40304
40592
  }
40305
- function shellQuote4(value) {
40593
+ function shellQuote5(value) {
40306
40594
  if (process.platform === "win32") {
40307
40595
  return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
40308
40596
  }
40309
40597
  return posixShellQuote(value);
40310
40598
  }
40311
40599
  function buildSourceUpdateCommand(sourceRoot) {
40312
- const quotedRoot = shellQuote4(sourceRoot);
40600
+ const quotedRoot = shellQuote5(sourceRoot);
40313
40601
  const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
40314
40602
  return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
40315
40603
  }
@@ -40321,7 +40609,7 @@ function buildSidecarProjectConfigCommand(versionDir, nodeBin) {
40321
40609
  "fs.mkdirSync(dir,{recursive:true});",
40322
40610
  `fs.writeFileSync(path.join(dir,'package.json'),${JSON.stringify(NPM_SDK_SIDECAR_PACKAGE_JSON)});`
40323
40611
  ].join("");
40324
- return `${shellQuote4(nodeBin)} -e ${shellQuote4(script)} ${shellQuote4(versionDir)}`;
40612
+ return `${shellQuote5(nodeBin)} -e ${shellQuote5(script)} ${shellQuote5(versionDir)}`;
40325
40613
  }
40326
40614
  function sidecarStateDir(input2) {
40327
40615
  const scope = input2.env.DEEPLINE_CONFIG_SCOPE?.trim();
@@ -40384,7 +40672,7 @@ function resolvePythonSidecarUpdatePlan(options) {
40384
40672
  const npmCommand = "npm";
40385
40673
  const registryUrl = sidecarRegistryUrl(hostUrl);
40386
40674
  const versionDir = join19(stateDir, "versions", "<version>");
40387
- const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote4(versionDir)} --registry ${shellQuote4(registryUrl)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote4).join(" ")} ${shellQuote4(packageSpec)}`;
40675
+ const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote5(versionDir)} --registry ${shellQuote5(registryUrl)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote5).join(" ")} ${shellQuote5(packageSpec)}`;
40388
40676
  return {
40389
40677
  kind: "python-sidecar",
40390
40678
  stateDir,
@@ -40404,7 +40692,7 @@ function findRepoBackedSdkRoot(startPath) {
40404
40692
  if (existsSync16(join19(current, "sdk", "package.json")) && existsSync16(join19(current, "sdk", "bin", "deepline-dev.ts"))) {
40405
40693
  return current;
40406
40694
  }
40407
- const parent = dirname16(current);
40695
+ const parent = dirname17(current);
40408
40696
  if (parent === current) return null;
40409
40697
  current = parent;
40410
40698
  }
@@ -40444,9 +40732,9 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
40444
40732
  }
40445
40733
  function resolveUpdatePlan(options = {}) {
40446
40734
  const env = options.env ?? process.env;
40447
- const homeDir2 = options.homeDir ?? homedir13();
40735
+ const homeDir2 = options.homeDir ?? homedir11();
40448
40736
  const entrypoint = options.entrypoint ?? (process.argv[1] ? resolve17(process.argv[1]) : "");
40449
- const sourceRoot = entrypoint ? findRepoBackedSdkRoot(dirname16(entrypoint)) : null;
40737
+ const sourceRoot = entrypoint ? findRepoBackedSdkRoot(dirname17(entrypoint)) : null;
40450
40738
  if (sourceRoot) {
40451
40739
  return {
40452
40740
  kind: "source",
@@ -40486,7 +40774,7 @@ function resolveUpdatePlan(options = {}) {
40486
40774
  fallbackRegistryUrl: publicNpmFallbackRegistryUrl(
40487
40775
  env.DEEPLINE_HOST_URL?.trim() || autoDetectBaseUrl()
40488
40776
  ),
40489
- manualCommand: `${command} ${args.map(shellQuote4).join(" ")}`
40777
+ manualCommand: `${command} ${args.map(shellQuote5).join(" ")}`
40490
40778
  };
40491
40779
  }
40492
40780
  var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
@@ -40496,7 +40784,7 @@ function autoUpdateFailurePath(plan) {
40496
40784
  return join19(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
40497
40785
  }
40498
40786
  return join19(
40499
- homedir13(),
40787
+ homedir11(),
40500
40788
  ".local",
40501
40789
  "deepline",
40502
40790
  "sdk-cli",
@@ -40534,8 +40822,8 @@ function writeAutoUpdateFailure(plan, exitCode) {
40534
40822
  manualCommand: plan.manualCommand
40535
40823
  };
40536
40824
  try {
40537
- mkdirSync12(dirname16(path), { recursive: true });
40538
- writeFileSync16(path, `${JSON.stringify(marker, null, 2)}
40825
+ mkdirSync13(dirname17(path), { recursive: true });
40826
+ writeFileSync17(path, `${JSON.stringify(marker, null, 2)}
40539
40827
  `, "utf8");
40540
40828
  } catch {
40541
40829
  }
@@ -40544,7 +40832,7 @@ function clearAutoUpdateFailure(plan) {
40544
40832
  const path = autoUpdateFailurePath(plan);
40545
40833
  if (!path) return;
40546
40834
  try {
40547
- unlinkSync(path);
40835
+ unlinkSync2(path);
40548
40836
  } catch {
40549
40837
  }
40550
40838
  }
@@ -40626,7 +40914,7 @@ function runCommand(command, args, env = process.env) {
40626
40914
  return new Promise((resolveResult) => {
40627
40915
  let output2 = "";
40628
40916
  const plan = resolveShellSpawn(command, args);
40629
- const child = spawn3(plan.command, plan.args, {
40917
+ const child = spawn4(plan.command, plan.args, {
40630
40918
  stdio: ["inherit", "pipe", "pipe"],
40631
40919
  shell: plan.shell,
40632
40920
  env
@@ -40714,9 +41002,9 @@ async function runNpmInstallWithRegistryFallback(input2) {
40714
41002
  return first.exitCode;
40715
41003
  }
40716
41004
  function writeSidecarLauncher(input2) {
40717
- mkdirSync12(dirname16(input2.path), { recursive: true });
40718
- const packageRoot = dirname16(dirname16(dirname16(input2.entryPath)));
40719
- const versionDir = dirname16(dirname16(packageRoot));
41005
+ mkdirSync13(dirname17(input2.path), { recursive: true });
41006
+ const packageRoot = dirname17(dirname17(dirname17(input2.entryPath)));
41007
+ const versionDir = dirname17(dirname17(packageRoot));
40720
41008
  const esbuildProbe = "const {createRequire}=require('node:module');const path=require('node:path');const req=createRequire(path.join(process.argv[1],'package.json'));const result=req('esbuild').transformSync('const value: number = 1;',{loader:'ts'});if(!result||typeof result.code!=='string')process.exit(3);";
40721
41009
  const criticalPaths = [
40722
41010
  ...SDK_SIDECAR_CRITICAL_PACKAGE_FILES.map(
@@ -40727,7 +41015,7 @@ function writeSidecarLauncher(input2) {
40727
41015
  )
40728
41016
  ];
40729
41017
  if (process.platform === "win32") {
40730
- writeFileSync16(
41018
+ writeFileSync17(
40731
41019
  input2.path,
40732
41020
  [
40733
41021
  `@set DEEPLINE_HOST_URL=${input2.hostUrl.replace(/\r?\n/g, "")}`,
@@ -40750,27 +41038,27 @@ function writeSidecarLauncher(input2) {
40750
41038
  );
40751
41039
  return;
40752
41040
  }
40753
- writeFileSync16(
41041
+ writeFileSync17(
40754
41042
  input2.path,
40755
41043
  [
40756
41044
  "#!/usr/bin/env sh",
40757
- `export DEEPLINE_HOST_URL=${shellQuote4(input2.hostUrl)}`,
40758
- `export DEEPLINE_CONFIG_SCOPE=${shellQuote4(input2.scope)}`,
40759
- `if ${criticalPaths.map((path) => `[ ! -f ${shellQuote4(path)} ]`).join(" || ")}; then`,
41045
+ `export DEEPLINE_HOST_URL=${shellQuote5(input2.hostUrl)}`,
41046
+ `export DEEPLINE_CONFIG_SCOPE=${shellQuote5(input2.scope)}`,
41047
+ `if ${criticalPaths.map((path) => `[ ! -f ${shellQuote5(path)} ]`).join(" || ")}; then`,
40760
41048
  ' if [ -n "${DEEPLINE_REAL_BINARY:-}" ] && [ -x "$DEEPLINE_REAL_BINARY" ]; then',
40761
41049
  ' exec "$DEEPLINE_REAL_BINARY" --version=v2 "$@"',
40762
41050
  " fi",
40763
41051
  ' printf "%s\\n" "Deepline SDK CLI install is incomplete. Run \\`deepline update\\` to repair it." >&2',
40764
41052
  " exit 1",
40765
41053
  "fi",
40766
- `if ! ${shellQuote4(input2.nodeBin)} -e ${shellQuote4(esbuildProbe)} ${shellQuote4(versionDir)} >/dev/null 2>&1; then`,
41054
+ `if ! ${shellQuote5(input2.nodeBin)} -e ${shellQuote5(esbuildProbe)} ${shellQuote5(versionDir)} >/dev/null 2>&1; then`,
40767
41055
  ' if [ -n "${DEEPLINE_REAL_BINARY:-}" ] && [ -x "$DEEPLINE_REAL_BINARY" ]; then',
40768
41056
  ' exec "$DEEPLINE_REAL_BINARY" --version=v2 "$@"',
40769
41057
  " fi",
40770
41058
  ' printf "%s\\n" "Deepline SDK CLI install is incomplete. Run \\`deepline update\\` to repair it." >&2',
40771
41059
  " exit 1",
40772
41060
  "fi",
40773
- `exec ${shellQuote4(input2.nodeBin)} ${shellQuote4(input2.entryPath)} "$@"`,
41061
+ `exec ${shellQuote5(input2.nodeBin)} ${shellQuote5(input2.entryPath)} "$@"`,
40774
41062
  ""
40775
41063
  ].join("\n"),
40776
41064
  { encoding: "utf8", mode: 493 }
@@ -40783,11 +41071,11 @@ async function runPythonSidecarUpdatePlan(plan) {
40783
41071
  `.tmp-sdk-update-${process.pid}-${Date.now()}`
40784
41072
  );
40785
41073
  rmSync5(tempDir, { recursive: true, force: true });
40786
- mkdirSync12(tempDir, { recursive: true });
40787
- writeFileSync16(join19(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
41074
+ mkdirSync13(tempDir, { recursive: true });
41075
+ writeFileSync17(join19(tempDir, "package.json"), NPM_SDK_SIDECAR_PACKAGE_JSON);
40788
41076
  const env = {
40789
41077
  ...process.env,
40790
- PATH: `${dirname16(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
41078
+ PATH: `${dirname17(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
40791
41079
  };
40792
41080
  const installResult = await runCommand(
40793
41081
  plan.npmCommand,
@@ -40907,27 +41195,27 @@ async function runPythonSidecarUpdatePlan(plan) {
40907
41195
  nodeBin: plan.nodeBin,
40908
41196
  entryPath: finalEntryPath
40909
41197
  });
40910
- writeFileSync16(
41198
+ writeFileSync17(
40911
41199
  join19(plan.stateDir, ".version"),
40912
41200
  `${installedVersion}
40913
41201
  `,
40914
41202
  "utf8"
40915
41203
  );
40916
- writeFileSync16(
41204
+ writeFileSync17(
40917
41205
  join19(plan.stateDir, ".install-method"),
40918
41206
  "python-sidecar\n",
40919
41207
  "utf8"
40920
41208
  );
40921
- writeFileSync16(
41209
+ writeFileSync17(
40922
41210
  join19(plan.stateDir, ".command-path"),
40923
41211
  `${plan.sidecarPath}
40924
41212
  `,
40925
41213
  "utf8"
40926
41214
  );
40927
- writeFileSync16(join19(plan.stateDir, ".runner"), "node\n", "utf8");
40928
- writeFileSync16(join19(plan.stateDir, ".node-bin"), `${plan.nodeBin}
41215
+ writeFileSync17(join19(plan.stateDir, ".runner"), "node\n", "utf8");
41216
+ writeFileSync17(join19(plan.stateDir, ".node-bin"), `${plan.nodeBin}
40929
41217
  `, "utf8");
40930
- writeFileSync16(
41218
+ writeFileSync17(
40931
41219
  join19(plan.stateDir, ".entry-path"),
40932
41220
  `${finalEntryPath}
40933
41221
  `,
@@ -41023,7 +41311,17 @@ async function runUpdateCommand(options, dependencies = {}) {
41023
41311
  if (updateExitCode !== 0) {
41024
41312
  return updateExitCode;
41025
41313
  }
41026
- await syncSkills(normalizeBaseUrl3(detectBaseUrl()));
41314
+ try {
41315
+ await syncSkills(normalizeBaseUrl3(detectBaseUrl()));
41316
+ } catch (error) {
41317
+ const detail = error instanceof Error ? error.message : String(error);
41318
+ stderr.write(
41319
+ `Deepline SDK/CLI update completed, but the optional local agent-skills refresh failed. Your CLI update succeeded; this does not affect authentication, data, billing, or the command result.
41320
+ Skills refresh detail: ${detail}
41321
+ To retry with full installer output, run: deepline skills --json
41322
+ `
41323
+ );
41324
+ }
41027
41325
  return 0;
41028
41326
  }
41029
41327
  function registerUpdateCommand(program) {
@@ -41051,7 +41349,7 @@ Examples:
41051
41349
 
41052
41350
  // src/cli/commands/workflow.ts
41053
41351
  import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
41054
- import { dirname as dirname17, join as join20, resolve as resolve18 } from "path";
41352
+ import { dirname as dirname18, join as join20, resolve as resolve18 } from "path";
41055
41353
 
41056
41354
  // src/cli/workflow-to-play.ts
41057
41355
  import { createHash as createHash5 } from "crypto";
@@ -41303,7 +41601,7 @@ async function transformOne(api, workflowId, outDir, publish) {
41303
41601
  { workflowName: workflow.name, version: revision.version }
41304
41602
  );
41305
41603
  const file = join20(resolve18(outDir), `${compiled.playName}.play.ts`);
41306
- await mkdir5(dirname17(file), { recursive: true });
41604
+ await mkdir5(dirname18(file), { recursive: true });
41307
41605
  await writeFile5(file, compiled.sourceCode, "utf8");
41308
41606
  let published = false;
41309
41607
  if (publish) {
@@ -41574,108 +41872,15 @@ function registerDeeplineCommandGroups(program) {
41574
41872
  registerCsvCommands(program);
41575
41873
  registerDbCommands(program);
41576
41874
  registerFeedbackCommands(program);
41577
- registerLegacyNoopCommands(program);
41875
+ registerDeprecatedCommands(program);
41578
41876
  registerUpdateCommand(program);
41579
41877
  registerSkillsCommand(program);
41580
41878
  registerSetupCommands(program);
41581
41879
  registerQuickstartCommands(program);
41582
- registerSwitchCommands(program);
41583
- }
41584
-
41585
- // ../shared_libs/cli/command-compatibility.json
41586
- var command_compatibility_default = {
41587
- enrich: {
41588
- family: "python",
41589
- label: "a legacy Python CLI enrichment command",
41590
- sdk_alternative: "Use `deepline plays ...` for durable workflows or `deepline tools execute ...` for one tool call."
41591
- },
41592
- session: {
41593
- family: "python",
41594
- label: "a legacy Python CLI session/playground command",
41595
- sdk_alternative: "Use `deepline sessions send ...` or `deepline sessions render ...` for transcript workflows."
41596
- },
41597
- workflows: {
41598
- family: "python",
41599
- label: "a legacy Python CLI workflow command",
41600
- sdk_alternative: "Use `deepline plays ...` in the SDK CLI."
41601
- },
41602
- events: {
41603
- family: "python",
41604
- label: "a legacy Python CLI event command"
41605
- },
41606
- plays: {
41607
- family: "sdk",
41608
- label: "an SDK CLI play command",
41609
- python_alternative: "Use `deepline workflows ...` only for legacy workflows."
41610
- },
41611
- runs: {
41612
- family: "sdk",
41613
- label: "an SDK CLI run inspection command"
41614
- },
41615
- sessions: {
41616
- family: "sdk",
41617
- label: "an SDK CLI session transcript command"
41618
- },
41619
- health: {
41620
- family: "sdk",
41621
- label: "an SDK CLI health command"
41622
- }
41623
- };
41624
-
41625
- // src/cli/command-compatibility.ts
41626
- var COMMAND_COMPATIBILITY = command_compatibility_default;
41627
- function cliFamilyLabel(family) {
41628
- return family === "sdk" ? "SDK CLI" : "legacy Python CLI";
41629
- }
41630
- function commandCompatibilityHint(currentFamily, commandName, baseUrl) {
41631
- const compatibility = COMMAND_COMPATIBILITY[commandName];
41632
- if (!compatibility || compatibility.family === currentFamily) {
41633
- return null;
41634
- }
41635
- const expectedFamily = compatibility.family;
41636
- const currentLabel = cliFamilyLabel(currentFamily);
41637
- const expectedLabel = cliFamilyLabel(expectedFamily);
41638
- const lines = [
41639
- "",
41640
- "Command compatibility:",
41641
- ` \`deepline ${commandName}\` is ${compatibility.label}.`,
41642
- ` Current binary: ${currentLabel}. Required binary: ${expectedLabel}.`,
41643
- " If this came from an agent skill, the installed skill likely targets the other Deepline CLI."
41644
- ];
41645
- if (currentFamily === "sdk") {
41646
- lines.push(
41647
- "",
41648
- " To stay on the SDK CLI, refresh the Deepline agent skills:",
41649
- ` ${skillsInstallCommand(baseUrl, DEFAULT_SDK_SKILL_NAMES)}`,
41650
- " To use the legacy Python CLI instead:",
41651
- ` ${legacyPythonInstallCommand(baseUrl)}`,
41652
- " `deepline update` updates this SDK CLI, but it will not switch CLI families."
41653
- );
41654
- if (compatibility.sdk_alternative) {
41655
- lines.push(` SDK alternative: ${compatibility.sdk_alternative}`);
41656
- }
41657
- } else {
41658
- lines.push(
41659
- "",
41660
- " To use SDK commands, install the SDK CLI and refresh Deepline agent skills:",
41661
- ` ${sdkNpmGlobalInstallCommand()}`,
41662
- ` ${skillsInstallCommand(baseUrl, DEFAULT_SDK_SKILL_NAMES)}`,
41663
- " `deepline update` updates this Python CLI and its skills, but it will not switch CLI families."
41664
- );
41665
- if (compatibility.python_alternative) {
41666
- lines.push(` Python alternative: ${compatibility.python_alternative}`);
41667
- }
41668
- }
41669
- return lines.join("\n");
41670
- }
41671
- function unknownCommandNameFromMessage(message) {
41672
- const match = message.match(/unknown command ['"]([^'"]+)['"]/i);
41673
- const command = match?.[1]?.trim();
41674
- return command ? command : null;
41675
41880
  }
41676
41881
 
41677
41882
  // src/cli/self-update.ts
41678
- import { spawn as spawn4 } from "child_process";
41883
+ import { spawn as spawn5 } from "child_process";
41679
41884
  function envTruthy(name) {
41680
41885
  const value = process.env[name]?.trim().toLowerCase();
41681
41886
  return value === "1" || value === "true" || value === "yes";
@@ -41722,7 +41927,7 @@ function relaunchCurrentCommand(plan) {
41722
41927
  return new Promise((resolve19) => {
41723
41928
  const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
41724
41929
  const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
41725
- const child = spawn4(command, args, {
41930
+ const child = spawn5(command, args, {
41726
41931
  stdio: "inherit",
41727
41932
  shell: process.platform === "win32",
41728
41933
  env: {
@@ -41791,357 +41996,6 @@ What changed in ${response.update_summary.version}: ${response.update_summary.su
41791
41996
  return true;
41792
41997
  }
41793
41998
 
41794
- // src/cli/skills-sync.ts
41795
- import { spawn as spawn5, spawnSync as spawnSync2 } from "child_process";
41796
- import {
41797
- existsSync as existsSync17,
41798
- mkdirSync as mkdirSync13,
41799
- readFileSync as readFileSync17,
41800
- unlinkSync as unlinkSync2,
41801
- writeFileSync as writeFileSync17
41802
- } from "fs";
41803
- import { dirname as dirname18, join as join21 } from "path";
41804
- var CHECK_TIMEOUT_MS2 = 3e3;
41805
- function shouldSkipSkillsSync() {
41806
- if (detectAgentRuntime() === "claude_cowork") {
41807
- return true;
41808
- }
41809
- const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
41810
- return value === "1" || value === "true" || value === "yes" || value === "on";
41811
- }
41812
- function activePluginSkillsDir() {
41813
- const pluginMode = process.env.DEEPLINE_PLUGIN_MODE?.trim().toLowerCase();
41814
- if (pluginMode !== "true" && pluginMode !== "1" && pluginMode !== "yes" && pluginMode !== "on") {
41815
- return "";
41816
- }
41817
- const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
41818
- return dir && existsSync17(dir) ? dir : "";
41819
- }
41820
- function readPluginSkillsVersion() {
41821
- const dir = activePluginSkillsDir();
41822
- if (!dir) return "";
41823
- try {
41824
- return readFileSync17(join21(dir, ".version"), "utf-8").trim();
41825
- } catch {
41826
- return "";
41827
- }
41828
- }
41829
- function sdkSkillsVersionPath(baseUrl) {
41830
- return join21(sdkCliStateDirPath(baseUrl), "skills-version");
41831
- }
41832
- function legacySdkSkillsVersionPath(baseUrl) {
41833
- return join21(dirname18(sdkCliStateDirPath(baseUrl)), "sdk-skills", ".version");
41834
- }
41835
- function unavailableSkillsNoticePath(baseUrl) {
41836
- return join21(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
41837
- }
41838
- function readSdkSkillsLocalVersion(baseUrl) {
41839
- const pluginVersion = readPluginSkillsVersion();
41840
- if (pluginVersion) return pluginVersion;
41841
- const path = existsSync17(sdkSkillsVersionPath(baseUrl)) ? sdkSkillsVersionPath(baseUrl) : legacySdkSkillsVersionPath(baseUrl);
41842
- if (!existsSync17(path)) return "";
41843
- try {
41844
- return readFileSync17(path, "utf-8").trim();
41845
- } catch {
41846
- return "";
41847
- }
41848
- }
41849
- function writeLocalSkillsVersion(baseUrl, version) {
41850
- const path = sdkSkillsVersionPath(baseUrl);
41851
- mkdirSync13(dirname18(path), { recursive: true });
41852
- writeFileSync17(path, `${version}
41853
- `, "utf-8");
41854
- }
41855
- function writeUnavailableSkillsNotice(baseUrl, remoteVersion, skillNames) {
41856
- const path = unavailableSkillsNoticePath(baseUrl);
41857
- try {
41858
- if (existsSync17(path) && readFileSync17(path, "utf-8").trim() === remoteVersion) {
41859
- return;
41860
- }
41861
- mkdirSync13(dirname18(path), { recursive: true });
41862
- writeFileSync17(path, `${remoteVersion}
41863
- `, "utf-8");
41864
- } catch {
41865
- }
41866
- const manualCommand = `npx ${buildSkillsInstallArgs(baseUrl, skillNames).join(" ")}`;
41867
- writeSdkSkillsStatusLine(
41868
- `Deepline agent skills are out of date, but neither \`bunx\` nor \`npx\` is available. Install Node.js/npm or Bun, then run:
41869
- ${manualCommand}`
41870
- );
41871
- }
41872
- function clearUnavailableSkillsNotice(baseUrl) {
41873
- try {
41874
- unlinkSync2(unavailableSkillsNoticePath(baseUrl));
41875
- } catch {
41876
- }
41877
- }
41878
- function sortedUniqueSkillNames(names) {
41879
- return [...new Set(names.map((name) => name.trim()).filter(Boolean))].sort(
41880
- (a, b) => a.localeCompare(b)
41881
- );
41882
- }
41883
- async function fetchV1SkillNames(baseUrl) {
41884
- const controller = new AbortController();
41885
- const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
41886
- try {
41887
- const response = await fetch(
41888
- new URL("/.well-known/skills/index.json", baseUrl),
41889
- { signal: controller.signal }
41890
- );
41891
- if (!response.ok) return [];
41892
- const data = await response.json().catch(() => null);
41893
- const names = (data?.skills ?? []).filter((skill) => skill.install_surface === "v1").map((skill) => skill.name).filter(
41894
- (name) => typeof name === "string" && name.length > 0
41895
- );
41896
- return sortedUniqueSkillNames(names);
41897
- } catch {
41898
- return [];
41899
- } finally {
41900
- clearTimeout(timeout);
41901
- }
41902
- }
41903
- function buildSdkSkillNames(v1SkillNames) {
41904
- return sortedUniqueSkillNames(v1SkillNames);
41905
- }
41906
- async function fetchSkillsUpdate(baseUrl, localVersion) {
41907
- const controller = new AbortController();
41908
- const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
41909
- try {
41910
- const response = await fetch(new URL("/api/v2/cli/update-check", baseUrl), {
41911
- method: "POST",
41912
- headers: { "Content-Type": "application/json" },
41913
- body: JSON.stringify({
41914
- skills: {
41915
- version: localVersion
41916
- }
41917
- }),
41918
- signal: controller.signal
41919
- });
41920
- if (!response.ok) return null;
41921
- const data = await response.json().catch(() => null);
41922
- const skills = data?.skills;
41923
- if (!skills) return null;
41924
- return {
41925
- needsUpdate: skills.needs_update === true,
41926
- remoteVersion: typeof skills.remote?.version === "string" ? skills.remote.version.trim() : ""
41927
- };
41928
- } catch {
41929
- return null;
41930
- } finally {
41931
- clearTimeout(timeout);
41932
- }
41933
- }
41934
- function buildSkillsInstallArgs(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES, agents) {
41935
- return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
41936
- agents
41937
- });
41938
- }
41939
- function buildBunxSkillsInstallArgs(baseUrl, skillNames, agents) {
41940
- return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
41941
- firstArg: "--bun",
41942
- agents
41943
- });
41944
- }
41945
- function resolveAutoSyncSkillAgents() {
41946
- switch (detectAgentRuntime()) {
41947
- case "codex":
41948
- return ["codex"];
41949
- case "claude_code":
41950
- return ["claude-code"];
41951
- case "cursor":
41952
- return ["cursor"];
41953
- case "gemini":
41954
- return ["gemini-cli"];
41955
- case "antigravity":
41956
- return ["antigravity"];
41957
- default:
41958
- return [];
41959
- }
41960
- }
41961
- function hasCommand(command) {
41962
- const plan = resolveShellSpawn(command, ["--version"]);
41963
- const result = spawnSync2(plan.command, plan.args, {
41964
- stdio: "ignore",
41965
- shell: plan.shell
41966
- });
41967
- return result.status === 0;
41968
- }
41969
- function shellQuote5(arg) {
41970
- return `'${arg.replace(/'/g, `'\\''`)}'`;
41971
- }
41972
- function resolveSkillsInstallSpawn(install, platform3 = process.platform) {
41973
- return resolveShellSpawn(install.command, install.args, platform3);
41974
- }
41975
- function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES, agents = DEFAULT_SKILL_AGENTS) {
41976
- const commands = [];
41977
- if (hasCommand("bunx")) {
41978
- const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames, agents);
41979
- commands.push({
41980
- command: "bunx",
41981
- args: bunxArgs,
41982
- manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
41983
- });
41984
- }
41985
- if (hasCommand("npx")) {
41986
- const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames, agents);
41987
- commands.push({
41988
- command: "npx",
41989
- args: npxArgs,
41990
- manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
41991
- });
41992
- }
41993
- return commands;
41994
- }
41995
- function runOneSkillsInstall(install) {
41996
- return new Promise((resolve19) => {
41997
- const plan = resolveSkillsInstallSpawn(install);
41998
- const child = spawn5(plan.command, plan.args, {
41999
- stdio: ["ignore", "ignore", "pipe"],
42000
- env: process.env,
42001
- shell: plan.shell
42002
- });
42003
- let stderr = "";
42004
- child.stderr.on("data", (chunk) => {
42005
- stderr += chunk.toString("utf-8");
42006
- });
42007
- child.on("error", (error) => {
42008
- resolve19({
42009
- ok: false,
42010
- detail: `failed to start ${install.command}: ${error.message}`,
42011
- manualCommand: install.manualCommand
42012
- });
42013
- });
42014
- child.on("close", (code) => {
42015
- if (code === 0) {
42016
- resolve19({ ok: true, detail: "", manualCommand: install.manualCommand });
42017
- return;
42018
- }
42019
- const detail = stderr.trim();
42020
- resolve19({
42021
- ok: false,
42022
- detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
42023
- manualCommand: install.manualCommand
42024
- });
42025
- });
42026
- });
42027
- }
42028
- async function runSkillsInstall(installs) {
42029
- const failures = [];
42030
- for (const install of installs) {
42031
- const result = await runOneSkillsInstall(install);
42032
- if (result.ok) return true;
42033
- failures.push(result);
42034
- }
42035
- const details = failures.map((failure) => failure.detail).filter(Boolean).join("\n");
42036
- const manualCommand = failures.at(-1)?.manualCommand;
42037
- process.stderr.write(
42038
- `SDK skills sync failed${details ? `:
42039
- ${details}` : ""}
42040
- ` + (manualCommand ? `Run manually: ${manualCommand}
42041
- ` : "")
42042
- );
42043
- return false;
42044
- }
42045
- function runLegacySkillsCleanup(agents) {
42046
- const candidates = hasCommand("bunx") ? [
42047
- {
42048
- command: "bunx",
42049
- args: [
42050
- "--bun",
42051
- "skills",
42052
- "remove",
42053
- "--global",
42054
- "--agent",
42055
- ...agents,
42056
- "-y",
42057
- ...LEGACY_SKILL_NAMES_TO_REMOVE
42058
- ]
42059
- },
42060
- {
42061
- command: "npx",
42062
- args: [
42063
- "--yes",
42064
- "skills",
42065
- "remove",
42066
- "--global",
42067
- "--agent",
42068
- ...agents,
42069
- "-y",
42070
- ...LEGACY_SKILL_NAMES_TO_REMOVE
42071
- ]
42072
- }
42073
- ] : [
42074
- {
42075
- command: "npx",
42076
- args: [
42077
- "--yes",
42078
- "skills",
42079
- "remove",
42080
- "--global",
42081
- "--agent",
42082
- ...agents,
42083
- "-y",
42084
- ...LEGACY_SKILL_NAMES_TO_REMOVE
42085
- ]
42086
- }
42087
- ];
42088
- for (const candidate of candidates) {
42089
- const plan = resolveShellSpawn(candidate.command, candidate.args);
42090
- const result = spawnSync2(plan.command, plan.args, {
42091
- stdio: "ignore",
42092
- env: process.env,
42093
- shell: plan.shell
42094
- });
42095
- if (result.status === 0) return;
42096
- }
42097
- }
42098
- function writeSdkSkillsStatusLine(line) {
42099
- const progress = getActiveCliProgress();
42100
- if (progress) {
42101
- progress.writeLine(line);
42102
- return;
42103
- }
42104
- process.stderr.write(`${line}
42105
- `);
42106
- }
42107
- async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
42108
- if (shouldSkipSkillsSync()) return;
42109
- const usingPluginSkills = Boolean(activePluginSkillsDir());
42110
- if (usingPluginSkills) {
42111
- return;
42112
- }
42113
- const localVersion = readSdkSkillsLocalVersion(baseUrl);
42114
- const update = options.update === void 0 ? await fetchSkillsUpdate(baseUrl, localVersion) : options.update ? {
42115
- needsUpdate: options.update.needs_update,
42116
- remoteVersion: options.update.remote.version
42117
- } : null;
42118
- if (!update?.needsUpdate || !update.remoteVersion) {
42119
- return;
42120
- }
42121
- const remoteSkillNames = await fetchV1SkillNames(baseUrl);
42122
- const skillNames = buildSdkSkillNames(
42123
- remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
42124
- );
42125
- if (skillNames.length === 0) return;
42126
- const agents = resolveAutoSyncSkillAgents();
42127
- if (agents.length === 0) {
42128
- writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
42129
- return;
42130
- }
42131
- const installs = resolveSkillsInstallCommands(baseUrl, skillNames, agents);
42132
- if (installs.length === 0) {
42133
- writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
42134
- return;
42135
- }
42136
- writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
42137
- const installed = await runSkillsInstall(installs);
42138
- if (!installed) return;
42139
- runLegacySkillsCleanup(agents);
42140
- writeLocalSkillsVersion(baseUrl, update.remoteVersion);
42141
- clearUnavailableSkillsNotice(baseUrl);
42142
- writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
42143
- }
42144
-
42145
41999
  // src/cli/failure-reporting.ts
42146
42000
  import { hostname as hostname2, platform as platform2, release } from "os";
42147
42001
  var FAILURE_REPORT_DISABLE_ENV = "DEEPLINE_DISABLE_FAILURE_REPORTING";
@@ -42420,7 +42274,7 @@ function shouldDeferSkillsSyncForCommand() {
42420
42274
  if (command === "providers" && subcommand === "list") return true;
42421
42275
  return (command === "play" || command === "plays") && subcommand === "run" && args.includes("--json");
42422
42276
  }
42423
- function isLegacyNoopInvocation() {
42277
+ function isDeprecatedCommandInvocation() {
42424
42278
  const command = process.argv.slice(2)[0];
42425
42279
  return command === "session" || command === "backend";
42426
42280
  }
@@ -42444,8 +42298,8 @@ function topLevelCommandKnown(program, commandName) {
42444
42298
  );
42445
42299
  }
42446
42300
  async function runPlayRunnerHealthCheck() {
42447
- const dir = await mkdtemp2(join22(tmpdir6(), "deepline-health-play-"));
42448
- const file = join22(dir, "health-check.play.ts");
42301
+ const dir = await mkdtemp2(join21(tmpdir6(), "deepline-health-play-"));
42302
+ const file = join21(dir, "health-check.play.ts");
42449
42303
  try {
42450
42304
  await writeFile6(
42451
42305
  file,
@@ -42687,7 +42541,7 @@ Exit codes:
42687
42541
  `
42688
42542
  );
42689
42543
  program.hook("preAction", async (_thisCommand, actionCommand) => {
42690
- if (actionCommand.name() === "version" || actionCommand.name() === "update" || actionCommand.name() === "switch" || actionCommand.name() === "setup" || actionCommand.name() === "skills" || actionCommand.name() === "doctor" || isLegacyNoopInvocation()) {
42544
+ if (actionCommand.name() === "version" || actionCommand.name() === "update" || actionCommand.name() === "setup" || actionCommand.name() === "skills" || actionCommand.name() === "doctor" || isDeprecatedCommandInvocation()) {
42691
42545
  return;
42692
42546
  }
42693
42547
  if (printStartupPhase) {
@@ -42716,18 +42570,6 @@ Exit codes:
42716
42570
  if (relaunched) {
42717
42571
  return;
42718
42572
  }
42719
- if (compatibility.response?.cli_family?.action === "force_python") {
42720
- forcePythonCliFamily();
42721
- process.stderr.write(
42722
- "Deepline SDK CLI rollback is active; switched installer-managed `deepline` back to the Python CLI. Re-run your command.\n"
42723
- );
42724
- const error = new Error(
42725
- "SDK CLI rollback is active"
42726
- );
42727
- error.code = "deepline.sdk_cli_rollback";
42728
- error.exitCode = 7;
42729
- throw error;
42730
- }
42731
42573
  enforceSdkCompatibilityResponse(compatibility.response);
42732
42574
  if (printStartupPhase) {
42733
42575
  progress?.phase("checking sdk skills");
@@ -42855,14 +42697,6 @@ Examples:
42855
42697
  process.exitCode = 2;
42856
42698
  return;
42857
42699
  }
42858
- const hint = commandCompatibilityHint(
42859
- "sdk",
42860
- requestedTopLevelCommand,
42861
- baseUrl
42862
- );
42863
- if (hint && !process.argv.includes("--json")) {
42864
- console.error(hint);
42865
- }
42866
42700
  process.exitCode = 2;
42867
42701
  return;
42868
42702
  }
@@ -42890,19 +42724,6 @@ Examples:
42890
42724
  const wantsJson = process.argv.includes("--json");
42891
42725
  if (commanderError) {
42892
42726
  if (commanderError.code === "commander.unknownCommand") {
42893
- const commandName = unknownCommandNameFromMessage(
42894
- commanderError.message
42895
- );
42896
- if (commandName && !wantsJson) {
42897
- const hint = commandCompatibilityHint(
42898
- "sdk",
42899
- commandName,
42900
- autoDetectBaseUrl()
42901
- );
42902
- if (hint) {
42903
- console.error(hint);
42904
- }
42905
- }
42906
42727
  }
42907
42728
  process.exitCode = commanderError.code === "commander.unknownCommand" && !wantsJson ? 2 : commanderError.exitCode ?? 1;
42908
42729
  return;