@khalilgharbaoui/opencode-claude-code-plugin 0.8.2 → 0.9.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/README.md CHANGED
@@ -209,6 +209,10 @@ The account model IDs are internally suffixed, for example `claude-sonnet-4-6@wo
209
209
  | `multiStepContinuation` | boolean | `true` | Append a system-prompt hint nudging Claude to chain tool calls within one turn instead of pausing between subtasks. Each opencode turn boundary requires the user to manually press "continue", so for multi-step tasks this reduces friction. Set `false` to disable. |
210
210
  | `autoContinueIncompleteTurns` | boolean \| `"smart"` | `"smart"` | Smartly continue incomplete Claude CLI results inside the same opencode turn. Reduces manual "continue" presses when Claude ends after reasoning/tool activity without a useful final answer. Set `false` to disable. |
211
211
  | `compactionModel` | string | `"claude-haiku-4-5"` | Model used when opencode invokes `/compact`. Override per-process via the `CLAUDE_CODE_COMPACTION_MODEL` env var (env wins over config). See [Compaction](#compaction). |
212
+ | `interactive` | boolean | `false` | **Experimental.** Drive the interactive `claude` TUI (subscription billing) instead of headless `--print`. Requires opencode running under Bun with PTY support; silently falls back to headless otherwise. Env: `CLAUDE_CODE_INTERACTIVE_TRANSPORT=1`. See [Interactive transport](#interactive-transport-experimental). |
213
+ | `interactiveBypass` | boolean | `false` | Deprecated/no-op with `interactive`: Claude Code's TUI shows a manual safety confirmation for `bypassPermissions`, so the plugin intentionally does not pass it. |
214
+ | `interactiveAllowTools` | string[] | `["Bash", "Edit", "Write", "Read", "WebFetch"]` | With `interactive`: built-in tools pre-allowed without prompting (replaces the default list). MCP server wildcards (`mcp__<server>__*`) are always added from the bridged config. |
215
+ | `interactiveSystemPrompt` | boolean | `true` | With `interactive`: append this plugin's CLI/AGENTS/continuation prompt via `--append-system-prompt-file`. The transport intentionally does not forward opencode's own system prompt, because it can trigger Claude Code's third-party-app usage gate on subscription accounts. Set `false` only for diagnostics. |
212
216
 
213
217
  ### Overriding model metadata
214
218
 
@@ -234,6 +238,43 @@ Anything you supply is merged on top of the defaults; you don't need to redeclar
234
238
 
235
239
  ---
236
240
 
241
+ ## Interactive transport (experimental)
242
+
243
+ By default the plugin spawns `claude --print` (headless). From **June 15, 2026** that usage bills against the separate [Agent SDK credit](#billing-change-june-15-2026-agent-sdk-credit) on subscription plans. The interactive transport instead drives the real interactive `claude` TUI — which bills as **normal plan usage** — under a native PTY inside opencode's Bun runtime, types your prompt into it, and streams the session transcript (`~/.claude/projects/<cwd>/<session-id>.jsonl`) back through the same pipeline the headless transport uses.
244
+
245
+ ```json
246
+ "options": { "interactive": true }
247
+ ```
248
+
249
+ Or per-process: `CLAUDE_CODE_INTERACTIVE_TRANSPORT=1`.
250
+
251
+ ### Requirements
252
+
253
+ - opencode must be running under **Bun** with `Bun.Terminal` (PTY) support. If it isn't, the flag is ignored and the headless transport is used — nothing breaks.
254
+ - A logged-in `claude` (subscription auth). The whole point is plan billing, so API-key auth gains nothing here.
255
+
256
+ ### What carries over from the headless transport
257
+
258
+ - The plugin's appended prompt (Claude CLI context, AGENTS.md guidance, continuation rules). The interactive transport intentionally does not forward opencode's own system prompt, because live testing showed that payload can trigger Claude Code's third-party-app usage gate on subscription accounts.
259
+ - The MCP bridge: bridged servers are passed via `--mcp-config` + `--strict-mcp-config`, and every bridged server is pre-allowed as `mcp__<server>__*`.
260
+ - Model selection, session reuse, and the whole streaming/usage pipeline.
261
+
262
+ Set `interactiveSystemPrompt: false` only for diagnostics. While disabled, the interactive session will not receive the plugin's CLI context, AGENTS.md guidance, or continuation hints.
263
+
264
+ ### What's different
265
+
266
+ - **Permissions:** the interactive TUI has no `can_use_tool` control channel, so tools can't be approved per-call through opencode. Built-in tools are pre-allowed via a settings allow list (default `Bash, Edit, Write, Read, WebFetch`; override with `interactiveAllowTools`). `bypassPermissions` is intentionally not used here because Claude Code shows a manual safety confirmation in the TUI and defaults to exit.
267
+ - **Input is text-only:** images and other non-text blocks are dropped (with a logged warning); tool results are rendered as labeled text.
268
+ - **Output granularity:** text arrives per transcript record, not token-by-token, so it can feel chunkier than headless streaming.
269
+ - **Turn timeout:** a turn that produces no terminal stop within 30 minutes is reported honestly as an error result (visible truncation), not silently ended.
270
+ - `/compact` always uses the headless transport regardless of this setting.
271
+
272
+ ### Known issue
273
+
274
+ - **Fresh sessions can hang at startup.** With `interactive: true`, starting a brand-new opencode session (under Bun) can leave the TUI blank and unresponsive before you can type. Resuming an existing session (`opencode --continue`) works, and once a session is running the transport is stable. Until this is fixed, leave `interactive` unset (headless default) if you hit it. Tracked for a follow-up release.
275
+
276
+ ---
277
+
237
278
  ## Selective tool proxy
238
279
 
239
280
  This is the core feature.
@@ -500,7 +541,7 @@ Partial support since v0.5.1. DCP runs in a useful degraded mode: automatic stra
500
541
  | DCP feature | Status | Notes |
501
542
  |---|---|---|
502
543
  | `experimental.chat.messages.transform` (compression placeholders, dedup, error purge) | ✅ Works | Transforms run inside opencode before reaching this plugin. |
503
- | `experimental.chat.system.transform` (context-limit nudges, iteration reminders) | ✅ Works | `extractSystemMessages` forwards system-role content to Claude CLI via `--append-system-prompt-file`. |
544
+ | `experimental.chat.system.transform` (context-limit nudges, iteration reminders) | ✅ Works in headless | Headless spawns forward system-role content via `--append-system-prompt-file`. Interactive mode intentionally omits opencode's forwarded system prompt and keeps only this plugin's CLI/AGENTS/continuation prompt. |
504
545
  | `/dcp compress`, `/dcp sweep`, `/dcp manual`, `/dcp context`, `/dcp stats` slash commands | ✅ Works | Handled by opencode's `command.execute.before` hook, not the model. |
505
546
  | Automatic `deduplication` + `purgeErrors` strategies | ✅ Works | Message-transform only, no model tool calls. |
506
547
  | Autonomous model-driven `compress` tool calls | ❌ Not supported | DCP registers `compress` as an opencode-native tool. Claude CLI only sees its own built-ins and MCP-bridged servers, so the model never sees `compress`. The plugin prepends a runtime note instructing Claude to ignore any system instruction that asks it to call `compress`/`distill`/`prune`. |
package/dist/index.d.ts CHANGED
@@ -138,6 +138,16 @@ type LogMode = "silent" | "debug";
138
138
  interface ClaudeCodeConfig {
139
139
  provider: string;
140
140
  cliPath: string;
141
+ /** Drive interactive claude (subscription) instead of headless --print. */
142
+ interactive?: boolean;
143
+ /** Deprecated/no-op with interactive: Claude Code's TUI requires manual confirmation for bypassPermissions. */
144
+ interactiveBypass?: boolean;
145
+ /** With interactive: built-in tools to allow without prompting (replaces
146
+ * the default Bash/Edit/Write/Read/WebFetch list; MCP wildcards are always
147
+ * derived from the bridged config). */
148
+ interactiveAllowTools?: string[];
149
+ /** With interactive: append this plugin's own prompts via --append-system-prompt-file. Defaults to true. */
150
+ interactiveSystemPrompt?: boolean;
141
151
  cwd?: string;
142
152
  account?: string;
143
153
  configDir?: string;
@@ -190,6 +200,16 @@ interface LoggingConfig {
190
200
  type WebSearchRouting = "claude" | "disabled" | (string & {});
191
201
  interface ClaudeCodeProviderSettings {
192
202
  cliPath?: string;
203
+ /** Drive interactive claude (subscription) instead of headless --print. */
204
+ interactive?: boolean;
205
+ /** Deprecated/no-op with interactive: Claude Code's TUI requires manual confirmation for bypassPermissions. */
206
+ interactiveBypass?: boolean;
207
+ /** With interactive: built-in tools to allow without prompting (replaces
208
+ * the default Bash/Edit/Write/Read/WebFetch list; MCP wildcards are always
209
+ * derived from the bridged config). */
210
+ interactiveAllowTools?: string[];
211
+ /** With interactive: append this plugin's own prompts via --append-system-prompt-file. Defaults to true. */
212
+ interactiveSystemPrompt?: boolean;
193
213
  cwd?: string;
194
214
  name?: string;
195
215
  providerID?: string;