@shgroup/dsh-serenity-hooks 1.27.1 → 1.27.2

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.27.1",
3
+ "version": "1.27.2",
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": {
package/lib/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { a as findSerenityRoot, c as matchBlacklist, d as readHandymanConfig, i as findGitRoot, l as pathInside, n as SAFE_MODE_MARKER, o as isSafeModeOn, p as resolveInside, r as classifyPath, s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS, u as readBlacklist } from "./ccc-CfDrlfA7.js";
3
3
  import { a as resolveRoleSystemPrompt, i as readSkiffRoles, l as systemPromptSource, r as isSkiffSessionId, s as roleToolWhitelist } from "./skiff-role-Dw7UKCUm.js";
4
- import { C as splitModel, E as skiffRoleFor, S as requireWhitelistedModel, T as writeProgress, _ as buildRoundPrompt, a as startSkiffDebugServer, b as newStopToken, c as askSkiff, d as skiffMsmGate, f as skiffSessionInfo, g as HANDYMAN_GUIDE, h as unregisterSkiffSession, l as createSkiffAgent, m as skiffTrajectoryEnabled, n as jscSafeJsonText, o as stopSkiffDebugServer, p as skiffSessionSnapshot, r as renderSkiffMarkdown, s as stripThink, t as discoverCccs, u as getSkiffAgent, v as handymanProgressPaths, w as writeFailedStatus, x as readProgress, y as listActiveHandymen } from "./skiff-debug-ZVbIqttn.js";
5
- import { a as weixinSessionIdFor, c as checkLocalstoreGitCompliance, d as runLocalStore, i as readWeixinSettings, l as localstorePath, n as matchWeixinRoute, r as readWeixinCredential, s as LOCALSTORE_SCOPES, t as extractWeixinText, u as readGitTrack } from "./weixin-route-CDdlFn1E.js";
4
+ import { C as splitModel, E as skiffRoleFor, S as requireWhitelistedModel, T as writeProgress, _ as buildRoundPrompt, a as startSkiffDebugServer, b as newStopToken, c as askSkiff, d as skiffMsmGate, f as skiffSessionInfo, g as HANDYMAN_GUIDE, h as unregisterSkiffSession, l as createSkiffAgent, m as skiffTrajectoryEnabled, n as jscSafeJsonText, o as stopSkiffDebugServer, p as skiffSessionSnapshot, r as renderSkiffMarkdown, s as stripThink, t as discoverCccs, u as getSkiffAgent, v as handymanProgressPaths, w as writeFailedStatus, x as readProgress, y as listActiveHandymen } from "./skiff-debug-vLsdk7wV.js";
5
+ import { a as weixinSessionIdFor, c as checkLocalstoreGitCompliance, d as runLocalStore, i as readWeixinSettings, l as localstorePath, n as matchWeixinRoute, r as readWeixinCredential, s as LOCALSTORE_SCOPES, t as extractWeixinText, u as readGitTrack } from "./weixin-route-CvAWARN3.js";
6
6
  import { n as sendTextMessage, t as getUpdates } from "./weixin-api-b8HLmcPE.js";
7
7
  import z from "@deepseek-ai/schemastery";
8
8
  import { defineTool } from "@deepseek-ai/dsh-tools";
@@ -8342,7 +8342,7 @@ function registerStatusApi(ctx, opts = {}) {
8342
8342
  workspace: url.searchParams.get("workspace") ?? void 0
8343
8343
  });
8344
8344
  const root = findSerenityRoot(workspace) ?? "";
8345
- const { discoverCccs } = await import("./skiff-debug-ZVbIqttn.js").then((n) => n.i);
8345
+ const { discoverCccs } = await import("./skiff-debug-vLsdk7wV.js").then((n) => n.i);
8346
8346
  sendJson$1(res, 200, { cccs: await discoverCccs(ctx, root) });
8347
8347
  } catch (err) {
8348
8348
  sendJson$1(res, 400, { error: err.message ?? String(err) });
@@ -8468,11 +8468,11 @@ function registerStatusApi(ctx, opts = {}) {
8468
8468
  sendJson$1(res, 400, { error: chk.error });
8469
8469
  return;
8470
8470
  }
8471
- const { readWeixinSettings } = await import("./weixin-route-CDdlFn1E.js").then((n) => n.o);
8471
+ const { readWeixinSettings } = await import("./weixin-route-CvAWARN3.js").then((n) => n.o);
8472
8472
  const { weixinBridgeStatus } = await Promise.resolve().then(() => weixin_bridge_exports);
8473
8473
  const settings = readWeixinSettings(chk.root);
8474
8474
  const bridge = weixinBridgeStatus().find((b) => b.ccc === chk.root);
8475
- const { readWeixinCredential } = await import("./weixin-route-CDdlFn1E.js").then((n) => n.o);
8475
+ const { readWeixinCredential } = await import("./weixin-route-CvAWARN3.js").then((n) => n.o);
8476
8476
  const accounts = (settings.accounts ?? []).map((a) => ({
8477
8477
  accountId: a.accountId,
8478
8478
  name: a.name ?? void 0,
@@ -8504,7 +8504,7 @@ function registerStatusApi(ctx, opts = {}) {
8504
8504
  const { fetchQRCode } = await import("./weixin-api-b8HLmcPE.js").then((n) => n.r);
8505
8505
  const { randomUUID } = await import("node:crypto");
8506
8506
  for (const [key, v] of weixinLogins) if (Date.now() - v.startedAt > WEIXIN_LOGIN_TTL_MS) weixinLogins.delete(key);
8507
- const { readWeixinSettings } = await import("./weixin-route-CDdlFn1E.js").then((n) => n.o);
8507
+ const { readWeixinSettings } = await import("./weixin-route-CvAWARN3.js").then((n) => n.o);
8508
8508
  const qr = await fetchQRCode({ botType: readWeixinSettings(root).botType ?? void 0 });
8509
8509
  const loginKey = randomUUID();
8510
8510
  weixinLogins.set(loginKey, {
@@ -8525,7 +8525,7 @@ function registerStatusApi(ctx, opts = {}) {
8525
8525
  sendJson$1(res, 400, { error: "missing accountId" });
8526
8526
  return;
8527
8527
  }
8528
- const { removeWeixinAccount } = await import("./weixin-route-CDdlFn1E.js").then((n) => n.o);
8528
+ const { removeWeixinAccount } = await import("./weixin-route-CvAWARN3.js").then((n) => n.o);
8529
8529
  const { syncCccBridge } = await Promise.resolve().then(() => weixin_bridge_exports);
8530
8530
  removeWeixinAccount(root, body.accountId);
8531
8531
  syncCccBridge(ctx, root);
@@ -8538,7 +8538,7 @@ function registerStatusApi(ctx, opts = {}) {
8538
8538
  sendJson$1(res, 400, { error: "invalid routes (expected [{user, role}, ...])" });
8539
8539
  return;
8540
8540
  }
8541
- const { saveWeixinRoutes } = await import("./weixin-route-CDdlFn1E.js").then((n) => n.o);
8541
+ const { saveWeixinRoutes } = await import("./weixin-route-CvAWARN3.js").then((n) => n.o);
8542
8542
  const { readSkiffRoles } = await import("./skiff-role-Dw7UKCUm.js").then((n) => n.c);
8543
8543
  const roles = readSkiffRoles(root);
8544
8544
  for (const r of routes) if (!roles.has(r.role)) {
@@ -8551,7 +8551,7 @@ function registerStatusApi(ctx, opts = {}) {
8551
8551
  }
8552
8552
  if (body.action === "set-enabled") {
8553
8553
  const enabled = body.enabled === true;
8554
- const { readWeixinSettings, setWeixinEnabled } = await import("./weixin-route-CDdlFn1E.js").then((n) => n.o);
8554
+ const { readWeixinSettings, setWeixinEnabled } = await import("./weixin-route-CvAWARN3.js").then((n) => n.o);
8555
8555
  const { syncCccBridge } = await Promise.resolve().then(() => weixin_bridge_exports);
8556
8556
  const settings = readWeixinSettings(root);
8557
8557
  if (enabled && (settings.accounts ?? []).length === 0) {
@@ -8598,7 +8598,7 @@ function registerStatusApi(ctx, opts = {}) {
8598
8598
  return;
8599
8599
  }
8600
8600
  const { pollQRStatus } = await import("./weixin-api-b8HLmcPE.js").then((n) => n.r);
8601
- const { readWeixinSettings } = await import("./weixin-route-CDdlFn1E.js").then((n) => n.o);
8601
+ const { readWeixinSettings } = await import("./weixin-route-CvAWARN3.js").then((n) => n.o);
8602
8602
  const settings = readWeixinSettings(login.root);
8603
8603
  const status = await pollQRStatus({
8604
8604
  baseUrl: void 0,
@@ -8613,7 +8613,7 @@ function registerStatusApi(ctx, opts = {}) {
8613
8613
  });
8614
8614
  return;
8615
8615
  }
8616
- const { upsertWeixinAccount, writeWeixinCredential, nextWeixinAccountId } = await import("./weixin-route-CDdlFn1E.js").then((n) => n.o);
8616
+ const { upsertWeixinAccount, writeWeixinCredential, nextWeixinAccountId } = await import("./weixin-route-CvAWARN3.js").then((n) => n.o);
8617
8617
  const { syncCccBridge } = await Promise.resolve().then(() => weixin_bridge_exports);
8618
8618
  const accountId = nextWeixinAccountId(settings);
8619
8619
  upsertWeixinAccount(login.root, {
@@ -10576,7 +10576,9 @@ async function runAccountLoop(ctx, root, accountId, cred, loop) {
10576
10576
  *
10577
10577
  * 会话语义:`weixinSessionIdFor(fromUserId)` 固定可重建——同用户长期同一会话;
10578
10578
  * 进程内已有(getSkiffAgent 命中)→ 延续;无(首次/进程重启)→ createSkiffAgent
10579
- * 以固定 id 新建(角色不变,记忆从新开始——重启后自动重建,与 3100 问答页同语义)。
10579
+ * 固定 id resume-or-create(v1.27.2):磁盘已有持久化 log → resume(历史延续,
10580
+ * 重启后记忆保留——真正的"同用户长期延续");无 log(首次)→ create。
10581
+ * "新的对话已开始"通知仅真正首次(create)时发送;resume/进程内延续不发。
10580
10582
  */
10581
10583
  async function handleIncoming(ctx, root, _accountId, cred, msg) {
10582
10584
  const fromUserId = msg.from_user_id;
@@ -10595,13 +10597,13 @@ async function handleIncoming(ctx, root, _accountId, cred, msg) {
10595
10597
  }
10596
10598
  const sessionId = weixinSessionIdFor(fromUserId);
10597
10599
  const existing = getSkiffAgent(sessionId);
10598
- const recreated = !existing;
10599
10600
  const hc = readHandymanConfig(root);
10600
10601
  const ref = existing ? {
10601
10602
  agent: existing,
10602
- sessionId
10603
+ sessionId,
10604
+ resumed: true
10603
10605
  } : await createSkiffAgent(ctx, root, roleName, role, hc?.defaultModel, sessionId);
10604
- if (recreated) await sendTextMessage({
10606
+ if (!ref.resumed) await sendTextMessage({
10605
10607
  baseUrl: cred.baseUrl,
10606
10608
  token: cred.token,
10607
10609
  toUserId: fromUserId,
@@ -10618,7 +10620,10 @@ async function handleIncoming(ctx, root, _accountId, cred, msg) {
10618
10620
  contextToken: msg.context_token
10619
10621
  });
10620
10622
  } catch (err) {
10621
- console.log(`[serenity-hooks] weixin-bridge error (ccc=${root}): ${err instanceof Error ? err.message : String(err)}`);
10623
+ const msg = err instanceof Error ? err.message : String(err);
10624
+ console.log(`[serenity-hooks] weixin-bridge error (ccc=${root}): ${msg}`);
10625
+ const stack = err instanceof Error ? err.stack : void 0;
10626
+ if (stack) console.log(`[serenity-hooks] weixin-bridge stack:\n${stack.slice(0, 1500)}`);
10622
10627
  }
10623
10628
  }
10624
10629
  /**
@@ -31,10 +31,19 @@ export interface SkiffAgentRef {
31
31
  handle: AgentHandle;
32
32
  agent: Agent;
33
33
  sessionId: string;
34
+ /** true = 从持久化恢复既有会话(历史延续,非新对话);false = 新建(首次/无持久化) */
35
+ resumed: boolean;
34
36
  }
35
37
  /**
36
38
  * 创建 Skiff agent:标准 DSH agent + cwd=CCC root + 角色模型 +
37
39
  * standard preset(平台工具面)+ scoped 系统提示词(基础提示词 + CCC 定义段,全替换 ACC 默认注入)。
40
+ *
41
+ * **固定 sessionId 的 resume-or-create(v1.27.2,微信桥 id collision 修复)**:
42
+ * 指定 sessionId 且磁盘已有持久化 log → `ctx.agents.resume`(DSH 持久化语义:
43
+ * sessionId 即身份,已持久化会话必须 resume——历史 + turn 续号延续,同用户长期记忆保留);
44
+ * 无 log(首次)/持久化未配置 → `ctx.agents.create`(新建)。不指定 sessionId →
45
+ * 随机 id 恒 create(ACP/调试页默认路径)。
46
+ *
38
47
  * @param sessionId 指定会话 id(可选;微信桥等外部面用固定 id 实现用户↔会话长期映射——
39
48
  * 不传则随机生成 skiff-<role>-<uuid>,ACP/调试页默认路径)
40
49
  */
@@ -251,6 +251,13 @@ const SKIFF_PRESET = "standard";
251
251
  /**
252
252
  * 创建 Skiff agent:标准 DSH agent + cwd=CCC root + 角色模型 +
253
253
  * standard preset(平台工具面)+ scoped 系统提示词(基础提示词 + CCC 定义段,全替换 ACC 默认注入)。
254
+ *
255
+ * **固定 sessionId 的 resume-or-create(v1.27.2,微信桥 id collision 修复)**:
256
+ * 指定 sessionId 且磁盘已有持久化 log → `ctx.agents.resume`(DSH 持久化语义:
257
+ * sessionId 即身份,已持久化会话必须 resume——历史 + turn 续号延续,同用户长期记忆保留);
258
+ * 无 log(首次)/持久化未配置 → `ctx.agents.create`(新建)。不指定 sessionId →
259
+ * 随机 id 恒 create(ACP/调试页默认路径)。
260
+ *
254
261
  * @param sessionId 指定会话 id(可选;微信桥等外部面用固定 id 实现用户↔会话长期映射——
255
262
  * 不传则随机生成 skiff-<role>-<uuid>,ACP/调试页默认路径)
256
263
  */
@@ -258,19 +265,12 @@ async function createSkiffAgent(ctx, root, roleName, role, defaultModel, session
258
265
  if (!ctx.agents) throw new Error("skiff: ctx.agents unavailable");
259
266
  const model = role.model?.trim() || defaultModel || "";
260
267
  const id = sessionId ?? `skiff-${roleName}-${randomUUID()}`;
261
- const handle = await ctx.agents.create({
262
- sessionId: id,
263
- meta: {
264
- cwd: root,
265
- agentPreset: SKIFF_PRESET
266
- },
267
- setup: async (agentCtx) => {
268
- try {
269
- await agentCtx.get("agentPresets")?.mount?.(agentCtx, SKIFF_PRESET);
270
- } catch {}
271
- },
272
- ...model ? { agentOptions: splitModel(model) } : {}
273
- });
268
+ const setup = async (agentCtx) => {
269
+ try {
270
+ await agentCtx.get("agentPresets")?.mount?.(agentCtx, SKIFF_PRESET);
271
+ } catch {}
272
+ };
273
+ const handle = await createOrResumeAgent(ctx, id, root, model, setup, sessionId !== void 0);
274
274
  const agent = handle.agent;
275
275
  let cccPrompt = "";
276
276
  try {
@@ -291,9 +291,68 @@ async function createSkiffAgent(ctx, root, roleName, role, defaultModel, session
291
291
  return {
292
292
  handle,
293
293
  agent,
294
- sessionId: id
294
+ sessionId: id,
295
+ resumed: handle.resumed
295
296
  };
296
297
  }
298
+ /**
299
+ * resume-or-create 分派:固定 id → 优先 resume(持久化历史延续),失败降级 create;
300
+ * 随机 id(无固定 sessionId)→ 恒 create。返回 handle + resumed 标志。
301
+ */
302
+ async function createOrResumeAgent(ctx, id, root, model, setup, fixedId) {
303
+ if (!fixedId) return {
304
+ ...await ctx.agents.create({
305
+ sessionId: id,
306
+ meta: {
307
+ cwd: root,
308
+ agentPreset: SKIFF_PRESET
309
+ },
310
+ setup,
311
+ ...model ? { agentOptions: splitModel(model) } : {}
312
+ }),
313
+ resumed: false
314
+ };
315
+ const agentsWithResume = ctx.agents;
316
+ if (typeof agentsWithResume.resume !== "function") return {
317
+ ...await ctx.agents.create({
318
+ sessionId: id,
319
+ meta: {
320
+ cwd: root,
321
+ agentPreset: SKIFF_PRESET
322
+ },
323
+ setup,
324
+ ...model ? { agentOptions: splitModel(model) } : {}
325
+ }),
326
+ resumed: false
327
+ };
328
+ try {
329
+ return {
330
+ ...await agentsWithResume.resume({
331
+ resumeSessionId: id,
332
+ setup,
333
+ ...model ? { agentOptions: splitModel(model) } : {}
334
+ }),
335
+ resumed: true
336
+ };
337
+ } catch (err) {
338
+ const msg = err instanceof Error ? err.message : String(err);
339
+ const stack = err instanceof Error ? err.stack ?? "" : "";
340
+ console.log(`[serenity-hooks] skiff resume 失败降级 create (id=${id}): ${msg}`);
341
+ if (stack) console.log(`[serenity-hooks] skiff resume stack:\n${stack.slice(0, 1200)}`);
342
+ return {
343
+ ...await ctx.agents.create({
344
+ sessionId: id,
345
+ meta: {
346
+ cwd: root,
347
+ agentPreset: SKIFF_PRESET
348
+ },
349
+ setup,
350
+ ...model ? { agentOptions: splitModel(model) } : {}
351
+ }),
352
+ resumed: false
353
+ };
354
+ }
355
+ }
297
356
  /** 等待 agent 空闲(agent/status → idle);无超时(agent 工作多久等多久,handyman 同款) */
298
357
  function waitIdle(ctx, agent) {
299
358
  return new Promise((resolve) => {
@@ -19,7 +19,9 @@ import { type WeixinAccountCredential } from './weixin-route.js';
19
19
  *
20
20
  * 会话语义:`weixinSessionIdFor(fromUserId)` 固定可重建——同用户长期同一会话;
21
21
  * 进程内已有(getSkiffAgent 命中)→ 延续;无(首次/进程重启)→ createSkiffAgent
22
- * 以固定 id 新建(角色不变,记忆从新开始——重启后自动重建,与 3100 问答页同语义)。
22
+ * 固定 id resume-or-create(v1.27.2):磁盘已有持久化 log → resume(历史延续,
23
+ * 重启后记忆保留——真正的"同用户长期延续");无 log(首次)→ create。
24
+ * "新的对话已开始"通知仅真正首次(create)时发送;resume/进程内延续不发。
23
25
  */
24
26
  export declare function handleIncoming(ctx: Context, root: string, _accountId: string, cred: WeixinAccountCredential, msg: {
25
27
  from_user_id?: string;
@@ -282,7 +282,8 @@ function runLocalStore(root, args) {
282
282
  * 职责(零 DSH 依赖,可独立单测):
283
283
  * - 读取 CCC 的 weixin 配置(.opencode/serenity.json weixin 段——结构/路由/开关)
284
284
  * - 读取/写入 CCC localstore 的账号凭据(weixin.accounts.<accountId>.token/.baseUrl/.userId)
285
- * - 微信用户 → skiff 会话 id 映射(固定可重建:skiff-weixin-<sha256(userid)>.slice(16)
285
+ * - 微信用户 → skiff 会话 id 映射(固定可重建:skiff-weixin-<sha256(userid)>.slice(1, 17)
286
+ * v1.27.3 错位一位避开损坏 log)
286
287
  * - 路由匹配(exact user → 通配 * 兜底)
287
288
  *
288
289
  * 配置归属(S142 用户拍板):**CCC 级**——serenity.json 结构 + localstore 凭据分离;
@@ -312,9 +313,12 @@ function accountKeyPart(accountId) {
312
313
  }
313
314
  /** 微信桥 skiff 会话 id 前缀(seams 旁路判定;对外面纯净——守卫识别外部面) */
314
315
  const WEIXIN_SESSION_PREFIX = "skiff-weixin-";
315
- /** 微信用户 → 固定会话 id(同用户长期同一会话,记忆延续;多用户天然隔离) */
316
+ /** 微信用户 → 固定会话 id(同用户长期同一会话,记忆延续;多用户天然隔离)。
317
+ * **v1.27.3 错位一位(用户拍板)**:`.slice(0, 16)` → `.slice(1, 17)`——旧规则生成的
318
+ * 固定 id 已与磁盘损坏的持久化 log 绑定(dsh 不可硬删,create 同 id 必撞)→
319
+ * 新规则下同用户生成**全新 id**,避开损坏 log;固定可重建语义不变(同用户恒同 id)。 */
316
320
  function weixinSessionIdFor(fromUserId) {
317
- const digest = createHash("sha256").update(fromUserId).digest("hex").slice(0, 16);
321
+ const digest = createHash("sha256").update(fromUserId).digest("hex").slice(1, 17);
318
322
  return `${WEIXIN_SESSION_PREFIX}${digest}`;
319
323
  }
320
324
  /**
@@ -4,7 +4,8 @@
4
4
  * 职责(零 DSH 依赖,可独立单测):
5
5
  * - 读取 CCC 的 weixin 配置(.opencode/serenity.json weixin 段——结构/路由/开关)
6
6
  * - 读取/写入 CCC localstore 的账号凭据(weixin.accounts.<accountId>.token/.baseUrl/.userId)
7
- * - 微信用户 → skiff 会话 id 映射(固定可重建:skiff-weixin-<sha256(userid)>.slice(16)
7
+ * - 微信用户 → skiff 会话 id 映射(固定可重建:skiff-weixin-<sha256(userid)>.slice(1, 17)
8
+ * v1.27.3 错位一位避开损坏 log)
8
9
  * - 路由匹配(exact user → 通配 * 兜底)
9
10
  *
10
11
  * 配置归属(S142 用户拍板):**CCC 级**——serenity.json 结构 + localstore 凭据分离;
@@ -15,7 +16,10 @@ import { type WeixinSettings, type WeixinRouteConfig, type WeixinAccountConfig }
15
16
  export declare const WEIXIN_SESSION_PREFIX = "skiff-weixin-";
16
17
  /** 判定 sessionId 是否为微信桥会话(外部面——输出守卫/轨迹隐藏生效) */
17
18
  export declare function isWeixinSessionId(sessionId: string | undefined): boolean;
18
- /** 微信用户 → 固定会话 id(同用户长期同一会话,记忆延续;多用户天然隔离) */
19
+ /** 微信用户 → 固定会话 id(同用户长期同一会话,记忆延续;多用户天然隔离)。
20
+ * **v1.27.3 错位一位(用户拍板)**:`.slice(0, 16)` → `.slice(1, 17)`——旧规则生成的
21
+ * 固定 id 已与磁盘损坏的持久化 log 绑定(dsh 不可硬删,create 同 id 必撞)→
22
+ * 新规则下同用户生成**全新 id**,避开损坏 log;固定可重建语义不变(同用户恒同 id)。 */
19
23
  export declare function weixinSessionIdFor(fromUserId: string): string;
20
24
  /**
21
25
  * 读取 CCC 微信桥配置(未配置/未启用 → 归一默认)。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.27.1",
3
+ "version": "1.27.2",
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": {