@zhin.js/adapter-kook 1.1.0 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/README.md +10 -12
  3. package/adapters/{kook.js → kook/index.js} +6 -6
  4. package/adapters/{kook.ts → kook/index.ts} +10 -10
  5. package/agents/kook/agent.json +20 -0
  6. package/agents/kook/boundaries.md +3 -0
  7. package/agents/kook/conventions.md +3 -0
  8. package/agents/kook/skills/kook/SKILL.md +20 -0
  9. package/agents/kook/skills/kook/tools/blacklist/index.js +31 -0
  10. package/{agent/tools/blacklist.ts → agents/kook/skills/kook/tools/blacklist/index.ts} +3 -3
  11. package/agents/kook/skills/kook/tools/create_role/index.js +23 -0
  12. package/{agent/tools/create_role.ts → agents/kook/skills/kook/tools/create_role/index.ts} +3 -3
  13. package/agents/kook/skills/kook/tools/delete_role/index.js +19 -0
  14. package/{agent/tools/delete_role.ts → agents/kook/skills/kook/tools/delete_role/index.ts} +3 -3
  15. package/agents/kook/skills/kook/tools/grant_role/index.js +20 -0
  16. package/{agent/tools/grant_role.ts → agents/kook/skills/kook/tools/grant_role/index.ts} +3 -3
  17. package/agents/kook/skills/kook/tools/list_roles/index.js +25 -0
  18. package/{agent/tools/list_roles.ts → agents/kook/skills/kook/tools/list_roles/index.ts} +1 -1
  19. package/agents/kook/skills/kook/tools/revoke_role/index.js +20 -0
  20. package/{agent/tools/revoke_role.ts → agents/kook/skills/kook/tools/revoke_role/index.ts} +3 -3
  21. package/agents/kook/system.md +3 -0
  22. package/commands/{endpoint/add/[id].js → kook/endpoint/add/[id]/index.js} +1 -1
  23. package/commands/kook/endpoint/add/[id]/index.ts +3 -0
  24. package/{lib/kook-endpoint-commands.js → commands/kook/endpoint/definition.js} +4 -3
  25. package/{src/kook-endpoint-commands.ts → commands/kook/endpoint/definition.ts} +3 -3
  26. package/commands/{endpoint/list.js → kook/endpoint/list/index.js} +1 -1
  27. package/commands/kook/endpoint/list/index.ts +3 -0
  28. package/commands/{endpoint/remove/[id].js → kook/endpoint/remove/[id]/index.js} +1 -1
  29. package/commands/kook/endpoint/remove/[id]/index.ts +3 -0
  30. package/lib/index.d.ts +1 -1
  31. package/lib/kook-runtime-state.js +1 -1
  32. package/lib/protocol.d.ts +7 -25
  33. package/lib/protocol.js +22 -35
  34. package/package.json +33 -21
  35. package/schema.json +45 -2
  36. package/src/index.ts +1 -1
  37. package/src/kook-runtime-state.ts +1 -1
  38. package/src/protocol.ts +30 -59
  39. package/agent/skills/kook.md +0 -80
  40. package/commands/endpoint/add/[id].ts +0 -3
  41. package/commands/endpoint/list.ts +0 -3
  42. package/commands/endpoint/remove/[id].ts +0 -3
  43. package/lib/kook-endpoint-commands.d.ts +0 -1
  44. /package/{agent/PERMITS.md → PERMITS.md} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,115 @@
1
1
  # @zhin.js/adapter-kook
2
2
 
