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