@shgroup/dsh-serenity-hooks 1.44.0 → 1.45.0
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/README.md +1 -1
- package/dsh.plugin.json +1 -1
- package/lib/client.js +9 -9
- package/lib/clock-runtime.d.ts +10 -4
- package/lib/index.js +13 -6
- package/lib/{settings-section-DMDUoQum.js → settings-section-CIuyoSOX.js} +3 -3
- package/lib/settings-section.d.ts +12 -6
- package/lib/{wake-scheduler-C2GwdriD.js → wake-scheduler-fVe71jkg.js} +34 -23
- package/lib/wake-scheduler.d.ts +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -289,7 +289,7 @@ DSH 一个进程可以同时带多个工作区,每个工作区各自对接自
|
|
|
289
289
|
| | 内容 |
|
|
290
290
|
|---|---|
|
|
291
291
|
| **程序放哪** | `<CCC 根>/AGENT_SESSIONS/<轨迹目录>/continuous-re-occurrence.ts`(放**轨迹自己目录**里 ⇒ 跟随轨迹跨载体存活、天然进 git) |
|
|
292
|
-
| **开关** |
|
|
292
|
+
| **开关** | ① **逐轨迹**:**文件在 = 启用,文件不在 = 禁用**(无 enabled 字段、无注册表)② 🔴 **总闸**:设置面板「**CRO(轨迹自编程唤起)**」(`croEnabled`,缺省**开**)——关掉**只停 CRO 阶段**,`send-later` / `send-now` / 唤醒表投递**照常工作** |
|
|
293
293
|
| **谁跑它** | ACC 的唤醒调度器(既有 **5 分钟** tick) |
|
|
294
294
|
| **给它什么** | 一条 stdin 进来的 **JSON 快照**:身份 / 时间 / 轨迹身体(SESSION.md 体积与 mtime、`references/` 清单)/ 绑定与载体(绑定的、live 的、🔴 **正在跑轮次的**)/ 调度面(本轨迹在办唤醒、调度器状态) |
|
|
295
295
|
| **它给我什么** | stdout **一行 JSON**:`{"wake":true,"prompt":"…","reason":"…"}` 或 `{"wake":false}`(**缺省 = 不打扰**) |
|
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-serenity-hooks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.45.0",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"description": "宁静号 ACC harness(Native Cordis 插件):给 DSH 装一个「AI 工作区」——11 个工具(container_fs/container_trajectory/dashboard/container_git/msm/praxis/handyman/localstore/container_admin/im-bridge/acc-diag;后两个按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 轨迹日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/trajectory 唤醒注册表。适配 DSH 0.1.5-rc.2(deepseek-ai/deepseek-harness)。",
|
|
6
6
|
"engines": {
|
package/lib/client.js
CHANGED
|
@@ -4825,13 +4825,13 @@ Instruction-following style:
|
|
|
4825
4825
|
const acpOn = value?.acpEnabled ?? false;
|
|
4826
4826
|
const acpPort = value?.acpHttpPort ?? 3100;
|
|
4827
4827
|
const publicAskOn = value?.publicAskEnabled ?? false;
|
|
4828
|
-
const
|
|
4828
|
+
const croOn = value?.croEnabled ?? true;
|
|
4829
4829
|
const [openGateway, setOpenGateway] = (0, react.useState)(false);
|
|
4830
4830
|
const [openRebuild, setOpenRebuild] = (0, react.useState)(false);
|
|
4831
4831
|
const [openSkiff, setOpenSkiff] = (0, react.useState)(false);
|
|
4832
4832
|
const [openAcp, setOpenAcp] = (0, react.useState)(false);
|
|
4833
4833
|
const [openPublicAsk, setOpenPublicAsk] = (0, react.useState)(false);
|
|
4834
|
-
const [
|
|
4834
|
+
const [openCro, setOpenCro] = (0, react.useState)(false);
|
|
4835
4835
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4836
4836
|
className: "ss-section",
|
|
4837
4837
|
children: [
|
|
@@ -4978,20 +4978,20 @@ Instruction-following style:
|
|
|
4978
4978
|
})
|
|
4979
4979
|
}) }),
|
|
4980
4980
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
|
|
4981
|
-
title: "
|
|
4982
|
-
desc: "
|
|
4981
|
+
title: "CRO(轨迹自编程唤起)",
|
|
4982
|
+
desc: "让轨迹用自己的一段程序决定何时唤起(全局开关,默认开)",
|
|
4983
4983
|
expandable: true,
|
|
4984
|
-
open:
|
|
4985
|
-
onToggle:
|
|
4984
|
+
open: openCro,
|
|
4985
|
+
onToggle: setOpenCro,
|
|
4986
4986
|
control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Toggle, {
|
|
4987
|
-
checked:
|
|
4988
|
-
onChange: (on) => toggle("
|
|
4987
|
+
checked: croOn,
|
|
4988
|
+
onChange: (on) => toggle("croEnabled", on)
|
|
4989
4989
|
}),
|
|
4990
4990
|
detail: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4991
4991
|
className: "ss-detailStack",
|
|
4992
4992
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4993
4993
|
className: "ss-detailIntro",
|
|
4994
|
-
children: "
|
|
4994
|
+
children: "CRO = Continuous Re-Occurrence(轨迹自编程唤起)。\n· 作用:轨迹目录下放一个 continuous-re-occurrence.ts,ACC 的 5min tick 会 spawn 它,\n 由这段程序自己决定“要不要唤、何时唤、唤起时说什么”\n· 怎么启用:程序文件在即启用(无需在此配置);本开关是**总闸**\n· 关掉它的后果:**只有 CRO 阶段停跑** —— 定时唤醒(send-later)、即时投递(send-now)\n 与唤醒表投递**照常工作**\n· 默认开:已在生产稳定运行,且“没有程序文件的轨迹”本来就不参与(默认存在感为零)\n· 与它同时废止的开关:原“唤醒调度器”闸(2026-09-21 所有者令砍掉)——\n 唤醒调度器现**恒开**,不再有可被误关的开关"
|
|
4995
4995
|
})
|
|
4996
4996
|
})
|
|
4997
4997
|
}) })
|
package/lib/clock-runtime.d.ts
CHANGED
|
@@ -129,10 +129,16 @@ export interface ClockOptions<T> {
|
|
|
129
129
|
ctx: unknown;
|
|
130
130
|
/** 热启动触发面事件名(回调恒为 `() => start()`——两条钟的触发面同形,不开放自定义回调) */
|
|
131
131
|
events?: string[];
|
|
132
|
-
/**
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
/**
|
|
133
|
+
* 闸(**可选**):**每次现读**(不缓存——面板改开关后要能立刻反映)+ 武装门**只**判它。
|
|
134
|
+
*
|
|
135
|
+
* ⚠️ **2026-09-21(所有者令)起可为缺省**:唤醒调度器的闸已被**砍掉**(原话「send-later 的开关
|
|
136
|
+
* 不再重要了,砍掉」)⇒ 「**本钟没有闸**」必须能被表达。**缺省 = 无闸**:恒武装、永不因闸跳过、
|
|
137
|
+
* `snapshot().enabled` 恒 `true`。(工厂**能力**保留——将来任何钟仍可自带闸。)
|
|
138
|
+
*/
|
|
139
|
+
gate?: () => boolean;
|
|
140
|
+
/** body 被**闸**跳过时写入 `lastSkipReason` 的文案(文案归各钟,工厂不编;**无闸时无意义**) */
|
|
141
|
+
gateOffReason?: string;
|
|
136
142
|
/**
|
|
137
143
|
* **同步前置阶段**(在 body 被调用**之前**、同一个 tick 内同步执行)。
|
|
138
144
|
*
|
package/lib/index.js
CHANGED
|
@@ -6,9 +6,9 @@ import { C as summarize, E as localFileStamp, S as showSession, T as isoLocal, _
|
|
|
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-CWMRa36W.js";
|
|
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-KqQA6pkr.js";
|
|
9
|
-
import { a as FACE_PORTS, c as MECHANISM_PORTS, i as ACP_HTTP_PORT, l as SKIFF_DEBUG_PORT, n as registerSettingsSection, o as GATEWAY_PORT, s as MAIN_WEB_PORT, t as readSimpleSettings, u as WEIXIN_SEND_PORT } from "./settings-section-
|
|
9
|
+
import { a as FACE_PORTS, c as MECHANISM_PORTS, i as ACP_HTTP_PORT, l as SKIFF_DEBUG_PORT, n as registerSettingsSection, o as GATEWAY_PORT, s as MAIN_WEB_PORT, t as readSimpleSettings, u as WEIXIN_SEND_PORT } from "./settings-section-CIuyoSOX.js";
|
|
10
10
|
import { r as sessionsRootDir, t as hasSessionLogById } from "./session-cleanup-BtkSmry8.js";
|
|
11
|
-
import { a as registerDisposer, c as addWake, i as registerCroTurnTracking, l as listWakes, n as sendToTrajectory, o as buildCroSnapshot, r as wakeSchedulerState, s as WAKE_CATCH_UP_MS, t as registerWakeScheduler } from "./wake-scheduler-
|
|
11
|
+
import { a as registerDisposer, c as addWake, i as registerCroTurnTracking, l as listWakes, n as sendToTrajectory, o as buildCroSnapshot, r as wakeSchedulerState, s as WAKE_CATCH_UP_MS, t as registerWakeScheduler } from "./wake-scheduler-fVe71jkg.js";
|
|
12
12
|
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-CtFYm53S.js";
|
|
13
13
|
import z from "@deepseek-ai/schemastery";
|
|
14
14
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
@@ -4365,7 +4365,13 @@ const CRO_GUIDE = `CRO(Continuous Re-Occurrence · 持续再发生)编写指
|
|
|
4365
4365
|
|
|
4366
4366
|
🔴 **文件名必须全写**(不许用缩写)。
|
|
4367
4367
|
🔴 **程序只有一个**:**文件在 = 启用;文件不在 = 禁用**。
|
|
4368
|
-
——
|
|
4368
|
+
—— 没有**逐条**开关、没有注册表、没有 enabled 字段。
|
|
4369
|
+
🔴 **但上面那条只管"这一条"** —— 另有一个**全局总闸** \`croEnabled\`
|
|
4370
|
+
(设置面板「**CRO(轨迹自编程唤起)**」,缺省**开**):
|
|
4371
|
+
关掉**只停 CRO 阶段** —— \`send-later\` / \`send-now\` / 唤醒表投递**照常工作**。
|
|
4372
|
+
⚠️ 所以「**文件在**」**不等于**「**一定会跑**」:总闸关掉时 ACC **根本不调用**你的程序
|
|
4373
|
+
(tick 日志里会记一行跳过理由 —— 这是为了让你事后能分辨
|
|
4374
|
+
「**总闸关着没跑**」和「**跑了、程序自己判了不叫**」这两件完全不同的事)。
|
|
4369
4375
|
|
|
4370
4376
|
## 3. 我给你什么(输入)
|
|
4371
4377
|
ACC 把这条轨迹的状态做成一个 **JSON 快照**,从 **stdin** 喂给你的程序。
|
|
@@ -4427,7 +4433,8 @@ CRO 程序**是可以自测的** —— 因为它只做一件事:**吃一份
|
|
|
4427
4433
|
(纯函数式的边界 ⇒ 不需要真机、不需要等 5 分钟 tick、不需要调度器。)
|
|
4428
4434
|
|
|
4429
4435
|
### 8.1 推荐流程:**用开发名写,绿了再改名**
|
|
4430
|
-
因为「**文件在 =
|
|
4436
|
+
因为「**文件在 = 启用**」**没有逐条开关**(总闸是全局的,管不了单条),
|
|
4437
|
+
**改名这个动作本身就是上线动作**:
|
|
4431
4438
|
|
|
4432
4439
|
1. 先用**开发名**写(如 \`continuous-re-occurrence.dev.ts\`)
|
|
4433
4440
|
—— 开发名**不会**被 ACC 启用(启用只认正式名 exact match),可以放心留一半
|
|
@@ -7057,7 +7064,7 @@ function registerStatusApi(ctx, opts = {}) {
|
|
|
7057
7064
|
return;
|
|
7058
7065
|
}
|
|
7059
7066
|
const settings = readAdvancedSettings();
|
|
7060
|
-
const { readSimpleSettings } = await import("./settings-section-
|
|
7067
|
+
const { readSimpleSettings } = await import("./settings-section-CIuyoSOX.js").then((n) => n.r);
|
|
7061
7068
|
const simple = readSimpleSettings();
|
|
7062
7069
|
const allowed = settings.publicAsk.allowed;
|
|
7063
7070
|
const port = simple.acpHttpPort ?? ACP_HTTP_PORT;
|
|
@@ -14829,7 +14836,7 @@ function renderClock(label, s) {
|
|
|
14829
14836
|
const ts = (ms) => ms === null ? "(从未)" : isoLocal(ms);
|
|
14830
14837
|
const parts = [
|
|
14831
14838
|
`armed=${s.armed}`,
|
|
14832
|
-
|
|
14839
|
+
`CRO 闸=${readSimpleSettings().croEnabled !== false}`,
|
|
14833
14840
|
`tick 次数=${s.ticks}`,
|
|
14834
14841
|
`上次 tick=${ts(s.lastTickAt)}`
|
|
14835
14842
|
];
|
|
@@ -78,7 +78,7 @@ const simpleSettingsSchema = z.object({
|
|
|
78
78
|
acpEnabled: z.boolean().default(false),
|
|
79
79
|
acpHttpPort: z.number().min(1024).max(65535).default(ACP_HTTP_PORT),
|
|
80
80
|
publicAskEnabled: z.boolean().default(false),
|
|
81
|
-
|
|
81
|
+
croEnabled: z.boolean().default(true)
|
|
82
82
|
});
|
|
83
83
|
/** 从插件 Config 提取 entry 默认(settings base 层) */
|
|
84
84
|
function entryDefaults(config) {
|
|
@@ -91,7 +91,7 @@ function entryDefaults(config) {
|
|
|
91
91
|
acpEnabled: config.acp?.enabled ?? false,
|
|
92
92
|
acpHttpPort: config.acp?.httpPort ?? ACP_HTTP_PORT,
|
|
93
93
|
publicAskEnabled: config.publicAsk?.enabled ?? false,
|
|
94
|
-
|
|
94
|
+
croEnabled: true
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
/** 运行时源(installSettingsSection 注入:settings scope 或 entry fallback) */
|
|
@@ -109,7 +109,7 @@ function defaultSimpleSettings() {
|
|
|
109
109
|
acpEnabled: false,
|
|
110
110
|
acpHttpPort: ACP_HTTP_PORT,
|
|
111
111
|
publicAskEnabled: false,
|
|
112
|
-
|
|
112
|
+
croEnabled: true
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
@@ -63,12 +63,18 @@ interface SerenitySimpleSettings {
|
|
|
63
63
|
acpHttpPort: number;
|
|
64
64
|
/** F4d 建议问答页总开关(实验性;默认关——按认知容器暴露问答页,key 认证) */
|
|
65
65
|
publicAskEnabled: boolean;
|
|
66
|
-
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
|
|
66
|
+
/** **CRO(轨迹自编程唤起)总开关** —— 2026-09-21 所有者令新增。
|
|
67
|
+
*
|
|
68
|
+
* CRO = 轨迹目录下放一个 `continuous-re-occurrence.ts`,由 ACC 的 5min tick spawn,
|
|
69
|
+
* 由**程序**决定"要不要唤、何时唤、唤起的提示词是什么"。
|
|
70
|
+
*
|
|
71
|
+
* **缺省开**:① 它已在生产上稳定运行(S151 / S185 各有程序在跑);② 它的**默认存在感为零**
|
|
72
|
+
* ——没有程序文件的轨迹本来就不参与;③ 缺省关会让"已上线的程序突然不跑"(等于静默回退)。
|
|
73
|
+
* **只关 CRO 阶段**:`send-later` / `send-now` / 唤醒表投递**照常**(见 `cro.ts` 头注的承诺)。
|
|
74
|
+
*
|
|
75
|
+
* ⚠️ 与它**同时废止**的键:`wakeSchedulerEnabled`(所有者 2026-09-21 令「send-later 的开关
|
|
76
|
+
* 不再重要了,砍掉」)——唤醒调度器**不再有任何闸**(恒开);旧配置里的该键**静默忽略**。 */
|
|
77
|
+
croEnabled: boolean;
|
|
72
78
|
}
|
|
73
79
|
/** 从插件 Config 提取 entry 默认(settings base 层) */
|
|
74
80
|
export declare function entryDefaults(config: SimpleConfigFragment): SerenitySimpleSettings;
|
|
@@ -2,7 +2,7 @@ import { r as hostService, t as hostAgents } from "./access-fiehjxV6.js";
|
|
|
2
2
|
import { g as resolveInside } from "./ccc-DG4Oc7I1.js";
|
|
3
3
|
import { o as listCccs } from "./ccc-roots-FxWXuZPw.js";
|
|
4
4
|
import { D as localHuman, O as localIdStamp, T as isoLocal, b as sessionsRoot, n as listBoundSessionIds, p as findSession } from "./trajectory-bound-BzdzsDPI.js";
|
|
5
|
-
import { t as readSimpleSettings } from "./settings-section-
|
|
5
|
+
import { t as readSimpleSettings } from "./settings-section-CIuyoSOX.js";
|
|
6
6
|
import { basename, dirname, join } from "node:path";
|
|
7
7
|
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { spawn } from "node:child_process";
|
|
@@ -1280,8 +1280,8 @@ function createClock(opts) {
|
|
|
1280
1280
|
for (const line of lines) console.log(`${opts.logFrom.prefix}${line}`);
|
|
1281
1281
|
};
|
|
1282
1282
|
const tick = () => {
|
|
1283
|
-
if (!opts.gate()) {
|
|
1284
|
-
runtime.lastSkipReason = opts.gateOffReason;
|
|
1283
|
+
if (opts.gate !== void 0 && !opts.gate()) {
|
|
1284
|
+
runtime.lastSkipReason = opts.gateOffReason ?? null;
|
|
1285
1285
|
return;
|
|
1286
1286
|
}
|
|
1287
1287
|
if (opts.begin) try {
|
|
@@ -1315,7 +1315,7 @@ function createClock(opts) {
|
|
|
1315
1315
|
st.wired = true;
|
|
1316
1316
|
attachClockEvents(opts.ctx, api, opts.events);
|
|
1317
1317
|
}
|
|
1318
|
-
if (!opts.gate()) return;
|
|
1318
|
+
if (opts.gate !== void 0 && !opts.gate()) return;
|
|
1319
1319
|
st.timer = setInterval(tick, TICK_MS);
|
|
1320
1320
|
st.timer.unref();
|
|
1321
1321
|
runtime.armed = true;
|
|
@@ -1336,7 +1336,7 @@ function createClock(opts) {
|
|
|
1336
1336
|
start,
|
|
1337
1337
|
dispose,
|
|
1338
1338
|
snapshot: () => ({
|
|
1339
|
-
enabled: opts.gate(),
|
|
1339
|
+
enabled: opts.gate === void 0 ? true : opts.gate(),
|
|
1340
1340
|
...runtime,
|
|
1341
1341
|
...runtime.lastTickLog ? { lastTickLog: [...runtime.lastTickLog] } : {}
|
|
1342
1342
|
}),
|
|
@@ -1389,24 +1389,20 @@ function resolveWakeTarget(root, target) {
|
|
|
1389
1389
|
};
|
|
1390
1390
|
}
|
|
1391
1391
|
/**
|
|
1392
|
-
*
|
|
1392
|
+
* 🔴 **本钟的全局闸已于 2026-09-21 砍掉**(所有者令逐字:「**send-later 的开关不再重要了,砍掉**」)。
|
|
1393
1393
|
*
|
|
1394
|
-
*
|
|
1395
|
-
*
|
|
1396
|
-
*
|
|
1397
|
-
*
|
|
1398
|
-
* 缺省由 false 改 true 的理由:唤醒注册表已是一等机制(D58),条目**全部由人类/agent 显式登记**
|
|
1399
|
-
* 未来时刻(无环境自主性),不需要"默认关"的实验保护;代价 = 一个 unref 的 5min 空检查。
|
|
1394
|
+
* **为什么砍**(R↓):唤醒已从"可选实验能力"长成**全容器的续接绳**——S142/S151/S185 的链、
|
|
1395
|
+
* 跨轨迹投递、`send-now`/`send-later` 都走它。留一个"能被误关的开关"的**代价**是
|
|
1396
|
+
* "整条链静默停摆且无人告警"(本仓已实测过同族事故:闸关 6.6h 零 tick、断链 1 天 14 小时);
|
|
1397
|
+
* 而**收益**只剩"关掉一个 5min unref 空检查"。⇒ **收益 < 代价,故删闸**(不是改为缺省开——是**没有这个键了**)。
|
|
1400
1398
|
*
|
|
1401
|
-
*
|
|
1399
|
+
* ⚠️ **兼容**:旧配置文件里残留的 `wakeSchedulerEnabled` **静默忽略**(无回退键、无告警噪声;
|
|
1400
|
+
* 与旧 `bootstrap` 段的处置先例一致)。**机制本身一行未动**(所有者:"我说的只是开关")。
|
|
1401
|
+
*
|
|
1402
|
+
* 历史(勿误读):v1.34 S-1 曾把两闸解耦(周期自唤醒 `autopilotWakeEnabled` / 本钟 `wakeSchedulerEnabled`),
|
|
1403
|
+
* 理由是"关 auto-trajectory 不得连带关一次性唤醒";随 ACC 侧 autopilot 于 v1.35.0 整段退场,
|
|
1404
|
+
* 两闸只剩本钟一座 ⇒ 现已整座移除。详见 `docs/trajectory-scheduling.md` §S-1 与 v1.44 CHANGELOG。
|
|
1402
1405
|
*/
|
|
1403
|
-
function wakeSchedulerEnabled() {
|
|
1404
|
-
try {
|
|
1405
|
-
return readSimpleSettings().wakeSchedulerEnabled !== false;
|
|
1406
|
-
} catch {
|
|
1407
|
-
return false;
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
1406
|
/**
|
|
1411
1407
|
* 🔴 **本钟的串行域**(C6b 硬约束):`clock.chain` 是**本实例私有**的——
|
|
1412
1408
|
* 与 autopilot 的串行链**零共享**。autopilot 每轮跑 CCC 偏见脚本可能阻塞数十秒,
|
|
@@ -1422,8 +1418,6 @@ const clockOpts = {
|
|
|
1422
1418
|
label: "trajectory 唤醒调度器",
|
|
1423
1419
|
ctx: void 0,
|
|
1424
1420
|
events: ["session/created", "serenity/settings-changed"],
|
|
1425
|
-
gate: wakeSchedulerEnabled,
|
|
1426
|
-
gateOffReason: "唤醒调度器闸关闭(wakeSchedulerEnabled=false)",
|
|
1427
1421
|
body: () => runWakeTick(clockOpts.ctx),
|
|
1428
1422
|
logFrom: {
|
|
1429
1423
|
prefix: "[serenity-hooks] trajectory 唤醒 ",
|
|
@@ -1432,7 +1426,9 @@ const clockOpts = {
|
|
|
1432
1426
|
startLog: () => "[serenity-hooks] ✓ trajectory 唤醒调度器启动(5min tick)"
|
|
1433
1427
|
};
|
|
1434
1428
|
const clock = createClock(clockOpts);
|
|
1435
|
-
/**
|
|
1429
|
+
/** 调度器进程态快照(只读)。
|
|
1430
|
+
* ⚠️ `enabled` 对**本钟已无意义**(2026-09-21 起无闸 ⇒ 恒 `true`);保留字段只为沿用工厂快照形状。
|
|
1431
|
+
* "这轮为什么没被唤起"现在看 `armed` / `lastSkipReason`(tick 内真实原因)+ **CRO 闸**(见 `croEnabled`)。 */
|
|
1436
1432
|
function wakeSchedulerState() {
|
|
1437
1433
|
return clock.snapshot();
|
|
1438
1434
|
}
|
|
@@ -1443,6 +1439,17 @@ function wakeSchedulerState() {
|
|
|
1443
1439
|
* @param dirName 目标 trajectory 目录名
|
|
1444
1440
|
* @returns 命中返回 agent 与取得方式(how 进 lastResult,便于诊断);未命中返回原因
|
|
1445
1441
|
* (原因带 `notReady` = **环境未就绪**而非投递失败,调用方**不得**据此记一次失败)
|
|
1442
|
+
*
|
|
1443
|
+
* 🔴 **前置条件:本轨迹名下必须有一条「未取代」的绑定记录**(2026-09-20 回源码答复 S151 实测):
|
|
1444
|
+
* 选人是**遍历 `listBoundSessionIds(root, dirName)` 给出的 id**(按绑定时间倒序),**live 只是这条
|
|
1445
|
+
* 记录的一个加分项**——「绑定里的那条恰好 live ⇒ 直接注入」,否则走冷载入。
|
|
1446
|
+
* ⇒ **「有 live 会话」≠「有绑定」**:会话活着但该轨迹**零条未取代绑定**时,本函数**直接返回
|
|
1447
|
+
* `无绑定会话记录…`**(`send-now` / `send-later` 到点投递同此判据)。
|
|
1448
|
+
* 实证(2026-09-20):S142 三条旧绑定于 **08:03** 被 `supersededAt` 取代(D69「同轨迹只留一条」),
|
|
1449
|
+
* 而当前载体的绑定**直到 17:05 那次 rebuild 才写入**(`queueRebuild` 内的 `appendBound(action:'rebuild')`)
|
|
1450
|
+
* ⇒ **10:42 的 `send-now` 落在这个窗口里** ⇒ 报"无绑定会话记录"(当时确有 live 会话)。
|
|
1451
|
+
* ⚠️ 已知**注释漂移**:本行上方"→ 标题回退"在函数体内**没有对应分支**(标题回退属 v1.29.2 R2,
|
|
1452
|
+
* 现行实现已只认绑定);**仅登记,未改**(改它属 ACC 代码改动,须具名令)。
|
|
1446
1453
|
*/
|
|
1447
1454
|
async function acquireWakeAgent(ctx, root, dirName) {
|
|
1448
1455
|
const agents = hostAgents(ctx);
|
|
@@ -1760,6 +1767,10 @@ async function deliverCroWake(ctx, root, dirName, prompt, reason) {
|
|
|
1760
1767
|
* @param log 本 tick 的人读摘要(就地追加)
|
|
1761
1768
|
*/
|
|
1762
1769
|
async function runCroPhase(ctx, root, registry, log) {
|
|
1770
|
+
if (readSimpleSettings().croEnabled === false) {
|
|
1771
|
+
log.push("CRO 阶段:已关闭(croEnabled=false)——既有唤醒投递不受影响");
|
|
1772
|
+
return;
|
|
1773
|
+
}
|
|
1763
1774
|
let dirs;
|
|
1764
1775
|
try {
|
|
1765
1776
|
dirs = listCroTrajectories(root);
|
package/lib/wake-scheduler.d.ts
CHANGED
|
@@ -68,7 +68,9 @@ interface WakeTarget {
|
|
|
68
68
|
* @returns 命中返回目录信息,未命中 null
|
|
69
69
|
*/
|
|
70
70
|
export declare function resolveWakeTarget(root: string, target: string): WakeTarget | null;
|
|
71
|
-
/**
|
|
71
|
+
/** 调度器进程态快照(只读)。
|
|
72
|
+
* ⚠️ `enabled` 对**本钟已无意义**(2026-09-21 起无闸 ⇒ 恒 `true`);保留字段只为沿用工厂快照形状。
|
|
73
|
+
* "这轮为什么没被唤起"现在看 `armed` / `lastSkipReason`(tick 内真实原因)+ **CRO 闸**(见 `croEnabled`)。 */
|
|
72
74
|
export declare function wakeSchedulerState(): WakeSchedulerRuntime & {
|
|
73
75
|
enabled: boolean;
|
|
74
76
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.45.0",
|
|
4
4
|
"description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:11 个工具(container_fs/container_trajectory/dashboard/container_git/msm/praxis/handyman/localstore/container_admin/im-bridge/acc-diag)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 工作日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/trajectory 唤醒注册表。适配 DSH 0.1.5-rc.2。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|