3
+ ## 1.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [5b5d270]
8
+ - Updated dependencies [36c2eb9]
9
+ - @zhin.js/im-contract@1.1.2
10
+ - @zhin.js/core@1.1.38
11
+ - @zhin.js/adapter@1.1.15
12
+ - @zhin.js/host-http@1.1.2
13
+ - @zhin.js/agent-feature@1.1.2
14
+ - @zhin.js/feature-kit@1.1.2
15
+ - @zhin.js/permission@1.1.2
16
+ - @zhin.js/skill@1.1.2
17
+ - @zhin.js/tool@1.1.2
18
+
19
+ ## 1.1.2
20
+
21
+ ### Patch Changes
22
+
23
+ - a9e4a40: Derive Command user routes only from explicit `commands/**/*/index.ts(x)` entry paths instead of prepending the plugin owner. Child plugins can now publish top-level static or dynamic commands, while duplicate routes across owners fail during generation construction. Adapter endpoint commands move to explicit paths such as `commands/qq/endpoint/list/index.ts` and are invoked as `qq endpoint list`.
24
+ - 8740059: Standardize TypeScript capabilities on named module directories such as `commands/foo/index.ts`, `middlewares/audit/index.ts`, `handlers/message-receive/index.ts`, `pages/workroom/index.tsx`, and `mcps/filesystem/index.ts`. Only the fixed `index` entry is discovered; sibling files remain private helpers.
25
+
26
+ Command route segments come from directories, while `[name]`, `[[name]]`, `[...name]`, and `[[...name]]` directories declare dynamic parameters. Plugin owners do not enter the route unless their config explicitly sets `commandNamespace`; Endpoint `commandPrefix` remains platform-owned and defaults to an empty string.
27
+
28
+ Migrate the built-in adapters, plugins, examples, generators, migration tooling, hot reload classification, Agent authoring surfaces, documentation, and release artifacts to the explicit entry convention.
29
+
30
+ Make Tool ownership and progressive disclosure explicit across all four supported locations: plugin-public `tools/`, Agent-private `agents/<name>/tools/`, Skill-private `skills/<name>/tools/`, and Agent-Skill-private `agents/<name>/skills/<name>/tools/`. Move adapter and group-suite operations that require domain instructions into their owning Skills so `load_skill` is the only path that unlocks their schemas.
31
+
32
+ Remove the package-root `agent/` convention. Public capabilities now use named package-root directories, schedules use `schedules/<name>/index.ts` or `plugin.ts` injection, MCP connections use `mcps/<name>/index.ts`, Prompt Sections use `prompt-sections/<name>/index.ts`, Agent definitions use `agents/<name>/`, and permission vocabulary is published as `PERMITS.md`.
33
+
34
+ - 25a845a: Unify Skills on `skills/<name>/SKILL.md`, support Agent-private Skills and nested Skill-private Tools, publish and mount existing plugin Skills, add governed Skill metadata and Turn access filtering, unlock only already-admitted same-owner Tools, and make `on-risk` and `once` approval behavior precise.
35
+ - ddbb92e: Isolate adapter Skills under platform-specific Agents and automatically select the matching platform Agent for IM ingress, preventing unrelated adapter Skills from entering another platform's prompt surface.
36
+ - 4380cf9: Colocate adapter command definitions and Agent Skill handlers with their owning capabilities, and provide a shared validated platform permission constructor.
37
+ - 639e076: Require the canonical KOOK endpoint array and stop reading endpoint identity, credentials, webhook verification, encryption, or path values from `process.env`. Configure accounts under `plugins.kook.endpoints`, for example `[{ id: "main", token: "${KOOK_TOKEN}", connection: "websocket" }]`; each entry uses `id` as its identity and may override the plugin-level connection settings. The public config type is now `KookEndpointConfig`.
38
+ - 5c3858e: Make `@zhin.js/im-contract` the explicit zero-dependency owner of transport identities, canonical segments, media guards, conversation facts, stores, and delivery contracts. Platform adapters now read media contracts from that foundation instead of reaching through Core.
39
+ - 33ea736: Use `tools/<name>/index.ts` and `defineAgentTool` from `@zhin.js/tool` as the sole Agent Tool authoring model. Remove the duplicate `@zhin.js/tools` definition, context, bridge, export, and discovery path; migrate plugin manifests, examples, scaffolding, HMR, and prepack compilation to the generation-owned Tool Feature.
40
+ - Updated dependencies [c861789]
41
+ - Updated dependencies [1414ccb]
42
+ - Updated dependencies [743d470]
43
+ - Updated dependencies [62dee52]
44
+ - Updated dependencies [cd54131]
45
+ - Updated dependencies [244e475]
46
+ - Updated dependencies [a9e4a40]
47
+ - Updated dependencies [5855db7]
48
+ - Updated dependencies [ec921d2]
49
+ - Updated dependencies [8740059]
50
+ - Updated dependencies [63d1f7a]
51
+ - Updated dependencies [25a845a]
52
+ - Updated dependencies [103f2c3]
53
+ - Updated dependencies [9110ab8]
54
+ - Updated dependencies [cd2a888]
55
+ - Updated dependencies [eb3227a]
56
+ - Updated dependencies [b853dba]
57
+ - Updated dependencies [e561309]
58
+ - Updated dependencies [d4c6175]
59
+ - Updated dependencies [7a0e1ca]
60
+ - Updated dependencies [103b5d3]
61
+ - Updated dependencies [5a7a7f7]
62
+ - Updated dependencies [b076eae]
63
+ - Updated dependencies [535fed1]
64
+ - Updated dependencies [73a24b7]
65
+ - Updated dependencies [4380cf9]
66
+ - Updated dependencies [2dbbc15]
67
+ - Updated dependencies [1cb1163]
68
+ - Updated dependencies [be3061e]
69
+ - Updated dependencies [75f8332]
70
+ - Updated dependencies [81935e2]
71
+ - Updated dependencies [f9ed01b]
72
+ - Updated dependencies [ac0ab50]
73
+ - Updated dependencies [5140ce1]
74
+ - Updated dependencies [522d75f]
75
+ - Updated dependencies [a7611b3]
76
+ - Updated dependencies [8823044]
77
+ - Updated dependencies [379439b]
78
+ - Updated dependencies [11c9352]
79
+ - Updated dependencies [6b70e46]
80
+ - Updated dependencies [135ac91]
81
+ - Updated dependencies [140cf0f]
82
+ - Updated dependencies [251e4d2]
83
+ - Updated dependencies [203ad34]
84
+ - Updated dependencies [e6c5113]
85
+ - Updated dependencies [e0f6478]
86
+ - Updated dependencies [baef56b]
87
+ - Updated dependencies [698f16f]
88
+ - Updated dependencies [da0a8e3]
89
+ - Updated dependencies [2fd8017]
90
+ - Updated dependencies [5c3858e]
91
+ - Updated dependencies [33ea736]
92
+ - Updated dependencies [507d602]
93
+ - Updated dependencies [df9f76b]
94
+ - @zhin.js/core@1.1.37
95
+ - @zhin.js/tool@1.1.1
96
+ - @zhin.js/host-http@1.1.1
97
+ - @zhin.js/adapter@1.1.14
98
+ - @zhin.js/feature-kit@1.1.1
99
+ - @zhin.js/agent-feature@1.1.1
100
+ - @zhin.js/skill@1.1.1
101
+ - @zhin.js/logger@1.1.1
102
+ - @zhin.js/im-contract@1.1.1
103
+ - @zhin.js/permission@1.1.1
104
+
105
+ ## 1.1.1
106
+
107
+ ### Patch Changes
108
+
109
+ - Updated dependencies [769e67f]
110
+ - @zhin.js/adapter@1.1.13
111
+ - @zhin.js/core@1.1.36
112
+
3
113
  ## 1.1.0
4
114
 
5
115
  ### Minor Changes
package/README.md CHANGED
@@ -19,7 +19,7 @@ pnpm add @zhin.js/adapter-kook
19
19
 
20
20
  ## Plugin Runtime
21
21
 
22
- - `@zhin.js/adapter` — 约定式 `adapters/kook.ts`(`defineAdapter`)
22
+ - `@zhin.js/adapter` — 约定式 `adapters/kook/index.ts`(`defineAdapter`)
23
23
  - `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
24
24
  - `@zhin.js/host-http` — Webhook 模式 POST 路由(WebSocket 不需要)
25
25
  - `zhin.js` — `plugin.ts`(`definePlugin`)
@@ -39,7 +39,7 @@ pnpm add @zhin.js/adapter-kook
39
39
  | **Webhook** | 需公网 HTTPS + Host `httpHostToken`;与 WebSocket 互斥 |
40
40
  | **host-http** | 仅 Webhook 模式需要 |
41
41
 
42
- 必填字段(`endpoints[i]`):`name`、`token`。
42
+ 必填字段(`endpoints[i]`):`id`、`token`。
43
43
 
44
44
  ## 最小配置
45
45
 
@@ -49,7 +49,7 @@ plugins:
49
49
  kook:
50
50
  # connection: websocket # 默认
51
51
  endpoints:
52
- - name: my-kook-bot
52
+ - id: my-kook-bot
53
53
  token: ${KOOK_TOKEN}
54
54
  ```
55
55
 
@@ -59,11 +59,9 @@ plugins:
59
59
 
60
60
  | 变量 | 说明 |
61
61
  |------|------|
62
- | `KOOK_TOKEN` / `KOOK_BOT_TOKEN` | Bot Token |
63
- | `KOOK_BOT_NAME` | 可选,默认 endpoint 名 |
64
- | `KOOK_VERIFY_TOKEN` | Webhook 模式 verify token |
65
- | `KOOK_ENCRYPT_KEY` | 可选,Webhook 消息加密密钥 |
66
- | `KOOK_WEBHOOK_PATH` | 可选,默认 `/kook/webhook` |
62
+ | `KOOK_TOKEN` | YAML 示例中 `token` 引用的 Bot Token |
63
+ | `KOOK_VERIFY_TOKEN` | YAML 中 `verify_token` 引用的 Webhook 验证令牌 |
64
+ | `KOOK_ENCRYPT_KEY` | YAML 中可选 `encrypt_key` 引用的消息加密密钥 |
67
65
 
68
66
  ## Webhook
69
67
 
@@ -75,7 +73,7 @@ plugins:
75
73
  connection: webhook
76
74
  webhookPath: /kook/webhook
77
75
  endpoints:
78
- - name: my-kook-bot
76
+ - id: my-kook-bot
79
77
  token: ${KOOK_TOKEN}
80
78
  verify_token: ${KOOK_VERIFY_TOKEN}
81
79
  # encrypt_key: ${KOOK_ENCRYPT_KEY} # 启用消息加密时必填
