@khalilgharbaoui/opencode-claude-code-plugin 0.60.0 → 0.60.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khalilgharbaoui/opencode-claude-code-plugin",
3
- "version": "0.60.0",
3
+ "version": "0.60.1",
4
4
  "description": "Claude Code CLI provider plugin for opencode",
5
5
  "homepage": "https://opencode-claude-code-plugin.dev/",
6
6
  "funding": {
@@ -652,7 +652,8 @@ Or once for every discovered subagent without a full provider/model pin:
652
652
  ```
653
653
 
654
654
  Rules, in order: on opencode 2 a model named for that dispatch in the conversation
655
- (the `task` call's `model`) wins over everything here; else `forceModel` wins; else
655
+ (the `task` call's `model`, recipe "One subagent on a model the user names") wins over
656
+ everything here; else `forceModel` wins; else
656
657
  `mode: subagent` with `defaultSubagentModel` set; else untouched. An agent with `model: <provider>/<id>` is left exactly as written,
657
658
  account and all (`model: claude-code-work/claude-opus-5@work` pins the account too).
658
659
  Undeclared built-ins are not discovered; a user definition with a built-in name can
@@ -692,6 +693,67 @@ the opencode schema requires it. Markdown fallback reads top-level scalar fields
692
693
  | `maxBudgetUsd` | Positive dollars, passed as `--max-budget-usd` (per process life, reset on resume). Discovered `mode: subagent` agents only; on a main agent it is refused with a WARN. Headless only. |
693
694
  | `fallbackModels` | Ordered registered bare model ids to try when this agent's model is refused. Both YAML spellings (`[a, b]` or a `- ` block). Replaces the provider-level `fallbackModels` rather than extending it. Keeps the caller's account; an entry carrying `@account` has it stripped. Unknown ids warn and are skipped. |
694
695
 
696
+ ### One subagent on a model the user names (opencode 2)
697
+
698
+ On opencode 2 the user can choose a subagent's model in the message itself, with no
699
+ configuration: the proxied `task` (and each `task_batch.tasks` item) takes an optional
700
+ `model`, forwarded to opencode's own `subagent` tool, which resolves it by exact id
701
+ against the models opencode has. opencode 1's `task` has no such field, so the plugin
702
+ leaves it out there; on 1.x point the user at `forceModel`, `defaultSubagentModel` or
703
+ `subagentDispatch: "ask"` instead. (PR #123, h #g254, h #g255.)
704
+
705
+ opencode's form is `providerID/modelID`, plus `#low`, `#medium`, `#high`, `#xhigh` or
706
+ `#max` for a reasoning variant (every model has them except `claude-haiku-4-5`):
707
+
708
+ | Install | Reference |
709
+ |---|---|
710
+ | No `accounts` | `claude-code/claude-sonnet-5-5` |
711
+ | `accounts`, the default account | `claude-code-default/claude-sonnet-5-5` |
712
+ | `accounts`, another account | `claude-code-<account>/claude-sonnet-5-5@<account>` |
713
+
714
+ A bare model id (`claude-sonnet-5-5`, `claude-sonnet-5-5#high`) is completed to the
715
+ reference this conversation's own provider serves (the first column's provider and
716
+ marker) before opencode sees it, so the subagent stays on the conversation's account.
717
+ Only an id the plugin registers is completed, and only with no `@` marker or the
718
+ provider's own; a full reference, another account's marker and an unknown id reach
719
+ opencode as written. Use the full reference only for another account or provider.
720
+
721
+ Tell the user to name the model by id: "Run the reviewer subagent on
722
+ `claude-sonnet-5-5#high`." Two ids in one request ("review it on `claude-opus-5-5` and
723
+ on `claude-sonnet-5-5`, in parallel") become one `task_batch` with a model per task. A
724
+ model named in words is a guess, and it depends on the model doing the dispatching.
725
+ Measured on opencode 2.0.31 with "a general subagent on Sonnet 5.5" and "on
726
+ claude-sonnet-5-5": Opus 5.5 passed `claude-code/claude-sonnet-5-5` first time; Haiku
727
+ 4.5 passed a bare `claude-sonnet-5-5` first both times, and before bare ids were
728
+ completed went on to `anthropic/claude-sonnet-5-5` and `claude-sonnet-5.5`, each refused
729
+ by opencode (`Invalid model "…"`, `Model "…" is not available`) with no subagent
730
+ started. With the completion both of Haiku's requests ran on the first call. A guessed
731
+ provider that IS in the user's opencode config would be accepted, though: an
732
+ `anthropic` provider serving that id would run the subagent there, outside this plugin
733
+ and billed to that provider. That is the reason to have the user name the model.
734
+
735
+ What the plugin adds on top of forwarding:
736
+
737
+ - The named model beats the agent's `forceModel` and `defaultSubagentModel`, and a
738
+ named `#variant` beats its `reasoningEffort`, which is opencode's own order. With no
739
+ variant the agent's effort still applies. A child resumed by `task_id` with a model
740
+ runs on it.
741
+ - A task that names a model is left out of the `subagentDispatch` form, and a dispatch
742
+ whose every task names one raises no form.
743
+ - A model on a plugin account outside the dispatching account's `accountGroups` group
744
+ is refused before any task of the call starts; `subagentDispatchCrossGroup: true`
745
+ lifts that. A model on any other provider is opencode's routing and is not checked.
746
+ - On 1.x a `model` set anyway is refused before dispatch, for the whole batch.
747
+
748
+ Claude is told to set `model` only when the user asked for one. If it ever sets one
749
+ unasked, that subagent runs on it, under the same rules.
750
+
751
+ Verify: the subagent's sidebar row shows the model it really spawned with, its tool row
752
+ shows the `model` opencode received (none there means opencode picked the model as
753
+ usual), and `plugin.log` has `bare task model completed to this conversation's own
754
+ provider` for a completion and `explicit task model claimed by its child session`. Every spawn logs
755
+ `task model gate` with `supported`, which is false on a 1.x host.
756
+
695
757
  ### Ask before each subagent dispatch
