# Git & GitHub Operations Tasks
# Tasks for Git operations and GitHub PR management

version: '3'

tasks:
  default:
    desc: 'Show available Git tasks'
    aliases: [help, h]
    silent: true
    cmds:
      - |
        # Color codes
        GREEN='\033[0;32m'
        YELLOW='\033[0;33m'
        BOLD='\033[1m'
        NC='\033[0m'

        echo -e "${BOLD}Git & GitHub Operations${NC}"
        echo ""
        echo "Command                            Alias     Description                              Examples"
        echo "───────────────────────────────────────────────────────────────────────────────────────────────────"
        echo -e "${BOLD}Repository Utilities:${NC}"
        echo -e "  ${GREEN}task git:repo:root${NC}               ${YELLOW}root${NC}      Get repository root path"
        echo -e "  ${GREEN}task git:repo:url${NC}                ${YELLOW}url${NC}       Get repository HTTPS URL"
        echo -e "  ${GREEN}task git:branch:current${NC}          ${YELLOW}branch${NC}    Get current branch name"
        echo -e "  ${GREEN}task git:branch:default${NC}          ${YELLOW}main${NC}      Get default branch (main/master)"
        echo -e "  ${GREEN}task git:branch:list${NC}             ${YELLOW}bl${NC}        List branches with local/remote status"
        echo -e "  ${GREEN}task git:branch:prune${NC}            ${YELLOW}prune${NC}     Delete local branches gone on remote"
        echo -e "  ${GREEN}task git:token${NC}                   ${YELLOW}token${NC}     Get GitHub authentication token"
        echo ""
        echo -e "${BOLD}Pull Request Management:${NC}"
        echo -e "  ${GREEN}task git:pr:create${NC}               ${YELLOW}pr${NC}        Create/update draft PR from file         FILE=\".pr.local.md\""
        echo -e "  ${GREEN}task git:pr:open${NC}                 ${YELLOW}pro${NC}       Open current PR in browser"
        echo -e "  ${GREEN}task git:pr:list${NC}                 ${YELLOW}prl${NC}       List pull requests                       LIMIT=10 STATE=open"
        echo -e "  ${GREEN}task git:pr:comments${NC}             ${YELLOW}com${NC}       Get all comments from current PR"
        echo ""
        echo -e "${BOLD}GitHub Actions:${NC}"
        echo -e "  ${GREEN}task git:runs:log${NC}               ${YELLOW}logs${NC}      Download workflow run logs                STATE=all ALL=true"
        echo -e "  ${GREEN}task git:actions:pin${NC}            ${YELLOW}pin${NC}       Pin actions to SHAs                       UPGRADE=1 CHECK=1"
        echo ""
        echo -e "${BOLD}Security:${NC}"
        echo -e "  ${GREEN}task git:leaks${NC}                   ${YELLOW}leaks${NC}     Scan for secrets with gitleaks"
        echo -e "  ${GREEN}task git:cve${NC}                     ${YELLOW}cve${NC}       Download CVEs for repository             MIN_SEVERITY=medium"
        echo ""
        echo -e "${BOLD}Usage Examples:${NC}"
        echo -e "  task git:pr:list LIMIT=20 STATE=open           List 20 open PRs"
        echo -e "  task git:pr:create FILE=\"custom.md\"            Create PR from custom file"
        echo -e "  task git:runs:log                              Download latest failed run"
        echo -e "  task git:runs:log STATE=all ALL=true           Download all runs (any state)"
        echo -e "  task git:runs:log RUN_ID=12345678              Download specific run"
        echo -e "  task git:runs:log WORKFLOW=\"Tests\" STATE=all   Download all test runs"
        echo ""

  cli:
    internal: true
    silent: true
    desc: Verify that gh CLI is installed, and install if not found
    cmds:
      - |
        # Check if gh is already installed
        if command -v gh &> /dev/null; then
          exit 0
        fi

        # gh not found, install it silently
        echo "Installing GitHub CLI..."

        # Detect OS
        OS="$(uname -s)"
        case "$OS" in
          Darwin)
            # macOS - use Homebrew
            if command -v brew &> /dev/null; then
              brew install gh --quiet
            else
              echo "Error: Homebrew not found. Install from https://brew.sh"
              exit 1
            fi
            ;;

          Linux)
            # Linux - try different package managers
            if command -v apt-get &> /dev/null; then
              # Debian/Ubuntu
              sudo mkdir -p -m 755 /etc/apt/keyrings
              wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null
              sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg
              echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
              sudo apt-get update -qq
              sudo apt-get install -qq -y gh
            elif command -v dnf &> /dev/null; then
              # Fedora/RHEL 9+
              sudo dnf install -q -y 'dnf-command(config-manager)'
              sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
              sudo dnf install -q -y gh
            elif command -v yum &> /dev/null; then
              # RHEL/CentOS 8
              sudo yum install -q -y 'dnf-command(config-manager)'
              sudo yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
              sudo yum install -q -y gh
            else
              echo "Error: No supported package manager found (apt-get, dnf, yum)"
              echo "Install manually from https://github.com/cli/cli/releases"
              exit 1
            fi
            ;;

          MINGW*|MSYS*|CYGWIN*)
            # Windows - try winget, then choco, then scoop
            if command -v winget.exe &> /dev/null; then
              winget.exe install --id GitHub.cli --silent --accept-package-agreements --accept-source-agreements
            elif command -v choco &> /dev/null; then
              choco install gh -y
            elif command -v scoop &> /dev/null; then
              scoop install gh
            else
              echo "Error: No supported package manager found (winget, chocolatey, scoop)"
              echo "Install manually from https://github.com/cli/cli/releases"
              exit 1
            fi
            ;;

          *)
            echo "Error: Unsupported operating system: $OS"
            echo "Install manually from https://github.com/cli/cli/releases"
            exit 1
            ;;
        esac

        # Verify installation
        if command -v gh &> /dev/null; then
          echo "✓ GitHub CLI installed successfully"
        else
          echo "Error: Installation completed but gh command not found"
          echo "Try closing and reopening your terminal"
          exit 1
        fi

  token:
    desc: Get the authentication token
    aliases: [token]
    silent: true
    cmds:
      - |
        # Source secrets if .env has 1Password references
        source $(task op:export)

        # Check if token is still encrypted (force a refresh)
        if [[ "${GITHUB_TOKEN:-}" == *"op://"* ]]; then
          source $(task op:export:force)
        fi

        # Check if token is STILL encrypted (1Password reference not resolved)
        if [[ "${GITHUB_TOKEN:-}" == *"op://"* ]]; then
          echo -e "${RED}❌ Unable to decrypt authentication token${NC}" >&2
          echo "1Password CLI may not be installed or configured" >&2
          exit 1
        fi

        # Validate GitHub token is available
        if [ -z "${GITHUB_TOKEN:-}" ]; then
          echo -e "${RED}❌ GitHub token not found${NC}" >&2
          echo "Set GITHUB_TOKEN in .env" >&2
          exit 1
        fi

        # Output token for capture by calling task
        echo "$GITHUB_TOKEN"

  repo:root:
    desc: Get the absolute path to the repository root
    silent: true
    aliases: [root]
    cmds:
      - |
        ROOT_DIR=$(git rev-parse --show-toplevel)
        if [ -z "$ROOT_DIR" ]; then
          echo "Error: Not in a git repository"
          exit 1
        fi
        echo "$ROOT_DIR"

  repo:url:
    silent: true
    aliases: [url]
    desc: Get repository HTTPS URL from git remote (converts SSH to HTTPS, git@git alias to github.com)
    cmds:
      - |
        # Get remote URL
        REMOTE_URL=$(git remote get-url origin 2>/dev/null)

        if [ -z "$REMOTE_URL" ]; then
          echo "Error: No git remote 'origin' found" >&2
          exit 1
        fi

        # Convert SSH URL to HTTPS URL using sed (more reliable than bash regex)
        # SSH formats:
        #   git@github.com:owner/repo.git
        #   git@git:owner/repo.git (alias for github.com)
        # HTTPS formats:
        #   https://github.com/owner/repo.git

        if echo "$REMOTE_URL" | grep -q '^git@'; then
          # SSH format: git@host:owner/repo.git
          # Extract host and path using sed
          HOST=$(echo "$REMOTE_URL" | sed -E 's/^git@([^:]+):.*/\1/')
          PATH=$(echo "$REMOTE_URL" | sed -E 's/^git@[^:]+:(.*)/\1/')

          # Remove .git suffix if present
          PATH="${PATH%.git}"

          # Convert git@git alias to github.com
          if [ "$HOST" = "git" ]; then
            HOST="github.com"
          fi

          HTTPS_URL="https://${HOST}/${PATH}"
        elif echo "$REMOTE_URL" | grep -q '^https\?://'; then
          # Already HTTPS format
          HTTPS_URL="${REMOTE_URL%.git}"
        else
          echo "Error: Unrecognized git remote URL format: $REMOTE_URL" >&2
          exit 1
        fi

        echo "$HTTPS_URL"

  branch:current:
    desc: Get the current branch name
    aliases: [branch]
    silent: true
    cmds:
      - |
        CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
        if [ -z "$CURRENT_BRANCH" ]; then
          echo "Error: Not in a git repository" >&2
          exit 1
        fi
        echo "$CURRENT_BRANCH"

  branch:default:
    desc: Get the default branch (main/master)
    silent: true
    aliases: [main]
    cmds:
      - |
        # Get default branch (local-only, no network access needed)
        DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')

        # Fallback: try to detect from remote branches
        if [ -z "$DEFAULT_BRANCH" ]; then
          if git show-ref --verify --quiet refs/remotes/origin/main; then
            DEFAULT_BRANCH="main"
          elif git show-ref --verify --quiet refs/remotes/origin/master; then
            DEFAULT_BRANCH="master"
          else
            # Last resort: use gh CLI
            DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' 2>/dev/null || echo "main")
          fi
        fi

        if [ -z "$DEFAULT_BRANCH" ]; then
          echo "Error: Unable to determine default branch" >&2
          exit 1
        fi

        echo "$DEFAULT_BRANCH"

  branch:prune:
    desc: Delete local branches that no longer exist on remote
    silent: true
    aliases: [prune, clean-branches]
    cmds:
      - bun run ./src/tasks/git/branch-prune.ts

  branch:list:
    desc: List all branches with local/remote status
    silent: true
    aliases: [branches, bl]
    cmds:
      - |
        # Color codes
        GREEN='\033[0;32m'
        YELLOW='\033[0;33m'
        RED='\033[0;31m'
        CYAN='\033[0;36m'
        BOLD='\033[1m'
        NC='\033[0m'

        # Fetch latest remote info (silent)
        git fetch --prune &>/dev/null || true

        # Get current branch
        CURRENT=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")

        # Get default branch
        DEFAULT=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main")

        # Collect local branches (strip * for current, + for worktree)
        LOCAL_BRANCHES=$(git branch 2>/dev/null | sed 's/^[\*+] //' | sed 's/^ *//' | sort -u)

        # Collect remote branches (strip origin/ prefix)
        REMOTE_BRANCHES=$(git branch -r 2>/dev/null | grep -v '\->' | sed 's/^ *//' | sed 's|^origin/||' | sort -u)

        # Combine and dedupe all branches
        ALL_BRANCHES=$(printf "%s\n%s" "$LOCAL_BRANCHES" "$REMOTE_BRANCHES" | sort -u | grep -v '^$')

        # Print header
        printf "${BOLD}Branches${NC}\n\n"
        printf "%-44s %-10s %-10s %s\n" "Branch" "Local" "Remote" "Status"
        printf "────────────────────────────────────────────────────────────────────────────────\n"

        # Counters
        TOTAL=0
        SYNCED=0
        LOCAL_ONLY=0
        REMOTE_ONLY=0

        # Process each branch
        echo "$ALL_BRANCHES" | while read -r branch; do
          [ -z "$branch" ] && continue

          # Check if exists locally
          IS_LOCAL=$(echo "$LOCAL_BRANCHES" | grep -Fx "$branch" > /dev/null && echo "yes" || echo "no")

          # Check if exists remotely
          IS_REMOTE=$(echo "$REMOTE_BRANCHES" | grep -Fx "$branch" > /dev/null && echo "yes" || echo "no")

          # Determine indicators and status
          if [ "$IS_LOCAL" = "yes" ] && [ "$IS_REMOTE" = "yes" ]; then
            LOCAL_IND="${GREEN}✓${NC}"
            REMOTE_IND="${GREEN}✓${NC}"
            STATUS="${GREEN}synced${NC}"
          elif [ "$IS_LOCAL" = "yes" ]; then
            LOCAL_IND="${GREEN}✓${NC}"
            REMOTE_IND="${RED}✗${NC}"
            STATUS="${YELLOW}local only${NC}"
          else
            LOCAL_IND="${RED}✗${NC}"
            REMOTE_IND="${GREEN}✓${NC}"
            STATUS="${CYAN}remote only${NC}"
          fi

          # Mark current and default branches
          MARKER=""
          if [ "$branch" = "$CURRENT" ]; then
            MARKER=" ${CYAN}← current${NC}"
          elif [ "$branch" = "$DEFAULT" ]; then
            MARKER=" ${YELLOW}← default${NC}"
          fi

          # Print row
          printf "%-44s ${LOCAL_IND}          ${REMOTE_IND}          ${STATUS}${MARKER}\n" "$branch"
        done

        # Calculate summary (outside subshell)
        TOTAL=$(echo "$ALL_BRANCHES" | grep -c '.' || echo 0)
        SYNCED=0
        LOCAL_ONLY=0
        REMOTE_ONLY=0

        echo "$ALL_BRANCHES" | while read -r branch; do
          [ -z "$branch" ] && continue
          IS_LOCAL=$(echo "$LOCAL_BRANCHES" | grep -Fx "$branch" > /dev/null && echo "yes" || echo "no")
          IS_REMOTE=$(echo "$REMOTE_BRANCHES" | grep -Fx "$branch" > /dev/null && echo "yes" || echo "no")
          if [ "$IS_LOCAL" = "yes" ] && [ "$IS_REMOTE" = "yes" ]; then
            SYNCED=$((SYNCED + 1))
          elif [ "$IS_LOCAL" = "yes" ]; then
            LOCAL_ONLY=$((LOCAL_ONLY + 1))
          else
            REMOTE_ONLY=$((REMOTE_ONLY + 1))
          fi
          echo "$SYNCED $LOCAL_ONLY $REMOTE_ONLY"
        done | tail -1 | read SYNCED LOCAL_ONLY REMOTE_ONLY 2>/dev/null || true

        # Recalculate to avoid subshell issue
        SYNCED=$(echo "$ALL_BRANCHES" | while read -r b; do
          [ -z "$b" ] && continue
          IL=$(echo "$LOCAL_BRANCHES" | grep -Fx "$b" > /dev/null && echo "y" || echo "n")
          IR=$(echo "$REMOTE_BRANCHES" | grep -Fx "$b" > /dev/null && echo "y" || echo "n")
          [ "$IL" = "y" ] && [ "$IR" = "y" ] && echo "$b"
        done | grep -c '.' || echo 0)

        LOCAL_ONLY=$(echo "$ALL_BRANCHES" | while read -r b; do
          [ -z "$b" ] && continue
          IL=$(echo "$LOCAL_BRANCHES" | grep -Fx "$b" > /dev/null && echo "y" || echo "n")
          IR=$(echo "$REMOTE_BRANCHES" | grep -Fx "$b" > /dev/null && echo "y" || echo "n")
          [ "$IL" = "y" ] && [ "$IR" = "n" ] && echo "$b"
        done | grep -c '.' || echo 0)

        REMOTE_ONLY=$(echo "$ALL_BRANCHES" | while read -r b; do
          [ -z "$b" ] && continue
          IL=$(echo "$LOCAL_BRANCHES" | grep -Fx "$b" > /dev/null && echo "y" || echo "n")
          IR=$(echo "$REMOTE_BRANCHES" | grep -Fx "$b" > /dev/null && echo "y" || echo "n")
          [ "$IL" = "n" ] && [ "$IR" = "y" ] && echo "$b"
        done | grep -c '.' || echo 0)

        printf "\n${BOLD}Summary:${NC} $TOTAL branches ($SYNCED synced, $LOCAL_ONLY local only, $REMOTE_ONLY remote only)\n"

  pr:list:
    desc: 'List pull requests (use LIMIT=n to change number shown, default 10)'
    silent: true
    deps: [cli]
    dotenv: ['.env']
    vars:
      LIMIT: '{{.LIMIT | default "10"}}'
      STATE: '{{.STATE | default "all"}}'
    cmds:
      - |
        # Get and validate GitHub token (handles 1Password decryption)
        export GH_TOKEN=$(task git:token)

        # Get repository info
        REPO=$(task git:repo:url)

        # If that fails, extract from git remote
        if [ -z "$REPO" ]; then
          REPO=$(git remote get-url origin | sed -E 's|^(https://github.com/|git@github.com:)||' | sed 's|\.git$||')
        fi

        echo -e "{{.CYAN}}Pull Requests for: $REPO{{.NC}}"
        echo ""

        # List PRs with state filter
        STATE="{{.STATE}}"
        STATE_FILTER=""
        if [ "$STATE" != "all" ]; then
          STATE_FILTER="--state $STATE"
        fi

        # Show PRs in a nice table format
        gh pr list $STATE_FILTER --limit {{.LIMIT}} --json number,title,state,author,createdAt,isDraft,headRefName,baseRefName --jq '.[] | "#\(.number) | " + (if .isDraft then "📝 " else "" end) + (.title | .[0:60]) + (if (.title | length) > 60 then "..." else "" end) + " | " + (.state | ascii_upcase) + " | " + .author.login + " | " + (.headRefName + " → " + .baseRefName) + " | " + (.createdAt | fromdateiso8601 | strftime("%Y-%m-%d"))' | column -t -s '|'

        echo ""
        echo -e "{{.YELLOW}}Total shown: {{.LIMIT}} (use LIMIT=n to change){{.NC}}"
        echo -e "{{.YELLOW}}State filter: {{.STATE}} (use STATE=open|closed|merged|all){{.NC}}"

    aliases: [prl]

  pr:create:
    desc: Create draft GitHub pull request from markdown file
    aliases: [pr]
    deps: [cli]
    silent: true
    vars:
      PR_FILE: '{{.FILE | default ".pr.local.md"}}'
    cmds:
      - |
        set -euo pipefail

        # Color codes
        GREEN='\033[0;32m'
        YELLOW='\033[0;33m'
        RED='\033[0;31m'
        BOLD='\033[1m'
        NC='\033[0m'

        PR_FILE="{{.PR_FILE}}"
        PR_URL=""
        PR_NUMBER=""
        PR_ACTION=""

        # Validate PR file exists
        if [ ! -f "$PR_FILE" ]; then
          echo -e "${RED}❌ PR file not found: $PR_FILE${NC}" >&2
          echo "Run /pr command first to generate PR content" >&2
          exit 1
        fi

        # Get and validate GitHub token (handles 1Password decryption)
        export GH_TOKEN=$(task git:token)

        # Ensure we're in a git repository
        if ! git rev-parse --git-dir > /dev/null 2>&1; then
          echo -e "${RED}❌ Not in a git repository${NC}" >&2
          exit 1
        fi

        # Check if current branch has commits
        if ! git log -1 > /dev/null 2>&1; then
          echo -e "${RED}❌ No commits on current branch${NC}" >&2
          echo "Make at least one commit before creating PR" >&2
          exit 1
        fi

        # Extract title (first line starting with # )
        TITLE=$(grep "^# " "$PR_FILE" | head -n 1 | sed 's/^# //')

        if [ -z "$TITLE" ]; then
          echo -e "${RED}❌ No title found in PR file${NC}" >&2
          echo "PR file must start with '# Title'" >&2
          exit 1
        fi

        # Extract body (everything after first line, skip empty lines at start)
        BODY=$(sed '1d' "$PR_FILE" | sed -e :a -e '/./,$!d;/^\n*$/{$d;N;};/\n$/ba')

        if [ -z "$BODY" ]; then
          echo -e "${RED}❌ No body content found in PR file${NC}" >&2
          exit 1
        fi

        echo -e "${GREEN}✓${NC} Title: $TITLE"

        # Get current and default branches
        CURRENT_BRANCH=$(task git:branch:current)
        DEFAULT_BRANCH=$(task git:branch:default)

        # Push branch to remote (gh pr create will handle this if needed)
        # Try to push, but don't fail if SSH isn't configured - gh CLI will use HTTPS

        if git push -u origin "$CURRENT_BRANCH" &>/dev/null; then
          echo -e "${GREEN}✓${NC} Branch pushed to origin/$CURRENT_BRANCH"
        else
          echo -e "${YELLOW}⚠${NC} Git push failed (possibly SSH not configured)"
          echo -e "${YELLOW}→${NC} Will rely on gh CLI to push via HTTPS"
        fi

        # Check if PR already exists for this branch
        EXISTING_PR=$(gh pr list --head "$CURRENT_BRANCH" --base "$DEFAULT_BRANCH" --json number --jq '.[0].number' 2>/dev/null || echo "")

        if [ -n "$EXISTING_PR" ]; then
          # Update PR title and body
          gh pr edit "$EXISTING_PR" \
            --title "$TITLE" \
            --body "$BODY" &>/dev/null

          PR_NUMBER="$EXISTING_PR"
          PR_ACTION="Updated"
        else
          # Create draft PR and capture output
          PR_OUTPUT=$(gh pr create \
            --base "$DEFAULT_BRANCH" \
            --head "$CURRENT_BRANCH" \
            --draft \
            --title "$TITLE" \
            --body "$BODY" 2>&1)

          if [ $? -ne 0 ]; then
            echo -e "${RED}❌ Failed to create PR${NC}" >&2
            echo "$PR_OUTPUT" >&2
            exit 1
          fi

          # Extract PR number from output URL
          PR_URL=$(echo "$PR_OUTPUT" | grep -o 'https://github.com/[^/]*/[^/]*/pull/[0-9]*' | head -1)
          PR_NUMBER=$(echo "$PR_URL" | grep -o '[0-9]*$')
          PR_ACTION="Created"
        fi

        # Get PR URL for opening in browser
        if [ -z "$PR_URL" ] && [ -n "$PR_NUMBER" ]; then
          # Get URL from gh CLI
          PR_URL=$(gh pr view "$PR_NUMBER" --json url --jq '.url' 2>/dev/null || echo "")
        fi

        # Display success message with URL
        if [ -n "$PR_URL" ]; then
          echo -e "${GREEN}✓${NC} ${PR_ACTION}: $PR_URL"

          # Open PR in browser (cross-platform)
          if [ "$(uname)" = "Darwin" ]; then
            # macOS
            open "$PR_URL"
          elif [ "$(uname)" = "Linux" ]; then
            # Linux
            if command -v xdg-open &> /dev/null; then
              xdg-open "$PR_URL"
            fi
          elif [ "$(uname -o 2>/dev/null)" = "Msys" ] || [ "$(uname -o 2>/dev/null)" = "Cygwin" ]; then
            # Windows (Git Bash or Cygwin)
            start "$PR_URL"
          fi
        fi

  pr:open:
    desc: Open current pull request in browser
    aliases: [pro]
    deps: [cli]
    silent: true
    cmds:
      - |
        set -euo pipefail

        # Color codes
        GREEN='\033[0;32m'
        YELLOW='\033[0;33m'
        RED='\033[0;31m'
        BOLD='\033[1m'
        NC='\033[0m'

        # Get and validate GitHub token
        export GH_TOKEN=$(task git:token)

        # Get current and default branches
        CURRENT_BRANCH=$(task git:branch:current)
        DEFAULT_BRANCH=$(task git:branch:default)

        # Check if PR exists for this branch
        PR_NUMBER=$(gh pr list --head "$CURRENT_BRANCH" --base "$DEFAULT_BRANCH" --json number --jq '.[0].number' 2>/dev/null || echo "")

        if [ -z "$PR_NUMBER" ]; then
          echo -e "${RED}❌ No pull request found for branch: $CURRENT_BRANCH${NC}" >&2
          echo "" >&2
          echo "Create a PR first:" >&2
          echo -e "  ${GREEN}task git:pr:create${NC}" >&2
          echo "" >&2
          exit 1
        fi

        # Get PR URL
        PR_URL=$(gh pr view "$PR_NUMBER" --json url --jq '.url' 2>/dev/null || echo "")

        if [ -z "$PR_URL" ]; then
          echo -e "${RED}❌ Failed to get PR URL${NC}" >&2
          exit 1
        fi

        echo -e "${GREEN}✓${NC} Opening: $PR_URL"

        # Detect OS and open browser
        if [ "$(uname)" = "Darwin" ]; then
          open "$PR_URL"
        elif [ "$(uname)" = "Linux" ]; then
          if command -v xdg-open &> /dev/null; then
            xdg-open "$PR_URL"
          fi
        elif [ "$(uname -o 2>/dev/null)" = "Msys" ] || [ "$(uname -o 2>/dev/null)" = "Cygwin" ]; then
          start "$PR_URL"
        fi

  pr:comments:
    desc: Retrieve all comments of the current pull request
    aliases: [com]
    silent: true
    deps: [cli]
    vars:
      REPO_ROOT:
        sh: git rev-parse --show-toplevel 2>/dev/null || pwd
      LOG_DIR:
        sh: echo "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.logs/github/comments"
    cmds:
      - |
        # Color codes
        GREEN='\033[0;32m'
        RED='\033[0;31m'
        NC='\033[0m'

        # Get and validate GitHub token
        export GH_TOKEN=$(task git:token)

        # Get current branch and repository
        CURRENT_BRANCH=$(task git:branch:current)
        DEFAULT_BRANCH=$(task git:branch:default)
        REPO=$(task git:repo:url | sed -E 's|^https://github.com/||')

        # Find PR for current branch
        PR_NUMBER=$(gh pr list --head "$CURRENT_BRANCH" --base "$DEFAULT_BRANCH" --json number --jq '.[0].number' 2>/dev/null || echo "")

        if [ -z "$PR_NUMBER" ]; then
          echo -e "${RED}❌ No pull request found for branch: $CURRENT_BRANCH${NC}" >&2
          exit 1
        fi

        # Get PR details
        PR_DATA=$(gh pr view "$PR_NUMBER" --json number,title,author,state)
        PR_TITLE=$(echo "$PR_DATA" | jq -r '.title')
        PR_AUTHOR=$(echo "$PR_DATA" | jq -r '.author.login')
        PR_STATE=$(echo "$PR_DATA" | jq -r '.state')

        # Create log directory
        mkdir -p "{{.LOG_DIR}}"

        # Generate timestamp
        TIMESTAMP=$(date +%Y%m%d-%H%M%S)
        LOG_FILE="{{.LOG_DIR}}/${TIMESTAMP}.log"

        # Fetch all comments (silent)
        {
          echo "=========================================="
          echo "PR Comments Report"
          echo "=========================================="
          echo "Generated: $(date)"
          echo "Repository: $REPO"
          echo "PR #$PR_NUMBER: $PR_TITLE"
          echo "Author: $PR_AUTHOR"
          echo "State: $PR_STATE"
          echo "Branch: $CURRENT_BRANCH"
          echo ""
          echo "=========================================="
          echo "ISSUE COMMENTS (General PR Discussion)"
          echo "=========================================="
          echo ""

          # Get issue comments
          ISSUE_COMMENTS=$(gh api "/repos/$REPO/issues/$PR_NUMBER/comments" --paginate 2>/dev/null | jq -s 'add // []')
          ISSUE_COUNT=$(echo "$ISSUE_COMMENTS" | jq 'length')

          if [ "$ISSUE_COUNT" -gt 0 ]; then
            echo "$ISSUE_COMMENTS" | jq -r '.[] | "[@\(.user.login)] \(.created_at)\n\(.body)\n\n---\n"'
          else
            echo "No general comments found."
            echo ""
          fi

          echo ""
          echo "=========================================="
          echo "REVIEW COMMENTS (Inline Code Comments)"
          echo "=========================================="
          echo ""

          # Get review comments
          REVIEW_COMMENTS=$(gh api "/repos/$REPO/pulls/$PR_NUMBER/comments" --paginate 2>/dev/null | jq -s 'add // []')
          REVIEW_COUNT=$(echo "$REVIEW_COMMENTS" | jq 'length')

          if [ "$REVIEW_COUNT" -gt 0 ]; then
            echo "$REVIEW_COMMENTS" | jq -r '.[] | "[@\(.user.login)] \(.path):\(.line // .original_line // "??") - \(.created_at)\n\(.body)\n\n---\n"'
          else
            echo "No code review comments found."
            echo ""
          fi

          echo ""
          echo "=========================================="
          echo "REVIEWS (Approve/Request Changes/Comment)"
          echo "=========================================="
          echo ""

          # Get reviews
          REVIEWS=$(gh api "/repos/$REPO/pulls/$PR_NUMBER/reviews" --paginate 2>/dev/null | jq -s 'add // []')
          REVIEWS_COUNT=$(echo "$REVIEWS" | jq 'length')

          if [ "$REVIEWS_COUNT" -gt 0 ]; then
            echo "$REVIEWS" | jq -r '.[] | "[@\(.user.login)] \(.state) - \(.submitted_at)\n\(.body // "No comment")\n\n---\n"'
          else
            echo "No reviews found."
            echo ""
          fi

          echo ""
          echo "=========================================="
          echo "SUMMARY"
          echo "=========================================="
          echo "General comments: $ISSUE_COUNT"
          echo "Code review comments: $REVIEW_COUNT"
          echo "Reviews: $REVIEWS_COUNT"
          echo "Total: $((ISSUE_COUNT + REVIEW_COUNT + REVIEWS_COUNT))"
        } > "$LOG_FILE"

        # Display summary - calculate counts from already-fetched data
        ISSUE_COUNT=$(gh api "/repos/$REPO/issues/$PR_NUMBER/comments" --paginate 2>/dev/null | jq -s 'add // [] | length')
        REVIEW_COUNT=$(gh api "/repos/$REPO/pulls/$PR_NUMBER/comments" --paginate 2>/dev/null | jq -s 'add // [] | length')
        REVIEWS_COUNT=$(gh api "/repos/$REPO/pulls/$PR_NUMBER/reviews" --paginate 2>/dev/null | jq -s 'add // [] | length')
        TOTAL=$((ISSUE_COUNT + REVIEW_COUNT + REVIEWS_COUNT))

        echo -e "${GREEN}✓${NC} Retrieved $TOTAL comments for PR #$PR_NUMBER → $LOG_FILE"

        # Open in VSCode if available (silent if not installed)
        if command -v code &> /dev/null; then
          code "$LOG_FILE" 2>/dev/null || true
        fi

  runs:log:
    desc: Download GitHub Actions workflow run logs
    aliases: [logs, rl]
    silent: true
    deps: [cli]
    vars:
      RUN_ID: '{{.RUN_ID | default ""}}'
      WORKFLOW: '{{.WORKFLOW | default ""}}'
      STATE: '{{.STATE | default "failure"}}'
      ALL: '{{.ALL | default "false"}}'
      REPO_ROOT:
        sh: git rev-parse --show-toplevel 2>/dev/null || pwd
      BASE_LOG_DIR:
        sh: echo "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.logs/github/runs"
    cmds:
      - |
        set -euo pipefail

        # Color codes
        GREEN='\033[0;32m'
        RED='\033[0;31m'
        YELLOW='\033[0;33m'
        NC='\033[0m'

        # Get and validate GitHub token
        export GH_TOKEN=$(task git:token)

        # Get repository info
        REPO=$(task git:repo:url | sed -E 's|^https://github.com/||')

        STATE="{{.STATE}}"
        DOWNLOAD_ALL="{{.ALL}}"

        # Create timestamped directory for this download session
        TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
        SESSION_DIR="{{.BASE_LOG_DIR}}/${TIMESTAMP}"
        mkdir -p "$SESSION_DIR"

        # Get current branch
        CURRENT_BRANCH=$(task git:branch:current)

        # If RUN_ID specified, download that specific run (ignore STATE and ALL)
        if [ -n "{{.RUN_ID}}" ]; then
          RUN_IDS=("{{.RUN_ID}}")
        elif [ "$DOWNLOAD_ALL" = "true" ]; then
          # Download all historical runs matching STATE (up to 100)
          WORKFLOW_FILTER=""
          if [ -n "{{.WORKFLOW}}" ]; then
            WORKFLOW_FILTER="--workflow {{.WORKFLOW}}"
          fi

          RUN_DATA=$(gh run list \
            -b "$CURRENT_BRANCH" \
            $WORKFLOW_FILTER \
            --status completed \
            --limit 100 \
            --json databaseId,name,conclusion 2>/dev/null || echo "[]")

          if [ "$RUN_DATA" = "[]" ] || [ -z "$RUN_DATA" ]; then
            echo -e "${RED}❌ No workflow runs found${NC}" >&2
            exit 1
          fi

          # Filter by conclusion/state
          if [ "$STATE" != "all" ]; then
            RUN_IDS=($(echo "$RUN_DATA" | jq -r ".[] | select(.conclusion == \"$STATE\") | .databaseId"))
          else
            RUN_IDS=($(echo "$RUN_DATA" | jq -r '.[].databaseId'))
          fi

          if [ ${#RUN_IDS[@]} -eq 0 ]; then
            echo -e "${YELLOW}⚠${NC}  No runs found with STATE=$STATE, switching to STATE=all"
            STATE="all"
            RUN_IDS=($(echo "$RUN_DATA" | jq -r '.[].databaseId'))
          fi
        else
          # Download latest run per workflow matching STATE
          WORKFLOW_FILTER=""
          if [ -n "{{.WORKFLOW}}" ]; then
            WORKFLOW_FILTER="--workflow {{.WORKFLOW}}"
          fi

          # Get all workflows in repo and latest run for each
          RUN_IDS=()

          if [ -n "{{.WORKFLOW}}" ]; then
            # Single workflow specified
            WORKFLOW_NAME="{{.WORKFLOW}}"

            if [ "$STATE" != "all" ]; then
              LATEST_RUN=$(gh run list \
                --workflow "$WORKFLOW_NAME" \
                -b "$CURRENT_BRANCH" \
                --status completed \
                --limit 10 \
                --json databaseId,conclusion 2>/dev/null | \
                jq -r ".[] | select(.conclusion == \"$STATE\") | .databaseId" | head -1)
            else
              LATEST_RUN=$(gh run list \
                --workflow "$WORKFLOW_NAME" \
                -b "$CURRENT_BRANCH" \
                --status completed \
                --limit 1 \
                --json databaseId 2>/dev/null | \
                jq -r '.[].databaseId')
            fi

            if [ -n "$LATEST_RUN" ]; then
              RUN_IDS+=("$LATEST_RUN")
            fi
          else
            # Get all workflows and process with while loop
            while IFS= read -r WORKFLOW_NAME; do
              [ -z "$WORKFLOW_NAME" ] && continue

              if [ "$STATE" != "all" ]; then
                LATEST_RUN=$(gh run list \
                  --workflow "$WORKFLOW_NAME" \
                  -b "$CURRENT_BRANCH" \
                  --status completed \
                  --limit 10 \
                  --json databaseId,conclusion 2>/dev/null | \
                  jq -r ".[] | select(.conclusion == \"$STATE\") | .databaseId" | head -1)
              else
                LATEST_RUN=$(gh run list \
                  --workflow "$WORKFLOW_NAME" \
                  -b "$CURRENT_BRANCH" \
                  --status completed \
                  --limit 1 \
                  --json databaseId 2>/dev/null | \
                  jq -r '.[].databaseId')
              fi

              if [ -n "$LATEST_RUN" ]; then
                RUN_IDS+=("$LATEST_RUN")
              fi
            done < <(gh api "/repos/$REPO/actions/workflows" --jq '.workflows[].name' 2>/dev/null)
          fi

          # Auto-fallback if no runs found
          if [ ${#RUN_IDS[@]} -eq 0 ]; then
            if [ "$STATE" != "all" ]; then
              echo -e "${YELLOW}⚠${NC}  No runs found with STATE=$STATE, retrying with STATE=all"
              STATE="all"
              RUN_IDS=()

              if [ -n "{{.WORKFLOW}}" ]; then
                WORKFLOW_NAME="{{.WORKFLOW}}"
                LATEST_RUN=$(gh run list \
                  --workflow "$WORKFLOW_NAME" \
                  -b "$CURRENT_BRANCH" \
                  --status completed \
                  --limit 1 \
                  --json databaseId 2>/dev/null | \
                  jq -r '.[].databaseId')

                if [ -n "$LATEST_RUN" ]; then
                  RUN_IDS+=("$LATEST_RUN")
                fi
              else
                while IFS= read -r WORKFLOW_NAME; do
                  [ -z "$WORKFLOW_NAME" ] && continue

                  LATEST_RUN=$(gh run list \
                    --workflow "$WORKFLOW_NAME" \
                    -b "$CURRENT_BRANCH" \
                    --status completed \
                    --limit 1 \
                    --json databaseId 2>/dev/null | \
                    jq -r '.[].databaseId')

                  if [ -n "$LATEST_RUN" ]; then
                    RUN_IDS+=("$LATEST_RUN")
                  fi
                done < <(gh api "/repos/$REPO/actions/workflows" --jq '.workflows[].name' 2>/dev/null)
              fi
            fi

            if [ ${#RUN_IDS[@]} -eq 0 ]; then
              echo -e "${RED}❌ No completed runs found on branch: $CURRENT_BRANCH${NC}" >&2
              exit 1
            fi
          fi
        fi

        # Download each run
        DOWNLOADED_COUNT=0
        TOTAL_LOGS=0
        LAST_LOG_DIR=""

        for RUN_ID in "${RUN_IDS[@]}"; do
          # Get run details (silent)
          RUN_INFO=$(gh api "/repos/$REPO/actions/runs/$RUN_ID" 2>/dev/null)

          if [ -z "$RUN_INFO" ]; then
            continue
          fi

          WORKFLOW_NAME=$(echo "$RUN_INFO" | jq -r '.name')
          WORKFLOW_SLUG=$(echo "$WORKFLOW_NAME" | tr ' ' '-' | tr '[:upper:]' '[:lower:]')
          RUN_NUMBER=$(echo "$RUN_INFO" | jq -r '.run_number')
          CONCLUSION=$(echo "$RUN_INFO" | jq -r '.conclusion // "in_progress"')

          # Create log directory within session
          LOG_DIR="$SESSION_DIR/${WORKFLOW_SLUG}-${RUN_ID}"
          mkdir -p "$LOG_DIR"

          # Download and extract logs (silent)
          if gh api "/repos/$REPO/actions/runs/$RUN_ID/logs" > "$LOG_DIR/logs.zip" 2>/dev/null; then
            # Extract logs (silent)
            cd "$LOG_DIR"
            if unzip -o -q logs.zip 2>/dev/null; then
              rm logs.zip

              # Save run metadata (silent)
              echo "$RUN_INFO" | jq '.' > "run-metadata.json" 2>/dev/null

              # Count log files
              LOG_COUNT=$(find . -name "*.txt" -type f | wc -l | tr -d ' ')
              TOTAL_LOGS=$((TOTAL_LOGS + LOG_COUNT))
              DOWNLOADED_COUNT=$((DOWNLOADED_COUNT + 1))
              LAST_LOG_DIR="$LOG_DIR"

              # Show individual success if downloading multiple
              if [ "$DOWNLOAD_ALL" = "true" ]; then
                echo -e "${GREEN}✓${NC} Run #$RUN_NUMBER ($CONCLUSION): $LOG_COUNT logs"
              fi
            fi
            cd - > /dev/null
          fi
        done

        # Display summary and generate README
        if [ $DOWNLOADED_COUNT -eq 0 ]; then
          echo -e "${RED}❌ Failed to download any logs${NC}" >&2
          exit 1
        fi

        # Always create README (for both single and multiple downloads)
        README_FILE="$SESSION_DIR/README.md"

        {
          echo "# GitHub Actions Workflow Runs"
          echo ""
          echo "**Downloaded:** $(date)"
          echo "**Repository:** $REPO"
          echo "**Branch:** $(task git:branch:current)"
          echo "**Filter:** STATE=$STATE"
          echo ""
          echo "**Total Runs:** $DOWNLOADED_COUNT"
          echo "**Total Log Files:** $TOTAL_LOGS"
          echo ""
          echo "## Run Details"
          echo ""
          echo "| Run # | Workflow | Conclusion | Logs | Directory |"
          echo "|-------|----------|------------|------|-----------|"

          # Generate table rows for each downloaded run
          for RUN_ID in "${RUN_IDS[@]}"; do
            RUN_INFO=$(gh api "/repos/$REPO/actions/runs/$RUN_ID" 2>/dev/null)

            if [ -z "$RUN_INFO" ]; then
              continue
            fi

            WORKFLOW_NAME=$(echo "$RUN_INFO" | jq -r '.name')
            WORKFLOW_SLUG=$(echo "$WORKFLOW_NAME" | tr ' ' '-' | tr '[:upper:]' '[:lower:]')
            RUN_NUMBER=$(echo "$RUN_INFO" | jq -r '.run_number')
            CONCLUSION=$(echo "$RUN_INFO" | jq -r '.conclusion // "in_progress"')
            RUN_DIR="${WORKFLOW_SLUG}-${RUN_ID}"

            # Count logs for this run
            RUN_LOG_COUNT=$(find "$SESSION_DIR/${RUN_DIR}" -name "*.txt" -type f 2>/dev/null | wc -l | tr -d ' ')

            # Format conclusion with emoji
            case "$CONCLUSION" in
              success)   CONCLUSION_DISPLAY="✅ success" ;;
              failure)   CONCLUSION_DISPLAY="❌ failure" ;;
              cancelled) CONCLUSION_DISPLAY="🚫 cancelled" ;;
              skipped)   CONCLUSION_DISPLAY="⏭️  skipped" ;;
              *)         CONCLUSION_DISPLAY="$CONCLUSION" ;;
            esac

            echo "| #$RUN_NUMBER | $WORKFLOW_NAME | $CONCLUSION_DISPLAY | $RUN_LOG_COUNT | [\`$RUN_DIR\`](./$RUN_DIR) |"
          done

          echo ""
          echo "## Quick Links"
          echo ""

          # Add links to each workflow directory
          for RUN_ID in "${RUN_IDS[@]}"; do
            RUN_INFO=$(gh api "/repos/$REPO/actions/runs/$RUN_ID" 2>/dev/null)

            if [ -z "$RUN_INFO" ]; then
              continue
            fi

            WORKFLOW_NAME=$(echo "$RUN_INFO" | jq -r '.name')
            WORKFLOW_SLUG=$(echo "$WORKFLOW_NAME" | tr ' ' '-' | tr '[:upper:]' '[:lower:]')
            RUN_NUMBER=$(echo "$RUN_INFO" | jq -r '.run_number')
            RUN_URL=$(echo "$RUN_INFO" | jq -r '.html_url')

            echo "- **Run #$RUN_NUMBER** ($WORKFLOW_NAME): [GitHub]($RUN_URL) • [Logs](./${WORKFLOW_SLUG}-${RUN_ID})"
          done
        } > "$README_FILE"

        # Display success message
        if [ $DOWNLOADED_COUNT -eq 1 ]; then
          RUN_ID="${RUN_IDS[0]}"
          RUN_INFO=$(gh api "/repos/$REPO/actions/runs/$RUN_ID" 2>/dev/null)
          RUN_NUMBER=$(echo "$RUN_INFO" | jq -r '.run_number')
          CONCLUSION=$(echo "$RUN_INFO" | jq -r '.conclusion // "in_progress"')

          echo -e "${GREEN}✓${NC} Downloaded $TOTAL_LOGS log files for run #$RUN_NUMBER ($CONCLUSION) → $SESSION_DIR"
        else
          echo -e "${GREEN}✓${NC} Downloaded $DOWNLOADED_COUNT runs with $TOTAL_LOGS total log files → $SESSION_DIR"
        fi

        # Open README in VSCode
        if command -v code &> /dev/null; then
          code "$README_FILE" 2>/dev/null || true
        fi

  actions:pin:
    desc: Pin GitHub Actions to specific commit SHAs with version comments
    silent: true
    aliases: [pin]
    vars:
      UPGRADE_FLAG: '{{if .UPGRADE}}--upgrade{{end}}'
      CHECK_FLAG: '{{if .CHECK}}--check{{end}}'
      DRY_RUN_FLAG: '{{if .DRY_RUN}}--dry-run{{end}}'
      TARGET_PATH: '{{.TARGET_PATH | default ".github/workflows"}}'
    cmds:
      - |
        # Get and validate GitHub token
        export GITHUB_TOKEN=$(task git:token)

        # Run pin-actions with authenticated API access
        ai-toolkit pin-actions {{.UPGRADE_FLAG}} {{.CHECK_FLAG}} {{.DRY_RUN_FLAG}} --target-path={{.TARGET_PATH}}

  leaks:
    desc: Scan for secrets with gitleaks
    silent: true
    aliases: [leaks]
    cmds:
      - |
        GREEN='\033[0;32m'
        YELLOW='\033[0;33m'
        RED='\033[0;31m'
        NC='\033[0m'

        echo -e "${YELLOW}🔍${NC} Running gitleaks secret scanner..."

        # Check if gitleaks is installed, install if not
        if ! command -v gitleaks >/dev/null 2>&1; then
          echo -e "${YELLOW}⚠️${NC}  gitleaks not installed, installing..."
          brew install gitleaks
        fi

        # Temporarily set git remote to HTTPS format for gitleaks platform detection
        REMOTE_URL=$(git remote get-url origin 2>/dev/null)
        RESTORED=false

        if [ -n "$REMOTE_URL" ] && echo "$REMOTE_URL" | grep -q '^git@'; then
          # SSH format: convert to HTTPS temporarily
          HOST=$(echo "$REMOTE_URL" | sed -E 's/^git@([^:]+):.*/\1/')
          REPO_PATH=$(echo "$REMOTE_URL" | sed -E 's/^git@[^:]+:(.*)/\1/')
          REPO_PATH="${REPO_PATH%.git}"
          # Convert git@git alias to github.com
          if [ "$HOST" = "git" ]; then
            HOST="github.com"
          fi
          HTTPS_URL="https://${HOST}/${REPO_PATH}"

          # Temporarily update remote for platform detection
          git remote set-url origin "$HTTPS_URL" 2>/dev/null && RESTORED=true
        fi

        # Run gitleaks (will auto-detect platform from git remote)
        if gitleaks detect --verbose --redact; then
          echo -e "${GREEN}✓${NC} No secrets found by gitleaks"
          EXIT_CODE=0
        else
          echo -e "${RED}❌${NC} gitleaks found secrets!"
          EXIT_CODE=1
        fi

        # Restore original remote URL
        if [ "$RESTORED" = "true" ]; then
          git remote set-url origin "$REMOTE_URL" 2>/dev/null
        fi

        exit $EXIT_CODE

  cve:
    desc: Download known CVEs for repository from Dependabot API
    aliases: [cve]
    silent: true
    deps: [cli]
    dotenv: ['.env']
    vars:
      MIN_SEVERITY: '{{.MIN_SEVERITY | default "medium"}}'
      REPO_ROOT:
        sh: git rev-parse --show-toplevel 2>/dev/null || pwd
      LOG_DIR:
        sh: echo "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.logs/github/cve"
    cmds:
      - |
        # Color codes
        GREEN='\033[0;32m'
        RED='\033[0;31m'
        YELLOW='\033[0;33m'
        NC='\033[0m'

        # Get and validate GitHub token
        export GH_TOKEN=$(task git:token)

        # Validate severity level
        MIN_SEVERITY="{{.MIN_SEVERITY}}"
        case "$MIN_SEVERITY" in
          critical|high|medium|low) ;;
          *)
            echo -e "${RED}❌ Invalid MIN_SEVERITY: $MIN_SEVERITY${NC}" >&2
            echo "Valid values: critical, high, medium, low" >&2
            exit 1
            ;;
        esac

        # Get repository info
        REPO=$(task git:repo:url | sed -E 's|^https://github.com/||')

        # Clean up old CVE logs
        if [ -d "{{.LOG_DIR}}" ]; then
          find "{{.LOG_DIR}}" -type f -name 'cve-*.*' -exec rm -f {} \; 2>/dev/null
        fi

        # Create log directory
        mkdir -p "{{.LOG_DIR}}"
        TIMESTAMP=$(date +%Y%m%d-%H%M%S)
        RAW_FILE="{{.LOG_DIR}}/cve-${TIMESTAMP}-raw.json"
        LOG_FILE="{{.LOG_DIR}}/cve-${TIMESTAMP}.json"
        SUMMARY_FILE="{{.LOG_DIR}}/cve-${TIMESTAMP}-summary.txt"

        # Fetch vulnerabilities from Dependabot API (silent)
        VULNS_RAW=$(gh api "/repos/$REPO/dependabot/alerts" --paginate 2>&1)

        if [ $? -ne 0 ]; then
          echo -e "${RED}❌ Failed to fetch CVEs from GitHub${NC}" >&2
          echo "$VULNS_RAW" >&2
          exit 1
        fi

        # Save raw response
        echo "$VULNS_RAW" > "$RAW_FILE"

        # Clean and process JSON
        VULNS_CLEAN=$(echo "$VULNS_RAW" | tr -d '\000-\010\013-\037')

        # Filter and deduplicate vulnerabilities
        VULNS=$(echo "$VULNS_CLEAN" | jq --arg min_sev "$MIN_SEVERITY" '
          [.[] | select(.state=="open") | {
            cve: (.security_advisory.cve_id // null),
            pkg: (.security_vulnerability.package.name // "unknown"),
            ecosystem: (.security_vulnerability.package.ecosystem // "unknown"),
            sev: (.security_vulnerability.severity // "unknown"),
            current_version: (.security_vulnerability.vulnerable_version_range // null),
            fixed_version: (.security_vulnerability.first_patched_version.identifier // null),
            manifest_path: (.dependency.manifest_path // null),
            summary: (.security_advisory.summary // null),
            ghsa_id: (.security_advisory.ghsa_id // null),
            cvss_score: (.security_advisory.cvss.score // null),
            created_at: (.created_at // null)
          } | select(
            if $min_sev == "low" then true
            elif $min_sev == "medium" then (.sev == "medium" or .sev == "high" or .sev == "critical")
            elif $min_sev == "high" then (.sev == "high" or .sev == "critical")
            elif $min_sev == "critical" then .sev == "critical"
            else true end
          )] |
          group_by((.cve // .ghsa_id // "NO-ID") + ":" + .pkg) |
          map({
            cve: .[0].cve,
            pkg: .[0].pkg,
            ecosystem: .[0].ecosystem,
            sev: .[0].sev,
            current_version: .[0].current_version,
            fixed_version: .[0].fixed_version,
            summary: .[0].summary,
            ghsa_id: .[0].ghsa_id,
            cvss_score: .[0].cvss_score,
            manifest_paths: [.[] | .manifest_path] | unique | sort,
            count: length
          }) | sort_by(
            if .sev == "critical" then 0
            elif .sev == "high" then 1
            elif .sev == "medium" then 2
            elif .sev == "low" then 3
            else 4 end
          )' 2>/dev/null || echo "[]")

        # Save filtered results
        echo "$VULNS" > "$LOG_FILE"

        # Count vulnerabilities
        VULN_COUNT=$(echo "$VULNS" | jq 'length' 2>/dev/null || echo "0")
        CRITICAL_COUNT=$(echo "$VULNS" | jq '[.[] | select(.sev == "critical")] | length' 2>/dev/null || echo "0")
        HIGH_COUNT=$(echo "$VULNS" | jq '[.[] | select(.sev == "high")] | length' 2>/dev/null || echo "0")
        MEDIUM_COUNT=$(echo "$VULNS" | jq '[.[] | select(.sev == "medium")] | length' 2>/dev/null || echo "0")
        LOW_COUNT=$(echo "$VULNS" | jq '[.[] | select(.sev == "low")] | length' 2>/dev/null || echo "0")

        # Create summary report
        {
          echo "CVE Security Report"
          echo "==================="
          echo "Repository: $REPO"
          echo "Date: $(date)"
          echo "Minimum severity: $MIN_SEVERITY and above"
          echo "Total vulnerabilities: $VULN_COUNT"
          echo ""

          if [ "$VULN_COUNT" -gt "0" ]; then
            echo "Severity breakdown:"
            [ "$CRITICAL_COUNT" -gt 0 ] && echo "  Critical: $CRITICAL_COUNT"
            [ "$HIGH_COUNT" -gt 0 ] && echo "  High: $HIGH_COUNT"
            [ "$MEDIUM_COUNT" -gt 0 ] && echo "  Medium: $MEDIUM_COUNT"
            [ "$LOW_COUNT" -gt 0 ] && echo "  Low: $LOW_COUNT"
            echo ""
            echo "Vulnerabilities:"
            echo "───────────────────────────────────────────────────────────────"
            echo ""

            echo "$VULNS" | jq -r '.[] |
              "CVE: \(.cve // .ghsa_id // "NO-ID")\n" +
              "Severity: \(.sev | ascii_upcase) (CVSS: \(.cvss_score // "N/A"))\n" +
              "Package: \(.ecosystem)/\(.pkg)\n" +
              "Locations (\(.count)):\n" +
              (.manifest_paths | map("  - " + .) | join("\n")) + "\n" +
              "Current: \(.current_version // "Unknown")\n" +
              "Fixed in: \(.fixed_version // "No fix available")\n" +
              "Summary: \(.summary // "No description available" | .[0:200])\n" +
              "───────────────────────────────────────────────────────────────\n"'
          else
            echo "No vulnerabilities found."
          fi
        } > "$SUMMARY_FILE"

        # Display results
        if [ "$VULN_COUNT" -gt "0" ]; then
          echo -e "${RED}❌ Found $VULN_COUNT CVEs ($MIN_SEVERITY and above)${NC}"
          [ "$CRITICAL_COUNT" -gt 0 ] && echo "  Critical: $CRITICAL_COUNT"
          [ "$HIGH_COUNT" -gt 0 ] && echo "  High: $HIGH_COUNT"
          [ "$MEDIUM_COUNT" -gt 0 ] && echo "  Medium: $MEDIUM_COUNT"
          [ "$LOW_COUNT" -gt 0 ] && echo "  Low: $LOW_COUNT"
          echo ""
          echo -e "${GREEN}✓${NC} Summary: $SUMMARY_FILE"
          echo -e "${GREEN}✓${NC} Filtered data: $LOG_FILE"
          echo -e "${GREEN}✓${NC} Raw API response: $RAW_FILE"
        else
          echo -e "${GREEN}✓${NC} No CVEs found ($MIN_SEVERITY severity and above) → $SUMMARY_FILE"
        fi

        # Open summary in VSCode
        if command -v code &> /dev/null; then
          code "$SUMMARY_FILE" 2>/dev/null || true
        fi
