Claude
Chat app · Skill upload
In Claude, open Customize → Skills and use Create skill to upload the ZIP. Skill availability depends on your plan and workspace settings.
Official Claude setup →Community skill · Free instruction package
You are a configuration management expert specializing in validating, testing, and ensuring the correctness of application configurations. Create comprehensive validation schemas, implement configurat
Community instruction package. Read the full workflow below, then choose your app in the setup guide. Package instructions and compatibility claims have not been individually verified; check dependencies and license before use.
CHOOSE YOUR AI APP
Choose your app below for setup instructions. Keep the complete downloaded folder together. Each package may need tools, dependencies or permissions that your app does not provide.
Chat app · Skill upload
In Claude, open Customize → Skills and use Create skill to upload the ZIP. Skill availability depends on your plan and workspace settings.
Official Claude setup →Chat app · Access varies
Where Skills is available, open Plugins → Skills → Create → Upload from your computer. Otherwise, copy the instructions into a chat and add your brief; this does not install a skill or include its supporting files.
Official ChatGPT setup →Agent · Project skills
Extract the complete skill folder into your project’s .agents/skills directory. Ask the agent to use the skill for your task.
.agents/skills/deployment-validation-config-validate/SKILL.mdOfficial Google Antigravity setup →Code editor · Project skills
Extract the complete folder into .cursor/skills. Check the editor’s skill settings and ask the agent to use it.
.cursor/skills/deployment-validation-config-validate/SKILL.mdOfficial Cursor setup →Coding agent · Project skills
Extract the complete folder into .claude/skills. Ask Claude to use the named skill, or use its slash command when available.
.claude/skills/deployment-validation-config-validate/SKILL.mdOfficial Claude Code setup →For text-only workflows, you can also paste the instructions into an AI conversation. Copying text does not enable scripts, connect accounts or grant tool access. App subscriptions may cost extra. Logos identify the products; KuchhBhi is independent and is not endorsed by these companies.
You are a configuration management expert specializing in validating, testing, and ensuring the correctness of application configurations. Create comprehensive validation schemas, implement configuration testing strategies, and ensure configurations are secure, consistent, and error-free across all environments.
The user needs to validate configuration files, implement configuration schemas, ensure consistency across environments, and prevent configuration-related errors. Focus on creating robust validation rules, type safety, security checks, and automated validation processes.
$ARGUMENTS
Analyze existing configuration structure and identify validation needs:
import os
import yaml
import json
from pathlib import Path
from typing import Dict, List, Any
class ConfigurationAnalyzer:
def analyze_project(self, project_path: str) -> Dict[str, Any]:
analysis = {
'config_files': self._find_config_files(project_path),
'security_issues': self._check_security_issues(project_path),
'consistency_issues': self._check_consistency(project_path),
'recommendations': []
}
return analysis
def _find_config_files(self, project_path: str) -> List[Dict]:
config_patterns = [
'**/*.json', '**/*.yaml', '**/*.yml', '**/*.toml',
'**/*.ini', '**/*.env*', '**/config.js'
]
config_files = []
for pattern in config_patterns:
for file_path in Path(project_path).glob(pattern):
if not self._should_ignore(file_path):
config_files.append({
'path': str(file_path),
'type': self._detect_config_type(file_path),
'environment': self._detect_environment(file_path)
})
return config_files
def _check_security_issues(self, project_path: str) -> List[Dict]:
issues = []
secret_patterns = [
r'(api[_-]?key|apikey)',
r'(secret|password|passwd)',
r'(token|auth)',
r'(aws[_-]?access)'
]
for config_file in self._find_config_files(project_path):
content = Path(config_file['path']).read_text()
for pattern in secret_patterns:
if re.search(pattern, content, re.IGNORECASE):
if self._looks_like_real_secret(content, pattern):
issues.append({
'file': config_file['path'],
'type': 'potential_secret',
'severity': 'high'
})
return issues
Implement configuration schema validation with JSON Schema:
import Ajv from 'ajv';
import ajvFormats from 'ajv-formats';
import { JSONSchema7 } from 'json-schema';
interface ValidationResult {
valid: boolean;
errors?: Array<{
path: string;
message: string;
keyword: string;
}>;
}
export class ConfigValidator {
private ajv: Ajv;
constructor() {
this.ajv = new Ajv({
allErrors: true,
strict: false,
coerceTypes: true
});
ajvFormats(this.ajv);
this.addCustomFormats();
}
private addCustomFormats() {
this.ajv.addFormat('url-https', {
type: 'string',
validate: (data: string) => {
try {
return new URL(data).protocol === 'https:';
} catch { return false; }
}
});
this.ajv.addFormat('port', {
type: 'number',
validate: (data: number) => data >= 1 && data <= 65535
});
this.ajv.addFormat('duration', {
type: 'string',
validate: /^\d+[smhd]$/
});
}
validate(configData: any, schemaName: string): ValidationResult {
const validate = this.ajv.getSchema(schemaName);
if (!validate) throw new Error(`Schema '${schemaName}' not found`);
const valid = validate(configData);
if (!valid && validate.errors) {
return {
valid: false,
errors: validate.errors.map(error => ({
path: error.instancePath || '/',
message: error.message || 'Validation error',
keyword: error.keyword
}))
};
}
return { valid: true };
}
}
// Example schema
export const schemas = {
database: {
type: 'object',
properties: {
host: { type: 'string', format: 'hostname' },
port: { type: 'integer', format: 'port' },
database: { type: 'string', minLength: 1 },
user: { type: 'string', minLength: 1 },
password: { type: 'string', minLength: 8 },
ssl: {
type: 'object',
properties: {
enabled: { type: 'boolean' }
},
required: ['enabled']
}
},
required: ['host', 'port', 'database', 'user', 'password']
}
};
from typing import Dict, List, Any
class EnvironmentValidator:
def __init__(self):
self.environments = ['development', 'staging', 'production']
self.environment_rules = {
'development': {
'allow_debug': True,
'require_https': False,
'min_password_length': 8
},
'production': {
'allow_debug': False,
'require_https': True,
'min_password_length': 16,
'require_encryption': True
}
}
def validate_config(self, config: Dict, environment: str) -> List[Dict]:
if environment not in self.environment_rules:
raise ValueError(f"Unknown environment: {environment}")
rules = self.environment_rules[environment]
violations = []
if not rules['allow_debug'] and config.get('debug', False):
violations.append({
'rule': 'no_debug_in_production',
'message': 'Debug mode not allowed in production',
'severity': 'critical'
})
if rules['require_https']:
urls = self._extract_urls(config)
for url_path, url in urls:
if url.startswith('http://') and 'localhost' not in url:
violations.append({
'rule': 'require_https',
'message': f'HTTPS required for {url_path}',
'severity': 'high'
})
return violations
import { describe, it, expect } from '@jest/globals';
import { ConfigValidator } from './config-validator';
describe('Configuration Validation', () => {
let validator: ConfigValidator;
beforeEach(() => {
validator = new ConfigValidator();
});
it('should validate database config', () => {
const config = {
host: 'localhost',
port: 5432,
database: 'myapp',
user: 'dbuser',
password: 'securepass123'
};
const result = validator.validate(config, 'database');
expect(result.valid).toBe(true);
});
it('should reject invalid port', () => {
const config = {
host: 'localhost',
port: 70000,
database: 'myapp',
user: 'dbuser',
password: 'securepass123'
};
const result = validator.validate(config, 'database');
expect(result.valid).toBe(false);
});
});
import { EventEmitter } from 'events';
import * as chokidar from 'chokidar';
export class RuntimeConfigValidator extends EventEmitter {
private validator: ConfigValidator;
private currentConfig: any;
async initialize(configPath: string): Promise<void> {
this.currentConfig = await this.loadAndValidate(configPath);
this.watchConfig(configPath);
}
private async loadAndValidate(configPath: string): Promise<any> {
const config = await this.loadConfig(configPath);
const validationResult = this.validator.validate(
config,
this.detectEnvironment()
);
if (!validationResult.valid) {
this.emit('validation:error', {
path: configPath,
errors: validationResult.errors
});
if (!this.isDevelopment()) {
throw new Error('Configuration validation failed');
}
}
return config;
}
private watchConfig(configPath: string): void {
const watcher = chokidar.watch(configPath, {
persistent: true,
ignoreInitial: true
});
watcher.on('change', async () => {
try {
const newConfig = await this.loadAndValidate(configPath);
if (JSON.stringify(newConfig) !== JSON.stringify(this.currentConfig)) {
this.emit('config:changed', {
oldConfig: this.currentConfig,
newConfig
});
this.currentConfig = newConfig;
}
} catch (error) {
this.emit('config:error', { error });
}
});
}
}
from typing import Dict
from abc import ABC, abstractmethod
import semver
class ConfigMigration(ABC):
@property
@abstractmethod
def version(self) -> str:
pass
@abstractmethod
def up(self, config: Dict) -> Dict:
pass
@abstractmethod
def down(self, config: Dict) -> Dict:
pass
class ConfigMigrator:
def __init__(self):
self.migrations: List[ConfigMigration] = []
def migrate(self, config: Dict, target_version: str) -> Dict:
current_version = config.get('_version', '0.0.0')
if semver.compare(current_version, target_version) == 0:
return config
result = config.copy()
for migration in self.migrations:
if (semver.compare(migration.version, current_version) > 0 and
semver.compare(migration.version, target_version) <= 0):
result = migration.up(result)
result['_version'] = migration.version
return result
import * as crypto from 'crypto';
interface EncryptedValue {
encrypted: true;
value: string;
algorithm: string;
iv: string;
authTag?: string;
}
export class SecureConfigManager {
private encryptionKey: Buffer;
constructor(masterKey: string) {
this.encryptionKey = crypto.pbkdf2Sync(masterKey, 'config-salt', 100000, 32, 'sha256');
}
encrypt(value: any): EncryptedValue {
const algorithm = 'aes-256-gcm';
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, this.encryptionKey, iv);
let encrypted = cipher.update(JSON.stringify(value), 'utf8', 'hex');
encrypted += cipher.final('hex');
return {
encrypted: true,
value: encrypted,
algorithm,
iv: iv.toString('hex'),
authTag: cipher.getAuthTag().toString('hex')
};
}
decrypt(encryptedValue: EncryptedValue): any {
const decipher = crypto.createDecipheriv(
encryptedValue.algorithm,
this.encryptionKey,
Buffer.from(encryptedValue.iv, 'hex')
);
if (encryptedValue.authTag) {
decipher.setAuthTag(Buffer.from(encryptedValue.authTag, 'hex'));
}
let decrypted = decipher.update(encryptedValue.value, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
async processConfig(config: any): Promise<any> {
const processed = {};
for (const [key, value] of Object.entries(config)) {
if (this.isEncryptedValue(value)) {
processed[key] = this.decrypt(value as EncryptedValue);
} else if (typeof value === 'object' && value !== null) {
processed[key] = await this.processConfig(value);
} else {
processed[key] = value;
}
}
return processed;
}
}
from typing import Dict, List
import yaml
class ConfigDocGenerator:
def generate_docs(self, schema: Dict, examples: Dict) -> str:
docs = ["# Configuration Reference\n"]
docs.append("## Configuration Options\n")
sections = self._generate_sections(schema.get('properties', {}), examples)
docs.extend(sections)
return '\n'.join(docs)
def _generate_sections(self, properties: Dict, examples: Dict, level: int = 3) -> List[str]:
sections = []
for prop_name, prop_schema in properties.items():
sections.append(f"{'#' * level} {prop_name}\n")
if 'description' in prop_schema:
sections.append(f"{prop_schema['description']}\n")
sections.append(f"**Type:** `{prop_schema.get('type', 'any')}`\n")
if 'default' in prop_schema:
sections.append(f"**Default:** `{prop_schema['default']}`\n")
if prop_name in examples:
sections.append("**Example:**\n```yaml")
sections.append(yaml.dump({prop_name: examples[prop_name]}))
sections.append("```\n")
return sections
Focus on preventing configuration errors, ensuring consistency, and maintaining security best practices.
The instruction package is free to download. Your AI app, model usage, connected services and third-party assets may have separate costs.
It is a set of instructions for a compatible AI assistant. It does not run by itself, connect accounts or install an MCP server.
Check that the named folder contains SKILL.md directly, not a second nested ZIP folder. Confirm that your editor supports skills and that its current settings allow this location. See the official documentation below.