dsh-rule-engine 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # dsh-rule-engine
2
2
 
3
3
  ![npm](https://img.shields.io/npm/v/dsh-rule-engine)
4
- ![version](https://img.shields.io/badge/version-0.6.0-blue)
4
+ ![version](https://img.shields.io/badge/version-0.6.1-blue)
5
5
 
6
6
  DSH 规则执行引擎 v3 的插件实现。它把 `~/.dsh/AGENTS.md` 当作唯一真相源,自动解析规则四要素与执行等级,再通过「工具守卫 + 文本检测 + 时序检查 + 审计台账」执行用户规则,而不是内置一套与用户无关的安全清单。
7
7
 
@@ -113,7 +113,7 @@ DSH 规则执行引擎 v3 的插件实现。它把 `~/.dsh/AGENTS.md` 当作唯
113
113
 
114
114
  ## 发行固定源
115
115
 
116
- - **0.6.0(当前)** 固定于 main Commit `14e4955`(`git checkout 14e4955` 可复现 npm `dsh-rule-engine@0.6.0` 与 GitHub Release v0.6.0 同源代码——0.6.0 = 本机集成层(localIntegrations 四键)+ 本机痕迹消号 + li-skipped/entry-script-missing 启动审计 + 发布门禁 B1/B2(readme-version-check / local-residue-scan,挂 verify-all/release-plugin/check:meta)+ check-tool-coverage 素材 fail-closed(第三方反馈润色:通用指引+配置注入本机提示);词表文件 `scripts/local-residue-markers.txt` 为本机门禁工具,不入库、不进发布物(见 .gitignore / package.json files 排除)。固定源之后的提交仅限 README 指针文本)。
116
+ - **0.6.0(当前)** 固定于 main Commit `be5b8c93`(`git checkout be5b8c93` 可复现 npm `dsh-rule-engine@0.6.0` 与 GitHub Release v0.6.0 同源代码——0.6.0 = 本机集成层(localIntegrations 四键)+ 本机痕迹消号 + li-skipped/entry-script-missing 启动审计 + 发布门禁 B1/B2(readme-version-check / local-residue-scan,挂 verify-all/release-plugin/check:meta)+ check-tool-coverage 素材 fail-closed(第三方反馈润色:通用指引+配置注入本机提示);词表文件 `scripts/local-residue-markers.txt` 为本机门禁工具,不入库、不进发布物(见 .gitignore / package.json files 排除)。固定源之后的提交仅限 README 指针文本)。
117
117
 
118
118
  ## 任务契约与反过度工程(可选)
119
119
 
@@ -242,7 +242,7 @@ dsh plugin --profile web add dsh-rule-engine
242
242
  - dsh-guardian(lonelymoon87)
243
243
  - dsh-visualize(Nagi-ovo)
244
244
  - dsh-rules-manager(jilian-dsh)
245
- - dsh-vision-router、dsh-super-injector 等未列出的作者
245
+ - dsh-vision-router、dsh-example-injector 等未列出的作者
246
246
  - **学习参考的社区文档/库作者**:
247
247
  - dsh-handbook(Electricitysheep)
248
248
  - SandBase deepseek-harness-handbook(sandbaseai)
@@ -129,14 +129,18 @@ export function inferTypeFromText(text) {
129
129
  /** 0.5.10 建议1①(用户审查采纳):ask 答复文本 → 结构化操作类型(修复"弹窗授权宽泛 any 接不住真操作")。
130
130
  * 返回 write | command | any(analysis/artifact 类本就不需授权,不落入授权记录)。
131
131
  * 明确操作词 → 具体类型;含糊/纯查看 → any(保守:TTL 短兜底)。 */
132
+ /** ask 授权类型推导(E3/簇 A 配置化):接入 TYPE_HINTS(内置表含 git 类)+ 配置层 typeHints 扩展共同生效。
133
+ * 多类型命中按具体类优先序取(delete/backup/git/network/archive/skill > write > command > analysis);无命中 → any(保守)。
134
+ * 原硬编码 write/command 两正则废弃——与 hints 表漂移("提交/覆盖"等中文词误映射)的风险源。 */
135
+ const ASK_SCOPE_PRIORITY = ["delete", "backup", "git", "archive", "skill", "write", "command", "network", "analysis"];
132
136
  export function classifyAskScopeType(text) {
133
137
  const s = String(text || "");
134
- const hasWrite = /(?:修改|编辑|写入|覆盖|保存|删除|丢弃|移除|移动|改名|创建|新建|上传|复制|下载到|发布|推送|提交|写文件)/i.test(s);
135
- const hasCommand = /(?:pwsh|powershell|命令|脚本|执行|运行|诊断|排查|体检)/i.test(s);
136
- if (hasWrite && !hasCommand) return "write";
137
- if (hasCommand && !hasWrite) return "command";
138
- // 同时含/都不含 any(保守;不含时 TTL 短)
139
- return "any";
138
+ const hints = currentHints();
139
+ const hits = [];
140
+ for (const h of hints) if (h.re.test(s)) hits.push(h.type);
141
+ if (hits.length === 0) return "any";
142
+ for (const t of ASK_SCOPE_PRIORITY) if (hits.includes(t)) return t;
143
+ return hits[0];
140
144
  }
141
145
 
142
146
  /** 从文本推断全部命中的操作类型(用于一条子句含多个操作,如“修改 A 并删除 B”) */
@@ -146,8 +146,10 @@ function isEntryChannelCommand(cmd, entryMarker) {
146
146
  if (ch === ";" || ch === "|" || ch === "&" || ch === "\n") return false;
147
147
  }
148
148
  // ② 重定向:摘除 fd 复制(N>&M / N<&M)后,任何 > / >> / &> 均非法(N1——含数字前置 2>/1> 盲区)
149
+ // 2026-09-06 0.6.x 修复:引号感知——参数值内的 >(如 markdown 引用符/⟨⟩ 占位)不再误判重定向
149
150
  const noFd = c.replace(/\d*\s*[<>]&\s*\d+/g, "");
150
- if (/>>|&>|(?:^|[^<])>/.test(noFd)) return false;
151
+ const noQuoted = noFd.replace(/"[^"]*"|'[^']*'/g, "");
152
+ if (/>>|&>|(?:^|[^<])>/.test(noQuoted)) return false;
151
153
  return true;
152
154
  }
153
155