@slkiser/opencode-quota 3.1.4 → 3.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.
Files changed (133) hide show
  1. package/README.md +256 -559
  2. package/dist/lib/anthropic.js +1 -1
  3. package/dist/lib/anthropic.js.map +1 -1
  4. package/dist/lib/cache.d.ts +17 -27
  5. package/dist/lib/cache.d.ts.map +1 -1
  6. package/dist/lib/cache.js +62 -65
  7. package/dist/lib/cache.js.map +1 -1
  8. package/dist/lib/config-file-utils.d.ts +12 -0
  9. package/dist/lib/config-file-utils.d.ts.map +1 -1
  10. package/dist/lib/config-file-utils.js +23 -0
  11. package/dist/lib/config-file-utils.js.map +1 -1
  12. package/dist/lib/config.d.ts +16 -3
  13. package/dist/lib/config.d.ts.map +1 -1
  14. package/dist/lib/config.js +448 -214
  15. package/dist/lib/config.js.map +1 -1
  16. package/dist/lib/copilot.d.ts.map +1 -1
  17. package/dist/lib/copilot.js +3 -2
  18. package/dist/lib/copilot.js.map +1 -1
  19. package/dist/lib/entries.d.ts +6 -2
  20. package/dist/lib/entries.d.ts.map +1 -1
  21. package/dist/lib/format-utils.d.ts.map +1 -1
  22. package/dist/lib/format-utils.js +3 -2
  23. package/dist/lib/format-utils.js.map +1 -1
  24. package/dist/lib/format.d.ts +2 -1
  25. package/dist/lib/format.d.ts.map +1 -1
  26. package/dist/lib/format.js +12 -6
  27. package/dist/lib/format.js.map +1 -1
  28. package/dist/lib/google-gemini-cli-companion.d.ts +29 -0
  29. package/dist/lib/google-gemini-cli-companion.d.ts.map +1 -0
  30. package/dist/lib/google-gemini-cli-companion.js +166 -0
  31. package/dist/lib/google-gemini-cli-companion.js.map +1 -0
  32. package/dist/lib/google-gemini-cli.d.ts +48 -0
  33. package/dist/lib/google-gemini-cli.d.ts.map +1 -0
  34. package/dist/lib/google-gemini-cli.js +404 -0
  35. package/dist/lib/google-gemini-cli.js.map +1 -0
  36. package/dist/lib/init-installer.d.ts +2 -1
  37. package/dist/lib/init-installer.d.ts.map +1 -1
  38. package/dist/lib/init-installer.js +10 -6
  39. package/dist/lib/init-installer.js.map +1 -1
  40. package/dist/lib/opencode-go.js +1 -1
  41. package/dist/lib/opencode-go.js.map +1 -1
  42. package/dist/lib/provider-metadata.d.ts +2 -1
  43. package/dist/lib/provider-metadata.d.ts.map +1 -1
  44. package/dist/lib/provider-metadata.js +27 -0
  45. package/dist/lib/provider-metadata.js.map +1 -1
  46. package/dist/lib/quota-format-style.d.ts +21 -0
  47. package/dist/lib/quota-format-style.d.ts.map +1 -0
  48. package/dist/lib/quota-format-style.js +38 -0
  49. package/dist/lib/quota-format-style.js.map +1 -0
  50. package/dist/lib/quota-render-data.d.ts +4 -12
  51. package/dist/lib/quota-render-data.d.ts.map +1 -1
  52. package/dist/lib/quota-render-data.js +83 -70
  53. package/dist/lib/quota-render-data.js.map +1 -1
  54. package/dist/lib/quota-runtime-context.d.ts +43 -0
  55. package/dist/lib/quota-runtime-context.d.ts.map +1 -0
  56. package/dist/lib/quota-runtime-context.js +61 -0
  57. package/dist/lib/quota-runtime-context.js.map +1 -0
  58. package/dist/lib/quota-state.d.ts +21 -0
  59. package/dist/lib/quota-state.d.ts.map +1 -0
  60. package/dist/lib/quota-state.js +228 -0
  61. package/dist/lib/quota-state.js.map +1 -0
  62. package/dist/lib/quota-status.d.ts +16 -0
  63. package/dist/lib/quota-status.d.ts.map +1 -1
  64. package/dist/lib/quota-status.js +63 -17
  65. package/dist/lib/quota-status.js.map +1 -1
  66. package/dist/lib/toast-format-grouped.d.ts.map +1 -1
  67. package/dist/lib/toast-format-grouped.js +5 -3
  68. package/dist/lib/toast-format-grouped.js.map +1 -1
  69. package/dist/lib/tui-config-diagnostics.d.ts +7 -2
  70. package/dist/lib/tui-config-diagnostics.d.ts.map +1 -1
  71. package/dist/lib/tui-config-diagnostics.js +27 -8
  72. package/dist/lib/tui-config-diagnostics.js.map +1 -1
  73. package/dist/lib/tui-runtime.d.ts +1 -2
  74. package/dist/lib/tui-runtime.d.ts.map +1 -1
  75. package/dist/lib/tui-runtime.js +24 -17
  76. package/dist/lib/tui-runtime.js.map +1 -1
  77. package/dist/lib/tui-sidebar-format.d.ts.map +1 -1
  78. package/dist/lib/tui-sidebar-format.js +2 -10
  79. package/dist/lib/tui-sidebar-format.js.map +1 -1
  80. package/dist/lib/types.d.ts +51 -9
  81. package/dist/lib/types.d.ts.map +1 -1
  82. package/dist/lib/types.js +2 -1
  83. package/dist/lib/types.js.map +1 -1
  84. package/dist/plugin.d.ts.map +1 -1
  85. package/dist/plugin.js +448 -242
  86. package/dist/plugin.js.map +1 -1
  87. package/dist/providers/alibaba-coding-plan.d.ts.map +1 -1
  88. package/dist/providers/alibaba-coding-plan.js +0 -16
  89. package/dist/providers/alibaba-coding-plan.js.map +1 -1
  90. package/dist/providers/anthropic.d.ts.map +1 -1
  91. package/dist/providers/anthropic.js +15 -29
  92. package/dist/providers/anthropic.js.map +1 -1
  93. package/dist/providers/copilot.d.ts.map +1 -1
  94. package/dist/providers/copilot.js +27 -53
  95. package/dist/providers/copilot.js.map +1 -1
  96. package/dist/providers/cursor.d.ts.map +1 -1
  97. package/dist/providers/cursor.js +38 -79
  98. package/dist/providers/cursor.js.map +1 -1
  99. package/dist/providers/google-gemini-cli.d.ts +3 -0
  100. package/dist/providers/google-gemini-cli.d.ts.map +1 -0
  101. package/dist/providers/google-gemini-cli.js +83 -0
  102. package/dist/providers/google-gemini-cli.js.map +1 -0
  103. package/dist/providers/kimi-code.d.ts.map +1 -1
  104. package/dist/providers/kimi-code.js +3 -15
  105. package/dist/providers/kimi-code.js.map +1 -1
  106. package/dist/providers/minimax-coding-plan.d.ts.map +1 -1
  107. package/dist/providers/minimax-coding-plan.js +3 -17
  108. package/dist/providers/minimax-coding-plan.js.map +1 -1
  109. package/dist/providers/nanogpt.d.ts.map +1 -1
  110. package/dist/providers/nanogpt.js +23 -42
  111. package/dist/providers/nanogpt.js.map +1 -1
  112. package/dist/providers/openai.d.ts.map +1 -1
  113. package/dist/providers/openai.js +6 -23
  114. package/dist/providers/openai.js.map +1 -1
  115. package/dist/providers/qwen-code.d.ts.map +1 -1
  116. package/dist/providers/qwen-code.js +7 -23
  117. package/dist/providers/qwen-code.js.map +1 -1
  118. package/dist/providers/registry.d.ts.map +1 -1
  119. package/dist/providers/registry.js +2 -0
  120. package/dist/providers/registry.js.map +1 -1
  121. package/dist/providers/result-helpers.d.ts +2 -2
  122. package/dist/providers/result-helpers.d.ts.map +1 -1
  123. package/dist/providers/result-helpers.js +7 -2
  124. package/dist/providers/result-helpers.js.map +1 -1
  125. package/dist/providers/synthetic.d.ts.map +1 -1
  126. package/dist/providers/synthetic.js +5 -14
  127. package/dist/providers/synthetic.js.map +1 -1
  128. package/dist/providers/zai.d.ts.map +1 -1
  129. package/dist/providers/zai.js +6 -28
  130. package/dist/providers/zai.js.map +1 -1
  131. package/dist/tui.d.ts.map +1 -1
  132. package/dist/tui.tsx +1 -15
  133. package/package.json +2 -1
