deepline 0.3.22 → 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.22",
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
  }
@@ -4633,6 +4698,10 @@ var DeeplineClient = class {
4633
4698
  },
4634
4699
  targetPlans: () => this.getTargetBillingPlans(),
4635
4700
  targetStatus: () => this.getTargetBillingStatus(),
4701
+ autoRecharge: {
4702
+ get: () => this.getTargetAutoRecharge(),
4703
+ update: (options2) => this.updateTargetAutoRecharge(options2)
4704
+ },
4636
4705
  purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
4637
4706
  transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
4638
4707
  portalSession: () => this.createTargetBillingPortalSession()
@@ -6718,6 +6787,28 @@ var DeeplineClient = class {
6718
6787
  async getTargetBillingStatus() {
6719
6788
  return this.http.get("/api/v2/billing/status");
6720
6789
  }
6790
+ /** Read the canonical Metronome automatic recharge configuration. */
6791
+ async getTargetAutoRecharge() {
6792
+ return this.http.get(
6793
+ "/api/v2/billing/auto-recharge"
6794
+ );
6795
+ }
6796
+ /** Update automatic recharge and return the server-verified configuration. */
6797
+ async updateTargetAutoRecharge(options) {
6798
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
6799
+ options.idempotencyKey
6800
+ );
6801
+ const response = await this.http.put(
6802
+ "/api/v2/billing/auto-recharge",
6803
+ options.enabled ? {
6804
+ enabled: true,
6805
+ threshold_credits: options.thresholdCredits,
6806
+ refill_to_credits: options.refillToCredits
6807
+ } : { enabled: false },
6808
+ { "Idempotency-Key": idempotencyKey }
6809
+ );
6810
+ return response.data;
6811
+ }
6721
6812
  /**
6722
6813
  * Purchase target-billing credits through the durable commercial operation
6723
6814
  * flow. The caller supplies an idempotency key for safe retries.
@@ -6951,19 +7042,19 @@ var DeeplineClient = class {
6951
7042
  };
6952
7043
 
6953
7044
  // src/compat.ts
6954
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
6955
- import { homedir as homedir4 } from "os";
6956
- 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";
6957
7048
  var CHECK_TIMEOUT_MS = 2e3;
6958
7049
  var SDK_COMPATIBILITY_CACHE_TTL_MS = 5 * 60 * 1e3;
6959
7050
  function shouldSkipCompatibilityCheck() {
6960
7051
  const value = process.env.DEEPLINE_SKIP_SDK_COMPAT_CHECK?.trim().toLowerCase();
6961
7052
  return value === "1" || value === "true" || value === "yes";
6962
7053
  }
6963
- function sdkCompatibilityCachePath(baseUrl, homeDir2 = homedir4()) {
7054
+ function sdkCompatibilityCachePath(baseUrl, homeDir2 = homedir3()) {
6964
7055
  return join3(sdkCliStateDirPath(baseUrl, homeDir2), "compat-cache.json");
6965
7056
  }
6966
- function legacySdkCompatibilityCachePath(homeDir2 = homedir4()) {
7057
+ function legacySdkCompatibilityCachePath(homeDir2 = homedir3()) {
6967
7058
  return join3(homeDir2, ".cache", "deepline", "sdk-compat-cache.json");
6968
7059
  }
6969
7060
  function compatibilityCacheKey(baseUrl, command, skillsVersion) {
@@ -7014,8 +7105,8 @@ function writeCachedCompatibility(baseUrl, command, skillsVersion, response) {
7014
7105
  savedAt: Date.now(),
7015
7106
  response
7016
7107
  };
7017
- mkdirSync2(dirname2(path), { recursive: true });
7018
- writeFileSync2(path, `${JSON.stringify({ entries }, null, 2)}
7108
+ mkdirSync3(dirname3(path), { recursive: true });
7109
+ writeFileSync3(path, `${JSON.stringify({ entries }, null, 2)}
7019
7110
  `);
7020
7111
  } catch {
7021
7112
  }
@@ -7088,26 +7179,26 @@ function enforceSdkCompatibilityResponse(response) {
7088
7179
  // src/cli/commands/auth.ts
7089
7180
  import {
7090
7181
  existsSync as existsSync5,
7091
- mkdirSync as mkdirSync4,
7182
+ mkdirSync as mkdirSync5,
7092
7183
  readFileSync as readFileSync5,
7093
7184
  rmSync as rmSync2,
7094
- writeFileSync as writeFileSync4
7185
+ writeFileSync as writeFileSync5
7095
7186
  } from "fs";
7096
7187
  import { hostname } from "os";
7097
- import { dirname as dirname4, join as join5 } from "path";
7188
+ import { dirname as dirname5, join as join5 } from "path";
7098
7189
 
7099
7190
  // src/cli/utils.ts
7100
7191
  import { createHash } from "crypto";
7101
7192
  import {
7102
7193
  existsSync as existsSync4,
7103
- mkdirSync as mkdirSync3,
7194
+ mkdirSync as mkdirSync4,
7104
7195
  readFileSync as readFileSync4,
7105
7196
  rmSync,
7106
- writeFileSync as writeFileSync3
7197
+ writeFileSync as writeFileSync4
7107
7198
  } from "fs";
7108
7199
  import { mkdir, writeFile } from "fs/promises";
7109
- import { homedir as homedir5, tmpdir, userInfo } from "os";
7110
- 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";
7111
7202
  import * as childProcess from "child_process";
7112
7203
  import { parse } from "csv-parse/sync";
7113
7204
  import { stringify } from "csv-stringify/sync";
@@ -7153,9 +7244,9 @@ function claimBrowserOpen(now = Date.now(), stateDir, targetUrl) {
7153
7244
  const targetKey = browserOpenTargetKey(targetUrl);
7154
7245
  let locked = false;
7155
7246
  try {
7156
- mkdirSync3(dirname3(statePath), { recursive: true, mode: 448 });
7247
+ mkdirSync4(dirname4(statePath), { recursive: true, mode: 448 });
7157
7248
  try {
7158
- mkdirSync3(lockPath, { mode: 448 });
7249
+ mkdirSync4(lockPath, { mode: 448 });
7159
7250
  locked = true;
7160
7251
  } catch {
7161
7252
  return false;
@@ -7177,7 +7268,7 @@ function claimBrowserOpen(now = Date.now(), stateDir, targetUrl) {
7177
7268
  return false;
7178
7269
  }
7179
7270
  }
7180
- writeFileSync3(
7271
+ writeFileSync4(
7181
7272
  statePath,
7182
7273
  JSON.stringify({
7183
7274
  lastOpenedAt: now,
@@ -7238,7 +7329,7 @@ function readMacosUserHome(runner = defaultBrowserCommandRunner) {
7238
7329
  } catch {
7239
7330
  }
7240
7331
  }
7241
- return homedir5();
7332
+ return homedir4();
7242
7333
  }
7243
7334
  function readDefaultMacBrowserBundleId(runner = defaultBrowserCommandRunner) {
7244
7335
  try {
@@ -7426,9 +7517,7 @@ function openUrlMacos(targetUrl, allowFocus, runner = defaultBrowserCommandRunne
7426
7517
  }
7427
7518
  }
7428
7519
  function browserOpeningDisabled() {
7429
- const value = String(
7430
- process.env.DEEPLINE_NO_BROWSER ?? process.env.PLAYGROUND_HEADLESS ?? ""
7431
- ).trim().toLowerCase();
7520
+ const value = String(process.env.DEEPLINE_NO_BROWSER ?? "").trim().toLowerCase();
7432
7521
  return value === "1" || value === "true" || value === "yes" || value === "on";
7433
7522
  }
7434
7523
  function openInBrowser(url, options = {}) {
@@ -7460,7 +7549,7 @@ function sleep3(ms) {
7460
7549
  return new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
7461
7550
  }
7462
7551
  function collectLocalEnvInfo() {
7463
- const homeDir2 = process.env.HOME?.trim() || homedir5();
7552
+ const homeDir2 = process.env.HOME?.trim() || homedir4();
7464
7553
  const info = {
7465
7554
  os: `${process.platform} ${process.arch}`,
7466
7555
  node_version: process.version,
@@ -7838,11 +7927,11 @@ function legacyPendingClaimTokenPath(baseUrl) {
7838
7927
  }
7839
7928
  function savePendingClaim(baseUrl, claim) {
7840
7929
  const filePath = pendingClaimPath(baseUrl, claim.scope);
7841
- const dir = dirname4(filePath);
7930
+ const dir = dirname5(filePath);
7842
7931
  if (!existsSync5(dir)) {
7843
- mkdirSync4(dir, { recursive: true });
7932
+ mkdirSync5(dir, { recursive: true });
7844
7933
  }
7845
- writeFileSync4(filePath, `${JSON.stringify(claim, null, 2)}
7934
+ writeFileSync5(filePath, `${JSON.stringify(claim, null, 2)}
7846
7935
  `, {
7847
7936
  encoding: "utf-8",
7848
7937
  mode: 384
@@ -8554,7 +8643,7 @@ Examples:
8554
8643
  import { Command } from "commander";
8555
8644
  import { randomUUID } from "crypto";
8556
8645
  import { appendFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
8557
- import { dirname as dirname5, resolve as resolve3 } from "path";
8646
+ import { dirname as dirname6, resolve as resolve3 } from "path";
8558
8647
  import { stringify as stringify2 } from "csv-stringify/sync";
8559
8648
  var SUBSCRIPTION_STATUS_NEXT_COMMAND = "deepline billing subscription status --json";
8560
8649
  var SUBSCRIPTION_CANCEL_PATH = "/api/v2/billing/subscription/cancel";
@@ -9013,7 +9102,7 @@ async function handleLedgerExportAll(options) {
9013
9102
  const entries = Array.isArray(payload.entries) ? payload.entries : [];
9014
9103
  const rows = entries.map(ledgerApiEntryToRow);
9015
9104
  if (!initializedOutput) {
9016
- await mkdir2(dirname5(outputPath), { recursive: true });
9105
+ await mkdir2(dirname6(outputPath), { recursive: true });
9017
9106
  await writeFile2(outputPath, ledgerRowsToCsv([], true), "utf-8");
9018
9107
  initializedOutput = true;
9019
9108
  }
@@ -9462,6 +9551,96 @@ async function handleTargetStatus(options) {
9462
9551
  { json: options.json }
9463
9552
  );
9464
9553
  }
9554
+ async function handleAutoRechargeStatus(options) {
9555
+ const payload = await new DeeplineClient().billing.autoRecharge.get();
9556
+ const state = payload.available ? payload.enabled ? "on" : "off" : "unavailable";
9557
+ const lines = [
9558
+ `State: ${state}`,
9559
+ ...payload.threshold_credits !== null ? [`Threshold: ${payload.threshold_credits} credits`] : [],
9560
+ ...payload.refill_to_credits !== null ? [`Refill balance to: ${payload.refill_to_credits} credits`] : []
9561
+ ];
9562
+ printCommandEnvelope(
9563
+ {
9564
+ ok: true,
9565
+ ...payload,
9566
+ render: { sections: [{ title: "automatic recharge", lines }] }
9567
+ },
9568
+ { json: options.json }
9569
+ );
9570
+ }
9571
+ async function handleAutoRechargeSet(options) {
9572
+ const thresholdCredits = parseTopUpCredits(options.thresholdCredits);
9573
+ const refillToCredits = parseTopUpCredits(options.refillToCredits);
9574
+ if (thresholdCredits === null || refillToCredits === null || refillToCredits <= thresholdCredits) {
9575
+ reportBillingFailure(
9576
+ {
9577
+ exitCode: 2,
9578
+ code: "INVALID_AUTO_RECHARGE_CONFIGURATION",
9579
+ message: "--threshold-credits and --refill-to-credits must be positive whole credits, and refill-to must be greater."
9580
+ },
9581
+ options
9582
+ );
9583
+ return;
9584
+ }
9585
+ const idempotencyKey = targetBillingIdempotencyKey(options.idempotencyKey);
9586
+ if (options.dryRun) {
9587
+ printCommandEnvelope(
9588
+ {
9589
+ ok: true,
9590
+ dry_run: true,
9591
+ idempotency_key: idempotencyKey,
9592
+ planned_request: {
9593
+ method: "PUT",
9594
+ path: "/api/v2/billing/auto-recharge",
9595
+ body: {
9596
+ enabled: true,
9597
+ threshold_credits: thresholdCredits,
9598
+ refill_to_credits: refillToCredits
9599
+ }
9600
+ }
9601
+ },
9602
+ { json: options.json }
9603
+ );
9604
+ return;
9605
+ }
9606
+ const payload = await new DeeplineClient().billing.autoRecharge.update({
9607
+ enabled: true,
9608
+ thresholdCredits,
9609
+ refillToCredits,
9610
+ idempotencyKey
9611
+ });
9612
+ printCommandEnvelope(
9613
+ { ok: true, idempotency_key: idempotencyKey, ...payload },
9614
+ { json: options.json }
9615
+ );
9616
+ }
9617
+ async function handleAutoRechargeOff(options) {
9618
+ const idempotencyKey = targetBillingIdempotencyKey(options.idempotencyKey);
9619
+ if (options.dryRun) {
9620
+ printCommandEnvelope(
9621
+ {
9622
+ ok: true,
9623
+ dry_run: true,
9624
+ idempotency_key: idempotencyKey,
9625
+ planned_request: {
9626
+ method: "PUT",
9627
+ path: "/api/v2/billing/auto-recharge",
9628
+ body: { enabled: false }
9629
+ }
9630
+ },
9631
+ { json: options.json }
9632
+ );
9633
+ return;
9634
+ }
9635
+ const payload = await new DeeplineClient().billing.autoRecharge.update({
9636
+ enabled: false,
9637
+ idempotencyKey
9638
+ });
9639
+ printCommandEnvelope(
9640
+ { ok: true, idempotency_key: idempotencyKey, ...payload },
9641
+ { json: options.json }
9642
+ );
9643
+ }
9465
9644
  async function handleBuyCredits(creditsRaw, options) {
9466
9645
  const credits = parseTopUpCredits(creditsRaw);
9467
9646
  if (credits === null) {
@@ -9723,6 +9902,31 @@ Examples:
9723
9902
  ).option("--dry-run", "Print the planned top-up without charging").option("--compact", "Keep only high-signal fields in JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleTopUp);
9724
9903
  billing.command("buy").description("Buy credits through the target billing contract.").argument("<credits>", "Positive integer Deepline credit amount").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleBuyCredits);
9725
9904
  billing.command("status").description("Show normalized target billing state.").option("--json", "Emit JSON output").action(handleTargetStatus);
9905
+ billing.command("auto-recharge").description("Inspect and manage automatic Deepline credit recharge.").addHelpText(
9906
+ "after",
9907
+ `
9908
+ Examples:
9909
+ deepline billing auto-recharge status --json
9910
+ deepline billing auto-recharge set --threshold-credits 1000 --refill-to-credits 3500 --dry-run --json
9911
+ deepline billing auto-recharge off --dry-run --json
9912
+ `
9913
+ ).addCommand(
9914
+ new Command("status").description("Show the canonical automatic recharge configuration.").option("--json", "Emit JSON output").action(handleAutoRechargeStatus)
9915
+ ).addCommand(
9916
+ new Command("set").description(
9917
+ "Enable automatic recharge with a threshold and refill target."
9918
+ ).requiredOption(
9919
+ "--threshold-credits <credits>",
9920
+ "Recharge when the balance reaches this amount"
9921
+ ).requiredOption(
9922
+ "--refill-to-credits <credits>",
9923
+ "Recharge the balance to this amount"
9924
+ ).option("--idempotency-key <key>", "Stable retry key").option("--dry-run", "Print the planned update without applying it").option("--json", "Emit JSON output").action(handleAutoRechargeSet)
9925
+ ).addCommand(
9926
+ new Command("off").description(
9927
+ "Disable automatic recharge without clearing saved amounts."
9928
+ ).option("--idempotency-key <key>", "Stable retry key").option("--dry-run", "Print the planned update without applying it").option("--json", "Emit JSON output").action(handleAutoRechargeOff)
9929
+ );
9726
9930
  billing.command("change-plan").description("Start or change the target billing plan.").argument("<plan_sku>", "payg-v1, builder-v1, or team-v1").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
9727
9931
  billing.command("cancel-plan").description("Cancel a target subscription at period end, or undo it.").option("--undo", "Undo a pending period-end cancellation").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlanCancellation);
9728
9932
  billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
@@ -9850,17 +10054,17 @@ import { randomUUID as randomUUID2 } from "crypto";
9850
10054
  import {
9851
10055
  closeSync,
9852
10056
  existsSync as existsSync6,
9853
- mkdirSync as mkdirSync5,
10057
+ mkdirSync as mkdirSync6,
9854
10058
  openSync,
9855
10059
  readFileSync as readFileSync6,
9856
10060
  rmSync as rmSync3,
9857
- writeFileSync as writeFileSync6
10061
+ writeFileSync as writeFileSync7
9858
10062
  } from "fs";
9859
- import { homedir as homedir6 } from "os";
10063
+ import { homedir as homedir5 } from "os";
9860
10064
  import { join as join6, resolve as resolve5 } from "path";
9861
10065
 
9862
10066
  // src/cli/dataset-stats.ts
9863
- import { writeFileSync as writeFileSync5 } from "fs";
10067
+ import { writeFileSync as writeFileSync6 } from "fs";
9864
10068
  import { resolve as resolve4 } from "path";
9865
10069
 
9866
10070
  // ../shared_libs/plays/dataset-summary.ts
@@ -10515,7 +10719,7 @@ function writeCanonicalRowsCsv(rowsInfo, outPath) {
10515
10719
  const rows = dataExportRows(sanitized.rows);
10516
10720
  const columns = dataExportColumns(rows, sanitized.columns);
10517
10721
  const resolved = resolve4(outPath);
10518
- writeFileSync5(resolved, csvStringFromRows(rows, columns), "utf-8");
10722
+ writeFileSync6(resolved, csvStringFromRows(rows, columns), "utf-8");
10519
10723
  return resolved;
10520
10724
  }
10521
10725
 
@@ -10623,13 +10827,13 @@ async function handleCsvShow(options) {
10623
10827
  );
10624
10828
  }
10625
10829
  function csvRenderStatePath() {
10626
- return join6(homedir6(), ".local", "deepline", "runtime", "csv-render.json");
10830
+ return join6(homedir5(), ".local", "deepline", "runtime", "csv-render.json");
10627
10831
  }
10628
10832
  function csvRenderLogPath() {
10629
- return join6(homedir6(), ".local", "deepline", "runtime", "csv-render.log");
10833
+ return join6(homedir5(), ".local", "deepline", "runtime", "csv-render.log");
10630
10834
  }
10631
10835
  function ensureCsvRenderStateDir() {
10632
- mkdirSync5(join6(homedir6(), ".local", "deepline", "runtime"), {
10836
+ mkdirSync6(join6(homedir5(), ".local", "deepline", "runtime"), {
10633
10837
  recursive: true
10634
10838
  });
10635
10839
  }
@@ -10643,7 +10847,7 @@ function readCsvRenderState() {
10643
10847
  }
10644
10848
  function writeCsvRenderState(state) {
10645
10849
  ensureCsvRenderStateDir();
10646
- writeFileSync6(csvRenderStatePath(), `${JSON.stringify(state, null, 2)}
10850
+ writeFileSync7(csvRenderStatePath(), `${JSON.stringify(state, null, 2)}
10647
10851
  `);
10648
10852
  }
10649
10853
  function parseCsvRenderPort(raw) {
@@ -10795,7 +10999,7 @@ async function handleCsvRenderStart(options) {
10795
10999
  rmSync3(csvRenderStatePath(), { force: true });
10796
11000
  } else if (existingOwned) {
10797
11001
  process.stdout.write(
10798
- "Playground render is already running; reusing current process.\n"
11002
+ "CSV render is already running; reusing current process.\n"
10799
11003
  );
10800
11004
  process.stdout.write(`Render URL: ${existing.url}
10801
11005
  `);
@@ -10811,20 +11015,16 @@ async function handleCsvRenderStart(options) {
10811
11015
  const logPath = csvRenderLogPath();
10812
11016
  const logFd = openSync(logPath, "w");
10813
11017
  const token = randomUUID2();
10814
- const child = spawn(
10815
- process.execPath,
10816
- ["-e", CSV_RENDER_SERVER_SOURCE],
10817
- {
10818
- detached: true,
10819
- stdio: ["ignore", logFd, logFd],
10820
- env: {
10821
- ...process.env,
10822
- DEEPLINE_CSV_RENDER_PORT: String(port),
10823
- DEEPLINE_CSV_RENDER_CSV: csvPath,
10824
- DEEPLINE_CSV_RENDER_TOKEN: token
10825
- }
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
10826
11026
  }
10827
- );
11027
+ });
10828
11028
  closeSync(logFd);
10829
11029
  child.unref();
10830
11030
  const state = {
@@ -10856,12 +11056,12 @@ ${clip(log, 2e3)}`;
10856
11056
  );
10857
11057
  }
10858
11058
  writeCsvRenderState(state);
10859
- writeFileSync6(
11059
+ writeFileSync7(
10860
11060
  logPath,
10861
11061
  `CSV render started at ${state.startedAt} on ${url}
10862
11062
  `
10863
11063
  );
10864
- process.stdout.write("Playground render is running.\n");
11064
+ process.stdout.write("CSV render is running.\n");
10865
11065
  process.stdout.write(`Render PID: ${child.pid}
10866
11066
  `);
10867
11067
  process.stdout.write(`Render URL: ${url}
@@ -10932,8 +11132,8 @@ async function handleCsvRenderStop(options) {
10932
11132
  stopped_pids: stopped,
10933
11133
  failed_pids: failed
10934
11134
  };
10935
- const text = stopped.length > 0 ? `Stopped playground render process(es): ${stopped.join(" ")}
10936
- ` : "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";
10937
11137
  printCommandEnvelope(payload, { json: options.json, text });
10938
11138
  }
10939
11139
  async function handleCsvRender(action, options) {
@@ -10983,7 +11183,7 @@ Examples:
10983
11183
  }
10984
11184
 
10985
11185
  // src/cli/commands/db.ts
10986
- import { writeFileSync as writeFileSync7 } from "fs";
11186
+ import { writeFileSync as writeFileSync8 } from "fs";
10987
11187
  import { resolve as resolve6 } from "path";
10988
11188
  var CUSTOMER_DB_QUERY_FORMATS = /* @__PURE__ */ new Set(["table", "json", "csv", "markdown"]);
