@slkiser/opencode-quota 4.10.4 → 4.10.6

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/README.md CHANGED
@@ -13,6 +13,7 @@
13
13
  <a href="https://www.npmjs.com/package/@slkiser/opencode-quota"><img alt="npm downloads" src="https://img.shields.io/npm/dm/%40slkiser%2Fopencode-quota?style=flat-square" /></a>
14
14
  <a href="https://github.com/slkiser/opencode-quota/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/slkiser/opencode-quota/ci.yml?style=flat-square&branch=main&label=CI" /></a>
15
15
  <a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square" /></a>
16
+ <a href="https://github.com/anomalyco/opencode/issues/38281"><img alt="Help us get listed: opencode#38281" src="https://img.shields.io/badge/%F0%9F%91%8D_help_us_get_listed-opencode%2338281-blue?style=flat-square" /></a>
16
17
  </p>
17
18
 
18
19
  [![OpenCode Quota sidebar](https://shawnkiser.com/opencode-quota/opencode-quota-sidebar.webp)](https://github.com/slkiser/opencode-quota)
@@ -58,12 +59,12 @@ OpenCode 1 users stay on 4.x: OpenCode Quota 5 needs OpenCode 2. The updater pin
58
59
 
59
60
  The updater prints the complete preview before its own config or cache changes. `--yes` authorizes only the previewed safe config edits and manifest-verified cache cleanup; it never moves or deletes secrets. See [Updating safely](docs/readme/updating.md) for detailed behavior and manual credential steps.
60
61
 
61
- **Breaking changes in 4.10.3:**
62
+ **Breaking changes since 4.10.3:**
62
63
 
63
64
  - Qwen Code was removed because Qwen ended its OAuth free tier; use Alibaba Coding Plan.
64
65
  - Google Antigravity was removed because its companion plugin is archived and Google rejects it; use Google AGY.
65
66
  - Personal Google accounts can no longer use Gemini CLI because Google ended them on 2026-06-18; use Google AGY.
66
- - OpenCode Zen now needs the new Console cookie in `consoleSessionCookie`; `authCookie` no longer works. See [OpenCode Zen setup](docs/readme/providers.md#opencode-zen).
67
+ - OpenCode Zen now uses your `opencode console login` session; the copied Console cookie file is no longer read. See [OpenCode Zen setup](docs/readme/providers.md#opencode-zen).
67
68
 
68
69
  ## Choose your setup
69
70
 
@@ -157,7 +158,7 @@ Run `npx @slkiser/opencode-quota@4 --help` for command options. See [External in
157
158
  | Ollama Cloud | Automatic | Remote API | Quota and usage |
158
159
  | OpenAI | Automatic | Remote API | Quota |
159
160
  | OpenCode Go | Automatic | Remote API | Quota |
160
- | OpenCode Zen | [Needs setup](docs/readme/providers.md#opencode-zen) | Dashboard API | Budget and balance |
161
+ | OpenCode Zen | [Needs setup](docs/readme/providers.md#opencode-zen) | Remote API | Budget and balance |
161
162
  | OpenRouter | Automatic | Remote API | Budget and spend |
162
163
  | Synthetic | Automatic | Remote API | Quota |
163
164
  | xAI SuperGrok | Automatic | Remote API | Quota |
@@ -177,7 +178,7 @@ Run `npx @slkiser/opencode-quota@4 --help` for command options. See [External in
177
178
  | Google AGY | [Needs setup](docs/readme/providers.md#google-agy-quick-setup) | Remote API | Quota |
178
179
  | NanoGPT | Automatic | Remote API | Quota and balance |
179
180
  | OpenAI | Automatic | Remote API | Quota |
180
- | OpenCode Zen | [Needs setup](docs/readme/providers.md#opencode-zen) | Dashboard API | Budget and balance |
181
+ | OpenCode Zen | [Needs setup](docs/readme/providers.md#opencode-zen) | Remote API | Budget and balance |
181
182
  | OpenRouter | Automatic | Remote API | Budget and spend |
182
183
  | Synthetic | Automatic | Remote API | Quota |
183
184
  | xAI SuperGrok | Automatic | Remote API | Quota |
@@ -17,7 +17,7 @@ const AGY_TOKEN_REFRESH_URL = "https://oauth2.googleapis.com/token";
17
17
  const AGY_TOKEN_TIMEOUT_MS = 8_000;
18
18
  const AGY_QUOTA_TIMEOUT_MS = 6_000;
19
19
  const AGY_ACCOUNTS_CONCURRENCY = 3;
20
- const AGY_USER_AGENT = "antigravity/cli/1.2.10 darwin/amd64";
20
+ const AGY_USER_AGENT = "antigravity/cli/1.2.11 darwin/amd64";
21
21
  function createAgyActivityRequestId() {
22
22
  return crypto.randomUUID();
23
23
  }
@@ -1,33 +1,33 @@
1
- export interface OpenCodeZenConfig {
2
- workspaceId: string;
3
- consoleSessionCookie: string;
1
+ export interface OpenCodeZenConsoleAccount {
2
+ /** Console base URL from the account row, e.g. https://opencode.ai/console */
3
+ baseUrl: string;
4
+ accessToken: string;
5
+ activeOrgId: string;
4
6
  }
5
- export type ResolvedOpenCodeZenConfig = {
7
+ export type ResolvedOpenCodeZenAccount = {
6
8
  state: "none";
7
9
  } | {
8
- state: "configured";
9
- config: OpenCodeZenConfig;
10
- source: string;
10
+ state: "expired";
11
+ expiryMs: number;
12
+ } | {
13
+ state: "no_active_account";
14
+ } | {
15
+ state: "missing_org";
16
+ } | {
17
+ state: "inactive_account";
11
18
  } | {
12
- state: "incomplete";
13
- source: string;
14
- missing: string;
19
+ state: "invalid_url";
15
20
  } | {
16
- state: "invalid";
17
- source: string;
18
- error: string;
21
+ state: "incompatible";
22
+ } | {
23
+ state: "read_error";
24
+ } | {
25
+ state: "configured";
26
+ account: OpenCodeZenConsoleAccount;
19
27
  };
20
- export interface OpenCodeZenConfigDiagnostics {
21
- state: ResolvedOpenCodeZenConfig["state"];
22
- source: string | null;
23
- missing: string | null;
24
- error: string | null;
25
- checkedPaths: string[];
26
- }
27
- export declare function resolveOpenCodeZenConfig(): Promise<ResolvedOpenCodeZenConfig>;
28
- export declare const DEFAULT_OPENCODE_ZEN_CONFIG_CACHE_MAX_AGE_MS = 30000;
29
- export declare function resolveOpenCodeZenConfigCached(params?: {
28
+ export declare function resolveOpenCodeZenAccount(): Promise<ResolvedOpenCodeZenAccount>;
29
+ export declare const DEFAULT_OPENCODE_ZEN_ACCOUNT_CACHE_MAX_AGE_MS = 30000;
30
+ export declare function resolveOpenCodeZenAccountCached(params?: {
30
31
  maxAgeMs?: number;
31
- }): Promise<ResolvedOpenCodeZenConfig>;
32
- export declare function getOpenCodeZenConfigDiagnostics(): Promise<OpenCodeZenConfigDiagnostics>;
32
+ }): Promise<ResolvedOpenCodeZenAccount>;
33
33
  //# sourceMappingURL=opencode-zen-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-zen-config.d.ts","sourceRoot":"","sources":["../../src/lib/opencode-zen-config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,yBAAyB,GACjC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClE;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAyCD,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAmCnF;AAKD,eAAO,MAAM,4CAA4C,QAAS,CAAC;AAEnE,wBAAsB,8BAA8B,CAAC,MAAM,CAAC,EAAE;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAUrC;AAED,wBAAsB,+BAA+B,IAAI,OAAO,CAAC,4BAA4B,CAAC,CAS7F"}
1
+ {"version":3,"file":"opencode-zen-config.d.ts","sourceRoot":"","sources":["../../src/lib/opencode-zen-config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,yBAAyB;IACxC,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,0BAA0B,GAClC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,KAAK,EAAE,mBAAmB,CAAA;CAAE,GAC9B;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,GACxB;IAAE,KAAK,EAAE,kBAAkB,CAAA;CAAE,GAC7B;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,GACxB;IAAE,KAAK,EAAE,cAAc,CAAA;CAAE,GACzB;IAAE,KAAK,EAAE,YAAY,CAAA;CAAE,GACvB;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,yBAAyB,CAAA;CAAE,CAAC;AA4JhE,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,0BAA0B,CAAC,CAErF;AAKD,eAAO,MAAM,6CAA6C,QAAS,CAAC;AAEpE,wBAAsB,+BAA+B,CAAC,MAAM,CAAC,EAAE;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAatC"}
@@ -1,87 +1,158 @@
1
- import { readFile } from "fs/promises";
2
- import { join } from "path";
3
- import { getOpencodeRuntimeDirCandidates } from "./opencode-runtime-paths.js";
4
- const LEGACY_AUTH_COOKIE_ERROR = "authCookie no longer works after the OpenCode Console redesign; paste the __Host-console_session cookie as consoleSessionCookie";
5
- function getConfigCandidatePaths() {
6
- const { configDirs } = getOpencodeRuntimeDirCandidates();
7
- return configDirs.map((dir) => join(dir, "opencode-quota", "opencode.json"));
1
+ import { statSync } from "node:fs";
2
+ import { openOpenCodeSqliteReadOnly } from "./opencode-sqlite.js";
3
+ import { getOpenCodeDbPath } from "./opencode-storage.js";
4
+ function asString(value) {
5
+ return typeof value === "string" && value.trim() ? value.trim() : null;
8
6
  }
9
- function getConfigFileError(error) {
10
- if (error instanceof SyntaxError) {
11
- return "Failed to parse JSON";
7
+ /** Checks a thrown error (e.g. from statSync) for a stable errno code. */
8
+ function hasErrnoCode(error, code) {
9
+ let current = error;
10
+ for (let depth = 0; current && depth < 5; depth += 1) {
11
+ if (current.code === code)
12
+ return true;
13
+ current = current.cause;
12
14
  }
13
- if (error instanceof Error && error.message) {
14
- return `Failed to read config file: ${error.message}`;
15
+ return false;
16
+ }
17
+ /**
18
+ * node:sqlite reports missing files as SQLITE_CANTOPEN (ERR_SQLITE_ERROR), the
19
+ * same errcode it uses for permission problems — so ask the filesystem for the
20
+ * real errno. statSync (unlike existsSync) distinguishes ENOENT from EACCES.
21
+ */
22
+ function isMissingStateDbFile(dbPath) {
23
+ try {
24
+ statSync(dbPath);
25
+ return false;
26
+ }
27
+ catch (statError) {
28
+ return hasErrnoCode(statError, "ENOENT");
15
29
  }
16
- return `Failed to read config file: ${String(error)}`;
17
30
  }
18
- async function readConfigFile(path) {
31
+ function normalizeBaseUrl(value) {
32
+ const raw = asString(value);
33
+ if (!raw)
34
+ return null;
35
+ let url;
19
36
  try {
20
- const data = await readFile(path, "utf8");
21
- const parsed = JSON.parse(data);
22
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
23
- return { state: "invalid", error: "Config file must contain a JSON object" };
24
- }
25
- return { state: "loaded", config: parsed };
37
+ url = new URL(raw);
26
38
  }
27
- catch (error) {
28
- if (error?.code === "ENOENT") {
29
- return { state: "missing" };
30
- }
31
- return { state: "invalid", error: getConfigFileError(error) };
39
+ catch {
40
+ return null;
32
41
  }
42
+ if (url.protocol !== "https:")
43
+ return null;
44
+ // Bare "?" / "#" leave search/hash empty but are not a valid Console base.
45
+ if (raw.includes("?") || raw.includes("#"))
46
+ return null;
47
+ if (url.username || url.password || url.search || url.hash)
48
+ return null;
49
+ return url.href.replace(/\/+$/, "");
33
50
  }
34
- export async function resolveOpenCodeZenConfig() {
35
- for (const path of getConfigCandidatePaths()) {
36
- const fileResult = await readConfigFile(path);
37
- if (fileResult.state === "missing")
38
- continue;
39
- if (fileResult.state === "invalid") {
40
- return { state: "invalid", source: path, error: fileResult.error };
51
+ /**
52
+ * Reads the active OpenCode Console CLI session (`opencode console login`)
53
+ * from OpenCode's local state database, strictly read-only. Tokens are never
54
+ * refreshed or written here.
55
+ */
56
+ async function readAccount() {
57
+ const safe = (resolved) => ({
58
+ resolved,
59
+ tokenExpiryMs: null,
60
+ });
61
+ const dbPath = getOpenCodeDbPath();
62
+ if (!dbPath)
63
+ return safe({ state: "none" });
64
+ let conn;
65
+ try {
66
+ conn = await openOpenCodeSqliteReadOnly(dbPath);
67
+ }
68
+ catch {
69
+ // Classify by the actual DB path, not the opener's error: node:sqlite
70
+ // surfaces missing files as SQLITE_CANTOPEN (ERR_SQLITE_ERROR) — the same
71
+ // errcode it uses for permission problems — and a wrapped unrelated ENOENT
72
+ // must never hide an existing DB. statSync distinguishes ENOENT (absent)
73
+ // from EACCES (unsearchable parent) without exception-text matching.
74
+ if (isMissingStateDbFile(dbPath))
75
+ return safe({ state: "none" });
76
+ return safe({ state: "read_error" });
77
+ }
78
+ try {
79
+ const tables = conn.all(`SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ('account', 'account_state')`);
80
+ const names = new Set(tables.map((row) => row?.name));
81
+ if (!names.has("account") || !names.has("account_state")) {
82
+ return safe({ state: "incompatible" });
41
83
  }
42
- const workspaceId = typeof fileResult.config.workspaceId === "string" ? fileResult.config.workspaceId.trim() : "";
43
- const consoleSessionCookie = typeof fileResult.config.consoleSessionCookie === "string"
44
- ? fileResult.config.consoleSessionCookie.trim()
45
- : "";
46
- if (!consoleSessionCookie && "authCookie" in fileResult.config) {
47
- return { state: "invalid", source: path, error: LEGACY_AUTH_COOKIE_ERROR };
84
+ // Column-level check: an older/newer schema that misses required columns is
85
+ // incompatible, while a failing read (lock, I/O) is a transient read_error.
86
+ const requiredColumns = {
87
+ account_state: new Set(["active_account_id", "active_org_id"]),
88
+ account: new Set(["id", "url", "access_token", "token_expiry"]),
89
+ };
90
+ for (const [table, required] of Object.entries(requiredColumns)) {
91
+ const columns = conn.all(`PRAGMA table_info(${table})`);
92
+ const columnNames = new Set(columns.map((row) => row?.name));
93
+ for (const column of required) {
94
+ if (!columnNames.has(column))
95
+ return safe({ state: "incompatible" });
96
+ }
48
97
  }
49
- if (workspaceId && consoleSessionCookie) {
50
- return {
51
- state: "configured",
52
- config: { workspaceId, consoleSessionCookie },
53
- source: path,
54
- };
98
+ const stateRow = conn.get(`SELECT active_account_id, active_org_id FROM "account_state" LIMIT 1`);
99
+ const activeAccountId = asString(stateRow?.active_account_id);
100
+ if (!activeAccountId)
101
+ return safe({ state: "no_active_account" });
102
+ const active = conn.get(`SELECT url, access_token, token_expiry FROM "account" WHERE id = ? LIMIT 1`, [activeAccountId]);
103
+ if (!active)
104
+ return safe({ state: "inactive_account" });
105
+ const activeOrgId = asString(stateRow?.active_org_id);
106
+ if (!activeOrgId)
107
+ return safe({ state: "missing_org" });
108
+ const accessToken = asString(active.access_token);
109
+ if (!accessToken)
110
+ return { resolved: { state: "expired", expiryMs: 0 }, tokenExpiryMs: 0 };
111
+ const expiryMs = typeof active.token_expiry === "number" && Number.isFinite(active.token_expiry)
112
+ ? active.token_expiry
113
+ : null;
114
+ if (expiryMs !== null && expiryMs <= Date.now()) {
115
+ // Propagate the already-passed expiry so the cache TTL collapses to 0 and
116
+ // the next read goes back to the DB (e.g. right after a fresh login).
117
+ return { resolved: { state: "expired", expiryMs }, tokenExpiryMs: expiryMs };
55
118
  }
119
+ const baseUrl = normalizeBaseUrl(active.url);
120
+ if (!baseUrl)
121
+ return safe({ state: "invalid_url" });
56
122
  return {
57
- state: "incomplete",
58
- source: path,
59
- missing: workspaceId ? "consoleSessionCookie" : "workspaceId",
123
+ resolved: {
124
+ state: "configured",
125
+ account: { baseUrl, accessToken, activeOrgId },
126
+ },
127
+ tokenExpiryMs: expiryMs,
60
128
  };
61
129
  }
62
- return { state: "none" };
63
- }
64
- let cachedConfig = null;
65
- let cachedAt = 0;
66
- export const DEFAULT_OPENCODE_ZEN_CONFIG_CACHE_MAX_AGE_MS = 30_000;
67
- export async function resolveOpenCodeZenConfigCached(params) {
68
- const maxAgeMs = Math.max(0, params?.maxAgeMs ?? DEFAULT_OPENCODE_ZEN_CONFIG_CACHE_MAX_AGE_MS);
69
- const now = Date.now();
70
- if (cachedConfig && now - cachedAt < maxAgeMs) {
71
- return cachedConfig;
130
+ catch {
131
+ // The schema is fine but the read failed (lock, disk I/O, ...): report a
132
+ // transient read error instead of throwing.
133
+ return safe({ state: "read_error" });
134
+ }
135
+ finally {
136
+ conn.close();
72
137
  }
73
- cachedConfig = await resolveOpenCodeZenConfig();
74
- cachedAt = now;
75
- return cachedConfig;
76
138
  }
77
- export async function getOpenCodeZenConfigDiagnostics() {
78
- const resolved = await resolveOpenCodeZenConfig();
79
- return {
80
- state: resolved.state,
81
- source: "source" in resolved ? resolved.source : null,
82
- missing: "missing" in resolved ? resolved.missing : null,
83
- error: "error" in resolved ? resolved.error : null,
84
- checkedPaths: getConfigCandidatePaths(),
85
- };
139
+ export async function resolveOpenCodeZenAccount() {
140
+ return (await readAccount()).resolved;
141
+ }
142
+ let cachedAccount = null;
143
+ let cachedExpiresAt = 0;
144
+ export const DEFAULT_OPENCODE_ZEN_ACCOUNT_CACHE_MAX_AGE_MS = 30_000;
145
+ export async function resolveOpenCodeZenAccountCached(params) {
146
+ const maxAgeMs = Math.max(0, params?.maxAgeMs ?? DEFAULT_OPENCODE_ZEN_ACCOUNT_CACHE_MAX_AGE_MS);
147
+ // A zero maxAgeMs explicitly bypasses an unexpired prior cache entry.
148
+ if (maxAgeMs > 0 && cachedAccount && Date.now() < cachedExpiresAt)
149
+ return cachedAccount;
150
+ const { resolved, tokenExpiryMs } = await readAccount();
151
+ // The cache must never outlive the token: cap the TTL at the token's expiry
152
+ // so an expired session triggers a fresh DB read (and a login prompt).
153
+ const ttl = tokenExpiryMs === null ? maxAgeMs : Math.min(maxAgeMs, Math.max(0, tokenExpiryMs - Date.now()));
154
+ cachedAccount = resolved;
155
+ cachedExpiresAt = Date.now() + ttl;
156
+ return resolved;
86
157
  }
87
158
  //# sourceMappingURL=opencode-zen-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-zen-config.js","sourceRoot":"","sources":["../../src/lib/opencode-zen-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"opencode-zen-config.js","sourceRoot":"","sources":["../../src/lib/opencode-zen-config.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { OpenCodeZenConsoleAccount } from "./opencode-zen-config.js";
1
2
  /**
2
3
  * The OpenCode Console reports amounts in micro-cents:
3
4
  * one US dollar is 100,000,000 micro-cents (billing units).
@@ -14,6 +15,8 @@ export interface OpenCodeZenBillingData {
14
15
  reload: boolean | null;
15
16
  reloadAmount: number | null;
16
17
  reloadTrigger: number | null;
18
+ /** Org-budget reset ISO timestamp; only set when budgets/org supplies the monthly budget. */
19
+ budgetResetIso: string | null;
17
20
  }
18
21
  /**
19
22
  * billing/status (balance) is required. The other routes are optional: when one fails,
@@ -27,7 +30,7 @@ export type OpenCodeZenResult = {
27
30
  success: false;
28
31
  error: string;
29
32
  };
30
- export declare function queryOpenCodeZenQuota(workspaceId: string, consoleSessionCookie: string, options?: {
33
+ export declare function queryOpenCodeZenQuota(account: OpenCodeZenConsoleAccount, options?: {
31
34
  requestTimeoutMs?: number;
32
35
  }): Promise<OpenCodeZenResult>;
33
36
  //# sourceMappingURL=opencode-zen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-zen.d.ts","sourceRoot":"","sources":["../../src/lib/opencode-zen.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,eAAO,MAAM,qCAAqC,YAAc,CAAC;AAEjE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,yFAAyF;IACzF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gFAAgF;IAChF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GACjE;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAoJtC,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,oBAAoB,EAAE,MAAM,EAC5B,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CAqC5B"}
1
+ {"version":3,"file":"opencode-zen.d.ts","sourceRoot":"","sources":["../../src/lib/opencode-zen.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAM1E;;;GAGG;AACH,eAAO,MAAM,qCAAqC,YAAc,CAAC;AAEjE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,yFAAyF;IACzF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gFAAgF;IAChF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,6FAA6F;IAC7F,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GACjE;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAyLtC,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,yBAAyB,EAClC,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CA4D5B"}
@@ -1,9 +1,7 @@
1
1
  import { sanitizeDisplayText } from "./display-sanitize.js";
2
2
  import { fetchWithTimeout } from "./http.js";
3
- const CONSOLE_API_URL = "https://opencode.ai/console/api";
4
- const USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Gecko/20100101 Firefox/148.0";
5
3
  const CONSOLE_TIMEOUT_MS = 10_000;
6
- const SESSION_ERROR = "OpenCode Console session expired or invalid — paste a fresh __Host-console_session cookie as consoleSessionCookie";
4
+ const SESSION_ERROR = "OpenCode Console session expired or invalid — run `opencode console login` to sign in again";
7
5
  /**
8
6
  * The OpenCode Console reports amounts in micro-cents:
9
7
  * one US dollar is 100,000,000 micro-cents (billing units).
@@ -75,6 +73,41 @@ function parseMonthlyUsage(json, now) {
75
73
  }
76
74
  return Number.isFinite(total) ? total : invalidResponse();
77
75
  }
76
+ /**
77
+ * Parses the org budget. The org has no budget configured when the Console returns
78
+ * `null`, an empty body, `{}`, or a null limit.
79
+ */
80
+ function parseOrgBudget(json) {
81
+ if (json === null)
82
+ return { limitMicroCents: null, spentMicroCents: null, resetsAt: null };
83
+ const budget = asRecord(json);
84
+ if (!budget)
85
+ return invalidResponse();
86
+ if (Object.keys(budget).length === 0) {
87
+ return { limitMicroCents: null, spentMicroCents: null, resetsAt: null };
88
+ }
89
+ const limitValue = budget.limitMicroCents;
90
+ if (limitValue === undefined)
91
+ return invalidResponse();
92
+ const limit = limitValue === null ? null : parseMicroCents(limitValue);
93
+ if (limitValue !== null && limit === null)
94
+ return invalidResponse();
95
+ const spentValue = budget.spentMicroCents;
96
+ if (spentValue === undefined)
97
+ return invalidResponse();
98
+ const spent = spentValue === null ? null : parseMicroCents(spentValue);
99
+ if (spentValue !== null && spent === null)
100
+ return invalidResponse();
101
+ const resetsAt = budget.resetsAt;
102
+ if (resetsAt !== null && resetsAt !== undefined && typeof resetsAt !== "string") {
103
+ return invalidResponse();
104
+ }
105
+ return {
106
+ limitMicroCents: limit,
107
+ spentMicroCents: spent,
108
+ resetsAt: typeof resetsAt === "string" ? resetsAt : null,
109
+ };
110
+ }
78
111
  function sanitizeMessage(text, secrets = [], maxLength = 120) {
79
112
  let sanitized = sanitizeDisplayText(text).replace(/\s+/g, " ").trim();
80
113
  for (const secret of secrets) {
@@ -85,22 +118,21 @@ function sanitizeMessage(text, secrets = [], maxLength = 120) {
85
118
  }
86
119
  async function fetchConsoleRoute(params) {
87
120
  try {
88
- return await fetchWithTimeout(`${CONSOLE_API_URL}/${params.route}`, {
121
+ return await fetchWithTimeout(`${params.account.baseUrl}/api/${params.route}`, {
89
122
  request: {
90
123
  method: "GET",
91
124
  redirect: "manual",
92
125
  headers: {
93
- "User-Agent": USER_AGENT,
94
126
  Accept: "application/json",
95
- Cookie: `__Host-console_session=${params.consoleSessionCookie}`,
96
- "x-org-id": params.workspaceId,
127
+ Authorization: `Bearer ${params.account.accessToken}`,
128
+ "x-org-id": params.account.activeOrgId,
97
129
  },
98
130
  },
99
131
  timeoutMs: params.timeoutMs,
100
132
  consume: async (response) => {
101
- if ((response.status >= 300 && response.status < 400) ||
102
- response.status === 401 ||
103
- response.status === 403) {
133
+ // Redirects and 401 mean the whole session is gone; a 403 is treated as
134
+ // a per-route failure so optional routes can fall back gracefully.
135
+ if ((response.status >= 300 && response.status < 400) || response.status === 401) {
104
136
  return { success: false, error: SESSION_ERROR };
105
137
  }
106
138
  if (!response.ok) {
@@ -114,7 +146,9 @@ async function fetchConsoleRoute(params) {
114
146
  }
115
147
  const text = await response.text();
116
148
  try {
117
- return { success: true, data: params.parse(JSON.parse(text)) };
149
+ // An empty body carries no value, so the route parser sees it as JSON null.
150
+ const json = text.trim() === "" ? null : JSON.parse(text);
151
+ return { success: true, data: params.parse(json) };
118
152
  }
119
153
  catch {
120
154
  return {
@@ -127,45 +161,65 @@ async function fetchConsoleRoute(params) {
127
161
  }
128
162
  catch (error) {
129
163
  const message = sanitizeMessage(error instanceof Error ? error.message : String(error), [
130
- params.consoleSessionCookie,
131
- params.workspaceId,
164
+ params.account.accessToken,
165
+ params.account.activeOrgId,
132
166
  ]);
133
167
  return { success: false, error: `OpenCode Console ${params.route} request failed: ${message}` };
134
168
  }
135
169
  }
136
- export async function queryOpenCodeZenQuota(workspaceId, consoleSessionCookie, options = {}) {
170
+ export async function queryOpenCodeZenQuota(account, options = {}) {
137
171
  const request = {
138
- workspaceId,
139
- consoleSessionCookie,
172
+ account,
140
173
  timeoutMs: options.requestTimeoutMs ?? CONSOLE_TIMEOUT_MS,
141
174
  };
142
175
  const now = new Date();
143
- const [balance, creditLimit, autoRecharge, monthlyUsage] = await Promise.all([
176
+ const [balance, creditLimit, autoRecharge, orgBudget, monthlyUsage] = await Promise.all([
144
177
  fetchConsoleRoute({ ...request, route: "billing/status", parse: parseBalance }),
145
178
  fetchConsoleRoute({ ...request, route: "billing/account", parse: parseCreditLimit }),
146
179
  fetchConsoleRoute({ ...request, route: "billing/auto-recharge", parse: parseAutoRecharge }),
180
+ fetchConsoleRoute({ ...request, route: "budgets/org", parse: parseOrgBudget }),
147
181
  fetchConsoleRoute({
148
182
  ...request,
149
183
  route: "usage/cost-by-day",
150
184
  parse: (json) => parseMonthlyUsage(json, now),
151
185
  }),
152
186
  ]);
153
- const optional = [creditLimit, autoRecharge, monthlyUsage];
187
+ const optional = [creditLimit, autoRecharge, orgBudget, monthlyUsage];
154
188
  if ([balance, ...optional].some((result) => !result.success && result.error === SESSION_ERROR)) {
155
189
  return { success: false, error: SESSION_ERROR };
156
190
  }
157
191
  if (!balance.success)
158
192
  return balance;
193
+ // Prefer the org budget when it supplies a positive limit and usable spend;
194
+ // otherwise fall back to the credit limit plus this month's usage costs.
195
+ let monthlyLimit = creditLimit.success ? creditLimit.data : null;
196
+ let usage = monthlyUsage.success ? monthlyUsage.data : null;
197
+ let budgetResetIso = null;
198
+ if (orgBudget.success) {
199
+ const { limitMicroCents, spentMicroCents, resetsAt } = orgBudget.data;
200
+ if (limitMicroCents !== null &&
201
+ limitMicroCents > 0 &&
202
+ spentMicroCents !== null &&
203
+ spentMicroCents >= 0) {
204
+ monthlyLimit = limitMicroCents / OPENCODE_ZEN_BILLING_UNITS_PER_DOLLAR;
205
+ usage = spentMicroCents;
206
+ // Normalize to canonical ISO so downstream result validation never sees a
207
+ // parseable-but-non-ISO reset (e.g. "0") and drops the whole result.
208
+ const resetTimeMs = resetsAt === null ? Number.NaN : Date.parse(resetsAt);
209
+ budgetResetIso = Number.isFinite(resetTimeMs) ? new Date(resetTimeMs).toISOString() : null;
210
+ }
211
+ }
159
212
  return {
160
213
  success: true,
161
214
  data: {
162
215
  balance: balance.data,
163
- monthlyLimit: creditLimit.success ? creditLimit.data : null,
164
- monthlyUsage: monthlyUsage.success ? monthlyUsage.data : null,
216
+ monthlyLimit,
217
+ monthlyUsage: usage,
165
218
  lastPayment: null,
166
219
  ...(autoRecharge.success
167
220
  ? autoRecharge.data
168
221
  : { reload: null, reloadAmount: null, reloadTrigger: null }),
222
+ budgetResetIso,
169
223
  },
170
224
  errors: optional.flatMap((result) => (result.success ? [] : [result.error])),
171
225
  };
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-zen.js","sourceRoot":"","sources":["../../src/lib/opencode-zen.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"opencode-zen.js","sourceRoot":"","sources":["../../src/lib/opencode-zen.ts"],"names":[],"mappings":"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"}