pumpkinai-config 1.0.14 → 1.0.17
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 +123 -66
- package/claude-setup.js +116 -204
- package/codex-api.js +1 -1
- package/codex-setup.js +1 -1
- package/package.json +1 -2
- package/templates/auth.json +0 -3
- package/templates/config.toml +0 -11
package/claude-api.js
CHANGED
|
@@ -134,77 +134,130 @@ function installClaude() {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
//
|
|
138
|
-
function
|
|
139
|
-
log('\n[配置]
|
|
137
|
+
// 设置系统用户环境变量
|
|
138
|
+
function setupEnvironmentVariables(apiKey) {
|
|
139
|
+
log('\n[配置] 设置系统用户环境变量...', 'cyan');
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
const osType = getOS();
|
|
142
142
|
let homeDir;
|
|
143
143
|
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
144
|
-
// Linux/Mac 使用 sudo 时,获取实际用户的 home 目录
|
|
145
144
|
const actualUser = process.env.SUDO_USER;
|
|
146
145
|
homeDir = process.platform === 'darwin' ? `/Users/${actualUser}` : `/home/${actualUser}`;
|
|
147
146
|
} else {
|
|
148
147
|
homeDir = os.homedir();
|
|
149
148
|
}
|
|
150
149
|
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
150
|
+
// 需要设置的环境变量
|
|
151
|
+
const envVars = {
|
|
152
|
+
ANTHROPIC_AUTH_TOKEN: apiKey,
|
|
153
|
+
ANTHROPIC_BASE_URL: "https://new.aicode.us.com",
|
|
154
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"
|
|
155
|
+
};
|
|
156
156
|
|
|
157
157
|
try {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
158
|
+
if (osType === 'windows') {
|
|
159
|
+
// Windows: 使用 setx 设置用户环境变量(永久生效)
|
|
160
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
161
|
+
try {
|
|
162
|
+
execSync(`setx ${key} "${value}"`, { stdio: 'pipe' });
|
|
163
|
+
log(`[成功] 设置环境变量: ${key}`, 'green');
|
|
164
|
+
} catch (error) {
|
|
165
|
+
log(`[错误] 设置环境变量 ${key} 失败: ${error.message}`, 'red');
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
log('[提示] 请重新打开终端使环境变量生效', 'yellow');
|
|
170
|
+
return true;
|
|
171
|
+
|
|
172
|
+
} else if (osType === 'mac') {
|
|
173
|
+
// macOS: 写入 ~/.zshrc
|
|
174
|
+
const zshrcPath = path.join(homeDir, '.zshrc');
|
|
175
|
+
let zshrcContent = '';
|
|
176
|
+
if (fs.existsSync(zshrcPath)) {
|
|
177
|
+
zshrcContent = fs.readFileSync(zshrcPath, 'utf8');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// 构建环境变量行
|
|
181
|
+
let envLines = '\n# Claude Code 环境变量 (pumpkinai)\n';
|
|
182
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
183
|
+
const envLine = `export ${key}="${value}"`;
|
|
184
|
+
if (!zshrcContent.includes(`export ${key}=`)) {
|
|
185
|
+
envLines += envLine + '\n';
|
|
186
|
+
log(`[成功] 添加环境变量: ${key}`, 'green');
|
|
187
|
+
} else {
|
|
188
|
+
// 替换已存在的环境变量
|
|
189
|
+
const regex = new RegExp(`export ${key}=.*`, 'g');
|
|
190
|
+
zshrcContent = zshrcContent.replace(regex, envLine);
|
|
191
|
+
log(`[更新] 更新环境变量: ${key}`, 'yellow');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 写入文件
|
|
196
|
+
if (envLines !== '\n# Claude Code 环境变量 (pumpkinai)\n') {
|
|
197
|
+
const newContent = zshrcContent + envLines;
|
|
198
|
+
fs.writeFileSync(zshrcPath, newContent, 'utf8');
|
|
199
|
+
} else {
|
|
200
|
+
fs.writeFileSync(zshrcPath, zshrcContent, 'utf8');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// 修改文件所有者
|
|
204
|
+
if (process.env.SUDO_USER) {
|
|
205
|
+
const actualUser = process.env.SUDO_USER;
|
|
206
|
+
try {
|
|
207
|
+
execSync(`chown ${actualUser}:staff ${zshrcPath}`);
|
|
208
|
+
} catch (error) {}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
log(`[成功] 环境变量已写入: ${zshrcPath}`, 'green');
|
|
212
|
+
log('[提示] 请重新打开终端或运行: source ~/.zshrc', 'yellow');
|
|
213
|
+
return true;
|
|
165
214
|
|
|
166
|
-
// 创建 .claude 目录
|
|
167
|
-
if (!fs.existsSync(claudeDir)) {
|
|
168
|
-
fs.mkdirSync(claudeDir, { recursive: true });
|
|
169
|
-
log(`[成功] 创建目录: ${claudeDir}`, 'green');
|
|
170
215
|
} else {
|
|
171
|
-
|
|
172
|
-
|
|
216
|
+
// Linux: 写入 ~/.bashrc
|
|
217
|
+
const bashrcPath = path.join(homeDir, '.bashrc');
|
|
218
|
+
let bashrcContent = '';
|
|
219
|
+
if (fs.existsSync(bashrcPath)) {
|
|
220
|
+
bashrcContent = fs.readFileSync(bashrcPath, 'utf8');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// 构建环境变量行
|
|
224
|
+
let envLines = '\n# Claude Code 环境变量 (pumpkinai)\n';
|
|
225
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
226
|
+
const envLine = `export ${key}="${value}"`;
|
|
227
|
+
if (!bashrcContent.includes(`export ${key}=`)) {
|
|
228
|
+
envLines += envLine + '\n';
|
|
229
|
+
log(`[成功] 添加环境变量: ${key}`, 'green');
|
|
230
|
+
} else {
|
|
231
|
+
// 替换已存在的环境变量
|
|
232
|
+
const regex = new RegExp(`export ${key}=.*`, 'g');
|
|
233
|
+
bashrcContent = bashrcContent.replace(regex, envLine);
|
|
234
|
+
log(`[更新] 更新环境变量: ${key}`, 'yellow');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
173
237
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
238
|
+
// 写入文件
|
|
239
|
+
if (envLines !== '\n# Claude Code 环境变量 (pumpkinai)\n') {
|
|
240
|
+
const newContent = bashrcContent + envLines;
|
|
241
|
+
fs.writeFileSync(bashrcPath, newContent, 'utf8');
|
|
242
|
+
} else {
|
|
243
|
+
fs.writeFileSync(bashrcPath, bashrcContent, 'utf8');
|
|
179
244
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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');
|
|
245
|
+
|
|
246
|
+
// 修改文件所有者
|
|
247
|
+
if (process.env.SUDO_USER) {
|
|
248
|
+
const actualUser = process.env.SUDO_USER;
|
|
249
|
+
try {
|
|
250
|
+
execSync(`chown ${actualUser}:${actualUser} ${bashrcPath}`);
|
|
251
|
+
} catch (error) {}
|
|
202
252
|
}
|
|
253
|
+
|
|
254
|
+
log(`[成功] 环境变量已写入: ${bashrcPath}`, 'green');
|
|
255
|
+
log('[提示] 请重新打开终端或运行: source ~/.bashrc', 'yellow');
|
|
256
|
+
return true;
|
|
203
257
|
}
|
|
204
258
|
|
|
205
|
-
return true;
|
|
206
259
|
} catch (error) {
|
|
207
|
-
log(`[错误]
|
|
260
|
+
log(`[错误] 设置环境变量失败: ${error.message}`, 'red');
|
|
208
261
|
return false;
|
|
209
262
|
}
|
|
210
263
|
}
|
|
@@ -227,14 +280,14 @@ async function configureEnvironment() {
|
|
|
227
280
|
return false;
|
|
228
281
|
}
|
|
229
282
|
|
|
230
|
-
return
|
|
283
|
+
return setupEnvironmentVariables(apiKey);
|
|
231
284
|
}
|
|
232
285
|
|
|
233
286
|
// 显示完成信息
|
|
234
287
|
function showCompletionInfo() {
|
|
235
288
|
const osType = getOS();
|
|
236
289
|
|
|
237
|
-
//
|
|
290
|
+
// 获取 home 目录
|
|
238
291
|
let homeDir;
|
|
239
292
|
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
240
293
|
const actualUser = process.env.SUDO_USER;
|
|
@@ -242,9 +295,6 @@ function showCompletionInfo() {
|
|
|
242
295
|
} else {
|
|
243
296
|
homeDir = os.homedir();
|
|
244
297
|
}
|
|
245
|
-
const claudeDir = path.join(homeDir, '.claude');
|
|
246
|
-
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
247
|
-
const configPath = path.join(claudeDir, 'config.json');
|
|
248
298
|
|
|
249
299
|
log('\n', 'reset');
|
|
250
300
|
log('=' + '='.repeat(68) + '=', 'yellow');
|
|
@@ -253,15 +303,21 @@ function showCompletionInfo() {
|
|
|
253
303
|
|
|
254
304
|
log('\n[已完成操作]', 'cyan');
|
|
255
305
|
log(' * 安装 @anthropic-ai/claude-code', 'green');
|
|
256
|
-
log(' *
|
|
257
|
-
log(' *
|
|
306
|
+
log(' * 设置用户环境变量 ANTHROPIC_AUTH_TOKEN', 'green');
|
|
307
|
+
log(' * 设置用户环境变量 ANTHROPIC_BASE_URL', 'green');
|
|
308
|
+
log(' * 设置用户环境变量 ANTHROPIC_SMALL_FAST_MODEL', 'green');
|
|
258
309
|
|
|
259
|
-
log('\n[
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
310
|
+
log('\n[环境变量配置]', 'cyan');
|
|
311
|
+
if (osType === 'windows') {
|
|
312
|
+
log(' 环境变量已通过 setx 设置到用户环境变量', 'reset');
|
|
313
|
+
log(' 可在 系统属性 -> 高级 -> 环境变量 中查看', 'yellow');
|
|
314
|
+
} else if (osType === 'mac') {
|
|
315
|
+
log(' 环境变量已写入: ~/.zshrc', 'reset');
|
|
316
|
+
log(` ${path.join(homeDir, '.zshrc')}`, 'yellow');
|
|
317
|
+
} else {
|
|
318
|
+
log(' 环境变量已写入: ~/.bashrc', 'reset');
|
|
319
|
+
log(` ${path.join(homeDir, '.bashrc')}`, 'yellow');
|
|
320
|
+
}
|
|
265
321
|
|
|
266
322
|
log('\n[启动方式]', 'cyan');
|
|
267
323
|
|
|
@@ -330,5 +386,6 @@ if (require.main === module) {
|
|
|
330
386
|
module.exports = {
|
|
331
387
|
main,
|
|
332
388
|
installClaude,
|
|
333
|
-
configureEnvironment
|
|
389
|
+
configureEnvironment,
|
|
390
|
+
setupEnvironmentVariables
|
|
334
391
|
};
|
package/claude-setup.js
CHANGED
|
@@ -86,14 +86,14 @@ function installClaude() {
|
|
|
86
86
|
log('[安装] 开始安装 @anthropic-ai/claude-code...', 'cyan');
|
|
87
87
|
|
|
88
88
|
if (osType === 'windows') {
|
|
89
|
-
command = 'npm install -g @anthropic-ai/claude-code
|
|
89
|
+
command = 'npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
|
|
90
90
|
} else {
|
|
91
91
|
// 检查是否已经是 root 用户(通过 sudo 运行或直接 root)
|
|
92
92
|
const isRoot = process.getuid && process.getuid() === 0;
|
|
93
93
|
if (isRoot) {
|
|
94
|
-
command = 'npm install -g @anthropic-ai/claude-code
|
|
94
|
+
command = 'npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
|
|
95
95
|
} else {
|
|
96
|
-
command = 'sudo npm install -g @anthropic-ai/claude-code
|
|
96
|
+
command = 'sudo npm install -g @anthropic-ai/claude-code --registry https://registry.npmmirror.com';
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
@@ -134,107 +134,9 @@ function installClaude() {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
//
|
|
138
|
-
function
|
|
139
|
-
log('\n[配置]
|
|
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 配置
|
|
175
|
-
const settings = {
|
|
176
|
-
env: {
|
|
177
|
-
ANTHROPIC_AUTH_TOKEN: apiKey,
|
|
178
|
-
ANTHROPIC_BASE_URL: "https://code.ppchat.vip"
|
|
179
|
-
},
|
|
180
|
-
autoUpdaterStatus: "disabled",
|
|
181
|
-
autoUpdates: false
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
|
|
185
|
-
log(`[成功] 创建配置文件: ${settingsPath}`, 'green');
|
|
186
|
-
|
|
187
|
-
// 创建 config.json 配置
|
|
188
|
-
const config = {
|
|
189
|
-
primaryApiKey: "1"
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
|
|
193
|
-
log(`[成功] 创建配置文件: ${configPath}`, 'green');
|
|
194
|
-
|
|
195
|
-
// 如果是通过 sudo 运行的,修改文件所有者
|
|
196
|
-
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
197
|
-
const actualUser = process.env.SUDO_USER;
|
|
198
|
-
const group = process.platform === 'darwin' ? 'staff' : actualUser;
|
|
199
|
-
try {
|
|
200
|
-
execSync(`chown -R ${actualUser}:${group} ${claudeDir}`);
|
|
201
|
-
log(`[成功] 设置文件所有者为: ${actualUser}`, 'green');
|
|
202
|
-
} catch (error) {
|
|
203
|
-
log(`[警告] 无法设置文件所有者: ${error.message}`, 'yellow');
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return true;
|
|
208
|
-
} catch (error) {
|
|
209
|
-
log(`[错误] 创建配置文件失败: ${error.message}`, 'red');
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// 配置 Claude
|
|
215
|
-
async function configureEnvironment() {
|
|
216
|
-
log('\n[配置] 配置 API Key...', 'cyan');
|
|
217
|
-
|
|
218
|
-
// 显示粘贴提示
|
|
219
|
-
if (process.platform === 'win32') {
|
|
220
|
-
log('[提示] Windows 粘贴方式:', 'yellow');
|
|
221
|
-
log(' • CMD/PowerShell: 鼠标右键 或 Shift+Insert', 'yellow');
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const apiKey = await getUserInput('请输入你的 Claude API Key (sk-xxx): ');
|
|
226
|
-
|
|
227
|
-
if (!apiKey || !apiKey.startsWith('sk-')) {
|
|
228
|
-
log('[错误] API Key 格式不正确,应该以 sk- 开头', 'red');
|
|
229
|
-
return false;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
return createClaudeConfig(apiKey);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// 配置环境变量到系统
|
|
236
|
-
function setupEnvironmentVariable() {
|
|
237
|
-
log('\n[配置] 设置系统环境变量...', 'cyan');
|
|
137
|
+
// 设置系统用户环境变量
|
|
138
|
+
function setupEnvironmentVariables(apiKey) {
|
|
139
|
+
log('\n[配置] 设置系统用户环境变量...', 'cyan');
|
|
238
140
|
|
|
239
141
|
const osType = getOS();
|
|
240
142
|
let homeDir;
|
|
@@ -245,122 +147,112 @@ function setupEnvironmentVariable() {
|
|
|
245
147
|
homeDir = os.homedir();
|
|
246
148
|
}
|
|
247
149
|
|
|
248
|
-
|
|
150
|
+
// 需要设置的环境变量
|
|
151
|
+
const envVars = {
|
|
152
|
+
ANTHROPIC_AUTH_TOKEN: apiKey,
|
|
153
|
+
ANTHROPIC_BASE_URL: "https://code.ppchat.vip",
|
|
154
|
+
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS:"1"
|
|
155
|
+
};
|
|
249
156
|
|
|
250
157
|
try {
|
|
251
158
|
if (osType === 'windows') {
|
|
252
159
|
// Windows: 使用 setx 设置用户环境变量(永久生效)
|
|
253
|
-
|
|
254
|
-
execSync('setx CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS "1"', { stdio: 'pipe' });
|
|
255
|
-
log('[成功] 已设置 Windows 用户环境变量', 'green');
|
|
256
|
-
log('[提示] 请重新打开终端使环境变量生效', 'yellow');
|
|
257
|
-
return true;
|
|
258
|
-
} catch (error) {
|
|
259
|
-
log('[警告] 无法使用 setx 设置环境变量', 'yellow');
|
|
260
|
-
|
|
261
|
-
// 创建 PowerShell Profile 配置
|
|
160
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
262
161
|
try {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const profileDir = path.dirname(profilePath);
|
|
268
|
-
if (!fs.existsSync(profileDir)) {
|
|
269
|
-
fs.mkdirSync(profileDir, { recursive: true });
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// 读取现有 Profile 内容
|
|
273
|
-
let profileContent = '';
|
|
274
|
-
if (fs.existsSync(profilePath)) {
|
|
275
|
-
profileContent = fs.readFileSync(profilePath, 'utf8');
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// 检查是否已存在该环境变量配置
|
|
279
|
-
const psEnvLine = '$env:CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS = "1"';
|
|
280
|
-
if (!profileContent.includes('CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS')) {
|
|
281
|
-
// 追加环境变量到 Profile
|
|
282
|
-
const newContent = profileContent + (profileContent ? '\n' : '') +
|
|
283
|
-
'# Claude Code 环境变量\n' + psEnvLine + '\n';
|
|
284
|
-
fs.writeFileSync(profilePath, newContent, 'utf8');
|
|
285
|
-
log(`[成功] 已添加环境变量到 PowerShell Profile: ${profilePath}`, 'green');
|
|
286
|
-
log('[提示] 请重新打开 PowerShell 使环境变量生效', 'yellow');
|
|
287
|
-
} else {
|
|
288
|
-
log('[提示] PowerShell Profile 中已存在该环境变量', 'yellow');
|
|
289
|
-
}
|
|
290
|
-
return true;
|
|
291
|
-
} catch (psError) {
|
|
292
|
-
log(`[警告] PowerShell Profile 配置失败: ${psError.message}`, 'yellow');
|
|
293
|
-
log('[提示] 请联系淘宝或者技术客服解决', 'yellow');
|
|
162
|
+
execSync(`setx ${key} "${value}"`, { stdio: 'pipe' });
|
|
163
|
+
log(`[成功] 设置环境变量: ${key}`, 'green');
|
|
164
|
+
} catch (error) {
|
|
165
|
+
log(`[错误] 设置环境变量 ${key} 失败: ${error.message}`, 'red');
|
|
294
166
|
return false;
|
|
295
167
|
}
|
|
296
168
|
}
|
|
169
|
+
log('[提示] 请重新打开终端使环境变量生效', 'yellow');
|
|
170
|
+
return true;
|
|
297
171
|
|
|
298
172
|
} else if (osType === 'mac') {
|
|
299
173
|
// macOS: 写入 ~/.zshrc
|
|
300
174
|
const zshrcPath = path.join(homeDir, '.zshrc');
|
|
301
|
-
|
|
302
|
-
// 读取现有内容
|
|
303
175
|
let zshrcContent = '';
|
|
304
176
|
if (fs.existsSync(zshrcPath)) {
|
|
305
177
|
zshrcContent = fs.readFileSync(zshrcPath, 'utf8');
|
|
306
178
|
}
|
|
307
179
|
|
|
308
|
-
//
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
execSync(`chown ${actualUser}:staff ${zshrcPath}`);
|
|
321
|
-
} catch (error) {
|
|
322
|
-
}
|
|
180
|
+
// 构建环境变量行
|
|
181
|
+
let envLines = '\n# Claude Code 环境变量 (pumpkinai)\n';
|
|
182
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
183
|
+
const envLine = `export ${key}="${value}"`;
|
|
184
|
+
if (!zshrcContent.includes(`export ${key}=`)) {
|
|
185
|
+
envLines += envLine + '\n';
|
|
186
|
+
log(`[成功] 添加环境变量: ${key}`, 'green');
|
|
187
|
+
} else {
|
|
188
|
+
// 替换已存在的环境变量
|
|
189
|
+
const regex = new RegExp(`export ${key}=.*`, 'g');
|
|
190
|
+
zshrcContent = zshrcContent.replace(regex, envLine);
|
|
191
|
+
log(`[更新] 更新环境变量: ${key}`, 'yellow');
|
|
323
192
|
}
|
|
193
|
+
}
|
|
324
194
|
|
|
325
|
-
|
|
326
|
-
|
|
195
|
+
// 写入文件
|
|
196
|
+
if (envLines !== '\n# Claude Code 环境变量 (pumpkinai)\n') {
|
|
197
|
+
const newContent = zshrcContent + envLines;
|
|
198
|
+
fs.writeFileSync(zshrcPath, newContent, 'utf8');
|
|
327
199
|
} else {
|
|
328
|
-
|
|
200
|
+
fs.writeFileSync(zshrcPath, zshrcContent, 'utf8');
|
|
329
201
|
}
|
|
202
|
+
|
|
203
|
+
// 修改文件所有者
|
|
204
|
+
if (process.env.SUDO_USER) {
|
|
205
|
+
const actualUser = process.env.SUDO_USER;
|
|
206
|
+
try {
|
|
207
|
+
execSync(`chown ${actualUser}:staff ${zshrcPath}`);
|
|
208
|
+
} catch (error) {}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
log(`[成功] 环境变量已写入: ${zshrcPath}`, 'green');
|
|
212
|
+
log('[提示] 请重新打开终端或运行: source ~/.zshrc', 'yellow');
|
|
330
213
|
return true;
|
|
331
214
|
|
|
332
215
|
} else {
|
|
333
216
|
// Linux: 写入 ~/.bashrc
|
|
334
217
|
const bashrcPath = path.join(homeDir, '.bashrc');
|
|
335
|
-
|
|
336
|
-
// 读取现有内容
|
|
337
218
|
let bashrcContent = '';
|
|
338
219
|
if (fs.existsSync(bashrcPath)) {
|
|
339
220
|
bashrcContent = fs.readFileSync(bashrcPath, 'utf8');
|
|
340
221
|
}
|
|
341
222
|
|
|
342
|
-
//
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
execSync(`chown ${actualUser}:${actualUser} ${bashrcPath}`);
|
|
355
|
-
} catch (error) {
|
|
356
|
-
}
|
|
223
|
+
// 构建环境变量行
|
|
224
|
+
let envLines = '\n# Claude Code 环境变量 (pumpkinai)\n';
|
|
225
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
226
|
+
const envLine = `export ${key}="${value}"`;
|
|
227
|
+
if (!bashrcContent.includes(`export ${key}=`)) {
|
|
228
|
+
envLines += envLine + '\n';
|
|
229
|
+
log(`[成功] 添加环境变量: ${key}`, 'green');
|
|
230
|
+
} else {
|
|
231
|
+
// 替换已存在的环境变量
|
|
232
|
+
const regex = new RegExp(`export ${key}=.*`, 'g');
|
|
233
|
+
bashrcContent = bashrcContent.replace(regex, envLine);
|
|
234
|
+
log(`[更新] 更新环境变量: ${key}`, 'yellow');
|
|
357
235
|
}
|
|
236
|
+
}
|
|
358
237
|
|
|
359
|
-
|
|
360
|
-
|
|
238
|
+
// 写入文件
|
|
239
|
+
if (envLines !== '\n# Claude Code 环境变量 (pumpkinai)\n') {
|
|
240
|
+
const newContent = bashrcContent + envLines;
|
|
241
|
+
fs.writeFileSync(bashrcPath, newContent, 'utf8');
|
|
361
242
|
} else {
|
|
362
|
-
|
|
243
|
+
fs.writeFileSync(bashrcPath, bashrcContent, 'utf8');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// 修改文件所有者
|
|
247
|
+
if (process.env.SUDO_USER) {
|
|
248
|
+
const actualUser = process.env.SUDO_USER;
|
|
249
|
+
try {
|
|
250
|
+
execSync(`chown ${actualUser}:${actualUser} ${bashrcPath}`);
|
|
251
|
+
} catch (error) {}
|
|
363
252
|
}
|
|
253
|
+
|
|
254
|
+
log(`[成功] 环境变量已写入: ${bashrcPath}`, 'green');
|
|
255
|
+
log('[提示] 请重新打开终端或运行: source ~/.bashrc', 'yellow');
|
|
364
256
|
return true;
|
|
365
257
|
}
|
|
366
258
|
|
|
@@ -370,11 +262,32 @@ function setupEnvironmentVariable() {
|
|
|
370
262
|
}
|
|
371
263
|
}
|
|
372
264
|
|
|
265
|
+
// 配置 Claude
|
|
266
|
+
async function configureEnvironment() {
|
|
267
|
+
log('\n[配置] 配置 API Key...', 'cyan');
|
|
268
|
+
|
|
269
|
+
// 显示粘贴提示
|
|
270
|
+
if (process.platform === 'win32') {
|
|
271
|
+
log('[提示] Windows 粘贴方式:', 'yellow');
|
|
272
|
+
log(' • CMD/PowerShell: 鼠标右键 或 Shift+Insert', 'yellow');
|
|
273
|
+
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const apiKey = await getUserInput('请输入你的 Claude API Key (sk-xxx): ');
|
|
277
|
+
|
|
278
|
+
if (!apiKey || !apiKey.startsWith('sk-')) {
|
|
279
|
+
log('[错误] API Key 格式不正确,应该以 sk- 开头', 'red');
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return setupEnvironmentVariables(apiKey);
|
|
284
|
+
}
|
|
285
|
+
|
|
373
286
|
// 显示完成信息
|
|
374
287
|
function showCompletionInfo() {
|
|
375
288
|
const osType = getOS();
|
|
376
289
|
|
|
377
|
-
//
|
|
290
|
+
// 获取 home 目录
|
|
378
291
|
let homeDir;
|
|
379
292
|
if (process.platform !== 'win32' && process.env.SUDO_USER) {
|
|
380
293
|
const actualUser = process.env.SUDO_USER;
|
|
@@ -382,9 +295,6 @@ function showCompletionInfo() {
|
|
|
382
295
|
} else {
|
|
383
296
|
homeDir = os.homedir();
|
|
384
297
|
}
|
|
385
|
-
const claudeDir = path.join(homeDir, '.claude');
|
|
386
|
-
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
387
|
-
const configPath = path.join(claudeDir, 'config.json');
|
|
388
298
|
|
|
389
299
|
log('\n', 'reset');
|
|
390
300
|
log('=' + '='.repeat(68) + '=', 'yellow');
|
|
@@ -393,16 +303,21 @@ function showCompletionInfo() {
|
|
|
393
303
|
|
|
394
304
|
log('\n[已完成操作]', 'cyan');
|
|
395
305
|
log(' * 安装 @anthropic-ai/claude-code', 'green');
|
|
396
|
-
log(' *
|
|
397
|
-
log(' *
|
|
398
|
-
log(' *
|
|
306
|
+
log(' * 设置用户环境变量 ANTHROPIC_AUTH_TOKEN', 'green');
|
|
307
|
+
log(' * 设置用户环境变量 ANTHROPIC_BASE_URL', 'green');
|
|
308
|
+
log(' * 设置用户环境变量 ANTHROPIC_SMALL_FAST_MODEL', 'green');
|
|
399
309
|
|
|
400
|
-
log('\n[
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
310
|
+
log('\n[环境变量配置]', 'cyan');
|
|
311
|
+
if (osType === 'windows') {
|
|
312
|
+
log(' 环境变量已通过 setx 设置到用户环境变量', 'reset');
|
|
313
|
+
log(' 可在 系统属性 -> 高级 -> 环境变量 中查看', 'yellow');
|
|
314
|
+
} else if (osType === 'mac') {
|
|
315
|
+
log(' 环境变量已写入: ~/.zshrc', 'reset');
|
|
316
|
+
log(` ${path.join(homeDir, '.zshrc')}`, 'yellow');
|
|
317
|
+
} else {
|
|
318
|
+
log(' 环境变量已写入: ~/.bashrc', 'reset');
|
|
319
|
+
log(` ${path.join(homeDir, '.bashrc')}`, 'yellow');
|
|
320
|
+
}
|
|
406
321
|
|
|
407
322
|
log('\n[启动方式]', 'cyan');
|
|
408
323
|
|
|
@@ -447,16 +362,13 @@ async function main() {
|
|
|
447
362
|
log('\n[提示] 安装失败,但你可以继续配置环境变量', 'yellow');
|
|
448
363
|
}
|
|
449
364
|
|
|
450
|
-
// 2. 配置 API Key
|
|
365
|
+
// 2. 配置 API Key (会自动设置环境变量)
|
|
451
366
|
const configSuccess = await configureEnvironment();
|
|
452
367
|
if (!configSuccess) {
|
|
453
368
|
process.exit(1);
|
|
454
369
|
}
|
|
455
370
|
|
|
456
|
-
// 3.
|
|
457
|
-
setupEnvironmentVariable();
|
|
458
|
-
|
|
459
|
-
// 4. 显示完成信息
|
|
371
|
+
// 3. 显示完成信息
|
|
460
372
|
showCompletionInfo();
|
|
461
373
|
|
|
462
374
|
} catch (error) {
|
|
@@ -475,5 +387,5 @@ module.exports = {
|
|
|
475
387
|
main,
|
|
476
388
|
installClaude,
|
|
477
389
|
configureEnvironment,
|
|
478
|
-
|
|
390
|
+
setupEnvironmentVariables
|
|
479
391
|
};
|
package/codex-api.js
CHANGED
|
@@ -190,7 +190,7 @@ function createConfigToml(codexDir) {
|
|
|
190
190
|
const configPath = path.join(codexDir, 'config.toml');
|
|
191
191
|
|
|
192
192
|
const configContent = `model_provider = "codex"
|
|
193
|
-
model = "gpt-5.
|
|
193
|
+
model = "gpt-5.2" #可更改为model = "gpt-5.1-codex或者gpt-5.1-codex-max"
|
|
194
194
|
model_reasoning_effort = "high"
|
|
195
195
|
disable_response_storage = true
|
|
196
196
|
|
package/codex-setup.js
CHANGED
|
@@ -190,7 +190,7 @@ function createConfigToml(codexDir) {
|
|
|
190
190
|
const configPath = path.join(codexDir, 'config.toml');
|
|
191
191
|
|
|
192
192
|
const configContent = `model_provider = "codex"
|
|
193
|
-
model = "gpt-5.
|
|
193
|
+
model = "gpt-5.2" #可更改为model = "gpt-5.1-codex或者gpt-5.1-codex-max"
|
|
194
194
|
model_reasoning_effort = "high"
|
|
195
195
|
disable_response_storage = true
|
|
196
196
|
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumpkinai-config",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.17",
|
|
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-au": "./claude-au.js",
|
|
11
10
|
"claude-api": "./claude-api.js"
|
|
12
11
|
},
|
|
13
12
|
"scripts": {
|
package/templates/auth.json
DELETED
package/templates/config.toml
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
model_provider = "codex"
|
|
2
|
-
model = "gpt-5.1" #可更改为model = "gpt-5.1-codex或者gpt-5.1-codex-max"
|
|
3
|
-
model_reasoning_effort = "high"
|
|
4
|
-
disable_response_storage = true
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[model_providers.codex]
|
|
8
|
-
name = "codex"
|
|
9
|
-
base_url = "https://code.ppchat.vip/v1"
|
|
10
|
-
wire_api = "responses"
|
|
11
|
-
requires_openai_auth = true
|