前言¶
DeepSeek Harness(DSH)在执行需要授权的工具调用时,默认只在主对话框里弹出审批卡片。窗口被最小化,或你正在其他应用里工作时,这条「等你点一下」的请求容易一直挂着,直到你切回 DSH。社区桌宠插件 dsh-pet 可以把一个小宠物常驻在桌面角落;若在宠物头顶也能看到同款审批、直接点「批准」或「拒绝」,就不必为了单次授权来回切换窗口。下面介绍非官方插件 dsh-pet-approval(维护者 joesl3epy-cloud,分类 admin-security)如何做到这一点。
这是什么¶
dsh-pet-approval 把 DSH 的权限审批同步送到 dsh-pet 桌宠的气泡里:宠物头顶弹出小卡片,点「拒绝」或「批准」(= 允许一次)即生效。对话框里的审批卡片照常显示;两条通道同时开放,谁先点谁生效,后点的那张自动失效、无副作用。
本插件与 DeepSeek、DSH、dsh-pet 的维护者无隶属关系,不代表官方立场。当前版本 0.3.1,许可证 MIT,peer 依赖 dsh-pet >= 0.3.7(可选:未装 dsh-pet 时仍可加载,只是没有桌宠通道)。
它解决什么问题¶
DSH 权限审批默认只出现在对话框。桌宠常驻视线内,把待审批单放到宠物头顶,相当于把「需要你确认」推到前台,减少因忘记切回 DSH 而长时间挂起的情况。
核心功能与工作方式¶
审批流经 DSH 的 approval/request 瀑布时,本插件并行开启两条路:
- GUI 通道:与官方行为一致,
next()走 DSH 自带审批卡片。 - 桌宠通道:在本机回环 HTTP(
127.0.0.1,端口区间 49395–49400)挂待审批单;dsh-pet 渲染端在宠物头顶显示气泡卡片,用户操作后POST /answer把结果送回 DSH。
两条通道没有「先桌宠、后对话框」的等待。桌宠若先答,插件会把注册审批单时的 request.signal 换成自管的 AbortController,桌宠一答就 abort,对话框那张卡随之消失(若未来 DSH 把 signal 改成只读,会记 swap fail 日志,其余功能仍可用,对话框卡片需手动关)。
双通道只结算一次:每个待审批单有 settled 标志;第一次有效回答后加锁,另一通道再提交会得到 404,结果不变。
安全相关(admin-security):
- 每个 profile 在插件
apply()时生成随机凭据(64 位十六进制),经pet-approval-runtime.json与index.html中data-token传给渲染端;请求头x-pet-token,宿主侧crypto.timingSafeEqual比对。Origin校验保留为辅助,不作为唯一鉴权依据。 - 高风险请求在桌宠端不能选「批准」:UI 藏按钮,服务端对
allowed-once且启发式assessRisk === 'high'返回 403(启发式依据toolName与 reason/参数片段,例如sudo、rm -rf、写~/.ssh等模式)。「拒绝」始终允许。
没有「自动批准」:超时只会收缩桌宠渠道或继续等 GUI,不会替用户做决定。
安装与启用¶
本包尚未发布到 npm,需在 profile 里用本地绝对路径安装(不要使用未在文档中出现的 dsh plugin add 拼接命令)。
# 1. 在 profile 的 package.json 里加本地依赖(dependencies,绝对路径)
cd ~/.dsh/profiles/<profile>
# "dsh-pet-approval": "file:/绝对路径/dsh-plugins/pet-approval"
# 2. 用 DSH 自带的 pnpm 安装(示例路径为 macOS 应用内 runtime)
node "/Applications/DeepSeek Harness.app/Contents/Resources/runtime/primary-runtime/dependencies/pnpm/bin/pnpm.mjs" install --dir .
# 3. 在同一 package.json 的 dsh.profile.bundles 里登记
# "...", "dsh-pet-approval"
# 4. 重启 DSH
启动时会自动检查并重放 dsh-pet 渲染端补丁(向 helper 目录复制 pet-approval.js,并在 index.html 的 </body> 前追加带 data-dsh-pet-approval 的一行 script)。不等重启时可手动执行:
node node_modules/dsh-pet-approval/install.mjs # 打印补丁到的 profile 与目录,不打印 token
node node_modules/dsh-pet-approval/check.mjs # 端到端自检
卸载补丁:
node node_modules/dsh-pet-approval/uninstall.mjs
配置¶
在 DSH profile 配置中可写:
- id: pet-approval
name: dsh-pet-approval
config:
enabled: true # false = 不监听端口、不等待桌宠,审批完全回落到 GUI
profile: desktop # 可选;不给则从 DSH_PROFILE / 包路径推断
dshHome: null # 可选;不给则用 DSH_HOME,再退 ~/.dsh
典型用法与诊断¶
日常无需额外命令:装好 dsh-pet 与本插件、启用 bundle 并重启后,出现权限审批时对话框与桌宠气泡会同时出现,在任意一侧点「批准」或「拒绝」即可。
排查问题时:
node node_modules/dsh-pet-approval/check.mjs
- 宿主日志:
~/.dsh/dsh-pet-approval/host.log(完整桌宠审批大致为asked→pet answered/pet gave up→decided via=pet|gui)。 - 渲染端:宠物窗口 DevTools,前缀
[dsh-pet-approval]。
手动探活(需 token,不带则 401):
HELPER=$(dirname "$(grep -rl data-dsh-pet-approval ~/.dsh/*/runtime/electron-helper/index.html 2>/dev/null | head -1)")
TOKEN=$(node -e 'console.log(JSON.parse(require("fs").readFileSync(process.argv[1],"utf8")).token)' "$HELPER/pet-approval-runtime.json")
curl -s -H "x-pet-token: $TOKEN" http://127.0.0.1:49395/health
项目内测试:node --test test/(README 记载 29 项)。
适用场景与注意¶
适合谁:已在用 DSH + dsh-pet、希望权限审批不绑死在主窗口、又能接受双通道「谁先点谁算」语义的用户。
务必注意:
- 插件在当前 DSH 进程权限下运行,安装前应自行阅读源码与 MIT 许可证;社区目录 SkillHub 插件页 与 GitHub 均为独立生态站点,非 DeepSeek 官方应用商店。
- 回环端口仅本机有意义;token 主要防浏览器里任意页访问
127.0.0.1,挡不住同用户本机其它已信任进程。 - 风险分级为启发式,不是完整沙箱替代;未命中模式的高危操作仍可能在桌宠上被批准,敏感操作建议只在对话框处理。
- README 写明仅在 macOS(Apple Silicon) 与 DSH 0.2.1-rc.5、dsh-pet 0.3.7 组合下实测;Windows / Linux 未测试。安装示例中的 pnpm 路径来自 macOS 应用包布局,其它系统需按本机 DSH 安装位置调整。
依赖 dsh-pet 渲染结构;不匹配时会退化为静态卡片,审批仍在 GUI 完成,不会卡死。
结尾¶
dsh-pet-approval 在不动 DSH 与 dsh-pet 源码的前提下,用 Cordis 接口与运行时补丁把审批双通道汇合到桌宠气泡,并加上 profile 级 token 与高风险服务端拦截。若你已经在桌面养了 dsh-pet,又常被对话框里的权限卡片打断节奏,可以按本地路径安装并在 bundle 中启用,用 check.mjs 验证链路。
- 目录页:https://www.skillhub.cn/plugins/joesl3epy-cloud/dsh-pet-approval
- 源码与完整说明:https://github.com/joesl3epy-cloud/dsh-pet-approval