@zhin.js/adapter-onebot11 1.1.0 → 1.1.2

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 (40) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/README.md +8 -6
  3. package/adapters/{onebot11.js → onebot11/index.js} +8 -8
  4. package/adapters/{onebot11.ts → onebot11/index.ts} +14 -14
  5. package/agents/onebot11/agent.json +20 -0
  6. package/agents/onebot11/boundaries.md +3 -0
  7. package/agents/onebot11/conventions.md +3 -0
  8. package/agents/onebot11/skills/onebot11/SKILL.md +15 -0
  9. package/agents/onebot11/skills/onebot11/tools/set_title/index.js +25 -0
  10. package/{agent/tools/set_title.ts → agents/onebot11/skills/onebot11/tools/set_title/index.ts} +1 -1
  11. package/agents/onebot11/system.md +3 -0
  12. package/commands/{endpoint/add/[id].js → onebot11/endpoint/add/[id]/index.js} +1 -1
  13. package/commands/onebot11/endpoint/add/[id]/index.ts +3 -0
  14. package/{lib/onebot11-endpoint-commands.js → commands/onebot11/endpoint/definition.js} +4 -3
  15. package/{src/onebot11-endpoint-commands.ts → commands/onebot11/endpoint/definition.ts} +3 -3
  16. package/commands/{endpoint/list.js → onebot11/endpoint/list/index.js} +1 -1
  17. package/commands/onebot11/endpoint/list/index.ts +3 -0
  18. package/commands/{endpoint/remove/[id].js → onebot11/endpoint/remove/[id]/index.js} +1 -1
  19. package/commands/onebot11/endpoint/remove/[id]/index.ts +3 -0
  20. package/lib/index.d.ts +2 -2
  21. package/lib/index.js +1 -1
  22. package/lib/onebot11-runtime-state.js +1 -1
  23. package/lib/protocol.d.ts +5 -22
  24. package/lib/protocol.js +37 -26
  25. package/lib/ws-transport.d.ts +0 -1
  26. package/lib/ws-transport.js +1 -13
  27. package/lib/wss-endpoint.js +63 -50
  28. package/package.json +33 -21
  29. package/schema.json +18 -1
  30. package/src/index.ts +0 -2
  31. package/src/onebot11-runtime-state.ts +1 -1
  32. package/src/protocol.ts +43 -50
  33. package/src/ws-transport.ts +1 -16
  34. package/src/wss-endpoint.ts +59 -48
  35. package/agent/skills/onebot11.md +0 -80
  36. package/commands/endpoint/add/[id].ts +0 -3
  37. package/commands/endpoint/list.ts +0 -3
  38. package/commands/endpoint/remove/[id].ts +0 -3
  39. package/lib/onebot11-endpoint-commands.d.ts +0 -1
  40. /package/{agent/PERMITS.md → PERMITS.md} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,100 @@
1
1
  # @zhin.js/adapter-onebot11
2
2
 
