@zhin.js/adapter-wecom 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 (42) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/README.md +10 -6
  3. package/adapters/{wecom.js → wecom/index.js} +6 -6
  4. package/adapters/{wecom.ts → wecom/index.ts} +9 -9
  5. package/agents/wecom/agent.json +20 -0
  6. package/agents/wecom/boundaries.md +3 -0
  7. package/agents/wecom/conventions.md +3 -0
  8. package/{agent/skills/wecom.md → agents/wecom/skills/wecom/SKILL.md} +4 -4
  9. package/agents/wecom/skills/wecom/tools/get_dept_users/index.js +16 -0
  10. package/{agent/tools/get_dept_users.ts → agents/wecom/skills/wecom/tools/get_dept_users/index.ts} +1 -1
  11. package/agents/wecom/skills/wecom/tools/get_user/index.js +15 -0
  12. package/{agent/tools/get_user.ts → agents/wecom/skills/wecom/tools/get_user/index.ts} +1 -1
  13. package/agents/wecom/skills/wecom/tools/list_departments/index.js +16 -0
  14. package/{agent/tools/list_departments.ts → agents/wecom/skills/wecom/tools/list_departments/index.ts} +1 -1
  15. package/agents/wecom/skills/wecom/tools/send_text/index.js +17 -0
  16. package/{agent/tools/send_text.ts → agents/wecom/skills/wecom/tools/send_text/index.ts} +1 -1
  17. package/agents/wecom/system.md +3 -0
  18. package/commands/{endpoint/add/[id].js → wecom/endpoint/add/[id]/index.js} +1 -1
  19. package/commands/wecom/endpoint/add/[id]/index.ts +3 -0
  20. package/{lib/wecom-endpoint-commands.js → commands/wecom/endpoint/definition.js} +4 -3
  21. package/{src/wecom-endpoint-commands.ts → commands/wecom/endpoint/definition.ts} +3 -3
  22. package/commands/{endpoint/list.js → wecom/endpoint/list/index.js} +1 -1
  23. package/commands/wecom/endpoint/list/index.ts +3 -0
  24. package/commands/{endpoint/remove/[id].js → wecom/endpoint/remove/[id]/index.js} +1 -1
  25. package/commands/wecom/endpoint/remove/[id]/index.ts +3 -0
  26. package/lib/index.d.ts +1 -1
  27. package/lib/media-upload.d.ts +1 -1
  28. package/lib/media-upload.js +1 -1
  29. package/lib/protocol.d.ts +8 -12
  30. package/lib/protocol.js +18 -19
  31. package/lib/wecom-runtime-state.js +1 -1
  32. package/package.json +33 -21
  33. package/schema.json +11 -1
  34. package/src/index.ts +1 -1
  35. package/src/media-upload.ts +1 -1
  36. package/src/protocol.ts +30 -32
  37. package/src/wecom-runtime-state.ts +1 -1
  38. package/commands/endpoint/add/[id].ts +0 -3
  39. package/commands/endpoint/list.ts +0 -3
  40. package/commands/endpoint/remove/[id].ts +0 -3
  41. package/lib/wecom-endpoint-commands.d.ts +0 -1
  42. /package/{agent/PERMITS.md → PERMITS.md} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,112 @@
