@yesdgq/claude-buddy 1.1.1005 → 1.1.1007
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/README.md +55 -35
- package/README_zh.md +132 -0
- package/assets/config.html +62 -37
- package/assets/config.js +187 -18
- package/assets/libs/style.css +101 -0
- package/dist/index.js +1 -1
- package/package.json +2 -1
package/assets/config.js
CHANGED
|
@@ -14,6 +14,11 @@ createApp({
|
|
|
14
14
|
configPath: '',
|
|
15
15
|
showHelp: false,
|
|
16
16
|
currentCli: 'Claude',
|
|
17
|
+
currentLang: 'en',
|
|
18
|
+
languages: [
|
|
19
|
+
{ code: 'en', label: 'English' },
|
|
20
|
+
{ code: 'zh', label: '中文' }
|
|
21
|
+
],
|
|
17
22
|
cliList: [
|
|
18
23
|
{ name: 'Claude', label: 'Claude', icon: 'images/claude.png' },
|
|
19
24
|
{ name: 'Codex', label: 'Codex', icon: 'images/gpt.png' },
|
|
@@ -21,10 +26,168 @@ createApp({
|
|
|
21
26
|
],
|
|
22
27
|
// 拖拽相关状态
|
|
23
28
|
draggingIndex: null,
|
|
24
|
-
dragOverIndex: null
|
|
29
|
+
dragOverIndex: null,
|
|
30
|
+
// 确认对话框
|
|
31
|
+
confirmDialog: {
|
|
32
|
+
show: false,
|
|
33
|
+
message: '',
|
|
34
|
+
onConfirm: null,
|
|
35
|
+
onCancel: null
|
|
36
|
+
},
|
|
37
|
+
// 翻译数据
|
|
38
|
+
translations: {
|
|
39
|
+
en: {
|
|
40
|
+
helpTitle: 'User Guide',
|
|
41
|
+
helpDescription: 'Claude Buddy is an easy-to-use CLI tool that helps you quickly configure API keys, model mappings, and other settings for CLI tools like Claude Code, Codex, and Gemini through a visual interface. It greatly simplifies your usage of these CLI tools.',
|
|
42
|
+
feature1Title: 'API Key Management',
|
|
43
|
+
feature1Desc: 'Easily store, switch, and manage multiple API keys',
|
|
44
|
+
feature2Title: 'Model Mapping',
|
|
45
|
+
feature2Desc: 'Conveniently customize and manage model configurations',
|
|
46
|
+
feature3Title: 'One-time Installation, Permanent Use',
|
|
47
|
+
feature3Desc: 'Local deployment with long-term usage after installation',
|
|
48
|
+
feature4Title: 'Quick Configuration',
|
|
49
|
+
feature4Desc: 'Visual interface, complete settings in seconds',
|
|
50
|
+
feature5Title: 'Developer Friendly',
|
|
51
|
+
feature5Desc: 'Designed for developers focused on coding',
|
|
52
|
+
commandUsageTitle: 'Command Usage',
|
|
53
|
+
command1: 'Open the configuration page to set your API URL and access token',
|
|
54
|
+
command2: 'Launch Claude Code',
|
|
55
|
+
command3: 'View conversation history',
|
|
56
|
+
command4: 'Resume the last conversation',
|
|
57
|
+
command5: 'View Claude-Buddy version',
|
|
58
|
+
command6: 'View Claude version',
|
|
59
|
+
restartNotice: 'After switching or updating configurations, you need to restart Claude Code (CLI tool) for changes to take effect.',
|
|
60
|
+
loading: 'Loading...',
|
|
61
|
+
currentUse: 'Current',
|
|
62
|
+
activate: 'Activate',
|
|
63
|
+
activateThisConfig: 'Activate this configuration',
|
|
64
|
+
emptyConfigCannotActivate: 'Empty configuration cannot be activated',
|
|
65
|
+
deleteThisConfig: 'Delete this configuration',
|
|
66
|
+
emptyConfigCannotDelete: 'Empty configuration cannot be deleted',
|
|
67
|
+
modelManagement: 'Model Management',
|
|
68
|
+
collapse: 'Collapse',
|
|
69
|
+
expand: 'Expand',
|
|
70
|
+
modelNamePlaceholder: 'Model name',
|
|
71
|
+
modelValuePlaceholder: 'Model value',
|
|
72
|
+
deleteThisModel: 'Delete this model',
|
|
73
|
+
addModel: 'Add Model',
|
|
74
|
+
envVariables: 'Environment Variables',
|
|
75
|
+
variableNamePlaceholder: 'Variable name',
|
|
76
|
+
variableValuePlaceholder: 'Variable value',
|
|
77
|
+
deleteThisEnvVar: 'Delete this environment variable',
|
|
78
|
+
addEnvVariable: 'Add Environment Variable',
|
|
79
|
+
addNewConfig: 'Add New Configuration',
|
|
80
|
+
saveConfig: 'Save Configuration',
|
|
81
|
+
saving: 'Saving...',
|
|
82
|
+
reload: 'Reload',
|
|
83
|
+
confirmDeleteWithName: 'Are you sure you want to delete configuration {name}?',
|
|
84
|
+
confirmDeleteWithIndex: 'Are you sure you want to delete configuration #{index}?',
|
|
85
|
+
emptyConfigCannotDeleteToast: 'Empty configuration cannot be deleted',
|
|
86
|
+
configLoadSuccess: 'Configuration loaded successfully',
|
|
87
|
+
configLoadFailed: 'Failed to load configuration',
|
|
88
|
+
pleaseFillConfig: 'Please fill at least one complete configuration',
|
|
89
|
+
configSaveSuccess: 'Configuration saved successfully!',
|
|
90
|
+
configSaveFailed: 'Failed to save configuration',
|
|
91
|
+
configDeleted: 'Configuration deleted',
|
|
92
|
+
deleteFailed: 'Failed to delete',
|
|
93
|
+
configActivated: 'Configuration activated',
|
|
94
|
+
notAvailableYet: 'Not available yet, stay tuned',
|
|
95
|
+
saveFailed: 'Save failed',
|
|
96
|
+
cancel: 'Cancel',
|
|
97
|
+
confirm: 'Confirm'
|
|
98
|
+
},
|
|
99
|
+
zh: {
|
|
100
|
+
helpTitle: '使用说明',
|
|
101
|
+
helpDescription: 'Claude Buddy 是一款简单易用的 CLI 工具,通过可视化方式快速配置 Claude Code、Codex 和 Gemini 等CLI的API密钥、模型映射等信息,可极大的方便和简化您对Claude Code等CLI的使用。',
|
|
102
|
+
feature1Title: 'API 密钥管理',
|
|
103
|
+
feature1Desc: '轻松存储、切换和管理多组API 密钥',
|
|
104
|
+
feature2Title: '模型映射',
|
|
105
|
+
feature2Desc: '便捷地自定义和管理模型配置',
|
|
106
|
+
feature3Title: '一次安装永久使用',
|
|
107
|
+
feature3Desc: '本地部署,安装后可长久使用',
|
|
108
|
+
feature4Title: '快速配置',
|
|
109
|
+
feature4Desc: '可视化界面,几秒钟即可完成设置',
|
|
110
|
+
feature5Title: '开发者友好',
|
|
111
|
+
feature5Desc: '专为专注于编码的开发者打造',
|
|
112
|
+
commandUsageTitle: '命令使用',
|
|
113
|
+
command1: '打开配置页面,配置您的 API 地址和访问令牌(TOKEN)',
|
|
114
|
+
command2: '启动claude code',
|
|
115
|
+
command3: '查看历史会话',
|
|
116
|
+
command4: '继续上次会话',
|
|
117
|
+
command5: '查看Claude-Buddy版本',
|
|
118
|
+
command6: '查看Claude版本',
|
|
119
|
+
restartNotice: '切换或更新配置后,需重启 Claude Code(CLI工具)方可生效。',
|
|
120
|
+
loading: '加载中...',
|
|
121
|
+
currentUse: '当前使用',
|
|
122
|
+
activate: '启用',
|
|
123
|
+
activateThisConfig: '启用此配置',
|
|
124
|
+
emptyConfigCannotActivate: '空配置不能启用',
|
|
125
|
+
deleteThisConfig: '删除此配置',
|
|
126
|
+
emptyConfigCannotDelete: '空配置不能删除',
|
|
127
|
+
modelManagement: '模型管理',
|
|
128
|
+
collapse: '收起',
|
|
129
|
+
expand: '展开',
|
|
130
|
+
modelNamePlaceholder: '模型名称',
|
|
131
|
+
modelValuePlaceholder: '模型值',
|
|
132
|
+
deleteThisModel: '删除此模型',
|
|
133
|
+
addModel: '添加模型',
|
|
134
|
+
envVariables: '环境变量',
|
|
135
|
+
variableNamePlaceholder: '变量名',
|
|
136
|
+
variableValuePlaceholder: '变量值',
|
|
137
|
+
deleteThisEnvVar: '删除此环境变量',
|
|
138
|
+
addEnvVariable: '添加环境变量',
|
|
139
|
+
addNewConfig: '添加新配置',
|
|
140
|
+
saveConfig: '保存配置',
|
|
141
|
+
saving: '保存中...',
|
|
142
|
+
reload: '重新加载',
|
|
143
|
+
confirmDeleteWithName: '确定要删除配置 {name} 吗?',
|
|
144
|
+
confirmDeleteWithIndex: '确定要删除配置 #{index} 吗?',
|
|
145
|
+
emptyConfigCannotDeleteToast: '空配置项不能删除',
|
|
146
|
+
configLoadSuccess: '配置加载成功',
|
|
147
|
+
configLoadFailed: '加载配置失败',
|
|
148
|
+
pleaseFillConfig: '请至少填写一个完整的配置',
|
|
149
|
+
configSaveSuccess: '配置保存成功!',
|
|
150
|
+
configSaveFailed: '保存配置失败',
|
|
151
|
+
configDeleted: '配置已删除',
|
|
152
|
+
deleteFailed: '删除失败',
|
|
153
|
+
configActivated: '配置启用成功',
|
|
154
|
+
notAvailableYet: '暂未开放,敬请期待',
|
|
155
|
+
saveFailed: '保存失败',
|
|
156
|
+
cancel: '取消',
|
|
157
|
+
confirm: '确认'
|
|
158
|
+
}
|
|
159
|
+
}
|
|
25
160
|
};
|
|
26
161
|
},
|
|
162
|
+
computed: {
|
|
163
|
+
t() {
|
|
164
|
+
return this.translations[this.currentLang];
|
|
165
|
+
}
|
|
166
|
+
},
|
|
27
167
|
methods: {
|
|
168
|
+
// 显示确认对话框
|
|
169
|
+
showConfirmDialog(message, onConfirm, onCancel) {
|
|
170
|
+
this.confirmDialog = {
|
|
171
|
+
show: true,
|
|
172
|
+
message,
|
|
173
|
+
onConfirm: () => {
|
|
174
|
+
this.confirmDialog.show = false;
|
|
175
|
+
if (onConfirm) onConfirm();
|
|
176
|
+
},
|
|
177
|
+
onCancel: () => {
|
|
178
|
+
this.confirmDialog.show = false;
|
|
179
|
+
if (onCancel) onCancel();
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
// 切换语言
|
|
185
|
+
setLanguage(langCode) {
|
|
186
|
+
this.currentLang = langCode;
|
|
187
|
+
// 保存语言设置到 localStorage
|
|
188
|
+
localStorage.setItem('ccby-lang', langCode);
|
|
189
|
+
},
|
|
190
|
+
|
|
28
191
|
// 重置服务器倒计时
|
|
29
192
|
async resetTimer() {
|
|
30
193
|
try {
|
|
@@ -139,11 +302,11 @@ createApp({
|
|
|
139
302
|
// 最后更新 config
|
|
140
303
|
this.config = config;
|
|
141
304
|
|
|
142
|
-
this.showToast(
|
|
305
|
+
this.showToast(this.t.configLoadSuccess);
|
|
143
306
|
// 重置服务器倒计时
|
|
144
307
|
this.resetTimer();
|
|
145
308
|
} catch (err) {
|
|
146
|
-
this.showToast('
|
|
309
|
+
this.showToast(this.t.configLoadFailed + ': ' + (err.response?.data?.error || err.message), 'error');
|
|
147
310
|
} finally {
|
|
148
311
|
this.loading = false;
|
|
149
312
|
}
|
|
@@ -162,7 +325,7 @@ createApp({
|
|
|
162
325
|
|
|
163
326
|
// 如果过滤后没有配置项,确保至少有一个空配置项在前端显示
|
|
164
327
|
if (configToSave.AUTH.length === 0 && this.config.AUTH.length > 0) {
|
|
165
|
-
this.showToast(
|
|
328
|
+
this.showToast(this.t.pleaseFillConfig, 'error');
|
|
166
329
|
return;
|
|
167
330
|
}
|
|
168
331
|
|
|
@@ -170,11 +333,11 @@ createApp({
|
|
|
170
333
|
config: configToSave,
|
|
171
334
|
cliType: this.currentCli.toLowerCase()
|
|
172
335
|
});
|
|
173
|
-
this.showToast(
|
|
336
|
+
this.showToast(this.t.configSaveSuccess);
|
|
174
337
|
// 重置服务器倒计时
|
|
175
338
|
this.resetTimer();
|
|
176
339
|
} catch (err) {
|
|
177
|
-
this.showToast('
|
|
340
|
+
this.showToast(this.t.configSaveFailed + ': ' + (err.response?.data?.error || err.message), 'error');
|
|
178
341
|
} finally {
|
|
179
342
|
this.saving = false;
|
|
180
343
|
}
|
|
@@ -198,16 +361,17 @@ createApp({
|
|
|
198
361
|
async deleteAuth(index) {
|
|
199
362
|
// 检查是否是唯一的空配置项
|
|
200
363
|
if (this.config.AUTH.length === 1 && this.isEmptyConfig(this.config.AUTH[index])) {
|
|
201
|
-
this.showToast(
|
|
364
|
+
this.showToast(this.t.emptyConfigCannotDeleteToast, 'error');
|
|
202
365
|
return;
|
|
203
366
|
}
|
|
204
367
|
|
|
205
368
|
const authName = this.config.AUTH[index].name;
|
|
206
369
|
const confirmMsg = authName
|
|
207
|
-
?
|
|
208
|
-
:
|
|
370
|
+
? this.t.confirmDeleteWithName.replace('{name}', authName)
|
|
371
|
+
: this.t.confirmDeleteWithIndex.replace('{index}', index + 1);
|
|
209
372
|
|
|
210
|
-
|
|
373
|
+
// 使用自定义确认对话框
|
|
374
|
+
this.showConfirmDialog(confirmMsg, async () => {
|
|
211
375
|
// 保存要删除的数据,以防保存失败时恢复
|
|
212
376
|
const deletedAuth = this.config.AUTH[index];
|
|
213
377
|
const deletedTokenState = this.showTokens[index];
|
|
@@ -258,11 +422,11 @@ createApp({
|
|
|
258
422
|
config: configToSave,
|
|
259
423
|
cliType: this.currentCli.toLowerCase()
|
|
260
424
|
});
|
|
261
|
-
this.showToast(
|
|
425
|
+
this.showToast(this.t.configDeleted);
|
|
262
426
|
// 重置服务器倒计时
|
|
263
427
|
this.resetTimer();
|
|
264
428
|
} catch (err) {
|
|
265
|
-
this.showToast('
|
|
429
|
+
this.showToast(this.t.deleteFailed + ': ' + (err.response?.data?.error || err.message), 'error');
|
|
266
430
|
// 如果保存失败,恢复删除的项
|
|
267
431
|
this.config.AUTH.splice(index, 0, deletedAuth);
|
|
268
432
|
this.showTokens.splice(index, 0, deletedTokenState);
|
|
@@ -270,7 +434,7 @@ createApp({
|
|
|
270
434
|
this.showModelSections.splice(index, 0, deletedModelState);
|
|
271
435
|
this.config.activeIndex = oldActiveIndex;
|
|
272
436
|
}
|
|
273
|
-
}
|
|
437
|
+
});
|
|
274
438
|
},
|
|
275
439
|
|
|
276
440
|
async setAsActive(index) {
|
|
@@ -293,11 +457,11 @@ createApp({
|
|
|
293
457
|
config: configToSave,
|
|
294
458
|
cliType: this.currentCli.toLowerCase()
|
|
295
459
|
});
|
|
296
|
-
this.showToast(
|
|
460
|
+
this.showToast(this.t.configActivated);
|
|
297
461
|
// 重置服务器倒计时
|
|
298
462
|
this.resetTimer();
|
|
299
463
|
} catch (err) {
|
|
300
|
-
this.showToast('
|
|
464
|
+
this.showToast(this.t.configSaveFailed + ': ' + (err.response?.data?.error || err.message), 'error');
|
|
301
465
|
// 如果保存失败,恢复原来的 activeIndex
|
|
302
466
|
this.config.activeIndex = oldIndex;
|
|
303
467
|
}
|
|
@@ -355,7 +519,7 @@ createApp({
|
|
|
355
519
|
// 选择 CLI 类型
|
|
356
520
|
async selectCli(cliName) {
|
|
357
521
|
if (cliName === 'Codex' || cliName === 'Gemini') {
|
|
358
|
-
this.showToast(
|
|
522
|
+
this.showToast(this.t.notAvailableYet, 'error');
|
|
359
523
|
this.resetTimer();
|
|
360
524
|
return;
|
|
361
525
|
}
|
|
@@ -364,7 +528,7 @@ createApp({
|
|
|
364
528
|
// 切换 CLI 时重新加载配置
|
|
365
529
|
await this.loadConfig(cliName.toLowerCase());
|
|
366
530
|
} else {
|
|
367
|
-
this.showToast('
|
|
531
|
+
this.showToast(this.t.notAvailableYet + '!', 'error');
|
|
368
532
|
}
|
|
369
533
|
},
|
|
370
534
|
|
|
@@ -458,7 +622,7 @@ createApp({
|
|
|
458
622
|
// 重置服务器倒计时
|
|
459
623
|
this.resetTimer();
|
|
460
624
|
} catch (err) {
|
|
461
|
-
this.showToast('
|
|
625
|
+
this.showToast(this.t.saveFailed + ': ' + (err.response?.data?.error || err.message), 'error');
|
|
462
626
|
// 恢复原始数据
|
|
463
627
|
this.config.AUTH = oldAuth;
|
|
464
628
|
this.config.activeIndex = oldActiveIndex;
|
|
@@ -469,6 +633,11 @@ createApp({
|
|
|
469
633
|
}
|
|
470
634
|
},
|
|
471
635
|
mounted() {
|
|
636
|
+
// 从 localStorage 读取语言设置
|
|
637
|
+
const savedLang = localStorage.getItem('ccby-lang');
|
|
638
|
+
if (savedLang && (savedLang === 'en' || savedLang === 'zh')) {
|
|
639
|
+
this.currentLang = savedLang;
|
|
640
|
+
}
|
|
472
641
|
this.loadConfig();
|
|
473
642
|
},
|
|
474
643
|
updated() {
|
package/assets/libs/style.css
CHANGED
|
@@ -112,6 +112,73 @@ code {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
/* 确认对话框 */
|
|
116
|
+
.confirm-dialog-overlay {
|
|
117
|
+
position: fixed;
|
|
118
|
+
top: 0;
|
|
119
|
+
left: 0;
|
|
120
|
+
right: 0;
|
|
121
|
+
bottom: 0;
|
|
122
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
123
|
+
display: flex;
|
|
124
|
+
align-items: center;
|
|
125
|
+
justify-content: center;
|
|
126
|
+
z-index: 10000;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.confirm-dialog {
|
|
130
|
+
background: white;
|
|
131
|
+
border-radius: 12px;
|
|
132
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
|
133
|
+
min-width: 320px;
|
|
134
|
+
max-width: 400px;
|
|
135
|
+
padding: 1.5rem;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.confirm-dialog-content {
|
|
139
|
+
margin-bottom: 1.5rem;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.confirm-dialog-content p {
|
|
143
|
+
font-size: 1rem;
|
|
144
|
+
color: #1f2937;
|
|
145
|
+
margin: 0;
|
|
146
|
+
line-height: 1.5;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.confirm-dialog-actions {
|
|
150
|
+
display: flex;
|
|
151
|
+
gap: 0.75rem;
|
|
152
|
+
justify-content: flex-end;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.confirm-dialog-actions button {
|
|
156
|
+
padding: 0.5rem 1rem;
|
|
157
|
+
border: none;
|
|
158
|
+
border-radius: 6px;
|
|
159
|
+
font-size: 0.875rem;
|
|
160
|
+
cursor: pointer;
|
|
161
|
+
transition: all 0.2s;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.btn-cancel {
|
|
165
|
+
background-color: #e5e7eb;
|
|
166
|
+
color: #374151;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.btn-cancel:hover {
|
|
170
|
+
background-color: #d1d5db;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.btn-confirm {
|
|
174
|
+
background-color: #ef4444;
|
|
175
|
+
color: white;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.btn-confirm:hover {
|
|
179
|
+
background-color: #dc2626;
|
|
180
|
+
}
|
|
181
|
+
|
|
115
182
|
/* 容器布局 */
|
|
116
183
|
.app-container {
|
|
117
184
|
min-height: 100vh;
|
|
@@ -132,6 +199,12 @@ code {
|
|
|
132
199
|
margin-bottom: 1.5rem;
|
|
133
200
|
}
|
|
134
201
|
|
|
202
|
+
.title-group {
|
|
203
|
+
display: flex;
|
|
204
|
+
align-items: center;
|
|
205
|
+
gap: 20px;
|
|
206
|
+
}
|
|
207
|
+
|
|
135
208
|
.page-title {
|
|
136
209
|
font-size: 2rem;
|
|
137
210
|
font-weight: bold;
|
|
@@ -148,6 +221,34 @@ code {
|
|
|
148
221
|
padding: 1.5px;
|
|
149
222
|
}
|
|
150
223
|
|
|
224
|
+
/* 语言选择器 */
|
|
225
|
+
.lang-selector {
|
|
226
|
+
display: flex;
|
|
227
|
+
gap: 2px;
|
|
228
|
+
background-color: #e5e7eb;
|
|
229
|
+
border-radius: 4px;
|
|
230
|
+
padding: 1px;
|
|
231
|
+
margin-left: 0;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.lang-btn {
|
|
235
|
+
background: none;
|
|
236
|
+
border: none;
|
|
237
|
+
padding: 4px 8px;
|
|
238
|
+
cursor: pointer;
|
|
239
|
+
border-radius: 4px;
|
|
240
|
+
color: #6b7280;
|
|
241
|
+
font-size: 0.75rem;
|
|
242
|
+
transition: all 0.2s;
|
|
243
|
+
min-width: 50px;
|
|
244
|
+
text-align: center;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.lang-btn-active {
|
|
248
|
+
background-color: #3b82f6;
|
|
249
|
+
color: white;
|
|
250
|
+
}
|
|
251
|
+
|
|
151
252
|
.cli-btn {
|
|
152
253
|
display: flex;
|
|
153
254
|
align-items: center;
|