dsh-wsl-first

wsltested: passnpmMIT

Publishes an ordered system prompt section that names wsl as the command executor to reach for first, so the agent prefers WSL over PowerShell on Windows. Registers no tools, and only advertises executors the agent can actually call.

下载量 / Downloads
1,240
依赖体积 / node_modules
0.06 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add dsh-wsl-first

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

dsh-wsl-first

[English](README.md) | 中文

让 DSH 在 Windows 上优先用 WSL 执行命令。

🎯 装了 WSL 就先用 WSL,别让模型默认去写 PowerShell。

理念

DSH 在 Windows 上给模型的默认命令工具是 pwsh。这本身没什么问题,但如果机器上已经装了 WSL,这个默认就有点亏。

模型写 bash 比写 PowerShell 顺手,它的命令习惯基本是 POSIX 那一套。硬切到 PowerShell,就得在管道、转义、路径之间来回换算,换算错了还得重来一遍。每多一次重试,就是白烧掉的 token。

输出也是一样。Linux 那边的命令输出大多紧凑;PowerShell 默认给你带表格、带对象属性,同样的信息占的地方明显更大。

路径同理。WSL 工具会自动把 C:\... 转成 /mnt/c/...,不需要模型自己操心。

所以这个插件做的事情很简单:往系统提示词里加一段,写明执行命令先找 wsl。不加能力、不禁用工具,只是把默认顺序调过来。

那段提示词里只列真实注册了的工具。哪个工具没装,里面就不会出现它,也就不会出现"让模型去用一个不存在的工具"这种事。静态的指令文件做不到这点,它只会照抄。

特性

🚀 省 token · 少一次语法换算,就少一次重试

🐧 对准 WSL · 模型按 bash 来写,直接跑在 Linux 侧

🪟 留退路 · 真需要 Windows 原生功能时,pwsh 还在工具表里

🔧 可配置 · 想改成 bash 优先,或者只想提 wsl,改配置就行

🩺 不乱说 · 只宣传真实注册的工具,没装的不写

🖥 侧栏面板 · 左侧栏有入口,一眼看到当前首选/退路/是否发布

侧栏面板

插件在左侧栏注册一个入口(图标 + WSL first 标签),点开是只读面板,显示当前生效的路由:

面板显示 · 含义

Reach for first · 首选执行器(对应 preferred)

Fall back to · 备选(对应 alternatives,去掉与首选重复的)

Last resort · 明确劝退的(对应 discouraged)

Prompt section · 提示词段是否在发布,以及它的 order

面板是只读的:路由由 bundle 行的 cordis.patch.yml 决定,再给一个表单入口等于让同一个设置有两个能互相打脸的主人。要改路由就改那个文件,然后重启 profile。

面板优先读行自己的覆盖值,其次读继承来的 bundle 默认值 —— 和宿主解析同一行的顺序一致。

首次启用要重启 DSH。 客户端包的判定结果会被宿主缓存:如果某个 profile 在装上带 dsh.client 的版本之前,装过同一个包的不带客户端版本,宿主会把「这不是客户端包」也缓存下来,重启前不会重新评估。重装、刷新页面、HMR 都不会让它回心转意 —— 只有重启。之后改动客户端产物,HMR 会自己接上。

依赖

DSH · >=0.1.7-rc.2

必需服务 · systemPrompt,标准 profile 都自带

必需插件 · dsh-wsl-tool,提供 wsl / wsl-path / wsl-env / wsl-doctor

WSL · WSL2,至少一个已注册的发行版,wsl.exe 在 PATH 上

平台 · 任意。Windows 是动机场景,路由器本身与平台无关

本插件自己不注册任何工具,只在别的插件提供的工具之间做路由。没有 dsh-wsl-tool 就没有 wsl 可首选,那段提示词会渲染成空。

安装

npm install dsh-wsl-first

装完加进 profile 的 package.json:

{
  "dsh": {
    "profile": {
      "bundles": ["...", "dsh-wsl-first"]
    }
  }
}

bundle 自带 cordis.patch.yml,会把这个路由行进程级插进去,每个 agent preset 都能拿到这段提示词,不用各自声明。需要重启 profile,loader 在启动时读组合配置。

如果 wsl 工具本身还没装,先装它:

npm install dsh-wsl-tool

DSH 版本兼容

package.json 里声明了 engines.dsh: ">=0.1.7-rc.2"。

