fix(smolmachines): bridge host SIGWINCH into the VM PTY (issue #82) #83
@@ -22,9 +22,21 @@ import sys
|
|||||||
from typing import Mapping
|
from typing import Mapping
|
||||||
|
|
||||||
from .. import Bottle, ExecResult
|
from .. import Bottle, ExecResult
|
||||||
|
from . import pty_resize as _pty_resize
|
||||||
from . import smolvm as _smolvm
|
from . import smolvm as _smolvm
|
||||||
|
|
||||||
|
|
||||||
|
# Absolute path to the pty_resize wrapper. The dashboard's tmux
|
||||||
|
# pane (split-window / respawn-pane) opens the new pane in its
|
||||||
|
# OWN cwd, not the cwd of the process running split-window — so
|
||||||
|
# invoking the wrapper as `python -m <dotted-path>` would fail
|
||||||
|
# with ModuleNotFoundError whenever the operator's tmux pane was
|
||||||
|
# started from anywhere outside the claude-bottle repo. Absolute
|
||||||
|
# path sidesteps the cwd dependence (the wrapper has no
|
||||||
|
# claude_bottle.* imports, so it runs as a standalone script).
|
||||||
|
|
|||||||
|
_PTY_RESIZE_SCRIPT = _pty_resize.__file__
|
||||||
|
|
||||||
|
|
||||||
# Per-user env the agent image's USER (node) expects. claude
|
# Per-user env the agent image's USER (node) expects. claude
|
||||||
# reads ~/.claude.json + writes session state under ~/.claude/;
|
# reads ~/.claude.json + writes session state under ~/.claude/;
|
||||||
# bare `runuser -u` inherits root's HOME=/root, which claude
|
# bare `runuser -u` inherits root's HOME=/root, which claude
|
||||||
@@ -96,8 +108,7 @@ class SmolmachinesBottle(Bottle):
|
|||||||
# happen to go through this method) stay light.
|
# happen to go through this method) stay light.
|
||||||
return flags
|
return flags
|
||||||
return [
|
return [
|
||||||
sys.executable, "-m",
|
sys.executable, _PTY_RESIZE_SCRIPT,
|
||||||
"claude_bottle.backend.smolmachines.pty_resize",
|
|
||||||
self.name, "--", *flags,
|
self.name, "--", *flags,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from __future__ import annotations
|
|||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
from claude_bottle.backend.smolmachines import pty_resize as _pty_resize
|
||||||
from claude_bottle.backend.smolmachines.bottle import SmolmachinesBottle
|
from claude_bottle.backend.smolmachines.bottle import SmolmachinesBottle
|
||||||
|
|
||||||
|
|
||||||
@@ -40,13 +41,15 @@ class TestClaudeArgvWrapped(unittest.TestCase):
|
|||||||
|
|
||||||
def test_pty_resize_wrapper_prefix(self):
|
def test_pty_resize_wrapper_prefix(self):
|
||||||
argv = _bottle().claude_argv([])
|
argv = _bottle().claude_argv([])
|
||||||
|
# Absolute script path (not `-m <dotted>`) so the tmux
|
||||||
|
# pane's cwd doesn't matter — see the `_PTY_RESIZE_SCRIPT`
|
||||||
|
# docstring in bottle.py.
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
[
|
[
|
||||||
sys.executable, "-m",
|
sys.executable, _pty_resize.__file__,
|
||||||
"claude_bottle.backend.smolmachines.pty_resize",
|
|
||||||
"claude-bottle-dev-abc", "--",
|
"claude-bottle-dev-abc", "--",
|
||||||
],
|
],
|
||||||
argv[:5],
|
argv[:4],
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_minimal_inner_argv_no_prompt(self):
|
def test_minimal_inner_argv_no_prompt(self):
|
||||||
@@ -128,7 +131,7 @@ class TestClaudeArgvNoTTY(unittest.TestCase):
|
|||||||
def test_no_wrapper_when_tty_false(self):
|
def test_no_wrapper_when_tty_false(self):
|
||||||
argv = _bottle().claude_argv([], tty=False)
|
argv = _bottle().claude_argv([], tty=False)
|
||||||
self.assertEqual("smolvm", argv[0])
|
self.assertEqual("smolvm", argv[0])
|
||||||
self.assertNotIn("pty_resize", " ".join(argv))
|
self.assertFalse(any("pty_resize" in a for a in argv))
|
||||||
|
|
||||||
def test_tty_false_drops_it_flags(self):
|
def test_tty_false_drops_it_flags(self):
|
||||||
argv = _bottle().claude_argv([], tty=False)
|
argv = _bottle().claude_argv([], tty=False)
|
||||||
|
|||||||
Reference in New Issue
Block a user
This wasn't the core issue, so I don't know if this logic is true. But it doesn't hurt/might be true, I think?
Fair call. The tmux-pane-cwd hypothesis was just a guess that turned out not to be the actual bug (libkrun's bringup race was), and I never went back to verify it. Rewrote the comment in
b3c6d66to drop the speculation and just state the operative reason: the wrapper is self-contained (noclaude_bottle.*imports), so an absolute-path invocation works regardless of cwd. Same one-line_PTY_RESIZE_SCRIPT = _pty_resize.__file__line, leaner justification.