codex-multi-auth 2.19.0 → 2.19.1

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 (32) hide show
  1. package/.codex-plugin/plugin.json +1 -1
  2. package/README.md +2 -2
  3. package/dist/lib/codex-manager/dashboard-settings-data.js +2 -0
  4. package/dist/lib/codex-manager/formatters/subscription-status.d.ts +2 -2
  5. package/dist/lib/codex-manager/formatters/text-style.js +4 -1
  6. package/dist/lib/codex-manager/settings-hub/dashboard.d.ts +1 -1
  7. package/dist/lib/codex-manager/settings-hub/dashboard.js +4 -0
  8. package/dist/lib/codex-manager/settings-panels.d.ts +1 -0
  9. package/dist/lib/codex-manager/settings-panels.js +1 -0
  10. package/dist/lib/codex-manager/theme-settings-panel.d.ts +2 -1
  11. package/dist/lib/codex-manager/theme-settings-panel.js +39 -0
  12. package/dist/lib/dashboard-settings.d.ts +2 -0
  13. package/dist/lib/dashboard-settings.js +18 -0
  14. package/dist/lib/model-route-policy.d.ts +5 -5
  15. package/dist/lib/quota-readiness.d.ts +2 -2
  16. package/dist/lib/request/url-rewriting.js +3 -1
  17. package/dist/lib/runtime/account-model-catalog.d.ts +5 -5
  18. package/dist/lib/runtime/account-reset-credits.d.ts +2 -2
  19. package/dist/lib/runtime/model-discovery-status.d.ts +5 -5
  20. package/dist/lib/runtime/reset-credits.d.ts +7 -7
  21. package/dist/lib/runtime/resume-picker.js +1 -1
  22. package/dist/lib/runtime/workspace-model-scopes.d.ts +3 -3
  23. package/dist/lib/schemas.d.ts +65 -65
  24. package/dist/lib/ui/index.d.ts +1 -1
  25. package/dist/lib/ui/index.js +1 -1
  26. package/dist/lib/ui/runtime.d.ts +3 -1
  27. package/dist/lib/ui/runtime.js +11 -1
  28. package/dist/lib/ui/theme.d.ts +20 -1
  29. package/dist/lib/ui/theme.js +154 -30
  30. package/dist/lib/ui/ui-copy.d.ts +3 -2
  31. package/dist/lib/ui/ui-copy.js +3 -2
  32. package/package.json +25 -24
@@ -48,6 +48,47 @@ function getGlyphs(mode) {
48
48
  cross: "x",
49
49
  };
50
50
  }
51
+ /** Perceived luminance (0.299/0.587/0.114) of the standard 16-color palette. */
52
+ const ANSI16_LUMINANCE = [
53
+ 0, 38, 75, 113, 15, 53, 90, 192, 128, 76, 150, 226, 29, 105, 179, 255,
54
+ ];
55
+ /**
56
+ * Interpret the `COLORFGBG` env convention (`"<fg>;<bg>"`, sometimes
57
+ * `"<fg>;default;<bg>"`) and report whether the terminal background is light.
58
+ * Returns `undefined` when the variable is absent or cannot be parsed.
59
+ */
60
+ function detectLightBackgroundFromEnv(env) {
61
+ const raw = env.COLORFGBG?.trim();
62
+ if (!raw)
63
+ return undefined;
64
+ const bgField = raw.split(";").pop()?.trim() ?? "";
65
+ if (!/^\d{1,2}$/.test(bgField))
66
+ return undefined;
67
+ const bg = Number.parseInt(bgField, 10);
68
+ const luminance = ANSI16_LUMINANCE[bg];
69
+ if (luminance === undefined)
70
+ return undefined;
71
+ return luminance >= 128;
72
+ }
73
+ /**
74
+ * Resolve the effective color mode for a theme.
75
+ *
76
+ * Resolution order:
77
+ * - `CODEX_TUI_COLOR_MODE` env override (`"auto"`, `"dark"`, or `"light"`)
78
+ * - the requested `mode` (`"dark"`/`"light"` win outright)
79
+ * - `COLORFGBG` terminal-background detection
80
+ * - `"dark"` (preserves the historical dark-on-dark styling by default)
81
+ */
82
+ export function resolveUiColorMode(mode = "auto", env = process.env) {
83
+ const envValue = env.CODEX_TUI_COLOR_MODE?.trim().toLowerCase();
84
+ const envMode = envValue === "dark" || envValue === "light" || envValue === "auto"
85
+ ? envValue
86
+ : undefined;
87
+ const requested = envMode ?? mode;
88
+ if (requested !== "auto")
89
+ return requested;
90
+ return detectLightBackgroundFromEnv(env) === true ? "light" : "dark";
91
+ }
51
92
  /**
52
93
  * Selects the ANSI escape sequence for the requested accent color according to the color profile.
53
94
  *
@@ -55,9 +96,47 @@ function getGlyphs(mode) {
55
96
  *
56
97
  * @param profile - The color profile to use (`"truecolor"`, `"ansi256"`, or `"ansi16"`)
57
98
  * @param accent - The accent name to resolve (`"green"`, `"cyan"`, `"blue"`, or `"yellow"`)
99
+ * @param mode - The resolved background mode; `"light"` shifts accent colors darker so they stay readable on light terminal backgrounds
58
100
  * @returns The escape sequence for the accent color suitable for use as a foreground color
59
101
  */