696
758
 
697
759
  Opt-in; off by default. Turns a fan-out into one question instead of a static agent file.
@@ -865,7 +927,7 @@ Names below become `mcp__opencode_proxy__<name>`; input config is case-insensiti
865
927
  | `edit` | `"Edit"`, default; replaces CLI Edit. |
866
928
  | `write` | `"Write"`, default; replaces CLI Write. |
867
929
  | `webfetch` | `"WebFetch"`, default; replaces CLI WebFetch. |
868
- | `task` | `"Task"`, default; disables CLI Agent and dispatches opencode subagents under its permissions. No proxy deadline by default; a positive `proxyToolTimeoutMs` entry adds one. Takes `background: true` only on a host that runs background subagents (see below). |
930
+ | `task` | `"Task"`, default; disables CLI Agent and dispatches opencode subagents under its permissions. No proxy deadline by default; a positive `proxyToolTimeoutMs` entry adds one. Takes `background: true` only on a host that runs background subagents (see below), and `model` only on opencode 2 (recipe "One subagent on a model the user names"). |
869
931
  | `task_batch` | Included with Task; one MCP call fans out two or more independent task inputs concurrently. Separate task calls were measured serial (2026-09-06, two 8-second calls: the second MCP request left the CLI 7 ms after the first resolved). The input must be a `tasks` array of at least two items, each with `description`, `prompt` and `subagent_type`; anything else is refused before the calls are queued. |
870
932
  | `task_status` | Included with Task, and only on a host that runs background subagents. Reads a background subagent's state by `task_id` and collects its result. A recovery path for a completion notification that never arrived, not a progress poll; a result is handed over once. Answered in-process (opencode has no such tool) and refuses any session that is not this conversation's subagent. Not nameable in `proxyTools`. |
871
933
  | `task_cancel` | Included with Task, same host gate as `task_status`. Aborts a background subagent's child session; a cancelled subagent sends no completion notification. |
@@ -884,13 +946,6 @@ rejects what the previous turn left pending and tells the CLI. The process exiti
884
946
  chat being deleted, or opencode exiting rejects the rest. That is why `task` and
885
947
  `task_batch` carry no default deadline and a subagent runs to completion.
886
948
 
887
- On opencode 2, `task` and each `task_batch.tasks` item take an optional `model`: opencode's exact `providerID/modelID` reference with an optional `#variant` (`claude-code/claude-sonnet-5-5#high`; on a multi-account install `claude-code-<account>/<model>@<account>`). The model is told to set it only when the user asked for a particular model, and only with an id the user gave. The proxy forwards it unchanged to opencode's own `subagent` tool, which resolves it against the models it has; omitted, opencode picks the model as usual, and `task_id` and `background` behave as before. What the plugin adds on top (h #g254):
888
-
889
- - An explicit model beats the agent's `forceModel` and `defaultSubagentModel`, and a named `#variant` beats its `reasoningEffort` (opencode's own order). The child's prologue finds the request by parent session, agent type and first message, the dispatch form's rule, and applies it only while the child runs on exactly that model.
890
- - A task that names a model is left out of the `subagentDispatch` form; a dispatch whose every task names one raises no form.
891
- - A model on a plugin account outside the dispatching account's `accountGroups` group is refused before any task of the call starts; `subagentDispatchCrossGroup: true` lifts it. A model on any other provider is opencode's own routing and is not checked.
892
- - opencode 1's `task` has no such field: the plugin reads the live `task` schema, leaves `model` out there, and refuses a call or a whole batch that sets it anyway, before dispatch.
893
-
894
949
  Three timers remain and are distinct from that: the optional per-tool deadlines
