snowcode 0.9.21 → 0.9.24

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.
Files changed (2) hide show
  1. package/dist/cli.mjs +160 -24
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -125648,7 +125648,7 @@ var init_metadata = __esm(() => {
125648
125648
  isClaudeAiAuth: isClaudeAISubscriber(),
125649
125649
  version: "99.0.0",
125650
125650
  versionBase: getVersionBase(),
125651
- buildTime: "2026-04-05T03:49:47.637Z",
125651
+ buildTime: "2026-04-05T13:10:54.983Z",
125652
125652
  deploymentEnvironment: env2.detectDeploymentEnvironment(),
125653
125653
  ...isEnvTruthy(process.env.GITHUB_ACTIONS) && {
125654
125654
  githubEventName: process.env.GITHUB_EVENT_NAME,
@@ -130352,6 +130352,10 @@ function parseChatgptAccountId(token) {
130352
130352
  const fromClaim = asTrimmedString(payload?.["https://api.openai.com/auth.chatgpt_account_id"]);
130353
130353
  if (fromClaim)
130354
130354
  return fromClaim;
130355
+ const nestedAuth = payload?.["https://api.openai.com/auth"] && typeof payload["https://api.openai.com/auth"] === "object" ? payload["https://api.openai.com/auth"] : undefined;
130356
+ const nestedClaim = asTrimmedString(nestedAuth?.chatgpt_account_id);
130357
+ if (nestedClaim)
130358
+ return nestedClaim;
130355
130359
  return asTrimmedString(payload?.chatgpt_account_id);
130356
130360
  }
130357
130361
  function loadCodexAuthJson(authPath) {
@@ -130678,13 +130682,18 @@ function compareVersions(a2, b) {
130678
130682
  return 0;
130679
130683
  }
130680
130684
  function getCurrentVersion() {
130681
- const displayVersion = (typeof MACRO !== "undefined" ? "0.9.21" : undefined) ?? (() => {
130682
- try {
130683
- const pkg = require2("../../package.json");
130684
- return pkg.version;
130685
- } catch {
130686
- return;
130685
+ const displayVersion = (typeof MACRO !== "undefined" ? "0.9.24" : undefined) ?? (() => {
130686
+ for (const candidate of ["../../package.json", "../package.json"]) {
130687
+ try {
130688
+ const pkg = require2(candidate);
130689
+ if (typeof pkg.version === "string") {
130690
+ return pkg.version;
130691
+ }
130692
+ } catch {
130693
+ continue;
130694
+ }
130687
130695
  }
130696
+ return;
130688
130697
  })() ?? "0.0.0";
130689
130698
  return displayVersion.replace(/[^0-9.]/g, "") || "0.0.0";
130690
130699
  }
@@ -130893,10 +130902,11 @@ async function printStartupScreen() {
130893
130902
  const sLen = ` ● ${sL} Ready — type /help to begin`.length;
130894
130903
  out.push(boxRow(sRow, W2, sLen));
130895
130904
  out.push(`${rgb(...BORDER)}╚${"═".repeat(W2 - 2)}╝${RESET}`);
130896
- const _ver = "0.9.21";
130905
+ const _ver = "0.9.24";
130906
+ const _currentVersion = getCurrentVersion();
130897
130907
  const _update = await getAvailableUpdateWithRefresh({ timeoutMs: 1200 });
130898
130908
  out.push(` ${DIM}${rgb(...DIMCOL)}snowcode v${_ver}${RESET}`);
130899
- if (_update) {
130909
+ if (_update && compareVersions(_update, _currentVersion) > 0) {
130900
130910
  out.push(` ${rgb(...ACCENT)}★ Update available v${_update} → /update${RESET}`);
130901
130911
  }
130902
130912
  out.push("");
@@ -370951,7 +370961,7 @@ function getAnthropicEnvMetadata() {
370951
370961
  function getBuildAgeMinutes() {
370952
370962
  if (false)
370953
370963
  ;
370954
- const buildTime = new Date("2026-04-05T03:49:47.637Z").getTime();
370964
+ const buildTime = new Date("2026-04-05T13:10:54.983Z").getTime();
370955
370965
  if (isNaN(buildTime))
370956
370966
  return;
370957
370967
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -411623,8 +411633,13 @@ function OAuthFlow({
411623
411633
  }, undefined, false, undefined, this),
411624
411634
  /* @__PURE__ */ jsx_dev_runtime209.jsxDEV(ThemedText, {
411625
411635
  dimColor: true,
411626
- children: "R replace existing · K keep existing · Esc cancel"
411627
- }, undefined, false, undefined, this)
411636
+ children: [
411637
+ duplicateDecision?.replaceHint ?? "R replace existing",
411638
+ " · ",
411639
+ duplicateDecision?.keepHint ?? "K keep existing",
411640
+ " · Esc cancel"
411641
+ ]
411642
+ }, undefined, true, undefined, this)
411628
411643
  ]
411629
411644
  }, undefined, true, undefined, this);
411630
411645
  return /* @__PURE__ */ jsx_dev_runtime209.jsxDEV(ThemedBox_default, {
@@ -412212,9 +412227,64 @@ function AuthCommand({
412212
412227
  code_verifier: verifier
412213
412228
  }, "codex_oauth");
412214
412229
  const email3 = emailFromTokens(tokens);
412230
+ const accountId = parseChatgptAccountId(tokens.access_token) ?? parseChatgptAccountId(tokens.id_token);
412215
412231
  persistCodexOauthSession(tokens);
412216
- addAccount({ type: "codex_oauth", label: `Codex: ${email3}`, email: email3, refreshToken: tokens.refresh_token, enabled: true });
412217
412232
  process.env.OPENAI_API_KEY = "chatgpt-oauth";
412233
+ const matchingAccounts = loadAccounts().accounts.filter((account) => account.type === "codex_oauth" && account.email?.trim().toLowerCase() === email3.trim().toLowerCase()).sort((left, right) => Date.parse(right.addedAt || "") - Date.parse(left.addedAt || ""));
412234
+ if (matchingAccounts.length > 0) {
412235
+ return {
412236
+ email: email3,
412237
+ refreshToken: tokens.refresh_token ?? "",
412238
+ duplicateDecision: {
412239
+ message: `This Codex account already exists: ${email3}`,
412240
+ replaceHint: "R replace existing",
412241
+ keepHint: "K keep both",
412242
+ onReplace: () => {
412243
+ const [primary, ...duplicates] = matchingAccounts;
412244
+ updateAccount(primary.id, {
412245
+ label: `Codex: ${email3}`,
412246
+ email: email3,
412247
+ accountId,
412248
+ refreshToken: tokens.refresh_token ?? primary.refreshToken,
412249
+ enabled: true
412250
+ });
412251
+ for (const duplicate of duplicates) {
412252
+ removeAccount(duplicate.id);
412253
+ }
412254
+ appendAuthLog("codex_oauth", `account replaced email=${email3} removedDuplicates=${duplicates.length}`);
412255
+ return {
412256
+ email: email3,
412257
+ refreshToken: tokens.refresh_token ?? primary.refreshToken ?? "",
412258
+ completionMessage: `Codex account updated: ${email3}`
412259
+ };
412260
+ },
412261
+ onKeep: () => {
412262
+ addAccount({
412263
+ type: "codex_oauth",
412264
+ label: `Codex: ${email3}`,
412265
+ email: email3,
412266
+ accountId,
412267
+ refreshToken: tokens.refresh_token,
412268
+ enabled: true
412269
+ });
412270
+ appendAuthLog("codex_oauth", `duplicate account saved email=${email3}`);
412271
+ return {
412272
+ email: email3,
412273
+ refreshToken: tokens.refresh_token ?? "",
412274
+ completionMessage: `Codex duplicate account added: ${email3}`
412275
+ };
412276
+ }
412277
+ }
412278
+ };
412279
+ }
412280
+ addAccount({
412281
+ type: "codex_oauth",
412282
+ label: `Codex: ${email3}`,
412283
+ email: email3,
412284
+ accountId,
412285
+ refreshToken: tokens.refresh_token,
412286
+ enabled: true
412287
+ });
412218
412288
  appendAuthLog("codex_oauth", `account saved email=${email3}`);
412219
412289
  return { email: email3, refreshToken: tokens.refresh_token ?? "" };
412220
412290
  },
@@ -449520,6 +449590,13 @@ function UsageBar({ value, width = 12 }) {
449520
449590
  function err2(e) {
449521
449591
  return e instanceof Error ? e.message : String(e);
449522
449592
  }
449593
+ function normalizeEmail(value) {
449594
+ const trimmed = value?.trim().toLowerCase();
449595
+ return trimmed || null;
449596
+ }
449597
+ function sortNewestFirst(accounts) {
449598
+ return [...accounts].sort((left, right) => Date.parse(right.addedAt || "") - Date.parse(left.addedAt || ""));
449599
+ }
449523
449600
  async function withRetry2(fn, retries = 3) {
449524
449601
  let lastError;
449525
449602
  for (let attempt = 1;attempt <= retries; attempt++) {
@@ -449807,15 +449884,73 @@ ${errorBody}`);
449807
449884
  throw new Error("Codex token refresh returned no access token");
449808
449885
  return json2;
449809
449886
  }
449887
+ async function refreshCodexTokenWithFallback(account) {
449888
+ const candidates = [];
449889
+ const seen = new Set;
449890
+ const pushCandidate = (refreshToken, candidateAccount, accountId) => {
449891
+ const trimmed = refreshToken?.trim();
449892
+ if (!trimmed || seen.has(trimmed))
449893
+ return;
449894
+ seen.add(trimmed);
449895
+ candidates.push({
449896
+ refreshToken: trimmed,
449897
+ account: candidateAccount,
449898
+ accountId: accountId ?? candidateAccount?.accountId
449899
+ });
449900
+ };
449901
+ pushCandidate(account.refreshToken, account, account.accountId);
449902
+ const accountEmail = normalizeEmail(account.email);
449903
+ if (accountEmail) {
449904
+ const siblingAccounts = sortNewestFirst(loadAccounts().accounts.filter((item) => item.enabled && item.type === "codex_oauth" && item.id !== account.id && normalizeEmail(item.email) === accountEmail));
449905
+ for (const sibling of siblingAccounts) {
449906
+ pushCandidate(sibling.refreshToken, sibling, sibling.accountId);
449907
+ }
449908
+ }
449909
+ const authJsonCredentials = resolveCodexApiCredentials();
449910
+ const enabledCodexAccounts = loadAccounts().accounts.filter((item) => item.enabled && item.type === "codex_oauth" && item.refreshToken);
449911
+ if (authJsonCredentials.refreshToken && (!account.accountId || authJsonCredentials.accountId === account.accountId || enabledCodexAccounts.length === 1)) {
449912
+ pushCandidate(authJsonCredentials.refreshToken, undefined, authJsonCredentials.accountId);
449913
+ }
449914
+ let lastError;
449915
+ for (const candidate of candidates) {
449916
+ try {
449917
+ const tokenResponse = await refreshCodexToken(candidate.refreshToken);
449918
+ const rotatedRefreshToken = tokenResponse.refresh_token ?? candidate.refreshToken;
449919
+ if (candidate.account?.id && rotatedRefreshToken !== candidate.account.refreshToken) {
449920
+ updateAccount(candidate.account.id, {
449921
+ refreshToken: rotatedRefreshToken
449922
+ });
449923
+ }
449924
+ if (account.id !== candidate.account?.id && rotatedRefreshToken !== account.refreshToken) {
449925
+ updateAccount(account.id, {
449926
+ refreshToken: rotatedRefreshToken,
449927
+ ...candidate.accountId ? { accountId: candidate.accountId } : {}
449928
+ });
449929
+ }
449930
+ return {
449931
+ tokenResponse,
449932
+ accountId: candidate.accountId
449933
+ };
449934
+ } catch (error42) {
449935
+ lastError = error42;
449936
+ }
449937
+ }
449938
+ throw lastError ?? new Error("Codex session expired. Re-run /auth for that ChatGPT account.");
449939
+ }
449810
449940
  async function fetchCodex(account) {
449811
- const tokenResponse = await refreshCodexToken(account.refreshToken);
449941
+ const { tokenResponse, accountId } = await refreshCodexTokenWithFallback(account);
449812
449942
  const token = tokenResponse.access_token;
449813
449943
  if (tokenResponse.refresh_token && tokenResponse.refresh_token !== account.refreshToken) {
449814
449944
  updateAccount(account.id, { refreshToken: tokenResponse.refresh_token });
449815
449945
  }
449816
449946
  const headers = { Authorization: `Bearer ${token}`, "User-Agent": "codex-cli" };
449817
- if (account.email)
449818
- headers["ChatGPT-Account-Id"] = account.email;
449947
+ const resolvedAccountId = account.accountId ?? accountId;
449948
+ if (resolvedAccountId) {
449949
+ headers["ChatGPT-Account-Id"] = resolvedAccountId;
449950
+ if (resolvedAccountId !== account.accountId) {
449951
+ updateAccount(account.id, { accountId: resolvedAccountId });
449952
+ }
449953
+ }
449819
449954
  const res = await fetch(CODEX_USAGE_URL, { headers });
449820
449955
  if (!res.ok) {
449821
449956
  const errorBody = await res.text().catch(() => "unknown error");
@@ -450420,6 +450555,7 @@ var React94, import_react161, jsx_dev_runtime278, AG_CLOUDCODE_BASE = "https://c
450420
450555
  var init_usage2 = __esm(() => {
450421
450556
  init_ink2();
450422
450557
  init_accountManager();
450558
+ init_providerConfig();
450423
450559
  init_antigravityOAuth();
450424
450560
  init_antigravityLocalSessions();
450425
450561
  init_antigravityLocalUsage();
@@ -464814,7 +464950,7 @@ var init_bridge_kick = __esm(() => {
464814
464950
  var call59 = async () => {
464815
464951
  return {
464816
464952
  type: "text",
464817
- value: `${"99.0.0"} (built ${"2026-04-05T03:49:47.637Z"})`
464953
+ value: `${"99.0.0"} (built ${"2026-04-05T13:10:54.983Z"})`
464818
464954
  };
464819
464955
  }, version2, version_default;
464820
464956
  var init_version = __esm(() => {
@@ -538276,7 +538412,7 @@ function WelcomeV2() {
538276
538412
  dimColor: true,
538277
538413
  children: [
538278
538414
  "v",
538279
- "0.9.21",
538415
+ "0.9.24",
538280
538416
  " "
538281
538417
  ]
538282
538418
  }, undefined, true, undefined, this)
@@ -538476,7 +538612,7 @@ function WelcomeV2() {
538476
538612
  dimColor: true,
538477
538613
  children: [
538478
538614
  "v",
538479
- "0.9.21",
538615
+ "0.9.24",
538480
538616
  " "
538481
538617
  ]
538482
538618
  }, undefined, true, undefined, this)
@@ -538702,7 +538838,7 @@ function AppleTerminalWelcomeV2(t0) {
538702
538838
  dimColor: true,
538703
538839
  children: [
538704
538840
  "v",
538705
- "0.9.21",
538841
+ "0.9.24",
538706
538842
  " "
538707
538843
  ]
538708
538844
  }, undefined, true, undefined, this);
@@ -538956,7 +539092,7 @@ function AppleTerminalWelcomeV2(t0) {
538956
539092
  dimColor: true,
538957
539093
  children: [
538958
539094
  "v",
538959
- "0.9.21",
539095
+ "0.9.24",
538960
539096
  " "
538961
539097
  ]
538962
539098
  }, undefined, true, undefined, this);
@@ -559077,7 +559213,7 @@ Usage: claude --remote "your task description"`, () => gracefulShutdown(1));
559077
559213
  pendingHookMessages
559078
559214
  }, renderAndRun);
559079
559215
  }
559080
- }).version("0.9.21 (Snowcode)", "-v, --version", "Output the version number");
559216
+ }).version("0.9.24 (Snowcode)", "-v, --version", "Output the version number");
559081
559217
  program.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
559082
559218
  program.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
559083
559219
  if (canUserConfigureAdvisor()) {
@@ -559638,7 +559774,7 @@ function validateProviderEnvOrExit() {
559638
559774
  async function main2() {
559639
559775
  const args = process.argv.slice(2);
559640
559776
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
559641
- console.log(`${"0.9.21"} (Snowcode)`);
559777
+ console.log(`${"0.9.24"} (Snowcode)`);
559642
559778
  return;
559643
559779
  }
559644
559780
  validateProviderEnvOrExit();
@@ -559727,4 +559863,4 @@ async function main2() {
559727
559863
  }
559728
559864
  main2();
559729
559865
 
559730
- //# debugId=E43E7FACDA558B6964756E2164756E21
559866
+ //# debugId=01B34F11D41CE63264756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snowcode",
3
- "version": "0.9.21",
3
+ "version": "0.9.24",
4
4
  "description": "It's cold outside, isn't it?",
5
5
  "type": "module",
6
6
  "bin": {