Skip to content

Latest commit

 

History

History
168 lines (132 loc) · 3.71 KB

File metadata and controls

168 lines (132 loc) · 3.71 KB

Adding Validators

How to extend the validation system.

Architecture

validation/
├── schemas/                       # JSON Schema definitions
│   ├── skill-frontmatter.schema.json
│   ├── command-frontmatter.schema.json
│   ├── agent-frontmatter.schema.json
│   └── power-frontmatter.schema.json
└── src/
    ├── index.ts                   # Orchestrator — invoked by `bun run validate`
    ├── frontmatter-validator.ts
    ├── bash-validator.ts
    ├── claude-validator.ts
    ├── codex-validator.ts
    ├── copilot-cowork-validator.ts
    ├── consistency-checker.ts
    ├── version-checker.ts
    ├── converters/                # `bun run convert` — not validators
    └── installer/                 # `bun run plugins:install:*` — not validators

Adding a New Frontmatter Schema

  1. Create schema file in validation/schemas/:
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "my-component.schema.json",
  "title": "My Component Frontmatter",
  "type": "object",
  "required": ["description"],
  "properties": {
    "description": {
      "type": "string",
      "minLength": 10
    }
  },
  "additionalProperties": true
}
  1. Import and compile in frontmatter-validator.ts:
import mySchema from "../schemas/my-component.schema.json";

const validators = {
  // ... existing validators
  myComponent: ajv.compile(mySchema),
};
  1. Add glob pattern to find files:
const myFiles = await fg("**/my-component/*.md", {
  cwd: root,
  ignore: ["**/node_modules/**"],
});
for (const file of myFiles) {
  results.push(
    await validateFile(path.join(root, file), validators.myComponent, "my-component")
  );
}

Adding a New Validator Module

  1. Create validator file in validation/src/:
// validation/src/my-validator.ts
export interface MyValidationResult {
  file: string;
  valid: boolean;
  errors: string[];
}

export interface MyValidationResults {
  hasErrors: boolean;
  results: MyValidationResult[];
}

export async function validateMyThing(root: string): Promise<MyValidationResults> {
  const results: MyValidationResult[] = [];

  // Your validation logic here

  return {
    hasErrors: results.some((r) => !r.valid),
    results,
  };
}
  1. Add to main entry in index.ts:
import { validateMyThing } from "./my-validator";

// In main():
if (runAll || myThingOnly) {
  printHeader("My Thing Validation");
  const myResults = await validateMyThing(ROOT);
  // ... print results
}
  1. Add CLI flag (optional):
const myThingOnly = args.includes("--my-thing-only");

Adding a Consistency Check

Edit consistency-checker.ts:

// Add new check
const myCheckErrors: string[] = [];

// Your check logic...
if (someCondition) {
  myCheckErrors.push("Description of the issue");
}

results.push({
  check: "My consistency check",
  valid: myCheckErrors.length === 0,
  details: myCheckErrors.length === 0
    ? ["All checks passed"]
    : myCheckErrors,
});

Testing Changes

# Run full validation
bun run validate

# Run specific validator
bun validation/src/index.ts --frontmatter-only

# Test with a broken file to verify error detection

Dependencies

Package Purpose
ajv JSON Schema validation
gray-matter YAML frontmatter parsing
fast-glob File pattern matching
execa Shell command execution

Related