codexmate 0.1.1 → 0.1.3
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 +6 -3
- package/cli/openai-bridge-retry.js +17 -9
- package/cli/openai-bridge-runtime.js +14 -1
- package/cli/openai-bridge.js +20 -10
- package/cli.js +375 -4
- package/package.json +1 -1
- package/web-ui/app.js +18 -4
- package/web-ui/index.html +1 -0
- package/web-ui/modules/app.computed.dashboard.mjs +14 -0
- package/web-ui/modules/app.methods.agents.mjs +2 -2
- package/web-ui/modules/app.methods.index.mjs +2 -0
- package/web-ui/modules/app.methods.install.mjs +14 -0
- package/web-ui/modules/app.methods.kilocode-config.mjs +164 -0
- package/web-ui/modules/app.methods.navigation.mjs +12 -0
- package/web-ui/modules/app.methods.openclaw-core.mjs +87 -0
- package/web-ui/modules/app.methods.providers.mjs +5 -32
- package/web-ui/modules/app.methods.startup-claude.mjs +2 -1
- package/web-ui/modules/app.methods.tool-config-permissions.mjs +3 -2
- package/web-ui/modules/app.methods.web-ui-preferences.mjs +2 -1
- package/web-ui/modules/config-mode.computed.mjs +11 -1
- package/web-ui/modules/i18n/locales/en.mjs +31 -4
- package/web-ui/modules/i18n/locales/ja.mjs +34 -8
- package/web-ui/modules/i18n/locales/vi.mjs +35 -9
- package/web-ui/modules/i18n/locales/zh-tw.mjs +36 -9
- package/web-ui/modules/i18n/locales/zh.mjs +40 -13
- package/web-ui/partials/index/layout-header.html +32 -21
- package/web-ui/partials/index/modal-config-template-agents.html +8 -4
- package/web-ui/partials/index/modals-basic.html +0 -26
- package/web-ui/partials/index/panel-config-kilocode.html +101 -0
- package/web-ui/partials/index/panel-config-openclaw.html +42 -14
- package/web-ui/partials/index/panel-config-opencode.html +1 -0
- package/web-ui/partials/index/panel-docs.html +17 -1
- package/web-ui/res/web-ui-render.precompiled.js +400 -123
- package/web-ui/styles/controls-forms.css +10 -0
- package/web-ui/styles/docs-panel.css +51 -0
- package/web-ui/styles/layout-shell.css +12 -0
- package/web-ui/styles/modals-core.css +79 -0
- package/web-ui/styles/openclaw-structured.css +117 -71
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<!-- KiloCode 配置 -->
|
|
2
|
+
<div
|
|
3
|
+
v-show="mainTab === 'config' && configMode === 'kilocode'"
|
|
4
|
+
class="mode-content mode-cards"
|
|
5
|
+
id="panel-config-kilocode"
|
|
6
|
+
role="tabpanel"
|
|
7
|
+
:aria-labelledby="forceCompactLayout ? 'tab-config' : 'side-tab-config-kilocode'">
|
|
8
|
+
<div v-if="forceCompactLayout && !sessionStandalone" class="segmented-control">
|
|
9
|
+
<button type="button" :class="['segment', { active: configMode === 'codex' }]" @click="switchConfigMode('codex')">{{ t('tab.config.codex') }}</button>
|
|
10
|
+
<button type="button" :class="['segment', { active: configMode === 'claude' }]" @click="switchConfigMode('claude')">{{ t('tab.config.claude') }}</button>
|
|
11
|
+
<button type="button" :class="['segment', { active: configMode === 'openclaw' }]" @click="switchConfigMode('openclaw')">{{ t('tab.config.openclaw') }}</button>
|
|
12
|
+
<button type="button" :class="['segment', { active: configMode === 'opencode' }]" @click="switchConfigMode('opencode')">{{ t('tab.config.opencode') }}</button>
|
|
13
|
+
<button type="button" :class="['segment', { active: configMode === 'kilocode' }]" @click="switchConfigMode('kilocode')">{{ t('tab.config.kilocode') }}</button>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<section class="tool-config-write-card" :aria-label="t('toolConfig.kilocode.title')">
|
|
17
|
+
<div class="tool-config-write-copy">
|
|
18
|
+
<div class="tool-config-write-title">{{ t('toolConfig.kilocode.title') }}</div>
|
|
19
|
+
<p class="tool-config-write-desc">{{ t('toolConfig.kilocode.desc') }}</p>
|
|
20
|
+
</div>
|
|
21
|
+
<label class="settings-toggle-row tool-config-write-toggle">
|
|
22
|
+
<input
|
|
23
|
+
type="checkbox"
|
|
24
|
+
autocomplete="off"
|
|
25
|
+
:checked="isToolConfigWriteAllowed('kilocode')"
|
|
26
|
+
:disabled="toolConfigPermissionSaving.kilocode"
|
|
27
|
+
@change="setToolConfigPermission('kilocode', $event.target.checked)">
|
|
28
|
+
<span class="toggle-track"><span class="toggle-thumb"></span></span>
|
|
29
|
+
<span>{{ toolConfigPermissionStatusLabel('kilocode') }}</span>
|
|
30
|
+
</label>
|
|
31
|
+
</section>
|
|
32
|
+
|
|
33
|
+
<div class="tool-config-write-scope" :class="{ locked: !isToolConfigWriteAllowed('kilocode') }">
|
|
34
|
+
<div class="tool-config-write-body">
|
|
35
|
+
<section class="selector-section">
|
|
36
|
+
<div class="selector-header">
|
|
37
|
+
<span class="selector-title">{{ t('kilocode.providerModel.title') }}</span>
|
|
38
|
+
</div>
|
|
39
|
+
<div class="config-template-hint">{{ t('kilocode.targetFile', { path: kilocodeConfigPath || '~/.config/kilo/kilo.jsonc', status: kilocodeConfigExists ? t('common.exists') : t('common.notExistsWillCreateOnSave') }) }}</div>
|
|
40
|
+
<div class="codex-config-grid">
|
|
41
|
+
<div class="form-group codex-config-field">
|
|
42
|
+
<label class="form-label" for="kilocode-provider">{{ t('field.provider') }}</label>
|
|
43
|
+
<input id="kilocode-provider" class="form-input" v-model="kilocodeProvider" autocomplete="off" spellcheck="false" placeholder="codexmate" @blur="autoSaveKilocodeConfig">
|
|
44
|
+
</div>
|
|
45
|
+
<div class="form-group codex-config-field">
|
|
46
|
+
<label class="form-label" for="kilocode-base-url">{{ t('field.url') }}</label>
|
|
47
|
+
<input id="kilocode-base-url" class="form-input" v-model="kilocodeBaseUrl" autocomplete="off" spellcheck="false" placeholder="https://api.example.com/v1" @blur="autoSaveKilocodeConfig">
|
|
48
|
+
</div>
|
|
49
|
+
<div class="form-group codex-config-field">
|
|
50
|
+
<label class="form-label" for="kilocode-model">{{ t('field.model') }}</label>
|
|
51
|
+
<input id="kilocode-model" class="form-input" v-model="kilocodeModel" autocomplete="off" spellcheck="false" placeholder="gpt-5.3" @blur="autoSaveKilocodeConfig">
|
|
52
|
+
</div>
|
|
53
|
+
<div class="form-group codex-config-field">
|
|
54
|
+
<label class="form-label" for="kilocode-api-key">{{ t('opencode.field.apiKeyKeep') }}</label>
|
|
55
|
+
<div class="input-with-toggle">
|
|
56
|
+
<input id="kilocode-api-key" class="form-input" v-model="kilocodeApiKey" :type="kilocodeShowKey ? 'text' : 'password'" autocomplete="off" spellcheck="false" placeholder="sk-..." @blur="autoSaveKilocodeConfig">
|
|
57
|
+
<button type="button" class="input-toggle-btn" @mousedown.prevent @click="kilocodeShowKey = !kilocodeShowKey" :title="kilocodeShowKey ? t('common.hide') : t('common.show')" :aria-label="kilocodeShowKey ? t('common.hide') : t('common.show')">
|
|
58
|
+
<svg v-if="!kilocodeShowKey" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" width="16" height="16"><path d="M10 4C5 4 1.73 8.11 1 10c.73 1.89 4 6 9 6s8.27-4.11 9-6c-.73-1.89-4-6-9-6z"/><circle cx="10" cy="10" r="3"/></svg>
|
|
59
|
+
<svg v-else viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5" width="16" height="16"><path d="M2 2l16 16M8.2 4.2A9.9 9.9 0 0 1 10 4c5 0 8.27 4.11 9 6-.44.94-1.5 2.7-3.2 4.2M14.5 14.5A5.9 5.9 0 0 1 10 16c-5 0-8.27-4.11-9-6 .76-1.66 2.2-3.6 4.3-5"/></svg>
|
|
60
|
+
</button>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<div v-if="kilocodeError" class="config-template-hint error-text">{{ kilocodeError }}</div>
|
|
65
|
+
</section>
|
|
66
|
+
|
|
67
|
+
<section class="selector-section" v-if="kilocodeProviders.length">
|
|
68
|
+
<div class="selector-header"><span class="selector-title">{{ t('kilocode.summary.title') }}</span></div>
|
|
69
|
+
<div class="card-list">
|
|
70
|
+
<div v-for="provider in kilocodeProviders" :key="provider.name" :class="['card', { active: normalizeKilocodeProviderNameForUi(provider.name) === normalizeKilocodeProviderNameForUi(kilocodeProvider) }]" @dblclick="selectKilocodeProvider(provider)" @keydown.enter.self.prevent="selectKilocodeProvider(provider)" tabindex="0" role="button" :aria-current="normalizeKilocodeProviderNameForUi(provider.name) === normalizeKilocodeProviderNameForUi(kilocodeProvider) ? 'true' : null">
|
|
71
|
+
<div class="card-leading">
|
|
72
|
+
<div class="card-icon">{{ provider.name.charAt(0).toUpperCase() }}</div>
|
|
73
|
+
<div class="card-content">
|
|
74
|
+
<div class="card-title">{{ provider.name }}</div>
|
|
75
|
+
<div class="card-subtitle">{{ provider.baseURL || provider.api || t('config.url.unset') }}</div>
|
|
76
|
+
<div class="card-subtitle">{{ (provider.models || []).join(', ') || t('opencode.summary.noModel') }}</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="card-trailing">
|
|
80
|
+
<span :class="['pill', provider.hasKey ? 'configured' : 'empty']">{{ provider.hasKey ? t('common.configured') : t('common.notConfigured') }}</span>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</section>
|
|
85
|
+
|
|
86
|
+
<section class="selector-section">
|
|
87
|
+
<div class="selector-header"><span class="selector-title">{{ t('kilocode.configPreview.title') }}</span></div>
|
|
88
|
+
<textarea class="template-textarea" :value="kilocodeContent" spellcheck="false" readonly aria-readonly="true"></textarea>
|
|
89
|
+
<div class="config-template-hint">{{ t('kilocode.configPreview.hint') }}</div>
|
|
90
|
+
</section>
|
|
91
|
+
|
|
92
|
+
<div v-if="!isToolConfigWriteAllowed('kilocode')" class="tool-config-write-overlay">
|
|
93
|
+
<div class="tool-config-write-overlay-card">
|
|
94
|
+
<div class="tool-config-write-overlay-title">{{ t('toolConfig.kilocode.lockedTitle') }}</div>
|
|
95
|
+
<p>{{ t('toolConfig.kilocode.lockedDesc') }}</p>
|
|
96
|
+
<button type="button" class="btn-tool" @click="setToolConfigPermission('kilocode', true)" :disabled="toolConfigPermissionSaving.kilocode">{{ t('toolConfig.enableWrite') }}</button>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
@@ -11,6 +11,27 @@
|
|
|
11
11
|
<button type="button" :class="['segment', { active: configMode === 'openclaw' }]" @click="switchConfigMode('openclaw')">{{ t('tab.config.openclaw') }}</button>
|
|
12
12
|
</div>
|
|
13
13
|
<div class="openclaw-layout">
|
|
14
|
+
<section class="settings-card settings-card--wide openclaw-summary-card" aria-label="OpenClaw 当前摘要">
|
|
15
|
+
<div class="settings-card-body">
|
|
16
|
+
<div class="openclaw-summary-header">
|
|
17
|
+
<div>
|
|
18
|
+
<div class="summary-eyebrow">OPENCLAW</div>
|
|
19
|
+
<div class="summary-title">配置与本地诊断</div>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="summary-note">配置摘要</div>
|
|
22
|
+
</div>
|
|
23
|
+
<div class="openclaw-summary-grid">
|
|
24
|
+
<div v-for="item in getOpenclawStatusSummaryItems()" :key="item.key" :class="['openclaw-summary-item', item.tone || '']">
|
|
25
|
+
<div class="summary-item-label">{{ item.label }}</div>
|
|
26
|
+
<div class="summary-item-value">{{ item.value }}</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="openclaw-diagnostic-note">
|
|
30
|
+
本页仅管理配置与工作区文件。
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</section>
|
|
34
|
+
|
|
14
35
|
<section class="settings-card settings-card--wide openclaw-workspace-card">
|
|
15
36
|
<div class="settings-card-body">
|
|
16
37
|
<div class="openclaw-tools-grid">
|
|
@@ -18,27 +39,29 @@
|
|
|
18
39
|
<div class="tool-icon">📄</div>
|
|
19
40
|
<div class="tool-content">
|
|
20
41
|
<div class="tool-title">AGENTS.md</div>
|
|
21
|
-
<div class="tool-meta">{{ agentsLoading ? t('config.modelLoading') :
|
|
42
|
+
<div class="tool-meta">{{ agentsLoading ? t('config.modelLoading') : 'Workspace file' }}</div>
|
|
22
43
|
</div>
|
|
23
44
|
<svg class="tool-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
24
45
|
<path d="M9 18l6-6-6-6"/>
|
|
25
46
|
</svg>
|
|
26
47
|
</button>
|
|
27
48
|
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</
|
|
49
|
+
<button
|
|
50
|
+
v-for="fileName in getOpenclawQuickWorkspaceFiles()"
|
|
51
|
+
:key="fileName"
|
|
52
|
+
type="button"
|
|
53
|
+
class="openclaw-tool-btn"
|
|
54
|
+
@click="openOpenclawQuickWorkspaceFile(fileName)"
|
|
55
|
+
:disabled="loading || !!initError || agentsLoading">
|
|
56
|
+
<div class="tool-icon">📄</div>
|
|
57
|
+
<div class="tool-content">
|
|
58
|
+
<div class="tool-title">{{ fileName }}</div>
|
|
59
|
+
<div class="tool-meta">Workspace file</div>
|
|
39
60
|
</div>
|
|
40
|
-
<
|
|
41
|
-
|
|
61
|
+
<svg class="tool-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
62
|
+
<path d="M9 18l6-6-6-6"/>
|
|
63
|
+
</svg>
|
|
64
|
+
</button>
|
|
42
65
|
</div>
|
|
43
66
|
</div>
|
|
44
67
|
</section>
|
|
@@ -60,6 +83,11 @@
|
|
|
60
83
|
<div class="card-content">
|
|
61
84
|
<div class="card-title">{{ name }}</div>
|
|
62
85
|
<div class="card-subtitle">{{ openclawSubtitle(config) }}</div>
|
|
86
|
+
<div v-if="openclawHasContent(config)" class="openclaw-config-summary-mini">
|
|
87
|
+
<span v-for="item in getOpenclawConfigSummary(config).slice(0, 3)" :key="item.key">
|
|
88
|
+
{{ item.label }}: {{ item.value }}
|
|
89
|
+
</span>
|
|
90
|
+
</div>
|
|
63
91
|
</div>
|
|
64
92
|
</div>
|
|
65
93
|
<div class="card-trailing">
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
<button type="button" :class="['segment', { active: configMode === 'claude' }]" @click="switchConfigMode('claude')">{{ t('tab.config.claude') }}</button>
|
|
11
11
|
<button type="button" :class="['segment', { active: configMode === 'openclaw' }]" @click="switchConfigMode('openclaw')">{{ t('tab.config.openclaw') }}</button>
|
|
12
12
|
<button type="button" :class="['segment', { active: configMode === 'opencode' }]" @click="switchConfigMode('opencode')">{{ t('tab.config.opencode') }}</button>
|
|
13
|
+
<button type="button" :class="['segment', { active: configMode === 'kilocode' }]" @click="switchConfigMode('kilocode')">{{ t('tab.config.kilocode') }}</button>
|
|
13
14
|
</div>
|
|
14
15
|
|
|
15
16
|
<section class="tool-config-write-card" :aria-label="t('opencode.writeAria')">
|
|
@@ -54,6 +54,22 @@
|
|
|
54
54
|
<strong class="docs-summary-value">{{ installRegistryPreview || 'npmmirror' }}</strong>
|
|
55
55
|
</div>
|
|
56
56
|
</div>
|
|
57
|
+
|
|
58
|
+
<div class="docs-installed-card">
|
|
59
|
+
<div class="docs-installed-head">
|
|
60
|
+
<span class="docs-installed-title">{{ t('docs.installed.title') }}</span>
|
|
61
|
+
<span class="docs-installed-count">{{ currentInstalledCommandCards.length ? t('docs.installed.count', { count: currentInstalledCommandCards.length }) : t('docs.installed.empty') }}</span>
|
|
62
|
+
</div>
|
|
63
|
+
<div v-if="currentInstalledCommandCards.length" class="docs-installed-list">
|
|
64
|
+
<div v-for="target in currentInstalledCommandCards" :key="'docs-installed-' + target.id" class="docs-installed-item">
|
|
65
|
+
<div class="docs-installed-main">
|
|
66
|
+
<span class="docs-installed-name">{{ target.name }}</span>
|
|
67
|
+
<span class="docs-installed-version">{{ target.version || '—' }}</span>
|
|
68
|
+
</div>
|
|
69
|
+
<code class="docs-installed-command">{{ target.commandPath || target.bin }}</code>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
57
73
|
</div>
|
|
58
74
|
|
|
59
75
|
<div class="selector-section">
|
|
@@ -111,4 +127,4 @@
|
|
|
111
127
|
</div>
|
|
112
128
|
</div>
|
|
113
129
|
</div>
|
|
114
|
-
</div>
|
|
130
|
+
</div>
|