MULTI_ACP_INACTIVITY_MS/MULTI_ACP_OVERALL_MSoperator env knobs for the ACP watchdog windows (same convention asCODEX_COMPANION_TURN_INACTIVITY_MS), read from the spawn env at turn start. Live-verified end-to-end: a knob set in Claude Code's settings env reaches the forwarder subagent's companion process and bounds a hanging CLI.- Forwarder-contract directive in the companion's fatal-error output. Every fatal companion error now ends with a
FORWARDER CONTRACT:block instructing a forwarding subagent to return the one-line failure format and NOT substitute its own answer — runtime steering at the exact decision moment for the catalogued #319-class failure. - HARD GATE block in all 11 forwarder agent definitions (unconditional forwarding: no task too trivial, Bash for the companion invocation only, failure line is the entire response on error), plus the same substitution ban in the
multi-cli-runtimeskill. Motivated by live stress tests: with the previous definitions, wrappers sometimes bypassed the companion entirely for trivial-looking questions or "helpfully" did the task themselves after a CLI failure — masking the outage from the caller. - Failure-mode regression tests (240 → 243): hang-at-handshake caught by the inactivity watchdog (not the 30-minute overall cap), mid-turn agent crash always yields an explicit error with partial text preserved, and the
MULTI_ACP_INACTIVITY_MSknob bounds a silent agent. New fake-agent fixture flags--hang-handshakeand--die-mid-turn.
- Docs caught up to the ACP transport. README gains a Transports section documenting the
MULTI_TRANSPORT_CURSOR/MULTI_TRANSPORT_OPENCODEopt-in; themulti-cli-anythingandcustomizeskills andAGENTS.mdwere corrected — they previously asserted "no shipped adapter uses ACP" and pointed at the legacylib/acp-client.mjs. They now describe ACP as a live transport for Cursor + OpenCode on the SDK-basedlib/acp/client.mjs, withcustomizedocumenting the transport toggle as a supported change. Also fixed a stale "Haiku forwarders" reference inAGENTS.md(all forwarders aremodel: sonnet)./multi:setupneeded no change (it's transport-agnostic — the ACP path passes no MCP servers in-protocol, so each CLI still reads its own MCP config). Docs only; no code change. - The four read-only forwarder agents (cursor-explore, opencode-explore, antigravity-explorer, codex-review) moved from
model: haikutomodel: sonnet. Live A/B under an injected CLI outage: the haiku wrapper ignored even a point-blank in-band contract directive and substituted its own answer; the sonnet wrapper honored the failure contract. (Consistent with openai/codex-plugin-cc merging its forwarder as sonnet over a haiku proposal in PR #169; haiku's price advantage is also undercut by subagent model-pin reliability issues and subscription-quota weighting.)
-
ACP inactivity watchdog now covers the HANDSHAKE phase. Previously it was first armed immediately before
session/prompt, so a CLI that spawned and hung silently at initialize/session-new (lock, auth, network) was only caught by the 30-minute overall cap — reproduced live, then fixed: the watchdog arms at connection start and re-arms after each completed handshake step. A silent hang now errors out afterinactivityMs(default 120 s) + the 5 s cancel grace. -
Mid-turn agent crash can no longer race to a success-shaped result. A post-handshake child exit with no stopReason and no cancel now sets an explicit
crasherror (whichever of the exit handler or the SDK's connection-closed rejection wins the race), with the stderr tail as detail and partial streamed text preserved. -
ACP cancel dispatch now reports
transport: "process-tree"when there is no in-flight ACP turn in the calling process (the cross-process cancel case — the mechanism that actually does the work is the companion's process-tree kill; the ACP child sits inside the worker's tree). Previously it reported"acp"while doing nothing in-process, which was dishonest and also made the suite sensitive to ambientMULTI_TRANSPORT_*env (3 pre-existing headless cancel tests failed when the dogfood flags were set session-wide).transport: "acp"is now reported only when a live in-flight handle was actually cancelled in-protocol. Suite verified green both with and without the ambient flags.
- ACP transport layer (slice 1): a shared, SDK-backed turn runner for the Cursor + OpenCode ACP path. New
plugins/multi/scripts/lib/acp/client.mjsexportsrunAcpTurn(spec), a policy layer over the official@agentclientprotocol/sdkClientSideConnection: it spawns one ACP child per turn, runs initialize → newSession → (optional set_mode / set_config_option model) → prompt, accumulatesagent_message_chunktext, and resolves to a uniform{ text, error, sessionId, stopReason, cancelled, modes, configOptions, usage, exitCode }(error set, never thrown — matching the adapter contract). Permission requests are auto-rejected by default and allowed only withallowWrites. Cancellation (promise.cancel()orspec.signal) sends in-protocolsession/cancel, waits a 5 s grace, then process-tree-kills the child via the existinglib/process.mjshelpers; per the verified cancelled-detection rule, a cancel-requested turn is reportedcancelled: trueregardless of the agent'sstopReason(OpenCode mislabels cancel asend_turn). Inactivity (reset on everysession/update) and overall watchdogs convert hangs to atimeouterror and reap the child; a child that dies before the handshake yields aspawnerror with the stderr tail. A requested model that is absent from the liveconfigOptionslist fails the turn with aconfigerror before prompting (no silent fallback). The runner imports only the vendored SDK bundle, node built-ins, and existing lib helpers, and never logs prompt content. - Win32-first ACP spawn resolution.
plugins/multi/scripts/lib/acp/resolve.mjsexportsresolveOpenCodeAcp()/resolveCursorAcp()returning{ exe, args }(or{ exe: null, detail }instead of throwing when not found). OpenCode resolves the platform exe under%APPDATA%\npm\…\opencode-windows-x64\bin(with a-baselinesibling probe); Cursor resolves the bundlednode.exe+index.js acpunder the lexically-latest^\d{4}\.version dir in%LOCALAPPDATA%\cursor-agent\versions(it self-updates in the background). Both honor the existingOPENCODE_CLI_PATH/CURSOR_AGENT_PATHoverrides and fall back to the bare binary name off-win32. - Vendored zero-runtime-dependency SDK bundle.
scripts/build-acp-vendor.mjs(run vianpm run build:acp-vendor) esbuild-bundles@agentclientprotocol/sdk+ itszodpeer into a single committed ESM file (plugins/multi/scripts/lib/acp/vendor/acp-sdk.bundle.mjs,external: node:*), so nothing is installed at plugin-install time. The SDK,zod, andesbuildare devDependencies only. A banner records the bundled SDK version; the build is idempotent (a second run is byte-identical). - Offline ACP contract test suite.
test/unit/acp-client.test.mjs(27 tests) drivesrunAcpTurnagainst a fake ACP agent fixture (test/fixtures/fake-acp-agent.mjs, raw newline-delimited JSON-RPC over stdio): happy-path streaming order, set_mode / set_config_option, model-not-in-options, permission reject/allow, all three cancel paths (honored,end_turn-mislabel, ignored→tree-kill with orphan-liveness assertion), inactivity timeout, child-exit-before-handshake, unknown/toleratedsessionUpdatekinds, and a cwd-with-spaces round-trip — plusresolve.mjsunit tests (env overrides, missing-binary{exe:null}, Cursor version-dir selection) and a drift-gate test asserting the vendor bundle exists, imports, exportsndJsonStream/ClientSideConnection/PROTOCOL_VERSION, and records the SDK version pinned inpackage-lock.json. - ACP transport behind per-CLI flags (slices 2 & 3): OpenCode + Cursor adapters can run over ACP instead of headless, opt-in and off by default. Two env vars select the transport per turn (read at
invoke()time, not import time, so it can be flipped per case):MULTI_TRANSPORT_OPENCODEandMULTI_TRANSPORT_CURSOR, eachacp|headless(defaultheadless). Selection lives entirely inside each adapter — the adapter contract, registry, companion, commands, and skills are untouched, and with no flag set the behavior is byte-identical to today (the headless path). On the ACP path each adapter calls the slice-1runAcpTurnand maps its options back to the SAME result shape the headlessinvoke()returns (text/error/sessionId/status/fileChanges/commandExecutions/toolCalls), so the render layer is unchanged;session/updatechunks are mapped to the existingonStreamphase/message_chunk convention. OpenCode ACP (opencode acp): read-only roles reuse the headlessbuildOpencodeSpawnEnvverbatim (theOPENCODE_PERMISSIONdeny floor — the same constant, not duplicated JSON), and the model passes through as the sameprovider/modelid the headless path gives--model, pinned viaset_config_option. Cursor ACP (cursor-agent acp): read-only roles (research/explore/…) set session modeask, write/delegate setagent(writes allowed); the friendly--modelname is resolved against the LIVE composite-id list fromsession/new(exact match → unique prefix match on the segment before[, e.g.composer-2.5→composer-2.5[fast=true]; ambiguous or no match → aconfigerror listing the available ids, no silent fallback). To resolve the composite id pre-prompt without a second session,runAcpTurngained a smallresolveModel(availableIds, requested)callback (validated aftersession/new, before the prompt). Cancellation routes to the in-flight ACP turn's in-protocol cancel handle (in-process) and reportstransport: "acp"; the authoritative cross-process cancel remains the companion's process-tree kill (the ACP child sits inside the worker's tree). The headless cancel/SIGTERM paths are untouched and never run on the ACP path. - Decoupled the slice-1 ACP layer from the legacy pre-retreat files.
lib/acp/client.mjsnow importssanitizeDiagnosticMessagefrom a newlib/acp/diagnostics.mjs(the function copied byte-for-byte from the legacylib/acp-diagnostics.mjs, which is left untouched), so the ACP-v2 layer no longer depends on a file slated for deletion. - Offline ACP-path tests for both adapters. New
test/unit/opencode-acp.test.mjs(16 tests) andtest/unit/cursor-acp.test.mjs(17 tests) drive each adapter'sinvoke()against the fake ACP agent via an injectedspawnSpec(the roleresolve.mjsenv overrides serve in production): transport selection honors the env flag and defaults to headless; the OpenCode read-only deny floor + model pass through (asserted via a new--echo-envfixture flag); Cursor session mode by role and model alias resolution (exact, prefix-unique, ambiguous→error, missing→error with the list); result-shape parity with the headless path; and cancel routing through the in-flight handle.acp-client.test.mjsgains 3 tests for the newresolveModelcallback. Suite total 204 → 240.
Versioning reset. The project moved to a pre-1.0
0.xscheme to reflect that it is in active development; the earlierv2.0.0/v2.0.1GitHub releases were removed. Entries under Pre-reset history below predate this reset and are kept as a record (their version numbers do not continue the0.xline).
-
OpenCode provider.
/opencode:delegate,/opencode:research, and/opencode:exploreare now shipped commands. Transport: headlessopencode run --format json, piped NDJSON. The adapter (lib/adapters/opencode.mjs) parses the NDJSON event stream (step_start, text, step_finish, tool_use, error), derives file changes and command executions from completed tool_use events, and delivers the prompt on stdin (newline-safe). Read-only roles (research,explore) are enforced via injected oc-* primary agents (OPENCODE_CONFIG_CONTENT) with write/edit/bash denied plus anOPENCODE_PERMISSIONdeny floor — OpenCode has no--read-onlyflag. Write roles use--dangerously-skip-permissions.--until-doneis supported;--effortis not. Default model:opencode/claude-opus-4-8(Zen, billed separately). Token-offload caveat:anthropic/*models reuse the Claude Code subscription — zero offload; useopencode/*,openai/*,google/*,github-copilot/*, orollama/*for real offload. MCP servers are read from OpenCode's ownopencode.json(not managed by/multi:setup). SetOPENCODE_CLI_PATHto pin a specific binary; setOPENCODE_CLI_DEFAULT_MODELto override the default model. The adapter is registered inlib/adapters/registry.mjsand the opencode plugin is listed in.claude-plugin/marketplace.json. -
Reworked the Cursor slice into
/cursor:delegate,/cursor:research,/cursor:explore(replacing/cursor:execute,/cursor:plan,/cursor:debug).delegateis agentic implementation (Cursor writes code; the calling Claude thread runs the listed## Verificationcommands),researchis read-only external web/docs research (Cursor's built-in WebSearch with the Exa MCP as a fallback), andexploreis read-only codebase Q&A (semantic search + grep). All three default to Cursor'sautomodel and accept--model.delegatealso gains the autonomous--until-donemulti-step loop (with--max-turns), previously Codex-only — the loop's stop logic is now a shared, transport-agnostic helper (evaluateAutonomousStop). -
Implemented the Antigravity slice on Google's headless
agyCLI (EXPERIMENTAL)./antigravity:researchand/antigravity:explorenow run read-only againstagy -p(Gemini 3.5 Flash). Becauseagy's headless stdout is empty upstream (gemini-cli#27466, unfixed as of agy 1.0.3), the adapter spawnsagy -p, learns the conversation id from a per-invocation--log-file, and recovers the answer from agy's on-disk transcript JSONL (~/.gemini/antigravity-cli/brain/<id>/.system_generated/logs/transcript.jsonl); the last non-emptyPLANNER_RESPONSEstep is the answer. Auth isagy's own OAuth keyring (no API key); the desktop app is not required. Cancel is a process-tree kill. Per-call--model, write-delegate, and--until-doneare intentionally unsupported on this path. New pure-helper tests intest/unit/antigravity-headless.test.mjs(against captured fixtures).
- Codex broker leak. The reused per-cwd app-server broker daemon now self-terminates after an idle window (
CODEX_COMPANION_BROKER_IDLE_MS, default 600000 ms), so brokers spawned for transient or extra workspaces no longer linger forever (and, on Windows, no longer pin their cwd directory open). The SessionEnd hook already reaped the session's primary-cwd broker; this idle timer is the backstop for every other case (app-server-broker.mjs,lib/broker-lifecycle.mjs→shouldIdleShutdown). - Unreachable review-gate toggle / dangling
/codex:setupreferences.setupwas renamed to/multi:setup, but the companion, the Codex adapter, the stop-review-gate hook, the stop-gate prompt, and thecodex-result-handlingskill still pointed users at the non-existent/codex:setup— and/multi:setupdid not expose--enable-review-gate/--disable-review-gate, so the stop-time review gate could not be toggled from any shipped command. Repointed every reference to/multi:setupand taught/multi:setupto forward the review-gate flags to the companion (which already implemented the toggle).
- Revamped the
customizeandmulti-cli-anythingskills to match the post-split, headless shape. Both predated the Cursor ACP→headless migration, the Antigravity headless-agyslice, the sharedmulti-cli-runtimeforwarding contract, and the companion monolith split — so they documented abuildPrompt()role→slash-prefix layer and anADAPTERSmap insidemulti-cli-companion.mjsthat no longer exist, and treated ACP as the default integration path.customizenow teaches the real four moving parts (slash command / forwarder framing block / adapter role→flag map / sharedmulti-cli-runtimecontract), the forwarder model-by-role policy (Sonnet for framing roles, Haiku for pure path-bridges), and headless-era escape hatches (CURSOR_AGENT_PATH,AGY_CLI_PATH, per-CLI MCP config), withACP_TRACEdemoted to legacy; its stale/cursor:research"add-a-command" example andcursor-researcherrole name are replaced with current ones.multi-cli-anythingnow leads with headless print-mode (cursor.mjs) as the common path, documents spawn-and-read-artifacts (antigravity.mjs) and ASP (codex.mjs), demotes ACP to a clearly-labeled legacy section, and points registration atlib/adapters/registry.mjsand dispatch atlib/commands/task.mjs(not the companion). Docs-only; no runtime change. - Refreshed the banner and README for the four-CLI lineup. New banner art (Cursor · Antigravity · OpenCode · OpenAI Codex, replacing the stale gold banner that still showed the removed Copilot/Gemini/Qwen). The "CLIs supported" badge and intro now include OpenCode, with a note that OpenCode is in active development (its
/opencode:*provider commands don't ship yet; today's working providers are Codex, Cursor, Antigravity). Also corrected the README's staleACP_TRACEtroubleshooting note — no shipped provider uses ACP. - Migrated the Cursor adapter from
agent acp(ACP JSON-RPC) to headlessagent -p. Headless fixes what ACP could not on Windows: MCP/web tools fire (they were silently dead in ACP since ~2026.04.17), cancel is a real process-tree kill (was a no-op), progress is parsed from the documentedstream-jsonevent stream, and model/mode selection are first-class flags (--model <flat-name>,--mode ask) instead of post-session RPCs — so the stale bracketed-modelIdresolution is gone andautois the default. The prompt is delivered on stdin (newline-safe). ACP (lib/acp-client.mjs) now serves only the antigravity/gemini path. Forwarders run on Sonnet (cursor-delegate,cursor-research) and Haiku (cursor-explore, a pure read-only path-bridge). - Forwarder subagent models tuned by role.
codex-executeandcodex-rescuerun on Sonnet: they frame and route the prompt (choosing model/effort and shaping the task) where a more capable model materially improves the work the external CLI then does — matching the officialcodex-plugin-ccrescue subagent.codex-reviewstays on Haiku: it does no framing, only bridging the plugin boundary to forwardreview/adversarial-reviewto the companion, so the cheapest model is the correct one. (The cursor/antigravity forwarders already run on Sonnet.) - Repo structure for multi-agent work (no behavior change). Added
AGENTS.md/CLAUDE.mdorientation,ARCHITECTURE.md, an explicit adapterCONTRACT.md, a zero-dependency offline test suite (npm test, Node's built-in runner) with a reusable sandbox fixture, and a gitignored.agent/scratch area. Began splitting the companion monolith: extracted the pure task-option normalizers (model alias, reasoning-effort validation, argv splitting) intolib/task-options.mjswith characterization tests. - Split the two monoliths into focused modules (no behavior change).
multi-cli-companion.mjs(1462 lines) is now a ~100-line dispatcher; its command handlers moved verbatim intolib/commands/{shared,setup,jobs,review,task}.mjs.lib/adapters/codex.mjs(1110 lines) is now a ~30-line re-export barrel overcodex-{roles-prompts,render-parse,transport}.mjs, keeping the public import surface and theadapterobject intact. Every function was moved byte-for-byte; the offline suite grew from 27 to 82 characterization tests (all passing), and the live suite plus an adversarial verbatim diff against the prior revision confirm the CLI surface and behavior are unchanged. - Antigravity transport: replaced the planned desktop Language Server (ConnectRPC live-attach) with the headless
agyCLI. The v3.0.0 stub targeted attaching to the running Antigravity 2.0 desktop app's LS; that approach is dropped — driving the Antigravity desktop/OAuth login from third-party software violates Google's ToS, and Google now ships the standaloneagyCLI (which runs without the desktop app). Theantigravity.mjsstub is replaced by a real adapter,handleCancelgained an antigravity branch, and/multi:setupnow points users at installingagyand signing in (rather than running the desktop app).
The entries below predate the move to 0.x versioning and are retained for the record.
Breaking release. The provider set is now Codex, Cursor, and Antigravity. Three providers were removed and command namespaces were reorganized — there is no in-place behavioral compatibility with v2.x for the dropped CLIs. After upgrading, restart Claude Code so the subagent roster refreshes, then re-run /multi:setup.
- Gemini, Copilot, and Qwen providers — their plugins, adapters, subagents, and commands are gone. Gemini CLI access was cut during the gap (Gemini CLI sunset); Copilot was dropped after MSFT's billing change; Qwen was unused in practice. The Antigravity provider replaces Gemini-family access via a different transport.
- The Gemini ACP broker lifecycle (
gemini-broker-lifecycle.mjs) and the/gemini:*,/copilot:*,/qwen:*command surfaces.
- Antigravity provider —
/antigravity:research(Gemini 3.1 Pro) and/antigravity:explore(Gemini 3.5 Flash), both read-only, reached through the running Antigravity 2.0 desktop app's Language Server. This release ships a stub adapter: process detection works (Windows-first), but the Language Server transport (ConnectRPC live-attach) lands in a follow-up (Phase 2)./antigravity:*commands currently return a clean "not implemented (Phase 2)" message; macOS/Linux discovery is also Phase 2. - Forked-and-merged the official OpenAI
codex-plugin-ccinto ourcodexslice: new/codex:rescue,/codex:review, and/codex:adversarial-reviewcommands, thecodex-rescueandcodex-reviewsubagents (with disjoint-trigger descriptions so Claude's auto-dispatch stops confusing them), and three vendored helper skills (codex-cli-runtime,gpt-5-4-prompting,codex-result-handling). All routed through ourmulticompanion. Attribution recorded inNOTICE(Apache-2.0).
- Latent ENOENT in the review / stop-gate paths. The companion dispatched
review/adversarial-reviewand the stop-review-gate hook, but the data files they read (schemas/review-output.schema.json,prompts/adversarial-review.md,prompts/stop-review-gate.md) were missing from the repo, so those paths threw at runtime. Restored the schema and prompt templates.
- Modernized the Cursor adapter. Model selection now uses
session/set_config_option(Cursor 2026.04.13+ ignoressession/new.modelandsession/set_model). Dropped the~/.cursor/cli-config.jsonallowlist injection entirely — the 2026.04.17 MCP/Terminal regression that required it was fixed upstream (forum #155544/#155516). Refreshed the current-model reference list and the known-broken-version warning. - Command-namespace policy. Provider plugins own their own command namespaces (
/codex:*,/cursor:*,/antigravity:*);/multi:*is reserved for cross-cutting operations (setup,status,result,cancel). /multi:setupdetection now probes Codex, Cursor, and Antigravity (and reports a running Antigravity desktop) instead of the removed CLIs. The companion's setup report enumerates the live provider set via each adapter'sisAvailable().- Skills (
customize,multi-cli-anything,multi-cli-runtime,multi-plan-handoff,multi-result-handling) updated for the new inventory;multi-cli-anythingnow documents Antigravity's non-ACP Language Server (ConnectRPC) transport as a worked example of a non-ACP adapter.
- Update the marketplace:
/plugin marketplace update cc-multi-cli-plugin. - Uninstall the dropped provider plugins if you had them:
/plugin uninstall gemini@cc-multi-cli-plugin(andcopilot,qwen). - Reinstall the hub and the providers you want:
/plugin install multi@cc-multi-cli-plugin --force, thencodex/cursor/antigravity. - Restart Claude Code (subagent definitions are cached at session start), then run
/multi:setup.
Bug-fix release. Real-world prompts beyond a one-shot text reply silently broke before this — agents stalled, errors vanished, the forwarding subagents reported success on empty output. This release fixes the entire ACP traffic path.
- ACP session hangs across all CLIs. The shared ACP client now responds to incoming JSON-RPC requests from the agent (previously dropped).
buildAutoApproveRequestHandlerservicessession/request_permission,cursor/ask_question, and the fullterminal/*family — without these, agents stalled forever waiting for our response. - Silently-dropped errors. Non-codex adapter branches now exit 0 on in-protocol errors (with the failure message in rendered output). Previously, exit 1 tripped the forwarding subagent's "if Bash fails, return nothing" rule and the user saw nothing at all.
- Cursor
agent acpTerminal hang. Plugin now auto-injects a permissive allowlist (Shell(*),Read/Write/Edit(**),MCP(*)) into~/.cursor/cli-config.jsonbefore each Cursor invocation. Without this, Cursor's out-of-band permission gate silently stalls everyexecutetool call. - Gemini
--model autohang. Companion now treatsautoas "skipsession/set_model" so the CLI's native alias resolver picks a real model id. Callingset_model("auto")over ACP was silently accepted but causedsession/promptto hang. - MCP server schema.
envis now an array of{name, value}per ACP spec (was aRecord<string, string>).
- MCP wiring (Exa + Context7) into ACP
session/newfor all four ACP adapters (Gemini, Cursor, Copilot, Qwen). Reads keys from~/.claude/plugins/cc-multi-cli-plugin/config.json(already populated by/multi:setup). - Client-side ACP terminal services (
scripts/lib/acp-terminals.mjs) —terminal/create,terminal/output,terminal/wait_for_exit,terminal/kill,terminal/releasebacked bychild_process.spawnwith a 1 MiB output ring buffer. Handshake declaresclientCapabilities.terminal: true. - Yolo / max-permission defaults. Gemini approval mode is now always
yolo; Codex sandbox for--writetasks isdanger-full-access; Cursor spawn includes--yolo --approve-mcps acpand explicitly sets ACP mode based on role. ACP_TRACE=1env var for full incoming-message tracing — single most useful diagnostic when an agent silently hangs.- One-time stderr warning when Cursor 2026.04.17-787b533 (the build with the documented MCP/Terminal regression) is detected. Auto-quiet on other versions.
- Operator escape hatches:
CURSOR_AGENT_PATHenv var is now honored for pinning a specific Cursor build. Documented in thecustomizeskill.
- All 10 multi/agents/*.md loosened forwarding contract: capture stderr (
2>&1), forbid ad-hoc polling/sleep/cat, return a structured one-line failure summary on Bash failure (instead of silently returning nothing).--writedefaults added to writer-style agents (cursor-debugger, cursor-writer, qwen-writer). - Skills (
multi-cli-anything,customize) now document the ACP gotchas we hit empirically — out-of-band permission gates, terminal capability semantics, MCP wiring quirks, mode-setting variance, version sensitivity.cursor.mjsis cited as the worked example. - README Known Issues section with documented Cursor 2026.04.17 upstream regressions (forum links).
- Cursor 2026.04.17
agent acpdoes not sendsession/request_permissionover the wire and silently stalls Terminal/MCP tool calls. Workaround: pre-approval viacli-config.jsonallowlist (auto-applied) keeps simple shell exec working; complex multi-tool runs may still hang. Pin an older build viaCURSOR_AGENT_PATHif needed.
This release fully replaces the former skill-gemini plugin. The plugin has a new name, a new repo URL (github.com/greenpolo/cc-multi-cli-plugin), a new scope (4 CLI providers, not just Gemini), and new commands. There is no in-place upgrade path.
Migration from v1 (skill-gemini):
- In Claude Code:
/plugin uninstall skill-gemini - In Claude Code:
/plugin install cc-multi-cli-plugin(from github.com/greenpolo/cc-multi-cli-plugin) - Run
/multi:setupto configure MCPs on each CLI - The old
skills/geminiSKILL is gone. Its functionality is absorbed by/gemini:researchand thegemini-researchersubagent.
Four CLI transport adapters, three protocols:
- Codex via App Server Protocol (ASP) —
codex --app-server - Gemini via Agent Client Protocol (ACP) —
gemini --acp - Cursor via ACP —
agent acp - GitHub Copilot via ACP —
copilot --acp --stdio
Eight slash commands:
/multi:setup— one-shot Claude-driven wizard that detects installed CLIs and configures Exa + Context7 MCPs on each/gemini:research— deep research / exploration with Gemini's 1M-token context (read-only)/codex:execute— delegate a specific plan step to Codex for rigorous implementation/cursor:write— bulk / multi-file code writing in Cursor Agent mode/cursor:plan— Cursor Plan mode for approach design (read-only)/cursor:debug— Cursor Debug mode for hypothesis-driven root-cause investigation/copilot:research— Copilot's /research (GitHub + web investigation)/copilot:review— Copilot's /review code review agent
Four auto-dispatch subagents (Claude proactively delegates via the Agent tool):
gemini-researcher,codex-execute,cursor-writer,cursor-debugger
Two extension skills:
customize— guides Claude through rewiring which CLI handles which role (swap, disable, restrict, etc.)multi-cli-anything— guides Claude through adding brand-new CLI providers (ACP, ASP, or subprocess paths)
Companion runtime (ported from OpenAI's codex-plugin-cc):
- Shared CLI adapter registry with
--cli <name>dispatch - Background job control (
--background/--wait) - Session state persistence under
~/.claude/plugins/cc-multi-cli-plugin/state/ - Session lifecycle hooks
- Windows-safe
spawn()pattern for.cmd-wrapped CLIs (Cursor, Gemini, Copilot on npm global installs)
- Plugin name:
skill-gemini→cc-multi-cli-plugin - License: unchanged (Apache 2.0) but
LICENSEandNOTICEfiles added with full upstream attribution - Repo layout: flattened from marketplace format (
plugins/skill-gemini/) to a single-plugin layout at the repo root
- The old Gemini-only
skills/gemini/SKILL.md— functionality absorbed bygemini-researcher+/gemini:research - The repo's former
plugins/skill-gemini/nested directory - The former
.claude-plugin/marketplace.jsonmarketplace manifest
These are explicit v2.0.0 deferrals. Filed for a future release.
- Background task worker untested for non-Codex CLIs. The
clifield is stored in the job request and threaded throughexecuteTaskRun, so Gemini/Cursor/Copilot background jobs should work — not yet verified end-to-end. --resume-lastis Codex-only. Gemini/Cursor/Copilot receive the flag but have no session-resumption logic wired to the adapter. Per-invocation ACP sessions work; cross-invocation resume does not yet.job-observabilityintegration between the shared runtime and non-Codex adapters is partial.recordObserverEventis a no-op in the Gemini/Cursor/Copilot paths. Doesn't affect correctness, does affect introspection./codex:reviewand/codex:adversarial-reviewremain in the officialopenai-codexplugin; our plugin has no review path for non-Codex CLIs yet. Gemini/Cursor/Copilot reviews can be invoked through each CLI's native slash command via the companion runtime but not through top-level plugin commands.- Setup wizard's MCP probes.
/multi:setupconfigures MCPs on each CLI but doesn't deeply verify Exa / Context7 are reachable after configuration. Users should do a sanity check by running/gemini:research testor similar after setup.
Apache 2.0 licensed. Major portions derived from:
- OpenAI's
codex-plugin-cc(Apache 2.0) — runtime architecture, Codex adapter, hooks sakibsadmanshajib/gemini-plugin-cc(Apache 2.0) — Gemini ACP transport patternblowmage/cursor-agent-acp-npm(MIT) — Cursor ACP adapter reference
See NOTICE for the full attribution.
Original Gemini-only read-only consultation skill. See v1.0.0 git tag for history. Superseded by v2.0.0.