@zhin.js/adapter-line 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 (36) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/README.md +8 -8
  3. package/adapters/{line.js → line/index.js} +6 -6
  4. package/adapters/{line.ts → line/index.ts} +9 -9
  5. package/agents/line/agent.json +20 -0
  6. package/agents/line/boundaries.md +3 -0
  7. package/agents/line/conventions.md +3 -0
  8. package/{agent/skills/line.md → agents/line/skills/line/SKILL.md} +3 -0
  9. package/agents/line/skills/line/tools/get_group_members/index.js +16 -0
  10. package/{agent/tools/get_group_members.ts → agents/line/skills/line/tools/get_group_members/index.ts} +1 -1
  11. package/agents/line/skills/line/tools/get_profile/index.js +16 -0
  12. package/{agent/tools/get_profile.ts → agents/line/skills/line/tools/get_profile/index.ts} +1 -1
  13. package/agents/line/system.md +3 -0
  14. package/commands/{endpoint/add/[id].js → line/endpoint/add/[id]/index.js} +1 -1
  15. package/commands/line/endpoint/add/[id]/index.ts +3 -0
  16. package/{lib/line-endpoint-commands.js → commands/line/endpoint/definition.js} +4 -3
  17. package/{src/line-endpoint-commands.ts → commands/line/endpoint/definition.ts} +3 -3
  18. package/commands/{endpoint/list.js → line/endpoint/list/index.js} +1 -1
  19. package/commands/line/endpoint/list/index.ts +3 -0
  20. package/commands/{endpoint/remove/[id].js → line/endpoint/remove/[id]/index.js} +1 -1
  21. package/commands/line/endpoint/remove/[id]/index.ts +3 -0
  22. package/lib/index.d.ts +1 -1
  23. package/lib/line-runtime-state.js +1 -1
  24. package/lib/protocol.d.ts +7 -11
  25. package/lib/protocol.js +13 -18
  26. package/package.json +32 -20
  27. package/plugin.js +1 -1
  28. package/schema.json +11 -1
  29. package/src/index.ts +1 -1
  30. package/src/line-runtime-state.ts +1 -1
  31. package/src/protocol.ts +24 -31
  32. package/commands/endpoint/add/[id].ts +0 -3
  33. package/commands/endpoint/list.ts +0 -3
  34. package/commands/endpoint/remove/[id].ts +0 -3
  35. package/lib/line-endpoint-commands.d.ts +0 -1
  36. /package/{agent/PERMITS.md → PERMITS.md} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,113 @@
1
1
  # @zhin.js/adapter-line
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
+ - 40d2c8f: Reduce the default Agent Tool surface by moving process diagnostics into a Skill and splitting broad platform Skills into focused task domains. Restore ICQQ friend and group directory tools with `on-risk` approval and explicit owner, administrator, master, or trusted access.
36
+ - 4380cf9: Colocate adapter command definitions and Agent Skill handlers with their owning capabilities, and provide a shared validated platform permission constructor.
37
+ - d8cdff0: Require the canonical expanded LINE endpoint configuration. The protocol no longer reinterprets nested `endpoints` or reads endpoint identity and credentials from `process.env`. The public config type is now `LineEndpointConfig`, and each schema entry uses `id` as its identity.
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 [2dbbc15]
66
+ - Updated dependencies [1cb1163]
67
+ - Updated dependencies [be3061e]
68
+ - Updated dependencies [75f8332]
69
+ - Updated dependencies [81935e2]
70
+ - Updated dependencies [f9ed01b]
71
+ - Updated dependencies [ac0ab50]
72
+ - Updated dependencies [5140ce1]
73
+ - Updated dependencies [522d75f]
74
+ - Updated dependencies [a7611b3]
75
+ - Updated dependencies [8823044]
76
+ - Updated dependencies [379439b]
77
+ - Updated dependencies [11c9352]
78
+ - Updated dependencies [6b70e46]
79
+ - Updated dependencies [135ac91]
80
+ - Updated dependencies [140cf0f]
81
+ - Updated dependencies [251e4d2]
82
+ - Updated dependencies [203ad34]
83
+ - Updated dependencies [e6c5113]
84
+ - Updated dependencies [e0f6478]
85
+ - Updated dependencies [baef56b]
86
+ - Updated dependencies [698f16f]
87
+ - Updated dependencies [da0a8e3]
88
+ - Updated dependencies [2fd8017]
89
+ - Updated dependencies [5c3858e]
90
+ - Updated dependencies [33ea736]
91
+ - Updated dependencies [507d602]
92
+ - Updated dependencies [df9f76b]
93
+ - @zhin.js/core@1.1.37
94
+ - @zhin.js/tool@1.1.1
95
+ - @zhin.js/host-http@1.1.1
96
+ - @zhin.js/adapter@1.1.14
97
+ - @zhin.js/feature-kit@1.1.1
98
+ - @zhin.js/agent-feature@1.1.1
99
+ - @zhin.js/skill@1.1.1
100
+ - @zhin.js/logger@1.1.1
101
+ - @zhin.js/im-contract@1.1.1
102
+
103
+ ## 1.1.1
104
+
105
+ ### Patch Changes
106
+
107
+ - Updated dependencies [769e67f]
108
+ - @zhin.js/adapter@1.1.13
109
+ - @zhin.js/core@1.1.36
110
+
3
111
  ## 1.1.0
