---
description: Analyze unit test coverage and identify low-coverage files
argument-hint: [glob-pattern] [--diff] [--strict] [--compare]
allowed-tools: Bash, Read, Edit, Write, Glob, Grep, Bash(task *)
plan-mode: true
---

# Coverage Analysis: $ARGUMENTS

**IMPORTANT - Report Location Pattern**: This command generates a coverage analysis report. See [REPORT-LOCATIONS.md](./REPORT-LOCATIONS.md) for the required pattern:

- **Save to temporary directory**: `${TMPDIR:-${TEMP:-/tmp}}/cover-report-$(date +%Y%m%d-%H%M%S).md`
- **Auto-open in VSCode**: `code "$REPORT_FILE"` after generation
- **Never save to project root**: No `.cover.report.local.md` files

**IMPORTANT**: This command creates multiple temporary files during execution. You MUST cleanup these files before completion (see Phase 6: Cleanup Temporary Files).

## Overview: Optimized Coverage Analysis

This command analyzes test coverage using an optimized workflow that prioritizes speed and reliability:

**Performance-First Approach:**

1. **Check for `task test:coverage:report`** - Fast path that uses existing coverage data
2. **Validate lcov file freshness** - Reuses recent coverage (< 5 minutes old)
3. **Regenerate if stale** - Runs `task test:coverage` when needed
4. **Fallback detection** - Auto-detects test framework if no Taskfile tasks
5. **Direct file analysis** - Parses lcov.info and junit.xml for accuracy

**Why This Approach:**

- **Speed**: Avoids re-running tests when coverage is fresh
- **Reliability**: Parses standardized lcov format instead of text output
- **Flexibility**: Works with or without Taskfile configuration
- **Comprehensive**: Includes both coverage and test result analysis

**Integration with Clean Architecture:**

Coverage issues often indicate architectural problems. When files have low coverage due to mixed business logic and system calls, use `/architect:clean` to refactor for better testability (see [Clean Architecture Guide](../guides/agents.clean.arch.md)).

**Required Setup in Taskfile.yml:**

For optimal performance, add these tasks to your project's `Taskfile.yml`:

```yaml
tasks:
  test:coverage:
    desc: 'Run tests with coverage'
    cmds:
      - bun test --coverage

  test:coverage:report:
    desc: 'Generate coverage report from existing data (fast)'
    cmds:
      - bun test --coverage-report=text
```

If these tasks don't exist, the command will detect your test framework automatically (Bun, Jest, or Vitest).

## Phase 0: Parse Arguments

Extract from `$ARGUMENTS`:

- **Glob pattern**: Optional file pattern (e.g., "src/cli/\*.ts", "src/\*\*/\*.ts")
- **--diff**: Only analyze staged files
- **--strict**: Fail if coverage below threshold (80%)
- **--compare**: Compare with previous `.cover.report.local.md`

## Phase 1: Determine Scope and Run Coverage

### 1.1 Parse Scope

````bash
# Determine what to test
if [[ "$ARGUMENTS" =~ --diff ]]; then
  SCOPE="--diff"
  echo "⚙️ Coverage analysis: staged files only"
elif [[ "$ARGUMENTS" =~ [a-zA-Z0-9/*] ]]; then
  # Extract glob pattern (everything before flags)
  PATTERN=$(echo "$ARGUMENTS" | sed 's/--[a-z]*//g' | xargs)
  SCOPE="--files=$PATTERN"
  echo "⚙️ Coverage analysis: $PATTERN"
else
  SCOPE=""
  echo "⚙️ Coverage analysis: all files"
fi
```text

### 1.2 Locate or Generate Coverage Data

**Priority Workflow (Fast → Comprehensive):**

1. Check for `task test:coverage:report` (fast - uses existing coverage)
2. Validate existing lcov file timestamp
3. Run `task test:coverage` if needed (regenerate coverage)
4. Fallback to test framework detection (no Taskfile available)
5. Analyze lcov and junit.xml files

#### Step 1: Check for Existing Coverage Report Task

```bash
# Check if fast report task exists
HAS_COVERAGE_REPORT_TASK=false
if task --list 2>/dev/null | grep -q "test:coverage:report"; then
  HAS_COVERAGE_REPORT_TASK=true
  echo "✅ Found task test:coverage:report"
fi
```text

#### Step 2: Find and Validate Existing Coverage Files

```bash
# Locate lcov file (common locations)
LCOV_LOCATIONS=(
  "coverage/lcov.info"
  "coverage/coverage-final.json"
  ".coverage/lcov.info"
  "lcov.info"
)

LCOV_FILE=""
for location in "${LCOV_LOCATIONS[@]}"; do
  if [ -f "$location" ]; then
    LCOV_FILE="$location"
    echo "📊 Found coverage file: $LCOV_FILE"
    break
  fi
done

# Check if coverage is recent (< 5 minutes old)
COVERAGE_IS_FRESH=false
if [ -n "$LCOV_FILE" ]; then
  FILE_AGE=$(($(date +%s) - $(stat -f %m "$LCOV_FILE" 2>/dev/null || stat -c %Y "$LCOV_FILE" 2>/dev/null)))
  if [ "$FILE_AGE" -lt 300 ]; then
    COVERAGE_IS_FRESH=true
    echo "✅ Coverage data is fresh (${FILE_AGE}s old)"
  else
    echo "⚠️  Coverage data is stale (${FILE_AGE}s old, threshold: 300s)"
  fi
fi
```text

#### Step 3: Generate Coverage if Needed

```bash
# Decision tree for coverage generation
NEED_TO_RUN_COVERAGE=false

if [ "$HAS_COVERAGE_REPORT_TASK" = "true" ] && [ "$COVERAGE_IS_FRESH" = "true" ]; then
  # Fast path: Use existing coverage report task
  echo "🚀 Using fast coverage report (existing data)"
  task test:coverage:report 2>&1 | tee .bun-coverage.txt

elif [ -n "$LCOV_FILE" ] && [ "$COVERAGE_IS_FRESH" = "false" ]; then
  # Coverage exists but is stale - regenerate
  NEED_TO_RUN_COVERAGE=true
  echo "🔄 Regenerating stale coverage data..."

elif [ -z "$LCOV_FILE" ]; then
  # No coverage exists - must generate
  NEED_TO_RUN_COVERAGE=true
  echo "📊 No coverage data found - generating..."
fi

# Run coverage generation if needed
if [ "$NEED_TO_RUN_COVERAGE" = "true" ]; then
  # Check for task-based coverage generation
  if task --list 2>/dev/null | grep -q "test:coverage"; then
    echo "✅ Running task test:coverage"
    if [ -n "$SCOPE" ]; then
      task test:coverage $SCOPE 2>&1 | tee .bun-coverage.txt
    else
      task test:coverage 2>&1 | tee .bun-coverage.txt
    fi

  elif task --list 2>/dev/null | grep -q "cov"; then
    echo "✅ Running task cov"
    task cov 2>&1 | tee .bun-coverage.txt

  else
    # Fallback: Detect test framework and run directly
    echo "⚠️  No task-based coverage found - detecting test framework..."

    # Detect package.json test framework
    if [ -f "package.json" ]; then
      if grep -q '"bun"' package.json; then
        echo "✅ Detected: Bun test runner"
        bun test --coverage 2>&1 | tee .bun-coverage.txt

      elif grep -q '"jest"' package.json; then
        echo "✅ Detected: Jest test runner"
        npm run test -- --coverage 2>&1 | tee .bun-coverage.txt

      elif grep -q '"vitest"' package.json; then
        echo "✅ Detected: Vitest test runner"
        npm run test -- --coverage 2>&1 | tee .bun-coverage.txt

      else
        echo "❌ Error: Cannot detect test framework"
        echo "   Please add 'task test:coverage' to Taskfile.yml"
        exit 1
      fi
    else
      echo "❌ Error: No package.json found"
      exit 1
    fi
  fi

  # Check if coverage ran successfully
  if [ ${PIPESTATUS[0]} -ne 0 ]; then
    echo "❌ Coverage run failed"
    exit 1
  fi

  # Re-locate lcov file after generation
  for location in "${LCOV_LOCATIONS[@]}"; do
    if [ -f "$location" ]; then
      LCOV_FILE="$location"
      echo "📊 Generated coverage file: $LCOV_FILE"
      break
    fi
  done
fi
```text

#### Step 4: Locate JUnit XML File (if available)

```bash
# Find JUnit XML for test results (optional but recommended)
JUNIT_LOCATIONS=(
  "test-results/junit.xml"
  "junit.xml"
  "coverage/junit.xml"
  ".test-results/junit.xml"
)

JUNIT_FILE=""
for location in "${JUNIT_LOCATIONS[@]}"; do
  if [ -f "$location" ]; then
    JUNIT_FILE="$location"
    echo "📋 Found JUnit file: $JUNIT_FILE"
    break
  fi
done

if [ -z "$JUNIT_FILE" ]; then
  echo "⚠️  No JUnit XML found (test results won't be analyzed)"
fi
```text

#### Step 5: Validate Coverage Data

```bash
# Verify we have coverage data to analyze
if [ -z "$LCOV_FILE" ] || [ ! -f "$LCOV_FILE" ]; then
  echo "❌ Error: No coverage data available"
  echo "   Tried locations:"
  for location in "${LCOV_LOCATIONS[@]}"; do
    echo "     - $location"
  done
  echo ""
  echo "   Ensure coverage was generated successfully"
  exit 1
fi

echo "✅ Coverage data validated: $LCOV_FILE"
```text

**Benefits of this approach:**

- **Speed**: Uses `task test:coverage:report` when available (no test execution)
- **Reliability**: Validates coverage freshness before using cached data
- **Flexibility**: Falls back to test framework detection when no tasks available
- **Comprehensive**: Analyzes both lcov (coverage) and junit.xml (test results)

### 1.3 Load Previous Report (if --compare)

```bash
if [[ "$ARGUMENTS" =~ --compare ]] && [ -f .cover.report.local.md ]; then
  PREV_TIMESTAMP=$(grep "^Generated:" .cover.report.local.md | head -1 | cut -d' ' -f2-)
  PREV_OVERALL=$(grep "^Overall Coverage:" .cover.report.local.md | head -1)
  echo "=� Comparing with previous report: $PREV_TIMESTAMP"
fi
```text

## Phase 2: Parse Coverage Data

### 2.1 Read Coverage Thresholds from docs/QA.md

```bash
# Extract thresholds from QA.md
THRESHOLD_FUNCTIONS=$(grep -A5 "Coverage Targets" docs/QA.md | grep "Function Coverage" | grep -oE "[0-9]+" | head -1)
THRESHOLD_LINES=$(grep -A5 "Coverage Targets" docs/QA.md | grep "Line Coverage" | grep -oE "[0-9]+" | head -1)

# Default to 80% if not found
THRESHOLD_FUNCTIONS=${THRESHOLD_FUNCTIONS:-80}
THRESHOLD_LINES=${THRESHOLD_LINES:-80}

echo "⚙️ Thresholds: Functions ${THRESHOLD_FUNCTIONS}%, Lines ${THRESHOLD_LINES}%"
```text

### 2.2 Parse LCOV Coverage Data

Parse lcov.info file for detailed coverage information:

```bash
# Parse lcov file for coverage data
# LCOV format: SF:<file> | FNF:<functions found> | FNH:<functions hit> | LF:<lines found> | LH:<lines hit>

echo "📊 Parsing coverage from: $LCOV_FILE"

# Extract overall coverage from lcov
TOTAL_FUNCTIONS_FOUND=0
TOTAL_FUNCTIONS_HIT=0
TOTAL_LINES_FOUND=0
TOTAL_LINES_HIT=0

# Parse lcov for per-file coverage
CURRENT_FILE=""
while IFS= read -r line; do
  if [[ "$line" =~ ^SF:(.*) ]]; then
    CURRENT_FILE="${BASH_REMATCH[1]}"
  elif [[ "$line" =~ ^FNF:([0-9]+) ]]; then
    FNF="${BASH_REMATCH[1]}"
    TOTAL_FUNCTIONS_FOUND=$((TOTAL_FUNCTIONS_FOUND + FNF))
  elif [[ "$line" =~ ^FNH:([0-9]+) ]]; then
    FNH="${BASH_REMATCH[1]}"
    TOTAL_FUNCTIONS_HIT=$((TOTAL_FUNCTIONS_HIT + FNH))
  elif [[ "$line" =~ ^LF:([0-9]+) ]]; then
    LF="${BASH_REMATCH[1]}"
    TOTAL_LINES_FOUND=$((TOTAL_LINES_FOUND + LF))
  elif [[ "$line" =~ ^LH:([0-9]+) ]]; then
    LH="${BASH_REMATCH[1]}"
    TOTAL_LINES_HIT=$((TOTAL_LINES_HIT + LH))
  elif [[ "$line" =~ ^end_of_record ]]; then
    # Calculate coverage percentages for current file
    if [ -n "$CURRENT_FILE" ] && [ "$FNF" -gt 0 ]; then
      FUNC_COV=$(awk "BEGIN {printf \"%.2f\", ($FNH / $FNF) * 100}")
      LINE_COV=$(awk "BEGIN {printf \"%.2f\", ($LH / $LF) * 100}")

      # Save to temporary file for analysis
      echo "$CURRENT_FILE|$FUNC_COV|$LINE_COV|$FNH/$FNF|$LH/$LF" >> .coverage-files.tmp
    fi

    # Reset for next file
    CURRENT_FILE=""
    FNF=0
    FNH=0
    LF=0
    LH=0
  fi
done < "$LCOV_FILE"

# Calculate overall coverage percentages
if [ "$TOTAL_FUNCTIONS_FOUND" -gt 0 ]; then
  OVERALL_FUNCTIONS=$(awk "BEGIN {printf \"%.2f\", ($TOTAL_FUNCTIONS_HIT / $TOTAL_FUNCTIONS_FOUND) * 100}")
else
  OVERALL_FUNCTIONS="0.00"
fi

if [ "$TOTAL_LINES_FOUND" -gt 0 ]; then
  OVERALL_LINES=$(awk "BEGIN {printf \"%.2f\", ($TOTAL_LINES_HIT / $TOTAL_LINES_FOUND) * 100}")
else
  OVERALL_LINES="0.00"
fi

echo "✅ Overall Coverage: Functions ${OVERALL_FUNCTIONS}%, Lines ${OVERALL_LINES}%"
```text

**LCOV file format reference:**

```text
SF:src/cli/index.ts
FNF:7     # Functions found
FNH:6     # Functions hit
LF:45     # Lines found
LH:42     # Lines hit
end_of_record
```text

### 2.2.1 Parse JUnit XML for Test Results (Optional)

If JUnit XML is available, extract test execution data:

```bash
if [ -n "$JUNIT_FILE" ] && [ -f "$JUNIT_FILE" ]; then
  echo "📋 Parsing test results from: $JUNIT_FILE"

  # Extract test summary from JUnit XML
  TOTAL_TESTS=$(grep -oP 'tests="\K[0-9]+' "$JUNIT_FILE" | head -1)
  FAILED_TESTS=$(grep -oP 'failures="\K[0-9]+' "$JUNIT_FILE" | head -1)
  ERROR_TESTS=$(grep -oP 'errors="\K[0-9]+' "$JUNIT_FILE" | head -1)
  SKIPPED_TESTS=$(grep -oP 'skipped="\K[0-9]+' "$JUNIT_FILE" | head -1)

  # Default to 0 if not found
  TOTAL_TESTS=${TOTAL_TESTS:-0}
  FAILED_TESTS=${FAILED_TESTS:-0}
  ERROR_TESTS=${ERROR_TESTS:-0}
  SKIPPED_TESTS=${SKIPPED_TESTS:-0}

  PASSED_TESTS=$((TOTAL_TESTS - FAILED_TESTS - ERROR_TESTS - SKIPPED_TESTS))

  echo "✅ Test Results: $PASSED_TESTS passed, $FAILED_TESTS failed, $SKIPPED_TESTS skipped (Total: $TOTAL_TESTS)"

  # Store for report
  TEST_SUMMARY="**Test Results**: $PASSED_TESTS/$TOTAL_TESTS passed ($FAILED_TESTS failed, $SKIPPED_TESTS skipped)"
else
  TEST_SUMMARY=""
fi
```text

### 2.3 Parse Exclusions from package.json

```bash
# Get coverage exclusions
EXCLUSIONS=$(cat package.json | jq -r '.coverage.exclude[]?' 2>/dev/null || echo "")

if [ -n "$EXCLUSIONS" ]; then
  echo "=� Exclusions configured:"
  echo "$EXCLUSIONS" | while read -r pattern; do
    echo "  � $pattern"
  done
fi
```text

## Phase 3: Analyze and Prioritize Files

### 3.1 Identify File Categories

#### Tier 1: New Files (created in current branch)

```bash
# Find files added in current branch vs main
NEW_FILES=$(git diff --name-status origin/main...HEAD 2>/dev/null | grep '^A' | awk '{print $2}' | grep '\.ts$')

# Cross-reference with coverage data
while read -r file; do
  # Check if file appears in coverage with low coverage
  COVERAGE=$(grep "$file" .coverage-files.tmp | awk '{print $3}' | tr -d '%')
  if [ -n "$COVERAGE" ]; then
    if (( $(echo "$COVERAGE < $THRESHOLD_FUNCTIONS" | bc -l) )); then
      echo "$file|$COVERAGE|NEW" >> .coverage-analysis.tmp
    fi
  else
    # New file with no tests at all
    echo "$file|0.00|NEW_NO_TESTS" >> .coverage-analysis.tmp
  fi
done <<< "$NEW_FILES"
```text

#### Tier 2: High-Impact Files (below threshold)

High-impact files based on docs/QA.md or project structure:

- `src/cli/**/*.ts` - CLI commands and interfaces
- `src/state/**/*.ts` - State management
- `src/config/**/*.ts` - Configuration handling
- `src/security/**/*.ts` - Security-critical code

```bash
# Define high-impact patterns
HIGH_IMPACT_PATTERNS=(
  "src/cli/"
  "src/state/"
  "src/config/"
  "src/security/"
)

# Find high-impact files below threshold
while read -r line; do
  FILE=$(echo "$line" | awk '{print $1}')
  FUNC_COV=$(echo "$line" | awk '{print $3}' | tr -d '%')

  # Skip if excluded
  EXCLUDED=false
  for pattern in $EXCLUSIONS; do
    if [[ "$FILE" =~ $pattern ]]; then
      EXCLUDED=true
      break
    fi
  done

  if [ "$EXCLUDED" = "true" ]; then
    continue
  fi

  # Check if high-impact and below threshold
  for pattern in "${HIGH_IMPACT_PATTERNS[@]}"; do
    if [[ "$FILE" =~ $pattern ]] && (( $(echo "$FUNC_COV < $THRESHOLD_FUNCTIONS" | bc -l) )); then
      # Skip if already in new files
      if ! grep -q "^$FILE|" .coverage-analysis.tmp 2>/dev/null; then
        echo "$FILE|$FUNC_COV|HIGH_IMPACT" >> .coverage-analysis.tmp
      fi
      break
    fi
  done
done < .coverage-files.tmp
```text

#### Tier 3: Other Files (below threshold)

```bash
# All other files below threshold
while read -r line; do
  FILE=$(echo "$line" | awk '{print $1}')
  FUNC_COV=$(echo "$line" | awk '{print $3}' | tr -d '%')
  LINE_COV=$(echo "$line" | awk '{print $4}' | tr -d '%')

  # Skip if excluded
  EXCLUDED=false
  for pattern in $EXCLUSIONS; do
    if [[ "$FILE" =~ $pattern ]]; then
      echo "$FILE|$FUNC_COV|EXCLUDED" >> .coverage-excluded.tmp
      EXCLUDED=true
      break
    fi
  done

  if [ "$EXCLUDED" = "true" ]; then
    continue
  fi

  # Check if below threshold and not already categorized
  if (( $(echo "$FUNC_COV < $THRESHOLD_FUNCTIONS" | bc -l) )) || (( $(echo "$LINE_COV < $THRESHOLD_LINES" | bc -l) )); then
    if ! grep -q "^$FILE|" .coverage-analysis.tmp 2>/dev/null; then
      echo "$FILE|$FUNC_COV|LOW_COVERAGE" >> .coverage-analysis.tmp
    fi
  fi
done < .coverage-files.tmp
```text

### 3.2 Identify Pure Engine Code (Recommend for Exclusion)

Characteristics of pure engine/plumbing code:

- Re-export files (only `export * from` or `export { ... }`)
- CLI wrappers with no business logic
- Type-only files

```bash
# Scan for re-export only files
find src -name "*.ts" -type f | while read -r file; do
  # Check if file is purely re-exports
  NON_EXPORT_LINES=$(grep -vE '^\s*(export|import|/\*|//|$)' "$file" | wc -l)

  if [ "$NON_EXPORT_LINES" -eq 0 ]; then
    # Pure re-export file
    if grep -q "^$file|" .coverage-files.tmp; then
      COVERAGE=$(grep "^$file|" .coverage-files.tmp | awk '{print $3}' | tr -d '%')
      echo "$file|$COVERAGE|PURE_ENGINE" >> .coverage-exclude-candidates.tmp
    fi
  fi
done
```

### 3.3 Identify Untestable Code (Architecture Issues)

Files with low coverage may be untestable due to architectural problems:

**Indicators of architectural issues:**

- Business logic mixed with system calls (execSync, fs operations, network calls)
- Hardcoded dependencies (cannot inject mocks)
- No separation between business logic and infrastructure

**For these files, coverage exclusion is NOT the solution.** Instead, refactor for testability:

```bash
# Identify files with mixed logic (heuristic)
while read -r line; do
  FILE=$(echo "$line" | awk -F'|' '{print $1}')
  FUNC_COV=$(echo "$line" | awk -F'|' '{print $2}')

  # Check if file contains system calls
  if grep -qE "(execSync|readFileSync|writeFileSync|fetch\()" "$FILE" 2>/dev/null; then
    # And has business logic (not just a thin wrapper)
    if [ $(wc -l < "$FILE") -gt 50 ]; then
      echo "$FILE|$FUNC_COV|MIXED_LOGIC" >> .coverage-architecture-issues.tmp
    fi
  fi
done < .coverage-files.tmp

# Report these for architectural refactoring
ARCH_ISSUES=$(wc -l < .coverage-architecture-issues.tmp 2>/dev/null || echo 0)
if [ "$ARCH_ISSUES" -gt 0 ]; then
  echo "⚠️  Found $ARCH_ISSUES files with mixed business/system logic"
  echo "   Consider: /architect:clean [scope] to refactor for testability"
fi
```text

## Phase 4: Generate Recommendations

### 4.1 Determine Overall Status

```bash
# Check if overall coverage meets threshold
OVERALL_PASS=true
if (( $(echo "$OVERALL_FUNCTIONS < $THRESHOLD_FUNCTIONS" | bc -l) )); then
  OVERALL_PASS=false
fi
if (( $(echo "$OVERALL_LINES < $THRESHOLD_LINES" | bc -l) )); then
  OVERALL_PASS=false
fi

if [ "$OVERALL_PASS" = "true" ]; then
  OVERALL_STATUS=" PASS"
else
  OVERALL_STATUS="L FAIL"
fi
```text

### 4.2 Generate Action Plan

Based on categorized files, create prioritized action plan:

1. **Fix new files first** (Tier 1) - AI-generated code without tests
2. **Fix high-impact files** (Tier 2) - Core functionality below threshold
3. **Consider excluding engine code** - Pure plumbing with no logic
4. **Add tests to remaining files** (Tier 3) - Other low-coverage files

**TDD Approach for Writing Tests:**

When adding tests to improve coverage, follow TDD principles for better test quality:

- **Red-Green-Refactor** - Write failing test, implement fix, improve code
- **Arrange-Act-Assert** - Structure tests clearly (setup → execute → verify)
- **Test behavior, not implementation** - Verify what code does, not how
- **Mock external dependencies** - Isolate unit under test from I/O

See: `~/.claude/guides/agents.tdd.md` for TDD principles
See: `~/.claude/guides/agents.tdd.ts.md` for TypeScript-specific testing patterns

```bash
# Count files in each tier
NEW_FILE_COUNT=$(grep "|NEW" .coverage-analysis.tmp 2>/dev/null | wc -l)
HIGH_IMPACT_COUNT=$(grep "|HIGH_IMPACT" .coverage-analysis.tmp 2>/dev/null | wc -l)
LOW_COVERAGE_COUNT=$(grep "|LOW_COVERAGE" .coverage-analysis.tmp 2>/dev/null | wc -l)
ENGINE_COUNT=$(wc -l < .coverage-exclude-candidates.tmp 2>/dev/null || echo 0)

echo "=� Analysis complete:"
echo "  <� New files without tests: $NEW_FILE_COUNT"
echo "  �  High-impact files below threshold: $HIGH_IMPACT_COUNT"
echo "  =� Other low-coverage files: $LOW_COVERAGE_COUNT"
echo "  =' Pure engine files (exclude candidates): $ENGINE_COUNT"
```text

## Phase 5: Generate Report

Create `.cover.report.local.md`:

```markdown
# Coverage Analysis Report

**Generated:** [timestamp ISO]
**Scope:** [all files | pattern | staged files]
**Overall Status:** [ PASS | L FAIL]

## Summary

- **Overall Coverage:**
  - Functions: [X.XX]% (threshold: [80]%)
  - Lines: [X.XX]% (threshold: [80]%)
- **Files Analyzed:** [count]
- **Files Below Threshold:** [count]
- **Action Required:** [Yes | No]

---

## Priority: Fix New Files First <�

**Issue:** AI-generated code often lacks tests. These files were added recently and have low/no coverage.

| File | Function % | Line % | Status |
|------|------------|--------|--------|
| src/cli/new-command.ts | 0.00 | 0.00 | No tests |
| src/utils/new-helper.ts | 25.00 | 30.00 | Partial |

**Action:**
- Add unit tests for these files first
- Follow TDD approach: write failing test (RED), implement (GREEN), refactor
- Focus on business logic and error paths
- Target: Achieve 80%+ coverage before merging

**TDD Resources:**
- See: `~/.claude/guides/agents.tdd.md` for TDD principles
- See: `~/.claude/guides/agents.tdd.ts.md` for TypeScript testing patterns

---

## Priority: High-Impact Files Below Threshold �

**Issue:** Core functionality with insufficient test coverage.

| File | Function % | Line % | Impact Area |
|------|------------|--------|-------------|
| src/cli/install.ts | 45.00 | 58.00 | CLI |
| src/state/config.ts | 62.00 | 70.00 | State |

**Action:**
- Add tests for critical paths and error handling
- Mock external dependencies (file system, network)
- Use TDD approach: test behavior, not implementation
- Prioritize by user-facing impact

---

## Priority: Architecture Issues ⚠️

**Issue:** Files with mixed business logic and system calls are untestable without refactoring.

| File | Function % | Line % | Issue |
|------|------------|--------|-------|
| src/utils/auth.ts | 35.00 | 42.00 | Mixed LDAP calls and validation |
| src/installers/npm.ts | 40.00 | 48.00 | Mixed execSync and business logic |

**Recommended Action:**

Use Clean Architecture refactoring instead of coverage exclusion:

``​`bash
# Analyze and refactor for testability
/architect:clean src/utils/auth.ts

# Review proposed refactorings in .clean.local.md
# The agent will:
#   1. Extract interfaces for system dependencies
#   2. Create *.system.ts files for system calls
#   3. Add dependency injection to business logic
#   4. Create mocks for testing
#   5. Update coverage configuration
``​`

**Why refactor instead of exclude:**

- Business logic becomes fully testable with mocks
- System files (*.system.ts) are excluded from coverage
- Overall coverage improves (business logic counted, system calls excluded)
- Better separation of concerns and maintainability

**See:** [Clean Architecture Guide](../guides/agents.clean.arch.md) | [/architect:clean Command](./architect/clean.md)

---

## Consider: Exclude Pure Engine Code ='

**Issue:** These files contain only re-exports or thin wrappers with no testable logic.

| File | Function % | Line % | Reason |
|------|------------|--------|--------|
| src/index.ts | 0.00 | 0.00 | Pure re-export |
| src/types/index.ts | 0.00 | 0.00 | Type-only |

**Recommendation:** Add Istanbul ignore or package.json exclusions:

### Option 1: Istanbul Ignore (TypeScript)

```typescript
/* istanbul ignore file */

// Rest of file...
```text

### Option 2: package.json Exclusions

```json
{
  "coverage": {
    "exclude": [
      "src/index.ts",
      "src/types/index.ts"
    ]
  }
}
```text

**Verify with operator before excluding** - Ensure files truly have no testable logic.

---

## Low Coverage Files (Other) =�

**Issue:** Files below threshold but not high-impact.

| File | Function % | Line % |
|------|------------|--------|
| src/utils/format.ts | 65.00 | 72.00 |
| src/ui/prompts.ts | 55.00 | 60.00 |

**Action:**

- Add tests when time allows
- Focus on public API and error cases
- Lower priority than Tier 1 and Tier 2

---

## Excluded Files �

These files are excluded from coverage analysis per `package.json` configuration:

[List files with exclusion pattern]

---

## Comparison with Previous Report

[Only if --compare used]

### Changes Since Last Run ([timestamp])

- **Overall Functions:** [prev]% � [current]% ([+/- delta])
- **Overall Lines:** [prev]% � [current]% ([+/- delta])
- **Files Fixed:** [count] files now meet threshold
- **New Issues:** [count] files dropped below threshold

---

## Recommendations

### =4 Critical (Do First)

1. **Add tests to [X] new files** - Start with files that have 0% coverage
2. **Fix high-impact files** - Focus on CLI and state management
3. **Review coverage in CI** - Ensure coverage doesn't regress

### =� High Priority

1. **Verify engine code exclusions** - Confirm with operator before ignoring
2. **Add integration tests** - Cover module interactions
3. **Test error paths** - Ensure failure cases are tested

### =� Low Priority

1. **Increase coverage on utility files** - Improve from 65% � 80%
2. **Add edge case tests** - Cover boundary conditions
3. **Consider snapshot tests** - For output formatting

---

## Testing Pyramid Reference

Per `docs/QA.md`, follow the testing pyramid:

- **Unit Tests (80%+ coverage target)** - Fast, isolated, mocked dependencies
- **Integration Tests (selective coverage)** - Real modules, mocked I/O
- **E2E Tests (manual validation)** - Real system, not measured in coverage

See [docs/QA.md](../QA.md) for full testing strategy.

---

## Next Steps

- [ ] Fix [X] new files (Tier 1 priority)
- [ ] Add tests to [X] high-impact files (Tier 2)
- [ ] Review and exclude [X] engine files (verify first)
- [ ] Run `/cover --compare` after changes to track progress

---

**Report Location:** `.cover.report.local.md`
**Rerun:** `/cover` or `/cover --compare`
**Exit Code:** [0 = pass | 1 = fail (if --strict)]

```text

### 5.1 Write Report to File

```bash
# Write generated report
echo "$REPORT_CONTENT" > .cover.report.local.md

# Add to gitignore if not already
if ! grep -q "^\.cover\.report\.local\.md$" .gitignore 2>/dev/null; then
  echo ".cover.report.local.md" >> .gitignore
fi
```

## Phase 6: Cleanup Temporary Files

**CRITICAL**: Remove all temporary files created during coverage analysis process.

```bash
echo "🧹 Cleaning up temporary files..."

# Remove all temporary coverage files
rm -f .bun-coverage.txt
rm -f .coverage-files.tmp
rm -f .coverage-analysis.tmp
rm -f .coverage-excluded.tmp
rm -f .coverage-exclude-candidates.tmp
rm -f .coverage-architecture-issues.tmp
rm -f .coverage-low.tmp

# Verify cleanup
if ls .coverage*.tmp .bun-coverage.txt 1> /dev/null 2>&1; then
  echo "⚠️  Warning: Some temporary files remain"
  ls -la .coverage*.tmp .bun-coverage.txt 2>/dev/null || true
else
  echo "✅ Temporary files cleaned up"
fi
```

**Files to remove:**

- `.bun-coverage.txt` - Raw coverage output from test runner
- `.coverage-files.tmp` - Parsed individual file coverage data
- `.coverage-analysis.tmp` - Categorized analysis results
- `.coverage-excluded.tmp` - Files excluded from analysis
- `.coverage-exclude-candidates.tmp` - Pure engine code candidates
- `.coverage-architecture-issues.tmp` - Files with mixed business/system logic
- `.coverage-low.tmp` - Files below coverage threshold

**Files to keep:**

- `.cover.report.local.md` - Final human-readable report (preserved for review)

**Why cleanup matters:**

- Prevents root folder clutter with temporary files
- Avoids confusion about which files are part of the codebase
- Prevents accidental commits of temporary analysis data
- Keeps workspace clean for next coverage execution

## Phase 7: Present Results (Plan Mode)

### 7.1 Console Summary

**Success case (coverage meets threshold):**

```bash
echo ""
echo " Coverage meets threshold"
echo ""
echo "=� Overall Coverage:"
echo "   Functions: ${OVERALL_FUNCTIONS}% (threshold: ${THRESHOLD_FUNCTIONS}%)"
echo "   Lines: ${OVERALL_LINES}% (threshold: ${THRESHOLD_LINES}%)"
echo ""
echo "=� Files analyzed: [count]"
echo "    Meeting threshold: [count]"
echo "   �  Below threshold: [count]"
echo ""
if [ "$NEW_FILE_COUNT" -gt 0 ]; then
  echo "<� Recommendation: Fix $NEW_FILE_COUNT new files first"
fi
echo ""
echo "=� Full report: .cover.report.local.md"
```text

**Failure case (coverage below threshold):**

```bash
echo ""
echo "L Coverage below threshold"
echo ""
echo "=� Overall Coverage:"
echo "   Functions: ${OVERALL_FUNCTIONS}% (threshold: ${THRESHOLD_FUNCTIONS}%) L"
echo "   Lines: ${OVERALL_LINES}% (threshold: ${THRESHOLD_LINES}%) L"
echo ""
echo "=4 Action Required:"
if [ "$NEW_FILE_COUNT" -gt 0 ]; then
  echo "   1. Fix $NEW_FILE_COUNT new files without tests (Tier 1)"
fi
if [ "$HIGH_IMPACT_COUNT" -gt 0 ]; then
  echo "   2. Add tests to $HIGH_IMPACT_COUNT high-impact files (Tier 2)"
fi
if [ "$ENGINE_COUNT" -gt 0 ]; then
  echo "   3. Consider excluding $ENGINE_COUNT pure engine files (verify first)"
fi
echo ""
echo "=� Full report: .cover.report.local.md"
echo ""
```text

### 7.2 Plan Mode Presentation

**Present findings and recommendations without making changes:**

1. **Show overall status** - Pass/fail vs threshold
2. **Present prioritized action plan** - Tier 1 � Tier 2 � Tier 3
3. **Highlight exclusion candidates** - Engine code to review
4. **Link to testing pyramid** - Reference docs/QA.md strategy

**DO NOT:**

- Automatically add Istanbul ignore comments
- Modify package.json exclusions
- Create test files
- Make any code changes

**Operator decides:**

- Which files to test vs exclude
- Testing approach (unit vs integration)
- Coverage targets for specific modules

### 7.3 Exit Codes

```bash
# Determine exit code
if [[ "$ARGUMENTS" =~ --strict ]]; then
  if [ "$OVERALL_PASS" = "true" ]; then
    exit 0  # Coverage meets threshold
  else
    exit 1  # Coverage below threshold (strict mode)
  fi
else
  exit 0  # Always succeed in non-strict mode (plan mode)
fi
```text

## Error Handling

**Important**: Always cleanup temporary files before exiting, even on error:

```bash
# Trap for cleanup on exit (success or failure)
cleanup_temp_files() {
  rm -f .bun-coverage.txt
  rm -f .coverage-files.tmp
  rm -f .coverage-analysis.tmp
  rm -f .coverage-excluded.tmp
  rm -f .coverage-exclude-candidates.tmp
  rm -f .coverage-architecture-issues.tmp
  rm -f .coverage-low.tmp
}

# Register cleanup on exit
trap cleanup_temp_files EXIT

# Or manual cleanup before error exit
if [ $ERROR_CONDITION ]; then
  cleanup_temp_files
  exit 1
fi
```

**Error handling guidelines:**

- **Cleanup fails**: Log warning but don't fail the command
- **Coverage run fails**: Cleanup temps before exit
- **Invalid pattern**: Warn but continue with analysis
- **Git unavailable**: Error if --diff used, suggest alternative

### Coverage Run Failed

```bash
if ! task test:coverage $SCOPE 2>&1 | tee .bun-coverage.txt; then
  echo "L Error: Coverage run failed"
  echo "   Check test errors above"
  echo "   Fix failing tests before analyzing coverage"
  exit 1
fi
```text

### No Coverage Data

```bash
if [ ! -s .bun-coverage.txt ]; then
  echo "L Error: No coverage data generated"
  echo "   Ensure tests ran successfully"
  echo "   Try: task test:coverage"
  exit 1
fi
```text

### Invalid Scope

```bash
if [[ "$SCOPE" == --files=* ]]; then
  PATTERN="${SCOPE#--files=}"
  FILE_COUNT=$(ls $PATTERN 2>/dev/null | wc -l)
  if [ "$FILE_COUNT" -eq 0 ]; then
    echo "�  Warning: No files match pattern: $PATTERN"
    echo "   Continuing with empty coverage..."
  fi
fi
```text

### Git Not Available (--diff mode)

```bash
if [[ "$SCOPE" == "--diff" ]]; then
  if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    echo "L Error: --diff requires git repository"
    echo "   Use glob pattern instead: /cover 'src/**/*.ts'"
    exit 1
  fi
fi
```text

## Phase 8: Usage Examples

```bash
# Analyze all files
/cover

# Analyze specific pattern
/cover 'src/cli/**/*.ts'

# Analyze staged files only
/cover --diff

# Strict mode (fail if below threshold)
/cover --strict

# Compare with previous analysis
/cover --compare

# Combination
/cover 'src/state/**/*.ts' --strict --compare
```

## Phase 9: Integration with Workflow

### After AI Code Generation

```bash
# AI generated new files
/cover --diff

# Review new files in report
# Add tests to new files
# Rerun to verify
/cover --diff --compare
```text

### Before Pull Request

```bash
# Check overall coverage
/cover --strict

# If fails, review report priorities
# Fix Tier 1 and Tier 2 files
# Verify coverage passes
/cover --strict
```text

### Regular Development

```bash
# Quick check on working files
/cover 'src/module/**/*.ts'

# Review recommendations
# Add tests incrementally
# Track progress with --compare
```

### Architecture-First Workflow (Recommended)

When coverage issues stem from architectural problems, use `/architect:clean` before adding tests:

```bash
# Step 1: Identify coverage issues
/cover --diff

# Step 2: Review .cover.report.local.md
# Look for "Priority: Architecture Issues ⚠️" section

# Step 3: Refactor files with mixed logic
/architect:clean src/utils/auth.ts

# Step 4: Review proposed refactorings in .clean.local.md
# Accept changes from worktree if satisfactory

# Step 5: Run coverage again to verify improvement
/cover --diff --compare

# Step 6: Add unit tests for refactored business logic
# Tests now use mocks instead of real system calls
```

**Why this workflow works:**

1. **Before refactoring**: Business logic mixed with system calls → Cannot test without real LDAP/file system/network
2. **After refactoring**: Business logic separated with DI → Can test with mocks
3. **Coverage impact**: System files excluded (*.system.ts), business logic included and testable

**Example:**

```bash
# Initial state: auth.ts has 35% coverage (mixed LDAP and validation)
/cover src/utils/

# Report shows: "Priority: Architecture Issues - src/utils/auth.ts"
# Recommendation: Use /architect:clean instead of excluding from coverage

# Refactor for testability
/architect:clean src/utils/auth.ts

# Result:
#   - ldap-interface.ts (interface definition)
#   - ldap.system.ts (LDAP calls, excluded from coverage)
#   - auth.ts (business logic with DI, now testable)
#   - tests/mocks/ldap-mock.ts (mock for unit tests)

# Add unit tests using mocks
# auth.ts coverage: 35% → 90%
# Overall coverage: Improved (system file excluded, business logic tested)

# Verify improvement
/cover src/utils/ --compare
```

**See also:**

- [Clean Architecture Guide](../guides/agents.clean.arch.md) - Principles and patterns
- [/architect:clean Command](./architect/clean.md) - Automated refactoring
- [Clean Architecture in TypeScript](../guides/agents.clean.arch.ts.md) - Language-specific guide

## Quick Reference

**Common workflows:**

```bash
# Analyze all files
/cover

# Analyze specific pattern
/cover 'src/cli/**/*.ts'

# Check staged files
/cover --diff

# Strict mode (fail if below threshold)
/cover --strict

# Track progress over time
/cover --compare
```

**Coverage data workflow (performance optimized):**

1. **Fast path**: Use `task test:coverage:report` if available and coverage is fresh (< 5 minutes)
2. **Regenerate**: Run `task test:coverage` if coverage is stale or missing
3. **Fallback**: Detect test framework (Bun, Jest, Vitest) if no Taskfile tasks available
4. **Analyze**: Parse lcov.info and junit.xml files directly for comprehensive analysis

**Coverage file locations checked:**

- `coverage/lcov.info` (standard)
- `coverage/coverage-final.json` (JSON format)
- `.coverage/lcov.info` (alternative)
- `lcov.info` (root)

**JUnit file locations checked:**

- `test-results/junit.xml` (standard)
- `junit.xml` (root)
- `coverage/junit.xml` (with coverage)
- `.test-results/junit.xml` (alternative)

**Temporary files created:**

- `.bun-coverage.txt` - Raw coverage output (if test run needed)
- `.coverage-files.tmp` - Parsed file coverage data from lcov
- `.coverage-analysis.tmp` - Analysis results by tier
- `.coverage-excluded.tmp` - Excluded files list
- `.coverage-exclude-candidates.tmp` - Pure engine code candidates
- `.coverage-architecture-issues.tmp` - Files with mixed business/system logic
- `.coverage-low.tmp` - Files below threshold

**CRITICAL**: Always cleanup temporary files after completion (see Phase 6)

**Priority tiers:**

1. **Tier 1 (Fix First)** - New files without tests
2. **Tier 2 (High Impact)** - Core functionality below threshold
3. **Architecture Issues** - Files with mixed business/system logic (use `/architect:clean`)
4. **Tier 3 (Low Priority)** - Other files below threshold
5. **Exclusion Candidates** - Pure engine code (verify before excluding)

**Execution order:**

1. Parse arguments → 2. **Locate/generate coverage** → 3. **Parse lcov/junit** → 4. Analyze files → 5. Generate recommendations → 6. Generate report → 7. **Cleanup temps** → 8. Present results

**Report location:** `.cover.report.local.md`

**Exit codes:**
- 0: Pass (or non-strict mode)
- 1: Fail (strict mode with coverage below threshold)

**Performance benefits:**

- ✅ Uses existing coverage when fresh (no test execution overhead)
- ✅ Detects test framework automatically (works without Taskfile)
- ✅ Parses lcov directly (more reliable than text parsing)
- ✅ Includes test results from junit.xml (comprehensive analysis)

**Integration with Clean Architecture:**

- For files with architectural issues, use `/architect:clean` to refactor before testing
- System files (*.system.ts) excluded from coverage, business logic becomes testable
- Improves coverage by separating concerns instead of excluding business logic
- See [Clean Architecture Guide](../guides/agents.clean.arch.md) for principles
````
