Feature Request: Environment Management for Hooks to Ensure Consistent Execution
Subject: Feature Request: Environment Management for Hooks to Ensure Consistent Execution
Labels: enhancement, feature-request, hooks, teams
Overview
The hooks feature introduced in v1.0.38 is a powerful mechanism for automating workflows and enforcing standards. However, the current implementation, which executes hooks in the user's ambient shell environment, is brittle and unreliable in a team setting. This issue proposes a new feature to define an execution environment for hooks, ensuring they run consistently across all developer machines and in CI/CD pipelines.
The Problem: Inconsistent Hook Execution
According to the documentation (en/docs/claude-code/hooks, section "Hook Execution Details"), hooks are executed "in the current directory with Claude Code's environment." This dependency on the local machine's configuration creates several problems for teams who want to share hooks via a checked-in .claude/settings.json:
- Divergent Tool Versions: A hook that runs a linter (
prettier,black,eslint) may fail or produce different results if team members have different versions of the tool installed globally. - Missing Dependencies: A script-based hook might rely on a specific version of a language (e.g., Python 3.11, Node 20) or a library (
jq,yq) that isn't present or configured correctly on another developer's machine. - Conflicting Environment Variables: A user's local
~/.bashrcor~/.zshrccould set environment variables that interfere with the hook's execution in unexpected ways.
This brittleness makes it difficult to rely on hooks for critical, team-wide automation, such as formatting, pre-commit checks, or validation.
A Concrete Use Case
A team wants to enforce a code formatting standard by using a PostToolUse hook that runs npx prettier --write on any file modified by the Edit or Write tools.
- The project's
package.jsonspecifiesprettier@3.2.5. - Developer A has the correct version. The hook works perfectly.
- Developer B has an older global version of
prettier(v2.8.0) in their path. The hook either fails or, worse, formats the code using the old rules, creating unnecessary diffs and style conflicts.
The hook, intended to enforce consistency, has become a source of inconsistency.
Proposed Solution: Definable Hook Environments
To solve this, I propose adding a new optional field, hookEnv, to the hook configuration in settings.json. This field would define an isolated, reproducible environment in which the hook's command is executed.
Here are some conceptual examples of what this could look like:
Example: Python Virtual Environment
The hook command would be executed after activating the specified virtual environment.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit(*.py)",
"hooks": [
{
"type": "command",
"command": "black ${CLAUDE_TOOL_INPUT_FILE_PATH}",
"hookEnv": {
"type": "pythonVenv",
"path": ".venv"
}
}
]
}
]
}
}
Example: Node.js Version Manager
The hook would use the Node.js version specified in a project's .nvmrc or package.json engines field.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit(*.ts)",
"hooks": [
{
"type": "command",
"command": "npx prettier --write ${CLAUDE_TOOL_INPUT_FILE_PATH}",
"hookEnv": {
"type": "nvm",
"path": ".nvmrc" // or infer from package.json
}
}
]
}
]
}
}
Example: Containerized Execution (Future-proof)
For ultimate isolation, the hook could run inside a specified container.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(terraform apply)",
"hooks": [
{
"type": "command",
"command": "terraform validate",
"hookEnv": {
"type": "container",
"image": "hashicorp/terraform:latest"
}
}
]
}
]
}
}
Benefits of this Feature
Implementing this feature would provide significant benefits:
- Consistency & Reproducibility: Guarantees that hooks execute in the exact same way for every developer and every CI run.
- Reliability: Eliminates a major class of failures related to local environment configuration drift.
- Portability: Makes automated workflows defined by hooks easily shareable and immediately usable when cloning a repository.
- Decoupling: Fully decouples the hook's execution from the host machine's state, a core tenet of modern development practices.
- Security: Provides a sandboxed environment, reducing the potential impact of a compromised hook.
This enhancement would elevate hooks from a powerful individual utility to a robust, enterprise-grade automation tool for development teams.
Thank you for your consideration.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