dsh-path-toolv1.0.0

zetako/dsh-path-tool

安全管理 MIT 最近更新 2026-11-11
0Stars
0Forks
0待解决 Issue
安装命令 dsh plugin --profile web add github:zetako/dsh-path-tool#7d31a8e3781fd82024419987a114e5b2ce4380b3

介绍

为 DSH 的 shell 命令注入 PATH 目录,并放宽 workspace-write 沙盒的可写目录(Seatbelt / bwrap / Landlock),带图形配置页。 | Inject PATH for DSH shell commands and widen workspace-write sandbox roots, with a GUI config page.

标签

cordis cordis-plugin deepseek-harness dsh dsh-plugin homebrew javascript linux macos nodejs path sandbox

概述

dsh-path-tool

English | 中文

终端路径工具(插件页显示名)。让 DSH(DeepSeek Harness)里的 shell 命令找得到非默认 PATH 下的工具,并让受限沙盒下的构建写得了自己的缓存目录。两项能力都在 Plugins 页提供图形配置界面。

它解决什么问题

DSH 执行 shell 命令用的是 bash -c,非交互、非登录、不读任何 rc 文件。这意味着:

  • macOS 上从 Finder/Dock 启动的 DSH 只继承 /usr/bin:/bin:/usr/sbin:/sbin,看不到 /opt/homebrew/bin,于是 git、go、rg、mysql 这些 Homebrew 装的东西在模型眼里全部「不存在」;
  • 即使用 ~/.zshenv 设了 PATH 也没用,因为 bash -c 不加载它;
  • DSH 自己也不会读你的 shell 配置:BOOTSTRAP_NAMES 明确拒绝从 .env 设置 PATH,ctx.shellEnv 注册表只管 DSH_* 命名空间。

另一半问题是沙盒。workspace-write 模式只放行「会话工作区 + /tmp」,而 Go 必须写 GOCACHE(~/.cache/go-build)与 GOMODCACHE(~/go/pkg/mod)。这些目录在沙盒外,于是每条 go build 都会触发一次沙箱升权审批——本该只在你真正要改工作区外的文件时被打断。

本插件把这两件事变成一次性配置。

功能

