@shgroup/dsh-serenity-hooks 1.56.5 → 1.56.6
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 +1 -1
- package/lib/index.js +110 -0
- package/lib/seams/guards.d.ts +16 -0
- package/package.json +1 -1
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-serenity-hooks",
|
|
3
|
-
"version": "1.56.
|
|
3
|
+
"version": "1.56.6",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"description": "宁静号 ACC harness(Native Cordis 插件):给 DSH 装一个「AI 工作区」——14 个工具(container_fs/container_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/handyman/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 轨迹日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/trajectory 唤醒注册表。适配 DSH 0.1.7-rc.1 与 0.2.0-rc.1(双档,deepseek-ai/deepseek-harness)。",
|
|
6
6
|
"engines": {
|
package/lib/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { a as readWeixinCredential, c as weixinInboundDir, d as LOCALSTORE_SCOPE
|
|
|
7
7
|
import { a as unregisterSkiffSession$1, i as skiffSessionSnapshot$1, n as skiffRoleFor$1, o as ACC_VERSION, r as skiffSessionInfo$1, t as registerSkiffSession$1 } from "./skiff-registry-BjIX_KD1.js";
|
|
8
8
|
import { a as readSkiffRoles, c as roleMsmWhitelist, d as systemPromptSource, f as trajectorySubset, i as isSkiffSessionId, l as roleToolWhitelist, n as buildSkiffBasePrompt, o as resolveRoleSystemPrompt, r as createRolePromptReader, s as resolveSkiffKind } from "./skiff-role-BSg6Qu9k.js";
|
|
9
9
|
import { a as ACP_HTTP_PORT, c as MAIN_WEB_PORT, d as WEIXIN_SEND_PORT, l as MECHANISM_PORTS, n as readSimpleSettings, o as FACE_PORTS, r as registerSettingsSection, s as GATEWAY_PORT, u as SKIFF_DEBUG_PORT } from "./settings-section-xHABl8nk.js";
|
|
10
|
+
import { REGISTERED_TOOLS } from "./invariant.js";
|
|
10
11
|
import { a as markdownToPlainText, c as sendTyping, i as getUpdates, l as sniffImageExt, n as downloadMedia, o as sendFileMessage, r as getConfig, s as sendTextMessage, t as TypingStatus } from "./weixin-api-BrRcPiQs.js";
|
|
11
12
|
import { createRequire } from "node:module";
|
|
12
13
|
import z from "@deepseek-ai/schemastery";
|
|
@@ -13865,6 +13866,106 @@ function forgetExclusiveToolsVisibility(sessionId) {
|
|
|
13865
13866
|
}
|
|
13866
13867
|
}
|
|
13867
13868
|
/**
|
|
13869
|
+
* 非 CCC 会话的工具隐藏状态(sessionId → restrict disposer)。
|
|
13870
|
+
*
|
|
13871
|
+
* 🔴 **为什么需要它(缺陷根因)**:工具是 `apply()` 里 `ctx.tools.register(...)` 注册到**宿主级**的
|
|
13872
|
+
* ⇒ 它们出现在**每一个**会话的工具清单里,**与会话 cwd 无关**。其余各缝(身份注入 / guards /
|
|
13873
|
+
* keeper / output-guard / unattended / bootstrap)都已有 `if (!root) return` 这道门,
|
|
13874
|
+
* **唯独"工具可见性"这一层没有** ⇒ 在非 CCC 目录开会话时,模型仍看得见这 14 个工具,
|
|
13875
|
+
* 于是会去调 —— 调了才抛 `No CCC found`。**那是运行时报错,不是事先不可见**。
|
|
13876
|
+
*
|
|
13877
|
+
* 判据(owner 原话:「宁静号所有功能在非宁静号目录不生效」):
|
|
13878
|
+
* - **在 CCC 内** → 解除隐藏(本机制**一次 restrict 都不发**,既有行为零改变)
|
|
13879
|
+
* - **不在 CCC 内** → `restrict({ deny: [...REGISTERED_TOOLS] })` ⇒ 从模型工具清单移除
|
|
13880
|
+
*
|
|
13881
|
+
* ⚠️ **与 `syncExclusiveToolsVisibility` 的分工**:那个管"CCC 内哪个工具可见"(按 CCC 配置判);
|
|
13882
|
+
* 本函数管"**这个会话配不配看到任何 ACC 工具**"(按"在不在 CCC 内"判)。二者独立、可叠加。
|
|
13883
|
+
*
|
|
13884
|
+
* ⚠️ **必须逐个名字显式列出**:宿主的 `restrict` 对**未注册的工具名**会让**整次调用失败**
|
|
13885
|
+
* (`dsh-tools` 契约逐字:"Empty filters, unknown names … fail")⇒ 不能写通配。
|
|
13886
|
+
* 但 `REGISTERED_TOOLS` 是"插件**具备**的工具面",其中 **`diagram` 是按开关注册的**
|
|
13887
|
+
* (缺省关 ⇒ 缺省**并不在册**)⇒ 直接拿全表去 deny **可能整次失败**,那样就会
|
|
13888
|
+
* **静默退回"工具照样可见"**=缺陷没修好。故此处走**两档尝试**(见 `hideAllFor`)。
|
|
13889
|
+
*/
|
|
13890
|
+
const nonCccRestrictions = /* @__PURE__ */ new Map();
|
|
13891
|
+
/**
|
|
13892
|
+
* 在非 CCC 会话上隐藏全部 ACC 工具(两档尝试)。
|
|
13893
|
+
*
|
|
13894
|
+
* 🔴 **为什么要两档(D119:不许照源码"意图"断言宿主行为)**:取消注册的工具名会让整次
|
|
13895
|
+
* `restrict` 失败,而 `diagram` 缺省不在册。若只发一次全表 deny,"deny 里有个不在册的名字"
|
|
13896
|
+
* 就会让**整次调用**失败 ⇒ 一个都不隐藏(且只有一行 console.error)。
|
|
13897
|
+
*
|
|
13898
|
+
* 档位(**先全覆盖、失败再退到"恒在册"那一段**):
|
|
13899
|
+
* ① 全表 `REGISTERED_TOOLS`(14:含条件工具)—— 首选,覆盖最全
|
|
13900
|
+
* ② 常驻段(前 `length - CONDITIONAL_TOOL_COUNT` 个)—— 退路:只保证**恒注册**的那些被隐藏
|
|
13901
|
+
*
|
|
13902
|
+
* 返回**实际生效的注销器**;两档都失败 → `{ failed: [...] }`(原因一并带回,由调用方决定怎么响)。
|
|
13903
|
+
*
|
|
13904
|
+
* ⚠️ **档位失败不在这里逐条告警**:档 ① 在 `diagram` 缺省关时**按设计**就会失败(它不在册),
|
|
13905
|
+
* 那是**常态**、不是故障 ⇒ 逐条 error 会在每个非 CCC 会话上刷**假警报**(看着像坏了,其实档 ② 已成功)。
|
|
13906
|
+
* 真正的失败只由调用方在"两档全失败"时**响亮报一次**。
|
|
13907
|
+
*/
|
|
13908
|
+
function hideAllFor(agent) {
|
|
13909
|
+
const resident = REGISTERED_TOOLS.slice(0, REGISTERED_TOOLS.length - 3);
|
|
13910
|
+
const tiers = [{
|
|
13911
|
+
label: "全表(含条件工具)",
|
|
13912
|
+
names: REGISTERED_TOOLS
|
|
13913
|
+
}, {
|
|
13914
|
+
label: "常驻段(跳过条件工具)",
|
|
13915
|
+
names: resident
|
|
13916
|
+
}];
|
|
13917
|
+
const failed = [];
|
|
13918
|
+
for (const tier of tiers) try {
|
|
13919
|
+
return {
|
|
13920
|
+
dispose: agent.ctx.tools.restrict({ deny: [...tier.names] }),
|
|
13921
|
+
names: tier.names
|
|
13922
|
+
};
|
|
13923
|
+
} catch (e) {
|
|
13924
|
+
failed.push(`${tier.label}: ${e.message}`);
|
|
13925
|
+
}
|
|
13926
|
+
return { failed };
|
|
13927
|
+
}
|
|
13928
|
+
/**
|
|
13929
|
+
* 同步「本会话在不在 CCC 内」的工具可见性(v1.56.6)。
|
|
13930
|
+
*
|
|
13931
|
+
* @param agent 目标会话的 agent
|
|
13932
|
+
* @param root 该会话的 CCC 根;`null` ⇒ **不在任何 CCC 内** ⇒ 隐藏全部 ACC 工具
|
|
13933
|
+
*
|
|
13934
|
+
* 幂等:同一会话重复调用不会重复 restrict(已是目标态即直接返回)。
|
|
13935
|
+
* 失败不抛(最坏情况:工具可见,但**调用时**仍被各工具自己的根解析拒绝——既有兜底不变)。
|
|
13936
|
+
*/
|
|
13937
|
+
function syncCccToolVisibility(agent, root) {
|
|
13938
|
+
const sessionId = agent.session.id ?? "global";
|
|
13939
|
+
const existing = nonCccRestrictions.get(sessionId);
|
|
13940
|
+
const shouldHide = root === null;
|
|
13941
|
+
if (shouldHide && !existing) {
|
|
13942
|
+
const hidden = hideAllFor(agent);
|
|
13943
|
+
if ("failed" in hidden) {
|
|
13944
|
+
console.error(`[serenity-hooks] 非 CCC 工具隐藏**两档全失败**(session=${sessionId}) —— 工具仍可见(但有各工具自身的 !root 兜底):${hidden.failed.join(" / ")}`);
|
|
13945
|
+
return;
|
|
13946
|
+
}
|
|
13947
|
+
nonCccRestrictions.set(sessionId, hidden.dispose);
|
|
13948
|
+
return;
|
|
13949
|
+
}
|
|
13950
|
+
if (!shouldHide && existing) {
|
|
13951
|
+
try {
|
|
13952
|
+
existing();
|
|
13953
|
+
} catch (e) {
|
|
13954
|
+
console.error(`[serenity-hooks] 非 CCC 工具恢复失败 (session=${sessionId}):`, e.message);
|
|
13955
|
+
}
|
|
13956
|
+
nonCccRestrictions.delete(sessionId);
|
|
13957
|
+
}
|
|
13958
|
+
}
|
|
13959
|
+
/** 会话销毁清理(lifecycle 调用;防 per-会话 Map 无界增长) */
|
|
13960
|
+
function forgetNonCccToolVisibility(sessionId) {
|
|
13961
|
+
const existing = nonCccRestrictions.get(sessionId);
|
|
13962
|
+
if (!existing) return;
|
|
13963
|
+
try {
|
|
13964
|
+
existing();
|
|
13965
|
+
} catch {}
|
|
13966
|
+
nonCccRestrictions.delete(sessionId);
|
|
13967
|
+
}
|
|
13968
|
+
/**
|
|
13868
13969
|
* 从 exec 参数中提取常见路径字段(write/edit 工具);宽松读取。
|
|
13869
13970
|
* container_fs 复合工具:path(单路径)/ paths(数组)/ src / dst——取第一个命中(越界检查
|
|
13870
13971
|
* 逐路径由 decideGuard 单 pathArg 覆盖;多路径字段取首个,避免漏检主体路径)。
|
|
@@ -14736,6 +14837,9 @@ function registerContext(ctx, opts = {}) {
|
|
|
14736
14837
|
const seed = (agent) => {
|
|
14737
14838
|
const cwd = agent.session?.header?.cwd ?? process.cwd();
|
|
14738
14839
|
const root = cccRootForCwd(cwd);
|
|
14840
|
+
try {
|
|
14841
|
+
syncCccToolVisibility(agent, root);
|
|
14842
|
+
} catch {}
|
|
14739
14843
|
if (!root) return;
|
|
14740
14844
|
const key = agentKey(agent);
|
|
14741
14845
|
if (isSkiffSessionId(key)) return;
|
|
@@ -14819,6 +14923,9 @@ function registerContext(ctx, opts = {}) {
|
|
|
14819
14923
|
const key = agentKey(agent);
|
|
14820
14924
|
const downstream = await next();
|
|
14821
14925
|
if (isSkiffSessionId(key)) return downstream;
|
|
14926
|
+
try {
|
|
14927
|
+
syncCccToolVisibility(agent, root);
|
|
14928
|
+
} catch {}
|
|
14822
14929
|
if (root) {
|
|
14823
14930
|
try {
|
|
14824
14931
|
syncSafeModeRestriction(agent, root);
|
|
@@ -22642,6 +22749,9 @@ function cleanupSessionState(sessionId) {
|
|
|
22642
22749
|
try {
|
|
22643
22750
|
forgetExclusiveToolsVisibility(sessionId);
|
|
22644
22751
|
} catch {}
|
|
22752
|
+
try {
|
|
22753
|
+
forgetNonCccToolVisibility(sessionId);
|
|
22754
|
+
} catch {}
|
|
22645
22755
|
try {
|
|
22646
22756
|
forgetLogbookCompactionState(sessionId);
|
|
22647
22757
|
} catch {}
|
package/lib/seams/guards.d.ts
CHANGED
|
@@ -90,6 +90,22 @@ export declare function getExclusiveToolsDiagnostics(): {
|
|
|
90
90
|
export declare function syncExclusiveToolsVisibility(agent: Agent, root: string): void;
|
|
91
91
|
/** 会话销毁清理(lifecycle 调用;本函数按 `${sessionId}::` 前缀回收全部专属工具项) */
|
|
92
92
|
export declare function forgetExclusiveToolsVisibility(sessionId: string): void;
|
|
93
|
+
/** 非 CCC 隐藏诊断(排查"工具为什么不见了") */
|
|
94
|
+
export declare function getNonCccHiddenDiagnostics(): {
|
|
95
|
+
hidden: string[];
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* 同步「本会话在不在 CCC 内」的工具可见性(v1.56.6)。
|
|
99
|
+
*
|
|
100
|
+
* @param agent 目标会话的 agent
|
|
101
|
+
* @param root 该会话的 CCC 根;`null` ⇒ **不在任何 CCC 内** ⇒ 隐藏全部 ACC 工具
|
|
102
|
+
*
|
|
103
|
+
* 幂等:同一会话重复调用不会重复 restrict(已是目标态即直接返回)。
|
|
104
|
+
* 失败不抛(最坏情况:工具可见,但**调用时**仍被各工具自己的根解析拒绝——既有兜底不变)。
|
|
105
|
+
*/
|
|
106
|
+
export declare function syncCccToolVisibility(agent: Agent, root: string | null): void;
|
|
107
|
+
/** 会话销毁清理(lifecycle 调用;防 per-会话 Map 无界增长) */
|
|
108
|
+
export declare function forgetNonCccToolVisibility(sessionId: string): void;
|
|
93
109
|
interface GuardRegistration {
|
|
94
110
|
/** 配置路径;缺省用 DEFAULT_SERENITY_CONFIG_PATHS */
|
|
95
111
|
configPaths?: string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.56.
|
|
3
|
+
"version": "1.56.6",
|
|
4
4
|
"description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:14 个工具(container_fs/container_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/handyman/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 工作日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/trajectory 唤醒注册表。适配 DSH 0.1.7-rc.1 与 0.2.0-rc.1(双档)。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|