[FEATURE] OSC 8 Hyperlinks for Clickable File Paths

Open 💬 22 comments Opened Dec 3, 2025 by vwieczorek

Problem Statement

When Claude Code outputs file paths like /Users/user/project/src/foo.ts:42, they are not clickable in terminals that support hyperlinks (Kitty, iTerm2, WezTerm, Windows Terminal).

This happens because:

  1. Paths are output as plain text without the file:// scheme
  2. ANSI color codes wrapped around paths break terminal pattern matching
  3. The path:line format isn't recognized as a clickable URL

Users must manually copy paths or use terminal-specific workarounds (like Kitty's hints kitten) to navigate to files.

Proposed Solution

Emit file paths using the OSC 8 hyperlink escape sequence, which is the terminal standard for embedded hyperlinks:

\033]8;;file:///absolute/path/to/file.ts\033\\file.ts:42\033]8;;\033\\

This makes paths clickable with a single click (or Cmd/Ctrl+click depending on terminal config). Many modern CLI tools already do this (ls, exa/eza, fd, bat).

Reference: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda

Alternative Solutions

  • Workaround I currently use: Kitty's hints kitten (Cmd+Shift+F to select paths) - works but requires extra keystrokes
  • file:// prefix only: Would partially help but less robust than OSC 8
  • Opt-in config: Could be a setting if terminal compatibility is a concern

Use Case Example

  1. I ask Claude Code to find a bug in my project
  2. Claude outputs: "The issue is in /Users/victor/project/src/auth.ts:142"
  3. Currently: I manually copy the path or use hints kitten
  4. With this feature: I Cmd+click the path and it opens in my editor

This is especially valuable when Claude references multiple files in a single response.

Additional Context

