codexmate 0.0.9 → 0.0.12
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 +25 -6
- package/README.zh-CN.md +25 -6
- package/package.json +53 -36
- package/res/logo.png +0 -0
- package/{cli.js → src/cli.js} +822 -327
- package/src/lib/cli-file-utils.js +151 -0
- package/src/lib/cli-models-utils.js +152 -0
- package/src/lib/cli-network-utils.js +148 -0
- package/src/lib/cli-session-utils.js +121 -0
- package/src/lib/cli-utils.js +139 -0
- package/src/res/json5.min.js +1 -0
- package/src/res/logo.png +0 -0
- package/src/res/screenshot.png +0 -0
- package/src/res/vue.global.js +18552 -0
- package/src/web-ui/app.js +2970 -0
- package/src/web-ui/index.html +1310 -0
- package/src/web-ui/logic.mjs +157 -0
- package/src/web-ui/styles.css +2868 -0
- package/src/web-ui.html +17 -0
- package/web-ui/app.js +273 -144
- package/web-ui/index.html +1310 -0
- package/web-ui/logic.mjs +21 -21
- package/web-ui/styles.css +2868 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -27
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
- package/.github/workflows/ci.yml +0 -26
- package/.github/workflows/release.yml +0 -159
- package/.planning/.fix-attempts +0 -1
- package/.planning/.lock +0 -6
- package/.planning/.verify-cache.json +0 -14
- package/.planning/CHECKPOINT.json +0 -46
- package/.planning/DESIGN.md +0 -26
- package/.planning/HISTORY.json +0 -124
- package/.planning/PLAN.md +0 -69
- package/.planning/REVIEW.md +0 -41
- package/.planning/STATE.md +0 -12
- package/.planning/STATS.json +0 -13
- package/.planning/VERIFICATION.md +0 -70
- package/.planning/daude-code-plan.md +0 -51
- package/.planning/research/architecture.md +0 -32
- package/.planning/research/conventions.md +0 -36
- package/.planning/task_1-REVIEW.md +0 -29
- package/.planning/task_1-SUMMARY.md +0 -32
- package/.planning/task_2-REVIEW.md +0 -24
- package/.planning/task_2-SUMMARY.md +0 -37
- package/.planning/task_3-REVIEW.md +0 -25
- package/.planning/task_3-SUMMARY.md +0 -31
- package/cmd/publish-npm.cmd +0 -65
- package/tests/e2e/helpers.js +0 -214
- package/tests/e2e/recent-health.e2e.js +0 -142
- package/tests/e2e/run.js +0 -154
- package/tests/e2e/test-claude.js +0 -21
- package/tests/e2e/test-config.js +0 -124
- package/tests/e2e/test-health-speed.js +0 -79
- package/tests/e2e/test-openclaw.js +0 -47
- package/tests/e2e/test-session-search.js +0 -114
- package/tests/e2e/test-sessions.js +0 -69
- package/tests/e2e/test-setup.js +0 -159
- package/tests/unit/run.mjs +0 -29
- package/tests/unit/web-ui-logic.test.mjs +0 -186
- package/web-ui.html +0 -3977
- /package/{CHANGELOG.md → doc/CHANGELOG.md} +0 -0
- /package/{CHANGELOG.zh-CN.md → doc/CHANGELOG.zh-CN.md} +0 -0
package/web-ui/app.js
CHANGED
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
currentProvider: '',
|
|
59
59
|
currentModel: '',
|
|
60
60
|
serviceTier: 'fast',
|
|
61
|
+
modelReasoningEffort: 'high',
|
|
61
62
|
providersList: [],
|
|
62
63
|
models: [],
|
|
63
64
|
codexModelsLoading: false,
|
|
@@ -80,8 +81,10 @@
|
|
|
80
81
|
showOpenclawConfigModal: false,
|
|
81
82
|
showConfigTemplateModal: false,
|
|
82
83
|
showAgentsModal: false,
|
|
84
|
+
showInstallModal: false,
|
|
83
85
|
configTemplateContent: '',
|
|
84
86
|
configTemplateApplying: false,
|
|
87
|
+
codexApplying: false,
|
|
85
88
|
agentsContent: '',
|
|
86
89
|
agentsPath: '',
|
|
87
90
|
agentsExists: false,
|
|
@@ -91,9 +94,9 @@
|
|
|
91
94
|
agentsContext: 'codex',
|
|
92
95
|
agentsModalTitle: 'AGENTS.md 编辑器',
|
|
93
96
|
agentsModalHint: '保存后会写入目标 AGENTS.md(与 config.toml 同级)。',
|
|
94
|
-
sessionsList: [],
|
|
95
|
-
sessionsLoading: false,
|
|
96
|
-
sessionFilterSource: '
|
|
97
|
+
sessionsList: [],
|
|
98
|
+
sessionsLoading: false,
|
|
99
|
+
sessionFilterSource: 'all',
|
|
97
100
|
sessionPathFilter: '',
|
|
98
101
|
sessionQuery: '',
|
|
99
102
|
sessionRoleFilter: 'all',
|
|
@@ -134,7 +137,12 @@
|
|
|
134
137
|
claudeSpeedLoading: {},
|
|
135
138
|
claudeShareLoading: {},
|
|
136
139
|
providerShareLoading: {},
|
|
140
|
+
installCommands: [
|
|
141
|
+
'npm install -g @anthropic-ai/claude-code',
|
|
142
|
+
'npm i -g @openai/codex'
|
|
143
|
+
],
|
|
137
144
|
newProvider: { name: '', url: '', key: '' },
|
|
145
|
+
resetConfigLoading: false,
|
|
138
146
|
editingProvider: { name: '', url: '', key: '' },
|
|
139
147
|
newModelName: '',
|
|
140
148
|
currentClaudeConfig: '',
|
|
@@ -248,19 +256,19 @@
|
|
|
248
256
|
this.loadAll();
|
|
249
257
|
},
|
|
250
258
|
|
|
251
|
-
computed: {
|
|
252
|
-
isSessionQueryEnabled() {
|
|
253
|
-
return isSessionQueryEnabled(this.sessionFilterSource);
|
|
254
|
-
},
|
|
255
|
-
sessionQueryPlaceholder() {
|
|
256
|
-
if (this.isSessionQueryEnabled) {
|
|
257
|
-
return '关键词检索(支持 Codex/Claude,例:claude code)';
|
|
258
|
-
}
|
|
259
|
-
return '当前来源暂不支持关键词检索';
|
|
260
|
-
},
|
|
261
|
-
claudeModelHasList() {
|
|
262
|
-
return Array.isArray(this.claudeModels) && this.claudeModels.length > 0;
|
|
263
|
-
},
|
|
259
|
+
computed: {
|
|
260
|
+
isSessionQueryEnabled() {
|
|
261
|
+
return isSessionQueryEnabled(this.sessionFilterSource);
|
|
262
|
+
},
|
|
263
|
+
sessionQueryPlaceholder() {
|
|
264
|
+
if (this.isSessionQueryEnabled) {
|
|
265
|
+
return '关键词检索(支持 Codex/Claude,例:claude code)';
|
|
266
|
+
}
|
|
267
|
+
return '当前来源暂不支持关键词检索';
|
|
268
|
+
},
|
|
269
|
+
claudeModelHasList() {
|
|
270
|
+
return Array.isArray(this.claudeModels) && this.claudeModels.length > 0;
|
|
271
|
+
},
|
|
264
272
|
claudeModelOptions() {
|
|
265
273
|
const list = Array.isArray(this.claudeModels) ? [...this.claudeModels] : [];
|
|
266
274
|
const current = (this.currentClaudeModel || '').trim();
|
|
@@ -275,8 +283,7 @@
|
|
|
275
283
|
this.loading = true;
|
|
276
284
|
this.initError = '';
|
|
277
285
|
try {
|
|
278
|
-
const statusRes = await api('status');
|
|
279
|
-
const listRes = await api('list');
|
|
286
|
+
const [statusRes, listRes] = await Promise.all([api('status'), api('list')]);
|
|
280
287
|
|
|
281
288
|
if (statusRes.error) {
|
|
282
289
|
this.initError = statusRes.error;
|
|
@@ -289,13 +296,18 @@
|
|
|
289
296
|
: '';
|
|
290
297
|
this.serviceTier = tier === 'fast' ? 'fast' : (tier ? 'standard' : 'fast');
|
|
291
298
|
}
|
|
299
|
+
{
|
|
300
|
+
const effort = typeof statusRes.modelReasoningEffort === 'string'
|
|
301
|
+
? statusRes.modelReasoningEffort.trim().toLowerCase()
|
|
302
|
+
: '';
|
|
303
|
+
this.modelReasoningEffort = effort || 'high';
|
|
304
|
+
}
|
|
292
305
|
this.providersList = listRes.providers;
|
|
293
|
-
await this.loadModelsForProvider(this.currentProvider);
|
|
294
306
|
if (statusRes.configReady === false) {
|
|
295
|
-
this.showMessage(
|
|
307
|
+
this.showMessage('配置已加载', 'info');
|
|
296
308
|
}
|
|
297
309
|
if (statusRes.initNotice) {
|
|
298
|
-
this.showMessage(
|
|
310
|
+
this.showMessage('配置就绪', 'info');
|
|
299
311
|
}
|
|
300
312
|
this.maybeShowStarPrompt();
|
|
301
313
|
}
|
|
@@ -304,6 +316,13 @@
|
|
|
304
316
|
} finally {
|
|
305
317
|
this.loading = false;
|
|
306
318
|
}
|
|
319
|
+
|
|
320
|
+
// 模型加载单独异步,不阻塞主 loading
|
|
321
|
+
try {
|
|
322
|
+
await this.loadModelsForProvider(this.currentProvider);
|
|
323
|
+
} catch (e) {
|
|
324
|
+
// loadModelsForProvider 内部已有 toast,这里吞掉防止抛出
|
|
325
|
+
}
|
|
307
326
|
},
|
|
308
327
|
|
|
309
328
|
async loadModelsForProvider(providerName) {
|
|
@@ -324,7 +343,7 @@
|
|
|
324
343
|
return;
|
|
325
344
|
}
|
|
326
345
|
if (res.error) {
|
|
327
|
-
this.showMessage('
|
|
346
|
+
this.showMessage('获取模型列表失败', 'error');
|
|
328
347
|
this.models = [];
|
|
329
348
|
this.modelsSource = 'error';
|
|
330
349
|
this.modelsHasCurrent = true;
|
|
@@ -335,7 +354,7 @@
|
|
|
335
354
|
this.modelsSource = res.source || 'remote';
|
|
336
355
|
this.modelsHasCurrent = !!this.currentModel && list.includes(this.currentModel);
|
|
337
356
|
} catch (e) {
|
|
338
|
-
this.showMessage('
|
|
357
|
+
this.showMessage('获取模型列表失败', 'error');
|
|
339
358
|
this.models = [];
|
|
340
359
|
this.modelsSource = 'error';
|
|
341
360
|
this.modelsHasCurrent = true;
|
|
@@ -380,7 +399,7 @@
|
|
|
380
399
|
const res = await api('get-claude-settings');
|
|
381
400
|
if (res && res.error) {
|
|
382
401
|
if (!silent) {
|
|
383
|
-
this.showMessage('
|
|
402
|
+
this.showMessage('读取配置失败', 'error');
|
|
384
403
|
}
|
|
385
404
|
return;
|
|
386
405
|
}
|
|
@@ -403,7 +422,7 @@
|
|
|
403
422
|
}
|
|
404
423
|
} catch (e) {
|
|
405
424
|
if (!silent) {
|
|
406
|
-
this.showMessage('
|
|
425
|
+
this.showMessage('读取配置失败', 'error');
|
|
407
426
|
}
|
|
408
427
|
}
|
|
409
428
|
},
|
|
@@ -454,7 +473,7 @@
|
|
|
454
473
|
return;
|
|
455
474
|
}
|
|
456
475
|
if (res.error) {
|
|
457
|
-
this.showMessage('
|
|
476
|
+
this.showMessage('获取模型列表失败', 'error');
|
|
458
477
|
this.claudeModels = [];
|
|
459
478
|
this.claudeModelsSource = 'error';
|
|
460
479
|
this.claudeModelsHasCurrent = true;
|
|
@@ -465,7 +484,7 @@
|
|
|
465
484
|
this.claudeModelsSource = res.source || 'remote';
|
|
466
485
|
this.updateClaudeModelsCurrent();
|
|
467
486
|
} catch (e) {
|
|
468
|
-
this.showMessage('
|
|
487
|
+
this.showMessage('获取模型列表失败', 'error');
|
|
469
488
|
this.claudeModels = [];
|
|
470
489
|
this.claudeModelsSource = 'error';
|
|
471
490
|
this.claudeModelsHasCurrent = true;
|
|
@@ -483,7 +502,7 @@
|
|
|
483
502
|
if (localStorage.getItem(storageKey)) {
|
|
484
503
|
return;
|
|
485
504
|
}
|
|
486
|
-
this.showMessage('
|
|
505
|
+
this.showMessage('欢迎到 GitHub 点 Star', 'info');
|
|
487
506
|
localStorage.setItem(storageKey, '1');
|
|
488
507
|
},
|
|
489
508
|
|
|
@@ -593,7 +612,7 @@
|
|
|
593
612
|
openSessionStandalone(session) {
|
|
594
613
|
const url = this.buildSessionStandaloneUrl(session);
|
|
595
614
|
if (!url) {
|
|
596
|
-
this.showMessage('
|
|
615
|
+
this.showMessage('无法生成链接', 'error');
|
|
597
616
|
return;
|
|
598
617
|
}
|
|
599
618
|
window.open(url, '_blank', 'noopener');
|
|
@@ -674,38 +693,52 @@
|
|
|
674
693
|
copyAgentsContent() {
|
|
675
694
|
const text = typeof this.agentsContent === 'string' ? this.agentsContent : '';
|
|
676
695
|
if (!text) {
|
|
677
|
-
this.showMessage('
|
|
696
|
+
this.showMessage('没有可复制内容', 'info');
|
|
678
697
|
return;
|
|
679
698
|
}
|
|
680
699
|
const ok = this.fallbackCopyText(text);
|
|
681
700
|
if (ok) {
|
|
682
|
-
this.showMessage('已复制
|
|
701
|
+
this.showMessage('已复制', 'success');
|
|
683
702
|
return;
|
|
684
703
|
}
|
|
685
|
-
this.showMessage('
|
|
704
|
+
this.showMessage('复制失败', 'error');
|
|
705
|
+
},
|
|
706
|
+
|
|
707
|
+
copyInstallCommand(cmd) {
|
|
708
|
+
const text = typeof cmd === 'string' ? cmd.trim() : '';
|
|
709
|
+
if (!text) {
|
|
710
|
+
this.showMessage('没有可复制内容', 'info');
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
const ok = this.fallbackCopyText(text);
|
|
714
|
+
if (ok) {
|
|
715
|
+
this.showMessage('已复制命令', 'success');
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
this.showMessage('复制失败', 'error');
|
|
686
719
|
},
|
|
687
720
|
|
|
688
721
|
async copyResumeCommand(session) {
|
|
689
722
|
if (!this.isResumeCommandAvailable(session)) {
|
|
690
|
-
this.showMessage('
|
|
723
|
+
this.showMessage('不支持此操作', 'error');
|
|
691
724
|
return;
|
|
692
725
|
}
|
|
693
726
|
const command = this.buildResumeCommand(session);
|
|
694
727
|
const ok = this.fallbackCopyText(command);
|
|
695
728
|
if (ok) {
|
|
696
|
-
this.showMessage('
|
|
729
|
+
this.showMessage('已复制', 'success');
|
|
697
730
|
return;
|
|
698
731
|
}
|
|
699
732
|
try {
|
|
700
733
|
if (navigator.clipboard && window.isSecureContext) {
|
|
701
734
|
await navigator.clipboard.writeText(command);
|
|
702
|
-
this.showMessage('
|
|
735
|
+
this.showMessage('已复制', 'success');
|
|
703
736
|
return;
|
|
704
737
|
}
|
|
705
738
|
} catch (e) {
|
|
706
739
|
// keep fallback failure message
|
|
707
740
|
}
|
|
708
|
-
this.showMessage('
|
|
741
|
+
this.showMessage('复制失败', 'error');
|
|
709
742
|
},
|
|
710
743
|
|
|
711
744
|
buildProviderShareCommand(payload) {
|
|
@@ -742,7 +775,7 @@
|
|
|
742
775
|
async copyProviderShareCommand(provider) {
|
|
743
776
|
const name = provider && typeof provider.name === 'string' ? provider.name.trim() : '';
|
|
744
777
|
if (!name) {
|
|
745
|
-
this.showMessage('
|
|
778
|
+
this.showMessage('参数无效', 'error');
|
|
746
779
|
return;
|
|
747
780
|
}
|
|
748
781
|
if (this.providerShareLoading[name]) {
|
|
@@ -757,26 +790,26 @@
|
|
|
757
790
|
}
|
|
758
791
|
const command = this.buildProviderShareCommand(res && res.payload ? res.payload : null);
|
|
759
792
|
if (!command) {
|
|
760
|
-
this.showMessage('
|
|
793
|
+
this.showMessage('生成命令失败', 'error');
|
|
761
794
|
return;
|
|
762
795
|
}
|
|
763
796
|
const ok = this.fallbackCopyText(command);
|
|
764
797
|
if (ok) {
|
|
765
|
-
this.showMessage('
|
|
798
|
+
this.showMessage('已复制', 'success');
|
|
766
799
|
return;
|
|
767
800
|
}
|
|
768
801
|
try {
|
|
769
802
|
if (navigator.clipboard && window.isSecureContext) {
|
|
770
803
|
await navigator.clipboard.writeText(command);
|
|
771
|
-
this.showMessage('
|
|
804
|
+
this.showMessage('已复制', 'success');
|
|
772
805
|
return;
|
|
773
806
|
}
|
|
774
807
|
} catch (e) {
|
|
775
808
|
// keep fallback failure message
|
|
776
809
|
}
|
|
777
|
-
this.showMessage('
|
|
810
|
+
this.showMessage('复制失败', 'error');
|
|
778
811
|
} catch (e) {
|
|
779
|
-
this.showMessage('
|
|
812
|
+
this.showMessage('生成命令失败', 'error');
|
|
780
813
|
} finally {
|
|
781
814
|
this.providerShareLoading[name] = false;
|
|
782
815
|
}
|
|
@@ -798,26 +831,26 @@
|
|
|
798
831
|
}
|
|
799
832
|
const command = this.buildClaudeShareCommand(res && res.payload ? res.payload : null);
|
|
800
833
|
if (!command) {
|
|
801
|
-
this.showMessage('
|
|
834
|
+
this.showMessage('生成命令失败', 'error');
|
|
802
835
|
return;
|
|
803
836
|
}
|
|
804
837
|
const ok = this.fallbackCopyText(command);
|
|
805
838
|
if (ok) {
|
|
806
|
-
this.showMessage('
|
|
839
|
+
this.showMessage('已复制', 'success');
|
|
807
840
|
return;
|
|
808
841
|
}
|
|
809
842
|
try {
|
|
810
843
|
if (navigator.clipboard && window.isSecureContext) {
|
|
811
844
|
await navigator.clipboard.writeText(command);
|
|
812
|
-
this.showMessage('
|
|
845
|
+
this.showMessage('已复制', 'success');
|
|
813
846
|
return;
|
|
814
847
|
}
|
|
815
848
|
} catch (e) {
|
|
816
849
|
// fall through
|
|
817
850
|
}
|
|
818
|
-
this.showMessage('
|
|
851
|
+
this.showMessage('复制失败', 'error');
|
|
819
852
|
} catch (e) {
|
|
820
|
-
this.showMessage('
|
|
853
|
+
this.showMessage('生成命令失败', 'error');
|
|
821
854
|
} finally {
|
|
822
855
|
this.claudeShareLoading[name] = false;
|
|
823
856
|
}
|
|
@@ -825,7 +858,7 @@
|
|
|
825
858
|
|
|
826
859
|
async cloneSession(session) {
|
|
827
860
|
if (!this.isCloneAvailable(session)) {
|
|
828
|
-
this.showMessage('
|
|
861
|
+
this.showMessage('不支持此操作', 'error');
|
|
829
862
|
return;
|
|
830
863
|
}
|
|
831
864
|
const key = this.getSessionExportKey(session);
|
|
@@ -844,7 +877,7 @@
|
|
|
844
877
|
return;
|
|
845
878
|
}
|
|
846
879
|
|
|
847
|
-
this.showMessage('
|
|
880
|
+
this.showMessage('操作成功', 'success');
|
|
848
881
|
await this.loadSessions();
|
|
849
882
|
if (res.sessionId) {
|
|
850
883
|
const matched = this.sessionsList.find(item => item.source === 'codex' && item.sessionId === res.sessionId);
|
|
@@ -853,7 +886,7 @@
|
|
|
853
886
|
}
|
|
854
887
|
}
|
|
855
888
|
} catch (e) {
|
|
856
|
-
this.showMessage('
|
|
889
|
+
this.showMessage('克隆失败', 'error');
|
|
857
890
|
} finally {
|
|
858
891
|
this.sessionCloning[key] = false;
|
|
859
892
|
}
|
|
@@ -861,7 +894,7 @@
|
|
|
861
894
|
|
|
862
895
|
async deleteSession(session) {
|
|
863
896
|
if (!this.isDeleteAvailable(session)) {
|
|
864
|
-
this.showMessage('
|
|
897
|
+
this.showMessage('不支持此操作', 'error');
|
|
865
898
|
return;
|
|
866
899
|
}
|
|
867
900
|
const key = this.getSessionExportKey(session);
|
|
@@ -879,10 +912,10 @@
|
|
|
879
912
|
this.showMessage(res.error, 'error');
|
|
880
913
|
return;
|
|
881
914
|
}
|
|
882
|
-
this.showMessage('
|
|
915
|
+
this.showMessage('操作成功', 'success');
|
|
883
916
|
await this.loadSessions();
|
|
884
917
|
} catch (e) {
|
|
885
|
-
this.showMessage('
|
|
918
|
+
this.showMessage('删除失败', 'error');
|
|
886
919
|
} finally {
|
|
887
920
|
this.sessionDeleting[key] = false;
|
|
888
921
|
}
|
|
@@ -893,7 +926,7 @@
|
|
|
893
926
|
return value.trim();
|
|
894
927
|
},
|
|
895
928
|
|
|
896
|
-
mergeSessionPathOptions(baseList = [], incomingList = []) {
|
|
929
|
+
mergeSessionPathOptions(baseList = [], incomingList = []) {
|
|
897
930
|
const merged = [];
|
|
898
931
|
const seen = new Set();
|
|
899
932
|
const append = (items) => {
|
|
@@ -931,8 +964,8 @@
|
|
|
931
964
|
return paths;
|
|
932
965
|
},
|
|
933
966
|
|
|
934
|
-
syncSessionPathOptionsForSource(source, nextOptions, mergeWithExisting = false) {
|
|
935
|
-
const targetSource = source === 'claude' ? 'claude' : 'codex';
|
|
967
|
+
syncSessionPathOptionsForSource(source, nextOptions, mergeWithExisting = false) {
|
|
968
|
+
const targetSource = source === 'claude' ? 'claude' : (source === 'all' ? 'all' : 'codex');
|
|
936
969
|
const current = Array.isArray(this.sessionPathOptionsMap[targetSource])
|
|
937
970
|
? this.sessionPathOptionsMap[targetSource]
|
|
938
971
|
: [];
|
|
@@ -944,10 +977,10 @@
|
|
|
944
977
|
[targetSource]: merged
|
|
945
978
|
};
|
|
946
979
|
this.refreshSessionPathOptions(targetSource);
|
|
947
|
-
},
|
|
948
|
-
|
|
949
|
-
refreshSessionPathOptions(source) {
|
|
950
|
-
const targetSource = source === 'claude' ? 'claude' : 'codex';
|
|
980
|
+
},
|
|
981
|
+
|
|
982
|
+
refreshSessionPathOptions(source) {
|
|
983
|
+
const targetSource = source === 'claude' ? 'claude' : (source === 'all' ? 'all' : 'codex');
|
|
951
984
|
const base = Array.isArray(this.sessionPathOptionsMap[targetSource])
|
|
952
985
|
? [...this.sessionPathOptionsMap[targetSource]]
|
|
953
986
|
: [];
|
|
@@ -960,8 +993,8 @@
|
|
|
960
993
|
}
|
|
961
994
|
},
|
|
962
995
|
|
|
963
|
-
async loadSessionPathOptions(options = {}) {
|
|
964
|
-
const source = options.source === 'claude' ? 'claude' : 'codex';
|
|
996
|
+
async loadSessionPathOptions(options = {}) {
|
|
997
|
+
const source = options.source === 'claude' ? 'claude' : (options.source === 'all' ? 'all' : 'codex');
|
|
965
998
|
const forceRefresh = !!options.forceRefresh;
|
|
966
999
|
const loaded = !!this.sessionPathOptionsLoadedMap[source];
|
|
967
1000
|
if (!forceRefresh && loaded) {
|
|
@@ -1013,12 +1046,12 @@
|
|
|
1013
1046
|
await this.loadSessions();
|
|
1014
1047
|
},
|
|
1015
1048
|
|
|
1016
|
-
async clearSessionFilters() {
|
|
1017
|
-
this.sessionFilterSource = '
|
|
1018
|
-
this.sessionPathFilter = '';
|
|
1019
|
-
this.sessionQuery = '';
|
|
1020
|
-
this.sessionRoleFilter = 'all';
|
|
1021
|
-
this.sessionTimePreset = 'all';
|
|
1049
|
+
async clearSessionFilters() {
|
|
1050
|
+
this.sessionFilterSource = 'all';
|
|
1051
|
+
this.sessionPathFilter = '';
|
|
1052
|
+
this.sessionQuery = '';
|
|
1053
|
+
this.sessionRoleFilter = 'all';
|
|
1054
|
+
this.sessionTimePreset = 'all';
|
|
1022
1055
|
await this.onSessionSourceChange();
|
|
1023
1056
|
},
|
|
1024
1057
|
|
|
@@ -1093,7 +1126,7 @@
|
|
|
1093
1126
|
this.activeSession = null;
|
|
1094
1127
|
this.activeSessionMessages = [];
|
|
1095
1128
|
this.activeSessionDetailClipped = false;
|
|
1096
|
-
this.showMessage('
|
|
1129
|
+
this.showMessage('加载会话失败', 'error');
|
|
1097
1130
|
} finally {
|
|
1098
1131
|
this.sessionsLoading = false;
|
|
1099
1132
|
}
|
|
@@ -1224,7 +1257,9 @@
|
|
|
1224
1257
|
},
|
|
1225
1258
|
|
|
1226
1259
|
downloadTextFile(fileName, content) {
|
|
1227
|
-
|
|
1260
|
+
// 使用 UTF-8 BOM 确保文本编辑器正确识别编码
|
|
1261
|
+
const BOM = '\uFEFF';
|
|
1262
|
+
const blob = new Blob([BOM + content], { type: 'text/markdown;charset=utf-8' });
|
|
1228
1263
|
const url = URL.createObjectURL(blob);
|
|
1229
1264
|
const link = document.createElement('a');
|
|
1230
1265
|
link.href = url;
|
|
@@ -1255,10 +1290,10 @@
|
|
|
1255
1290
|
const maxLabel = res.maxMessages === 'all' ? 'all' : res.maxMessages;
|
|
1256
1291
|
this.showMessage(`会话导出完成(已截断:最多 ${maxLabel} 条消息)`, 'info');
|
|
1257
1292
|
} else {
|
|
1258
|
-
this.showMessage('
|
|
1293
|
+
this.showMessage('操作成功', 'success');
|
|
1259
1294
|
}
|
|
1260
1295
|
} catch (e) {
|
|
1261
|
-
this.showMessage('
|
|
1296
|
+
this.showMessage('导出失败', 'error');
|
|
1262
1297
|
} finally {
|
|
1263
1298
|
this.sessionExporting[key] = false;
|
|
1264
1299
|
}
|
|
@@ -1267,15 +1302,22 @@
|
|
|
1267
1302
|
async switchProvider(name) {
|
|
1268
1303
|
this.currentProvider = name;
|
|
1269
1304
|
await this.loadModelsForProvider(name);
|
|
1270
|
-
|
|
1305
|
+
if (this.modelsSource === 'remote' && this.models.length > 0 && !this.models.includes(this.currentModel)) {
|
|
1306
|
+
this.currentModel = this.models[0];
|
|
1307
|
+
}
|
|
1308
|
+
await this.applyCodexConfigDirect({ silent: true });
|
|
1271
1309
|
},
|
|
1272
1310
|
|
|
1273
1311
|
async onModelChange() {
|
|
1274
|
-
await this.
|
|
1312
|
+
await this.applyCodexConfigDirect();
|
|
1275
1313
|
},
|
|
1276
1314
|
|
|
1277
1315
|
async onServiceTierChange() {
|
|
1278
|
-
await this.
|
|
1316
|
+
await this.applyCodexConfigDirect({ silent: true });
|
|
1317
|
+
},
|
|
1318
|
+
|
|
1319
|
+
async onReasoningEffortChange() {
|
|
1320
|
+
await this.applyCodexConfigDirect({ silent: true });
|
|
1279
1321
|
},
|
|
1280
1322
|
|
|
1281
1323
|
async runHealthCheck() {
|
|
@@ -1320,15 +1362,15 @@
|
|
|
1320
1362
|
remote
|
|
1321
1363
|
};
|
|
1322
1364
|
if (ok) {
|
|
1323
|
-
this.showMessage('
|
|
1365
|
+
this.showMessage('检查通过', 'success');
|
|
1324
1366
|
}
|
|
1325
1367
|
} else {
|
|
1326
1368
|
this.healthCheckResult = null;
|
|
1327
|
-
this.showMessage('
|
|
1369
|
+
this.showMessage('检查失败', 'error');
|
|
1328
1370
|
}
|
|
1329
1371
|
} catch (e) {
|
|
1330
1372
|
this.healthCheckResult = null;
|
|
1331
|
-
this.showMessage('
|
|
1373
|
+
this.showMessage('检查失败', 'error');
|
|
1332
1374
|
} finally {
|
|
1333
1375
|
if (this.configMode === 'claude') {
|
|
1334
1376
|
try {
|
|
@@ -1369,7 +1411,50 @@
|
|
|
1369
1411
|
this.configTemplateContent = template;
|
|
1370
1412
|
this.showConfigTemplateModal = true;
|
|
1371
1413
|
} catch (e) {
|
|
1372
|
-
this.showMessage('
|
|
1414
|
+
this.showMessage('加载模板失败', 'error');
|
|
1415
|
+
}
|
|
1416
|
+
},
|
|
1417
|
+
|
|
1418
|
+
async applyCodexConfigDirect(options = {}) {
|
|
1419
|
+
if (this.codexApplying) return;
|
|
1420
|
+
|
|
1421
|
+
const provider = (this.currentProvider || '').trim();
|
|
1422
|
+
const model = (this.currentModel || '').trim();
|
|
1423
|
+
if (!provider || !model) {
|
|
1424
|
+
this.showMessage('请选择提供商和模型', 'error');
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
this.codexApplying = true;
|
|
1429
|
+
try {
|
|
1430
|
+
const tplRes = await api('get-config-template', {
|
|
1431
|
+
provider,
|
|
1432
|
+
model,
|
|
1433
|
+
serviceTier: this.serviceTier,
|
|
1434
|
+
reasoningEffort: this.modelReasoningEffort
|
|
1435
|
+
});
|
|
1436
|
+
if (tplRes.error) {
|
|
1437
|
+
this.showMessage('获取模板失败', 'error');
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
const applyRes = await api('apply-config-template', {
|
|
1442
|
+
template: tplRes.template
|
|
1443
|
+
});
|
|
1444
|
+
if (applyRes.error) {
|
|
1445
|
+
this.showMessage('应用模板失败', 'error');
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
if (options.silent !== true) {
|
|
1450
|
+
this.showMessage('配置已应用', 'success');
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
await this.loadAll();
|
|
1454
|
+
} catch (e) {
|
|
1455
|
+
this.showMessage('应用失败', 'error');
|
|
1456
|
+
} finally {
|
|
1457
|
+
this.codexApplying = false;
|
|
1373
1458
|
}
|
|
1374
1459
|
},
|
|
1375
1460
|
|
|
@@ -1380,7 +1465,7 @@
|
|
|
1380
1465
|
|
|
1381
1466
|
async applyConfigTemplate() {
|
|
1382
1467
|
if (!this.configTemplateContent || !this.configTemplateContent.trim()) {
|
|
1383
|
-
this.showMessage('
|
|
1468
|
+
this.showMessage('模板不能为空', 'error');
|
|
1384
1469
|
return;
|
|
1385
1470
|
}
|
|
1386
1471
|
|
|
@@ -1393,11 +1478,11 @@
|
|
|
1393
1478
|
this.showMessage(res.error, 'error');
|
|
1394
1479
|
return;
|
|
1395
1480
|
}
|
|
1396
|
-
this.showMessage('
|
|
1481
|
+
this.showMessage('模板已应用', 'success');
|
|
1397
1482
|
this.closeConfigTemplateModal();
|
|
1398
1483
|
await this.loadAll();
|
|
1399
1484
|
} catch (e) {
|
|
1400
|
-
this.showMessage('
|
|
1485
|
+
this.showMessage('应用模板失败', 'error');
|
|
1401
1486
|
} finally {
|
|
1402
1487
|
this.configTemplateApplying = false;
|
|
1403
1488
|
}
|
|
@@ -1418,7 +1503,7 @@
|
|
|
1418
1503
|
this.agentsLineEnding = res.lineEnding === '\r\n' ? '\r\n' : '\n';
|
|
1419
1504
|
this.showAgentsModal = true;
|
|
1420
1505
|
} catch (e) {
|
|
1421
|
-
this.showMessage('
|
|
1506
|
+
this.showMessage('加载文件失败', 'error');
|
|
1422
1507
|
} finally {
|
|
1423
1508
|
this.agentsLoading = false;
|
|
1424
1509
|
}
|
|
@@ -1442,7 +1527,7 @@
|
|
|
1442
1527
|
this.agentsLineEnding = res.lineEnding === '\r\n' ? '\r\n' : '\n';
|
|
1443
1528
|
this.showAgentsModal = true;
|
|
1444
1529
|
} catch (e) {
|
|
1445
|
-
this.showMessage('
|
|
1530
|
+
this.showMessage('加载文件失败', 'error');
|
|
1446
1531
|
} finally {
|
|
1447
1532
|
this.agentsLoading = false;
|
|
1448
1533
|
}
|
|
@@ -1451,7 +1536,7 @@
|
|
|
1451
1536
|
async openOpenclawWorkspaceEditor() {
|
|
1452
1537
|
const fileName = (this.openclawWorkspaceFileName || '').trim();
|
|
1453
1538
|
if (!fileName) {
|
|
1454
|
-
this.showMessage('
|
|
1539
|
+
this.showMessage('请输入文件名', 'error');
|
|
1455
1540
|
return;
|
|
1456
1541
|
}
|
|
1457
1542
|
this.setAgentsModalContext('openclaw-workspace', { fileName });
|
|
@@ -1471,7 +1556,7 @@
|
|
|
1471
1556
|
this.agentsLineEnding = res.lineEnding === '\r\n' ? '\r\n' : '\n';
|
|
1472
1557
|
this.showAgentsModal = true;
|
|
1473
1558
|
} catch (e) {
|
|
1474
|
-
this.showMessage('
|
|
1559
|
+
this.showMessage('加载文件失败', 'error');
|
|
1475
1560
|
} finally {
|
|
1476
1561
|
this.agentsLoading = false;
|
|
1477
1562
|
}
|
|
@@ -1533,7 +1618,7 @@
|
|
|
1533
1618
|
this.showMessage(successLabel, 'success');
|
|
1534
1619
|
this.closeAgentsModal();
|
|
1535
1620
|
} catch (e) {
|
|
1536
|
-
this.showMessage('
|
|
1621
|
+
this.showMessage('保存失败', 'error');
|
|
1537
1622
|
} finally {
|
|
1538
1623
|
this.agentsSaving = false;
|
|
1539
1624
|
}
|
|
@@ -1548,29 +1633,40 @@
|
|
|
1548
1633
|
return this.showMessage('名称不能为空', 'error');
|
|
1549
1634
|
}
|
|
1550
1635
|
if (this.providersList.some(item => item.name === name)) {
|
|
1551
|
-
return this.showMessage('
|
|
1636
|
+
return this.showMessage('名称已存在', 'error');
|
|
1552
1637
|
}
|
|
1553
1638
|
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1639
|
+
try {
|
|
1640
|
+
const res = await api('add-provider', {
|
|
1641
|
+
name,
|
|
1642
|
+
url: this.newProvider.url.trim(),
|
|
1643
|
+
key: this.newProvider.key || ''
|
|
1644
|
+
});
|
|
1645
|
+
if (res.error) {
|
|
1646
|
+
this.showMessage(res.error, 'error');
|
|
1647
|
+
return;
|
|
1648
|
+
}
|
|
1558
1649
|
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
});
|
|
1650
|
+
this.showMessage('操作成功', 'success');
|
|
1651
|
+
this.closeAddModal();
|
|
1652
|
+
await this.loadAll();
|
|
1653
|
+
} catch (e) {
|
|
1654
|
+
this.showMessage('添加失败', 'error');
|
|
1655
|
+
}
|
|
1566
1656
|
},
|
|
1567
1657
|
|
|
1568
1658
|
async deleteProvider(name) {
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
}
|
|
1659
|
+
const res = await api('delete-provider', { name });
|
|
1660
|
+
if (res.error) {
|
|
1661
|
+
this.showMessage(res.error, 'error');
|
|
1662
|
+
return;
|
|
1663
|
+
}
|
|
1664
|
+
if (res.switched && res.provider) {
|
|
1665
|
+
this.showMessage(`已删除提供商,自动切换到 ${res.provider}${res.model ? ` / ${res.model}` : ''}`, 'success');
|
|
1666
|
+
} else {
|
|
1667
|
+
this.showMessage('操作成功', 'success');
|
|
1668
|
+
}
|
|
1669
|
+
await this.loadAll();
|
|
1574
1670
|
},
|
|
1575
1671
|
|
|
1576
1672
|
openEditModal(provider) {
|
|
@@ -1588,13 +1684,20 @@
|
|
|
1588
1684
|
}
|
|
1589
1685
|
|
|
1590
1686
|
const name = this.editingProvider.name;
|
|
1591
|
-
const
|
|
1592
|
-
const
|
|
1687
|
+
const url = this.editingProvider.url.trim();
|
|
1688
|
+
const key = this.editingProvider.key || '';
|
|
1593
1689
|
this.closeEditModal();
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1690
|
+
try {
|
|
1691
|
+
const res = await api('update-provider', { name, url, key });
|
|
1692
|
+
if (res.error) {
|
|
1693
|
+
this.showMessage(res.error, 'error');
|
|
1694
|
+
return;
|
|
1695
|
+
}
|
|
1696
|
+
this.showMessage('操作成功', 'success');
|
|
1697
|
+
await this.loadAll();
|
|
1698
|
+
} catch (e) {
|
|
1699
|
+
this.showMessage('更新失败', 'error');
|
|
1700
|
+
}
|
|
1598
1701
|
},
|
|
1599
1702
|
|
|
1600
1703
|
closeEditModal() {
|
|
@@ -1602,27 +1705,45 @@
|
|
|
1602
1705
|
this.editingProvider = { name: '', url: '', key: '' };
|
|
1603
1706
|
},
|
|
1604
1707
|
|
|
1708
|
+
async resetConfig() {
|
|
1709
|
+
if (this.resetConfigLoading) return;
|
|
1710
|
+
this.resetConfigLoading = true;
|
|
1711
|
+
try {
|
|
1712
|
+
const res = await api('reset-config');
|
|
1713
|
+
if (res.error) {
|
|
1714
|
+
this.showMessage(res.error, 'error');
|
|
1715
|
+
return;
|
|
1716
|
+
}
|
|
1717
|
+
const backup = res.backupFile ? `(已备份: ${res.backupFile})` : '';
|
|
1718
|
+
this.showMessage(`配置已重装${backup}`, 'success');
|
|
1719
|
+
await this.loadAll();
|
|
1720
|
+
} catch (e) {
|
|
1721
|
+
this.showMessage('重装失败', 'error');
|
|
1722
|
+
} finally {
|
|
1723
|
+
this.resetConfigLoading = false;
|
|
1724
|
+
}
|
|
1725
|
+
},
|
|
1726
|
+
|
|
1605
1727
|
async addModel() {
|
|
1606
1728
|
if (!this.newModelName || !this.newModelName.trim()) {
|
|
1607
|
-
return this.showMessage('
|
|
1729
|
+
return this.showMessage('请输入模型', 'error');
|
|
1608
1730
|
}
|
|
1609
1731
|
const res = await api('add-model', { model: this.newModelName.trim() });
|
|
1610
1732
|
if (res.error) {
|
|
1611
1733
|
this.showMessage(res.error, 'error');
|
|
1612
1734
|
} else {
|
|
1613
|
-
this.showMessage('
|
|
1735
|
+
this.showMessage('操作成功', 'success');
|
|
1614
1736
|
this.closeModelModal();
|
|
1615
1737
|
await this.loadAll();
|
|
1616
1738
|
}
|
|
1617
1739
|
},
|
|
1618
1740
|
|
|
1619
1741
|
async removeModel(model) {
|
|
1620
|
-
if (!confirm(`确定删除模型 "${model}"?`)) return;
|
|
1621
1742
|
const res = await api('delete-model', { model });
|
|
1622
1743
|
if (res.error) {
|
|
1623
1744
|
this.showMessage(res.error, 'error');
|
|
1624
1745
|
} else {
|
|
1625
|
-
this.showMessage('
|
|
1746
|
+
this.showMessage('操作成功', 'success');
|
|
1626
1747
|
await this.loadAll();
|
|
1627
1748
|
}
|
|
1628
1749
|
},
|
|
@@ -1677,7 +1798,7 @@
|
|
|
1677
1798
|
this.saveClaudeConfigs();
|
|
1678
1799
|
this.updateClaudeModelsCurrent();
|
|
1679
1800
|
if (!this.claudeConfigs[name].apiKey) {
|
|
1680
|
-
this.showMessage('
|
|
1801
|
+
this.showMessage('请先配置 API Key', 'error');
|
|
1681
1802
|
return;
|
|
1682
1803
|
}
|
|
1683
1804
|
this.applyClaudeConfig(name);
|
|
@@ -1707,7 +1828,7 @@
|
|
|
1707
1828
|
hasKey: !!this.editingConfig.apiKey
|
|
1708
1829
|
};
|
|
1709
1830
|
this.saveClaudeConfigs();
|
|
1710
|
-
this.showMessage('
|
|
1831
|
+
this.showMessage('操作成功', 'success');
|
|
1711
1832
|
this.closeEditConfigModal();
|
|
1712
1833
|
if (name === this.currentClaudeConfig) {
|
|
1713
1834
|
this.refreshClaudeModelContext();
|
|
@@ -1731,7 +1852,7 @@
|
|
|
1731
1852
|
|
|
1732
1853
|
const config = this.claudeConfigs[name];
|
|
1733
1854
|
if (!config.apiKey) {
|
|
1734
|
-
this.showMessage('
|
|
1855
|
+
this.showMessage('已保存,未应用', 'info');
|
|
1735
1856
|
this.closeEditConfigModal();
|
|
1736
1857
|
if (name === this.currentClaudeConfig) {
|
|
1737
1858
|
this.refreshClaudeModelContext();
|
|
@@ -1741,7 +1862,7 @@
|
|
|
1741
1862
|
|
|
1742
1863
|
const res = await api('apply-claude-config', { config });
|
|
1743
1864
|
if (res.error || res.success === false) {
|
|
1744
|
-
this.showMessage(res.error || '
|
|
1865
|
+
this.showMessage(res.error || '应用配置失败', 'error');
|
|
1745
1866
|
} else {
|
|
1746
1867
|
const targetTip = res.targetPath ? `(${res.targetPath})` : '';
|
|
1747
1868
|
this.showMessage(`已保存并应用到 Claude 配置${targetTip}`, 'success');
|
|
@@ -1754,15 +1875,15 @@
|
|
|
1754
1875
|
|
|
1755
1876
|
addClaudeConfig() {
|
|
1756
1877
|
if (!this.newClaudeConfig.name || !this.newClaudeConfig.name.trim()) {
|
|
1757
|
-
return this.showMessage('
|
|
1878
|
+
return this.showMessage('请输入名称', 'error');
|
|
1758
1879
|
}
|
|
1759
1880
|
const name = this.newClaudeConfig.name.trim();
|
|
1760
1881
|
if (this.claudeConfigs[name]) {
|
|
1761
|
-
return this.showMessage('
|
|
1882
|
+
return this.showMessage('名称已存在', 'error');
|
|
1762
1883
|
}
|
|
1763
1884
|
const duplicateName = this.findDuplicateClaudeConfigName(this.newClaudeConfig);
|
|
1764
1885
|
if (duplicateName) {
|
|
1765
|
-
return this.showMessage('
|
|
1886
|
+
return this.showMessage('配置已存在', 'info');
|
|
1766
1887
|
}
|
|
1767
1888
|
|
|
1768
1889
|
this.claudeConfigs[name] = {
|
|
@@ -1774,14 +1895,14 @@
|
|
|
1774
1895
|
|
|
1775
1896
|
this.currentClaudeConfig = name;
|
|
1776
1897
|
this.saveClaudeConfigs();
|
|
1777
|
-
this.showMessage('
|
|
1898
|
+
this.showMessage('操作成功', 'success');
|
|
1778
1899
|
this.closeClaudeConfigModal();
|
|
1779
1900
|
this.refreshClaudeModelContext();
|
|
1780
1901
|
},
|
|
1781
1902
|
|
|
1782
1903
|
deleteClaudeConfig(name) {
|
|
1783
1904
|
if (Object.keys(this.claudeConfigs).length <= 1) {
|
|
1784
|
-
return this.showMessage('
|
|
1905
|
+
return this.showMessage('至少保留一项', 'error');
|
|
1785
1906
|
}
|
|
1786
1907
|
|
|
1787
1908
|
if (!confirm(`确定删除配置 "${name}"?`)) return;
|
|
@@ -1791,7 +1912,7 @@
|
|
|
1791
1912
|
this.currentClaudeConfig = Object.keys(this.claudeConfigs)[0];
|
|
1792
1913
|
}
|
|
1793
1914
|
this.saveClaudeConfigs();
|
|
1794
|
-
this.showMessage('
|
|
1915
|
+
this.showMessage('操作成功', 'success');
|
|
1795
1916
|
this.refreshClaudeModelContext();
|
|
1796
1917
|
},
|
|
1797
1918
|
|
|
@@ -1801,12 +1922,12 @@
|
|
|
1801
1922
|
const config = this.claudeConfigs[name];
|
|
1802
1923
|
|
|
1803
1924
|
if (!config.apiKey) {
|
|
1804
|
-
return this.showMessage('
|
|
1925
|
+
return this.showMessage('请先配置 API Key', 'error');
|
|
1805
1926
|
}
|
|
1806
1927
|
|
|
1807
1928
|
const res = await api('apply-claude-config', { config });
|
|
1808
1929
|
if (res.error || res.success === false) {
|
|
1809
|
-
this.showMessage(res.error || '
|
|
1930
|
+
this.showMessage(res.error || '应用配置失败', 'error');
|
|
1810
1931
|
} else {
|
|
1811
1932
|
const targetTip = res.targetPath ? `(${res.targetPath})` : '';
|
|
1812
1933
|
this.showMessage(`已应用配置到 Claude 设置: ${name}${targetTip}`, 'success');
|
|
@@ -2014,7 +2135,7 @@
|
|
|
2014
2135
|
}
|
|
2015
2136
|
this.fillOpenclawQuickFromConfig(parsed.data);
|
|
2016
2137
|
if (!silent) {
|
|
2017
|
-
this.showMessage('
|
|
2138
|
+
this.showMessage('已读取配置', 'success');
|
|
2018
2139
|
}
|
|
2019
2140
|
return true;
|
|
2020
2141
|
},
|
|
@@ -2110,7 +2231,7 @@
|
|
|
2110
2231
|
this.refreshOpenclawProviders(parsed.data);
|
|
2111
2232
|
this.refreshOpenclawAgentsList(parsed.data);
|
|
2112
2233
|
if (!silent) {
|
|
2113
|
-
this.showMessage('
|
|
2234
|
+
this.showMessage('已刷新配置', 'success');
|
|
2114
2235
|
}
|
|
2115
2236
|
return true;
|
|
2116
2237
|
},
|
|
@@ -2408,7 +2529,7 @@
|
|
|
2408
2529
|
this.refreshOpenclawProviders(config);
|
|
2409
2530
|
this.refreshOpenclawAgentsList(config);
|
|
2410
2531
|
this.fillOpenclawQuickFromConfig(config);
|
|
2411
|
-
this.showMessage('
|
|
2532
|
+
this.showMessage('已写入', 'success');
|
|
2412
2533
|
},
|
|
2413
2534
|
|
|
2414
2535
|
applyOpenclawQuickToText() {
|
|
@@ -2421,7 +2542,7 @@
|
|
|
2421
2542
|
const providerName = (this.openclawQuick.providerName || '').trim();
|
|
2422
2543
|
const modelId = (this.openclawQuick.modelId || '').trim();
|
|
2423
2544
|
if (!providerName) {
|
|
2424
|
-
this.showMessage('
|
|
2545
|
+
this.showMessage('请填写名称', 'error');
|
|
2425
2546
|
return;
|
|
2426
2547
|
}
|
|
2427
2548
|
if (providerName.includes('/')) {
|
|
@@ -2429,7 +2550,7 @@
|
|
|
2429
2550
|
return;
|
|
2430
2551
|
}
|
|
2431
2552
|
if (!modelId) {
|
|
2432
|
-
this.showMessage('请填写模型
|
|
2553
|
+
this.showMessage('请填写模型', 'error');
|
|
2433
2554
|
return;
|
|
2434
2555
|
}
|
|
2435
2556
|
|
|
@@ -2440,7 +2561,7 @@
|
|
|
2440
2561
|
const provider = ensureObject(providers[providerName]);
|
|
2441
2562
|
const baseUrl = (this.openclawQuick.baseUrl || '').trim();
|
|
2442
2563
|
if (!baseUrl && !provider.baseUrl) {
|
|
2443
|
-
this.showMessage('请填写
|
|
2564
|
+
this.showMessage('请填写 URL', 'error');
|
|
2444
2565
|
return;
|
|
2445
2566
|
}
|
|
2446
2567
|
|
|
@@ -2526,7 +2647,7 @@
|
|
|
2526
2647
|
this.fillOpenclawStructured(config);
|
|
2527
2648
|
this.refreshOpenclawProviders(config);
|
|
2528
2649
|
this.refreshOpenclawAgentsList(config);
|
|
2529
|
-
this.showMessage('
|
|
2650
|
+
this.showMessage('配置已写入', 'success');
|
|
2530
2651
|
},
|
|
2531
2652
|
|
|
2532
2653
|
addOpenclawFallback() {
|
|
@@ -2630,6 +2751,14 @@
|
|
|
2630
2751
|
this.resetOpenclawQuick();
|
|
2631
2752
|
},
|
|
2632
2753
|
|
|
2754
|
+
openInstallModal() {
|
|
2755
|
+
this.showInstallModal = true;
|
|
2756
|
+
},
|
|
2757
|
+
|
|
2758
|
+
closeInstallModal() {
|
|
2759
|
+
this.showInstallModal = false;
|
|
2760
|
+
},
|
|
2761
|
+
|
|
2633
2762
|
async loadOpenclawConfigFromFile(options = {}) {
|
|
2634
2763
|
const silent = !!options.silent;
|
|
2635
2764
|
const force = !!options.force;
|
|
@@ -2655,11 +2784,11 @@
|
|
|
2655
2784
|
}
|
|
2656
2785
|
this.syncOpenclawStructuredFromText({ silent: true });
|
|
2657
2786
|
if (!silent) {
|
|
2658
|
-
this.showMessage('
|
|
2787
|
+
this.showMessage('加载完成', 'success');
|
|
2659
2788
|
}
|
|
2660
2789
|
} catch (e) {
|
|
2661
2790
|
if (!silent) {
|
|
2662
|
-
this.showMessage('
|
|
2791
|
+
this.showMessage('加载配置失败', 'error');
|
|
2663
2792
|
}
|
|
2664
2793
|
} finally {
|
|
2665
2794
|
this.openclawFileLoading = false;
|
|
@@ -2668,12 +2797,12 @@
|
|
|
2668
2797
|
|
|
2669
2798
|
persistOpenclawConfig({ closeModal = true } = {}) {
|
|
2670
2799
|
if (!this.openclawEditing.name || !this.openclawEditing.name.trim()) {
|
|
2671
|
-
this.showMessage('
|
|
2800
|
+
this.showMessage('请输入名称', 'error');
|
|
2672
2801
|
return '';
|
|
2673
2802
|
}
|
|
2674
2803
|
const name = this.openclawEditing.name.trim();
|
|
2675
2804
|
if (!this.openclawEditing.lockName && this.openclawConfigs[name]) {
|
|
2676
|
-
this.showMessage('
|
|
2805
|
+
this.showMessage('名称已存在', 'error');
|
|
2677
2806
|
return '';
|
|
2678
2807
|
}
|
|
2679
2808
|
if (!this.openclawEditing.content || !this.openclawEditing.content.trim()) {
|
|
@@ -2697,7 +2826,7 @@
|
|
|
2697
2826
|
try {
|
|
2698
2827
|
const name = this.persistOpenclawConfig();
|
|
2699
2828
|
if (!name) return;
|
|
2700
|
-
this.showMessage('
|
|
2829
|
+
this.showMessage('操作成功', 'success');
|
|
2701
2830
|
} finally {
|
|
2702
2831
|
this.openclawSaving = false;
|
|
2703
2832
|
}
|
|
@@ -2714,7 +2843,7 @@
|
|
|
2714
2843
|
lineEnding: this.openclawLineEnding
|
|
2715
2844
|
});
|
|
2716
2845
|
if (res.error || res.success === false) {
|
|
2717
|
-
this.showMessage(res.error || '
|
|
2846
|
+
this.showMessage(res.error || '应用配置失败', 'error');
|
|
2718
2847
|
return;
|
|
2719
2848
|
}
|
|
2720
2849
|
this.openclawConfigPath = res.targetPath || this.openclawConfigPath;
|
|
@@ -2723,7 +2852,7 @@
|
|
|
2723
2852
|
this.showMessage(`已保存并应用 OpenClaw 配置${targetTip}`, 'success');
|
|
2724
2853
|
this.closeOpenclawConfigModal();
|
|
2725
2854
|
} catch (e) {
|
|
2726
|
-
this.showMessage('
|
|
2855
|
+
this.showMessage('应用配置失败', 'error');
|
|
2727
2856
|
} finally {
|
|
2728
2857
|
this.openclawApplying = false;
|
|
2729
2858
|
}
|
|
@@ -2731,7 +2860,7 @@
|
|
|
2731
2860
|
|
|
2732
2861
|
deleteOpenclawConfig(name) {
|
|
2733
2862
|
if (Object.keys(this.openclawConfigs).length <= 1) {
|
|
2734
|
-
return this.showMessage('
|
|
2863
|
+
return this.showMessage('至少保留一项', 'error');
|
|
2735
2864
|
}
|
|
2736
2865
|
if (!confirm(`确定删除配置 "${name}"?`)) return;
|
|
2737
2866
|
delete this.openclawConfigs[name];
|
|
@@ -2739,21 +2868,21 @@
|
|
|
2739
2868
|
this.currentOpenclawConfig = Object.keys(this.openclawConfigs)[0];
|
|
2740
2869
|
}
|
|
2741
2870
|
this.saveOpenclawConfigs();
|
|
2742
|
-
this.showMessage('
|
|
2871
|
+
this.showMessage('操作成功', 'success');
|
|
2743
2872
|
},
|
|
2744
2873
|
|
|
2745
2874
|
async applyOpenclawConfig(name) {
|
|
2746
2875
|
this.currentOpenclawConfig = name;
|
|
2747
2876
|
const config = this.openclawConfigs[name];
|
|
2748
2877
|
if (!this.openclawHasContent(config)) {
|
|
2749
|
-
return this.showMessage('
|
|
2878
|
+
return this.showMessage('配置为空', 'error');
|
|
2750
2879
|
}
|
|
2751
2880
|
const res = await api('apply-openclaw-config', {
|
|
2752
2881
|
content: config.content,
|
|
2753
2882
|
lineEnding: this.openclawLineEnding
|
|
2754
2883
|
});
|
|
2755
2884
|
if (res.error || res.success === false) {
|
|
2756
|
-
this.showMessage(res.error || '
|
|
2885
|
+
this.showMessage(res.error || '应用配置失败', 'error');
|
|
2757
2886
|
} else {
|
|
2758
2887
|
this.openclawConfigPath = res.targetPath || this.openclawConfigPath;
|
|
2759
2888
|
this.openclawConfigExists = true;
|