feat(hermes): replace Prompts entry with Memory panel

Hermes has no slash-prompt concept (templates live as Skills), so the
Prompts tab for the Hermes app was always empty. Swap the toolbar Book
button for a Brain button that opens a new Memory panel editing
~/.hermes/memories/{MEMORY,USER}.md — Hermes' first-class memory store
which its Web UI exposes only as on/off toggles, never as an editor.

The panel shows each file in its own tab with a character-budget bar
read from config.yaml's nested memory.* section (memory_char_limit /
user_char_limit, default 2200 / 1375). Edits are written atomically;
Hermes picks them up on the next session start per MemoryStore.

Also extract useDarkMode to src/hooks/useDarkMode.ts — the codebase
already repeats the same MutationObserver pattern in 12+ places; this
PR introduces the shared hook and uses it once, leaving the migration
of the other copies to a follow-up.
This commit is contained in:
Jason
2026-04-19 21:49:27 +08:00
parent 088b47b08a
commit acc6d795e4
12 changed files with 552 additions and 6 deletions
+27 -1
View File
@@ -1,5 +1,10 @@
import { invoke } from "@tauri-apps/api/core";
import type { HermesModelConfig, HermesHealthWarning } from "@/types";
import type {
HermesHealthWarning,
HermesMemoryKind,
HermesMemoryLimits,
HermesModelConfig,
} from "@/types";
/**
* Hermes Agent configuration API (CC Switch side).
@@ -27,4 +32,25 @@ export const hermesApi = {
async openWebUI(path?: string): Promise<void> {
await invoke("open_hermes_web_ui", { path: path ?? null });
},
/**
* Read one of Hermes' memory blobs (`MEMORY.md` or `USER.md`). Returns an
* empty string when the file hasn't been created yet.
*/
async getMemory(kind: HermesMemoryKind): Promise<string> {
return await invoke("get_hermes_memory", { kind });
},
/** Atomically overwrite a Hermes memory file. */
async setMemory(kind: HermesMemoryKind, content: string): Promise<void> {
await invoke("set_hermes_memory", { kind, content });
},
/**
* Character budgets + enable flags for both memory blobs, read from
* config.yaml with Hermes defaults as fallback.
*/
async getMemoryLimits(): Promise<HermesMemoryLimits> {
return await invoke("get_hermes_memory_limits");
},
};