@linxiraos/pi-channels 1.1.7 → 1.1.9
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 +8 -0
- package/package.json +62 -65
- package/src/host.ts +4 -1
- package/src/index.ts +22 -4
- package/src/telegram.ts +17 -4
- package/src/types.ts +6 -1
- package/src/wechat.ts +29 -7
- package/LICENSE +0 -23
- package/THIRD-PARTY-NOTICES.txt +0 -22909
- package/dist/types/channel.d.ts +0 -20
- package/dist/types/feishu.d.ts +0 -29
- package/dist/types/host.d.ts +0 -43
- package/dist/types/index.d.ts +0 -76
- package/dist/types/telegram.d.ts +0 -27
- package/dist/types/types.d.ts +0 -76
- package/dist/types/wechat.d.ts +0 -68
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.1.9] - 2026-09-05
|
|
6
|
+
|
|
7
|
+
- v18.1.10 sync baseline; channel tools remain top-level-session only.
|
|
8
|
+
|
|
9
|
+
## [1.1.8] - 2026-09-04
|
|
10
|
+
|
|
11
|
+
- OMP sync v18.1.2–v18.1.5: channel forwarding task-depth guard and channel tool surface alignment.
|
|
12
|
+
|
|
5
13
|
## [1.1.7] - 2026-09-01
|
|
6
14
|
|
|
7
15
|
- 版本线随 1.1.7 发布对齐(随本体 v18.0.11 同步与主题/网关更新),包内无独立变更。
|
package/package.json
CHANGED
|
@@ -1,67 +1,64 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
},
|
|
65
|
-
"./*.js": "./src/*.ts"
|
|
66
|
-
}
|
|
2
|
+
"exports": {
|
|
3
|
+
"./*.js": "./src/*.ts",
|
|
4
|
+
"./*": {
|
|
5
|
+
"import": "./src/*.ts",
|
|
6
|
+
"types": "./src/*.ts"
|
|
7
|
+
},
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./src/index.ts",
|
|
10
|
+
"types": "./src/index.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"src",
|
|
15
|
+
"README.md",
|
|
16
|
+
"CHANGELOG.md"
|
|
17
|
+
],
|
|
18
|
+
"engines": {
|
|
19
|
+
"bun": ">=1.3.14"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"@linxiraos/pi-ai": "1.1.9"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/bun": "^1.3.14",
|
|
26
|
+
"@linxiraos/pi-ai": "1.1.9"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@larksuiteoapi/node-sdk": "^1.71.1",
|
|
30
|
+
"@linxiraos/pi-utils": "1.1.9"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"test": "bun test --parallel",
|
|
34
|
+
"fmt": "biome format --write .",
|
|
35
|
+
"fix": "biome check --write --unsafe .",
|
|
36
|
+
"lint": "biome lint .",
|
|
37
|
+
"check:types": "tsgo -p tsconfig.json --noEmit",
|
|
38
|
+
"check": "biome check . && bun run check:types"
|
|
39
|
+
},
|
|
40
|
+
"types": "./src/index.ts",
|
|
41
|
+
"main": "./src/index.ts",
|
|
42
|
+
"keywords": [
|
|
43
|
+
"wechat",
|
|
44
|
+
"feishu",
|
|
45
|
+
"telegram",
|
|
46
|
+
"channels",
|
|
47
|
+
"im"
|
|
48
|
+
],
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/Linxira-OS/linxira-zeta/issues"
|
|
51
|
+
},
|
|
52
|
+
"repository": {
|
|
53
|
+
"directory": "packages/channels",
|
|
54
|
+
"url": "git+https://github.com/Linxira-OS/linxira-zeta.git",
|
|
55
|
+
"type": "git"
|
|
56
|
+
},
|
|
57
|
+
"license": "MIT",
|
|
58
|
+
"author": "Can Boluk",
|
|
59
|
+
"homepage": "https://linxira-os.github.io/zeta/",
|
|
60
|
+
"description": "IM channel adapters for Zeta (WeChat / Feishu / Telegram)",
|
|
61
|
+
"type": "module",
|
|
62
|
+
"version": "1.1.9",
|
|
63
|
+
"name": "@linxiraos/pi-channels"
|
|
67
64
|
}
|
package/src/host.ts
CHANGED
|
@@ -87,7 +87,10 @@ export class ChannelHost {
|
|
|
87
87
|
// Optional allowlist: when configured, only listed peers may reach the
|
|
88
88
|
// agent (empty allowlist = everyone, unchanged behavior).
|
|
89
89
|
if (this.#allowedPeers.length > 0 && !this.#allowedPeers.includes(peer)) {
|
|
90
|
-
logger.debug("Channel message from non-allowed peer dropped", {
|
|
90
|
+
logger.debug("Channel message from non-allowed peer dropped", {
|
|
91
|
+
channel: channelId,
|
|
92
|
+
peer,
|
|
93
|
+
});
|
|
91
94
|
return;
|
|
92
95
|
}
|
|
93
96
|
const agentId = this.#session.getAgentId();
|
package/src/index.ts
CHANGED
|
@@ -20,11 +20,29 @@ import type { ChannelSession, ChannelsWebConfig } from "./types";
|
|
|
20
20
|
import { WeChatChannel, type WeChatQrStatus } from "./wechat";
|
|
21
21
|
|
|
22
22
|
export type { ChannelId, ChatChannel, ChatImage } from "./channel";
|
|
23
|
-
export {
|
|
23
|
+
export {
|
|
24
|
+
FeishuChannel,
|
|
25
|
+
type FeishuChannelOptions,
|
|
26
|
+
type FeishuInboundHandler,
|
|
27
|
+
} from "./feishu";
|
|
24
28
|
export { ChannelHost } from "./host";
|
|
25
|
-
export {
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
export {
|
|
30
|
+
TelegramChannel,
|
|
31
|
+
type TelegramChannelOptions,
|
|
32
|
+
type TelegramInboundHandler,
|
|
33
|
+
} from "./telegram";
|
|
34
|
+
export type {
|
|
35
|
+
ChannelSession,
|
|
36
|
+
ChannelSessionEvent,
|
|
37
|
+
ChannelsWebConfig,
|
|
38
|
+
IrcMessage,
|
|
39
|
+
} from "./types";
|
|
40
|
+
export {
|
|
41
|
+
WeChatChannel,
|
|
42
|
+
type WeChatChannelOptions,
|
|
43
|
+
type WeChatInboundHandler,
|
|
44
|
+
type WeChatQrStatus,
|
|
45
|
+
} from "./wechat";
|
|
28
46
|
|
|
29
47
|
/**
|
|
30
48
|
* Module-level QR-login state bridge between the running channel and the web
|
package/src/telegram.ts
CHANGED
|
@@ -66,7 +66,10 @@ export class TelegramChannel implements ChatChannel {
|
|
|
66
66
|
try {
|
|
67
67
|
const url = `${this.#apiUrl("getUpdates")}?timeout=${POLL_TIMEOUT_SECONDS}&offset=${this.#offset + 1}`;
|
|
68
68
|
const res = await this.#fetch(url, {
|
|
69
|
-
signal: AbortSignal.any([
|
|
69
|
+
signal: AbortSignal.any([
|
|
70
|
+
this.#abort?.signal ?? AbortSignal.abort(),
|
|
71
|
+
AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
72
|
+
]),
|
|
70
73
|
});
|
|
71
74
|
if (res.status === 401) {
|
|
72
75
|
logger.error("Telegram bot token rejected (HTTP 401); polling stopped");
|
|
@@ -81,7 +84,11 @@ export class TelegramChannel implements ChatChannel {
|
|
|
81
84
|
ok?: boolean;
|
|
82
85
|
result?: Array<{
|
|
83
86
|
update_id?: number;
|
|
84
|
-
message?: {
|
|
87
|
+
message?: {
|
|
88
|
+
message_id?: number;
|
|
89
|
+
chat?: { id?: number };
|
|
90
|
+
text?: string;
|
|
91
|
+
};
|
|
85
92
|
}>;
|
|
86
93
|
};
|
|
87
94
|
for (const update of data.result ?? []) {
|
|
@@ -92,7 +99,10 @@ export class TelegramChannel implements ChatChannel {
|
|
|
92
99
|
const text = update.message?.text;
|
|
93
100
|
if (chatId === undefined || typeof text !== "string" || text === "") continue;
|
|
94
101
|
if (text.startsWith("/")) continue;
|
|
95
|
-
logger.debug("Telegram message received", {
|
|
102
|
+
logger.debug("Telegram message received", {
|
|
103
|
+
chatId,
|
|
104
|
+
length: text.length,
|
|
105
|
+
});
|
|
96
106
|
this.#onMessage(String(chatId), text, String(update.message?.message_id ?? ""));
|
|
97
107
|
}
|
|
98
108
|
} catch (error) {
|
|
@@ -122,7 +132,10 @@ export class TelegramChannel implements ChatChannel {
|
|
|
122
132
|
form.append("chat_id", to);
|
|
123
133
|
form.append("photo", new Blob([image.data], { type: image.mime }), "plan.png");
|
|
124
134
|
if (caption && caption !== "") form.append("caption", caption);
|
|
125
|
-
const res = await this.#fetch(this.#apiUrl("sendPhoto"), {
|
|
135
|
+
const res = await this.#fetch(this.#apiUrl("sendPhoto"), {
|
|
136
|
+
method: "POST",
|
|
137
|
+
body: form,
|
|
138
|
+
});
|
|
126
139
|
if (!res.ok) {
|
|
127
140
|
throw new Error(`Telegram sendPhoto failed (HTTP ${res.status}): ${await res.text()}`);
|
|
128
141
|
}
|
package/src/types.ts
CHANGED
|
@@ -61,7 +61,12 @@ export interface ChannelsWebConfig {
|
|
|
61
61
|
endpoint?: string;
|
|
62
62
|
peerTokens?: Record<string, string>;
|
|
63
63
|
};
|
|
64
|
-
feishu: {
|
|
64
|
+
feishu: {
|
|
65
|
+
enabled: boolean;
|
|
66
|
+
appId?: string;
|
|
67
|
+
appSecret?: string;
|
|
68
|
+
domain?: "feishu" | "lark";
|
|
69
|
+
};
|
|
65
70
|
telegram: { enabled: boolean; botToken?: string };
|
|
66
71
|
allowedPeers?: string[];
|
|
67
72
|
};
|
package/src/wechat.ts
CHANGED
|
@@ -167,7 +167,10 @@ export class WeChatChannel implements ChatChannel {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
#baseInfo(): Record<string, string> {
|
|
170
|
-
return {
|
|
170
|
+
return {
|
|
171
|
+
channel_version: CHANNEL_VERSION,
|
|
172
|
+
bot_agent: "zeta-WeChat-ClawBot/1.0.0",
|
|
173
|
+
};
|
|
171
174
|
}
|
|
172
175
|
|
|
173
176
|
async #apiGet(path: string): Promise<Record<string, unknown>> {
|
|
@@ -236,7 +239,9 @@ export class WeChatChannel implements ChatChannel {
|
|
|
236
239
|
|
|
237
240
|
while (this.#started && !this.#abort?.signal.aborted) {
|
|
238
241
|
try {
|
|
239
|
-
const result = await this.#apiPost("api/v1/wechat/qrcode/status", {
|
|
242
|
+
const result = await this.#apiPost("api/v1/wechat/qrcode/status", {
|
|
243
|
+
qrcode: token,
|
|
244
|
+
});
|
|
240
245
|
const body = (result.data as Record<string, unknown> | undefined) ?? result;
|
|
241
246
|
const status = typeof body.status === "string" ? body.status : "";
|
|
242
247
|
if (status === "confirmed") {
|
|
@@ -274,13 +279,23 @@ export class WeChatChannel implements ChatChannel {
|
|
|
274
279
|
await config.set("channels.wechat.ilinkUserId", ilinkUserId);
|
|
275
280
|
}
|
|
276
281
|
}
|
|
277
|
-
this.#options.onQrCode?.({
|
|
278
|
-
|
|
282
|
+
this.#options.onQrCode?.({
|
|
283
|
+
qrcode: token,
|
|
284
|
+
qrcodeUrl,
|
|
285
|
+
status: "confirmed",
|
|
286
|
+
});
|
|
287
|
+
logger.info("WeChat channel logged in (v1 API)", {
|
|
288
|
+
baseUrl: this.#baseUrl,
|
|
289
|
+
});
|
|
279
290
|
return;
|
|
280
291
|
}
|
|
281
292
|
if (status === "expired") {
|
|
282
293
|
logger.warn("WeChat QR code expired; fetching a fresh one");
|
|
283
|
-
this.#options.onQrCode?.({
|
|
294
|
+
this.#options.onQrCode?.({
|
|
295
|
+
qrcode: token,
|
|
296
|
+
qrcodeUrl,
|
|
297
|
+
status: "expired",
|
|
298
|
+
});
|
|
284
299
|
return await this.#loginFlowV1();
|
|
285
300
|
}
|
|
286
301
|
this.#options.onQrCode?.({
|
|
@@ -405,7 +420,10 @@ export class WeChatChannel implements ChatChannel {
|
|
|
405
420
|
}
|
|
406
421
|
const textItem = (msg.item_list ?? []).find(item => item.type === 1)?.text_item?.text;
|
|
407
422
|
if (typeof textItem !== "string" || textItem === "") continue;
|
|
408
|
-
logger.debug("WeChat message received", {
|
|
423
|
+
logger.debug("WeChat message received", {
|
|
424
|
+
from,
|
|
425
|
+
length: textItem.length,
|
|
426
|
+
});
|
|
409
427
|
this.#onMessage(from, textItem, String(msg.to_user_id ?? ""));
|
|
410
428
|
}
|
|
411
429
|
} catch (error) {
|
|
@@ -534,7 +552,11 @@ export class WeChatChannel implements ChatChannel {
|
|
|
534
552
|
}
|
|
535
553
|
|
|
536
554
|
// 2. PUT the encrypted payload to the CDN.
|
|
537
|
-
const putRes = await this.#fetch(uploadUrl, {
|
|
555
|
+
const putRes = await this.#fetch(uploadUrl, {
|
|
556
|
+
method: "PUT",
|
|
557
|
+
body: encrypted,
|
|
558
|
+
signal: this.#abort?.signal,
|
|
559
|
+
});
|
|
538
560
|
if (!putRes.ok) {
|
|
539
561
|
throw new Error(`WeChat CDN upload failed (HTTP ${putRes.status})`);
|
|
540
562
|
}
|
package/LICENSE
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Mario Zechner
|
|
4
|
-
Copyright (c) 2025-2026 Can Bölük
|
|
5
|
-
Copyright (c) 2026 Stencil Labs, Inc.
|
|
6
|
-
|
|
7
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
-
in the Software without restriction, including without limitation the rights
|
|
10
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
-
furnished to do so, subject to the following conditions:
|
|
13
|
-
|
|
14
|
-
The above copyright notice and this permission notice shall be included in all
|
|
15
|
-
copies or substantial portions of the Software.
|
|
16
|
-
|
|
17
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
-
SOFTWARE.
|