package/README.md CHANGED
@@ -1,90 +1,46 @@
1
- # OpenCode Quota
2
-
3
- [![npm version](https://img.shields.io/npm/v/%40slkiser%2Fopencode-quota)](https://www.npmjs.com/package/@slkiser/opencode-quota)
4
- [![npm downloads](https://img.shields.io/npm/dm/%40slkiser%2Fopencode-quota)](https://www.npmjs.com/package/@slkiser/opencode-quota)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
6
- [![CI](https://img.shields.io/github/actions/workflow/status/slkiser/opencode-quota/ci.yml?branch=main&label=CI)](https://github.com/slkiser/opencode-quota/actions/workflows/ci.yml)
7
- [![Node >=18](https://img.shields.io/badge/node-%3E%3D18-339933)](./package.json)
8
-
9
- `opencode-quota` adds usage quota and token visibility to OpenCode with zero context-window pollution.
10
-
11
- What you get:
12
-
13
- - TUI sidebar panel with quota
14
- - popup quota toasts after assistant responses
15
- - manual `/quota`, `/quota_status`, and `/tokens_*` commands
16
-
17
- **Quota providers**: Anthropic (Claude), GitHub Copilot, OpenAI (Plus/Pro), Cursor, Qwen Code, Alibaba Coding Plan, MiniMax Coding Plan, Kimi Code, Chutes AI, Synthetic, Google Antigravity, Z.ai Coding Plan, NanoGPT, and OpenCode Go.
18
-
19
- **Token reports**: All models and providers in [models.dev](https://models.dev), plus deterministic local pricing for Cursor Auto/Composer and Cursor model aliases that are not on models.dev.
20
-
21
- <table>
22
- <tr>
23
- <td width="100%">
24
- <img src="https://shawnkiser.com/opencode-quota/sidebar.webp" alt="Image of opencode-quota /tokens_weekly output" />
25
- </td>
26
- </tr>
27
- <tr>
28
- <td width="100%" align="center">Example of TUI sidebar</td>
29
- </tr>
30
- </table>
31
-
32
- <table>
33
-
34
- <tr>
35
- <td width="50%">
36
- <img src="https://shawnkiser.com/opencode-quota/toast.webp" alt="Image of opencode-quota toast" />
37
- </td>
38
- <td width="50%">
39
- <img src="https://shawnkiser.com/opencode-quota/token.webp" alt="Image of opencode-quota /tokens_weekly output" />
40
- </td>
41
- </tr>
42
- <tr>
43
- <td width="50%" align="center">Example of popup toast</td>
44
- <td width="50%" align="center">Example of <code>/tokens_weekly</code></td>
45
- </tr>
46
- </table>
47
-
48
- OpenCode `>= 1.4.3` is required.
49
-
50
- If you are coming back later:
51
-
52
- - see [Provider Setup At A Glance](#provider-setup-at-a-glance) for provider-specific setup needs
53
- - see [Commands](#commands) for the slash commands
54
- - see [Configuration Reference](#configuration-reference) when you want to customize behavior
55
- - see [Troubleshooting](#troubleshooting) if something does not appear or auto-detect correctly
56
-
57
- ## Installation
58
-
59
- ### Automatic setup (recommended)
60
-
61
- ```sh
1
+ <p align="center">
2
+ <a href="https://github.com/slkiser/opencode-quota">
3
+ <picture>
4
+ <source srcset="opencode-quota-logo-dark.svg" media="(prefers-color-scheme: dark)">
5
+ <source srcset="opencode-quota-logo-light.svg" media="(prefers-color-scheme: light)">
6
+ <img src="opencode-quota-logo-light.svg" alt="OpenCode Quota logo">
7
+ </picture>
8
+ </a>
9
+ </p>
10
+ <p align="center">Quota, usage, and token visibility for OpenCode.</p>
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/@slkiser/opencode-quota"><img alt="npm" src="https://img.shields.io/npm/v/%40slkiser%2Fopencode-quota?style=flat-square" /></a>
13
+ <a href="https://www.npmjs.com/package/@slkiser/opencode-quota"><img alt="npm downloads" src="https://img.shields.io/npm/dm/%40slkiser%2Fopencode-quota?style=flat-square" /></a>
14
+ <a href="https://github.com/slkiser/opencode-quota/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/slkiser/opencode-quota/ci.yml?style=flat-square&branch=main&label=CI" /></a>
15
+ <a href="./LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square" /></a>
16
+ </p>
17
+
18
+ [![OpenCode Quota sidebar](https://shawnkiser.com/opencode-quota/sidebar.webp)](https://github.com/slkiser/opencode-quota)
19
+
20
+ ---
21
+
22
+ ### Installation
23
+
24
+ ```bash
25
+ # Automatic setup
62
26
  npx @slkiser/opencode-quota init
63
27
  ```
64
28
 
65
- The installer (append-only, preserves existing values) asks for:
29
+ > [!IMPORTANT]
30
+ > OpenCode `>= 1.4.3` and Node.js `>= 18` are required.
66
31
 
67
- - **Scope**: `Project` or `Global`
68
- - **Quota UI**: `Toast`, `Sidebar`, `Toast + Sidebar`, or `None (manual /quota and /tokens_* only)`
69
- - **Provider mode**: `Auto-detect` or `Manual select`
70
- - **Layout style**: `classic` or `grouped`
71
- - **Percent display (toast/sidebar only)**: `remaining` or `used`
72
- - **Show session input/output tokens**: `Yes` or `No`
32
+ The installer is append-only and preserves existing config values. It asks where to install, which quota UI to enable, whether providers should be auto-detected, which quota display style to use, how percentages should be labeled, and whether session input/output tokens should appear in quota displays.
73
33
 
74
- All quota settings live in `opencode.json` or `opencode.jsonc`. `tui.json` or `tui.jsonc` is only for loading the sidebar plugin.
75
-
76
- ### After install
34
+ After install:
77
35
 
78
36
  1. Restart OpenCode.
79
37
  2. Run `/quota_status`.
80
38
  3. Run `/quota`.
81
- 4. If you chose `Sidebar` or `Toast + Sidebar`, open the session sidebar and confirm the `Quota` panel appears.
82
-
83
- ### Manual setup
39
+ 4. If you enabled the sidebar, open the session sidebar and confirm the `Quota` panel appears.
84
40
 
85
- You can install manually, but the installer is easier and safer.
41
+ ### Manual Setup
86
42
 
87
- 1. Add the server plugin to `opencode.json` or `opencode.jsonc`:
43
+ Add the server plugin to `opencode.json` or `opencode.jsonc`:
88
44
 
89
45
  ```jsonc
90
46
  {
@@ -93,7 +49,7 @@ You can install manually, but the installer is easier and safer.
93
49
  }
94
50
  ```
95
51
 
96
- 2. If you also want the sidebar, add the same package to a `tui.json` or `tui.jsonc` file that OpenCode loads (commonly the same folder):
52
+ If you also want the sidebar, add the same package to the `tui.json` or `tui.jsonc` file that OpenCode loads:
97
53
 
98
54
  ```jsonc
99
55
  {
@@ -102,123 +58,143 @@ You can install manually, but the installer is easier and safer.
102
58
  }
103
59
  ```
104
60
 
105
- 3. Optional settings still go in `opencode.json`, not `tui.json`.
61
+ All quota settings live in `opencode.json` or `opencode.jsonc`, not `tui.json`.
106
62
 
107
- Providers are auto-detected from your existing OpenCode setup by default, and most providers work from your existing OpenCode auth.
63
+ ### What It Adds
108
64
 
109
- <details>
110
- <summary><strong>Example: Sidebar only (turn off popup toasts)</strong></summary>
65
+ - TUI sidebar panel with quota rows
66
+ - Popup quota toasts after assistant responses
67
+ - Manual `/quota`, `/quota_status`, and `/tokens_*` commands
68
+ - Local token reports using bundled and runtime `models.dev` pricing
69
+ - Cursor Auto/Composer and Cursor alias pricing that stays deterministic locally
111
70
 
112
- Keep the `tui.json` or `tui.jsonc` entry above and disable toasts in `opencode.json` or `opencode.jsonc`:
71
+ <table>
72
+ <tr>
73
+ <td width="50%">
74
+ <img src="https://shawnkiser.com/opencode-quota/toast.webp" alt="OpenCode Quota popup toast" />
75
+ </td>
76
+ <td width="50%">
77
+ <img src="https://shawnkiser.com/opencode-quota/token.webp" alt="OpenCode Quota token report" />
78
+ </td>
79
+ </tr>
80
+ <tr>
81
+ <td width="50%" align="center">Popup quota toast</td>
82
+ <td width="50%" align="center"><code>/tokens_weekly</code> report</td>
83
+ </tr>
84
+ </table>
85
+
86
+ ### Providers
87
+
88
+ | Provider | Auto setup? | Setup / plugin order | Quota source |
89
+ | ----------------------- | ------------------ | --------------------------------------------------------- | ------------------------ |
90
+ | Anthropic (Claude) | [Needs quick setup](#anthropic-claude-quick-setup) | Install and authenticate Claude CLI | Local CLI or OAuth usage |
91
+ | GitHub Copilot | Usually automatic | Existing OpenCode auth, or optional PAT config | Remote API |
92
+ | OpenAI | Automatic | Existing OpenCode auth | Remote API |
93
+ | Cursor | [Needs quick setup](#cursor-quick-setup) | `["@playwo/opencode-cursor-oauth", "@slkiser/opencode-quota"]` | Local estimation |
94
+ | Qwen Code | [Needs quick setup](#qwen-code-quick-setup) | `["opencode-qwencode-auth", "@slkiser/opencode-quota"]` | Local estimation |
95
+ | Alibaba Coding Plan | Automatic | Existing OpenCode auth, global config, or env | Local estimation |
96
+ | MiniMax Coding Plan | Automatic | Existing OpenCode auth, global config, or env | Remote API |
97
+ | Kimi Code | Automatic | Existing OpenCode auth, global config, or env | Remote API |
98
+ | Chutes AI | Usually automatic | Existing OpenCode auth, global config, or env | Remote API |
99
+ | Synthetic | Automatic | Existing OpenCode auth, global config, or env | Remote API |
100
+ | Google Antigravity | [Needs quick setup](#google-antigravity-quick-setup) | `["opencode-antigravity-auth", "@slkiser/opencode-quota"]` | Remote API |
101
+ | Gemini CLI | [Needs quick setup](#gemini-cli-quick-setup) | `["opencode-gemini-auth", "@slkiser/opencode-quota"]` | Remote API |
102
+ | Z.ai Coding Plan | Automatic | Existing OpenCode auth, global config, or env | Remote API |
103
+ | NanoGPT | Usually automatic | Existing OpenCode auth, global config, or env | Remote API |
104
+ | OpenCode Go | [Needs quick setup](#opencode-go-quick-setup) | Set workspace ID and `auth` cookie | Dashboard scraping |
105
+
106
+ For companion auth providers, put the companion plugin first and `@slkiser/opencode-quota` second. The companion plugin handles login or token storage; OpenCode Quota reads that auth state and renders quota.
107
+
108
+ Providers are auto-detected by default. To choose providers explicitly:
113
109
 
114
110
  ```jsonc
115
111
  {
116
- "$schema": "https://opencode.ai/config.json",
117
- "plugin": ["@slkiser/opencode-quota"],
118
112
  "experimental": {
119
113
  "quotaToast": {
120
- "enableToast": false,
114
+ "enabledProviders": ["copilot", "openai", "google-gemini-cli"],
121
115
  },
122
116
  },
123
117
  }
124
118
  ```
125
119
 
126
- </details>
120
+ ### Display Options
127
121
 
128
- <details>
129
- <summary><strong>Example: Turn off auto-detection and choose providers</strong></summary>
122
+ Show every quota window instead of the default most-constrained window:
130
123
 
131
124
  ```jsonc
132
125
  {
133
126
  "experimental": {
134
127
  "quotaToast": {
135
- "enabledProviders": ["copilot", "openai", "google-antigravity"],
128
+ "formatStyle": "allWindows",
136
129
  },
137
130
  },
138
131
  }
139
132
  ```
140
133
 
141
- </details>
142
-
143
- <details>
144
- <summary><strong>Example: Grouped quota layout instead of the default classic layout</strong></summary>
134
+ Show percentages as used instead of remaining in toasts and the sidebar:
145
135
 
146
136
  ```jsonc
147
137
  {
148
138
  "experimental": {
149
139
  "quotaToast": {
150
- "formatStyle": "grouped",
140
+ "percentDisplayMode": "used",
151
141
  },
152
142
  },
153
143
  }
154
144
  ```
155
145
 
156
- </details>
157
-
158
- <details>
159
- <summary><strong>Example: Show percent used instead of percent remaining in toasts and the sidebar</strong></summary>
146
+ Turn off popup toasts while keeping `/quota` and the sidebar:
160
147
 
161
148
  ```jsonc
162
149
  {
163
150
  "experimental": {
164
151
  "quotaToast": {
165
- "percentDisplayMode": "used",
152
+ "enableToast": false,
166
153
  },
167
154
  },
168
155
  }
169
156
  ```
170
157
 
171
- </details>
158
+ ### Commands
172
159
 
173
- ## Provider Setup At A Glance
174
-
175
- | Provider | Auto setup | Authentication | Quota |
176
- | ----------------------- | ---------------------------------------------------- | ------------------------------- | ------------------------ |
177
- | **Anthropic (Claude)** | Needs [quick setup](#anthropic-quick-setup) | Local CLI auth | Local CLI, OAuth |
178
- | **GitHub Copilot** | Usually | OpenCode auth or PAT | Remote API |
179
- | **OpenAI** | Yes | OpenCode auth | Remote API |
180
- | **Cursor** | Needs [quick setup](#cursor-quick-setup) | Companion auth | Local estimation |
181
- | **Qwen Code** | Needs [quick setup](#qwen-code-quick-setup) | Companion auth | Local estimation |
182
- | **Alibaba Coding Plan** | Yes | OpenCode auth/global config/env | Local estimation |
183
- | **Synthetic** | Yes | OpenCode auth/global config/env | Remote API |
184
- | **Chutes AI** | Usually | OpenCode auth/global config/env | Remote API |
185
- | **Google Antigravity** | Needs [quick setup](#google-antigravity-quick-setup) | Companion auth | Remote API |
186
- | **Z.ai** | Yes | OpenCode auth/global config/env | Remote API |
187
- | **NanoGPT** | Usually | OpenCode auth/global config/env | Remote API |
188
- | **MiniMax Coding Plan** | Yes | OpenCode auth/global config/env | Remote API |
189
- | **Kimi Code** | Yes | OpenCode auth/global config/env | Remote API |
190
- | **OpenCode Go** | Needs [quick setup](#opencode-go-quick-setup) | Env/config auth | Dashboard scraping |
191
-
192
- <a id="anthropic-quick-setup"></a>
160
+ | Command | What it shows |
161
+ | --------------------- | -------------------------------------------------- |
162
+ | `/quota` | Detailed quota report |
163
+ | `/quota_status` | Config, provider, auth, pricing, and live probes |
164
+ | `/pricing_refresh` | Refresh local runtime pricing from `models.dev` |
165
+ | `/tokens_today` | Tokens used today |
166
+ | `/tokens_daily` | Tokens used in the last 24 hours |
167
+ | `/tokens_weekly` | Tokens used in the last 7 days |
168
+ | `/tokens_monthly` | Tokens used in the last 30 days, including pricing |
169
+ | `/tokens_all` | Tokens used across all local history |
170
+ | `/tokens_session` | Tokens used in the current session |
171
+ | `/tokens_session_all` | Current session plus descendant sessions |
172
+ | `/tokens_between` | Tokens used between `YYYY-MM-DD YYYY-MM-DD` |
193
173
 
194
- <details>
195
- <summary><strong>Quick setup: Anthropic (Claude)</strong></summary>
174
+ <a id="anthropic-claude-quick-setup"></a>
196
175
 
197
- Anthropic quota support is local-first: it checks the local Claude CLI first, and if Claude auth is confirmed but local quota windows are missing, it falls back to Claude OAuth credentials plus the Anthropic OAuth usage API.
176
+ ### Anthropic Quick Setup
198
177
 
199
- If Claude Code is already installed and authenticated, this usually works automatically. Otherwise:
178
+ Anthropic does not use a companion OpenCode plugin. Install Claude Code, authenticate it, and make sure `claude` is available on your `PATH`:
200
179
 
201
- 1. Install Claude Code so `claude` is available on your `PATH`.
202
- 2. Run `claude auth login`.
203
- 3. Confirm `claude auth status --json` or `claude auth status` succeeds locally.
204
- 4. Confirm OpenCode is configured with the `anthropic` provider.
205
-
206
- If Claude lives at a custom path, set `experimental.quotaToast.anthropicBinaryPath`. The default is `claude`.
207
-
208
- When local CLI auth is present but local windows are missing, the plugin first checks the macOS Keychain service `Claude Code-credentials`, then falls back to `~/.claude/.credentials.json`, extracts `claudeAiOauth.accessToken`, and queries Anthropic's OAuth usage endpoint. No manual Claude consumer token config is required.
180
+ ```bash
181
+ claude auth login
182
+ claude auth status
183
+ ```
209
184
 
210
- If you use Anthropic via API key in OpenCode, model usage still works normally. This plugin only shows Anthropic quota rows when local Claude auth is present and either the CLI or the Claude OAuth fallback can provide quota windows. If Claude auth is present but both quota probes fail, `/quota`, toasts, and the sidebar surface a sanitized Anthropic error instead of silently skipping the provider.
185
+ If Claude lives at a custom path, set `experimental.quotaToast.anthropicBinaryPath` in `opencode.json`.
211
186
 
212
- For behavior details and troubleshooting, see [Anthropic notes](#anthropic-notes).
187
+ ### Companion Providers
213
188
 
214
- </details>
189
+ Some providers need an auth companion plugin installed separately. Add the companion plugin first and `@slkiser/opencode-quota` second in `opencode.json` or `opencode.jsonc`.
215
190
 
216
191
  <a id="cursor-quick-setup"></a>
217
192
 
218
- <details>
219
- <summary><strong>Quick setup: Cursor</strong></summary>
193
+ #### Cursor
194
+
195
+ Companion plugin: `@playwo/opencode-cursor-oauth`
220
196
 
221
- Cursor quota support requires the `@playwo/opencode-cursor-oauth` [plugin](https://github.com/PoolPirate/opencode-cursor):
197
+ Add both plugins to `opencode.json`, with the Cursor auth plugin first:
222
198
 
223
199
  ```jsonc
224
200
  {
@@ -226,545 +202,266 @@ Cursor quota support requires the `@playwo/opencode-cursor-oauth` [plugin](https
226
202
  "plugin": ["@playwo/opencode-cursor-oauth", "@slkiser/opencode-quota"],
227
203
  "provider": {
228
204
  "cursor": {
229
- "name": "Cursor",
230
- },
231
- },
232
- "experimental": {
233
- "quotaToast": {
234
- "cursorPlan": "pro",
235
- "cursorBillingCycleStartDay": 7,
236
- },
237
- },
205
+ "name": "Cursor"
206
+ }
207
+ }
238
208
  }
239
209
  ```
240
210
 
241
- Then authenticate once:
211
+ Then authenticate Cursor once:
242
212
 
243
- ```sh
213
+ ```bash
244
214
  opencode auth login --provider cursor
245
215
  ```
246
216
 
247
- For behavior details and troubleshooting, see [Cursor notes](#cursor-notes).
248
-
249
- </details>
217
+ <a id="qwen-code-quick-setup"></a>
250
218
 
251
- <a id="google-antigravity-quick-setup"></a>
219
+ #### Qwen Code
252
220
 
253
- <details>
254
- <summary><strong>Quick setup: Google Antigravity</strong></summary>
221
+ Companion plugin: `opencode-qwencode-auth`
255
222
 
256
- Google quota support requires the `opencode-antigravity-auth` [plugin](https://github.com/NoeFabris/opencode-antigravity-auth). `@slkiser/opencode-quota` does not install that companion plugin transitively, so install/configure it separately and then enable both plugins:
223
+ Add both plugins to `opencode.json`, with the Qwen auth plugin first:
257
224
 
258
225
  ```jsonc
259
226
  {
260
- "plugin": ["opencode-antigravity-auth", "@slkiser/opencode-quota"],
227
+ "$schema": "https://opencode.ai/config.json",
228
+ "plugin": ["opencode-qwencode-auth", "@slkiser/opencode-quota"]
261
229
  }
262
230
  ```
263
231
 
264
- For behavior details and troubleshooting, see [Google Antigravity notes](#google-antigravity-notes).
265
-
266
- </details>
232
+ <a id="google-antigravity-quick-setup"></a>
267
233
 
268
- <a id="qwen-code-quick-setup"></a>
234
+ #### Google Antigravity
269
235
 
270
- <details>
271
- <summary><strong>Quick setup: Qwen Code</strong></summary>
236
+ Companion plugin: `opencode-antigravity-auth`
272
237
 
273
- Qwen quota support requires the `opencode-qwencode-auth` [plugin](https://github.com/gustavodiasdev/opencode-qwencode-auth):
238
+ Add both plugins to `opencode.json`, with the Antigravity auth plugin first:
274
239
 
275
240
  ```jsonc
276
241
  {
277
- "plugin": ["opencode-qwencode-auth", "@slkiser/opencode-quota"],
242
+ "$schema": "https://opencode.ai/config.json",
243
+ "plugin": ["opencode-antigravity-auth", "@slkiser/opencode-quota"]
278
244
  }
279
245
  ```
280
246
 
281
- For behavior details and troubleshooting, see [Qwen Code notes](#qwen-code-notes).
247
+ <a id="gemini-cli-quick-setup"></a>
282
248
 
283
- </details>
249
+ #### Gemini CLI
284
250
 
285
- <a id="opencode-go-quick-setup"></a>
251
+ Companion plugin: `opencode-gemini-auth`
286
252
 
287
- <details>
288
- <summary><strong>Quick setup: OpenCode Go</strong></summary>
253
+ Add both plugins to `opencode.json`, with the Gemini auth plugin first. If you manually choose providers, include `google-gemini-cli`:
289
254
 
290
- OpenCode Go quota scrapes the OpenCode Go dashboard. It requires a workspace ID and an auth cookie.
291
-
292
- **Option A — Environment variables:**
293
-
294
- ```sh
295
- export OPENCODE_GO_WORKSPACE_ID="your-workspace-id"
296
- export OPENCODE_GO_AUTH_COOKIE="your-auth-cookie"
255
+ ```jsonc
256
+ {
257
+ "$schema": "https://opencode.ai/config.json",
258
+ "plugin": ["opencode-gemini-auth", "@slkiser/opencode-quota"],
259
+ "experimental": {
260
+ "quotaToast": {
261
+ "enabledProviders": ["google-gemini-cli"]
262
+ }
263
+ }
264
+ }
297
265
  ```
298
266
 
299
- **Option B Config file** (for example, `~/.config/opencode/opencode-quota/opencode-go.json` on Linux or legacy macOS installs):
267
+ Then authenticate Google once:
300
268
 
301
- ```json
302
- {
303
- "workspaceId": "your-workspace-id",
304
- "authCookie": "your-auth-cookie"
305
- }
269
+ ```bash
270
+ opencode auth login --provider google
306
271
  ```
307
272
 
308
- To find these values:
273
+ ### OpenCode Go
309
274
 
310
- 1. **workspaceId** — Visit [opencode.ai](https://opencode.ai), open your workspace, and copy the workspace ID from the URL: `https://opencode.ai/workspace/<workspaceId>/go`.
311
- 2. **authCookie** — Open your browser DevTools on `opencode.ai`, go to Application → Cookies, and copy the value of the `auth` cookie.
275
+ <a id="opencode-go-quick-setup"></a>
312
276
 
313
- Environment variables take precedence over the config file. Run `/quota_status` to see the exact config paths checked on your machine. For behavior details and troubleshooting, see [OpenCode Go notes](#opencode-go-notes).
277
+ OpenCode Go quota scrapes the dashboard and needs a workspace ID plus an `auth` cookie:
314
278
 
315
- </details>
279
+ ```bash
280
+ export OPENCODE_GO_WORKSPACE_ID="your-workspace-id"
281
+ export OPENCODE_GO_AUTH_COOKIE="your-auth-cookie"
282
+ ```
316
283
 
317
- ## Commands
284
+ Environment variables take precedence over the optional `opencode-go.json` config file. Run `/quota_status` to see the exact paths checked on your machine.
318
285
 
319
- | Command | What it shows |
320
- | --------------------- | ---------------------------------------------------------------------------------------------------------------- |
321
- | `/quota` | Manual grouped quota report with a local call timestamp |
322
- | `/quota_status` | Concise diagnostics for config, TUI setup, provider availability, account detection, pricing snapshot health, and fresh compact live probe rows in matching provider sections |
323
- | `/pricing_refresh` | Pull the local runtime pricing snapshot from `models.dev` on demand |
324
- | `/tokens_today` | Tokens used today (calendar day) |
325
- | `/tokens_daily` | Tokens used in the last 24 hours |
326
- | `/tokens_weekly` | Tokens used in the last 7 days |
327
- | `/tokens_monthly` | Tokens used in the last 30 days, including pricing sections |
328
- | `/tokens_all` | Tokens used across all local history |
329
- | `/tokens_session` | Tokens used in the current session only |
330
- | `/tokens_session_all` | Tokens used in the current session plus all descendant child/subagent sessions |
331
- | `/tokens_between` | Tokens used between two dates: `YYYY-MM-DD YYYY-MM-DD` |
286
+ ### Troubleshooting
332
287
 
333
- ## Provider-Specific Notes
288
+ If quota or token data looks wrong:
334
289
 
335
- `/quota_status` keeps each provider's existing diagnostics and, for enabled + available supported providers, also appends a fresh sanitized compact probe summary (`live_probe`, `live_entry_*`, `live_error_*`) in that provider's section. If a fresh probe returns nothing reportable, `/quota_status` shows `live_probe: no_data`. Qwen Code and Alibaba Coding Plan use dedicated `qwen_code` and `alibaba_coding_plan` compact probe sections because their auth and local-state diagnostics already live under `paths` and `cursor`.
290
+ 1. Run `/quota_status`.
291
+ 2. Confirm the expected provider appears in the detected provider list.
292
+ 3. Confirm OpenCode has already created `opencode.db` if token reports are empty.
293
+ 4. Check companion plugins for Cursor, Qwen Code, Google Antigravity, and Gemini CLI.
294
+ 5. Use the quick-setup link in the provider table for provider-specific auth and config notes.
336
295
 
337
- <a id="anthropic-notes"></a>
296
+ ### Provider Troubleshooting
338
297
 
339
298
  <details>
340
299
  <summary><strong>Anthropic (Claude)</strong></summary>
341
300
 
342
- The plugin probes the local Claude CLI with `anthropicBinaryPath --version` and `anthropicBinaryPath auth status --json` first. By default `anthropicBinaryPath` is `claude`, so standard installs work without extra config.
343
-
344
- If the Claude CLI exposes 5-hour and 7-day quota windows in local structured output, the plugin shows them directly. If the CLI only exposes auth state, the plugin falls back to the macOS Keychain service `Claude Code-credentials` and then `~/.claude/.credentials.json` before calling Anthropic's OAuth usage endpoint. When Claude is authenticated but both quota probes fail, `/quota`, toasts, and the sidebar surface a sanitized Anthropic error instead of silently skipping the provider.
345
-
346
- - Provider availability remains local-only: Anthropic is considered available when the local Claude CLI is installed and authenticated.
347
- - `experimental.quotaToast.anthropicBinaryPath` only changes CLI probing. It does not change Claude OAuth credential lookup locations.
348
- - `/quota_status` shows `quota_source` as either `claude-auth-status-json`, `claude-credentials-oauth-api`, or `(none)`.
349
-
350
- **Troubleshooting:**
301
+ Run `/quota_status` and check the Anthropic section.
351
302
 
352
- | Problem | Solution |
353
- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
354
- | `claude` not found | Install Claude Code and make sure `claude` is on your `PATH` |
355
- | Claude installed at a custom path | Set `experimental.quotaToast.anthropicBinaryPath` to the Claude executable path |
356
- | Not authenticated | Run `claude auth login`, then confirm `claude auth status --json` or `claude auth status` works |
357
- | Authenticated but no quota rows | Run `/quota_status` and check `quota_source` plus `message` to see whether the local CLI, the macOS Keychain / fallback credentials file, or the fallback API failed |
358
- | Missing or invalid Claude OAuth credentials | Re-authenticate Claude Code so it refreshes the macOS Keychain entry and local credentials file, then rerun `/quota_status` |
359
- | Fallback API error or no quota response | Check `/quota_status` for the sanitized fallback error detail and retry after Claude Code refreshes local auth |
360
- | Plugin not detected | Confirm OpenCode is configured with the `anthropic` provider |
303
+ | Symptom | Fix |
304
+ | --- | --- |
305
+ | `claude` not found | Install Claude Code and make sure `claude` is on your `PATH`. |
306
+ | Claude is installed at a custom path | Set `experimental.quotaToast.anthropicBinaryPath` in `opencode.json`. |
307
+ | Not authenticated | Run `claude auth login`, then confirm `claude auth status` works. |
308
+ | Auth works but no quota rows appear | Check `quota_source` and `message` in `/quota_status`; re-authenticate Claude if the OAuth credential fallback is missing or stale. |
309
+ | Provider not detected | Confirm OpenCode is configured to use the `anthropic` provider. |
361
310
 
362
311
  </details>
363
312
 
364
- <a id="github-copilot-notes"></a>
365
-
366
313
  <details>
367
314
  <summary><strong>GitHub Copilot</strong></summary>
368
315
 
369
- Personal quota works automatically when OpenCode is already signed in. Without `copilot-quota-token.json`, the plugin reads the OpenCode Copilot OAuth token from `~/.local/share/opencode/auth.json` and calls `GET https://api.github.com/copilot_internal/user`.
370
-
371
- - Managed billing uses `copilot-quota-token.json` in the OpenCode runtime config directory (`opencode debug paths`). `business` requires `organization`; `enterprise` requires `enterprise` and can also filter by `organization` or `username`.
372
- - `copilot-quota-token.json` takes precedence over OAuth. If the PAT config is invalid, the plugin reports that error and does not silently fall back.
373
- - Output is labeled `[Copilot] (personal)` or `[Copilot] (business)`, and managed output includes the org or enterprise slug.
374
- - Enterprise premium usage does not support fine-grained PATs or GitHub App tokens.
375
- - Check `/quota_status` for `copilot_quota_auth`, `billing_mode`, `billing_scope`, `quota_api`, `effective_source`, and `billing_api_access_likely`.
376
-
377
- Example `copilot-quota-token.json`:
316
+ Run `/quota_status` and check `copilot_quota_auth`, `billing_mode`, `billing_scope`, and `quota_api`.
378
317
 
379
- ```json
380
- {
381
- "token": "github_pat_...",
382
- "tier": "business",
383
- "organization": "your-org-slug"
384
- }
385
- ```
386
-
387
- ```json
388
- {
389
- "token": "ghp_...",
390
- "tier": "enterprise",
391
- "enterprise": "your-enterprise-slug",
392
- "organization": "optional-org-filter",
393
- "username": "optional-user-filter"
394
- }
395
- ```
318
+ | Symptom | Fix |
319
+ | --- | --- |
320
+ | Personal quota missing | Confirm OpenCode Copilot auth works. The plugin can read OpenCode's Copilot OAuth token. |
321
+ | Business or Enterprise quota missing | Add `copilot-quota-token.json` in the OpenCode runtime config directory shown by `opencode debug paths`. |
322
+ | PAT config exists but quota fails | Fix `copilot-quota-token.json`; when present, it takes precedence over OAuth and does not silently fall back. |
323
+ | Enterprise usage missing | Use a classic PAT with the required billing access. Fine-grained PATs and GitHub App tokens are not supported for Enterprise premium usage. |
396
324
 
397
325
  </details>
398
326
 
399
- <a id="cursor-notes"></a>
400
-
401
327
  <details>
402
- <summary><strong>Cursor</strong></summary>
403
-
404
- See [Cursor quick setup](#cursor-quick-setup) for companion-plugin OAuth auth. The canonical companion package is `@playwo/opencode-cursor-oauth`; older plugin names such as `opencode-cursor-oauth`, `opencode-cursor`, and `cursor-acp` are still detected as compatibility aliases. Quota and token reporting stays local to OpenCode history and local pricing data.
328
+ <summary><strong>OpenAI</strong></summary>
405
329
 
406
- - Detects Cursor usage when the provider is `cursor` or the stored/current model id is `cursor/*`.
407
- - `/tokens_*` maps Cursor API-pool models to official pricing and uses bundled static pricing for `auto` and `composer*`.
408
- - `/quota` and toasts estimate the current billing-cycle spend from local history only. Session cookies and team APIs are not required.
409
- - Remaining percentage appears only when `experimental.quotaToast.cursorPlan` or `experimental.quotaToast.cursorIncludedApiUsd` is set. Billing cycle defaults to the local calendar month unless `experimental.quotaToast.cursorBillingCycleStartDay` is set.
410
- - Legacy `cursor-acp/*` history remains readable. Unknown future Cursor model ids appear in `/quota_status` under Cursor diagnostics and `unknown_pricing`.
330
+ Run `/quota_status` and check the OpenAI auth source and token status.
411
331
 
412
- Example override:
413
-
414
- ```jsonc
415
- {
416
- "experimental": {
417
- "quotaToast": {
418
- "cursorPlan": "none",
419
- "cursorIncludedApiUsd": 120,
420
- },
421
- },
422
- }
423
- ```
332
+ | Symptom | Fix |
333
+ | --- | --- |
334
+ | OpenAI quota missing | Confirm OpenCode native OpenAI auth is present in `auth.json`. |
335
+ | Token expired | Re-run OpenCode's OpenAI auth flow. |
336
+ | Provider not detected | Confirm your OpenCode config uses the `openai` provider or a compatible OpenAI auth entry. |
424
337
 
425
338
  </details>
426
339
 
427
- <a id="openai-notes"></a>
428
-
429
340
  <details>
430
- <summary><strong>OpenAI</strong></summary>
341
+ <summary><strong>Cursor</strong></summary>
431
342
 
432
- OpenAI uses native OpenCode OAuth from `auth.json`. The canonical auth family is OpenCode auth, not companion-plugin auth.
343
+ Run `/quota_status` and check the Cursor section.
433
344
 
434
- - Quota is fetched from the OpenAI usage API using the native OpenCode OAuth token stored under `openai` in `auth.json`.
435
- - Older OpenCode installs may still have compatible OpenAI OAuth entries under `codex`, `chatgpt`, or `opencode`. Those remain supported for backward compatibility.
436
- - `/quota_status` includes an `openai` section with the detected auth source, token status, expiry, and account details derived from the token when available.
345
+ | Symptom | Fix |
346
+ | --- | --- |
347
+ | Cursor not detected | Put `@playwo/opencode-cursor-oauth` before `@slkiser/opencode-quota` in `opencode.json`. |
348
+ | Cursor auth missing | Run `opencode auth login --provider cursor`. |
349
+ | Quota appears but no remaining percentage | Set `experimental.quotaToast.cursorPlan` or `experimental.quotaToast.cursorIncludedApiUsd`. |
350
+ | Billing cycle looks wrong | Set `experimental.quotaToast.cursorBillingCycleStartDay` to your local billing anchor day. |
351
+ | Unknown Cursor pricing | Run `/pricing_refresh`; if still unknown, check `/quota_status` for unknown model ids. |
437
352
 
438
353
  </details>
439
354
 
440
- <a id="qwen-code-notes"></a>
441
-
442
355
  <details>
443
356
  <summary><strong>Qwen Code</strong></summary>
444
357
 
445
- See [Qwen Code quick setup](#qwen-code-quick-setup) for auth. Usage is local-only estimation for the free plan; the plugin does not call an Alibaba quota API.
358
+ Run `/quota_status` and check `qwen_oauth_source`, `qwen_local_plan`, and the `qwen_code` live probe section.
446
359
 
447
- - Free tier limits: `1000` requests per UTC day and `60` requests per rolling minute.
448
- - The canonical companion auth key is `qwen-code`. Older installs may still use `opencode-qwencode-auth`, which remains a supported fallback.
449
- - Counters increment on successful question-tool completions while the current model is `qwen-code/*`.
450
- - State file: `.../opencode/opencode-quota/qwen-local-quota.json`.
451
- - Check `/quota_status` for auth detection, `qwen_oauth_source`, `qwen_local_plan`, local counter state, and the dedicated `qwen_code` compact live probe section when Qwen Code is enabled and available.
360
+ | Symptom | Fix |
361
+ | --- | --- |
362
+ | Qwen not detected | Put `opencode-qwencode-auth` before `@slkiser/opencode-quota` in `opencode.json`. |
363
+ | Auth missing | Complete the Qwen companion plugin auth flow. |
364
+ | Counters do not move | Confirm the current model is `qwen-code/*`; Qwen quota is local request estimation for matching model usage. |
365
+ | Usage looks stale | Check the local state file path shown by `/quota_status`. |
452
366
 
453
367
  </details>
454
368
 
455
- <a id="alibaba-coding-plan-notes"></a>
456
-
457
369
  <details>
458
370
  <summary><strong>Alibaba Coding Plan</strong></summary>
459
371
 
460
- Alibaba Coding Plan uses trusted env vars or trusted user/global OpenCode config first, then native OpenCode auth from `alibaba-coding-plan` or `alibaba` in `auth.json`. Quota is local request-count estimation with rolling windows.
461
-
462
- - `lite`: `1200 / 5h`, `9000 / week`, `18000 / month`
463
- - `pro`: `6000 / 5h`, `45000 / week`, `90000 / month`
464
- - API key sources are `ALIBABA_CODING_PLAN_API_KEY`, `ALIBABA_API_KEY`, trusted user/global `provider["alibaba-coding-plan"].options.apiKey` or `provider.alibaba.options.apiKey`, then `auth.json`.
465
- - Repo-local `opencode.json` / `opencode.jsonc` is ignored for Alibaba secrets.
466
- - Allowed env templates are limited to `{env:ALIBABA_CODING_PLAN_API_KEY}` and `{env:ALIBABA_API_KEY}`.
467
- - If auth fallback wins and omits `tier`, or if env/config wins, the plugin uses `experimental.quotaToast.alibabaCodingPlanTier`, which defaults to `lite`.
468
- - Counters increment on successful question-tool completions while the current model is `alibaba/*` or `alibaba-cn/*`.
469
- - State file: `.../opencode/opencode-quota/alibaba-coding-plan-local-quota.json`.
470
- - `/quota_status` shows auth detection, resolved tier, state-file path, current 5h/weekly/monthly usage, and the dedicated `alibaba_coding_plan` compact live probe section when Alibaba Coding Plan is enabled and available.
471
-
472
- Example fallback tier:
473
-
474
- ```jsonc
475
- {
476
- "experimental": {
477
- "quotaToast": {
478
- "alibabaCodingPlanTier": "lite",
479
- },
480
- },
481
- }
482
- ```
483
-
484
- </details>
485
-
486
- <a id="minimax-coding-plan-notes"></a>
487
-
488
- <details>
489
- <summary><strong>MiniMax Coding Plan</strong></summary>
490
-
491
- MiniMax Coding Plan uses trusted env vars or trusted user/global OpenCode config first, then native OpenCode auth from `auth.json["minimax-coding-plan"]`. No additional plugin is required.
492
-
493
- - `MiniMax-M*` models — rolling 5-hour interval + weekly
494
- - API key sources are `MINIMAX_CODING_PLAN_API_KEY`, `MINIMAX_API_KEY`, trusted user/global `provider["minimax-coding-plan"].options.apiKey` or `provider.minimax.options.apiKey`, then `auth.json`.
495
- - Repo-local `opencode.json` / `opencode.jsonc` is ignored for MiniMax secrets.
496
- - Allowed env templates are limited to `{env:MINIMAX_CODING_PLAN_API_KEY}` and `{env:MINIMAX_API_KEY}`.
497
- - When `auth.json` fallback wins, the plugin reads `key` first and falls back to `access`.
498
- - `/quota_status` shows auth detection, API-key diagnostics, live quota state, and endpoint errors
499
-
500
- </details>
501
-
502
- <a id="kimi-code-notes"></a>
503
-
504
- <details>
505
- <summary><strong>Kimi Code</strong></summary>
506
-
507
- Kimi Code uses trusted env vars or trusted user/global OpenCode config first, then native OpenCode auth from `auth.json["kimi-for-coding"]` or `auth.json["kimi-code"]`. No additional plugin is required.
508
-
509
- - API key sources are `KIMI_API_KEY`, `KIMI_CODE_API_KEY`, trusted user/global `provider["kimi-for-coding"].options.apiKey` or `provider["kimi-code"].options.apiKey`, then `auth.json`.
510
- - Repo-local `opencode.json` / `opencode.jsonc` is ignored for Kimi secrets.
511
- - Allowed env templates are limited to `{env:KIMI_API_KEY}` and `{env:KIMI_CODE_API_KEY}`.
512
- - The plugin calls `https://api.kimi.com/coding/v1/usages`.
513
- - `/quota_status` shows auth detection, API-key diagnostics, live quota state, and endpoint errors.
514
-
515
- </details>
372
+ Run `/quota_status` and check the Alibaba auth, resolved tier, state-file path, and `alibaba_coding_plan` live probe section.
516
373
 
517
- <a id="zai-notes"></a>
518
-
519
- <details>
520
- <summary><strong>Z.ai</strong></summary>
521
-
522
- Z.ai uses trusted env vars or trusted user/global OpenCode config first, then native OpenCode auth from `auth.json["zai-coding-plan"]`.
523
-
524
- - API key sources are `ZAI_API_KEY`, `ZAI_CODING_PLAN_API_KEY`, trusted user/global `provider.zai.options.apiKey`, `provider["zai-coding-plan"].options.apiKey`, or `provider.glm.options.apiKey`, then `auth.json`.
525
- - Repo-local `opencode.json` / `opencode.jsonc` is ignored for Z.ai secrets.
526
- - Allowed env templates are limited to `{env:ZAI_API_KEY}` and `{env:ZAI_CODING_PLAN_API_KEY}`.
527
- - `/quota_status` shows auth diagnostics plus live 5-hour, weekly, and MCP quota windows when the Z.ai API reports them.
528
- - Malformed `zai-coding-plan` fallback auth is surfaced as an auth error instead of being silently treated as missing.
374
+ | Symptom | Fix |
375
+ | --- | --- |
376
+ | API key not detected | Use `ALIBABA_CODING_PLAN_API_KEY`, `ALIBABA_API_KEY`, trusted user/global OpenCode config, or OpenCode auth. Repo-local provider secrets are ignored. |
377
+ | Wrong tier | Set `experimental.quotaToast.alibabaCodingPlanTier` to `lite` or `pro`. |
378
+ | Counters do not move | Confirm the current model is `alibaba/*` or `alibaba-cn/*`. |
379
+ | Quota seems stale | Check the state-file path shown in `/quota_status`. |
529
380
 
530
381
  </details>
531
382
 
532
- <a id="synthetic-notes"></a>
533
-
534
383
  <details>
535
- <summary><strong>Synthetic</strong></summary>
536
-
537
- If OpenCode already has Synthetic configured, it should work automatically. Optional API key: `provider.synthetic.options.apiKey`.
384
+ <summary><strong>MiniMax, Kimi, Chutes AI, Synthetic, Z.ai, and NanoGPT</strong></summary>
538
385
 
539
- For security, provider secrets are read from `SYNTHETIC_API_KEY`, your user/global OpenCode config, or `auth.json.synthetic` only. Repo-local `opencode.json` / `opencode.jsonc` is ignored for `provider.synthetic.options.apiKey`.
386
+ These providers use trusted env vars, trusted user/global OpenCode config, or native OpenCode auth. Run `/quota_status` and check the provider-specific API-key diagnostics.
540
387
 
541
- - The plugin calls `GET https://api.synthetic.new/v2/quotas`.
542
- - It uses only the current top-level Synthetic payload sections: `rollingFiveHourLimit` (`max`, `remaining`, `nextTickAt`) and `weeklyTokenLimit` (`maxCredits`, `remainingCredits`, `percentRemaining`, `nextRegenAt`).
543
- - `weeklyTokenLimit.maxCredits` and `weeklyTokenLimit.remainingCredits` are parsed from the real Synthetic dollar-string format (for example `$24.00` and `$2.02`). Legacy `subscription.limit`, `subscription.requests`, and `subscription.renewsAt` are ignored.
544
- - Missing or malformed top-level windows are treated as API-shape errors. Invalid reset timestamps are ignored. Weekly `percentRemaining` uses `weeklyTokenLimit.percentRemaining` when valid and otherwise falls back to deterministic derivation from the parsed credit amounts.
545
- - `/quota`, toasts, and the sidebar surface both Synthetic windows: `Synthetic 5h` / `Synthetic Weekly` in classic mode, or grouped `5h:` / `Weekly:` rows under `Synthetic`.
546
- - Compact summaries still round displayed `used` values, and the weekly row keeps dollar semantics (for example `$22/$24`) instead of showing long floats.
547
- - `/quota_status` keeps the existing Synthetic API-key diagnostics and adds a compact sanitized live probe summary from those same Synthetic rows when Synthetic is enabled and detected/available.
548
- - Allowed env templates are limited to `{env:SYNTHETIC_API_KEY}`.
388
+ | Provider | Useful checks |
389
+ | --- | --- |
390
+ | MiniMax Coding Plan | Use `MINIMAX_CODING_PLAN_API_KEY` or `MINIMAX_API_KEY`; repo-local provider secrets are ignored. |
391
+ | Kimi Code | Use `KIMI_API_KEY` or `KIMI_CODE_API_KEY`; repo-local provider secrets are ignored. |
392
+ | Chutes AI | Use `CHUTES_API_KEY` or trusted user/global config. |
393
+ | Synthetic | Use `SYNTHETIC_API_KEY`, trusted user/global config, or OpenCode auth. |
394
+ | Z.ai Coding Plan | Use `ZAI_API_KEY` or `ZAI_CODING_PLAN_API_KEY`; malformed fallback auth is surfaced as an auth error. |
395
+ | NanoGPT | Use `NANOGPT_API_KEY`, `NANO_GPT_API_KEY`, trusted user/global config, or OpenCode auth. |
549
396
 
550
- Example user/global config (`~/.config/opencode/opencode.jsonc` on Linux/macOS):
551
-
552
- ```jsonc
553
- {
554
- "provider": {
555
- "synthetic": {
556
- "options": {
557
- "apiKey": "{env:SYNTHETIC_API_KEY}",
558
- },
559
- },
560
- },
561
- }
562
- ```
397
+ For security, repo-local `opencode.json` / `opencode.jsonc` is ignored for provider secrets in these integrations. Put secrets in environment variables or trusted user/global config.
563
398
 
564
399
  </details>
565
400
 
566
- <a id="chutes-ai-notes"></a>
567
-
568
- <details>
569
- <summary><strong>Chutes AI</strong></summary>
570
-
571
- If OpenCode already has Chutes configured, it usually works automatically. Optional API key: `provider.chutes.options.apiKey`.
572
-
573
- For security, provider secrets are read from environment variables or your user/global OpenCode config only. Repo-local `opencode.json` / `opencode.jsonc` is ignored for `provider.chutes.options.apiKey`.
574
-
575
- Allowed env templates are limited to `{env:CHUTES_API_KEY}`.
576
-
577
- - `/quota_status` keeps the existing `chutes` API-key diagnostics and appends a compact sanitized live probe summary when the Chutes provider is enabled and available.
578
-
579
- Example user/global config (`~/.config/opencode/opencode.jsonc` on Linux/macOS):
580
-
581
- ```jsonc
582
- {
583
- "provider": {
584
- "chutes": {
585
- "options": {
586
- "apiKey": "{env:CHUTES_API_KEY}",
587
- },
588
- },
589
- },
590
- }
591
- ```
592
-
593
- </details>
594
-
595
- <a id="google-antigravity-notes"></a>
596
-
597
401
  <details>
598
402
  <summary><strong>Google Antigravity</strong></summary>
599
403
 
600
- See [Google Antigravity quick setup](#google-antigravity-quick-setup). This companion auth flow does not use `auth.json`; it reads `antigravity-accounts.json` from the OpenCode runtime directories. `@slkiser/opencode-quota` expects the companion plugin to be installed separately.
404
+ Run `/quota_status` and check the `google_antigravity` section.
601
405
 
602
- - `/quota_status` includes a `google_antigravity` section with the selected accounts path, all present/candidate paths, account counts, valid refresh-token counts, companion package state/path, the Google token-cache path, and compact live probe rows when the provider returns reportable data.
603
- - If the companion plugin is missing or incompatible, `/quota_status` shows `companion_package_state` and `companion_error`.
604
- - If detection looks wrong, start with the `google_antigravity` section in `/quota_status`.
406
+ | Symptom | Fix |
407
+ | --- | --- |
408
+ | Companion missing | Put `opencode-antigravity-auth` before `@slkiser/opencode-quota` in `opencode.json`. |
409
+ | Accounts not found | Check the selected `antigravity-accounts.json` path shown by `/quota_status`. |
410
+ | Refresh tokens invalid | Re-authenticate with the companion plugin. |
411
+ | Provider returns no rows | Check `live_probe`, `live_entry_*`, and `live_error_*` in `/quota_status`. |
605
412
 
606
413
  </details>
607
414
 
608
- <a id="nanogpt-notes"></a>
609
-
610
415
  <details>
611
- <summary><strong>NanoGPT</strong></summary>
416
+ <summary><strong>Gemini CLI</strong></summary>
612
417
 
613
- NanoGPT uses live NanoGPT subscription usage and balance endpoints, so `/quota`, grouped/classic toasts, and `/quota_status` can show daily quota, monthly quota, and account balance in real time.
418
+ Run `/quota_status` and check the Gemini CLI live probe rows.
614
419
 
615
- - Canonical provider id is `nanogpt`. Alias `nano-gpt` also normalizes in `enabledProviders`.
616
- - Optional API key: `provider.nanogpt.options.apiKey` or `provider["nano-gpt"].options.apiKey`.
617
- - For security, provider secrets are read from `NANOGPT_API_KEY`, `NANO_GPT_API_KEY`, your user/global OpenCode config, or `auth.json`. Repo-local `opencode.json` / `opencode.jsonc` is ignored for NanoGPT secrets.
618
- - Allowed env templates are limited to `{env:NANOGPT_API_KEY}` and `{env:NANO_GPT_API_KEY}`.
619
- - `/quota_status` prints a `nanogpt` section with API-key diagnostics, auth candidate paths, live subscription state, daily/monthly usage windows, endpoint errors, and balance details.
620
- - NanoGPT quota reflects subscription-covered requests and account balance. It is not token-priced in `/tokens_*`.
621
-
622
- Example user/global config (`~/.config/opencode/opencode.jsonc` on Linux/macOS):
623
-
624
- ```jsonc
625
- {
626
- "provider": {
627
- "nanogpt": {
628
- "options": {
629
- "apiKey": "{env:NANOGPT_API_KEY}",
630
- },
631
- },
632
- },
633
- }
634
- ```
420
+ | Symptom | Fix |
421
+ | --- | --- |
422
+ | Companion missing | Put `opencode-gemini-auth` before `@slkiser/opencode-quota` in `opencode.json`. |
423
+ | Provider not enabled in manual mode | Include `google-gemini-cli` in `experimental.quotaToast.enabledProviders`. |
424
+ | Auth missing | Run `opencode auth login --provider google`. |
425
+ | Project missing | Set `provider.google.options.projectId`, `OPENCODE_GEMINI_PROJECT_ID`, `GOOGLE_CLOUD_PROJECT`, or `GOOGLE_CLOUD_PROJECT_ID`. |
635
426
 
636
427
  </details>
637
428
 
638
- <a id="opencode-go-notes"></a>
639
-
640
429
  <details>
641
430
  <summary><strong>OpenCode Go</strong></summary>
642
431
 
643
- OpenCode Go quota scrapes the OpenCode Go dashboard at `https://opencode.ai/workspace/<workspaceId>/go` using an `auth` cookie. There is no official usage API yet; the plugin parses the SolidJS SSR hydration output for `monthlyUsage` data.
644
-
645
- - **Config sources** (checked in order):
646
- 1. Environment variables: `OPENCODE_GO_WORKSPACE_ID` and `OPENCODE_GO_AUTH_COOKIE`
647
- 2. Config file: for example `~/.config/opencode/opencode-quota/opencode-go.json` on Linux or legacy macOS installs, with `{ "workspaceId": "...", "authCookie": "..." }`
648
- - Environment variables take precedence. Both `workspaceId` and `authCookie` must come from the same source.
649
- - Quota returns a usage percentage and a reset countdown. There is no absolute request count.
650
- - `/quota_status` shows an `opencode_go` section with config state, config source, checked paths, and live scrape results or errors.
651
- - Because this is a scraper, it may break if OpenCode changes their dashboard markup. An official API ([opencode#16513](https://github.com/anomalyco/opencode/pull/16513)) is pending.
432
+ Run `/quota_status` and check the `opencode_go` section.
652
433
 
653
- **Troubleshooting:**
654
-
655
- | Problem | Solution |
656
- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
657
- | Config not detected | Confirm `OPENCODE_GO_WORKSPACE_ID` and `OPENCODE_GO_AUTH_COOKIE` are set, then use `/quota_status` to inspect the exact config paths checked on your machine |
658
- | Incomplete config | Both `workspaceId` and `authCookie` are required; check `/quota_status` for which field is missing |
659
- | Scrape returns no data | The auth cookie may have expired; get a fresh one from your browser |
660
- | Dashboard format changed | The SolidJS SSR pattern may have changed; file an issue or wait for the official API |
434
+ | Symptom | Fix |
435
+ | --- | --- |
436
+ | Config not detected | Set both `OPENCODE_GO_WORKSPACE_ID` and `OPENCODE_GO_AUTH_COOKIE`, then rerun `/quota_status`. |
437
+ | Incomplete config | `workspaceId` and `authCookie` must come from the same source. |
438
+ | Scrape returns no data | Refresh the browser `auth` cookie from `opencode.ai`. |
439
+ | Dashboard format changed | This integration scrapes the dashboard, so it can break if the dashboard markup changes. |
661
440
 
662
441
  </details>
663
442
 
664
- ## Configuration Reference
665
-
666
- All quota plugin settings live under `experimental.quotaToast` in `opencode.json` or `opencode.jsonc`.
667
-
668
- Project/workspace config may override display-oriented settings for that project, but user/global config remains authoritative for automatic/network-affecting settings such as `enabled`, `enabledProviders`, `minIntervalMs`, `pricingSnapshot.*`, `showOnIdle`, `showOnQuestion`, `showOnCompact`, and `showOnBothFail`. SDK config is only used when no config files are found.
669
-
670
- ### Core/shared settings
671
-
672
- | Option | Default | Meaning |
673
- | ----------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
674
- | `enabled` | `true` | Master switch for quota collection and handled slash commands. When `false`, `/quota`, `/quota_status`, `/pricing_refresh`, and `/tokens_*` are handled as no-ops. |
675
- | `enabledProviders` | `"auto"` | Auto-detect providers, or set an explicit provider list. |
676
- | `minIntervalMs` | `300000` | Minimum fetch interval between provider updates. |
677
- | `formatStyle` | `classic` | Shared quota-row style for popup toasts and the TUI sidebar: `classic` or `grouped`. Legacy `toastStyle` is still accepted on read for backward compatibility, but `formatStyle` is the canonical key. |
678
- | `percentDisplayMode` | `remaining` | Shared percent meaning for popup toasts and the TUI sidebar: `remaining` renders labels like `81% left`, while `used` renders labels like `19% used`; the bar fill always matches the shown meaning. |
679
- | `onlyCurrentModel` | `false` | Filter quota rows to the current model/provider when that session selection can be resolved. |
680
- | `showSessionTokens` | `true` | Show the `Session input/output tokens` section in quota displays when session token data is available. Toasts and `/quota` show per-model input/output rows; the TUI sidebar shows a one-line total summary. |
681
- | `pricingSnapshot.source` | `"auto"` | Token pricing snapshot selection for `/tokens_*`: `auto`, `bundled`, or `runtime`. |
682
- | `pricingSnapshot.autoRefresh` | `7` | Refresh stale local pricing data after this many days. |
683
-
684
- `percentDisplayMode` affects popup toasts and the TUI sidebar only. `/quota` keeps its existing remaining-oriented percentage output. Value-only rows such as spend or used/limit summaries are unchanged.
685
-
686
- ### Toast settings
687
-
688
- | Option | Default | Meaning |
689
- | ----------------- | ------- | ------------------------------------------------------------------------------- |
690
- | `enableToast` | `true` | Show popup toasts. Disabling this does not disable `/quota` or the TUI sidebar. |
691
- | `toastDurationMs` | `9000` | Toast duration in milliseconds. |
692
- | `showOnIdle` | `true` | Show a toast on the idle trigger. |
693
- | `showOnQuestion` | `true` | Show a toast after a question/assistant response. |
694
- | `showOnCompact` | `true` | Show a toast after session compaction. |
695
- | `showOnBothFail` | `true` | Show a fallback toast when providers attempted quota reads and all failed. |
696
- | `layout.maxWidth` | `50` | Toast formatting width target. Ignored by the TUI sidebar. |
697
- | `layout.narrowAt` | `42` | Toast compact-layout breakpoint. Ignored by the TUI sidebar. |
698
- | `layout.tinyAt` | `32` | Toast tiny-layout breakpoint. Ignored by the TUI sidebar. |
699
- | `debug` | `false` | Append toast debug context when troubleshooting. |
700
-
701
- ### TUI sidebar setup
702
-
703
- If you want the `Quota` sidebar panel, you need **two files**:
704
-
705
- 1. **`tui.json` or `tui.jsonc`**: add the plugin entry so OpenCode mounts the sidebar panel.
706
- 2. **`opencode.json` or `opencode.jsonc`**: put all quota settings under `experimental.quotaToast`.
707
-
708
- **Important:** `experimental.quotaToast.*` settings do **not** go in `tui.json`. `tui.json` is only for loading the TUI plugin.
709
-
710
- | File | What goes there | Needed for sidebar? |
711
- | ---------------------------------- | ---------------------------------------- | ------------------- |
712
- | `tui.json` / `tui.jsonc` | `plugin: ["@slkiser/opencode-quota"]` | Yes |
713
- | `opencode.json` / `opencode.jsonc` | All `experimental.quotaToast.*` settings | Yes |
714
-
715
- ### Provider-specific settings
716
-
717
- | Option | Default | Meaning |
718
- | ---------------------------- | ------------ | ---------------------------------------------------------------------------------------------------- |
719
- | `anthropicBinaryPath` | `"claude"` | Command/path used for local Claude CLI probing; override this for custom installs or shim locations. |
720
- | `googleModels` | `["CLAUDE"]` | Google model keys to query: `CLAUDE`, `G3PRO`, `G3FLASH`, `G3IMAGE`. |
721
- | `alibabaCodingPlanTier` | `"lite"` | Fallback Alibaba Coding Plan tier when auth does not include `tier`. |
722
- | `cursorPlan` | `"none"` | Cursor included API budget preset: `none`, `pro`, `pro-plus`, `ultra`. |
723
- | `cursorIncludedApiUsd` | unset | Override Cursor monthly included API budget in USD. |
724
- | `cursorBillingCycleStartDay` | unset | Local billing-cycle anchor day `1..28`; when unset, Cursor usage resets on the local calendar month. |
725
-
726
- ## Token Pricing Snapshot
727
-
728
- `/tokens_*` uses a local `models.dev` pricing snapshot. A bundled snapshot ships for offline use, and Cursor `auto` and `composer*` pricing stays bundled because those ids are not on `models.dev`.
729
-
730
- | `pricingSnapshot.source` | Active pricing behavior |
731
- | ------------------------ | ----------------------------------------------------------------------------------------- |
732
- | `auto` | Newer runtime snapshot wins; otherwise bundled pricing stays active. |
733
- | `bundled` | Packaged bundled snapshot stays active. |
734
- | `runtime` | Runtime snapshot stays active when present; bundled pricing is fallback until one exists. |
735
-
736
- - See [Configuration Reference](#configuration-reference) for option defaults.
737
- - `pricingSnapshot.autoRefresh` controls how many days a runtime snapshot can age before background refresh.
738
- - `/pricing_refresh` refreshes only the local runtime snapshot under the OpenCode cache directory. It never rewrites the packaged bundled snapshot.
739
- - If `pricingSnapshot.source` is `bundled`, `/pricing_refresh` still updates the runtime cache, but active pricing stays bundled.
740
- - Reports keep working if refresh fails.
741
- - Pricing selection stays local and deterministic. There are no custom URLs or arbitrary pricing sources.
742
-
743
- ## Troubleshooting
744
-
745
- If something is missing or looks wrong:
746
-
747
- 1. Run `/quota_status`.
748
- 2. Confirm the expected provider appears in the detected provider list.
749
- 3. If token reports are empty, make sure OpenCode has already created `opencode.db`.
750
- 4. If Copilot managed billing is expected, confirm `copilot-quota-token.json` is present and valid.
751
- 5. If provider setup looks wrong, check [Provider Setup At A Glance](#provider-setup-at-a-glance) and [Provider-Specific Notes](#provider-specific-notes). For Google Antigravity or Qwen Code, confirm the companion auth plugin is installed. For Alibaba Coding Plan, confirm OpenCode `alibaba` or `alibaba-coding-plan` auth is configured; `tier` may be `lite` or `pro`, and if it is missing the plugin falls back to `experimental.quotaToast.alibabaCodingPlanTier`.
443
+ <details>
444
+ <summary><strong>Token Reports</strong></summary>
752
445
 
753
- If `opencode.db` is missing, start OpenCode once and let its local migration complete.
446
+ Run `/quota_status` and check pricing snapshot health plus OpenCode database paths.
754
447
 
755
- ## Contribution
448
+ | Symptom | Fix |
449
+ | --- | --- |
450
+ | `/tokens_*` is empty | Start OpenCode once so it creates `opencode.db`, then run a session with model usage. |
451
+ | Pricing looks stale | Run `/pricing_refresh`. |
452
+ | Runtime pricing does not change output | Check `experimental.quotaToast.pricingSnapshot.source`; `bundled` keeps packaged pricing active. |
453
+ | Cursor model has unknown pricing | Run `/pricing_refresh`; Cursor `auto` and `composer*` use bundled deterministic pricing. |
756
454
 
757
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for contribution workflow and repository policy.
455
+ </details>
758
456
 
759
- ## License
457
+ ### License
760
458
 
761
459
  MIT
762
460
 
763
- ## Remarks
461
+ ### Remarks
764
462
 
765
463
  OpenCode Quota is not built by the OpenCode team and is not affiliated with OpenCode or any provider listed above.
766
464
 
767
- ## Star History
768
- [![Star History Chart](https://api.star-history.com/chart?repos=slkiser/opencode-quota&type=date&legend=bottom-right)](https://www.star-history.com/?repos=slkiser%2Fopencode-quota&type=date&legend=bottom-right)
769
-
465
+ ### Star History
770
466
 
467
+ [![Star History Chart](https://api.star-history.com/chart?repos=slkiser/opencode-quota&type=date&legend=bottom-right)](https://www.star-history.com/?repos=slkiser%2Fopencode-quota&type=date&legend=bottom-right)