BUG: Cmd/Ctrl+A does not select all in the chat input #115

Description

@jeonghun-jj-lee

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

ShortcutNative actionStatusNotes
Cmd+VPasteWorksPatch #11 — explicit handleKeyDown + bridge
Cmd+UAttach fileWorksExplicit handleKeyDown
Cmd+ASelect allBrokenNative selectAll suppressed
Cmd+CCopyBrokenglobal-clipboard.ts bridge either doesn't fire or silently fails
Cmd+XCutBrokenSame mechanism as Cmd+C
Cmd+ZUndoBrokenNative undo suppressed
Cmd+Shift+Z / Cmd+YRedoBroken (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

ShortcutJS implementation
Cmd+Aevent.preventDefault() + window.getSelection().selectAllChildren(editableRoot) where editableRoot is the closest [contenteditable] ancestor (for input/textarea: .select())
Cmd+Cevent.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+XSame as Cmd+C + deleteFromDocument() on the selection
Cmd+Zevent.preventDefault() + document.execCommand('undo') on the contenteditable (browser-managed undo stack)
Cmd+Shift+Z / Cmd+Yevent.preventDefault() + document.execCommand('redo')

File changes

  • packages/app/src/utils/global-clipboard.ts — extend installGlobalPasteFallback to handle a, z, y in addition to existing v, 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.json keybinding 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

#ApproachVerdict
CGlobal keydown fallback (extends patch #11)Selected — proven pattern, single install point, no extension-side changes
APer-element explicit handlers in handleKeyDownRejected — scatters the fix across components; doesn't cover non-prompt editables (API key fields, etc.)
BVS Code extension-side command forwarding via package.json keybindingsRejected — 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 test passes, 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 why writeClipboardViaBridge silently 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


Diagnostics (original filing)

intake: ready
suggested_path: C
diagnostics: inline
upstream: anomalyco/opencode#8504 (open); #25637 closed not-planned (same symptom, TUI input)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
     blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    
    Skip to content

    BUG: Cmd/Ctrl+A does not select all in the chat input #115

    Description

    @jeonghun-jj-lee

    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

    ShortcutNative actionStatusNotes
    Cmd+VPasteWorksPatch #11 — explicit handleKeyDown + bridge
    Cmd+UAttach fileWorksExplicit handleKeyDown
    Cmd+ASelect allBrokenNative selectAll suppressed
    Cmd+CCopyBrokenglobal-clipboard.ts bridge either doesn't fire or silently fails
    Cmd+XCutBrokenSame mechanism as Cmd+C
    Cmd+ZUndoBrokenNative undo suppressed
    Cmd+Shift+Z / Cmd+YRedoBroken (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

    ShortcutJS implementation
    Cmd+Aevent.preventDefault() + window.getSelection().selectAllChildren(editableRoot) where editableRoot is the closest [contenteditable] ancestor (for input/textarea: .select())
    Cmd+Cevent.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+XSame as Cmd+C + deleteFromDocument() on the selection
    Cmd+Zevent.preventDefault() + document.execCommand('undo') on the contenteditable (browser-managed undo stack)
    Cmd+Shift+Z / Cmd+Yevent.preventDefault() + document.execCommand('redo')

    File changes

    • packages/app/src/utils/global-clipboard.ts — extend installGlobalPasteFallback to handle a, z, y in addition to existing v, 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.json keybinding 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

    #ApproachVerdict
    CGlobal keydown fallback (extends patch #11)Selected — proven pattern, single install point, no extension-side changes
    APer-element explicit handlers in handleKeyDownRejected — scatters the fix across components; doesn't cover non-prompt editables (API key fields, etc.)
    BVS Code extension-side command forwarding via package.json keybindingsRejected — 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 test passes, 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 why writeClipboardViaBridge silently 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


    Diagnostics (original filing)

    intake: ready
    suggested_path: C
    diagnostics: inline
    upstream: anomalyco/opencode#8504 (open); #25637 closed not-planned (same symptom, TUI input)

    Activity

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
      Skip to content

      BUG: Cmd/Ctrl+A does not select all in the chat input #115

      Description

      @jeonghun-jj-lee

      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

      ShortcutNative actionStatusNotes
      Cmd+VPasteWorksPatch #11 — explicit handleKeyDown + bridge
      Cmd+UAttach fileWorksExplicit handleKeyDown
      Cmd+ASelect allBrokenNative selectAll suppressed
      Cmd+CCopyBrokenglobal-clipboard.ts bridge either doesn't fire or silently fails
      Cmd+XCutBrokenSame mechanism as Cmd+C
      Cmd+ZUndoBrokenNative undo suppressed
      Cmd+Shift+Z / Cmd+YRedoBroken (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

      ShortcutJS implementation
      Cmd+Aevent.preventDefault() + window.getSelection().selectAllChildren(editableRoot) where editableRoot is the closest [contenteditable] ancestor (for input/textarea: .select())
      Cmd+Cevent.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+XSame as Cmd+C + deleteFromDocument() on the selection
      Cmd+Zevent.preventDefault() + document.execCommand('undo') on the contenteditable (browser-managed undo stack)
      Cmd+Shift+Z / Cmd+Yevent.preventDefault() + document.execCommand('redo')

      File changes

      • packages/app/src/utils/global-clipboard.ts — extend installGlobalPasteFallback to handle a, z, y in addition to existing v, 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.json keybinding 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

      #ApproachVerdict
      CGlobal keydown fallback (extends patch #11)Selected — proven pattern, single install point, no extension-side changes
      APer-element explicit handlers in handleKeyDownRejected — scatters the fix across components; doesn't cover non-prompt editables (API key fields, etc.)
      BVS Code extension-side command forwarding via package.json keybindingsRejected — 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 test passes, 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 why writeClipboardViaBridge silently 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


      Diagnostics (original filing)

      intake: ready
      suggested_path: C
      diagnostics: inline
      upstream: anomalyco/opencode#8504 (open); #25637 closed not-planned (same symptom, TUI input)

      Activity

      Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

      Metadata

      Metadata

      Labels

      bugSomething isn't working

      Type

      No type

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
        Skip to content

        BUG: Cmd/Ctrl+A does not select all in the chat input #115

        Description

        @jeonghun-jj-lee

        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

        ShortcutNative actionStatusNotes
        Cmd+VPasteWorksPatch #11 — explicit handleKeyDown + bridge
        Cmd+UAttach fileWorksExplicit handleKeyDown
        Cmd+ASelect allBrokenNative selectAll suppressed
        Cmd+CCopyBrokenglobal-clipboard.ts bridge either doesn't fire or silently fails
        Cmd+XCutBrokenSame mechanism as Cmd+C
        Cmd+ZUndoBrokenNative undo suppressed
        Cmd+Shift+Z / Cmd+YRedoBroken (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

        ShortcutJS implementation
        Cmd+Aevent.preventDefault() + window.getSelection().selectAllChildren(editableRoot) where editableRoot is the closest [contenteditable] ancestor (for input/textarea: .select())
        Cmd+Cevent.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+XSame as Cmd+C + deleteFromDocument() on the selection
        Cmd+Zevent.preventDefault() + document.execCommand('undo') on the contenteditable (browser-managed undo stack)
        Cmd+Shift+Z / Cmd+Yevent.preventDefault() + document.execCommand('redo')

        File changes

        • packages/app/src/utils/global-clipboard.ts — extend installGlobalPasteFallback to handle a, z, y in addition to existing v, 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.json keybinding 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

        #ApproachVerdict
        CGlobal keydown fallback (extends patch #11)Selected — proven pattern, single install point, no extension-side changes
        APer-element explicit handlers in handleKeyDownRejected — scatters the fix across components; doesn't cover non-prompt editables (API key fields, etc.)
        BVS Code extension-side command forwarding via package.json keybindingsRejected — 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 test passes, 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 why writeClipboardViaBridge silently 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


        Diagnostics (original filing)

        intake: ready
        suggested_path: C
        diagnostics: inline
        upstream: anomalyco/opencode#8504 (open); #25637 closed not-planned (same symptom, TUI input)

        Activity

        Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

        Metadata

        Metadata

        Labels

        bugSomething isn't working

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
          Skip to content

          BUG: Cmd/Ctrl+A does not select all in the chat input #115

          Description

          @jeonghun-jj-lee

          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

          ShortcutNative actionStatusNotes
          Cmd+VPasteWorksPatch #11 — explicit handleKeyDown + bridge
          Cmd+UAttach fileWorksExplicit handleKeyDown
          Cmd+ASelect allBrokenNative selectAll suppressed
          Cmd+CCopyBrokenglobal-clipboard.ts bridge either doesn't fire or silently fails
          Cmd+XCutBrokenSame mechanism as Cmd+C
          Cmd+ZUndoBrokenNative undo suppressed
          Cmd+Shift+Z / Cmd+YRedoBroken (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

          ShortcutJS implementation
          Cmd+Aevent.preventDefault() + window.getSelection().selectAllChildren(editableRoot) where editableRoot is the closest [contenteditable] ancestor (for input/textarea: .select())
          Cmd+Cevent.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+XSame as Cmd+C + deleteFromDocument() on the selection
          Cmd+Zevent.preventDefault() + document.execCommand('undo') on the contenteditable (browser-managed undo stack)
          Cmd+Shift+Z / Cmd+Yevent.preventDefault() + document.execCommand('redo')

          File changes

          • packages/app/src/utils/global-clipboard.ts — extend installGlobalPasteFallback to handle a, z, y in addition to existing v, 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.json keybinding 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

          #ApproachVerdict
          CGlobal keydown fallback (extends patch #11)Selected — proven pattern, single install point, no extension-side changes
          APer-element explicit handlers in handleKeyDownRejected — scatters the fix across components; doesn't cover non-prompt editables (API key fields, etc.)
          BVS Code extension-side command forwarding via package.json keybindingsRejected — 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 test passes, 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 why writeClipboardViaBridge silently 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


          Diagnostics (original filing)

          intake: ready
          suggested_path: C
          diagnostics: inline
          upstream: anomalyco/opencode#8504 (open); #25637 closed not-planned (same symptom, TUI input)

          Activity

          Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

          Metadata

          Metadata

          Labels

          bugSomething isn't working

          Type

          No type

          Projects

          No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
            Skip to content

            BUG: Cmd/Ctrl+A does not select all in the chat input #115

            Description

            @jeonghun-jj-lee

            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

            ShortcutNative actionStatusNotes
            Cmd+VPasteWorksPatch #11 — explicit handleKeyDown + bridge
            Cmd+UAttach fileWorksExplicit handleKeyDown
            Cmd+ASelect allBrokenNative selectAll suppressed
            Cmd+CCopyBrokenglobal-clipboard.ts bridge either doesn't fire or silently fails
            Cmd+XCutBrokenSame mechanism as Cmd+C
            Cmd+ZUndoBrokenNative undo suppressed
            Cmd+Shift+Z / Cmd+YRedoBroken (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

            ShortcutJS implementation
            Cmd+Aevent.preventDefault() + window.getSelection().selectAllChildren(editableRoot) where editableRoot is the closest [contenteditable] ancestor (for input/textarea: .select())
            Cmd+Cevent.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+XSame as Cmd+C + deleteFromDocument() on the selection
            Cmd+Zevent.preventDefault() + document.execCommand('undo') on the contenteditable (browser-managed undo stack)
            Cmd+Shift+Z / Cmd+Yevent.preventDefault() + document.execCommand('redo')

            File changes

            • packages/app/src/utils/global-clipboard.ts — extend installGlobalPasteFallback to handle a, z, y in addition to existing v, 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.json keybinding 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

            #ApproachVerdict
            CGlobal keydown fallback (extends patch #11)Selected — proven pattern, single install point, no extension-side changes
            APer-element explicit handlers in handleKeyDownRejected — scatters the fix across components; doesn't cover non-prompt editables (API key fields, etc.)
            BVS Code extension-side command forwarding via package.json keybindingsRejected — 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 test passes, 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 why writeClipboardViaBridge silently 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


            Diagnostics (original filing)

            intake: ready
            suggested_path: C
            diagnostics: inline
            upstream: anomalyco/opencode#8504 (open); #25637 closed not-planned (same symptom, TUI input)

            Activity

            Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

            Metadata

            Metadata

            Labels

            bugSomething isn't working

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              BUG: Cmd/Ctrl+A does not select all in the chat input #115

              Description

              @jeonghun-jj-lee

              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

              ShortcutNative actionStatusNotes
              Cmd+VPasteWorksPatch #11 — explicit handleKeyDown + bridge
              Cmd+UAttach fileWorksExplicit handleKeyDown
              Cmd+ASelect allBrokenNative selectAll suppressed
              Cmd+CCopyBrokenglobal-clipboard.ts bridge either doesn't fire or silently fails
              Cmd+XCutBrokenSame mechanism as Cmd+C
              Cmd+ZUndoBrokenNative undo suppressed
              Cmd+Shift+Z / Cmd+YRedoBroken (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

              ShortcutJS implementation
              Cmd+Aevent.preventDefault() + window.getSelection().selectAllChildren(editableRoot) where editableRoot is the closest [contenteditable] ancestor (for input/textarea: .select())
              Cmd+Cevent.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+XSame as Cmd+C + deleteFromDocument() on the selection
              Cmd+Zevent.preventDefault() + document.execCommand('undo') on the contenteditable (browser-managed undo stack)
              Cmd+Shift+Z / Cmd+Yevent.preventDefault() + document.execCommand('redo')

              File changes

              • packages/app/src/utils/global-clipboard.ts — extend installGlobalPasteFallback to handle a, z, y in addition to existing v, 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.json keybinding 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

              #ApproachVerdict
              CGlobal keydown fallback (extends patch #11)Selected — proven pattern, single install point, no extension-side changes
              APer-element explicit handlers in handleKeyDownRejected — scatters the fix across components; doesn't cover non-prompt editables (API key fields, etc.)
              BVS Code extension-side command forwarding via package.json keybindingsRejected — 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 test passes, 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 why writeClipboardViaBridge silently 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


              Diagnostics (original filing)

              intake: ready
              suggested_path: C
              diagnostics: inline
              upstream: anomalyco/opencode#8504 (open); #25637 closed not-planned (same symptom, TUI input)

              Activity

              Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

              Metadata

              Metadata

              Labels

              bugSomething isn't working

              Type

              No type

              Projects

              No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                Skip to content

                BUG: Cmd/Ctrl+A does not select all in the chat input #115

                Description

                @jeonghun-jj-lee

                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

                ShortcutNative actionStatusNotes
                Cmd+VPasteWorksPatch #11 — explicit handleKeyDown + bridge
                Cmd+UAttach fileWorksExplicit handleKeyDown
                Cmd+ASelect allBrokenNative selectAll suppressed
                Cmd+CCopyBrokenglobal-clipboard.ts bridge either doesn't fire or silently fails
                Cmd+XCutBrokenSame mechanism as Cmd+C
                Cmd+ZUndoBrokenNative undo suppressed
                Cmd+Shift+Z / Cmd+YRedoBroken (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

                ShortcutJS implementation
                Cmd+Aevent.preventDefault() + window.getSelection().selectAllChildren(editableRoot) where editableRoot is the closest [contenteditable] ancestor (for input/textarea: .select())
                Cmd+Cevent.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+XSame as Cmd+C + deleteFromDocument() on the selection
                Cmd+Zevent.preventDefault() + document.execCommand('undo') on the contenteditable (browser-managed undo stack)
                Cmd+Shift+Z / Cmd+Yevent.preventDefault() + document.execCommand('redo')

                File changes

                • packages/app/src/utils/global-clipboard.ts — extend installGlobalPasteFallback to handle a, z, y in addition to existing v, 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.json keybinding 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

                #ApproachVerdict
                CGlobal keydown fallback (extends patch #11)Selected — proven pattern, single install point, no extension-side changes
                APer-element explicit handlers in handleKeyDownRejected — scatters the fix across components; doesn't cover non-prompt editables (API key fields, etc.)
                BVS Code extension-side command forwarding via package.json keybindingsRejected — 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 test passes, 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 why writeClipboardViaBridge silently 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


                Diagnostics (original filing)

                intake: ready
                suggested_path: C
                diagnostics: inline
                upstream: anomalyco/opencode#8504 (open); #25637 closed not-planned (same symptom, TUI input)

                Activity

                Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                Metadata

                Metadata

                Labels

                bugSomething isn't working

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions