github / github/copilot-cli

Ctrl+H (delete previous character) is misinterpreted as Ctrl+Backspace (delete word) under WSL2 due to WT_SESSION leaking from Windows Terminal

Open Beginner friendly
#4,328 7 comments 0 reactions 0 assignees View on GitHub
area:input-keyboard area:platform-windows
Dominant language
Shell
Stars
11.2k
Forks
1.9k
Avg merge
14h 16m
Merged PRs (30d)
6

Description

### Description

`/help` documents `ctrl+h` as "delete previous character", but under WSL2 it instead deletes the whole previous word (i.e. behaves like `ctrl+w`/Ctrl+Backspace).

### Environment

- Copilot CLI version: 1.0.78-2
- Platform: WSL2 (`Linux ... 6.18.33.2-microsoft-standard-WSL2`), Windows Terminal as host, plain `xterm-256color` inside (issue reproduces both inside and outside tmux)
- `WSLENV=WT_SESSION:WT_PROFILE_ID:` (default WSL/Windows Terminal integration), so `WT_SESSION` is present in the WSL shell environment even though the CLI is not running as a native Windows process

### Root cause

In the bundled `app.js`, the raw-byte key decoder special-cases byte `0x08` (`\b`) — which is exactly what Ctrl+H sends — as Ctrl+Backspace when a `ctrlHIsCtrlBackspace` flag is set:

```js
function ZDe(t, e=!1) {
return t.length!==1 ? null
: t==="\r" ? {code:"return"}
: ...
: t==="\b" && e ? {code:"backspace", ctrl:!0} // <-- Ctrl+H reinterpreted as Ctrl+Backspace
: t==="\b" || t==="\x7F" ? {code:"backspace"}
: ...
}
```

The flag is computed once at startup:

```js
reader = new ope({ ctrlHIsCtrlBackspace: fSt() })

function Nk() { return !RA() && !process.env.TMUX && !process.env.STY }
function fSt() { return process.platform==="win32" && Nk() || !!process.env.WT_SESSION }
```

The intent is reasonable on **native Windows** (Windows Console/Windows Terminal apps can't distinguish a literal Ctrl+H keypress from Ctrl+Backspace, since both produce byte 0x08), so trading away the Ctrl+H binding there makes sense. However, the `|| !!process.env.WT_SESSION` clause has no accompanying `process.platform==="win32"` check, so it also fires under **WSL2**, where `WT_SESSION` is forwarded into the Linux environment by `WSLENV` for terminal-integration purposes, but the CLI is actually running in a normal Linux pty where Ctrl+H and Ctrl+Backspace *are* distinguishable. This causes a false positive: the workaround for a Windows-only ambiguity ends up breaking a real, distinguishable keybinding on WSL.

This also affects users in the reverse scenario, if `WT_SESSION` is otherwise present in the environment (e.g. propagated through SSH or subshells) on non-Windows platforms.

### Steps to reproduce

1. Launch Copilot CLI inside WSL2 under Windows Terminal (default `WSLENV` integration).
2. Type some text, then press Ctrl+H.
3. **Expected:** deletes one character before the cursor (per `/help`).
4. **Actual:** deletes the entire previous word.

### Suggested fix

Gate the `WT_SESSION` check on `process.platform === "win32"` as well, e.g.:

```js
function fSt() {
return process.platform === "win32" && (Nk() || !!process.env.WT_SESSION);
}
```

or otherwise detect WSL (e.g. via `/proc/version` containing "microsoft" or `process.platform !== "win32"`) and skip the `ctrlHIsCtrlBackspace` heuristic in that case.

### Workaround

`unset WT_SESSION` before launching `copilot` restores the documented Ctrl+H behavior.

Contributor guide

Open the contributing guide

Research direction

Start in the bundled app.js at fSt() and its reader initialization, then verify how WT_SESSION and process.platform affect ctrlHIsCtrlBackspace before checking ZDe(). Reproduce under WSL2 with WT_SESSION set and unset; done when Ctrl+H deletes one character while native Windows behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, linux, node.js
Domain
cli, operating-systems
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.