dsh-remote-wsl: Open WSL projects directly as DSH workspaces

Introduction

DSH defaults to recognizing only Windows directories when opening a new session. If your project’s build, test, and run processes are all inside a WSL distribution (Windows 10/11 + WSL2 environment), the common practice is to write the project path on the Windows side and then manually switch to the Linux terminal to execute commands. However, the agent’s bash tools run on Windows, which does not match the real build environment. The plugin introduced below, dsh-remote-wsl, solves this problem: it adds a “Connect WSL” entry in DSH’s “Add workspace” flow, allowing you to browse directories directly inside a WSL distribution and select a Linux path as a workspace. The plugin is maintained by MFJip612, repository address https://github.com/MFJip612/dsh-remote-wsl , license MIT. It uses only DSH’s official services and does not depend on or invoke any third-party WSL plugins.

What is this

In one sentence: It makes DSH’s workspace point to a directory inside a WSL distribution and places that workspace’s terminal and agent tools on the Linux side for execution.

The problem with existing approaches is that for workspaces under Windows paths, the agent uses the Windows-side toolchain when executing bash, whereas the toolchain for WSL projects is inside the distribution. Both sides have different paths, environment variables, and file system views. This plugin requires no wrapper scripts in your project; after installation, there will simply be an additional option in the directory selection dialog.

Core Features

Entry Point. The “+” in the workspace header of the sidebar and the “Add workspace” in the new session page share the same add flow. The dialog first asks where the folder comes from; the first item, Local folder, is the original Windows directory selection, behavior unchanged; the second item, Connect WSL, is the new line. When expanded, you select a distribution.

Select Distribution. The Connect WSL dialog lists all distributions on the local machine (including stopped ones), displays running status, and allows refreshing the list in the top right. The list is enumerated via wsl.exe -l -v --all, automatically detecting UTF-16LE output. The default distribution is marked with *, and the list is cached for 5 seconds.

Select Project. After selecting a distribution, browsing starts from that distribution’s default user $HOME. Breadcrumbs (e.g., Ubuntu / home / me) are clickable; the search box filters the current level, or you can directly enter a Linux path to jump; you can toggle the display of hidden folders. Click Confirm after selecting the current directory.

Register as Workspace. Projects on the Linux file system are registered as \\wsl.localhost\<distro>\<path> (it will automatically probe \\wsl$ as a fallback). Projects under /mnt/<drive>/... are registered as real Windows paths (e.g., D:\work\proj) because WSL’s 9P share does not allow access to /mnt, and only real drive letter paths are readable and writable. The plugin remembers which distribution it came from. After registration, it becomes a normal workspace in a new session, just with a different execution context.

Terminal inside Distribution. When opening the sidebar terminal for this workspace, it actually executes wsl.exe -d <distro> --cd <linux path>, which is the distribution’s login shell, with the start directory being the project directory.

Agent Tools inside Distribution. In sessions for this workspace:

Tool Behavior
bash Executes bash -lc inside the distribution, workspace is the default directory, a new shell is spawned for every call
read / write / edit Uses Linux paths; write and edit use temporary files with atomic rename (WSL’s 9P share does not support DSH’s native hard link publish)
glob / grep Uses globstar / GNU grep inside the distribution for searching

Windows PowerShell tools are hidden in WSL workspaces; normal Windows workspaces are unaffected.

Installation and Enable

Install from DSH’s Plugins page for a local directory, or use the command:

dsh plugin --profile web add github:MFJip612/dsh-remote-wsl

The repository only contains TypeScript source code. Before installing a local directory, execute npm ci (which builds automatically) or npm run build. When installing via GitHub, the build is triggered by prepare; if pnpm blocks the build script, retry after allowing that specific package key in the corresponding profile’s pnpm-workspace.yaml as prompted by the installer. You can also execute npm pack to install a tarball containing the build artifacts.

You can also let the agent use the plugin manager to install that directory in a session. link: only guarantees that files in the directory are readable, not that the running Host will reload the code. By default, changes to Host-side code require completely exiting and restarting DSH, while changes to the Browser-side code only require refreshing the page. DSH’s default HMR configuration is root: [], listening only to config files. If the exit prompt says there are running tasks, wait for them to finish before restarting.

