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.
package/dist/cli/index.js CHANGED
@@ -186,8 +186,8 @@ configureProxyFromEnv();
186
186
 
187
187
  // src/cli/index.ts
188
188
  var import_promises10 = require("fs/promises");
189
- var import_node_path26 = require("path");
190
- var import_node_os19 = require("os");
189
+ var import_node_path25 = require("path");
190
+ var import_node_os17 = require("os");
191
191
  var import_commander4 = require("commander");
192
192
 
193
193
  // src/config.ts
@@ -994,11 +994,6 @@ function getActiveProjectAuthSource(startDir = process.cwd()) {
994
994
  return loadProjectEnvCandidates(startDir)[0] ?? null;
995
995
  }
996
996
 
997
- // src/http.ts
998
- var import_node_fs2 = require("fs");
999
- var import_node_os3 = require("os");
1000
- var import_node_path2 = require("path");
1001
-
1002
997
  // ../shared_libs/plays/artifact-contract-version.ts
1003
998
  var CURRENT_PLAY_ARTIFACT_CONTRACT_VERSION = 2;
1004
999
 
@@ -1047,7 +1042,7 @@ var SDK_RELEASE = {
1047
1042
  // 0.3.0 introduces raw-v2: complete scrubbed provider responses are
1048
1043
  // available at toolResponse.rawV2 while toolResponse.raw and all declared
1049
1044
  // getters keep their established compatibility behavior.
1050
- version: "0.3.22",
1045
+ version: "0.3.24",
1051
1046
  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.",
1052
1047
  contracts: {
1053
1048
  api: {
@@ -1236,6 +1231,88 @@ function detectAgentRuntime(options = {}) {
1236
1231
  return options.defaultRuntime ?? "unknown";
1237
1232
  }
1238
1233
 
1234
+ // src/skills-version.ts
1235
+ var import_node_fs2 = require("fs");
1236
+ var import_node_path2 = require("path");
1237
+ function activePluginSkillsDir() {
1238
+ const pluginMode = process.env.DEEPLINE_PLUGIN_MODE?.trim().toLowerCase();
1239
+ if (pluginMode !== "true" && pluginMode !== "1" && pluginMode !== "yes" && pluginMode !== "on") {
1240
+ return "";
1241
+ }
1242
+ const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
1243
+ return dir && (0, import_node_fs2.existsSync)(dir) ? dir : "";
1244
+ }
1245
+ function hasActivePluginSkills() {
1246
+ return Boolean(activePluginSkillsDir());
1247
+ }
1248
+ function readPluginSkillsVersion() {
1249
+ const dir = activePluginSkillsDir();
1250
+ if (!dir) return "";
1251
+ try {
1252
+ return (0, import_node_fs2.readFileSync)((0, import_node_path2.join)(dir, ".version"), "utf-8").trim();
1253
+ } catch {
1254
+ return "";
1255
+ }
1256
+ }
1257
+ function sdkSkillsVersionPath(baseUrl, agents = []) {
1258
+ const suffix = agents.length > 0 ? `-${agents.join("-")}` : "";
1259
+ return (0, import_node_path2.join)(sdkCliStateDirPath(baseUrl), `skills${suffix}-version`);
1260
+ }
1261
+ function legacySdkSkillsVersionPath(baseUrl) {
1262
+ return (0, import_node_path2.join)((0, import_node_path2.dirname)(sdkCliStateDirPath(baseUrl)), "sdk-skills", ".version");
1263
+ }
1264
+ function resolveAutoSyncSkillAgents() {
1265
+ switch (detectAgentRuntime()) {
1266
+ case "codex":
1267
+ return ["codex"];
1268
+ case "claude_code":
1269
+ return ["claude-code"];
1270
+ case "cursor":
1271
+ return ["cursor"];
1272
+ case "gemini":
1273
+ return ["gemini-cli"];
1274
+ case "antigravity":
1275
+ return ["antigravity"];
1276
+ default:
1277
+ return [];
1278
+ }
1279
+ }
1280
+ function readSdkSkillsLocalVersion(baseUrl) {
1281
+ const pluginVersion = readPluginSkillsVersion();
1282
+ if (pluginVersion) return pluginVersion;
1283
+ const agents = resolveAutoSyncSkillAgents();
1284
+ const scopedPath = sdkSkillsVersionPath(baseUrl, agents);
1285
+ if (agents.length > 0 && (0, import_node_fs2.existsSync)(scopedPath)) {
1286
+ try {
1287
+ return (0, import_node_fs2.readFileSync)(scopedPath, "utf-8").trim();
1288
+ } catch {
1289
+ return "";
1290
+ }
1291
+ }
1292
+ if (agents.length > 0) {
1293
+ const legacyPath = legacySdkSkillsVersionPath(baseUrl);
1294
+ if (!(0, import_node_fs2.existsSync)(legacyPath)) return "";
1295
+ try {
1296
+ return (0, import_node_fs2.readFileSync)(legacyPath, "utf-8").trim();
1297
+ } catch {
1298
+ return "";
1299
+ }
1300
+ }
1301
+ const path = (0, import_node_fs2.existsSync)(sdkSkillsVersionPath(baseUrl)) ? sdkSkillsVersionPath(baseUrl) : legacySdkSkillsVersionPath(baseUrl);
1302
+ if (!(0, import_node_fs2.existsSync)(path)) return "";
1303
+ try {
1304
+ return (0, import_node_fs2.readFileSync)(path, "utf-8").trim();
1305
+ } catch {
1306
+ return "";
1307
+ }
1308
+ }
1309
+ function writeSdkSkillsLocalVersion(baseUrl, version, agents) {
1310
+ const path = sdkSkillsVersionPath(baseUrl, agents);
1311
+ (0, import_node_fs2.mkdirSync)((0, import_node_path2.dirname)(path), { recursive: true });
1312
+ (0, import_node_fs2.writeFileSync)(path, `${version}
1313
+ `, "utf-8");
1314
+ }
1315
+
1239
1316
  // ../shared_libs/play-runtime/coordinator-headers.ts
1240
1317
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
1241
1318
  var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
@@ -1572,21 +1649,9 @@ var HttpClient = class {
1572
1649
  );
1573
1650
  if (explicit) return explicit;
1574
1651
  try {
1575
- const versionPath = (0, import_node_path2.join)(
1576
- sdkCliStateDirPath(this.config.baseUrl),
1577
- "skills-version"
1578
- );
1579
- const legacyVersionPath = (0, import_node_path2.join)(
1580
- process.env.HOME?.trim() || (0, import_node_os3.homedir)(),
1581
- ".local",
1582
- "deepline",
1583
- baseUrlSlug(this.config.baseUrl),
1584
- "sdk-skills",
1585
- ".version"
1652
+ return this.cleanDiagnosticHeader(
1653
+ readSdkSkillsLocalVersion(this.config.baseUrl)
1586
1654
  );
1587
- const resolvedPath = (0, import_node_fs2.existsSync)(versionPath) ? versionPath : legacyVersionPath;
1588
- if (!(0, import_node_fs2.existsSync)(resolvedPath)) return null;
1589
- return this.cleanDiagnosticHeader((0, import_node_fs2.readFileSync)(resolvedPath, "utf-8"));
1590
1655
  } catch {
1591
1656
  return null;
1592
1657
  }
@@ -4647,6 +4712,10 @@ var DeeplineClient = class {
4647
4712
  },
4648
4713
  targetPlans: () => this.getTargetBillingPlans(),
4649
4714
  targetStatus: () => this.getTargetBillingStatus(),
4715
+ autoRecharge: {
4716
+ get: () => this.getTargetAutoRecharge(),
4717
+ update: (options2) => this.updateTargetAutoRecharge(options2)
4718
+ },
4650
4719
  purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
4651
4720
  transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
4652
4721
  portalSession: () => this.createTargetBillingPortalSession()
@@ -6732,6 +6801,28 @@ var DeeplineClient = class {
6732
6801
  async getTargetBillingStatus() {
6733
6802
  return this.http.get("/api/v2/billing/status");
6734
6803
  }
6804
+ /** Read the canonical Metronome automatic recharge configuration. */
6805
+ async getTargetAutoRecharge() {
6806
+ return this.http.get(
6807
+ "/api/v2/billing/auto-recharge"
6808
+ );
6809
+ }
6810
+ /** Update automatic recharge and return the server-verified configuration. */
6811
+ async updateTargetAutoRecharge(options) {
6812
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
6813
+ options.idempotencyKey
6814
+ );
6815
+ const response = await this.http.put(
6816
+ "/api/v2/billing/auto-recharge",
6817
+ options.enabled ? {
6818
+ enabled: true,
6819
+ threshold_credits: options.thresholdCredits,
6820
+ refill_to_credits: options.refillToCredits
6821
+ } : { enabled: false },
6822
+ { "Idempotency-Key": idempotencyKey }
6823
+ );
6824
+ return response.data;
6825
+ }
6735
6826
  /**
6736
6827
  * Purchase target-billing credits through the durable commercial operation
6737
6828
  * flow. The caller supplies an idempotency key for safe retries.
@@ -6966,7 +7057,7 @@ var DeeplineClient = class {
6966
7057
 
6967
7058
  // src/compat.ts
6968
7059
  var import_node_fs3 = require("fs");
6969
- var import_node_os4 = require("os");
7060
+ var import_node_os3 = require("os");
6970
7061
  var import_node_path3 = require("path");
6971
7062
  var CHECK_TIMEOUT_MS = 2e3;
6972
7063
  var SDK_COMPATIBILITY_CACHE_TTL_MS = 5 * 60 * 1e3;
@@ -6974,10 +7065,10 @@ function shouldSkipCompatibilityCheck() {
6974
7065
  const value = process.env.DEEPLINE_SKIP_SDK_COMPAT_CHECK?.trim().toLowerCase();
6975
7066
  return value === "1" || value === "true" || value === "yes";
6976
7067
  }
6977
- function sdkCompatibilityCachePath(baseUrl, homeDir2 = (0, import_node_os4.homedir)()) {
7068
+ function sdkCompatibilityCachePath(baseUrl, homeDir2 = (0, import_node_os3.homedir)()) {
6978
7069
  return (0, import_node_path3.join)(sdkCliStateDirPath(baseUrl, homeDir2), "compat-cache.json");
6979
7070
  }
6980
- function legacySdkCompatibilityCachePath(homeDir2 = (0, import_node_os4.homedir)()) {
7071
+ function legacySdkCompatibilityCachePath(homeDir2 = (0, import_node_os3.homedir)()) {
6981
7072
  return (0, import_node_path3.join)(homeDir2, ".cache", "deepline", "sdk-compat-cache.json");
6982
7073
  }
6983
7074
  function compatibilityCacheKey(baseUrl, command, skillsVersion) {
@@ -7101,14 +7192,14 @@ function enforceSdkCompatibilityResponse(response) {
7101
7192
 
7102
7193
  // src/cli/commands/auth.ts
7103
7194
  var import_node_fs5 = require("fs");
7104
- var import_node_os6 = require("os");
7195
+ var import_node_os5 = require("os");
7105
7196
  var import_node_path5 = require("path");
7106
7197
 
7107
7198
  // src/cli/utils.ts
7108
7199
  var import_node_crypto = require("crypto");
7109
7200
  var import_node_fs4 = require("fs");
7110
7201
  var import_promises = require("fs/promises");
7111
- var import_node_os5 = require("os");
7202
+ var import_node_os4 = require("os");
7112
7203
  var import_node_path4 = require("path");
7113
7204
  var childProcess = __toESM(require("child_process"));
7114
7205
  var import_sync = require("csv-parse/sync");
@@ -7129,7 +7220,7 @@ async function writeOutputFile(filename, content) {
7129
7220
  }
7130
7221
  function stableOsUserId() {
7131
7222
  try {
7132
- const info = (0, import_node_os5.userInfo)();
7223
+ const info = (0, import_node_os4.userInfo)();
7133
7224
  if (typeof info.uid === "number") return `uid-${info.uid}`;
7134
7225
  if (info.username) return `user-${info.username}`;
7135
7226
  } catch {
@@ -7137,7 +7228,7 @@ function stableOsUserId() {
7137
7228
  return "unknown-user";
7138
7229
  }
7139
7230
  function defaultBrowserOpenStateDir() {
7140
- return (0, import_node_path4.join)((0, import_node_os5.tmpdir)(), `deepline-${stableOsUserId()}`, "runtime", "state");
7231
+ return (0, import_node_path4.join)((0, import_node_os4.tmpdir)(), `deepline-${stableOsUserId()}`, "runtime", "state");
7141
7232
  }
7142
7233
  function browserOpenStateFile(stateDir = defaultBrowserOpenStateDir()) {
7143
7234
  return (0, import_node_path4.join)(stateDir, "browser-open.json");
@@ -7220,7 +7311,7 @@ function browserAppNameFromBundleId(bundleId) {
7220
7311
  }
7221
7312
  function currentOsUsername() {
7222
7313
  try {
7223
- return (0, import_node_os5.userInfo)().username || "";
7314
+ return (0, import_node_os4.userInfo)().username || "";
7224
7315
  } catch {
7225
7316
  return "";
7226
7317
  }
@@ -7240,7 +7331,7 @@ function readMacosUserHome(runner = defaultBrowserCommandRunner) {
7240
7331
  } catch {
7241
7332
  }
7242
7333
  }
7243
- return (0, import_node_os5.homedir)();
7334
+ return (0, import_node_os4.homedir)();
7244
7335
  }
7245
7336
  function readDefaultMacBrowserBundleId(runner = defaultBrowserCommandRunner) {
7246
7337
  try {
@@ -7428,9 +7519,7 @@ function openUrlMacos(targetUrl, allowFocus, runner = defaultBrowserCommandRunne
7428
7519
  }
7429
7520
  }
7430
7521
  function browserOpeningDisabled() {
7431
- const value = String(
7432
- process.env.DEEPLINE_NO_BROWSER ?? process.env.PLAYGROUND_HEADLESS ?? ""
7433
- ).trim().toLowerCase();
7522
+ const value = String(process.env.DEEPLINE_NO_BROWSER ?? "").trim().toLowerCase();
7434
7523
  return value === "1" || value === "true" || value === "yes" || value === "on";
7435
7524
  }
7436
7525
  function openInBrowser(url, options = {}) {
@@ -7462,7 +7551,7 @@ function sleep3(ms) {
7462
7551
  return new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
7463
7552
  }
7464
7553
  function collectLocalEnvInfo() {
7465
- const homeDir2 = process.env.HOME?.trim() || (0, import_node_os5.homedir)();
7554
+ const homeDir2 = process.env.HOME?.trim() || (0, import_node_os4.homedir)();
7466
7555
  const info = {
7467
7556
  os: `${process.platform} ${process.arch}`,
7468
7557
  node_version: process.version,
@@ -8083,7 +8172,7 @@ async function handleRegister(args) {
8083
8172
  }
8084
8173
  if (!agentName) {
8085
8174
  try {
8086
- agentName = (0, import_node_os6.hostname)() || "Deepline CLI (TS)";
8175
+ agentName = (0, import_node_os5.hostname)() || "Deepline CLI (TS)";
8087
8176
  } catch {
8088
8177
  agentName = "Deepline CLI (TS)";
8089
8178
  }
@@ -9464,6 +9553,96 @@ async function handleTargetStatus(options) {
9464
9553
  { json: options.json }
9465
9554
  );
9466
9555
  }
9556
+ async function handleAutoRechargeStatus(options) {
9557
+ const payload = await new DeeplineClient().billing.autoRecharge.get();
9558
+ const state = payload.available ? payload.enabled ? "on" : "off" : "unavailable";
9559
+ const lines = [
9560
+ `State: ${state}`,
9561
+ ...payload.threshold_credits !== null ? [`Threshold: ${payload.threshold_credits} credits`] : [],
9562
+ ...payload.refill_to_credits !== null ? [`Refill balance to: ${payload.refill_to_credits} credits`] : []
9563
+ ];
9564
+ printCommandEnvelope(
9565
+ {
9566
+ ok: true,
9567
+ ...payload,
9568
+ render: { sections: [{ title: "automatic recharge", lines }] }
9569
+ },
9570
+ { json: options.json }
9571
+ );
9572
+ }
9573
+ async function handleAutoRechargeSet(options) {
9574
+ const thresholdCredits = parseTopUpCredits(options.thresholdCredits);
9575
+ const refillToCredits = parseTopUpCredits(options.refillToCredits);
9576
+ if (thresholdCredits === null || refillToCredits === null || refillToCredits <= thresholdCredits) {
9577
+ reportBillingFailure(
9578
+ {
9579
+ exitCode: 2,
9580
+ code: "INVALID_AUTO_RECHARGE_CONFIGURATION",
9581
+ message: "--threshold-credits and --refill-to-credits must be positive whole credits, and refill-to must be greater."
9582
+ },
9583
+ options
9584
+ );
9585
+ return;
9586
+ }
9587
+ const idempotencyKey = targetBillingIdempotencyKey(options.idempotencyKey);
9588
+ if (options.dryRun) {
9589
+ printCommandEnvelope(
9590
+ {
9591
+ ok: true,
9592
+ dry_run: true,
9593
+ idempotency_key: idempotencyKey,
9594
+ planned_request: {
9595
+ method: "PUT",
9596
+ path: "/api/v2/billing/auto-recharge",
9597
+ body: {
9598
+ enabled: true,
9599
+ threshold_credits: thresholdCredits,
9600
+ refill_to_credits: refillToCredits
9601
+ }
9602
+ }
9603
+ },
9604
+ { json: options.json }
9605
+ );
9606
+ return;
9607
+ }
9608
+ const payload = await new DeeplineClient().billing.autoRecharge.update({
9609
+ enabled: true,
9610
+ thresholdCredits,
9611
+ refillToCredits,
9612
+ idempotencyKey
9613
+ });
9614
+ printCommandEnvelope(
9615
+ { ok: true, idempotency_key: idempotencyKey, ...payload },
9616
+ { json: options.json }
9617
+ );
9618
+ }
9619
+ async function handleAutoRechargeOff(options) {
9620
+ const idempotencyKey = targetBillingIdempotencyKey(options.idempotencyKey);
9621
+ if (options.dryRun) {
9622
+ printCommandEnvelope(
9623
+ {
9624
+ ok: true,
9625
+ dry_run: true,
9626
+ idempotency_key: idempotencyKey,
9627
+ planned_request: {
9628
+ method: "PUT",
9629
+ path: "/api/v2/billing/auto-recharge",
9630
+ body: { enabled: false }
9631
+ }
9632
+ },
9633
+ { json: options.json }
9634
+ );
9635
+ return;
9636
+ }
9637
+ const payload = await new DeeplineClient().billing.autoRecharge.update({
9638
+ enabled: false,
9639
+ idempotencyKey
9640
+ });
9641
+ printCommandEnvelope(
9642
+ { ok: true, idempotency_key: idempotencyKey, ...payload },
9643
+ { json: options.json }
9644
+ );
9645
+ }
9467
9646
  async function handleBuyCredits(creditsRaw, options) {
9468
9647
  const credits = parseTopUpCredits(creditsRaw);
9469
9648
  if (credits === null) {
@@ -9725,6 +9904,31 @@ Examples:
9725
9904
  ).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);
9726
9905
  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);
9727
9906
  billing.command("status").description("Show normalized target billing state.").option("--json", "Emit JSON output").action(handleTargetStatus);
9907
+ billing.command("auto-recharge").description("Inspect and manage automatic Deepline credit recharge.").addHelpText(
9908
+ "after",
9909
+ `
9910
+ Examples:
9911
+ deepline billing auto-recharge status --json
9912
+ deepline billing auto-recharge set --threshold-credits 1000 --refill-to-credits 3500 --dry-run --json
9913
+ deepline billing auto-recharge off --dry-run --json
9914
+ `
9915
+ ).addCommand(
9916
+ new import_commander.Command("status").description("Show the canonical automatic recharge configuration.").option("--json", "Emit JSON output").action(handleAutoRechargeStatus)
9917
+ ).addCommand(
9918
+ new import_commander.Command("set").description(
9919
+ "Enable automatic recharge with a threshold and refill target."
9920
+ ).requiredOption(
9921
+ "--threshold-credits <credits>",
9922
+ "Recharge when the balance reaches this amount"
9923
+ ).requiredOption(
9924
+ "--refill-to-credits <credits>",
9925
+ "Recharge the balance to this amount"
9926
+ ).option("--idempotency-key <key>", "Stable retry key").option("--dry-run", "Print the planned update without applying it").option("--json", "Emit JSON output").action(handleAutoRechargeSet)
9927
+ ).addCommand(
9928
+ new import_commander.Command("off").description(
9929
+ "Disable automatic recharge without clearing saved amounts."
9930
+ ).option("--idempotency-key <key>", "Stable retry key").option("--dry-run", "Print the planned update without applying it").option("--json", "Emit JSON output").action(handleAutoRechargeOff)
9931
+ );
9728
9932
  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);
9729
9933
  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);
9730
9934
  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,7 +10054,7 @@ Examples:
9850
10054
  var import_node_child_process = require("child_process");
9851
10055
  var import_node_crypto3 = require("crypto");
9852
10056
  var import_node_fs7 = require("fs");
9853
- var import_node_os7 = require("os");
10057
+ var import_node_os6 = require("os");
9854
10058
  var import_node_path8 = require("path");
9855
10059
 
9856
10060
  // src/cli/dataset-stats.ts
@@ -10617,13 +10821,13 @@ async function handleCsvShow(options) {
10617
10821
  );
10618
10822
  }
10619
10823
  function csvRenderStatePath() {
10620
- return (0, import_node_path8.join)((0, import_node_os7.homedir)(), ".local", "deepline", "runtime", "csv-render.json");
10824
+ return (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".local", "deepline", "runtime", "csv-render.json");
10621
10825
  }
10622
10826
  function csvRenderLogPath() {
10623
- return (0, import_node_path8.join)((0, import_node_os7.homedir)(), ".local", "deepline", "runtime", "csv-render.log");
10827
+ return (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".local", "deepline", "runtime", "csv-render.log");
10624
10828
  }
10625
10829
  function ensureCsvRenderStateDir() {
10626
- (0, import_node_fs7.mkdirSync)((0, import_node_path8.join)((0, import_node_os7.homedir)(), ".local", "deepline", "runtime"), {
10830
+ (0, import_node_fs7.mkdirSync)((0, import_node_path8.join)((0, import_node_os6.homedir)(), ".local", "deepline", "runtime"), {
10627
10831
  recursive: true
10628
10832
  });
10629
10833
  }
@@ -10789,7 +10993,7 @@ async function handleCsvRenderStart(options) {
10789
10993
  (0, import_node_fs7.rmSync)(csvRenderStatePath(), { force: true });
10790
10994
  } else if (existingOwned) {
10791
10995
  process.stdout.write(
10792
- "Playground render is already running; reusing current process.\n"
10996
+ "CSV render is already running; reusing current process.\n"
10793
10997
  );
10794
10998
  process.stdout.write(`Render URL: ${existing.url}
10795
10999
  `);
@@ -10805,20 +11009,16 @@ async function handleCsvRenderStart(options) {
10805
11009
  const logPath = csvRenderLogPath();
10806
11010
  const logFd = (0, import_node_fs7.openSync)(logPath, "w");
10807
11011
  const token = (0, import_node_crypto3.randomUUID)();
10808
- const child = (0, import_node_child_process.spawn)(
10809
- process.execPath,
10810
- ["-e", CSV_RENDER_SERVER_SOURCE],
10811
- {
10812
- detached: true,
10813
- stdio: ["ignore", logFd, logFd],
10814
- env: {
10815
- ...process.env,
10816
- DEEPLINE_CSV_RENDER_PORT: String(port),
10817
- DEEPLINE_CSV_RENDER_CSV: csvPath,
10818
- DEEPLINE_CSV_RENDER_TOKEN: token
10819
- }
11012
+ const child = (0, import_node_child_process.spawn)(process.execPath, ["-e", CSV_RENDER_SERVER_SOURCE], {
11013
+ detached: true,
11014
+ stdio: ["ignore", logFd, logFd],
11015
+ env: {
11016
+ ...process.env,
11017
+ DEEPLINE_CSV_RENDER_PORT: String(port),
11018
+ DEEPLINE_CSV_RENDER_CSV: csvPath,
11019
+ DEEPLINE_CSV_RENDER_TOKEN: token
10820
11020
  }
10821
- );
11021
+ });
10822
11022
  (0, import_node_fs7.closeSync)(logFd);
10823
11023
  child.unref();
10824
11024
  const state = {
@@ -10855,7 +11055,7 @@ ${clip(log, 2e3)}`;
10855
11055
  `CSV render started at ${state.startedAt} on ${url}
10856
11056
  `
10857
11057
  );
10858
- process.stdout.write("Playground render is running.\n");
11058
+ process.stdout.write("CSV render is running.\n");
10859
11059
  process.stdout.write(`Render PID: ${child.pid}
10860
11060
  `);
10861
11061
  process.stdout.write(`Render URL: ${url}
@@ -10926,8 +11126,8 @@ async function handleCsvRenderStop(options) {
10926
11126
  stopped_pids: stopped,
10927
11127
  failed_pids: failed
10928
11128
  };
10929
- const text = stopped.length > 0 ? `Stopped playground render process(es): ${stopped.join(" ")}
10930
- ` : "No running playground render process found.\n";
11129
+ const text = stopped.length > 0 ? `Stopped CSV render process(es): ${stopped.join(" ")}
11130
+ ` : "No running CSV render process found.\n";
10931
11131
  printCommandEnvelope(payload, { json: options.json, text });
10932
11132
  }
10933
11133
  async function handleCsvRender(action, options) {
@@ -11409,7 +11609,7 @@ Examples:
11409
11609
 
11410
11610
  // src/cli/commands/enrich.ts
11411
11611
  var import_promises7 = require("fs/promises");
11412
- var import_node_os10 = require("os");
11612
+ var import_node_os9 = require("os");
11413
11613
  var import_node_path15 = require("path");
11414
11614
  var import_commander2 = require("commander");
11415
11615
 
@@ -13119,7 +13319,7 @@ Examples:
13119
13319
  }
13120
13320
 
13121
13321
  // src/plays/bundle-play-file.ts
13122
- var import_node_os9 = require("os");
13322
+ var import_node_os8 = require("os");
13123
13323
  var import_node_path13 = require("path");
13124
13324
  var import_node_url = require("url");
13125
13325
  var import_node_fs11 = require("fs");
@@ -13129,7 +13329,7 @@ var import_promises5 = require("fs/promises");
13129
13329
  var import_node_crypto4 = require("crypto");
13130
13330
  var import_node_fs10 = require("fs");
13131
13331
  var import_promises3 = require("fs/promises");
13132
- var import_node_os8 = require("os");
13332
+ var import_node_os7 = require("os");
13133
13333
  var import_node_path11 = require("path");
13134
13334
  var import_node_module = require("module");
13135
13335
  var import_acorn2 = require("acorn");
@@ -17363,7 +17563,7 @@ var MAX_PLAY_BUNDLE_BYTES = 30 * 1024 * 1024;
17363
17563
  // ../shared_libs/plays/bundling/index.ts
17364
17564
  var PLAY_BUNDLE_CACHE_VERSION = 36;
17365
17565
  var PLAY_ARTIFACT_CACHE_DIR = (0, import_node_path11.join)(
17366
- (0, import_node_os8.tmpdir)(),
17566
+ (0, import_node_os7.tmpdir)(),
17367
17567
  `deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION}`
17368
17568
  );
17369
17569
  var NODE_BUILTIN_SET = new Set(
@@ -19418,7 +19618,9 @@ function stringMetadata(metadata, key) {
19418
19618
  }
19419
19619
  function inputFieldFromCsvArg(csvArg) {
19420
19620
  if (typeof csvArg !== "string") return null;
19421
- const match = /^input\.([A-Za-z_$][\w$]*)$/.exec(csvArg.trim());
19621
+ const match = /^\(?\s*input\.([A-Za-z_$][\w$]*)\s*\)?(?:\s*\?\?[\s\S]+)?$/.exec(
19622
+ csvArg.trim()
19623
+ );
19422
19624
  return match?.[1] ?? null;
19423
19625
  }
19424
19626
  function fileInputBindingsFromPlaySchema(inputSchema) {
@@ -23191,6 +23393,21 @@ function printPlayCheckLimits(limits) {
23191
23393
  console.log(
23192
23394
  ` bundle: ${formatByteBudget(limits.bundle.usedBytes, limits.bundle.limitBytes)}`
23193
23395
  );
23396
+ if (limits.activeScheduledPlays) {
23397
+ const { used, limit, remaining } = limits.activeScheduledPlays;
23398
+ console.log(
23399
+ ` scheduled plays: ${used} / ${limit} active (${remaining} available)`
23400
+ );
23401
+ }
23402
+ }
23403
+ function formatPlayRuntimeLimit(runtimeLimit) {
23404
+ if (!runtimeLimit || !Number.isFinite(runtimeLimit.timeoutSeconds)) {
23405
+ return null;
23406
+ }
23407
+ const seconds = runtimeLimit.timeoutSeconds;
23408
+ if (seconds % 3600 === 0) return `${seconds / 3600}h`;
23409
+ if (seconds % 60 === 0) return `${seconds / 60}m`;
23410
+ return `${seconds}s`;
23194
23411
  }
23195
23412
  function isRecord10(value) {
23196
23413
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -23655,6 +23872,10 @@ function printPlayCheckOutcome(outcome, target, prefix) {
23655
23872
  console.error(
23656
23873
  `\u2717 ${prefix}${playName} failed ${playCheckFailureStage(outcome)}`
23657
23874
  );
23875
+ printPlayCheckFeatureFlags(
23876
+ result.featureFlags,
23877
+ (line) => console.error(line)
23878
+ );
23658
23879
  const { unstructuredErrors } = partitionMirroredErrors(
23659
23880
  result.errors,
23660
23881
  result.issues
@@ -23674,12 +23895,15 @@ function printPlayCheckOutcome(outcome, target, prefix) {
23674
23895
  console.log(
23675
23896
  summary ? `\u2713 ${prefix}${playName} valid \u2014 ${summary}` : `\u2713 ${prefix}${playName} passed ${result.limits ? "cloud" : "local"} play check`
23676
23897
  );
23898
+ printPlayCheckFeatureFlags(result.featureFlags, (line) => console.log(line));
23677
23899
  if (result.artifactHash) {
23678
23900
  console.log(` artifact: ${result.artifactHash.slice(0, 12)}`);
23679
23901
  }
23680
23902
  if (result.sourceHash) {
23681
23903
  console.log(` source: ${result.sourceHash.slice(0, 12)}`);
23682
23904
  }
23905
+ const runtimeLimit = formatPlayRuntimeLimit(result.runtimeLimit);
23906
+ if (runtimeLimit) console.log(` runtime limit: ${runtimeLimit}`);
23683
23907
  printPlayCheckLimits(result.limits);
23684
23908
  if (result.artifactHash && outcome.exportName === PLAY_DEFAULT_EXPORT) {
23685
23909
  console.log(
@@ -23695,6 +23919,11 @@ function printPlayCheckOutcome(outcome, target, prefix) {
23695
23919
  );
23696
23920
  printToolGetterHints(result.toolGetterHints);
23697
23921
  }
23922
+ function printPlayCheckFeatureFlags(flags, write) {
23923
+ for (const flag of flags ?? []) {
23924
+ write(` feature flag enabled: ${flag.label} \u2014 ${flag.reason}`);
23925
+ }
23926
+ }
23698
23927
  function printPlayCheckOutcomes(outcomes, target) {
23699
23928
  if (outcomes.length === 1) {
23700
23929
  printPlayCheckOutcome(outcomes[0], target, "");
@@ -28373,10 +28602,10 @@ function expandAtFilePath(rawPath) {
28373
28602
  (_match, bareName, bracedName) => process.env[bareName ?? bracedName ?? ""] ?? ""
28374
28603
  );
28375
28604
  if (expanded === "~") {
28376
- return (0, import_node_os10.homedir)();
28605
+ return (0, import_node_os9.homedir)();
28377
28606
  }
28378
28607
  if (expanded.startsWith("~/") || expanded.startsWith("~\\")) {
28379
- return (0, import_node_path15.join)((0, import_node_os10.homedir)(), expanded.slice(2));
28608
+ return (0, import_node_path15.join)((0, import_node_os9.homedir)(), expanded.slice(2));
28380
28609
  }
28381
28610
  return expanded;
28382
28611
  }
@@ -30839,7 +31068,7 @@ async function persistEnrichFailureReport(input2) {
30839
31068
  if (input2.jobs.length === 0 && input2.issues.length === 0) {
30840
31069
  return null;
30841
31070
  }
30842
- const stateDir = (0, import_node_path15.join)((0, import_node_os10.homedir)(), ".local", "deepline", "runtime", "state");
31071
+ const stateDir = (0, import_node_path15.join)((0, import_node_os9.homedir)(), ".local", "deepline", "runtime", "state");
30843
31072
  const reportPrefix = input2.jobs.length > 0 ? "run-block-failures" : "enrich-issues";
30844
31073
  await (0, import_promises7.mkdir)(stateDir, { recursive: true });
30845
31074
  const reportPath = (0, import_node_path15.join)(
@@ -31771,7 +32000,7 @@ function registerEnrichCommand(program) {
31771
32000
  sdkEnrichTelemetryCompleted = true;
31772
32001
  await completeSdkEnrichTelemetry(sdkEnrichTelemetry, input2);
31773
32002
  };
31774
- const tempDir = await (0, import_promises7.mkdtemp)((0, import_node_path15.join)((0, import_node_os10.tmpdir)(), "deepline-enrich-play-"));
32003
+ const tempDir = await (0, import_promises7.mkdtemp)((0, import_node_path15.join)((0, import_node_os9.tmpdir)(), "deepline-enrich-play-"));
31775
32004
  await emitSdkEnrichTelemetry(sdkEnrichTelemetry, "enrich_started");
31776
32005
  const tempPlay = (0, import_node_path15.join)(tempDir, "deepline-enrich.play.ts");
31777
32006
  let inPlaceTempDir = null;
@@ -32082,7 +32311,7 @@ Examples:
32082
32311
 
32083
32312
  // src/cli/commands/sessions.ts
32084
32313
  var import_node_fs13 = require("fs");
32085
- var import_node_os11 = require("os");
32314
+ var import_node_os10 = require("os");
32086
32315
  var import_node_path16 = require("path");
32087
32316
  var import_node_zlib = require("zlib");
32088
32317
  var import_node_crypto7 = require("crypto");
@@ -32097,14 +32326,14 @@ var MAX_EVENT_OBJECT_KEYS = 80;
32097
32326
  var TRUNCATION_MARKER = "...[truncated]";
32098
32327
  var NOISE_EVENT_TYPES = /* @__PURE__ */ new Set(["progress", "file-history-snapshot"]);
32099
32328
  function homeDir() {
32100
- return process.env.HOME?.trim() || (0, import_node_os11.homedir)();
32329
+ return process.env.HOME?.trim() || (0, import_node_os10.homedir)();
32101
32330
  }
32102
32331
  function detectShellContext() {
32103
32332
  const shellPath = process.env.SHELL?.trim() || process.env.ComSpec?.trim() || process.env.COMSPEC?.trim() || "";
32104
32333
  return {
32105
32334
  shell: shellPath ? (0, import_node_path16.basename)(shellPath).replace(/\.exe$/i, "") : "unknown",
32106
32335
  shell_path: shellPath || null,
32107
- os: (0, import_node_os11.platform)(),
32336
+ os: (0, import_node_os10.platform)(),
32108
32337
  cwd: process.cwd()
32109
32338
  };
32110
32339
  }
@@ -32820,30 +33049,31 @@ var BACKEND_SUBCOMMANDS = [
32820
33049
  "refresh-runtime",
32821
33050
  "sync-runtime"
32822
33051
  ];
32823
- function legacyNoopEnvelope(input2) {
33052
+ function deprecatedCommandEnvelope(input2) {
32824
33053
  const command = ["deepline", input2.family, input2.subcommand].filter(Boolean).join(" ");
32825
- const subject = input2.family === "session" ? "Legacy Session UI/playground command" : "Legacy local playground backend command";
32826
- 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.";
33054
+ const commandLabel = input2.family === "session" ? "Legacy session command" : "Legacy backend command";
33055
+ 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`.";
32827
33056
  return {
32828
- ok: true,
32829
- noop: true,
33057
+ ok: false,
32830
33058
  command,
32831
- compatibility: {
32832
- family: "legacy_python_cli",
32833
- sdk_behavior: "noop"
32834
- },
33059
+ code: "DEPRECATED_COMMAND",
33060
+ error: `${commandLabel} is deprecated. ${note}`,
33061
+ next: input2.family === "session" ? "deepline sessions send --current-session --json" : "deepline-admin dev status --json",
32835
33062
  render: {
32836
33063
  sections: [
32837
33064
  {
32838
- title: subject,
33065
+ title: `${commandLabel} deprecated`,
32839
33066
  lines: [note]
32840
33067
  }
32841
33068
  ]
32842
33069
  }
32843
33070
  };
32844
33071
  }
32845
- function printLegacyNoop(input2) {
32846
- printCommandEnvelope(legacyNoopEnvelope(input2), { json: input2.options.json });
33072
+ function printDeprecatedCommand(input2) {
33073
+ printCommandEnvelope(deprecatedCommandEnvelope(input2), {
33074
+ json: input2.options.json
33075
+ });
33076
+ process.exitCode = 2;
32847
33077
  }
32848
33078
  function legacySubcommandFromArgv(family) {
32849
33079
  const args = process.argv.slice(2);
@@ -32851,18 +33081,18 @@ function legacySubcommandFromArgv(family) {
32851
33081
  const nextToken = familyIndex >= 0 ? args[familyIndex + 1] : void 0;
32852
33082
  return nextToken && !nextToken.startsWith("-") ? nextToken : void 0;
32853
33083
  }
32854
- function addLegacyNoopSubcommand(parent, family, subcommand, description) {
33084
+ function addDeprecatedSubcommand(parent, family, subcommand, description) {
32855
33085
  parent.command(subcommand).description(description).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").action((_args, options) => {
32856
- printLegacyNoop({ family, subcommand, options });
33086
+ printDeprecatedCommand({ family, subcommand, options });
32857
33087
  });
32858
33088
  }
32859
- function registerLegacyNoopCommands(program) {
32860
- 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(
33089
+ function registerDeprecatedCommands(program) {
33090
+ const session = program.command("session").description("Deprecated legacy session command namespace.").allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
32861
33091
  "after",
32862
33092
  `
32863
33093
  Notes:
32864
- The SDK CLI accepts singular session commands from older agent skills so they
32865
- do not fail, but it does not manage the legacy Python Session UI.
33094
+ The legacy Python Session UI was retired. Legacy session commands now fail
33095
+ with a migration instruction; they no longer report a successful no-op.
32866
33096
  Use "deepline sessions send" or "deepline sessions render" for real SDK
32867
33097
  transcript workflows. "deepline session send" and "deepline session render"
32868
33098
  are accepted aliases for those real SDK workflows.
@@ -32874,7 +33104,7 @@ Examples:
32874
33104
  `
32875
33105
  ).action((args, options) => {
32876
33106
  void args;
32877
- printLegacyNoop({
33107
+ printDeprecatedCommand({
32878
33108
  family: "session",
32879
33109
  subcommand: legacySubcommandFromArgv("session"),
32880
33110
  options
@@ -32882,21 +33112,19 @@ Examples:
32882
33112
  });
32883
33113
  registerSessionSendRenderCommands(session, "session");
32884
33114
  for (const subcommand of SESSION_SUBCOMMANDS) {
32885
- addLegacyNoopSubcommand(
33115
+ addDeprecatedSubcommand(
32886
33116
  session,
32887
33117
  "session",
32888
33118
  subcommand,
32889
- `Accept legacy "deepline session ${subcommand}" as an SDK no-op.`
33119
+ `Deprecated legacy "deepline session ${subcommand}" command.`
32890
33120
  );
32891
33121
  }
32892
- const backend = program.command("backend").description(
32893
- "Compatibility no-ops for legacy Python local backend commands."
32894
- ).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
33122
+ const backend = program.command("backend").description("Deprecated legacy local backend command namespace.").allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
32895
33123
  "after",
32896
33124
  `
32897
33125
  Notes:
32898
- The SDK CLI uses the configured Deepline host and V2 play runtime. It does not
32899
- start, stop, or refresh the legacy Python local playground backend.
33126
+ The legacy local backend was retired. Use deepline-admin for local runtime
33127
+ lifecycle operations.
32900
33128
 
32901
33129
  Examples:
32902
33130
  deepline backend start
@@ -32905,18 +33133,18 @@ Examples:
32905
33133
  `
32906
33134
  ).action((args, options) => {
32907
33135
  void args;
32908
- printLegacyNoop({
33136
+ printDeprecatedCommand({
32909
33137
  family: "backend",
32910
33138
  subcommand: legacySubcommandFromArgv("backend"),
32911
33139
  options
32912
33140
  });
32913
33141
  });
32914
33142
  for (const subcommand of BACKEND_SUBCOMMANDS) {
32915
- addLegacyNoopSubcommand(
33143
+ addDeprecatedSubcommand(
32916
33144
  backend,
32917
33145
  "backend",
32918
33146
  subcommand,
32919
- `Accept legacy "deepline backend ${subcommand}" as an SDK no-op.`
33147
+ `Deprecated legacy "deepline backend ${subcommand}" command.`
32920
33148
  );
32921
33149
  }
32922
33150
  }
@@ -33984,6 +34212,11 @@ Notes:
33984
34212
  Deploy is a full desired definition for its key: omitting a previously stored
33985
34213
  field removes it and can replace the upstream resource. Use \`monitors update\`
33986
34214
  for a patch-style change.
34215
+ Repeating the exact saved definition resumes an incomplete deploy cleanup:
34216
+ Deepline keeps the replacement, removes only the stored previous binding after
34217
+ provider confirmation, and never creates or charges another monitor. Deepline
34218
+ also retries eligible incomplete deploy cleanups automatically in bounded
34219
+ background passes; no separate repair command is required.
33987
34220
  For a bounded urgent Deepline Native preview, set
33988
34221
  controls.execution_type="priority". Deepline injects the provider custom
33989
34222
  field and enforces a ten-slot per-org cap; do not use it for regular or bulk
@@ -34955,17 +35188,17 @@ Examples:
34955
35188
  }
34956
35189
 
34957
35190
  // src/cli/commands/setup.ts
35191
+ var import_node_child_process4 = require("child_process");
35192
+ var import_node_fs17 = require("fs");
35193
+ var import_node_os12 = require("os");
35194
+ var import_node_path19 = require("path");
35195
+
35196
+ // src/cli/commands/skills.ts
34958
35197
  var import_node_child_process3 = require("child_process");
34959
35198
  var import_node_fs16 = require("fs");
34960
- var import_node_os13 = require("os");
35199
+ var import_node_os11 = require("os");
34961
35200
  var import_node_path18 = require("path");
34962
35201
 
34963
- // src/cli/commands/skills.ts
34964
- var import_node_child_process2 = require("child_process");
34965
- var import_node_fs15 = require("fs");
34966
- var import_node_os12 = require("os");
34967
- var import_node_path17 = require("path");
34968
-
34969
35202
  // ../shared_libs/cli/install-commands.json
34970
35203
  var install_commands_default = {
34971
35204
  skills: {
@@ -34993,7 +35226,6 @@ var install_commands_default = {
34993
35226
  ]
34994
35227
  },
34995
35228
  cli: {
34996
- legacy_python_shell_template: "curl -s {base_url}/api/v2/cli/install | bash",
34997
35229
  sdk_npm_global: "npm install -g deepline@latest"
34998
35230
  }
34999
35231
  };
@@ -35032,9 +35264,6 @@ function renderTemplate(template, values) {
35032
35264
  return values[key] ?? match;
35033
35265
  });
35034
35266
  }
35035
- function shellJoin(args) {
35036
- return args.join(" ");
35037
- }
35038
35267
  function skillsIndexUrl(baseUrl) {
35039
35268
  return `${normalizeBaseUrl2(baseUrl)}${INSTALL_COMMANDS.skills.index_path}`;
35040
35269
  }
@@ -35069,19 +35298,11 @@ function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
35069
35298
  );
35070
35299
  return rendered;
35071
35300
  }
35072
- function skillsInstallCommand(baseUrl, skillName) {
35073
- return `${INSTALL_COMMANDS.skills.npx_binary} ${shellJoin(
35074
- buildSkillsAddArgs(baseUrl, skillName)
35075
- )}`;
35076
- }
35077
- function legacyPythonInstallCommand(baseUrl) {
35078
- return renderTemplate(INSTALL_COMMANDS.cli.legacy_python_shell_template, {
35079
- base_url: normalizeBaseUrl2(baseUrl)
35080
- });
35081
- }
35082
- function sdkNpmGlobalInstallCommand() {
35083
- return INSTALL_COMMANDS.cli.sdk_npm_global;
35084
- }
35301
+
35302
+ // src/cli/skills-sync.ts
35303
+ var import_node_child_process2 = require("child_process");
35304
+ var import_node_fs15 = require("fs");
35305
+ var import_node_path17 = require("path");
35085
35306
 
35086
35307
  // src/cli/windows-arg-escape.ts
35087
35308
  var CMD_META_CHARS = /([()\][%!^"`<>&|;, *?])/g;
@@ -35106,6 +35327,351 @@ function resolveShellSpawn(command, args, platform3 = process.platform) {
35106
35327
  };
35107
35328
  }
35108
35329
 
35330
+ // src/cli/skills-sync.ts
35331
+ var CHECK_TIMEOUT_MS2 = 3e3;
35332
+ function shouldSkipSkillsSync() {
35333
+ if (detectAgentRuntime() === "claude_cowork") {
35334
+ return true;
35335
+ }
35336
+ const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
35337
+ return value === "1" || value === "true" || value === "yes" || value === "on";
35338
+ }
35339
+ function unavailableSkillsNoticePath(baseUrl) {
35340
+ return (0, import_node_path17.join)(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
35341
+ }
35342
+ function failedSkillsSyncPath(baseUrl, agents) {
35343
+ return (0, import_node_path17.join)(
35344
+ sdkCliStateDirPath(baseUrl),
35345
+ `skills-sync-failed-${agents.join("-")}-version`
35346
+ );
35347
+ }
35348
+ function hasMarkedSkillsSyncVersion(path, version) {
35349
+ return Boolean(version) && readMarkedSkillsSyncVersion(path) === version;
35350
+ }
35351
+ function readMarkedSkillsSyncVersion(path) {
35352
+ try {
35353
+ return (0, import_node_fs15.existsSync)(path) ? (0, import_node_fs15.readFileSync)(path, "utf-8").trim() : "";
35354
+ } catch {
35355
+ return "";
35356
+ }
35357
+ }
35358
+ function writeMarkedSkillsSyncVersion(path, version) {
35359
+ try {
35360
+ (0, import_node_fs15.mkdirSync)((0, import_node_path17.dirname)(path), { recursive: true });
35361
+ (0, import_node_fs15.writeFileSync)(path, `${version}
35362
+ `, "utf-8");
35363
+ } catch {
35364
+ }
35365
+ }
35366
+ function writeUnavailableSkillsNotice(baseUrl, remoteVersion, skillNames) {
35367
+ const path = unavailableSkillsNoticePath(baseUrl);
35368
+ if (hasMarkedSkillsSyncVersion(path, remoteVersion)) return;
35369
+ writeMarkedSkillsSyncVersion(path, remoteVersion);
35370
+ const manualCommand = `npx ${buildSkillsInstallArgs(baseUrl, skillNames).join(" ")}`;
35371
+ writeSdkSkillsStatusLine(
35372
+ `Deepline agent skills are out of date, but neither \`bunx\` nor \`npx\` is available. Install Node.js/npm or Bun, then run:
35373
+ ${manualCommand}`
35374
+ );
35375
+ }
35376
+ function clearUnavailableSkillsNotice(baseUrl) {
35377
+ try {
35378
+ (0, import_node_fs15.unlinkSync)(unavailableSkillsNoticePath(baseUrl));
35379
+ } catch {
35380
+ }
35381
+ }
35382
+ function hasFailedSkillsSync(baseUrl, remoteVersion, agents) {
35383
+ return hasMarkedSkillsSyncVersion(
35384
+ failedSkillsSyncPath(baseUrl, agents),
35385
+ remoteVersion
35386
+ );
35387
+ }
35388
+ function hasFailedAutomaticSkillsSync(baseUrl, agents) {
35389
+ return (0, import_node_fs15.existsSync)(failedSkillsSyncPath(baseUrl, agents));
35390
+ }
35391
+ function markFailedSkillsSync(baseUrl, remoteVersion, agents) {
35392
+ writeMarkedSkillsSyncVersion(
35393
+ failedSkillsSyncPath(baseUrl, agents),
35394
+ remoteVersion
35395
+ );
35396
+ }
35397
+ function clearFailedSkillsSync(baseUrl, agents) {
35398
+ try {
35399
+ (0, import_node_fs15.unlinkSync)(failedSkillsSyncPath(baseUrl, agents));
35400
+ } catch {
35401
+ }
35402
+ }
35403
+ function clearFailedAutomaticSkillsSync(baseUrl, agents) {
35404
+ clearFailedSkillsSync(baseUrl, agents);
35405
+ }
35406
+ function sortedUniqueSkillNames(names) {
35407
+ return [...new Set(names.map((name) => name.trim()).filter(Boolean))].sort(
35408
+ (a, b) => a.localeCompare(b)
35409
+ );
35410
+ }
35411
+ async function fetchV1SkillNames(baseUrl) {
35412
+ const controller = new AbortController();
35413
+ const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
35414
+ try {
35415
+ const response = await fetch(
35416
+ new URL("/.well-known/skills/index.json", baseUrl),
35417
+ { signal: controller.signal }
35418
+ );
35419
+ if (!response.ok) return [];
35420
+ const data = await response.json().catch(() => null);
35421
+ const names = (data?.skills ?? []).filter((skill) => skill.install_surface === "v1").map((skill) => skill.name).filter(
35422
+ (name) => typeof name === "string" && name.length > 0
35423
+ );
35424
+ return sortedUniqueSkillNames(names);
35425
+ } catch {
35426
+ return [];
35427
+ } finally {
35428
+ clearTimeout(timeout);
35429
+ }
35430
+ }
35431
+ function buildSdkSkillNames(v1SkillNames) {
35432
+ return sortedUniqueSkillNames(v1SkillNames);
35433
+ }
35434
+ async function fetchSkillsUpdate(baseUrl, localVersion) {
35435
+ const controller = new AbortController();
35436
+ const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
35437
+ try {
35438
+ const response = await fetch(new URL("/api/v2/cli/update-check", baseUrl), {
35439
+ method: "POST",
35440
+ headers: { "Content-Type": "application/json" },
35441
+ body: JSON.stringify({
35442
+ skills: {
35443
+ version: localVersion
35444
+ }
35445
+ }),
35446
+ signal: controller.signal
35447
+ });
35448
+ if (!response.ok) return null;
35449
+ const data = await response.json().catch(() => null);
35450
+ const skills = data?.skills;
35451
+ if (!skills) return null;
35452
+ return {
35453
+ needsUpdate: skills.needs_update === true,
35454
+ remoteVersion: typeof skills.remote?.version === "string" ? skills.remote.version.trim() : ""
35455
+ };
35456
+ } catch {
35457
+ return null;
35458
+ } finally {
35459
+ clearTimeout(timeout);
35460
+ }
35461
+ }
35462
+ function buildSkillsInstallArgs(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES, agents) {
35463
+ return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
35464
+ agents
35465
+ });
35466
+ }
35467
+ function buildBunxSkillsInstallArgs(baseUrl, skillNames, agents) {
35468
+ return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
35469
+ firstArg: "--bun",
35470
+ agents
35471
+ });
35472
+ }
35473
+ function hasCommand(command) {
35474
+ const plan = resolveShellSpawn(command, ["--version"]);
35475
+ const result = (0, import_node_child_process2.spawnSync)(plan.command, plan.args, {
35476
+ stdio: "ignore",
35477
+ shell: plan.shell
35478
+ });
35479
+ return result.status === 0;
35480
+ }
35481
+ function shellQuote3(arg) {
35482
+ return `'${arg.replace(/'/g, `'\\''`)}'`;
35483
+ }
35484
+ function temporarySkillsSyncSkipCommand() {
35485
+ if (process.platform === "win32") {
35486
+ return "set DEEPLINE_SKIP_SKILLS_SYNC=1 && deepline <command> (cmd), or $env:DEEPLINE_SKIP_SKILLS_SYNC='1'; deepline <command> (PowerShell)";
35487
+ }
35488
+ return "DEEPLINE_SKIP_SKILLS_SYNC=1 deepline <command>";
35489
+ }
35490
+ function resolveSkillsInstallSpawn(install, platform3 = process.platform) {
35491
+ return resolveShellSpawn(install.command, install.args, platform3);
35492
+ }
35493
+ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES, agents = DEFAULT_SKILL_AGENTS) {
35494
+ const commands = [];
35495
+ if (hasCommand("bunx")) {
35496
+ const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames, agents);
35497
+ commands.push({
35498
+ command: "bunx",
35499
+ args: bunxArgs,
35500
+ manualCommand: `bunx ${bunxArgs.map(shellQuote3).join(" ")}`
35501
+ });
35502
+ }
35503
+ if (hasCommand("npx")) {
35504
+ const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames, agents);
35505
+ commands.push({
35506
+ command: "npx",
35507
+ args: npxArgs,
35508
+ manualCommand: `npx ${npxArgs.map(shellQuote3).join(" ")}`
35509
+ });
35510
+ }
35511
+ return commands;
35512
+ }
35513
+ function runOneSkillsInstall(install) {
35514
+ return new Promise((resolve19) => {
35515
+ const plan = resolveSkillsInstallSpawn(install);
35516
+ const child = (0, import_node_child_process2.spawn)(plan.command, plan.args, {
35517
+ stdio: ["ignore", "ignore", "pipe"],
35518
+ env: process.env,
35519
+ shell: plan.shell
35520
+ });
35521
+ let stderr = "";
35522
+ child.stderr.on("data", (chunk) => {
35523
+ stderr += chunk.toString("utf-8");
35524
+ });
35525
+ child.on("error", (error) => {
35526
+ resolve19({
35527
+ ok: false,
35528
+ detail: `failed to start ${install.command}: ${error.message}`,
35529
+ manualCommand: install.manualCommand
35530
+ });
35531
+ });
35532
+ child.on("close", (code) => {
35533
+ if (code === 0) {
35534
+ resolve19({ ok: true, detail: "", manualCommand: install.manualCommand });
35535
+ return;
35536
+ }
35537
+ const detail = stderr.trim();
35538
+ resolve19({
35539
+ ok: false,
35540
+ detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
35541
+ manualCommand: install.manualCommand
35542
+ });
35543
+ });
35544
+ });
35545
+ }
35546
+ async function runSkillsInstall(installs, agents) {
35547
+ const failures = [];
35548
+ for (const install of installs) {
35549
+ const result = await runOneSkillsInstall(install);
35550
+ if (result.ok) return true;
35551
+ failures.push(result);
35552
+ }
35553
+ const details = failures.map((failure) => failure.detail).filter(Boolean).join("\n");
35554
+ const attemptedCommands = failures.map((failure) => ` ${failure.manualCommand}`).join("\n");
35555
+ const retryAgent = agents.at(0);
35556
+ process.stderr.write(
35557
+ `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.
35558
+ ` + (attemptedCommands ? `Attempted installer command${failures.length === 1 ? "" : "s"}:
35559
+ ${attemptedCommands}
35560
+ ` : "") + (details ? `Installer output:
35561
+ ${details}
35562
+ ` : "") + (retryAgent ? `To retry with full installer output: deepline skills --agent ${retryAgent} --json
35563
+ ` : "") + `To temporarily suppress automatic skills sync: ${temporarySkillsSyncSkipCommand()}
35564
+ `
35565
+ );
35566
+ return false;
35567
+ }
35568
+ function runLegacySkillsCleanup(agents) {
35569
+ const candidates = hasCommand("bunx") ? [
35570
+ {
35571
+ command: "bunx",
35572
+ args: [
35573
+ "--bun",
35574
+ "skills",
35575
+ "remove",
35576
+ "--global",
35577
+ "--agent",
35578
+ ...agents,
35579
+ "-y",
35580
+ ...LEGACY_SKILL_NAMES_TO_REMOVE
35581
+ ]
35582
+ },
35583
+ {
35584
+ command: "npx",
35585
+ args: [
35586
+ "--yes",
35587
+ "skills",
35588
+ "remove",
35589
+ "--global",
35590
+ "--agent",
35591
+ ...agents,
35592
+ "-y",
35593
+ ...LEGACY_SKILL_NAMES_TO_REMOVE
35594
+ ]
35595
+ }
35596
+ ] : [
35597
+ {
35598
+ command: "npx",
35599
+ args: [
35600
+ "--yes",
35601
+ "skills",
35602
+ "remove",
35603
+ "--global",
35604
+ "--agent",
35605
+ ...agents,
35606
+ "-y",
35607
+ ...LEGACY_SKILL_NAMES_TO_REMOVE
35608
+ ]
35609
+ }
35610
+ ];
35611
+ for (const candidate of candidates) {
35612
+ const plan = resolveShellSpawn(candidate.command, candidate.args);
35613
+ const result = (0, import_node_child_process2.spawnSync)(plan.command, plan.args, {
35614
+ stdio: "ignore",
35615
+ env: process.env,
35616
+ shell: plan.shell
35617
+ });
35618
+ if (result.status === 0) return;
35619
+ }
35620
+ }
35621
+ function writeSdkSkillsStatusLine(line) {
35622
+ const progress = getActiveCliProgress();
35623
+ if (progress) {
35624
+ progress.writeLine(line);
35625
+ return;
35626
+ }
35627
+ process.stderr.write(`${line}
35628
+ `);
35629
+ }
35630
+ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
35631
+ if (shouldSkipSkillsSync()) return;
35632
+ const usingPluginSkills = hasActivePluginSkills();
35633
+ if (usingPluginSkills) {
35634
+ return;
35635
+ }
35636
+ const localVersion = readSdkSkillsLocalVersion(baseUrl);
35637
+ const update = options.update === void 0 ? await fetchSkillsUpdate(baseUrl, localVersion) : options.update ? {
35638
+ needsUpdate: options.update.needs_update,
35639
+ remoteVersion: options.update.remote.version
35640
+ } : null;
35641
+ if (!update?.needsUpdate || !update.remoteVersion) {
35642
+ return;
35643
+ }
35644
+ const agents = resolveAutoSyncSkillAgents();
35645
+ if (agents.length > 0 && hasFailedSkillsSync(baseUrl, update.remoteVersion, agents)) {
35646
+ return;
35647
+ }
35648
+ const remoteSkillNames = await fetchV1SkillNames(baseUrl);
35649
+ const skillNames = buildSdkSkillNames(
35650
+ remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
35651
+ );
35652
+ if (skillNames.length === 0) return;
35653
+ if (agents.length === 0) {
35654
+ writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
35655
+ return;
35656
+ }
35657
+ const installs = resolveSkillsInstallCommands(baseUrl, skillNames, agents);
35658
+ if (installs.length === 0) {
35659
+ writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
35660
+ return;
35661
+ }
35662
+ writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
35663
+ const installed = await runSkillsInstall(installs, agents);
35664
+ if (!installed) {
35665
+ markFailedSkillsSync(baseUrl, update.remoteVersion, agents);
35666
+ return;
35667
+ }
35668
+ runLegacySkillsCleanup(agents);
35669
+ writeSdkSkillsLocalVersion(baseUrl, update.remoteVersion, agents);
35670
+ clearUnavailableSkillsNotice(baseUrl);
35671
+ clearFailedSkillsSync(baseUrl, agents);
35672
+ writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
35673
+ }
35674
+
35109
35675
  // src/cli/commands/skills.ts
35110
35676
  var RUNTIME_TO_SKILLS_AGENT = {
35111
35677
  antigravity: "antigravity",
@@ -35167,17 +35733,17 @@ function detectSkillsAgents(input2) {
35167
35733
  if (knownAgent) return [knownAgent];
35168
35734
  const roots = [
35169
35735
  ...input2.scope === "local" && input2.root ? [input2.root] : [],
35170
- input2.homeDir ?? (0, import_node_os12.homedir)()
35736
+ input2.homeDir ?? (0, import_node_os11.homedir)()
35171
35737
  ];
35172
35738
  const detected = AGENT_MARKERS.filter(
35173
35739
  (marker) => roots.some(
35174
- (root) => marker.paths.some((path) => (0, import_node_fs15.existsSync)((0, import_node_path17.join)(root, path)))
35740
+ (root) => marker.paths.some((path) => (0, import_node_fs16.existsSync)((0, import_node_path18.join)(root, path)))
35175
35741
  )
35176
35742
  ).map((marker) => marker.agent);
35177
35743
  return detected.length > 0 ? detected : ["*"];
35178
35744
  }
35179
35745
  function skillsStatePathForScope(baseUrl, scope, root) {
35180
- return scope === "local" && root ? (0, import_node_path17.join)(root, ".deepline", "setup", "skills.json") : (0, import_node_path17.join)(sdkCliStateDirPath(baseUrl), "skills-install.json");
35746
+ return scope === "local" && root ? (0, import_node_path18.join)(root, ".deepline", "setup", "skills.json") : (0, import_node_path18.join)(sdkCliStateDirPath(baseUrl), "skills-install.json");
35181
35747
  }
35182
35748
  function buildSkillsPlan(input2) {
35183
35749
  const scopeArgs = input2.scope === "global" ? ["--global"] : [];
@@ -35244,7 +35810,7 @@ function isSkillsPlanCurrent(plan, state) {
35244
35810
  }
35245
35811
  function readSkillsInstallState(path) {
35246
35812
  try {
35247
- const parsed = JSON.parse((0, import_node_fs15.readFileSync)(path, "utf8"));
35813
+ const parsed = JSON.parse((0, import_node_fs16.readFileSync)(path, "utf8"));
35248
35814
  return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
35249
35815
  } catch {
35250
35816
  return null;
@@ -35253,7 +35819,7 @@ function readSkillsInstallState(path) {
35253
35819
  function runProcess(command, args, cwd) {
35254
35820
  return new Promise((resolve19, reject) => {
35255
35821
  const plan = resolveShellSpawn(command, args);
35256
- const child = (0, import_node_child_process2.spawn)(plan.command, plan.args, {
35822
+ const child = (0, import_node_child_process3.spawn)(plan.command, plan.args, {
35257
35823
  cwd,
35258
35824
  env: process.env,
35259
35825
  stdio: ["ignore", "ignore", "pipe"],
@@ -35307,7 +35873,7 @@ async function runSkillsCommand(options, dependencies = {}) {
35307
35873
  );
35308
35874
  return 0;
35309
35875
  }
35310
- if (isSkillsPlanCurrent(plan, readSkillsInstallState(plan.statePath))) {
35876
+ if (isSkillsPlanCurrent(plan, readSkillsInstallState(plan.statePath)) && !hasFailedAutomaticSkillsSync(baseUrl, agents)) {
35311
35877
  printCommandEnvelope(
35312
35878
  {
35313
35879
  ok: true,
@@ -35388,8 +35954,8 @@ async function runSkillsCommand(options, dependencies = {}) {
35388
35954
  );
35389
35955
  return 5;
35390
35956
  }
35391
- (0, import_node_fs15.mkdirSync)((0, import_node_path17.dirname)(plan.statePath), { recursive: true });
35392
- (0, import_node_fs15.writeFileSync)(
35957
+ (0, import_node_fs16.mkdirSync)((0, import_node_path18.dirname)(plan.statePath), { recursive: true });
35958
+ (0, import_node_fs16.writeFileSync)(
35393
35959
  plan.statePath,
35394
35960
  `${JSON.stringify(
35395
35961
  {
@@ -35407,6 +35973,9 @@ async function runSkillsCommand(options, dependencies = {}) {
35407
35973
  `,
35408
35974
  "utf8"
35409
35975
  );
35976
+ if (scope === "global") {
35977
+ clearFailedAutomaticSkillsSync(baseUrl, agents);
35978
+ }
35410
35979
  printCommandEnvelope(
35411
35980
  {
35412
35981
  ok: true,
@@ -35523,7 +36092,7 @@ function phasesFromLegacyStatus(status) {
35523
36092
  function readSetupState(input2) {
35524
36093
  try {
35525
36094
  const parsed = JSON.parse(
35526
- (0, import_node_fs16.readFileSync)(
36095
+ (0, import_node_fs17.readFileSync)(
35527
36096
  setupStatePath(input2.baseUrl, input2.scope, input2.root),
35528
36097
  "utf8"
35529
36098
  )
@@ -35599,7 +36168,7 @@ function buildPendingAuthorizationOutput(input2) {
35599
36168
  };
35600
36169
  }
35601
36170
  function setupStatePath(baseUrl, scope, root) {
35602
- return scope === "local" && root ? (0, import_node_path18.join)(root, ".deepline", "setup", "state.json") : (0, import_node_path18.join)(sdkCliStateDirPath(baseUrl), "setup.json");
36171
+ return scope === "local" && root ? (0, import_node_path19.join)(root, ".deepline", "setup", "state.json") : (0, import_node_path19.join)(sdkCliStateDirPath(baseUrl), "setup.json");
35603
36172
  }
35604
36173
  async function captureStdout2(run) {
35605
36174
  let stdout = "";
@@ -35628,14 +36197,14 @@ function asRecord3(value) {
35628
36197
  }
35629
36198
  function safeRead(path) {
35630
36199
  try {
35631
- return (0, import_node_fs16.readFileSync)(path, "utf8");
36200
+ return (0, import_node_fs17.readFileSync)(path, "utf8");
35632
36201
  } catch {
35633
36202
  return "";
35634
36203
  }
35635
36204
  }
35636
36205
  function isNpmManagedDeeplinePath(path) {
35637
36206
  try {
35638
- return (0, import_node_fs16.realpathSync)(path).includes(`${(0, import_node_path18.join)("node_modules", "deepline")}`);
36207
+ return (0, import_node_fs17.realpathSync)(path).includes(`${(0, import_node_path19.join)("node_modules", "deepline")}`);
35639
36208
  } catch {
35640
36209
  return false;
35641
36210
  }
@@ -35645,50 +36214,50 @@ function isInstallerManagedLegacyLauncher(path) {
35645
36214
  return content.includes("DEEPLINE_REAL_BINARY") && content.includes("DEEPLINE_ACTIVE_FILE");
35646
36215
  }
35647
36216
  function removeKnownLegacyPaths(baseUrl) {
35648
- const home = (0, import_node_os13.homedir)();
35649
- const hostDir = (0, import_node_path18.join)(home, ".local", "deepline", baseUrlSlug(baseUrl));
35650
- const legacyLauncherPath = (0, import_node_path18.join)(home, ".local", "bin", "deepline");
36217
+ const home = (0, import_node_os12.homedir)();
36218
+ const hostDir = (0, import_node_path19.join)(home, ".local", "deepline", baseUrlSlug(baseUrl));
36219
+ const legacyLauncherPath = (0, import_node_path19.join)(home, ".local", "bin", "deepline");
35651
36220
  const installerCommandPath = safeRead(
35652
- (0, import_node_path18.join)(hostDir, "sdk", ".command-path")
36221
+ (0, import_node_path19.join)(hostDir, "sdk", ".command-path")
35653
36222
  ).trim();
35654
- const relativeInstallerCommandPath = installerCommandPath ? (0, import_node_path18.relative)((0, import_node_path18.resolve)(hostDir), (0, import_node_path18.resolve)(installerCommandPath)) : "";
36223
+ const relativeInstallerCommandPath = installerCommandPath ? (0, import_node_path19.relative)((0, import_node_path19.resolve)(hostDir), (0, import_node_path19.resolve)(installerCommandPath)) : "";
35655
36224
  const isOwnedInstallerCommand = Boolean(installerCommandPath) && relativeInstallerCommandPath !== "" && !relativeInstallerCommandPath.startsWith(
35656
36225
  `..${process.platform === "win32" ? "\\" : "/"}`
35657
- ) && relativeInstallerCommandPath !== ".." && (0, import_node_path18.basename)(installerCommandPath) === "deepline";
36226
+ ) && relativeInstallerCommandPath !== ".." && (0, import_node_path19.basename)(installerCommandPath) === "deepline";
35658
36227
  const candidates = [
35659
36228
  ...isInstallerManagedLegacyLauncher(legacyLauncherPath) ? [legacyLauncherPath] : [],
35660
- (0, import_node_path18.join)(home, ".local", "bin", "deepline-real"),
35661
- (0, import_node_path18.join)(hostDir, "bin", "deepline"),
35662
- (0, import_node_path18.join)(hostDir, "bin", "deepline-real"),
35663
- (0, import_node_path18.join)(hostDir, "cli", ".install-method"),
35664
- (0, import_node_path18.join)(hostDir, "cli", ".version"),
35665
- (0, import_node_path18.join)(hostDir, "sdk", ".install-method"),
35666
- (0, import_node_path18.join)(hostDir, "sdk", ".command-path"),
36229
+ (0, import_node_path19.join)(home, ".local", "bin", "deepline-real"),
36230
+ (0, import_node_path19.join)(hostDir, "bin", "deepline"),
36231
+ (0, import_node_path19.join)(hostDir, "bin", "deepline-real"),
36232
+ (0, import_node_path19.join)(hostDir, "cli", ".install-method"),
36233
+ (0, import_node_path19.join)(hostDir, "cli", ".version"),
36234
+ (0, import_node_path19.join)(hostDir, "sdk", ".install-method"),
36235
+ (0, import_node_path19.join)(hostDir, "sdk", ".command-path"),
35667
36236
  ...isOwnedInstallerCommand ? [
35668
36237
  installerCommandPath,
35669
- (0, import_node_path18.join)((0, import_node_path18.dirname)(installerCommandPath), "deepline-sdk")
36238
+ (0, import_node_path19.join)((0, import_node_path19.dirname)(installerCommandPath), "deepline-sdk")
35670
36239
  ] : []
35671
36240
  ];
35672
36241
  const removed = [];
35673
36242
  for (const path of candidates) {
35674
- if (!(0, import_node_fs16.existsSync)(path)) continue;
36243
+ if (!(0, import_node_fs17.existsSync)(path)) continue;
35675
36244
  if (path === installerCommandPath && isNpmManagedDeeplinePath(path)) {
35676
36245
  continue;
35677
36246
  }
35678
- (0, import_node_fs16.rmSync)(path, { force: true });
36247
+ (0, import_node_fs17.rmSync)(path, { force: true });
35679
36248
  removed.push(path);
35680
36249
  }
35681
36250
  return removed;
35682
36251
  }
35683
36252
  function resolvePathCommands(command) {
35684
- const lookup = (0, import_node_child_process3.spawnSync)(
36253
+ const lookup = (0, import_node_child_process4.spawnSync)(
35685
36254
  process.platform === "win32" ? "where" : "which",
35686
36255
  process.platform === "win32" ? [command] : ["-a", command],
35687
36256
  { encoding: "utf8", shell: process.platform === "win32" }
35688
36257
  );
35689
36258
  return [
35690
36259
  ...new Set(
35691
- String(lookup.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((path) => (0, import_node_path18.resolve)(path))
36260
+ String(lookup.stdout ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((path) => (0, import_node_path19.resolve)(path))
35692
36261
  )
35693
36262
  ];
35694
36263
  }
@@ -35698,7 +36267,7 @@ function resolvePathCommand(command) {
35698
36267
  function isHomebrewFormulaCommand(path) {
35699
36268
  let resolvedPath = path;
35700
36269
  try {
35701
- resolvedPath = (0, import_node_fs16.realpathSync)(path);
36270
+ resolvedPath = (0, import_node_fs17.realpathSync)(path);
35702
36271
  } catch {
35703
36272
  return false;
35704
36273
  }
@@ -35708,8 +36277,8 @@ function isHomebrewFormulaCommand(path) {
35708
36277
  }
35709
36278
  function resolvePersistentGlobalCommand(dependencies = {}) {
35710
36279
  const platform3 = dependencies.platform ?? process.platform;
35711
- const run = dependencies.spawn ?? import_node_child_process3.spawnSync;
35712
- const pathExists = dependencies.exists ?? import_node_fs16.existsSync;
36280
+ const run = dependencies.spawn ?? import_node_child_process4.spawnSync;
36281
+ const pathExists = dependencies.exists ?? import_node_fs17.existsSync;
35713
36282
  const pathClis = dependencies.pathClis ?? resolvePathCommands("deepline");
35714
36283
  const homebrewCommand = pathClis.find(isHomebrewFormulaCommand);
35715
36284
  if (homebrewCommand) return homebrewCommand;
@@ -35721,7 +36290,7 @@ function resolvePersistentGlobalCommand(dependencies = {}) {
35721
36290
  if (prefix.status !== 0) return null;
35722
36291
  const root = String(prefix.stdout ?? "").trim();
35723
36292
  if (!root) return null;
35724
- const candidates = platform3 === "win32" ? [(0, import_node_path18.join)(root, "deepline.cmd"), (0, import_node_path18.join)(root, "deepline")] : [(0, import_node_path18.join)(root, "bin", "deepline")];
36293
+ const candidates = platform3 === "win32" ? [(0, import_node_path19.join)(root, "deepline.cmd"), (0, import_node_path19.join)(root, "deepline")] : [(0, import_node_path19.join)(root, "bin", "deepline")];
35725
36294
  return candidates.find((candidate) => pathExists(candidate)) ?? null;
35726
36295
  }
35727
36296
  function inspectGlobalCliAvailability(input2) {
@@ -35734,20 +36303,20 @@ function inspectGlobalCliAvailability(input2) {
35734
36303
  }
35735
36304
  function pathsResolveToSameFile(left, right) {
35736
36305
  try {
35737
- return (0, import_node_fs16.realpathSync)(left) === (0, import_node_fs16.realpathSync)(right);
36306
+ return (0, import_node_fs17.realpathSync)(left) === (0, import_node_fs17.realpathSync)(right);
35738
36307
  } catch {
35739
- return (0, import_node_path18.resolve)(left) === (0, import_node_path18.resolve)(right);
36308
+ return (0, import_node_path19.resolve)(left) === (0, import_node_path19.resolve)(right);
35740
36309
  }
35741
36310
  }
35742
36311
  function isKnownDeeplineCommand(path) {
35743
- const entrypoint = process.argv[1] ? (0, import_node_path18.resolve)(process.argv[1]) : "";
36312
+ const entrypoint = process.argv[1] ? (0, import_node_path19.resolve)(process.argv[1]) : "";
35744
36313
  let resolvedPath = path;
35745
36314
  try {
35746
- resolvedPath = (0, import_node_fs16.realpathSync)(path);
36315
+ resolvedPath = (0, import_node_fs17.realpathSync)(path);
35747
36316
  } catch {
35748
36317
  }
35749
36318
  if (entrypoint && resolvedPath === entrypoint) return true;
35750
- if (resolvedPath.includes(`${(0, import_node_path18.join)("node_modules", "deepline")}`)) return true;
36319
+ if (resolvedPath.includes(`${(0, import_node_path19.join)("node_modules", "deepline")}`)) return true;
35751
36320
  const content = safeRead(path);
35752
36321
  return content.includes("node_modules/deepline") || content.includes("node_modules\\deepline") || content.includes("DEEPLINE_CONFIG_SCOPE") || content.includes("deepline-real");
35753
36322
  }
@@ -35755,9 +36324,9 @@ function inspectPathConflict() {
35755
36324
  const commandPath = resolvePathCommand("deepline");
35756
36325
  if (!commandPath || isKnownDeeplineCommand(commandPath)) return null;
35757
36326
  try {
35758
- if ((0, import_node_fs16.lstatSync)(commandPath).isSymbolicLink()) {
35759
- const target = (0, import_node_fs16.realpathSync)(commandPath);
35760
- if (target.includes(`${(0, import_node_path18.join)("node_modules", "deepline")}`)) return null;
36327
+ if ((0, import_node_fs17.lstatSync)(commandPath).isSymbolicLink()) {
36328
+ const target = (0, import_node_fs17.realpathSync)(commandPath);
36329
+ if (target.includes(`${(0, import_node_path19.join)("node_modules", "deepline")}`)) return null;
35761
36330
  }
35762
36331
  } catch {
35763
36332
  }
@@ -35765,8 +36334,8 @@ function inspectPathConflict() {
35765
36334
  }
35766
36335
  function writeSetupState(input2) {
35767
36336
  const path = setupStatePath(input2.baseUrl, input2.scope, input2.root);
35768
- (0, import_node_fs16.mkdirSync)((0, import_node_path18.dirname)(path), { recursive: true });
35769
- (0, import_node_fs16.writeFileSync)(
36337
+ (0, import_node_fs17.mkdirSync)((0, import_node_path19.dirname)(path), { recursive: true });
36338
+ (0, import_node_fs17.writeFileSync)(
35770
36339
  path,
35771
36340
  `${JSON.stringify(
35772
36341
  {
@@ -35806,7 +36375,7 @@ function failSetupPhase(phases, phase, code) {
35806
36375
  phases[phase] = { status: "failed", code };
35807
36376
  }
35808
36377
  function rollbackCommand(scope, root) {
35809
- const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify((0, import_node_path18.join)(root, ".deepline", "runtime"))}` : "";
36378
+ const prefix = scope === "local" && root ? ` --prefix ${JSON.stringify((0, import_node_path19.join)(root, ".deepline", "runtime"))}` : "";
35810
36379
  return `npm install -g${prefix} --no-audit --no-fund --include=optional --allow-scripts=esbuild deepline@${SDK_VERSION}`;
35811
36380
  }
35812
36381
  function setupResumeCommand(baseUrl, scope) {
@@ -35893,12 +36462,12 @@ function buildDoctorAssessment(input2) {
35893
36462
  const connected = input2.authStatus.payload?.connected === true;
35894
36463
  const authScopeOk = input2.scope === "local" ? Boolean(projectAuth) : Boolean(apiKey && !projectAuth);
35895
36464
  const skillsOk = skillsState?.scope === input2.scope && typeof skillsState.skillsVersion === "string" && Array.isArray(skillsState.agents) && skillsState.agents.length > 0;
35896
- const runningCliPath = process.argv[1] ? (0, import_node_path18.resolve)(process.argv[1]) : null;
36465
+ const runningCliPath = process.argv[1] ? (0, import_node_path19.resolve)(process.argv[1]) : null;
35897
36466
  const globalCli = input2.scope === "global" ? inspectGlobalCliAvailability() : null;
35898
36467
  const pathGlobalCli = globalCli?.path ?? null;
35899
36468
  const cliPath = input2.scope === "global" ? pathGlobalCli : runningCliPath;
35900
36469
  const cliScopeOk = input2.scope === "global" ? Boolean(pathGlobalCli) : Boolean(
35901
- input2.root && runningCliPath?.includes((0, import_node_path18.join)(input2.root, ".deepline", "runtime"))
36470
+ input2.root && runningCliPath?.includes((0, import_node_path19.join)(input2.root, ".deepline", "runtime"))
35902
36471
  );
35903
36472
  const checks = {
35904
36473
  cli: {
@@ -37053,174 +37622,15 @@ chooses the connected Slack channel or member and the events it receives.
37053
37622
  });
37054
37623
  }
37055
37624
 
37056
- // src/cli/commands/switch.ts
37057
- var import_node_fs17 = require("fs");
37058
- var import_node_os14 = require("os");
37059
- var import_node_path19 = require("path");
37060
- function hostSlugFromBaseUrl(baseUrl) {
37061
- try {
37062
- const url = new URL(baseUrl);
37063
- const port = url.port ? Number.parseInt(url.port, 10) : null;
37064
- let slug = (url.hostname || "unknown").replace(/[^a-zA-Z0-9]/g, "-");
37065
- if (port && port !== 80 && port !== 443) {
37066
- slug = `${slug}-${port}`;
37067
- }
37068
- return slug.toLowerCase().replace(/^-+|-+$/g, "") || "unknown";
37069
- } catch {
37070
- return "unknown";
37071
- }
37072
- }
37073
- function resolveConfigScope() {
37074
- const explicit = (process.env.DEEPLINE_CONFIG_SCOPE || "").trim();
37075
- if (explicit) return explicit;
37076
- return hostSlugFromBaseUrl(autoDetectBaseUrl());
37077
- }
37078
- function activeFamilyPath() {
37079
- const home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os14.homedir)();
37080
- return (0, import_node_path19.join)(
37081
- home,
37082
- ".local",
37083
- "deepline",
37084
- resolveConfigScope(),
37085
- "cli",
37086
- ".active-family"
37087
- );
37088
- }
37089
- function readActiveFamily() {
37090
- const path = activeFamilyPath();
37091
- try {
37092
- return (0, import_node_fs17.readFileSync)(path, "utf-8").trim() || "sdk";
37093
- } catch {
37094
- return "sdk";
37095
- }
37096
- }
37097
- function writeActiveFamily(family) {
37098
- const path = activeFamilyPath();
37099
- (0, import_node_fs17.mkdirSync)((0, import_node_path19.dirname)(path), { recursive: true });
37100
- (0, import_node_fs17.writeFileSync)(path, `${family}
37101
- `, "utf-8");
37102
- return path;
37103
- }
37104
- function forcePythonCliFamily() {
37105
- return writeActiveFamily("python");
37106
- }
37107
- function handleSwitch(action, options) {
37108
- const normalized = (action || "status").trim().toLowerCase();
37109
- if (normalized === "status") {
37110
- const path = activeFamilyPath();
37111
- const activeFamily = readActiveFamily();
37112
- printCommandEnvelope(
37113
- {
37114
- ok: true,
37115
- active_family: activeFamily,
37116
- active_family_path: path,
37117
- active_family_file_exists: (0, import_node_fs17.existsSync)(path),
37118
- render: {
37119
- sections: [
37120
- {
37121
- title: "cli switch",
37122
- lines: [
37123
- `Active CLI family: ${activeFamily}`,
37124
- `Active family file: ${path}`
37125
- ]
37126
- }
37127
- ]
37128
- }
37129
- },
37130
- { json: options.json }
37131
- );
37132
- return 0;
37133
- }
37134
- if (normalized === "python" || normalized === "rollback") {
37135
- const path = writeActiveFamily("python");
37136
- printCommandEnvelope(
37137
- {
37138
- ok: true,
37139
- active_family: "python",
37140
- active_family_path: path,
37141
- render: {
37142
- sections: [
37143
- {
37144
- title: "cli switch",
37145
- lines: [
37146
- "Switched installer-managed `deepline` to the Python CLI."
37147
- ]
37148
- }
37149
- ]
37150
- }
37151
- },
37152
- { json: options.json }
37153
- );
37154
- return 0;
37155
- }
37156
- if (normalized === "sdk") {
37157
- const path = writeActiveFamily("sdk");
37158
- printCommandEnvelope(
37159
- {
37160
- ok: true,
37161
- active_family: "sdk",
37162
- active_family_path: path,
37163
- render: {
37164
- sections: [
37165
- {
37166
- title: "cli switch",
37167
- lines: ["Switched installer-managed `deepline` to the SDK CLI."]
37168
- }
37169
- ]
37170
- }
37171
- },
37172
- { json: options.json }
37173
- );
37174
- return 0;
37175
- }
37176
- const message = `Unknown switch target: ${action}. Use one of: status, sdk, python, rollback.`;
37177
- const envelope = {
37178
- ok: false,
37179
- error: message,
37180
- code: "usage_error",
37181
- render: {
37182
- sections: [{ title: "cli switch", lines: [message] }]
37183
- }
37184
- };
37185
- const wantsJson = options.json === true;
37186
- if (wantsJson) {
37187
- printCommandEnvelope(envelope, { json: true });
37188
- } else {
37189
- process.stderr.write(`${message}
37190
- `);
37191
- }
37192
- return 2;
37193
- }
37194
- function registerSwitchCommands(program) {
37195
- program.command("switch [target]").description(
37196
- "Switch the installer-managed Deepline CLI between SDK and Python families."
37197
- ).option("--json", "Emit JSON output").addHelpText(
37198
- "after",
37199
- `
37200
- Notes:
37201
- This command changes only the local installer-managed wrapper state. It does
37202
- not re-authenticate, reinstall packages, or contact Deepline servers.
37203
-
37204
- Examples:
37205
- deepline switch status
37206
- deepline switch python
37207
- deepline switch rollback
37208
- deepline switch sdk
37209
- `
37210
- ).action((target, options) => {
37211
- process.exitCode = handleSwitch(target, options);
37212
- });
37213
- }
37214
-
37215
37625
  // src/cli/commands/tools.ts
37216
37626
  var import_commander3 = require("commander");
37217
37627
  var import_node_fs19 = require("fs");
37218
- var import_node_os16 = require("os");
37628
+ var import_node_os14 = require("os");
37219
37629
  var import_node_path21 = require("path");
37220
37630
 
37221
37631
  // src/tool-output.ts
37222
37632
  var import_node_fs18 = require("fs");
37223
- var import_node_os15 = require("os");
37633
+ var import_node_os13 = require("os");
37224
37634
  var import_node_path20 = require("path");
37225
37635
  function isPlainObject(value) {
37226
37636
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -37348,7 +37758,7 @@ function projectRowOutput(conversion) {
37348
37758
  };
37349
37759
  }
37350
37760
  function ensureOutputDir() {
37351
- const outputDir = (0, import_node_path20.join)((0, import_node_os15.homedir)(), ".local", "share", "deepline", "data");
37761
+ const outputDir = (0, import_node_path20.join)((0, import_node_os13.homedir)(), ".local", "share", "deepline", "data");
37352
37762
  (0, import_node_fs18.mkdirSync)(outputDir, { recursive: true });
37353
37763
  return outputDir;
37354
37764
  }
@@ -37436,6 +37846,9 @@ var TOOL_CATEGORY_DESCRIPTIONS = {
37436
37846
  premium: "Higher-cost tools with premium provider coverage.",
37437
37847
  free: "Free tools that do not spend Deepline credits."
37438
37848
  };
37849
+ var WELL_KNOWN_TOOL_CATEGORIES = Object.freeze(
37850
+ Object.keys(TOOL_CATEGORY_DESCRIPTIONS)
37851
+ );
37439
37852
  function describeToolCategory(category) {
37440
37853
  return TOOL_CATEGORY_DESCRIPTIONS[category] ?? null;
37441
37854
  }
@@ -38420,17 +38833,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
38420
38833
  const extractedValues = extractionContractEntries(
38421
38834
  arrayField2(toolExecutionResult, "extractedValues", "extracted_values")
38422
38835
  );
38423
- const cost = recordField2(tool, "cost");
38424
- const deeplineCredits = numberField2(
38425
- tool,
38426
- "deeplineCreditsPerPricingUnit",
38427
- "deepline_credits_per_pricing_unit"
38428
- );
38429
- const deeplineUsdPerPricingUnit = numberField2(
38430
- tool,
38431
- "deeplineUsdPerPricingUnit",
38432
- "deepline_usd_per_pricing_unit"
38433
- );
38836
+ const pricing = toolPricingContractForDescribe(tool);
38434
38837
  const deprecation = recordField2(tool, "deprecation");
38435
38838
  const replacementToolId = stringField2(
38436
38839
  deprecation,
@@ -38472,12 +38875,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
38472
38875
  ...Object.prototype.hasOwnProperty.call(field, "default") ? { default: field.default } : {}
38473
38876
  })),
38474
38877
  inputSchema,
38475
- cost: {
38476
- pricingModel: stringField2(cost, "pricingModel", "pricing_model") || null,
38477
- billingMode: stringField2(cost, "billingMode", "billing_mode") || null,
38478
- deeplineCreditsPerPricingUnit: deeplineCredits,
38479
- deeplineUsdPerPricingUnit
38480
- },
38878
+ cost: pricing,
38481
38879
  getters: {
38482
38880
  extractedLists,
38483
38881
  extractedValues
@@ -38486,6 +38884,38 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
38486
38884
  ...starterScript ? { starterScript } : {}
38487
38885
  };
38488
38886
  }
38887
+ function toolPricingContractForDescribe(tool) {
38888
+ const legacyCost = recordField2(tool, "cost");
38889
+ const pricingValue = tool.pricing;
38890
+ const hasCanonicalPricing = isRecord12(pricingValue);
38891
+ const canonicalPricing = hasCanonicalPricing ? pricingValue : {};
38892
+ const unit = stringField2(canonicalPricing, "unit");
38893
+ const legacyPricingModel = stringField2(
38894
+ legacyCost,
38895
+ "pricingModel",
38896
+ "pricing_model"
38897
+ );
38898
+ const pricingModel = unit === "call" ? "fixed" : unit === "result" || unit === "page" ? `per_${unit}` : unit === "usage" ? "provider_usage" : legacyPricingModel;
38899
+ return {
38900
+ pricingModel: pricingModel || null,
38901
+ unit: unit || null,
38902
+ displayText: stringField2(canonicalPricing, "displayText", "display_text") || null,
38903
+ summary: stringField2(canonicalPricing, "summary") || null,
38904
+ billingMode: stringField2(legacyCost, "billingMode", "billing_mode") || null,
38905
+ billingSource: stringField2(tool, "billingSource", "billing_source") || null,
38906
+ billingSourceLabel: stringField2(tool, "billingSourceLabel", "billing_source_label") || null,
38907
+ deeplineCreditsPerPricingUnit: hasCanonicalPricing ? numberField2(canonicalPricing, "creditsPerUnit", "credits_per_unit") : numberField2(
38908
+ tool,
38909
+ "deeplineCreditsPerPricingUnit",
38910
+ "deepline_credits_per_pricing_unit"
38911
+ ),
38912
+ deeplineUsdPerPricingUnit: hasCanonicalPricing ? numberField2(canonicalPricing, "usdPerUnit", "usd_per_unit") : numberField2(
38913
+ tool,
38914
+ "deeplineUsdPerPricingUnit",
38915
+ "deepline_usd_per_pricing_unit"
38916
+ )
38917
+ };
38918
+ }
38489
38919
  function extractionContractEntries(entries) {
38490
38920
  return entries.flatMap((entry) => {
38491
38921
  if (!isRecord12(entry)) return [];
@@ -38715,13 +39145,16 @@ function printToolPricingOnly(tool, requestedToolId, options = {}) {
38715
39145
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
38716
39146
  const cost = isRecord12(contract.cost) ? contract.cost : {};
38717
39147
  const pricingModel = stringField2(cost, "pricingModel") || "unknown";
38718
- const billingMode = stringField2(cost, "billingMode") || "unknown";
38719
- const unit = pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit";
39148
+ const billing = stringField2(cost, "billingMode") || stringField2(cost, "billingSourceLabel") || stringField2(cost, "billingSource") || "unknown";
39149
+ const explicitUnit = stringField2(cost, "unit");
39150
+ const unit = explicitUnit || (pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit");
38720
39151
  const credits = numberField2(cost, "deeplineCreditsPerPricingUnit");
38721
39152
  const usd = numberField2(cost, "deeplineUsdPerPricingUnit");
38722
- const price = credits !== null ? `${formatDecimal(credits)} Deepline credits${usd !== null ? ` / ${formatUsd(usd)}` : ""} per ${unit}` : "pricing unavailable";
39153
+ const displayText = stringField2(cost, "displayText");
39154
+ const summary = stringField2(cost, "summary");
39155
+ const price = displayText || summary || (credits !== null ? `${formatDecimal(credits)} Deepline credits${usd !== null ? ` / ${formatUsd(usd)}` : ""} per ${unit}` : "pricing unavailable");
38723
39156
  console.log(`${options.heading ?? `Pricing: ${contract.toolId}`}: ${price}`);
38724
- console.log(`Billing: ${billingMode}`);
39157
+ console.log(`Billing: ${billing}`);
38725
39158
  }
38726
39159
  function printToolSchemaOnly(tool, requestedToolId) {
38727
39160
  if (isMonitorTypeTool(tool)) {
@@ -39192,9 +39625,9 @@ function apifySyncRecoveryNext(rawResponse) {
39192
39625
  const getDatasetItemsTool = stringField2(getDatasetItems, "tool");
39193
39626
  const getDatasetItemsPayload = recordField2(getDatasetItems, "payload");
39194
39627
  return {
39195
- getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote3(JSON.stringify(getActorRunPayload))} --json`,
39628
+ getActorRun: `deepline tools execute ${getActorRunTool} --input ${shellQuote4(JSON.stringify(getActorRunPayload))} --json`,
39196
39629
  ...getDatasetItemsTool && Object.keys(getDatasetItemsPayload).length > 0 ? {
39197
- getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote3(JSON.stringify(getDatasetItemsPayload))} --json`
39630
+ getDatasetItems: `deepline tools execute ${getDatasetItemsTool} --input ${shellQuote4(JSON.stringify(getDatasetItemsPayload))} --json`
39198
39631
  } : {}
39199
39632
  };
39200
39633
  }
@@ -39367,7 +39800,7 @@ function parseExecuteOptions(args) {
39367
39800
  function safeFileStem(value) {
39368
39801
  return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
39369
39802
  }
39370
- function shellQuote3(value) {
39803
+ function shellQuote4(value) {
39371
39804
  return `'${value.replace(/'/g, `'\\''`)}'`;
39372
39805
  }
39373
39806
  function powerShellQuote(value) {
@@ -39387,7 +39820,7 @@ function starterScriptJson(script) {
39387
39820
  function seedToolListScript(input2) {
39388
39821
  const stem = safeFileStem(input2.toolId);
39389
39822
  const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
39390
- const scriptDir = (0, import_node_fs19.mkdtempSync)((0, import_node_path21.join)((0, import_node_os16.tmpdir)(), "deepline-workflow-seed-"));
39823
+ const scriptDir = (0, import_node_fs19.mkdtempSync)((0, import_node_path21.join)((0, import_node_os14.tmpdir)(), "deepline-workflow-seed-"));
39391
39824
  (0, import_node_fs19.chmodSync)(scriptDir, 448);
39392
39825
  const scriptPath = (0, import_node_path21.join)(scriptDir, fileName);
39393
39826
  const projectDir = `deepline/projects/${stem}-workflow`;
@@ -39437,7 +39870,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
39437
39870
  path: scriptPath,
39438
39871
  sourceCode: script,
39439
39872
  projectDir,
39440
- macCopyCommand: `mkdir -p ${shellQuote3(projectDir)} && cp ${shellQuote3(scriptPath)} ${shellQuote3(`${projectDir}/${fileName}`)}`,
39873
+ macCopyCommand: `mkdir -p ${shellQuote4(projectDir)} && cp ${shellQuote4(scriptPath)} ${shellQuote4(`${projectDir}/${fileName}`)}`,
39441
39874
  windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
39442
39875
  };
39443
39876
  }
@@ -39464,7 +39897,7 @@ function buildToolExecuteBaseEnvelope(input2) {
39464
39897
  envelope,
39465
39898
  "output"
39466
39899
  );
39467
- const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote3(JSON.stringify(input2.params))} --json`;
39900
+ const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote4(JSON.stringify(input2.params))} --json`;
39468
39901
  const actions = input2.listConversion ? [
39469
39902
  {
39470
39903
  label: "next",
@@ -39857,9 +40290,9 @@ Examples:
39857
40290
  }
39858
40291
 
39859
40292
  // src/cli/commands/update.ts
39860
- var import_node_child_process4 = require("child_process");
40293
+ var import_node_child_process5 = require("child_process");
39861
40294
  var import_node_fs21 = require("fs");
39862
- var import_node_os17 = require("os");
40295
+ var import_node_os15 = require("os");
39863
40296
  var import_node_path23 = require("path");
39864
40297
 
39865
40298
  // src/cli/install-integrity.ts
@@ -40052,14 +40485,14 @@ function posixShellQuote(value) {
40052
40485
  function windowsCmdQuote(value) {
40053
40486
  return `"${value.replace(/"/g, '""')}"`;
40054
40487
  }
40055
- function shellQuote4(value) {
40488
+ function shellQuote5(value) {
40056
40489
  if (process.platform === "win32") {
40057
40490
  return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
40058
40491
  }
40059
40492
  return posixShellQuote(value);
40060
40493
  }
40061
40494
  function buildSourceUpdateCommand(sourceRoot) {
40062
- const quotedRoot = shellQuote4(sourceRoot);
40495
+ const quotedRoot = shellQuote5(sourceRoot);
40063
40496
  const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
40064
40497
  return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
40065
40498
  }
@@ -40071,7 +40504,7 @@ function buildSidecarProjectConfigCommand(versionDir, nodeBin) {
40071
40504
  "fs.mkdirSync(dir,{recursive:true});",
40072
40505
  `fs.writeFileSync(path.join(dir,'package.json'),${JSON.stringify(NPM_SDK_SIDECAR_PACKAGE_JSON)});`
40073
40506
  ].join("");
40074
- return `${shellQuote4(nodeBin)} -e ${shellQuote4(script)} ${shellQuote4(versionDir)}`;
40507
+ return `${shellQuote5(nodeBin)} -e ${shellQuote5(script)} ${shellQuote5(versionDir)}`;
40075
40508
  }
40076
40509
  function sidecarStateDir(input2) {
40077
40510
  const scope = input2.env.DEEPLINE_CONFIG_SCOPE?.trim();
@@ -40134,7 +40567,7 @@ function resolvePythonSidecarUpdatePlan(options) {
40134
40567
  const npmCommand = "npm";
40135
40568
  const registryUrl = sidecarRegistryUrl(hostUrl);
40136
40569
  const versionDir = (0, import_node_path23.join)(stateDir, "versions", "<version>");
40137
- const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote4(versionDir)} --registry ${shellQuote4(registryUrl)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote4).join(" ")} ${shellQuote4(packageSpec)}`;
40570
+ const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote5(versionDir)} --registry ${shellQuote5(registryUrl)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote5).join(" ")} ${shellQuote5(packageSpec)}`;
40138
40571
  return {
40139
40572
  kind: "python-sidecar",
40140
40573
  stateDir,
@@ -40194,7 +40627,7 @@ function isHomebrewFormulaEntrypoint(entrypoint) {
40194
40627
  }
40195
40628
  function resolveUpdatePlan(options = {}) {
40196
40629
  const env = options.env ?? process.env;
40197
- const homeDir2 = options.homeDir ?? (0, import_node_os17.homedir)();
40630
+ const homeDir2 = options.homeDir ?? (0, import_node_os15.homedir)();
40198
40631
  const entrypoint = options.entrypoint ?? (process.argv[1] ? (0, import_node_path23.resolve)(process.argv[1]) : "");
40199
40632
  const sourceRoot = entrypoint ? findRepoBackedSdkRoot((0, import_node_path23.dirname)(entrypoint)) : null;
40200
40633
  if (sourceRoot) {
@@ -40236,7 +40669,7 @@ function resolveUpdatePlan(options = {}) {
40236
40669
  fallbackRegistryUrl: publicNpmFallbackRegistryUrl(
40237
40670
  env.DEEPLINE_HOST_URL?.trim() || autoDetectBaseUrl()
40238
40671
  ),
40239
- manualCommand: `${command} ${args.map(shellQuote4).join(" ")}`
40672
+ manualCommand: `${command} ${args.map(shellQuote5).join(" ")}`
40240
40673
  };
40241
40674
  }
40242
40675
  var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
@@ -40246,7 +40679,7 @@ function autoUpdateFailurePath(plan) {
40246
40679
  return (0, import_node_path23.join)(plan.stateDir, AUTO_UPDATE_FAILURE_FILE);
40247
40680
  }
40248
40681
  return (0, import_node_path23.join)(
40249
- (0, import_node_os17.homedir)(),
40682
+ (0, import_node_os15.homedir)(),
40250
40683
  ".local",
40251
40684
  "deepline",
40252
40685
  "sdk-cli",
@@ -40376,7 +40809,7 @@ function runCommand(command, args, env = process.env) {
40376
40809
  return new Promise((resolveResult) => {
40377
40810
  let output2 = "";
40378
40811
  const plan = resolveShellSpawn(command, args);
40379
- const child = (0, import_node_child_process4.spawn)(plan.command, plan.args, {
40812
+ const child = (0, import_node_child_process5.spawn)(plan.command, plan.args, {
40380
40813
  stdio: ["inherit", "pipe", "pipe"],
40381
40814
  shell: plan.shell,
40382
40815
  env
@@ -40504,23 +40937,23 @@ function writeSidecarLauncher(input2) {
40504
40937
  input2.path,
40505
40938
  [
40506
40939
  "#!/usr/bin/env sh",
40507
- `export DEEPLINE_HOST_URL=${shellQuote4(input2.hostUrl)}`,
40508
- `export DEEPLINE_CONFIG_SCOPE=${shellQuote4(input2.scope)}`,
40509
- `if ${criticalPaths.map((path) => `[ ! -f ${shellQuote4(path)} ]`).join(" || ")}; then`,
40940
+ `export DEEPLINE_HOST_URL=${shellQuote5(input2.hostUrl)}`,
40941
+ `export DEEPLINE_CONFIG_SCOPE=${shellQuote5(input2.scope)}`,
40942
+ `if ${criticalPaths.map((path) => `[ ! -f ${shellQuote5(path)} ]`).join(" || ")}; then`,
40510
40943
  ' if [ -n "${DEEPLINE_REAL_BINARY:-}" ] && [ -x "$DEEPLINE_REAL_BINARY" ]; then',
40511
40944
  ' exec "$DEEPLINE_REAL_BINARY" --version=v2 "$@"',
40512
40945
  " fi",
40513
40946
  ' printf "%s\\n" "Deepline SDK CLI install is incomplete. Run \\`deepline update\\` to repair it." >&2',
40514
40947
  " exit 1",
40515
40948
  "fi",
40516
- `if ! ${shellQuote4(input2.nodeBin)} -e ${shellQuote4(esbuildProbe)} ${shellQuote4(versionDir)} >/dev/null 2>&1; then`,
40949
+ `if ! ${shellQuote5(input2.nodeBin)} -e ${shellQuote5(esbuildProbe)} ${shellQuote5(versionDir)} >/dev/null 2>&1; then`,
40517
40950
  ' if [ -n "${DEEPLINE_REAL_BINARY:-}" ] && [ -x "$DEEPLINE_REAL_BINARY" ]; then',
40518
40951
  ' exec "$DEEPLINE_REAL_BINARY" --version=v2 "$@"',
40519
40952
  " fi",
40520
40953
  ' printf "%s\\n" "Deepline SDK CLI install is incomplete. Run \\`deepline update\\` to repair it." >&2',
40521
40954
  " exit 1",
40522
40955
  "fi",
40523
- `exec ${shellQuote4(input2.nodeBin)} ${shellQuote4(input2.entryPath)} "$@"`,
40956
+ `exec ${shellQuote5(input2.nodeBin)} ${shellQuote5(input2.entryPath)} "$@"`,
40524
40957
  ""
40525
40958
  ].join("\n"),
40526
40959
  { encoding: "utf8", mode: 493 }
@@ -40773,7 +41206,17 @@ async function runUpdateCommand(options, dependencies = {}) {
40773
41206
  if (updateExitCode !== 0) {
40774
41207
  return updateExitCode;
40775
41208
  }
40776
- await syncSkills(normalizeBaseUrl3(detectBaseUrl()));
41209
+ try {
41210
+ await syncSkills(normalizeBaseUrl3(detectBaseUrl()));
41211
+ } catch (error) {
41212
+ const detail = error instanceof Error ? error.message : String(error);
41213
+ stderr.write(
41214
+ `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.
41215
+ Skills refresh detail: ${detail}
41216
+ To retry with full installer output, run: deepline skills --json
41217
+ `
41218
+ );
41219
+ }
40777
41220
  return 0;
40778
41221
  }
40779
41222
  function registerUpdateCommand(program) {
@@ -41324,108 +41767,15 @@ function registerDeeplineCommandGroups(program) {
41324
41767
  registerCsvCommands(program);
41325
41768
  registerDbCommands(program);
41326
41769
  registerFeedbackCommands(program);
41327
- registerLegacyNoopCommands(program);
41770
+ registerDeprecatedCommands(program);
41328
41771
  registerUpdateCommand(program);
41329
41772
  registerSkillsCommand(program);
41330
41773
  registerSetupCommands(program);
41331
41774
  registerQuickstartCommands(program);
41332
- registerSwitchCommands(program);
41333
- }
41334
-
41335
- // ../shared_libs/cli/command-compatibility.json
41336
- var command_compatibility_default = {
41337
- enrich: {
41338
- family: "python",
41339
- label: "a legacy Python CLI enrichment command",
41340
- sdk_alternative: "Use `deepline plays ...` for durable workflows or `deepline tools execute ...` for one tool call."
41341
- },
41342
- session: {
41343
- family: "python",
41344
- label: "a legacy Python CLI session/playground command",
41345
- sdk_alternative: "Use `deepline sessions send ...` or `deepline sessions render ...` for transcript workflows."
41346
- },
41347
- workflows: {
41348
- family: "python",
41349
- label: "a legacy Python CLI workflow command",
41350
- sdk_alternative: "Use `deepline plays ...` in the SDK CLI."
41351
- },
41352
- events: {
41353
- family: "python",
41354
- label: "a legacy Python CLI event command"
41355
- },
41356
- plays: {
41357
- family: "sdk",
41358
- label: "an SDK CLI play command",
41359
- python_alternative: "Use `deepline workflows ...` only for legacy workflows."
41360
- },
41361
- runs: {
41362
- family: "sdk",
41363
- label: "an SDK CLI run inspection command"
41364
- },
41365
- sessions: {
41366
- family: "sdk",
41367
- label: "an SDK CLI session transcript command"
41368
- },
41369
- health: {
41370
- family: "sdk",
41371
- label: "an SDK CLI health command"
41372
- }
41373
- };
41374
-
41375
- // src/cli/command-compatibility.ts
41376
- var COMMAND_COMPATIBILITY = command_compatibility_default;
41377
- function cliFamilyLabel(family) {
41378
- return family === "sdk" ? "SDK CLI" : "legacy Python CLI";
41379
- }
41380
- function commandCompatibilityHint(currentFamily, commandName, baseUrl) {
41381
- const compatibility = COMMAND_COMPATIBILITY[commandName];
41382
- if (!compatibility || compatibility.family === currentFamily) {
41383
- return null;
41384
- }
41385
- const expectedFamily = compatibility.family;
41386
- const currentLabel = cliFamilyLabel(currentFamily);
41387
- const expectedLabel = cliFamilyLabel(expectedFamily);
41388
- const lines = [
41389
- "",
41390
- "Command compatibility:",
41391
- ` \`deepline ${commandName}\` is ${compatibility.label}.`,
41392
- ` Current binary: ${currentLabel}. Required binary: ${expectedLabel}.`,
41393
- " If this came from an agent skill, the installed skill likely targets the other Deepline CLI."
41394
- ];
41395
- if (currentFamily === "sdk") {
41396
- lines.push(
41397
- "",
41398
- " To stay on the SDK CLI, refresh the Deepline agent skills:",
41399
- ` ${skillsInstallCommand(baseUrl, DEFAULT_SDK_SKILL_NAMES)}`,
41400
- " To use the legacy Python CLI instead:",
41401
- ` ${legacyPythonInstallCommand(baseUrl)}`,
41402
- " `deepline update` updates this SDK CLI, but it will not switch CLI families."
41403
- );
41404
- if (compatibility.sdk_alternative) {
41405
- lines.push(` SDK alternative: ${compatibility.sdk_alternative}`);
41406
- }
41407
- } else {
41408
- lines.push(
41409
- "",
41410
- " To use SDK commands, install the SDK CLI and refresh Deepline agent skills:",
41411
- ` ${sdkNpmGlobalInstallCommand()}`,
41412
- ` ${skillsInstallCommand(baseUrl, DEFAULT_SDK_SKILL_NAMES)}`,
41413
- " `deepline update` updates this Python CLI and its skills, but it will not switch CLI families."
41414
- );
41415
- if (compatibility.python_alternative) {
41416
- lines.push(` Python alternative: ${compatibility.python_alternative}`);
41417
- }
41418
- }
41419
- return lines.join("\n");
41420
- }
41421
- function unknownCommandNameFromMessage(message) {
41422
- const match = message.match(/unknown command ['"]([^'"]+)['"]/i);
41423
- const command = match?.[1]?.trim();
41424
- return command ? command : null;
41425
41775
  }
41426
41776
 
41427
41777
  // src/cli/self-update.ts
41428
- var import_node_child_process5 = require("child_process");
41778
+ var import_node_child_process6 = require("child_process");
41429
41779
  function envTruthy(name) {
41430
41780
  const value = process.env[name]?.trim().toLowerCase();
41431
41781
  return value === "1" || value === "true" || value === "yes";
@@ -41472,7 +41822,7 @@ function relaunchCurrentCommand(plan) {
41472
41822
  return new Promise((resolve19) => {
41473
41823
  const command = plan.kind === "python-sidecar" ? plan.sidecarPath : process.execPath;
41474
41824
  const args = plan.kind === "python-sidecar" ? process.argv.slice(2) : process.argv.slice(1);
41475
- const child = (0, import_node_child_process5.spawn)(command, args, {
41825
+ const child = (0, import_node_child_process6.spawn)(command, args, {
41476
41826
  stdio: "inherit",
41477
41827
  shell: process.platform === "win32",
41478
41828
  env: {
@@ -41541,353 +41891,8 @@ What changed in ${response.update_summary.version}: ${response.update_summary.su
41541
41891
  return true;
41542
41892
  }
41543
41893
 
41544
- // src/cli/skills-sync.ts
41545
- var import_node_child_process6 = require("child_process");
41546
- var import_node_fs22 = require("fs");
41547
- var import_node_path25 = require("path");
41548
- var CHECK_TIMEOUT_MS2 = 3e3;
41549
- function shouldSkipSkillsSync() {
41550
- if (detectAgentRuntime() === "claude_cowork") {
41551
- return true;
41552
- }
41553
- const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
41554
- return value === "1" || value === "true" || value === "yes" || value === "on";
41555
- }
41556
- function activePluginSkillsDir() {
41557
- const pluginMode = process.env.DEEPLINE_PLUGIN_MODE?.trim().toLowerCase();
41558
- if (pluginMode !== "true" && pluginMode !== "1" && pluginMode !== "yes" && pluginMode !== "on") {
41559
- return "";
41560
- }
41561
- const dir = process.env.DEEPLINE_PLUGIN_SKILLS_DIR?.trim() ?? "";
41562
- return dir && (0, import_node_fs22.existsSync)(dir) ? dir : "";
41563
- }
41564
- function readPluginSkillsVersion() {
41565
- const dir = activePluginSkillsDir();
41566
- if (!dir) return "";
41567
- try {
41568
- return (0, import_node_fs22.readFileSync)((0, import_node_path25.join)(dir, ".version"), "utf-8").trim();
41569
- } catch {
41570
- return "";
41571
- }
41572
- }
41573
- function sdkSkillsVersionPath(baseUrl) {
41574
- return (0, import_node_path25.join)(sdkCliStateDirPath(baseUrl), "skills-version");
41575
- }
41576
- function legacySdkSkillsVersionPath(baseUrl) {
41577
- return (0, import_node_path25.join)((0, import_node_path25.dirname)(sdkCliStateDirPath(baseUrl)), "sdk-skills", ".version");
41578
- }
41579
- function unavailableSkillsNoticePath(baseUrl) {
41580
- return (0, import_node_path25.join)(sdkCliStateDirPath(baseUrl), "skills-sync-unavailable-version");
41581
- }
41582
- function readSdkSkillsLocalVersion(baseUrl) {
41583
- const pluginVersion = readPluginSkillsVersion();
41584
- if (pluginVersion) return pluginVersion;
41585
- const path = (0, import_node_fs22.existsSync)(sdkSkillsVersionPath(baseUrl)) ? sdkSkillsVersionPath(baseUrl) : legacySdkSkillsVersionPath(baseUrl);
41586
- if (!(0, import_node_fs22.existsSync)(path)) return "";
41587
- try {
41588
- return (0, import_node_fs22.readFileSync)(path, "utf-8").trim();
41589
- } catch {
41590
- return "";
41591
- }
41592
- }
41593
- function writeLocalSkillsVersion(baseUrl, version) {
41594
- const path = sdkSkillsVersionPath(baseUrl);
41595
- (0, import_node_fs22.mkdirSync)((0, import_node_path25.dirname)(path), { recursive: true });
41596
- (0, import_node_fs22.writeFileSync)(path, `${version}
41597
- `, "utf-8");
41598
- }
41599
- function writeUnavailableSkillsNotice(baseUrl, remoteVersion, skillNames) {
41600
- const path = unavailableSkillsNoticePath(baseUrl);
41601
- try {
41602
- if ((0, import_node_fs22.existsSync)(path) && (0, import_node_fs22.readFileSync)(path, "utf-8").trim() === remoteVersion) {
41603
- return;
41604
- }
41605
- (0, import_node_fs22.mkdirSync)((0, import_node_path25.dirname)(path), { recursive: true });
41606
- (0, import_node_fs22.writeFileSync)(path, `${remoteVersion}
41607
- `, "utf-8");
41608
- } catch {
41609
- }
41610
- const manualCommand = `npx ${buildSkillsInstallArgs(baseUrl, skillNames).join(" ")}`;
41611
- writeSdkSkillsStatusLine(
41612
- `Deepline agent skills are out of date, but neither \`bunx\` nor \`npx\` is available. Install Node.js/npm or Bun, then run:
41613
- ${manualCommand}`
41614
- );
41615
- }
41616
- function clearUnavailableSkillsNotice(baseUrl) {
41617
- try {
41618
- (0, import_node_fs22.unlinkSync)(unavailableSkillsNoticePath(baseUrl));
41619
- } catch {
41620
- }
41621
- }
41622
- function sortedUniqueSkillNames(names) {
41623
- return [...new Set(names.map((name) => name.trim()).filter(Boolean))].sort(
41624
- (a, b) => a.localeCompare(b)
41625
- );
41626
- }
41627
- async function fetchV1SkillNames(baseUrl) {
41628
- const controller = new AbortController();
41629
- const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
41630
- try {
41631
- const response = await fetch(
41632
- new URL("/.well-known/skills/index.json", baseUrl),
41633
- { signal: controller.signal }
41634
- );
41635
- if (!response.ok) return [];
41636
- const data = await response.json().catch(() => null);
41637
- const names = (data?.skills ?? []).filter((skill) => skill.install_surface === "v1").map((skill) => skill.name).filter(
41638
- (name) => typeof name === "string" && name.length > 0
41639
- );
41640
- return sortedUniqueSkillNames(names);
41641
- } catch {
41642
- return [];
41643
- } finally {
41644
- clearTimeout(timeout);
41645
- }
41646
- }
41647
- function buildSdkSkillNames(v1SkillNames) {
41648
- return sortedUniqueSkillNames(v1SkillNames);
41649
- }
41650
- async function fetchSkillsUpdate(baseUrl, localVersion) {
41651
- const controller = new AbortController();
41652
- const timeout = setTimeout(() => controller.abort(), CHECK_TIMEOUT_MS2);
41653
- try {
41654
- const response = await fetch(new URL("/api/v2/cli/update-check", baseUrl), {
41655
- method: "POST",
41656
- headers: { "Content-Type": "application/json" },
41657
- body: JSON.stringify({
41658
- skills: {
41659
- version: localVersion
41660
- }
41661
- }),
41662
- signal: controller.signal
41663
- });
41664
- if (!response.ok) return null;
41665
- const data = await response.json().catch(() => null);
41666
- const skills = data?.skills;
41667
- if (!skills) return null;
41668
- return {
41669
- needsUpdate: skills.needs_update === true,
41670
- remoteVersion: typeof skills.remote?.version === "string" ? skills.remote.version.trim() : ""
41671
- };
41672
- } catch {
41673
- return null;
41674
- } finally {
41675
- clearTimeout(timeout);
41676
- }
41677
- }
41678
- function buildSkillsInstallArgs(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES, agents) {
41679
- return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
41680
- agents
41681
- });
41682
- }
41683
- function buildBunxSkillsInstallArgs(baseUrl, skillNames, agents) {
41684
- return buildSkillsAddArgs(baseUrl, sortedUniqueSkillNames(skillNames), {
41685
- firstArg: "--bun",
41686
- agents
41687
- });
41688
- }
41689
- function resolveAutoSyncSkillAgents() {
41690
- switch (detectAgentRuntime()) {
41691
- case "codex":
41692
- return ["codex"];
41693
- case "claude_code":
41694
- return ["claude-code"];
41695
- case "cursor":
41696
- return ["cursor"];
41697
- case "gemini":
41698
- return ["gemini-cli"];
41699
- case "antigravity":
41700
- return ["antigravity"];
41701
- default:
41702
- return [];
41703
- }
41704
- }
41705
- function hasCommand(command) {
41706
- const plan = resolveShellSpawn(command, ["--version"]);
41707
- const result = (0, import_node_child_process6.spawnSync)(plan.command, plan.args, {
41708
- stdio: "ignore",
41709
- shell: plan.shell
41710
- });
41711
- return result.status === 0;
41712
- }
41713
- function shellQuote5(arg) {
41714
- return `'${arg.replace(/'/g, `'\\''`)}'`;
41715
- }
41716
- function resolveSkillsInstallSpawn(install, platform3 = process.platform) {
41717
- return resolveShellSpawn(install.command, install.args, platform3);
41718
- }
41719
- function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES, agents = DEFAULT_SKILL_AGENTS) {
41720
- const commands = [];
41721
- if (hasCommand("bunx")) {
41722
- const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames, agents);
41723
- commands.push({
41724
- command: "bunx",
41725
- args: bunxArgs,
41726
- manualCommand: `bunx ${bunxArgs.map(shellQuote5).join(" ")}`
41727
- });
41728
- }
41729
- if (hasCommand("npx")) {
41730
- const npxArgs = buildSkillsInstallArgs(baseUrl, skillNames, agents);
41731
- commands.push({
41732
- command: "npx",
41733
- args: npxArgs,
41734
- manualCommand: `npx ${npxArgs.map(shellQuote5).join(" ")}`
41735
- });
41736
- }
41737
- return commands;
41738
- }
41739
- function runOneSkillsInstall(install) {
41740
- return new Promise((resolve19) => {
41741
- const plan = resolveSkillsInstallSpawn(install);
41742
- const child = (0, import_node_child_process6.spawn)(plan.command, plan.args, {
41743
- stdio: ["ignore", "ignore", "pipe"],
41744
- env: process.env,
41745
- shell: plan.shell
41746
- });
41747
- let stderr = "";
41748
- child.stderr.on("data", (chunk) => {
41749
- stderr += chunk.toString("utf-8");
41750
- });
41751
- child.on("error", (error) => {
41752
- resolve19({
41753
- ok: false,
41754
- detail: `failed to start ${install.command}: ${error.message}`,
41755
- manualCommand: install.manualCommand
41756
- });
41757
- });
41758
- child.on("close", (code) => {
41759
- if (code === 0) {
41760
- resolve19({ ok: true, detail: "", manualCommand: install.manualCommand });
41761
- return;
41762
- }
41763
- const detail = stderr.trim();
41764
- resolve19({
41765
- ok: false,
41766
- detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
41767
- manualCommand: install.manualCommand
41768
- });
41769
- });
41770
- });
41771
- }
41772
- async function runSkillsInstall(installs) {
41773
- const failures = [];
41774
- for (const install of installs) {
41775
- const result = await runOneSkillsInstall(install);
41776
- if (result.ok) return true;
41777
- failures.push(result);
41778
- }
41779
- const details = failures.map((failure) => failure.detail).filter(Boolean).join("\n");
41780
- const manualCommand = failures.at(-1)?.manualCommand;
41781
- process.stderr.write(
41782
- `SDK skills sync failed${details ? `:
41783
- ${details}` : ""}
41784
- ` + (manualCommand ? `Run manually: ${manualCommand}
41785
- ` : "")
41786
- );
41787
- return false;
41788
- }
41789
- function runLegacySkillsCleanup(agents) {
41790
- const candidates = hasCommand("bunx") ? [
41791
- {
41792
- command: "bunx",
41793
- args: [
41794
- "--bun",
41795
- "skills",
41796
- "remove",
41797
- "--global",
41798
- "--agent",
41799
- ...agents,
41800
- "-y",
41801
- ...LEGACY_SKILL_NAMES_TO_REMOVE
41802
- ]
41803
- },
41804
- {
41805
- command: "npx",
41806
- args: [
41807
- "--yes",
41808
- "skills",
41809
- "remove",
41810
- "--global",
41811
- "--agent",
41812
- ...agents,
41813
- "-y",
41814
- ...LEGACY_SKILL_NAMES_TO_REMOVE
41815
- ]
41816
- }
41817
- ] : [
41818
- {
41819
- command: "npx",
41820
- args: [
41821
- "--yes",
41822
- "skills",
41823
- "remove",
41824
- "--global",
41825
- "--agent",
41826
- ...agents,
41827
- "-y",
41828
- ...LEGACY_SKILL_NAMES_TO_REMOVE
41829
- ]
41830
- }
41831
- ];
41832
- for (const candidate of candidates) {
41833
- const plan = resolveShellSpawn(candidate.command, candidate.args);
41834
- const result = (0, import_node_child_process6.spawnSync)(plan.command, plan.args, {
41835
- stdio: "ignore",
41836
- env: process.env,
41837
- shell: plan.shell
41838
- });
41839
- if (result.status === 0) return;
41840
- }
41841
- }
41842
- function writeSdkSkillsStatusLine(line) {
41843
- const progress = getActiveCliProgress();
41844
- if (progress) {
41845
- progress.writeLine(line);
41846
- return;
41847
- }
41848
- process.stderr.write(`${line}
41849
- `);
41850
- }
41851
- async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
41852
- if (shouldSkipSkillsSync()) return;
41853
- const usingPluginSkills = Boolean(activePluginSkillsDir());
41854
- if (usingPluginSkills) {
41855
- return;
41856
- }
41857
- const localVersion = readSdkSkillsLocalVersion(baseUrl);
41858
- const update = options.update === void 0 ? await fetchSkillsUpdate(baseUrl, localVersion) : options.update ? {
41859
- needsUpdate: options.update.needs_update,
41860
- remoteVersion: options.update.remote.version
41861
- } : null;
41862
- if (!update?.needsUpdate || !update.remoteVersion) {
41863
- return;
41864
- }
41865
- const remoteSkillNames = await fetchV1SkillNames(baseUrl);
41866
- const skillNames = buildSdkSkillNames(
41867
- remoteSkillNames.length > 0 ? remoteSkillNames : DEFAULT_SDK_SKILL_NAMES
41868
- );
41869
- if (skillNames.length === 0) return;
41870
- const agents = resolveAutoSyncSkillAgents();
41871
- if (agents.length === 0) {
41872
- writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
41873
- return;
41874
- }
41875
- const installs = resolveSkillsInstallCommands(baseUrl, skillNames, agents);
41876
- if (installs.length === 0) {
41877
- writeUnavailableSkillsNotice(baseUrl, update.remoteVersion, skillNames);
41878
- return;
41879
- }
41880
- writeSdkSkillsStatusLine("Deepline skills changed; syncing agent skills...");
41881
- const installed = await runSkillsInstall(installs);
41882
- if (!installed) return;
41883
- runLegacySkillsCleanup(agents);
41884
- writeLocalSkillsVersion(baseUrl, update.remoteVersion);
41885
- clearUnavailableSkillsNotice(baseUrl);
41886
- writeSdkSkillsStatusLine("Deepline agent skills are up to date.");
41887
- }
41888
-
41889
41894
  // src/cli/failure-reporting.ts
41890
- var import_node_os18 = require("os");
41895
+ var import_node_os16 = require("os");
41891
41896
  var FAILURE_REPORT_DISABLE_ENV = "DEEPLINE_DISABLE_FAILURE_REPORTING";
41892
41897
  var REPORT_FAILURE_TIMEOUT_MS = 1e4;
41893
41898
  var MAX_FAILURE_TEXT_CHARS = 4e3;
@@ -41989,12 +41994,12 @@ function isNetworkFailure(error) {
41989
41994
  }
41990
41995
  function buildEnvironmentContext() {
41991
41996
  const context = {
41992
- os: (0, import_node_os18.platform)(),
41993
- os_release: (0, import_node_os18.release)(),
41994
- platform: `${(0, import_node_os18.platform)()}-${(0, import_node_os18.release)()}-${process.arch}`,
41997
+ os: (0, import_node_os16.platform)(),
41998
+ os_release: (0, import_node_os16.release)(),
41999
+ platform: `${(0, import_node_os16.platform)()}-${(0, import_node_os16.release)()}-${process.arch}`,
41995
42000
  node_version: process.version,
41996
42001
  runtime: "Node.js",
41997
- hostname: (0, import_node_os18.hostname)(),
42002
+ hostname: (0, import_node_os16.hostname)(),
41998
42003
  agent_runtime: detectAgentRuntime()
41999
42004
  };
42000
42005
  for (const key of ["CLAUDE_CODE_REMOTE", "DEEPLINE_PLUGIN_MODE"]) {
@@ -42164,7 +42169,7 @@ function shouldDeferSkillsSyncForCommand() {
42164
42169
  if (command === "providers" && subcommand === "list") return true;
42165
42170
  return (command === "play" || command === "plays") && subcommand === "run" && args.includes("--json");
42166
42171
  }
42167
- function isLegacyNoopInvocation() {
42172
+ function isDeprecatedCommandInvocation() {
42168
42173
  const command = process.argv.slice(2)[0];
42169
42174
  return command === "session" || command === "backend";
42170
42175
  }
@@ -42188,8 +42193,8 @@ function topLevelCommandKnown(program, commandName) {
42188
42193
  );
42189
42194
  }
42190
42195
  async function runPlayRunnerHealthCheck() {
42191
- const dir = await (0, import_promises10.mkdtemp)((0, import_node_path26.join)((0, import_node_os19.tmpdir)(), "deepline-health-play-"));
42192
- const file = (0, import_node_path26.join)(dir, "health-check.play.ts");
42196
+ const dir = await (0, import_promises10.mkdtemp)((0, import_node_path25.join)((0, import_node_os17.tmpdir)(), "deepline-health-play-"));
42197
+ const file = (0, import_node_path25.join)(dir, "health-check.play.ts");
42193
42198
  try {
42194
42199
  await (0, import_promises10.writeFile)(
42195
42200
  file,
@@ -42431,7 +42436,7 @@ Exit codes:
42431
42436
  `
42432
42437
  );
42433
42438
  program.hook("preAction", async (_thisCommand, actionCommand) => {
42434
- if (actionCommand.name() === "version" || actionCommand.name() === "update" || actionCommand.name() === "switch" || actionCommand.name() === "setup" || actionCommand.name() === "skills" || actionCommand.name() === "doctor" || isLegacyNoopInvocation()) {
42439
+ if (actionCommand.name() === "version" || actionCommand.name() === "update" || actionCommand.name() === "setup" || actionCommand.name() === "skills" || actionCommand.name() === "doctor" || isDeprecatedCommandInvocation()) {
42435
42440
  return;
42436
42441
  }
42437
42442
  if (printStartupPhase) {
@@ -42460,18 +42465,6 @@ Exit codes:
42460
42465
  if (relaunched) {
42461
42466
  return;
42462
42467
  }
42463
- if (compatibility.response?.cli_family?.action === "force_python") {
42464
- forcePythonCliFamily();
42465
- process.stderr.write(
42466
- "Deepline SDK CLI rollback is active; switched installer-managed `deepline` back to the Python CLI. Re-run your command.\n"
42467
- );
42468
- const error = new Error(
42469
- "SDK CLI rollback is active"
42470
- );
42471
- error.code = "deepline.sdk_cli_rollback";
42472
- error.exitCode = 7;
42473
- throw error;
42474
- }
42475
42468
  enforceSdkCompatibilityResponse(compatibility.response);
42476
42469
  if (printStartupPhase) {
42477
42470
  progress?.phase("checking sdk skills");
@@ -42599,14 +42592,6 @@ Examples:
42599
42592
  process.exitCode = 2;
42600
42593
  return;
42601
42594
  }
42602
- const hint = commandCompatibilityHint(
42603
- "sdk",
42604
- requestedTopLevelCommand,
42605
- baseUrl
42606
- );
42607
- if (hint && !process.argv.includes("--json")) {
42608
- console.error(hint);
42609
- }
42610
42595
  process.exitCode = 2;
42611
42596
  return;
42612
42597
  }
@@ -42634,19 +42619,6 @@ Examples:
42634
42619
  const wantsJson = process.argv.includes("--json");
42635
42620
  if (commanderError) {
42636
42621
  if (commanderError.code === "commander.unknownCommand") {
42637
- const commandName = unknownCommandNameFromMessage(
42638
- commanderError.message
42639
- );
42640
- if (commandName && !wantsJson) {
42641
- const hint = commandCompatibilityHint(
42642
- "sdk",
42643
- commandName,
42644
- autoDetectBaseUrl()
42645
- );
42646
- if (hint) {
42647
- console.error(hint);
42648
- }
42649
- }
42650
42622
  }
42651
42623
  process.exitCode = commanderError.code === "commander.unknownCommand" && !wantsJson ? 2 : commanderError.exitCode ?? 1;
42652
42624
  return;