@shgroup/dsh-serenity-hooks 1.19.0 → 1.19.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/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-serenity-hooks",
3
- "version": "1.19.0",
3
+ "version": "1.19.1",
4
4
  "main": "lib/index.js",
5
5
  "description": "宁静号 ACC harness(Native Cordis 插件):真实 DSH 工具 cc_fs/session/acc_msm/eap/neat/cce/loop + 拦截缝机械约束(safe-mode/路径守卫)。适配 DSH 公开版(0.1.0-rc,deepseek-ai/deepseek-harness)。私有(dsh-external 组织)。",
6
6
  "engines": {
package/lib/index.js CHANGED
@@ -1897,6 +1897,32 @@ const sessionTool = defineTool({
1897
1897
  *
1898
1898
  * 对应 opencode-serenity-plugin 的 tool.execute.before 路径守卫 + bash 开关 + 黑名单。
1899
1899
  */
1900
+ /** 写类工具名(黑名单/治理文件只拦这些;读工具只做路径越界检查——对齐 osp) */
1901
+ const WRITE_TOOLS = /* @__PURE__ */ new Set([
1902
+ "write",
1903
+ "edit",
1904
+ "str_replace_editor",
1905
+ "cc_fs",
1906
+ "bash",
1907
+ "append",
1908
+ "touch"
1909
+ ]);
1910
+ /** cc_fs 的写类子命令(mkdir/rm/mv/cp/touch/append);其余 9 子命令(root/resolve/exists/
1911
+ * list/tree/relative/reveal/info/find)为只读——只读子命令不查黑名单(同 read 语义) */
1912
+ const CC_FS_WRITE_ACTIONS = /* @__PURE__ */ new Set([
1913
+ "mkdir",
1914
+ "rm",
1915
+ "mv",
1916
+ "cp",
1917
+ "touch",
1918
+ "append"
1919
+ ]);
1920
+ /** 判定工具是否为写类:普通工具按名;cc_fs 复合工具按子命令 action */
1921
+ function isWriteTool(toolName, action) {
1922
+ if (!WRITE_TOOLS.has(toolName)) return false;
1923
+ if (toolName === "cc_fs") return action !== void 0 && CC_FS_WRITE_ACTIONS.has(action);
1924
+ return true;
1925
+ }
1900
1926
  /**
1901
1927
  * 安全模式 + 黑名单 + P3 路径守卫的纯决策。
1902
1928
  * 对齐 opencode-serenity-plugin 标准:安全模式 = **bash 禁用** + 写入黑名单;
@@ -1904,7 +1930,7 @@ const sessionTool = defineTool({
1904
1930
  * 优先级:safe-mode bash > 路径越界 > 黑名单命中。
1905
1931
  */
1906
1932
  function decideGuard(input) {
1907
- const { root, toolName, safeModeOn, blacklist, pathArg } = input;
1933
+ const { root, toolName, safeModeOn, blacklist, pathArg, action } = input;
1908
1934
  if (safeModeOn && toolName === "bash") return {
1909
1935
  deny: `bash: 没有这个工具`,
1910
1936
  kind: "deny"
@@ -1915,7 +1941,7 @@ function decideGuard(input) {
1915
1941
  deny: `path escape blocked: "${pathArg}" 越出 CCC 根`,
1916
1942
  kind: "deny"
1917
1943
  };
1918
- if (toolName === "write" || toolName === "edit" || toolName === "str_replace_editor" || toolName === "cc_fs" || toolName === "bash" || toolName === "append" || toolName === "touch") {
1944
+ if (isWriteTool(toolName, action)) {
1919
1945
  const rel = relative(root, abs).split("\\").join("/");
1920
1946
  if (rel === ".serenity-safe-on" || rel === ".serenity" || rel.startsWith(".serenity-safe-on/") || rel.startsWith(".serenity/")) return {
1921
1947
  deny: `CCC 治理文件 "${rel}" 保留给用户,agent 不可写`,
@@ -1994,7 +2020,11 @@ function syncSafeModeRestriction(agent, root) {
1994
2020
  }
1995
2021
  writeRestrictDiag(root);
1996
2022
  }
1997
- /** 从 exec 参数中提取常见路径字段(write/edit 工具);宽松读取 */
2023
+ /**
2024
+ * 从 exec 参数中提取常见路径字段(write/edit 工具);宽松读取。
2025
+ * cc_fs 复合工具:path(单路径)/ paths(数组)/ src / dst——取第一个命中(越界检查
2026
+ * 逐路径由 decideGuard 单 pathArg 覆盖;多路径字段取首个,避免漏检主体路径)。
2027
+ */
1998
2028
  function extractPathArg(exec) {
1999
2029
  const args = exec.arguments;
2000
2030
  if (args === null || typeof args !== "object") return void 0;
@@ -2003,11 +2033,21 @@ function extractPathArg(exec) {
2003
2033
  "path",
2004
2034
  "file_path",
2005
2035
  "target",
2036
+ "src",
2006
2037
  "dst"
2007
2038
  ]) {
2008
2039
  const v = a[key];
2009
2040
  if (typeof v === "string") return v;
2010
2041
  }
2042
+ const paths = a["paths"];
2043
+ if (Array.isArray(paths) && paths.length > 0 && typeof paths[0] === "string") return paths[0];
2044
+ }
2045
+ /** 从 exec 参数提取 cc_fs 子命令 action;无则 undefined */
2046
+ function extractAction(exec) {
2047
+ const args = exec.arguments;
2048
+ if (args === null || typeof args !== "object") return void 0;
2049
+ const a = args;
2050
+ return typeof a.action === "string" ? a.action : void 0;
2011
2051
  }
2012
2052
  /**
2013
2053
  * 注册守卫:tools/pre-execute 瀑布 + ctx.tools.guard 终局。
@@ -2021,12 +2061,14 @@ function registerGuards(ctx, opts = {}) {
2021
2061
  const safeModeOn = isSafeModeOn(root);
2022
2062
  const blacklist = readBlacklist(root, configPaths);
2023
2063
  const pathArg = extractPathArg(exec);
2064
+ const action = extractAction(exec);
2024
2065
  return decideGuard({
2025
2066
  root,
2026
2067
  toolName: exec.name,
2027
2068
  safeModeOn,
2028
2069
  blacklist,
2029
- pathArg
2070
+ pathArg,
2071
+ action
2030
2072
  });
2031
2073
  };
2032
2074
  ctx.on("tools/pre-execute", async (exec, next) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.19.0",
3
+ "version": "1.19.1",
4
4
  "description": "宁静号 ACC harness — Native Cordis 插件(DeepSeek Harness 运行时)。真实 DSH 工具注册(cc_fs/session/acc_msm 等 9 工具)+ 拦截缝机械约束(safe-mode/路径守卫/会话落盘)+ 系统提示词注入(ACC/CCE/Constraints/SKILL/Session 五块)。适配 DSH 公开版(deepseek-ai/deepseek-harness 0.1.0-rc)。",
5
5
  "license": "MIT",
6
6
  "repository": {