dsh-plugin-guard

DSH PLUGIN安全与权限

仓库 wodaimnd/dsh-plugin-guard · npm @local/dsh-plugin-guard

安全与权限 L5 · 运行验证通过 安全审查:低风险 可信度:金 可安装插件
安装这个插件

DSH 插件运维台:体检已装插件为何挂不上,定位装载行 name 解析失败并就地自愈,改前需逐条授权、可撤销。

一句话选型结论

按资料字段整理

dsh-plugin-guard 是安全与权限类的 DSH 可安装插件,验证等级 L5 · 运行验证通过,安全审查为低风险,列出 5 项功能,有可直接复制的安装命令。验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么;涉及密钥或系统权限的,建议先在隔离环境试装。

分类安全与权限 收录类型可安装插件 验证等级L5 · 运行验证通过 安全审查低风险
验证等级 L5 L5 · 运行验证通过
GitHub 星标 0 复刻 0 · 未关闭 issue 0
最近更新 2026-11-04 创建于 2026-11-04
README 12.8 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
dsh plugin --profile web add github:wodaimnd/dsh-plugin-guard#v0.1.1
  1. 1
    确认版本与运行环境

    兼容的 DSH 版本为 0.2.2-rc.1;版本不匹配时安装会报错。

  2. 2
    执行安装命令

    在 DSH 里执行上面的命令;多包仓库要注意区分具体子包名,别装错包。

  3. 3
    确认已挂载

    用 dsh plugin list 查看列表里是否出现这个插件,出现即挂载成功。

  4. 4
    试跑并检查权限

    加载后跑一个最小用例,确认它能正常工作;同时看它申请了哪些文件、命令或网络权限。

兼容 DSH 版本0.2.2-rc.1版本不匹配时安装会报错
Node.js 要求未标注来自仓库 package.json 的 engines 字段
前置依赖无需要同时安装的同级依赖
npm 包名@local/dsh-plugin-guard可用 npm view 查看包信息

能做什么

5 项功能
字段来自项目仓库与公开索引,中文说明由本站标注

dsh-plugin-guard:DeepSeek Harness 的插件运维工作台

  • 体检已装插件挂载故障
  • 装载行 name 解析自愈
  • 计划逐条勾选授权
  • 装前静态体检
  • 按 journal 逐字节撤销

适用场景

代码评审存储

上游标签

deepseekdshdsh-plugin

验证等级与安全审查

L5 · 运行验证通过
自动化流程结论,不是人工审核
验证等级L5 · 运行验证通过在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来
安全审查低风险静态分析结论,未标注不代表已通过审查
仓库健康度活跃按仓库活跃度与最近更新时间给出
可信度金综合仓库活跃度与验证结果

上面的结论来自上游最近一次自动化验证(2026-11-10): 同一套检查会在插件发新版后重跑,页面显示的是最新一次的逐项结果。

逐项检查结果

L1 · 已找到 ✓ 通过
  • L1.0_DEFAULTED_FROM_L3 由 L3 推定 默认通过——L3 安装规范已通过(全库 L3 扫描策略)
L2 · 结构化 ✓ 通过
  • L2.0_DEFAULTED_FROM_L3 由 L3 推定 默认通过——L3 安装规范已通过(全库 L3 扫描策略)
L3 · 安装规范 ✓ 通过
  • L3.1_INSTALL_COMMAND_PARSED 安装命令已解析 方式:安装规范解析
  • L3.2_DSH_VERSION_DECLARED DSH 版本已声明 方式:DSH 版本声明
L4 · 安装已测 ✓ 通过
  • L4.1_INSTALL_EXECUTED_CONFINED 受限沙盒内执行安装 方式:沙盒安装执行
  • L4.2_INSTALL_SUCCESS 沙盒安装成功 方式:沙盒安装执行
  • L4.3_ARTIFACT_CONFIRMED 安装产物已确认 方式:沙盒安装执行
L5 · 运行已测 ✓ 通过
  • L5.1_INSTALL_PASSED_SANDBOXED 沙盒安装通过 方式:沙盒安装执行
  • L5.2_WEB_BOOT_READY Web 启动就绪 方式:Web 启动
  • L5.3_HTTP_SERVED HTTP 服务响应 方式:HTTP 请求
  • L5.4_PLUGIN_INVENTORY_ACTIVE 插件清单中已激活 方式:插件清单查询

风险详情

  • 结论说明 静态扫描 低;动态审计无结论(以下以静态为准)→ 总评级 低。
  • 风险计数 严重 0 / 高 0

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 验证等级 L5:安装和运行都在沙盒里跑通过,装完能直接用的概率高。
  • 静态安全审查为低风险,没有发现明显可疑行为。
  • 有可直接复制的安装命令,不用自己翻文档找入口。
  • 标注了兼容的 DSH 版本(0.2.2-rc.1),按版本装不容易报错。
  • 列出了 5 项功能,能直接看出它解决什么问题。

先想清楚的地方

  • 没有声明 Node.js 版本要求,版本不匹配可能装不上。
  • 验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么。

更适合

  • 需要在安全与权限场景里给 DSH 补能力的人。
  • 想装完就能用、不想自己排依赖的人。
  • 能接受在本地装依赖、愿意自己确认权限的人。

不太适合

  • 只使用 DSH 官方内置能力、不接受第三方插件的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
插件验证等级安全审查星标兼容版本安装命令
dsh-plugin-guard当前 L5 · 运行验证通过 低风险 0 0.2.2-rc.1 有
dsh-infinite-gen-4 未做沙盒验证 未标注 1,611 未标注 无
cc-safety-net 未做沙盒验证 未标注 1,591 未标注 无
dsh-wallpaper-engine L5 · 运行验证通过 低风险 1,018 0.2.0-rc.2 等 10 个 有
api-relay-audit L5 · 运行验证通过 低风险 875 0.2.0-rc.2 等 10 个 有
hol-guard L4 · 沙盒安装通过 不在扫描口径 828 未标注 有

仓库档案

安全与权限
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方wodaimnd仓库 dsh-plugin-guard · 默认分支 main
分类安全与权限security
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言JavaScript仓库主语言
许可证MIT商用或二次分发前请确认条款原文
星标 / 复刻 / issue0 / 0 / 0收录时的数值,非实时
创建 / 更新2026-11-04 · 2026-11-04最后推送 2026-11-04
本站收录2026-11-05首次进入本站目录的时间

README 全文

12.8 KB
作者原文,中文版优先;只做安全转义,不改内容

@local/dsh-plugin-guard —— 插件运维台

把 dsh-compat-vet 的审查修复层与 dsh-forge 的锻造台合成一个插件,
并补上两者都没有的那一格:装载行的 name 能不能被 loader 解析。

一个侧栏入口、一块工作台,三件事:

能力 回答什么问题 什么时候用
体检 guard_audit 已装的插件里,哪些装上了却挂不上?哪些 bundle 解析失败 / peer 不满足 / 装了没启用 / tool id 冲突? 插件「装了没反应」、面板不见了、设置页少了东西、升级 dsh 之后功能消失
计划 + 授权 guard_plan → guard_apply 要改哪几个字节、可不可逆、要不要重启;你勾选哪些才执行哪些 准备修,但不想让工具擅自动别人的包
自愈 guard_heal 把「name 解析不了」就地修好,幂等、可 dry-run、置信度不足不猜 想彻底不用管
装前体检 guard_check_bundle 我准备装的这个包写得对不对(manifest / patch / 语法 / client 包装器 / locale / slot / 副作用 / skill 预算) 自己写插件、或装第三方包之前
撤销 guard_undo 按 journal 逐字节写回 修完发现不对

1. 它补的那一格:装载行解析

这是旧 compat-vet 查不出来的一类故障,也是本插件存在的理由。

故障长什么样

某个插件装在 profile 里、dsh.profile.bundles 里也有它、node_modules 里文件齐全,
但:

  • 设置页里没有它的那一项
  • 输入框的模型选择器里没有它的分组
  • 它该有的数据目录从未被创建
  • dsh 日志里一行都不提

为什么

它自带的 cordis.patch.yml 里,装载行写的是裸包名,而包本身是 scoped 安装:

- insert:
- id: our-free-model
name: 'dsh-our-free-model'     # ← 真名是 @ebony-vinyl/dsh-our-free-model
config: {}

loader 拿这一行的 name 去走 Node ESM 解析:

  • cordis-plugin-loader/src/config/entry.ts → this.parent.tree.import(name, baseUrl)
  • dsh-app-boot 的 HostResolvedRootInclude.import:裸名按 dsh 安装目录解析,
    scoped 名 / 相对路径按 profile 目录解析

裸名在 profile 的 node_modules 与 dsh 安装目录里都不存在(profile 里只有 @ebony-vinyl/ 这一层),
于是 MODULE_NOT_FOUND —— 宿主半身与浏览器半身一起挂不上。

为什么 profile 层 YAML 改不了它

dsh-app-boot/lib/index.js 的 applyEntryPatches:

const { id, insert, name, ...overrides } = patch
...
if (name && name !== target.name) {
warn('patch: name mismatch for %C (expected %C, got %C), skipping', ...)
continue                                   // ← name 只作身份断言
}
for (const [key, value] of Object.entries(overrides)) target[key] = value

name 不是可覆盖字段,它只用来断言「你改的是你以为的那一行」。
所以「往 profile 的 cordis.patch.yml 追加三行就能修好」这条路不存在,
必须落到 bundle 自己的 patch 文件上。

因此自愈分两级

一级(默认):就地改字节。 只替换那一行 name 的那一段,其它字节、注释、引号风格全不动。

-      name: 'dsh-our-free-model'
+      name: '@ebony-vinyl/dsh-our-free-model'

二级(包目录只读时):不碰 bundle 字节,改用 profile 层补丁。

这条路径的合法性来自 applyEntryPatches 的另外两条语义:

if (insert) { data.push(...insert); buildMap(insert) }   // 插入的行会进索引
...
target[key] = value                                       // disabled 可覆盖

于是可以「停掉坏行 + 补一条好的」:

- id: our-free-model
disabled: true                       # 停掉原行
- insert:
- id: our-free-model--guard
name: '@ebony-vinyl/dsh-our-free-model'
config: {}

buildMap(insert) 保证后一条 patch 能引用前一条插入的行,所以两段必须按顺序放。


2. 授权闸门:为什么确认必须自建

这台机器上 DSH 的 user-approval 被改成了 decide() => 'allowed-once',
DSH 原生的确认对话不会弹出来。在这样的环境里,「点一下就改别人包」的按钮等于没有护栏。

所以确认建在协议层,不是界面上的一个弹窗:

plan(只读)─→ planId + 每条:动作 / 目标文件 / 改前改后 / 可逆性 / 是否需重启
│
├─ 用户在面板上逐条勾选 ← 这就是授权
▼
apply(planId, approved[]) ─→ 校验① planId 有效(未过期、未执行)
② 指纹未变
③ 只有 approved 里的条目执行
└→ 任何一条不满足:拒绝,错误码 stale-approval
▼
复检 ─→ 本次批准的那条 issue 是否还在?不在了才算成功
▼
└→ 不在就自动回滚本次改动的全部字节
▼
undo(journalId) ─→ 从备份逐字节写回

指纹为什么要带目标文件的字节哈希

sha256(report.checkedAt + report.summary + package.json 字节 + cordis.patch.yml 字节 + 每条目标文件的字节哈希 + 已装版本)

只校验「报告有没有变」不够:报告证明「当时判过」,字节哈希证明「现在改的还是同一个东西」。
中间可能有人手动改了那个 patch,也可能有别的安装动作重写了 node_modules。

实测:报告一变 → 指纹变 → stale-approval → 不执行。


3. 与 dsh-compat-vet / dsh-forge 的关系

旧插件 保留了什么 补了什么 / 改了什么
dsh-compat-vet 三层复检(磁盘清单 + 自身 reaudit + 轮询 dsh 判定)、backupProfile/restoreBackup、explainErrorCode 含 stale-approval、回环 + 同源校验 新增 patch-bundle-row / activate 两个动作;新增 plan/apply/undo 协议;修掉内置包误报
dsh-forge 装前静态体检全部判据(manifest / exports / patch / syntax / client / locale / icon / slot / effects / lifecycle / skill 预算)、账本与 diff 改名为 auditBundle;工具名换成 guard_* 前缀(与 forge 并存时不撞 id)
@local/market-verdict 字面量口径的 tool/service 冲突扫描 冲突按包对聚合(82 个同名 tool 摊成 82 条会把真问题淹掉)

修掉的两个误报(这两个误报会让用户学会忽略报告)

① 内置包被报成未解析。
@deepseek-ai/dsh-base、@deepseek-ai/dsh-web-app 在 app.asar 里,
createRequire 解析不到,但它们确实是内置 bundle、确实能挂上。
旧 compat-vet 只按 createRequire 判定,所以每次体检都带两条噪音。

正解是 读安装体的 package.json dependencies(app-boot 自己就这么做)。
它在 asar 里,所以要能读 asar —— lib/asar.js 是最小实现(只读 header 索引,不写、失败返回 undefined)。

实测:本机 version=0.2.1-rc.5,dependencies 305 项,@deepseek-ai/dsh-base 在内。

