From 4f7693322e181137049b7af9ff36387934d81930 Mon Sep 17 00:00:00 2001 From: George Ng Date: Mon, 20 Jul 2026 17:34:24 -0700 Subject: [PATCH 01/15] Add standard ctrl/cmd + C or + x commands for vscode shell --- ts/packages/chat-ui/src/contextMenu.ts | 74 ++++++++ ts/packages/chat-ui/src/index.ts | 6 +- ts/packages/chat-ui/test/contextMenu.spec.ts | 175 +++++++++++++++++++ ts/packages/vscode-shell/src/webview/main.ts | 13 ++ 4 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 ts/packages/chat-ui/test/contextMenu.spec.ts diff --git a/ts/packages/chat-ui/src/contextMenu.ts b/ts/packages/chat-ui/src/contextMenu.ts index 8bd5c3fcf8..1452fe2054 100644 --- a/ts/packages/chat-ui/src/contextMenu.ts +++ b/ts/packages/chat-ui/src/contextMenu.ts @@ -277,3 +277,77 @@ function selectAll(target: HTMLElement) { sel?.removeAllRanges(); sel?.addRange(range); } + +/** + * Copy or cut the active selection for a Ctrl/Cmd+C or Ctrl/Cmd+X + * keyboard shortcut, using the same clipboard path as the right-click + * menu (getSelection + navigator.clipboard, with an execCommand + * fallback). + * + * VS Code webviews don't run the native clipboard action on the DOM + * selection for these keys, so only the JS path works - that is why the + * right-click menu copies but the keyboard doesn't. A host can call this + * from a keydown listener to restore keyboard copy/cut over the chat + * history and the message input. The Electron shell gets these natively + * and does not need it. + * + * Returns true when it acted on a non-empty selection, so the caller can + * call preventDefault(). + */ +export function handleClipboardShortcut(e: KeyboardEvent): boolean { + if ( + e.defaultPrevented || + e.altKey || + e.shiftKey || + !(e.ctrlKey || e.metaKey) + ) { + return false; + } + const key = e.key.toLowerCase(); + const isCopy = key === "c"; + const isCut = key === "x"; + if (!isCopy && !isCut) { + return false; + } + + // Native /