qwenproxy-cli 1.4.0 → 1.4.2

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/index.js CHANGED
@@ -151,6 +151,8 @@ var init_paths = __esm({
151
151
  });
152
152
 
153
153
  // src/core/config.ts
154
+ import fs2 from "node:fs";
155
+ import dotenv from "dotenv";
154
156
  import { z } from "zod";
155
157
  function isStatelessChatMode(mode) {
156
158
  if (!mode) return false;
@@ -200,6 +202,15 @@ var envSchema, env, config;
200
202
  var init_config = __esm({
201
203
  "src/core/config.ts"() {
202
204
  "use strict";
205
+ init_paths();
206
+ if (!isRunningUnderNodeTest()) {
207
+ const envPath2 = getEnvFilePath();
208
+ if (fs2.existsSync(envPath2)) {
209
+ dotenv.config({ path: envPath2, quiet: true });
210
+ } else {
211
+ dotenv.config({ quiet: true });
212
+ }
213
+ }
203
214
  envSchema = z.object({
204
215
  PORT: z.string().regex(/^\d+$/, "PORT must be a number").refine((value) => {
205
216
  const port = Number(value);
@@ -566,7 +577,7 @@ var init_config = __esm({
566
577
  });
567
578
 
568
579
  // src/tui/settings.ts
569
- import fs2 from "node:fs";
580
+ import fs3 from "node:fs";
570
581
  import path2 from "node:path";
571
582
  function loadTuiSettings() {
572
583
  if (cachedSettings) {
@@ -578,8 +589,8 @@ function loadTuiSettings() {
578
589
  }
579
590
  const filePath = getTuiSettingsPath();
580
591
  try {
581
- if (fs2.existsSync(filePath)) {
582
- const raw = fs2.readFileSync(filePath, "utf-8");
592
+ if (fs3.existsSync(filePath)) {
593
+ const raw = fs3.readFileSync(filePath, "utf-8");
583
594
  const parsed = JSON.parse(raw);
584
595
  const loaded = {
585
596
  ...defaultSettings,
@@ -620,10 +631,10 @@ function saveTuiSettings(updates) {
620
631
  cachedSettings = merged;
621
632
  const filePath = getTuiSettingsPath();
622
633
  const dir = path2.dirname(filePath);
623
- if (!fs2.existsSync(dir)) {
624
- fs2.mkdirSync(dir, { recursive: true });
634
+ if (!fs3.existsSync(dir)) {
635
+ fs3.mkdirSync(dir, { recursive: true });
625
636
  }
626
- fs2.writeFileSync(filePath, JSON.stringify(merged, null, 2), "utf-8");
637
+ fs3.writeFileSync(filePath, JSON.stringify(merged, null, 2), "utf-8");
627
638
  } catch {
628
639
  }
629
640
  }
@@ -1379,7 +1390,7 @@ var init_memory_cache = __esm({
1379
1390
 
1380
1391
  // src/core/crypto-utils.ts
1381
1392
  import crypto2 from "crypto";
1382
- import fs3 from "fs";
1393
+ import fs4 from "fs";
1383
1394
  function getOrCreateKey() {
1384
1395
  if (cachedKey) return cachedKey;
1385
1396
  const envKey = process.env.ENCRYPTION_KEY;
@@ -1387,15 +1398,15 @@ function getOrCreateKey() {
1387
1398
  cachedKey = crypto2.scryptSync(envKey, "qwenproxy-salt", KEY_LENGTH);
1388
1399
  return cachedKey;
1389
1400
  }
1390
- if (fs3.existsSync(KEY_PATH)) {
1391
- cachedKey = Buffer.from(fs3.readFileSync(KEY_PATH, "utf-8"), "hex");
1401
+ if (fs4.existsSync(KEY_PATH)) {
1402
+ cachedKey = Buffer.from(fs4.readFileSync(KEY_PATH, "utf-8"), "hex");
1392
1403
  return cachedKey;
1393
1404
  }
1394
- if (!fs3.existsSync(DATA_DIR)) {
1395
- fs3.mkdirSync(DATA_DIR, { recursive: true, mode: 493 });
1405
+ if (!fs4.existsSync(DATA_DIR)) {
1406
+ fs4.mkdirSync(DATA_DIR, { recursive: true, mode: 493 });
1396
1407
  }
1397
1408
  const key = crypto2.randomBytes(KEY_LENGTH);
1398
- fs3.writeFileSync(KEY_PATH, key.toString("hex"), { mode: 384 });
1409
+ fs4.writeFileSync(KEY_PATH, key.toString("hex"), { mode: 384 });
1399
1410
  cachedKey = key;
1400
1411
  return cachedKey;
1401
1412
  }
@@ -1459,21 +1470,21 @@ __export(database_exports, {
1459
1470
  });
1460
1471
  import Database from "better-sqlite3";
1461
1472
  import path3 from "path";
1462
- import fs4 from "fs";
1473
+ import fs5 from "fs";
1463
1474
  function getDatabase() {
1464
1475
  if (db) return db;
1465
1476
  try {
1466
- if (!fs4.existsSync(DB_DIR)) {
1467
- fs4.mkdirSync(DB_DIR, { recursive: true, mode: 493 });
1477
+ if (!fs5.existsSync(DB_DIR)) {
1478
+ fs5.mkdirSync(DB_DIR, { recursive: true, mode: 493 });
1468
1479
  }
1469
1480
  const migrateLegacyDatabase = (legacyPath, legacyWalPath, legacyShmPath) => {
1470
- if (fs4.existsSync(legacyPath) && !fs4.existsSync(DB_PATH)) {
1471
- fs4.renameSync(legacyPath, DB_PATH);
1472
- if (fs4.existsSync(legacyWalPath) && !fs4.existsSync(DB_WAL_PATH)) {
1473
- fs4.renameSync(legacyWalPath, DB_WAL_PATH);
1481
+ if (fs5.existsSync(legacyPath) && !fs5.existsSync(DB_PATH)) {
1482
+ fs5.renameSync(legacyPath, DB_PATH);
1483
+ if (fs5.existsSync(legacyWalPath) && !fs5.existsSync(DB_WAL_PATH)) {
1484
+ fs5.renameSync(legacyWalPath, DB_WAL_PATH);
1474
1485
  }
1475
- if (fs4.existsSync(legacyShmPath) && !fs4.existsSync(DB_SHM_PATH)) {
1476
- fs4.renameSync(legacyShmPath, DB_SHM_PATH);
1486
+ if (fs5.existsSync(legacyShmPath) && !fs5.existsSync(DB_SHM_PATH)) {
1487
+ fs5.renameSync(legacyShmPath, DB_SHM_PATH);
1477
1488
  }
1478
1489
  console.log(`\u{1F4E6} [Database] Migrated legacy database to ${DB_PATH}`);
1479
1490
  }
@@ -1488,12 +1499,12 @@ function getDatabase() {
1488
1499
  LEGACY_DB_IN_DIR_WAL_PATH,
1489
1500
  LEGACY_DB_IN_DIR_SHM_PATH
1490
1501
  );
1491
- if (fs4.existsSync(LEGACY_JSON_BAK_PATH) && !fs4.existsSync(DB_JSON_BAK_PATH)) {
1492
- fs4.renameSync(LEGACY_JSON_BAK_PATH, DB_JSON_BAK_PATH);
1502
+ if (fs5.existsSync(LEGACY_JSON_BAK_PATH) && !fs5.existsSync(DB_JSON_BAK_PATH)) {
1503
+ fs5.renameSync(LEGACY_JSON_BAK_PATH, DB_JSON_BAK_PATH);
1493
1504
  }
1494
1505
  const testFile = path3.join(DB_DIR, ".write-test");
1495
- fs4.writeFileSync(testFile, "");
1496
- fs4.unlinkSync(testFile);
1506
+ fs5.writeFileSync(testFile, "");
1507
+ fs5.unlinkSync(testFile);
1497
1508
  } catch (err) {
1498
1509
  console.error(
1499
1510
  `\u274C [Database] Cannot access database directory '${DB_DIR}':`,
@@ -1633,12 +1644,12 @@ function encryptPlaintextPasswords(db2) {
1633
1644
  }
1634
1645
  function migrateFromJson(db2) {
1635
1646
  const jsonPath = LEGACY_JSON_PATH;
1636
- if (!fs4.existsSync(jsonPath)) return;
1647
+ if (!fs5.existsSync(jsonPath)) return;
1637
1648
  try {
1638
- const raw = fs4.readFileSync(jsonPath, "utf-8");
1649
+ const raw = fs5.readFileSync(jsonPath, "utf-8");
1639
1650
  const accounts = JSON.parse(raw);
1640
1651
  if (!Array.isArray(accounts) || accounts.length === 0) {
1641
- fs4.renameSync(jsonPath, DB_JSON_BAK_PATH);
1652
+ fs5.renameSync(jsonPath, DB_JSON_BAK_PATH);
1642
1653
  return;
1643
1654
  }
1644
1655
  const insert = db2.prepare(`
@@ -1652,7 +1663,7 @@ function migrateFromJson(db2) {
1652
1663
  }
1653
1664
  });
1654
1665
  migrate();
1655
- fs4.renameSync(jsonPath, DB_JSON_BAK_PATH);
1666
+ fs5.renameSync(jsonPath, DB_JSON_BAK_PATH);
1656
1667
  console.log(
1657
1668
  `[Database] Migrated ${accounts.length} account(s) from accounts.json to SQLite`
1658
1669
  );
@@ -1766,7 +1777,7 @@ var init_database = __esm({
1766
1777
 
1767
1778
  // src/core/local-auth.ts
1768
1779
  import crypto3 from "node:crypto";
1769
- import fs5 from "node:fs";
1780
+ import fs6 from "node:fs";
1770
1781
  function isPlaceholderApiKey(key) {
1771
1782
  const value = (key || "").trim();
1772
1783
  return value.length === 0 || value === PLACEHOLDER_API_KEY;
@@ -1793,7 +1804,7 @@ function assertBindAllowed(host, apiKey) {
1793
1804
  }
1794
1805
  function updateEnvVariable(key, value, envPath2 = getEnvFilePath()) {
1795
1806
  try {
1796
- const existing = fs5.existsSync(envPath2) ? fs5.readFileSync(envPath2, "utf-8") : "";
1807
+ const existing = fs6.existsSync(envPath2) ? fs6.readFileSync(envPath2, "utf-8") : "";
1797
1808
  const regex = new RegExp(`^([ \\t]*)${key}[ \\t]*=.*$`, "m");
1798
1809
  const assignment = regex.exec(existing);
1799
1810
  let updated;
@@ -1806,7 +1817,7 @@ function updateEnvVariable(key, value, envPath2 = getEnvFilePath()) {
1806
1817
  const prefix = existing.length === 0 || existing.endsWith("\n") ? "" : lineEnding;
1807
1818
  updated = `${existing}${prefix}${key}=${value}${lineEnding}`;
1808
1819
  }
1809
- fs5.writeFileSync(envPath2, updated, { encoding: "utf-8", mode: 384 });
1820
+ fs6.writeFileSync(envPath2, updated, { encoding: "utf-8", mode: 384 });
1810
1821
  } catch (err) {
1811
1822
  console.warn(
1812
1823
  `\u26A0\uFE0F [Config] Could not update ${key} in .env:`,
@@ -1824,7 +1835,7 @@ function persistCustomApiKey(apiKey, envPath2 = getEnvFilePath()) {
1824
1835
  }
1825
1836
  function persistApiKey(apiKey, envPath2 = getEnvFilePath()) {
1826
1837
  try {
1827
- const existing = fs5.existsSync(envPath2) ? fs5.readFileSync(envPath2, "utf-8") : "";
1838
+ const existing = fs6.existsSync(envPath2) ? fs6.readFileSync(envPath2, "utf-8") : "";
1828
1839
  const assignment = /^([ \t]*)API_KEY[ \t]*=[ \t]*(.*)$/m.exec(existing);
1829
1840
  if (assignment?.[2].trim()) return;
1830
1841
  let updated;
@@ -1837,7 +1848,7 @@ function persistApiKey(apiKey, envPath2 = getEnvFilePath()) {
1837
1848
  const prefix = existing.length === 0 || existing.endsWith("\n") ? "" : lineEnding;
1838
1849
  updated = `${existing}${prefix}API_KEY=${apiKey}${lineEnding}`;
1839
1850
  }
1840
- fs5.writeFileSync(
1851
+ fs6.writeFileSync(
1841
1852
  envPath2,
1842
1853
  updated,
1843
1854
  { encoding: "utf-8", mode: 384 }
@@ -1889,7 +1900,7 @@ __export(accounts_exports, {
1889
1900
  });
1890
1901
  import "dotenv/config";
1891
1902
  import crypto4 from "crypto";
1892
- import fs6 from "node:fs";
1903
+ import fs7 from "node:fs";
1893
1904
  import path4 from "node:path";
1894
1905
  function isPlaceholderAccountEmail(email, password) {
1895
1906
  if (!email || typeof email !== "string") return false;
@@ -2136,20 +2147,20 @@ function addAccount(email, password, id) {
2136
2147
  function wipeAccountSessionFiles(id) {
2137
2148
  const profilePath = getAccountProfilePath(id);
2138
2149
  try {
2139
- fs6.rmSync(profilePath, { recursive: true, force: true });
2150
+ fs7.rmSync(profilePath, { recursive: true, force: true });
2140
2151
  } catch (error) {
2141
2152
  const message = error instanceof Error ? error.message : String(error ?? "");
2142
2153
  if (message.includes("EPERM") || message.includes("EBUSY") || message.includes("Permission denied")) {
2143
2154
  try {
2144
2155
  const stalePath = `${profilePath}.stale-${Date.now()}`;
2145
- fs6.renameSync(profilePath, stalePath);
2156
+ fs7.renameSync(profilePath, stalePath);
2146
2157
  } catch {
2147
2158
  }
2148
2159
  }
2149
2160
  }
2150
2161
  const siblingState = path4.join(getProfilesDir(), `${id}_state.json`);
2151
2162
  try {
2152
- fs6.rmSync(siblingState, { force: true });
2163
+ fs7.rmSync(siblingState, { force: true });
2153
2164
  } catch {
2154
2165
  }
2155
2166
  }
@@ -4050,7 +4061,7 @@ __export(clean_cache_exports, {
4050
4061
  getDirStats: () => getDirStats
4051
4062
  });
4052
4063
  import "dotenv/config";
4053
- import fs7 from "node:fs";
4064
+ import fs8 from "node:fs";
4054
4065
  import path5 from "node:path";
4055
4066
  import os3 from "node:os";
4056
4067
  import { chromium } from "patchright";
@@ -4065,14 +4076,14 @@ function getDirStats(dir) {
4065
4076
  let files = 0;
4066
4077
  function walk(d) {
4067
4078
  try {
4068
- const entries = fs7.readdirSync(d, { withFileTypes: true });
4079
+ const entries = fs8.readdirSync(d, { withFileTypes: true });
4069
4080
  for (const e of entries) {
4070
4081
  const full = path5.join(d, e.name);
4071
4082
  if (e.isDirectory()) {
4072
4083
  walk(full);
4073
4084
  } else if (e.isFile()) {
4074
4085
  try {
4075
- bytes += fs7.statSync(full).size;
4086
+ bytes += fs8.statSync(full).size;
4076
4087
  files++;
4077
4088
  } catch {
4078
4089
  }
@@ -4101,17 +4112,17 @@ async function cleanPlaywrightBrowsers(cleanUnused) {
4101
4112
  }
4102
4113
  } catch {
4103
4114
  }
4104
- if (!msPlaywrightDir || !fs7.existsSync(msPlaywrightDir)) {
4115
+ if (!msPlaywrightDir || !fs8.existsSync(msPlaywrightDir)) {
4105
4116
  const defaultPlaywrightDir = process.env.PLAYWRIGHT_BROWSERS_PATH || (process.platform === "win32" ? path5.join(os3.homedir(), "AppData", "Local", "ms-playwright") : process.platform === "darwin" ? path5.join(os3.homedir(), "Library", "Caches", "ms-playwright") : path5.join(os3.homedir(), ".cache", "ms-playwright"));
4106
- if (fs7.existsSync(defaultPlaywrightDir)) {
4117
+ if (fs8.existsSync(defaultPlaywrightDir)) {
4107
4118
  msPlaywrightDir = defaultPlaywrightDir;
4108
4119
  }
4109
4120
  }
4110
4121
  const unusedDirs = [];
4111
4122
  let freedBytes = 0;
4112
- if (msPlaywrightDir && fs7.existsSync(msPlaywrightDir)) {
4123
+ if (msPlaywrightDir && fs8.existsSync(msPlaywrightDir)) {
4113
4124
  try {
4114
- const entries = fs7.readdirSync(msPlaywrightDir, { withFileTypes: true });
4125
+ const entries = fs8.readdirSync(msPlaywrightDir, { withFileTypes: true });
4115
4126
  for (const entry of entries) {
4116
4127
  if (!entry.isDirectory()) continue;
4117
4128
  const folderName = entry.name;
@@ -4134,7 +4145,7 @@ async function cleanPlaywrightBrowsers(cleanUnused) {
4134
4145
  if (cleanUnused && unusedDirs.length > 0) {
4135
4146
  for (const item of unusedDirs) {
4136
4147
  try {
4137
- fs7.rmSync(item.path, { recursive: true, force: true });
4148
+ fs8.rmSync(item.path, { recursive: true, force: true });
4138
4149
  freedBytes += item.bytes;
4139
4150
  } catch (err) {
4140
4151
  console.warn(`[CleanCache] Warning: could not remove ${item.name}:`, err);
@@ -4270,7 +4281,7 @@ __export(playwright_exports, {
4270
4281
  });
4271
4282
  import { chromium as chromium2 } from "patchright";
4272
4283
  import path6 from "path";
4273
- import fs8 from "fs";
4284
+ import fs9 from "fs";
4274
4285
  import crypto5 from "crypto";
4275
4286
  import { spawnSync } from "child_process";
4276
4287
  import { createRequire } from "module";
@@ -4284,7 +4295,7 @@ function autoInstallPlaywrightChromium() {
4284
4295
  try {
4285
4296
  const patchrightEntry = requireLocal.resolve("patchright");
4286
4297
  const cliPath = path6.join(path6.dirname(patchrightEntry), "cli.js");
4287
- if (fs8.existsSync(cliPath)) {
4298
+ if (fs9.existsSync(cliPath)) {
4288
4299
  console.log("\u23F3 [Playwright] Navegador Chromium n\xE3o encontrado. Instalando automaticamente...");
4289
4300
  const res2 = spawnSync(process.execPath, [cliPath, "install", "chromium"], {
4290
4301
  stdio: "inherit",
@@ -4420,10 +4431,10 @@ function getStorageStatePath(accountId) {
4420
4431
  function loadStorageState(accountId) {
4421
4432
  const p1 = getStorageStatePath(accountId);
4422
4433
  const p2 = path6.join(path6.dirname(p1), `${accountId}_state.json`);
4423
- const chosenPath = fs8.existsSync(p1) ? p1 : fs8.existsSync(p2) ? p2 : void 0;
4434
+ const chosenPath = fs9.existsSync(p1) ? p1 : fs9.existsSync(p2) ? p2 : void 0;
4424
4435
  if (!chosenPath) return void 0;
4425
4436
  try {
4426
- const raw = fs8.readFileSync(chosenPath, "utf8");
4437
+ const raw = fs9.readFileSync(chosenPath, "utf8");
4427
4438
  const state = JSON.parse(raw);
4428
4439
  if (!state || typeof state !== "object" || !Array.isArray(state.cookies)) {
4429
4440
  return void 0;
@@ -4437,8 +4448,8 @@ async function saveStorageState(context, accountId, timeoutMs = 5e3) {
4437
4448
  try {
4438
4449
  const stateFile = getStorageStatePath(accountId);
4439
4450
  const dir = path6.dirname(stateFile);
4440
- if (!fs8.existsSync(dir)) {
4441
- fs8.mkdirSync(dir, { recursive: true });
4451
+ if (!fs9.existsSync(dir)) {
4452
+ fs9.mkdirSync(dir, { recursive: true });
4442
4453
  }
4443
4454
  await withTimeout(
4444
4455
  context.storageState({ path: stateFile }),
@@ -4547,7 +4558,7 @@ async function isPageLoggedIn(page, timeoutMs = SESSION_PROBE_NAVIGATION_TIMEOUT
4547
4558
  return false;
4548
4559
  }
4549
4560
  }
4550
- async function getOrLaunchSharedBrowser(browserType = "chromium", headless = true) {
4561
+ async function getOrLaunchSharedBrowser(browserType = "chromium", headless = config.playwright.headless) {
4551
4562
  if (sharedBrowser && sharedBrowser.isConnected()) {
4552
4563
  return sharedBrowser;
4553
4564
  }
@@ -4607,13 +4618,40 @@ async function getOrLaunchSharedBrowser(browserType = "chromium", headless = tru
4607
4618
  }
4608
4619
  }
4609
4620
  async function clearVisibleChallenge(page) {
4610
- if (!config.captcha.enabled) return;
4611
- await solveBaxiaCaptcha(page, {
4612
- waitForMs: 0,
4613
- maxAttempts: config.captcha.maxAttempts,
4614
- retryDelayMs: config.captcha.retryDelayMs,
4615
- settleMs: config.captcha.settleMs
4616
- }).catch(() => false);
4621
+ if (page.isClosed()) return;
4622
+ if (config.captcha.enabled) {
4623
+ await solveBaxiaCaptcha(page, {
4624
+ waitForMs: 0,
4625
+ maxAttempts: config.captcha.maxAttempts,
4626
+ retryDelayMs: config.captcha.retryDelayMs,
4627
+ settleMs: config.captcha.settleMs
4628
+ }).catch(() => false);
4629
+ }
4630
+ try {
4631
+ const modalCloseSelectors = [
4632
+ ".ant-modal-close",
4633
+ ".ant-modal-close-x",
4634
+ "button.ant-modal-close",
4635
+ "button[aria-label*='Close' i]",
4636
+ "button[aria-label*='Fechar' i]",
4637
+ ".index-module__whats-new-modal-close",
4638
+ "button:has-text('Cancel')",
4639
+ "button:has-text('Cancelar')",
4640
+ "button:has-text('I understand')",
4641
+ "button:has-text('Entendi')",
4642
+ "button:has-text('OK')"
4643
+ ];
4644
+ for (const sel of modalCloseSelectors) {
4645
+ if (page.isClosed()) return;
4646
+ const btn = page.locator(sel).first();
4647
+ if (await btn.isVisible({ timeout: 150 }).catch(() => false)) {
4648
+ await btn.click({ timeout: 500 }).catch(() => {
4649
+ });
4650
+ await sleep2(200);
4651
+ }
4652
+ }
4653
+ } catch {
4654
+ }
4617
4655
  }
4618
4656
  function getErrorMessage(error) {
4619
4657
  return error instanceof Error ? error.message : String(error);
@@ -5041,6 +5079,21 @@ function getStealthScript(profile) {
5041
5079
  spoofedFunctions.add(window.performance.getEntriesByType);
5042
5080
  }
5043
5081
  } catch(e) {}
5082
+
5083
+ // --- Auto-resolve birthday compliance & eliminate false logout markers ---
5084
+ try {
5085
+ localStorage.removeItem("qwen_token_logged_out_marker");
5086
+ const b = localStorage.getItem("qwen_account_birthday");
5087
+ if (b) {
5088
+ try {
5089
+ const parsed = JSON.parse(b);
5090
+ if (!parsed.birthday) {
5091
+ parsed.birthday = "1995-06-15";
5092
+ localStorage.setItem("qwen_account_birthday", JSON.stringify(parsed));
5093
+ }
5094
+ } catch {}
5095
+ }
5096
+ } catch(e) {}
5044
5097
  })();
5045
5098
  `;
5046
5099
  }
@@ -5339,7 +5392,7 @@ async function resolveAccountCredentials(account) {
5339
5392
  }
5340
5393
  return account;
5341
5394
  }
5342
- async function initPlaywrightForAccount(rawAccount, headless = true, browserType = "chromium", options = {}) {
5395
+ async function initPlaywrightForAccount(rawAccount, headless = config.playwright.headless, browserType = "chromium", options = {}) {
5343
5396
  const account = await resolveAccountCredentials(rawAccount);
5344
5397
  if (accountPages.has(account.id)) {
5345
5398
  console.log(
@@ -5465,7 +5518,7 @@ async function initPlaywrightForAccount(rawAccount, headless = true, browserType
5465
5518
  const storageState = loadStorageState(account.id);
5466
5519
  if (storageState) {
5467
5520
  try {
5468
- const raw = fs8.readFileSync(storageState, "utf8");
5521
+ const raw = fs9.readFileSync(storageState, "utf8");
5469
5522
  const parsed = JSON.parse(raw);
5470
5523
  if (Array.isArray(parsed.cookies) && parsed.cookies.length > 0) {
5471
5524
  const currentCookies = await acctContext.cookies();
@@ -5552,11 +5605,19 @@ async function initPlaywrightForAccount(rawAccount, headless = true, browserType
5552
5605
  }
5553
5606
  if (restoredFromDb) {
5554
5607
  if (!acctPage.isClosed() && (acctPage.url() === "about:blank" || !acctPage.url().startsWith(qwenOrigin()))) {
5555
- void acctPage.goto(qwenUrl("/"), {
5556
- waitUntil: "domcontentloaded",
5557
- timeout: config.timeouts.navigation
5558
- }).catch(() => {
5559
- });
5608
+ try {
5609
+ await acctPage.goto(qwenUrl("/"), {
5610
+ waitUntil: "domcontentloaded",
5611
+ timeout: config.timeouts.navigation
5612
+ });
5613
+ await sleep2(300);
5614
+ } catch (err) {
5615
+ if (!err?.message?.includes("ERR_ABORTED")) {
5616
+ console.warn(
5617
+ `\u26A0\uFE0F [Playwright] Background navigation warning for ${maskEmail(account.email)}: ${err.message}`
5618
+ );
5619
+ }
5620
+ }
5560
5621
  }
5561
5622
  return;
5562
5623
  }
@@ -5677,7 +5738,7 @@ async function validateAccountLogin(rawAccount, headless = true, browserType = "
5677
5738
  const storageState = loadStorageState(account.id);
5678
5739
  if (storageState) {
5679
5740
  try {
5680
- const raw = fs8.readFileSync(storageState, "utf8");
5741
+ const raw = fs9.readFileSync(storageState, "utf8");
5681
5742
  const parsed = JSON.parse(raw);
5682
5743
  if (Array.isArray(parsed.cookies) && parsed.cookies.length > 0) {
5683
5744
  const currentCookies = await acctContext.cookies();
@@ -5796,18 +5857,34 @@ async function loginToQwen(accountId, email, password) {
5796
5857
  const apiResult = await loginViaApi(page, email, password);
5797
5858
  if (apiResult.success) {
5798
5859
  cookieCaches.delete(accountId);
5799
- const cache3 = headerCaches.get(accountId);
5800
- if (cache3) {
5801
- cache3.headers = {};
5802
- cache3.lastRefresh = 0;
5803
- }
5804
- unmarkAccountHeadersReady(accountId);
5860
+ await saveStorageState(page.context(), accountId);
5805
5861
  try {
5806
- const { deleteAuthSession: deleteAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
5807
- deleteAuthSession2(accountId);
5862
+ const liveCookies = await page.context().cookies();
5863
+ const tokenCookie = liveCookies.find((c) => c.name === "token");
5864
+ if (tokenCookie) {
5865
+ const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
5866
+ const cache3 = getHeaderCache(accountId);
5867
+ cache3.headers.cookie = cookieStr;
5868
+ cache3.lastRefresh = Date.now();
5869
+ markAccountHeadersReady(accountId);
5870
+ const { saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
5871
+ const exp = parseJwtExpiry(tokenCookie.value);
5872
+ saveAuthSession2(accountId, {
5873
+ cookie: cookieStr,
5874
+ userAgent: cache3.headers["user-agent"] || "",
5875
+ bxV: cache3.headers["bx-v"] || "2.5.37",
5876
+ bxUa: cache3.headers["bx-ua"] || "",
5877
+ bxUmidtoken: cache3.headers["bx-umidtoken"] || "",
5878
+ secChUa: cache3.headers["sec-ch-ua"] || void 0,
5879
+ secChUaMobile: cache3.headers["sec-ch-ua-mobile"] || void 0,
5880
+ secChUaPlatform: cache3.headers["sec-ch-ua-platform"] || void 0,
5881
+ version: cache3.headers["version"] || void 0,
5882
+ tokenExpiresAt: exp || void 0,
5883
+ capturedAt: Date.now()
5884
+ });
5885
+ }
5808
5886
  } catch {
5809
5887
  }
5810
- await saveStorageState(page.context(), accountId);
5811
5888
  return true;
5812
5889
  }
5813
5890
  if (apiResult.permanentFailure) {
@@ -5824,18 +5901,34 @@ async function loginToQwen(accountId, email, password) {
5824
5901
  const uiResult = await loginViaUi(page, email, password);
5825
5902
  if (uiResult.success) {
5826
5903
  cookieCaches.delete(accountId);
5827
- const cache3 = headerCaches.get(accountId);
5828
- if (cache3) {
5829
- cache3.headers = {};
5830
- cache3.lastRefresh = 0;
5831
- }
5832
- unmarkAccountHeadersReady(accountId);
5904
+ await saveStorageState(page.context(), accountId);
5833
5905
  try {
5834
- const { deleteAuthSession: deleteAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
5835
- deleteAuthSession2(accountId);
5906
+ const liveCookies = await page.context().cookies();
5907
+ const tokenCookie = liveCookies.find((c) => c.name === "token");
5908
+ if (tokenCookie) {
5909
+ const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
5910
+ const cache3 = getHeaderCache(accountId);
5911
+ cache3.headers.cookie = cookieStr;
5912
+ cache3.lastRefresh = Date.now();
5913
+ markAccountHeadersReady(accountId);
5914
+ const { saveAuthSession: saveAuthSession2 } = await Promise.resolve().then(() => (init_database(), database_exports));
5915
+ const exp = parseJwtExpiry(tokenCookie.value);
5916
+ saveAuthSession2(accountId, {
5917
+ cookie: cookieStr,
5918
+ userAgent: cache3.headers["user-agent"] || "",
5919
+ bxV: cache3.headers["bx-v"] || "2.5.37",
5920
+ bxUa: cache3.headers["bx-ua"] || "",
5921
+ bxUmidtoken: cache3.headers["bx-umidtoken"] || "",
5922
+ secChUa: cache3.headers["sec-ch-ua"] || void 0,
5923
+ secChUaMobile: cache3.headers["sec-ch-ua-mobile"] || void 0,
5924
+ secChUaPlatform: cache3.headers["sec-ch-ua-platform"] || void 0,
5925
+ version: cache3.headers["version"] || void 0,
5926
+ tokenExpiresAt: exp || void 0,
5927
+ capturedAt: Date.now()
5928
+ });
5929
+ }
5836
5930
  } catch {
5837
5931
  }
5838
- await saveStorageState(page.context(), accountId);
5839
5932
  return true;
5840
5933
  }
5841
5934
  if (uiResult.permanentFailure) {
@@ -6034,10 +6127,16 @@ async function loginViaUi(page, email, password) {
6034
6127
  );
6035
6128
  return { success: false, reason: "Campo de e-mail n\xE3o encontrado (poss\xEDvel captcha)" };
6036
6129
  }
6130
+ await clearVisibleChallenge(page);
6131
+ const findPasswordModeButton = () => {
6132
+ return page.locator('button, [role="button"], a, div').filter({
6133
+ hasText: /(?:log\s*in\s*with\s*(?:a\s*)?password|fazer\s*login\s*com\s*senha|entrar\s*com\s*(?:uma\s*)?senha|iniciar\s*sesi[oó]n\s*con\s*contrase[nñ]a|密码登录)/i
6134
+ }).first();
6135
+ };
6037
6136
  try {
6038
- const pwdModeBtn = page.getByText(/Log in with a password/i).first();
6039
- if (await pwdModeBtn.isVisible({ timeout: 1500 }).catch(() => false)) {
6040
- await pwdModeBtn.click().catch(() => {
6137
+ const pwdModeBtn = findPasswordModeButton();
6138
+ if (await pwdModeBtn.isVisible({ timeout: 2e3 }).catch(() => false)) {
6139
+ await pwdModeBtn.click({ timeout: 2e3 }).catch(() => {
6041
6140
  });
6042
6141
  await sleep2(500);
6043
6142
  }
@@ -6046,9 +6145,9 @@ async function loginViaUi(page, email, password) {
6046
6145
  await page.fill(emailSelector, email);
6047
6146
  await sleep2(300);
6048
6147
  try {
6049
- const pwdModeBtn = page.getByText(/Log in with a password/i).first();
6050
- if (await pwdModeBtn.isVisible({ timeout: 1e3 }).catch(() => false)) {
6051
- await pwdModeBtn.click().catch(() => {
6148
+ const pwdModeBtn = findPasswordModeButton();
6149
+ if (await pwdModeBtn.isVisible({ timeout: 1500 }).catch(() => false)) {
6150
+ await pwdModeBtn.click({ timeout: 2e3 }).catch(() => {
6052
6151
  });
6053
6152
  await sleep2(500);
6054
6153
  }
@@ -6073,7 +6172,7 @@ async function loginViaUi(page, email, password) {
6073
6172
  }
6074
6173
  await page.fill(passwordSelector, password);
6075
6174
  await sleep2(500);
6076
- const submitSelector = 'button.qwenchat-auth-pc-submit-button, button[type="submit"], button:has-text("Log in"), button:has-text("Sign in")';
6175
+ const submitSelector = 'button.qwenchat-auth-pc-submit-button, button[type="submit"], button:has-text("Log in"), button:has-text("Sign in"), button:has-text("Fazer login"), button:has-text("Entrar"), button:has-text("Iniciar sesi\xF3n"), button:has-text("\u767B\u5F55")';
6077
6176
  const submitButton = page.locator(submitSelector).first();
6078
6177
  try {
6079
6178
  await page.waitForSelector('button[type="submit"]:not([disabled])', {
@@ -6678,7 +6777,7 @@ async function refreshHeadersInternal(accountId, timeoutMs = config.timeouts.hea
6678
6777
  await executeReauth();
6679
6778
  }
6680
6779
  }
6681
- if (reauthExecuted && hasRequiredQwenHeaders(cache3.headers)) {
6780
+ if (hasRequiredQwenHeaders(cache3.headers)) {
6682
6781
  const liveCookies = await page.context().cookies();
6683
6782
  if (liveCookies.some((c) => c.name === "token")) {
6684
6783
  const cookieStr = liveCookies.map((c) => `${c.name}=${c.value}`).join("; ");
@@ -6794,12 +6893,12 @@ async function resetPlaywrightProfileLocked(accountId) {
6794
6893
  removePlaywrightProfile(profilePath);
6795
6894
  const stateFile2 = path6.join(path6.dirname(profilePath), `${accountId}_state.json`);
6796
6895
  try {
6797
- fs8.rmSync(stateFile2, { force: true });
6896
+ fs9.rmSync(stateFile2, { force: true });
6798
6897
  } catch {
6799
6898
  }
6800
6899
  }
6801
6900
  function removePlaywrightProfile(profilePath, rmSyncOverride) {
6802
- const doRemove = rmSyncOverride ?? ((p, opts) => fs8.rmSync(p, opts));
6901
+ const doRemove = rmSyncOverride ?? ((p, opts) => fs9.rmSync(p, opts));
6803
6902
  try {
6804
6903
  doRemove(profilePath, { recursive: true, force: true });
6805
6904
  } catch (error) {
@@ -6808,7 +6907,7 @@ function removePlaywrightProfile(profilePath, rmSyncOverride) {
6808
6907
  if (message.includes("EPERM") || message.includes("EBUSY") || message.includes("Permission denied")) {
6809
6908
  try {
6810
6909
  const stalePath = `${profilePath}.stale-${Date.now()}`;
6811
- fs8.renameSync(profilePath, stalePath);
6910
+ fs9.renameSync(profilePath, stalePath);
6812
6911
  } catch {
6813
6912
  }
6814
6913
  return;
@@ -6831,23 +6930,23 @@ function prunePlaywrightProfileCaches(profilePath) {
6831
6930
  let freedFiles = 0;
6832
6931
  try {
6833
6932
  const defaultDir = path6.join(profilePath, "Default");
6834
- if (!fs8.existsSync(defaultDir)) {
6933
+ if (!fs9.existsSync(defaultDir)) {
6835
6934
  return { freedBytes, freedFiles };
6836
6935
  }
6837
6936
  for (const dirName of transientDirNames) {
6838
6937
  const targetDir = path6.join(defaultDir, dirName);
6839
- if (fs8.existsSync(targetDir)) {
6938
+ if (fs9.existsSync(targetDir)) {
6840
6939
  try {
6841
6940
  const countAndRemove = (d) => {
6842
6941
  try {
6843
- const entries = fs8.readdirSync(d, { withFileTypes: true });
6942
+ const entries = fs9.readdirSync(d, { withFileTypes: true });
6844
6943
  for (const e of entries) {
6845
6944
  const full = path6.join(d, e.name);
6846
6945
  if (e.isDirectory()) {
6847
6946
  countAndRemove(full);
6848
6947
  } else if (e.isFile()) {
6849
6948
  try {
6850
- freedBytes += fs8.statSync(full).size;
6949
+ freedBytes += fs9.statSync(full).size;
6851
6950
  freedFiles++;
6852
6951
  } catch {
6853
6952
  }
@@ -6857,7 +6956,7 @@ function prunePlaywrightProfileCaches(profilePath) {
6857
6956
  }
6858
6957
  };
6859
6958
  countAndRemove(targetDir);
6860
- fs8.rmSync(targetDir, { recursive: true, force: true });
6959
+ fs9.rmSync(targetDir, { recursive: true, force: true });
6861
6960
  } catch {
6862
6961
  }
6863
6962
  }
@@ -6871,10 +6970,10 @@ function pruneAllPlaywrightProfiles(baseDir = getProfilesDir()) {
6871
6970
  let totalFreedFiles = 0;
6872
6971
  let profilesCleaned = 0;
6873
6972
  try {
6874
- if (!fs8.existsSync(baseDir)) {
6973
+ if (!fs9.existsSync(baseDir)) {
6875
6974
  return { totalFreedBytes, totalFreedFiles, profilesCleaned };
6876
6975
  }
6877
- const entries = fs8.readdirSync(baseDir, { withFileTypes: true });
6976
+ const entries = fs9.readdirSync(baseDir, { withFileTypes: true });
6878
6977
  for (const entry of entries) {
6879
6978
  if (entry.isDirectory()) {
6880
6979
  const profilePath = path6.join(baseDir, entry.name);
@@ -6894,11 +6993,11 @@ function cleanupOrphanProfiles(baseDir = getProfilesDir(), activeAccountIds) {
6894
6993
  let removedCount = 0;
6895
6994
  let freedBytes = 0;
6896
6995
  try {
6897
- if (!fs8.existsSync(baseDir)) {
6996
+ if (!fs9.existsSync(baseDir)) {
6898
6997
  return { removedCount, freedBytes };
6899
6998
  }
6900
6999
  const activeIds = activeAccountIds ?? new Set(loadAccounts().map((a) => a.id));
6901
- const entries = fs8.readdirSync(baseDir, { withFileTypes: true });
7000
+ const entries = fs9.readdirSync(baseDir, { withFileTypes: true });
6902
7001
  for (const entry of entries) {
6903
7002
  if (!entry.isDirectory()) continue;
6904
7003
  const isStale = entry.name.includes(".stale-");
@@ -6909,13 +7008,13 @@ function cleanupOrphanProfiles(baseDir = getProfilesDir(), activeAccountIds) {
6909
7008
  let bytes = 0;
6910
7009
  const countSize = (d) => {
6911
7010
  try {
6912
- const subEntries = fs8.readdirSync(d, { withFileTypes: true });
7011
+ const subEntries = fs9.readdirSync(d, { withFileTypes: true });
6913
7012
  for (const e of subEntries) {
6914
7013
  const full = path6.join(d, e.name);
6915
7014
  if (e.isDirectory()) countSize(full);
6916
7015
  else if (e.isFile()) {
6917
7016
  try {
6918
- bytes += fs8.statSync(full).size;
7017
+ bytes += fs9.statSync(full).size;
6919
7018
  } catch {
6920
7019
  }
6921
7020
  }
@@ -6925,7 +7024,7 @@ function cleanupOrphanProfiles(baseDir = getProfilesDir(), activeAccountIds) {
6925
7024
  };
6926
7025
  countSize(targetPath);
6927
7026
  removePlaywrightProfile(targetPath);
6928
- if (!fs8.existsSync(targetPath)) {
7027
+ if (!fs9.existsSync(targetPath)) {
6929
7028
  removedCount++;
6930
7029
  freedBytes += bytes;
6931
7030
  }
@@ -11083,10 +11182,17 @@ async function withQwenBrowserPage(accountId, fn, targetPath, operationTimeoutMs
11083
11182
  }
11084
11183
  const needsNavigation = currentOrigin !== targetOrigin || normalizedTargetPath !== null && currentPath !== normalizedTargetPath;
11085
11184
  if (needsNavigation) {
11086
- await page.goto(targetUrl, {
11087
- waitUntil: "domcontentloaded",
11088
- timeout: Math.min(config.timeouts.navigation, operationTimeoutMs)
11089
- });
11185
+ try {
11186
+ await page.goto(targetUrl, {
11187
+ waitUntil: "domcontentloaded",
11188
+ timeout: Math.min(config.timeouts.navigation, operationTimeoutMs)
11189
+ });
11190
+ } catch (err) {
11191
+ if (err?.message?.includes("ERR_ABORTED") && page.url().startsWith(targetOrigin)) {
11192
+ } else {
11193
+ throw err;
11194
+ }
11195
+ }
11090
11196
  }
11091
11197
  return fn(page);
11092
11198
  },
@@ -11138,7 +11244,7 @@ async function requestQwenTextInBrowser(accountId, method, path21, headers, body
11138
11244
  const controller = new AbortController();
11139
11245
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
11140
11246
  try {
11141
- const response2 = await fetch(url2, {
11247
+ let response2 = await fetch(url2, {
11142
11248
  method: method2,
11143
11249
  credentials: "include",
11144
11250
  headers: headers2,
@@ -11146,6 +11252,36 @@ async function requestQwenTextInBrowser(accountId, method, path21, headers, body
11146
11252
  signal: controller.signal,
11147
11253
  ...referrer ? { referrer } : {}
11148
11254
  });
11255
+ if (response2.status === 401) {
11256
+ try {
11257
+ const refreshRes = await fetch("https://auth.qwen.ai/api/v2/auths/refresh", {
11258
+ method: "GET",
11259
+ credentials: "include",
11260
+ signal: AbortSignal.timeout(3e3)
11261
+ });
11262
+ if (refreshRes.status === 200) {
11263
+ const refreshJson = await refreshRes.json().catch(() => null);
11264
+ if (refreshJson && refreshJson.success === true && refreshJson.data?.token) {
11265
+ const freshTok = refreshJson.data.token;
11266
+ localStorage.setItem("token", freshTok);
11267
+ document.cookie = `token=${encodeURIComponent(freshTok)}; path=/; domain=.qwen.ai; max-age=31536000`;
11268
+ if (headers2["authorization"] || headers2["Authorization"]) {
11269
+ headers2["authorization"] = `Bearer ${freshTok}`;
11270
+ headers2["Authorization"] = `Bearer ${freshTok}`;
11271
+ }
11272
+ response2 = await fetch(url2, {
11273
+ method: method2,
11274
+ credentials: "include",
11275
+ headers: headers2,
11276
+ body: body2,
11277
+ signal: controller.signal,
11278
+ ...referrer ? { referrer } : {}
11279
+ });
11280
+ }
11281
+ }
11282
+ } catch {
11283
+ }
11284
+ }
11149
11285
  return {
11150
11286
  status: response2.status,
11151
11287
  contentType: response2.headers.get("content-type") || "",
@@ -11247,18 +11383,6 @@ async function requestQwenSettingsDirectFetch(accountId, method, path21, headers
11247
11383
  }
11248
11384
  }
11249
11385
  async function requestQwenPersonalizationInBrowser(accountId, method, path21, headers, payload) {
11250
- if (!config.qwen.browserOnlyFetch && !isAuthMockEnabled()) {
11251
- const direct = await requestQwenSettingsDirectFetch(
11252
- accountId,
11253
- method,
11254
- path21,
11255
- headers,
11256
- payload
11257
- );
11258
- if (direct) {
11259
- return direct;
11260
- }
11261
- }
11262
11386
  const response = await requestQwenTextInBrowser(
11263
11387
  accountId,
11264
11388
  method,
@@ -21907,6 +22031,7 @@ async function chatCompletions(c) {
21907
22031
  )) {
21908
22032
  c.header(name, value);
21909
22033
  }
22034
+ c.header("X-QwenProxy-Account", streamResult.activeAccountLabel);
21910
22035
  const replayed = streamResult.replayedFullContext === true;
21911
22036
  console.log(
21912
22037
  `\u{1F4E4} [${routeLabel}] Request | req=${reqId} | ${streamResult.activeAccountLabel} | ${body.model} | ${replayed ? parsed.messageCount : msgCount} msg(s) | ${replayed ? fullPromptForRequest.length : finalPrompt.length} chars${replayed ? " | full-replay" : ""} | chat=${streamResult.uiSessionId.substring(0, 12)}${declaredTools.length ? ` | ${declaredTools.length} tool(s)` : ""}${files.length ? ` | ${files.length} file(s)` : ""} | +${Date.now() - reqStartedAt}ms`
@@ -25160,18 +25285,18 @@ var init_theme = __esm({
25160
25285
  });
25161
25286
 
25162
25287
  // src/core/server-log-buffer.ts
25163
- import fs9 from "node:fs";
25288
+ import fs10 from "node:fs";
25164
25289
  function appendServerLogToFile(time, level, message) {
25165
25290
  if (isRunningUnderNodeTest()) return;
25166
25291
  try {
25167
25292
  const filePath = getServerLogFilePath();
25168
- if (fs9.existsSync(filePath)) {
25169
- const stats = fs9.statSync(filePath);
25293
+ if (fs10.existsSync(filePath)) {
25294
+ const stats = fs10.statSync(filePath);
25170
25295
  if (stats.size > 20 * 1024 * 1024) {
25171
25296
  const oldPath = filePath + ".old";
25172
25297
  try {
25173
- if (fs9.existsSync(oldPath)) fs9.unlinkSync(oldPath);
25174
- fs9.renameSync(filePath, oldPath);
25298
+ if (fs10.existsSync(oldPath)) fs10.unlinkSync(oldPath);
25299
+ fs10.renameSync(filePath, oldPath);
25175
25300
  } catch {
25176
25301
  }
25177
25302
  }
@@ -25181,7 +25306,7 @@ function appendServerLogToFile(time, level, message) {
25181
25306
  const dateStr = (/* @__PURE__ */ new Date()).toLocaleDateString("pt-BR");
25182
25307
  const line = `[${dateStr} ${time}] [${level}] ${message}
25183
25308
  `;
25184
- fs9.appendFileSync(filePath, line, "utf-8");
25309
+ fs10.appendFileSync(filePath, line, "utf-8");
25185
25310
  } catch {
25186
25311
  }
25187
25312
  }
@@ -25356,7 +25481,7 @@ var version_exports = {};
25356
25481
  __export(version_exports, {
25357
25482
  getAppVersion: () => getAppVersion
25358
25483
  });
25359
- import fs10 from "node:fs";
25484
+ import fs11 from "node:fs";
25360
25485
  import path7 from "node:path";
25361
25486
  import { fileURLToPath } from "node:url";
25362
25487
  function getAppVersion() {
@@ -25364,8 +25489,8 @@ function getAppVersion() {
25364
25489
  try {
25365
25490
  const currentDir = path7.dirname(fileURLToPath(import.meta.url));
25366
25491
  const pkgPath = path7.resolve(currentDir, "../../package.json");
25367
- if (fs10.existsSync(pkgPath)) {
25368
- const pkg = JSON.parse(fs10.readFileSync(pkgPath, "utf-8"));
25492
+ if (fs11.existsSync(pkgPath)) {
25493
+ const pkg = JSON.parse(fs11.readFileSync(pkgPath, "utf-8"));
25369
25494
  if (pkg.version) {
25370
25495
  cachedVersion = `v${pkg.version}`;
25371
25496
  return cachedVersion;
@@ -25373,7 +25498,7 @@ function getAppVersion() {
25373
25498
  }
25374
25499
  } catch {
25375
25500
  }
25376
- cachedVersion = "v1.4.0";
25501
+ cachedVersion = "v1.4.2";
25377
25502
  return cachedVersion;
25378
25503
  }
25379
25504
  var cachedVersion;
@@ -26486,7 +26611,7 @@ var init_server_manager = __esm({
26486
26611
 
26487
26612
  // src/tui/screen.ts
26488
26613
  import readline from "node:readline";
26489
- import fs11 from "node:fs";
26614
+ import fs12 from "node:fs";
26490
26615
  var Screen;
26491
26616
  var init_screen = __esm({
26492
26617
  "src/tui/screen.ts"() {
@@ -26706,7 +26831,7 @@ var init_screen = __esm({
26706
26831
  this.lastHoverTime = 0;
26707
26832
  const restoreSeq = ANSI.disableMouse + ANSI.exitAltScreen + ANSI.showCursor + ANSI.reset;
26708
26833
  try {
26709
- fs11.writeSync(1, restoreSeq);
26834
+ fs12.writeSync(1, restoreSeq);
26710
26835
  } catch {
26711
26836
  try {
26712
26837
  ServerManager.getInstance().withTuiRendering(() => {
@@ -29151,7 +29276,7 @@ var init_chat_view = __esm({
29151
29276
  });
29152
29277
 
29153
29278
  // src/sync/utils.ts
29154
- import fs12 from "node:fs";
29279
+ import fs13 from "node:fs";
29155
29280
  import path8 from "node:path";
29156
29281
  function createTimestampBackup(filePath) {
29157
29282
  const dir = path8.dirname(filePath);
@@ -29161,19 +29286,19 @@ function createTimestampBackup(filePath) {
29161
29286
  const pad2 = (n) => String(n).padStart(2, "0");
29162
29287
  const timestamp = `${now.getFullYear()}${pad2(now.getMonth() + 1)}${pad2(now.getDate())}_${pad2(now.getHours())}${pad2(now.getMinutes())}${pad2(now.getSeconds())}`;
29163
29288
  const backupPath = path8.join(dir, `${base}.qwenproxy.${timestamp}${ext}.bak`);
29164
- fs12.copyFileSync(filePath, backupPath);
29289
+ fs13.copyFileSync(filePath, backupPath);
29165
29290
  return backupPath;
29166
29291
  }
29167
29292
  function findLatestBackup(filePath) {
29168
29293
  const dir = path8.dirname(filePath);
29169
29294
  const ext = path8.extname(filePath);
29170
29295
  const base = path8.basename(filePath, ext);
29171
- if (!fs12.existsSync(dir)) return void 0;
29296
+ if (!fs13.existsSync(dir)) return void 0;
29172
29297
  try {
29173
- const files = fs12.readdirSync(dir);
29298
+ const files = fs13.readdirSync(dir);
29174
29299
  const candidates = files.filter((f) => f.startsWith(base) && f.includes("qwenproxy") && f.endsWith(".bak")).map((f) => path8.join(dir, f)).sort((a, b) => {
29175
29300
  try {
29176
- return fs12.statSync(b).mtimeMs - fs12.statSync(a).mtimeMs;
29301
+ return fs13.statSync(b).mtimeMs - fs13.statSync(a).mtimeMs;
29177
29302
  } catch {
29178
29303
  return 0;
29179
29304
  }
@@ -29184,13 +29309,13 @@ function findLatestBackup(filePath) {
29184
29309
  }
29185
29310
  }
29186
29311
  function restoreFromBackup(filePath, backupPath) {
29187
- const targetBackup = backupPath && fs12.existsSync(backupPath) ? backupPath : findLatestBackup(filePath);
29188
- if (!targetBackup || !fs12.existsSync(targetBackup)) {
29312
+ const targetBackup = backupPath && fs13.existsSync(backupPath) ? backupPath : findLatestBackup(filePath);
29313
+ if (!targetBackup || !fs13.existsSync(targetBackup)) {
29189
29314
  return false;
29190
29315
  }
29191
- fs12.copyFileSync(targetBackup, filePath);
29316
+ fs13.copyFileSync(targetBackup, filePath);
29192
29317
  try {
29193
- fs12.unlinkSync(targetBackup);
29318
+ fs13.unlinkSync(targetBackup);
29194
29319
  } catch {
29195
29320
  }
29196
29321
  return true;
@@ -29209,18 +29334,18 @@ var init_utils = __esm({
29209
29334
  });
29210
29335
 
29211
29336
  // src/sync/claude-code.ts
29212
- import fs13 from "node:fs";
29337
+ import fs14 from "node:fs";
29213
29338
  import path9 from "node:path";
29214
29339
  function syncClaudeCode(options) {
29215
29340
  const { filePath, apiKey, baseUrl, model = "qwen3.8-max" } = options;
29216
29341
  try {
29217
- fs13.mkdirSync(path9.dirname(filePath), { recursive: true });
29342
+ fs14.mkdirSync(path9.dirname(filePath), { recursive: true });
29218
29343
  let backupPath;
29219
29344
  let existingSettings = {};
29220
- if (fs13.existsSync(filePath)) {
29345
+ if (fs14.existsSync(filePath)) {
29221
29346
  backupPath = createTimestampBackup(filePath);
29222
29347
  try {
29223
- const content = fs13.readFileSync(filePath, "utf-8");
29348
+ const content = fs14.readFileSync(filePath, "utf-8");
29224
29349
  existingSettings = JSON.parse(content);
29225
29350
  } catch {
29226
29351
  existingSettings = {};
@@ -29246,7 +29371,7 @@ function syncClaudeCode(options) {
29246
29371
  model,
29247
29372
  enableArtifact: false
29248
29373
  };
29249
- fs13.writeFileSync(filePath, JSON.stringify(updatedSettings, null, 2) + "\n", "utf-8");
29374
+ fs14.writeFileSync(filePath, JSON.stringify(updatedSettings, null, 2) + "\n", "utf-8");
29250
29375
  return {
29251
29376
  client: "claude-code",
29252
29377
  filePath,
@@ -29268,9 +29393,9 @@ function syncClaudeCode(options) {
29268
29393
  function restoreClaudeCode(filePath, backupPath) {
29269
29394
  const restoredFromBackup = restoreFromBackup(filePath, backupPath);
29270
29395
  let manuallyCleaned = false;
29271
- if (fs13.existsSync(filePath)) {
29396
+ if (fs14.existsSync(filePath)) {
29272
29397
  try {
29273
- const data = JSON.parse(fs13.readFileSync(filePath, "utf-8"));
29398
+ const data = JSON.parse(fs14.readFileSync(filePath, "utf-8"));
29274
29399
  if (data.env && (data.env.ANTHROPIC_BASE_URL?.includes("7936") || data.env.ANTHROPIC_AUTH_TOKEN === "sk-qwenproxy-local" || data.env.ANTHROPIC_MODEL?.includes("qwen"))) {
29275
29400
  delete data.env.ANTHROPIC_BASE_URL;
29276
29401
  delete data.env.ANTHROPIC_AUTH_TOKEN;
@@ -29290,7 +29415,7 @@ function restoreClaudeCode(filePath, backupPath) {
29290
29415
  if (Object.keys(data.env).length === 0) {
29291
29416
  delete data.env;
29292
29417
  }
29293
- fs13.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
29418
+ fs14.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
29294
29419
  manuallyCleaned = true;
29295
29420
  }
29296
29421
  } catch {
@@ -29314,7 +29439,7 @@ var init_claude_code = __esm({
29314
29439
  });
29315
29440
 
29316
29441
  // src/sync/codex.ts
29317
- import fs14 from "node:fs";
29442
+ import fs15 from "node:fs";
29318
29443
  import path10 from "node:path";
29319
29444
  import os4 from "node:os";
29320
29445
  function removeTomlSection(content, sectionHeader) {
@@ -29355,12 +29480,12 @@ function updateTopLevelKey(content, key, value) {
29355
29480
  return newTopPart + restPart;
29356
29481
  }
29357
29482
  function syncCodexSingleFile(targetPath, options) {
29358
- fs14.mkdirSync(path10.dirname(targetPath), { recursive: true });
29483
+ fs15.mkdirSync(path10.dirname(targetPath), { recursive: true });
29359
29484
  let backupPath;
29360
29485
  let content = "";
29361
- if (fs14.existsSync(targetPath)) {
29486
+ if (fs15.existsSync(targetPath)) {
29362
29487
  backupPath = createTimestampBackup(targetPath);
29363
- content = fs14.readFileSync(targetPath, "utf-8");
29488
+ content = fs15.readFileSync(targetPath, "utf-8");
29364
29489
  }
29365
29490
  const { apiKey, baseUrl, model = "qwen3.8-max", setActive = true } = options;
29366
29491
  const providerBlock = `[model_providers.qwenproxy]
@@ -29381,8 +29506,8 @@ experimental_bearer_token = "${apiKey}"
29381
29506
  try {
29382
29507
  const rawCatalogPath = catalogMatch[1];
29383
29508
  const catalogPath = path10.isAbsolute(rawCatalogPath) ? rawCatalogPath : path10.resolve(path10.dirname(targetPath), rawCatalogPath);
29384
- if (fs14.existsSync(catalogPath)) {
29385
- const catalog = JSON.parse(fs14.readFileSync(catalogPath, "utf-8"));
29509
+ if (fs15.existsSync(catalogPath)) {
29510
+ const catalog = JSON.parse(fs15.readFileSync(catalogPath, "utf-8"));
29386
29511
  if (Array.isArray(catalog.models)) {
29387
29512
  const hasModel = catalog.models.some((m) => m?.slug === model);
29388
29513
  if (!hasModel) {
@@ -29395,14 +29520,14 @@ experimental_bearer_token = "${apiKey}"
29395
29520
  context_window: 1e6,
29396
29521
  max_context_window: 1e6
29397
29522
  });
29398
- fs14.writeFileSync(catalogPath, JSON.stringify(catalog, null, 2), "utf-8");
29523
+ fs15.writeFileSync(catalogPath, JSON.stringify(catalog, null, 2), "utf-8");
29399
29524
  }
29400
29525
  }
29401
29526
  }
29402
29527
  } catch {
29403
29528
  }
29404
29529
  }
29405
- fs14.writeFileSync(targetPath, content.trimEnd() + "\n", "utf-8");
29530
+ fs15.writeFileSync(targetPath, content.trimEnd() + "\n", "utf-8");
29406
29531
  return { backupPath };
29407
29532
  }
29408
29533
  function syncCodex(options) {
@@ -29418,7 +29543,7 @@ function syncCodex(options) {
29418
29543
  const alternatePath = isStandard ? codexHomePath : standardPath;
29419
29544
  if (alternatePath && path10.resolve(alternatePath).toLowerCase() !== path10.resolve(filePath).toLowerCase()) {
29420
29545
  try {
29421
- if (fs14.existsSync(alternatePath) || fs14.existsSync(path10.dirname(alternatePath))) {
29546
+ if (fs15.existsSync(alternatePath) || fs15.existsSync(path10.dirname(alternatePath))) {
29422
29547
  syncCodexSingleFile(alternatePath, options);
29423
29548
  }
29424
29549
  } catch {
@@ -29447,16 +29572,16 @@ function restoreCodex(filePath, backupPath) {
29447
29572
  const restoredFromBackup = restoreFromBackup(filePath, backupPath);
29448
29573
  let manuallyCleaned = false;
29449
29574
  const cleanSingleFile = (p) => {
29450
- if (fs14.existsSync(p)) {
29575
+ if (fs15.existsSync(p)) {
29451
29576
  try {
29452
- let content = fs14.readFileSync(p, "utf-8");
29577
+ let content = fs15.readFileSync(p, "utf-8");
29453
29578
  if (content.includes("[model_providers.qwenproxy]") || /^model_provider\s*=\s*["']qwenproxy["']/m.test(content)) {
29454
29579
  content = removeTomlSection(content, "model_providers.qwenproxy");
29455
29580
  content = content.replace(/^model_provider\s*=\s*["']qwenproxy["']\r?\n?/m, "");
29456
29581
  if (/^model\s*=\s*["']qwen/m.test(content)) {
29457
29582
  content = content.replace(/^model\s*=\s*["']qwen[^"']*["']\r?\n?/m, "");
29458
29583
  }
29459
- fs14.writeFileSync(p, content.trimEnd() + "\n", "utf-8");
29584
+ fs15.writeFileSync(p, content.trimEnd() + "\n", "utf-8");
29460
29585
  manuallyCleaned = true;
29461
29586
  }
29462
29587
  } catch {
@@ -29494,7 +29619,7 @@ var init_codex = __esm({
29494
29619
  });
29495
29620
 
29496
29621
  // src/sync/opencode.ts
29497
- import fs15 from "node:fs";
29622
+ import fs16 from "node:fs";
29498
29623
  import path11 from "node:path";
29499
29624
  function buildOpenCodeProviderObject(baseUrl, apiKey, primaryModel = "qwen3.8-max", models) {
29500
29625
  const modelsObj = {};
@@ -29620,12 +29745,12 @@ function syncOpenCode(options) {
29620
29745
  setActive = true
29621
29746
  } = options;
29622
29747
  try {
29623
- fs15.mkdirSync(path11.dirname(filePath), { recursive: true });
29748
+ fs16.mkdirSync(path11.dirname(filePath), { recursive: true });
29624
29749
  let backupPath;
29625
29750
  let content = "";
29626
- if (fs15.existsSync(filePath)) {
29751
+ if (fs16.existsSync(filePath)) {
29627
29752
  backupPath = createTimestampBackup(filePath);
29628
- content = fs15.readFileSync(filePath, "utf-8");
29753
+ content = fs16.readFileSync(filePath, "utf-8");
29629
29754
  }
29630
29755
  const providerObj = buildOpenCodeProviderObject(baseUrl, apiKey, model, models);
29631
29756
  const providerJson = JSON.stringify(providerObj, null, 6).split("\n").map((line, idx) => idx === 0 ? line : ` ${line}`).join("\n");
@@ -29640,7 +29765,7 @@ function syncOpenCode(options) {
29640
29765
  initial.provider = {
29641
29766
  qwenproxy: providerObj
29642
29767
  };
29643
- fs15.writeFileSync(filePath, JSON.stringify(initial, null, 2) + "\n", "utf-8");
29768
+ fs16.writeFileSync(filePath, JSON.stringify(initial, null, 2) + "\n", "utf-8");
29644
29769
  } else {
29645
29770
  const existingSpan = findKeyObjectSpan(content, "qwenproxy");
29646
29771
  if (existingSpan) {
@@ -29664,7 +29789,7 @@ ${qwenEntry}
29664
29789
  }
29665
29790
  }
29666
29791
  }
29667
- fs15.writeFileSync(
29792
+ fs16.writeFileSync(
29668
29793
  filePath,
29669
29794
  applyOpenCodeActiveModel(content, model, setActive),
29670
29795
  "utf-8"
@@ -29691,9 +29816,9 @@ ${qwenEntry}
29691
29816
  function restoreOpenCode(filePath, backupPath) {
29692
29817
  const restoredFromBackup = restoreFromBackup(filePath, backupPath);
29693
29818
  let manuallyCleaned = false;
29694
- if (fs15.existsSync(filePath)) {
29819
+ if (fs16.existsSync(filePath)) {
29695
29820
  try {
29696
- const data = JSON.parse(fs15.readFileSync(filePath, "utf-8"));
29821
+ const data = JSON.parse(fs16.readFileSync(filePath, "utf-8"));
29697
29822
  if (data.provider && data.provider.qwenproxy) {
29698
29823
  delete data.provider.qwenproxy;
29699
29824
  if (data.model && data.model.includes("qwen")) {
@@ -29702,7 +29827,7 @@ function restoreOpenCode(filePath, backupPath) {
29702
29827
  if (Object.keys(data.provider).length === 0) {
29703
29828
  delete data.provider;
29704
29829
  }
29705
- fs15.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
29830
+ fs16.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
29706
29831
  manuallyCleaned = true;
29707
29832
  }
29708
29833
  } catch {
@@ -29726,7 +29851,7 @@ var init_opencode = __esm({
29726
29851
  });
29727
29852
 
29728
29853
  // src/sync/omp.ts
29729
- import fs16 from "node:fs";
29854
+ import fs17 from "node:fs";
29730
29855
  import path12 from "node:path";
29731
29856
  function buildOmpProviderYaml(baseUrl, apiKey, primaryModel = "qwen3.8-max", models) {
29732
29857
  const modelList = Array.from(
@@ -29758,12 +29883,12 @@ ${formattedModels}
29758
29883
  function syncOmp(options) {
29759
29884
  const { filePath, apiKey, baseUrl, model = "qwen3.8-max", models } = options;
29760
29885
  try {
29761
- fs16.mkdirSync(path12.dirname(filePath), { recursive: true });
29886
+ fs17.mkdirSync(path12.dirname(filePath), { recursive: true });
29762
29887
  let backupPath;
29763
29888
  let content = "";
29764
- if (fs16.existsSync(filePath)) {
29889
+ if (fs17.existsSync(filePath)) {
29765
29890
  backupPath = createTimestampBackup(filePath);
29766
- content = fs16.readFileSync(filePath, "utf-8");
29891
+ content = fs17.readFileSync(filePath, "utf-8");
29767
29892
  }
29768
29893
  const providerBlock = buildOmpProviderYaml(baseUrl, apiKey, model, models);
29769
29894
  if (!content.trim()) {
@@ -29783,7 +29908,7 @@ ${providerBlock}`;
29783
29908
  }
29784
29909
  }
29785
29910
  }
29786
- fs16.writeFileSync(filePath, content.trimEnd() + "\n", "utf-8");
29911
+ fs17.writeFileSync(filePath, content.trimEnd() + "\n", "utf-8");
29787
29912
  return {
29788
29913
  client: "omp",
29789
29914
  filePath,
@@ -29805,13 +29930,13 @@ ${providerBlock}`;
29805
29930
  function restoreOmp(filePath, backupPath) {
29806
29931
  const restoredFromBackup = restoreFromBackup(filePath, backupPath);
29807
29932
  let manuallyCleaned = false;
29808
- if (fs16.existsSync(filePath)) {
29933
+ if (fs17.existsSync(filePath)) {
29809
29934
  try {
29810
- let content = fs16.readFileSync(filePath, "utf-8");
29935
+ let content = fs17.readFileSync(filePath, "utf-8");
29811
29936
  if (content.includes("qwenproxy:")) {
29812
29937
  const regex = /^\s*qwenproxy:\s*\r?\n(?:^[ \t].*\r?\n?)*/m;
29813
29938
  content = content.replace(regex, "");
29814
- fs16.writeFileSync(filePath, content, "utf-8");
29939
+ fs17.writeFileSync(filePath, content, "utf-8");
29815
29940
  manuallyCleaned = true;
29816
29941
  }
29817
29942
  } catch {
@@ -29835,7 +29960,7 @@ var init_omp = __esm({
29835
29960
  });
29836
29961
 
29837
29962
  // src/sync/hermes.ts
29838
- import fs17 from "node:fs";
29963
+ import fs18 from "node:fs";
29839
29964
  import path13 from "node:path";
29840
29965
  function buildHermesModelBlock(baseUrl, apiKey, model = "qwen3.8-max", reasoningEffort = "high") {
29841
29966
  return `model:
@@ -29859,12 +29984,12 @@ function buildHermesProviderBlock(baseUrl, apiKey) {
29859
29984
  function syncHermes(options) {
29860
29985
  const { filePath, apiKey, baseUrl, model = "qwen3.8-max", reasoningEffort = "high" } = options;
29861
29986
  try {
29862
- fs17.mkdirSync(path13.dirname(filePath), { recursive: true });
29987
+ fs18.mkdirSync(path13.dirname(filePath), { recursive: true });
29863
29988
  let backupPath;
29864
29989
  let content = "";
29865
- if (fs17.existsSync(filePath)) {
29990
+ if (fs18.existsSync(filePath)) {
29866
29991
  backupPath = createTimestampBackup(filePath);
29867
- content = fs17.readFileSync(filePath, "utf-8");
29992
+ content = fs18.readFileSync(filePath, "utf-8");
29868
29993
  }
29869
29994
  const modelBlock = buildHermesModelBlock(baseUrl, apiKey, model, reasoningEffort);
29870
29995
  const providerBlock = buildHermesProviderBlock(baseUrl, apiKey);
@@ -29890,7 +30015,7 @@ function syncHermes(options) {
29890
30015
  }
29891
30016
  }
29892
30017
  }
29893
- fs17.writeFileSync(filePath, content.trimEnd() + "\n", "utf-8");
30018
+ fs18.writeFileSync(filePath, content.trimEnd() + "\n", "utf-8");
29894
30019
  return {
29895
30020
  client: "hermes",
29896
30021
  filePath,
@@ -29928,7 +30053,7 @@ var init_hermes = __esm({
29928
30053
  });
29929
30054
 
29930
30055
  // src/sync/openclaw.ts
29931
- import fs18 from "node:fs";
30056
+ import fs19 from "node:fs";
29932
30057
  import path14 from "node:path";
29933
30058
  function findKeyObjectSpan2(content, key) {
29934
30059
  const regex = new RegExp(`"${key}"\\s*:\\s*\\{`);
@@ -30027,12 +30152,12 @@ function buildOpenClawProviderObject(baseUrl, apiKey, model = "qwen3.8-max", mod
30027
30152
  function syncOpenClaw(options) {
30028
30153
  const { filePath, apiKey, baseUrl, model = "qwen3.8-max", models, reasoningEffort = "high" } = options;
30029
30154
  try {
30030
- fs18.mkdirSync(path14.dirname(filePath), { recursive: true });
30155
+ fs19.mkdirSync(path14.dirname(filePath), { recursive: true });
30031
30156
  let backupPath;
30032
30157
  let content = "";
30033
- if (fs18.existsSync(filePath)) {
30158
+ if (fs19.existsSync(filePath)) {
30034
30159
  backupPath = createTimestampBackup(filePath);
30035
- content = fs18.readFileSync(filePath, "utf-8");
30160
+ content = fs19.readFileSync(filePath, "utf-8");
30036
30161
  }
30037
30162
  const providerObj = buildOpenClawProviderObject(baseUrl, apiKey, model, models);
30038
30163
  const providerJson = JSON.stringify(providerObj, null, 6).split("\n").map((line, idx) => idx === 0 ? line : ` ${line}`).join("\n");
@@ -30056,7 +30181,7 @@ function syncOpenClaw(options) {
30056
30181
  }
30057
30182
  }
30058
30183
  };
30059
- fs18.writeFileSync(filePath, JSON.stringify(initial, null, 2) + "\n", "utf-8");
30184
+ fs19.writeFileSync(filePath, JSON.stringify(initial, null, 2) + "\n", "utf-8");
30060
30185
  } else {
30061
30186
  const existingSpan = findKeyObjectSpan2(content, "qwenproxy");
30062
30187
  if (existingSpan) {
@@ -30093,7 +30218,7 @@ ${qwenEntry}
30093
30218
  }
30094
30219
  }
30095
30220
  }
30096
- fs18.writeFileSync(filePath, content, "utf-8");
30221
+ fs19.writeFileSync(filePath, content, "utf-8");
30097
30222
  }
30098
30223
  return {
30099
30224
  client: "openclaw",
@@ -30132,7 +30257,7 @@ var init_openclaw = __esm({
30132
30257
  });
30133
30258
 
30134
30259
  // src/sync/kilo.ts
30135
- import fs19 from "node:fs";
30260
+ import fs20 from "node:fs";
30136
30261
  import path15 from "node:path";
30137
30262
  function findKeyObjectSpan3(content, key) {
30138
30263
  const regex = new RegExp(`"${key}"\\s*:\\s*\\{`);
@@ -30239,12 +30364,12 @@ function buildKiloProviderObject(baseUrl, apiKey, primaryModel = "qwen3.8-max",
30239
30364
  function syncKilo(options) {
30240
30365
  const { filePath, apiKey, baseUrl, model = "qwen3.8-max", models, setActive = true } = options;
30241
30366
  try {
30242
- fs19.mkdirSync(path15.dirname(filePath), { recursive: true });
30367
+ fs20.mkdirSync(path15.dirname(filePath), { recursive: true });
30243
30368
  let backupPath;
30244
30369
  let content = "";
30245
- if (fs19.existsSync(filePath)) {
30370
+ if (fs20.existsSync(filePath)) {
30246
30371
  backupPath = createTimestampBackup(filePath);
30247
- content = fs19.readFileSync(filePath, "utf-8");
30372
+ content = fs20.readFileSync(filePath, "utf-8");
30248
30373
  }
30249
30374
  const providerObj = buildKiloProviderObject(baseUrl, apiKey, model, models);
30250
30375
  const providerJson = JSON.stringify(providerObj, null, 6).split("\n").map((line, idx) => idx === 0 ? line : ` ${line}`).join("\n");
@@ -30259,7 +30384,7 @@ function syncKilo(options) {
30259
30384
  if (setActive) {
30260
30385
  initial.model = `qwenproxy/${model}`;
30261
30386
  }
30262
- fs19.writeFileSync(filePath, JSON.stringify(initial, null, 2) + "\n", "utf-8");
30387
+ fs20.writeFileSync(filePath, JSON.stringify(initial, null, 2) + "\n", "utf-8");
30263
30388
  } else {
30264
30389
  const existingSpan = findKeyObjectSpan3(content, "qwenproxy");
30265
30390
  if (existingSpan) {
@@ -30289,7 +30414,7 @@ ${qwenEntry}
30289
30414
  content = content.replace(modelRegex, `"model": "qwenproxy/${model}"`);
30290
30415
  }
30291
30416
  }
30292
- fs19.writeFileSync(filePath, content, "utf-8");
30417
+ fs20.writeFileSync(filePath, content, "utf-8");
30293
30418
  }
30294
30419
  return {
30295
30420
  client: "kilo",
@@ -30328,15 +30453,15 @@ var init_kilo = __esm({
30328
30453
  });
30329
30454
 
30330
30455
  // src/sync/cline.ts
30331
- import fs20 from "node:fs";
30456
+ import fs21 from "node:fs";
30332
30457
  import path16 from "node:path";
30333
30458
  import Database2 from "better-sqlite3";
30334
30459
  function syncCline(options) {
30335
30460
  const { filePath, baseUrl, model = "qwen3.8-max", reasoningEffort = "high" } = options;
30336
30461
  try {
30337
- fs20.mkdirSync(path16.dirname(filePath), { recursive: true });
30462
+ fs21.mkdirSync(path16.dirname(filePath), { recursive: true });
30338
30463
  let backupPath;
30339
- if (fs20.existsSync(filePath)) {
30464
+ if (fs21.existsSync(filePath)) {
30340
30465
  backupPath = createTimestampBackup(filePath);
30341
30466
  }
30342
30467
  const db2 = new Database2(filePath);
@@ -30408,7 +30533,7 @@ function syncCline(options) {
30408
30533
  function restoreCline(filePath, backupPath) {
30409
30534
  const restoredFromBackup = restoreFromBackup(filePath, backupPath);
30410
30535
  let manuallyCleaned = false;
30411
- if (fs20.existsSync(filePath)) {
30536
+ if (fs21.existsSync(filePath)) {
30412
30537
  try {
30413
30538
  const db2 = new Database2(filePath);
30414
30539
  const rows = db2.prepare("SELECT key, value FROM ItemTable WHERE key = 'saoudrizwan.claude-dev' OR key = 'ZooCodeOrganization.zoo-code'").all();
@@ -30453,7 +30578,7 @@ var init_cline = __esm({
30453
30578
  });
30454
30579
 
30455
30580
  // src/sync/zed.ts
30456
- import fs21 from "node:fs";
30581
+ import fs22 from "node:fs";
30457
30582
  import path17 from "node:path";
30458
30583
  function parseJsonWithComments(raw) {
30459
30584
  let result = "";
@@ -30567,13 +30692,13 @@ function buildZedAvailableModels(primaryModel = "qwen3.8-max", models) {
30567
30692
  function syncZed(options) {
30568
30693
  const { filePath, baseUrl, model = "qwen3.8-max", models, setActive = true } = options;
30569
30694
  try {
30570
- fs21.mkdirSync(path17.dirname(filePath), { recursive: true });
30695
+ fs22.mkdirSync(path17.dirname(filePath), { recursive: true });
30571
30696
  let backupPath;
30572
30697
  let existingSettings = {};
30573
- if (fs21.existsSync(filePath)) {
30698
+ if (fs22.existsSync(filePath)) {
30574
30699
  backupPath = createTimestampBackup(filePath);
30575
30700
  try {
30576
- const content = fs21.readFileSync(filePath, "utf-8");
30701
+ const content = fs22.readFileSync(filePath, "utf-8");
30577
30702
  existingSettings = parseJsonWithComments(content);
30578
30703
  } catch {
30579
30704
  existingSettings = {};
@@ -30603,7 +30728,7 @@ function syncZed(options) {
30603
30728
  }
30604
30729
  };
30605
30730
  }
30606
- fs21.writeFileSync(filePath, JSON.stringify(updatedSettings, null, 2) + "\n", "utf-8");
30731
+ fs22.writeFileSync(filePath, JSON.stringify(updatedSettings, null, 2) + "\n", "utf-8");
30607
30732
  return {
30608
30733
  client: "zed",
30609
30734
  filePath,
@@ -30625,9 +30750,9 @@ function syncZed(options) {
30625
30750
  function restoreZed(filePath, backupPath) {
30626
30751
  const restoredFromBackup = restoreFromBackup(filePath, backupPath);
30627
30752
  let manuallyCleaned = false;
30628
- if (fs21.existsSync(filePath)) {
30753
+ if (fs22.existsSync(filePath)) {
30629
30754
  try {
30630
- let content = fs21.readFileSync(filePath, "utf-8");
30755
+ let content = fs22.readFileSync(filePath, "utf-8");
30631
30756
  if (content.includes("127.0.0.1:7936") || content.includes("qwen3.8-max")) {
30632
30757
  const data = parseJsonWithComments(content);
30633
30758
  if (data.language_models?.openai?.api_url?.includes("7936")) {
@@ -30635,7 +30760,7 @@ function restoreZed(filePath, backupPath) {
30635
30760
  if (Object.keys(data.language_models).length === 0) {
30636
30761
  delete data.language_models;
30637
30762
  }
30638
- fs21.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
30763
+ fs22.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
30639
30764
  manuallyCleaned = true;
30640
30765
  }
30641
30766
  }
@@ -30660,7 +30785,7 @@ var init_zed = __esm({
30660
30785
  });
30661
30786
 
30662
30787
  // src/sync/aider.ts
30663
- import fs22 from "node:fs";
30788
+ import fs23 from "node:fs";
30664
30789
  import path18 from "node:path";
30665
30790
  function updateYamlKeyValue(content, key, value) {
30666
30791
  const regex = new RegExp(`^${key}:.*$`, "m");
@@ -30680,12 +30805,12 @@ function syncAider(options) {
30680
30805
  modelSettingsPath
30681
30806
  } = options;
30682
30807
  try {
30683
- fs22.mkdirSync(path18.dirname(filePath), { recursive: true });
30808
+ fs23.mkdirSync(path18.dirname(filePath), { recursive: true });
30684
30809
  let backupPath;
30685
30810
  let confContent = "";
30686
- if (fs22.existsSync(filePath)) {
30811
+ if (fs23.existsSync(filePath)) {
30687
30812
  backupPath = createTimestampBackup(filePath);
30688
- confContent = fs22.readFileSync(filePath, "utf-8");
30813
+ confContent = fs23.readFileSync(filePath, "utf-8");
30689
30814
  }
30690
30815
  const fullModelName = model.startsWith("openai/") ? model : `openai/${model}`;
30691
30816
  const weakModelName = "openai/qwen3.7-plus";
@@ -30694,15 +30819,15 @@ function syncAider(options) {
30694
30819
  confContent = updateYamlKeyValue(confContent, "model", fullModelName);
30695
30820
  confContent = updateYamlKeyValue(confContent, "editor-model", fullModelName);
30696
30821
  confContent = updateYamlKeyValue(confContent, "weak-model", weakModelName);
30697
- fs22.writeFileSync(filePath, confContent.trimEnd() + "\n", "utf-8");
30822
+ fs23.writeFileSync(filePath, confContent.trimEnd() + "\n", "utf-8");
30698
30823
  let extraBackupPath;
30699
30824
  const resolvedSettingsPath = modelSettingsPath || path18.join(path18.dirname(filePath), ".aider.model.settings.yml");
30700
30825
  if (resolvedSettingsPath) {
30701
- fs22.mkdirSync(path18.dirname(resolvedSettingsPath), { recursive: true });
30826
+ fs23.mkdirSync(path18.dirname(resolvedSettingsPath), { recursive: true });
30702
30827
  let settingsContent = "";
30703
- if (fs22.existsSync(resolvedSettingsPath)) {
30828
+ if (fs23.existsSync(resolvedSettingsPath)) {
30704
30829
  extraBackupPath = createTimestampBackup(resolvedSettingsPath);
30705
- settingsContent = fs22.readFileSync(resolvedSettingsPath, "utf-8");
30830
+ settingsContent = fs23.readFileSync(resolvedSettingsPath, "utf-8");
30706
30831
  }
30707
30832
  const modelBlock = `- name: ${fullModelName}
30708
30833
  extra_params:
@@ -30716,7 +30841,7 @@ function syncAider(options) {
30716
30841
  } else {
30717
30842
  settingsContent = settingsContent.trimEnd() + (settingsContent.length > 0 ? "\n\n" : "") + modelBlock;
30718
30843
  }
30719
- fs22.writeFileSync(resolvedSettingsPath, settingsContent.trimEnd() + "\n", "utf-8");
30844
+ fs23.writeFileSync(resolvedSettingsPath, settingsContent.trimEnd() + "\n", "utf-8");
30720
30845
  }
30721
30846
  return {
30722
30847
  client: "aider",
@@ -30761,7 +30886,7 @@ var init_aider = __esm({
30761
30886
 
30762
30887
  // src/sync/index.ts
30763
30888
  import "dotenv/config";
30764
- import fs23 from "node:fs";
30889
+ import fs24 from "node:fs";
30765
30890
  import path19 from "node:path";
30766
30891
  import os5 from "node:os";
30767
30892
  import Database3 from "better-sqlite3";
@@ -30801,14 +30926,14 @@ function getDefaultPaths() {
30801
30926
  path19.join(home, ".opencode", "opencode.jsonc"),
30802
30927
  path19.join(home, ".opencode", "opencode.json")
30803
30928
  ];
30804
- const existingOpenCode = openCodeCandidates.find((p) => fs23.existsSync(p));
30929
+ const existingOpenCode = openCodeCandidates.find((p) => fs24.existsSync(p));
30805
30930
  const kiloCandidates = [
30806
30931
  path19.join(home, ".config", "kilo", "kilo.json"),
30807
30932
  path19.join(home, ".kilo", "kilo.json"),
30808
30933
  path19.join(home, ".config", "kilo", "config.json"),
30809
30934
  path19.join(home, ".kilo", "config.json")
30810
30935
  ];
30811
- const existingKilo = kiloCandidates.find((p) => fs23.existsSync(p));
30936
+ const existingKilo = kiloCandidates.find((p) => fs24.existsSync(p));
30812
30937
  let clinePath;
30813
30938
  if (isWindows) {
30814
30939
  clinePath = path19.join(appData, "Code", "User", "globalStorage", "state.vscdb");
@@ -30825,7 +30950,7 @@ function getDefaultPaths() {
30825
30950
  }
30826
30951
  return {
30827
30952
  claudeCode: path19.join(home, ".claude", "settings.json"),
30828
- codex: fs23.existsSync(path19.join(home, ".codex", "config.toml")) ? path19.join(home, ".codex", "config.toml") : process.env.CODEX_HOME ? path19.join(process.env.CODEX_HOME, "config.toml") : path19.join(home, ".codex", "config.toml"),
30953
+ codex: fs24.existsSync(path19.join(home, ".codex", "config.toml")) ? path19.join(home, ".codex", "config.toml") : process.env.CODEX_HOME ? path19.join(process.env.CODEX_HOME, "config.toml") : path19.join(home, ".codex", "config.toml"),
30829
30954
  openCode: existingOpenCode || openCodeCandidates[0],
30830
30955
  omp: path19.join(home, ".omp", "agent", "models.yml"),
30831
30956
  hermes: path19.join(home, ".hermes", "config.yaml"),
@@ -30847,7 +30972,7 @@ function isExecutableInPath(name) {
30847
30972
  for (const ext of extensions) {
30848
30973
  const fullPath = path19.join(dir, name + ext);
30849
30974
  try {
30850
- if (fs23.existsSync(fullPath) && !fs23.statSync(fullPath).isDirectory()) {
30975
+ if (fs24.existsSync(fullPath) && !fs24.statSync(fullPath).isDirectory()) {
30851
30976
  return true;
30852
30977
  }
30853
30978
  } catch {
@@ -30865,9 +30990,9 @@ function isVscodeExtensionInstalled(pattern) {
30865
30990
  path19.join(home, ".windsurf", "extensions")
30866
30991
  ];
30867
30992
  for (const d of candidateDirs) {
30868
- if (fs23.existsSync(d)) {
30993
+ if (fs24.existsSync(d)) {
30869
30994
  try {
30870
- const entries = fs23.readdirSync(d);
30995
+ const entries = fs24.readdirSync(d);
30871
30996
  if (entries.some((e) => pattern.test(e))) return true;
30872
30997
  } catch {
30873
30998
  }
@@ -30879,9 +31004,9 @@ function isZedInstalled() {
30879
31004
  if (isExecutableInPath("zed")) return true;
30880
31005
  if (process.platform === "win32") {
30881
31006
  const local = process.env.LOCALAPPDATA || "";
30882
- if (fs23.existsSync(path19.join(local, "Programs", "Zed"))) return true;
31007
+ if (fs24.existsSync(path19.join(local, "Programs", "Zed"))) return true;
30883
31008
  } else if (process.platform === "darwin") {
30884
- if (fs23.existsSync("/Applications/Zed.app")) return true;
31009
+ if (fs24.existsSync("/Applications/Zed.app")) return true;
30885
31010
  }
30886
31011
  return false;
30887
31012
  }
@@ -30894,7 +31019,7 @@ function isMatchingLocalHost(text, port = 7936) {
30894
31019
  }
30895
31020
  function isClientToolInstalled(id, targetPath, isCustomTestPath = false) {
30896
31021
  if (isCustomTestPath) {
30897
- return fs23.existsSync(targetPath);
31022
+ return fs24.existsSync(targetPath);
30898
31023
  }
30899
31024
  switch (id) {
30900
31025
  case "hermes":
@@ -30910,15 +31035,15 @@ function isClientToolInstalled(id, targetPath, isCustomTestPath = false) {
30910
31035
  case "zed":
30911
31036
  return isZedInstalled();
30912
31037
  case "claude-code":
30913
- return isExecutableInPath("claude") || fs23.existsSync(targetPath);
31038
+ return isExecutableInPath("claude") || fs24.existsSync(targetPath);
30914
31039
  case "codex":
30915
- return isExecutableInPath("codex") || fs23.existsSync(targetPath);
31040
+ return isExecutableInPath("codex") || fs24.existsSync(targetPath);
30916
31041
  case "opencode":
30917
- return isExecutableInPath("opencode") || fs23.existsSync(targetPath);
31042
+ return isExecutableInPath("opencode") || fs24.existsSync(targetPath);
30918
31043
  case "omp":
30919
- return isExecutableInPath("omp") || fs23.existsSync(targetPath);
31044
+ return isExecutableInPath("omp") || fs24.existsSync(targetPath);
30920
31045
  default:
30921
- return fs23.existsSync(targetPath);
31046
+ return fs24.existsSync(targetPath);
30922
31047
  }
30923
31048
  }
30924
31049
  function inspectClientSyncStatus(id, filePath, port = 7936) {
@@ -30928,7 +31053,7 @@ function inspectClientSyncStatus(id, filePath, port = 7936) {
30928
31053
  filePath && defaultTarget && path19.resolve(filePath) !== path19.resolve(defaultTarget)
30929
31054
  );
30930
31055
  const targetPath = filePath || defaultTarget;
30931
- if (!fs23.existsSync(targetPath)) {
31056
+ if (!fs24.existsSync(targetPath)) {
30932
31057
  return { id, installed: false, synced: false };
30933
31058
  }
30934
31059
  const toolInstalled = isClientToolInstalled(id, targetPath, isCustomTestPath);
@@ -30958,7 +31083,7 @@ function inspectClientSyncStatus(id, filePath, port = 7936) {
30958
31083
  const isInstalled = isCustomTestPath ? true : rowExists || isExecutableInPath("cline") || isVscodeExtensionInstalled(/cline|zoo-code|roo-cline/i);
30959
31084
  return { id, installed: isInstalled, synced: isInstalled && isSynced, model };
30960
31085
  }
30961
- const raw = fs23.readFileSync(targetPath, "utf-8");
31086
+ const raw = fs24.readFileSync(targetPath, "utf-8");
30962
31087
  if (id === "claude-code") {
30963
31088
  const data = JSON.parse(raw);
30964
31089
  const url = data?.env?.ANTHROPIC_BASE_URL || "";
@@ -31084,7 +31209,7 @@ function syncAllClients(options = {}) {
31084
31209
  return options.targets.includes(client);
31085
31210
  };
31086
31211
  if (shouldSync("claude-code")) {
31087
- const claudeExisted = fs23.existsSync(paths.claudeCode);
31212
+ const claudeExisted = fs24.existsSync(paths.claudeCode);
31088
31213
  const claudeRes = syncClaudeCode({
31089
31214
  filePath: paths.claudeCode,
31090
31215
  apiKey,
@@ -31102,7 +31227,7 @@ function syncAllClients(options = {}) {
31102
31227
  }
31103
31228
  }
31104
31229
  if (shouldSync("codex")) {
31105
- const codexExisted = fs23.existsSync(paths.codex);
31230
+ const codexExisted = fs24.existsSync(paths.codex);
31106
31231
  const codexRes = syncCodex({
31107
31232
  filePath: paths.codex,
31108
31233
  apiKey,
@@ -31121,7 +31246,7 @@ function syncAllClients(options = {}) {
31121
31246
  }
31122
31247
  }
31123
31248
  if (shouldSync("opencode")) {
31124
- const openCodeExisted = fs23.existsSync(paths.openCode);
31249
+ const openCodeExisted = fs24.existsSync(paths.openCode);
31125
31250
  const openCodeRes = syncOpenCode({
31126
31251
  filePath: paths.openCode,
31127
31252
  apiKey,
@@ -31141,7 +31266,7 @@ function syncAllClients(options = {}) {
31141
31266
  }
31142
31267
  }
31143
31268
  if (shouldSync("omp")) {
31144
- const ompExisted = fs23.existsSync(paths.omp);
31269
+ const ompExisted = fs24.existsSync(paths.omp);
31145
31270
  const ompRes = syncOmp({
31146
31271
  filePath: paths.omp,
31147
31272
  apiKey,
@@ -31160,7 +31285,7 @@ function syncAllClients(options = {}) {
31160
31285
  }
31161
31286
  }
31162
31287
  if (shouldSync("hermes")) {
31163
- const hermesExisted = fs23.existsSync(paths.hermes);
31288
+ const hermesExisted = fs24.existsSync(paths.hermes);
31164
31289
  const hermesRes = syncHermes({
31165
31290
  filePath: paths.hermes,
31166
31291
  apiKey,
@@ -31178,7 +31303,7 @@ function syncAllClients(options = {}) {
31178
31303
  }
31179
31304
  }
31180
31305
  if (shouldSync("openclaw")) {
31181
- const openClawExisted = fs23.existsSync(paths.openClaw);
31306
+ const openClawExisted = fs24.existsSync(paths.openClaw);
31182
31307
  const openClawRes = syncOpenClaw({
31183
31308
  filePath: paths.openClaw,
31184
31309
  apiKey,
@@ -31197,7 +31322,7 @@ function syncAllClients(options = {}) {
31197
31322
  }
31198
31323
  }
31199
31324
  if (shouldSync("kilo")) {
31200
- const kiloExisted = fs23.existsSync(paths.kilo);
31325
+ const kiloExisted = fs24.existsSync(paths.kilo);
31201
31326
  const kiloRes = syncKilo({
31202
31327
  filePath: paths.kilo,
31203
31328
  apiKey,
@@ -31217,7 +31342,7 @@ function syncAllClients(options = {}) {
31217
31342
  }
31218
31343
  }
31219
31344
  if (shouldSync("cline")) {
31220
- const clineExisted = fs23.existsSync(paths.cline);
31345
+ const clineExisted = fs24.existsSync(paths.cline);
31221
31346
  const clineRes = syncCline({
31222
31347
  filePath: paths.cline,
31223
31348
  apiKey,
@@ -31235,7 +31360,7 @@ function syncAllClients(options = {}) {
31235
31360
  }
31236
31361
  }
31237
31362
  if (shouldSync("zed")) {
31238
- const zedExisted = fs23.existsSync(paths.zed);
31363
+ const zedExisted = fs24.existsSync(paths.zed);
31239
31364
  const zedRes = syncZed({
31240
31365
  filePath: paths.zed,
31241
31366
  apiKey,
@@ -31255,7 +31380,7 @@ function syncAllClients(options = {}) {
31255
31380
  }
31256
31381
  }
31257
31382
  if (shouldSync("aider")) {
31258
- const aiderExisted = fs23.existsSync(paths.aider);
31383
+ const aiderExisted = fs24.existsSync(paths.aider);
31259
31384
  const aiderRes = syncAider({
31260
31385
  filePath: paths.aider,
31261
31386
  apiKey,
@@ -31273,11 +31398,11 @@ function syncAllClients(options = {}) {
31273
31398
  }
31274
31399
  }
31275
31400
  try {
31276
- fs23.mkdirSync(path19.dirname(stateFilePath), { recursive: true });
31401
+ fs24.mkdirSync(path19.dirname(stateFilePath), { recursive: true });
31277
31402
  let existingClients = {};
31278
- if (fs23.existsSync(stateFilePath)) {
31403
+ if (fs24.existsSync(stateFilePath)) {
31279
31404
  try {
31280
- const raw = fs23.readFileSync(stateFilePath, "utf-8");
31405
+ const raw = fs24.readFileSync(stateFilePath, "utf-8");
31281
31406
  const parsed = JSON.parse(raw);
31282
31407
  if (parsed?.clients && typeof parsed.clients === "object") {
31283
31408
  existingClients = parsed.clients;
@@ -31296,7 +31421,7 @@ function syncAllClients(options = {}) {
31296
31421
  ...stateRecords
31297
31422
  }
31298
31423
  };
31299
- fs23.writeFileSync(stateFilePath, JSON.stringify(stateContent, null, 2) + "\n", "utf-8");
31424
+ fs24.writeFileSync(stateFilePath, JSON.stringify(stateContent, null, 2) + "\n", "utf-8");
31300
31425
  } catch (err) {
31301
31426
  console.error("Warning: could not write sync state file:", err);
31302
31427
  }
@@ -31308,9 +31433,9 @@ function restoreAllClients(options = {}) {
31308
31433
  const details = [];
31309
31434
  let restoredCount = 0;
31310
31435
  let state = null;
31311
- if (fs23.existsSync(stateFilePath)) {
31436
+ if (fs24.existsSync(stateFilePath)) {
31312
31437
  try {
31313
- const raw = fs23.readFileSync(stateFilePath, "utf-8");
31438
+ const raw = fs24.readFileSync(stateFilePath, "utf-8");
31314
31439
  state = JSON.parse(raw);
31315
31440
  } catch {
31316
31441
  }
@@ -31335,7 +31460,7 @@ function restoreAllClients(options = {}) {
31335
31460
  if (!shouldRestore(c.id)) continue;
31336
31461
  const filePath = c.stateRecord?.filePath || c.defaultPath;
31337
31462
  const backupPath = c.stateRecord?.backupPath;
31338
- const canAttempt = options.stateFilePath ? Boolean(c.stateRecord) : Boolean(c.stateRecord || fs23.existsSync(filePath));
31463
+ const canAttempt = options.stateFilePath ? Boolean(c.stateRecord) : Boolean(c.stateRecord || fs24.existsSync(filePath));
31339
31464
  if (canAttempt) {
31340
31465
  const res = c.restoreFn(filePath, backupPath);
31341
31466
  details.push(res);
@@ -31348,12 +31473,12 @@ function restoreAllClients(options = {}) {
31348
31473
  }
31349
31474
  }
31350
31475
  }
31351
- if (stateFilePath && fs23.existsSync(stateFilePath)) {
31476
+ if (stateFilePath && fs24.existsSync(stateFilePath)) {
31352
31477
  try {
31353
31478
  if (state && state.clients && Object.keys(state.clients).length > 0) {
31354
- fs23.writeFileSync(stateFilePath, JSON.stringify(state, null, 2) + "\n", "utf-8");
31479
+ fs24.writeFileSync(stateFilePath, JSON.stringify(state, null, 2) + "\n", "utf-8");
31355
31480
  } else {
31356
- fs23.unlinkSync(stateFilePath);
31481
+ fs24.unlinkSync(stateFilePath);
31357
31482
  }
31358
31483
  } catch {
31359
31484
  }
@@ -31790,7 +31915,7 @@ var init_sync_view = __esm({
31790
31915
  });
31791
31916
 
31792
31917
  // src/tui/views/storage-view.ts
31793
- import fs24 from "node:fs";
31918
+ import fs25 from "node:fs";
31794
31919
  import path20 from "node:path";
31795
31920
  var StorageView;
31796
31921
  var init_storage_view = __esm({
@@ -31856,8 +31981,8 @@ var init_storage_view = __esm({
31856
31981
  let totalBytes = 0;
31857
31982
  let count = 0;
31858
31983
  this.profileStats = [];
31859
- if (fs24.existsSync(profilesDir)) {
31860
- const entries = fs24.readdirSync(profilesDir, { withFileTypes: true });
31984
+ if (fs25.existsSync(profilesDir)) {
31985
+ const entries = fs25.readdirSync(profilesDir, { withFileTypes: true });
31861
31986
  for (const entry of entries) {
31862
31987
  if (entry.isDirectory()) {
31863
31988
  count++;
@@ -33892,8 +34017,8 @@ var init_app = __esm({
33892
34017
  // src/index.ts
33893
34018
  init_paths();
33894
34019
  init_server();
33895
- import dotenv from "dotenv";
33896
- import fs25 from "node:fs";
34020
+ import dotenv2 from "dotenv";
34021
+ import fs26 from "node:fs";
33897
34022
  try {
33898
34023
  process.title = "QwenProxy";
33899
34024
  } catch {
@@ -33901,10 +34026,10 @@ try {
33901
34026
  process.env.DOTENV_CONFIG_QUIET = "true";
33902
34027
  ensureDataDirs();
33903
34028
  var envPath = getEnvFilePath();
33904
- if (fs25.existsSync(envPath)) {
33905
- dotenv.config({ path: envPath, quiet: true });
34029
+ if (fs26.existsSync(envPath)) {
34030
+ dotenv2.config({ path: envPath, quiet: true });
33906
34031
  } else {
33907
- dotenv.config({ quiet: true });
34032
+ dotenv2.config({ quiet: true });
33908
34033
  }
33909
34034
  process.on("uncaughtException", async (error) => {
33910
34035
  const { isPlaywrightAlreadyClosedError: isPlaywrightAlreadyClosedError2 } = await Promise.resolve().then(() => (init_playwright(), playwright_exports));