You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(terminal): Ctrl+click a file path to open it in wmux or the default app - #365
In VS Code's terminal, a path an agent prints (docs/itch/devlog/0.5.md) is a link: Ctrl+click opens it. In wmux it is plain text. activateTerminalLink drops anything that is not http(s), so the only way to open that file is to find it again in the explorer.
Task
Make printed file paths Ctrl+clickable without giving the renderer any reach the explorer does not already have (#210's jail).
Action
src/main/terminal-file-link.ts, behind a new terminal:resolve-file-link channel. It takes the path as printed, relative or absolute, resolves it against the pane's explorer root and sends it through resolveInRoot. The renderer still never chooses a root. The only thing allowed outside the jail is a file on markdown's extension whitelist, which markdown.readFile already opens from any absolute path. SSH panes get nothing.
src/renderer/utils/terminal-file-links.ts registers an xterm link provider. It picks path-shaped tokens (strips :line:col and trailing punctuation, skips URLs, flags and bare numbers), asks main which of them exist, and underlines only those.
What opens where: a text file goes to the preview tab, like a single click in the explorer. Anything the code viewer refuses (binary, too_large) goes to explorer.openInApp, so EXEC_EXT still decides what may be launched. Markdown outside the root opens in a markdown tab.
Moved findOwner from CodePane.tsx into split-utils.ts as findSurfaceOwner; the note there said to do that once a second caller showed up.
CLAUDE.md: a row for the new module and a line in the preload table.
Result
28 new tests in tests/unit/terminal-file-link.test.ts and tests/unit/terminal-file-links.test.ts, all passing.
Full suite on my machine: 5431 passed. 4 files fail, and they fail the same way on master here: cli-config-path, install-scope and installer-icon-refresh (missing app-builder-lib NSIS templates in my install, plus the existing wait-probes.ts type error), and one pty-manager test about pwsh WindowsApps aliases.
eslint reports no new errors. The 5 it does report, in ipc-handlers.ts and useTerminal.ts, are on lines this PR does not touch.
Live test on the dev build: in a PowerShell pane sitting in a project folder, Ctrl+click on docs/itch/devlog/0.5.md opened it in a markdown tab. The same text in a pane sitting in my home folder was not linked, which is correct, since the file does not exist there.
Not tested live: a binary going to the default app, markdown outside the root, and a Ctrl+click inside a mouse-tracking app. Unit tests cover all three; a live run did not.
Merged, thank you! One hardening commit on top (70afa5a): UNC/device paths (\\host\share\a.md, //host/..., \\?\) are refused before any stat, because the resolver runs on hover over output a remote host controls (SMB connection = NTLM leak + main-loop stall); the outside-root stat is async; panes with no root still go through the ownership and ssh gates; and a binary in-root file is revealed in Explorer rather than launched in its default app, so a Ctrl+click on printed text can't open a macro document or mount an image. Ships in 2.43.0.
Merged, thank you! One hardening commit on top (70afa5a): UNC/device paths (\\host\share\a.md, //host/..., \\?\) are refused before any stat, because the resolver runs on hover over output a remote host controls (SMB connection = NTLM leak + main-loop stall); the outside-root stat is async; panes with no root still go through the ownership and ssh gates; and a binary in-root file is revealed in Explorer rather than launched in its default app, so a Ctrl+click on printed text can't open a macro document or mount an image. Ships in 2.43.0.
Love the program dude, really do will keep helping as i can. From itself haha
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Situation
In VS Code's terminal, a path an agent prints (
docs/itch/devlog/0.5.md) is a link: Ctrl+click opens it. In wmux it is plain text.activateTerminalLinkdrops anything that is not http(s), so the only way to open that file is to find it again in the explorer.Task
Make printed file paths Ctrl+clickable without giving the renderer any reach the explorer does not already have (#210's jail).
Action
src/main/terminal-file-link.ts, behind a newterminal:resolve-file-linkchannel. It takes the path as printed, relative or absolute, resolves it against the pane's explorer root and sends it throughresolveInRoot. The renderer still never chooses a root. The only thing allowed outside the jail is a file on markdown's extension whitelist, whichmarkdown.readFilealready opens from any absolute path. SSH panes get nothing.src/renderer/utils/terminal-file-links.tsregisters an xterm link provider. It picks path-shaped tokens (strips:line:coland trailing punctuation, skips URLs, flags and bare numbers), asks main which of them exist, and underlines only those.binary,too_large) goes toexplorer.openInApp, soEXEC_EXTstill decides what may be launched. Markdown outside the root opens in a markdown tab.findOwnerfromCodePane.tsxintosplit-utils.tsasfindSurfaceOwner; the note there said to do that once a second caller showed up.CLAUDE.md: a row for the new module and a line in the preload table.Result
tests/unit/terminal-file-link.test.tsandtests/unit/terminal-file-links.test.ts, all passing.masterhere:cli-config-path,install-scopeandinstaller-icon-refresh(missing app-builder-lib NSIS templates in my install, plus the existingwait-probes.tstype error), and onepty-managertest aboutpwshWindowsApps aliases.eslintreports no new errors. The 5 it does report, inipc-handlers.tsanduseTerminal.ts, are on lines this PR does not touch.docs/itch/devlog/0.5.mdopened it in a markdown tab. The same text in a pane sitting in my home folder was not linked, which is correct, since the file does not exist there.