@illiadotdev/codex-usage-plugin 0.2.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Illia Rudyi - illiadotdev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Codex Usage Plugin for OpenCode
2
+
3
+ OpenCode plugin that exposes a `/codex-usage` TUI command for viewing Codex ChatGPT usage limits and credits. It also keeps a `codex_usage` tool for manual/debug agent use.
4
+
5
+ ## Usage
6
+
7
+ 1. Install the package globally:
8
+
9
+ ```sh
10
+ npm install -g @illiadotdev/codex-usage-plugin
11
+ ```
12
+
13
+ 2. Register the plugin in OpenCode:
14
+
15
+ ```sh
16
+ codex-usage-plugin --install
17
+ ```
18
+
19
+ This builds `dist/` and registers the generated plugin path in `~/.config/opencode/opencode.jsonc`.
20
+ 3. Restart OpenCode so it loads `dist/index.js`.
21
+ 4. Run `/codex-usage` in the OpenCode TUI.
22
+
23
+ To remove the plugin registration:
24
+
25
+ ```sh
26
+ codex-usage-plugin --uninstall
27
+ ```
28
+
29
+ To remove the npm package too:
30
+
31
+ ```sh
32
+ npm uninstall -g @illiadotdev/codex-usage-plugin
33
+ ```
34
+
35
+ The `/codex-usage` slash command is registered and handled by the plugin through OpenCode's server plugin hooks. It shows an OpenCode toast.
36
+
37
+ ## What It Reads
38
+
39
+ The plugin reads auth from:
40
+
41
+ - `OPENCODE_AUTH_PATH`, when set
42
+ - `~/.local/share/opencode/auth.json`
43
+ - `~/Library/Application Support/opencode/auth.json` on macOS
44
+ - `~/.opencode/auth.json`
45
+ - `%LOCALAPPDATA%\\OpenCode\\auth.json` as a fallback
46
+ - `$CODEX_HOME/auth.json`, when `CODEX_HOME` is set
47
+ - `~/.codex/auth.json`, otherwise
48
+
49
+ It calls the same ChatGPT backend usage surfaces Codex uses:
50
+
51
+ - `https://chatgpt.com/backend-api/wham/usage`
52
+ - `https://chatgpt.com/backend-api/wham/profiles/me`
53
+
54
+ ## Limitations
55
+
56
+ Plugin supports file-backed OpenCode/Codex auth only. If your client stores tokens in the OS keyring, the plugin will report that `auth.json` is unavailable. Keyring support can be added later.
57
+
58
+ The plugin never prints access tokens, refresh tokens, or ID tokens.
59
+
60
+ ## Publishing
61
+
62
+ Maintainers publish by pushing a tag like `v0.2.2`. The release workflow runs tests and publishes the package to npm automatically.
63
+
64
+ This uses npm trusted publishing, so no `NPM_TOKEN` secret is needed. The npm package must be configured to trust this GitHub repository for publishing.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runCliSafely } from "../cli.js";
3
+ await runCliSafely();
4
+ //# sourceMappingURL=codex-usage-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-usage-plugin.js","sourceRoot":"","sources":["../../src/bin/codex-usage-plugin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,YAAY,EAAE,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function runCli(argv?: string[]): Promise<void>;
2
+ export declare function runCliSafely(argv?: string[]): Promise<void>;
package/dist/cli.js ADDED
@@ -0,0 +1,331 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ const helpText = () => [
6
+ "Usage: codex-usage-plugin [options]",
7
+ "",
8
+ "Options:",
9
+ " -h, --help Show this help message",
10
+ " --install Add built plugin path to global OpenCode config",
11
+ " --uninstall Remove plugin path from global OpenCode config",
12
+ " --config <path> Server OpenCode config path",
13
+ " --tui-config <path> TUI config path to clean old registrations",
14
+ "",
15
+ "Examples:",
16
+ " codex-usage-plugin --install",
17
+ " codex-usage-plugin --uninstall",
18
+ ].join("\n");
19
+ function moduleDistDir() {
20
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
21
+ return moduleDir.endsWith(`${join("dist", "bin")}`)
22
+ ? resolve(moduleDir, "..")
23
+ : moduleDir;
24
+ }
25
+ function pluginPath(name) {
26
+ return normalizePath(join(moduleDistDir(), `${name}.js`));
27
+ }
28
+ function repoRootFromDist() {
29
+ return normalizePath(resolve(moduleDistDir(), ".."));
30
+ }
31
+ function normalizePath(value) {
32
+ return resolve(value).replaceAll("\\", "/");
33
+ }
34
+ function defaultOpencodeConfigPath() {
35
+ return join(homedir(), ".config", "opencode", "opencode.jsonc");
36
+ }
37
+ function defaultTuiConfigPath() {
38
+ return join(homedir(), ".config", "opencode", "tui.json");
39
+ }
40
+ function parseCliOptions(argv) {
41
+ const options = { help: false, install: false, uninstall: false };
42
+ for (let index = 0; index < argv.length; index += 1) {
43
+ const arg = argv[index];
44
+ if (arg === "-h" || arg === "--help") {
45
+ options.help = true;
46
+ continue;
47
+ }
48
+ if (arg === "--install") {
49
+ options.install = true;
50
+ continue;
51
+ }
52
+ if (arg === "--uninstall") {
53
+ options.uninstall = true;
54
+ continue;
55
+ }
56
+ if (arg === "--config" || arg === "--tui-config") {
57
+ const value = argv[index + 1];
58
+ if (!value || value.startsWith("--"))
59
+ throw new Error(`${arg} requires a value`);
60
+ if (arg === "--config")
61
+ options.opencodeConfigPath = resolve(value);
62
+ else
63
+ options.tuiConfigPath = resolve(value);
64
+ index += 1;
65
+ continue;
66
+ }
67
+ if (arg.startsWith("--config=")) {
68
+ options.opencodeConfigPath = resolve(arg.slice("--config=".length));
69
+ continue;
70
+ }
71
+ if (arg.startsWith("--tui-config=")) {
72
+ options.tuiConfigPath = resolve(arg.slice("--tui-config=".length));
73
+ continue;
74
+ }
75
+ throw new Error(`unknown option: ${arg}`);
76
+ }
77
+ if (options.install && options.uninstall)
78
+ throw new Error("--install and --uninstall cannot be combined");
79
+ return options;
80
+ }
81
+ function findMatchingBracket(text, openIndex) {
82
+ let depth = 0;
83
+ let inString = false;
84
+ let escaped = false;
85
+ for (let index = openIndex; index < text.length; index += 1) {
86
+ const char = text[index];
87
+ if (inString) {
88
+ if (escaped) {
89
+ escaped = false;
90
+ continue;
91
+ }
92
+ if (char === "\\") {
93
+ escaped = true;
94
+ continue;
95
+ }
96
+ if (char === '"')
97
+ inString = false;
98
+ continue;
99
+ }
100
+ if (char === '"') {
101
+ inString = true;
102
+ continue;
103
+ }
104
+ if (char === "[")
105
+ depth += 1;
106
+ if (char === "]") {
107
+ depth -= 1;
108
+ if (depth === 0)
109
+ return index;
110
+ }
111
+ }
112
+ return -1;
113
+ }
114
+ function splitTopLevelArrayItems(content) {
115
+ const items = [];
116
+ let squareDepth = 0;
117
+ let curlyDepth = 0;
118
+ let inString = false;
119
+ let escaped = false;
120
+ let start = 0;
121
+ for (let index = 0; index < content.length; index += 1) {
122
+ const char = content[index];
123
+ if (inString) {
124
+ if (escaped) {
125
+ escaped = false;
126
+ continue;
127
+ }
128
+ if (char === "\\") {
129
+ escaped = true;
130
+ continue;
131
+ }
132
+ if (char === '"')
133
+ inString = false;
134
+ continue;
135
+ }
136
+ if (char === '"') {
137
+ inString = true;
138
+ continue;
139
+ }
140
+ if (char === "[")
141
+ squareDepth += 1;
142
+ if (char === "]")
143
+ squareDepth = Math.max(0, squareDepth - 1);
144
+ if (char === "{")
145
+ curlyDepth += 1;
146
+ if (char === "}")
147
+ curlyDepth = Math.max(0, curlyDepth - 1);
148
+ if (char === "," && squareDepth === 0 && curlyDepth === 0) {
149
+ const item = content.slice(start, index).trim();
150
+ if (item)
151
+ items.push(item);
152
+ start = index + 1;
153
+ }
154
+ }
155
+ const tail = content.slice(start).trim();
156
+ if (tail)
157
+ items.push(tail);
158
+ return items;
159
+ }
160
+ function parseStringLiteral(item) {
161
+ try {
162
+ const parsed = JSON.parse(item);
163
+ return typeof parsed === "string" ? normalizePath(parsed) : undefined;
164
+ }
165
+ catch {
166
+ return undefined;
167
+ }
168
+ }
169
+ function rebuildPluginArray(content, nextItems) {
170
+ const pluginMatch = /"plugin"\s*:\s*\[/m.exec(content);
171
+ if (!pluginMatch || pluginMatch.index === undefined)
172
+ return undefined;
173
+ const openIndex = content.indexOf("[", pluginMatch.index);
174
+ if (openIndex < 0)
175
+ return undefined;
176
+ const closeIndex = findMatchingBracket(content, openIndex);
177
+ if (closeIndex < 0)
178
+ return undefined;
179
+ const lineStart = content.lastIndexOf("\n", pluginMatch.index) + 1;
180
+ const baseIndent = content.slice(lineStart, pluginMatch.index).match(/^\s*/)?.[0] ?? "";
181
+ const itemIndent = `${baseIndent} `;
182
+ const inside = nextItems.length
183
+ ? `\n${nextItems.map((item) => `${itemIndent}${item}`).join(",\n")}\n${baseIndent}`
184
+ : `\n${baseIndent}`;
185
+ return `${content.slice(0, openIndex + 1)}${inside}${content.slice(closeIndex)}`;
186
+ }
187
+ function pluginArrayItems(content) {
188
+ const pluginMatch = /"plugin"\s*:\s*\[/m.exec(content);
189
+ if (!pluginMatch || pluginMatch.index === undefined)
190
+ return undefined;
191
+ const openIndex = content.indexOf("[", pluginMatch.index);
192
+ if (openIndex < 0)
193
+ return undefined;
194
+ const closeIndex = findMatchingBracket(content, openIndex);
195
+ if (closeIndex < 0)
196
+ return undefined;
197
+ return splitTopLevelArrayItems(content.slice(openIndex + 1, closeIndex));
198
+ }
199
+ function addPluginProperty(content, pluginLiteral) {
200
+ const firstBrace = content.indexOf("{");
201
+ if (firstBrace < 0)
202
+ return undefined;
203
+ return `${content.slice(0, firstBrace + 1)}\n "plugin": [\n ${pluginLiteral}\n ],${content.slice(firstBrace + 1)}`;
204
+ }
205
+ function updateConfigContent(content, target, action) {
206
+ const pluginLiteral = JSON.stringify(target.pluginPath);
207
+ const stale = new Set(target.stalePluginPaths.map(normalizePath));
208
+ const items = pluginArrayItems(content);
209
+ if (!items) {
210
+ if (action === "uninstall")
211
+ return content;
212
+ return (addPluginProperty(content, pluginLiteral) ?? freshConfig(target, action));
213
+ }
214
+ const nextItems = items.filter((item) => {
215
+ const parsed = parseStringLiteral(item);
216
+ return parsed !== target.pluginPath && (parsed ? !stale.has(parsed) : true);
217
+ });
218
+ if (action === "install")
219
+ nextItems.push(pluginLiteral);
220
+ return rebuildPluginArray(content, nextItems) ?? content;
221
+ }
222
+ function freshConfig(target, action) {
223
+ const pluginItems = action === "install"
224
+ ? `\n ${JSON.stringify(target.pluginPath)}\n `
225
+ : "";
226
+ return `{
227
+ "$schema": ${JSON.stringify(target.schema)},
228
+ "plugin": [${pluginItems}]
229
+ }
230
+ `;
231
+ }
232
+ async function readConfig(path) {
233
+ try {
234
+ return await readFile(path, "utf8");
235
+ }
236
+ catch (error) {
237
+ if (typeof error === "object" &&
238
+ error &&
239
+ "code" in error &&
240
+ error.code === "ENOENT")
241
+ return undefined;
242
+ throw error;
243
+ }
244
+ }
245
+ async function writeConfig(target, action) {
246
+ const current = await readConfig(target.path);
247
+ if (current === undefined) {
248
+ if (action === "uninstall") {
249
+ process.stdout.write(`No changes needed: ${target.path}\n`);
250
+ return;
251
+ }
252
+ const next = freshConfig(target, action);
253
+ await mkdir(dirname(target.path), { recursive: true });
254
+ await writeFile(target.path, next, "utf8");
255
+ process.stdout.write(`Updated: ${target.path}\n`);
256
+ return;
257
+ }
258
+ const next = updateConfigContent(current, target, action);
259
+ if (next === current) {
260
+ process.stdout.write(`No changes needed: ${target.path}\n`);
261
+ return;
262
+ }
263
+ await mkdir(dirname(target.path), { recursive: true });
264
+ await writeFile(target.path, next, "utf8");
265
+ process.stdout.write(`${action === "install" ? "Updated" : "Removed from"}: ${target.path}\n`);
266
+ }
267
+ async function cleanupConfigIfExists(target) {
268
+ const current = await readConfig(target.path);
269
+ if (current === undefined)
270
+ return;
271
+ const next = updateConfigContent(current, target, "uninstall");
272
+ if (next === current) {
273
+ process.stdout.write(`No changes needed: ${target.path}\n`);
274
+ return;
275
+ }
276
+ await writeFile(target.path, next, "utf8");
277
+ process.stdout.write(`Removed old registration from: ${target.path}\n`);
278
+ }
279
+ function configTargets(options) {
280
+ const root = repoRootFromDist();
281
+ return [
282
+ {
283
+ path: options.opencodeConfigPath ?? defaultOpencodeConfigPath(),
284
+ pluginPath: pluginPath("index"),
285
+ schema: "https://opencode.ai/config.json",
286
+ stalePluginPaths: [
287
+ `${root}/dist/server.js`,
288
+ `${root}/src/index.ts`,
289
+ `${root}/src/server.ts`,
290
+ `${root}/.opencode/codex-usage-plugin/server.ts`,
291
+ `${root}/.opencode/codex-usage-plugin`,
292
+ ],
293
+ },
294
+ ];
295
+ }
296
+ function tuiCleanupTarget(options) {
297
+ const root = repoRootFromDist();
298
+ return {
299
+ path: options.tuiConfigPath ?? defaultTuiConfigPath(),
300
+ pluginPath: pluginPath("tui"),
301
+ schema: "https://opencode.ai/tui.json",
302
+ stalePluginPaths: [
303
+ `${root}/src/tui.ts`,
304
+ `${root}/.opencode/codex-usage-plugin/tui.ts`,
305
+ `${root}/.opencode/codex-usage-plugin`,
306
+ ],
307
+ };
308
+ }
309
+ export async function runCli(argv = process.argv.slice(2)) {
310
+ const options = parseCliOptions(argv);
311
+ if (options.help || (!options.install && !options.uninstall)) {
312
+ process.stdout.write(`${helpText()}\n`);
313
+ return;
314
+ }
315
+ const action = options.install ? "install" : "uninstall";
316
+ await Promise.all([
317
+ ...configTargets(options).map((target) => writeConfig(target, action)),
318
+ cleanupConfigIfExists(tuiCleanupTarget(options)),
319
+ ]);
320
+ }
321
+ export async function runCliSafely(argv = process.argv.slice(2)) {
322
+ try {
323
+ await runCli(argv);
324
+ }
325
+ catch (error) {
326
+ const message = error instanceof Error ? error.message : String(error);
327
+ process.stderr.write(`${message}\n`);
328
+ process.exitCode = 1;
329
+ }
330
+ }
331
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function getCodexUsage(options?: {
2
+ requestTimeoutMs?: number;
3
+ }): Promise<{
4
+ markdown: string;
5
+ toast: string;
6
+ }>;
@@ -0,0 +1,359 @@
1
+ import { existsSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { join, resolve } from "node:path";
5
+ const CHATGPT_BACKEND_URL = "https://chatgpt.com/backend-api";
6
+ const USAGE_URL = `${CHATGPT_BACKEND_URL}/wham/usage`;
7
+ const PROFILE_URL = `${CHATGPT_BACKEND_URL}/wham/profiles/me`;
8
+ const CHATGPT_USAGE_URL = "https://chatgpt.com/codex/settings/usage";
9
+ function codexHome() {
10
+ const fromEnv = process.env.CODEX_HOME?.trim();
11
+ if (fromEnv)
12
+ return resolve(fromEnv);
13
+ return join(homedir(), ".codex");
14
+ }
15
+ function openCodeAuthPath() {
16
+ const fromEnv = process.env.OPENCODE_AUTH_PATH?.trim();
17
+ if (fromEnv)
18
+ return resolve(fromEnv);
19
+ if (process.platform === "darwin") {
20
+ return join(homedir(), "Library", "Application Support", "opencode", "auth.json");
21
+ }
22
+ const xdgDataHome = process.env.XDG_DATA_HOME?.trim() || join(homedir(), ".local", "share");
23
+ return join(xdgDataHome, "opencode", "auth.json");
24
+ }
25
+ function codexAuthPath() {
26
+ return join(codexHome(), "auth.json");
27
+ }
28
+ function normalizeAuthFile(raw) {
29
+ if (!raw || typeof raw !== "object")
30
+ return undefined;
31
+ const parsed = raw;
32
+ const tokens = parsed.tokens;
33
+ const accessToken = stringValue(tokens?.access_token);
34
+ if (accessToken) {
35
+ return {
36
+ auth_mode: stringValue(parsed.auth_mode),
37
+ OPENAI_API_KEY: typeof parsed.OPENAI_API_KEY === "string" ? parsed.OPENAI_API_KEY : undefined,
38
+ tokens: {
39
+ id_token: tokens?.id_token,
40
+ access_token: accessToken,
41
+ refresh_token: stringValue(tokens?.refresh_token),
42
+ account_id: stringValue(tokens?.account_id),
43
+ },
44
+ };
45
+ }
46
+ const openai = parsed.openai;
47
+ const openaiAccess = stringValue(openai?.access);
48
+ if (openaiAccess) {
49
+ return {
50
+ tokens: {
51
+ access_token: openaiAccess,
52
+ account_id: stringValue(openai?.accountId),
53
+ },
54
+ };
55
+ }
56
+ return undefined;
57
+ }
58
+ async function readAuthFile(authPath) {
59
+ if (!existsSync(authPath))
60
+ return undefined;
61
+ const raw = await readFile(authPath, "utf8");
62
+ const parsed = JSON.parse(raw);
63
+ const auth = normalizeAuthFile(parsed);
64
+ if (!auth?.tokens?.access_token &&
65
+ parsed &&
66
+ typeof parsed === "object" &&
67
+ typeof parsed.OPENAI_API_KEY === "string" &&
68
+ stringValue(parsed.OPENAI_API_KEY)) {
69
+ throw new Error("Codex is configured with an API key. ChatGPT/Codex OAuth auth is required to read usage limits.");
70
+ }
71
+ if (!auth?.tokens?.access_token) {
72
+ throw new Error(`Auth file at ${authPath} does not contain ChatGPT OAuth tokens.`);
73
+ }
74
+ return auth;
75
+ }
76
+ async function readAuth() {
77
+ const authPaths = [
78
+ openCodeAuthPath(),
79
+ join(homedir(), ".local", "share", "opencode", "auth.json"),
80
+ join(homedir(), ".opencode", "auth.json"),
81
+ join(process.env.LOCALAPPDATA?.trim() || join(homedir(), "AppData", "Local"), "OpenCode", "auth.json"),
82
+ codexAuthPath(),
83
+ ];
84
+ let lastError;
85
+ for (const authPath of authPaths) {
86
+ try {
87
+ const auth = await readAuthFile(authPath);
88
+ if (auth)
89
+ return auth;
90
+ }
91
+ catch (error) {
92
+ lastError = error instanceof Error ? error : new Error(String(error));
93
+ }
94
+ }
95
+ if (lastError)
96
+ throw lastError;
97
+ throw new Error(`Auth file not found at ${authPaths.join(" or ")}.`);
98
+ }
99
+ function decodeIdToken(auth) {
100
+ const idToken = auth.tokens?.id_token;
101
+ if (!idToken)
102
+ return {};
103
+ if (typeof idToken === "object")
104
+ return idToken;
105
+ const [, payload] = idToken.split(".");
106
+ if (!payload)
107
+ return { raw_jwt: idToken };
108
+ try {
109
+ const normalized = payload.replaceAll("-", "+").replaceAll("_", "/");
110
+ const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "=");
111
+ const claims = JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
112
+ const profile = claims["https://api.openai.com/profile"];
113
+ const authClaims = claims["https://api.openai.com/auth"];
114
+ return {
115
+ email: stringValue(claims.email) ?? stringValue(profile?.email),
116
+ chatgpt_plan_type: stringValue(authClaims?.chatgpt_plan_type),
117
+ chatgpt_user_id: stringValue(authClaims?.chatgpt_user_id) ??
118
+ stringValue(authClaims?.user_id),
119
+ chatgpt_account_id: stringValue(authClaims?.chatgpt_account_id),
120
+ chatgpt_account_is_fedramp: authClaims?.chatgpt_account_is_fedramp === true,
121
+ raw_jwt: idToken,
122
+ };
123
+ }
124
+ catch {
125
+ return { raw_jwt: idToken };
126
+ }
127
+ }
128
+ function stringValue(value) {
129
+ return typeof value === "string" && value.trim() ? value : undefined;
130
+ }
131
+ function planDisplay(plan) {
132
+ const raw = typeof plan === "string"
133
+ ? plan
134
+ : typeof plan === "object" && plan
135
+ ? stringValue(plan.value)
136
+ : undefined;
137
+ if (!raw)
138
+ return undefined;
139
+ return raw
140
+ .split(/[_-]/g)
141
+ .filter(Boolean)
142
+ .map((part) => part[0]?.toUpperCase() + part.slice(1))
143
+ .join(" ");
144
+ }
145
+ async function fetchJson(url, auth, idToken, timeoutMs = 10_000) {
146
+ const controller = new AbortController();
147
+ const timeoutId = timeoutMs > 0
148
+ ? setTimeout(() => controller.abort(new Error(`Request timed out after ${timeoutMs}ms`)), timeoutMs)
149
+ : undefined;
150
+ const headers = {
151
+ Authorization: `Bearer ${auth.tokens?.access_token ?? ""}`,
152
+ "User-Agent": "codex-usage-opencode-plugin",
153
+ };
154
+ const accountId = auth.tokens?.account_id ?? idToken.chatgpt_account_id;
155
+ if (accountId)
156
+ headers["ChatGPT-Account-ID"] = accountId;
157
+ if (idToken.chatgpt_account_is_fedramp)
158
+ headers["X-OpenAI-Fedramp"] = "true";
159
+ try {
160
+ const response = await fetch(url, { headers, signal: controller.signal });
161
+ if (!response.ok) {
162
+ const body = await response.text().catch(() => "");
163
+ const safeBody = body
164
+ .slice(0, 500)
165
+ .replace(/[A-Za-z0-9_-]{24,}\.[A-Za-z0-9_-]{24,}\.[A-Za-z0-9_-]{24,}/g, "<redacted-jwt>");
166
+ throw new Error(`${url} failed with HTTP ${response.status}${safeBody ? `: ${safeBody}` : ""}`);
167
+ }
168
+ return (await response.json());
169
+ }
170
+ finally {
171
+ if (timeoutId)
172
+ clearTimeout(timeoutId);
173
+ }
174
+ }
175
+ function renderUsage(auth, idToken, usage, profile) {
176
+ const lines = [];
177
+ const email = idToken.email;
178
+ const plan = planDisplay(idToken.chatgpt_plan_type) ?? planDisplay(usage.plan_type);
179
+ lines.push("# Codex Usage", "");
180
+ if (email || plan)
181
+ lines.push(`Account: ${[email, plan ? `(${plan})` : undefined].filter(Boolean).join(" ")}`);
182
+ lines.push(`Source: ${CHATGPT_USAGE_URL}`, "");
183
+ const limitLines = renderLimitRows(usage);
184
+ lines.push("## Limits");
185
+ lines.push(...(limitLines.length
186
+ ? limitLines
187
+ : ["No displayable limit data returned for this account."]));
188
+ const creditLines = renderCredits(usage);
189
+ if (creditLines.length)
190
+ lines.push("", "## Credits", ...creditLines);
191
+ const profileLines = renderProfile(profile);
192
+ if (profileLines.length)
193
+ lines.push("", "## Token Usage Profile", ...profileLines);
194
+ const accountId = auth.tokens?.account_id ?? idToken.chatgpt_account_id;
195
+ if (accountId)
196
+ lines.push("", `Workspace account: ${accountId}`);
197
+ return lines.join("\n");
198
+ }
199
+ function renderToastMessage(usage) {
200
+ const parts = [];
201
+ parts.push(...renderToastWindows(undefined, usage.rate_limit ?? undefined));
202
+ parts.push(...(usage.additional_rate_limits ?? []).flatMap((additional) => renderToastWindows(additional.limit_name ?? additional.metered_feature ?? "Additional", additional.rate_limit ?? undefined)));
203
+ parts.push(...renderCredits(usage).map((row) => row.replace(/^- /, "")));
204
+ const individual = usage.spend_control?.individual_limit;
205
+ if (individual) {
206
+ const remaining = clamp(numberValue(individual.remaining_percent), 0, 100);
207
+ parts.push(`Monthly credits: ${remaining.toFixed(0)}% left`);
208
+ }
209
+ return parts.length
210
+ ? parts.slice(0, 5).join(" | ")
211
+ : "No displayable limit data returned for this account.";
212
+ }
213
+ function renderLimitRows(usage) {
214
+ const rows = [];
215
+ rows.push(...renderWindowRows(undefined, usage.rate_limit ?? undefined));
216
+ for (const additional of usage.additional_rate_limits ?? []) {
217
+ const label = additional.limit_name ?? additional.metered_feature ?? "Additional";
218
+ rows.push(...renderWindowRows(label, additional.rate_limit ?? undefined));
219
+ }
220
+ const individual = usage.spend_control?.individual_limit;
221
+ if (individual) {
222
+ const remaining = clamp(numberValue(individual.remaining_percent), 0, 100);
223
+ const detail = formatCreditUsage(individual.used, individual.limit);
224
+ rows.push(`- Monthly credit limit: ${statusIndicator(remaining)} ${progress(remaining)} ${remaining.toFixed(0)}% left${resetSuffix(individual.reset_at)}${detail ? ` (${detail})` : ""}`);
225
+ }
226
+ return rows;
227
+ }
228
+ function renderWindowRows(prefix, details) {
229
+ const rows = [];
230
+ for (const entry of [
231
+ { window: details?.primary_window, secondary: false },
232
+ { window: details?.secondary_window, secondary: true },
233
+ ]) {
234
+ if (!entry.window)
235
+ continue;
236
+ const label = limitLabel(entry.window.limit_window_seconds, entry.secondary);
237
+ const fullLabel = prefix ? `${prefix} ${label}` : label;
238
+ const used = clamp(numberValue(entry.window.used_percent), 0, 100);
239
+ const remaining = 100 - used;
240
+ rows.push(`- ${fullLabel}: ${statusIndicator(remaining)} ${progress(remaining)} ${remaining.toFixed(0)}% left${resetSuffix(entry.window.reset_at)}`);
241
+ }
242
+ return rows;
243
+ }
244
+ function renderToastWindows(prefix, details) {
245
+ const rows = [];
246
+ for (const entry of [
247
+ { window: details?.primary_window, secondary: false },
248
+ { window: details?.secondary_window, secondary: true },
249
+ ]) {
250
+ if (!entry.window)
251
+ continue;
252
+ const label = limitLabel(entry.window.limit_window_seconds, entry.secondary).replace(/ limit$/i, "");
253
+ const fullLabel = prefix ? `${prefix} ${label}` : label;
254
+ const used = clamp(numberValue(entry.window.used_percent), 0, 100);
255
+ const remaining = 100 - used;
256
+ rows.push(`${fullLabel}: ${statusIndicator(remaining)} ${remaining.toFixed(0)}% left`);
257
+ }
258
+ return rows;
259
+ }
260
+ function renderCredits(usage) {
261
+ const credits = usage.credits;
262
+ if (!credits?.has_credits)
263
+ return [];
264
+ if (credits.unlimited)
265
+ return ["- Credits: Unlimited"];
266
+ const balance = Number.parseFloat(credits.balance ?? "");
267
+ if (!Number.isFinite(balance) || balance <= 0)
268
+ return [];
269
+ return [`- Credits: ${Math.round(balance).toLocaleString()} credits`];
270
+ }
271
+ function renderProfile(profile) {
272
+ const stats = profile?.stats;
273
+ if (!stats)
274
+ return [];
275
+ const rows = [];
276
+ pushStat(rows, "Lifetime tokens", stats.lifetime_tokens);
277
+ pushStat(rows, "Peak daily tokens", stats.peak_daily_tokens);
278
+ pushStat(rows, "Current streak", stats.current_streak_days, " days");
279
+ pushStat(rows, "Longest streak", stats.longest_streak_days, " days");
280
+ pushStat(rows, "Longest turn", stats.longest_running_turn_sec, " sec");
281
+ return rows;
282
+ }
283
+ function pushStat(rows, label, value, suffix = "") {
284
+ if (typeof value === "number" && Number.isFinite(value))
285
+ rows.push(`- ${label}: ${value.toLocaleString()}${suffix}`);
286
+ }
287
+ function limitLabel(seconds, secondary) {
288
+ const minutes = typeof seconds === "number" && seconds > 0
289
+ ? Math.ceil(seconds / 60)
290
+ : undefined;
291
+ if (minutes === 60 * 5)
292
+ return "5h limit";
293
+ if (minutes === 60 * 24 * 7)
294
+ return "Weekly limit";
295
+ if (minutes === 60 * 24 * 30 || minutes === 60 * 24 * 31)
296
+ return "Monthly limit";
297
+ if (minutes)
298
+ return `${formatDuration(minutes)} limit`;
299
+ return secondary ? "Secondary limit" : "Primary limit";
300
+ }
301
+ function formatDuration(minutes) {
302
+ if (minutes % (60 * 24 * 7) === 0)
303
+ return `${minutes / (60 * 24 * 7)}w`;
304
+ if (minutes % (60 * 24) === 0)
305
+ return `${minutes / (60 * 24)}d`;
306
+ if (minutes % 60 === 0)
307
+ return `${minutes / 60}h`;
308
+ return `${minutes}m`;
309
+ }
310
+ function resetSuffix(epochSeconds) {
311
+ if (typeof epochSeconds !== "number" ||
312
+ !Number.isFinite(epochSeconds) ||
313
+ epochSeconds <= 0)
314
+ return "";
315
+ return ` (resets ${new Date(epochSeconds * 1000).toLocaleString()})`;
316
+ }
317
+ function progress(remaining) {
318
+ const width = 20;
319
+ const filled = Math.min(width, Math.max(0, Math.round((remaining / 100) * width)));
320
+ return `[${"█".repeat(filled)}${"░".repeat(width - filled)}]`;
321
+ }
322
+ function statusIndicator(remaining) {
323
+ if (remaining < 20)
324
+ return "🔴";
325
+ if (remaining < 50)
326
+ return "🟡";
327
+ return "🟢";
328
+ }
329
+ function numberValue(value) {
330
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
331
+ }
332
+ function clamp(value, min, max) {
333
+ return Math.min(max, Math.max(min, value));
334
+ }
335
+ function formatCreditUsage(used, limit) {
336
+ const usedNumber = Number.parseFloat(used ?? "");
337
+ const limitNumber = Number.parseFloat(limit ?? "");
338
+ if (!Number.isFinite(usedNumber) || !Number.isFinite(limitNumber))
339
+ return undefined;
340
+ return `${Math.round(usedNumber).toLocaleString()} of ${Math.round(limitNumber).toLocaleString()} credits used`;
341
+ }
342
+ export async function getCodexUsage(options) {
343
+ const auth = await readAuth();
344
+ const idToken = decodeIdToken(auth);
345
+ const requestTimeoutMs = options?.requestTimeoutMs ?? 10_000;
346
+ const usage = await fetchJson(USAGE_URL, auth, idToken, requestTimeoutMs);
347
+ let profile;
348
+ try {
349
+ profile = await fetchJson(PROFILE_URL, auth, idToken, requestTimeoutMs);
350
+ }
351
+ catch {
352
+ profile = undefined;
353
+ }
354
+ return {
355
+ markdown: renderUsage(auth, idToken, usage, profile),
356
+ toast: renderToastMessage(usage),
357
+ };
358
+ }
359
+ //# sourceMappingURL=codex-usage-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-usage-core.js","sourceRoot":"","sources":["../src/codex-usage-core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ declare const _default: {
2
+ id: string;
3
+ server: ({ client }: import("@opencode-ai/plugin").PluginInput) => Promise<{
4
+ config: (config: import("@opencode-ai/plugin").Config) => Promise<void>;
5
+ "command.execute.before": (input: {
6
+ command: string;
7
+ sessionID: string;
8
+ arguments: string;
9
+ }) => Promise<void>;
10
+ tool: {
11
+ codex_usage: {
12
+ description: string;
13
+ args: {};
14
+ execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<import("@opencode-ai/plugin").ToolResult>;
15
+ };
16
+ };
17
+ }>;
18
+ };
19
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,64 @@
1
+ import { tool } from "@opencode-ai/plugin";
2
+ import { getCodexUsage } from "./codex-usage-core.js";
3
+ export default {
4
+ id: "codex-usage-server",
5
+ server: (async ({ client }) => {
6
+ async function showCodexUsageToast() {
7
+ await client.tui.showToast({
8
+ body: {
9
+ title: "Codex Usage",
10
+ message: "Fetching usage limits...",
11
+ variant: "info",
12
+ duration: 1_000,
13
+ },
14
+ });
15
+ const result = await getCodexUsage();
16
+ await client.tui.showToast({
17
+ body: {
18
+ title: "Codex Usage",
19
+ message: result.toast,
20
+ variant: "success",
21
+ duration: 10_000,
22
+ },
23
+ });
24
+ }
25
+ return {
26
+ config: async (config) => {
27
+ config.command ??= {};
28
+ config.command["codex-usage"] = {
29
+ description: "Show Codex usage limits and credits",
30
+ template: "",
31
+ };
32
+ },
33
+ "command.execute.before": async (input) => {
34
+ if (input.command !== "codex-usage" && input.command !== "/codex-usage")
35
+ return;
36
+ try {
37
+ await showCodexUsageToast();
38
+ }
39
+ catch (error) {
40
+ await client.tui.showToast({
41
+ body: {
42
+ title: "Codex Usage Failed",
43
+ message: error instanceof Error ? error.message : String(error),
44
+ variant: "error",
45
+ duration: 10_000,
46
+ },
47
+ });
48
+ throw error;
49
+ }
50
+ throw new Error("codex-usage:handled");
51
+ },
52
+ tool: {
53
+ codex_usage: tool({
54
+ description: "Show Codex ChatGPT usage limits, credits, and token profile from the local Codex CLI login.",
55
+ args: {},
56
+ async execute() {
57
+ return (await getCodexUsage()).markdown;
58
+ },
59
+ }),
60
+ },
61
+ };
62
+ }),
63
+ };
64
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,eAAe;IACb,EAAE,EAAE,oBAAoB;IACxB,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5B,KAAK,UAAU,mBAAmB;YAChC,MAAM,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;gBACzB,IAAI,EAAE;oBACJ,KAAK,EAAE,aAAa;oBACpB,OAAO,EAAE,0BAA0B;oBACnC,OAAO,EAAE,MAAM;oBACf,QAAQ,EAAE,KAAK;iBAChB;aACF,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;YACrC,MAAM,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;gBACzB,IAAI,EAAE;oBACJ,KAAK,EAAE,aAAa;oBACpB,OAAO,EAAE,MAAM,CAAC,KAAK;oBACrB,OAAO,EAAE,SAAS;oBAClB,QAAQ,EAAE,MAAM;iBACjB;aACF,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;gBACvB,MAAM,CAAC,OAAO,KAAK,EAAE,CAAC;gBACtB,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG;oBAC9B,WAAW,EAAE,qCAAqC;oBAClD,QAAQ,EAAE,EAAE;iBACb,CAAC;YACJ,CAAC;YACD,wBAAwB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACxC,IAAI,KAAK,CAAC,OAAO,KAAK,aAAa,IAAI,KAAK,CAAC,OAAO,KAAK,cAAc;oBACrE,OAAO;gBACT,IAAI,CAAC;oBACH,MAAM,mBAAmB,EAAE,CAAC;gBAC9B,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;wBACzB,IAAI,EAAE;4BACJ,KAAK,EAAE,oBAAoB;4BAC3B,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;4BAC/D,OAAO,EAAE,OAAO;4BAChB,QAAQ,EAAE,MAAM;yBACjB;qBACF,CAAC,CAAC;oBACH,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,EAAE;gBACJ,WAAW,EAAE,IAAI,CAAC;oBAChB,WAAW,EACT,6FAA6F;oBAC/F,IAAI,EAAE,EAAE;oBACR,KAAK,CAAC,OAAO;wBACX,OAAO,CAAC,MAAM,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC;oBAC1C,CAAC;iBACF,CAAC;aACH;SACF,CAAC;IACJ,CAAC,CAAkB;CACpB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@illiadotdev/codex-usage-plugin",
3
+ "version": "0.2.1",
4
+ "license": "MIT",
5
+ "description": "OpenCode plugin for viewing Codex ChatGPT usage limits and credits.",
6
+ "private": false,
7
+ "type": "module",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/iluhaar/codex-usage-plugin.git"
11
+ },
12
+ "homepage": "https://github.com/iluhaar/codex-usage-plugin#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/iluhaar/codex-usage-plugin/issues"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "files": [
20
+ "dist/",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "bin": {
25
+ "codex-usage-plugin": "dist/bin/codex-usage-plugin.js"
26
+ },
27
+ "keywords": [
28
+ "opencode",
29
+ "codex",
30
+ "plugin",
31
+ "quota",
32
+ "tui"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsc -p tsconfig.build.json",
36
+ "prepack": "npm run build",
37
+ "install-plugin": "npm run build && node dist/bin/codex-usage-plugin.js --install",
38
+ "uninstall-plugin": "node dist/bin/codex-usage-plugin.js --uninstall",
39
+ "lint": "oxlint .",
40
+ "typecheck": "tsc --noEmit",
41
+ "pretest": "npm run build",
42
+ "test": "node --test test/plugin.test.mjs"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^24.0.0",
46
+ "@opencode-ai/plugin": "latest",
47
+ "oxlint": "^1.0.0",
48
+ "typescript": "^5.9.3"
49
+ }
50
+ }