@leo000001/opencode-quota-sidebar 3.0.1 → 3.0.3
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 +14 -2
- package/CONTRIBUTING.md +4 -1
- package/README.md +210 -514
- package/README.zh-CN.md +337 -0
- package/SECURITY.md +2 -2
- package/assets/OpenCode-Quota-Sidebar.png +0 -0
- package/dist/cost.d.ts +3 -3
- package/dist/cost.js +258 -169
- package/dist/format.js +10 -3
- package/dist/index.js +4 -3
- package/dist/providers/common.d.ts +6 -0
- package/dist/providers/common.js +32 -12
- package/dist/providers/core/anthropic.d.ts +1 -1
- package/dist/providers/core/anthropic.js +43 -39
- package/dist/providers/core/kimi_for_coding.d.ts +1 -1
- package/dist/providers/core/kimi_for_coding.js +44 -64
- package/dist/providers/core/minimax_cn_coding_plan.d.ts +2 -0
- package/dist/providers/core/minimax_cn_coding_plan.js +214 -0
- package/dist/providers/core/zhipu_coding_plan.d.ts +1 -1
- package/dist/providers/core/zhipu_coding_plan.js +41 -61
- package/dist/providers/index.d.ts +3 -3
- package/dist/providers/index.js +5 -5
- package/dist/providers/third_party/rightcode.d.ts +1 -1
- package/dist/providers/third_party/rightcode.js +41 -61
- package/dist/providers/third_party/xyai.d.ts +2 -0
- package/dist/providers/third_party/{xyai_vibe.js → xyai.js} +113 -79
- package/dist/quota.d.ts +2 -2
- package/dist/quota.js +24 -18
- package/dist/quota_render.d.ts +1 -1
- package/dist/quota_render.js +23 -17
- package/dist/storage_parse.js +1 -0
- package/dist/title.js +7 -7
- package/dist/title_apply.js +18 -1
- package/dist/tools.d.ts +13 -8
- package/dist/tools.js +4 -2
- package/dist/tui.tsx +2 -1
- package/dist/tui_helpers.d.ts +2 -1
- package/dist/tui_helpers.js +6 -1
- package/dist/types.d.ts +2 -0
- package/package.json +11 -3
- package/quota-sidebar.config.example.json +45 -45
- package/dist/providers/third_party/buzz.d.ts +0 -2
- package/dist/providers/third_party/buzz.js +0 -156
- package/dist/providers/third_party/xyai_vibe.d.ts +0 -2
package/README.md
CHANGED
|
@@ -3,53 +3,86 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@leo000001/opencode-quota-sidebar)
|
|
4
4
|
[](https://github.com/xihuai18/opencode-quota-sidebar/blob/main/LICENSE)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
[简体中文](./README.zh-CN.md)
|
|
7
|
+
|
|
8
|
+
OpenCode plugin that shows token usage and provider quota in the TUI sidebar, while keeping the shared session title compact and readable across Desktop, Web, and TUI.
|
|
7
9
|
|
|
8
10
|

|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
The screenshot above comes from [`./assets/OpenCode-Quota-Sidebar.png`](./assets/OpenCode-Quota-Sidebar.png) and shows the actual TUI sidebar layout this plugin renders.
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
## What It Does
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
- Renders dedicated `TITLE`, `USAGE`, and `QUOTA` blocks in the TUI sidebar
|
|
17
|
+
- Keeps the shared `session.title` on a compact single line instead of pushing multiline telemetry into every client
|
|
18
|
+
- Aggregates usage for `session`, `day`, `week`, and `month`
|
|
19
|
+
- Supports provider quota/balance fetchers for OpenAI, Copilot, Anthropic, Kimi, Zhipu, MiniMax, RightCode, and XYAI
|
|
20
|
+
- Can include descendant subagent sessions in session-scoped usage/quota totals
|
|
21
|
+
- Exposes `quota_summary` and `quota_show` tools for reports and title toggling
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
## Architecture Overview
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
{
|
|
20
|
-
"plugin": ["@leo000001/opencode-quota-sidebar@2.0.26"]
|
|
21
|
-
}
|
|
22
|
-
```
|
|
25
|
+
This repository is a pure plugin implementation. It does not modify OpenCode core.
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
- Server layer: aggregates usage, fetches quota snapshots, stores state, manages title refresh, and exposes tools
|
|
28
|
+
- TUI layer: renders the sidebar panel UI and reads persisted sidebar-panel payloads
|
|
29
|
+
- Persistence layer: stores global state plus day-partitioned session chunks so historical sessions can render without full rescans
|
|
30
|
+
- Provider adapter layer: maps each provider to a common `QuotaSnapshot` shape through a registry of adapters
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
{
|
|
28
|
-
"plugin": ["@leo000001/opencode-quota-sidebar@2.0.26"]
|
|
29
|
-
}
|
|
30
|
-
```
|
|
32
|
+
The implementation is built on top of `@opencode-ai/plugin` and `@opencode-ai/sdk`.
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
## How It Works
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
This plugin also accepts both `config.providers` and older `provider.list` runtime shapes when discovering provider options.
|
|
36
|
+
This plugin has two display layers:
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
- TUI sidebar panel: renders structured `TITLE`, `USAGE`, and `QUOTA` blocks
|
|
39
|
+
- Shared session title: stays compact so Desktop, Web, and TUI can all read the same title cleanly
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
In `sidebar.titleMode="auto"`, the shared title remains a compact single line. The richer multiline layout is handled by the dedicated TUI plugin instead of being written into `session.title` for every client.
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
Session-scoped aggregation can include descendant subagent sessions when `sidebar.includeChildren=true`. Day/week/month summaries do not merge descendants.
|
|
44
|
+
|
|
45
|
+
## Supported Providers
|
|
46
|
+
|
|
47
|
+
Built-in quota adapters:
|
|
48
|
+
|
|
49
|
+
| Provider | Endpoint family | Auth | Quota shape | Notes |
|
|
50
|
+
| ------------------- | ---------------------------------------------------------- | --------------------- | -------------------------- | --------------------------------------------------------- |
|
|
51
|
+
| OpenAI Codex | `chatgpt.com/backend-api/wham/usage` | OAuth | Multi-window subscription | Reads ChatGPT usage windows such as short-term + weekly |
|
|
52
|
+
| GitHub Copilot | `api.github.com/copilot_internal/user` | OAuth | Monthly subscription | Uses the Copilot internal user endpoint |
|
|
53
|
+
| Anthropic | `api.anthropic.com/api/oauth/usage` | OAuth | Multi-window subscription | Supports plan-based usage windows |
|
|
54
|
+
| Kimi For Coding | `api.kimi.com/coding/v1/usages` | API key | Multi-window subscription | Typically `5h` + weekly windows |
|
|
55
|
+
| Zhipu Coding Plan | `bigmodel.cn/api/monitor/usage/quota/limit` | API key | Token quota | Coding-plan style quota window |
|
|
56
|
+
| MiniMax Coding Plan | `www.minimaxi.com/v1/api/openplatform/coding_plan/remains` | API key | Multi-window subscription | Typically `5h` + weekly windows |
|
|
57
|
+
| RightCode | `www.right.codes/account/summary` | API key | Daily quota and/or balance | Prefix-based subscription matching, with balance fallback |
|
|
58
|
+
| XYAI | `new.xychatai.com/frontend-api/*` | Login -> session auth | Daily balance | Disabled by default, configured in `quota.providers.xyai` |
|
|
59
|
+
|
|
60
|
+
Generic providers without a built-in quota endpoint can still contribute usage totals, but they will not show quota/balance unless an adapter exists.
|
|
61
|
+
|
|
62
|
+
Provider notes:
|
|
63
|
+
|
|
64
|
+
- OpenAI, Copilot, and Anthropic quota support is based on OAuth/session auth, not generic API-key billing endpoints
|
|
65
|
+
- RightCode can show both a daily allowance line and a balance line
|
|
66
|
+
- XYAI requires login credentials in config so the plugin can obtain and cache session auth
|
|
67
|
+
- Copilot quota is supported, but API-equivalent cost is intentionally not shown because runtime pricing is not reliable enough
|
|
68
|
+
|
|
69
|
+
## Display Rules
|
|
70
|
+
|
|
71
|
+
- Sidebar quota lines show providers actually used in the current session and recognized by an adapter
|
|
72
|
+
- `quota_summary` fetches default quota providers even if they were not used in the current session
|
|
73
|
+
- The TUI sidebar reads persisted `sidebarPanel` / usage state first, so historical sessions can render quickly on open or resume
|
|
74
|
+
- Compact-title quota parsing is only a fallback path; the TUI panel prefers persisted structured data
|
|
75
|
+
- `quota_show` toggles title decoration on or off, but the TUI panel remains the main rich display path
|
|
76
|
+
|
|
77
|
+
## Install
|
|
45
78
|
|
|
46
|
-
|
|
79
|
+
OpenCode loads the server plugin from `opencode.json` and the TUI plugin from `tui.json`.
|
|
47
80
|
|
|
48
81
|
`opencode.json`
|
|
49
82
|
|
|
50
83
|
```json
|
|
51
84
|
{
|
|
52
|
-
"plugin": ["
|
|
85
|
+
"plugin": ["@leo000001/opencode-quota-sidebar@latest"]
|
|
53
86
|
}
|
|
54
87
|
```
|
|
55
88
|
|
|
@@ -57,298 +90,121 @@ Add the built server file to your `opencode.json` and the TUI file to your `tui.
|
|
|
57
90
|
|
|
58
91
|
```json
|
|
59
92
|
{
|
|
60
|
-
"plugin": ["
|
|
93
|
+
"plugin": ["@leo000001/opencode-quota-sidebar@latest"]
|
|
61
94
|
}
|
|
62
95
|
```
|
|
63
96
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
- `file:///D:/Lab/opencode-quota-sidebar/dist/index.js`
|
|
67
|
-
- `file:///D:/Lab/opencode-quota-sidebar/dist/tui.tsx`
|
|
68
|
-
|
|
69
|
-
## Supported quota providers
|
|
70
|
-
|
|
71
|
-
| Provider | Endpoint | Auth | Status |
|
|
72
|
-
| --------------- | -------------------------------------- | --------------------- | --------------------------------------- |
|
|
73
|
-
| OpenAI Codex | `chatgpt.com/backend-api/wham/usage` | OAuth (ChatGPT) | Multi-window (short-term + weekly) |
|
|
74
|
-
| GitHub Copilot | `api.github.com/copilot_internal/user` | OAuth | Monthly quota |
|
|
75
|
-
| Kimi For Coding | `api.kimi.com/coding/v1/usages` | API key | Multi-window subscription (5h + weekly) |
|
|
76
|
-
| RightCode | `www.right.codes/account/summary` | API key | Subscription or balance (by prefix) |
|
|
77
|
-
| Buzz | `buzzai.cc/v1/dashboard/billing/*` | API key | Balance only (computed from total-used) |
|
|
78
|
-
| Anthropic | `api.anthropic.com/api/oauth/usage` | OAuth | Multi-window (5h + weekly / plan-based) |
|
|
79
|
-
| XYAI Vibe | `new.xychatai.com/frontend-api/*` | Login -> session auth | Daily balance quota with reset time |
|
|
80
|
-
|
|
81
|
-
Want to add support for another provider (Google Antigravity, Zhipu AI, Firmware AI, etc.)? See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
82
|
-
|
|
83
|
-
## Features
|
|
84
|
-
|
|
85
|
-
- TUI sidebar can render a dedicated block layout instead of stuffing telemetry into the shared title:
|
|
86
|
-
- `TITLE`: clean base session title
|
|
87
|
-
- `USAGE`: compact request/input/output/cache lines such as `R184 I189k O53.2k`, `CR31.4k CW3.2k Cd66%`, `Est $12.8`
|
|
88
|
-
- `QUOTA`: one compact provider group per provider, with indented continuation lines for multi-window quotas or balances
|
|
89
|
-
- while active, the TUI plugin temporarily deactivates the built-in `internal:sidebar-context` block so the custom panel does not duplicate it
|
|
90
|
-
- Shared `session.title` now stays compact in `auto` mode. Desktop, Web UI / `serve`, and TUI all keep the shared title on a compact single line such as `<base> | OAI 5h80 R16:20 W70 R04-03 | RC D88.9/60 B260 | Cd66% | Est$0.12`.
|
|
91
|
-
- TUI panel data is read from persisted day-chunk session state (`usage` + `sidebarPanel`) so entering or resuming a session can render from persistence first; compact-title parsing remains only a defensive fallback.
|
|
92
|
-
- `sidebar.titleMode=multiline` is still available as a legacy fallback when you explicitly want the old multiline title decoration path.
|
|
93
|
-
- `sidebar.titleMode` can force `auto`, `multiline`, or `compact` if the heuristic does not match your workflow.
|
|
94
|
-
- Multi-client caveat: the shared title is still one `session.title` for every client. The new TUI sidebar blocks avoid polluting that shared title, but Desktop/Web still see the compact shared title rather than a sidebar panel.
|
|
95
|
-
- Session-scoped usage/quota can include descendant subagent sessions (enabled by default via `sidebar.includeChildren=true`). Traversal is bounded by `childrenMaxDepth` (default 6), `childrenMaxSessions` (default 128), and `childrenConcurrency` (default 5); truncation is logged when `OPENCODE_QUOTA_DEBUG=1`. Day/week/month ranges never merge children — only session scope does.
|
|
96
|
-
- Toast message can include four sections: `Token Usage`, `Cost as API` (per provider), `Provider Cache` (when provider-level cached ratios are available), and `Quota`
|
|
97
|
-
- Expiry reminders are shown in a separate `Expiry Soon` toast section only for providers with real subscription expiry timestamps, and each session shows that auto-reminder at most once
|
|
98
|
-
- `quota_summary` markdown / toast also include `Cached` summary lines when cache activity is available
|
|
99
|
-
- Quota snapshots are de-duplicated before rendering to avoid repeated provider lines
|
|
100
|
-
- Custom tools:
|
|
101
|
-
- `quota_summary` — generate usage report for session/day/week/month (full markdown report + toast). The markdown report and toast keep the full human-readable wording; they do not switch to compact sidebar tokens.
|
|
102
|
-
- `quota_show` — toggle shared title decoration on/off (state persists across sessions)
|
|
103
|
-
- After startup, titles are restored immediately when persisted display mode is OFF; when persisted display mode is ON, touched titles refresh on startup and the rest update on the next relevant session/message event or when `quota_show` is toggled
|
|
104
|
-
- Quota connectors:
|
|
105
|
-
- OpenAI Codex OAuth (`/backend-api/wham/usage`)
|
|
106
|
-
- GitHub Copilot OAuth (`/copilot_internal/user`)
|
|
107
|
-
- Kimi For Coding API key (`/usages`, built-in `kimi-for-coding` provider)
|
|
108
|
-
- RightCode API key (`/account/summary`)
|
|
109
|
-
- Buzz API key (`/v1/dashboard/billing/subscription` + `/v1/dashboard/billing/usage`)
|
|
110
|
-
- Anthropic Claude OAuth (`/api/oauth/usage`, with beta header)
|
|
111
|
-
- XYAI Vibe account login (`/frontend-api/login` -> cached `share-session` -> `/frontend-api/vibe-code/quota`)
|
|
112
|
-
- OpenAI OAuth quota checks auto-refresh expired access token (using refresh token)
|
|
113
|
-
- Generic API key providers without quota endpoints still show usage aggregation only; built-in adapters such as Kimi For Coding, RightCode, Buzz, and XYAI Vibe also show quota or balance details.
|
|
114
|
-
- Incremental usage aggregation — only processes new messages since last cursor
|
|
115
|
-
- Sidebar token units are adaptive (`k`/`m` with one decimal where applicable)
|
|
116
|
-
|
|
117
|
-
### Kimi For Coding notes
|
|
118
|
-
|
|
119
|
-
- OpenCode's built-in provider ID is `kimi-for-coding` and its runtime base URL is `https://api.kimi.com/coding/v1`.
|
|
120
|
-
- The plugin treats Kimi as a subscription quota source, not a balance source.
|
|
121
|
-
- Quota data is read from `GET https://api.kimi.com/coding/v1/usages`.
|
|
122
|
-
- The current implementation maps the short rolling window in `limits[]` to `5h` and the top-level `usage` block to `Weekly`.
|
|
123
|
-
- Rendering follows the same compact reset formatting as OpenAI: short windows show `Rst MM-DD HH:MM` when they cross days, and longer windows show `Rst MM-DD`.
|
|
124
|
-
|
|
125
|
-
### XYAI Vibe notes
|
|
126
|
-
|
|
127
|
-
- Enable it explicitly under `quota.providers.xyai-vibe.enabled`; it is not enabled by default.
|
|
128
|
-
- Configure login credentials in `quota-sidebar.config.json`, not in source code.
|
|
129
|
-
- The adapter logs in via `POST https://new.xychatai.com/frontend-api/login`, caches the returned `share-session`, and retries quota fetches with that session.
|
|
130
|
-
- Quota data is read from `GET https://new.xychatai.com/frontend-api/vibe-code/quota`.
|
|
131
|
-
- Compact displays show the daily balance and the true reset time when present; expiry stays as secondary report/toast metadata.
|
|
132
|
-
|
|
133
|
-
## Storage layout
|
|
134
|
-
|
|
135
|
-
The plugin stores lightweight global state and date-partitioned session chunks.
|
|
136
|
-
|
|
137
|
-
- Global metadata: `<opencode-data>/quota-sidebar.state.json`
|
|
138
|
-
- `titleEnabled`
|
|
139
|
-
- `sessionDateMap` (sessionID -> `YYYY-MM-DD`)
|
|
140
|
-
- `quotaCache`
|
|
141
|
-
- Session chunks: `<opencode-data>/quota-sidebar-sessions/YYYY/MM/DD.json`
|
|
142
|
-
- per-session title state (`baseTitle`, `lastAppliedTitle`)
|
|
143
|
-
- `createdAt`
|
|
144
|
-
- `parentID` (when the session is a subagent child session)
|
|
145
|
-
- `expiryToastShown` (session-level dedupe for automatic expiry reminders)
|
|
146
|
-
- cached usage summary used by `quota_summary`, including session-level and provider-level `cacheBuckets` for cached-ratio reporting and legacy cache classification
|
|
147
|
-
- `sidebarPanel` cache used by the TUI sidebar plugin (`version`, cached usage, compact quota snapshots`) so `TITLE / USAGE / QUOTA` can render from persisted structure on session open/resume
|
|
148
|
-
- incremental aggregation cursor
|
|
149
|
-
|
|
150
|
-
Notes on cache bucket persistence:
|
|
151
|
-
|
|
152
|
-
- Older cached usage written before `cacheBuckets` existed can only be approximated from top-level `cache_read` / `cache_write` totals.
|
|
153
|
-
- In those legacy cases, mixed read-only + read-write cache traffic may be attributed to a single fallback bucket until the session is recomputed from messages.
|
|
154
|
-
|
|
155
|
-
Example tree:
|
|
156
|
-
|
|
157
|
-
```text
|
|
158
|
-
~/.local/share/opencode/
|
|
159
|
-
quota-sidebar.state.json
|
|
160
|
-
quota-sidebar-sessions/
|
|
161
|
-
2026/
|
|
162
|
-
02/
|
|
163
|
-
23.json
|
|
164
|
-
24.json
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
Sessions older than `retentionDays` (default 730 days / 2 years) are evicted from
|
|
168
|
-
memory on startup. Chunk files remain on disk for historical range scans.
|
|
169
|
-
|
|
170
|
-
## Compatibility
|
|
171
|
-
|
|
172
|
-
- Node.js: >= 18 (for `fetch` + `AbortController`)
|
|
173
|
-
- OpenCode: plugin SDK `@opencode-ai/plugin` ^1.3.5
|
|
174
|
-
- OpenCode config split: if you are on `>=1.2.15`, keep this plugin in `opencode.json` and keep TUI-only keys in `tui.json`.
|
|
97
|
+
For OpenCode `>=1.2.15`, keep server plugins in `opencode.json` and TUI plugins in `tui.json`.
|
|
175
98
|
|
|
176
|
-
##
|
|
99
|
+
## Sidebar Demo
|
|
177
100
|
|
|
178
|
-
|
|
101
|
+
Typical TUI sidebar layout:
|
|
179
102
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
Windows PowerShell example:
|
|
194
|
-
|
|
195
|
-
```powershell
|
|
196
|
-
Remove-Item -Recurse -Force "$HOME\.cache\opencode\node_modules\@leo000001\opencode-quota-sidebar" -ErrorAction SilentlyContinue
|
|
197
|
-
Remove-Item -Recurse -Force "$HOME\node_modules\@leo000001\opencode-quota-sidebar" -ErrorAction SilentlyContinue
|
|
103
|
+
```text
|
|
104
|
+
TITLE
|
|
105
|
+
Fix quota adapter matching
|
|
106
|
+
USAGE
|
|
107
|
+
R184 I189k O53.2k
|
|
108
|
+
CR31.4k CW3.2k Cd66%
|
|
109
|
+
Est $12.8
|
|
110
|
+
QUOTA
|
|
111
|
+
OAI 5h80 R16:20
|
|
112
|
+
W70 R04-03
|
|
113
|
+
Cop M78 R04-01
|
|
114
|
+
RC D$88.9/$60 E02-27
|
|
115
|
+
B260
|
|
198
116
|
```
|
|
199
117
|
|
|
200
|
-
|
|
118
|
+
Compact shared title example:
|
|
201
119
|
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
rm -rf ~/node_modules/@leo000001/opencode-quota-sidebar
|
|
120
|
+
```text
|
|
121
|
+
Fix quota adapter matching | OAI 5h80 R16:20 W70 R04-03 | RC D$88.9/$60 B260 | Cd66% | Est$12.8
|
|
205
122
|
```
|
|
206
123
|
|
|
207
|
-
|
|
124
|
+
Another compact title example with multiple providers:
|
|
208
125
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
```json
|
|
212
|
-
{
|
|
213
|
-
"command": {
|
|
214
|
-
"qday": {
|
|
215
|
-
"description": "Show today's usage and quota",
|
|
216
|
-
"template": "Call tool quota_summary with period=day and toast=true."
|
|
217
|
-
},
|
|
218
|
-
"qweek": {
|
|
219
|
-
"description": "Show this week's usage and quota",
|
|
220
|
-
"template": "Call tool quota_summary with period=week and toast=true."
|
|
221
|
-
},
|
|
222
|
-
"qmonth": {
|
|
223
|
-
"description": "Show this month's usage and quota",
|
|
224
|
-
"template": "Call tool quota_summary with period=month and toast=true."
|
|
225
|
-
},
|
|
226
|
-
"qtoggle": {
|
|
227
|
-
"description": "Toggle sidebar usage display on/off",
|
|
228
|
-
"template": "Call tool quota_show (no arguments, it toggles)."
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
126
|
+
```text
|
|
127
|
+
Add XYAI quota adapter | Ant 5h100 W77 O7d60 | Cop M78 R04-01 | Cd52% | Est$2.34
|
|
232
128
|
```
|
|
233
129
|
|
|
234
|
-
|
|
130
|
+
## Tool Report Demo
|
|
235
131
|
|
|
236
|
-
|
|
132
|
+
Example `quota_summary` markdown output shape:
|
|
237
133
|
|
|
238
|
-
|
|
134
|
+
```md
|
|
135
|
+
## Session Usage
|
|
239
136
|
|
|
240
|
-
-
|
|
241
|
-
|
|
242
|
-
|
|
137
|
+
- Requests: 184
|
|
138
|
+
- Input: 189k
|
|
139
|
+
- Output: 53.2k
|
|
140
|
+
- Cache Read: 31.4k
|
|
141
|
+
- Cache Write: 3.2k
|
|
142
|
+
- Cost as API: $12.8
|
|
243
143
|
|
|
244
|
-
|
|
245
|
-
- `<directory>/quota-sidebar.config.json` (when different from `worktree`)
|
|
246
|
-
- `<worktree>/.opencode/quota-sidebar.config.json`
|
|
247
|
-
- `<directory>/.opencode/quota-sidebar.config.json` (when different from `worktree`)
|
|
144
|
+
## Quota
|
|
248
145
|
|
|
249
|
-
|
|
146
|
+
- OpenAI: 5h 80% (reset 16:20), Weekly 70% (reset 04-03)
|
|
147
|
+
- Copilot: Monthly 78% (reset 04-01)
|
|
148
|
+
- RightCode: Daily $88.9/$60 (exp 02-27), Balance $260
|
|
149
|
+
```
|
|
250
150
|
|
|
251
|
-
|
|
151
|
+
The tool already returns full markdown. Clients should display that report directly instead of replacing it with a short summary.
|
|
252
152
|
|
|
253
|
-
|
|
153
|
+
Sidebar output uses compact tokens. Toasts and markdown reports keep fuller human-readable wording.
|
|
254
154
|
|
|
255
|
-
|
|
155
|
+
## Why The TUI Panel Exists
|
|
256
156
|
|
|
257
|
-
|
|
157
|
+
OpenCode renders the sidebar title as plain text inside a single styled title field. That means the shared title is great for compact telemetry, but not ideal for a rich multi-section layout.
|
|
258
158
|
|
|
259
|
-
|
|
260
|
-
2. `<worktree>/quota-sidebar.config.json`
|
|
261
|
-
3. `<directory>/quota-sidebar.config.json`
|
|
262
|
-
4. `<worktree>/.opencode/quota-sidebar.config.json`
|
|
263
|
-
5. `<directory>/.opencode/quota-sidebar.config.json`
|
|
264
|
-
6. `OPENCODE_QUOTA_CONFIG`
|
|
159
|
+
This plugin therefore uses:
|
|
265
160
|
|
|
266
|
-
|
|
161
|
+
- shared compact titles for cross-client compatibility
|
|
162
|
+
- a dedicated TUI sidebar panel for the detailed block layout
|
|
267
163
|
|
|
268
|
-
|
|
164
|
+
That split avoids polluting Desktop/Web titles while still giving TUI users a readable quota dashboard.
|
|
269
165
|
|
|
270
|
-
|
|
166
|
+
## Abbreviations
|
|
271
167
|
|
|
272
|
-
|
|
168
|
+
Usage tokens:
|
|
273
169
|
|
|
274
|
-
|
|
170
|
+
- `R`: requests
|
|
171
|
+
- `I`: input tokens
|
|
172
|
+
- `O`: output tokens, including reasoning tokens
|
|
173
|
+
- `CR`: cache read tokens
|
|
174
|
+
- `CW`: cache write tokens
|
|
175
|
+
- `Cd`: cached ratio / cache coverage
|
|
176
|
+
- `Est`: API-equivalent cost estimate
|
|
275
177
|
|
|
276
|
-
|
|
277
|
-
- `sidebar.width`: `36` (clamped to `20`-`60`)
|
|
278
|
-
- `sidebar.titleMode`: `auto` (`auto`/`multiline`/`compact`)
|
|
279
|
-
- `sidebar.multilineTitle`: `true` (legacy compatibility field; title style is now chosen automatically)
|
|
280
|
-
- `sidebar.showCost`: `true`
|
|
281
|
-
- `sidebar.showQuota`: `true`
|
|
282
|
-
- `sidebar.wrapQuotaLines`: `true`
|
|
283
|
-
- `sidebar.includeChildren`: `true`
|
|
284
|
-
- `sidebar.childrenMaxDepth`: `6` (clamped to `1`-`32`)
|
|
285
|
-
- `sidebar.childrenMaxSessions`: `128` (clamped to `0`-`2000`)
|
|
286
|
-
- `sidebar.childrenConcurrency`: `5` (clamped to `1`-`10`)
|
|
287
|
-
- `sidebar.desktopCompact.recentRequests`: `50` (compact single-line titles)
|
|
288
|
-
- `sidebar.desktopCompact.recentMinutes`: `60` (compact single-line titles)
|
|
178
|
+
Quota tokens:
|
|
289
179
|
|
|
290
|
-
|
|
180
|
+
- `OAI`: OpenAI
|
|
181
|
+
- `Cop`: GitHub Copilot
|
|
182
|
+
- `Ant`: Anthropic
|
|
183
|
+
- `RC`: RightCode
|
|
184
|
+
- `B`: balance
|
|
185
|
+
- `D`: daily window
|
|
186
|
+
- `W`: weekly window
|
|
187
|
+
- `M`: monthly window
|
|
188
|
+
- `R16:20`: reset at `16:20`
|
|
189
|
+
- `R04-03`: reset on `04-03`
|
|
190
|
+
- `E02-27`: expiry on `02-27`
|
|
291
191
|
|
|
292
|
-
|
|
293
|
-
- `quota.includeOpenAI`: `true`
|
|
294
|
-
- `quota.includeCopilot`: `true`
|
|
295
|
-
- `quota.includeAnthropic`: `true`
|
|
296
|
-
- `quota.providers`: `{}` (per-adapter switches and adapter-specific config, for example `rightcode.enabled` or `xyai-vibe.login.username/password`)
|
|
297
|
-
- `quota.refreshAccessToken`: `false`
|
|
298
|
-
- `quota.requestTimeoutMs`: `8000` (clamped to `>=1000`)
|
|
192
|
+
Example compact quota fragments:
|
|
299
193
|
|
|
300
|
-
|
|
194
|
+
- `OAI 5h80 R16:20`: OpenAI short window, 80% remaining, resets at `16:20`
|
|
195
|
+
- `Cop M78 R04-01`: Copilot monthly quota, 78% remaining, resets on `04-01`
|
|
196
|
+
- `RC D$88.9/$60 E02-27 B260`: RightCode daily quota plus balance
|
|
301
197
|
|
|
302
|
-
|
|
303
|
-
- `retentionDays`: `730`
|
|
198
|
+
## Config
|
|
304
199
|
|
|
305
|
-
|
|
200
|
+
Recommended config file locations:
|
|
306
201
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
"width": 36,
|
|
312
|
-
"titleMode": "auto",
|
|
313
|
-
"multilineTitle": true,
|
|
314
|
-
"showCost": true,
|
|
315
|
-
"showQuota": true,
|
|
316
|
-
"wrapQuotaLines": true,
|
|
317
|
-
"includeChildren": true,
|
|
318
|
-
"childrenMaxDepth": 6,
|
|
319
|
-
"childrenMaxSessions": 128,
|
|
320
|
-
"childrenConcurrency": 5,
|
|
321
|
-
"desktopCompact": {
|
|
322
|
-
"recentRequests": 50,
|
|
323
|
-
"recentMinutes": 60
|
|
324
|
-
}
|
|
325
|
-
},
|
|
326
|
-
"quota": {
|
|
327
|
-
"refreshMs": 300000,
|
|
328
|
-
"includeOpenAI": true,
|
|
329
|
-
"includeCopilot": true,
|
|
330
|
-
"includeAnthropic": true,
|
|
331
|
-
"providers": {
|
|
332
|
-
"buzz": {
|
|
333
|
-
"enabled": true
|
|
334
|
-
},
|
|
335
|
-
"rightcode": {
|
|
336
|
-
"enabled": true
|
|
337
|
-
}
|
|
338
|
-
},
|
|
339
|
-
"refreshAccessToken": false,
|
|
340
|
-
"requestTimeoutMs": 8000
|
|
341
|
-
},
|
|
342
|
-
"toast": {
|
|
343
|
-
"durationMs": 12000
|
|
344
|
-
},
|
|
345
|
-
"retentionDays": 730
|
|
346
|
-
}
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
### Common minimal configs
|
|
202
|
+
- `~/.config/opencode/quota-sidebar.config.json`
|
|
203
|
+
- `<worktree>/quota-sidebar.config.json`
|
|
204
|
+
- `<worktree>/.opencode/quota-sidebar.config.json`
|
|
205
|
+
- `OPENCODE_QUOTA_CONFIG=/absolute/path/to/config.json`
|
|
350
206
|
|
|
351
|
-
|
|
207
|
+
Minimal example:
|
|
352
208
|
|
|
353
209
|
```json
|
|
354
210
|
{
|
|
@@ -362,268 +218,108 @@ Keep the shared title compact and let TUI render the structured panel:
|
|
|
362
218
|
}
|
|
363
219
|
```
|
|
364
220
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
```json
|
|
368
|
-
{
|
|
369
|
-
"quota": {
|
|
370
|
-
"providers": {
|
|
371
|
-
"xyai-vibe": {
|
|
372
|
-
"enabled": true,
|
|
373
|
-
"login": {
|
|
374
|
-
"username": "your-account",
|
|
375
|
-
"password": "your-password"
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
```
|
|
221
|
+
See [`quota-sidebar.config.example.json`](./quota-sidebar.config.example.json) for a fuller config example.
|
|
382
222
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
- `sidebar.showCost` controls API-cost visibility in the TUI `USAGE` block, the compact shared title, `quota_summary` markdown report, and toast message.
|
|
386
|
-
- `quota_summary` follows the same reset compaction rules for short windows in its subscription section (`5h` / `1d` / `Daily` show time, long windows show date, RightCode `Exp` stays date-only).
|
|
387
|
-
- `sidebar.width` is measured in terminal cells. CJK/emoji truncation is best-effort to avoid sidebar overflow.
|
|
388
|
-
- `sidebar.titleMode` defaults to `auto`: the shared `session.title` stays compact for Desktop, Web UI / `serve`, and TUI alike. The rich TUI layout comes from the dedicated TUI plugin slots instead of a multiline shared title. Use `multiline` only if you explicitly want the legacy decorated-title path, or `compact` to force compact titles everywhere.
|
|
389
|
-
- The TUI plugin renders `TITLE`, `USAGE`, and `QUOTA` blocks in the sidebar and temporarily disables the built-in `internal:sidebar-context` block while it is active.
|
|
390
|
-
- The shared `session.title` is still one string per session for all clients. TUI sidebar blocks avoid polluting that title, but Desktop/Web still see the compact shared title rather than a TUI panel.
|
|
391
|
-
- `sidebar.multilineTitle` is kept for backward compatibility, but `sidebar.titleMode` now controls the active policy.
|
|
392
|
-
- `sidebar.wrapQuotaLines` controls quota line wrapping and continuation indentation (default: `true`).
|
|
393
|
-
- `sidebar.includeChildren` controls whether session-scoped usage/quota includes descendant subagent sessions (default: `true`).
|
|
394
|
-
- `sidebar.childrenMaxDepth` limits how many levels of nested subagents are traversed (default: `6`, clamped 1–32).
|
|
395
|
-
- `sidebar.childrenMaxSessions` caps the total number of descendant sessions aggregated (default: `128`, clamped 0–2000).
|
|
396
|
-
- `sidebar.childrenConcurrency` controls parallel fetches for descendant session messages (default: `5`, clamped 1–10).
|
|
397
|
-
- `sidebar.desktopCompact.recentRequests` and `sidebar.desktopCompact.recentMinutes` control which recently used providers remain visible in compact single-line titles.
|
|
398
|
-
- `sidebar.desktopCompact.recentRequests` and `sidebar.desktopCompact.recentMinutes` only control provider filtering inside compact titles; they do not affect the dedicated TUI sidebar panel.
|
|
399
|
-
- `output` includes reasoning tokens (`output = tokens.output + tokens.reasoning`). Reasoning is not rendered as a separate line.
|
|
400
|
-
- API cost bills reasoning tokens at the output rate (same as completion tokens).
|
|
401
|
-
- API cost is computed from OpenCode model pricing metadata, not from `message.cost`. This keeps subscription-backed providers such as OpenAI OAuth usable for API-equivalent cost estimation even when OpenCode's measured cost is `0`.
|
|
402
|
-
- When OpenCode exposes a long-context tier like `context_over_200k`, the plugin uses that premium rate for the whole request once `input > 200000`, matching OpenCode's current pricing schema.
|
|
403
|
-
- `quota.providers` is the extensible per-adapter switch map.
|
|
404
|
-
- If API Cost is `$0.00`, it usually means the model/provider has no pricing mapping in OpenCode at the moment, so equivalent API cost cannot be estimated.
|
|
405
|
-
- Usage chunks cache both measured `cost` and computed `apiCost`. `quota_summary` (`/qday`, `/qweek`, `/qmonth`) recomputes range totals from session messages so period filtering follows message completion time; refreshed full-session usage may then be persisted back into day chunks when billing-cache refresh is needed.
|
|
406
|
-
|
|
407
|
-
### Buzz provider example
|
|
408
|
-
|
|
409
|
-
Buzz matching is based on the provider `baseURL`, similar to RightCode. Any OpenAI-compatible provider that points at `https://buzzai.cc` will be recognized by the Buzz adapter and rendered as a balance-only quota source.
|
|
410
|
-
|
|
411
|
-
Provider options example:
|
|
223
|
+
Important config notes:
|
|
412
224
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
```
|
|
225
|
+
- `sidebar.titleMode`: `auto`, `compact`, or `multiline`
|
|
226
|
+
- `sidebar.showCost`: controls API-equivalent cost in sidebar, title, markdown report, and toast
|
|
227
|
+
- `sidebar.wrapQuotaLines`: wraps long quota lines with indentation instead of dropping fields
|
|
228
|
+
- `sidebar.includeChildren`: includes descendant subagent sessions for `period=session`
|
|
229
|
+
- `quota.providers.xyai.enabled`: must be explicitly enabled if you want XYAI quota
|
|
230
|
+
- `quota.providers.xyai.login.username/password`: used to fetch and refresh XYAI session auth
|
|
422
231
|
|
|
423
|
-
|
|
232
|
+
Config is layered. The later source overrides the earlier one:
|
|
424
233
|
|
|
425
|
-
|
|
234
|
+
1. global config
|
|
235
|
+
2. worktree config
|
|
236
|
+
3. directory config
|
|
237
|
+
4. worktree `.opencode` config
|
|
238
|
+
5. directory `.opencode` config
|
|
239
|
+
6. `OPENCODE_QUOTA_CONFIG`
|
|
426
240
|
|
|
427
|
-
|
|
428
|
-
Buzz B¥10.17
|
|
429
|
-
```
|
|
241
|
+
## Persistence And Aggregation
|
|
430
242
|
|
|
431
|
-
|
|
243
|
+
The plugin stores:
|
|
432
244
|
|
|
433
|
-
|
|
245
|
+
- global state in `<opencode-data>/quota-sidebar.state.json`
|
|
246
|
+
- session chunks in `<opencode-data>/quota-sidebar-sessions/YYYY/MM/DD.json`
|
|
434
247
|
|
|
435
|
-
|
|
248
|
+
Those persisted chunks keep title state, cached usage, sidebar-panel payloads, and quota cache data. This lets the TUI sidebar render from stored structured state on session open/resume instead of depending entirely on live message scans.
|
|
436
249
|
|
|
437
|
-
|
|
250
|
+
Usage aggregation is incremental. The plugin tracks a cursor per session and processes only new messages when possible. If message history changes in a way that invalidates the incremental view, it can rescan and refresh persisted usage.
|
|
438
251
|
|
|
439
|
-
|
|
252
|
+
## Tools
|
|
440
253
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
Fix quota adapter matching
|
|
444
|
-
USAGE
|
|
445
|
-
R184 I189k O53.2k
|
|
446
|
-
CR31.4k CW3.2k Cd66%
|
|
447
|
-
Est $12.8
|
|
448
|
-
QUOTA
|
|
449
|
-
OAI 5h80 R16:20
|
|
450
|
-
W70 R04-03
|
|
451
|
-
Cop M78 R04-01
|
|
452
|
-
RC D$88.9/$60 E02-27
|
|
453
|
-
B260
|
|
454
|
-
```
|
|
254
|
+
- `quota_summary`: shows usage and quota for `session`, `day`, `week`, or `month`
|
|
255
|
+
- `quota_show`: toggles title decoration on or off
|
|
455
256
|
|
|
456
|
-
|
|
257
|
+
Behavior notes:
|
|
457
258
|
|
|
458
|
-
|
|
259
|
+
- `quota_summary` returns the full markdown report body
|
|
260
|
+
- `quota_summary` can show a toast in addition to returning markdown
|
|
261
|
+
- `quota_summary(includeChildren=true)` only changes `period=session`
|
|
262
|
+
- `quota_show(enabled=true|false)` can explicitly force a state instead of toggling
|
|
459
263
|
|
|
460
|
-
|
|
461
|
-
{
|
|
462
|
-
"sidebar": {
|
|
463
|
-
"titleMode": "compact"
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
```
|
|
264
|
+
Example command aliases:
|
|
467
265
|
|
|
468
266
|
```json
|
|
469
267
|
{
|
|
470
|
-
"
|
|
471
|
-
"
|
|
268
|
+
"command": {
|
|
269
|
+
"qday": {
|
|
270
|
+
"description": "Show today's usage and quota",
|
|
271
|
+
"template": "Call tool quota_summary with period=day and toast=true."
|
|
272
|
+
},
|
|
273
|
+
"qweek": {
|
|
274
|
+
"description": "Show this week's usage and quota",
|
|
275
|
+
"template": "Call tool quota_summary with period=week and toast=true."
|
|
276
|
+
},
|
|
277
|
+
"qmonth": {
|
|
278
|
+
"description": "Show this month's usage and quota",
|
|
279
|
+
"template": "Call tool quota_summary with period=month and toast=true."
|
|
280
|
+
},
|
|
281
|
+
"qtoggle": {
|
|
282
|
+
"description": "Toggle sidebar usage display on/off",
|
|
283
|
+
"template": "Call tool quota_show (no arguments, it toggles)."
|
|
284
|
+
}
|
|
472
285
|
}
|
|
473
286
|
}
|
|
474
287
|
```
|
|
475
288
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
```text
|
|
479
|
-
(no quota block)
|
|
480
|
-
```
|
|
481
|
-
|
|
482
|
-
1 provider, 1 window (fits):
|
|
483
|
-
|
|
484
|
-
```text
|
|
485
|
-
Cop M78 R04-01
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
1 provider, multi-window (for example OpenAI 5h + Weekly):
|
|
489
|
-
|
|
490
|
-
```text
|
|
491
|
-
OAI 5h78 R05:05 W73 R03-12
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
1 provider, multi-window on narrow width:
|
|
495
|
-
|
|
496
|
-
```text
|
|
497
|
-
OAI 5h78 R05:05
|
|
498
|
-
W73 R03-12
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
1 provider, short window crossing into the next day:
|
|
502
|
-
|
|
503
|
-
```text
|
|
504
|
-
Ant 5h0 R03-10 01:00 W46 R03-15
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
2+ providers (even if each provider is single-window):
|
|
508
|
-
|
|
509
|
-
```text
|
|
510
|
-
OAI 5h78 R05:05
|
|
511
|
-
Cop M78 R04-01
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
2+ providers mixed (multi-window + single-window):
|
|
289
|
+
## Development
|
|
515
290
|
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
2+ providers mixed (window providers + Buzz balance):
|
|
522
|
-
|
|
523
|
-
```text
|
|
524
|
-
OAI 5h78 R05:05
|
|
525
|
-
Cop M78 R04-01
|
|
526
|
-
Buzz B¥10.2
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
Balance-style quota:
|
|
530
|
-
|
|
531
|
-
```text
|
|
532
|
-
RC B260
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
Buzz balance quota:
|
|
536
|
-
|
|
537
|
-
```text
|
|
538
|
-
Buzz B¥10.17
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
Multi-detail quota (window + balance):
|
|
542
|
-
|
|
543
|
-
```text
|
|
544
|
-
RC D$88.9/$60 E02-27 B260
|
|
291
|
+
```bash
|
|
292
|
+
npm install
|
|
293
|
+
npm run build
|
|
294
|
+
npm test
|
|
545
295
|
```
|
|
546
296
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
```text
|
|
550
|
-
Ant 5h80
|
|
551
|
-
Cop unavailable
|
|
552
|
-
OAI ?
|
|
553
|
-
```
|
|
297
|
+
For local development, load:
|
|
554
298
|
|
|
555
|
-
|
|
299
|
+
- `file:///ABSOLUTE/PATH/opencode-quota-sidebar/dist/index.js` in `opencode.json`
|
|
300
|
+
- `file:///ABSOLUTE/PATH/opencode-quota-sidebar/dist/tui.tsx` in `tui.json`
|
|
556
301
|
|
|
557
|
-
|
|
302
|
+
On Windows, use forward slashes in `file:///` URLs.
|
|
558
303
|
|
|
559
|
-
|
|
560
|
-
<base> | OAI 5h80 R16:20 W70 R04-03 | Cop M78 R04-01 | RC D88.9/60 B260 | Buzz B¥10.2 | Cd66% | Est$0.12
|
|
561
|
-
```
|
|
304
|
+
## Compatibility And Caveats
|
|
562
305
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
-
|
|
566
|
-
-
|
|
567
|
-
-
|
|
568
|
-
-
|
|
569
|
-
- `B260` / `B¥10.2` = balance
|
|
570
|
-
- `Cd66%` = cached ratio (`cache.read / (input + cache.read)`)
|
|
571
|
-
- `Est$0.12` = equivalent API cost estimate
|
|
572
|
-
- Compact shared titles omit `R/I/O/CR/CW`; the dedicated TUI sidebar keeps the richer `TITLE / USAGE / QUOTA` breakdown.
|
|
573
|
-
- Order is `base | quota... | usage-summary` for compact shared titles.
|
|
574
|
-
|
|
575
|
-
`quota_summary` also supports an optional `includeChildren` flag (only effective for `period=session`) to override the config per call. For `day`/`week`/`month` periods, children are never merged — each session is counted independently.
|
|
576
|
-
|
|
577
|
-
## Billing cache behavior
|
|
578
|
-
|
|
579
|
-
- Cached per-session usage stores token totals, measured `cost`, computed `apiCost`, provider breakdowns, and the incremental cursor.
|
|
580
|
-
- Session-scoped sidebar aggregation can merge descendant subagents when `sidebar.includeChildren=true` (default). Measured `cost` stays aligned with the root session's OpenCode `message.cost`, while API-equivalent cost still includes descendant usage.
|
|
581
|
-
- Range tools such as `/qday`, `/qweek`, and `/qmonth` do not merge children. They aggregate each session independently across the selected time window.
|
|
582
|
-
- When API-cost logic changes, the plugin bumps an internal billing-cache version so historical range reports are recomputed with the new rules the next time they are queried.
|
|
583
|
-
|
|
584
|
-
## Debug logging
|
|
585
|
-
|
|
586
|
-
Set `OPENCODE_QUOTA_DEBUG=1` to enable debug logging to stderr. This logs:
|
|
587
|
-
|
|
588
|
-
- Chunk I/O operations
|
|
589
|
-
- Auth refresh attempts and failures
|
|
590
|
-
- Session eviction counts
|
|
591
|
-
- Symlink write refusals
|
|
592
|
-
|
|
593
|
-
## Security & privacy notes
|
|
594
|
-
|
|
595
|
-
- The plugin reads OpenCode credentials from `<opencode-data>/auth.json`.
|
|
596
|
-
- If enabled, quota checks call external endpoints:
|
|
597
|
-
- OpenAI Codex: `https://chatgpt.com/backend-api/wham/usage`
|
|
598
|
-
- GitHub Copilot: `https://api.github.com/copilot_internal/user`
|
|
599
|
-
- Kimi For Coding: `https://api.kimi.com/coding/v1/usages`
|
|
600
|
-
- RightCode: `https://www.right.codes/account/summary`
|
|
601
|
-
- Buzz: `https://buzzai.cc/v1/dashboard/billing/subscription` and `https://buzzai.cc/v1/dashboard/billing/usage`
|
|
602
|
-
- Anthropic: `https://api.anthropic.com/api/oauth/usage`
|
|
603
|
-
- **Screen-sharing warning**: Session titles and toasts surface usage/quota
|
|
604
|
-
information. If you are screen-sharing or recording, consider toggling the
|
|
605
|
-
sidebar display off (`/qtoggle` or `quota_show` tool) to avoid leaking
|
|
606
|
-
subscription details.
|
|
607
|
-
- State is persisted under `<opencode-data>/quota-sidebar.state.json` and
|
|
608
|
-
`<opencode-data>/quota-sidebar-sessions/` (see Storage layout).
|
|
609
|
-
- OpenAI OAuth token refresh is disabled by default; set
|
|
610
|
-
`quota.refreshAccessToken=true` if you want the plugin to refresh access
|
|
611
|
-
tokens when expired.
|
|
612
|
-
- Anthropic quota currently uses a beta/internal-style OAuth usage endpoint and
|
|
613
|
-
request header; response fields may change without notice.
|
|
614
|
-
- Kimi For Coding quota uses the current `/usages` response shape exposed by the Kimi coding service; if Kimi changes that payload, window parsing may need to be updated.
|
|
615
|
-
- State/chunk file writes refuse to write through symlinked targets (best-effort defense-in-depth).
|
|
616
|
-
- The `OPENCODE_QUOTA_DATA_HOME` env var overrides the OpenCode data directory
|
|
617
|
-
path (for testing); do not set this in production.
|
|
618
|
-
- The `OPENCODE_QUOTA_CONFIG_HOME` env var overrides global config directory
|
|
619
|
-
lookup (`<config-home>/opencode`).
|
|
620
|
-
- The `OPENCODE_QUOTA_CONFIG` env var points to an explicit config file and
|
|
621
|
-
applies as the highest-priority override.
|
|
306
|
+
- Node.js `>=18`
|
|
307
|
+
- OpenCode plugin SDK `@opencode-ai/plugin` / `@opencode-ai/sdk` `^1.3.5`
|
|
308
|
+
- For OpenCode `>=1.2.15`, TUI config belongs in `tui.json`
|
|
309
|
+
- The shared title is still one `session.title` value for all clients
|
|
310
|
+
- The plugin avoids ANSI styling in sidebar titles to keep resize behavior stable
|
|
311
|
+
- Some providers expose true quota windows, others only expose balance data
|
|
622
312
|
|
|
623
313
|
## Contributing
|
|
624
314
|
|
|
625
|
-
|
|
315
|
+
- Changelog: [CHANGELOG.md](./CHANGELOG.md)
|
|
316
|
+
- Adapter and architecture notes: [CONTRIBUTING.md](./CONTRIBUTING.md)
|
|
317
|
+
- Security policy: [SECURITY.md](./SECURITY.md)
|
|
626
318
|
|
|
627
|
-
##
|
|
319
|
+
## Documentation Navigation
|
|
628
320
|
|
|
629
|
-
|
|
321
|
+
- English README: [`README.md`](./README.md)
|
|
322
|
+
- Simplified Chinese README: [`README.zh-CN.md`](./README.zh-CN.md)
|
|
323
|
+
- Changelog: [`CHANGELOG.md`](./CHANGELOG.md)
|
|
324
|
+
- Contributing guide: [`CONTRIBUTING.md`](./CONTRIBUTING.md)
|
|
325
|
+
- Security policy: [`SECURITY.md`](./SECURITY.md)
|