@zhin.js/adapter-icqq 6.0.1 → 6.0.3

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.
Files changed (125) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +32 -437
  3. package/adapters/icqq.ts +30 -0
  4. package/agent/tools/announce.ts +21 -0
  5. package/agent/tools/essence.ts +22 -0
  6. package/agent/tools/friend_list.ts +19 -0
  7. package/agent/tools/group_files.ts +27 -0
  8. package/agent/tools/group_invite.ts +20 -0
  9. package/agent/tools/group_list.ts +20 -0
  10. package/agent/tools/group_sign.ts +19 -0
  11. package/agent/tools/list_muted.ts +22 -0
  12. package/agent/tools/poke.ts +20 -0
  13. package/agent/tools/send_user_like.ts +22 -0
  14. package/agent/tools/set_anonymous.ts +22 -0
  15. package/agent/tools/set_title.ts +25 -0
  16. package/lib/agent-prompt.d.ts +0 -1
  17. package/lib/agent-prompt.js +0 -1
  18. package/lib/cq-message.d.ts +0 -1
  19. package/lib/cq-message.js +0 -1
  20. package/lib/endpoint.d.ts +45 -97
  21. package/lib/endpoint.js +357 -628
  22. package/lib/forward-msg.d.ts +1 -2
  23. package/lib/forward-msg.js +4 -2
  24. package/lib/icqq-agent-deps.d.ts +25 -0
  25. package/lib/icqq-agent-deps.js +32 -0
  26. package/lib/icqq-guild.d.ts +1 -2
  27. package/lib/icqq-guild.js +4 -2
  28. package/lib/icqq-inbound.d.ts +10 -1
  29. package/lib/icqq-inbound.js +27 -3
  30. package/lib/index.d.ts +6 -18
  31. package/lib/index.js +6 -50
  32. package/lib/ipc-client.d.ts +0 -1
  33. package/lib/ipc-client.js +0 -1
  34. package/lib/outbound-media.d.ts +0 -1
  35. package/lib/outbound-media.js +0 -1
  36. package/lib/protocol.d.ts +73 -2
  37. package/lib/protocol.js +124 -2
  38. package/lib/types.d.ts +0 -1
  39. package/lib/types.js +0 -1
  40. package/package.json +51 -43
  41. package/plugin.ts +32 -0
  42. package/schema.json +35 -0
  43. package/src/agent-prompt.ts +1 -2
  44. package/src/endpoint.ts +399 -800
  45. package/src/forward-msg.ts +2 -2
  46. package/src/icqq-agent-deps.ts +57 -0
  47. package/src/icqq-guild.ts +1 -2
  48. package/src/icqq-inbound.ts +31 -2
  49. package/src/index.ts +35 -69
  50. package/src/protocol.ts +191 -1
  51. package/client/ICQQManagement.tsx +0 -147
  52. package/client/LoginAssistPanel.tsx +0 -300
  53. package/client/index.tsx +0 -11
  54. package/client/tsconfig.json +0 -7
  55. package/client/utils/api.ts +0 -30
  56. package/dist/index.js +0 -34
  57. package/lib/adapter.d.ts +0 -46
  58. package/lib/adapter.d.ts.map +0 -1
  59. package/lib/adapter.js +0 -128
  60. package/lib/adapter.js.map +0 -1
  61. package/lib/agent-prompt.d.ts.map +0 -1
  62. package/lib/agent-prompt.js.map +0 -1
  63. package/lib/cq-message.d.ts.map +0 -1
  64. package/lib/cq-message.js.map +0 -1
  65. package/lib/endpoint.d.ts.map +0 -1
  66. package/lib/endpoint.js.map +0 -1
  67. package/lib/forward-msg.d.ts.map +0 -1
  68. package/lib/forward-msg.js.map +0 -1
  69. package/lib/get-msg.d.ts +0 -3
  70. package/lib/get-msg.d.ts.map +0 -1
  71. package/lib/get-msg.js +0 -46
  72. package/lib/get-msg.js.map +0 -1
  73. package/lib/icqq-guild.d.ts.map +0 -1
  74. package/lib/icqq-guild.js.map +0 -1
  75. package/lib/icqq-inbound.d.ts.map +0 -1
  76. package/lib/icqq-inbound.js.map +0 -1
  77. package/lib/icqq-login-assist-bridge.d.ts +0 -5
  78. package/lib/icqq-login-assist-bridge.d.ts.map +0 -1
  79. package/lib/icqq-login-assist-bridge.js +0 -148
  80. package/lib/icqq-login-assist-bridge.js.map +0 -1
  81. package/lib/icqq-side-events.d.ts +0 -34
  82. package/lib/icqq-side-events.d.ts.map +0 -1
  83. package/lib/icqq-side-events.js +0 -194
  84. package/lib/icqq-side-events.js.map +0 -1
  85. package/lib/index.d.ts.map +0 -1
  86. package/lib/index.js.map +0 -1
  87. package/lib/ipc-client.d.ts.map +0 -1
  88. package/lib/ipc-client.js.map +0 -1
  89. package/lib/login-assist-routes.d.ts +0 -7
  90. package/lib/login-assist-routes.d.ts.map +0 -1
  91. package/lib/login-assist-routes.js +0 -29
  92. package/lib/login-assist-routes.js.map +0 -1
  93. package/lib/login-ipc-contract.d.ts +0 -44
  94. package/lib/login-ipc-contract.d.ts.map +0 -1
  95. package/lib/login-ipc-contract.js +0 -35
  96. package/lib/login-ipc-contract.js.map +0 -1
  97. package/lib/outbound-media.d.ts.map +0 -1
  98. package/lib/outbound-media.js.map +0 -1
  99. package/lib/protocol.d.ts.map +0 -1
  100. package/lib/protocol.js.map +0 -1
  101. package/lib/routes.d.ts +0 -8
  102. package/lib/routes.d.ts.map +0 -1
  103. package/lib/routes.js +0 -67
  104. package/lib/routes.js.map +0 -1
  105. package/lib/segment-mapper.d.ts +0 -2
  106. package/lib/segment-mapper.d.ts.map +0 -1
  107. package/lib/segment-mapper.js +0 -2
  108. package/lib/segment-mapper.js.map +0 -1
  109. package/lib/tools/index.d.ts +0 -10
  110. package/lib/tools/index.d.ts.map +0 -1
  111. package/lib/tools/index.js +0 -341
  112. package/lib/tools/index.js.map +0 -1
  113. package/lib/types.d.ts.map +0 -1
  114. package/lib/types.js.map +0 -1
  115. package/plugin.yml +0 -3
  116. package/src/adapter.ts +0 -151
  117. package/src/get-msg.ts +0 -56
  118. package/src/icqq-login-assist-bridge.ts +0 -196
  119. package/src/icqq-side-events.ts +0 -228
  120. package/src/login-assist-routes.ts +0 -39
  121. package/src/login-ipc-contract.ts +0 -52
  122. package/src/routes.ts +0 -83
  123. package/src/segment-mapper.ts +0 -1
  124. package/src/tools/index.ts +0 -412
  125. /package/{skills/icqq → agent}/PERMITS.md +0 -0
