DSH Windows Plugin: After the Web UI lets users select their preferred default terminal, shell tools consistently invoke PowerShell, Git Bash, or WSL to execute commands.
- Language
- JavaScript
- License
- MIT
- Branch
- master
Install
$ dsh plugin --profile web add dsh-bash-terminalRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Install via your agent
Install the DeepSeek Harness plugin MAXeaglet/dsh-bash-terminal for me: review the repository at https://github.com/MAXeaglet/dsh-bash-terminal first, then run the install command and verify the plugin loads successfully.
Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.
One-Line Positioning
DSH's Windows plugin: unify PowerShell, Git Bash, and WSL into a single shell tool, the default terminal is determined by the user in the Web UI settings page, and AI models cannot bypass user selection. Also includes an interactive terminal tool based on PTY.
Core Capabilities
- Select default terminal (PowerShell / Git Bash / WSL) in Web UI "Settings → General", the shell tool always executes according to this selection
- Provides the
shelltool, which starts a fresh shell for each invocation and follows DSH sandbox policies (restricted mode fail-closed) - Provides the
terminaltool, which starts a PTY interactive session (cwd / variables / aliases persist across calls), suitable for REPL / ssh / interactive CLI - Supports background tasks: long-running commands can be set to
run_in_background, obtaining a job id to collect output viajob_outputor terminate viajob_kill - When sandbox denies, gives the official
[sandbox: file access denied]marker and allows one-time upgrade in the same round usingsandbox_permissions+justification
Technical Implementation
- Language: JavaScript (ESM, main package) + React JSX (client side)
- Key dependencies:
@deepseek-ai/cordis,@deepseek-ai/dsh-tools,@deepseek-ai/dsh-sandbox,node-pty,@deepseek-ai/dsh-shell - Architecture pattern: Cordis plugin (inserts
tool-bash-terminalnode viacordis.patch.ymlwhen profile loads), simultaneously registers host-side (shell+terminaltools) and client-side (settings page "Default Terminal" dropdown) - Entry files:
lib/index.js(host side),src/client.jsx→dist/client.js(client side)
Use Cases
Windows users who want the model to use Git Bash or WSL instead of PowerShell when running commands in the shell tool; or need to preserve session state for interactive commands (REPL, ssh, long-running processes). Also suitable for those who frequently switch between PowerShell, Git Bash, and WSL and want unified management through a single dropdown.
Prerequisites and Compatibility
| Dependency | Min Version | Description |
|---|---|---|
| DSH | ^0.1.0-rc.6 | Requires cordis / dsh-tools / dsh-sandbox / dh-shell / dsh-settings / dsh-llm / dsh-timeout / client runtime etc. |
| Node.js | >=20 | package.json#engines.node |
| OS | Windows (win32) | Plugin skips registration on non-win32 platforms, lib/index.js:424 returns early |
| Native module | node-pty | Required for interactive terminal tool, called directly on Windows platform |
| React | ^18.2.0 | Only used by client settings panel |
| PowerShell 7 | Recommended | PowerShell 5.1 cannot start interactive sessions under ConPTY (one-time commands unaffected) |
Installation
dsh plugin --profile web add github:MAXeaglet/dsh-bash-terminal
After initial installation, also run
powershell -ExecutionPolicy Bypass -File install.ps1 installto patch the DSH settings UI whitelist (addbash-terminalnamespace), otherwise changes in settings page won't take effect. Re-run this script after upgrading DSH.
Configuration Options
| Config | Type | Description | Default |
|---|---|---|---|
defaultShell | string | Backend used when user hasn't overridden in settings page (powershell / gitbash / wsl) | powershell |
timeoutMs | number | Default timeout for single invocation (milliseconds) | 120000 |
maxTimeoutMs | number | Upper limit for caller's timeoutMs parameter | 600000 |
pwshPath | string | Lock absolute path to pwsh.exe, auto-detect from candidate directories if empty | auto-detect |
gitBashPath | string | Lock absolute path to Git Bash bash.exe, auto-detect from candidate directories (auto-exclude System32 WSL forwarder) | auto-detect |
wslPath | string | Lock absolute path to wsl.exe, use %SystemRoot%\System32\wsl.exe if empty | auto-detect |
User changes to "Default Terminal" in Web UI settings persist to settings.yaml, taking priority over defaultShell here.
FAQ
Q: Can AI models switch between PowerShell / Git Bash / WSL on their own?
A: No. Terminal selection is changed and persisted in Web UI "Settings → General → Default Terminal" dropdown; the shell tool doesn't expose terminal parameters to the model. Each invocation executes according to current settings, and the model cannot see other options.
Q: Will it conflict with DSH's built-in pwsh tool?
A: No conflict. The plugin specifically avoids the ctx.shell seam, keeping the official sandboxed pwsh tool intact and usable; this plugin registers another tool named shell, an additional multi-terminal entry point.
Q: Can it be installed on macOS or Linux?
A: Yes, it can be installed, but it won't take effect. apply returns early when process.platform !== "win32", so no tools will be registered.
Q: How to enable "upgrade once" in restricted mode?
A: When sandbox denies a command, results carry the [sandbox: file access denied under <mode> mode] marker; the model can retry in the same round with sandbox_permissions (e.g., workspace-write / danger-full-access) + justification, which will go through ctx.approval user approval.
Q: What to do when PowerShell 5.1 interactive terminal reports an error?
A: This is a known ConPTY limitation (0x8009001d). Installing PowerShell 7 resolves it; one-time commands (shell tool) are unaffected.
Q: What to do about sporadic WSL interactive terminal RPC errors?
A: Sporadic 0x8007072c under ConPTY. Continue using one-time commands via shell tool (wsl -e bash -lc ... is stable), or run interactive scenarios directly in Windows Terminal or WSL terminal, or retry.
Q: Settings panel not working after DSH upgrade?
A: DSH upgrades restore the settings UI whitelist. Re-run powershell -ExecutionPolicy Bypass -File install.ps1 install.
Learning Curve
Beginner — regular users only need to select the default terminal once in Web UI settings to use; local development requires understanding PowerShell, junction links, install.ps1 and additional steps.
Known Issues and Limitations
- Tools only register on Windows;
shellandterminaltools won't appear on macOS / Linux after installation - PowerShell 5.1 cannot start interactive sessions under ConPTY (error 0x8009001d), requires PowerShell 7; one-time commands work normally
- WSL interactive mode under ConPTY may trigger WSL service RPC errors (0x8007072c, sporadic); one-time
wsl -e bash -lc ...works normally - node-pty on Windows doesn't accept named signals: only
SIGINTmaps to Ctrl+C, other signals (SIGTERM / SIGKILL / SIGTSTP / SIGHUP) degrade to direct session termination - WSL background processes may briefly persist in distribution after timeout / interrupt (WSL instances auto-close after last process exits)
- Git Bash is an msys2 environment, with behavioral differences from WSL's Linux (path mapping, available packages)
- DSH's Windows ACL sandbox launcher (
node-addon-landlock-run-win32-x64) not yet published to npm; local sandbox backend temporarily unavailable - DSH settings UI has hardcoded whitelist for third-party settings namespace; must patch with install.ps1 to allow users to write default terminal preference in UI
DSH(DeepSeek Harness)插件:一个 shell 工具,在 Windows 上统一执行 PowerShell / Git Bash / WSL 三种终端命令。
| 后端 | 实际执行 | 语法 / 路径 | 环境变量 |
|---|---|---|---|
powershell(默认) | pwsh -NoLogo -NoProfile -NonInteractive -Command <cmd> | PowerShell;C:\... | $env:NAME |
gitbash | Git for Windows bash -lc <cmd> | POSIX;/d/WorkSpace;PATH 含 /usr/bin、/mingw64/bin | $NAME |
wsl | wsl [-d <distro>] -e bash -lc <cmd> | Linux;/mnt/d/... | $NAME(经 WSLENV) |
每次调用都启动全新 shell:不保留状态(cwd / 变量 / 别名)——请传 workdir 而不是用 cd。
设计要点
- 终端由用户决定,AI 无法更改:Web UI 设置页(设置 → 通用)出现"默认终端"下拉(PowerShell / Git Bash / WSL);
shell工具永远只使用该设置,不暴露终端参数给模型。设置通过 DSH settings 系统持久化(settings.yaml)。 - 不占用
ctx.shell能力接缝:DSH 自带的沙箱化pwsh工具保持原样可用;本插件的shell工具是额外的多终端入口。 - 通过共享的
ctx.subprocessseam 派生进程:进程树终止(Windowstaskkill /T)、SIGTERM→grace→SIGKILL、输出 spill 文件,与官方dsh-tool-bash/dsh-tool-pwsh行为一致。 - 后台任务注册进通用
jobsregistry,支持run_in_background/job_output/job_kill。 - 前端设置页的「默认终端」是枚举(UI 自动渲染为下拉),模型每次调用都只按该设置执行,无法自行切换终端。
安装(web profile)
标准安装(npm 发布后,官方 bundle 机制)
插件带官方 dsh.bundle manifest(包内 cordis.patch.yml),profile 列出本包时 DSH 自动应用挂载,无需手改 profile 配置:
# 1. 安装插件包
npm install -g dsh-bash-terminal
dsh plugin --profile web add dsh-bash-terminal # 自动加进 profile 的 bundles 并应用 patch
# 2. patch DSH 设置白名单(DSH 限制,见下方说明)
powershell -ExecutionPolicy Bypass -File install.ps1 install
# 3. 重启 dsh web
已用临时 profile 实测:
bundles: [dsh-bash-terminal]→ dump-config 自动出现tool-bash-terminalentry。
本地开发安装(junction 直连,改源码即时生效)
# 1. 链接插件包到 profile 的 node_modules(junction,改源码即时生效)
$profile = "$env:USERPROFILE\.dsh\profiles\web"
New-Item -ItemType Junction -Path "$profile\node_modules\dsh-bash-terminal" -Target "D:\WorkSpace\projects\dsh-bash-terminal" | Out-Null
# 2. 让插件能解析 @deepseek-ai/* 依赖(junction 到 profile 的依赖树)
New-Item -ItemType Junction -Path "D:\WorkSpace\projects\dsh-bash-terminal\node_modules\@deepseek-ai" -Target "$profile\..\node_modules\@deepseek-ai" | Out-Null
# 3. 让 profile 通过官方 bundle 挂载插件(install.ps1 install 会自动做;等价于在 dsh.profile.bundles 加 "dsh-bash-terminal")
# 4. (仅修改前端源码后)重新打包 client bundle:
# cd D:\WorkSpace\projects\dsh-bash-terminal && node scripts/build-client.mjs
# 5. 让设置 UI 接受本插件的设置写入(DSH 限制,见下方说明)
# 6. 重启 dsh web
DSH 设置 UI 白名单限制:DSH 的 api-gateway(dsh-host-apiproxy)对 Web 设置客户端暴露的 settings namespace 有硬编码白名单(第三方插件 的设置默认会被
settings-not-exposed拒绝,UI 里改了不生效)。 install.ps1 会自动 patch 该白名单(加入bash-terminal,先备份原文件)。 升级 DSH 后需重新运行 install.ps1 恢复 patch。卸载时 install.ps1 会还原。
当前已不再需要手动改 profile 的
cordis.patch.yml:插件包内自带dsh.bundle.patch(包内cordis.patch.yml),只要 profile 的dsh.profile.bundles里有dsh-bash-terminal,DSH 就会自动挂载。
验证组合树(无需重启):
node "$env:APPDATA\nvm\v24.16.0\node_modules\@deepseek-ai\dsh\lib\bin.js" --profile web --dump-config | Select-String dsh-bash-terminal
使用
用户在 Web UI 设置默认终端:打开设置(齿轮)→ 通用 →「默认终端」下拉,选择 PowerShell / Git Bash / WSL 之一。改动即时生效并持久化。
模型看到 shell 工具后,执行命令时自动使用你选择的终端(工具不暴露终端参数,模型无法更改你的选择):
- 默认终端 = Git Bash 时:
shell(command: "git status")走 Git Bash - 默认终端 = WSL 时:
shell(command: "ls -la /mnt/d/WorkSpace")走 WSL;传distro: "Ubuntu"可指定发行版 - 默认终端 = PowerShell 时:
shell(command: "Get-Process node")走 PowerShell
模型使用示例
- 一次性命令(默认终端):
shell(command: "git status", description: "查看 git 状态") - 跨轮保持状态(交互式):
terminal(action: "open")→ 记下sessionId→terminal(action: "send", sessionId, input: "cd /d/project\n")→terminal(action: "send", sessionId, input: "npm run dev\n")→terminal(action: "close", sessionId) - 中断正在运行的程序:
terminal(action: "signal", sessionId, signal: "SIGINT") - 查看活动会话:
terminal(action: "list") - 沙箱拒绝后升级:
shell(command: ..., sandbox_permissions: "workspace-write", justification: "...")
配置
Web UI 设置(推荐):设置 → 通用 →「默认终端」。
插件 row 的 config(覆盖默认,作为设置的 composition 基准):
| 键 | 默认 | 说明 |
|---|---|---|
defaultShell | powershell | 设置未覆盖时的后端 |
timeoutMs | 120000 | 默认超时 |
maxTimeoutMs | 600000 | 调用方 timeoutMs 上限 |
pwshPath | 自动探测 | 固定 pwsh.exe 路径 |
gitBashPath | 自动探测 | 固定 git bash.exe 路径 |
wslPath | 自动探测 | 固定 wsl.exe 路径 |
发布(npm)
npm 账号已启用 2FA 发布验证,需一次性验证码:
cd D:\WorkSpace\projects\dsh-bash-terminal
npm publish --otp <验证码> # 验证码来自你的认证器
发布前先 npm pack --dry-run 检查内容、跑 node scripts/build-client.mjs 重建 client bundle。
卸载
推荐直接运行:
powershell -ExecutionPolicy Bypass -File install.ps1 uninstall
它会删除 junction、恢复设置白名单、清理旧版遗留的 cordis.patch.yml 挂载块,并从 dsh.profile.bundles 移除 dsh-bash-terminal。之后重启 dsh web 即可。
手动卸载时,除了删除 node_modules\dsh-bash-terminal,还要记得从 profile package.json 的 dsh.profile.bundles 中移除 dsh-bash-terminal。
交互式终端(terminal 工具)
terminal 工具在 PTY 接缝(node-pty;Windows 上因上游 spawnTerminal 的 process inspector 仅支持 POSIX,由 lib/terminal.js 直连 node-pty,非 Windows 仍走官方 ctx.subprocess.spawnTerminal)上提供持久交互会话:
action: open启动一个真实终端会话(按你设置的默认终端;wsl 可传distro),返回sessionIdaction: send写入输入并读新输出;action: read只读不写;action: signal向前台进程组发信号(SIGINT = Ctrl+C)action: close终止会话- 会话状态跨调用保持(cwd / 变量 / 别名),适合 REPL、ssh、交互式 CLI
send会等待输出稳定(300ms 静默,上限 5s)返回完整回复;输出超 1MB 时报truncated提示- 输入用
\\n(或 \r)结尾表示回车
沙箱(官方机制对接)
shell 工具走 DSH 官方沙箱接缝(ctx.sandboxPolicy + ctx.sandbox):
- 每次调用解析当前沙箱策略;
danger-full-access会话直接执行(不包装)。 - PowerShell / Git Bash 后端经
ctx.sandbox.confine包装 argv —— 与官方 executor 相同的 fail-closed 语义:请求受限模式但无可用后端时抛SandboxUnavailableError,拒绝裸跑。 - WSL 后端不包装:WSL 独立 Linux 虚拟机本身就是隔离(结果报告
enforcement: wsl-isolation)。 - 受限模式下被沙箱拒绝时,结果携带官方标记
[sandbox: file access denied under <mode> mode]与同轮升级提示;模型可凭sandbox_permissions+justification发起一次升级(经ctx.approval用户审批),与官方 bash/pwsh 工具完全一致。 - 注意:DSH 的 Windows ACL 沙箱 launcher(
node-addon-landlock-run-win32-x64)当前尚未在 npm 发布,本机沙箱后端暂不可用;架构已就绪,DSH 发布后自动生效。
⚠️ 安全说明
shell 工具的受限模式会经 ctx.sandbox.confine 包装(fail-closed),但它是额外的多终端入口,不享受官方 pwsh 工具的 ConstrainedLanguage 限制;danger-full-access 下与 dsh 进程同权限。DSH 的文件操作工具(read/write/edit)仍受文件沙箱约束。仅在你信任的会话中使用;需要受沙箱保护的 PowerShell 时请继续使用官方 pwsh 工具。
交互终端已知限制(ConPTY)
- PowerShell 5.1 无法在 ConPTY 启动(0x8009001d)—— 交互式 PowerShell 需要安装 PowerShell 7(一次性命令不受影响)。
- wsl.exe 交互模式在 ConPTY 下可能触发 WSL 服务 RPC 错误(0x8007072c,偶发)—— 一次性
wsl -e bash -lc ...命令正常;交互会话建议直接用 Windows Terminal / WSL 终端,或重试。 - Windows 上 node-pty 不接受命名信号:
signal的SIGINT映射为 Ctrl+C(\x03),其他信号(SIGTERM/SIGKILL/SIGTSTP/SIGHUP)退化为终止会话。 - Git Bash 交互会话完全正常。
已知限制
- WSL 后台进程在超时/中断后可能在发行版内短暂残留(WSL 实例在最后一个进程退出后自动关闭)。
- Git Bash 是 msys2 环境,与 WSL 的 Linux 行为存在差异(路径映射、包可用性)。
- 本插件仅在
win32平台注册工具。
测试
cd D:\WorkSpace\projects\dsh-bash-terminal
node test\unit.mjs # 纯函数单测(路径解析/argv/env/渲染/校验)
node test\apply.mjs # apply + execute mock 集成测试(用户设置决定后端、workdir、WSLENV、超时)
node test\client.mjs # client 插件逻辑测试(slot 注册/初始快照/setShell 写透)
node scripts/build-client.mjs # 打包前端设置项 bundle → dist/client.js
Read the usage guide →
Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.
Listing badge
[](https://deepseek-plugin.org/plugins/MAXeaglet/dsh-bash-terminal)Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.