diff --git a/plugins/compounding-engineering/skills/git-worktree/SKILL.md b/plugins/compounding-engineering/skills/git-worktree/SKILL.md index 71a1dae..c8ffc5e 100644 --- a/plugins/compounding-engineering/skills/git-worktree/SKILL.md +++ b/plugins/compounding-engineering/skills/git-worktree/SKILL.md @@ -15,6 +15,24 @@ This skill provides a unified interface for managing Git worktrees across your d - **Clean up completed worktrees** automatically - **Interactive confirmations** at each step - **Automatic .gitignore management** for worktree directory +- **Automatic .env file copying** from main repo to new worktrees + +## CRITICAL: Always Use the Manager Script + +**NEVER call `git worktree add` directly.** Always use the `worktree-manager.sh` script. + +The script handles critical setup that raw git commands don't: +1. Copies `.env`, `.env.local`, `.env.test`, etc. from main repo +2. Ensures `.worktrees` is in `.gitignore` +3. Creates consistent directory structure + +```bash +# ✅ CORRECT - Always use the script +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh create feature-name + +# ❌ WRONG - Never do this directly +git worktree add .worktrees/feature-name -b feature-name main +``` ## When to Use This Skill @@ -41,17 +59,20 @@ The skill is automatically called from `/review` and `/work` commands: You can also invoke the skill directly from bash: ```bash -# Create a new worktree -bash .claude/skills/git-worktree/scripts/worktree-manager.sh create feature-login +# Create a new worktree (copies .env files automatically) +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh create feature-login # List all worktrees -bash .claude/skills/git-worktree/scripts/worktree-manager.sh list +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh list # Switch to a worktree -bash .claude/skills/git-worktree/scripts/worktree-manager.sh switch feature-login +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh switch feature-login + +# Copy .env files to an existing worktree (if they weren't copied) +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh copy-env feature-login # Clean up completed worktrees -bash .claude/skills/git-worktree/scripts/worktree-manager.sh cleanup +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh cleanup ``` ## Commands @@ -66,14 +87,15 @@ Creates a new worktree with the given branch name. **Example:** ```bash -bash .claude/skills/git-worktree/scripts/worktree-manager.sh create feature-login +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh create feature-login ``` **What happens:** 1. Checks if worktree already exists 2. Updates the base branch from remote 3. Creates new worktree and branch -4. Shows path for cd-ing to the worktree +4. **Copies all .env files from main repo** (.env, .env.local, .env.test, etc.) +5. Shows path for cd-ing to the worktree ### `list` or `ls` @@ -81,7 +103,7 @@ Lists all available worktrees with their branches and current status. **Example:** ```bash -bash .claude/skills/git-worktree/scripts/worktree-manager.sh list +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh list ``` **Output shows:** @@ -96,7 +118,7 @@ Switches to an existing worktree and cd's into it. **Example:** ```bash -bash .claude/skills/git-worktree/scripts/worktree-manager.sh switch feature-login +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh switch feature-login ``` **Optional:** @@ -108,7 +130,7 @@ Interactively cleans up inactive worktrees with confirmation. **Example:** ```bash -bash .claude/skills/git-worktree/scripts/worktree-manager.sh cleanup +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh cleanup ``` **What happens:** @@ -126,35 +148,35 @@ bash .claude/skills/git-worktree/scripts/worktree-manager.sh cleanup # Offers: "Use worktree for isolated review? (y/n)" # You respond: yes -# Script runs: -bash .claude/skills/git-worktree/scripts/worktree-manager.sh create pr-123-feature-name +# Script runs (copies .env files automatically): +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh create pr-123-feature-name -# You're now in isolated worktree for review +# You're now in isolated worktree for review with all env vars cd .worktrees/pr-123-feature-name # After review, return to main: cd ../.. -bash .claude/skills/git-worktree/scripts/worktree-manager.sh cleanup +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh cleanup ``` ### Parallel Feature Development ```bash -# For first feature: -bash .claude/skills/git-worktree/scripts/worktree-manager.sh create feature-login +# For first feature (copies .env files): +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh create feature-login -# Later, start second feature: -bash .claude/skills/git-worktree/scripts/worktree-manager.sh create feature-notifications +# Later, start second feature (also copies .env files): +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh create feature-notifications # List what you have: -bash .claude/skills/git-worktree/scripts/worktree-manager.sh list +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh list # Switch between them as needed: -bash .claude/skills/git-worktree/scripts/worktree-manager.sh switch feature-login +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh switch feature-login # Return to main and cleanup when done: cd . -bash .claude/skills/git-worktree/scripts/worktree-manager.sh cleanup +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh cleanup ``` ## Key Design Principles @@ -216,11 +238,11 @@ If you see this, the script will ask if you want to switch to it instead. ### "Cannot remove worktree: it is the current worktree" -Switch out of the worktree first, then cleanup: +Switch out of the worktree first (to main repo), then cleanup: ```bash -cd /Users/kieranklaassen/rails/cora -bash .claude/skills/git-worktree/scripts/worktree-manager.sh cleanup +cd $(git rev-parse --show-toplevel) +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh cleanup ``` ### Lost in a worktree? @@ -228,7 +250,15 @@ bash .claude/skills/git-worktree/scripts/worktree-manager.sh cleanup See where you are: ```bash -bash .claude/skills/git-worktree/scripts/worktree-manager.sh list +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh list +``` + +### .env files missing in worktree? + +If a worktree was created without .env files (e.g., via raw `git worktree add`), copy them: + +```bash +bash ${CLAUDE_PLUGIN_ROOT}/skills/git-worktree/scripts/worktree-manager.sh copy-env feature-name ``` Navigate back to main: diff --git a/plugins/compounding-engineering/skills/git-worktree/scripts/worktree-manager.sh b/plugins/compounding-engineering/skills/git-worktree/scripts/worktree-manager.sh index d77943e..713c7fa 100755 --- a/plugins/compounding-engineering/skills/git-worktree/scripts/worktree-manager.sh +++ b/plugins/compounding-engineering/skills/git-worktree/scripts/worktree-manager.sh @@ -24,6 +24,47 @@ ensure_gitignore() { fi } +# Copy .env files from main repo to worktree +copy_env_files() { + local worktree_path="$1" + + echo -e "${BLUE}Copying environment files...${NC}" + + # Find all .env* files in root (excluding .env.example which should be in git) + local env_files=() + for f in "$GIT_ROOT"/.env*; do + if [[ -f "$f" ]]; then + local basename=$(basename "$f") + # Skip .env.example (that's typically committed to git) + if [[ "$basename" != ".env.example" ]]; then + env_files+=("$basename") + fi + fi + done + + if [[ ${#env_files[@]} -eq 0 ]]; then + echo -e " ${YELLOW}ℹ️ No .env files found in main repository${NC}" + return + fi + + local copied=0 + for env_file in "${env_files[@]}"; do + local source="$GIT_ROOT/$env_file" + local dest="$worktree_path/$env_file" + + if [[ -f "$dest" ]]; then + echo -e " ${YELLOW}⚠️ $env_file already exists, backing up to ${env_file}.backup${NC}" + cp "$dest" "${dest}.backup" + fi + + cp "$source" "$dest" + echo -e " ${GREEN}✓ Copied $env_file${NC}" + copied=$((copied + 1)) + done + + echo -e " ${GREEN}✓ Copied $copied environment file(s)${NC}" +} + # Create a new worktree create_worktree() { local branch_name="$1" @@ -71,6 +112,9 @@ create_worktree() { echo -e "${BLUE}Creating worktree...${NC}" git worktree add -b "$branch_name" "$worktree_path" "$from_branch" + # Copy environment files + copy_env_files "$worktree_path" + echo -e "${GREEN}✓ Worktree created successfully!${NC}" echo "" echo "To switch to this worktree:" @@ -141,6 +185,38 @@ switch_worktree() { echo -e "${BLUE}Now in: $(pwd)${NC}" } +# Copy env files to an existing worktree (or current directory if in a worktree) +copy_env_to_worktree() { + local worktree_name="$1" + local worktree_path + + if [[ -z "$worktree_name" ]]; then + # Check if we're currently in a worktree + local current_dir=$(pwd) + if [[ "$current_dir" == "$WORKTREE_DIR"/* ]]; then + worktree_path="$current_dir" + worktree_name=$(basename "$worktree_path") + echo -e "${BLUE}Detected current worktree: $worktree_name${NC}" + else + echo -e "${YELLOW}Usage: worktree-manager.sh copy-env [worktree-name]${NC}" + echo "Or run from within a worktree to copy to current directory" + list_worktrees + return 1 + fi + else + worktree_path="$WORKTREE_DIR/$worktree_name" + + if [[ ! -d "$worktree_path" ]]; then + echo -e "${RED}Error: Worktree not found: $worktree_name${NC}" + list_worktrees + return 1 + fi + fi + + copy_env_files "$worktree_path" + echo "" +} + # Clean up completed worktrees cleanup_worktrees() { if [[ ! -d "$WORKTREE_DIR" ]]; then @@ -213,6 +289,9 @@ main() { switch|go) switch_worktree "$2" ;; + copy-env|env) + copy_env_to_worktree "$2" + ;; cleanup|clean) cleanup_worktrees ;; @@ -235,16 +314,27 @@ Git Worktree Manager Usage: worktree-manager.sh [options] Commands: - create [from-branch] Create new worktree + create [from-branch] Create new worktree (copies .env files automatically) (from-branch defaults to main) list | ls List all worktrees switch | go [name] Switch to worktree + copy-env | env [name] Copy .env files from main repo to worktree + (if name omitted, uses current worktree) cleanup | clean Clean up inactive worktrees help Show this help message +Environment Files: + - Automatically copies .env, .env.local, .env.test, etc. on create + - Skips .env.example (should be in git) + - Creates .backup files if destination already exists + - Use 'copy-env' to refresh env files after main repo changes + Examples: worktree-manager.sh create feature-login + worktree-manager.sh create feature-auth develop worktree-manager.sh switch feature-login + worktree-manager.sh copy-env feature-login + worktree-manager.sh copy-env # copies to current worktree worktree-manager.sh cleanup worktree-manager.sh list