UNPKG

@nestbox-ai/cli

Version:

The cli tools that helps developers to build agents

159 lines (139 loc) 5.89 kB
import { Command } from "commander"; import chalk from "chalk"; import ora from "ora"; import fs from "fs"; import { createNestboxConfig, } from "../../utils/agent"; import { generateWithPlop, listAvailableTemplates } from "../../utils/plopGenerator"; import { isValidFunctionName } from "../../utils/validation"; import inquirer from "inquirer"; import path from "path"; export function registerProjectCommand(generateCommand: Command): void { generateCommand .command("project <folder>") .description("Generate a new project from templates") .option("--lang <language>", "Project language (ts|js)") .option("--template <type>", "Template type (agent|chatbot)") .option("--name <agentName>", "Agent/Chatbot name (must be a valid function name)") .option("--project <projectId>", "Project ID") .action(async (folder, options) => { try { const spinner = ora("Initializing project generation...").start(); // Ensure target folder doesn't exist if (fs.existsSync(folder)) { spinner.fail(`Folder ${folder} already exists`); return; } let selectedLang = options.lang; let selectedTemplate = options.template; let agentName = options.name; // Interactive selection if not provided if (!selectedLang || !selectedTemplate) { spinner.stop(); const answers = await inquirer.prompt([ { type: 'list', name: 'lang', message: 'Select project language:', choices: [ { name: 'TypeScript', value: 'ts' }, { name: 'JavaScript', value: 'js' } ], when: () => !selectedLang }, { type: 'list', name: 'template', message: 'Select template type:', choices: [ { name: 'Agent', value: 'agent' }, { name: 'Chatbot', value: 'chatbot' } ], when: () => !selectedTemplate }, { type: 'input', name: 'agentName', message: 'Enter agent/chatbot name (must be a valid function name):', when: () => !agentName, default: (answers: any) => { const type = selectedTemplate || answers.template; return type === 'agent' ? 'myAgent' : 'myChatbot'; }, validate: (input: string) => { if (!input.trim()) { return 'Agent name cannot be empty'; } if (!isValidFunctionName(input.trim())) { return 'Must be a valid function name (e.g., myAgent, chatBot123, my_agent)'; } return true; } } ]); selectedLang = selectedLang || answers.lang; selectedTemplate = selectedTemplate || answers.template; agentName = agentName || answers.agentName; spinner.start("Generating project..."); } // Validate agent name if provided via CLI option if (agentName && !isValidFunctionName(agentName)) { spinner.fail(`Invalid agent name: "${agentName}". Must be a valid function name (e.g., myAgent, chatBot123, my_agent)`); return; } // Set default agent name if not provided if (!agentName) { agentName = selectedTemplate === 'agent' ? 'myAgent' : 'myChatbot'; } // Find matching template in local templates folder const templateMapping: Record<string, string> = { 'agent': 'base', 'chatbot': 'chatbot' }; const mappedTemplateType = templateMapping[selectedTemplate] || selectedTemplate; // Check if template directory exists const templatePath = path.resolve(__dirname, `../../../../templates/${mappedTemplateType}-${selectedLang}`); if (!fs.existsSync(templatePath)) { spinner.fail(`Template not found: ${templatePath}`); // Show available templates const availableTemplates = listAvailableTemplates(); if (availableTemplates.length > 0) { console.log(chalk.yellow('Available templates:')); availableTemplates.forEach(template => { console.log(chalk.yellow(` - ${template}`)); }); } else { console.log(chalk.red('No templates found. Please add your templates to the templates directory.')); } return; } spinner.text = `Generating ${mappedTemplateType} project in ${folder}...`; try { // Generate project using plop await generateWithPlop(selectedTemplate, selectedLang, folder, path.basename(folder), agentName); // Create nestbox.config.json for TypeScript projects createNestboxConfig(folder, selectedLang === 'ts'); spinner.succeed(`Successfully generated ${mappedTemplateType} project in ${folder}`); console.log(chalk.green("\nNext steps:")); console.log(chalk.yellow(` cd ${folder}`)); console.log(chalk.yellow(" npm install")); if (selectedLang === 'ts') { console.log(chalk.yellow(" npm run build")); } console.log(chalk.yellow(" nestbox agent deploy --agent <agent-name> --instance <instance-name>")); } catch (error) { // Clean up on error if (fs.existsSync(folder)) { fs.rmSync(folder, { recursive: true, force: true }); } throw error; } } catch (error: any) { console.error( chalk.red("Error:"), error.message || "Failed to generate project" ); } }); }