pumpkinai-config 1.0.20 → 1.3.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/claude-api.js CHANGED
@@ -49,16 +49,6 @@ function getUserInput(question) {
49
49
  });
50
50
  }
51
51
 
52
- // 检查 @anthropic-ai/claude-code 是否已安装
53
- function checkClaudeInstalled() {
54
- try {
55
- const output = execSync('npm list -g @anthropic-ai/claude-code --depth=0', { encoding: 'utf8' });
56
- return output.includes('@anthropic-ai/claude-code');
57
- } catch (error) {
58
- return false;
59
- }
60
- }
61
-
62
52
  // 获取 @anthropic-ai/claude-code 版本号
63
53
  function getClaudeVersion() {
64
54
  try {
@@ -75,25 +65,17 @@ function installClaude() {
75
65
  const osType = getOS();
76
66
  let command;
77
67
 
78
- log('\n[检查] 检查 @anthropic-ai/claude-code 安装状态...', 'cyan');
79
-
80
- // 先检查是否已安装
81
- if (checkClaudeInstalled()) {
82
- log('[成功] @anthropic-ai/claude-code 已安装,跳过安装步骤', 'green');
83
- return true;
84
- }
85
-
86
- log('[安装] 开始安装 @anthropic-ai/claude-code...', 'cyan');
68
+ log('\n[安装] 开始安装 @anthropic-ai/claude-code...', 'cyan');
87
69
 
88
70
  if (osType === 'windows') {
89
- command = 'npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
71
+ command = 'npm install -g @anthropic-ai/claude-code@2.0.59 --registry https://registry.npmmirror.com';
90
72
  } else {
91
73
  // 检查是否已经是 root 用户(通过 sudo 运行或直接 root)
92
74
  const isRoot = process.getuid && process.getuid() === 0;
93
75
  if (isRoot) {
94
- command = 'npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
76
+ command = 'npm install -g @anthropic-ai/claude-code@2.0.59 --registry https://registry.npmmirror.com';
95
77
  } else {
96
- command = 'sudo npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
78
+ command = 'sudo npm install -g @anthropic-ai/claude-code@2.0.59 --registry https://registry.npmmirror.com';
97
79
  }
98
80
  }
99
81
 
@@ -147,28 +129,28 @@ function setupEnvironmentVariables(apiKey) {
147
129
  homeDir = os.homedir();
148
130
  }
149
131
 
150
- // 静默删除旧的配置文件
151
- const oldConfigPath = path.join(homeDir, '.claude.json');
152
- const oldConfigBackupPath = path.join(homeDir, '.claude.json.backup');
153
- try {
154
- if (fs.existsSync(oldConfigPath)) {
155
- fs.unlinkSync(oldConfigPath);
156
- }
157
- if (fs.existsSync(oldConfigBackupPath)) {
158
- fs.unlinkSync(oldConfigBackupPath);
159
- }
160
- } catch (error) {}
161
-
162
- // 创建 .claude 目录和 config.json
132
+ // 创建 .claude 目录和配置文件
163
133
  const claudeDir = path.join(homeDir, '.claude');
164
134
  const configPath = path.join(claudeDir, 'config.json');
135
+ const settingsPath = path.join(claudeDir, 'settings.json');
165
136
  try {
166
137
  if (!fs.existsSync(claudeDir)) {
167
138
  fs.mkdirSync(claudeDir, { recursive: true });
168
139
  }
140
+ // 创建 config.json
169
141
  const config = { primaryApiKey: "1" };
170
142
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
171
143
 
144
+ // 创建 settings.json
145
+ const settings = {
146
+ env: {
147
+ ANTHROPIC_AUTH_TOKEN: apiKey,
148
+ ANTHROPIC_BASE_URL: "https://new.aicode.us.com",
149
+ ANTHROPIC_SMALL_FAST_MODEL: "claude-3-5-haiku-20241022"
150
+ }
151
+ };
152
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
153
+
172
154
  // 如果是通过 sudo 运行的,修改文件所有者
173
155
  if (process.platform !== 'win32' && process.env.SUDO_USER) {
174
156
  const actualUser = process.env.SUDO_USER;
package/claude-fix.js ADDED
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Claude Code 报错修复工具
5
+ * 彻底清理并重新安装 Claude Code
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const os = require('os');
11
+ const { execSync } = require('child_process');
12
+
13
+ // 颜色输出
14
+ const colors = {
15
+ red: '\x1b[31m',
16
+ green: '\x1b[32m',
17
+ yellow: '\x1b[33m',
18
+ blue: '\x1b[34m',
19
+ magenta: '\x1b[35m',
20
+ cyan: '\x1b[36m',
21
+ reset: '\x1b[0m',
22
+ dim: '\x1b[2m'
23
+ };
24
+
25
+ function log(message, color = 'reset') {
26
+ console.log(`${colors[color]}${message}${colors.reset}`);
27
+ }
28
+
29
+ // 获取用户目录
30
+ function getHomeDir() {
31
+ if (process.platform !== 'win32' && process.env.SUDO_USER) {
32
+ const actualUser = process.env.SUDO_USER;
33
+ return process.platform === 'darwin' ? `/Users/${actualUser}` : `/home/${actualUser}`;
34
+ }
35
+ return os.homedir();
36
+ }
37
+
38
+ // 彻底重新安装 Claude Code
39
+ async function reinstallClaudeCode() {
40
+ console.clear();
41
+ log('\n[报错修复] 开始彻底重新安装 Claude Code...\n', 'cyan');
42
+
43
+ const homeDir = getHomeDir();
44
+
45
+ // 1. 删除 .claude 文件夹
46
+ const claudeDir = path.join(homeDir, '.claude');
47
+ if (fs.existsSync(claudeDir)) {
48
+ log('[清理] 删除 .claude 文件夹...', 'yellow');
49
+ try {
50
+ fs.rmSync(claudeDir, { recursive: true, force: true });
51
+ log('[成功] .claude 文件夹已删除', 'green');
52
+ } catch (error) {
53
+ log(`[警告] 删除 .claude 文件夹失败: ${error.message}`, 'yellow');
54
+ }
55
+ } else {
56
+ log('[跳过] .claude 文件夹不存在', 'dim');
57
+ }
58
+
59
+ // 2. 删除 .claude.json
60
+ const claudeJson = path.join(homeDir, '.claude.json');
61
+ if (fs.existsSync(claudeJson)) {
62
+ log('[清理] 删除 .claude.json...', 'yellow');
63
+ try {
64
+ fs.unlinkSync(claudeJson);
65
+ log('[成功] .claude.json 已删除', 'green');
66
+ } catch (error) {
67
+ log(`[警告] 删除 .claude.json 失败: ${error.message}`, 'yellow');
68
+ }
69
+ } else {
70
+ log('[跳过] .claude.json 不存在', 'dim');
71
+ }
72
+
73
+ // 3. 删除 .claude.json.backup
74
+ const claudeJsonBackup = path.join(homeDir, '.claude.json.backup');
75
+ if (fs.existsSync(claudeJsonBackup)) {
76
+ log('[清理] 删除 .claude.json.backup...', 'yellow');
77
+ try {
78
+ fs.unlinkSync(claudeJsonBackup);
79
+ log('[成功] .claude.json.backup 已删除', 'green');
80
+ } catch (error) {
81
+ log(`[警告] 删除 .claude.json.backup 失败: ${error.message}`, 'yellow');
82
+ }
83
+ } else {
84
+ log('[跳过] .claude.json.backup 不存在', 'dim');
85
+ }
86
+
87
+ // 4. 卸载 claude-code
88
+ log('\n[卸载] 卸载 @anthropic-ai/claude-code...', 'yellow');
89
+ try {
90
+ const osType = process.platform;
91
+ let uninstallCmd;
92
+ if (osType === 'win32') {
93
+ uninstallCmd = 'npm uninstall -g @anthropic-ai/claude-code';
94
+ } else {
95
+ const isRoot = process.getuid && process.getuid() === 0;
96
+ uninstallCmd = isRoot ? 'npm uninstall -g @anthropic-ai/claude-code' : 'sudo npm uninstall -g @anthropic-ai/claude-code';
97
+ }
98
+ execSync(uninstallCmd, { stdio: 'inherit' });
99
+ log('[成功] @anthropic-ai/claude-code 已卸载', 'green');
100
+ } catch (error) {
101
+ log('[提示] 卸载过程中出现问题,可能未安装', 'yellow');
102
+ }
103
+
104
+ log('\n[完成] 清理完成,现在请选择套餐重新安装配置\n', 'green');
105
+ }
106
+
107
+ // 主函数
108
+ async function main() {
109
+ await reinstallClaudeCode();
110
+
111
+ // 等待用户按键
112
+ log('按任意键返回菜单...', 'dim');
113
+
114
+ return new Promise((resolve) => {
115
+ if (process.stdin.isTTY) {
116
+ process.stdin.setRawMode(true);
117
+ }
118
+ process.stdin.resume();
119
+ process.stdin.once('data', () => {
120
+ if (process.stdin.isTTY) {
121
+ process.stdin.setRawMode(false);
122
+ }
123
+ resolve();
124
+ });
125
+ });
126
+ }
127
+
128
+ // 如果直接运行此脚本
129
+ if (require.main === module) {
130
+ main().then(() => {
131
+ process.exit(0);
132
+ }).catch(error => {
133
+ log(`\n[错误] ${error.message}`, 'red');
134
+ process.exit(1);
135
+ });
136
+ }
137
+
138
+ module.exports = { main, reinstallClaudeCode };
@@ -0,0 +1,372 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Claude Code 网络修复工具
5
+ * 检测当前域名并允许切换到备用域名
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const os = require('os');
11
+ const { execSync } = require('child_process');
12
+
13
+ // 颜色输出
14
+ const colors = {
15
+ red: '\x1b[31m',
16
+ green: '\x1b[32m',
17
+ yellow: '\x1b[33m',
18
+ blue: '\x1b[34m',
19
+ magenta: '\x1b[35m',
20
+ cyan: '\x1b[36m',
21
+ reset: '\x1b[0m',
22
+ dim: '\x1b[2m',
23
+ bright: '\x1b[1m'
24
+ };
25
+
26
+ function log(message, color = 'reset') {
27
+ console.log(`${colors[color]}${message}${colors.reset}`);
28
+ }
29
+
30
+ // 可用域名列表
31
+ const domainOptions = [
32
+ { name: '主域名', url: 'https://code.ppchat.vip' },
33
+ { name: '备用域名1', url: 'https://code2.ppchat.vip' },
34
+ { name: '备用域名2', url: 'https://code.pumpkinai.vip' },
35
+ { name: '清理DNS缓存-推荐', url: 'dns_flush' }
36
+ ];
37
+
38
+ // 检测操作系统
39
+ function getOS() {
40
+ const platform = os.platform();
41
+ if (platform === 'win32') return 'windows';
42
+ if (platform === 'darwin') return 'mac';
43
+ return 'linux';
44
+ }
45
+
46
+ // 获取用户目录
47
+ function getHomeDir() {
48
+ if (process.platform !== 'win32' && process.env.SUDO_USER) {
49
+ const actualUser = process.env.SUDO_USER;
50
+ return process.platform === 'darwin' ? `/Users/${actualUser}` : `/home/${actualUser}`;
51
+ }
52
+ return os.homedir();
53
+ }
54
+
55
+ // 获取当前使用的域名
56
+ function getCurrentDomain() {
57
+ const homeDir = getHomeDir();
58
+ const settingsPath = path.join(homeDir, '.claude', 'settings.json');
59
+
60
+ // 优先从 settings.json 读取
61
+ if (fs.existsSync(settingsPath)) {
62
+ try {
63
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
64
+ if (settings.env && settings.env.ANTHROPIC_BASE_URL) {
65
+ return settings.env.ANTHROPIC_BASE_URL;
66
+ }
67
+ } catch (error) {}
68
+ }
69
+
70
+ // 从环境变量读取
71
+ if (process.env.ANTHROPIC_BASE_URL) {
72
+ return process.env.ANTHROPIC_BASE_URL;
73
+ }
74
+
75
+ return null;
76
+ }
77
+
78
+ // 更新 settings.json 中的域名
79
+ function updateSettingsJson(newUrl) {
80
+ const homeDir = getHomeDir();
81
+ const settingsPath = path.join(homeDir, '.claude', 'settings.json');
82
+
83
+ try {
84
+ if (fs.existsSync(settingsPath)) {
85
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
86
+ if (!settings.env) settings.env = {};
87
+ settings.env.ANTHROPIC_BASE_URL = newUrl;
88
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
89
+
90
+ // 如果是通过 sudo 运行的,修改文件所有者
91
+ if (process.platform !== 'win32' && process.env.SUDO_USER) {
92
+ const actualUser = process.env.SUDO_USER;
93
+ const group = process.platform === 'darwin' ? 'staff' : actualUser;
94
+ try {
95
+ execSync(`chown ${actualUser}:${group} ${settingsPath}`);
96
+ } catch (error) {}
97
+ }
98
+
99
+ return true;
100
+ }
101
+ } catch (error) {
102
+ log(`[警告] 更新 settings.json 失败: ${error.message}`, 'yellow');
103
+ }
104
+ return false;
105
+ }
106
+
107
+ // 更新系统环境变量中的域名
108
+ function updateSystemEnv(newUrl) {
109
+ const osType = getOS();
110
+ const homeDir = getHomeDir();
111
+
112
+ try {
113
+ if (osType === 'windows') {
114
+ execSync(`setx ANTHROPIC_BASE_URL "${newUrl}"`, { stdio: 'pipe' });
115
+ return true;
116
+ } else if (osType === 'mac') {
117
+ const zshrcPath = path.join(homeDir, '.zshrc');
118
+ if (fs.existsSync(zshrcPath)) {
119
+ let content = fs.readFileSync(zshrcPath, 'utf8');
120
+ const regex = /export ANTHROPIC_BASE_URL=.*/g;
121
+ if (content.match(regex)) {
122
+ content = content.replace(regex, `export ANTHROPIC_BASE_URL="${newUrl}"`);
123
+ fs.writeFileSync(zshrcPath, content, 'utf8');
124
+
125
+ if (process.env.SUDO_USER) {
126
+ const actualUser = process.env.SUDO_USER;
127
+ try {
128
+ execSync(`chown ${actualUser}:staff ${zshrcPath}`);
129
+ } catch (error) {}
130
+ }
131
+ return true;
132
+ }
133
+ }
134
+ } else {
135
+ const bashrcPath = path.join(homeDir, '.bashrc');
136
+ if (fs.existsSync(bashrcPath)) {
137
+ let content = fs.readFileSync(bashrcPath, 'utf8');
138
+ const regex = /export ANTHROPIC_BASE_URL=.*/g;
139
+ if (content.match(regex)) {
140
+ content = content.replace(regex, `export ANTHROPIC_BASE_URL="${newUrl}"`);
141
+ fs.writeFileSync(bashrcPath, content, 'utf8');
142
+
143
+ if (process.env.SUDO_USER) {
144
+ const actualUser = process.env.SUDO_USER;
145
+ try {
146
+ execSync(`chown ${actualUser}:${actualUser} ${bashrcPath}`);
147
+ } catch (error) {}
148
+ }
149
+ return true;
150
+ }
151
+ }
152
+ }
153
+ } catch (error) {
154
+ log(`[警告] 更新系统环境变量失败: ${error.message}`, 'yellow');
155
+ }
156
+ return false;
157
+ }
158
+
159
+ // 清理 DNS 缓存
160
+ function flushDnsCache() {
161
+ const osType = getOS();
162
+ log('\n[DNS] 正在清理 DNS 缓存...', 'cyan');
163
+
164
+ try {
165
+ if (osType === 'windows') {
166
+ execSync('ipconfig /flushdns', { stdio: 'pipe' });
167
+ log('[成功] DNS 缓存已清理 (ipconfig /flushdns)', 'green');
168
+ } else if (osType === 'mac') {
169
+ // macOS 需要 sudo 权限
170
+ const isRoot = process.getuid && process.getuid() === 0;
171
+ if (isRoot) {
172
+ execSync('dscacheutil -flushcache && killall -HUP mDNSResponder', { stdio: 'pipe' });
173
+ } else {
174
+ execSync('sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder', { stdio: 'pipe' });
175
+ }
176
+ log('[成功] DNS 缓存已清理 (dscacheutil -flushcache)', 'green');
177
+ } else {
178
+ // Linux - 不同发行版命令不同,尝试常见的
179
+ const isRoot = process.getuid && process.getuid() === 0;
180
+ try {
181
+ if (isRoot) {
182
+ execSync('systemd-resolve --flush-caches 2>/dev/null || resolvectl flush-caches 2>/dev/null || true', { stdio: 'pipe' });
183
+ } else {
184
+ execSync('sudo systemd-resolve --flush-caches 2>/dev/null || sudo resolvectl flush-caches 2>/dev/null || true', { stdio: 'pipe' });
185
+ }
186
+ log('[成功] DNS 缓存已清理', 'green');
187
+ } catch (e) {
188
+ log('[提示] DNS 缓存清理命令不适用于此系统,已跳过', 'yellow');
189
+ }
190
+ }
191
+ return true;
192
+ } catch (error) {
193
+ log(`[警告] DNS 缓存清理失败: ${error.message}`, 'yellow');
194
+ return false;
195
+ }
196
+ }
197
+
198
+ // 切换域名
199
+ function switchDomain(newUrl) {
200
+ log(`\n[切换] 正在切换到: ${newUrl}`, 'cyan');
201
+
202
+ // 1. 更新 settings.json
203
+ const settingsUpdated = updateSettingsJson(newUrl);
204
+ if (settingsUpdated) {
205
+ log('[成功] settings.json 已更新', 'green');
206
+ } else {
207
+ log('[跳过] settings.json 不存在或更新失败', 'yellow');
208
+ }
209
+
210
+ // 2. 更新系统环境变量
211
+ const envUpdated = updateSystemEnv(newUrl);
212
+ if (envUpdated) {
213
+ log('[成功] 系统环境变量已更新', 'green');
214
+ } else {
215
+ log('[跳过] 系统环境变量更新失败或不存在', 'yellow');
216
+ }
217
+
218
+ if (settingsUpdated || envUpdated) {
219
+ log('\n[完成] 域名切换成功!', 'green');
220
+ const osType = getOS();
221
+ if (osType === 'windows') {
222
+ log('[提示] 请重新打开终端使环境变量生效', 'yellow');
223
+ } else if (osType === 'mac') {
224
+ log('[提示] 请重新打开终端或运行: source ~/.zshrc', 'yellow');
225
+ } else {
226
+ log('[提示] 请重新打开终端或运行: source ~/.bashrc', 'yellow');
227
+ }
228
+ } else {
229
+ log('\n[警告] 没有配置文件被更新,请先运行安装配置', 'yellow');
230
+ }
231
+ }
232
+
233
+ let selectedIndex = 0;
234
+
235
+ // 渲染域名选择菜单
236
+ function renderMenu() {
237
+ console.clear();
238
+ log('\n', 'reset');
239
+ log(' ' + '='.repeat(54), 'cyan');
240
+ log(' 网络修复 - 域名切换', 'magenta');
241
+ log(' ' + '='.repeat(54), 'cyan');
242
+ log('', 'reset');
243
+
244
+ const currentDomain = getCurrentDomain();
245
+
246
+ log(' 请选择要使用的域名 (↑↓选择, Enter确认, ESC返回):\n', 'cyan');
247
+
248
+ domainOptions.forEach((option, index) => {
249
+ const isSelected = index === selectedIndex;
250
+ const prefix = isSelected ? ' ▶ ' : ' ';
251
+ const nameColor = isSelected ? '\x1b[1m\x1b[33m' : '\x1b[0m';
252
+ const numLabel = `${index + 1}. `;
253
+
254
+ // 检查是否是当前使用的域名
255
+ const isCurrent = option.url && currentDomain === option.url;
256
+ const currentIndicator = isCurrent ? ' \x1b[32m← 当前使用\x1b[0m' : '';
257
+
258
+ console.log(`${prefix}${nameColor}${numLabel}${option.name}${currentIndicator}\x1b[0m`);
259
+ if (option.url && option.url !== 'dns_flush') {
260
+ const descColor = isSelected ? '\x1b[36m' : '\x1b[2m';
261
+ console.log(` ${descColor}${option.url}\x1b[0m`);
262
+ }
263
+ console.log('');
264
+ });
265
+
266
+ log(' ' + '='.repeat(54), 'cyan');
267
+
268
+ if (currentDomain) {
269
+ log(`\n 当前域名: ${currentDomain}`, 'dim');
270
+ } else {
271
+ log('\n 当前域名: 未配置', 'dim');
272
+ }
273
+ }
274
+
275
+ // 主函数
276
+ async function main() {
277
+ // 启用原始模式以捕获按键
278
+ if (process.stdin.isTTY) {
279
+ process.stdin.setRawMode(true);
280
+ }
281
+ process.stdin.resume();
282
+ process.stdin.setEncoding('utf8');
283
+
284
+ renderMenu();
285
+
286
+ return new Promise((resolve) => {
287
+ const handleKeyPress = (key) => {
288
+ // Ctrl+C 退出
289
+ if (key === '\u0003') {
290
+ console.clear();
291
+ process.exit(0);
292
+ }
293
+
294
+ // ESC 返回
295
+ if (key === '\u001b') {
296
+ if (process.stdin.isTTY) {
297
+ process.stdin.setRawMode(false);
298
+ }
299
+ process.stdin.removeAllListeners('data');
300
+ resolve(false);
301
+ return;
302
+ }
303
+
304
+ // 上箭头
305
+ if (key === '\u001b[A' || key === 'k') {
306
+ selectedIndex = selectedIndex > 0 ? selectedIndex - 1 : domainOptions.length - 1;
307
+ renderMenu();
308
+ }
309
+
310
+ // 下箭头
311
+ if (key === '\u001b[B' || key === 'j') {
312
+ selectedIndex = selectedIndex < domainOptions.length - 1 ? selectedIndex + 1 : 0;
313
+ renderMenu();
314
+ }
315
+
316
+ // Enter 确认
317
+ if (key === '\r' || key === '\n') {
318
+ const selected = domainOptions[selectedIndex];
319
+
320
+ // 切换域名
321
+ if (process.stdin.isTTY) {
322
+ process.stdin.setRawMode(false);
323
+ }
324
+ process.stdin.removeAllListeners('data');
325
+
326
+ // 根据选项执行不同操作
327
+ if (selected.url === 'dns_flush') {
328
+ flushDnsCache();
329
+ } else {
330
+ switchDomain(selected.url);
331
+ }
332
+
333
+ // 等待用户按键返回
334
+ log('\n按任意键返回菜单...', 'dim');
335
+
336
+ if (process.stdin.isTTY) {
337
+ process.stdin.setRawMode(true);
338
+ }
339
+ process.stdin.resume();
340
+ process.stdin.once('data', () => {
341
+ if (process.stdin.isTTY) {
342
+ process.stdin.setRawMode(false);
343
+ }
344
+ selectedIndex = 0;
345
+ resolve(false);
346
+ });
347
+ return;
348
+ }
349
+
350
+ // 数字键快捷选择
351
+ const num = parseInt(key);
352
+ if (num >= 1 && num <= domainOptions.length) {
353
+ selectedIndex = num - 1;
354
+ renderMenu();
355
+ }
356
+ };
357
+
358
+ process.stdin.on('data', handleKeyPress);
359
+ });
360
+ }
361
+
362
+ // 如果直接运行此脚本
363
+ if (require.main === module) {
364
+ main().then(() => {
365
+ process.exit(0);
366
+ }).catch(error => {
367
+ log(`\n[错误] ${error.message}`, 'red');
368
+ process.exit(1);
369
+ });
370
+ }
371
+
372
+ module.exports = { main, getCurrentDomain, switchDomain };
package/claude-setup.js CHANGED
@@ -49,16 +49,6 @@ function getUserInput(question) {
49
49
  });
50
50
  }
51
51
 
52
- // 检查 @anthropic-ai/claude-code 是否已安装
53
- function checkClaudeInstalled() {
54
- try {
55
- const output = execSync('npm list -g @anthropic-ai/claude-code --depth=0', { encoding: 'utf8' });
56
- return output.includes('@anthropic-ai/claude-code');
57
- } catch (error) {
58
- return false;
59
- }
60
- }
61
-
62
52
  // 获取 @anthropic-ai/claude-code 版本号
63
53
  function getClaudeVersion() {
64
54
  try {
@@ -75,25 +65,17 @@ function installClaude() {
75
65
  const osType = getOS();
76
66
  let command;
77
67
 
78
- log('\n[检查] 检查 @anthropic-ai/claude-code 安装状态...', 'cyan');
79
-
80
- // 先检查是否已安装
81
- if (checkClaudeInstalled()) {
82
- log('[成功] @anthropic-ai/claude-code 已安装,跳过安装步骤', 'green');
83
- return true;
84
- }
85
-
86
- log('[安装] 开始安装 @anthropic-ai/claude-code...', 'cyan');
68
+ log('\n[安装] 开始安装 @anthropic-ai/claude-code...', 'cyan');
87
69
 
88
70
  if (osType === 'windows') {
89
- command = 'npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
71
+ command = 'npm install -g @anthropic-ai/claude-code@2.0.59 --registry https://registry.npmmirror.com';
90
72
  } else {
91
73
  // 检查是否已经是 root 用户(通过 sudo 运行或直接 root)
92
74
  const isRoot = process.getuid && process.getuid() === 0;
93
75
  if (isRoot) {
94
- command = 'npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
76
+ command = 'npm install -g @anthropic-ai/claude-code@2.0.59 --registry https://registry.npmmirror.com';
95
77
  } else {
96
- command = 'sudo npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
78
+ command = 'sudo npm install -g @anthropic-ai/claude-code@2.0.59 --registry https://registry.npmmirror.com';
97
79
  }
98
80
  }
99
81
 
@@ -147,28 +129,28 @@ function setupEnvironmentVariables(apiKey) {
147
129
  homeDir = os.homedir();
148
130
  }
149
131
 
150
- // 静默删除旧的配置文件
151
- const oldConfigPath = path.join(homeDir, '.claude.json');
152
- const oldConfigBackupPath = path.join(homeDir, '.claude.json.backup');
153
- try {
154
- if (fs.existsSync(oldConfigPath)) {
155
- fs.unlinkSync(oldConfigPath);
156
- }
157
- if (fs.existsSync(oldConfigBackupPath)) {
158
- fs.unlinkSync(oldConfigBackupPath);
159
- }
160
- } catch (error) {}
161
-
162
- // 创建 .claude 目录和 config.json
132
+ // 创建 .claude 目录和配置文件
163
133
  const claudeDir = path.join(homeDir, '.claude');
164
134
  const configPath = path.join(claudeDir, 'config.json');
135
+ const settingsPath = path.join(claudeDir, 'settings.json');
165
136
  try {
166
137
  if (!fs.existsSync(claudeDir)) {
167
138
  fs.mkdirSync(claudeDir, { recursive: true });
168
139
  }
140
+ // 创建 config.json
169
141
  const config = { primaryApiKey: "1" };
170
142
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
171
143
 
144
+ // 创建 settings.json
145
+ const settings = {
146
+ env: {
147
+ ANTHROPIC_AUTH_TOKEN: apiKey,
148
+ ANTHROPIC_BASE_URL: "https://code.ppchat.vip",
149
+ ANTHROPIC_SMALL_FAST_MODEL: "claude-3-5-haiku-20241022"
150
+ }
151
+ };
152
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
153
+
172
154
  // 如果是通过 sudo 运行的,修改文件所有者
173
155
  if (process.platform !== 'win32' && process.env.SUDO_USER) {
174
156
  const actualUser = process.env.SUDO_USER;