能力说明
PATH 注入把指定目录前置或后置进每条 shell 命令的 PATH,覆盖前台、run_in_background 与超时转后台三条执行路径
沙盒放宽workspace-write 下额外放行你指定的可写目录,后端自动适配 macOS Seatbelt、Linux bwrap 与 Landlock 回退
图形配置在 Plugins 页逐条增删目录、切换前置/后置、一键恢复当前平台的默认项,保存后下一条命令即生效
平台默认值默认目录按宿主平台生成(macOS /opt/homebrew/*、Linux /usr/local/*),不会给你塞一堆本机不存在的路径
零依赖不打包、不构建,react 由 DSH 提供,其余控件自绘

工作原理

flowchart LR
    subgraph Host["DSH Host"]
        P["Plugins 页配置表单<br/>(client.js)"] -->|"PUT /dsh-path-tool/prefs"| R["偏好路由<br/>(index.mjs)"]
        R -->|"prefs.json"| F[("$DSH_HOME/dsh-path-tool/prefs.json")]
        R -->|"内存权威副本"| E["包装后的 ctx.shell<br/>resolve / execute"]
        R --> S["包装后的 ctx.sandbox<br/>confine()"]
    end
    E -->|"spec.env.PATH"| B["bash -c"]
    S -->|"改写 argv profile"| C["bwrap / Seatbelt / landlock-run"]

PATH 注入

插件包装 ctx.shell 实例上的 resolve 与 execute。execute(spec) 是所有执行请求的唯一收口,因此在这里改写 spec.env.PATH 就能覆盖全部执行路径,且不会重复合并。偏好保存在内存里,每次执行都读最新值——改完配置不需要重启。

不能通过重新 provide 一个同名 service 来替换 ctx.shell:cordis 会抛 service "shell" has been registered。

沙盒放宽

插件包装 ctx.sandbox 的 confine(),在它返回的 argv 里追加可写目录:

沙盒后端追加方式
Seatbelt(macOS)往 SBPL profile 末尾追加 (allow file-write* (subpath "…"))
bwrap(Linux 首选)在 -- 之前插入 --bind <dir> <dir>,靠后的挂载覆盖只读根
Landlock(Linux 回退)在 -- 之前插入 --rw <dir>

沙箱本身没有改变,只是可写集合变大。read-only 与 danger-full-access 完全不受影响。三种后端都要求授予的路径真实存在,插件会在保存偏好时自动创建缺失的目录。

只放宽 shell,不放宽文件工具。 文件工具(dsh-fs-sandbox)的可写集合仍按原规则计算,模型不能借这条路径读写你配置的缓存目录。这是有意为之。

安装

要求:DSH >=0.2.1-rc.5 <0.3.0(见 package.json 的 engines.dsh),Node.js ≥ 22。

方式一:从本地目录安装(推荐用于本仓库)

# 在 profile 里以 link 方式挂载本目录
dsh plugin --profile web add link:/绝对路径/dsh-path-tool

也可以直接把目录 link: 进 ~/.dsh/profiles/web/package.json 的 dependencies,并在 dsh.profile.bundles 里加上 "dsh-path-tool"。

方式二:在 Plugins 页操作

打开 DSH Web → Plugins → 安装,把 dsh-path-tool 指向本目录即可;安装器同样接受本地路径。

安装后重启 dsh web(或等 HMR 热加载),插件会自动插入自己的配置行。

配置

Plugins 页 → 已安装 → 终端路径工具(dsh-path-tool)→ 配置,或用该行右侧的 Configure 入口。

配置项说明默认值
追加的 PATH 目录必须是绝对路径,非绝对路径会被忽略;重复项自动去重macOS:/opt/homebrew/bin、/opt/homebrew/sbin、/opt/homebrew/opt/mysql-client/binLinux:/usr/local/bin、/usr/local/sbin、~/.local/bin
注入位置「前置」让这些目录优先于系统 PATH;「后置」只在系统 PATH 找不到时才生效前置
workspace-write 额外可写目录仅在 workspace-write 下生效;不存在的目录会自动创建GOCACHE 与 ~/go/pkg/mod

偏好以 $DSH_HOME/dsh-path-tool/prefs.json 为权威(DSH_HOME 缺省为 ~/.dsh)。也可以直接编辑该文件,或用路由读写:

# 读取当前偏好、平台默认值与沙盒接入状态
curl -s http://127.0.0.1:3080/dsh-path-tool/prefs | jq

# 覆盖偏好(PUT 与 POST 等价)
curl -s -X PUT http://127.0.0.1:3080/dsh-path-tool/prefs 
  -H 'content-type: application/json' 
  -d '{"pathEntries":["/opt/homebrew/bin"],"mode":"prepend","sandboxRoots":["/Users/me/.cache/go-build"]}'

GET 的响应形如:

{
  "ok": true,
  "prefs": { "pathEntries": ["…"], "mode": "prepend", "sandboxRoots": ["…"] },
  "defaults": { "pathEntries": ["…"], "mode": "prepend", "sandboxRoots": ["…"] },
  "status": { "platform": "darwin", "sandboxAttached": true }
}

status.sandboxAttached 为 false 时配置界面上会出现提示——它表示 Host 侧没有可用的 ctx.sandbox,此时「额外可写目录」不生效(PATH 注入不受影响)。

安全提醒:dsh-host-webserver 本身不做鉴权,它靠绑定回环地址(默认 127.0.0.1)与 DSH 的 trusted-host 机制来限制访问。如果你用反向代理或 --trusted-host 把 Web UI 暴露给他人,那么任何能打开这个界面的人都能改写插件的偏好——包括往 PATH 里塞任意目录、放行任意可写路径。不要把带本插件的 DSH 暴露给不可信的用户。

验证

  1. PATH:在会话里让模型执行 which <你的工具>,应当命中你配置的目录。也可以直接看 Host 日志里的 [dsh-path-tool] PATH prepend: …。
  2. 沙盒:把 workspace-write 下的 GOCACHE 指向配置的目录,跑一次 go build,不应再弹出沙盒审批。日志里的 [dsh-path-tool] workspace-write 额外可写: … 会列出实际授予的目录。
  3. 单元测试:
   npm test

兼容性

  • 声明 engines.dsh: ">=0.2.1-rc.5 <0.3.0"。DSH 在安装与 profile 启动时都会校验该范围,越界会要求显式豁免,而不是静默组合出问题。
  • Windows 不支持:本插件针对 POSIX 的 PATH 与 argv 形态实现,Windows 上会得到空的默认值、沙盒放宽不生效。DSH 官方 profile 目前也不以 Windows 为主目标。
  • 沙盒后端由 DSH 的沙盒包动态选择;插件只识别上述三种 argv 形态,遇到不认识的形态会原样返回、不做改写(并打日志说明)。
  • lib/prefs.mjs 在模块加载时读取 DSH_HOME,修改 DSH_HOME 需要重启 DSH 才生效。

卸载

dsh plugin --profile web remove dsh-path-tool

插件不会改动 DSH 自身文件,卸载后 PATH 与沙盒立即恢复原生行为。偏好文件 $DSH_HOME/dsh-path-tool/prefs.json 会保留,如不需要可手动删除。

开发

npm test                              # 15 个用例,覆盖三种后端、偏好持久化与包装还原
node --check index.mjs
node --check client.js

维护本仓库前请先读 AGENTS.md,里面记录了包装幂等、可选注入、偏好隔离等硬约束。测试的夹具与 DSH_HOME 都落在临时目录,不会污染你本机的配置。

许可

MIT © 2026 Zhang Yexi (zetako)

星级评价

0.0 按 GitHub Stars 换算的社区热度,非用户打分
Stars0
Forks0
待解决 Issue0
最近更新2026-11-11

基本信息

作者zetako
版本1.0.0
开源许可MIT
默认分支main
入库时间2026-11-11

插件信息来自公开 GitHub 仓库与 SkillHub,版权归原作者所有;安装前请自行审查仓库代码。