Repository navigation
BUG: Cmd/Ctrl+A does not select all in the chat input #115
Description
Important
Problem: Standard editing shortcuts (Cmd+A, Cmd+C, Cmd+X, Cmd+Z, Cmd+Y) are dead in the chat input — no select-all, no copy, no undo. Only shortcuts with explicit JS handlers (Cmd+V paste, Cmd+U attach) work.
Approach: Generalize the existing installGlobalPasteFallback (patch #11) into a document-level keydown handler that explicitly implements selectAll, copy, cut, undo, and redo in JS — the same "don't rely on native browser defaults" pattern that already fixed paste.
Scope: All standard editing Cmd+key shortcuts in any editable element inside the chat iframe. Non-editing shortcuts (Cmd+F, etc.) are out of scope.
Root cause
The chat input is a contenteditable div inside a sandboxed cross-origin iframe (sandbox="allow-scripts allow-forms allow-same-origin allow-popups allow-downloads") embedded in a VS Code WebviewPanel.
Confirmed by code audit: no app code calls preventDefault() or stopPropagation() on Cmd+A/C/Z when the target is the contenteditable. The command.tsx capture-phase handler explicitly returns early for clipboard chords on editable targets. CSS user-select is correctly set to text. The iframe sandbox and Permissions-Policy (clipboard-read; clipboard-write) are permissive.
Conclusion by elimination: the VS Code / Electron platform layer suppresses native browser actions for these shortcuts. Keydown events DO reach the iframe (typing works, Cmd+V's explicit handler works), but the associated DOM default action (selectAll, clipboard copy, undo) never fires. The Electron Edit-menu accelerators or VS Code's webview keyboard routing consumes the action at the platform level.
This is the same class of bug that affected paste (patch #11): native browser defaults cannot be relied on inside this sandboxed-iframe-in-a-webview architecture. The fix is the same pattern: explicit JS implementation, activated only in the framed context.
Affected shortcuts
| Shortcut | Native action | Status | Notes |
|---|---|---|---|
| Cmd+V | Paste | Works | Patch #11 — explicit handleKeyDown + bridge |
| Cmd+U | Attach file | Works | Explicit handleKeyDown |
| Cmd+A | Select all | Broken | Native selectAll suppressed |
| Cmd+C | Copy | Broken | global-clipboard.ts bridge either doesn't fire or silently fails |
| Cmd+X | Cut | Broken | Same mechanism as Cmd+C |
| Cmd+Z | Undo | Broken | Native undo suppressed |
| Cmd+Shift+Z / Cmd+Y | Redo | Broken (assumed) | Same mechanism as undo |
Approach: Global editing fallback (extends patch #11)
Architecture
Extend installGlobalPasteFallback (or rename it to installGlobalEditingFallback) in packages/app/src/utils/global-clipboard.ts to cover all standard editing shortcuts. Single install point in entry.tsx.
Activation guard (same as paste fallback):
window.parent !== window— only fires in the framed/VS Code context; plain browser keeps native behavior- Target is an editable element (
input,textarea, or[contenteditable]) event.metaKey || event.ctrlKey(platform-appropriate modifier)
Implementation per shortcut
| Shortcut | JS implementation |
|---|---|
| Cmd+A | event.preventDefault() + window.getSelection().selectAllChildren(editableRoot) where editableRoot is the closest [contenteditable] ancestor (for input/textarea: .select()) |
| Cmd+C | event.preventDefault() + extract selection text + writeClipboardViaBridge() (the bridge from patch #11; diagnose why global-clipboard.ts's existing Cmd+C path silently fails — likely the bridge response never arrives) |
| Cmd+X | Same as Cmd+C + deleteFromDocument() on the selection |
| Cmd+Z | event.preventDefault() + document.execCommand('undo') on the contenteditable (browser-managed undo stack) |
| Cmd+Shift+Z / Cmd+Y | event.preventDefault() + document.execCommand('redo') |
File changes
packages/app/src/utils/global-clipboard.ts— extendinstallGlobalPasteFallbackto handlea,z,yin addition to existingv,c,x(fix the existing broken Cmd+C/X path while here)packages/app/src/entry.tsx— no change needed (already installs the fallback)- Zero extension-side changes, zero
package.jsonkeybinding contributions
Diagnostic confirmation (pre-implementation)
To record the exact Electron mechanism (for AMICODE-PATCHES.md's root-cause documentation):
// Paste into the iframe's devtools console:
document.addEventListener('keydown', e => {
if (e.metaKey) console.log(`META+${e.key}`, 'defaultPrevented:', e.defaultPrevented, 'target:', e.target.tagName)
}, true)If defaultPrevented: true for Cmd+A, the event arrives already cancelled by Electron. If false, the native action is cancelled AFTER JS dispatch (accelerator fires asynchronously). Either way, the fix is the same — explicit JS implementation.
Approaches considered
| # | Approach | Verdict |
|---|---|---|
| C | Global keydown fallback (extends patch #11) | Selected — proven pattern, single install point, no extension-side changes |
| A | Per-element explicit handlers in handleKeyDown |
Rejected — scatters the fix across components; doesn't cover non-prompt editables (API key fields, etc.) |
| B | VS Code extension-side command forwarding via package.json keybindings |
Rejected — requires focus-context tracking, when clause management, couples fix to VS Code API surface |
Acceptance criteria
- Cmd+A selects all text in the chat input (contenteditable)
- Cmd+C copies mouse-selected or Cmd+A-selected text to OS clipboard
- Cmd+X cuts selected text to OS clipboard
- Cmd+Z undoes the last edit in the chat input
- Cmd+Shift+Z (or Cmd+Y) redoes
- All of the above also work in other editables inside the iframe (API key fields, search inputs)
- Plain browser tab at
http://127.0.0.1:{port}is unaffected (native behavior preserved) - Existing Cmd+V paste behavior unchanged
-
bun testpasses, typecheck green
Constraints & invariants
- The framed-context guard (
window.parent !== window) MUST remain — non-VS-Code contexts keep native behavior. global-clipboard.ts's existing Cmd+C bridge path must be FIXED, not duplicated — diagnose whywriteClipboardViaBridgesilently fails and repair it.execCommand('undo'/'redo')is deprecated but functional in all Chromium-based webviews. A proper undo manager is out of scope (separate issue if needed).
Prior art
- Patch Fix chat scroll jitter during streaming; respect reduced motion #11 (
installGlobalPasteFallback) — the exact same pattern for paste - Patch Fix chat scroll jitter during streaming; respect reduced motion #11 addendum (
installGlobalPasteFallbackgeneralized to all editables, not just the composer) — same architectural decision we're extending here - Upstream: [FEATURE]: Select all current text anomalyco/opencode#8504 (open feature request), #25637 (closed not-planned, TUI input)
Diagnostics (original filing)
- Engine pin: v1.18.10-amicode.1 (ref 81c3e71); no active run, no run-id pointer.
- Repro: type text in the chat input → press Cmd+A (macOS) → no selection.
- Upstream traces (searched, no fix exists): cmd-A or control-A does not select all in the input field anymore anomalyco/opencode#25637 — same
symptom in the TUI input, closed not-planned; #8504 — open feature request for
select-all; #12723 — open, Cmd+A in the web comment editor.
intake: ready
suggested_path: C
diagnostics: inline
upstream: anomalyco/opencode#8504 (open); #25637 closed not-planned (same symptom, TUI input)
Activity
jeonghun-jj-lee commentedon Aug 3, 2026
Same keybinding-swallow pattern, broader symptom: Cmd+C does not copy selected text in the chat panel, and other standard editing shortcuts are likewise unresponsive (reported from a live session). Expected Cmd+C to copy the selection.
Environment matches this issue: extension harmoniqs.amicode 0.2.0, macOS (Darwin 25.5.0, arm64), engine pin v1.18.10-amicode.1, no active run.
Taken together with Cmd+A, this reads less like a missing select-all handler and more like the input component intercepting standard editing keybindings wholesale — worth weighing that reframing at maturation.