OSC 8 terminal support (https://github.com/Alhadis/OSC8-Adoption):

  • Kitty, iTerm2 (3.1+), WezTerm, Windows Terminal
  • GNOME Terminal (VTE 0.50+), foot, Konsole
  • Alacritty (recent versions)

Related but distinct from #609 (URL text wrapping) - this is about file paths not being hyperlinks at all.

Environment: macOS, Kitty terminal with detect_urls yes, allow_hyperlinks yes

View original on GitHub ↗

22 Comments

sleepo581 · 7 months ago

This is critical

It's not clear what is selected

<img width="1143" height="279" alt="Image" src="https://github.com/user-attachments/assets/7d0c92dc-4ab0-4339-b831-fc985297d120" />

jhob101 · 7 months ago
This is critical It's not clear what is selected <img alt="Image" width="1143" height="279" src="https://private-user-images.githubusercontent.com/30793892/523358811-7d0c92dc-4ab0-4339-b831-fc985297d120.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NjUxMjI5NjIsIm5iZiI6MTc2NTEyMjY2MiwicGF0aCI6Ii8zMDc5Mzg5Mi81MjMzNTg4MTEtN2QwYzkyZGMtNGFiMC00MzM5LWI4MzEtZmM5ODUyOTdkMTIwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTEyMDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUxMjA3VDE1NTEwMlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWYyYjBkN2YwNzJmNWY1NjA0ZTE5N2VhNDc3ZjljMjY4NDYzMWU3NmE2NDAzNmZjNTY3YWIwM2VjOGJmZDEwNDEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.YKJqMsClOdXwZz9TaTiI_nUWWjIe59wA9HQcKGg9kWo">

Yep, this is my big issue with it too. Massive problem when you can't see what's selected and makes referencing files, which we do all the time, really cumbersome to use.

github-actions[bot] · 6 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

mash · 6 months ago

Here's a solution for the visitors.
I personally use Ghostty and wanted the links in Claude Code to become clickable.

https://github.com/mash/osc8wrap

MarcinOrlowski · 6 months ago

@mash Clickable links in that form as you demonstrated are not a challenge. Custom links were you see not the url but its label (like HTML <a href="URL">LABEL</a>) is. It's very useful think in terminal and i use it heavily. I already do have custom status linke but I'd cram more info there if some of my links could be OSC 8 links (with short label and url not exposed directly).

i.e. try to run this directly in compatible terminal

"🏁 \x1b]8;id=link1;https://google.com\x07\x1b[4;38;2;46;171;12mGoogle\x1b[0m\x1b]8;;\x07 · 🌐 \x1b]8;id=link2;https://github.com\x07\x1b[4;38;2;46;171;12mGitHub\x1b[0m\x1b]8;;\x07 · 🪲 \x1b]8;id=link3;https://example.com\x07\x1b[4;38;2;230;159;28mExample\x1b[0m\x1b]8;;\x07"

and then try to return this from statusline - will not work.

ShravanSunder · 5 months ago

it would be great if file paths are clickable as well. when the text claude outputs has file links it, should also be compatable with osc 8. this will help a lot to review or follow the file

him0 · 5 months ago

I ran into an issue with OSC 8 hyperlinks where the sequence did not work in the Claude Code statusline, and I was able to narrow it down to the choice of terminator.

What didn’t work (ST / ESC \)

// Using ST (String Terminator)
return `\x1b]8;;${url}\x1b\\${text}\x1b]8;;\x1b\\`;

What works (BEL / 0x07)

// Using BEL terminator
return `\x1b]8;;${url}\x07${text}\x1b]8;;\x07`;

Technical notes

OSC 8 sequences support two possible terminators:

|Terminator | Escape sequence | Compatibility|
| ---- | ---- | ---- |
| ST (String Terminator) | \x1b\\ (ESC \) | Not reliably handled in some environments |
| BEL | \x07 | Historically supported, more widely compatible |

In the Claude Code statusline rendering path, the ST terminator does not appear to be interpreted correctly. Switching to BEL makes the hyperlink work as expected.

Since many terminal emulators have long supported BEL as an OSC terminator, using BEL by default (or at least providing it as a fallback) may provide better compatibility, especially in statusline or intermediate rendering contexts (e.g. tmux-like pipelines).

Verified in practice

I have confirmed that this works correctly in a real statusline implementation:
https://github.com/him0/claude-code-statusline

MarcinOrlowski · 5 months ago

Just tested and seems BEL is working workaround to make custom links work with status line. Thanks @him0

senguttuvang · 5 months ago

Use Case: Paths with Spaces

Adding voice to this request with a specific use case: file paths containing spaces.

Current Behavior

When Claude Code outputs a path like:

Created: /Users/name/Projects/My Project/docs/file.md

The path breaks at the space — terminal treats Project/docs/file.md as a separate token. Not clickable.

Workaround (Ugly)

Current workaround via CLAUDE.md instructions:

Created: file:///Users/name/Projects/My%20Project/docs/file.md

Works, but the %20 encoding is visually noisy and harder to read.

Desired Behavior

Other CLI tools (e.g., Codex) output paths with OSC 8 hyperlinks:

  • User sees: /Users/name/Projects/My Project/docs/file.md (clean, underlined, clickable)
  • Hidden link: file:///Users/name/Projects/My%20Project/docs/file.md

Why This Matters

macOS conventions use Title Case with spaces for folders (Documentation, Source Code, project names). These are common in real-world projects. OSC 8 would let Claude Code display human-readable paths while maintaining clickability.

Terminal Support

Both iTerm2 and Ghostty fully support OSC 8 hyperlinks.

---

Co-Authored-By: Claude Code <noreply@anthropic.com>

gradigit · 4 months ago

This issue is a real pain point for me too.

I’ve been using a workaround that’s been stable in daily use:

• a strict CLAUDE.md rule to output OSC-8 links for file/web references
• short visible labels
• plain absolute-path fallback line for local files
• BEL-terminated OSC-8 output for compatibility-sensitive paths
• explicit Bash printf OSC-8 emit patterns in the instructions so output is consistent
sample image of how it looks (all urls and paths are cmd-clickable):
<img width="235" height="228" alt="Image" src="https://github.com/user-attachments/assets/3c5934ce-2ba6-4a64-b466-e0a2f4f50c90" />

Exact CLAUDE.md workaround block (copy/paste): https://gist.github.com/gradigit/b7f924aed6fe7ea042ebe3811cad777f

---

I also built a helper tool (https://github.com/gradigit/claude-pager). I use ctrl-g to edit prompts very often anyway, and along with actually being able to see the session context, it also shortens links and makes them highlighted and clickabled. It made this workflow much more usable.

Before:
<img width="400" height="300" alt="Image" src="https://github.com/user-attachments/assets/d8b0ae35-4f48-427d-b99b-4ec744234272" />

After:
<img width="400" height="300" alt="Image" src="https://github.com/user-attachments/assets/af830bc4-7447-4869-8dd7-5be26b912f71" />

This is still a workaround, not a replacement for native support.
I’d love to see first-class OSC-8 behavior in Claude Code across all rendering paths.

ilepn · 4 months ago

+1 — tried to get ahead of this by implementing OSC 8 file:// hyperlinks in a custom statusline (for clickable working directory + clickable modified-file basenames on a second statusline row). The escape sequences generate correctly but don't render as clickable in standalone terminals due to #26356.

Beyond the statusline, having native OSC 8 wrapping on file paths in Claude's own responses would be a huge UX win. Right now we get colored path:line text that you have to manually copy. With OSC 8, you'd Ctrl+click straight into your editor. Tools like eza, fd, and bat already do this — Claude Code output should too.

olejorgenb · 4 months ago

Yeah, this should be a no-brainer?

Have a post-processing step looking for path-like strings (including line:col). Then checking which paths leads to real files/dirs and linkify them in the output (kinda optional, but perhaps nice). Ideally the link format would be configurable as well. I want to output zed:///file/...:$LINE:$COL

<details>
<summary>Workaround: The Kitty terminal has a feature which linkify all path-looking strings
</summary>

https://sw.kovidgoyal.net/kitty/conf/#shortcut-kitty.Insert-selected-path

It's primary purpose is to easily grab the text and insert, but it also linkify the text so you can click them. The program handling the click is configurable:

mouse_map ctrl+right press ungrabbed kitten hints --type path --program "zed --add"

It works with line numbered paths as well.

</details>

olejorgenb · 4 months ago
Mash: ... https://github.com/mash/osc8wrap ... > MarcinOrlowski: @mash Clickable links in that form as you demonstrated are not a challenge ...

Huh, it's is precisely the challenge. Sure it might be EVEN nicer if the path where intelligently shortened (in such a way that it was self evident for the user which file the shorted link referred to) . But this is a much harder problem and would likely need to be done by the model (or a post-processing mode) burning token better spent on other thing IMO. (unless I misread you?)

I think it's awesome that someone made osc8wrap - a pty proxy which linkify terminal output (in theory from arbitrary programs) if I understand correctly? I'm curious how well it works in practice though. Before I landed on using the built-in Kitty functionality I brainstormed a similar tool with Claude and got scared by the hairiness of the problem.

Though - in the few cases where the Claude harness output information such links should be used. The edit tool already linkify the path inside * Update(...). But it could also linkfy the linenumber in the diff (this would require to redo how the numbering is done somewhat) If not - at least provide a line-numbered path for the beginning of the hunks shown.

gradigit · 4 months ago

https://github.com/anthropics/claude-code/issues/13008#issuecomment-3968687969

Huh, it's is precisely the challenge. Sure it might be EVEN nicer if the path where intelligently shortened (in such a way that it was self evident for the user which file the shorted link referred to) . But this is a much harder problem and would likely need to be done by the model (or a post-processing mode) burning token better spent on other thing IMO. (unless I misread you?) I think it's awesome that someone made osc8wrap - a pty proxy which linkify terminal output (in theory from arbitrary programs) if I understand correctly? I'm curious how well it works in practice though. Before I landed on using the built-in Kitty functionality I brainstormed a similar tool with Claude and got scared by the hairiness of the problem. Though - in the few cases where the Claude harness output information such links should be used. The edit tool already linkify the path inside * Update(...). But it could also linkfy the linenumber in the diff (this would require to redo how the numbering is done somewhat) If not - at least provide a line-numbered path for the beginning of the hunks shown.

the shortening is part of why i built claude-pager, so i can press ctrl+g and quickly get a shortened link that still makes sense.

im working on trying to display the diff view next, and i think your linenumber in diff idea might be worth implementing into claude-pager as well.
I'll see if that's possible

KirkPX · 4 months ago

Still an issue.
Will give https://github.com/mash/osc8wrap a try in the interim.

Peaches491 · 3 months ago

Definitely an issue for AWS console links as well. I'm having Claude do an AWS deploy, launch some process, and then give me a link to the AWS console page for it.

The AWS console links are notoriously long, and end up wrapping within my Claude terminal width. The indentation from the TUI breaks the link detection in iterm and only the first line becomes clickable

OSC8 would be a natural fix for this issue 🙏

<img width="358" height="435" alt="Image" src="https://github.com/user-attachments/assets/9bf61692-e42c-4dea-9c96-6c77b5aa7492" />

yurukusa · 3 months ago

Until Claude Code supports OSC 8 hyperlinks natively, here are ways to make file paths clickable:
Workaround 1 — Terminal-specific path detection:
Most modern terminals can auto-detect file paths if configured:

  • iTerm2: Preferences → Profiles → Advanced → "Semantic History" → set to "Open with editor" and configure "Regular expression" to match paths like (/[^:]+):(\d+)
  • Kitty (kitty.conf):

``
map ctrl+shift+o kitten hints --type path --program "code --goto {}"
``

  • WezTerm (wezterm.lua):

``lua
config.hyperlink_rules = {
-- Match file:line patterns
{ regex = '([/~][\\w./-]+\\.\\w+):(\\d+)', format = 'file://$1#$2' },
}
``
Workaround 2 — Use VS Code extension:
The VS Code extension renders file paths as clickable links in the Native UI. Clicking opens the file at the correct line. This is the easiest solution if you're using VS Code.
Workaround 3 — PostToolUse hook to create clickable links:
This is experimental, but you could post-process output:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Read",
        "hook": "bash -c 'INPUT=$(cat); FILE=$(echo \"$INPUT\" | jq -r \".tool_input.file_path // empty\"); [ -n \"$FILE\" ] && echo \"  → $FILE\" >&2'"
      }
    ]
  }
}

