/** * kernel-skills.ts - Skills API methods for KernelClient * * Installed onto KernelClient.prototype via installSkillMethods(). */ import { invoke } from '@tauri-apps/api/core'; import type { KernelClient } from './kernel-client'; import { useConversationStore } from '../store/chat/conversationStore'; /** Skill shape returned by list/refresh/create/update operations. */ type SkillItem = { id: string; name: string; description: string; version: string; capabilities: string[]; tags: string[]; mode: string; enabled: boolean; triggers: string[]; category?: string; }; /** Skill list container shared by list/refresh responses. */ type SkillListResult = { skills: SkillItem[] }; export function installSkillMethods(ClientClass: { prototype: KernelClient }): void { const proto = ClientClass.prototype as any; // ─── Skills API ─── /** * List all discovered skills */ proto.listSkills = async function (this: KernelClient): Promise { const skills = await invoke('skill_list'); return { skills: skills || [] }; }; /** * Refresh skills from directory */ proto.refreshSkills = async function (this: KernelClient, skillDir?: string): Promise { const skills = await invoke('skill_refresh', { skillDir: skillDir || null }); return { skills: skills || [] }; }; /** * Create a new skill */ proto.createSkill = async function (this: KernelClient, skill: { name: string; description?: string; triggers: Array<{ type: string; pattern?: string }>; actions: Array<{ type: string; params?: Record }>; enabled?: boolean; }): Promise<{ skill?: SkillItem }> { const result = await invoke('skill_create', { request: { name: skill.name, description: skill.description, triggers: skill.triggers.map(t => t.pattern || t.type), actions: skill.actions.map(a => a.type), enabled: skill.enabled, }, }); return { skill: result }; }; /** * Update an existing skill */ proto.updateSkill = async function (this: KernelClient, id: string, updates: { name?: string; description?: string; triggers?: Array<{ type: string; pattern?: string }>; actions?: Array<{ type: string; params?: Record }>; enabled?: boolean; }): Promise<{ skill?: SkillItem }> { const result = await invoke('skill_update', { id, request: { name: updates.name, description: updates.description, triggers: updates.triggers?.map(t => t.pattern || t.type), actions: updates.actions?.map(a => a.type), enabled: updates.enabled, }, }); return { skill: result }; }; /** * Delete a skill */ proto.deleteSkill = async function (this: KernelClient, id: string): Promise { await invoke('skill_delete', { id }); }; /** * Execute a skill by ID with optional input parameters. * Checks autonomy level before execution. */ proto.executeSkill = async function (this: KernelClient, id: string, input?: Record): Promise<{ success: boolean; output?: unknown; error?: string; durationMs?: number; }> { const convStore = useConversationStore.getState(); const agent = convStore.currentAgent; const sessionKey = convStore.sessionKey; return invoke('skill_execute', { id, context: { agentId: agent?.id || 'zclaw-main', sessionId: sessionKey || crypto.randomUUID(), workingDir: null, }, input: input || {}, }); }; }