10989
11189
  var CUSTOMER_DB_QUERY_MAX_ROWS = 1e3;
@@ -11130,7 +11330,7 @@ function dbRepairPlainText(result) {
11130
11330
  }
11131
11331
  function writeCustomerDbCsv(result, outPath) {
11132
11332
  const resolved = resolve6(outPath);
11133
- writeFileSync7(
11333
+ writeFileSync8(
11134
11334
  resolved,
11135
11335
  dataExportCsvString(customerDbRows(result), customerDbColumnNames(result)),
11136
11336
  "utf-8"
@@ -11243,7 +11443,7 @@ async function handleDbQuery(args) {
11243
11443
  );
11244
11444
  if (outPath) {
11245
11445
  const exportedPath = resolve6(outPath);
11246
- writeFileSync7(exportedPath, content, "utf-8");
11446
+ writeFileSync8(exportedPath, content, "utf-8");
11247
11447
  printCommandEnvelope(
11248
11448
  dbQueryExportEnvelope({
11249
11449
  result,
@@ -11426,20 +11626,20 @@ import {
11426
11626
  stat as stat3,
11427
11627
  writeFile as writeFile4
11428
11628
  } from "fs/promises";
11429
- import { homedir as homedir7, tmpdir as tmpdir4 } from "os";
11430
- 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";
11431
11631
  import { Option } from "commander";
11432
11632
 
11433
11633
  // src/cli/commands/play.ts
11434
11634
  import { createHash as createHash4, randomUUID as randomUUID3 } from "crypto";
11435
11635
  import {
11436
11636
  existsSync as existsSync9,
11437
- mkdirSync as mkdirSync6,
11637
+ mkdirSync as mkdirSync7,
11438
11638
  readFileSync as readFileSync8,
11439
11639
  readdirSync as readdirSync2,
11440
11640
  realpathSync as realpathSync2,
11441
11641
  statSync as statSync3,
11442
- writeFileSync as writeFileSync9
11642
+ writeFileSync as writeFileSync10
11443
11643
  } from "fs";
11444
11644
  import {
11445
11645
  lstat,
@@ -11450,7 +11650,7 @@ import {
11450
11650
  } from "fs/promises";
11451
11651
  import {
11452
11652
  basename as basename3,
11453
- dirname as dirname9,
11653
+ dirname as dirname10,
11454
11654
  isAbsolute as isAbsolute5,
11455
11655
  join as join10,
11456
11656
  relative as relative4,
@@ -11464,7 +11664,7 @@ import {
11464
11664
  openSync as openSync2,
11465
11665
  readSync,
11466
11666
  statSync as statSync2,
11467
- writeFileSync as writeFileSync8
11667
+ writeFileSync as writeFileSync9
11468
11668
  } from "fs";
11469
11669
  import { isAbsolute as isAbsolute2, relative, resolve as resolve7 } from "path";
11470
11670
  import { parse as parseCsvSync } from "csv-parse/sync";
@@ -13026,7 +13226,7 @@ function renderPlayBootstrapError(error) {
13026
13226
  }
13027
13227
  function writeBootstrapSource(source, out) {
13028
13228
  if (out) {
13029
- writeFileSync8(resolve7(out), source, "utf-8");
13229
+ writeFileSync9(resolve7(out), source, "utf-8");
13030
13230
  process.stdout.write(`Wrote ${resolve7(out)}
13031
13231
  `);
13032
13232
  return 0;
@@ -13164,7 +13364,7 @@ Examples:
13164
13364
 
13165
13365
  // src/plays/bundle-play-file.ts
13166
13366
  import { tmpdir as tmpdir3 } from "os";
13167
- 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";
13168
13368
  import { fileURLToPath } from "url";
13169
13369
  import { existsSync as existsSync8 } from "fs";
13170
13370
  import { realpath as realpath2 } from "fs/promises";
@@ -13176,7 +13376,7 @@ import { mkdir as mkdir3, readFile, realpath, stat, writeFile as writeFile3 } fr
13176
13376
  import { tmpdir as tmpdir2 } from "os";
13177
13377
  import {
13178
13378
  basename,
13179
- dirname as dirname6,
13379
+ dirname as dirname7,
13180
13380
  extname,
13181
13381
  isAbsolute as isAbsolute3,
13182
13382
  join as join7,
@@ -18024,7 +18224,7 @@ import { createHash as createHash3 } from "crypto";
18024
18224
  import { readFile as readFile2, stat as stat2 } from "fs/promises";
18025
18225
  import {
18026
18226
  basename as basename2,
18027
- dirname as dirname7,
18227
+ dirname as dirname8,
18028
18228
  extname as extname2,
18029
18229
  isAbsolute as isAbsolute4,
18030
18230
  join as join8,
@@ -18033,7 +18233,7 @@ import {
18033
18233
  } from "path";
18034
18234
 
18035
18235
  // src/plays/bundle-play-file.ts
18036
- var MODULE_DIR = dirname8(fileURLToPath(import.meta.url));
18236
+ var MODULE_DIR = dirname9(fileURLToPath(import.meta.url));
18037
18237
  var SDK_PACKAGE_ROOT = resolve10(MODULE_DIR, "..", "..");
18038
18238
  var SOURCE_REPO_ROOT = resolve10(SDK_PACKAGE_ROOT, "..");
18039
18239
  var HAS_SOURCE_BUNDLING_SOURCES = existsSync8(
@@ -18886,7 +19086,7 @@ async function pathExistsIncludingSymlink(path) {
18886
19086
  }
18887
19087
  function runIdFileTempPath(destination) {
18888
19088
  return join10(
18889
- dirname9(destination),
19089
+ dirname10(destination),
18890
19090
  `.${basename3(destination)}.${process.pid}.${randomUUID3()}.tmp`
18891
19091
  );
18892
19092
  }
@@ -18963,7 +19163,7 @@ async function writePlayRunIdFile(destination, runId) {
18963
19163
  try {
18964
19164
  await link(tempPath, destination);
18965
19165
  if (process.platform !== "win32") {
18966
- const directory = await open(dirname9(destination), "r");
19166
+ const directory = await open(dirname10(destination), "r");
18967
19167
  try {
18968
19168
  await directory.sync();
18969
19169
  } finally {
@@ -19304,12 +19504,12 @@ function materializeRemotePlaySource(input2) {
19304
19504
  `Refusing to materialize unsafe Play source path ${JSON.stringify(logicalPath)}.`
19305
19505
  );
19306
19506
  }
19307
- mkdirSync6(dirname9(outputPath2), { recursive: true });
19507
+ mkdirSync7(dirname10(outputPath2), { recursive: true });
19308
19508
  if (!existsSync9(outputPath2)) {
19309
- writeFileSync9(outputPath2, sourceCode, "utf-8");
19509
+ writeFileSync10(outputPath2, sourceCode, "utf-8");
19310
19510
  created += 1;
19311
19511
  } else if (readFileSync8(outputPath2, "utf-8") !== sourceCode) {
19312
- writeFileSync9(outputPath2, sourceCode, "utf-8");
19512
+ writeFileSync10(outputPath2, sourceCode, "utf-8");
19313
19513
  updated += 1;
19314
19514
  }
19315
19515
  }
@@ -19326,10 +19526,10 @@ function materializeRemotePlaySource(input2) {
19326
19526
  if (existingSource === entrySource) {
19327
19527
  return { path: outputPath, status: "unchanged", created: false };
19328
19528
  }
19329
- writeFileSync9(outputPath, entrySource, "utf-8");
19529
+ writeFileSync10(outputPath, entrySource, "utf-8");
19330
19530
  return { path: outputPath, status: "updated", created: false };
19331
19531
  }
19332
- writeFileSync9(outputPath, entrySource, "utf-8");
19532
+ writeFileSync10(outputPath, entrySource, "utf-8");
19333
19533
  return { path: outputPath, status: "created", created: true };
19334
19534
  }
19335
19535
  function formatLoadedPlayMessage(materializedFile) {
@@ -19481,7 +19681,9 @@ function stringMetadata(metadata, key) {
19481
19681
  }
19482
19682
  function inputFieldFromCsvArg(csvArg) {
19483
19683
  if (typeof csvArg !== "string") return null;
19484
- 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
+ );
19485
19687
  return match?.[1] ?? null;
19486
19688
  }
19487
19689
  function fileInputBindingsFromPlaySchema(inputSchema) {
@@ -23254,6 +23456,21 @@ function printPlayCheckLimits(limits) {
23254
23456
  console.log(
23255
23457
  ` bundle: ${formatByteBudget(limits.bundle.usedBytes, limits.bundle.limitBytes)}`
23256
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`;
23257
23474
  }
23258
23475
  function isRecord10(value) {
23259
23476
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -23718,6 +23935,10 @@ function printPlayCheckOutcome(outcome, target, prefix) {
23718
23935
  console.error(
23719
23936
  `\u2717 ${prefix}${playName} failed ${playCheckFailureStage(outcome)}`
23720
23937
  );
23938
+ printPlayCheckFeatureFlags(
23939
+ result.featureFlags,
23940
+ (line) => console.error(line)
23941
+ );
23721
23942
  const { unstructuredErrors } = partitionMirroredErrors(
23722
23943
  result.errors,
23723
23944
  result.issues
@@ -23737,12 +23958,15 @@ function printPlayCheckOutcome(outcome, target, prefix) {
23737
23958
  console.log(
23738
23959
  summary ? `\u2713 ${prefix}${playName} valid \u2014 ${summary}` : `\u2713 ${prefix}${playName} passed ${result.limits ? "cloud" : "local"} play check`
23739
23960
  );
23961
+ printPlayCheckFeatureFlags(result.featureFlags, (line) => console.log(line));
23740
23962
  if (result.artifactHash) {
23741
23963
  console.log(` artifact: ${result.artifactHash.slice(0, 12)}`);
23742
23964
  }
23743
23965
  if (result.sourceHash) {
23744
23966
  console.log(` source: ${result.sourceHash.slice(0, 12)}`);
23745
23967
  }
23968
+ const runtimeLimit = formatPlayRuntimeLimit(result.runtimeLimit);
23969
+ if (runtimeLimit) console.log(` runtime limit: ${runtimeLimit}`);
23746
23970
  printPlayCheckLimits(result.limits);
23747
23971
  if (result.artifactHash && outcome.exportName === PLAY_DEFAULT_EXPORT) {
23748
23972
  console.log(
@@ -23758,6 +23982,11 @@ function printPlayCheckOutcome(outcome, target, prefix) {
23758
23982
  );
23759
23983
  printToolGetterHints(result.toolGetterHints);
23760
23984
  }
23985
+ function printPlayCheckFeatureFlags(flags, write) {
23986
+ for (const flag of flags ?? []) {
23987
+ write(` feature flag enabled: ${flag.label} \u2014 ${flag.reason}`);
23988
+ }
23989
+ }
23761
23990
  function printPlayCheckOutcomes(outcomes, target) {
23762
23991
  if (outcomes.length === 1) {
23763
23992
  printPlayCheckOutcome(outcomes[0], target, "");
@@ -24177,7 +24406,7 @@ async function handlePlayRun(args, hooks) {
24177
24406
  }
24178
24407
  const resolved = resolve11(options.target.path);
24179
24408
  console.error(`File not found: ${resolved}`);
24180
- const dir = dirname9(resolved);
24409
+ const dir = dirname10(resolved);
24181
24410
  if (existsSync9(dir)) {
24182
24411
  const base = basename3(resolved);
24183
24412
  try {
@@ -24464,7 +24693,7 @@ async function handleRunLogs(args) {
24464
24693
  if (outPath) {
24465
24694
  const result2 = await client2.runs.logs(runId, { all: true });
24466
24695
  const logs = result2.entries;
24467
- writeFileSync9(outPath, `${logs.join("\n")}${logs.length > 0 ? "\n" : ""}`);
24696
+ writeFileSync10(outPath, `${logs.join("\n")}${logs.length > 0 ? "\n" : ""}`);
24468
24697
  printCommandEnvelope(
24469
24698
  {
24470
24699
  runId: result2.runId,
@@ -24678,7 +24907,7 @@ async function handleRunExport(args) {
24678
24907
  }
24679
24908
  };
24680
24909
  if (metadataOutPath) {
24681
- writeFileSync9(
24910
+ writeFileSync10(
24682
24911
  metadataOutPath,
24683
24912
  `${JSON.stringify(payload, null, 2)}
24684
24913
  `,
@@ -28436,10 +28665,10 @@ function expandAtFilePath(rawPath) {
28436
28665
  (_match, bareName, bracedName) => process.env[bareName ?? bracedName ?? ""] ?? ""
28437
28666
  );
28438
28667
  if (expanded === "~") {
28439
- return homedir7();
28668
+ return homedir6();
28440
28669
  }
28441
28670
  if (expanded.startsWith("~/") || expanded.startsWith("~\\")) {
28442
- return join11(homedir7(), expanded.slice(2));
28671
+ return join11(homedir6(), expanded.slice(2));
28443
28672
  }
28444
28673
  return expanded;
28445
28674
  }
@@ -30821,7 +31050,7 @@ function sidecarEnrichRowsExportPath(outputPath) {
30821
31050
  const resolved = resolve12(outputPath);
30822
31051
  const ext = extname3(resolved) || ".csv";
30823
31052
  const stem = basename4(resolved, ext);
30824
- return join11(dirname10(resolved), `${stem}.deepline-enrich-rows${ext}`);
31053
+ return join11(dirname11(resolved), `${stem}.deepline-enrich-rows${ext}`);
30825
31054
  }
30826
31055
  function collectDatasetFollowUpCommands(value, state) {
30827
31056
  if (state.depth > 12 || !value || typeof value !== "object" || state.commands.length >= 8) {
@@ -30902,7 +31131,7 @@ async function persistEnrichFailureReport(input2) {
30902
31131
  if (input2.jobs.length === 0 && input2.issues.length === 0) {
30903
31132
  return null;
30904
31133
  }
30905
- const stateDir = join11(homedir7(), ".local", "deepline", "runtime", "state");
31134
+ const stateDir = join11(homedir6(), ".local", "deepline", "runtime", "state");
30906
31135
  const reportPrefix = input2.jobs.length > 0 ? "run-block-failures" : "enrich-issues";
30907
31136
  await mkdir4(stateDir, { recursive: true });
30908
31137
  const reportPath = join11(
@@ -31865,7 +32094,7 @@ function registerEnrichCommand(program) {
31865
32094
  }
31866
32095
  inPlaceTempDir = await mkdtemp(
31867
32096
  join11(
31868
- dirname10(inPlaceCommitOutputPath ?? resolve12(inputCsv)),
32097
+ dirname11(inPlaceCommitOutputPath ?? resolve12(inputCsv)),
31869
32098
  ".deepline-enrich-in-place-"
31870
32099
  )
31871
32100
  );
@@ -32146,14 +32375,14 @@ Examples:
32146
32375
  // src/cli/commands/sessions.ts
32147
32376
  import {
32148
32377
  existsSync as existsSync10,
32149
- mkdirSync as mkdirSync7,
32378
+ mkdirSync as mkdirSync8,
32150
32379
  readdirSync as readdirSync3,
32151
32380
  readFileSync as readFileSync9,
32152
32381
  statSync as statSync4,
32153
- writeFileSync as writeFileSync10
32382
+ writeFileSync as writeFileSync11
32154
32383
  } from "fs";
32155
- import { homedir as homedir8, platform } from "os";
32156
- 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";
32157
32386
  import { gzipSync } from "zlib";
32158
32387
  import { randomUUID as randomUUID4 } from "crypto";
32159
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;
@@ -32167,7 +32396,7 @@ var MAX_EVENT_OBJECT_KEYS = 80;
32167
32396
  var TRUNCATION_MARKER = "...[truncated]";
32168
32397
  var NOISE_EVENT_TYPES = /* @__PURE__ */ new Set(["progress", "file-history-snapshot"]);
32169
32398
  function homeDir() {
32170
- return process.env.HOME?.trim() || homedir8();
32399
+ return process.env.HOME?.trim() || homedir7();
32171
32400
  }
32172
32401
  function detectShellContext() {
32173
32402
  const shellPath = process.env.SHELL?.trim() || process.env.ComSpec?.trim() || process.env.COMSPEC?.trim() || "";
@@ -32702,9 +32931,9 @@ function loadViewerAssets() {
32702
32931
  const cliEntry = process.argv[1]?.trim() ? resolve13(process.argv[1]) : null;
32703
32932
  const candidateRoots2 = [
32704
32933
  ...cliEntry ? [
32705
- join12(dirname11(dirname11(cliEntry)), "viewer"),
32934
+ join12(dirname12(dirname12(cliEntry)), "viewer"),
32706
32935
  join12(
32707
- dirname11(dirname11(dirname11(cliEntry))),
32936
+ dirname12(dirname12(dirname12(cliEntry))),
32708
32937
  "src",
32709
32938
  "lib",
32710
32939
  "cli",
@@ -32747,13 +32976,13 @@ async function handleSessionsRender(options) {
32747
32976
  let outputPath = options.output ? resolve13(options.output) : "";
32748
32977
  if (!outputPath) {
32749
32978
  const outputDir = join12(process.cwd(), "deepline", "data");
32750
- mkdirSync7(outputDir, { recursive: true });
32979
+ mkdirSync8(outputDir, { recursive: true });
32751
32980
  outputPath = join12(
32752
32981
  outputDir,
32753
32982
  targets.length > 1 ? "session-viewer.html" : `session-${targets[0]?.sessionId}.html`
32754
32983
  );
32755
32984
  } else {
32756
- mkdirSync7(dirname11(outputPath), { recursive: true });
32985
+ mkdirSync8(dirname12(outputPath), { recursive: true });
32757
32986
  }
32758
32987
  const sessions = targets.map((target) => ({
32759
32988
  label: target.label,
@@ -32783,7 +33012,7 @@ ${refreshMeta}
32783
33012
  <script>${js}</script>
32784
33013
  </body>
32785
33014
  </html>`;
32786
- writeFileSync10(outputPath, html, "utf8");
33015
+ writeFileSync11(outputPath, html, "utf8");
32787
33016
  printCommandEnvelope(
32788
33017
  {
32789
33018
  ok: true,
@@ -32890,30 +33119,31 @@ var BACKEND_SUBCOMMANDS = [
32890
33119
  "refresh-runtime",
32891
33120
  "sync-runtime"
32892
33121
  ];
32893
- function legacyNoopEnvelope(input2) {
33122
+ function deprecatedCommandEnvelope(input2) {
32894
33123
  const command = ["deepline", input2.family, input2.subcommand].filter(Boolean).join(" ");
32895
- const subject = input2.family === "session" ? "Legacy Session UI/playground command" : "Legacy local playground backend command";
32896
- 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`.";
32897
33126
  return {
32898
- ok: true,
32899
- noop: true,
33127
+ ok: false,
32900
33128
  command,
32901
- compatibility: {
32902
- family: "legacy_python_cli",
32903
- sdk_behavior: "noop"
32904
- },
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",
32905
33132
  render: {
32906
33133
  sections: [
32907
33134
  {
32908
- title: subject,
33135
+ title: `${commandLabel} deprecated`,
32909
33136
  lines: [note]
32910
33137
  }
32911
33138
  ]
32912
33139
  }
32913
33140
  };
32914
33141
  }
32915
- function printLegacyNoop(input2) {
32916
- 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;
32917
33147
  }
32918
33148
  function legacySubcommandFromArgv(family) {
32919
33149
  const args = process.argv.slice(2);
@@ -32921,18 +33151,18 @@ function legacySubcommandFromArgv(family) {
32921
33151
  const nextToken = familyIndex >= 0 ? args[familyIndex + 1] : void 0;
32922
33152
  return nextToken && !nextToken.startsWith("-") ? nextToken : void 0;
32923
33153
  }
32924
- function addLegacyNoopSubcommand(parent, family, subcommand, description) {
33154
+ function addDeprecatedSubcommand(parent, family, subcommand, description) {
32925
33155
  parent.command(subcommand).description(description).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").action((_args, options) => {
32926
- printLegacyNoop({ family, subcommand, options });
33156
+ printDeprecatedCommand({ family, subcommand, options });
32927
33157
  });
32928
33158
  }
32929
- function registerLegacyNoopCommands(program) {
32930
- 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(
32931
33161
  "after",
32932
33162
  `
32933
33163
  Notes:
32934
- The SDK CLI accepts singular session commands from older agent skills so they
32935
- 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.
32936
33166
  Use "deepline sessions send" or "deepline sessions render" for real SDK
32937
33167
  transcript workflows. "deepline session send" and "deepline session render"
32938
33168
  are accepted aliases for those real SDK workflows.
@@ -32944,7 +33174,7 @@ Examples:
32944
33174
  `
32945
33175
  ).action((args, options) => {
32946
33176
  void args;
32947
- printLegacyNoop({
33177
+ printDeprecatedCommand({
32948
33178
  family: "session",
32949
33179
  subcommand: legacySubcommandFromArgv("session"),
32950
33180
  options
@@ -32952,21 +33182,19 @@ Examples:
32952
33182
  });
32953
33183
  registerSessionSendRenderCommands(session, "session");
32954
33184
  for (const subcommand of SESSION_SUBCOMMANDS) {
32955
- addLegacyNoopSubcommand(
33185
+ addDeprecatedSubcommand(
32956
33186
  session,
32957
33187
  "session",
32958
33188
  subcommand,
32959
- `Accept legacy "deepline session ${subcommand}" as an SDK no-op.`
33189
+ `Deprecated legacy "deepline session ${subcommand}" command.`
32960
33190
  );
32961
33191
  }
32962
- const backend = program.command("backend").description(
32963
- "Compatibility no-ops for legacy Python local backend commands."
32964
- ).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(
32965
33193
  "after",
32966
33194
  `
32967
33195
  Notes:
32968
- The SDK CLI uses the configured Deepline host and V2 play runtime. It does not
32969
- 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.
32970
33198
 
32971
33199
  Examples:
32972
33200
  deepline backend start
@@ -32975,18 +33203,18 @@ Examples:
32975
33203
  `
32976
33204
  ).action((args, options) => {
32977
33205
  void args;
32978
- printLegacyNoop({
33206
+ printDeprecatedCommand({
32979
33207
  family: "backend",
32980
33208
  subcommand: legacySubcommandFromArgv("backend"),
32981
33209
  options
32982
33210
  });
32983
33211
  });
32984
33212
  for (const subcommand of BACKEND_SUBCOMMANDS) {
32985
- addLegacyNoopSubcommand(
33213
+ addDeprecatedSubcommand(
32986
33214
  backend,
32987
33215
  "backend",
32988
33216
  subcommand,
32989
- `Accept legacy "deepline backend ${subcommand}" as an SDK no-op.`
33217
+ `Deprecated legacy "deepline backend ${subcommand}" command.`
32990
33218
  );
32991
33219
  }
32992
33220
  }
@@ -34054,6 +34282,11 @@ Notes:
34054
34282
  Deploy is a full desired definition for its key: omitting a previously stored
34055
34283
  field removes it and can replace the upstream resource. Use \`monitors update\`
34056
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.
34057
34290
  For a bounded urgent Deepline Native preview, set
34058
34291
  controls.execution_type="priority". Deepline injects the provider custom
34059
34292
  field and enforces a ten-slot per-org cap; do not use it for regular or bulk
@@ -35025,24 +35258,24 @@ Examples:
35025
35258
  }
35026
35259
 
35027
35260
  // src/cli/commands/setup.ts
35028
- import { spawnSync } from "child_process";
35261
+ import { spawnSync as spawnSync2 } from "child_process";
35029
35262
  import {
35030
- existsSync as existsSync12,
35263
+ existsSync as existsSync13,
35031
35264
  lstatSync,
35032
- mkdirSync as mkdirSync9,
35033
- readFileSync as readFileSync12,
35265
+ mkdirSync as mkdirSync11,
35266
+ readFileSync as readFileSync13,
35034
35267
  realpathSync as realpathSync3,
35035
35268
  rmSync as rmSync4,
35036
- writeFileSync as writeFileSync12
35269
+ writeFileSync as writeFileSync14
35037
35270
  } from "fs";
35038
- import { homedir as homedir10 } from "os";
35039
- 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";
35040
35273
 
35041
35274
  // src/cli/commands/skills.ts
35042
- import { spawn as spawn2 } from "child_process";
35043
- import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync11 } from "fs";
35044
- import { homedir as homedir9 } from "os";
35045
- 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";
35046
35279
 
35047
35280
  // ../shared_libs/cli/install-commands.json
35048
35281
  var install_commands_default = {
@@ -35071,7 +35304,6 @@ var install_commands_default = {
35071
35304
  ]
35072
35305
  },
35073
35306
  cli: {
35074
- legacy_python_shell_template: "curl -s {base_url}/api/v2/cli/install | bash",
35075
35307
  sdk_npm_global: "npm install -g deepline@latest"
35076
35308
  }
35077
35309
  };
@@ -35110,9 +35342,6 @@ function renderTemplate(template, values) {
35110
35342
  return values[key] ?? match;
35111
35343
  });
35112
35344
  }
35113
- function shellJoin(args) {
35114
- return args.join(" ");
35115
- }
35116
35345
  function skillsIndexUrl(baseUrl) {
35117
35346
  return `${normalizeBaseUrl2(baseUrl)}${INSTALL_COMMANDS.skills.index_path}`;
35118
35347
  }
@@ -35147,19 +35376,17 @@ function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
35147
35376
  );
35148
35377
  return rendered;
35149
35378
  }
35150
- function skillsInstallCommand(baseUrl, skillName) {
35151
- return `${INSTALL_COMMANDS.skills.npx_binary} ${shellJoin(
35152
- buildSkillsAddArgs(baseUrl, skillName)
35153
- )}`;
35154
- }
35155
- function legacyPythonInstallCommand(baseUrl) {
35156
- return renderTemplate(INSTALL_COMMANDS.cli.legacy_python_shell_template, {
35157
- base_url: normalizeBaseUrl2(baseUrl)
35158
- });
35159
- }
35160
- function sdkNpmGlobalInstallCommand() {
35161
- return INSTALL_COMMANDS.cli.sdk_npm_global;
35162
- }
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";
35163
35390
 
35164
35391
  // src/cli/windows-arg-escape.ts
35165
35392
  var CMD_META_CHARS = /([()\][%!^"`<>&|;, *?])/g;
@@ -35184,6 +35411,351 @@ function resolveShellSpawn(command, args, platform3 = process.platform) {
35184
35411
  };
35185
35412
  }
35186
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
+
35187
35759
  // src/cli/commands/skills.ts
35188
35760
  var RUNTIME_TO_SKILLS_AGENT = {
35189
35761
  antigravity: "antigravity",
@@ -35245,17 +35817,17 @@ function detectSkillsAgents(input2) {
35245
35817
  if (knownAgent) return [knownAgent];
35246
35818
  const roots = [
35247
35819
  ...input2.scope === "local" && input2.root ? [input2.root] : [],
35248
- input2.homeDir ?? homedir9()
35820
+ input2.homeDir ?? homedir8()
35249
35821
  ];
35250
35822
  const detected = AGENT_MARKERS.filter(
35251
35823
  (marker) => roots.some(
35252
- (root) => marker.paths.some((path) => existsSync11(join13(root, path)))
35824
+ (root) => marker.paths.some((path) => existsSync12(join14(root, path)))
35253
35825
  )
35254
35826
  ).map((marker) => marker.agent);
35255
35827
  return detected.length > 0 ? detected : ["*"];
35256
35828
  }
35257
35829
  function skillsStatePathForScope(baseUrl, scope, root) {
35258
- 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");
35259
35831
  }
35260
35832
  function buildSkillsPlan(input2) {
35261
35833
  const scopeArgs = input2.scope === "global" ? ["--global"] : [];
@@ -35322,7 +35894,7 @@ function isSkillsPlanCurrent(plan, state) {
35322
35894
  }
35323
35895
  function readSkillsInstallState(path) {
35324
35896
  try {
35325
- const parsed = JSON.parse(readFileSync11(path, "utf8"));
35897
+ const parsed = JSON.parse(readFileSync12(path, "utf8"));
35326
35898
  return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
35327
35899
  } catch {
35328
35900
  return null;
@@ -35331,7 +35903,7 @@ function readSkillsInstallState(path) {
35331
35903
  function runProcess(command, args, cwd) {
35332
35904
  return new Promise((resolve19, reject) => {
35333
35905
  const plan = resolveShellSpawn(command, args);
35334
- const child = spawn2(plan.command, plan.args, {
35906
+ const child = spawn3(plan.command, plan.args, {
35335
35907
  cwd,
35336
35908
  env: process.env,
35337
35909
  stdio: ["ignore", "ignore", "pipe"],
@@ -35385,7 +35957,7 @@ async function runSkillsCommand(options, dependencies = {}) {
35385
35957
  );
35386
35958
  return 0;
35387
35959
  }
35388
- if (isSkillsPlanCurrent(plan, readSkillsInstallState(plan.statePath))) {
35960
+ if (isSkillsPlanCurrent(plan, readSkillsInstallState(plan.statePath)) && !hasFailedAutomaticSkillsSync(baseUrl, agents)) {
35389
35961
  printCommandEnvelope(
35390
35962
  {
35391
35963
  ok: true,
@@ -35466,8 +36038,8 @@ async function runSkillsCommand(options, dependencies = {}) {
35466
36038
  );
35467
36039
  return 5;
35468
36040
  }
35469
- mkdirSync8(dirname12(plan.statePath), { recursive: true });
35470
- writeFileSync11(
36041
+ mkdirSync10(dirname14(plan.statePath), { recursive: true });
36042
+ writeFileSync13(
35471
36043
  plan.statePath,
35472
36044
  `${JSON.stringify(
35473
36045
  {
@@ -35485,6 +36057,9 @@ async function runSkillsCommand(options, dependencies = {}) {
35485
36057
  `,
35486
36058
  "utf8"
35487
36059
  );
36060
+ if (scope === "global") {
36061
+ clearFailedAutomaticSkillsSync(baseUrl, agents);
36062
+ }
35488
36063
  printCommandEnvelope(
35489
36064
  {
35490
36065
  ok: true,
@@ -35601,7 +36176,7 @@ function phasesFromLegacyStatus(status) {
35601
36176
  function readSetupState(input2) {
35602
36177
  try {
35603
36178
  const parsed = JSON.parse(
35604
- readFileSync12(
36179
+ readFileSync13(
35605
36180
  setupStatePath(input2.baseUrl, input2.scope, input2.root),
35606
36181
  "utf8"
35607
36182
  )
@@ -35677,7 +36252,7 @@ function buildPendingAuthorizationOutput(input2) {
35677
36252
  };
35678
36253
  }
35679
36254
  function setupStatePath(baseUrl, scope, root) {
35680
- 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");
35681
36256
  }
35682
36257
  async function captureStdout2(run) {
35683
36258
  let stdout = "";
@@ -35706,14 +36281,14 @@ function asRecord3(value) {
35706
36281
  }
35707
36282
  function safeRead(path) {
35708
36283
  try {
35709
- return readFileSync12(path, "utf8");
36284
+ return readFileSync13(path, "utf8");
35710
36285
  } catch {
35711
36286
  return "";
35712
36287
  }
35713
36288
  }
35714
36289
  function isNpmManagedDeeplinePath(path) {
35715
36290
  try {
35716
- return realpathSync3(path).includes(`${join14("node_modules", "deepline")}`);
36291
+ return realpathSync3(path).includes(`${join15("node_modules", "deepline")}`);
35717
36292
  } catch {
35718
36293
  return false;
35719
36294
  }
@@ -35723,11 +36298,11 @@ function isInstallerManagedLegacyLauncher(path) {
35723
36298
  return content.includes("DEEPLINE_REAL_BINARY") && content.includes("DEEPLINE_ACTIVE_FILE");
35724
36299
  }
35725
36300
  function removeKnownLegacyPaths(baseUrl) {
35726
- const home = homedir10();
35727
- const hostDir = join14(home, ".local", "deepline", baseUrlSlug(baseUrl));
35728
- 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");
35729
36304
  const installerCommandPath = safeRead(
35730
- join14(hostDir, "sdk", ".command-path")
36305
+ join15(hostDir, "sdk", ".command-path")
35731
36306
  ).trim();
35732
36307
  const relativeInstallerCommandPath = installerCommandPath ? relative5(resolve14(hostDir), resolve14(installerCommandPath)) : "";
35733
36308
  const isOwnedInstallerCommand = Boolean(installerCommandPath) && relativeInstallerCommandPath !== "" && !relativeInstallerCommandPath.startsWith(
@@ -35735,21 +36310,21 @@ function removeKnownLegacyPaths(baseUrl) {
35735
36310
  ) && relativeInstallerCommandPath !== ".." && basename6(installerCommandPath) === "deepline";
35736
36311
  const candidates = [
35737
36312
  ...isInstallerManagedLegacyLauncher(legacyLauncherPath) ? [legacyLauncherPath] : [],
35738
- join14(home, ".local", "bin", "deepline-real"),
35739
- join14(hostDir, "bin", "deepline"),
35740
- join14(hostDir, "bin", "deepline-real"),
35741
- join14(hostDir, "cli", ".install-method"),
35742
- join14(hostDir, "cli", ".version"),
35743
- join14(hostDir, "sdk", ".install-method"),
35744
- 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"),
35745
36320
  ...isOwnedInstallerCommand ? [
35746
36321
  installerCommandPath,
35747
- join14(dirname13(installerCommandPath), "deepline-sdk")
36322
+ join15(dirname15(installerCommandPath), "deepline-sdk")
35748
36323
  ] : []
35749
36324
  ];
35750
36325
  const removed = [];
35751
36326
  for (const path of candidates) {
35752
- if (!existsSync12(path)) continue;
36327
+ if (!existsSync13(path)) continue;
35753
36328
  if (path === installerCommandPath && isNpmManagedDeeplinePath(path)) {
35754
36329
  continue;
35755
36330
  }
@@ -35759,7 +36334,7 @@ function removeKnownLegacyPaths(baseUrl) {
35759
36334
  return removed;
35760
36335
  }
35761
36336
  function resolvePathCommands(command) {
35762
- const lookup = spawnSync(
36337
+ const lookup = spawnSync2(
35763
36338
  process.platform === "win32" ? "where" : "which",
35764
36339
  process.platform === "win32" ? [command] : ["-a", command],
35765
36340
  { encoding: "utf8", shell: process.platform === "win32" }
@@ -35786,8 +36361,8 @@ function isHomebrewFormulaCommand(path) {
35786
36361
  }
35787
36362
  function resolvePersistentGlobalCommand(dependencies = {}) {
35788
36363
  const platform3 = dependencies.platform ?? process.platform;
35789
- const run = dependencies.spawn ?? spawnSync;
35790
- const pathExists = dependencies.exists ?? existsSync12;
36364
+ const run = dependencies.spawn ?? spawnSync2;
36365
+ const pathExists = dependencies.exists ?? existsSync13;
35791
36366
  const pathClis = dependencies.pathClis ?? resolvePathCommands("deepline");
35792
36367
  const homebrewCommand = pathClis.find(isHomebrewFormulaCommand);
35793
36368
  if (homebrewCommand) return homebrewCommand;
@@ -35799,7 +36374,7 @@ function resolvePersistentGlobalCommand(dependencies = {}) {
35799
36374
  if (prefix.status !== 0) return null;
35800
36375
  const root = String(prefix.stdout ?? "").trim();
35801
36376
  if (!root) return null;
35802
- 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")];
35803
36378
  return candidates.find((candidate) => pathExists(candidate)) ?? null;
35804
36379
  }
35805
36380
  function inspectGlobalCliAvailability(input2) {
@@ -35825,7 +36400,7 @@ function isKnownDeeplineCommand(path) {
35825
36400
  } catch {
35826
36401
  }
35827
36402
  if (entrypoint && resolvedPath === entrypoint) return true;
35828
- if (resolvedPath.includes(`${join14("node_modules", "deepline")}`)) return true;
36403
+ if (resolvedPath.includes(`${join15("node_modules", "deepline")}`)) return true;
35829
36404
  const content = safeRead(path);
35830
36405
  return content.includes("node_modules/deepline") || content.includes("node_modules\\deepline") || content.includes("DEEPLINE_CONFIG_SCOPE") || content.includes("deepline-real");
35831
36406
  }
@@ -35835,7 +36410,7 @@ function inspectPathConflict() {
35835
36410
  try {
35836
36411
  if (lstatSync(commandPath).isSymbolicLink()) {
35837
36412
  const target = realpathSync3(commandPath);
35838
- if (target.includes(`${join14("node_modules", "deepline")}`)) return null;
36413
+ if (target.includes(`${join15("node_modules", "deepline")}`)) return null;
35839
36414
  }
35840
36415
  } catch {
35841
36416
  }
@@ -35843,8 +36418,8 @@ function inspectPathConflict() {
35843
36418
  }
35844
36419
  function writeSetupState(input2) {
35845
36420
  const path = setupStatePath(input2.baseUrl, input2.scope, input2.root);
35846
- mkdirSync9(dirname13(path), { recursive: true });
35847
- writeFileSync12(
36421
+ mkdirSync11(dirname15(path), { recursive: true });
36422
+ writeFileSync14(
35848
36423
  path,
35849
36424
  `${JSON.stringify(
35850
36425
  {
@@ -35884,7 +36459,7 @@ function failSetupPhase(phases, phase, code) {
35884
36459
  phases[phase] = { status: "failed", code };
35885
36460
  }
35886
36461
  function rollbackCommand(scope, root) {
35887
- 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"))}` : "";
35888
36463
  return `npm install -g${prefix} --no-audit --no-fund --include=optional --allow-scripts=esbuild deepline@${SDK_VERSION}`;
35889
36464
  }
35890
36465
  function setupResumeCommand(baseUrl, scope) {
@@ -35976,7 +36551,7 @@ function buildDoctorAssessment(input2) {
35976
36551
  const pathGlobalCli = globalCli?.path ?? null;
35977
36552
  const cliPath = input2.scope === "global" ? pathGlobalCli : runningCliPath;
35978
36553
  const cliScopeOk = input2.scope === "global" ? Boolean(pathGlobalCli) : Boolean(
35979
- input2.root && runningCliPath?.includes(join14(input2.root, ".deepline", "runtime"))
36554
+ input2.root && runningCliPath?.includes(join15(input2.root, ".deepline", "runtime"))
35980
36555
  );
35981
36556
  const checks = {
35982
36557
  cli: {
@@ -37131,165 +37706,6 @@ chooses the connected Slack channel or member and the events it receives.
37131
37706
  });
37132
37707
  }
37133
37708
 
37134
- // src/cli/commands/switch.ts
37135
- import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
37136
- import { homedir as homedir11 } from "os";
37137
- import { dirname as dirname14, join as join15 } from "path";
37138
- function hostSlugFromBaseUrl(baseUrl) {
37139
- try {
37140
- const url = new URL(baseUrl);
37141
- const port = url.port ? Number.parseInt(url.port, 10) : null;
37142
- let slug = (url.hostname || "unknown").replace(/[^a-zA-Z0-9]/g, "-");
37143
- if (port && port !== 80 && port !== 443) {
37144
- slug = `${slug}-${port}`;
37145
- }
37146
- return slug.toLowerCase().replace(/^-+|-+$/g, "") || "unknown";
37147
- } catch {
37148
- return "unknown";
37149
- }
37150
- }
37151
- function resolveConfigScope() {
37152
- const explicit = (process.env.DEEPLINE_CONFIG_SCOPE || "").trim();
37153
- if (explicit) return explicit;
37154
- return hostSlugFromBaseUrl(autoDetectBaseUrl());
37155
- }
37156
- function activeFamilyPath() {
37157
- const home = process.env.HOME || process.env.USERPROFILE || homedir11();
37158
- return join15(
37159
- home,
37160
- ".local",
37161
- "deepline",
37162
- resolveConfigScope(),
37163
- "cli",
37164
- ".active-family"
37165
- );
37166
- }
37167
- function readActiveFamily() {
37168
- const path = activeFamilyPath();
37169
- try {
37170
- return readFileSync13(path, "utf-8").trim() || "sdk";
37171
- } catch {
37172
- return "sdk";
37173
- }
37174
- }
37175
- function writeActiveFamily(family) {
37176
- const path = activeFamilyPath();
37177
- mkdirSync10(dirname14(path), { recursive: true });
37178
- writeFileSync13(path, `${family}
37179
- `, "utf-8");
37180
- return path;
37181
- }
37182
- function forcePythonCliFamily() {
37183
- return writeActiveFamily("python");
37184
- }
37185
- function handleSwitch(action, options) {
37186
- const normalized = (action || "status").trim().toLowerCase();
37187
- if (normalized === "status") {
37188
- const path = activeFamilyPath();
37189
- const activeFamily = readActiveFamily();
37190
- printCommandEnvelope(
37191
- {
37192
- ok: true,
37193
- active_family: activeFamily,
37194
- active_family_path: path,
37195
- active_family_file_exists: existsSync13(path),
37196
- render: {
37197
- sections: [
37198
- {
37199
- title: "cli switch",
37200
- lines: [
37201
- `Active CLI family: ${activeFamily}`,
37202
- `Active family file: ${path}`
37203
- ]
37204
- }
37205
- ]
37206
- }
37207
- },
37208
- { json: options.json }
37209
- );
37210
- return 0;
37211
- }
37212
- if (normalized === "python" || normalized === "rollback") {
37213
- const path = writeActiveFamily("python");
37214
- printCommandEnvelope(
37215
- {
37216
- ok: true,
37217
- active_family: "python",
37218
- active_family_path: path,
37219
- render: {
37220
- sections: [
37221
- {
37222
- title: "cli switch",
37223
- lines: [
37224
- "Switched installer-managed `deepline` to the Python CLI."
37225
- ]
37226
- }
37227
- ]
37228
- }
37229
- },
37230
- { json: options.json }
37231
- );
37232
- return 0;
37233
- }
37234
- if (normalized === "sdk") {
37235
- const path = writeActiveFamily("sdk");
37236
- printCommandEnvelope(
37237
- {
37238
- ok: true,
37239
- active_family: "sdk",
37240
- active_family_path: path,
37241
- render: {
37242
- sections: [
37243
- {
37244
- title: "cli switch",
37245
- lines: ["Switched installer-managed `deepline` to the SDK CLI."]
37246
- }
37247
- ]
37248
- }
37249
- },
37250
- { json: options.json }
37251
- );
37252
- return 0;
37253
- }
37254
- const message = `Unknown switch target: ${action}. Use one of: status, sdk, python, rollback.`;
37255
- const envelope = {
37256
- ok: false,
37257
- error: message,
37258
- code: "usage_error",
37259
- render: {
37260
- sections: [{ title: "cli switch", lines: [message] }]
37261
- }
37262
- };
37263
- const wantsJson = options.json === true;
37264
- if (wantsJson) {
37265
- printCommandEnvelope(envelope, { json: true });
37266
- } else {
37267
- process.stderr.write(`${message}
37268
- `);
37269
- }
37270
- return 2;
37271
- }
37272
- function registerSwitchCommands(program) {
37273
- program.command("switch [target]").description(
37274
- "Switch the installer-managed Deepline CLI between SDK and Python families."
37275
- ).option("--json", "Emit JSON output").addHelpText(
37276
- "after",
37277
- `
37278
- Notes:
37279
- This command changes only the local installer-managed wrapper state. It does
37280
- not re-authenticate, reinstall packages, or contact Deepline servers.
37281
-
37282
- Examples:
37283
- deepline switch status
37284
- deepline switch python
37285
- deepline switch rollback
37286
- deepline switch sdk
37287
- `
37288
- ).action((target, options) => {
37289
- process.exitCode = handleSwitch(target, options);
37290
- });
37291
- }
37292
-
37293
37709
  // src/cli/commands/tools.ts
37294
37710
  import { Option as Option2 } from "commander";
37295
37711
  import {
@@ -37297,7 +37713,7 @@ import {
37297
37713
  existsSync as existsSync14,
37298
37714
  mkdtempSync,
37299
37715
  readFileSync as readFileSync14,
37300
- writeFileSync as writeFileSync15
37716
+ writeFileSync as writeFileSync16
37301
37717
  } from "fs";
37302
37718
  import { tmpdir as tmpdir5 } from "os";
37303
37719
  import { join as join17, resolve as resolve15 } from "path";
@@ -37305,13 +37721,13 @@ import { join as join17, resolve as resolve15 } from "path";
37305
37721
  // src/tool-output.ts
37306
37722
  import {
37307
37723
  closeSync as closeSync3,
37308
- mkdirSync as mkdirSync11,
37724
+ mkdirSync as mkdirSync12,
37309
37725
  openSync as openSync3,
37310
- writeFileSync as writeFileSync14,
37726
+ writeFileSync as writeFileSync15,
37311
37727
  writeSync
37312
37728
  } from "fs";
37313
- import { homedir as homedir12 } from "os";
37314
- 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";
37315
37731
  function isPlainObject(value) {
37316
37732
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
37317
37733
  }
@@ -37438,19 +37854,19 @@ function projectRowOutput(conversion) {
37438
37854
  };
37439
37855
  }
37440
37856
  function ensureOutputDir() {
37441
- const outputDir = join16(homedir12(), ".local", "share", "deepline", "data");
37442
- mkdirSync11(outputDir, { recursive: true });
37857
+ const outputDir = join16(homedir10(), ".local", "share", "deepline", "data");
37858
+ mkdirSync12(outputDir, { recursive: true });
37443
37859
  return outputDir;
37444
37860
  }
37445
37861
  function writeJsonOutputFile(payload, stem) {
37446
37862
  const outputDir = ensureOutputDir();
37447
37863
  const outputPath = join16(outputDir, `${stem}_${Date.now()}.json`);
37448
- writeFileSync14(outputPath, JSON.stringify(payload, null, 2), "utf-8");
37864
+ writeFileSync15(outputPath, JSON.stringify(payload, null, 2), "utf-8");
37449
37865
  return outputPath;
37450
37866
  }
37451
37867
  function writeCsvOutputFile(rows, stem, options) {
37452
37868
  const outputPath = options?.outPath ? options.outPath : join16(ensureOutputDir(), `${stem}_${Date.now()}.csv`);
37453
- mkdirSync11(dirname15(outputPath), { recursive: true });
37869
+ mkdirSync12(dirname16(outputPath), { recursive: true });
37454
37870
  const columns = columnsForRows(rows);
37455
37871
  const escapeCell = (value) => {
37456
37872
  const normalized = value == null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value);
@@ -37526,6 +37942,9 @@ var TOOL_CATEGORY_DESCRIPTIONS = {
37526
37942
  premium: "Higher-cost tools with premium provider coverage.",
37527
37943
  free: "Free tools that do not spend Deepline credits."
37528
37944
  };
37945
+ var WELL_KNOWN_TOOL_CATEGORIES = Object.freeze(
37946
+ Object.keys(TOOL_CATEGORY_DESCRIPTIONS)
37947
+ );
37529
37948
  function describeToolCategory(category) {
37530
37949
  return TOOL_CATEGORY_DESCRIPTIONS[category] ?? null;
37531
37950
  }
@@ -38510,17 +38929,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
38510
38929
  const extractedValues = extractionContractEntries(
38511
38930
  arrayField2(toolExecutionResult, "extractedValues", "extracted_values")
38512
38931
  );
38513
- const cost = recordField2(tool, "cost");
38514
- const deeplineCredits = numberField2(
38515
- tool,
38516
- "deeplineCreditsPerPricingUnit",
38517
- "deepline_credits_per_pricing_unit"
38518
- );
38519
- const deeplineUsdPerPricingUnit = numberField2(
38520
- tool,
38521
- "deeplineUsdPerPricingUnit",
38522
- "deepline_usd_per_pricing_unit"
38523
- );
38932
+ const pricing = toolPricingContractForDescribe(tool);
38524
38933
  const deprecation = recordField2(tool, "deprecation");
38525
38934
  const replacementToolId = stringField2(
38526
38935
  deprecation,
@@ -38562,12 +38971,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
38562
38971
  ...Object.prototype.hasOwnProperty.call(field, "default") ? { default: field.default } : {}
38563
38972
  })),
38564
38973
  inputSchema,
38565
- cost: {
38566
- pricingModel: stringField2(cost, "pricingModel", "pricing_model") || null,
38567
- billingMode: stringField2(cost, "billingMode", "billing_mode") || null,
38568
- deeplineCreditsPerPricingUnit: deeplineCredits,
38569
- deeplineUsdPerPricingUnit
38570
- },
38974
+ cost: pricing,
38571
38975
  getters: {
38572
38976
  extractedLists,
38573
38977
  extractedValues
@@ -38576,6 +38980,38 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
38576
38980
  ...starterScript ? { starterScript } : {}
38577
38981
  };
38578
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
+ }
38579
39015
  function extractionContractEntries(entries) {
38580
39016
  return entries.flatMap((entry) => {
38581
39017
  if (!isRecord12(entry)) return [];
@@ -38805,13 +39241,16 @@ function printToolPricingOnly(tool, requestedToolId, options = {}) {
38805
39241
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
38806
39242
  const cost = isRecord12(contract.cost) ? contract.cost : {};
38807
39243
  const pricingModel = stringField2(cost, "pricingModel") || "unknown";
38808
- const billingMode = stringField2(cost, "billingMode") || "unknown";
38809
- 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");
38810
39247
  const credits = numberField2(cost, "deeplineCreditsPerPricingUnit");
38811
39248
  const usd = numberField2(cost, "deeplineUsdPerPricingUnit");
38812
- 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");
38813
39252
  console.log(`${options.heading ?? `Pricing: ${contract.toolId}`}: ${price}`);
38814
- console.log(`Billing: ${billingMode}`);
39253
+ console.log(`Billing: ${billing}`);
38815
39254
  }
38816
39255
  function printToolSchemaOnly(tool, requestedToolId) {
38817
39256
  if (isMonitorTypeTool(tool)) {
@@ -39282,9 +39721,9 @@ function apifySyncRecoveryNext(rawResponse) {
39282
39721
  const getDatasetItemsTool = stringField2(getDatasetItems, "tool");
39283
39722
  const getDatasetItemsPayload = recordField2(getDatasetItems, "payload");
39284
39723
  return {
39285
- getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote3(JSON.stringify(getActorRunPayload))} --json`,
39724
+ getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote4(JSON.stringify(getActorRunPayload))} --json`,
39286
39725
  ...getDatasetItemsTool && Object.keys(getDatasetItemsPayload).length > 0 ? {
39287
- getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote3(JSON.stringify(getDatasetItemsPayload))} --json`
39726
+ getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote4(JSON.stringify(getDatasetItemsPayload))} --json`
39288
39727
  } : {}
39289
39728
  };
39290
39729
  }
@@ -39457,7 +39896,7 @@ function parseExecuteOptions(args) {
39457
39896
  function safeFileStem(value) {
39458
39897
  return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
39459
39898
  }
39460
- function shellQuote3(value) {
39899
+ function shellQuote4(value) {
39461
39900
  return `'${value.replace(/'/g, `'\\''`)}'`;
39462
39901
  }
39463
39902
  function powerShellQuote(value) {
@@ -39522,12 +39961,12 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
39522
39961
  description: ${JSON.stringify(`Seed ${input2.toolId} rows into a Deepline workflow-ready dataset.`)},
39523
39962
  });
39524
39963
  `;
39525
- writeFileSync15(scriptPath, script, { encoding: "utf-8", mode: 384 });
39964
+ writeFileSync16(scriptPath, script, { encoding: "utf-8", mode: 384 });
39526
39965
  return {
39527
39966
  path: scriptPath,
39528
39967
  sourceCode: script,
39529
39968
  projectDir,
39530
- macCopyCommand: `mkdir -p ${shellQuote3(projectDir)} && cp ${shellQuote3(scriptPath)} ${shellQuote3(`${projectDir}/${fileName}`)}`,
39969
+ macCopyCommand: `mkdir -p ${shellQuote4(projectDir)} && cp ${shellQuote4(scriptPath)} ${shellQuote4(`${projectDir}/${fileName}`)}`,
39531
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}`)}`
39532
39971
  };
39533
39972
  }
@@ -39554,7 +39993,7 @@ function buildToolExecuteBaseEnvelope(input2) {
39554
39993
  envelope,
39555
39994
  "output"
39556
39995
  );
39557
- 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`;
39558
39997
  const actions = input2.listConversion ? [
39559
39998
  {
39560
39999
  label: "next",
@@ -39947,19 +40386,19 @@ Examples:
39947
40386
  }
39948
40387
 
39949
40388
  // src/cli/commands/update.ts
39950
- import { spawn as spawn3 } from "child_process";
40389
+ import { spawn as spawn4 } from "child_process";
39951
40390
  import {
39952
40391
  existsSync as existsSync16,
39953
- mkdirSync as mkdirSync12,
40392
+ mkdirSync as mkdirSync13,
39954
40393
  realpathSync as realpathSync4,
39955
40394
  readFileSync as readFileSync16,
39956
40395
  renameSync,
39957
40396
  rmSync as rmSync5,
39958
- unlinkSync,
39959
- writeFileSync as writeFileSync16
40397
+ unlinkSync as unlinkSync2,
40398
+ writeFileSync as writeFileSync17
39960
40399
  } from "fs";
39961
- import { homedir as homedir13 } from "os";
39962
- 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";
39963
40402
 
39964
40403
  // src/cli/install-integrity.ts
39965
40404
  import { createRequire } from "module";
@@ -40151,14 +40590,14 @@ function posixShellQuote(value) {
40151
40590
  function windowsCmdQuote(value) {
40152
40591
  return `"${value.replace(/"/g, '""')}"`;
40153
40592
  }
40154
- function shellQuote4(value) {
40593
+ function shellQuote5(value) {
40155
40594
  if (process.platform === "win32") {
40156
40595
  return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
40157
40596
  }
40158
40597
  return posixShellQuote(value);
40159
40598
  }
40160
40599
  function buildSourceUpdateCommand(sourceRoot) {
40161
- const quotedRoot = shellQuote4(sourceRoot);
40600
+ const quotedRoot = shellQuote5(sourceRoot);
40162
40601
  const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
40163
40602
  return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
40164
40603
  }
@@ -40170,7 +40609,7 @@ function buildSidecarProjectConfigCommand(versionDir, nodeBin) {
40170
40609
  "fs.mkdirSync(dir,{recursive:true});",
40171
40610
  `fs.writeFileSync(path.join(dir,'package.json'),${JSON.stringify(NPM_SDK_SIDECAR_PACKAGE_JSON)});`
40172
40611
  ].join("");
40173
- return `${shellQuote4(nodeBin)} -e ${shellQuote4(script)} ${shellQuote4(versionDir)}`;
40612
+ return `${shellQuote5(nodeBin)} -e ${shellQuote5(script)} ${shellQuote5(versionDir)}`;
40174
40613
  }
40175
40614
  function sidecarStateDir(input2) {
40176
40615
  const scope = input2.env.DEEPLINE_CONFIG_SCOPE?.trim();
@@ -40233,7 +40672,7 @@ function resolvePythonSidecarUpdatePlan(options) {
40233
40672
  const npmCommand = "npm";
40234
40673
  const registryUrl = sidecarRegistryUrl(hostUrl);
40235
40674
  const versionDir = join19(stateDir, "versions", "<version>");
40236
- 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)}`;
40237
40676
  return {
40238
40677
  kind: "python-sidecar",
40239
40678
  stateDir,
@@ -40253,7 +40692,7 @@ function findRepoBackedSdkRoot(startPath) {
40253
40692
  if (existsSync16(join19(current, "sdk", "package.json")) && existsSync16(join19(current, "sdk", "bin", "deepline-dev.ts"))) {
40254
40693
  return current;
40255
40694
  }
40256
- const parent = dirname16(current);
40695
+ const parent = dirname17(current);
40257
40696
  if (parent === current) return null;
40258
40697
  current = parent;
40259
40698
  }
@@ -40293,9 +40732,9 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
40293
40732
  }
40294
40733
  function resolveUpdatePlan(options = {}) {
40295
40734
  const env = options.env ?? process.env;
40296
- const homeDir2 = options.homeDir ?? homedir13();
40735
+ const homeDir2 = options.homeDir ?? homedir11();
40297
40736
  const entrypoint = options.entrypoint ?? (process.argv[1] ? resolve17(process.argv[1]) : "");
40298
- const sourceRoot = entrypoint ? findRepoBackedSdkRoot(dirname16(entrypoint)) : null;
40737
+ const sourceRoot = entrypoint ? findRepoBackedSdkRoot(dirname17(entrypoint)) : null;
40299
40738
  if (sourceRoot) {
40300
40739
  return {
40301
40740
  kind: "source",
@@ -40335,7 +40774,7 @@ function resolveUpdatePlan(options = {}) {
40335
40774
  fallbackRegistryUrl: publicNpmFallbackRegistryUrl(
40336
40775
  env.DEEPLINE_HOST_URL?.trim() || autoDetectBaseUrl()
40337
40776
  ),
40338
- manualCommand: `${command} ${args.map(shellQuote4).join(" ")}`
40777
+ manualCommand: `${command} ${args.map(shellQuote5).join(" ")}`
40339
40778
  };
40340
40779
  }
40341
40780
  var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
@@ -40345,7 +40784,7 @@ function autoUpdateFailurePath(plan) {
40345
40784
  return join19(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
40346
40785
  }
40347
40786
  return join19(
40348
- homedir13(),
40787
+ homedir11(),
40349
40788
  ".local",
40350
40789
  "deepline",
40351
40790
  "sdk-cli",
@@ -40383,8 +40822,8 @@ function writeAutoUpdateFailure(plan, exitCode) {
40383
40822
  manualCommand: plan.manualCommand
40384
40823
  };
40385
40824
  try {
40386
- mkdirSync12(dirname16(path), { recursive: true });
40387
- writeFileSync16(path, `${JSON.stringify(marker, null, 2)}
40825
+ mkdirSync13(dirname17(path), { recursive: true });
40826
+ writeFileSync17(path, `${JSON.stringify(marker, null, 2)}
40388
40827
  `, "utf8");
40389
40828
  } catch {
40390
40829
  }
@@ -40393,7 +40832,7 @@ function clearAutoUpdateFailure(plan) {
40393
40832
  const path = autoUpdateFailurePath(plan);
40394
40833
  if (!path) return;
40395
40834
  try {
40396
- unlinkSync(path);
40835
+ unlinkSync2(path);
40397
40836
  } catch {
40398
40837
  }
40399
40838
  }
@@ -40475,7 +40914,7 @@ function runCommand(command, args, env = process.env) {
40475
40914
  return new Promise((resolveResult) => {
40476
40915
  let output2 = "";
40477
40916
  const plan = resolveShellSpawn(command, args);
40478
- const child = spawn3(plan.command, plan.args, {
40917
+ const child = spawn4(plan.command, plan.args, {
40479
40918
  stdio: ["inherit", "pipe", "pipe"],
40480
40919
  shell: plan.shell,
40481
40920
  env
@@ -40563,9 +41002,9 @@ async function runNpmInstallWithRegistryFallback(input2) {
40563
41002
  return first.exitCode;
40564
41003
  }
40565
41004
  function writeSidecarLauncher(input2) {
40566
- mkdirSync12(dirname16(input2.path), { recursive: true });
40567
- const packageRoot = dirname16(dirname16(dirname16(input2.entryPath)));
40568
- 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));
40569
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);";
40570
41009
  const criticalPaths = [
40571
41010
  ...SDK_SIDECAR_CRITICAL_PACKAGE_FILES.map(
@@ -40576,7 +41015,7 @@ function writeSidecarLauncher(input2) {
40576
41015
  )
40577
41016
  ];
40578
41017
  if (process.platform === "win32") {
40579
- writeFileSync16(
41018
+ writeFileSync17(
40580
41019
  input2.path,
40581
41020
  [
40582
41021
  `@set DEEPLINE_HOST_URL=${input2.hostUrl.replace(/\r?\n/g, "")}`,
@@ -40599,27 +41038,27 @@ function writeSidecarLauncher(input2) {
40599
41038
  );
40600
41039
  return;
40601
41040
  }
40602
- writeFileSync16(
41041
+ writeFileSync17(
40603
41042
  input2.path,
40604
41043
  [
40605
41044
  "#!/usr/bin/env sh",
40606
- `export DEEPLINE_HOST_URL=${shellQuote4(input2.hostUrl)}`,
40607
- `export DEEPLINE_CONFIG_SCOPE=${shellQuote4(input2.scope)}`,
40608
- `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`,
40609
41048
  ' if [ -n "${DEEPLINE_REAL_BINARY:-}" ] && [ -x "$DEEPLINE_REAL_BINARY" ]; then',
40610
41049
  ' exec "$DEEPLINE_REAL_BINARY" --version=v2 "$@"',
40611
41050
  " fi",
40612
41051
  ' printf "%s\\n" "Deepline SDK CLI install is incomplete. Run \\`deepline update\\` to repair it." >&2',
40613
41052
  " exit 1",
40614
41053
  "fi",
40615
- `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`,
40616
41055
  ' if [ -n "${DEEPLINE_REAL_BINARY:-}" ] && [ -x "$DEEPLINE_REAL_BINARY" ]; then',
40617
41056
  ' exec "$DEEPLINE_REAL_BINARY" --version=v2 "$@"',
40618
41057
  " fi",
40619
41058
  ' printf "%s\\n" "Deepline SDK CLI install is incomplete. Run \\`deepline update\\` to repair it." >&2',
40620
41059
  " exit 1",
40621
41060
  "fi",
40622
- `exec ${shellQuote4(input2.nodeBin)} ${shellQuote4(input2.entryPath)} "$@"`,
41061
+ `exec ${shellQuote5(input2.nodeBin)} ${shellQuote5(input2.entryPath)} "$@"`,
40623
41062
  ""
40624
41063
  ].join("\n"),
40625
41064
  { encoding: "utf8", mode: 493 }
@@ -40632,11 +41071,11 @@ async function runPythonSidecarUpdatePlan(plan) {
40632
41071
  `.tmp-sdk-update-${process.pid}-${Date.now()}`
40633
41072
  );
40634
41073
  rmSync5(tempDir, { recursive: true, force: true });
40635
- mkdirSync12(tempDir, { recursive: true });
40636
- 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);
40637
41076
  const env = {
40638
41077
  ...process.env,
40639
- PATH: `${dirname16(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
41078
+ PATH: `${dirname17(plan.nodeBin)}${process.platform === "win32" ? ";" : ":"}${process.env.PATH ?? ""}`
40640
41079
  };
40641
41080
  const installResult = await runCommand(
40642
41081
  plan.npmCommand,
@@ -40756,27 +41195,27 @@ async function runPythonSidecarUpdatePlan(plan) {
40756
41195
  nodeBin: plan.nodeBin,
40757
41196
  entryPath: finalEntryPath
40758
41197
  });
40759
- writeFileSync16(
41198
+ writeFileSync17(
40760
41199
  join19(plan.stateDir, ".version"),
40761
41200
  `${installedVersion}
40762
41201
  `,
40763
41202
  "utf8"
40764
41203
  );
40765
- writeFileSync16(
41204
+ writeFileSync17(
40766
41205
  join19(plan.stateDir, ".install-method"),
40767
41206
  "python-sidecar\n",
40768
41207
  "utf8"
40769
41208
  );
40770
- writeFileSync16(
41209
+ writeFileSync17(
40771
41210
  join19(plan.stateDir, ".command-path"),
40772
41211
  `${plan.sidecarPath}
40773
41212
  `,
40774
41213
  "utf8"
40775
41214
  );
40776
- writeFileSync16(join19(plan.stateDir, ".runner"), "node\n", "utf8");
40777
- 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}
40778
41217
  `, "utf8");
40779
- writeFileSync16(
41218
+ writeFileSync17(
40780
41219
  join19(plan.stateDir, ".entry-path"),
40781
41220
  `${finalEntryPath}
40782
41221
  `,
@@ -40872,7 +41311,17 @@ async function runUpdateCommand(options, dependencies = {}) {
40872
41311
  if (updateExitCode !== 0) {
40873
41312
  return updateExitCode;
40874
41313
  }
40875
- 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
+ }
40876
41325
  return 0;
40877
41326
  }
40878
41327
  function registerUpdateCommand(program) {
@@ -40900,7 +41349,7 @@ Examples:
40900
41349
 
40901
41350
  // src/cli/commands/workflow.ts
40902
41351
  import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
40903
- 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";
40904
41353
 
40905
41354
  // src/cli/workflow-to-play.ts
40906
41355
  import { createHash as createHash5 } from "crypto";
@@ -41152,7 +41601,7 @@ async function transformOne(api, workflowId, outDir, publish) {
41152
41601
  { workflowName: workflow.name, version: revision.version }
41153
41602
  );
41154
41603
  const file = join20(resolve18(outDir), `${compiled.playName}.play.ts`);
41155
- await mkdir5(dirname17(file), { recursive: true });
41604
+ await mkdir5(dirname18(file), { recursive: true });
41156
41605
  await writeFile5(file, compiled.sourceCode, "utf8");
41157
41606
  let published = false;
41158
41607
  if (publish) {
@@ -41423,108 +41872,15 @@ function registerDeeplineCommandGroups(program) {
41423
41872
  registerCsvCommands(program);
41424
41873
  registerDbCommands(program);
41425
41874
  registerFeedbackCommands(program);
41426
- registerLegacyNoopCommands(program);
41875
+ registerDeprecatedCommands(program);
41427
41876
  registerUpdateCommand(program);
41428
41877
  registerSkillsCommand(program);
41429
41878
  registerSetupCommands(program);
41430
41879
  registerQuickstartCommands(program);
41431
- registerSwitchCommands(program);
41432
- }
41433
-
41434
- // ../shared_libs/cli/command-compatibility.json
41435
- var command_compatibility_default = {
41436
- enrich: {
41437
- family: "python",
41438
- label: "a legacy Python CLI enrichment command",
41439
- sdk_alternative: "Use `deepline plays ...` for durable workflows or `deepline tools execute ...` for one tool call."
41440
- },
41441
- session: {
41442
- family: "python",
41443
- label: "a legacy Python CLI session/playground command",
41444
- sdk_alternative: "Use `deepline sessions send ...` or `deepline sessions render ...` for transcript workflows."
41445
- },
41446
- workflows: {
41447
- family: "python",
41448
- label: "a legacy Python CLI workflow command",
41449
- sdk_alternative: "Use `deepline plays ...` in the SDK CLI."
41450
- },
41451
- events: {
41452
- family: "python",
41453
- label: "a legacy Python CLI event command"
41454
- },
41455
- plays: {
41456
- family: "sdk",
41457
- label: "an SDK CLI play command",
41458
- python_alternative: "Use `deepline workflows ...` only for legacy workflows."
41459
- },
41460
- runs: {
41461
- family: "sdk",
41462
- label: "an SDK CLI run inspection command"
41463
- },
41464
- sessions: {
41465
- family: "sdk",
41466
- label: "an SDK CLI session transcript command"
41467
- },
41468
- health: {
41469
- family: "sdk",
41470
- label: "an SDK CLI health command"
41471
- }
41472
- };
41473
-
41474
- // src/cli/command-compatibility.ts
41475
- var COMMAND_COMPATIBILITY = command_compatibility_default;
41476
- function cliFamilyLabel(family) {
41477
- return family === "sdk" ? "SDK CLI" : "legacy Python CLI";
41478
- }
41479
- function commandCompatibilityHint(currentFamily, commandName, baseUrl) {
41480
- const compatibility = COMMAND_COMPATIBILITY[commandName];
41481
- if (!compatibility || compatibility.family === currentFamily) {
41482
- return null;
41483
- }
41484
- const expectedFamily = compatibility.family;
41485
- const currentLabel = cliFamilyLabel(currentFamily);
41486
- const expectedLabel = cliFamilyLabel(expectedFamily);
41487
- const lines = [
41488
- "",
41489
- "Command compatibility:",
41490
- ` \`deepline ${commandName}\` is ${compatibility.label}.`,
41491
- ` Current binary: ${currentLabel}. Required binary: ${expectedLabel}.`,
41492
- " If this came from an agent skill, the installed skill likely targets the other Deepline CLI."
41493
- ];
41494
- if (currentFamily === "sdk") {
41495
- lines.push(
41496
- "",
41497
- " To stay on the SDK CLI, refresh the Deepline agent skills:",
41498
- ` ${skillsInstallCommand(baseUrl, DEFAULT_SDK_SKILL_NAMES)}`,
41499
- " To use the legacy Python CLI instead:",
41500
- ` ${legacyPythonInstallCommand(baseUrl)}`,
41501
- " `deepline update` updates this SDK CLI, but it will not switch CLI families."
41502
- );
41503
- if (compatibility.sdk_alternative) {
41504
- lines.push(` SDK alternative: ${compatibility.sdk_alternative}`);
41505
- }
41506
- } else {
41507
- lines.push(
41508
- "",
41509
- " To use SDK commands, install the SDK CLI and refresh Deepline agent skills:",
41510
- ` ${sdkNpmGlobalInstallCommand()}`,
41511
- ` ${skillsInstallCommand(baseUrl, DEFAULT_SDK_SKILL_NAMES)}`,
41512
- " `deepline update` updates this Python CLI and its skills, but it will not switch CLI families."
41513
- );
41514
- if (compatibility.python_alternative) {
41515
- lines.push(` Python alternative: ${compatibility.python_alternative}`);
41516
- }
41517
- }
41518
- return lines.join("\n");
41519
- }
41520
- function unknownCommandNameFromMessage(message) {
41521
- const match = message.match(/unknown command ['"]([^'"]+)['"]/i);
41522
- const command = match?.[1]?.trim();
41523
- return command ? command : null;
41524
41880
  }
41525
41881
 
41526
41882
  // src/cli/self-update.ts
41527
- import { spawn as spawn4 } from "child_process";
41883
+ import { spawn as spawn5 } from "child_process";
41528
41884
  function envTruthy(name) {
41529
41885
  const value = process.env[name]?.trim().toLowerCase();
41530
41886
  return value === "1" || value === "true" || value === "yes";
@@ -41571,7 +41927,7 @@ function relaunchCurrentCommand(plan) {
41571
41927
  return new Promise((resolve19) => {
41572
41928
  const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
41573
41929
  const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
41574
- const child = spawn4(command, args, {
41930
+ const child = spawn5(command, args, {
41575
41931
  stdio: "inherit",
41576
41932
  shell: process.platform === "win32",
41577
41933
  env: {
@@ -41640,357 +41996,6 @@ What changed in ${response.update_summary.version}: ${response.update_summary.su
41640
41996
  return true;
41641
41997
  }
41642
41998
 
41643
- // src/cli/skills-sync.ts
41644
- import { spawn as spawn5, spawnSync as spawnSync2 } from "child_process";
41645
- import {
41646
- existsSync as existsSync17,
41647
- mkdirSync as mkdirSync13,
41648
- readFileSync as readFileSync17,
41649
- unlinkSync as unlinkSync2,
41650
- writeFileSync as writeFileSync17
41651
- } from "fs";
41652
- import { dirname as dirname18, join as join21 } from "path";
41653
- var CHECK_TIMEOUT_MS2 = 3e3;
41654
- function shouldSkipSkillsSync() {
41655
- if (detectAgentRuntime() === "claude_cowork") {
41656
- return true;
41657
- }
41658
- const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
41659
- return value === "1" || value === "true" || value === "yes" || value === "on";
41660
- }
41661
- function activePluginSkillsDir() {
41662
- const pluginMode = process.env.DEEPLINE_PLUGIN_MODE?.trim().toLowerCase();
41663
- if (pluginMode !== "true" && pluginMode !== "1" && pluginMode !== "yes" && pluginMode !== "on") {
41664
- return "";
41665
- }
41666
- const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
41667
- return dir && existsSync17(dir) ? dir : "";
41668
- }
41669
- function readPluginSkillsVersion() {
41670
- const dir = activePluginSkillsDir();
41671
- if (!dir) return "";
41672
- try {
41673
- return readFileSync17(join21(dir, ".version"), "utf-8").trim();
41674
- } catch {
41675
- return "";
41676
- }
41677
- }
41678
- function sdkSkillsVersionPath(baseUrl) {
41679
- return join21(sdkCliStateDirPath(baseUrl), "skills-version");
41680
- }
41681
- function legacySdkSkillsVersionPath(baseUrl) {
41682
- return join21(dirname18(sdkCliStateDirPath(baseUrl)), "sdk-skills", ".version");
41683
- }
41684
- function unavailableSkillsNoticePath(baseUrl) {
41685
- return join21(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
41686
- }
41687
- function readSdkSkillsLocalVersion(baseUrl) {
41688
- const pluginVersion = readPluginSkillsVersion();
41689
- if (pluginVersion) return pluginVersion;
41690
- const path = existsSync17(sdkSkillsVersionPath(baseUrl)) ? sdkSkillsVersionPath(baseUrl) : legacySdkSkillsVersionPath(baseUrl);
41691
- if (!existsSync17(path)) return "";
41692
- try {
41693
- return readFileSync17(path, "utf-8").trim();
41694
- } catch {
41695
- return "";
41696
- }
41697
- }
41698
- function writeLocalSkillsVersion(baseUrl, version) {
41699
- const path = sdkSkillsVersionPath(baseUrl);
41700
- mkdirSync13(dirname18(path), { recursive: true });
41701
- writeFileSync17(path, `${version}
41702
- `, "utf-8");
41703
- }
41704
- function writeUnavailableSkillsNotice(baseUrl, remoteVersion, skillNames) {
41705
- const path = unavailableSkillsNoticePath(baseUrl);
41706
- try {
41707
- if (existsSync17(path) && readFileSync17(path, "utf-8").trim() === remoteVersion) {
41708
- return;
41709
- }
41710
- mkdirSync13(dirname18(path), { recursive: true });
41711
- writeFileSync17(path, `${remoteVersion}
41712
- `, "utf-8");
41713
- } catch {
41714
- }
41715
- const manualCommand = `npx ${buildSkillsInstallArgs(baseUrl, skillNames).join(" ")}`;
41716
- writeSdkSkillsStatusLine(
41717
- `Deepline agent skills are out of date, but neither \`bunx\` nor \`npx\` is available. Install Node.js/npm or Bun, then run:
41718
- ${manualCommand}`
41719
- );
41720
- }
41721
- function clearUnavailableSkillsNotice(baseUrl) {
41722
- try {
41723
- unlinkSync2(unavailableSkillsNoticePath(baseUrl));
41724
- } catch {
41725
- }
41726
- }
41727
- function sortedUniqueSkillNames(names) {
41728
- return [...new Set(names.map((name) => name.trim()).filter(Boolean))].sort(
41729
- (a, b) => a.localeCompare(b)
41730
- );
41731
- }
41732
- async function fetchV1SkillNames(baseUrl) {
41733
- const controller = new AbortController();
41734
- const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
41735
- try {
41736
- const response = await fetch(
41737
- new URL("/.well-known/skills/index.json", baseUrl),
41738
- { signal: controller.signal }
41739
- );
41740
- if (!response.ok) return [];
41741
- const data = await response.json().catch(() => null);
41742
- const names = (data?.skills ?? []).filter((skill) => skill.install_surface === "v1").map((skill) => skill.name).filter(
41743
- (name) => typeof name === "string" && name.length > 0
41744
- );
41745
- return sortedUniqueSkillNames(names);
41746
- } catch {
41747
- return [];
41748
- } finally {
41749
- clearTimeout(timeout);
41750
- }
41751
- }
41752
- function buildSdkSkillNames(v1SkillNames) {
41753
- return sortedUniqueSkillNames(v1SkillNames);
41754
- }
41755
- async function fetchSkillsUpdate(baseUrl, localVersion) {
41756
- const controller = new AbortController();
41757
- const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
41758
- try {
41759
- const response = await fetch(new URL("/api/v2/cli/update-check", baseUrl), {
41760
- method: "POST",
41761
- headers: { "Content-Type": "application/json" },
41762
- body: JSON.stringify({
41763
- skills: {
41764
- version: localVersion
41765
- }
41766
- }),
41767
- signal: controller.signal
41768
- });
41769
- if (!response.ok) return null;
41770
- const data = await response.json().catch(() => null);
41771
- const skills = data?.skills;
41772
- if (!skills) return null;
41773
- return {
41774
- needsUpdate: skills.needs_update === true,
41775
- remoteVersion: typeof skills.remote?.version === "string" ? skills.remote.version.trim() : ""
41776
- };
41777
- } catch {
41778
- return null;
41779
- } finally {
41780
- clearTimeout(timeout);
41781
- }
41782
- }
41783
- function buildSkillsInstallArgs(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES, agents) {
41784
- return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
41785
- agents
41786
- });
41787
- }
41788
- function buildBunxSkillsInstallArgs(baseUrl, skillNames, agents) {
41789
- return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
41790
- firstArg: "--bun",
41791
- agents
41792
- });
41793
- }
41794
- function resolveAutoSyncSkillAgents() {
41795
- switch (detectAgentRuntime()) {
41796
- case "codex":
41797
- return ["codex"];
41798
- case "claude_code":
41799
- return ["claude-code"];
41800
- case "cursor":
41801
- return ["cursor"];
41802
- case "gemini":
41803
- return ["gemini-cli"];
41804
- case "antigravity":
41805
- return ["antigravity"];
41806
- default:
41807
- return [];
41808
- }
41809
- }
41810
- function hasCommand(command) {
41811
- const plan = resolveShellSpawn(command, ["--version"]);
41812
- const result = spawnSync2(plan.command, plan.args, {
41813
- stdio: "ignore",
41814
- shell: plan.shell
41815
- });
41816
- return result.status === 0;
41817
- }
41818
- function shellQuote5(arg) {
41819
- return `'${arg.replace(/'/g, `'\\''`)}'`;
41820
- }
41821
- function resolveSkillsInstallSpawn(install, platform3 = process.platform) {
41822
- return resolveShellSpawn(install.command, install.args, platform3);
41823
- }
41824
- function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES, agents = DEFAULT_SKILL_AGENTS) {
41825
- const commands = [];
41826
- if (hasCommand("bunx")) {
41827
- const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames, agents);
41828
- commands.push({
41829
- command: "bunx",
41830
- args: bunxArgs,
41831
- manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
41832
- });
41833
- }
41834
- if (hasCommand("npx")) {
41835
- const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames, agents);
41836
- commands.push({
41837
- command: "npx",
41838
- args: npxArgs,
41839
- manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
41840
- });
41841
- }
41842
- return commands;
41843
- }
41844
- function runOneSkillsInstall(install) {
41845
- return new Promise((resolve19) => {
41846
- const plan = resolveSkillsInstallSpawn(install);
41847
- const child = spawn5(plan.command, plan.args, {
41848
- stdio: ["ignore", "ignore", "pipe"],
41849
- env: process.env,
41850
- shell: plan.shell
41851
- });
41852
- let stderr = "";
41853
- child.stderr.on("data", (chunk) => {
41854
- stderr += chunk.toString("utf-8");
41855
- });
41856
- child.on("error", (error) => {
41857
- resolve19({
41858
- ok: false,
41859
- detail: `failed to start ${install.command}: ${error.message}`,
41860
- manualCommand: install.manualCommand
41861
- });
41862
- });
41863
- child.on("close", (code) => {
41864
- if (code === 0) {
41865
- resolve19({ ok: true, detail: "", manualCommand: install.manualCommand });
41866
- return;
41867
- }
41868
- const detail = stderr.trim();
41869
- resolve19({
41870
- ok: false,
41871
- detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
41872
- manualCommand: install.manualCommand
41873
- });
41874
- });
41875
- });
41876
- }
41877
- async function runSkillsInstall(installs) {
41878
- const failures = [];
41879
- for (const install of installs) {
41880
- const result = await runOneSkillsInstall(install);
41881
- if (result.ok) return true;
41882
- failures.push(result);
41883
- }
41884
- const details = failures.map((failure) => failure.detail).filter(Boolean).join("\n");
41885
- const manualCommand = failures.at(-1)?.manualCommand;
41886
- process.stderr.write(
41887
- `SDK skills sync failed${details ? `:
41888
- ${details}` : ""}
41889
- ` + (manualCommand ? `Run manually: ${manualCommand}
41890
- ` : "")
41891
- );
41892
- return false;
41893
- }
41894
- function runLegacySkillsCleanup(agents) {
41895
- const candidates = hasCommand("bunx") ? [
41896
- {
41897
- command: "bunx",
41898
- args: [
41899
- "--bun",
41900
- "skills",
41901
- "remove",
41902
- "--global",
41903
- "--agent",
41904
- ...agents,
41905
- "-y",
41906
- ...LEGACY_SKILL_NAMES_TO_REMOVE
41907
- ]
41908
- },
41909
- {
41910
- command: "npx",
41911
- args: [
41912
- "--yes",
41913
- "skills",
41914
- "remove",
41915
- "--global",
41916
- "--agent",
41917
- ...agents,
41918
- "-y",
41919
- ...LEGACY_SKILL_NAMES_TO_REMOVE
41920
- ]
41921
- }
41922
- ] : [
41923
- {
41924
- command: "npx",
41925
- args: [
41926
- "--yes",
41927
- "skills",
41928
- "remove",
41929
- "--global",
41930
- "--agent",
41931
- ...agents,
41932
- "-y",
41933
- ...LEGACY_SKILL_NAMES_TO_REMOVE
41934
- ]
41935
- }
41936
- ];
41937
- for (const candidate of candidates) {
41938
- const plan = resolveShellSpawn(candidate.command, candidate.args);
41939
- const result = spawnSync2(plan.command, plan.args, {
41940
- stdio: "ignore",
41941
- env: process.env,
41942
- shell: plan.shell
41943
- });
41944
- if (result.status === 0) return;
41945
- }
41946
- }
41947
- function writeSdkSkillsStatusLine(line) {
41948
- const progress = getActiveCliProgress();
41949
- if (progress) {
41950
- progress.writeLine(line);
41951
- return;
41952
- }
41953
- process.stderr.write(`${line}
41954
- `);
41955
- }
41956
- async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
41957
- if (shouldSkipSkillsSync()) return;
41958
- const usingPluginSkills = Boolean(activePluginSkillsDir());
41959
- if (usingPluginSkills) {
41960
- return;
41961
- }
41962
- const localVersion = readSdkSkillsLocalVersion(baseUrl);
41963
- const update = options.update === void 0 ? await fetchSkillsUpdate(baseUrl, localVersion) : options.update ? {
41964
- needsUpdate: options.update.needs_update,
41965
- remoteVersion: options.update.remote.version
41966
- } : null;
41967
- if (!update?.needsUpdate || !update.remoteVersion) {
41968
- return;
41969
- }
41970
- const remoteSkillNames = await fetchV1SkillNames(baseUrl);
41971
- const skillNames = buildSdkSkillNames(
41972
- remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
41973
- );
41974
- if (skillNames.length === 0) return;
41975
- const agents = resolveAutoSyncSkillAgents();
41976
- if (agents.length === 0) {
41977
- writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
41978
- return;
41979
- }
41980
- const installs = resolveSkillsInstallCommands(baseUrl, skillNames, agents);
41981
- if (installs.length === 0) {
41982
- writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
41983
- return;
41984
- }
41985
- writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
41986
- const installed = await runSkillsInstall(installs);
41987
- if (!installed) return;
41988
- runLegacySkillsCleanup(agents);
41989
- writeLocalSkillsVersion(baseUrl, update.remoteVersion);
41990
- clearUnavailableSkillsNotice(baseUrl);
41991
- writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
41992
- }
41993
-
41994
41999
  // src/cli/failure-reporting.ts
41995
42000
  import { hostname as hostname2, platform as platform2, release } from "os";
41996
42001
  var FAILURE_REPORT_DISABLE_ENV = "DEEPLINE_DISABLE_FAILURE_REPORTING";
@@ -42269,7 +42274,7 @@ function shouldDeferSkillsSyncForCommand() {
42269
42274
  if (command === "providers" && subcommand === "list") return true;
42270
42275
  return (command === "play" || command === "plays") && subcommand === "run" && args.includes("--json");
42271
42276
  }
42272
- function isLegacyNoopInvocation() {
42277
+ function isDeprecatedCommandInvocation() {
42273
42278
  const command = process.argv.slice(2)[0];
42274
42279
  return command === "session" || command === "backend";
42275
42280
  }
@@ -42293,8 +42298,8 @@ function topLevelCommandKnown(program, commandName) {
42293
42298
  );
42294
42299
  }
42295
42300
  async function runPlayRunnerHealthCheck() {
42296
- const dir = await mkdtemp2(join22(tmpdir6(), "deepline-health-play-"));
42297
- 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");
42298
42303
  try {
42299
42304
  await writeFile6(
42300
42305
  file,
@@ -42536,7 +42541,7 @@ Exit codes:
42536
42541
  `
42537
42542
  );
42538
42543
  program.hook("preAction", async (_thisCommand, actionCommand) => {
42539
- 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()) {
42540
42545
  return;
42541
42546
  }
42542
42547
  if (printStartupPhase) {
@@ -42565,18 +42570,6 @@ Exit codes:
42565
42570
  if (relaunched) {
42566
42571
  return;
42567
42572
  }
42568
- if (compatibility.response?.cli_family?.action === "force_python") {
42569
- forcePythonCliFamily();
42570
- process.stderr.write(
42571
- "Deepline SDK CLI rollback is active; switched installer-managed `deepline` back to the Python CLI. Re-run your command.\n"
42572
- );
42573
- const error = new Error(
42574
- "SDK CLI rollback is active"
42575
- );
42576
- error.code = "deepline.sdk_cli_rollback";
42577
- error.exitCode = 7;
42578
- throw error;
42579
- }
42580
42573
  enforceSdkCompatibilityResponse(compatibility.response);
42581
42574
  if (printStartupPhase) {
42582
42575
  progress?.phase("checking sdk skills");
@@ -42704,14 +42697,6 @@ Examples:
42704
42697
  process.exitCode = 2;
42705
42698
  return;
42706
42699
  }
42707
- const hint = commandCompatibilityHint(
42708
- "sdk",
42709
- requestedTopLevelCommand,
42710
- baseUrl
42711
- );
42712
- if (hint && !process.argv.includes("--json")) {
42713
- console.error(hint);
42714
- }
42715
42700
  process.exitCode = 2;
42716
42701
  return;
42717
42702
  }
@@ -42739,19 +42724,6 @@ Examples:
42739
42724
  const wantsJson = process.argv.includes("--json");
42740
42725
  if (commanderError) {
42741
42726
  if (commanderError.code === "commander.unknownCommand") {
42742
- const commandName = unknownCommandNameFromMessage(
42743
- commanderError.message
42744
- );
42745
- if (commandName && !wantsJson) {
42746
- const hint = commandCompatibilityHint(
42747
- "sdk",
42748
- commandName,
42749
- autoDetectBaseUrl()
42750
- );
42751
- if (hint) {
42752
- console.error(hint);
42753
- }
42754
- }
42755
42727
  }
42756
42728
  process.exitCode = commanderError.code === "commander.unknownCommand" && !wantsJson ? 2 : commanderError.exitCode ?? 1;
42757
42729
  return;