@xtruder/opencode-claude-max-plugin 0.4.5 → 2.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,106 +1,100 @@
1
1
  # @xtruder/opencode-claude-max-plugin
2
2
 
3
- An [OpenCode](https://opencode.ai/) plugin that enables Claude Pro/Max subscription access via the official [`@anthropic-ai/sdk`](https://github.com/anthropics/anthropic-sdk-typescript), using OAuth credentials from Claude Code (`~/.claude/.credentials.json`).
3
+ Use Claude Pro/Max subscription credentials in OpenCode, with a subscription-usage sidebar and `/usage` dialog. The plugin uses the official Anthropic SDK through OpenCode's AI SDK adapter.
4
4
 
5
- ![Usage sidebar and /usage command dialog](assets/example-with-usage.png)
6
-
7
- ## Why?
8
-
9
- - **Use your Claude subscription** — Automatically reads OAuth credentials from Claude Code, no separate API key needed
10
- - **Matches Claude Code 2.1.220** — Same request format and behavior as the official CLI
11
- - **Prompt caching** — Multi-turn conversations cache properly, keeping costs and latency low
12
- - **Supported Claude models** — Opus 5, Sonnet 5, Fable 5, Opus 4.8, Opus 4.7, Opus 4.6, Sonnet 4.6, Haiku 4.5
13
- - **Extended / adaptive thinking** — Full reasoning support across models, including Claude 5 adaptive thinking
14
- - **Safety-refusal fallback** — Opus 5 and Fable 5 classifier refusals can fall back in the same request, with TUI notification
15
- - **Usage tracking** — Sidebar widget with live progress bars + `/usage` command
16
- - **Self-registering** — Models are registered automatically, no manual provider config needed
5
+ **Requires OpenCode 2.0.16 or later. OpenCode v1 is not supported.** Model availability depends on your account.
17
6
 
18
7
  ## Installation
19
8
 
20
- Add the plugin to your `opencode.json` (project-level or `~/.config/opencode/opencode.json` globally):
9
+ Sign in to Claude Code, then add the plugin to `~/.config/opencode/opencode.json` or your existing `opencode.jsonc`:
10
+
11
+ ```sh
12
+ claude auth login
13
+ ```
21
14
 
22
15
  ```json
23
16
  {
24
- "$schema": "https://opencode.ai/config.json",
25
- "plugin": ["@xtruder/opencode-claude-max-plugin"]
17
+ "plugins": ["@xtruder/opencode-claude-max-plugin"]
26
18
  }
27
19
  ```
28
20
 
29
- That's it. The plugin self-registers the `anthropic-sdk` provider and its models (Haiku 4.5, Sonnet 4.6, Sonnet 5, Opus 4.6, Opus 4.7, Opus 4.8, Opus 5, Fable 5) at startup via the OpenCode config hook. No separate `provider` block is needed.
30
-
31
- Then open OpenCode and models will automatically be available under `anthropic-sdk` provider.
21
+ OpenCode installs the package and discovers both its provider and terminal UI. No separate provider configuration is needed. Restart OpenCode after changing the configuration; if you use a shared server, restart it and the terminal client.
32
22
 
33
- ### TUI Plugin (sidebar + /usage command)
23
+ When migrating from v1, replace the old `plugin` entry with the v2 `plugins` configuration and remove any separate registration of `src/tui.tsx`. Use a v2-compatible plugin release; version 0.4.6 predates this migration.
34
24
 
35
- The plugin includes a TUI component that shows subscription usage in the sidebar and registers a `/usage` slash command. To enable it, add the plugin to your `tui.json` as well:
25
+ ## Authentication
36
26
 
37
- **Project-level** (`.opencode/tui.json`):
27
+ For subscription access, sign in with Claude Code:
38
28
 
39
- ```json
40
- {
41
- "plugin": ["@xtruder/opencode-claude-max-plugin"]
42
- }
29
+ ```sh
30
+ claude auth login
43
31
  ```
44
32
 
45
- **Or globally** (`~/.config/opencode/tui.json`):
33
+ The plugin reads `~/.claude/.credentials.json`. Credential refresh is deferred until an inference request needs it.
46
34
 
47
- ```json
48
- {
49
- "plugin": ["@xtruder/opencode-claude-max-plugin"]
50
- }
51
- ```
52
-
53
- The TUI plugin provides:
35
+ Authentication is selected in this order:
54
36
 
55
- - **Sidebar widget** — Compact progress bars for 5-hour session and 7-day weekly usage
56
- - **`/usage` command** — Opens a dialog with full usage breakdown (per-model, extra usage)
57
- - **Auto-refresh** — Polls the usage API every 60s and after each inference call
58
- - **Fallback indicator** — Toast when a classifier refusal falls back, plus a sidebar line showing which model served the latest turn
37
+ 1. An explicit `apiKey` plugin option.
38
+ 2. The `ANTHROPIC_API_KEY` environment variable.
39
+ 3. Claude Code's OAuth credentials.
59
40
 
60
- #### TUI Configuration
41
+ If you intend to use your subscription, make sure an API key is not overriding it. API-key requests use API billing rather than subscription access.
61
42
 
62
- Options can be set in the `tui.json` plugin entry:
43
+ For a custom credentials file, supply server plugin options:
63
44
 
64
45
  ```json
65
46
  {
66
- "plugin": [
67
- [
68
- "@xtruder/opencode-claude-max-plugin",
69
- {
70
- "enabled": true,
71
- "sidebar": true,
72
- "poll_interval": 60
47
+ "plugins": [
48
+ {
49
+ "package": "@xtruder/opencode-claude-max-plugin",
50
+ "options": {
51
+ "credentialsPath": "/absolute/path/to/.credentials.json"
73
52
  }
74
- ]
53
+ }
75
54
  ]
76
55
  }
77
56
  ```
78
57
 
79
- | Option | Type | Default | Description |
80
- | --------------- | ------- | ------- | ----------------------------------------- |
81
- | `enabled` | boolean | `true` | Enable/disable the TUI plugin entirely |
82
- | `sidebar` | boolean | `true` | Show/hide sidebar usage widget |
83
- | `poll_interval` | number | `60` | Seconds between usage API polls (min: 10) |
58
+ The credentials must be accessible to the process running the provider. The usage TUI reads credentials on the machine running the terminal client.
59
+
60
+ ## Usage
61
+
62
+ Choose a model from the `anthropic-sdk` provider in OpenCode, or run:
63
+
64
+ ```sh
65
+ opencode run --standalone -m anthropic-sdk/claude-haiku-4-5 'Reply with exactly OK.'
66
+ opencode run --standalone -m 'anthropic-sdk/claude-sonnet-5#high' 'Explain this code.'
67
+ ```
68
+
69
+ Registered models (each row is a separate selectable entry):
84
70
 
85
- ### Custom model options
71
+ | Model | OpenCode model ID |
72
+ | ---------------- | ------------------ |
73
+ | Claude Haiku 4.5 | `claude-haiku-4-5` |
74
+ | Claude Sonnet 5 | `claude-sonnet-5` |
75
+ | Claude Opus 4.8 | `claude-opus-4-8` |
76
+ | Claude Opus 5 | `claude-opus-5` |
77
+ | Claude Opus 5.5 | `claude-opus-5-5` |
78
+ | Claude Fable 5 | `claude-fable-5` |
79
+ | Claude Fable 5.1 | `claude-fable-5-1` |
86
80
 
87
- If you want to override model settings (e.g. thinking budgets, variants), you can add a `provider` block alongside the plugin:
81
+ [Claude Opus 5](https://platform.claude.com/docs/en/models/opus-5/overview) remains available as a legacy model; it is not an alias for [Opus 5.5](https://platform.claude.com/docs/en/models/opus-5-5/overview). Anthropic names it “Claude Opus 5”, not “Claude Opus 5.0”.
82
+
83
+ Sonnet 4.6, Opus 4.6 (including the `-1m` variant), and Opus 4.7 are no longer registered by this plugin. Select a supported model when continuing sessions that used them.
84
+
85
+ Registration does not guarantee account access to a model. Use these OpenCode IDs rather than dated API aliases.
86
+
87
+ ### Model settings
88
+
89
+ Use OpenCode v2's `providers` configuration for model overrides. For example, to disable refusal fallback for a model:
88
90
 
89
91
  ```json
90
92
  {
91
- "$schema": "https://opencode.ai/config.json",
92
- "plugin": ["@xtruder/opencode-claude-max-plugin"],
93
- "provider": {
93
+ "providers": {
94
94
  "anthropic-sdk": {
95
95
  "models": {
96
- "claude-sonnet-4-6": {
97
- "options": {
98
- "thinking": { "type": "enabled", "budgetTokens": 1024 }
99
- },
100
- "variants": {
101
- "high": { "thinking": { "type": "enabled", "budgetTokens": 10000 } },
102
- "max": { "thinking": { "type": "enabled", "budgetTokens": 32000 } }
103
- }
96
+ "claude-fable-5": {
97
+ "settings": { "refusalFallback": false }
104
98
  }
105
99
  }
106
100
  }
@@ -108,94 +102,85 @@ If you want to override model settings (e.g. thinking budgets, variants), you ca
108
102
  }
109
103
  ```
110
104
 
111
- Config-level settings are merged with plugin defaults — you only need to specify what you want to override.
105
+ The provider supports model-specific prompts, prompt caching, thinking, tool calls, pause-turn continuation, and server-side refusal fallbacks. See [RESEARCH.md](RESEARCH.md) for request-format details.
106
+
107
+ ## Subscription usage
112
108
 
113
- ### Claude Fable 5 and safety-refusal fallback
109
+ The terminal sidebar shows available 5-hour and 7-day usage windows and reset times. Run `/usage` or select it from the command palette for additional model-specific windows and extra-usage status. Press Escape to close the dialog.
114
110
 
115
- Claude Fable 5 (`claude-fable-5`) ships with stricter safety classifiers that can refuse a request at the API level (`stop_reason: "refusal"`) — even for benign follow-ups if the conversation contains a flagged topic. To keep sessions usable, the plugin enables Anthropic's server-side fallback by default: when Fable 5 refuses, **Opus 4.8 answers the same request in the same round trip**. Tool loops keep running, thinking chains stay verified, and prompt caching is unaffected.
111
+ Usage comes from subscription data, not estimates derived from token counts. It is separate from OpenCode's native token/cost statistics.
116
112
 
117
- When a fallback happens:
113
+ The display checks its shared cache every 60 seconds by default. Usage API results are cached for five minutes; opening `/usage` does not bypass that cache or rate-limit backoff. Failed requests retain cached values with a status notice. Fetching usage does not send an inference request or launch Claude Code to refresh credentials.
118
114
 
119
- - The TUI shows a toast (`fable-5 refused — answered by opus-4-8`) on the first fallback turn
120
- - The sidebar shows a `Model Fallback` line while the latest turn was served by the fallback model
121
- - The served model is recorded in part metadata (`anthropic.servedBy`) — the model's own self-report will still say `claude-fable-5`, since identity comes from the prompt, not the serving model
115
+ ### TUI settings
122
116
 
123
- Configure via the `refusalFallback` model option:
117
+ Defaults work with the server plugin registration alone. To customize the terminal UI, add an entry to `~/.config/opencode/cli.json`:
124
118
 
125
119
  ```json
126
120
  {
127
- "provider": {
128
- "anthropic-sdk": {
129
- "models": {
130
- "claude-fable-5": {
131
- "options": {
132
- "refusalFallback": false
133
- }
134
- }
121
+ "plugins": [
122
+ {
123
+ "package": "@xtruder/opencode-claude-max-plugin",
124
+ "options": {
125
+ "enabled": true,
126
+ "sidebar": true,
127
+ "poll_interval": 60
135
128
  }
136
129
  }
137
- }
130
+ ]
138
131
  }
139
132
  ```
140
133
 
141
- Set it to another model ID to change the fallback target, or `false` to disable (refusals then surface as errors with the refusal category).
142
-
143
- Claude Opus 5 also has safety classifiers. Its `refusalFallback` defaults to `"default"`, which lets Anthropic select the recommended fallback for each refusal category. Override or disable it through the same model option on `claude-opus-5`.
134
+ | Option | Default | Description |
135
+ | ----------------- | ----------------------------- | ---------------------------------------------------------- |
136
+ | `enabled` | `true` | Enable the usage TUI. |
137
+ | `sidebar` | `true` | Show sidebar usage. Disabling it keeps `/usage` available. |
138
+ | `poll_interval` | `60` | Cache polling interval in seconds; minimum 10. |
139
+ | `credentialsPath` | `~/.claude/.credentials.json` | Credentials file used by the usage TUI. |
144
140
 
145
- ## Authentication
141
+ Server plugin options are not automatically passed to the TUI. Set a custom TUI credentials path in `cli.json`, even if it is already configured for the server. The usage cache is shared within an XDG state directory, not separated by credentials file or account.
146
142
 
147
- Credentials are resolved in order:
143
+ ## Development
148
144
 
149
- 1. **`ANTHROPIC_API_KEY` env var** or **`apiKey` provider option**
150
- 2. **Claude Code credentials** — auto-read from `~/.claude/.credentials.json`
145
+ Building and testing require **Node.js 26.4+ and npm**. Bun is not required for this workflow. Run these commands from a checkout of the repository:
151
146
 
152
- For Claude Code credentials, log in via `claude` CLI first (`claude auth login`).
147
+ ```sh
148
+ npm ci
149
+ npm run build
150
+ npm run dev # rebuild on changes
151
+ npm run typecheck
152
+ npm run lint
153
+ npm run format:check
154
+ npm test
155
+ ```
153
156
 
154
- ## Features
157
+ Vite builds three ESM entrypoints: `build/index.js` (AI SDK provider), `build/server.js` (OpenCode registration), and `build/tui.js` (terminal UI). It compiles Solid JSX for OpenTUI and embeds prompt `.txt` files into JavaScript. Keep the entire `build/` directory together, including shared chunks.
155
158
 
156
- - Streaming and non-streaming completions
157
- - Tool/function calling with Claude Code tool name mapping (`task` → `Agent`, `webfetch` → `WebFetch`, etc.)
158
- - MCP tool name remapping (`server_tool` → `mcp__server__tool`)
159
- - Extended thinking (Sonnet/Opus 4.6) and adaptive thinking (Opus 4.7+, Sonnet 5) with effort levels and multi-turn signature passthrough
160
- - Prompt caching that holds across long, tool-heavy conversations
161
- - Server-side safety-refusal fallback for Opus 5 and Fable 5 (configurable, on by default)
162
- - Subscription rate limit detection — fails fast with a clear message instead of hanging
163
- - Long-context auto-detection for large prompts
164
- - TUI sidebar with live usage bars + `/usage` slash command
159
+ The build currently also runs TypeScript declaration generation for the exported provider API. `npm run typecheck` checks types without emitting files. `npm run dev` watches JavaScript and prompt changes; run the full build before packaging to refresh declarations.
165
160
 
166
- ## With Vercel AI SDK
161
+ The `aisdk:` prefix is applied internally to the provider's runtime file URL. Do not add it to the plugin name in your configuration. Runtime packages remain external to the bundle; the plugin uses OpenCode's adapter rather than maintaining a second transport implementation.
167
162
 
168
- The plugin also works as a standalone Vercel AI SDK provider:
163
+ ### Testing
169
164
 
170
- ```typescript
171
- import { CLAUDE_CODE_SYSTEM_PROMPT, createAnthropicSDK } from "@xtruder/opencode-claude-max-plugin"
172
- import { streamText } from "ai"
165
+ `npm test` builds the plugin and runs offline tests with Vitest. It does not perform Claude inference.
173
166
 
174
- // Uses ~/.claude/.credentials.json automatically
175
- const provider = createAnthropicSDK()
176
- const model = provider.languageModel("claude-sonnet-4-6")
167
+ For a real terminal integration check:
177
168
 
178
- const result = streamText({
179
- model,
180
- system: CLAUDE_CODE_SYSTEM_PROMPT,
181
- prompt: "Hello!",
182
- })
183
- for await (const chunk of result.textStream) {
184
- process.stdout.write(chunk)
185
- }
169
+ ```sh
170
+ npm run test:tui-smoke
186
171
  ```
187
172
 
188
- When using Claude Code OAuth credentials outside OpenCode, you must pass a Claude-compatible system prompt yourself. Exported `CLAUDE_CODE_SYSTEM_PROMPT` is the prompt used by the OpenCode plugin hook.
173
+ This requires OpenCode, Python, and `uv`. It starts an isolated OpenCode instance with fixture usage data and checks the sidebar, dialog, resizing, polling, and error states. It does not attach to your running server or send model prompts.
189
174
 
190
- ## Development
175
+ Live Claude tests are explicit opt-in:
191
176
 
192
- ```bash
193
- bun install
194
- bun run build
195
- bun test src/*.test.ts # unit + integration tests (model tests require ANTHROPIC_API_KEY or Claude Code credentials)
177
+ ```sh
178
+ npm run test:live
196
179
  ```
197
180
 
198
- See [RESEARCH.md](RESEARCH.md) for detailed reverse-engineering findings on how we matched Claude Code's request format.
181
+ These tests can consume quota and refresh credentials.
182
+
183
+ Native Node rendering uses OpenTUI's experimental `node:ffi` backend, which requires Node 26.4+ and may print an experimental warning. Standalone Node TUI harnesses must select Solid's reactive runtime with `--conditions=browser`. The plugin has also been tested in the Bun-compiled OpenCode 2.0.16 host; using npm to build the plugin does not change the host's runtime.
199
184
 
200
185
  ## License
201
186