codex-multi-auth 2.6.0 → 2.7.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/.codex-plugin/plugin.json +9 -9
- package/README.md +433 -424
- package/dist/lib/auth/browser.d.ts +4 -0
- package/dist/lib/auth/browser.d.ts.map +1 -1
- package/dist/lib/auth/browser.js +73 -19
- package/dist/lib/auth/callback-guidance.d.ts +39 -0
- package/dist/lib/auth/callback-guidance.d.ts.map +1 -0
- package/dist/lib/auth/callback-guidance.js +106 -0
- package/dist/lib/auth/server.d.ts.map +1 -1
- package/dist/lib/auth/server.js +1 -0
- package/dist/lib/codex-manager/formatters/quota-formatters.d.ts +20 -3
- package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.js +28 -13
- package/dist/lib/codex-manager/help.d.ts.map +1 -1
- package/dist/lib/codex-manager/help.js +18 -14
- package/dist/lib/codex-manager/login-oauth.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-oauth.js +11 -0
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +13 -0
- package/dist/lib/quota-probe.d.ts +13 -0
- package/dist/lib/quota-probe.d.ts.map +1 -1
- package/dist/lib/quota-probe.js +6 -4
- package/dist/lib/types.d.ts +6 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/wsl.d.ts +28 -0
- package/dist/lib/wsl.d.ts.map +1 -0
- package/dist/lib/wsl.js +57 -0
- package/package.json +1 -1
|
@@ -17,6 +17,10 @@ export declare function isBrowserLaunchSuppressed(): boolean;
|
|
|
17
17
|
* OAuth codes) from `url` before calling. Invocations are not atomic—concurrent calls may race but are
|
|
18
18
|
* safe to perform.
|
|
19
19
|
*
|
|
20
|
+
* Under WSL the browser lives on the Windows host, so `xdg-open` is the wrong tool and is usually not
|
|
21
|
+
* even installed. Prefer `wslview` (wslu), then Windows PowerShell via interop, before falling back to
|
|
22
|
+
* the Linux opener.
|
|
23
|
+
*
|
|
20
24
|
* @param url - The URL to open; redact sensitive tokens (e.g., OAuth codes) before passing.
|
|
21
25
|
* @returns `true` if a browser launch was attempted, `false` if no suitable opener was available or an exception occurred.
|
|
22
26
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../lib/auth/browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../lib/auth/browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAKzC;AAED,wBAAgB,yBAAyB,IAAI,OAAO,CAQnD;AAqGD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAyCnD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA8DzD"}
|
package/dist/lib/auth/browser.js
CHANGED
|
@@ -6,6 +6,7 @@ import { spawn } from "node:child_process";
|
|
|
6
6
|
import fs from "node:fs";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { PLATFORM_OPENERS } from "../constants.js";
|
|
9
|
+
import { isWsl } from "../wsl.js";
|
|
9
10
|
const BROWSER_DISABLED_VALUES = new Set(["0", "false", "no", "off", "none"]);
|
|
10
11
|
const NO_BROWSER_TRUTHY_VALUES = new Set(["1", "true", "yes", "on"]);
|
|
11
12
|
/**
|
|
@@ -89,6 +90,40 @@ function commandExists(command) {
|
|
|
89
90
|
}
|
|
90
91
|
return false;
|
|
91
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Escape a value for safe interpolation into a double-quoted PowerShell string.
|
|
95
|
+
*
|
|
96
|
+
* Neutralizes backticks, `$` sub-expression injection, and embedded double quotes.
|
|
97
|
+
*/
|
|
98
|
+
function escapeForPowerShell(value) {
|
|
99
|
+
return value.replace(/`/g, "``").replace(/\$/g, "`$").replace(/"/g, '""');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Run a PowerShell command, fire-and-forget.
|
|
103
|
+
*
|
|
104
|
+
* Reachable from Windows and from WSL, where `powershell.exe` resolves through
|
|
105
|
+
* Windows/Linux PATH interop.
|
|
106
|
+
*
|
|
107
|
+
* @param command - A PowerShell command string; interpolated values must already be escaped.
|
|
108
|
+
* @param stdinText - Optional text piped to the command's stdin.
|
|
109
|
+
* @returns `true` if the spawn was attempted, `false` if PowerShell is unavailable.
|
|
110
|
+
*/
|
|
111
|
+
function spawnPowerShell(command, stdinText) {
|
|
112
|
+
if (!commandExists("powershell.exe")) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
const child = spawn("powershell.exe", ["-NoLogo", "-NoProfile", "-Command", command], {
|
|
116
|
+
stdio: stdinText === undefined ? "ignore" : ["pipe", "ignore", "ignore"],
|
|
117
|
+
});
|
|
118
|
+
child.on("error", () => { });
|
|
119
|
+
if (stdinText !== undefined) {
|
|
120
|
+
// A child that dies before draining stdin emits EPIPE on the stream, not
|
|
121
|
+
// on the child. Unhandled, that is an async throw no try/catch can catch.
|
|
122
|
+
child.stdin?.on("error", () => { });
|
|
123
|
+
child.stdin?.end(stdinText);
|
|
124
|
+
}
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
92
127
|
/**
|
|
93
128
|
* Launches the user's default browser to open the provided URL using a platform-appropriate command.
|
|
94
129
|
*
|
|
@@ -98,6 +133,10 @@ function commandExists(command) {
|
|
|
98
133
|
* OAuth codes) from `url` before calling. Invocations are not atomic—concurrent calls may race but are
|
|
99
134
|
* safe to perform.
|
|
100
135
|
*
|
|
136
|
+
* Under WSL the browser lives on the Windows host, so `xdg-open` is the wrong tool and is usually not
|
|
137
|
+
* even installed. Prefer `wslview` (wslu), then Windows PowerShell via interop, before falling back to
|
|
138
|
+
* the Linux opener.
|
|
139
|
+
*
|
|
101
140
|
* @param url - The URL to open; redact sensitive tokens (e.g., OAuth codes) before passing.
|
|
102
141
|
* @returns `true` if a browser launch was attempted, `false` if no suitable opener was available or an exception occurred.
|
|
103
142
|
*/
|
|
@@ -108,17 +147,22 @@ export function openBrowserUrl(url) {
|
|
|
108
147
|
}
|
|
109
148
|
// Windows: use PowerShell Start-Process to avoid cmd/start quirks with URLs containing '&' or ':'
|
|
110
149
|
if (process.platform === "win32") {
|
|
111
|
-
|
|
112
|
-
|
|
150
|
+
return spawnPowerShell(`Start-Process "${escapeForPowerShell(url)}"`);
|
|
151
|
+
}
|
|
152
|
+
if (isWsl()) {
|
|
153
|
+
// wslu's browser shim: hands the URL to the Windows default browser.
|
|
154
|
+
if (commandExists("wslview")) {
|
|
155
|
+
const child = spawn("wslview", [url], {
|
|
156
|
+
stdio: "ignore",
|
|
157
|
+
shell: false,
|
|
158
|
+
});
|
|
159
|
+
child.on("error", () => { });
|
|
160
|
+
return true;
|
|
113
161
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
.replace(/"/g, '""');
|
|
119
|
-
const child = spawn("powershell.exe", ["-NoLogo", "-NoProfile", "-Command", `Start-Process "${psUrl}"`], { stdio: "ignore" });
|
|
120
|
-
child.on("error", () => { });
|
|
121
|
-
return true;
|
|
162
|
+
if (spawnPowerShell(`Start-Process "${escapeForPowerShell(url)}"`)) {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
// Fall through: an X/Wayland browser inside the distro is still possible.
|
|
122
166
|
}
|
|
123
167
|
const opener = getBrowserOpener();
|
|
124
168
|
if (!commandExists(opener)) {
|
|
@@ -151,16 +195,24 @@ export function copyTextToClipboard(text) {
|
|
|
151
195
|
if (!text)
|
|
152
196
|
return false;
|
|
153
197
|
if (process.platform === "win32") {
|
|
154
|
-
|
|
155
|
-
|
|
198
|
+
return spawnPowerShell(`Set-Clipboard -Value "${escapeForPowerShell(text)}"`);
|
|
199
|
+
}
|
|
200
|
+
if (isWsl()) {
|
|
201
|
+
// The clipboard the user pastes from is the Windows one, not the distro's.
|
|
202
|
+
if (commandExists("clip.exe")) {
|
|
203
|
+
const child = spawn("clip.exe", [], {
|
|
204
|
+
stdio: ["pipe", "ignore", "ignore"],
|
|
205
|
+
shell: false,
|
|
206
|
+
});
|
|
207
|
+
child.on("error", () => { });
|
|
208
|
+
child.stdin?.on("error", () => { });
|
|
209
|
+
child.stdin?.end(text);
|
|
210
|
+
return true;
|
|
156
211
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const child = spawn("powershell.exe", ["-NoLogo", "-NoProfile", "-Command", `Set-Clipboard -Value "${psText}"`], { stdio: "ignore" });
|
|
162
|
-
child.on("error", () => { });
|
|
163
|
-
return true;
|
|
212
|
+
if (spawnPowerShell(`Set-Clipboard -Value "${escapeForPowerShell(text)}"`)) {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
// Fall through to the Linux clipboard tools.
|
|
164
216
|
}
|
|
165
217
|
if (process.platform === "darwin") {
|
|
166
218
|
if (!commandExists("pbcopy"))
|
|
@@ -170,6 +222,7 @@ export function copyTextToClipboard(text) {
|
|
|
170
222
|
shell: false,
|
|
171
223
|
});
|
|
172
224
|
child.on("error", () => { });
|
|
225
|
+
child.stdin?.on("error", () => { });
|
|
173
226
|
child.stdin?.end(text);
|
|
174
227
|
return true;
|
|
175
228
|
}
|
|
@@ -186,6 +239,7 @@ export function copyTextToClipboard(text) {
|
|
|
186
239
|
shell: false,
|
|
187
240
|
});
|
|
188
241
|
child.on("error", () => { });
|
|
242
|
+
child.stdin?.on("error", () => { });
|
|
189
243
|
child.stdin?.end(text);
|
|
190
244
|
return true;
|
|
191
245
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator-facing guidance for OAuth callback failures on the fixed callback port.
|
|
3
|
+
*
|
|
4
|
+
* The redirect URI is registered with the provider, so the port cannot be
|
|
5
|
+
* negotiated away when it is contended. The best the CLI can do is name the
|
|
6
|
+
* likely conflict and point at a flow that does not need the port at all.
|
|
7
|
+
*
|
|
8
|
+
* Windows and WSL contend for that port as far as a browser running on the
|
|
9
|
+
* Windows host is concerned, so a listener on either side can swallow a callback
|
|
10
|
+
* intended for the other. From inside the distro this is invisible: the WSL
|
|
11
|
+
* listener binds cleanly and simply never receives the redirect.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Why the browser callback did not produce an authorization code.
|
|
15
|
+
*
|
|
16
|
+
* - `bind-failed`: the local listener could not take the callback port at all.
|
|
17
|
+
* - `callback-timeout`: the listener bound, but no redirect ever arrived.
|
|
18
|
+
*/
|
|
19
|
+
export type CallbackFailureReason = "bind-failed" | "callback-timeout";
|
|
20
|
+
/** @internal */
|
|
21
|
+
export type CallbackFailureContext = {
|
|
22
|
+
/** `errno` code from a failed listen, when one is known. */
|
|
23
|
+
bindErrorCode?: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Build the lines shown to the user when a browser OAuth callback fails.
|
|
27
|
+
*
|
|
28
|
+
* Contention is only *asserted* when it was actually observed — that is, the
|
|
29
|
+
* listen failed with `EADDRINUSE`. A callback that never arrives is far more
|
|
30
|
+
* often a cancelled or abandoned sign-in than a stolen redirect, so that case
|
|
31
|
+
* is phrased as a conditional ("if you completed sign-in and still landed
|
|
32
|
+
* here") rather than a diagnosis.
|
|
33
|
+
*
|
|
34
|
+
* @param reason - Which half of the callback flow broke.
|
|
35
|
+
* @param context - Extra detail from the failed bind, when available.
|
|
36
|
+
* @returns Guidance lines. Empty strings are intentional blank separators.
|
|
37
|
+
*/
|
|
38
|
+
export declare function describeCallbackFailure(reason: CallbackFailureReason, context?: CallbackFailureContext): string[];
|
|
39
|
+
//# sourceMappingURL=callback-guidance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback-guidance.d.ts","sourceRoot":"","sources":["../../../lib/auth/callback-guidance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAEvE,gBAAgB;AAChB,MAAM,MAAM,sBAAsB,GAAG;IACpC,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AA4CF;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,GAAE,sBAA2B,GAClC,MAAM,EAAE,CA0CV"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator-facing guidance for OAuth callback failures on the fixed callback port.
|
|
3
|
+
*
|
|
4
|
+
* The redirect URI is registered with the provider, so the port cannot be
|
|
5
|
+
* negotiated away when it is contended. The best the CLI can do is name the
|
|
6
|
+
* likely conflict and point at a flow that does not need the port at all.
|
|
7
|
+
*
|
|
8
|
+
* Windows and WSL contend for that port as far as a browser running on the
|
|
9
|
+
* Windows host is concerned, so a listener on either side can swallow a callback
|
|
10
|
+
* intended for the other. From inside the distro this is invisible: the WSL
|
|
11
|
+
* listener binds cleanly and simply never receives the redirect.
|
|
12
|
+
*/
|
|
13
|
+
import { AUTH_REDIRECT } from "./auth.js";
|
|
14
|
+
import { getWslDistroName, isWsl } from "../wsl.js";
|
|
15
|
+
const INSPECT_WINDOWS = ` Windows (PowerShell): Get-NetTCPConnection -LocalPort ${AUTH_REDIRECT.port}`;
|
|
16
|
+
const INSPECT_LINUX = ` Linux / WSL: ss -lptn 'sport = :${AUTH_REDIRECT.port}'`;
|
|
17
|
+
const INSPECT_DARWIN = ` macOS: lsof -nP -iTCP:${AUTH_REDIRECT.port} -sTCP:LISTEN`;
|
|
18
|
+
const USE_DEVICE_AUTH = " Or sign in without the callback port: codex-multi-auth login --device-auth";
|
|
19
|
+
/**
|
|
20
|
+
* The commands that would reveal a listener on the callback port here.
|
|
21
|
+
*
|
|
22
|
+
* Inside WSL both sides of the boundary are worth checking, because the
|
|
23
|
+
* offending listener is usually the one on the Windows host.
|
|
24
|
+
*/
|
|
25
|
+
function inspectCommands() {
|
|
26
|
+
if (isWsl())
|
|
27
|
+
return [INSPECT_WINDOWS, INSPECT_LINUX];
|
|
28
|
+
if (process.platform === "win32")
|
|
29
|
+
return [INSPECT_WINDOWS];
|
|
30
|
+
if (process.platform === "darwin")
|
|
31
|
+
return [INSPECT_DARWIN];
|
|
32
|
+
return [INSPECT_LINUX];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Why a listener on the other side of the Windows/WSL boundary may be at fault.
|
|
36
|
+
*
|
|
37
|
+
* @returns Explanatory lines, or an empty array when no WSL boundary is in play.
|
|
38
|
+
*/
|
|
39
|
+
function crossBoundaryNote() {
|
|
40
|
+
if (isWsl()) {
|
|
41
|
+
const distro = getWslDistroName();
|
|
42
|
+
const where = distro ? `WSL (${distro})` : "WSL";
|
|
43
|
+
return [
|
|
44
|
+
`You are running inside ${where}, but the browser opens on the Windows host.`,
|
|
45
|
+
`Windows and ${where} contend for localhost:${AUTH_REDIRECT.port}, so a codex-multi-auth`,
|
|
46
|
+
"or Codex login or proxy on the Windows side can take the callback meant for this one.",
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
if (process.platform === "win32") {
|
|
50
|
+
return [
|
|
51
|
+
`A codex-multi-auth login or proxy running inside WSL can also hold port ${AUTH_REDIRECT.port}.`,
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build the lines shown to the user when a browser OAuth callback fails.
|
|
58
|
+
*
|
|
59
|
+
* Contention is only *asserted* when it was actually observed — that is, the
|
|
60
|
+
* listen failed with `EADDRINUSE`. A callback that never arrives is far more
|
|
61
|
+
* often a cancelled or abandoned sign-in than a stolen redirect, so that case
|
|
62
|
+
* is phrased as a conditional ("if you completed sign-in and still landed
|
|
63
|
+
* here") rather than a diagnosis.
|
|
64
|
+
*
|
|
65
|
+
* @param reason - Which half of the callback flow broke.
|
|
66
|
+
* @param context - Extra detail from the failed bind, when available.
|
|
67
|
+
* @returns Guidance lines. Empty strings are intentional blank separators.
|
|
68
|
+
*/
|
|
69
|
+
export function describeCallbackFailure(reason, context = {}) {
|
|
70
|
+
const port = AUTH_REDIRECT.port;
|
|
71
|
+
if (reason === "bind-failed") {
|
|
72
|
+
// A failed listen is hard evidence: something is on the port right now.
|
|
73
|
+
if (context.bindErrorCode === "EADDRINUSE") {
|
|
74
|
+
return [
|
|
75
|
+
`Could not listen on port ${port} for the OAuth callback — another process already holds it.`,
|
|
76
|
+
...crossBoundaryNote(),
|
|
77
|
+
"",
|
|
78
|
+
`Find the listener:`,
|
|
79
|
+
...inspectCommands(),
|
|
80
|
+
"",
|
|
81
|
+
"Close it, then retry.",
|
|
82
|
+
USE_DEVICE_AUTH,
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
return [
|
|
86
|
+
`Could not listen on port ${port} for the OAuth callback${context.bindErrorCode ? ` (${context.bindErrorCode})` : ""}.`,
|
|
87
|
+
"",
|
|
88
|
+
"The callback port is fixed by the provider and cannot be changed.",
|
|
89
|
+
USE_DEVICE_AUTH,
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
// The listener bound cleanly and nothing arrived. Usually the sign-in was
|
|
93
|
+
// simply cancelled or abandoned — say so first, and do not misdiagnose it.
|
|
94
|
+
return [
|
|
95
|
+
`No OAuth callback arrived on port ${port} before the sign-in window closed.`,
|
|
96
|
+
"",
|
|
97
|
+
"If you closed or cancelled the browser sign-in, just run login again.",
|
|
98
|
+
"",
|
|
99
|
+
"If you completed sign-in in the browser and still landed here, something else",
|
|
100
|
+
`may have taken the callback on port ${port}:`,
|
|
101
|
+
...crossBoundaryNote(),
|
|
102
|
+
...inspectCommands(),
|
|
103
|
+
"",
|
|
104
|
+
USE_DEVICE_AUTH,
|
|
105
|
+
];
|
|
106
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../lib/auth/server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAWnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,EACrC,KAAK,GACL,EAAE;IACF,KAAK,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../lib/auth/server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAWnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,EACrC,KAAK,GACL,EAAE;IACF,KAAK,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,eAAe,CAAC,CAiH3B"}
|
package/dist/lib/auth/server.js
CHANGED
|
@@ -2,8 +2,25 @@ import type { DashboardDisplaySettings } from "../../dashboard-settings.js";
|
|
|
2
2
|
import type { QuotaCacheEntry } from "../../quota-cache.js";
|
|
3
3
|
import { type CodexQuotaSnapshot, fetchCodexQuotaSnapshot } from "../../quota-probe.js";
|
|
4
4
|
export declare function styleQuotaSummary(summary: string): string;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Render the per-account health line printed by `codex-multi-auth check`.
|
|
7
|
+
*
|
|
8
|
+
* `check` is the only caller, and unlike the dashboard rows and account menu it
|
|
9
|
+
* prints one account per line with no width pressure, so it opts into the
|
|
10
|
+
* absolute reset clock for each quota window.
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatQuotaSnapshotForDashboard(snapshot: Awaited<ReturnType<typeof fetchCodexQuotaSnapshot>>, settings: DashboardDisplaySettings, now?: number): string;
|
|
6
13
|
export declare function quotaCacheEntryToSnapshot(entry: QuotaCacheEntry): CodexQuotaSnapshot;
|
|
7
|
-
|
|
8
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Options shared by the compact quota formatters.
|
|
16
|
+
*
|
|
17
|
+
* `showReset` is opt-in so that space-constrained surfaces (dashboard rows, the
|
|
18
|
+
* account menu, forecast lines) keep their existing single-line width, while
|
|
19
|
+
* `codex-multi-auth check` can append the absolute reset time.
|
|
20
|
+
*/
|
|
21
|
+
export interface CompactQuotaFormatOptions {
|
|
22
|
+
showReset?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function formatCompactQuotaSnapshot(snapshot: CodexQuotaSnapshot, now?: number, options?: CompactQuotaFormatOptions): string;
|
|
25
|
+
export declare function formatAccountQuotaSummary(entry: QuotaCacheEntry, now?: number, options?: CompactQuotaFormatOptions): string;
|
|
9
26
|
//# sourceMappingURL=quota-formatters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota-formatters.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/formatters/quota-formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EACN,KAAK,kBAAkB,EACvB,uBAAuB,
|
|
1
|
+
{"version":3,"file":"quota-formatters.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/formatters/quota-formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EACN,KAAK,kBAAkB,EACvB,uBAAuB,EAGvB,MAAM,sBAAsB,CAAC;AAY9B,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmCzD;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,EAC7D,QAAQ,EAAE,wBAAwB,EAClC,GAAG,SAAa,GACd,MAAM,CAGR;AAED,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,eAAe,GACpB,kBAAkB,CAgBpB;AAaD;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAqBD,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,kBAAkB,EAC5B,GAAG,SAAa,EAChB,OAAO,GAAE,yBAA8B,GACrC,MAAM,CA6BR;AAED,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,eAAe,EACtB,GAAG,SAAa,EAChB,OAAO,GAAE,yBAA8B,GACrC,MAAM,CA6BR"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { formatQuotaSnapshotLine, } from "../../quota-probe.js";
|
|
1
|
+
import { formatQuotaResetAt, formatQuotaSnapshotLine, } from "../../quota-probe.js";
|
|
2
2
|
import { isQuotaCacheEntryExhausted, quotaLeftPercentFromUsed, } from "../../quota-readiness.js";
|
|
3
3
|
import { quotaToneFromLeftPercent } from "../../ui/format.js";
|
|
4
4
|
import { collapseWhitespace, joinStyledSegments, stylePromptText, } from "./text-style.js";
|
|
@@ -16,7 +16,7 @@ export function styleQuotaSummary(summary) {
|
|
|
16
16
|
if (/rate-limited/i.test(segment)) {
|
|
17
17
|
return stylePromptText(segment, "danger");
|
|
18
18
|
}
|
|
19
|
-
const match = segment.match(/^([0-9a-zA-Z]+)\s+(\d{1,3})
|
|
19
|
+
const match = segment.match(/^([0-9a-zA-Z]+)\s+(\d{1,3})%(,\s*resets\s+\S.*)?$/);
|
|
20
20
|
if (!match) {
|
|
21
21
|
return stylePromptText(segment, "muted");
|
|
22
22
|
}
|
|
@@ -26,14 +26,24 @@ export function styleQuotaSummary(summary) {
|
|
|
26
26
|
return stylePromptText(segment, "muted");
|
|
27
27
|
}
|
|
28
28
|
const tone = quotaToneFromLeftPercent(leftPercent);
|
|
29
|
-
|
|
29
|
+
const resetSuffix = match[3]
|
|
30
|
+
? stylePromptText(match[3], "muted")
|
|
31
|
+
: "";
|
|
32
|
+
return `${stylePromptText(windowLabel, "muted")} ${stylePromptText(`${leftPercent}%`, tone)}${resetSuffix}`;
|
|
30
33
|
});
|
|
31
34
|
return joinStyledSegments(rendered);
|
|
32
35
|
}
|
|
33
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Render the per-account health line printed by `codex-multi-auth check`.
|
|
38
|
+
*
|
|
39
|
+
* `check` is the only caller, and unlike the dashboard rows and account menu it
|
|
40
|
+
* prints one account per line with no width pressure, so it opts into the
|
|
41
|
+
* absolute reset clock for each quota window.
|
|
42
|
+
*/
|
|
43
|
+
export function formatQuotaSnapshotForDashboard(snapshot, settings, now = Date.now()) {
|
|
34
44
|
if (!settings.showQuotaDetails)
|
|
35
45
|
return "live session OK";
|
|
36
|
-
return `live session OK (${formatCompactQuotaSnapshot(snapshot)})`;
|
|
46
|
+
return `live session OK (${formatCompactQuotaSnapshot(snapshot, now, { showReset: true })})`;
|
|
37
47
|
}
|
|
38
48
|
export function quotaCacheEntryToSnapshot(entry) {
|
|
39
49
|
return {
|
|
@@ -62,18 +72,23 @@ function formatCompactQuotaWindowLabel(windowMinutes) {
|
|
|
62
72
|
return `${windowMinutes / 60}h`;
|
|
63
73
|
return `${windowMinutes}m`;
|
|
64
74
|
}
|
|
65
|
-
function formatCompactQuotaPart(windowMinutes, usedPercent) {
|
|
75
|
+
function formatCompactQuotaPart(windowMinutes, usedPercent, resetAtMs, options, now) {
|
|
66
76
|
const label = formatCompactQuotaWindowLabel(windowMinutes);
|
|
67
77
|
if (typeof usedPercent !== "number" || !Number.isFinite(usedPercent)) {
|
|
68
78
|
return null;
|
|
69
79
|
}
|
|
70
80
|
const left = quotaLeftPercentFromUsed(usedPercent);
|
|
71
|
-
|
|
81
|
+
const part = `${label} ${left}%`;
|
|
82
|
+
if (!options.showReset)
|
|
83
|
+
return part;
|
|
84
|
+
// A missing or malformed reset timestamp must never drop the percentage.
|
|
85
|
+
const reset = formatQuotaResetAt(resetAtMs, now);
|
|
86
|
+
return reset ? `${part}, resets ${reset}` : part;
|
|
72
87
|
}
|
|
73
|
-
export function formatCompactQuotaSnapshot(snapshot, now = Date.now()) {
|
|
88
|
+
export function formatCompactQuotaSnapshot(snapshot, now = Date.now(), options = {}) {
|
|
74
89
|
const parts = [
|
|
75
|
-
formatCompactQuotaPart(snapshot.primary.windowMinutes, snapshot.primary.usedPercent),
|
|
76
|
-
formatCompactQuotaPart(snapshot.secondary.windowMinutes, snapshot.secondary.usedPercent),
|
|
90
|
+
formatCompactQuotaPart(snapshot.primary.windowMinutes, snapshot.primary.usedPercent, snapshot.primary.resetAtMs, options, now),
|
|
91
|
+
formatCompactQuotaPart(snapshot.secondary.windowMinutes, snapshot.secondary.usedPercent, snapshot.secondary.resetAtMs, options, now),
|
|
77
92
|
].filter((value) => typeof value === "string" && value.length > 0);
|
|
78
93
|
if (snapshot.status === 429) {
|
|
79
94
|
parts.push("rate-limited");
|
|
@@ -86,10 +101,10 @@ export function formatCompactQuotaSnapshot(snapshot, now = Date.now()) {
|
|
|
86
101
|
}
|
|
87
102
|
return formatQuotaSnapshotLine(snapshot);
|
|
88
103
|
}
|
|
89
|
-
export function formatAccountQuotaSummary(entry, now = Date.now()) {
|
|
104
|
+
export function formatAccountQuotaSummary(entry, now = Date.now(), options = {}) {
|
|
90
105
|
const parts = [
|
|
91
|
-
formatCompactQuotaPart(entry.primary.windowMinutes, entry.primary.usedPercent),
|
|
92
|
-
formatCompactQuotaPart(entry.secondary.windowMinutes, entry.secondary.usedPercent),
|
|
106
|
+
formatCompactQuotaPart(entry.primary.windowMinutes, entry.primary.usedPercent, entry.primary.resetAtMs, options, now),
|
|
107
|
+
formatCompactQuotaPart(entry.secondary.windowMinutes, entry.secondary.usedPercent, entry.secondary.resetAtMs, options, now),
|
|
93
108
|
].filter((value) => typeof value === "string" && value.length > 0);
|
|
94
109
|
if (entry.status === 429) {
|
|
95
110
|
parts.push("rate-limited");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/help.ts"],"names":[],"mappings":"AAIA,wBAAgB,UAAU,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/help.ts"],"names":[],"mappings":"AAIA,wBAAgB,UAAU,IAAI,IAAI,CAsDjC;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAgEtE;AAED,UAAU,cAAc;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,cAAc,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,wBAAgB,cAAc,IAAI,IAAI,CAgBrC;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CAyD5D"}
|
|
@@ -6,46 +6,50 @@ export function printUsage() {
|
|
|
6
6
|
"",
|
|
7
7
|
"Start here:",
|
|
8
8
|
" codex-multi-auth login [--device-auth|--manual|--no-browser] [--org <org_id>]",
|
|
9
|
-
" codex-multi-auth status",
|
|
10
|
-
" codex-multi-auth check",
|
|
9
|
+
" codex-multi-auth status [--json] (list is the same command)",
|
|
10
|
+
" codex-multi-auth check (always live-probes)",
|
|
11
11
|
"",
|
|
12
12
|
"Daily use:",
|
|
13
|
-
" codex-multi-auth list",
|
|
13
|
+
" codex-multi-auth list [--json]",
|
|
14
14
|
" codex-multi-auth switch <index> (pins the account for runtime routing)",
|
|
15
15
|
" codex-multi-auth unpin (clears the manual pin set by switch)",
|
|
16
16
|
" codex-multi-auth workspace <account> [workspace] (list or switch an account's workspaces)",
|
|
17
17
|
" codex-multi-auth best [--live] [--json] [--model <model>] (clears any manual pin set by switch)",
|
|
18
|
-
" codex-multi-auth forecast [--live] [--json] [--model <model>]",
|
|
19
|
-
" codex-multi-auth account tag|untag|weight|pause|unpause|drain|undrain|note ...",
|
|
18
|
+
" codex-multi-auth forecast [--live] [--json] [--explain] [--model <model>] [--no-runtime-overlay]",
|
|
19
|
+
" codex-multi-auth account tag|untag|weight|pause|unpause|drain|undrain|note|policy list ...",
|
|
20
20
|
"",
|
|
21
21
|
"Repair:",
|
|
22
22
|
" codex-multi-auth uninstall [--dry-run] [--json] [--clear-accounts]",
|
|
23
|
-
" codex-multi-auth verify-flagged [--dry-run] [--json] [--no-restore]",
|
|
23
|
+
" codex-multi-auth verify-flagged [--dry-run|-n] [--json] [--no-restore]",
|
|
24
24
|
" codex-multi-auth verify [--paths | --flagged | --all] [--json]",
|
|
25
|
-
" codex-multi-auth fix [--dry-run] [--json] [--live] [--model <model>]",
|
|
26
|
-
" codex-multi-auth doctor [--json] [--fix] [--dry-run]",
|
|
25
|
+
" codex-multi-auth fix [--dry-run|-n] [--json] [--live] [--model <model>]",
|
|
26
|
+
" codex-multi-auth doctor [--json] [--fix] [--dry-run|-n] (--dry-run requires --fix)",
|
|
27
27
|
"",
|
|
28
28
|
"Diagnostics:",
|
|
29
29
|
" codex-multi-auth usage [--since <time|duration>] [--by <group>] [--json|--csv] [--out <path>]",
|
|
30
|
-
" codex-multi-auth
|
|
31
|
-
" codex-multi-auth
|
|
30
|
+
" codex-multi-auth usage rotate [--if-larger-than-bytes <n>] [--json]",
|
|
31
|
+
" codex-multi-auth budget limit <key> --window <hour|day|week|month> [--requests N] [--tokens N] [--cost USD]",
|
|
32
|
+
" codex-multi-auth budget check|list [--json]",
|
|
33
|
+
" codex-multi-auth bridge token create|list|rotate|revoke [--json]",
|
|
32
34
|
" codex-multi-auth integrations [--kind <name>] [--base-url <url>] [--model <model>] [--json]",
|
|
33
35
|
" codex-multi-auth models [--json] [--model <model>]",
|
|
34
36
|
" codex-multi-auth monitor [--json]",
|
|
35
|
-
" codex-multi-auth rotation <enable|disable|status|bind-app|unbind-app>",
|
|
37
|
+
" codex-multi-auth rotation <enable|disable|status|bind-app|unbind-app|reset-runtime>",
|
|
36
38
|
" codex-multi-auth rotation reset-rate-limits [--all | --account <idx>] [--dry-run] [--json]",
|
|
37
|
-
" codex-multi-auth why-selected [--now | --last] [--json]",
|
|
39
|
+
" codex-multi-auth why-selected [--now|-n | --last|-l] [--json]",
|
|
38
40
|
" codex-multi-auth history [list|show <id>] [--json] (all local sessions, ignores /resume provider filtering)",
|
|
39
41
|
"",
|
|
40
42
|
"Advanced:",
|
|
41
|
-
" codex-multi-auth report [--live] [--json] [--explain] [--model <model>] [--out <path>]",
|
|
43
|
+
" codex-multi-auth report [--live] [--json] [--explain] [--model <model>] [--max-accounts <n>] [--max-probes <n>] [--cached-only] [--out <path>]",
|
|
42
44
|
" codex-multi-auth config explain [--json]",
|
|
45
|
+
" codex-multi-auth config template|init-config [modern|legacy|minimal] [--write <path>] [--stdout]",
|
|
43
46
|
" codex-multi-auth debug bundle [--json]",
|
|
44
|
-
" codex-multi-auth features",
|
|
47
|
+
" codex-multi-auth features (partial built-in checklist; see docs/features.md for the full product map)",
|
|
45
48
|
"",
|
|
46
49
|
"Notes:",
|
|
47
50
|
" - Uses ~/.codex/multi-auth/openai-codex-accounts.json",
|
|
48
51
|
" - Syncs active account into Codex CLI auth state",
|
|
52
|
+
" - Default live probe model: " + DEFAULT_LIVE_PROBE_MODEL,
|
|
49
53
|
" - See docs/reference/commands.md for the full command and flag matrix",
|
|
50
54
|
].join("\n"));
|
|
51
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login-oauth.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/login-oauth.ts"],"names":[],"mappings":"AAEA,OAAO,EAON,KAAK,SAAS,EACd,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"login-oauth.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/login-oauth.ts"],"names":[],"mappings":"AAEA,OAAO,EAON,KAAK,SAAS,EACd,MAAM,gBAAgB,CAAC;AAsBxB,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EACN,KAAK,uBAAuB,EAG5B,MAAM,yBAAyB,CAAC;AAOjC;;;;;GAKG;AAEH,gBAAgB;AAChB,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AACrE,gBAAgB;AAChB,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG;IACpD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CACzB,CAAC;AAIF,gBAAgB;AAChB,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,GAC/C,OAAO,CAGT;AAED,gBAAgB;AAChB,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIpD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,YAAY,EACpB,WAAW,CAAC,EAAE,MAAM,GAClB,uBAAuB,CA+DzB;AA0FD,gBAAgB;AAChB,MAAM,MAAM,eAAe,GACxB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,gBAAgB,GAChB,QAAQ,CAAC;AACZ,gBAAgB;AAChB,MAAM,MAAM,iBAAiB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,gBAAgB;AAChB,wBAAsB,YAAY,CACjC,aAAa,EAAE,OAAO,EACtB,UAAU,EAAE,OAAO,CAAC,eAAe,EAAE,SAAS,GAAG,QAAQ,CAAC,GACxD,OAAO,CAAC,WAAW,CAAC,CAsItB;AAED,gBAAgB;AAChB,wBAAsB,aAAa,CAClC,aAAa,EAAE,OAAO,EACtB,UAAU,EAAE,OAAO,CAAC,eAAe,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC,EACrE,OAAO,GAAE,iBAAsB,GAC7B,OAAO,CAAC,WAAW,CAAC,CAetB;AAED,gBAAgB;AAChB,MAAM,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAEhE,gBAAgB;AAChB,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,uBAAuB,EAAE,EAClC,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAuD3C;AAED,gBAAgB;AAChB,wBAAsB,oBAAoB,CACzC,MAAM,EAAE,uBAAuB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|
|
@@ -6,6 +6,7 @@ import { copyTextToClipboard, openBrowserUrl, } from "../auth/browser.js";
|
|
|
6
6
|
import { runDeviceAuthFlow } from "../auth/device-auth.js";
|
|
7
7
|
import { resolveOrgOverride } from "../auth/org-override.js";
|
|
8
8
|
import { startLocalOAuthServer } from "../auth/server.js";
|
|
9
|
+
import { describeCallbackFailure } from "../auth/callback-guidance.js";
|
|
9
10
|
import { setCodexCliActiveSelection } from "../codex-cli/writer.js";
|
|
10
11
|
import { createLogger } from "../logger.js";
|
|
11
12
|
import { MODEL_FAMILIES } from "../prompts/codex.js";
|
|
@@ -230,6 +231,16 @@ export async function runOAuthFlow(forceNewLogin, signInMode) {
|
|
|
230
231
|
: signInMode === "manual"
|
|
231
232
|
? UI_COPY.oauth.callbackBypassed
|
|
232
233
|
: UI_COPY.oauth.callbackUnavailable, "warning"));
|
|
234
|
+
// Explain *why* the callback failed before dropping the user into the
|
|
235
|
+
// manual-paste prompt. A contended port 1455 — most often a Windows
|
|
236
|
+
// listener shadowing a WSL one, or vice versa — otherwise presents as
|
|
237
|
+
// an unexplained broken login.
|
|
238
|
+
if (signInMode === "browser") {
|
|
239
|
+
const failureLines = describeCallbackFailure(waitingForCallback ? "callback-timeout" : "bind-failed", { bindErrorCode: oauthServer?.bindErrorCode });
|
|
240
|
+
for (const line of failureLines) {
|
|
241
|
+
console.log(line.length > 0 ? stylePromptText(line, "muted") : "");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
233
244
|
const manualResult = await promptManualCallback(state, {
|
|
234
245
|
allowNonTty: signInMode === "manual",
|
|
235
246
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-manager.d.ts","sourceRoot":"","sources":["../../lib/codex-manager.ts"],"names":[],"mappings":"AAqFA,OAAO,EAEN,mBAAmB,EAMnB,sBAAsB,EAGtB,MAAM,qCAAqC,CAAC;AAiD7C,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"codex-manager.d.ts","sourceRoot":"","sources":["../../lib/codex-manager.ts"],"names":[],"mappings":"AAqFA,OAAO,EAEN,mBAAmB,EAMnB,sBAAsB,EAGtB,MAAM,qCAAqC,CAAC;AAiD7C,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,CAAC;AA4IvD,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,OAAO,CAAC,CAuGrE;AAwRD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4C7E"}
|
|
@@ -113,6 +113,19 @@ const IMPLEMENTED_FEATURES = [
|
|
|
113
113
|
{ id: 39, name: "Unified color/theme runtime (v2 UI)" },
|
|
114
114
|
{ id: 40, name: "OAuth browser-first flow with manual callback fallback" },
|
|
115
115
|
{ id: 41, name: "Auto-switch to best account command" },
|
|
116
|
+
{ id: 42, name: "Device-code OAuth login (--device-auth)" },
|
|
117
|
+
{ id: 43, name: "Workspace/org-bound login (--org)" },
|
|
118
|
+
{ id: 44, name: "Manual pin, unpin, and affinity-generation invalidation" },
|
|
119
|
+
{ id: 45, name: "Per-account workspace selection command" },
|
|
120
|
+
{ id: 46, name: "Default-on runtime Responses rotation proxy" },
|
|
121
|
+
{ id: 47, name: "Reversible packaged Codex app bind and launcher routing" },
|
|
122
|
+
{ id: 48, name: "Local usage ledger, budgets, and account policies" },
|
|
123
|
+
{ id: 49, name: "Routing profiles and model capability matrix" },
|
|
124
|
+
{ id: 50, name: "Local bridge tokens and integration snippets" },
|
|
125
|
+
{ id: 51, name: "Provider-agnostic local history listing" },
|
|
126
|
+
{ id: 52, name: "Why-selected and monitor diagnostics" },
|
|
127
|
+
{ id: 53, name: "Config explain, init-config templates, and debug bundle" },
|
|
128
|
+
{ id: 54, name: "mcodex convenience launcher (monitor/tmux/forward)" },
|
|
116
129
|
];
|
|
117
130
|
async function runForecast(args) {
|
|
118
131
|
return runForecastCommand(args, {
|
|
@@ -32,6 +32,19 @@ export interface CodexQuotaSnapshot {
|
|
|
32
32
|
secondary: CodexQuotaWindow;
|
|
33
33
|
model: string;
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Format a millisecond epoch timestamp into a concise human-readable reset time.
|
|
37
|
+
*
|
|
38
|
+
* Returns a 24-hour time "HH:MM" when the timestamp is today, otherwise "HH:MM on Mon DD".
|
|
39
|
+
*
|
|
40
|
+
* This function has no side effects, is safe for concurrent use, does not access the filesystem,
|
|
41
|
+
* and produces no sensitive token data.
|
|
42
|
+
*
|
|
43
|
+
* @param resetAtMs - Timestamp in milliseconds since epoch; if `undefined`, non-finite, or <= 0, the function returns `undefined`.
|
|
44
|
+
* @param nowMs - Reference timestamp used for the "is today" comparison; defaults to the current time.
|
|
45
|
+
* @returns The formatted reset time string, or `undefined` if `resetAtMs` is invalid or not provided.
|
|
46
|
+
*/
|
|
47
|
+
export declare function formatQuotaResetAt(resetAtMs: number | undefined, nowMs?: number): string | undefined;
|
|
35
48
|
/**
|
|
36
49
|
* Produce a single-line human-readable summary of a Codex quota snapshot.
|
|
37
50
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota-probe.d.ts","sourceRoot":"","sources":["../../lib/quota-probe.ts"],"names":[],"mappings":"AAYA;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,yCAAyC,CAAC;AAEnF;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,OAAO,EACd,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GACrC,MAAM,CAMR;AAED,MAAM,WAAW,gBAAgB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACd;
|
|
1
|
+
{"version":3,"file":"quota-probe.d.ts","sourceRoot":"","sources":["../../lib/quota-probe.ts"],"names":[],"mappings":"AAYA;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,yCAAyC,CAAC;AAEnF;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,OAAO,EACd,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GACrC,MAAM,CAMR;AAED,MAAM,WAAW,gBAAgB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACd;AA0MD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,KAAK,SAAa,GAChB,MAAM,GAAG,SAAS,CAqBpB;AAwBD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,CAa5E;AAED,MAAM,WAAW,sBAAsB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,uBAAuB,CAC5C,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC,kBAAkB,CAAC,CA4G7B"}
|