中文EN

dsh-terminal-shell

wsl已测通过npmMIT

选择 Windows 终端工具背后的 shell:PowerShell、本地 Git Bash 或 cmd.exe。

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

安装

dsh plugin --profile web add dsh-terminal-shell

沙箱测试结果

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

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

README

<p align="center">

<img src="./assets/readme/hero.svg" width="100%" alt="dsh-terminal-shell —— 在 Windows 上选择智能体终端工具背后的 shell:PowerShell、本机 Git Bash 或 cmd.exe">

</p>

dsh-terminal-shell

[English](README.md) | 中文

在 Windows 上选择智能体调用的终端工具背后用哪个 shell:PowerShell(pwsh)、本机 Git Bash(bash),或 cmd.exe(cmd)。在 设置 → 通用 里一个开关,仅对新会话生效:不改任何 preset 文件,不接管全局 ctx.shell。

v0.2.1 · MIT · Windows(DSH Desktop / Web shell) · engines.node >=22 · engines.dsh >=0.2.1-rc.2 <0.3.0

为什么要这个插件

DSH 0.2.1-rc.2 每个平台只带一个终端,Windows 上那个是 PowerShell:bash 家族被 dsh-base 里的 !!js process.platform === 'win32' 断言关掉,而 ctx.shell 是单实例服务(同一 context 内注册第二个会抛 service "shell" has been registered)。所以 Windows 会话里既没有 bash 执行器,也没有 bash 工具。

社区里常见的几种绕法,各有代价:

做法 · 代价 / 局限

改 dsh-base / profile 的平台断言 · 要动第一方组合;只影响那一个平面;需重启

自研 PTY / 自研工具 · 重写 60KB+ 的工具契约;容易与官方行为漂移

装一个全局 shell 替换器 · 会让所有会话(含没选的)跟着变;与宿主执行器冲突

本插件做的是「会话级隔离替换」,这正是它的优势:

  • 只对新会话、且只对你切换过的那个会话生效。 执行器只组装进每个新会话自己的 isolate('shell') 子树,宿主平面和其它会话都不动,卸载后无残留。
  • 三种方言、一个开关,装上什么都不变。 dialect 默认 pwsh,开箱行为与官方完全一致。
  • 不写死任何可执行文件路径。 Git Bash 在每台机器上运行时发现,同一个仓库放哪儿都能用。
  • 顺带覆盖侧边栏。 多一个选项,让侧边栏 新建终端 → 选择 Shell 菜单启动本机 Git Bash,而不是 WSL 的 bash——原版菜单做不到这点。

除了 Git Bash,cmd 方言用于你想要 Windows 原生行为、而非 POSIX 层的场景:原汁原味的 cmd.exe 批处理语义(.cmd 脚本、%VAR% 变量展开、原生管道与重定向),且不依赖 MSYS。它是复用官方工具契约的一次性执行器,模型可像操作系统本身那样驱动纯 cmd。

超时、输出溢出、abort 归类、后台任务、sandbox_permissions 提权、会话 cwd、工具卡片、退出码标记等一律继承或复用官方实现。

工作原理

在 agent/created 时,插件只对一个新会话做如下装配:

shellCtx = agentCtx.isolate('shell')                 // 该 agent 私有的 shell realm
shellCtx.plugin(GitBashExecutor, {...})              // 执行器只在这个子树里可见
shellCtx.plugin(ToolBash, {...})                     // 注册出的 bash 落在 agent 自己的工具层
agentCtx.tools.restrict({ deny: ['pwsh'] })          // 只过滤「继承来的」工具
agentCtx.systemPrompt.section({ name: 'tool:pwsh', text: '' })  // 空文本 = 渲染时丢弃

restrict 只隐藏继承层,所以它恰好移除 preset 带进来的 pwsh,不影响本层注册的 bash(cmd 方言同时 deny pwsh + bash)。各步在会话结束时逆序释放,中途失败则回滚。只对新会话生效——工具目录在会话创建时装配,运行中无法替换。

<p align="center">

<img src="./assets/readme/settings-row.svg" width="100%" alt="「设置 → 通用」下的 Terminal shell 设置行(bash 方言):终端 Shell、Git Bash 路径、沙箱策略、极简模式,以及新增的「侧边栏终端」选项(本机 Git Bash)。">

</p>

设置 → 通用下的 Terminal shell 行(bash 方言)。高亮的最后一行 侧边栏终端,就是让侧边栏新建终端使用本机 Git Bash 的选项。

安装 / 启用

前置条件: Windows;DSH Desktop / Web shell >=0.2.1-rc.2 <0.3.0;用 bash 需本机装有 Git for Windows / MSYS2 / Cygwin;用 cmd 无需额外安装。

和其它 profile 插件一样安装,二选一:

  • 在应用内: 打开 插件 → 添加插件,填入包名 dsh-terminal-shell(或本仓库地址、本地目录路径),点 安装,再点 立即启用。
  • 命令行: dsh plugin --profile <profile> add dsh-terminal-shell —— 它会在 profile 内运行 pnpm,并自动把该 bundle 注册进 profile。也可换成本仓库地址或本地目录路径。

