@kenkaiiii/gg-core 5.87.2 → 5.87.3

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.cjs CHANGED
@@ -70,8 +70,8 @@ __export(index_exports, {
70
70
  getAuthProvider: () => getAuthProvider,
71
71
  getAuthStorageKey: () => getAuthStorageKey,
72
72
  getAuthStorageKeys: () => getAuthStorageKeys,
73
- getClaudeCliUserAgent: () => getClaudeCliUserAgent,
74
- getClaudeCodeVersion: () => getClaudeCodeVersion,
73
+ getClaudeCliUserAgent: () => import_gg_ai.getClaudeCliUserAgent,
74
+ getClaudeCodeVersion: () => import_gg_ai.getClaudeCodeVersion,
75
75
  getContextWindow: () => getContextWindow,
76
76
  getDefaultModel: () => getDefaultModel,
77
77
  getDefaultThinkingLevel: () => getDefaultThinkingLevel,
@@ -108,7 +108,7 @@ __export(index_exports, {
108
108
  oauthStorageKey: () => oauthStorageKey,
109
109
  openLog: () => openLog,
110
110
  parseLocalModelId: () => parseLocalModelId,
111
- pendingClaudeCodeVersionRefresh: () => pendingClaudeCodeVersionRefresh,
111
+ pendingClaudeCodeVersionRefresh: () => import_gg_ai.pendingClaudeCodeVersionRefresh,
112
112
  probeEndpoint: () => probeEndpoint,
113
113
  providerStorageKeys: () => providerStorageKeys,
114
114
  readStoredBaseUrlSync: () => readStoredBaseUrlSync,
@@ -384,12 +384,12 @@ async function refreshKimiToken(refreshToken) {
384
384
  }
385
385
 
386
386
  // src/auth-storage.ts
387
- var import_promises4 = __toESM(require("fs/promises"), 1);
387
+ var import_promises3 = __toESM(require("fs/promises"), 1);
388
388
  var import_node_fs3 = require("fs");
389
389
  var import_node_crypto6 = __toESM(require("crypto"), 1);
390
390
 
391
391
  // src/oauth/anthropic.ts
392
- var import_node_crypto3 = __toESM(require("crypto"), 1);
392
+ var import_node_crypto2 = __toESM(require("crypto"), 1);
393
393
 
394
394
  // src/oauth/pkce.ts
395
395
  function base64urlEncode(bytes) {
@@ -410,283 +410,7 @@ async function generatePKCE() {
410
410
  }
411
411
 
412
412
  // src/claude-code-version.ts
413
- var import_promises = __toESM(require("fs/promises"), 1);
414
- var import_node_path4 = __toESM(require("path"), 1);
415
-
416
- // src/logger.ts
417
- var import_node_fs2 = __toESM(require("fs"), 1);
418
- var import_node_path3 = __toESM(require("path"), 1);
419
- var import_node_crypto2 = require("crypto");
420
413
  var import_gg_ai = require("@kenkaiiii/gg-ai");
421
- var MAX_BYTES = 10 * 1024 * 1024;
422
- var MIN_HEADROOM_BYTES = 64 * 1024;
423
- var fd = null;
424
- var logPath = null;
425
- var fileBytes = 0;
426
- var processBytes = 0;
427
- var rotationFailed = false;
428
- var capped = false;
429
- var sessionId = "";
430
- var appName = "app";
431
- var cleanups = [];
432
- var exactSecrets = [];
433
- function rotateIfNeeded(filePath, force = false) {
434
- try {
435
- const st = import_node_fs2.default.statSync(filePath);
436
- if (!force && st.size <= MAX_BYTES - MIN_HEADROOM_BYTES) return;
437
- const rotated = `${filePath}.1`;
438
- try {
439
- import_node_fs2.default.unlinkSync(rotated);
440
- } catch {
441
- }
442
- import_node_fs2.default.renameSync(filePath, rotated);
443
- } catch {
444
- }
445
- }
446
- function rotateOpenLog() {
447
- if (fd === null || logPath === null) return false;
448
- const sizeBefore = fileBytes;
449
- try {
450
- import_node_fs2.default.closeSync(fd);
451
- } catch {
452
- }
453
- fd = null;
454
- rotateIfNeeded(logPath, true);
455
- try {
456
- fd = import_node_fs2.default.openSync(logPath, "a");
457
- fileBytes = import_node_fs2.default.fstatSync(fd).size;
458
- } catch {
459
- if (fd !== null) {
460
- try {
461
- import_node_fs2.default.closeSync(fd);
462
- } catch {
463
- }
464
- }
465
- fd = null;
466
- capped = true;
467
- return false;
468
- }
469
- if (fileBytes >= sizeBefore) rotationFailed = true;
470
- return true;
471
- }
472
- function openLog(filePath, name) {
473
- if (fd !== null || capped) return false;
474
- appName = name;
475
- exactSecrets = (0, import_gg_ai.environmentSecrets)(process.env);
476
- try {
477
- import_node_fs2.default.mkdirSync(import_node_path3.default.dirname(filePath), { recursive: true, mode: 448 });
478
- } catch {
479
- }
480
- rotateIfNeeded(filePath);
481
- try {
482
- fd = import_node_fs2.default.openSync(filePath, "a");
483
- } catch {
484
- fd = null;
485
- fileBytes = 0;
486
- return false;
487
- }
488
- try {
489
- fileBytes = import_node_fs2.default.fstatSync(fd).size;
490
- } catch {
491
- try {
492
- import_node_fs2.default.closeSync(fd);
493
- } catch {
494
- }
495
- fd = null;
496
- fileBytes = 0;
497
- return false;
498
- }
499
- logPath = filePath;
500
- processBytes = 0;
501
- rotationFailed = false;
502
- sessionId = (0, import_node_crypto2.randomBytes)(4).toString("hex");
503
- try {
504
- if (fileBytes < MAX_BYTES) {
505
- const written = import_node_fs2.default.writeSync(fd, "\n");
506
- fileBytes += written;
507
- processBytes += written;
508
- }
509
- } catch {
510
- }
511
- return true;
512
- }
513
- function getSessionId() {
514
- return sessionId;
515
- }
516
- function isLoggerOpen() {
517
- return fd !== null;
518
- }
519
- function log(level, category, message, data) {
520
- if (fd === null) return;
521
- const ts = (/* @__PURE__ */ new Date()).toISOString();
522
- const safeMessage = (0, import_gg_ai.redactText)(message, { secrets: exactSecrets });
523
- let line = `[${ts}] [sid=${sessionId}] [${level}] [${category}] ${safeMessage}`;
524
- if (data) {
525
- const safeData = (0, import_gg_ai.redactValue)(data, { secrets: exactSecrets });
526
- const pairs = Object.entries(safeData).map(([k, v]) => {
527
- if (typeof v === "string") return `${k}=${v}`;
528
- if (typeof v === "bigint") return `${k}=${String(v)}`;
529
- return `${k}=${JSON.stringify(v)}`;
530
- }).join(" ");
531
- if (pairs) line += ` ${pairs}`;
532
- }
533
- line += "\n";
534
- const lineBytes = Buffer.byteLength(line);
535
- if (processBytes + lineBytes > MAX_BYTES) {
536
- const capLine = `[${ts}] [sid=${sessionId}] [WARN] [logger] Log cap reached; file logging disabled until restart
537
- `;
538
- try {
539
- if (fileBytes + Buffer.byteLength(capLine) <= MAX_BYTES) {
540
- fileBytes += import_node_fs2.default.writeSync(fd, capLine);
541
- }
542
- import_node_fs2.default.closeSync(fd);
543
- } catch {
544
- }
545
- fd = null;
546
- capped = true;
547
- return;
548
- }
549
- if (fileBytes + lineBytes > MAX_BYTES && !rotationFailed && !rotateOpenLog()) return;
550
- if (fd === null) return;
551
- try {
552
- const written = import_node_fs2.default.writeSync(fd, line);
553
- fileBytes += written;
554
- processBytes += written;
555
- } catch {
556
- }
557
- }
558
- function registerLogCleanup(fn) {
559
- cleanups.push(fn);
560
- }
561
- function closeLogger(opts) {
562
- if (fd !== null) {
563
- if (opts?.shutdownLine !== false) log("INFO", "shutdown", `${appName} shutting down`);
564
- try {
565
- if (fd !== null) import_node_fs2.default.closeSync(fd);
566
- } catch {
567
- }
568
- }
569
- fd = null;
570
- logPath = null;
571
- fileBytes = 0;
572
- processBytes = 0;
573
- rotationFailed = false;
574
- capped = false;
575
- exactSecrets = [];
576
- for (const unsub of cleanups) unsub();
577
- cleanups = [];
578
- }
579
-
580
- // src/claude-code-version.ts
581
- var NPM_LATEST_URL = "https://registry.npmjs.org/@anthropic-ai/claude-code/latest";
582
- var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
583
- var FETCH_TIMEOUT_MS = 3e3;
584
- var FALLBACK_VERSION = "2.1.88";
585
- var memoryCache = null;
586
- var inflight = null;
587
- function cachePath() {
588
- return import_node_path4.default.join(getAppPaths().agentDir, "claude-code-version.json");
589
- }
590
- async function readDiskCache() {
591
- try {
592
- const raw = await import_promises.default.readFile(cachePath(), "utf-8");
593
- const parsed = JSON.parse(raw);
594
- if (typeof parsed.version === "string" && typeof parsed.fetchedAt === "number") {
595
- return parsed;
596
- }
597
- return null;
598
- } catch {
599
- return null;
600
- }
601
- }
602
- async function writeDiskCache(data) {
603
- try {
604
- await import_promises.default.mkdir(getAppPaths().agentDir, { recursive: true, mode: 448 });
605
- await import_promises.default.writeFile(cachePath(), JSON.stringify(data), { mode: 384 });
606
- } catch (err) {
607
- log(
608
- "WARN",
609
- "claude-code-version",
610
- `Failed to write cache: ${err instanceof Error ? err.message : String(err)}`
611
- );
612
- }
613
- }
614
- async function fetchLatest() {
615
- const controller = new AbortController();
616
- const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
617
- try {
618
- const response = await fetch(NPM_LATEST_URL, { signal: controller.signal });
619
- if (!response.ok) return null;
620
- const data = await response.json();
621
- if (typeof data.version === "string" && /^\d/.test(data.version)) {
622
- return data.version;
623
- }
624
- return null;
625
- } catch {
626
- return null;
627
- } finally {
628
- clearTimeout(timer);
629
- }
630
- }
631
- var refreshing = null;
632
- function refreshInBackground() {
633
- refreshing ??= (async () => {
634
- try {
635
- const fetched = await fetchLatest();
636
- if (!fetched) return;
637
- await writeDiskCache({ version: fetched, fetchedAt: Date.now() });
638
- memoryCache = { version: fetched, expiresAt: Date.now() + CACHE_TTL_MS };
639
- } finally {
640
- refreshing = null;
641
- }
642
- })();
643
- return refreshing;
644
- }
645
- function pendingClaudeCodeVersionRefresh() {
646
- return refreshing;
647
- }
648
- async function getClaudeCodeVersion() {
649
- if (memoryCache && Date.now() < memoryCache.expiresAt) {
650
- return memoryCache.version;
651
- }
652
- if (inflight) return inflight;
653
- inflight = (async () => {
654
- const disk = await readDiskCache();
655
- const diskFresh = disk && Date.now() - disk.fetchedAt < CACHE_TTL_MS;
656
- if (disk && diskFresh) {
657
- memoryCache = { version: disk.version, expiresAt: Date.now() + CACHE_TTL_MS };
658
- return disk.version;
659
- }
660
- if (disk) {
661
- memoryCache = { version: disk.version, expiresAt: Date.now() + 5 * 60 * 1e3 };
662
- void refreshInBackground();
663
- return disk.version;
664
- }
665
- const fetched = await fetchLatest();
666
- if (fetched) {
667
- await writeDiskCache({ version: fetched, fetchedAt: Date.now() });
668
- memoryCache = { version: fetched, expiresAt: Date.now() + CACHE_TTL_MS };
669
- return fetched;
670
- }
671
- const resolved = FALLBACK_VERSION;
672
- memoryCache = { version: resolved, expiresAt: Date.now() + 5 * 60 * 1e3 };
673
- log(
674
- "WARN",
675
- "claude-code-version",
676
- `Failed to fetch latest Claude Code version; using ${resolved}`
677
- );
678
- return resolved;
679
- })();
680
- try {
681
- return await inflight;
682
- } finally {
683
- inflight = null;
684
- }
685
- }
686
- async function getClaudeCliUserAgent() {
687
- const version = await getClaudeCodeVersion();
688
- return `claude-cli/${version} (external, cli)`;
689
- }
690
414
 
691
415
  // src/oauth/anthropic.ts
692
416
  var CLIENT_ID2 = atob("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
@@ -701,7 +425,7 @@ async function postTokenRequest(body, label) {
701
425
  const encoded = JSON.stringify(body);
702
426
  const headers = {
703
427
  "Content-Type": "application/json",
704
- "User-Agent": await getClaudeCliUserAgent(),
428
+ "User-Agent": await (0, import_gg_ai.getClaudeCliUserAgent)(),
705
429
  "anthropic-beta": "oauth-2025-04-20"
706
430
  };
707
431
  let lastError = null;
@@ -738,7 +462,7 @@ function toCredentials(data) {
738
462
  }
739
463
  async function loginAnthropic(callbacks) {
740
464
  const { verifier, challenge } = await generatePKCE();
741
- const state = import_node_crypto3.default.randomBytes(16).toString("hex");
465
+ const state = import_node_crypto2.default.randomBytes(16).toString("hex");
742
466
  const params = new URLSearchParams({
743
467
  code: "true",
744
468
  client_id: CLIENT_ID2,
@@ -786,7 +510,7 @@ async function refreshAnthropicToken(refreshToken) {
786
510
 
787
511
  // src/oauth/openai.ts
788
512
  var import_node_http = __toESM(require("http"), 1);
789
- var import_node_crypto4 = __toESM(require("crypto"), 1);
513
+ var import_node_crypto3 = __toESM(require("crypto"), 1);
790
514
  var CLIENT_ID3 = "app_EMoamEEZ73f0CkXaXp7hrann";
791
515
  var AUTHORIZE_URL2 = "https://auth.openai.com/oauth/authorize";
792
516
  var TOKEN_URL = "https://auth.openai.com/oauth/token";
@@ -798,7 +522,7 @@ var MAX_PASTE_ATTEMPTS = 3;
798
522
  var MIN_RAW_CODE_LENGTH = 10;
799
523
  async function loginOpenAI(callbacks) {
800
524
  const { verifier, challenge } = await generatePKCE();
801
- const state = import_node_crypto4.default.randomBytes(16).toString("hex");
525
+ const state = import_node_crypto3.default.randomBytes(16).toString("hex");
802
526
  const url = new URL(AUTHORIZE_URL2);
803
527
  url.searchParams.set("response_type", "code");
804
528
  url.searchParams.set("client_id", CLIENT_ID3);
@@ -1006,7 +730,7 @@ async function refreshOpenAIToken(refreshToken) {
1006
730
 
1007
731
  // src/oauth/gemini.ts
1008
732
  var import_node_http2 = __toESM(require("http"), 1);
1009
- var import_node_crypto5 = __toESM(require("crypto"), 1);
733
+ var import_node_crypto4 = __toESM(require("crypto"), 1);
1010
734
  var CLIENT_ID_ENV = "GGCODER_GEMINI_OAUTH_CLIENT_ID";
1011
735
  var CLIENT_SECRET_ENV = "GGCODER_GEMINI_OAUTH_CLIENT_SECRET";
1012
736
  var DEFAULT_CLIENT_ID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com";
@@ -1040,7 +764,7 @@ var CodeAssistHttpError = class extends Error {
1040
764
  async function loginGemini(callbacks) {
1041
765
  const { clientId: clientId2, clientSecret } = getGeminiOAuthClientCredentials();
1042
766
  const { verifier, challenge } = await generatePKCE();
1043
- const state = import_node_crypto5.default.randomBytes(32).toString("hex");
767
+ const state = import_node_crypto4.default.randomBytes(32).toString("hex");
1044
768
  const redirectUri = await getLoopbackRedirectUri();
1045
769
  const url = new URL(AUTHORIZE_URL3);
1046
770
  url.searchParams.set("response_type", "code");
@@ -1569,8 +1293,8 @@ async function refreshXaiToken(refreshToken) {
1569
1293
  }
1570
1294
 
1571
1295
  // src/file-lock.ts
1572
- var import_promises2 = __toESM(require("fs/promises"), 1);
1573
- var import_promises3 = require("timers/promises");
1296
+ var import_promises = __toESM(require("fs/promises"), 1);
1297
+ var import_promises2 = require("timers/promises");
1574
1298
  var STALE_TIMEOUT_MS = 1e4;
1575
1299
  var RETRY_INTERVAL_MS = 50;
1576
1300
  var MAX_WAIT_MS = 5e3;
@@ -1588,36 +1312,36 @@ async function acquireLock(lockPath) {
1588
1312
  while (true) {
1589
1313
  try {
1590
1314
  const info = { pid: process.pid, timestamp: Date.now() };
1591
- await import_promises2.default.writeFile(lockPath, JSON.stringify(info), { flag: "wx" });
1315
+ await import_promises.default.writeFile(lockPath, JSON.stringify(info), { flag: "wx" });
1592
1316
  return;
1593
1317
  } catch (err) {
1594
1318
  if (err.code !== "EEXIST") throw err;
1595
1319
  try {
1596
- const content = await import_promises2.default.readFile(lockPath, "utf-8");
1320
+ const content = await import_promises.default.readFile(lockPath, "utf-8");
1597
1321
  const info = JSON.parse(content);
1598
1322
  const isProcessAlive = isAlive(info.pid);
1599
1323
  const isStale = Date.now() - info.timestamp > STALE_TIMEOUT_MS;
1600
1324
  if (!isProcessAlive || isStale) {
1601
- await import_promises2.default.unlink(lockPath).catch(() => {
1325
+ await import_promises.default.unlink(lockPath).catch(() => {
1602
1326
  });
1603
1327
  continue;
1604
1328
  }
1605
1329
  } catch {
1606
- await import_promises2.default.unlink(lockPath).catch(() => {
1330
+ await import_promises.default.unlink(lockPath).catch(() => {
1607
1331
  });
1608
1332
  continue;
1609
1333
  }
1610
1334
  if (Date.now() - startTime > MAX_WAIT_MS) {
1611
- await import_promises2.default.unlink(lockPath).catch(() => {
1335
+ await import_promises.default.unlink(lockPath).catch(() => {
1612
1336
  });
1613
1337
  continue;
1614
1338
  }
1615
- await (0, import_promises3.setTimeout)(RETRY_INTERVAL_MS);
1339
+ await (0, import_promises2.setTimeout)(RETRY_INTERVAL_MS);
1616
1340
  }
1617
1341
  }
1618
1342
  }
1619
1343
  async function releaseLock(lockPath) {
1620
- await import_promises2.default.unlink(lockPath).catch(() => {
1344
+ await import_promises.default.unlink(lockPath).catch(() => {
1621
1345
  });
1622
1346
  }
1623
1347
  function isAlive(pid) {
@@ -1630,6 +1354,170 @@ function isAlive(pid) {
1630
1354
  }
1631
1355
  }
1632
1356
 
1357
+ // src/logger.ts
1358
+ var import_node_fs2 = __toESM(require("fs"), 1);
1359
+ var import_node_path3 = __toESM(require("path"), 1);
1360
+ var import_node_crypto5 = require("crypto");
1361
+ var import_gg_ai2 = require("@kenkaiiii/gg-ai");
1362
+ var MAX_BYTES = 10 * 1024 * 1024;
1363
+ var MIN_HEADROOM_BYTES = 64 * 1024;
1364
+ var fd = null;
1365
+ var logPath = null;
1366
+ var fileBytes = 0;
1367
+ var processBytes = 0;
1368
+ var rotationFailed = false;
1369
+ var capped = false;
1370
+ var sessionId = "";
1371
+ var appName = "app";
1372
+ var cleanups = [];
1373
+ var exactSecrets = [];
1374
+ function rotateIfNeeded(filePath, force = false) {
1375
+ try {
1376
+ const st = import_node_fs2.default.statSync(filePath);
1377
+ if (!force && st.size <= MAX_BYTES - MIN_HEADROOM_BYTES) return;
1378
+ const rotated = `${filePath}.1`;
1379
+ try {
1380
+ import_node_fs2.default.unlinkSync(rotated);
1381
+ } catch {
1382
+ }
1383
+ import_node_fs2.default.renameSync(filePath, rotated);
1384
+ } catch {
1385
+ }
1386
+ }
1387
+ function rotateOpenLog() {
1388
+ if (fd === null || logPath === null) return false;
1389
+ const sizeBefore = fileBytes;
1390
+ try {
1391
+ import_node_fs2.default.closeSync(fd);
1392
+ } catch {
1393
+ }
1394
+ fd = null;
1395
+ rotateIfNeeded(logPath, true);
1396
+ try {
1397
+ fd = import_node_fs2.default.openSync(logPath, "a");
1398
+ fileBytes = import_node_fs2.default.fstatSync(fd).size;
1399
+ } catch {
1400
+ if (fd !== null) {
1401
+ try {
1402
+ import_node_fs2.default.closeSync(fd);
1403
+ } catch {
1404
+ }
1405
+ }
1406
+ fd = null;
1407
+ capped = true;
1408
+ return false;
1409
+ }
1410
+ if (fileBytes >= sizeBefore) rotationFailed = true;
1411
+ return true;
1412
+ }
1413
+ function openLog(filePath, name) {
1414
+ if (fd !== null || capped) return false;
1415
+ appName = name;
1416
+ exactSecrets = (0, import_gg_ai2.environmentSecrets)(process.env);
1417
+ try {
1418
+ import_node_fs2.default.mkdirSync(import_node_path3.default.dirname(filePath), { recursive: true, mode: 448 });
1419
+ } catch {
1420
+ }
1421
+ rotateIfNeeded(filePath);
1422
+ try {
1423
+ fd = import_node_fs2.default.openSync(filePath, "a");
1424
+ } catch {
1425
+ fd = null;
1426
+ fileBytes = 0;
1427
+ return false;
1428
+ }
1429
+ try {
1430
+ fileBytes = import_node_fs2.default.fstatSync(fd).size;
1431
+ } catch {
1432
+ try {
1433
+ import_node_fs2.default.closeSync(fd);
1434
+ } catch {
1435
+ }
1436
+ fd = null;
1437
+ fileBytes = 0;
1438
+ return false;
1439
+ }
1440
+ logPath = filePath;
1441
+ processBytes = 0;
1442
+ rotationFailed = false;
1443
+ sessionId = (0, import_node_crypto5.randomBytes)(4).toString("hex");
1444
+ try {
1445
+ if (fileBytes < MAX_BYTES) {
1446
+ const written = import_node_fs2.default.writeSync(fd, "\n");
1447
+ fileBytes += written;
1448
+ processBytes += written;
1449
+ }
1450
+ } catch {
1451
+ }
1452
+ return true;
1453
+ }
1454
+ function getSessionId() {
1455
+ return sessionId;
1456
+ }
1457
+ function isLoggerOpen() {
1458
+ return fd !== null;
1459
+ }
1460
+ function log(level, category, message, data) {
1461
+ if (fd === null) return;
1462
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
1463
+ const safeMessage = (0, import_gg_ai2.redactText)(message, { secrets: exactSecrets });
1464
+ let line = `[${ts}] [sid=${sessionId}] [${level}] [${category}] ${safeMessage}`;
1465
+ if (data) {
1466
+ const safeData = (0, import_gg_ai2.redactValue)(data, { secrets: exactSecrets });
1467
+ const pairs = Object.entries(safeData).map(([k, v]) => {
1468
+ if (typeof v === "string") return `${k}=${v}`;
1469
+ if (typeof v === "bigint") return `${k}=${String(v)}`;
1470
+ return `${k}=${JSON.stringify(v)}`;
1471
+ }).join(" ");
1472
+ if (pairs) line += ` ${pairs}`;
1473
+ }
1474
+ line += "\n";
1475
+ const lineBytes = Buffer.byteLength(line);
1476
+ if (processBytes + lineBytes > MAX_BYTES) {
1477
+ const capLine = `[${ts}] [sid=${sessionId}] [WARN] [logger] Log cap reached; file logging disabled until restart
1478
+ `;
1479
+ try {
1480
+ if (fileBytes + Buffer.byteLength(capLine) <= MAX_BYTES) {
1481
+ fileBytes += import_node_fs2.default.writeSync(fd, capLine);
1482
+ }
1483
+ import_node_fs2.default.closeSync(fd);
1484
+ } catch {
1485
+ }
1486
+ fd = null;
1487
+ capped = true;
1488
+ return;
1489
+ }
1490
+ if (fileBytes + lineBytes > MAX_BYTES && !rotationFailed && !rotateOpenLog()) return;
1491
+ if (fd === null) return;
1492
+ try {
1493
+ const written = import_node_fs2.default.writeSync(fd, line);
1494
+ fileBytes += written;
1495
+ processBytes += written;
1496
+ } catch {
1497
+ }
1498
+ }
1499
+ function registerLogCleanup(fn) {
1500
+ cleanups.push(fn);
1501
+ }
1502
+ function closeLogger(opts) {
1503
+ if (fd !== null) {
1504
+ if (opts?.shutdownLine !== false) log("INFO", "shutdown", `${appName} shutting down`);
1505
+ try {
1506
+ if (fd !== null) import_node_fs2.default.closeSync(fd);
1507
+ } catch {
1508
+ }
1509
+ }
1510
+ fd = null;
1511
+ logPath = null;
1512
+ fileBytes = 0;
1513
+ processBytes = 0;
1514
+ rotationFailed = false;
1515
+ capped = false;
1516
+ exactSecrets = [];
1517
+ for (const unsub of cleanups) unsub();
1518
+ cleanups = [];
1519
+ }
1520
+
1633
1521
  // src/hidden-providers.ts
1634
1522
  var HIDDEN_PROVIDERS = ["gemini"];
1635
1523
  function isHiddenProvider(provider) {
@@ -1836,7 +1724,7 @@ var AuthStorage = class {
1836
1724
  const first = !this.loaded;
1837
1725
  await withFileLock(this.filePath, async () => {
1838
1726
  try {
1839
- const content = await import_promises4.default.readFile(this.filePath, "utf-8");
1727
+ const content = await import_promises3.default.readFile(this.filePath, "utf-8");
1840
1728
  this.data = JSON.parse(content);
1841
1729
  if (first) {
1842
1730
  log("INFO", "auth", `Loaded credentials from ${this.filePath}`, {
@@ -1882,7 +1770,7 @@ var AuthStorage = class {
1882
1770
  }
1883
1771
  let changed;
1884
1772
  try {
1885
- const stat = await import_promises4.default.stat(this.filePath);
1773
+ const stat = await import_promises3.default.stat(this.filePath);
1886
1774
  changed = stat.ino !== this.snapshotIno || stat.mtimeMs !== this.snapshotMtimeMs || stat.size !== this.snapshotSize;
1887
1775
  } catch {
1888
1776
  changed = this.snapshotSize !== -1;
@@ -1895,7 +1783,7 @@ var AuthStorage = class {
1895
1783
  */
1896
1784
  async rememberSnapshot() {
1897
1785
  try {
1898
- const stat = await import_promises4.default.stat(this.filePath);
1786
+ const stat = await import_promises3.default.stat(this.filePath);
1899
1787
  this.snapshotMtimeMs = stat.mtimeMs;
1900
1788
  this.snapshotSize = stat.size;
1901
1789
  this.snapshotIno = stat.ino;
@@ -2136,7 +2024,7 @@ var AuthStorage = class {
2136
2024
  };
2137
2025
  async function readAuthData(filePath) {
2138
2026
  try {
2139
- const content = await import_promises4.default.readFile(filePath, "utf-8");
2027
+ const content = await import_promises3.default.readFile(filePath, "utf-8");
2140
2028
  return JSON.parse(content);
2141
2029
  } catch (error) {
2142
2030
  if (error.code === "ENOENT") return {};
@@ -2146,10 +2034,10 @@ async function readAuthData(filePath) {
2146
2034
  async function atomicWriteFile(filePath, content) {
2147
2035
  const tmpPath = `${filePath}.${process.pid}.${Date.now()}.${import_node_crypto6.default.randomUUID().slice(0, 8)}.tmp`;
2148
2036
  try {
2149
- await import_promises4.default.writeFile(tmpPath, content, { encoding: "utf-8", mode: 384 });
2150
- await import_promises4.default.rename(tmpPath, filePath);
2037
+ await import_promises3.default.writeFile(tmpPath, content, { encoding: "utf-8", mode: 384 });
2038
+ await import_promises3.default.rename(tmpPath, filePath);
2151
2039
  } catch (err) {
2152
- await import_promises4.default.unlink(tmpPath).catch(() => {
2040
+ await import_promises3.default.unlink(tmpPath).catch(() => {
2153
2041
  });
2154
2042
  throw err;
2155
2043
  }
@@ -3147,7 +3035,7 @@ var FALLBACK_CONTEXT_WINDOW = 4096;
3147
3035
  var LOCAL_API_KEY_PLACEHOLDER = "local";
3148
3036
  var DEFAULT_PROBE_TIMEOUT_MS = 1200;
3149
3037
  var ENRICH_CONCURRENCY = 6;
3150
- var CACHE_TTL_MS2 = 3e4;
3038
+ var CACHE_TTL_MS = 3e4;
3151
3039
  var NON_CHAT_ID_PATTERN = /(?:^|[-_/])(?:embed|embedding|rerank|reranker|bge|nomic-embed)/i;
3152
3040
  var LOCAL_ID_PREFIX = "local/";
3153
3041
  function formatLocalModelId(endpointId, rawId) {
@@ -3388,7 +3276,7 @@ function cacheKey(endpoints) {
3388
3276
  }
3389
3277
  async function discoverLocalModels(endpoints = DEFAULT_LOCAL_ENDPOINTS, options = {}) {
3390
3278
  const key = cacheKey(endpoints);
3391
- if (!options.force && cache && cache.key === key && Date.now() - cache.at < CACHE_TTL_MS2) {
3279
+ if (!options.force && cache && cache.key === key && Date.now() - cache.at < CACHE_TTL_MS) {
3392
3280
  return cache.result;
3393
3281
  }
3394
3282
  const probes = await Promise.all(endpoints.map((endpoint) => probeEndpoint(endpoint, options)));
@@ -4161,9 +4049,9 @@ async function transcribeVoice(fileUrl) {
4161
4049
  // src/auto-update.ts
4162
4050
  var import_node_child_process2 = require("child_process");
4163
4051
  var import_node_fs4 = __toESM(require("fs"), 1);
4164
- var import_node_path5 = __toESM(require("path"), 1);
4052
+ var import_node_path4 = __toESM(require("path"), 1);
4165
4053
  var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
4166
- var FETCH_TIMEOUT_MS2 = 1e4;
4054
+ var FETCH_TIMEOUT_MS = 1e4;
4167
4055
  function compareVersions(a, b) {
4168
4056
  const pa = a.split(".").map(Number);
4169
4057
  const pb = b.split(".").map(Number);
@@ -4203,7 +4091,7 @@ function createAutoUpdater(config) {
4203
4091
  function writeState(state) {
4204
4092
  try {
4205
4093
  const filePath = stateFilePath();
4206
- import_node_fs4.default.mkdirSync(import_node_path5.default.dirname(filePath), { recursive: true, mode: 448 });
4094
+ import_node_fs4.default.mkdirSync(import_node_path4.default.dirname(filePath), { recursive: true, mode: 448 });
4207
4095
  import_node_fs4.default.writeFileSync(filePath, JSON.stringify(state));
4208
4096
  } catch {
4209
4097
  }
@@ -4233,7 +4121,7 @@ function createAutoUpdater(config) {
4233
4121
  async function fetchLatestVersion() {
4234
4122
  try {
4235
4123
  const controller = new AbortController();
4236
- const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS2);
4124
+ const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
4237
4125
  const response = await fetch(REGISTRY_URL, { signal: controller.signal });
4238
4126
  clearTimeout(timeout);
4239
4127
  const data = await response.json();