@zhin.js/adapter-icqq 8.0.3 → 8.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-icqq",
3
- "version": "8.0.3",
3
+ "version": "8.0.6",
4
4
  "description": "Zhin.js ICQQ adapter for Plugin Runtime (IPC daemon client)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -34,20 +34,20 @@
34
34
  "directory": "plugins/adapters/icqq"
35
35
  },
36
36
  "dependencies": {
37
- "@zhin.js/adapter": "1.1.5",
38
- "@zhin.js/command": "1.0.7",
39
- "@zhin.js/core": "1.5.2",
40
- "@zhin.js/im-contract": "1.0.1",
41
- "@zhin.js/logger": "1.0.75",
42
- "@zhin.js/plugin-runtime": "1.1.3"
37
+ "@zhin.js/adapter": "1.1.7",
38
+ "@zhin.js/command": "1.0.10",
39
+ "@zhin.js/core": "1.5.5",
40
+ "@zhin.js/im-contract": "1.0.3",
41
+ "@zhin.js/logger": "1.0.76",
42
+ "@zhin.js/plugin-runtime": "1.1.5"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "zod": "^4.0.0",
46
- "@zhin.js/adapter": "1.1.5",
47
- "@zhin.js/agent": "1.1.3",
48
- "@zhin.js/core": "1.5.2",
49
- "@zhin.js/plugin-runtime": "1.1.3",
50
- "zhin.js": "6.0.2"
46
+ "@zhin.js/adapter": "1.1.7",
47
+ "@zhin.js/agent": "1.1.6",
48
+ "@zhin.js/core": "1.5.5",
49
+ "@zhin.js/plugin-runtime": "1.1.5",
50
+ "zhin.js": "6.0.5"
51
51
  },
52
52
  "peerDependenciesMeta": {
53
53
  "zhin.js": {
@@ -65,8 +65,8 @@
65
65
  "typescript": "^6.0.3",
66
66
  "vitest": "^4.1.10",
67
67
  "zod": "^4.4.3",
68
- "@zhin.js/agent": "1.1.3",
69
- "zhin.js": "6.0.2"
68
+ "@zhin.js/agent": "1.1.6",
69
+ "zhin.js": "6.0.5"
70
70
  },
71
71
  "files": [
72
72
  "adapters",
package/schema.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "string",
9
9
  "number"
10
10
  ],
11
- "description": "Endpoint Owner QQ uin (for /approve bash and master role)"
11
+ "description": "框架 master QQ uin(/approve、AI/工具权限);endpoints[i].master 可逐项覆盖"
12
12
  },
13
13
  "trusted": {
14
14
  "type": "array",
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "description": "Trusted QQ uin"
21
21
  },
22
- "description": "Trusted QQ uin list"
22
+ "description": "框架 trusted QQ uin 列表(弱于 master)"
23
23
  },
24
24
  "autoReconnect": {
25
25
  "type": "boolean",
@@ -35,21 +35,17 @@
35
35
  },
36
36
  "endpoints": {
37
37
  "type": "array",
38
- "description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(name 必填,其余覆盖顶层)",
38
+ "description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(id 必填,其余覆盖顶层)",
39
39
  "items": {
40
40
  "type": "object",
41
41
  "additionalProperties": true,
42
42
  "properties": {
43
- "name": {
44
- "type": "string",
45
- "description": "QQ uin (must match icqq login account)"
46
- },
47
43
  "master": {
48
44
  "type": [
49
45
  "string",
50
46
  "number"
51
47
  ],
52
- "description": "Endpoint Owner QQ uin (for /approve bash and master role)"
48
+ "description": "本 endpoint 的框架 master QQ uin;覆盖顶层 master"
53
49
  },
54
50
  "trusted": {
55
51
  "type": "array",
@@ -60,7 +56,7 @@
60
56
  ],
61
57
  "description": "Trusted QQ uin"
62
58
  },
63
- "description": "Trusted QQ uin list"
59
+ "description": "本 endpoint 的 trusted 列表"
64
60
  },
65
61
  "rpc": {
66
62
  "type": "object",
@@ -84,10 +80,14 @@
84
80
  "port",
85
81
  "token"
86
82
  ]
83
+ },
84
+ "id": {
85
+ "type": "string",
86
+ "description": "QQ uin (must match icqq login account)"
87
87
  }
