Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:04:14 +08:00
commit 70c36b5eff
248 changed files with 47482 additions and 0 deletions

View File

@@ -0,0 +1,259 @@
/**
* Autocomplete Prompt Template
*
* Use for: Large option lists with search
* Features: Type-ahead, fuzzy matching, suggestions
*
* Note: Requires inquirer-autocomplete-prompt plugin
* Install: npm install inquirer-autocomplete-prompt
*/
import inquirer from 'inquirer';
import inquirerAutocomplete from 'inquirer-autocomplete-prompt';
// Register the autocomplete prompt type
inquirer.registerPrompt('autocomplete', inquirerAutocomplete);
// Example: Countries list for autocomplete
const countries = [
'Afghanistan', 'Albania', 'Algeria', 'Andorra', 'Angola',
'Argentina', 'Armenia', 'Australia', 'Austria', 'Azerbaijan',
'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', 'Belarus',
'Belgium', 'Belize', 'Benin', 'Bhutan', 'Bolivia',
'Brazil', 'Brunei', 'Bulgaria', 'Burkina Faso', 'Burundi',
'Cambodia', 'Cameroon', 'Canada', 'Cape Verde', 'Chad',
'Chile', 'China', 'Colombia', 'Comoros', 'Congo',
'Costa Rica', 'Croatia', 'Cuba', 'Cyprus', 'Czech Republic',
'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic',
'Ecuador', 'Egypt', 'El Salvador', 'Estonia', 'Ethiopia',
'Fiji', 'Finland', 'France', 'Gabon', 'Gambia',
'Georgia', 'Germany', 'Ghana', 'Greece', 'Grenada',
'Guatemala', 'Guinea', 'Guyana', 'Haiti', 'Honduras',
'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran',
'Iraq', 'Ireland', 'Israel', 'Italy', 'Jamaica',
'Japan', 'Jordan', 'Kazakhstan', 'Kenya', 'Kuwait',
'Laos', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia',
'Libya', 'Lithuania', 'Luxembourg', 'Madagascar', 'Malawi',
'Malaysia', 'Maldives', 'Mali', 'Malta', 'Mexico',
'Moldova', 'Monaco', 'Mongolia', 'Morocco', 'Mozambique',
'Myanmar', 'Namibia', 'Nepal', 'Netherlands', 'New Zealand',
'Nicaragua', 'Niger', 'Nigeria', 'Norway', 'Oman',
'Pakistan', 'Panama', 'Paraguay', 'Peru', 'Philippines',
'Poland', 'Portugal', 'Qatar', 'Romania', 'Russia',
'Rwanda', 'Saudi Arabia', 'Senegal', 'Serbia', 'Singapore',
'Slovakia', 'Slovenia', 'Somalia', 'South Africa', 'South Korea',
'Spain', 'Sri Lanka', 'Sudan', 'Sweden', 'Switzerland',
'Syria', 'Taiwan', 'Tanzania', 'Thailand', 'Togo',
'Tunisia', 'Turkey', 'Uganda', 'Ukraine', 'United Arab Emirates',
'United Kingdom', 'United States', 'Uruguay', 'Uzbekistan',
'Venezuela', 'Vietnam', 'Yemen', 'Zambia', 'Zimbabwe'
];
// Example: NPM packages for autocomplete
const popularPackages = [
'express', 'react', 'vue', 'angular', 'next', 'nuxt',
'axios', 'lodash', 'moment', 'dayjs', 'uuid', 'dotenv',
'typescript', 'eslint', 'prettier', 'jest', 'mocha', 'chai',
'webpack', 'vite', 'rollup', 'babel', 'esbuild',
'socket.io', 'redis', 'mongodb', 'mongoose', 'sequelize',
'prisma', 'typeorm', 'knex', 'pg', 'mysql2',
'bcrypt', 'jsonwebtoken', 'passport', 'helmet', 'cors',
'multer', 'sharp', 'puppeteer', 'playwright', 'cheerio'
];
// Fuzzy search function
function fuzzySearch(input, choices) {
if (!input) return choices;
const searchTerm = input.toLowerCase();
return choices.filter(choice => {
const item = typeof choice === 'string' ? choice : choice.name;
return item.toLowerCase().includes(searchTerm);
});
}
async function autocompletePromptExample() {
const answers = await inquirer.prompt([
{
type: 'autocomplete',
name: 'country',
message: 'Select your country:',
source: (answersSoFar, input) => {
return Promise.resolve(fuzzySearch(input, countries));
},
pageSize: 10
},
{
type: 'autocomplete',
name: 'package',
message: 'Search for an npm package:',
source: (answersSoFar, input) => {
const filtered = fuzzySearch(input, popularPackages);
return Promise.resolve(filtered);
},
pageSize: 8,
validate: (input) => {
return input.length > 0 || 'Please select a package';
}
},
{
type: 'autocomplete',
name: 'city',
message: 'Select city:',
source: async (answersSoFar, input) => {
// Example: Cities based on selected country
const citiesByCountry = {
'United States': ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix'],
'United Kingdom': ['London', 'Manchester', 'Birmingham', 'Glasgow', 'Liverpool'],
'Canada': ['Toronto', 'Vancouver', 'Montreal', 'Calgary', 'Ottawa'],
'Australia': ['Sydney', 'Melbourne', 'Brisbane', 'Perth', 'Adelaide'],
'Germany': ['Berlin', 'Munich', 'Hamburg', 'Frankfurt', 'Cologne']
};
const cities = citiesByCountry[answersSoFar.country] || ['Capital City', 'Major City'];
return fuzzySearch(input, cities);
},
when: (answers) => ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany'].includes(answers.country)
}
]);
console.log('\n✅ Selections:');
console.log(JSON.stringify(answers, null, 2));
return answers;
}
// Example: Framework/Library search
async function frameworkSearchExample() {
const frameworks = [
{ name: 'React - UI library by Facebook', value: 'react' },
{ name: 'Vue.js - Progressive JavaScript framework', value: 'vue' },
{ name: 'Angular - Platform for building web apps', value: 'angular' },
{ name: 'Svelte - Cybernetically enhanced web apps', value: 'svelte' },
{ name: 'Next.js - React framework with SSR', value: 'next' },
{ name: 'Nuxt.js - Vue.js framework with SSR', value: 'nuxt' },
{ name: 'Remix - Full stack web framework', value: 'remix' },
{ name: 'SvelteKit - Svelte framework', value: 'sveltekit' },
{ name: 'Express - Fast Node.js web framework', value: 'express' },
{ name: 'Fastify - Fast and low overhead web framework', value: 'fastify' },
{ name: 'NestJS - Progressive Node.js framework', value: 'nestjs' },
{ name: 'Koa - Expressive middleware for Node.js', value: 'koa' }
];
const answer = await inquirer.prompt([
{
type: 'autocomplete',
name: 'framework',
message: 'Search for a framework:',
source: (answersSoFar, input) => {
const filtered = fuzzySearch(input, frameworks);
return Promise.resolve(filtered);
},
pageSize: 10
}
]);
console.log(`\n✅ Selected: ${answer.framework}`);
return answer;
}
// Example: Command search with categories
async function commandSearchExample() {
const commands = [
{ name: '📦 install - Install dependencies', value: 'install' },
{ name: '🚀 start - Start development server', value: 'start' },
{ name: '🏗️ build - Build for production', value: 'build' },
{ name: '🧪 test - Run tests', value: 'test' },
{ name: '🔍 lint - Check code quality', value: 'lint' },
{ name: '✨ format - Format code', value: 'format' },
{ name: '📝 generate - Generate files', value: 'generate' },
{ name: '🔄 update - Update dependencies', value: 'update' },
{ name: '🧹 clean - Clean build artifacts', value: 'clean' },
{ name: '🚢 deploy - Deploy application', value: 'deploy' },
{ name: '📊 analyze - Analyze bundle size', value: 'analyze' },
{ name: '🐛 debug - Start debugger', value: 'debug' }
];
const answer = await inquirer.prompt([
{
type: 'autocomplete',
name: 'command',
message: 'Search for a command:',
source: (answersSoFar, input) => {
return Promise.resolve(fuzzySearch(input, commands));
},
pageSize: 12
}
]);
console.log(`\n✅ Running: ${answer.command}`);
return answer;
}
// Example: Dynamic API search (simulated)
async function apiSearchExample() {
console.log('\n🔍 API Endpoint Search\n');
const answer = await inquirer.prompt([
{
type: 'autocomplete',
name: 'endpoint',
message: 'Search API endpoints:',
source: async (answersSoFar, input) => {
// Simulate API call
await new Promise(resolve => setTimeout(resolve, 100));
const endpoints = [
{ name: 'GET /users - List all users', value: '/users' },
{ name: 'GET /users/:id - Get user by ID', value: '/users/:id' },
{ name: 'POST /users - Create new user', value: '/users' },
{ name: 'PUT /users/:id - Update user', value: '/users/:id' },
{ name: 'DELETE /users/:id - Delete user', value: '/users/:id' },
{ name: 'GET /posts - List all posts', value: '/posts' },
{ name: 'GET /posts/:id - Get post by ID', value: '/posts/:id' },
{ name: 'POST /posts - Create new post', value: '/posts' },
{ name: 'GET /comments - List comments', value: '/comments' },
{ name: 'POST /auth/login - User login', value: '/auth/login' },
{ name: 'POST /auth/register - User registration', value: '/auth/register' },
{ name: 'POST /auth/logout - User logout', value: '/auth/logout' }
];
return fuzzySearch(input, endpoints);
},
pageSize: 10
}
]);
console.log(`\n✅ Selected endpoint: ${answer.endpoint}`);
return answer;
}
// Run if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
(async () => {
console.log('=== Autocomplete Examples ===\n');
console.log('1. Country & Package Selection');
await autocompletePromptExample();
console.log('\n2. Framework Search');
await frameworkSearchExample();
console.log('\n3. Command Search');
await commandSearchExample();
console.log('\n4. API Endpoint Search');
await apiSearchExample();
process.exit(0);
})().catch((error) => {
if (error.isTtyError) {
console.error('❌ Prompt could not be rendered in this environment');
} else {
console.error('❌ User interrupted prompt');
}
process.exit(1);
});
}
export { autocompletePromptExample, frameworkSearchExample, commandSearchExample, apiSearchExample };