4
112
 
5
113
  ### Minor Changes
package/README.md CHANGED
@@ -18,7 +18,7 @@ pnpm add @zhin.js/adapter-line
18
18
 
19
19
  ## Plugin Runtime
20
20
 
21
- - `@zhin.js/adapter` — 约定式 `adapters/line.ts`(`defineAdapter`)
21
+ - `@zhin.js/adapter` — 约定式 `adapters/line/index.ts`(`defineAdapter`)
22
22
  - `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
23
23
  - `@zhin.js/host-http` — `httpHostToken` 注册 Webhook 路由(**非** legacy host-router/Koa)
24
24
  - `zhin.js` — `plugin.ts`(`definePlugin`)
@@ -35,7 +35,7 @@ pnpm add @zhin.js/adapter-line
35
35
  4. 在 Console 中启用 **Use webhooks** 并关闭 **Auto-reply messages**
36
36
  5. Runtime Host(`http`)须已 listen,Webhook 才可达
37
37
 
38
- 必填字段(`endpoints[i]`):`name`、`channelSecret`、`channelAccessToken`。
38
+ 必填字段(`endpoints[i]`):`id`、`channelSecret`、`channelAccessToken`。
39
39
 
40
40
  ## 最小配置
41
41
 
@@ -46,7 +46,7 @@ plugins:
46
46
  webhookPath: /line/webhook # 可选,默认 /line/webhook
47
47
  apiBaseUrl: https://api.line.me # 可选,调试时可改为 LINE API 沙盒地址
48
48
  endpoints:
49
- - name: my-line-bot
49
+ - id: my-line-bot
50
50
  channelSecret: ${LINE_CHANNEL_SECRET}
51
51
  channelAccessToken: ${LINE_CHANNEL_ACCESS_TOKEN}
52
52
  ```
@@ -57,8 +57,8 @@ plugins:
57
57
 
58
58
  | 变量 | 说明 |
59
59
  |------|------|
60
- | `LINE_CHANNEL_SECRET` | Channel Secret(签名验证用) |
61
- | `LINE_CHANNEL_ACCESS_TOKEN` | Long-lived Channel Access Token(API 调用用) |
60
+ | `LINE_CHANNEL_SECRET` | 示例中由 YAML `${LINE_CHANNEL_SECRET}` 引用的 Channel Secret;变量名可自行定义 |
61
+ | `LINE_CHANNEL_ACCESS_TOKEN` | 示例中由 YAML `${LINE_CHANNEL_ACCESS_TOKEN}` 引用的 Channel Access Token;变量名可自行定义 |
62
62
 
63
63
  ## Webhook URL 配置
64
64
 
@@ -86,9 +86,9 @@ LINE 要求 Webhook URL 以 HTTPS 开头。常见方案:
86
86
 
87
87
  | 类别 | 路径 |
88
88
  |------|------|
