deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
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。
shell 工具永远只使用该设置,不暴露终端参数给模型。设置通过 DSH settings 系统持久化(settings.yaml)。ctx.shell 能力接缝:DSH 自带的沙箱化 pwsh 工具保持原样可用;本插件的 shell 工具是额外的多终端入口。ctx.subprocess seam 派生进程:进程树终止(Windows taskkill /T)、SIGTERM→grace→SIGKILL、输出 spill 文件,与官方 dsh-tool-bash / dsh-tool-pwsh 行为一致。jobs registry,支持 run_in_background / job_output / job_kill。插件带官方 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。
# 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. 重启 dsh web
⚠️ 不要在本项目里跑
npm install:它会删掉上面第 2 步的 junction,转而给插件装一份独立的@deepseek-ai/*副本 —— 插件和宿主就不再共用模块实例,宿主升级后插件会停在旧 API 上 (本项目曾因此停在 0.1.0-rc.6)。只刷新 lock 时用npm install --package-lock-only。
兼容性:要求 DSH ≥ 0.1.5-rc.1。0.1.5 把浏览器模块表里的
@deepseek-ai/dsh-client-runtime改名为@deepseek-ai/dsh-client-store且只按精确裸名命中;旧 bundle 在新宿主上会报Failed to load plugins/require(...) missed the module table。另:0.1.5 的 Web 设置面改为
settings.describe()动态枚举,不再有 namespace 白名单 (settings-not-exposed已不存在),install.ps1里的白名单 patch 只是历史遗留、可忽略。
当前已不再需要手动改 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 工具后,执行命令时自动使用你选择的终端(工具不暴露终端参数,模型无法更改你的选择):
shell(command: "git status") 走 Git Bashshell(command: "ls -la /mnt/d/WorkSpace") 走 WSL;传 distro: "Ubuntu" 可指定发行版shell(command: "Get-Process node") 走 PowerShellshell(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 账号已启用 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 工具在 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 终止会话send 会等待输出稳定(300ms 静默,上限 5s)返回完整回复;输出超 1MB 时报 truncated 提示\\n(或 \r)结尾表示回车shell 工具走 DSH 官方沙箱接缝(ctx.sandboxPolicy + ctx.sandbox):
danger-full-access 会话直接执行(不包装)。ctx.sandbox.confine 包装 argv —— 与官方 executor 相同的 fail-closed 语义:请求受限模式但无可用后端时抛 SandboxUnavailableError,拒绝裸跑。CreateFileMapping Win32 error 5 终止),因此 Git Bash 在受限模式下也不经沙箱包装;结果报告 enforcement: gitbash-unconfined。enforcement: wsl-isolation)。[sandbox: file access denied under <mode> mode] 与同轮升级提示;模型可凭 sandbox_permissions + justification 发起一次升级(经 ctx.approval 用户审批),与官方 bash/pwsh 工具完全一致。shell 工具在受限模式下:PowerShell 会经 ctx.sandbox.confine 包装(fail-closed);Git Bash 因 Cygwin/MSYS2 与 Windows ACL 受限令牌不兼容而不包装(与 dsh 进程同权限);WSL 因独立 Linux VM 不包装。它是额外的多终端入口,不享受官方 pwsh 工具的 ConstrainedLanguage 限制。DSH 的文件操作工具(read/write/edit)仍受文件沙箱约束。仅在你信任的会话中使用;需要受沙箱保护的 PowerShell 时请继续使用官方 pwsh 工具。
wsl -e bash -lc ... 命令正常;交互会话建议直接用 Windows Terminal / WSL 终端,或重试。signal 的 SIGINT 映射为 Ctrl+C(\x03),其他信号(SIGTERM / SIGKILL / SIGTSTP / SIGHUP)退化为终止会话。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 → lib/client.js CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。