View File

@@ -0,0 +1,140 @@
/**
* Checkbox Prompt Template
*
* Use for: Multiple selections from options
* Features: Space to toggle, Enter to confirm
*/
import inquirer from 'inquirer';
async function checkboxPromptExample() {
const answers = await inquirer.prompt([
{
type: 'checkbox',
name: 'features',
message: 'Select features to include:',
choices: [
'Authentication',
'Authorization',
'Database Integration',
'API Documentation',
'Testing Suite',
'CI/CD Pipeline',
'Monitoring',
'Logging'
],
validate: (choices) => {
if (choices.length === 0) {
return 'You must select at least one feature';
}
return true;
}
},
{
type: 'checkbox',
name: 'tools',
message: 'Select development tools:',
choices: [
{ name: 'ESLint (Linting)', value: 'eslint', checked: true },
{ name: 'Prettier (Formatting)', value: 'prettier', checked: true },
{ name: 'Jest (Testing)', value: 'jest' },
{ name: 'Husky (Git Hooks)', value: 'husky' },
{ name: 'TypeDoc (Documentation)', value: 'typedoc' },
{ name: 'Webpack (Bundling)', value: 'webpack' }
]
},
{
type: 'checkbox',
name: 'plugins',
message: 'Select plugins to install:',
choices: [
new inquirer.Separator('=== Essential ==='),
{ name: 'dotenv - Environment variables', value: 'dotenv', checked: true },
{ name: 'axios - HTTP client', value: 'axios', checked: true },
new inquirer.Separator('=== Utilities ==='),
{ name: 'lodash - Utility functions', value: 'lodash' },
{ name: 'dayjs - Date manipulation', value: 'dayjs' },
{ name: 'uuid - Unique IDs', value: 'uuid' },
new inquirer.Separator('=== Validation ==='),
{ name: 'joi - Schema validation', value: 'joi' },
{ name: 'zod - TypeScript-first validation', value: 'zod' },
new inquirer.Separator('=== Advanced ==='),
{ name: 'bull - Job queues', value: 'bull' },
{ name: 'socket.io - WebSockets', value: 'socket.io' }
],
pageSize: 15,
validate: (choices) => {
if (choices.length > 10) {
return 'Please select no more than 10 plugins to avoid bloat';
}
return true;
}
},
{
type: 'checkbox',
name: 'permissions',
message: 'Grant the following permissions:',
choices: [
{ name: '📁 Read files', value: 'read', checked: true },
{ name: '✏️ Write files', value: 'write' },
{ name: '🗑️ Delete files', value: 'delete' },
{ name: '🌐 Network access', value: 'network', checked: true },
{ name: '🖥️ System commands', value: 'system' },
{ name: '🔒 Keychain access', value: 'keychain' }
],
validate: (choices) => {
if (choices.includes('delete') && !choices.includes('write')) {
return 'Delete permission requires write permission';
}
return true;
}
},
{
type: 'checkbox',
name: 'environments',
message: 'Select deployment environments:',
choices: [
{ name: 'Development', value: 'dev', checked: true },
{ name: 'Staging', value: 'staging' },
{ name: 'Production', value: 'prod' },
{ name: 'Testing', value: 'test', checked: true }
],
validate: (choices) => {
if (!choices.includes('dev')) {
return 'Development environment is required';
}
if (choices.includes('prod') && !choices.includes('staging')) {
return 'Staging environment is recommended before production';
}
return true;
}
}
]);
console.log('\n✅ Selected options:');
console.log(JSON.stringify(answers, null, 2));
// Example: Process selections
console.log('\n📦 Installing selected features...');
answers.features.forEach(feature => {
console.log(` - ${feature}`);
});
return answers;
}
// Run if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
checkboxPromptExample()
.then(() => process.exit(0))
.catch((error) => {
if (error.isTtyError) {
console.error('❌ Prompt could not be rendered in this environment');
} else {
console.error('❌ User interrupted prompt');
}
process.exit(1);
});
}
export { checkboxPromptExample };

