Agent skill
argument-validator-generator
Generate argument validation logic with type coercion, constraints, custom validators, and helpful error messages 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/argument-validator-generator
SKILL.md
Argument Validator Generator
Generate comprehensive argument validation logic for CLI applications with type coercion and constraint checking.
Capabilities
- Generate type coercion functions for arguments
- Create custom validators with constraint checking
- Set up validation error messages
- Implement value normalization
- Configure mutually exclusive validation
- Generate validation schemas
Usage
Invoke this skill when you need to:
- Add type validation to CLI arguments
- Create custom argument validators
- Implement complex constraint checking
- Generate helpful validation error messages
Inputs
| Parameter | Type | Required | Description |
|---|---|---|---|
| language | string | Yes | Target language (typescript, python, go, rust) |
| validators | array | Yes | List of validators to generate |
| outputPath | string | No | Output path for generated files |
Validator Structure
{
"validators": [
{
"name": "port",
"type": "number",
"constraints": {
"min": 1,
"max": 65535
},
"errorMessage": "Port must be between 1 and 65535"
},
{
"name": "email",
"type": "string",
"pattern": "^[\\w.-]+@[\\w.-]+\\.\\w+$",
"errorMessage": "Invalid email format"
},
{
"name": "environment",
"type": "enum",
"values": ["development", "staging", "production"],
"aliases": { "dev": "development", "prod": "production" }
}
]
}
Generated Code Patterns
TypeScript Validators
import { z } from 'zod';
// Port validator
export const portSchema = z
.number()
.int()
.min(1, 'Port must be at least 1')
.max(65535, 'Port must be at most 65535');
export function validatePort(value: unknown): number {
const parsed = typeof value === 'string' ? parseInt(value, 10) : value;
return portSchema.parse(parsed);
}
// Email validator
export const emailSchema = z
.string()
.email('Invalid email format')
.toLowerCase();
export function validateEmail(value: unknown): string {
return emailSchema.parse(value);
}
// Environment enum with aliases
const envAliases: Record<string, string> = {
dev: 'development',
prod: 'production',
};
export const environmentSchema = z
.string()
.transform((val) => envAliases[val] || val)
.pipe(z.enum(['development', 'staging', 'production']));
export function validateEnvironment(value: unknown): string {
return environmentSchema.parse(value);
}
Python Validators
from typing import Any, List, Optional, Union
import re
class ValidationError(Exception):
"""Raised when validation fails."""
pass
def validate_port(value: Any) -> int:
"""Validate port number."""
try:
port = int(value)
except (TypeError, ValueError):
raise ValidationError(f"Invalid port number: {value}")
if not 1 <= port <= 65535:
raise ValidationError("Port must be between 1 and 65535")
return port
def validate_email(value: Any) -> str:
"""Validate email address."""
if not isinstance(value, str):
raise ValidationError(f"Email must be a string, got {type(value).__name__}")
pattern = r'^[\w.-]+@[\w.-]+\.\w+$'
if not re.match(pattern, value):
raise ValidationError("Invalid email format")
return value.lower()
ENV_ALIASES = {'dev': 'development', 'prod': 'production'}
VALID_ENVIRONMENTS = ['development', 'staging', 'production']
def validate_environment(value: Any) -> str:
"""Validate environment name."""
if not isinstance(value, str):
raise ValidationError(f"Environment must be a string")
normalized = ENV_ALIASES.get(value, value)
if normalized not in VALID_ENVIRONMENTS:
raise ValidationError(
f"Invalid environment: {value}. "
f"Must be one of: {', '.join(VALID_ENVIRONMENTS)}"
)
return normalized
Go Validators
package validators
import (
"fmt"
"regexp"
"strconv"
"strings"
)
// ValidationError represents a validation failure
type ValidationError struct {
Field string
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Message)
}
// ValidatePort validates a port number
func ValidatePort(value string) (int, error) {
port, err := strconv.Atoi(value)
if err != nil {
return 0, &ValidationError{
Field: "port",
Message: fmt.Sprintf("invalid port number: %s", value),
}
}
if port < 1 || port > 65535 {
return 0, &ValidationError{
Field: "port",
Message: "port must be between 1 and 65535",
}
}
return port, nil
}
// ValidateEmail validates an email address
func ValidateEmail(value string) (string, error) {
pattern := `^[\w.-]+@[\w.-]+\.\w+$`
matched, _ := regexp.MatchString(pattern, value)
if !matched {
return "", &ValidationError{
Field: "email",
Message: "invalid email format",
}
}
return strings.ToLower(value), nil
}
var envAliases = map[string]string{
"dev": "development",
"prod": "production",
}
var validEnvironments = []string{"development", "staging", "production"}
// ValidateEnvironment validates environment name
func ValidateEnvironment(value string) (string, error) {
if alias, ok := envAliases[value]; ok {
value = alias
}
for _, env := range validEnvironments {
if env == value {
return value, nil
}
}
return "", &ValidationError{
Field: "environment",
Message: fmt.Sprintf("invalid environment: %s", value),
}
}
Validation Patterns
Composite Validators
// URL with specific protocol
export const apiUrlSchema = z
.string()
.url()
.refine(
(url) => url.startsWith('https://'),
'API URL must use HTTPS'
);
// File path that must exist
export const existingFileSchema = z
.string()
.refine(
(path) => fs.existsSync(path),
(path) => ({ message: `File not found: ${path}` })
);
Dependent Validation
// Validate that end date is after start date
export const dateRangeSchema = z.object({
startDate: z.coerce.date(),
endDate: z.coerce.date(),
}).refine(
(data) => data.endDate > data.startDate,
'End date must be after start date'
);
Workflow
- Analyze requirements - Review validation needs
- Generate base validators - Type coercion and basic checks
- Add constraints - Min/max, patterns, enums
- Create error messages - Helpful, actionable messages
- Add aliases/transforms - Normalize input values
- Generate tests - Validation test cases
Best Practices Applied
- Type coercion before validation
- Descriptive error messages
- Input normalization (lowercase, trim)
- Alias support for common values
- Composable validation schemas
- Consistent error types
Target Processes
- argument-parser-setup
- error-handling-user-feedback
- cli-command-structure-design
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?