feat(omo): add OMO Slim (oh-my-opencode-slim) support

Implement full OMO Slim profile management to align with ai-toolbox:
- Backend: Slim service methods, DAO, Tauri commands, plugin conflict handling
- Frontend: types, API, query hooks, form integration with isSlim parameterization
- Slim variant: 6 agents (no categories), separate config file and plugin name
- Mutual exclusion: standard OMO and Slim cannot coexist as plugins
- i18n: zh/en/ja translations for all Slim agent descriptions
This commit is contained in:
Jason
2026-02-19 20:47:55 +08:00
parent 51476953ae
commit 8e219b5eb1
26 changed files with 1176 additions and 165 deletions
+100 -1
View File
@@ -1,5 +1,5 @@
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { omoApi } from "@/lib/api/omo";
import { omoApi, omoSlimApi } from "@/lib/api/omo";
import * as configApi from "@/lib/api/config";
import type { OmoGlobalConfig } from "@/types/omo";
@@ -93,3 +93,102 @@ export function useDisableCurrentOmo() {
onSuccess: () => invalidateOmoQueries(queryClient),
});
}
// ============================================================================
// OMO Slim query hooks
// ============================================================================
export const omoSlimKeys = {
all: ["omo-slim"] as const,
globalConfig: () => [...omoSlimKeys.all, "global-config"] as const,
currentProviderId: () => [...omoSlimKeys.all, "current-provider-id"] as const,
providerCount: () => [...omoSlimKeys.all, "provider-count"] as const,
};
function invalidateOmoSlimQueries(
queryClient: ReturnType<typeof useQueryClient>,
) {
queryClient.invalidateQueries({ queryKey: omoSlimKeys.globalConfig() });
queryClient.invalidateQueries({ queryKey: ["providers"] });
queryClient.invalidateQueries({
queryKey: omoSlimKeys.currentProviderId(),
});
queryClient.invalidateQueries({ queryKey: omoSlimKeys.providerCount() });
}
export function useOmoSlimGlobalConfig(enabled = true) {
return useQuery({
queryKey: omoSlimKeys.globalConfig(),
enabled,
queryFn: async (): Promise<OmoGlobalConfig> => {
const raw = await configApi.getCommonConfigSnippet("omo_slim");
if (!raw) {
return {
id: "global",
disabledAgents: [],
disabledMcps: [],
disabledHooks: [],
disabledSkills: [],
updatedAt: new Date().toISOString(),
};
}
try {
return JSON.parse(raw) as OmoGlobalConfig;
} catch (error) {
console.warn(
"[omo-slim] invalid global config json, fallback to defaults",
error,
);
return {
id: "global",
disabledAgents: [],
disabledMcps: [],
disabledHooks: [],
disabledSkills: [],
updatedAt: new Date().toISOString(),
};
}
},
});
}
export function useCurrentOmoSlimProviderId(enabled = true) {
return useQuery({
queryKey: omoSlimKeys.currentProviderId(),
queryFn: omoSlimApi.getCurrentProviderId,
enabled,
});
}
export function useOmoSlimProviderCount(enabled = true) {
return useQuery({
queryKey: omoSlimKeys.providerCount(),
queryFn: omoSlimApi.getProviderCount,
enabled,
});
}
export function useSaveOmoSlimGlobalConfig() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (input: OmoGlobalConfig) => {
const jsonStr = JSON.stringify(input);
await configApi.setCommonConfigSnippet("omo_slim", jsonStr);
},
onSuccess: () => invalidateOmoSlimQueries(queryClient),
});
}
export function useReadOmoSlimLocalFile() {
return useMutation({
mutationFn: () => omoSlimApi.readLocalFile(),
});
}
export function useDisableCurrentOmoSlim() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: () => omoSlimApi.disableCurrent(),
onSuccess: () => invalidateOmoSlimQueries(queryClient),
});
}