From f9d37984cbdca5f1084a9706a50b014fc7629a16 Mon Sep 17 00:00:00 2001 From: Ken Date: Wed, 27 May 2026 22:36:06 +0000 Subject: [PATCH] fix: xterm.js link handling - OSC 8 hyperlinks and plain-text URL click detection - OSC 8 hyperlinks (ESC]8;;URL sequences from ls --hyperlink, gcc, grep) now open directly in new tabs instead of showing confirm() dialog - WebLinksAddon plain-text URL detection now opens on plain click instead of requiring Ctrl/Cmd+Click - Matches Ghostty/iTerm2 behavior for terminal link handling in browser-based terminal Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- muxplex/frontend/terminal.js | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/muxplex/frontend/terminal.js b/muxplex/frontend/terminal.js index c794e22..3f4abe1 100644 --- a/muxplex/frontend/terminal.js +++ b/muxplex/frontend/terminal.js @@ -287,20 +287,37 @@ function createTerminal(fontSize) { }, scrollback: mobile ? 500 : 5000, allowProposedApi: true, + // Override OSC 8 hyperlink handler — the default shows a confirm() dialog. + // This opens links directly, matching native terminal behavior (Ghostty, iTerm2). + linkHandler: { + activate: function(event, uri) { + window.open(uri, '_blank'); + }, + }, }); _fitAddon = new window.FitAddon.FitAddon(); _term.loadAddon(_fitAddon); - // Clickable URLs — Ctrl+Click (Windows/Linux) or Cmd+Click (macOS) opens in new tab. - // xterm-addon-web-links auto-detects URLs and adds hover underlines. - // Plain click is preserved for normal terminal text selection. + // --- Link handling --- + // Two link systems work together: + // + // 1. WebLinksAddon: regex-detects plain-text URLs (http://..., https://...) + // and makes them clickable. Click opens in new tab. + // + // 2. OSC 8 hyperlinks: programs emit ESC]8;;URL\atext\aESC]8;;\a to make + // arbitrary text clickable (like Ghostty, iTerm2, etc.). xterm.js has + // built-in OscLinkProvider support, but its default handler shows a + // confirm() dialog. We override with a linkHandler that opens directly. + // + // Both open on plain click. Ctrl/Cmd+Click is not required — this is a + // browser-based terminal where the link-vs-select distinction comes from + // whether the user drags (select) or clicks (link). + var WebLinksAddon = window.WebLinksAddon && window.WebLinksAddon.WebLinksAddon; if (WebLinksAddon) { _term.loadAddon(new WebLinksAddon(function(event, uri) { - if (event.ctrlKey || event.metaKey) { - window.open(uri, '_blank'); - } + window.open(uri, '_blank'); })); }