diff --git a/.githooks/pre-commit b/.githooks/pre-commit deleted file mode 100755 index 5153309..0000000 --- a/.githooks/pre-commit +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env bash -# .githooks/pre-commit — blocks sensitive files and API key patterns -set -euo pipefail - -RED='\033[0;31m'; YELLOW='\033[1;33m'; NC='\033[0m' - -BLOCKED_PATHS=( - "config/user.yaml" - "config/server.yaml" - "config/llm.yaml" - "config/notion.yaml" - "config/adzuna.yaml" - "config/label_tool.yaml" - ".env" -) - -BLOCKED_PATTERNS=( - "data/.*\.db$" - "data/.*\.jsonl$" - "demo/data/.*\.db$" -) - -KEY_REGEXES=( - 'sk-[A-Za-z0-9]{20,}' - 'Bearer [A-Za-z0-9\-_]{20,}' - 'api_key:[[:space:]]*["\x27]?[A-Za-z0-9\-_]{16,}' -) - -ERRORS=0 - -# Get list of staged files -EMPTY_TREE="4b825dc642cb6eb9a060e54bf8d69288fbee4904" -mapfile -t staged_files < <(git diff-index --cached --name-only HEAD 2>/dev/null || \ - git diff-index --cached --name-only "$EMPTY_TREE") - -for file in "${staged_files[@]}"; do - # Exact path blocklist - for blocked in "${BLOCKED_PATHS[@]}"; do - if [[ "$file" == "$blocked" ]]; then - echo -e "${RED}BLOCKED:${NC} $file is in the sensitive file blocklist." - echo -e " Use: ${YELLOW}git restore --staged $file${NC}" - ERRORS=$((ERRORS + 1)) - fi - done - - # Pattern blocklist - for pattern in "${BLOCKED_PATTERNS[@]}"; do - if echo "$file" | grep -qE "$pattern"; then - echo -e "${RED}BLOCKED:${NC} $file matches sensitive path pattern ($pattern)." - echo -e " Add to .gitignore or: ${YELLOW}git restore --staged $file${NC}" - ERRORS=$((ERRORS + 1)) - fi - done - - # Content scan for key patterns (only on existing staged files) - if [[ -f "$file" ]]; then - staged_content=$(git diff --cached -- "$file" 2>/dev/null | grep '^+' | grep -v '^+++' || true) - for regex in "${KEY_REGEXES[@]}"; do - if echo "$staged_content" | grep -qE "$regex"; then - echo -e "${RED}BLOCKED:${NC} $file appears to contain an API key or token." - echo -e " Pattern matched: ${YELLOW}$regex${NC}" - echo -e " Review with: ${YELLOW}git diff --cached -- $file${NC}" - echo -e " Use: ${YELLOW}git restore --staged $file${NC}" - ERRORS=$((ERRORS + 1)) - break - fi - done - fi -done - -if [[ $ERRORS -gt 0 ]]; then - echo "" - echo -e "${RED}Commit blocked.${NC} Fix the issues above and try again." - exit 1 -fi -exit 0 diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 0000000..42321db --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,11 @@ +# peregrine/.gitleaks.toml — per-repo allowlists extending the shared base config +[extend] +path = "/Library/Development/CircuitForge/circuitforge-hooks/gitleaks.toml" + +[allowlist] +description = "Peregrine-specific allowlists" +regexes = [ + '\d{10}\.html', # Craigslist listing IDs (10-digit paths, look like phone numbers) + '\d{10}\/', # LinkedIn job IDs in URLs + 'localhost:\d{4,5}', # port numbers that could trip phone pattern +] diff --git a/setup.sh b/setup.sh index 21b7c9e..25e1342 100755 --- a/setup.sh +++ b/setup.sh @@ -90,11 +90,15 @@ configure_git_safe_dir() { } activate_git_hooks() { - local repo_dir + local repo_dir hooks_installer repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - if [[ -d "$repo_dir/.githooks" ]]; then + hooks_installer="/Library/Development/CircuitForge/circuitforge-hooks/install.sh" + if [[ -f "$hooks_installer" ]]; then + bash "$hooks_installer" --quiet + success "CircuitForge hooks activated (circuitforge-hooks)." + elif [[ -d "$repo_dir/.githooks" ]]; then git -C "$repo_dir" config core.hooksPath .githooks - success "Git hooks activated (.githooks/)." + success "Git hooks activated (.githooks/) — circuitforge-hooks not found, using local fallback." fi }