aicodeswitch 2.0.6 → 2.0.8

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 CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### 2.0.8 (2026-02-02)
6
+
7
+ ### 2.0.7 (2026-02-02)
8
+
5
9
  ### 2.0.6 (2026-02-01)
6
10
 
7
11
  ### 2.0.5 (2026-01-27)
package/bin/ui.js CHANGED
@@ -7,19 +7,24 @@ const { getServerInfo } = require('./utils/get-server');
7
7
 
8
8
  const openBrowser = (url) => {
9
9
  let command;
10
+ let args;
10
11
 
11
12
  if (os.platform() === 'darwin') {
12
13
  command = 'open';
14
+ args = [url];
13
15
  } else if (os.platform() === 'win32') {
14
- command = 'start';
16
+ command = 'cmd';
17
+ args = ['/c', 'start', '', url]; // 空字符串作为窗口标题
15
18
  } else {
16
19
  // Linux and others
17
20
  command = 'xdg-open';
21
+ args = [url];
18
22
  }
19
23
 
20
- const child = spawn(command, [url], {
24
+ const child = spawn(command, args, {
21
25
  detached: true,
22
- stdio: 'ignore'
26
+ stdio: 'ignore',
27
+ shell: os.platform() === 'win32' // Windows 需要 shell
23
28
  });
24
29
 
25
30
  child.unref();
@@ -27,13 +27,15 @@ const version_check_1 = require("./version-check");
27
27
  const utils_1 = require("./utils");
28
28
  const config_metadata_1 = require("./config-metadata");
29
29
  const config_1 = require("./config");
30
- const dotenvPath = path_1.default.resolve(os_1.default.homedir(), '.aicodeswitch/aicodeswitch.conf');
30
+ const appDir = path_1.default.join(os_1.default.homedir(), '.aicodeswitch');
31
+ const dataDir = path_1.default.join(appDir, 'data');
32
+ const dotenvPath = path_1.default.resolve(appDir, 'aicodeswitch.conf');
33
+ const migrationHashFilePath = path_1.default.join(appDir, 'migration-hash');
31
34
  if (fs_1.default.existsSync(dotenvPath)) {
32
35
  dotenv_1.default.config({ path: dotenvPath });
33
36
  }
34
37
  const host = process.env.HOST || '127.0.0.1';
35
38
  const port = process.env.PORT ? parseInt(process.env.PORT, 10) : 4567;
36
- const dataDir = process.env.DATA_DIR ? path_1.default.resolve(process.cwd(), process.env.DATA_DIR) : path_1.default.join(os_1.default.homedir(), '.aicodeswitch/data');
37
39
  let globalProxyConfig = null;
38
40
  function updateProxyConfig(config) {
39
41
  if (config.proxyEnabled && config.proxyUrl) {
@@ -116,16 +118,17 @@ const writeClaudeConfig = (dbManager) => __awaiter(void 0, void 0, void 0, funct
116
118
  fs_1.default.writeFileSync(claudeSettingsPath, JSON.stringify(claudeSettings, null, 2));
117
119
  // Claude Code .claude.json
118
120
  const claudeJsonPath = path_1.default.join(homeDir, '.claude.json');
119
- // 同样处理 .claude.json 的备份
121
+ // 先读取原文件内容(如果存在)
122
+ let claudeJson = {};
123
+ if (fs_1.default.existsSync(claudeJsonPath)) {
124
+ claudeJson = JSON.parse(fs_1.default.readFileSync(claudeJsonPath, 'utf8'));
125
+ }
126
+ // 然后处理备份
120
127
  if (!fs_1.default.existsSync(claudeJsonBakPath)) {
121
128
  if (fs_1.default.existsSync(claudeJsonPath)) {
122
129
  fs_1.default.renameSync(claudeJsonPath, claudeJsonBakPath);
123
130
  }
124
131
  }
125
- let claudeJson = {};
126
- if (fs_1.default.existsSync(claudeJsonPath)) {
127
- claudeJson = JSON.parse(fs_1.default.readFileSync(claudeJsonPath, 'utf8'));
128
- }
129
132
  claudeJson.hasCompletedOnboarding = true;
130
133
  fs_1.default.writeFileSync(claudeJsonPath, JSON.stringify(claudeJson, null, 2));
131
134
  // 保存元数据
@@ -1288,8 +1291,6 @@ ${instruction}
1288
1291
  const text = yield resp.text();
1289
1292
  res.type('text/plain').send(text);
1290
1293
  })));
1291
- // Migration 相关端点
1292
- const getMigrationHashPath = () => path_1.default.join(dataDir, '.migration-hash');
1293
1294
  // 查找 migration.md 文件的路径
1294
1295
  const findMigrationPath = () => {
1295
1296
  // 可能的路径列表
@@ -1314,20 +1315,18 @@ ${instruction}
1314
1315
  res.json({ shouldShow: false, content: '' });
1315
1316
  return;
1316
1317
  }
1317
- const content = fs_1.default.readFileSync(migrationPath, 'utf-8');
1318
+ const content = fs_1.default.readFileSync(migrationPath, 'utf-8').trim();
1318
1319
  // 计算当前内容的 hash
1319
1320
  const currentHash = (0, crypto_1.createHash)('sha256').update(content).digest('hex');
1320
- // 读取之前保存的 hash
1321
- const hashPath = getMigrationHashPath();
1322
1321
  // 如果 hash 文件不存在,说明是第一次安装
1323
- if (!fs_1.default.existsSync(hashPath)) {
1322
+ if (!fs_1.default.existsSync(migrationHashFilePath)) {
1324
1323
  // 第一次安装,直接保存当前 hash,不显示弹窗
1325
- fs_1.default.writeFileSync(hashPath, currentHash, 'utf-8');
1324
+ fs_1.default.writeFileSync(migrationHashFilePath, currentHash, 'utf-8');
1326
1325
  res.json({ shouldShow: false, content: '' });
1327
1326
  return;
1328
1327
  }
1329
1328
  // 读取已保存的 hash
1330
- const savedHash = fs_1.default.readFileSync(hashPath, 'utf-8').trim();
1329
+ const savedHash = fs_1.default.readFileSync(migrationHashFilePath, 'utf-8').trim();
1331
1330
  // 如果 hash 不同,需要显示弹窗
1332
1331
  const shouldShow = savedHash !== currentHash;
1333
1332
  res.json({ shouldShow, content: shouldShow ? content : '' });
@@ -1345,11 +1344,10 @@ ${instruction}
1345
1344
  res.json({ success: false });
1346
1345
  return;
1347
1346
  }
1348
- const content = fs_1.default.readFileSync(migrationPath, 'utf-8');
1347
+ const content = fs_1.default.readFileSync(migrationPath, 'utf-8').trim();
1349
1348
  const hash = (0, crypto_1.createHash)('sha256').update(content).digest('hex');
1350
1349
  // 保存 hash 到文件
1351
- const hashPath = getMigrationHashPath();
1352
- fs_1.default.writeFileSync(hashPath, hash, 'utf-8');
1350
+ fs_1.default.writeFileSync(migrationHashFilePath, hash, 'utf-8');
1353
1351
  res.json({ success: true });
1354
1352
  }
1355
1353
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aicodeswitch",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "description": "A tool to help you manage AI programming tools to access large language models locally. It allows your Claude Code, Codex and other tools to no longer be limited to official models.",
5
5
  "author": "tangshuang",
6
6
  "license": "GPL-3.0",