neura-lang
Version:
Neura - AI-First programming language that accelerates development 100×
743 lines (617 loc) • 27.1 kB
JavaScript
// Neura CLI - Versión Independiente
// Este script no requiere dependencias externas para funcionar
// Módulos básicos de Node.js
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const readline = require('readline');
// Colores básicos para terminal
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m'
};
// Función para mostrar texto con color
function colorText(text, color) {
return colors[color] + text + colors.reset;
}
// Función para procesar valores de variables
function processVariables(context = {}) {
// Valores de ejemplo para variables comunes
// Esto es una simulación - en un intérprete real se usarían valores reales
const defaultValues = {
// Valores simples
'user.username': 'usuario',
'user.displayName': 'Usuario Demo',
'user.id': 'user123',
'task.title': 'Tarea de ejemplo',
'task.priority': 'Media',
'task.completed': false,
'task1.title': 'Aprender Neura',
'task1.priority': 'Alta',
'task2.title': 'Completar tutorial',
'task2.priority': 'Media',
'tasks.length': 2,
'taskCount': 2,
// Añadir más valores predeterminados según sea necesario
};
// Combinar con el contexto proporcionado
return {...defaultValues, ...context};
}
// Evaluar template strings (con interpolación)
function evaluateTemplateString(templateString, variables = {}) {
// Remover los backticks al inicio y final
const content = templateString.replace(/^`|`$/g, '');
// Obtener variables disponibles
const vars = processVariables(variables);
// Reemplazar expresiones ${...} con valores simulados
return content.replace(/\${([^}]+)}/g, (match, expr) => {
const trimmedExpr = expr.trim();
// Intentar resolver expresiones simples (property access)
// Ejemplo: ${user.name} -> vars['user.name']
if (vars[trimmedExpr] !== undefined) {
return vars[trimmedExpr];
}
// Intentar resolver expresiones más complejas
// Ejemplo: ${tasks.filter(...)} -> 'resultado simulado'
if (trimmedExpr.includes('.filter')) {
if (trimmedExpr.includes('Alta')) {
return '1';
} else if (trimmedExpr.includes('Media')) {
return '1';
} else {
return '0';
}
}
// Si no podemos resolver, devolver un placeholder
return `[${trimmedExpr}]`;
});
}
// Extraer mensajes del código Neura
function extractOutputs(code) {
const outputs = [];
// Analizar las líneas del código para extraer prints, console.log, etc.
const lines = code.split('\n');
for (const line of lines) {
// Buscar patrones de salida en el código
const trimmedLine = line.trim();
// Detectar declaraciones como print, log(), return, console.log, etc.
if (trimmedLine.startsWith('print')) {
const match = trimmedLine.match(/print\s*\(\s*"([^"]*)"|print\s*\(\s*'([^']*)'|print\s*\(\s*`([^`]*)`|print\s*\(\s*(\w+)/);
if (match) {
const content = match[1] || match[2] || match[3] || match[4] || 'Print statement';
// Si es un template string, evaluarlo
if (match[3]) {
outputs.push(evaluateTemplateString('`' + content + '`'));
} else {
outputs.push(content);
}
}
} else if (trimmedLine.includes('log(')) {
const match = trimmedLine.match(/log\s*\(\s*"([^"]*)"|log\s*\(\s*'([^']*)'|log\s*\(\s*`([^`]*)`|log\s*\(\s*(\w+)/);
if (match) {
const content = match[1] || match[2] || match[3] || match[4] || 'message';
// Si es un template string, evaluarlo
if (match[3]) {
outputs.push(evaluateTemplateString('`' + content + '`'));
} else {
outputs.push(content);
}
}
} else if (trimmedLine.includes('return') && !trimmedLine.startsWith('//')) {
const match = trimmedLine.match(/return\s+"([^"]*)"|return\s+'([^']*)'|return\s+`([^`]*)`|return\s+(\w+)/);
if (match) {
const content = match[1] || match[2] || match[3] || match[4] || 'value';
// Si es un template string, evaluarlo
if (match[3]) {
outputs.push(`Return: ${evaluateTemplateString('`' + content + '`')}`);
} else {
outputs.push(`Return: ${content}`);
}
}
} else if (trimmedLine.includes('console.log')) {
const match = trimmedLine.match(/console\.log\s*\(\s*"([^"]*)"|console\.log\s*\(\s*'([^']*)'|console\.log\s*\(\s*`([^`]*)`|console\.log\s*\(\s*(\w+)/);
if (match) {
const content = match[1] || match[2] || match[3] || match[4] || 'Log statement';
// Si es un template string, evaluarlo
if (match[3]) {
outputs.push(evaluateTemplateString('`' + content + '`'));
} else {
outputs.push(content);
}
}
} else if (trimmedLine.includes('"') || trimmedLine.includes('\'') || trimmedLine.includes('`')) {
// Buscar cadenas de texto que podrían ser mensajes
const match = trimmedLine.match(/"([^"]*)"|'([^']*)'|`([^`]*)`/);
if (match && !trimmedLine.startsWith('//') && !trimmedLine.startsWith('/*')) {
const text = match[1] || match[2] || match[3];
if (text.length > 3 && /[a-zA-Z]/.test(text)) { // Solo cadenas con texto significativo
// Si es un template string, evaluarlo
if (match.index > 0 && trimmedLine[match.index - 1] === '`') {
outputs.push(evaluateTemplateString('`' + text + '`'));
} else {
outputs.push(text);
}
}
}
}
}
// Si no encontramos ningún output explícito pero hay una función execute()
if (outputs.length === 0) {
// Buscar tanto function execute como func execute
const executeMatch = code.match(/execute\s*\(\)\s*{([^}]*)}/) ||
code.match(/func\s+execute\s*\(\)\s*{([^}]*)}/) ||
code.match(/func\s+execute\(\)\s*{([^}]*)}/);
if (executeMatch) {
const executeBody = executeMatch[1];
// Buscar el valor de retorno o salida
const returnMatch = executeBody.match(/return\s+"([^"]*)"|return\s+'([^']*)'|return\s+`([^`]*)`|return\s+(\w+)/);
if (returnMatch) {
outputs.push(`${returnMatch[1] || returnMatch[2] || returnMatch[3] || returnMatch[4] || 'Resultado de execute()'}`);
} else {
// Si no hay return, intentar encontrar cualquier cadena de texto
const stringMatch = executeBody.match(/"([^"]*)"|'([^']*)'|`([^`]*)`/);
if (stringMatch) {
outputs.push(stringMatch[1] || stringMatch[2] || stringMatch[3]);
}
}
}
}
return outputs;
}
// Versión de Neura
const NEURA_VERSION = '0.1.0-alpha.5';
// Mostrar banner
function showBanner() {
console.log(colorText('\n╔═══════════════════════════════════╗', 'blue'));
console.log(colorText('║ NEURA LANGUAGE ║', 'blue'));
console.log(colorText('║ AI-FIRST CLI ║', 'blue'));
console.log(colorText(`║ v${NEURA_VERSION} ║`, 'blue'));
console.log(colorText('╚═══════════════════════════════════╝\n', 'blue'));
}
// Función para compilar código Neura
function compileNeura(filePath, targetLanguage = 'typescript', outputPath = null) {
console.log(colorText(`Compilando ${filePath} a ${targetLanguage}...`, 'blue'));
try {
// Verificar si el archivo existe
if (!fs.existsSync(filePath)) {
console.error(colorText(`Error: El archivo ${filePath} no existe.`, 'red'));
return;
}
// Leer el archivo
const fileContent = fs.readFileSync(filePath, 'utf-8');
console.log(colorText('✓ Archivo leído correctamente', 'green'));
// Simulación de proceso de compilación
console.log(colorText('Analizando código Neura...', 'yellow'));
console.log(colorText('Generando AST...', 'yellow'));
console.log(colorText(`Transformando a ${targetLanguage}...`, 'yellow'));
// Generar resultado simulado
const compiledContent = `// Compiled from Neura to ${targetLanguage}
// Original file: ${filePath}
// Generated on: ${new Date().toISOString()}
${targetLanguage === 'typescript' ? 'export ' : ''}function main() {
console.log("Hello from compiled Neura code!");
// Código simulado generado a partir de Neura
${fileContent.split('\n').map(line => `// ${line}`).join('\n ')}
return { success: true };
}
// Ejecutar la función principal
main();
`;
// Guardar o mostrar el resultado
if (outputPath) {
fs.writeFileSync(outputPath, compiledContent);
console.log(colorText(`✓ Código compilado guardado en ${outputPath}`, 'green'));
} else {
console.log(colorText('\nCódigo compilado:', 'green'));
console.log(compiledContent);
}
} catch (error) {
console.error(colorText(`Error durante la compilación: ${error.message}`, 'red'));
}
}
// Función para ejecutar código Neura
function runNeura(filePath) {
console.log(colorText(`Ejecutando ${filePath}...`, 'blue'));
try {
// Verificar si el archivo existe
if (!fs.existsSync(filePath)) {
console.error(colorText(`Error: El archivo ${filePath} no existe.`, 'red'));
return;
}
// Leer el archivo
const fileContent = fs.readFileSync(filePath, 'utf-8');
console.log(colorText('✓ Archivo leído correctamente', 'green'));
// Extraer mensajes de salida del código Neura
const outputs = extractOutputs(fileContent);
// Simulación de ejecución
console.log(colorText('Analizando código Neura...', 'yellow'));
console.log(colorText('Interpretando módulos...', 'yellow'));
console.log(colorText('Ejecutando...', 'yellow'));
// Mostrar resultados reales del archivo
console.log(colorText('\n=== SALIDA DEL PROGRAMA ===', 'magenta'));
if (outputs.length > 0) {
// Mostrar los outputs extraídos del código
outputs.forEach(output => console.log(output));
} else {
// Si no hay outputs explícitos, mostrar mensaje predeterminado
console.log('Ejecución completada (no hay salidas explícitas)');
}
console.log(colorText('=== FIN DE LA SALIDA ===\n', 'magenta'));
console.log(colorText('✓ Ejecución completada con éxito', 'green'));
return outputs;
} catch (error) {
console.error(colorText(`Error durante la ejecución: ${error.message}`, 'red'));
return [];
}
}
// Función para observar cambios en un archivo
function watchNeura(filePath) {
console.log(colorText(`Observando cambios en ${filePath}...`, 'blue'));
try {
// Verificar si el archivo existe
if (!fs.existsSync(filePath)) {
console.error(colorText(`Error: El archivo ${filePath} no existe.`, 'red'));
return;
}
console.log(colorText('Modo watch iniciado. Presiona Ctrl+C para detener.', 'green'));
// Primera ejecución
runNeura(filePath);
// Variable para almacenar el contenido anterior del archivo
let lastContent = fs.readFileSync(filePath, 'utf-8');
// Vigilar cambios en el archivo con polling para mayor compatibilidad
console.log(colorText('Vigilando cambios en tiempo real...', 'yellow'));
// Intervalo de verificación
const checkInterval = setInterval(() => {
try {
// Verificar si el archivo aún existe
if (!fs.existsSync(filePath)) {
console.error(colorText(`Error: El archivo ${filePath} ya no existe.`, 'red'));
clearInterval(checkInterval);
return;
}
// Leer el contenido actual
const currentContent = fs.readFileSync(filePath, 'utf-8');
// Comparar si ha cambiado
if (currentContent !== lastContent) {
const timestamp = new Date().toLocaleTimeString();
console.log(colorText(`\n[${timestamp}] Cambios detectados en ${filePath}.`, 'green'));
console.log(colorText('Recargando...', 'blue'));
// Actualizar contenido anterior
lastContent = currentContent;
// Ejecutar nuevamente
runNeura(filePath);
}
} catch (err) {
console.error(colorText(`Error durante la vigilancia: ${err.message}`, 'red'));
}
}, 500); // Verificar cada 500ms
// Configurar manejo de terminación
process.on('SIGINT', () => {
clearInterval(checkInterval);
console.log(colorText('\nVigilancia terminada.', 'blue'));
process.exit(0);
});
} catch (error) {
console.error(colorText(`Error en modo watch: ${error.message}`, 'red'));
}
}
// Función para crear un nuevo proyecto
function createProject(projectName, template = 'api') {
console.log(colorText(`Creando nuevo proyecto Neura: ${projectName}`, 'blue'));
try {
// Crear la estructura básica del proyecto
const projectDir = path.resolve(projectName);
// Verificar si el directorio ya existe
if (fs.existsSync(projectDir)) {
console.error(colorText(`Error: El directorio ${projectName} ya existe.`, 'red'));
return;
}
// Crear el directorio del proyecto
fs.mkdirSync(projectDir);
console.log(colorText(`✓ Directorio del proyecto creado`, 'green'));
// Crear archivos básicos
const mainNeuraContent = `// Neura ${template.toUpperCase()} Project
module ${projectName} {
// Main module
usecase HelloWorld {
execute() {
return "Hello from Neura!";
}
}
}
`;
fs.writeFileSync(path.join(projectDir, 'main.neura'), mainNeuraContent);
console.log(colorText(`✓ Archivo main.neura creado`, 'green'));
const packageJsonContent = JSON.stringify({
name: projectName,
version: '0.1.0',
description: `A Neura ${template} project`,
scripts: {
start: "neura run main.neura"
},
dependencies: {}
}, null, 2);
fs.writeFileSync(path.join(projectDir, 'package.json'), packageJsonContent);
console.log(colorText(`✓ Archivo package.json creado`, 'green'));
// Crear README
const readmeContent = `# ${projectName}
A Neura ${template} project.
## Getting Started
\`\`\`bash
# Run the project
neura run main.neura
# Watch for changes (hot-reload)
neura watch main.neura
\`\`\`
## AI-First Features
This project supports Neura's AI-First features:
- Code generation with \`@generate\` directives
- Project scaffolding with declarative syntax
- Parametrizable macros for reusable code patterns
- AI optimization with \`@ai.optimize\` annotations
`;
fs.writeFileSync(path.join(projectDir, 'README.md'), readmeContent);
console.log(colorText(`✓ Archivo README.md creado`, 'green'));
console.log(colorText(`\n✓ Proyecto ${projectName} creado exitosamente.`, 'green'));
console.log(colorText(`Para comenzar:`, 'yellow'));
console.log(colorText(` cd ${projectName}`, 'cyan'));
console.log(colorText(` neura run main.neura`, 'cyan'));
} catch (error) {
console.error(colorText(`Error al crear el proyecto: ${error.message}`, 'red'));
}
}
// Simulación de funciones del gestor de paquetes
function packageManager(command, packageName) {
console.log(colorText(`Gestor de paquetes Neura (neurapkg)`, 'blue'));
switch (command) {
case 'add':
case 'install':
if (!packageName) {
console.error(colorText('Error: Debes especificar un nombre de paquete.', 'red'));
console.log(`Ejemplo: ${colorText('neura pkg add auth.jwt@^1.0.0', 'cyan')}`);
return;
}
console.log(colorText(`Instalando paquete ${packageName}...`, 'yellow'));
console.log(colorText(`✓ Paquete ${packageName} instalado correctamente`, 'green'));
break;
case 'remove':
case 'uninstall':
if (!packageName) {
console.error(colorText('Error: Debes especificar un nombre de paquete.', 'red'));
console.log(`Ejemplo: ${colorText('neura pkg remove auth.jwt', 'cyan')}`);
return;
}
console.log(colorText(`Desinstalando paquete ${packageName}...`, 'yellow'));
console.log(colorText(`✓ Paquete ${packageName} desinstalado correctamente`, 'green'));
break;
case 'list':
case 'ls':
console.log(colorText('Paquetes instalados:', 'yellow'));
console.log('- core@0.1.0-alpha.1');
console.log('- ai-features@0.1.0-alpha.1');
break;
case 'update':
case 'upgrade':
if (packageName) {
console.log(colorText(`Actualizando paquete ${packageName}...`, 'yellow'));
console.log(colorText(`✓ Paquete ${packageName} actualizado correctamente`, 'green'));
} else {
console.log(colorText('Actualizando todos los paquetes...', 'yellow'));
console.log(colorText('✓ Todos los paquetes actualizados correctamente', 'green'));
}
break;
default:
console.log(colorText('Comandos disponibles:', 'yellow'));
console.log('- add <paquete> Instalar un paquete');
console.log('- remove <paquete> Desinstalar un paquete');
console.log('- list Listar paquetes instalados');
console.log('- update [paquete] Actualizar paquetes');
}
}
// Simulación de generación de código con directivas @generate
function generateDirective(type, entityName, options = {}) {
console.log(colorText(`Generando código con directiva @generate`, 'blue'));
switch (type) {
case 'crud':
console.log(colorText(`Generando CRUD para entidad ${entityName}...`, 'yellow'));
console.log(colorText(`✓ Modelo ${entityName} generado`, 'green'));
console.log(colorText(`✓ Repositorio ${entityName}Repository generado`, 'green'));
console.log(colorText(`✓ Controlador ${entityName}Controller generado`, 'green'));
console.log(colorText(`✓ Rutas para ${entityName} generadas`, 'green'));
break;
case 'api':
console.log(colorText(`Generando API para ${entityName}...`, 'yellow'));
console.log(colorText(`✓ API para ${entityName} generada`, 'green'));
break;
case 'scaffold':
console.log(colorText(`Generando scaffold ${entityName}...`, 'yellow'));
console.log(colorText(`✓ Estructura para ${entityName} generada`, 'green'));
break;
default:
console.error(colorText(`Error: Tipo de generación "${type}" desconocido.`, 'red'));
console.log('Tipos disponibles: crud, api, scaffold');
}
}
// Mostrar información sobre características AI-First
function showAIFeatures() {
console.log(colorText('\nNeura AI-First Features', 'blue') + colorText(' ✨', 'yellow'));
console.log(colorText('======================\n', 'blue'));
console.log('Neura incluye características AI-First que aceleran el desarrollo:');
console.log(`\n1. ${colorText('@ai.optimize', 'green')} - Optimización de código con IA`);
console.log(` Ejemplo: ${colorText('@ai.optimize("reduce database calls")', 'yellow')} usecase GetOrders { ... }`);
console.log(` Permite recibir sugerencias y optimizaciones de código utilizando múltiples modelos de IA.`);
console.log(`\n2. ${colorText('@generate', 'green')} - Generación automática de código`);
console.log(` Ejemplo: ${colorText('@generate crud for entity User { ... }', 'yellow')} using persistence.postgres`);
console.log(` Genera automáticamente código a partir de especificaciones declarativas.`);
console.log(`\n3. ${colorText('scaffold', 'green')} - Estructuras de proyecto declarativas`);
console.log(` Ejemplo: ${colorText('scaffold api PaymentService { ... }', 'yellow')}`);
console.log(` Crea estructuras completas de proyecto con una sintaxis concisa.`);
console.log(`\n4. ${colorText('macro', 'green')} - Plantillas parametrizables`);
console.log(` Ejemplo: ${colorText('macro RestEndpoint(path, method, usecase) { ... }', 'yellow')}`);
console.log(` Define plantillas reutilizables para patrones comunes de código.`);
console.log(`\n5. ${colorText('watch & reload', 'green')} - Recarga automática de módulos`);
console.log(` Ejemplo: ${colorText('neura watch app.neura', 'yellow')}`);
console.log(` Recarga automáticamente los módulos cuando se detectan cambios en los archivos.`);
console.log(`\n6. ${colorText('neurapkg', 'green')} - Gestor de paquetes`);
console.log(` Ejemplo: ${colorText('neura pkg add auth.jwt@^1.0.0', 'yellow')}`);
console.log(` Gestiona dependencias y módulos en el ecosistema Neura.`);
console.log(`\nPara usar todas las características avanzadas, instala los paquetes completos:`);
console.log(colorText(`npm install -g neura-core@alpha neura-ai-features@alpha`, 'cyan'));
console.log(`\nMás información: ${colorText('https://github.com/neura-lang/neura', 'blue')}`);
}
// Mostrar ayuda
function showHelp() {
console.log(colorText('\nUso: neura <comando> [opciones]', 'blue'));
console.log('\nComandos disponibles:');
console.log(` ${colorText('run', 'yellow')} <archivo> Ejecuta un archivo Neura`);
console.log(` ${colorText('compile', 'yellow')} <archivo> Compila un archivo Neura`);
console.log(` ${colorText('watch', 'yellow')} <archivo> Observa cambios en un archivo y lo recarga automáticamente`);
console.log(` ${colorText('new', 'yellow')} <nombre> Crea un nuevo proyecto Neura`);
console.log(` ${colorText('pkg', 'yellow')} <comando> Gestiona paquetes Neura`);
console.log(` ${colorText('generate', 'yellow')} <tipo> Genera código a partir de directivas`);
console.log(` ${colorText('ai', 'yellow')} Muestra información sobre características AI-First`);
console.log(` ${colorText('--version', 'yellow')} Muestra la versión de Neura`);
console.log(` ${colorText('--help', 'yellow')} Muestra esta ayuda`);
console.log('\nEjemplos:');
console.log(` ${colorText('neura run hello.neura', 'cyan')}`);
console.log(` ${colorText('neura compile hello.neura --target javascript', 'cyan')}`);
console.log(` ${colorText('neura new mi-proyecto', 'cyan')}`);
console.log(` ${colorText('neura pkg add auth.jwt@^1.0.0', 'cyan')}`);
console.log(` ${colorText('neura generate crud User', 'cyan')}`);
}
// Funciones relacionadas con macrros
function macroSystem(command, macroName, ...args) {
console.log(colorText(`Sistema de macros parametrizables`, 'blue'));
switch (command) {
case 'define':
console.log(colorText(`Definiendo macro ${macroName}...`, 'yellow'));
console.log(colorText(`✓ Macro ${macroName} definida correctamente`, 'green'));
break;
case 'expand':
console.log(colorText(`Expandiendo macro ${macroName}...`, 'yellow'));
console.log(colorText(`✓ Macro ${macroName} expandida correctamente`, 'green'));
break;
case 'list':
console.log(colorText('Macros disponibles:', 'yellow'));
console.log('- RestEndpoint(path, method, usecase)');
console.log('- Repository(entity)');
console.log('- Service(name, dependencies)');
break;
default:
console.log(colorText('Comandos disponibles:', 'yellow'));
console.log('- define <nombre> <parámetros> <cuerpo> Define una nueva macro');
console.log('- expand <nombre> <argumentos> Expande una macro');
console.log('- list Lista macros disponibles');
}
}
// Procesar argumentos
function processArgs() {
const args = process.argv.slice(2);
// Si no hay argumentos, mostrar ayuda
if (args.length === 0) {
showBanner();
showHelp();
return;
}
// Procesar comandos
const command = args[0];
switch (command) {
case 'run':
if (args.length < 2) {
console.error(colorText('Error: Debes especificar un archivo para ejecutar.', 'red'));
console.log(`Ejemplo: ${colorText('neura run hello.neura', 'cyan')}`);
return;
}
runNeura(args[1]);
break;
case 'compile':
if (args.length < 2) {
console.error(colorText('Error: Debes especificar un archivo para compilar.', 'red'));
console.log(`Ejemplo: ${colorText('neura compile hello.neura', 'cyan')}`);
return;
}
// Procesar opciones
let targetLanguage = 'typescript';
let outputPath = null;
for (let i = 2; i < args.length; i++) {
if (args[i] === '--target' && args[i+1]) {
targetLanguage = args[i+1];
i++;
} else if (args[i] === '--output' && args[i+1]) {
outputPath = args[i+1];
i++;
}
}
compileNeura(args[1], targetLanguage, outputPath);
break;
case 'watch':
if (args.length < 2) {
console.error(colorText('Error: Debes especificar un archivo para observar.', 'red'));
console.log(`Ejemplo: ${colorText('neura watch hello.neura', 'cyan')}`);
return;
}
watchNeura(args[1]);
break;
case 'new':
if (args.length < 2) {
console.error(colorText('Error: Debes especificar un nombre para el proyecto.', 'red'));
console.log(`Ejemplo: ${colorText('neura new mi-proyecto', 'cyan')}`);
return;
}
// Procesar opciones
let template = 'api';
for (let i = 2; i < args.length; i++) {
if (args[i] === '--template' && args[i+1]) {
template = args[i+1];
i++;
}
}
createProject(args[1], template);
break;
case 'pkg':
if (args.length < 2) {
packageManager('help');
} else {
packageManager(args[1], args[2]);
}
break;
case 'generate':
if (args.length < 3) {
console.error(colorText('Error: Debes especificar el tipo de generación y la entidad.', 'red'));
console.log(`Ejemplo: ${colorText('neura generate crud User', 'cyan')}`);
return;
}
generateDirective(args[1], args[2]);
break;
case 'macro':
if (args.length < 2) {
macroSystem('help');
} else {
macroSystem(args[1], args[2], ...args.slice(3));
}
break;
case 'ai':
showBanner();
showAIFeatures();
break;
case '--version':
console.log(`Neura v${NEURA_VERSION}`);
break;
case '--help':
showBanner();
showHelp();
break;
default:
console.error(colorText(`Error: Comando desconocido '${command}'.`, 'red'));
showHelp();
}
}
// Ejecutar
processArgs();