② peer 判定口径写错会误报所有插件。
unmetRequirements(dsh-app-boot/lib/index.js:279-299)有三条例外,必须一起照抄:

  1. 有 engines.dsh → 只看它,peerDependencies 整段忽略
  2. peer 名只看 @deepseek-ai/dsh 与 @deepseek-ai/dsh-* 前缀
    (@deepseek-ai/cordis、@deepseek-ai/schemastery 不参与判定)
  3. range 对着 runtimeVersion 求值,不是对着 peer 包自己的版本
    (这是 dsh 的独特约定);workspace:^ / ~ / * 视为当前运行时

按自己直觉写会得出「dsh-plugin@2.2.7 与运行时冲突」的假结论
(它声明 @deepseek-ai/cordis: "4.0.1",运行时是 4.0.5 —— 但 cordis 根本不在判定范围内)。


4. 配置

cordis.patch.yml 里的 config:

键 默认 说明
tools true 注册 6 个 guard_* 模型工具。关掉 = 退化为纯面板(0 token)
pageUi true 挂 /api/dsh-plugin-guard 与侧栏面板
warnOnStartup true 启动时把阻断问题打到 stderr
selfHeal true 启动自愈。关掉后本插件退化为纯只读体检
selfHealDryRun false true = 只报告打算改什么,不写盘
syntaxCheck true 装前体检是否跑 node --check
ledgerDir .plugin-guard 状态目录(计划 / journal / 自愈账本),相对工作区根
planTtlMs 900000 计划有效期(15 分钟)。超时后 apply 返回 stale-approval
maxScanBundles 64 最多扫多少个 bundle 的 patch,防超大 profile 卡死
promptSection true 往系统提示词写一段「有插件挂不上」的提醒;无问题时不占上下文

selfHeal: false + tools: true 是一个常用组合:只报告、不自动改盘,
所有改动都要经过你在面板上勾选。


5. 验证

cd "G:\AI PGRM\DSH\plugins\plugin-guard"

# ① 协议正确性(合成 fixture)
node test/e2e.mjs

# ② 真机集成(真实 profile + 真实 asar)
node test/integration.mjs

# ③ 浏览器半协议形状
node test/client-contract.mjs

期望:

测试 结果 它证明什么
e2e.mjs 25/25 审计能抓 OFM 故障、plan 不改盘、指纹变即失效、只改一行、注释全保留、undo 逐字符还原、重复 apply 被拒
integration.mjs 16/16 从 asar 读出运行时与内置包清单、内置 bundle 不再误报、自愈 dry-run 零改动、装前体检自检 ERROR=0
client-contract.mjs 25/25 id 与包名一致、factory 真跑得起来、slot 注册对、无裸写死颜色、client/host 端点一致

e2e.mjs 里有两个坑值得记下来,它们是测试本身最容易写错的地方:

  1. 故障包的目录必须是 node_modules/@ebony-vinyl/dsh-our-free-model(scoped 布局)。
    放在 node_modules/dsh-our-free-model 会让裸名恰好可解析,复现不出问题。
  2. 修复只改 patch 行,不改 bundles 条目。要是测试场景把 bundles 也写成裸名,
    修完 patch 之后 bundle 级仍然解析不了,复检会(正确)判失败。

6. 安装

$p = "C:\Users\Shinelon\.dsh\profiles\desktop"
# ① 依赖(link: 安装,改动即时生效)
#   package.json → dependencies 里加:
#     "@local/dsh-plugin-guard": "link:G:/AI PGRM/DSH/plugins/plugin-guard"
pnpm install --dir $p

# ② 启用(bundles 末尾加一项)
#   package.json → dsh.profile.bundles 里加 "@local/dsh-plugin-guard"
# ③ 重启 DSH Desktop

与 dsh-compat-vet、dsh-forge 并存是安全的:工具名用 guard_* 前缀,
不会撞 id。但功能重叠——建议启用本插件后停用这两个,避免同一件事有两个入口。


7. 回滚

$p = "C:\Users\Shinelon\.dsh\profiles\desktop"
# ① 停用:从 dsh.profile.bundles 删掉 "@local/dsh-plugin-guard"
# ② 撤销所有自愈改动:自愈账本里每一项都有 beforeHash / afterHash
#    按 journal 撤销面板上执行过的改动:
#      guard_undo(journalId) 或面板「记录」页的「撤销」按钮
# ③ 彻底移除依赖:从 dependencies 删掉那行,pnpm install --dir $p
# ④ 清状态目录:Remove-Item "$p\..\..\plugin-guard" -Recurse -Force

