@zhin.js/adapter-kook 1.0.83 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +813 -16
  2. package/README.md +75 -374
  3. package/adapters/kook.js +41 -0
  4. package/adapters/kook.ts +56 -0
  5. package/agent/PERMITS.md +23 -0
  6. package/agent/tools/blacklist.ts +31 -0
  7. package/agent/tools/create_role.ts +23 -0
  8. package/agent/tools/delete_role.ts +19 -0
  9. package/agent/tools/grant_role.ts +20 -0
  10. package/agent/tools/list_roles.ts +25 -0
  11. package/agent/tools/revoke_role.ts +20 -0
  12. package/commands/endpoint/add/[id].js +3 -0
  13. package/commands/endpoint/add/[id].ts +3 -0
  14. package/commands/endpoint/list.js +3 -0
  15. package/commands/endpoint/list.ts +3 -0
  16. package/commands/endpoint/remove/[id].js +3 -0
  17. package/commands/endpoint/remove/[id].ts +3 -0
  18. package/lib/client.d.ts +11 -0
  19. package/lib/client.js +2 -0
  20. package/lib/endpoint.d.ts +59 -0
  21. package/lib/endpoint.js +374 -0
  22. package/lib/index.d.ts +6 -18
  23. package/lib/index.js +6 -342
  24. package/lib/kook-endpoint-commands.d.ts +1 -0
  25. package/lib/kook-endpoint-commands.js +18 -0
  26. package/lib/kook-runtime-state.d.ts +1 -0
  27. package/lib/kook-runtime-state.js +6 -0
  28. package/lib/platform-permit.d.ts +22 -0
  29. package/lib/platform-permit.js +48 -0
  30. package/lib/protocol.d.ts +144 -0
  31. package/lib/protocol.js +313 -0
  32. package/lib/side-event-dispatch.d.ts +3 -0
  33. package/lib/side-event-dispatch.js +49 -0
  34. package/lib/webhook.d.ts +16 -0
  35. package/lib/webhook.js +71 -0
  36. package/lib/ws.d.ts +56 -0
  37. package/lib/ws.js +63 -0
  38. package/package.json +60 -28
  39. package/plugin.js +19 -0
  40. package/schema.json +128 -0
  41. package/src/client.ts +15 -0
  42. package/src/endpoint.ts +433 -0
  43. package/src/index.ts +45 -322
  44. package/src/kook-endpoint-commands.ts +19 -0
  45. package/src/kook-runtime-state.ts +7 -0
  46. package/src/platform-permit.ts +75 -0
  47. package/src/protocol.ts +462 -0
  48. package/src/side-event-dispatch.ts +54 -0
  49. package/src/webhook.ts +114 -0
  50. package/src/ws.ts +131 -0
  51. package/client/Dashboard.tsx +0 -255
  52. package/client/index.tsx +0 -11
  53. package/client/tsconfig.json +0 -7
  54. package/client/utils/api.ts +0 -17
  55. package/dist/index.js +0 -31
  56. package/lib/adapter.d.ts +0 -26
  57. package/lib/adapter.d.ts.map +0 -1
  58. package/lib/adapter.js +0 -61
  59. package/lib/adapter.js.map +0 -1
  60. package/lib/bot.d.ts +0 -122
  61. package/lib/bot.d.ts.map +0 -1
  62. package/lib/bot.js +0 -608
  63. package/lib/bot.js.map +0 -1
  64. package/lib/index.d.ts.map +0 -1
  65. package/lib/index.js.map +0 -1
  66. package/lib/types.d.ts +0 -32
  67. package/lib/types.d.ts.map +0 -1
  68. package/lib/types.js +0 -8
  69. package/lib/types.js.map +0 -1
  70. package/plugin.yml +0 -3
  71. package/src/adapter.ts +0 -71
  72. package/src/bot.ts +0 -693
  73. package/src/types.ts +0 -36
  74. /package/{skills/kook/SKILL.md → agent/skills/kook.md} +0 -0
