https://gitlab.synchro.net/main/sbbs/-/work_items/872#note_10652
The OSC 8 spec itself still defines no detection method, but SyncTERM/CTerm can now be asked directly. 6fed22aa9d (opera-49-felt, 2026-03-17) added OSC 8 support to CTerm along with a capability query:
- Send `CSI = 6 n`
- CTerm replies `CSI = 6 ; pA n`, where `pA` is 1 if OSC 8 hyperlinks are available and 0 if not (`src/conio/cterm.adoc`, "State/Mode Request/Report (`CTSMRR`)"; implemented in `src/conio/cterm_cterm.c`).
That makes the original goal possible: show a short link label (e.g. "[click here]") to terminals that support OSC 8, and the full URL to all others, so a non-supporting terminal never silently eats the URL.
Proposed design:
1. **Detection.** Add `"\x1b[=6n"` to the terminal auto-detection probe in `answer.cpp`, before the first cursor position request, so the reply arrives before the `R` that ends the read loop. Parse `[=6;1n` in the same response loop that already handles the CTerm version and audio state replies, and set a new per-session flag (e.g. `term->hyperlinks`, next to `audio_apc`). Terminals that don't recognize `CSI = Ps n` ignore it.
2. **Output helper.** One function (e.g. `term->hyperlink(uri, text)`) that emits `ESC ] 8 ; ; uri ESC \ text ESC ] 8 ; ; ESC \` when the flag is set, and the bare URI otherwise. CTerm only accepts `http`, `https`, `ftp`, and `ftps` URIs and silently ignores other schemes, which would leave the label visible with nothing to click, so `mailto:`, `
telnet://`, etc. should always fall back to the plain URI.
3. **Exposure.** A JS method (e.g. `console.hyperlink(uri, text)`) and an @-code for menu/display files (e.g. `@LINK:uri|text@`), both with the same fallback.
Column tracking should already be safe: the Terminal class tracks outgoing DCS/OSC/PM/APC control strings, so the hidden URI shouldn't advance the cursor column or disturb word-wrap. Needs one test with a long URI.
Limitation: only CTerm answers `CSI = 6 n`. xterm-family terminals that support OSC 8 (Windows Terminal, kitty, iTerm2, GNOME Terminal, etc.) won't reply, so they'd get the full URL. That's the safe direction to err. A per-user "force hyperlinks on" setting could cover them later, rather than guessing from the terminal type.
*Authored by Claude (Claude Code), on behalf of @rswindell*
--- SBBSecho 3.38-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)