fix(dashboard): hoist claude_argv to Bottle ABC so smolmachines pane attach works #81

Merged
didericis merged 1 commits from dashboard-smolmachines-claude-argv into main 2026-05-27 19:56:04 -04:00
Collaborator

Summary

Launching a smolmachines agent from the dashboard inside tmux crashed with

AttributeError: 'SmolmachinesBottle' object has no attribute 'claude_docker_argv'

The tmux pane-respawn path called bottle.claude_docker_argv(...) directly — a method that only existed on DockerBottle. The foreground-handoff path doesn't hit it because it goes through bottle.exec_claude (which is on the ABC).

Changes

  • Bottle ABC gains claude_argv(argv, *, tty=True) -> list[str]. Both backends implement it; both exec_claude impls collapse to subprocess.run(self.claude_argv(argv, tty=tty), check=False).
  • DockerBottle: rename claude_docker_argvclaude_argv, body unchanged.
  • SmolmachinesBottle: extract the argv-building from exec_claude into claude_argv; the new method returns the full smolvm machine exec --name … -- runuser -u node -- claude … argv. The runuser switch lives on the exec-framing prefix so the dashboard's _build_resume_argv_with_fallback split-at-claude trick keeps the UID switch when wrapping the claude tail in sh -c "… --continue || …".
  • Dashboard: drop docker-specific wording — local + helper arg names docker_argvclaude_argv; docstrings on _build_resume_argv_with_fallback, _build_split_pane_argv, _build_respawn_pane_argv now say "backend-exec argv". The shell-fallback wrap logic is unchanged.

Tests

  • tests/unit/test_smolmachines_bottle.py (new): locks down the smolmachines argv shape — prompt-file flag injection, guest-env -e K=V forwarding, TTY toggle, runuser precedes claude invariant.
  • test_docker_bottle.py: TestClaudeDockerArgvTestClaudeArgv; method renames follow.
  • test_dashboard_active_agents.py: docstring follow.

615 unit tests pass.

Stacking

Independent — branches off main directly. Touches the Bottle ABC and the two backends' bottle implementations plus the dashboard's tmux path.

## Summary Launching a smolmachines agent from the dashboard inside tmux crashed with ``` AttributeError: 'SmolmachinesBottle' object has no attribute 'claude_docker_argv' ``` The tmux pane-respawn path called `bottle.claude_docker_argv(...)` directly — a method that only existed on `DockerBottle`. The foreground-handoff path doesn't hit it because it goes through `bottle.exec_claude` (which is on the ABC). ## Changes - **`Bottle` ABC gains `claude_argv(argv, *, tty=True) -> list[str]`.** Both backends implement it; both `exec_claude` impls collapse to `subprocess.run(self.claude_argv(argv, tty=tty), check=False)`. - **`DockerBottle`:** rename `claude_docker_argv` → `claude_argv`, body unchanged. - **`SmolmachinesBottle`:** extract the argv-building from `exec_claude` into `claude_argv`; the new method returns the full `smolvm machine exec --name … -- runuser -u node -- claude …` argv. The `runuser` switch lives on the exec-framing prefix so the dashboard's `_build_resume_argv_with_fallback` split-at-`claude` trick keeps the UID switch when wrapping the claude tail in `sh -c "… --continue || …"`. - **Dashboard:** drop docker-specific wording — local + helper arg names `docker_argv` → `claude_argv`; docstrings on `_build_resume_argv_with_fallback`, `_build_split_pane_argv`, `_build_respawn_pane_argv` now say "backend-exec argv". The shell-fallback wrap logic is unchanged. ## Tests - `tests/unit/test_smolmachines_bottle.py` (new): locks down the smolmachines argv shape — prompt-file flag injection, guest-env `-e K=V` forwarding, TTY toggle, `runuser` precedes `claude` invariant. - `test_docker_bottle.py`: `TestClaudeDockerArgv` → `TestClaudeArgv`; method renames follow. - `test_dashboard_active_agents.py`: docstring follow. 615 unit tests pass. ## Stacking Independent — branches off main directly. Touches the Bottle ABC and the two backends' bottle implementations plus the dashboard's tmux path.
didericis-claude added 1 commit 2026-05-27 19:52:22 -04:00
fix(dashboard): hoist claude_argv to Bottle ABC so smolmachines pane attach works
test / unit (pull_request) Successful in 27s
test / integration (pull_request) Successful in 42s
test / unit (push) Successful in 26s
test / integration (push) Successful in 45s
3103266053
Launching a smolmachines agent from the dashboard inside tmux
crashed with

  AttributeError: 'SmolmachinesBottle' object has no attribute
  'claude_docker_argv'

because the tmux pane-respawn path called
`bottle.claude_docker_argv(...)` directly — a method that only
existed on DockerBottle. The foreground-handoff path (curses
endwin → subprocess.run → restore) doesn't hit it; it goes
through `bottle.exec_claude` which is on the ABC.

- Move the argv builder onto the `Bottle` ABC as
  `claude_argv(argv, *, tty=True) -> list[str]`. Both backends
  implement it; both `exec_claude` impls collapse to
  `subprocess.run(self.claude_argv(argv, tty=tty), check=False)`.

- DockerBottle: rename `claude_docker_argv` → `claude_argv`,
  body unchanged.

- SmolmachinesBottle: extract the argv-building from
  `exec_claude` into `claude_argv`; the new method returns the
  full `smolvm machine exec --name … -- runuser -u node --
  claude …` argv. The `runuser` switch lives on the
  exec-framing prefix so the dashboard's
  `_build_resume_argv_with_fallback` split-at-"claude" trick
  keeps the UID switch when wrapping the claude tail in
  `sh -c "… --continue || …"`.

- Dashboard: drop the docker-specific wording — local + helper
  arg names `docker_argv` → `claude_argv`; docstrings on
  `_build_resume_argv_with_fallback`, `_build_split_pane_argv`,
  `_build_respawn_pane_argv` now say "backend-exec argv". The
  shell-fallback wrap is unchanged; the existing logic works
  for smolmachines because `claude` is still the marker token.

Tests:
- `tests/unit/test_smolmachines_bottle.py` (new): locks down
  the smolmachines argv shape — prompt-file flag injection,
  guest-env `-e K=V` forwarding, TTY toggle, runuser-precedes-
  claude invariant.
- `test_docker_bottle.py`: TestClaudeDockerArgv →
  TestClaudeArgv; method renames follow.
- `test_dashboard_active_agents.py`: docstring follow.

615 unit tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
didericis approved these changes 2026-05-27 19:55:53 -04:00
didericis merged commit 3103266053 into main 2026-05-27 19:56:04 -04:00
didericis deleted branch dashboard-smolmachines-claude-argv 2026-05-27 19:56:04 -04:00
Sign in to join this conversation.