@zhin.js/adapter-line 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.
- package/CHANGELOG.md +93 -0
- package/README.md +8 -8
- package/adapters/{line.js → line/index.js} +6 -6
- package/adapters/{line.ts → line/index.ts} +9 -9
- package/agents/line/agent.json +20 -0
- package/agents/line/boundaries.md +3 -0
- package/agents/line/conventions.md +3 -0
- package/{agent/skills/line.md → agents/line/skills/line/SKILL.md} +3 -0
- package/agents/line/skills/line/tools/get_group_members/index.js +16 -0
- package/{agent/tools/get_group_members.ts → agents/line/skills/line/tools/get_group_members/index.ts} +1 -1
- package/agents/line/skills/line/tools/get_profile/index.js +16 -0
- package/{agent/tools/get_profile.ts → agents/line/skills/line/tools/get_profile/index.ts} +1 -1
- package/agents/line/system.md +3 -0
- package/commands/{endpoint/add/[id].js → line/endpoint/add/[id]/index.js} +1 -1
- package/commands/line/endpoint/add/[id]/index.ts +3 -0
- package/{lib/line-endpoint-commands.js → commands/line/endpoint/definition.js} +4 -3
- package/{src/line-endpoint-commands.ts → commands/line/endpoint/definition.ts} +3 -3
- package/commands/{endpoint/list.js → line/endpoint/list/index.js} +1 -1
- package/commands/line/endpoint/list/index.ts +3 -0
- package/commands/{endpoint/remove/[id].js → line/endpoint/remove/[id]/index.js} +1 -1
- package/commands/line/endpoint/remove/[id]/index.ts +3 -0
- package/lib/index.d.ts +1 -1
- package/lib/line-runtime-state.js +1 -1
- package/lib/protocol.d.ts +7 -11
- package/lib/protocol.js +13 -18
- package/package.json +32 -20
- package/plugin.js +1 -1
- package/schema.json +11 -1
- package/src/index.ts +1 -1
- package/src/line-runtime-state.ts +1 -1
- package/src/protocol.ts +24 -31
- package/commands/endpoint/add/[id].ts +0 -3
- package/commands/endpoint/list.ts +0 -3
- package/commands/endpoint/remove/[id].ts +0 -3
- package/lib/line-endpoint-commands.d.ts +0 -1
- /package/{agent/PERMITS.md → PERMITS.md} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,98 @@
|
|
|
1
1
|
# @zhin.js/adapter-line
|
|
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
|
+
- 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.
|
|
21
|
+
- 4380cf9: Colocate adapter command definitions and Agent Skill handlers with their owning capabilities, and provide a shared validated platform permission constructor.
|
|
22
|
+
- 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.
|
|
23
|
+
- 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.
|
|
24
|
+
- 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.
|
|
25
|
+
- Updated dependencies [c861789]
|
|
26
|
+
- Updated dependencies [1414ccb]
|
|
27
|
+
- Updated dependencies [743d470]
|
|
28
|
+
- Updated dependencies [62dee52]
|
|
29
|
+
- Updated dependencies [cd54131]
|
|
30
|
+
- Updated dependencies [244e475]
|
|
31
|
+
- Updated dependencies [a9e4a40]
|
|
32
|
+
- Updated dependencies [5855db7]
|
|
33
|
+
- Updated dependencies [ec921d2]
|
|
34
|
+
- Updated dependencies [8740059]
|
|
35
|
+
- Updated dependencies [63d1f7a]
|
|
36
|
+
- Updated dependencies [25a845a]
|
|
37
|
+
- Updated dependencies [103f2c3]
|
|
38
|
+
- Updated dependencies [9110ab8]
|
|
39
|
+
- Updated dependencies [cd2a888]
|
|
40
|
+
- Updated dependencies [eb3227a]
|
|
41
|
+
- Updated dependencies [b853dba]
|
|
42
|
+
- Updated dependencies [e561309]
|
|
43
|
+
- Updated dependencies [d4c6175]
|
|
44
|
+
- Updated dependencies [7a0e1ca]
|
|
45
|
+
- Updated dependencies [103b5d3]
|
|
46
|
+
- Updated dependencies [5a7a7f7]
|
|
47
|
+
- Updated dependencies [b076eae]
|
|
48
|
+
- Updated dependencies [535fed1]
|
|
49
|
+
- Updated dependencies [73a24b7]
|
|
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
|
+
|
|
88
|
+
## 1.1.1
|
|
89
|
+
|
|
90
|
+
### Patch Changes
|
|
91
|
+
|
|
92
|
+
- Updated dependencies [769e67f]
|
|
93
|
+
- @zhin.js/adapter@1.1.13
|
|
94
|
+
- @zhin.js/core@1.1.36
|
|
95
|
+
|
|
3
96
|
## 1.1.0
|
|
4
97
|
|
|
5
98
|
### 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]`):`
|
|
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
|
-
-
|
|
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` |
|
|
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 词汇 | `
|
|
90
|
-
| 平台工具(2 个) | `
|
|
91
|
-
| 技能说明 | `
|
|
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 "
|
|
8
|
-
import { resolveLineConfig, } from "
|
|
9
|
-
import { lineRuntimeStateToken } from "
|
|
10
|
-
export { LineEndpoint } from "
|
|
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
|
|
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 '
|
|
6
|
+
import { LineEndpoint } from '../../src/endpoint.js';
|
|
7
7
|
import {
|
|
8
8
|
resolveLineConfig,
|
|
9
|
-
type
|
|
10
|
-
} from '
|
|
11
|
-
import { lineRuntimeStateToken } from '
|
|
9
|
+
type LineEndpointConfig,
|
|
10
|
+
} from '../../src/protocol.js';
|
|
11
|
+
import { lineRuntimeStateToken } from '../../src/line-runtime-state.js';
|
|
12
12
|
|
|
13
|
-
export { LineEndpoint } from '
|
|
14
|
-
export type { LineEndpointOptions, LineFetch } from '
|
|
13
|
+
export { LineEndpoint } from '../../src/endpoint.js';
|
|
14
|
+
export type { LineEndpointOptions, LineFetch } from '../../src/endpoint.js';
|
|
15
15
|
|
|
16
|
-
export default defineAdapter<
|
|
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
|
|
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,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
|
+
});
|
|
@@ -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,10 +1,11 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
1
2
|
/**
|
|
2
|
-
* `line
|
|
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
|
|
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
|
|
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 '
|
|
7
|
+
import { lineRuntimeStateToken } from '../../../src/line-runtime-state.js';
|
|
8
8
|
|
|
9
9
|
export const lineEndpointCommands = createEndpointCommands({
|
|
10
10
|
adapterKey: 'line',
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { formatInboundContent, formatOutboundMessages, generateMessageId, isMessageEvent, isPostbackEvent, isValidLineRecipientId, normalizeWebhookPath, readTextBody, resolveChannel, resolveLineConfig, verifySignature, type
|
|
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
|
|
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
|
|
7
|
-
/**
|
|
8
|
-
export interface
|
|
9
|
-
readonly id
|
|
10
|
-
readonly channelSecret
|
|
11
|
-
readonly channelAccessToken
|
|
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
|
|
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/
|
|
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
|
|
11
|
-
const channelSecret = config.channelSecret
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
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.
|
|
3
|
+
"version": "1.1.2",
|
|
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.
|
|
36
|
-
"@zhin.js/
|
|
37
|
-
"@zhin.js/
|
|
38
|
-
"@zhin.js/
|
|
39
|
-
"@zhin.js/
|
|
40
|
-
"@zhin.js/
|
|
35
|
+
"@zhin.js/adapter": "1.1.14",
|
|
36
|
+
"@zhin.js/agent-feature": "1.1.1",
|
|
37
|
+
"@zhin.js/core": "1.1.37",
|
|
38
|
+
"@zhin.js/feature-kit": "1.1.1",
|
|
39
|
+
"@zhin.js/host-http": "1.1.1",
|
|
40
|
+
"@zhin.js/im-contract": "1.1.1",
|
|
41
|
+
"@zhin.js/logger": "1.1.1",
|
|
42
|
+
"@zhin.js/skill": "1.1.1",
|
|
43
|
+
"@zhin.js/tool": "1.1.1"
|
|
41
44
|
},
|
|
42
45
|
"peerDependencies": {
|
|
43
46
|
"zod": "^4.0.0",
|
|
44
|
-
"@zhin.js/adapter": "^1.1.
|
|
45
|
-
"@zhin.js/
|
|
46
|
-
"@zhin.js/
|
|
47
|
-
"@zhin.js/
|
|
48
|
-
"
|
|
49
|
-
"zhin.js": "^1.1.0"
|
|
47
|
+
"@zhin.js/adapter": "^1.1.14",
|
|
48
|
+
"@zhin.js/command": "^1.1.1",
|
|
49
|
+
"@zhin.js/core": "^1.1.37",
|
|
50
|
+
"@zhin.js/host-http": "^1.1.1",
|
|
51
|
+
"zhin.js": "^1.1.2"
|
|
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
|
-
"
|
|
71
|
-
"zhin.js": "1.1.0"
|
|
69
|
+
"zhin.js": "1.1.2"
|
|
72
70
|
},
|
|
73
71
|
"files": [
|
|
74
72
|
"adapters",
|
|
@@ -77,9 +75,11 @@
|
|
|
77
75
|
"schema.json",
|
|
78
76
|
"src",
|
|
79
77
|
"lib",
|
|
80
|
-
"
|
|
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
|
|
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":
|
|
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LINE 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
|
|
3
|
-
* 由 plugin.ts setup() provide,adapter create 与 `line
|
|
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/
|
|
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
|
-
/**
|
|
15
|
-
export interface
|
|
16
|
-
readonly id
|
|
17
|
-
readonly channelSecret
|
|
18
|
-
readonly channelAccessToken
|
|
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:
|
|
165
|
-
const
|
|
166
|
-
const channelSecret = config.channelSecret
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
|
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 +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
|