60
- function accentColorForProfile(profile, accent) {
102
+ function accentColorForProfile(profile, accent, mode) {
103
+ if (mode === "light") {
104
+ switch (profile) {
105
+ case "truecolor":
106
+ switch (accent) {
107
+ case "cyan":
108
+ return truecolor(14, 116, 144);
109
+ case "blue":
110
+ return truecolor(29, 78, 216);
111
+ case "yellow":
112
+ return truecolor(180, 83, 9);
113
+ default:
114
+ return truecolor(21, 128, 61);
115
+ }
116
+ case "ansi256":
117
+ switch (accent) {
118
+ case "cyan":
119
+ return ansi256(31);
120
+ case "blue":
121
+ return ansi256(25);
122
+ case "yellow":
123
+ return ansi256(166);
124
+ default:
125
+ return ansi256(28);
126
+ }
127
+ default:
128
+ switch (accent) {
129
+ case "cyan":
130
+ return ansi16(36);
131
+ case "blue":
132
+ return ansi16(34);
133
+ case "yellow":
134
+ return ansi16(33);
135
+ default:
136
+ return ansi16(32);
137
+ }
138
+ }
139
+ }
61
140
  switch (profile) {
62
141
  case "truecolor":
63
142
  switch (accent) {
@@ -102,57 +181,95 @@ function accentColorForProfile(profile, accent) {
102
181
  * @param profile - The color capability profile to target (`"ansi16" | "ansi256" | "truecolor"`)
103
182
  * @param palette - The UI palette selection that influences primary/success/border colors (`"green" | "blue"`)
104
183
  * @param accent - The accent color choice used for the `accent` token (`"green" | "cyan" | "blue" | "yellow"`)
184
+ * @param mode - The resolved background mode; `"light"` darkens colors painted directly on the terminal background while badge/focus colors keep their own dark backgrounds
105
185
  * @returns A UiThemeColors object containing resolved color tokens (e.g., `reset`, `dim`, `muted`, `heading`, `primary`, `accent`, `success`, `warning`, `danger`, `border`, `focusBg`, and `focusText`)
106
186
  */
107
- function getColors(profile, palette, accent) {
108
- const accentColor = accentColorForProfile(profile, accent);
187
+ function getColors(profile, palette, accent, mode) {
188
+ const accentColor = accentColorForProfile(profile, accent, mode);
109
189
  const isBluePalette = palette === "blue";
190
+ const light = mode === "light";
110
191
  switch (profile) {
111
- case "truecolor":
192
+ case "truecolor": {
193
+ const primary = isBluePalette
194
+ ? light
195
+ ? truecolor(29, 78, 216)
196
+ : truecolor(96, 165, 250)
197
+ : light
198
+ ? truecolor(21, 128, 61)
199
+ : truecolor(74, 222, 128);
112
200
  return {
113
201
  reset: "\x1b[0m",
114
202
  dim: "\x1b[2m",
115
- muted: truecolor(148, 163, 184),
116
- heading: truecolor(240, 253, 244),
117
- primary: isBluePalette ? truecolor(96, 165, 250) : truecolor(74, 222, 128),
203
+ muted: light ? truecolor(71, 85, 105) : truecolor(148, 163, 184),
204
+ heading: light ? truecolor(30, 41, 59) : truecolor(240, 253, 244),
205
+ primary,
118
206
  accent: accentColor,
119
- success: isBluePalette ? truecolor(96, 165, 250) : truecolor(74, 222, 128),
120
- warning: truecolor(245, 158, 11),
121
- danger: truecolor(239, 68, 68),
122
- border: isBluePalette ? truecolor(59, 130, 246) : truecolor(34, 197, 94),
207
+ success: primary,
208
+ warning: light ? truecolor(180, 83, 9) : truecolor(245, 158, 11),
209
+ danger: light ? truecolor(185, 28, 28) : truecolor(239, 68, 68),
210
+ border: isBluePalette
211
+ ? light
212
+ ? truecolor(37, 99, 235)
213
+ : truecolor(59, 130, 246)
214
+ : light
215
+ ? truecolor(22, 163, 74)
216
+ : truecolor(34, 197, 94),
123
217
  focusBg: isBluePalette ? truecolorBg(37, 99, 235) : truecolorBg(22, 101, 52),
124
218
  focusText: truecolor(248, 250, 252),
125
219
  };
126
- case "ansi256":
220
+ }
221
+ case "ansi256": {
222
+ const primary = isBluePalette
223
+ ? light
224
+ ? ansi256(25)
225
+ : ansi256(75)
226
+ : light
227
+ ? ansi256(28)
228
+ : ansi256(83);
127
229
  return {
128
230
  reset: "\x1b[0m",
129
231
  dim: "\x1b[2m",
130
- muted: ansi256(102),
131
- heading: ansi256(255),
132
- primary: isBluePalette ? ansi256(75) : ansi256(83),
232
+ muted: light ? ansi256(240) : ansi256(102),
233
+ heading: light ? ansi256(234) : ansi256(255),
234
+ primary,
133
235
  accent: accentColor,
134
- success: isBluePalette ? ansi256(75) : ansi256(83),
135
- warning: ansi256(214),
136
- danger: ansi256(196),
137
- border: isBluePalette ? ansi256(27) : ansi256(40),
236
+ success: primary,
237
+ warning: light ? ansi256(166) : ansi256(214),
238
+ danger: light ? ansi256(160) : ansi256(196),
239
+ border: isBluePalette
240
+ ? light
241
+ ? ansi256(25)
242
+ : ansi256(27)
243
+ : light
244
+ ? ansi256(28)
245
+ : ansi256(40),
138
246
  focusBg: isBluePalette ? ansi256Bg(26) : ansi256Bg(28),
139
247
  focusText: ansi256(231),
140
248
  };
141
- default:
249
+ }
250
+ default: {
251
+ const primary = isBluePalette
252
+ ? light
253
+ ? ansi16(34)
254
+ : ansi16(94)
255
+ : light
256
+ ? ansi16(32)
257
+ : ansi16(92);
142
258
  return {
143
259
  reset: "\x1b[0m",
144
260
  dim: "\x1b[2m",
145
- muted: ansi16(37),
146
- heading: ansi16(97),
147
- primary: isBluePalette ? ansi16(94) : ansi16(92),
261
+ muted: light ? ansi16(30) : ansi16(37),
262
+ heading: light ? ansi16(30) : ansi16(97),
263
+ primary,
148
264
  accent: accentColor,
149
- success: isBluePalette ? ansi16(94) : ansi16(92),
150
- warning: ansi16(93),
151
- danger: ansi16(91),
152
- border: isBluePalette ? ansi16(94) : ansi16(92),
265
+ success: primary,
266
+ warning: light ? ansi16(33) : ansi16(93),
267
+ danger: light ? ansi16(31) : ansi16(91),
268
+ border: primary,
153
269
  focusBg: isBluePalette ? "\x1b[104m" : "\x1b[102m",
154
270
  focusText: "\x1b[30m",
155
271
  };
272
+ }
156
273
  }
157
274
  }
158
275
  /**
@@ -191,8 +308,11 @@ function stripColors(colors) {
191
308
  * - glyphMode: glyph rendering mode; defaults to `"ascii"`.
192
309
  * - palette: overall palette variant; defaults to `"green"`.
193
310
  * - accent: accent color selection; defaults to `"green"`.
311
+ * - colorMode: background mode; defaults to `"auto"`, which honors
312
+ * `CODEX_TUI_COLOR_MODE`, then `COLORFGBG` detection, then `"dark"`.
194
313
  * - disableColor: force the color-stripped theme regardless of env/TTY.
195
- * @returns The constructed UiTheme object containing `profile`, `glyphMode`, `glyphs`, and `colors`.
314
+ * - env: environment override for detection and color gating; defaults to `process.env`.
315
+ * @returns The constructed UiTheme object containing `profile`, `glyphMode`, resolved `colorMode`, `glyphs`, and `colors`.
196
316
  *
197
317
  * @remarks
198
318
  * - Concurrency: creation is pure and side-effect free, safe to call concurrently.
@@ -204,14 +324,18 @@ export function createUiTheme(options) {
204
324
  const glyphMode = options?.glyphMode ?? "ascii";
205
325
  const palette = options?.palette ?? "green";
206
326
  const accent = options?.accent ?? "green";
327
+ const env = options?.env ?? process.env;
207
328
  const resolvedGlyphMode = resolveGlyphMode(glyphMode);
208
- const colors = getColors(profile, palette, accent);
329
+ const colorMode = resolveUiColorMode(options?.colorMode ?? "auto", env);
330
+ const colors = getColors(profile, palette, accent, colorMode);
209
331
  // ui-04: honor NO_COLOR / FORCE_COLOR / non-TTY by blanking color tokens. The
210
332
  // caller may also force this explicitly (e.g. for snapshot-stable output).
211
- const disableColor = options?.disableColor ?? shouldDisableColor();
333
+ const disableColor = options?.disableColor ??
334
+ shouldDisableColor(env, Boolean(process.stdout?.isTTY));
212
335
  return {
213
336
  profile,
214
337
  glyphMode,
338
+ colorMode,
215
339
  glyphs: getGlyphs(resolvedGlyphMode),
216
340
  colors: disableColor ? stripColors(colors) : colors,
217
341
  };
@@ -120,8 +120,8 @@ export declare const UI_COPY: {
120
120
  readonly behaviorSubtitle: "Control how result screens return";
121
121
  readonly behaviorHelp: "Enter Select | 1-3 Delay | P Pause | L AutoFetch | F Status | T TTL | S Save | Q Back (No Save)";
122
122
  readonly themeTitle: "Color Theme";
123
- readonly themeSubtitle: "Pick base color and accent";
124
- readonly themeHelp: "Enter Select | 1-2 Base | S Save | Q Back (No Save)";
123
+ readonly themeSubtitle: "Pick base color, accent, and background mode";
124
+ readonly themeHelp: "Enter Select | 1-2 Base | A/D/L Mode | S Save | Q Back (No Save)";
125
125
  readonly backendTitle: "Backend Controls";
126
126
  readonly backendSubtitle: "Tune sync, retry, and limit behavior";
127
127
  readonly backendHelp: "Enter Open | 1-4 Category | S Save | R Reset | Q Back (No Save)";
@@ -136,6 +136,7 @@ export declare const UI_COPY: {
136
136
  readonly backendBackToCategories: "Back to Categories";
137
137
  readonly baseTheme: "Base Color";
138
138
  readonly accentColor: "Accent Color";
139
+ readonly terminalBackground: "Terminal Background";
139
140
  readonly actionTiming: "Auto Return Delay";
140
141
  readonly moveUp: "Move Focused Field Up";
141
142
  readonly moveDown: "Move Focused Field Down";
@@ -121,8 +121,8 @@ export const UI_COPY = {
121
121
  behaviorSubtitle: "Control how result screens return",
122
122
  behaviorHelp: "Enter Select | 1-3 Delay | P Pause | L AutoFetch | F Status | T TTL | S Save | Q Back (No Save)",
123
123
  themeTitle: "Color Theme",
124
- themeSubtitle: "Pick base color and accent",
125
- themeHelp: "Enter Select | 1-2 Base | S Save | Q Back (No Save)",
124
+ themeSubtitle: "Pick base color, accent, and background mode",
125
+ themeHelp: "Enter Select | 1-2 Base | A/D/L Mode | S Save | Q Back (No Save)",
126
126
  backendTitle: "Backend Controls",
127
127
  backendSubtitle: "Tune sync, retry, and limit behavior",
128
128
  backendHelp: "Enter Open | 1-4 Category | S Save | R Reset | Q Back (No Save)",
@@ -137,6 +137,7 @@ export const UI_COPY = {
137
137
  backendBackToCategories: "Back to Categories",
138
138
  baseTheme: "Base Color",
139
139
  accentColor: "Accent Color",
140
+ terminalBackground: "Terminal Background",
140
141
  actionTiming: "Auto Return Delay",
141
142
  moveUp: "Move Focused Field Up",
142
143
  moveDown: "Move Focused Field Down",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-multi-auth",
3
- "version": "2.19.0",
3
+ "version": "2.19.1",
4
4
  "description": "Codex CLI multi-account OAuth manager with account switching, health checks, runtime rotation, diagnostics, and recovery tools for @openai/codex",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -78,10 +78,10 @@
78
78
  "url": "https://github.com/ndycode/codex-multi-auth/issues"
79
79
  },
80
80
  "scripts": {
81
- "build": "tsc && node scripts/copy-oauth-success.js",
81
+ "build": "node node_modules/tsgo/bin/tsc && node scripts/copy-oauth-success.js",
82
82
  "generate:schema": "npm run build && node scripts/generate-config-schema.mjs",
83
- "typecheck": "tsc --noEmit",
84
- "typecheck:scripts": "tsc -p tsconfig.scripts.json",
83
+ "typecheck": "node node_modules/tsgo/bin/tsc --noEmit",
84
+ "typecheck:scripts": "node node_modules/tsgo/bin/tsc -p tsconfig.scripts.json",
85
85
  "lint": "npm run lint:ts && npm run lint:scripts",
86
86
  "lint:ts": "eslint . --ext .ts",
87
87
  "lint:scripts": "eslint scripts --ext .js,.mjs",
@@ -154,39 +154,40 @@
154
154
  ]
155
155
  },
156
156
  "engines": {
157
- "node": ">=18.17.0"
157
+ "node": ">=22.19.0"
158
158
  },
159
159
  "devDependencies": {
160
- "@types/node": "^20.19.42",
161
- "@types/ws": "8.18.1",
162
- "@typescript-eslint/eslint-plugin": "^8.56.0",
163
- "@typescript-eslint/parser": "^8.56.0",
164
- "@vitest/coverage-v8": "^4.1.8",
165
- "@vitest/ui": "^4.1.8",
166
- "eslint": "^10.0.0",
160
+ "@types/node": "^26.6.3",
161
+ "@types/ws": "8.18.2",
162
+ "@typescript-eslint/eslint-plugin": "^8.71.1",
163
+ "@typescript-eslint/parser": "^8.71.1",
164
+ "@vitest/coverage-v8": "^5.0.2",
165
+ "@vitest/ui": "^5.0.2",
166
+ "eslint": "^10.12.0",
167
167
  "eslint-import-resolver-typescript": "^4.4.5",
168
- "eslint-plugin-import-x": "^4.16.2",
169
- "fast-check": "^4.5.3",
168
+ "eslint-plugin-import-x": "^4.17.1",
169
+ "fast-check": "^4.10.2",
170
170
  "husky": "^9.1.7",
171
- "lint-staged": "^16.2.7",
172
- "typescript": "^5.9.3",
173
- "typescript-language-server": "^5.1.3",
174
- "vitest": "^4.1.8"
171
+ "lint-staged": "^17.6.0",
172
+ "tsgo": "npm:typescript@^7.0.2",
173
+ "typescript": "^6.0.3",
174
+ "typescript-language-server": "^6.0.1",
175
+ "vitest": "^5.0.2"
175
176
  },
176
177
  "dependencies": {
177
178
  "@codex-ai/plugin": "file:vendor/codex-ai-plugin",
178
179
  "@codex-ai/sdk": "file:vendor/codex-ai-sdk",
179
- "hono": "4.13.9",
180
- "undici": "6.29.0",
181
- "ws": "8.21.3",
182
- "zod": "4.4.3"
180
+ "hono": "4.13.13",
181
+ "undici": "8.11.2",
182
+ "ws": "8.22.0",
183
+ "zod": "4.6.5"
183
184
  },
184
185
  "overrides": {
185
- "hono": "4.13.9",
186
+ "hono": "4.13.13",
186
187
  "flatted": "3.4.2",
187
188
  "minimatch": {
188
189
  ".": "10.2.4",
189
- "brace-expansion": "5.0.9"
190
+ "brace-expansion": "5.0.12"
190
191
  },
191
192
  "picomatch": "4.0.4",
192
193
  "rollup": "4.59.0",