@napuketto/kernel 0.0.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.
@@ -0,0 +1,2252 @@
1
+ import pino from "pino";
2
+ //#region src/types/entities.d.ts
3
+ /**
4
+ * 实体类型层(运行时探测产物 + 公开资料作说明书,ADR-006)
5
+ *
6
+ * ⚠️ 部分字段按公开资料(wrapper 外部契约)自研描述,待下一次进程内
7
+ * 探测(probe.ts)校准——接口签名是外部系统事实,自研描述其形状。
8
+ */
9
+ /** 会话类型(QQ wrapper 外部契约)。 */
10
+ declare const ChatType: {
11
+ readonly C2C: 1;
12
+ readonly GROUP: 2;
13
+ readonly DISC: 3;
14
+ readonly GUILD: 4;
15
+ readonly C2C_TEMP: 100;
16
+ };
17
+ type ChatType = (typeof ChatType)[keyof typeof ChatType];
18
+ /** 会话对象(peer 目标:群号 / 用户 uid)。 */
19
+ interface Peer {
20
+ chatType: ChatType;
21
+ peerUid: string;
22
+ guildId?: string;
23
+ }
24
+ /** 文本元素(at 用 atType + atUid 表达)。 */
25
+ interface TextElement {
26
+ content: string;
27
+ atType?: number;
28
+ atUid?: string;
29
+ }
30
+ /** 图片元素(发送时 picPath 必须;接收含 url)。 */
31
+ interface PicElement {
32
+ picPath?: string;
33
+ picUrl?: string;
34
+ picType?: number;
35
+ picWidth?: number;
36
+ picHeight?: number;
37
+ md5?: string;
38
+ fileName?: string;
39
+ sourcePath?: string;
40
+ thumbPath?: string;
41
+ }
42
+ /** 语音元素(silk)。 */
43
+ interface PttElement {
44
+ filePath?: string;
45
+ md5?: string;
46
+ fileName?: string;
47
+ duration?: number;
48
+ /** 语音转文字结果(translatePtt2Text 异步写回)。 */
49
+ text?: string;
50
+ }
51
+ /** 表情元素。 */
52
+ interface FaceElement {
53
+ faceIndex: number;
54
+ faceType?: number;
55
+ }
56
+ /** 回复元素(引用消息)。 */
57
+ interface ReplyElement {
58
+ replayMsgId: string;
59
+ replayMsgSeq?: string;
60
+ replayMsgTime?: string;
61
+ senderUid?: string;
62
+ senderUin?: string;
63
+ }
64
+ /** 视频元素。 */
65
+ interface VideoElement {
66
+ filePath?: string;
67
+ videoUrl?: string;
68
+ fileName?: string;
69
+ fileSize?: string;
70
+ }
71
+ /** 文件元素。 */
72
+ interface FileElement {
73
+ filePath?: string;
74
+ fileName?: string;
75
+ fileSize?: string;
76
+ fileUuid?: string;
77
+ }
78
+ /** 灰色提示子类型(系统事件类型,QQ wrapper 契约)。 */
79
+ declare const GrayTipSubType: {
80
+ readonly REVOKE: 1;
81
+ readonly PROCLAMATION: 2;
82
+ readonly GROUP: 4;
83
+ readonly BUDDY: 5;
84
+ readonly FEED: 6;
85
+ readonly ESSENCE: 7;
86
+ readonly GROUP_NOTIFY: 8;
87
+ readonly BUDDY_NOTIFY: 9;
88
+ readonly FILE: 10;
89
+ readonly JSON: 17;
90
+ };
91
+ type GrayTipSubType = (typeof GrayTipSubType)[keyof typeof GrayTipSubType];
92
+ /** 群成员变动类型(TipGroupElement.type)。 */
93
+ declare const TipGroupElementType: {
94
+ readonly MEMBER_ADD: 1;
95
+ readonly DISBANDED: 2;
96
+ readonly QUIT: 3;
97
+ readonly CREATED: 4;
98
+ readonly GROUP_NAME_MODIFIED: 5;
99
+ readonly BLOCK: 6;
100
+ readonly UNBLOCK: 7;
101
+ readonly SHUT_UP: 8;
102
+ };
103
+ type TipGroupElementType = (typeof TipGroupElementType)[keyof typeof TipGroupElementType];
104
+ /** 撤回元素(revokeElement)。 */
105
+ interface GrayTipRevokeElement {
106
+ operatorUid: string;
107
+ operatorNick?: string;
108
+ operatorRole?: string;
109
+ isSelfOperate?: boolean;
110
+ wording?: string;
111
+ }
112
+ /** AIOP 操作元素(戳一戳等,aioOpGrayTipElement)。 */
113
+ interface TipAioOpGrayTipElement {
114
+ operateType?: number;
115
+ peerUid?: string;
116
+ fromGrpCodeOfTmpChat?: string;
117
+ }
118
+ /** 群成员变动元素(groupElement 内的 TipGroupElement)。 */
119
+ interface TipGroupElement {
120
+ type?: TipGroupElementType;
121
+ groupName?: string;
122
+ memberUid?: string;
123
+ memberNick?: string;
124
+ memberRemark?: string;
125
+ adminUid?: string;
126
+ adminNick?: string;
127
+ adminRemark?: string;
128
+ shutUp?: {
129
+ curTime?: string;
130
+ duration?: string;
131
+ admin?: {
132
+ uid?: string;
133
+ card?: string;
134
+ name?: string;
135
+ role?: number;
136
+ };
137
+ member?: {
138
+ uid?: string;
139
+ card?: string;
140
+ name?: string;
141
+ role?: number;
142
+ };
143
+ };
144
+ }
145
+ /** 灰色提示元素(elementType=8,系统事件载体)。 */
146
+ interface GrayTipElement {
147
+ subElementType?: GrayTipSubType;
148
+ revokeElement?: GrayTipRevokeElement;
149
+ groupElement?: TipGroupElement;
150
+ aioOpGrayTipElement?: TipAioOpGrayTipElement;
151
+ xmlElement?: {
152
+ busiId?: string;
153
+ content?: string;
154
+ templId?: string;
155
+ };
156
+ jsonGrayTipElement?: {
157
+ busiId?: string;
158
+ jsonStr?: string;
159
+ };
160
+ }
161
+ /** 消息元素(RawMessage.elements 成员,elementType + 子元素互斥)。 */
162
+ interface RawElement {
163
+ elementType: number;
164
+ elementId?: string;
165
+ textElement?: TextElement;
166
+ picElement?: PicElement;
167
+ pttElement?: PttElement;
168
+ faceElement?: FaceElement;
169
+ replyElement?: ReplyElement;
170
+ videoElement?: VideoElement;
171
+ fileElement?: FileElement;
172
+ grayTipElement?: GrayTipElement;
173
+ /** 合并转发元素(elementType=16 MULTI_FORWARD)。 */
174
+ multiForwardMsgElement?: {
175
+ resId: string;
176
+ fileName: string;
177
+ xmlContent: string;
178
+ };
179
+ }
180
+ /** QQ 消息(RawMessage,说明书参考字段,探测后校准)。 */
181
+ interface RawMessage {
182
+ msgId: string;
183
+ msgSeq: string;
184
+ msgTime: string;
185
+ msgRandom?: string;
186
+ msgType: number;
187
+ chatType: ChatType;
188
+ peerUid: string;
189
+ peerUin: string;
190
+ senderUid: string;
191
+ senderUin: string;
192
+ peerName: string;
193
+ sendNickName: string;
194
+ sendMemberName?: string;
195
+ elements: RawElement[];
196
+ records?: RawMessage[];
197
+ guildId?: string;
198
+ [key: string]: unknown;
199
+ }
200
+ //#endregion
201
+ //#region src/types/services/msg-service.d.ts
202
+ /** 原生通用返回:result 非 0 即失败(errMsg 附原因)。 */
203
+ interface GeneralCallResult {
204
+ result: number;
205
+ errMsg: string;
206
+ }
207
+ /** 消息元素类型枚举(QQ wrapper 外部契约,自研描述)。 */
208
+ declare const ElementType: {
209
+ readonly UNKNOWN: 0;
210
+ readonly TEXT: 1;
211
+ readonly PIC: 2;
212
+ readonly FILE: 3;
213
+ readonly PTT: 4;
214
+ readonly VIDEO: 5;
215
+ readonly FACE: 6;
216
+ readonly REPLY: 7;
217
+ readonly GRAY_TIP: 8;
218
+ readonly WALLET: 9;
219
+ readonly ARK: 10;
220
+ readonly MFACE: 11;
221
+ readonly LIVE_GIFT: 12;
222
+ readonly STRUCT_LONG_MSG: 13;
223
+ readonly MARKDOWN: 14;
224
+ readonly GIPHY: 15;
225
+ readonly MULTI_FORWARD: 16;
226
+ readonly INLINE_KEYBOARD: 17;
227
+ readonly INTEXT_GIFT: 18;
228
+ readonly CALENDAR: 19;
229
+ };
230
+ type ElementType = (typeof ElementType)[keyof typeof ElementType];
231
+ /** 发送消息元素(session 发送用,elementType + 各子元素互斥)。 */
232
+ interface SendMessageElement {
233
+ elementType: ElementType;
234
+ elementId?: string;
235
+ textElement?: TextElement;
236
+ faceElement?: FaceElement;
237
+ replyElement?: ReplyElement;
238
+ picElement?: PicElement;
239
+ pttElement?: PttElement;
240
+ }
241
+ /** 消息服务:apis/msg 用到的核心方法面。 */
242
+ interface NodeIKernelMsgService {
243
+ addKernelMsgListener(listener: unknown): number;
244
+ removeKernelMsgListener(listenerId: number): void;
245
+ generateMsgUniqueId(chatType: number, time: string): string;
246
+ sendMsg(msgId: string, peer: Peer, elements: SendMessageElement[], map: Map<number, unknown>): Promise<GeneralCallResult>;
247
+ recallMsg(peer: Peer, msgIds: string[]): Promise<GeneralCallResult>;
248
+ getMsgs(peer: Peer, msgId: string, count: number, queryOrder: boolean): Promise<GeneralCallResult & {
249
+ msgList?: RawMessage[];
250
+ }>;
251
+ /** 按 msgId 批量拉取消息(get_msg / 精华消息 / ptt 转文字共用)。 */
252
+ getMsgsByMsgId(peer: Peer, ids: string[]): Promise<GeneralCallResult & {
253
+ msgList?: RawMessage[];
254
+ }>;
255
+ setMsgRead(peer: Peer): Promise<GeneralCallResult>;
256
+ /** 消息表情表态(set_msg_emoji_like;setOrCancel=true 点赞,false 取消)。 */
257
+ setMsgEmojiLikes(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, setOrCancel: boolean): Promise<GeneralCallResult>;
258
+ /** 语音转文字(fetch_ptt_text;异步转写,结果写回 pttElement.text)。 */
259
+ translatePtt2Text(msgId: string, peer: Peer, msgElement: unknown): Promise<GeneralCallResult>;
260
+ /** 输入状态(set_input_status;eventType=1 输入中,0 停止)。 */
261
+ sendShowInputStatusReq(chatType: number, eventType: number, toUid: string): Promise<unknown>;
262
+ /** 合并转发组装(send_group/private_forward_msg;返回 MULTI_FORWARD 元素)。 */
263
+ buildMultiForwardMsg(req: {
264
+ srcMsgIds: string[];
265
+ srcContact: Peer;
266
+ }): Promise<GeneralCallResult & {
267
+ rspInfo?: {
268
+ elements?: SendMessageElement[];
269
+ };
270
+ }>;
271
+ /** 获取合并转发内容(get_forward_msg;resId 取自 multiForwardMsgElement)。 */
272
+ getMultiMsg(peer: Peer, msgId: string, resId: string): Promise<GeneralCallResult & {
273
+ msgList?: RawMessage[];
274
+ }>;
275
+ /** 单条转发(forward_group/friend_single_msg;msgIds 源、dstPeers 目标)。 */
276
+ forwardMsg(msgIds: string[], peer: Peer, dstPeers: Peer[], commentElements: unknown): Promise<GeneralCallResult>;
277
+ /** 设置在线状态(set_online_status;customStatus 为自定义状态)。 */
278
+ setStatus(args: {
279
+ status: number;
280
+ extStatus: number;
281
+ batteryStatus: number;
282
+ customStatus?: {
283
+ faceId: string;
284
+ wording: string;
285
+ faceType: string;
286
+ };
287
+ }): Promise<GeneralCallResult>;
288
+ }
289
+ //#endregion
290
+ //#region src/types/services/buddy-service.d.ts
291
+ /** 好友列表分类(getBuddyListV2 返回,说明书参考)。 */
292
+ interface BuddyCategory {
293
+ categoryId: number;
294
+ categorySortId: number;
295
+ categroyName: string;
296
+ categroyMbCount: number;
297
+ onlineCount: number;
298
+ buddyUids: string[];
299
+ }
300
+ /** 好友申请(getBuddyReq 返回的 buddyReqs 成员,说明书参考,待探测校准)。 */
301
+ interface BuddyReq {
302
+ reqTime: string;
303
+ friendUid: string;
304
+ friendNick?: string;
305
+ sourceId?: number;
306
+ sourceName?: string;
307
+ [key: string]: unknown;
308
+ }
309
+ /** 可疑好友申请(getDoubtBuddyReq 返回的 doubtList 成员,说明书参考)。 */
310
+ interface DoubtBuddyReq {
311
+ uid: string;
312
+ nick?: string;
313
+ source?: string;
314
+ reason?: string;
315
+ msg?: string;
316
+ groupCode?: string;
317
+ reqTime?: string;
318
+ [key: string]: unknown;
319
+ }
320
+ /** 好友服务:apis/friend 用到的核心方法面。 */
321
+ interface NodeIKernelBuddyService {
322
+ addKernelBuddyListener(listener: unknown): number;
323
+ removeKernelBuddyListener(listenerId: number): void;
324
+ getBuddyListV2(callFrom: string, isPullRefresh: boolean, reqType: number): Promise<GeneralCallResult & {
325
+ data: BuddyCategory[];
326
+ }>;
327
+ getBuddyListFromCache(reqType: number): Promise<BuddyCategory[]>;
328
+ getBuddyNick(uid: string): string;
329
+ getBuddyRemark(uid: string): string;
330
+ isBuddy(uid: string): boolean;
331
+ /** 好友申请列表(set_friend_add_request 应答前查找匹配项)。 */
332
+ getBuddyReq(): Promise<GeneralCallResult & {
333
+ buddyReqs?: BuddyReq[];
334
+ }>;
335
+ /** 同意/拒绝加好友请求(set_friend_add_request)。 */
336
+ approvalFriendRequest(arg: {
337
+ friendUid: string;
338
+ reqTime: string;
339
+ accept: boolean;
340
+ }): Promise<void>;
341
+ /** 设置好友备注(set_friend_remark;void 语义乐观处理)。 */
342
+ setBuddyRemark(param: {
343
+ uid: string;
344
+ remark: string;
345
+ }): void;
346
+ /** 删除好友(delete_friend)。 */
347
+ delBuddy(param: {
348
+ friendUid: string;
349
+ tempBlock: boolean;
350
+ tempBothDel: boolean;
351
+ }): Promise<unknown>;
352
+ /** 可疑好友申请列表(get_doubt_friends_add_request;reqId 作回执匹配)。 */
353
+ getDoubtBuddyReq(reqId: string, num: number, uk: string): Promise<GeneralCallResult & {
354
+ doubtList?: DoubtBuddyReq[];
355
+ }>;
356
+ /** 处理可疑好友申请(set_doubt_friends_add_request;str1/str2 语义未知,传空串)。 */
357
+ approvalDoubtBuddyReq(uid: string, str1: string, str2: string): void;
358
+ }
359
+ //#endregion
360
+ //#region src/types/wrapper.d.ts
361
+ /**
362
+ * wrapper.node 的 NAPI 接口面(自研描述,非移植)
363
+ *
364
+ * 来源:wrapper.node 在 QQ 定制版 Electron 里通过 napi_define_class / napi_set_named_property
365
+ * 注册的 JS 类(2026-08-05 Ghidra 反编译 FUN_180c6274a / FUN_180c80224 确认类名)。
366
+ * 这些接口是 wrapper.node 对外暴露的外部系统契约——我们自研描述其形状,未复制任何第三方代码。
367
+ *
368
+ * 注意:这里所有对象由 QQ 运行时的 NAPI 层自动构建/转换,业务层禁止触碰 C++ ABI。
369
+ */
370
+ /** 平台类型(与 wrapper.node 的 platform 字段对应)。 */
371
+ declare const PlatformType: {
372
+ readonly KUNKNOWN: 0;
373
+ readonly KANDROID: 1;
374
+ readonly KIOS: 2;
375
+ readonly KWINDOWS: 3;
376
+ readonly KMAC: 4;
377
+ readonly KLINUX: 5;
378
+ };
379
+ type PlatformType = (typeof PlatformType)[keyof typeof PlatformType];
380
+ /** 厂商类型(deviceInfo.vendorType)。 */
381
+ declare const VendorType: {
382
+ readonly KNOSETONIOS: 0;
383
+ readonly KUNSUPPORTANDROIDPUSH: 1;
384
+ readonly KSUPPORTTPNS: 2;
385
+ readonly KSUPPORTHMS: 3;
386
+ readonly KSUPPORTOPPOPUSH: 4;
387
+ readonly KSUPPORTVIVOPUSH: 5;
388
+ readonly KSUPPORTGOOGLEPUSH: 99;
389
+ };
390
+ type VendorType = (typeof VendorType)[keyof typeof VendorType];
391
+ /** NodeQQNTWrapperUtil:通用工具类(静态服务)。 */
392
+ interface NodeQQNTWrapperUtil {
393
+ get(): NodeQQNTWrapperUtil;
394
+ getNTUserDataInfoConfig(): string;
395
+ getFileSize(path: string): Promise<number>;
396
+ fileIsExist(path: string): unknown;
397
+ makeDirByPath(path: string): unknown;
398
+ }
399
+ /** engine 初始化配置(initWithDeskTopConfig 第一参,JS 对象直接传)。 */
400
+ interface EnginInitDesktopConfig {
401
+ base_path_prefix: string;
402
+ platform_type: PlatformType;
403
+ app_type: 4;
404
+ app_version: string;
405
+ os_version: string;
406
+ use_xlog: boolean;
407
+ qua: string;
408
+ global_path_config: {
409
+ desktopGlobalPath: string;
410
+ };
411
+ thumb_config: {
412
+ maxSide: 324;
413
+ minSide: 48;
414
+ longLimit: 6;
415
+ density: 2;
416
+ };
417
+ }
418
+ /** NodeIQQNTWrapperEngine 实例方法。 */
419
+ interface NodeIQQNTWrapperEngine {
420
+ initWithDeskTopConfig(config: EnginInitDesktopConfig, adapter: NodeIGlobalAdapter): void;
421
+ initWithMobileConfig(config: unknown, adapter: NodeIGlobalAdapter): void;
422
+ initLog(arg: unknown): void;
423
+ setLogLevel(arg: unknown): void;
424
+ onSendSSOReply(a: unknown, b: unknown, c: unknown, d: unknown, e: unknown): void;
425
+ }
426
+ /** NodeIQQNTWrapperEngine 构造器(含静态 get())。 */
427
+ type NodeIQQNTWrapperEngineCtor = new () => NodeIQQNTWrapperEngine & {
428
+ get(): NodeIQQNTWrapperEngine;
429
+ };
430
+ /** desktopPathConfig 结构。 */
431
+ interface DesktopPathConfig {
432
+ account_path: string;
433
+ }
434
+ /** rdeliveryConfig 结构。 */
435
+ interface RDeliveryConfig {
436
+ appKey: string;
437
+ systemId: number;
438
+ appId: string;
439
+ logicEnvironment: string;
440
+ platform: PlatformType;
441
+ language: string;
442
+ sdkVersion: string;
443
+ userId: string;
444
+ appVersion: string;
445
+ osVersion: string;
446
+ bundleId: string;
447
+ serverUrl: string;
448
+ fixedAfterHitKeys: string[];
449
+ }
450
+ /** deviceInfo 结构。 */
451
+ interface DeviceInfo {
452
+ guid: string;
453
+ buildVer: string;
454
+ localId: number;
455
+ devName: string;
456
+ devType: string;
457
+ vendorName: string;
458
+ osVer: string;
459
+ vendorOsName: string;
460
+ setMute: boolean;
461
+ vendorType: VendorType;
462
+ }
463
+ /** session.init 的完整配置(JS 对象,NAPI 自动转换)。 */
464
+ interface WrapperSessionInitConfig {
465
+ selfUin: string;
466
+ selfUid: string;
467
+ desktopPathConfig: DesktopPathConfig;
468
+ clientVer: string;
469
+ a2: string;
470
+ d2: string;
471
+ d2Key: string;
472
+ machineId: string;
473
+ platform: PlatformType;
474
+ platVer: string;
475
+ appid: string;
476
+ rdeliveryConfig: RDeliveryConfig;
477
+ defaultFileDownloadPath: string;
478
+ deviceInfo: DeviceInfo;
479
+ deviceConfig: string;
480
+ }
481
+ /** NodeIQQNTWrapperSession 构造器(含静态 get / getNTWrapperSession / create)。 */
482
+ type NodeIQQNTWrapperSessionCtor = {
483
+ new (): NodeIQQNTWrapperSession;
484
+ get(): NodeIQQNTWrapperSession;
485
+ getNTWrapperSession(name: string): NodeIQQNTWrapperSession;
486
+ create(): NodeIQQNTWrapperSession;
487
+ };
488
+ /** NodeIQQNTWrapperSession:会话主入口(实例方法)。 */
489
+ interface NodeIQQNTWrapperSession {
490
+ init(config: WrapperSessionInitConfig, depends: NodeIDependsAdapter, dispatcher: NodeIDispatcherAdapter, listener: NodeIKernelSessionListener): void;
491
+ startNT(sessionId?: number): void;
492
+ close(arg: unknown): void;
493
+ onLine(arg: unknown): void;
494
+ offLine(arg: unknown): void;
495
+ disableIpDirect(arg: unknown): void;
496
+ getAccountPath(arg: unknown): string;
497
+ updateTicket(arg: unknown): void;
498
+ getMsgService(): unknown;
499
+ getGroupService(): unknown;
500
+ getBuddyService(): unknown;
501
+ getTicketService(): unknown;
502
+ getRichMediaService(): unknown;
503
+ getProfileService(): unknown;
504
+ getProfileLikeService(): unknown;
505
+ getTipOffService(): unknown;
506
+ }
507
+ /** NodeIQQNTStartupSessionWrapper:启动会话实例方法。 */
508
+ interface NodeIQQNTStartupSessionWrapper {
509
+ stop(): void;
510
+ start(): void;
511
+ createWithModuleList(uk: unknown): unknown;
512
+ getSessionIdList(): Promise<Map<unknown, unknown>>;
513
+ }
514
+ /** NodeIQQNTStartupSessionWrapper 构造器(含静态 create)。 */
515
+ type NodeIQQNTStartupSessionWrapperCtor = new () => NodeIQQNTStartupSessionWrapper & {
516
+ create(): NodeIQQNTStartupSessionWrapper;
517
+ };
518
+ /** NodeIKernelLoginService 实例方法。 */
519
+ interface NodeIKernelLoginService {
520
+ addKernelLoginListener(listener: unknown): number;
521
+ removeKernelLoginListener(listener: number): void;
522
+ initConfig(config: unknown): void;
523
+ connect(): void;
524
+ getLoginList(): Promise<{
525
+ result: number;
526
+ LocalLoginInfoList: unknown[];
527
+ }>;
528
+ quickLoginWithUin(uin: string): Promise<unknown>;
529
+ getQRCodePicture(): boolean;
530
+ getMsfStatus(): number;
531
+ }
532
+ /** NodeIKernelLoginService 构造器(含静态 get)。 */
533
+ type NodeIKernelLoginServiceCtor = new () => NodeIKernelLoginService & {
534
+ get(): NodeIKernelLoginService;
535
+ };
536
+ /** NodeIO3MiscService:O3 杂项服务。 */
537
+ interface NodeIO3MiscService {
538
+ get(): NodeIO3MiscService;
539
+ addO3MiscListener(listener: unknown): number;
540
+ }
541
+ interface NodeIGlobalAdapter {
542
+ onLog?(...args: unknown[]): void;
543
+ onGetSrvCalTime?(...args: unknown[]): void;
544
+ onShowErrUITips?(...args: unknown[]): void;
545
+ fixPicImgType?(...args: unknown[]): unknown;
546
+ getAppSetting?(...args: unknown[]): unknown;
547
+ onInstallFinished?(...args: unknown[]): void;
548
+ onUpdateGeneralFlag?(...args: unknown[]): void;
549
+ onGetOfflineMsg?(...args: unknown[]): void;
550
+ }
551
+ /** session.init 第二参:依赖回调(普通 JS 对象)。 */
552
+ interface NodeIDependsAdapter {
553
+ onMSFStatusChange?(statusType: number, changeReasonType: number): void;
554
+ onMSFSsoError?(code: number, desc: string): void;
555
+ getGroupCode?(...args: unknown[]): unknown;
556
+ }
557
+ /** session.init 第三参:请求分发回调(普通 JS 对象)。 */
558
+ interface NodeIDispatcherAdapter {
559
+ dispatchRequest?(arg: unknown): void;
560
+ dispatchCall?(arg: unknown): void;
561
+ dispatchCallWithJson?(arg: unknown): void;
562
+ }
563
+ /** 登录监听器接口(普通 JS 对象,传给 loginService.addKernelLoginListener)。自研描述。 */
564
+ interface IKernelLoginListener {
565
+ onLoginConnected?(...args: unknown[]): void;
566
+ onLoginDisConnected?(...args: unknown[]): void;
567
+ onLoginConnecting?(...args: unknown[]): void;
568
+ onQRCodeGetPicture?(arg: {
569
+ pngBase64QrcodeData: string;
570
+ qrcodeUrl: string;
571
+ }): void;
572
+ onQRCodeLoginPollingStarted?(...args: unknown[]): void;
573
+ onQRCodeSessionUserScaned?(...args: unknown[]): void;
574
+ onQRCodeLoginSucceed?(loginResult: {
575
+ uid: string;
576
+ uin: string;
577
+ nick?: string;
578
+ }): void;
579
+ onQRCodeSessionFailed?(errType: number, errCode: number, errMsg: string): void;
580
+ onLoginFailed?(args: unknown): void;
581
+ onLogoutSucceed?(...args: unknown[]): void;
582
+ onLogoutFailed?(...args: unknown[]): void;
583
+ onUserLoggedIn?(userid: string): void;
584
+ onQRCodeSessionQuickLoginFailed?(...args: unknown[]): void;
585
+ onPasswordLoginFailed?(...args: unknown[]): void;
586
+ onQQLoginNumLimited?(...args: unknown[]): void;
587
+ onLoginState?(...args: unknown[]): void;
588
+ }
589
+ /**
590
+ * NodeIKernelSessionListener:session.init 第四参监听器(普通 JS 对象)。
591
+ * init 完成信号:以 onOpentelemetryInit(is_init===true) 为准(onSessionInitComplete 为辅)。
592
+ */
593
+ interface NodeIKernelSessionListener {
594
+ onNTSessionCreate?(sessionId: string): void;
595
+ onGProSessionCreate?(sessionId: string): void;
596
+ onSessionInitComplete?(result: unknown): void;
597
+ onOpentelemetryInit?(info: {
598
+ is_init: boolean;
599
+ is_report: boolean;
600
+ }): void;
601
+ onUserOnlineResult?(result: unknown): void;
602
+ onGetSelfTinyId?(result: unknown): void;
603
+ }
604
+ /** wrapper.node 的 NAPI 顶层导出(module.exports)。 */
605
+ interface WrapperNodeApi {
606
+ NodeIO3MiscService: NodeIO3MiscService;
607
+ NodeQQNTWrapperUtil: NodeQQNTWrapperUtil;
608
+ /** 构造器:`new wrapper.NodeIQQNTWrapperSession()`。 */
609
+ NodeIQQNTWrapperSession: NodeIQQNTWrapperSessionCtor;
610
+ NodeIQQNTStartupSessionWrapper: NodeIQQNTStartupSessionWrapperCtor;
611
+ /** 构造器:`new wrapper.NodeIQQNTWrapperEngine()`。 */
612
+ NodeIQQNTWrapperEngine: NodeIQQNTWrapperEngineCtor;
613
+ /** 构造器:`new wrapper.NodeIKernelLoginService()`。 */
614
+ NodeIKernelLoginService: NodeIKernelLoginServiceCtor;
615
+ }
616
+ //#endregion
617
+ //#region src/apis/friend.d.ts
618
+ /** 好友条目(uid + 昵称/备注,昵称由 buddy service 缓存补全)。 */
619
+ interface Friend {
620
+ uid: string;
621
+ uin: string;
622
+ nickname: string;
623
+ remark: string;
624
+ }
625
+ /** 带分类的好友列表项(get_friends_with_category 返回)。 */
626
+ interface FriendCategory {
627
+ categoryId: number;
628
+ categorySortId: number;
629
+ categoryName: string;
630
+ categoryMbCount: number;
631
+ onlineCount: number;
632
+ buddyList: Friend[];
633
+ }
634
+ /** 可疑好友申请(OB11 结构,get_doubt_friends_add_request 返回)。 */
635
+ interface DoubtFriendRequestInfo {
636
+ flag: string;
637
+ uin: number;
638
+ nick?: string;
639
+ source?: string;
640
+ reason?: string;
641
+ msg?: string;
642
+ group_code?: string;
643
+ time?: string;
644
+ type: "doubt";
645
+ }
646
+ /** FriendApi 构造选项。 */
647
+ interface FriendApiOptions {
648
+ /** uid→uin 转换器(通常注入 GroupApi.uidToUin);缺省 uin 退化为 uid。 */
649
+ uidToUin?: (uids: string[]) => Promise<Map<string, string>>;
650
+ }
651
+ /** 好友 API:从 session 拿 buddy service,包装成语义化方法。 */
652
+ declare class FriendApi {
653
+ private readonly service;
654
+ private readonly uidToUin;
655
+ constructor(session: NodeIQQNTWrapperSession, opts?: FriendApiOptions);
656
+ /** 好友列表(分类拍平为 Friend[];昵称/备注从 service 缓存读取)。 */
657
+ getFriendList(): Promise<Friend[]>;
658
+ /** 带分类的好友列表(get_friends_with_category,分类保留)。 */
659
+ getFriendCategories(): Promise<FriendCategory[]>;
660
+ /** 原始分类(getBuddyListV2 / 缓存)。 */
661
+ private getBuddyCategories;
662
+ /** 判断是否好友。 */
663
+ isBuddy(uid: string): boolean;
664
+ /** 好友申请列表(set_friend_add_request 应答前查找匹配项)。 */
665
+ getBuddyReqList(): Promise<BuddyReq[]>;
666
+ /** 应答好友申请(accept=true 同意;remark 由调用方另行 setFriendRemark)。 */
667
+ handleFriendRequest(notify: BuddyReq, accept: boolean): Promise<void>;
668
+ /** 设置好友备注(void 语义乐观处理)。 */
669
+ setFriendRemark(uid: string, remark: string): void;
670
+ /** 删除好友(tempBlock=拉黑,tempBothDel=双向删除)。 */
671
+ deleteFriend(uid: string, tempBlock?: boolean, tempBothDel?: boolean): Promise<void>;
672
+ /** 可疑好友申请列表(get_doubt_friends_add_request;uin 经 uidToUin 转换)。 */
673
+ getDoubtFriendRequest(count: number): Promise<DoubtFriendRequestInfo[]>;
674
+ /** 单项转换:DoubtBuddyReq → OB11 结构(可选字段条件赋值,exactOptionalPropertyTypes)。 */
675
+ private toDoubtFriendRequestInfo;
676
+ /** 处理可疑好友申请(set_doubt_friends_add_request;uid=flag)。 */
677
+ handleDoubtFriendRequest(uid: string): void;
678
+ }
679
+ //#endregion
680
+ //#region src/types/services/group-service.d.ts
681
+ /** 群成员角色(QQ wrapper 契约)。 */
682
+ declare const NTGroupMemberRole: {
683
+ readonly UNSPECIFIED: 0;
684
+ readonly STRANGER: 1;
685
+ readonly MEMBER: 2;
686
+ readonly ADMIN: 3;
687
+ readonly OWNER: 4;
688
+ };
689
+ type NTGroupMemberRole = (typeof NTGroupMemberRole)[keyof typeof NTGroupMemberRole];
690
+ /** 踢人请求项(KickMemberV2Req.kickList 成员,说明书参考,字段值待探测校准)。 */
691
+ interface KickMemberInfo {
692
+ optFlag: number;
693
+ optOperate: number;
694
+ optMemberUid: string;
695
+ optBytesMsg: string;
696
+ }
697
+ /** 踢人请求(set_group_kick 的 kickMemberV2 参数,说明书参考)。 */
698
+ interface KickMemberV2Req {
699
+ groupCode: string;
700
+ kickFlag: number;
701
+ kickList: KickMemberInfo[];
702
+ kickListUids: string[];
703
+ kickMsg: string;
704
+ }
705
+ /** @all 剩余次数(getGroupRemainAtTimes 返回)。 */
706
+ interface GroupRemainAtTimes {
707
+ canAtAll: boolean;
708
+ remainAtAllCountForUin: number;
709
+ remainAtAllCountForGroup: number;
710
+ atTimesMsg: string;
711
+ canNotAtAllMsg: string;
712
+ }
713
+ /** 群通知类型(GroupNotifyMsgType,说明书参考)。 */
714
+ declare const GroupNotifyMsgType: {
715
+ readonly UN_SPECIFIED: 0;
716
+ readonly INVITED_BY_MEMBER: 1;
717
+ readonly REFUSE_INVITED: 2;
718
+ readonly REFUSED_BY_ADMINI_STRATOR: 3;
719
+ readonly AGREED_TOJOIN_DIRECT: 4;
720
+ readonly INVITED_NEED_ADMINI_STRATOR_PASS: 5;
721
+ readonly AGREED_TO_JOIN_BY_ADMINI_STRATOR: 6;
722
+ readonly REQUEST_JOIN_NEED_ADMINI_STRATOR_PASS: 7;
723
+ readonly SET_ADMIN: 8;
724
+ readonly KICK_MEMBER_NOTIFY_ADMIN: 9;
725
+ readonly KICK_MEMBER_NOTIFY_KICKED: 10;
726
+ readonly MEMBER_LEAVE_NOTIFY_ADMIN: 11;
727
+ readonly CANCEL_ADMIN_NOTIFY_CANCELED: 12;
728
+ readonly CANCEL_ADMIN_NOTIFY_ADMIN: 13;
729
+ readonly TRANSFER_GROUP_NOTIFY_OLDOWNER: 14;
730
+ readonly TRANSFER_GROUP_NOTIFY_ADMIN: 15;
731
+ };
732
+ type GroupNotifyMsgType = (typeof GroupNotifyMsgType)[keyof typeof GroupNotifyMsgType];
733
+ /** 群通知处理状态(GroupNotifyMsgStatus,说明书参考)。 */
734
+ declare const GroupNotifyMsgStatus: {
735
+ readonly KINIT: 0;
736
+ readonly KUNHANDLE: 1;
737
+ readonly KAGREED: 2;
738
+ readonly KREFUSED: 3;
739
+ readonly KIGNORED: 4;
740
+ };
741
+ type GroupNotifyMsgStatus = (typeof GroupNotifyMsgStatus)[keyof typeof GroupNotifyMsgStatus];
742
+ /** 群请求操作类型(NTGroupRequestOperateTypes,说明书参考)。 */
743
+ declare const NTGroupRequestOperateTypes: {
744
+ readonly KUNSPECIFIED: 0;
745
+ readonly KAGREE: 1;
746
+ readonly KREFUSE: 2;
747
+ readonly KIGNORE: 3;
748
+ readonly KDELETE: 4;
749
+ };
750
+ type NTGroupRequestOperateTypes = (typeof NTGroupRequestOperateTypes)[keyof typeof NTGroupRequestOperateTypes];
751
+ /** 群通知(getSingleScreenNotifies 返回项,说明书参考,待探测校准)。 */
752
+ interface GroupNotify {
753
+ seq: string;
754
+ type: GroupNotifyMsgType;
755
+ status: GroupNotifyMsgStatus;
756
+ group?: {
757
+ groupCode: string;
758
+ groupName: string;
759
+ };
760
+ user1?: {
761
+ uid: string;
762
+ nickName: string;
763
+ };
764
+ user2?: {
765
+ uid: string;
766
+ nickName: string;
767
+ };
768
+ actionTime?: string;
769
+ postscript?: string;
770
+ warningTips?: string;
771
+ }
772
+ /** 禁言成员(getGroupShutUpMemberList 返回项,说明书参考,待探测校准)。 */
773
+ interface ShutUpGroupMember {
774
+ uid: string;
775
+ qid: string;
776
+ uin: string;
777
+ nick: string;
778
+ remark: string;
779
+ cardName: string;
780
+ shutUpTime: number;
781
+ memberSpecialTitle?: string;
782
+ }
783
+ /** 群列表项(Group 实体,说明书参考)。 */
784
+ interface Group {
785
+ groupCode: string;
786
+ groupName: string;
787
+ memberCount: number;
788
+ maxMember: number;
789
+ remarkName?: string;
790
+ groupOwnerId?: {
791
+ memberUin: string;
792
+ memberUid: string;
793
+ };
794
+ memberRole?: number;
795
+ isTop?: boolean;
796
+ [key: string]: unknown;
797
+ }
798
+ /** 群详情(getGroupDetailInfo 返回,说明书参考)。 */
799
+ interface GroupDetailInfo {
800
+ groupCode: string;
801
+ groupUin: string;
802
+ ownerUin: string;
803
+ ownerUid?: string;
804
+ groupName: string;
805
+ memberNum: number;
806
+ maxMemberNum: number;
807
+ remarkName?: string;
808
+ isTop?: boolean;
809
+ groupCreateTime?: number;
810
+ [key: string]: unknown;
811
+ }
812
+ /** 群成员(getAllMemberList result.infos 的 value,说明书参考)。 */
813
+ interface GroupMember {
814
+ uid: string;
815
+ uin: string;
816
+ nick: string;
817
+ cardName: string;
818
+ remark: string;
819
+ role: NTGroupMemberRole;
820
+ shutUpTime: number;
821
+ joinTime: string;
822
+ lastSpeakTime: string;
823
+ memberSpecialTitle?: string;
824
+ sex?: number;
825
+ age?: number;
826
+ isRobot?: boolean;
827
+ [key: string]: unknown;
828
+ }
829
+ /** 群服务:apis/group 用到的核心方法面。 */
830
+ interface NodeIKernelGroupService {
831
+ addKernelGroupListener(listener: unknown): number;
832
+ removeKernelGroupListener(listenerId: number): void;
833
+ getGroupList(force: boolean): Promise<GeneralCallResult>;
834
+ getGroupDetailInfo(groupCode: string, groupInfoSource: number): Promise<GeneralCallResult>;
835
+ getAllMemberList(groupCode: string, forceFetch: boolean): Promise<{
836
+ errCode: number;
837
+ errMsg: string;
838
+ result: {
839
+ ids: Array<{
840
+ uid: string;
841
+ index: number;
842
+ }>;
843
+ infos: Map<string, GroupMember>;
844
+ finish: boolean;
845
+ };
846
+ }>;
847
+ getMemberInfo(groupCode: string, uids: string[], forceFetch: boolean): Promise<GeneralCallResult>;
848
+ /** uin → uid(私聊发送等需要,说明书参考)。 */
849
+ getUidByUins(uins: string[]): Promise<{
850
+ errCode: number;
851
+ errMsg: string;
852
+ uids: Map<string, string>;
853
+ }>;
854
+ /** uid → uin。 */
855
+ getUinByUids(uids: string[]): Promise<{
856
+ errCode: number;
857
+ errMsg: string;
858
+ uins: Map<string, string>;
859
+ }>;
860
+ /** 踢人(set_group_kick)。 */
861
+ kickMemberV2(param: KickMemberV2Req): Promise<GeneralCallResult>;
862
+ /** 成员禁言(set_group_ban;timeStamp=0 解除禁言)。 */
863
+ setMemberShutUp(groupCode: string, memberTimes: Array<{
864
+ uid: string;
865
+ timeStamp: number;
866
+ }>): Promise<GeneralCallResult>;
867
+ /** 全员禁言(set_group_whole_ban)。 */
868
+ setGroupShutUp(groupCode: string, shutUp: boolean): Promise<GeneralCallResult>;
869
+ /** 设置管理员(set_group_admin;void 语义,乐观处理)。 */
870
+ modifyMemberRole(groupCode: string, uid: string, role: NTGroupMemberRole): void;
871
+ /** 设置群名片(set_group_card;void 语义)。 */
872
+ modifyMemberCardName(groupCode: string, uid: string, cardName: string): void;
873
+ /** 修改群名(set_group_name)。 */
874
+ modifyGroupName(groupCode: string, groupName: string, isNormalMember: boolean): Promise<GeneralCallResult>;
875
+ /** 退群(set_group_leave)。 */
876
+ quitGroupV2(param: {
877
+ groupCode: string;
878
+ needDeleteLocalMsg: boolean;
879
+ }): Promise<GeneralCallResult>;
880
+ /** 设置精华消息(msgSeq/msgRandom 取自消息本体)。 */
881
+ addGroupEssence(param: {
882
+ groupCode: string;
883
+ msgRandom: number;
884
+ msgSeq: number;
885
+ }): Promise<unknown>;
886
+ /** 取消精华消息。 */
887
+ removeGroupEssence(param: {
888
+ groupCode: string;
889
+ msgRandom: number;
890
+ msgSeq: number;
891
+ }): Promise<unknown>;
892
+ /** @all 剩余次数(get_group_at_all_remain)。 */
893
+ getGroupRemainAtTimes(groupCode: string): Promise<Omit<GeneralCallResult, "result"> & {
894
+ errCode: number;
895
+ atInfo: GroupRemainAtTimes;
896
+ }>;
897
+ /** 单屏通知列表(get_group_system_msg / set_group_add_request 共用;列表可能走 listener,宽松解包)。 */
898
+ getSingleScreenNotifies(doubt: boolean, startSeq: string, count: number): Promise<GeneralCallResult & {
899
+ result?: unknown;
900
+ }>;
901
+ /** 禁言成员列表(get_group_shut_list;同 listener 风格,宽松解包)。 */
902
+ getGroupShutUpMemberList(groupCode: string): Promise<GeneralCallResult & {
903
+ result?: unknown;
904
+ }>;
905
+ /** 处理群请求(set_group_add_request 应答;postscript 空值可能导致失败,默认空格)。 */
906
+ operateSysNotify(doubt: boolean, operateMsg: {
907
+ operateType: NTGroupRequestOperateTypes;
908
+ targetMsg: {
909
+ seq: string;
910
+ type: GroupNotifyMsgType;
911
+ groupCode: string;
912
+ postscript: string;
913
+ };
914
+ }): Promise<void>;
915
+ }
916
+ //#endregion
917
+ //#region src/apis/group.d.ts
918
+ /** 群 API:从 session 拿 group service,包装成语义化方法。 */
919
+ declare class GroupApi {
920
+ private readonly service;
921
+ /** 精华消息需要 msg service(按 msgId 拉消息取 msgSeq/msgRandom)。 */
922
+ private readonly msgService;
923
+ constructor(session: NodeIQQNTWrapperSession);
924
+ /** 群列表(force=true 强制刷新,默认缓存)。 */
925
+ getGroupList(force?: boolean): Promise<Group[]>;
926
+ /** 群详情(groupCode 为群号字符串)。
927
+ * getGroupDetailInfo 返回形状:失败 result=错误码;成功详情可能直接在 result
928
+ * 对象里,也可能在 groupInfo/detailInfo 字段——三种形状都兼容(探测校准)。
929
+ * 2026-08-07 修复:成功(result=0)时不再把 {result:0,errMsg} 原样当详情返回,
930
+ * 而是提取详情字段;形状异常抛 UNKNOWN 而非静默返回垃圾数据。 */
931
+ getGroupInfo(groupCode: string): Promise<GroupDetailInfo>;
932
+ /** 群成员列表(forceFetch=true 强制拉取,默认缓存优先)。 */
933
+ getGroupMemberList(groupCode: string, forceFetch?: boolean): Promise<GroupMember[]>;
934
+ /** 群成员详情(uids 为空返回空数组)。 */
935
+ getGroupMemberInfo(groupCode: string, uids: string[]): Promise<GroupMember[]>;
936
+ /** uin → uid(私聊发送等需要)。 */
937
+ uinToUid(uins: string[]): Promise<Map<string, string>>;
938
+ /** uid → uin。 */
939
+ uidToUin(uids: string[]): Promise<Map<string, string>>;
940
+ /** 群成员角色 → OB11 role 字符串。 */
941
+ static roleToString(role: NTGroupMemberRole): "owner" | "admin" | "member";
942
+ /**
943
+ * 踢人(set_group_kick)。memberUids 为成员 uid;refuseForever=true 拉黑拒绝再次入群。
944
+ * kickMemberV2 的 kickFlag/kickList 字段值待探测校准(TODO P3 联调)。
945
+ */
946
+ kickMember(groupCode: string, memberUids: string[], refuseForever: boolean, reason?: string): Promise<void>;
947
+ /** 成员禁言(duration 秒,0 解除禁言)。 */
948
+ setMemberShutUp(groupCode: string, members: Array<{
949
+ uid: string;
950
+ duration: number;
951
+ }>): Promise<void>;
952
+ /** 全员禁言(enable=true 开启全群禁言)。 */
953
+ setGroupShutUp(groupCode: string, enable: boolean): Promise<void>;
954
+ /** 设置管理员(role=ADMIN 设管理,MEMBER 取消;void 语义乐观处理)。 */
955
+ setMemberRole(groupCode: string, uid: string, role: NTGroupMemberRole): void;
956
+ /** 设置群名片(void 语义乐观处理)。 */
957
+ setMemberCardName(groupCode: string, uid: string, cardName: string): void;
958
+ /** 修改群名。 */
959
+ modifyGroupName(groupCode: string, groupName: string): Promise<void>;
960
+ /** 退群(needDeleteLocalMsg=is_dismiss:是否解散群,仅群主)。 */
961
+ quitGroup(groupCode: string, needDeleteLocalMsg?: boolean): Promise<void>;
962
+ /** 设置精华消息(msgId 经 msgService 取 msgSeq/msgRandom)。 */
963
+ addGroupEssence(groupCode: string, msgId: string): Promise<void>;
964
+ /** 取消精华消息。 */
965
+ removeGroupEssence(groupCode: string, msgId: string): Promise<void>;
966
+ /** 精华消息公共流程:按 msgId 拉消息 → add/removeGroupEssence。 */
967
+ private setEssence;
968
+ /** @all 剩余次数(get_group_at_all_remain)。 */
969
+ getGroupRemainAtTimes(groupCode: string): Promise<{
970
+ canAtAll: boolean;
971
+ remainAtAllCountForUin: number;
972
+ remainAtAllCountForGroup: number;
973
+ }>;
974
+ }
975
+ //#endregion
976
+ //#region src/apis/group-notify.d.ts
977
+ /** 群通知 API:从 session 拿 group service,包装成语义化方法。 */
978
+ declare class GroupNotifyApi {
979
+ private readonly service;
980
+ constructor(session: NodeIQQNTWrapperSession);
981
+ /** 单屏通知列表(get_group_system_msg / set_group_add_request 共用)。 */
982
+ getSingleScreenNotifies(doubt: boolean, count: number): Promise<GroupNotify[]>;
983
+ /** 禁言成员列表(get_group_shut_list)。 */
984
+ getGroupShutUpMemberList(groupCode: string): Promise<GroupMember[]>;
985
+ /** 处理群请求(set_group_add_request 应答;approve=true 同意 / false 拒绝)。 */
986
+ handleGroupRequest(doubt: boolean, notify: GroupNotify, operateType: NTGroupRequestOperateTypes, reason: string): Promise<void>;
987
+ }
988
+ //#endregion
989
+ //#region src/types/message-element.d.ts
990
+ /** NT RawMessage → canonical 元素(与 toSendElements 对称,接收方向)。 */
991
+ declare function toCanonicalElements(msg: RawMessage): CanonicalElement[];
992
+ /** canonical 元素 → NT 发送元素(text/at/face/image/voice/reply 核心五类)。 */
993
+ declare function toSendElements(elements: CanonicalElement[]): SendMessageElement[];
994
+ /** 协议无关的规范消息元素。 */
995
+ type CanonicalElement = {
996
+ type: "text";
997
+ text: string;
998
+ } | {
999
+ type: "at";
1000
+ target: string;
1001
+ display?: string;
1002
+ } | {
1003
+ type: "image";
1004
+ path: string;
1005
+ url?: string;
1006
+ size?: {
1007
+ width: number;
1008
+ height: number;
1009
+ };
1010
+ } | {
1011
+ type: "face";
1012
+ id: string;
1013
+ } | {
1014
+ type: "voice";
1015
+ path: string;
1016
+ durationMs?: number;
1017
+ url?: string;
1018
+ } | {
1019
+ type: "video";
1020
+ path: string;
1021
+ url?: string;
1022
+ } | {
1023
+ type: "file";
1024
+ path: string;
1025
+ name?: string;
1026
+ size?: number;
1027
+ } | {
1028
+ type: "reply";
1029
+ messageId: string;
1030
+ } | {
1031
+ type: "forward";
1032
+ messageIds: string[];
1033
+ } | {
1034
+ type: "json";
1035
+ raw: unknown;
1036
+ } | {
1037
+ type: "xml";
1038
+ raw: unknown;
1039
+ } | {
1040
+ type: "unknown";
1041
+ raw: unknown;
1042
+ };
1043
+ //#endregion
1044
+ //#region src/apis/msg.d.ts
1045
+ /** 消息 API:从 session 拿 msg service,包装成语义化方法。 */
1046
+ declare class MsgApi {
1047
+ private readonly service;
1048
+ /** 上次生成 msgId 的时间(单调递增,2026-08-07 防同毫秒并发碰撞)。 */
1049
+ private lastMsgTime;
1050
+ constructor(session: NodeIQQNTWrapperSession);
1051
+ /**
1052
+ * 生成 msgId 时间戳(单调递增)。
1053
+ * generateMsgUniqueId(chatType, time) 以 time 区分消息——同毫秒并发发送
1054
+ * (机器人群发/多会话同时回复)Date.now() 会碰撞,msgId 相同导致 wrapper
1055
+ * 拒绝或覆盖。严格单调递增保证进程内唯一。
1056
+ */
1057
+ private nextMsgTime;
1058
+ /**
1059
+ * 发送消息:canonical 元素 → NT 发送元素 → sendMsg。
1060
+ * 返回 NT msgId(雪花 ID)。
1061
+ */
1062
+ sendMessage(target: Peer, elements: CanonicalElement[]): Promise<{
1063
+ msgId: string;
1064
+ }>;
1065
+ /** 撤回消息(群聊管理员 / 私聊 2 分钟内)。 */
1066
+ recallMessage(target: Peer, msgIds: string[]): Promise<void>;
1067
+ /** 拉取历史消息(msgId 为空从最新拉;count 条,时间倒序)。 */
1068
+ fetchMessages(target: Peer, opts: {
1069
+ count: number;
1070
+ msgId?: string;
1071
+ }): Promise<RawMessage[]>;
1072
+ /** 按 msgId 批量拉取消息(get_msg / 精华消息 / ptt 转文字共用)。 */
1073
+ fetchMsgsByMsgId(target: Peer, ids: string[]): Promise<RawMessage[]>;
1074
+ /** 消息表情表态(set_msg_emoji_like;like=true 点赞,false 取消)。 */
1075
+ setMsgEmojiLike(target: Peer, opts: {
1076
+ msgSeq: string;
1077
+ emojiId: string;
1078
+ emojiType: string;
1079
+ like: boolean;
1080
+ }): Promise<void>;
1081
+ /**
1082
+ * 语音转文字(fetch_ptt_text)。
1083
+ * 流程:按 msgId 拉消息 → 找 PTT 元素 → translatePtt2Text(异步转写)
1084
+ * → 再拉一次消息读 pttElement.text。
1085
+ */
1086
+ fetchPttText(msgId: string, target: Peer): Promise<string>;
1087
+ /** 标记会话已读。 */
1088
+ markRead(target: Peer): Promise<void>;
1089
+ /** 发送输入状态(set_input_status;eventType=1 输入中,0 停止)。 */
1090
+ setInputStatus(target: Peer, eventType: number): Promise<void>;
1091
+ /**
1092
+ * 发送合并转发(send_group/private_forward_msg)。
1093
+ * buildMultiForwardMsg 组装 MULTI_FORWARD 元素 → 直接作 sendMsg 元素发送。
1094
+ */
1095
+ sendForwardMessage(target: Peer, sourcePeer: Peer, srcMsgIds: string[]): Promise<{
1096
+ msgId: string;
1097
+ }>;
1098
+ /** 获取合并转发内容(get_forward_msg;resId 取自 multiForwardMsgElement)。 */
1099
+ fetchForwardMessage(peer: Peer, msgId: string): Promise<RawMessage[]>;
1100
+ /** 单条转发(forward_group/friend_single_msg;srcMsgIds 源、dstPeer 目标)。 */
1101
+ forwardSingleMessage(sourcePeer: Peer, srcMsgIds: string[], dstPeer: Peer): Promise<void>;
1102
+ /** 设置在线状态(set_online_status;customStatus 为自定义状态)。 */
1103
+ setOnlineStatus(opts: {
1104
+ status: number;
1105
+ extStatus: number;
1106
+ batteryStatus: number;
1107
+ customStatus?: {
1108
+ faceId: string;
1109
+ wording: string;
1110
+ faceType: string;
1111
+ };
1112
+ }): Promise<void>;
1113
+ }
1114
+ //#endregion
1115
+ //#region src/types/services/ticket-service.d.ts
1116
+ /** forceFetchClientKey 返回(get_clientkey 直接返回,get_cookies 用 clientKey 换跳转票据)。 */
1117
+ interface ForceFetchClientKeyRetType extends GeneralCallResult {
1118
+ url: string;
1119
+ keyIndex: string;
1120
+ clientKey: string;
1121
+ expireTime: string;
1122
+ }
1123
+ /** 票据服务。 */
1124
+ interface NodeIKernelTicketService {
1125
+ addKernelTicketListener(listener: unknown): number;
1126
+ removeKernelTicketListener(listenerId: number): void;
1127
+ forceFetchClientKey(arg: string): Promise<ForceFetchClientKeyRetType>;
1128
+ isNull(): boolean;
1129
+ }
1130
+ //#endregion
1131
+ //#region src/apis/ticket.d.ts
1132
+ /** 票据 API:从 session 拿 ticket service,包装成语义化方法。 */
1133
+ declare class TicketApi {
1134
+ private readonly service;
1135
+ constructor(session: NodeIQQNTWrapperSession);
1136
+ /** 获取 clientKey(get_clientkey)。 */
1137
+ getClientKey(): Promise<ForceFetchClientKeyRetType>;
1138
+ /** 获取指定域名的 cookies(get_cookies;uin 为机器人 QQ 号)。 */
1139
+ getCookies(domain: string, uin: string): Promise<Record<string, string>>;
1140
+ /** 计算 bkn(get_csrf_token 与 web 接口共用;skey → bkn 哈希)。 */
1141
+ static getBkn(skey: string): string;
1142
+ }
1143
+ //#endregion
1144
+ //#region src/apis/profile.d.ts
1145
+ /** 陌生人信息(get_stranger_info 返回)。 */
1146
+ interface StrangerInfo {
1147
+ user_id: number;
1148
+ uid: string;
1149
+ nickname: string;
1150
+ age: number;
1151
+ qid: string;
1152
+ qq_level: number;
1153
+ sex: "male" | "female" | "unknown";
1154
+ long_nick: string;
1155
+ reg_time: number;
1156
+ is_vip: boolean;
1157
+ is_years_vip: boolean;
1158
+ vip_level: number;
1159
+ remark: string;
1160
+ status: number;
1161
+ login_days: number;
1162
+ }
1163
+ /** 资料 API:从 session 拿 profile service,包装成语义化方法。 */
1164
+ declare class ProfileApi {
1165
+ private readonly service;
1166
+ constructor(session: NodeIQQNTWrapperSession);
1167
+ /** 设置个性签名(set_self_longnick)。 */
1168
+ setLongNick(longNick: string): Promise<void>;
1169
+ /** 设置昵称(set_qq_profile)。 */
1170
+ setNickName(nickName: string): Promise<void>;
1171
+ /** 设置头像(set_qq_avatar;filePath 为本地路径)。 */
1172
+ setHeader(filePath: string): Promise<void>;
1173
+ /** 获取陌生人信息(get_stranger_info;uin 为用户 QQ 号)。 */
1174
+ getStrangerInfo(uin: string): Promise<StrangerInfo>;
1175
+ }
1176
+ //#endregion
1177
+ //#region src/apis/profile-like.d.ts
1178
+ /** 点赞 API:从 session 拿 profile like service,包装成语义化方法。 */
1179
+ declare class ProfileLikeApi {
1180
+ private readonly service;
1181
+ constructor(session: NodeIQQNTWrapperSession);
1182
+ /** 点赞(send_like;uid 为目标 uid,count 次数)。 */
1183
+ sendLike(uid: string, count?: number): Promise<void>;
1184
+ }
1185
+ //#endregion
1186
+ //#region src/types/services/richmedia-service.d.ts
1187
+ /** 群文件列表参数(getGroupFileList,说明书参考)。 */
1188
+ interface GetFileListParam {
1189
+ sortType: number;
1190
+ fileCount: number;
1191
+ startIndex: number;
1192
+ sortOrder: number;
1193
+ showOnlinedocFolder: number;
1194
+ }
1195
+ /** 群文件项(getGroupFileList 返回的 fileInfo,说明书参考,待探测校准)。 */
1196
+ interface GroupFileItemInfo {
1197
+ fileId: string;
1198
+ fileName: string;
1199
+ fileSize: string;
1200
+ fileUuid?: string;
1201
+ parent?: string;
1202
+ uploadTime?: number;
1203
+ modifyTime?: number;
1204
+ uploaderUid?: string;
1205
+ uploaderUin?: string;
1206
+ [key: string]: unknown;
1207
+ }
1208
+ /** 群文件夹项(getGroupFileList 返回的 folderInfo,说明书参考,待探测校准)。 */
1209
+ interface GroupFolderInfo {
1210
+ folderId: string;
1211
+ folderName: string;
1212
+ folderPath?: string;
1213
+ folderUid?: string;
1214
+ [key: string]: unknown;
1215
+ }
1216
+ /** 群文件空间信息(getGroupFileList 的 groupSpaceResult,说明书参考)。 */
1217
+ interface GroupSpaceInfo {
1218
+ retCode: number;
1219
+ retMsg: string;
1220
+ clientWording: string;
1221
+ totalSpace: number;
1222
+ usedSpace: number;
1223
+ allUpload: boolean;
1224
+ }
1225
+ /** 富媒体服务。 */
1226
+ interface NodeIKernelRichMediaService {
1227
+ addKernelRichMediaListener(listener: unknown): number;
1228
+ removeKernelRichMediaListener(listenerId: number): void;
1229
+ /** 英文单词翻译(translate_en2zh)。 */
1230
+ translateEnWordToZn(words: string[]): Promise<GeneralCallResult & {
1231
+ words?: string[];
1232
+ }>;
1233
+ /** 群文件列表(get_group_root_files / get_group_files_by_folder)。 */
1234
+ getGroupFileList(groupCode: string, params: GetFileListParam): Promise<GeneralCallResult & {
1235
+ groupSpaceResult?: GroupSpaceInfo;
1236
+ result?: unknown;
1237
+ }>;
1238
+ /** 创建群文件夹(create_group_file_folder)。 */
1239
+ createGroupFolder(groupCode: string, folderName: string): Promise<GeneralCallResult>;
1240
+ /** 删除群文件(delete_group_file;params 业务类型,Files 为文件 ID 列表)。 */
1241
+ deleteGroupFile(groupCode: string, params: number[], files: string[]): Promise<GeneralCallResult>;
1242
+ /** 删除群文件夹(delete_group_folder)。 */
1243
+ deleteGroupFolder(groupCode: string, folderId: string): Promise<GeneralCallResult>;
1244
+ /** 重命名群文件(rename_group_file;参数待探测校准)。 */
1245
+ renameGroupFile(arg1: string, arg2: number, arg3: string, arg4: string, arg5: string): Promise<unknown>;
1246
+ /** 移动群文件(move_group_file)。 */
1247
+ moveGroupFile(groupCode: string, busId: number[], fileList: string[], currentParentDirectory: string, targetParentDirectory: string): Promise<GeneralCallResult>;
1248
+ /** 转存群文件(trans_group_file)。 */
1249
+ transGroupFile(groupCode: string, fileId: string): Promise<GeneralCallResult>;
1250
+ /** 批量群文件数(get_group_file_system_info 补充)。 */
1251
+ batchGetGroupFileCount(groupCodes: string[]): Promise<GeneralCallResult & {
1252
+ groupCodes?: string[];
1253
+ groupFileCounts?: number[];
1254
+ }>;
1255
+ isNull(): boolean;
1256
+ }
1257
+ //#endregion
1258
+ //#region src/apis/richmedia.d.ts
1259
+ /** 群文件列表条目(fileInfo/folderInfo 取其一)。 */
1260
+ interface GroupFileListItem {
1261
+ fileInfo?: GroupFileItemInfo;
1262
+ folderInfo?: GroupFolderInfo;
1263
+ }
1264
+ /** 群文件系统信息。 */
1265
+ interface GroupFileSystemInfo {
1266
+ fileCount: number;
1267
+ limitCount: number;
1268
+ usedSpace: number;
1269
+ totalSpace: number;
1270
+ }
1271
+ /** 富媒体 API:从 session 拿 rich media service,包装成语义化方法。 */
1272
+ declare class RichMediaApi {
1273
+ private readonly service;
1274
+ constructor(session: NodeIQQNTWrapperSession);
1275
+ /** 英文单词翻译(translate_en2zh)。 */
1276
+ translateWords(words: string[]): Promise<string[]>;
1277
+ /** 群文件列表(get_group_root_files;parent 缺省根目录)。 */
1278
+ getGroupFileList(groupCode: string, parentFolderId?: string, fileCount?: number): Promise<GroupFileListItem[]>;
1279
+ /** 群文件系统信息(get_group_file_system_info;getGroupFileList 的 groupSpaceResult)。 */
1280
+ getGroupFileSystemInfo(groupCode: string): Promise<GroupFileSystemInfo>;
1281
+ /** 创建群文件夹(create_group_file_folder)。 */
1282
+ createGroupFolder(groupCode: string, folderName: string): Promise<string>;
1283
+ /** 删除群文件(delete_group_file)。 */
1284
+ deleteGroupFile(groupCode: string, fileIds: string[]): Promise<void>;
1285
+ /** 删除群文件夹(delete_group_folder)。 */
1286
+ deleteGroupFolder(groupCode: string, folderId: string): Promise<void>;
1287
+ /** 重命名群文件(rename_group_file;参数语义待探测校准)。 */
1288
+ renameGroupFile(groupCode: string, fileId: string, newName: string): Promise<void>;
1289
+ /** 移动群文件(move_group_file;targetFolder 空为根目录)。 */
1290
+ moveGroupFile(groupCode: string, fileIds: string[], targetFolderId: string): Promise<void>;
1291
+ /** 转存群文件(trans_group_file)。 */
1292
+ transGroupFile(groupCode: string, fileId: string): Promise<void>;
1293
+ }
1294
+ //#endregion
1295
+ //#region src/apis/webapi.d.ts
1296
+ /** 精华消息项(digest_list 返回 data.msg_list 成员,说明书参考)。 */
1297
+ interface EssenceMsgItem {
1298
+ msg_seq: number;
1299
+ msg_random: number;
1300
+ sender_uin: string;
1301
+ sender_nick: string;
1302
+ add_digest_uin: string;
1303
+ add_digest_nick: string;
1304
+ add_digest_time: number;
1305
+ msg_content: Array<{
1306
+ msg_type?: number;
1307
+ text?: string;
1308
+ image_url?: string;
1309
+ }>;
1310
+ }
1311
+ /** 群荣誉项(honorlist 返回列表项,说明书参考)。 */
1312
+ interface HonorListItem {
1313
+ uin: string;
1314
+ name: string;
1315
+ avatar: string;
1316
+ desc: string;
1317
+ }
1318
+ /** 群荣誉信息(getGroupHonorInfo 返回)。 */
1319
+ interface GroupHonorWebInfo {
1320
+ group_id: number;
1321
+ current_talkative: HonorListItem | null;
1322
+ talkative_list: HonorListItem[];
1323
+ performer_list: HonorListItem[];
1324
+ legend_list: HonorListItem[];
1325
+ emotion_list: HonorListItem[];
1326
+ strong_newbie_list: HonorListItem[];
1327
+ }
1328
+ /** 群荣誉类型(1=龙王 2=群聊之火 3=群聊炽热 6=快乐源泉)。 */
1329
+ declare const WebHonorType: {
1330
+ readonly ALL: 0;
1331
+ readonly TALKATIVE: 1;
1332
+ readonly PERFORMER: 2;
1333
+ readonly LEGEND: 3;
1334
+ readonly EMOTION: 6;
1335
+ };
1336
+ type WebHonorType = (typeof WebHonorType)[keyof typeof WebHonorType];
1337
+ /** 群空间 web API(Cookie 经 TicketApi 注入)。 */
1338
+ declare class WebApi {
1339
+ private readonly getCookies;
1340
+ constructor(opts: {
1341
+ getCookies: (domain: string) => Promise<Record<string, string>>;
1342
+ });
1343
+ /** 获取群精华消息列表(get_essence_msg_list;分页拉取至 is_end)。 */
1344
+ getEssenceMsgList(groupCode: string): Promise<EssenceMsgItem[]>;
1345
+ /** 获取群荣誉信息(get_group_honor_info;type 0=全部)。 */
1346
+ getGroupHonorInfo(groupCode: string, type: WebHonorType): Promise<GroupHonorWebInfo>;
1347
+ /** 拉取单类荣誉列表(honorlist 接口,正则提取 __INITIAL_STATE__)。 */
1348
+ private fetchHonorList;
1349
+ }
1350
+ //#endregion
1351
+ //#region src/event-channel.d.ts
1352
+ /** Listener 接口形状(宽约束;精确签名由实例化时的具体接口保证)。 */
1353
+ type ListenerShape = Record<string, unknown>;
1354
+ /** 事件名:`${Service}/${method}`。 */
1355
+ type EventName<L extends ListenerShape, Name extends string> = `${Name}/${keyof L & string}`;
1356
+ /** 按事件名从 Listener 精确提取 handler 类型(条件类型 infer,泛型安全)。 */
1357
+ type EventHandler<L extends ListenerShape, Name extends string, E extends EventName<L, Name>> = Extract<{ [K in keyof L]: L[K] extends ((...args: infer A) => infer R) ? {
1358
+ name: `${Name}/${K & string}`;
1359
+ fn: (...args: A) => R;
1360
+ } : never; }[keyof L], {
1361
+ name: E;
1362
+ }>["fn"];
1363
+ /** 按事件名从 Listener 精确提取参数类型。 */
1364
+ type EventArgs<L extends ListenerShape, Name extends string, E extends EventName<L, Name>> = Extract<{ [K in keyof L]: L[K] extends ((...args: infer A) => unknown) ? {
1365
+ name: `${Name}/${K & string}`;
1366
+ args: A;
1367
+ } : never; }[keyof L], {
1368
+ name: E;
1369
+ }>["args"];
1370
+ /** 从 Listener 接口推导事件映射(文档/调试用):`{ "Msg/onRecvMsg": fn }`。 */
1371
+ type ListenerEvents<L extends ListenerShape, Name extends string> = { [K in keyof L as `${Name}/${K & string}`]: L[K]; };
1372
+ /**
1373
+ * 类型化事件通道。
1374
+ *
1375
+ * @typeParam L - Listener 接口(探测产物,如 MsgListener)
1376
+ * @typeParam Name - Service 名(事件名前缀,如 "Msg")
1377
+ */
1378
+ declare class NTEventChannel<L extends ListenerShape, Name extends string> {
1379
+ readonly serviceName: Name;
1380
+ private readonly emitter;
1381
+ private readonly errorHandlers;
1382
+ constructor(serviceName: Name);
1383
+ /**
1384
+ * 订阅事件:返回 unsubscribe(只注销该 handler,不影响其他订阅者)。
1385
+ * 每个 Service 只注册一次原生监听,缓存维护与协议翻译都订阅这里。
1386
+ */
1387
+ on<E extends EventName<L, Name>>(event: E, handler: EventHandler<L, Name, E>): () => void;
1388
+ /**
1389
+ * 请求-响应桥:注册临时监听 → filter 命中 → resolve;超时自动清理并 reject。
1390
+ * 替代魔法字符串事件名方案。
1391
+ */
1392
+ waitFor<E extends EventName<L, Name>>(event: E, opts?: {
1393
+ filter?: (...args: EventArgs<L, Name, E>) => boolean;
1394
+ timeout?: number;
1395
+ }): Promise<EventArgs<L, Name, E>>;
1396
+ /**
1397
+ * 类型化派发:wrapper-loader 的原生回调经此推入通道。
1398
+ * 2026-08-07 修复:原生 EventEmitter.emit 中一个 listener 抛异常会中断后续
1399
+ * listener 派发(Node 语义)——改为快照数组逐个 try/catch,保证「单个订阅者
1400
+ * 异常不打断派发」(协议翻译层异常不饿死缓存维护等其他订阅者)。
1401
+ */
1402
+ emit<E extends EventName<L, Name>>(event: E, ...args: EventArgs<L, Name, E>): void;
1403
+ /** 订阅错误通知(监听器抛出的异常 / 其他内部错误)。 */
1404
+ onError(handler: (err: unknown) => void): () => void;
1405
+ }
1406
+ //#endregion
1407
+ //#region src/types/listeners/group.d.ts
1408
+ /** 群列表更新类型(说明书参考,值待探测校准)。 */
1409
+ declare const GroupListUpdateType: {
1410
+ /** 全量更新(groupList 为完整列表)。 */
1411
+ readonly ALL: 0;
1412
+ /** 增量更新(合并到现有缓存)。 */
1413
+ readonly PARTIAL: 1;
1414
+ };
1415
+ type GroupListUpdateType = (typeof GroupListUpdateType)[keyof typeof GroupListUpdateType];
1416
+ /** 成员数据来源(onMemberInfoChange 第二参,说明书参考)。 */
1417
+ declare const GroupMemberDataSource: {
1418
+ /** 本地缓存。 */
1419
+ readonly CACHE: 0;
1420
+ /** 网络拉取。 */
1421
+ readonly NETWORK: 1;
1422
+ };
1423
+ type GroupMemberDataSource = (typeof GroupMemberDataSource)[keyof typeof GroupMemberDataSource];
1424
+ /** onMemberListChange 参数(sceneId 为群号 groupCode)。 */
1425
+ interface GroupMemberListChange {
1426
+ sceneId: string;
1427
+ ids: string[];
1428
+ /** uid → GroupMember。 */
1429
+ infos: Map<string, GroupMember>;
1430
+ hasPrev: boolean;
1431
+ hasNext: boolean;
1432
+ hasRobot: boolean;
1433
+ }
1434
+ /** 群服务(GroupService)的原生回调监听接口。 */
1435
+ type GroupListener = {
1436
+ /** 群列表初始化完成(listEmpty:是否无群)。 */
1437
+ onGroupListInited: (listEmpty: boolean) => void;
1438
+ /** 群列表更新。 */
1439
+ onGroupListUpdate: (updateType: GroupListUpdateType, groupList: Group[]) => void;
1440
+ /** 群详情变化。 */
1441
+ onGroupDetailInfoChange: (detailInfo: GroupDetailInfo) => void;
1442
+ /** 群成员列表变化(sceneId=groupCode)。 */
1443
+ onMemberListChange: (arg: GroupMemberListChange) => void;
1444
+ /** 群成员信息变化(dataSource 区分本地缓存/网络)。 */
1445
+ onMemberInfoChange: (groupCode: string, dataSource: GroupMemberDataSource, members: Map<string, GroupMember>) => void;
1446
+ /** 群通知更新(doubt:是否可疑/忽略列表)。 */
1447
+ onGroupNotifiesUpdated: (doubt: boolean, notifies: GroupNotify[]) => void;
1448
+ /** 群通知单屏(分页 seq)。 */
1449
+ onGroupSingleScreenNotifies: (doubt: boolean, seq: string, notifies: GroupNotify[]) => void;
1450
+ /** 群禁言成员列表变化。 */
1451
+ onShutUpMemberListChanged: (groupCode: string, members: ShutUpGroupMember[]) => void;
1452
+ };
1453
+ //#endregion
1454
+ //#region src/bridge/group-bridge.d.ts
1455
+ /** 群事件通道的固定类型(事件名前缀 "Group")。 */
1456
+ type GroupEventChannel = NTEventChannel<GroupListener, "Group">;
1457
+ /**
1458
+ * 群事件桥:注册原生监听 → 回调 emit 到 channel。
1459
+ * 无全局单例(ADR-015 推论)——每进程每 session 实例化一份。
1460
+ */
1461
+ declare class GroupBridge {
1462
+ private readonly service;
1463
+ private readonly channel;
1464
+ private listenerId;
1465
+ constructor(session: NodeIQQNTWrapperSession, channel: GroupEventChannel);
1466
+ /** 注册原生监听(幂等)。 */
1467
+ register(): void;
1468
+ /** 注销原生监听(幂等)。 */
1469
+ unregister(): void;
1470
+ }
1471
+ //#endregion
1472
+ //#region src/types/listeners/msg.d.ts
1473
+ /** 消息已读上报(peer + 已读 seq)。 */
1474
+ interface MsgReadReportItem {
1475
+ peer: unknown;
1476
+ readSeq: string;
1477
+ }
1478
+ /** 消息回执(msgId + 已读 seq)。 */
1479
+ interface MsgReceipt {
1480
+ msgId: string;
1481
+ readSeq: string;
1482
+ }
1483
+ /** 消息服务(MsgService)的原生回调监听接口。
1484
+ * 用 type 别名(非 interface):需满足 ListenerShape(Record<string, unknown>)
1485
+ * 约束——interface 无隐式索引签名不兼容;type 对象类型天然满足。
1486
+ *
1487
+ * ⚠️ 2026-08-07 运行时探测实证(自建宿主,QQ 9.9.33):onRecvMsg 回调参数是
1488
+ * **消息数组**(多条批量推送),非单条 RawMessage——此前单条签名错误(收到数组后
1489
+ * msg.msgId/elements 全 undefined)。信号链:原生回调 → MsgBridge 透传数组 →
1490
+ * 事件通道 → 订阅方遍历处理。 */
1491
+ type MsgListener = {
1492
+ /** 收到新消息(批量数组,运行时实证)。 */
1493
+ onRecvMsg: (msgs: RawMessage[]) => void;
1494
+ /** 消息已读上报。 */
1495
+ onRecvMsgReadReport: (reports: MsgReadReportItem[]) => void;
1496
+ /** 消息回执。 */
1497
+ onRecvMsgReceipt: (receipts: MsgReceipt[]) => void;
1498
+ };
1499
+ //#endregion
1500
+ //#region src/bridge/msg-bridge.d.ts
1501
+ /** 消息事件通道的固定类型(事件名前缀 "Msg")。 */
1502
+ type MsgEventChannel = NTEventChannel<MsgListener, "Msg">;
1503
+ /**
1504
+ * 消息事件桥:注册原生监听 → 回调 emit 到 channel。
1505
+ * 无全局单例(ADR-015 推论)——每进程每 session 实例化一份。
1506
+ */
1507
+ declare class MsgBridge {
1508
+ private readonly service;
1509
+ private readonly channel;
1510
+ private listenerId;
1511
+ constructor(session: NodeIQQNTWrapperSession, channel: MsgEventChannel);
1512
+ /** 注册原生监听(幂等)。 */
1513
+ register(): void;
1514
+ /** 注销原生监听(幂等)。 */
1515
+ unregister(): void;
1516
+ }
1517
+ //#endregion
1518
+ //#region src/cache/group-cache.d.ts
1519
+ /** GroupCache 构造参数。 */
1520
+ interface GroupCacheOptions {
1521
+ /** 群事件通道(GroupBridge 注册原生监听后 emit 到这里)。 */
1522
+ channel: GroupEventChannel;
1523
+ /** 群 API(惰性回填用)。 */
1524
+ groupApi: GroupApi;
1525
+ }
1526
+ /**
1527
+ * 群/成员缓存:事件主动维护 + 查询惰性回填。
1528
+ * 只读接口 getGroupDetail / getMembers / getMember / getGroup(列表项)。
1529
+ */
1530
+ declare class GroupCache {
1531
+ private readonly channel;
1532
+ private readonly groupApi;
1533
+ /** 群列表项(onGroupListUpdate / getGroupList 回填)。 */
1534
+ private readonly groupList;
1535
+ /** 群详情(onGroupDetailInfoChange / getGroupInfo 回填)。 */
1536
+ private readonly groupDetails;
1537
+ /** 群成员:groupCode → (uid → GroupMember)。 */
1538
+ private readonly members;
1539
+ /** 惰性回填 in-flight 去重。 */
1540
+ private readonly inFlight;
1541
+ private unsubscribes;
1542
+ constructor(opts: GroupCacheOptions);
1543
+ /** 订阅群事件通道(幂等)。 */
1544
+ register(): void;
1545
+ /** 退订事件通道(幂等)。 */
1546
+ unregister(): void;
1547
+ /** 合并成员到该群缓存(uid → GroupMember)。 */
1548
+ private upsertMembers;
1549
+ /** 群列表是否已有缓存(同步判断)。 */
1550
+ hasGroup(groupCode: string): boolean;
1551
+ /**
1552
+ * 群列表项(只读;缺失惰性回填 getGroupList)。
1553
+ * 返回 undefined 表示群不存在。
1554
+ */
1555
+ getGroup(groupCode: string): Promise<Group | undefined>;
1556
+ /**
1557
+ * 群详情(只读;缺失惰性回填 getGroupInfo)。
1558
+ * getGroupInfo 恒返回对象(失败抛 KernelError),直接缓存。
1559
+ */
1560
+ getGroupDetail(groupCode: string): Promise<GroupDetailInfo>;
1561
+ /**
1562
+ * 群成员列表(只读;缺失惰性回填 getAllMemberList(forceFetch=true))。
1563
+ * 返回空数组表示该群无成员(或拉取失败已由 GroupApi 抛 KernelError)。
1564
+ */
1565
+ getMembers(groupCode: string): Promise<GroupMember[]>;
1566
+ /**
1567
+ * 群成员(只读;缺失回填:先整群拉取,再按 uid 取;仍无则 getMemberInfo 单查)。
1568
+ * 返回 undefined 表示成员不在群。
1569
+ */
1570
+ getMember(groupCode: string, uid: string): Promise<GroupMember | undefined>;
1571
+ /** 惰性回填全量群列表(getGroup 缺失时)。 */
1572
+ private loadGroupList;
1573
+ /** 惰性回填并发去重:同 key 并发只拉一次。 */
1574
+ private dedupe;
1575
+ }
1576
+ //#endregion
1577
+ //#region src/infra/paths.d.ts
1578
+ /** 默认数据根目录名(用户目录下,程序目录可能只读,见 ADR-016)。 */
1579
+ declare const DEFAULT_DATA_ROOT_NAME = ".napuketto";
1580
+ /** 全局配置文件名。 */
1581
+ declare const MAIN_CONFIG_FILE = "napuketto.toml";
1582
+ interface PathOptions {
1583
+ /** 显式数据根(cli `--data-dir` 传入,优先级最高)。 */
1584
+ dataRoot?: string;
1585
+ /** QQ 号,用于多账号隔离;缺省时直接使用数据根本身。 */
1586
+ account?: string;
1587
+ }
1588
+ /**
1589
+ * 解析数据根:显式参数 > 环境变量 > 用户目录默认。
1590
+ * 返回绝对路径。独立导出便于 cli / 探测脚本复用。
1591
+ */
1592
+ declare function resolveDataRoot(dataRoot?: string): string;
1593
+ interface ConfigPathOptions {
1594
+ /** 兜底数据根(探测全部失败时用 `<dataRoot>/napuketto.toml`,保持旧行为)。 */
1595
+ dataRoot?: string;
1596
+ }
1597
+ /**
1598
+ * 全局配置文件路径解析(2026-08-07 用户拍板:**配置文件放项目根目录,
1599
+ * 数据仍按数据根组织**——数据根只承载账号目录/日志/缓存/QQ 数据)。
1600
+ *
1601
+ * 优先级:
1602
+ * 1. `NAPKETTO_CONFIG` 环境变量(显式指定完整路径,任意场景可用)
1603
+ * 2. 入口模块向上找 `pnpm-workspace.yaml`(monorepo 开发场景,即项目根)
1604
+ * 3. 运行目录(cwd)向上找 `pnpm-workspace.yaml` / `package.json`(发布后用户项目)
1605
+ * 4. 数据根兜底 `<dataRoot>/napuketto.toml`(旧行为兼容)
1606
+ *
1607
+ * 返回绝对路径。独立导出便于 cli / loader 装配链复用。
1608
+ */
1609
+ declare function resolveConfigPath(opts?: ConfigPathOptions): string;
1610
+ /**
1611
+ * 路径装配器:持有账号数据目录下的全部子目录。
1612
+ * 无全局单例(ADR-015 推论)——每账号每进程实例化一份。
1613
+ */
1614
+ declare class PathWrapper {
1615
+ /** 数据根(绝对路径)。 */
1616
+ readonly root: string;
1617
+ /** 账号数据目录(绝对路径),缺省 account 时等于 root。 */
1618
+ readonly accountDir: string;
1619
+ /** config 目录(napuketto.json + 各协议配置)。 */
1620
+ readonly configDir: string;
1621
+ /** logs 目录(pino 文件日志)。 */
1622
+ readonly logsDir: string;
1623
+ /** cache 目录(临时文件、媒体缓存)。 */
1624
+ readonly cacheDir: string;
1625
+ constructor(opts?: PathOptions);
1626
+ /** 递归创建全部目录,启动装配时调用一次。 */
1627
+ ensure(): void;
1628
+ /** 账号目录内的文件路径(如 `file('config', 'napuketto.json')`)。 */
1629
+ file(...segments: string[]): string;
1630
+ /**
1631
+ * 清空缓存目录(clean_cache 动作经注入回调消费)。
1632
+ * 只删除 cacheDir 下的条目,保留目录本身。
1633
+ */
1634
+ clearCache(): void;
1635
+ }
1636
+ //#endregion
1637
+ //#region src/wrapper/wrapper-loader.d.ts
1638
+ /**
1639
+ * Electron 进程类型(Node 的 process 类型无此字段)。
1640
+ * - "browser":QQ 主进程(V1 模式)
1641
+ * - "utility":utilityProcess Worker(路线 B,2026-08-06)
1642
+ */
1643
+ declare function electronProcessType(): string | undefined;
1644
+ /**
1645
+ * 解析 QQ 用户数据根(登录数据目录,如 `C:\Users\<user>\Documents\Tencent Files`)。
1646
+ * 优先 NodeQQNTWrapperUtil.getNTUserDataInfoConfig()(QQ 官方 API),回退默认位置。
1647
+ *
1648
+ * 背景(2026-08-06 P2-1 实测):worker(utilityProcess)模式下 loginService 是
1649
+ * `new NodeIKernelLoginService()` 新建的,其 initConfig 的 commonPath 必须指向
1650
+ * QQ 真实数据路径才能读到历史账号——cli 的 `.napuketto\default` 数据目录读不到
1651
+ * (getLoginList 返回空 → 只能 QR 登录)。V1 主进程模式 QQ 自己 initConfig 过
1652
+ * 正确路径,无需此解析。
1653
+ */
1654
+ declare function resolveQqUserDataRoot(exports: WrapperNodeApi): string | null;
1655
+ /** QQ 版本信息(登录握手用)。 */
1656
+ interface QQVersionContext {
1657
+ fullVersion: string;
1658
+ buildVersion: string;
1659
+ }
1660
+ /** 已引导的 wrapper 上下文(运行在 QQ Electron 主进程内)。 */
1661
+ interface WrapperContext {
1662
+ /** wrapper.node 的 NAPI 顶层导出。 */
1663
+ exports: WrapperNodeApi;
1664
+ /** engine 单例(get() 已调用)。 */
1665
+ engine: NodeIQQNTWrapperEngine;
1666
+ /** 版本信息(供登录握手等使用)。 */
1667
+ versionInfo: QQVersionContext;
1668
+ /** 会话(QQ 拦截捕获 / createSession 后填充)。 */
1669
+ session: NodeIQQNTWrapperSession | null;
1670
+ /** 启动会话包装(NapCat 同款:StartupSessionWrapper.create(),start() 替代 startNT)。 */
1671
+ startupSession: NodeIQQNTStartupSessionWrapper | null;
1672
+ /** QQ 的 loginService 实例(拦截 new 捕获,可为 null)。 */
1673
+ loginService: unknown;
1674
+ }
1675
+ /**
1676
+ * 从 loader 截获的 NAPI exports 创建 wrapper 上下文。
1677
+ * 在 QQ 主进程内调用(boot.cjs → kernel 入口)。
1678
+ */
1679
+ declare function createWrapper(exports: WrapperNodeApi, versionInfo: QQVersionContext): WrapperContext;
1680
+ /** engine 初始化(wrapper 契约:先 engine 后 session)。config 为普通 JS 对象。 */
1681
+ declare function initEngine(ctx: WrapperContext, config: EnginInitDesktopConfig): void;
1682
+ /**
1683
+ * 创建会话(2026-08-06 P2-0 实测修正——NapCat 方式自研等价):
1684
+ * 1. StartupSessionWrapper.create()(启动会话包装)
1685
+ * 2. getNTWrapperSession("nt_1")(QQ 主 session,带完整 cpp_impl)
1686
+ * 3. S.create() 回退
1687
+ *
1688
+ * 背景:`new NodeIQQNTWrapperSession()` 构造对象缺 cpp_impl,session.init 断言
1689
+ * "implementation of IQQNTWrapperSession is not valid"(P2-0 实测确认)。
1690
+ * NapCat 用 StartupSessionWrapper.create() + getNTWrapperSession('nt_1') 解决——
1691
+ * 返回带完整实现的实例。worker(utilityProcess)继承 QQ env 后同样有效。
1692
+ */
1693
+ declare function createSession(ctx: WrapperContext): NodeIQQNTWrapperSession;
1694
+ /** session 初始化(4 参全为 JS 对象,NAPI 自动转换)。 */
1695
+ declare function initSession(ctx: WrapperContext, config: WrapperSessionInitConfig, listener: NodeIKernelSessionListener): void;
1696
+ /**
1697
+ * 启动会话(有 startupSession 用 start(),否则 startNT(0))。
1698
+ *
1699
+ * ⚠️ 2026-08-07 V9 修正:单纯 start() 只在「已 init」的 session 上有效。
1700
+ * 自建宿主必须走 initAndStartSession(先 session.init 再 startupSession.start())——
1701
+ * 先 start 后 init 业务 service 不挂载(HANDOVER-V9 实测)。本函数保留给
1702
+ * 已 init 的 session 补启动用;新路径请用 initAndStartSession。
1703
+ */
1704
+ declare function startSession(ctx: WrapperContext): void;
1705
+ /**
1706
+ * boot 装配入口:createWrapper → initEngine → session。
1707
+ *
1708
+ * **session 来源(2026-08-05 修正)**:
1709
+ * 1. qqSession(boot.cjs 拦截 `new` 窃取的 QQ 已 init session)——尚未落地
1710
+ * 2. createSession(`new NodeIQQNTWrapperSession()`)——实测可用,默认路径
1711
+ * (getMainSession 实测为空壳:service 全 null + 缺 startNT,仅 probe 探测参考)
1712
+ *
1713
+ * 由 loader runtime/boot.cjs 在 QQ 主进程内调用(import kernel dist 后)。
1714
+ * 返回 WrapperContext;失败抛 KernelError。
1715
+ */
1716
+ declare function startNapuketto(options: StartNapukettoOptions): WrapperContext;
1717
+ /** startNapuketto 的引导环境(由 loader launcher 注入环境变量,boot.cjs 透传)。 */
1718
+ interface BootEnv {
1719
+ /** QQ 版本(如 "9.9.31-49919")。 */
1720
+ qqVersion?: string;
1721
+ /** 用户数据目录(cfgDir 的父级,用于 desktopPathConfig)。 */
1722
+ dataDir?: string;
1723
+ /** 账号 uin(可选,提供则一步 init+start)。 */
1724
+ selfUin?: string;
1725
+ /** 账号 uid(可选)。 */
1726
+ selfUid?: string;
1727
+ }
1728
+ /** startNapuketto 选项。 */
1729
+ interface StartNapukettoOptions {
1730
+ /** 截获的 wrapper.node NAPI exports(boot.cjs 传入)。 */
1731
+ wrapperExports: WrapperNodeApi;
1732
+ /** 引导环境(版本/数据目录/账号)。 */
1733
+ env?: BootEnv;
1734
+ /** 覆盖 engine 配置(联调用)。 */
1735
+ engineConfig?: EnginInitDesktopConfig;
1736
+ /** 覆盖 session 配置(联调用,提供则自动 init+start)。 */
1737
+ sessionConfig?: WrapperSessionInitConfig;
1738
+ /** QQ 已 init 的 session(boot.cjs 拦截 new 捕获)。 */
1739
+ qqSession?: NodeIQQNTWrapperSession | null;
1740
+ /** QQ 的 loginService 实例(boot.cjs 拦截 new 捕获)。 */
1741
+ qqLoginService?: unknown;
1742
+ }
1743
+ //#endregion
1744
+ //#region src/login/lifecycle.d.ts
1745
+ /**
1746
+ * 等待 QQ 自己完成 session 初始化(framework 复用模式,2026-08-05 修正)。
1747
+ *
1748
+ * 背景:QQ 9.9.31 实测——session 由 QQ 主进程自己创建并 init(登录后)。
1749
+ * 我们不自己 init(重复 init 断言 "implementation of IQQNTWrapperSession is not valid"),
1750
+ * 也不自己 create(登录前 create() 干扰 QQ,实测 QQ 退出 code=0)。
1751
+ * 正确做法:等 QQ 的 session 就绪(getMsgService 非 null = 核心 service 已挂载)。
1752
+ */
1753
+ declare function waitSessionReady(ctx: WrapperContext, opts: {
1754
+ timeoutMs?: number;
1755
+ }): Promise<void>;
1756
+ /** 登录结果(QR 或快速登录)。 */
1757
+ interface LoginResult {
1758
+ uin: string;
1759
+ uid: string;
1760
+ nick: string;
1761
+ }
1762
+ /** 登录列表项(getLoginList 返回,说明书参考)。 */
1763
+ interface LoginAccountInfo {
1764
+ uin: string;
1765
+ uid?: string;
1766
+ nickName?: string;
1767
+ isQuickLogin?: boolean;
1768
+ }
1769
+ /**
1770
+ * 等待网络连接就绪(loginService.getMsfStatus() === 3)。
1771
+ * 参考 NapCat waitForNetworkConnection 思路(自研实现):快速登录在 QQ 刚拉起、
1772
+ * 网络栈未初始化时报 1006511 网络异常——等待 MSF 连接后再重试。
1773
+ * @returns 是否在超时前就绪。
1774
+ */
1775
+ declare function waitForNetworkConnection(ctx: WrapperContext, opts?: {
1776
+ timeoutMs?: number;
1777
+ }): Promise<boolean>;
1778
+ /** 列出历史登录账号(boot.cjs 启动横幅用,「可用快速登录 of QQ」)。 */
1779
+ declare function listLoginAccounts(ctx: WrapperContext): Promise<LoginAccountInfo[]>;
1780
+ /**
1781
+ * 快速登录:遍历历史登录列表尝试。
1782
+ * P2-1:失败且错误为网络异常(1006511)时,等网络就绪后重试(最多 NETWORK_RETRY_MAX 次)。
1783
+ */
1784
+ declare function quickLogin(ctx: WrapperContext, opts: {
1785
+ uin?: string;
1786
+ timeoutMs?: number;
1787
+ }): Promise<LoginResult>;
1788
+ /** session 初始化(4 参全为普通 JS 对象,等 init 完成信号)。 */
1789
+ declare function initAndStartSession(ctx: WrapperContext, config: WrapperSessionInitConfig, listener: NodeIKernelSessionListener, opts: {
1790
+ timeoutMs?: number;
1791
+ }): Promise<void>;
1792
+ //#endregion
1793
+ //#region src/context.d.ts
1794
+ interface CoreContextOptions {
1795
+ /** pino logger(console + 可选文件,由装配层创建)。 */
1796
+ logger: pino.Logger;
1797
+ /** 账号数据目录布局(config/logs/cache)。 */
1798
+ paths: PathWrapper;
1799
+ }
1800
+ /**
1801
+ * 装配根:持有进程级共享对象。
1802
+ * wrapper / login 由 NapukettoCore 装配后填充,未装配前为 null。
1803
+ */
1804
+ interface CoreContext {
1805
+ readonly logger: pino.Logger;
1806
+ readonly paths: PathWrapper;
1807
+ /** QQ wrapper 上下文(attachWrapper 后填充)。 */
1808
+ wrapper: WrapperContext | null;
1809
+ /** 登录结果(login 成功后填充)。 */
1810
+ login: LoginResult | null;
1811
+ }
1812
+ /** 创建装配根(初始 wrapper/login 为 null)。 */
1813
+ declare function createCoreContext(opts: CoreContextOptions): CoreContext;
1814
+ //#endregion
1815
+ //#region src/infra/logger.d.ts
1816
+ /** 日志级别(pino 标准级别 + silent)。 */
1817
+ type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal" | "silent";
1818
+ interface LoggerOptions {
1819
+ /** 日志级别,默认 `info`。 */
1820
+ level?: LogLevel;
1821
+ /** 是否输出到 console(pretty 模式),默认 true。 */
1822
+ console?: boolean;
1823
+ /** 文件日志路径;不传则不写文件(父目录自动创建)。 */
1824
+ file?: string;
1825
+ /** 附加基础字段(如 `{ name: 'kernel' }`),自动保留 pid;name 用 pino 保留字段
1826
+ * (logger name),pino-pretty 渲染为 `(name/pid)` 元数据头。 */
1827
+ base?: Record<string, unknown>;
1828
+ /** 追加的敏感字段路径(默认内置 token/票据等,见 DEFAULT_REDACT_PATHS)。 */
1829
+ redact?: string[];
1830
+ }
1831
+ /**
1832
+ * 创建 pino logger:console(pretty)+ 可选文件,统一 level / redact。
1833
+ *
1834
+ * 文件目的地用同步写入(`sync: true`):日志量级下性能可接受,且进程退出不丢日志,
1835
+ * 无需额外的 flush 步骤(对比异步 SonicBoom 的 flushSync 时序陷阱)。
1836
+ */
1837
+ declare function createLogger(opts?: LoggerOptions): pino.Logger;
1838
+ //#endregion
1839
+ //#region src/core.d.ts
1840
+ interface NapukettoCoreOptions {
1841
+ /** 数据根 / 账号(透传给 PathWrapper,见 ADR-016)。 */
1842
+ paths?: PathOptions;
1843
+ /** 日志级别,默认 info。 */
1844
+ logLevel?: LogLevel;
1845
+ /** 文件日志路径;不传则默认 `logs/napuketto.log`(父目录自动创建)。 */
1846
+ logFile?: string;
1847
+ /** 是否输出 console,默认 true。 */
1848
+ consoleLog?: boolean;
1849
+ }
1850
+ /** login 参数。 */
1851
+ interface CoreLoginOptions {
1852
+ /** appid(登录握手,兜底 537237765)。 */
1853
+ appid: string;
1854
+ /** session.init 超时(毫秒),默认 15s。 */
1855
+ initTimeoutMs?: number;
1856
+ /** 指定快速登录账号(缺省遍历历史列表)。 */
1857
+ quickUin?: string;
1858
+ /** 快速登录失败时回退 QR 登录(二维码写缓存目录),默认 false。 */
1859
+ qrFallback?: boolean;
1860
+ /** QR 二维码图片保存路径(默认缓存目录 qrcode.png)。 */
1861
+ qrCodePath?: string;
1862
+ }
1863
+ /**
1864
+ * 核心装配器:持有 CoreContext,负责启动/停止编排。
1865
+ * 无全局单例(ADR-015 推论)——每账号每进程实例化一份。
1866
+ */
1867
+ declare class NapukettoCore {
1868
+ /** 装配根(协议层 / apis / cache 的消费入口)。 */
1869
+ readonly ctx: CoreContext;
1870
+ /** 由 create() 装配,不直接 new。 */
1871
+ private constructor();
1872
+ /**
1873
+ * 装配:paths(建目录)→ logger → CoreContext。
1874
+ * 不加载 wrapper / 不登录——启动阶段由 attachWrapper + login 完成。
1875
+ */
1876
+ static create(opts?: NapukettoCoreOptions): NapukettoCore;
1877
+ /**
1878
+ * 装配 wrapper:wrapperExports → startNapuketto(engine.init + session 创建),
1879
+ * 结果挂到 ctx.wrapper。在 QQ 主进程内调用(boot.cjs 截获 exports 后)。
1880
+ * captured:boot.cjs 拦截 `new` 捕获的 QQ 实例(session/loginService,优先使用)。
1881
+ */
1882
+ attachWrapper(wrapperExports: WrapperNodeApi, env?: BootEnv, captured?: {
1883
+ qqSession?: NodeIQQNTWrapperSession | null;
1884
+ qqLoginService?: unknown;
1885
+ }): WrapperContext;
1886
+ /**
1887
+ * 登录 + session 初始化(wrapper 契约,2026-08-05 实测确认):
1888
+ * loginService.initConfig → 登录(快速/QR)→ **登录成功后** create session + init
1889
+ * → 等 onOpentelemetryInit(is_init) 完成信号。成功后填 ctx.login。
1890
+ *
1891
+ * 关键(实测):登录前 create()/init 均断言失败(session 未 init / 干扰 QQ);
1892
+ * 登录后 QQ 自己 init 并触发 listener.onOpentelemetryInit——我们只需在登录后
1893
+ * create + init 并监听该信号。
1894
+ */
1895
+ login(opts: CoreLoginOptions): Promise<LoginResult>;
1896
+ /**
1897
+ * 替换当前 session(登录后 Proxy 捕获的 QQ 新实例替换自己 create 的无效实例)。
1898
+ * 在 QQ 主进程内由 boot.cjs 调用(登录成功后)。
1899
+ */
1900
+ setSession(session: NodeIQQNTWrapperSession): void;
1901
+ /** QR 登录:QrLoginSession 状态机 + 二维码写缓存目录(无 UI,cli 可打印路径)。 */
1902
+ private loginByQr;
1903
+ /** 停止:日志收尾(资源清理留给 P2 常驻管理)。 */
1904
+ stop(): void;
1905
+ }
1906
+ //#endregion
1907
+ //#region src/infra/config.d.ts
1908
+ /** 配置文本格式。 */
1909
+ type ConfigFormat = "json" | "toml";
1910
+ /**
1911
+ * 校验器最小接口。zod 的 `ZodType<T>`(`parse(data: unknown): T`)天然满足;
1912
+ * 手写校验器包装成该形状即可。
1913
+ */
1914
+ interface ConfigSchema<T> {
1915
+ parse: (input: unknown) => T;
1916
+ }
1917
+ interface ConfigOptions<T> {
1918
+ /** 配置文件绝对路径。 */
1919
+ path: string;
1920
+ /** 校验器(协议 schema 用 zod;kernel 主配置用手写校验器包装)。 */
1921
+ schema: ConfigSchema<T>;
1922
+ /** 默认值:文件缺失时生成并落盘;校验以它为兜底。 */
1923
+ defaults: T;
1924
+ /** 内存初值(已校验对象):load() 时直接使用,跳过文件读写(全局 TOML 分段的装配方式)。 */
1925
+ seed?: T | undefined;
1926
+ /** 文本格式(缺省按扩展名推断)。 */
1927
+ format?: ConfigFormat | undefined;
1928
+ }
1929
+ /**
1930
+ * 配置基类。每次 `load()` / `save()` 都经过 schema 校验,
1931
+ * 校验失败抛 `KernelError('INVALID_PARAM')`,不静默吞掉。
1932
+ * - `load()`:seed 存在 → 直接用 seed;否则读文件(缺失落默认值)。
1933
+ * - `save()`:按格式序列化(TOML/JSON)原子写。
1934
+ */
1935
+ declare class ConfigBase<T> {
1936
+ readonly path: string;
1937
+ readonly defaults: T;
1938
+ private readonly schema;
1939
+ private readonly format;
1940
+ private readonly seed;
1941
+ private value;
1942
+ constructor(opts: ConfigOptions<T>);
1943
+ /** 当前内存值(只读消费;外部不得直接修改返回对象)。 */
1944
+ get(): T;
1945
+ /**
1946
+ * 加载配置:
1947
+ * - seed 存在 → 直接用 seed(已校验,不读文件;全局 TOML 分段装配方式);
1948
+ * - 文件缺失 → 写入默认值并落盘(首次运行自动生成),返回默认值;
1949
+ * - 文件存在 → 读取 + 校验,更新内存,返回。
1950
+ */
1951
+ load(): Promise<T>;
1952
+ /** 重新从磁盘加载(外部变更后的热更新入口,P2 配置热更新使用)。 */
1953
+ reload(): Promise<T>;
1954
+ /** 校验并落盘(原子写:临时文件 + rename),随后更新内存。 */
1955
+ save(next: T): Promise<void>;
1956
+ /** 对象 → 文本(TOML/JSON)。 */
1957
+ private serialize;
1958
+ /** 文本 → 对象(TOML/JSON)。 */
1959
+ private deserialize;
1960
+ /** 反序列化 + schema 校验,错误统一包装为 KernelError。 */
1961
+ private parse;
1962
+ }
1963
+ /** 解析 TOML 文本 → 对象(boot.cjs / 探测脚本等无 ConfigBase 场景复用)。 */
1964
+ declare function parseToml(text: string): Record<string, unknown>;
1965
+ /** 对象 → TOML 文本(config init 生成全局配置文件等场景)。 */
1966
+ declare function stringifyToml(value: Record<string, unknown>): string;
1967
+ //#endregion
1968
+ //#region src/infra/errors.d.ts
1969
+ /**
1970
+ * kernel 类型化错误(ADR-009 / ADR-017)
1971
+ *
1972
+ * apis 层内部解包原生 `{ result, errMsg }`:成功返回纯业务值,失败抛 KernelError。
1973
+ * 协议层只需维护 `KernelErrorCode → 协议错误码` 映射表,不解析错误逻辑。
1974
+ */
1975
+ /**
1976
+ * 错误码分类。P1 探测真实错误返回后再增删。
1977
+ * 当前 INVALID_PARAM 也承担基础设施层(配置校验失败等)的错误语义。
1978
+ */
1979
+ type KernelErrorCode = "SEND_FAILED" | "PERMISSION_DENIED" | "NOT_FOUND" | "TIMEOUT" | "NOT_LOGIN" | "INVALID_PARAM" | "INVALID_STATE" | "UNKNOWN";
1980
+ /**
1981
+ * 全部错误码集合。协议层映射表可据此推导:
1982
+ * `Record<(typeof KERNEL_ERROR_CODES)[number], number>`。
1983
+ */
1984
+ declare const KERNEL_ERROR_CODES: readonly ["SEND_FAILED", "PERMISSION_DENIED", "NOT_FOUND", "TIMEOUT", "NOT_LOGIN", "INVALID_PARAM", "INVALID_STATE", "UNKNOWN"];
1985
+ /** kernel 类型化错误:apis / 基础设施层抛出的统一错误形态。 */
1986
+ declare class KernelError extends Error {
1987
+ readonly code: KernelErrorCode;
1988
+ constructor(message: string, code?: KernelErrorCode, options?: ErrorOptions);
1989
+ }
1990
+ /** 便捷构造:`kernelError('消息不存在', 'NOT_FOUND', { cause })`。 */
1991
+ declare function kernelError(message: string, code?: KernelErrorCode, options?: ErrorOptions): KernelError;
1992
+ /** 类型守卫:协议层 catch 统一映射时区分 KernelError 与意外错误。 */
1993
+ declare function isKernelError(err: unknown): err is KernelError;
1994
+ //#endregion
1995
+ //#region src/login/login.d.ts
1996
+ /** 登录状态。 */
1997
+ type LoginState = "idle" | "waiting_scan" | "scanned" | "logged_in" | "failed";
1998
+ /** 二维码数据(png base64 + 解码 url)。 */
1999
+ interface QrCodeData {
2000
+ pngBase64: string;
2001
+ qrcodeUrl: string;
2002
+ }
2003
+ /** selfInfo(登录成功后填写)。 */
2004
+ interface SelfInfo {
2005
+ uin: string;
2006
+ uid: string;
2007
+ nick: string;
2008
+ }
2009
+ /** 快速登录项。 */
2010
+ interface LoginListItem {
2011
+ uin: string;
2012
+ uid?: string;
2013
+ nickName?: string;
2014
+ isQuickLogin?: boolean;
2015
+ }
2016
+ /** QR 登录会话(状态机 + 回调订阅)。 */
2017
+ declare class QrLoginSession {
2018
+ private readonly loginService;
2019
+ private state;
2020
+ private listenerId;
2021
+ private self;
2022
+ private readonly qrCodeHandlers;
2023
+ private readonly stateHandlers;
2024
+ constructor(loginService: unknown);
2025
+ /** 当前状态。 */
2026
+ get currentState(): LoginState;
2027
+ /** selfInfo(登录成功后有值)。 */
2028
+ get selfInfo(): SelfInfo | null;
2029
+ /** 订阅二维码(png base64 + url)。返回退订函数。 */
2030
+ onQrCode(cb: (qr: QrCodeData) => void): () => void;
2031
+ /** 订阅状态变化。返回退订函数。 */
2032
+ onStateChange(cb: (state: LoginState) => void): () => void;
2033
+ /** 开始登录:注册监听 → connect → 快速登录(指定账号)或触发二维码。 */
2034
+ start(opts?: {
2035
+ quickUin?: string;
2036
+ }): void;
2037
+ /** 刷新二维码(手动 / 过期自动)。 */
2038
+ refresh(): void;
2039
+ /** 构建登录监听(普通 JS 对象,NAPI 反射)。 */
2040
+ private buildListener;
2041
+ /** 停止:注销监听(登录成功后调用,防重复回调)。 */
2042
+ stop(): void;
2043
+ private setState;
2044
+ private emitQrCode;
2045
+ }
2046
+ //#endregion
2047
+ //#region src/types/services/profile-like-service.d.ts
2048
+ /**
2049
+ * NodeIKernelProfileLikeService:资料点赞服务接口面(自研描述,非移植)
2050
+ *
2051
+ * 依据:运行时反射 + wrapper 外部契约(接口签名是 QQ 的外部事实,自研描述其形状,
2052
+ * 零复制实现)。
2053
+ * (接口签名是外部系统的事实,我们自研描述其形状,零复制实现)。
2054
+ * 只收录 apis/profile-like 需要的方法;其余按需探测后补齐。
2055
+ */
2056
+ /** 点赞返回(setBuddyProfileLike,说明书参考)。 */
2057
+ interface BuddyProfileLikeResult {
2058
+ result: number;
2059
+ errMsg: string;
2060
+ succCounts: number;
2061
+ }
2062
+ /** 资料点赞服务。 */
2063
+ interface NodeIKernelProfileLikeService {
2064
+ addKernelProfileLikeListener(listener: unknown): number;
2065
+ removeKernelProfileLikeListener(listenerId: number): void;
2066
+ /** 点赞(send_like;sourceId=71 赞来源,doLikeCount 次数)。 */
2067
+ setBuddyProfileLike(arg: {
2068
+ friendUid: string;
2069
+ sourceId: number;
2070
+ doLikeCount: number;
2071
+ doLikeTollCount: number;
2072
+ }): Promise<BuddyProfileLikeResult>;
2073
+ isNull(): boolean;
2074
+ }
2075
+ //#endregion
2076
+ //#region src/types/services/profile-service.d.ts
2077
+ /** 用户详情(getUserDetailInfoByUin / getUserDetailInfo 返回,宽松自研描述,待探测校准)。 */
2078
+ interface UserDetailInfoByUin {
2079
+ detail?: {
2080
+ uid?: string;
2081
+ uin?: string;
2082
+ simpleInfo?: {
2083
+ coreInfo?: {
2084
+ nick?: string;
2085
+ remark?: string;
2086
+ };
2087
+ baseInfo?: {
2088
+ age?: number;
2089
+ qid?: string;
2090
+ sex?: number;
2091
+ longNick?: string;
2092
+ };
2093
+ vasInfo?: {
2094
+ svipFlag?: boolean;
2095
+ yearVipFlag?: boolean;
2096
+ vipLevel?: number;
2097
+ };
2098
+ status?: {
2099
+ status?: number;
2100
+ };
2101
+ relationFlags?: Record<string, unknown>;
2102
+ };
2103
+ commonExt?: {
2104
+ qqLevel?: number;
2105
+ regTime?: number;
2106
+ };
2107
+ };
2108
+ [key: string]: unknown;
2109
+ }
2110
+ /** 资料服务。 */
2111
+ interface NodeIKernelProfileService {
2112
+ addKernelProfileListener(listener: unknown): number;
2113
+ removeKernelProfileListener(listenerId: number): void;
2114
+ /** 设置个性签名(set_self_longnick)。 */
2115
+ setLongNick(longNick: string): Promise<unknown>;
2116
+ /** 设置昵称(set_qq_profile)。 */
2117
+ setNickName(nickName: string): Promise<unknown>;
2118
+ /** 设置头像(set_qq_avatar)。 */
2119
+ setHeader(filePath: string): Promise<GeneralCallResult>;
2120
+ /** 按 uin 获取用户详情(get_stranger_info 第一步)。 */
2121
+ getUserDetailInfoByUin(uin: string): Promise<UserDetailInfoByUin>;
2122
+ /** 按 uid 获取用户详情(get_stranger_info 第二步,noCache=true 强制刷新)。 */
2123
+ getUserDetailInfo(uid: string): Promise<UserDetailInfoByUin>;
2124
+ isNull(): boolean;
2125
+ }
2126
+ //#endregion
2127
+ //#region src/wrapper/probe.d.ts
2128
+ /**
2129
+ * 探测 wrapper 运行时:dump session 方法与各 service 方法到 JSON。
2130
+ * 返回探测结果对象;同时写文件(NAPUTO_CFG_DIR/<file>,默认 napuketto-probe.json)。
2131
+ */
2132
+ declare function probeRuntime(ctx: WrapperContext, file?: string): Record<string, unknown>;
2133
+ //#endregion
2134
+ //#region src/wrapper/qq-data-path.d.ts
2135
+ /**
2136
+ * QQ 数据根路径解析(P2-1,2026-08-06)
2137
+ *
2138
+ * 从 `getNTUserDataInfoConfig()` 的返回值中提取 QQ 真实数据根路径:
2139
+ * worker(utilityProcess)模式下 loginService 是 new 的,commonPath 必须指向
2140
+ * QQ 真实数据路径才能读到历史账号(cli 的 `.napuketto\default` 读不到,
2141
+ * getLoginList 空,P2-1 实测)。
2142
+ *
2143
+ * 返回值形态可能是 JSON 字符串(对象/数组)或纯路径字符串,此处做宽容解析。
2144
+ */
2145
+ /**
2146
+ * QQ 全局数据目录(commonPath / desktopGlobalPath = 数据根/nt_qq/global,
2147
+ * HANDOVER-V6 自建宿主三要素之三,p0-kernel-flow 实证)。
2148
+ *
2149
+ * 防御:已含 nt_qq/global 后缀(worker 环境下 getNTUserDataInfoConfig 可能
2150
+ * 返回完整路径)则不重复拼接,避免 `nt_qq/global/nt_qq/global` 错位。
2151
+ */
2152
+ declare function resolveQqGlobalPath(root: string): string;
2153
+ //#endregion
2154
+ //#region src/wrapper/session-resolver.d.ts
2155
+ /**
2156
+ * 复用 QQ 已有 session(P1-4:QQ 已登录,直接拿单例避免重复 init)。
2157
+ * 优先 `NodeIQQNTWrapperSession.get()`;返回 null 时回退 createSession。
2158
+ */
2159
+ declare function getExistingSession(ctx: WrapperContext): NodeIQQNTWrapperSession | null;
2160
+ /**
2161
+ * 复用 QQ 主 session(P1-4 实测链路):
2162
+ * `NodeIQQNTStartupSessionWrapper.create()` → `start()` → `getSessionIdList()`(Map
2163
+ * {nt:"nt_3", gpro:"gpro_3"})→ `NodeIQQNTWrapperSession.getNTWrapperSession("nt_3")`。
2164
+ * 注:实测这些 session 是空壳(核心 service null),真正可用的是 new + init(lifecycle.ts)。
2165
+ */
2166
+ declare function getMainSession(ctx: WrapperContext): NodeIQQNTWrapperSession | null;
2167
+ //#endregion
2168
+ //#region src/wrapper/wrapper-adapters.d.ts
2169
+ /** 会话监听器选项。 */
2170
+ interface SessionListenerOptions {
2171
+ /** 事件日志回调(默认静默——boot 阶段事件对用户是噪音;调试时可传回调观察)。 */
2172
+ onEvent?: (name: string, ...args: unknown[]) => void;
2173
+ }
2174
+ /**
2175
+ * 创建会话监听器(默认静默,boot 阶段默认;login 模块接入后可覆盖)。
2176
+ * 回调方法必须存在(NAPI 按方法名反射),但输出与否由调用方决定——
2177
+ * onNTSessionCreate / onOpentelemetryInit 等对用户无信息量,默认不打 stdout。
2178
+ */
2179
+ declare function createSessionListener(opts?: SessionListenerOptions): NodeIKernelSessionListener;
2180
+ /** 创建登录监听器(占位,登录器接入时填充)。 */
2181
+ declare function createLoginListener(): IKernelLoginListener;
2182
+ //#endregion
2183
+ //#region src/wrapper/wrapper-config.d.ts
2184
+ /**
2185
+ * 从 major.node 提取 appid(NapCat parseAppidFromMajorV2 的自研等价实现)。
2186
+ * major.node 含 `QQAppId/` 标记后跟数字(腾讯工具链产物,实测确认)。
2187
+ * 返回 null 表示解析失败(调用方回退硬编码表)。
2188
+ */
2189
+ declare function parseAppidFromMajor(majorPath: string): string | null;
2190
+ /**
2191
+ * 解析 appid / qua(自研,参考 NapCat QQBasicInfoWrapper 思路但独立实现):
2192
+ * 1. 优先从 major.node 提取 appid(实测 9.9.33-51802 = 537376818)
2193
+ * 2. 回退硬编码表(旧版 537237765)
2194
+ * majorPath 传 wrapper.node 同目录 major.node;不传则跳过 major 解析。
2195
+ */
2196
+ declare function resolveAppidQua(fullVersion: string, majorPath?: string): {
2197
+ appid: string;
2198
+ qua: string;
2199
+ };
2200
+ /** 生成 engine 桌面配置(wrapper 契约字段)。majorPath 可选(解析 appid/qua)。 */
2201
+ declare function buildEngineConfig(fullVersion: string, dataPathGlobal: string, majorPath?: string): EnginInitDesktopConfig;
2202
+ /** 生成登录初始化配置(externalVersion: false 与 NapCat 同款,扫码兼容关键)。 */
2203
+ declare function buildLoginConfig(appid: string, fullVersion: string, commonPath: string): Record<string, unknown>;
2204
+ /** buildSessionConfig 参数。 */
2205
+ interface SessionConfigOptions {
2206
+ appid: string;
2207
+ fullVersion: string;
2208
+ selfUin: string;
2209
+ selfUid: string;
2210
+ accountPath: string;
2211
+ downloadPath: string;
2212
+ }
2213
+ /** 生成 session 初始化配置(登录成功后调用)。 */
2214
+ declare function buildSessionConfig(options: SessionConfigOptions): WrapperSessionInitConfig;
2215
+ //#endregion
2216
+ //#region src/wrapper/wrapper-version.d.ts
2217
+ /**
2218
+ * QQ 安装目录探测(ADR-018)
2219
+ *
2220
+ * wrapper.node 路径随 QQ 版本变化:`<安装目录>/versions/<版本>/resources/app/wrapper.node`。
2221
+ * 加载前必须知道版本(登录握手参数 appid/qua 与版本强相关)。
2222
+ *
2223
+ * 已实测确认(2026-08-05,QQ 9.9.31-49919):
2224
+ * - 目录结构:versions/<9.9.31-49919>/resources/app/wrapper.node
2225
+ * - 版本信息在 versions/<版本>/resources/app/package.json(name=qq-chat / version / buildVersion)
2226
+ * - wrapper.node 是 C++ ABI 模块(非 N-API),导出 INTSessionShell 等符号
2227
+ */
2228
+ /** 解析 wrapper.node 绝对路径(按 ADR-018 目录约定)。 */
2229
+ declare function resolveWrapperPath(installDir: string, version: string): string;
2230
+ /**
2231
+ * 探测指定版本信息(校验 wrapper.node 存在)。
2232
+ * 版本号不匹配目录时抛 NOT_FOUND(明确失败而非静默)。
2233
+ */
2234
+ declare function resolveQQVersion(installDir: string, version: string): QQVersionInfo;
2235
+ /** 扫描 versions 目录,取可加载的版本列表(按目录名倒序,最新在前)。 */
2236
+ declare function listQQVersions(installDir: string): string[];
2237
+ /** QQ 版本信息。 */
2238
+ interface QQVersionInfo {
2239
+ /** 完整版本号,如 "9.9.31-49919"。 */
2240
+ fullVersion: string;
2241
+ /** 构建号,如 "49919"。 */
2242
+ buildVersion: string;
2243
+ /** wrapper.node 绝对路径。 */
2244
+ wrapperPath: string;
2245
+ /** 登录握手参数(P1 探测脚本产出,暂为空串)。 */
2246
+ appid: string;
2247
+ /** 登录握手参数(P1 探测脚本产出,暂为空串)。 */
2248
+ qua: string;
2249
+ }
2250
+ //#endregion
2251
+ export { type BootEnv, type BuddyCategory, type BuddyReq, type CanonicalElement, ChatType, ConfigBase, type ConfigFormat, type ConfigOptions, type ConfigSchema, type CoreContext, type CoreContextOptions, type CoreLoginOptions, DEFAULT_DATA_ROOT_NAME, type DesktopPathConfig, type DeviceInfo, type DoubtBuddyReq, type DoubtFriendRequestInfo, ElementType, type EnginInitDesktopConfig, type EssenceMsgItem, type ForceFetchClientKeyRetType, type Friend, FriendApi, type FriendCategory, type GeneralCallResult, type GetFileListParam, type GrayTipElement, type GrayTipRevokeElement, GrayTipSubType, type Group, GroupApi, GroupBridge, GroupCache, type GroupCacheOptions, type GroupDetailInfo, type GroupEventChannel, type GroupFileItemInfo, type GroupFolderInfo, type GroupHonorWebInfo, GroupListUpdateType, type GroupListener, type GroupMember, type GroupMemberDataSource, type GroupMemberListChange, type GroupNotify, GroupNotifyApi, GroupNotifyMsgStatus, GroupNotifyMsgType, type GroupSpaceInfo, type HonorListItem, KERNEL_ERROR_CODES, KernelError, type KernelErrorCode, type ListenerEvents, type LogLevel, type LoggerOptions, type LoginAccountInfo, type LoginListItem, type LoginResult, type LoginState, MAIN_CONFIG_FILE, MsgApi, MsgBridge, type MsgEventChannel, type MsgListener, NTEventChannel, NTGroupMemberRole, NTGroupRequestOperateTypes, NapukettoCore, type NapukettoCoreOptions, type NodeIDependsAdapter, type NodeIDispatcherAdapter, type NodeIGlobalAdapter, type NodeIKernelBuddyService, type NodeIKernelGroupService, type NodeIKernelLoginService, type NodeIKernelMsgService, type NodeIKernelProfileLikeService, type NodeIKernelProfileService, type NodeIKernelRichMediaService, type NodeIKernelSessionListener, type NodeIKernelTicketService, type NodeIQQNTStartupSessionWrapper, type NodeIQQNTWrapperEngine, type NodeIQQNTWrapperSession, type NodeQQNTWrapperUtil, type PathOptions, PathWrapper, type Peer, type PlatformType, ProfileApi, ProfileLikeApi, type QQVersionContext, type QQVersionInfo, type QrCodeData, QrLoginSession, type RDeliveryConfig, type RawElement, type RawMessage, RichMediaApi, type SelfInfo, type SendMessageElement, type SessionConfigOptions, type ShutUpGroupMember, type StartNapukettoOptions, type StrangerInfo, TicketApi, type TipAioOpGrayTipElement, type TipGroupElement, TipGroupElementType, type UserDetailInfoByUin, type VendorType, WebApi, WebHonorType, type WrapperContext, type WrapperNodeApi, type WrapperSessionInitConfig, buildEngineConfig, buildLoginConfig, buildSessionConfig, createCoreContext, createSessionListener as createLifecycleSessionListener, createSessionListener, createLogger, createLoginListener, createSession, createWrapper, electronProcessType, getExistingSession, getMainSession, initAndStartSession, initEngine, initSession, isKernelError, kernelError, listLoginAccounts, listQQVersions, parseAppidFromMajor, parseToml, probeRuntime, quickLogin, resolveAppidQua, resolveConfigPath, resolveDataRoot, resolveQQVersion, resolveQqGlobalPath, resolveQqUserDataRoot, resolveWrapperPath, startNapuketto, startSession, stringifyToml, toCanonicalElements, toSendElements, waitForNetworkConnection, waitSessionReady };
2252
+ //# sourceMappingURL=index.d.mts.map