fix(terminal): gate Shift+Enter CSI-u on active protocol (#8427)

This commit is contained in:
Neil 2026-07-12 15:09:20 -07:00 committed by GitHub
parent b93ec86fef
commit 2306f82113
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 26 deletions

View File

@ -66,12 +66,12 @@ describe('resolveTerminalShortcutAction', () => {
).toEqual({ type: 'focusPane', direction: 'next' })
})
it('keeps shift-enter and delete helpers explicit', () => {
it('keeps inactive shift-enter and delete helpers explicit', () => {
expect(
resolveTerminalShortcutAction(event({ key: 'Enter', code: 'Enter', shiftKey: true }), true)
).toEqual({
type: 'sendInput',
data: '\x1b[13;2u'
data: '\x1b\r'
})
expect(resolveTerminalShortcutAction(event({ key: 'Backspace', ctrlKey: true }), true)).toEqual(
{ type: 'sendInput', data: '\x17' }
@ -164,9 +164,9 @@ describe('resolveTerminalShortcutAction', () => {
expect(getWindowsShiftEnterEncoding).not.toHaveBeenCalled()
})
it('always uses CSI-u Shift+Enter off Windows regardless of Windows encoding', () => {
it('uses CSI-u Shift+Enter off Windows only while Kitty keyboard is active', () => {
for (const encoding of [() => 'csi-u' as const, () => 'alt-enter' as const, undefined]) {
expect(
const resolve = (kittyActive: boolean) =>
resolveTerminalShortcutAction(
event({ key: 'Enter', code: 'Enter', shiftKey: true }),
false,
@ -175,11 +175,12 @@ describe('resolveTerminalShortcutAction', () => {
false,
undefined,
undefined,
undefined,
() => kittyActive,
undefined,
encoding
)
).toEqual({ type: 'sendInput', data: '\x1b[13;2u' })
expect(resolve(true)).toEqual({ type: 'sendInput', data: '\x1b[13;2u' })
expect(resolve(false)).toEqual({ type: 'sendInput', data: '\x1b\r' })
}
})

View File

@ -158,7 +158,11 @@ export function resolveTerminalShortcutAction(
: isWindows
? 'alt-enter'
: 'csi-u'
return { type: 'sendInput', data: encoding === 'csi-u' ? '\x1b[13;2u' : '\x1b\r' }
// Why: CSI-u is application input, not a universal terminal sequence. Off
// Windows, only send it while the pane's application has KKP active.
const canSendCsiU =
encoding === 'csi-u' && (useLocalWindowsCapability || isKittyKeyboardActivePane?.() === true)
return { type: 'sendInput', data: canSendCsiU ? '\x1b[13;2u' : '\x1b\r' }
}
if (

View File

@ -518,19 +518,26 @@ test.describe('Terminal Shortcuts', () => {
await waitForPaneCount(orcaPage, 1, 30_000)
})
test('Shift+Enter writes the platform newline chord for terminal TUIs', async ({
orcaPage,
electronApp
}) => {
test('Shift+Enter follows the pane Kitty keyboard state', async ({ orcaPage, electronApp }) => {
await installMainProcessPtyWriteSpy(electronApp)
await waitForActivePanePtyId(orcaPage)
const ptyId = await waitForActivePanePtyId(orcaPage)
await pressAndExpectWrite(
orcaPage,
electronApp,
'Shift+Enter',
process.platform === 'win32' ? '\x1b\r' : '\x1b[13;2u'
)
await pressAndExpectWrite(orcaPage, electronApp, 'Shift+Enter', '\x1b\r')
if (process.platform === 'win32') {
return
}
// Why: exercise the production PTY-output tracker, not xterm's renderer-
// local flag state, so the test covers the bytes the shortcut policy sees.
await execInTerminal(orcaPage, ptyId, "printf '\\033[>1u'")
await expect.poll(() => getKittyKeyboardFlags(orcaPage)).toBe(1)
await pressAndExpectWrite(orcaPage, electronApp, 'Shift+Enter', '\x1b[13;2u')
// The shell is only standing in for a KKP-aware TUI and does not consume
// the CSI-u input above, so cancel that synthetic line before its reset.
await execInTerminal(orcaPage, ptyId, "\x03printf '\\033[<u'")
await expect.poll(() => getKittyKeyboardFlags(orcaPage)).toBe(0)
await pressAndExpectWrite(orcaPage, electronApp, 'Shift+Enter', '\x1b\r')
})
test('Droid gets CSI-u Shift+Enter on Windows without changing Antigravity', async ({
@ -769,14 +776,8 @@ test.describe('Terminal Shortcuts', () => {
// Ctrl+Backspace → \x17 (unix-word-rubout).
await pressAndExpectWrite(orcaPage, electronApp, 'Control+Backspace', '\x17')
// Shift+Enter stays distinct; Windows keeps Esc+CR unless the active agent
// explicitly requires CSI-u (currently Droid, #7620).
await pressAndExpectWrite(
orcaPage,
electronApp,
'Shift+Enter',
process.platform === 'win32' ? '\x1b\r' : '\x1b[13;2u'
)
// The shell has not enabled KKP, so Shift+Enter must not leak CSI-u text.
await pressAndExpectWrite(orcaPage, electronApp, 'Shift+Enter', '\x1b\r')
// --- send-input chords (macOS-only) ---