# dsh-glob-rules [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![DSH Plugin topic](https://img.shields.io/badge/topic-dsh--plugin-blue)](https://github.com/topics/dsh-plugin) **中文** | [English](./README.md) 为 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)提供 glob 激活式规则提示——Claude Code `rules.md` / `# Path:` 风格的机制。每条规则声明 glob 模式;当 agent **读取或编辑** 匹配的文件时,规则激活,其内容(任意提示词或 markdown 文档)以一条“取代旧快照”的 `` 消息注入对话。 > 这是 [`dsh-rules`](https://github.com/rj-jiangyichen/dsh-rules) 的 TypeScript 重制版,行为一致,但按当前[官方插件开发文档](https://deepseek-harness.github.io/deepseek-harness/en/develop/basic/)与本机安装的框架版本(cordis 4.x、`dsh-*` rc 包)重写。与原版相比的关键 API 变化:会话历史改用 `session.snapshotEvents()` 读取(旧版 `session.events` 数组已不存在);同时改为与现生态一致的 TypeScript + `tsc` 构建。 > 适用于**所有 DSH 部署形态**:桌面 / web / tui / headless / 自定义 profile。 ## 特性 - **Glob 激活** — 按 agent 触碰的文件激活规则:支持 `**`、`*`、`?`、`{a,b}`、`[abc]` 与 `!` 取反(picomatch)。 - **兼容 Claude Code** — 支持普通规则文件(`.dsh/rules/*.md`),也支持 `CLAUDE.md` / `AGENTS.md` 中的 `# Path:` 段落。 - **可见且持久** — 激活的规则作为用户消息注入:UI 可见、会话日志持久保存;每条快照取代之前的快照,模型始终看到当前集合。 - **预算受限** — 按字节预算渲染(默认 32 KB):优先丢弃低优先级规则,最后一条被截断;内容被转义,不会逃逸出框架标签。 - **可续聊** — 会话续聊时从日志(`session.snapshotEvents()`)恢复最近一次快照及其匹配文件,避免重复注入。 - **按会话跟踪** — 每个 agent/会话各自记录触碰的文件(含子代理);无 `path` 的全局规则始终激活。 ## 工作方式 ``` workspace .dsh/rules/*.md ← 规则定义(frontmatter 声明 globs) ~/.dsh/rules/*.md ← 用户级规则(可选) AGENTS.md/CLAUDE.md ← 可选:# Path: 段落(兼容 Claude Code) agent 读取/编辑文件(fs/observed)→ 记录本会话触碰路径 ↓ 每一步(agent/pre-step) 用 globs 匹配触碰路径 → 收集激活规则 → 渲染 快照注入对话 ``` ## 安装 包声明了 `dsh.bundle.patch`(DSH bundle),因此 `dsh plugin` 一条命令即可安装**并激活**: ```powershell # 按需调整 profile 名:desktop / web / tui / headless dsh plugin --profile desktop add dsh-glob-rules ``` reconcile 会自动把 `dsh-glob-rules` 追加进 profile 的 `dsh.profile.bundles` 层列表——**无需手工编辑 `cordis.patch.yml`**。重启 DSH 后插件随下一次 Cordis 组合加载。 本地或 git 安装:包带 `prepare` 脚本(`tsc` 从 `src/` 构建 `lib/`),因此 `dsh plugin --profile desktop add .`(或 `add github:you/dsh-glob-rules`)同样可用。pnpm ≥10 会先要求你放行 git 依赖的 `prepare` 脚本:把 pnpm 打印的包 key 抄进 profile 的 `pnpm-workspace.yaml` 的 `allowBuilds` 后重试 `add`。 按 profile 覆盖默认配置(可选),在 `/cordis.patch.yml` 中写: ```yaml - id: dsh-glob-rules name: dsh-glob-rules config: includeClaudeSections: true projectRootMarkers: [".git", ".dsh"] ``` 卸载:`dsh plugin --profile desktop remove dsh-glob-rules`,然后重启。 ## 规则格式 ### 来源 A:规则文件(`.dsh/rules/*.md` 与 `~/.dsh/rules/*.md`) ```markdown --- path: - "src/**/*.ts" - "!src/**/*.test.ts" --- 规则正文(markdown,激活时原样注入——任何提示词内容均可) ``` | frontmatter 字段 | 说明 | | --- | --- | | `path` | 字符串或 glob 列表,相对项目根目录、`/` 分隔;`!` 前缀为排除模式。**缺失或为空 = 全局常驻规则**。 | | `name` | 可选;规则标识(同名去重用)。缺省为去掉 `.md` 的文件名。 | ### 来源 B:`# Path:` 段落(需 `includeClaudeSections: true`) 解析 `AGENTS.md` / `CLAUDE.md`(含 `.local.md` 变体与 `~/.dsh/AGENTS.md`)中的 `# Path: ` 标题: ```markdown # 项目说明(首个标题之前的内容由内置 agent-instructions 处理,不属于本插件) # Path: src/**/*.ts, scripts/** 仅当触碰 src/**/*.ts 或 scripts/ 下文件时本段落才激活 ``` - 每个 `# Path:` 标题开启一条规则,直到下一个标题或文件末尾。 - globs 可用逗号或空格分隔。 - 首个 `# Path:` 之前的内容有意**不**注入——DSH 内置的 `agent-instructions` 已注入完整 AGENTS.md/CLAUDE.md 基线。 ### 优先级与去重 项目规则(100)> 用户规则(200)> `# Path:` 段落(300)。同名保留高优先级条目;渲染按 (rank, name) 排序,跨步骤确定。 ## 配置 | 选项 | 默认 | 说明 | | --- | --- | --- | | `dshHome` | `$DSH_HOME` / `~/.dsh` | 用户规则与 `~/.dsh/AGENTS.md` 的根目录 | | `projectRootMarkers` | `[".git"]` | 向上查找项目根目录时使用的标记文件/目录 | | `ruleDirNames` | `[".dsh/rules"]` | 项目内的规则目录(相对项目根,可多个) | | `includeUserRules` | `true` | 启用 `~/.dsh/rules/*.md` | | `includeClaudeSections` | `false` | 解析 `# Path:` 段落 | | `instructionFileCandidates` | `["AGENTS.md", "CLAUDE.md"]` | `# Path:` 段落的候选文件名 | | `localInstructionFileCandidates` | `["AGENTS.local.md", "CLAUDE.local.md"]` | 逐目录候选文件名 | | `maxBytes` | `32768` | 单次注入渲染预算(UTF-8 字节);`<= 0` 关闭插件 | | `maxSourceBytes` | `1048576` | 单条规则源大小上限,更大文件跳过 | | `maxTouchedPaths` | `512` | 每会话触碰路径上限(FIFO 淘汰) | ## 开发 ```powershell pnpm install pnpm run check # typecheck + build(tsc) pnpm test # node --test:解析 / glob 匹配 / 优先级 / 预算 / 确定性 / fs 回退 ``` 目录结构: - `src/index.ts` — 插件入口(`name` / `Config` / `apply`):`fs/observed` 触碰跟踪、`agent/pre-step` 注入、`agent/disposed` 清理、基于 `session.snapshotEvents()` 的续聊恢复。 - `src/rules.ts` — 纯逻辑:frontmatter 与 `# Path:` 解析、glob 编译/匹配、优先级合并、预算渲染。 - `src/fs.ts` — 带版本缓存的发现/读取:优先 harness `fs` 服务,回退 Node 文件系统。 - `test/rules.test.mjs`、`test/apply.test.mjs` — 单元 + apply 级测试(对编译后的 `lib/` 运行)。 - `examples/.dsh/rules/` — 示例规则(复制进你的项目即可上手)。 - `fixtures/demo-project/` — 现成的试玩项目。 ## License [MIT](LICENSE) — 保留对本项目所移植原版 [dsh-rules](https://github.com/rj-jiangyichen/dsh-rules) 的署名。