Post-Edit Validation Skill
Validates files after modifications with syntax, formatting, and linting checks.
Overview
The Post-Edit Validation Skill ensures code quality and correctness after edit operations by running configurable validation pipelines. It detects syntax errors, formatting issues, and code quality problems with real-time feedback.
Features
- Multi-Format Support: TypeScript, JavaScript, JSON, Bash, Markdown, Python
- Syntax Validation: Detects syntax errors in JSON and type errors in TypeScript
- Formatting Checks: Detects trailing whitespace, mixed line endings, mixed indentation
- Code Quality: Detects duplication, complexity patterns, and best practice violations
- Configurable Pipeline: Enable/disable checks per file type
- Blocking Mode: Optional enforcement of validation rules
- Non-Blocking Feedback: Warnings and suggestions without blocking workflow
Architecture
Validation Pipeline
File Input
↓
Type Detection (.ts, .js, .json, .sh, etc.)
↓
Type-Specific Validation (syntax, type checking)
↓
Common Checks (formatting, duplication)
↓
Result Aggregation (errors, warnings, suggestions)
↓
Feedback Generation
Configuration
Default config: .claude/hooks/cfn-post-edit.config.json
{
"enabled": true,
"blocking": false,
"validation": {
"typescript": {
"enabled": true,
"noEmit": true,
"skipLibCheck": true
},
"bash": {
"enabled": true,
"validators": ["pipe-safety", "dependency-checker", "line-endings"],
"timeout": 5000
}
},
"feedback": {
"provideSuggestions": true,
"autoFixable": ["LINT_ISSUES"],
"nonBlocking": ["TYPE_WARNING", "LINT_ISSUES", "BASH_VALIDATOR_WARNING"],
"blocking": ["SYNTAX_ERROR", "BASH_VALIDATOR_ERROR"]
}
}
TypeScript API
PostEditValidator Class
import { PostEditValidator, ValidationResult } from '@/hooks/post-edit-validator';
const validator = new PostEditValidator(projectRoot);
// Load configuration
const config = await validator.loadConfig();
// Validate a file
const result: ValidationResult = await validator.validateFile(filePath, agentId);
// Result: {
// passed: true,
// errors: [],
// warnings: ["Mixed tabs and spaces detected"],
// suggestions: ["1 lines have trailing whitespace"],
// timestamp: "2024-11-20T10:30:45.123Z",
// filePath: "/project/src/file.ts",
// executionTime: 145
// }
// Run custom validation pipeline
const customResult = await validator.runValidationPipeline(filePath);
// Get human-readable summary
const summary = validator.getValidationSummary(result);
console.log(summary);
// Output:
// ✅ Validation passed
// Warnings (1):
// - Mixed tabs and spaces detected
// Suggestions (1):
// - 1 lines have trailing whitespace
// Execution time: 145ms
ValidationResult Interface
interface ValidationResult {
passed: boolean; // Overall validation status
errors: string[]; // Blocking issues
warnings: string[]; // Non-blocking concerns
suggestions: string[]; // Improvement recommendations
timestamp: string; // ISO 8601 timestamp
filePath: string; // Validated file path
executionTime: number; // Milliseconds
}
CLI Interface
Post-Edit Hook CLI
Validates file after modification:
# TypeScript compiled version
node dist/cli/post-edit-hook.js /path/to/file.ts
# With agent ID
node dist/cli/post-edit-hook.js /path/to/file.ts --agent-id agent-123
# Blocking mode (exit 1 on failure)
node dist/cli/post-edit-hook.js /path/to/file.ts --blocking
# Output
# {
# "passed": true,
# "errors": [],
# "warnings": [],
# "suggestions": [],
# "timestamp": "2024-11-20T10:30:45.123Z",
# "filePath": "/path/to/file.ts",
# "executionTime": 145
# }
Bash Wrapper
For agent compatibility:
# Primary wrapper (tries TypeScript, falls back to bash)
./.claude/hooks/cfn-invoke-post-edit-ts.sh /path/to/file.ts
# With agent ID
./.claude/hooks/cfn-invoke-post-edit-ts.sh /path/to/file.ts --agent-id agent-123
# Blocking mode
./.claude/hooks/cfn-invoke-post-edit-ts.sh /path/to/file.ts --blocking
# Legacy bash-only wrapper
./.claude/hooks/cfn-invoke-post-edit.sh /path/to/file.ts
Validators by File Type
TypeScript/JavaScript
// Checks:
// - Type errors (via tsc --noEmit)
// - Syntax errors
// - Import/export correctness
// - Undefined symbols
const result = await validator.validateFile('src/component.ts');
if (!result.passed) {
result.errors.forEach(err => console.error(err));
}
JSON
// Checks:
// - JSON syntax validity
// - Schema structure
// - Special character handling
const result = await validator.validateFile('config.json');
// Detects: { invalid json }
Bash Scripts
// Checks:
// - Unquoted variable usage
// - Pipe-to-while-read patterns
// - Missing strict mode (set -euo pipefail)
// - Line endings (LF vs CRLF)
const result = await validator.validateFile('script.sh');
// Warnings: "unquoted variables", "pipe-to-while-read", "missing strict mode"
Formatting Checks (All Types)
// Checks run on all file types:
// - Trailing whitespace
// - Mixed line endings (CRLF + LF)
// - Mixed indentation (tabs + spaces)
const result = await validator.validateFile('any-file.ts');
if (result.warnings.some(w => w.includes('trailing'))) {
// Fix trailing whitespace
}
Duplication Detection
When enabled:
// Checks:
// - Identical consecutive lines (>20 chars)
// - Copy-paste patterns
// - Duplicate functions/methods
const result = await validator.validateFile('file.ts');
result.suggestions.forEach(s => {
if (s.includes('Duplicate')) {
// Consider refactoring duplicated code
}
});
Integration
In Agent Workflows
Post-edit validation is automatically called via hooks after Edit/Write operations:
# After Edit or Write operation
./.claude/hooks/cfn-invoke-post-edit-ts.sh "$FILE_PATH" --agent-id "$AGENT_ID"
# In blocking mode (fails the workflow if validation fails)
./.claude/hooks/cfn-invoke-post-edit-ts.sh "$FILE_PATH" --agent-id "$AGENT_ID" --blocking
Redis Publishing
When enabled, validation results are published to Redis:
{
"channel": "swarm:hooks:post-edit",
"message": {
"file": "/path/to/file.ts",
"agentId": "agent-123",
"exitCode": 0,
"timestamp": "1700000000"
}
}
Use Cases
1. Type Safety
// Catch type errors immediately
const result = await validator.validateFile('app.ts');
if (!result.passed) {
console.error('Type errors detected:');
result.errors.forEach(e => console.error(` - ${e}`));
process.exit(1);
}
2. Code Quality Gates
// Enforce formatting standards
const result = await validator.validateFile('src/utils.ts');
if (result.warnings.length > 0) {
console.warn('Code quality issues found:');
result.warnings.forEach(w => console.warn(` - ${w}`));
}
3. Pre-Commit Validation
#!/bin/bash
# Pre-commit hook
FILES=$(git diff --cached --name-only --diff-filter=ACM)
for file in $FILES; do
result=$(./.claude/hooks/cfn-invoke-post-edit-ts.sh "$file" --blocking)
if [ $? -ne 0 ]; then
echo "Validation failed for $file"
exit 1
fi
done
4. Agent Feedback Loop
// Provide actionable feedback to agents
const result = await validator.validateFile(filePath, agentId);
const summary = validator.getValidationSummary(result);
console.log('Validation Report:');
console.log(summary);
console.log('\nNext Steps:');
if (result.errors.length > 0) {
console.log('Fix errors above before proceeding');
} else if (result.suggestions.length > 0) {
console.log('Consider addressing suggestions for better code quality');
}
Configuration
Enable/Disable Checks
# Disable TypeScript checking
export TS_VALIDATION_ENABLED=false
# Enable formatting checks only
export CHECK_FORMATTING=true
export CHECK_SYNTAX=false
# Strict mode (all checks blocking)
export BLOCKING_VALIDATION=true
Custom Pipeline
// Create custom validator with specific rules
const validator = new PostEditValidator(projectRoot);
validator.config = {
checkSyntax: true,
checkFormatting: true,
checkDuplication: true,
blockingValidation: false,
typescript: { enabled: true, noEmit: true, skipLibCheck: true },
bash: { enabled: true, validators: ['pipe-safety'], timeout: 5000 },
};
const result = await validator.runValidationPipeline(filePath);
Testing
Run tests with Jest:
npm test tests/post-edit-validator.test.ts
# With coverage
npm test tests/post-edit-validator.test.ts -- --coverage
# Specific test suite
npm test tests/post-edit-validator.test.ts -t "validateJSON"
Test coverage includes:
- JSON syntax validation
- Bash script validation
- Formatting checks (whitespace, line endings, indentation)
- Duplication detection
- File type detection
- Configuration loading
- Result aggregation
- Error handling
- Edge cases (empty files, large files, special characters)
Performance
- JSON Validation: <5ms
- Bash Validation: <20ms
- TypeScript Check: 100-500ms (depends on project size)
- Formatting Checks: <10ms
- Full Pipeline: <600ms typical
Troubleshooting
TypeScript Check Fails
# Verify TypeScript is installed
npm ls typescript
# Check tsconfig.json
cat tsconfig.json
# Run tsc directly
npx tsc --noEmit
JSON Validation Issues
# Validate JSON syntax with jq
jq . < file.json
# Pretty-print and check
jq '.' < file.json > /tmp/formatted.json
Bash Validation Warnings
# Check bash syntax directly
bash -n script.sh
# Verify strict mode
grep 'set -euo pipefail' script.sh
# Fix unquoted variables
sed -i 's/\$\([a-zA-Z_][a-zA-Z0-9_]*\)/"$\1"/g' script.sh
Configuration Reference
cfn-post-edit.config.json
{
"enabled": true,
"version": "2.0.0",
"blocking": false,
"validation": {
"typescript": {
"enabled": true,
"noEmit": true,
"skipLibCheck": true
},
"bash": {
"enabled": true,
"validators": ["pipe-safety", "dependency-checker", "line-endings"],
"timeout": 5000
}
},
"feedback": {
"provideSuggestions": true,
"autoFixable": ["LINT_ISSUES"],
"nonBlocking": ["TYPE_WARNING", "LINT_ISSUES"],
"blocking": ["SYNTAX_ERROR", "BASH_VALIDATOR_ERROR"]
}
}
References
- Configuration:
.claude/hooks/cfn-post-edit.config.json - Tests:
tests/post-edit-validator.test.ts - CLI Entry:
src/cli/post-edit-hook.ts - Hook Wrappers:
.claude/hooks/cfn-invoke-post-edit*.sh - Pre-Edit Backup:
.claude/skills/pre-edit-backup/SKILL.md
⚠️ Bash Deprecation Notice
The bash implementation of this skill is deprecated as of 2025-11-20.
Deprecation Date: 2025-11-20
Removal Date: 2026-02-20 (90 days)
TypeScript Implementation: dist/cli/pre-edit-hook.js and dist/cli/post-edit-hook.js
Migration Guide: src/hooks/README.md
Why Migrate to TypeScript?
- Type Safety: Zero runtime type errors with compile-time validation
- Better Performance: 5-10ms faster execution, optimized Redis operations
- Comprehensive Testing: 90%+ test coverage with unit, integration, and E2E tests
- Modern Tooling: Full IDE support, autocomplete, and inline documentation
- Maintainability: Single source of truth, easier debugging
Automatic Migration
Set environment variable to automatically use TypeScript:
export USE_TYPESCRIPT=true
All coordinators and orchestrators will automatically prefer TypeScript implementations.
Rollback
If issues arise:
export USE_TYPESCRIPT=false
Bash scripts will continue working for the 90-day deprecation period.
See Also
- Complete Deprecation List: docs/BASH_DEPRECATION_NOTICE.md
- TypeScript Benefits: See individual migration guides
- Test Coverage: Run
npm testto verify TypeScript implementation