codexmate 0.0.20 → 0.0.22
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 +289 -152
- package/README.zh.md +321 -0
- package/cli/agents-files.js +224 -0
- package/cli/archive-helpers.js +446 -0
- package/cli/auth-profiles.js +359 -0
- package/cli/builtin-proxy.js +1044 -0
- package/cli/claude-proxy.js +998 -0
- package/cli/config-bootstrap.js +384 -0
- package/cli/openai-bridge.js +950 -0
- package/cli/openclaw-config.js +629 -0
- package/cli/session-usage.concurrent.js +28 -0
- package/cli/session-usage.js +112 -0
- package/cli/session-usage.models.js +176 -0
- package/cli/skills.js +1141 -0
- package/cli/zip-commands.js +510 -0
- package/cli.js +9408 -9719
- package/lib/cli-models-utils.js +109 -1
- package/lib/cli-path-utils.js +69 -0
- package/lib/cli-sessions.js +386 -0
- package/lib/download-artifacts.js +77 -0
- package/lib/task-orchestrator.js +869 -0
- package/package.json +14 -10
- package/res/logo.png +0 -0
- package/res/vue.global.prod.js +13 -0
- package/web-ui/app.js +193 -15
- package/web-ui/index.html +5 -1
- package/web-ui/logic.agents-diff.mjs +1 -1
- package/web-ui/logic.claude.mjs +60 -0
- package/web-ui/logic.runtime.mjs +11 -7
- package/web-ui/logic.sessions.mjs +372 -21
- package/web-ui/modules/api.mjs +22 -1
- package/web-ui/modules/app.computed.dashboard.mjs +23 -10
- package/web-ui/modules/app.computed.index.mjs +4 -0
- package/web-ui/modules/app.computed.main-tabs.mjs +198 -0
- package/web-ui/modules/app.computed.session.mjs +521 -9
- package/web-ui/modules/app.methods.agents.mjs +62 -11
- package/web-ui/modules/app.methods.codex-config.mjs +189 -34
- package/web-ui/modules/app.methods.index.mjs +7 -1
- package/web-ui/modules/app.methods.install.mjs +24 -20
- package/web-ui/modules/app.methods.navigation.mjs +142 -1
- package/web-ui/modules/app.methods.openclaw-core.mjs +339 -39
- package/web-ui/modules/app.methods.openclaw-editing.mjs +39 -4
- package/web-ui/modules/app.methods.openclaw-persist.mjs +122 -4
- package/web-ui/modules/app.methods.providers.mjs +192 -53
- package/web-ui/modules/app.methods.session-actions.mjs +99 -19
- package/web-ui/modules/app.methods.session-browser.mjs +196 -5
- package/web-ui/modules/app.methods.session-timeline.mjs +22 -15
- package/web-ui/modules/app.methods.session-trash.mjs +3 -0
- package/web-ui/modules/app.methods.startup-claude.mjs +70 -71
- package/web-ui/modules/app.methods.task-orchestration.mjs +471 -0
- package/web-ui/modules/config-mode.computed.mjs +2 -0
- package/web-ui/modules/config-template-confirm-pref.mjs +33 -0
- package/web-ui/modules/i18n.mjs +1609 -0
- package/web-ui/modules/plugins.computed.mjs +220 -0
- package/web-ui/modules/plugins.methods.mjs +620 -0
- package/web-ui/modules/plugins.storage.mjs +37 -0
- package/web-ui/partials/index/layout-footer.html +1 -57
- package/web-ui/partials/index/layout-header.html +299 -175
- package/web-ui/partials/index/modal-config-template-agents.html +79 -29
- package/web-ui/partials/index/modal-confirm-toast.html +1 -1
- package/web-ui/partials/index/modal-health-check.html +14 -14
- package/web-ui/partials/index/modal-openclaw-config.html +47 -42
- package/web-ui/partials/index/modal-skills.html +130 -114
- package/web-ui/partials/index/modals-basic.html +71 -102
- package/web-ui/partials/index/panel-config-claude.html +50 -12
- package/web-ui/partials/index/panel-config-codex.html +34 -37
- package/web-ui/partials/index/panel-config-openclaw.html +10 -16
- package/web-ui/partials/index/panel-docs.html +147 -0
- package/web-ui/partials/index/panel-market.html +38 -38
- package/web-ui/partials/index/panel-orchestration.html +397 -0
- package/web-ui/partials/index/panel-plugins.html +243 -0
- package/web-ui/partials/index/panel-sessions.html +51 -146
- package/web-ui/partials/index/panel-settings.html +188 -96
- package/web-ui/partials/index/panel-usage.html +353 -0
- package/web-ui/session-helpers.mjs +221 -10
- package/web-ui/styles/base-theme.css +120 -229
- package/web-ui/styles/controls-forms.css +59 -51
- package/web-ui/styles/docs-panel.css +247 -0
- package/web-ui/styles/layout-shell.css +394 -128
- package/web-ui/styles/modals-core.css +18 -3
- package/web-ui/styles/navigation-panels.css +184 -183
- package/web-ui/styles/plugins-panel.css +518 -0
- package/web-ui/styles/responsive.css +102 -62
- package/web-ui/styles/sessions-list.css +13 -27
- package/web-ui/styles/sessions-preview.css +13 -7
- package/web-ui/styles/sessions-toolbar-trash.css +25 -0
- package/web-ui/styles/sessions-usage.css +581 -6
- package/web-ui/styles/settings-panel.css +166 -0
- package/web-ui/styles/skills-list.css +16 -11
- package/web-ui/styles/skills-market.css +63 -2
- package/web-ui/styles/task-orchestration.css +776 -0
- package/web-ui/styles/titles-cards.css +67 -66
- package/web-ui/styles.css +4 -0
- package/README.en.md +0 -259
- package/res/screenshot.png +0 -0
- package/res/vue.global.js +0 -18552
|
@@ -10,15 +10,41 @@
|
|
|
10
10
|
<svg class="icon" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2">
|
|
11
11
|
<path d="M10 4v12M4 10h12"/>
|
|
12
12
|
</svg>
|
|
13
|
-
|
|
13
|
+
{{ t('claude.addProvider') }}
|
|
14
14
|
</button>
|
|
15
15
|
<div class="config-template-hint">
|
|
16
|
-
|
|
16
|
+
{{ t('claude.applyDefault') }}
|
|
17
17
|
</div>
|
|
18
18
|
|
|
19
19
|
<div class="selector-section">
|
|
20
20
|
<div class="selector-header">
|
|
21
|
-
<span class="selector-title"
|
|
21
|
+
<span class="selector-title">{{ t('claude.presetProviders') }}</span>
|
|
22
|
+
</div>
|
|
23
|
+
<div class="btn-group" style="flex-wrap: wrap; gap: 8px;">
|
|
24
|
+
<button type="button" class="btn-mini" @click="closeClaudeConfigModal(); showClaudeConfigModal = true">{{ t('claude.customConfig') }}</button>
|
|
25
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'Claude Official'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://api.anthropic.com'; newClaudeConfig.model = 'claude-sonnet-4'; showClaudeConfigModal = true">Claude Official</button>
|
|
26
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'DeepSeek'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://api.deepseek.com/anthropic'; newClaudeConfig.model = 'DeepSeek-V3.2'; showClaudeConfigModal = true">DeepSeek</button>
|
|
27
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'Zhipu GLM'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://open.bigmodel.cn/api/anthropic'; newClaudeConfig.model = 'glm-5'; showClaudeConfigModal = true">Zhipu GLM</button>
|
|
28
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'Z.ai GLM'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://api.z.ai/api/anthropic'; newClaudeConfig.model = 'glm-5'; showClaudeConfigModal = true">Z.ai GLM</button>
|
|
29
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'Qwen Coder'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://coding.dashscope.aliyuncs.com/apps/anthropic'; newClaudeConfig.model = 'qwen3-coder'; showClaudeConfigModal = true">Qwen Coder</button>
|
|
30
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'Kimi k2'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://api.moonshot.cn/anthropic'; newClaudeConfig.model = 'kimi-k2.5'; showClaudeConfigModal = true">Kimi k2</button>
|
|
31
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'Kimi For Coding'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://api.kimi.com/coding/'; newClaudeConfig.model = 'kimi-k2.5'; showClaudeConfigModal = true">Kimi For Coding</button>
|
|
32
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'KAT-Coder'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://vanchin.streamlake.ai/api/gateway/v1/endpoints/${ENDPOINT_ID}/claude-code-proxy'; newClaudeConfig.model = 'KAT-Coder-Pro V1'; showClaudeConfigModal = true">KAT-Coder</button>
|
|
33
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'Longcat'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://api.longcat.chat/anthropic'; newClaudeConfig.model = 'LongCat-Flash-Chat'; showClaudeConfigModal = true">Longcat</button>
|
|
34
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'MiniMax'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://api.minimaxi.com/anthropic'; newClaudeConfig.model = 'MiniMax-M2.7'; showClaudeConfigModal = true">MiniMax</button>
|
|
35
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'MiniMax en'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://api.minimax.io/anthropic'; newClaudeConfig.model = 'MiniMax-M2.7'; showClaudeConfigModal = true">MiniMax en</button>
|
|
36
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'DouBaoSeed'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://ark.cn-beijing.volces.com/api/coding'; newClaudeConfig.model = 'doubao-seed-2-0-code-preview-latest'; showClaudeConfigModal = true">DouBaoSeed</button>
|
|
37
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'BaiLing'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://api.tbox.cn/api/anthropic'; newClaudeConfig.model = 'Ling-2.5-1T'; showClaudeConfigModal = true">BaiLing</button>
|
|
38
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'ModelScope'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://api-inference.modelscope.cn'; newClaudeConfig.model = 'ZhipuAI/GLM-5'; showClaudeConfigModal = true">ModelScope</button>
|
|
39
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'AiHubMix'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://aihubmix.com'; newClaudeConfig.model = 'glm-4.7'; showClaudeConfigModal = true">AiHubMix</button>
|
|
40
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'DMXAPI'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://www.dmxapi.cn'; newClaudeConfig.model = 'glm-4.7'; showClaudeConfigModal = true">DMXAPI</button>
|
|
41
|
+
<button type="button" class="btn-mini" @click="newClaudeConfig.name = 'PackyCode'; newClaudeConfig.apiKey = ''; newClaudeConfig.baseUrl = 'https://www.packyapi.com'; newClaudeConfig.model = 'glm-4.7'; showClaudeConfigModal = true">PackyCode</button>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div class="selector-section">
|
|
46
|
+
<div class="selector-header">
|
|
47
|
+
<span class="selector-title">{{ t('claude.model') }}</span>
|
|
22
48
|
</div>
|
|
23
49
|
<select
|
|
24
50
|
v-if="claudeModelHasList"
|
|
@@ -34,20 +60,32 @@
|
|
|
34
60
|
v-model="currentClaudeModel"
|
|
35
61
|
@blur="onClaudeModelChange"
|
|
36
62
|
@keyup.enter="onClaudeModelChange"
|
|
37
|
-
placeholder="
|
|
63
|
+
:placeholder="t('claude.model.placeholder')"
|
|
38
64
|
>
|
|
39
65
|
<div class="config-template-hint">
|
|
40
|
-
|
|
66
|
+
{{ t('claude.model.hint') }}
|
|
41
67
|
</div>
|
|
42
68
|
</div>
|
|
43
69
|
|
|
44
70
|
<div class="selector-section">
|
|
45
71
|
<div class="selector-header">
|
|
46
|
-
<span class="selector-title"
|
|
72
|
+
<span class="selector-title">{{ t('claude.health.title') }}</span>
|
|
47
73
|
</div>
|
|
48
74
|
<button class="btn-tool" @click="runHealthCheck" :disabled="healthCheckLoading || loading || !!initError">
|
|
49
|
-
{{ healthCheckLoading ? '
|
|
75
|
+
{{ healthCheckLoading ? t('claude.health.running') : t('claude.health.run') }}
|
|
76
|
+
</button>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<div class="selector-section">
|
|
80
|
+
<div class="selector-header">
|
|
81
|
+
<span class="selector-title">CLAUDE.md</span>
|
|
82
|
+
</div>
|
|
83
|
+
<button class="btn-tool" @click="openClaudeMdEditor" :disabled="loading || !!initError || agentsLoading">
|
|
84
|
+
{{ agentsLoading ? t('config.modelLoading') : t('claude.md.open') }}
|
|
50
85
|
</button>
|
|
86
|
+
<div class="config-template-hint">
|
|
87
|
+
{{ t('claude.md.hint') }}
|
|
88
|
+
</div>
|
|
51
89
|
</div>
|
|
52
90
|
|
|
53
91
|
<div class="card-list">
|
|
@@ -63,31 +101,31 @@
|
|
|
63
101
|
<div class="card-icon">{{ name.charAt(0).toUpperCase() }}</div>
|
|
64
102
|
<div class="card-content">
|
|
65
103
|
<div class="card-title">{{ name }}</div>
|
|
66
|
-
<div class="card-subtitle">{{ config.model || '
|
|
104
|
+
<div class="card-subtitle">{{ config.model || t('claude.model.unset') }}</div>
|
|
67
105
|
</div>
|
|
68
106
|
</div>
|
|
69
107
|
<div class="card-trailing">
|
|
70
108
|
<span :class="['pill', config.hasKey ? 'configured' : 'empty']">
|
|
71
|
-
{{ config.hasKey ? '
|
|
109
|
+
{{ config.hasKey ? t('claude.configured') : t('claude.notConfigured') }}
|
|
72
110
|
</span>
|
|
73
111
|
<span v-if="claudeSpeedResults[name]" :class="['latency', claudeSpeedResults[name].ok ? 'ok' : 'error']">
|
|
74
112
|
{{ formatLatency(claudeSpeedResults[name]) }}
|
|
75
113
|
</span>
|
|
76
114
|
<div class="card-actions" @click.stop>
|
|
77
|
-
<button class="card-action-btn" @click="openEditConfigModal(name)" :aria-label="`Edit Claude config ${name}`" title="
|
|
115
|
+
<button class="card-action-btn" @click="openEditConfigModal(name)" :aria-label="`Edit Claude config ${name}`" :title="t('claude.action.edit')">
|
|
78
116
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
79
117
|
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
|
|
80
118
|
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
|
81
119
|
</svg>
|
|
82
120
|
</button>
|
|
83
|
-
<button class="card-action-btn" :class="{ loading: claudeShareLoading[name] }" @click="copyClaudeShareCommand(name)" disabled title="
|
|
121
|
+
<button class="card-action-btn" :class="{ loading: claudeShareLoading[name] }" @click="copyClaudeShareCommand(name)" disabled :title="t('claude.action.shareDisabled')" aria-label="Share import command">
|
|
84
122
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
85
123
|
<path d="M4 12v7a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-7"/>
|
|
86
124
|
<path d="M16 6l-4-4-4 4"/>
|
|
87
125
|
<path d="M12 2v14"/>
|
|
88
126
|
</svg>
|
|
89
127
|
</button>
|
|
90
|
-
<button class="card-action-btn delete" @click="deleteClaudeConfig(name)" :aria-label="`Delete Claude config ${name}`" title="
|
|
128
|
+
<button class="card-action-btn delete" @click="deleteClaudeConfig(name)" :aria-label="`Delete Claude config ${name}`" :title="t('claude.action.delete')">
|
|
91
129
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
92
130
|
<path d="M3 6h18"/>
|
|
93
131
|
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
<svg class="icon" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2">
|
|
11
11
|
<path d="M10 4v12M4 10h12"/>
|
|
12
12
|
</svg>
|
|
13
|
-
|
|
13
|
+
{{ t('config.addProvider') }}
|
|
14
14
|
</button>
|
|
15
15
|
|
|
16
16
|
<!-- 模型选择器 -->
|
|
17
17
|
<div class="selector-section">
|
|
18
18
|
<div class="selector-header">
|
|
19
|
-
<span class="selector-title"
|
|
19
|
+
<span class="selector-title">{{ t('config.models') }}</span>
|
|
20
20
|
<div class="selector-actions">
|
|
21
21
|
<button class="btn-icon" @click="showModelModal = true" aria-label="Add model" title="添加模型" v-if="modelsSource === 'legacy'">+</button>
|
|
22
22
|
<button class="btn-icon" @click="showModelListModal = true" aria-label="Manage models" title="管理模型" v-if="modelsSource === 'legacy'">≡</button>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
@change="onModelChange"
|
|
30
30
|
:disabled="codexModelsLoading"
|
|
31
31
|
>
|
|
32
|
-
<option v-if="codexModelsLoading" value=""
|
|
32
|
+
<option v-if="codexModelsLoading" value="">{{ t('config.modelLoading') }}</option>
|
|
33
33
|
<option v-else v-for="model in models" :key="model" :value="model">{{ model }}</option>
|
|
34
34
|
</select>
|
|
35
35
|
<input
|
|
@@ -40,63 +40,63 @@
|
|
|
40
40
|
:placeholder="activeProviderModelPlaceholder"
|
|
41
41
|
>
|
|
42
42
|
<div class="config-template-hint" v-if="modelsSource === 'unlimited'">
|
|
43
|
-
|
|
43
|
+
{{ t('config.models.unlimited') }}
|
|
44
44
|
</div>
|
|
45
45
|
<div class="config-template-hint" v-if="modelsSource === 'error'">
|
|
46
|
-
|
|
46
|
+
{{ t('config.models.error') }}
|
|
47
47
|
</div>
|
|
48
48
|
<div class="config-template-hint" v-if="modelsSource === 'remote' && !modelsHasCurrent">
|
|
49
|
-
{{ isCodexConfigMode ? '
|
|
49
|
+
{{ isCodexConfigMode ? t('config.models.notInList.codex') : t('config.models.notInList.other') }}
|
|
50
50
|
</div>
|
|
51
51
|
<div class="config-template-hint" v-if="isCodexConfigMode">
|
|
52
|
-
|
|
52
|
+
{{ t('config.template.editFirst') }}
|
|
53
53
|
</div>
|
|
54
54
|
<div class="config-template-hint" v-else-if="activeProviderBridgeHint">
|
|
55
|
-
{{ activeProviderBridgeHint }}
|
|
55
|
+
{{ t('config.template.bridgeCodexOnly', { hint: activeProviderBridgeHint }) }}
|
|
56
56
|
</div>
|
|
57
57
|
<button class="btn-tool btn-template-editor" v-if="isCodexConfigMode" @click="openConfigTemplateEditor" :disabled="loading || !!initError">
|
|
58
|
-
|
|
58
|
+
{{ t('config.template.openEditor') }}
|
|
59
59
|
</button>
|
|
60
60
|
</div>
|
|
61
61
|
|
|
62
62
|
<template v-if="isCodexConfigMode">
|
|
63
63
|
<div class="selector-section">
|
|
64
64
|
<div class="selector-header">
|
|
65
|
-
<span class="selector-title"
|
|
65
|
+
<span class="selector-title">{{ t('config.serviceTier') }}</span>
|
|
66
66
|
</div>
|
|
67
67
|
<select class="model-select" v-model="serviceTier" @change="onServiceTierChange">
|
|
68
|
-
<option value="fast">fast
|
|
68
|
+
<option value="fast">{{ t('config.serviceTier.fast') }}</option>
|
|
69
69
|
<option value="standard">standard</option>
|
|
70
70
|
</select>
|
|
71
71
|
<div class="config-template-hint">
|
|
72
|
-
|
|
72
|
+
{{ t('config.serviceTier.hint', { field: 'service_tier' }) }}
|
|
73
73
|
</div>
|
|
74
74
|
</div>
|
|
75
75
|
|
|
76
76
|
<div class="selector-section">
|
|
77
77
|
<div class="selector-header">
|
|
78
|
-
<span class="selector-title"
|
|
78
|
+
<span class="selector-title">{{ t('config.reasoningEffort') }}</span>
|
|
79
79
|
</div>
|
|
80
80
|
<select class="model-select" v-model="modelReasoningEffort" @change="onReasoningEffortChange">
|
|
81
81
|
<option value="high">high</option>
|
|
82
|
-
<option value="medium">medium
|
|
82
|
+
<option value="medium">{{ t('config.reasoningEffort.medium') }}</option>
|
|
83
83
|
<option value="low">low</option>
|
|
84
84
|
<option value="xhigh">xhigh</option>
|
|
85
85
|
</select>
|
|
86
86
|
<div class="config-template-hint">
|
|
87
|
-
|
|
87
|
+
{{ t('config.reasoningEffort.hint') }}
|
|
88
88
|
</div>
|
|
89
89
|
</div>
|
|
90
90
|
|
|
91
91
|
<div class="selector-section">
|
|
92
92
|
<div class="selector-header">
|
|
93
|
-
<span class="selector-title"
|
|
93
|
+
<span class="selector-title">{{ t('config.contextBudget') }}</span>
|
|
94
94
|
<div class="selector-actions">
|
|
95
95
|
<button
|
|
96
96
|
class="btn-tool btn-tool-compact"
|
|
97
97
|
@click="resetCodexContextBudgetDefaults"
|
|
98
98
|
:disabled="loading || !!initError || codexApplying">
|
|
99
|
-
|
|
99
|
+
{{ t('config.reset') }}
|
|
100
100
|
</button>
|
|
101
101
|
</div>
|
|
102
102
|
</div>
|
|
@@ -109,12 +109,12 @@
|
|
|
109
109
|
class="form-input"
|
|
110
110
|
inputmode="numeric"
|
|
111
111
|
autocomplete="off"
|
|
112
|
-
placeholder="
|
|
112
|
+
:placeholder="t('config.example', { value: 190000 })"
|
|
113
113
|
@focus="editingCodexBudgetField = 'modelContextWindowInput'"
|
|
114
114
|
@input="sanitizePositiveIntegerDraft('modelContextWindowInput')"
|
|
115
115
|
@blur="onModelContextWindowBlur"
|
|
116
116
|
@keydown.enter.prevent="onModelContextWindowBlur">
|
|
117
|
-
<div class="form-hint"
|
|
117
|
+
<div class="form-hint">{{ t('config.contextWindow.hint') }}</div>
|
|
118
118
|
</div>
|
|
119
119
|
<div class="form-group codex-config-field">
|
|
120
120
|
<label class="form-label" for="codex-model-auto-compact-token-limit">model_auto_compact_token_limit</label>
|
|
@@ -124,12 +124,12 @@
|
|
|
124
124
|
class="form-input"
|
|
125
125
|
inputmode="numeric"
|
|
126
126
|
autocomplete="off"
|
|
127
|
-
placeholder="
|
|
127
|
+
:placeholder="t('config.example', { value: 185000 })"
|
|
128
128
|
@focus="editingCodexBudgetField = 'modelAutoCompactTokenLimitInput'"
|
|
129
129
|
@input="sanitizePositiveIntegerDraft('modelAutoCompactTokenLimitInput')"
|
|
130
130
|
@blur="onModelAutoCompactTokenLimitBlur"
|
|
131
131
|
@keydown.enter.prevent="onModelAutoCompactTokenLimitBlur">
|
|
132
|
-
<div class="form-hint"
|
|
132
|
+
<div class="form-hint">{{ t('config.autoCompact.hint') }}</div>
|
|
133
133
|
</div>
|
|
134
134
|
</div>
|
|
135
135
|
</div>
|
|
@@ -139,21 +139,12 @@
|
|
|
139
139
|
<span class="selector-title">AGENTS.md</span>
|
|
140
140
|
</div>
|
|
141
141
|
<button class="btn-tool" @click="openAgentsEditor" :disabled="loading || !!initError || agentsLoading">
|
|
142
|
-
{{ agentsLoading ? '
|
|
142
|
+
{{ agentsLoading ? t('config.modelLoading') : t('config.agents.open') }}
|
|
143
143
|
</button>
|
|
144
144
|
</div>
|
|
145
145
|
|
|
146
146
|
</template>
|
|
147
147
|
|
|
148
|
-
<div class="selector-section">
|
|
149
|
-
<div class="selector-header">
|
|
150
|
-
<span class="selector-title">健康检测</span>
|
|
151
|
-
</div>
|
|
152
|
-
<button class="btn-tool" @click="openHealthCheckDialog()" :disabled="loading || !!initError">
|
|
153
|
-
检测对话
|
|
154
|
-
</button>
|
|
155
|
-
</div>
|
|
156
|
-
|
|
157
148
|
<div v-if="!loading && !initError" class="card-list">
|
|
158
149
|
<div v-for="provider in displayProvidersList" :key="provider.name"
|
|
159
150
|
:class="['card', { active: displayCurrentProvider === provider.name }]"
|
|
@@ -168,10 +159,10 @@
|
|
|
168
159
|
<div class="card-content">
|
|
169
160
|
<div class="card-title">
|
|
170
161
|
<span>{{ provider.name }}</span>
|
|
171
|
-
<span v-if="provider.readOnly" class="provider-readonly-badge"
|
|
162
|
+
<span v-if="provider.readOnly" class="provider-readonly-badge">{{ t('config.badge.system') }}</span>
|
|
172
163
|
</div>
|
|
173
164
|
<div class="card-subtitle">
|
|
174
|
-
{{ provider.url || '
|
|
165
|
+
{{ provider.url || t('config.url.unset') }}
|
|
175
166
|
</div>
|
|
176
167
|
</div>
|
|
177
168
|
</div>
|
|
@@ -183,7 +174,13 @@
|
|
|
183
174
|
{{ formatLatency(speedResults[provider.name]) }}
|
|
184
175
|
</span>
|
|
185
176
|
<div class="card-actions" @click.stop>
|
|
186
|
-
<button
|
|
177
|
+
<button
|
|
178
|
+
class="card-action-btn"
|
|
179
|
+
@click="openHealthCheckDialog({ providerName: provider.name, locked: true })"
|
|
180
|
+
:disabled="displayCurrentProvider !== provider.name"
|
|
181
|
+
:aria-label="`Open health dialog for ${provider.name}`"
|
|
182
|
+
:title="displayCurrentProvider === provider.name ? t('config.healthTest') : t('config.switchProviderFirst')"
|
|
183
|
+
>
|
|
187
184
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
188
185
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
|
|
189
186
|
<path d="M8 9h8"/>
|
|
@@ -193,10 +190,10 @@
|
|
|
193
190
|
<button
|
|
194
191
|
v-if="!provider.readOnly"
|
|
195
192
|
class="card-action-btn"
|
|
196
|
-
:class="{ loading: providerShareLoading[provider.name] }"
|
|
197
|
-
disabled
|
|
193
|
+
:class="{ loading: providerShareLoading[provider.name], disabled: !shouldAllowProviderShare(provider) }"
|
|
194
|
+
:disabled="providerShareLoading[provider.name] || !shouldAllowProviderShare(provider)"
|
|
198
195
|
@click="copyProviderShareCommand(provider)"
|
|
199
|
-
title="
|
|
196
|
+
:title="shouldAllowProviderShare(provider) ? t('config.shareCommand') : t('config.shareDisabled')"
|
|
200
197
|
aria-label="Share import command">
|
|
201
198
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
202
199
|
<path d="M4 12v7a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-7"/>
|
|
@@ -5,14 +5,8 @@
|
|
|
5
5
|
id="panel-config-openclaw"
|
|
6
6
|
role="tabpanel"
|
|
7
7
|
:aria-labelledby="'tab-config-openclaw'">
|
|
8
|
-
<button class="btn-add" @click="openOpenclawAddModal" v-if="!loading && !initError">
|
|
9
|
-
<svg class="icon" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2">
|
|
10
|
-
<path d="M10 4v12M4 10h12"/>
|
|
11
|
-
</svg>
|
|
12
|
-
新增 OpenClaw 配置
|
|
13
|
-
</button>
|
|
14
8
|
<div class="config-template-hint">
|
|
15
|
-
|
|
9
|
+
{{ t('openclaw.applyHint') }}
|
|
16
10
|
</div>
|
|
17
11
|
|
|
18
12
|
<div class="selector-section">
|
|
@@ -20,27 +14,27 @@
|
|
|
20
14
|
<span class="selector-title">AGENTS.md</span>
|
|
21
15
|
</div>
|
|
22
16
|
<div class="config-template-hint">
|
|
23
|
-
|
|
17
|
+
{{ t('openclaw.agents.hint') }}
|
|
24
18
|
</div>
|
|
25
19
|
<button class="btn-tool" @click="openOpenclawAgentsEditor" :disabled="loading || !!initError || agentsLoading">
|
|
26
|
-
{{ agentsLoading ? '
|
|
20
|
+
{{ agentsLoading ? t('config.modelLoading') : t('openclaw.agents.open') }}
|
|
27
21
|
</button>
|
|
28
22
|
</div>
|
|
29
23
|
|
|
30
24
|
<div class="selector-section">
|
|
31
25
|
<div class="selector-header">
|
|
32
|
-
<label class="selector-title" for="openclaw-workspace-file"
|
|
26
|
+
<label class="selector-title" for="openclaw-workspace-file">{{ t('openclaw.workspaceFile') }}</label>
|
|
33
27
|
</div>
|
|
34
28
|
<input
|
|
35
29
|
id="openclaw-workspace-file"
|
|
36
30
|
class="form-input"
|
|
37
31
|
v-model="openclawWorkspaceFileName"
|
|
38
|
-
placeholder="
|
|
32
|
+
:placeholder="t('openclaw.workspace.placeholder')">
|
|
39
33
|
<div class="config-template-hint">
|
|
40
|
-
|
|
34
|
+
{{ t('openclaw.workspace.hint') }}
|
|
41
35
|
</div>
|
|
42
36
|
<button class="btn-tool" @click="openOpenclawWorkspaceEditor" :disabled="loading || !!initError || agentsLoading">
|
|
43
|
-
{{ agentsLoading ? '
|
|
37
|
+
{{ agentsLoading ? t('config.modelLoading') : t('openclaw.workspace.open') }}
|
|
44
38
|
</button>
|
|
45
39
|
</div>
|
|
46
40
|
|
|
@@ -62,16 +56,16 @@
|
|
|
62
56
|
</div>
|
|
63
57
|
<div class="card-trailing">
|
|
64
58
|
<span :class="['pill', openclawHasContent(config) ? 'configured' : 'empty']">
|
|
65
|
-
{{ openclawHasContent(config) ? '
|
|
59
|
+
{{ openclawHasContent(config) ? t('openclaw.configured') : t('openclaw.notConfigured') }}
|
|
66
60
|
</span>
|
|
67
61
|
<div class="card-actions" @click.stop>
|
|
68
|
-
<button class="card-action-btn" @click="openOpenclawEditModal(name)" :aria-label="`Edit OpenClaw config ${name}`" title="
|
|
62
|
+
<button class="card-action-btn" @click="openOpenclawEditModal(name)" :aria-label="`Edit OpenClaw config ${name}`" :title="t('openclaw.action.edit')">
|
|
69
63
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
70
64
|
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
|
|
71
65
|
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
|
72
66
|
</svg>
|
|
73
67
|
</button>
|
|
74
|
-
<button class="card-action-btn delete" @click="deleteOpenclawConfig(name)" :aria-label="`Delete OpenClaw config ${name}`" title="
|
|
68
|
+
<button v-if="name !== '默认配置'" class="card-action-btn delete" @click="deleteOpenclawConfig(name)" :aria-label="`Delete OpenClaw config ${name}`" :title="t('openclaw.action.delete')">
|
|
75
69
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
76
70
|
<path d="M3 6h18"/>
|
|
77
71
|
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
<div
|
|
2
|
+
v-show="mainTab === 'docs'"
|
|
3
|
+
class="mode-content docs-mode-content"
|
|
4
|
+
id="panel-docs"
|
|
5
|
+
role="tabpanel"
|
|
6
|
+
aria-labelledby="tab-docs">
|
|
7
|
+
<div class="selector-section docs-overview-section">
|
|
8
|
+
<div class="selector-header docs-overview-header">
|
|
9
|
+
<div>
|
|
10
|
+
<span class="selector-title">{{ t('docs.title') }}</span>
|
|
11
|
+
<div class="skills-panel-note docs-section-note">{{ t('docs.subtitle') }}</div>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div class="docs-toolbar-grid">
|
|
16
|
+
<div class="docs-toolbar-card">
|
|
17
|
+
<label class="form-label" for="docs-install-package-manager">{{ t('common.packageManager') }}</label>
|
|
18
|
+
<select id="docs-install-package-manager" class="form-input" v-model="installPackageManager">
|
|
19
|
+
<option value="npm">npm</option>
|
|
20
|
+
<option value="pnpm">pnpm</option>
|
|
21
|
+
<option value="bun">bun</option>
|
|
22
|
+
</select>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="docs-toolbar-card docs-toolbar-card-wide">
|
|
26
|
+
<label class="form-label">{{ t('common.mirror') }}</label>
|
|
27
|
+
<div class="install-action-tabs">
|
|
28
|
+
<button type="button" class="btn-mini" :class="{ active: installRegistryPreset === 'default' }" @click="setInstallRegistryPreset('default')">{{ t('common.official') }}</button>
|
|
29
|
+
<button type="button" class="btn-mini" :class="{ active: installRegistryPreset === 'npmmirror' }" @click="setInstallRegistryPreset('npmmirror')">npmmirror</button>
|
|
30
|
+
<button type="button" class="btn-mini" :class="{ active: installRegistryPreset === 'tencent' }" @click="setInstallRegistryPreset('tencent')">{{ t('docs.registry.tencent') }}</button>
|
|
31
|
+
<button type="button" class="btn-mini" :class="{ active: installRegistryPreset === 'custom' }" @click="setInstallRegistryPreset('custom')">{{ t('common.custom') }}</button>
|
|
32
|
+
</div>
|
|
33
|
+
<input
|
|
34
|
+
v-if="installRegistryPreset === 'custom'"
|
|
35
|
+
v-model="installRegistryCustom"
|
|
36
|
+
class="form-input install-registry-input"
|
|
37
|
+
placeholder="https://registry.example.com">
|
|
38
|
+
<div class="form-hint install-registry-hint" v-if="installRegistryPreview">
|
|
39
|
+
{{ t('docs.registryHintPrefix') }} --registry={{ installRegistryPreview }}
|
|
40
|
+
</div>
|
|
41
|
+
<div class="form-hint install-registry-hint" v-else-if="installRegistryPreset === 'custom'">
|
|
42
|
+
{{ t('docs.registryHintCustom') }}
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div class="docs-toolbar-card docs-toolbar-card-wide">
|
|
47
|
+
<label class="form-label">{{ t('common.action') }}</label>
|
|
48
|
+
<div class="install-action-tabs">
|
|
49
|
+
<button type="button" class="btn-mini" :class="{ active: installCommandAction === 'install' }" @click="setInstallCommandAction('install')">{{ t('common.install') }}</button>
|
|
50
|
+
<button type="button" class="btn-mini" :class="{ active: installCommandAction === 'update' }" @click="setInstallCommandAction('update')">{{ t('common.update') }}</button>
|
|
51
|
+
<button type="button" class="btn-mini" :class="{ active: installCommandAction === 'uninstall' }" @click="setInstallCommandAction('uninstall')">{{ t('common.uninstall') }}</button>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div class="docs-summary-strip">
|
|
57
|
+
<div class="docs-summary-item">
|
|
58
|
+
<span class="docs-summary-label">{{ t('common.targets') }}</span>
|
|
59
|
+
<strong class="docs-summary-value">{{ installTargetCards.length }}</strong>
|
|
60
|
+
</div>
|
|
61
|
+
<div class="docs-summary-item">
|
|
62
|
+
<span class="docs-summary-label">{{ t('common.currentPm') }}</span>
|
|
63
|
+
<strong class="docs-summary-value">{{ String(installPackageManager || 'npm').toUpperCase() }}</strong>
|
|
64
|
+
</div>
|
|
65
|
+
<div class="docs-summary-item">
|
|
66
|
+
<span class="docs-summary-label">{{ t('common.currentAction') }}</span>
|
|
67
|
+
<strong class="docs-summary-value">{{ installCommandAction === 'update' ? t('common.update') : (installCommandAction === 'uninstall' ? t('common.uninstall') : t('common.install')) }}</strong>
|
|
68
|
+
</div>
|
|
69
|
+
<div class="docs-summary-item docs-summary-item-wide">
|
|
70
|
+
<span class="docs-summary-label">{{ t('common.mirrorActive') }}</span>
|
|
71
|
+
<strong class="docs-summary-value">{{ installRegistryPreview || t('common.defaultOfficial') }}</strong>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div class="selector-section docs-command-section">
|
|
77
|
+
<div class="selector-header docs-section-header">
|
|
78
|
+
<div>
|
|
79
|
+
<span class="selector-title">{{ t('docs.section.commands') }}</span>
|
|
80
|
+
<div class="skills-panel-note docs-section-note">{{ t('docs.section.commandsNote') }}</div>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<div class="install-list docs-install-list">
|
|
85
|
+
<div
|
|
86
|
+
class="install-row docs-install-row"
|
|
87
|
+
v-for="target in installTargetCards"
|
|
88
|
+
:key="'docs-install-command-' + target.id + '-' + installCommandAction">
|
|
89
|
+
<div class="install-row-main">
|
|
90
|
+
<div class="docs-command-head">
|
|
91
|
+
<div class="install-row-title">{{ target.name }}</div>
|
|
92
|
+
<div class="docs-command-meta">
|
|
93
|
+
<span class="docs-meta-pill">{{ target.packageName }}</span>
|
|
94
|
+
<span class="docs-meta-pill">bin: {{ target.bin }}</span>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
<div class="docs-command-row">
|
|
98
|
+
<div class="docs-command-box" role="group" :aria-label="`${target.name} command`">
|
|
99
|
+
<code class="install-command">{{ target.command }}</code>
|
|
100
|
+
<button
|
|
101
|
+
type="button"
|
|
102
|
+
class="btn-mini docs-copy-btn"
|
|
103
|
+
:disabled="!target.command"
|
|
104
|
+
@click="copyInstallCommand(target.command)">{{ t('common.copy') }}</button>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
<div
|
|
108
|
+
v-if="target.id === 'codex' && target.termuxCommand && target.termuxCommand !== target.command"
|
|
109
|
+
class="docs-command-row docs-command-row-secondary">
|
|
110
|
+
<div class="docs-command-box" role="group" :aria-label="t('docs.termuxAria')">
|
|
111
|
+
<code class="install-command"><span class="docs-command-prefix">{{ t('docs.termuxLabel') }}</span>{{ target.termuxCommand }}</code>
|
|
112
|
+
<button
|
|
113
|
+
type="button"
|
|
114
|
+
class="btn-mini docs-copy-btn"
|
|
115
|
+
@click="copyInstallCommand(target.termuxCommand)">{{ t('common.copy') }}</button>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<div class="selector-section docs-help-section">
|
|
124
|
+
<div class="selector-header docs-section-header">
|
|
125
|
+
<div>
|
|
126
|
+
<span class="selector-title">{{ t('docs.section.faq') }}</span>
|
|
127
|
+
<div class="skills-panel-note docs-section-note">{{ t('docs.section.faqNote') }}</div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div class="docs-help-grid">
|
|
132
|
+
<div class="docs-note-card">
|
|
133
|
+
<div class="docs-note-title">{{ t('common.troubleshooting') }}</div>
|
|
134
|
+
<ul class="install-help-list docs-help-list">
|
|
135
|
+
<li v-for="tip in installTroubleshootingTips" :key="tip">{{ tip }}</li>
|
|
136
|
+
</ul>
|
|
137
|
+
</div>
|
|
138
|
+
<div class="docs-note-card">
|
|
139
|
+
<div class="docs-note-title">{{ t('common.rules') }}</div>
|
|
140
|
+
<ul class="docs-static-list">
|
|
141
|
+
<li>{{ t('docs.rule.1') }}</li>
|
|
142
|
+
<li>{{ t('docs.rule.2') }}</li>
|
|
143
|
+
</ul>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|