pumpkinai-config 1.3.1 → 1.4.1

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 ADDED
@@ -0,0 +1,406 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * PPChat Claude Code 一键安装配置工具 (API 版本)
5
+ * 自动安装 @anthropic-ai/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
+ const readline = require('readline');
13
+
14
+ // 颜色输出
15
+ const colors = {
16
+ red: '\x1b[31m',
17
+ green: '\x1b[32m',
18
+ yellow: '\x1b[33m',
19
+ blue: '\x1b[34m',
20
+ magenta: '\x1b[35m',
21
+ cyan: '\x1b[36m',
22
+ reset: '\x1b[0m'
23
+ };
24
+
25
+ function log(message, color = 'reset') {
26
+ console.log(`${colors[color]}${message}${colors.reset}`);
27
+ }
28
+
29
+ // 检测操作系统
30
+ function getOS() {
31
+ const platform = os.platform();
32
+ if (platform === 'win32') return 'windows';
33
+ if (platform === 'darwin') return 'mac';
34
+ return 'linux';
35
+ }
36
+
37
+ // 获取用户输入
38
+ function getUserInput(question) {
39
+ const rl = readline.createInterface({
40
+ input: process.stdin,
41
+ output: process.stdout
42
+ });
43
+
44
+ return new Promise((resolve) => {
45
+ rl.question(question, (answer) => {
46
+ rl.close();
47
+ resolve(answer.trim());
48
+ });
49
+ });
50
+ }
51
+
52
+ // 获取 @anthropic-ai/claude-code 版本号
53
+ function getClaudeVersion() {
54
+ try {
55
+ const output = execSync('npm list -g @anthropic-ai/claude-code --depth=0', { encoding: 'utf8' });
56
+ const match = output.match(/@anthropic-ai\/claude-code@([\d.]+)/);
57
+ return match ? match[1] : '未知';
58
+ } catch (error) {
59
+ return '未知';
60
+ }
61
+ }
62
+
63
+ // 安装 @anthropic-ai/claude-code
64
+ function installClaude() {
65
+ const osType = getOS();
66
+ let command;
67
+
68
+ log('\n[安装] 开始安装 @anthropic-ai/claude-code...', 'cyan');
69
+
70
+ if (osType === 'windows') {
71
+ command = 'npm install -g @anthropic-ai/claude-code@2.0.59 --registry https://registry.npmmirror.com';
72
+ } else {
73
+ // 检查是否已经是 root 用户(通过 sudo 运行或直接 root)
74
+ const isRoot = process.getuid && process.getuid() === 0;
75
+ if (isRoot) {
76
+ command = 'npm install -g @anthropic-ai/claude-code@2.0.59 --registry https://registry.npmmirror.com';
77
+ } else {
78
+ command = 'sudo npm install -g @anthropic-ai/claude-code@2.0.59 --registry https://registry.npmmirror.com';
79
+ }
80
+ }
81
+
82
+ log(`[执行] ${command}`, 'yellow');
83
+
84
+ try {
85
+ execSync(command, { stdio: 'inherit' });
86
+ log('[成功] @anthropic-ai/claude-code 安装成功', 'green');
87
+ return true;
88
+ } catch (error) {
89
+ log('[错误] @anthropic-ai/claude-code 安装失败', 'red');
90
+ log('\n[错误详情]', 'red');
91
+
92
+ // 显示错误信息
93
+ if (error.message) {
94
+ log(`错误信息: ${error.message}`, 'red');
95
+ }
96
+
97
+ // 显示退出码
98
+ if (error.status !== undefined) {
99
+ log(`退出码: ${error.status}`, 'red');
100
+ }
101
+
102
+ // 显示错误输出
103
+ if (error.stderr) {
104
+ log(`错误输出:\n${error.stderr.toString()}`, 'red');
105
+ }
106
+
107
+ // 显示标准输出(可能包含有用信息)
108
+ if (error.stdout) {
109
+ log(`标准输出:\n${error.stdout.toString()}`, 'yellow');
110
+ }
111
+
112
+ log('\n[提示] 你可以手动安装:', 'yellow');
113
+ log(` ${command}`, 'yellow');
114
+ log(' 然后重新运行此工具', 'yellow');
115
+ return false;
116
+ }
117
+ }
118
+
119
+ // 设置系统用户环境变量
120
+ function setupEnvironmentVariables(apiKey) {
121
+ log('\n[配置] 设置系统用户环境变量...', 'cyan');
122
+
123
+ const osType = getOS();
124
+ let homeDir;
125
+ if (process.platform !== 'win32' && process.env.SUDO_USER) {
126
+ const actualUser = process.env.SUDO_USER;
127
+ homeDir = process.platform === 'darwin' ? `/Users/${actualUser}` : `/home/${actualUser}`;
128
+ } else {
129
+ homeDir = os.homedir();
130
+ }
131
+
132
+ // 创建 .claude 目录和配置文件
133
+ const claudeDir = path.join(homeDir, '.claude');
134
+ const configPath = path.join(claudeDir, 'config.json');
135
+ const settingsPath = path.join(claudeDir, 'settings.json');
136
+ try {
137
+ if (!fs.existsSync(claudeDir)) {
138
+ fs.mkdirSync(claudeDir, { recursive: true });
139
+ }
140
+ // 创建 config.json
141
+ const config = { primaryApiKey: "1" };
142
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
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
+
154
+ // 如果是通过 sudo 运行的,修改文件所有者
155
+ if (process.platform !== 'win32' && process.env.SUDO_USER) {
156
+ const actualUser = process.env.SUDO_USER;
157
+ const group = process.platform === 'darwin' ? 'staff' : actualUser;
158
+ try {
159
+ execSync(`chown -R ${actualUser}:${group} ${claudeDir}`);
160
+ } catch (error) {}
161
+ }
162
+ } catch (error) {}
163
+
164
+ // 需要设置的环境变量
165
+ const envVars = {
166
+ ANTHROPIC_AUTH_TOKEN: apiKey,
167
+ ANTHROPIC_BASE_URL: "https://new.aicode.us.com",
168
+ CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1",
169
+ ANTHROPIC_SMALL_FAST_MODEL:"claude-3-5-haiku-20241022"
170
+ };
171
+
172
+ try {
173
+ if (osType === 'windows') {
174
+ // Windows: 使用 setx 设置用户环境变量(永久生效)
175
+ for (const [key, value] of Object.entries(envVars)) {
176
+ try {
177
+ execSync(`setx ${key} "${value}"`, { stdio: 'pipe' });
178
+ log(`[成功] 设置环境变量: ${key}`, 'green');
179
+ } catch (error) {
180
+ log(`[错误] 设置环境变量 ${key} 失败: ${error.message}`, 'red');
181
+ return false;
182
+ }
183
+ }
184
+ log('[提示] 请重新打开终端使环境变量生效', 'yellow');
185
+ return true;
186
+
187
+ } else if (osType === 'mac') {
188
+ // macOS: 写入 ~/.zshrc
189
+ const zshrcPath = path.join(homeDir, '.zshrc');
190
+ let zshrcContent = '';
191
+ if (fs.existsSync(zshrcPath)) {
192
+ zshrcContent = fs.readFileSync(zshrcPath, 'utf8');
193
+ }
194
+
195
+ // 构建环境变量行
196
+ let envLines = '\n# Claude Code 环境变量 (pumpkinai)\n';
197
+ for (const [key, value] of Object.entries(envVars)) {
198
+ const envLine = `export ${key}="${value}"`;
199
+ if (!zshrcContent.includes(`export ${key}=`)) {
200
+ envLines += envLine + '\n';
201
+ log(`[成功] 添加环境变量: ${key}`, 'green');
202
+ } else {
203
+ // 替换已存在的环境变量
204
+ const regex = new RegExp(`export ${key}=.*`, 'g');
205
+ zshrcContent = zshrcContent.replace(regex, envLine);
206
+ log(`[更新] 更新环境变量: ${key}`, 'yellow');
207
+ }
208
+ }
209
+
210
+ // 写入文件
211
+ if (envLines !== '\n# Claude Code 环境变量 (pumpkinai)\n') {
212
+ const newContent = zshrcContent + envLines;
213
+ fs.writeFileSync(zshrcPath, newContent, 'utf8');
214
+ } else {
215
+ fs.writeFileSync(zshrcPath, zshrcContent, 'utf8');
216
+ }
217
+
218
+ // 修改文件所有者
219
+ if (process.env.SUDO_USER) {
220
+ const actualUser = process.env.SUDO_USER;
221
+ try {
222
+ execSync(`chown ${actualUser}:staff ${zshrcPath}`);
223
+ } catch (error) {}
224
+ }
225
+
226
+ log(`[成功] 环境变量已写入: ${zshrcPath}`, 'green');
227
+ log('[提示] 请重新打开终端或运行: source ~/.zshrc', 'yellow');
228
+ return true;
229
+
230
+ } else {
231
+ // Linux: 写入 ~/.bashrc
232
+ const bashrcPath = path.join(homeDir, '.bashrc');
233
+ let bashrcContent = '';
234
+ if (fs.existsSync(bashrcPath)) {
235
+ bashrcContent = fs.readFileSync(bashrcPath, 'utf8');
236
+ }
237
+
238
+ // 构建环境变量行
239
+ let envLines = '\n# Claude Code 环境变量 (pumpkinai)\n';
240
+ for (const [key, value] of Object.entries(envVars)) {
241
+ const envLine = `export ${key}="${value}"`;
242
+ if (!bashrcContent.includes(`export ${key}=`)) {
243
+ envLines += envLine + '\n';
244
+ log(`[成功] 添加环境变量: ${key}`, 'green');
245
+ } else {
246
+ // 替换已存在的环境变量
247
+ const regex = new RegExp(`export ${key}=.*`, 'g');
248
+ bashrcContent = bashrcContent.replace(regex, envLine);
249
+ log(`[更新] 更新环境变量: ${key}`, 'yellow');
250
+ }
251
+ }
252
+
253
+ // 写入文件
254
+ if (envLines !== '\n# Claude Code 环境变量 (pumpkinai)\n') {
255
+ const newContent = bashrcContent + envLines;
256
+ fs.writeFileSync(bashrcPath, newContent, 'utf8');
257
+ } else {
258
+ fs.writeFileSync(bashrcPath, bashrcContent, 'utf8');
259
+ }
260
+
261
+ // 修改文件所有者
262
+ if (process.env.SUDO_USER) {
263
+ const actualUser = process.env.SUDO_USER;
264
+ try {
265
+ execSync(`chown ${actualUser}:${actualUser} ${bashrcPath}`);
266
+ } catch (error) {}
267
+ }
268
+
269
+ log(`[成功] 环境变量已写入: ${bashrcPath}`, 'green');
270
+ log('[提示] 请重新打开终端或运行: source ~/.bashrc', 'yellow');
271
+ return true;
272
+ }
273
+
274
+ } catch (error) {
275
+ log(`[错误] 设置环境变量失败: ${error.message}`, 'red');
276
+ return false;
277
+ }
278
+ }
279
+
280
+ // 配置 Claude
281
+ async function configureEnvironment() {
282
+ log('\n[配置] 配置 API Key...', 'cyan');
283
+
284
+ // 显示粘贴提示
285
+ if (process.platform === 'win32') {
286
+ log('[提示] Windows 粘贴方式:', 'yellow');
287
+ log(' • CMD/PowerShell: 鼠标右键 或 Shift+Insert', 'yellow');
288
+
289
+ }
290
+
291
+ const apiKey = await getUserInput('请输入你的 Claude API Key (sk-xxx): ');
292
+
293
+ if (!apiKey || !apiKey.startsWith('sk-')) {
294
+ log('[错误] API Key 格式不正确,应该以 sk- 开头', 'red');
295
+ return false;
296
+ }
297
+
298
+ return setupEnvironmentVariables(apiKey);
299
+ }
300
+
301
+ // 显示完成信息
302
+ function showCompletionInfo() {
303
+ const osType = getOS();
304
+
305
+ // 获取 home 目录
306
+ let homeDir;
307
+ if (process.platform !== 'win32' && process.env.SUDO_USER) {
308
+ const actualUser = process.env.SUDO_USER;
309
+ homeDir = process.platform === 'darwin' ? `/Users/${actualUser}` : `/home/${actualUser}`;
310
+ } else {
311
+ homeDir = os.homedir();
312
+ }
313
+
314
+ log('\n', 'reset');
315
+ log('=' + '='.repeat(68) + '=', 'yellow');
316
+ log(' 欢迎使用 Claude 开始您的 AI 编程之旅', 'yellow');
317
+ log('=' + '='.repeat(68) + '=', 'yellow');
318
+
319
+ log('\n[已完成操作]', 'cyan');
320
+ log(' * 安装 @anthropic-ai/claude-code', 'green');
321
+ log(' * 设置用户环境变量 ANTHROPIC_AUTH_TOKEN', 'green');
322
+ log(' * 设置用户环境变量 ANTHROPIC_BASE_URL', 'green');
323
+ log(' * 设置用户环境变量 ANTHROPIC_SMALL_FAST_MODEL', 'green');
324
+
325
+ log('\n[环境变量配置]', 'cyan');
326
+ if (osType === 'windows') {
327
+ log(' 环境变量已通过 setx 设置到用户环境变量', 'reset');
328
+ log(' 可在 系统属性 -> 高级 -> 环境变量 中查看', 'yellow');
329
+ } else if (osType === 'mac') {
330
+ log(' 环境变量已写入: ~/.zshrc', 'reset');
331
+ log(` ${path.join(homeDir, '.zshrc')}`, 'yellow');
332
+ } else {
333
+ log(' 环境变量已写入: ~/.bashrc', 'reset');
334
+ log(` ${path.join(homeDir, '.bashrc')}`, 'yellow');
335
+ }
336
+
337
+ log('\n[启动方式]', 'cyan');
338
+
339
+ if (osType === 'windows') {
340
+ log(' 请重新打开终端后运行:', 'reset');
341
+ log(' claude', 'yellow');
342
+ } else if (osType === 'mac') {
343
+ log(' 请重新打开终端后运行:', 'reset');
344
+ log(' claude', 'yellow');
345
+
346
+ } else {
347
+ log(' 请重新打开终端后运行:', 'reset');
348
+ log(' claude', 'yellow');
349
+ }
350
+
351
+ const claudeVersion = getClaudeVersion();
352
+ log('\n Claude Code 版本: v' + claudeVersion, 'reset');
353
+ log(' 支持系统: Windows 10/11 • macOS • Linux', 'reset');
354
+ log('\n', 'reset');
355
+ }
356
+
357
+ // 主函数
358
+ async function main() {
359
+ console.clear();
360
+
361
+ // ASCII Logo - 水平渐变 (蓝→紫→粉)
362
+ log('\n', 'reset');
363
+ console.log(' \x1b[38;5;39m██████╗\x1b[38;5;75m██╗ \x1b[38;5;111m█████╗ \x1b[38;5;147m██╗ ██╗\x1b[38;5;183m██████╗ \x1b[38;5;219m███████╗\x1b[0m');
364
+ console.log(' \x1b[38;5;39m██╔════╝\x1b[38;5;75m██║ \x1b[38;5;111m██╔══██╗\x1b[38;5;147m██║ ██║\x1b[38;5;183m██╔══██╗\x1b[38;5;219m██╔════╝\x1b[0m');
365
+ console.log(' \x1b[38;5;45m██║ \x1b[38;5;81m██║ \x1b[38;5;117m███████║\x1b[38;5;153m██║ ██║\x1b[38;5;189m██║ ██║\x1b[38;5;225m█████╗ \x1b[0m');
366
+ console.log(' \x1b[38;5;75m██║ \x1b[38;5;111m██║ \x1b[38;5;147m██╔══██║\x1b[38;5;183m██║ ██║\x1b[38;5;219m██║ ██║\x1b[38;5;225m██╔══╝ \x1b[0m');
367
+ console.log(' \x1b[38;5;111m╚██████╗\x1b[38;5;147m███████╗\x1b[38;5;183m██║ ██║\x1b[38;5;219m╚██████╔╝\x1b[38;5;225m██████╔╝\x1b[38;5;231m███████╗\x1b[0m');
368
+ console.log(' \x1b[38;5;147m╚═════╝\x1b[38;5;183m╚══════╝\x1b[38;5;219m╚═╝ ╚═╝\x1b[38;5;225m ╚═════╝ \x1b[38;5;231m╚═════╝ ╚══════╝\x1b[0m');
369
+ log('\n pumpkinai Claude Code config Tool (API)', 'magenta');
370
+ log(' ' + '='.repeat(50), 'cyan');
371
+ log('', 'reset');
372
+
373
+ try {
374
+ // 1. 安装 @anthropic-ai/claude-code
375
+ const installSuccess = installClaude();
376
+ if (!installSuccess) {
377
+ log('\n[提示] 安装失败,但你可以继续配置环境变量', 'yellow');
378
+ }
379
+
380
+ // 2. 配置 API Key
381
+ const configSuccess = await configureEnvironment();
382
+ if (!configSuccess) {
383
+ process.exit(1);
384
+ }
385
+
386
+ // 3. 显示完成信息 (不再设置系统环境变量)
387
+ showCompletionInfo();
388
+
389
+ } catch (error) {
390
+ log(`\n[错误] 安装过程中出现错误: ${error.message}`, 'red');
391
+ process.exit(1);
392
+ }
393
+ }
394
+
395
+ // 如果直接运行此脚本
396
+ if (require.main === module) {
397
+ main();
398
+ }
399
+
400
+ // 导出函数供其他模块使用
401
+ module.exports = {
402
+ main,
403
+ installClaude,
404
+ configureEnvironment,
405
+ setupEnvironmentVariables
406
+ };
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 };