895
950
  (`proxyToolTimeoutMs`, a backstop the user chooses), the start and inactivity
896
951
  watchdogs (for a process that is alive but silent, which emits nothing to listen to; a
@@ -1203,6 +1258,8 @@ Useful log lines to search for (redact payloads): `spawning new claude process`,
1203
1258
  `bridged opencode skills into claude`, `interrupt sent for aborted turn`, `btw:`,
1204
1259
  `rendering opencode-side tool result as text`, `proxy-mcp tool call received`,
1205
1260
  `evicting idle claude process`, `evicting LRU claude process`, `background subagent gate`,
1261
+ `task model gate`, `bare task model completed`, `explicit task model claimed by its child session`,
1262
+ `task model refused`,
1206
1263
  `proxy call still waiting`, `fast mode` warnings.
1207
1264
 
1208
1265
  Version requirements. The first four are flag gates in `src/cli-version.ts`; the last two
@@ -1393,6 +1450,10 @@ Prefer the doctor: it needs no logging change and no restart.
1393
1450
  | `Subagent failed (task_id …): Tool execution aborted` while the child finished fine | Bug fixed in 0.15.1 | Upgrade |
1394
1451
  | A `subtask: true` command's subagent output is "lost" | Bug fixed in 0.15.4 | Upgrade |
1395
1452
  | Two subagents run one after another | The CLI serialises MCP calls | Plugin 0.17.0+; the model must use `mcp__opencode_proxy__task_batch` |
1453
+ | On opencode 2, a subagent the user asked for on a particular model ran on another | Claude passed no `model` (the subagent's tool row shows none), most often because the model was named in words and the dispatching model did not turn it into a reference; or the plugin is older than 0.60.0, whose `task` tool had no `model` | Have the user name the model by id (`claude-sonnet-5-5`, completed to this conversation's own account) or by full reference for another account; see "One subagent on a model the user names". If the tool row does carry a `model` and the sidebar row shows another model, that is a bug: ask for `/claude-code-doctor bundle` |
1454
+ | `Invalid model "…"` or `Model "…" is not available` on a subagent row, on opencode 2 | Claude passed a reference opencode does not have, usually a guess at a model named in words | Nothing ran: opencode refused it before starting anything, and Claude normally tries again. A bare id the plugin registers is completed instead of refused, so on a current plugin this is a misspelt id, another account's marker without its provider, or a guessed provider; an older plugin refused every bare id. Naming the model by id or full reference avoids the guessing |
1455
+ | A dispatch refused with `… which is outside this conversation's account group, so no tasks were started` | The `model` sits on a plugin account in another `accountGroups` group | Working as designed. Name a model on an account in this conversation's group, or set `subagentDispatchCrossGroup: true` only if the user wants groups crossed |
1456
+ | On opencode 1, Claude says its task tool cannot take a model, or a dispatch fails with "This opencode's task tool takes no per-call `model`" | opencode 1's `task` has no `model` field | Not available on 1.x. Use an agent's `forceModel`, `defaultSubagentModel`, or `subagentDispatch: "ask"` |
1396
1457
  | Esc does not stop Claude; aborted turns keep running | Plugin older than 0.16.0 | Upgrade |
1397
1458
  | Esc pressed in the first moment of a turn does nothing, and the turn runs and bills anyway | A turn prepares before it asks the CLI for anything (spawn directory, `claude --version`, opencode's MCP status and tool registry), and a stop that landed in that window used to be dropped. Fixed: the turn ends there, spawning nothing and writing nothing, and the reply is empty | Upgrade and fully relaunch every opencode window. Grep `plugin.log` for `abort while the turn was still being prepared` |
1398
1459
  | Under `opencode serve` or the web UI every project spawns Claude in the server's launch dir | Plugin older than 0.16.0 | Upgrade, or pin `cwd` |