89
- | Permit 词汇 | `agent/PERMITS.md` |
90
- | 平台工具(2 个) | `agent/tools/`(`line_get_profile`、`line_get_group_members`) |
91
- | 技能说明 | `agent/skills/line.md` |
89
+ | Permit 词汇 | `PERMITS.md` |
90
+ | 平台工具(2 个) | `tools/`(`line_get_profile`、`line_get_group_members`) |
91
+ | 技能说明 | `agents/line/skills/line/SKILL.md` |
92
92
 
93
93
  ## 已知限制
94
94
 
@@ -1,13 +1,13 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  /**
3
- * Convention entry: discover `adapters/line.ts` → defineAdapter.
3
+ * Convention entry: discover `adapters/line/index.ts` → defineAdapter.
4
4
  */
5
5
  import { defineAdapter } from 'zhin.js/adapter';
6
6
  import { httpHostToken } from '@zhin.js/host-http';
7
- import { LineEndpoint } from "../lib/endpoint.js";
8
- import { resolveLineConfig, } from "../lib/protocol.js";
9
- import { lineRuntimeStateToken } from "../lib/line-runtime-state.js";
10
- export { LineEndpoint } from "../lib/endpoint.js";
7
+ import { LineEndpoint } from "../../lib/endpoint.js";
8
+ import { resolveLineConfig, } from "../../lib/protocol.js";
9
+ import { lineRuntimeStateToken } from "../../lib/line-runtime-state.js";
10
+ export { LineEndpoint } from "../../lib/endpoint.js";
11
11
  export default defineAdapter({
12
12
  capabilities: ['inbound', 'outbound'],
13
13
  // LINE Messaging API 媒体消息仅消费远程 URL;无按钮交互面,交互段降级纯文本。
@@ -17,7 +17,7 @@ export default defineAdapter({
17
17
  },
18
18
  create(context) {
19
19
  const config = resolveLineConfig(context.config);
20
- // 注册到插件运行时状态(line.endpoint list 的"运行中"数据源)
20
+ // 注册到插件运行时状态(line endpoint list 的"运行中"数据源)
21
21
  context.use(lineRuntimeStateToken).endpoints.set(config.id, {
22
22
  id: config.id,
23
23
  mode: 'webhook',
@@ -1,19 +1,19 @@
1
1
  /**
2
- * Convention entry: discover `adapters/line.ts` → defineAdapter.
2
+ * Convention entry: discover `adapters/line/index.ts` → defineAdapter.
3
3
  */
4
4
  import { defineAdapter } from 'zhin.js/adapter';
5
5
  import { httpHostToken } from '@zhin.js/host-http';
6
- import { LineEndpoint } from '../src/endpoint.js';
6
+ import { LineEndpoint } from '../../src/endpoint.js';
7
7
  import {
8
8
  resolveLineConfig,
9
- type LineAdapterConfig,
10
- } from '../src/protocol.js';
11
- import { lineRuntimeStateToken } from '../src/line-runtime-state.js';
9
+ type LineEndpointConfig,
10
+ } from '../../src/protocol.js';
11
+ import { lineRuntimeStateToken } from '../../src/line-runtime-state.js';
12
12
 
13
- export { LineEndpoint } from '../src/endpoint.js';
14
- export type { LineEndpointOptions, LineFetch } from '../src/endpoint.js';
13
+ export { LineEndpoint } from '../../src/endpoint.js';
14
+ export type { LineEndpointOptions, LineFetch } from '../../src/endpoint.js';
15
15
 
16
- export default defineAdapter<LineAdapterConfig>({
16
+ export default defineAdapter<LineEndpointConfig>({
17
17
  capabilities: ['inbound', 'outbound'],
18
18
  // LINE Messaging API 媒体消息仅消费远程 URL;无按钮交互面,交互段降级纯文本。
19
19
  segments: {
@@ -22,7 +22,7 @@ export default defineAdapter<LineAdapterConfig>({
22
22
  },
23
23
  create(context) {
24
24
  const config = resolveLineConfig(context.config);
25
- // 注册到插件运行时状态(line.endpoint list 的"运行中"数据源)
25
+ // 注册到插件运行时状态(line endpoint list 的"运行中"数据源)
26
26
  context.use(lineRuntimeStateToken).endpoints.set(config.id, {
27
27
  id: config.id,
28
28
  mode: 'webhook',
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "LINE Platform Agent",
3
+ "version": "1.0.0",
4
+ "description": "Handles line platform-specific operations and progressively loads only the required platform Skill.",
5
+ "trigger_rules": {
6
+ "file_patterns": [],
7
+ "keywords": [
8
+ "line",
9
+ "adapter:line"
10
+ ]
11
+ },
12
+ "entry_points": [
13
+ "system.md",
14
+ "boundaries.md",
15
+ "conventions.md"
16
+ ],
17
+ "platforms": [
18
+ "line"
19
+ ]
20
+ }
@@ -0,0 +1,3 @@
1
+ # Boundaries
2
+
3
+ Operate only on the active line 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.
@@ -14,6 +14,9 @@ keywords:
14
14
  tags:
15
15
  - im
16
16
  - adapter
17
+ tools:
18
+ - "get_group_members"
19
+ - "get_profile"
17
20
  ---
18
21
  # LINE Messaging API 技能
19
22
 
@@ -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: 'Get LINE group member IDs',
6
+ adapter: 'line',
7
+ inputSchema: z.object({
8
+ groupId: z.string().min(1),
9
+ }),
10
+ async execute({ groupId }, context) {
11
+ if (!groupId.startsWith('G')) {
12
+ throw new Error(`Invalid groupId "${groupId}": must start with G`);
13
+ }
14
+ return context.$client.getGroupMemberIds(groupId);
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
 
4
4
  export default defineAgentTool<{ groupId: string }>({
@@ -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: 'Get LINE user profile by userId',
6
+ adapter: 'line',
7
+ inputSchema: z.object({
8
+ userId: z.string().min(1),
9
+ }),
10
+ async execute({ userId }, context) {
11
+ if (!userId.startsWith('U')) {
12
+ throw new Error(`Invalid userId "${userId}": must start with U`);
13
+ }
14
+ return context.$client.getProfile(userId);
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
 
4
4
  export default defineAgentTool<{ userId: string }>({
@@ -0,0 +1,3 @@
1
+ # LINE Platform Agent
2
+
3
+ You are the line platform specialist. Interpret requests in the current line 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 { lineEndpointCommands } from "../../../lib/line-endpoint-commands.js";
2
+ import { lineEndpointCommands } from '../../definition.js';
3
3
  export default lineEndpointCommands.add;
@@ -0,0 +1,3 @@
1
+ import { lineEndpointCommands } from '../../definition.js';
2
+
3
+ export default lineEndpointCommands.add;
@@ -1,10 +1,11 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
1
2
  /**
2
- * `line.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
- * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
3
+ * `line endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
4
+ * commands/line/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
5
  */
5
6
  import { createEndpointCommands } from 'zhin.js/adapter';
6
7
  import { defineCommand } from 'zhin.js/command';
7
- import { lineRuntimeStateToken } from './line-runtime-state.js';
8
+ import { lineRuntimeStateToken } from "../../../lib/line-runtime-state.js";
8
9
  export const lineEndpointCommands = createEndpointCommands({
9
10
  adapterKey: 'line',
10
11
  adapterDisplayName: 'LINE',
@@ -1,10 +1,10 @@
1
1
  /**
2
- * `line.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
- * commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
2
+ * `line endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
3
+ * commands/line/endpoint/ 下的 list / add / remove 直接默认导出这三项。
4
4
  */
5
5
  import { createEndpointCommands } from 'zhin.js/adapter';
6
6
  import { defineCommand } from 'zhin.js/command';
7
- import { lineRuntimeStateToken } from './line-runtime-state.js';
7
+ import { lineRuntimeStateToken } from '../../../src/line-runtime-state.js';
8
8
 
9
9
  export const lineEndpointCommands = createEndpointCommands({
10
10
  adapterKey: 'line',
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { lineEndpointCommands } from "../../lib/line-endpoint-commands.js";
2
+ import { lineEndpointCommands } from '../definition.js';
3
3
  export default lineEndpointCommands.list;
@@ -0,0 +1,3 @@
1
+ import { lineEndpointCommands } from '../definition.js';
2
+
3
+ export default lineEndpointCommands.list;
@@ -1,3 +1,3 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { lineEndpointCommands } from "../../../lib/line-endpoint-commands.js";
2
+ import { lineEndpointCommands } from '../../definition.js';
3
3
  export default lineEndpointCommands.remove;
@@ -0,0 +1,3 @@
1
+ import { lineEndpointCommands } from '../../definition.js';
2
+
3
+ export default lineEndpointCommands.remove;
package/lib/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { formatInboundContent, formatOutboundMessages, generateMessageId, isMessageEvent, isPostbackEvent, isValidLineRecipientId, normalizeWebhookPath, readTextBody, resolveChannel, resolveLineConfig, verifySignature, type LineAdapterConfig, type LineApiResponse, type LineChannel, type LineEvent, type LineFollowEvent, type LineJoinEvent, type LineLeaveEvent, type LineMessage, type LineMessageEvent, type LinePostbackEvent, type LinePushRequest, type LineReplyMessage, type LineReplyRequest, type LineSource, type LineUnfollowEvent, type LineUser, type LineWebhookBody, type LineWireSegment, type ResolvedLineConfig, } from './protocol.js';
1
+ export { formatInboundContent, formatOutboundMessages, generateMessageId, isMessageEvent, isPostbackEvent, isValidLineRecipientId, normalizeWebhookPath, readTextBody, resolveChannel, resolveLineConfig, verifySignature, type LineEndpointConfig, type LineApiResponse, type LineChannel, type LineEvent, type LineFollowEvent, type LineJoinEvent, type LineLeaveEvent, type LineMessage, type LineMessageEvent, type LinePostbackEvent, type LinePushRequest, type LineReplyMessage, type LineReplyRequest, type LineSource, type LineUnfollowEvent, type LineUser, type LineWebhookBody, type LineWireSegment, type ResolvedLineConfig, } from './protocol.js';
2
2
  export { LineEndpoint, type LineEndpointOptions, type LineFetch, } from './endpoint.js';
3
3
  export { registerLineWebhookRoutes, handleLineWebhookRequest, type LineWebhookHandler, } from './webhook.js';
4
4
  export { LineClient, lineClient, type LineClientEventMap, type LineGroupMember, } from './client.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * LINE 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
- * 由 plugin.ts setup() provide,adapter create 与 `line.endpoint` 命令共享(同一 owner generation)。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `line endpoint` 命令共享(同一 owner generation)。
4
4
  */
5
5
  import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
6
  export const lineRuntimeStateToken = defineEndpointRuntimeStateToken('line');
package/lib/protocol.d.ts CHANGED
@@ -3,18 +3,14 @@
3
3
  * Canonicalization is owned by gateway/core before endpoint.send.
4
4
  */
5
5
  import type { IncomingMessage } from 'node:http';
6
- import type { ConversationRef } from '@zhin.js/im-contract';
7
- /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
8
- export interface LineAdapterConfig {
9
- readonly id?: string;
10
- readonly channelSecret?: string;
11
- readonly channelAccessToken?: string;
6
+ import { type ConversationRef } from '@zhin.js/im-contract';
7
+ /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
8
+ export interface LineEndpointConfig {
9
+ readonly id: string;
10
+ readonly channelSecret: string;
11
+ readonly channelAccessToken: string;
12
12
  readonly webhookPath?: string;
13
13
  readonly apiBaseUrl?: string;
14
- /** Transitional: legacy root `endpoints[]` with `context: line`. */
15
- readonly endpoints?: ReadonlyArray<Partial<ResolvedLineConfig> & {
16
- readonly context?: string;
17
- }>;
18
14
  }
19
15
  export interface ResolvedLineConfig {
20
16
  readonly context: 'line';
@@ -132,7 +128,7 @@ export interface LineChannel {
132
128
  readonly channelType: 'private' | 'group' | 'channel';
133
129
  readonly channelId: string;
134
130
  }
135
- export declare function resolveLineConfig(config?: LineAdapterConfig): ResolvedLineConfig;
131
+ export declare function resolveLineConfig(config: LineEndpointConfig): ResolvedLineConfig;
136
132
  export declare function normalizeWebhookPath(path: string): string;
137
133
  export declare function isMessageEvent(event: LineEvent): event is LineMessageEvent;
138
134
  export declare function isLineLifecycleEvent(event: LineEvent): boolean;
package/lib/protocol.js CHANGED
@@ -3,26 +3,15 @@
3
3
  * Canonicalization is owned by gateway/core before endpoint.send.
4
4
  */
5
5
  import { createHmac, timingSafeEqual } from 'node:crypto';
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('line');
9
- export function resolveLineConfig(config = {}) {
10
- const entry = config.endpoints?.find((item) => item.context === 'line');
11
- const channelSecret = config.channelSecret
12
- ?? entry?.channelSecret
13
- ?? process.env.LINE_CHANNEL_SECRET;
14
- const channelAccessToken = config.channelAccessToken
15
- ?? entry?.channelAccessToken
16
- ?? process.env.LINE_CHANNEL_ACCESS_TOKEN;
17
- if (!channelSecret || !channelAccessToken) {
18
- throw new TypeError('LINE adapter requires channelSecret + channelAccessToken (plugins.<key> or endpoints with context: line)');
19
- }
20
- const id = (typeof config.id === 'string' && config.id)
21
- || (typeof entry?.id === 'string' && entry.id)
22
- || process.env.LINE_BOT_NAME
23
- || 'line-bot';
24
- const webhookPath = normalizeWebhookPath(config.webhookPath ?? entry?.webhookPath ?? '/line/webhook');
25
- const apiBaseUrl = (config.apiBaseUrl ?? entry?.apiBaseUrl ?? 'https://api.line.me').replace(/\/$/, '');
9
+ export function resolveLineConfig(config) {
10
+ const id = requiredEndpointField(config.id, 'id');
11
+ const channelSecret = requiredEndpointField(config.channelSecret, 'channelSecret');
12
+ const channelAccessToken = requiredEndpointField(config.channelAccessToken, 'channelAccessToken');
13
+ const webhookPath = normalizeWebhookPath(config.webhookPath ?? '/line/webhook');
14
+ const apiBaseUrl = (config.apiBaseUrl ?? 'https://api.line.me').replace(/\/$/, '');
26
15
  return {
27
16
  context: 'line',
28
17
  id,
@@ -32,6 +21,12 @@ export function resolveLineConfig(config = {}) {
32
21
  apiBaseUrl,
33
22
  };
34
23
  }
24
+ function requiredEndpointField(value, field) {
25
+ if (typeof value !== 'string' || !value.trim()) {
26
+ throw new TypeError(`LINE endpoint requires a non-empty ${field}`);
27
+ }
28
+ return value.trim();
29
+ }
35
30
  export function normalizeWebhookPath(path) {
36
31
  const trimmed = path.trim() || '/line/webhook';
37
32
  return trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-line",
3
- "version": "1.1.0",
3
+ "version": "1.1.3",
4
4
  "description": "Zhin.js LINE Messaging API adapter for Plugin Runtime (HTTP webhook)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -32,26 +32,25 @@
32
32
  "directory": "plugins/adapters/line"
33
33
  },
34
34
  "dependencies": {
35
- "@zhin.js/adapter": "1.1.12",
36
- "@zhin.js/core": "1.1.35",
37
- "@zhin.js/feature-kit": "1.1.0",
38
- "@zhin.js/host-http": "1.1.0",
39
- "@zhin.js/im-contract": "1.1.0",
40
- "@zhin.js/logger": "1.1.0"
35
+ "@zhin.js/adapter": "1.1.15",
36
+ "@zhin.js/agent-feature": "1.1.2",
37
+ "@zhin.js/core": "1.1.38",
38
+ "@zhin.js/feature-kit": "1.1.2",
39
+ "@zhin.js/host-http": "1.1.2",
40
+ "@zhin.js/im-contract": "1.1.2",
41
+ "@zhin.js/logger": "1.1.1",
42
+ "@zhin.js/skill": "1.1.2",
43
+ "@zhin.js/tool": "1.1.2"
41
44
  },
42
45
  "peerDependencies": {
43
46
  "zod": "^4.0.0",
44
- "@zhin.js/adapter": "^1.1.12",
45
- "@zhin.js/agent": "^1.1.23",
46
- "@zhin.js/command": "^1.1.0",
47
- "@zhin.js/core": "^1.1.35",
48
- "@zhin.js/host-http": "^1.1.0",
49
- "zhin.js": "^1.1.0"
47
+ "@zhin.js/adapter": "^1.1.15",
48
+ "@zhin.js/command": "^1.1.2",
49
+ "@zhin.js/core": "^1.1.38",
50
+ "@zhin.js/host-http": "^1.1.2",
51
+ "zhin.js": "^1.1.3"
50
52
  },
51
53
  "peerDependenciesMeta": {
52
- "@zhin.js/agent": {
53
- "optional": true
54
- },
55
54
  "@zhin.js/command": {
56
55
  "optional": true
57
56
  },
@@ -67,8 +66,7 @@
67
66
  "typescript": "^6.0.3",
68
67
  "vitest": "^4.1.10",
69
68
  "zod": "^4.4.3",
70
- "@zhin.js/agent": "1.1.23",
71
- "zhin.js": "1.1.0"
69
+ "zhin.js": "1.1.3"
72
70
  },
73
71
  "files": [
74
72
  "adapters",
@@ -77,9 +75,11 @@
77
75
  "schema.json",
78
76
  "src",
79
77
  "lib",
80
- "agent",
78
+ "tools",
79
+ "agents",
81
80
  "README.md",
82
- "CHANGELOG.md"
81
+ "CHANGELOG.md",
82
+ "PERMITS.md"
83
83
  ],
84
84
  "publishConfig": {
85
85
  "access": "public",
@@ -102,6 +102,18 @@
102
102
  {
103
103
  "package": "@zhin.js/command",
104
104
  "api": "^1.0.0"
105
+ },
106
+ {
107
+ "package": "@zhin.js/tool",
108
+ "api": "^1.0.0"
109
+ },
110
+ {
111
+ "package": "@zhin.js/skill",
112
+ "api": "^1.0.0"
113
+ },
114
+ {
115
+ "package": "@zhin.js/agent-feature",
116
+ "api": "^1.0.0"
105
117
  }
106
118
  ],
107
119
  "plugins": []
package/plugin.js CHANGED
@@ -8,7 +8,7 @@ export default definePlugin({
8
8
  displayName: 'LINE Messaging API Adapter',
9
9
  },
10
10
  setup(context) {
11
- // 运行中 endpoint 注册表(line.endpoint list 的"运行中"数据源)
11
+ // 运行中 endpoint 注册表(line endpoint list 的"运行中"数据源)
12
12
  context.resources.provide(lineRuntimeStateToken, createEndpointRuntimeState());
13
13
  },
14
14
  });
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": [
@@ -62,6 +63,15 @@
62
63
  "type": "string",
63
64
  "description": "LINE channel access token"
64
65
  },
66
+ "webhookPath": {
67
+ "type": "string"
68
+ },
69
+ "apiBaseUrl": {
70
+ "type": "string"
71
+ },
72
+ "commandPrefix": {
73
+ "type": "string"
74
+ },
65
75
  "id": {
66
76
  "type": "string",
67
77
  "description": "LINE bot name"
package/src/index.ts CHANGED
@@ -10,7 +10,7 @@ export {
10
10
  resolveChannel,
11
11
  resolveLineConfig,
12
12
  verifySignature,
13
- type LineAdapterConfig,
13
+ type LineEndpointConfig,
14
14
  type LineApiResponse,
15
15
  type LineChannel,
16
16
  type LineEvent,
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * LINE 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
3
- * 由 plugin.ts setup() provide,adapter create 与 `line.endpoint` 命令共享(同一 owner generation)。
3
+ * 由 plugin.ts setup() provide,adapter create 与 `line endpoint` 命令共享(同一 owner generation)。
4
4
  */
5
5
  import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
6
6
 
package/src/protocol.ts CHANGED
@@ -5,23 +5,18 @@
5
5
 
6
6
  import { createHmac, timingSafeEqual } from 'node:crypto';
7
7
  import type { IncomingMessage } from 'node:http';
8
- import { isMediaRef } from '@zhin.js/core';
9
- import type { ConversationRef } from '@zhin.js/im-contract';
8
+ import { isMediaRef, type ConversationRef } from '@zhin.js/im-contract';
10
9
  import { formatCompact, getLogger } from '@zhin.js/logger';
11
10
 
12
11
  const logger = getLogger('line');
13
12
 
14
- /** Plugin Runtime owner config (`plugins.<instanceKey>` / schema.json). */
15
- export interface LineAdapterConfig {
16
- readonly id?: string;
17
- readonly channelSecret?: string;
18
- readonly channelAccessToken?: string;
13
+ /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
14
+ export interface LineEndpointConfig {
15
+ readonly id: string;
16
+ readonly channelSecret: string;
17
+ readonly channelAccessToken: string;
19
18
  readonly webhookPath?: string;
20
19
  readonly apiBaseUrl?: string;
21
- /** Transitional: legacy root `endpoints[]` with `context: line`. */
22
- readonly endpoints?: ReadonlyArray<Partial<ResolvedLineConfig> & {
23
- readonly context?: string;
24
- }>;
25
20
  }
26
21
 
27
22
  export interface ResolvedLineConfig {
@@ -161,27 +156,15 @@ export interface LineChannel {
161
156
  readonly channelId: string;
162
157
  }
163
158
 
164
- export function resolveLineConfig(config: LineAdapterConfig = {}): ResolvedLineConfig {
165
- const entry = config.endpoints?.find((item) => item.context === 'line');
166
- const channelSecret = config.channelSecret
167
- ?? entry?.channelSecret
168
- ?? process.env.LINE_CHANNEL_SECRET;
169
- const channelAccessToken = config.channelAccessToken
170
- ?? entry?.channelAccessToken
171
- ?? process.env.LINE_CHANNEL_ACCESS_TOKEN;
172
- if (!channelSecret || !channelAccessToken) {
173
- throw new TypeError(
174
- 'LINE adapter requires channelSecret + channelAccessToken (plugins.<key> or endpoints with context: line)',
175
- );
176
- }
177
- const id = (typeof config.id === 'string' && config.id)
178
- || (typeof entry?.id === 'string' && entry.id)
179
- || process.env.LINE_BOT_NAME
180
- || 'line-bot';
181
- const webhookPath = normalizeWebhookPath(
182
- config.webhookPath ?? entry?.webhookPath ?? '/line/webhook',
159
+ export function resolveLineConfig(config: LineEndpointConfig): ResolvedLineConfig {
160
+ const id = requiredEndpointField(config.id, 'id');
161
+ const channelSecret = requiredEndpointField(config.channelSecret, 'channelSecret');
162
+ const channelAccessToken = requiredEndpointField(
163
+ config.channelAccessToken,
164
+ 'channelAccessToken',
183
165
  );
184
- const apiBaseUrl = (config.apiBaseUrl ?? entry?.apiBaseUrl ?? 'https://api.line.me').replace(/\/$/, '');
166
+ const webhookPath = normalizeWebhookPath(config.webhookPath ?? '/line/webhook');
167
+ const apiBaseUrl = (config.apiBaseUrl ?? 'https://api.line.me').replace(/\/$/, '');
185
168
  return {
186
169
  context: 'line',
187
170
  id,
@@ -192,6 +175,16 @@ export function resolveLineConfig(config: LineAdapterConfig = {}): ResolvedLineC
192
175
  };
193
176
  }
194
177
 
178
+ function requiredEndpointField(
179
+ value: unknown,
180
+ field: 'id' | 'channelSecret' | 'channelAccessToken',
181
+ ): string {
182
+ if (typeof value !== 'string' || !value.trim()) {
183
+ throw new TypeError(`LINE endpoint requires a non-empty ${field}`);
184
+ }
185
+ return value.trim();
186
+ }
187
+
195
188
  export function normalizeWebhookPath(path: string): string {
196
189
  const trimmed = path.trim() || '/line/webhook';
197
190
  return trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
@@ -1,3 +0,0 @@
1
- import { lineEndpointCommands } from '../../../src/line-endpoint-commands.js';
2
-
3
- export default lineEndpointCommands.add;
@@ -1,3 +0,0 @@
1
- import { lineEndpointCommands } from '../../src/line-endpoint-commands.js';
2
-
3
- export default lineEndpointCommands.list;
@@ -1,3 +0,0 @@
1
- import { lineEndpointCommands } from '../../../src/line-endpoint-commands.js';
2
-
3
- export default lineEndpointCommands.remove;
@@ -1 +0,0 @@
1
- export declare const lineEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;
File without changes