@wu529778790/open-im 1.10.6-beta.0 → 1.10.6-beta.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/README.md +3 -5
- package/README.zh-CN.md +3 -5
- package/dist/config/types.d.ts +1 -1
- package/dist/config-web-page-i18n.d.ts +4 -2
- package/dist/config-web-page-i18n.js +4 -2
- package/dist/config-web.js +20 -17
- package/dist/config.js +41 -23
- package/dist/setup.js +37 -35
- package/package.json +1 -1
- package/web/dist/assets/index-B-oVSMUp.js +57 -0
- package/web/dist/index.html +1 -1
- package/web/dist/assets/index-BuYsYEMc.js +0 -57
package/README.md
CHANGED
|
@@ -62,13 +62,12 @@ Session state is stored in **`~/.open-im/data/sessions.json`** (per user, not IM
|
|
|
62
62
|
|
|
63
63
|
### Per-platform AI
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
Set **`platforms.<name>.aiCommand`** per channel (`claude` / `codex` / `codebuddy`). If unset, the process **`AI_COMMAND`** env var is used when present; otherwise it defaults to **`claude`**.
|
|
66
66
|
|
|
67
67
|
```json
|
|
68
68
|
{
|
|
69
|
-
"aiCommand": "claude",
|
|
70
69
|
"platforms": {
|
|
71
|
-
"telegram": { "enabled": true, "aiCommand": "codex" }
|
|
70
|
+
"telegram": { "enabled": true, "aiCommand": "codex", "botToken": "..." }
|
|
72
71
|
}
|
|
73
72
|
}
|
|
74
73
|
```
|
|
@@ -105,12 +104,11 @@ codebuddy login
|
|
|
105
104
|
|
|
106
105
|
```json
|
|
107
106
|
{
|
|
108
|
-
"aiCommand": "claude",
|
|
109
107
|
"tools": {
|
|
110
108
|
"claude": { "workDir": "/path/to/project", "skipPermissions": true, "timeoutMs": 600000 }
|
|
111
109
|
},
|
|
112
110
|
"platforms": {
|
|
113
|
-
"telegram": { "enabled": true, "botToken": "YOUR_TELEGRAM_BOT_TOKEN" }
|
|
111
|
+
"telegram": { "enabled": true, "aiCommand": "claude", "botToken": "YOUR_TELEGRAM_BOT_TOKEN" }
|
|
114
112
|
}
|
|
115
113
|
}
|
|
116
114
|
```
|
package/README.zh-CN.md
CHANGED
|
@@ -62,13 +62,12 @@ npx @wu529778790/open-im start
|
|
|
62
62
|
|
|
63
63
|
### 按平台指定 AI
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
在每个已启用渠道上设置 **`platforms.<name>.aiCommand`**(`claude` / `codex` / `codebuddy`)。若未设置,会尝试进程环境变量 **`AI_COMMAND`**;再否则默认为 **`claude`**。
|
|
66
66
|
|
|
67
67
|
```json
|
|
68
68
|
{
|
|
69
|
-
"aiCommand": "claude",
|
|
70
69
|
"platforms": {
|
|
71
|
-
"telegram": { "enabled": true, "aiCommand": "codex" }
|
|
70
|
+
"telegram": { "enabled": true, "aiCommand": "codex", "botToken": "..." }
|
|
72
71
|
}
|
|
73
72
|
}
|
|
74
73
|
```
|
|
@@ -105,12 +104,11 @@ codebuddy login
|
|
|
105
104
|
|
|
106
105
|
```json
|
|
107
106
|
{
|
|
108
|
-
"aiCommand": "claude",
|
|
109
107
|
"tools": {
|
|
110
108
|
"claude": { "workDir": "/path/to/project", "skipPermissions": true, "timeoutMs": 600000 }
|
|
111
109
|
},
|
|
112
110
|
"platforms": {
|
|
113
|
-
"telegram": { "enabled": true, "botToken": "YOUR_TELEGRAM_BOT_TOKEN" }
|
|
111
|
+
"telegram": { "enabled": true, "aiCommand": "claude", "botToken": "YOUR_TELEGRAM_BOT_TOKEN" }
|
|
114
112
|
}
|
|
115
113
|
}
|
|
116
114
|
```
|
package/dist/config/types.d.ts
CHANGED
|
@@ -21,7 +21,6 @@ export interface Config {
|
|
|
21
21
|
weworkAllowedUserIds: string[];
|
|
22
22
|
dingtalkAllowedUserIds: string[];
|
|
23
23
|
workbuddyAllowedUserIds: string[];
|
|
24
|
-
aiCommand: AiCommand;
|
|
25
24
|
codexCliPath: string;
|
|
26
25
|
codebuddyCliPath: string;
|
|
27
26
|
/** Claude 访问 API 的代理(如 http://127.0.0.1:7890) */
|
|
@@ -182,6 +181,7 @@ export interface FileConfig {
|
|
|
182
181
|
dingtalk?: FilePlatformDingtalk;
|
|
183
182
|
workbuddy?: FilePlatformWorkBuddy;
|
|
184
183
|
};
|
|
184
|
+
/** @deprecated 仅旧配置兼容;运行时以各 platforms.*.aiCommand 为准 */
|
|
185
185
|
aiCommand?: string;
|
|
186
186
|
tools?: {
|
|
187
187
|
claude?: FileToolClaude;
|
|
@@ -86,7 +86,8 @@ export declare const PAGE_TEXTS: {
|
|
|
86
86
|
readonly optional: "Optional";
|
|
87
87
|
readonly commaSeparatedIds: "Comma-separated IDs";
|
|
88
88
|
readonly aiTitle: "AI Tooling";
|
|
89
|
-
readonly aiHint: "
|
|
89
|
+
readonly aiHint: "Claude SDK keys: sidebar Config files → ~/.claude/settings.json. Set which AI each platform uses under Platforms above. Codex / CodeBuddy need a CLI path in the panels below when any platform uses them.";
|
|
90
|
+
readonly aiPerPlatformHint: "Which AI to use is configured per platform in the Platforms section (default: claude). This section sets shared paths, proxy, and logs.";
|
|
90
91
|
readonly claudeNote: "Claude credentials are still read from environment variables or ~/.claude/settings.json. This page manages local bridge config, not Claude account auth.";
|
|
91
92
|
readonly aiCommonTitle: "Shared defaults";
|
|
92
93
|
readonly aiCommonHint: "Choose the default AI tool first. Tool-specific fields are shown below.";
|
|
@@ -238,7 +239,8 @@ export declare const PAGE_TEXTS: {
|
|
|
238
239
|
readonly optional: "可选";
|
|
239
240
|
readonly commaSeparatedIds: "多个 ID 用逗号分隔";
|
|
240
241
|
readonly aiTitle: "AI 工具配置";
|
|
241
|
-
readonly aiHint: "
|
|
242
|
+
readonly aiHint: "Claude SDK:左侧栏「配置文件」→ ~/.claude/settings.json。各渠道用哪个 AI 在上方「平台」里分别设置。若任一平台选 Codex/CodeBuddy,再在下方填对应 CLI 路径。";
|
|
243
|
+
readonly aiPerPlatformHint: "每个平台的 AI 工具在上方「平台」中配置(默认 claude)。本区域设置共用路径、代理与日志。";
|
|
242
244
|
readonly claudeNote: "Claude 凭证仍然从环境变量或 ~/.claude/settings.json 读取。这个页面只管理本地桥接配置,不负责 Claude 账号登录。";
|
|
243
245
|
readonly aiCommonTitle: "公共默认配置";
|
|
244
246
|
readonly aiCommonHint: "先选择默认 AI 工具,下方再显示对应的工具专属配置。";
|
|
@@ -86,7 +86,8 @@ export const PAGE_TEXTS = {
|
|
|
86
86
|
optional: "Optional",
|
|
87
87
|
commaSeparatedIds: "Comma-separated IDs",
|
|
88
88
|
aiTitle: "AI Tooling",
|
|
89
|
-
aiHint: "
|
|
89
|
+
aiHint: "Claude SDK keys: sidebar Config files → ~/.claude/settings.json. Set which AI each platform uses under Platforms above. Codex / CodeBuddy need a CLI path in the panels below when any platform uses them.",
|
|
90
|
+
aiPerPlatformHint: "Which AI to use is configured per platform in the Platforms section (default: claude). This section sets shared paths, proxy, and logs.",
|
|
90
91
|
claudeNote: "Claude credentials are still read from environment variables or ~/.claude/settings.json. This page manages local bridge config, not Claude account auth.",
|
|
91
92
|
aiCommonTitle: "Shared defaults",
|
|
92
93
|
aiCommonHint: "Choose the default AI tool first. Tool-specific fields are shown below.",
|
|
@@ -238,7 +239,8 @@ export const PAGE_TEXTS = {
|
|
|
238
239
|
optional: "\u53ef\u9009",
|
|
239
240
|
commaSeparatedIds: "\u591a\u4e2a ID \u7528\u9017\u53f7\u5206\u9694",
|
|
240
241
|
aiTitle: "AI \u5de5\u5177\u914d\u7f6e",
|
|
241
|
-
aiHint: "
|
|
242
|
+
aiHint: "Claude SDK\uff1a\u5de6\u4fa7\u680f\u300c\u914d\u7f6e\u6587\u4ef6\u300d\u2192 ~/.claude/settings.json\u3002\u5404\u6e20\u9053\u7528\u54ea\u4e2a AI \u5728\u4e0a\u65b9\u300c\u5e73\u53f0\u300d\u91cc\u5206\u522b\u8bbe\u7f6e\u3002\u82e5\u4efb\u4e00\u5e73\u53f0\u9009 Codex/CodeBuddy\uff0c\u518d\u5728\u4e0b\u65b9\u586b\u5bf9\u5e94 CLI \u8def\u5f84\u3002",
|
|
243
|
+
aiPerPlatformHint: "\u6bcf\u4e2a\u5e73\u53f0\u7684 AI \u5de5\u5177\u5728\u4e0a\u65b9\u300c\u5e73\u53f0\u300d\u4e2d\u914d\u7f6e\uff08\u9ed8\u8ba4 claude\uff09\u3002\u672c\u533a\u57df\u8bbe\u7f6e\u5171\u7528\u8def\u5f84\u3001\u4ee3\u7406\u4e0e\u65e5\u5fd7\u3002",
|
|
242
244
|
claudeNote: "Claude \u51ed\u8bc1\u4ecd\u7136\u4ece\u73af\u5883\u53d8\u91cf\u6216 ~/.claude/settings.json \u8bfb\u53d6\u3002\u8fd9\u4e2a\u9875\u9762\u53ea\u7ba1\u7406\u672c\u5730\u6865\u63a5\u914d\u7f6e\uff0c\u4e0d\u8d1f\u8d23 Claude \u8d26\u53f7\u767b\u5f55\u3002",
|
|
243
245
|
aiCommonTitle: "\u516c\u5171\u9ed8\u8ba4\u914d\u7f6e",
|
|
244
246
|
aiCommonHint: "\u5148\u9009\u62e9\u9ed8\u8ba4 AI \u5de5\u5177\uff0c\u4e0b\u65b9\u518d\u663e\u793a\u5bf9\u5e94\u7684\u5de5\u5177\u4e13\u5c5e\u914d\u7f6e\u3002",
|
package/dist/config-web.js
CHANGED
|
@@ -6,7 +6,7 @@ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
|
6
6
|
import { join, dirname } from "node:path";
|
|
7
7
|
import { DWClient } from "dingtalk-stream";
|
|
8
8
|
import { WEB_CONFIG_PORT, getPublicWebDashboardUrl } from "./constants.js";
|
|
9
|
-
import { CONFIG_PATH, getClaudeConfigHome, loadClaudeSettingsEnv, saveClaudeSettingsEnv, loadConfig, loadFileConfig, saveFileConfig, CODEX_AUTH_PATHS } from "./config.js";
|
|
9
|
+
import { CONFIG_PATH, getClaudeConfigHome, loadClaudeSettingsEnv, saveClaudeSettingsEnv, loadConfig, loadFileConfig, saveFileConfig, normalizeAiCommand, CODEX_AUTH_PATHS, } from "./config.js";
|
|
10
10
|
import { getWebDistDir, tryServeDashboardStatic } from "./config-web-static.js";
|
|
11
11
|
import { getServiceStatus, startBackgroundService, stopBackgroundService } from "./service-control.js";
|
|
12
12
|
import { initWeWork, stopWeWork } from "./wework/client.js";
|
|
@@ -225,6 +225,12 @@ function clean(value) {
|
|
|
225
225
|
const trimmed = value.trim();
|
|
226
226
|
return trimmed ? trimmed : undefined;
|
|
227
227
|
}
|
|
228
|
+
function persistedPlatformAi(v) {
|
|
229
|
+
const c = clean(v);
|
|
230
|
+
if (c === "codex" || c === "codebuddy" || c === "claude")
|
|
231
|
+
return c;
|
|
232
|
+
return "claude";
|
|
233
|
+
}
|
|
228
234
|
function isMasked(value) {
|
|
229
235
|
return typeof value === "string" && value.includes("****");
|
|
230
236
|
}
|
|
@@ -276,35 +282,35 @@ function buildInitialPayload(file) {
|
|
|
276
282
|
platforms: {
|
|
277
283
|
telegram: {
|
|
278
284
|
enabled: file.platforms?.telegram?.enabled ?? Boolean(file.platforms?.telegram?.botToken),
|
|
279
|
-
aiCommand: file.platforms?.telegram?.aiCommand
|
|
285
|
+
aiCommand: normalizeAiCommand(file.platforms?.telegram?.aiCommand, "claude"),
|
|
280
286
|
botToken: maskSecret(file.platforms?.telegram?.botToken),
|
|
281
287
|
proxy: file.platforms?.telegram?.proxy ?? "",
|
|
282
288
|
allowedUserIds: (file.platforms?.telegram?.allowedUserIds ?? []).join(", "),
|
|
283
289
|
},
|
|
284
290
|
feishu: {
|
|
285
291
|
enabled: file.platforms?.feishu?.enabled ?? Boolean(file.platforms?.feishu?.appId && file.platforms?.feishu?.appSecret),
|
|
286
|
-
aiCommand: file.platforms?.feishu?.aiCommand
|
|
292
|
+
aiCommand: normalizeAiCommand(file.platforms?.feishu?.aiCommand, "claude"),
|
|
287
293
|
appId: file.platforms?.feishu?.appId ?? "",
|
|
288
294
|
appSecret: maskSecret(file.platforms?.feishu?.appSecret),
|
|
289
295
|
allowedUserIds: (file.platforms?.feishu?.allowedUserIds ?? []).join(", "),
|
|
290
296
|
},
|
|
291
297
|
qq: {
|
|
292
298
|
enabled: file.platforms?.qq?.enabled ?? Boolean(file.platforms?.qq?.appId && file.platforms?.qq?.secret),
|
|
293
|
-
aiCommand: file.platforms?.qq?.aiCommand
|
|
299
|
+
aiCommand: normalizeAiCommand(file.platforms?.qq?.aiCommand, "claude"),
|
|
294
300
|
appId: file.platforms?.qq?.appId ?? "",
|
|
295
301
|
secret: maskSecret(file.platforms?.qq?.secret),
|
|
296
302
|
allowedUserIds: (file.platforms?.qq?.allowedUserIds ?? []).join(", "),
|
|
297
303
|
},
|
|
298
304
|
wework: {
|
|
299
305
|
enabled: file.platforms?.wework?.enabled ?? Boolean(file.platforms?.wework?.corpId && file.platforms?.wework?.secret),
|
|
300
|
-
aiCommand: file.platforms?.wework?.aiCommand
|
|
306
|
+
aiCommand: normalizeAiCommand(file.platforms?.wework?.aiCommand, "claude"),
|
|
301
307
|
corpId: file.platforms?.wework?.corpId ?? "",
|
|
302
308
|
secret: maskSecret(file.platforms?.wework?.secret),
|
|
303
309
|
allowedUserIds: (file.platforms?.wework?.allowedUserIds ?? []).join(", "),
|
|
304
310
|
},
|
|
305
311
|
dingtalk: {
|
|
306
312
|
enabled: file.platforms?.dingtalk?.enabled ?? Boolean(file.platforms?.dingtalk?.clientId && file.platforms?.dingtalk?.clientSecret),
|
|
307
|
-
aiCommand: file.platforms?.dingtalk?.aiCommand
|
|
313
|
+
aiCommand: normalizeAiCommand(file.platforms?.dingtalk?.aiCommand, "claude"),
|
|
308
314
|
clientId: file.platforms?.dingtalk?.clientId ?? "",
|
|
309
315
|
clientSecret: maskSecret(file.platforms?.dingtalk?.clientSecret),
|
|
310
316
|
cardTemplateId: file.platforms?.dingtalk?.cardTemplateId ?? "",
|
|
@@ -312,7 +318,7 @@ function buildInitialPayload(file) {
|
|
|
312
318
|
},
|
|
313
319
|
workbuddy: {
|
|
314
320
|
enabled: file.platforms?.workbuddy?.enabled ?? Boolean(file.platforms?.workbuddy?.accessToken && file.platforms?.workbuddy?.refreshToken && file.platforms?.workbuddy?.userId),
|
|
315
|
-
aiCommand: file.platforms?.workbuddy?.aiCommand
|
|
321
|
+
aiCommand: normalizeAiCommand(file.platforms?.workbuddy?.aiCommand, "claude"),
|
|
316
322
|
accessToken: maskSecret(file.platforms?.workbuddy?.accessToken),
|
|
317
323
|
refreshToken: maskSecret(file.platforms?.workbuddy?.refreshToken),
|
|
318
324
|
userId: file.platforms?.workbuddy?.userId ?? "",
|
|
@@ -321,7 +327,6 @@ function buildInitialPayload(file) {
|
|
|
321
327
|
},
|
|
322
328
|
},
|
|
323
329
|
ai: {
|
|
324
|
-
aiCommand: file.aiCommand ?? "claude",
|
|
325
330
|
claudeWorkDir: file.tools?.claude?.workDir ?? process.cwd(),
|
|
326
331
|
claudeConfigPath: process.platform === 'win32'
|
|
327
332
|
? getClaudeConfigHome() + "\\.claude\\settings.json"
|
|
@@ -471,7 +476,6 @@ function createProbeConfig(values) {
|
|
|
471
476
|
weworkAllowedUserIds: [],
|
|
472
477
|
dingtalkAllowedUserIds: [],
|
|
473
478
|
workbuddyAllowedUserIds: [],
|
|
474
|
-
aiCommand: "claude",
|
|
475
479
|
codexCliPath: "codex",
|
|
476
480
|
claudeWorkDir: process.cwd(),
|
|
477
481
|
claudeSessionIdleTtlMinutes: 30,
|
|
@@ -631,10 +635,9 @@ function toFileConfig(payload, existing) {
|
|
|
631
635
|
saveClaudeSettingsEnv(claudeEnv);
|
|
632
636
|
}
|
|
633
637
|
// claudeConfigPath is informational only, not saved
|
|
634
|
-
const { env: _discardLegacyRootEnv, ...existingWithoutRootEnv } = existing;
|
|
638
|
+
const { env: _discardLegacyRootEnv, aiCommand: _discardLegacyGlobalAi, ...existingWithoutRootEnv } = existing;
|
|
635
639
|
return {
|
|
636
640
|
...existingWithoutRootEnv,
|
|
637
|
-
aiCommand: payload.ai.aiCommand,
|
|
638
641
|
logDir: payload.ai.logDir === undefined ? existing.logDir : clean(payload.ai.logDir),
|
|
639
642
|
logLevel: payload.ai.logLevel === "default" ? undefined : payload.ai.logLevel,
|
|
640
643
|
tools: {
|
|
@@ -660,7 +663,7 @@ function toFileConfig(payload, existing) {
|
|
|
660
663
|
telegram: {
|
|
661
664
|
...existing.platforms?.telegram,
|
|
662
665
|
enabled: payload.platforms.telegram.enabled,
|
|
663
|
-
aiCommand:
|
|
666
|
+
aiCommand: persistedPlatformAi(payload.platforms.telegram.aiCommand),
|
|
664
667
|
botToken: resolveSecret(payload.platforms.telegram.botToken, existing.platforms?.telegram?.botToken),
|
|
665
668
|
proxy: clean(payload.platforms.telegram.proxy),
|
|
666
669
|
allowedUserIds: splitCsv(payload.platforms.telegram.allowedUserIds),
|
|
@@ -668,7 +671,7 @@ function toFileConfig(payload, existing) {
|
|
|
668
671
|
feishu: {
|
|
669
672
|
...existing.platforms?.feishu,
|
|
670
673
|
enabled: payload.platforms.feishu.enabled,
|
|
671
|
-
aiCommand:
|
|
674
|
+
aiCommand: persistedPlatformAi(payload.platforms.feishu.aiCommand),
|
|
672
675
|
appId: clean(payload.platforms.feishu.appId),
|
|
673
676
|
appSecret: resolveSecret(payload.platforms.feishu.appSecret, existing.platforms?.feishu?.appSecret),
|
|
674
677
|
allowedUserIds: splitCsv(payload.platforms.feishu.allowedUserIds),
|
|
@@ -676,7 +679,7 @@ function toFileConfig(payload, existing) {
|
|
|
676
679
|
qq: {
|
|
677
680
|
...existing.platforms?.qq,
|
|
678
681
|
enabled: payload.platforms.qq.enabled,
|
|
679
|
-
aiCommand:
|
|
682
|
+
aiCommand: persistedPlatformAi(payload.platforms.qq.aiCommand),
|
|
680
683
|
appId: clean(payload.platforms.qq.appId),
|
|
681
684
|
secret: resolveSecret(payload.platforms.qq.secret, existing.platforms?.qq?.secret),
|
|
682
685
|
allowedUserIds: splitCsv(payload.platforms.qq.allowedUserIds),
|
|
@@ -684,7 +687,7 @@ function toFileConfig(payload, existing) {
|
|
|
684
687
|
wework: {
|
|
685
688
|
...existing.platforms?.wework,
|
|
686
689
|
enabled: payload.platforms.wework.enabled,
|
|
687
|
-
aiCommand:
|
|
690
|
+
aiCommand: persistedPlatformAi(payload.platforms.wework.aiCommand),
|
|
688
691
|
corpId: clean(payload.platforms.wework.corpId),
|
|
689
692
|
secret: resolveSecret(payload.platforms.wework.secret, existing.platforms?.wework?.secret),
|
|
690
693
|
allowedUserIds: splitCsv(payload.platforms.wework.allowedUserIds),
|
|
@@ -692,7 +695,7 @@ function toFileConfig(payload, existing) {
|
|
|
692
695
|
dingtalk: {
|
|
693
696
|
...existing.platforms?.dingtalk,
|
|
694
697
|
enabled: payload.platforms.dingtalk.enabled,
|
|
695
|
-
aiCommand:
|
|
698
|
+
aiCommand: persistedPlatformAi(payload.platforms.dingtalk.aiCommand),
|
|
696
699
|
clientId: clean(payload.platforms.dingtalk.clientId),
|
|
697
700
|
clientSecret: resolveSecret(payload.platforms.dingtalk.clientSecret, existing.platforms?.dingtalk?.clientSecret),
|
|
698
701
|
cardTemplateId: clean(payload.platforms.dingtalk.cardTemplateId),
|
|
@@ -701,7 +704,7 @@ function toFileConfig(payload, existing) {
|
|
|
701
704
|
workbuddy: {
|
|
702
705
|
...existing.platforms?.workbuddy,
|
|
703
706
|
enabled: payload.platforms.workbuddy.enabled,
|
|
704
|
-
aiCommand:
|
|
707
|
+
aiCommand: persistedPlatformAi(payload.platforms.workbuddy.aiCommand),
|
|
705
708
|
accessToken: resolveSecret(payload.platforms.workbuddy.accessToken, existing.platforms?.workbuddy?.accessToken),
|
|
706
709
|
refreshToken: resolveSecret(payload.platforms.workbuddy.refreshToken, existing.platforms?.workbuddy?.refreshToken),
|
|
707
710
|
userId: clean(payload.platforms.workbuddy.userId),
|
package/dist/config.js
CHANGED
|
@@ -10,6 +10,22 @@ import { join, isAbsolute } from 'node:path';
|
|
|
10
10
|
import { createLogger } from './logger.js';
|
|
11
11
|
import { APP_HOME, DEFAULT_TELEMETRY_INGEST_URL, DEFAULT_TELEMETRY_INGEST_TOKEN, } from './constants.js';
|
|
12
12
|
const log = createLogger('config');
|
|
13
|
+
/** 分渠道 AI 工具:未配置时使用 AI_COMMAND / 旧版根级 aiCommand / 默认 claude */
|
|
14
|
+
function resolveFilePlatformAi(file, platform) {
|
|
15
|
+
const pf = file.platforms;
|
|
16
|
+
const raw = platform === 'telegram'
|
|
17
|
+
? pf?.telegram?.aiCommand
|
|
18
|
+
: platform === 'feishu'
|
|
19
|
+
? pf?.feishu?.aiCommand
|
|
20
|
+
: platform === 'qq'
|
|
21
|
+
? pf?.qq?.aiCommand
|
|
22
|
+
: platform === 'wework'
|
|
23
|
+
? pf?.wework?.aiCommand
|
|
24
|
+
: platform === 'dingtalk'
|
|
25
|
+
? pf?.dingtalk?.aiCommand
|
|
26
|
+
: pf?.workbuddy?.aiCommand;
|
|
27
|
+
return normalizeAiCommand(raw ?? process.env.AI_COMMAND ?? file.aiCommand, 'claude');
|
|
28
|
+
}
|
|
13
29
|
// Re-export file I/O and credential helpers from sub-modules
|
|
14
30
|
export { CONFIG_PATH, loadFileConfig, saveFileConfig, getClaudeConfigHome, loadClaudeSettingsEnv, saveClaudeSettingsEnv, normalizeAiCommand, hasCodexAuth, parseCommaSeparated, CLAUDE_AUTH_ENV_KEYS, refreshClaudeEnvToProcess, processEnvForNonClaudeCliChild, CODEX_AUTH_PATHS, } from './config/file-io.js';
|
|
15
31
|
import { loadFileConfig, normalizeAiCommand, hasCodexAuth, parseCommaSeparated, loadClaudeSettingsEnv, } from './config/file-io.js';
|
|
@@ -159,7 +175,6 @@ export function loadConfig() {
|
|
|
159
175
|
? parseCommaSeparated(process.env.WORKBUDDY_ALLOWED_USER_IDS)
|
|
160
176
|
: fileWorkBuddy?.allowedUserIds ?? allowedUserIds;
|
|
161
177
|
// 5. AI / 工作目录 / 安全配置(从 tools 读取)
|
|
162
|
-
const aiCommand = normalizeAiCommand(process.env.AI_COMMAND ?? file.aiCommand, 'claude');
|
|
163
178
|
const tc = file.tools?.claude ?? {};
|
|
164
179
|
const tcod = file.tools?.codex ?? {};
|
|
165
180
|
const tcb = file.tools?.codebuddy ?? {};
|
|
@@ -216,9 +231,12 @@ export function loadConfig() {
|
|
|
216
231
|
else {
|
|
217
232
|
claudeSessionIdleTtlMinutes = 30;
|
|
218
233
|
}
|
|
219
|
-
// 6. 校验 Claude API
|
|
220
|
-
|
|
221
|
-
|
|
234
|
+
// 6. 校验 Claude API 凭证(任一已启用渠道使用 claude 时需配置)
|
|
235
|
+
const toolsNeeded = new Set();
|
|
236
|
+
for (const p of enabledPlatforms) {
|
|
237
|
+
toolsNeeded.add(resolveFilePlatformAi(file, p));
|
|
238
|
+
}
|
|
239
|
+
if (toolsNeeded.has('claude')) {
|
|
222
240
|
// 校验凭证时直接从各来源读取,不修改 process.env
|
|
223
241
|
const claudeToolEnvForCheck = file.tools?.claude?.env;
|
|
224
242
|
const claudeSettingsForCheck = loadClaudeSettingsEnv();
|
|
@@ -258,8 +276,8 @@ export function loadConfig() {
|
|
|
258
276
|
throw new Error(errorMsg);
|
|
259
277
|
}
|
|
260
278
|
}
|
|
261
|
-
// 7. 校验 Codex CLI
|
|
262
|
-
if (
|
|
279
|
+
// 7. 校验 Codex CLI(任一已启用渠道使用 codex 时)
|
|
280
|
+
if (toolsNeeded.has('codex')) {
|
|
263
281
|
if (isAbsolute(codexCliPath) || codexCliPath.includes('/') || codexCliPath.includes('\\')) {
|
|
264
282
|
try {
|
|
265
283
|
accessSync(codexCliPath, constants.F_OK);
|
|
@@ -300,8 +318,8 @@ export function loadConfig() {
|
|
|
300
318
|
'或在 shell 中 export OPENAI_API_KEY。');
|
|
301
319
|
}
|
|
302
320
|
}
|
|
303
|
-
// 8. 校验 CodeBuddy CLI
|
|
304
|
-
if (
|
|
321
|
+
// 8. 校验 CodeBuddy CLI(任一已启用渠道使用 codebuddy 时)
|
|
322
|
+
if (toolsNeeded.has('codebuddy')) {
|
|
305
323
|
if (isAbsolute(codebuddyCliPath) || codebuddyCliPath.includes('/') || codebuddyCliPath.includes('\\')) {
|
|
306
324
|
try {
|
|
307
325
|
accessSync(codebuddyCliPath, constants.F_OK);
|
|
@@ -402,66 +420,66 @@ export function loadConfig() {
|
|
|
402
420
|
telegram: telegramEnabled
|
|
403
421
|
? {
|
|
404
422
|
enabled: true,
|
|
405
|
-
aiCommand:
|
|
423
|
+
aiCommand: resolveFilePlatformAi(file, 'telegram'),
|
|
406
424
|
proxy: process.env.TELEGRAM_PROXY ?? file.platforms?.telegram?.proxy,
|
|
407
425
|
allowedUserIds: telegramAllowedUserIds,
|
|
408
426
|
}
|
|
409
427
|
: {
|
|
410
428
|
enabled: false,
|
|
411
|
-
aiCommand:
|
|
429
|
+
aiCommand: resolveFilePlatformAi(file, 'telegram'),
|
|
412
430
|
proxy: process.env.TELEGRAM_PROXY ?? file.platforms?.telegram?.proxy,
|
|
413
431
|
allowedUserIds: telegramAllowedUserIds,
|
|
414
432
|
},
|
|
415
433
|
feishu: feishuEnabled
|
|
416
434
|
? {
|
|
417
435
|
enabled: true,
|
|
418
|
-
aiCommand:
|
|
436
|
+
aiCommand: resolveFilePlatformAi(file, 'feishu'),
|
|
419
437
|
allowedUserIds: feishuAllowedUserIds,
|
|
420
438
|
}
|
|
421
439
|
: {
|
|
422
440
|
enabled: false,
|
|
423
|
-
aiCommand:
|
|
441
|
+
aiCommand: resolveFilePlatformAi(file, 'feishu'),
|
|
424
442
|
allowedUserIds: feishuAllowedUserIds,
|
|
425
443
|
},
|
|
426
444
|
qq: qqEnabled
|
|
427
445
|
? {
|
|
428
446
|
enabled: true,
|
|
429
|
-
aiCommand:
|
|
447
|
+
aiCommand: resolveFilePlatformAi(file, 'qq'),
|
|
430
448
|
allowedUserIds: qqAllowedUserIds,
|
|
431
449
|
}
|
|
432
450
|
: {
|
|
433
451
|
enabled: false,
|
|
434
|
-
aiCommand:
|
|
452
|
+
aiCommand: resolveFilePlatformAi(file, 'qq'),
|
|
435
453
|
allowedUserIds: qqAllowedUserIds,
|
|
436
454
|
},
|
|
437
455
|
wework: weworkEnabled
|
|
438
456
|
? {
|
|
439
457
|
enabled: true,
|
|
440
|
-
aiCommand:
|
|
458
|
+
aiCommand: resolveFilePlatformAi(file, 'wework'),
|
|
441
459
|
allowedUserIds: weworkAllowedUserIds,
|
|
442
460
|
}
|
|
443
461
|
: {
|
|
444
462
|
enabled: false,
|
|
445
|
-
aiCommand:
|
|
463
|
+
aiCommand: resolveFilePlatformAi(file, 'wework'),
|
|
446
464
|
allowedUserIds: weworkAllowedUserIds,
|
|
447
465
|
},
|
|
448
466
|
dingtalk: dingtalkEnabled
|
|
449
467
|
? {
|
|
450
468
|
enabled: true,
|
|
451
|
-
aiCommand:
|
|
469
|
+
aiCommand: resolveFilePlatformAi(file, 'dingtalk'),
|
|
452
470
|
allowedUserIds: dingtalkAllowedUserIds,
|
|
453
471
|
cardTemplateId: dingtalkCardTemplateId,
|
|
454
472
|
}
|
|
455
473
|
: {
|
|
456
474
|
enabled: false,
|
|
457
|
-
aiCommand:
|
|
475
|
+
aiCommand: resolveFilePlatformAi(file, 'dingtalk'),
|
|
458
476
|
allowedUserIds: dingtalkAllowedUserIds,
|
|
459
477
|
cardTemplateId: dingtalkCardTemplateId,
|
|
460
478
|
},
|
|
461
479
|
workbuddy: workbuddyEnabled
|
|
462
480
|
? {
|
|
463
481
|
enabled: true,
|
|
464
|
-
aiCommand:
|
|
482
|
+
aiCommand: resolveFilePlatformAi(file, 'workbuddy'),
|
|
465
483
|
allowedUserIds: workbuddyAllowedUserIds,
|
|
466
484
|
accessToken: workbuddyAccessToken,
|
|
467
485
|
refreshToken: workbuddyRefreshToken,
|
|
@@ -472,7 +490,7 @@ export function loadConfig() {
|
|
|
472
490
|
}
|
|
473
491
|
: {
|
|
474
492
|
enabled: false,
|
|
475
|
-
aiCommand:
|
|
493
|
+
aiCommand: resolveFilePlatformAi(file, 'workbuddy'),
|
|
476
494
|
allowedUserIds: workbuddyAllowedUserIds,
|
|
477
495
|
accessToken: workbuddyAccessToken,
|
|
478
496
|
refreshToken: workbuddyRefreshToken,
|
|
@@ -502,7 +520,6 @@ export function loadConfig() {
|
|
|
502
520
|
weworkAllowedUserIds,
|
|
503
521
|
dingtalkAllowedUserIds,
|
|
504
522
|
workbuddyAllowedUserIds,
|
|
505
|
-
aiCommand,
|
|
506
523
|
codexCliPath,
|
|
507
524
|
codebuddyCliPath,
|
|
508
525
|
claudeProxy,
|
|
@@ -540,10 +557,11 @@ export function getPlatformsWithCredentials(config) {
|
|
|
540
557
|
return r;
|
|
541
558
|
}
|
|
542
559
|
export function resolvePlatformAiCommand(config, platform) {
|
|
543
|
-
|
|
560
|
+
const v = config.platforms[platform]?.aiCommand;
|
|
561
|
+
return v === 'claude' || v === 'codex' || v === 'codebuddy' ? v : 'claude';
|
|
544
562
|
}
|
|
545
563
|
export function getConfiguredAiCommands(config) {
|
|
546
|
-
const commands = new Set(
|
|
564
|
+
const commands = new Set();
|
|
547
565
|
for (const platform of config.enabledPlatforms) {
|
|
548
566
|
commands.add(resolvePlatformAiCommand(config, platform));
|
|
549
567
|
}
|