diff --git a/backend/internal/adapters/runtime/tmux/tmux.go b/backend/internal/adapters/runtime/tmux/tmux.go index 8388a5713..892add6b9 100644 --- a/backend/internal/adapters/runtime/tmux/tmux.go +++ b/backend/internal/adapters/runtime/tmux/tmux.go @@ -236,7 +236,7 @@ func (r *Runtime) Attach(ctx context.Context, handle ports.RuntimeHandle, rows, if err != nil { return nil, err } - return ptyexec.Spawn(ctx, argv, nil, rows, cols) + return ptyexec.Spawn(ctx, argv, attachEnv(os.Environ()), rows, cols) } // attachCommand returns the argv to attach a terminal to the session. @@ -249,6 +249,17 @@ func (r *Runtime) attachCommand(handle ports.RuntimeHandle) ([]string, error) { return []string{r.binary, "attach-session", "-t", id}, nil } +func attachEnv(base []string) []string { + env := append([]string(nil), base...) + for i, kv := range env { + if strings.HasPrefix(kv, "TERM=") { + env[i] = "TERM=xterm-256color" + return env + } + } + return append(env, "TERM=xterm-256color") +} + // run wraps runner.Run with a per-call timeout context. func (r *Runtime) run(ctx context.Context, args ...string) ([]byte, error) { cmdCtx, cancel := context.WithTimeout(ctx, r.timeout) diff --git a/backend/internal/adapters/runtime/tmux/tmux_test.go b/backend/internal/adapters/runtime/tmux/tmux_test.go index 04242099d..a6ae8bf68 100644 --- a/backend/internal/adapters/runtime/tmux/tmux_test.go +++ b/backend/internal/adapters/runtime/tmux/tmux_test.go @@ -551,6 +551,18 @@ func TestAttachCommandRejectsInvalidHandle(t *testing.T) { } } +func TestAttachEnvForcesUsableTerm(t *testing.T) { + env := attachEnv([]string{"PATH=/bin", "TERM=dumb", "SHELL=/bin/sh"}) + if got, want := env, []string{"PATH=/bin", "TERM=xterm-256color", "SHELL=/bin/sh"}; !reflect.DeepEqual(got, want) { + t.Fatalf("attachEnv = %#v, want %#v", got, want) + } + + env = attachEnv([]string{"PATH=/bin"}) + if got, want := env, []string{"PATH=/bin", "TERM=xterm-256color"}; !reflect.DeepEqual(got, want) { + t.Fatalf("attachEnv without TERM = %#v, want %#v", got, want) + } +} + // -- commandError tests -- func TestCommandErrorUnwraps(t *testing.T) {