hop-claude 1.0.0
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/CHANGELOG.md +316 -0
- package/README.md +574 -0
- package/SECURITY.md +280 -0
- package/bin/cli.js +6 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +147 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/config-manager.d.ts +88 -0
- package/dist/config/config-manager.d.ts.map +1 -0
- package/dist/config/config-manager.js +334 -0
- package/dist/config/config-manager.js.map +1 -0
- package/dist/config/encryption-v2.d.ts +51 -0
- package/dist/config/encryption-v2.d.ts.map +1 -0
- package/dist/config/encryption-v2.js +93 -0
- package/dist/config/encryption-v2.js.map +1 -0
- package/dist/config/encryption.d.ts +36 -0
- package/dist/config/encryption.d.ts.map +1 -0
- package/dist/config/encryption.js +72 -0
- package/dist/config/encryption.js.map +1 -0
- package/dist/config/keychain.d.ts +56 -0
- package/dist/config/keychain.d.ts.map +1 -0
- package/dist/config/keychain.js +112 -0
- package/dist/config/keychain.js.map +1 -0
- package/dist/config/storage.d.ts +32 -0
- package/dist/config/storage.d.ts.map +1 -0
- package/dist/config/storage.js +87 -0
- package/dist/config/storage.js.map +1 -0
- package/dist/config/validator.d.ts +9 -0
- package/dist/config/validator.d.ts.map +1 -0
- package/dist/config/validator.js +53 -0
- package/dist/config/validator.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +38 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/display.d.ts +25 -0
- package/dist/ui/display.d.ts.map +1 -0
- package/dist/ui/display.js +39 -0
- package/dist/ui/display.js.map +1 -0
- package/dist/ui/prompts.d.ts +52 -0
- package/dist/ui/prompts.d.ts.map +1 -0
- package/dist/ui/prompts.js +339 -0
- package/dist/ui/prompts.js.map +1 -0
- package/dist/utils/backup.d.ts +14 -0
- package/dist/utils/backup.d.ts.map +1 -0
- package/dist/utils/backup.js +27 -0
- package/dist/utils/backup.js.map +1 -0
- package/dist/utils/claude-launcher.d.ts +8 -0
- package/dist/utils/claude-launcher.d.ts.map +1 -0
- package/dist/utils/claude-launcher.js +68 -0
- package/dist/utils/claude-launcher.js.map +1 -0
- package/dist/utils/migration.d.ts +18 -0
- package/dist/utils/migration.d.ts.map +1 -0
- package/dist/utils/migration.js +176 -0
- package/dist/utils/migration.js.map +1 -0
- package/dist/utils/platform.d.ts +19 -0
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +91 -0
- package/dist/utils/platform.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { validateApiKey } from '../config/validator.js';
|
|
4
|
+
import { backupConfig, restoreConfig } from '../utils/backup.js';
|
|
5
|
+
import { displayTitle, displaySuccess, displayError, displayWarning, displayInfo } from './display.js';
|
|
6
|
+
/**
|
|
7
|
+
* 交互式 UI 类
|
|
8
|
+
*/
|
|
9
|
+
export class InteractiveUI {
|
|
10
|
+
configManager;
|
|
11
|
+
constructor(configManager) {
|
|
12
|
+
this.configManager = configManager;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 显示当前配置并询问是否修改
|
|
16
|
+
*/
|
|
17
|
+
async showCurrentAndAsk() {
|
|
18
|
+
const current = await this.configManager.getCurrentProfile();
|
|
19
|
+
displayTitle('🔧 Claude Code Configuration Manager');
|
|
20
|
+
if (current) {
|
|
21
|
+
console.log(chalk.cyan('Current Configuration:'));
|
|
22
|
+
displayInfo('Domain', chalk.green(current.domain));
|
|
23
|
+
displayInfo('Base URL', current.baseUrl);
|
|
24
|
+
displayInfo('Proxy', current.proxy, '(none)');
|
|
25
|
+
displayInfo('Disable Traffic', current.disableNonessentialTraffic ? 'Yes' : 'No');
|
|
26
|
+
console.log();
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
displayWarning('No configuration set up yet.\n');
|
|
30
|
+
}
|
|
31
|
+
const { action } = await prompts({
|
|
32
|
+
type: 'select',
|
|
33
|
+
name: 'action',
|
|
34
|
+
message: 'What would you like to do?',
|
|
35
|
+
choices: [
|
|
36
|
+
{ title: 'Continue with current configuration', value: 'continue', disabled: !current },
|
|
37
|
+
{ title: 'Modify configuration', value: 'modify' },
|
|
38
|
+
{ title: 'Exit', value: 'exit' },
|
|
39
|
+
],
|
|
40
|
+
initial: current ? 0 : 1,
|
|
41
|
+
});
|
|
42
|
+
if (action === 'exit' || action === undefined) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
if (action === 'modify') {
|
|
46
|
+
await this.manageConfiguration();
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 配置管理主界面
|
|
52
|
+
*/
|
|
53
|
+
async manageConfiguration() {
|
|
54
|
+
const profiles = await this.configManager.listProfiles();
|
|
55
|
+
const { action } = await prompts({
|
|
56
|
+
type: 'select',
|
|
57
|
+
name: 'action',
|
|
58
|
+
message: 'Configuration Management',
|
|
59
|
+
choices: [
|
|
60
|
+
{ title: 'Select existing configuration', value: 'select', disabled: profiles.length === 0 },
|
|
61
|
+
{ title: 'Create new configuration', value: 'create' },
|
|
62
|
+
{ title: 'Edit existing configuration', value: 'edit', disabled: profiles.length === 0 },
|
|
63
|
+
{ title: 'Delete configuration', value: 'delete', disabled: profiles.length === 0 },
|
|
64
|
+
{ title: 'Export configuration', value: 'export' },
|
|
65
|
+
{ title: 'Import configuration', value: 'import' },
|
|
66
|
+
{ title: 'Back', value: 'back' },
|
|
67
|
+
],
|
|
68
|
+
});
|
|
69
|
+
switch (action) {
|
|
70
|
+
case 'select':
|
|
71
|
+
await this.selectProfile(profiles);
|
|
72
|
+
break;
|
|
73
|
+
case 'create':
|
|
74
|
+
await this.createProfile();
|
|
75
|
+
break;
|
|
76
|
+
case 'edit':
|
|
77
|
+
await this.editProfile(profiles);
|
|
78
|
+
break;
|
|
79
|
+
case 'delete':
|
|
80
|
+
await this.deleteProfile(profiles);
|
|
81
|
+
break;
|
|
82
|
+
case 'export':
|
|
83
|
+
await this.exportConfiguration();
|
|
84
|
+
break;
|
|
85
|
+
case 'import':
|
|
86
|
+
await this.importConfiguration();
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 选择 profile
|
|
92
|
+
*/
|
|
93
|
+
async selectProfile(profiles) {
|
|
94
|
+
const { domain } = await prompts({
|
|
95
|
+
type: 'select',
|
|
96
|
+
name: 'domain',
|
|
97
|
+
message: 'Select a configuration:',
|
|
98
|
+
choices: profiles.map(p => ({
|
|
99
|
+
title: `${p.domain} (${p.maskedApiKey})`,
|
|
100
|
+
value: p.domain,
|
|
101
|
+
})),
|
|
102
|
+
});
|
|
103
|
+
if (domain) {
|
|
104
|
+
await this.configManager.setCurrentProfile(domain);
|
|
105
|
+
displaySuccess(`Switched to: ${domain}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 创建新 profile
|
|
110
|
+
*/
|
|
111
|
+
async createProfile() {
|
|
112
|
+
const answers = await prompts([
|
|
113
|
+
{
|
|
114
|
+
type: 'text',
|
|
115
|
+
name: 'domain',
|
|
116
|
+
message: 'Domain/Profile name:',
|
|
117
|
+
validate: value => value.trim() ? true : 'Domain cannot be empty',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
type: 'password',
|
|
121
|
+
name: 'apiKey',
|
|
122
|
+
message: 'API Key:',
|
|
123
|
+
validate: value => value.trim() ? true : 'API Key cannot be empty',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
type: 'text',
|
|
127
|
+
name: 'baseUrl',
|
|
128
|
+
message: 'Base URL (optional):',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: 'text',
|
|
132
|
+
name: 'proxy',
|
|
133
|
+
message: 'Proxy (optional):',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
type: 'confirm',
|
|
137
|
+
name: 'disableNonessentialTraffic',
|
|
138
|
+
message: 'Disable nonessential traffic?',
|
|
139
|
+
initial: false,
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
type: 'confirm',
|
|
143
|
+
name: 'validate',
|
|
144
|
+
message: 'Validate API Key?',
|
|
145
|
+
initial: false,
|
|
146
|
+
},
|
|
147
|
+
]);
|
|
148
|
+
if (!answers.domain || !answers.apiKey) {
|
|
149
|
+
displayWarning('Cancelled');
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// 验证 API Key(如果用户选择)
|
|
153
|
+
if (answers.validate) {
|
|
154
|
+
console.log(chalk.gray('Validating API Key...'));
|
|
155
|
+
const result = await validateApiKey(answers.apiKey, answers.baseUrl);
|
|
156
|
+
if (!result.valid) {
|
|
157
|
+
displayError(`API Key validation failed: ${result.error}`);
|
|
158
|
+
const { continueAnyway } = await prompts({
|
|
159
|
+
type: 'confirm',
|
|
160
|
+
name: 'continueAnyway',
|
|
161
|
+
message: 'Continue anyway?',
|
|
162
|
+
initial: false,
|
|
163
|
+
});
|
|
164
|
+
if (!continueAnyway) {
|
|
165
|
+
displayWarning('Cancelled');
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
displaySuccess('API Key is valid');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const profile = {
|
|
174
|
+
domain: answers.domain,
|
|
175
|
+
apiKey: answers.apiKey,
|
|
176
|
+
baseUrl: answers.baseUrl || undefined,
|
|
177
|
+
proxy: answers.proxy || undefined,
|
|
178
|
+
disableNonessentialTraffic: answers.disableNonessentialTraffic,
|
|
179
|
+
createdAt: Date.now(),
|
|
180
|
+
updatedAt: Date.now(),
|
|
181
|
+
};
|
|
182
|
+
await this.configManager.saveProfile(profile);
|
|
183
|
+
await this.configManager.setCurrentProfile(profile.domain);
|
|
184
|
+
displaySuccess(`Configuration "${profile.domain}" created and activated`);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* 编辑 profile
|
|
188
|
+
*/
|
|
189
|
+
async editProfile(profiles) {
|
|
190
|
+
const { domain } = await prompts({
|
|
191
|
+
type: 'select',
|
|
192
|
+
name: 'domain',
|
|
193
|
+
message: 'Select configuration to edit:',
|
|
194
|
+
choices: profiles.map(p => ({
|
|
195
|
+
title: `${p.domain} (${p.maskedApiKey})`,
|
|
196
|
+
value: p.domain,
|
|
197
|
+
})),
|
|
198
|
+
});
|
|
199
|
+
if (!domain)
|
|
200
|
+
return;
|
|
201
|
+
const existing = await this.configManager.getProfile(domain);
|
|
202
|
+
if (!existing)
|
|
203
|
+
return;
|
|
204
|
+
const answers = await prompts([
|
|
205
|
+
{
|
|
206
|
+
type: 'password',
|
|
207
|
+
name: 'apiKey',
|
|
208
|
+
message: 'API Key (leave empty to keep current):',
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
type: 'text',
|
|
212
|
+
name: 'baseUrl',
|
|
213
|
+
message: 'Base URL:',
|
|
214
|
+
initial: existing.baseUrl,
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
type: 'text',
|
|
218
|
+
name: 'proxy',
|
|
219
|
+
message: 'Proxy:',
|
|
220
|
+
initial: existing.proxy,
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
type: 'confirm',
|
|
224
|
+
name: 'disableNonessentialTraffic',
|
|
225
|
+
message: 'Disable nonessential traffic?',
|
|
226
|
+
initial: existing.disableNonessentialTraffic,
|
|
227
|
+
},
|
|
228
|
+
]);
|
|
229
|
+
const updated = {
|
|
230
|
+
...existing,
|
|
231
|
+
apiKey: answers.apiKey || existing.apiKey,
|
|
232
|
+
baseUrl: answers.baseUrl || undefined,
|
|
233
|
+
proxy: answers.proxy || undefined,
|
|
234
|
+
disableNonessentialTraffic: answers.disableNonessentialTraffic,
|
|
235
|
+
};
|
|
236
|
+
await this.configManager.saveProfile(updated);
|
|
237
|
+
displaySuccess(`Configuration "${domain}" updated`);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* 删除 profile
|
|
241
|
+
*/
|
|
242
|
+
async deleteProfile(profiles) {
|
|
243
|
+
const { domain } = await prompts({
|
|
244
|
+
type: 'select',
|
|
245
|
+
name: 'domain',
|
|
246
|
+
message: 'Select configuration to delete:',
|
|
247
|
+
choices: profiles.map(p => ({
|
|
248
|
+
title: `${p.domain} (${p.maskedApiKey})`,
|
|
249
|
+
value: p.domain,
|
|
250
|
+
})),
|
|
251
|
+
});
|
|
252
|
+
if (!domain)
|
|
253
|
+
return;
|
|
254
|
+
const { confirm } = await prompts({
|
|
255
|
+
type: 'confirm',
|
|
256
|
+
name: 'confirm',
|
|
257
|
+
message: `Are you sure you want to delete "${domain}"?`,
|
|
258
|
+
initial: false,
|
|
259
|
+
});
|
|
260
|
+
if (confirm) {
|
|
261
|
+
await this.configManager.deleteProfile(domain);
|
|
262
|
+
displaySuccess(`Configuration "${domain}" deleted`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* 列出所有配置
|
|
267
|
+
*/
|
|
268
|
+
async listConfigurations() {
|
|
269
|
+
const profiles = await this.configManager.listProfiles();
|
|
270
|
+
const config = await this.configManager.getConfig();
|
|
271
|
+
displayTitle('📋 All Configurations:');
|
|
272
|
+
if (profiles.length === 0) {
|
|
273
|
+
console.log(chalk.gray(' No configurations found\n'));
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
profiles.forEach(p => {
|
|
277
|
+
const isCurrent = p.domain === config.currentProfile;
|
|
278
|
+
const marker = isCurrent ? chalk.green('●') : chalk.gray('○');
|
|
279
|
+
console.log(`${marker} ${chalk.bold(p.domain)}`);
|
|
280
|
+
displayInfo('API Key', p.maskedApiKey);
|
|
281
|
+
displayInfo('Base URL', p.baseUrl);
|
|
282
|
+
displayInfo('Proxy', p.proxy, '(none)');
|
|
283
|
+
displayInfo('Disable Traffic', p.disableNonessentialTraffic ? 'Yes' : 'No');
|
|
284
|
+
console.log();
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* 导出配置
|
|
289
|
+
*/
|
|
290
|
+
async exportConfiguration() {
|
|
291
|
+
const { outputPath } = await prompts({
|
|
292
|
+
type: 'text',
|
|
293
|
+
name: 'outputPath',
|
|
294
|
+
message: 'Export to file:',
|
|
295
|
+
initial: './cproxy-config-backup.json',
|
|
296
|
+
});
|
|
297
|
+
if (!outputPath)
|
|
298
|
+
return;
|
|
299
|
+
try {
|
|
300
|
+
await backupConfig(this.configManager, outputPath);
|
|
301
|
+
displaySuccess(`Configuration exported to: ${outputPath}`);
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
305
|
+
displayError(`Export failed: ${err.message}`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* 导入配置
|
|
310
|
+
*/
|
|
311
|
+
async importConfiguration() {
|
|
312
|
+
const { inputPath } = await prompts({
|
|
313
|
+
type: 'text',
|
|
314
|
+
name: 'inputPath',
|
|
315
|
+
message: 'Import from file:',
|
|
316
|
+
});
|
|
317
|
+
if (!inputPath)
|
|
318
|
+
return;
|
|
319
|
+
const { confirm } = await prompts({
|
|
320
|
+
type: 'confirm',
|
|
321
|
+
name: 'confirm',
|
|
322
|
+
message: 'This will replace all existing configurations. Continue?',
|
|
323
|
+
initial: false,
|
|
324
|
+
});
|
|
325
|
+
if (!confirm) {
|
|
326
|
+
displayWarning('Cancelled');
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
try {
|
|
330
|
+
await restoreConfig(this.configManager, inputPath);
|
|
331
|
+
displaySuccess('Configuration imported successfully');
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
335
|
+
displayError(`Import failed: ${err.message}`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/ui/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ConfigManager } from '../config/config-manager.js';
|
|
2
|
+
/**
|
|
3
|
+
* 导出配置到文件
|
|
4
|
+
* @param configManager 配置管理器
|
|
5
|
+
* @param outputPath 输出文件路径
|
|
6
|
+
*/
|
|
7
|
+
export declare function backupConfig(configManager: ConfigManager, outputPath: string): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* 从文件导入配置
|
|
10
|
+
* @param configManager 配置管理器
|
|
11
|
+
* @param inputPath 输入文件路径
|
|
12
|
+
*/
|
|
13
|
+
export declare function restoreConfig(configManager: ConfigManager, inputPath: string): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=backup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../src/utils/backup.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* 导出配置到文件
|
|
5
|
+
* @param configManager 配置管理器
|
|
6
|
+
* @param outputPath 输出文件路径
|
|
7
|
+
*/
|
|
8
|
+
export async function backupConfig(configManager, outputPath) {
|
|
9
|
+
const configData = await configManager.exportConfig();
|
|
10
|
+
// 确保输出目录存在
|
|
11
|
+
const dir = path.dirname(outputPath);
|
|
12
|
+
await fs.mkdir(dir, { recursive: true });
|
|
13
|
+
// 写入配置文件
|
|
14
|
+
await fs.writeFile(outputPath, configData, 'utf8');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 从文件导入配置
|
|
18
|
+
* @param configManager 配置管理器
|
|
19
|
+
* @param inputPath 输入文件路径
|
|
20
|
+
*/
|
|
21
|
+
export async function restoreConfig(configManager, inputPath) {
|
|
22
|
+
// 读取配置文件
|
|
23
|
+
const configData = await fs.readFile(inputPath, 'utf8');
|
|
24
|
+
// 导入配置
|
|
25
|
+
await configManager.importConfig(configData);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/utils/backup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,aAA4B,EAC5B,UAAkB;IAElB,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,YAAY,EAAE,CAAC;IAEtD,WAAW;IACX,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,SAAS;IACT,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,aAA4B,EAC5B,SAAiB;IAEjB,SAAS;IACT,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAExD,OAAO;IACP,MAAM,aAAa,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DecryptedProfile } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 启动 Claude CLI 并应用配置
|
|
4
|
+
* @param profile 配置 profile
|
|
5
|
+
* @param args 透传给 claude 的参数
|
|
6
|
+
*/
|
|
7
|
+
export declare function launchClaude(profile: DecryptedProfile, args?: string[]): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=claude-launcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-launcher.d.ts","sourceRoot":"","sources":["../../src/utils/claude-launcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAwB,MAAM,mBAAmB,CAAC;AA8BhF;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,gBAAgB,EACzB,IAAI,GAAE,MAAM,EAAO,GAClB,OAAO,CAAC,IAAI,CAAC,CAwCf"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import which from 'which';
|
|
3
|
+
/**
|
|
4
|
+
* 获取 Claude CLI 可执行文件路径
|
|
5
|
+
* 跨平台检测,支持 Windows 的 .cmd 和 .exe 扩展名
|
|
6
|
+
*/
|
|
7
|
+
function getClaudeBinary() {
|
|
8
|
+
// Unix 系统直接返回 'claude'
|
|
9
|
+
if (process.platform !== 'win32') {
|
|
10
|
+
return 'claude';
|
|
11
|
+
}
|
|
12
|
+
// Windows 系统:尝试多个变体
|
|
13
|
+
const variants = ['claude.cmd', 'claude.exe', 'claude'];
|
|
14
|
+
for (const variant of variants) {
|
|
15
|
+
try {
|
|
16
|
+
const resolved = which.sync(variant, { nothrow: true });
|
|
17
|
+
if (resolved) {
|
|
18
|
+
return variant;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// 继续尝试下一个
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// 如果都找不到,返回默认值(会在后续报错)
|
|
26
|
+
return 'claude';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 启动 Claude CLI 并应用配置
|
|
30
|
+
* @param profile 配置 profile
|
|
31
|
+
* @param args 透传给 claude 的参数
|
|
32
|
+
*/
|
|
33
|
+
export async function launchClaude(profile, args = []) {
|
|
34
|
+
// 构建环境变量
|
|
35
|
+
const env = {
|
|
36
|
+
...process.env,
|
|
37
|
+
ANTHROPIC_API_KEY: profile.apiKey,
|
|
38
|
+
};
|
|
39
|
+
if (profile.baseUrl) {
|
|
40
|
+
env.ANTHROPIC_BASE_URL = profile.baseUrl;
|
|
41
|
+
}
|
|
42
|
+
if (profile.proxy) {
|
|
43
|
+
env.HTTP_PROXY = profile.proxy;
|
|
44
|
+
env.HTTPS_PROXY = profile.proxy;
|
|
45
|
+
}
|
|
46
|
+
if (profile.disableNonessentialTraffic) {
|
|
47
|
+
env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = '1';
|
|
48
|
+
}
|
|
49
|
+
// 启动 claude CLI
|
|
50
|
+
// 注意:不使用 shell: true 以防止命令注入攻击
|
|
51
|
+
const command = getClaudeBinary();
|
|
52
|
+
const claude = spawn(command, args, {
|
|
53
|
+
env: env,
|
|
54
|
+
stdio: 'inherit', // 继承父进程的 stdio
|
|
55
|
+
});
|
|
56
|
+
// 处理退出
|
|
57
|
+
claude.on('exit', (code) => {
|
|
58
|
+
process.exit(code || 0);
|
|
59
|
+
});
|
|
60
|
+
// 处理错误
|
|
61
|
+
claude.on('error', (error) => {
|
|
62
|
+
console.error('Failed to launch claude:', error.message);
|
|
63
|
+
console.error('\nMake sure Claude CLI is installed and available in your PATH.');
|
|
64
|
+
console.error('Install it from: https://github.com/anthropics/claude-code');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=claude-launcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-launcher.js","sourceRoot":"","sources":["../../src/utils/claude-launcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;GAGG;AACH,SAAS,eAAe;IACtB,uBAAuB;IACvB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,oBAAoB;IACpB,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IAExD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACxD,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,UAAU;QACZ,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAyB,EACzB,OAAiB,EAAE;IAEnB,SAAS;IACT,MAAM,GAAG,GAAyB;QAChC,GAAG,OAAO,CAAC,GAAG;QACd,iBAAiB,EAAE,OAAO,CAAC,MAAM;KAClC,CAAC;IAEF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,GAAG,CAAC,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,GAAG,CAAC,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC;QAC/B,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC;IAClC,CAAC;IAED,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;QACvC,GAAG,CAAC,wCAAwC,GAAG,GAAG,CAAC;IACrD,CAAC;IAED,gBAAgB;IAChB,+BAA+B;IAC/B,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;QAClC,GAAG,EAAE,GAAwB;QAC7B,KAAK,EAAE,SAAS,EAAE,eAAe;KAClC,CAAC,CAAC;IAEH,OAAO;IACP,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACzB,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,OAAO;IACP,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC3B,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACzD,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACjF,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ConfigManager } from '../config/config-manager.js';
|
|
2
|
+
/**
|
|
3
|
+
* 加密模式迁移工具
|
|
4
|
+
* 帮助用户从 legacy 模式迁移到 keychain 或 passphrase 模式
|
|
5
|
+
*/
|
|
6
|
+
export declare class EncryptionMigration {
|
|
7
|
+
private configManager;
|
|
8
|
+
constructor(configManager: ConfigManager);
|
|
9
|
+
/**
|
|
10
|
+
* 执行加密模式迁移
|
|
11
|
+
*/
|
|
12
|
+
migrate(): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* 显示当前加密模式信息
|
|
15
|
+
*/
|
|
16
|
+
showEncryptionInfo(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=migration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../src/utils/migration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAK5D;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,aAAa,CAAgB;gBAEzB,aAAa,EAAE,aAAa;IAIxC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsJ9B;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;CAsC1C"}
|