@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
package/lib/index.js CHANGED
@@ -1,342 +1,6 @@
1
- /**
2
- * KOOK 适配器入口:类型扩展、导出、注册
3
- */
4
- import path from "node:path";
5
- import { usePlugin, createGroupManagementTools } from "zhin.js";
6
- import { KookAdapter } from "./adapter.js";
7
- export * from "./types.js";
8
- export { KookBot } from "./bot.js";
9
- export { KookAdapter } from "./adapter.js";
10
- const plugin = usePlugin();
11
- const { provide, useContext } = plugin;
12
- provide({
13
- name: "kook",
14
- description: "KOOK Adapter",
15
- mounted: async (p) => {
16
- const adapter = new KookAdapter(p);
17
- await adapter.start();
18
- return adapter;
19
- },
20
- dispose: async (adapter) => {
21
- await adapter.stop();
22
- },
23
- });
24
- useContext('tool', 'kook', (toolService, kook) => {
25
- const groupTools = createGroupManagementTools(kook, 'kook');
26
- const disposers = groupTools.map(t => toolService.addTool(t, plugin.name));
27
- disposers.push(toolService.addTool({
28
- name: 'kook_grant_role',
29
- description: '给用户授予 KOOK 服务器角色',
30
- parameters: {
31
- type: 'object',
32
- properties: {
33
- bot: { type: 'string', description: 'Bot 名称' },
34
- guild_id: { type: 'string', description: '服务器 ID' },
35
- user_id: { type: 'string', description: '用户 ID' },
36
- role_id: { type: 'string', description: '角色 ID' },
37
- },
38
- required: ['bot', 'guild_id', 'user_id', 'role_id'],
39
- },
40
- platforms: ['kook'],
41
- tags: ['kook'],
42
- execute: async (args) => {
43
- const bot = kook.bots.get(args.bot);
44
- if (!bot)
45
- throw new Error(`Bot ${args.bot} 不存在`);
46
- const success = await bot.grantRole(args.guild_id, args.user_id, args.role_id);
47
- return { success, message: success ? `已授予用户 ${args.user_id} 角色 ${args.role_id}` : '授予角色失败' };
48
- },
49
- }, plugin.name));
50
- disposers.push(toolService.addTool({
51
- name: 'kook_revoke_role',
52
- description: '撤销用户的 KOOK 服务器角色',
53
- parameters: {
54
- type: 'object',
55
- properties: {
56
- bot: { type: 'string', description: 'Bot 名称' },
57
- guild_id: { type: 'string', description: '服务器 ID' },
58
- user_id: { type: 'string', description: '用户 ID' },
59
- role_id: { type: 'string', description: '角色 ID' },
60
- },
61
- required: ['bot', 'guild_id', 'user_id', 'role_id'],
62
- },
63
- platforms: ['kook'],
64
- tags: ['kook'],
65
- execute: async (args) => {
66
- const bot = kook.bots.get(args.bot);
67
- if (!bot)
68
- throw new Error(`Bot ${args.bot} 不存在`);
69
- const success = await bot.revokeRole(args.guild_id, args.user_id, args.role_id);
70
- return { success, message: success ? `已撤销用户 ${args.user_id} 的角色 ${args.role_id}` : '撤销角色失败' };
71
- },
72
- }, plugin.name));
73
- disposers.push(toolService.addTool({
74
- name: 'kook_list_roles',
75
- description: '获取 KOOK 服务器的角色列表',
76
- parameters: {
77
- type: 'object',
78
- properties: {
79
- bot: { type: 'string', description: 'Bot 名称' },
80
- guild_id: { type: 'string', description: '服务器 ID' },
81
- },
82
- required: ['bot', 'guild_id'],
83
- },
84
- platforms: ['kook'],
85
- tags: ['kook'],
86
- execute: async (args) => {
87
- const bot = kook.bots.get(args.bot);
88
- if (!bot)
89
- throw new Error(`Bot ${args.bot} 不存在`);
90
- const roles = await bot.getRoleList(args.guild_id);
91
- return {
92
- roles: roles.map((r) => ({
93
- id: r.role_id,
94
- name: r.name,
95
- color: r.color,
96
- position: r.position,
97
- permissions: r.permissions,
98
- })),
99
- count: roles.length,
100
- };
101
- },
102
- }, plugin.name));
103
- disposers.push(toolService.addTool({
104
- name: 'kook_create_role',
105
- description: '在 KOOK 服务器中创建新角色',
106
- parameters: {
107
- type: 'object',
108
- properties: {
109
- bot: { type: 'string', description: 'Bot 名称' },
110
- guild_id: { type: 'string', description: '服务器 ID' },
111
- name: { type: 'string', description: '角色名称' },
112
- },
113
- required: ['bot', 'guild_id', 'name'],
114
- },
115
- platforms: ['kook'],
116
- tags: ['kook'],
117
- execute: async (args) => {
118
- const bot = kook.bots.get(args.bot);
119
- if (!bot)
120
- throw new Error(`Bot ${args.bot} 不存在`);
121
- const role = await bot.createRole(args.guild_id, args.name);
122
- return {
123
- success: true,
124
- message: `已创建角色 "${args.name}"`,
125
- role: { id: role.role_id, name: role.name },
126
- };
127
- },
128
- }, plugin.name));
129
- disposers.push(toolService.addTool({
130
- name: 'kook_delete_role',
131
- description: '删除 KOOK 服务器中的角色',
132
- parameters: {
133
- type: 'object',
134
- properties: {
135
- bot: { type: 'string', description: 'Bot 名称' },
136
- guild_id: { type: 'string', description: '服务器 ID' },
137
- role_id: { type: 'string', description: '角色 ID' },
138
- },
139
- required: ['bot', 'guild_id', 'role_id'],
140
- },
141
- platforms: ['kook'],
142
- tags: ['kook'],
143
- execute: async (args) => {
144
- const bot = kook.bots.get(args.bot);
145
- if (!bot)
146
- throw new Error(`Bot ${args.bot} 不存在`);
147
- const success = await bot.deleteRole(args.guild_id, args.role_id);
148
- return { success, message: success ? `已删除角色 ${args.role_id}` : '删除角色失败' };
149
- },
150
- }, plugin.name));
151
- disposers.push(toolService.addTool({
152
- name: 'kook_blacklist',
153
- description: 'KOOK 服务器黑名单管理:添加/移除',
154
- parameters: {
155
- type: 'object',
156
- properties: {
157
- bot: { type: 'string', description: 'Bot 名称' },
158
- guild_id: { type: 'string', description: '服务器 ID' },
159
- action: { type: 'string', description: 'add|remove', enum: ['add', 'remove'] },
160
- user_id: { type: 'string', description: '用户 ID' },
161
- remark: { type: 'string', description: '备注(add 可选)' },
162
- },
163
- required: ['bot', 'guild_id', 'action', 'user_id'],
164
- },
165
- platforms: ['kook'],
166
- tags: ['kook'],
167
- execute: async (args) => {
168
- const bot = kook.bots.get(args.bot);
169
- if (!bot)
170
- throw new Error(`Bot ${args.bot} 不存在`);
171
- switch (args.action) {
172
- case 'add': {
173
- const success = await bot.addToBlacklist(args.guild_id, args.user_id, args.remark);
174
- return { success, message: success ? `已将 ${args.user_id} 加入黑名单` : '操作失败' };
175
- }
176
- case 'remove': {
177
- const success = await bot.removeFromBlacklist(args.guild_id, args.user_id);
178
- return { success, message: success ? `已将 ${args.user_id} 从黑名单移除` : '操作失败' };
179
- }
180
- default:
181
- return { success: false, message: `未知操作: ${args.action}` };
182
- }
183
- },
184
- }, plugin.name));
185
- return () => disposers.forEach(d => d());
186
- });
187
- // ── Web 控制台 ─────────────────────────────────────────────────────────
188
- useContext("web", (pageManager) => {
189
- pageManager.addEntry({
190
- id: "kook",
191
- development: path.resolve(import.meta.dirname, "../client/index.tsx"),
192
- production: path.resolve(import.meta.dirname, "../dist/index.js"),
193
- meta: { name: "KOOK" },
194
- });
195
- });
196
- useContext("router", "kook", (router, kook) => {
197
- router.get("/api/kook/bots", async (ctx) => {
198
- try {
199
- const bots = Array.from(kook.bots.values());
200
- const result = bots.map((bot) => {
201
- try {
202
- return {
203
- name: bot.$config.name,
204
- connected: bot.$connected || false,
205
- guildCount: bot.guilds?.size || 0,
206
- status: bot.$connected ? "online" : "offline",
207
- };
208
- }
209
- catch {
210
- return { name: bot.$config.name, connected: false, guildCount: 0, status: "error" };
211
- }
212
- });
213
- ctx.body = { success: true, data: result };
214
- }
215
- catch {
216
- ctx.status = 500;
217
- ctx.body = { success: false, error: "获取机器人数据失败" };
218
- }
219
- });
220
- // Bot 连接/断开
221
- router.post("/api/kook/bots/:name/connect", async (ctx) => {
222
- try {
223
- const bot = kook.bots.get(ctx.params.name);
224
- if (!bot) {
225
- ctx.status = 404;
226
- ctx.body = { success: false, error: "Bot 不存在" };
227
- return;
228
- }
229
- if (bot.$connected) {
230
- ctx.body = { success: true, message: "已经在线" };
231
- return;
232
- }
233
- await bot.$connect();
234
- ctx.body = { success: true, message: "连接成功" };
235
- }
236
- catch (e) {
237
- ctx.status = 500;
238
- ctx.body = { success: false, error: e?.message || "连接失败" };
239
- }
240
- });
241
- router.post("/api/kook/bots/:name/disconnect", async (ctx) => {
242
- try {
243
- const bot = kook.bots.get(ctx.params.name);
244
- if (!bot) {
245
- ctx.status = 404;
246
- ctx.body = { success: false, error: "Bot 不存在" };
247
- return;
248
- }
249
- if (!bot.$connected) {
250
- ctx.body = { success: true, message: "已经离线" };
251
- return;
252
- }
253
- await bot.$disconnect();
254
- ctx.body = { success: true, message: "已断开" };
255
- }
256
- catch (e) {
257
- ctx.status = 500;
258
- ctx.body = { success: false, error: e?.message || "断开失败" };
259
- }
260
- });
261
- // 角色列表
262
- router.get("/api/kook/bots/:name/guilds/:guildId/roles", async (ctx) => {
263
- try {
264
- const bot = kook.bots.get(ctx.params.name);
265
- if (!bot) {
266
- ctx.status = 404;
267
- ctx.body = { success: false, error: "Bot 不存在" };
268
- return;
269
- }
270
- if (!bot.$connected) {
271
- ctx.status = 400;
272
- ctx.body = { success: false, error: "Bot 未连接" };
273
- return;
274
- }
275
- const roles = await bot.getRoleList(ctx.params.guildId);
276
- ctx.body = {
277
- success: true,
278
- data: roles.map((r) => ({
279
- id: r.role_id,
280
- name: r.name,
281
- color: r.color,
282
- position: r.position,
283
- })),
284
- };
285
- }
286
- catch (e) {
287
- ctx.status = 500;
288
- ctx.body = { success: false, error: e?.message || "获取角色列表失败" };
289
- }
290
- });
291
- // 创建角色
292
- router.post("/api/kook/bots/:name/guilds/:guildId/roles", async (ctx) => {
293
- try {
294
- const bot = kook.bots.get(ctx.params.name);
295
- if (!bot) {
296
- ctx.status = 404;
297
- ctx.body = { success: false, error: "Bot 不存在" };
298
- return;
299
- }
300
- if (!bot.$connected) {
301
- ctx.status = 400;
302
- ctx.body = { success: false, error: "Bot 未连接" };
303
- return;
304
- }
305
- const { name } = ctx.request.body || {};
306
- if (!name) {
307
- ctx.status = 400;
308
- ctx.body = { success: false, error: "缺少角色名称" };
309
- return;
310
- }
311
- const role = await bot.createRole(ctx.params.guildId, name);
312
- ctx.body = { success: true, data: { id: role.role_id, name: role.name } };
313
- }
314
- catch (e) {
315
- ctx.status = 500;
316
- ctx.body = { success: false, error: e?.message || "创建角色失败" };
317
- }
318
- });
319
- // 删除角色
320
- router.delete("/api/kook/bots/:name/guilds/:guildId/roles/:roleId", async (ctx) => {
321
- try {
322
- const bot = kook.bots.get(ctx.params.name);
323
- if (!bot) {
324
- ctx.status = 404;
325
- ctx.body = { success: false, error: "Bot 不存在" };
326
- return;
327
- }
328
- if (!bot.$connected) {
329
- ctx.status = 400;
330
- ctx.body = { success: false, error: "Bot 未连接" };
331
- return;
332
- }
333
- const success = await bot.deleteRole(ctx.params.guildId, ctx.params.roleId);
334
- ctx.body = { success, message: success ? "角色已删除" : "删除失败" };
335
- }
336
- catch (e) {
337
- ctx.status = 500;
338
- ctx.body = { success: false, error: e?.message || "删除角色失败" };
339
- }
340
- });
341
- });
342
- //# sourceMappingURL=index.js.map
1
+ export { formatInboundContent, formatOutboundKmarkdown, resolveKookConfig, senderDisplayName, KookPermission, } from './protocol.js';
2
+ export { KookWebhookEndpoint, KookWebsocketEndpoint, } from './endpoint.js';
3
+ export { registerKookWebhookRoutes, handleKookWebhookRequest, } from './webhook.js';
4
+ export { defaultCreateClient, defaultCreateWebhookClient, normalizeKookMessage, } from './ws.js';
5
+ export { kookClient } from './client.js';
6
+ export { checkKookPlatformPermit, kookGroupPermitResolver, normalizeKookSenderForPermit, platformPermit, } from './platform-permit.js';
@@ -0,0 +1 @@
1
+ export declare const kookEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `kook.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
+ * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
+ */
5
+ import { createEndpointCommands } from 'zhin.js/adapter';
6
+ import { defineCommand } from 'zhin.js/command';
7
+ import { kookRuntimeStateToken } from './kook-runtime-state.js';
8
+ export const kookEndpointCommands = createEndpointCommands({
9
+ adapterKey: 'kook',
10
+ adapterDisplayName: 'KOOK',
11
+ fields: [
12
+ { key: 'token', required: true, env: true, description: 'KOOK bot token' },
13
+ { key: 'encrypt_key', env: true, description: 'webhook 加密密钥(connection: webhook)' },
14
+ { key: 'verify_token', env: true, description: 'webhook 验证 token(connection: webhook)' },
15
+ ],
16
+ running: (use) => use(kookRuntimeStateToken).endpoints.values(),
17
+ describeEntry: (entry) => `token: ${String(entry.token)}`,
18
+ }, defineCommand);
@@ -0,0 +1 @@
1
+ export declare const kookRuntimeStateToken: import("zhin.js").Token<import("@zhin.js/adapter").EndpointRuntimeState>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * KOOK 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `kook.endpoint` 命令共享(同一 owner generation)。
4
+ */
5
+ import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
+ export const kookRuntimeStateToken = defineEndpointRuntimeStateToken('kook');
@@ -0,0 +1,22 @@
1
+ /**
2
+ * KOOK platform permit — guild / channel 差异化门禁
3
+ */
4
+ import type { PermissionSubject } from '@zhin.js/permission';
5
+ import { KookPermission } from './protocol.js';
6
+ export declare function platformPermit(perm: string): string;
7
+ export declare function kookGroupPermitResolver(logicalPerm: string): string;
8
+ export interface KookSenderInfo {
9
+ id: string;
10
+ name: string;
11
+ permission?: KookPermission;
12
+ roles?: number[];
13
+ isGuildOwner?: boolean;
14
+ isAdmin?: boolean;
15
+ role?: string;
16
+ permissions?: string[];
17
+ }
18
+ export declare function normalizeKookSenderForPermit(info: KookSenderInfo, isChannel: boolean): {
19
+ role?: string;
20
+ permissions?: string[];
21
+ };
22
+ export declare function checkKookPlatformPermit(perm: string, subject: PermissionSubject): boolean;
@@ -0,0 +1,48 @@
1
+ import { KookPermission } from './protocol.js';
2
+ const ADAPTER = 'kook';
3
+ export function platformPermit(perm) {
4
+ return `platform(${ADAPTER},${perm})`;
5
+ }
6
+ const FACTORY_PERM_MAP = {
7
+ scene_admin: 'guild_admin',
8
+ scene_owner: 'guild_owner',
9
+ };
10
+ export function kookGroupPermitResolver(logicalPerm) {
11
+ return platformPermit(FACTORY_PERM_MAP[logicalPerm] ?? logicalPerm);
12
+ }
13
+ export function normalizeKookSenderForPermit(info, isChannel) {
14
+ const permissions = [];
15
+ if (info.roles?.length) {
16
+ permissions.push(...info.roles.map((r) => `role:${r}`));
17
+ }
18
+ if (info.isGuildOwner || info.permission === KookPermission.Owner) {
19
+ permissions.push('guild_owner', 'guild_admin');
20
+ return { role: 'owner', permissions };
21
+ }
22
+ if (info.permission === KookPermission.ChannelAdmin && isChannel) {
23
+ permissions.push('channel_admin', 'guild_admin');
24
+ return { role: 'channel_admin', permissions };
25
+ }
26
+ if (info.isAdmin || info.permission === KookPermission.Admin) {
27
+ permissions.push('guild_admin');
28
+ return { role: 'admin', permissions };
29
+ }
30
+ return { role: 'member', permissions };
31
+ }
32
+ export function checkKookPlatformPermit(perm, subject) {
33
+ const role = subject.sender?.role?.[0];
34
+ const permissions = subject.sender?.permissions ?? [];
35
+ const has = (t) => permissions.includes(t);
36
+ switch (perm) {
37
+ case 'guild_owner':
38
+ return role === 'owner' || has('guild_owner');
39
+ case 'guild_admin':
40
+ return role === 'owner' || role === 'admin' || role === 'channel_admin' || has('guild_admin') || has('channel_admin');
41
+ case 'channel_admin':
42
+ return role === 'owner' || role === 'admin' || role === 'channel_admin' || has('channel_admin') || has('guild_admin');
43
+ case 'manage_roles':
44
+ return role === 'owner' || role === 'admin' || has('guild_owner') || has('guild_admin');
45
+ default:
46
+ return false;
47
+ }
48
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * KOOK protocol helpers — no legacy Adapter/Endpoint / segment-mapper.
3
+ * Canonicalization is owned by gateway/core before endpoint.send.
4
+ */
5
+ import type { IncomingMessage } from 'node:http';
6
+ import type { ConversationRef } from '@zhin.js/im-contract';
7
+ export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'mark' | 'off';
8
+ export declare enum KookPermission {
9
+ Normal = 1,
10
+ Admin = 2,
11
+ Owner = 4,
12
+ ChannelAdmin = 5
13
+ }
14
+ /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
15
+ export interface KookAdapterConfig {
16
+ readonly id?: string;
17
+ readonly token?: string;
18
+ /** Default `websocket`. `webhook` requires httpHostToken + verify_token. */
19
+ readonly connection?: 'websocket' | 'webhook';
20
+ readonly webhookPath?: string;
21
+ readonly verify_token?: string;
22
+ readonly encrypt_key?: string;
23
+ readonly data_dir?: string;
24
+ readonly timeout?: number;
25
+ readonly max_retry?: number;
26
+ readonly ignore?: 'bot' | 'self';
27
+ readonly logLevel?: LogLevel;
28
+ /** Transitional: legacy root `endpoints[]` with `context: kook`. */
29
+ readonly endpoints?: ReadonlyArray<{
30
+ readonly context?: string;
31
+ readonly id?: string;
32
+ readonly token?: string;
33
+ readonly connection?: 'websocket' | 'webhook';
34
+ readonly webhookPath?: string;
35
+ readonly verify_token?: string;
36
+ readonly encrypt_key?: string;
37
+ readonly data_dir?: string;
38
+ readonly timeout?: number;
39
+ readonly max_retry?: number;
40
+ readonly ignore?: 'bot' | 'self';
41
+ readonly logLevel?: LogLevel;
42
+ }>;
43
+ }
44
+ export interface ResolvedKookWebsocketConfig {
45
+ readonly context: 'kook';
46
+ readonly connection: 'websocket';
47
+ readonly id: string;
48
+ readonly token: string;
49
+ readonly data_dir?: string;
50
+ readonly timeout: number;
51
+ readonly max_retry: number;
52
+ readonly ignore: 'bot' | 'self';
53
+ readonly logLevel: LogLevel;
54
+ }
55
+ export interface ResolvedKookWebhookConfig {
56
+ readonly context: 'kook';
57
+ readonly connection: 'webhook';
58
+ readonly id: string;
59
+ readonly token: string;
60
+ readonly webhookPath: string;
61
+ readonly verifyToken: string;
62
+ readonly encryptKey?: string;
63
+ readonly ignore: 'bot' | 'self';
64
+ readonly logLevel: LogLevel;
65
+ }
66
+ export interface KookWebhookEventData {
67
+ readonly channel_type?: string;
68
+ readonly type?: number;
69
+ readonly target_id?: string;
70
+ readonly author_id?: string;
71
+ readonly content?: string;
72
+ readonly msg_id?: string;
73
+ readonly msg_timestamp?: number;
74
+ readonly verify_token?: string;
75
+ readonly challenge?: string;
76
+ readonly extra?: {
77
+ readonly guild_id?: string;
78
+ readonly author?: {
79
+ readonly id?: string;
80
+ readonly username?: string;
81
+ readonly bot?: boolean;
82
+ readonly roles?: number[];
83
+ };
84
+ };
85
+ }
86
+ export interface KookWebhookFrame {
87
+ readonly s?: number;
88
+ readonly sn?: number;
89
+ readonly d?: KookWebhookEventData;
90
+ readonly encrypt?: string;
91
+ }
92
+ export type ResolvedKookConfig = ResolvedKookWebsocketConfig | ResolvedKookWebhookConfig;
93
+ export interface KookInboundMessage {
94
+ readonly id: string;
95
+ readonly content: string;
96
+ readonly channelKind: 'private' | 'channel';
97
+ readonly channelId: string;
98
+ readonly authorId: string;
99
+ readonly authorName: string;
100
+ readonly authorBot?: boolean;
101
+ readonly authorRoles?: number[];
102
+ readonly timestamp: number;
103
+ readonly guildId?: string;
104
+ readonly rawMessage?: string;
105
+ }
106
+ export interface KookWireSegment {
107
+ readonly type: string;
108
+ readonly data?: Record<string, unknown>;
109
+ }
110
+ export declare function resolveKookConfig(config?: KookAdapterConfig): ResolvedKookConfig;
111
+ /**
112
+ * 入站归一化 → ConversationRef:频道消息的所属 guild 进 `parent`(guild 容器
113
+ * 映射为 channel 容器);私聊(PERSON)无容器,直接 kind 'private'。
114
+ */
115
+ export declare function kookInboundConversation(endpointKey: string, msg: KookInboundMessage): ConversationRef;
116
+ export declare function senderDisplayName(msg: KookInboundMessage): string;
117
+ /** Build inbound text for OutboundMessageService.receive */
118
+ export declare function formatInboundContent(msg: KookInboundMessage): string;
119
+ /**
120
+ * KOOK @ 用户标记为 `(met)<userId>(met)`;content 含 `(met)<botId>(met)` 时视为 @ 机器人。
121
+ * botId 取 client 缓存的 self_id(/me 类接口),拿不到则不标注。
122
+ */
123
+ export declare function isKookBotMentioned(msg: KookInboundMessage, selfId?: string): boolean;
124
+ /**
125
+ * Wire-encode an already-rendered outbound payload into KOOK KMarkdown.
126
+ * Segment canonicalization is intentionally not done here.
127
+ */
128
+ export declare function formatOutboundKmarkdown(payload: unknown): string;
129
+ export declare function normalizeWebhookPath(path: string): string;
130
+ export declare function readTextBody(request: IncomingMessage, options?: {
131
+ readonly limit?: number;
132
+ }): Promise<string>;
133
+ export declare function readRequestBody(request: IncomingMessage, options?: {
134
+ readonly limit?: number;
135
+ }): Promise<Buffer>;
136
+ export declare function padKookEncryptKey(key: string): Buffer;
137
+ export declare function decryptKookWebhookPayload(encrypted: string, encryptKey: string): Buffer;
138
+ export declare function parseKookWebhookBody(rawBody: Buffer, encryptKey?: string): KookWebhookFrame;
139
+ export declare function isKookWebhookChallenge(event: KookWebhookEventData): boolean;
140
+ export declare function verifyKookWebhookToken(expected: string, actual?: string): boolean;
141
+ export declare function normalizeKookWebhookEvent(event: KookWebhookEventData, options?: {
142
+ readonly ignore?: 'bot' | 'self';
143
+ readonly selfId?: string;
144
+ }): KookInboundMessage | null;