UNPKG

@idealyst/cli

Version:

CLI tool for generating Idealyst Framework projects

515 lines • 25.6 kB
#!/usr/bin/env node "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const commander_1 = require("commander"); const chalk_1 = __importDefault(require("chalk")); const fs = __importStar(require("fs")); const path = __importStar(require("path")); const index_1 = require("./generators/index"); const utils_1 = require("./generators/utils"); const program = new commander_1.Command(); program .name('idealyst') .description('CLI tool for generating Idealyst Framework projects') .version('1.0.1'); program .command('init [project-name]') .description('Initialize a new full-stack Idealyst workspace with all packages') .option('-d, --directory <directory>', 'Output directory', '.') .option('--figma-token <token>', 'Figma personal access token for integration') .option('--skip-install', 'Skip installing dependencies') .action(async (projectName, options) => { try { // Prompt for project name if not provided if (!projectName) { projectName = await (0, utils_1.promptForProjectName)(); } else { // Validate provided project name const { validateProjectName } = await Promise.resolve().then(() => __importStar(require('./generators/utils'))); if (!validateProjectName(projectName.toLowerCase())) { console.error(chalk_1.default.red(`Invalid project name: ${projectName}`)); console.error(chalk_1.default.yellow('Project name must be a valid npm package name (lowercase, no spaces)')); process.exit(1); } projectName = projectName.toLowerCase(); } await (0, index_1.generateProject)({ name: projectName, type: 'fullstack', directory: options.directory, skipInstall: options.skipInstall || false, figmaToken: options.figmaToken }); console.log(''); console.log(chalk_1.default.green(`šŸŽ‰ Full-stack workspace created successfully!`)); console.log(chalk_1.default.blue(`šŸ“ Project created in: ${options.directory}/${projectName}`)); console.log(''); console.log(chalk_1.default.yellow('šŸš€ Next steps:')); console.log(chalk_1.default.white(` cd ${projectName}`)); console.log(chalk_1.default.white(' yarn dev # Start all development servers')); console.log(chalk_1.default.white(' yarn web:dev # Start web app only')); console.log(chalk_1.default.white(' yarn mobile:start # Start mobile app')); console.log(''); } catch (error) { console.error(chalk_1.default.red('āŒ Failed to create project:')); console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error))); process.exit(1); } }); program .command('create [project-name]') .description('Create a new individual Idealyst project (for existing workspaces)') .option('-t, --type <type>', 'Project type: native, web, shared, api, or database') .option('-d, --directory <directory>', 'Output directory', '.') .option('-a, --app-name <app-name>', 'Display name for native apps (e.g., "My Awesome App")') .option('--with-trpc', 'Include tRPC boilerplate and setup (for web/native projects)') .option('--skip-install', 'Skip installing dependencies') .action(async (projectName, options) => { try { // Prompt for project name if not provided if (!projectName) { projectName = await (0, utils_1.promptForProjectName)(); } else { // Validate provided project name const { validateProjectName } = await Promise.resolve().then(() => __importStar(require('./generators/utils'))); if (!validateProjectName(projectName.toLowerCase())) { console.error(chalk_1.default.red(`Invalid project name: ${projectName}`)); console.error(chalk_1.default.yellow('Project name must be a valid npm package name (lowercase, no spaces)')); process.exit(1); } projectName = projectName.toLowerCase(); } // Prompt for project type if not provided let projectType = options.type; if (!projectType) { projectType = await (0, utils_1.promptForProjectType)(); } const validTypes = ['native', 'web', 'shared', 'api', 'database']; if (!validTypes.includes(projectType)) { console.error(chalk_1.default.red(`Invalid project type: ${projectType}`)); console.error(chalk_1.default.yellow(`Valid types are: ${validTypes.join(', ')}`)); process.exit(1); } // Prompt for app name if it's a native project and app name not provided let appName = options.appName; if (projectType === 'native' && !appName) { appName = await (0, utils_1.promptForAppName)(projectName); } // Prompt for tRPC integration if it's a web/native project and flag not provided let withTrpc = options.withTrpc; if ((projectType === 'web' || projectType === 'native') && withTrpc === undefined) { withTrpc = await (0, utils_1.promptForTrpcIntegration)(); } await (0, index_1.generateProject)({ name: projectName, type: projectType, directory: options.directory, skipInstall: options.skipInstall || false, appName, withTrpc: withTrpc || false }); console.log(chalk_1.default.green(`✨ Successfully created ${projectName}!`)); console.log(chalk_1.default.blue(`šŸ“ Project created in: ${options.directory}/packages/${projectName}`)); if (projectType === 'native') { console.log(chalk_1.default.yellow('\nšŸ“± Next steps for React Native:')); console.log(chalk_1.default.white(' cd packages/' + projectName)); console.log(chalk_1.default.white(' yarn android # or yarn ios')); } else if (projectType === 'web') { console.log(chalk_1.default.yellow('\n🌐 Next steps for React Web:')); console.log(chalk_1.default.white(' cd packages/' + projectName)); console.log(chalk_1.default.white(' yarn dev')); } else if (projectType === 'api') { console.log(chalk_1.default.yellow('\nšŸš€ Next steps for API Server:')); console.log(chalk_1.default.white(' cd packages/' + projectName)); console.log(chalk_1.default.white(' yarn dev # Start development server')); console.log(chalk_1.default.white(' yarn build # Build for production')); } else if (projectType === 'database') { console.log(chalk_1.default.yellow('\nšŸ—„ļø Next steps for Database:')); console.log(chalk_1.default.white(' cd packages/' + projectName)); console.log(chalk_1.default.white(' yarn db:generate # Generate Prisma client')); console.log(chalk_1.default.white(' yarn db:push # Push database schema')); console.log(chalk_1.default.white(' yarn db:studio # Open Prisma Studio')); console.log(chalk_1.default.white(' yarn build # Build for export to other packages')); } else { console.log(chalk_1.default.yellow('\nšŸ“¦ Next steps for Shared Library:')); console.log(chalk_1.default.white(' cd packages/' + projectName)); console.log(chalk_1.default.white(' yarn build')); } } catch (error) { console.error(chalk_1.default.red('āŒ Error creating project:'), error); process.exit(1); } }); program .command('init [project-name]') .description('Initialize a new Idealyst monorepo workspace') .option('-d, --directory <directory>', 'Output directory', '.') .option('--skip-install', 'Skip installing dependencies') .option('--figma-token <token>', 'Figma personal access token (enables figma-developer-mcp server)') .action(async (projectName, options) => { try { // Prompt for project name if not provided if (!projectName) { projectName = await (0, utils_1.promptForProjectName)(); } else { // Validate provided project name const { validateProjectName } = await Promise.resolve().then(() => __importStar(require('./generators/utils'))); if (!validateProjectName(projectName.toLowerCase())) { console.error(chalk_1.default.red(`Invalid project name: ${projectName}`)); console.error(chalk_1.default.yellow('Project name must be a valid npm package name (lowercase, no spaces)')); process.exit(1); } projectName = projectName.toLowerCase(); } await (0, index_1.generateProject)({ name: projectName, type: 'workspace', directory: options.directory, skipInstall: options.skipInstall || false, figmaToken: options.figmaToken }); console.log(chalk_1.default.green('✨ Successfully initialized Idealyst workspace!')); console.log(chalk_1.default.blue(`šŸ“ Workspace created in: ${options.directory}/${projectName}`)); console.log(chalk_1.default.yellow('\nšŸš€ Next steps:')); console.log(chalk_1.default.white(` cd ${projectName}`)); console.log(chalk_1.default.white(' idealyst create my-app --type native')); console.log(chalk_1.default.white(' idealyst create my-web-app --type web')); } catch (error) { console.error(chalk_1.default.red('āŒ Error initializing workspace:'), error); process.exit(1); } }); // LLM Reference Data Structure function getLLMReference() { return { overview: { description: "The Idealyst Framework CLI is a powerful tool for generating TypeScript monorepo projects with React Native, React Web, API servers, database layers, and shared libraries.", warning: "āš ļø CRITICAL: Always provide ALL required arguments to avoid interactive prompts that can hang automated processes!" }, safeCommands: { workspace: { command: "idealyst init <workspace-name>", description: "Create a new monorepo workspace", example: "idealyst init my-awesome-project" }, database: { command: "idealyst create <name> --type database", description: "Create standalone database package with Prisma + Zod", example: "idealyst create user-db --type database" }, api: { command: "idealyst create <name> --type api", description: "Create API server with Express + tRPC (no database)", example: "idealyst create user-api --type api" }, shared: { command: "idealyst create <name> --type shared", description: "Create shared utilities and types package", example: "idealyst create common-utils --type shared" }, web: { command: "idealyst create <name> --type web --with-trpc|--no-trpc", description: "Create React web app with Vite", examples: [ "idealyst create web-app --type web --with-trpc", "idealyst create web-app --type web --no-trpc" ] }, native: { command: "idealyst create <name> --type native --app-name \"Name\" --with-trpc|--no-trpc", description: "Create React Native app", examples: [ "idealyst create mobile-app --type native --app-name \"My App\" --with-trpc", "idealyst create mobile-app --type native --app-name \"My App\" --no-trpc" ] } }, dangerousCommands: [ { command: "idealyst init", issue: "Missing workspace name - will prompt interactively" }, { command: "idealyst create my-app", issue: "Missing --type parameter - will prompt interactively" }, { command: "idealyst create my-app --type web", issue: "Missing tRPC choice - will prompt interactively" }, { command: "idealyst create my-app --type native", issue: "Missing --app-name and tRPC choice - will prompt interactively" } ], projectTypes: { workspace: "Monorepo setup with Yarn workspaces", database: "Prisma + Zod schemas (standalone, no API)", api: "Express + tRPC server (no database included)", shared: "Shared utilities and types", web: "React web app with Vite", native: "React Native app" }, architecture: { database: "Export: { db, schemas, PrismaClient, types }", api: "Consume database packages as dependencies", typescript: "All projects use strict TypeScript", monorepo: "Yarn workspaces for dependency management" } }; } function generateTextReference(reference) { const lines = []; lines.push('šŸ¤– IDEALYST CLI - COMPLETE LLM REFERENCE'); lines.push('='.repeat(50)); lines.push(''); lines.push(reference.overview.description); lines.push(''); lines.push(reference.overview.warning); lines.push(''); lines.push('āœ… LLM-SAFE COMMANDS:'); lines.push('-'.repeat(25)); Object.entries(reference.safeCommands).forEach(([key, cmd]) => { lines.push(`\n${key.toUpperCase()}:`); lines.push(` Command: ${cmd.command}`); lines.push(` Description: ${cmd.description}`); if (cmd.example) { lines.push(` Example: ${cmd.example}`); } if (cmd.examples) { lines.push(` Examples:`); cmd.examples.forEach((ex) => lines.push(` ${ex}`)); } }); lines.push('\nāŒ DANGEROUS COMMANDS (WILL HANG):'); lines.push('-'.repeat(35)); reference.dangerousCommands.forEach((cmd) => { lines.push(` ${cmd.command}`); lines.push(` Issue: ${cmd.issue}`); }); lines.push('\nšŸ“‹ PROJECT TYPES:'); lines.push('-'.repeat(20)); Object.entries(reference.projectTypes).forEach(([type, desc]) => { lines.push(` ${type}: ${desc}`); }); lines.push('\nšŸ—ļø ARCHITECTURE:'); lines.push('-'.repeat(18)); Object.entries(reference.architecture).forEach(([key, desc]) => { lines.push(` ${key}: ${desc}`); }); return lines.join('\n'); } function generateMarkdownReference(reference) { const lines = []; lines.push('# Idealyst CLI - LLM Reference'); lines.push(''); lines.push(reference.overview.description); lines.push(''); lines.push(`> ${reference.overview.warning}`); lines.push(''); lines.push('## āœ… LLM-Safe Commands'); lines.push(''); Object.entries(reference.safeCommands).forEach(([key, cmd]) => { lines.push(`### ${key.charAt(0).toUpperCase() + key.slice(1)}`); lines.push(''); lines.push('```bash'); lines.push(cmd.command); lines.push('```'); lines.push(''); lines.push(cmd.description); lines.push(''); if (cmd.example) { lines.push('**Example:**'); lines.push('```bash'); lines.push(cmd.example); lines.push('```'); lines.push(''); } if (cmd.examples) { lines.push('**Examples:**'); lines.push('```bash'); cmd.examples.forEach((ex) => lines.push(ex)); lines.push('```'); lines.push(''); } }); lines.push('## āŒ Dangerous Commands'); lines.push(''); lines.push('These commands will hang by prompting for user input:'); lines.push(''); reference.dangerousCommands.forEach((cmd) => { lines.push(`- \`${cmd.command}\` - ${cmd.issue}`); }); lines.push(''); lines.push('## šŸ“‹ Project Types'); lines.push(''); Object.entries(reference.projectTypes).forEach(([type, desc]) => { lines.push(`- **${type}**: ${desc}`); }); lines.push(''); lines.push('## šŸ—ļø Architecture'); lines.push(''); Object.entries(reference.architecture).forEach(([key, desc]) => { lines.push(`- **${key}**: ${desc}`); }); return lines.join('\n'); } program .command('llm-commands') .description('Display only safe LLM command templates') .action(() => { const reference = getLLMReference(); console.log(chalk_1.default.yellow('āš ļø Always provide ALL required arguments!\n')); Object.entries(reference.safeCommands).forEach(([key, cmd]) => { console.log(chalk_1.default.cyan(cmd.command)); if (cmd.examples) { cmd.examples.forEach((ex) => console.log(chalk_1.default.cyan(ex))); } }); }); program .command('llm-info') .description('Display LLM access methods and available formats') .action(() => { console.log(chalk_1.default.blue.bold('šŸ¤– LLM Access Methods for Idealyst CLI\n')); console.log(chalk_1.default.green('Available Commands:')); console.log(chalk_1.default.white(' idealyst llm-help ') + chalk_1.default.gray('- Quick reference with safe commands')); console.log(chalk_1.default.white(' idealyst llm-commands ') + chalk_1.default.gray('- Just the command templates')); console.log(chalk_1.default.white(' idealyst llm-reference ') + chalk_1.default.gray('- Complete reference (text format)')); console.log(chalk_1.default.white(' idealyst llm-reference --format json ') + chalk_1.default.gray('- Machine-readable JSON')); console.log(chalk_1.default.white(' idealyst llm-reference --format markdown ') + chalk_1.default.gray('- Generated markdown')); console.log(chalk_1.default.white(' idealyst llm-reference --format file ') + chalk_1.default.gray('- Full markdown documentation\n')); console.log(chalk_1.default.yellow('āš ļø Critical for LLMs:')); console.log(chalk_1.default.red(' • Never use commands without required arguments')); console.log(chalk_1.default.red(' • Always specify --type for create commands')); console.log(chalk_1.default.red(' • Always specify --app-name for native projects')); console.log(chalk_1.default.red(' • Always specify --with-trpc or --no-trpc for web/native\n')); console.log(chalk_1.default.blue('šŸ“– Documentation:')); console.log(chalk_1.default.white(' • Built-in: Use commands above')); console.log(chalk_1.default.white(' • Files: docs/LLM-CLI-REFERENCE.md (comprehensive)')); console.log(chalk_1.default.white(' • Files: docs/LLM-CLI-QUICK-REFERENCE.md (condensed)')); }); program .command('llm-reference') .description('Display complete LLM reference documentation') .option('--format <format>', 'Output format: text, json, markdown, or file', 'text') .action((options) => { const reference = getLLMReference(); switch (options.format) { case 'json': console.log(JSON.stringify(reference, null, 2)); break; case 'markdown': console.log(generateMarkdownReference(reference)); break; case 'file': // Try to read the markdown file from docs const docsPath = path.join(__dirname, '..', 'docs', 'LLM-CLI-REFERENCE.md'); try { if (fs.existsSync(docsPath)) { const content = fs.readFileSync(docsPath, 'utf8'); console.log(content); } else { console.log(chalk_1.default.yellow('āš ļø Docs file not found, generating markdown instead:')); console.log(generateMarkdownReference(reference)); } } catch (error) { console.log(chalk_1.default.yellow('āš ļø Error reading docs file, generating markdown instead:')); console.log(generateMarkdownReference(reference)); } break; default: console.log(generateTextReference(reference)); } }); program .command('llm-help') .description('Display quick LLM-friendly CLI reference') .action(() => { console.log(chalk_1.default.blue.bold('šŸ¤– Idealyst CLI - LLM Quick Reference\n')); console.log(chalk_1.default.yellow('āš ļø CRITICAL: Always provide ALL required arguments to avoid interactive prompts!\n')); console.log(chalk_1.default.green.bold('āœ… LLM-Safe Commands:\n')); console.log(chalk_1.default.white('šŸ“ Initialize Workspace:')); console.log(chalk_1.default.cyan(' idealyst init <workspace-name>\n')); console.log(chalk_1.default.white('šŸ“¦ Create Projects (No extra args needed):')); console.log(chalk_1.default.cyan(' idealyst create <name> --type database')); console.log(chalk_1.default.cyan(' idealyst create <name> --type api')); console.log(chalk_1.default.cyan(' idealyst create <name> --type shared\n')); console.log(chalk_1.default.white('🌐 Create Web Projects (tRPC choice required):')); console.log(chalk_1.default.cyan(' idealyst create <name> --type web --with-trpc')); console.log(chalk_1.default.cyan(' idealyst create <name> --type web --no-trpc\n')); console.log(chalk_1.default.white('šŸ“± Create Native Projects (app-name + tRPC required):')); console.log(chalk_1.default.cyan(' idealyst create <name> --type native --app-name "Display Name" --with-trpc')); console.log(chalk_1.default.cyan(' idealyst create <name> --type native --app-name "Display Name" --no-trpc\n')); console.log(chalk_1.default.red.bold('āŒ Commands That Will Hang LLMs:\n')); console.log(chalk_1.default.red(' idealyst init # Missing name')); console.log(chalk_1.default.red(' idealyst create my-app # Missing --type')); console.log(chalk_1.default.red(' idealyst create my-app --type web # Missing tRPC choice')); console.log(chalk_1.default.red(' idealyst create my-app --type native # Missing --app-name + tRPC\n')); console.log(chalk_1.default.blue('šŸ“‹ Project Types:')); console.log(chalk_1.default.white(' • workspace - Monorepo setup with Yarn workspaces')); console.log(chalk_1.default.white(' • database - Prisma + Zod schemas (new standalone type)')); console.log(chalk_1.default.white(' • api - Express + tRPC server (no database included)')); console.log(chalk_1.default.white(' • shared - Shared utilities and types')); console.log(chalk_1.default.white(' • web - React web app with Vite')); console.log(chalk_1.default.white(' • native - React Native app\n')); console.log(chalk_1.default.magenta('šŸ”— Key Architecture:')); console.log(chalk_1.default.white(' • Database packages export: { db, schemas, PrismaClient, types }')); console.log(chalk_1.default.white(' • API packages consume database packages as dependencies')); console.log(chalk_1.default.white(' • All projects are TypeScript with strict type safety')); console.log(chalk_1.default.white(' • Monorepo uses Yarn workspaces for dependency management\n')); console.log(chalk_1.default.green('šŸ“– For complete documentation:')); console.log(chalk_1.default.cyan(' idealyst llm-reference')); console.log(chalk_1.default.cyan(' idealyst llm-reference --format markdown')); console.log(chalk_1.default.cyan(' idealyst llm-reference --format json')); }); program.parse(); //# sourceMappingURL=index.js.map