Refactor clawx (#344)

Co-authored-by: ashione <skyzlxuan@gmail.com>
This commit is contained in:
paisley
2026-03-09 13:10:42 +08:00
committed by GitHub
Unverified
parent 3d804a9f5e
commit 2c5c82bb74
75 changed files with 7640 additions and 3106 deletions

View File

@@ -3,8 +3,9 @@
* Manages skill/plugin state
*/
import { create } from 'zustand';
import { hostApiFetch } from '@/lib/host-api';
import { useGatewayStore } from './gateway';
import type { Skill, MarketplaceSkill } from '../types/skill';
import { invokeIpc } from '@/lib/api-client';
type GatewaySkillStatus = {
skillKey: string;
@@ -24,12 +25,6 @@ type GatewaySkillsStatusResult = {
skills?: GatewaySkillStatus[];
};
type GatewayRpcResponse<T> = {
success: boolean;
result?: T;
error?: string;
};
type ClawHubListResult = {
slug: string;
version?: string;
@@ -71,27 +66,20 @@ export const useSkillsStore = create<SkillsState>((set, get) => ({
}
try {
// 1. Fetch from Gateway (running skills)
const gatewayResult = await invokeIpc<GatewayRpcResponse<GatewaySkillsStatusResult>>(
'gateway:rpc',
'skills.status'
);
const gatewayData = await useGatewayStore.getState().rpc<GatewaySkillsStatusResult>('skills.status');
// 2. Fetch from ClawHub (installed on disk)
const clawhubResult = await invokeIpc<{ success: boolean; results?: ClawHubListResult[]; error?: string }>(
'clawhub:list'
);
const clawhubResult = await hostApiFetch<{ success: boolean; results?: ClawHubListResult[]; error?: string }>('/api/clawhub/list');
// 3. Fetch configurations directly from Electron (since Gateway doesn't return them)
const configResult = await invokeIpc<Record<string, { apiKey?: string; env?: Record<string, string> }>>(
'skill:getAllConfigs'
);
const configResult = await hostApiFetch<Record<string, { apiKey?: string; env?: Record<string, string> }>>('/api/skills/configs');
let combinedSkills: Skill[] = [];
const currentSkills = get().skills;
// Map gateway skills info
if (gatewayResult.success && gatewayResult.result?.skills) {
combinedSkills = gatewayResult.result.skills.map((s: GatewaySkillStatus) => {
if (gatewayData.skills) {
combinedSkills = gatewayData.skills.map((s: GatewaySkillStatus) => {
// Merge with direct config if available
const directConfig = configResult[s.skillKey] || {};
@@ -156,7 +144,10 @@ export const useSkillsStore = create<SkillsState>((set, get) => ({
searchSkills: async (query: string) => {
set({ searching: true, searchError: null });
try {
const result = await invokeIpc<{ success: boolean; results?: MarketplaceSkill[]; error?: string }>('clawhub:search', { query });
const result = await hostApiFetch<{ success: boolean; results?: MarketplaceSkill[]; error?: string }>('/api/clawhub/search', {
method: 'POST',
body: JSON.stringify({ query }),
});
if (result.success) {
set({ searchResults: result.results || [] });
} else {
@@ -178,7 +169,10 @@ export const useSkillsStore = create<SkillsState>((set, get) => ({
installSkill: async (slug: string, version?: string) => {
set((state) => ({ installing: { ...state.installing, [slug]: true } }));
try {
const result = await invokeIpc<{ success: boolean; error?: string }>('clawhub:install', { slug, version });
const result = await hostApiFetch<{ success: boolean; error?: string }>('/api/clawhub/install', {
method: 'POST',
body: JSON.stringify({ slug, version }),
});
if (!result.success) {
if (result.error?.includes('Timeout')) {
throw new Error('installTimeoutError');
@@ -205,7 +199,10 @@ export const useSkillsStore = create<SkillsState>((set, get) => ({
uninstallSkill: async (slug: string) => {
set((state) => ({ installing: { ...state.installing, [slug]: true } }));
try {
const result = await invokeIpc<{ success: boolean; error?: string }>('clawhub:uninstall', { slug });
const result = await hostApiFetch<{ success: boolean; error?: string }>('/api/clawhub/uninstall', {
method: 'POST',
body: JSON.stringify({ slug }),
});
if (!result.success) {
throw new Error(result.error || 'Uninstall failed');
}
@@ -227,17 +224,8 @@ export const useSkillsStore = create<SkillsState>((set, get) => ({
const { updateSkill } = get();
try {
const result = await invokeIpc<GatewayRpcResponse<unknown>>(
'gateway:rpc',
'skills.update',
{ skillKey: skillId, enabled: true }
);
if (result.success) {
updateSkill(skillId, { enabled: true });
} else {
throw new Error(result.error || 'Failed to enable skill');
}
await useGatewayStore.getState().rpc('skills.update', { skillKey: skillId, enabled: true });
updateSkill(skillId, { enabled: true });
} catch (error) {
console.error('Failed to enable skill:', error);
throw error;
@@ -253,17 +241,8 @@ export const useSkillsStore = create<SkillsState>((set, get) => ({
}
try {
const result = await invokeIpc<GatewayRpcResponse<unknown>>(
'gateway:rpc',
'skills.update',
{ skillKey: skillId, enabled: false }
);
if (result.success) {
updateSkill(skillId, { enabled: false });
} else {
throw new Error(result.error || 'Failed to disable skill');
}
await useGatewayStore.getState().rpc('skills.update', { skillKey: skillId, enabled: false });
updateSkill(skillId, { enabled: false });
} catch (error) {
console.error('Failed to disable skill:', error);
throw error;
@@ -279,4 +258,4 @@ export const useSkillsStore = create<SkillsState>((set, get) => ({
),
}));
},
}));
}));