88
88
  },
89
89
  "required": [
90
- "name"
90
+ "id"
91
91
  ]
92
92
  }
93
93
  },
@@ -101,4 +101,4 @@
101
101
  "master",
102
102
  "endpoints"
103
103
  ]
104
- }
104
+ }
package/src/endpoint.ts CHANGED
@@ -8,7 +8,7 @@ import type {
8
8
  EndpointSendRequest,
9
9
  } from '@zhin.js/adapter';
10
10
  import type { MessageGateway } from '@zhin.js/core/runtime';
11
- import { formatCompact, getLogger } from '@zhin.js/logger';
11
+ import { formatCompact, getAdapterLogger, truncatePreview } from '@zhin.js/logger';
12
12
  import type { CapabilityId } from '@zhin.js/plugin-runtime';
13
13
  import { registerIcqqAgentEndpoint } from './icqq-agent-deps.js';
14
14
  import {
@@ -53,8 +53,6 @@ import {
53
53
  } from './protocol.js';
54
54
  import type { IpcFriendInfo, IpcGroupInfo, IpcMemberInfo, IpcSystemMessage } from './types.js';
55
55
 
56
- const logger = getLogger('icqq');
57
-
58
56
  /** Minimal IPC surface used by the endpoint (real IpcClient or test mock). */
59
57
  export interface IcqqIpcTransport {
60
58
  request(action: string, params?: Record<string, unknown>): Promise<IpcResponse>;
@@ -89,6 +87,8 @@ export interface IcqqEndpointOptions {
89
87
  }
90
88
 
91
89
  export class IcqqIpcEndpoint implements EndpointInstance {
90
+ readonly #logger!: ReturnType<typeof getAdapterLogger>;
91
+
92
92
  readonly #options: IcqqEndpointOptions;
93
93
  readonly #createIpc: CreateIcqqIpc;
94
94
  readonly name: string;
@@ -131,8 +131,9 @@ export class IcqqIpcEndpoint implements EndpointInstance {
131
131
  #reconnectRunning = false;
132
132
 
133
133
  constructor(options: IcqqEndpointOptions) {
134
+ this.#logger = getAdapterLogger('icqq', options.config.id);
134
135
  this.#options = options;
135
- this.name = options.config.name;
136
+ this.name = options.config.id;
136
137
  this.#createIpc = options.createIpc ?? defaultCreateIpc;
137
138
  }
138
139
 
@@ -150,18 +151,14 @@ export class IcqqIpcEndpoint implements EndpointInstance {
150
151
  try {
151
152
  await this.#bindIpcSession();
152
153
  this.#unregisterAgent = registerIcqqAgentEndpoint(this.name, this);
153
- logger.info(formatCompact({
154
- op: 'connect',
155
- endpoint: this.name,
156
- mode: this.#options.config.rpc ? 'rpc' : 'ipc',
157
- friends: this.friends.size,
158
- groups: this.groups.size,
159
- }));
154
+ this.#logger.info(
155
+ `connected (${this.#options.config.rpc ? 'rpc' : 'ipc'}) | friends: ${this.friends.size} | groups: ${this.groups.size}`,
156
+ );
160
157
  } catch (error) {
161
158
  await this.stop();
162
159
  // Startup connect failures are surfaced once (with stack) by AdapterIndex;
163
160
  // keep this at debug to avoid a duplicate error-level log.
164
- logger.debug(`Failed to connect ICQQ IPC: ${error instanceof Error ? error.stack ?? error.message : String(error)}`);
161
+ this.#logger.debug(`Failed to connect ICQQ IPC: ${error instanceof Error ? error.stack ?? error.message : String(error)}`);
165
162
  throw error;
166
163
  }
167
164
  }
@@ -200,10 +197,9 @@ export class IcqqIpcEndpoint implements EndpointInstance {
200
197
  const jitter = Math.floor(Math.random() * 400);
201
198
  const delayMs = base + jitter;
202
199
  // 首次断开 WARN,后续重试静默为 DEBUG,避免刷屏
203
- const disconnectLog = attempt === 0 ? logger.warn.bind(logger) : logger.debug.bind(logger);
200
+ const disconnectLog = attempt === 0 ? this.#logger.warn.bind(this.#logger) : this.#logger.debug.bind(this.#logger);
204
201
  disconnectLog(formatCompact({
205
202
  op: 'disconnect',
206
- endpoint: this.name,
207
203
  ok: false,
208
204
  delay_ms: delayMs,
209
205
  attempt: attempt + 1,
@@ -212,17 +208,13 @@ export class IcqqIpcEndpoint implements EndpointInstance {
212
208
  if (this.#intentionalDisconnect) break;
213
209
  try {
214
210
  await this.#bindIpcSession();
215
- logger.info(formatCompact({
216
- op: 'reconnect',
217
- endpoint: this.name,
218
- ok: true,
219
- attempts: attempt + 1,
220
- friends: this.friends.size,
221
- groups: this.groups.size,
222
- }));
211
+ this.#logger.info(
212
+ `reconnected after ${attempt + 1} attempt(s)`
213
+ + ` | friends: ${this.friends.size} | groups: ${this.groups.size}`,
214
+ );
223
215
  break;
224
216
  } catch (error) {
225
- const retryLog = attempt === 0 ? logger.warn.bind(logger) : logger.debug.bind(logger);
217
+ const retryLog = attempt === 0 ? this.#logger.warn.bind(this.#logger) : this.#logger.debug.bind(this.#logger);
226
218
  retryLog(formatCompact({
227
219
  op: 'reconnect',
228
220
  endpoint: this.name,
@@ -267,7 +259,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
267
259
  // 置空 ipc:start 前 / stop 后的 request() 走防御性报错而非 TypeError
268
260
  this.ipc = undefined as unknown as IcqqIpcTransport;
269
261
  this.#started = false;
270
- logger.debug(formatCompact({ op: 'disconnect', endpoint: this.name }));
262
+ this.#logger.debug(formatCompact({ op: 'disconnect' }));
271
263
  }
272
264
 
273
265
  async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
@@ -310,17 +302,17 @@ export class IcqqIpcEndpoint implements EndpointInstance {
310
302
  }
311
303
  const resp = await this.ipc.request(action, params);
312
304
  if (!resp.ok) {
305
+ this.#logger.warn(
306
+ `send failed ${conversation.kind}:${conversation.id} | ${resp.error} | ${truncatePreview(typeof message === 'string' ? message : String(message), 80)}`,
307
+ );
313
308
  throw new Error(`发送消息失败: ${resp.error}`);
314
309
  }
315
310
  const messageId = String(
316
311
  (resp.data as { message_id?: unknown } | undefined)?.message_id ?? `sent_${Date.now()}`,
317
312
  );
318
- logger.debug(formatCompact({
319
- op: 'icqq_send',
320
- endpoint: this.name,
321
- target: `${conversation.kind}:${conversation.id}`,
322
- messageId,
323
- }));
313
+ this.#logger.info(
314
+ `send ${conversation.kind}:${conversation.id} | id: ${messageId} | ${truncatePreview(typeof message === 'string' ? message : String(message), 80)}`,
315
+ );
324
316
  return messageId;
325
317
  }
326
318
 
@@ -353,7 +345,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
353
345
  id: emojiId,
354
346
  });
355
347
  if (!resp.ok) {
356
- logger.warn(formatCompact({
348
+ this.#logger.warn(formatCompact({
357
349
  op: 'add_reaction',
358
350
  endpoint: this.name,
359
351
  message_id: messageId,
@@ -364,7 +356,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
364
356
  }));
365
357
  return null;
366
358
  }
367
- logger.debug(formatCompact({
359
+ this.#logger.debug(formatCompact({
368
360
  op: 'add_reaction',
369
361
  endpoint: this.name,
370
362
  message_id: messageId,
@@ -374,7 +366,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
374
366
  }));
375
367
  return emojiId;
376
368
  } catch (error) {
377
- logger.warn(formatCompact({
369
+ this.#logger.warn(formatCompact({
378
370
  op: 'add_reaction',
379
371
  endpoint: this.name,
380
372
  message_id: messageId,
@@ -395,7 +387,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
395
387
  id: emojiId,
396
388
  });
397
389
  if (!resp.ok) {
398
- logger.warn(formatCompact({
390
+ this.#logger.warn(formatCompact({
399
391
  op: 'remove_reaction',
400
392
  endpoint: this.name,
401
393
  message_id: messageId,
@@ -406,7 +398,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
406
398
  }));
407
399
  return;
408
400
  }
409
- logger.debug(formatCompact({
401
+ this.#logger.debug(formatCompact({
410
402
  op: 'remove_reaction',
411
403
  endpoint: this.name,
412
404
  message_id: messageId,
@@ -415,7 +407,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
415
407
  ok: true,
416
408
  }));
417
409
  } catch (error) {
418
- logger.warn(formatCompact({
410
+ this.#logger.warn(formatCompact({
419
411
  op: 'remove_reaction',
420
412
  endpoint: this.name,
421
413
  message_id: messageId,
@@ -432,7 +424,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
432
424
  try {
433
425
  const resp = await this.request(Actions.RECALL_MSG, { message_id: messageId });
434
426
  if (!resp.ok) {
435
- logger.warn(formatCompact({
427
+ this.#logger.warn(formatCompact({
436
428
  op: 'recall_message',
437
429
  endpoint: this.name,
438
430
  message_id: messageId,
@@ -441,14 +433,14 @@ export class IcqqIpcEndpoint implements EndpointInstance {
441
433
  }));
442
434
  return;
443
435
  }
444
- logger.debug(formatCompact({
436
+ this.#logger.debug(formatCompact({
445
437
  op: 'recall_message',
446
438
  endpoint: this.name,
447
439
  message_id: messageId,
448
440
  ok: true,
449
441
  }));
450
442
  } catch (error) {
451
- logger.warn(formatCompact({
443
+ this.#logger.warn(formatCompact({
452
444
  op: 'recall_message',
453
445
  endpoint: this.name,
454
446
  message_id: messageId,
@@ -637,7 +629,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
637
629
  admit(msg: IcqqInboundMessage): void {
638
630
  const conversation = msg.conversation;
639
631
  if (!this.#open) {
640
- logger.debug(formatCompact({
632
+ this.#logger.debug(formatCompact({
641
633
  op: 'icqq_inbound_skip',
642
634
  reason: 'endpoint_closed',
643
635
  endpoint: this.name,
@@ -652,33 +644,33 @@ export class IcqqIpcEndpoint implements EndpointInstance {
652
644
  content: msg.segments,
653
645
  rawMessage: msg.content,
654
646
  });
655
- logger.debug(formatCompact({
656
- op: 'icqq_inbound_admit',
657
- endpoint: this.name,
658
- id: msg.id,
659
- target: `${conversation.kind}:${conversation.id}`,
660
- sender: msg.sender,
661
- channelType: msg.channelType,
662
- mentioned: mentioned || undefined,
663
- preview: msg.content.slice(0, 80),
664
- segments: summarizeSegmentTypes(msg.segments),
665
- }));
647
+ this.#logger.info(
648
+ `recv ${conversation.kind}:${conversation.id}`
649
+ + (msg.sender ? ` from ${msg.sender.name ?? msg.sender.id}` : '')
650
+ + (mentioned ? ' (mentioned)' : '')
651
+ + ` | ${truncatePreview(msg.content, 80)}`,
652
+ );
653
+ const quoteId = msg.metadata?.quote_id;
654
+ const { quote_id: _dropQuoteId, ...restMetadata } = msg.metadata ?? {};
666
655
  void this.#options.gateway.receive({
667
656
  conversation,
668
657
  message: { conversation, id: msg.id },
669
658
  content: msg.content,
670
659
  ...(msg.segments ? { segments: msg.segments } : {}),
671
660
  sender: msg.sender,
661
+ endpointId: this.name,
662
+ ...(mentioned ? { mentioned: true } : {}),
663
+ ...(quoteId ? { replyTo: { id: String(quoteId) } } : {}),
672
664
  metadata: Object.freeze({
673
- endpoint: this.name,
674
665
  channelType: msg.channelType,
675
- ...msg.metadata,
676
- ...(mentioned ? { mentioned: true } : {}),
666
+ ...restMetadata,
677
667
  }),
678
668
  }).catch((err) => {
679
- logger.warn(formatCompact({
680
- op: 'icqq_gateway_receive_failed',
669
+ this.#logger.warn(formatCompact({
670
+ op: 'recv',
671
+ endpoint: this.name,
681
672
  target: `${conversation.kind}:${conversation.id}`,
673
+ ok: false,
682
674
  error: err instanceof Error ? err.message : String(err),
683
675
  }));
684
676
  });
@@ -721,7 +713,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
721
713
  if (!isIcqqMessagePostType(payload)) return;
722
714
  const data = payload as IcqqIpcMessageEvent;
723
715
  if (shouldSkipSelfInboundMessage(data)) {
724
- logger.debug(formatCompact({
716
+ this.#logger.debug(formatCompact({
725
717
  op: 'icqq_inbound_skip',
726
718
  reason: 'self',
727
719
  endpoint: this.name,
@@ -732,7 +724,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
732
724
  }
733
725
  const normalized = normalizeIcqqInboundMessage(data);
734
726
  if (!normalized) {
735
- logger.debug(formatCompact({
727
+ this.#logger.debug(formatCompact({
736
728
  op: 'icqq_inbound_skip',
737
729
  reason: 'normalize_failed',
738
730
  endpoint: this.name,
@@ -742,7 +734,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
742
734
  return;
743
735
  }
744
736
  if (!this.#inboundDeduper.shouldProcess(normalized.messageId)) {
745
- logger.debug(formatCompact({
737
+ this.#logger.debug(formatCompact({
746
738
  op: 'icqq_inbound_skip',
747
739
  reason: 'dedupe',
748
740
  endpoint: this.name,
@@ -759,7 +751,11 @@ export class IcqqIpcEndpoint implements EndpointInstance {
759
751
  }),
760
752
  content: formatInboundContent(normalized.rawMessage),
761
753
  segments: normalized.content,
762
- sender: normalized.userId,
754
+ sender: {
755
+ id: normalized.userId,
756
+ name: normalized.nickname || undefined,
757
+ ...(normalized.senderRole ? { roles: [normalized.senderRole] } : {}),
758
+ },
763
759
  channelType: normalized.channelType,
764
760
  metadata: buildIcqqQuoteMetadata(data, {
765
761
  nickname: normalized.nickname,
@@ -775,7 +771,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
775
771
  payload as Parameters<typeof normalizeIcqqGuildInboundMessage>[0],
776
772
  );
777
773
  if (!normalized) {
778
- logger.debug(formatCompact({
774
+ this.#logger.debug(formatCompact({
779
775
  op: 'icqq_inbound_skip',
780
776
  reason: 'guild_normalize_failed',
781
777
  endpoint: this.name,
@@ -784,7 +780,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
784
780
  }
785
781
  this.#guildCatalog.upsertFromInbound(normalized.raw);
786
782
  if (!this.#inboundDeduper.shouldProcess(`guild:${normalized.messageId}`)) {
787
- logger.debug(formatCompact({
783
+ this.#logger.debug(formatCompact({
788
784
  op: 'icqq_inbound_skip',
789
785
  reason: 'dedupe',
790
786
  endpoint: this.name,
@@ -801,7 +797,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
801
797
  }),
802
798
  content: formatInboundContent(normalized.rawMessage),
803
799
  segments: normalized.content,
804
- sender: normalized.userId,
800
+ sender: { id: normalized.userId, name: normalized.nickname || undefined },
805
801
  channelType: 'channel',
806
802
  metadata: {
807
803
  guildId: normalized.guildId,
@@ -811,9 +807,9 @@ export class IcqqIpcEndpoint implements EndpointInstance {
811
807
  }
812
808
 
813
809
  /** 收件箱行公共前缀:adapter 槽 localName + endpoint live 名(uin)。 */
814
- #inboxBase(): { adapter: string; endpointId: string } {
810
+ #inboxBase(): { adapter: string; endpointKey: string } {
815
811
  const id = String(this.#options.id);
816
- return { adapter: id.split('\0').pop() ?? id, endpointId: this.name };
812
+ return { adapter: id.split('\0').pop() ?? id, endpointKey: this.name };
817
813
  }
818
814
 
819
815
  #recordInboxRequest(payload: Record<string, unknown>): void {
@@ -864,7 +860,7 @@ export class IcqqIpcEndpoint implements EndpointInstance {
864
860
  hooks.publish?.('endpoint:request', row);
865
861
  }
866
862
  } catch (error) {
867
- logger.debug(formatCompact({
863
+ this.#logger.debug(formatCompact({
868
864
  op: 'inbox_pull_system_msg',
869
865
  endpoint: this.name,
870
866
  error: error instanceof Error ? error.message : String(error),
@@ -913,23 +909,8 @@ function toNumericId(value: number | string, label: string): number {
913
909
  return n;
914
910
  }
915
911
 
916
- function summarizeSegmentTypes(
917
- segments: readonly { readonly type?: unknown }[] | undefined,
918
- ): string | undefined {
919
- if (!segments?.length) return undefined;
920
- return segments
921
- .map((segment) => {
922
- if (typeof segment.type === 'string') return segment.type;
923
- if (segment.type && typeof segment.type === 'object' && 'name' in segment.type) {
924
- return String((segment.type as { name: unknown }).name);
925
- }
926
- return '?';
927
- })
928
- .join(',');
929
- }
930
-
931
912
  async function defaultCreateIpc(config: ResolvedIcqqConfig): Promise<IcqqIpcTransport> {
932
- const uin = Number(config.name);
913
+ const uin = Number(config.id);
933
914
  if (config.rpc) {
934
915
  return IpcClient.connectRpc(config.rpc);
935
916
  }
@@ -18,7 +18,7 @@ export interface IcqqAgentEndpoint {
18
18
  }
19
19
 
20
20
  export interface IcqqAgentDeps {
21
- getEndpoint: (endpointId: string) => IcqqAgentEndpoint;
21
+ getEndpoint: (endpointKey: string) => IcqqAgentEndpoint;
22
22
  getAdapter?: () => { getEndpoint: (id: string) => IcqqAgentEndpoint };
23
23
  }
24
24
 
@@ -26,13 +26,13 @@ const endpoints = new Map<string, IcqqAgentEndpoint>();
26
26
  let override: IcqqAgentDeps | null = null;
27
27
 
28
28
  export function registerIcqqAgentEndpoint(
29
- endpointId: string,
29
+ endpointKey: string,
30
30
  endpoint: IcqqAgentEndpoint,
31
31
  ): () => void {
32
- endpoints.set(endpointId, endpoint);
32
+ endpoints.set(endpointKey, endpoint);
33
33
  return () => {
34
- if (endpoints.get(endpointId) === endpoint) {
35
- endpoints.delete(endpointId);
34
+ if (endpoints.get(endpointKey) === endpoint) {
35
+ endpoints.delete(endpointKey);
36
36
  }
37
37
  };
38
38
  }
@@ -42,9 +42,9 @@ export function setIcqqAgentDeps(deps: IcqqAgentDeps | null): void {
42
42
  override = deps;
43
43
  }
44
44
 
45
- function lookup(endpointId: string): IcqqAgentEndpoint {
46
- const registered = endpoints.get(endpointId);
47
- if (!registered) throw new Error(`Endpoint ${endpointId} 不存在`);
45
+ function lookup(endpointKey: string): IcqqAgentEndpoint {
46
+ const registered = endpoints.get(endpointKey);
47
+ if (!registered) throw new Error(`Endpoint ${endpointKey} 不存在`);
48
48
  return registered;
49
49
  }
50
50
 
@@ -4,7 +4,7 @@
4
4
  * ICQQ 的凭据由外部守护进程(@icqqjs/cli)按账号持有(~/.icqq/<uin>/),
5
5
  * 其 IPC/RPC 协议是「按 uin 连接 + auth + 账号级 action」,没有 add-account /
6
6
  * 触发 login 的 action——扫码登录只能经 `icqq login <uin>` CLI 完成。
7
- * 因此 add 不走 kv 凭据录入,而是 bindFlow:校验 uin、把 { name: '<uin>' }
7
+ * 因此 add 不走 kv 凭据录入,而是 bindFlow:校验 uin、把 { id: '<uin>' }
8
8
  * 追加到 plugins.icqq.endpoints,并引导用户先完成守护进程登录。
9
9
  */
10
10
  import { addEndpointToConfig, createEndpointCommands } from '@zhin.js/adapter';
@@ -17,18 +17,18 @@ export const icqqEndpointCommands = createEndpointCommands({
17
17
  running: (use) => use(icqqRuntimeStateToken).endpoints.values(),
18
18
  describeEntry: (entry) => (entry.rpc ? 'rpc(远程守护进程)' : 'ipc(本地守护进程)'),
19
19
  addDescription: '登记 ICQQ endpoint(uin 需先经 icqq login 完成扫码登录;重启 zhin 生效)',
20
- bindFlow: ({ name }) => {
21
- if (!name) {
20
+ bindFlow: ({ id }) => {
21
+ if (!id) {
22
22
  return '用法:icqq.endpoint add <uin>(uin 为纯数字 QQ 号,且需先执行 icqq login <uin> 完成扫码登录)';
23
23
  }
24
- if (!/^\d+$/.test(name)) {
24
+ if (!/^\d+$/.test(id)) {
25
25
  return 'icqq endpoint 名必须是纯数字 QQ 号(uin)';
26
26
  }
27
27
  try {
28
- const filePath = addEndpointToConfig('icqq', { name });
28
+ const filePath = addEndpointToConfig('icqq', { id });
29
29
  return (
30
- `✅ endpoint「${name}」已追加到 ${filePath} 的 plugins.icqq.endpoints。\n` +
31
- `⚠️ 请确保已执行 icqq login ${name} 启动守护进程并完成扫码登录;重启 zhin 后生效。`
30
+ `✅ endpoint「${id}」已追加到 ${filePath} 的 plugins.icqq.endpoints。\n` +
31
+ `⚠️ 请确保已执行 icqq login ${id} 启动守护进程并完成扫码登录;重启 zhin 后生效。`
32
32
  );
33
33
  } catch (error) {
34
34
  return `添加失败:${error instanceof Error ? error.message : String(error)}`;
package/src/icqq-inbox.ts CHANGED
@@ -11,7 +11,7 @@ import type { IpcSystemMessage } from './types.js';
11
11
  /** 行级公共前缀:adapter 槽 localName + endpoint live 名(uin)。 */
12
12
  export interface IcqqInboxBase {
13
13
  readonly adapter: string;
14
- readonly endpointId: string;
14
+ readonly endpointKey: string;
15
15
  }
16
16
 
17
17
  /** post_type=request / request.* 判定(OneBot 事件壳)。 */
@@ -46,7 +46,7 @@ export function buildIcqqInboxRequestRow(
46
46
  const isGroup = requestType === 'group' || groupId != null;
47
47
  return {
48
48
  adapter: base.adapter,
49
- endpoint_id: base.endpointId,
49
+ endpoint_id: base.endpointKey,
50
50
  platform_request_id: platformRequestId,
51
51
  type: isGroup ? 'group' : (requestType ?? 'friend'),
52
52
  scene_type: isGroup ? 'group' : null,
@@ -85,7 +85,7 @@ export function buildIcqqInboxNoticeRow(
85
85
  const targetId = userId != null && String(userId) !== String(actorId ?? '') ? userId : undefined;
86
86
  return {
87
87
  adapter: base.adapter,
88
- endpoint_id: base.endpointId,
88
+ endpoint_id: base.endpointKey,
89
89
  platform_notice_id: platformNoticeId,
90
90
  type: noticeType,
91
91
  scene_type: groupId != null ? 'group' : null,
@@ -117,7 +117,7 @@ export function buildIcqqSystemRequestRow(
117
117
  if (!platformRequestId) return null;
118
118
  return {
119
119
  adapter: base.adapter,
120
- endpoint_id: base.endpointId,
120
+ endpoint_id: base.endpointKey,
121
121
  platform_request_id: platformRequestId,
122
122
  type: kind,
123
123
  scene_type: kind === 'group' ? 'group' : null,