oc-codex-multi-auth 6.18.0 → 6.19.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.
@@ -307,6 +307,29 @@ function mergeStandaloneAccounts(target, source) {
307
307
  return mergeStandaloneAccounts(source, target);
308
308
  }
309
309
 
310
+ // Mirror of `isStaleGeneratedAccountLabel` / `dropStaleGeneratedLabel` in
311
+ // lib/auth/token-utils.ts and lib/storage/normalize.ts. The standalone CLI
312
+ // reads the pool through this normalizer and never through the compiled
313
+ // `normalizeAccountStorage`, so without the mirror `status`, `list`, `health`,
314
+ // `doctor` and `dashboard` keep printing the org-derived label the plugin
315
+ // itself now drops - next to the account id, which is the identity the label
316
+ // was misnaming. The marker must hold this account's own id suffix so a name
317
+ // set with `codex-label` survives.
318
+ const GENERATED_LABEL_PATTERN = /\s\[id:[^\]]*\]$/;
319
+
320
+ function dropStaleStandaloneLabel(account) {
321
+ const label = typeof account?.accountLabel === "string" ? account.accountLabel.trim() : "";
322
+ const accountId = typeof account?.accountId === "string" ? account.accountId.trim() : "";
323
+ if (!label || !accountId) return account;
324
+ const marker = label.match(GENERATED_LABEL_PATTERN)?.[0];
325
+ if (!marker) return account;
326
+ const suffix = accountId.length > 6 ? accountId.slice(-6) : accountId;
327
+ if (marker !== ` [id:${suffix}]`) return account;
328
+ const next = { ...account };
329
+ delete next.accountLabel;
330
+ return next;
331
+ }
332
+
310
333
  function normalizeStandaloneStorage(storage) {
311
334
  if (!Array.isArray(storage.accounts)) return storage;
312
335
  const accounts = [...storage.accounts];
@@ -324,7 +347,9 @@ function normalizeStandaloneStorage(storage) {
324
347
  if (sourceIndex === i) break;
325
348
  }
326
349
  }
327
- const normalizedAccounts = accounts.filter((_, index) => !removed.has(index));
350
+ const normalizedAccounts = accounts
351
+ .filter((_, index) => !removed.has(index))
352
+ .map(dropStaleStandaloneLabel);
328
353
  return {
329
354
  ...storage,
330
355
  accounts: normalizedAccounts,
@@ -332,9 +357,37 @@ function normalizeStandaloneStorage(storage) {
332
357
  };
333
358
  }
334
359
 
360
+ const MASKED_VALUE = "*****";
361
+ // The head/tail mask keeps eight characters, so it conceals nothing worth
362
+ // concealing below thirteen: `me@x.io` would print in full and `me@x.io12`
363
+ // all but its middle character. `doctor` output is what users paste into
364
+ // issues, so anything shorter is replaced outright instead. Input is trimmed
365
+ // first, or `" me@x.io "` clears the cutoff on padding alone and drops back
366
+ // into the partial mask.
367
+ const MASK_MIN_LENGTH = 13;
368
+
335
369
  function maskValue(value, includeSensitive) {
336
- if (includeSensitive || typeof value !== "string" || value.length <= 8) return value;
337
- return `${value.slice(0, 4)}...${value.slice(-4)}`;
370
+ if (includeSensitive || typeof value !== "string") return value;
371
+ const trimmed = value.trim();
372
+ if (!trimmed) return trimmed;
373
+ if (trimmed.length < MASK_MIN_LENGTH) return MASKED_VALUE;
374
+ return `${trimmed.slice(0, 4)}...${trimmed.slice(-4)}`;
375
+ }
376
+
377
+ // Six characters when the id is shown in full, matching what the
378
+ // in-conversation surfaces print as `id:`. Four when it is head/tail masked,
379
+ // which is the tail `maskValue` already discloses as `accountId` in the same
380
+ // payload, so the printed identity never reveals more of an id than the field
381
+ // beside it. Nothing at all when the id was too short for that mask: the
382
+ // `accountId` next to it is then `*****`, and four raw characters of a short
383
+ // id can be the whole id.
384
+ function accountIdSuffix(accountId, includeSensitive) {
385
+ if (!accountId) return undefined;
386
+ if (includeSensitive) {
387
+ return accountId.length > 6 ? accountId.slice(-6) : accountId;
388
+ }
389
+ if (accountId.length < MASK_MIN_LENGTH) return undefined;
390
+ return accountId.slice(-4);
338
391
  }
339
392
 
