API Reference
Functions
defineCodeValidator()
Creates a new validator instance.
function defineCodeValidator(): Validator;
Returns
A Validator instance with the following methods:
registerRule(rule: ValidationRule)- Register a validation rulevalidate(input: ClaudeCodeHookInput)- Validate hook inputparseInput(input: ClaudeCodeHookInput)- Parse hook input to ValidationContextgetRules()- Get all registered rulesgetHooks()- Get hookable instance for custom hooks
Example
import { defineCodeValidator } from "@syncrolabs/claude-code-validator";
const validator = defineCodeValidator();
// Register a rule
validator.registerRule(myRule);
// Validate input
const result = await validator.validate(hookInput);
if (!result.valid) {
console.error(result.formatErrors());
process.exit(2);
}
defineCodeRule()
Define a validation rule with type safety and auto-completion.
function defineCodeRule(rule: ValidationRule): ValidationRule;
Parameters
rule- AValidationRuleobject
Returns
The same ValidationRule object (provides type checking)
Example
import { defineCodeRule } from "@syncrolabs/claude-code-validator";
export const myRule = defineCodeRule({
name: "my-rule",
description: "Description of the rule",
shouldRun: (context) => true,
validate: (context) => [],
});
loadRules()
Auto-discovers and loads validation rules from a directory.
async function loadRules(rulesDir: string): Promise<ValidationRule[]>;
Parameters
rulesDir- Path to directory containing rules (e.g.,.claude/rules)
Returns
Promise resolving to array of ValidationRule objects
Example
import { loadRules } from "@syncrolabs/claude-code-validator";
const rules = await loadRules(".claude/rules");
console.log(`Loaded ${rules.length} rules`);
for (const rule of rules) {
console.log(`- ${rule.name}: ${rule.description}`);
}
createValidator() (deprecated)
Legacy alias for defineCodeValidator().
function createValidator(): Validator;
Note: Prefer using
defineCodeValidator()for consistency with ecosystem naming conventions.
Types
ValidationContext
Context passed to validation rules containing information about the file being validated.
interface ValidationContext {
toolName: string;
filePath: string;
content: string;
oldContent?: string;
operation: "edit" | "write";
}
Properties
toolName- The name of the tool being used (e.g., 'Edit', 'Write')filePath- The path to the file being validatedcontent- The new/current content of the fileoldContent- The old content (for Edit operations only)operation- The type of operation being performed
ValidationRule
A validation rule that can be registered with the validator.
interface ValidationRule {
name: string;
description: string;
shouldRun: (context: ValidationContext) => boolean;
validate: (context: ValidationContext) => Promise<string[]> | string[];
}
Properties
name- Unique name for this ruledescription- Human-readable description of what this rule validatesshouldRun- Function to determine if this rule should run for the given contextvalidate- Function to perform validation and return array of error messages
ValidationResult
Result returned by the validator.
interface ValidationResult {
valid: boolean;
errors: string[];
formatErrors: () => string;
}
Properties
valid- Whether validation passed (no errors)errors- Array of error messagesformatErrors- Function to format errors for display to the user
PatternRule
A simple pattern-based validation rule.
interface PatternRule {
regex: RegExp;
message: string;
replacement?: string;
}
Properties
regex- Regular expression to match againstmessage- Error message to show when pattern is foundreplacement- Optional suggested replacement
ClaudeCodeHookInput
Input from Claude Code hooks.
interface ClaudeCodeHookInput {
tool_name: string;
tool_input: {
file_path?: string;
content?: string;
new_string?: string;
old_string?: string;
[key: string]: any;
};
}
Properties
tool_name- Name of the tool being invokedtool_input- Tool-specific input parameters
Validator
Type returned by defineCodeValidator().
type Validator = {
registerRule(rule: ValidationRule): void;
validate(input: ClaudeCodeHookInput): Promise<ValidationResult>;
parseInput(input: ClaudeCodeHookInput): ValidationContext;
getRules(): ValidationRule[];
getHooks(): Hookable;
};
Hookable Events
The validator emits lifecycle events via hookable:
validate:before
Emitted before validation starts.
hooks.hook("validate:before", (context: ValidationContext) => {
console.log("Starting validation for:", context.filePath);
});
validate:after
Emitted after validation completes.
hooks.hook("validate:after", (context: ValidationContext, errors: string[]) => {
console.log(`Found ${errors.length} errors`);
});
validate:{ruleName}
Emitted when a specific rule runs.
hooks.hook("validate:my-rule", (context: ValidationContext) => {
console.log("Running my-rule");
});
Example Usage
Complete Example
import {
defineCodeValidator,
defineCodeRule,
loadRules,
} from "@syncrolabs/claude-code-validator";
// Create validator
const validator = defineCodeValidator();
// Define a custom rule
const customRule = defineCodeRule({
name: "custom",
description: "Custom validation",
shouldRun: (context) => context.filePath.endsWith(".ts"),
validate(context) {
if (context.content.includes("TODO")) {
return ["❌ Remove TODO comments before committing"];
}
return [];
},
});
// Register custom rule
validator.registerRule(customRule);
// Load rules from directory
const rules = await loadRules(".claude/rules");
for (const rule of rules) {
validator.registerRule(rule);
}
// Add lifecycle hooks
const hooks = validator.getHooks();
hooks.hook("validate:before", (context) => {
console.log(`Validating ${context.filePath}...`);
});
// Parse and validate input
const input = JSON.parse(await Bun.stdin.text());
const result = await validator.validate(input);
if (!result.valid) {
console.error(result.formatErrors());
process.exit(2);
}
console.log("✅ Validation passed");