Repository navigation
Description
Bug Description
When a hyperlink wraps across multiple terminal lines, Cmd/Ctrl+Click only selects the portion on the clicked line instead of the full URL. This happens because the OSC 8 hyperlink escape sequences emitted by the renderer are missing the id parameter, so the terminal treats the link segments on each row as separate hyperlinks rather than one continuous link.
Video Demonstration
opencode-issues.mov
Root Cause
In packages/core/src/zig/renderer.zig at line 670, the OSC 8 open sequence does not include an id parameter:
// Current (line 670):
writer.print("\x1b]8;;{s}\x1b\\", .{url_bytes}) catch {};Per the OSC 8 hyperlink spec, when a hyperlink is split across multiple rows (e.g., link text ends at end of row N, padding spaces close it, then it reopens on row N+1), the terminal needs the id parameter to recognize that both segments belong to the same logical hyperlink.
Proposed Fix
Add the link ID to the OSC 8 open sequence:
// Fixed:
writer.print("\x1b]8;id={d};{s}\x1b\\", .{currentLinkId, url_bytes}) catch {};currentLinkId is already tracked in the renderer's state and is the correct identifier to use here.
Rendering Flow (for context)
- JS layer:
textBufferSetStyledText()receives chunks with optionallink: { url }property - Link encoding:
linkAlloc()allocates URL in ZigLinkPool, returns numeric ID; ID is packed into the upper 24 bits ofattributesu32 - Style registration:
setStyledText()intext-buffer.zigcallsregisterStyle()with full attributes (including link_id bits) - Word wrapping:
text-buffer-view.zigcalculateVirtualLinesGeneric()— wrapping is link-unaware, splits purely on geometry - Cell rendering:
buffer.zigdrawTextBufferInternal()resolves style spans per-cell; link_id flows throughresolved_style.attributesinto cell attributes - Terminal output:
renderer.zigprepareRenderFrame()emits OSC 8 sequences —currentLinkIdpersists across rows (never reset between rows), but the missingidparam prevents the terminal from grouping the segments
Test Coverage
Existing hyperlink tests in packages/core/src/zig/tests/renderer_test.zig (lines 621-760) cover basic hyperlink rendering but do not test multi-line wrapped hyperlinks. A new test should verify that wrapped hyperlinks emit matching id parameters.
Activity
fix(renderer): add id parameter to OSC 8 hyperlink sequences
fix(renderer): add id parameter to OSC 8 hyperlink sequences