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 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
- current[key] = {};
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
- current[key] = {};
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
  }
@@ -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
- // 如果开启对bypassPermissions的支持,添加对应的配置项
293
- if (enableBypassPermissionsSupport) {
294
- proxySettings.permissions = {
295
- defaultMode: "bypassPermissions"
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 result = yield writeClaudeConfig(dbManager, enableAgentTeams, enableBypassPermissionsSupport, undefined, appConfig.claudeDefaultModel, appConfig.autocompactPctOverride);
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
  })));