@@ -0,0 +1,20 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { platformPermit } from '../../src/platform-permit.js';
4
+
5
+ export default defineAgentTool<{ guild_id: string; user_id: string; role_id: string }>({
6
+ description: '给用户授予 KOOK 服务器角色',
7
+ inputSchema: z.object({
8
+ guild_id: z.string().describe('服务器 ID'),
9
+ user_id: z.string().describe('用户 ID'),
10
+ role_id: z.string().describe('角色 ID'),
11
+ }),
12
+ adapter: 'kook',
13
+ tags: ['kook'],
14
+ permissions: [platformPermit('manage_roles')],
15
+ async execute({ guild_id, user_id, role_id }: { guild_id: string; user_id: string; role_id: string }, context) {
16
+ const client = context.$client;
17
+ const success = await client.pickGuildMember(guild_id, user_id).grant(role_id);
18
+ return { success, message: success ? `已授予用户 ${user_id} 角色 ${role_id}` : '授予角色失败' };
19
+ },
20
+ });
@@ -0,0 +1,25 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+
4
+ export default defineAgentTool<{ guild_id: string }>({
5
+ description: '获取 KOOK 服务器的角色列表',
6
+ inputSchema: z.object({
7
+ guild_id: z.string().describe('服务器 ID'),
8
+ }),
9
+ adapter: 'kook',
10
+ tags: ['kook'],
11
+ async execute({ guild_id }: { guild_id: string }, context) {
12
+ const client = context.$client;
13
+ const roles = await client.pickGuild(guild_id).getRoleList();
14
+ return {
15
+ roles: roles.map((r) => ({
16
+ id: String(r.role_id),
17
+ name: r.name,
18
+ color: r.color,
19
+ position: r.position,
20
+ permissions: r.permissions,
21
+ })),
22
+ count: roles.length,
23
+ };
24
+ },
25
+ });
@@ -0,0 +1,20 @@
1
+ import { defineAgentTool } from '@zhin.js/agent/tools';
2
+ import { z } from 'zod';
3
+ import { platformPermit } from '../../src/platform-permit.js';
4
+
5
+ export default defineAgentTool<{ guild_id: string; user_id: string; role_id: string }>({
6
+ description: '撤销用户的 KOOK 服务器角色',
7
+ inputSchema: z.object({
8
+ guild_id: z.string().describe('服务器 ID'),
9
+ user_id: z.string().describe('用户 ID'),
10
+ role_id: z.string().describe('角色 ID'),
11
+ }),
12
+ adapter: 'kook',
13
+ tags: ['kook'],
14
+ permissions: [platformPermit('manage_roles')],
15
+ async execute({ guild_id, user_id, role_id }: { guild_id: string; user_id: string; role_id: string }, context) {
16
+ const client = context.$client;
17
+ const success = await client.pickGuildMember(guild_id, user_id).revoke(role_id);
18
+ return { success, message: success ? `已撤销用户 ${user_id} 的角色 ${role_id}` : '撤销角色失败' };
19
+ },
20
+ });
@@ -0,0 +1,3 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { kookEndpointCommands } from "../../../lib/kook-endpoint-commands.js";
3
+ export default kookEndpointCommands.add;
@@ -0,0 +1,3 @@
1
+ import { kookEndpointCommands } from '../../../src/kook-endpoint-commands.js';
2
+
3
+ export default kookEndpointCommands.add;
@@ -0,0 +1,3 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { kookEndpointCommands } from "../../lib/kook-endpoint-commands.js";
3
+ export default kookEndpointCommands.list;
@@ -0,0 +1,3 @@
1
+ import { kookEndpointCommands } from '../../src/kook-endpoint-commands.js';
2
+
3
+ export default kookEndpointCommands.list;
@@ -0,0 +1,3 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { kookEndpointCommands } from "../../../lib/kook-endpoint-commands.js";
3
+ export default kookEndpointCommands.remove;
@@ -0,0 +1,3 @@
1
+ import { kookEndpointCommands } from '../../../src/kook-endpoint-commands.js';
2
+
3
+ export default kookEndpointCommands.remove;
@@ -0,0 +1,11 @@
1
+ import type { KookClientTransport } from './ws.js';
2
+ export type KookClientEventMap = Record<string, unknown>;
3
+ declare module '@zhin.js/feature-kit' {
4
+ interface AdapterClientRegistry {
5
+ readonly kook: {
6
+ readonly client: KookClientTransport;
7
+ readonly events: KookClientEventMap;
8
+ };
9
+ }
10
+ }
11
+ export declare const kookClient: import("@zhin.js/adapter").EndpointClientToken<KookClientTransport, KookClientEventMap>;
package/lib/client.js ADDED
@@ -0,0 +1,2 @@
1
+ import { defineEndpointClient } from 'zhin.js/adapter';
2
+ export const kookClient = defineEndpointClient('kook');
@@ -0,0 +1,59 @@
1
+ import { Endpoint } from 'zhin.js/adapter';
2
+ import { type EndpointControl, type EndpointManagement, type EndpointSendRequest } from 'zhin.js/adapter';
3
+ import type { HttpHost } from '@zhin.js/host-http';
4
+ import type { CapabilityId } from 'zhin.js';
5
+ import { type KookInboundMessage, type KookWebhookEventData, type ResolvedKookWebhookConfig, type ResolvedKookWebsocketConfig } from './protocol.js';
6
+ import { type CreateKookClient, type KookClientTransport } from './ws.js';
7
+ export interface KookEndpointOptions {
8
+ readonly id: CapabilityId;
9
+ readonly config: ResolvedKookWebsocketConfig;
10
+ readonly createClient?: CreateKookClient;
11
+ }
12
+ export declare class KookWebsocketEndpoint extends Endpoint<KookClientTransport> {
13
+ #private;
14
+ readonly management: EndpointManagement;
15
+ readonly control: EndpointControl;
16
+ constructor(options: KookEndpointOptions);
17
+ get client(): KookClientTransport;
18
+ start(): Promise<void>;
19
+ open(): void;
20
+ close(): void;
21
+ stop(): Promise<void>;
22
+ send({ conversation, payload }: EndpointSendRequest): Promise<string>;
23
+ /** Test / internal: admit a normalized message when open. */
24
+ admit(msg: KookInboundMessage): void;
25
+ recallMessage(messageId: string): Promise<void>;
26
+ }
27
+ export interface KookWebhookEndpointOptions {
28
+ readonly id: CapabilityId;
29
+ readonly http: HttpHost;
30
+ readonly config: ResolvedKookWebhookConfig;
31
+ readonly createClient?: CreateKookClient;
32
+ }
33
+ export declare class KookWebhookEndpoint extends Endpoint<KookClientTransport> {
34
+ #private;
35
+ readonly management: EndpointManagement;
36
+ readonly control: EndpointControl;
37
+ constructor(options: KookWebhookEndpointOptions);
38
+ get client(): KookClientTransport;
39
+ /** Used by webhook handler. */
40
+ get isOpen(): boolean;
41
+ get config(): ResolvedKookWebhookConfig;
42
+ get selfId(): string | undefined;
43
+ start(): Promise<void>;
44
+ open(): void;
45
+ close(): void;
46
+ stop(): Promise<void>;
47
+ send({ conversation, payload }: EndpointSendRequest): Promise<string>;
48
+ admitEvent(event: KookWebhookEventData): void;
49
+ /** Test / internal: admit a message when open. */
50
+ admit(msg: KookInboundMessage): void;
51
+ recallMessage(messageId: string): Promise<void>;
52
+ checkAndRememberSn(sn: number): boolean;
53
+ }
54
+ /**
55
+ * KOOK endpoint 的 EndpointManagement 语义端口(websocket / webhook 共用)。
56
+ * 数据走 kook-client 的 HTTP API 封装:/api/v3/guild/list、
57
+ * /api/v3/channel/list、/api/v3/guild/user-list(SDK 内部已做分页聚合)。
58
+ */
59
+ export declare function createKookEndpointManagement(requireClient: () => KookClientTransport): EndpointManagement;
@@ -0,0 +1,374 @@
1
+ import { Endpoint } from 'zhin.js/adapter';
2
+ import { createRecallEndpointControl, } from 'zhin.js/adapter';
3
+ import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
4
+ import { formatInboundContent, formatOutboundKmarkdown, isKookBotMentioned, kookInboundConversation, normalizeKookWebhookEvent, senderDisplayName, } from './protocol.js';
5
+ import { registerKookWebhookRoutes } from './webhook.js';
6
+ import { defaultCreateClient, defaultCreateWebhookClient, normalizeKookMessage, } from './ws.js';
7
+ import { receiveKookSideEvent } from './side-event-dispatch.js';
8
+ export class KookWebsocketEndpoint extends Endpoint {
9
+ #logger;
10
+ #options;
11
+ #createClient;
12
+ #client = null;
13
+ #open = false;
14
+ #started = false;
15
+ management = createKookEndpointManagement(() => this.#requireClient());
16
+ control = createRecallEndpointControl((id) => this.recallMessage(id));
17
+ constructor(options) {
18
+ super();
19
+ this.#logger = getAdapterLogger('kook', options.config.id);
20
+ this.#options = options;
21
+ this.#createClient = options.createClient ?? defaultCreateClient;
22
+ }
23
+ get client() {
24
+ return this.#requireClient();
25
+ }
26
+ async start() {
27
+ if (this.#started)
28
+ return;
29
+ this.#started = true;
30
+ try {
31
+ this.#client = this.#createClient(this.#options.config);
32
+ this.#bindClient(this.#client);
33
+ await this.#client.connect();
34
+ this.#logger.info(formatCompact({
35
+ op: 'connect',
36
+ endpoint: this.#options.config.id,
37
+ mode: 'websocket',
38
+ self_id: this.#client.self_id != null ? String(this.#client.self_id) : undefined,
39
+ }));
40
+ }
41
+ catch (error) {
42
+ await this.stop();
43
+ this.#logger.error('Failed to connect KOOK websocket:', error);
44
+ throw error;
45
+ }
46
+ }
47
+ open() {
48
+ this.#open = true;
49
+ }
50
+ close() {
51
+ this.#open = false;
52
+ }
53
+ async stop() {
54
+ this.#open = false;
55
+ if (this.#client) {
56
+ try {
57
+ this.#client.removeAllListeners();
58
+ await this.#client.disconnect();
59
+ }
60
+ catch {
61
+ /* ignore */
62
+ }
63
+ this.#client = null;
64
+ }
65
+ this.#started = false;
66
+ this.#logger.debug(formatCompact({ op: 'disconnect' }));
67
+ }
68
+ async send({ conversation, payload }) {
69
+ const body = formatOutboundKmarkdown(payload);
70
+ const client = this.#requireClient();
71
+ const result = conversation.kind === 'private'
72
+ ? await client.sendPrivateMsg(conversation.id, body)
73
+ : await client.sendChannelMsg(conversation.id, body);
74
+ const messageId = result?.msg_id != null ? String(result.msg_id) : '';
75
+ this.#logger.debug(formatCompact({
76
+ op: 'kook_send',
77
+ endpoint: this.#options.config.id,
78
+ target: `${conversation.kind}:${conversation.id}`,
79
+ messageId,
80
+ }));
81
+ return messageId;
82
+ }
83
+ /** Test / internal: admit a normalized message when open. */
84
+ admit(msg) {
85
+ if (!this.#open)
86
+ return;
87
+ if (msg.authorBot)
88
+ return;
89
+ const conversation = kookInboundConversation(String(this.#options.id), msg);
90
+ const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
91
+ void this.emit('message.receive', {
92
+ conversation,
93
+ message: { conversation, id: msg.id },
94
+ content: formatInboundContent(msg),
95
+ sender: {
96
+ id: msg.authorId,
97
+ name: senderDisplayName(msg) || undefined,
98
+ ...(msg.authorRoles?.length ? { roles: msg.authorRoles.map(String) } : {}),
99
+ },
100
+ endpointId: this.#options.config.id,
101
+ ...(isKookBotMentioned(msg, selfId) ? { mentioned: true } : {}),
102
+ metadata: Object.freeze({
103
+ channelKind: msg.channelKind,
104
+ userId: msg.authorId,
105
+ guildId: msg.guildId,
106
+ roles: msg.authorRoles,
107
+ }),
108
+ }).catch((err) => {
109
+ this.#logger.warn(formatCompact({
110
+ op: 'kook_gateway_receive_failed',
111
+ target: `${conversation.kind}:${conversation.id}`,
112
+ error: err instanceof Error ? err.message : String(err),
113
+ }));
114
+ });
115
+ }
116
+ async recallMessage(messageId) {
117
+ if (!messageId)
118
+ return;
119
+ await this.#requireClient().recallMsg?.(messageId);
120
+ }
121
+ #bindClient(client) {
122
+ client.on('message', (raw) => {
123
+ this.#emitPlatformEvent('message', raw);
124
+ const msg = normalizeKookMessage(raw);
125
+ if (msg)
126
+ this.admit(msg);
127
+ });
128
+ const receiver = client.receiver;
129
+ receiver?.on('event', (raw) => {
130
+ this.#emitPlatformEvent('event', raw);
131
+ receiveKookSideEvent((name, payload) => this.emit(name, payload), this.#options.config.id, raw, this.#logger);
132
+ });
133
+ }
134
+ #emitPlatformEvent(name, event) {
135
+ void this.emitPlatform(name, event).catch((error) => {
136
+ this.#logger.warn(formatCompact({
137
+ op: 'kook_platform_event_failed',
138
+ event: name,
139
+ error: error instanceof Error ? error.message : String(error),
140
+ }));
141
+ });
142
+ }
143
+ #requireClient() {
144
+ if (!this.#client)
145
+ throw new Error('KOOK client not connected');
146
+ return this.#client;
147
+ }
148
+ }
149
+ export class KookWebhookEndpoint extends Endpoint {
150
+ #logger;
151
+ #options;
152
+ #createClient;
153
+ #client = null;
154
+ #routeReleases = [];
155
+ #processedSn = new Set();
156
+ #open = false;
157
+ #started = false;
158
+ management = createKookEndpointManagement(() => this.#requireClient());
159
+ control = createRecallEndpointControl((id) => this.recallMessage(id));
160
+ constructor(options) {
161
+ super();
162
+ this.#logger = getAdapterLogger('kook', options.config.id);
163
+ this.#options = options;
164
+ this.#createClient = options.createClient ?? defaultCreateWebhookClient;
165
+ }
166
+ get client() {
167
+ return this.#requireClient();
168
+ }
169
+ /** Used by webhook handler. */
170
+ get isOpen() {
171
+ return this.#open;
172
+ }
173
+ get config() {
174
+ return this.#options.config;
175
+ }
176
+ get selfId() {
177
+ return this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
178
+ }
179
+ async start() {
180
+ if (this.#started)
181
+ return;
182
+ this.#started = true;
183
+ try {
184
+ this.#client = this.#createClient(this.#options.config);
185
+ await this.#client.init();
186
+ this.#routeReleases.push(...registerKookWebhookRoutes(this.#options.http, this));
187
+ this.#logger.info(formatCompact({
188
+ op: 'connect',
189
+ endpoint: this.#options.config.id,
190
+ mode: 'webhook',
191
+ path: this.#options.config.webhookPath,
192
+ self_id: this.#client.self_id != null ? String(this.#client.self_id) : undefined,
193
+ }));
194
+ }
195
+ catch (error) {
196
+ await this.stop();
197
+ this.#logger.error('Failed to connect KOOK webhook:', error);
198
+ throw error;
199
+ }
200
+ }
201
+ open() {
202
+ this.#open = true;
203
+ }
204
+ close() {
205
+ this.#open = false;
206
+ }
207
+ async stop() {
208
+ this.#open = false;
209
+ for (const release of this.#routeReleases.splice(0))
210
+ release();
211
+ this.#processedSn.clear();
212
+ if (this.#client) {
213
+ try {
214
+ this.#client.removeAllListeners();
215
+ await this.#client.disconnect();
216
+ }
217
+ catch {
218
+ /* ignore */
219
+ }
220
+ this.#client = null;
221
+ }
222
+ this.#started = false;
223
+ this.#logger.debug(formatCompact({ op: 'disconnect' }));
224
+ }
225
+ async send({ conversation, payload }) {
226
+ const body = formatOutboundKmarkdown(payload);
227
+ const client = this.#requireClient();
228
+ const result = conversation.kind === 'private'
229
+ ? await client.sendPrivateMsg(conversation.id, body)
230
+ : await client.sendChannelMsg(conversation.id, body);
231
+ const messageId = result?.msg_id != null ? String(result.msg_id) : '';
232
+ this.#logger.debug(formatCompact({
233
+ op: 'kook_send',
234
+ endpoint: this.#options.config.id,
235
+ target: `${conversation.kind}:${conversation.id}`,
236
+ messageId,
237
+ }));
238
+ return messageId;
239
+ }
240
+ admitEvent(event) {
241
+ void this.emitPlatform(String(event.type ?? 'event'), event).catch((error) => {
242
+ this.#logger.warn(formatCompact({
243
+ op: 'kook_platform_event_failed',
244
+ event: String(event.type ?? 'event'),
245
+ error: error instanceof Error ? error.message : String(error),
246
+ }));
247
+ });
248
+ if (receiveKookSideEvent((name, payload) => this.emit(name, payload), this.#options.config.id, event, this.#logger))
249
+ return;
250
+ const message = normalizeKookWebhookEvent(event, {
251
+ ignore: this.#options.config.ignore,
252
+ selfId: this.selfId,
253
+ });
254
+ if (message)
255
+ this.admit(message);
256
+ }
257
+ /** Test / internal: admit a message when open. */
258
+ admit(msg) {
259
+ if (!this.#open)
260
+ return;
261
+ if (msg.authorBot)
262
+ return;
263
+ const conversation = kookInboundConversation(String(this.#options.id), msg);
264
+ const selfId = this.#client?.self_id != null ? String(this.#client.self_id) : undefined;
265
+ void this.emit('message.receive', {
266
+ conversation,
267
+ message: { conversation, id: msg.id },
268
+ content: formatInboundContent(msg),
269
+ sender: {
270
+ id: msg.authorId,
271
+ name: senderDisplayName(msg) || undefined,
272
+ ...(msg.authorRoles?.length ? { roles: msg.authorRoles.map(String) } : {}),
273
+ },
274
+ endpointId: this.#options.config.id,
275
+ ...(isKookBotMentioned(msg, selfId) ? { mentioned: true } : {}),
276
+ metadata: Object.freeze({
277
+ channelKind: msg.channelKind,
278
+ userId: msg.authorId,
279
+ guildId: msg.guildId,
280
+ roles: msg.authorRoles,
281
+ }),
282
+ }).catch((err) => {
283
+ this.#logger.warn(formatCompact({
284
+ op: 'kook_gateway_receive_failed',
285
+ target: `${conversation.kind}:${conversation.id}`,
286
+ error: err instanceof Error ? err.message : String(err),
287
+ }));
288
+ });
289
+ }
290
+ async recallMessage(messageId) {
291
+ if (!messageId)
292
+ return;
293
+ await this.#requireClient().recallMsg?.(messageId);
294
+ }
295
+ checkAndRememberSn(sn) {
296
+ if (this.#processedSn.has(sn))
297
+ return false;
298
+ this.#processedSn.add(sn);
299
+ if (this.#processedSn.size > 1024) {
300
+ const first = this.#processedSn.values().next().value;
301
+ if (first != null)
302
+ this.#processedSn.delete(first);
303
+ }
304
+ return true;
305
+ }
306
+ #requireClient() {
307
+ if (!this.#client)
308
+ throw new Error('KOOK client not initialized');
309
+ return this.#client;
310
+ }
311
+ }
312
+ /**
313
+ * KOOK guild/channel/user id 是字符串形式的雪花号,超出
314
+ * Number.MAX_SAFE_INTEGER,Number() 会丢精度。Console 社交面只把 group_id
315
+ * 当 JSON 值透传、并以字符串回传给 listGroupMembers,因此保留原始字符串
316
+ * (仅按契约类型声明强转)是全链路最不丢信息的方案。
317
+ */
318
+ function toGroupId(id) {
319
+ return id;
320
+ }
321
+ /** KOOK 文字频道标记:HTTP API type=1(2=语音),kook-client 消息侧用 'GROUP'。 */
322
+ function isKookTextChannelType(type) {
323
+ return type === 1 || type === '1' || type === 'GROUP';
324
+ }
325
+ /**
326
+ * KOOK endpoint 的 EndpointManagement 语义端口(websocket / webhook 共用)。
327
+ * 数据走 kook-client 的 HTTP API 封装:/api/v3/guild/list、
328
+ * /api/v3/channel/list、/api/v3/guild/user-list(SDK 内部已做分页聚合)。
329
+ */
330
+ export function createKookEndpointManagement(requireClient) {
331
+ return Object.freeze({
332
+ async listGroups() {
333
+ const guilds = await requireClient().getGuildList();
334
+ const groups = [];
335
+ for (const guild of guilds) {
336
+ if (guild?.id == null)
337
+ continue;
338
+ groups.push({
339
+ group_id: toGroupId(String(guild.id)),
340
+ name: String(guild.name ?? guild.id),
341
+ });
342
+ }
343
+ return groups;
344
+ },
345
+ async listChannels() {
346
+ const client = requireClient();
347
+ const channels = [];
348
+ for (const guild of await client.getGuildList()) {
349
+ if (guild?.id == null)
350
+ continue;
351
+ const guildId = String(guild.id);
352
+ const guildName = String(guild.name ?? guildId);
353
+ for (const channel of await client.getChannelList(guildId)) {
354
+ if (channel?.id == null)
355
+ continue;
356
+ if (channel.is_category)
357
+ continue;
358
+ if (!isKookTextChannelType(channel.type))
359
+ continue;
360
+ channels.push({
361
+ id: String(channel.id),
362
+ name: channel.name ? String(channel.name) : undefined,
363
+ parent: { type: 'guild', id: guildId, name: guildName },
364
+ });
365
+ }
366
+ }
367
+ return channels;
368
+ },
369
+ async listGroupMembers(groupId) {
370
+ // 平台形状(User.Info[])原样返回
371
+ return requireClient().getGuildUserList(groupId);
372
+ },
373
+ });
374
+ }
package/lib/index.d.ts CHANGED
@@ -1,18 +1,6 @@
1
- import { KookAdapter } from "./adapter.js";
2
- import { PageManager } from "@zhin.js/console";
3
- declare module "zhin.js" {
4
- namespace Plugin {
5
- interface Contexts {
6
- web: PageManager;
7
- }
8
- }
9
- }
10
- declare module "zhin.js" {
11
- interface Adapters {
12
- kook: KookAdapter;
13
- }
14
- }
15
- export * from "./types.js";
16
- export { KookBot } from "./bot.js";
17
- export { KookAdapter } from "./adapter.js";
18
- //# sourceMappingURL=index.d.ts.map
1
+ export { formatInboundContent, formatOutboundKmarkdown, resolveKookConfig, senderDisplayName, KookPermission, type KookAdapterConfig, type KookInboundMessage, type KookWireSegment, type LogLevel, type ResolvedKookConfig, type ResolvedKookWebhookConfig, type ResolvedKookWebsocketConfig, } from './protocol.js';
2
+ export { KookWebhookEndpoint, KookWebsocketEndpoint, type KookEndpointOptions, type KookWebhookEndpointOptions, } from './endpoint.js';
3
+ export { registerKookWebhookRoutes, handleKookWebhookRequest, type KookWebhookHandler, } from './webhook.js';
4
+ export { defaultCreateClient, defaultCreateWebhookClient, normalizeKookMessage, type CreateKookClient, type KookClientTransport, } from './ws.js';
5
+ export { kookClient, type KookClientEventMap } from './client.js';
6
+ export { checkKookPlatformPermit, kookGroupPermitResolver, normalizeKookSenderForPermit, platformPermit, type KookSenderInfo, } from './platform-permit.js';