View File

@@ -0,0 +1,456 @@
/**
* Comprehensive CLI Example
*
* Complete project initialization wizard combining all prompt types:
* - Text input with validation
* - List selections
* - Checkbox selections
* - Password input
* - Autocomplete (optional)
* - Conditional logic
*/
import inquirer from 'inquirer';
async function projectInitWizard() {
console.log(`
╔═══════════════════════════════════════════════════════════╗
║ ║
║ 🚀 Project Initialization Wizard 🚀 ║
║ ║
╚═══════════════════════════════════════════════════════════╝
`);
const config = await inquirer.prompt([
// === PROJECT BASICS ===
{
type: 'input',
name: 'projectName',
message: '📦 Project name:',
validate: (input) => {
if (input.length === 0) return 'Project name is required';
if (!/^[a-z0-9-_]+$/.test(input)) {
return 'Use lowercase letters, numbers, hyphens, and underscores only';
}
if (input.length < 3) return 'Project name must be at least 3 characters';
return true;
},
transformer: (input) => input.toLowerCase()
},
{
type: 'input',
name: 'description',
message: '📝 Project description:',
validate: (input) => input.length > 0 || 'Description is required'
},
{
type: 'input',
name: 'version',
message: '🏷️ Initial version:',
default: '0.1.0',
validate: (input) => {
return /^\d+\.\d+\.\d+$/.test(input) || 'Use semantic versioning (e.g., 0.1.0)';
}
},
{
type: 'input',
name: 'author',
message: '👤 Author name:',
default: process.env.USER || ''
},
{
type: 'input',
name: 'email',
message: '📧 Author email:',
validate: (input) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(input) || 'Invalid email address';
}
},
{
type: 'list',
name: 'license',
message: '📜 License:',
choices: ['MIT', 'Apache-2.0', 'GPL-3.0', 'BSD-3-Clause', 'ISC', 'Unlicensed'],
default: 'MIT'
},
// === TECHNOLOGY STACK ===
{
type: 'list',
name: 'projectType',
message: '🛠️ Project type:',
choices: [
'Web Application',
'CLI Tool',
'API/Backend',
'Library/Package',
'Desktop Application',
'Mobile Application'
]
},
{
type: 'list',
name: 'language',
message: '💻 Programming language:',
choices: [
{ name: 'TypeScript (Recommended)', value: 'typescript', short: 'TS' },
{ name: 'JavaScript', value: 'javascript', short: 'JS' },
{ name: 'Python', value: 'python', short: 'Py' },
{ name: 'Go', value: 'go', short: 'Go' },
{ name: 'Rust', value: 'rust', short: 'Rust' }
]
},
{
type: 'list',
name: 'framework',
message: '🎨 Framework/Runtime:',
choices: (answers) => {
const frameworks = {
typescript: ['Next.js', 'Remix', 'Nest.js', 'Express', 'Fastify', 'Node.js'],
javascript: ['React', 'Vue', 'Svelte', 'Express', 'Fastify', 'Node.js'],
python: ['FastAPI', 'Django', 'Flask', 'Tornado', 'Sanic'],
go: ['Gin', 'Echo', 'Fiber', 'Standard library'],
rust: ['Actix', 'Rocket', 'Axum', 'Warp']
};
return frameworks[answers.language] || ['None'];
}
},
// === FEATURES & TOOLS ===
{
type: 'checkbox',
name: 'features',
message: '✨ Select features:',
choices: (answers) => {
const baseFeatures = [
{ name: 'Environment variables (.env)', value: 'env', checked: true },
{ name: 'Configuration management', value: 'config', checked: true },
{ name: 'Logging', value: 'logging', checked: true },
{ name: 'Error handling', value: 'error-handling', checked: true }
];
if (answers.projectType === 'Web Application' || answers.projectType === 'API/Backend') {
baseFeatures.push(
{ name: 'Authentication', value: 'auth' },
{ name: 'Database integration', value: 'database' },
{ name: 'API documentation', value: 'api-docs' },
{ name: 'CORS handling', value: 'cors' }
);
}
if (answers.projectType === 'CLI Tool') {
baseFeatures.push(
{ name: 'Command-line arguments parser', value: 'cli-parser', checked: true },
{ name: 'Interactive prompts', value: 'prompts', checked: true },
{ name: 'Progress bars', value: 'progress' }
);
}
return baseFeatures;
},
validate: (choices) => choices.length > 0 || 'Select at least one feature'
},
{
type: 'checkbox',
name: 'devTools',
message: '🔧 Development tools:',
choices: (answers) => {
const tools = [];
if (['typescript', 'javascript'].includes(answers.language)) {
tools.push(
{ name: 'ESLint - Linting', value: 'eslint', checked: true },
{ name: 'Prettier - Code formatting', value: 'prettier', checked: true },
{ name: 'Husky - Git hooks', value: 'husky' },
{ name: 'Jest - Testing framework', value: 'jest', checked: true },
{ name: 'TypeDoc/JSDoc - Documentation', value: 'docs' }
);
} else if (answers.language === 'python') {
tools.push(
{ name: 'Black - Code formatting', value: 'black', checked: true },
{ name: 'Flake8 - Linting', value: 'flake8', checked: true },
{ name: 'mypy - Type checking', value: 'mypy' },
{ name: 'pytest - Testing framework', value: 'pytest', checked: true },
{ name: 'Sphinx - Documentation', value: 'sphinx' }
);
}
return tools;
},
default: ['eslint', 'prettier', 'jest']
},
// === DATABASE CONFIGURATION ===
{
type: 'confirm',
name: 'useDatabase',
message: '🗄️ Use database?',
default: (answers) => {
return answers.features.includes('database') ||
['Web Application', 'API/Backend'].includes(answers.projectType);
},
when: (answers) => ['Web Application', 'API/Backend', 'CLI Tool'].includes(answers.projectType)
},
{
type: 'list',
name: 'databaseType',
message: '📊 Database type:',
choices: [
{ name: '🐘 PostgreSQL (Relational)', value: 'postgresql' },
{ name: '🐬 MySQL (Relational)', value: 'mysql' },
{ name: '🍃 MongoDB (Document)', value: 'mongodb' },
{ name: '⚡ Redis (Key-Value)', value: 'redis' },
{ name: '📁 SQLite (Embedded)', value: 'sqlite' },
{ name: '🔥 Supabase (PostgreSQL + APIs)', value: 'supabase' }
],
when: (answers) => answers.useDatabase
},
{
type: 'list',
name: 'databaseORM',
message: '🔗 ORM/Database client:',
choices: (answers) => {
const orms = {
typescript: {
postgresql: ['Prisma', 'TypeORM', 'Kysely', 'Drizzle'],
mysql: ['Prisma', 'TypeORM', 'Kysely', 'Drizzle'],
mongodb: ['Mongoose', 'Prisma', 'TypeORM'],
sqlite: ['Prisma', 'TypeORM', 'Better-SQLite3'],
supabase: ['Supabase Client', 'Prisma']
},
python: {
postgresql: ['SQLAlchemy', 'Django ORM', 'Tortoise ORM'],
mysql: ['SQLAlchemy', 'Django ORM', 'Tortoise ORM'],
mongodb: ['Motor', 'PyMongo', 'MongoEngine'],
sqlite: ['SQLAlchemy', 'Django ORM']
}
};
const lang = answers.language;
const db = answers.databaseType;
return orms[lang]?.[db] || ['None'];
},
when: (answers) => answers.useDatabase && answers.databaseType !== 'redis'
},
// === TESTING CONFIGURATION ===
{
type: 'confirm',
name: 'setupTesting',
message: '🧪 Setup testing?',
default: true
},
{
type: 'checkbox',
name: 'testTypes',
message: '🔬 Test types:',
choices: [
{ name: 'Unit tests', value: 'unit', checked: true },
{ name: 'Integration tests', value: 'integration', checked: true },
{ name: 'E2E tests', value: 'e2e' },
{ name: 'Performance tests', value: 'performance' }
],
when: (answers) => answers.setupTesting
},
// === CI/CD CONFIGURATION ===
{
type: 'confirm',
name: 'setupCICD',
message: '⚙️ Setup CI/CD?',
default: true
},
{
type: 'list',
name: 'cicdProvider',
message: '🔄 CI/CD provider:',
choices: ['GitHub Actions', 'GitLab CI', 'CircleCI', 'Jenkins', 'None'],
when: (answers) => answers.setupCICD
},
// === DEPLOYMENT CONFIGURATION ===
{
type: 'confirm',
name: 'setupDeployment',
message: '🚀 Setup deployment?',
default: (answers) => answers.projectType !== 'Library/Package'
},
{
type: 'list',
name: 'deploymentPlatform',
message: '☁️ Deployment platform:',
choices: (answers) => {
if (answers.projectType === 'Web Application') {
return ['Vercel', 'Netlify', 'AWS', 'Google Cloud', 'Azure', 'Self-hosted'];
} else if (answers.projectType === 'API/Backend') {
return ['AWS', 'Google Cloud', 'Azure', 'DigitalOcean', 'Heroku', 'Self-hosted'];
} else if (answers.projectType === 'CLI Tool') {
return ['npm', 'PyPI', 'Homebrew', 'Binary releases', 'Docker'];
}
return ['AWS', 'Google Cloud', 'Azure', 'Self-hosted'];
},
when: (answers) => answers.setupDeployment
},
{
type: 'confirm',
name: 'useDocker',
message: '🐳 Use Docker?',
default: true,
when: (answers) => {
return answers.setupDeployment &&
!['Vercel', 'Netlify'].includes(answers.deploymentPlatform);
}
},
// === MONITORING & OBSERVABILITY ===
{
type: 'confirm',
name: 'setupMonitoring',
message: '📊 Setup monitoring & observability?',
default: (answers) => answers.projectType !== 'Library/Package'
},
{
type: 'checkbox',
name: 'monitoringTools',
message: '📈 Monitoring tools:',
choices: [
{ name: 'Sentry - Error tracking', value: 'sentry' },
{ name: 'DataDog - Full observability', value: 'datadog' },
{ name: 'Prometheus - Metrics', value: 'prometheus' },
{ name: 'Grafana - Dashboards', value: 'grafana' },
{ name: 'New Relic - APM', value: 'newrelic' }
],
when: (answers) => answers.setupMonitoring
},
// === DOCUMENTATION ===
{
type: 'confirm',
name: 'generateDocs',
message: '📚 Generate documentation?',
default: true
},
{
type: 'checkbox',
name: 'docTypes',
message: '📖 Documentation types:',
choices: [
{ name: 'README.md', value: 'readme', checked: true },
{ name: 'API documentation', value: 'api', checked: true },
{ name: 'Contributing guidelines', value: 'contributing' },
{ name: 'Code of conduct', value: 'coc' },
{ name: 'Changelog', value: 'changelog', checked: true }
],
when: (answers) => answers.generateDocs
},
// === SECURITY ===
{
type: 'confirm',
name: 'securitySetup',
message: '🔒 Setup security features?',
default: true,
when: (answers) => ['Web Application', 'API/Backend'].includes(answers.projectType)
},
{
type: 'checkbox',
name: 'securityFeatures',
message: '🛡️ Security features:',
choices: [
{ name: 'Dependency scanning', value: 'dep-scan', checked: true },
{ name: 'Secret scanning', value: 'secret-scan', checked: true },
{ name: 'HTTPS enforcement', value: 'https' },
{ name: 'Rate limiting', value: 'rate-limit' },
{ name: 'Input validation', value: 'validation', checked: true },
{ name: 'Security headers', value: 'headers' }
],
when: (answers) => answers.securitySetup
},
// === FINAL CONFIRMATION ===
{
type: 'confirm',
name: 'confirm',
message: '✅ Initialize project with these settings?',
default: true
}
]);
if (!config.confirm) {
console.log('\n❌ Project initialization cancelled.\n');
return null;
}
// Display configuration summary
console.log('\n' + '═'.repeat(60));
console.log('📋 PROJECT CONFIGURATION SUMMARY');
console.log('═'.repeat(60) + '\n');
console.log(`📦 Project: ${config.projectName} v${config.version}`);
console.log(`📝 Description: ${config.description}`);
console.log(`👤 Author: ${config.author} <${config.email}>`);
console.log(`📜 License: ${config.license}\n`);
console.log(`💻 Language: ${config.language}`);
console.log(`🎨 Framework: ${config.framework}`);
console.log(`🛠️ Type: ${config.projectType}\n`);
if (config.useDatabase) {
console.log(`🗄️ Database: ${config.databaseType}`);
if (config.databaseORM) {
console.log(`🔗 ORM: ${config.databaseORM}\n`);
}
}
if (config.features.length > 0) {
console.log(`✨ Features: ${config.features.join(', ')}`);
}
if (config.devTools.length > 0) {
console.log(`🔧 Dev Tools: ${config.devTools.join(', ')}\n`);
}
if (config.setupDeployment) {
console.log(`🚀 Deployment: ${config.deploymentPlatform}`);
if (config.useDocker) console.log(`🐳 Docker: Enabled`);
}
if (config.setupCICD) {
console.log(`⚙️ CI/CD: ${config.cicdProvider}`);
}
console.log('\n' + '═'.repeat(60) + '\n');
console.log('🎉 Configuration complete! Initializing project...\n');
// Here you would actually create the project files
// This is just a demonstration
return config;
}
// Run if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
projectInitWizard()
.then((config) => {
if (config) {
console.log('✅ Project initialized successfully!\n');
console.log('Next steps:');
console.log(` 1. cd ${config.projectName}`);
console.log(' 2. Install dependencies');
console.log(' 3. Start development');
}
process.exit(0);
})
.catch((error) => {
if (error.isTtyError) {
console.error('❌ Prompt could not be rendered in this environment');
} else {
console.error('❌ User interrupted prompt');
}
process.exit(1);
});
}
export { projectInitWizard };

