Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions bin/comms_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ def warm_workspace_title(paths: comms_lib.Paths) -> str:
# instead of going through model_tiers like pulse.py/strategist.py/
# lesson-extractor.py/narrate-brief.py already do — it broke the moment the
# operator's alias stopped defaulting to Bedrock).
CLAUDE_BIN = os.environ.get("CLAUDE_BIN", str(HOME / ".local/bin/claude"))
# Unset: the pane runs `command claude`, a PATH lookup that reaches cmux's claude
# shim (its wrapper registers the session with cmux) and skips the shell alias.
CLAUDE_BIN = os.environ.get("CLAUDE_BIN")


def _resolve_warm_model_and_backend() -> tuple[str, str, bool]:
Expand Down Expand Up @@ -838,7 +840,7 @@ def _warm_launch(agent: str, resolved: tuple[str, str, bool] | None = None) -> s
prefix = "" if pinned else f"CLAUDE_CODE_USE_BEDROCK={'1' if backend == 'bedrock' else '0'} "
return (
f"{prefix}"
f"{shlex.quote(CLAUDE_BIN)} --model {shlex.quote(model)} "
f"{shlex.quote(CLAUDE_BIN) if CLAUDE_BIN else 'command claude'} --model {shlex.quote(model)} "
f"--dangerously-skip-permissions "
f"--add-dir {shlex.quote(str(REPO_ROOT))} --add-dir {shlex.quote(str(HOME / '.assistant'))} "
f"--add-dir {shlex.quote(str(HOME / '.architect'))} --add-dir /tmp"
Expand Down
16 changes: 16 additions & 0 deletions tests/test_comms_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,22 @@ def test_warm_launch_pinned_model_skips_the_backend_prefix(monkeypatch):
assert "us.anthropic.claude-sonnet-4-6[1m]" in cmd


def test_warm_launch_finds_claude_on_path_so_cmux_wraps_it(monkeypatch):
# The pane's login shell must resolve `claude` through PATH (cmux's shim) — a
# hardcoded ~/.local/bin/claude skips cmux's wrapper and its session hooks.
monkeypatch.setattr(cs, "CLAUDE_BIN", None)
cmd = cs._warm_launch(ag.CLAUDE)
assert " command claude --model " in f" {cmd}"
assert ".local/bin/claude" not in cmd


def test_warm_launch_honors_an_explicit_claude_bin(monkeypatch):
monkeypatch.setattr(cs, "CLAUDE_BIN", "/opt/agents/claude code")
cmd = cs._warm_launch(ag.CLAUDE)
assert "'/opt/agents/claude code' --model " in cmd
assert "command claude" not in cmd


def test_resolve_warm_model_and_backend_respects_env(monkeypatch):
monkeypatch.setenv("CLAUDE_CODE_USE_BEDROCK", "1")
model, backend, pinned = cs._resolve_warm_model_and_backend()
Expand Down
Loading