@khalilgharbaoui/opencode-claude-code-plugin 0.47.0 → 0.48.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 +215 -51
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/claude-code-plugin/SKILL.md +24 -6
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
|
|
|
@@ -859,7 +873,10 @@ Registered ids: `claude-haiku-4-5`, `claude-sonnet-4-5`, `claude-sonnet-4-6`,
|
|
|
859
873
|
- The `-fast` ids are this plugin's own markers. They spawn the base model with
|
|
860
874
|
`--settings '{"fastMode":true}'` (Claude Code 2.1.220+). Fast mode fails soft: an
|
|
861
875
|
ineligible account runs at standard speed and the plugin logs a warning naming the
|
|
862
|
-
reason
|
|
876
|
+
reason, read off the terminal `result` rather than the `system`/`init` frame, which
|
|
877
|
+
is optimistic (2.1.288 says `"on"` at init and `"off" / extra_usage_disabled` at the
|
|
878
|
+
end for an account with usage credits off).
|
|
879
|
+
Switch to a non-fast id rather than silently enabling paid usage credits.
|
|
863
880
|
Review eligibility/billing with the user; the enabled state needs live verification
|
|
864
881
|
on their account. CLI floors are gates, not proof of model access.
|
|
865
882
|
- `claude-sonnet-5-5` needs Claude Code 2.1.284+ to run on its real limits. An older CLI
|
|
@@ -1084,6 +1101,7 @@ Prefer the doctor: it needs no logging change and no restart.
|
|
|
1084
1101
|
| "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
1102
|
| 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
1103
|
| `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" |
|
|
1104
|
+
| 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
1105
|
| 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
1106
|
| 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
1107
|
| `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 |
|