中文EN

dsh-wsl-first

wsl已测通过npmMIT

发布一段带顺序的系统提示词段,指定 wsl 为执行命令时优先选用的执行器,让模型在 Windows 上优先走 WSL 而不是 PowerShell。不注册任何工具,且只宣传模型真实可调用的执行器。

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

安装

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

沙箱测试结果

阶段结果
1 安装✓
2 列装✓
3 挂载✓
4 启动—

四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。

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)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:4,最后更新 2026-10-24

链接

GitHub · Homepage · npm

同类插件