aicodeswitch 5.2.5 → 5.2.6
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 +1 -0
- package/bin/utils/config-helpers.js +2 -1
- package/bin/utils/managed-fields.js +1 -1
- package/dist/server/config-managed-fields.js +1 -1
- package/dist/server/config-merge.js +2 -1
- package/dist/server/fs-database.js +18 -0
- package/dist/server/main.js +26 -9
- package/dist/ui/assets/index-KBja3wfR.js +822 -0
- package/dist/ui/assets/index-MjMlew6J.css +1 -0
- package/dist/ui/index.html +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/index-BTjE2wK0.js +0 -821
- package/dist/ui/assets/index-CzfKxImD.css +0 -1
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ AI Code Switch 是帮助你在本地管理 AI 编程工具接入大模型的工
|
|
|
11
11
|
- 视频演示:[https://www.bilibili.com/video/BV1uEznBuEJd/](https://www.bilibili.com/video/BV1uEznBuEJd/?from=github)
|
|
12
12
|
- 1分钟让Claude Code接入GLM国产模型:[https://www.bilibili.com/video/BV1a865B8ErA/](https://www.bilibili.com/video/BV1a865B8ErA/)
|
|
13
13
|
- 1分钟让Codex接入免费模型Agnes:[https://www.bilibili.com/video/BV1tQ7Q63Eva/](https://www.bilibili.com/video/BV1tQ7Q63Eva/) Codex接入Deepseek可参考该方法实现
|
|
14
|
+
- 在线教程:[https://space.bilibili.com/37442719/lists/8333248](https://space.bilibili.com/37442719/lists/8333248)
|
|
14
15
|
|
|
15
16
|
## 功能要点
|
|
16
17
|
|
|
@@ -70,7 +70,8 @@ const deepSet = (obj, fieldPath, value) => {
|
|
|
70
70
|
for (let i = 0; i < fieldPath.length - 1; i += 1) {
|
|
71
71
|
const key = fieldPath[i];
|
|
72
72
|
if (current[key] === undefined || current[key] === null || typeof current[key] !== 'object') {
|
|
73
|
-
|
|
73
|
+
// 下一级路径为数字索引时创建数组,否则创建对象(正确还原数组结构)
|
|
74
|
+
current[key] = typeof fieldPath[i + 1] === 'number' ? [] : {};
|
|
74
75
|
}
|
|
75
76
|
current = current[key];
|
|
76
77
|
}
|
|
@@ -18,7 +18,7 @@ const CLAUDE_SETTINGS_MANAGED_FIELDS = [
|
|
|
18
18
|
'env.ANTHROPIC_DEFAULT_HAIKU_MODEL',
|
|
19
19
|
'env.ANTHROPIC_DEFAULT_SONNET_MODEL',
|
|
20
20
|
'env.ANTHROPIC_DEFAULT_OPUS_MODEL',
|
|
21
|
-
'permissions',
|
|
21
|
+
'permissions.defaultMode',
|
|
22
22
|
'skipDangerousModePermissionPrompt',
|
|
23
23
|
'effortLevel',
|
|
24
24
|
'model',
|
|
@@ -16,7 +16,7 @@ exports.CLAUDE_SETTINGS_MANAGED_FIELDS = [
|
|
|
16
16
|
{ path: ['env', 'ANTHROPIC_DEFAULT_HAIKU_MODEL'], optional: true },
|
|
17
17
|
{ path: ['env', 'ANTHROPIC_DEFAULT_SONNET_MODEL'], optional: true },
|
|
18
18
|
{ path: ['env', 'ANTHROPIC_DEFAULT_OPUS_MODEL'], optional: true },
|
|
19
|
-
{ path: ['permissions'], optional: true },
|
|
19
|
+
{ path: ['permissions', 'defaultMode'], optional: true },
|
|
20
20
|
{ path: ['skipDangerousModePermissionPrompt'], optional: true },
|
|
21
21
|
{ path: ['effortLevel'], optional: true },
|
|
22
22
|
{ path: ['model'], optional: true },
|
|
@@ -115,7 +115,8 @@ const deepSet = (obj, path, value) => {
|
|
|
115
115
|
for (let i = 0; i < path.length - 1; i++) {
|
|
116
116
|
const key = path[i];
|
|
117
117
|
if (current[key] === undefined || current[key] === null || typeof current[key] !== 'object') {
|
|
118
|
-
|
|
118
|
+
// 下一级路径为数字索引时创建数组,否则创建对象(正确还原 collectPaths 收集到的数组结构)
|
|
119
|
+
current[key] = typeof path[i + 1] === 'number' ? [] : {};
|
|
119
120
|
}
|
|
120
121
|
current = current[key];
|
|
121
122
|
}
|
|
@@ -34,12 +34,17 @@ const DEFAULT_CODEX_REASONING_EFFORT = 'high';
|
|
|
34
34
|
const DEFAULT_FAILOVER_RECOVERY_SECONDS = 30;
|
|
35
35
|
const VALID_CLAUDE_EFFORT_LEVELS = ['low', 'medium', 'high', 'max'];
|
|
36
36
|
const DEFAULT_CLAUDE_EFFORT_LEVEL = 'medium';
|
|
37
|
+
const VALID_CLAUDE_PERMISSION_DEFAULT_MODES = ['default', 'acceptEdits', 'plan', 'auto', 'dontAsk', 'bypassPermissions'];
|
|
38
|
+
const DEFAULT_CLAUDE_PERMISSION_DEFAULT_MODE = 'default';
|
|
37
39
|
const isCodexReasoningEffort = (value) => {
|
|
38
40
|
return typeof value === 'string' && VALID_CODEX_REASONING_EFFORTS.includes(value);
|
|
39
41
|
};
|
|
40
42
|
const isClaudeEffortLevel = (value) => {
|
|
41
43
|
return typeof value === 'string' && VALID_CLAUDE_EFFORT_LEVELS.includes(value);
|
|
42
44
|
};
|
|
45
|
+
const isClaudePermissionDefaultMode = (value) => {
|
|
46
|
+
return typeof value === 'string' && VALID_CLAUDE_PERMISSION_DEFAULT_MODES.includes(value);
|
|
47
|
+
};
|
|
43
48
|
const isValidAutocompactPct = (v) => {
|
|
44
49
|
return typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 100;
|
|
45
50
|
};
|
|
@@ -1208,6 +1213,7 @@ class FileSystemDatabaseManager {
|
|
|
1208
1213
|
ruleGlobalTimeout: undefined,
|
|
1209
1214
|
enableAgentTeams: false,
|
|
1210
1215
|
enableBypassPermissionsSupport: false,
|
|
1216
|
+
claudePermissionsDefaultMode: DEFAULT_CLAUDE_PERMISSION_DEFAULT_MODE,
|
|
1211
1217
|
claudeEffortLevel: DEFAULT_CLAUDE_EFFORT_LEVEL,
|
|
1212
1218
|
autocompactPctOverride: undefined,
|
|
1213
1219
|
claudeDefaultModel: undefined,
|
|
@@ -1228,6 +1234,12 @@ class FileSystemDatabaseManager {
|
|
|
1228
1234
|
if (!isClaudeEffortLevel(this.config.claudeEffortLevel)) {
|
|
1229
1235
|
this.config.claudeEffortLevel = DEFAULT_CLAUDE_EFFORT_LEVEL;
|
|
1230
1236
|
}
|
|
1237
|
+
if (!isClaudePermissionDefaultMode(this.config.claudePermissionsDefaultMode)) {
|
|
1238
|
+
// 缺失或非法时,按旧 enableBypassPermissionsSupport 推导(迁移兼容)
|
|
1239
|
+
this.config.claudePermissionsDefaultMode = this.config.enableBypassPermissionsSupport === true
|
|
1240
|
+
? 'bypassPermissions'
|
|
1241
|
+
: DEFAULT_CLAUDE_PERMISSION_DEFAULT_MODE;
|
|
1242
|
+
}
|
|
1231
1243
|
if (typeof this.config.autocompactPctOverride !== 'undefined' && !isValidAutocompactPct(this.config.autocompactPctOverride)) {
|
|
1232
1244
|
this.config.autocompactPctOverride = undefined;
|
|
1233
1245
|
}
|
|
@@ -1252,6 +1264,7 @@ class FileSystemDatabaseManager {
|
|
|
1252
1264
|
const hasGlobalToolConfig = !!this.config &&
|
|
1253
1265
|
(Object.prototype.hasOwnProperty.call(this.config, 'enableAgentTeams') ||
|
|
1254
1266
|
Object.prototype.hasOwnProperty.call(this.config, 'enableBypassPermissionsSupport') ||
|
|
1267
|
+
Object.prototype.hasOwnProperty.call(this.config, 'claudePermissionsDefaultMode') ||
|
|
1255
1268
|
Object.prototype.hasOwnProperty.call(this.config, 'codexModelReasoningEffort'));
|
|
1256
1269
|
if (!hasGlobalToolConfig) {
|
|
1257
1270
|
const getPreferredRoute = (targetType) => {
|
|
@@ -2318,6 +2331,11 @@ class FileSystemDatabaseManager {
|
|
|
2318
2331
|
if (!isClaudeEffortLevel(merged.claudeEffortLevel)) {
|
|
2319
2332
|
merged.claudeEffortLevel = DEFAULT_CLAUDE_EFFORT_LEVEL;
|
|
2320
2333
|
}
|
|
2334
|
+
if (!isClaudePermissionDefaultMode(merged.claudePermissionsDefaultMode)) {
|
|
2335
|
+
merged.claudePermissionsDefaultMode = merged.enableBypassPermissionsSupport === true
|
|
2336
|
+
? 'bypassPermissions'
|
|
2337
|
+
: DEFAULT_CLAUDE_PERMISSION_DEFAULT_MODE;
|
|
2338
|
+
}
|
|
2321
2339
|
if (typeof merged.autocompactPctOverride !== 'undefined' && !isValidAutocompactPct(merged.autocompactPctOverride)) {
|
|
2322
2340
|
merged.autocompactPctOverride = undefined;
|
|
2323
2341
|
}
|
package/dist/server/main.js
CHANGED
|
@@ -219,13 +219,18 @@ const asyncHandler = (handler) => (req, res, next) => {
|
|
|
219
219
|
};
|
|
220
220
|
const VALID_CLAUDE_EFFORT_LEVELS = ['low', 'medium', 'high', 'max'];
|
|
221
221
|
const DEFAULT_CLAUDE_EFFORT_LEVEL = 'medium';
|
|
222
|
+
const VALID_CLAUDE_PERMISSION_DEFAULT_MODES = ['default', 'acceptEdits', 'plan', 'auto', 'dontAsk', 'bypassPermissions'];
|
|
223
|
+
const DEFAULT_CLAUDE_PERMISSION_DEFAULT_MODE = 'default';
|
|
222
224
|
const isClaudeEffortLevel = (value) => {
|
|
223
225
|
return typeof value === 'string' && VALID_CLAUDE_EFFORT_LEVELS.includes(value);
|
|
224
226
|
};
|
|
227
|
+
const isClaudePermissionDefaultMode = (value) => {
|
|
228
|
+
return typeof value === 'string' && VALID_CLAUDE_PERMISSION_DEFAULT_MODES.includes(value);
|
|
229
|
+
};
|
|
225
230
|
const isValidAutocompactPct = (v) => {
|
|
226
231
|
return typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 100;
|
|
227
232
|
};
|
|
228
|
-
const writeClaudeConfig = (_dbManager_1, enableAgentTeams_1, enableBypassPermissionsSupport_1, effortLevel_1, defaultModel_1, autocompactPctOverride_1, ...args_1) => __awaiter(void 0, [_dbManager_1, enableAgentTeams_1, enableBypassPermissionsSupport_1, effortLevel_1, defaultModel_1, autocompactPctOverride_1, ...args_1], void 0, function* (_dbManager, enableAgentTeams, enableBypassPermissionsSupport, effortLevel, defaultModel, autocompactPctOverride, options = {}) {
|
|
233
|
+
const writeClaudeConfig = (_dbManager_1, enableAgentTeams_1, enableBypassPermissionsSupport_1, permissionsDefaultMode_1, effortLevel_1, defaultModel_1, autocompactPctOverride_1, ...args_1) => __awaiter(void 0, [_dbManager_1, enableAgentTeams_1, enableBypassPermissionsSupport_1, permissionsDefaultMode_1, effortLevel_1, defaultModel_1, autocompactPctOverride_1, ...args_1], void 0, function* (_dbManager, enableAgentTeams, enableBypassPermissionsSupport, permissionsDefaultMode, effortLevel, defaultModel, autocompactPctOverride, options = {}) {
|
|
229
234
|
var _a;
|
|
230
235
|
try {
|
|
231
236
|
const homeDir = os_1.default.homedir();
|
|
@@ -289,11 +294,17 @@ const writeClaudeConfig = (_dbManager_1, enableAgentTeams_1, enableBypassPermiss
|
|
|
289
294
|
const proxySettings = {
|
|
290
295
|
env: claudeSettingsEnv
|
|
291
296
|
};
|
|
292
|
-
//
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
+
// 解析默认权限模式:bypassPermissions 必须门控开启才生效,否则降级为 default
|
|
298
|
+
let claudeDefaultMode = isClaudePermissionDefaultMode(permissionsDefaultMode)
|
|
299
|
+
? permissionsDefaultMode
|
|
300
|
+
: DEFAULT_CLAUDE_PERMISSION_DEFAULT_MODE;
|
|
301
|
+
if (claudeDefaultMode === 'bypassPermissions' && enableBypassPermissionsSupport !== true) {
|
|
302
|
+
claudeDefaultMode = 'default';
|
|
303
|
+
}
|
|
304
|
+
proxySettings.permissions = {
|
|
305
|
+
defaultMode: claudeDefaultMode
|
|
306
|
+
};
|
|
307
|
+
if (claudeDefaultMode === 'bypassPermissions') {
|
|
297
308
|
proxySettings.skipDangerousModePermissionPrompt = true;
|
|
298
309
|
}
|
|
299
310
|
// 如果设置了 effortLevel,添加对应的配置项
|
|
@@ -665,7 +676,7 @@ const syncConfigsOnServerStartup = (dbManager) => __awaiter(void 0, void 0, void
|
|
|
665
676
|
const claudeEffortLevel = isClaudeEffortLevel(config.claudeEffortLevel)
|
|
666
677
|
? config.claudeEffortLevel
|
|
667
678
|
: DEFAULT_CLAUDE_EFFORT_LEVEL;
|
|
668
|
-
const claudeWritten = yield writeClaudeConfig(dbManager, config.enableAgentTeams, config.enableBypassPermissionsSupport, claudeEffortLevel, config.claudeDefaultModel, config.autocompactPctOverride);
|
|
679
|
+
const claudeWritten = yield writeClaudeConfig(dbManager, config.enableAgentTeams, config.enableBypassPermissionsSupport, config.claudePermissionsDefaultMode, claudeEffortLevel, config.claudeDefaultModel, config.autocompactPctOverride);
|
|
669
680
|
console.log(`[Startup Config Sync] Claude Code config ${claudeWritten ? 'written' : 'skipped'}`);
|
|
670
681
|
const modelReasoningEffort = isCodexReasoningEffort(config.codexModelReasoningEffort)
|
|
671
682
|
? config.codexModelReasoningEffort
|
|
@@ -678,7 +689,7 @@ const syncConfigsOnGlobalConfigUpdate = (dbManager) => __awaiter(void 0, void 0,
|
|
|
678
689
|
const claudeEffortLevel = isClaudeEffortLevel(config.claudeEffortLevel)
|
|
679
690
|
? config.claudeEffortLevel
|
|
680
691
|
: DEFAULT_CLAUDE_EFFORT_LEVEL;
|
|
681
|
-
const claudeUpdated = yield writeClaudeConfig(dbManager, config.enableAgentTeams, config.enableBypassPermissionsSupport, claudeEffortLevel, config.claudeDefaultModel, config.autocompactPctOverride, { allowOverwriteRefresh: true });
|
|
692
|
+
const claudeUpdated = yield writeClaudeConfig(dbManager, config.enableAgentTeams, config.enableBypassPermissionsSupport, config.claudePermissionsDefaultMode, claudeEffortLevel, config.claudeDefaultModel, config.autocompactPctOverride, { allowOverwriteRefresh: true });
|
|
682
693
|
console.log(`[Config Update Sync] Claude Code config ${claudeUpdated ? 'written' : 'skipped'}`);
|
|
683
694
|
const modelReasoningEffort = isCodexReasoningEffort(config.codexModelReasoningEffort)
|
|
684
695
|
? config.codexModelReasoningEffort
|
|
@@ -2003,13 +2014,19 @@ ${instruction}
|
|
|
2003
2014
|
const appConfig = dbManager.getConfig();
|
|
2004
2015
|
const requestedEnableAgentTeams = req.body.enableAgentTeams;
|
|
2005
2016
|
const requestedBypass = req.body.enableBypassPermissionsSupport;
|
|
2017
|
+
const requestedMode = req.body.permissionsDefaultMode;
|
|
2006
2018
|
const enableAgentTeams = typeof requestedEnableAgentTeams === 'boolean'
|
|
2007
2019
|
? requestedEnableAgentTeams
|
|
2008
2020
|
: appConfig.enableAgentTeams;
|
|
2009
2021
|
const enableBypassPermissionsSupport = typeof requestedBypass === 'boolean'
|
|
2010
2022
|
? requestedBypass
|
|
2011
2023
|
: appConfig.enableBypassPermissionsSupport;
|
|
2012
|
-
const
|
|
2024
|
+
const permissionsDefaultMode = isClaudePermissionDefaultMode(requestedMode)
|
|
2025
|
+
? requestedMode
|
|
2026
|
+
: isClaudePermissionDefaultMode(appConfig.claudePermissionsDefaultMode)
|
|
2027
|
+
? appConfig.claudePermissionsDefaultMode
|
|
2028
|
+
: DEFAULT_CLAUDE_PERMISSION_DEFAULT_MODE;
|
|
2029
|
+
const result = yield writeClaudeConfig(dbManager, enableAgentTeams, enableBypassPermissionsSupport, permissionsDefaultMode, undefined, appConfig.claudeDefaultModel, appConfig.autocompactPctOverride);
|
|
2013
2030
|
applyWriteLocalRecords(proxyServer);
|
|
2014
2031
|
res.json(result);
|
|
2015
2032
|
})));
|