Skip to content

Live pane terminal UX: selection, copy/paste are hard to use #131

Open

Description

@malys

Version: v8.0.2

The live pane is the only way to interact with Claude Code on the command line (answer interactive prompts, etc.). But the web terminal gives a poor UX: selecting text, copying and pasting are unreliable and awkward. For comparison, the Proxmox web console (also xterm.js) is much more comfortable to use.

Observations in the code (v8.0.2)

public/index.html:19575 creates the terminal with minimal options, and only FitAddon is loaded (public/vendor contains only xterm.js and xterm-addon-fit.js):

new Terminal({ fontSize, fontFamily, theme, cursorBlink: true, scrollback: 10000, allowProposedApi: true })
  • Copy on select is forced (mouseup handler, line ~19622): every selection overwrites the clipboard. There is no explicit copy (Ctrl+Shift+C / context menu) and no way to turn it off.
  • Right-click clears the selection before the context menu opens (as the code comment says), so the native browser Copy / Paste menu does not work.
  • Mouse tracking: the Claude TUI (inside tmux) enables mouse reporting, so a drag is sent to the application instead of selecting text. The user must know to hold Shift (or Alt on macOS). macOptionClickForcesSelection and rightClickSelectsWord are not set.
  • No keyboard shortcuts for copy/paste: no attachCustomKeyEventHandler for Ctrl+Shift+C / Ctrl+Shift+V.
  • Missing addons: no web-links (clickable URLs), no search, no clipboard addon, no unicode11 (wide characters and emoji in the Claude TUI can misalign), no WebGL/canvas renderer.

Suggestions

  • Add Ctrl+Shift+C / Ctrl+Shift+V (and Cmd+C / Cmd+V on macOS) through attachCustomKeyEventHandler.
  • Make copy-on-select optional (a setting, default off or on), and add a context menu with Copy / Paste.
  • Set macOptionClickForcesSelection: true, and show a hint that Shift+drag selects text when the application uses the mouse.
  • Load @xterm/addon-web-links, @xterm/addon-clipboard, @xterm/addon-unicode11, @xterm/addon-search and @xterm/addon-webgl.

Expected: selection and copy/paste work as in a native terminal or in the Proxmox console.
Actual: selection is unreliable, copy/paste is awkward, and the live pane is hard to use for real work.