340
393
  function summarizeStandaloneAccounts(storage, includeSensitive, tag) {
@@ -345,21 +398,27 @@ function summarizeStandaloneAccounts(storage, includeSensitive, tag) {
345
398
  .filter(({ account }) => !normalizedTag ||
346
399
  (Array.isArray(account?.accountTags) &&
347
400
  account.accountTags.some((entry) => String(entry).toLowerCase() === normalizedTag)))
348
- .map(({ account, index }) => ({
349
- index,
350
- label: account?.accountLabel ?? `Account ${index + 1}`,
351
- email: maskValue(account?.email, includeSensitive),
352
- accountId: maskValue(account?.accountId, includeSensitive),
353
- accountIdSource: account?.accountIdSource,
354
- enabled: account?.enabled !== false,
355
- hasRefreshToken: typeof account?.refreshToken === "string" && account.refreshToken.length > 0,
356
- hasAccessToken: typeof account?.accessToken === "string" && account.accessToken.length > 0,
357
- expiresAt: account?.expiresAt,
358
- expired: typeof account?.expiresAt === "number" ? account.expiresAt <= Date.now() : undefined,
359
- tags: Array.isArray(account?.accountTags) ? account.accountTags : [],
360
- note: account?.accountNote,
361
- rateLimitResetTimes: account?.rateLimitResetTimes ?? {},
362
- }));
401
+ .map(({ account, index }) => {
402
+ const trimmedId =
403
+ typeof account?.accountId === "string" ? account.accountId.trim() : "";
404
+ const accountId = trimmedId || undefined;
405
+ return {
406
+ index,
407
+ label: account?.accountLabel ?? `Account ${index + 1}`,
408
+ email: maskValue(account?.email, includeSensitive),
409
+ accountId: maskValue(accountId, includeSensitive),
410
+ idSuffix: accountIdSuffix(accountId, includeSensitive),
411
+ accountIdSource: account?.accountIdSource,
412
+ enabled: account?.enabled !== false,
413
+ hasRefreshToken: typeof account?.refreshToken === "string" && account.refreshToken.length > 0,
414
+ hasAccessToken: typeof account?.accessToken === "string" && account.accessToken.length > 0,
415
+ expiresAt: account?.expiresAt,
416
+ expired: typeof account?.expiresAt === "number" ? account.expiresAt <= Date.now() : undefined,
417
+ tags: Array.isArray(account?.accountTags) ? account.accountTags : [],
418
+ note: account?.accountNote,
419
+ rateLimitResetTimes: account?.rateLimitResetTimes ?? {},
420
+ };
421
+ });
363
422
  }
364
423
 
365
424
  function printStandaloneResult(command, payload, json) {
@@ -373,7 +432,11 @@ function printStandaloneResult(command, payload, json) {
373
432
  console.log(`Accounts: ${payload.totalAccounts}`);
374
433
  if (Array.isArray(payload.accounts)) {
375
434
  for (const account of payload.accounts) {
376
- console.log(`- [${account.index}] ${account.label} enabled=${account.enabled} refresh=${account.hasRefreshToken} access=${account.hasAccessToken}`);
435
+ const identity = [account.email, account.idSuffix ? `id:${account.idSuffix}` : undefined]
436
+ .filter(Boolean)
437
+ .join(", ");
438
+ const name = identity ? `${account.label} (${identity})` : account.label;
439
+ console.log(`- [${account.index}] ${name} enabled=${account.enabled} refresh=${account.hasRefreshToken} access=${account.hasAccessToken}`);
377
440
  }
378
441
  }
379
442
  if (payload.error) console.log(`Error: ${payload.error}`);
@@ -624,6 +687,14 @@ export async function runLimitsCommand(parsed, options = {}) {
624
687
  }
625
688
  entry.planType = usage.planType;
626
689
  entry.credits = usage.credits;
690
+ // Raw counts stay in `resetCredits` and the rendered line lives in
691
+ // its own field: embedding the English summary inside the counts
692
+ // object would make `--json` consumers parse presentation text to
693
+ // reach a number that is already beside it.
694
+ entry.resetCredits = usage.resetCredits;
695
+ entry.resetCreditsSummary = usage.resetCredits
696
+ ? usageMod.formatResetCredits(usage.resetCredits)
697
+ : null;
627
698
  entry.limits = usage.limits;
628
699
  } catch (error) {
629
700
  // `ensureCodexUsageAccessToken` can surface a raw OAuth refresh
@@ -675,6 +746,9 @@ function printLimitsResult(payload, json) {
675
746
  }
676
747
  if (account.planType) console.log(` Plan: ${account.planType}`);
677
748
  if (account.credits) console.log(` Credits: ${account.credits}`);
749
+ if (account.resetCredits && account.resetCredits.available > 0) {
750
+ console.log(` Resets: ${account.resetCreditsSummary}`);
751
+ }
678
752
  }
679
753
  if (payload.nextAction) console.log(`Next: ${payload.nextAction}`);
680
754
  }