Workaround 4 — tmux + vim keybinding:
In tmux, you can select paths and open them:

bind-key o run-shell "tmux capture-pane -p | grep -oP '[/~][\\w./-]+\\.\\w+:\\d+' | tail -1 | xargs -I{} code --goto {}"

Press Ctrl+B o to open the last file path in your editor.

mpedrummer · 3 months ago

Worth noting: Claude Code itself reports that OSC8 links are not currently supported when asked. It would be a nice touch if the feature detection and rendering were consistent - i.e., Claude Code renders OSC8 links when the parent terminal supports them, rather than telling users it can't.

dopawei · 3 months ago

While waiting for native OSC 8 support in Claude Code, I built a cross-platform workaround: termlink

It's a PTY proxy (Node.js + node-pty) that sits between Claude Code and your terminal, detects file paths in the output stream, and wraps them with OSC 8 hyperlinks. Ctrl+Click to open files.

Key features

  • Windows support via ConPTY (osc8wrap only supports macOS/Linux)
  • ANSI-aware: strips ANSI codes before detection, remaps positions, preserves styling
  • Detects absolute, relative, and path:line:col formats (100+ file extensions)
  • file:// URIs → opens with system default application
  • One-command setup: termlink --setup configures your shell (PowerShell/bash/zsh)

