Commit Graph
2 Commits
Author SHA1 Message Date
tao.chen 5ed618494d feat(shell): run bash on a real PTY via creack/pty
The shell manager used os.Pipe() for stdin/stdout/stderr, so bash ran
without a tty. Programs that check isatty() (python, htop, less,
vim-style REPLs) would drop echo, ignore line-editing, and leak literal
0x1b bytes into the program — Python's REPL reported 'invalid
non-printable character U+001B' on input.

Switch to github.com/creack/pty:StartWithSize with an 80x24 default
and TERM=xterm-256color in cmd.Env. The PTY file replaces both the
stdin and stdout pipes; sess.Stdin is the pty *os.File and the
output capture goroutine reads from it directly. waitExit no longer
needs to close sess.Stdin — the capture goroutine's defer handles it
when the process dies and the pty returns EOF.

- go.mod / go.sum: add creack/pty v1.1.24.
- internal/shell/manager.go: rewrite Start to use pty.StartWithSize;
  captureOutput reads from the pty; waitExit simplified; race-clean
  exited map to avoid the cmd.ProcessState data race.
- internal/shell/manager_test.go (new): TestShellPTYIsRealTerminal
  (echo with echo + output interleaved proves PTY echo is on) and
  TestShellPTYTermEnv (TERM=xterm-256color propagates).

E2E against the real bash: 'python3 -q' returns the >>> prompt,
print(2+2) returns 4, exit() returns to bash, 0 ESC bytes leak.

Conversation: 019f35fa-601b-73c1-bd9e-221971c31a56
2026-07-06 14:05:47 +08:00
tao.chenandClaude 0ec3efa812 feat(shell): add parallel bash shell subsystem auto-started per workspace
Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-03 16:36:35 +08:00