[FEATURE] Add PostWorktreeCreate hook (or setup command) for environment initialization in worktrees
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
When using --worktree, isolation: worktree (subagents), or Agent Teams, Claude Code creates a new git worktree via git worktree add. This correctly copies all tracked files but does not carry over gitignored state — most critically:
.venv/— Python virtual environment with all project dependencies.env— environment variables (DB credentials, API keys, service URLs)node_modules/— (less critical,npm installis fast and safe)
For Python projects, this means agents in worktrees cannot execute code, run tests, or use linters — the core value proposition of worktree isolation is lost.
Why this matters
The worktree feature is designed for parallel agent execution. But in a typical Python project:
- Agent starts in a fresh worktree
- Agent tries to run
pytest,ruff,mypy, or any Python script - Fails — no
.venv, no dependencies installed - Agent must either:
pip installinto system Python (unsafe, contaminates host)- Create a new venv + install all deps (slow: 30-120s depending on project size, wastes disk)
- Fail and report it cannot complete the task
This affects all three worktree use cases:
| Use case | Can user manually set up env? | Automated? |
|---|---|---|
| claude --worktree (CLI) | ✅ Yes, before running claude | ❌ No hook |
| isolation: worktree (subagents) | ❌ No, agent creates worktree automatically | ❌ No hook |
| Agent Teams (teammates) | ❌ No, worktrees created automatically | ❌ No hook |
For subagents and Agent Teams — the primary use case for parallel development — there is no way for the user to intervene between worktree creation and agent start.
Current workarounds and why they're insufficient
Workaround 1: CLAUDE.md instructions
# CLAUDE.md
When working in a worktree, first run: python -m venv .venv && source .venv/bin/activate && pip install -e ".[dev]"
Problems:
- Unreliable — Claude often ignores venv instructions (see #273, #2709, #9368)
- Slow — full dependency installation on every worktree creation
- Wastes tokens on environment setup instead of actual work
- Not deterministic — hooks exist precisely because LLM compliance isn't guaranteed
Workaround 2: Hijack WorktreeCreate hook
#!/bin/bash
set -e
INPUT=$(cat)
NAME=$(echo "$INPUT" | jq -r '.name')
DIR="$CLAUDE_PROJECT_DIR/.claude/worktrees/$NAME"
# Reproduce default git behavior
git worktree add "$DIR" -b "worktree-$NAME" HEAD >&2
# Set up environment
ln -s "$CLAUDE_PROJECT_DIR/.venv" "$DIR/.venv" >&2
ln -s "$CLAUDE_PROJECT_DIR/.env" "$DIR/.env" >&2
echo "$DIR"
Problems:
- Fragile — reproduces internal Claude Code logic (
git worktree add -b worktree-$NAME HEAD). If the default behavior changes (branch naming, base ref, worktree path), the hook silently creates incompatible worktrees WorktreeCreateis documented as a replacement for non-git VCS, not a post-creation hook- Symlinked
.venvis unsafe if agent runspip install— it modifies the shared venv
Workaround 3: Use uv instead of pip/venv
uv sync && uv run pytest is fast and doesn't require a pre-existing venv. But:
- Requires the project to adopt
uv(not always possible) - Still doesn't solve
.envfiles - Still relies on CLAUDE.md instructions (non-deterministic)
Proposed Solution
Add a PostWorktreeCreate hook event that fires after the standard git worktree add completes successfully.
Hook specification
Event name: PostWorktreeCreate
When it fires: After Claude Code's built-in git worktree add creates the worktree, but before the agent session starts in it.
Input (stdin JSON):
{
"session_id": "abc123",
"hook_event_name": "PostWorktreeCreate",
"cwd": "/Users/dev/my-project",
"worktree_path": "/Users/dev/my-project/.claude/worktrees/feature-auth",
"worktree_name": "feature-auth",
"branch_name": "worktree-feature-auth",
"base_ref": "HEAD"
}
Key fields:
worktree_path— absolute path to the created worktree (critical for setup scripts)worktree_name— the slug identifierbranch_name— the branch created by git worktree addbase_ref— the ref the worktree was branched from
Output: Standard allow/block decision model (or no output required — just run the command).
On failure: Warning only, do not block worktree creation. The agent should still start — it can attempt to set up the environment itself or report the issue. This is environment optimization, not a gate.
Example usage
.claude/settings.json:
{
"hooks": {
"PostWorktreeCreate": [
{
"hooks": [
{
"type": "command",
"command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/post-worktree-setup.sh\"",
"timeout": 60
}
]
}
]
}
}
.claude/hooks/post-worktree-setup.sh:
#!/bin/bash
set -e
INPUT=$(cat)
WORKTREE_PATH=$(echo "$INPUT" | jq -r '.worktree_path')
PROJECT_DIR=$(echo "$INPUT" | jq -r '.cwd')
# Symlink Python venv (fast, no disk overhead)
if [ -d "$PROJECT_DIR/.venv" ] && [ ! -e "$WORKTREE_PATH/.venv" ]; then
ln -s "$PROJECT_DIR/.venv" "$WORKTREE_PATH/.venv" >&2
echo "Symlinked .venv" >&2
fi
# Copy .env (not symlink — agent might modify it)
if [ -f "$PROJECT_DIR/.env" ] && [ ! -e "$WORKTREE_PATH/.env" ]; then
cp "$PROJECT_DIR/.env" "$WORKTREE_PATH/.env" >&2
echo "Copied .env" >&2
fi
Alternative: worktreeSetupFiles configuration
If a new hook event is too heavy, a simpler alternative: a configuration option in settings.json that specifies files/directories to symlink or copy into new worktrees:
{
"worktree": {
"setupFiles": [
{ "path": ".venv", "strategy": "symlink" },
{ "path": ".env", "strategy": "copy" },
{ "path": "config/local.yaml", "strategy": "copy" }
]
}
}
This would cover 90% of use cases without requiring users to write shell scripts.
Related Issues
- #273 — Claude doesn't detect
.venv/automatically - #2709 — Claude uses global pip instead of venv
- #8855 — No persistent venv activation across commands
- #9368 — Claude ignores CLAUDE.md instructions about venv/uv
- #19938 — Missing instructions for environment file setup in worktree workflow
- #20905 — Dependency installation guidance buried in Tips, not in Steps
- #21613 — No Python support in official devcontainer
Additional Context
Scope of impact
Python is one of the most popular languages for Claude Code users (acknowledged in #21613). Every Python project using venv/virtualenv (which is effectively all of them) is affected when using worktree isolation.
What other tools do
claude-worktree(PyPI) — third-party wrapper that auto-symlinks.venvandnode_modules, supports configurable copy-files. Validates the need exists.git-worktree-runner(coderabbitai) — supportscopy_patternsandrun_hooks_in()post-creation.worktrunk— supports post-start hooks for dependency installation.
The ecosystem has independently converged on the same solution: a post-creation setup step. Claude Code is the only tool in this space that lacks it.
Why WorktreeCreate is not sufficient
Per the docs: "For other version control systems like SVN, Perforce, or Mercurial, configure WorktreeCreate and WorktreeRemove hooks to provide custom worktree creation and cleanup logic. When configured, these hooks replace the default git behavior."
WorktreeCreate replaces git worktree add — it's a VCS adapter, not a setup hook. Using it for environment setup requires reproducing Claude Code's internal git worktree logic, which is undocumented, may change, and creates a maintenance burden for users.
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