Claude Code hooks that enable autonomous execution, session persistence, and quality enforcement.
These hooks integrate with Claude Code's hook system to provide:
- Autonomous execution until completion
- Session memory persistence
- State preservation across context compaction
- Anti-abandonment enforcement
- Scope validation and enforcement
- Dangerous command blocking
- Quality gate detection and escalation
- MCP server integration
When DevTeam is installed as a Claude Code plugin (via marketplace or local install), all hooks are configured automatically through hooks/hooks.json. No manual setup is required.
# Install from marketplace (hooks auto-configured)
/plugin marketplace add https://github.com/michael-harris/devteam
/plugin install devteam@devteam-marketplaceAll hook paths use ${CLAUDE_PLUGIN_ROOT} to resolve correctly regardless of where the plugin is cached.
If running hooks outside the plugin system, you can still install manually:
# Linux/macOS
./hooks/install.sh
# Windows PowerShell
.\hooks\install.ps1The installer will:
- Make all hooks executable
- Install git pre-commit hook for scope checking
- Generate Claude Code settings configuration
- Optionally auto-install to your settings.json
All hooks are available in both Bash (Linux/macOS) and PowerShell (Windows):
| Hook | Linux/macOS | Windows |
|---|---|---|
| Shared Library | lib/hook-common.sh |
lib/hook-common.ps1 |
| Pre-Tool-Use | pre-tool-use-hook.sh |
pre-tool-use-hook.ps1 |
| Post-Tool-Use | post-tool-use-hook.sh |
post-tool-use-hook.ps1 |
| Stop Hook | stop-hook.sh |
stop-hook.ps1 |
| Persistence Hook | persistence-hook.sh |
persistence-hook.ps1 |
| Scope Check | scope-check.sh |
scope-check.ps1 |
| Session Start | session-start.sh |
session-start.ps1 |
| Session End | session-end.sh |
session-end.ps1 |
| Pre-Compact | pre-compact.sh |
pre-compact.ps1 |
| Installer | install.sh |
install.ps1 |
Purpose: Validates tool calls BEFORE execution.
Behavior:
- Validates file operations against task scope
- Blocks dangerous commands (rm -rf /, force push to main, etc.)
- Injects iteration warnings when approaching limits
- Notifies MCP server of tool usage
Dangerous Commands Blocked:
rm -rf /,rm -rf /*git push --force main/masterDROP DATABASE,DROP TABLE- Fork bombs, disk destruction commands
- Credential exposure attempts
Exit Codes:
0: Allow tool call2: Block tool call (with injected message)
Purpose: Analyzes results AFTER tool execution.
Behavior:
- Detects success/failure patterns in output
- Tracks consecutive failures
- Triggers model escalation when threshold reached
- Detects quality gate results (tests, lint, typecheck, security)
- Provides specific error guidance
Quality Gates Detected:
- Tests: pytest, jest, vitest, go test, etc.
- Type Check: tsc, mypy, pyright
- Lint: eslint, ruff, golangci-lint, rubocop
- Security: bandit, npm audit, gosec, snyk
- Coverage: coverage, --cov, nyc
Exit Codes:
0: Continue normally (post hooks don't block)
Purpose: Detects and prevents premature task abandonment.
Behavior:
- Analyzes Claude's output for "give up" patterns
- Detects direct abandonment: "I give up", "I cannot complete"
- Detects passive abandonment: "Let me know if you need"
- Detects permission-seeking: "Should I proceed?"
- Blocks abandonment and injects re-engagement prompts
- Escalates model tier after repeated attempts
- Activates Bug Council if agent remains stuck
Abandonment Patterns Detected:
- Direct: "I give up", "I'm stuck", "I cannot determine"
- Passive: "Let me know if", "Feel free to", "Hope that helps"
- Permission-seeking: "Should I proceed", "Would you like me to"
Escalation Sequence:
| Attempt | Response |
|---|---|
| 1st | Gentle redirect - try different approach |
| 2nd | Forceful redirect - list 3 alternatives |
| 3rd | Model upgrade to Opus + Bug Council |
| 4th+ | Human notification (keep trying) |
Exit Codes:
0: Allow (output acceptable)2: Block and re-engage (abandonment detected)
Purpose: Implements autonomous execution loop control.
Behavior:
- Checks for valid exit signals in Claude's output
- If autonomous mode active and no signal, blocks exit
- Monitors circuit breaker for consecutive failures
- Tracks iteration count against maximum
- Saves checkpoint before authorized exits
- Cleans up session on authorized exit
Valid Exit Signals:
EXIT_SIGNAL: trueAll quality gates passedTask completed successfullyImplementation complete/devteam:end
Exit Codes:
0: Allow exit (work complete or not autonomous)2: Block exit and continue
Purpose: Enforce strict scope compliance at commit time.
Behavior:
- Reads current task ID from
.devteam/current-task.txt - Loads task scope from database or task JSON file
- Validates all staged files against allowed/forbidden lists
- Detects potentially sensitive files (.env, *.key, credentials)
- Blocks commit if any file is out of scope
Exit Codes:
0: All changes within scope1: Scope violation (commit blocked)
Scope Definition:
// docs/planning/tasks/TASK-XXX.json
{
"scope": {
"allowed_files": ["src/auth/session.ts"],
"allowed_patterns": ["tests/auth/**/*.test.ts"],
"forbidden_files": ["src/auth/oauth.ts"],
"forbidden_directories": ["src/api/"]
}
}The shared library provides common functions for all hooks:
DEVTEAM_ROOT- Project root directoryDEVTEAM_DIR- .devteam directory pathDEVTEAM_DB- SQLite database pathMAX_ITERATIONS- Maximum iteration count (default: 100)MAX_FAILURES- Circuit breaker threshold (default: 5)
log_debug/info/warn/error(hook, message)- Structured logging- Logs to
.devteam/hooks.log
db_exists()- Check if database existsdb_query(sql)- Execute SQL queryget_current_session()- Get running session IDget_current_task()- Get in-progress task IDget_current_iteration()- Get iteration countget_current_model()- Get current model tierget_consecutive_failures()- Get failure countincrement_failures()/reset_failures()log_event_to_db(type, category, message, data)
mcp_available()- Check if MCP server is runningmcp_notify(event_type, data)- Send event to MCP
file_in_scope(file)- Check if file is in allowed scopeget_scope_files()- Get scope patterns for current task
get_claude_context()- Extract current context as JSONinject_system_message(tag, message)- Create system message
is_autonomous_mode()- Check if autonomous mode activeis_circuit_breaker_open()- Check if too many failuresis_max_iterations_reached()- Check iteration limittrigger_escalation(reason)- Trigger model upgradesave_checkpoint(message)- Save progress checkpoint
Hooks use these environment variables from Claude Code:
| Variable | Description |
|---|---|
CLAUDE_TOOL_NAME |
Name of tool being called |
CLAUDE_TOOL_INPUT |
Tool input parameters (JSON) |
CLAUDE_TOOL_RESULT |
Tool execution result |
CLAUDE_OUTPUT |
Claude's text output |
STOP_HOOK_MESSAGE |
Message for stop hook |
Configuration via environment:
| Variable | Description | Default |
|---|---|---|
DEVTEAM_MAX_ITERATIONS |
Max iterations before stop | 100 |
DEVTEAM_MAX_FAILURES |
Circuit breaker threshold | 5 |
DEVTEAM_ECO_MODE |
Use higher escalation thresholds | false |
DEVTEAM_DEBUG |
Enable debug logging | false |
The hooks read/write these files in .devteam/:
| File | Purpose |
|---|---|
devteam.db |
SQLite database for state |
autonomous-mode |
Autonomous mode marker |
circuit-breaker.json |
Failure tracking |
current-task.txt |
Active task ID |
consecutive-failures.txt |
Failure counter |
hooks.log |
Hook execution log |
abandonment-attempts.log |
Abandonment tracking |
escalation-trigger |
Model escalation signals |
last-errors.txt |
Recent error summary |
human-attention-needed.log |
Human notification log |
memory/*.md |
Session memory files |
Hooks integrate with the MCP server when available:
- Socket:
.devteam/mcp.sock(Unix socket) - HTTP:
MCP_SERVER_URLenvironment variable
Events sent to MCP:
pre_tool_use- Before tool executionpost_tool_use- After tool executionabandonment_detected- When abandonment blockedexit_blocked- When exit preventedsession_exit- When session endsscope_violation- When scope check failscommit_validated- When commit passes scope
Run the hook test suite:
./hooks/tests/test-hooks.shTests verify:
- Hook library loads correctly
- Persistence hook detects abandonment patterns
- Stop hook respects EXIT_SIGNAL
- Pre-tool-use hook blocks dangerous commands
- Post-tool-use hook detects failures
- All hook files exist
# Verify hooks are executable
chmod +x hooks/*.sh hooks/lib/*.sh
# Check paths are absolute in settings.json
# Verify Claude Code version supports hooks# Check execution policy
Get-ExecutionPolicy
# Hooks should use -ExecutionPolicy Bypass flag
# Verify PowerShell version (5.1+ or 7+)
$PSVersionTable.PSVersion# Check marker file exists
ls -la .devteam/autonomous-mode
# Check circuit breaker state
cat .devteam/circuit-breaker.json
# Check hook log for errors
tail -50 .devteam/hooks.log# Verify task file exists
cat .devteam/current-task.txt
# Check task scope definition
cat docs/planning/tasks/TASK-XXX.json
# Run scope check manually
./hooks/scope-check.shThe database is auto-initialized on first use. To force reinitialize:
# Delete and let auto-init recreate it
rm -f .devteam/devteam.db*
/devteam:status
# Or manually (local development only):
# Linux/macOS
./scripts/db-init.sh
# Windows
# powershell ./scripts/db-init.ps1
# Check database exists
ls -la .devteam/devteam.db
# Query database
sqlite3 .devteam/devteam.db "SELECT * FROM sessions;"bash(4.0+)sqlite3(for database access)jq(optional, for JSON parsing)- Standard Unix tools: date, mkdir, cat, grep
- PowerShell 5.1+ or PowerShell Core 7+
- No additional dependencies (uses built-in cmdlets)
- Hooks run with user permissions
- State files may contain project details
- Add
.devteam/to.gitignorefor sensitive projects - Dangerous commands are blocked by pre-tool-use hook
- Sensitive files (.env, *.key) trigger warnings in scope check
- On Windows,
-ExecutionPolicy Bypassonly affects specific script execution