@zhin.js/adapter-kook 1.1.17 → 1.1.19

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/lib/protocol.js CHANGED
@@ -297,6 +297,8 @@ export function normalizeKookWebhookEvent(event, options = {}) {
297
297
  return null;
298
298
  return {
299
299
  id: String(event.msg_id),
300
+ event,
301
+ ...(typeof event.msg_timestamp === 'number' ? { platformSentAt: event.msg_timestamp } : {}),
300
302
  content: event.content ?? '',
301
303
  channelKind,
302
304
  channelId,
@@ -328,5 +330,5 @@ export function normalizeKookButtonEvent(raw) {
328
330
  if (!channelId)
329
331
  return null;
330
332
  const timestamp = event.msg_timestamp ?? Date.now();
331
- return { id: String(event.msg_id || `button:${body.msg_id}:${timestamp}`), sourceMessageId: String(body.msg_id), payload: body.value, userId: String(body.user_id), channelKind, channelId, timestamp };
333
+ return { event: raw, ...(typeof event.msg_timestamp === 'number' ? { platformSentAt: event.msg_timestamp } : {}), id: String(event.msg_id || `button:${body.msg_id}:${timestamp}`), sourceMessageId: String(body.msg_id), payload: body.value, userId: String(body.user_id), channelKind, channelId, timestamp };
332
334
  }
package/lib/webhook.d.ts CHANGED
@@ -1,11 +1,12 @@
1
+ import { type Endpoint } from 'zhin.js/adapter';
1
2
  /**
2
3
  * KOOK webhook HTTP: verify → parse → admit.
3
4
  */
4
5
  import type { IncomingMessage, ServerResponse } from 'node:http';
5
6
  import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
6
7
  import { type KookInboundMessage, type KookWebhookEventData, type ResolvedKookWebhookConfig } from './protocol.js';
7
- export interface KookWebhookHandler {
8
- readonly config: ResolvedKookWebhookConfig;
8
+ export interface KookWebhookHandler extends Endpoint {
9
+ readonly endpointConfig: ResolvedKookWebhookConfig;
9
10
  readonly isOpen: boolean;
10
11
  readonly selfId?: string;
11
12
  admit(msg: KookInboundMessage): void;
package/lib/webhook.js CHANGED
@@ -1,8 +1,9 @@
1
+ import { endpointSpec } from 'zhin.js/adapter';
1
2
  import { formatCompact, getLogger } from '@zhin.js/logger';
2
3
  import { isKookWebhookChallenge, parseKookWebhookBody, readRequestBody, verifyKookWebhookToken, } from './protocol.js';
3
4
  const logger = getLogger('kook');
4
5
  export function registerKookWebhookRoutes(http, handler) {
5
- const path = handler.config.webhookPath;
6
+ const path = handler.endpointConfig.webhookPath;
6
7
  return [
7
8
  http.route('POST', path, async (request, response) => {
8
9
  await handleKookWebhookRequest(request, response, handler);
@@ -14,7 +15,7 @@ export async function handleKookWebhookRequest(request, response, handler) {
14
15
  const rawBody = await readRequestBody(request);
15
16
  let frame;
16
17
  try {
17
- frame = parseKookWebhookBody(rawBody, handler.config.encryptKey);
18
+ frame = parseKookWebhookBody(rawBody, handler.endpointConfig.encryptKey);
18
19
  }
19
20
  catch (error) {
20
21
  logger.warn(formatCompact({
@@ -33,7 +34,7 @@ export async function handleKookWebhookRequest(request, response, handler) {
33
34
  return;
34
35
  }
35
36
  if (isKookWebhookChallenge(event)) {
36
- if (!verifyKookWebhookToken(handler.config.verifyToken, event.verify_token)) {
37
+ if (!verifyKookWebhookToken(handler.endpointConfig.verifyToken, event.verify_token)) {
37
38
  response.writeHead(403, { 'Content-Type': 'application/json' });
38
39
  response.end(JSON.stringify({ message: 'Invalid verify_token' }));
39
40
  return;
@@ -42,7 +43,7 @@ export async function handleKookWebhookRequest(request, response, handler) {
42
43
  response.end(JSON.stringify({ challenge: event.challenge ?? '' }));
43
44
  return;
44
45
  }
45
- if (!verifyKookWebhookToken(handler.config.verifyToken, event.verify_token)) {
46
+ if (!verifyKookWebhookToken(handler.endpointConfig.verifyToken, event.verify_token)) {
46
47
  response.writeHead(403, { 'Content-Type': 'application/json' });
47
48
  response.end(JSON.stringify({ message: 'Invalid verify_token' }));
48
49
  return;
@@ -52,25 +53,27 @@ export async function handleKookWebhookRequest(request, response, handler) {
52
53
  response.end(JSON.stringify({ message: 'Endpoint unavailable' }));
53
54
  return;
54
55
  }
55
- if (frame.sn != null) {
56
- if (!handler.checkAndRememberSn(frame.sn)) {
57
- response.writeHead(200, { 'Content-Type': 'application/json' });
58
- response.end(JSON.stringify({ message: 'OK' }));
56
+ await handler[endpointSpec].events.run(async () => {
57
+ if (frame.sn != null) {
58
+ if (!handler.checkAndRememberSn(frame.sn)) {
59
+ response.writeHead(200, { 'Content-Type': 'application/json' });
60
+ response.end(JSON.stringify({ message: 'OK' }));
61
+ return;
62
+ }
63
+ }
64
+ try {
65
+ await handler.admitEvent(event);
66
+ }
67
+ catch {
68
+ if (frame.sn != null)
69
+ handler.forgetSn?.(frame.sn);
70
+ response.writeHead(503, { 'Content-Type': 'application/json' });
71
+ response.end(JSON.stringify({ message: 'Admission unavailable' }));
59
72
  return;
60
73
  }
61
- }
62
- try {
63
- await handler.admitEvent(event);
64
- }
65
- catch {
66
- if (frame.sn != null)
67
- handler.forgetSn?.(frame.sn);
68
- response.writeHead(503, { 'Content-Type': 'application/json' });
69
- response.end(JSON.stringify({ message: 'Admission unavailable' }));
70
- return;
71
- }
72
- response.writeHead(200, { 'Content-Type': 'application/json' });
73
- response.end(JSON.stringify({ message: 'OK' }));
74
+ response.writeHead(200, { 'Content-Type': 'application/json' });
75
+ response.end(JSON.stringify({ message: 'OK' }));
76
+ });
74
77
  }
75
78
  catch (error) {
76
79
  logger.error('KOOK webhook error:', error);
package/lib/ws.d.ts CHANGED
@@ -1,70 +1,8 @@
1
1
  import { type KookApiProxy } from './api-proxy.js';
2
2
  import { Client } from 'kook-client';
3
3
  import { createEndpointLifecycle, type EndpointTransportState } from 'zhin.js/adapter';
4
- import { type KookInboundMessage, type ResolvedKookConfig, type ResolvedKookWebhookConfig, type ResolvedKookWebsocketConfig } from './protocol.js';
5
- /** Minimal client surface used by the endpoint (real kook-client or test mock). */
6
- export interface KookClientTransport {
7
- getTransportState?(): EndpointTransportState | undefined;
8
- connect(): Promise<void>;
9
- disconnect(): Promise<void>;
10
- on(event: string, listener: (...args: unknown[]) => void): void;
11
- removeAllListeners(): void;
12
- sendChannelMsg(channelId: string, message: unknown, quote?: {
13
- message_id: string;
14
- }): Promise<{
15
- msg_id?: string | number;
16
- }>;
17
- sendPrivateMsg(userId: string, message: unknown, quote?: {
18
- message_id: string;
19
- }): Promise<{
20
- msg_id?: string | number;
21
- }>;
22
- uploadMedia?(data: Buffer): Promise<string>;
23
- recallChannelMsg?(channelId: string, messageId: string): Promise<boolean>;
24
- recallPrivateMsg?(userId: string, messageId: string): Promise<boolean>;
25
- /** GET /api/v3/guild/view(群主 id)。 */
26
- getGuildInfo?(guildId: string): Promise<{
27
- user_id?: string | number;
28
- }>;
29
- pickGuild(guildId: string): {
30
- kick(userId: string): Promise<boolean>;
31
- getRoleList(): Promise<Array<{
32
- role_id: string | number;
33
- name: string;
34
- color?: number;
35
- position?: number;
36
- permissions?: unknown;
37
- }>>;
38
- createRole(name: string): Promise<{
39
- role_id: string | number;
40
- name: string;
41
- }>;
42
- deleteRole(roleId: string): Promise<boolean>;
43
- };
44
- pickGuildMember(guildId: string, userId: string): {
45
- addToBlackList(remark?: string, delMsgDays?: number): Promise<boolean>;
46
- removeFromBlackList(): Promise<boolean>;
47
- grant(roleId: string): Promise<boolean>;
48
- revoke(roleId: string): Promise<boolean>;
49
- setNickname(nickname: string): Promise<boolean>;
50
- };
51
- /** GET /api/v3/guild/list(kook-client 内部分页聚合)。 */
52
- getGuildList(): Promise<Array<{
53
- id: string | number;
54
- name?: string;
55
- }>>;
56
- /** GET /api/v3/channel/list(type: 1=文字 2=语音;is_category 为分组)。 */
57
- getChannelList(guildId: string): Promise<Array<{
58
- id: string | number;
59
- name?: string;
60
- type?: string | number;
61
- is_category?: boolean;
62
- }>>;
63
- /** GET /api/v3/guild/user-list。 */
64
- getGuildUserList(guildId: string, channelId?: string): Promise<unknown[]>;
65
- self_id?: string | number;
66
- }
67
- export type CreateKookClient = (config: ResolvedKookConfig) => KookClientTransport;
4
+ import { type KookInboundMessage, type ResolvedKookWebhookConfig, type ResolvedKookWebsocketConfig } from './protocol.js';
5
+ export type KookClientTransport = RuntimeKookClient;
68
6
  export declare function normalizeKookMessage(raw: unknown): KookInboundMessage | null;
69
7
  export declare class RuntimeKookClient extends Client {
70
8
  #private;
@@ -77,5 +15,5 @@ export declare class RuntimeKookClient extends Client {
77
15
  init(): Promise<void>;
78
16
  getBlacklist(guildId: string): Promise<import("kook-client").Guild.BlackInfo[]>;
79
17
  }
80
- export declare function defaultCreateClient(config: ResolvedKookWebsocketConfig): KookClientTransport;
81
- export declare function defaultCreateWebhookClient(config: ResolvedKookWebhookConfig): KookClientTransport;
18
+ export declare function kookWebsocketClientOptions(config: ResolvedKookWebsocketConfig): ConstructorParameters<typeof Client>[0];
19
+ export declare function kookWebhookClientOptions(config: ResolvedKookWebhookConfig): ConstructorParameters<typeof Client>[0];
package/lib/ws.js CHANGED
@@ -42,6 +42,8 @@ export function normalizeKookMessage(raw) {
42
42
  catch { /* optional cache enrichment unavailable */ }
43
43
  return {
44
44
  id: String(msg.message_id),
45
+ event: raw,
46
+ ...(typeof msg.timestamp === 'number' ? { platformSentAt: msg.timestamp } : {}),
45
47
  content,
46
48
  channelKind,
47
49
  channelId,
@@ -57,6 +59,7 @@ export function normalizeKookMessage(raw) {
57
59
  };
58
60
  }
59
61
  export class RuntimeKookClient extends Client {
62
+ #apiAgent;
60
63
  #lifecycle;
61
64
  #initialized = false;
62
65
  #connectionAttempt = 0;
@@ -64,7 +67,8 @@ export class RuntimeKookClient extends Client {
64
67
  super({ ...config, autoReconnect: false, handleProcessErrors: false });
65
68
  this.#lifecycle = createEndpointLifecycle(lifecycleOptions);
66
69
  if (apiProxy) {
67
- this.request.defaults.httpsAgent = createKookApiAgent(apiProxy);
70
+ this.#apiAgent = createKookApiAgent(apiProxy);
71
+ this.request.defaults.httpsAgent = this.#apiAgent;
68
72
  this.request.defaults.proxy = false;
69
73
  this.request.defaults.maxRedirects = 0;
70
74
  this.request.interceptors.request.use(request => {
@@ -125,7 +129,12 @@ export class RuntimeKookClient extends Client {
125
129
  }
126
130
  });
127
131
  }
128
- async disconnect() { await this.#lifecycle.stop(); }
132
+ async disconnect() { try {
133
+ await this.#lifecycle.stop();
134
+ }
135
+ finally {
136
+ this.#apiAgent?.destroy();
137
+ } }
129
138
  /** Native FormData avoids kook-client's Buffer-to-text multipart conversion. */
130
139
  async uploadMedia(data) {
131
140
  let bytes;
@@ -190,8 +199,8 @@ export class RuntimeKookClient extends Client {
190
199
  }
191
200
  }
192
201
  }
193
- export function defaultCreateClient(config) {
194
- return new RuntimeKookClient({
202
+ export function kookWebsocketClientOptions(config) {
203
+ return {
195
204
  token: config.token,
196
205
  mode: 'websocket',
197
206
  socketFactory: (url) => createKookStreamSocket(url, config.streamProxy),
@@ -200,10 +209,10 @@ export function defaultCreateClient(config) {
200
209
  max_retry: config.max_retry,
201
210
  ignore: config.ignore,
202
211
  logLevel: config.logLevel,
203
- }, undefined, config.apiProxy);
212
+ };
204
213
  }
205
- export function defaultCreateWebhookClient(config) {
206
- return new RuntimeKookClient({
214
+ export function kookWebhookClientOptions(config) {
215
+ return {
207
216
  token: config.token,
208
217
  mode: 'webhook',
209
218
  data_dir: path.join(process.cwd(), 'data', 'kook'),
@@ -211,5 +220,5 @@ export function defaultCreateWebhookClient(config) {
211
220
  max_retry: 3,
212
221
  ignore: config.ignore,
213
222
  logLevel: config.logLevel,
214
- }, undefined, config.apiProxy);
223
+ };
215
224
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-kook",
3
- "version": "1.1.17",
3
+ "version": "1.1.19",
4
4
  "description": "Zhin.js KOOK adapter for Plugin Runtime (WebSocket gateway or Webhook)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -33,23 +33,26 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "kook-client": "^1.0.5",
36
- "@zhin.js/adapter": "1.1.24",
37
- "@zhin.js/agent-feature": "1.1.10",
38
- "@zhin.js/core": "1.1.52",
39
- "@zhin.js/feature-kit": "1.1.9",
40
- "@zhin.js/host-http": "1.1.11",
41
- "@zhin.js/im-contract": "1.1.8",
36
+ "@zhin.js/adapter": "1.1.26",
37
+ "@zhin.js/agent-feature": "1.1.11",
38
+ "@zhin.js/client": "1.1.22",
39
+ "@zhin.js/console-contract": "1.1.3",
40
+ "@zhin.js/core": "1.1.54",
41
+ "@zhin.js/feature-kit": "1.1.10",
42
+ "@zhin.js/host-http": "1.1.12",
43
+ "@zhin.js/im-contract": "1.1.9",
42
44
  "@zhin.js/logger": "1.1.2",
43
- "@zhin.js/permission": "1.1.9",
44
- "@zhin.js/skill": "1.1.10",
45
- "@zhin.js/tool": "1.1.11"
45
+ "@zhin.js/page": "1.1.11",
46
+ "@zhin.js/permission": "1.1.10",
47
+ "@zhin.js/skill": "1.1.11",
48
+ "@zhin.js/tool": "1.1.13"
46
49
  },
47
50
  "peerDependencies": {
48
51
  "zod": "^4.0.0",
49
- "@zhin.js/adapter": "^1.1.24",
50
- "@zhin.js/command": "^1.1.11",
51
- "@zhin.js/core": "^1.1.52",
52
- "zhin.js": "^1.1.17"
52
+ "@zhin.js/adapter": "^1.1.26",
53
+ "@zhin.js/command": "^1.1.12",
54
+ "@zhin.js/core": "^1.1.54",
55
+ "zhin.js": "^1.1.19"
53
56
  },
54
57
  "peerDependenciesMeta": {
55
58
  "@zhin.js/command": {
@@ -67,12 +70,13 @@
67
70
  "typescript": "^6.0.3",
68
71
  "vitest": "^4.1.10",
69
72
  "zod": "^4.4.3",
70
- "@zhin.js/host-http": "1.1.11",
71
- "zhin.js": "1.1.17"
73
+ "@zhin.js/host-http": "1.1.12",
74
+ "zhin.js": "1.1.19"
72
75
  },
73
76
  "files": [
74
77
  "adapters",
75
78
  "commands",
79
+ "pages",
76
80
  "plugin.js",
77
81
  "schema.json",
78
82
  "src",
@@ -99,7 +103,7 @@
99
103
  "features": [
100
104
  {
101
105
  "package": "@zhin.js/adapter",
102
- "api": "^1.0.0"
106
+ "api": "^2.0.0"
103
107
  },
104
108
  {
105
109
  "package": "@zhin.js/command",
@@ -116,6 +120,10 @@
116
120
  {
117
121
  "package": "@zhin.js/agent-feature",
118
122
  "api": "^1.0.0"
123
+ },
124
+ {
125
+ "package": "@zhin.js/page",
126
+ "api": "^1.0.0"
119
127
  }
120
128
  ],
121
129
  "plugins": []
@@ -0,0 +1,15 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { definePage } from '@zhin.js/console-contract';
3
+ import { createAdapterConsolePage } from '@zhin.js/client';
4
+ export const meta = definePage({
5
+ title: 'KOOK',
6
+ titleI18n: { en: 'KOOK' },
7
+ icon: 'Gamepad2',
8
+ order: 65,
9
+ requiredPermissions: ['kook:read'],
10
+ });
11
+ /**
12
+ * Convention page: `pages/index/index.ts` → `/kook`(插件路径)。
13
+ * 连接状态、连接测试、endpoint 增删;登录待办来自 LoginAssist(ICQQ 等)。
14
+ */
15
+ export default createAdapterConsolePage('kook');
@@ -0,0 +1,16 @@
1
+ import { definePage } from '@zhin.js/console-contract';
2
+ import { createAdapterConsolePage } from '@zhin.js/client';
3
+
4
+ export const meta = definePage({
5
+ title: 'KOOK',
6
+ titleI18n: { en: 'KOOK' },
7
+ icon: 'Gamepad2',
8
+ order: 65,
9
+ requiredPermissions: ['kook:read'],
10
+ });
11
+
12
+ /**
13
+ * Convention page: `pages/index/index.ts` → `/kook`(插件路径)。
14
+ * 连接状态、连接测试、endpoint 增删;登录待办来自 LoginAssist(ICQQ 等)。
15
+ */
16
+ export default createAdapterConsolePage('kook');
package/plugin.js CHANGED
@@ -1,16 +1,15 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { createEndpointRuntimeState } from 'zhin.js/adapter';
3
- import { definePlugin } from 'zhin.js';
2
+ import { definePlugin, pluginConsoleRpcToken } from 'zhin.js';
4
3
  import { permissionHostToken } from '@zhin.js/permission';
5
4
  import { checkKookPlatformPermit } from "./lib/platform-permit.js";
6
- import { kookRuntimeStateToken } from "./lib/kook-runtime-state.js";
5
+ import { createKookConsoleRpc } from "./lib/console.js";
7
6
  export default definePlugin({
8
7
  name: 'kook',
9
8
  metadata: {
10
9
  displayName: 'KOOK WebSocket Adapter',
11
10
  },
12
11
  setup(context) {
13
- context.resources.provide(kookRuntimeStateToken, createEndpointRuntimeState());
12
+ context.resources.provide(pluginConsoleRpcToken, createKookConsoleRpc(() => context.config.get()));
14
13
  if (context.resources.has(permissionHostToken)) {
15
14
  const host = context.resources.use(permissionHostToken);
16
15
  return host.registerPlatform('kook', checkKookPlatformPermit);
package/src/adapter.ts ADDED
@@ -0,0 +1,35 @@
1
+ import { Adapter, type AdapterContext, type EndpointCreationContext } from 'zhin.js/adapter';
2
+ import { httpHostToken } from '@zhin.js/host-http';
3
+ import { KookWebhookEndpoint, KookWebsocketEndpoint } from './endpoint.js';
4
+ import { RuntimeKookClient, kookWebhookClientOptions, kookWebsocketClientOptions } from './ws.js';
5
+ import { resolveKookConfig, type KookEndpointConfig } from './protocol.js';
6
+ import type { KookClientEventMap } from './client.js';
7
+
8
+ export class KookAdapter extends Adapter<KookWebhookEndpoint | KookWebsocketEndpoint, KookEndpointConfig, KookClientEventMap> {
9
+ constructor(private readonly context: AdapterContext<KookEndpointConfig>) { super(); }
10
+ override get configurationIdentityFields(): readonly string[] { return ['id']; }
11
+ override get configurationIdentityProbeFields(): readonly string[] { return ['token', 'verify_token', 'encrypt_key']; }
12
+ override get configurationUpdateFields(): readonly string[] { return ['token', 'verify_token', 'encrypt_key', 'connection',
13
+ 'webhookPath', 'data_dir', 'timeout', 'max_retry', 'ignore', 'logLevel', 'apiProxy', 'apiProxy.port',
14
+ 'streamProxy', 'streamProxy.port', 'streamProxy.serverName']; }
15
+ protected override validateConfiguration(input: KookEndpointConfig): void { resolveKookConfig(input); }
16
+ protected override async identifyConfiguration(input: KookEndpointConfig, signal: AbortSignal, changedFields: readonly string[]): Promise<string | undefined> {
17
+ if (changedFields.some(field => field !== 'token')) return undefined;
18
+ const config = resolveKookConfig(input);
19
+ const options = config.connection === 'websocket' ? kookWebsocketClientOptions(config) : kookWebhookClientOptions(config);
20
+ // Webhook receiver construction has no gateway socket or login; only GET /v3/user/me is issued.
21
+ const client = new RuntimeKookClient({ ...options, mode: 'webhook' }, undefined, config.apiProxy);
22
+ client.request.interceptors.request.use(request => { request.signal = signal; return request; });
23
+ try {
24
+ const me = await client.getSelfInfo();
25
+ if (typeof me?.id !== 'string' || !me.id.trim()) throw new Error('KOOK identity response is incomplete');
26
+ return JSON.stringify(['kook', me.id]);
27
+ } finally { await client.disconnect(); }
28
+ }
29
+ protected createEndpoint(input: KookEndpointConfig, execution: EndpointCreationContext): KookWebhookEndpoint | KookWebsocketEndpoint {
30
+ const config = resolveKookConfig(input);
31
+ return config.connection === 'webhook'
32
+ ? new KookWebhookEndpoint({ id: execution.canonicalId, config, http: this.context.use(httpHostToken) })
33
+ : new KookWebsocketEndpoint({ id: execution.canonicalId, config });
34
+ }
35
+ }
package/src/client.ts CHANGED
@@ -1,15 +1,8 @@
1
- import { defineEndpointClient } from 'zhin.js/adapter';
2
- import type { KookClientTransport } from './ws.js';
1
+ import type { EventMap } from 'kook-client';
2
+ import type { KookAdapter } from './adapter.js';
3
3
 
4
- export type KookClientEventMap = Record<string, unknown>;
4
+ export type KookClientEventMap = { readonly [K in keyof EventMap]: EventMap[K] extends (event: infer E, ...args: never[]) => unknown ? E : never };
5
5
 
6
6
  declare module '@zhin.js/feature-kit' {
7
- interface AdapterClientRegistry {
8
- readonly kook: {
9
- readonly client: KookClientTransport;
10
- readonly events: KookClientEventMap;
11
- };
12
- }
7
+ interface AdapterRegistry { readonly kook: KookAdapter; }
13
8
  }
14
-
15
- export const kookClient = defineEndpointClient<KookClientTransport, KookClientEventMap>('kook');
@@ -0,0 +1,27 @@
1
+ /**
2
+ * KOOK Console 页面元数据(浏览器与服务端共享;不要在这里 import 服务端代码)。
3
+ */
4
+ import type { AdapterConsoleField } from 'zhin.js/adapter';
5
+
6
+ export const kookConsoleSpec = {
7
+ adapterKey: 'kook',
8
+ adapterDisplayName: 'KOOK',
9
+ fields: [
10
+ { key: 'token', required: true, env: true, description: 'KOOK bot token' },
11
+ { key: 'encrypt_key', env: true, description: 'webhook 加密密钥(connection: webhook)', descriptionI18n: { en: 'Webhook encryption secret' } },
12
+ { key: 'verify_token', env: true, description: 'webhook 验证 token(connection: webhook)', descriptionI18n: { en: 'Webhook verification token' } },
13
+ { key: 'connection', description: 'websocket or webhook' },
14
+ { key: 'webhookPath', description: 'Local webhook route' },
15
+ { key: 'data_dir', description: 'SDK data directory' },
16
+ { key: 'timeout', type: 'number', description: 'SDK request timeout' },
17
+ { key: 'max_retry', type: 'number', description: 'SDK configured retry count' },
18
+ { key: 'ignore', description: 'SDK inbound ignore setting: bot or self' },
19
+ { key: 'logLevel', description: 'SDK log level' },
20
+ { key: 'apiProxy.port', type: 'number', description: 'Configured API loopback proxy port' },
21
+ { key: 'streamProxy.port', type: 'number', description: 'Configured Gateway loopback proxy port' },
22
+ { key: 'streamProxy.serverName', description: 'Expected Gateway TLS hostname' },
23
+ ] as readonly AdapterConsoleField[],
24
+ docsUrl: 'https://zhin.js.org/adapters/kook',
25
+ readPermission: 'kook:read',
26
+ writePermission: 'kook:write',
27
+ } as const;
package/src/console.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * KOOK Console RPC:运行状态 + endpoint 增删(原 `kook endpoint` 聊天命令)。
3
+ *
4
+ * 页面绑定 `pages/index`,读取 / 写入分别要求 `<adapter>:read` / `<adapter>:write`。
5
+ */
6
+ import { createAdapterConsoleRpc } from 'zhin.js/adapter';
7
+ import type { PluginConsoleRpc } from 'zhin.js';
8
+ import { kookConsoleSpec } from './console-spec.js';
9
+
10
+ export function createKookConsoleRpc(
11
+ getConfig: () => unknown,
12
+ ): PluginConsoleRpc {
13
+ return createAdapterConsoleRpc({
14
+ ...kookConsoleSpec,
15
+ getConfig,
16
+ });
17
+ }