@shgroup/dsh-serenity-hooks 1.26.17 → 1.27.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/dsh.plugin.json +1 -1
- package/lib/ccc.d.ts +42 -0
- package/lib/client.js +416 -1
- package/lib/index.js +387 -815
- package/lib/rolldown-runtime-D7D4PA-g.js +13 -0
- package/lib/skiff-core-BewZSbVH.js +424 -0
- package/lib/skiff-core.d.ts +3 -1
- package/lib/skiff-role-Dw7UKCUm.js +126 -0
- package/lib/weixin-api-b8HLmcPE.js +211 -0
- package/lib/weixin-api.d.ts +119 -0
- package/lib/weixin-bridge.d.ts +56 -0
- package/lib/weixin-route-CHCWBvLZ.js +473 -0
- package/lib/weixin-route.d.ts +61 -0
- package/package.json +1 -1
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
//#region src/weixin-api.ts
|
|
4
|
+
/**
|
|
5
|
+
* weixin-api.ts — 微信个人号 iLink Bot API 客户端(F4c-3,v1.27.0 实验性)
|
|
6
|
+
*
|
|
7
|
+
* 纯 fetch 客户端(Node ≥ 18 原生 fetch + node:crypto),零第三方依赖——
|
|
8
|
+
* 对齐 openclaw-weixin 插件 api.ts 语义(协议全解见 docs/weixin-bot-api.md)。
|
|
9
|
+
*
|
|
10
|
+
* 定位:**Mech 传输层**——只做 HTTP 编解码与请求头,不含业务逻辑(路由/会话映射
|
|
11
|
+
* 在 weixin-route.ts / weixin-bridge.ts)。所有函数可单测(fetch 注入 mock)。
|
|
12
|
+
*
|
|
13
|
+
* 关键协议事实(实证裸调 2026-08-31):
|
|
14
|
+
* - get_bot_qrcode 无需任何凭据即可取码(无 OpenClaw 账号体系/平台审核)
|
|
15
|
+
* - 鉴权后请求头:AuthorizationType: ilink_bot_token + X-WECHAT-UIN(随机防重放)
|
|
16
|
+
* + Authorization: Bearer <bot_token> + iLink-App-Id/ClientVersion
|
|
17
|
+
* - getupdates 长轮询 35s hold;游标 get_updates_buf 从响应原样带回续传
|
|
18
|
+
* - sendmessage 必须回带 context_token 关联对话
|
|
19
|
+
*/
|
|
20
|
+
var weixin_api_exports = /* @__PURE__ */ __exportAll({
|
|
21
|
+
ILINK_CDN_BASE_URL: () => ILINK_CDN_BASE_URL,
|
|
22
|
+
ILINK_DEFAULT_BASE_URL: () => ILINK_DEFAULT_BASE_URL,
|
|
23
|
+
MessageItemType: () => MessageItemType,
|
|
24
|
+
MessageState: () => MessageState,
|
|
25
|
+
MessageType: () => MessageType,
|
|
26
|
+
buildClientVersion: () => buildClientVersion,
|
|
27
|
+
fetchQRCode: () => fetchQRCode,
|
|
28
|
+
getUpdates: () => getUpdates,
|
|
29
|
+
markdownToPlainText: () => markdownToPlainText,
|
|
30
|
+
pollQRStatus: () => pollQRStatus,
|
|
31
|
+
sendTextMessage: () => sendTextMessage
|
|
32
|
+
});
|
|
33
|
+
/** iLink API Base URL(腾讯官方) */
|
|
34
|
+
const ILINK_DEFAULT_BASE_URL = "https://ilinkai.weixin.qq.com";
|
|
35
|
+
/** iLink-App-Id(openclaw-weixin 同款) */
|
|
36
|
+
const ILINK_APP_ID = "bot";
|
|
37
|
+
/** 通道版本(对齐 openclaw-weixin 2.1.1;buildClientVersion 编码) */
|
|
38
|
+
const CHANNEL_VERSION = "2.1.1";
|
|
39
|
+
/** 版本号 → ClientVersion 整数:(major<<16)|(minor<<8)|patch */
|
|
40
|
+
function buildClientVersion(version) {
|
|
41
|
+
const parts = version.split(".").map((p) => parseInt(p, 10));
|
|
42
|
+
const major = parts[0] ?? 0;
|
|
43
|
+
const minor = parts[1] ?? 0;
|
|
44
|
+
const patch = parts[2] ?? 0;
|
|
45
|
+
return (major & 255) << 16 | (minor & 255) << 8 | patch & 255;
|
|
46
|
+
}
|
|
47
|
+
const CLIENT_VERSION = buildClientVersion(CHANNEL_VERSION);
|
|
48
|
+
/** 随机 X-WECHAT-UIN(uint32 → base64;每请求不同,防重放) */
|
|
49
|
+
function randomWechatUin() {
|
|
50
|
+
const uint32 = randomBytes(4).readUInt32BE(0);
|
|
51
|
+
return Buffer.from(String(uint32), "utf-8").toString("base64");
|
|
52
|
+
}
|
|
53
|
+
function ensureTrailingSlash(url) {
|
|
54
|
+
return url.endsWith("/") ? url : `${url}/`;
|
|
55
|
+
}
|
|
56
|
+
function buildCommonHeaders() {
|
|
57
|
+
return {
|
|
58
|
+
"iLink-App-Id": ILINK_APP_ID,
|
|
59
|
+
"iLink-App-ClientVersion": String(CLIENT_VERSION)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function buildHeaders(token) {
|
|
63
|
+
return {
|
|
64
|
+
"Content-Type": "application/json",
|
|
65
|
+
AuthorizationType: "ilink_bot_token",
|
|
66
|
+
"X-WECHAT-UIN": randomWechatUin(),
|
|
67
|
+
...token ? { Authorization: `Bearer ${token}` } : {},
|
|
68
|
+
...buildCommonHeaders()
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
let currentFetch = (...args) => fetch(...args);
|
|
72
|
+
async function apiGet(params) {
|
|
73
|
+
const base = ensureTrailingSlash(params.baseUrl);
|
|
74
|
+
const url = new URL(params.endpoint, base);
|
|
75
|
+
const controller = new AbortController();
|
|
76
|
+
const timer = setTimeout(() => controller.abort(), params.timeoutMs);
|
|
77
|
+
try {
|
|
78
|
+
const res = await currentFetch(url.toString(), {
|
|
79
|
+
method: "GET",
|
|
80
|
+
headers: buildCommonHeaders(),
|
|
81
|
+
signal: controller.signal
|
|
82
|
+
});
|
|
83
|
+
clearTimeout(timer);
|
|
84
|
+
const rawText = await res.text();
|
|
85
|
+
if (!res.ok) throw new Error(`${params.endpoint} ${res.status}: ${rawText}`);
|
|
86
|
+
return rawText;
|
|
87
|
+
} catch (err) {
|
|
88
|
+
clearTimeout(timer);
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function apiPost(params) {
|
|
93
|
+
const base = ensureTrailingSlash(params.baseUrl);
|
|
94
|
+
const url = new URL(params.endpoint, base);
|
|
95
|
+
const controller = new AbortController();
|
|
96
|
+
const timer = setTimeout(() => controller.abort(), params.timeoutMs);
|
|
97
|
+
try {
|
|
98
|
+
const res = await currentFetch(url.toString(), {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: buildHeaders(params.token),
|
|
101
|
+
body: params.body,
|
|
102
|
+
signal: controller.signal
|
|
103
|
+
});
|
|
104
|
+
clearTimeout(timer);
|
|
105
|
+
const rawText = await res.text();
|
|
106
|
+
if (!res.ok) throw new Error(`${params.endpoint} ${res.status}: ${rawText}`);
|
|
107
|
+
return rawText;
|
|
108
|
+
} catch (err) {
|
|
109
|
+
clearTimeout(timer);
|
|
110
|
+
throw err;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/** 取登录二维码(无需凭据;实证裸调可用) */
|
|
114
|
+
async function fetchQRCode(params) {
|
|
115
|
+
const botType = params.botType ?? "3";
|
|
116
|
+
const rawText = await apiGet({
|
|
117
|
+
baseUrl: params.baseUrl ?? "https://ilinkai.weixin.qq.com",
|
|
118
|
+
endpoint: `ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(botType)}`,
|
|
119
|
+
timeoutMs: params.timeoutMs ?? 5e3
|
|
120
|
+
});
|
|
121
|
+
return JSON.parse(rawText);
|
|
122
|
+
}
|
|
123
|
+
async function pollQRStatus(params) {
|
|
124
|
+
try {
|
|
125
|
+
const rawText = await apiGet({
|
|
126
|
+
baseUrl: params.baseUrl ?? "https://ilinkai.weixin.qq.com",
|
|
127
|
+
endpoint: `ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(params.qrcode)}`,
|
|
128
|
+
timeoutMs: params.timeoutMs ?? 35e3
|
|
129
|
+
});
|
|
130
|
+
return JSON.parse(rawText);
|
|
131
|
+
} catch {
|
|
132
|
+
return { status: "wait" };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** 长轮询收消息(35s hold;超时返回空 msgs 不报错——对齐 openclaw-weixin) */
|
|
136
|
+
async function getUpdates(params) {
|
|
137
|
+
const timeout = params.timeoutMs ?? 35e3;
|
|
138
|
+
try {
|
|
139
|
+
const rawText = await apiPost({
|
|
140
|
+
baseUrl: params.baseUrl,
|
|
141
|
+
endpoint: "ilink/bot/getupdates",
|
|
142
|
+
body: JSON.stringify({ get_updates_buf: params.getUpdatesBuf ?? "" }),
|
|
143
|
+
token: params.token,
|
|
144
|
+
timeoutMs: timeout
|
|
145
|
+
});
|
|
146
|
+
return JSON.parse(rawText);
|
|
147
|
+
} catch (err) {
|
|
148
|
+
if (err instanceof Error && err.name === "AbortError") return {
|
|
149
|
+
ret: 0,
|
|
150
|
+
msgs: [],
|
|
151
|
+
get_updates_buf: params.getUpdatesBuf
|
|
152
|
+
};
|
|
153
|
+
throw err;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const MessageType = {
|
|
157
|
+
NONE: 0,
|
|
158
|
+
USER: 1,
|
|
159
|
+
BOT: 2
|
|
160
|
+
};
|
|
161
|
+
const MessageState = {
|
|
162
|
+
NEW: 0,
|
|
163
|
+
GENERATING: 1,
|
|
164
|
+
FINISH: 2
|
|
165
|
+
};
|
|
166
|
+
const MessageItemType = {
|
|
167
|
+
NONE: 0,
|
|
168
|
+
TEXT: 1,
|
|
169
|
+
IMAGE: 2,
|
|
170
|
+
VOICE: 3,
|
|
171
|
+
FILE: 4,
|
|
172
|
+
VIDEO: 5
|
|
173
|
+
};
|
|
174
|
+
/** 发文本消息(必须回带 context_token 关联对话;md→plain 内置——微信不支持 Markdown) */
|
|
175
|
+
async function sendTextMessage(params) {
|
|
176
|
+
const clientId = params.clientId ?? `dsp-weixin-${randomBytes(4).toString("hex")}`;
|
|
177
|
+
await apiPost({
|
|
178
|
+
baseUrl: params.baseUrl,
|
|
179
|
+
endpoint: "ilink/bot/sendmessage",
|
|
180
|
+
body: JSON.stringify({ msg: {
|
|
181
|
+
from_user_id: "",
|
|
182
|
+
to_user_id: params.toUserId,
|
|
183
|
+
client_id: clientId,
|
|
184
|
+
message_type: MessageType.BOT,
|
|
185
|
+
message_state: MessageState.FINISH,
|
|
186
|
+
item_list: [{
|
|
187
|
+
type: MessageItemType.TEXT,
|
|
188
|
+
text_item: { text: markdownToPlainText(params.text) }
|
|
189
|
+
}],
|
|
190
|
+
...params.contextToken ? { context_token: params.contextToken } : {}
|
|
191
|
+
} }),
|
|
192
|
+
token: params.token,
|
|
193
|
+
timeoutMs: params.timeoutMs ?? 15e3
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/** Markdown → 纯文本(代码块/图片/链接/表格/标题/粗斜体/删除线 7 类) */
|
|
197
|
+
function markdownToPlainText(text) {
|
|
198
|
+
let result = text;
|
|
199
|
+
result = result.replace(/```[^\n]*\n?([\s\S]*?)```/g, (_, code) => code.trim());
|
|
200
|
+
result = result.replace(/!\[[^\]]*\]\([^)]*\)/g, "");
|
|
201
|
+
result = result.replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
|
|
202
|
+
result = result.replace(/^\|.*\|[ \t]*$/gm, "");
|
|
203
|
+
result = result.replace(/^#+\s*/gm, "");
|
|
204
|
+
result = result.replace(/\*\*([^*]+)\*\*/g, "$1");
|
|
205
|
+
result = result.replace(/\*([^*]+)\*/g, "$1");
|
|
206
|
+
result = result.replace(/`([^`]+)`/g, "$1");
|
|
207
|
+
result = result.replace(/~~([^~]+)~~/g, "$1");
|
|
208
|
+
return result.trim();
|
|
209
|
+
}
|
|
210
|
+
//#endregion
|
|
211
|
+
export { sendTextMessage as n, weixin_api_exports as r, getUpdates as t };
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* weixin-api.ts — 微信个人号 iLink Bot API 客户端(F4c-3,v1.27.0 实验性)
|
|
3
|
+
*
|
|
4
|
+
* 纯 fetch 客户端(Node ≥ 18 原生 fetch + node:crypto),零第三方依赖——
|
|
5
|
+
* 对齐 openclaw-weixin 插件 api.ts 语义(协议全解见 docs/weixin-bot-api.md)。
|
|
6
|
+
*
|
|
7
|
+
* 定位:**Mech 传输层**——只做 HTTP 编解码与请求头,不含业务逻辑(路由/会话映射
|
|
8
|
+
* 在 weixin-route.ts / weixin-bridge.ts)。所有函数可单测(fetch 注入 mock)。
|
|
9
|
+
*
|
|
10
|
+
* 关键协议事实(实证裸调 2026-08-31):
|
|
11
|
+
* - get_bot_qrcode 无需任何凭据即可取码(无 OpenClaw 账号体系/平台审核)
|
|
12
|
+
* - 鉴权后请求头:AuthorizationType: ilink_bot_token + X-WECHAT-UIN(随机防重放)
|
|
13
|
+
* + Authorization: Bearer <bot_token> + iLink-App-Id/ClientVersion
|
|
14
|
+
* - getupdates 长轮询 35s hold;游标 get_updates_buf 从响应原样带回续传
|
|
15
|
+
* - sendmessage 必须回带 context_token 关联对话
|
|
16
|
+
*/
|
|
17
|
+
/** iLink API Base URL(腾讯官方) */
|
|
18
|
+
export declare const ILINK_DEFAULT_BASE_URL = "https://ilinkai.weixin.qq.com";
|
|
19
|
+
/** CDN Base(媒体上传/下载;P3 媒体期用) */
|
|
20
|
+
export declare const ILINK_CDN_BASE_URL = "https://novac2c.cdn.weixin.qq.com/c2c";
|
|
21
|
+
/** 版本号 → ClientVersion 整数:(major<<16)|(minor<<8)|patch */
|
|
22
|
+
export declare function buildClientVersion(version: string): number;
|
|
23
|
+
/** fetch 注入点(测试替换;生产 = 全局 fetch) */
|
|
24
|
+
export type FetchLike = typeof fetch;
|
|
25
|
+
/** 测试注入:替换全局 fetch 实现(生产零调用) */
|
|
26
|
+
export declare function __setWeixinFetchForTest(fn: FetchLike | null): void;
|
|
27
|
+
/** 取登录二维码(无需凭据;实证裸调可用) */
|
|
28
|
+
export declare function fetchQRCode(params: {
|
|
29
|
+
baseUrl?: string;
|
|
30
|
+
botType?: string;
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
}): Promise<{
|
|
33
|
+
qrcode: string;
|
|
34
|
+
qrcode_img_content: string;
|
|
35
|
+
}>;
|
|
36
|
+
/** 扫码状态(轮询;1s 间隔建议,5min 有效) */
|
|
37
|
+
export interface QrStatusResult {
|
|
38
|
+
status: string;
|
|
39
|
+
bot_token?: string;
|
|
40
|
+
ilink_bot_id?: string;
|
|
41
|
+
baseurl?: string;
|
|
42
|
+
ilink_user_id?: string;
|
|
43
|
+
redirect_host?: string;
|
|
44
|
+
}
|
|
45
|
+
export declare function pollQRStatus(params: {
|
|
46
|
+
baseUrl?: string;
|
|
47
|
+
qrcode: string;
|
|
48
|
+
timeoutMs?: number;
|
|
49
|
+
}): Promise<QrStatusResult>;
|
|
50
|
+
export interface WeixinMessageItem {
|
|
51
|
+
type?: number;
|
|
52
|
+
msg_id?: string;
|
|
53
|
+
text_item?: {
|
|
54
|
+
text?: string;
|
|
55
|
+
};
|
|
56
|
+
image_item?: Record<string, unknown>;
|
|
57
|
+
voice_item?: Record<string, unknown>;
|
|
58
|
+
file_item?: Record<string, unknown>;
|
|
59
|
+
video_item?: Record<string, unknown>;
|
|
60
|
+
}
|
|
61
|
+
export interface WeixinMessage {
|
|
62
|
+
seq?: number;
|
|
63
|
+
message_id?: number;
|
|
64
|
+
from_user_id?: string;
|
|
65
|
+
to_user_id?: string;
|
|
66
|
+
client_id?: string;
|
|
67
|
+
create_time_ms?: number;
|
|
68
|
+
session_id?: string;
|
|
69
|
+
group_id?: string;
|
|
70
|
+
message_type?: number;
|
|
71
|
+
message_state?: number;
|
|
72
|
+
item_list?: WeixinMessageItem[];
|
|
73
|
+
context_token?: string;
|
|
74
|
+
}
|
|
75
|
+
export interface GetUpdatesResp {
|
|
76
|
+
ret?: number;
|
|
77
|
+
errcode?: number;
|
|
78
|
+
errmsg?: string;
|
|
79
|
+
msgs?: WeixinMessage[];
|
|
80
|
+
get_updates_buf?: string;
|
|
81
|
+
longpolling_timeout_ms?: number;
|
|
82
|
+
}
|
|
83
|
+
/** 长轮询收消息(35s hold;超时返回空 msgs 不报错——对齐 openclaw-weixin) */
|
|
84
|
+
export declare function getUpdates(params: {
|
|
85
|
+
baseUrl: string;
|
|
86
|
+
token: string;
|
|
87
|
+
getUpdatesBuf?: string;
|
|
88
|
+
timeoutMs?: number;
|
|
89
|
+
}): Promise<GetUpdatesResp>;
|
|
90
|
+
export declare const MessageType: {
|
|
91
|
+
readonly NONE: 0;
|
|
92
|
+
readonly USER: 1;
|
|
93
|
+
readonly BOT: 2;
|
|
94
|
+
};
|
|
95
|
+
export declare const MessageState: {
|
|
96
|
+
readonly NEW: 0;
|
|
97
|
+
readonly GENERATING: 1;
|
|
98
|
+
readonly FINISH: 2;
|
|
99
|
+
};
|
|
100
|
+
export declare const MessageItemType: {
|
|
101
|
+
readonly NONE: 0;
|
|
102
|
+
readonly TEXT: 1;
|
|
103
|
+
readonly IMAGE: 2;
|
|
104
|
+
readonly VOICE: 3;
|
|
105
|
+
readonly FILE: 4;
|
|
106
|
+
readonly VIDEO: 5;
|
|
107
|
+
};
|
|
108
|
+
/** 发文本消息(必须回带 context_token 关联对话;md→plain 内置——微信不支持 Markdown) */
|
|
109
|
+
export declare function sendTextMessage(params: {
|
|
110
|
+
baseUrl: string;
|
|
111
|
+
token: string;
|
|
112
|
+
toUserId: string;
|
|
113
|
+
text: string;
|
|
114
|
+
contextToken?: string;
|
|
115
|
+
clientId?: string;
|
|
116
|
+
timeoutMs?: number;
|
|
117
|
+
}): Promise<void>;
|
|
118
|
+
/** Markdown → 纯文本(代码块/图片/链接/表格/标题/粗斜体/删除线 7 类) */
|
|
119
|
+
export declare function markdownToPlainText(text: string): string;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* weixin-bridge.ts — 微信桥装配(F4c-3,v1.27.0 实验性)
|
|
3
|
+
*
|
|
4
|
+
* **CCC 级**:dsh 一个进程含多个 CCC,每个 CCC 独立对接微信桥(S142 用户拍板)——
|
|
5
|
+
* 扫描 live CCC → 每 CCC 读 weixin 配置(enabled + accounts + routes)→
|
|
6
|
+
* 启动该 CCC 该账号的 iLink 轮询循环。消息 → weixin-route 路由 → AcpServer 直调
|
|
7
|
+
* (session/new + session/prompt,同进程不经网络——acp-core 传输无关设计)。
|
|
8
|
+
*
|
|
9
|
+
* 实验性质:未配置/未启用 → 完全不启动(零资源占用)。配置变化(面板写入)
|
|
10
|
+
* → 热重建受影响 CCC 的桥(对齐 gateway 热重建模式)。
|
|
11
|
+
*
|
|
12
|
+
* 外部面纯净(D9/D11 延续):微信桥会话 = 外部面——session/prompt 走
|
|
13
|
+
* includeTrajectory:false(对外不返回轨迹);skiff 角色白名单即授权(G9)。
|
|
14
|
+
*/
|
|
15
|
+
import type { Context } from 'cordis';
|
|
16
|
+
import { type WeixinAccountCredential } from './weixin-route.js';
|
|
17
|
+
/**
|
|
18
|
+
* 处理单条微信消息:路由 → skiff 会话(固定 id 创建/延续)→ 提问 → 回复回写。
|
|
19
|
+
*
|
|
20
|
+
* 会话语义:`weixinSessionIdFor(fromUserId)` 固定可重建——同用户长期同一会话;
|
|
21
|
+
* 进程内已有(getSkiffAgent 命中)→ 延续;无(首次/进程重启)→ createSkiffAgent
|
|
22
|
+
* 以固定 id 新建(角色不变,记忆从新开始——重启后自动重建,与 3100 问答页同语义)。
|
|
23
|
+
*/
|
|
24
|
+
export declare function handleIncoming(ctx: Context, root: string, _accountId: string, cred: WeixinAccountCredential, msg: {
|
|
25
|
+
from_user_id?: string;
|
|
26
|
+
context_token?: string;
|
|
27
|
+
item_list?: Array<{
|
|
28
|
+
type?: number;
|
|
29
|
+
text_item?: {
|
|
30
|
+
text?: string;
|
|
31
|
+
};
|
|
32
|
+
}>;
|
|
33
|
+
}): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* 启动/重建某 CCC 的桥:读配置 → 对每个 enabled + 有凭据的账号启动轮询循环。
|
|
36
|
+
* 已存在(配置变化热重建)→ 先停旧循环再启动新的。
|
|
37
|
+
*/
|
|
38
|
+
export declare function syncCccBridge(ctx: Context, root: string): void;
|
|
39
|
+
/** 停止某 CCC 的桥(移除账号/禁用时) */
|
|
40
|
+
export declare function stopCccBridge(root: string): void;
|
|
41
|
+
/** 停止全部桥(插件 dispose) */
|
|
42
|
+
export declare function stopAllBridges(): void;
|
|
43
|
+
/** 桥状态快照(面板数据源):每 CCC → 每账号 → 轮询健康 */
|
|
44
|
+
export declare function weixinBridgeStatus(): Array<{
|
|
45
|
+
ccc: string;
|
|
46
|
+
accounts: Array<{
|
|
47
|
+
accountId: string;
|
|
48
|
+
lastPollAt: number;
|
|
49
|
+
lastError?: string;
|
|
50
|
+
}>;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* 装配(index.ts 调用):扫描 live CCC 启动桥 + 监听会话变化。
|
|
54
|
+
* 事件驱动(对齐 autotrajectory v1.26.15):live 会话出现 → 同步该 CCC 桥。
|
|
55
|
+
*/
|
|
56
|
+
export declare function registerWeixinBridge(ctx: Context): void;
|