Skip to content

feat(paths): a file or folder path on screen is a link when it exists (#99) - #100

Merged
Maxaubert merged 5 commits into
mainfrom
feat/99-clickable-paths
Sep 29, 2026
Merged

Maxaubert merged 5 commits into
mainfrom
feat/99-clickable-paths

Conversation

@Maxaubert

Copy link
Copy Markdown
Owner

Closes #99.

A file or folder path on screen is now a link when it exists. It can be relative to the tab's folder (docs/sign-off/rapport.pdf, as Claude writes them) or absolute (C:\...).

What happens:

  • Only real paths light up. lib/termPaths finds text that could be a path, taking off sentence punctuation and a :12 line number. Main answers which of those exist from the shell's folder. Only those get the link colour and a pointer.
    • The check is batched, and results are cached per folder. A "no" is forgotten after 15 s, so a file written after its name was printed lights up later.
  • A left click opens a file in the app Windows gives it, and a folder in Explorer.
  • Anything runnable is never run. An .exe, a script, a shortcut or an installer (isRunnable) is shown selected in Explorer instead.
  • The right-click menu reads Open (or Open folder), Show in Explorer, Copy path. Copy path copies the absolute path.
  • Prompts are left alone. PS C:\x> and C:\x> would otherwise make every prompt line a link.
  • It works in Claude's fullscreen view too, through fix(links): paint links in full-screen programs too, in a calmer blue (#97) #98's painting of the alternate screen.

Safety:

  • Main never trusts the page with a path. A click sends the TEXT back, and main resolves it and checks it exists again before doing anything.
  • Network (UNC) paths are refused, because a share can stall a stat.
  • Under --e2e, main records what it would open (__e2eOpenedPaths) and opens nothing.

Core change, so Prism too:

  • A host whose main does not hand registerTermIpc its paths openers paints no paths at all, so nothing is ever painted that a click could not open. That is Prism until it is wired.
  • The new optional TermHostConfig.openPath is where Prism will open files inside Prism, as the owner asked. That wiring is a Prism follow-up PR.

The scope line in CLAUDE.md now says that opening a path in its own app is in (the owner's call). Stacked on #98, which must merge first. Core 0.17.0, app 0.20.0. These numbers overlap with the other open PRs, and whichever merges later gets bumped again.

Verified:

  • Unit tests: 952 pass. They cover the finder (the owner's screenshot line, Windows paths, URLs left to the link finder, words and flags ignored), main's resolve, exists, open and reveal, the runnable list, and prompts.
  • Lint and typecheck pass.
  • A new pathLinks e2e in a real pwsh checks all of the following (10 checks):
    • a file, a folder and a .bat that exist are painted, and a missing path is not;
    • a click opens the file and the folder;
    • the .bat is revealed and never opened;
    • a right-click opens nothing;
    • the menu rows are correct;
    • Show in Explorer and Copy path work, and the clipboard is restored afterwards.
  • The full e2e suite passes.
  • .e2e-shots/path-links.png was checked by eye.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t

Maxaubert and others added 4 commits September 28, 2026 21:22
…ullscreen view draws (#97)

xterm has no markers, so no decorations, on the alternate screen. Each row
drawn there has its link text wrapped in a span of the link colour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t
The owner found #4ea1ff too saturated. Same hue and lightness, half the
saturation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t
…#99)

Relative to the shell's folder or absolute. A click opens a file in its own
app and a folder in Explorer; anything runnable is only shown in Explorer.
Main resolves and checks every path itself. Menu: Open, Show in Explorer,
Copy path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t
@Maxaubert
Maxaubert changed the base branch from fix/97-links-on-alternate-screen to main September 29, 2026 21:50
@Maxaubert
Maxaubert merged commit 19dcfbc into main Sep 29, 2026
2 checks passed
@Maxaubert
Maxaubert deleted the feat/99-clickable-paths branch September 29, 2026 22:13
github-actions Bot pushed a commit that referenced this pull request Sep 29, 2026
…#99) (#100)

* fix(links): paint links on the alternate screen too, where Claude's fullscreen view draws (#97)

xterm has no markers, so no decorations, on the alternate screen. Each row
drawn there has its link text wrapped in a span of the link colour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t

* style(links): a calmer link blue, #79a7d8 (#97)

The owner found #4ea1ff too saturated. Same hue and lightness, half the
saturation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t

* feat(paths): a file or folder path on screen is a link when it exists (#99)

Relative to the shell's folder or absolute. A click opens a file in its own
app and a folder in Explorer; anything runnable is only shown in Explorer.
Main resolves and checks every path itself. Menu: Open, Show in Explorer,
Copy path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t

* test(paths): real backslashes in the prompt cases (#99)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Clickable file and folder paths in the terminal

1 participant