Hooks Overview
conclaude integrates with Claude Code through lifecycle hooks—strategic intervention points that let you enforce rules, run validations, and maintain control over your codebase.
How Hooks Work
Section titled “How Hooks Work”When Claude Code runs in a directory with conclaude configured, it invokes conclaude at specific moments:
- Claude Code fires a hook event (e.g., “PreToolUse”)
- conclaude receives the event as a JSON payload via stdin
- conclaude evaluates rules and runs commands based on your configuration
- conclaude returns a result (allow, block, or error)
- Claude Code proceeds based on the result
Hook Types
Section titled “Hook Types”PreToolUse
Section titled “PreToolUse”When: Before Claude uses any tool (Write, Bash, Read, etc.)
Purpose: Gate tool execution based on your rules.
Common Use Cases:
- Block file creation at project root
- Protect critical files from modification
- Validate tool inputs before execution
Configuration:
preToolUse: preventRootAdditions: true uneditableFiles: - "Cargo.lock" - ".env*" - "target/**"Example Scenario:
Claude wants to create debug.log in your project root. With preventRootAdditions: true, conclaude blocks the operation. Claude adapts and creates logs/debug.log instead.
PostToolUse
Section titled “PostToolUse”When: After a tool operation completes
Purpose: Observe and log tool results.
Common Use Cases:
- Audit logging of all changes
- Performance monitoring
- Post-processing validation
Note: PostToolUse is currently used for logging and observation. It does not block operations.
When: Claude finishes a task and the session is about to end
Purpose: Final validation gate before session completion.
This is the most important hook for enforcing code quality.
Configuration:
stop: commands: - run: cargo fmt --check message: "Check code formatting" - run: cargo clippy -- -D warnings message: "Run clippy lints" - run: cargo test message: "Run test suite"How It Works:
- Claude completes a task
- conclaude runs each command in order
- If any command fails, Claude sees the error output
- Claude can fix the issues
- Session only completes when all commands pass
Infinite Mode:
For long coding sessions, enable continuous validation:
stop: commands: - run: cargo check - run: cargo test infinite: true infiniteMessage: "Monitoring active - validating after each change"With infinite mode, validation runs after every task completion, not just at session end.
Workflow Guardrails: PR Verification
Beyond code quality checks, Stop hooks can enforce workflow policies. This example ensures all changes are committed and a pull request exists before the session ends:
stop: commands: # Ensure no uncommitted changes - run: | if [ -n "$(git status --porcelain)" ]; then echo "Error: Uncommitted changes detected" git status --short exit 1 fi message: "Check for uncommitted changes"
# Ensure no untracked files - run: | UNTRACKED=$(git ls-files --others --exclude-standard) if [ -n "$UNTRACKED" ]; then echo "Error: Untracked files detected:" echo "$UNTRACKED" exit 1 fi message: "Check for untracked files"
# Verify PR exists for current branch - run: | BRANCH=$(git branch --show-current) if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then exit 0 # Skip PR check on main/master fi PR_COUNT=$(gh pr list --head "$BRANCH" --json number --jq 'length') if [ "$PR_COUNT" -eq 0 ]; then echo "Error: No open PR found for branch '$BRANCH'" echo "Create a PR with: gh pr create" exit 1 fi message: "Verify pull request exists"Prerequisites:
- Git must be installed and the directory must be a Git repository
- GitHub CLI (
gh) must be installed and authenticated for PR verification - Run
gh auth loginto authenticate if needed
How It Works:
- Uncommitted changes check: Uses
git status --porcelainto detect any staged or unstaged modifications - Untracked files check: Uses
git ls-files --others --exclude-standardto find files not yet added to Git - PR verification: Queries GitHub for open PRs from the current branch using
gh pr list
When Checks Fail:
- If uncommitted changes exist, Claude sees the list of modified files and can commit them
- If untracked files exist, Claude sees the file list and can add them to Git
- If no PR exists, Claude sees instructions to create one with
gh pr create - The session only completes when all checks pass
Combining with Code Quality:
stop: commands: # Code quality first - run: cargo fmt --check message: "Check formatting" - run: cargo test message: "Run tests"
# Then workflow checks - run: test -z "$(git status --porcelain)" message: "No uncommitted changes" - run: | BRANCH=$(git branch --show-current) [ "$BRANCH" = "main" ] || gh pr list --head "$BRANCH" --json number --jq 'length' | grep -q '[1-9]' message: "PR exists for branch"This pattern ensures code quality AND workflow discipline before session completion.
SessionStart
Section titled “SessionStart”When: A new Claude Code session begins
Purpose: Initialize session-specific resources.
Use Cases:
- Set up session logging
- Initialize monitoring
- Prepare workspace
UserPromptSubmit
Section titled “UserPromptSubmit”When: User submits input to Claude
Purpose: Process user prompts and inject context based on prompt content.
Use Cases:
- Context injection based on prompt patterns
- Automatically load project-specific guidelines
- Audit logging of user inputs
Configuration:
userPromptSubmit: contextRules: - pattern: "sidebar|navigation" prompt: | Read @.claude/contexts/sidebar.md before making changes.
- pattern: "auth|login|authentication" prompt: | Review authentication patterns in @.claude/contexts/auth.md caseInsensitive: trueHow It Works:
Context injection allows you to automatically prepend relevant guidelines, documentation, or reminders to Claude’s system prompt based on what you’re asking about. When your prompt matches a configured pattern, conclaude injects the associated context before Claude processes your request.
Example Scenario:
You ask: “How do I update the sidebar component?”
With the configuration above:
- Pattern
sidebar|navigationmatches “sidebar” - conclaude prepends the context from
.claude/contexts/sidebar.md - Claude receives your prompt with additional context about sidebar guidelines
- Claude responds with knowledge of your project-specific sidebar patterns
Pattern Matching:
- Supports regular expressions for flexible matching
- Multiple rules can match and inject context
- Case-sensitive by default (use
caseInsensitive: trueto override) - File references using
@syntax are expanded to file contents
See Also: UserPromptSubmit Configuration Reference
SubagentStart
Section titled “SubagentStart”When: A Claude subagent (coder, tester, stuck, etc.) begins work
Purpose: Track subagent initialization.
Payload Fields:
agent_id— Identifier for the subagent (e.g., “coder”, “tester”)subagent_type— Category of subagent (e.g., “implementation”, “testing”)agent_transcript_path— Path to subagent’s transcript file
Configuration:
notifications: enabled: true hooks: - "SubagentStart"Use Cases:
- Log when specific agents start
- Initialize agent-specific resources
- Collect timing metrics
SubagentStop
Section titled “SubagentStop”When: A Claude subagent completes its work
Purpose: Handle subagent completion.
Payload Fields:
agent_id— Identifier for the completed subagentagent_transcript_path— Path to subagent’s transcript file
Configuration:
notifications: enabled: true hooks: - "SubagentStop"Use Cases:
- Log subagent completion
- Cleanup operations
- Performance metrics
Notification
Section titled “Notification”When: System notifications are sent
Purpose: Handle and filter system alerts.
PreCompact
Section titled “PreCompact”When: Before transcript compaction
Purpose: Prepare transcripts before archival.
PermissionRequest
Section titled “PermissionRequest”When: A tool requests permission
Purpose: Handle permission flows.
SessionEnd
Section titled “SessionEnd”When: A session terminates
Purpose: Cleanup and final logging.
Configuration Examples
Section titled “Configuration Examples”Basic Development Setup
Section titled “Basic Development Setup”stop: commands: - run: cargo check message: "Type check"
preToolUse: preventRootAdditions: false uneditableFiles: - "Cargo.toml"Production Quality Gates
Section titled “Production Quality Gates”stop: commands: - run: cargo fmt --check message: "Formatting must pass" - run: cargo clippy -- -D warnings message: "No clippy warnings allowed" - run: cargo test message: "All tests must pass" - run: cargo build --release message: "Release build must succeed"
preToolUse: preventRootAdditions: true uneditableFiles: - "Cargo.toml" - "Cargo.lock" - ".env*" - ".github/workflows/**"Node.js Project
Section titled “Node.js Project”stop: commands: - run: npm run lint message: "ESLint check" - run: npm run typecheck message: "TypeScript check" - run: npm test message: "Jest tests"
preToolUse: preventRootAdditions: true uneditableFiles: - "package-lock.json" - ".env*" - "node_modules/**"Continuous Monitoring Session
Section titled “Continuous Monitoring Session”stop: commands: - run: cargo check --quiet - run: cargo test --quiet infinite: true infiniteMessage: "Validating after each change..."
preToolUse: preventRootAdditions: falseContext Injection for Project Guidelines
Section titled “Context Injection for Project Guidelines”Automatically inject relevant context when working on specific features:
userPromptSubmit: contextRules: # React component guidelines - pattern: "component|react|jsx|tsx" prompt: | Component guidelines: @.claude/contexts/components.md - Use TypeScript - Add PropTypes - Include unit tests caseInsensitive: true
# API development standards - pattern: "api|endpoint|route" prompt: | API standards: @.claude/contexts/api.md - Use proper HTTP status codes - Implement error handling - Add request validation
# Security reminders - pattern: "auth|login|password|security" prompt: | SECURITY CHECKLIST: - Never commit secrets - Use environment variables - Review: @.claude/contexts/security.md caseInsensitive: true
# Optional: Get notified when context is injectednotifications: enabled: true hooks: - "UserPromptSubmit" showSuccess: trueHow This Helps:
When you ask “How do I add a new React component?”, conclaude automatically reminds Claude about your component guidelines before it responds. You don’t need to repeat instructions manually.
Notifications
Section titled “Notifications”Get system notifications when hooks execute:
notifications: enabled: true hooks: - "Stop" - "PreToolUse"Use ["*"] for all hooks:
notifications: enabled: true hooks: ["*"]Environment Variables
Section titled “Environment Variables”Commands executed by hooks have access to context variables:
| Variable | Description |
|---|---|
CONCLAUDE_SESSION_ID | Unique session identifier |
CONCLAUDE_TRANSCRIPT_PATH | Path to session transcript |
CONCLAUDE_CWD | Current working directory |
CONCLAUDE_HOOK_EVENT | Name of executing hook |
CONCLAUDE_CONFIG_DIR | Directory containing config |
For subagent hooks:
| Variable | Description |
|---|---|
CONCLAUDE_AGENT_ID | Raw agent identifier (e.g., “adb0a8b”) |
CONCLAUDE_AGENT_NAME | Semantic agent name (e.g., “coder”, “tester”, “stuck”). Falls back to agent ID if extraction fails. (SubagentStop only) |
CONCLAUDE_SUBAGENT_TYPE | Subagent type (e.g., “implementation”) (SubagentStart only) |
CONCLAUDE_AGENT_TRANSCRIPT_PATH | Path to subagent transcript |
Next Steps
Section titled “Next Steps”- CLI Reference — All commands and hook handlers
- Configuration Reference — Complete configuration options
- Stop Hook — Detailed stop hook configuration
- PreToolUse Hook — File protection rules
- UserPromptSubmit Hook — Context injection configuration