mirror of
https://github.com/stablyai/orca.git
synced 2026-10-20 00:03:45 +00:00
fix(dashboard): key the preview by the user's terminal shortcut policy
The preview passed 11 of the 12 inputs the pane's policy takes and let the 12th default to orca-first. Under terminal-first a remapped tab.close chord is meant to yield to the shell — Ctrl+W is a word-kill there — but the preview kept claiming it as a pane close and swallowed the bytes.
This commit is contained in:
@@ -227,7 +227,8 @@ export function AgentTerminalPreview({
|
||||
macOptionAsAlt: macOptionAsAltRef.current,
|
||||
keybindings: useAppStore.getState().keybindings,
|
||||
terminalInput: terminalInputRef.current,
|
||||
kittyKeyboardActive: () => kittyKeyboardModes.flags > 0
|
||||
kittyKeyboardActive: () => kittyKeyboardModes.flags > 0,
|
||||
terminalShortcutPolicy: settingsRef.current?.terminalShortcutPolicy
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ function contextFor(
|
||||
keybindings: undefined,
|
||||
terminalInput: LOCAL_MAC,
|
||||
kittyKeyboardActive: () => overrides.kitty === true,
|
||||
terminalShortcutPolicy: 'orca-first',
|
||||
...overrides
|
||||
}
|
||||
}
|
||||
@@ -110,6 +111,34 @@ describe('resolvePreviewShortcutAction', () => {
|
||||
).toEqual({ type: 'splitActivePane', direction: 'vertical' })
|
||||
})
|
||||
|
||||
// Why: a terminal-first user remapped terminal.closePane away, so only the
|
||||
// tab.close alias still matches Ctrl+W — which the shell owns as a word-kill.
|
||||
// The pane yields it; the preview must not swallow it.
|
||||
it('follows the terminal shortcut policy for the tab.close pane-close alias', () => {
|
||||
const keybindings = {
|
||||
'terminal.closePane': ['Mod+Shift+W'],
|
||||
'tab.close': ['Ctrl+W']
|
||||
} as unknown as PreviewShortcutContext['keybindings']
|
||||
const chord = (): KeyboardEvent => keydown({ key: 'w', code: 'KeyW', ctrlKey: true })
|
||||
expect(
|
||||
resolvePreviewShortcutAction(
|
||||
chord(),
|
||||
contextFor({ clientPlatform: 'linux', terminalInput: null, keybindings })
|
||||
)
|
||||
).toEqual({ type: 'closeActivePane' })
|
||||
expect(
|
||||
resolvePreviewShortcutAction(
|
||||
chord(),
|
||||
contextFor({
|
||||
clientPlatform: 'linux',
|
||||
terminalInput: null,
|
||||
keybindings,
|
||||
terminalShortcutPolicy: 'terminal-first'
|
||||
})
|
||||
)
|
||||
).toBeNull()
|
||||
})
|
||||
|
||||
it('leaves ordinary typing to xterm', () => {
|
||||
expect(
|
||||
resolvePreviewShortcutAction(keydown({ key: 'a', code: 'KeyA' }), contextFor())
|
||||
|
||||
@@ -5,7 +5,11 @@ import {
|
||||
} from '@/components/terminal-pane/terminal-shortcut-policy'
|
||||
import { getLayoutBaseCharacterForCode } from '@/lib/keyboard-layout/layout-base-character'
|
||||
import type { DashboardCardTerminalInput } from '../../../../shared/dashboard-snapshot'
|
||||
import type { KeybindingOverrides } from '../../../../shared/keybindings'
|
||||
import {
|
||||
normalizeTerminalShortcutPolicy,
|
||||
type KeybindingOverrides,
|
||||
type TerminalShortcutPolicy
|
||||
} from '../../../../shared/keybindings'
|
||||
|
||||
export type PreviewShortcutContext = {
|
||||
clientPlatform: NodeJS.Platform
|
||||
@@ -17,6 +21,8 @@ export type PreviewShortcutContext = {
|
||||
terminalInput: DashboardCardTerminalInput | null
|
||||
/** Live kitty-protocol flags mirrored from this pty's output. */
|
||||
kittyKeyboardActive: () => boolean
|
||||
/** The user's setting; terminal-first yields the tab.close alias to the shell. */
|
||||
terminalShortcutPolicy: TerminalShortcutPolicy | null | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,6 +50,9 @@ export function resolvePreviewShortcutAction(
|
||||
getLayoutBaseCharacterForCode,
|
||||
() => context.terminalInput?.windowsShiftEnterEncoding ?? 'alt-enter',
|
||||
// Why: byte protocols follow the pty's host, which differs from the client OS on remote runtimes.
|
||||
() => hostPlatform === 'win32'
|
||||
() => hostPlatform === 'win32',
|
||||
// Why: without it a terminal-first user's remapped tab.close chord — Ctrl+W
|
||||
// is a shell word-kill — reaches the shell in the pane but is swallowed here.
|
||||
normalizeTerminalShortcutPolicy(context.terminalShortcutPolicy)
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user