@shgroup/dsh-serenity-hooks 1.68.0 → 1.69.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 +1 -1
- package/lib/api.d.ts +27 -4
- package/lib/ccc.d.ts +0 -63
- package/lib/client.js +6 -340
- package/lib/index.d.ts +0 -28
- package/lib/index.js +182 -1236
- package/lib/ports.d.ts +3 -5
- package/lib/{settings-section-B1YzjFz6.js → settings-section-DcZPcWPv.js} +2 -28
- package/lib/settings-section.d.ts +0 -22
- package/lib/voyage-page.d.ts +5 -0
- package/lib/voyage-vocab.d.ts +51 -0
- package/lib/weixin-route-D_DvgPqy.js +558 -0
- package/package.json +1 -1
- package/lib/acp-auth.d.ts +0 -273
- package/lib/acp-face.d.ts +0 -244
- package/lib/localstore-ops-ylQoPz1Q.js +0 -282
- package/lib/weixin-route-BoSC-uPp.js +0 -281
package/lib/ports.d.ts
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
* 本模块是**零依赖叶模块**(纯常量,无 import)——output-guard(守卫词表)、config-ops
|
|
21
21
|
* (默认值)、settings-section(面板默认)、index(Config 默认)都可安全引用而不引入依赖环。
|
|
22
22
|
*/
|
|
23
|
-
/**
|
|
24
|
-
export type FaceId = 'main' | 'gateway' | 'weixinSend' | 'skiffDebug'
|
|
23
|
+
/** 面标识(四个对外面;A 由宿主监听,B/C/D 由本插件监听) */
|
|
24
|
+
export type FaceId = 'main' | 'gateway' | 'weixinSend' | 'skiffDebug';
|
|
25
25
|
/** 一个面的端口语义 */
|
|
26
26
|
export interface PortSpec {
|
|
27
27
|
/** 端口号 */
|
|
@@ -36,7 +36,7 @@ export interface PortSpec {
|
|
|
36
36
|
/**
|
|
37
37
|
* 集中端口表。
|
|
38
38
|
* A=宿主主面(插件不监听)/ B=网关(可配,默认关)/ C=微信发送(默认开,仅 loopback)
|
|
39
|
-
* / D=Skiff
|
|
39
|
+
* / D=Skiff 调试(默认关)。
|
|
40
40
|
*/
|
|
41
41
|
export declare const FACE_PORTS: Readonly<Record<FaceId, PortSpec>>;
|
|
42
42
|
/** 宿主主 WebUI 端口(面 A:插件**不监听**,只读取;`readWebPort` 的回退值) */
|
|
@@ -47,8 +47,6 @@ export declare const GATEWAY_PORT: number;
|
|
|
47
47
|
export declare const WEIXIN_SEND_PORT: number;
|
|
48
48
|
/** Skiff 调试页端口默认值(面 D) */
|
|
49
49
|
export declare const SKIFF_DEBUG_PORT: number;
|
|
50
|
-
/** 官方 ACP 面端口默认值(面 E,2026-10-16) */
|
|
51
|
-
export declare const ACP_PORT: number;
|
|
52
50
|
/**
|
|
53
51
|
* **机制端口**词表(output-guard 用:agent 在**用户可见输出**里提及内部端口即打回)。
|
|
54
52
|
*
|
|
@@ -41,7 +41,7 @@ function unregisterSkiffSession(sessionId) {
|
|
|
41
41
|
/**
|
|
42
42
|
* 集中端口表。
|
|
43
43
|
* A=宿主主面(插件不监听)/ B=网关(可配,默认关)/ C=微信发送(默认开,仅 loopback)
|
|
44
|
-
* / D=Skiff
|
|
44
|
+
* / D=Skiff 调试(默认关)。
|
|
45
45
|
*/
|
|
46
46
|
const FACE_PORTS = {
|
|
47
47
|
main: {
|
|
@@ -67,26 +67,6 @@ const FACE_PORTS = {
|
|
|
67
67
|
host: "127.0.0.1",
|
|
68
68
|
defaultEnabled: false,
|
|
69
69
|
meaning: "Skiff 调试问答面(人工调试子角色;无认证,仅靠 loopback)"
|
|
70
|
-
},
|
|
71
|
-
/**
|
|
72
|
-
* 🔴 面 E:**官方 ACP 面**(2026-10-16,owner 令「跑在 dsh web 进程内」→ 已实测跑通)。
|
|
73
|
-
*
|
|
74
|
-
* 与已退役的**旧面 E(3100)不是一回事**,别混淆:
|
|
75
|
-
* · 旧面 E = 当年**自造**的 HTTP+HTML 问答面,2026-10-15 owner 裁「砍掉外部问答」时**整组退役**;
|
|
76
|
-
* · 本面 = **官方 `@deepseek-ai/dsh-acp`**(官方 SDK + 现成客户端 Agmente),
|
|
77
|
-
* 且**跑在宿主 web 进程内**(不另起进程、不需要 stdio 桥)。
|
|
78
|
-
* ⇒ 端口**另选 3200**:既避开 3080/3081/3082/3099,也让"新旧一眼可分"。
|
|
79
|
-
*
|
|
80
|
-
* ⚠️ **安全边界(不许含混)**:**ACP 协议本身不做认证**(`dsh-acp` 的 `authenticate` 恒成功),
|
|
81
|
-
* 而本面按 owner 裁决绑 **`0.0.0.0`**(局域网内任何设备可连)⇒ **必须靠外部接入层兜底**
|
|
82
|
-
* (现为 Cloudflare Access)。⛔ **"隧道不是 ACC 该关心的事"(Q3 裁决)成立,但
|
|
83
|
-
* "所以不需要认证层"不成立** —— 交付文档与诊断输出里都要显式带这个前提。
|
|
84
|
-
*/
|
|
85
|
-
acp: {
|
|
86
|
-
port: 3200,
|
|
87
|
-
host: "0.0.0.0",
|
|
88
|
-
defaultEnabled: false,
|
|
89
|
-
meaning: "官方 ACP 面(Agmente 等标准客户端登入本 CCC;**协议无认证**,靠外部 Access 兜底)"
|
|
90
70
|
}
|
|
91
71
|
};
|
|
92
72
|
/** 宿主主 WebUI 端口(面 A:插件**不监听**,只读取;`readWebPort` 的回退值) */
|
|
@@ -97,8 +77,6 @@ const GATEWAY_PORT = FACE_PORTS.gateway.port;
|
|
|
97
77
|
const WEIXIN_SEND_PORT = FACE_PORTS.weixinSend.port;
|
|
98
78
|
/** Skiff 调试页端口默认值(面 D) */
|
|
99
79
|
const SKIFF_DEBUG_PORT = FACE_PORTS.skiffDebug.port;
|
|
100
|
-
/** 官方 ACP 面端口默认值(面 E,2026-10-16) */
|
|
101
|
-
const ACP_PORT = FACE_PORTS.acp.port;
|
|
102
80
|
/**
|
|
103
81
|
* **机制端口**词表(output-guard 用:agent 在**用户可见输出**里提及内部端口即打回)。
|
|
104
82
|
*
|
|
@@ -124,8 +102,6 @@ function defaultSimpleSettings() {
|
|
|
124
102
|
skiffDebugPort: SKIFF_DEBUG_PORT,
|
|
125
103
|
croEnabled: true,
|
|
126
104
|
diagramEnabled: false,
|
|
127
|
-
acpFaceEnabled: false,
|
|
128
|
-
acpFacePort: ACP_PORT,
|
|
129
105
|
humanChannel: defaultHumanChannelSettings()
|
|
130
106
|
};
|
|
131
107
|
}
|
|
@@ -221,8 +197,6 @@ function simpleSettingsFromConfig(config) {
|
|
|
221
197
|
skiffDebugPort: unwrapVolatile(config.skiffDebugPort) ?? config.skiff?.debugPort ?? d.skiffDebugPort,
|
|
222
198
|
croEnabled: unwrapVolatile(config.croEnabled) ?? d.croEnabled,
|
|
223
199
|
diagramEnabled: unwrapVolatile(config.diagramEnabled) ?? config.diagram?.enabled ?? d.diagramEnabled,
|
|
224
|
-
acpFaceEnabled: unwrapVolatile(config.acpFaceEnabled) ?? config.acpFace?.enabled ?? d.acpFaceEnabled,
|
|
225
|
-
acpFacePort: unwrapVolatile(config.acpFacePort) ?? config.acpFace?.port ?? d.acpFacePort,
|
|
226
200
|
humanChannel: humanChannelSettingsFromConfig(config.humanChannel)
|
|
227
201
|
};
|
|
228
202
|
}
|
|
@@ -261,4 +235,4 @@ function registerSettingsSection(ctx, config) {
|
|
|
261
235
|
} catch {}
|
|
262
236
|
}
|
|
263
237
|
//#endregion
|
|
264
|
-
export {
|
|
238
|
+
export { GATEWAY_PORT as a, SKIFF_DEBUG_PORT as c, skiffRoleFor as d, skiffSessionInfo as f, FACE_PORTS as i, WEIXIN_SEND_PORT as l, ACC_VERSION as m, readSimpleSettings as n, MAIN_WEB_PORT as o, unregisterSkiffSession as p, registerSettingsSection as r, MECHANISM_PORTS as s, SERENITY_SETTINGS_NS as t, registerSkiffSession as u };
|
|
@@ -69,13 +69,6 @@ interface SimpleConfigFragment {
|
|
|
69
69
|
diagram?: {
|
|
70
70
|
enabled?: boolean;
|
|
71
71
|
};
|
|
72
|
-
/** 🔴 面 E(官方 ACP,2026-10-16 owner 令「跑在 dsh web 进程内」):部署层嵌套段。
|
|
73
|
-
* ⚠️ **键名刻意不用 `acp.*`** —— 旧面 E 退役时 `acp.*` 是**被静默忽略**的遗留名,
|
|
74
|
-
* 复用会让"当年那份旧配置"在新面上复活(判据:退役 ≠ 删名,名字仍需保留为"无人读")。 */
|
|
75
|
-
acpFace?: {
|
|
76
|
-
enabled?: boolean;
|
|
77
|
-
port?: number;
|
|
78
|
-
};
|
|
79
72
|
/** human-channel(人机信道;**机器级**;2026-09-26 owner 定案):账号 / 订阅表 / 主控 / 出站白名单 */
|
|
80
73
|
humanChannel?: HumanChannelConfigFragment;
|
|
81
74
|
gatewayEnabled?: PanelBoolean;
|
|
@@ -84,9 +77,6 @@ interface SimpleConfigFragment {
|
|
|
84
77
|
skiffDebugPort?: PanelNumber;
|
|
85
78
|
croEnabled?: PanelBoolean;
|
|
86
79
|
diagramEnabled?: PanelBoolean;
|
|
87
|
-
/** 🔴 面 E(官方 ACP,2026-10-16):开关 + 端口(面板层扁平键) */
|
|
88
|
-
acpFaceEnabled?: PanelBoolean;
|
|
89
|
-
acpFacePort?: PanelNumber;
|
|
90
80
|
}
|
|
91
81
|
/**
|
|
92
82
|
* 设置面板命名空间 = **profile 条目 id**(v0.1.7 起;与旧 `settings.yaml` 段名逐字相同)。
|
|
@@ -122,18 +112,6 @@ interface SerenitySimpleSettings {
|
|
|
122
112
|
* 零 token、不会被误调),同 `skiff` 的"未开启零资源占用"口径。
|
|
123
113
|
* 依赖面:随包分发 3.8 MB 内置字体(`assets/diagram/`,wasm 对系统字体不可见)。 */
|
|
124
114
|
diagramEnabled: boolean;
|
|
125
|
-
/** 🔴 **面 E:官方 ACP 总开关**(2026-10-16 owner 令「跑在 dsh web 进程内」;**缺省关**)。
|
|
126
|
-
*
|
|
127
|
-
* 开启后:ACC 在自己进程里起一个 **ACP 服务面**(面宿主统一建 listener),
|
|
128
|
-
* 标准 ACP 客户端(Agmente 等)经 WebSocket 登入本 CCC —— **不另起进程、不需 stdio 桥**。
|
|
129
|
-
* **缺省关**:① 它把本 CCC 开给外部客户端;② ⚠️ **ACP 协议本身无认证**(`dsh-acp` 的
|
|
130
|
-
* `authenticate` 恒成功),而本面按 owner 裁决绑 **`0.0.0.0`** ⇒ **开之前必须有外部接入层
|
|
131
|
-
* 兜底**(现为 Cloudflare Access)。缺省关 = "不配就没有暴露面"。
|
|
132
|
-
* ⚠️ **与已退役的旧面 E(3100 自造问答面)无关**:本面是**官方** `@deepseek-ai/dsh-acp`。
|
|
133
|
-
* 实测(P0′,8/8)见 S142 `2026-10-16T0745-…-p0prime-inproc-findings.md`。 */
|
|
134
|
-
acpFaceEnabled: boolean;
|
|
135
|
-
/** 面 E 端口(默认 3200;避开 3080/3081/3082/3099 与已退役的 3100) */
|
|
136
|
-
acpFacePort: number;
|
|
137
115
|
/** **human-channel(人机信道)机器级配置**(2026-09-26 owner 定案;P0-1 立 schema + 投影)。
|
|
138
116
|
* 三张表(账号 / 订阅 / 主控)+ 出站白名单;**跨 CCC** ⇒ 归机器级,CCC 侧 `weixin.*` 随之退役
|
|
139
117
|
* (退役动作在 P0-2~P0-4;本版**只立机器级面**,旧面照旧)。缺省与归一规则见
|
package/lib/voyage-page.d.ts
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* 技能/公理/MSM/本体词元与实测容器规模数字。
|
|
22
22
|
*/
|
|
23
23
|
import type { Context } from 'cordis';
|
|
24
|
+
import type { IncomingMessage } from 'node:http';
|
|
24
25
|
export declare const VOYAGE_PATH = "/serenity/voyage";
|
|
25
26
|
/**
|
|
26
27
|
* 资产相对包根的路径。
|
|
@@ -38,7 +39,11 @@ export declare function resetVoyageCache(): void;
|
|
|
38
39
|
/**
|
|
39
40
|
* 注册 `/serenity/voyage`(GET)。
|
|
40
41
|
* @param opts.assetPath 覆盖资产路径(测试用;生产不传)
|
|
42
|
+
* @param opts.resolveRoot 解析本次请求所属 CCC 根(生产由 api.ts 的 resolveWorkspace 提供)。
|
|
43
|
+
* 🔴 **2026-10-18 新增**:词表按请求所属 CCC **运行时注入**(owner 报「在别的 CCC 点开
|
|
44
|
+
* 显示的还是 home-serenity 的信息」)。不传 ⇒ 不注入(保持资产原样 = 旧行为)。
|
|
41
45
|
*/
|
|
42
46
|
export declare function registerVoyageApi(ctx: Context, opts?: {
|
|
43
47
|
assetPath?: string;
|
|
48
|
+
resolveRoot?: (req: IncomingMessage) => string | null;
|
|
44
49
|
}): void;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* voyage-vocab.ts — 航行页词表改为**按当前 CCC 运行时注入**(纯逻辑,零 DSH 依赖)
|
|
3
|
+
*
|
|
4
|
+
* ## 为什么需要它(owner 2026-10-18 报的缺陷)
|
|
5
|
+
* 资产 `assets/serenity-voyage.html` 的词表是**构建期扫描容器写死的常量**:
|
|
6
|
+
* `var VOCAB = {"skills":[...],"msms":[...],"zh":[...],"onto":[...],"counts":{...}}`
|
|
7
|
+
* v2 改版把"写死名单"改成"构建期扫描"是为防名单漂移——方向对,但代价是:
|
|
8
|
+
* **一份静态资产只能属于一个 CCC**。于是任何别的 CCC 打开动画,看到的都是
|
|
9
|
+
* **构建它的那个 CCC** 的技能/工具/本体名字与计数。owner 原话:
|
|
10
|
+
* 「为什么我在别的 CCC 点开显示的还是我们 home-serenity 的信息」「动画也有这个毛病」。
|
|
11
|
+
*
|
|
12
|
+
* ## 修法(owner 裁决:运行时按当前 CCC 注入)
|
|
13
|
+
* 资产**保持静态**(一份文件服务所有 CCC,永不漂);由它的**服务端路由**在返回前
|
|
14
|
+
* 把 `var VOCAB = {...};` 那一行替换成从该请求所属 CCC 实况读出的词表。
|
|
15
|
+
*
|
|
16
|
+
* 三条判据(R↓):
|
|
17
|
+
* ① **只替换那一行**(锚 = 行首 `var VOCAB = ` 到行尾 `;`)—— 资产里其余 3000+ 行
|
|
18
|
+
* three.js / 渲染代码**一个字节都不动**。
|
|
19
|
+
* ② **读不出来就走原样**:锚认不出、或原 VOCAB 解析失败 ⇒ **返回入参本身**,不报错。
|
|
20
|
+
* 航行页是**装饰**,不该因为某个 CCC 缺目录、或资产结构变了就打不开(旁路容忍铁律)。
|
|
21
|
+
* ③ **`zh` 不来自容器**:中文隐喻词是作品的语汇装饰,属资产自身 ⇒ 注入时**保留原值**。
|
|
22
|
+
* 实现上不"重建"整个对象,而是**在原对象上覆盖**四个实况键 —— 未列出的键自动保留。
|
|
23
|
+
*/
|
|
24
|
+
/** 从 CCC 实况读出的词表(只含**会变**的四个键;`zh` 与其它装饰键不在其中) */
|
|
25
|
+
export interface VoyageLiveVocab {
|
|
26
|
+
skills: string[];
|
|
27
|
+
msms: string[];
|
|
28
|
+
onto: string[];
|
|
29
|
+
counts: Record<string, number>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 扫描一个 CCC 的实况词表。**每一项独立容错**:任一来源缺失/读坏 ⇒ 该项为空,其余照常。
|
|
33
|
+
*
|
|
34
|
+
* | 字段 | 来源 | 为什么是它 |
|
|
35
|
+
* |---|---|---|
|
|
36
|
+
* | `skills` | `.opencode/skills/` 下含 `SKILL.md` 的目录名 | 与状态面板同一条判据 |
|
|
37
|
+
* | `msms` | `mech-registry.json` 的注册名 | **MSM 的唯一真相源** |
|
|
38
|
+
* | `onto` | `.opencode/skills/` 下含 `skill.ttl` 的目录名 | 增强型(建模过)的 skill |
|
|
39
|
+
* | `counts` | 上述长度 + 轨迹数 | 计数与词表同源,否则 HUD 与星场对不上 |
|
|
40
|
+
*
|
|
41
|
+
* @param root CCC 根
|
|
42
|
+
*/
|
|
43
|
+
export declare function scanVoyageLiveVocab(root: string): VoyageLiveVocab;
|
|
44
|
+
/**
|
|
45
|
+
* 把实况词表注入资产 HTML。
|
|
46
|
+
*
|
|
47
|
+
* 做法 = **在原 VOCAB 对象上覆盖**四个实况键(不重建整个对象)⇒ `zh` 等装饰键自动保留。
|
|
48
|
+
* 任一环节不成立就**原样返回**(见文件头判据②),因此:
|
|
49
|
+
* @returns 注入后的 HTML;未注入时**与入参逐字节相同**
|
|
50
|
+
*/
|
|
51
|
+
export declare function injectVoyageVocab(html: string, live: VoyageLiveVocab | null): string;
|