View File

@@ -0,0 +1,460 @@
/**
* Conditional Prompt Template
*
* Use for: Dynamic forms based on previous answers
* Features: Skip logic, dependent questions, branching
*/
import inquirer from 'inquirer';
async function conditionalPromptExample() {
const answers = await inquirer.prompt([
{
type: 'confirm',
name: 'useDatabase',
message: 'Do you want to use a database?',
default: true
},
{
type: 'list',
name: 'databaseType',
message: 'Select database type:',
choices: ['PostgreSQL', 'MySQL', 'MongoDB', 'SQLite', 'Redis'],
when: (answers) => answers.useDatabase
},
{
type: 'input',
name: 'databaseHost',
message: 'Database host:',
default: 'localhost',
when: (answers) => {
return answers.useDatabase && answers.databaseType !== 'SQLite';
}
},
{
type: 'input',
name: 'databasePort',
message: 'Database port:',
default: (answers) => {
const ports = {
'PostgreSQL': '5432',
'MySQL': '3306',
'MongoDB': '27017',
'Redis': '6379'
};
return ports[answers.databaseType] || '5432';
},
when: (answers) => {
return answers.useDatabase && answers.databaseType !== 'SQLite';
}
},
{
type: 'input',
name: 'databaseName',
message: 'Database name:',
when: (answers) => answers.useDatabase,
validate: (input) => input.length > 0 || 'Database name required'
},
{
type: 'confirm',
name: 'useAuthentication',
message: 'Do you want to use authentication?',
default: true,
when: (answers) => answers.useDatabase
},
{
type: 'input',
name: 'databaseUsername',
message: 'Database username:',
when: (answers) => answers.useDatabase && answers.useAuthentication,
validate: (input) => input.length > 0 || 'Username required'
},
{
type: 'password',
name: 'databasePassword',
message: 'Database password:',
mask: '*',
when: (answers) => answers.useDatabase && answers.useAuthentication
},
{
type: 'confirm',
name: 'useSSL',
message: 'Use SSL connection?',
default: false,
when: (answers) => {
return answers.useDatabase &&
answers.databaseType !== 'SQLite' &&
answers.databaseHost !== 'localhost';
}
},
{
type: 'input',
name: 'sslCertPath',
message: 'Path to SSL certificate:',
when: (answers) => answers.useSSL,
validate: (input) => input.length > 0 || 'SSL certificate path required'
}
]);
console.log('\n✅ Configuration:');
console.log(JSON.stringify(answers, null, 2));
return answers;
}
// Example: Deployment configuration wizard
async function deploymentWizard() {
console.log('\n🚀 Deployment Configuration Wizard\n');
const config = await inquirer.prompt([
{
type: 'list',
name: 'environment',
message: 'Select deployment environment:',
choices: ['Development', 'Staging', 'Production']
},
{
type: 'confirm',
name: 'useDocker',
message: 'Deploy using Docker?',
default: true
},
{
type: 'input',
name: 'dockerImage',
message: 'Docker image name:',
when: (answers) => answers.useDocker,
default: 'myapp:latest',
validate: (input) => /^[a-z0-9-_/:.]+$/.test(input) || 'Invalid Docker image name'
},
{
type: 'list',
name: 'registry',
message: 'Container registry:',
choices: ['Docker Hub', 'GitHub Container Registry', 'AWS ECR', 'Google Artifact Registry'],
when: (answers) => answers.useDocker
},
{
type: 'list',
name: 'platform',
message: 'Deployment platform:',
choices: ['AWS', 'Google Cloud', 'Azure', 'DigitalOcean', 'Vercel', 'Netlify', 'Self-hosted']
},
{
type: 'list',
name: 'awsService',
message: 'AWS service:',
choices: ['ECS', 'EKS', 'Lambda', 'Elastic Beanstalk', 'EC2'],
when: (answers) => answers.platform === 'AWS'
},
{
type: 'list',
name: 'gcpService',
message: 'Google Cloud service:',
choices: ['Cloud Run', 'GKE', 'App Engine', 'Compute Engine'],
when: (answers) => answers.platform === 'Google Cloud'
},
{
type: 'confirm',
name: 'autoScale',
message: 'Enable auto-scaling?',
default: true,
when: (answers) => {
const scalableServices = ['ECS', 'EKS', 'Cloud Run', 'GKE'];
return scalableServices.includes(answers.awsService) ||
scalableServices.includes(answers.gcpService);
}
},
{
type: 'input',
name: 'minInstances',
message: 'Minimum instances:',
default: '1',
when: (answers) => answers.autoScale,
validate: (input) => {
const num = parseInt(input);
return num > 0 || 'Must be at least 1';
}
},
{
type: 'input',
name: 'maxInstances',
message: 'Maximum instances:',
default: '10',
when: (answers) => answers.autoScale,
validate: (input, answers) => {
const num = parseInt(input);
const min = parseInt(answers.minInstances);
return num >= min || `Must be at least ${min}`;
}
},
{
type: 'confirm',
name: 'useCDN',
message: 'Use CDN for static assets?',
default: true,
when: (answers) => answers.environment === 'Production'
},
{
type: 'list',
name: 'cdnProvider',
message: 'CDN provider:',
choices: ['CloudFlare', 'AWS CloudFront', 'Google Cloud CDN', 'Azure CDN'],
when: (answers) => answers.useCDN
},
{
type: 'confirm',
name: 'setupMonitoring',
message: 'Setup monitoring?',
default: true
},
{
type: 'checkbox',
name: 'monitoringTools',
message: 'Select monitoring tools:',
choices: ['Prometheus', 'Grafana', 'Datadog', 'New Relic', 'Sentry'],
when: (answers) => answers.setupMonitoring,
validate: (choices) => choices.length > 0 || 'Select at least one tool'
}
]);
console.log('\n✅ Deployment configuration complete!');
console.log(JSON.stringify(config, null, 2));
return config;
}
// Example: Feature flag configuration
async function featureFlagWizard() {
console.log('\n🎛 Feature Flag Configuration\n');
const config = await inquirer.prompt([
{
type: 'input',
name: 'featureName',
message: 'Feature name:',
validate: (input) => /^[a-z-_]+$/.test(input) || 'Use lowercase, hyphens, underscores only'
},
{
type: 'confirm',
name: 'enabledByDefault',
message: 'Enabled by default?',
default: false
},
{
type: 'list',
name: 'rolloutStrategy',
message: 'Rollout strategy:',
choices: [
'All users',
'Percentage rollout',
'User targeting',
'Beta users only',
'Manual control'
]
},
{
type: 'input',
name: 'rolloutPercentage',
message: 'Rollout percentage (0-100):',
when: (answers) => answers.rolloutStrategy === 'Percentage rollout',
default: '10',
validate: (input) => {
const num = parseInt(input);
return (num >= 0 && num <= 100) || 'Must be between 0 and 100';
}
},
{
type: 'checkbox',
name: 'targetUserGroups',
message: 'Target user groups:',
choices: ['Beta testers', 'Premium users', 'Internal team', 'Early adopters', 'Specific regions'],
when: (answers) => answers.rolloutStrategy === 'User targeting',
validate: (choices) => choices.length > 0 || 'Select at least one group'
},
{
type: 'checkbox',
name: 'targetRegions',
message: 'Target regions:',
choices: ['North America', 'Europe', 'Asia Pacific', 'South America', 'Africa'],
when: (answers) => {
return answers.rolloutStrategy === 'User targeting' &&
answers.targetUserGroups.includes('Specific regions');
}
},
{
type: 'confirm',
name: 'enableMetrics',
message: 'Track feature usage metrics?',
default: true
},
{
type: 'checkbox',
name: 'metrics',
message: 'Select metrics to track:',
choices: [
'Usage count',
'User adoption rate',
'Performance impact',
'Error rate',
'User feedback'
],
when: (answers) => answers.enableMetrics
},
{
type: 'confirm',
name: 'addExpirationDate',
message: 'Set feature flag expiration?',
default: false
},
{
type: 'input',
name: 'expirationDate',
message: 'Expiration date (YYYY-MM-DD):',
when: (answers) => answers.addExpirationDate,
validate: (input) => {
const date = new Date(input);
if (isNaN(date.getTime())) return 'Invalid date format';
if (date < new Date()) return 'Date must be in the future';
return true;
}
}
]);
console.log('\n✅ Feature flag configured!');
console.log(JSON.stringify(config, null, 2));
return config;
}
// Example: CI/CD pipeline setup
async function cicdPipelineWizard() {
console.log('\n⚙ CI/CD Pipeline Configuration\n');
const config = await inquirer.prompt([
{
type: 'list',
name: 'provider',
message: 'CI/CD provider:',
choices: ['GitHub Actions', 'GitLab CI', 'CircleCI', 'Jenkins', 'Travis CI']
},
{
type: 'checkbox',
name: 'triggers',
message: 'Pipeline triggers:',
choices: [
'Push to main/master',
'Pull request',
'Tag creation',
'Manual trigger',
'Scheduled (cron)'
],
default: ['Push to main/master', 'Pull request']
},
{
type: 'input',
name: 'cronSchedule',
message: 'Cron schedule:',
when: (answers) => answers.triggers.includes('Scheduled (cron)'),
default: '0 2 * * *',
validate: (input) => {
// Basic cron validation
const parts = input.split(' ');
return parts.length === 5 || 'Invalid cron format (5 parts required)';
}
},
{
type: 'checkbox',
name: 'stages',
message: 'Pipeline stages:',
choices: ['Build', 'Test', 'Lint', 'Security scan', 'Deploy'],
default: ['Build', 'Test', 'Deploy'],
validate: (choices) => choices.length > 0 || 'Select at least one stage'
},
{
type: 'checkbox',
name: 'testTypes',
message: 'Test types to run:',
choices: ['Unit tests', 'Integration tests', 'E2E tests', 'Performance tests'],
when: (answers) => answers.stages.includes('Test')
},
{
type: 'checkbox',
name: 'securityTools',
message: 'Security scanning tools:',
choices: ['Snyk', 'Dependabot', 'SonarQube', 'OWASP Dependency Check'],
when: (answers) => answers.stages.includes('Security scan')
},
{
type: 'checkbox',
name: 'deployEnvironments',
message: 'Deployment environments:',
choices: ['Development', 'Staging', 'Production'],
when: (answers) => answers.stages.includes('Deploy'),
default: ['Staging', 'Production']
},
{
type: 'confirm',
name: 'requireApproval',
message: 'Require manual approval for production?',
default: true,
when: (answers) => {
return answers.stages.includes('Deploy') &&
answers.deployEnvironments?.includes('Production');
}
},
{
type: 'confirm',
name: 'enableNotifications',
message: 'Enable build notifications?',
default: true
},
{
type: 'checkbox',
name: 'notificationChannels',
message: 'Notification channels:',
choices: ['Email', 'Slack', 'Discord', 'Microsoft Teams'],
when: (answers) => answers.enableNotifications
}
]);
console.log('\n✅ CI/CD pipeline configured!');
console.log(JSON.stringify(config, null, 2));
return config;
}
// Run if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
(async () => {
console.log('=== Conditional Prompt Examples ===\n');
console.log('1. Database Configuration');
await conditionalPromptExample();
console.log('\n2. Deployment Wizard');
await deploymentWizard();
console.log('\n3. Feature Flag Configuration');
await featureFlagWizard();
console.log('\n4. CI/CD Pipeline Setup');
await cicdPipelineWizard();
process.exit(0);
})().catch((error) => {
if (error.isTtyError) {
console.error('❌ Prompt could not be rendered in this environment');
} else {
console.error('❌ User interrupted prompt');
}
process.exit(1);
});
}
export {
conditionalPromptExample,
deploymentWizard,
featureFlagWizard,
cicdPipelineWizard
};

