@zhin.js/adapter-kook 5.0.1 → 5.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.
- package/CHANGELOG.md +60 -0
- package/README.md +58 -451
- package/adapters/kook.ts +46 -0
- package/agent/tools/blacklist.ts +33 -0
- package/agent/tools/create_role.ts +25 -0
- package/agent/tools/delete_role.ts +21 -0
- package/agent/tools/grant_role.ts +22 -0
- package/agent/tools/list_roles.ts +27 -0
- package/agent/tools/revoke_role.ts +22 -0
- package/lib/endpoint.d.ts +80 -151
- package/lib/endpoint.js +260 -736
- package/lib/index.d.ts +6 -18
- package/lib/index.js +6 -350
- package/lib/kook-agent-deps.d.ts +29 -0
- package/lib/kook-agent-deps.js +30 -0
- package/lib/platform-permit.d.ts +12 -3
- package/lib/platform-permit.js +5 -3
- package/lib/protocol.d.ts +147 -0
- package/lib/protocol.js +279 -0
- package/lib/webhook.d.ts +15 -0
- package/lib/webhook.js +76 -0
- package/lib/ws.d.ts +42 -0
- package/lib/ws.js +63 -0
- package/package.json +47 -33
- package/plugin.ts +13 -0
- package/schema.json +55 -0
- package/src/endpoint.ts +287 -866
- package/src/index.ts +55 -331
- package/src/kook-agent-deps.ts +55 -0
- package/src/platform-permit.ts +13 -4
- package/src/protocol.ts +429 -0
- package/src/webhook.ts +116 -0
- package/src/ws.ts +120 -0
- package/client/Dashboard.tsx +0 -255
- package/client/index.tsx +0 -11
- package/client/tsconfig.json +0 -7
- package/client/utils/api.ts +0 -30
- package/dist/index.js +0 -31
- package/lib/adapter.d.ts +0 -30
- package/lib/adapter.d.ts.map +0 -1
- package/lib/adapter.js +0 -67
- package/lib/adapter.js.map +0 -1
- package/lib/endpoint.d.ts.map +0 -1
- package/lib/endpoint.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/kook-asset-upload.d.ts +0 -12
- package/lib/kook-asset-upload.d.ts.map +0 -1
- package/lib/kook-asset-upload.js +0 -46
- package/lib/kook-asset-upload.js.map +0 -1
- package/lib/kook-inbound.d.ts +0 -6
- package/lib/kook-inbound.d.ts.map +0 -1
- package/lib/kook-inbound.js +0 -22
- package/lib/kook-inbound.js.map +0 -1
- package/lib/kook-msg-route.d.ts +0 -34
- package/lib/kook-msg-route.d.ts.map +0 -1
- package/lib/kook-msg-route.js +0 -106
- package/lib/kook-msg-route.js.map +0 -1
- package/lib/kook-side-events.d.ts +0 -46
- package/lib/kook-side-events.d.ts.map +0 -1
- package/lib/kook-side-events.js +0 -189
- package/lib/kook-side-events.js.map +0 -1
- package/lib/outbound-keyboard.d.ts +0 -13
- package/lib/outbound-keyboard.d.ts.map +0 -1
- package/lib/outbound-keyboard.js +0 -63
- package/lib/outbound-keyboard.js.map +0 -1
- package/lib/outbound-media.d.ts +0 -10
- package/lib/outbound-media.d.ts.map +0 -1
- package/lib/outbound-media.js +0 -42
- package/lib/outbound-media.js.map +0 -1
- package/lib/outbound-sendable.d.ts +0 -12
- package/lib/outbound-sendable.d.ts.map +0 -1
- package/lib/outbound-sendable.js +0 -64
- package/lib/outbound-sendable.js.map +0 -1
- package/lib/platform-permit.d.ts.map +0 -1
- package/lib/platform-permit.js.map +0 -1
- package/lib/segment-mapper.d.ts +0 -2
- package/lib/segment-mapper.d.ts.map +0 -1
- package/lib/segment-mapper.js +0 -2
- package/lib/segment-mapper.js.map +0 -1
- package/lib/types.d.ts +0 -54
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js +0 -8
- package/lib/types.js.map +0 -1
- package/plugin.yml +0 -3
- package/src/adapter.ts +0 -76
- package/src/kook-asset-upload.ts +0 -55
- package/src/kook-inbound.ts +0 -22
- package/src/kook-msg-route.ts +0 -122
- package/src/kook-side-events.ts +0 -250
- package/src/outbound-keyboard.ts +0 -78
- package/src/outbound-media.ts +0 -67
- package/src/outbound-sendable.ts +0 -73
- package/src/segment-mapper.ts +0 -1
- package/src/types.ts +0 -59
- /package/{skills/kook → agent}/PERMITS.md +0 -0
- /package/{skills/kook/SKILL.md → agent/skills/kook.md} +0 -0
package/lib/index.d.ts
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
declare module "zhin.js" {
|
|
11
|
-
interface Adapters {
|
|
12
|
-
kook: KookAdapter;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
export * from "./types.js";
|
|
16
|
-
export { KookEndpoint } from "./endpoint.js";
|
|
17
|
-
export { KookAdapter } from "./adapter.js";
|
|
18
|
-
//# sourceMappingURL=index.d.ts.map
|
|
1
|
+
export { formatInboundContent, formatInboundTarget, formatOutboundKmarkdown, parseSendTarget, resolveKookConfig, senderDisplayName, KookPermission, type KookAdapterConfig, type KookInboundMessage, type KookWireSegment, type LogLevel, type ParsedSendTarget, 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 { getKookAgentDeps, registerKookAgentEndpoint, setKookAgentDeps, type KookAgentDeps, type KookAgentEndpoint, } from './kook-agent-deps.js';
|
|
6
|
+
export { checkKookPlatformPermit, kookGroupPermitResolver, normalizeKookSenderForPermit, platformPermit, registerKookPlatformPermitChecker, type KookSenderInfo, } from './platform-permit.js';
|
package/lib/index.js
CHANGED
|
@@ -1,350 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import { kookGroupPermitResolver, platformPermit, registerKookPlatformPermitChecker } from "./platform-permit.js";
|
|
8
|
-
export * from "./types.js";
|
|
9
|
-
export { KookEndpoint } from "./endpoint.js";
|
|
10
|
-
export { KookAdapter } from "./adapter.js";
|
|
11
|
-
const plugin = usePlugin();
|
|
12
|
-
const { provide, useContext } = plugin;
|
|
13
|
-
provide({
|
|
14
|
-
name: "kook",
|
|
15
|
-
description: "KOOK Adapter",
|
|
16
|
-
mounted: async (p) => {
|
|
17
|
-
const adapter = new KookAdapter(p);
|
|
18
|
-
await adapter.start();
|
|
19
|
-
return adapter;
|
|
20
|
-
},
|
|
21
|
-
dispose: async (adapter) => {
|
|
22
|
-
await adapter.stop();
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
useContext('tool', 'kook', (toolService, kook) => {
|
|
26
|
-
const disposers = [];
|
|
27
|
-
disposers.push(registerKookPlatformPermitChecker());
|
|
28
|
-
const sceneTools = createSceneManagementTools(kook, 'kook', { permitResolver: kookGroupPermitResolver, registerChecker: false });
|
|
29
|
-
disposers.push(...sceneTools.map(t => toolService.addTool(t, plugin.name)));
|
|
30
|
-
disposers.push(toolService.addTool({
|
|
31
|
-
name: 'kook_grant_role',
|
|
32
|
-
description: '给用户授予 KOOK 服务器角色',
|
|
33
|
-
parameters: {
|
|
34
|
-
type: 'object',
|
|
35
|
-
properties: {
|
|
36
|
-
endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
|
|
37
|
-
guild_id: { type: 'string', description: '服务器 ID' },
|
|
38
|
-
user_id: { type: 'string', description: '用户 ID' },
|
|
39
|
-
role_id: { type: 'string', description: '角色 ID' },
|
|
40
|
-
},
|
|
41
|
-
required: ['endpoint_id', 'guild_id', 'user_id', 'role_id'],
|
|
42
|
-
},
|
|
43
|
-
platforms: ['kook'],
|
|
44
|
-
tags: ['kook'],
|
|
45
|
-
permissions: [platformPermit('manage_roles')],
|
|
46
|
-
execute: async (args) => {
|
|
47
|
-
const endpoint = kook.endpoints.get(args.endpoint_id);
|
|
48
|
-
if (!endpoint)
|
|
49
|
-
throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
50
|
-
const success = await endpoint.grantRole(args.guild_id, args.user_id, args.role_id);
|
|
51
|
-
return { success, message: success ? `已授予用户 ${args.user_id} 角色 ${args.role_id}` : '授予角色失败' };
|
|
52
|
-
},
|
|
53
|
-
}, plugin.name));
|
|
54
|
-
disposers.push(toolService.addTool({
|
|
55
|
-
name: 'kook_revoke_role',
|
|
56
|
-
description: '撤销用户的 KOOK 服务器角色',
|
|
57
|
-
parameters: {
|
|
58
|
-
type: 'object',
|
|
59
|
-
properties: {
|
|
60
|
-
endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
|
|
61
|
-
guild_id: { type: 'string', description: '服务器 ID' },
|
|
62
|
-
user_id: { type: 'string', description: '用户 ID' },
|
|
63
|
-
role_id: { type: 'string', description: '角色 ID' },
|
|
64
|
-
},
|
|
65
|
-
required: ['endpoint_id', 'guild_id', 'user_id', 'role_id'],
|
|
66
|
-
},
|
|
67
|
-
platforms: ['kook'],
|
|
68
|
-
tags: ['kook'],
|
|
69
|
-
permissions: [platformPermit('manage_roles')],
|
|
70
|
-
execute: async (args) => {
|
|
71
|
-
const endpoint = kook.endpoints.get(args.endpoint_id);
|
|
72
|
-
if (!endpoint)
|
|
73
|
-
throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
74
|
-
const success = await endpoint.revokeRole(args.guild_id, args.user_id, args.role_id);
|
|
75
|
-
return { success, message: success ? `已撤销用户 ${args.user_id} 的角色 ${args.role_id}` : '撤销角色失败' };
|
|
76
|
-
},
|
|
77
|
-
}, plugin.name));
|
|
78
|
-
disposers.push(toolService.addTool({
|
|
79
|
-
name: 'kook_list_roles',
|
|
80
|
-
description: '获取 KOOK 服务器的角色列表',
|
|
81
|
-
parameters: {
|
|
82
|
-
type: 'object',
|
|
83
|
-
properties: {
|
|
84
|
-
endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
|
|
85
|
-
guild_id: { type: 'string', description: '服务器 ID' },
|
|
86
|
-
},
|
|
87
|
-
required: ['endpoint_id', 'guild_id'],
|
|
88
|
-
},
|
|
89
|
-
platforms: ['kook'],
|
|
90
|
-
tags: ['kook'],
|
|
91
|
-
execute: async (args) => {
|
|
92
|
-
const endpoint = kook.endpoints.get(args.endpoint_id);
|
|
93
|
-
if (!endpoint)
|
|
94
|
-
throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
95
|
-
const roles = await endpoint.getRoleList(args.guild_id);
|
|
96
|
-
return {
|
|
97
|
-
roles: roles.map((r) => ({
|
|
98
|
-
id: r.role_id,
|
|
99
|
-
name: r.name,
|
|
100
|
-
color: r.color,
|
|
101
|
-
position: r.position,
|
|
102
|
-
permissions: r.permissions,
|
|
103
|
-
})),
|
|
104
|
-
count: roles.length,
|
|
105
|
-
};
|
|
106
|
-
},
|
|
107
|
-
}, plugin.name));
|
|
108
|
-
disposers.push(toolService.addTool({
|
|
109
|
-
name: 'kook_create_role',
|
|
110
|
-
description: '在 KOOK 服务器中创建新角色',
|
|
111
|
-
parameters: {
|
|
112
|
-
type: 'object',
|
|
113
|
-
properties: {
|
|
114
|
-
endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
|
|
115
|
-
guild_id: { type: 'string', description: '服务器 ID' },
|
|
116
|
-
name: { type: 'string', description: '角色名称' },
|
|
117
|
-
},
|
|
118
|
-
required: ['endpoint_id', 'guild_id', 'name'],
|
|
119
|
-
},
|
|
120
|
-
platforms: ['kook'],
|
|
121
|
-
tags: ['kook'],
|
|
122
|
-
permissions: [platformPermit('guild_owner')],
|
|
123
|
-
execute: async (args) => {
|
|
124
|
-
const endpoint = kook.endpoints.get(args.endpoint_id);
|
|
125
|
-
if (!endpoint)
|
|
126
|
-
throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
127
|
-
const role = await endpoint.createRole(args.guild_id, args.name);
|
|
128
|
-
return {
|
|
129
|
-
success: true,
|
|
130
|
-
message: `已创建角色 "${args.name}"`,
|
|
131
|
-
role: { id: role.role_id, name: role.name },
|
|
132
|
-
};
|
|
133
|
-
},
|
|
134
|
-
}, plugin.name));
|
|
135
|
-
disposers.push(toolService.addTool({
|
|
136
|
-
name: 'kook_delete_role',
|
|
137
|
-
description: '删除 KOOK 服务器中的角色',
|
|
138
|
-
parameters: {
|
|
139
|
-
type: 'object',
|
|
140
|
-
properties: {
|
|
141
|
-
endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
|
|
142
|
-
guild_id: { type: 'string', description: '服务器 ID' },
|
|
143
|
-
role_id: { type: 'string', description: '角色 ID' },
|
|
144
|
-
},
|
|
145
|
-
required: ['endpoint_id', 'guild_id', 'role_id'],
|
|
146
|
-
},
|
|
147
|
-
platforms: ['kook'],
|
|
148
|
-
tags: ['kook'],
|
|
149
|
-
permissions: [platformPermit('guild_owner')],
|
|
150
|
-
execute: async (args) => {
|
|
151
|
-
const endpoint = kook.endpoints.get(args.endpoint_id);
|
|
152
|
-
if (!endpoint)
|
|
153
|
-
throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
154
|
-
const success = await endpoint.deleteRole(args.guild_id, args.role_id);
|
|
155
|
-
return { success, message: success ? `已删除角色 ${args.role_id}` : '删除角色失败' };
|
|
156
|
-
},
|
|
157
|
-
}, plugin.name));
|
|
158
|
-
disposers.push(toolService.addTool({
|
|
159
|
-
name: 'kook_blacklist',
|
|
160
|
-
description: 'KOOK 服务器黑名单管理:添加/移除',
|
|
161
|
-
parameters: {
|
|
162
|
-
type: 'object',
|
|
163
|
-
properties: {
|
|
164
|
-
endpoint_id: { type: 'string', description: 'Endpoint 名称', contextKey: 'endpointId' },
|
|
165
|
-
guild_id: { type: 'string', description: '服务器 ID' },
|
|
166
|
-
action: { type: 'string', description: 'add|remove', enum: ['add', 'remove'] },
|
|
167
|
-
user_id: { type: 'string', description: '用户 ID' },
|
|
168
|
-
remark: { type: 'string', description: '备注(add 可选)' },
|
|
169
|
-
},
|
|
170
|
-
required: ['endpoint_id', 'guild_id', 'action', 'user_id'],
|
|
171
|
-
},
|
|
172
|
-
platforms: ['kook'],
|
|
173
|
-
tags: ['kook'],
|
|
174
|
-
permissions: [platformPermit('guild_admin')],
|
|
175
|
-
execute: async (args) => {
|
|
176
|
-
const endpoint = kook.endpoints.get(args.endpoint_id);
|
|
177
|
-
if (!endpoint)
|
|
178
|
-
throw new Error(`Endpoint ${args.endpoint_id} 不存在`);
|
|
179
|
-
switch (args.action) {
|
|
180
|
-
case 'add': {
|
|
181
|
-
const success = await endpoint.addToBlacklist(args.guild_id, args.user_id, args.remark);
|
|
182
|
-
return { success, message: success ? `已将 ${args.user_id} 加入黑名单` : '操作失败' };
|
|
183
|
-
}
|
|
184
|
-
case 'remove': {
|
|
185
|
-
const success = await endpoint.removeFromBlacklist(args.guild_id, args.user_id);
|
|
186
|
-
return { success, message: success ? `已将 ${args.user_id} 从黑名单移除` : '操作失败' };
|
|
187
|
-
}
|
|
188
|
-
default:
|
|
189
|
-
return { success: false, message: `未知操作: ${args.action}` };
|
|
190
|
-
}
|
|
191
|
-
},
|
|
192
|
-
}, plugin.name));
|
|
193
|
-
return () => disposers.forEach(d => d());
|
|
194
|
-
});
|
|
195
|
-
// ── Web 控制台 ─────────────────────────────────────────────────────────
|
|
196
|
-
useContext("web", (pageManager) => {
|
|
197
|
-
pageManager.addEntry({
|
|
198
|
-
id: "kook",
|
|
199
|
-
development: path.resolve(import.meta.dirname, "../client/index.tsx"),
|
|
200
|
-
production: path.resolve(import.meta.dirname, "../dist/index.js"),
|
|
201
|
-
meta: { name: "KOOK" },
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
useContext("router", "kook", (router, kook) => {
|
|
205
|
-
router.get("/api/kook/endpoints", async (ctx) => {
|
|
206
|
-
try {
|
|
207
|
-
const endpoints = Array.from(kook.endpoints.values());
|
|
208
|
-
const result = endpoints.map((endpoint) => {
|
|
209
|
-
try {
|
|
210
|
-
return {
|
|
211
|
-
name: endpoint.$config.name,
|
|
212
|
-
connected: endpoint.$connected || false,
|
|
213
|
-
guildCount: endpoint.guilds?.size || 0,
|
|
214
|
-
status: endpoint.$connected ? "online" : "offline",
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
catch {
|
|
218
|
-
return { name: endpoint.$config.name, connected: false, guildCount: 0, status: "error" };
|
|
219
|
-
}
|
|
220
|
-
});
|
|
221
|
-
ctx.body = { success: true, data: result };
|
|
222
|
-
}
|
|
223
|
-
catch {
|
|
224
|
-
ctx.status = 500;
|
|
225
|
-
ctx.body = { success: false, error: "获取 Endpoint 数据失败" };
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
// Endpoint 连接/断开
|
|
229
|
-
router.post("/api/kook/endpoints/:name/connect", async (ctx) => {
|
|
230
|
-
try {
|
|
231
|
-
const endpoint = kook.endpoints.get(ctx.params.name);
|
|
232
|
-
if (!endpoint) {
|
|
233
|
-
ctx.status = 404;
|
|
234
|
-
ctx.body = { success: false, error: "Endpoint 不存在" };
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
if (endpoint.$connected) {
|
|
238
|
-
ctx.body = { success: true, message: "已经在线" };
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
await endpoint.$connect();
|
|
242
|
-
ctx.body = { success: true, message: "连接成功" };
|
|
243
|
-
}
|
|
244
|
-
catch (e) {
|
|
245
|
-
ctx.status = 500;
|
|
246
|
-
ctx.body = { success: false, error: e instanceof Error ? e.message : "连接失败" };
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
router.post("/api/kook/endpoints/:name/disconnect", async (ctx) => {
|
|
250
|
-
try {
|
|
251
|
-
const endpoint = kook.endpoints.get(ctx.params.name);
|
|
252
|
-
if (!endpoint) {
|
|
253
|
-
ctx.status = 404;
|
|
254
|
-
ctx.body = { success: false, error: "Endpoint 不存在" };
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
if (!endpoint.$connected) {
|
|
258
|
-
ctx.body = { success: true, message: "已经离线" };
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
await endpoint.$disconnect();
|
|
262
|
-
ctx.body = { success: true, message: "已断开" };
|
|
263
|
-
}
|
|
264
|
-
catch (e) {
|
|
265
|
-
ctx.status = 500;
|
|
266
|
-
ctx.body = { success: false, error: e instanceof Error ? e.message : "断开失败" };
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
// 角色列表
|
|
270
|
-
router.get("/api/kook/endpoints/:name/guilds/:guildId/roles", async (ctx) => {
|
|
271
|
-
try {
|
|
272
|
-
const endpoint = kook.endpoints.get(ctx.params.name);
|
|
273
|
-
if (!endpoint) {
|
|
274
|
-
ctx.status = 404;
|
|
275
|
-
ctx.body = { success: false, error: "Endpoint 不存在" };
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
if (!endpoint.$connected) {
|
|
279
|
-
ctx.status = 400;
|
|
280
|
-
ctx.body = { success: false, error: "Endpoint 未连接" };
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
const roles = await endpoint.getRoleList(ctx.params.guildId);
|
|
284
|
-
ctx.body = {
|
|
285
|
-
success: true,
|
|
286
|
-
data: roles.map((r) => ({
|
|
287
|
-
id: r.role_id,
|
|
288
|
-
name: r.name,
|
|
289
|
-
color: r.color,
|
|
290
|
-
position: r.position,
|
|
291
|
-
})),
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
catch (e) {
|
|
295
|
-
ctx.status = 500;
|
|
296
|
-
ctx.body = { success: false, error: e instanceof Error ? e.message : "获取角色列表失败" };
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
// 创建角色
|
|
300
|
-
router.post("/api/kook/endpoints/:name/guilds/:guildId/roles", async (ctx) => {
|
|
301
|
-
try {
|
|
302
|
-
const endpoint = kook.endpoints.get(ctx.params.name);
|
|
303
|
-
if (!endpoint) {
|
|
304
|
-
ctx.status = 404;
|
|
305
|
-
ctx.body = { success: false, error: "Endpoint 不存在" };
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
if (!endpoint.$connected) {
|
|
309
|
-
ctx.status = 400;
|
|
310
|
-
ctx.body = { success: false, error: "Endpoint 未连接" };
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
const { name } = ctx.request.body || {};
|
|
314
|
-
if (!name) {
|
|
315
|
-
ctx.status = 400;
|
|
316
|
-
ctx.body = { success: false, error: "缺少角色名称" };
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
const role = await endpoint.createRole(ctx.params.guildId, name);
|
|
320
|
-
ctx.body = { success: true, data: { id: role.role_id, name: role.name } };
|
|
321
|
-
}
|
|
322
|
-
catch (e) {
|
|
323
|
-
ctx.status = 500;
|
|
324
|
-
ctx.body = { success: false, error: e instanceof Error ? e.message : "创建角色失败" };
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
// 删除角色
|
|
328
|
-
router.delete("/api/kook/endpoints/:name/guilds/:guildId/roles/:roleId", async (ctx) => {
|
|
329
|
-
try {
|
|
330
|
-
const endpoint = kook.endpoints.get(ctx.params.name);
|
|
331
|
-
if (!endpoint) {
|
|
332
|
-
ctx.status = 404;
|
|
333
|
-
ctx.body = { success: false, error: "Endpoint 不存在" };
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
if (!endpoint.$connected) {
|
|
337
|
-
ctx.status = 400;
|
|
338
|
-
ctx.body = { success: false, error: "Endpoint 未连接" };
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
const success = await endpoint.deleteRole(ctx.params.guildId, ctx.params.roleId);
|
|
342
|
-
ctx.body = { success, message: success ? "角色已删除" : "删除失败" };
|
|
343
|
-
}
|
|
344
|
-
catch (e) {
|
|
345
|
-
ctx.status = 500;
|
|
346
|
-
ctx.body = { success: false, error: e instanceof Error ? e.message : "删除角色失败" };
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
});
|
|
350
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export { formatInboundContent, formatInboundTarget, formatOutboundKmarkdown, parseSendTarget, 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 { getKookAgentDeps, registerKookAgentEndpoint, setKookAgentDeps, } from './kook-agent-deps.js';
|
|
6
|
+
export { checkKookPlatformPermit, kookGroupPermitResolver, normalizeKookSenderForPermit, platformPermit, registerKookPlatformPermitChecker, } from './platform-permit.js';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent tool deps for kook.
|
|
3
|
+
* Endpoints register themselves on start; tools look up by config name / endpoint id.
|
|
4
|
+
*/
|
|
5
|
+
export interface KookAgentEndpoint {
|
|
6
|
+
getRoleList(guildId: string): Promise<Array<{
|
|
7
|
+
role_id: string | number;
|
|
8
|
+
name: string;
|
|
9
|
+
color?: number;
|
|
10
|
+
position?: number;
|
|
11
|
+
permissions?: unknown;
|
|
12
|
+
}>>;
|
|
13
|
+
createRole(guildId: string, name: string): Promise<{
|
|
14
|
+
role_id: string | number;
|
|
15
|
+
name: string;
|
|
16
|
+
}>;
|
|
17
|
+
deleteRole(guildId: string, roleId: string): Promise<boolean>;
|
|
18
|
+
grantRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
19
|
+
revokeRole(guildId: string, userId: string, roleId: string): Promise<boolean>;
|
|
20
|
+
addToBlacklist(guildId: string, userId: string, remark?: string): Promise<boolean>;
|
|
21
|
+
removeFromBlacklist(guildId: string, userId: string): Promise<boolean>;
|
|
22
|
+
}
|
|
23
|
+
export interface KookAgentDeps {
|
|
24
|
+
getEndpoint: (endpointId: string) => KookAgentEndpoint;
|
|
25
|
+
}
|
|
26
|
+
export declare function registerKookAgentEndpoint(endpointId: string, endpoint: KookAgentEndpoint): () => void;
|
|
27
|
+
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
28
|
+
export declare function setKookAgentDeps(deps: KookAgentDeps | null): void;
|
|
29
|
+
export declare function getKookAgentDeps(): KookAgentDeps;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent tool deps for kook.
|
|
3
|
+
* Endpoints register themselves on start; tools look up by config name / endpoint id.
|
|
4
|
+
*/
|
|
5
|
+
const endpoints = new Map();
|
|
6
|
+
let override = null;
|
|
7
|
+
export function registerKookAgentEndpoint(endpointId, endpoint) {
|
|
8
|
+
endpoints.set(endpointId, endpoint);
|
|
9
|
+
return () => {
|
|
10
|
+
if (endpoints.get(endpointId) === endpoint) {
|
|
11
|
+
endpoints.delete(endpointId);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** Optional override used by tests / transitional callers. Pass `null` to clear. */
|
|
16
|
+
export function setKookAgentDeps(deps) {
|
|
17
|
+
override = deps;
|
|
18
|
+
}
|
|
19
|
+
export function getKookAgentDeps() {
|
|
20
|
+
if (override)
|
|
21
|
+
return override;
|
|
22
|
+
return {
|
|
23
|
+
getEndpoint(endpointId) {
|
|
24
|
+
const registered = endpoints.get(endpointId);
|
|
25
|
+
if (!registered)
|
|
26
|
+
throw new Error(`Endpoint ${endpointId} 不存在`);
|
|
27
|
+
return registered;
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
package/lib/platform-permit.d.ts
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* KOOK platform permit — guild / channel 差异化门禁
|
|
3
3
|
*/
|
|
4
|
-
import type
|
|
5
|
-
import
|
|
4
|
+
import { type Message } from '@zhin.js/core';
|
|
5
|
+
import { KookPermission } from './protocol.js';
|
|
6
6
|
export declare function platformPermit(perm: string): string;
|
|
7
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
|
+
}
|
|
8
18
|
export declare function normalizeKookSenderForPermit(info: KookSenderInfo, isChannel: boolean): {
|
|
9
19
|
role?: string;
|
|
10
20
|
permissions?: string[];
|
|
11
21
|
};
|
|
12
22
|
export declare function checkKookPlatformPermit(perm: string, message: Message<any>): boolean;
|
|
13
23
|
export declare function registerKookPlatformPermitChecker(): () => void;
|
|
14
|
-
//# sourceMappingURL=platform-permit.d.ts.map
|
package/lib/platform-permit.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* KOOK platform permit — guild / channel 差异化门禁
|
|
3
|
+
*/
|
|
4
|
+
import { registerPlatformPermitChecker } from '@zhin.js/core';
|
|
5
|
+
import { KookPermission } from './protocol.js';
|
|
3
6
|
const ADAPTER = 'kook';
|
|
4
7
|
export function platformPermit(perm) {
|
|
5
8
|
return `platform(${ADAPTER},${perm})`;
|
|
@@ -60,4 +63,3 @@ export function checkKookPlatformPermit(perm, message) {
|
|
|
60
63
|
export function registerKookPlatformPermitChecker() {
|
|
61
64
|
return registerPlatformPermitChecker(ADAPTER, checkKookPlatformPermit);
|
|
62
65
|
}
|
|
63
|
-
//# sourceMappingURL=platform-permit.js.map
|
|
@@ -0,0 +1,147 @@
|
|
|
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
|
+
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'mark' | 'off';
|
|
7
|
+
export declare enum KookPermission {
|
|
8
|
+
Normal = 1,
|
|
9
|
+
Admin = 2,
|
|
10
|
+
Owner = 4,
|
|
11
|
+
ChannelAdmin = 5
|
|
12
|
+
}
|
|
13
|
+
/** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
|
|
14
|
+
export interface KookAdapterConfig {
|
|
15
|
+
readonly name?: string;
|
|
16
|
+
readonly token?: string;
|
|
17
|
+
/** Default `websocket`. `webhook` requires httpHostToken + verify_token. */
|
|
18
|
+
readonly connection?: 'websocket' | 'webhook';
|
|
19
|
+
readonly webhookPath?: string;
|
|
20
|
+
readonly verify_token?: string;
|
|
21
|
+
readonly encrypt_key?: string;
|
|
22
|
+
readonly data_dir?: string;
|
|
23
|
+
readonly timeout?: number;
|
|
24
|
+
readonly max_retry?: number;
|
|
25
|
+
readonly ignore?: 'bot' | 'self';
|
|
26
|
+
readonly logLevel?: LogLevel;
|
|
27
|
+
/** Transitional: legacy root `endpoints[]` with `context: kook`. */
|
|
28
|
+
readonly endpoints?: ReadonlyArray<{
|
|
29
|
+
readonly context?: string;
|
|
30
|
+
readonly name?: string;
|
|
31
|
+
readonly token?: string;
|
|
32
|
+
readonly connection?: 'websocket' | 'webhook';
|
|
33
|
+
readonly webhookPath?: string;
|
|
34
|
+
readonly verify_token?: string;
|
|
35
|
+
readonly encrypt_key?: string;
|
|
36
|
+
readonly data_dir?: string;
|
|
37
|
+
readonly timeout?: number;
|
|
38
|
+
readonly max_retry?: number;
|
|
39
|
+
readonly ignore?: 'bot' | 'self';
|
|
40
|
+
readonly logLevel?: LogLevel;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
export interface ResolvedKookWebsocketConfig {
|
|
44
|
+
readonly context: 'kook';
|
|
45
|
+
readonly connection: 'websocket';
|
|
46
|
+
readonly name: string;
|
|
47
|
+
readonly token: string;
|
|
48
|
+
readonly data_dir?: string;
|
|
49
|
+
readonly timeout: number;
|
|
50
|
+
readonly max_retry: number;
|
|
51
|
+
readonly ignore: 'bot' | 'self';
|
|
52
|
+
readonly logLevel: LogLevel;
|
|
53
|
+
}
|
|
54
|
+
export interface ResolvedKookWebhookConfig {
|
|
55
|
+
readonly context: 'kook';
|
|
56
|
+
readonly connection: 'webhook';
|
|
57
|
+
readonly name: string;
|
|
58
|
+
readonly token: string;
|
|
59
|
+
readonly webhookPath: string;
|
|
60
|
+
readonly verifyToken: string;
|
|
61
|
+
readonly encryptKey?: string;
|
|
62
|
+
readonly ignore: 'bot' | 'self';
|
|
63
|
+
readonly logLevel: LogLevel;
|
|
64
|
+
}
|
|
65
|
+
export interface KookWebhookEventData {
|
|
66
|
+
readonly channel_type?: string;
|
|
67
|
+
readonly type?: number;
|
|
68
|
+
readonly target_id?: string;
|
|
69
|
+
readonly author_id?: string;
|
|
70
|
+
readonly content?: string;
|
|
71
|
+
readonly msg_id?: string;
|
|
72
|
+
readonly msg_timestamp?: number;
|
|
73
|
+
readonly verify_token?: string;
|
|
74
|
+
readonly challenge?: string;
|
|
75
|
+
readonly extra?: {
|
|
76
|
+
readonly guild_id?: string;
|
|
77
|
+
readonly author?: {
|
|
78
|
+
readonly id?: string;
|
|
79
|
+
readonly username?: string;
|
|
80
|
+
readonly bot?: boolean;
|
|
81
|
+
readonly roles?: number[];
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export interface KookWebhookFrame {
|
|
86
|
+
readonly s?: number;
|
|
87
|
+
readonly sn?: number;
|
|
88
|
+
readonly d?: KookWebhookEventData;
|
|
89
|
+
readonly encrypt?: string;
|
|
90
|
+
}
|
|
91
|
+
export type ResolvedKookConfig = ResolvedKookWebsocketConfig | ResolvedKookWebhookConfig;
|
|
92
|
+
export interface KookInboundMessage {
|
|
93
|
+
readonly id: string;
|
|
94
|
+
readonly content: string;
|
|
95
|
+
readonly channelKind: 'private' | 'channel';
|
|
96
|
+
readonly channelId: string;
|
|
97
|
+
readonly authorId: string;
|
|
98
|
+
readonly authorName: string;
|
|
99
|
+
readonly authorBot?: boolean;
|
|
100
|
+
readonly authorRoles?: number[];
|
|
101
|
+
readonly timestamp: number;
|
|
102
|
+
readonly guildId?: string;
|
|
103
|
+
readonly rawMessage?: string;
|
|
104
|
+
}
|
|
105
|
+
export interface KookWireSegment {
|
|
106
|
+
readonly type: string;
|
|
107
|
+
readonly data?: Record<string, unknown>;
|
|
108
|
+
}
|
|
109
|
+
export interface ParsedSendTarget {
|
|
110
|
+
readonly kind: 'private' | 'channel';
|
|
111
|
+
readonly id: string;
|
|
112
|
+
}
|
|
113
|
+
export declare function resolveKookConfig(config?: KookAdapterConfig): ResolvedKookConfig;
|
|
114
|
+
/**
|
|
115
|
+
* Gateway reply target:`private:uid` / `channel:cid`,便于 send() 还原 API。
|
|
116
|
+
*/
|
|
117
|
+
export declare function formatInboundTarget(msg: KookInboundMessage): string;
|
|
118
|
+
export declare function parseSendTarget(target: string): ParsedSendTarget;
|
|
119
|
+
export declare function senderDisplayName(msg: KookInboundMessage): string;
|
|
120
|
+
/** Build inbound text for MessageGateway.receive */
|
|
121
|
+
export declare function formatInboundContent(msg: KookInboundMessage): string;
|
|
122
|
+
/**
|
|
123
|
+
* KOOK @ 用户标记为 `(met)<userId>(met)`;content 含 `(met)<botId>(met)` 时视为 @ 机器人。
|
|
124
|
+
* botId 取 client 缓存的 self_id(/me 类接口),拿不到则不标注。
|
|
125
|
+
*/
|
|
126
|
+
export declare function isKookBotMentioned(msg: KookInboundMessage, selfId?: string): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Wire-encode an already-rendered outbound payload into KOOK KMarkdown.
|
|
129
|
+
* Segment canonicalization is intentionally not done here.
|
|
130
|
+
*/
|
|
131
|
+
export declare function formatOutboundKmarkdown(payload: unknown): string;
|
|
132
|
+
export declare function normalizeWebhookPath(path: string): string;
|
|
133
|
+
export declare function readTextBody(request: IncomingMessage, options?: {
|
|
134
|
+
readonly limit?: number;
|
|
135
|
+
}): Promise<string>;
|
|
136
|
+
export declare function readRequestBody(request: IncomingMessage, options?: {
|
|
137
|
+
readonly limit?: number;
|
|
138
|
+
}): Promise<Buffer>;
|
|
139
|
+
export declare function padKookEncryptKey(key: string): Buffer;
|
|
140
|
+
export declare function decryptKookWebhookPayload(encrypted: string, encryptKey: string): Buffer;
|
|
141
|
+
export declare function parseKookWebhookBody(rawBody: Buffer, encryptKey?: string): KookWebhookFrame;
|
|
142
|
+
export declare function isKookWebhookChallenge(event: KookWebhookEventData): boolean;
|
|
143
|
+
export declare function verifyKookWebhookToken(expected: string, actual?: string): boolean;
|
|
144
|
+
export declare function normalizeKookWebhookEvent(event: KookWebhookEventData, options?: {
|
|
145
|
+
readonly ignore?: 'bot' | 'self';
|
|
146
|
+
readonly selfId?: string;
|
|
147
|
+
}): KookInboundMessage | null;
|