Claude-skill-registry create-questions
Build interactive CLI questionnaires with validation, conditional logic, parameter mapping, and review capabilities using the question-and-answer library
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/create-questions" ~/.claude/skills/majiayu000-claude-skill-registry-create-questions && rm -rf "$T"
skills/data/create-questions/SKILL.mdQuestion 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:
- The question textprompt
- Variable name to store the answerparameter
Questions MAY have:
- "boolean", "integer", "numeric", or "string" (default)type
- Default valuedefault
- Array of choices (creates selection menu)options
- Boolean, allows multiple comma-separated answersmultiValue
- Custom separator for multiValue (default: comma)separator
- Expression; skip if falsycondition
- Object with validation rulesvalidations
- Boolean, ask even if parameter already definednoSkipDefined
{ 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
- String lengthmax-length
,min-value
- Numeric rangemax-value
,min-count
- Multi-value countmax-count
- Exact match requiredrequire-exact
,require-truthy
- Boolean validationrequire-falsy
- Regular expression patternmatch-regexp
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:
or"boolean"
- Accepts: y/yes/true/n/no/false (case-insensitive)"bool"
or"integer"
- Whole numbers only"int"
or"numeric"
- Decimal numbers"float"
- Default, no coercion"string"
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
for non-string data to ensure proper coerciontype - 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:
- Complete API referencereference.md
- Common implementation patternspatterns.md
- Working interrogation bundlesexamples/
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
before integrationnpx qna bundle.json
Error Handling
The library throws standard errors:
- Validation failedArgumentInvalidError
- Required field missingArgumentMissingError
- Type mismatchArgumentTypeError
Always wrap
questioner.question() in try-catch for production use.