mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-31 11:01:36 +08:00
feat(hermes): launch dashboard from toolbar when Web UI is offline
When the Hermes Web UI probe fails, the toolbar entry now opens an info confirm dialog offering to run `hermes dashboard` in the user's preferred terminal. Accepting spawns it via a temp bash/batch script; `hermes dashboard` itself opens the browser once ready, so we do not poll. The Memory panel and Health banner keep the existing toast behavior. Also corrects the stale `hermes web` hint in the offline toast (the real command is `hermes dashboard`) and reorders Linux terminal detection to try `which` before stat'ing /usr/bin, /bin, /usr/local/bin.
This commit is contained in:
+27
-1
@@ -46,6 +46,7 @@ import {
|
||||
useHermesHealth,
|
||||
useOpenHermesWebUI,
|
||||
} from "@/hooks/useHermes";
|
||||
import { hermesApi } from "@/lib/api/hermes";
|
||||
import { useProxyStatus } from "@/hooks/useProxyStatus";
|
||||
import { useAutoCompact } from "@/hooks/useAutoCompact";
|
||||
import { useLastValidValue } from "@/hooks/useLastValidValue";
|
||||
@@ -628,7 +629,10 @@ function App() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const openHermesWebUI = useOpenHermesWebUI();
|
||||
const [launchDashboardOpen, setLaunchDashboardOpen] = useState(false);
|
||||
const openHermesWebUI = useOpenHermesWebUI(() =>
|
||||
setLaunchDashboardOpen(true),
|
||||
);
|
||||
|
||||
const handleOpenWebsite = async (url: string) => {
|
||||
try {
|
||||
@@ -1611,6 +1615,28 @@ function App() {
|
||||
onCancel={() => setConfirmAction(null)}
|
||||
/>
|
||||
|
||||
<ConfirmDialog
|
||||
isOpen={launchDashboardOpen}
|
||||
title={t("hermes.webui.launchConfirmTitle")}
|
||||
message={t("hermes.webui.launchConfirmMessage")}
|
||||
confirmText={t("hermes.webui.launchConfirmAction")}
|
||||
variant="info"
|
||||
onConfirm={() => {
|
||||
setLaunchDashboardOpen(false);
|
||||
void (async () => {
|
||||
try {
|
||||
await hermesApi.launchDashboard();
|
||||
toast.success(t("hermes.webui.launching"));
|
||||
} catch (error) {
|
||||
toast.error(t("hermes.webui.launchFailed"), {
|
||||
description: extractErrorMessage(error) || undefined,
|
||||
});
|
||||
}
|
||||
})();
|
||||
}}
|
||||
onCancel={() => setLaunchDashboardOpen(false)}
|
||||
/>
|
||||
|
||||
<DeepLinkImportDialog />
|
||||
<FirstRunNoticeDialog />
|
||||
</div>
|
||||
|
||||
+10
-5
@@ -155,10 +155,11 @@ export function useToggleHermesMemoryEnabled() {
|
||||
|
||||
/**
|
||||
* Returns a handler that probes the local Hermes Web UI, opens it in the
|
||||
* system browser, and surfaces a localized toast on failure. Callers only
|
||||
* need to wire the returned function to a click handler.
|
||||
* system browser, and surfaces a localized toast on failure. When
|
||||
* `onOffline` is provided, it replaces the default offline toast —
|
||||
* callers can use this to open a launch-dashboard confirm dialog instead.
|
||||
*/
|
||||
export function useOpenHermesWebUI() {
|
||||
export function useOpenHermesWebUI(onOffline?: () => void) {
|
||||
const { t } = useTranslation();
|
||||
return useCallback(
|
||||
async (path?: string) => {
|
||||
@@ -167,7 +168,11 @@ export function useOpenHermesWebUI() {
|
||||
} catch (error) {
|
||||
const detail = extractErrorMessage(error);
|
||||
if (detail === HERMES_WEB_OFFLINE_ERROR) {
|
||||
toast.error(t("hermes.webui.offline"));
|
||||
if (onOffline) {
|
||||
onOffline();
|
||||
} else {
|
||||
toast.error(t("hermes.webui.offline"));
|
||||
}
|
||||
} else {
|
||||
toast.error(t("hermes.webui.openFailed"), {
|
||||
description: detail || undefined,
|
||||
@@ -175,6 +180,6 @@ export function useOpenHermesWebUI() {
|
||||
}
|
||||
}
|
||||
},
|
||||
[t],
|
||||
[t, onOffline],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1677,9 +1677,14 @@
|
||||
},
|
||||
"webui": {
|
||||
"open": "Open Hermes Web UI",
|
||||
"offline": "Hermes Web UI is not running. Start it with `hermes web` first.",
|
||||
"offline": "Hermes Web UI is not running. Start it with `hermes dashboard` first.",
|
||||
"openFailed": "Failed to open Hermes Web UI",
|
||||
"fixInWebUI": "Fix in Hermes Web UI"
|
||||
"fixInWebUI": "Fix in Hermes Web UI",
|
||||
"launchConfirmTitle": "Hermes Dashboard is not running",
|
||||
"launchConfirmMessage": "Open a terminal and start it now with `hermes dashboard`?\n\nThe browser will open automatically once startup completes.\n\nIf the terminal reports that `hermes` cannot be found or the web extras are missing, run first:\npip install hermes-agent[web]",
|
||||
"launchConfirmAction": "Open terminal & launch",
|
||||
"launching": "Started `hermes dashboard` in a terminal.",
|
||||
"launchFailed": "Failed to open terminal"
|
||||
},
|
||||
"health": {
|
||||
"title": "Hermes config warnings detected",
|
||||
|
||||
@@ -1677,9 +1677,14 @@
|
||||
},
|
||||
"webui": {
|
||||
"open": "Hermes Web UI を開く",
|
||||
"offline": "Hermes Web UI が起動していません。まず `hermes web` を実行してください。",
|
||||
"offline": "Hermes Web UI が起動していません。まず `hermes dashboard` を実行してください。",
|
||||
"openFailed": "Hermes Web UI を開けませんでした",
|
||||
"fixInWebUI": "Hermes Web UI で修正"
|
||||
"fixInWebUI": "Hermes Web UI で修正",
|
||||
"launchConfirmTitle": "Hermes Dashboard が起動していません",
|
||||
"launchConfirmMessage": "ターミナルを開いて `hermes dashboard` を実行しますか?\n\n起動完了後、ブラウザが自動的に開きます。\n\nターミナルに `hermes` が見つからない、または web 依存が不足するというエラーが表示される場合は、まず次を実行してください:\npip install hermes-agent[web]",
|
||||
"launchConfirmAction": "ターミナルを開いて起動",
|
||||
"launching": "ターミナルで hermes dashboard を起動しました。",
|
||||
"launchFailed": "ターミナルを開けませんでした"
|
||||
},
|
||||
"health": {
|
||||
"title": "Hermes 設定の警告を検出",
|
||||
|
||||
@@ -1677,9 +1677,14 @@
|
||||
},
|
||||
"webui": {
|
||||
"open": "打开 Hermes Web UI",
|
||||
"offline": "Hermes Web UI 未启动,请先运行 `hermes web` 启动服务。",
|
||||
"offline": "Hermes Web UI 未启动,请先运行 `hermes dashboard` 启动服务。",
|
||||
"openFailed": "打开 Hermes Web UI 失败",
|
||||
"fixInWebUI": "在 Hermes Web UI 修复"
|
||||
"fixInWebUI": "在 Hermes Web UI 修复",
|
||||
"launchConfirmTitle": "Hermes Dashboard 未启动",
|
||||
"launchConfirmMessage": "是否打开终端并运行 `hermes dashboard` 启动服务?\n\n启动完成后会自动打开浏览器。\n\n若终端提示找不到 hermes 或缺少 web 依赖,请先运行:\npip install hermes-agent[web]",
|
||||
"launchConfirmAction": "打开终端并启动",
|
||||
"launching": "已在终端启动 hermes dashboard",
|
||||
"launchFailed": "打开终端失败"
|
||||
},
|
||||
"health": {
|
||||
"title": "检测到 Hermes 配置警告",
|
||||
|
||||
@@ -33,6 +33,11 @@ export const hermesApi = {
|
||||
await invoke("open_hermes_web_ui", { path: path ?? null });
|
||||
},
|
||||
|
||||
/** Open the preferred terminal and run `hermes dashboard` (non-blocking). */
|
||||
async launchDashboard(): Promise<void> {
|
||||
await invoke("launch_hermes_dashboard");
|
||||
},
|
||||
|
||||
/**
|
||||
* Read one of Hermes' memory blobs (`MEMORY.md` or `USER.md`). Returns an
|
||||
* empty string when the file hasn't been created yet.
|
||||
|
||||
Reference in New Issue
Block a user