npx command
This commit is contained in:
155
create-agentic-app/index.js
Normal file
155
create-agentic-app/index.js
Normal file
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { program } from 'commander';
|
||||
import chalk from 'chalk';
|
||||
import prompts from 'prompts';
|
||||
import ora from 'ora';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { execSync } from 'child_process';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const TEMPLATE_DIR = path.join(__dirname, 'template');
|
||||
|
||||
async function main() {
|
||||
console.log(chalk.bold.cyan('\n🤖 Create Agentic App\n'));
|
||||
|
||||
program
|
||||
.name('create-agentic-app')
|
||||
.description('Scaffold a new agentic AI application')
|
||||
.argument('[project-directory]', 'Project directory name (use "." for current directory)')
|
||||
.parse(process.argv);
|
||||
|
||||
const args = program.args;
|
||||
let projectDir = args[0] || '.';
|
||||
|
||||
// Resolve the target directory
|
||||
const targetDir = path.resolve(process.cwd(), projectDir);
|
||||
const projectName = projectDir === '.' ? path.basename(targetDir) : projectDir;
|
||||
|
||||
// Check if directory exists and is not empty
|
||||
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 (!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
|
||||
});
|
||||
|
||||
if (!packageManager) {
|
||||
console.log(chalk.yellow('Cancelled.'));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
console.log();
|
||||
const spinner = ora('Creating project...').start();
|
||||
|
||||
try {
|
||||
// Create target directory if it doesn't exist
|
||||
fs.ensureDirSync(targetDir);
|
||||
|
||||
// Copy template files
|
||||
spinner.text = 'Copying template files...';
|
||||
await fs.copy(TEMPLATE_DIR, targetDir, {
|
||||
overwrite: false,
|
||||
errorOnExist: false,
|
||||
filter: (src) => {
|
||||
// Skip node_modules, .next, and other build artifacts
|
||||
const relativePath = path.relative(TEMPLATE_DIR, src);
|
||||
return !relativePath.includes('node_modules') &&
|
||||
!relativePath.includes('.next') &&
|
||||
!relativePath.includes('.git') &&
|
||||
!relativePath.includes('pnpm-lock.yaml') &&
|
||||
!relativePath.includes('package-lock.json') &&
|
||||
!relativePath.includes('yarn.lock') &&
|
||||
!relativePath.includes('tsconfig.tsbuildinfo');
|
||||
}
|
||||
});
|
||||
|
||||
// Copy .env.example to .env if it doesn't exist
|
||||
const envExamplePath = path.join(targetDir, 'env.example');
|
||||
const envPath = path.join(targetDir, '.env');
|
||||
|
||||
if (fs.existsSync(envExamplePath) && !fs.existsSync(envPath)) {
|
||||
spinner.text = 'Setting up environment file...';
|
||||
await fs.copy(envExamplePath, envPath);
|
||||
}
|
||||
|
||||
// Update package.json name if not current directory
|
||||
if (projectDir !== '.') {
|
||||
const packageJsonPath = path.join(targetDir, 'package.json');
|
||||
if (fs.existsSync(packageJsonPath)) {
|
||||
const packageJson = await fs.readJson(packageJsonPath);
|
||||
packageJson.name = projectName;
|
||||
await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
|
||||
}
|
||||
}
|
||||
|
||||
spinner.succeed(chalk.green('Project created successfully!'));
|
||||
|
||||
// Install dependencies
|
||||
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`));
|
||||
}
|
||||
|
||||
// Display next steps
|
||||
console.log();
|
||||
console.log(chalk.bold.green('✨ Your agentic app is ready!\n'));
|
||||
console.log(chalk.bold('Next steps:\n'));
|
||||
|
||||
if (projectDir !== '.') {
|
||||
console.log(chalk.cyan(` cd ${projectDir}`));
|
||||
}
|
||||
|
||||
console.log(chalk.cyan(' 1. Update the .env file with your API keys and database credentials'));
|
||||
console.log(chalk.cyan(` 2. Start the database: docker compose up -d`));
|
||||
console.log(chalk.cyan(` 3. Run database migrations: ${packageManager} run db:migrate`));
|
||||
console.log(chalk.cyan(` 4. Start the development server: ${packageManager} run dev`));
|
||||
|
||||
console.log();
|
||||
console.log(chalk.gray('For more information, check out the README.md file.\n'));
|
||||
|
||||
} catch (error) {
|
||||
spinner.fail(chalk.red('Failed to create project'));
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
Reference in New Issue
Block a user