UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

333 lines 13.5 kB
/** * WASM Agent CLI Subcommands * * Exposes @ruvector/rvagent-wasm operations via the `agent` CLI command. * Wraps functions from ruvector/agent-wasm.ts for CLI usage. */ import { output } from '../output.js'; const WASM_NOT_AVAILABLE_MSG = '@ruvector/rvagent-wasm is not installed.\n' + 'Install it with: npm install @ruvector/rvagent-wasm'; async function loadWasm() { const mod = await import('../ruvector/agent-wasm.js'); return mod; } // agent wasm-status export const wasmStatusCommand = { name: 'wasm-status', description: 'Check rvagent-wasm availability, version, and capabilities', options: [], examples: [ { command: 'claude-flow agent wasm-status', description: 'Check WASM agent runtime status' }, ], action: async (ctx) => { try { const wasm = await loadWasm(); const available = await wasm.isAgentWasmAvailable(); if (!available) { output.writeln(); output.printWarning(WASM_NOT_AVAILABLE_MSG); if (ctx.flags.format === 'json') { output.printJson({ available: false }); } return { success: true, data: { available: false } }; } // Init to get full status await wasm.initAgentWasm(); const agents = wasm.listWasmAgents(); let galleryCount = 0; let categories = {}; try { galleryCount = await wasm.getGalleryCount(); categories = await wasm.getGalleryCategories(); } catch { // Gallery may not be available in all builds } const statusData = { available: true, activeAgents: agents.length, gallery: { templates: galleryCount, categories, }, tools: ['read_file', 'write_file', 'edit_file', 'write_todos', 'list_files'], features: ['sandboxed-execution', 'virtual-filesystem', 'gallery-templates', 'rvf-containers', 'mcp-bridge'], }; if (ctx.flags.format === 'json') { output.printJson(statusData); return { success: true, data: statusData }; } output.writeln(); output.writeln(output.bold('WASM Agent Runtime')); output.writeln(); output.printTable({ columns: [ { key: 'property', header: 'Property', width: 20 }, { key: 'value', header: 'Value', width: 40 }, ], data: [ { property: 'Available', value: output.success('yes') }, { property: 'Active Agents', value: String(agents.length) }, { property: 'Gallery Templates', value: String(galleryCount) }, { property: 'Sandbox Tools', value: statusData.tools.join(', ') }, { property: 'Features', value: statusData.features.join(', ') }, ], }); if (Object.keys(categories).length > 0) { output.writeln(); output.writeln(output.bold('Gallery Categories')); output.printTable({ columns: [ { key: 'category', header: 'Category', width: 20 }, { key: 'count', header: 'Templates', width: 10, align: 'right' }, ], data: Object.entries(categories).map(([category, count]) => ({ category, count })), }); } return { success: true, data: statusData }; } catch (error) { output.printError(`WASM status check failed: ${String(error)}`); return { success: false, exitCode: 1 }; } }, }; // agent wasm-create export const wasmCreateCommand = { name: 'wasm-create', description: 'Create a WASM-sandboxed agent', options: [ { name: 'template', short: 't', description: 'Gallery template (coder, researcher, tester, reviewer, security, swarm)', type: 'string', }, { name: 'model', short: 'm', description: 'Model identifier (default: anthropic:claude-sonnet-4-6)', type: 'string', }, { name: 'instructions', short: 'i', description: 'System instructions for the agent', type: 'string', }, { name: 'max-turns', description: 'Maximum conversation turns (default: 50)', type: 'number', default: 50, }, ], examples: [ { command: 'claude-flow agent wasm-create', description: 'Create a default WASM agent' }, { command: 'claude-flow agent wasm-create -t coder', description: 'Create from gallery template' }, { command: 'claude-flow agent wasm-create -m "anthropic:claude-sonnet-4-6" -i "You are a security auditor"', description: 'Create with custom config' }, ], action: async (ctx) => { try { const wasm = await loadWasm(); const available = await wasm.isAgentWasmAvailable(); if (!available) { output.printError(WASM_NOT_AVAILABLE_MSG); return { success: false, exitCode: 1 }; } const template = ctx.flags.template; let info; if (template) { output.printInfo(`Creating WASM agent from template: ${output.highlight(template)}`); info = await wasm.createAgentFromTemplate(template); } else { output.printInfo('Creating WASM agent...'); info = await wasm.createWasmAgent({ model: ctx.flags.model, instructions: ctx.flags.instructions, maxTurns: ctx.flags['max-turns'], }); } if (ctx.flags.format === 'json') { output.printJson({ success: true, agent: info, source: template ? 'gallery' : 'custom' }); return { success: true, data: info }; } output.writeln(); output.printTable({ columns: [ { key: 'property', header: 'Property', width: 15 }, { key: 'value', header: 'Value', width: 45 }, ], data: [ { property: 'ID', value: info.id }, { property: 'State', value: info.state }, { property: 'Model', value: info.model }, { property: 'Turn Count', value: String(info.turnCount) }, { property: 'File Count', value: String(info.fileCount) }, { property: 'Created', value: info.createdAt }, ...(template ? [{ property: 'Template', value: template }] : []), ], }); output.writeln(); output.printSuccess(`WASM agent created: ${info.id}`); return { success: true, data: info }; } catch (error) { output.printError(`Failed to create WASM agent: ${String(error)}`); return { success: false, exitCode: 1 }; } }, }; // agent wasm-prompt export const wasmPromptCommand = { name: 'wasm-prompt', description: 'Send a prompt to a WASM agent', options: [ { name: 'agent-id', short: 'a', description: 'WASM agent ID (required)', type: 'string', }, { name: 'input', short: 'i', description: 'Prompt text to send', type: 'string', }, ], examples: [ { command: 'claude-flow agent wasm-prompt -a wasm-agent-1-abc -i "Write a hello world"', description: 'Send prompt to WASM agent' }, ], action: async (ctx) => { const agentId = ctx.flags['agent-id'] || ctx.args[0]; const promptInput = ctx.flags.input || ctx.args[1]; if (!agentId) { output.printError('Agent ID is required. Use --agent-id or -a'); return { success: false, exitCode: 1 }; } if (!promptInput) { output.printError('Prompt input is required. Use --input or -i'); return { success: false, exitCode: 1 }; } try { const wasm = await loadWasm(); const available = await wasm.isAgentWasmAvailable(); if (!available) { output.printError(WASM_NOT_AVAILABLE_MSG); return { success: false, exitCode: 1 }; } output.printInfo(`Sending prompt to ${output.highlight(agentId)}...`); const result = await wasm.promptWasmAgent(agentId, promptInput); if (ctx.flags.format === 'json') { output.printJson({ agentId, response: result }); return { success: true, data: { agentId, response: result } }; } output.writeln(); output.writeln(output.bold('Response')); output.writeln(); output.writeln(result); // Show updated agent info const info = wasm.getWasmAgent(agentId); if (info) { output.writeln(); output.writeln(output.dim(`[turns: ${info.turnCount}, files: ${info.fileCount}, state: ${info.state}]`)); } return { success: true, data: { agentId, response: result } }; } catch (error) { output.printError(`Prompt failed: ${String(error)}`); return { success: false, exitCode: 1 }; } }, }; // agent wasm-gallery export const wasmGalleryCommand = { name: 'wasm-gallery', description: 'List available WASM agent gallery templates', options: [ { name: 'search', short: 's', description: 'Search templates by query', type: 'string', }, { name: 'category', short: 'c', description: 'Filter by category', type: 'string', }, ], examples: [ { command: 'claude-flow agent wasm-gallery', description: 'List all gallery templates' }, { command: 'claude-flow agent wasm-gallery -s coder', description: 'Search gallery templates' }, ], action: async (ctx) => { try { const wasm = await loadWasm(); const available = await wasm.isAgentWasmAvailable(); if (!available) { output.printError(WASM_NOT_AVAILABLE_MSG); return { success: false, exitCode: 1 }; } const searchQuery = ctx.flags.search; const category = ctx.flags.category; let templates; if (searchQuery) { output.printInfo(`Searching gallery for: ${output.highlight(searchQuery)}`); templates = await wasm.searchGalleryTemplates(searchQuery); } else { templates = await wasm.listGalleryTemplates(); } // Filter by category if specified if (category) { templates = templates.filter((t) => t.category.toLowerCase() === category.toLowerCase()); } if (ctx.flags.format === 'json') { output.printJson({ templates, count: templates.length }); return { success: true, data: { templates, count: templates.length } }; } output.writeln(); output.writeln(output.bold('WASM Agent Gallery')); output.writeln(); if (templates.length === 0) { output.printInfo('No templates found matching criteria'); return { success: true, data: { templates: [], count: 0 } }; } output.printTable({ columns: [ { key: 'id', header: 'ID', width: 20 }, { key: 'name', header: 'Name', width: 18 }, { key: 'category', header: 'Category', width: 12 }, { key: 'description', header: 'Description', width: 35 }, { key: 'version', header: 'Version', width: 10 }, ], data: templates.map((t) => ({ id: t.id, name: t.name, category: t.category, description: t.description.length > 35 ? t.description.slice(0, 32) + '...' : t.description, version: t.version, })), }); output.writeln(); output.printInfo(`${templates.length} template(s) found. Create with: agent wasm-create -t <id>`); return { success: true, data: { templates, count: templates.length } }; } catch (error) { output.printError(`Gallery listing failed: ${String(error)}`); return { success: false, exitCode: 1 }; } }, }; /** All WASM subcommands for the agent command */ export const wasmSubcommands = [ wasmStatusCommand, wasmCreateCommand, wasmPromptCommand, wasmGalleryCommand, ]; //# sourceMappingURL=agent-wasm.js.map