feat(about): add Hermes Agent upgrade/uninstall/config buttons

Hermes 卡片已安装状态下新增三个操作按钮:
- 配置: 跳转到 Hermes 设置页
- 升级: 调用 updateHermes() 重新安装最新版
- 卸载: 调用 uninstallHermes(),支持选择是否清除配置
新增 12 个 i18n 键 (zh/en/繁/ja/ko)
This commit is contained in:
晴天
2026-04-13 10:24:03 +08:00
parent c88a652bc5
commit 6971bd32e8
2 changed files with 62 additions and 1 deletions

View File

@@ -20,6 +20,17 @@ export default {
notInstalled: _('未安装', 'Not installed', '未安裝', '未インストール', '미설치', 'Chưa cài đặt', 'No instalado', 'Não instalado', 'Не установлен', 'Non installé', 'Nicht installiert'),
installed: _('已安装', 'Installed', '已安裝'),
hermesSetup: _('前往配置', 'Go to Setup', '前往配置'),
hermesConfig: _('配置', 'Config', '配置', '設定', '설정'),
hermesUpgrade: _('升级', 'Upgrade', '升級', 'アップグレード', '업그레이드'),
hermesUninstall: _('卸载', 'Uninstall', '卸載', 'アンインストール', '제거'),
upgrading: _('升级中...', 'Upgrading...', '升級中...', 'アップグレード中...', '업그레이드 중...'),
uninstalling: _('卸载中...', 'Uninstalling...', '卸載中...', 'アンインストール中...', '제거 중...'),
hermesUpgradeOk: _('Hermes Agent 已升级到 {version}', 'Hermes Agent upgraded to {version}', 'Hermes Agent 已升級到 {version}'),
hermesUpgradeFail: _('升级失败: {error}', 'Upgrade failed: {error}', '升級失敗: {error}'),
hermesUninstallConfirm: _('确定要卸载 Hermes Agent 吗?', 'Are you sure you want to uninstall Hermes Agent?', '確定要卸載 Hermes Agent 嗎?'),
hermesUninstallCleanConfig: _('是否同时清除配置文件?(选「取消」保留配置)', 'Also remove config files? (Cancel to keep)', '是否同時清除配置文件?(選「取消」保留配置)'),
hermesUninstallOk: _('Hermes Agent 已卸载', 'Hermes Agent uninstalled', 'Hermes Agent 已卸載'),
hermesUninstallFail: _('卸载失败: {error}', 'Uninstall failed: {error}', '卸載失敗: {error}'),
aheadOfRecommended: _('当前版本高于推荐稳定版: {ver}', 'Current version is ahead of recommended stable: {ver}', '目前版本高於推薦穩定版: {ver}'),
rollbackToRecommended: _('回退到推荐版', 'Rollback to recommended', '回退到推薦版'),
recommendedStable: _('推荐稳定版: {ver}', 'Recommended stable: {ver}', '推薦穩定版: {ver}', '推奨安定版: {ver}', '권장 안정 버전: {ver}'),

View File

@@ -89,6 +89,8 @@ async function loadHermesData(page) {
const esc = s => String(s || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
const btnSm = 'padding:2px 8px;font-size:var(--font-size-xs)'
cards.innerHTML = `
<div class="stat-card">
<div class="stat-card-header"><span class="stat-card-label">ClawPanel</span></div>
@@ -103,7 +105,12 @@ async function loadHermesData(page) {
? `<span style="color:var(--success)">● Gateway ${t('engine.dashRunning')} · :${port}</span>`
: `<span style="color:var(--text-tertiary)">○ Gateway ${t('engine.dashStopped')}</span>`}
${model ? `<span style="color:var(--text-secondary)">${t('engine.dashModel')}: ${esc(model)}</span>` : ''}
${!installed ? `<a class="btn btn-primary btn-sm" href="#/h/setup" style="padding:2px 8px;font-size:var(--font-size-xs)">${t('about.hermesSetup')}</a>` : ''}
${!installed ? `<a class="btn btn-primary btn-sm" href="#/h/setup" style="${btnSm}">${t('about.hermesSetup')}</a>` : ''}
${installed ? `
<a class="btn btn-secondary btn-sm" href="#/h/setup" style="${btnSm}">${t('about.hermesConfig')}</a>
<button class="btn btn-secondary btn-sm" id="btn-hermes-upgrade" style="${btnSm}">${t('about.hermesUpgrade')}</button>
<button class="btn btn-danger btn-sm" id="btn-hermes-uninstall" style="${btnSm}">${t('about.hermesUninstall')}</button>
` : ''}
</div>
</div>
<div class="stat-card">
@@ -112,6 +119,49 @@ async function loadHermesData(page) {
<div class="stat-card-meta" style="word-break:break-all">${esc(pyPath)}</div>
</div>
`
// Hermes 管理按钮事件
if (installed) {
const upgradeBtn = cards.querySelector('#btn-hermes-upgrade')
const uninstallBtn = cards.querySelector('#btn-hermes-uninstall')
if (upgradeBtn) {
upgradeBtn.onclick = async () => {
upgradeBtn.disabled = true
upgradeBtn.textContent = t('about.upgrading')
try {
const ver = await api.updateHermes()
toast(t('about.hermesUpgradeOk', { version: ver || '' }), 'success')
loadHermesData(page)
} catch (e) {
toast(t('about.hermesUpgradeFail', { error: e.message || e }), 'error')
} finally {
upgradeBtn.disabled = false
upgradeBtn.textContent = t('about.hermesUpgrade')
}
}
}
if (uninstallBtn) {
uninstallBtn.onclick = async () => {
const confirmed = confirm(t('about.hermesUninstallConfirm'))
if (!confirmed) return
const cleanConfig = confirm(t('about.hermesUninstallCleanConfig'))
uninstallBtn.disabled = true
uninstallBtn.textContent = t('about.uninstalling')
try {
await api.uninstallHermes(cleanConfig)
toast(t('about.hermesUninstallOk'), 'success')
loadHermesData(page)
} catch (e) {
toast(t('about.hermesUninstallFail', { error: e.message || e }), 'error')
} finally {
uninstallBtn.disabled = false
uninstallBtn.textContent = t('about.hermesUninstall')
}
}
}
}
} catch {
cards.innerHTML = `<div class="stat-card"><div class="stat-card-label">${t('common.loadFailed')}</div></div>`
}