dsh-host-file-explorer: Browse host machine files in DSH

Preface

When developing DSH plugins or debugging agents, it is often necessary to confirm directory structures, configuration file contents, or specific images on the host machine within the browser interface. Previously, such operations involved either jumping back to the terminal to run commands or letting the plugin implement a file tree component on its own. The plugin introduced below adds a file management panel directly to the DSH left sidebar, bringing host machine file browsing, previewing, downloading, and uploading into the interface.

  • Plugin Name: ccfeeling/dsh-host-file-explorer (npm package name @local/dsh-host-file-explorer, version 1.2.0)
  • Maintainer: ccfeeling
  • License: MIT
  • Category: Client Plugin
  • Source: Community Plugin Directory (not DeepSeek / Huafang official app store), GitHub repository is https://github.com/ccfeeling/dsh-host-file-explorer

Positioning

This is a standard DSH bundle, consisting of a Host half and a Client half. The Host half attaches a service to ctx.hostFiles, providing seven verbs based on node:fs/promises; the Client half registers a host-files panel in the sidebar, providing directory listings, text and image previews, file download, file upload, and creating new folders, and supports twelve interface languages.

All reading operations go through the Host/Client Remote channel—the same boundary used by the agent’s own file system tools—rather than bypassing it to access the file system directly.

Core Features

The feature list is as follows, all taken from the README:

  • Directory List: Directories first, files last, each item includes type, size, and modification time; hidden items are displayed in a dimmed style.
  • Text Preview: Reads the first 256 KiB of text files and renders them; binary files report themselves rather than printing garbage.
  • Image Preview: PNG, JPEG, GIF, WebP, AVIF, and SVG are displayed inline, not read as text.
  • Download: Handled to the browser via Harness’s authentication file routing, preserving the original filename.
  • Upload: Sends files in the browser as a Remote call to the currently open directory; bytes are carried with the command, not through the browser file routing.
  • New Folder: Creates a single subdirectory under the current directory.
  • Path Navigation: Jump to absolute paths, return to the parent directory, plus shortcuts for HOME, tmp, cwd, and the filesystem root.

Installation and Enabling

There are three installation methods; choose one based on your use case.

The first is plugin manager installation (recommended in the README). Clone the repository, then install from the local path:

# clone
git clone https://github.com/ccfeeling/dsh-host-file-explorer.git

# Install to a specific DSH profile, replace profile name and path with your environment
dsh plugin --profile web add /path/to/dsh-host-file-explorer

The corresponding tool call is plugin_manager { action: 'install_bundle', target: '<local path>' }.

The second is installation from the plugin marketplace. This plugin is listed in the awesome-dsh-plugin list, so it can be installed directly from GitHub:

dsh plugin --profile web add github:ccfeeling/dsh-host-file-explorer

The third is declaration as a profile dependency. Edit ~/.dsh/profiles/<profile>/package.json:

{
  "dependencies": {
    "@local/dsh-host-file-explorer": "link:/abs/path/to/dsh-host-file-explorer"
  }
}

After installation, a folder icon will appear in the sidebar after Plugins and Schedules. Clicking it opens the panel.

A pitfall related to profile dependencies: If a profile has a dependency that publishes agent skills along with the package (e.g., dsh-answer-me-with-html), pnpm 10.11+ and 12.x will refuse installation and throw ERR_PNPM_NO_AGENT_SKILLS_DIR if the skills directory is not declared. Adding a section in the profile’s pnpm-workspace.yaml fixes this:

skills:
  dirs: []

Underlying Architecture

The plugin’s code structure is as follows:

index.js   (Host)    ctx.hostFiles  ——  seven verbs based on node:fs/promises
client.js  (Client)  sidebar entry + main panel + Remote namespace mount

The Host half declares Remote transport using prototype markers @deepseek-ai/dsh-typert-protocol/remote-methods, allowing the gateway to discover these methods in SRC mode:

Method Parameters Returns
roots() — HOME, tmp, cwd, filesystem root
list(path, signal) path { path, parent, home, entries[{ name, path, kind, size, modified, mime, hidden }], truncated }
stat(path, signal) path { path, kind, size, modified, mime }
read(path, signal) path { path, size, modified, binary, truncated, text }
mkdir(path, name, signal) path, name { path }
upload(path, name, data, signal) path, name, data { path, size }
limits() — Maximum bytes allowed for a single download

Here is a signature constraint: signal must be the last parameter. The gateway uses Function.prototype.toString() to parse method signatures and deduce parameter types; getting the signature wrong will cause the call to fail.

Regarding how files reach the browser: The page itself does not transmit file bytes via the Remote channel. Instead, it asks the Host for the address of the file on Harness’s authentication file routing (the same route used for Markdown images in document previews), and the browser reuses the session already held by the page to retrieve it. Downloads preserve the original filename, and previews obtain the original Content-Type, so PNGs are rendered as PNGs. Single responses are constrained by Harness’s attachment byte limit (default 20 MiB); the panel will read this limit from the Host first and refuse downloads that exceed the limit with an explanation, rather than starting a doomed transmission.

The Client half hand-wrote a Typert Remote contribution, mounted via ctx.remote.$mount(...), and then registered two slots:

  • sidebar.panellist: id host-files, order 30, with a dedicated folder icon;
  • main: key host-files, which is the panel opened by the sidebar button.

Two Development Traps

The README specifically emphasizes two points that need to be noted when extending or copying this plugin.

First, the namespace cannot be declared as the plugin’s own inject. The mounted remote.hostFiles is an independent service and only exists after this plugin is mounted; if a fiber tries to wait for it, it will wait forever, and the plugin will fail to start. You must read directly from the shared store using a Cordis mixin entry:

const namespace = ctx.get('remote.hostFiles');

Official plugins can write inject: ['remote.agentPresets'] because other packages have mounted those namespaces, allowing consumers to declare dependencies directly; this plugin cannot be written this way, precisely because of that.

Second, the Client half does not depend on any Harness client package. It only uses react and zod, and implements styling using --dsw-alias-* theme variables, importing nothing from @deepseek-ai/dsh-client-ui-primitives or similar packages.

Permissions and Boundaries

Before using it, you need to clarify these limitations:

  • The plugin reads the host machine’s file system with the permissions of the Harness process itself; whatever the account can read, it can read. This is an inherent attribute of a host file browser, so only enable it on machines and accounts you trust.
  • Capabilities are read-only, plus creating new folders and uploading files. It cannot modify, delete, or rename existing files, and uploads never overwrite files with the same name.
  • A single list returns a maximum of 2000 items, and a single preview reads a maximum of 256 KiB.
  • A single download does not exceed Harness’s attachment byte limit (default 20 MiB), and the panel will explain the reason before a download that exceeds the limit starts.

Before installing a third-party plugin, it is recommended to read the source code and license (this plugin is MIT) first to confirm that the directory scope for downloads and uploads meets expectations.

Summary

The value of this plugin lies in converging host file system operations into the DSH interface, while reusing the agent’s existing Remote channel without introducing additional privilege escalation paths. For DSH users and plugin developers who need to verify configuration files, view images, or send/receive files on the web, it is a client tool that can be installed directly.

  • Directory Page: https://www.skillhub.cn/plugins/ccfeeling/dsh-host-file-explorer
  • GitHub: https://github.com/ccfeeling/dsh-host-file-explorer

During the development phase, you can use the commands provided in the README for basic checks:

node --check index.js
node --check client.js
npm pack --dry-run      # View the actual file list to be published
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye