@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/{chunk-HMJZM62P.js → chunk-5ZYOOESD.js} +192 -300
- package/dist/chunk-5ZYOOESD.js.map +1 -0
- package/dist/index.cjs +197 -309
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -13
- package/dist/index.d.ts +2 -13
- package/dist/index.js +1 -1
- package/dist/model-registry.cjs +14 -18
- package/dist/model-registry.cjs.map +1 -1
- package/dist/model-registry.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-HMJZM62P.js.map +0 -1
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
1573
|
-
var
|
|
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
|
|
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
|
|
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
|
|
1325
|
+
await import_promises.default.unlink(lockPath).catch(() => {
|
|
1602
1326
|
});
|
|
1603
1327
|
continue;
|
|
1604
1328
|
}
|
|
1605
1329
|
} catch {
|
|
1606
|
-
await
|
|
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
|
|
1335
|
+
await import_promises.default.unlink(lockPath).catch(() => {
|
|
1612
1336
|
});
|
|
1613
1337
|
continue;
|
|
1614
1338
|
}
|
|
1615
|
-
await (0,
|
|
1339
|
+
await (0, import_promises2.setTimeout)(RETRY_INTERVAL_MS);
|
|
1616
1340
|
}
|
|
1617
1341
|
}
|
|
1618
1342
|
}
|
|
1619
1343
|
async function releaseLock(lockPath) {
|
|
1620
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2150
|
-
await
|
|
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
|
|
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
|
|
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 <
|
|
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
|
|
4052
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
4165
4053
|
var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
4166
|
-
var
|
|
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(
|
|
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(),
|
|
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();
|