@shgroup/dsh-serenity-hooks 1.27.14 → 1.28.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 +3 -2
- package/lib/{ccc-CfDrlfA7.js → ccc-CX48YNUL.js} +19 -1
- package/lib/ccc.d.ts +9 -0
- package/lib/client.js +26 -55
- package/lib/config-ops.d.ts +21 -10
- package/lib/index.d.ts +3 -2
- package/lib/index.js +485 -174
- package/lib/invariant.d.ts +1 -1
- package/lib/invariant.js +2 -1
- package/lib/kit-ops.d.ts +27 -0
- package/lib/msm-ops.d.ts +16 -2
- package/lib/rebuild.d.ts +5 -0
- package/lib/seams/bootstrap.d.ts +9 -0
- package/lib/seams/guards.d.ts +14 -0
- package/lib/seams/keeper.d.ts +4 -1
- package/lib/seams/system-prompt.d.ts +15 -4
- package/lib/session-ops.d.ts +11 -0
- package/lib/settings-section-BfVxgCZy.js +91 -0
- package/lib/settings-section.d.ts +10 -6
- package/lib/{skiff-debug-BRlc17GU.js → skiff-debug-CBU6T2F_.js} +16 -5
- package/lib/{skiff-role-Dw7UKCUm.js → skiff-role-BTdBHyOQ.js} +1 -1
- package/lib/tools/session.d.ts +23 -6
- package/lib/{weixin-route-BUJLsCGS.js → weixin-route-DFkRf9ou.js} +1 -1
- package/package.json +18 -16
- package/lib/settings-section-PzeHStWP.js +0 -2124
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-serenity-hooks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.28.1",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"description": "宁静号 ACC harness(Native Cordis 插件):真实 DSH 工具 cc_fs/session/acc_msm/eap/neat/cce/handyman/session_rebuild/skiff_admin + 拦截缝机械约束(safe-mode/路径守卫)+ 高级设定面板(双端口网关/账号管理)+ Skiff 认知子集角色(实验性)。适配 DSH 公开版(0.1.0-rc,deepseek-ai/deepseek-harness)。",
|
|
6
6
|
"engines": {
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"handyman",
|
|
20
20
|
"session_rebuild",
|
|
21
21
|
"localstore",
|
|
22
|
-
"skiff_admin"
|
|
22
|
+
"skiff_admin",
|
|
23
|
+
"autopilot-trajectory"
|
|
23
24
|
],
|
|
24
25
|
"skills": []
|
|
25
26
|
}
|
|
@@ -59,6 +59,24 @@ function resolveInside(root, p) {
|
|
|
59
59
|
return abs;
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
|
+
* CCC 名:从 .serenity 标记解析——**跳过 # 注释与空行的首个非空行**。
|
|
63
|
+
* 注册表聚合档路径(.opencode/skills/<cccName>/references/mech-registry.json)以此为准,
|
|
64
|
+
* 是 guards/fs-ops/msm-ops/kit-ops 四处解析的唯一真相源(review P2-2 收口,09-05:
|
|
65
|
+
* 原四处分叉——msm-ops/kit-ops 取严格首行、guards/fs-ops 跳注释——首行为注释/空行时
|
|
66
|
+
* register 目标路径与保护路径分叉,潜在隐患)。
|
|
67
|
+
* @returns CCC 名;无标记/读失败/全注释空行 → null
|
|
68
|
+
*/
|
|
69
|
+
function readCccName(root) {
|
|
70
|
+
try {
|
|
71
|
+
const marker = resolve(root, ".serenity");
|
|
72
|
+
if (!existsSync(marker)) return null;
|
|
73
|
+
const line = readFileSync(marker, "utf-8").split("\n").map((l) => l.trim()).find((l) => l !== "" && !l.startsWith("#"));
|
|
74
|
+
return line && line !== "" ? line : null;
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
62
80
|
* 解析 handyman 配置(v1.24.0:取代 loop.defaultModel;不兼容旧 loop 配置——用户拍板)。
|
|
63
81
|
* @returns 白名单 + 缺省模型 + 上限;models 未配置返回 null(工具应报错要求配置)
|
|
64
82
|
*/
|
|
@@ -138,4 +156,4 @@ function matchBlacklist(relPath, rules) {
|
|
|
138
156
|
return null;
|
|
139
157
|
}
|
|
140
158
|
//#endregion
|
|
141
|
-
export { findSerenityRoot as a, matchBlacklist as c,
|
|
159
|
+
export { findSerenityRoot as a, matchBlacklist as c, readCccName as d, readHandymanConfig as f, findGitRoot as i, pathInside as l, resolveInside as m, SAFE_MODE_MARKER as n, isSafeModeOn as o, readUtf8 as p, classifyPath as r, loadSerenityConfig as s, DEFAULT_SERENITY_CONFIG_PATHS as t, readBlacklist as u };
|
package/lib/ccc.d.ts
CHANGED
|
@@ -22,6 +22,15 @@ export type PathClass = 'inside' | 'outside' | 'same';
|
|
|
22
22
|
export declare function pathInside(rootAbs: string, abs: string, caseInsensitive?: boolean): boolean;
|
|
23
23
|
export declare function classifyPath(p: string, root: string): PathClass;
|
|
24
24
|
export declare function resolveInside(root: string, p: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* CCC 名:从 .serenity 标记解析——**跳过 # 注释与空行的首个非空行**。
|
|
27
|
+
* 注册表聚合档路径(.opencode/skills/<cccName>/references/mech-registry.json)以此为准,
|
|
28
|
+
* 是 guards/fs-ops/msm-ops/kit-ops 四处解析的唯一真相源(review P2-2 收口,09-05:
|
|
29
|
+
* 原四处分叉——msm-ops/kit-ops 取严格首行、guards/fs-ops 跳注释——首行为注释/空行时
|
|
30
|
+
* register 目标路径与保护路径分叉,潜在隐患)。
|
|
31
|
+
* @returns CCC 名;无标记/读失败/全注释空行 → null
|
|
32
|
+
*/
|
|
33
|
+
export declare function readCccName(root: string): string | null;
|
|
25
34
|
export interface SerenityConfig {
|
|
26
35
|
/** handyman(杂工)配置:模型白名单(v1.24.0 取代 loop) */
|
|
27
36
|
handyman?: {
|
package/lib/client.js
CHANGED
|
@@ -3206,44 +3206,18 @@ window.__ModuleLoader__.load({
|
|
|
3206
3206
|
return null;
|
|
3207
3207
|
}
|
|
3208
3208
|
const CONFIG_PATH = "/serenity/config";
|
|
3209
|
-
/**
|
|
3210
|
-
* 获取已有工作区列表(需求 1:白名单从已有工作区选择而非手输)。
|
|
3211
|
-
* 走 DSH 原生 RPC `POST /api/workspace.list`(JSON RPC 形态)。
|
|
3212
|
-
* 信封必须是完整 ClientRequest:`{ type: 'client-request', rpcId, method, payload }`
|
|
3213
|
-
* (api/rpc.ts wire 契约——缺 type/method → clientRequestSchema 校验失败 → bad-request)。
|
|
3214
|
-
* 返回 { path, title }[];失败返回空数组(面板显示"暂无可选工作区")。
|
|
3215
|
-
*/
|
|
3216
|
-
async function fetchWorkspaces() {
|
|
3217
|
-
try {
|
|
3218
|
-
const res = await fetch("/api/workspace.list", {
|
|
3219
|
-
method: "POST",
|
|
3220
|
-
headers: { "content-type": "application/json" },
|
|
3221
|
-
body: JSON.stringify({
|
|
3222
|
-
type: "client-request",
|
|
3223
|
-
rpcId: `ws-${Date.now().toString(36)}`,
|
|
3224
|
-
method: "workspace.list",
|
|
3225
|
-
payload: {}
|
|
3226
|
-
})
|
|
3227
|
-
});
|
|
3228
|
-
if (!res.ok) return [];
|
|
3229
|
-
const items = (await res.json())?.result?.value?.items;
|
|
3230
|
-
if (!Array.isArray(items)) return [];
|
|
3231
|
-
return items.filter((i) => typeof i.path === "string" && i.path !== "").map((i) => ({
|
|
3232
|
-
path: i.path,
|
|
3233
|
-
title: typeof i.title === "string" && i.title !== "" ? i.title : i.path
|
|
3234
|
-
}));
|
|
3235
|
-
} catch {
|
|
3236
|
-
return [];
|
|
3237
|
-
}
|
|
3238
|
-
}
|
|
3239
|
-
/** GET 配置(含账号列表;无 hash) */
|
|
3209
|
+
/** GET 配置(含账号列表 + knownWorkspaces;无 hash) */
|
|
3240
3210
|
async function fetchConfig() {
|
|
3241
3211
|
const res = await fetch(CONFIG_PATH, { headers: {
|
|
3242
3212
|
accept: "application/json",
|
|
3243
3213
|
"x-serenity-ui": "1"
|
|
3244
3214
|
} });
|
|
3245
3215
|
if (!res.ok) return null;
|
|
3246
|
-
|
|
3216
|
+
const body = await res.json();
|
|
3217
|
+
return {
|
|
3218
|
+
config: body.config ?? null,
|
|
3219
|
+
knownWorkspaces: body.knownWorkspaces ?? []
|
|
3220
|
+
};
|
|
3247
3221
|
}
|
|
3248
3222
|
/** PUT 配置(账号 patch + 工作区白名单 + persona 彩蛋 + 开放容器白名单)→ 返回保存后的 wire */
|
|
3249
3223
|
async function saveConfig(patch) {
|
|
@@ -3303,9 +3277,10 @@ window.__ModuleLoader__.load({
|
|
|
3303
3277
|
const [saved, setSaved] = (0, react.useState)(false);
|
|
3304
3278
|
(0, react.useEffect)(() => {
|
|
3305
3279
|
let alive = true;
|
|
3306
|
-
|
|
3280
|
+
fetchConfig().then((resp) => {
|
|
3307
3281
|
if (!alive) return;
|
|
3308
|
-
|
|
3282
|
+
const cfg = resp?.config ?? null;
|
|
3283
|
+
setKnownWorkspaces(resp?.knownWorkspaces ?? []);
|
|
3309
3284
|
if (cfg) {
|
|
3310
3285
|
setConfig(cfg);
|
|
3311
3286
|
setHost(cfg.gateway.host);
|
|
@@ -3734,8 +3709,8 @@ Instruction-following style:
|
|
|
3734
3709
|
let alive = true;
|
|
3735
3710
|
fetchConfig().then((cfg) => {
|
|
3736
3711
|
if (!alive || !cfg) return;
|
|
3737
|
-
setMode(cfg.persona?.mode ?? "");
|
|
3738
|
-
setOverrideText(cfg.persona?.overrideText ?? "");
|
|
3712
|
+
setMode(cfg.config?.persona?.mode ?? "");
|
|
3713
|
+
setOverrideText(cfg.config?.persona?.overrideText ?? "");
|
|
3739
3714
|
setLoaded(true);
|
|
3740
3715
|
});
|
|
3741
3716
|
return () => {
|
|
@@ -3893,7 +3868,7 @@ Instruction-following style:
|
|
|
3893
3868
|
try {
|
|
3894
3869
|
const cfg = await fetchConfig();
|
|
3895
3870
|
if (!alive) return;
|
|
3896
|
-
setAllowed(cfg?.publicAsk?.allowed ?? []);
|
|
3871
|
+
setAllowed(cfg?.config?.publicAsk?.allowed ?? []);
|
|
3897
3872
|
} catch {}
|
|
3898
3873
|
})();
|
|
3899
3874
|
return () => {
|
|
@@ -4737,7 +4712,7 @@ Instruction-following style:
|
|
|
4737
4712
|
scope.set(field, on);
|
|
4738
4713
|
};
|
|
4739
4714
|
const setThreshold = (v) => {
|
|
4740
|
-
scope.set("
|
|
4715
|
+
scope.set("rebuildThresholdK", Math.min(4e3, Math.max(50, Math.round(v))));
|
|
4741
4716
|
};
|
|
4742
4717
|
const setSkiffPort = (v) => {
|
|
4743
4718
|
scope.set("skiffDebugPort", Math.min(65535, Math.max(1024, Math.round(v))));
|
|
@@ -4754,7 +4729,7 @@ Instruction-following style:
|
|
|
4754
4729
|
});
|
|
4755
4730
|
const gatewayOn = value?.gatewayEnabled ?? false;
|
|
4756
4731
|
const rebuildOn = value?.rebuildEnabled ?? true;
|
|
4757
|
-
const
|
|
4732
|
+
const thresholdK = value?.rebuildThresholdK ?? 400;
|
|
4758
4733
|
const skiffOn = value?.skiffEnabled ?? false;
|
|
4759
4734
|
const skiffPort = value?.skiffDebugPort ?? 3099;
|
|
4760
4735
|
const acpOn = value?.acpEnabled ?? false;
|
|
@@ -4796,22 +4771,18 @@ Instruction-following style:
|
|
|
4796
4771
|
})
|
|
4797
4772
|
}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
|
|
4798
4773
|
title: "重建阈值",
|
|
4799
|
-
desc: "
|
|
4800
|
-
help: "
|
|
4801
|
-
control: /* @__PURE__ */ (0, react_jsx_runtime.
|
|
4802
|
-
className: "ss-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4812
|
-
className: "ss-value",
|
|
4813
|
-
children: threshold.toFixed(2)
|
|
4814
|
-
})]
|
|
4774
|
+
desc: "上下文占用达到该 K 数值时提示(单位 K token,默认 400)",
|
|
4775
|
+
help: "重建触发阈值(需求①:K 数值,默认 400K,范围 50~4000K):\n· 含义:上下文 projected tokens 达到 thresholdK × 1000 时,轨迹跟踪器开始提醒重建\n· 纯绝对数值(不再依赖窗口比例)——配多大就多大,无窗口上限保护\n· 迁移:旧版 0~1 比例(settings.yaml rebuildThreshold,如 0.9)已废弃并被忽略——\n 请按 K 数值在此重设(如 0.9 → 900);若从未设置则默认 400K 生效\n· 调低:更早触发(适合长任务,避免上下文耗尽前措手不及)\n· 调高:更晚触发(适合短对话,减少不必要的重建提示)\n· 仅「超限重建」开启时有意义",
|
|
4776
|
+
control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4777
|
+
className: "ss-portInput",
|
|
4778
|
+
type: "number",
|
|
4779
|
+
min: 50,
|
|
4780
|
+
max: 4e3,
|
|
4781
|
+
step: 50,
|
|
4782
|
+
value: thresholdK,
|
|
4783
|
+
disabled: !rebuildOn,
|
|
4784
|
+
title: "重建阈值(K token,默认 400)",
|
|
4785
|
+
onChange: (e) => setThreshold(Number(e.target.value))
|
|
4815
4786
|
})
|
|
4816
4787
|
}) })]
|
|
4817
4788
|
}),
|
package/lib/config-ops.d.ts
CHANGED
|
@@ -42,12 +42,6 @@ export interface GatewaySettings {
|
|
|
42
42
|
/** 是否启用 Authenticator 第二因素(v1.22.4;false = TOTP 完全禁用——登录不要求、绑定入口隐藏) */
|
|
43
43
|
totpEnabled: boolean;
|
|
44
44
|
}
|
|
45
|
-
/** F2 超限重建配置 */
|
|
46
|
-
export interface RebuildSettings {
|
|
47
|
-
enabled: boolean;
|
|
48
|
-
/** contextPressure 触发比例(0~1) */
|
|
49
|
-
thresholdRatio: number;
|
|
50
|
-
}
|
|
51
45
|
/** 彩蛋功能:persona 模式(v1.23.1,S142 用户需求)
|
|
52
46
|
* 配置后替换 ACC 系统提示词中"输出约束/指令遵循约束"部分(EAP 块 + MSM 原则段);
|
|
53
47
|
* 未配置(mode 空)→ 完全默认行为,零影响。 */
|
|
@@ -66,10 +60,15 @@ export interface PublicAskSettings {
|
|
|
66
60
|
/** 开放容器白名单(CCC 目录名,如 home-serenity);空数组 = 全部容器开放 */
|
|
67
61
|
allowed: string[];
|
|
68
62
|
}
|
|
69
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* 高级设定全量(~/.dsh/serenity-hooks.json 持久化形态;passHash 含 hash)。
|
|
65
|
+
* review P2-3:**rebuild 已从高级配置删除**——rebuild 开关/阈值归"简单配置"
|
|
66
|
+
* (settings.yaml 原生面板,见 settings-section.ts),运行时只读 readSimpleSettings();
|
|
67
|
+
* 旧高级 rebuild 字段是死双胞胎(/serenity/config PUT 回显但运行时从不读它)——
|
|
68
|
+
* 删除防误导(用户在高级面板改了却无效)。历史残留字段被 mergeWithDefaults 忽略(幂等安全)。
|
|
69
|
+
*/
|
|
70
70
|
export interface AdvancedSettings {
|
|
71
71
|
gateway: GatewaySettings;
|
|
72
|
-
rebuild: RebuildSettings;
|
|
73
72
|
persona: PersonaSettings;
|
|
74
73
|
publicAsk: PublicAskSettings;
|
|
75
74
|
}
|
|
@@ -131,7 +130,7 @@ export interface GatewayAccountWire {
|
|
|
131
130
|
/** 该账号是否已绑定 TOTP(v1.22.4) */
|
|
132
131
|
hasTotp: boolean;
|
|
133
132
|
}
|
|
134
|
-
/** 设定 wire 形态(GET /serenity/config 返回;
|
|
133
|
+
/** 设定 wire 形态(GET /serenity/config 返回;gateway 去 hash) */
|
|
135
134
|
export interface AdvancedSettingsWire {
|
|
136
135
|
gateway: {
|
|
137
136
|
enabled: boolean;
|
|
@@ -143,7 +142,6 @@ export interface AdvancedSettingsWire {
|
|
|
143
142
|
allowWorkspaceCreate: boolean;
|
|
144
143
|
totpEnabled: boolean;
|
|
145
144
|
};
|
|
146
|
-
rebuild: RebuildSettings;
|
|
147
145
|
persona: PersonaSettings;
|
|
148
146
|
publicAsk: {
|
|
149
147
|
/** 开放容器白名单(v1.26.2:容器名数组;空 = 全部开放) */
|
|
@@ -152,6 +150,19 @@ export interface AdvancedSettingsWire {
|
|
|
152
150
|
}
|
|
153
151
|
/** 持久化 → wire(剥离 passHash/totpSecret;只留布尔) */
|
|
154
152
|
export declare function toWire(settings: AdvancedSettings): AdvancedSettingsWire;
|
|
153
|
+
/**
|
|
154
|
+
* 已知工作区投影(v1.28.0 适配 0.1.2-rc.1 A2 方案 A′):
|
|
155
|
+
* rc.1 workspace.list unary 删除 → AccountsEditor 白名单下拉的数据源改走 gateway 自有
|
|
156
|
+
* /serenity/config 的 knownWorkspaces(host workspaceRegistry.list() 投影,白名单过滤)。
|
|
157
|
+
* 纯函数可单测。allowPrefixes 空 = 全部放行(向后兼容默认)。
|
|
158
|
+
*/
|
|
159
|
+
export declare function projectKnownWorkspaces(workspaces: Array<{
|
|
160
|
+
path?: string;
|
|
161
|
+
title?: string;
|
|
162
|
+
}>, allowPrefixes: readonly string[]): Array<{
|
|
163
|
+
path: string;
|
|
164
|
+
title: string;
|
|
165
|
+
}>;
|
|
155
166
|
/**
|
|
156
167
|
* wire → 持久化(面板 PUT 用):
|
|
157
168
|
* accounts 元素可选带 `pass`:非空 → 重新 hash;空/缺省 → 保留现有 hash(按 id 匹配)。
|
package/lib/index.d.ts
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
import type { Context } from 'cordis';
|
|
15
15
|
import z from '@deepseek-ai/schemastery';
|
|
16
16
|
export declare const name = "dsh-serenity-hooks";
|
|
17
|
-
/** 主动调用的服务;其余(agent 事件)随 harness 装配必然存在
|
|
17
|
+
/** 主动调用的服务;其余(agent 事件)随 harness 装配必然存在
|
|
18
|
+
* (v1.28.0 适配 0.1.2-rc.1:+ 'settings'——B4 settings 服务由 provider 插件加载后才有) */
|
|
18
19
|
export declare const inject: string[];
|
|
19
20
|
/** 插件配置(cordis.yml 提供;进程级) */
|
|
20
21
|
export interface Config {
|
|
@@ -47,7 +48,7 @@ export interface Config {
|
|
|
47
48
|
/** F2 超限重建(entry 默认值,运行时经 DSH settings) */
|
|
48
49
|
rebuild?: {
|
|
49
50
|
enabled?: boolean;
|
|
50
|
-
|
|
51
|
+
thresholdK?: number;
|
|
51
52
|
};
|
|
52
53
|
/** F4 Skiff(实验性):调试服务启停(entry 默认值,运行时经 DSH settings) */
|
|
53
54
|
skiff?: {
|