leobrival

validation

Modular validation system for Claude Code hooks. Provides security command validation (PreToolUse), TypeScript type checking (PostToolUse), and lint checking (PostToolUse). Includes configurable security patterns, multi-linter detection, webhook notifications, and structured logging. Use when setting up or troubleshooting Claude Code validation hooks.

leobrival 0 Updated 3mo ago

Resources

1
GitHub

Install

npx skillscat add leobrival/topographic-plugins-official/validation

Install via the SkillsCat registry.

SKILL.md

Validation System

Modular validation system for Claude Code with security, linting, and type checking hooks.

Overview

This skill provides three hook entry points for Claude Code:

Hook Type Script Purpose
validate-command PreToolUse dist/commands/validate-command.js Block dangerous bash commands
type-check PostToolUse dist/commands/type-check.js TypeScript type validation on file edits
lint-check PostToolUse dist/commands/lint-check.js Lint validation on file edits

Architecture

scripts/validation/
├── src/
│   ├── commands/           # Hook entry points
│   │   ├── validate-command.ts   # PreToolUse: security validation
│   │   ├── type-check.ts         # PostToolUse: TypeScript checking
│   │   ├── lint-check.ts         # PostToolUse: lint checking
│   │   └── test-webhook.ts       # Webhook testing utility
│   └── lib/
│       ├── config.ts             # Configuration manager (env var interpolation)
│       ├── types.ts              # Core type definitions
│       ├── formatters.ts         # Output formatting utilities
│       ├── logger.ts             # Structured logger with file output
│       ├── detectors/
│       │   ├── project-detector.ts   # Detect project root, tsconfig, package.json
│       │   ├── package-detector.ts   # Detect package manager (bun > pnpm > yarn > npm)
│       │   └── linter-detector.ts    # Detect available linters (Biome, ESLint, Prettier, etc.)
│       ├── executors/
│       │   ├── command-executor.ts   # Shell command execution with fallbacks
│       │   └── linter-executor.ts    # Linter execution with priority order
│       ├── validators/
│       │   ├── command-validator.ts  # Security pattern matching
│       │   ├── type-validator.ts     # TypeScript type checking
│       │   └── lint-validator.ts     # Lint file validation
│       └── webhooks/
│           ├── ifttt-client.ts       # IFTTT webhook client
│           ├── webhook-manager.ts    # Multi-endpoint sender with retry
│           ├── webhook-service.ts    # High-level webhook API
│           └── notification-templates.ts  # Template selection and rendering
├── config/
│   ├── default.json              # Main configuration
│   ├── security/
│   │   ├── dangerous-patterns.json   # Blocked command patterns
│   │   └── safe-patterns.json        # Allowed command patterns
│   └── webhooks/
│       ├── endpoints.json            # Webhook endpoint configuration
│       └── notification-templates.json  # Notification templates
├── dist/                         # Compiled output (generated by `tsc`)
├── package.json
├── tsconfig.json
└── biome.json

Installation

Step 1: Build the project

After plugin install/update, build the validation project:

cd ~/.claude/plugins/marketplaces/topographic-plugins-official/plugins/dev/skills/validation/scripts/validation
bun install && bun run build

Step 2: Configure hooks in settings.json

Add or update the following hooks in ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "bun ~/.claude/plugins/marketplaces/topographic-plugins-official/plugins/dev/skills/validation/scripts/validation/dist/commands/validate-command.js"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|MultiEdit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bun ~/.claude/plugins/marketplaces/topographic-plugins-official/plugins/dev/skills/validation/scripts/validation/dist/commands/type-check.js"
          },
          {
            "type": "command",
            "command": "bun ~/.claude/plugins/marketplaces/topographic-plugins-official/plugins/dev/skills/validation/scripts/validation/dist/commands/lint-check.js"
          },
          {
            "type": "command",
            "command": "bun run format || true"
          }
        ]
      }
    ]
  }
}

Step 3: Verify installation

Test that the hooks work correctly:

# Check scripts exist
ls ~/.claude/plugins/marketplaces/topographic-plugins-official/plugins/dev/skills/validation/scripts/validation/dist/commands/

