Skip to content

[FEATURE] Add PostWorktreeCreate hook (or setup command) for environment initialization in worktrees #27744

Description

@nikitaCodeSave

Preflight Checklist

  • I have searched existing requests and this feature hasn't been requested yet
  • 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 install is 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:

  1. Agent starts in a fresh worktree
  2. Agent tries to run pytest, ruff, mypy, or any Python script
  3. Fails — no .venv, no dependencies installed
  4. Agent must either:
    • pip install into 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:

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
  • WorktreeCreate is documented as a replacement for non-git VCS, not a post-creation hook
  • Symlinked .venv is unsafe if agent runs pip 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 .env files
  • 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 identifier
  • branch_name — the branch created by git worktree add
  • base_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

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 .venv and node_modules, supports configurable copy-files. Validates the need exists.
  • git-worktree-runner (coderabbitai) — supports copy_patterns and run_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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions