dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
dsh-TUI /open command: open files and folders by path or fuzzy workspace search (v0.15 manifest, MIT)
English · 中文
/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 · a plugin built for the dsh-TUI ecosystem
This plugin is a dsh-TUI ecosystem plugin; ecosystem site: https://dshtui.com/. Community v0.15 manifest, MIT licensed, supporting Windows / macOS / Linux (including WSL).
/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)
共 N 个匹配,仅显示前 100 个 — never a silent swallow工作区中找不到与 “…” 相关的文件或文件夹# 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 <path to this repository>
# 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.
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 "" "<target>" | a single-instance Explorer swallows start <directory> 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.
@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)commands.dsh/v1alpha1#Command required; commands.invoke is declared, allowed by default and revocable through the authorization file's denies)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)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~/.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 --testDISPLAY/WAYLAND_DISPLAY; WSL is the exception (it goes through the Windows side). When unavailable it reports an explicit error rather than failing silentlyubuntu-latest / windows-latest / macos-latest (Node 24, plus Ubuntu × Node 22 to cover the engines lower bound)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.
/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).| 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.
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.
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.
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.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.~ expansion covers ~ / ~/… / ~\… only; ~user is not resolved (no passwd lookup).已打开 requires an exit 0 inside the window, and a launcher still alive when the window expires is reported as 已启动 …(未确认退出码).% 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.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.xdg-open blocks until the application exits — this plugin is unaffected (it counts as opened once the grace window has passed).v* tags (.github/workflows/release.yml: verify the tag matches the package.json version → build/test/checks → npm publish --provenance → GitHub Release)release.yml) — publishing uses OIDC, so no token has to be stored in the repository[dsh-TUI](https://github.com/ccch1mneyyy/dsh-TUI) · 一个为 dsh-TUI 生态打造的插件)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