Activity

  1. malys commented on Nov 8, 2026

    @malys
    Author

    Mobile experience

    The mobile experience of the live pane is poor too.

    Reference: Proxmox shell consoles use pve-xtermjs (xterm.js) in the browser, with termproxy (Rust) relaying to a real PTY on the server. The VM consoles use noVNC, which has a side toolbar (Ctrl, Alt, Tab, Esc, Ctrl+Alt+Del, clipboard, and a keyboard button on mobile). So this is the same library as the live pane. The difference is the setup: a direct PTY with no tmux layer, plus add-ons and an extra-keys toolbar.

    Proposals

    1. Extra keys bar above the phone keyboard, like Termux: Esc, Tab, Shift+Tab, Ctrl, Alt, the 4 arrows, /, |, Enter. This would extend the on-screen Ctrl from Feature request: Add mobile terminal extra keys for Gboard users #117. The Claude TUI needs Esc, the arrows and Shift+Tab all the time.
    2. Separate typing field: a native text field under the terminal, with a Send button. Typing directly into xterm on a phone is unreliable: autocorrect, predictive text and IME composition break it.
    3. Touch scrolling: inside tmux, a swipe is sent as mouse events instead of scrolling. Turn a vertical swipe into scrolling through the scrollback, or into tmux copy mode.
    4. Selection by long press: a long press selects a word, with drag handles and a Copy / Paste menu. The native browser selection does not work on the xterm canvas.
    5. Pinch to zoom the font: change fontSize, then refit and resize the tmux window. Add a button to reset the size.
    6. Small screens: show the live pane full screen, and keep the terminal at 80 columns or more with horizontal scrolling. This stops the Claude TUI layout from breaking on very narrow widths.
    7. Chat-first on mobile: show Claude's answer as text in the chat, and use the terminal only to answer prompts (see Live pane and web UI out of sync: task shown finished in live pane, web UI stays waiting #130).
    8. Quick prompt buttons: when input_needed fires, show the TUI options (1/2/3, Yes/No) as large buttons in the web UI. Most interactions then no longer need the terminal.

    Proposals 7 and 8 would help the most, because on mobile they avoid the terminal for most interactions.

  2. Lexus2016 commented on Nov 8, 2026

    @Lexus2016
    Owner

    Confirmed, and the cause is exactly where you put it. In v8.0.2 public/vendor holds only xterm.js, xterm-addon-fit.js and xterm.css, the terminal is built at public/index.html:19575 with no rightClickSelectsWord, no macOptionClickForcesSelection and no custom key handler, and the mouseup at :19622 writes every selection straight to the clipboard — so a right-click that clears the selection kills both the native copy and the native menu.

    Two additions to your list:

    • allowProposedApi: true is already set in the constructor, so @xterm/addon-unicode11 can be loaded and activated (term.unicode.activeVersion = '11') without changing that line. Wide characters and emoji in the TUI are the clearest symptom you reported, and this is the smallest change that fixes it.
    • The clipboard fallback you would need already exists: copyText() at :7309 writes through navigator.clipboard with a fallback for plain http, so a context-menu Copy can reuse it instead of a second implementation.

    What I will do, smallest first: attachCustomKeyEventHandler for Ctrl+Shift+C / Ctrl+Shift+V (and Cmd+C / Cmd+V on macOS), a context menu with Copy, Paste and Select all that does not clear the selection first, macOptionClickForcesSelection: true plus a one-line hint that Shift+drag selects when the application uses the mouse, then copy-on-select made a setting that defaults to off, then the addons (web-links, unicode11, search) — clipboard and webgl last, since they change rendering and need a wider check on the embedded Electron build.

    The Proxmox comparison is the right bar: it is xterm.js too, so nothing here needs a different terminal library.

  3. Lexus2016 commented on Nov 8, 2026

    @Lexus2016
    Owner

    First slice is on main (PR #133, squash e28cb11f), in the order you wrote in your
    comment — smallest first, addons deferred.

    What landed:

    • Ctrl+Shift+C / Ctrl+Shift+V on Linux and Windows, Cmd+C / Cmd+V on macOS, through
      attachCustomKeyEventHandler. The handler returns false for a chord it handled, which
      is what keeps it out of the TUI — otherwise Ctrl+Shift+C would copy and send ^C to
      the running agent. Plain Ctrl+C is untouched, so SIGINT still reaches it.
    • A pane context menu on right-click: Copy / Paste / Select all / Copy on select.
      Copy is disabled while nothing is selected, and a right-button release is now skipped
      before the copy branch, so the selection you just made is what Copy acts on instead of
      being copied and dropped. Paste reuses the existing bracketed-paste path
      (pasteToTerminal), which never auto-submits; it took an optional { silent } so a
      paste from the keyboard does not toast.
    • Copy-on-select is a setting now, off by default, toggled from that menu and
      remembered in localStorage. It was the only way to copy before and fired on every
      mouseup, so an accidental drag replaced the clipboard.
    • macOptionClickForcesSelection: true, rightClickSelectsWord: false, and a title on
      the pane that says Shift+drag selects when the app reports mouse events.

    Verified with a test that runs the real code: the helper block and _createTerminal are cut
    out of public/index.html and evaluated with a fake xterm, element and clipboard — the
    chord map per platform, Ctrl+C passthrough, the copy-on-select default and persistence, the
    menu model, and the mouseup/contextmenu wiring. CI green on Node 20 and 24.

    Still open in this issue:

    1. Addons: web-links (clickable URLs in the pane), unicode11 (wide characters and
      emoji alignment — allowProposedApi: true is already set, so this is the smallest
      rendering change), search, then clipboard and webgl last since they change
      rendering and need a wider check on the embedded Electron build. They need vendored
      files under public/vendor, so they get their own PR.
    2. The mobile proposals in the second comment (typing field under the pane, touch
      scrolling, long-press selection, pinch-to-zoom, 80-column floor, prompt buttons on
      input_needed). The extra-keys bar from Feature request: Add mobile terminal extra keys for Gboard users #117 is already there; the rest is a separate
      piece of work and 7/8 interact with Live pane and web UI out of sync: task shown finished in live pane, web UI stays waiting #130.
  4. Lexus2016 commented on Nov 9, 2026

    @Lexus2016
    Owner

    Second slice is on main (PR #134, squash 2d95fe4), so everything in the first comment now exists except the two rendering-changing addons.

    What landed this time:

    • Unicode 11 width tables (@xterm/addon-unicode11 0.7.0). This is the fix for the
      misaligned TUI: wide characters and emoji were being drawn one column wide, so every
      line after one of them on the same row shifted. Loading the addon alone does nothing —
      it registers its tables and waits — so the pane also activates it
      (term.unicode.activeVersion = '11'). Checked in a real Chromium: versions is
      ['6', '11'] and the active one is 11.
    • Clickable URLs (@xterm/addon-web-links 0.10.0). A URL in the output opens in the
      user's browser, not inside the app window, and only http(s) can leave at all — the
      handler refuses file:// and javascript: so a future link provider cannot widen that.
      Checked in Chromium: clicking https://example.com/x in the pane calls the handler with
      exactly that URL.
    • Search (@xterm/addon-search 0.14.0) with its own bar. Ctrl+Shift+F — or Cmd+F
      on macOS — and a Find… item in the pane's context menu open a row above the
      terminal: typing searches incrementally, Enter / Shift+Enter step forward and back,
      Esc closes it, clears the highlights and gives the keyboard back to the pane. The
      count reads 3 of 12, 1000 of 1000+ at the highlight cap, No matches otherwise.
      The bar belongs to the pane it was opened on — a tab switch closes it, and results from
      a pane that is not on screen cannot write into it. Plain Ctrl+F is untouched: it stays
      readline's forward-char for whatever runs inside.

    All three files are vendored into public/vendor from the same 5.3.0 release as
    xterm.js itself (it is byte-identical to xterm@5.3.0), so the addons are the matching
    builds rather than a newer API on an older core. Each one is optional: a checkout that
    lost a vendor file keeps the pane it has instead of failing before xterm.open().

    Verified locally on npm test (Node 22.22.2) plus a real Chromium run of the pane's own
    code, and CI is green on Node 20 and 24 (test (20), test (24), GitGuardian).

    Still open here:

    1. clipboard and webgl — the two that change rendering. They need a wider check on
      the embedded Electron build (webgl falls back silently but changes antialiasing, and a
      clipboard addon would take over the copy path this slice just made explicit), so they
      stay last, on purpose.
    2. The mobile proposals from the second comment: typing field under the pane, touch
      scrolling, long-press selection, pinch-to-zoom, an 80-column floor, and prompt buttons
      on input_needed. Proposals 7 and 8 still look like the ones worth doing first — they
      keep a phone out of the terminal for most interactions — and 7/8 interact with Live pane and web UI out of sync: task shown finished in live pane, web UI stays waiting #130.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions