@shgroup/dsh-serenity-hooks 1.31.3 → 1.31.4

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.31.3",
3
+ "version": "1.31.4",
4
4
  "main": "lib/index.js",
5
5
  "description": "宁静号 ACC harness(Native Cordis 插件):给 DSH 装一个「AI 工作区」——11 个工具(container_fs/logbook/dashboard/container_git/msm/praxis/handyman/localstore/container_admin/autopilot-trajectory/im-bridge)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 工作日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/自主巡航。适配 DSH 0.1.2-rc.1(deepseek-ai/deepseek-harness)。",
6
6
  "engines": {
@@ -23,10 +23,30 @@ function hostService(ctx, name) {
23
23
  return;
24
24
  }
25
25
  }
26
- /** 直接属性读取(injected 服务:`ctx.<name>`),属性缺失时回落 `ctx.get` */
26
+ /**
27
+ * 直接属性读取(injected 服务:`ctx.<name>`),属性缺失**或读取抛错**时回落 `ctx.get`。
28
+ *
29
+ * v1.31.4 修复(R↓,实证 v1.31.3 真机首测):cordis 的 Context 是 Proxy,
30
+ * `ReflectService.handler.get`(`vendor/cordis/src/reflect.ts`)对**未经 `inject` 声明**
31
+ * 的服务名会沿 fiber 链查找,找不到时**抛错**而非返回 undefined:
32
+ *
33
+ * cannot get property "<name>" without inject
34
+ *
35
+ * 于是"先直接属性读、失败回落 ctx.get"的写法在**真实 cordis** 下永远走不到回落分支——
36
+ * 异常直接逃逸(`hostService` 的 try/catch 被绕过)。v1.31.3 的 `hostSubagents`
37
+ * 正是这样炸的:`subagents` 是 lazy 服务(不在插件 `inject` 列表内)。
38
+ * 现有 fake ctx 单测(普通对象无 getter)复现不了 → 真 cordis 用例见
39
+ * `tests/host/cordis-access.test.ts`。
40
+ *
41
+ * 为什么吞掉异常而不是让它冒泡:本模块的契约是"服务缺失一律返回 undefined,**不抛错**"
42
+ * (宿主对插件 apply 抛错 = 整个 dsh 启动失败)。读取失败 = 服务不可用,等价于缺失。
43
+ */
27
44
  function hostInjected(ctx, name) {
28
- const direct = ctx?.[name];
29
- if (direct !== void 0) return direct;
45
+ const c = ctx;
46
+ try {
47
+ const direct = c?.[name];
48
+ if (direct !== void 0) return direct;
49
+ } catch {}
30
50
  return hostService(ctx, name);
31
51
  }
32
52
  /** `ctx.sessions`(injected) */
@@ -14,7 +14,24 @@
14
14
  */
15
15
  /** 通用读取:`ctx.get(name)`(含异常吞掉——服务 getter 抛错视为不可用) */
16
16
  export declare function hostService<T = unknown>(ctx: unknown, name: string): T | undefined;
17
- /** 直接属性读取(injected 服务:`ctx.<name>`),属性缺失时回落 `ctx.get` */
17
+ /**
18
+ * 直接属性读取(injected 服务:`ctx.<name>`),属性缺失**或读取抛错**时回落 `ctx.get`。
19
+ *
20
+ * v1.31.4 修复(R↓,实证 v1.31.3 真机首测):cordis 的 Context 是 Proxy,
21
+ * `ReflectService.handler.get`(`vendor/cordis/src/reflect.ts`)对**未经 `inject` 声明**
22
+ * 的服务名会沿 fiber 链查找,找不到时**抛错**而非返回 undefined:
23
+ *
24
+ * cannot get property "<name>" without inject
25
+ *
26
+ * 于是"先直接属性读、失败回落 ctx.get"的写法在**真实 cordis** 下永远走不到回落分支——
27
+ * 异常直接逃逸(`hostService` 的 try/catch 被绕过)。v1.31.3 的 `hostSubagents`
28
+ * 正是这样炸的:`subagents` 是 lazy 服务(不在插件 `inject` 列表内)。
29
+ * 现有 fake ctx 单测(普通对象无 getter)复现不了 → 真 cordis 用例见
30
+ * `tests/host/cordis-access.test.ts`。
31
+ *
32
+ * 为什么吞掉异常而不是让它冒泡:本模块的契约是"服务缺失一律返回 undefined,**不抛错**"
33
+ * (宿主对插件 apply 抛错 = 整个 dsh 启动失败)。读取失败 = 服务不可用,等价于缺失。
34
+ */
18
35
  export declare function hostInjected<T = unknown>(ctx: unknown, name: string): T | undefined;
19
36
  export interface HostSessionLike {
20
37
  id?: string;
@@ -61,6 +78,9 @@ export declare function hostWeb(ctx: unknown): HostWeb | undefined;
61
78
  *
62
79
  * 形状对照宿主 rc.1:`SubagentRuntime.start(name, request)` → `SubagentRun`
63
80
  * (`result` / `dispose` / `id`)。本模块只做形状收口;语义与错误处理归调用方。
81
+ *
82
+ * 注(v1.31.4):本服务**不在** dsp 的 `inject` 列表内,因此走 `hostInjected` 的
83
+ * 回落分支(`ctx.get`)——见 `hostInjected` 的 v1.31.4 说明与真实 cordis 用例。
64
84
  */
65
85
  export interface HostSubagents {
66
86
  start?: (name: string, request: unknown) => Promise<unknown>;
package/lib/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { a as findSerenityRoot, c as matchBlacklist, d as readCccName$2, f as readHandymanConfig, i as findGitRoot, l as pathInside, m as resolveInside, n as SAFE_MODE_MARKER, o as isSafeModeOn, r as classifyPath, s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS, u as readBlacklist } from "./ccc-DAsSHsub.js";
3
3
  import { a as readSkiffRoles, d as systemPromptSource, i as isSkiffSessionId, l as roleToolWhitelist, o as resolveRoleSystemPrompt } from "./skiff-role-BYvNnwv1.js";
4
- import { A as skiffRoleFor, C as listActiveHandymen, D as splitModel, E as requireWhitelistedModel, O as writeFailedStatus, S as handymanProgressPaths, T as readProgress, _ as unregisterSkiffSession, a as startSkiffDebugServer, b as HANDYMAN_GUIDE, c as askSkiff, d as ensureWorkspacePromptSection, f as getSkiffAgent, g as skiffTrajectoryEnabled, h as skiffSessionSnapshot, k as writeProgress, l as createSkiffAgent, m as skiffSessionInfo, n as jscSafeJsonText, o as stopSkiffDebugServer, p as skiffMsmGate, r as renderSkiffMarkdown, s as stripThink, t as discoverCccs, u as ensureSkiffSession, v as workspaceTrajectoryLine, w as newStopToken, x as buildRoundPrompt, y as waitAgentIdle } from "./skiff-debug-sdGryydE.js";
5
- import { c as hostWebServer, i as hostSessions, n as hostInjected, o as hostSubagents, r as hostService, s as hostWeb, t as hostAgents } from "./access-BqtkTl9M.js";
4
+ import { A as skiffRoleFor, C as listActiveHandymen, D as splitModel, E as requireWhitelistedModel, O as writeFailedStatus, S as handymanProgressPaths, T as readProgress, _ as unregisterSkiffSession, a as startSkiffDebugServer, b as HANDYMAN_GUIDE, c as askSkiff, d as ensureWorkspacePromptSection, f as getSkiffAgent, g as skiffTrajectoryEnabled, h as skiffSessionSnapshot, k as writeProgress, l as createSkiffAgent, m as skiffSessionInfo, n as jscSafeJsonText, o as stopSkiffDebugServer, p as skiffMsmGate, r as renderSkiffMarkdown, s as stripThink, t as discoverCccs, u as ensureSkiffSession, v as workspaceTrajectoryLine, w as newStopToken, x as buildRoundPrompt, y as waitAgentIdle } from "./skiff-debug-B445WY23.js";
5
+ import { c as hostWebServer, i as hostSessions, n as hostInjected, o as hostSubagents, r as hostService, s as hostWeb, t as hostAgents } from "./access-fiehjxV6.js";
6
6
  import { a as readWeixinCredential, c as weixinInboundDir, d as LOCALSTORE_SCOPES, f as checkLocalstoreGitCompliance, g as runLocalStore, h as readStore, i as matchWeixinRoute, l as weixinSessionIdFor, m as readGitTrack, n as extractWeixinText, o as readWeixinSettings, p as localstorePath, r as hasVoiceItem, s as sanitizeFileName$1, t as extractWeixinMedia } from "./weixin-route-wWk4AIwV.js";
7
7
  import { C as useSession, S as summarize, _ as resolveSessionByTitle, a as archiveSessions, b as setActiveSessionInfo, c as createSession, d as getActiveSessionInfo, f as healthCheck, g as readActiveSessionMd, h as qaCheck, i as SESSION_ACTIONS, l as extractSessionMdPathFromText, m as parseSessionContextFromEvents, n as readLastBound, o as clearActiveSessionInfo, p as listSessions, r as DEFAULT_SESSION_SCOPE, s as closeSession, t as appendBound, u as findSession, v as sessionEvents, x as showSession, y as sessionsRoot } from "./session-bound-BpTayaIS.js";
8
- import { n as registerSettingsSection, t as readSimpleSettings } from "./settings-section-BxoNXUqk.js";
8
+ import { n as registerSettingsSection, t as readSimpleSettings } from "./settings-section-01rTVq6v.js";
9
9
  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-PjEhmjlZ.js";
10
10
  import z from "@deepseek-ai/schemastery";
11
11
  import { defineTool } from "@deepseek-ai/dsh-tools";
@@ -3070,7 +3070,7 @@ async function runForegroundJob(ctx, opts) {
3070
3070
  const { task, label, model, models, parent, signal } = opts;
3071
3071
  requireWhitelistedModel(model, models);
3072
3072
  const subagents = hostSubagents(ctx);
3073
- if (!subagents?.start) throw new Error("handyman foreground: host subagents service unavailable (ctx.subagents.start missing) use mode=\"background\" (does not need this service) or check the host-contract report");
3073
+ if (!subagents?.start) throw new Error("handyman foreground: host subagents service unavailable — neither ctx.subagents nor ctx.get(\"subagents\") yielded a start() function. Check `dashboard health` (host-contract section, service \"subagents\"); mode=\"background\" does not need this service and still works.");
3074
3074
  if (!parent) throw new Error("handyman foreground: requires a calling agent (exec.agent was undefined)");
3075
3075
  const { provider, model: modelName } = splitModel(model);
3076
3076
  const run = await subagents.start("spawn", {
@@ -6999,7 +6999,7 @@ function registerStatusApi(ctx, opts = {}) {
6999
6999
  workspace: url.searchParams.get("workspace") ?? void 0
7000
7000
  });
7001
7001
  const root = findSerenityRoot(workspace) ?? "";
7002
- const { discoverCccs } = await import("./skiff-debug-sdGryydE.js").then((n) => n.i);
7002
+ const { discoverCccs } = await import("./skiff-debug-B445WY23.js").then((n) => n.i);
7003
7003
  sendJson$2(res, 200, { cccs: await discoverCccs(ctx, root) });
7004
7004
  } catch (err) {
7005
7005
  sendJson$2(res, 400, { error: err.message ?? String(err) });
@@ -7029,7 +7029,7 @@ function registerStatusApi(ctx, opts = {}) {
7029
7029
  return;
7030
7030
  }
7031
7031
  const settings = readAdvancedSettings();
7032
- const { readSimpleSettings } = await import("./settings-section-BxoNXUqk.js").then((n) => n.r);
7032
+ const { readSimpleSettings } = await import("./settings-section-01rTVq6v.js").then((n) => n.r);
7033
7033
  const simple = readSimpleSettings();
7034
7034
  const allowed = settings.publicAsk.allowed;
7035
7035
  const port = simple.acpHttpPort ?? 3100;
@@ -10604,7 +10604,7 @@ function matchCcc(input, candidates) {
10604
10604
  }
10605
10605
  /** 组装候选列表(discoverCccs 投影 + `.serenity` 名;动态 import 保持本模块静态依赖轻量) */
10606
10606
  async function collectCandidates(ctx) {
10607
- const { discoverCccs } = await import("./skiff-debug-sdGryydE.js").then((n) => n.i);
10607
+ const { discoverCccs } = await import("./skiff-debug-B445WY23.js").then((n) => n.i);
10608
10608
  const entries = await discoverCccs(ctx, process.cwd());
10609
10609
  const seen = /* @__PURE__ */ new Set();
10610
10610
  const out = [];
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { a as hostSettings } from "./access-BqtkTl9M.js";
2
+ import { a as hostSettings } from "./access-fiehjxV6.js";
3
3
  import z from "@deepseek-ai/schemastery";
4
4
  //#region src/settings-section.ts
5
5
  var settings_section_exports = /* @__PURE__ */ __exportAll({
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { a as findSerenityRoot, f as readHandymanConfig } from "./ccc-DAsSHsub.js";
3
3
  import { a as readSkiffRoles, c as roleMsmWhitelist, f as trajectorySubset, i as isSkiffSessionId, n as buildSkiffBasePrompt, o as resolveRoleSystemPrompt, r as createRolePromptReader, s as resolveSkiffKind } from "./skiff-role-BYvNnwv1.js";
4
- import { i as hostSessions, r as hostService, t as hostAgents } from "./access-BqtkTl9M.js";
4
+ import { i as hostSessions, r as hostService, t as hostAgents } from "./access-fiehjxV6.js";
5
5
  import { b as setActiveSessionInfo, c as createSession, d as getActiveSessionInfo, n as readLastBound, t as appendBound } from "./session-bound-BpTayaIS.js";
6
6
  import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
7
7
  import { basename, join } from "node:path";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.31.3",
3
+ "version": "1.31.4",
4
4
  "description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:11 个工具(container_fs/logbook/dashboard/container_git/msm/praxis/handyman/localstore/container_admin/autopilot-trajectory/im-bridge)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 工作日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/自主巡航。适配 DSH 0.1.2-rc.1。",
5
5
  "license": "MIT",
6
6
  "repository": {