pumpkinai-config 1.0.8 → 1.0.9
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 +334 -0
- package/codex-api.js +573 -0
- package/codex-setup.js +2 -2
- package/package.json +3 -2
package/claude-api.js
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
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 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
|
+
// 获取 @anthropic-ai/claude-code 版本号
|
|
63
|
+
function getClaudeVersion() {
|
|
64
|
+
try {
|
|
65
|
+
const output = execSync('npm list -g @anthropic-ai/claude-code --depth=0', { encoding: 'utf8' });
|
|
66
|
+
const match = output.match(/@anthropic-ai\/claude-code@([\d.]+)/);
|
|
67
|
+
return match ? match[1] : '未知';
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return '未知';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 安装 @anthropic-ai/claude-code
|
|
74
|
+
function installClaude() {
|
|
75
|
+
const osType = getOS();
|
|
76
|
+
let command;
|
|
77
|
+
|
|
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');
|
|
87
|
+
|
|
88
|
+
if (osType === 'windows') {
|
|
89
|
+
command = 'npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
|
|
90
|
+
} else {
|
|
91
|
+
// 检查是否已经是 root 用户(通过 sudo 运行或直接 root)
|
|
92
|
+
const isRoot = process.getuid && process.getuid() === 0;
|
|
93
|
+
if (isRoot) {
|
|
94
|
+
command = 'npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
|
|
95
|
+
} else {
|
|
96
|
+
command = 'sudo npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
log(`[执行] ${command}`, 'yellow');
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
execSync(command, { stdio: 'inherit' });
|
|
104
|
+
log('[成功] @anthropic-ai/claude-code 安装成功', 'green');
|
|
105
|
+
return true;
|
|
106
|
+
} catch (error) {
|
|
107
|
+
log('[错误] @anthropic-ai/claude-code 安装失败', 'red');
|
|
108
|
+
log('\n[错误详情]', 'red');
|
|
109
|
+
|
|
110
|
+
// 显示错误信息
|
|
111
|
+
if (error.message) {
|
|
112
|
+
log(`错误信息: ${error.message}`, 'red');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 显示退出码
|
|
116
|
+
if (error.status !== undefined) {
|
|
117
|
+
log(`退出码: ${error.status}`, 'red');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 显示错误输出
|
|
121
|
+
if (error.stderr) {
|
|
122
|
+
log(`错误输出:\n${error.stderr.toString()}`, 'red');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 显示标准输出(可能包含有用信息)
|
|
126
|
+
if (error.stdout) {
|
|
127
|
+
log(`标准输出:\n${error.stdout.toString()}`, 'yellow');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
log('\n[提示] 你可以手动安装:', 'yellow');
|
|
131
|
+
log(` ${command}`, 'yellow');
|
|
132
|
+
log(' 然后重新运行此工具', 'yellow');
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 创建 .claude 目录和配置文件
|
|
138
|
+
function createClaudeConfig(apiKey) {
|
|
139
|
+
log('\n[配置] 创建 Claude 配置文件...', 'cyan');
|
|
140
|
+
|
|
141
|
+
// 获取实际用户的 home 目录
|
|
142
|
+
let homeDir;
|
|
143
|
+
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
144
|
+
// Linux/Mac 使用 sudo 时,获取实际用户的 home 目录
|
|
145
|
+
const actualUser = process.env.SUDO_USER;
|
|
146
|
+
homeDir = process.platform === 'darwin' ? `/Users/${actualUser}` : `/home/${actualUser}`;
|
|
147
|
+
} else {
|
|
148
|
+
homeDir = os.homedir();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const claudeDir = path.join(homeDir, '.claude');
|
|
152
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
153
|
+
const configPath = path.join(claudeDir, 'config.json');
|
|
154
|
+
const oldConfigPath = path.join(homeDir, '.claude.json');
|
|
155
|
+
const oldConfigBackupPath = path.join(homeDir, '.claude.json.backup');
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
// 删除旧的配置文件(不提示用户)
|
|
159
|
+
if (fs.existsSync(oldConfigPath)) {
|
|
160
|
+
fs.unlinkSync(oldConfigPath);
|
|
161
|
+
}
|
|
162
|
+
if (fs.existsSync(oldConfigBackupPath)) {
|
|
163
|
+
fs.unlinkSync(oldConfigBackupPath);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// 创建 .claude 目录
|
|
167
|
+
if (!fs.existsSync(claudeDir)) {
|
|
168
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
169
|
+
log(`[成功] 创建目录: ${claudeDir}`, 'green');
|
|
170
|
+
} else {
|
|
171
|
+
log(`[提示] 目录已存在: ${claudeDir}`, 'yellow');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 创建 settings.json 配置 (删除了 ANTHROPIC_DEFAULT_HAIKU_MODEL)
|
|
175
|
+
const settings = {
|
|
176
|
+
env: {
|
|
177
|
+
ANTHROPIC_AUTH_TOKEN: apiKey,
|
|
178
|
+
ANTHROPIC_BASE_URL: "https://cc.aicode.us.com/"
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
|
|
183
|
+
log(`[成功] 创建配置文件: ${settingsPath}`, 'green');
|
|
184
|
+
|
|
185
|
+
// 创建 config.json 配置
|
|
186
|
+
const config = {
|
|
187
|
+
primaryApiKey: "1"
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
|
|
191
|
+
log(`[成功] 创建配置文件: ${configPath}`, 'green');
|
|
192
|
+
|
|
193
|
+
// 如果是通过 sudo 运行的,修改文件所有者
|
|
194
|
+
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
195
|
+
const actualUser = process.env.SUDO_USER;
|
|
196
|
+
const group = process.platform === 'darwin' ? 'staff' : actualUser;
|
|
197
|
+
try {
|
|
198
|
+
execSync(`chown -R ${actualUser}:${group} ${claudeDir}`);
|
|
199
|
+
log(`[成功] 设置文件所有者为: ${actualUser}`, 'green');
|
|
200
|
+
} catch (error) {
|
|
201
|
+
log(`[警告] 无法设置文件所有者: ${error.message}`, 'yellow');
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return true;
|
|
206
|
+
} catch (error) {
|
|
207
|
+
log(`[错误] 创建配置文件失败: ${error.message}`, 'red');
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// 配置 Claude
|
|
213
|
+
async function configureEnvironment() {
|
|
214
|
+
log('\n[配置] 配置 API Key...', 'cyan');
|
|
215
|
+
|
|
216
|
+
// 显示粘贴提示
|
|
217
|
+
if (process.platform === 'win32') {
|
|
218
|
+
log('[提示] Windows 粘贴方式:', 'yellow');
|
|
219
|
+
log(' • CMD/PowerShell: 鼠标右键 或 Shift+Insert', 'yellow');
|
|
220
|
+
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const apiKey = await getUserInput('请输入你的 Claude API Key (sk-xxx): ');
|
|
224
|
+
|
|
225
|
+
if (!apiKey || !apiKey.startsWith('sk-')) {
|
|
226
|
+
log('[错误] API Key 格式不正确,应该以 sk- 开头', 'red');
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return createClaudeConfig(apiKey);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// 显示完成信息
|
|
234
|
+
function showCompletionInfo() {
|
|
235
|
+
const osType = getOS();
|
|
236
|
+
|
|
237
|
+
// 获取配置文件路径
|
|
238
|
+
let homeDir;
|
|
239
|
+
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
240
|
+
const actualUser = process.env.SUDO_USER;
|
|
241
|
+
homeDir = process.platform === 'darwin' ? `/Users/${actualUser}` : `/home/${actualUser}`;
|
|
242
|
+
} else {
|
|
243
|
+
homeDir = os.homedir();
|
|
244
|
+
}
|
|
245
|
+
const claudeDir = path.join(homeDir, '.claude');
|
|
246
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
247
|
+
const configPath = path.join(claudeDir, 'config.json');
|
|
248
|
+
|
|
249
|
+
log('\n', 'reset');
|
|
250
|
+
log('=' + '='.repeat(68) + '=', 'yellow');
|
|
251
|
+
log(' 欢迎使用 Claude 开始您的 AI 编程之旅', 'yellow');
|
|
252
|
+
log('=' + '='.repeat(68) + '=', 'yellow');
|
|
253
|
+
|
|
254
|
+
log('\n[已完成操作]', 'cyan');
|
|
255
|
+
log(' * 安装 @anthropic-ai/claude-code', 'green');
|
|
256
|
+
log(' * 创建配置文件 settings.json', 'green');
|
|
257
|
+
log(' * 创建配置文件 config.json', 'green');
|
|
258
|
+
|
|
259
|
+
log('\n[配置文件路径]', 'cyan');
|
|
260
|
+
log(' settings.json (可在此处修改key和域名url):', 'reset');
|
|
261
|
+
log(` ${settingsPath}`, 'yellow');
|
|
262
|
+
log('', 'reset');
|
|
263
|
+
log(' config.json:', 'reset');
|
|
264
|
+
log(` ${configPath}`, 'yellow');
|
|
265
|
+
|
|
266
|
+
log('\n[启动方式]', 'cyan');
|
|
267
|
+
|
|
268
|
+
if (osType === 'windows') {
|
|
269
|
+
log(' 请重新打开终端后运行:', 'reset');
|
|
270
|
+
log(' claude', 'yellow');
|
|
271
|
+
} else if (osType === 'mac') {
|
|
272
|
+
log(' 请重新打开终端后运行:', 'reset');
|
|
273
|
+
log(' claude', 'yellow');
|
|
274
|
+
|
|
275
|
+
} else {
|
|
276
|
+
log(' 请重新打开终端后运行:', 'reset');
|
|
277
|
+
log(' claude', 'yellow');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const claudeVersion = getClaudeVersion();
|
|
281
|
+
log('\n Claude Code 版本: v' + claudeVersion, 'reset');
|
|
282
|
+
log(' 支持系统: Windows 10/11 • macOS • Linux', 'reset');
|
|
283
|
+
log('\n', 'reset');
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// 主函数
|
|
287
|
+
async function main() {
|
|
288
|
+
console.clear();
|
|
289
|
+
|
|
290
|
+
// ASCII Logo - 水平渐变 (蓝→紫→粉)
|
|
291
|
+
log('\n', 'reset');
|
|
292
|
+
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');
|
|
293
|
+
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');
|
|
294
|
+
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');
|
|
295
|
+
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');
|
|
296
|
+
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');
|
|
297
|
+
console.log(' \x1b[38;5;147m╚═════╝\x1b[38;5;183m╚══════╝\x1b[38;5;219m╚═╝ ╚═╝\x1b[38;5;225m ╚═════╝ \x1b[38;5;231m╚═════╝ ╚══════╝\x1b[0m');
|
|
298
|
+
log('\n pumpkinai Claude Code config Tool (API)', 'magenta');
|
|
299
|
+
log(' ' + '='.repeat(50), 'cyan');
|
|
300
|
+
log('', 'reset');
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
// 1. 安装 @anthropic-ai/claude-code
|
|
304
|
+
const installSuccess = installClaude();
|
|
305
|
+
if (!installSuccess) {
|
|
306
|
+
log('\n[提示] 安装失败,但你可以继续配置环境变量', 'yellow');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// 2. 配置 API Key
|
|
310
|
+
const configSuccess = await configureEnvironment();
|
|
311
|
+
if (!configSuccess) {
|
|
312
|
+
process.exit(1);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// 3. 显示完成信息 (不再设置系统环境变量)
|
|
316
|
+
showCompletionInfo();
|
|
317
|
+
|
|
318
|
+
} catch (error) {
|
|
319
|
+
log(`\n[错误] 安装过程中出现错误: ${error.message}`, 'red');
|
|
320
|
+
process.exit(1);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// 如果直接运行此脚本
|
|
325
|
+
if (require.main === module) {
|
|
326
|
+
main();
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// 导出函数供其他模块使用
|
|
330
|
+
module.exports = {
|
|
331
|
+
main,
|
|
332
|
+
installClaude,
|
|
333
|
+
configureEnvironment
|
|
334
|
+
};
|
package/codex-api.js
ADDED
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PPChat Codex 一键安装配置工具
|
|
5
|
+
* 自动安装 @openai/codex 并配置相关文件
|
|
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
|
+
// 解析 JSONC (JSON with Comments)
|
|
30
|
+
function parseJSONC(text) {
|
|
31
|
+
// 移除单行注释
|
|
32
|
+
let cleaned = text.replace(/\/\/.*$/gm, '');
|
|
33
|
+
// 移除多行注释
|
|
34
|
+
cleaned = cleaned.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
35
|
+
// 移除尾随逗号
|
|
36
|
+
cleaned = cleaned.replace(/,(\s*[}\]])/g, '$1');
|
|
37
|
+
// 解析 JSON
|
|
38
|
+
return JSON.parse(cleaned);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 检测操作系统
|
|
42
|
+
function getOS() {
|
|
43
|
+
const platform = os.platform();
|
|
44
|
+
if (platform === 'win32') return 'windows';
|
|
45
|
+
if (platform === 'darwin') return 'mac';
|
|
46
|
+
return 'linux';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 获取用户输入
|
|
50
|
+
function getUserInput(question) {
|
|
51
|
+
const rl = readline.createInterface({
|
|
52
|
+
input: process.stdin,
|
|
53
|
+
output: process.stdout
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return new Promise((resolve) => {
|
|
57
|
+
rl.question(question, (answer) => {
|
|
58
|
+
rl.close();
|
|
59
|
+
resolve(answer.trim());
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 检查 @openai/codex 是否已安装
|
|
65
|
+
function checkCodexInstalled() {
|
|
66
|
+
try {
|
|
67
|
+
const output = execSync('npm list -g @openai/codex --depth=0', { encoding: 'utf8' });
|
|
68
|
+
return output.includes('@openai/codex');
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 获取 @openai/codex 版本号
|
|
75
|
+
function getCodexVersion() {
|
|
76
|
+
try {
|
|
77
|
+
const output = execSync('npm list -g @openai/codex --depth=0', { encoding: 'utf8' });
|
|
78
|
+
const match = output.match(/@openai\/codex@([\d.]+)/);
|
|
79
|
+
return match ? match[1] : '未知';
|
|
80
|
+
} catch (error) {
|
|
81
|
+
return '未知';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 安装 @openai/codex
|
|
86
|
+
function installCodex() {
|
|
87
|
+
const osType = getOS();
|
|
88
|
+
let command;
|
|
89
|
+
|
|
90
|
+
log('\n[检查] 检查 @openai/codex 安装状态...', 'cyan');
|
|
91
|
+
|
|
92
|
+
// 先检查是否已安装
|
|
93
|
+
if (checkCodexInstalled()) {
|
|
94
|
+
log('[成功] @openai/codex 已安装,跳过安装步骤', 'green');
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
log('[安装] 开始安装 @openai/codex...', 'cyan');
|
|
99
|
+
|
|
100
|
+
if (osType === 'windows') {
|
|
101
|
+
command = 'npm install -g @openai/codex --registry https://registry.npmmirror.com';
|
|
102
|
+
} else {
|
|
103
|
+
// 检查是否已经是 root 用户(通过 sudo 运行或直接 root)
|
|
104
|
+
const isRoot = process.getuid && process.getuid() === 0;
|
|
105
|
+
if (isRoot) {
|
|
106
|
+
command = 'npm install -g @openai/codex --registry https://registry.npmmirror.com';
|
|
107
|
+
} else {
|
|
108
|
+
command = 'sudo npm install -g @openai/codex --registry https://registry.npmmirror.com';
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
log(`[执行] ${command}`, 'yellow');
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
execSync(command, { stdio: 'inherit' });
|
|
116
|
+
log('[成功] @openai/codex 安装成功', 'green');
|
|
117
|
+
return true;
|
|
118
|
+
} catch (error) {
|
|
119
|
+
log('[错误] @openai/codex 安装失败', 'red');
|
|
120
|
+
log('\n[错误详情]', 'red');
|
|
121
|
+
|
|
122
|
+
// 显示错误信息
|
|
123
|
+
if (error.message) {
|
|
124
|
+
log(`错误信息: ${error.message}`, 'red');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 显示退出码
|
|
128
|
+
if (error.status !== undefined) {
|
|
129
|
+
log(`退出码: ${error.status}`, 'red');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 显示错误输出
|
|
133
|
+
if (error.stderr) {
|
|
134
|
+
log(`错误输出:\n${error.stderr.toString()}`, 'red');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 显示标准输出(可能包含有用信息)
|
|
138
|
+
if (error.stdout) {
|
|
139
|
+
log(`标准输出:\n${error.stdout.toString()}`, 'yellow');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
log('\n[提示] 你可以手动安装:', 'yellow');
|
|
143
|
+
log(` ${command}`, 'yellow');
|
|
144
|
+
log(' 然后重新运行此工具', 'yellow');
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 创建 .codex 目录
|
|
150
|
+
function createCodexDir() {
|
|
151
|
+
// 获取真实用户的 home 目录
|
|
152
|
+
let homeDir;
|
|
153
|
+
|
|
154
|
+
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
155
|
+
// Linux/Mac 使用 sudo 时,获取实际用户的 home 目录
|
|
156
|
+
const actualUser = process.env.SUDO_USER;
|
|
157
|
+
homeDir = `/home/${actualUser}`;
|
|
158
|
+
} else {
|
|
159
|
+
// Windows 或非 sudo 情况,使用默认
|
|
160
|
+
homeDir = os.homedir();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const codexDir = path.join(homeDir, '.codex');
|
|
164
|
+
|
|
165
|
+
log('\n[配置] 创建配置目录...', 'cyan');
|
|
166
|
+
|
|
167
|
+
if (!fs.existsSync(codexDir)) {
|
|
168
|
+
fs.mkdirSync(codexDir, { recursive: true });
|
|
169
|
+
|
|
170
|
+
// 如果是 sudo 运行,修改目录所有者为实际用户
|
|
171
|
+
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
172
|
+
const actualUser = process.env.SUDO_USER;
|
|
173
|
+
try {
|
|
174
|
+
execSync(`chown -R ${actualUser}:${actualUser} ${codexDir}`);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
// 忽略权限错误
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
log(`[成功] 创建目录: ${codexDir}`, 'green');
|
|
181
|
+
} else {
|
|
182
|
+
log(`[跳过] 目录已存在: ${codexDir}`, 'yellow');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return codexDir;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// 创建 config.toml 文件
|
|
189
|
+
function createConfigToml(codexDir) {
|
|
190
|
+
const configPath = path.join(codexDir, 'config.toml');
|
|
191
|
+
|
|
192
|
+
const configContent = `model_provider = "codex"
|
|
193
|
+
model = "gpt-5.1" #可更改为model = "gpt-5.1-codex或者gpt-5.1-codex-max"
|
|
194
|
+
model_reasoning_effort = "high"
|
|
195
|
+
disable_response_storage = true
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
[model_providers.codex]
|
|
199
|
+
name = "codex"
|
|
200
|
+
base_url = "https://cc.aicode.us.com/v1"
|
|
201
|
+
wire_api = "responses"
|
|
202
|
+
requires_openai_auth = true`;
|
|
203
|
+
|
|
204
|
+
log('\n[配置] 创建 config.toml 文件...', 'cyan');
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
208
|
+
|
|
209
|
+
// 如果是 sudo 运行,修改文件所有者为实际用户
|
|
210
|
+
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
211
|
+
const actualUser = process.env.SUDO_USER;
|
|
212
|
+
try {
|
|
213
|
+
execSync(`chown ${actualUser}:${actualUser} ${configPath}`);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
// 忽略权限错误
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
log(`[成功] 创建文件: ${configPath}`, 'green');
|
|
220
|
+
return true;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
log(`[错误] 创建 config.toml 失败: ${error.message}`, 'red');
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// 创建 auth.json 文件
|
|
228
|
+
async function createAuthJson(codexDir) {
|
|
229
|
+
const authPath = path.join(codexDir, 'auth.json');
|
|
230
|
+
|
|
231
|
+
log('\n[配置] 配置 API Key...', 'cyan');
|
|
232
|
+
|
|
233
|
+
// 显示粘贴提示
|
|
234
|
+
if (process.platform === 'win32') {
|
|
235
|
+
log('[提示] Windows 粘贴方式:', 'yellow');
|
|
236
|
+
log(' • CMD/PowerShell: 鼠标右键 或 Shift+Insert', 'yellow');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// 获取用户的 API Key
|
|
240
|
+
const apiKey = await getUserInput('请输入你的 OpenAI API Key (sk-xxx): ');
|
|
241
|
+
|
|
242
|
+
if (!apiKey || !apiKey.startsWith('sk-')) {
|
|
243
|
+
log('[错误] API Key 格式不正确,应该以 sk- 开头', 'red');
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const authContent = {
|
|
248
|
+
"OPENAI_API_KEY": apiKey
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
try {
|
|
252
|
+
fs.writeFileSync(authPath, JSON.stringify(authContent, null, 4), 'utf8');
|
|
253
|
+
|
|
254
|
+
// 如果是 sudo 运行,修改文件所有者为实际用户
|
|
255
|
+
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
256
|
+
const actualUser = process.env.SUDO_USER;
|
|
257
|
+
try {
|
|
258
|
+
execSync(`chown ${actualUser}:${actualUser} ${authPath}`);
|
|
259
|
+
} catch (error) {
|
|
260
|
+
// 忽略权限错误
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
log(`[成功] 创建文件: ${authPath}`, 'green');
|
|
265
|
+
return true;
|
|
266
|
+
} catch (error) {
|
|
267
|
+
log(`[错误] 创建 auth.json 失败: ${error.message}`, 'red');
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// 获取 VS Code 配置路径
|
|
273
|
+
function getVSCodeSettingsPath() {
|
|
274
|
+
let settingsPath;
|
|
275
|
+
|
|
276
|
+
if (process.platform === 'win32') {
|
|
277
|
+
// Windows 路径
|
|
278
|
+
const appData = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');
|
|
279
|
+
settingsPath = path.join(appData, 'Code', 'User', 'settings.json');
|
|
280
|
+
} else if (process.platform === 'darwin') {
|
|
281
|
+
// macOS 路径
|
|
282
|
+
let homeDir = os.homedir();
|
|
283
|
+
if (process.env.SUDO_USER) {
|
|
284
|
+
homeDir = `/Users/${process.env.SUDO_USER}`;
|
|
285
|
+
}
|
|
286
|
+
settingsPath = path.join(homeDir, 'Library', 'Application Support', 'Code', 'User', 'settings.json');
|
|
287
|
+
} else {
|
|
288
|
+
// Linux 路径
|
|
289
|
+
let homeDir = os.homedir();
|
|
290
|
+
if (process.env.SUDO_USER) {
|
|
291
|
+
homeDir = `/home/${process.env.SUDO_USER}`;
|
|
292
|
+
}
|
|
293
|
+
settingsPath = path.join(homeDir, '.config', 'Code', 'User', 'settings.json');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return settingsPath;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// 配置 VS Code settings.json(静默配置)
|
|
300
|
+
function configureVSCodeSettings() {
|
|
301
|
+
const settingsPath = getVSCodeSettingsPath();
|
|
302
|
+
const settingsDir = path.dirname(settingsPath);
|
|
303
|
+
|
|
304
|
+
// 如果 VS Code 目录不存在,说明未安装,直接返回
|
|
305
|
+
if (!fs.existsSync(settingsDir)) {
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
// 新的 ChatGPT 配置
|
|
311
|
+
const newSettings = {
|
|
312
|
+
"chatgpt.apiBase": "https://cc.aicode.us.com/v1",
|
|
313
|
+
"chatgpt.config": {
|
|
314
|
+
"preferred_auth_method": "apikey",
|
|
315
|
+
"model": "gpt-5",
|
|
316
|
+
"model_reasoning_effort": "high",
|
|
317
|
+
"wire_api": "responses"
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
let currentSettings = {};
|
|
322
|
+
|
|
323
|
+
// 如果文件存在,读取现有配置
|
|
324
|
+
if (fs.existsSync(settingsPath)) {
|
|
325
|
+
try {
|
|
326
|
+
const content = fs.readFileSync(settingsPath, 'utf8');
|
|
327
|
+
const trimmedContent = content.trim();
|
|
328
|
+
const cleanContent = trimmedContent.replace(/^\uFEFF/, '');
|
|
329
|
+
|
|
330
|
+
if (cleanContent) {
|
|
331
|
+
// 使用 JSONC 解析器处理带注释的 JSON
|
|
332
|
+
currentSettings = parseJSONC(cleanContent);
|
|
333
|
+
}
|
|
334
|
+
} catch (parseError) {
|
|
335
|
+
// JSON 解析失败,保持空对象
|
|
336
|
+
currentSettings = {};
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// 合并配置(保留原有配置,添加新配置)
|
|
341
|
+
const mergedSettings = { ...currentSettings, ...newSettings };
|
|
342
|
+
|
|
343
|
+
// 写入配置文件
|
|
344
|
+
fs.writeFileSync(settingsPath, JSON.stringify(mergedSettings, null, 2), 'utf8');
|
|
345
|
+
|
|
346
|
+
// 如果是通过 sudo 运行的,修改文件所有者
|
|
347
|
+
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
348
|
+
const actualUser = process.env.SUDO_USER;
|
|
349
|
+
const group = process.platform === 'darwin' ? 'staff' : actualUser;
|
|
350
|
+
try {
|
|
351
|
+
execSync(`chown -R ${actualUser}:${group} ${settingsDir}`);
|
|
352
|
+
} catch (error) {
|
|
353
|
+
// 忽略权限错误
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return true;
|
|
358
|
+
|
|
359
|
+
} catch (error) {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// 获取 Cursor 配置路径
|
|
365
|
+
function getCursorSettingsPath() {
|
|
366
|
+
let settingsPath;
|
|
367
|
+
|
|
368
|
+
if (process.platform === 'win32') {
|
|
369
|
+
// Windows 路径
|
|
370
|
+
const appData = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');
|
|
371
|
+
settingsPath = path.join(appData, 'Cursor', 'User', 'settings.json');
|
|
372
|
+
} else if (process.platform === 'darwin') {
|
|
373
|
+
// macOS 路径
|
|
374
|
+
let homeDir = os.homedir();
|
|
375
|
+
if (process.env.SUDO_USER) {
|
|
376
|
+
homeDir = `/Users/${process.env.SUDO_USER}`;
|
|
377
|
+
}
|
|
378
|
+
settingsPath = path.join(homeDir, 'Library', 'Application Support', 'Cursor', 'User', 'settings.json');
|
|
379
|
+
} else {
|
|
380
|
+
// Linux 路径
|
|
381
|
+
let homeDir = os.homedir();
|
|
382
|
+
if (process.env.SUDO_USER) {
|
|
383
|
+
homeDir = `/home/${process.env.SUDO_USER}`;
|
|
384
|
+
}
|
|
385
|
+
settingsPath = path.join(homeDir, '.config', 'Cursor', 'User', 'settings.json');
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return settingsPath;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// 配置 Cursor settings.json(静默配置)
|
|
392
|
+
function configureCursorSettings() {
|
|
393
|
+
const settingsPath = getCursorSettingsPath();
|
|
394
|
+
const settingsDir = path.dirname(settingsPath);
|
|
395
|
+
|
|
396
|
+
// 如果 Cursor 目录不存在,说明未安装,直接返回
|
|
397
|
+
if (!fs.existsSync(settingsDir)) {
|
|
398
|
+
return false;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
try {
|
|
402
|
+
// 新的 ChatGPT 配置
|
|
403
|
+
const newSettings = {
|
|
404
|
+
"chatgpt.apiBase": "https://cc.aicode.us.com/v1",
|
|
405
|
+
"chatgpt.config": {
|
|
406
|
+
"preferred_auth_method": "apikey",
|
|
407
|
+
"model": "gpt-5",
|
|
408
|
+
"model_reasoning_effort": "high",
|
|
409
|
+
"wire_api": "responses"
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
let currentSettings = {};
|
|
414
|
+
|
|
415
|
+
// 如果文件存在,读取现有配置
|
|
416
|
+
if (fs.existsSync(settingsPath)) {
|
|
417
|
+
try {
|
|
418
|
+
const content = fs.readFileSync(settingsPath, 'utf8');
|
|
419
|
+
const trimmedContent = content.trim();
|
|
420
|
+
|
|
421
|
+
// 移除 UTF-8 BOM 标记(如果存在)
|
|
422
|
+
const cleanContent = trimmedContent.replace(/^\uFEFF/, '');
|
|
423
|
+
|
|
424
|
+
if (cleanContent) {
|
|
425
|
+
// 使用 JSONC 解析器处理带注释的 JSON
|
|
426
|
+
currentSettings = parseJSONC(cleanContent);
|
|
427
|
+
}
|
|
428
|
+
} catch (parseError) {
|
|
429
|
+
// JSON 解析失败,保持空对象
|
|
430
|
+
currentSettings = {};
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// 合并配置(保留原有配置,添加新配置)
|
|
435
|
+
const mergedSettings = { ...currentSettings, ...newSettings };
|
|
436
|
+
|
|
437
|
+
// 写入配置文件
|
|
438
|
+
fs.writeFileSync(settingsPath, JSON.stringify(mergedSettings, null, 2), 'utf8');
|
|
439
|
+
|
|
440
|
+
// 如果是通过 sudo 运行的,修改文件所有者
|
|
441
|
+
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
442
|
+
const actualUser = process.env.SUDO_USER;
|
|
443
|
+
const group = process.platform === 'darwin' ? 'staff' : actualUser;
|
|
444
|
+
try {
|
|
445
|
+
execSync(`chown -R ${actualUser}:${group} ${settingsDir}`);
|
|
446
|
+
} catch (error) {
|
|
447
|
+
// 忽略权限错误
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return true;
|
|
452
|
+
|
|
453
|
+
} catch (error) {
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// 显示完成信息
|
|
459
|
+
function showCompletionInfo() {
|
|
460
|
+
const osType = getOS();
|
|
461
|
+
|
|
462
|
+
// 根据操作系统获取实际的 .codex 目录路径
|
|
463
|
+
let codexPath;
|
|
464
|
+
if (osType === 'windows') {
|
|
465
|
+
const homeDir = os.homedir();
|
|
466
|
+
codexPath = path.join(homeDir, '.codex');
|
|
467
|
+
} else if (osType === 'mac' || osType === 'linux') {
|
|
468
|
+
if (process.env.SUDO_USER) {
|
|
469
|
+
const actualUser = process.env.SUDO_USER;
|
|
470
|
+
const homeDir = osType === 'mac' ? `/Users/${actualUser}` : `/home/${actualUser}`;
|
|
471
|
+
codexPath = path.join(homeDir, '.codex');
|
|
472
|
+
} else {
|
|
473
|
+
codexPath = path.join(os.homedir(), '.codex');
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
const configPath = path.join(codexPath, 'config.toml');
|
|
478
|
+
const authPath = path.join(codexPath, 'auth.json');
|
|
479
|
+
|
|
480
|
+
log('\n', 'reset');
|
|
481
|
+
log('=' + '='.repeat(68) + '=', 'yellow');
|
|
482
|
+
log(' 欢迎使用 Codex 开始您的 AI 编程之旅', 'yellow');
|
|
483
|
+
log('=' + '='.repeat(68) + '=', 'yellow');
|
|
484
|
+
|
|
485
|
+
log('\n[已完成操作]', 'cyan');
|
|
486
|
+
log(' * 安装 @openai/codex', 'green');
|
|
487
|
+
log(` * 创建目录 ${codexPath}`, 'green');
|
|
488
|
+
log(' * 创建配置文件 config.toml', 'green');
|
|
489
|
+
log(' * 创建认证文件 auth.json', 'green');
|
|
490
|
+
|
|
491
|
+
log('\n[配置文件路径]', 'cyan');
|
|
492
|
+
log(' config.toml (可在此处修改域名url):', 'reset');
|
|
493
|
+
log(` ${configPath}`, 'yellow');
|
|
494
|
+
log('', 'reset');
|
|
495
|
+
log(' auth.json (可在此处修改key):', 'reset');
|
|
496
|
+
log(` ${authPath}`, 'yellow');
|
|
497
|
+
|
|
498
|
+
log('\n[使用方式]', 'cyan');
|
|
499
|
+
log(' 在终端输入以下命令启动 Codex:', 'reset');
|
|
500
|
+
log(' codex', 'yellow');
|
|
501
|
+
|
|
502
|
+
const codexVersion = getCodexVersion();
|
|
503
|
+
log('\n Codex 版本: v' + codexVersion, 'reset');
|
|
504
|
+
log(' 支持系统: Windows 10/11 • macOS • Linux', 'reset');
|
|
505
|
+
log('\n', 'reset');
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// 主函数
|
|
509
|
+
async function main() {
|
|
510
|
+
console.clear();
|
|
511
|
+
|
|
512
|
+
// ASCII Logo - 水平渐变 (蓝→紫→粉)
|
|
513
|
+
log('\n', 'reset');
|
|
514
|
+
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');
|
|
515
|
+
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');
|
|
516
|
+
console.log(' \x1b[38;5;45m██║ \x1b[38;5;81m██║ ██║\x1b[38;5;117m██║ ██║\x1b[38;5;153m█████╗ \x1b[38;5;189m ╚███╔╝ \x1b[0m');
|
|
517
|
+
console.log(' \x1b[38;5;75m██║ \x1b[38;5;111m██║ ██║\x1b[38;5;147m██║ ██║\x1b[38;5;183m██╔══╝ \x1b[38;5;219m ██╔██╗ \x1b[0m');
|
|
518
|
+
console.log(' \x1b[38;5;111m╚██████╗\x1b[38;5;147m╚██████╔╝\x1b[38;5;183m██████╔╝\x1b[38;5;219m███████╗\x1b[38;5;225m██╔╝ ██╗\x1b[0m');
|
|
519
|
+
console.log(' \x1b[38;5;147m╚═════╝ \x1b[38;5;183m╚═════╝ \x1b[38;5;219m╚═════╝ \x1b[38;5;225m╚══════╝\x1b[38;5;231m╚═╝ ╚═╝\x1b[0m');
|
|
520
|
+
log('\n pumpkinai Codex config Tool', 'magenta');
|
|
521
|
+
log(' ' + '='.repeat(44), 'cyan');
|
|
522
|
+
log('', 'reset');
|
|
523
|
+
|
|
524
|
+
try {
|
|
525
|
+
// 1. 安装 @openai/codex
|
|
526
|
+
const installSuccess = installCodex();
|
|
527
|
+
if (!installSuccess) {
|
|
528
|
+
process.exit(1);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// 2. 创建 .codex 目录
|
|
532
|
+
const codexDir = createCodexDir();
|
|
533
|
+
|
|
534
|
+
// 3. 创建 config.toml
|
|
535
|
+
const configSuccess = createConfigToml(codexDir);
|
|
536
|
+
if (!configSuccess) {
|
|
537
|
+
process.exit(1);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// 4. 创建 auth.json
|
|
541
|
+
const authSuccess = await createAuthJson(codexDir);
|
|
542
|
+
if (!authSuccess) {
|
|
543
|
+
process.exit(1);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// 5. 配置 VS Code settings.json
|
|
547
|
+
configureVSCodeSettings();
|
|
548
|
+
|
|
549
|
+
// 6. 配置 Cursor settings.json
|
|
550
|
+
configureCursorSettings();
|
|
551
|
+
|
|
552
|
+
// 7. 显示完成信息
|
|
553
|
+
showCompletionInfo();
|
|
554
|
+
|
|
555
|
+
} catch (error) {
|
|
556
|
+
log(`\n[错误] 安装过程中出现错误: ${error.message}`, 'red');
|
|
557
|
+
process.exit(1);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// 如果直接运行此脚本
|
|
562
|
+
if (require.main === module) {
|
|
563
|
+
main();
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// 导出函数供其他模块使用
|
|
567
|
+
module.exports = {
|
|
568
|
+
main,
|
|
569
|
+
installCodex,
|
|
570
|
+
createCodexDir,
|
|
571
|
+
createConfigToml,
|
|
572
|
+
createAuthJson
|
|
573
|
+
};
|
package/codex-setup.js
CHANGED
|
@@ -312,7 +312,7 @@ function configureVSCodeSettings() {
|
|
|
312
312
|
"chatgpt.apiBase": "https://code.ppchat.vip/v1",
|
|
313
313
|
"chatgpt.config": {
|
|
314
314
|
"preferred_auth_method": "apikey",
|
|
315
|
-
"model": "gpt-5",
|
|
315
|
+
"model": "gpt-5.1",
|
|
316
316
|
"model_reasoning_effort": "high",
|
|
317
317
|
"wire_api": "responses"
|
|
318
318
|
}
|
|
@@ -404,7 +404,7 @@ function configureCursorSettings() {
|
|
|
404
404
|
"chatgpt.apiBase": "https://code.ppchat.vip/v1",
|
|
405
405
|
"chatgpt.config": {
|
|
406
406
|
"preferred_auth_method": "apikey",
|
|
407
|
-
"model": "gpt-5",
|
|
407
|
+
"model": "gpt-5.1",
|
|
408
408
|
"model_reasoning_effort": "high",
|
|
409
409
|
"wire_api": "responses"
|
|
410
410
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumpkinai-config",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
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
|
"claude-config": "./claude-setup.js",
|
|
9
|
-
"claude-au": "./claude-au.js"
|
|
9
|
+
"claude-au": "./claude-au.js",
|
|
10
|
+
"claude-api": "./claude-api.js"
|
|
10
11
|
},
|
|
11
12
|
"scripts": {
|
|
12
13
|
"test": "node codex-setup.js",
|