conclaude
v0.1.1
Published
Claude Code hook handler CLI tool that processes hook events and manages lifecycle hooks for tool usage, session management, and transcript processing
Downloads
53
Maintainers
Readme
conclaude
A Claude Code hook handler CLI tool that processes hook events from Claude Code by reading JSON payloads from stdin and executing handlers for each event type. The tool provides lifecycle hooks for tool usage, session management, and transcript processing with YAML-based configuration.
Features
- Comprehensive Hook System: Handle all Claude Code lifecycle events (PreToolUse, PostToolUse, Stop, etc.)
- YAML Configuration: Simple, readable YAML configuration files with cosmiconfig
- Command Execution: Run linting, testing, and validation commands during Stop hooks
- File Protection: Prevent unwanted root-level file creation via
preventRootAdditionsrule - Session Logging: Winston-based logging with session-specific file output
- Pattern Matching: Glob pattern support for file protection rules
Installation
Global Installation (Recommended)
# Install globally with bun
bun install -g conclaude
# Or install from npm
npm install -g conclaudeNix Flake Installation
# Use the flake directly
nix run github:connix-io/conclaude -- --helpAdding conclaude to your development shell
Add conclaude as a flake input and include it in your development shell:
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
conclaude.url = "github:connix-io/conclaude";
};
outputs = { self, nixpkgs, conclaude, ... }:
let
system = "x86_64-linux"; # or your system
pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.default = pkgs.mkShell {
packages = [
conclaude.packages.${system}.default
# your other packages...
];
shellHook = ''
echo "conclaude available in development environment"
conclaude --help
'';
};
};
}Then enter the development shell:
nix developDevelopment Installation
# Clone and install for development
git clone https://github.com/connix-io/conclaude.git
cd conclaude
bun installConfiguration System
conclaude uses cosmiconfig with YAML configuration files. The system searches for configuration in the following order:
.conclaude.yaml- Primary configuration file.conclaude.yml- Alternative YAML extension
Configuration Schema
# .conclaude.yaml
stop:
run: |
nix develop -c "lint"
bun test
rules:
preventRootAdditions: true
uneditableFiles:
- "./package.json"
- "*.lock"
- ".env*"Configuration Schema
interface ConclaudeConfig {
stop: {
run: string; // Commands to execute during Stop hook
};
rules: {
preventRootAdditions: boolean; // Block file creation at repo root
uneditableFiles: string[]; // Glob patterns for protected files
};
}Hook Types
PreToolUse Hook
Fired before Claude executes any tool. Enables:
- Tool execution blocking based on custom rules
- Input validation and security checks
- Root file creation prevention via
preventRootAdditions
PostToolUse Hook
Fired after tool execution. Enables:
- Result logging and analysis
- Performance monitoring
- Post-processing of tool outputs
Stop Hook
Fired when Claude session terminates. Enables:
- Command execution (lint, test, build)
- Session cleanup and validation
- Blocks session if any command fails
Other Hooks
- UserPromptSubmit - Process user input before Claude sees it
- SessionStart - Session initialization
- SubagentStop - Subagent completion handling
- Notification - System notification processing
- PreCompact - Transcript compaction preprocessing
Configuration Examples
Basic Configuration (.conclaude.yaml)
# Commands to run during Stop hook
stop:
run: |
bun x tsc --noEmit
bun test
bun build
# Validation rules
rules:
# Block file creation at repository root
preventRootAdditions: true
# Files that cannot be edited (glob patterns)
uneditableFiles:
- "./package.json"
- "./bun.lockb"
- ".env*"
- "*.lock"Development Configuration Example
# Minimal checks for development
stop:
run: |
echo "Running development checks..."
bun x tsc --noEmit
rules:
preventRootAdditions: false # Allow root edits during development
uneditableFiles:
- "./package.json" # Still protect package.jsonProduction Configuration Example
# Comprehensive validation for production
stop:
run: |
echo "Running production validation..."
bun x tsc --noEmit
bun test
bun run lint
bun run build
rules:
preventRootAdditions: true
uneditableFiles:
- "./package.json"
- "./bun.lockb"
- ".env*"
- "dist/**"
- "node_modules/**"Usage
Claude Code Integration
conclaude is designed to be used as a hook handler in Claude Code. After global installation, use the conclaude init command to automatically configure Claude Code hooks:
# Initialize conclaude in your project
conclaude initThis creates:
.conclaude.yaml- Your project configuration.claude/settings.json- Claude Code hook configuration
Manual Claude Code Configuration
If you prefer manual setup, configure hooks in your Claude Code settings:
{
"hooks": {
"PreToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "conclaude PreToolUse"
}
]
}
],
"PostToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "conclaude PostToolUse"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "conclaude Stop"
}
]
}
]
}
}Initialize Configuration
# Create initial .conclaude.yaml configuration
conclaude init
# Force overwrite existing configuration
conclaude init --force
# Specify custom paths
conclaude init --config-path ./custom.yaml --claude-path ./.claude-customManual Testing
# Test Stop hook
echo '{"session_id":"test","transcript_path":"/tmp/test.jsonl","hook_event_name":"Stop","stop_hook_active":true}' | \
conclaude Stop
# Test PreToolUse hook
echo '{"session_id":"test","transcript_path":"/tmp/test.jsonl","hook_event_name":"PreToolUse","tool_name":"Write","tool_input":{"file_path":"test.txt"}}' | \
conclaude PreToolUse
# Get help
conclaude --help
conclaude Stop --helpExit Codes
- 0: Success - operation allowed to proceed
- 1: Error - validation failure, parsing error, or handler crash
- 2: Blocked - hook explicitly blocked the operation
Hook Behavior Examples
Stop Hook Command Execution
The Stop hook executes commands from config.stop.run sequentially:
# Configuration
stop:
run: |
bun x tsc --noEmit
bun test
# Execution: If any command fails, the entire hook fails and blocks the session
✓ Command 1/2: bun x tsc --noEmit
✗ Command 2/2: bun test (exit code 1)
❌ Hook blocked: Command failed with exit code 1: bun testPreToolUse Root Protection
When preventRootAdditions: true, file-modifying tools are blocked at repo root:
# Blocked operations
Write → /repo/newfile.txt ❌ Blocked
Edit → /repo/config.json ❌ Blocked
# Allowed operations
Write → /repo/.gitignore ✓ Allowed (dotfile)
Write → /repo/src/component.tsx ✓ Allowed (subdirectory)
Read → /repo/package.json ✓ Allowed (read-only)Development
Commands
# Type checking
bun run lint
# Run tests
bun test
# Build for distribution
bun run build
# Run hooks directly (development)
bun src/index.ts <hook-type>
# Use Nix development environment
nix develop -c lint # Run linting
nix develop -c tests # Run testsProject Structure
├── src/
│ ├── index.ts # Main CLI with hook handlers
│ ├── config.ts # Configuration loading with cosmiconfig
│ ├── types.ts # TypeScript payload definitions
│ └── logger.ts # Winston logging configuration
├── .conclaude.yaml # YAML configuration file
├── flake.nix # Nix development environment
├── package.json # Package configuration
└── README.mdConfiguration Loading
Configuration is loaded using cosmiconfig with YAML files:
.conclaude.yaml- Primary configuration file.conclaude.yml- Alternative YAML extension
If no configuration file is found, conclaude will throw an error requiring you to run conclaude init first.
Adding New Hooks
- Define payload interface in
types.ts - Add handler function in
index.ts - Create command definition
- Register command with yargs CLI
Architecture
Hook Processing Flow
stdin JSON → readPayload() → validateFields() → handler() → HookResult → exit codeConfiguration Resolution
.conclaude.yaml → YAML parsing → ConclaudeConfig interfaceCommand Execution (Stop Hook)
config.stop.run → extractBashCommands() → Bun.spawn() → sequential execution → fail fastLicense
This project is part of the connix ecosystem and follows the same licensing terms.
