@kenkaiiii/gg-core 5.93.0 → 5.94.0
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/README.md +11 -11
- package/dist/{chunk-2X5L6U4Z.js → chunk-GXOFTHM5.js} +4 -2
- package/dist/chunk-GXOFTHM5.js.map +1 -0
- package/dist/{chunk-SDUIKPGO.js → chunk-JLEBGMG4.js} +649 -164
- package/dist/chunk-JLEBGMG4.js.map +1 -0
- package/dist/index.cjs +826 -228
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +180 -37
- package/dist/index.d.ts +180 -37
- package/dist/index.js +170 -57
- package/dist/index.js.map +1 -1
- package/dist/model-registry.cjs +53 -16
- package/dist/model-registry.cjs.map +1 -1
- package/dist/model-registry.js +2 -2
- package/dist/paths.cjs +3 -1
- package/dist/paths.cjs.map +1 -1
- package/dist/paths.d.cts +4 -0
- package/dist/paths.d.ts +4 -0
- package/dist/paths.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-2X5L6U4Z.js.map +0 -1
- package/dist/chunk-SDUIKPGO.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,9 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
AUTH_PROVIDERS: () => AUTH_PROVIDERS,
|
|
34
34
|
AuthStorage: () => AuthStorage,
|
|
35
|
+
CLAUDE_CODE_AUTH_KEY: () => CLAUDE_CODE_AUTH_KEY,
|
|
36
|
+
CLAUDE_CODE_AUTH_MARKER: () => CLAUDE_CODE_AUTH_MARKER,
|
|
37
|
+
CLAUDE_CODE_MANIFEST: () => CLAUDE_CODE_MANIFEST,
|
|
35
38
|
DEFAULT_LOCAL_ENDPOINTS: () => DEFAULT_LOCAL_ENDPOINTS,
|
|
36
39
|
DEFAULT_MAX_VIDEO_BYTES: () => DEFAULT_MAX_VIDEO_BYTES,
|
|
37
40
|
FALLBACK_CONTEXT_WINDOW: () => FALLBACK_CONTEXT_WINDOW,
|
|
@@ -54,6 +57,14 @@ __export(index_exports, {
|
|
|
54
57
|
XIAOMI_TOKEN_PLAN_BASE_URLS: () => XIAOMI_TOKEN_PLAN_BASE_URLS,
|
|
55
58
|
authPriorityNote: () => authPriorityNote,
|
|
56
59
|
clampThinkingForPlanMode: () => clampThinkingForPlanMode,
|
|
60
|
+
claudeCodeAuthStatus: () => claudeCodeAuthStatus,
|
|
61
|
+
claudeCodeBinaryPath: () => claudeCodeBinaryPath,
|
|
62
|
+
claudeCodeCallbackUrl: () => claudeCodeCallbackUrl,
|
|
63
|
+
claudeCodeConfigDir: () => claudeCodeConfigDir,
|
|
64
|
+
claudeCodeEnv: () => claudeCodeEnv,
|
|
65
|
+
claudeCodeHome: () => claudeCodeHome,
|
|
66
|
+
claudeCodePlatformKey: () => claudeCodePlatformKey,
|
|
67
|
+
clearClaudeCodeUsage: () => clearClaudeCodeUsage,
|
|
57
68
|
clearLocalDiscoveryCache: () => clearLocalDiscoveryCache,
|
|
58
69
|
clearRuntimeModels: () => clearRuntimeModels,
|
|
59
70
|
closeLogger: () => closeLogger,
|
|
@@ -67,8 +78,10 @@ __export(index_exports, {
|
|
|
67
78
|
dualAuthProvider: () => dualAuthProvider,
|
|
68
79
|
dualAuthProviderByOAuthKey: () => dualAuthProviderByOAuthKey,
|
|
69
80
|
endpointRoot: () => endpointRoot,
|
|
81
|
+
ensureClaudeCodeBinary: () => ensureClaudeCodeBinary,
|
|
70
82
|
fetchSubscriptionUsage: () => fetchSubscriptionUsage,
|
|
71
83
|
findProbedModel: () => findProbedModel,
|
|
84
|
+
formatClaudeCodeInstallProgress: () => formatClaudeCodeInstallProgress,
|
|
72
85
|
formatLocalModelId: () => formatLocalModelId,
|
|
73
86
|
generatePKCE: () => generatePKCE,
|
|
74
87
|
getAllModels: () => getAllModels,
|
|
@@ -76,8 +89,6 @@ __export(index_exports, {
|
|
|
76
89
|
getAuthProvider: () => getAuthProvider,
|
|
77
90
|
getAuthStorageKey: () => getAuthStorageKey,
|
|
78
91
|
getAuthStorageKeys: () => getAuthStorageKeys,
|
|
79
|
-
getClaudeCliUserAgent: () => import_gg_ai.getClaudeCliUserAgent,
|
|
80
|
-
getClaudeCodeVersion: () => import_gg_ai.getClaudeCodeVersion,
|
|
81
92
|
getContextWindow: () => getContextWindow,
|
|
82
93
|
getDefaultModel: () => getDefaultModel,
|
|
83
94
|
getDefaultThinkingLevel: () => getDefaultThinkingLevel,
|
|
@@ -95,9 +106,11 @@ __export(index_exports, {
|
|
|
95
106
|
getVideoByteLimit: () => getVideoByteLimit,
|
|
96
107
|
grokCliBaseUrl: () => grokCliBaseUrl,
|
|
97
108
|
grokCliHeaders: () => grokCliHeaders,
|
|
109
|
+
isClaudeCodeAuthMarker: () => isClaudeCodeAuthMarker,
|
|
98
110
|
isGrokCliEndpoint: () => isGrokCliEndpoint,
|
|
99
111
|
isHiddenProvider: () => isHiddenProvider,
|
|
100
112
|
isKimiCodingEndpoint: () => isKimiCodingEndpoint,
|
|
113
|
+
isLegacyClaudeOAuth: () => isLegacyClaudeOAuth,
|
|
101
114
|
isLocalModelId: () => isLocalModelId,
|
|
102
115
|
isLoggerOpen: () => isLoggerOpen,
|
|
103
116
|
isModelLoaded: () => isModelLoaded,
|
|
@@ -108,21 +121,23 @@ __export(index_exports, {
|
|
|
108
121
|
localAuthStorageKey: () => localAuthStorageKey,
|
|
109
122
|
localModelShortName: () => localModelShortName,
|
|
110
123
|
log: () => log,
|
|
111
|
-
|
|
124
|
+
loginClaudeCode: () => loginClaudeCode,
|
|
112
125
|
loginGemini: () => loginGemini,
|
|
113
126
|
loginKimi: () => loginKimi,
|
|
114
127
|
loginOpenAI: () => loginOpenAI,
|
|
115
128
|
loginXai: () => loginXai,
|
|
129
|
+
logoutClaudeCode: () => logoutClaudeCode,
|
|
130
|
+
mergeClaudeCodeRateLimit: () => mergeClaudeCodeRateLimit,
|
|
116
131
|
oauthStorageKey: () => oauthStorageKey,
|
|
117
132
|
ollamaServedContext: () => ollamaServedContext,
|
|
118
133
|
openLog: () => openLog,
|
|
119
134
|
parseLocalModelId: () => parseLocalModelId,
|
|
120
135
|
parseOpenRouterCatalog: () => parseOpenRouterCatalog,
|
|
121
|
-
pendingClaudeCodeVersionRefresh: () => import_gg_ai.pendingClaudeCodeVersionRefresh,
|
|
122
136
|
probeEndpoint: () => probeEndpoint,
|
|
123
137
|
providerStorageKeys: () => providerStorageKeys,
|
|
138
|
+
readClaudeCodeUsage: () => readClaudeCodeUsage,
|
|
124
139
|
readStoredBaseUrlSync: () => readStoredBaseUrlSync,
|
|
125
|
-
|
|
140
|
+
recordClaudeCodeRateLimit: () => recordClaudeCodeRateLimit,
|
|
126
141
|
refreshGeminiToken: () => refreshGeminiToken,
|
|
127
142
|
refreshKimiToken: () => refreshKimiToken,
|
|
128
143
|
refreshOpenAIToken: () => refreshOpenAIToken,
|
|
@@ -130,8 +145,11 @@ __export(index_exports, {
|
|
|
130
145
|
registerLogCleanup: () => registerLogCleanup,
|
|
131
146
|
registerRuntimeModels: () => registerRuntimeModels,
|
|
132
147
|
resample: () => resample,
|
|
148
|
+
resolveClaudeCodeBinary: () => resolveClaudeCodeBinary,
|
|
133
149
|
setProgressCallback: () => setProgressCallback,
|
|
134
150
|
setProviderCatalog: () => setProviderCatalog,
|
|
151
|
+
signInWithClaudeCode: () => signInWithClaudeCode,
|
|
152
|
+
signOutOfClaudeCode: () => signOutOfClaudeCode,
|
|
135
153
|
toModelInfo: () => toModelInfo,
|
|
136
154
|
transcribeVoice: () => transcribeVoice,
|
|
137
155
|
usesOpenAICodexTransport: () => usesOpenAICodexTransport,
|
|
@@ -170,7 +188,9 @@ function getAppPaths() {
|
|
|
170
188
|
agentsDir: import_node_path.default.join(agentDir, "agents"),
|
|
171
189
|
progressFile: import_node_path.default.join(agentDir, "progress.json"),
|
|
172
190
|
progressBackupFile: import_node_path.default.join(agentDir, "progress.backup.json"),
|
|
173
|
-
trophiesFile: import_node_path.default.join(agentDir, "trophies.json")
|
|
191
|
+
trophiesFile: import_node_path.default.join(agentDir, "trophies.json"),
|
|
192
|
+
claudeCodeDir: import_node_path.default.join(agentDir, "claude-code"),
|
|
193
|
+
claudeCodeConfigDir: import_node_path.default.join(agentDir, "claude-code", "config")
|
|
174
194
|
};
|
|
175
195
|
}
|
|
176
196
|
|
|
@@ -395,137 +415,539 @@ async function refreshKimiToken(refreshToken) {
|
|
|
395
415
|
}
|
|
396
416
|
|
|
397
417
|
// src/auth-storage.ts
|
|
398
|
-
var
|
|
399
|
-
var
|
|
418
|
+
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
419
|
+
var import_node_fs5 = require("fs");
|
|
400
420
|
var import_node_crypto6 = __toESM(require("crypto"), 1);
|
|
401
421
|
|
|
402
|
-
// src/
|
|
422
|
+
// src/claude-code/runtime.ts
|
|
423
|
+
var import_node_child_process2 = require("child_process");
|
|
403
424
|
var import_node_crypto2 = __toESM(require("crypto"), 1);
|
|
425
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
426
|
+
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
427
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
404
428
|
|
|
405
|
-
// src/
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
429
|
+
// src/claude-code/tar.ts
|
|
430
|
+
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
431
|
+
var import_promises = __toESM(require("fs/promises"), 1);
|
|
432
|
+
var import_node_zlib = __toESM(require("zlib"), 1);
|
|
433
|
+
var BLOCK = 512;
|
|
434
|
+
function readString(buf, offset, length) {
|
|
435
|
+
const end = buf.indexOf(0, offset);
|
|
436
|
+
return buf.toString("utf8", offset, end === -1 || end > offset + length ? offset + length : end);
|
|
437
|
+
}
|
|
438
|
+
function readSize(buf, offset) {
|
|
439
|
+
if (buf[offset] & 128) {
|
|
440
|
+
let value = buf[offset] & 127;
|
|
441
|
+
for (let i = 1; i < 12; i++) value = value * 256 + buf[offset + i];
|
|
442
|
+
return value;
|
|
443
|
+
}
|
|
444
|
+
const text = readString(buf, offset, 12).trim();
|
|
445
|
+
return text ? parseInt(text, 8) : 0;
|
|
446
|
+
}
|
|
447
|
+
function paxPath(data) {
|
|
448
|
+
let pos = 0;
|
|
449
|
+
while (pos < data.length) {
|
|
450
|
+
const space = data.indexOf(32, pos);
|
|
451
|
+
if (space === -1) break;
|
|
452
|
+
const len = parseInt(data.toString("utf8", pos, space), 10);
|
|
453
|
+
if (!Number.isFinite(len) || len <= 0) break;
|
|
454
|
+
const record = data.toString("utf8", space + 1, pos + len - 1);
|
|
455
|
+
const eq = record.indexOf("=");
|
|
456
|
+
if (eq !== -1 && record.slice(0, eq) === "path") return record.slice(eq + 1);
|
|
457
|
+
pos += len;
|
|
410
458
|
}
|
|
411
|
-
return
|
|
459
|
+
return void 0;
|
|
412
460
|
}
|
|
413
|
-
async function
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
461
|
+
async function extractFileFromTarGz(tgzPath, entryName, destPath) {
|
|
462
|
+
const input = import_node_fs2.default.createReadStream(tgzPath).pipe(import_node_zlib.default.createGunzip());
|
|
463
|
+
let pending = Buffer.alloc(0);
|
|
464
|
+
let remaining = 0;
|
|
465
|
+
let padding = 0;
|
|
466
|
+
let kind = "skip";
|
|
467
|
+
let meta = [];
|
|
468
|
+
let overridePath;
|
|
469
|
+
let out;
|
|
470
|
+
let found = false;
|
|
471
|
+
try {
|
|
472
|
+
for await (const chunk of input) {
|
|
473
|
+
pending = pending.length ? Buffer.concat([pending, chunk]) : chunk;
|
|
474
|
+
let pos = 0;
|
|
475
|
+
while (pos < pending.length) {
|
|
476
|
+
if (remaining > 0) {
|
|
477
|
+
const take = Math.min(remaining, pending.length - pos);
|
|
478
|
+
const slice = pending.subarray(pos, pos + take);
|
|
479
|
+
if (kind === "target") await out.write(slice);
|
|
480
|
+
else if (kind === "pax" || kind === "longname") meta.push(Buffer.from(slice));
|
|
481
|
+
pos += take;
|
|
482
|
+
remaining -= take;
|
|
483
|
+
if (remaining === 0) {
|
|
484
|
+
if (kind === "target") {
|
|
485
|
+
await out.close();
|
|
486
|
+
out = void 0;
|
|
487
|
+
found = true;
|
|
488
|
+
} else if (kind === "pax") {
|
|
489
|
+
overridePath = paxPath(Buffer.concat(meta)) ?? overridePath;
|
|
490
|
+
} else if (kind === "longname") {
|
|
491
|
+
overridePath = readString(Buffer.concat(meta), 0, Number.MAX_SAFE_INTEGER);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
496
|
+
if (padding > 0) {
|
|
497
|
+
const skip = Math.min(padding, pending.length - pos);
|
|
498
|
+
pos += skip;
|
|
499
|
+
padding -= skip;
|
|
500
|
+
continue;
|
|
501
|
+
}
|
|
502
|
+
if (found) break;
|
|
503
|
+
if (pending.length - pos < BLOCK) break;
|
|
504
|
+
const header = pending.subarray(pos, pos + BLOCK);
|
|
505
|
+
pos += BLOCK;
|
|
506
|
+
if (header.every((b) => b === 0)) continue;
|
|
507
|
+
const size = readSize(header, 124);
|
|
508
|
+
const type2 = String.fromCharCode(header[156] || 48);
|
|
509
|
+
let name = readString(header, 0, 100);
|
|
510
|
+
if (readString(header, 257, 6) === "ustar") {
|
|
511
|
+
const prefix = readString(header, 345, 155);
|
|
512
|
+
if (prefix) name = `${prefix}/${name}`;
|
|
513
|
+
}
|
|
514
|
+
remaining = size;
|
|
515
|
+
padding = (BLOCK - size % BLOCK) % BLOCK;
|
|
516
|
+
meta = [];
|
|
517
|
+
if (type2 === "x") kind = "pax";
|
|
518
|
+
else if (type2 === "L") kind = "longname";
|
|
519
|
+
else {
|
|
520
|
+
const path7 = overridePath ?? name;
|
|
521
|
+
overridePath = void 0;
|
|
522
|
+
if ((type2 === "0" || type2 === "\0" || type2 === "7") && path7 === entryName) {
|
|
523
|
+
kind = "target";
|
|
524
|
+
out = await import_promises.default.open(destPath, "w", 493);
|
|
525
|
+
if (size === 0) {
|
|
526
|
+
await out.close();
|
|
527
|
+
out = void 0;
|
|
528
|
+
found = true;
|
|
529
|
+
}
|
|
530
|
+
} else {
|
|
531
|
+
kind = "skip";
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
pending = pos < pending.length ? Buffer.from(pending.subarray(pos)) : Buffer.alloc(0);
|
|
536
|
+
if (found) break;
|
|
537
|
+
}
|
|
538
|
+
if (!found && out) throw new Error(`Archive ended inside ${entryName}`);
|
|
539
|
+
return found;
|
|
540
|
+
} finally {
|
|
541
|
+
if (out) await out.close().catch(() => {
|
|
542
|
+
});
|
|
543
|
+
input.destroy();
|
|
544
|
+
}
|
|
421
545
|
}
|
|
422
546
|
|
|
423
|
-
// src/claude-code
|
|
424
|
-
var
|
|
547
|
+
// src/claude-code/manifest.json
|
|
548
|
+
var manifest_default = {
|
|
549
|
+
sdkVersion: "0.3.318",
|
|
550
|
+
claudeCodeVersion: "2.1.318",
|
|
551
|
+
platforms: {
|
|
552
|
+
"darwin-arm64": {
|
|
553
|
+
url: "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.318.tgz",
|
|
554
|
+
integrity: "sha512-AWoXeDXzAMD3RaA21lWuHvCrKd8xmbTTmKjovninn4j07jheoVSMzFbCFjpp4kk5TdhT36JtWPkAxvjNMbcO8w==",
|
|
555
|
+
bin: "claude"
|
|
556
|
+
},
|
|
557
|
+
"darwin-x64": {
|
|
558
|
+
url: "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.318.tgz",
|
|
559
|
+
integrity: "sha512-6CkZ5PCdebSY/LePp16sf/HYRtM6zVuxtn8qYICFS5KUZFsjccJJ9swVsOdHXNHi4SWZcSmIFTwoUbfFCzisRw==",
|
|
560
|
+
bin: "claude"
|
|
561
|
+
},
|
|
562
|
+
"linux-arm64": {
|
|
563
|
+
url: "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.318.tgz",
|
|
564
|
+
integrity: "sha512-mBm4su17aMitLBBCQj3bHdejyUDY6z/ormGih+HG24N689RSbdKECjGjkT87tDBIR/4jyoqmuSeHqM1DI8TJlg==",
|
|
565
|
+
bin: "claude"
|
|
566
|
+
},
|
|
567
|
+
"linux-arm64-musl": {
|
|
568
|
+
url: "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.318.tgz",
|
|
569
|
+
integrity: "sha512-l4LSYFOrvlYCrUImGfxMTQ0wg+T3s9CBhrBvPF/0oJGKZg+QnxHHU8jUVm9e9/xYmDRTtqFIrr4id/5AfH4XGw==",
|
|
570
|
+
bin: "claude"
|
|
571
|
+
},
|
|
572
|
+
"linux-x64": {
|
|
573
|
+
url: "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.318.tgz",
|
|
574
|
+
integrity: "sha512-+mE+ueBD3oRFdaG16rd0h+LMjdeivGxL0pr/+FZK7JeLWVu+yPSw/f/X02b9oK36/DWykiFTu2G6HnJ9/+YO6w==",
|
|
575
|
+
bin: "claude"
|
|
576
|
+
},
|
|
577
|
+
"linux-x64-musl": {
|
|
578
|
+
url: "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.318.tgz",
|
|
579
|
+
integrity: "sha512-SAF3lj/2OzTU84p+OOA13QEKA9+5fYAw0M9E7AJjdnRmVFGqQfbV7Do1i1f9Sj0mIubB3rLTRphGRw8O4HZjgA==",
|
|
580
|
+
bin: "claude"
|
|
581
|
+
},
|
|
582
|
+
"win32-arm64": {
|
|
583
|
+
url: "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.318.tgz",
|
|
584
|
+
integrity: "sha512-19iVSZ4379QbZU1XnGUtfFvhKS1WzS8H1sbU/DbrzqbJ5Kq1eB1drj+obB1fCxTh6m26tRPj0zMJmdeu/jk3Gw==",
|
|
585
|
+
bin: "claude.exe"
|
|
586
|
+
},
|
|
587
|
+
"win32-x64": {
|
|
588
|
+
url: "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.318.tgz",
|
|
589
|
+
integrity: "sha512-ZdKVWpyVNVt0cXrOf8sUBaxcxLEAP+oGMdQDLBWr/BqOxTWLy7TBWOj1kzw+wVg/9WIkjkgQWeJzGXPWulR1sA==",
|
|
590
|
+
bin: "claude.exe"
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
};
|
|
425
594
|
|
|
426
|
-
// src/
|
|
427
|
-
var
|
|
428
|
-
var
|
|
429
|
-
var
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
595
|
+
// src/claude-code/runtime.ts
|
|
596
|
+
var CLAUDE_CODE_MANIFEST = manifest_default;
|
|
597
|
+
var CLAUDE_CODE_AUTH_KEY = "anthropic-claude-code";
|
|
598
|
+
var CLAUDE_CODE_AUTH_MARKER = { via: "claude-code" };
|
|
599
|
+
function isClaudeCodeAuthMarker(value) {
|
|
600
|
+
return value?.via === CLAUDE_CODE_AUTH_MARKER.via;
|
|
601
|
+
}
|
|
602
|
+
function isLegacyClaudeOAuth(value) {
|
|
603
|
+
const token = value?.accessToken;
|
|
604
|
+
return typeof token === "string" && token.startsWith("sk-ant-oat");
|
|
605
|
+
}
|
|
606
|
+
function isMusl() {
|
|
607
|
+
if (process.platform !== "linux") return false;
|
|
608
|
+
const report = typeof process.report?.getReport === "function" ? process.report.getReport() : null;
|
|
609
|
+
return report != null && report.header?.glibcVersionRuntime === void 0;
|
|
610
|
+
}
|
|
611
|
+
function claudeCodePlatformKey(info = { platform: process.platform, arch: process.arch, musl: isMusl() }) {
|
|
612
|
+
const arch2 = info.arch === "arm64" || info.arch === "x64" ? info.arch : null;
|
|
613
|
+
if (!arch2) return null;
|
|
614
|
+
if (info.platform === "darwin" || info.platform === "win32") return `${info.platform}-${arch2}`;
|
|
615
|
+
if (info.platform === "linux") return `linux-${arch2}${info.musl ? "-musl" : ""}`;
|
|
616
|
+
return null;
|
|
617
|
+
}
|
|
618
|
+
function resolveAsset(opts) {
|
|
619
|
+
const manifest = opts.manifest ?? CLAUDE_CODE_MANIFEST;
|
|
620
|
+
const key = opts.platformKey ?? claudeCodePlatformKey();
|
|
621
|
+
const asset = key ? manifest.platforms[key] : void 0;
|
|
622
|
+
if (!asset) {
|
|
623
|
+
throw new Error(
|
|
624
|
+
`Claude Code isn't available for ${process.platform}-${process.arch}. Use an Anthropic API key instead.`
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
return { manifest, asset };
|
|
628
|
+
}
|
|
629
|
+
function claudeCodeHome(opts = {}) {
|
|
630
|
+
return opts.home ?? getAppPaths().claudeCodeDir;
|
|
631
|
+
}
|
|
632
|
+
function claudeCodeConfigDir(opts = {}) {
|
|
633
|
+
return opts.home ? import_node_path3.default.join(opts.home, "config") : getAppPaths().claudeCodeConfigDir;
|
|
634
|
+
}
|
|
635
|
+
function claudeCodeBinaryPath(opts = {}) {
|
|
636
|
+
const { manifest, asset } = resolveAsset(opts);
|
|
637
|
+
return import_node_path3.default.join(claudeCodeHome(opts), manifest.claudeCodeVersion, asset.bin);
|
|
638
|
+
}
|
|
639
|
+
function resolveClaudeCodeBinary(opts = {}) {
|
|
640
|
+
let binary;
|
|
641
|
+
try {
|
|
642
|
+
binary = claudeCodeBinaryPath(opts);
|
|
643
|
+
} catch {
|
|
644
|
+
return null;
|
|
645
|
+
}
|
|
646
|
+
try {
|
|
647
|
+
return import_node_fs3.default.statSync(binary).isFile() ? binary : null;
|
|
648
|
+
} catch {
|
|
649
|
+
return null;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
var installs = /* @__PURE__ */ new Map();
|
|
653
|
+
async function ensureClaudeCodeBinary(opts = {}) {
|
|
654
|
+
const existing = resolveClaudeCodeBinary(opts);
|
|
655
|
+
if (existing) return existing;
|
|
656
|
+
const target = claudeCodeBinaryPath(opts);
|
|
657
|
+
let install = installs.get(target);
|
|
658
|
+
if (!install) {
|
|
659
|
+
install = installClaudeCode(opts).finally(() => installs.delete(target));
|
|
660
|
+
installs.set(target, install);
|
|
661
|
+
}
|
|
662
|
+
return install;
|
|
663
|
+
}
|
|
664
|
+
async function installClaudeCode(opts) {
|
|
665
|
+
const { manifest, asset } = resolveAsset(opts);
|
|
666
|
+
const home = claudeCodeHome(opts);
|
|
667
|
+
const versionDir = import_node_path3.default.join(home, manifest.claudeCodeVersion);
|
|
668
|
+
const binary = import_node_path3.default.join(versionDir, asset.bin);
|
|
669
|
+
await import_promises2.default.mkdir(home, { recursive: true });
|
|
670
|
+
const tag = `${process.pid}-${import_node_crypto2.default.randomBytes(4).toString("hex")}`;
|
|
671
|
+
const tarball = import_node_path3.default.join(home, `.download-${tag}.tgz`);
|
|
672
|
+
const staging = import_node_path3.default.join(home, `.staging-${tag}`);
|
|
673
|
+
try {
|
|
674
|
+
await download(asset, tarball, opts);
|
|
675
|
+
opts.onProgress?.({ phase: "extract" });
|
|
676
|
+
await import_promises2.default.mkdir(staging, { recursive: true });
|
|
677
|
+
const found = await extractFileFromTarGz(
|
|
678
|
+
tarball,
|
|
679
|
+
`package/${asset.bin}`,
|
|
680
|
+
import_node_path3.default.join(staging, asset.bin)
|
|
681
|
+
);
|
|
682
|
+
if (!found) throw new Error(`The Claude Code download has no ${asset.bin} binary.`);
|
|
683
|
+
await import_promises2.default.chmod(import_node_path3.default.join(staging, asset.bin), 493);
|
|
445
684
|
try {
|
|
446
|
-
|
|
447
|
-
method: "POST",
|
|
448
|
-
headers,
|
|
449
|
-
body: encoded,
|
|
450
|
-
signal: oauthRequestSignal()
|
|
451
|
-
});
|
|
685
|
+
await import_promises2.default.rename(staging, versionDir);
|
|
452
686
|
} catch (err) {
|
|
453
|
-
|
|
454
|
-
continue;
|
|
687
|
+
if (!import_node_fs3.default.existsSync(binary)) throw err;
|
|
455
688
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
689
|
+
await removeOldVersions(home, manifest.claudeCodeVersion);
|
|
690
|
+
return binary;
|
|
691
|
+
} finally {
|
|
692
|
+
await import_promises2.default.rm(tarball, { force: true }).catch(() => {
|
|
693
|
+
});
|
|
694
|
+
await import_promises2.default.rm(staging, { recursive: true, force: true }).catch(() => {
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
async function download(asset, dest, opts) {
|
|
699
|
+
const doFetch = opts.fetch ?? fetch;
|
|
700
|
+
const res = await doFetch(asset.url, { signal: opts.signal });
|
|
701
|
+
if (!res.ok || !res.body) {
|
|
702
|
+
throw new Error(`Claude Code download failed (HTTP ${res.status}).`);
|
|
703
|
+
}
|
|
704
|
+
const totalBytes = Number(res.headers.get("content-length")) || void 0;
|
|
705
|
+
const hash = import_node_crypto2.default.createHash("sha512");
|
|
706
|
+
const out = await import_promises2.default.open(dest, "w");
|
|
707
|
+
let receivedBytes = 0;
|
|
708
|
+
let lastReported = -1;
|
|
709
|
+
try {
|
|
710
|
+
opts.onProgress?.({ phase: "download", receivedBytes, totalBytes });
|
|
711
|
+
for await (const chunk of res.body) {
|
|
712
|
+
if (opts.signal?.aborted) throw opts.signal.reason ?? new Error("Download cancelled.");
|
|
713
|
+
hash.update(chunk);
|
|
714
|
+
await out.write(chunk);
|
|
715
|
+
receivedBytes += chunk.byteLength;
|
|
716
|
+
const step = totalBytes ? Math.floor(receivedBytes / totalBytes * 100) : Math.floor(receivedBytes / 4194304);
|
|
717
|
+
if (step !== lastReported) {
|
|
718
|
+
lastReported = step;
|
|
719
|
+
opts.onProgress?.({ phase: "download", receivedBytes, totalBytes });
|
|
720
|
+
}
|
|
462
721
|
}
|
|
463
|
-
|
|
722
|
+
} finally {
|
|
723
|
+
await out.close();
|
|
724
|
+
}
|
|
725
|
+
opts.onProgress?.({ phase: "verify" });
|
|
726
|
+
const expected = asset.integrity.replace(/^sha512-/, "");
|
|
727
|
+
if (hash.digest("base64") !== expected) {
|
|
728
|
+
throw new Error(
|
|
729
|
+
"The Claude Code download didn't match its pinned checksum, so it was discarded."
|
|
730
|
+
);
|
|
464
731
|
}
|
|
465
|
-
throw lastError ?? new Error(`Anthropic ${label} failed: all endpoints unreachable`);
|
|
466
732
|
}
|
|
467
|
-
function
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
733
|
+
async function removeOldVersions(home, keep) {
|
|
734
|
+
let entries;
|
|
735
|
+
try {
|
|
736
|
+
entries = await import_promises2.default.readdir(home, { withFileTypes: true });
|
|
737
|
+
} catch {
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
for (const entry of entries) {
|
|
741
|
+
if (!entry.isDirectory() || entry.name === keep || entry.name === "config") continue;
|
|
742
|
+
if (!/^\d+\.\d+\.\d+/.test(entry.name)) continue;
|
|
743
|
+
await import_promises2.default.rm(import_node_path3.default.join(home, entry.name), { recursive: true, force: true }).catch(() => {
|
|
744
|
+
});
|
|
745
|
+
}
|
|
473
746
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
747
|
+
function formatClaudeCodeInstallProgress(progress) {
|
|
748
|
+
if (progress.phase === "verify") return "Checking the Claude Code download\u2026";
|
|
749
|
+
if (progress.phase === "extract") return "Unpacking Claude Code\u2026";
|
|
750
|
+
const mb = (bytes) => Math.round(bytes / 1048576);
|
|
751
|
+
if (!progress.totalBytes) return `Downloading Claude Code\u2026 ${mb(progress.receivedBytes)} MB`;
|
|
752
|
+
const pct = Math.floor(progress.receivedBytes / progress.totalBytes * 100);
|
|
753
|
+
return `Downloading Claude Code\u2026 ${pct}% (${mb(progress.receivedBytes)} of ${mb(progress.totalBytes)} MB)`;
|
|
754
|
+
}
|
|
755
|
+
var STRIPPED_ENV = [
|
|
756
|
+
"ANTHROPIC_API_KEY",
|
|
757
|
+
"ANTHROPIC_AUTH_TOKEN",
|
|
758
|
+
"ANTHROPIC_BASE_URL",
|
|
759
|
+
"CLAUDE_CODE_OAUTH_TOKEN",
|
|
760
|
+
"CLAUDE_CODE_OAUTH_REFRESH_TOKEN",
|
|
761
|
+
"CLAUDE_CODE_USE_BEDROCK",
|
|
762
|
+
"CLAUDE_CODE_USE_VERTEX",
|
|
763
|
+
"CLAUDE_CODE_USE_FOUNDRY",
|
|
764
|
+
"NODE_OPTIONS"
|
|
765
|
+
];
|
|
766
|
+
function claudeCodeEnv(opts = {}, base = process.env) {
|
|
767
|
+
const env = {};
|
|
768
|
+
for (const [key, value] of Object.entries(base)) {
|
|
769
|
+
if (value !== void 0 && !STRIPPED_ENV.includes(key)) env[key] = value;
|
|
770
|
+
}
|
|
771
|
+
env.CLAUDE_CONFIG_DIR = claudeCodeConfigDir(opts);
|
|
772
|
+
env.DISABLE_AUTOUPDATER = "1";
|
|
773
|
+
return env;
|
|
774
|
+
}
|
|
775
|
+
function runCommand(opts) {
|
|
776
|
+
if (opts.binary) return { command: opts.binary, prefix: opts.binaryArgs ?? [] };
|
|
777
|
+
const binary = resolveClaudeCodeBinary(opts);
|
|
778
|
+
if (!binary) throw new Error("Claude Code isn't installed yet. Sign in with Claude first.");
|
|
779
|
+
return { command: binary, prefix: [] };
|
|
780
|
+
}
|
|
781
|
+
function runClaude(args, opts) {
|
|
782
|
+
const { command, prefix } = runCommand(opts);
|
|
783
|
+
return new Promise((resolve, reject) => {
|
|
784
|
+
const child = (0, import_node_child_process2.spawn)(command, [...prefix, ...args], {
|
|
785
|
+
env: claudeCodeEnv(opts),
|
|
786
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
787
|
+
windowsHide: true,
|
|
788
|
+
signal: opts.signal
|
|
789
|
+
});
|
|
790
|
+
let stdout = "";
|
|
791
|
+
let stderr = "";
|
|
792
|
+
child.stdout.on("data", (d) => stdout += d.toString());
|
|
793
|
+
child.stderr.on("data", (d) => stderr += d.toString());
|
|
794
|
+
child.on("error", reject);
|
|
795
|
+
child.on("close", (code) => resolve({ code, stdout, stderr }));
|
|
486
796
|
});
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
const
|
|
491
|
-
|
|
492
|
-
|
|
797
|
+
}
|
|
798
|
+
async function claudeCodeAuthStatus(opts = {}) {
|
|
799
|
+
if (!opts.binary && !resolveClaudeCodeBinary(opts)) return { loggedIn: false };
|
|
800
|
+
const { stdout } = await runClaude(["auth", "status", "--json"], opts);
|
|
801
|
+
try {
|
|
802
|
+
const parsed = JSON.parse(stdout);
|
|
803
|
+
return {
|
|
804
|
+
loggedIn: parsed.loggedIn === true,
|
|
805
|
+
...typeof parsed.authMethod === "string" ? { authMethod: parsed.authMethod } : {},
|
|
806
|
+
...typeof parsed.email === "string" ? { email: parsed.email } : {},
|
|
807
|
+
...typeof parsed.subscriptionType === "string" ? { subscriptionType: parsed.subscriptionType } : {}
|
|
808
|
+
};
|
|
809
|
+
} catch {
|
|
810
|
+
return { loggedIn: false };
|
|
493
811
|
}
|
|
494
|
-
return exchangeAnthropicCode(parts[0], parts[1], verifier);
|
|
495
812
|
}
|
|
496
|
-
async function
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
client_id: CLIENT_ID2,
|
|
501
|
-
code,
|
|
502
|
-
state,
|
|
503
|
-
redirect_uri: REDIRECT_URI,
|
|
504
|
-
code_verifier: verifier
|
|
505
|
-
},
|
|
506
|
-
"token exchange"
|
|
507
|
-
);
|
|
508
|
-
return toCredentials(data);
|
|
813
|
+
async function logoutClaudeCode(opts = {}) {
|
|
814
|
+
if (!opts.binary && !resolveClaudeCodeBinary(opts)) return;
|
|
815
|
+
const { code, stderr } = await runClaude(["auth", "logout"], opts);
|
|
816
|
+
if (code !== 0) throw new Error(stderr.trim() || `claude auth logout exited with ${code}`);
|
|
509
817
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
return
|
|
818
|
+
var OPEN_URL_HOOK = `const arg = String(process.argv[1] || "");
|
|
819
|
+
const file = process.env.GG_CLAUDE_CODE_URL_FILE;
|
|
820
|
+
if (file && /https?:/.test(arg)) {
|
|
821
|
+
require("node:fs").appendFileSync(file, arg + "\\n");
|
|
822
|
+
process.exit(0);
|
|
823
|
+
}
|
|
824
|
+
`;
|
|
825
|
+
var CAPTURE_WAIT_MS = 3e3;
|
|
826
|
+
function stripAnsi(text) {
|
|
827
|
+
return text.replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b\[[0-9;?]*[A-Za-z]/g, "");
|
|
828
|
+
}
|
|
829
|
+
function claudeCodeCallbackUrl(manualUrl, captured) {
|
|
830
|
+
const port = /localhost(?::|%3A)(\d{2,5})(?:\/|%2F)callback/i.exec(captured)?.[1];
|
|
831
|
+
if (!port) return null;
|
|
832
|
+
try {
|
|
833
|
+
const url = new URL(manualUrl);
|
|
834
|
+
url.searchParams.set("redirect_uri", `http://localhost:${port}/callback`);
|
|
835
|
+
return url.toString();
|
|
836
|
+
} catch {
|
|
837
|
+
return null;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
async function loginClaudeCode(callbacks, opts = {}) {
|
|
841
|
+
const { command, prefix } = runCommand(opts);
|
|
842
|
+
const home = claudeCodeHome(opts);
|
|
843
|
+
await import_promises2.default.mkdir(claudeCodeConfigDir(opts), { recursive: true });
|
|
844
|
+
const tag = `${process.pid}-${import_node_crypto2.default.randomBytes(4).toString("hex")}`;
|
|
845
|
+
const hookFile = import_node_path3.default.join(home, `.open-url-${tag}.cjs`);
|
|
846
|
+
const urlFile = import_node_path3.default.join(home, `.open-url-${tag}.txt`);
|
|
847
|
+
await import_promises2.default.writeFile(hookFile, OPEN_URL_HOOK);
|
|
848
|
+
const env = {
|
|
849
|
+
...claudeCodeEnv(opts),
|
|
850
|
+
BROWSER: process.execPath,
|
|
851
|
+
NODE_OPTIONS: `--require ${JSON.stringify(hookFile)}`,
|
|
852
|
+
GG_CLAUDE_CODE_URL_FILE: urlFile
|
|
853
|
+
};
|
|
854
|
+
const promptAbort = new AbortController();
|
|
855
|
+
let timer;
|
|
856
|
+
try {
|
|
857
|
+
await new Promise((resolve, reject) => {
|
|
858
|
+
const child = (0, import_node_child_process2.spawn)(command, [...prefix, "auth", "login", "--claudeai"], {
|
|
859
|
+
env,
|
|
860
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
861
|
+
windowsHide: true
|
|
862
|
+
});
|
|
863
|
+
let stdout = "";
|
|
864
|
+
let stderr = "";
|
|
865
|
+
let manualUrl = null;
|
|
866
|
+
let opened = false;
|
|
867
|
+
const onAbort = () => child.kill();
|
|
868
|
+
opts.signal?.addEventListener("abort", onAbort, { once: true });
|
|
869
|
+
const open = (url, needsCode) => {
|
|
870
|
+
if (opened) return;
|
|
871
|
+
opened = true;
|
|
872
|
+
clearInterval(timer);
|
|
873
|
+
callbacks.onOpenUrl(url);
|
|
874
|
+
callbacks.onStatus("Finish signing in to Claude in your browser\u2026");
|
|
875
|
+
if (!needsCode) return;
|
|
876
|
+
void callbacks.onPromptCode("Paste the code shown after signing in to Claude:", promptAbort.signal).then((code) => {
|
|
877
|
+
const trimmed = code.trim();
|
|
878
|
+
if (trimmed && !child.stdin.destroyed) child.stdin.write(`${trimmed}
|
|
879
|
+
`);
|
|
880
|
+
}).catch(() => {
|
|
881
|
+
});
|
|
882
|
+
};
|
|
883
|
+
child.stdout.on("data", (d) => {
|
|
884
|
+
stdout += d.toString();
|
|
885
|
+
if (manualUrl) return;
|
|
886
|
+
const match = /visit:\s*(https:\/\/\S+)/.exec(stripAnsi(stdout));
|
|
887
|
+
if (!match) return;
|
|
888
|
+
manualUrl = match[1];
|
|
889
|
+
const started = Date.now();
|
|
890
|
+
timer = setInterval(() => {
|
|
891
|
+
let captured = "";
|
|
892
|
+
try {
|
|
893
|
+
captured = import_node_fs3.default.readFileSync(urlFile, "utf8");
|
|
894
|
+
} catch {
|
|
895
|
+
}
|
|
896
|
+
const callbackUrl = captured ? claudeCodeCallbackUrl(manualUrl, captured) : null;
|
|
897
|
+
if (callbackUrl) open(callbackUrl, false);
|
|
898
|
+
else if (Date.now() - started > (opts.browserWaitMs ?? CAPTURE_WAIT_MS))
|
|
899
|
+
open(manualUrl, true);
|
|
900
|
+
}, 100);
|
|
901
|
+
});
|
|
902
|
+
child.stderr.on("data", (d) => stderr += d.toString());
|
|
903
|
+
child.on("error", reject);
|
|
904
|
+
child.on("close", (code) => {
|
|
905
|
+
opts.signal?.removeEventListener("abort", onAbort);
|
|
906
|
+
if (opts.signal?.aborted) reject(new Error("Sign-in cancelled."));
|
|
907
|
+
else if (code === 0) resolve();
|
|
908
|
+
else {
|
|
909
|
+
const detail = stripAnsi(stderr).trim().split("\n").pop()?.trim();
|
|
910
|
+
reject(new Error(detail || `Claude sign-in failed (exit ${code}).`));
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
});
|
|
914
|
+
} finally {
|
|
915
|
+
clearInterval(timer);
|
|
916
|
+
promptAbort.abort();
|
|
917
|
+
await import_promises2.default.rm(hookFile, { force: true }).catch(() => {
|
|
918
|
+
});
|
|
919
|
+
await import_promises2.default.rm(urlFile, { force: true }).catch(() => {
|
|
920
|
+
});
|
|
921
|
+
}
|
|
520
922
|
}
|
|
521
923
|
|
|
522
924
|
// src/oauth/openai.ts
|
|
523
925
|
var import_node_http = __toESM(require("http"), 1);
|
|
524
926
|
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
525
|
-
|
|
526
|
-
|
|
927
|
+
|
|
928
|
+
// src/oauth/pkce.ts
|
|
929
|
+
function base64urlEncode(bytes) {
|
|
930
|
+
let binary = "";
|
|
931
|
+
for (const byte of bytes) {
|
|
932
|
+
binary += String.fromCharCode(byte);
|
|
933
|
+
}
|
|
934
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
935
|
+
}
|
|
936
|
+
async function generatePKCE() {
|
|
937
|
+
const verifierBytes = new Uint8Array(32);
|
|
938
|
+
crypto.getRandomValues(verifierBytes);
|
|
939
|
+
const verifier = base64urlEncode(verifierBytes);
|
|
940
|
+
const data = new TextEncoder().encode(verifier);
|
|
941
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
942
|
+
const challenge = base64urlEncode(new Uint8Array(hashBuffer));
|
|
943
|
+
return { verifier, challenge };
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// src/oauth/openai.ts
|
|
947
|
+
var CLIENT_ID2 = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
948
|
+
var AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize";
|
|
527
949
|
var TOKEN_URL = "https://auth.openai.com/oauth/token";
|
|
528
|
-
var
|
|
950
|
+
var REDIRECT_URI = "http://localhost:1455/auth/callback";
|
|
529
951
|
var SCOPE = "openid profile email offline_access api.connectors.read api.connectors.invoke";
|
|
530
952
|
var JWT_CLAIM_PATH = "https://api.openai.com/auth";
|
|
531
953
|
var CALLBACK_TIMEOUT_MS = 12e4;
|
|
@@ -534,10 +956,10 @@ var MIN_RAW_CODE_LENGTH = 10;
|
|
|
534
956
|
async function loginOpenAI(callbacks) {
|
|
535
957
|
const { verifier, challenge } = await generatePKCE();
|
|
536
958
|
const state = import_node_crypto3.default.randomBytes(16).toString("hex");
|
|
537
|
-
const url = new URL(
|
|
959
|
+
const url = new URL(AUTHORIZE_URL);
|
|
538
960
|
url.searchParams.set("response_type", "code");
|
|
539
|
-
url.searchParams.set("client_id",
|
|
540
|
-
url.searchParams.set("redirect_uri",
|
|
961
|
+
url.searchParams.set("client_id", CLIENT_ID2);
|
|
962
|
+
url.searchParams.set("redirect_uri", REDIRECT_URI);
|
|
541
963
|
url.searchParams.set("scope", SCOPE);
|
|
542
964
|
url.searchParams.set("code_challenge", challenge);
|
|
543
965
|
url.searchParams.set("code_challenge_method", "S256");
|
|
@@ -693,9 +1115,9 @@ async function exchangeOpenAICode(code, verifier) {
|
|
|
693
1115
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
694
1116
|
body: new URLSearchParams({
|
|
695
1117
|
grant_type: "authorization_code",
|
|
696
|
-
client_id:
|
|
1118
|
+
client_id: CLIENT_ID2,
|
|
697
1119
|
code,
|
|
698
|
-
redirect_uri:
|
|
1120
|
+
redirect_uri: REDIRECT_URI,
|
|
699
1121
|
code_verifier: verifier
|
|
700
1122
|
}),
|
|
701
1123
|
signal: oauthRequestSignal()
|
|
@@ -718,7 +1140,7 @@ async function refreshOpenAIToken(refreshToken) {
|
|
|
718
1140
|
body: new URLSearchParams({
|
|
719
1141
|
grant_type: "refresh_token",
|
|
720
1142
|
refresh_token: refreshToken,
|
|
721
|
-
client_id:
|
|
1143
|
+
client_id: CLIENT_ID2
|
|
722
1144
|
}),
|
|
723
1145
|
signal: oauthRequestSignal()
|
|
724
1146
|
});
|
|
@@ -746,7 +1168,7 @@ var CLIENT_ID_ENV = "GGCODER_GEMINI_OAUTH_CLIENT_ID";
|
|
|
746
1168
|
var CLIENT_SECRET_ENV = "GGCODER_GEMINI_OAUTH_CLIENT_SECRET";
|
|
747
1169
|
var DEFAULT_CLIENT_ID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com";
|
|
748
1170
|
var DEFAULT_CLIENT_SECRET = "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";
|
|
749
|
-
var
|
|
1171
|
+
var AUTHORIZE_URL2 = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
750
1172
|
var TOKEN_URL2 = "https://oauth2.googleapis.com/token";
|
|
751
1173
|
var CODE_ASSIST_BASE_URL = "https://cloudcode-pa.googleapis.com";
|
|
752
1174
|
var CODE_ASSIST_API_VERSION = "v1internal";
|
|
@@ -777,7 +1199,7 @@ async function loginGemini(callbacks) {
|
|
|
777
1199
|
const { verifier, challenge } = await generatePKCE();
|
|
778
1200
|
const state = import_node_crypto4.default.randomBytes(32).toString("hex");
|
|
779
1201
|
const redirectUri = await getLoopbackRedirectUri();
|
|
780
|
-
const url = new URL(
|
|
1202
|
+
const url = new URL(AUTHORIZE_URL2);
|
|
781
1203
|
url.searchParams.set("response_type", "code");
|
|
782
1204
|
url.searchParams.set("client_id", clientId2);
|
|
783
1205
|
url.searchParams.set("redirect_uri", redirectUri);
|
|
@@ -814,7 +1236,7 @@ async function loginGemini(callbacks) {
|
|
|
814
1236
|
}
|
|
815
1237
|
async function refreshGeminiToken(refreshToken) {
|
|
816
1238
|
const { clientId: clientId2, clientSecret } = getGeminiOAuthClientCredentials();
|
|
817
|
-
const data = await
|
|
1239
|
+
const data = await postTokenRequest({
|
|
818
1240
|
grant_type: "refresh_token",
|
|
819
1241
|
refresh_token: refreshToken,
|
|
820
1242
|
client_id: clientId2,
|
|
@@ -909,7 +1331,7 @@ async function loginWithServer(authUrl, redirectUri, expectedState, callbacks) {
|
|
|
909
1331
|
});
|
|
910
1332
|
}
|
|
911
1333
|
async function exchangeGeminiCode(code, verifier, redirectUri, clientId2, clientSecret) {
|
|
912
|
-
const data = await
|
|
1334
|
+
const data = await postTokenRequest({
|
|
913
1335
|
grant_type: "authorization_code",
|
|
914
1336
|
client_id: clientId2,
|
|
915
1337
|
client_secret: clientSecret,
|
|
@@ -926,7 +1348,7 @@ async function exchangeGeminiCode(code, verifier, redirectUri, clientId2, client
|
|
|
926
1348
|
expiresAt: Date.now() + data.expires_in * 1e3 - 5 * 60 * 1e3
|
|
927
1349
|
};
|
|
928
1350
|
}
|
|
929
|
-
async function
|
|
1351
|
+
async function postTokenRequest(body) {
|
|
930
1352
|
const response = await fetch(TOKEN_URL2, {
|
|
931
1353
|
method: "POST",
|
|
932
1354
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
@@ -1304,8 +1726,8 @@ async function refreshXaiToken(refreshToken) {
|
|
|
1304
1726
|
}
|
|
1305
1727
|
|
|
1306
1728
|
// src/file-lock.ts
|
|
1307
|
-
var
|
|
1308
|
-
var
|
|
1729
|
+
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
1730
|
+
var import_promises4 = require("timers/promises");
|
|
1309
1731
|
var STALE_TIMEOUT_MS = 1e4;
|
|
1310
1732
|
var RETRY_INTERVAL_MS = 50;
|
|
1311
1733
|
var MAX_WAIT_MS = 5e3;
|
|
@@ -1325,7 +1747,7 @@ async function acquireLock(lockPath) {
|
|
|
1325
1747
|
while (true) {
|
|
1326
1748
|
try {
|
|
1327
1749
|
const info = { pid: process.pid, timestamp: Date.now() };
|
|
1328
|
-
await
|
|
1750
|
+
await import_promises3.default.writeFile(lockPath, JSON.stringify(info), { flag: "wx" });
|
|
1329
1751
|
return;
|
|
1330
1752
|
} catch (err) {
|
|
1331
1753
|
const code = err.code;
|
|
@@ -1334,47 +1756,47 @@ async function acquireLock(lockPath) {
|
|
|
1334
1756
|
const lockPresent = await lockFileExists(lockPath);
|
|
1335
1757
|
if (!lockPresent && ++refusedWithoutLock > 3) throw err;
|
|
1336
1758
|
if (Date.now() - startTime > MAX_WAIT_MS) throw err;
|
|
1337
|
-
await (0,
|
|
1759
|
+
await (0, import_promises4.setTimeout)(RETRY_INTERVAL_MS);
|
|
1338
1760
|
continue;
|
|
1339
1761
|
}
|
|
1340
1762
|
try {
|
|
1341
|
-
const content = await
|
|
1763
|
+
const content = await import_promises3.default.readFile(lockPath, "utf-8");
|
|
1342
1764
|
const info = JSON.parse(content);
|
|
1343
1765
|
const isProcessAlive = isAlive(info.pid);
|
|
1344
1766
|
const isStale = Date.now() - info.timestamp > STALE_TIMEOUT_MS;
|
|
1345
1767
|
if (!isProcessAlive || isStale) {
|
|
1346
|
-
await
|
|
1768
|
+
await import_promises3.default.unlink(lockPath).catch(() => {
|
|
1347
1769
|
});
|
|
1348
1770
|
continue;
|
|
1349
1771
|
}
|
|
1350
1772
|
} catch {
|
|
1351
|
-
const stat = await
|
|
1773
|
+
const stat = await import_promises3.default.stat(lockPath).catch(() => null);
|
|
1352
1774
|
if (!stat) continue;
|
|
1353
1775
|
if (Date.now() - stat.mtimeMs > STALE_TIMEOUT_MS) {
|
|
1354
|
-
await
|
|
1776
|
+
await import_promises3.default.unlink(lockPath).catch(() => {
|
|
1355
1777
|
});
|
|
1356
1778
|
continue;
|
|
1357
1779
|
}
|
|
1358
1780
|
}
|
|
1359
1781
|
if (Date.now() - startTime > MAX_WAIT_MS) {
|
|
1360
|
-
await
|
|
1782
|
+
await import_promises3.default.unlink(lockPath).catch(() => {
|
|
1361
1783
|
});
|
|
1362
1784
|
continue;
|
|
1363
1785
|
}
|
|
1364
|
-
await (0,
|
|
1786
|
+
await (0, import_promises4.setTimeout)(RETRY_INTERVAL_MS);
|
|
1365
1787
|
}
|
|
1366
1788
|
}
|
|
1367
1789
|
}
|
|
1368
1790
|
async function lockFileExists(lockPath) {
|
|
1369
1791
|
try {
|
|
1370
|
-
await
|
|
1792
|
+
await import_promises3.default.stat(lockPath);
|
|
1371
1793
|
return true;
|
|
1372
1794
|
} catch (err) {
|
|
1373
1795
|
return err.code !== "ENOENT";
|
|
1374
1796
|
}
|
|
1375
1797
|
}
|
|
1376
1798
|
async function releaseLock(lockPath) {
|
|
1377
|
-
await
|
|
1799
|
+
await import_promises3.default.unlink(lockPath).catch(() => {
|
|
1378
1800
|
});
|
|
1379
1801
|
}
|
|
1380
1802
|
function isAlive(pid) {
|
|
@@ -1388,10 +1810,10 @@ function isAlive(pid) {
|
|
|
1388
1810
|
}
|
|
1389
1811
|
|
|
1390
1812
|
// src/logger.ts
|
|
1391
|
-
var
|
|
1392
|
-
var
|
|
1813
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
1814
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
1393
1815
|
var import_node_crypto5 = require("crypto");
|
|
1394
|
-
var
|
|
1816
|
+
var import_gg_ai = require("@kenkaiiii/gg-ai");
|
|
1395
1817
|
var MAX_BYTES = 10 * 1024 * 1024;
|
|
1396
1818
|
var MIN_HEADROOM_BYTES = 64 * 1024;
|
|
1397
1819
|
var fd = null;
|
|
@@ -1406,14 +1828,14 @@ var cleanups = [];
|
|
|
1406
1828
|
var exactSecrets = [];
|
|
1407
1829
|
function rotateIfNeeded(filePath, force = false) {
|
|
1408
1830
|
try {
|
|
1409
|
-
const st =
|
|
1831
|
+
const st = import_node_fs4.default.statSync(filePath);
|
|
1410
1832
|
if (!force && st.size <= MAX_BYTES - MIN_HEADROOM_BYTES) return;
|
|
1411
1833
|
const rotated = `${filePath}.1`;
|
|
1412
1834
|
try {
|
|
1413
|
-
|
|
1835
|
+
import_node_fs4.default.unlinkSync(rotated);
|
|
1414
1836
|
} catch {
|
|
1415
1837
|
}
|
|
1416
|
-
|
|
1838
|
+
import_node_fs4.default.renameSync(filePath, rotated);
|
|
1417
1839
|
} catch {
|
|
1418
1840
|
}
|
|
1419
1841
|
}
|
|
@@ -1421,18 +1843,18 @@ function rotateOpenLog() {
|
|
|
1421
1843
|
if (fd === null || logPath === null) return false;
|
|
1422
1844
|
const sizeBefore = fileBytes;
|
|
1423
1845
|
try {
|
|
1424
|
-
|
|
1846
|
+
import_node_fs4.default.closeSync(fd);
|
|
1425
1847
|
} catch {
|
|
1426
1848
|
}
|
|
1427
1849
|
fd = null;
|
|
1428
1850
|
rotateIfNeeded(logPath, true);
|
|
1429
1851
|
try {
|
|
1430
|
-
fd =
|
|
1431
|
-
fileBytes =
|
|
1852
|
+
fd = import_node_fs4.default.openSync(logPath, "a");
|
|
1853
|
+
fileBytes = import_node_fs4.default.fstatSync(fd).size;
|
|
1432
1854
|
} catch {
|
|
1433
1855
|
if (fd !== null) {
|
|
1434
1856
|
try {
|
|
1435
|
-
|
|
1857
|
+
import_node_fs4.default.closeSync(fd);
|
|
1436
1858
|
} catch {
|
|
1437
1859
|
}
|
|
1438
1860
|
}
|
|
@@ -1446,24 +1868,24 @@ function rotateOpenLog() {
|
|
|
1446
1868
|
function openLog(filePath, name) {
|
|
1447
1869
|
if (fd !== null || capped) return false;
|
|
1448
1870
|
appName = name;
|
|
1449
|
-
exactSecrets = (0,
|
|
1871
|
+
exactSecrets = (0, import_gg_ai.environmentSecrets)(process.env);
|
|
1450
1872
|
try {
|
|
1451
|
-
|
|
1873
|
+
import_node_fs4.default.mkdirSync(import_node_path4.default.dirname(filePath), { recursive: true, mode: 448 });
|
|
1452
1874
|
} catch {
|
|
1453
1875
|
}
|
|
1454
1876
|
rotateIfNeeded(filePath);
|
|
1455
1877
|
try {
|
|
1456
|
-
fd =
|
|
1878
|
+
fd = import_node_fs4.default.openSync(filePath, "a");
|
|
1457
1879
|
} catch {
|
|
1458
1880
|
fd = null;
|
|
1459
1881
|
fileBytes = 0;
|
|
1460
1882
|
return false;
|
|
1461
1883
|
}
|
|
1462
1884
|
try {
|
|
1463
|
-
fileBytes =
|
|
1885
|
+
fileBytes = import_node_fs4.default.fstatSync(fd).size;
|
|
1464
1886
|
} catch {
|
|
1465
1887
|
try {
|
|
1466
|
-
|
|
1888
|
+
import_node_fs4.default.closeSync(fd);
|
|
1467
1889
|
} catch {
|
|
1468
1890
|
}
|
|
1469
1891
|
fd = null;
|
|
@@ -1476,7 +1898,7 @@ function openLog(filePath, name) {
|
|
|
1476
1898
|
sessionId = (0, import_node_crypto5.randomBytes)(4).toString("hex");
|
|
1477
1899
|
try {
|
|
1478
1900
|
if (fileBytes < MAX_BYTES) {
|
|
1479
|
-
const written =
|
|
1901
|
+
const written = import_node_fs4.default.writeSync(fd, "\n");
|
|
1480
1902
|
fileBytes += written;
|
|
1481
1903
|
processBytes += written;
|
|
1482
1904
|
}
|
|
@@ -1493,10 +1915,10 @@ function isLoggerOpen() {
|
|
|
1493
1915
|
function log(level, category, message, data) {
|
|
1494
1916
|
if (fd === null) return;
|
|
1495
1917
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
1496
|
-
const safeMessage = (0,
|
|
1918
|
+
const safeMessage = (0, import_gg_ai.redactText)(message, { secrets: exactSecrets });
|
|
1497
1919
|
let line = `[${ts}] [sid=${sessionId}] [${level}] [${category}] ${safeMessage}`;
|
|
1498
1920
|
if (data) {
|
|
1499
|
-
const safeData = (0,
|
|
1921
|
+
const safeData = (0, import_gg_ai.redactValue)(data, { secrets: exactSecrets });
|
|
1500
1922
|
const pairs = Object.entries(safeData).map(([k, v]) => {
|
|
1501
1923
|
if (typeof v === "string") return `${k}=${v}`;
|
|
1502
1924
|
if (typeof v === "bigint") return `${k}=${String(v)}`;
|
|
@@ -1511,9 +1933,9 @@ function log(level, category, message, data) {
|
|
|
1511
1933
|
`;
|
|
1512
1934
|
try {
|
|
1513
1935
|
if (fileBytes + Buffer.byteLength(capLine) <= MAX_BYTES) {
|
|
1514
|
-
fileBytes +=
|
|
1936
|
+
fileBytes += import_node_fs4.default.writeSync(fd, capLine);
|
|
1515
1937
|
}
|
|
1516
|
-
|
|
1938
|
+
import_node_fs4.default.closeSync(fd);
|
|
1517
1939
|
} catch {
|
|
1518
1940
|
}
|
|
1519
1941
|
fd = null;
|
|
@@ -1523,7 +1945,7 @@ function log(level, category, message, data) {
|
|
|
1523
1945
|
if (fileBytes + lineBytes > MAX_BYTES && !rotationFailed && !rotateOpenLog()) return;
|
|
1524
1946
|
if (fd === null) return;
|
|
1525
1947
|
try {
|
|
1526
|
-
const written =
|
|
1948
|
+
const written = import_node_fs4.default.writeSync(fd, line);
|
|
1527
1949
|
fileBytes += written;
|
|
1528
1950
|
processBytes += written;
|
|
1529
1951
|
} catch {
|
|
@@ -1536,7 +1958,7 @@ function closeLogger(opts) {
|
|
|
1536
1958
|
if (fd !== null) {
|
|
1537
1959
|
if (opts?.shutdownLine !== false) log("INFO", "shutdown", `${appName} shutting down`);
|
|
1538
1960
|
try {
|
|
1539
|
-
if (fd !== null)
|
|
1961
|
+
if (fd !== null) import_node_fs4.default.closeSync(fd);
|
|
1540
1962
|
} catch {
|
|
1541
1963
|
}
|
|
1542
1964
|
}
|
|
@@ -1558,7 +1980,7 @@ function isHiddenProvider(provider) {
|
|
|
1558
1980
|
}
|
|
1559
1981
|
|
|
1560
1982
|
// src/auth-storage.ts
|
|
1561
|
-
var
|
|
1983
|
+
var import_gg_ai2 = require("@kenkaiiii/gg-ai");
|
|
1562
1984
|
|
|
1563
1985
|
// src/minimax-region.ts
|
|
1564
1986
|
var MINIMAX_GLOBAL_BASE_URL = "https://api.minimax.io/anthropic";
|
|
@@ -1703,7 +2125,7 @@ function cachedMiniMaxRegion(apiKey) {
|
|
|
1703
2125
|
}
|
|
1704
2126
|
function readStoredBaseUrlSync(authFile, provider) {
|
|
1705
2127
|
try {
|
|
1706
|
-
const data = JSON.parse((0,
|
|
2128
|
+
const data = JSON.parse((0, import_node_fs5.readFileSync)(authFile, "utf-8"));
|
|
1707
2129
|
return activeBaseUrlEntry(data, provider)?.baseUrl;
|
|
1708
2130
|
} catch {
|
|
1709
2131
|
return void 0;
|
|
@@ -1717,6 +2139,8 @@ function refreshThresholdMs(creds) {
|
|
|
1717
2139
|
}
|
|
1718
2140
|
var USAGE_EXHAUSTED_DEFAULT_MS = 15 * 60 * 1e3;
|
|
1719
2141
|
var STATIC_API_KEY_PROVIDERS = /* @__PURE__ */ new Set([
|
|
2142
|
+
// Anthropic is API-key only; Claude subscriptions run through Claude Code.
|
|
2143
|
+
"anthropic",
|
|
1720
2144
|
"glm",
|
|
1721
2145
|
"moonshot",
|
|
1722
2146
|
"xiaomi",
|
|
@@ -1797,11 +2221,44 @@ var AuthStorage = class {
|
|
|
1797
2221
|
if (provider === "gemini") {
|
|
1798
2222
|
return Boolean(this.data["gemini"] || this.data[GEMINI_API_KEY]);
|
|
1799
2223
|
}
|
|
2224
|
+
if (provider === "anthropic") {
|
|
2225
|
+
return Boolean(this.data.anthropic) && !isLegacyClaudeOAuth(this.data.anthropic) || isClaudeCodeAuthMarker(this.data[CLAUDE_CODE_AUTH_KEY]);
|
|
2226
|
+
}
|
|
1800
2227
|
if (provider === "local") {
|
|
1801
2228
|
return Object.keys(this.data).some((key) => key.startsWith(LOCAL_AUTH_KEY_PREFIX));
|
|
1802
2229
|
}
|
|
1803
2230
|
return Boolean(this.data[provider]);
|
|
1804
2231
|
}
|
|
2232
|
+
/** True when the user signed in with Claude through Claude Code (marker only, no token). */
|
|
2233
|
+
async hasClaudeCodeLogin() {
|
|
2234
|
+
await this.ensureFresh();
|
|
2235
|
+
return isClaudeCodeAuthMarker(this.data[CLAUDE_CODE_AUTH_KEY]);
|
|
2236
|
+
}
|
|
2237
|
+
/** Record a Claude Code sign-in. Claude Code keeps the token; auth.json gets only the marker. */
|
|
2238
|
+
async setClaudeCodeLogin() {
|
|
2239
|
+
await this.mutateLatest((latest) => {
|
|
2240
|
+
latest[CLAUDE_CODE_AUTH_KEY] = { ...CLAUDE_CODE_AUTH_MARKER };
|
|
2241
|
+
if (isLegacyClaudeOAuth(latest.anthropic)) delete latest.anthropic;
|
|
2242
|
+
});
|
|
2243
|
+
}
|
|
2244
|
+
/**
|
|
2245
|
+
* Remove an old GG Claude sign-in token (`sk-ant-oat…`), if any. True when one
|
|
2246
|
+
* was removed, so the caller can tell the user once to sign in with Claude again.
|
|
2247
|
+
*/
|
|
2248
|
+
async takeLegacyClaudeSignIn() {
|
|
2249
|
+
await this.ensureFresh();
|
|
2250
|
+
if (!isLegacyClaudeOAuth(this.data.anthropic)) return false;
|
|
2251
|
+
let removed = false;
|
|
2252
|
+
await this.mutateLatest((latest) => {
|
|
2253
|
+
if (!isLegacyClaudeOAuth(latest.anthropic)) return;
|
|
2254
|
+
delete latest.anthropic;
|
|
2255
|
+
removed = true;
|
|
2256
|
+
});
|
|
2257
|
+
return removed;
|
|
2258
|
+
}
|
|
2259
|
+
async clearClaudeCodeLogin() {
|
|
2260
|
+
await this.clearCredentials(CLAUDE_CODE_AUTH_KEY);
|
|
2261
|
+
}
|
|
1805
2262
|
/** Endpoint ids that currently have a `local:<id>` credential stored. */
|
|
1806
2263
|
async listLocalEndpointIds() {
|
|
1807
2264
|
await this.ensureLoaded();
|
|
@@ -1814,7 +2271,7 @@ var AuthStorage = class {
|
|
|
1814
2271
|
*/
|
|
1815
2272
|
async setLocalEndpoint(endpointId, baseUrl, apiKey) {
|
|
1816
2273
|
await this.setCredentials(`${LOCAL_AUTH_KEY_PREFIX}${endpointId}`, {
|
|
1817
|
-
accessToken: apiKey && apiKey.length > 0 ? apiKey :
|
|
2274
|
+
accessToken: apiKey && apiKey.length > 0 ? apiKey : import_gg_ai2.LOCAL_NO_API_KEY,
|
|
1818
2275
|
refreshToken: "",
|
|
1819
2276
|
expiresAt: Date.now() + LOCAL_CREDENTIAL_LIFETIME_MS,
|
|
1820
2277
|
baseUrl
|
|
@@ -1855,7 +2312,7 @@ var AuthStorage = class {
|
|
|
1855
2312
|
const first = !this.loaded;
|
|
1856
2313
|
await withFileLock(this.filePath, async () => {
|
|
1857
2314
|
try {
|
|
1858
|
-
const content = await
|
|
2315
|
+
const content = await import_promises5.default.readFile(this.filePath, "utf-8");
|
|
1859
2316
|
this.data = JSON.parse(content);
|
|
1860
2317
|
if (first) {
|
|
1861
2318
|
log("INFO", "auth", `Loaded credentials from ${this.filePath}`, {
|
|
@@ -1901,7 +2358,7 @@ var AuthStorage = class {
|
|
|
1901
2358
|
}
|
|
1902
2359
|
let changed;
|
|
1903
2360
|
try {
|
|
1904
|
-
const stat = await
|
|
2361
|
+
const stat = await import_promises5.default.stat(this.filePath);
|
|
1905
2362
|
changed = stat.ino !== this.snapshotIno || stat.mtimeMs !== this.snapshotMtimeMs || stat.size !== this.snapshotSize;
|
|
1906
2363
|
} catch {
|
|
1907
2364
|
changed = this.snapshotSize !== -1;
|
|
@@ -1914,7 +2371,7 @@ var AuthStorage = class {
|
|
|
1914
2371
|
*/
|
|
1915
2372
|
async rememberSnapshot() {
|
|
1916
2373
|
try {
|
|
1917
|
-
const stat = await
|
|
2374
|
+
const stat = await import_promises5.default.stat(this.filePath);
|
|
1918
2375
|
this.snapshotMtimeMs = stat.mtimeMs;
|
|
1919
2376
|
this.snapshotSize = stat.size;
|
|
1920
2377
|
this.snapshotIno = stat.ino;
|
|
@@ -2055,7 +2512,7 @@ var AuthStorage = class {
|
|
|
2055
2512
|
await this.ensureFresh();
|
|
2056
2513
|
}
|
|
2057
2514
|
const directStorageKeys = opts?.storageKeys && !(opts.storageKeys.length === 1 && opts.storageKeys[0] === provider) ? opts.storageKeys : providerStorageKeys(provider);
|
|
2058
|
-
if (!directStorageKeys.some((key) => Boolean(this.data[key]))) {
|
|
2515
|
+
if (!directStorageKeys.some((key) => Boolean(this.data[key])) && !(provider === "anthropic" && this.data[CLAUDE_CODE_AUTH_KEY])) {
|
|
2059
2516
|
await this.reloadLatest();
|
|
2060
2517
|
}
|
|
2061
2518
|
if (opts?.storageKeys && !(opts.storageKeys.length === 1 && opts.storageKeys[0] === provider)) {
|
|
@@ -2078,6 +2535,12 @@ var AuthStorage = class {
|
|
|
2078
2535
|
}
|
|
2079
2536
|
throw new NotLoggedInError(provider);
|
|
2080
2537
|
}
|
|
2538
|
+
if (provider === "anthropic" && (!this.data.anthropic || isLegacyClaudeOAuth(this.data.anthropic))) {
|
|
2539
|
+
if (isClaudeCodeAuthMarker(this.data[CLAUDE_CODE_AUTH_KEY])) {
|
|
2540
|
+
return { accessToken: "", refreshToken: "", expiresAt: Number.MAX_SAFE_INTEGER };
|
|
2541
|
+
}
|
|
2542
|
+
if (this.data.anthropic) throw new NotLoggedInError(provider);
|
|
2543
|
+
}
|
|
2081
2544
|
const dual = dualAuthProvider(provider);
|
|
2082
2545
|
const dualOAuthCreds = dual ? this.data[dual.oauthKey] : void 0;
|
|
2083
2546
|
if (dual && dualOAuthCreds) {
|
|
@@ -2140,7 +2603,7 @@ var AuthStorage = class {
|
|
|
2140
2603
|
this.data = latest;
|
|
2141
2604
|
return latestCreds;
|
|
2142
2605
|
}
|
|
2143
|
-
const refreshFn = provider === "
|
|
2606
|
+
const refreshFn = provider === "gemini" ? refreshGeminiToken : provider === MOONSHOT_OAUTH_KEY ? refreshKimiToken : provider === XAI_OAUTH_KEY ? refreshXaiToken : refreshOpenAIToken;
|
|
2144
2607
|
let refreshed;
|
|
2145
2608
|
try {
|
|
2146
2609
|
refreshed = await refreshFn(latestCreds.refreshToken);
|
|
@@ -2199,7 +2662,7 @@ var AuthStorage = class {
|
|
|
2199
2662
|
};
|
|
2200
2663
|
async function readAuthData(filePath) {
|
|
2201
2664
|
try {
|
|
2202
|
-
const content = await
|
|
2665
|
+
const content = await import_promises5.default.readFile(filePath, "utf-8");
|
|
2203
2666
|
return JSON.parse(content);
|
|
2204
2667
|
} catch (error) {
|
|
2205
2668
|
if (error.code === "ENOENT") return {};
|
|
@@ -2209,10 +2672,10 @@ async function readAuthData(filePath) {
|
|
|
2209
2672
|
async function atomicWriteFile(filePath, content) {
|
|
2210
2673
|
const tmpPath = `${filePath}.${process.pid}.${Date.now()}.${import_node_crypto6.default.randomUUID().slice(0, 8)}.tmp`;
|
|
2211
2674
|
try {
|
|
2212
|
-
await
|
|
2213
|
-
await
|
|
2675
|
+
await import_promises5.default.writeFile(tmpPath, content, { encoding: "utf-8", mode: 384 });
|
|
2676
|
+
await import_promises5.default.rename(tmpPath, filePath);
|
|
2214
2677
|
} catch (err) {
|
|
2215
|
-
await
|
|
2678
|
+
await import_promises5.default.unlink(tmpPath).catch(() => {
|
|
2216
2679
|
});
|
|
2217
2680
|
throw err;
|
|
2218
2681
|
}
|
|
@@ -2415,9 +2878,9 @@ var MODELS = [
|
|
|
2415
2878
|
billing: CODEX_FAST_BILLING
|
|
2416
2879
|
},
|
|
2417
2880
|
// GPT-6 Sol + Luna — released 2026-09-22 below Astra, replacing the whole
|
|
2418
|
-
// GPT-5.6 family (Sol/Terra/Luna; there
|
|
2881
|
+
// GPT-5.6 family (Sol/Terra/Luna; there was no GPT-6 Terra — OpenAI's Codex
|
|
2419
2882
|
// catalog upgrades 5.6 Terra to 6 Sol). GPT-6.1 Sol (2026-09-29) then replaced
|
|
2420
|
-
// GPT-6 Sol. Same window split as Astra: 1.05M on the public Responses API,
|
|
2883
|
+
// GPT-6 Sol, and GPT-6.1 Terra (2026-10-26) sits between Sol and Luna. Same window split as Astra: 1.05M on the public Responses API,
|
|
2421
2884
|
// 272K on the Codex route; 128K output, text+image input, freeform
|
|
2422
2885
|
// apply_patch, responses-lite transport. The GPT-5.6 ids and `gpt-6-sol` are
|
|
2423
2886
|
// retired — a saved session on one falls back to the provider default on
|
|
@@ -2459,6 +2922,40 @@ var MODELS = [
|
|
|
2459
2922
|
maxThinkingLevel: "ultra",
|
|
2460
2923
|
billing: CODEX_FAST_BILLING
|
|
2461
2924
|
},
|
|
2925
|
+
{
|
|
2926
|
+
// GPT-6.1 Terra (Codex priority 7, default low, client >= 0.153.0). $1/$5
|
|
2927
|
+
// MTok, cached input $0.05. Unlike Sol/Astra the Codex route gets a 500K
|
|
2928
|
+
// window (catalog `context_window`). Same ladder and Ultra preset as Sol.
|
|
2929
|
+
id: "gpt-6.1-terra",
|
|
2930
|
+
name: "GPT-6.1 Terra",
|
|
2931
|
+
provider: "openai",
|
|
2932
|
+
contextWindow: 105e4,
|
|
2933
|
+
codexContextWindow: 5e5,
|
|
2934
|
+
maxOutputTokens: 128e3,
|
|
2935
|
+
supportsThinking: true,
|
|
2936
|
+
defaultThinkingLevel: "low",
|
|
2937
|
+
supportsImages: true,
|
|
2938
|
+
supportsVideo: false,
|
|
2939
|
+
costTier: "medium",
|
|
2940
|
+
maxThinkingLevel: "ultra"
|
|
2941
|
+
},
|
|
2942
|
+
{
|
|
2943
|
+
// Codex Fast mode for 6.1 Terra ("1.5x speed") — see `gpt-6-astra-fast`
|
|
2944
|
+
// for the wire mapping and billing.
|
|
2945
|
+
id: "gpt-6.1-terra-fast",
|
|
2946
|
+
name: "GPT-6.1 Terra Fast",
|
|
2947
|
+
provider: "openai",
|
|
2948
|
+
contextWindow: 105e4,
|
|
2949
|
+
codexContextWindow: 5e5,
|
|
2950
|
+
maxOutputTokens: 128e3,
|
|
2951
|
+
supportsThinking: true,
|
|
2952
|
+
defaultThinkingLevel: "low",
|
|
2953
|
+
supportsImages: true,
|
|
2954
|
+
supportsVideo: false,
|
|
2955
|
+
costTier: "medium",
|
|
2956
|
+
maxThinkingLevel: "ultra",
|
|
2957
|
+
billing: CODEX_FAST_BILLING
|
|
2958
|
+
},
|
|
2462
2959
|
{
|
|
2463
2960
|
// Luna — "Fast and affordable model for easier tasks." (Codex priority 4,
|
|
2464
2961
|
// default medium, needs a Codex client >= 0.155.0). $0.10/$0.50 MTok.
|
|
@@ -3319,12 +3816,12 @@ function clampThinkingForPlanMode(level) {
|
|
|
3319
3816
|
}
|
|
3320
3817
|
|
|
3321
3818
|
// src/local-models.ts
|
|
3322
|
-
var
|
|
3819
|
+
var import_gg_ai3 = require("@kenkaiiii/gg-ai");
|
|
3323
3820
|
var DEFAULT_LOCAL_ENDPOINTS = [
|
|
3324
3821
|
{ id: "ollama", label: "Ollama", baseUrl: "http://127.0.0.1:11434/v1", kind: "ollama" }
|
|
3325
3822
|
];
|
|
3326
3823
|
var FALLBACK_CONTEXT_WINDOW = 4096;
|
|
3327
|
-
var LOCAL_API_KEY_PLACEHOLDER =
|
|
3824
|
+
var LOCAL_API_KEY_PLACEHOLDER = import_gg_ai3.LOCAL_NO_API_KEY;
|
|
3328
3825
|
var DEFAULT_PROBE_TIMEOUT_MS = 1200;
|
|
3329
3826
|
var ENRICH_CONCURRENCY = 6;
|
|
3330
3827
|
var CACHE_TTL_MS = 3e4;
|
|
@@ -3353,7 +3850,7 @@ function endpointRoot(baseUrl) {
|
|
|
3353
3850
|
return baseUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
|
|
3354
3851
|
}
|
|
3355
3852
|
function authHeaders(endpoint) {
|
|
3356
|
-
const key = (0,
|
|
3853
|
+
const key = (0, import_gg_ai3.localBearerKey)(endpoint.apiKey);
|
|
3357
3854
|
return {
|
|
3358
3855
|
...key ? { Authorization: `Bearer ${key}` } : {},
|
|
3359
3856
|
Accept: "application/json"
|
|
@@ -3643,18 +4140,138 @@ function findProbedModel(probes, modelId) {
|
|
|
3643
4140
|
return void 0;
|
|
3644
4141
|
}
|
|
3645
4142
|
|
|
4143
|
+
// src/claude-code/usage.ts
|
|
4144
|
+
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
4145
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
4146
|
+
var USAGE_FILE = "usage.json";
|
|
4147
|
+
var WINDOWS = {
|
|
4148
|
+
five_hour: { kind: "current", label: "5-hour" },
|
|
4149
|
+
seven_day: { kind: "weekly", label: "Weekly" }
|
|
4150
|
+
};
|
|
4151
|
+
function finite(value) {
|
|
4152
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
4153
|
+
}
|
|
4154
|
+
function toWindow(key, raw) {
|
|
4155
|
+
const shape = WINDOWS[key];
|
|
4156
|
+
const fraction = finite(raw?.utilization);
|
|
4157
|
+
if (!shape || fraction === void 0) return null;
|
|
4158
|
+
const resetsAt = finite(raw?.resetsAt);
|
|
4159
|
+
return {
|
|
4160
|
+
...shape,
|
|
4161
|
+
usedPercent: Math.min(100, Math.max(0, fraction * 100)),
|
|
4162
|
+
...resetsAt !== void 0 ? { resetsAt: resetsAt * 1e3 } : {}
|
|
4163
|
+
};
|
|
4164
|
+
}
|
|
4165
|
+
function mergeClaudeCodeRateLimit(info, previous, now = Date.now()) {
|
|
4166
|
+
const reported = info.unifiedWindows ? Object.entries(info.unifiedWindows).map(([key, raw]) => toWindow(key, raw)) : info.rateLimitType ? [toWindow(info.rateLimitType, info)] : [];
|
|
4167
|
+
const byKind = new Map(previous?.windows.map((w) => [w.kind, w]) ?? []);
|
|
4168
|
+
for (const window of reported) if (window) byKind.set(window.kind, window);
|
|
4169
|
+
const windows = [...byKind.values()].sort(
|
|
4170
|
+
(a, b) => a.kind === b.kind ? 0 : a.kind === "current" ? -1 : 1
|
|
4171
|
+
);
|
|
4172
|
+
return { provider: "anthropic", displayName: "Anthropic", windows, fetchedAt: now };
|
|
4173
|
+
}
|
|
4174
|
+
function usagePath(opts) {
|
|
4175
|
+
return import_node_path5.default.join(claudeCodeHome(opts), USAGE_FILE);
|
|
4176
|
+
}
|
|
4177
|
+
async function readClaudeCodeUsage(opts = {}) {
|
|
4178
|
+
let parsed;
|
|
4179
|
+
try {
|
|
4180
|
+
parsed = JSON.parse(await import_promises6.default.readFile(usagePath(opts), "utf8"));
|
|
4181
|
+
} catch {
|
|
4182
|
+
return null;
|
|
4183
|
+
}
|
|
4184
|
+
if (!Array.isArray(parsed?.windows) || typeof parsed.fetchedAt !== "number") return null;
|
|
4185
|
+
const now = opts.now ?? Date.now();
|
|
4186
|
+
const windows = parsed.windows.filter(
|
|
4187
|
+
(w) => (w.kind === "current" || w.kind === "weekly") && typeof w.usedPercent === "number" && (w.resetsAt === void 0 || w.resetsAt > now)
|
|
4188
|
+
);
|
|
4189
|
+
return { provider: "anthropic", displayName: "Anthropic", windows, fetchedAt: parsed.fetchedAt };
|
|
4190
|
+
}
|
|
4191
|
+
var writeQueue = Promise.resolve();
|
|
4192
|
+
function recordClaudeCodeRateLimit(info, opts = {}) {
|
|
4193
|
+
const write = async () => {
|
|
4194
|
+
const now = opts.now ?? Date.now();
|
|
4195
|
+
const next = mergeClaudeCodeRateLimit(info, await readClaudeCodeUsage({ ...opts, now }), now);
|
|
4196
|
+
if (next.windows.length === 0) return;
|
|
4197
|
+
const file = usagePath(opts);
|
|
4198
|
+
await import_promises6.default.mkdir(import_node_path5.default.dirname(file), { recursive: true });
|
|
4199
|
+
await import_promises6.default.writeFile(file, JSON.stringify(next), "utf8");
|
|
4200
|
+
};
|
|
4201
|
+
writeQueue = writeQueue.then(write).catch(() => {
|
|
4202
|
+
});
|
|
4203
|
+
return writeQueue;
|
|
4204
|
+
}
|
|
4205
|
+
async function clearClaudeCodeUsage(opts = {}) {
|
|
4206
|
+
await writeQueue;
|
|
4207
|
+
await import_promises6.default.rm(usagePath(opts), { force: true }).catch(() => {
|
|
4208
|
+
});
|
|
4209
|
+
}
|
|
4210
|
+
|
|
4211
|
+
// src/claude-code/sign-in.ts
|
|
4212
|
+
async function signInWithClaudeCode(auth, callbacks, opts = {}) {
|
|
4213
|
+
if (!opts.binary && !resolveClaudeCodeBinary(opts)) {
|
|
4214
|
+
callbacks.onStatus("Downloading Claude Code (one time)\u2026");
|
|
4215
|
+
await ensureClaudeCodeBinary({
|
|
4216
|
+
...opts,
|
|
4217
|
+
onProgress: (progress) => {
|
|
4218
|
+
callbacks.onStatus(formatClaudeCodeInstallProgress(progress));
|
|
4219
|
+
opts.onProgress?.(progress);
|
|
4220
|
+
}
|
|
4221
|
+
});
|
|
4222
|
+
}
|
|
4223
|
+
let status = await claudeCodeAuthStatus(opts);
|
|
4224
|
+
if (!status.loggedIn) {
|
|
4225
|
+
callbacks.onStatus("Opening Claude sign-in\u2026");
|
|
4226
|
+
await loginClaudeCode(callbacks, opts);
|
|
4227
|
+
status = await claudeCodeAuthStatus(opts);
|
|
4228
|
+
}
|
|
4229
|
+
if (!status.loggedIn) throw new Error("Claude sign-in didn't finish. Try again.");
|
|
4230
|
+
await auth.setClaudeCodeLogin();
|
|
4231
|
+
return status;
|
|
4232
|
+
}
|
|
4233
|
+
async function signOutOfClaudeCode(auth, opts = {}) {
|
|
4234
|
+
await auth.clearClaudeCodeLogin();
|
|
4235
|
+
await clearClaudeCodeUsage(opts);
|
|
4236
|
+
try {
|
|
4237
|
+
await logoutClaudeCode(opts);
|
|
4238
|
+
} catch (err) {
|
|
4239
|
+
log(
|
|
4240
|
+
"WARN",
|
|
4241
|
+
"auth",
|
|
4242
|
+
`claude auth logout failed: ${err instanceof Error ? err.message : String(err)}`
|
|
4243
|
+
);
|
|
4244
|
+
}
|
|
4245
|
+
}
|
|
4246
|
+
|
|
3646
4247
|
// src/auth-providers.ts
|
|
3647
4248
|
var ALL_AUTH_PROVIDERS = [
|
|
3648
4249
|
{
|
|
3649
4250
|
value: "anthropic",
|
|
3650
4251
|
label: "Anthropic",
|
|
3651
4252
|
description: "Claude Fable 5.1, Opus 5.5, Opus 5.5 Fast, Sonnet 5.5, Haiku 5.5",
|
|
3652
|
-
methods: ["oauth"]
|
|
4253
|
+
methods: ["oauth", "apikey"],
|
|
4254
|
+
apiKeyLabel: "Anthropic",
|
|
4255
|
+
methodDetails: {
|
|
4256
|
+
oauth: {
|
|
4257
|
+
method: "oauth",
|
|
4258
|
+
label: "Sign in with Claude",
|
|
4259
|
+
billing: "Uses your Claude Pro or Max plan.",
|
|
4260
|
+
when: "Runs through Anthropic's Claude Code, which GG Coder downloads once (about 140 MB) the first time you pick this.",
|
|
4261
|
+
requires: "A Claude Pro or Max subscription."
|
|
4262
|
+
},
|
|
4263
|
+
apikey: {
|
|
4264
|
+
method: "apikey",
|
|
4265
|
+
label: "Anthropic API key",
|
|
4266
|
+
billing: "Pay-per-token from an Anthropic Console key.",
|
|
4267
|
+
when: "No subscription needed. Used only while you are not signed in with Claude."
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
3653
4270
|
},
|
|
3654
4271
|
{
|
|
3655
4272
|
value: "openai",
|
|
3656
4273
|
label: "OpenAI",
|
|
3657
|
-
description: "GPT-6 Astra, GPT-6 Astra Fast, GPT-6.1 Sol, GPT-6.1 Sol Fast, GPT-6 Luna, GPT-6 Luna Fast",
|
|
4274
|
+
description: "GPT-6 Astra, GPT-6 Astra Fast, GPT-6.1 Sol, GPT-6.1 Sol Fast, GPT-6.1 Terra, GPT-6.1 Terra Fast, GPT-6 Luna, GPT-6 Luna Fast",
|
|
3658
4275
|
methods: ["oauth"]
|
|
3659
4276
|
},
|
|
3660
4277
|
{
|
|
@@ -3817,6 +4434,9 @@ function authPriorityNote(provider) {
|
|
|
3817
4434
|
if (provider === "gemini") {
|
|
3818
4435
|
return "Uses the Gemini API key first when one is set; otherwise the Google sign-in.";
|
|
3819
4436
|
}
|
|
4437
|
+
if (provider === "anthropic") {
|
|
4438
|
+
return "Uses Sign in with Claude while you are signed in; otherwise the Anthropic API key.";
|
|
4439
|
+
}
|
|
3820
4440
|
const dual = dualAuthProvider(provider);
|
|
3821
4441
|
if (!dual) return void 0;
|
|
3822
4442
|
return `Uses ${dual.oauthLabel} first; the ${dual.apiKeyLabel} takes over when it runs out, then switches back.`;
|
|
@@ -3831,7 +4451,6 @@ var SubscriptionUsageError = class extends Error {
|
|
|
3831
4451
|
this.name = "SubscriptionUsageError";
|
|
3832
4452
|
}
|
|
3833
4453
|
};
|
|
3834
|
-
var ANTHROPIC_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
3835
4454
|
var CODEX_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
|
|
3836
4455
|
function finiteNumber(value) {
|
|
3837
4456
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
@@ -3899,45 +4518,6 @@ async function readUsageResponse(response, now) {
|
|
|
3899
4518
|
throw new SubscriptionUsageError("Subscription usage response was not valid JSON");
|
|
3900
4519
|
}
|
|
3901
4520
|
}
|
|
3902
|
-
async function fetchAnthropicUsage(credentials, fetchFn, signal, now) {
|
|
3903
|
-
const response = await fetchFn(ANTHROPIC_USAGE_URL, {
|
|
3904
|
-
method: "GET",
|
|
3905
|
-
signal,
|
|
3906
|
-
headers: {
|
|
3907
|
-
Authorization: `Bearer ${credentials.accessToken}`,
|
|
3908
|
-
Accept: "application/json",
|
|
3909
|
-
"anthropic-version": "2023-06-01",
|
|
3910
|
-
"anthropic-beta": "oauth-2025-04-20",
|
|
3911
|
-
"User-Agent": "ggcoder"
|
|
3912
|
-
}
|
|
3913
|
-
});
|
|
3914
|
-
const data = await readUsageResponse(response, now());
|
|
3915
|
-
const windows = [];
|
|
3916
|
-
const currentPercent = clampPercent(data.five_hour?.utilization);
|
|
3917
|
-
if (currentPercent !== void 0) {
|
|
3918
|
-
windows.push({
|
|
3919
|
-
kind: "current",
|
|
3920
|
-
label: "5-hour",
|
|
3921
|
-
usedPercent: currentPercent,
|
|
3922
|
-
resetsAt: isoTimestamp(data.five_hour?.resets_at)
|
|
3923
|
-
});
|
|
3924
|
-
}
|
|
3925
|
-
const weeklyPercent = clampPercent(data.seven_day?.utilization);
|
|
3926
|
-
if (weeklyPercent !== void 0) {
|
|
3927
|
-
windows.push({
|
|
3928
|
-
kind: "weekly",
|
|
3929
|
-
label: "Weekly",
|
|
3930
|
-
usedPercent: weeklyPercent,
|
|
3931
|
-
resetsAt: isoTimestamp(data.seven_day?.resets_at)
|
|
3932
|
-
});
|
|
3933
|
-
}
|
|
3934
|
-
return {
|
|
3935
|
-
provider: "anthropic",
|
|
3936
|
-
displayName: "Anthropic",
|
|
3937
|
-
windows,
|
|
3938
|
-
fetchedAt: now()
|
|
3939
|
-
};
|
|
3940
|
-
}
|
|
3941
4521
|
async function fetchCodexUsage(credentials, fetchFn, signal, now) {
|
|
3942
4522
|
const headers = {
|
|
3943
4523
|
Authorization: `Bearer ${credentials.accessToken}`,
|
|
@@ -4053,7 +4633,7 @@ async function fetchSubscriptionUsage(provider, credentials, options = {}) {
|
|
|
4053
4633
|
const now = options.now ?? Date.now;
|
|
4054
4634
|
const signal = AbortSignal.timeout(options.timeoutMs ?? 8e3);
|
|
4055
4635
|
try {
|
|
4056
|
-
return provider === "
|
|
4636
|
+
return provider === "openai" ? await fetchCodexUsage(credentials, fetchFn, signal, now) : await fetchKimiUsage(credentials, fetchFn, signal, now);
|
|
4057
4637
|
} catch (error) {
|
|
4058
4638
|
if (error instanceof SubscriptionUsageError) throw error;
|
|
4059
4639
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -4389,9 +4969,9 @@ async function transcribeVoice(fileUrl) {
|
|
|
4389
4969
|
}
|
|
4390
4970
|
|
|
4391
4971
|
// src/auto-update.ts
|
|
4392
|
-
var
|
|
4393
|
-
var
|
|
4394
|
-
var
|
|
4972
|
+
var import_node_child_process3 = require("child_process");
|
|
4973
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
4974
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
4395
4975
|
var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
4396
4976
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
4397
4977
|
function compareVersions(a, b) {
|
|
@@ -4406,7 +4986,7 @@ function compareVersions(a, b) {
|
|
|
4406
4986
|
function performUpdateInBackground(command) {
|
|
4407
4987
|
try {
|
|
4408
4988
|
const parts = command.split(" ");
|
|
4409
|
-
const child = (0,
|
|
4989
|
+
const child = (0, import_node_child_process3.spawn)(parts[0], parts.slice(1), {
|
|
4410
4990
|
detached: true,
|
|
4411
4991
|
stdio: "ignore",
|
|
4412
4992
|
env: { ...process.env, npm_config_loglevel: "silent" }
|
|
@@ -4424,7 +5004,7 @@ function createAutoUpdater(config) {
|
|
|
4424
5004
|
}
|
|
4425
5005
|
function readState() {
|
|
4426
5006
|
try {
|
|
4427
|
-
const raw =
|
|
5007
|
+
const raw = import_node_fs6.default.readFileSync(stateFilePath(), "utf-8");
|
|
4428
5008
|
return JSON.parse(raw);
|
|
4429
5009
|
} catch {
|
|
4430
5010
|
return null;
|
|
@@ -4433,8 +5013,8 @@ function createAutoUpdater(config) {
|
|
|
4433
5013
|
function writeState(state) {
|
|
4434
5014
|
try {
|
|
4435
5015
|
const filePath = stateFilePath();
|
|
4436
|
-
|
|
4437
|
-
|
|
5016
|
+
import_node_fs6.default.mkdirSync(import_node_path6.default.dirname(filePath), { recursive: true, mode: 448 });
|
|
5017
|
+
import_node_fs6.default.writeFileSync(filePath, JSON.stringify(state));
|
|
4438
5018
|
} catch {
|
|
4439
5019
|
}
|
|
4440
5020
|
}
|
|
@@ -4560,6 +5140,9 @@ function createAutoUpdater(config) {
|
|
|
4560
5140
|
0 && (module.exports = {
|
|
4561
5141
|
AUTH_PROVIDERS,
|
|
4562
5142
|
AuthStorage,
|
|
5143
|
+
CLAUDE_CODE_AUTH_KEY,
|
|
5144
|
+
CLAUDE_CODE_AUTH_MARKER,
|
|
5145
|
+
CLAUDE_CODE_MANIFEST,
|
|
4563
5146
|
DEFAULT_LOCAL_ENDPOINTS,
|
|
4564
5147
|
DEFAULT_MAX_VIDEO_BYTES,
|
|
4565
5148
|
FALLBACK_CONTEXT_WINDOW,
|
|
@@ -4582,6 +5165,14 @@ function createAutoUpdater(config) {
|
|
|
4582
5165
|
XIAOMI_TOKEN_PLAN_BASE_URLS,
|
|
4583
5166
|
authPriorityNote,
|
|
4584
5167
|
clampThinkingForPlanMode,
|
|
5168
|
+
claudeCodeAuthStatus,
|
|
5169
|
+
claudeCodeBinaryPath,
|
|
5170
|
+
claudeCodeCallbackUrl,
|
|
5171
|
+
claudeCodeConfigDir,
|
|
5172
|
+
claudeCodeEnv,
|
|
5173
|
+
claudeCodeHome,
|
|
5174
|
+
claudeCodePlatformKey,
|
|
5175
|
+
clearClaudeCodeUsage,
|
|
4585
5176
|
clearLocalDiscoveryCache,
|
|
4586
5177
|
clearRuntimeModels,
|
|
4587
5178
|
closeLogger,
|
|
@@ -4595,8 +5186,10 @@ function createAutoUpdater(config) {
|
|
|
4595
5186
|
dualAuthProvider,
|
|
4596
5187
|
dualAuthProviderByOAuthKey,
|
|
4597
5188
|
endpointRoot,
|
|
5189
|
+
ensureClaudeCodeBinary,
|
|
4598
5190
|
fetchSubscriptionUsage,
|
|
4599
5191
|
findProbedModel,
|
|
5192
|
+
formatClaudeCodeInstallProgress,
|
|
4600
5193
|
formatLocalModelId,
|
|
4601
5194
|
generatePKCE,
|
|
4602
5195
|
getAllModels,
|
|
@@ -4604,8 +5197,6 @@ function createAutoUpdater(config) {
|
|
|
4604
5197
|
getAuthProvider,
|
|
4605
5198
|
getAuthStorageKey,
|
|
4606
5199
|
getAuthStorageKeys,
|
|
4607
|
-
getClaudeCliUserAgent,
|
|
4608
|
-
getClaudeCodeVersion,
|
|
4609
5200
|
getContextWindow,
|
|
4610
5201
|
getDefaultModel,
|
|
4611
5202
|
getDefaultThinkingLevel,
|
|
@@ -4623,9 +5214,11 @@ function createAutoUpdater(config) {
|
|
|
4623
5214
|
getVideoByteLimit,
|
|
4624
5215
|
grokCliBaseUrl,
|
|
4625
5216
|
grokCliHeaders,
|
|
5217
|
+
isClaudeCodeAuthMarker,
|
|
4626
5218
|
isGrokCliEndpoint,
|
|
4627
5219
|
isHiddenProvider,
|
|
4628
5220
|
isKimiCodingEndpoint,
|
|
5221
|
+
isLegacyClaudeOAuth,
|
|
4629
5222
|
isLocalModelId,
|
|
4630
5223
|
isLoggerOpen,
|
|
4631
5224
|
isModelLoaded,
|
|
@@ -4636,21 +5229,23 @@ function createAutoUpdater(config) {
|
|
|
4636
5229
|
localAuthStorageKey,
|
|
4637
5230
|
localModelShortName,
|
|
4638
5231
|
log,
|
|
4639
|
-
|
|
5232
|
+
loginClaudeCode,
|
|
4640
5233
|
loginGemini,
|
|
4641
5234
|
loginKimi,
|
|
4642
5235
|
loginOpenAI,
|
|
4643
5236
|
loginXai,
|
|
5237
|
+
logoutClaudeCode,
|
|
5238
|
+
mergeClaudeCodeRateLimit,
|
|
4644
5239
|
oauthStorageKey,
|
|
4645
5240
|
ollamaServedContext,
|
|
4646
5241
|
openLog,
|
|
4647
5242
|
parseLocalModelId,
|
|
4648
5243
|
parseOpenRouterCatalog,
|
|
4649
|
-
pendingClaudeCodeVersionRefresh,
|
|
4650
5244
|
probeEndpoint,
|
|
4651
5245
|
providerStorageKeys,
|
|
5246
|
+
readClaudeCodeUsage,
|
|
4652
5247
|
readStoredBaseUrlSync,
|
|
4653
|
-
|
|
5248
|
+
recordClaudeCodeRateLimit,
|
|
4654
5249
|
refreshGeminiToken,
|
|
4655
5250
|
refreshKimiToken,
|
|
4656
5251
|
refreshOpenAIToken,
|
|
@@ -4658,8 +5253,11 @@ function createAutoUpdater(config) {
|
|
|
4658
5253
|
registerLogCleanup,
|
|
4659
5254
|
registerRuntimeModels,
|
|
4660
5255
|
resample,
|
|
5256
|
+
resolveClaudeCodeBinary,
|
|
4661
5257
|
setProgressCallback,
|
|
4662
5258
|
setProviderCatalog,
|
|
5259
|
+
signInWithClaudeCode,
|
|
5260
|
+
signOutOfClaudeCode,
|
|
4663
5261
|
toModelInfo,
|
|
4664
5262
|
transcribeVoice,
|
|
4665
5263
|
usesOpenAICodexTransport,
|