1
1
  # @zhin.js/adapter-wecom
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/skill@1.1.2
16
+ - @zhin.js/tool@1.1.2
17
+
18
+ ## 1.1.2
19
+
20
+ ### Patch Changes
21
+
22
+ - 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`.
23
+ - 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.
24
+
25
+ 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.
26
+
27
+ 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.
28
+
29
+ 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.
30
+
31
+ 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`.
32
+
33
+ - 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.
34
+ - 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.
35
+ - 4380cf9: Colocate adapter command definitions and Agent Skill handlers with their owning capabilities, and provide a shared validated platform permission constructor.
36
+ - b74e131: Require one canonical expanded WeCom endpoint configuration. The protocol no longer reinterprets nested `endpoints` or reads endpoint identity and credentials from `process.env`.
37
+ - 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.
38
+ - 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.
39
+ - Updated dependencies [c861789]
40
+ - Updated dependencies [1414ccb]
41
+ - Updated dependencies [743d470]
42
+ - Updated dependencies [62dee52]
43
+ - Updated dependencies [cd54131]
44
+ - Updated dependencies [244e475]
45
+ - Updated dependencies [a9e4a40]
46
+ - Updated dependencies [5855db7]
47
+ - Updated dependencies [ec921d2]
48
+ - Updated dependencies [8740059]
49
+ - Updated dependencies [63d1f7a]
50
+ - Updated dependencies [25a845a]
51
+ - Updated dependencies [103f2c3]
52
+ - Updated dependencies [9110ab8]
53
+ - Updated dependencies [cd2a888]
54
+ - Updated dependencies [eb3227a]
55
+ - Updated dependencies [b853dba]
56
+ - Updated dependencies [e561309]
57
+ - Updated dependencies [d4c6175]
58
+ - Updated dependencies [7a0e1ca]
59
+ - Updated dependencies [103b5d3]
60
+ - Updated dependencies [5a7a7f7]
61
+ - Updated dependencies [b076eae]
62
+ - Updated dependencies [535fed1]
63
+ - Updated dependencies [73a24b7]
64
+ - Updated dependencies [2dbbc15]
65
+ - Updated dependencies [1cb1163]
66
+ - Updated dependencies [be3061e]
67
+ - Updated dependencies [75f8332]
68
+ - Updated dependencies [81935e2]
69
+ - Updated dependencies [f9ed01b]
70
+ - Updated dependencies [ac0ab50]
71
+ - Updated dependencies [5140ce1]
72
+ - Updated dependencies [522d75f]
73
+ - Updated dependencies [a7611b3]
74
+ - Updated dependencies [8823044]
75
+ - Updated dependencies [379439b]
76
+ - Updated dependencies [11c9352]
77
+ - Updated dependencies [6b70e46]
78
+ - Updated dependencies [135ac91]
79
+ - Updated dependencies [140cf0f]
80
+ - Updated dependencies [251e4d2]
81
+ - Updated dependencies [203ad34]
82
+ - Updated dependencies [e6c5113]
83
+ - Updated dependencies [e0f6478]
84
+ - Updated dependencies [baef56b]
85
+ - Updated dependencies [698f16f]
86
+ - Updated dependencies [da0a8e3]
87
+ - Updated dependencies [2fd8017]
88
+ - Updated dependencies [5c3858e]
89
+ - Updated dependencies [33ea736]
90
+ - Updated dependencies [507d602]
91
+ - Updated dependencies [df9f76b]
92
+ - @zhin.js/core@1.1.37
93
+ - @zhin.js/tool@1.1.1
94
+ - @zhin.js/host-http@1.1.1
95
+ - @zhin.js/adapter@1.1.14
96
+ - @zhin.js/feature-kit@1.1.1
97
+ - @zhin.js/agent-feature@1.1.1
98
+ - @zhin.js/skill@1.1.1
99
+ - @zhin.js/logger@1.1.1
100
+ - @zhin.js/im-contract@1.1.1
101
+
102
+ ## 1.1.1
103
+
104
+ ### Patch Changes
105
+
106
+ - Updated dependencies [769e67f]
107
+ - @zhin.js/adapter@1.1.13
108
+ - @zhin.js/core@1.1.36
109
+
3
110
  ## 1.1.0
4
111
 
5
112
  ### Minor Changes
package/README.md CHANGED
@@ -17,7 +17,7 @@ pnpm add @zhin.js/adapter-wecom
17
17
 
18
18
  ## Plugin Runtime
19
19
 
