new: [opencode-greenpt-usage] add GreenPT credit balance plugin

Show the remaining GreenPT API credit balance in the OpenCode TUI
sidebar. The key is resolved from the ``apiKey`` option, the
``GREENPT_API_KEY`` environment variable, or the active OpenCode
``auth.json`` (provider ``greenpt``); the section is hidden when no key
is present, so the plugin stays portable across machines and profiles.

The balance is read from the ``x-credits-remaining`` header returned by
a free ``HEAD /v1/chat/completions`` probe (HTTP 400 before any credit
is consumed), which avoids a billable call per refresh. Tests cover the
credential resolution, the header parsing and the live API.

Distribute via git clone; there is no npm publish.
This commit is contained in:
Stéphan Sainléger
2026-09-29 21:54:23 +02:00
commit 5c11754e2d
18 changed files with 5268 additions and 0 deletions

102
README.md Normal file
View File

@@ -0,0 +1,102 @@
# opencode-greenpt-usage
An [OpenCode](https://opencode.ai) TUI plugin that shows the remaining
**GreenPT API credit balance** in the sidebar.
```
▼ GreenPT
Balance 5.31 € updated 21:35
```
## How it works
- The API key is resolved in this order:
1. the plugin `apiKey` option;
2. the `GREENPT_API_KEY` environment variable;
3. the **active** OpenCode auth store (`auth.json`, provider `greenpt`,
entry `type: "api"`) — i.e. exactly what a plain `opencode auth login`
produces.
- The balance is read with a **free** `HEAD /v1/chat/completions` probe:
the API answers `400 Bad Request` before any billing, yet the response
still carries the `x-credits-remaining` header. No credit is consumed
and no generation is triggered.
- The section is **hidden while no GreenPT key is present**.
- Refresh happens on startup, at the end of a session, on server
reconnection, on a timer (300 s by default) and on demand through the
`greenpt.refresh` command.
There is no dependency on any local profile or command: the plugin only
looks for a key.
## Requirements
- OpenCode `>= 1.18.0` (TUI plugin system).
- A GreenPT account and API key.
## Installation
1. **Clone this repository** wherever you keep your projects.
2. **Connect GreenPT to OpenCode**:
```bash
opencode auth login
```
Pick **GreenPT** from the list, then paste the API key.
(Alternative: export `GREENPT_API_KEY` in your environment.)
3. **Register the plugin** in `~/.config/opencode/tui.json`, setting the
**absolute path to your clone**:
```jsonc
{
"$schema": "https://opencode.ai/tui.json",
"plugin": [
["file:///ABSOLUTE/PATH/TO/opencode-greenpt-usage/src/index.tsx", { "order": 700 }]
]
}
```
> Use a `file://` URL pointing at the source file `src/index.tsx`
> (OpenCode compiles the TSX itself). Do not point at a bundle: that
> would embed a second copy of `solid-js` and the section would stay
> blank.
4. **Fully quit OpenCode and relaunch it** (plugins are not hot-reloaded).
## Configuration
All options are optional and go in the plugin entry of `tui.json`:
| Option | Type | Default | Description |
| --------------------- | ------- | --------------------------- | ------------------------------------------------------- |
| `apiKey` | string | resolved automatically | Explicit GreenPT key. |
| `baseUrl` | string | `https://api.greenpt.ai/v1` | GreenPT API base URL. |
| `refreshInterval` | number | `300` | Refresh interval in seconds (`0` disables the timer). |
| `order` | number | `700` | Sidebar section position. |
| `showWhenUnavailable` | boolean | `false` | Show a hint when no GreenPT key exists. |
| `unit` | string | `€` | Unit appended after the amount. |
## Troubleshooting
- **The section does not appear**: make sure `opencode auth login` stored a
`greenpt` key (or that `GREENPT_API_KEY` is set), and that the `file://`
URL in `tui.json` points at the right path.
- **"invalid GreenPT key"**: the API key was rejected (HTTP 401).
- **"balance unavailable"**: GreenPT did not return the balance header; try
again later.
## Development
```bash
npm install
npm test # unit tests
npm run typecheck # type check
GREENPT_API_KEY=... npm run test:integration # test against the live API
```
## License
AGPL-3.0-or-later. See [LICENSE](LICENSE).