@@ -87,9 +85,9 @@ Host 需注入 `httpHostToken`。Challenge(`type: 255`)会校验 `verify_tok
87
85
 
88
86
  | 类别 | 路径 |
89
87
  |------|------|
90
- | Permit 词汇 | `agent/PERMITS.md` |
91
- | 平台工具 | `agent/tools/`(角色、黑名单等) |
92
- | 技能说明 | `agent/skills/kook.md` |
88
+ | Permit 词汇 | `PERMITS.md` |
89
+ | 平台工具 | `tools/`(角色、黑名单等) |
90
+ | 技能说明 | `agents/kook/skills/kook/SKILL.md` |
93
91
 
94
92
  ## 平台权限(platform permit)
95
93
 
@@ -1,14 +1,14 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  /**
3
- * Convention entry: discover `adapters/kook.ts` → defineAdapter.
3
+ * Convention entry: discover `adapters/kook/index.ts` → defineAdapter.
4
4
  * Implementation lives under `src/` (endpoint / webhook / ws / protocol).
5
5
  */
6
6
  import { defineAdapter } from 'zhin.js/adapter';
7
7
  import { httpHostToken } from '@zhin.js/host-http';
8
- import { KookWebhookEndpoint, KookWebsocketEndpoint, } from "../lib/endpoint.js";
9
- import { resolveKookConfig, } from "../lib/protocol.js";
10
- import { kookRuntimeStateToken } from "../lib/kook-runtime-state.js";
11
- export { KookWebhookEndpoint, KookWebsocketEndpoint, } from "../lib/endpoint.js";
8
+ import { KookWebhookEndpoint, KookWebsocketEndpoint, } from "../../lib/endpoint.js";
9
+ import { resolveKookConfig, } from "../../lib/protocol.js";
10
+ import { kookRuntimeStateToken } from "../../lib/kook-runtime-state.js";
11
+ export { KookWebhookEndpoint, KookWebsocketEndpoint, } from "../../lib/endpoint.js";
12
12
  export default defineAdapter({
13
13
  capabilities: ['inbound', 'outbound'],
14
14
  operations: ['recall'],
@@ -21,7 +21,7 @@ export default defineAdapter({
21
21
  },
22
22
  create(context) {
23
23
  const config = resolveKookConfig(context.config);
24
- // 注册到插件运行时状态(kook.endpoint list 的"运行中"数据源)
24
+ // 注册到插件运行时状态(kook endpoint list 的"运行中"数据源)
25
25
  context.use(kookRuntimeStateToken).endpoints.set(config.id, {
26
26
  id: config.id,
27
27
  mode: config.connection,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Convention entry: discover `adapters/kook.ts` → defineAdapter.
2
+ * Convention entry: discover `adapters/kook/index.ts` → defineAdapter.
3
3
  * Implementation lives under `src/` (endpoint / webhook / ws / protocol).
4
4
  */
5
5
  import { defineAdapter } from 'zhin.js/adapter';
@@ -7,24 +7,24 @@ import { httpHostToken } from '@zhin.js/host-http';
7
7
  import {
8
8
  KookWebhookEndpoint,
9
9
  KookWebsocketEndpoint,
10
- } from '../src/endpoint.js';
10
+ } from '../../src/endpoint.js';
11
11
  import {
12
12
  resolveKookConfig,
13
- type KookAdapterConfig,
14
- } from '../src/protocol.js';
15
- import { kookRuntimeStateToken } from '../src/kook-runtime-state.js';
13
+ type KookEndpointConfig,
14
+ } from '../../src/protocol.js';
15
+ import { kookRuntimeStateToken } from '../../src/kook-runtime-state.js';
16
16
 
17
17
  export {
18
18
  KookWebhookEndpoint,
19
19
  KookWebsocketEndpoint,
20
- } from '../src/endpoint.js';
20
+ } from '../../src/endpoint.js';
21
21
  export type {
22
22
  KookEndpointOptions,
23
23
  KookWebhookEndpointOptions,
24
- } from '../src/endpoint.js';
25
- export type { CreateKookClient, KookClientTransport } from '../src/ws.js';
24
+ } from '../../src/endpoint.js';
25
+ export type { CreateKookClient, KookClientTransport } from '../../src/ws.js';
26
26
 
27
- export default defineAdapter<KookAdapterConfig>({
27
+ export default defineAdapter<KookEndpointConfig>({
28
28
  capabilities: ['inbound', 'outbound'],
29
29
  operations: ['recall'],
30
30
  // KOOK 图片消息消费远程 URL;KMarkdown 由 endpoint codec 原生消费;
@@ -36,7 +36,7 @@ export default defineAdapter<KookAdapterConfig>({
36
36
  },
37
37
  create(context) {
38
38
  const config = resolveKookConfig(context.config);
39
- // 注册到插件运行时状态(kook.endpoint list 的"运行中"数据源)
39
+ // 注册到插件运行时状态(kook endpoint list 的"运行中"数据源)
40
40
  context.use(kookRuntimeStateToken).endpoints.set(config.id, {
41
41
  id: config.id,
42
42
  mode: config.connection,
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "KOOK Platform Agent",
3
+ "version": "1.0.0",
4
+ "description": "Handles kook platform-specific operations and progressively loads only the required platform Skill.",
5
+ "trigger_rules": {
6
+ "file_patterns": [],
7
+ "keywords": [
8
+ "kook",
9
+ "adapter:kook"
10
+ ]
11
+ },
12
+ "entry_points": [
13
+ "system.md",
14
+ "boundaries.md",
15
+ "conventions.md"
16
+ ],
17
+ "platforms": [
18
+ "kook"
19
+ ]
20
+ }
@@ -0,0 +1,3 @@
1
+ # Boundaries
2
+
3
+ Operate only on the active kook endpoint and authenticated conversation context. Respect every Tool permission and approval policy. Do not infer identifiers, roles, or authorization from display names.
@@ -0,0 +1,3 @@
1
+ # Conventions
2
+
3
+ Use stable platform identifiers from the current turn or directory queries. Load one task-specific Skill at a time, and use the unified reply and outbound message path.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: kook
3
+ platforms: [kook]
4
+ description: KOOK 角色和黑名单管理能力。
5
+ keywords: [kook, role, 角色, blacklist, 黑名单]
6
+ tags: [adapter, community]
7
+ tools:
8
+ - grant_role
9
+ - revoke_role
10
+ - list_roles
11
+ - create_role
12
+ - delete_role
13
+ - blacklist
14
+ ---
15
+
16
+ # KOOK
17
+
18
+ 角色操作前先用 `list_roles` 确认角色 ID,再授予、撤销、创建或删除角色。`blacklist` 是黑名单操作,影响用户重新加入服务器,执行前应确认目标用户和意图。
19
+
20
+ 当前 Agent Tool 不提供普通踢人、改昵称或成员列表查询,不要用黑名单代替普通踢人。
@@ -0,0 +1,31 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { platformPermission } from '@zhin.js/permission';
5
+ export default defineAgentTool({
6
+ description: 'KOOK 服务器黑名单管理:添加/移除',
7
+ inputSchema: z.object({
8
+ guild_id: z.string().describe('服务器 ID'),
9
+ action: z.enum(['add', 'remove']).describe('add|remove'),
10
+ user_id: z.string().describe('用户 ID'),
11
+ remark: z.string().optional().describe('备注(add 可选)'),
12
+ }),
13
+ adapter: 'kook',
14
+ tags: ['kook'],
15
+ permissions: [platformPermission('kook', 'guild_admin')],
16
+ async execute({ guild_id, action, user_id, remark }, context) {
17
+ const member = context.$client.pickGuildMember(guild_id, user_id);
18
+ switch (action) {
19
+ case 'add': {
20
+ const success = await member.addToBlackList(remark);
21
+ return { success, message: success ? `已将 ${user_id} 加入黑名单` : '操作失败' };
22
+ }
23
+ case 'remove': {
24
+ const success = await member.removeFromBlackList();
25
+ return { success, message: success ? `已将 ${user_id} 从黑名单移除` : '操作失败' };
26
+ }
27
+ default:
28
+ return { success: false, message: `未知操作: ${action}` };
29
+ }
30
+ },
31
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { platformPermit } from '../../src/platform-permit.js';
3
+ import { platformPermission } from '@zhin.js/permission';
4
4
 
5
5
  export default defineAgentTool<{ guild_id: string; action: 'add' | 'remove'; user_id: string; remark?: string }>({
6
6
  description: 'KOOK 服务器黑名单管理:添加/移除',
@@ -12,7 +12,7 @@ export default defineAgentTool<{ guild_id: string; action: 'add' | 'remove'; use
12
12
  }),
13
13
  adapter: 'kook',
14
14
  tags: ['kook'],
15
- permissions: [platformPermit('guild_admin')],
15
+ permissions: [platformPermission('kook', 'guild_admin')],
16
16
  async execute({ guild_id, action, user_id, remark }: { guild_id: string; action: 'add' | 'remove'; user_id: string; remark?: string }, context) {
17
17
  const member = context.$client.pickGuildMember(guild_id, user_id);
18
18
  switch (action) {
@@ -0,0 +1,23 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { platformPermission } from '@zhin.js/permission';
5
+ export default defineAgentTool({
6
+ description: '在 KOOK 服务器中创建新角色',
7
+ inputSchema: z.object({
8
+ guild_id: z.string().describe('服务器 ID'),
9
+ name: z.string().describe('角色名称'),
10
+ }),
11
+ adapter: 'kook',
12
+ tags: ['kook'],
13
+ permissions: [platformPermission('kook', 'guild_owner')],
14
+ async execute({ guild_id, name }, context) {
15
+ const client = context.$client;
16
+ const role = await client.pickGuild(guild_id).createRole(name);
17
+ return {
18
+ success: true,
19
+ message: `已创建角色 "${name}"`,
20
+ role: { id: role.role_id, name: role.name },
21
+ };
22
+ },
23
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { platformPermit } from '../../src/platform-permit.js';
3
+ import { platformPermission } from '@zhin.js/permission';
4
4
 
5
5
  export default defineAgentTool<{ guild_id: string; name: string }>({
6
6
  description: '在 KOOK 服务器中创建新角色',
@@ -10,7 +10,7 @@ export default defineAgentTool<{ guild_id: string; name: string }>({
10
10
  }),
11
11
  adapter: 'kook',
12
12
  tags: ['kook'],
13
- permissions: [platformPermit('guild_owner')],
13
+ permissions: [platformPermission('kook', 'guild_owner')],
14
14
  async execute({ guild_id, name }: { guild_id: string; name: string }, context) {
15
15
  const client = context.$client;
16
16
  const role = await client.pickGuild(guild_id).createRole(name);
@@ -0,0 +1,19 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { platformPermission } from '@zhin.js/permission';
5
+ export default defineAgentTool({
6
+ description: '删除 KOOK 服务器中的角色',
7
+ inputSchema: z.object({
8
+ guild_id: z.string().describe('服务器 ID'),
9
+ role_id: z.string().describe('角色 ID'),
10
+ }),
11
+ adapter: 'kook',
12
+ tags: ['kook'],
13
+ permissions: [platformPermission('kook', 'guild_owner')],
14
+ async execute({ guild_id, role_id }, context) {
15
+ const client = context.$client;
16
+ const success = await client.pickGuild(guild_id).deleteRole(role_id);
17
+ return { success, message: success ? `已删除角色 ${role_id}` : '删除角色失败' };
18
+ },
19
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { platformPermit } from '../../src/platform-permit.js';
3
+ import { platformPermission } from '@zhin.js/permission';
4
4
 
5
5
  export default defineAgentTool<{ guild_id: string; role_id: string }>({
6
6
  description: '删除 KOOK 服务器中的角色',
@@ -10,7 +10,7 @@ export default defineAgentTool<{ guild_id: string; role_id: string }>({
10
10
  }),
11
11
  adapter: 'kook',
12
12
  tags: ['kook'],
13
- permissions: [platformPermit('guild_owner')],
13
+ permissions: [platformPermission('kook', 'guild_owner')],
14
14
  async execute({ guild_id, role_id }: { guild_id: string; role_id: string }, context) {
15
15
  const client = context.$client;
16
16
  const success = await client.pickGuild(guild_id).deleteRole(role_id);
@@ -0,0 +1,20 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { platformPermission } from '@zhin.js/permission';
5
+ export default defineAgentTool({
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: [platformPermission('kook', 'manage_roles')],
15
+ async execute({ guild_id, user_id, role_id }, 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
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { platformPermit } from '../../src/platform-permit.js';
3
+ import { platformPermission } from '@zhin.js/permission';
4
4
 
5
5
  export default defineAgentTool<{ guild_id: string; user_id: string; role_id: string }>({
6
6
  description: '给用户授予 KOOK 服务器角色',
@@ -11,7 +11,7 @@ export default defineAgentTool<{ guild_id: string; user_id: string; role_id: str
11
11
  }),
12
12
  adapter: 'kook',
13
13
  tags: ['kook'],
14
- permissions: [platformPermit('manage_roles')],
14
+ permissions: [platformPermission('kook', 'manage_roles')],
15
15
  async execute({ guild_id, user_id, role_id }: { guild_id: string; user_id: string; role_id: string }, context) {
16
16
  const client = context.$client;
17
17
  const success = await client.pickGuildMember(guild_id, user_id).grant(role_id);
@@ -0,0 +1,25 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ export default defineAgentTool({
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 }, 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
+ });
@@ -1,4 +1,4 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
3
 
4
4
  export default defineAgentTool<{ guild_id: string }>({
@@ -0,0 +1,20 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineAgentTool } from '@zhin.js/tool';
3
+ import { z } from 'zod';
4
+ import { platformPermission } from '@zhin.js/permission';
5
+ export default defineAgentTool({
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: [platformPermission('kook', 'manage_roles')],
15
+ async execute({ guild_id, user_id, role_id }, 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
+ });
@@ -1,6 +1,6 @@
1
- import { defineAgentTool } from '@zhin.js/agent/tools';
1
+ import { defineAgentTool } from '@zhin.js/tool';
2
2
  import { z } from 'zod';
3
- import { platformPermit } from '../../src/platform-permit.js';
3
+ import { platformPermission } from '@zhin.js/permission';
4
4
 
5
5
  export default defineAgentTool<{ guild_id: string; user_id: string; role_id: string }>({
6
6
  description: '撤销用户的 KOOK 服务器角色',
@@ -11,7 +11,7 @@ export default defineAgentTool<{ guild_id: string; user_id: string; role_id: str
11
11
  }),
12
12
  adapter: 'kook',
13
13
  tags: ['kook'],
14
- permissions: [platformPermit('manage_roles')],
14
+ permissions: [platformPermission('kook', 'manage_roles')],
15
15
  async execute({ guild_id, user_id, role_id }: { guild_id: string; user_id: string; role_id: string }, context) {
16
16
  const client = context.$client;
17
17
  const success = await client.pickGuildMember(guild_id, user_id).revoke(role_id);
@@ -0,0 +1,3 @@
1
+ # KOOK Platform Agent
2
+
3
+ You are the kook platform specialist. Interpret requests in the current kook conversation and load only the narrowest private Skill needed for the task.
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { kookEndpointCommands } from "../../../lib/kook-endpoint-commands.js";
2
+ import { kookEndpointCommands } from '../../definition.js';
3
3
  export default kookEndpointCommands.add;
@@ -0,0 +1,3 @@
1
+ import { kookEndpointCommands } from '../../definition.js';
2
+
3
+ export default kookEndpointCommands.add;
@@ -1,10 +1,11 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
1
2
  /**
2
- * `kook.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
- * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
3
+ * `kook endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
4
+ * commands/kook/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
5
  */
5
6
  import { createEndpointCommands } from 'zhin.js/adapter';
6
7
  import { defineCommand } from 'zhin.js/command';
7
- import { kookRuntimeStateToken } from './kook-runtime-state.js';
8
+ import { kookRuntimeStateToken } from "../../../lib/kook-runtime-state.js";
8
9
  export const kookEndpointCommands = createEndpointCommands({
9
10
  adapterKey: 'kook',
10
11
  adapterDisplayName: 'KOOK',
@@ -1,10 +1,10 @@
1
1
  /**
2
- * `kook.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
- * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
2
+ * `kook endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
+ * commands/kook/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
4
  */
5
5
  import { createEndpointCommands } from 'zhin.js/adapter';
6
6
  import { defineCommand } from 'zhin.js/command';
7
- import { kookRuntimeStateToken } from './kook-runtime-state.js';
7
+ import { kookRuntimeStateToken } from '../../../src/kook-runtime-state.js';
8
8
 
9
9
  export const kookEndpointCommands = createEndpointCommands({
10
10
  adapterKey: 'kook',
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { kookEndpointCommands } from "../../lib/kook-endpoint-commands.js";
2
+ import { kookEndpointCommands } from '../definition.js';
3
3
  export default kookEndpointCommands.list;
@@ -0,0 +1,3 @@
1
+ import { kookEndpointCommands } from '../definition.js';
2
+
3
+ export default kookEndpointCommands.list;
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { kookEndpointCommands } from "../../../lib/kook-endpoint-commands.js";
2
+ import { kookEndpointCommands } from '../../definition.js';
3
3
  export default kookEndpointCommands.remove;
@@ -0,0 +1,3 @@
1
+ import { kookEndpointCommands } from '../../definition.js';
2
+
3
+ export default kookEndpointCommands.remove;
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { formatInboundContent, formatOutboundKmarkdown, resolveKookConfig, senderDisplayName, KookPermission, type KookAdapterConfig, type KookInboundMessage, type KookWireSegment, type LogLevel, type ResolvedKookConfig, type ResolvedKookWebhookConfig, type ResolvedKookWebsocketConfig, } from './protocol.js';
1
+ export { formatInboundContent, formatOutboundKmarkdown, resolveKookConfig, senderDisplayName, KookPermission, type KookEndpointConfig, type KookInboundMessage, type KookWireSegment, type LogLevel, type ResolvedKookConfig, type ResolvedKookWebhookConfig, type ResolvedKookWebsocketConfig, } from './protocol.js';
2
2
  export { KookWebhookEndpoint, KookWebsocketEndpoint, type KookEndpointOptions, type KookWebhookEndpointOptions, } from './endpoint.js';
3
3
  export { registerKookWebhookRoutes, handleKookWebhookRequest, type KookWebhookHandler, } from './webhook.js';
4
4
  export { defaultCreateClient, defaultCreateWebhookClient, normalizeKookMessage, type CreateKookClient, type KookClientTransport, } from './ws.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * KOOK 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
- * 由 plugin.ts setup() provide,adapter create 与 `kook.endpoint` 命令共享(同一 owner generation)。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `kook endpoint` 命令共享(同一 owner generation)。
4
4
  */
5
5
  import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
6
  export const kookRuntimeStateToken = defineEndpointRuntimeStateToken('kook');
package/lib/protocol.d.ts CHANGED
@@ -1,9 +1,6 @@
1
- /**
2
- * KOOK protocol helpers — no legacy Adapter/Endpoint / segment-mapper.
3
- * Canonicalization is owned by gateway/core before endpoint.send.
4
- */
1
+ /** KOOK protocol helpers. Canonicalization is owned by Core. */
5
2
  import type { IncomingMessage } from 'node:http';
6
- import type { ConversationRef } from '@zhin.js/im-contract';
3
+ import { type ConversationRef } from '@zhin.js/im-contract';
7
4
  export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'mark' | 'off';
8
5
  export declare enum KookPermission {
9
6
  Normal = 1,
@@ -11,10 +8,10 @@ export declare enum KookPermission {
11
8
  Owner = 4,
12
9
  ChannelAdmin = 5
13
10
  }
14
- /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
15
- export interface KookAdapterConfig {
16
- readonly id?: string;
17
- readonly token?: string;
11
+ /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
12
+ export interface KookEndpointConfig {
13
+ readonly id: string;
14
+ readonly token: string;
18
15
  /** Default `websocket`. `webhook` requires httpHostToken + verify_token. */
19
16
  readonly connection?: 'websocket' | 'webhook';
20
17
  readonly webhookPath?: string;
@@ -25,21 +22,6 @@ export interface KookAdapterConfig {
25
22
  readonly max_retry?: number;
26
23
  readonly ignore?: 'bot' | 'self';
27
24
  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
25
  }
44
26
  export interface ResolvedKookWebsocketConfig {
45
27
  readonly context: 'kook';
@@ -107,7 +89,7 @@ export interface KookWireSegment {
107
89
  readonly type: string;
108
90
  readonly data?: Record<string, unknown>;
109
91
  }
110
- export declare function resolveKookConfig(config?: KookAdapterConfig): ResolvedKookConfig;
92
+ export declare function resolveKookConfig(config: KookEndpointConfig): ResolvedKookConfig;
111
93
  /**
112
94
  * 入站归一化 → ConversationRef:频道消息的所属 guild 进 `parent`(guild 容器
113
95
  * 映射为 channel 容器);私聊(PERSON)无容器,直接 kind 'private'。
package/lib/protocol.js CHANGED
@@ -1,11 +1,7 @@
1
- /**
2
- * KOOK protocol helpers — no legacy Adapter/Endpoint / segment-mapper.
3
- * Canonicalization is owned by gateway/core before endpoint.send.
4
- */
1
+ /** KOOK protocol helpers. Canonicalization is owned by Core. */
5
2
  import { createDecipheriv, timingSafeEqual } from 'node:crypto';
6
3
  import { inflateSync } from 'node:zlib';
7
- import { pickCredential } from 'zhin.js/adapter';
8
- import { isMediaRef } from '@zhin.js/core';
4
+ import { isMediaRef } from '@zhin.js/im-contract';
9
5
  import { formatCompact, getLogger } from '@zhin.js/logger';
10
6
  const logger = getLogger('kook');
11
7
  export var KookPermission;
@@ -15,38 +11,23 @@ export var KookPermission;
15
11
  KookPermission[KookPermission["Owner"] = 4] = "Owner";
16
12
  KookPermission[KookPermission["ChannelAdmin"] = 5] = "ChannelAdmin";
17
13
  })(KookPermission || (KookPermission = {}));
18
- export function resolveKookConfig(config = {}) {
19
- const entry = config.endpoints?.find((item) => item.context === 'kook' || !item.context);
20
- const token = pickCredential(config.token, entry?.token, process.env.KOOK_TOKEN, process.env.KOOK_BOT_TOKEN);
21
- if (!token) {
22
- throw new TypeError('KOOK adapter requires token (plugins.<key>.token or endpoints with context: kook)');
23
- }
24
- const id = (typeof config.id === 'string' && config.id)
25
- || (typeof entry?.id === 'string' && entry.id)
26
- || process.env.KOOK_BOT_NAME
27
- || 'kook-bot';
28
- const connection = config.connection
29
- ?? entry?.connection
30
- ?? 'websocket';
14
+ export function resolveKookConfig(config) {
15
+ const id = requiredEndpointField(config.id, 'id');
16
+ const token = requiredEndpointField(config.token, 'token');
17
+ const connection = config.connection ?? 'websocket';
31
18
  if (connection === 'webhook') {
32
- const verifyToken = (typeof config.verify_token === 'string' && config.verify_token)
33
- || (typeof entry?.verify_token === 'string' && entry.verify_token)
34
- || process.env.KOOK_VERIFY_TOKEN
35
- || '';
36
- if (!verifyToken) {
37
- throw new TypeError('KOOK webhook mode requires verify_token (plugins.<key>.verify_token or KOOK_VERIFY_TOKEN)');
38
- }
39
- const encryptKey = config.encrypt_key ?? entry?.encrypt_key ?? process.env.KOOK_ENCRYPT_KEY;
19
+ const verifyToken = requiredEndpointField(config.verify_token, 'verify_token');
20
+ const encryptKey = config.encrypt_key;
40
21
  return {
41
22
  context: 'kook',
42
23
  connection: 'webhook',
43
24
  id,
44
25
  token,
45
- webhookPath: normalizeWebhookPath(config.webhookPath ?? entry?.webhookPath ?? process.env.KOOK_WEBHOOK_PATH ?? '/kook/webhook'),
26
+ webhookPath: normalizeWebhookPath(config.webhookPath ?? '/kook/webhook'),
46
27
  verifyToken,
47
28
  encryptKey: typeof encryptKey === 'string' && encryptKey ? encryptKey : undefined,
48
- ignore: config.ignore ?? entry?.ignore ?? 'bot',
49
- logLevel: config.logLevel ?? entry?.logLevel ?? 'info',
29
+ ignore: config.ignore ?? 'bot',
30
+ logLevel: config.logLevel ?? 'info',
50
31
  };
51
32
  }
52
33
  return {
@@ -54,13 +35,19 @@ export function resolveKookConfig(config = {}) {
54
35
  connection: 'websocket',
55
36
  id,
56
37
  token,
57
- data_dir: config.data_dir ?? entry?.data_dir,
58
- timeout: config.timeout ?? entry?.timeout ?? 10_000,
59
- max_retry: config.max_retry ?? entry?.max_retry ?? 3,
60
- ignore: config.ignore ?? entry?.ignore ?? 'bot',
61
- logLevel: config.logLevel ?? entry?.logLevel ?? 'info',
38
+ data_dir: config.data_dir,
39
+ timeout: config.timeout ?? 10_000,
40
+ max_retry: config.max_retry ?? 3,
41
+ ignore: config.ignore ?? 'bot',
42
+ logLevel: config.logLevel ?? 'info',
62
43
  };
63
44
  }
45
+ function requiredEndpointField(value, field) {
46
+ if (typeof value !== 'string' || !value.trim()) {
47
+ throw new TypeError(`KOOK endpoint requires a non-empty ${field}`);
48
+ }
49
+ return value.trim();
50
+ }
64
51
  /**
65
52
  * 入站归一化 → ConversationRef:频道消息的所属 guild 进 `parent`(guild 容器
66
53
  * 映射为 channel 容器);私聊(PERSON)无容器,直接 kind 'private'。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-kook",
3
- "version": "1.1.0",
3
+ "version": "1.1.3",
4
4
  "description": "Zhin.js KOOK adapter for Plugin Runtime (WebSocket gateway or Webhook)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -34,26 +34,25 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "kook-client": "^1.0.4",
37
- "@zhin.js/adapter": "1.1.12",
38
- "@zhin.js/core": "1.1.35",
39
- "@zhin.js/feature-kit": "1.1.0",
40
- "@zhin.js/host-http": "1.1.0",
41
- "@zhin.js/im-contract": "1.1.0",
42
- "@zhin.js/logger": "1.1.0",
43
- "@zhin.js/permission": "1.1.0"
37
+ "@zhin.js/adapter": "1.1.15",
38
+ "@zhin.js/agent-feature": "1.1.2",
39
+ "@zhin.js/core": "1.1.38",
40
+ "@zhin.js/feature-kit": "1.1.2",
41
+ "@zhin.js/host-http": "1.1.2",
42
+ "@zhin.js/im-contract": "1.1.2",
43
+ "@zhin.js/logger": "1.1.1",
44
+ "@zhin.js/permission": "1.1.2",
45
+ "@zhin.js/skill": "1.1.2",
46
+ "@zhin.js/tool": "1.1.2"
44
47
  },
45
48
  "peerDependencies": {
46
49
  "zod": "^4.0.0",
47
- "@zhin.js/adapter": "^1.1.12",
48
- "@zhin.js/agent": "^1.1.23",
49
- "@zhin.js/command": "^1.1.0",
50
- "@zhin.js/core": "^1.1.35",
51
- "zhin.js": "^1.1.0"
50
+ "@zhin.js/adapter": "^1.1.15",
51
+ "@zhin.js/command": "^1.1.2",
52
+ "@zhin.js/core": "^1.1.38",
53
+ "zhin.js": "^1.1.3"
52
54
  },
53
55
  "peerDependenciesMeta": {
54
- "@zhin.js/agent": {
55
- "optional": true
56
- },
57
56
  "@zhin.js/command": {
58
57
  "optional": true
59
58
  },
@@ -69,9 +68,8 @@
69
68
  "typescript": "^6.0.3",
70
69
  "vitest": "^4.1.10",
71
70
  "zod": "^4.4.3",
72
- "@zhin.js/agent": "1.1.23",
73
- "@zhin.js/host-http": "1.1.0",
74
- "zhin.js": "1.1.0"
71
+ "@zhin.js/host-http": "1.1.2",
72
+ "zhin.js": "1.1.3"
75
73
  },
76
74
  "files": [
77
75
  "adapters",
@@ -80,9 +78,11 @@
80
78
  "schema.json",
81
79
  "src",
82
80
  "lib",
83
- "agent",
81
+ "tools",
82
+ "agents",
84
83
  "README.md",
85
- "CHANGELOG.md"
84
+ "CHANGELOG.md",
85
+ "PERMITS.md"
86
86
  ],
87
87
  "publishConfig": {
88
88
  "access": "public",
@@ -105,6 +105,18 @@
105
105
  {
106
106
  "package": "@zhin.js/command",
107
107
  "api": "^1.0.0"
108
+ },
109
+ {
110
+ "package": "@zhin.js/tool",
111
+ "api": "^1.0.0"
112
+ },
113
+ {
114
+ "package": "@zhin.js/skill",
115
+ "api": "^1.0.0"
116
+ },
117
+ {
118
+ "package": "@zhin.js/agent-feature",
119
+ "api": "^1.0.0"
108
120
  }
109
121
  ],
110
122
  "plugins": []
package/schema.json CHANGED
@@ -70,10 +70,11 @@
70
70
  },
71
71
  "endpoints": {
72
72
  "type": "array",
73
- "description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(id 必填,其余覆盖顶层)",
73
+ "minItems": 1,
74
+ "description": "多账号:每项定义一个 endpoint,id/token 必填,其余字段覆盖实例默认值",
74
75
  "items": {
75
76
  "type": "object",
76
- "additionalProperties": true,
77
+ "additionalProperties": false,
77
78
  "properties": {
78
79
  "master": {
79
80
  "type": [
@@ -97,6 +98,16 @@
97
98
  "type": "string",
98
99
  "description": "KOOK bot token"
99
100
  },
101
+ "connection": {
102
+ "type": "string",
103
+ "enum": [
104
+ "websocket",
105
+ "webhook"
106
+ ]
107
+ },
108
+ "webhookPath": {
109
+ "type": "string"
110
+ },
100
111
  "verify_token": {
101
112
  "type": "string",
102
113
  "description": "KOOK developer console verify token (required for webhook mode)."
@@ -105,6 +116,38 @@
105
116
  "type": "string",
106
117
  "description": "Optional Encrypt Key when message encryption is enabled in KOOK console."
107
118
  },
119
+ "data_dir": {
120
+ "type": "string"
121
+ },
122
+ "timeout": {
123
+ "type": "number"
124
+ },
125
+ "max_retry": {
126
+ "type": "number"
127
+ },
128
+ "ignore": {
129
+ "type": "string",
130
+ "enum": [
131
+ "bot",
132
+ "self"
133
+ ]
134
+ },
135
+ "logLevel": {
136
+ "type": "string",
137
+ "enum": [
138
+ "trace",
139
+ "debug",
140
+ "info",
141
+ "warn",
142
+ "error",
143
+ "fatal",
144
+ "mark",
145
+ "off"
146
+ ]
147
+ },
148
+ "commandPrefix": {
149
+ "type": "string"
150
+ },
108
151
  "id": {
109
152
  "type": "string",
110
153
  "description": "KOOK bot name"
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ export {
4
4
  resolveKookConfig,
5
5
  senderDisplayName,
6
6
  KookPermission,
7
- type KookAdapterConfig,
7
+ type KookEndpointConfig,
8
8
  type KookInboundMessage,
9
9
  type KookWireSegment,
10
10
  type LogLevel,
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * KOOK 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
- * 由 plugin.ts setup() provide,adapter create 与 `kook.endpoint` 命令共享(同一 owner generation)。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `kook endpoint` 命令共享(同一 owner generation)。
4
4
  */
5
5
  import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
6
 
package/src/protocol.ts CHANGED
@@ -1,14 +1,9 @@
1
- /**
2
- * KOOK protocol helpers — no legacy Adapter/Endpoint / segment-mapper.
3
- * Canonicalization is owned by gateway/core before endpoint.send.
4
- */
1
+ /** KOOK protocol helpers. Canonicalization is owned by Core. */
5
2
 
6
3
  import { createDecipheriv, timingSafeEqual } from 'node:crypto';
7
4
  import { inflateSync } from 'node:zlib';
8
5
  import type { IncomingMessage } from 'node:http';
9
- import { pickCredential } from 'zhin.js/adapter';
10
- import { isMediaRef } from '@zhin.js/core';
11
- import type { ConversationRef } from '@zhin.js/im-contract';
6
+ import { isMediaRef, type ConversationRef } from '@zhin.js/im-contract';
12
7
  import { formatCompact, getLogger } from '@zhin.js/logger';
13
8
 
14
9
  const logger = getLogger('kook');
@@ -30,10 +25,10 @@ export enum KookPermission {
30
25
  ChannelAdmin = 5,
31
26
  }
32
27
 
33
- /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
34
- export interface KookAdapterConfig {
35
- readonly id?: string;
36
- readonly token?: string;
28
+ /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
29
+ export interface KookEndpointConfig {
30
+ readonly id: string;
31
+ readonly token: string;
37
32
  /** Default `websocket`. `webhook` requires httpHostToken + verify_token. */
38
33
  readonly connection?: 'websocket' | 'webhook';
39
34
  readonly webhookPath?: string;
@@ -44,21 +39,6 @@ export interface KookAdapterConfig {
44
39
  readonly max_retry?: number;
45
40
  readonly ignore?: 'bot' | 'self';
46
41
  readonly logLevel?: LogLevel;
47
- /** Transitional: legacy root `endpoints[]` with `context: kook`. */
48
- readonly endpoints?: ReadonlyArray<{
49
- readonly context?: string;
50
- readonly id?: string;
51
- readonly token?: string;
52
- readonly connection?: 'websocket' | 'webhook';
53
- readonly webhookPath?: string;
54
- readonly verify_token?: string;
55
- readonly encrypt_key?: string;
56
- readonly data_dir?: string;
57
- readonly timeout?: number;
58
- readonly max_retry?: number;
59
- readonly ignore?: 'bot' | 'self';
60
- readonly logLevel?: LogLevel;
61
- }>;
62
42
  }
63
43
 
64
44
  export interface ResolvedKookWebsocketConfig {
@@ -134,45 +114,26 @@ export interface KookWireSegment {
134
114
  readonly data?: Record<string, unknown>;
135
115
  }
136
116
 
137
- export function resolveKookConfig(config: KookAdapterConfig = {}): ResolvedKookConfig {
138
- const entry = config.endpoints?.find((item) => item.context === 'kook' || !item.context);
139
- const token = pickCredential(config.token, entry?.token, process.env.KOOK_TOKEN, process.env.KOOK_BOT_TOKEN);
140
- if (!token) {
141
- throw new TypeError(
142
- 'KOOK adapter requires token (plugins.<key>.token or endpoints with context: kook)',
143
- );
144
- }
145
- const id = (typeof config.id === 'string' && config.id)
146
- || (typeof entry?.id === 'string' && entry.id)
147
- || process.env.KOOK_BOT_NAME
148
- || 'kook-bot';
149
- const connection = config.connection
150
- ?? entry?.connection
151
- ?? 'websocket';
117
+ export function resolveKookConfig(config: KookEndpointConfig): ResolvedKookConfig {
118
+ const id = requiredEndpointField(config.id, 'id');
119
+ const token = requiredEndpointField(config.token, 'token');
120
+ const connection = config.connection ?? 'websocket';
152
121
 
153
122
  if (connection === 'webhook') {
154
- const verifyToken = (typeof config.verify_token === 'string' && config.verify_token)
155
- || (typeof entry?.verify_token === 'string' && entry.verify_token)
156
- || process.env.KOOK_VERIFY_TOKEN
157
- || '';
158
- if (!verifyToken) {
159
- throw new TypeError(
160
- 'KOOK webhook mode requires verify_token (plugins.<key>.verify_token or KOOK_VERIFY_TOKEN)',
161
- );
162
- }
163
- const encryptKey = config.encrypt_key ?? entry?.encrypt_key ?? process.env.KOOK_ENCRYPT_KEY;
123
+ const verifyToken = requiredEndpointField(config.verify_token, 'verify_token');
124
+ const encryptKey = config.encrypt_key;
164
125
  return {
165
126
  context: 'kook',
166
127
  connection: 'webhook',
167
128
  id,
168
129
  token,
169
130
  webhookPath: normalizeWebhookPath(
170
- config.webhookPath ?? entry?.webhookPath ?? process.env.KOOK_WEBHOOK_PATH ?? '/kook/webhook',
131
+ config.webhookPath ?? '/kook/webhook',
171
132
  ),
172
133
  verifyToken,
173
134
  encryptKey: typeof encryptKey === 'string' && encryptKey ? encryptKey : undefined,
174
- ignore: config.ignore ?? entry?.ignore ?? 'bot',
175
- logLevel: config.logLevel ?? entry?.logLevel ?? 'info',
135
+ ignore: config.ignore ?? 'bot',
136
+ logLevel: config.logLevel ?? 'info',
176
137
  };
177
138
  }
178
139
 
@@ -181,14 +142,24 @@ export function resolveKookConfig(config: KookAdapterConfig = {}): ResolvedKookC
181
142
  connection: 'websocket',
182
143
  id,
183
144
  token,
184
- data_dir: config.data_dir ?? entry?.data_dir,
185
- timeout: config.timeout ?? entry?.timeout ?? 10_000,
186
- max_retry: config.max_retry ?? entry?.max_retry ?? 3,
187
- ignore: config.ignore ?? entry?.ignore ?? 'bot',
188
- logLevel: config.logLevel ?? entry?.logLevel ?? 'info',
145
+ data_dir: config.data_dir,
146
+ timeout: config.timeout ?? 10_000,
147
+ max_retry: config.max_retry ?? 3,
148
+ ignore: config.ignore ?? 'bot',
149
+ logLevel: config.logLevel ?? 'info',
189
150
  };
190
151
  }
191
152
 
153
+ function requiredEndpointField(
154
+ value: unknown,
155
+ field: 'id' | 'token' | 'verify_token',
156
+ ): string {
157
+ if (typeof value !== 'string' || !value.trim()) {
158
+ throw new TypeError(`KOOK endpoint requires a non-empty ${field}`);
159
+ }
160
+ return value.trim();
161
+ }
162
+
192
163
  /**
193
164
  * 入站归一化 → ConversationRef:频道消息的所属 guild 进 `parent`(guild 容器
194
165
  * 映射为 channel 容器);私聊(PERSON)无容器,直接 kind 'private'。
@@ -1,80 +0,0 @@
1
- ---
2
- name: kook
3
- platforms:
4
- - kook
5
- description: >-
6
- KOOK 服务器管理能力。当用户在 KOOK 中请求群管(踢人、封禁、解封、改昵称)、
7
- 角色管理(创建/删除/授予/撤销角色)、黑名单操作或查询成员列表时使用。
8
- 即使用户没有提到 KOOK,只要上下文是 KOOK 场景且涉及上述操作,就应触发。
9
- 仅有昵称时必须先 list_members 获取 user_id。
10
- keywords:
11
- - kook
12
- - KOOK
13
- - adapter:kook
14
- - 群管理
15
- - 角色
16
- - 黑名单
17
- - 封禁
18
- - list_members
19
- tags:
20
- - group
21
- - management
22
- - im
23
- tools:
24
- - kook_grant_role
25
- - kook_revoke_role
26
- - kook_list_roles
27
- - kook_create_role
28
- - kook_delete_role
29
- - kook_blacklist
30
- - kook_kick_member
31
- - kook_ban_member
32
- - kook_unban_member
33
- - kook_set_nickname
34
- - kook_list_members
35
- ---
36
-
37
- # KOOK 服务器管理技能
38
-
39
- KOOK 的管理模型类似 Discord,以角色为核心。此技能覆盖成员管理和角色系统。
40
-
41
- ## 核心原则
42
-
43
- ### ID 获取链
44
-
45
- 操作成员需要 KOOK 用户 ID,操作角色需要角色 ID:
46
- - `kook_list_members` → 获取用户 ID
47
- - `kook_list_roles` → 获取角色 ID
48
-
49
- ### 黑名单 ≠ 踢人
50
-
51
- `kook_blacklist` 是永久性封禁,被拉黑的用户无法再加入服务器。`kook_kick_member` 只是移除,用户可以通过邀请重新加入。
52
-
53
- ## 工具详解
54
-
55
- ### 成员管理
56
-
57
- | 工具 | 用途 | 说明 |
58
- |------|------|------|
59
- | `kook_kick_member` | 踢出 | 可重新加入 |
60
- | `kook_ban_member` | 封禁 | 阻止重新加入 |
61
- | `kook_unban_member` | 解除封禁 | — |
62
- | `kook_set_nickname` | 改昵称 | 服务器内昵称 |
63
- | `kook_list_members` | 成员列表 | — |
64
- | `kook_blacklist` | 黑名单操作 | **不可逆,谨慎使用** |
65
-
66
- ### 角色管理
67
-
68
- | 工具 | 用途 | 说明 |
69
- |------|------|------|
70
- | `kook_create_role` | 创建角色 | — |
71
- | `kook_delete_role` | 删除角色 | — |
72
- | `kook_grant_role` | 授予角色 | 需 user_id + role_id |
73
- | `kook_revoke_role` | 撤销角色 | 需 user_id + role_id |
74
- | `kook_list_roles` | 角色列表 | 获取所有角色及 ID |
75
-
76
- ## 易错点
77
-
78
- 1. **黑名单是永久封禁**,与普通踢人(kick)不同。用户说「把他踢了」用 kick,说「永久拉黑」才用 blacklist。
79
- 2. **角色操作需要 role_id**,先 `kook_list_roles` 查询。
80
- 3. **创建角色后还需要 grant_role 才能给成员分配**,创建 ≠ 分配。
@@ -1,3 +0,0 @@
1
- import { kookEndpointCommands } from '../../../src/kook-endpoint-commands.js';
2
-
3
- export default kookEndpointCommands.add;
@@ -1,3 +0,0 @@
1
- import { kookEndpointCommands } from '../../src/kook-endpoint-commands.js';
2
-
3
- export default kookEndpointCommands.list;
@@ -1,3 +0,0 @@
1
- import { kookEndpointCommands } from '../../../src/kook-endpoint-commands.js';
2
-
3
- export default kookEndpointCommands.remove;
@@ -1 +0,0 @@
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>>>;
File without changes