codexmate 0.0.42 → 0.0.44
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 +2 -0
- package/README.zh.md +2 -0
- package/cli/claude-proxy.js +611 -14
- package/cli/update.js +77 -7
- package/cli.js +191 -23
- package/package.json +2 -2
- package/web-ui/app.js +39 -10
- package/web-ui/logic.claude.mjs +65 -2
- package/web-ui/logic.runtime.mjs +0 -7
- package/web-ui/modules/app.methods.agents.mjs +6 -6
- package/web-ui/modules/app.methods.claude-config.mjs +65 -49
- package/web-ui/modules/app.methods.codex-config.mjs +10 -10
- package/web-ui/modules/app.methods.index.mjs +1 -1
- package/web-ui/modules/app.methods.install.mjs +129 -1
- package/web-ui/modules/app.methods.openclaw-persist.mjs +1 -1
- package/web-ui/modules/app.methods.providers.mjs +17 -16
- package/web-ui/modules/app.methods.runtime.mjs +27 -21
- package/web-ui/modules/app.methods.session-actions.mjs +25 -20
- package/web-ui/modules/app.methods.session-timeline.mjs +0 -1
- package/web-ui/modules/app.methods.startup-claude.mjs +29 -3
- package/web-ui/modules/app.methods.tool-config-permissions.mjs +3 -0
- package/web-ui/modules/i18n/locales/en.mjs +65 -1
- package/web-ui/modules/i18n/locales/ja.mjs +65 -1
- package/web-ui/modules/i18n/locales/vi.mjs +77 -2
- package/web-ui/modules/i18n/locales/zh.mjs +66 -2
- package/web-ui/partials/index/layout-header.html +24 -0
- package/web-ui/partials/index/modals-basic.html +18 -1
- package/web-ui/partials/index/panel-config-claude.html +5 -2
- package/web-ui/partials/index/panel-config-codex.html +2 -1
- package/web-ui/res/web-ui-render.precompiled.js +115 -22
- package/web-ui/styles/controls-forms.css +5 -5
- package/web-ui/styles/layout-shell.css +145 -0
- package/web-ui/styles/responsive.css +12 -0
- package/web-ui/styles/titles-cards.css +10 -4
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export function createInstallMethods() {
|
|
1
|
+
export function createInstallMethods(options = {}) {
|
|
2
|
+
const { api } = options;
|
|
2
3
|
return {
|
|
3
4
|
normalizeInstallPackageManager(value) {
|
|
4
5
|
const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
@@ -16,6 +17,133 @@ export function createInstallMethods() {
|
|
|
16
17
|
return 'install';
|
|
17
18
|
},
|
|
18
19
|
|
|
20
|
+
normalizePackageVersion(value) {
|
|
21
|
+
const normalized = typeof value === 'string' ? value.trim().replace(/^v/i, '') : '';
|
|
22
|
+
return /^\d+(?:\.\d+){0,2}(?:[-+][0-9A-Za-z.-]+)?$/.test(normalized) ? normalized : '';
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
comparePackageVersions(left, right) {
|
|
26
|
+
const normalizeParts = (value) => {
|
|
27
|
+
const normalized = this.normalizePackageVersion(value);
|
|
28
|
+
if (!normalized) return null;
|
|
29
|
+
return normalized.split(/[+-]/)[0].split('.').map((part) => Number.parseInt(part, 10) || 0);
|
|
30
|
+
};
|
|
31
|
+
const a = normalizeParts(left);
|
|
32
|
+
const b = normalizeParts(right);
|
|
33
|
+
if (!a || !b) return 0;
|
|
34
|
+
for (let i = 0; i < 3; i += 1) {
|
|
35
|
+
const diff = (a[i] || 0) - (b[i] || 0);
|
|
36
|
+
if (diff < 0) return -1;
|
|
37
|
+
if (diff > 0) return 1;
|
|
38
|
+
}
|
|
39
|
+
return 0;
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
isAppUpdateAvailable() {
|
|
43
|
+
const current = this.normalizePackageVersion(this.appVersion);
|
|
44
|
+
const latest = this.normalizePackageVersion(this.appLatestVersion);
|
|
45
|
+
if (!current || !latest) return false;
|
|
46
|
+
return this.comparePackageVersions(current, latest) < 0;
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
isAppVersionStatusVisible() {
|
|
50
|
+
return !!(this.appVersion || this.appLatestVersion || this.appVersionStatusLoading || this.appVersionStatusChecked || this.appVersionStatusError);
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
appVersionStatusKind() {
|
|
54
|
+
if (this.appVersionStatusLoading) return 'loading';
|
|
55
|
+
if (this.appVersionStatusError) return 'error';
|
|
56
|
+
if (this.isAppUpdateAvailable()) return 'available';
|
|
57
|
+
if (this.appVersionStatusChecked) return 'current';
|
|
58
|
+
return 'idle';
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
appUpdateNoticeText() {
|
|
62
|
+
if (this.appVersionStatusLoading) return this.t('side.update.checking');
|
|
63
|
+
if (this.appVersionStatusError) return this.t('side.update.retry');
|
|
64
|
+
const latest = this.normalizePackageVersion(this.appLatestVersion);
|
|
65
|
+
if (this.isAppUpdateAvailable()) return latest
|
|
66
|
+
? this.t('side.update.availableWithVersion', { version: latest })
|
|
67
|
+
: this.t('side.update.available');
|
|
68
|
+
if (this.appVersionStatusChecked) return this.t('side.update.upToDate');
|
|
69
|
+
return this.t('side.update.check');
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
appUpdateNoticeMeta() {
|
|
73
|
+
if (this.appVersionStatusLoading) return this.t('side.update.checkingMeta');
|
|
74
|
+
if (this.appVersionStatusError) return this.appVersionStatusError;
|
|
75
|
+
const current = this.normalizePackageVersion(this.appVersion);
|
|
76
|
+
const latest = this.normalizePackageVersion(this.appLatestVersion);
|
|
77
|
+
if (current && latest) {
|
|
78
|
+
return this.t('side.update.metaVersions', { current, latest });
|
|
79
|
+
}
|
|
80
|
+
if (current) {
|
|
81
|
+
return this.t('side.update.currentOnly', { current });
|
|
82
|
+
}
|
|
83
|
+
return this.t('side.update.meta');
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
appVersionStatusTitle() {
|
|
87
|
+
const source = typeof this.appVersionStatusSource === 'string' ? this.appVersionStatusSource.trim() : '';
|
|
88
|
+
const checkedAt = typeof this.appVersionStatusCheckedAt === 'string' ? this.appVersionStatusCheckedAt.trim() : '';
|
|
89
|
+
const suffix = [source, checkedAt].filter(Boolean).join(' · ');
|
|
90
|
+
const meta = this.appUpdateNoticeMeta();
|
|
91
|
+
return suffix ? `${meta} · ${suffix}` : meta;
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
handleAppVersionStatusClick() {
|
|
95
|
+
if (this.isAppUpdateAvailable()) {
|
|
96
|
+
this.openAppUpdateDocs();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
void this.loadAppVersionStatus({ silent: false, force: true });
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
async loadAppVersionStatus(options = {}) {
|
|
103
|
+
if (typeof api !== 'function') return false;
|
|
104
|
+
if (this.appVersionStatusLoading) return false;
|
|
105
|
+
this.appVersionStatusLoading = true;
|
|
106
|
+
this.appVersionStatusError = '';
|
|
107
|
+
try {
|
|
108
|
+
const res = await api('version-status', options.force ? { force: true } : {});
|
|
109
|
+
if (res && res.currentVersion && !this.appVersion) {
|
|
110
|
+
this.appVersion = this.normalizePackageVersion(res.currentVersion) || String(res.currentVersion || '');
|
|
111
|
+
}
|
|
112
|
+
if (res && res.latestVersion) {
|
|
113
|
+
this.appLatestVersion = this.normalizePackageVersion(res.latestVersion) || String(res.latestVersion || '');
|
|
114
|
+
}
|
|
115
|
+
if (res && typeof res.source === 'string') {
|
|
116
|
+
this.appVersionStatusSource = res.source;
|
|
117
|
+
}
|
|
118
|
+
if (res && typeof res.checkedAt === 'string') {
|
|
119
|
+
this.appVersionStatusCheckedAt = res.checkedAt;
|
|
120
|
+
}
|
|
121
|
+
if (res && res.error) {
|
|
122
|
+
this.appVersionStatusError = res.error;
|
|
123
|
+
this.appVersionStatusChecked = true;
|
|
124
|
+
if (!options.silent) this.showMessage(res.error, 'error');
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
this.appVersionStatusChecked = true;
|
|
128
|
+
return true;
|
|
129
|
+
} catch (e) {
|
|
130
|
+
const message = e && e.message ? e.message : this.t('side.update.checkFailed');
|
|
131
|
+
this.appVersionStatusError = message;
|
|
132
|
+
this.appVersionStatusChecked = true;
|
|
133
|
+
if (!options.silent) this.showMessage(message, 'error');
|
|
134
|
+
return false;
|
|
135
|
+
} finally {
|
|
136
|
+
this.appVersionStatusLoading = false;
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
openAppUpdateDocs() {
|
|
141
|
+
this.installCommandAction = 'update';
|
|
142
|
+
if (typeof this.switchMainTab === 'function') {
|
|
143
|
+
this.switchMainTab('docs');
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
|
|
19
147
|
normalizeInstallRegistryPreset(value) {
|
|
20
148
|
const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
21
149
|
if (normalized === 'default' || normalized === 'npmmirror' || normalized === 'tencent' || normalized === 'custom') {
|
|
@@ -274,7 +274,7 @@ export function createOpenclawPersistMethods(options = {}) {
|
|
|
274
274
|
try {
|
|
275
275
|
const name = this.persistOpenclawConfig();
|
|
276
276
|
if (!name) return;
|
|
277
|
-
this.showMessage('
|
|
277
|
+
this.showMessage(this.t('toast.operation.success'), 'success');
|
|
278
278
|
} finally {
|
|
279
279
|
this.openclawSaving = false;
|
|
280
280
|
}
|
|
@@ -170,7 +170,7 @@ export function createProvidersMethods(options = {}) {
|
|
|
170
170
|
normalizeProviderDraftState(this.newProvider);
|
|
171
171
|
const validation = getProviderValidationForContext(this, 'add');
|
|
172
172
|
if (!validation.ok) {
|
|
173
|
-
return this.showMessage(validation.errors.name || validation.errors.url || validation.errors.key || validation.errors.model || '
|
|
173
|
+
return this.showMessage(validation.errors.name || validation.errors.url || validation.errors.key || validation.errors.model || this.t('toast.provider.fieldsRequired'), 'error');
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
try {
|
|
@@ -206,7 +206,7 @@ export function createProvidersMethods(options = {}) {
|
|
|
206
206
|
};
|
|
207
207
|
this.providersList = [...this.providersList, newProvider];
|
|
208
208
|
|
|
209
|
-
this.showMessage('
|
|
209
|
+
this.showMessage(this.t('toast.operation.success'), 'success');
|
|
210
210
|
this.closeAddModal();
|
|
211
211
|
|
|
212
212
|
if (suggestedModel) {
|
|
@@ -214,7 +214,7 @@ export function createProvidersMethods(options = {}) {
|
|
|
214
214
|
this.currentModels[validation.name] = suggestedModel;
|
|
215
215
|
}
|
|
216
216
|
} catch (e) {
|
|
217
|
-
this.showMessage('
|
|
217
|
+
this.showMessage(this.t('toast.provider.addFail'), 'error');
|
|
218
218
|
}
|
|
219
219
|
},
|
|
220
220
|
|
|
@@ -275,7 +275,7 @@ export function createProvidersMethods(options = {}) {
|
|
|
275
275
|
|
|
276
276
|
async deleteProvider(name) {
|
|
277
277
|
if (this.isNonDeletableProvider(name)) {
|
|
278
|
-
this.showMessage('
|
|
278
|
+
this.showMessage(this.t('toast.provider.notDeletable'), 'info');
|
|
279
279
|
return;
|
|
280
280
|
}
|
|
281
281
|
try {
|
|
@@ -301,12 +301,13 @@ export function createProvidersMethods(options = {}) {
|
|
|
301
301
|
...p,
|
|
302
302
|
current: p.name === res.provider
|
|
303
303
|
}));
|
|
304
|
-
|
|
304
|
+
const modelSuffix = res.model ? ` / ${res.model}` : '';
|
|
305
|
+
this.showMessage(this.t('toast.provider.deletedAndSwitched', { provider: res.provider, model: modelSuffix }), 'success');
|
|
305
306
|
} else {
|
|
306
|
-
this.showMessage('
|
|
307
|
+
this.showMessage(this.t('toast.operation.success'), 'success');
|
|
307
308
|
}
|
|
308
309
|
} catch (_) {
|
|
309
|
-
this.showMessage('
|
|
310
|
+
this.showMessage(this.t('toast.delete.fail'), 'error');
|
|
310
311
|
}
|
|
311
312
|
},
|
|
312
313
|
|
|
@@ -330,7 +331,7 @@ export function createProvidersMethods(options = {}) {
|
|
|
330
331
|
const requestId = Symbol('openEditModal');
|
|
331
332
|
this._openEditModalRequestId = requestId;
|
|
332
333
|
if (!this.shouldShowProviderEdit(provider)) {
|
|
333
|
-
this.showMessage('
|
|
334
|
+
this.showMessage(this.t('toast.provider.notEditable'), 'info');
|
|
334
335
|
return;
|
|
335
336
|
}
|
|
336
337
|
const isTransformProvider = (() => {
|
|
@@ -398,14 +399,14 @@ export function createProvidersMethods(options = {}) {
|
|
|
398
399
|
|
|
399
400
|
async updateProvider() {
|
|
400
401
|
if (this.editingProvider.readOnly || this.editingProvider.nonEditable) {
|
|
401
|
-
this.showMessage('
|
|
402
|
+
this.showMessage(this.t('toast.provider.notEditable'), 'error');
|
|
402
403
|
this.closeEditModal();
|
|
403
404
|
return;
|
|
404
405
|
}
|
|
405
406
|
normalizeProviderDraftState(this.editingProvider);
|
|
406
407
|
const validation = getProviderValidationForContext(this, 'edit');
|
|
407
408
|
if (!validation.ok) {
|
|
408
|
-
return this.showMessage(validation.errors.name || validation.errors.url || '
|
|
409
|
+
return this.showMessage(validation.errors.name || validation.errors.url || this.t('toast.provider.urlRequired'), 'error');
|
|
409
410
|
}
|
|
410
411
|
|
|
411
412
|
const params = { name: validation.name, url: validation.url };
|
|
@@ -441,9 +442,9 @@ export function createProvidersMethods(options = {}) {
|
|
|
441
442
|
});
|
|
442
443
|
|
|
443
444
|
this.closeEditModal();
|
|
444
|
-
this.showMessage('
|
|
445
|
+
this.showMessage(this.t('toast.operation.success'), 'success');
|
|
445
446
|
} catch (e) {
|
|
446
|
-
this.showMessage('
|
|
447
|
+
this.showMessage(this.t('toast.provider.updateFail'), 'error');
|
|
447
448
|
}
|
|
448
449
|
},
|
|
449
450
|
|
|
@@ -469,10 +470,10 @@ export function createProvidersMethods(options = {}) {
|
|
|
469
470
|
return;
|
|
470
471
|
}
|
|
471
472
|
const backup = res.backupFile ? `(已备份: ${res.backupFile})` : '';
|
|
472
|
-
this.showMessage(
|
|
473
|
+
this.showMessage(this.t('toast.provider.resetSuccess', { backup }), 'success');
|
|
473
474
|
await this.loadAll();
|
|
474
475
|
} catch (e) {
|
|
475
|
-
this.showMessage('
|
|
476
|
+
this.showMessage(this.t('toast.provider.resetFail'), 'error');
|
|
476
477
|
} finally {
|
|
477
478
|
this.resetConfigLoading = false;
|
|
478
479
|
}
|
|
@@ -501,7 +502,7 @@ export function createProvidersMethods(options = {}) {
|
|
|
501
502
|
}
|
|
502
503
|
return p;
|
|
503
504
|
});
|
|
504
|
-
this.showMessage('
|
|
505
|
+
this.showMessage(this.t('toast.operation.success'), 'success');
|
|
505
506
|
this.closeModelModal();
|
|
506
507
|
}
|
|
507
508
|
} catch (_) {
|
|
@@ -525,7 +526,7 @@ export function createProvidersMethods(options = {}) {
|
|
|
525
526
|
}
|
|
526
527
|
return p;
|
|
527
528
|
});
|
|
528
|
-
this.showMessage('
|
|
529
|
+
this.showMessage(this.t('toast.operation.success'), 'success');
|
|
529
530
|
}
|
|
530
531
|
} catch (_) {
|
|
531
532
|
this.showMessage('删除模型失败', 'error');
|
|
@@ -4,21 +4,21 @@ import {
|
|
|
4
4
|
} from '../logic.mjs';
|
|
5
5
|
|
|
6
6
|
const UI_MESSAGE_KEY_BY_TEXT = Object.freeze({
|
|
7
|
-
'操作成功': 'toast.
|
|
8
|
-
'操作失败': 'toast.
|
|
9
|
-
'添加失败': 'toast.
|
|
10
|
-
'更新失败': 'toast.
|
|
11
|
-
'删除失败': 'toast.
|
|
12
|
-
'已删除': 'toast.
|
|
13
|
-
'已复制': 'toast.
|
|
14
|
-
'复制失败': 'toast.
|
|
7
|
+
'操作成功': 'toast.operation.success',
|
|
8
|
+
'操作失败': 'toast.operation.fail',
|
|
9
|
+
'添加失败': 'toast.provider.addFail',
|
|
10
|
+
'更新失败': 'toast.provider.updateFail',
|
|
11
|
+
'删除失败': 'toast.delete.fail',
|
|
12
|
+
'已删除': 'toast.delete.ok',
|
|
13
|
+
'已复制': 'toast.copy.ok',
|
|
14
|
+
'复制失败': 'toast.copy.fail',
|
|
15
15
|
'剪贴板为空': 'toast.clipboardEmpty',
|
|
16
16
|
'无法读取剪贴板': 'toast.clipboardReadFailed',
|
|
17
17
|
'已粘贴': 'toast.pasted',
|
|
18
18
|
'未检测到改动': 'toast.noChanges',
|
|
19
|
-
'配置已应用': 'toast.
|
|
20
|
-
'应用配置失败': 'toast.
|
|
21
|
-
'应用失败': 'toast.
|
|
19
|
+
'配置已应用': 'toast.apply.success',
|
|
20
|
+
'应用配置失败': 'toast.apply.fail',
|
|
21
|
+
'应用失败': 'toast.apply.fail',
|
|
22
22
|
'配置已加载': 'toast.configLoaded',
|
|
23
23
|
'配置就绪': 'toast.configReady',
|
|
24
24
|
'加载配置失败': 'toast.loadConfigFailed',
|
|
@@ -26,12 +26,12 @@ const UI_MESSAGE_KEY_BY_TEXT = Object.freeze({
|
|
|
26
26
|
'读取配置超时': 'toast.readConfigTimeout',
|
|
27
27
|
'备份失败': 'toast.backupFailed',
|
|
28
28
|
'备份成功,开始下载': 'toast.backupReadyDownload',
|
|
29
|
-
'导入失败': 'toast.
|
|
30
|
-
'导入成功': 'toast.
|
|
29
|
+
'导入失败': 'toast.import.fail',
|
|
30
|
+
'导入成功': 'toast.import.ok',
|
|
31
31
|
'导入 skill 失败': 'toast.importSkillFailed',
|
|
32
|
-
'导出失败': 'toast.
|
|
33
|
-
'保存失败': 'toast.
|
|
34
|
-
'加载文件失败': 'toast.
|
|
32
|
+
'导出失败': 'toast.export.fail',
|
|
33
|
+
'保存失败': 'toast.save.fail',
|
|
34
|
+
'加载文件失败': 'toast.load.fail',
|
|
35
35
|
'请填写名称': 'toast.nameRequired',
|
|
36
36
|
'请输入名称': 'toast.nameRequired',
|
|
37
37
|
'名称已存在': 'toast.nameExists',
|
|
@@ -45,8 +45,8 @@ const UI_MESSAGE_KEY_BY_TEXT = Object.freeze({
|
|
|
45
45
|
'不可分享': 'toast.notShareable',
|
|
46
46
|
'已移入回收站': 'toast.movedToTrash',
|
|
47
47
|
'生成命令失败': 'toast.commandGenerationFailed',
|
|
48
|
-
'没有可复制内容': 'toast.
|
|
49
|
-
'没有可导出内容': 'toast.
|
|
48
|
+
'没有可复制内容': 'toast.copy.empty',
|
|
49
|
+
'没有可导出内容': 'toast.export.empty',
|
|
50
50
|
'会话已恢复': 'toast.sessionRestored',
|
|
51
51
|
'恢复失败': 'toast.restoreFailed',
|
|
52
52
|
'已彻底删除': 'toast.purged',
|
|
@@ -66,16 +66,22 @@ const UI_MESSAGE_PREFIX_ENTRIES = Object.freeze(
|
|
|
66
66
|
Object.entries(UI_MESSAGE_KEY_BY_TEXT).sort((a, b) => b[0].length - a[0].length)
|
|
67
67
|
);
|
|
68
68
|
|
|
69
|
-
function translateUiMessage(context, text) {
|
|
69
|
+
export function translateUiMessage(context, text) {
|
|
70
70
|
if (!context || typeof context.t !== 'function' || typeof text !== 'string') return text;
|
|
71
|
+
const translateKey = (key) => {
|
|
72
|
+
const translated = context.t(key);
|
|
73
|
+
return typeof translated === 'string' && translated && translated !== key ? translated : '';
|
|
74
|
+
};
|
|
71
75
|
const exactKey = UI_MESSAGE_KEY_BY_TEXT[text];
|
|
72
|
-
if (exactKey) return
|
|
76
|
+
if (exactKey) return translateKey(exactKey) || text;
|
|
73
77
|
const prefixEntry = UI_MESSAGE_PREFIX_ENTRIES.find(([sourceText]) => {
|
|
74
78
|
return text.length > sourceText.length && text.startsWith(sourceText);
|
|
75
79
|
});
|
|
76
80
|
if (!prefixEntry) return text;
|
|
77
81
|
const [sourceText, key] = prefixEntry;
|
|
78
|
-
|
|
82
|
+
const translatedPrefix = translateKey(key);
|
|
83
|
+
if (!translatedPrefix) return text;
|
|
84
|
+
return `${translatedPrefix}${text.slice(sourceText.length)}`;
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
function clearProgressResetTimer(context, timerKey) {
|
|
@@ -126,7 +126,7 @@ export function createSessionActionMethods(options = {}) {
|
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
128
|
} catch (_) {}
|
|
129
|
-
this.showMessage('
|
|
129
|
+
this.showMessage(this.t('toast.copy.fail'), 'error');
|
|
130
130
|
},
|
|
131
131
|
|
|
132
132
|
getSessionFilePath(session) {
|
|
@@ -152,7 +152,7 @@ export function createSessionActionMethods(options = {}) {
|
|
|
152
152
|
return;
|
|
153
153
|
}
|
|
154
154
|
} catch (_) {}
|
|
155
|
-
this.showMessage('
|
|
155
|
+
this.showMessage(this.t('toast.copy.fail'), 'error');
|
|
156
156
|
},
|
|
157
157
|
|
|
158
158
|
getSessionExportKey(session) {
|
|
@@ -312,15 +312,15 @@ export function createSessionActionMethods(options = {}) {
|
|
|
312
312
|
copyAgentsContent() {
|
|
313
313
|
const text = typeof this.agentsContent === 'string' ? this.agentsContent : '';
|
|
314
314
|
if (!text) {
|
|
315
|
-
this.showMessage('
|
|
315
|
+
this.showMessage(this.t('toast.copy.empty'), 'info');
|
|
316
316
|
return;
|
|
317
317
|
}
|
|
318
318
|
const ok = this.fallbackCopyText(text);
|
|
319
319
|
if (ok) {
|
|
320
|
-
this.showMessage('
|
|
320
|
+
this.showMessage(this.t('toast.copy.ok'), 'success');
|
|
321
321
|
return;
|
|
322
322
|
}
|
|
323
|
-
this.showMessage('
|
|
323
|
+
this.showMessage(this.t('toast.copy.fail'), 'error');
|
|
324
324
|
},
|
|
325
325
|
|
|
326
326
|
exportAgentsContent() {
|
|
@@ -344,7 +344,7 @@ export function createSessionActionMethods(options = {}) {
|
|
|
344
344
|
async copyInstallCommand(cmd) {
|
|
345
345
|
const text = typeof cmd === 'string' ? cmd.trim() : '';
|
|
346
346
|
if (!text) {
|
|
347
|
-
this.showMessage('
|
|
347
|
+
this.showMessage(this.t('toast.copy.empty'), 'info');
|
|
348
348
|
return;
|
|
349
349
|
}
|
|
350
350
|
try {
|
|
@@ -359,7 +359,7 @@ export function createSessionActionMethods(options = {}) {
|
|
|
359
359
|
this.showMessage('已复制命令', 'success');
|
|
360
360
|
return;
|
|
361
361
|
}
|
|
362
|
-
this.showMessage('
|
|
362
|
+
this.showMessage(this.t('toast.copy.fail'), 'error');
|
|
363
363
|
},
|
|
364
364
|
|
|
365
365
|
async copyResumeCommand(session) {
|
|
@@ -370,17 +370,17 @@ export function createSessionActionMethods(options = {}) {
|
|
|
370
370
|
const command = this.buildResumeCommand(session);
|
|
371
371
|
const ok = this.fallbackCopyText(command);
|
|
372
372
|
if (ok) {
|
|
373
|
-
this.showMessage('
|
|
373
|
+
this.showMessage(this.t('toast.copy.ok'), 'success');
|
|
374
374
|
return;
|
|
375
375
|
}
|
|
376
376
|
try {
|
|
377
377
|
if (navigator.clipboard && window.isSecureContext) {
|
|
378
378
|
await navigator.clipboard.writeText(command);
|
|
379
|
-
this.showMessage('
|
|
379
|
+
this.showMessage(this.t('toast.copy.ok'), 'success');
|
|
380
380
|
return;
|
|
381
381
|
}
|
|
382
382
|
} catch (_) {}
|
|
383
|
-
this.showMessage('
|
|
383
|
+
this.showMessage(this.t('toast.copy.fail'), 'error');
|
|
384
384
|
},
|
|
385
385
|
|
|
386
386
|
buildProviderShareCommand(payload) {
|
|
@@ -412,11 +412,16 @@ export function createSessionActionMethods(options = {}) {
|
|
|
412
412
|
const model = typeof payload.model === 'string' && payload.model.trim()
|
|
413
413
|
? payload.model.trim()
|
|
414
414
|
: 'glm-4.7';
|
|
415
|
-
|
|
415
|
+
const targetApiRaw = typeof payload.targetApi === 'string' ? payload.targetApi.trim().toLowerCase() : '';
|
|
416
|
+
const targetApi = targetApiRaw === 'chat_completions' || targetApiRaw === 'chat-completions' || targetApiRaw === 'chat/completions'
|
|
417
|
+
? 'chat_completions'
|
|
418
|
+
: (targetApiRaw === 'ollama' ? 'ollama' : 'responses');
|
|
419
|
+
if (!baseUrl || (!apiKey && targetApi !== 'ollama')) return '';
|
|
416
420
|
const urlArg = this.quoteShellArg(baseUrl);
|
|
417
421
|
const keyArg = this.quoteShellArg(apiKey);
|
|
418
422
|
const modelArg = this.quoteShellArg(model);
|
|
419
|
-
|
|
423
|
+
const targetArg = targetApi !== 'responses' ? ` --target-api ${this.quoteShellArg(targetApi)}` : '';
|
|
424
|
+
return `${this.getShareCommandPrefixInvocation()} claude ${urlArg} ${keyArg} ${modelArg}${targetArg}`;
|
|
420
425
|
},
|
|
421
426
|
|
|
422
427
|
async copyProviderShareCommand(provider) {
|
|
@@ -446,17 +451,17 @@ export function createSessionActionMethods(options = {}) {
|
|
|
446
451
|
}
|
|
447
452
|
const ok = this.fallbackCopyText(command);
|
|
448
453
|
if (ok) {
|
|
449
|
-
this.showMessage('
|
|
454
|
+
this.showMessage(this.t('toast.copy.ok'), 'success');
|
|
450
455
|
return;
|
|
451
456
|
}
|
|
452
457
|
try {
|
|
453
458
|
if (navigator.clipboard && window.isSecureContext) {
|
|
454
459
|
await navigator.clipboard.writeText(command);
|
|
455
|
-
this.showMessage('
|
|
460
|
+
this.showMessage(this.t('toast.copy.ok'), 'success');
|
|
456
461
|
return;
|
|
457
462
|
}
|
|
458
463
|
} catch (_) {}
|
|
459
|
-
this.showMessage('
|
|
464
|
+
this.showMessage(this.t('toast.copy.fail'), 'error');
|
|
460
465
|
} catch (_) {
|
|
461
466
|
this.showMessage('生成命令失败', 'error');
|
|
462
467
|
} finally {
|
|
@@ -485,17 +490,17 @@ export function createSessionActionMethods(options = {}) {
|
|
|
485
490
|
}
|
|
486
491
|
const ok = this.fallbackCopyText(command);
|
|
487
492
|
if (ok) {
|
|
488
|
-
this.showMessage('
|
|
493
|
+
this.showMessage(this.t('toast.copy.ok'), 'success');
|
|
489
494
|
return;
|
|
490
495
|
}
|
|
491
496
|
try {
|
|
492
497
|
if (navigator.clipboard && window.isSecureContext) {
|
|
493
498
|
await navigator.clipboard.writeText(command);
|
|
494
|
-
this.showMessage('
|
|
499
|
+
this.showMessage(this.t('toast.copy.ok'), 'success');
|
|
495
500
|
return;
|
|
496
501
|
}
|
|
497
502
|
} catch (_) {}
|
|
498
|
-
this.showMessage('
|
|
503
|
+
this.showMessage(this.t('toast.copy.fail'), 'error');
|
|
499
504
|
} catch (_) {
|
|
500
505
|
this.showMessage('生成命令失败', 'error');
|
|
501
506
|
} finally {
|
|
@@ -524,7 +529,7 @@ export function createSessionActionMethods(options = {}) {
|
|
|
524
529
|
return;
|
|
525
530
|
}
|
|
526
531
|
|
|
527
|
-
this.showMessage('
|
|
532
|
+
this.showMessage(this.t('toast.operation.success'), 'success');
|
|
528
533
|
if (typeof this.invalidateSessionsUsageData === 'function') {
|
|
529
534
|
this.invalidateSessionsUsageData({ preserveList: true });
|
|
530
535
|
}
|
|
@@ -608,7 +613,7 @@ export function createSessionActionMethods(options = {}) {
|
|
|
608
613
|
// The delete already succeeded remotely; keep the success result.
|
|
609
614
|
}
|
|
610
615
|
} catch (_) {
|
|
611
|
-
this.showMessage('
|
|
616
|
+
this.showMessage(this.t('toast.delete.fail'), 'error');
|
|
612
617
|
} finally {
|
|
613
618
|
this.sessionDeleting[key] = false;
|
|
614
619
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
findDuplicateClaudeConfigName,
|
|
3
3
|
getClaudeModelCatalogForBaseUrl,
|
|
4
|
+
isLikelyBuiltinClaudeProxySettingsEnv,
|
|
5
|
+
matchBuiltinClaudeProxyConfigFromSettings,
|
|
4
6
|
matchClaudeConfigFromSettings,
|
|
5
7
|
normalizeClaudeConfig,
|
|
6
8
|
normalizeClaudeSettingsEnv,
|
|
@@ -125,6 +127,9 @@ export function createStartupClaudeMethods(options = {}) {
|
|
|
125
127
|
codex: statusRes.toolConfigPermissions.codex === true,
|
|
126
128
|
claude: statusRes.toolConfigPermissions.claude === true
|
|
127
129
|
};
|
|
130
|
+
try {
|
|
131
|
+
localStorage.setItem('toolConfigPermissions', JSON.stringify(this.toolConfigPermissions));
|
|
132
|
+
} catch (_) {}
|
|
128
133
|
}
|
|
129
134
|
this.providersList = listRes.providers;
|
|
130
135
|
if (typeof this.loadLocalBridgeExcluded === 'function') { this.loadLocalBridgeExcluded(); }
|
|
@@ -238,6 +243,14 @@ export function createStartupClaudeMethods(options = {}) {
|
|
|
238
243
|
return matchClaudeConfigFromSettings(this.claudeConfigs, env);
|
|
239
244
|
},
|
|
240
245
|
|
|
246
|
+
matchBuiltinClaudeProxyConfigFromSettings(env) {
|
|
247
|
+
return matchBuiltinClaudeProxyConfigFromSettings(this.claudeConfigs, env, this.currentClaudeConfig);
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
shouldSuppressClaudeSettingsImport(env) {
|
|
251
|
+
return isLikelyBuiltinClaudeProxySettingsEnv(env);
|
|
252
|
+
},
|
|
253
|
+
|
|
241
254
|
findDuplicateClaudeConfigName(config) {
|
|
242
255
|
return findDuplicateClaudeConfigName(this.claudeConfigs, config);
|
|
243
256
|
},
|
|
@@ -253,7 +266,8 @@ export function createStartupClaudeMethods(options = {}) {
|
|
|
253
266
|
baseUrl: next.baseUrl,
|
|
254
267
|
model: next.model || previous.model || 'glm-4.7',
|
|
255
268
|
hasKey: !!(next.apiKey || externalCredentialType),
|
|
256
|
-
externalCredentialType
|
|
269
|
+
externalCredentialType,
|
|
270
|
+
targetApi: next.targetApi || previous.targetApi || 'responses'
|
|
257
271
|
};
|
|
258
272
|
},
|
|
259
273
|
|
|
@@ -329,7 +343,8 @@ export function createStartupClaudeMethods(options = {}) {
|
|
|
329
343
|
}
|
|
330
344
|
return;
|
|
331
345
|
}
|
|
332
|
-
const
|
|
346
|
+
const settingsEnv = (res && res.env) || {};
|
|
347
|
+
const matchName = this.matchClaudeConfigFromSettings(settingsEnv);
|
|
333
348
|
if (matchName) {
|
|
334
349
|
if (this.currentClaudeConfig !== matchName) {
|
|
335
350
|
this.currentClaudeConfig = matchName;
|
|
@@ -338,7 +353,18 @@ export function createStartupClaudeMethods(options = {}) {
|
|
|
338
353
|
this.refreshClaudeModelContext({ silentError: silentModelError });
|
|
339
354
|
return;
|
|
340
355
|
}
|
|
341
|
-
const
|
|
356
|
+
const builtinProxyMatch = this.matchBuiltinClaudeProxyConfigFromSettings(settingsEnv);
|
|
357
|
+
if (builtinProxyMatch) {
|
|
358
|
+
if (this.currentClaudeConfig !== builtinProxyMatch) {
|
|
359
|
+
this.currentClaudeConfig = builtinProxyMatch;
|
|
360
|
+
try { localStorage.setItem('currentClaudeConfig', builtinProxyMatch); } catch (_) {}
|
|
361
|
+
}
|
|
362
|
+
this.refreshClaudeModelContext({ silentError: silentModelError });
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
const importedName = this.shouldSuppressClaudeSettingsImport(settingsEnv)
|
|
366
|
+
? ''
|
|
367
|
+
: this.ensureClaudeConfigFromSettings(settingsEnv);
|
|
342
368
|
if (importedName) {
|
|
343
369
|
if (this.currentClaudeConfig !== importedName) {
|
|
344
370
|
this.currentClaudeConfig = importedName;
|
|
@@ -64,6 +64,9 @@ export function createToolConfigPermissionMethods(options = {}) {
|
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
this.toolConfigPermissions = normalizePermissions(res && res.permissions);
|
|
67
|
+
try {
|
|
68
|
+
localStorage.setItem('toolConfigPermissions', JSON.stringify(this.toolConfigPermissions));
|
|
69
|
+
} catch (_) {}
|
|
67
70
|
this.showMessage(
|
|
68
71
|
nextAllowWrite
|
|
69
72
|
? this.t('toolConfig.allowToast')
|