Summary
The Cascade chat input widget in Windsurf does not propagate focus to VS Code's standard inputFocus and editorTextFocus context keys when focused. As a result, any extension whose keybindings use !inputFocus or !editorTextFocus as a when-clause exclusion (a very common and well-established pattern) will silently and incorrectly activate inside the Cascade chat input.
The same input box in GitHub Copilot Chat running on stock VS Code does not have this problem, because Copilot Chat's input is a Monaco editor properly registered with ICodeEditorService and therefore correctly sets the standard context keys. Comparing the two confirms this is specific to Windsurf's custom Cascade widget (built on top of @exa/chat-client).
Concrete observable bug — z cannot be typed in Cascade chat
A widely-installed extension, vscode-neovim, registers Vim-style tree-fold chord bindings (z o, z c, z a, z m, and shift-variants) with this when clause:
!editorTextFocus && !inputFocus
This is a perfectly valid scope for "tree-fold shortcuts that should only fire in the file explorer." It evaluates correctly in stock VS Code (and inside Copilot Chat, where inputFocus is set). But in Windsurf's Cascade chat input, neither key is set, so the when clause matches and pressing z triggers the chord-prefix wait state:
(Z) was pressed. Waiting for second key of chord…
The user cannot type the letter z in Cascade chat at all — they have to paste it from elsewhere. Other letters work because vscode-neovim does not register single-letter normal-mode bindings outside of editor focus.
This is one example. The same root cause silently breaks any other extension using !inputFocus for similar exclusion logic.
Steps to reproduce
- Open Windsurf 1.110.1.
- Install vscode-neovim 1.18.24 (no special config needed).
- Open the Cascade chat panel and click into the input box.
- Press
z.
- Expected:
z is typed.
- Actual: Status bar shows
(Z) was pressed. Waiting for second key of chord... — no character is inserted.
- Compare: do the same in GitHub Copilot Chat in stock VS Code with the same vscode-neovim version installed →
z types normally.
Evidence — context keys are not toggled
Searching the compiled Cascade extension (extensions/windsurf/dist/extension.js):
- The strings
chatInputHasFocus, inChatInput, chatInputPart, etc. exist (inherited from VS Code's stock chat strings).
- Only one
setContext call relates to chat: EXTENSION_CONTEXT_KEYS.CAN_TRIGGER_TERMINAL_COMMAND_ACTION. No setContext for any focus context key.
A user-level keybindings.json entry that tries to negate the chords with "when": "chatInputHasFocus || inChatInput" does not apply — confirming neither standard nor inherited context keys are toggled when Cascade input is focused. The only effective workaround is unconditional negation, which sacrifices the chord behaviour everywhere.
Suggested fix
When the Cascade chat input gains/loses keyboard focus, set the standard VS Code context keys:
inputFocus (true while focused)
editorTextFocus (true while focused, if Cascade input is a Monaco editor — typical for chat inputs)
Setting inputFocus alone would already fix !inputFocus-scoped bindings (the most common pattern). Setting both matches what stock VS Code's chat extension and Copilot Chat do, and ensures parity for any extension that relies on either key.
If, for design reasons, Cascade intentionally wants extensions to be able to differentiate "in chat" from "in code editor", also expose a documented Windsurf-specific key like windsurfCascade.inputFocused and document it. That gives extensions a clean way to opt in/out.
Why this matters beyond vscode-neovim
The !inputFocus / !editorTextFocus exclusion pattern is canonical in the VS Code extension ecosystem — used by tree-view extensions, multi-cursor extensions, refactoring extensions, and many others. Each one is currently silently broken inside Cascade chat in ways that may never be reported (because most users won't realise the activation came from "their" extension). The z key issue is just the most visible symptom because it produces an obvious chord-wait status bar message.
Cross-filed
Environment
- Windsurf: 1.110.1 (commit
08b5de9bae1728a5ad46386c9b8903192a125c51, 2026-04-22)
- macOS: Sonoma (Apple Silicon)
- vscode-neovim: 1.18.24 (the trigger; bug is independent of this version)
Summary
The Cascade chat input widget in Windsurf does not propagate focus to VS Code's standard
inputFocusandeditorTextFocuscontext keys when focused. As a result, any extension whose keybindings use!inputFocusor!editorTextFocusas awhen-clause exclusion (a very common and well-established pattern) will silently and incorrectly activate inside the Cascade chat input.The same input box in GitHub Copilot Chat running on stock VS Code does not have this problem, because Copilot Chat's input is a Monaco editor properly registered with
ICodeEditorServiceand therefore correctly sets the standard context keys. Comparing the two confirms this is specific to Windsurf's custom Cascade widget (built on top of@exa/chat-client).Concrete observable bug —
zcannot be typed in Cascade chatA widely-installed extension, vscode-neovim, registers Vim-style tree-fold chord bindings (
z o,z c,z a,z m, and shift-variants) with thiswhenclause:This is a perfectly valid scope for "tree-fold shortcuts that should only fire in the file explorer." It evaluates correctly in stock VS Code (and inside Copilot Chat, where
inputFocusis set). But in Windsurf's Cascade chat input, neither key is set, so thewhenclause matches and pressingztriggers the chord-prefix wait state:The user cannot type the letter
zin Cascade chat at all — they have to paste it from elsewhere. Other letters work because vscode-neovim does not register single-letter normal-mode bindings outside of editor focus.This is one example. The same root cause silently breaks any other extension using
!inputFocusfor similar exclusion logic.Steps to reproduce
z.zis typed.(Z) was pressed. Waiting for second key of chord...— no character is inserted.ztypes normally.Evidence — context keys are not toggled
Searching the compiled Cascade extension (
extensions/windsurf/dist/extension.js):chatInputHasFocus,inChatInput,chatInputPart, etc. exist (inherited from VS Code's stock chat strings).setContextcall relates to chat:EXTENSION_CONTEXT_KEYS.CAN_TRIGGER_TERMINAL_COMMAND_ACTION. No setContext for any focus context key.A user-level
keybindings.jsonentry that tries to negate the chords with"when": "chatInputHasFocus || inChatInput"does not apply — confirming neither standard nor inherited context keys are toggled when Cascade input is focused. The only effective workaround is unconditional negation, which sacrifices the chord behaviour everywhere.Suggested fix
When the Cascade chat input gains/loses keyboard focus, set the standard VS Code context keys:
inputFocus(true while focused)editorTextFocus(true while focused, if Cascade input is a Monaco editor — typical for chat inputs)Setting
inputFocusalone would already fix!inputFocus-scoped bindings (the most common pattern). Setting both matches what stock VS Code's chat extension and Copilot Chat do, and ensures parity for any extension that relies on either key.If, for design reasons, Cascade intentionally wants extensions to be able to differentiate "in chat" from "in code editor", also expose a documented Windsurf-specific key like
windsurfCascade.inputFocusedand document it. That gives extensions a clean way to opt in/out.Why this matters beyond vscode-neovim
The
!inputFocus/!editorTextFocusexclusion pattern is canonical in the VS Code extension ecosystem — used by tree-view extensions, multi-cursor extensions, refactoring extensions, and many others. Each one is currently silently broken inside Cascade chat in ways that may never be reported (because most users won't realise the activation came from "their" extension). Thezkey issue is just the most visible symptom because it produces an obvious chord-wait status bar message.Cross-filed
Environment
08b5de9bae1728a5ad46386c9b8903192a125c51, 2026-04-22)