@khalilgharbaoui/opencode-claude-code-plugin 0.47.0 → 0.49.0
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/dist/index.d.ts +16 -0
- package/dist/index.js +264 -55
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/claude-code-plugin/SKILL.md +39 -10
package/package.json
CHANGED
|
@@ -115,6 +115,7 @@ Defaults below describe normal headless opencode use when the key is absent.
|
|
|
115
115
|
| `accountFailover` | `"ask"` / `"off"` | `"off"` | **Opt-in: only an explicit `"ask"` opens the switch form**, so unset and `"off"` behave identically. `"ask"` ends a usage-limited turn on opencode's native `question` form listing the other configured accounts, and continues the task on the pick inside the same opencode turn. Only ever fires with more than one account configured. The pick is sticky for the LIMITED account until the limit's reset time (or until opencode restarts when the CLI reported none), so it covers every session on that account and subagents follow their parent; child sessions are never shown the form. Leaving it unanswered waits and costs nothing. `stop`, a dismissal, or text that is not one of the offered accounts ends the turn the way a limited turn ends without the form. Triggered only by a rejected `rate_limit_event`, one of the two known account-limit error texts, or one of the five account-level failure kinds the CLI names on its own error reply (`authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `verification_required`, `billing_error`); never by a generic failure. Never on compaction turns; both transports (the TUI's limit reply carries the same `error: "rate_limit"` kind). A switch carries the Claude conversation to the target account's config dir and resumes it there (`crossAccountResume`, default on) and only replays the thread as text when that copy is refused; either way, MCP servers configured only in the limited account's Claude profile are gone. With the default `"off"`, a limited turn ends on one `▌ **usage limit:**` note instead (see "When an account runs out of usage"). |
|
|
116
116
|
| `failoverAccounts` | string[] | unset/derived | Account expansion supplies the resolved account list so a limited account can offer the others. Do not hand-wire it; set `accounts` instead. |
|
|
117
117
|
| `baseCliPath` | string | unset/derived | The `cliPath` before the per-account wrapper substitution, so a failover can build another account's wrapper on the same binary. Supplied by the config hook. Do not hand-wire it. |
|
|
118
|
+
| `accountInProcess` | boolean | unset/derived | Set by the config hook on Windows, where there is no per-account wrapper script: the spawn exports `CLAUDE_CONFIG_DIR` itself and strips the `@<account>` marker off `--model`. Do not hand-wire it. |
|
|
118
119
|
| `defaultSubagentModel` | string | unset | Seed-config default for discovered `mode: subagent` agents without a full `provider/model` pin; `forceModel` takes precedence. Keeps the caller's account. Unknown ids warn and keep the inherited model. Not independently read per expanded account. |
|
|
119
120
|
| `defaultSubagentCacheTtl` | string | unset | Prompt cache TTL (`5m` / `1h`) for discovered `mode: subagent` agents that declare no `cacheTtl`; the agent's own value takes precedence. Unset leaves the CLI's default (1 hour on a subscription). Unknown values warn and change nothing. Headless and interactive spawns, never compaction. |
|
|
120
121
|
| `fallbackModels` | string[] | unset | Ordered models to try when the model a turn would run on is refused. Default for agents declaring no `fallbackModels`; a per-agent list replaces it rather than extending it. Same account throughout, never a switch. Armed only by the CLI refusing the model (`model_not_found`) or by a usage limit when the `accountFailover` form is not taking the turn, which is the case whenever it is `"off"` (its default) or has no other account to offer; with `"ask"` and another account the switch form wins. Entries must be registered model ids, unknown ones warn and are skipped, the current model is dropped from its own chain, each entry is tried at most once per turn, and an exhausted chain surfaces the original error. Never on compaction or title stubs; both transports. Writes a `▌ **model fallback:**` note that transcript rebuilds strip. Not independently read per expanded account. |
|
|
@@ -359,11 +360,24 @@ models have no suffix, other accounts have `@<account>` (`claude-opus-5@work`).
|
|
|
359
360
|
normalize to lowercase hyphen-separated ids, so choose distinct simple names.
|
|
360
361
|
After the user approves login, they authenticate each non-default account interactively,
|
|
361
362
|
for example `CLAUDE_CONFIG_DIR="$HOME/.claude-work" claude auth login`, using the chosen
|
|
362
|
-
binary. Never copy credentials between accounts. The
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
363
|
+
binary. Never copy credentials between accounts. The model suffix is stripped and the
|
|
364
|
+
config dir set by the generated bash wrapper on macOS and Linux; on **Windows there is
|
|
365
|
+
no wrapper at all** and the plugin does both itself on the spawn (`accountInProcess`),
|
|
366
|
+
because a `.cmd` forwarding `%*` would re-parse every argument a third time. Existing
|
|
367
|
+
`CLAUDE.md`, `settings.json`, `skills/`, `agents/`, `commands/`, `plugins/` in
|
|
368
|
+
`~/.claude` are linked only when targets are missing; existing targets stay untouched.
|
|
369
|
+
Directories become junctions on Windows; a file there falls back symlink -> hard link ->
|
|
370
|
+
copy, and a copy warns because it does not follow later edits. This shares
|
|
371
|
+
capabilities/settings, not an isolation boundary. Auth/session files are not part of the
|
|
372
|
+
shared list.
|
|
373
|
+
|
|
374
|
+
Each provider's display name carries the account's plan tier when it can be read:
|
|
375
|
+
`Claude Code (Work, Max 20x)`, also `Max 5x`, `Max`, `Pro`, `Team`, `Enterprise`. It
|
|
376
|
+
comes from `organizationType` plus `organizationRateLimitTier` in
|
|
377
|
+
`<config dir>/.claude.json` (the default account also falls back to the legacy
|
|
378
|
+
`~/.claude.json`), read-only, no token and no spawn, and nothing else in that file is
|
|
379
|
+
ever displayed or logged. Unreadable or unrecognised means no suffix. There is no
|
|
380
|
+
option for it.
|
|
367
381
|
|
|
368
382
|
### When an account runs out of usage
|
|
369
383
|
|
|
@@ -840,7 +854,7 @@ No manual skill copy/update is needed. Do not publish or release as part of conf
|
|
|
840
854
|
|
|
841
855
|
### Registered model ids
|
|
842
856
|
|
|
843
|
-
Registered ids: `claude-haiku-4-5`, `claude-sonnet-4-5`, `claude-sonnet-4-6`,
|
|
857
|
+
Registered ids: `claude-haiku-4-5`, `claude-haiku-5-5`, `claude-sonnet-4-5`, `claude-sonnet-4-6`,
|
|
844
858
|
`claude-sonnet-5`, `claude-sonnet-5-5`, `claude-opus-4-5`, `claude-opus-4-6`,
|
|
845
859
|
`claude-opus-4-7`, `claude-opus-4-8`, `claude-opus-4-8-fast`, `claude-opus-5`,
|
|
846
860
|
`claude-opus-5-fast`, `claude-opus-5-5`, `claude-opus-5-5-fast`, `claude-fable-5`,
|
|
@@ -848,10 +862,11 @@ Registered ids: `claude-haiku-4-5`, `claude-sonnet-4-5`, `claude-sonnet-4-6`,
|
|
|
848
862
|
|
|
849
863
|
### Variants and costs
|
|
850
864
|
|
|
851
|
-
- Display names end in a `(N×)` list-price multiplier
|
|
865
|
+
- Display names end in a `(N×)` list-price multiplier anchored on Haiku 4.5: 0.1× haiku 5.5,
|
|
866
|
+
1× haiku 4.5,
|
|
852
867
|
2× sonnet 5 and 5.5, 3× sonnet 4.5/4.6, 4× opus 5.5, 5× other opus, 8× fast-mode opus 5.5, 10× fable, mythos
|
|
853
868
|
and fast-mode opus 5 / 4.8. It is display only.
|
|
854
|
-
- Every model except Haiku has reasoning variants `low`, `medium`, `high`, `xhigh`,
|
|
869
|
+
- Every model except Haiku 4.5 has reasoning variants `low`, `medium`, `high`, `xhigh`,
|
|
855
870
|
`max`, picked in opencode's model selector. A variant becomes
|
|
856
871
|
`CLAUDE_CODE_EFFORT_LEVEL` on the spawned CLI unless an agent effort wins. For direct
|
|
857
872
|
AI-SDK calls, `ClaudeCodeCallOptions.reasoningEffort` supports the same levels plus
|
|
@@ -859,12 +874,24 @@ Registered ids: `claude-haiku-4-5`, `claude-sonnet-4-5`, `claude-sonnet-4-6`,
|
|
|
859
874
|
- The `-fast` ids are this plugin's own markers. They spawn the base model with
|
|
860
875
|
`--settings '{"fastMode":true}'` (Claude Code 2.1.220+). Fast mode fails soft: an
|
|
861
876
|
ineligible account runs at standard speed and the plugin logs a warning naming the
|
|
862
|
-
reason
|
|
877
|
+
reason, read off the terminal `result` rather than the `system`/`init` frame, which
|
|
878
|
+
is optimistic (2.1.288 says `"on"` at init and `"off" / extra_usage_disabled` at the
|
|
879
|
+
end for an account with usage credits off).
|
|
880
|
+
Switch to a non-fast id rather than silently enabling paid usage credits.
|
|
863
881
|
Review eligibility/billing with the user; the enabled state needs live verification
|
|
864
882
|
on their account. CLI floors are gates, not proof of model access.
|
|
865
883
|
- `claude-sonnet-5-5` needs Claude Code 2.1.284+ to run on its real limits. An older CLI
|
|
866
884
|
still serves it on fallback limits (200k context, an estimated cost), and the plugin
|
|
867
885
|
logs a WARN naming the model and the floor: the fix is `claude update`.
|
|
886
|
+
- `claude-haiku-5-5` needs Claude Code 2.1.293+ for the same reason, the release that
|
|
887
|
+
added it and made it the default Haiku. It is a tenth of Haiku 4.5 ($0.10/$0.50), has
|
|
888
|
+
a 1M context, 128k output and adaptive thinking, so it carries reasoning variants
|
|
889
|
+
where Haiku 4.5 does not, and it has no `-fast` id (the CLI's catalog gives it no
|
|
890
|
+
fast-mode capability). It is the only model Anthropic prices by prompt length: over
|
|
891
|
+
**100,000 prompt tokens** (input plus cache read plus cache write) the whole call
|
|
892
|
+
bills at 5× ($0.50/$2.50). The registered cost is the base rate, because opencode's
|
|
893
|
+
only tier field is fixed at 200,000 tokens; the interactive transport's own per-turn
|
|
894
|
+
cost does apply the tier. Tell the user to budget for up to 5× on long prompts.
|
|
868
895
|
- `claude-mythos-5` and `claude-mythos-5-1` are limited availability (Project Glasswing).
|
|
869
896
|
Without access `claude --model` errors; use the corresponding `claude-fable-*`.
|
|
870
897
|
- Ordinary calls can pass through unregistered ids; availability and opencode model
|
|
@@ -901,7 +928,7 @@ directory. MCP names are disk discovery, not proof of live connectivity. The sta
|
|
|
901
928
|
when `interactive` was requested by either spelling; neither proves the PTY ran
|
|
902
929
|
(`auto` stays headless until the CLI refuses `--print`). `/claude-code-doctor`'s
|
|
903
930
|
live-process rows carry a per-process transport column, which is the proof; the
|
|
904
|
-
spawn log line is the other. The PTY was measured on Claude Code 2.1.
|
|
931
|
+
spawn log line is the other. The PTY was measured on Claude Code 2.1.293: a newer
|
|
905
932
|
CLI logs one WARN per version ("has not been measured") and the doctor flags it,
|
|
906
933
|
but nothing is refused.
|
|
907
934
|
|
|
@@ -923,6 +950,7 @@ that does not answer it disables every gated flag.
|
|
|
923
950
|
| 2.1.263+ | `--permission-prompts none` (the second read-only layer) |
|
|
924
951
|
| 2.1.280+ | `claude-opus-5-5`; the API rejects it from an older CLI with a 400 naming that floor |
|
|
925
952
|
| 2.1.284+ | `claude-sonnet-5-5` on its real limits; an older CLI still runs it, on fallback limits, and the plugin warns |
|
|
953
|
+
| 2.1.293+ | `claude-haiku-5-5` on its real limits, same fallback and warning |
|
|
926
954
|
|
|
927
955
|
Below a flag gate the plugin drops the flag rather than failing the spawn, and says so
|
|
928
956
|
at WARN. `--plugin-dir` (the skill bridge) has no published version marker, so it is
|
|
@@ -1084,6 +1112,7 @@ Prefer the doctor: it needs no logging change and no restart.
|
|
|
1084
1112
|
| "Failed to authenticate: OAuth session expired", one account, turns failing in milliseconds | That account's CLI login lapsed | `claude auth status` for it, then log in again with the command the `▌ **claude account:**` note prints (`CLAUDE_CONFIG_DIR=<that account's dir> claude auth login`). Restart opencode after: a switch taken from the failover form lasts until restart. Login is a user action, never a diagnostic probe |
|
|
1085
1113
|
| A tool call reported as rejected although it ran | Two fixed causes: opencode 1.18.32 aborts the provider signal of every step ending in tool calls, read as an operator stop (0.26.1); and a call waiting on an unanswered permission prompt was rejected at the flat 10-minute deadline, after which the late approval cancelled Claude's next call (0.26.2) | Upgrade to 0.26.2+ and relaunch. Do NOT raise `proxyToolTimeoutMs` for this: a deadline now waits while opencode reports the session busy |
|
|
1086
1114
|
| `proxy call still waiting` in the log, or a `task` that looks stuck | Expected: `task`/`task_batch` carry no default deadline, and the line is a status report | `/claude-code-doctor` lists pending calls with tool, age and deadline. Tell a working subagent from a wedged one there before proposing any timeout change; see the note under "Proxy tool names" |
|
|
1115
|
+
| An MCP server's tool returns nothing useful, and `plugin.log` carries `MCP server asked for operator input and was declined` | That server raised an MCP **elicitation**, a mid-call request for the operator to type or choose something. The Claude Code session the plugin drives is headless, so there is nobody to ask: the plugin answers `{"action":"decline"}` under the CLI's documented schema and warns once per server. The tool call still returns and the turn continues | Not configurable, and deliberately so: accepting would mean inventing the answer the server asked for. Run that server's flow in Claude Code directly, where its own dialog can take the input, or configure the server so that path does not elicit |
|
|
1087
1116
|
| An MCP server's tools are simply absent | Claude Code could not connect that server | Read the once-per-process WARN at session start, and the doctor's **MCP config entries Claude Code skipped** section for one the CLI refused outright. `mcpServers` in the ready block is disk discovery, not live connectivity; fix the server where it is configured |
|
|
1088
1117
|
| An MCP server opencode has configured is missing on the FIRST turn of a fresh `opencode run`, but present in the TUI | Not a config fault, and mostly fixed. The bridge reads opencode's live MCP status when the turn plans its spawn. On opencode 2 a server still connecting is reported `pending`, which the bridge no longer reads as disabled, and the turn waits up to `mcpConnectWaitMs` (3 s) for the host to decide; opencode 1 cannot reach this state, because its own status call blocks until every server resolves. If the server is slower than the budget it is still bridged, and if it genuinely joins later `hotReloadMcp` moves the conversation onto a process that has it on the next turn, logging `opencode MCP servers changed, respawning claude` with the joined names | Nothing, usually. For a very slow server raise `mcpConnectWaitMs`. Check `plugin.log` for `waited for opencode MCP servers to finish connecting` and for the respawn line; if neither appears and the server is still absent, the status the host reported was a real refusal (`failed`, `needs_auth`), which is opencode's to fix |
|
|
1089
1118
|
| `permissionPreset` set but nothing about the session looks restricted | The option never reached that provider, or the name is not one the plugin knows (only `read-only` exists) | Read the `permissionPreset` row in `/claude-code-doctor`, or `permissionPresets` in the ready block, for the provider the conversation is on: `none` means it is not configured there (each account is its own provider id), `applied: false` with a name means an unrecognised name applied nothing, and `overrides` lists what an applied preset replaced |
|