opencode-usage 0.5.5 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +62 -17
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -321,6 +321,31 @@ async function directCodexPing(alias) {
|
|
|
321
321
|
};
|
|
322
322
|
}
|
|
323
323
|
}
|
|
324
|
+
async function tryDirectCodexRefresh(alias) {
|
|
325
|
+
const STORE_PATHS = [
|
|
326
|
+
join8(homedir6(), ".config", "opencode", "codex-multi-account-accounts.json"),
|
|
327
|
+
join8(homedir6(), ".config", "opencode", "codex-multi-accounts.json"),
|
|
328
|
+
join8(homedir6(), ".config", "oc-codex-multi-account", "accounts.json")
|
|
329
|
+
];
|
|
330
|
+
let storePath = null;
|
|
331
|
+
let store = null;
|
|
332
|
+
for (const p of STORE_PATHS) {
|
|
333
|
+
try {
|
|
334
|
+
store = JSON.parse(await Bun.file(p).text());
|
|
335
|
+
storePath = p;
|
|
336
|
+
break;
|
|
337
|
+
} catch {
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
if (!store || !storePath)
|
|
342
|
+
return false;
|
|
343
|
+
const accounts = store.accounts ?? {};
|
|
344
|
+
const account = accounts[alias];
|
|
345
|
+
if (!account)
|
|
346
|
+
return false;
|
|
347
|
+
return refreshSingleCodexToken(alias, account, storePath);
|
|
348
|
+
}
|
|
324
349
|
function decodeJwtPayload(token) {
|
|
325
350
|
try {
|
|
326
351
|
const parts = token.split(".");
|
|
@@ -341,7 +366,7 @@ function getAccountIdFromJwt(claims) {
|
|
|
341
366
|
const auth = claims?.["https://api.openai.com/auth"];
|
|
342
367
|
return auth?.chatgpt_account_id ?? null;
|
|
343
368
|
}
|
|
344
|
-
async function refreshSingleCodexToken(alias, account, storePath
|
|
369
|
+
async function refreshSingleCodexToken(alias, account, storePath) {
|
|
345
370
|
const refreshToken = account.refreshToken;
|
|
346
371
|
if (typeof refreshToken !== "string" || !refreshToken) {
|
|
347
372
|
console.log(`[proactiveRefresh] ${alias}: no refresh token, skipping`);
|
|
@@ -366,16 +391,21 @@ async function refreshSingleCodexToken(alias, account, storePath, store) {
|
|
|
366
391
|
const accessClaims = decodeJwtPayload(tokens.access_token);
|
|
367
392
|
const idClaims = tokens.id_token ? decodeJwtPayload(tokens.id_token) : null;
|
|
368
393
|
const expiresAt = getExpiryFromJwt(accessClaims) ?? getExpiryFromJwt(idClaims) ?? Date.now() + tokens.expires_in * 1000;
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
if (
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
394
|
+
const freshStore = JSON.parse(await Bun.file(storePath).text());
|
|
395
|
+
const freshAccounts = freshStore.accounts ?? {};
|
|
396
|
+
const freshAcct = freshAccounts[alias];
|
|
397
|
+
if (freshAcct) {
|
|
398
|
+
freshAcct.accessToken = tokens.access_token;
|
|
399
|
+
if (tokens.refresh_token)
|
|
400
|
+
freshAcct.refreshToken = tokens.refresh_token;
|
|
401
|
+
if (tokens.id_token)
|
|
402
|
+
freshAcct.idToken = tokens.id_token;
|
|
403
|
+
freshAcct.expiresAt = expiresAt;
|
|
404
|
+
freshAcct.lastRefresh = new Date().toISOString();
|
|
405
|
+
freshAcct.accountId = getAccountIdFromJwt(idClaims) ?? getAccountIdFromJwt(accessClaims) ?? freshAcct.accountId;
|
|
406
|
+
freshAcct.authInvalid = false;
|
|
407
|
+
}
|
|
408
|
+
await Bun.write(storePath, JSON.stringify(freshStore, null, 2));
|
|
379
409
|
const daysLeft = ((expiresAt - Date.now()) / (24 * 60 * 60 * 1000)).toFixed(1);
|
|
380
410
|
console.log(`[proactiveRefresh] ${alias}: refreshed in ${Date.now() - t0}ms, new expiry in ${daysLeft}d`);
|
|
381
411
|
return true;
|
|
@@ -412,7 +442,13 @@ async function proactiveRefreshCodexTokens() {
|
|
|
412
442
|
const timeSinceRefresh = now - lastRefresh;
|
|
413
443
|
const timeToExpiry = expiresAt - now;
|
|
414
444
|
if (timeToExpiry <= 0) {
|
|
415
|
-
console.log(`[proactiveRefresh] ${alias}: token expired,
|
|
445
|
+
console.log(`[proactiveRefresh] ${alias}: token expired, attempting refresh\u2026`);
|
|
446
|
+
const ok2 = await refreshSingleCodexToken(alias, account, storePath);
|
|
447
|
+
if (ok2) {
|
|
448
|
+
refreshed++;
|
|
449
|
+
} else {
|
|
450
|
+
console.log(`[proactiveRefresh] ${alias}: refresh failed \u2014 needs reauth`);
|
|
451
|
+
}
|
|
416
452
|
continue;
|
|
417
453
|
}
|
|
418
454
|
if (timeSinceRefresh < REFRESH_COOLDOWN_MS) {
|
|
@@ -422,7 +458,7 @@ async function proactiveRefreshCodexTokens() {
|
|
|
422
458
|
}
|
|
423
459
|
const hoursStale = (timeSinceRefresh / (60 * 60 * 1000)).toFixed(1);
|
|
424
460
|
console.log(`[proactiveRefresh] ${alias}: ${hoursStale}h since refresh, refreshing\u2026`);
|
|
425
|
-
const ok = await refreshSingleCodexToken(alias, account, storePath
|
|
461
|
+
const ok = await refreshSingleCodexToken(alias, account, storePath);
|
|
426
462
|
if (ok)
|
|
427
463
|
refreshed++;
|
|
428
464
|
}
|
|
@@ -537,8 +573,8 @@ async function clearStaleMetrics(provider, alias) {
|
|
|
537
573
|
const rl = acct.rateLimits;
|
|
538
574
|
for (const key of ["fiveHour", "weekly"]) {
|
|
539
575
|
const w2 = rl[key];
|
|
540
|
-
if (w2?.resetAt && typeof w2.resetAt === "
|
|
541
|
-
if (
|
|
576
|
+
if (w2?.resetAt && typeof w2.resetAt === "number") {
|
|
577
|
+
if (w2.resetAt < now) {
|
|
542
578
|
w2.remaining = w2.limit;
|
|
543
579
|
delete w2.resetAt;
|
|
544
580
|
changed = true;
|
|
@@ -730,7 +766,16 @@ var init_plugin_adapters = __esm(() => {
|
|
|
730
766
|
return { status: "ok", message: "pong" };
|
|
731
767
|
}
|
|
732
768
|
if (direct.status === "expired") {
|
|
733
|
-
ctx.log("info", "Token expired \u2014
|
|
769
|
+
ctx.log("info", "Token expired \u2014 attempting direct token refresh\u2026");
|
|
770
|
+
const directRefreshOk = await tryDirectCodexRefresh(input.alias);
|
|
771
|
+
if (directRefreshOk) {
|
|
772
|
+
const rePing = await directCodexPing(input.alias);
|
|
773
|
+
if (rePing.status === "ok") {
|
|
774
|
+
await clearStaleMetrics(input.provider, input.alias);
|
|
775
|
+
return { status: "ok", message: "pong (token refreshed)" };
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
ctx.log("info", "Direct refresh failed \u2014 trying plugin CLI\u2026");
|
|
734
779
|
try {
|
|
735
780
|
const result = await spawnPluginCli("oc-codex-multi-account", [
|
|
736
781
|
"ping",
|
|
@@ -31109,4 +31154,4 @@ async function main2() {
|
|
|
31109
31154
|
var WATCH_INTERVAL_MS = 5 * 60 * 1000;
|
|
31110
31155
|
main2().catch(console.error);
|
|
31111
31156
|
|
|
31112
|
-
//# debugId=
|
|
31157
|
+
//# debugId=31E49E1C5B0730A864756E2164756E21
|