本插件**没有声明任何 @deepseek-ai/* peer dependency,也不 import 它们的值。这是一条刻意的设计:DSH 启动时会用 evaluatePluginCompatibility 逐个校验 profile bundle 的 peer 区间,只要有一个不覆盖当前运行时版本,整个 bundle 会被跳过**,cordis.patch.yml 不生效,表现就是"插件装了但没反应"。本插件没有任何 peer 区间可校验,也就不会因为这种原因被跳过。

升级 DSH 大版本后如果本插件突然没了动静,先看 stderr 有没有 skipping profile bundle 字样,再查 engines.dsh 是否还覆盖。

已知问题

在插件管理器里切换开关可能报错

在插件管理器里关闭(或重新开启)本插件时,可能弹出下面其中之一:

停用失败: dsh: profile reload requires the root Include entry
启用失败: dsh: warning: 1 entry did not activate

这不影响插件正常工作。 路由段仍在系统提示词里,插件照常运行 —— 只是这一次的开关没有生效,配置也不会丢失。

重启 DSH 即可:关掉应用再打开。改动会在启动时生效,之后一切正常。

在同一个 profile 里切换其他插件时,也可能出现同样的提示。

另外值得留意:DSH 运行期间编辑 profile 的 cordis.patch.yml,可能会让正在进行的会话丢失部分工具。改完这个文件请重启,不要依赖热重载。

配置

每个字段都可选,写在 profile patch(- id: wsl-first-routing / config:)或环境变量里。优先级:行配置 > 环境变量 > 内置默认值。

字段 · 默认值 · 环境变量 · 说明

preferred · wsl · DSH_WSL_FIRST_PREFERRED · 最先尝试的工具

alternatives · ['bash'] · DSH_WSL_FIRST_ALTERNATIVES · 首选项之后依次尝试(逗号分隔)

discouraged · ['pwsh'] · DSH_WSL_FIRST_DISCOURAGED · 压到"最后手段"的工具(逗号分隔)

promptPolicy · true · — · 是否发布这一段

sectionOrder · 3260 · — · 段的排序位置

sectionName · dsh-wsl-first:shell-routing · — · 段的稳定名称

extraGuidance · '' · — · 追加到段末尾的额外文字

labels · 内置 · — · 表格里 {工具: 任务描述}

requirePreferred · false · — · 仅当 preferred 可见时才发布

只提 wsl,别的都不要

- id: wsl-first-routing
  config:
    preferred: wsl
    alternatives: []
    discouraged: []

这样那段只写 wsl,在没装 wsl 的环境里干脆不出现。

改成 bash 优先

- id: wsl-first-routing
  config:
    preferred: bash
    alternatives: []
    discouraged: []

wsl 只是默认值,这插件本质是个通用的执行器路由器。

两条配置规则

同一个工具既当执行器又当"最后手段"是矛盾,会直接报错,不让某个静默的胜者决定。而 preferred 在 alternatives 里重复出现不算矛盾,那只是冗余(把 preferred 指到 bash 时会自然发生),直接去重。

渲染出来的提示词

# Shell routing: wsl first

**For every command execution, call `wsl` as the first and default tool.**

| Task | Tool |
| --- | --- |
| Any command, build, git, pipeline, script, file listing, search | `wsl` |
| Windows-native only: registry, services, COM, cmdlets with no Linux equivalent | `pwsh` (last resort) |

## Rules

- `wsl` is the primary command executor. Reach for it first, every time.
- Use `pwsh` **only** when the task genuinely requires functionality no other available tool provides — and say why in the same reply.
- Never use `pwsh` merely because it appears first in a tool list, and never as a fallback when a `wsl` command fails: fix the command and retry there.
- Do not mix shell syntaxes. A `wsl` call contains the syntax of the shell that tool runs; each executor has its own quoting and path rules.
- `wsl` paths are Linux paths (`/mnt/c/...`). Windows paths in `command`/`workdir` are translated automatically; pass `translatePaths: false` to hand a native path to a Windows program.

上面这份是从真实会话的系统提示词里读回来的。注意里面没有 bash 那一行:在实测的那个 profile 里 bash 工具没注册,路由器就把它去掉了。

它刻意不做的事

不隐藏、不禁用任何工具。 目标是让 wsl 被优先选中,而不是让 pwsh 消失。隐藏工具改变的是模型能做什么,路由段改变的只是它默认先够哪个。

想要硬版本(把 pwsh 整个摘掉)是你自己 profile patch 的事:

- id: pwsh-sandbox
  disabled: true

改之前先在活着的 loader 树里确认那一行的真实 id,写错会静默失效。

项目结构

dsh-wsl-first
├── index.js          # Host 端插件:注册 systemPrompt 段
├── endpoint.js       # Client 端:侧栏入口与面板
├── lib/
│   ├── config.js     # 配置解析、优先级、校验
│   └── policy.js     # 层级排序与提示词渲染
├── test/
│   ├── smoke.mjs     # 配置与渲染(27 项)
│   ├── mount.mjs     # 真实 apply() 挂载(8 项)
│   ├── docs.mjs      # 断言两份 README 引用的是真实渲染(3 项)
│   └── panel.mjs     # 客户端挂载:注册与渲染(15 项)
├── cordis.patch.yml  # bundle 层:进程级插入路由行
├── dsh-plugin.json   # 插件清单
├── CHANGELOG.md      # 更新说明
└── package.json

更新说明

每个版本改了什么见 [CHANGELOG.md](CHANGELOG.md)。

测试

`

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::4,最后更新 2026-10-24

Links

GitHub · Homepage · npm

Same category