@arandevcode/opencode-quota-extended 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README-es.md +23 -13
- package/README.md +22 -12
- package/bin/quota.mjs +8 -1
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -7
- package/dist/index.js.map +1 -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/server.d.ts +17 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +12 -0
- package/dist/server.js.map +1 -1
- package/dist/tui.d.ts +3 -0
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.tsx +14 -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/dist/v2.d.ts +61 -0
- package/dist/v2.d.ts.map +1 -0
- package/dist/v2.js +67 -0
- package/dist/v2.js.map +1 -0
- package/images/opencode_quota_extended_cli.png +0 -0
- package/images/opencode_quota_extended_sidebar.png +0 -0
- package/package.json +10 -3
- package/scripts/setup.mjs +30 -22
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.0 — 2026-11-06
|
|
4
|
+
- OpenCode 2 support (early preview): the package now registers on both OpenCode 1.x and 2.x; tested on 2.1.2.
|
|
5
|
+
|
|
6
|
+
## 0.2.4 — 2026-10-21
|
|
7
|
+
- OpenCode Go quota, spend and balance read with a personal API key.
|
|
8
|
+
- More compact sidebar layout.
|
|
9
|
+
|
|
10
|
+
## 0.2.3 — 2026-10-19
|
|
11
|
+
- Credit balance and usage pace in the sidebar.
|
|
12
|
+
- Coalesced TUI refreshes to stop provider error storms.
|
|
13
|
+
|
|
14
|
+
## 0.2.2 — 2026-08-06
|
|
15
|
+
- Allow OpenTUI 0.5 peer dependencies.
|
|
16
|
+
|
|
17
|
+
## 0.2.1 — 2026-08-05
|
|
18
|
+
- Packaging cleanup: removed stray files from the published package.
|
|
19
|
+
|
|
20
|
+
## 0.2.0 — 2026-08-05
|
|
21
|
+
- Theme-aware colors, single-row gauge, error boundary and guarded event handlers.
|
|
22
|
+
|
|
23
|
+
## 0.1.x — 2026-06 / 2026-07
|
|
24
|
+
- First releases: per-window quota cards for OpenAI, GitHub Copilot and OpenCode Go, plus the `quota` CLI.
|
package/README-es.md
CHANGED
|
@@ -44,6 +44,10 @@ O instala desde GitHub para seguir el desarrollo más reciente:
|
|
|
44
44
|
}
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
### OpenCode 2 (versión preliminar)
|
|
48
|
+
|
|
49
|
+
El mismo paquete funciona en OpenCode 1.x y en OpenCode 2: trae una entrada para cada uno y carga la que toca. El soporte V2 es nuevo (probado en OpenCode 2.1.2); si ves algo raro, abre un issue.
|
|
50
|
+
|
|
47
51
|
## Desinstalación
|
|
48
52
|
|
|
49
53
|
Cuatro pasos, en orden:
|
|
@@ -121,7 +125,7 @@ Registra un plugin TUI que renderiza un panel `sidebar_content` en la posición
|
|
|
121
125
|
|---|---|---|
|
|
122
126
|
| **OpenAI** | 5h móvil, Semanal, Code Review | `auth.json` → entrada `openai` / `chatgpt` |
|
|
123
127
|
| **GitHub Copilot** | Solicitudes Premium (ventana única) | `auth.json` → entrada `github-copilot` |
|
|
124
|
-
| **OpenCode Go** | 5h, Semanal, Mensual |
|
|
128
|
+
| **OpenCode Go** | 5h, Semanal, Mensual + gasto | API key personal (o cookie de sesión legacy) |
|
|
125
129
|
|
|
126
130
|
Colores de semáforo: ≥50% `theme.success` (verde), 25-49% `theme.warning` (naranja), <25% `theme.error` (rojo).
|
|
127
131
|
|
|
@@ -129,38 +133,43 @@ Colores de semáforo: ≥50% `theme.success` (verde), 25-49% `theme.warning` (na
|
|
|
129
133
|
|
|
130
134
|
Lee credenciales del archivo de autenticación de OpenCode (`~/.local/share/opencode/auth.json`). **No** almacena, solicita ni distribuye secretos.
|
|
131
135
|
|
|
132
|
-
**OpenCode Go**
|
|
136
|
+
**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
137
|
|
|
134
138
|
Crea `~/.config/opencode/opencode-quota/opencode-go.json`:
|
|
135
139
|
|
|
136
140
|
```json
|
|
137
141
|
{
|
|
138
|
-
"
|
|
139
|
-
"authCookie": "st_..."
|
|
142
|
+
"apiKey": "oc_sk_..."
|
|
140
143
|
}
|
|
141
144
|
```
|
|
142
145
|
|
|
143
146
|
| Campo | Descripción | Cómo obtenerlo |
|
|
144
147
|
|---|---|---|
|
|
145
|
-
| `
|
|
146
|
-
|
|
148
|
+
| `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. |
|
|
149
|
+
|
|
150
|
+
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
151
|
|
|
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**.
|
|
152
|
+
**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
153
|
|
|
150
154
|
```sh
|
|
151
|
-
# p. ej.
|
|
155
|
+
# p. ej. una segunda cuenta
|
|
152
156
|
cp ~/.config/opencode/opencode-quota/opencode-go.json \
|
|
153
157
|
~/.config/opencode/opencode-quota/opencode-go-work.json
|
|
154
|
-
# luego
|
|
158
|
+
# luego sustituye apiKey dentro de opencode-go-work.json
|
|
155
159
|
```
|
|
156
160
|
|
|
157
161
|
**Setup automatizado** (recomendado):
|
|
158
162
|
```sh
|
|
159
|
-
npm run setup
|
|
163
|
+
npm run setup # cuenta base -> opencode-go.json
|
|
164
|
+
npm run setup work # cuenta extra -> opencode-go-work.json
|
|
160
165
|
```
|
|
161
|
-
Te solicita
|
|
166
|
+
Te solicita la API key, escribe el archivo con permisos `600` e indica dónde crearla.
|
|
167
|
+
|
|
168
|
+
También puedes usar `OPENCODE_GO_API_KEY` en vez de un archivo.
|
|
169
|
+
|
|
170
|
+
**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
171
|
|
|
163
|
-
**
|
|
172
|
+
**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
173
|
|
|
165
174
|
### Relación con [`@slkiser/opencode-quota`](https://github.com/slkiser/opencode-quota)
|
|
166
175
|
|
|
@@ -169,7 +178,8 @@ Te solicita ambos valores y crea el archivo automáticamente. También muestra i
|
|
|
169
178
|
### Solución de problemas
|
|
170
179
|
|
|
171
180
|
- **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
|
|
181
|
+
- **OpenCode Go muestra "skipped"**: confirma que el archivo sidecar o `OPENCODE_GO_API_KEY` está configurado
|
|
182
|
+
- **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
183
|
- **Bug antiguo de pinning `@opentui/solid`**: usa `^0.4.1 || ^0.5.0` y reinstala limpio (`rm -rf node_modules && npm ci`)
|
|
174
184
|
|
|
175
185
|
### Desarrollo
|
package/README.md
CHANGED
|
@@ -45,6 +45,10 @@ Or install from GitHub source to follow latest development:
|
|
|
45
45
|
}
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
### OpenCode 2 (early preview)
|
|
49
|
+
|
|
50
|
+
The same package works on OpenCode 1.x and OpenCode 2: it ships one entry for each and loads the right one. V2 support is new (tested on OpenCode 2.1.2), so please report anything odd.
|
|
51
|
+
|
|
48
52
|
## Uninstall
|
|
49
53
|
|
|
50
54
|
Four steps, in order:
|
|
@@ -122,7 +126,7 @@ Registers a TUI plugin that renders a `sidebar_content` panel at order 145, show
|
|
|
122
126
|
|---|---|---|
|
|
123
127
|
| **OpenAI** | 5h rolling, Weekly, Code Review | `auth.json` → `openai` / `chatgpt` entry |
|
|
124
128
|
| **GitHub Copilot** | Premium requests (single window) | `auth.json` → `github-copilot` entry |
|
|
125
|
-
| **OpenCode Go** | 5h, Weekly, Monthly |
|
|
129
|
+
| **OpenCode Go** | 5h, Weekly, Monthly + spend | Personal API key (or legacy session cookie) |
|
|
126
130
|
|
|
127
131
|
Traffic-light colors: ≥50% `theme.success` (green), 25-49% `theme.warning` (orange), <25% `theme.error` (red).
|
|
128
132
|
|
|
@@ -130,38 +134,43 @@ Traffic-light colors: ≥50% `theme.success` (green), 25-49% `theme.warning` (or
|
|
|
130
134
|
|
|
131
135
|
Reads credentials from OpenCode's runtime auth file (`~/.local/share/opencode/auth.json`). Does **not** store, prompt for, or distribute secrets.
|
|
132
136
|
|
|
133
|
-
**OpenCode Go**
|
|
137
|
+
**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
138
|
|
|
135
139
|
Create `~/.config/opencode/opencode-quota/opencode-go.json`:
|
|
136
140
|
|
|
137
141
|
```json
|
|
138
142
|
{
|
|
139
|
-
"
|
|
140
|
-
"authCookie": "st_..."
|
|
143
|
+
"apiKey": "oc_sk_..."
|
|
141
144
|
}
|
|
142
145
|
```
|
|
143
146
|
|
|
144
147
|
| Field | Description | How to get it |
|
|
145
148
|
|---|---|---|
|
|
146
|
-
| `
|
|
147
|
-
|
|
149
|
+
| `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. |
|
|
150
|
+
|
|
151
|
+
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
152
|
|
|
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**.
|
|
153
|
+
**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
154
|
|
|
151
155
|
```sh
|
|
152
156
|
# e.g. a second workspace
|
|
153
157
|
cp ~/.config/opencode/opencode-quota/opencode-go.json \
|
|
154
158
|
~/.config/opencode/opencode-quota/opencode-go-work.json
|
|
155
|
-
# then
|
|
159
|
+
# then replace apiKey inside opencode-go-work.json
|
|
156
160
|
```
|
|
157
161
|
|
|
158
162
|
**Automated setup** (recommended):
|
|
159
163
|
```sh
|
|
160
|
-
npm run setup
|
|
164
|
+
npm run setup # base account -> opencode-go.json
|
|
165
|
+
npm run setup work # extra account -> opencode-go-work.json
|
|
161
166
|
```
|
|
162
|
-
This prompts for
|
|
167
|
+
This prompts for the API key, writes the file with mode `600`, and prints where to create the key.
|
|
168
|
+
|
|
169
|
+
You can also use `OPENCODE_GO_API_KEY` instead of a file.
|
|
170
|
+
|
|
171
|
+
**Legacy:** `{ "workspaceId": "wrk_...", "authCookie": "st_..." }` is still accepted for backwards compatibility, but the browser session cookie expires. Prefer the API key.
|
|
163
172
|
|
|
164
|
-
**
|
|
173
|
+
**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
174
|
|
|
166
175
|
### Relationship with [`@slkiser/opencode-quota`](https://github.com/slkiser/opencode-quota)
|
|
167
176
|
|
|
@@ -170,7 +179,8 @@ This prompts for both values and creates the file for you. It also prints step-b
|
|
|
170
179
|
### Troubleshooting
|
|
171
180
|
|
|
172
181
|
- **Panel doesn't appear**: `grep '@arandevcode/opencode-quota-extended' ~/.local/share/opencode/log/*.log`
|
|
173
|
-
- **OpenCode Go shows "skipped"**: confirm sidecar file or
|
|
182
|
+
- **OpenCode Go shows "skipped"**: confirm the sidecar file or `OPENCODE_GO_API_KEY` is set
|
|
183
|
+
- **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
184
|
- **Old `@opentui/solid` pinning bug**: use `^0.4.1 || ^0.5.0` and clean-install (`rm -rf node_modules && npm ci`)
|
|
175
185
|
|
|
176
186
|
### 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/index.d.ts
CHANGED
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @packageDocumentation
|
|
8
8
|
*/
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export default pluginModule;
|
|
13
|
-
export { quotaCardsServerPlugin };
|
|
9
|
+
import plugin from "./server.js";
|
|
10
|
+
export { quotaCardsServerPlugin } from "./server.js";
|
|
11
|
+
export default plugin;
|
|
14
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode Quota Cards Plugin (server entry)
|
|
3
|
+
*
|
|
4
|
+
* Renders quota usage as progress-bar cards in the TUI sidebar for
|
|
5
|
+
* OpenAI, GitHub Copilot and OpenCode Go (5h / weekly / monthly).
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import plugin from "./server.js";
|
|
10
|
+
export { quotaCardsServerPlugin } from "./server.js";
|
|
11
|
+
export default plugin;
|
|
8
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,eAAe,MAAM,CAAC"}
|
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":"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;AAsBpC,SAAS,sBAAsB;IAC7B,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,uBAAuB;IAC9B,OAAO,sBAAsB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,wBAAwB;IAC/B,OAAO,uBAAuB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,yBAAyB,CAAC,EAAU;IAC3C,IAAI,EAAE,KAAK,UAAU;QAAE,OAAO,wBAAwB,EAAE,CAAC;IACzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5C,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,OAAO,uBAAuB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,YAAY,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC;AACxF,CAAC;AAED,SAAS,OAAO;IACd,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC;IACvD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACrF,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,EAAE,CAAC;IACjE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,CAAC;IAC/D,IAAI,CAAC,WAAW,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC1D,IAAI,WAAW,IAAI,UAAU,EAAE,CAAC;QAC9B,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE;YACnD,MAAM,EAAE,KAAK;SACd,CAAC;IACJ,CAAC;IACD,OAAO;QACL,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa;KACpD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,kBAAkB,CAC/B,IAAY;IAEZ,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAClE,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;IACJ,CAAC;IACD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACpF,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC1E,CAAC;IACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC;IACnF,CAAC;IACD,MAAM,GAAG,GAAG,MAAiC,CAAC;IAC9C,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,MAAM,WAAW,GAAG,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtF,MAAM,UAAU,GAAG,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACpF,CAAC;IACD,IAAI,WAAW,IAAI,UAAU,EAAE,CAAC;QAC9B,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE;YACnD,MAAM,EAAE,IAAI;SACb,CAAC;IACJ,CAAC;IACD,OAAO;QACL,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ;KAC5E,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,KAAe;IAEf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,UAAU,KAAK,IAAI;YAAE,SAAS;QAClC,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,SAAS,GAAG,OAAO,EAAE,CAAC;IAC5B,IAAI,SAAS,CAAC,KAAK,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IACjD,OAAO,gBAAgB,CAAC,wBAAwB,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,qDAAqD;AACrD,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,EAAU;IAEV,OAAO,gBAAgB,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B;IAC/C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,SAAS,GAAyB,EAAE,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,uBAAuB,EAAE,EAAE,CAAC;QAC5C,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;gBAAE,SAAS;YAC7C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAChE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,SAAS;YAC1C,yEAAyE;YACzE,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,SAAS;YAC7D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjB,SAAS,CAAC,IAAI,CAAC;gBACb,EAAE,EAAE,GAAG,YAAY,GAAG,MAAM,EAAE;gBAC9B,KAAK,EAAE,GAAG,kBAAkB,KAAK,MAAM,GAAG;aAC3C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,IAAI,MAAM,GAA6D,IAAI,CAAC;AAC5E,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,6BAA6B;IACjD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,EAAE,GAAG,gBAAgB;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IACtE,MAAM,KAAK,GAAG,MAAM,uBAAuB,EAAE,CAAC;IAC9C,MAAM,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,aAAa,GAAG,IAAI,GAAG,EAG1B,CAAC;AAEJ,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,EAAU;IAEV,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,EAAE,GAAG,gBAAgB;QAAE,OAAO,GAAG,CAAC,KAAK,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,yBAAyB,CAAC,EAAE,CAAC,CAAC;IAClD,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,0BAA0B;IACxC,MAAM,GAAG,IAAI,CAAC;IACd,aAAa,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC"}
|
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":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OpenCode Quota Cards — server plugin (minimal).
|
|
2
|
+
* OpenCode Quota Cards — server plugin (minimal, dual V1/V2).
|
|
3
3
|
*
|
|
4
4
|
* This plugin is primarily a TUI sidebar plugin. The server module
|
|
5
5
|
* is kept registered for compatibility but provides no additional
|
|
6
6
|
* tools or commands.
|
|
7
|
+
*
|
|
8
|
+
* Both `index.ts` (root) and this `./server` entry export the same object.
|
|
9
|
+
* V1's `oc-plugin: ["server"]` loads it and calls `server`; V2 resolves the
|
|
10
|
+
* `./server` subpath first for dual packages and reads `id` + `setup`. Keeping
|
|
11
|
+
* both entries V2-shaped avoids the "Plugin must export a default definition"
|
|
12
|
+
* error when V2 discovers a directory that contains both files.
|
|
7
13
|
*/
|
|
8
14
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
9
15
|
export declare const quotaCardsServerPlugin: Plugin;
|
|
16
|
+
type V2SetupContext = {
|
|
17
|
+
storage?: unknown;
|
|
18
|
+
location?: unknown;
|
|
19
|
+
};
|
|
20
|
+
declare const plugin: {
|
|
21
|
+
id: string;
|
|
22
|
+
server: Plugin;
|
|
23
|
+
setup(ctx?: V2SetupContext): Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
export default plugin;
|
|
10
26
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,qBAAqB,CAAC;AAEzD,eAAO,MAAM,sBAAsB,EAAE,MAEpC,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,QAAA,MAAM,MAAM;;YAEwB,MAAM;gBACtB,cAAc;CAMjC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
export const quotaCardsServerPlugin = async () => {
|
|
2
2
|
return {};
|
|
3
3
|
};
|
|
4
|
+
const plugin = {
|
|
5
|
+
id: "@local/opencode-quota-extended",
|
|
6
|
+
server: quotaCardsServerPlugin,
|
|
7
|
+
async setup(ctx) {
|
|
8
|
+
// OpenCode 1.19.x calls setup() too, but without the V2 context.
|
|
9
|
+
if (!ctx?.storage || !ctx?.location)
|
|
10
|
+
return;
|
|
11
|
+
// V2 has no server-side quota work. The TUI cards are still V1-only;
|
|
12
|
+
// this entry point exists so V2 can load the package without error.
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
export default plugin;
|
|
4
16
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,MAAM,sBAAsB,GAAW,KAAK,IAAoB,EAAE;IACvE,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAOF,MAAM,MAAM,GAAG;IACb,EAAE,EAAE,gCAAgC;IACpC,MAAM,EAAE,sBAAgC;IACxC,KAAK,CAAC,KAAK,CAAC,GAAoB;QAC9B,iEAAiE;QACjE,IAAI,CAAC,GAAG,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,QAAQ;YAAE,OAAO;QAC5C,qEAAqE;QACrE,oEAAoE;IACtE,CAAC;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/tui.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { TuiPlugin, TuiPluginModule } from "@opencode-ai/plugin/tui";
|
|
2
|
+
import { type V2Context } from "./v2.js";
|
|
2
3
|
export declare const quotaCardsTuiPlugin: TuiPlugin;
|
|
4
|
+
export declare function quotaCardsTuiV2(context: V2Context): Promise<() => void>;
|
|
3
5
|
declare const pluginModule: TuiPluginModule & {
|
|
4
6
|
id: string;
|
|
7
|
+
setup?: (context: V2Context) => Promise<() => void>;
|
|
5
8
|
};
|
|
6
9
|
export default pluginModule;
|
|
7
10
|
//# sourceMappingURL=tui.d.ts.map
|
package/dist/tui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAK1E,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAO3D,eAAO,MAAM,mBAAmB,EAAE,SAkFjC,CAAC;AAEF,wBAAsB,eAAe,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAS7E;AAED,QAAA,MAAM,YAAY,EAAE,eAAe,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,KAAK,OAAO,CAAC,MAAM,IAAI,CAAC,CAAA;CAItG,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
package/dist/tui.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import { loadCardsConfig } from "./config/loader.js";
|
|
|
5
5
|
import { createRefreshScheduler } from "./lib/refresh-scheduler.js";
|
|
6
6
|
import { collectSnapshot } from "./providers/registry.js";
|
|
7
7
|
import { SidebarPanel } from "./ui/SidebarPanel.js";
|
|
8
|
+
import { createQuotaV2Api, type V2Context } from "./v2.js";
|
|
8
9
|
|
|
9
10
|
const REFRESH_INTERVAL_MS = 60_000;
|
|
10
11
|
const MOUNT_RECOVERY_DELAY_MS = 1_500;
|
|
@@ -95,9 +96,21 @@ export const quotaCardsTuiPlugin: TuiPlugin = async (api, _options, _meta) => {
|
|
|
95
96
|
}
|
|
96
97
|
};
|
|
97
98
|
|
|
98
|
-
|
|
99
|
+
export async function quotaCardsTuiV2(context: V2Context): Promise<() => void> {
|
|
100
|
+
const cleanups: Array<() => void> = [];
|
|
101
|
+
const api = createQuotaV2Api(context, cleanups);
|
|
102
|
+
await quotaCardsTuiPlugin(api, context.options ?? {}, {} as any);
|
|
103
|
+
return () => {
|
|
104
|
+
for (const cleanup of cleanups.reverse()) {
|
|
105
|
+
try { cleanup(); } catch {}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const pluginModule: TuiPluginModule & { id: string; setup?: (context: V2Context) => Promise<() => void> } = {
|
|
99
111
|
id: "@local/opencode-quota-extended",
|
|
100
112
|
tui: quotaCardsTuiPlugin,
|
|
113
|
+
setup: quotaCardsTuiV2,
|
|
101
114
|
};
|
|
102
115
|
|
|
103
116
|
export default pluginModule;
|
|
@@ -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
|
}
|
package/dist/v2.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export type V2Theme = {
|
|
2
|
+
text?: {
|
|
3
|
+
base?: string;
|
|
4
|
+
muted?: string;
|
|
5
|
+
} | string;
|
|
6
|
+
accent?: {
|
|
7
|
+
base?: string;
|
|
8
|
+
} | string;
|
|
9
|
+
background?: {
|
|
10
|
+
panel?: string;
|
|
11
|
+
element?: string;
|
|
12
|
+
};
|
|
13
|
+
status?: {
|
|
14
|
+
success?: string;
|
|
15
|
+
warning?: string;
|
|
16
|
+
danger?: string;
|
|
17
|
+
error?: string;
|
|
18
|
+
};
|
|
19
|
+
primary?: string;
|
|
20
|
+
success?: string;
|
|
21
|
+
warning?: string;
|
|
22
|
+
error?: string;
|
|
23
|
+
textMuted?: string;
|
|
24
|
+
backgroundPanel?: string;
|
|
25
|
+
backgroundElement?: string;
|
|
26
|
+
};
|
|
27
|
+
export type V2Context = {
|
|
28
|
+
theme?: V2Theme;
|
|
29
|
+
options?: Record<string, unknown>;
|
|
30
|
+
data?: {
|
|
31
|
+
on?: (type: string, handler: (event: unknown) => void) => () => void;
|
|
32
|
+
listen?: (handler: (event: unknown) => void) => () => void;
|
|
33
|
+
};
|
|
34
|
+
ui?: {
|
|
35
|
+
slot?: (input: {
|
|
36
|
+
append?: string;
|
|
37
|
+
render: (props: {
|
|
38
|
+
sessionID?: string;
|
|
39
|
+
}) => unknown;
|
|
40
|
+
}) => () => void;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export declare function asColor(value: unknown, fallback: string): string;
|
|
44
|
+
export declare function v2Theme(theme?: V2Theme): {
|
|
45
|
+
text: string;
|
|
46
|
+
textMuted: string;
|
|
47
|
+
primary: string;
|
|
48
|
+
accent: string;
|
|
49
|
+
success: string;
|
|
50
|
+
warning: string;
|
|
51
|
+
error: string;
|
|
52
|
+
backgroundPanel: string;
|
|
53
|
+
backgroundElement: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Adapt a V2 CLI plugin context to the V1 TUI API the cards already use.
|
|
57
|
+
* The components only read `theme.current`; events and slots are bridged so
|
|
58
|
+
* the existing refresh scheduler and sidebar markup stay unchanged.
|
|
59
|
+
*/
|
|
60
|
+
export declare function createQuotaV2Api(context: V2Context, cleanups: Array<() => void>): any;
|
|
61
|
+
//# sourceMappingURL=v2.d.ts.map
|
package/dist/v2.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2.d.ts","sourceRoot":"","sources":["../src/v2.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAClD,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACpC,UAAU,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE;QACL,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;QACrE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;KAC5D,CAAC;IACF,EAAE,CAAC,EAAE;QACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,CAAC,KAAK,EAAE;gBAAE,SAAS,CAAC,EAAE,MAAM,CAAA;aAAE,KAAK,OAAO,CAAA;SAAE,KAAK,MAAM,IAAI,CAAC;KACvG,CAAC;CACH,CAAC;AAEF,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED,wBAAgB,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO;;;;;;;;;;EAatC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,GAuCjC,GAAG,CACjD"}
|
package/dist/v2.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export function asColor(value, fallback) {
|
|
2
|
+
if (typeof value === "string")
|
|
3
|
+
return value;
|
|
4
|
+
if (value && typeof value === "object" && typeof value.base === "string") {
|
|
5
|
+
return value.base;
|
|
6
|
+
}
|
|
7
|
+
return fallback;
|
|
8
|
+
}
|
|
9
|
+
export function v2Theme(theme) {
|
|
10
|
+
const text = theme?.text;
|
|
11
|
+
return {
|
|
12
|
+
text: typeof text === "string" ? text : asColor(text?.base, "#ffffff"),
|
|
13
|
+
textMuted: typeof text === "object" ? asColor(text?.muted, "#888888") : asColor(theme?.textMuted, "#888888"),
|
|
14
|
+
primary: asColor(theme?.primary, "#4aa3ff"),
|
|
15
|
+
accent: asColor(theme?.accent, "#4aa3ff"),
|
|
16
|
+
success: asColor(theme?.status?.success ?? theme?.success, "#4cc46a"),
|
|
17
|
+
warning: asColor(theme?.status?.warning ?? theme?.warning, "#e6b450"),
|
|
18
|
+
error: asColor(theme?.status?.danger ?? theme?.status?.error ?? theme?.error, "#e5534b"),
|
|
19
|
+
backgroundPanel: asColor(theme?.background?.panel ?? theme?.backgroundPanel, "#111111"),
|
|
20
|
+
backgroundElement: asColor(theme?.background?.element ?? theme?.backgroundElement, "#222222"),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Adapt a V2 CLI plugin context to the V1 TUI API the cards already use.
|
|
25
|
+
* The components only read `theme.current`; events and slots are bridged so
|
|
26
|
+
* the existing refresh scheduler and sidebar markup stay unchanged.
|
|
27
|
+
*/
|
|
28
|
+
export function createQuotaV2Api(context, cleanups) {
|
|
29
|
+
const currentTheme = v2Theme(context.theme);
|
|
30
|
+
const theme = { current: currentTheme };
|
|
31
|
+
Object.defineProperty(theme, "current", { get: () => v2Theme(context.theme) });
|
|
32
|
+
const event = {
|
|
33
|
+
on(_type, handler) {
|
|
34
|
+
const unsubscribe = context.data?.on?.("session.execution.started", handler)
|
|
35
|
+
?? context.data?.on?.("session.updated", handler)
|
|
36
|
+
?? (() => { });
|
|
37
|
+
if (context.data?.listen) {
|
|
38
|
+
const stop = context.data.listen(handler);
|
|
39
|
+
cleanups.push(stop);
|
|
40
|
+
}
|
|
41
|
+
cleanups.push(unsubscribe);
|
|
42
|
+
return () => {
|
|
43
|
+
unsubscribe();
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
const lifecycle = {
|
|
48
|
+
onDispose(fn) {
|
|
49
|
+
cleanups.push(fn);
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
const slots = {
|
|
53
|
+
register(input) {
|
|
54
|
+
const render = input.slots.sidebar_content;
|
|
55
|
+
if (!render || !context.ui?.slot)
|
|
56
|
+
return;
|
|
57
|
+
const dispose = context.ui.slot({
|
|
58
|
+
append: "sidebar.content",
|
|
59
|
+
render: (props) => render({}, { session_id: props.sessionID ?? "" }),
|
|
60
|
+
});
|
|
61
|
+
if (typeof dispose === "function")
|
|
62
|
+
cleanups.push(dispose);
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
return { theme, event, lifecycle, slots };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=v2.js.map
|
package/dist/v2.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2.js","sourceRoot":"","sources":["../src/v2.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arandevcode/opencode-quota-extended",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
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",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"scripts/setup.mjs",
|
|
36
36
|
"README.md",
|
|
37
37
|
"README-es.md",
|
|
38
|
-
"LICENSE"
|
|
38
|
+
"LICENSE",
|
|
39
|
+
"CHANGELOG.md"
|
|
39
40
|
],
|
|
40
41
|
"scripts": {
|
|
41
42
|
"clean": "node scripts/clean.mjs",
|
|
@@ -74,5 +75,11 @@
|
|
|
74
75
|
"access": "public"
|
|
75
76
|
},
|
|
76
77
|
"author": "arandevcode",
|
|
77
|
-
"license": "MIT"
|
|
78
|
+
"license": "MIT",
|
|
79
|
+
"repository": {
|
|
80
|
+
"type": "git",
|
|
81
|
+
"url": "git+https://github.com/arandevcode/opencode-plugins.git",
|
|
82
|
+
"directory": "opencode-quota-extended"
|
|
83
|
+
},
|
|
84
|
+
"homepage": "https://github.com/arandevcode/opencode-plugins/tree/main/opencode-quota-extended#readme"
|
|
78
85
|
}
|
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.");
|