Install & use

npm install -g termlink
termlink --setup
# Restart terminal, then just type 'claude' as usual

Repo: https://github.com/dopawei/termlink

Tested on Windows Terminal + Claude Code. Should also work on iTerm2, Kitty, WezTerm, and any OSC 8-capable terminal.

Would love to see this built natively into Claude Code, but hope this helps others in the meantime!

dopawei · 3 months ago

Root cause found: outdated supports-hyperlinks dependency

After digging into Claude Code v2.1.88's bundled source, I found the exact reason file paths aren't clickable on Windows:

Claude Code already has full OSC 8 hyperlink infrastructureink-link component, pathToFileURL(), the \x1B]8;; escape sequences — it's all there and working.

But the bundled supports-hyperlinks package has this detection logic:

// Bundled in Claude Code v2.1.88:
if (process.platform === "win32") return false;  // ← hard reject Windows

Meanwhile, the latest supports-hyperlinks v4.4.0 already fixed this:

// Current upstream (v4.4.0):
if ('WT_SESSION' in process.env) return true;  // ← Windows Terminal supported!
if (process.platform === 'win32') return false;

The fix is simply updating the supports-hyperlinks dependency. Windows Terminal has supported OSC 8 since v1.4 (2020), and the latest supports-hyperlinks correctly detects it via the WT_SESSION environment variable.

As a temporary workaround, users can set FORCE_HYPERLINK=1 — the detection code respects this env var and skips all platform checks. But updating the dependency is the proper fix.

TL;DR: The rendering pipeline works. The detection is outdated. Update supports-hyperlinks → Windows users get clickable file paths for free.

advenimus · 1 month ago

This is still broken in the new TUI fullscreen interface.

nickname55 · 6 days ago

+1 — running Claude Code in a plain Linux terminal (no IDE integration), and file paths it prints are dead text. When Claude creates or references a file (e.g. a drafted letter/report .md), I want to Ctrl+click it open right from the terminal.

Concretely:

  • Emit local file references as OSC 8 hyperlinks with a proper file:// URI (most modern terminals — GNOME Terminal, Konsole, kitty, WezTerm — make these clickable out of the box).
  • Make the link output format configurable (plain path / file:// OSC 8 / markdown), e.g. a setting like terminalLinkFormat, since capability varies by terminal and some users want emission off entirely (#72998).

Today the only workaround is asking the model to print file:// URIs manually, which it doesn't do by default and doesn't persist.