# path-click A plugin for the [DeepSeek Harness](https://github.com/deepseek-ai/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. [πŸ‡¨πŸ‡³ δΈ­ζ–‡](README.md) | πŸ‡¬πŸ‡§ 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 ` 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\UserChoice` registry association (Chrome / Edge / Firefox…) and passes the `file://` URL as a command-line argument β€” bypassing file-type associations, so unassociated types like `.js` or `.lnk` open in the browser without the "How do you want to open this file?" dialog - **Browser (http/https)**: the same mechanism; `mailto:` goes through `rundll32 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://`, 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](https://pnpm.io/). ### From git ```bash dsh plugin --profile web add github:harmony520/path-click ``` ### From a local directory ```bash 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 ```bash dsh plugin --profile web remove path-click ``` ## Development & tests ```bash # 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.mjs ``` Diagnostic 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.md ``` ## Compatibility - 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 to `cmd start` / `rundll32` otherwise ## License [MIT](LICENSE)