Skip to content

Commit f087632

Browse files
committed
fix: auto-install bridge dependencies when connecting Claude Max
Instead of showing an error when the Claude Agent SDK is missing, automatically install bun and run bun install in the bridge directory. This removes the manual setup step for new users connecting their Claude Max subscription.
1 parent 2609e56 commit f087632

1 file changed

Lines changed: 61 additions & 3 deletions

File tree

atn/runtime/provider_manager.py

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -556,12 +556,13 @@ async def configure_provider(self, provider_id: str, api_key: str = "") -> dict[
556556
return {"status": "ok", "provider": provider_id, "models": models}
557557

558558
elif info["auth_type"] == "bridge":
559+
# Auto-install bridge dependencies if missing
560+
await self._ensure_bridge_deps()
559561
auth = await self._check_claude_auth()
560562
if not auth["installed"]:
561563
raise ValueError(
562-
"Claude Code SDK not found. Install Claude Code "
563-
"(https://claude.ai/download) and run 'bun install' "
564-
"in the bridge/ directory."
564+
"Bridge setup failed. Ensure 'bun' is installed "
565+
"(npm i -g bun) and try again."
565566
)
566567
if not auth["logged_in"]:
567568
log.info("Claude Code not authenticated — launching browser login")
@@ -853,6 +854,63 @@ async def _validate_api_key(self, provider_id: str, api_key: str) -> None:
853854
except httpx.TimeoutException:
854855
raise ValueError(f"Timeout connecting to {provider_id} API")
855856

857+
async def _ensure_bridge_deps(self) -> None:
858+
"""Auto-install bridge dependencies (bun install) if missing."""
859+
bridge_dir = Path(__file__).resolve().parent.parent.parent / "bridge"
860+
pkg_json = bridge_dir / "package.json"
861+
node_modules = bridge_dir / "node_modules"
862+
cli_js = node_modules / "@anthropic-ai" / "claude-agent-sdk" / "cli.js"
863+
864+
if cli_js.exists():
865+
return # Already installed
866+
867+
if not pkg_json.exists():
868+
log.warning("Bridge package.json not found at %s", bridge_dir)
869+
return
870+
871+
# Check bun is available
872+
import shutil
873+
bun = shutil.which("bun")
874+
if not bun:
875+
# Try installing bun via npm
876+
npm = shutil.which("npm")
877+
if npm:
878+
log.info("Installing bun via npm...")
879+
try:
880+
proc = await asyncio.create_subprocess_exec(
881+
npm, "install", "-g", "bun",
882+
stdout=asyncio.subprocess.PIPE,
883+
stderr=asyncio.subprocess.PIPE,
884+
)
885+
await asyncio.wait_for(proc.communicate(), timeout=120)
886+
bun = shutil.which("bun")
887+
except Exception as e:
888+
log.warning("Failed to install bun: %s", e)
889+
890+
if not bun:
891+
log.warning("bun not found — cannot auto-install bridge dependencies")
892+
return
893+
894+
# Run bun install in the bridge directory
895+
log.info("Installing bridge dependencies in %s ...", bridge_dir)
896+
try:
897+
proc = await asyncio.create_subprocess_exec(
898+
bun, "install",
899+
cwd=str(bridge_dir),
900+
stdout=asyncio.subprocess.PIPE,
901+
stderr=asyncio.subprocess.PIPE,
902+
)
903+
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=120)
904+
if proc.returncode == 0:
905+
log.info("Bridge dependencies installed successfully")
906+
else:
907+
log.warning("bun install failed (exit %s): %s",
908+
proc.returncode, stderr.decode(errors="replace")[:500])
909+
except asyncio.TimeoutError:
910+
log.warning("bun install timed out")
911+
except Exception as e:
912+
log.warning("Failed to install bridge dependencies: %s", e)
913+
856914
def _resolve_sdk_cli(self) -> Path | None:
857915
bridge_dir = Path(__file__).resolve().parent.parent.parent / "bridge"
858916
cli_js = bridge_dir / "node_modules" / "@anthropic-ai" / "claude-agent-sdk" / "cli.js"

0 commit comments

Comments
 (0)