pumpkinai-config 1.5.0 → 1.5.2
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-ide.js +254 -0
- package/package.json +3 -2
package/claude-ide.js
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PPChat Claude IDE 配置工具
|
|
5
|
+
* 自动配置 VSCode 和 Cursor 的 Claude 环境变量
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
const readline = require('readline');
|
|
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
|
+
};
|
|
23
|
+
|
|
24
|
+
function log(message, color = 'reset') {
|
|
25
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 获取用户输入
|
|
29
|
+
function getUserInput(question) {
|
|
30
|
+
const rl = readline.createInterface({
|
|
31
|
+
input: process.stdin,
|
|
32
|
+
output: process.stdout
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
rl.question(question, (answer) => {
|
|
37
|
+
rl.close();
|
|
38
|
+
resolve(answer.trim());
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 获取配置文件路径
|
|
44
|
+
function getSettingsPaths() {
|
|
45
|
+
const homeDir = os.homedir();
|
|
46
|
+
const platform = os.platform();
|
|
47
|
+
|
|
48
|
+
if (platform === 'win32') {
|
|
49
|
+
const appData = process.env.APPDATA || path.join(homeDir, 'AppData', 'Roaming');
|
|
50
|
+
return {
|
|
51
|
+
vscode: path.join(appData, 'Code', 'User', 'settings.json'),
|
|
52
|
+
cursor: path.join(appData, 'Cursor', 'User', 'settings.json')
|
|
53
|
+
};
|
|
54
|
+
} else if (platform === 'darwin') {
|
|
55
|
+
return {
|
|
56
|
+
vscode: path.join(homeDir, 'Library', 'Application Support', 'Code', 'User', 'settings.json'),
|
|
57
|
+
cursor: path.join(homeDir, 'Library', 'Application Support', 'Cursor', 'User', 'settings.json')
|
|
58
|
+
};
|
|
59
|
+
} else {
|
|
60
|
+
// Linux
|
|
61
|
+
return {
|
|
62
|
+
vscode: path.join(homeDir, '.config', 'Code', 'User', 'settings.json'),
|
|
63
|
+
cursor: path.join(homeDir, '.config', 'Cursor', 'User', 'settings.json')
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 读取 JSON 文件(带注释处理)
|
|
69
|
+
function readJsonFile(filePath) {
|
|
70
|
+
try {
|
|
71
|
+
if (!fs.existsSync(filePath)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
75
|
+
// 移除 JSON 中的注释(简单处理)
|
|
76
|
+
const cleanContent = content
|
|
77
|
+
.replace(/\/\/.*$/gm, '') // 移除单行注释
|
|
78
|
+
.replace(/\/\*[\s\S]*?\*\//g, ''); // 移除多行注释
|
|
79
|
+
return JSON.parse(cleanContent);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
log(`[警告] 读取文件失败: ${filePath}`, 'yellow');
|
|
82
|
+
log(` ${error.message}`, 'yellow');
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 写入 JSON 文件
|
|
88
|
+
function writeJsonFile(filePath, data) {
|
|
89
|
+
try {
|
|
90
|
+
// 确保目录存在
|
|
91
|
+
const dir = path.dirname(filePath);
|
|
92
|
+
if (!fs.existsSync(dir)) {
|
|
93
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
94
|
+
}
|
|
95
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8');
|
|
96
|
+
return true;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
log(`[错误] 写入文件失败: ${filePath}`, 'red');
|
|
99
|
+
log(` ${error.message}`, 'red');
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 配置 IDE 的 settings.json
|
|
105
|
+
function configureIDESettings(settingsPath, ideName, apiKey) {
|
|
106
|
+
log(`\n[配置] 正在配置 ${ideName}...`, 'cyan');
|
|
107
|
+
|
|
108
|
+
// 检查配置文件是否存在
|
|
109
|
+
let settings = readJsonFile(settingsPath);
|
|
110
|
+
|
|
111
|
+
if (settings === null) {
|
|
112
|
+
// 文件不存在或读取失败,创建新配置
|
|
113
|
+
log(`[信息] ${ideName} 配置文件不存在,将创建新文件`, 'yellow');
|
|
114
|
+
settings = {};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 要添加的环境变量
|
|
118
|
+
const envVarsToAdd = [
|
|
119
|
+
{
|
|
120
|
+
name: "ANTHROPIC_BASE_URL",
|
|
121
|
+
value: "https://code.ppchat.vip"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "ANTHROPIC_AUTH_TOKEN",
|
|
125
|
+
value: apiKey
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS",
|
|
129
|
+
value: "1"
|
|
130
|
+
}
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
// 获取或创建 claudeCode.environmentVariables 数组
|
|
134
|
+
if (!settings['claudeCode.environmentVariables']) {
|
|
135
|
+
settings['claudeCode.environmentVariables'] = [];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 更新环境变量
|
|
139
|
+
for (const envVar of envVarsToAdd) {
|
|
140
|
+
const existingIndex = settings['claudeCode.environmentVariables'].findIndex(
|
|
141
|
+
item => item.name === envVar.name
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
if (existingIndex >= 0) {
|
|
145
|
+
// 更新已存在的环境变量
|
|
146
|
+
settings['claudeCode.environmentVariables'][existingIndex] = envVar;
|
|
147
|
+
log(`[更新] ${envVar.name}`, 'yellow');
|
|
148
|
+
} else {
|
|
149
|
+
// 添加新的环境变量
|
|
150
|
+
settings['claudeCode.environmentVariables'].push(envVar);
|
|
151
|
+
log(`[添加] ${envVar.name}`, 'green');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 写入配置文件
|
|
156
|
+
if (writeJsonFile(settingsPath, settings)) {
|
|
157
|
+
log(`[成功] ${ideName} 配置完成: ${settingsPath}`, 'green');
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 显示完成信息
|
|
165
|
+
function showCompletionInfo(configuredIDEs) {
|
|
166
|
+
log('\n', 'reset');
|
|
167
|
+
log('=' + '='.repeat(58) + '=', 'yellow');
|
|
168
|
+
log(' Claude IDE 配置完成', 'yellow');
|
|
169
|
+
log('=' + '='.repeat(58) + '=', 'yellow');
|
|
170
|
+
|
|
171
|
+
log('\n[已配置的 IDE]', 'cyan');
|
|
172
|
+
for (const ide of configuredIDEs) {
|
|
173
|
+
log(` * ${ide}`, 'green');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
log('\n[配置内容]', 'cyan');
|
|
177
|
+
log(' * ANTHROPIC_BASE_URL = https://code.ppchat.vip', 'reset');
|
|
178
|
+
log(' * ANTHROPIC_AUTH_TOKEN = sk-xxx...', 'reset');
|
|
179
|
+
log(' * CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = 1', 'reset');
|
|
180
|
+
|
|
181
|
+
log('\n[下一步]', 'cyan');
|
|
182
|
+
log(' 请重启 VSCode / Cursor 使配置生效', 'yellow');
|
|
183
|
+
log('\n', 'reset');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// 主函数
|
|
187
|
+
async function main() {
|
|
188
|
+
console.clear();
|
|
189
|
+
|
|
190
|
+
// ASCII Logo
|
|
191
|
+
log('\n', 'reset');
|
|
192
|
+
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');
|
|
193
|
+
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');
|
|
194
|
+
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');
|
|
195
|
+
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');
|
|
196
|
+
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');
|
|
197
|
+
console.log(' \x1b[38;5;147m ╚═════╝\x1b[38;5;183m╚══════╝\x1b[38;5;219m╚═╝ ╚═╝\x1b[38;5;225m ╚═════╝ \x1b[38;5;231m╚═════╝ ╚══════╝\x1b[0m');
|
|
198
|
+
log('\n pumpkinai Claude IDE Config Tool', 'magenta');
|
|
199
|
+
log(' ' + '='.repeat(50), 'cyan');
|
|
200
|
+
log('', 'reset');
|
|
201
|
+
|
|
202
|
+
// 获取配置文件路径
|
|
203
|
+
const paths = getSettingsPaths();
|
|
204
|
+
|
|
205
|
+
log('[信息] 检测到的配置文件路径:', 'cyan');
|
|
206
|
+
log(` VSCode: ${paths.vscode}`, 'reset');
|
|
207
|
+
log(` Cursor: ${paths.cursor}`, 'reset');
|
|
208
|
+
|
|
209
|
+
// 显示粘贴提示
|
|
210
|
+
if (process.platform === 'win32') {
|
|
211
|
+
log('\n[提示] Windows 粘贴方式:', 'yellow');
|
|
212
|
+
log(' • CMD/PowerShell: 鼠标右键 或 Shift+Insert', 'yellow');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// 获取 API Key
|
|
216
|
+
const apiKey = await getUserInput('\n请输入你的 Claude API Key (sk-xxx): ');
|
|
217
|
+
|
|
218
|
+
if (!apiKey || !apiKey.startsWith('sk-')) {
|
|
219
|
+
log('[错误] API Key 格式不正确,应该以 sk- 开头', 'red');
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const configuredIDEs = [];
|
|
224
|
+
|
|
225
|
+
// 配置 VSCode
|
|
226
|
+
if (configureIDESettings(paths.vscode, 'VSCode', apiKey)) {
|
|
227
|
+
configuredIDEs.push('VSCode');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// 配置 Cursor
|
|
231
|
+
if (configureIDESettings(paths.cursor, 'Cursor', apiKey)) {
|
|
232
|
+
configuredIDEs.push('Cursor');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (configuredIDEs.length === 0) {
|
|
236
|
+
log('\n[错误] 没有成功配置任何 IDE', 'red');
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// 显示完成信息
|
|
241
|
+
showCompletionInfo(configuredIDEs);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// 如果直接运行此脚本
|
|
245
|
+
if (require.main === module) {
|
|
246
|
+
main();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// 导出函数供其他模块使用
|
|
250
|
+
module.exports = {
|
|
251
|
+
main,
|
|
252
|
+
configureIDESettings,
|
|
253
|
+
getSettingsPaths
|
|
254
|
+
};
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumpkinai-config",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "PumpkinAI 一键安装配置工具 - 支持 Codex 和 Claude Code",
|
|
5
5
|
"main": "codex-setup.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"codex-config": "./codex-setup.js",
|
|
8
8
|
"codex-api": "./codex-api.js",
|
|
9
9
|
"claude-config": "./claude-setup.js",
|
|
10
|
-
"claude-api": "./claude-api.js"
|
|
10
|
+
"claude-api": "./claude-api.js",
|
|
11
|
+
"claude-ide": "./claude-ide.js"
|
|
11
12
|
},
|
|
12
13
|
"scripts": {
|
|
13
14
|
"test": "node codex-setup.js",
|