@xtruder/opencode-claude-max-plugin 0.1.0 → 0.1.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/README.md +204 -44
- package/build/index.js +3 -0
- package/build/model.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,91 +8,251 @@ An [OpenCode](https://opencode.ai/) plugin that enables Claude Pro/Max subscript
|
|
|
8
8
|
- **Matches Claude Code exactly** — Same headers, billing, tool names, and request format as Claude Code CLI
|
|
9
9
|
- **Prompt caching** — 98% of input tokens served from cache (system prompt + tools cached globally)
|
|
10
10
|
- **All Claude models** — Opus 4.6, Sonnet 4.6, Sonnet 4.5, Haiku 4.5, and more
|
|
11
|
-
- **Extended thinking** — Full reasoning support with
|
|
11
|
+
- **Extended thinking** — Full reasoning support with thinking variants (high/max)
|
|
12
12
|
- **Usage tracking** — Built-in `/usage` command shows subscription utilization
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
npm install @xtruder/opencode-claude-max-plugin
|
|
18
|
-
# or
|
|
19
|
-
bun add @xtruder/opencode-claude-max-plugin
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## Quick Start
|
|
16
|
+
You do not need to install the package manually — OpenCode auto-installs it when it first loads your config.
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Add to `.opencode/opencode.json`. If you have Claude Code credentials (`~/.claude/.credentials.json`), no environment variable is needed:
|
|
18
|
+
Just add the following to `.opencode/opencode.json` in your project (or `~/.config/opencode/opencode.json` globally):
|
|
27
19
|
|
|
28
20
|
```json
|
|
29
21
|
{
|
|
22
|
+
"$schema": "https://opencode.ai/config.json",
|
|
30
23
|
"provider": {
|
|
31
24
|
"anthropic-sdk": {
|
|
32
25
|
"npm": "@xtruder/opencode-claude-max-plugin",
|
|
33
26
|
"name": "Anthropic SDK",
|
|
34
27
|
"models": {
|
|
35
|
-
"claude-sonnet-4-6":
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
"claude-sonnet-4-6": {
|
|
29
|
+
"name": "Claude Sonnet 4.6",
|
|
30
|
+
"attachment": false,
|
|
31
|
+
"reasoning": true,
|
|
32
|
+
"tool_call": true,
|
|
33
|
+
"temperature": true,
|
|
34
|
+
"options": {
|
|
35
|
+
"thinking": { "type": "enabled", "budgetTokens": 10000 }
|
|
36
|
+
},
|
|
37
|
+
"variants": {
|
|
38
|
+
"normal": { "thinking": { "type": "enabled", "budgetTokens": 1024 } },
|
|
39
|
+
"high": { "thinking": { "type": "enabled", "budgetTokens": 10000 } },
|
|
40
|
+
"max": { "thinking": { "type": "enabled", "budgetTokens": 32000 } }
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"claude-opus-4-6": {
|
|
44
|
+
"name": "Claude Opus 4.6",
|
|
45
|
+
"attachment": false,
|
|
46
|
+
"reasoning": true,
|
|
47
|
+
"tool_call": true,
|
|
48
|
+
"temperature": true,
|
|
49
|
+
"options": {
|
|
50
|
+
"thinking": { "type": "adaptive" }
|
|
51
|
+
},
|
|
52
|
+
"variants": {
|
|
53
|
+
"normal": { "thinking": { "type": "adaptive" } },
|
|
54
|
+
"high": { "thinking": { "type": "enabled", "budgetTokens": 10000 } },
|
|
55
|
+
"max": { "thinking": { "type": "enabled", "budgetTokens": 32000 } }
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"claude-opus-4-5-20251101": {
|
|
59
|
+
"name": "Claude Opus 4.5",
|
|
60
|
+
"attachment": false,
|
|
61
|
+
"reasoning": true,
|
|
62
|
+
"tool_call": true,
|
|
63
|
+
"temperature": true,
|
|
64
|
+
"options": {
|
|
65
|
+
"thinking": { "type": "enabled", "budgetTokens": 10000 }
|
|
66
|
+
},
|
|
67
|
+
"variants": {
|
|
68
|
+
"normal": { "thinking": { "type": "enabled", "budgetTokens": 1024 } },
|
|
69
|
+
"high": { "thinking": { "type": "enabled", "budgetTokens": 10000 } },
|
|
70
|
+
"max": { "thinking": { "type": "enabled", "budgetTokens": 32000 } }
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"claude-sonnet-4-5-20250929": {
|
|
74
|
+
"name": "Claude Sonnet 4.5",
|
|
75
|
+
"attachment": false,
|
|
76
|
+
"reasoning": true,
|
|
77
|
+
"tool_call": true,
|
|
78
|
+
"temperature": true,
|
|
79
|
+
"options": {
|
|
80
|
+
"thinking": { "type": "enabled", "budgetTokens": 10000 }
|
|
81
|
+
},
|
|
82
|
+
"variants": {
|
|
83
|
+
"normal": { "thinking": { "type": "enabled", "budgetTokens": 1024 } },
|
|
84
|
+
"high": { "thinking": { "type": "enabled", "budgetTokens": 10000 } },
|
|
85
|
+
"max": { "thinking": { "type": "enabled", "budgetTokens": 32000 } }
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"claude-haiku-4-5-20251001": {
|
|
89
|
+
"name": "Claude Haiku 4.5",
|
|
90
|
+
"attachment": false,
|
|
91
|
+
"reasoning": false,
|
|
92
|
+
"tool_call": true,
|
|
93
|
+
"temperature": true
|
|
94
|
+
},
|
|
95
|
+
"claude-opus-4-1-20250805": {
|
|
96
|
+
"name": "Claude Opus 4.1",
|
|
97
|
+
"attachment": false,
|
|
98
|
+
"reasoning": true,
|
|
99
|
+
"tool_call": true,
|
|
100
|
+
"temperature": true,
|
|
101
|
+
"options": {
|
|
102
|
+
"thinking": { "type": "enabled", "budgetTokens": 10000 }
|
|
103
|
+
},
|
|
104
|
+
"variants": {
|
|
105
|
+
"normal": { "thinking": { "type": "enabled", "budgetTokens": 1024 } },
|
|
106
|
+
"high": { "thinking": { "type": "enabled", "budgetTokens": 10000 } },
|
|
107
|
+
"max": { "thinking": { "type": "enabled", "budgetTokens": 32000 } }
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"claude-opus-4-20250514": {
|
|
111
|
+
"name": "Claude Opus 4",
|
|
112
|
+
"attachment": false,
|
|
113
|
+
"reasoning": true,
|
|
114
|
+
"tool_call": true,
|
|
115
|
+
"temperature": true,
|
|
116
|
+
"options": {
|
|
117
|
+
"thinking": { "type": "enabled", "budgetTokens": 10000 }
|
|
118
|
+
},
|
|
119
|
+
"variants": {
|
|
120
|
+
"normal": { "thinking": { "type": "enabled", "budgetTokens": 1024 } },
|
|
121
|
+
"high": { "thinking": { "type": "enabled", "budgetTokens": 10000 } },
|
|
122
|
+
"max": { "thinking": { "type": "enabled", "budgetTokens": 32000 } }
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"claude-sonnet-4-20250514": {
|
|
126
|
+
"name": "Claude Sonnet 4",
|
|
127
|
+
"attachment": false,
|
|
128
|
+
"reasoning": true,
|
|
129
|
+
"tool_call": true,
|
|
130
|
+
"temperature": true,
|
|
131
|
+
"options": {
|
|
132
|
+
"thinking": { "type": "enabled", "budgetTokens": 10000 }
|
|
133
|
+
},
|
|
134
|
+
"variants": {
|
|
135
|
+
"normal": { "thinking": { "type": "enabled", "budgetTokens": 1024 } },
|
|
136
|
+
"high": { "thinking": { "type": "enabled", "budgetTokens": 10000 } },
|
|
137
|
+
"max": { "thinking": { "type": "enabled", "budgetTokens": 32000 } }
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
"claude-3-haiku-20240307": {
|
|
141
|
+
"name": "Claude 3 Haiku",
|
|
142
|
+
"attachment": false,
|
|
143
|
+
"reasoning": false,
|
|
144
|
+
"tool_call": true,
|
|
145
|
+
"temperature": true
|
|
146
|
+
}
|
|
38
147
|
}
|
|
39
148
|
}
|
|
40
149
|
}
|
|
41
150
|
}
|
|
42
151
|
```
|
|
43
152
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
import { createAnthropicSDK } from "@xtruder/opencode-claude-max-plugin";
|
|
48
|
-
import { streamText, generateText } from "ai";
|
|
49
|
-
|
|
50
|
-
// Uses ~/.claude/.credentials.json automatically
|
|
51
|
-
const provider = createAnthropicSDK();
|
|
52
|
-
const model = provider.languageModel("claude-sonnet-4-6");
|
|
53
|
-
|
|
54
|
-
const result = streamText({ model, prompt: "Hello!" });
|
|
55
|
-
for await (const chunk of result.textStream) {
|
|
56
|
-
process.stdout.write(chunk);
|
|
57
|
-
}
|
|
58
|
-
```
|
|
153
|
+
Then open OpenCode and run `/connect` → Other → `anthropic-sdk`. If Claude Code is installed and you're logged in, credentials are read automatically from `~/.claude/.credentials.json` — no API key needed.
|
|
59
154
|
|
|
60
155
|
## Authentication
|
|
61
156
|
|
|
62
157
|
Credentials are resolved in order:
|
|
63
158
|
|
|
64
|
-
1. **`
|
|
159
|
+
1. **`ANTHROPIC_API_KEY` env var** or **`apiKey` provider option**
|
|
65
160
|
2. **Claude Code credentials** — auto-read from `~/.claude/.credentials.json`
|
|
66
161
|
|
|
67
|
-
For Claude Code credentials, log in via `claude` CLI first.
|
|
162
|
+
For Claude Code credentials, log in via `claude` CLI first (`claude auth login`).
|
|
163
|
+
|
|
164
|
+
## Models
|
|
165
|
+
|
|
166
|
+
| Model ID | Name | Thinking | Notes |
|
|
167
|
+
|---|---|---|---|
|
|
168
|
+
| `claude-opus-4-6` | Claude Opus 4.6 | ✓ | Native 1M context window |
|
|
169
|
+
| `claude-sonnet-4-6` | Claude Sonnet 4.6 | ✓ | ~120K token limit on subscription |
|
|
170
|
+
| `claude-opus-4-5-20251101` | Claude Opus 4.5 | ✓ | |
|
|
171
|
+
| `claude-sonnet-4-5-20250929` | Claude Sonnet 4.5 | ✓ | |
|
|
172
|
+
| `claude-haiku-4-5-20251001` | Claude Haiku 4.5 | — | 200K token hard limit |
|
|
173
|
+
| `claude-opus-4-1-20250805` | Claude Opus 4.1 | ✓ | |
|
|
174
|
+
| `claude-opus-4-20250514` | Claude Opus 4 | ✓ | |
|
|
175
|
+
| `claude-sonnet-4-20250514` | Claude Sonnet 4 | ✓ | |
|
|
176
|
+
| `claude-3-haiku-20240307` | Claude 3 Haiku | — | |
|
|
177
|
+
|
|
178
|
+
### Thinking variants
|
|
179
|
+
|
|
180
|
+
Reasoning models support thinking levels selectable in OpenCode via `/model`:
|
|
181
|
+
|
|
182
|
+
| Variant | Opus 4.6 | Other reasoning models |
|
|
183
|
+
|---|---|---|
|
|
184
|
+
| **normal** | `adaptive` (Claude decides) | `enabled`, 1024 tokens |
|
|
185
|
+
| **high** | `enabled`, 10000 tokens | `enabled`, 10000 tokens |
|
|
186
|
+
| **max** | `enabled`, 32000 tokens | `enabled`, 32000 tokens |
|
|
187
|
+
|
|
188
|
+
Opus 4.6 uses `{ type: "adaptive" }` by default — Claude decides when and how much to think. This is the recommended mode for Opus 4.6. Other models use `{ type: "enabled", budgetTokens: N }` with a fixed budget.
|
|
189
|
+
|
|
190
|
+
Budget values match Claude Code's defaults: `al1 = 1024` (normal), `10000` (high), `32000` (max).
|
|
68
191
|
|
|
69
192
|
## Context Window Limits
|
|
70
193
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
|
74
|
-
|
|
75
|
-
|
|
|
194
|
+
Tested on Claude Max subscription (Extra usage disabled):
|
|
195
|
+
|
|
196
|
+
| Model | Included context | Above limit |
|
|
197
|
+
|---|---|---|
|
|
198
|
+
| Opus 4.6 | ~615K+ tokens (native 1M) | Not tested |
|
|
199
|
+
| Sonnet 4.6 | ~120K tokens | 429 — enable Extra usage at claude.ai |
|
|
200
|
+
| Haiku 4.5 | 200K tokens (hard limit) | `prompt is too long` error |
|
|
76
201
|
|
|
77
202
|
## Features
|
|
78
203
|
|
|
79
204
|
- Streaming and non-streaming completions
|
|
80
|
-
- Tool/function calling with Claude Code tool name mapping
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
205
|
+
- Tool/function calling with Claude Code tool name mapping (`task` → `Agent`, etc.)
|
|
206
|
+
- MCP tool name remapping (`server_tool` → `mcp__server__tool`)
|
|
207
|
+
- Extended thinking with signature passthrough for multi-turn conversations
|
|
208
|
+
- Prompt caching (98% cache hit rate with full OpenCode tool set)
|
|
209
|
+
- Subscription rate limit detection — fails fast with clear message instead of hanging
|
|
210
|
+
- Long context auto-detection — adds `context-1m` beta header when request body is large
|
|
211
|
+
- `/usage` slash command — shows current session and weekly utilization
|
|
212
|
+
|
|
213
|
+
## Usage Command
|
|
214
|
+
|
|
215
|
+
After adding the config, run `/usage` inside OpenCode to see your subscription usage:
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
Claude Subscription Usage
|
|
219
|
+
────────────────────────────────────────────────────
|
|
220
|
+
Current session
|
|
221
|
+
████████████████████████████████░░░░░░░░░░░░░░░░░░ 67% used
|
|
222
|
+
Resets 7:00 PM GMT+1
|
|
223
|
+
|
|
224
|
+
Current week (all models)
|
|
225
|
+
████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8% used
|
|
226
|
+
Resets Mar 30, 7:00 AM GMT+2
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## With Vercel AI SDK
|
|
230
|
+
|
|
231
|
+
The plugin also works as a standalone Vercel AI SDK provider:
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import { createAnthropicSDK } from "@xtruder/opencode-claude-max-plugin";
|
|
235
|
+
import { streamText } from "ai";
|
|
236
|
+
|
|
237
|
+
// Uses ~/.claude/.credentials.json automatically
|
|
238
|
+
const provider = createAnthropicSDK();
|
|
239
|
+
const model = provider.languageModel("claude-sonnet-4-6");
|
|
240
|
+
|
|
241
|
+
const result = streamText({ model, prompt: "Hello!" });
|
|
242
|
+
for await (const chunk of result.textStream) {
|
|
243
|
+
process.stdout.write(chunk);
|
|
244
|
+
}
|
|
245
|
+
```
|
|
86
246
|
|
|
87
247
|
## Development
|
|
88
248
|
|
|
89
249
|
```bash
|
|
90
250
|
bun install
|
|
91
251
|
bun run build
|
|
92
|
-
bun run test # 17 integration tests
|
|
252
|
+
bun run test # 17 integration tests (requires ANTHROPIC_API_KEY or Claude Code credentials)
|
|
93
253
|
```
|
|
94
254
|
|
|
95
|
-
See [RESEARCH.md](RESEARCH.md) for detailed reverse-engineering findings.
|
|
255
|
+
See [RESEARCH.md](RESEARCH.md) for detailed reverse-engineering findings on how we matched Claude Code's request format.
|
|
96
256
|
|
|
97
257
|
## License
|
|
98
258
|
|
package/build/index.js
CHANGED
|
@@ -653,6 +653,9 @@ class AnthropicSDKModel {
|
|
|
653
653
|
}
|
|
654
654
|
async doGenerate(options) {
|
|
655
655
|
const { params, warnings } = this.buildParams(options);
|
|
656
|
+
if (!options.maxOutputTokens && params.max_tokens > 4096) {
|
|
657
|
+
params.max_tokens = 4096;
|
|
658
|
+
}
|
|
656
659
|
let response;
|
|
657
660
|
try {
|
|
658
661
|
response = await this.client.messages.create({
|
package/build/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,0BAA0B,EAK3B,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAA;AAQ9C,KAAK,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;AAC1E,KAAK,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;AAqGtE,qBAAa,iBAAkB,YAAW,eAAe;IAQrD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IATjB,QAAQ,CAAC,oBAAoB,EAAG,IAAI,CAAS;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAK;gBAGnD,OAAO,EAAE,MAAM,EACP,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,OAAe;IAMlC,OAAO,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,0BAA0B,EAK3B,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAA;AAQ9C,KAAK,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;AAC1E,KAAK,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;AAqGtE,qBAAa,iBAAkB,YAAW,eAAe;IAQrD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IATjB,QAAQ,CAAC,oBAAoB,EAAG,IAAI,CAAS;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAK;gBAGnD,OAAO,EAAE,MAAM,EACP,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,OAAe;IAMlC,OAAO,CAAC,WAAW;IAsLb,UAAU,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAsE1E,QAAQ,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,cAAc,CAAC;CA2C7E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xtruder/opencode-claude-max-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "OpenCode plugin for Claude Max/Pro subscription via @anthropic-ai/sdk - uses Claude Code OAuth credentials",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|