Agent skill
inquirer-prompt-generator
Generate interactive command-line prompts using Inquirer.js with validation, conditional logic, and custom renderers. Creates user-friendly input collection flows for CLI applications.
Install this agent skill to your Project
npx add-skill https://github.com/a5c-ai/babysitter/tree/main/library/specializations/cli-mcp-development/skills/inquirer-prompt-generator
SKILL.md
Inquirer Prompt Generator
Generate interactive CLI prompts using Inquirer.js with comprehensive validation, conditional flows, and custom formatting.
Capabilities
- Generate Inquirer.js prompt definitions
- Create multi-step wizard flows
- Implement input validation
- Support conditional prompts
- Generate TypeScript interfaces for answers
- Create custom prompt formatters
Usage
Invoke this skill when you need to:
- Create interactive CLI input collection
- Build configuration wizards
- Implement user confirmation flows
- Generate form-like CLI interfaces
Inputs
| Parameter | Type | Required | Description |
|---|---|---|---|
| flowName | string | Yes | Name of the prompt flow |
| prompts | array | Yes | List of prompt definitions |
| typescript | boolean | No | Generate TypeScript types (default: true) |
| validation | boolean | No | Include validation helpers (default: true) |
Prompt Definition Structure
{
"prompts": [
{
"type": "input",
"name": "projectName",
"message": "What is your project name?",
"default": "my-project",
"validate": {
"required": true,
"pattern": "^[a-z][a-z0-9-]*$",
"message": "Project name must be lowercase with hyphens"
}
},
{
"type": "list",
"name": "template",
"message": "Select a template:",
"choices": [
{ "name": "React + TypeScript", "value": "react-ts" },
{ "name": "Vue + TypeScript", "value": "vue-ts" },
{ "name": "Node.js + Express", "value": "node-express" }
]
},
{
"type": "checkbox",
"name": "features",
"message": "Select features to include:",
"choices": ["ESLint", "Prettier", "Husky", "Jest", "Docker"],
"when": "answers.template !== 'node-express'"
},
{
"type": "confirm",
"name": "installDeps",
"message": "Install dependencies now?",
"default": true
}
]
}
Output Structure
prompts/
├── <flowName>/
│ ├── index.ts # Main prompt flow
│ ├── types.ts # TypeScript interfaces
│ ├── validators.ts # Validation functions
│ ├── formatters.ts # Custom formatters
│ └── README.md # Usage documentation
Generated Code Patterns
Prompt Flow (index.ts)
import { input, select, checkbox, confirm } from '@inquirer/prompts';
import { validateProjectName, validatePort } from './validators';
import type { ProjectConfig } from './types';
export async function createProjectPrompt(): Promise<ProjectConfig> {
// Project name
const projectName = await input({
message: 'What is your project name?',
default: 'my-project',
validate: validateProjectName,
});
// Template selection
const template = await select({
message: 'Select a template:',
choices: [
{ name: 'React + TypeScript', value: 'react-ts' },
{ name: 'Vue + TypeScript', value: 'vue-ts' },
{ name: 'Node.js + Express', value: 'node-express' },
],
});
// Conditional features (not shown for node-express)
let features: string[] = [];
if (template !== 'node-express') {
features = await checkbox({
message: 'Select features to include:',
choices: [
{ name: 'ESLint', value: 'eslint', checked: true },
{ name: 'Prettier', value: 'prettier', checked: true },
{ name: 'Husky', value: 'husky' },
{ name: 'Jest', value: 'jest' },
{ name: 'Docker', value: 'docker' },
],
});
}
// Confirmation
const installDeps = await confirm({
message: 'Install dependencies now?',
default: true,
});
return {
projectName,
template,
features,
installDeps,
};
}
TypeScript Types (types.ts)
/**
* Configuration collected from create-project prompts
*/
export interface ProjectConfig {
/** Project name (lowercase, hyphens allowed) */
projectName: string;
/** Selected project template */
template: 'react-ts' | 'vue-ts' | 'node-express';
/** Selected optional features */
features: Array<'eslint' | 'prettier' | 'husky' | 'jest' | 'docker'>;
/** Whether to install dependencies */
installDeps: boolean;
}
/**
* Template metadata for display
*/
export interface TemplateChoice {
name: string;
value: ProjectConfig['template'];
description?: string;
}
Validators (validators.ts)
/**
* Validate project name format
* - Must start with lowercase letter
* - Only lowercase letters, numbers, and hyphens
* - Max 50 characters
*/
export function validateProjectName(value: string): string | true {
if (!value.trim()) {
return 'Project name is required';
}
if (!/^[a-z][a-z0-9-]*$/.test(value)) {
return 'Project name must start with a letter and contain only lowercase letters, numbers, and hyphens';
}
if (value.length > 50) {
return 'Project name must be 50 characters or less';
}
return true;
}
/**
* Validate port number
*/
export function validatePort(value: string): string | true {
const port = parseInt(value, 10);
if (isNaN(port)) {
return 'Port must be a number';
}
if (port < 1024 || port > 65535) {
return 'Port must be between 1024 and 65535';
}
return true;
}
/**
* Validate URL format
*/
export function validateUrl(value: string): string | true {
try {
new URL(value);
return true;
} catch {
return 'Please enter a valid URL';
}
}
/**
* Create async validator that checks for conflicts
*/
export function createConflictValidator(
checkFn: (value: string) => Promise<boolean>
): (value: string) => Promise<string | true> {
return async (value: string) => {
const exists = await checkFn(value);
if (exists) {
return `"${value}" already exists`;
}
return true;
};
}
Custom Formatters (formatters.ts)
import chalk from 'chalk';
/**
* Format project name for display
*/
export function formatProjectName(value: string): string {
return chalk.cyan(value);
}
/**
* Format feature list for summary
*/
export function formatFeatures(features: string[]): string {
if (features.length === 0) {
return chalk.dim('None selected');
}
return features.map(f => chalk.green(`+ ${f}`)).join('\n');
}
/**
* Format configuration summary
*/
export function formatSummary(config: ProjectConfig): string {
return `
${chalk.bold('Project Configuration:')}
${chalk.dim('Name:')} ${formatProjectName(config.projectName)}
${chalk.dim('Template:')} ${config.template}
${chalk.dim('Features:')}
${formatFeatures(config.features).split('\n').map(l => ' ' + l).join('\n')}
${chalk.dim('Install:')} ${config.installDeps ? chalk.green('Yes') : chalk.yellow('No')}
`;
}
Prompt Types
| Type | Description | Use Case |
|---|---|---|
| input | Single-line text | Names, values |
| password | Hidden input | Secrets, tokens |
| number | Numeric input | Ports, counts |
| confirm | Yes/No | Confirmations |
| select | Single choice list | Options |
| checkbox | Multiple choice | Features |
| expand | Abbreviated choices | Quick actions |
| editor | Multi-line editor | Long text |
| search | Searchable list | Large lists |
| rawlist | Numbered list | Indexed options |
Validation Patterns
Required Field
validate: (value) => value.trim() ? true : 'This field is required'
Pattern Matching
validate: (value) => /^[a-z-]+$/.test(value) || 'Invalid format'
Async Validation
validate: async (value) => {
const exists = await checkExists(value);
return exists ? 'Already exists' : true;
}
Dependent Validation
validate: (value, answers) => {
if (answers.type === 'advanced' && !value) {
return 'Required for advanced mode';
}
return true;
}
Conditional Prompts
When Function
{
type: 'input',
name: 'apiKey',
message: 'Enter API key:',
when: (answers) => answers.useExternalApi
}
Skip Logic
const prompts = basePrompts.filter(p => {
if (p.name === 'advanced' && !options.showAdvanced) {
return false;
}
return true;
});
Workflow
- Parse prompt definitions - Validate structure
- Generate prompt flow - Create main prompt file
- Generate types - TypeScript interfaces
- Generate validators - Validation functions
- Generate formatters - Display helpers
- Create documentation - Usage guide
Best Practices Applied
- Modern @inquirer/prompts API
- Reusable validation functions
- Type-safe answer interfaces
- Conditional flow support
- Custom formatters for output
- Clear error messages
References
- Inquirer.js: https://github.com/SBoudrias/Inquirer.js
- @inquirer/prompts: https://www.npmjs.com/package/@inquirer/prompts
- Chalk: https://github.com/chalk/chalk
Target Processes
- interactive-prompt-system
- interactive-form-implementation
- cli-application-bootstrap
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
gsd-tools
Central utility skill for GSD operations. Provides config parsing, slug generation, timestamps, path operations, and orchestrates calls to other specialized skills. Acts as the unified entry point that the original gsd-tools.cjs provided via its lib/ modules (commands, config, core, init).
model-profile-resolution
Resolve model profile (quality/balanced/budget) at orchestration start and map agents to specific models. Enables cost/quality tradeoffs by selecting appropriate AI models for each agent role.
verification-suite
Plan structure validation, phase completeness checks, reference integrity verification, and artifact existence confirmation. Provides the structured verification layer ensuring GSD artifacts are well-formed and complete.
state-management
STATE.md reading, writing, and field-level updates. Provides cross-session state persistence via .planning/STATE.md with structured fields for current task, completed phases, blockers, decisions, and quick tasks.
git-integration
Git commit patterns, formats, and conventions for GSD methodology. Provides atomic commits per task, structured commit messages, planning file commits, branch management, and milestone tag operations.
frontmatter-parsing
YAML frontmatter parsing and manipulation for .planning/ documents. Provides read, write, update, query, and validation operations on frontmatter blocks in GSD markdown artifacts.
Didn't find tool you were looking for?