调用 WSL、nushell、MSYS2 与真实控制台执行命令
30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/15 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Nesarf/dsh-shell-surfaces该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:待复验
是什么
dsh 原生插件 · dev
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 16 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件
查看扫描证据(共 32 处,展示前 31 条)
- 写入本地文件lib/index.js:1017
appendFileSync(file, `${new Date().toISOString()}\tdisposed=${sessionId}\towners=${owners.join(',') || '-'}\n`); - 读取本地文件lib/surfaces.js:91
if (!existsSync(file)) return []; - 读取本地文件lib/surfaces.js:93
text = readFileSync(file, 'utf8'); - 读取本地文件lib/surfaces.js:743
if (/[ /]/.test(exe)) return existsSync(exe); - 执行外部命令来自配置/变量lib/surfaces.js:754
const result = spawnSync(probe.command, probe.args, { stdio: 'ignore', timeout: 5000 }); - 读取本地文件lib/usage.js:36
const parsed = JSON.parse(readFileSync(FILE, 'utf8')); - 写入本地文件lib/usage.js:54
mkdirSync(dirname(FILE), { recursive: true }); - 写入本地文件lib/usage.js:57
writeFileSync(temporary, `${JSON.stringify(usage, null, 2)}\n`, 'utf8'); - 写入本地文件lib/usage.js:58
renameSync(temporary, FILE); - 写入本地文件lib/runner.js:30
mkdirSync(dir, { recursive: true }); - 写入本地文件lib/runner.js:51
writeFileSync(file, text, 'utf8'); - 执行外部命令来自配置/变量lib/runner.js:76
child = spawn(argv[0], argv.slice(1), { - 执行外部命令来自配置/变量lib/runner.js:247
const helper = spawn(argv[0], argv.slice(1), { stdio: 'ignore', windowsHide: true }); - 写入本地文件lib/runner.js:322
writeFileSync(file, command, 'utf8'); - 执行外部命令来自配置/变量lib/runner.js:444
const spawned = spawnSync(spec.exe, argv, { encoding: 'utf8', timeout: 15000, windowsHide: true }); - 执行外部命令来自配置/变量lib/runner.js:469
const read = spawnSync(spec.exe, ['cli', 'get-text', '--pane-id', paneId], { - 执行外部命令来自配置/变量lib/runner.js:481
spawnSync(spec.exe, ['cli', 'kill-pane', '--pane-id', paneId], { encoding: 'utf8', timeout: 10000, windowsHide: true }); - 执行外部命令来自配置/变量lib/runner.js:536
const child = spawn(argv[0], argv.slice(1), { windowsHide: true, detached: true, stdio: 'ignore' }); - 读取本地文件lib/runner.js:556
if (existsSync(out)) { - 读取本地文件lib/runner.js:558
const parsed = JSON.parse(readFileSync(out, 'utf8')); - 写入本地文件lib/runner.js:619
mkdirSync(dirname(jobFile), { recursive: true }); - 写入本地文件lib/runner.js:620
writeFileSync(jobFile, JSON.stringify({ id, command: options.command, timeoutMs: options.timeoutMs }), 'utf8'); - 删除本地文件lib/runner.js:635
unlinkSync(resultFile); - 读取本地文件lib/runner.js:659
if (existsSync(resultFile)) { - 读取本地文件lib/runner.js:661
const parsed = JSON.parse(readFileSync(resultFile, 'utf8')); - 删除本地文件lib/runner.js:754
unlinkSync(file); - 执行外部命令来自配置/变量lib/sessions.js:36
const child = spawn(argv[0], argv.slice(1), { - 读取本地文件lib/discover.js:60
return readdirSync(dir); - 执行外部命令固定命令lib/discover.js:141
const result = spawnSync('wsl.exe', ['-l', '-q'], { encoding: 'buffer', timeout: 4000, windowsHide: true }); - 执行外部命令固定命令lib/discover.js:172
const result = spawnSync('wsl.exe', ['-d', distro, '--', 'bash', '-l', '-s'], { - 读取本地文件lib/discover.js:235
if (!existsSync(path)) continue;
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
机器的非 pwsh 执行面统一成一个 DSH 工具:WSL Linux 用户态、nushell 结构化管道、MSYS2 用户态(bash/zsh/fish/brush),以及给交互式程序用的真实控制台。
README
由 DeepSeek 最新模型翻译生成dsh-shell-surfaces
https://github.com/Nesarf/dsh-shell-surfaces —— 一个 DSH 插件,用 dsh plugin --profile <profile> add github:Nesarf/dsh-shell-surfaces 安装。
一个 DSH 工具,用来调用这台机器上 pwsh 之外的执行面:WSL Linux 用户态、nushell 的结构化管道、MSYS2 用户态(bash / zsh / fish / brush),以及给交互式程序用的真实控制台。
它之所以存在,是因为只写在纸上的规则不算能力。这些执行面的选择规则已经记录了一段时间,但会话想照着做,只能拼一条命令字符串交给 pwsh,然后祈祷引号能活着走完全程。现在它们可以直接调用了。
shell_surfaces(action="surfaces") what exists here, and where each was looked for
shell_surfaces(action="run", surface="wsl", command="grep -P '(?
展开完整文档(README 剩余 1 节)
dsh-shell-surfaces https://github.com/Nesarf/dsh-shell-surfaces —— 一个 DSH 插件,用 dsh plugin --profile <profile> add github:Nesarf/dsh-shell-surfaces 安装。 一个 DSH 工具,用来调用这台机器上 pwsh 之外的执行面:WSL Linux 用户态、nushell 的结构化管道、MSYS2 用户态(bash / zsh / fish / brush),以及给交互式程序用的真实控制台。 它之所以存在,是因为只写在纸上的规则不算能力。这些执行面的选择规则已经记录了一段时间,但会话想照着做,只能拼一条命令字符串交给 pwsh,然后祈祷引号能活着走完全程。现在它们可以直接调用了。 shell_surfaces(action="surfaces") what exists here, and where each was looked for shell_surfaces(action="run", surface="wsl", command="grep -P '(?<=Linux )[0-9.]+' /proc/version") shell_surfaces(action="run", surface="nu", command="open data.json | where n > 3 | to json") shell_surfaces(action="run", surface="msys", command="pacman -Q | wc -l") shell_surfaces(action="run", surface="pty", command="powershell -File install.ps1", send=["y\n"]) 为什么是一个工具,而不是七个 每个注册的工具都要花掉一部分上下文来写自己的描述。七个工具会把同一件事说七遍。选择规则——结构化管道用哪个执行面、只有 Linux 才有的工具用哪个、等待输入的程序用哪个——都写在这一个描述里,会话在挑选的那一刻正好读到。 它不是什么 * 不注入提示词,也不挂消息钩子。 它只注册一个工具,别的什么都不做,所以它不可能成为那个写出畸形消息的插件。 * 不是终端模拟器。 终端模拟器给人画文字,对子进程没有任何用处。唯一需要控制台的那个执行面直接跟 ConPTY 对话。 参数列表背后的事实 下面每一条都在本机实测过,每一条都决定了 argv 长什么样: | 事实 | 后果 | | 命令经过 shell 传递时可能被重新解析两次 | 命令以单个 argv 元素传递;脚本文件优先于内联字符串 | | MSYS2 的 /tmp 跟随 TMPDIR,而本机把它作为 Windows 路径传下去 | msys / zsh / fish 以 login shell 运行,这样环境会被规范化 | | brush 旁边没有 Cygwin 运行时,所以 /tmp 就是 <drive>:\tmp | brush 不加 login 标志,也不做 POSIX 路径假设;它的 PATH 需要 usr\bin 和 ucrt64\bin,否则每条外部命令都会失败,而 shell 却报告版本正常 | | PtyProcess.read 会阻塞 | 读取放在自己的线程上;一个同时决定何时停止的读取循环,会阻塞掉那个本该让它停下来的检查 | | 控制台要的是 Enter,也就是回车符 | send 会把结尾的换行(真实的、转义的或字面的)规范成 CR,只给一个裸答案时则补上一个 | | wsl.exe 有时会打印结果,然后拒绝退出 | 有输出的超时和没有输出的超时,上报方式不同;wsl.exe --shutdown 是重置手段(实测:冷实例 58 秒才应答,重置后同样的调用 8 秒,热态 0.13 秒) | 目录结构 | 路径 | 说明 | | lib/index.js | 工具本体:一个 shell_surfaces,动作有 run 和 surfaces | | lib/surfaces.js | 表:每个 surface 的路径、参数、环境,以及不可用的原因 | | lib/runner.js | 构造 argv、带溢出的有界输出、超时分类 | | scripts/pty_runner.py | 控制台:pywinpty、读取线程、剥离 ANSI、输出一份 JSON 报告 | | scripts/live-check.mjs | 每个 surface 各跑一条真实命令,走插件自己的代码路径 | | scripts/pty-gate.ps1 | 交互式夹具:为 pty 场景准备一个 Read-Host 提示 | | test/surfaces-test.mjs | 表、argv 形状、工具契约 | 验证 node test/surfaces-test.mjs # 55 checks, no host needed node scripts/live-check.mjs # one real command per surface on this machine node scripts/live-check.mjs wsl nu # or only some of them 每个 surface 也都真跑过(2026-10-15):wsl 返回了内核和 /proc 计数,nu 通过结构化管道返回了一个数字,msys 返回了它的 bash 版本和包数量,zsh 返回了参数展开结果,fish 返回了算术结果,brush 返回了一个转成大写的字符串,pty 用 y 应答了 Read-Host 提示,并打印出它走的分支。 如实说明边界 * Windows 优先。 它认识的 surface 就是这类机器上的:WSL 发行版、MSYS2、nushell、ConPTY。在 POSIX 上,平台本身只带一个 shell,所以这里的大部分东西在那边用不上。 * 它自身不做隔离:命令以 harness 进程的权限运行。文件沙箱和审批策略仍然作用于整个进程树。 * MSYS 系输出按 UTF-8 处理(设置了 LANG=C.UTF-8)。通过 surface 调起的 Windows 程序仍可能用 OEM 代码页应答。 * 如果 MSYS2 不在 D:\msys64,MSYS2 系 surface 需要 DSH_MSYS_ROOT;如果 nu.exe 不在 %LOCALAPPDATA%\Programs\nu\bin,nushell 需要 DSH_NU;pty surface 需要 PATH 上有 python,并且装好 pywinpty。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
Nesarf/dsh-shell-surfaces
调用 WSL、nushell、MSYS2 与真实控制台执行命令
相关插件 · 开发 / 工程
隐私简历生成器reactive-resume/reactive-resume
Reactive Resume 已迁至 GitHub 上的…
★ 45,125已汉化MCP
71.7
AI 架构文档生成器sopaco/deepwiki-rs
🚀 Litho 已进化为 Terrain —— 给你的 AI 智能体一张会呼吸的代码库地图。
★ 3,157已汉化DSH
70.8
长时任务执行闭环AMAP-ML/LongHorizon-Harness
面向 Computer-Use Agent 的 Loop Engineering
★ 1,764已汉化DSH
70.5
AI 编程纪律方法包GanyuanRan/Aegis
让 AI 编程 agent 变得可信:少返工、更安全、说“完成”前先给证据。
★ 1,384已汉化DSH
69.6
多代理编排运行时Enderfga/claw-orchestrator
面向编程智能体的运行时。把 Claude Code、Codex、Antigravity、Grok…
★ 586已汉化MCP
69.4
记忆进化插件csyangwen/dsh-memory-evolve
dsh-memory-evolve 使用场景指南
★ 461已汉化DSH
67.9