@khalilgharbaoui/opencode-claude-code-plugin 0.7.0 → 0.8.1
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 +45 -11
- package/dist/index.js +67 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ claude --version
|
|
|
23
23
|
|
|
24
24
|
That's it. Restart opencode, pick a `claude-code` model, done.
|
|
25
25
|
|
|
26
|
-
The plugin self-registers the `claude-code` provider, all current Claude Code models (Haiku 4.5, Sonnet 4.5/4.6, Opus 4.5/4.6/4.7/4.8) with reasoning variants (`low` / `medium` / `high` / `xhigh` / `max`), and sensible defaults for tool proxying. You don't need to write a `provider` block at all unless you want to override something.
|
|
26
|
+
The plugin self-registers the `claude-code` provider, all current Claude Code models (Haiku 4.5, Sonnet 4.5/4.6, Opus 4.5/4.6/4.7/4.8, Fable 5, Mythos 5) with reasoning variants (`low` / `medium` / `high` / `xhigh` / `max`), and sensible defaults for tool proxying. You don't need to write a `provider` block at all unless you want to override something.
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
@@ -66,18 +66,24 @@ In your `opencode.json`, point at the local build with a `file://` URL:
|
|
|
66
66
|
|
|
67
67
|
The plugin auto-registers the following. They appear in the model picker without any extra config.
|
|
68
68
|
|
|
69
|
-
| ID | Display name | Context | Output | Reasoning variants |
|
|
70
|
-
|
|
71
|
-
| `claude-haiku-4-5` | Claude
|
|
72
|
-
| `claude-sonnet-4-5` | Claude
|
|
73
|
-
| `claude-sonnet-4-6` | Claude
|
|
74
|
-
| `claude-opus-4-5` | Claude
|
|
75
|
-
| `claude-opus-4-6` | Claude
|
|
76
|
-
| `claude-opus-4-7` | Claude
|
|
77
|
-
| `claude-opus-4-8` | Claude
|
|
69
|
+
| ID | Display name | Context | Output | Reasoning variants | Price × |
|
|
70
|
+
|---|---|---|---|---|---|
|
|
71
|
+
| `claude-haiku-4-5` | Claude Haiku 4.5 | 200k | 8,192 | – | 1× |
|
|
72
|
+
| `claude-sonnet-4-5` | Claude Sonnet 4.5 | 1M | 16,384 | low/medium/high/xhigh/max | 3× |
|
|
73
|
+
| `claude-sonnet-4-6` | Claude Sonnet 4.6 | 1M | 16,384 | low/medium/high/xhigh/max | 3× |
|
|
74
|
+
| `claude-opus-4-5` | Claude Opus 4.5 | 1M | 16,384 | low/medium/high/xhigh/max | 5× |
|
|
75
|
+
| `claude-opus-4-6` | Claude Opus 4.6 | 1M | 16,384 | low/medium/high/xhigh/max | 5× |
|
|
76
|
+
| `claude-opus-4-7` | Claude Opus 4.7 | 1M | 16,384 | low/medium/high/xhigh/max | 5× |
|
|
77
|
+
| `claude-opus-4-8` | Claude Opus 4.8 | 1M | 16,384 | low/medium/high/xhigh/max | 5× |
|
|
78
|
+
| `claude-fable-5` | Claude Fable 5 | 1M | 16,384 | low/medium/high/xhigh/max | 10× |
|
|
79
|
+
| `claude-mythos-5` | Claude Mythos 5 | 1M | 16,384 | low/medium/high/xhigh/max | 10× |
|
|
80
|
+
|
|
81
|
+
`claude-mythos-5` is Mythos-class like Fable 5 but without safety classifiers, and is **limited availability via [Project Glasswing](https://anthropic.com/glasswing)**. It's registered unconditionally; if your Claude account lacks access, `claude --model claude-mythos-5` just errors. Use `claude-fable-5` (generally available) otherwise.
|
|
78
82
|
|
|
79
83
|
Capabilities for every model: text + image input, text output, tool use, attachments. No temperature control, no PDF/audio/video, no interleaved streaming.
|
|
80
84
|
|
|
85
|
+
**Price ×** is each model's per-token list price relative to Haiku, the cheapest model. It's derived exactly from Anthropic's published pricing — input and output ratios both come out the same (Haiku $1/$5 = 1×, Sonnet $3/$15 = 3×, Opus 4.8 $5/$25 = 5×, Fable 5 / Mythos 5 $10/$50 = 10×), so **Fable 5 and Mythos 5 cost 2× Opus 4.8**. The same multiplier is shown as a `(N×)` suffix on the display name in opencode's model picker, since opencode has no dedicated multiplier field. On a flat Max/Pro subscription it doubles as a rough guide to how fast each model drains your usage limit.
|
|
86
|
+
|
|
81
87
|
The model ID is passed straight through to `claude --model`, so anything Claude Code accepts works.
|
|
82
88
|
|
|
83
89
|
### Picking a variant
|
|
@@ -86,6 +92,34 @@ Variants set the underlying reasoning effort. They're regular opencode model var
|
|
|
86
92
|
|
|
87
93
|
---
|
|
88
94
|
|
|
95
|
+
## Billing change: June 15, 2026 (Agent SDK credit)
|
|
96
|
+
|
|
97
|
+
This plugin drives Claude Code headlessly (`claude --print`), which Anthropic bills as [`claude -p` / Agent SDK usage](https://support.claude.com/en/articles/15036540-use-the-claude-agent-sdk-with-your-claude-plan). Starting **June 15, 2026**, on subscription plans that usage no longer counts toward your normal plan limits — it draws from a separate monthly **Agent SDK credit**:
|
|
98
|
+
|
|
99
|
+
| Plan | Monthly credit |
|
|
100
|
+
|---|---|
|
|
101
|
+
| Pro | $20 |
|
|
102
|
+
| Max 5x | $100 |
|
|
103
|
+
| Max 20x | $200 |
|
|
104
|
+
| Team Standard | $20/seat |
|
|
105
|
+
| Team Premium | $100/seat |
|
|
106
|
+
| Enterprise (Standard seats) | none |
|
|
107
|
+
|
|
108
|
+
What this means for plugin users:
|
|
109
|
+
|
|
110
|
+
- **Claim the credit once.** It's a one-time opt-in via your Claude account (claim emails started going out June 8, 2026); after that it refreshes every billing cycle. Unused credit does not roll over.
|
|
111
|
+
- **When the credit runs out, plugin requests stop** until the next billing cycle — unless you enable usage credits in your Claude account, in which case overflow is billed at standard API rates.
|
|
112
|
+
- **The credit is denominated in dollars at standard API rates**, so the Price × column above maps directly to how fast each model drains it — Fable 5 / Mythos 5 burn it 10× faster than Haiku, 2× faster than Opus 4.8.
|
|
113
|
+
- **API-key auth is unaffected.** If your `claude` CLI authenticates with an Anthropic API key / Console billing instead of a subscription, nothing changes — pay-as-you-go as before.
|
|
114
|
+
- **Interactive Claude Code in your terminal is unaffected.** The change targets programmatic usage only: the Agent SDK, `claude -p`, Claude Code GitHub Actions, and third-party apps like this plugin.
|
|
115
|
+
|
|
116
|
+
Two related dates:
|
|
117
|
+
|
|
118
|
+
- **June 15, 2026** also retires the original Claude 4 model IDs `claude-sonnet-4-20250514` and `claude-opus-4-20250514` from the API. The plugin doesn't register either, but model IDs pass straight through to `claude --model` — if you've configured one of these as an override, migrate to `claude-sonnet-4-6` / `claude-opus-4-8` before then.
|
|
119
|
+
- **June 22, 2026** is the last day [Fable 5 is included at no extra cost](https://platform.claude.com/docs/en/about-claude/models/introducing-claude-fable-5-and-claude-mythos-5) on Pro, Max, Team, and seat-based Enterprise plans. From June 23, `claude-fable-5` requires usage credits (Anthropic says it aims to fold it back into plans once capacity allows). `claude-mythos-5` is unaffected — it's Glasswing access-gated either way.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
89
123
|
## Configuration
|
|
90
124
|
|
|
91
125
|
The minimum config is just the `plugin` entry above. Everything below is optional override that goes in a `provider.claude-code` block.
|
|
@@ -245,7 +279,7 @@ Claude Code ships a built-in `WebSearch` tool. The `webSearch` option controls w
|
|
|
245
279
|
|
|
246
280
|
| `webSearch` value | Behavior | When to use |
|
|
247
281
|
|---|---|---|
|
|
248
|
-
| `"claude"` (default) | Claude CLI runs WebSearch internally via Anthropic. Zero setup, no extra cost, no API key. | Most users. |
|
|
282
|
+
| `"claude"` (default) | Claude CLI runs WebSearch internally via Anthropic. Zero setup, no extra cost, no API key. The query is shown in the transcript as a `> Web search:` line (opencode has no `WebSearch` tool registry entry, so a raw tool row would render as `⚙ invalid`). | Most users. |
|
|
249
283
|
| `"<opencode-tool-name>"` (e.g. `"websearch_web_search_exa"`) | Forward to that opencode-side tool with `executed:false`. Requires the corresponding MCP server to be configured in opencode (e.g. [exa-mcp-server](https://github.com/exa-labs/exa-mcp-server)). | You want a specific search backend (Exa, Tavily, Brave) and have the MCP wired up in opencode. |
|
|
250
284
|
| `"disabled"` | `WebSearch` is added to `--disallowedTools` so the model can't call it. | Compliance/security scenarios where outbound search isn't allowed. |
|
|
251
285
|
|
package/dist/index.js
CHANGED
|
@@ -210,6 +210,12 @@ function clearLedger(sessionId) {
|
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
// src/tool-mapping.ts
|
|
213
|
+
function isWebSearchTool(name) {
|
|
214
|
+
return name === "WebSearch" || name === "web_search";
|
|
215
|
+
}
|
|
216
|
+
function isWebSearchHandledByCli(route) {
|
|
217
|
+
return !route || route === "claude" || route === "disabled";
|
|
218
|
+
}
|
|
213
219
|
function mapToolInput(name, input) {
|
|
214
220
|
if (!input) return input;
|
|
215
221
|
switch (name) {
|
|
@@ -326,7 +332,7 @@ function mapTool(name, input, opts) {
|
|
|
326
332
|
const mappedInput = mapToolInput(name, input);
|
|
327
333
|
return { name: "todowrite", input: mappedInput, executed: false };
|
|
328
334
|
}
|
|
329
|
-
if (name
|
|
335
|
+
if (isWebSearchTool(name)) {
|
|
330
336
|
const mappedInput = input?.query ? { query: input.query } : input;
|
|
331
337
|
const route = opts?.webSearch;
|
|
332
338
|
if (route && route !== "claude" && route !== "disabled") {
|
|
@@ -334,7 +340,7 @@ function mapTool(name, input, opts) {
|
|
|
334
340
|
return { name: route, input: mappedInput, executed: false };
|
|
335
341
|
}
|
|
336
342
|
log.debug("WebSearch executed by Claude CLI", { mappedInput });
|
|
337
|
-
return { name: "WebSearch", input: mappedInput, executed: true };
|
|
343
|
+
return { name: "WebSearch", input: mappedInput, executed: true, skip: true };
|
|
338
344
|
}
|
|
339
345
|
if (name === "TaskOutput") {
|
|
340
346
|
if (!input) return { name: "bash", executed: false };
|
|
@@ -3495,6 +3501,17 @@ ${plan}
|
|
|
3495
3501
|
|
|
3496
3502
|
---
|
|
3497
3503
|
**Do you want to proceed with this plan?** (yes/no)
|
|
3504
|
+
`
|
|
3505
|
+
});
|
|
3506
|
+
endTextBlock();
|
|
3507
|
+
} else if (isWebSearchTool(tc.name) && isWebSearchHandledByCli(self.config.webSearch)) {
|
|
3508
|
+
const query = typeof parsedInput?.query === "string" ? parsedInput.query : JSON.stringify(parsedInput);
|
|
3509
|
+
const searchId = startTextBlock();
|
|
3510
|
+
controller.enqueue({
|
|
3511
|
+
type: "text-delta",
|
|
3512
|
+
id: searchId,
|
|
3513
|
+
delta: `
|
|
3514
|
+
> **Web search:** ${query}
|
|
3498
3515
|
`
|
|
3499
3516
|
});
|
|
3500
3517
|
endTextBlock();
|
|
@@ -3654,6 +3671,18 @@ ${plan}
|
|
|
3654
3671
|
|
|
3655
3672
|
---
|
|
3656
3673
|
**Do you want to proceed with this plan?** (yes/no)
|
|
3674
|
+
`
|
|
3675
|
+
});
|
|
3676
|
+
endTextBlock();
|
|
3677
|
+
} else if (isWebSearchTool(block.name) && isWebSearchHandledByCli(self.config.webSearch)) {
|
|
3678
|
+
toolCallsById.delete(block.id);
|
|
3679
|
+
const query = typeof parsedInput?.query === "string" ? parsedInput.query : JSON.stringify(parsedInput);
|
|
3680
|
+
const searchId = startTextBlock();
|
|
3681
|
+
controller.enqueue({
|
|
3682
|
+
type: "text-delta",
|
|
3683
|
+
id: searchId,
|
|
3684
|
+
delta: `
|
|
3685
|
+
> **Web search:** ${query}
|
|
3657
3686
|
`
|
|
3658
3687
|
});
|
|
3659
3688
|
endTextBlock();
|
|
@@ -4128,7 +4157,7 @@ function defineModel(opts) {
|
|
|
4128
4157
|
id: opts.id,
|
|
4129
4158
|
providerID: PROVIDER_ID,
|
|
4130
4159
|
api: { id: opts.id, url: "", npm: NPM },
|
|
4131
|
-
name: opts.name
|
|
4160
|
+
name: `${opts.name} (${opts.multiplier}\xD7)`,
|
|
4132
4161
|
family: opts.family,
|
|
4133
4162
|
capabilities: { ...baseCapabilities, reasoning: opts.reasoning },
|
|
4134
4163
|
cost: {
|
|
@@ -4146,7 +4175,8 @@ function defineModel(opts) {
|
|
|
4146
4175
|
}
|
|
4147
4176
|
var haikuCost = { input: 1e-6, output: 5e-6, cacheRead: 1e-7, cacheWrite: 125e-8 };
|
|
4148
4177
|
var sonnetCost = { input: 3e-6, output: 15e-6, cacheRead: 3e-7, cacheWrite: 375e-8 };
|
|
4149
|
-
var opusCost = { input:
|
|
4178
|
+
var opusCost = { input: 5e-6, output: 25e-6, cacheRead: 5e-7, cacheWrite: 625e-8 };
|
|
4179
|
+
var fableCost = { input: 1e-5, output: 5e-5, cacheRead: 1e-6, cacheWrite: 125e-7 };
|
|
4150
4180
|
function toConfigModel(model) {
|
|
4151
4181
|
const inputMods = [];
|
|
4152
4182
|
const outputMods = [];
|
|
@@ -4188,6 +4218,7 @@ var defaultModels = {
|
|
|
4188
4218
|
context: 2e5,
|
|
4189
4219
|
output: 8192,
|
|
4190
4220
|
cost: haikuCost,
|
|
4221
|
+
multiplier: 1,
|
|
4191
4222
|
releaseDate: "2024-10-22"
|
|
4192
4223
|
}),
|
|
4193
4224
|
"claude-sonnet-4-5": defineModel({
|
|
@@ -4198,6 +4229,7 @@ var defaultModels = {
|
|
|
4198
4229
|
context: 1e6,
|
|
4199
4230
|
output: 16384,
|
|
4200
4231
|
cost: sonnetCost,
|
|
4232
|
+
multiplier: 3,
|
|
4201
4233
|
releaseDate: "2025-04-14"
|
|
4202
4234
|
}),
|
|
4203
4235
|
"claude-sonnet-4-6": defineModel({
|
|
@@ -4208,6 +4240,7 @@ var defaultModels = {
|
|
|
4208
4240
|
context: 1e6,
|
|
4209
4241
|
output: 16384,
|
|
4210
4242
|
cost: sonnetCost,
|
|
4243
|
+
multiplier: 3,
|
|
4211
4244
|
releaseDate: "2025-06-19"
|
|
4212
4245
|
}),
|
|
4213
4246
|
"claude-opus-4-5": defineModel({
|
|
@@ -4218,6 +4251,7 @@ var defaultModels = {
|
|
|
4218
4251
|
context: 1e6,
|
|
4219
4252
|
output: 16384,
|
|
4220
4253
|
cost: opusCost,
|
|
4254
|
+
multiplier: 5,
|
|
4221
4255
|
releaseDate: "2025-04-14"
|
|
4222
4256
|
}),
|
|
4223
4257
|
"claude-opus-4-6": defineModel({
|
|
@@ -4228,6 +4262,7 @@ var defaultModels = {
|
|
|
4228
4262
|
context: 1e6,
|
|
4229
4263
|
output: 16384,
|
|
4230
4264
|
cost: opusCost,
|
|
4265
|
+
multiplier: 5,
|
|
4231
4266
|
releaseDate: "2025-06-19"
|
|
4232
4267
|
}),
|
|
4233
4268
|
"claude-opus-4-7": defineModel({
|
|
@@ -4238,6 +4273,7 @@ var defaultModels = {
|
|
|
4238
4273
|
context: 1e6,
|
|
4239
4274
|
output: 16384,
|
|
4240
4275
|
cost: opusCost,
|
|
4276
|
+
multiplier: 5,
|
|
4241
4277
|
releaseDate: "2025-07-16"
|
|
4242
4278
|
}),
|
|
4243
4279
|
"claude-opus-4-8": defineModel({
|
|
@@ -4248,7 +4284,34 @@ var defaultModels = {
|
|
|
4248
4284
|
context: 1e6,
|
|
4249
4285
|
output: 16384,
|
|
4250
4286
|
cost: opusCost,
|
|
4287
|
+
multiplier: 5,
|
|
4251
4288
|
releaseDate: "2026-05-28"
|
|
4289
|
+
}),
|
|
4290
|
+
"claude-fable-5": defineModel({
|
|
4291
|
+
id: "claude-fable-5",
|
|
4292
|
+
name: "Claude Fable 5",
|
|
4293
|
+
family: "fable",
|
|
4294
|
+
reasoning: true,
|
|
4295
|
+
context: 1e6,
|
|
4296
|
+
output: 16384,
|
|
4297
|
+
cost: fableCost,
|
|
4298
|
+
multiplier: 10,
|
|
4299
|
+
releaseDate: "2026-06-09"
|
|
4300
|
+
}),
|
|
4301
|
+
// Mythos 5 shares Fable 5's capabilities and pricing without the safety
|
|
4302
|
+
// classifiers; limited availability via Project Glasswing. `claude --model
|
|
4303
|
+
// claude-mythos-5` simply errors for accounts without access, so it's safe to
|
|
4304
|
+
// register unconditionally.
|
|
4305
|
+
"claude-mythos-5": defineModel({
|
|
4306
|
+
id: "claude-mythos-5",
|
|
4307
|
+
name: "Claude Mythos 5",
|
|
4308
|
+
family: "mythos",
|
|
4309
|
+
reasoning: true,
|
|
4310
|
+
context: 1e6,
|
|
4311
|
+
output: 16384,
|
|
4312
|
+
cost: fableCost,
|
|
4313
|
+
multiplier: 10,
|
|
4314
|
+
releaseDate: "2026-06-09"
|
|
4252
4315
|
})
|
|
4253
4316
|
};
|
|
4254
4317
|
|