Additionally, the runtime requires Node >= 24.9.0 (see engines in package.json), and the peer dependency for @deepseek-ai/cordis is >=4.0.5 <5.

Configuration

Override the plugin’s config in the profile’s cordis.patch.yml:

- id: dsh-remote-wsl
  name: 'dsh-remote-wsl'
  config:
    terminal: true
    tools: true
Field Default Description
terminal true Whether the sidebar terminal for a WSL workspace opens inside the distribution
tools true Whether to enable Linux-side tools for WSL workspace sessions
execTimeoutMs 15000 Timeout for a single wsl.exe call (milliseconds)
distroCacheMs 5000 Duration of the distribution list cache
maxEntries 2000 Maximum number of entries returned by the selector for a single directory level
maxReadBytes 2000000 Maximum number of bytes returned by a single read
defaultDistro '' Reserved: Default distribution override (empty = use WSL default)
mountRoot '' Automount root directory (empty = read from distribution’s /etc/wsl.conf, fallback /mnt)
remote false Whether to allow non-loopback clients to call the plugin routes

File Changes and Delivery Cards

Before publishing, WSL write / edit first go through the official fs/write-intent / fs/edit-intent to let DSH capture the content before editing, and record fs/observed upon success. Tool results reuse the output format, metadata, and diff presentation of the native write/edit; official workspace-changes generates the list of modified files and comparison at the end of the round. Read-only, out-of-bounds, unobserved, or expired-version writes will still be rejected.

present continues to use the official executor and the deliverables/presented event. The plugin converts Linux absolute paths, relative paths, ~/, and mounted drive paths to Windows-accessible paths, preserving description, file count limit, and normal file checksum and click preview/open behavior. UNC paths pointing to other distributions will be rejected.

The list of modified files automatically aggregates content successfully changed by file tools; individual file cards are still emitted by the model calling present; the plugin does not automatically emit cards for every source code change. If files are changed only via bash (and source code in non-Git directories lacks file tool pre-capturing), you should explicitly instruct the model to call present when a separate card is needed.

Implementation Highlights

The entry point occupies two singleton slots declared by the official workspace component: sidebar.workspaces.directoryFlow and conversation.hero.workspace.directoryFlow. It renders its own Local folder / Connect WSL selector. The priority is lower than the official occupant, and the dialog is drawn on shell.overlay. When selecting Local folder, it calls the official ctx.uiWorkspace.pickDirectory() (or the injected __DSH_DIRECTORY_PICKER__ on desktop), keeping native selection behavior unchanged.

Host-side routing: GET /dsh-remote-wsl/{status,distros,warm,list} and POST /dsh-remote-wsl/connect. Both are same-origin JSON, rejecting cross-site requests, and default to allowing only loopback; connect registers the workspace via the official workspaceRegistry.create(). Directory browsing goes directly through the \\wsl.localhost share, falling back to executing find inside the distribution if the share denies access. The terminal wraps the official subprocess.spawnTerminal, replacing argv only when cwd falls inside a WSL workspace; other terminals are passed through transparently.

Use Cases and Precautions

Suitable for users developing on Windows 10/11 + WSL2 where the project actually builds and runs on the Linux side, and want it to run with the permissions of the current dsh process: the plugin’s Host routes and subprocess calls execute with the permissions of the user who started DSH. Setting remote: true also exposes the routes to non-loopback clients, so you need to confirm the network boundary before enabling.

Before installing, you should check the source code and license (MIT) to confirm that the wsl.exe subcommands and network routes it calls match your deployment environment. The plugin is currently marked as unverified (status: unverified) in the community directory, the repository has 1 star, and it is an early project. It is recommended to test run in an isolated environment before integrating into production workflows.

Conclusion

The problem dsh-remote-wsl solves is very specific: making DSH’s workspace, terminal, and agent tools all fall on the WSL distribution side, rather than manually switching between Windows and Linux. Directory page: https://www.skillhub.cn/plugins/MFJip612/dsh-remote-wsl ; Source code and docs: https://github.com/MFJip612/dsh-remote-wsl .

羽毛球分组比赛记分
小程序二维码

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

Xiaoye