botmux 2.60.1 → 2.62.0
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/README.en.md +4 -4
- package/README.md +5 -5
- package/dist/bot-registry.d.ts +24 -0
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +30 -0
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +28 -31
- package/dist/cli.js.map +1 -1
- package/dist/core/command-discovery.d.ts +24 -0
- package/dist/core/command-discovery.d.ts.map +1 -0
- package/dist/core/command-discovery.js +201 -0
- package/dist/core/command-discovery.js.map +1 -0
- package/dist/core/command-handler.d.ts +9 -0
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +59 -10
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +2 -1
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dashboard-rows.d.ts +2 -1
- package/dist/core/dashboard-rows.d.ts.map +1 -1
- package/dist/core/dashboard-rows.js +6 -4
- package/dist/core/dashboard-rows.js.map +1 -1
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +3 -0
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +5 -4
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/bot-onboarding.js +10 -13
- package/dist/dashboard/bot-onboarding.js.map +1 -1
- package/dist/dashboard/web/groups.d.ts.map +1 -1
- package/dist/dashboard/web/groups.js +6 -1
- package/dist/dashboard/web/groups.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +12 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +12 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts +17 -0
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +84 -0
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +7 -5
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +2 -1
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +15 -9
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/lark-hosts.d.ts +44 -0
- package/dist/im/lark/lark-hosts.d.ts.map +1 -0
- package/dist/im/lark/lark-hosts.js +49 -0
- package/dist/im/lark/lark-hosts.js.map +1 -0
- package/dist/setup/verify-permissions.d.ts +2 -1
- package/dist/setup/verify-permissions.d.ts.map +1 -1
- package/dist/setup/verify-permissions.js +5 -8
- package/dist/setup/verify-permissions.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/lark-upload.d.ts +2 -1
- package/dist/utils/lark-upload.d.ts.map +1 -1
- package/dist/utils/lark-upload.js +11 -7
- package/dist/utils/lark-upload.js.map +1 -1
- package/dist/utils/user-token.d.ts +12 -4
- package/dist/utils/user-token.d.ts.map +1 -1
- package/dist/utils/user-token.js +64 -25
- package/dist/utils/user-token.js.map +1 -1
- package/dist/worker.js +4 -1
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
package/dist/utils/user-token.js
CHANGED
|
@@ -13,9 +13,19 @@ import { join, dirname } from 'node:path';
|
|
|
13
13
|
import { homedir } from 'node:os';
|
|
14
14
|
import { randomBytes } from 'node:crypto';
|
|
15
15
|
import { logger } from './logger.js';
|
|
16
|
+
import { larkHosts } from '../im/lark/lark-hosts.js';
|
|
16
17
|
// ─── Token paths ──────────────────────────────────────────────────────────────
|
|
17
|
-
const
|
|
18
|
+
const TOKEN_DIR = join(homedir(), '.botmux', 'data');
|
|
19
|
+
/** 旧版单文件(升级前都是单 feishu bot)。仅作向后兼容读取,不再写入。 */
|
|
20
|
+
const LEGACY_TOKEN_PATH = join(TOKEN_DIR, 'user-token.json');
|
|
18
21
|
const BUFFER_MS = 60_000; // 60s safety margin before expiry
|
|
22
|
+
/**
|
|
23
|
+
* Per-app token 文件:`~/.botmux/data/user-token-<appId>.json`。
|
|
24
|
+
* 一台机器混挂 Feishu + Lark 多 bot 时,各自的 User Token 互不覆盖、互不串用。
|
|
25
|
+
*/
|
|
26
|
+
function tokenPathForApp(appId) {
|
|
27
|
+
return join(TOKEN_DIR, `user-token-${appId}.json`);
|
|
28
|
+
}
|
|
19
29
|
const pendingLogins = new Map(); // keyed by state
|
|
20
30
|
// ─── Token I/O ────────────────────────────────────────────────────────────────
|
|
21
31
|
function loadTokenFromPath(path) {
|
|
@@ -26,7 +36,8 @@ function loadTokenFromPath(path) {
|
|
|
26
36
|
return null;
|
|
27
37
|
}
|
|
28
38
|
}
|
|
29
|
-
function
|
|
39
|
+
function saveTokenForApp(token, appId) {
|
|
40
|
+
const path = tokenPathForApp(appId);
|
|
30
41
|
const dir = dirname(path);
|
|
31
42
|
if (!existsSync(dir))
|
|
32
43
|
mkdirSync(dir, { recursive: true });
|
|
@@ -37,17 +48,39 @@ function isValid(isoDate) {
|
|
|
37
48
|
return false;
|
|
38
49
|
return Date.now() + BUFFER_MS < new Date(isoDate).getTime();
|
|
39
50
|
}
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
/**
|
|
52
|
+
* 一个落盘 token 是否真的属于本次请求的 (appId, brand)。除文件名外,**再校验文件
|
|
53
|
+
* 内容里的 appId/brand**(Codex review hardening)——防止 per-app 文件被改名 / 手动
|
|
54
|
+
* 误编辑 / 旧迁移残留导致拿错域的 token:
|
|
55
|
+
* - 未标 appId(升级前的旧单文件)→ 仅当请求 feishu 时认领(彼时只有 feishu 单 bot)
|
|
56
|
+
* - 标了 appId → 必须同 appId;若也标了 brand,则必须同 brand
|
|
57
|
+
*/
|
|
58
|
+
function tokenMatches(t, appId, brand) {
|
|
59
|
+
if (t.appId === undefined)
|
|
60
|
+
return brand === 'feishu';
|
|
61
|
+
if (t.appId !== appId)
|
|
62
|
+
return false;
|
|
63
|
+
if (t.brand !== undefined && t.brand !== brand)
|
|
64
|
+
return false;
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 取指定 app 的 token。优先 per-app 文件,其次回退旧的单文件;两者都过
|
|
69
|
+
* {@link tokenMatches} 校验(文件名 + 内容双重把关),不匹配一律视为无 token。
|
|
70
|
+
*/
|
|
71
|
+
function loadTokenForApp(appId, brand) {
|
|
72
|
+
const perApp = loadTokenFromPath(tokenPathForApp(appId));
|
|
73
|
+
if (perApp && tokenMatches(perApp, appId, brand))
|
|
74
|
+
return { token: perApp, source: 'botmux' };
|
|
75
|
+
const legacy = loadTokenFromPath(LEGACY_TOKEN_PATH);
|
|
76
|
+
if (legacy && tokenMatches(legacy, appId, brand))
|
|
77
|
+
return { token: legacy, source: 'botmux(legacy)' };
|
|
45
78
|
return null;
|
|
46
79
|
}
|
|
47
80
|
// ─── Token refresh ────────────────────────────────────────────────────────────
|
|
48
|
-
async function refreshToken(token, appId, appSecret) {
|
|
81
|
+
async function refreshToken(token, appId, appSecret, brand = 'feishu') {
|
|
49
82
|
try {
|
|
50
|
-
const res = await fetch(
|
|
83
|
+
const res = await fetch(`${larkHosts(brand).openApi}/open-apis/authen/v2/oauth/token`, {
|
|
51
84
|
method: 'POST',
|
|
52
85
|
headers: { 'Content-Type': 'application/json' },
|
|
53
86
|
body: JSON.stringify({
|
|
@@ -72,10 +105,12 @@ async function refreshToken(token, appId, appSecret) {
|
|
|
72
105
|
? new Date(now.getTime() + data.refresh_token_expires_in * 1000).toISOString()
|
|
73
106
|
: token.refresh_expires_at,
|
|
74
107
|
scope: data.scope || token.scope,
|
|
108
|
+
appId,
|
|
109
|
+
brand,
|
|
75
110
|
};
|
|
76
|
-
//
|
|
111
|
+
// Write to this app's own token file (per-app, brand-stamped)
|
|
77
112
|
try {
|
|
78
|
-
|
|
113
|
+
saveTokenForApp(updated, appId);
|
|
79
114
|
}
|
|
80
115
|
catch { /* best-effort */ }
|
|
81
116
|
logger.info('[user-token] Refreshed User Access Token');
|
|
@@ -91,13 +126,13 @@ async function refreshToken(token, appId, appSecret) {
|
|
|
91
126
|
* Resolve a valid User Access Token.
|
|
92
127
|
* Returns access_token string, or null if unavailable.
|
|
93
128
|
*/
|
|
94
|
-
export async function resolveUserToken(appId, appSecret) {
|
|
95
|
-
// 1. Environment variable
|
|
129
|
+
export async function resolveUserToken(appId, appSecret, brand = 'feishu') {
|
|
130
|
+
// 1. Environment variable (explicit global override)
|
|
96
131
|
const envToken = process.env.FEISHU_USER_ACCESS_TOKEN;
|
|
97
132
|
if (envToken)
|
|
98
133
|
return envToken;
|
|
99
|
-
// 2.
|
|
100
|
-
const loaded =
|
|
134
|
+
// 2. Per-app token file (mismatched / 别的 bot 的 token → null,调用方提示 /login)
|
|
135
|
+
const loaded = loadTokenForApp(appId, brand);
|
|
101
136
|
if (!loaded)
|
|
102
137
|
return null;
|
|
103
138
|
const { token } = loaded;
|
|
@@ -106,7 +141,7 @@ export async function resolveUserToken(appId, appSecret) {
|
|
|
106
141
|
}
|
|
107
142
|
// access_token expired — try refresh
|
|
108
143
|
if (isValid(token.refresh_expires_at) || (!token.refresh_expires_at && token.refresh_token)) {
|
|
109
|
-
const refreshed = await refreshToken(token, appId, appSecret);
|
|
144
|
+
const refreshed = await refreshToken(token, appId, appSecret, brand);
|
|
110
145
|
if (refreshed)
|
|
111
146
|
return refreshed.access_token;
|
|
112
147
|
}
|
|
@@ -114,7 +149,6 @@ export async function resolveUserToken(appId, appSecret) {
|
|
|
114
149
|
return null;
|
|
115
150
|
}
|
|
116
151
|
// ─── Public API: OAuth login flow ─────────────────────────────────────────────
|
|
117
|
-
const FEISHU_AUTH_URL = 'https://accounts.feishu.cn/open-apis/authen/v1/authorize';
|
|
118
152
|
const DEFAULT_PORT = 9768;
|
|
119
153
|
const DEFAULT_SCOPES = [
|
|
120
154
|
'im:message:readonly',
|
|
@@ -125,7 +159,7 @@ const DEFAULT_SCOPES = [
|
|
|
125
159
|
* Generate an OAuth authorization URL. Returns the URL and stores pending state.
|
|
126
160
|
* Called by /login command handler.
|
|
127
161
|
*/
|
|
128
|
-
export function generateAuthUrl(appId, appSecret) {
|
|
162
|
+
export function generateAuthUrl(appId, appSecret, brand = 'feishu') {
|
|
129
163
|
const state = randomBytes(32).toString('hex');
|
|
130
164
|
const redirectUri = `http://127.0.0.1:${DEFAULT_PORT}/callback`;
|
|
131
165
|
const params = new URLSearchParams({
|
|
@@ -135,13 +169,15 @@ export function generateAuthUrl(appId, appSecret) {
|
|
|
135
169
|
state,
|
|
136
170
|
scope: DEFAULT_SCOPES,
|
|
137
171
|
});
|
|
138
|
-
|
|
172
|
+
// authorize 走 accounts host(feishu: accounts.feishu.cn / lark: accounts.larksuite.com)
|
|
173
|
+
const authUrl = `${larkHosts(brand).accounts}/open-apis/authen/v1/authorize?${params.toString()}`;
|
|
139
174
|
// Store pending state for verification (expires in 5 minutes)
|
|
140
175
|
pendingLogins.set(state, {
|
|
141
176
|
state,
|
|
142
177
|
redirectUri,
|
|
143
178
|
appId,
|
|
144
179
|
appSecret,
|
|
180
|
+
brand,
|
|
145
181
|
createdAt: Date.now(),
|
|
146
182
|
});
|
|
147
183
|
// Clean up stale pending logins
|
|
@@ -170,7 +206,7 @@ export async function handleCallbackUrl(url) {
|
|
|
170
206
|
pendingLogins.delete(state);
|
|
171
207
|
// Exchange code for token
|
|
172
208
|
try {
|
|
173
|
-
const res = await fetch(
|
|
209
|
+
const res = await fetch(`${larkHosts(pending.brand).openApi}/open-apis/authen/v2/oauth/token`, {
|
|
174
210
|
method: 'POST',
|
|
175
211
|
headers: { 'Content-Type': 'application/json' },
|
|
176
212
|
body: JSON.stringify({
|
|
@@ -198,9 +234,11 @@ export async function handleCallbackUrl(url) {
|
|
|
198
234
|
? new Date(now.getTime() + data.refresh_token_expires_in * 1000).toISOString()
|
|
199
235
|
: '',
|
|
200
236
|
scope: data.scope,
|
|
237
|
+
appId: pending.appId,
|
|
238
|
+
brand: pending.brand,
|
|
201
239
|
};
|
|
202
|
-
|
|
203
|
-
logger.info(
|
|
240
|
+
saveTokenForApp(token, pending.appId);
|
|
241
|
+
logger.info(`[user-token] OAuth login successful, token saved for ${pending.appId}`);
|
|
204
242
|
const expiresAt = new Date(token.expires_at).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
|
|
205
243
|
return `✅ 授权成功!Token 已保存。\n有效期至 ${expiresAt},过期后自动刷新。`;
|
|
206
244
|
}
|
|
@@ -215,10 +253,11 @@ export function isCallbackUrl(text) {
|
|
|
215
253
|
return /^https?:\/\/127\.0\.0\.1[:/].*[?&]code=/.test(text.trim());
|
|
216
254
|
}
|
|
217
255
|
/**
|
|
218
|
-
* Get current token status for /login status display.
|
|
256
|
+
* Get current token status for /login status display. Per-app: reports the
|
|
257
|
+
* token belonging to this bot (appId/brand), not whatever was last written.
|
|
219
258
|
*/
|
|
220
|
-
export function getTokenStatus() {
|
|
221
|
-
const loaded =
|
|
259
|
+
export function getTokenStatus(appId, brand = 'feishu') {
|
|
260
|
+
const loaded = loadTokenForApp(appId, brand);
|
|
222
261
|
if (!loaded)
|
|
223
262
|
return '未登录(无 User Token)';
|
|
224
263
|
const { token, source } = loaded;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-token.js","sourceRoot":"","sources":["../../src/utils/user-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"user-token.js","sourceRoot":"","sources":["../../src/utils/user-token.ts"],"names":[],"mappings":"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"}
|
package/dist/worker.js
CHANGED
|
@@ -2175,6 +2175,7 @@ let pendingShotTimer = null;
|
|
|
2175
2175
|
let lastShotHash = '';
|
|
2176
2176
|
let larkAppIdForUpload = '';
|
|
2177
2177
|
let larkAppSecretForUpload = '';
|
|
2178
|
+
let larkBrandForUpload = 'feishu';
|
|
2178
2179
|
function startScreenshotLoop() {
|
|
2179
2180
|
stopScreenshotLoop();
|
|
2180
2181
|
screenshotTimer = setInterval(() => { void captureAndUpload(); }, SCREENSHOT_INTERVAL_MS);
|
|
@@ -2288,7 +2289,7 @@ async function captureAndUpload() {
|
|
|
2288
2289
|
}
|
|
2289
2290
|
let imageKey;
|
|
2290
2291
|
try {
|
|
2291
|
-
imageKey = await uploadImageBuffer(larkAppIdForUpload, larkAppSecretForUpload, png);
|
|
2292
|
+
imageKey = await uploadImageBuffer(larkAppIdForUpload, larkAppSecretForUpload, png, larkBrandForUpload);
|
|
2292
2293
|
}
|
|
2293
2294
|
catch (err) {
|
|
2294
2295
|
logError(`Screenshot upload failed: ${err?.message ?? err}`);
|
|
@@ -4181,6 +4182,8 @@ process.on('message', async (raw) => {
|
|
|
4181
4182
|
// Capture credentials for direct image upload from worker
|
|
4182
4183
|
larkAppIdForUpload = msg.larkAppId;
|
|
4183
4184
|
larkAppSecretForUpload = msg.larkAppSecret;
|
|
4185
|
+
// brand 决定截图上传打哪个域(feishu / larksuite)。缺省 feishu。
|
|
4186
|
+
larkBrandForUpload = msg.brand === 'lark' ? 'lark' : 'feishu';
|
|
4184
4187
|
// Resolve render dimensions BEFORE startScreenUpdates() — the
|
|
4185
4188
|
// headless xterm and PNG canvas need to know the source pane size
|
|
4186
4189
|
// up-front. Setting them later (after the renderer was built at
|