把全局规则拆成多个可独立开关的 markdown 文件
29.5/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/26 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/kingzhz/dsh-global-rules.git状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 39 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件发起外部网络请求
查看扫描证据(共 20 处,展示前 14 条)
- 写入本地文件lib/index.js:197
await mkdir(directory, { recursive: true }) - 写入本地文件lib/index.js:199
await writeFile(tempPath, text, 'utf8') - 写入本地文件lib/index.js:201
await rename(tempPath, targetPath) - 删除本地文件lib/index.js:203
await rm(tempPath, { force: true }).catch(() => {}) - 写入本地文件lib/index.js:219
mkdirSync(rulesDir, { recursive: true }) - 读取本地文件lib/index.js:234
entries = readdirSync(rulesDir) - 读取本地文件lib/index.js:247
info = statSync(absolutePath) - 读取本地文件lib/index.js:259
text = readFileSync(absolutePath, 'utf8') - 发起网络请求lib/index.js:438
async fetch(request) { - 读取本地文件lib/index.js:530
if (!existsSync(absolutePath)) { - 读取本地文件lib/index.js:533
const text = readFileSync(absolutePath, 'utf8') - 读取本地文件lib/index.js:557
priority = parseFrontMatter(readFileSync(join(rulesDir, entry), 'utf8')).priority - 删除本地文件lib/index.js:626
await rm(absolutePath, { force: true }) - 写入本地文件lib/index.js:641
await rename(from, join(rulesDir, target))
扫描于 2026/10/31(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 规则拆分为多个文件
- 独立开关控制
- 设置界面管理
把全局 AGENTS 风格规则拆成多个独立 markdown 文件,配一个设置界面,补上 DeepSeek Harness 只有单个硬编码全局 AGENTS.md 的空缺。
README
由 DeepSeek 最新模型翻译生成dsh-global-rules
给 DeepSeek Harness 的原生 AGENTS.md 机制补上它缺的那一块:全局规则拆成多个独立文件,并配一个设置页 GUI。
为什么需要它
DSH 内建的 @deepseek-ai/dsh-agent-instructions 只读一个用户全局文件:
// dsh-agent-instructions/lib/index.js
const USER_GLOBAL_FILE = "AGENTS.md"; // 硬编码常量 const userGlobal = join(config.dshHome, USER_GLOBAL_FILE); // 无循环
对比项目层——它会遍历一整个候选名列表:
for (const dir of ancestorChain(projectRoot, cwd))
for (const candidates of [config.instructionFileCandidates, ...])
也就是说:项目层支持多文件,全局层写死一个。instructionFileCandidates 配置碰不到全局层,候选名里的子路径会被 resolveInstructionFileCandidates 过滤掉,@path import 官方也明确不做。
展开完整文档(README 剩余 1 节)
dsh-global-rules
给 DeepSeek Harness 的原生 AGENTS.md 机制补上它缺的那一块:全局规则拆成多个独立文件,并配一个设置页 GUI。
为什么需要它
DSH 内建的 @deepseek-ai/dsh-agent-instructions 只读一个用户全局文件:
// dsh-agent-instructions/lib/index.js
const USER_GLOBAL_FILE = "AGENTS.md"; // 硬编码常量 const userGlobal = join(config.dshHome, USER_GLOBAL_FILE); // 无循环
对比项目层——它会遍历一整个候选名列表:
for (const dir of ancestorChain(projectRoot, cwd))
for (const candidates of [config.instructionFileCandidates, ...])
也就是说:项目层支持多文件,全局层写死一个。instructionFileCandidates 配置碰不到全局层,候选名里的子路径会被 resolveInstructionFileCandidates 过滤掉,@path import 官方也明确不做。
于是全局规则只能全塞进 $DSH_HOME/AGENTS.md 一个文件里。本插件解决的就是这件事。
它做什么
$DSH_HOME/rules/ 下一个 markdown 文件 = 一条全局规则,每条独立增删改、独立开关:
$DSH_HOME/rules/
01-回答风格.md 02-代码改动规范.md 03-隐私禁区.md 04-临时停用的规则.md.disabled ← 暂停即改名,内容一字节不丢
每条规则作为一个有序的 system-prompt 段(order: 100,紧随部署 persona 之后)注入,对所有会话与模型生效。
改完下一步请求即生效,无需重启 DSH。 因为段的 text 是每次装配时求值的函数,而不是启动时快照的字符串。
安装
dsh plugin --profile web add github:kingzhz/dsh-global-rules
dsh web # host 侧代码在进程启动时装载,需重启一次
装好后在 设置 → 全局规则 打开 GUI。
只有 host 侧需要重启一次。之后增删改规则文件、开关规则都不需要重启——包括 GUI 里的操作。
GUI
设置页提供:
- 按优先级分档列出规则(每档显示条数与字节合计),显示标题、文件名、生效/暂停状态
- 每条规则一个优先级下拉,改档即写入其 front matter
- 点任意一条即在下方编辑,保存走原子写(同目录临时文件 + rename)
- 新建规则(自动加数字前缀,保持顺序稳定)
- 删除规则(二次确认)
- 暂停 / 启用:改名加去 .disabled,内容零丢失
- 顶部显示规则目录路径与预算占用(已用 / 上限)
也可以完全不用 GUI:直接往 rules/ 目录扔 .md 文件即可。
优先级
多条规则冲突时该听谁的?用优先级表达。
priority: 0
安全红线
绝对不执行 rm -rf、不 force push。
| 优先级 | front matter | system-prompt 段 order | 预算耗尽时 |
| P0 最高 | priority: 0 | 100 | 最后被丢 |
| P1 高 | priority: 1 | 200 | 倒数第二被丢 |
| P2 默认 | priority: 2(不写即此档) | 300 | 正常 |
| P3 低 | priority: 3 | 400 | 最先被丢 |
也接受 priority: p1 这种写法。超出范围的值会被夹到最近的档(负数 → P0,99 → P3);写成非数字则退回 P2,不会报错。
为什么这是真优先级,不只是标签
每个优先级档注册成独立的 system-prompt 段,order 依次为 100/200/300/400。DSH 按 order 升序拼接段,于是:
1. 位置真的分层 —— P0 的规则排在 P1 之前,P1 在 P2 之前。
2. 预算按优先级分配 —— 从最高档开始满足,不够时先丢 P3、再丢 P2。低优先级规则挤不掉高优先级规则。
3. 显式冲突声明 —— 注入文本开头写明“按优先级从高到低排列;两条冲突时以更靠前的为准”。
一个诚实的边界: DSH 不会在机制层面强制“高优先级覆盖低优先级”——最终是模型读文本。上面的位置分层 + 显式声明 + 预算保护,是实际能做到的最强形态。
同一优先级内,文件名数字前缀决定顺序。
配置
- id: global-rules
name: 'dsh-global-rules'
config:
rulesDir: ~/.dsh/rules # 默认 /rules maxBytes: 32768 # 注入文本的字节上限,默认 32768 maxSourceBytes: 262144 # 单个规则文件的读取上限,默认 256 KiB order: 100 # 最高优先级档(P0)的段序号,默认 100 heading: Global rules # 注入块的开头说明 enabled: true # 置 false 则完全不注入
order 是 P0 的段序号;P1/P2/P3 依次 +100。$DSH_HOME 解析顺序:显式配置 → $DSH_HOME 环境变量 → ~/.dsh。
预算行为
预算按优先级从高到低分配:先满足 P0,再 P1,依此类推。某档放不下时,该规则在剩余额度内截断(额度太小则整体省略),并附一条 [Global rules omitted for budget: ...] 提示,日志同时记录。
渲染结果绝不会超过 maxBytes。单文件超过 maxSourceBytes 时截断注入并在日志告警——磁盘上的原文件不动。
访问范围如实列出这个插件碰什么、不碰什么。
| 类别 | 范围 |
| 读 | rules/ 目录下的 .md / .md.disabled(仅此目录,仅此两种形态) |
| 写 | 同上白名单。原子写(临时文件 + rename),崩溃不会截断原文件 |
| 改名 | 同上白名单,用于「暂停/恢复」 |
| 网络 | 零。host 侧只 import node:fs / node:fs/promises / node:path / node:os / node:crypto |
| 会话 | 不读取。不碰 session 记录、不读对话内容 |
| 路径 | 客户端永远不传路径,只传文件名;host 侧用严格白名单正则校验后才 join。链外路径一律拒绝 |
路径穿越防护
host 侧只接受裸文件名,并校验:
const RULE_FILE_PATTERN = /^[^\\/:*?"<>|\u0000-\u001f]{1,120}\.md(\.disabled)?$/
含 /、\、:、盘符、绝对路径、..、空名的输入全部抛错拒绝。已实测 7 类穿越攻击(见下)。
测试
自带一套零依赖测试(不需要 npm install):
node tests/run.mjs
| 文件 | 覆盖 |
| tests/priority.test.mjs | 段注册与 order、front matter 解析与拼写变体、越界夹取、畸形头不报错、预算按优先级裁剪、RPC 优先级往返、写入不破坏/不重复头 |
| tests/regression.test.mjs | 路径穿越防护(7 类 × 4 个方法)、CRUD 生命周期、Fetch 路由请求形状校验、无残留临时文件 |
| tests/client-bundle.test.mjs | bundle 注册、slot 注册、页面在分档数据下的渲染 |
测试全部使用独立的临时目录,不会读写你真实的 rules/。
已验证
| 项 | 结果 |
| 配置树组合(dsh --dump-config) | 插件行正确注入,无加载错误 |
| 独立实例启动(dsh web --port 0) | 正常启动,不破坏 DSH |
| client bundle 投递 | 200,内容完整,含 settings.section 注册 |
| RPC 端到端(含认证) | 200,rules.list 返回四档元数据 |
| 优先级端到端 | 建 P0 规则 → front matter 落盘 → 改档生效 → 删除 |
| CRUD 全循环 | 建 / 改 / 停 / 删 全通 |
| 路径穿越防护 | ../、..\、绝对路径、子目录、ok.md/../x.md、空名 —— 4 个方法全部拒绝 |
| 规则真实注入 | 会话日志 system/message 中确认出现规则全文 |
| 测试套件 | 3/3 文件通过(共 92 项执行断言) |
实现说明
两半组成:
- host 半(lib/index.js):扫描规则目录(带 (mtimeMs, size) 缓存,外部编辑可见)、注册 systemPrompt.section()、提供 connection.fetch.register() 的 CRUD RPC 路由。
- client 半(lib/client/rules-panel.js):手写 CommonJS bundle,无构建步骤。用 React.createElement(不用 JSX),只 require('react'),通过 window.__ModuleLoader__.load() 注册。改完刷新页面即可。
两个刻意的实现选择:
1. interpolate: false — 规则是用户手写的散文,可能含字面 {{...}};而 system-prompt 的变量插值是严格的,未知引用会抛错。规则文本绝不能有能力搞崩提示词装配。
2. ctx.inject(['connection'], …) 而非 ctx.get('connection') — 前者会等 connection 服务真正出现再注册路由,消除「服务晚于插件激活」的时序竞态。而 connection 刻意不放进静态 inject 列表:headless / CLI profile 没有 Connection,静态 inject 会让插件(连同规则)在那里装不上。
已知取舍
- 暂停靠改名,会在磁盘留痕 —— .disabled 是真实文件名变更。若该目录在 git 里,git status 会多一行改名;不 git add 就不会进索引。
- GUI 面板本身需要刷新浏览器才能看到 —— host 侧即时生效,但 client bundle 的 boot graph 是启动时生成的。
- 读是同步的 —— systemPrompt 的 text 提供者必须同步返回字符串,因此用 readFileSync;文件很小,且有 stat 缓存。
- 不接管 $DSH_HOME/AGENTS.md —— 官方插件继续读它,两者并存互不干扰。
- 段顺序固定为 order: 100,暂不支持逐条排序(靠文件名数字前缀控制)。
License
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
kingzhz/dsh-global-rules
把全局规则拆成多个可独立开关的 markdown 文件
相关插件 · 技能 / 提示词
人设统管ZiChuanLan/agent-purge
一份系统提示词,喂给多个 coding…
★ 931已汉化DSH
73.8
人物画像蒸馏titanwings/distilly
Distilly — 把他们的思考方式提炼成可复用的技能,供任何智能体或机器人使用。原名 Colleague Skill(原同事 Skill)。
★ 25,659已汉化DSH
71.3
推理工作空间套件Tiger3807861189/J-Space-Cognition-Suite
J-Space 是面向复杂推理、大型仓库工程、子代理协作与授权安全分析的推理时工作空间和控制套件。
★ 2,957已汉化DSH
70.5
两阶段工具锚定预设xiaobright/dsh-anchored-standard
实验性 DeepSeek Harness agent preset…
★ 3,742已汉化DSH
70.1
智能体工作流编排nrslib/takt
不再日夜盯着 AI 编码智能体。
★ 1,402已汉化DSH
70
Agent 运行时手册Electricitysheep/dsh-handbook
DeepSeek Harness dsh 从 0 到 1 深度手册:安装/插件开发/性能调优/实测案例/同模型多…
★ 827已汉化DSH
68.7