path-click
A plugin for the DeepSeek Harness (DSH) Web UI: hover a file path or URL and a small bubble menu pops up, letting you reveal it in Explorer or open it in your default browser — any file type opens in the browser, exactly like pasting the file:// address into the address bar.
🇨🇳 中文 | 🇬🇧 English
Features
- Hover file paths in messages (inline code, produced-file chips, file mentions) → bubble menu:
- 📁 Show in file manager: files open their parent folder, folders open directly - 🌐 Open in browser: opens in the default browser regardless of file type (HTML, JS, images, logs…)
- Hover URLs (http/https/file/mailto links) → open in the default browser
- File paths on tool-call cards (including workspace-relative paths) are supported too
- Vertical bubble layout; the mouse can move from the path onto the buttons without the bubble disappearing
How it works
The plugin ships both halves in one package:
| Half | File | Role |
|---|---|---|
| Host | lib/index.js | Registers the /path-click HTTP route and performs the open actions; loaded as a bundle |
| Browser | lib/client.js | Hover detection and bubble UI; discovered by dsh-client-modules through the dsh.client declaration |
Open mechanisms (Windows)
- File manager: calls
explorer.exe <path>directly (files → their parent folder; deliberately avoids explorer's flaky/select,switch when passing paths across process boundaries) - Browser (file paths): resolves the default browser executable from the
http\UserChoiceregistry association (Chrome / Edge / Firefox…) and passes thefile://URL as a command-line argument — bypassing file-type associations, so unassociated types like.jsor.lnkopen in the browser without the "How do you want to open this file?" dialog - Browser (http/https): the same mechanism;
mailto:goes throughrundll32 url.dll,FileProtocolHandler
> Why not ShellExecute / start? ShellExecute routes file:// through file-type associations: HTML works, but .js and friends trigger the "choose an app" dialog — and explorer.exe navigates file:// URLs in Explorer itself. Launching the browser executable directly is the most controllable option.
Security design
- The route lives outside
/api(that prefix is owned by DSH's fixed route table, which third-party plugins cannot extend), so it applies its own trust gate:
- Only POST + application/json is accepted (forces a CORS preflight, blocking cross-site requests) - Origin must equal http://<Host>, and Host must be a loopback authority (127.0.0.1 / localhost / ::1) — protects against both cross-site CSRF and DNS rebinding
- Open actions only activate on loopback deployments
- URL scheme allowlist:
http:/https:/file:/mailto:only; values containing quotes/newlines are rejected - Paths containing a literal
%are refused for browser opening (avoids cmd environment-variable expansion) - The browser half checks path existence before handing anything to the host
Known issues & trade-offs
- Relative paths (e.g. tool cards showing
plugins/foo/bar.js) are resolved against the host process cwd; in a default deployment the cwd is the workspace root, so this is correct — but a workspace elsewhere would misresolve - Trailing separators are stripped before invoking explorer (
path\"would break command-line quote parsing and make explorer fall back to the default folder) - Paths embedded in large plain-text passages (e.g. the Think/reasoning disclosure) are intentionally not matched, to avoid false positives — only text that is exactly a path is matched
- macOS / Linux branches (
open -R/xdg-open) are implemented but untested on real hardware
Installation
Prerequisites: DSH (dsh on PATH) and pnpm.
From git
dsh plugin --profile web add github:harmony520/path-clickFrom a local directory
dsh plugin --profile web add /path/to/path-click> Windows caveat: when the path contains spaces (e.g. a username like "Mo Haowei"), dsh plugin's pnpm forwarding splits the argument. Work around it with pnpm directly: > > ``powershell > cd %USERPROFILE%\.dsh\profiles\web > pnpm add C:\path\to\path-click > ` > > Then append "path-click" to the dsh.profile.bundles list in that directory's package.json`.
After installing, restart DSH (close the console window and start again) and press F5 in the browser.
> Client modules (lib/client.js) hot-reload: DSH polls module files every 500ms, so saving the file takes effect in the current window without a restart. Host-side changes (lib/index.js) and package/config renames need a restart.
Usage
1. Open the DSH Web UI (default http://127.0.0.1:3080) 2. Hover any file path or URL 3. Click a button in the bubble
Uninstall
dsh plugin --profile web remove path-clickDevelopment & tests
# Syntax checks
node --check lib/index.js
node --check lib/client.js
# Host logic unit tests (validation, trust gate, path normalization; opens nothing)
node test-host.mjsDiagnostic log: %TEMP%\path-click.log (every open action logs its command and result).
Layout
path-click/
├── lib/
│ ├── index.js # Host: /path-click route, trust gate, open logic, default-browser detection
│ └── client.js # Browser: hover detection and bubble toolbar (dsh.client module)
├── cordis.patch.yml # Bundle patch: registers the loader row
├── package.json # dsh.bundle + dsh.client declarations
├── test-host.mjs # Host logic unit tests
└── README.mdCompatibility
- Developed against DSH
0.1.0-rc.6 - Windows is the primary platform; macOS / Linux branches exist but are untested
- Depends on readable browser associations (
reg.exe); falls back tocmd start/rundll32otherwise
License
[MIT](LICENSE)