View File

@@ -0,0 +1,104 @@
/**
* List Selection Prompt Template
*
* Use for: Single choice from predefined options
* Features: Arrow key navigation, search filtering
*/
import inquirer from 'inquirer';
async function listPromptExample() {
const answers = await inquirer.prompt([
{
type: 'list',
name: 'framework',
message: 'Choose your preferred framework:',
choices: [
'React',
'Vue',
'Angular',
'Svelte',
'Next.js',
'Nuxt.js'
],
default: 'React'
},
{
type: 'list',
name: 'language',
message: 'Choose programming language:',
choices: [
{ name: 'JavaScript', value: 'js' },
{ name: 'TypeScript', value: 'ts' },
{ name: 'Python', value: 'py' },
{ name: 'Ruby', value: 'rb' },
{ name: 'Go', value: 'go' }
],
default: 'ts'
},
{
type: 'list',
name: 'packageManager',
message: 'Choose package manager:',
choices: [
{ name: 'npm (Node Package Manager)', value: 'npm', short: 'npm' },
{ name: 'yarn (Fast, reliable package manager)', value: 'yarn', short: 'yarn' },
{ name: 'pnpm (Fast, disk space efficient)', value: 'pnpm', short: 'pnpm' },
{ name: 'bun (All-in-one toolkit)', value: 'bun', short: 'bun' }
]
},
{
type: 'list',
name: 'environment',
message: 'Select deployment environment:',
choices: [
new inquirer.Separator('--- Cloud Platforms ---'),
'AWS',
'Google Cloud',
'Azure',
new inquirer.Separator('--- Serverless ---'),
'Vercel',
'Netlify',
'Cloudflare Workers',
new inquirer.Separator('--- Self-hosted ---'),
'Docker',
'Kubernetes'
]
},
{
type: 'list',
name: 'database',
message: 'Choose database:',
choices: [
{ name: '🐘 PostgreSQL (Relational)', value: 'postgresql' },
{ name: '🐬 MySQL (Relational)', value: 'mysql' },
{ name: '🍃 MongoDB (Document)', value: 'mongodb' },
{ name: '⚡ Redis (Key-Value)', value: 'redis' },
{ name: '📊 SQLite (Embedded)', value: 'sqlite' },
{ name: '🔥 Supabase (PostgreSQL + APIs)', value: 'supabase' }
],
pageSize: 10
}
]);
console.log('\n✅ Selections:');
console.log(JSON.stringify(answers, null, 2));
return answers;
}
// Run if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
listPromptExample()
.then(() => process.exit(0))
.catch((error) => {
if (error.isTtyError) {
console.error('❌ Prompt could not be rendered in this environment');
} else {
console.error('❌ User interrupted prompt');
}
process.exit(1);
});
}
export { listPromptExample };

