Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Generate argument validation logic with type coercion, constraints, custom validators, and helpful error messages for CLI applications.
.claude/skills/a5c-ai-argument-validator-generator/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 68% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 41% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 13% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 143% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 56% | 0% |
Generate comprehensive argument validation logic for CLI applications with type coercion and constraint checking.
Invoke this skill when you need to:
| 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 |
json{ "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" } } ] }
typescriptimport { 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); }
pythonfrom 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
gopackage 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), } }
typescript// 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}` }) );
typescript// 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' );
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 13,863 | 11,559 | -17% | 1 | 1 | 0% | 3,139 | 4,636 | +48% | 0 | 0 | — |
case-02 | fail→pass | 15,269 | 11,576 | -24% | 1 | 1 | 0% | 2,659 | 4,462 | +68% | 0 | 0 | — |
case-03 | fail→pass | 14,494 | 9,722 | -33% | 1 | 1 | 0% | 2,835 | 3,997 | +41% | 0 | 0 | — |
case-04 | fail→pass | 15,372 | 8,048 | -48% | 1 | 1 | 0% | 3,130 | 3,542 | +13% | 0 | 0 | — |
case-05 | fail→fail | 12,863 | 20,161 | +57% | 1 | 1 | 0% | 2,822 | 5,663 | +101% | 0 | 0 | — |
case-06 | fail→pass | 6,538 | 6,257 | -4% | 1 | 1 | 0% | 1,389 | 3,371 | +143% | 0 | 0 | — |
case-07 | pass→pass | 9,873 | 8,186 | -17% | 1 | 1 | 0% | 1,985 | 3,671 | +85% | 0 | 0 | — |
case-08 | fail→fail | 9,217 | 8,166 | -11% | 1 | 1 | 0% | 1,906 | 3,335 | +75% | 0 | 0 | — |
case-09 | fail→pass | 12,992 | 7,532 | -42% | 1 | 1 | 0% | 2,181 | 3,400 | +56% | 0 | 0 | — |
case-10 | fail→fail | 9,963 | 6,332 | -36% | 1 | 1 | 0% | 2,040 | 3,213 | +57% | 0 | 0 | — |
case-11 | fail→pass | 13,969 | 9,809 | -30% | 1 | 1 | 0% | 2,875 | 3,928 | +37% | 0 | 0 | — |
case-12 | fail→fail | 7,746 | 7,390 | -5% | 1 | 1 | 0% | 1,640 | 3,544 | +116% | 0 | 0 | — |
case-13 | fail→pass | 11,737 | 8,766 | -25% | 1 | 1 | 0% | 1,947 | 3,744 | +92% | 0 | 0 | — |
case-14 | fail→fail | 11,479 | 6,370 | -45% | 1 | 1 | 0% | 1,449 | 3,371 | +133% | 0 | 0 | — |
case-15 | fail→fail | 8,858 | 7,074 | -20% | 1 | 1 | 0% | 1,630 | 3,238 | +99% | 0 | 0 | — |
case-16 | fail→pass | 13,711 | 13,167 | -4% | 1 | 1 | 0% | 2,688 | 4,770 | +77% | 0 | 0 | — |
case-17 | fail→pass | 9,200 | 7,211 | -22% | 1 | 1 | 0% | 1,917 | 3,374 | +76% | 0 | 0 | — |
case-18 | fail→fail | 7,194 | 14,295 | +99% | 1 | 1 | 0% | 1,557 | 4,450 | +186% | 0 | 0 | — |
case-19 | fail→pass | 8,148 | 6,618 | -19% | 1 | 1 | 0% | 1,294 | 3,161 | +144% | 0 | 0 | — |
case-20 | fail→fail | 7,407 | 12,063 | +63% | 1 | 1 | 0% | 1,622 | 4,543 | +180% | 0 | 0 | — |
case-21 | fail→fail | 10,282 | 7,228 | -30% | 1 | 1 | 0% | 1,806 | 3,309 | +83% | 0 | 0 | — |
case-22 | fail→fail | 6,166 | 6,725 | +9% | 1 | 1 | 0% | 1,233 | 2,922 | +137% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +45 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.