Bug
Text cannot be copied from (or reliably pasted into) the in-app session terminal that attaches to zellij. The xterm.js surface is constructed with several addons but no clipboard integration is wired anywhere in the frontend, so a user has no working path to copy the agent/terminal output.
Source: reported via /bug-triage | Analyzed against: 73b166a (origin/main)
Platform observed: macOS (Darwin) — cross-platform impact flagged below
Confidence: High (mechanism traced); Medium on the exact failing interaction (see Open Questions)
Reproduction
- Open a worker/session and focus the embedded terminal (
XtermTerminal, attached via /mux to zellij attach).
- Drag the mouse to select text → no selection appears (the drag is consumed by zellij).
- Try
Cmd/Ctrl+C to copy, or Cmd/Ctrl+V to paste → nothing is copied to the system clipboard.
Root Cause
frontend/src/renderer/components/XtermTerminal.tsx loads FitAddon, Unicode11Addon, WebLinksAddon, SearchAddon, and the WebGL/Canvas renderer — but no clipboard handling:
- xterm.js does not copy-on-select and does not bind
Cmd/Ctrl+C to copy by default. The embedding app must do it (e.g. term.attachCustomKeyEventHandler + navigator.clipboard.writeText(term.getSelection()), a copy-on-select handler, or @xterm/addon-clipboard). None of these exist anywhere in frontend/src (grep for navigator.clipboard, attachCustomKeyEventHandler, addon-clipboard, getSelection → no matches). @xterm/addon-clipboard is not in frontend/package.json.
- xterm.js selection is an internal model rendered to canvas, not a DOM selection, so the OS/Electron default "Copy" never captures it.
frontend/src/main.ts also defines no custom application Menu, so there are no explicit copy/paste roles either.
- Selection itself is blocked by design: the PTY runs
zellij attach, a full-screen alt-buffer app with SGR mouse tracking enabled (see the scrollback: 0 comment, XtermTerminal.tsx:119-125). With mouse reporting on, a plain mouse drag is sent to zellij as mouse events rather than used for local selection. xterm.js only forces local selection on Shift+drag, which is undiscoverable and still copies nothing without the wiring above.
This appears to be a port gap: the component header notes it was "ported from yyork's terminal architecture," and per DESIGN.md the renderer clones the agent-orchestrator web app — the reference terminal almost certainly wires clipboard handling that wasn't carried over.
Fix
In XtermTerminal.tsx, wire clipboard handling on the constructed Terminal. Recommended minimal approach:
term.attachCustomKeyEventHandler to handle Cmd/Ctrl+C (and Cmd/Ctrl+Shift+C) → if term.hasSelection(), navigator.clipboard.writeText(term.getSelection()) and swallow the event; otherwise let it pass through to the PTY (so Ctrl+C still sends SIGINT when there's no selection).
- Handle paste →
navigator.clipboard.readText() then term.paste(text) / forward via onData, or rely on xterm's built-in paste DOM event (verify it fires under Electron on all platforms).
- Consider a copy-on-select option and/or a right-click context menu, and document that Shift+drag is required to select while zellij mouse mode is active.
Cross-platform: verify on Windows/Linux — there is no default Electron menu bar there, so any reliance on native Edit-menu accelerators will not exist; explicit key handling is required regardless.
Impact
- Users cannot copy command output, errors, URLs, or diffs out of the session terminal — a basic and frequently-needed terminal interaction in a terminal-centric app.
- No workaround beyond external screen-scraping; Shift+drag selects but still cannot be copied.
Related
- #280 — "Codex Terminal is sort of clipped. can't write, can't scroll." (same terminal subsystem)
- #294 — "Add a reload shell button" (terminal UX)
Open Questions
- Which interaction(s) specifically fail for the reporter: copy, paste, or both? (Assumed both.)
- Exact OS/build where observed (assumed macOS from the reporting environment).
Bug
Text cannot be copied from (or reliably pasted into) the in-app session terminal that attaches to zellij. The xterm.js surface is constructed with several addons but no clipboard integration is wired anywhere in the frontend, so a user has no working path to copy the agent/terminal output.
Source: reported via
/bug-triage| Analyzed against:73b166a(origin/main)Platform observed: macOS (Darwin) — cross-platform impact flagged below
Confidence: High (mechanism traced); Medium on the exact failing interaction (see Open Questions)
Reproduction
XtermTerminal, attached via/muxtozellij attach).Cmd/Ctrl+Cto copy, orCmd/Ctrl+Vto paste → nothing is copied to the system clipboard.Root Cause
frontend/src/renderer/components/XtermTerminal.tsxloadsFitAddon,Unicode11Addon,WebLinksAddon,SearchAddon, and the WebGL/Canvas renderer — but no clipboard handling:Cmd/Ctrl+Cto copy by default. The embedding app must do it (e.g.term.attachCustomKeyEventHandler+navigator.clipboard.writeText(term.getSelection()), a copy-on-select handler, or@xterm/addon-clipboard). None of these exist anywhere infrontend/src(grep fornavigator.clipboard,attachCustomKeyEventHandler,addon-clipboard,getSelection→ no matches).@xterm/addon-clipboardis not infrontend/package.json.frontend/src/main.tsalso defines no custom applicationMenu, so there are no explicit copy/paste roles either.zellij attach, a full-screen alt-buffer app with SGR mouse tracking enabled (see thescrollback: 0comment,XtermTerminal.tsx:119-125). With mouse reporting on, a plain mouse drag is sent to zellij as mouse events rather than used for local selection. xterm.js only forces local selection on Shift+drag, which is undiscoverable and still copies nothing without the wiring above.This appears to be a port gap: the component header notes it was "ported from yyork's terminal architecture," and per
DESIGN.mdthe renderer clones the agent-orchestrator web app — the reference terminal almost certainly wires clipboard handling that wasn't carried over.Fix
In
XtermTerminal.tsx, wire clipboard handling on the constructedTerminal. Recommended minimal approach:term.attachCustomKeyEventHandlerto handleCmd/Ctrl+C(andCmd/Ctrl+Shift+C) → ifterm.hasSelection(),navigator.clipboard.writeText(term.getSelection())and swallow the event; otherwise let it pass through to the PTY (soCtrl+Cstill sends SIGINT when there's no selection).navigator.clipboard.readText()thenterm.paste(text)/ forward viaonData, or rely on xterm's built-inpasteDOM event (verify it fires under Electron on all platforms).Cross-platform: verify on Windows/Linux — there is no default Electron menu bar there, so any reliance on native Edit-menu accelerators will not exist; explicit key handling is required regardless.
Impact
Related
Open Questions