View File

@@ -0,0 +1,208 @@
/**
* Password Prompt Template
*
* Use for: Sensitive input (credentials, tokens)
* Features: Hidden input, confirmation, validation
*/
import inquirer from 'inquirer';
async function passwordPromptExample() {
const answers = await inquirer.prompt([
{
type: 'password',
name: 'password',
message: 'Enter your password:',
mask: '*',
validate: (input) => {
if (input.length < 8) {
return 'Password must be at least 8 characters';
}
if (!/[A-Z]/.test(input)) {
return 'Password must contain at least one uppercase letter';
}
if (!/[a-z]/.test(input)) {
return 'Password must contain at least one lowercase letter';
}
if (!/[0-9]/.test(input)) {
return 'Password must contain at least one number';
}
if (!/[!@#$%^&*(),.?":{}|<>]/.test(input)) {
return 'Password must contain at least one special character';
}
return true;
}
},
{
type: 'password',
name: 'confirmPassword',
message: 'Confirm your password:',
mask: '*',
validate: (input, answers) => {
if (input !== answers.password) {
return 'Passwords do not match';
}
return true;
}
},
{
type: 'password',
name: 'apiKey',
message: 'Enter your API key:',
mask: '•',
validate: (input) => {
if (input.length === 0) {
return 'API key is required';
}
// Example: Validate API key format (e.g., sk-...)
if (!input.startsWith('sk-') && !input.startsWith('pk-')) {
return 'API key must start with "sk-" or "pk-"';
}
if (input.length < 32) {
return 'API key appears to be too short';
}
return true;
}
},
{
type: 'password',
name: 'oldPassword',
message: 'Enter your old password (for password change):',
mask: '*',
when: (answers) => {
// Only ask for old password if changing password
return answers.password && answers.confirmPassword;
},
validate: (input) => {
if (input.length === 0) {
return 'Old password is required';
}
// In real app, you'd verify against stored password
return true;
}
},
{
type: 'password',
name: 'encryptionKey',
message: 'Enter encryption key (optional):',
mask: '#',
validate: (input) => {
if (input.length === 0) return true; // Optional
if (input.length < 16) {
return 'Encryption key must be at least 16 characters';
}
return true;
}
}
]);
// Don't log actual passwords!
console.log('\n✅ Credentials received (not displayed for security)');
console.log('Password strength:', calculatePasswordStrength(answers.password));
console.log('API key format:', answers.apiKey.substring(0, 6) + '...');
// In real app, you'd:
// - Hash the password before storing
// - Encrypt the API key
// - Store securely (not in plain text)
return {
passwordHash: hashPassword(answers.password),
apiKeyEncrypted: encryptApiKey(answers.apiKey)
};
}
// Helper function to calculate password strength
function calculatePasswordStrength(password) {
let strength = 0;
if (password.length >= 8) strength++;
if (password.length >= 12) strength++;
if (/[a-z]/.test(password)) strength++;
if (/[A-Z]/.test(password)) strength++;
if (/[0-9]/.test(password)) strength++;
if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) strength++;
const levels = ['Very Weak', 'Weak', 'Fair', 'Good', 'Strong', 'Very Strong'];
return levels[Math.min(strength, levels.length - 1)];
}
// Placeholder for password hashing (use bcrypt in production)
function hashPassword(password) {
return `[HASHED:${password.length}_chars]`;
}
// Placeholder for API key encryption (use proper encryption in production)
function encryptApiKey(apiKey) {
return `[ENCRYPTED:${apiKey.substring(0, 6)}...]`;
}
// Example: Secure credential storage
async function securePasswordExample() {
console.log('\n🔐 Secure Password Setup\n');
const credentials = await inquirer.prompt([
{
type: 'input',
name: 'username',
message: 'Username:',
validate: (input) => input.length > 0 || 'Username required'
},
{
type: 'password',
name: 'password',
message: 'Password:',
mask: '*',
validate: (input) => {
const issues = [];
if (input.length < 12) issues.push('at least 12 characters');
if (!/[A-Z]/.test(input)) issues.push('an uppercase letter');
if (!/[a-z]/.test(input)) issues.push('a lowercase letter');
if (!/[0-9]/.test(input)) issues.push('a number');
if (!/[!@#$%^&*]/.test(input)) issues.push('a special character (!@#$%^&*)');
if (issues.length > 0) {
return `Password must contain: ${issues.join(', ')}`;
}
return true;
}
},
{
type: 'password',
name: 'confirm',
message: 'Confirm password:',
mask: '*',
validate: (input, answers) => {
return input === answers.password || 'Passwords do not match';
}
},
{
type: 'confirm',
name: 'remember',
message: 'Remember credentials? (stored securely)',
default: false
}
]);
console.log(`\n✅ Account created for: ${credentials.username}`);
console.log(`🔒 Password strength: ${calculatePasswordStrength(credentials.password)}`);
return credentials;
}
// Run if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
passwordPromptExample()
.then(() => securePasswordExample())
.then(() => process.exit(0))
.catch((error) => {
if (error.isTtyError) {
console.error('❌ Prompt could not be rendered in this environment');
} else {
console.error('❌ User interrupted prompt');
}
process.exit(1);
});
}
export { passwordPromptExample, securePasswordExample };

View File

@@ -0,0 +1,105 @@
/**
* Text Input Prompt Template
*
* Use for: Names, emails, URLs, paths, free-form text
* Features: Validation, default values, transform
*/
import inquirer from 'inquirer';
async function textPromptExample() {
const answers = await inquirer.prompt([
{
type: 'input',
name: 'username',
message: 'Enter your username:',
default: '',
validate: (input) => {
if (input.length === 0) {
return 'Username is required';
}
if (input.length < 3) {
return 'Username must be at least 3 characters';
}
if (!/^[a-zA-Z0-9_-]+$/.test(input)) {
return 'Username can only contain letters, numbers, hyphens, and underscores';
}
return true;
},
transformer: (input) => {
return input.toLowerCase();
}
},
{
type: 'input',
name: 'email',
message: 'Enter your email:',
validate: (input) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(input) || 'Invalid email address';
}
},
{
type: 'input',
name: 'website',
message: 'Enter your website (optional):',
default: '',
validate: (input) => {
if (input.length === 0) return true; // Optional field
const urlRegex = /^https?:\/\/.+/;
return urlRegex.test(input) || 'Must be a valid URL (http:// or https://)';
}
},
{
type: 'input',
name: 'age',
message: 'Enter your age:',
validate: (input) => {
const age = parseInt(input);
if (isNaN(age)) {
return 'Please enter a valid number';
}
if (age < 18) {
return 'You must be at least 18 years old';
}
if (age > 120) {
return 'Please enter a realistic age';
}
return true;
},
filter: (input) => parseInt(input)
},
{
type: 'input',
name: 'bio',
message: 'Enter a short bio:',
validate: (input) => {
if (input.length > 200) {
return 'Bio must be 200 characters or less';
}
return true;
}
}
]);
console.log('\n✅ Answers received:');
console.log(JSON.stringify(answers, null, 2));
return answers;
}
// Run if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
textPromptExample()
.then(() => process.exit(0))
.catch((error) => {
if (error.isTtyError) {
console.error('❌ Prompt could not be rendered in this environment');
} else {
console.error('❌ User interrupted prompt');
}
process.exit(1);
});
}
export { textPromptExample };