feat: add Hermes frontend types, API layer, and hooks (Phase 7)

- Add "hermes" to AppId union type and all exhaustive Record<AppId>
- Add HermesModelConfig, HermesAgentConfig, HermesEnvConfig types
- Add hermes field to VisibleApps, McpApps, ProxyTakeoverStatus
- Create src/lib/api/hermes.ts with Tauri invoke wrappers
- Create src/hooks/useHermes.ts with 5 query + 3 mutation hooks
- Register hermes in APP_IDS, APP_ICON_MAP (violet color scheme)
- Split MCP_SKILLS_APP_IDS into MCP_APP_IDS (includes hermes) and
  SKILLS_APP_IDS (excludes hermes, since Hermes has no Skills support)
- Wire hermes additive-mode into App.tsx (remove/duplicate handlers),
  ProviderList.tsx (live provider ID query + In Config badge),
  mutations.ts (cache invalidation on switch/add/delete)
- Add Hermes checkbox to McpFormModal
- Add basic hermes i18n keys (en/zh/ja)
This commit is contained in:
Jason
2026-04-15 17:41:33 +08:00
parent 576ff53a75
commit a0b585992a
23 changed files with 467 additions and 33 deletions
+13 -3
View File
@@ -10,7 +10,7 @@ import type {
type ProvidersByApp = Record<AppId, Record<string, Provider>>;
type CurrentProviderState = Record<AppId, string>;
type McpConfigState = Record<AppId, Record<string, McpServer>>;
type LiveProviderIdsByApp = Record<"opencode" | "openclaw", string[]>;
type LiveProviderIdsByApp = Record<"opencode" | "openclaw" | "hermes", string[]>;
const createDefaultProviders = (): ProvidersByApp => ({
claude: {
@@ -66,6 +66,7 @@ const createDefaultProviders = (): ProvidersByApp => ({
},
opencode: {},
openclaw: {},
hermes: {},
});
const createDefaultCurrent = (): CurrentProviderState => ({
@@ -74,6 +75,7 @@ const createDefaultCurrent = (): CurrentProviderState => ({
gemini: "gemini-1",
opencode: "",
openclaw: "",
hermes: "",
});
let providers = createDefaultProviders();
@@ -81,6 +83,7 @@ let current = createDefaultCurrent();
let liveProviderIds: LiveProviderIdsByApp = {
opencode: [],
openclaw: [],
hermes: [],
};
let settingsState: Settings = {
showInTray: true,
@@ -153,6 +156,7 @@ let mcpConfigs: McpConfigState = {
gemini: false,
opencode: false,
openclaw: false,
hermes: false,
},
server: {
type: "stdio",
@@ -171,6 +175,7 @@ let mcpConfigs: McpConfigState = {
gemini: false,
opencode: false,
openclaw: false,
hermes: false,
},
server: {
type: "http",
@@ -181,6 +186,7 @@ let mcpConfigs: McpConfigState = {
gemini: {},
opencode: {},
openclaw: {},
hermes: {},
};
const cloneProviders = (value: ProvidersByApp) =>
@@ -192,6 +198,7 @@ export const resetProviderState = () => {
liveProviderIds = {
opencode: [],
openclaw: [],
hermes: [],
};
sessionsState = createDefaultSessions();
sessionMessagesState = createDefaultSessionMessages();
@@ -216,6 +223,7 @@ export const resetProviderState = () => {
gemini: false,
opencode: false,
openclaw: false,
hermes: false,
},
server: {
type: "stdio",
@@ -234,6 +242,7 @@ export const resetProviderState = () => {
gemini: false,
opencode: false,
openclaw: false,
hermes: false,
},
server: {
type: "http",
@@ -244,6 +253,7 @@ export const resetProviderState = () => {
gemini: {},
opencode: {},
openclaw: {},
hermes: {},
};
};
@@ -252,12 +262,12 @@ export const getProviders = (appType: AppId) =>
export const getCurrentProviderId = (appType: AppId) => current[appType] ?? "";
export const getLiveProviderIds = (appType: "opencode" | "openclaw") => [
export const getLiveProviderIds = (appType: "opencode" | "openclaw" | "hermes") => [
...liveProviderIds[appType],
];
export const setLiveProviderIds = (
appType: "opencode" | "openclaw",
appType: "opencode" | "openclaw" | "hermes",
ids: string[],
) => {
liveProviderIds[appType] = [...ids];