[BUG] Markdown link labels never clickable in Orca/tmux — no OSC 8 emitted for unrecognized TERM_PROGRAM, FORCE_HYPERLINK=1 ignored
Bug Description
Markdown links ([label](url)) in assistant responses render as a styled label with no OSC 8 escape emitted, so the label is not clickable. Only bare URLs (linkified as plain text by the terminal itself) remain clickable. This happens whenever the terminal is not recognized — observed with TERM_PROGRAM=Orca (Orca embedded terminal) and TERM_PROGRAM=tmux (tmux inside Orca).
Setting FORCE_HYPERLINK=1 before launching has no effect (also noted in #72998, where the variable is ignored for the opposite purpose — disabling).
Steps to Reproduce
- Run Claude Code inside a terminal whose
TERM_PROGRAMis not on the capability allowlist — e.g. Orca (TERM_PROGRAM=Orca) or any tmux session (TERM_PROGRAM=tmux,TERM=tmux-256color). - Ask the assistant to print both forms:
- markdown:
[example](https://example.com/some/long/path) - bare URL:
https://example.com/some/long/path
- Observe: the markdown label renders styled but is not clickable (no OSC 8 region, nothing on hover); the bare URL is clickable only because the terminal itself linkifies plain-text URLs.
FORCE_HYPERLINK=1 claude— behavior unchanged.
Why the terminal is not the problem
| Layer | OSC 8 support | Evidence |
|---|---|---|
| Orca terminal | ✅ renders OSC 8 | stablyai/orca#6880 (test matrix in issue body: "rendered, clickable, URL hidden") |
| tmux 3.7b | ✅ supports the hyperlinks terminal-feature | binary contains the feature and Hls=\E]8;...; passthrough needs set -as terminal-features ",*:hyperlinks" |
| Claude Code renderer | ❌ no OSC 8 emitted for markdown labels | this report |
So in the direct-Orca case the chain is known-good end to end, yet no OSC 8 arrives; in the tmux case the user can open the tmux side with one config line, but that is moot while nothing is emitted upstream.
Expected
Either of:
- honor
FORCE_HYPERLINK=1as an explicit user override of terminal capability detection (matching thesupports-hyperlinksecosystem convention), and/or - treat
TERM_PROGRAM=tmux(tmux ≥ 3.4 supports thehyperlinksfeature) andTERM_PROGRAM=Orcaas hyperlink-capable.
The TERM_PROGRAM allowlist approach can never see through tmux nesting (the outer terminal's identity is not visible inside), so an env-var override is the only mechanism that works for every setup.
Related: #79839 (file-path OSC 8 regression in assistant responses), #72998 (FORCE_HYPERLINK ignored for disabling), #13008 / #77576 (file-path hyperlink requests), stablyai/orca#6880 (terminal-capability detectability for agent TUIs).
Environment Info
- Platform: macOS 26.5.2
- Terminal: Orca (embedded terminal,
TERM_PROGRAM=Orca) and tmux 3.7b inside Orca (TERM_PROGRAM=tmux,TERM=tmux-256color) - Version: 2.1.220
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Follow-up verification: with tmux's
set -as terminal-features ",*:hyperlinks"applied, a manually printed OSC 8 sequence (printf '\e]8;;https://example.com\e\\label\e]8;;\e\\') renders as a clickable label through the full Orca → tmux chain. So the terminal path is now confirmed good end to end by direct test, not just by the references above — the only missing piece is the emission from Claude Code's assistant-message renderer.Also reproduces under herdr (a non-tmux Rust terminal multiplexer) — and pins the cause down to
$TERM, not just$TERM_PROGRAMEnvironment
kitten ssh)Key data point — same physical terminal, same SSH session type, only difference is whether herdr is in the middle:
| | outside herdr (plain SSH) | inside a herdr pane |
|---|---|---|
|
TERM|xterm-kitty|xterm-256color||
COLORTERM|truecolor|truecolor||
TERM_PROGRAM| (empty) | (empty) ||
KITTY_WINDOW_ID| (empty) | (empty) || Markdown link (
[label](url)) clickable? | ✅ yes | ❌ no — styled text only, no OSC 8, no hover state |TERM_PROGRAM/KITTY_WINDOW_IDare empty in both cases (plainsshdoesn't forward these; onlykitten sshdoes), so those can't be what's flipping the behavior here. The only variable that changes isTERMitself:xterm-kittyoutside herdr vs. the genericxterm-256colorherdr substitutes for its pane environment — mirroring exactly what tmux does withTERM=screen-256color/tmux-256color.Confirmed the terminal chain itself is not at fault: hand-crafted OSC 8 sequences sent directly via
printf(including variants with SGR styling around the label,BELterminator instead ofST, and an explicitid=parameter) all rendered correctly as clickable, hover-highlighted hyperlinks through the same herdr→SSH→Kitty chain where Claude Code's own markdown links fail.FORCE_HYPERLINK=1had no effect either, consistent with what's already reported here and in #72998.This suggests the detection logic currently treats
TERM=xterm-kittyas sufficient signal on its own (since that's the only thing that changed between the working/non-working cases above), but that signal is inherently unavailable through any multiplexer that normalizesTERMfor its own pane environment — not just tmux. Reinforces the issue's conclusion that only an honoredFORCE_HYPERLINK=1override can cover every setup, sinceTERM/TERM_PROGRAMallowlisting can't see through nesting of any kind (SSH withoutkitten ssh, tmux, herdr, or otherwise).Data point that splits this into two different bugs: on 2.1.251, inside tmux, Claude Code does emit OSC 8 — I measured it rather than inferring from clickability. The sequences are sitting in tmux's grid (tmux 3.7c, TERM inside
xterm-256color, outer terminal Alacritty 0.15.1):So for the tmux case, the label isn't clickable because of a downstream strip, not missing emission: tmux ≥ 3.4 parses and stores OSC 8 unconditionally, but only re-emits it to your terminal if the attached client negotiated the
hyperlinksterminal feature — off by default for most TERMs. Check what your client actually negotiated:Fix:
then detach and reattach — features are negotiated when the client attaches, so
source-fileor setting the option live does not upgrade an already-attached client. That reattach step is a trap: with the option set but the client attached from before,#{client_termfeatures}still lackshyperlinksand nothing changes, which looks exactly like "the option doesn't work".Layer-by-layer triage for anyone landing here with unclickable links in tmux:
tmux capture-pane -e -p | grep -c ']8;;'— nonzero means Claude Code emitted; the problem is downstream (this comment). Zero means the renderer really didn't emit (the Orca half of this issue).tmux display -p '#{client_termfeatures}'— nohyperlinksmeans tmux is the strip; fix above.Terminal-independent alternative:
wfxr/tmux-fzf-url(since wfxr/tmux-fzf-url#42) andalberti42/tmux-fzf-linksboth extract OSC 8 targets fromcapture-pane -e, giving a keyboard-driven fzf picker that catches links whose URL isn't visible text — which copy-mode search and regex-only pickers structurally can't.The Orca-direct case (unrecognized
TERM_PROGRAM, nothing in step 1,FORCE_HYPERLINK=1ignored) is a genuine renderer-side gate and none of the above helps it — that half stands.