# Test validate-command (should exit 0 for safe commands)
echo '{"tool_name":"Bash","tool_input":{"command":"ls -la"}}' | bun ~/.claude/plugins/marketplaces/topographic-plugins-official/plugins/dev/skills/validation/scripts/validation/dist/commands/validate-command.js

# Test validate-command (should exit 2 for dangerous commands)
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' | bun ~/.claude/plugins/marketplaces/topographic-plugins-official/plugins/dev/skills/validation/scripts/validation/dist/commands/validate-command.js

Security Patterns

Dangerous Patterns (Blocked)

Commands matching these patterns are blocked with exit code 2:

  • rm -rf - Recursive force remove (critical)
  • sudo / su - Elevated privileges (high)
  • chmod 777 - Unsafe permissions (high)
  • eval() / exec() - Code execution (high)
  • curl | sh / wget | sh - Remote code execution (critical)
  • /etc/passwd / /etc/shadow - System file access (high/critical)
  • ../ - Path traversal (medium)
  • dd if= / mkfs. / fdisk - Disk operations (critical)

Safe Patterns (Allowed)

Commands matching these patterns are explicitly allowed:

  • git, gh - Version control
  • bun, npm, pnpm, yarn - Package managers
  • docker, docker-compose - Containers
  • vercel, railway, neon, convex - Cloud platforms
  • ls, cd, pwd, cat, echo - Basic shell
  • mkdir, touch, cp, mv, grep - File operations
  • curl (without pipes), wget (without pipes) - HTTP requests

Customizing Patterns

Edit the JSON files in config/security/:

  • dangerous-patterns.json - Add patterns to block
  • safe-patterns.json - Add patterns to allow

Each pattern has: pattern (regex), description, optional severity (critical/high/medium/low).

Linter Detection

The system auto-detects available linters in the current project:

Linter Detection Method
Biome biome.json, biome.jsonc, or @biomejs/biome in package.json
ESLint .eslintrc.*, eslint.config.*, or eslint in package.json
Prettier .prettierrc*, prettier.config.*, or prettier in package.json
markdownlint .markdownlint.*, .markdownlintrc, or markdownlint-cli* in package.json
TSLint tslint.json (legacy)

Priority order: Biome > ESLint > Prettier > markdownlint > TSLint

Webhook Notifications

Supports IFTTT, Slack, and Discord webhook endpoints for real-time notifications.

Events

  • command_blocked / command_allowed - Security events
  • lint_error / lint_success - Linting events
  • typecheck_error / typecheck_success - Type checking events
  • security_alert - Security alerts
  • session_start / session_end - Session lifecycle

Configuration

Edit config/webhooks/endpoints.json to configure webhook endpoints.
Uses ${ENV_VAR} interpolation for secrets.

Testing Webhooks

cd ~/.claude/plugins/marketplaces/topographic-plugins-official/plugins/dev/skills/validation/scripts/validation
bun run test:webhook

Logging

Structured logging to ~/.claude/logs/validation/ with daily rotation.

Control via environment variables:

  • LOG_DIR - Custom log directory
  • LOG_LEVEL - Log level (debug/info/warn/error)

Development

Build

cd skills/validation/scripts/validation
bun install
bun run build        # Compile TypeScript
bun run build:watch  # Watch mode

Lint

bun run lint         # Check
bun run lint:fix     # Auto-fix
bun run format       # Format

Troubleshooting

Hook not running

  1. Verify dist/ exists: ls ~/.claude/plugins/marketplaces/topographic-plugins-official/plugins/dev/skills/validation/scripts/validation/dist/commands/
  2. If missing, rebuild: cd <path> && bun install && bun run build
  3. Check settings.json hook paths match the marketplace path

False positives from type-check

The type-check hook may report failures with errorCount: 0 — this is a known false positive. The hook returns non-zero but the actual error count is zero. Safe to ignore.

Blocked command that should be allowed

Add a new pattern to config/security/safe-patterns.json:

{
  "pattern": "^your-command\\s+",
  "description": "Your safe command"
}

Logs not appearing

Check that ~/.claude/logs/validation/ exists and is writable.
Override with: LOG_DIR=/custom/path bun <script>