dsh-open-path
dsh-TUI 的 /open 命令:按路径或工作区模糊搜索打开文件、文件夹与 http(s) 链接;不带参数则用文件管理器打开当前会话工作目录
vvilliam-qwq
@vvilliam-qwq
⬇ 1
★ 1
main
安装
dsh plugin --profile web add github:vvilliam-qwq/dsh-open-path
需要可复现安装时,可在仓库后追加 #commit 固定提交。
dsh-TUI 的 /open 命令:按路径或工作区模糊搜索打开文件、文件夹与 http(s) 链接;不带参数则用文件管理器打开当前会话工作目录
该插件未提供要点说明,请参考仓库 README。
deepseekdeepseek-harnessdshdsh-plugindsh-tuifile-manager
- 安装并启动 DeepSeek Harness:
npx @deepseek-ai/dsh web - 在终端执行上面的安装命令(CLI 会解析插件并核验来源)
- 用 dsh plugins list 确认已安装,必要时重启 Harness 生效
插件以当前 dsh 进程的权限运行,安装时可能执行代码。请先通读仓库源码与许可证,确认无破坏性命令与越权访问;本站只做索引,不对第三方插件安全性作担保。
| 代码仓库 | github.com/vvilliam-qwq/dsh-open-path |
| 许可证 | MIT |
| 主要语言 | main |
| 下载量 | 1 |
| GitHub 星标 | 1 |
| 最近推送 | 2026-09-16 |
| 收录日期 | 2026-09-19 |
| 分类 | 工具与能力 |
事实信息来自公开插件目录快照(2026-10-01),介绍文案由本站再加工。
以下为插件仓库 README 全文(原始内容,由公开目录抓取整理)。
# dsh-open-path
[](https://github.com/VviLliAm-qwq/dsh-open-path/actions/workflows/ci.yml)
**English** · [中文](README.zh.md)
`/open` — opens files and http(s) links with the system default program and folders in the file manager, covering direct paths, direct URLs and fuzzy workspace search.
[dsh-TUI](https://github.com/ccch1mneyyy/dsh-TUI) · a plugin built for the dsh-TUI ecosystem
This plugin is a [dsh-TUI](https://github.com/ccch1mneyyy/dsh-TUI) ecosystem plugin; ecosystem site: . Community v0.15 manifest, MIT licensed, supporting Windows / macOS / Linux (including WSL).
## Capabilities
- **`/open`** (no argument) → opens **the current session's working directory** in the system file manager
- **`/open https://example.com`** → opens the http(s) link with the default browser/handler (case-insensitive; only http/https are let through, and `file:`/`ftp:`/`javascript:` and other schemes are rejected with an explicit error)
- **`/open github.com`** → bare domains get their scheme filled in: domains get `https://`, `localhost:5173`/`127.0.0.1:8080` get `http://` (local development); a **real file of the same name in the workspace wins**; common file extensions (`.md`/`.ts`/`.json`…) are not misread as domains
- **`/open src/index.ts`** → opens an existing relative / absolute path
- **`/open ~/docs`** → `~` / `~/…` expands to the home directory (`~user` is not expanded)
- **`/open readme`** → fuzzy-searches the current workspace (file/folder names, CJK- and case-insensitive, Unicode NFD/NFC normalised)
- exactly one hit → opened directly
- several hits → the host's managed dialog (TUI seam 十) lists the candidates, **with no cap on the count**: the panel is windowed to the terminal height and scrolls up/down with ↑/↓ (with scroll arrows), Enter opens, Esc cancels
- more hits than the host dialog's ceiling (100) → only the top 100 are shown, and the title spells it out: `共 N 个匹配,仅显示前 100 个` — never a silent swallow
- zero hits → an explicit error: `工作区中找不到与 “…” 相关的文件或文件夹`
- a folder hit → the folder opens in the file manager; a file hit → it opens in the associated default program
## Install
```sh
# install from npm (package name: dsh-open-path)
dsh plugin --profile dsh-tui add dsh-open-path
# install from a local checkout of this repository (development)
pnpm install --frozen-lockfile && pnpm build
cd ~/.dsh/profiles/dsh-tui && pnpm add
# and add dsh-open-path to dsh.profile.bundles in package.json
```
After installing, run `/restart` inside the TUI (or reopen the window) for it to take effect.
## Platform support
The open action runs an **ordered launcher chain**: the first candidate on the chain that can start successfully (and does not exit non-zero within the grace window) wins; otherwise it automatically falls back to the next one; when the whole chain fails it reports an explicit error and lists the launchers it tried. A chain can also come back **empty** — a Windows file/URL containing `%` has no cmd-free channel — and that is reported as a refusal naming the reason, never as an attempted hand-off.
| Platform | Folders | Files / http(s) links | Notes |
|---|---|---|---|
| **Windows** | `Shell.Application` COM, falling back to `cmd /c start` | `cmd /d /s /c start "" ""` | a single-instance Explorer swallows `start ` requests, so the COM channel is the only reliable way to open a folder; that COM child process **cannot** be detached (a console-less PowerShell drops the call), so only `windowsHide` is used; a target containing `%` is **refused** on the `start` channel (`cmd` expands `%VAR%` even inside quotes), while folders still open through the COM channel, whose PowerShell single-quoted literal leaves `%` alone |
| **macOS** | `open` | `open` | the NFD (on disk) / NFC (as typed) file-name difference is already normalised in the matching layer |
| **Linux** | `xdg-open` → `gio open` → `kde-open5` → `kde-open` → `exo-open` | the same as on the left | any one of them must be installed (most distributions ship `xdg-utils`); all of them handle files, folders and URLs |
| **WSL** | `wslview` → the Linux chain above | `wslview` → the chain above → `cmd.exe /c start` | without WSLg (no `DISPLAY`/`WAYLAND_DISPLAY`) the session still counts as graphical, and the request switches to the Windows-side handler; the `cmd.exe` last resort is dropped for a `%`-carrying URL for the same cmd reason |
Failure is not judged by "the process started, so it worked": a launcher that cannot be spawned (`xdg-open` not installed → ENOENT) or that exits non-zero quickly (no associated program) is recognised and triggers the fallback; when the target path itself does not exist it reports an explicit error instead of falsely claiming `已打开`.
The receipt also says which evidence the success rests on: `已打开` only when the launcher exited 0 inside the grace window, and `已启动 …(未确认退出码)` when the window expired with the launcher still alive — a timeout is never upgraded into a confirmed open.
## Compatibility
- **Minimum dependency**: `@deepseek-harness-tui/dsh-tui >= 0.10.0-beta.5` (command-registration surface C-041 managed surface + fallback; the managed dialog is a "stable candidate" seam)
- **Manifest**: Community v0.15 (`commands.dsh/v1alpha1#Command` required; `commands.invoke` is declared, allowed by default and revocable through the authorization file's `denies`)
- **Command registration**: prefers `ctx.tuiPluginHost.registerCommand` (C-041 attribution + invoke checkpoint); when the host does not provide it, it falls back to the plain `commands` service (C-070 boundary — functionally equivalent, but without the attribution mark)
- **Dialog**: a soft probe through `ctx.get('tuiDialogs', false)` (#183 discipline); when the service is missing it degrades to a clear error listing the candidates, never crashing and never affecting TUI startup
- **Diagnostic log**: `~/.dsh-tui/dsh-open-path.log` — one line each for module import / `apply` start / seam probes (`tuiPluginHost`·`commands`·`tuiDialogs`, each 0/1) / the registration result / unload; trimmed past 128 KiB to keep the newest half; not written during test runs and under `node --test`
- **No dependency pollution**: it does not import upstream package types (structural minimal interfaces), so upstream version drift cannot break this plugin; it also does not reuse the TUI's internal private modules
- **No graphical session**: always available on Windows/macOS (on Windows this is an assumption rather than a probe — see Known Limitations); Linux needs `DISPLAY`/`WAYLAND_DISPLAY`; WSL is the exception (it goes through the Windows side). When unavailable it reports an explicit error rather than failing silently
- **CI**: `ubuntu-latest` / `windows-latest` / `macos-latest` (Node 24, plus Ubuntu × Node 22 to cover the `engines` lower bound)
## Language
Command receipts, error messages, picker candidates and command hints all follow
the host language, resolved along the same chain dsh-TUI itself uses:
`DSH_TUI_LANG` → the live `dsh-tui` settings namespace (where `/lang` writes) →
`~/.dsh-tui/lang.json` → the OS locale → Chinese.
- An unsupported but *present* locale falls back to English; a **missing** one
keeps Chinese, which is what keeps a Chinese host that never wrote a
preference byte-identical to the pre-i18n releases.
- The language is re-resolved on every invocation, so switching with `/lang`
needs **no restart**; the hint text inside command completion is a snapshot
taken at registration time and follows the new language after a restart.
- `DSH_OPEN_PATH_LANG_FILE` overrides the preferences file path (for tests and
diagnostics).
## Configuration
| Key | Default | Description |
|---|---|---|
| `maxCandidates` | `0` | the maximum number of candidates the picker shows; `0` = no limit (every fuzzy match, still bounded by the host dialog's ceiling of 100), or set a positive integer to narrow it yourself |
| `includeHidden` | `false` | whether hidden (dot-prefixed) files/folders are indexed |
Configuration is overridden through `/settings` or the profile's cordis configuration; every key has a default, and a missing one degrades to the default behaviour.
## Working-directory semantics
The command is relative to the **working directory of the receiving session** (`agent.session.header.cwd`, the host-side cwd recorded in the DSH session header) rather than the process cwd — switching with `/workspace` in the TUI creates a new session, whose header carries the new directory, so `/open` always follows along; in extreme cases it falls back through `session.meta.cwd` (the older host alias) → the process start directory in turn.
Relative paths in the fuzzy index are always separated with `/` (equally true on Windows), so the same index has identical semantics on all three platforms.
## Model Experience
The command executes on the UI command plane and the result text is rendered directly by the adapter: **it produces no model messages, counts toward no model tokens and enters no model KV cache**. `command/run` / `command/done` are recorded in the session log as log-only events.
## Known Limitations
- Only `http://` / `https://` links are accepted (including bare-domain completion); `file:`, `ftp:`, `javascript:`, `mailto:` and other schemes are rejected with an explicit error and are never handed to the system. The bare-domain guess exempts common file extensions (`.md`/`.ts`/`.json` etc. are treated as files), and single-character TLDs (such as `a.b`) and version numbers (`v2.0.1`) are not taken for URLs either.
- The fuzzy index is bounded by depth (≤6 levels) and entry count (≤20000); on very large repositories the scan stops at the cancellation signal or the ceiling, and whatever lies beyond is not searched.
- The number of rows in the managed picker is ultimately bounded by the **host**: dsh-tui 0.10.x's `tuiDialogs.select` keeps only the first 100 options of the request (the rest are dropped silently, and the plugin cannot read that constant). This plugin therefore aligns itself with 100 and says so in the title when there are more hits, but **candidates beyond 100 cannot be shown on the current host**; a genuinely unlimited picker would have to go through a self-drawn `tuiScenes` selector.
- Symbolic links pointing at directories are indexed as directories but are **not traversed recursively** (loop and workspace-escape protection).
- `~` expansion covers `~` / `~/…` / `~\…` only; `~user` is not resolved (no passwd lookup).
- When the target is a file and the system has no associated program, the behaviour is up to the system (Windows may show a "How do you want to open this file?" dialog) — the platform default is kept, and no program is chosen on your behalf.
- The open action is still fire-and-forget: failure is observed and rolled back only within a 180 ms grace window, after which it no longer waits for the target program to finish loading; a launcher that crashes after the window goes unnoticed. The window can only ever prove "still running", so the receipt keeps the two readings apart — `已打开` requires an exit 0 inside the window, and a launcher still alive when the window expires is reported as `已启动 …(未确认退出码)`.
- A Windows target containing `%` cannot be handed to `cmd` at all: `%VAR%` is expanded even inside double quotes, so a percent-encoded URL (`https://x.com/a%20b%20c`) or a path like `50%off` would be silently rewritten to a different target. Such a **file or URL** is refused with an explicit error naming `%`; a **folder** with `%` still opens, because its channel is the PowerShell COM call, whose single-quoted literal leaves `%` alone. macOS/Linux/WSL channels pass `%` through unchanged.
- On Windows the plugin assumes a graphical session always exists (`hasGraphicalSession()` returns `true` unconditionally), so a desktop-less Windows host — a pure SSH session, a service account — is never told "no graphical session"; the reported result on such a host may be inaccurate.
- In some desktop environments `xdg-open` blocks until the application exits — this plugin is unaffected (it counts as opened once the grace window has passed).
## Publishing
- **Repository**: (public)
- **Versioning**: semantic versioning; releases are driven by `v*` tags (`.github/workflows/release.yml`: verify the tag matches the `package.json` version → build/test/checks → `npm publish --provenance` → GitHub Release)
- **Prerequisite**: the npm package has a Trusted Publisher configured (GitHub Actions · this repository · `release.yml`) — publishing uses OIDC, so no token has to be stored in the repository
- **Ecosystem listing**: per the listing requirements of , this README carries the dsh-TUI link at the top (the fixed wording given by that site: `[dsh-TUI](https://github.com/ccch1mneyyy/dsh-TUI) · 一个为 dsh-TUI 生态打造的插件`)
## Development and verification
```sh
pnpm install
pnpm build # tsc -> lib/
pnpm test # vitest (platform branches are covered cross-platform through injected platform/env)
pnpm validate:manifest # dsh-plugin.json admission-shape check
pnpm pack:verify # published-artifact layout check
pnpm prepublishOnly # all four, in one go
```
## License
[MIT](LICENSE)
数据来源:公开的 DeepSeek Harness 插件目录与各插件 GitHub 仓库。本站为独立第三方目录,与 DeepSeek、幻方(High-Flyer)及插件作者均无隶属或背书关系。