diff --git a/.gitignore b/.gitignore index 6b039f7..a6b856b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ coverage.* .idea/ .vscode/ /.claude/worktrees/ +/.worktrees/ /CLAUDE.md /PLAN.md graphify_out/ diff --git a/README.md b/README.md index 546e49f..31f1e64 100644 --- a/README.md +++ b/README.md @@ -156,8 +156,7 @@ agent's PTY: `UAM_ATTACH_MOUSE` controls whether provider mouse reporting is preserved: -- `auto` (the default) enables it locally and disables it when `SSH_CONNECTION` - or `SSH_TTY` indicates an SSH session +- `auto` (the default) preserves provider mouse reporting locally and over SSH - `on` preserves provider mouse reporting everywhere - `off` suppresses provider mouse modes so the terminal keeps selection and paste gestures @@ -166,10 +165,11 @@ Bracketed-paste payload is forwarded byte-for-byte. Control bytes inside a paste do not trigger UAM's attach shortcuts. UAM cannot access the client clipboard or turn an unsent mouse gesture into remote input. -For PowerShell SSH, use Windows Terminal and configure a Windows Terminal paste -binding such as right-click, `Ctrl+Shift+V`, or `Shift+Insert`. Keep -`UAM_ATTACH_MOUSE=auto` (or set it to `off`) on the remote host if provider mouse -tracking captures selection or right-click. Native Windows remains unsupported; +For PowerShell SSH, use Windows Terminal and configure a keyboard paste binding +such as `Ctrl+V`, `Ctrl+Shift+V`, or `Shift+Insert`. Provider mouse reporting is +enabled by default so OpenCode and other mouse-aware providers can scroll. Set +`UAM_ATTACH_MOUSE=off` on the remote host when terminal-owned selection or +right-click paste is more important. Native Windows remains unsupported; Windows is the SSH client in this setup. In the TUI, `Ctrl+X` followed by `y` stops the process **and removes its stored diff --git a/docs/adr/0002-terminal-ownership-over-ssh.md b/docs/adr/0002-terminal-ownership-over-ssh.md index 74176f1..779dcdd 100644 --- a/docs/adr/0002-terminal-ownership-over-ssh.md +++ b/docs/adr/0002-terminal-ownership-over-ssh.md @@ -2,6 +2,7 @@ - Status: Accepted - Date: 2026-07-12 +- Amended: 2026-07-14 — provider scrolling now takes priority over terminal-owned mouse gestures by default. ## Context @@ -43,14 +44,16 @@ Non-terminal streams do not receive alternate-screen control sequences. | Value | Behavior | |---|---| -| `auto` or unset | Enable provider mouse reporting locally. Disable it when `SSH_CONNECTION` or `SSH_TTY` indicates an SSH session. | +| `auto` or unset | Preserve provider mouse reporting locally and over SSH. | | `on` | Preserve provider mouse reporting, including over SSH. | | `off` | Suppress provider mouse-reporting modes while attached. | -Invalid values use `auto`. With mouse reporting off, UAM removes only the -well-known mouse mode parameters from provider control sequences and preserves -unrelated terminal modes. This makes local selection and terminal-defined paste -more predictable over SSH without rewriting provider text. +Invalid values use the default `auto` behavior. Only explicit `off` suppresses +provider mouse reporting, retaining the former SSH behavior for users who +prioritize terminal-owned selection and paste. With mouse reporting off, UAM +removes only the well-known mouse mode parameters from provider control +sequences and preserves unrelated terminal modes without rewriting provider +text. ### Paste is a byte stream @@ -69,11 +72,11 @@ observe the local clipboard, convert a Windows mouse event into remote input, or make PowerShell's console host behave like another terminal. For Windows clients, Windows Terminal is the recommended host for PowerShell -SSH. Configure a local paste binding such as right-click, `Ctrl+Shift+V`, or +SSH. Configure a keyboard paste binding such as `Ctrl+V`, `Ctrl+Shift+V`, or `Shift+Insert`; the exact binding belongs to Windows Terminal. Once it sends the -text, UAM forwards it unchanged. If selection or right-click is captured by a -remote provider, keep `UAM_ATTACH_MOUSE=auto` or set it to `off` on the remote -host. +text, UAM forwards it unchanged. Provider mouse reporting is preserved by +default so remote providers can scroll. Set `UAM_ATTACH_MOUSE=off` on the remote +host when terminal-owned selection or right-click paste is more important. Windows remains an SSH client in this design. UAM is not a native Windows process. @@ -92,10 +95,11 @@ never sends the paste action. Rejected because it destroys user-visible shell history and resets unrelated terminal preferences. Targeted cleanup is sufficient to re-establish ownership. -### Always enable provider mouse reporting +### Disable provider mouse reporting automatically over SSH -Rejected because many SSH terminal workflows depend on the local terminal for -selection and paste. Users can still opt in with `UAM_ATTACH_MOUSE=on`. +Rejected because it prevents wheel and touch scrolling in providers such as +OpenCode and OMP. Users who prioritize terminal-owned selection or paste can +still opt out with `UAM_ATTACH_MOUSE=off`. ### Strip all private terminal modes @@ -107,8 +111,8 @@ mouse policy. - Returning from attach or quitting the dashboard leaves a predictable shell surface without erasing scrollback. -- SSH defaults favor terminal selection and paste; local use retains provider - mouse interaction. +- SSH defaults favor provider mouse interaction; terminal selection and paste + may require keyboard bindings or explicit `UAM_ATTACH_MOUSE=off`. - Pasted control bytes cannot accidentally trigger UAM detach or suppression shortcuts. - Terminal-client configuration remains necessary when the client does not send diff --git a/docs/responsive-tui.md b/docs/responsive-tui.md index c3bdb61..85f4dc2 100644 --- a/docs/responsive-tui.md +++ b/docs/responsive-tui.md @@ -120,10 +120,10 @@ changes. UAM does not assume a fixed phone aspect ratio. ## SSH, mouse, and paste -Mouse reporting defaults on for local attachment and off when the environment -contains `SSH_CONNECTION` or `SSH_TTY`. Override it with -`UAM_ATTACH_MOUSE=on|off|auto`. Keeping it off over SSH lets the terminal retain -selection and paste gestures; setting it on restores provider mouse interaction. +Mouse reporting defaults on for local and SSH attachments so wheel and touch +gestures reach mouse-aware providers such as OpenCode and OMP. Override it with +`UAM_ATTACH_MOUSE=on|off|auto`. Set it to `off` when terminal-owned selection or +right-click paste is more important than provider scrolling. Bracketed-paste payload is forwarded literally, including control bytes, UTF-8, and line endings. UAM cannot initiate paste from a local clipboard. Windows users @@ -153,10 +153,11 @@ If right-click paste behaves differently through PowerShell SSH: 1. Confirm the SSH command is running inside Windows Terminal rather than the legacy console host. -2. Confirm Windows Terminal has a paste binding for the gesture or key chord. -3. Keep the remote setting at `UAM_ATTACH_MOUSE=auto`, or set it to `off`. -4. Test `Ctrl+Shift+V` or `Shift+Insert` to separate a client binding problem - from remote input handling. +2. Confirm Windows Terminal has a keyboard paste binding such as `Ctrl+V`, + `Ctrl+Shift+V`, or `Shift+Insert`. +3. Keep the remote setting at `UAM_ATTACH_MOUSE=auto` for provider scrolling. +4. If terminal-owned selection or right-click paste is preferred, set the + remote setting to `UAM_ATTACH_MOUSE=off` and reattach. If resuming a stopped row reports ambiguity, read the provider and Workspace in the message. Confirm only when selecting the provider's latest conversation is diff --git a/docs/superpowers/plans/2026-07-14-enable-ssh-provider-mouse.md b/docs/superpowers/plans/2026-07-14-enable-ssh-provider-mouse.md new file mode 100644 index 0000000..b115b76 --- /dev/null +++ b/docs/superpowers/plans/2026-07-14-enable-ssh-provider-mouse.md @@ -0,0 +1,234 @@ +# Enable SSH Provider Mouse Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Preserve provider mouse reporting by default over SSH so OpenCode and OMP wheel/touch scrolling works through UAM. + +**Architecture:** Keep the existing attach output filter and explicit `UAM_ATTACH_MOUSE` policy boundary. Change only policy resolution so every value except `off` preserves provider-requested mouse modes, then document keyboard paste and explicit `off` as the compatibility fallback. + +**Tech Stack:** Go 1.25.12, Unix PTYs, DEC private terminal modes, Go `testing`, Markdown documentation. + +## Global Constraints + +- Provider mouse reporting is enabled by default for local and SSH viewers. +- `UAM_ATTACH_MOUSE=off` retains terminal-owned mouse gestures. +- UAM preserves mouse modes only when the provider requests them. +- Do not change the attach protocol, store schema, provider arguments, session metadata, input framing, alternate-screen ownership, or detach cleanup. +- Linux, Ubuntu, and macOS behavior must remain supported. +- Use `rtk` for every shell command as required by `/opt/codex/RTK.md`. + +--- + +### Task 1: Make SSH Mouse Reporting the Default + +**Files:** +- Modify: `internal/session/attach_filter_test.go:27-79` +- Modify: `internal/session/attach.go:27-44` + +**Interfaces:** +- Consumes: `attachMouseEnabled(getenv func(string) string) bool` and `newAttachOutputFilter(dst io.Writer, mouse bool) *attachOutputFilter`. +- Produces: unchanged `attachMouseEnabled` signature with the new rule that only explicit `off` returns false. + +- [ ] **Step 1: Write the failing policy and OpenCode regression tests** + +Change the SSH expectations in `TestAttachMousePolicy` and add an integration-level policy/filter test: + +```go +func TestAttachMousePolicy(t *testing.T) { + tests := []struct { + name, value, sshConnection, sshTTY string + want bool + }{ + {"unset local", "", "", "", true}, {"auto local", "auto", "", "", true}, + {"unset ssh connection", "", "client", "", true}, {"auto ssh tty", "auto", "", "/dev/pts/1", true}, + {"on ssh", "on", "client", "", true}, {"off local", "off", "", "", false}, + {"off ssh", "off", "client", "/dev/pts/1", false}, + {"invalid local", "maybe", "", "", true}, {"invalid ssh", "maybe", "client", "", true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + env := map[string]string{AttachMouseEnv: tt.value, "SSH_CONNECTION": tt.sshConnection, "SSH_TTY": tt.sshTTY} + if got := attachMouseEnabled(func(key string) string { return env[key] }); got != tt.want { + t.Fatalf("got %v, want %v", got, tt.want) + } + }) + } +} + +func TestAttachDefaultSSHPreservesOpenCodeMouseModes(t *testing.T) { + env := map[string]string{ + AttachMouseEnv: "", + "SSH_CONNECTION": "client 123 server 22", + "SSH_TTY": "/dev/pts/1", + } + mouse := attachMouseEnabled(func(key string) string { return env[key] }) + input := []byte("\x1b[?1000;1002;1003;1006h") + if got := filterHostOutput(t, mouse, input); !bytes.Equal(got, input) { + t.Fatalf("default SSH attach changed OpenCode mouse modes: got %q, want %q", got, input) + } +} +``` + +- [ ] **Step 2: Run the focused tests and verify RED** + +Run: + +```bash +rtk proxy env GOTOOLCHAIN=go1.25.12 go test ./internal/session -run 'Test(AttachMousePolicy|AttachDefaultSSHPreservesOpenCodeMouseModes)' -count=1 -v +``` + +Expected: FAIL for the SSH `auto`/unset/invalid cases and for the OpenCode grouped mouse-mode assertion because current SSH auto policy returns false. + +- [ ] **Step 3: Implement the minimal policy change** + +Replace `attachMouseEnabled` and its comment in `internal/session/attach.go` with: + +```go +// attachMouseEnabled resolves the per-viewer mouse policy. Providers keep mouse +// support locally and over SSH by default so wheel and touch scrolling work. +// Explicit off leaves mouse gestures under terminal control for selection/paste. +func attachMouseEnabled(getenv func(string) string) bool { + return getenv(AttachMouseEnv) != "off" +} +``` + +- [ ] **Step 4: Run focused and session-package tests and verify GREEN** + +Run: + +```bash +rtk proxy env GOTOOLCHAIN=go1.25.12 go test ./internal/session -run 'Test(AttachMousePolicy|AttachDefaultSSHPreservesOpenCodeMouseModes|AttachOutputFilterOwnedModes|MouseEventsDoNotDisarm|AttachOwnsTerminalStateOnTTY|ReattachReplaysAgentPrivateModes|AttachMouseOffFiltersReplayedProviderModes)' -count=1 -v +rtk proxy env GOTOOLCHAIN=go1.25.12 go test ./internal/session -count=1 +``` + +Expected: PASS. The default SSH test preserves the complete OpenCode sequence, explicit `off` still strips mouse modes, stdin wheel bytes remain unchanged, and detach ownership tests remain green. + +- [ ] **Step 5: Format and commit the behavioral change** + +Run: + +```bash +rtk proxy gofmt -w internal/session/attach.go internal/session/attach_filter_test.go +rtk proxy git diff --check +rtk proxy git add internal/session/attach.go internal/session/attach_filter_test.go +rtk proxy git commit -m "fix(attach): enable provider mouse over SSH" +``` + +Expected: commit contains only the policy and regression-test changes. + +--- + +### Task 2: Align Documentation and Run the Full Quality Gate + +**Files:** +- Modify: `README.md:157-173` +- Modify: `docs/responsive-tui.md:121-132` +- Modify: `docs/responsive-tui.md:152-159` +- Modify: `docs/adr/0002-terminal-ownership-over-ssh.md:1-115` + +**Interfaces:** +- Consumes: the `UAM_ATTACH_MOUSE` behavior implemented in Task 1. +- Produces: one consistent user contract for `auto`, `on`, `off`, invalid values, SSH scrolling, and keyboard paste fallback. + +- [ ] **Step 1: Update the README contract and PowerShell guidance** + +Replace the mouse policy list in `README.md` with: + +```markdown +`UAM_ATTACH_MOUSE` controls whether provider mouse reporting is preserved: + +- `auto` (the default) preserves provider mouse reporting locally and over SSH +- `on` preserves provider mouse reporting everywhere +- `off` suppresses provider mouse modes so the terminal keeps selection and + paste gestures +``` + +Replace the PowerShell guidance with: + +```markdown +For PowerShell SSH, use Windows Terminal and configure a keyboard paste binding +such as `Ctrl+V`, `Ctrl+Shift+V`, or `Shift+Insert`. Provider mouse reporting is +enabled by default so OpenCode and other mouse-aware providers can scroll. Set +`UAM_ATTACH_MOUSE=off` on the remote host when terminal-owned selection or +right-click paste is more important. Native Windows remains unsupported; +Windows is the SSH client in this setup. +``` + +- [ ] **Step 2: Update responsive TUI operations guidance** + +Replace the opening paragraph under `## SSH, mouse, and paste` with: + +```markdown +Mouse reporting defaults on for local and SSH attachments so wheel and touch +gestures reach mouse-aware providers such as OpenCode and OMP. Override it with +`UAM_ATTACH_MOUSE=on|off|auto`. Set it to `off` when terminal-owned selection or +right-click paste is more important than provider scrolling. +``` + +Replace troubleshooting steps 2-4 with: + +```markdown +2. Confirm Windows Terminal has a keyboard paste binding such as `Ctrl+V`, + `Ctrl+Shift+V`, or `Shift+Insert`. +3. Keep the remote setting at `UAM_ATTACH_MOUSE=auto` for provider scrolling. +4. If terminal-owned selection or right-click paste is preferred, set the + remote setting to `UAM_ATTACH_MOUSE=off` and reattach. +``` + +- [ ] **Step 3: Amend ADR 0002 to record the changed priority** + +Add this metadata after the original date: + +```markdown +- Amended: 2026-07-14 — provider scrolling now takes priority over terminal-owned mouse gestures by default. +``` + +Change the policy table so `auto` or unset preserves mouse reporting locally and over SSH. State that invalid values use this default; explicit `off` retains the former SSH behavior. Replace the rejected `Always enable provider mouse reporting` alternative with: + +```markdown +### Disable provider mouse reporting automatically over SSH + +Rejected because it prevents wheel and touch scrolling in providers such as +OpenCode and OMP. Users who prioritize terminal-owned selection or paste can +still opt out with `UAM_ATTACH_MOUSE=off`. +``` + +Update the consequence to state that SSH defaults favor provider mouse interaction and that terminal selection/paste may require keyboard bindings or explicit `off`. + +- [ ] **Step 4: Verify documentation consistency** + +Run: + +```bash +rtk rg -n 'disables it when|defaults on for local attachment and off|SSH defaults favor terminal selection|keep the remote setting at `UAM_ATTACH_MOUSE=auto`, or set it to `off`' README.md docs +rtk rg -n 'UAM_ATTACH_MOUSE|provider mouse|OpenCode|OMP' README.md docs/responsive-tui.md docs/adr/0002-terminal-ownership-over-ssh.md +rtk proxy git diff --check +``` + +Expected: the stale-policy search returns no matches; the second search shows the same default-on/explicit-off contract in all three documents; `git diff --check` exits successfully. + +- [ ] **Step 5: Run the complete quality gate** + +Run: + +```bash +rtk proxy env GOTOOLCHAIN=go1.25.12 go test -race -count=1 -covermode=atomic -coverpkg=./... ./... +rtk proxy env GOTOOLCHAIN=go1.25.12 go vet ./... +rtk proxy env GOTOOLCHAIN=go1.25.12 golangci-lint run ./... +rtk proxy env GOTOOLCHAIN=go1.25.12 staticcheck ./... +rtk proxy go mod verify +rtk proxy git diff --check +``` + +Expected: all tests and analyzers exit zero, module verification prints `all modules verified`, and the diff check is clean. + +- [ ] **Step 6: Commit documentation after verification** + +Run: + +```bash +rtk proxy git add README.md docs/responsive-tui.md docs/adr/0002-terminal-ownership-over-ssh.md +rtk proxy git commit -m "docs: prioritize provider scrolling over SSH" +``` + +Expected: commit contains only the README, responsive TUI guide, and ADR changes. diff --git a/docs/superpowers/specs/2026-07-14-ssh-provider-mouse-default-design.md b/docs/superpowers/specs/2026-07-14-ssh-provider-mouse-default-design.md new file mode 100644 index 0000000..48be7fc --- /dev/null +++ b/docs/superpowers/specs/2026-07-14-ssh-provider-mouse-default-design.md @@ -0,0 +1,90 @@ +# SSH Provider Mouse Default + +## Context + +UAM's attach client currently treats `UAM_ATTACH_MOUSE=auto` or an unset value +as provider mouse enabled for local terminals and disabled for SSH terminals. +When disabled, the attach output filter removes DEC mouse modes requested by a +provider. OpenCode and OMP rely on those modes for wheel and touch scrolling, so +their internal views cannot scroll through UAM over SSH. + +The existing SSH default prioritized terminal-owned selection and right-click +paste. The product priority is now provider scrolling. Clipboard behavior is +best effort and can use terminal keyboard bindings such as `Ctrl+V`, +`Ctrl+Shift+V`, or `Shift+Insert`. + +## Decision + +Provider mouse reporting is enabled by default for every attach viewer, +including SSH viewers. The environment variable remains the compatibility and +escape hatch: + +| `UAM_ATTACH_MOUSE` value | Behavior | +|---|---| +| unset or `auto` | Preserve provider mouse modes locally and over SSH. | +| `on` | Preserve provider mouse modes locally and over SSH. | +| `off` | Remove supported provider mouse modes so the terminal owns mouse gestures. | +| invalid | Use the `auto` behavior and preserve provider mouse modes. | + +This policy remains provider-neutral. UAM preserves mouse modes only when the +provider requests them; it does not synthesize mouse events or force mouse mode +for providers that do not use it. + +## Implementation + +`attachMouseEnabled` will resolve every value except explicit `off` to true. +The attach output filter, stdin filter, socket framing, terminal cleanup, and +alternate-screen ownership remain unchanged. + +The output path remains: + +1. The provider emits a DEC mouse-mode enable sequence. +2. The session host records and replays the sequence. +3. The attach output filter preserves it unless the viewer selected `off`. +4. The terminal converts wheel or touch gestures into mouse reports. +5. The stdin filter and framed attach connection forward those bytes unchanged. + +On detach, UAM continues disabling mouse modes before restoring the caller's +terminal. This prevents provider state from leaking into the dashboard or +shell. + +## Compatibility and Trade-offs + +No CLI flags, protocols, session metadata, provider arguments, store schema, or +terminal cleanup sequences change. Existing `on` and `off` overrides remain +valid. + +With provider mouse enabled, some terminals route clicks, drag selection, and +right-click gestures to the provider instead of handling them locally. Users +who prioritize terminal-owned selection or paste can set +`UAM_ATTACH_MOUSE=off`. Keyboard paste remains terminal-dependent because UAM +can forward only bytes supplied by the SSH client. + +## Testing + +Regression coverage will verify: + +- unset and `auto` preserve provider mouse modes over SSH; +- `on` preserves provider mouse modes over SSH; +- only explicit `off` suppresses provider mouse modes; +- invalid values follow `auto` and preserve provider mouse modes; +- OpenCode's grouped `1000/1002/1003/1006` enable sequence survives the default + SSH attach path; +- SGR wheel input remains byte-exact through the stdin filter; +- detach cleanup still disables mouse modes and restores the terminal; +- the complete race-enabled test suite remains green. + +## Documentation and Rollout + +The terminal ownership ADR and user-facing documentation will describe +scrolling as the default priority over SSH and `off` as the selection/paste +opt-out. This is a default-policy change with no migration or irreversible +state, so it can ship as a patch release and be reverted independently. + +## Acceptance Criteria + +- OpenCode and OMP wheel/touch scrolling works through a default SSH attach. +- Local attach behavior is unchanged. +- `UAM_ATTACH_MOUSE=off` retains the previous SSH mouse behavior. +- Provider output, input bytes, attach lifecycle, and terminal cleanup remain + otherwise unchanged. diff --git a/internal/session/attach.go b/internal/session/attach.go index 2fb3843..708e654 100644 --- a/internal/session/attach.go +++ b/internal/session/attach.go @@ -27,20 +27,11 @@ const ctrlC = 0x03 const AttachQuietEnv = "UAM_ATTACH_QUIET" const AttachMouseEnv = "UAM_ATTACH_MOUSE" -// attachMouseEnabled resolves the per-viewer mouse policy. Local attaches keep -// provider mouse support by default; SSH attaches leave mouse gestures to the -// local terminal so selection and paste continue to work. +// attachMouseEnabled resolves the per-viewer mouse policy. Providers keep mouse +// support locally and over SSH by default so wheel and touch scrolling work. +// Explicit off leaves mouse gestures under terminal control for selection/paste. func attachMouseEnabled(getenv func(string) string) bool { - switch getenv(AttachMouseEnv) { - case "on": - return true - case "off": - return false - case "", "auto": - return getenv("SSH_CONNECTION") == "" && getenv("SSH_TTY") == "" - default: - return getenv("SSH_CONNECTION") == "" && getenv("SSH_TTY") == "" - } + return getenv(AttachMouseEnv) != "off" } type attachOptions struct { diff --git a/internal/session/attach_filter_test.go b/internal/session/attach_filter_test.go index f0eb8c1..180ca8a 100644 --- a/internal/session/attach_filter_test.go +++ b/internal/session/attach_filter_test.go @@ -30,9 +30,10 @@ func TestAttachMousePolicy(t *testing.T) { want bool }{ {"unset local", "", "", "", true}, {"auto local", "auto", "", "", true}, - {"unset ssh connection", "", "client", "", false}, {"auto ssh tty", "auto", "", "/dev/pts/1", false}, + {"unset ssh connection", "", "client", "", true}, {"auto ssh tty", "auto", "", "/dev/pts/1", true}, {"on ssh", "on", "client", "", true}, {"off local", "off", "", "", false}, - {"invalid local", "maybe", "", "", true}, {"invalid ssh", "maybe", "client", "", false}, + {"off ssh", "off", "client", "/dev/pts/1", false}, + {"invalid local", "maybe", "", "", true}, {"invalid ssh", "maybe", "client", "", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -59,6 +60,19 @@ func filterHostOutput(t *testing.T, mouse bool, chunks ...[]byte) []byte { return out.Bytes() } +func TestAttachDefaultSSHPreservesOpenCodeMouseModes(t *testing.T) { + env := map[string]string{ + AttachMouseEnv: "", + "SSH_CONNECTION": "client 123 server 22", + "SSH_TTY": "/dev/pts/1", + } + mouse := attachMouseEnabled(func(key string) string { return env[key] }) + input := []byte("\x1b[?1000;1002;1003;1006h") + if got := filterHostOutput(t, mouse, input); !bytes.Equal(got, input) { + t.Fatalf("default SSH attach changed OpenCode mouse modes: got %q, want %q", got, input) + } +} + func TestAttachOutputFilterOwnedModes(t *testing.T) { for _, mouse := range []bool{true, false} { for _, mode := range []string{"47", "1047", "1049"} {