包自带 dsh.bundle.patch,只插入一行、不固定任何可执行文件路径:

- insert:
    - id: terminal-shell
      name: dsh-terminal-shell
      disabled: !!js process.platform !== 'win32'

安装或升级后必须重启 DSH——运行期插入的行只进入组合树,apply 要重启后才会被调用。在你切换方言之前,dialect 一直是 pwsh。

启用

重启后,设置 → 通用 底部会出现新的 Terminal shell 行(settings.general.item,id terminal-shell,order 60,locale terminal-shell)。在上面选方言即可;每个控件与 [配置参考](#配置参考) 里的字段一一对应。

<details>

<summary>原始界面截图(bash / cmd,中文界面——第一张早于「侧边栏终端」改名)</summary>

</details>


用法

行布局。 与官方通用设置行一致:左侧标题 + 一行说明 + 右侧控件,沿用官方设计变量、跟随主题。顺序: bash = 路径 → 沙箱策略 → 极简模式 → 侧边栏终端;cmd = 路径 → 沙箱策略 → 极简模式 → 代码页;pwsh 只显示方言行。

切换方言即触发一次扫描——选 shell 本身就是扫描,没有单独的「检测」按钮。路径框平时是可输入的输入框,扫描出多个候选时变成下拉。已选且仍有效的路径不会被后续扫描覆盖,写入或扫描失败会自动重试一次,挂载时既不扫描也不写配置。

沙箱策略(bash 用 confinedPolicy,cmd 用 cmdConfinedPolicy):

取值 · 行为

Bypass the sandbox(unconfined) · 受限 Windows 档位下直接以普通权限启动、不调 ctx.sandbox.confine();调用立刻成功,但命令不受文件沙箱约束

Request permission(escalate) · 先按官方方式进沙箱;MSYS 启动失败被标为 denied,模型收到官方提权提示后改用 sandbox_permissions: danger-full-access 重试

两者的默认值不同是有意为之:bash 默认 unconfined,因为 MSYS2 / Git Bash 在受限 Windows token 下无法启动(NtCreateDirectoryObject → 0xC0000022),若默认 escalate 则每条命令都要先失败一次再走审批;cmd 默认 escalate,因为 cmd.exe 在受限 token 下能正常启动,走真沙箱既安全又不失败。审批完全由第一方工具处理,插件只把 MSYS 启动失败归类为 denied。

极简模式(minimalMode,仅 bash):官方 minimal 预设带一个持久 pwsh 终端,所以 minimal 会话需要一次决定——leave(保留 pwsh)、oneshot(切成一发式 bash,默认)、variant(额外注册持久 minimal-gitbash 预设,官方 minimal 不动,无引用时自动移除,需对每个新会话单独选择)。

控制台代码页(cmdCodePage,仅 cmd):执行前先跑 chcp <codePage>>nul;默认 65001(UTF-8),是唯一能让非 ASCII 输出保持完整的取值。

Bash 发现顺序(bashPath 为空时):显式 bashPath → bashCandidates → 注册表 HKLM\SOFTWARE\GitForWindows 的 InstallPath → %ProgramFiles%\Git 等 → MSYS2 → Cygwin → 由 PATH 上的 git.exe 反推。WSL 被硬排除(System32\bash.exe、WindowsApps\bash.exe 是不同操作系统/文件系统)。发现只做文件系统 stat 加一次异步 reg.exe query,绝不 spawn bash --version。

cmd 发现(cmdPath 为空时):cmdPath → %ComSpec% → %SystemRoot%\System32\cmd.exe,不扫描磁盘;非 cmd.exe 的 cmdPath 视为未设置。

子进程 PATH:工具链 bin → usr\bin → bin → usr\local\bin → extraPath → 宿主 PATH,让 MSYS2 工具优先、同时保留原生 node / python。


配置参考

所有字段都是 .volatile(),经官方 configForms 呈现;设置行直接编辑其中一部分,其余仍可写进 profile patch。

patch 键 · 类型 · 默认 · 含义

dialect · 'pwsh' \ · 'bash' \ · 'cmd' · 'pwsh' · 终端方言

bashPath · string · '' · 显式 bash.exe 路径;空 = 自动发现

bashCandidates · string[] · [] · 额外的发现根 / 显式路径,在内置顺序之前尝试

autoDiscover · boolean · true · bashPath 为空时在会话装配阶段自动发现

discoverTimeoutMs · number · 1500 · 单次发现的时间上限

loginShell · boolean · false · 传 -l 读取登录 profile

extraPath · string[] · [] · 追加到子进程 PATH 的目录

pythonUtf8 · boolean · true · 导出 PYTHONIOENCODING=utf-8

confinedPolicy · 'unconfined' \ · 'escalate' · 'unconfined' · bash 在受限档位下的行为

cmdPath · string · '' · 显式 cmd.exe 路径;空 = %ComSpec% 回退

cmdCodePage · number · 65001 · chcp 代码页

`cmdC

…(truncated)

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

版本

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

链接

GitHub · Homepage · npm

同类插件