20
- - `@zhin.js/adapter` — 约定式 `adapters/wecom.ts`(`defineAdapter`)
20
+ - `@zhin.js/adapter` — 约定式 `adapters/wecom/index.ts`(`defineAdapter`)
21
21
  - `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
22
22
  - `@zhin.js/host-http` — `httpHostToken` 注册 Webhook 路由(**非** legacy host-router/Koa)
23
23
  - `zhin.js` — `plugin.ts`(`definePlugin`)
@@ -39,7 +39,9 @@ pnpm add @zhin.js/adapter-wecom
39
39
  - **Token** / **EncodingAESKey** 与配置一致
40
40
  4. Runtime Host(`http`)须已 listen,Webhook 才可达
41
41
 
42
- 必填字段(`endpoints[i]`):`name`、`corpId`、`agentSecret`、`token`、`encodingAESKey`。
42
+ 必填字段(`endpoints[i]`):`id`、`corpId`、`agentSecret`、`token`、`encodingAESKey`。
43
+ 运行时由 AdapterIndex 把实例级默认值与每个 endpoint 合并;协议实现只接收一份展开后的
44
+ endpoint 配置。
43
45
 
44
46
  ## 最小配置
45
47
 
@@ -50,7 +52,7 @@ plugins:
50
52
  webhookPath: /wecom/callback # 可选,默认 /wecom/callback
51
53
  apiBaseUrl: https://qyapi.weixin.qq.com # 可选
52
54
  endpoints:
53
- - name: wecom-bot
55
+ - id: wecom-bot
54
56
  corpId: ${WECOM_CORP_ID}
55
57
  agentSecret: ${WECOM_AGENT_SECRET}
56
58
  token: ${WECOM_TOKEN}
@@ -61,6 +63,8 @@ plugins:
61
63
 
62
64
  ## 环境变量
63
65
 
66
+ 环境变量通过 `zhin.config.yml` 的 `${...}` 引用解析;适配器协议层不会直接读取它们。
67
+
64
68
  | 变量 | 说明 |
65
69
  |------|------|
66
70
  | `WECOM_CORP_ID` | 企业 ID |
@@ -108,9 +112,9 @@ Access Token 在过期前 5 分钟自动刷新。
108
112
 
109
113
  | 类别 | 路径 |
110
114
  |------|------|
111
- | Permit 词汇 | `agent/PERMITS.md` |
112
- | 平台工具(4 个) | `agent/tools/` |
113
- | 技能说明 | `agent/skills/wecom.md` |
115
+ | Permit 词汇 | `PERMITS.md` |
116
+ | 平台工具(4 个) | `tools/` |
117
+ | 技能说明 | `agents/wecom/skills/wecom/SKILL.md` |
114
118
 
115
119
  ## 平台权限(platform permit)
116
120
 
@@ -1,14 +1,14 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  /**
3
- * Convention entry: discover `adapters/wecom.ts` → defineAdapter.
3
+ * Convention entry: discover `adapters/wecom/index.ts` → defineAdapter.
4
4
  * Implementation lives under `src/` (endpoint / webhook / protocol).
5
5
  */
6
6
  import { defineAdapter } from 'zhin.js/adapter';
7
7
  import { httpHostToken } from '@zhin.js/host-http';
8
- import { WecomEndpoint } from "../lib/endpoint.js";
9
- import { resolveWecomConfig, } from "../lib/protocol.js";
10
- import { wecomRuntimeStateToken } from "../lib/wecom-runtime-state.js";
11
- export { WecomEndpoint } from "../lib/endpoint.js";
8
+ import { WecomEndpoint } from "../../lib/endpoint.js";
9
+ import { resolveWecomConfig, } from "../../lib/protocol.js";
10
+ import { wecomRuntimeStateToken } from "../../lib/wecom-runtime-state.js";
11
+ export { WecomEndpoint } from "../../lib/endpoint.js";
12
12
  export default defineAdapter({
13
13
  capabilities: ['inbound', 'outbound'],
14
14
  operations: ['recall'],
@@ -20,7 +20,7 @@ export default defineAdapter({
20
20
  },
21
21
  create(context) {
22
22
  const config = resolveWecomConfig(context.config);
23
- // 注册到插件运行时状态(wecom.endpoint list 的"运行中"数据源)
23
+ // 注册到插件运行时状态(wecom endpoint list 的"运行中"数据源)
24
24
  context.use(wecomRuntimeStateToken).endpoints.set(config.id, {
25
25
  id: config.id,
26
26
  mode: 'webhook',
@@ -1,20 +1,20 @@
1
1
  /**
2
- * Convention entry: discover `adapters/wecom.ts` → defineAdapter.
2
+ * Convention entry: discover `adapters/wecom/index.ts` → defineAdapter.
3
3
  * Implementation lives under `src/` (endpoint / webhook / protocol).
4
4
  */
5
5
  import { defineAdapter } from 'zhin.js/adapter';
6
6
  import { httpHostToken } from '@zhin.js/host-http';
7
- import { WecomEndpoint } from '../src/endpoint.js';
7
+ import { WecomEndpoint } from '../../src/endpoint.js';
8
8
  import {
9
9
  resolveWecomConfig,
10
- type WecomAdapterConfig,
11
- } from '../src/protocol.js';
12
- import { wecomRuntimeStateToken } from '../src/wecom-runtime-state.js';
10
+ type WecomEndpointConfig,
11
+ } from '../../src/protocol.js';
12
+ import { wecomRuntimeStateToken } from '../../src/wecom-runtime-state.js';
13
13
 
14
- export { WecomEndpoint } from '../src/endpoint.js';
15
- export type { WecomEndpointOptions, WecomFetch } from '../src/endpoint.js';
14
+ export { WecomEndpoint } from '../../src/endpoint.js';
15
+ export type { WecomEndpointOptions, WecomFetch } from '../../src/endpoint.js';
16
16
 
17
- export default defineAdapter<WecomAdapterConfig>({
17
+ export default defineAdapter<WecomEndpointConfig>({
18
18
  capabilities: ['inbound', 'outbound'],
19
19
  operations: ['recall'],
20
20
  // image 段全部经 /cgi-bin/media/upload 物化为 media_id(url 下载后上传、
@@ -25,7 +25,7 @@ export default defineAdapter<WecomAdapterConfig>({
25
25
  },
26
26
  create(context) {
27
27
  const config = resolveWecomConfig(context.config);
28
- // 注册到插件运行时状态(wecom.endpoint list 的"运行中"数据源)
28
+ // 注册到插件运行时状态(wecom endpoint list 的"运行中"数据源)
29
29
  context.use(wecomRuntimeStateToken).endpoints.set(config.id, {
30
30
  id: config.id,
31
31
  mode: 'webhook',
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "WECOM Platform Agent",
3
+ "version": "1.0.0",
4
+ "description": "Handles wecom platform-specific operations and progressively loads only the required platform Skill.",
5
+ "trigger_rules": {
6
+ "file_patterns": [],
7
+ "keywords": [
8
+ "wecom",
9
+ "adapter:wecom"
10
+ ]
11
+ },
12
+ "entry_points": [
13
+ "system.md",
14
+ "boundaries.md",
15
+ "conventions.md"
16
+ ],
17
+ "platforms": [
18
+ "wecom"
19
+ ]
20
+ }
@@ -0,0 +1,3 @@
1
+ # Boundaries
2
+
3
+ Operate only on the active wecom 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.
@@ -18,10 +18,10 @@ tags:
18
18
  - im
19
19
  - enterprise
20
20
  tools:
21
- - wecom_get_user
22
- - wecom_get_dept_users
23
- - wecom_list_departments
24
- - wecom_send_text
21
+ - get_user
22
+ - get_dept_users
23
+ - list_departments
24
+ - send_text
25
25
  ---
26
26
 
27
27
  # 企业微信技能
@@ -0,0 +1,16 @@
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: '获取企业微信部门用户列表',
6
+ inputSchema: z.object({
7
+ dept_id: z.string().describe('部门 ID'),
8
+ }),
9
+ adapter: 'wecom',
10
+ tags: ['wecom'],
11
+ async execute({ dept_id }, context) {
12
+ const endpoint = context.$client;
13
+ const users = await endpoint.getDepartmentUsers(Number(dept_id));
14
+ return { users, count: users.length };
15
+ },
16
+ });
@@ -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<{ dept_id: string }>({
4
4
  description: '获取企业微信部门用户列表',
@@ -0,0 +1,15 @@
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: '获取企业微信用户信息',
6
+ inputSchema: z.object({
7
+ user_id: z.string().describe('用户 ID'),
8
+ }),
9
+ adapter: 'wecom',
10
+ tags: ['wecom'],
11
+ async execute({ user_id }, context) {
12
+ const endpoint = context.$client;
13
+ return await endpoint.getUserInfo(user_id);
14
+ },
15
+ });
@@ -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<{ user_id: string }>({
4
4
  description: '获取企业微信用户信息',
@@ -0,0 +1,16 @@
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: '获取企业微信部门列表',
6
+ inputSchema: z.object({
7
+ dept_id: z.string().optional().describe('父部门 ID,默认 1(根部门)'),
8
+ }),
9
+ adapter: 'wecom',
10
+ tags: ['wecom'],
11
+ async execute({ dept_id }, context) {
12
+ const endpoint = context.$client;
13
+ const departments = await endpoint.getDepartmentList(Number(dept_id) || 1);
14
+ return { departments, count: departments.length };
15
+ },
16
+ });
@@ -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<{ dept_id?: string }>({
4
4
  description: '获取企业微信部门列表',
@@ -0,0 +1,17 @@
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: '向指定企业微信用户发送文本消息',
6
+ inputSchema: z.object({
7
+ user_id: z.string().describe('用户 ID'),
8
+ content: z.string().describe('消息内容'),
9
+ }),
10
+ adapter: 'wecom',
11
+ tags: ['wecom'],
12
+ async execute({ user_id, content }, context) {
13
+ const endpoint = context.$client;
14
+ const success = await endpoint.sendTextMessage(user_id, content);
15
+ return { success, message: success ? '消息已发送' : '发送失败' };
16
+ },
17
+ });
@@ -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<{ user_id: string; content: string }>({
4
4
  description: '向指定企业微信用户发送文本消息',
@@ -0,0 +1,3 @@
1
+ # WECOM Platform Agent
2
+
3
+ You are the wecom platform specialist. Interpret requests in the current wecom 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 { wecomEndpointCommands } from "../../../lib/wecom-endpoint-commands.js";
2
+ import { wecomEndpointCommands } from '../../definition.js';
3
3
  export default wecomEndpointCommands.add;
@@ -0,0 +1,3 @@
1
+ import { wecomEndpointCommands } from '../../definition.js';
2
+
3
+ export default wecomEndpointCommands.add;
@@ -1,10 +1,11 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
1
2
  /**
2
- * `wecom.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
- * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
3
+ * `wecom endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
4
+ * commands/wecom/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
5
  */
5
6
  import { createEndpointCommands } from 'zhin.js/adapter';
6
7
  import { defineCommand } from 'zhin.js/command';
7
- import { wecomRuntimeStateToken } from './wecom-runtime-state.js';
8
+ import { wecomRuntimeStateToken } from "../../../lib/wecom-runtime-state.js";
8
9
  export const wecomEndpointCommands = createEndpointCommands({
9
10
  adapterKey: 'wecom',
10
11
  adapterDisplayName: 'WeCom',
@@ -1,10 +1,10 @@
1
1
  /**
2
- * `wecom.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
- * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
2
+ * `wecom endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
+ * commands/wecom/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
4
  */
5
5
  import { createEndpointCommands } from 'zhin.js/adapter';
6
6
  import { defineCommand } from 'zhin.js/command';
7
- import { wecomRuntimeStateToken } from './wecom-runtime-state.js';
7
+ import { wecomRuntimeStateToken } from '../../../src/wecom-runtime-state.js';
8
8
 
9
9
  export const wecomEndpointCommands = createEndpointCommands({
10
10
  adapterKey: 'wecom',
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { wecomEndpointCommands } from "../../lib/wecom-endpoint-commands.js";
2
+ import { wecomEndpointCommands } from '../definition.js';
3
3
  export default wecomEndpointCommands.list;
@@ -0,0 +1,3 @@
1
+ import { wecomEndpointCommands } from '../definition.js';
2
+
3
+ export default wecomEndpointCommands.list;
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { wecomEndpointCommands } from "../../../lib/wecom-endpoint-commands.js";
2
+ import { wecomEndpointCommands } from '../../definition.js';
3
3
  export default wecomEndpointCommands.remove;
@@ -0,0 +1,3 @@
1
+ import { wecomEndpointCommands } from '../../definition.js';
2
+
3
+ export default wecomEndpointCommands.remove;
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { buildSendRequestBody, decryptMessage, extractEncryptFromXml, formatInboundContent, formatOutboundBody, getAesKey, normalizeEchostrParam, normalizeWebhookPath, parseXmlMessage, queryParam, readTextBody, resolveChatType, resolveWecomConfig, verifySignature, type AccessToken, type ResolvedWecomConfig, type WecomAdapterConfig, type WecomApiResponse, type WecomMessage, type WecomSendBody, type WecomWireSegment, } from './protocol.js';
1
+ export { buildSendRequestBody, decryptMessage, extractEncryptFromXml, formatInboundContent, formatOutboundBody, getAesKey, normalizeEchostrParam, normalizeWebhookPath, parseXmlMessage, queryParam, readTextBody, resolveChatType, resolveWecomConfig, verifySignature, type AccessToken, type ResolvedWecomConfig, type WecomEndpointConfig, type WecomApiResponse, type WecomMessage, type WecomSendBody, type WecomWireSegment, } from './protocol.js';
2
2
  export { wecomClient, type WecomClientEventMap } from './client.js';
3
3
  export { checkWecomPlatformPermit, normalizeWecomSenderForPermit, platformPermit, wecomGroupPermitResolver, } from './platform-permit.js';
4
4
  export { WecomClient, WecomEndpoint, type WecomClientApi, type WecomEndpointOptions, type WecomFetch, } from './endpoint.js';
@@ -1,4 +1,4 @@
1
- import { type MediaRef } from '@zhin.js/core';
1
+ import { type MediaRef } from '@zhin.js/im-contract';
2
2
  export interface MediaBinary {
3
3
  readonly data: Buffer;
4
4
  readonly mimeType: string;
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { readFile } from 'node:fs/promises';
7
7
  import { basename } from 'node:path';
8
- import { isMediaRef } from '@zhin.js/core';
8
+ import { isMediaRef } from '@zhin.js/im-contract';
9
9
  const MIME_EXT = {
10
10
  'image/jpeg': 'jpg',
11
11
  'image/png': 'png',
package/lib/protocol.d.ts CHANGED
@@ -4,19 +4,15 @@
4
4
  */
5
5
  import type { IncomingMessage } from 'node:http';
6
6
  import type { ConversationRef } from '@zhin.js/im-contract';
7
- /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
8
- export interface WecomAdapterConfig {
9
- readonly id?: string;
10
- readonly corpId?: string;
11
- readonly agentSecret?: string;
12
- readonly token?: string;
13
- readonly encodingAESKey?: string;
7
+ /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
8
+ export interface WecomEndpointConfig {
9
+ readonly id: string;
10
+ readonly corpId: string;
11
+ readonly agentSecret: string;
12
+ readonly token: string;
13
+ readonly encodingAESKey: string;
14
14
  readonly webhookPath?: string;
15
15
  readonly apiBaseUrl?: string;
16
- /** Transitional: legacy root `endpoints[]` with `context: wecom`. */
17
- readonly endpoints?: ReadonlyArray<Partial<ResolvedWecomConfig> & {
18
- readonly context?: string;
19
- }>;
20
16
  }
21
17
  export interface ResolvedWecomConfig {
22
18
  readonly context: 'wecom';
@@ -74,7 +70,7 @@ export interface WecomSendBody {
74
70
  readonly msgtype: string;
75
71
  readonly data: Record<string, unknown>;
76
72
  }
77
- export declare function resolveWecomConfig(config?: WecomAdapterConfig): ResolvedWecomConfig;
73
+ export declare function resolveWecomConfig(config: WecomEndpointConfig): ResolvedWecomConfig;
78
74
  export declare function normalizeWebhookPath(path: string): string;
79
75
  export declare function queryParam(value: string | null | undefined): string;
80
76
  /** URL 查询里的 Base64 可能把 `+` 解码成空格 */
package/lib/protocol.js CHANGED
@@ -3,21 +3,12 @@
3
3
  * Canonicalization is owned by gateway/core before endpoint.send.
4
4
  */
5
5
  import { createHash, createDecipheriv, timingSafeEqual } from 'node:crypto';
6
- export function resolveWecomConfig(config = {}) {
7
- const entry = config.endpoints?.find((item) => item.context === 'wecom');
8
- const corpId = config.corpId ?? entry?.corpId ?? process.env.WECOM_CORP_ID;
9
- const agentSecret = config.agentSecret ?? entry?.agentSecret ?? process.env.WECOM_AGENT_SECRET;
10
- const token = config.token ?? entry?.token ?? process.env.WECOM_TOKEN;
11
- const encodingAESKey = config.encodingAESKey
12
- ?? entry?.encodingAESKey
13
- ?? process.env.WECOM_AES_KEY;
14
- if (!corpId || !agentSecret || !token || !encodingAESKey) {
15
- throw new TypeError('WeCom adapter requires corpId + agentSecret + token + encodingAESKey (plugins.<key> or endpoints with context: wecom)');
16
- }
17
- const id = (typeof config.id === 'string' && config.id)
18
- || (typeof entry?.id === 'string' && entry.id)
19
- || process.env.WECOM_BOT_NAME
20
- || 'wecom-bot';
6
+ export function resolveWecomConfig(config) {
7
+ const id = requiredEndpointField(config.id, 'id');
8
+ const corpId = requiredEndpointField(config.corpId, 'corpId');
9
+ const agentSecret = requiredEndpointField(config.agentSecret, 'agentSecret');
10
+ const token = requiredEndpointField(config.token, 'token');
11
+ const encodingAESKey = requiredEndpointField(config.encodingAESKey, 'encodingAESKey');
21
12
  return {
22
13
  context: 'wecom',
23
14
  id,
@@ -25,12 +16,20 @@ export function resolveWecomConfig(config = {}) {
25
16
  agentSecret,
26
17
  token,
27
18
  encodingAESKey,
28
- webhookPath: normalizeWebhookPath(config.webhookPath ?? entry?.webhookPath ?? '/wecom/callback'),
29
- apiBaseUrl: config.apiBaseUrl
30
- ?? entry?.apiBaseUrl
31
- ?? 'https://qyapi.weixin.qq.com',
19
+ webhookPath: normalizeWebhookPath(optionalEndpointField(config.webhookPath) ?? '/wecom/callback'),
20
+ apiBaseUrl: optionalEndpointField(config.apiBaseUrl) ?? 'https://qyapi.weixin.qq.com',
32
21
  };
33
22
  }
23
+ function requiredEndpointField(value, field) {
24
+ const resolved = optionalEndpointField(value);
25
+ if (!resolved) {
26
+ throw new TypeError(`WeCom endpoint requires a non-empty ${field}`);
27
+ }
28
+ return resolved;
29
+ }
30
+ function optionalEndpointField(value) {
31
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
32
+ }
34
33
  export function normalizeWebhookPath(path) {
35
34
  const trimmed = path.trim() || '/wecom/callback';
36
35
  return trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * WeCom 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
- * 由 plugin.ts setup() provide,adapter create 与 `wecom.endpoint` 命令共享(同一 owner generation)。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `wecom endpoint` 命令共享(同一 owner generation)。
4
4
  */
5
5
  import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
6
  export const wecomRuntimeStateToken = defineEndpointRuntimeStateToken('wecom');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-wecom",
3
- "version": "1.1.0",
3
+ "version": "1.1.3",
4
4
  "description": "Zhin.js WeCom (企业微信) adapter for Plugin Runtime (HTTP webhook)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -34,27 +34,26 @@
34
34
  "directory": "plugins/adapters/wecom"
35
35
  },
36
36
  "dependencies": {
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"
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/skill": "1.1.2",
45
+ "@zhin.js/tool": "1.1.2"
43
46
  },
44
47
  "peerDependencies": {
45
48
  "zod": "^4.0.0",
46
- "@zhin.js/adapter": "^1.1.12",
47
- "@zhin.js/agent": "^1.1.23",
48
- "@zhin.js/command": "^1.1.0",
49
- "@zhin.js/core": "^1.1.35",
50
- "@zhin.js/host-http": "^1.1.0",
51
- "@zhin.js/permission": "^1.1.0",
52
- "zhin.js": "^1.1.0"
49
+ "@zhin.js/adapter": "^1.1.15",
50
+ "@zhin.js/command": "^1.1.2",
51
+ "@zhin.js/core": "^1.1.38",
52
+ "@zhin.js/host-http": "^1.1.2",
53
+ "@zhin.js/permission": "^1.1.2",
54
+ "zhin.js": "^1.1.3"
53
55
  },
54
56
  "peerDependenciesMeta": {
55
- "@zhin.js/agent": {
56
- "optional": true
57
- },
58
57
  "@zhin.js/command": {
59
58
  "optional": true
60
59
  },
@@ -70,8 +69,7 @@
70
69
  "typescript": "^6.0.3",
71
70
  "vitest": "^4.1.10",
72
71
  "zod": "^4.4.3",
73
- "@zhin.js/agent": "1.1.23",
74
- "zhin.js": "1.1.0"
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
@@ -31,10 +31,11 @@
31
31
  },
32
32
  "endpoints": {
33
33
  "type": "array",
34
+ "minItems": 1,
34
35
  "description": "多账号:一个插件实例挂多个 endpoint。每项与顶层字段同构(id 必填,其余覆盖顶层)",
35
36
  "items": {
36
37
  "type": "object",
37
- "additionalProperties": true,
38
+ "additionalProperties": false,
38
39
  "properties": {
39
40
  "master": {
40
41
  "type": [
@@ -70,6 +71,15 @@
70
71
  "type": "string",
71
72
  "description": "WeCom encoding AES key"
72
73
  },
74
+ "webhookPath": {
75
+ "type": "string"
76
+ },
77
+ "apiBaseUrl": {
78
+ "type": "string"
79
+ },
80
+ "commandPrefix": {
81
+ "type": "string"
82
+ },
73
83
  "id": {
74
84
  "type": "string",
75
85
  "description": "WeCom bot name"
package/src/index.ts CHANGED
@@ -15,7 +15,7 @@ export {
15
15
  verifySignature,
16
16
  type AccessToken,
17
17
  type ResolvedWecomConfig,
18
- type WecomAdapterConfig,
18
+ type WecomEndpointConfig,
19
19
  type WecomApiResponse,
20
20
  type WecomMessage,
21
21
  type WecomSendBody,
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { readFile } from 'node:fs/promises';
7
7
  import { basename } from 'node:path';
8
- import { isMediaRef, type MediaRef } from '@zhin.js/core';
8
+ import { isMediaRef, type MediaRef } from '@zhin.js/im-contract';
9
9
 
10
10
  export interface MediaBinary {
11
11
  readonly data: Buffer;
package/src/protocol.ts CHANGED
@@ -7,19 +7,15 @@ import { createHash, createDecipheriv, timingSafeEqual } from 'node:crypto';
7
7
  import type { IncomingMessage } from 'node:http';
8
8
  import type { ConversationRef } from '@zhin.js/im-contract';
9
9
 
10
- /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
11
- export interface WecomAdapterConfig {
12
- readonly id?: string;
13
- readonly corpId?: string;
14
- readonly agentSecret?: string;
15
- readonly token?: string;
16
- readonly encodingAESKey?: string;
10
+ /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
11
+ export interface WecomEndpointConfig {
12
+ readonly id: string;
13
+ readonly corpId: string;
14
+ readonly agentSecret: string;
15
+ readonly token: string;
16
+ readonly encodingAESKey: string;
17
17
  readonly webhookPath?: string;
18
18
  readonly apiBaseUrl?: string;
19
- /** Transitional: legacy root `endpoints[]` with `context: wecom`. */
20
- readonly endpoints?: ReadonlyArray<Partial<ResolvedWecomConfig> & {
21
- readonly context?: string;
22
- }>;
23
19
  }
24
20
 
25
21
  export interface ResolvedWecomConfig {
@@ -84,23 +80,12 @@ export interface WecomSendBody {
84
80
  readonly data: Record<string, unknown>;
85
81
  }
86
82
 
87
- export function resolveWecomConfig(config: WecomAdapterConfig = {}): ResolvedWecomConfig {
88
- const entry = config.endpoints?.find((item) => item.context === 'wecom');
89
- const corpId = config.corpId ?? entry?.corpId ?? process.env.WECOM_CORP_ID;
90
- const agentSecret = config.agentSecret ?? entry?.agentSecret ?? process.env.WECOM_AGENT_SECRET;
91
- const token = config.token ?? entry?.token ?? process.env.WECOM_TOKEN;
92
- const encodingAESKey = config.encodingAESKey
93
- ?? entry?.encodingAESKey
94
- ?? process.env.WECOM_AES_KEY;
95
- if (!corpId || !agentSecret || !token || !encodingAESKey) {
96
- throw new TypeError(
97
- 'WeCom adapter requires corpId + agentSecret + token + encodingAESKey (plugins.<key> or endpoints with context: wecom)',
98
- );
99
- }
100
- const id = (typeof config.id === 'string' && config.id)
101
- || (typeof entry?.id === 'string' && entry.id)
102
- || process.env.WECOM_BOT_NAME
103
- || 'wecom-bot';
83
+ export function resolveWecomConfig(config: WecomEndpointConfig): ResolvedWecomConfig {
84
+ const id = requiredEndpointField(config.id, 'id');
85
+ const corpId = requiredEndpointField(config.corpId, 'corpId');
86
+ const agentSecret = requiredEndpointField(config.agentSecret, 'agentSecret');
87
+ const token = requiredEndpointField(config.token, 'token');
88
+ const encodingAESKey = requiredEndpointField(config.encodingAESKey, 'encodingAESKey');
104
89
  return {
105
90
  context: 'wecom',
106
91
  id,
@@ -109,14 +94,27 @@ export function resolveWecomConfig(config: WecomAdapterConfig = {}): ResolvedWec
109
94
  token,
110
95
  encodingAESKey,
111
96
  webhookPath: normalizeWebhookPath(
112
- config.webhookPath ?? entry?.webhookPath ?? '/wecom/callback',
97
+ optionalEndpointField(config.webhookPath) ?? '/wecom/callback',
113
98
  ),
114
- apiBaseUrl: config.apiBaseUrl
115
- ?? entry?.apiBaseUrl
116
- ?? 'https://qyapi.weixin.qq.com',
99
+ apiBaseUrl: optionalEndpointField(config.apiBaseUrl) ?? 'https://qyapi.weixin.qq.com',
117
100
  };
118
101
  }
119
102
 
103
+ function requiredEndpointField(
104
+ value: unknown,
105
+ field: 'id' | 'corpId' | 'agentSecret' | 'token' | 'encodingAESKey',
106
+ ): string {
107
+ const resolved = optionalEndpointField(value);
108
+ if (!resolved) {
109
+ throw new TypeError(`WeCom endpoint requires a non-empty ${field}`);
110
+ }
111
+ return resolved;
112
+ }
113
+
114
+ function optionalEndpointField(value: unknown): string | undefined {
115
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
116
+ }
117
+
120
118
  export function normalizeWebhookPath(path: string): string {
121
119
  const trimmed = path.trim() || '/wecom/callback';
122
120
  return trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * WeCom 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
- * 由 plugin.ts setup() provide,adapter create 与 `wecom.endpoint` 命令共享(同一 owner generation)。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `wecom endpoint` 命令共享(同一 owner generation)。
4
4
  */
5
5
  import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
6
 
@@ -1,3 +0,0 @@
1
- import { wecomEndpointCommands } from '../../../src/wecom-endpoint-commands.js';
2
-
3
- export default wecomEndpointCommands.add;
@@ -1,3 +0,0 @@
1
- import { wecomEndpointCommands } from '../../src/wecom-endpoint-commands.js';
2
-
3
- export default wecomEndpointCommands.list;
@@ -1,3 +0,0 @@
1
- import { wecomEndpointCommands } from '../../../src/wecom-endpoint-commands.js';
2
-
3
- export default wecomEndpointCommands.remove;
@@ -1 +0,0 @@
1
- export declare const wecomEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;
File without changes