2f321fb2aa
* Fix: Security allowlist not working in worktree mode
This fixes three related bugs that prevented .auto-claude-allowlist from working in isolated workspace (worktree) mode:
1. Security hook reads from wrong directory
- Hook used os.getcwd() which returns main project dir, not worktree
- Added AUTO_CLAUDE_PROJECT_DIR env var set by agent on startup
- Files: security/hooks.py, agents/coder.py, qa/loop.py
2. Security profile cache doesn't track allowlist changes
- Cache only tracked .auto-claude-security.json mtime
- Now also tracks .auto-claude-allowlist mtime
- File: security/profile.py
3. Allowlist not copied to worktree
- .env files were copied but not security config files
- Now copies both .auto-claude-allowlist and .auto-claude-security.json
- File: core/workspace/setup.py
Impact: Custom commands (cargo, dotnet, etc.) were always blocked in worktree mode even with proper allowlist configuration.
Tested on Windows with Rust project (cargo commands).
* Address Gemini Code Assist review comments
- hooks.py: Add input_data.get("cwd") back to priority chain (HIGH)
- coder.py: Move import os to top of file (MEDIUM)
- loop.py: Move import os to top of file (MEDIUM)
- profile.py: Remove redundant exists() check, catch FileNotFoundError (MEDIUM)
- setup.py: Refactor security files copying with loop (MEDIUM)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add clarifying comment for security file overwrite behavior
Addresses CodeRabbit review comment explaining why security files
always overwrite (unlike env files) - prevents security bypasses.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: Add security commands configuration guide
Explains the security system for command validation:
- How automatic stack detection works
- When and how to use .auto-claude-allowlist
- Troubleshooting common issues
- Worktree mode behavior
This helps users understand why commands may be blocked
and how to properly configure custom commands.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add error handling for security file copy
Addresses CodeRabbit review: wrap shutil.copy2 in try/except
to provide clear error messages instead of crashing on
permission or disk space issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: Fix markdown formatting nitpicks
- Add 'text' language specifier to ASCII diagram code block
- Add 'text' language specifier to allowlist example
- Add blank line before code fence in troubleshooting section
Addresses CodeRabbit trivial review comments.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: Use shared constants for security filenames and env var
Addresses Auto Claude PR Review findings:
MEDIUM:
- setup.py: Use ProjectAnalyzer.PROFILE_FILENAME and
StructureAnalyzer.CUSTOM_ALLOWLIST_FILENAME instead of magic strings
- profile.py: Use StructureAnalyzer.CUSTOM_ALLOWLIST_FILENAME
LOW:
- Create security/constants.py with PROJECT_DIR_ENV_VAR
- Use constant in hooks.py, coder.py, loop.py
- Expand worktree documentation to explain overwrite behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: Centralize security filenames in constants.py
Move ALLOWLIST_FILENAME and PROFILE_FILENAME to security/constants.py
for better cohesion. All security-related constants are now in one place.
- setup.py: Import from security.constants
- profile.py: Import from .constants (same module)
Addresses CodeRabbit review suggestion.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* style: Simplify exception handling (FileNotFoundError is subclass of OSError)
* style: Fix import sorting order (ruff I001)
* style: fix ruff formatting issues
- Add blank line after import inside function (hooks.py)
- Split global statements onto separate lines (profile.py)
- Reformat long if condition with `and` at line start (profile.py)
- Break long print_status line (setup.py)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Arcker <Arcker@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>