@khalilgharbaoui/opencode-claude-code-plugin 0.8.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 CHANGED
@@ -92,6 +92,34 @@ Variants set the underlying reasoning effort. They're regular opencode model var
92
92
 
93
93
  ---
94
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
+
95
123
  ## Configuration
96
124
 
97
125
  The minimum config is just the `plugin` entry above. Everything below is optional override that goes in a `provider.claude-code` block.
@@ -251,7 +279,7 @@ Claude Code ships a built-in `WebSearch` tool. The `webSearch` option controls w
251
279
 
252
280
  | `webSearch` value | Behavior | When to use |
253
281
  |---|---|---|
254
- | `"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. |
255
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. |
256
284
  | `"disabled"` | `WebSearch` is added to `--disallowedTools` so the model can't call it. | Compliance/security scenarios where outbound search isn't allowed. |
257
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 === "WebSearch" || name === "web_search") {
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();