| name | create-questions |
| description | Build interactive CLI questionnaires with validation, conditional logic, parameter mapping, and review capabilities using the question-and-answer library |
Question and Answer Library Integration
You are helping developers integrate the question-and-answer library into their Node.js projects. This library provides command-line question and answer functionality for building interactive CLI interrogations.
When to Use This Skill
Use this skill when the user wants to:
- Create interactive CLI questionnaires or wizards
- Build user onboarding flows
- Generate configuration files interactively
- Collect user input with validation
- Create surveys or forms in CLI applications
- Implement conditional question flows
Installation
npm install question-and-answer
Core Architecture
The library centers on the Questioner class, which processes an interrogation bundle - an array of actions that execute sequentially. Each action is one of four types:
- Question - Prompts user for input and stores in a parameter
- Statement - Displays text to the user
- Map - Derives new parameters from existing ones using expressions
- Review - Allows user to review and modify previous answers
Basic Implementation Pattern
import { Questioner } from 'question-and-answer'
const interactions = [
// Array of action objects
]
const questioner = new Questioner({ interactions })
await questioner.question()
// Access results
const value = questioner.get('PARAMETER_NAME')
Action Types
Question Actions
Questions MUST have:
prompt- The question textparameter- Variable name to store the answer
Questions MAY have:
type- "boolean", "integer", "numeric", or "string" (default)default- Default valueoptions- Array of choices (creates selection menu)multiValue- Boolean, allows multiple comma-separated answersseparator- Custom separator for multiValue (default: comma)condition- Expression; skip if falsyvalidations- Object with validation rulesnoSkipDefined- Boolean, ask even if parameter already defined
{
prompt: "What is your name?",
parameter: "USER_NAME"
}
{
prompt: "Choose a color",
options: ["red", "blue", "green"],
parameter: "COLOR"
}
{
prompt: "Enable debug mode?",
type: "boolean",
parameter: "DEBUG",
default: false
}
Statement Actions
Statements display text without user input:
{
statement: "Welcome to the configuration wizard!"
}
{
statement: "<warn>Warning:<rst> This will overwrite existing files",
condition: "FILES_EXIST === true"
}
Map Actions
Maps derive new parameters from existing ones:
{
maps: [
{
source: "AGE >= 18",
parameter: "IS_ADULT",
type: "boolean"
},
{
source: "PRICE * QUANTITY",
parameter: "TOTAL",
type: "numeric"
},
{
value: "literal-value",
parameter: "CONSTANT"
}
]
}
Maps use condition-eval syntax for source expressions.
Review Actions
Reviews let users verify and modify answers:
{
review: "questions" // Only review questions
}
{
review: "maps" // Only review maps
}
{
review: "all" // Review both
}
During review:
- Press ENTER to accept current value
- Enter new value to change
- Enter
-to clear value - If rejected, interrogation restarts
Validation
Use the validations object with specify-string format:
{
prompt: "Enter email",
parameter: "EMAIL",
validations: {
"match-regexp": "^[^@]+@[^@]+\\.[^@]+$"
}
}
{
prompt: "Rate 1-10",
type: "integer",
parameter: "RATING",
validations: {
"min-value": 1,
"max-value": 10
}
}
{
prompt: "Select 2-3 options",
multiValue: true,
options: ["A", "B", "C", "D"],
parameter: "CHOICES",
validations: {
"min-count": 2,
"max-count": 3
}
}
Common validation keys:
min-length,max-length- String lengthmin-value,max-value- Numeric rangemin-count,max-count- Multi-value countrequire-exact- Exact match requiredrequire-truthy,require-falsy- Boolean validationmatch-regexp- Regular expression pattern
Conditional Logic
Any action can have a condition field with an expression:
{
prompt: "Enter API key",
parameter: "API_KEY",
condition: "ENVIRONMENT === 'production'"
}
{
statement: "Debug mode is enabled",
condition: "DEBUG === true"
}
Conditions use condition-eval syntax and can reference any previously set parameter.
Type System
The type field coerces answers:
"boolean"or"bool"- Accepts: y/yes/true/n/no/false (case-insensitive)"integer"or"int"- Whole numbers only"numeric"or"float"- Decimal numbers"string"- Default, no coercion
Accessing Results
// Single value
const name = questioner.get('USER_NAME')
// Full result object (includes metadata)
const result = questioner.getResult('USER_NAME')
// Check existence
if (questioner.has('EMAIL')) { ... }
// All values as object
const values = questioner.values
// All results (with metadata)
const results = questioner.results
// Interrogation with dispositions
const interactions = questioner.interactions
Constructor Options
const questioner = new Questioner({
interactions, // Required: array of actions
initialParameters: {}, // Optional: pre-populated values
noSkipDefined: false, // Optional: ask defined questions
input: process.stdin, // Optional: custom input stream
output: customOutput, // Optional: custom output handler
printOptions: {} // Optional: magic-print options
})
Implementation Guidelines
1. Start Simple
Begin with basic questions, add complexity incrementally:
const interactions = [
{ prompt: "Project name", parameter: "NAME" },
{ prompt: "Version", parameter: "VERSION", default: "1.0.0" }
]
2. Add Validation
Layer in validation for data quality:
{
prompt: "Project name",
parameter: "NAME",
validations: {
"min-length": 1,
"max-length": 50,
"match-regexp": "^[a-z0-9-]+$"
}
}
3. Use Options for Fixed Choices
When answers are constrained, use options:
{
prompt: "License",
options: ["MIT", "Apache-2.0", "GPL-3.0", "ISC"],
parameter: "LICENSE"
}
4. Add Conditional Logic
Build dynamic flows with conditions:
{
prompt: "Use TypeScript?",
type: "boolean",
parameter: "USE_TS"
},
{
prompt: "TypeScript version",
parameter: "TS_VERSION",
default: "latest",
condition: "USE_TS === true"
}
5. Derive Computed Values
Use maps for calculated parameters:
{
maps: [
{
source: "USE_TS === true",
parameter: "FILE_EXTENSION",
value: "ts"
},
{
source: "USE_TS === false",
parameter: "FILE_EXTENSION",
value: "js"
}
]
}
6. End with Review
Let users verify their answers:
{ review: "questions" }
Common Patterns
See patterns.md for detailed examples of:
- User onboarding flows
- Configuration wizards
- Surveys with validation
- Conditional branching
- Multi-value inputs
Testing Interrogations
Test bundles using the CLI:
npx qna path/to/interrogation.json
Important Notes
- Action Order Matters - Actions execute sequentially; parameters must be defined before use in conditions/maps
- Parameter Skipping - Questions/maps skip if parameter already defined (unless
noSkipDefined: true) - Condition Evaluation - Uses condition-eval library; supports comparisons, arithmetic, logical operators
- Type Safety - Always specify
typefor non-string data to ensure proper coercion - Review Behavior - Reviews collect all non-skipped questions/maps since last review
- Validation Timing - Validations run immediately; invalid answers re-prompt
Reference Materials
When you need detailed information, refer to:
reference.md- Complete API referencepatterns.md- Common implementation patternsexamples/- Working interrogation bundles
Code Generation
When generating interrogation bundles:
- Wrap in proper structure:
{ "actions": [...] } - Use consistent parameter naming (UPPER_SNAKE_CASE recommended)
- Add validations for data quality
- Include review step for important flows
- Test with
npx qna bundle.jsonbefore integration
Error Handling
The library throws standard errors:
ArgumentInvalidError- Validation failedArgumentMissingError- Required field missingArgumentTypeError- Type mismatch
Always wrap questioner.question() in try-catch for production use.