You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Dockerfile.claude installs @anthropic-ai/claude-code globally via npm and carefully pins CLAUDE_CODE_VERSION=2.1.104 (PR #333, reaffirmed in PR #412) to dodge the 2.1.105+ auth regression.
However, claude-agent-acp@0.25.0+does not invoke the globally installed /usr/local/bin/claude at runtime. The adapter shells out to the cli.js bundled inside its own node_modules/@anthropic-ai/claude-agent-sdk/cli.js:
isStaticBinary() is only true when CLAUDE_AGENT_ACP_IS_SINGLE_FILE_BUN is set (bun single-file build), which openab never sets. So the non-static branch always wins and the adapter uses the SDK-bundled cli.js, not the globally installed @anthropic-ai/claude-code.
Consequence: pinning CLAUDE_CODE_VERSION in Dockerfile.claude has no effect on what Claude CLI actually runs inside sessions. The claude-code version that matters is the one claude-agent-sdk bundles, which is implicitly chosen by the claude-agent-acp version.
This is not a recent regression — the adapter has never used the globally installed @anthropic-ai/claude-code for normal (non-static) npm installs. Timeline verified against the adapter's git tags (src/acp-agent.ts):
claude-agent-acp version
Released
pathToClaudeCodeExecutable behavior
v0.2.x (Feb 2025–Sep 2025)
—
Field not set at all; SDK default (bundled cli.js) applies unconditionally
v0.6.0
2025-10-15
Introduced CLAUDE_CODE_EXECUTABLE env override; still SDK-default when env var unset
v0.7.0 – v0.18.0
2025-10-27 → 2026-02-18
Same behavior as v0.6.0
v0.19.0
2026-02-27
Added isStaticBinary() + claudeCliPath() helper for bun single-file builds only; non-static npm installs still pass {} → SDK default
v0.20.x – v0.28.0
2026-03-03 → 2026-04-15
Same logic as v0.19.0
v0.29.0 (current)
2026-04-16
Same logic
In every version, openab's integration (npm install inside a Debian container, no CLAUDE_AGENT_ACP_IS_SINGLE_FILE_BUN, no CLAUDE_CODE_EXECUTABLE) falls through to the SDK default, which is the SDK's own bundled cli.js. The globally installed /usr/local/bin/claude has been dead code in Dockerfile.claude since the Dockerfile was first authored.
By extension, PR #333's rationale ("revert to 2.1.104 due to 2.1.105+ auth regression in the TUI paste flow") is based on a false premise: the adapter never runs the system claude binary's /login TUI. The auth regression it cited (anthropics/claude-code#47648) cannot affect openab sessions. Same for PR #412's "stay on 2.1.104" reasoning about the parallel-mkdir race in 2.1.112 — that race is in the claude-code binary's runtime, which the adapter doesn't invoke.
Concrete evidence: compare Opus 4.7 knowledge between the two install locations in the same container (adapter 0.29.0 + CLAUDE_CODE_VERSION=2.1.104):
/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js (globally installed, in PATH, unused by adapter)
❌ no — only up to Opus 4.6, claude-opus-4-6
Despite the global install reporting up to Opus 4.6 only, an openab session running adapter 0.29.0 correctly returns availableModels containing Opus 4.7 and accepts currentModelId: "opus" as 4.7.
Steps to Reproduce
Build the current Dockerfile.claude at main and inspect the two cli.js files inside the container:
The two lists differ — proving the global install is out-of-sync with the one the adapter actually uses.
Additionally, trace which binary is spawned when openab opens a Claude session:
# In a running openab-claude container with a session open:
ps auxf | grep -i claude
lsof -p $(pgrep -f claude-agent-acp)| grep cli.js
The cli.js being read is under @agentclientprotocol/claude-agent-acp/node_modules/@anthropic-ai/claude-agent-sdk/ — never /usr/local/lib/node_modules/@anthropic-ai/claude-code/.
Expected Behavior
One of the following should hold:
Drop @anthropic-ai/claude-code from Dockerfile.claude — if nothing in the container actually relies on it, the install is pure bloat (~50 MB image) and its pinning effort is cargo-cult.
Or wire it in explicitly — set CLAUDE_CODE_EXECUTABLE=/usr/local/bin/claude in the container env (adapter checks this env var first per acp-agent.js:1079) so the pinned version is what the adapter actually runs. Then CLAUDE_CODE_VERSION becomes load-bearing again.
Description
Dockerfile.claudeinstalls@anthropic-ai/claude-codeglobally via npm and carefully pinsCLAUDE_CODE_VERSION=2.1.104(PR #333, reaffirmed in PR #412) to dodge the 2.1.105+ auth regression.However,
claude-agent-acp@0.25.0+does not invoke the globally installed/usr/local/bin/claudeat runtime. The adapter shells out to thecli.jsbundled inside its ownnode_modules/@anthropic-ai/claude-agent-sdk/cli.js:isStaticBinary()is onlytruewhenCLAUDE_AGENT_ACP_IS_SINGLE_FILE_BUNis set (bun single-file build), which openab never sets. So the non-static branch always wins and the adapter uses the SDK-bundled cli.js, not the globally installed@anthropic-ai/claude-code.Consequence: pinning
CLAUDE_CODE_VERSIONinDockerfile.claudehas no effect on what Claude CLI actually runs inside sessions. The claude-code version that matters is the oneclaude-agent-sdkbundles, which is implicitly chosen by theclaude-agent-acpversion.This is not a recent regression — the adapter has never used the globally installed
@anthropic-ai/claude-codefor normal (non-static) npm installs. Timeline verified against the adapter's git tags (src/acp-agent.ts):pathToClaudeCodeExecutablebehaviorcli.js) applies unconditionallyCLAUDE_CODE_EXECUTABLEenv override; still SDK-default when env var unsetisStaticBinary()+claudeCliPath()helper for bun single-file builds only; non-static npm installs still pass{}→ SDK defaultIn every version, openab's integration (npm install inside a Debian container, no
CLAUDE_AGENT_ACP_IS_SINGLE_FILE_BUN, noCLAUDE_CODE_EXECUTABLE) falls through to the SDK default, which is the SDK's own bundledcli.js. The globally installed/usr/local/bin/claudehas been dead code inDockerfile.claudesince the Dockerfile was first authored.By extension, PR #333's rationale ("revert to 2.1.104 due to 2.1.105+ auth regression in the TUI paste flow") is based on a false premise: the adapter never runs the system
claudebinary's/loginTUI. The auth regression it cited (anthropics/claude-code#47648) cannot affect openab sessions. Same for PR #412's "stay on 2.1.104" reasoning about the parallel-mkdir race in 2.1.112 — that race is in theclaude-codebinary's runtime, which the adapter doesn't invoke.Concrete evidence: compare Opus 4.7 knowledge between the two install locations in the same container (adapter
0.29.0+CLAUDE_CODE_VERSION=2.1.104):node_modules/@agentclientprotocol/claude-agent-acp/node_modules/@anthropic-ai/claude-agent-sdk/cli.js(what adapter actually runs)Opus 4.7,claude-opus-4-7both present/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js(globally installed, in PATH, unused by adapter)Opus 4.6,claude-opus-4-6Despite the global install reporting up to Opus 4.6 only, an openab session running adapter 0.29.0 correctly returns
availableModelscontaining Opus 4.7 and acceptscurrentModelId: "opus"as 4.7.Steps to Reproduce
Build the current
Dockerfile.claudeatmainand inspect the two cli.js files inside the container:The two lists differ — proving the global install is out-of-sync with the one the adapter actually uses.
Additionally, trace which binary is spawned when openab opens a Claude session:
The
cli.jsbeing read is under@agentclientprotocol/claude-agent-acp/node_modules/@anthropic-ai/claude-agent-sdk/— never/usr/local/lib/node_modules/@anthropic-ai/claude-code/.Expected Behavior
One of the following should hold:
@anthropic-ai/claude-codefromDockerfile.claude— if nothing in the container actually relies on it, the install is pure bloat (~50 MB image) and its pinning effort is cargo-cult.CLAUDE_CODE_EXECUTABLE=/usr/local/bin/claudein the container env (adapter checks this env var first peracp-agent.js:1079) so the pinned version is what the adapter actually runs. ThenCLAUDE_CODE_VERSIONbecomes load-bearing again.Dockerfile.claudeexplaining that@anthropic-ai/claude-codeis installed only forclaude --versiondebugging / auth tooling, and that the real Claude CLI used by sessions is the one bundled inclaude-agent-acp. This saves future maintainers from repeating the PR fix: revert claude-code to 2.1.104 due to upstream auth regression #333 / fix: bump CLI versions — codex 0.121.0, gemini 0.38.1, copilot 1.0.30, cursor 2026.04.15 #412 analysis believing it's load-bearing when it isn't.Option (2) is the most correct if reproducibility is the goal, since it decouples adapter-bundled sdk version from the CLI version.
Environment
openab 0.7.7ghcr.io/openabdev/openab-claude:0.7.7(and verified in local build ofDockerfile.claudeatmaincommitde9bce4)@agentclientprotocol/claude-agent-acp@0.25.0(Dockerfile default;0.29.0in my local repro)@anthropic-ai/claude-code@2.1.104node:22-bookworm-slimbaseScreenshots / Logs
acp-agent.js:34(adapter source) — see Description section.Grep output from my running container (adapter 0.29.0 + CLI 2.1.104):
ACP
session/newresponse from the same pod showing Opus 4.7 available despite global install being 2.1.104:{ "modelId": "opus", "name": "Opus", "description": "Opus 4.7 · Most capable for complex work" }