import { useCanvasStore } from '../../stores/canvas' import { registerTool, unregisterTools } from '../webmcp' import { renderInlineComponent, componentsApi, type VueComponentDefinition } from '../dynamicComponents' export const COMPONENT_TOOLS = [ 'save_vue_component', 'load_vue_component', 'list_vue_components', 'delete_vue_component' ] function getCanvasContainer() { return document.getElementById('canvas-content') } function removePlaceholder(container: HTMLElement) { const placeholder = container.querySelector('.canvas-placeholder') if (placeholder) placeholder.remove() } export function registerComponentTools() { const canvasStore = useCanvasStore() // save_vue_component registerTool( 'save_vue_component', 'Guarda un componente Vue en la base de datos para reutilizarlo después', { type: 'object', properties: { id: { type: 'string', description: 'ID único del componente (se genera automáticamente si no se proporciona)' }, name: { type: 'string', description: 'Nombre del componente' }, template: { type: 'string', description: 'Template HTML del componente' }, setup: { type: 'string', description: 'Código de la función setup' }, style: { type: 'string', description: 'CSS del componente' }, props: { type: 'array', items: { type: 'string' }, description: 'Lista de props' }, imports: { type: 'array', items: { type: 'string' }, description: 'Funciones de Vue necesarias' } }, required: ['name', 'template'] }, async (args: Omit & { id?: string }) => { try { const result = await componentsApi.save({ id: args.id || `comp-${Date.now()}`, name: args.name, template: args.template, setup: args.setup, style: args.style, props: args.props, imports: args.imports }) canvasStore.addToHistory({ tool: 'save_vue_component', args, timestamp: Date.now() }) return `Componente "${args.name}" guardado con ID: ${result.id}` } catch (e: any) { return `Error al guardar: ${e.message}` } } ) // load_vue_component registerTool( 'load_vue_component', 'Carga un componente Vue guardado desde la base de datos y lo renderiza', { type: 'object', properties: { id: { type: 'string', description: 'ID del componente a cargar' }, componentProps: { type: 'object', description: 'Props para pasar al componente' }, mode: { type: 'string', enum: ['replace', 'append'], description: 'replace: limpia el canvas, append: agrega al final' } }, required: ['id'] }, async (args: { id: string; componentProps?: Record; mode?: string }) => { try { const definition = await componentsApi.getById(args.id) if (!definition) { return `Error: Componente con ID "${args.id}" no encontrado` } const container = getCanvasContainer() if (!container) return 'Error: canvas no encontrado' removePlaceholder(container) const isAppend = args.mode === 'append' const result = renderInlineComponent(definition, container, args.componentProps || {}, isAppend) ;(window as any).__vueComponentUnmount = result.unmount canvasStore.addToHistory({ tool: 'load_vue_component', args, timestamp: Date.now() }) return `Componente "${definition.name}" cargado y renderizado` } catch (e: any) { return `Error: ${e.message}` } } ) // list_vue_components registerTool( 'list_vue_components', 'Lista todos los componentes Vue guardados en la base de datos', { type: 'object', properties: {} }, async () => { try { const components = await componentsApi.getAll() if (components.length === 0) { return 'No hay componentes guardados' } const list = components.map(c => `- ${c.id}: ${c.name}`).join('\n') return `Componentes guardados:\n${list}` } catch (e: any) { return `Error: ${e.message}` } } ) // delete_vue_component registerTool( 'delete_vue_component', 'Elimina un componente Vue de la base de datos', { type: 'object', properties: { id: { type: 'string', description: 'ID del componente a eliminar' } }, required: ['id'] }, async (args: { id: string }) => { try { await componentsApi.delete(args.id) return `Componente "${args.id}" eliminado` } catch (e: any) { return `Error: ${e.message}` } } ) } export function unregisterComponentTools() { unregisterTools(COMPONENT_TOOLS) }