@@ -1,412 +0,0 @@
1
- /**
2
- * ICQQ 平台特有工具注册 — 通过 IPC 调用守护进程 Actions
3
- *
4
- * 通用群管理工具由 createSceneManagementTools() 自动生成;
5
- * 本模块注册 ICQQ 独有的扩展工具。
6
- */
7
- import type { ToolFeature } from "zhin.js";
8
- import { createSceneManagementTools } from "zhin.js";
9
- import type { IcqqAdapter } from "../adapter.js";
10
- import { Actions } from "../protocol.js";
11
-
12
- export function registerTools(
13
- toolService: ToolFeature,
14
- icqq: IcqqAdapter,
15
- pluginName: string,
16
- ): () => void {
17
- const disposers: (() => void)[] = [];
18
-
19
- // ── 通用群管工具 ───────────────────────────────────────────────────
20
- const sceneTools = createSceneManagementTools(icqq, "icqq");
21
- disposers.push(...sceneTools.map((t) => toolService.addTool(t, pluginName)));
22
-
23
- // ── 设置头衔 ───────────────────────────────────────────────────────
24
- disposers.push(
25
- toolService.addTool(
26
- {
27
- name: "icqq_set_title",
28
- description: "设置 QQ 群成员的专属头衔",
29
- parameters: {
30
- type: "object",
31
- properties: {
32
- endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
33
- group_id: { type: "number", description: "目标群号" },
34
- user_id: { type: "number", description: "目标成员 QQ号" },
35
- title: { type: "string", description: "头衔文字" },
36
- duration: { type: "number", description: "持续时间(秒),-1永久" },
37
- },
38
- required: ["endpoint_id", "group_id", "user_id", "title"],
39
- },
40
- platforms: ["icqq"],
41
- tags: ["icqq"],
42
- permissions: ["platform(icqq,scene_owner)"],
43
- execute: async (args: Record<string, any>) => {
44
- const endpoint = icqq.endpoints.get(args.endpoint_id);
45
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
46
- const resp = await endpoint.ipc.request(Actions.SET_GROUP_TITLE, {
47
- group_id: args.group_id,
48
- user_id: args.user_id,
49
- title: args.title,
50
- duration: args.duration ?? -1,
51
- });
52
- return { success: resp.ok, message: resp.ok ? `已将 ${args.user_id} 的头衔设为 "${args.title}"` : (resp.error ?? "设置失败") };
53
- },
54
- },
55
- pluginName,
56
- ),
57
- );
58
-
59
- // ── 发送群公告 ─────────────────────────────────────────────────────
60
- disposers.push(
61
- toolService.addTool(
62
- {
63
- name: "icqq_announce",
64
- description: "发送 QQ 群公告(需要管理员权限)",
65
- parameters: {
66
- type: "object",
67
- properties: {
68
- endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
69
- group_id: { type: "number", description: "目标群号" },
70
- content: { type: "string", description: "公告内容" },
71
- },
72
- required: ["endpoint_id", "group_id", "content"],
73
- },
74
- platforms: ["icqq"],
75
- tags: ["icqq"],
76
- permissions: ["platform(icqq,scene_admin)"],
77
- execute: async (args: Record<string, any>) => {
78
- const endpoint = icqq.endpoints.get(args.endpoint_id);
79
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
80
- const resp = await endpoint.ipc.request(Actions.GROUP_ANNOUNCE, {
81
- group_id: args.group_id,
82
- content: args.content,
83
- });
84
- return { success: resp.ok, message: resp.ok ? "群公告已发送" : (resp.error ?? "发送失败") };
85
- },
86
- },
87
- pluginName,
88
- ),
89
- );
90
-
91
- // ── 戳一戳 ─────────────────────────────────────────────────────────
92
- disposers.push(
93
- toolService.addTool(
94
- {
95
- name: "icqq_poke",
96
- description: "在 QQ 群中对某个成员执行戳一戳互动操作",
97
- parameters: {
98
- type: "object",
99
- properties: {
100
- endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
101
- group_id: { type: "number", description: "目标群号" },
102
- user_id: { type: "number", description: "要戳的目标成员 QQ号" },
103
- },
104
- required: ["endpoint_id", "group_id", "user_id"],
105
- },
106
- platforms: ["icqq"],
107
- tags: ["icqq"],
108
- execute: async (args: Record<string, any>) => {
109
- const endpoint = icqq.endpoints.get(args.endpoint_id);
110
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
111
- const resp = await endpoint.ipc.request(Actions.GROUP_POKE, {
112
- group_id: args.group_id,
113
- user_id: args.user_id,
114
- });
115
- return { success: resp.ok, message: resp.ok ? `已戳了戳 ${args.user_id}` : (resp.error ?? "戳一戳失败") };
116
- },
117
- },
118
- pluginName,
119
- ),
120
- );
121
-
122
- // ── 获取被禁言列表 ─────────────────────────────────────────────────
123
- disposers.push(
124
- toolService.addTool(
125
- {
126
- name: "icqq_list_muted",
127
- description: "查询 QQ 群中当前被禁言的成员列表",
128
- parameters: {
129
- type: "object",
130
- properties: {
131
- endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
132
- group_id: { type: "number", description: "目标群号" },
133
- },
134
- required: ["endpoint_id", "group_id"],
135
- },
136
- platforms: ["icqq"],
137
- tags: ["icqq"],
138
- permissions: ["platform(icqq,scene_admin)"],
139
- execute: async (args: Record<string, any>) => {
140
- const endpoint = icqq.endpoints.get(args.endpoint_id);
141
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
142
- const resp = await endpoint.ipc.request(Actions.GROUP_MUTED_LIST, {
143
- group_id: args.group_id,
144
- });
145
- if (!resp.ok) throw new Error(resp.error ?? "获取禁言列表失败");
146
- const list = Array.isArray(resp.data) ? resp.data : [];
147
- return { muted_members: list, count: list.length };
148
- },
149
- },
150
- pluginName,
151
- ),
152
- );
153
-
154
- // ── 给用户点赞 ─────────────────────────────────────────────────────
155
- disposers.push(
156
- toolService.addTool(
157
- {
158
- name: "icqq_send_user_like",
159
- description: "给用户点赞(竖大拇指),每人每天最多 20 次",
160
- parameters: {
161
- type: "object",
162
- properties: {
163
- endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
164
- user_id: { type: "number", description: "要点赞的目标用户 QQ号" },
165
- times: { type: "number", description: "点赞次数(1-20),默认 1" },
166
- },
167
- required: ["endpoint_id", "user_id"],
168
- },
169
- platforms: ["icqq"],
170
- tags: ["icqq"],
171
- execute: async (args: Record<string, any>) => {
172
- const endpoint = icqq.endpoints.get(args.endpoint_id);
173
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
174
- const resp = await endpoint.ipc.request(Actions.FRIEND_LIKE, {
175
- user_id: args.user_id,
176
- times: Math.min(args.times ?? 1, 20),
177
- });
178
- return { success: resp.ok, message: resp.ok ? `已给 ${args.user_id} 点赞` : (resp.error ?? "点赞失败") };
179
- },
180
- },
181
- pluginName,
182
- ),
183
- );
184
-
185
- // ── 设置匿名聊天 ───────────────────────────────────────────────────
186
- disposers.push(
187
- toolService.addTool(
188
- {
189
- name: "icqq_set_anonymous",
190
- description: "开启或关闭 QQ 群的匿名聊天功能",
191
- parameters: {
192
- type: "object",
193
- properties: {
194
- endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
195
- group_id: { type: "number", description: "目标群号" },
196
- enable: { type: "boolean", description: "true=开启,false=关闭,默认 true" },
197
- },
198
- required: ["endpoint_id", "group_id"],
199
- },
200
- platforms: ["icqq"],
201
- tags: ["icqq"],
202
- permissions: ["platform(icqq,scene_owner)"],
203
- execute: async (args: Record<string, any>) => {
204
- const endpoint = icqq.endpoints.get(args.endpoint_id);
205
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
206
- const enable = args.enable ?? true;
207
- const resp = await endpoint.ipc.request(Actions.GROUP_ALLOW_ANONY, {
208
- group_id: args.group_id,
209
- enable,
210
- });
211
- return { success: resp.ok, message: resp.ok ? (enable ? "已开启匿名聊天" : "已关闭匿名聊天") : (resp.error ?? "操作失败") };
212
- },
213
- },
214
- pluginName,
215
- ),
216
- );
217
-
218
- // ── 群文件列表 ─────────────────────────────────────────────────────
219
- disposers.push(
220
- toolService.addTool(
221
- {
222
- name: "icqq_group_files",
223
- description: "获取 QQ 群的群文件列表",
224
- parameters: {
225
- type: "object",
226
- properties: {
227
- endpoint_id: { type: "string", description: "Endpoint 名称", contextKey: 'endpointId' },
228
- group_id: { type: "number", description: "群号" },
229
- },
230
- required: ["endpoint_id", "group_id"],
231
- },
232
- platforms: ["icqq"],
233
- tags: ["icqq"],
234
- execute: async (args: Record<string, any>) => {
235
- const endpoint = icqq.endpoints.get(args.endpoint_id);
236
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
237
- const resp = await endpoint.ipc.request(Actions.GFS_LIST, {
238
- group_id: args.group_id,
239
- });
240
- if (!resp.ok) throw new Error(resp.error ?? "获取群文件失败");
241
- const files = Array.isArray(resp.data) ? resp.data : [];
242
- if (!files.length) return { files: [], message: "群文件为空" };
243
- return {
244
- files: files.slice(0, 30).map((f: any) => ({
245
- name: f.name,
246
- size: f.size,
247
- uploader: f.uploader_uin,
248
- upload_time: f.upload_time,
249
- })),
250
- count: files.length,
251
- };
252
- },
253
- },
254
- pluginName,
255
- ),
256
- );
257
-
258
- // ── 好友列表 ───────────────────────────────────────────────────────
259
- disposers.push(
260
- toolService.addTool(
261
- {
262
- name: "icqq_friend_list",
263
- description: "获取 QQ 好友列表",
264
- parameters: {
265
- type: "object",
266
- properties: {
267
- endpoint_id: { type: "string", description: "Endpoint 名称", contextKey: 'endpointId' },
268
- },
269
- required: ["endpoint_id"],
270
- },
271
- platforms: ["icqq"],
272
- tags: ["icqq"],
273
- execute: async (args: Record<string, any>) => {
274
- const endpoint = icqq.endpoints.get(args.endpoint_id);
275
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
276
- const friends = Array.from(endpoint.friends.values()).map((f) => ({
277
- user_id: f.user_id,
278
- nickname: f.nickname,
279
- remark: f.remark,
280
- }));
281
- return { friends: friends.slice(0, 50), count: endpoint.friends.size };
282
- },
283
- },
284
- pluginName,
285
- ),
286
- );
287
-
288
- // ── 群列表 ─────────────────────────────────────────────────────────
289
- disposers.push(
290
- toolService.addTool(
291
- {
292
- name: "icqq_group_list",
293
- description: "获取 Endpoint 的 QQ 群列表",
294
- parameters: {
295
- type: "object",
296
- properties: {
297
- endpoint_id: { type: "string", description: "Endpoint 名称", contextKey: 'endpointId' },
298
- },
299
- required: ["endpoint_id"],
300
- },
301
- platforms: ["icqq"],
302
- tags: ["icqq"],
303
- execute: async (args: Record<string, any>) => {
304
- const endpoint = icqq.endpoints.get(args.endpoint_id);
305
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
306
- const groups = Array.from(endpoint.groups.values()).map((g) => ({
307
- group_id: g.group_id,
308
- group_name: g.group_name,
309
- member_count: g.member_count,
310
- max_member_count: g.max_member_count,
311
- }));
312
- return { groups: groups.slice(0, 50), count: endpoint.groups.size };
313
- },
314
- },
315
- pluginName,
316
- ),
317
- );
318
-
319
- // ── 群签到 ─────────────────────────────────────────────────────────
320
- disposers.push(
321
- toolService.addTool(
322
- {
323
- name: "icqq_group_sign",
324
- description: "QQ 群签到打卡",
325
- parameters: {
326
- type: "object",
327
- properties: {
328
- endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
329
- group_id: { type: "number", description: "目标群号" },
330
- },
331
- required: ["endpoint_id", "group_id"],
332
- },
333
- platforms: ["icqq"],
334
- tags: ["icqq"],
335
- execute: async (args: Record<string, any>) => {
336
- const endpoint = icqq.endpoints.get(args.endpoint_id);
337
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
338
- const resp = await endpoint.ipc.request(Actions.GROUP_SIGN, {
339
- group_id: args.group_id,
340
- });
341
- return { success: resp.ok, message: resp.ok ? "群签到成功" : (resp.error ?? "签到失败") };
342
- },
343
- },
344
- pluginName,
345
- ),
346
- );
347
-
348
- // ── 邀请入群 ───────────────────────────────────────────────────────
349
- disposers.push(
350
- toolService.addTool(
351
- {
352
- name: "icqq_group_invite",
353
- description: "邀请好友加入 QQ 群",
354
- parameters: {
355
- type: "object",
356
- properties: {
357
- endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
358
- group_id: { type: "number", description: "目标群号" },
359
- user_id: { type: "number", description: "要邀请的 QQ号" },
360
- },
361
- required: ["endpoint_id", "group_id", "user_id"],
362
- },
363
- platforms: ["icqq"],
364
- tags: ["icqq"],
365
- execute: async (args: Record<string, any>) => {
366
- const endpoint = icqq.endpoints.get(args.endpoint_id);
367
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
368
- const resp = await endpoint.ipc.request(Actions.GROUP_INVITE, {
369
- group_id: args.group_id,
370
- user_id: args.user_id,
371
- });
372
- return { success: resp.ok, message: resp.ok ? `已邀请 ${args.user_id} 加入群` : (resp.error ?? "邀请失败") };
373
- },
374
- },
375
- pluginName,
376
- ),
377
- );
378
-
379
- // ── 设为/移除精华消息 ──────────────────────────────────────────────
380
- disposers.push(
381
- toolService.addTool(
382
- {
383
- name: "icqq_essence",
384
- description: "设置或移除 QQ 群精华消息",
385
- parameters: {
386
- type: "object",
387
- properties: {
388
- endpoint_id: { type: "string", description: "Endpoint QQ号", contextKey: 'endpointId' },
389
- message_id: { type: "string", description: "消息 ID" },
390
- action: { type: "string", description: "add=设为精华, remove=移除精华" },
391
- },
392
- required: ["endpoint_id", "message_id", "action"],
393
- },
394
- platforms: ["icqq"],
395
- tags: ["icqq"],
396
- permissions: ["platform(icqq,scene_admin)"],
397
- execute: async (args: Record<string, any>) => {
398
- const endpoint = icqq.endpoints.get(args.endpoint_id);
399
- if (!endpoint) throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
400
- const action = args.action === "add" ? Actions.GROUP_ESSENCE_ADD : Actions.GROUP_ESSENCE_REMOVE;
401
- const resp = await endpoint.ipc.request(action, {
402
- message_id: args.message_id,
403
- });
404
- return { success: resp.ok, message: resp.ok ? (args.action === "add" ? "已设为精华" : "已移除精华") : (resp.error ?? "操作失败") };
405
- },
406
- },
407
- pluginName,
408
- ),
409
- );
410
-
411
- return () => disposers.forEach((d) => d());
412
- }
File without changes