3
+ ## 1.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 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`.
8
+ - 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.
9
+
10
+ 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.
11
+
12
+ 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.
13
+
14
+ 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.
15
+
16
+ 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`.
17
+
18
+ - 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.
19
+ - 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.
20
+ - 4380cf9: Colocate adapter command definitions and Agent Skill handlers with their owning capabilities, and provide a shared validated platform permission constructor.
21
+ - d08d3d3: Require one canonical expanded OneBot 11 endpoint configuration. Remove nested endpoint, environment, `type: ws_reverse`, and standalone heartbeat compatibility surfaces; reverse WebSocket connection replacement, heartbeat, pending actions, and stale-event admission now share the endpoint lifecycle.
22
+ - 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.
23
+ - 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.
24
+ - Updated dependencies [c861789]
25
+ - Updated dependencies [1414ccb]
26
+ - Updated dependencies [743d470]
27
+ - Updated dependencies [62dee52]
28
+ - Updated dependencies [cd54131]
29
+ - Updated dependencies [244e475]
30
+ - Updated dependencies [a9e4a40]
31
+ - Updated dependencies [5855db7]
32
+ - Updated dependencies [ec921d2]
33
+ - Updated dependencies [8740059]
34
+ - Updated dependencies [63d1f7a]
35
+ - Updated dependencies [25a845a]
36
+ - Updated dependencies [103f2c3]
37
+ - Updated dependencies [9110ab8]
38
+ - Updated dependencies [cd2a888]
39
+ - Updated dependencies [eb3227a]
40
+ - Updated dependencies [b853dba]
41
+ - Updated dependencies [e561309]
42
+ - Updated dependencies [d4c6175]
43
+ - Updated dependencies [7a0e1ca]
44
+ - Updated dependencies [103b5d3]
45
+ - Updated dependencies [5a7a7f7]
46
+ - Updated dependencies [b076eae]
47
+ - Updated dependencies [535fed1]
48
+ - Updated dependencies [73a24b7]
49
+ - Updated dependencies [4380cf9]
50
+ - Updated dependencies [2dbbc15]
51
+ - Updated dependencies [1cb1163]
52
+ - Updated dependencies [be3061e]
53
+ - Updated dependencies [75f8332]
54
+ - Updated dependencies [81935e2]
55
+ - Updated dependencies [f9ed01b]
56
+ - Updated dependencies [ac0ab50]
57
+ - Updated dependencies [5140ce1]
58
+ - Updated dependencies [522d75f]
59
+ - Updated dependencies [a7611b3]
60
+ - Updated dependencies [8823044]
61
+ - Updated dependencies [379439b]
62
+ - Updated dependencies [11c9352]
63
+ - Updated dependencies [6b70e46]
64
+ - Updated dependencies [135ac91]
65
+ - Updated dependencies [140cf0f]
66
+ - Updated dependencies [251e4d2]
67
+ - Updated dependencies [203ad34]
68
+ - Updated dependencies [e6c5113]
69
+ - Updated dependencies [e0f6478]
70
+ - Updated dependencies [baef56b]
71
+ - Updated dependencies [698f16f]
72
+ - Updated dependencies [da0a8e3]
73
+ - Updated dependencies [2fd8017]
74
+ - Updated dependencies [5c3858e]
75
+ - Updated dependencies [33ea736]
76
+ - Updated dependencies [507d602]
77
+ - Updated dependencies [df9f76b]
78
+ - @zhin.js/core@1.1.37
79
+ - @zhin.js/tool@1.1.1
80
+ - @zhin.js/host-http@1.1.1
81
+ - @zhin.js/adapter@1.1.14
82
+ - @zhin.js/feature-kit@1.1.1
83
+ - @zhin.js/agent-feature@1.1.1
84
+ - @zhin.js/skill@1.1.1
85
+ - @zhin.js/logger@1.1.1
86
+ - @zhin.js/im-contract@1.1.1
87
+ - @zhin.js/permission@1.1.1
88
+
89
+ ## 1.1.1
90
+
91
+ ### Patch Changes
92
+
93
+ - 33b1582: Update vulnerable dependencies and replace unsafe HTML and protocol-text regular expressions with bounded scanners.
94
+ - Updated dependencies [769e67f]
95
+ - @zhin.js/adapter@1.1.13
96
+ - @zhin.js/core@1.1.36
97
+
3
98
  ## 1.1.0
4
99
 
5
100
  ### Minor Changes
package/README.md CHANGED
@@ -18,11 +18,13 @@ pnpm add @zhin.js/adapter-onebot11
18
18
 
19
19
  ## Plugin Runtime
20
20
 
21
- - `@zhin.js/adapter` — 约定式 `adapters/onebot11.ts`(`defineAdapter`)
21
+ - `@zhin.js/adapter` — 约定式 `adapters/onebot11/index.ts`(`defineAdapter`)
22
22
  - `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
23
23
  - `zhin.js` — `plugin.ts`(`definePlugin`)
24
24
  - 配置经插件 `schema.json` 落到 `plugins.<instanceKey>`
25
25
 
26
+ `AdapterIndex` 会把实例默认值与 `endpoints[]` 的逐项覆盖合并;协议层只接收一个已经展开的 endpoint 配置,不再读取嵌套 endpoint、旧 `type: ws_reverse` 别名或进程环境。
27
+
26
28
  每个 Endpoint 的 `$client` 是 `@imhelper/onebot-v11` 的 `OneBotV11Client`。业务代码直接调用
27
29
  `$client.call(action, params)` 和 Client 的公开平台能力;双工 WS 的 `echo` 响应由 Endpoint
28
30
  先行分流,只有事件帧进入 Client 的 `ingest()` 和公开事件流。
@@ -46,7 +48,7 @@ plugins:
46
48
  reconnect_interval: 5000
47
49
  heartbeat_interval: 30000
48
50
  endpoints:
