liceses
dsh-all-gitbash
DeepSeek Harness 插件:把 Windows 上 所有 pwsh 命令执行改道 Git for Windows bash —— 模型从第一轮对话起就只有 bash 工具(pwsh 工具被直接禁用),实际执行的是 Git for Windows bash(MSYS),不再写 PowerShell。
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 16, 2026
- Updated
- Aug 16, 2026
Introduction
dsh-all-gitbash
DeepSeek Harness 插件:把 Windows 上 所有 pwsh 命令执行改道 Git for Windows bash ——
模型从第一轮对话起就只有 bash 工具(pwsh 工具被直接禁用),实际执行的是
Git for Windows bash(MSYS),不再写 PowerShell。
姊妹插件:dsh-gitbash-preset (极简模式的 bash → Git Bash 引导器)。两者可同时安装、互不冲突,详见 与 dsh-gitbash-preset 的关系。
特性
- 运行时改道,免重启:不改 composition、不碰 profile patch,注入即生效;热重载 / 卸载即净
- 模型侧原生 bash:注册官方形态的
bash工具(完整沙箱升级 / 后台任务 / 终端卡片),pwsh工具从模型工具面整体移除,bash 工具描述 / 提示词段落与 Linux 会话逐字对齐 (无 pwsh / PowerShell / MSYS / 路径转换字样——模型获得与 Linux 原生 bash 完全相同的体验) - 一键开关:Web 设置面板 General 页的滑块开关(DSH 风格),或
~/.dsh/settings.yaml的enabled字段,点一下整套改道装配 / 还原,往返无损、重启保持 - 命令翻译兼容层:剥离 PowerShell preamble、
$env:NAME→${NAME}、C:\...→/c/...(模型偶尔写 PowerShell 习惯语法时不会炸) - 诚实的沙箱门控:MSYS 在受限令牌沙箱内无法启动(signal pipe),受限模式快速失败并给 单次升级指引——不绕过沙箱边界
- 零构建依赖:纯 JS(同 dsh-gitbash-preset 惯例),
src/→lib/拷贝即用,27 个单测
动机
模型写 bash 远比写 PowerShell 顺手(路径、管道、$VAR、条件判断的生态都是 POSIX 向的)。
DSH 在 win32 上默认只挂 pwsh-sandbox + tool-pwsh(dsh-base 把 bash 栈按平台门控禁用),
于是 AI 被迫写 PowerShell。与其做 PowerShell 语法翻译(治标),不如把执行器整个换成
Git Bash(治本):模型写 bash,命令跑 bash,且模型看到的命令工具信息与 Linux 会话完全一致。
工作原理
数据流
模型 ──bash 工具──► ctx.shell(SandboxPwshExecutor 实例)
(pwsh 工具已禁用)
▼
argv() 被实例级替换(原型方法遮蔽)
│
["<git bash>", "-c", 翻译后命令]
│
前台 ──────────► subprocess.spawn ──► Git Bash (MSYS)
后台 ──jobs──► (同一 argv 构造)
沙箱 ──confine──► ACL 受限令牌 runner ──► Git Bash(受限模式下门控拒绝)
各环节
| 环节 | 说明 |
|---|---|
| 执行器改道 | 把 ctx.shell(@deepseek-ai/dsh-pwsh-sandbox 实例)的 argv() 整体替换为 "<git bash>" -c <命令>。pwsh 执行器的 confine() 调 this.argv(spec),因此前台 / 后台 / 沙箱链三条路径全部生效 |
| bash 工具 | 注册原生 bash 工具(win32 上官方 tool-bash 被禁用,名字空闲),定义镜像官方 dsh-tool-bash:沙箱升级、后台任务、终端卡片齐全,模型看到的是 bash 文档 |
| pwsh 工具 | tools registry 里全部层的 pwsh 定义(每个 agent 预设各一份)直接删除,官方 tool:pwsh 提示词 section 一并删除——模型工具面只剩 bash,且所有模型可见文本无 pwsh/Windows 字样;关开关 / 卸载时原样恢复 |
| 提示词 | systemPrompt 段落(order 120,位于工具段 105 之后)声明:命令工具 = Git Bash,写 POSIX bash |
| PATH 垫片 | 生成 ~/.dsh/dsh-all-gitbash/bin/{pwsh,powershell} 脚本并前置 PATH —— git bash 会话内敲 pwsh 也进 git bash |
| 设置 API | webServer 路由 GET/POST /api/dsh-all-gitbash:设置页开关行的读写通道(settings 命名空间不在 apiproxy 配置白名单内,故走插件自有通道,同 dsh-workspace-tree 模式) |
Git Bash 探测
显式 bashPath 配置 → GIT_BASH 环境变量 → 注册表 HKLM\SOFTWARE\GitForWindows
(及其 WOW6432Node)→ 常规安装根(ProgramFiles / (x86) / LOCALAPPDATA)→
PATH 逐目录扫描(跳过 WindowsApps 的 WSL Store 存根)→ 兜底裸 bash。
注册表探针是关键:Git for Windows 默认只把
cmd目录加进 PATH,bin\bash.exe常常不在 PATH 上(本机实测)。
命令翻译
仅执行层生效,不进模型提示(描述/提示词不提及,模型写纯 bash 用不到):
- 剥离
dsh-pwsh-local注入的 UTF-8 preamble(PowerShell 语句,bash 跑不了); $env:NAME→${NAME};C:\...→/c/...(驱动器反斜杠路径在 bash 里是字面量,会炸;整 token 转换含后续反斜杠)。
一键开关
插件把整套改道资源收进一个运行时开关(settings 命名空间 dsh-all-gitbash),
两个入口等效,点一下即生效、重启后保持:
- Web 设置面板 → General:「Git Bash 模式(dsh-all-gitbash)」滑块开关
(DSH 风格,client 半区注入
settings.general.item插槽,经/api/dsh-all-gitbash读写); - settings 文件:
~/.dsh/settings.yaml里dsh-all-gitbash.enabled: false关闭。
效果:enabled: true = 所有命令走 Git Bash(argv 改道 + bash 工具 + 提示词
- PATH 垫片 + pwsh 工具禁用);
enabled: false= 完整还原为原装 pwsh (argv 还原、bash 工具注销、pwsh 工具恢复、PATH 垫片移除),开关往返无损。
开关行需要刷新一次浏览器页面后出现(client bundle 随 boot 清单注入)。
# ~/.dsh/settings.yaml
dsh-all-gitbash:
enabled: true # 总开关
sandboxGate: true # 受限沙箱快速失败 + 升级指引
translateEnvVars: true # $env:NAME → ${NAME}
translateDrivePaths: true # C:\... → /c/...
与 dsh-gitbash-preset 的关系
dsh-gitbash-preset 是配套的姊妹插件: 它解决「极简模式的 bash 指向谁」——把 DSH 极简模式(minimal preset)的 bash 工具 引导到 Git for Windows bash(自动探测 shell 路径、按沙箱策略门控);本插件解决 「完整模式(web)下 pwsh 也变成 bash」并让模型工具面与 Linux 对齐。两者互补、 可同时安装、互不冲突:
| dsh-gitbash-preset | dsh-all-gitbash | |
|---|---|---|
| 作用对象 | 极简模式(minimal preset)的 bash 工具 | 完整模式(web)的 pwsh 执行器 + 工具面 |
| 形态 | agent preset 安装器(需重启装配) | 运行时注入/装配的宿主插件 |
| 开关 | 无(preset 常驻) | 一键开关(UI 滑块 / settings.yaml) |
| 安装 | dsh plugin --profile web add @icelily/dsh-gitbash-preset | dev_inject_plugin 或 dsh plugin add |
兼容性说明
| 关注点 | 结论 |
|---|---|
| bash 工具名 | minimal-gitbash 会话里 preset 的 bash 工具注册在会话 scoped 层,遮蔽本插件的全局 bash 工具——两边都是 Git Bash,模型看到哪个都是 bash,无重复/无冲突 |
| 执行器 | preset 在会话 realm 内自供 shell(gitbash-executor),本插件改道的是宿主全局 pwsh 执行器——互不触碰 |
| pwsh 工具删除 | minimal 会话本来就没有 pwsh 工具,本插件的删除逻辑找不到目标即空操作 |
| 沙箱 | 两者一致:MSYS 在受限令牌沙箱内无法启动,均门控到 danger-full-access 并给升级指引 |
| 一键开关 | 只影响本插件的 web 改道装配,对 minimal preset 会话无副作用 |
| PATH 垫片 / 设置 API | 两者各自独立,无交叉 |
推荐用法:极简模式(minimal-gitbash preset)与完整模式(web + dsh-all-gitbash) 按需选用;两个都装上,极简会话走 preset 的 bash,完整会话走本插件的 bash,行为一致。
安装
运行时注入(免重启):
# 1) 构建(零依赖,无需 DSH checkout)
npm run build
# 2) 用 dsh-super-injector 注入(会话内调用 dev 工具)
dev_inject_plugin {"dir": ".../dsh-all-gitbash"}
持久安装(重启后由 profile bundles 装配):
dsh plugin --profile web add @icelily/dsh-all-gitbash
卸载:dev_uninject_plugin {"match": "dsh-all-gitbash"}(argv 还原、bash 工具注销、
pwsh 工具恢复、PATH 垫片移除)。
配置
| 字段 | 默认 | 说明 |
|---|---|---|
enabled | true | 总开关:false = 完整还原为原装 pwsh(settings 面板 / settings.yaml 一键切换,运行时生效) |
bashPath | 自动探测 | 显式 Git Bash 路径;缺省按 GIT_BASH env → 注册表 → 安装根 → PATH(跳过 WindowsApps WSL 存根)→ 兜底 bash |
sandboxGate | true | 受限沙箱下快速失败并给升级指引(MSYS 无法在受限令牌内启动) |
stripPreamble | true | 剥离 dsh-pwsh-local 的 UTF-8 preamble |
translateEnvVars | true | $env:NAME → ${NAME} |
translateDrivePaths | true | C:\... → /c/... |
registerBashTool | true | 注册原生 bash 工具 |
disablePwshTool | true | 从模型工具面移除 pwsh 工具(只留 bash,避免先 pwsh 报错再换 bash);false = 保留 pwsh(legacy 别名语义) |
pathShim | true | PATH 注入 pwsh/powershell → git bash 脚本垫片 |
shimDir | ~/.dsh/dsh-all-gitbash/bin | 垫片目录 |
除
bashPath/shimDir外,所有开关都可通过 settings 运行时切换(见「一键开关」)。
开发与测试
npm run check # 语法检查(src + lib,host + client)
npm run test # 25 个单元测试:翻译 / 探测 / 门控 / argv 改道 / 描述 patch / PATH 垫片 / toggle 周期
npm run build # src → lib(纯 JS,零构建依赖)
实测验证矩阵(本机):
bash工具输出MINGW64_NT-10.0-26100(真实 MSYS)、pwd为/d/...;模型工具面无pwsh$env:USERPROFILE→C:\Users\ROG;cat C:\Windows\win.ini正常读(翻译生效)- 退出码透传
[exit code: 3];后台任务正常(bg-done+ MINGW64) - 一键开关往返:关闭 → pwsh 工具恢复(registry 4 层还原)、bash 注销、PATH 垫片移除;开启 → pwsh 再禁、全部恢复
- 卸载即净:uninject 后 argv 还原、bash 工具注销、描述还原、垫片清除
FAQ
对 AI 来说,all-gitbash 模式和 Linux 原生调用 bash 有区别吗?
语法层 100% 一致(都是 bash -c、POSIX 语义、同一套退出码/超时/后台契约),
但从第一轮对话起模型能感知三处差异:
- 环境身份:
uname -s返回MINGW64_NT-10.0-26100,pwd是/d/...,$HOME是/c/Users/...;工具描述与提示词也声明这是 Git for Windows bash; - 双路径心智(已收敛):文件工具跑在 Node(Windows 路径
D:\...),bash 跑在 MSYS(POSIX 路径/d/...)——提示词已建议统一用盘符:/...正斜杠形式(两域 交集语言:Node fs 与 MSYS bash 都直接接受),翻译垫片兜底反斜杠抄写; - 沙箱门控:Linux 的 workspace-write 下 bash 照常执行(Landlock 限文件不拦 shell), 而 MSYS 在受限令牌内无法启动,受限模式下每条命令都会快速失败并提示升级——想获得 最接近 Linux 的体验,建议 Git Bash 会话默认 danger-full-access。
为什么不在设置面板自动出现,还要插件自带开关行?
DSH 的 apiproxy 只对白名单内的 settings 命名空间开放 Web 读写(官方设计:
"a future registration does not become remotely readable or writable by default"),
插件命名空间会被 describe 过滤、mutate 拒绝。因此插件自带 webServer 路由
/api/dsh-all-gitbash 作为读写通道,设置页开关行走这个通道。
为什么不用官方「bash-restore 配方」(禁用 pwsh 栈、启用 bash 栈)?
dsh-base 文档的配方要求同时禁 pwsh-sandbox/tool-pwsh 并启用 bash-sandbox/tool-bash,
是 composition 层改动、需重启,且 win32 上 bash 栈被禁的原因正是「bash 没有 Windows
runner」——受限沙箱下 bash 同样起不来。本插件保留 pwsh 执行器(沙箱链完好),
只把它的 argv 改道 Git Bash,运行时生效、可逆、可开关。
重启后开关状态?
settings.yaml 持久化 enabled,重启后保持;开关行随 boot 清单注入,刷新页面即恢复。
发布
# 构建 + 打包
npm run build && npm pack
# 发布 GitHub Release(dsh-super-injector 的 dev 工具)
dev_release_plugin {"dir": ".../dsh-all-gitbash", "version": "0.1.0"}
版本历史见 CHANGELOG.md。
License
MIT