diff --git a/create-agentic-app/README.md b/create-agentic-app/README.md index 9cfbc23..739b001 100644 --- a/create-agentic-app/README.md +++ b/create-agentic-app/README.md @@ -16,6 +16,27 @@ Create a new project in a subdirectory: npx create-agentic-app@latest my-app ``` +### Non-Interactive Mode (for CI/CD and coding agents) + +All prompts can be bypassed with CLI flags, enabling fully automated project scaffolding: + +```bash +# Full non-interactive setup +npx create-agentic-app@latest my-app -y -p pnpm + +# Skip install and git init for faster scaffolding +npx create-agentic-app@latest my-app -y -p npm --skip-install --skip-git +``` + +#### Available Flags + +| Flag | Short | Description | +|------|-------|-------------| +| `--yes` | `-y` | Auto-confirm non-empty directory prompt | +| `--package-manager ` | `-p` | Package manager to use: `pnpm`, `npm`, or `yarn` | +| `--skip-install` | | Skip dependency installation | +| `--skip-git` | | Skip git repository initialization | + ## What's Included This starter kit includes: diff --git a/create-agentic-app/index.js b/create-agentic-app/index.js index d87b8f8..4c1b836 100644 --- a/create-agentic-app/index.js +++ b/create-agentic-app/index.js @@ -21,11 +21,24 @@ async function main() { .name('create-agentic-app') .description('Scaffold a new agentic AI application') .argument('[project-directory]', 'Project directory name (use "." for current directory)') + .option('-y, --yes', 'Auto-confirm non-empty directory prompt') + .option('-p, --package-manager ', 'Package manager to use: pnpm | npm | yarn') + .option('--skip-install', 'Skip dependency installation') + .option('--skip-git', 'Skip git repository initialization') .parse(process.argv); const args = program.args; + const opts = program.opts(); let projectDir = args[0] || '.'; + // Validate --package-manager value if provided + const validPackageManagers = ['pnpm', 'npm', 'yarn']; + if (opts.packageManager && !validPackageManagers.includes(opts.packageManager)) { + console.log(chalk.red(`Invalid package manager: "${opts.packageManager}"`)); + console.log(chalk.yellow(`Valid options: ${validPackageManagers.join(', ')}`)); + process.exit(1); + } + // Resolve the target directory const targetDir = path.resolve(process.cwd(), projectDir); const projectName = projectDir === '.' ? path.basename(targetDir) : projectDir; @@ -34,36 +47,46 @@ async function main() { if (fs.existsSync(targetDir)) { const files = fs.readdirSync(targetDir); if (files.length > 0 && projectDir !== '.') { - const { proceed } = await prompts({ - type: 'confirm', - name: 'proceed', - message: `Directory "${projectDir}" is not empty. Continue anyway?`, - initial: false - }); + if (opts.yes) { + console.log(chalk.yellow(`Directory "${projectDir}" is not empty. Proceeding (--yes).`)); + } else { + const { proceed } = await prompts({ + type: 'confirm', + name: 'proceed', + message: `Directory "${projectDir}" is not empty. Continue anyway?`, + initial: false + }); - if (!proceed) { - console.log(chalk.yellow('Cancelled.')); - process.exit(0); + if (!proceed) { + console.log(chalk.yellow('Cancelled.')); + process.exit(0); + } } } } - // Prompt for package manager - const { packageManager } = await prompts({ - type: 'select', - name: 'packageManager', - message: 'Which package manager do you want to use?', - choices: [ - { title: 'pnpm (recommended)', value: 'pnpm' }, - { title: 'npm', value: 'npm' }, - { title: 'yarn', value: 'yarn' } - ], - initial: 0 - }); + // Determine package manager + let packageManager; + if (opts.packageManager) { + packageManager = opts.packageManager; + } else { + const response = await prompts({ + type: 'select', + name: 'packageManager', + message: 'Which package manager do you want to use?', + choices: [ + { title: 'pnpm (recommended)', value: 'pnpm' }, + { title: 'npm', value: 'npm' }, + { title: 'yarn', value: 'yarn' } + ], + initial: 0 + }); + packageManager = response.packageManager; - if (!packageManager) { - console.log(chalk.yellow('Cancelled.')); - process.exit(0); + if (!packageManager) { + console.log(chalk.yellow('Cancelled.')); + process.exit(0); + } } console.log(); @@ -122,43 +145,51 @@ async function main() { spinner.succeed(chalk.green('Project created successfully!')); // Install dependencies - console.log(); - const installSpinner = ora(`Installing dependencies with ${packageManager}...`).start(); + if (opts.skipInstall) { + console.log(chalk.yellow('\nSkipping dependency installation (--skip-install).')); + } else { + console.log(); + const installSpinner = ora(`Installing dependencies with ${packageManager}...`).start(); - try { - const installCmd = packageManager === 'yarn' ? 'yarn install' : `${packageManager} install`; - execSync(installCmd, { - cwd: targetDir, - stdio: 'pipe' - }); - installSpinner.succeed(chalk.green('Dependencies installed!')); - } catch (error) { - installSpinner.fail(chalk.red('Failed to install dependencies')); - console.log(chalk.yellow(`\nPlease run "${packageManager} install" manually.\n`)); - } - - // Initialize Git repository - console.log(); - const gitSpinner = ora('Initializing Git repository...').start(); - - try { - // Check if git is available - execSync('git --version', { stdio: 'pipe' }); - - // Initialize git repo if not already initialized - if (!fs.existsSync(path.join(targetDir, '.git'))) { - execSync('git init', { cwd: targetDir, stdio: 'pipe' }); - execSync('git add .', { cwd: targetDir, stdio: 'pipe' }); - execSync('git commit -m "Initial commit from create-agentic-app"', { + try { + const installCmd = packageManager === 'yarn' ? 'yarn install' : `${packageManager} install`; + execSync(installCmd, { cwd: targetDir, stdio: 'pipe' }); - gitSpinner.succeed(chalk.green('Git repository initialized!')); - } else { - gitSpinner.info(chalk.blue('Git repository already exists')); + installSpinner.succeed(chalk.green('Dependencies installed!')); + } catch (error) { + installSpinner.fail(chalk.red('Failed to install dependencies')); + console.log(chalk.yellow(`\nPlease run "${packageManager} install" manually.\n`)); + } + } + + // Initialize Git repository + if (opts.skipGit) { + console.log(chalk.yellow('\nSkipping git initialization (--skip-git).')); + } else { + console.log(); + const gitSpinner = ora('Initializing Git repository...').start(); + + try { + // Check if git is available + execSync('git --version', { stdio: 'pipe' }); + + // Initialize git repo if not already initialized + if (!fs.existsSync(path.join(targetDir, '.git'))) { + execSync('git init', { cwd: targetDir, stdio: 'pipe' }); + execSync('git add .', { cwd: targetDir, stdio: 'pipe' }); + execSync('git commit -m "Initial commit from create-agentic-app"', { + cwd: targetDir, + stdio: 'pipe' + }); + gitSpinner.succeed(chalk.green('Git repository initialized!')); + } else { + gitSpinner.info(chalk.blue('Git repository already exists')); + } + } catch (error) { + gitSpinner.warn(chalk.yellow('Git not found - skipping repository initialization')); } - } catch (error) { - gitSpinner.warn(chalk.yellow('Git not found - skipping repository initialization')); } // Display next steps diff --git a/create-agentic-app/package-lock.json b/create-agentic-app/package-lock.json index 4c2dfc7..d95324a 100644 --- a/create-agentic-app/package-lock.json +++ b/create-agentic-app/package-lock.json @@ -1,12 +1,12 @@ { "name": "create-agentic-app", - "version": "1.1.46", + "version": "1.1.47", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "create-agentic-app", - "version": "1.1.46", + "version": "1.1.47", "license": "MIT", "dependencies": { "chalk": "^5.3.0", diff --git a/create-agentic-app/package.json b/create-agentic-app/package.json index 2f8f120..24a04b6 100644 --- a/create-agentic-app/package.json +++ b/create-agentic-app/package.json @@ -1,6 +1,6 @@ { "name": "create-agentic-app", - "version": "1.1.46", + "version": "1.1.47", "description": "Scaffold a new agentic AI application with Next.js, Better Auth, and AI SDK", "type": "module", "bin": {