49
- - name: ob11-bot
51
+ - id: ob11-bot
50
52
  url: "ws://127.0.0.1:6700"
51
53
  access_token: "${ONEBOT11_ACCESS_TOKEN}"
52
54
  ```
@@ -74,15 +76,15 @@ plugins:
74
76
 
75
77
  | 类别 | 路径 |
76
78
  |------|------|
77
- | Permit 词汇 | `agent/PERMITS.md` |
78
- | 平台工具 | `agent/tools/set_title.ts` → `onebot11_set_title` |
79
- | 技能说明 | `agent/skills/onebot11.md` |
79
+ | Permit 词汇 | `PERMITS.md` |
80
+ | 平台工具 | `tools/set_title/index.ts` → `onebot11_set_title` |
81
+ | 技能说明 | `agents/onebot11/skills/onebot11/SKILL.md` |
80
82
 
81
83
  ## 迁移说明(Plugin Runtime)
82
84
 
83
85
  - **notice / request / meta 侧事件**:经 the unified `Endpoint.emit(...)` ingress 归一后分发到 `handlers`;消息仍走 `outboundMessageToken`。
84
86
  - **群管工具暂未迁移**:旧 Adapter 经 `createSceneManagementTools` 注册踢人 / 禁言 / 群名片等成套 agent 工具;迁移后仅保留 `onebot11_set_title`,其余群管能力可通过 `$client.call()`(如 `set_group_kick`、`set_group_ban`)作为逃生舱调用。
85
- - **平台权限门禁**:`plugin.ts` setup 已注册 `registerDefaultScenePlatformPermitChecker('onebot11')`,`scene_admin` / `scene_owner` 依据入站 metadata 中的 sender `role`(owner / admin)判定。
87
+ - **平台权限门禁**:`plugin.ts` setup 通过 generation-owned `permissionHostToken` 调用 `host.registerPlatform('onebot11', createSceneRolePlatformChecker())`,`scene_admin` / `scene_owner` 依据入站 metadata 中的 sender `role`(owner / admin)判定。
86
88
 
87
89
  ## 文档链接
88
90
 
@@ -1,15 +1,15 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  /**
3
- * Convention entry: discover `adapters/onebot11.ts` → defineAdapter.
3
+ * Convention entry: discover `adapters/onebot11/index.ts` → defineAdapter.
4
4
  */
5
5
  import { defineAdapter } from 'zhin.js/adapter';
6
6
  import { httpHostToken } from '@zhin.js/host-http';
7
- import { OneBot11WsEndpoint } from "../lib/ws-endpoint.js";
8
- import { OneBot11WssEndpoint } from "../lib/wss-endpoint.js";
9
- import { resolveOneBot11Config, } from "../lib/protocol.js";
10
- import { onebot11RuntimeStateToken } from "../lib/onebot11-runtime-state.js";
11
- export { OneBot11WsEndpoint } from "../lib/ws-endpoint.js";
12
- export { OneBot11WssEndpoint } from "../lib/wss-endpoint.js";
7
+ import { OneBot11WsEndpoint } from "../../lib/ws-endpoint.js";
8
+ import { OneBot11WssEndpoint } from "../../lib/wss-endpoint.js";
9
+ import { resolveOneBot11Config, } from "../../lib/protocol.js";
10
+ import { onebot11RuntimeStateToken } from "../../lib/onebot11-runtime-state.js";
11
+ export { OneBot11WsEndpoint } from "../../lib/ws-endpoint.js";
12
+ export { OneBot11WssEndpoint } from "../../lib/wss-endpoint.js";
13
13
  export default defineAdapter({
14
14
  capabilities: ['inbound', 'outbound'],
15
15
  operations: ['recall'],
@@ -20,7 +20,7 @@ export default defineAdapter({
20
20
  },
21
21
  create(context) {
22
22
  const config = resolveOneBot11Config(context.config);
23
- // 注册到插件运行时状态(onebot11.endpoint list 的"运行中"数据源)
23
+ // 注册到插件运行时状态(onebot11 endpoint list 的"运行中"数据源)
24
24
  context.use(onebot11RuntimeStateToken).endpoints.set(config.id, {
25
25
  id: config.id,
26
26
  mode: config.connection,
@@ -1,29 +1,29 @@
1
1
  /**
2
- * Convention entry: discover `adapters/onebot11.ts` → defineAdapter.
2
+ * Convention entry: discover `adapters/onebot11/index.ts` → defineAdapter.
3
3
  */
4
4
  import { defineAdapter } from 'zhin.js/adapter';
5
5
  import { httpHostToken } from '@zhin.js/host-http';
6
- import { OneBot11WsEndpoint } from '../src/ws-endpoint.js';
7
- import { OneBot11WssEndpoint } from '../src/wss-endpoint.js';
6
+ import { OneBot11WsEndpoint } from '../../src/ws-endpoint.js';
7
+ import { OneBot11WssEndpoint } from '../../src/wss-endpoint.js';
8
8
  import {
9
9
  resolveOneBot11Config,
10
- type OneBot11AdapterConfig,
11
- } from '../src/protocol.js';
12
- import { onebot11RuntimeStateToken } from '../src/onebot11-runtime-state.js';
10
+ type OneBot11EndpointConfig,
11
+ } from '../../src/protocol.js';
12
+ import { onebot11RuntimeStateToken } from '../../src/onebot11-runtime-state.js';
13
13
 
14
- export { OneBot11WsEndpoint } from '../src/ws-endpoint.js';
15
- export type { OneBot11WsEndpointOptions } from '../src/ws-endpoint.js';
16
- export { OneBot11WssEndpoint } from '../src/wss-endpoint.js';
17
- export type { OneBot11WssEndpointOptions } from '../src/wss-endpoint.js';
18
- export type { OneBot11WsSocket, OneBot11WsCreateOptions } from '../src/ws-types.js';
14
+ export { OneBot11WsEndpoint } from '../../src/ws-endpoint.js';
15
+ export type { OneBot11WsEndpointOptions } from '../../src/ws-endpoint.js';
16
+ export { OneBot11WssEndpoint } from '../../src/wss-endpoint.js';
17
+ export type { OneBot11WssEndpointOptions } from '../../src/wss-endpoint.js';
18
+ export type { OneBot11WsSocket, OneBot11WsCreateOptions } from '../../src/ws-types.js';
19
19
 
20
20
  declare module '@zhin.js/core' {
21
21
  interface AdapterEndpoints {
22
- onebot11: import('../src/ws-endpoint.js').OneBot11WsEndpoint;
22
+ onebot11: import('../../src/ws-endpoint.js').OneBot11WsEndpoint;
23
23
  }
24
24
  }
25
25
 
26
- export default defineAdapter<OneBot11AdapterConfig>({
26
+ export default defineAdapter<OneBot11EndpointConfig>({
27
27
  capabilities: ['inbound', 'outbound'],
28
28
  operations: ['recall'],
29
29
  // OneBot file 参数原生消费 url / base64:// 媒体;无卡片交互面,交互段降级纯文本。
@@ -33,7 +33,7 @@ export default defineAdapter<OneBot11AdapterConfig>({
33
33
  },
34
34
  create(context) {
35
35
  const config = resolveOneBot11Config(context.config);
36
- // 注册到插件运行时状态(onebot11.endpoint list 的"运行中"数据源)
36
+ // 注册到插件运行时状态(onebot11 endpoint list 的"运行中"数据源)
37
37
  context.use(onebot11RuntimeStateToken).endpoints.set(config.id, {
38
38
  id: config.id,
39
39
  mode: config.connection,
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "ONEBOT11 Platform Agent",
3
+ "version": "1.0.0",
4
+ "description": "Handles onebot11 platform-specific operations and progressively loads only the required platform Skill.",
5
+ "trigger_rules": {
6
+ "file_patterns": [],
7
+ "keywords": [
8
+ "onebot11",
9
+ "adapter:onebot11"
10
+ ]
11
+ },
12
+ "entry_points": [
13
+ "system.md",
14
+ "boundaries.md",
15
+ "conventions.md"
16
+ ],
17
+ "platforms": [
18
+ "onebot11"
19
+ ]
20
+ }
@@ -0,0 +1,3 @@
1
+ # Boundaries
2
+
3
+ Operate only on the active onebot11 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,15 @@
1
+ ---
2
+ name: onebot11
3
+ platforms: [onebot11]
4
+ description: OneBot 11 消息通道与群专属头衔设置能力。
5
+ keywords: [onebot11, qq, title, 头衔]
6
+ tags: [adapter, messaging]
7
+ tools:
8
+ - set_title
9
+ ---
10
+
11
+ # OneBot 11
12
+
13
+ `set_title` 用于设置群成员专属头衔。执行前确认群、目标用户和头衔文本,并遵守 Tool 自身审批与平台权限。
14
+
15
+ 当前 Agent Tool 不提供踢人、禁言、管理员、群名片、成员列表或群信息操作。
@@ -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: '设置 QQ 群成员的专属头衔。只有群主才能设置。',
6
+ inputSchema: z.object({
7
+ group_id: z.number().describe('目标群号'),
8
+ user_id: z.number().describe('目标成员 QQ号'),
9
+ title: z.string().describe('头衔文字'),
10
+ }),
11
+ adapter: 'onebot11',
12
+ tags: ['onebot11'],
13
+ permissions: ['platform(onebot11,scene_owner)'],
14
+ async execute({ group_id, user_id, title }, context) {
15
+ const client = context.$client;
16
+ const response = await client.call('set_group_special_title', {
17
+ group_id,
18
+ user_id,
19
+ special_title: title,
20
+ duration: -1,
21
+ });
22
+ const success = response.status === 'ok';
23
+ return { success, message: success ? `已将 ${user_id} 的头衔设为 "${title}"` : '设置失败' };
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
  export default defineAgentTool<{ group_id: number; user_id: number; title: string }>({
4
4
  description: '设置 QQ 群成员的专属头衔。只有群主才能设置。',
@@ -0,0 +1,3 @@
1
+ # ONEBOT11 Platform Agent
2
+
3
+ You are the onebot11 platform specialist. Interpret requests in the current onebot11 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 { onebot11EndpointCommands } from "../../../lib/onebot11-endpoint-commands.js";
2
+ import { onebot11EndpointCommands } from '../../definition.js';
3
3
  export default onebot11EndpointCommands.add;
@@ -0,0 +1,3 @@
1
+ import { onebot11EndpointCommands } from '../../definition.js';
2
+
3
+ export default onebot11EndpointCommands.add;
@@ -1,10 +1,11 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
1
2
  /**
2
- * `onebot11.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
- * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
3
+ * `onebot11 endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
4
+ * commands/onebot11/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
5
  */
5
6
  import { createEndpointCommands } from 'zhin.js/adapter';
6
7
  import { defineCommand } from 'zhin.js/command';
7
- import { onebot11RuntimeStateToken } from './onebot11-runtime-state.js';
8
+ import { onebot11RuntimeStateToken } from "../../../lib/onebot11-runtime-state.js";
8
9
  export const onebot11EndpointCommands = createEndpointCommands({
9
10
  adapterKey: 'onebot11',
10
11
  adapterDisplayName: 'OneBot 11',
@@ -1,10 +1,10 @@
1
1
  /**
2
- * `onebot11.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
- * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
2
+ * `onebot11 endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
+ * commands/onebot11/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
4
  */
5
5
  import { createEndpointCommands } from 'zhin.js/adapter';
6
6
  import { defineCommand } from 'zhin.js/command';
7
- import { onebot11RuntimeStateToken } from './onebot11-runtime-state.js';
7
+ import { onebot11RuntimeStateToken } from '../../../src/onebot11-runtime-state.js';
8
8
 
9
9
  export const onebot11EndpointCommands = createEndpointCommands({
10
10
  adapterKey: 'onebot11',
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { onebot11EndpointCommands } from "../../lib/onebot11-endpoint-commands.js";
2
+ import { onebot11EndpointCommands } from '../definition.js';
3
3
  export default onebot11EndpointCommands.list;
@@ -0,0 +1,3 @@
1
+ import { onebot11EndpointCommands } from '../definition.js';
2
+
3
+ export default onebot11EndpointCommands.list;
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { onebot11EndpointCommands } from "../../../lib/onebot11-endpoint-commands.js";
2
+ import { onebot11EndpointCommands } from '../../definition.js';
3
3
  export default onebot11EndpointCommands.remove;
@@ -0,0 +1,3 @@
1
+ import { onebot11EndpointCommands } from '../../definition.js';
2
+
3
+ export default onebot11EndpointCommands.remove;
package/lib/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { buildSendAction, buildWsConnectOptions, extractQuoteId, formatInboundContent, formatInboundMetadata, formatOutboundSegments, getChannelId, isMessageEvent, isOneBot11BotMentioned, mediaRefToOneBotFile, onebot11InboundConversation, resolveOneBot11Config, senderDisplayName, senderNickname, senderUserId, type OneBot11ActionRequest, type OneBot11ActionResponse, type OneBot11AdapterConfig, type OneBot11ConfigBase, type OneBot11EndpointConfig, type OneBot11Event, type OneBot11Segment, type OneBot11Sender, type OneBot11WireSegment, type OneBot11WsConfig, type OneBot11WssConfig, type ResolvedOneBot11Config, } from './protocol.js';
1
+ export { buildSendAction, buildWsConnectOptions, extractQuoteId, formatInboundContent, formatInboundMetadata, formatOutboundSegments, getChannelId, isMessageEvent, isOneBot11BotMentioned, mediaRefToOneBotFile, onebot11InboundConversation, resolveOneBot11Config, senderDisplayName, senderNickname, senderUserId, type OneBot11ActionRequest, type OneBot11ActionResponse, type OneBot11ConfigBase, type OneBot11EndpointConfig, type OneBot11Event, type OneBot11Segment, type OneBot11Sender, type OneBot11WireSegment, type OneBot11WsConfig, type OneBot11WssConfig, type ResolvedOneBot11Config, } from './protocol.js';
2
2
  export { OneBot11WsEndpoint, type OneBot11WsEndpointOptions, } from './ws-endpoint.js';
3
3
  export { OneBot11WssEndpoint, type OneBot11WssEndpointOptions, } from './wss-endpoint.js';
4
4
  export type { OneBot11WsSocket, OneBot11WsCreateOptions } from './ws-types.js';
5
- export { callOneBot11WsAction, decodeWsPayload, handleOneBot11WsMessage, rejectAllPending, startOneBot11Heartbeat, } from './ws-transport.js';
5
+ export { callOneBot11WsAction, decodeWsPayload, handleOneBot11WsMessage, rejectAllPending, } from './ws-transport.js';
6
6
  export { verifyOneBotAccessToken } from './wss-auth.js';
7
7
  export { Onebot11Client, onebot11Client, type Onebot11ClientEventMap, } from './client.js';
8
8
  export type { OneBotV11ActionUrlResolver, OneBotV11AdapterConfig as ImHelperOneBotV11AdapterConfig, OneBotV11Call, OneBotV11ClientConfig, OneBotV11Event as ImHelperOneBotV11Event, OneBotV11Response, } from '@imhelper/onebot-v11';
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export { buildSendAction, buildWsConnectOptions, extractQuoteId, formatInboundContent, formatInboundMetadata, formatOutboundSegments, getChannelId, isMessageEvent, isOneBot11BotMentioned, mediaRefToOneBotFile, onebot11InboundConversation, resolveOneBot11Config, senderDisplayName, senderNickname, senderUserId, } from './protocol.js';
2
2
  export { OneBot11WsEndpoint, } from './ws-endpoint.js';
3
3
  export { OneBot11WssEndpoint, } from './wss-endpoint.js';
4
- export { callOneBot11WsAction, decodeWsPayload, handleOneBot11WsMessage, rejectAllPending, startOneBot11Heartbeat, } from './ws-transport.js';
4
+ export { callOneBot11WsAction, decodeWsPayload, handleOneBot11WsMessage, rejectAllPending, } from './ws-transport.js';
5
5
  export { verifyOneBotAccessToken } from './wss-auth.js';
6
6
  export { Onebot11Client, onebot11Client, } from './client.js';
7
7
  export { ProtocolError } from '@imhelper/onebot-v11';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * OneBot11 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
- * 由 plugin.ts setup() provide,adapter create 与 `onebot11.endpoint` 命令共享(同一 owner generation)。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `onebot11 endpoint` 命令共享(同一 owner generation)。
4
4
  */
5
5
  import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
6
  export const onebot11RuntimeStateToken = defineEndpointRuntimeStateToken('onebot11');
package/lib/protocol.d.ts CHANGED
@@ -3,32 +3,16 @@
3
3
  * Canonicalization is owned by gateway/core before endpoint.send.
4
4
  * Spec: https://github.com/botuniverse/onebot-11
5
5
  */
6
- import { type MediaRef } from '@zhin.js/core';
7
- import type { ConversationRef } from '@zhin.js/im-contract';
8
- /** Transitional legacy endpoint row (`endpoints[]` with `context: onebot11`). */
9
- export interface OneBot11LegacyEndpointRow {
10
- readonly context?: string;
6
+ import { type MediaRef, type ConversationRef } from '@zhin.js/im-contract';
7
+ /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
8
+ export interface OneBot11EndpointConfig {
11
9
  readonly connection?: 'ws' | 'wss';
12
- /** Legacy alias: `type: 'ws' | 'ws_reverse'` */
13
- readonly type?: string;
14
- readonly id?: string;
15
- readonly access_token?: string;
16
- readonly url?: string;
17
- readonly path?: string;
18
- readonly reconnect_interval?: number;
19
- readonly heartbeat_interval?: number;
20
- }
21
- /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
22
- export interface OneBot11AdapterConfig {
23
- readonly connection?: 'ws' | 'wss';
24
- readonly id?: string;
10
+ readonly id: string;
25
11
  readonly access_token?: string;
26
12
  readonly url?: string;
27
13
  readonly path?: string;
28
14
  readonly reconnect_interval?: number;
29
15
  readonly heartbeat_interval?: number;
30
- /** Transitional: legacy root `endpoints[]` with `context: onebot11`. */
31
- readonly endpoints?: ReadonlyArray<OneBot11LegacyEndpointRow>;
32
16
  }
33
17
  export interface OneBot11ConfigBase {
34
18
  readonly context: 'onebot11';
@@ -49,7 +33,6 @@ export interface OneBot11WssConfig extends OneBot11ConfigBase {
49
33
  readonly heartbeat_interval: number;
50
34
  }
51
35
  export type ResolvedOneBot11Config = OneBot11WsConfig | OneBot11WssConfig;
52
- export type OneBot11EndpointConfig = ResolvedOneBot11Config;
53
36
  export interface OneBot11Sender {
54
37
  readonly role?: string;
55
38
  readonly nickname?: string;
@@ -92,7 +75,7 @@ export interface OneBot11WireSegment {
92
75
  readonly type: string;
93
76
  readonly data?: Record<string, unknown>;
94
77
  }
95
- export declare function resolveOneBot11Config(config?: OneBot11AdapterConfig): ResolvedOneBot11Config;
78
+ export declare function resolveOneBot11Config(config: OneBot11EndpointConfig): ResolvedOneBot11Config;
96
79
  /** 判断是否为消息事件(post_type=message) */
97
80
  export declare function isMessageEvent(ev: OneBot11Event): ev is OneBot11Event & {
98
81
  message_id: number | string;
package/lib/protocol.js CHANGED
@@ -3,57 +3,53 @@
3
3
  * Canonicalization is owned by gateway/core before endpoint.send.
4
4
  * Spec: https://github.com/botuniverse/onebot-11
5
5
  */
6
- import { isMediaRef } from '@zhin.js/core';
6
+ import { isMediaRef } from '@zhin.js/im-contract';
7
7
  import { formatCompact, getLogger } from '@zhin.js/logger';
8
8
  const logger = getLogger('onebot11');
9
- function normalizeConnection(connection, legacyType) {
9
+ function normalizeConnection(connection) {
10
10
  if (connection === 'ws' || connection === 'wss')
11
11
  return connection;
12
- if (legacyType === 'ws_reverse' || legacyType === 'wss')
13
- return 'wss';
14
- if (legacyType === 'ws')
15
- return 'ws';
16
12
  return 'ws';
17
13
  }
18
- export function resolveOneBot11Config(config = {}) {
19
- const entry = config.endpoints?.find((item) => item.context === 'onebot11');
20
- const connection = normalizeConnection(config.connection ?? entry?.connection, entry?.type);
21
- const id = (typeof config.id === 'string' && config.id)
22
- || (typeof entry?.id === 'string' && entry.id)
23
- || process.env.ONEBOT11_BOT_NAME
24
- || 'onebot11-bot';
25
- const access_token = config.access_token ?? entry?.access_token;
14
+ export function resolveOneBot11Config(config) {
15
+ const connection = normalizeConnection(config.connection);
16
+ const id = requiredEndpointField(config.id, 'id');
17
+ const access_token = optionalEndpointField(config.access_token);
26
18
  if (connection === 'ws') {
27
- const url = config.url ?? entry?.url;
28
- if (!url) {
29
- throw new TypeError('OneBot11 connection:ws requires url (plugins.<key>.url or endpoints with context: onebot11)');
30
- }
19
+ const url = requiredEndpointField(config.url, 'url');
31
20
  return {
32
21
  context: 'onebot11',
33
22
  connection: 'ws',
34
23
  id,
35
24
  access_token,
36
25
  url,
37
- reconnect_interval: config.reconnect_interval ?? entry?.reconnect_interval ?? 5000,
38
- heartbeat_interval: config.heartbeat_interval ?? entry?.heartbeat_interval ?? 30_000,
26
+ reconnect_interval: config.reconnect_interval ?? 5000,
27
+ heartbeat_interval: config.heartbeat_interval ?? 30_000,
39
28
  };
40
29
  }
41
30
  if (connection === 'wss') {
42
- const path = config.path ?? entry?.path;
43
- if (!path) {
44
- throw new TypeError('OneBot11 connection:wss requires path');
45
- }
31
+ const path = requiredEndpointField(config.path, 'path');
46
32
  return {
47
33
  context: 'onebot11',
48
34
  connection: 'wss',
49
35
  id,
50
36
  access_token,
51
37
  path,
52
- heartbeat_interval: config.heartbeat_interval ?? entry?.heartbeat_interval ?? 30_000,
38
+ heartbeat_interval: config.heartbeat_interval ?? 30_000,
53
39
  };
54
40
  }
55
41
  throw new TypeError(`Unknown OneBot11 connection: ${String(connection)}`);
56
42
  }
43
+ function requiredEndpointField(value, field) {
44
+ const resolved = optionalEndpointField(value);
45
+ if (!resolved) {
46
+ throw new TypeError(`OneBot11 endpoint requires a non-empty ${field}`);
47
+ }
48
+ return resolved;
49
+ }
50
+ function optionalEndpointField(value) {
51
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
52
+ }
57
53
  /** 判断是否为消息事件(post_type=message) */
58
54
  export function isMessageEvent(ev) {
59
55
  return ev.post_type === 'message' && ev.message_id != null;
@@ -91,9 +87,24 @@ export function formatInboundContent(ev) {
91
87
  .join('');
92
88
  }
93
89
  return typeof ev.raw_message === 'string'
94
- ? ev.raw_message.replace(/\[CQ:[^\]]+\]/g, '').trim()
90
+ ? stripCqCodes(ev.raw_message).trim()
95
91
  : '';
96
92
  }
93
+ function stripCqCodes(input) {
94
+ let result = '';
95
+ let cursor = 0;
96
+ while (cursor < input.length) {
97
+ const start = input.indexOf('[CQ:', cursor);
98
+ if (start < 0)
99
+ return result + input.slice(cursor);
100
+ result += input.slice(cursor, start);
101
+ const end = input.indexOf(']', start + 4);
102
+ if (end < 0)
103
+ return result + input.slice(start);
104
+ cursor = end + 1;
105
+ }
106
+ return result;
107
+ }
97
108
  export function senderDisplayName(ev) {
98
109
  const name = ev.sender?.card || ev.sender?.nickname;
99
110
  if (typeof name === 'string' && name)
@@ -9,5 +9,4 @@ export declare function handleOneBot11WsMessage(data: unknown, options: {
9
9
  export declare function callOneBot11WsAction(ws: OneBot11WsSocket | undefined, pending: Map<string, OneBot11PendingAction>, requestId: {
10
10
  value: number;
11
11
  }, action: string, params: Record<string, unknown>): Promise<OneBot11ActionResponse>;
12
- export declare function startOneBot11Heartbeat(ws: OneBot11WsSocket | undefined, intervalMs: number, existingTimer?: NodeJS.Timeout): NodeJS.Timeout;
13
12
  export declare function rejectAllPending(pending: Map<string, OneBot11PendingAction>, message?: string): void;
@@ -1,4 +1,4 @@
1
- import { clearInterval, clearTimeout, setInterval, setTimeout } from 'node:timers';
1
+ import { clearTimeout, setTimeout } from 'node:timers';
2
2
  import { formatCompact, getLogger } from '@zhin.js/logger';
3
3
  import { WS_OPEN, } from './ws-types.js';
4
4
  const logger = getLogger('onebot11');
@@ -50,18 +50,6 @@ export function callOneBot11WsAction(ws, pending, requestId, action, params) {
50
50
  ws.send(JSON.stringify(req));
51
51
  });
52
52
  }
53
- export function startOneBot11Heartbeat(ws, intervalMs, existingTimer) {
54
- if (existingTimer)
55
- clearInterval(existingTimer);
56
- return setInterval(() => {
57
- try {
58
- ws?.ping?.();
59
- }
60
- catch {
61
- /* ignore */
62
- }
63
- }, intervalMs);
64
- }
65
53
  export function rejectAllPending(pending, message = '连接已关闭') {
66
54
  for (const [, entry] of pending) {
67
55
  clearTimeout(entry.timeout);