自愈改过的 bundle patch 会在 pnpm install 之后被重写回原样(node_modules 是 pnpm 的产物)。
这不是问题:下次启动自愈会再跑一遍(幂等),所以「彻底不用管」成立的前提是
本插件保持启用。停用之后,那些包的 patch 会退回上游的写法,故障随之回来。


8. 已知边界(诚实声明)

  • 只认字面量:tool id 扫描只看 defineTool({ name: 'x' }) / .register({ name: 'x' })。
    拼接出来的名字(name: dynName)不在视野内。
  • !!js 表达式的 name 不判:静态判不了,标为 expression 并跳过。
  • 相对路径的 name 只查 package.json 存在性,不模拟 loader 的锚点解析完整链。
  • 不替你做决定:多包 tool 冲突时只给「隔离其中一个」的选项,不替你选留哪个。
  • 升级 / 卸载动作不实现:ACTION.UNINSTALL / UPGRADE 在 plan 里有定义但没有执行体,
    面板会明说「请用官方插件页」。理由:这两个动作的正确性依赖 dsh 自己的 pluginManager,
    自己 spawn pnpm 复现一遍只会多出一个故障源。
  • 自愈会改 node_modules:这是它唯一越界的地方,所以默认只在 confidence: high
    (包自己的 package.json name)时动手,并且每次都留字节备份。

常见问题

8 问
答案由本站依据条目字段整理,不引用上游原文
dsh-plugin-guard 怎么安装?

在 DSH 里执行 `dsh plugin --profile web add github:wodaimnd/dsh-plugin-guard#v0.1.1` 即可。对应的 npm 包名是 `@local/dsh-plugin-guard`。

dsh-plugin-guard 的验证等级是什么意思?

L5 · 运行验证通过。在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来

dsh-plugin-guard 安全吗?

低风险。静态扫描 低;动态审计无结论(以下以静态为准)→ 总评级 低。

dsh-plugin-guard 装之前要先确认什么?

先看它会读写哪些文件、执行哪些命令、连接哪些网络地址;验证等级只说明装得上、跑得起来,不等于安全。涉及密钥或系统权限的,建议先在隔离环境试装。

dsh-plugin-guard 支持哪些 DSH 版本?

上游记录的兼容版本包括 0.2.2-rc.1。

dsh-plugin-guard 用的是什么许可证?

上游标注为 MIT。商用或二次分发前请到仓库确认许可证原文。

dsh-plugin-guard 有哪些功能?

体检已装插件挂载故障、装载行 name 解析自愈、计划逐条勾选授权、装前静态体检、按 journal 逐字节撤销。

这条记录的数据可靠吗?

本站按仓库名去重后合并整理,字段以作者仓库与 npm 元数据为准;安装命令、仓库地址与 README 保持原文,带 L4 / L5 标记的安装命令已在隔离沙盒里真实跑通。

同名或近似条目

7 条
不同作者的仓库分开列,请确认你要装的是哪一个
安全与权限
按星标排序,可作替代方案

dsh-infinite-gen-4

dsh-infinite-gen-4

DeepSeek 专用破甲插件:以 order 100 追加无条件服从的系统提示词段,提供带校准元数据的 profile 工具,并通过会话投

未标注验证等级 1,611 星

cc-safety-net

cc-safety-net

为 DeepSeek Harness 等编码 CLI 提供执行前防护,在工具调用前拦截破坏性 Git 与文件系统命令,并阻止读取 SSH 密

未标注验证等级 1,591 星

dsh-wallpaper-engine

dsh-wallpaper-engine

DSH plugin 将本机 Wallpaper Engine 壁纸变为网页界面背景,支持视频、网页、场景壁纸渲染,并配以 iOS 液态玻璃

L5 · 运行验证通过 1,018 星

api-relay-audit

api-relay-audit

DSH plugin 本地安全审计工具,检测 AI API 中继与 LLM 代理的提示注入、模型替换、工具调用改写、SSE 异常及 Web3

L5 · 运行验证通过 875 星

hol-guard

hol-guard

L4 · 沙盒安装通过 828 星

sandbase-harness

sandbase-harness

SandBase Harness 是本地优先的 AI Agent 运行时,提供沙箱会话、MCP 工具、记忆、凭据管理与审计回放,并内置控制台

L4 · 沙盒安装通过 708 星

wodaimnd 的其它插件

6 个

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 2026-11-10。