Back to home@czhzz

dsh-danger-guard

No description

Stars
0
Language
TypeScript
Created
Sep 1, 2026
Updated
Sep 1, 2026
GitHub repo

Introduction

dsh-danger-guard

DSH 危险命令守卫(双面插件:host 门禁 + client 设置页):挂在 tools/pre-execute 门禁上,在 bash/pwsh 工具派发前检查命令文本,拦截高危命令。

  • 不注册任何模型可见工具——纯粹是执行流水线上的"门禁";
  • 分级策略critical 极高危(rm -rf /mkfs、dd 写设备、fork 炸弹、根目录 777 等)无视全局配置始终拒绝medium 中危(curl|shgit push --force、读私钥等)跟随全局 action
  • 可扩展:用户自定义规则 + 白名单正则,全部可进 --dump-config 查看;
  • Web 设置页:在浏览器「设置 → 插件配置」里以卡片形式编辑全部配置(开关/策略/规则 JSON/白名单),保存即热生效(settings 文档 → host watch 热更新)。

安装

方式一:从 GitHub 安装(推荐)

dsh plugin --profile web add github:czhzz/dsh-danger-guard

git 安装拉取的是源码,首次 add 需要为该包授权构建脚本(pnpm ≥10 默认拒绝运行 git 依赖的 prepare)。首次失败时,把 pnpm 提示的包键复制进 profile 的 pnpm-workspace.yaml

allowBuilds:
  dsh-danger-guard: true

然后重新执行 add。建议锁定 commit(github:czhzz/dsh-danger-guard#<sha>)。

方式二:从 npm 安装(发布后)

dsh plugin --profile web add dsh-danger-guard

验证

# 1) 配置树里出现插件行与默认配置
dsh --profile web --dump-config | grep -A 20 dsh-danger-guard

# 2) client bundle 被 web shell 提供(boot 图含 dsh-danger-guard)
dsh --profile web --no-open --port 0
# 浏览器打开后:设置 → 插件配置 → 「危险命令守卫」卡片

# 3) 让模型尝试危险命令,观察拦截
dsh --profile headless "用 bash 工具执行命令:git push --force origin main"
# 预期:模型收到拒绝原因(内置规则 git-push-force),命令未执行

配置

两层配置来源(同源 schema,设置页编辑即修改第二层):

位置说明
cordis Configprofile 的 cordis.patch.ymlschema 默认值 + 装配层覆盖,--dump-config 可见
settings 文档设置页「插件配置」卡片用户覆盖层,保存即持久化并热更新
默认说明
enabledtrue总开关
actiondenymedium 规则处理方式:deny 直接拒绝 / ask 转审批(未挂载审批时自动退化为拒绝)/ log 仅记录放行
rules[]用户自定义规则 [{pattern, reason, level?}]pattern 为 JS 正则字符串
allow[]白名单正则,命中直接放行(优先级最高,含 critical)
disableBuiltinfalse关闭内置规则集

示例(在 profile 的 cordis.patch.yml 中覆盖):

- update:
    - id: dsh-danger-guard
      config:
        action: ask
        allow:
          - 'npm install.*--force'
        rules:
          - pattern: 'git\s+rebase\s+--(continue|abort)'
            reason: 需要人工确认 rebase 操作
            level: medium

开发

npm install
npm run build           # host: tsc → lib/index.js;client: esbuild → lib/client.js
npm test                # node --test tests/(匹配逻辑单测)

结构:

src/
├── index.ts            # host 半侧:settings 命名空间注册 + pre-execute 门禁
└── client/
    ├── index.tsx       # client 半侧:settings.plugin.item 卡片 + CardForm
    └── styles.css      # 卡片样式(esbuild 内联为 <style>)
scripts/build.mjs       # esbuild 打包 client(lazy-CJS factory,平台模块走 external)

client 契约要点:package.jsondsh.clientinject + platform: web)声明 + exports["./client"]; client 入口导出 inject + apply(ctx),用 ctx.settingsScope.bind({namespace}) + ctx.slots.register 注册卡片; 构建用 esbuild 产出 window.__ModuleLoader__.load({id, factory}) CJS 格式(平台模块由 shell 模块表提供,esbuild 只转译不查类型)。

卸载

dsh plugin --profile web remove dsh-danger-guard