@arandevcode/opencode-quota-extended 0.2.3 → 0.2.4
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-es.md +19 -13
- package/README.md +18 -12
- package/bin/quota.mjs +8 -1
- package/dist/lib/balance.d.ts +3 -1
- package/dist/lib/balance.d.ts.map +1 -1
- package/dist/lib/balance.js +22 -0
- package/dist/lib/balance.js.map +1 -1
- package/dist/lib/opencode-go-config.d.ts +6 -1
- package/dist/lib/opencode-go-config.d.ts.map +1 -1
- package/dist/lib/opencode-go-config.js +29 -3
- package/dist/lib/opencode-go-config.js.map +1 -1
- package/dist/lib/types.d.ts +4 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/providers/opencode-go.d.ts +6 -5
- package/dist/providers/opencode-go.d.ts.map +1 -1
- package/dist/providers/opencode-go.js +17 -7
- package/dist/providers/opencode-go.js.map +1 -1
- package/dist/ui/SidebarPanel.d.ts.map +1 -1
- package/dist/ui/SidebarPanel.tsx +2 -21
- package/dist/ui/cards.d.ts.map +1 -1
- package/dist/ui/cards.tsx +14 -6
- package/images/opencode_quota_extended_cli.png +0 -0
- package/images/opencode_quota_extended_sidebar.png +0 -0
- package/package.json +1 -1
- package/scripts/setup.mjs +30 -22
package/README-es.md
CHANGED
|
@@ -121,7 +121,7 @@ Registra un plugin TUI que renderiza un panel `sidebar_content` en la posición
|
|
|
121
121
|
|---|---|---|
|
|
122
122
|
| **OpenAI** | 5h móvil, Semanal, Code Review | `auth.json` → entrada `openai` / `chatgpt` |
|
|
123
123
|
| **GitHub Copilot** | Solicitudes Premium (ventana única) | `auth.json` → entrada `github-copilot` |
|
|
124
|
-
| **OpenCode Go** | 5h, Semanal, Mensual |
|
|
124
|
+
| **OpenCode Go** | 5h, Semanal, Mensual + gasto | API key personal (o cookie de sesión legacy) |
|
|
125
125
|
|
|
126
126
|
Colores de semáforo: ≥50% `theme.success` (verde), 25-49% `theme.warning` (naranja), <25% `theme.error` (rojo).
|
|
127
127
|
|
|
@@ -129,38 +129,43 @@ Colores de semáforo: ≥50% `theme.success` (verde), 25-49% `theme.warning` (na
|
|
|
129
129
|
|
|
130
130
|
Lee credenciales del archivo de autenticación de OpenCode (`~/.local/share/opencode/auth.json`). **No** almacena, solicita ni distribuye secretos.
|
|
131
131
|
|
|
132
|
-
**OpenCode Go**
|
|
132
|
+
**OpenCode Go** usa una API key personal. El plugin llama al mismo endpoint del console que el dashboard y lee las tres ventanas de cuota, el gasto en dólares por ventana y el balance de crédito prepago.
|
|
133
133
|
|
|
134
134
|
Crea `~/.config/opencode/opencode-quota/opencode-go.json`:
|
|
135
135
|
|
|
136
136
|
```json
|
|
137
137
|
{
|
|
138
|
-
"
|
|
139
|
-
"authCookie": "st_..."
|
|
138
|
+
"apiKey": "oc_sk_..."
|
|
140
139
|
}
|
|
141
140
|
```
|
|
142
141
|
|
|
143
142
|
| Campo | Descripción | Cómo obtenerlo |
|
|
144
143
|
|---|---|---|
|
|
145
|
-
| `
|
|
146
|
-
| `authCookie` | Cookie de sesión del console | Abre DevTools (F12) → Application → Cookies → `https://opencode.ai` → busca `__Host-console_session` (el valor empieza por `st_...`). Es `HttpOnly`, así que solo se puede leer desde DevTools (no con `document.cookie`). |
|
|
144
|
+
| `apiKey` | API key personal de OpenCode | Abre [opencode.ai/console](https://opencode.ai/console) → **Personal API keys** → crea una key con permisos **All**. Copia el valor `oc_sk_...`. No uses una service account: no puede leer billing. |
|
|
147
145
|
|
|
148
|
-
|
|
146
|
+
La key se guarda con permisos `600` y solo se envía a `opencode.ai`. Una key **All** muestra cuota, gasto y balance. Una key `read` no sirve para este plugin: no puede llamar a `go/status`.
|
|
147
|
+
|
|
148
|
+
**Múltiples workspaces/cuentas:** cualquier archivo `opencode-go-<sufijo>.json` en el mismo directorio añade una sección extra `Opencode GO (<sufijo>)` (p. ej. `opencode-go-work.json` → **Opencode GO (work)**). El `opencode-go.json` base siempre se muestra como **OpenCode Go**. Los archivos `opencode-go-<sufijo>-key.json` que mantiene el switch de cuentas los ignora el plugin de cuota.
|
|
149
149
|
|
|
150
150
|
```sh
|
|
151
|
-
# p. ej.
|
|
151
|
+
# p. ej. una segunda cuenta
|
|
152
152
|
cp ~/.config/opencode/opencode-quota/opencode-go.json \
|
|
153
153
|
~/.config/opencode/opencode-quota/opencode-go-work.json
|
|
154
|
-
# luego
|
|
154
|
+
# luego sustituye apiKey dentro de opencode-go-work.json
|
|
155
155
|
```
|
|
156
156
|
|
|
157
157
|
**Setup automatizado** (recomendado):
|
|
158
158
|
```sh
|
|
159
|
-
npm run setup
|
|
159
|
+
npm run setup # cuenta base -> opencode-go.json
|
|
160
|
+
npm run setup work # cuenta extra -> opencode-go-work.json
|
|
160
161
|
```
|
|
161
|
-
Te solicita
|
|
162
|
+
Te solicita la API key, escribe el archivo con permisos `600` e indica dónde crearla.
|
|
163
|
+
|
|
164
|
+
También puedes usar `OPENCODE_GO_API_KEY` en vez de un archivo.
|
|
165
|
+
|
|
166
|
+
**Legacy:** `{ "workspaceId": "wrk_...", "authCookie": "st_..." }` sigue aceptándose por compatibilidad, pero la cookie de sesión del navegador caduca. Mejor usa la API key.
|
|
162
167
|
|
|
163
|
-
**
|
|
168
|
+
**Migrar una cuenta existente:** si ya tienes `opencode-go-<Cuenta>.json`, sustituye todo su contenido por `{ "apiKey": "oc_sk_..." }`. No hacen falta `workspaceId` ni `authCookie`. `npm run setup <Cuenta>` respeta mayúsculas: el sufijo debe coincidir exactamente con el nombre del archivo.
|
|
164
169
|
|
|
165
170
|
### Relación con [`@slkiser/opencode-quota`](https://github.com/slkiser/opencode-quota)
|
|
166
171
|
|
|
@@ -169,7 +174,8 @@ Te solicita ambos valores y crea el archivo automáticamente. También muestra i
|
|
|
169
174
|
### Solución de problemas
|
|
170
175
|
|
|
171
176
|
- **El panel no aparece**: `grep '@arandevcode/opencode-quota-extended' ~/.local/share/opencode/log/*.log`
|
|
172
|
-
- **OpenCode Go muestra "skipped"**: confirma que el archivo sidecar o
|
|
177
|
+
- **OpenCode Go muestra "skipped"**: confirma que el archivo sidecar o `OPENCODE_GO_API_KEY` está configurado
|
|
178
|
+
- **OpenCode Go muestra 401/403**: la key no es válida, ha caducado o le faltan permisos; crea una key personal **All** (las service account no pueden leer billing)
|
|
173
179
|
- **Bug antiguo de pinning `@opentui/solid`**: usa `^0.4.1 || ^0.5.0` y reinstala limpio (`rm -rf node_modules && npm ci`)
|
|
174
180
|
|
|
175
181
|
### Desarrollo
|
package/README.md
CHANGED
|
@@ -122,7 +122,7 @@ Registers a TUI plugin that renders a `sidebar_content` panel at order 145, show
|
|
|
122
122
|
|---|---|---|
|
|
123
123
|
| **OpenAI** | 5h rolling, Weekly, Code Review | `auth.json` → `openai` / `chatgpt` entry |
|
|
124
124
|
| **GitHub Copilot** | Premium requests (single window) | `auth.json` → `github-copilot` entry |
|
|
125
|
-
| **OpenCode Go** | 5h, Weekly, Monthly |
|
|
125
|
+
| **OpenCode Go** | 5h, Weekly, Monthly + spend | Personal API key (or legacy session cookie) |
|
|
126
126
|
|
|
127
127
|
Traffic-light colors: ≥50% `theme.success` (green), 25-49% `theme.warning` (orange), <25% `theme.error` (red).
|
|
128
128
|
|
|
@@ -130,38 +130,43 @@ Traffic-light colors: ≥50% `theme.success` (green), 25-49% `theme.warning` (or
|
|
|
130
130
|
|
|
131
131
|
Reads credentials from OpenCode's runtime auth file (`~/.local/share/opencode/auth.json`). Does **not** store, prompt for, or distribute secrets.
|
|
132
132
|
|
|
133
|
-
**OpenCode Go**
|
|
133
|
+
**OpenCode Go** uses a personal API key. The plugin calls the same console endpoint as the dashboard and reads the three quota windows, the dollar spend per window, and the prepaid credit balance.
|
|
134
134
|
|
|
135
135
|
Create `~/.config/opencode/opencode-quota/opencode-go.json`:
|
|
136
136
|
|
|
137
137
|
```json
|
|
138
138
|
{
|
|
139
|
-
"
|
|
140
|
-
"authCookie": "st_..."
|
|
139
|
+
"apiKey": "oc_sk_..."
|
|
141
140
|
}
|
|
142
141
|
```
|
|
143
142
|
|
|
144
143
|
| Field | Description | How to get it |
|
|
145
144
|
|---|---|---|
|
|
146
|
-
| `
|
|
147
|
-
| `authCookie` | Console session cookie | Open DevTools (F12) → Application → Cookies → `https://opencode.ai` → find `__Host-console_session` (value starts with `st_...`). It is `HttpOnly`, so it can only be read from DevTools (not `document.cookie`). |
|
|
145
|
+
| `apiKey` | Personal OpenCode API key | Open [opencode.ai/console](https://opencode.ai/console) → **Personal API keys** → create a key with **All** permissions. Copy the `oc_sk_...` value. Do not use a service-account key: service accounts cannot read billing. |
|
|
148
146
|
|
|
149
|
-
|
|
147
|
+
The key is stored with mode `600` and is only sent to `opencode.ai`. An **All** key shows quota, dollar spend and credit balance. A `read` key is not enough for this plugin: it cannot call `go/status`.
|
|
148
|
+
|
|
149
|
+
**Multiple workspaces/accounts:** any `opencode-go-<suffix>.json` file in the same directory adds an extra `Opencode GO (<suffix>)` section (e.g. `opencode-go-work.json` → **Opencode GO (work)**). The base `opencode-go.json` always renders as **OpenCode Go**. The `opencode-go-<suffix>-key.json` files maintained by the account switcher are ignored by the quota plugin.
|
|
150
150
|
|
|
151
151
|
```sh
|
|
152
152
|
# e.g. a second workspace
|
|
153
153
|
cp ~/.config/opencode/opencode-quota/opencode-go.json \
|
|
154
154
|
~/.config/opencode/opencode-quota/opencode-go-work.json
|
|
155
|
-
# then
|
|
155
|
+
# then replace apiKey inside opencode-go-work.json
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
**Automated setup** (recommended):
|
|
159
159
|
```sh
|
|
160
|
-
npm run setup
|
|
160
|
+
npm run setup # base account -> opencode-go.json
|
|
161
|
+
npm run setup work # extra account -> opencode-go-work.json
|
|
161
162
|
```
|
|
162
|
-
This prompts for
|
|
163
|
+
This prompts for the API key, writes the file with mode `600`, and prints where to create the key.
|
|
164
|
+
|
|
165
|
+
You can also use `OPENCODE_GO_API_KEY` instead of a file.
|
|
166
|
+
|
|
167
|
+
**Legacy:** `{ "workspaceId": "wrk_...", "authCookie": "st_..." }` is still accepted for backwards compatibility, but the browser session cookie expires. Prefer the API key.
|
|
163
168
|
|
|
164
|
-
**
|
|
169
|
+
**Migrating an existing account:** if you already have `opencode-go-<Account>.json`, replace its entire contents with `{ "apiKey": "oc_sk_..." }`. No `workspaceId` or `authCookie` needed. `npm run setup <Account>` is case-sensitive: the suffix must match the filename exactly.
|
|
165
170
|
|
|
166
171
|
### Relationship with [`@slkiser/opencode-quota`](https://github.com/slkiser/opencode-quota)
|
|
167
172
|
|
|
@@ -170,7 +175,8 @@ This prompts for both values and creates the file for you. It also prints step-b
|
|
|
170
175
|
### Troubleshooting
|
|
171
176
|
|
|
172
177
|
- **Panel doesn't appear**: `grep '@arandevcode/opencode-quota-extended' ~/.local/share/opencode/log/*.log`
|
|
173
|
-
- **OpenCode Go shows "skipped"**: confirm sidecar file or
|
|
178
|
+
- **OpenCode Go shows "skipped"**: confirm the sidecar file or `OPENCODE_GO_API_KEY` is set
|
|
179
|
+
- **OpenCode Go shows 401/403**: the key is invalid, expired or lacks permissions; create a personal **All** key (service-account keys cannot read billing)
|
|
174
180
|
- **Old `@opentui/solid` pinning bug**: use `^0.4.1 || ^0.5.0` and clean-install (`rm -rf node_modules && npm ci`)
|
|
175
181
|
|
|
176
182
|
### Development
|
package/bin/quota.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { loadCardsConfig } from "../dist/config/loader.js";
|
|
|
6
6
|
import { collectSnapshot } from "../dist/providers/registry.js";
|
|
7
7
|
import { renderProgressBar, trafficLight } from "../dist/ui/progress-bar.js";
|
|
8
8
|
import { formatResetCombined } from "../dist/lib/reset-format.js";
|
|
9
|
+
import { formatBalance, formatWindowSpend } from "../dist/lib/balance.js";
|
|
9
10
|
|
|
10
11
|
const INDENT = 4;
|
|
11
12
|
|
|
@@ -13,6 +14,7 @@ const COLORS = {
|
|
|
13
14
|
ok: "\x1b[32m",
|
|
14
15
|
warning: "\x1b[33m",
|
|
15
16
|
error: "\x1b[31m",
|
|
17
|
+
accent: "\x1b[36m",
|
|
16
18
|
};
|
|
17
19
|
const RESET = "\x1b[0m";
|
|
18
20
|
const BOLD = "\x1b[1m";
|
|
@@ -74,7 +76,10 @@ async function main() {
|
|
|
74
76
|
continue;
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
|
|
79
|
+
const credit = formatBalance(provider.balance);
|
|
80
|
+
console.log(
|
|
81
|
+
` ${BOLD}${provider.label}${RESET}${credit ? ` ${COLORS.accent}${credit}${RESET}` : ""}`,
|
|
82
|
+
);
|
|
78
83
|
|
|
79
84
|
for (const [i, win] of provider.windows.entries()) {
|
|
80
85
|
if (i > 0) console.log();
|
|
@@ -91,6 +96,8 @@ async function main() {
|
|
|
91
96
|
const leftStr = `${color}${pct}% left${RESET}`;
|
|
92
97
|
const rightStr = `${DIM}${usedPct(pct)}${RESET}`;
|
|
93
98
|
console.log(" ".repeat(INDENT) + padRight(leftStr, rightStr));
|
|
99
|
+
const spend = formatWindowSpend(win);
|
|
100
|
+
if (spend) console.log(" ".repeat(INDENT) + DIM + spend + RESET);
|
|
94
101
|
}
|
|
95
102
|
console.log();
|
|
96
103
|
}
|
package/dist/lib/balance.d.ts
CHANGED
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
* dollar amount and the auto-recharge flag are ever rendered — never the raw
|
|
7
7
|
* microcents, and never anything that came from the account credentials.
|
|
8
8
|
*/
|
|
9
|
-
import type { ProviderBalance } from "./types.js";
|
|
9
|
+
import type { ProviderBalance, QuotaWindow } from "./types.js";
|
|
10
10
|
/** Available credit in dollars (2 decimals), or null when unreadable. */
|
|
11
11
|
export declare function balanceUsd(balance: ProviderBalance | undefined): number | null;
|
|
12
12
|
/** "$9.18 credit", plus a note when credits are drawn or auto-recharge is on. */
|
|
13
13
|
export declare function formatBalance(balance: ProviderBalance | undefined): string;
|
|
14
|
+
/** "$2.64 / $30.00" for a window that exposes both money fields. */
|
|
15
|
+
export declare function formatWindowSpend(window: QuotaWindow): string;
|
|
14
16
|
//# sourceMappingURL=balance.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../src/lib/balance.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../src/lib/balance.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAM9E;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,CAO1E;AAcD,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAK7D"}
|
package/dist/lib/balance.js
CHANGED
|
@@ -20,4 +20,26 @@ export function formatBalance(balance) {
|
|
|
20
20
|
parts.push("auto-recharge");
|
|
21
21
|
return parts.join(" · ");
|
|
22
22
|
}
|
|
23
|
+
/** Dollars from a microcents decimal string, using cents precision. */
|
|
24
|
+
function microCentsUsd(raw) {
|
|
25
|
+
if (typeof raw !== "string" || raw.trim() === "")
|
|
26
|
+
return null;
|
|
27
|
+
try {
|
|
28
|
+
const micro = BigInt(raw.trim());
|
|
29
|
+
if (micro < 0n)
|
|
30
|
+
return null;
|
|
31
|
+
return Number((micro + 500000n) / 1000000n) / 100;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** "$2.64 / $30.00" for a window that exposes both money fields. */
|
|
38
|
+
export function formatWindowSpend(window) {
|
|
39
|
+
const spent = microCentsUsd(window.spentMicroCents);
|
|
40
|
+
const limit = microCentsUsd(window.limitMicroCents);
|
|
41
|
+
if (spent === null || limit === null || limit <= 0)
|
|
42
|
+
return "";
|
|
43
|
+
return `$${spent.toFixed(2)} / $${limit.toFixed(2)}`;
|
|
44
|
+
}
|
|
23
45
|
//# sourceMappingURL=balance.js.map
|
package/dist/lib/balance.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/lib/balance.ts"],"names":[],"mappings":"AAUA,yEAAyE;AACzE,MAAM,UAAU,UAAU,CAAC,OAAoC;IAC7D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,mBAAmB,CAAC;IACxC,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACjE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACvC,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,aAAa,CAAC,OAAoC;IAChE,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,UAAU,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,YAAY,EAAE,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC"}
|
|
1
|
+
{"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/lib/balance.ts"],"names":[],"mappings":"AAUA,yEAAyE;AACzE,MAAM,UAAU,UAAU,CAAC,OAAoC;IAC7D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,mBAAmB,CAAC;IACxC,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACjE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACvC,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,aAAa,CAAC,OAAoC;IAChE,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,UAAU,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,YAAY,EAAE,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,uEAAuE;AACvE,SAAS,aAAa,CAAC,GAAuB;IAC5C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACjC,IAAI,KAAK,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QAC5B,OAAO,MAAM,CAAC,CAAC,KAAK,GAAG,OAAQ,CAAC,GAAG,QAAU,CAAC,GAAG,GAAG,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACpD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9D,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;AACvD,CAAC"}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
export type OpenCodeGoConfig = {
|
|
2
|
+
auth: "api-key";
|
|
3
|
+
apiKey: string;
|
|
4
|
+
} | {
|
|
5
|
+
auth: "cookie";
|
|
2
6
|
workspaceId: string;
|
|
3
7
|
authCookie: string;
|
|
4
8
|
};
|
|
9
|
+
export type OpenCodeGoMissingField = "apiKey" | "workspaceId" | "authCookie";
|
|
5
10
|
export type OpenCodeGoConfigResolution = {
|
|
6
11
|
state: "configured";
|
|
7
12
|
config: OpenCodeGoConfig;
|
|
@@ -9,7 +14,7 @@ export type OpenCodeGoConfigResolution = {
|
|
|
9
14
|
} | {
|
|
10
15
|
state: "incomplete";
|
|
11
16
|
source: string;
|
|
12
|
-
missing:
|
|
17
|
+
missing: OpenCodeGoMissingField;
|
|
13
18
|
} | {
|
|
14
19
|
state: "invalid";
|
|
15
20
|
source: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode-go-config.d.ts","sourceRoot":"","sources":["../../src/lib/opencode-go-config.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"opencode-go-config.d.ts","sourceRoot":"","sources":["../../src/lib/opencode-go-config.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC;AAE7E,MAAM,MAAM,0BAA0B,GAClC;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,sBAAsB,CAAA;CAAE,GACxE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtB,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;CACf;AA2HD,gFAAgF;AAChF,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,0BAA0B,CAAC,CAInF;AAED,qDAAqD;AACrD,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,0BAA0B,CAAC,CAErC;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CA0BjF;AAKD,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,0BAA0B,CAAC,CAMzF;AAOD,wBAAsB,+BAA+B,CACnD,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,0BAA0B,CAAC,CAOrC;AAED,uEAAuE;AACvE,wBAAgB,0BAA0B,IAAI,IAAI,CAGjD"}
|
|
@@ -37,12 +37,20 @@ function getInstanceCandidatePaths(id) {
|
|
|
37
37
|
return getSidecarDirCandidates().map((d) => join(d, `${EXTRA_PREFIX}${suffix}.json`));
|
|
38
38
|
}
|
|
39
39
|
function fromEnv() {
|
|
40
|
+
const apiKey = process.env.OPENCODE_GO_API_KEY?.trim();
|
|
41
|
+
if (apiKey) {
|
|
42
|
+
return { state: "configured", config: { auth: "api-key", apiKey }, source: "env" };
|
|
43
|
+
}
|
|
40
44
|
const workspaceId = process.env.OPENCODE_GO_WORKSPACE_ID?.trim();
|
|
41
45
|
const authCookie = process.env.OPENCODE_GO_AUTH_COOKIE?.trim();
|
|
42
46
|
if (!workspaceId && !authCookie)
|
|
43
47
|
return { state: "none" };
|
|
44
48
|
if (workspaceId && authCookie) {
|
|
45
|
-
return {
|
|
49
|
+
return {
|
|
50
|
+
state: "configured",
|
|
51
|
+
config: { auth: "cookie", workspaceId, authCookie },
|
|
52
|
+
source: "env",
|
|
53
|
+
};
|
|
46
54
|
}
|
|
47
55
|
return {
|
|
48
56
|
state: "incomplete",
|
|
@@ -79,19 +87,34 @@ async function readFileResolution(path) {
|
|
|
79
87
|
error: err instanceof Error ? err.message : String(err),
|
|
80
88
|
};
|
|
81
89
|
}
|
|
90
|
+
if (typeof parsed === "string") {
|
|
91
|
+
const apiKey = parsed.trim();
|
|
92
|
+
if (apiKey) {
|
|
93
|
+
return { state: "configured", config: { auth: "api-key", apiKey }, source: path };
|
|
94
|
+
}
|
|
95
|
+
return { state: "invalid", source: path, error: "Config key is empty" };
|
|
96
|
+
}
|
|
82
97
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
83
98
|
return { state: "invalid", source: path, error: "Config must be a JSON object" };
|
|
84
99
|
}
|
|
85
100
|
const obj = parsed;
|
|
101
|
+
const apiKey = typeof obj.apiKey === "string" ? obj.apiKey.trim() : "";
|
|
86
102
|
const workspaceId = typeof obj.workspaceId === "string" ? obj.workspaceId.trim() : "";
|
|
87
103
|
const authCookie = typeof obj.authCookie === "string" ? obj.authCookie.trim() : "";
|
|
104
|
+
if (apiKey) {
|
|
105
|
+
return { state: "configured", config: { auth: "api-key", apiKey }, source: path };
|
|
106
|
+
}
|
|
88
107
|
if (workspaceId && authCookie) {
|
|
89
|
-
return {
|
|
108
|
+
return {
|
|
109
|
+
state: "configured",
|
|
110
|
+
config: { auth: "cookie", workspaceId, authCookie },
|
|
111
|
+
source: path,
|
|
112
|
+
};
|
|
90
113
|
}
|
|
91
114
|
return {
|
|
92
115
|
state: "incomplete",
|
|
93
116
|
source: path,
|
|
94
|
-
missing: workspaceId ? "authCookie" : "workspaceId",
|
|
117
|
+
missing: workspaceId ? "authCookie" : authCookie ? "workspaceId" : "apiKey",
|
|
95
118
|
};
|
|
96
119
|
}
|
|
97
120
|
async function resolveFromPaths(paths) {
|
|
@@ -139,6 +162,9 @@ export async function discoverOpenCodeGoInstances() {
|
|
|
139
162
|
const suffix = name.slice(EXTRA_PREFIX.length, -".json".length);
|
|
140
163
|
if (!suffix || seen.has(suffix))
|
|
141
164
|
continue;
|
|
165
|
+
// Helper files maintained by the account switcher are not quota configs.
|
|
166
|
+
if (suffix === "active" || suffix.endsWith("-key"))
|
|
167
|
+
continue;
|
|
142
168
|
seen.add(suffix);
|
|
143
169
|
instances.push({
|
|
144
170
|
id: `${EXTRA_PREFIX}${suffix}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode-go-config.js","sourceRoot":"","sources":["../../src/lib/opencode-go-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,WAAW,GAAG,gBAAgB,CAAC;AACrC,MAAM,YAAY,GAAG,kBAAkB,CAAC;AACxC,MAAM,YAAY,GAAG,cAAc,CAAC;AACpC,MAAM,kBAAkB,GAAG,aAAa,CAAC;AACzC,MAAM,UAAU,GAAG,aAAa,CAAC;AACjC,MAAM,aAAa,GAAG,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"opencode-go-config.js","sourceRoot":"","sources":["../../src/lib/opencode-go-config.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -24,6 +24,10 @@ export interface QuotaWindow {
|
|
|
24
24
|
used?: number;
|
|
25
25
|
/** Remaining quota for the window, if exposed by the provider. */
|
|
26
26
|
remaining?: number;
|
|
27
|
+
/** Money spent in this window, in microcents (1e8 microcents = 1 USD). */
|
|
28
|
+
spentMicroCents?: string;
|
|
29
|
+
/** Money limit for this window, in microcents (1e8 microcents = 1 USD). */
|
|
30
|
+
limitMicroCents?: string;
|
|
27
31
|
}
|
|
28
32
|
/** Status of a single provider fetch. */
|
|
29
33
|
export type ProviderStatus = "ok" | "no-auth" | "error" | "skipped" | "loading";
|
package/dist/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,uEAAuE;AACvE,MAAM,MAAM,QAAQ,GAChB,IAAI,GACJ,QAAQ,GACR,SAAS,GACT,aAAa,GACb,SAAS,CAAC;AAEd,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,EAAE,EAAE,QAAQ,CAAC;IACb,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,gBAAgB,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qGAAqG;IACrG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,uEAAuE;AACvE,MAAM,MAAM,QAAQ,GAChB,IAAI,GACJ,QAAQ,GACR,SAAS,GACT,aAAa,GACb,SAAS,CAAC;AAEd,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,EAAE,EAAE,QAAQ,CAAC;IACb,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,gBAAgB,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qGAAqG;IACrG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,yCAAyC;AACzC,MAAM,MAAM,cAAc,GACtB,IAAI,GACJ,SAAS,GACT,OAAO,GACP,SAAS,GACT,SAAS,CAAC;AAEd,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC9B,oFAAoF;IACpF,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uFAAuF;IACvF,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,6CAA6C;IAC7C,YAAY,CAAC,EAAE;QACb,OAAO,EAAE,OAAO,CAAC;QACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;KAChC,CAAC;CACH;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAC;IACX,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B"}
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Fetches usage data from the opencode.ai console API:
|
|
5
5
|
* GET https://opencode.ai/console/api/go/status
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
*
|
|
7
|
+
* Preferred auth: a personal API key (`oc_sk_...`) with All permissions, sent
|
|
8
|
+
* as `Authorization: Bearer`. It also unlocks dollar spend and the credit
|
|
9
|
+
* balance. A legacy browser session cookie is still accepted for backwards
|
|
10
|
+
* compatibility: `{ workspaceId, authCookie }` sent as `x-org-id` + Cookie.
|
|
11
|
+
*
|
|
11
12
|
* Additional instances can be configured via opencode-go-<suffix>.json files,
|
|
12
13
|
* each rendered as its own "Opencode Go <suffix>" section.
|
|
13
14
|
* Returns up to 3 windows: 5h (rolling), Weekly, Monthly.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode-go.d.ts","sourceRoot":"","sources":["../../src/providers/opencode-go.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"opencode-go.d.ts","sourceRoot":"","sources":["../../src/providers/opencode-go.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,YAAY,CAAC;AAyL5D,+DAA+D;AAC/D,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,yBAAyB,GAAG,QAAQ,CA4ElF;AAED,eAAO,MAAM,kBAAkB,EAAE,QAG/B,CAAC"}
|
|
@@ -43,6 +43,20 @@ function sessionCookieHeader(value) {
|
|
|
43
43
|
const name = value.startsWith("st_") ? "__Host-console_session" : "auth";
|
|
44
44
|
return `${name}=${value}`;
|
|
45
45
|
}
|
|
46
|
+
/** Build console API headers for either API-key or legacy cookie auth. */
|
|
47
|
+
function buildHeaders(config) {
|
|
48
|
+
const headers = {
|
|
49
|
+
"User-Agent": USER_AGENT,
|
|
50
|
+
Accept: "application/json",
|
|
51
|
+
};
|
|
52
|
+
if (config.auth === "api-key") {
|
|
53
|
+
headers.Authorization = `Bearer ${config.apiKey}`;
|
|
54
|
+
return headers;
|
|
55
|
+
}
|
|
56
|
+
headers.Cookie = sessionCookieHeader(config.authCookie);
|
|
57
|
+
headers["x-org-id"] = config.workspaceId;
|
|
58
|
+
return headers;
|
|
59
|
+
}
|
|
46
60
|
/** GET a console JSON endpoint. Errors never carry the response body or headers. */
|
|
47
61
|
async function getConsoleJson(url, headers, timeoutMs) {
|
|
48
62
|
const res = await fetchWithTimeout(url, { method: "GET", headers }, timeoutMs);
|
|
@@ -127,6 +141,8 @@ function buildWindows(status) {
|
|
|
127
141
|
id: spec.id,
|
|
128
142
|
label: spec.label,
|
|
129
143
|
percentRemaining: clampPercent(100 - percentUsed(used, limit)),
|
|
144
|
+
spentMicroCents: used.toString(),
|
|
145
|
+
limitMicroCents: limit.toString(),
|
|
130
146
|
};
|
|
131
147
|
const resetTimeIso = toIso(spec.resetsAt);
|
|
132
148
|
if (resetTimeIso)
|
|
@@ -166,13 +182,7 @@ export function createOpenCodeGoProvider(opts) {
|
|
|
166
182
|
if (r.state === "invalid") {
|
|
167
183
|
return { ...base, status: "error", error: `Invalid config: ${r.error}` };
|
|
168
184
|
}
|
|
169
|
-
const
|
|
170
|
-
const headers = {
|
|
171
|
-
"User-Agent": USER_AGENT,
|
|
172
|
-
Accept: "application/json",
|
|
173
|
-
Cookie: sessionCookieHeader(authCookie),
|
|
174
|
-
"x-org-id": workspaceId,
|
|
175
|
-
};
|
|
185
|
+
const headers = buildHeaders(r.config);
|
|
176
186
|
try {
|
|
177
187
|
const res = await fetchWithTimeout(GO_STATUS_URL, { method: "GET", headers }, ctx.requestTimeoutMs);
|
|
178
188
|
const bodyText = await res.text();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode-go.js","sourceRoot":"","sources":["../../src/providers/opencode-go.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"opencode-go.js","sourceRoot":"","sources":["../../src/providers/opencode-go.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAE/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,aAAa,GAAG,2CAA2C,CAAC;AAClE,MAAM,kBAAkB,GAAG,gDAAgD,CAAC;AAC5E,MAAM,iBAAiB,GAAG,uDAAuD,CAAC;AAClF,MAAM,UAAU,GACd,8EAA8E,CAAC;AAuBjF,iEAAiE;AACjE,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,OAAO,KAAK,EAAE;YAAE,OAAO,IAAI,CAAC;QAChC,IAAI,CAAC;YACH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAC1B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3D,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,wEAAwE;AACxE,SAAS,WAAW,CAAC,IAAY,EAAE,KAAa;IAC9C,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC,CAAC,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,KAAa;IACxC,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,MAAM,CAAC;IACzE,OAAO,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,0EAA0E;AAC1E,SAAS,YAAY,CAAC,MAAwB;IAC5C,MAAM,OAAO,GAA2B;QACtC,YAAY,EAAE,UAAU;QACxB,MAAM,EAAE,kBAAkB;KAC3B,CAAC;IACF,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,CAAC,aAAa,GAAG,UAAU,MAAM,CAAC,MAAM,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,CAAC,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACxD,OAAO,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC;IACzC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,oFAAoF;AACpF,KAAK,UAAU,cAAc,CAC3B,GAAW,EACX,OAA+B,EAC/B,SAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC/E,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,qFAAqF;AACrF,SAAS,wBAAwB,CAAC,IAAa;IAC7C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,KAAK,GAAG,QAAQ,CAAE,IAA0C,CAAC,mBAAmB,CAAC,CAAC;IACxF,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;AAChE,CAAC;AAED,qFAAqF;AACrF,SAAS,iBAAiB,CAAC,IAAa;IACtC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,GAAG,GAAG,IAA+B,CAAC;IAC5C,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,GAAG,GAAiD,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IACnF,IAAI,OAAO,GAAG,CAAC,gBAAgB,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACtF,GAAG,CAAC,gBAAgB,GAAG,GAAG,CAAC,gBAAgB,CAAC;IAC9C,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,qBAAqB,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,CAAC;QAChG,GAAG,CAAC,qBAAqB,GAAG,GAAG,CAAC,qBAAqB,CAAC;IACxD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,YAAY,CACzB,OAA+B,EAC/B,SAAiB,EACjB,UAA0B;IAE1B,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;QACnD,cAAc,CAAC,kBAAkB,EAAE,OAAO,EAAE,SAAS,CAAC;QACtD,cAAc,CAAC,iBAAiB,EAAE,OAAO,EAAE,SAAS,CAAC;KACtD,CAAC,CAAC;IACH,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO,SAAS,CAAC;IACrD,MAAM,mBAAmB,GAAG,wBAAwB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACpE,IAAI,mBAAmB,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IACnD,MAAM,OAAO,GAAoB,EAAE,mBAAmB,EAAE,UAAU,EAAE,CAAC;IACrE,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACvD,IAAI,YAAY;YAAE,OAAO,CAAC,YAAY,GAAG,YAAY,CAAC;IACxD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,KAAK,CAAC,KAAc;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IACvE,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IAChD,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACzB,CAAC;AAED,SAAS,YAAY,CAAC,MAAgB;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IACnC,MAAM,KAAK,GAKL;QACJ,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE;QACtF,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE;QACtF,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;KAClF,CAAC;IACF,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC5C,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;YAAE,SAAS;QAC9C,MAAM,MAAM,GAAgB;YAC1B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,gBAAgB,EAAE,YAAY,CAAC,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC9D,eAAe,EAAE,IAAI,CAAC,QAAQ,EAAE;YAChC,eAAe,EAAE,KAAK,CAAC,QAAQ,EAAE;SAClC,CAAC;QACF,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,YAAY;YAAE,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAQD,MAAM,UAAU,wBAAwB,CAAC,IAA+B;IACtE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IAC3B,OAAO;QACL,EAAE;QACF,YAAY,EAAE,KAAK;QACnB,KAAK,CAAC,WAAW;YACf,MAAM,CAAC,GAAG,MAAM,+BAA+B,CAAC,EAAE,CAAC,CAAC;YACpD,OAAO,CAAC,CAAC,KAAK,KAAK,YAAY,CAAC;QAClC,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,GAAoB;YAC9B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAkB;gBAC1B,EAAE;gBACF,KAAK;gBACL,MAAM,EAAE,SAAS;gBACjB,OAAO,EAAE,EAAE;gBACX,SAAS;aACV,CAAC;YACF,MAAM,CAAC,GAAG,MAAM,+BAA+B,CAAC,EAAE,CAAC,CAAC;YACpD,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YAC9D,IAAI,CAAC,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;gBAC7B,OAAO;oBACL,GAAG,IAAI;oBACP,MAAM,EAAE,OAAO;oBACf,KAAK,EAAE,WAAW,CAAC,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,GAAG;iBACpD,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC1B,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YAC3E,CAAC;YACD,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACvC,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAChC,aAAa,EACb,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAC1B,GAAG,CAAC,gBAAgB,CACrB,CAAC;gBACF,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBAClC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;oBACZ,OAAO;wBACL,GAAG,IAAI;wBACP,MAAM,EAAE,OAAO;wBACf,KAAK,EAAE,yBAAyB,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;qBACxE,CAAC;gBACJ,CAAC;gBACD,IAAI,IAAa,CAAC;gBAClB,IAAI,CAAC;oBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC9B,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO;wBACL,GAAG,IAAI;wBACP,MAAM,EAAE,OAAO;wBACf,KAAK,EAAE,uCAAuC;qBAC/C,CAAC;gBACJ,CAAC;gBACD,MAAM,MAAM,GAAG,CAAC,IAAI,IAAI,EAAE,CAAa,CAAC;gBACxC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;gBACrC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACzB,OAAO;wBACL,GAAG,IAAI;wBACP,MAAM,EAAE,OAAO;wBACf,KAAK,EAAE,MAAM,CAAC,MAAM;4BAClB,CAAC,CAAC,qDAAqD;4BACvD,CAAC,CAAC,oCAAoC;qBACzC,CAAC;gBACJ,CAAC;gBACD,MAAM,UAAU,GACd,OAAO,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;gBACpE,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;gBAC9E,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7E,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACjE,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YACpE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAa,wBAAwB,CAAC;IACnE,EAAE,EAAE,aAAa;IACjB,KAAK,EAAE,aAAa;CACrB,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SidebarPanel.d.ts","sourceRoot":"","sources":["../../src/ui/SidebarPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"SidebarPanel.d.ts","sourceRoot":"","sources":["../../src/ui/SidebarPanel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,GAAG,EAAE,YAAY,CAAC;IAClB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,MAAM,aAAa,CAAC;CAC/B,GAAG,GAAG,CAAC,OAAO,CAsBd"}
|
package/dist/ui/SidebarPanel.tsx
CHANGED
|
@@ -6,8 +6,6 @@ import type { TuiPluginApi } from "@opencode-ai/plugin/tui";
|
|
|
6
6
|
import type { CardsPluginConfig } from "../config/defaults.js";
|
|
7
7
|
import type { CardsSnapshot } from "../lib/types.js";
|
|
8
8
|
import { ProviderCards } from "./cards.js";
|
|
9
|
-
import { quotaPace } from "../lib/pace.js";
|
|
10
|
-
import { balanceUsd } from "../lib/balance.js";
|
|
11
9
|
|
|
12
10
|
export function SidebarPanel(props: {
|
|
13
11
|
api: TuiPluginApi;
|
|
@@ -21,23 +19,6 @@ export function SidebarPanel(props: {
|
|
|
21
19
|
props.snapshot().providers.filter((p) => p.status === "ok").length;
|
|
22
20
|
const totalCount = () => props.snapshot().providers.length;
|
|
23
21
|
|
|
24
|
-
const estimatedHeight = () => {
|
|
25
|
-
let total = 0
|
|
26
|
-
let blocks = 0
|
|
27
|
-
for (const p of props.snapshot().providers) {
|
|
28
|
-
if (p.status === "skipped") continue
|
|
29
|
-
blocks += 1
|
|
30
|
-
if (p.status === "no-auth" || p.status === "error") { total += 1; continue }
|
|
31
|
-
const windows = p.windows ?? []
|
|
32
|
-
if (windows.length === 0) { total += 1; continue }
|
|
33
|
-
// Each window is label + bar + left/used, plus a pace line when it applies.
|
|
34
|
-
const rows = windows.reduce((sum, w) => sum + 3 + (quotaPace(w) ? 1 : 0), 0)
|
|
35
|
-
const credit = balanceUsd(p.balance) === null ? 0 : 1 // a credit line under the title
|
|
36
|
-
total += 1 + credit + rows + (windows.length - 1) // title + credit + windows + gaps
|
|
37
|
-
}
|
|
38
|
-
return Math.min(total + Math.max(0, blocks - 1), 50) // + scrollbox gaps between providers
|
|
39
|
-
}
|
|
40
|
-
|
|
41
22
|
return (
|
|
42
23
|
<box flexDirection="column" gap={0}>
|
|
43
24
|
<box flexDirection="row" gap={1}>
|
|
@@ -45,11 +26,11 @@ export function SidebarPanel(props: {
|
|
|
45
26
|
Quota ({providerCount()}/{totalCount()})
|
|
46
27
|
</text>
|
|
47
28
|
</box>
|
|
48
|
-
<
|
|
29
|
+
<box flexDirection="column" gap={1}>
|
|
49
30
|
<For each={props.snapshot().providers}>
|
|
50
31
|
{(p) => <ProviderCards api={props.api} provider={p} showOnlyMultiWindow={props.config.showOnlyMultiWindow} />}
|
|
51
32
|
</For>
|
|
52
|
-
</
|
|
33
|
+
</box>
|
|
53
34
|
</box>
|
|
54
35
|
);
|
|
55
36
|
}
|
package/dist/ui/cards.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cards.d.ts","sourceRoot":"","sources":["../../src/ui/cards.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,iBAAiB,CAAC;AAMlE,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,GAAG,EAAE;QAAE,KAAK,EAAE;YAAE,OAAO,EAAE,eAAe,CAAA;SAAE,CAAA;KAAE,CAAC;IAC7C,QAAQ,EAAE,aAAa,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;CAC9B,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"cards.d.ts","sourceRoot":"","sources":["../../src/ui/cards.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,iBAAiB,CAAC;AAMlE,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,GAAG,EAAE;QAAE,KAAK,EAAE;YAAE,OAAO,EAAE,eAAe,CAAA;SAAE,CAAA;KAAE,CAAC;IAC7C,QAAQ,EAAE,aAAa,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;CAC9B,GAAG,GAAG,CAAC,OAAO,CAmDd"}
|
package/dist/ui/cards.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import type { ProviderQuota, QuotaWindow } from "../lib/types.js";
|
|
|
7
7
|
import { trafficLight, trafficLightColorKey } from "./progress-bar.js";
|
|
8
8
|
import { formatResetCombined } from "../lib/reset-format.js";
|
|
9
9
|
import { formatPace, quotaPace } from "../lib/pace.js";
|
|
10
|
-
import { formatBalance } from "../lib/balance.js";
|
|
10
|
+
import { formatBalance, formatWindowSpend } from "../lib/balance.js";
|
|
11
11
|
|
|
12
12
|
export function ProviderCards(props: {
|
|
13
13
|
api: { theme: { current: TuiThemeCurrent } };
|
|
@@ -51,10 +51,12 @@ export function ProviderCards(props: {
|
|
|
51
51
|
|
|
52
52
|
return (
|
|
53
53
|
<box flexDirection="column" gap={0} width="100%">
|
|
54
|
-
<
|
|
55
|
-
{
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
<box flexDirection="row" gap={1} width="100%">
|
|
55
|
+
<text fg={theme().text} attributes={TextAttributes.BOLD}>
|
|
56
|
+
{props.provider.label}
|
|
57
|
+
</text>
|
|
58
|
+
{credit() ? <text fg={theme().accent}>{credit()}</text> : null}
|
|
59
|
+
</box>
|
|
58
60
|
<box flexDirection="column" gap={1} width="100%">
|
|
59
61
|
<For each={props.provider.windows}>
|
|
60
62
|
{(window) => <WindowRow api={props.api} window={window} />}
|
|
@@ -78,6 +80,7 @@ function WindowRow(props: {
|
|
|
78
80
|
};
|
|
79
81
|
const label = () => windowDisplayLabel(props.window);
|
|
80
82
|
const reset = () => formatReset(props.window.resetTimeIso);
|
|
83
|
+
const spend = () => formatWindowSpend(props.window);
|
|
81
84
|
const pace = createMemo(() => quotaPace(props.window));
|
|
82
85
|
const paceText = () => formatPace(props.window);
|
|
83
86
|
const paceColor = () => {
|
|
@@ -97,7 +100,12 @@ function WindowRow(props: {
|
|
|
97
100
|
<text fg={barColor()}>{percent()}% left</text>
|
|
98
101
|
<text fg={muted()}>{100 - percent()}% used</text>
|
|
99
102
|
</box>
|
|
100
|
-
{
|
|
103
|
+
{spend() || paceText() ? (
|
|
104
|
+
<box flexDirection="row" gap={0} justifyContent="space-between" width="100%">
|
|
105
|
+
<text fg={muted()}>{spend()}</text>
|
|
106
|
+
<text fg={paceColor()}>{paceText()}</text>
|
|
107
|
+
</box>
|
|
108
|
+
) : null}
|
|
101
109
|
</box>
|
|
102
110
|
);
|
|
103
111
|
}
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arandevcode/opencode-quota-extended",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "OpenCode plugin: quota usage cards with theme-colored gauge progress bars (5h / weekly / monthly) for OpenAI, GitHub Copilot and OpenCode Go in the TUI sidebar.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
package/scripts/setup.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createInterface } from "node:readline";
|
|
3
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { mkdir, writeFile, chmod } from "node:fs/promises";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
|
|
@@ -8,38 +8,46 @@ const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
|
8
8
|
const ask = (q) => new Promise((r) => rl.question(q, r));
|
|
9
9
|
|
|
10
10
|
const outDir = join(homedir(), ".config", "opencode", "opencode-quota");
|
|
11
|
-
const
|
|
11
|
+
const argSuffix = process.argv[2]?.trim();
|
|
12
12
|
|
|
13
13
|
console.log("");
|
|
14
14
|
console.log("== OpenCode Go — setup ==");
|
|
15
15
|
console.log("");
|
|
16
|
-
console.log("Necesitas
|
|
17
|
-
console.log(" 1.
|
|
18
|
-
console.log(" 2.
|
|
19
|
-
|
|
16
|
+
console.log("Necesitas una API key personal de OpenCode Go:");
|
|
17
|
+
console.log(" 1. Abre https://opencode.ai/console");
|
|
18
|
+
console.log(" 2. Ve a 'Personal API keys' y crea una key");
|
|
19
|
+
console.log(" 3. Permisos: 'All' (es la unica forma de leer cuotas, gasto y balance)");
|
|
20
|
+
console.log(" No uses una service account: no puede gestionar billing.");
|
|
21
|
+
console.log(" 4. Copia el valor (empieza con oc_sk_...)");
|
|
20
22
|
console.log("");
|
|
21
|
-
console.log("
|
|
22
|
-
console.log(" A. Abre https://opencode.ai y loguéate en Chrome");
|
|
23
|
-
console.log(" B. Abre DevTools (F12) → Application → Cookies → https://opencode.ai");
|
|
24
|
-
console.log(" C. Busca la cookie '__Host-console_session' — copia su valor (empieza con st_...)");
|
|
25
|
-
console.log(" (es HttpOnly, así que document.cookie no la ve; usa DevTools)");
|
|
26
|
-
console.log(" D. El Workspace ID está en la URL: https://opencode.ai/workspace/wrk_XXX/go");
|
|
23
|
+
console.log("La key se guarda solo en tu equipo, con permisos 600.");
|
|
27
24
|
console.log("");
|
|
28
25
|
|
|
29
|
-
const
|
|
30
|
-
const
|
|
26
|
+
const suffixInput = argSuffix ?? (await ask("Nombre de cuenta (opcional, ej. work): ")).trim();
|
|
27
|
+
const suffix = suffixInput
|
|
28
|
+
.replace(/[^A-Za-z0-9._-]+/g, "-")
|
|
29
|
+
.replace(/^-+|-+$/g, "");
|
|
30
|
+
if (suffix === "active" || suffix.endsWith("-key")) {
|
|
31
|
+
console.error("Ese nombre esta reservado por el switch de cuentas. Usa otro.");
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const apiKey = (await ask("Pega la API key (oc_sk_...): ")).trim();
|
|
31
36
|
rl.close();
|
|
32
37
|
|
|
33
|
-
if (!
|
|
34
|
-
console.error("
|
|
38
|
+
if (!apiKey) {
|
|
39
|
+
console.error("La API key es obligatoria. Abortando.");
|
|
35
40
|
process.exit(1);
|
|
36
41
|
}
|
|
42
|
+
if (!apiKey.startsWith("oc_sk_")) {
|
|
43
|
+
console.warn("Aviso: la key no empieza por 'oc_sk_'. Se guarda igualmente.");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const outFile = join(outDir, suffix ? `opencode-go-${suffix}.json` : "opencode-go.json");
|
|
37
47
|
|
|
38
48
|
await mkdir(outDir, { recursive: true });
|
|
39
|
-
await writeFile(
|
|
40
|
-
|
|
41
|
-
JSON.stringify({ workspaceId, authCookie }, null, 2) + "\n",
|
|
42
|
-
);
|
|
49
|
+
await writeFile(outFile, JSON.stringify({ apiKey }, null, 2) + "\n", { mode: 0o600 });
|
|
50
|
+
await chmod(outFile, 0o600);
|
|
43
51
|
|
|
44
|
-
console.log(`\
|
|
45
|
-
console.log("Reinicia OpenCode y el panel 'Quota cards'
|
|
52
|
+
console.log(`\nConfiguracion guardada en: ${outFile}`);
|
|
53
|
+
console.log("Reinicia OpenCode y el panel 'Quota cards' aparecera.");
|