@northbridge-security/secureai 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/README.md +122 -0
- package/.claude/commands/architect/clean.md +978 -0
- package/.claude/commands/architect/kiss.md +762 -0
- package/.claude/commands/architect/review.md +704 -0
- package/.claude/commands/catchup.md +90 -0
- package/.claude/commands/code.md +115 -0
- package/.claude/commands/commit.md +1218 -0
- package/.claude/commands/cover.md +1298 -0
- package/.claude/commands/fmea.md +275 -0
- package/.claude/commands/kaizen.md +312 -0
- package/.claude/commands/pr.md +503 -0
- package/.claude/commands/todo.md +99 -0
- package/.claude/commands/worktree.md +738 -0
- package/.claude/commands/wrapup.md +103 -0
- package/LICENSE +183 -0
- package/README.md +108 -0
- package/dist/cli.js +75634 -0
- package/docs/agents/devops-reviewer.md +889 -0
- package/docs/agents/kiss-simplifier.md +1088 -0
- package/docs/agents/typescript.md +8 -0
- package/docs/guides/README.md +109 -0
- package/docs/guides/agents.clean.arch.md +244 -0
- package/docs/guides/agents.clean.arch.ts.md +1314 -0
- package/docs/guides/agents.gotask.md +1037 -0
- package/docs/guides/agents.markdown.md +1209 -0
- package/docs/guides/agents.onepassword.md +285 -0
- package/docs/guides/agents.sonar.md +857 -0
- package/docs/guides/agents.tdd.md +838 -0
- package/docs/guides/agents.tdd.ts.md +1062 -0
- package/docs/guides/agents.typesript.md +1389 -0
- package/docs/guides/github-mcp.md +1075 -0
- package/package.json +130 -0
- package/packages/secureai-cli/src/cli.ts +21 -0
- package/tasks/README.md +880 -0
- package/tasks/aws.yml +64 -0
- package/tasks/bash.yml +118 -0
- package/tasks/bun.yml +738 -0
- package/tasks/claude.yml +183 -0
- package/tasks/docker.yml +420 -0
- package/tasks/docs.yml +127 -0
- package/tasks/git.yml +1336 -0
- package/tasks/gotask.yml +132 -0
- package/tasks/json.yml +77 -0
- package/tasks/markdown.yml +95 -0
- package/tasks/onepassword.yml +350 -0
- package/tasks/security.yml +102 -0
- package/tasks/sonar.yml +437 -0
- package/tasks/template.yml +74 -0
- package/tasks/vscode.yml +103 -0
- package/tasks/yaml.yml +121 -0
|
@@ -0,0 +1,1298 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Analyze unit test coverage and identify low-coverage files
|
|
3
|
+
argument-hint: [glob-pattern] [--diff] [--strict] [--compare]
|
|
4
|
+
allowed-tools: Bash, Read, Edit, Write, Glob, Grep, Bash(task *)
|
|
5
|
+
plan-mode: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Coverage Analysis: $ARGUMENTS
|
|
9
|
+
|
|
10
|
+
**IMPORTANT - Report Location Pattern**: This command generates a coverage analysis report. See [REPORT-LOCATIONS.md](./REPORT-LOCATIONS.md) for the required pattern:
|
|
11
|
+
|
|
12
|
+
- **Save to temporary directory**: `${TMPDIR:-${TEMP:-/tmp}}/cover-report-$(date +%Y%m%d-%H%M%S).md`
|
|
13
|
+
- **Auto-open in VSCode**: `code "$REPORT_FILE"` after generation
|
|
14
|
+
- **Never save to project root**: No `.cover.report.local.md` files
|
|
15
|
+
|
|
16
|
+
**IMPORTANT**: This command creates multiple temporary files during execution. You MUST cleanup these files before completion (see Phase 6: Cleanup Temporary Files).
|
|
17
|
+
|
|
18
|
+
## Overview: Optimized Coverage Analysis
|
|
19
|
+
|
|
20
|
+
This command analyzes test coverage using an optimized workflow that prioritizes speed and reliability:
|
|
21
|
+
|
|
22
|
+
**Performance-First Approach:**
|
|
23
|
+
|
|
24
|
+
1. **Check for `task test:coverage:report`** - Fast path that uses existing coverage data
|
|
25
|
+
2. **Validate lcov file freshness** - Reuses recent coverage (< 5 minutes old)
|
|
26
|
+
3. **Regenerate if stale** - Runs `task test:coverage` when needed
|
|
27
|
+
4. **Fallback detection** - Auto-detects test framework if no Taskfile tasks
|
|
28
|
+
5. **Direct file analysis** - Parses lcov.info and junit.xml for accuracy
|
|
29
|
+
|
|
30
|
+
**Why This Approach:**
|
|
31
|
+
|
|
32
|
+
- **Speed**: Avoids re-running tests when coverage is fresh
|
|
33
|
+
- **Reliability**: Parses standardized lcov format instead of text output
|
|
34
|
+
- **Flexibility**: Works with or without Taskfile configuration
|
|
35
|
+
- **Comprehensive**: Includes both coverage and test result analysis
|
|
36
|
+
|
|
37
|
+
**Integration with Clean Architecture:**
|
|
38
|
+
|
|
39
|
+
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)).
|
|
40
|
+
|
|
41
|
+
**Required Setup in Taskfile.yml:**
|
|
42
|
+
|
|
43
|
+
For optimal performance, add these tasks to your project's `Taskfile.yml`:
|
|
44
|
+
|
|
45
|
+
```yaml
|
|
46
|
+
tasks:
|
|
47
|
+
test:coverage:
|
|
48
|
+
desc: "Run tests with coverage"
|
|
49
|
+
cmds:
|
|
50
|
+
- bun test --coverage
|
|
51
|
+
|
|
52
|
+
test:coverage:report:
|
|
53
|
+
desc: "Generate coverage report from existing data (fast)"
|
|
54
|
+
cmds:
|
|
55
|
+
- bun test --coverage-report=text
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
If these tasks don't exist, the command will detect your test framework automatically (Bun, Jest, or Vitest).
|
|
59
|
+
|
|
60
|
+
## Phase 0: Parse Arguments
|
|
61
|
+
|
|
62
|
+
Extract from `$ARGUMENTS`:
|
|
63
|
+
|
|
64
|
+
- **Glob pattern**: Optional file pattern (e.g., "src/cli/\*.ts", "src/\*\*/\*.ts")
|
|
65
|
+
- **--diff**: Only analyze staged files
|
|
66
|
+
- **--strict**: Fail if coverage below threshold (80%)
|
|
67
|
+
- **--compare**: Compare with previous `.cover.report.local.md`
|
|
68
|
+
|
|
69
|
+
## Phase 1: Determine Scope and Run Coverage
|
|
70
|
+
|
|
71
|
+
### 1.1 Parse Scope
|
|
72
|
+
|
|
73
|
+
````bash
|
|
74
|
+
# Determine what to test
|
|
75
|
+
if [[ "$ARGUMENTS" =~ --diff ]]; then
|
|
76
|
+
SCOPE="--diff"
|
|
77
|
+
echo "⚙️ Coverage analysis: staged files only"
|
|
78
|
+
elif [[ "$ARGUMENTS" =~ [a-zA-Z0-9/*] ]]; then
|
|
79
|
+
# Extract glob pattern (everything before flags)
|
|
80
|
+
PATTERN=$(echo "$ARGUMENTS" | sed 's/--[a-z]*//g' | xargs)
|
|
81
|
+
SCOPE="--files=$PATTERN"
|
|
82
|
+
echo "⚙️ Coverage analysis: $PATTERN"
|
|
83
|
+
else
|
|
84
|
+
SCOPE=""
|
|
85
|
+
echo "⚙️ Coverage analysis: all files"
|
|
86
|
+
fi
|
|
87
|
+
```text
|
|
88
|
+
|
|
89
|
+
### 1.2 Locate or Generate Coverage Data
|
|
90
|
+
|
|
91
|
+
**Priority Workflow (Fast → Comprehensive):**
|
|
92
|
+
|
|
93
|
+
1. Check for `task test:coverage:report` (fast - uses existing coverage)
|
|
94
|
+
2. Validate existing lcov file timestamp
|
|
95
|
+
3. Run `task test:coverage` if needed (regenerate coverage)
|
|
96
|
+
4. Fallback to test framework detection (no Taskfile available)
|
|
97
|
+
5. Analyze lcov and junit.xml files
|
|
98
|
+
|
|
99
|
+
#### Step 1: Check for Existing Coverage Report Task
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Check if fast report task exists
|
|
103
|
+
HAS_COVERAGE_REPORT_TASK=false
|
|
104
|
+
if task --list 2>/dev/null | grep -q "test:coverage:report"; then
|
|
105
|
+
HAS_COVERAGE_REPORT_TASK=true
|
|
106
|
+
echo "✅ Found task test:coverage:report"
|
|
107
|
+
fi
|
|
108
|
+
```text
|
|
109
|
+
|
|
110
|
+
#### Step 2: Find and Validate Existing Coverage Files
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Locate lcov file (common locations)
|
|
114
|
+
LCOV_LOCATIONS=(
|
|
115
|
+
"coverage/lcov.info"
|
|
116
|
+
"coverage/coverage-final.json"
|
|
117
|
+
".coverage/lcov.info"
|
|
118
|
+
"lcov.info"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
LCOV_FILE=""
|
|
122
|
+
for location in "${LCOV_LOCATIONS[@]}"; do
|
|
123
|
+
if [ -f "$location" ]; then
|
|
124
|
+
LCOV_FILE="$location"
|
|
125
|
+
echo "📊 Found coverage file: $LCOV_FILE"
|
|
126
|
+
break
|
|
127
|
+
fi
|
|
128
|
+
done
|
|
129
|
+
|
|
130
|
+
# Check if coverage is recent (< 5 minutes old)
|
|
131
|
+
COVERAGE_IS_FRESH=false
|
|
132
|
+
if [ -n "$LCOV_FILE" ]; then
|
|
133
|
+
FILE_AGE=$(($(date +%s) - $(stat -f %m "$LCOV_FILE" 2>/dev/null || stat -c %Y "$LCOV_FILE" 2>/dev/null)))
|
|
134
|
+
if [ "$FILE_AGE" -lt 300 ]; then
|
|
135
|
+
COVERAGE_IS_FRESH=true
|
|
136
|
+
echo "✅ Coverage data is fresh (${FILE_AGE}s old)"
|
|
137
|
+
else
|
|
138
|
+
echo "⚠️ Coverage data is stale (${FILE_AGE}s old, threshold: 300s)"
|
|
139
|
+
fi
|
|
140
|
+
fi
|
|
141
|
+
```text
|
|
142
|
+
|
|
143
|
+
#### Step 3: Generate Coverage if Needed
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Decision tree for coverage generation
|
|
147
|
+
NEED_TO_RUN_COVERAGE=false
|
|
148
|
+
|
|
149
|
+
if [ "$HAS_COVERAGE_REPORT_TASK" = "true" ] && [ "$COVERAGE_IS_FRESH" = "true" ]; then
|
|
150
|
+
# Fast path: Use existing coverage report task
|
|
151
|
+
echo "🚀 Using fast coverage report (existing data)"
|
|
152
|
+
task test:coverage:report 2>&1 | tee .bun-coverage.txt
|
|
153
|
+
|
|
154
|
+
elif [ -n "$LCOV_FILE" ] && [ "$COVERAGE_IS_FRESH" = "false" ]; then
|
|
155
|
+
# Coverage exists but is stale - regenerate
|
|
156
|
+
NEED_TO_RUN_COVERAGE=true
|
|
157
|
+
echo "🔄 Regenerating stale coverage data..."
|
|
158
|
+
|
|
159
|
+
elif [ -z "$LCOV_FILE" ]; then
|
|
160
|
+
# No coverage exists - must generate
|
|
161
|
+
NEED_TO_RUN_COVERAGE=true
|
|
162
|
+
echo "📊 No coverage data found - generating..."
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# Run coverage generation if needed
|
|
166
|
+
if [ "$NEED_TO_RUN_COVERAGE" = "true" ]; then
|
|
167
|
+
# Check for task-based coverage generation
|
|
168
|
+
if task --list 2>/dev/null | grep -q "test:coverage"; then
|
|
169
|
+
echo "✅ Running task test:coverage"
|
|
170
|
+
if [ -n "$SCOPE" ]; then
|
|
171
|
+
task test:coverage $SCOPE 2>&1 | tee .bun-coverage.txt
|
|
172
|
+
else
|
|
173
|
+
task test:coverage 2>&1 | tee .bun-coverage.txt
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
elif task --list 2>/dev/null | grep -q "cov"; then
|
|
177
|
+
echo "✅ Running task cov"
|
|
178
|
+
task cov 2>&1 | tee .bun-coverage.txt
|
|
179
|
+
|
|
180
|
+
else
|
|
181
|
+
# Fallback: Detect test framework and run directly
|
|
182
|
+
echo "⚠️ No task-based coverage found - detecting test framework..."
|
|
183
|
+
|
|
184
|
+
# Detect package.json test framework
|
|
185
|
+
if [ -f "package.json" ]; then
|
|
186
|
+
if grep -q '"bun"' package.json; then
|
|
187
|
+
echo "✅ Detected: Bun test runner"
|
|
188
|
+
bun test --coverage 2>&1 | tee .bun-coverage.txt
|
|
189
|
+
|
|
190
|
+
elif grep -q '"jest"' package.json; then
|
|
191
|
+
echo "✅ Detected: Jest test runner"
|
|
192
|
+
npm run test -- --coverage 2>&1 | tee .bun-coverage.txt
|
|
193
|
+
|
|
194
|
+
elif grep -q '"vitest"' package.json; then
|
|
195
|
+
echo "✅ Detected: Vitest test runner"
|
|
196
|
+
npm run test -- --coverage 2>&1 | tee .bun-coverage.txt
|
|
197
|
+
|
|
198
|
+
else
|
|
199
|
+
echo "❌ Error: Cannot detect test framework"
|
|
200
|
+
echo " Please add 'task test:coverage' to Taskfile.yml"
|
|
201
|
+
exit 1
|
|
202
|
+
fi
|
|
203
|
+
else
|
|
204
|
+
echo "❌ Error: No package.json found"
|
|
205
|
+
exit 1
|
|
206
|
+
fi
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
# Check if coverage ran successfully
|
|
210
|
+
if [ ${PIPESTATUS[0]} -ne 0 ]; then
|
|
211
|
+
echo "❌ Coverage run failed"
|
|
212
|
+
exit 1
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
# Re-locate lcov file after generation
|
|
216
|
+
for location in "${LCOV_LOCATIONS[@]}"; do
|
|
217
|
+
if [ -f "$location" ]; then
|
|
218
|
+
LCOV_FILE="$location"
|
|
219
|
+
echo "📊 Generated coverage file: $LCOV_FILE"
|
|
220
|
+
break
|
|
221
|
+
fi
|
|
222
|
+
done
|
|
223
|
+
fi
|
|
224
|
+
```text
|
|
225
|
+
|
|
226
|
+
#### Step 4: Locate JUnit XML File (if available)
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# Find JUnit XML for test results (optional but recommended)
|
|
230
|
+
JUNIT_LOCATIONS=(
|
|
231
|
+
"test-results/junit.xml"
|
|
232
|
+
"junit.xml"
|
|
233
|
+
"coverage/junit.xml"
|
|
234
|
+
".test-results/junit.xml"
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
JUNIT_FILE=""
|
|
238
|
+
for location in "${JUNIT_LOCATIONS[@]}"; do
|
|
239
|
+
if [ -f "$location" ]; then
|
|
240
|
+
JUNIT_FILE="$location"
|
|
241
|
+
echo "📋 Found JUnit file: $JUNIT_FILE"
|
|
242
|
+
break
|
|
243
|
+
fi
|
|
244
|
+
done
|
|
245
|
+
|
|
246
|
+
if [ -z "$JUNIT_FILE" ]; then
|
|
247
|
+
echo "⚠️ No JUnit XML found (test results won't be analyzed)"
|
|
248
|
+
fi
|
|
249
|
+
```text
|
|
250
|
+
|
|
251
|
+
#### Step 5: Validate Coverage Data
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# Verify we have coverage data to analyze
|
|
255
|
+
if [ -z "$LCOV_FILE" ] || [ ! -f "$LCOV_FILE" ]; then
|
|
256
|
+
echo "❌ Error: No coverage data available"
|
|
257
|
+
echo " Tried locations:"
|
|
258
|
+
for location in "${LCOV_LOCATIONS[@]}"; do
|
|
259
|
+
echo " - $location"
|
|
260
|
+
done
|
|
261
|
+
echo ""
|
|
262
|
+
echo " Ensure coverage was generated successfully"
|
|
263
|
+
exit 1
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
echo "✅ Coverage data validated: $LCOV_FILE"
|
|
267
|
+
```text
|
|
268
|
+
|
|
269
|
+
**Benefits of this approach:**
|
|
270
|
+
|
|
271
|
+
- **Speed**: Uses `task test:coverage:report` when available (no test execution)
|
|
272
|
+
- **Reliability**: Validates coverage freshness before using cached data
|
|
273
|
+
- **Flexibility**: Falls back to test framework detection when no tasks available
|
|
274
|
+
- **Comprehensive**: Analyzes both lcov (coverage) and junit.xml (test results)
|
|
275
|
+
|
|
276
|
+
### 1.3 Load Previous Report (if --compare)
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
if [[ "$ARGUMENTS" =~ --compare ]] && [ -f .cover.report.local.md ]; then
|
|
280
|
+
PREV_TIMESTAMP=$(grep "^Generated:" .cover.report.local.md | head -1 | cut -d' ' -f2-)
|
|
281
|
+
PREV_OVERALL=$(grep "^Overall Coverage:" .cover.report.local.md | head -1)
|
|
282
|
+
echo "=� Comparing with previous report: $PREV_TIMESTAMP"
|
|
283
|
+
fi
|
|
284
|
+
```text
|
|
285
|
+
|
|
286
|
+
## Phase 2: Parse Coverage Data
|
|
287
|
+
|
|
288
|
+
### 2.1 Read Coverage Thresholds from docs/QA.md
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
# Extract thresholds from QA.md
|
|
292
|
+
THRESHOLD_FUNCTIONS=$(grep -A5 "Coverage Targets" docs/QA.md | grep "Function Coverage" | grep -oE "[0-9]+" | head -1)
|
|
293
|
+
THRESHOLD_LINES=$(grep -A5 "Coverage Targets" docs/QA.md | grep "Line Coverage" | grep -oE "[0-9]+" | head -1)
|
|
294
|
+
|
|
295
|
+
# Default to 80% if not found
|
|
296
|
+
THRESHOLD_FUNCTIONS=${THRESHOLD_FUNCTIONS:-80}
|
|
297
|
+
THRESHOLD_LINES=${THRESHOLD_LINES:-80}
|
|
298
|
+
|
|
299
|
+
echo "⚙️ Thresholds: Functions ${THRESHOLD_FUNCTIONS}%, Lines ${THRESHOLD_LINES}%"
|
|
300
|
+
```text
|
|
301
|
+
|
|
302
|
+
### 2.2 Parse LCOV Coverage Data
|
|
303
|
+
|
|
304
|
+
Parse lcov.info file for detailed coverage information:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# Parse lcov file for coverage data
|
|
308
|
+
# LCOV format: SF:<file> | FNF:<functions found> | FNH:<functions hit> | LF:<lines found> | LH:<lines hit>
|
|
309
|
+
|
|
310
|
+
echo "📊 Parsing coverage from: $LCOV_FILE"
|
|
311
|
+
|
|
312
|
+
# Extract overall coverage from lcov
|
|
313
|
+
TOTAL_FUNCTIONS_FOUND=0
|
|
314
|
+
TOTAL_FUNCTIONS_HIT=0
|
|
315
|
+
TOTAL_LINES_FOUND=0
|
|
316
|
+
TOTAL_LINES_HIT=0
|
|
317
|
+
|
|
318
|
+
# Parse lcov for per-file coverage
|
|
319
|
+
CURRENT_FILE=""
|
|
320
|
+
while IFS= read -r line; do
|
|
321
|
+
if [[ "$line" =~ ^SF:(.*) ]]; then
|
|
322
|
+
CURRENT_FILE="${BASH_REMATCH[1]}"
|
|
323
|
+
elif [[ "$line" =~ ^FNF:([0-9]+) ]]; then
|
|
324
|
+
FNF="${BASH_REMATCH[1]}"
|
|
325
|
+
TOTAL_FUNCTIONS_FOUND=$((TOTAL_FUNCTIONS_FOUND + FNF))
|
|
326
|
+
elif [[ "$line" =~ ^FNH:([0-9]+) ]]; then
|
|
327
|
+
FNH="${BASH_REMATCH[1]}"
|
|
328
|
+
TOTAL_FUNCTIONS_HIT=$((TOTAL_FUNCTIONS_HIT + FNH))
|
|
329
|
+
elif [[ "$line" =~ ^LF:([0-9]+) ]]; then
|
|
330
|
+
LF="${BASH_REMATCH[1]}"
|
|
331
|
+
TOTAL_LINES_FOUND=$((TOTAL_LINES_FOUND + LF))
|
|
332
|
+
elif [[ "$line" =~ ^LH:([0-9]+) ]]; then
|
|
333
|
+
LH="${BASH_REMATCH[1]}"
|
|
334
|
+
TOTAL_LINES_HIT=$((TOTAL_LINES_HIT + LH))
|
|
335
|
+
elif [[ "$line" =~ ^end_of_record ]]; then
|
|
336
|
+
# Calculate coverage percentages for current file
|
|
337
|
+
if [ -n "$CURRENT_FILE" ] && [ "$FNF" -gt 0 ]; then
|
|
338
|
+
FUNC_COV=$(awk "BEGIN {printf \"%.2f\", ($FNH / $FNF) * 100}")
|
|
339
|
+
LINE_COV=$(awk "BEGIN {printf \"%.2f\", ($LH / $LF) * 100}")
|
|
340
|
+
|
|
341
|
+
# Save to temporary file for analysis
|
|
342
|
+
echo "$CURRENT_FILE|$FUNC_COV|$LINE_COV|$FNH/$FNF|$LH/$LF" >> .coverage-files.tmp
|
|
343
|
+
fi
|
|
344
|
+
|
|
345
|
+
# Reset for next file
|
|
346
|
+
CURRENT_FILE=""
|
|
347
|
+
FNF=0
|
|
348
|
+
FNH=0
|
|
349
|
+
LF=0
|
|
350
|
+
LH=0
|
|
351
|
+
fi
|
|
352
|
+
done < "$LCOV_FILE"
|
|
353
|
+
|
|
354
|
+
# Calculate overall coverage percentages
|
|
355
|
+
if [ "$TOTAL_FUNCTIONS_FOUND" -gt 0 ]; then
|
|
356
|
+
OVERALL_FUNCTIONS=$(awk "BEGIN {printf \"%.2f\", ($TOTAL_FUNCTIONS_HIT / $TOTAL_FUNCTIONS_FOUND) * 100}")
|
|
357
|
+
else
|
|
358
|
+
OVERALL_FUNCTIONS="0.00"
|
|
359
|
+
fi
|
|
360
|
+
|
|
361
|
+
if [ "$TOTAL_LINES_FOUND" -gt 0 ]; then
|
|
362
|
+
OVERALL_LINES=$(awk "BEGIN {printf \"%.2f\", ($TOTAL_LINES_HIT / $TOTAL_LINES_FOUND) * 100}")
|
|
363
|
+
else
|
|
364
|
+
OVERALL_LINES="0.00"
|
|
365
|
+
fi
|
|
366
|
+
|
|
367
|
+
echo "✅ Overall Coverage: Functions ${OVERALL_FUNCTIONS}%, Lines ${OVERALL_LINES}%"
|
|
368
|
+
```text
|
|
369
|
+
|
|
370
|
+
**LCOV file format reference:**
|
|
371
|
+
|
|
372
|
+
```text
|
|
373
|
+
SF:src/cli/index.ts
|
|
374
|
+
FNF:7 # Functions found
|
|
375
|
+
FNH:6 # Functions hit
|
|
376
|
+
LF:45 # Lines found
|
|
377
|
+
LH:42 # Lines hit
|
|
378
|
+
end_of_record
|
|
379
|
+
```text
|
|
380
|
+
|
|
381
|
+
### 2.2.1 Parse JUnit XML for Test Results (Optional)
|
|
382
|
+
|
|
383
|
+
If JUnit XML is available, extract test execution data:
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
if [ -n "$JUNIT_FILE" ] && [ -f "$JUNIT_FILE" ]; then
|
|
387
|
+
echo "📋 Parsing test results from: $JUNIT_FILE"
|
|
388
|
+
|
|
389
|
+
# Extract test summary from JUnit XML
|
|
390
|
+
TOTAL_TESTS=$(grep -oP 'tests="\K[0-9]+' "$JUNIT_FILE" | head -1)
|
|
391
|
+
FAILED_TESTS=$(grep -oP 'failures="\K[0-9]+' "$JUNIT_FILE" | head -1)
|
|
392
|
+
ERROR_TESTS=$(grep -oP 'errors="\K[0-9]+' "$JUNIT_FILE" | head -1)
|
|
393
|
+
SKIPPED_TESTS=$(grep -oP 'skipped="\K[0-9]+' "$JUNIT_FILE" | head -1)
|
|
394
|
+
|
|
395
|
+
# Default to 0 if not found
|
|
396
|
+
TOTAL_TESTS=${TOTAL_TESTS:-0}
|
|
397
|
+
FAILED_TESTS=${FAILED_TESTS:-0}
|
|
398
|
+
ERROR_TESTS=${ERROR_TESTS:-0}
|
|
399
|
+
SKIPPED_TESTS=${SKIPPED_TESTS:-0}
|
|
400
|
+
|
|
401
|
+
PASSED_TESTS=$((TOTAL_TESTS - FAILED_TESTS - ERROR_TESTS - SKIPPED_TESTS))
|
|
402
|
+
|
|
403
|
+
echo "✅ Test Results: $PASSED_TESTS passed, $FAILED_TESTS failed, $SKIPPED_TESTS skipped (Total: $TOTAL_TESTS)"
|
|
404
|
+
|
|
405
|
+
# Store for report
|
|
406
|
+
TEST_SUMMARY="**Test Results**: $PASSED_TESTS/$TOTAL_TESTS passed ($FAILED_TESTS failed, $SKIPPED_TESTS skipped)"
|
|
407
|
+
else
|
|
408
|
+
TEST_SUMMARY=""
|
|
409
|
+
fi
|
|
410
|
+
```text
|
|
411
|
+
|
|
412
|
+
### 2.3 Parse Exclusions from package.json
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
# Get coverage exclusions
|
|
416
|
+
EXCLUSIONS=$(cat package.json | jq -r '.coverage.exclude[]?' 2>/dev/null || echo "")
|
|
417
|
+
|
|
418
|
+
if [ -n "$EXCLUSIONS" ]; then
|
|
419
|
+
echo "=� Exclusions configured:"
|
|
420
|
+
echo "$EXCLUSIONS" | while read -r pattern; do
|
|
421
|
+
echo " � $pattern"
|
|
422
|
+
done
|
|
423
|
+
fi
|
|
424
|
+
```text
|
|
425
|
+
|
|
426
|
+
## Phase 3: Analyze and Prioritize Files
|
|
427
|
+
|
|
428
|
+
### 3.1 Identify File Categories
|
|
429
|
+
|
|
430
|
+
#### Tier 1: New Files (created in current branch)
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
# Find files added in current branch vs main
|
|
434
|
+
NEW_FILES=$(git diff --name-status origin/main...HEAD 2>/dev/null | grep '^A' | awk '{print $2}' | grep '\.ts$')
|
|
435
|
+
|
|
436
|
+
# Cross-reference with coverage data
|
|
437
|
+
while read -r file; do
|
|
438
|
+
# Check if file appears in coverage with low coverage
|
|
439
|
+
COVERAGE=$(grep "$file" .coverage-files.tmp | awk '{print $3}' | tr -d '%')
|
|
440
|
+
if [ -n "$COVERAGE" ]; then
|
|
441
|
+
if (( $(echo "$COVERAGE < $THRESHOLD_FUNCTIONS" | bc -l) )); then
|
|
442
|
+
echo "$file|$COVERAGE|NEW" >> .coverage-analysis.tmp
|
|
443
|
+
fi
|
|
444
|
+
else
|
|
445
|
+
# New file with no tests at all
|
|
446
|
+
echo "$file|0.00|NEW_NO_TESTS" >> .coverage-analysis.tmp
|
|
447
|
+
fi
|
|
448
|
+
done <<< "$NEW_FILES"
|
|
449
|
+
```text
|
|
450
|
+
|
|
451
|
+
#### Tier 2: High-Impact Files (below threshold)
|
|
452
|
+
|
|
453
|
+
High-impact files based on docs/QA.md or project structure:
|
|
454
|
+
|
|
455
|
+
- `src/cli/**/*.ts` - CLI commands and interfaces
|
|
456
|
+
- `src/state/**/*.ts` - State management
|
|
457
|
+
- `src/config/**/*.ts` - Configuration handling
|
|
458
|
+
- `src/security/**/*.ts` - Security-critical code
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
# Define high-impact patterns
|
|
462
|
+
HIGH_IMPACT_PATTERNS=(
|
|
463
|
+
"src/cli/"
|
|
464
|
+
"src/state/"
|
|
465
|
+
"src/config/"
|
|
466
|
+
"src/security/"
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
# Find high-impact files below threshold
|
|
470
|
+
while read -r line; do
|
|
471
|
+
FILE=$(echo "$line" | awk '{print $1}')
|
|
472
|
+
FUNC_COV=$(echo "$line" | awk '{print $3}' | tr -d '%')
|
|
473
|
+
|
|
474
|
+
# Skip if excluded
|
|
475
|
+
EXCLUDED=false
|
|
476
|
+
for pattern in $EXCLUSIONS; do
|
|
477
|
+
if [[ "$FILE" =~ $pattern ]]; then
|
|
478
|
+
EXCLUDED=true
|
|
479
|
+
break
|
|
480
|
+
fi
|
|
481
|
+
done
|
|
482
|
+
|
|
483
|
+
if [ "$EXCLUDED" = "true" ]; then
|
|
484
|
+
continue
|
|
485
|
+
fi
|
|
486
|
+
|
|
487
|
+
# Check if high-impact and below threshold
|
|
488
|
+
for pattern in "${HIGH_IMPACT_PATTERNS[@]}"; do
|
|
489
|
+
if [[ "$FILE" =~ $pattern ]] && (( $(echo "$FUNC_COV < $THRESHOLD_FUNCTIONS" | bc -l) )); then
|
|
490
|
+
# Skip if already in new files
|
|
491
|
+
if ! grep -q "^$FILE|" .coverage-analysis.tmp 2>/dev/null; then
|
|
492
|
+
echo "$FILE|$FUNC_COV|HIGH_IMPACT" >> .coverage-analysis.tmp
|
|
493
|
+
fi
|
|
494
|
+
break
|
|
495
|
+
fi
|
|
496
|
+
done
|
|
497
|
+
done < .coverage-files.tmp
|
|
498
|
+
```text
|
|
499
|
+
|
|
500
|
+
#### Tier 3: Other Files (below threshold)
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
# All other files below threshold
|
|
504
|
+
while read -r line; do
|
|
505
|
+
FILE=$(echo "$line" | awk '{print $1}')
|
|
506
|
+
FUNC_COV=$(echo "$line" | awk '{print $3}' | tr -d '%')
|
|
507
|
+
LINE_COV=$(echo "$line" | awk '{print $4}' | tr -d '%')
|
|
508
|
+
|
|
509
|
+
# Skip if excluded
|
|
510
|
+
EXCLUDED=false
|
|
511
|
+
for pattern in $EXCLUSIONS; do
|
|
512
|
+
if [[ "$FILE" =~ $pattern ]]; then
|
|
513
|
+
echo "$FILE|$FUNC_COV|EXCLUDED" >> .coverage-excluded.tmp
|
|
514
|
+
EXCLUDED=true
|
|
515
|
+
break
|
|
516
|
+
fi
|
|
517
|
+
done
|
|
518
|
+
|
|
519
|
+
if [ "$EXCLUDED" = "true" ]; then
|
|
520
|
+
continue
|
|
521
|
+
fi
|
|
522
|
+
|
|
523
|
+
# Check if below threshold and not already categorized
|
|
524
|
+
if (( $(echo "$FUNC_COV < $THRESHOLD_FUNCTIONS" | bc -l) )) || (( $(echo "$LINE_COV < $THRESHOLD_LINES" | bc -l) )); then
|
|
525
|
+
if ! grep -q "^$FILE|" .coverage-analysis.tmp 2>/dev/null; then
|
|
526
|
+
echo "$FILE|$FUNC_COV|LOW_COVERAGE" >> .coverage-analysis.tmp
|
|
527
|
+
fi
|
|
528
|
+
fi
|
|
529
|
+
done < .coverage-files.tmp
|
|
530
|
+
```text
|
|
531
|
+
|
|
532
|
+
### 3.2 Identify Pure Engine Code (Recommend for Exclusion)
|
|
533
|
+
|
|
534
|
+
Characteristics of pure engine/plumbing code:
|
|
535
|
+
|
|
536
|
+
- Re-export files (only `export * from` or `export { ... }`)
|
|
537
|
+
- CLI wrappers with no business logic
|
|
538
|
+
- Type-only files
|
|
539
|
+
|
|
540
|
+
```bash
|
|
541
|
+
# Scan for re-export only files
|
|
542
|
+
find src -name "*.ts" -type f | while read -r file; do
|
|
543
|
+
# Check if file is purely re-exports
|
|
544
|
+
NON_EXPORT_LINES=$(grep -vE '^\s*(export|import|/\*|//|$)' "$file" | wc -l)
|
|
545
|
+
|
|
546
|
+
if [ "$NON_EXPORT_LINES" -eq 0 ]; then
|
|
547
|
+
# Pure re-export file
|
|
548
|
+
if grep -q "^$file|" .coverage-files.tmp; then
|
|
549
|
+
COVERAGE=$(grep "^$file|" .coverage-files.tmp | awk '{print $3}' | tr -d '%')
|
|
550
|
+
echo "$file|$COVERAGE|PURE_ENGINE" >> .coverage-exclude-candidates.tmp
|
|
551
|
+
fi
|
|
552
|
+
fi
|
|
553
|
+
done
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
### 3.3 Identify Untestable Code (Architecture Issues)
|
|
557
|
+
|
|
558
|
+
Files with low coverage may be untestable due to architectural problems:
|
|
559
|
+
|
|
560
|
+
**Indicators of architectural issues:**
|
|
561
|
+
|
|
562
|
+
- Business logic mixed with system calls (execSync, fs operations, network calls)
|
|
563
|
+
- Hardcoded dependencies (cannot inject mocks)
|
|
564
|
+
- No separation between business logic and infrastructure
|
|
565
|
+
|
|
566
|
+
**For these files, coverage exclusion is NOT the solution.** Instead, refactor for testability:
|
|
567
|
+
|
|
568
|
+
```bash
|
|
569
|
+
# Identify files with mixed logic (heuristic)
|
|
570
|
+
while read -r line; do
|
|
571
|
+
FILE=$(echo "$line" | awk -F'|' '{print $1}')
|
|
572
|
+
FUNC_COV=$(echo "$line" | awk -F'|' '{print $2}')
|
|
573
|
+
|
|
574
|
+
# Check if file contains system calls
|
|
575
|
+
if grep -qE "(execSync|readFileSync|writeFileSync|fetch\()" "$FILE" 2>/dev/null; then
|
|
576
|
+
# And has business logic (not just a thin wrapper)
|
|
577
|
+
if [ $(wc -l < "$FILE") -gt 50 ]; then
|
|
578
|
+
echo "$FILE|$FUNC_COV|MIXED_LOGIC" >> .coverage-architecture-issues.tmp
|
|
579
|
+
fi
|
|
580
|
+
fi
|
|
581
|
+
done < .coverage-files.tmp
|
|
582
|
+
|
|
583
|
+
# Report these for architectural refactoring
|
|
584
|
+
ARCH_ISSUES=$(wc -l < .coverage-architecture-issues.tmp 2>/dev/null || echo 0)
|
|
585
|
+
if [ "$ARCH_ISSUES" -gt 0 ]; then
|
|
586
|
+
echo "⚠️ Found $ARCH_ISSUES files with mixed business/system logic"
|
|
587
|
+
echo " Consider: /architect:clean [scope] to refactor for testability"
|
|
588
|
+
fi
|
|
589
|
+
```text
|
|
590
|
+
|
|
591
|
+
## Phase 4: Generate Recommendations
|
|
592
|
+
|
|
593
|
+
### 4.1 Determine Overall Status
|
|
594
|
+
|
|
595
|
+
```bash
|
|
596
|
+
# Check if overall coverage meets threshold
|
|
597
|
+
OVERALL_PASS=true
|
|
598
|
+
if (( $(echo "$OVERALL_FUNCTIONS < $THRESHOLD_FUNCTIONS" | bc -l) )); then
|
|
599
|
+
OVERALL_PASS=false
|
|
600
|
+
fi
|
|
601
|
+
if (( $(echo "$OVERALL_LINES < $THRESHOLD_LINES" | bc -l) )); then
|
|
602
|
+
OVERALL_PASS=false
|
|
603
|
+
fi
|
|
604
|
+
|
|
605
|
+
if [ "$OVERALL_PASS" = "true" ]; then
|
|
606
|
+
OVERALL_STATUS=" PASS"
|
|
607
|
+
else
|
|
608
|
+
OVERALL_STATUS="L FAIL"
|
|
609
|
+
fi
|
|
610
|
+
```text
|
|
611
|
+
|
|
612
|
+
### 4.2 Generate Action Plan
|
|
613
|
+
|
|
614
|
+
Based on categorized files, create prioritized action plan:
|
|
615
|
+
|
|
616
|
+
1. **Fix new files first** (Tier 1) - AI-generated code without tests
|
|
617
|
+
2. **Fix high-impact files** (Tier 2) - Core functionality below threshold
|
|
618
|
+
3. **Consider excluding engine code** - Pure plumbing with no logic
|
|
619
|
+
4. **Add tests to remaining files** (Tier 3) - Other low-coverage files
|
|
620
|
+
|
|
621
|
+
**TDD Approach for Writing Tests:**
|
|
622
|
+
|
|
623
|
+
When adding tests to improve coverage, follow TDD principles for better test quality:
|
|
624
|
+
|
|
625
|
+
- **Red-Green-Refactor** - Write failing test, implement fix, improve code
|
|
626
|
+
- **Arrange-Act-Assert** - Structure tests clearly (setup → execute → verify)
|
|
627
|
+
- **Test behavior, not implementation** - Verify what code does, not how
|
|
628
|
+
- **Mock external dependencies** - Isolate unit under test from I/O
|
|
629
|
+
|
|
630
|
+
See: `~/.claude/guides/agents.tdd.md` for TDD principles
|
|
631
|
+
See: `~/.claude/guides/agents.tdd.ts.md` for TypeScript-specific testing patterns
|
|
632
|
+
|
|
633
|
+
```bash
|
|
634
|
+
# Count files in each tier
|
|
635
|
+
NEW_FILE_COUNT=$(grep "|NEW" .coverage-analysis.tmp 2>/dev/null | wc -l)
|
|
636
|
+
HIGH_IMPACT_COUNT=$(grep "|HIGH_IMPACT" .coverage-analysis.tmp 2>/dev/null | wc -l)
|
|
637
|
+
LOW_COVERAGE_COUNT=$(grep "|LOW_COVERAGE" .coverage-analysis.tmp 2>/dev/null | wc -l)
|
|
638
|
+
ENGINE_COUNT=$(wc -l < .coverage-exclude-candidates.tmp 2>/dev/null || echo 0)
|
|
639
|
+
|
|
640
|
+
echo "=� Analysis complete:"
|
|
641
|
+
echo " <� New files without tests: $NEW_FILE_COUNT"
|
|
642
|
+
echo " � High-impact files below threshold: $HIGH_IMPACT_COUNT"
|
|
643
|
+
echo " =� Other low-coverage files: $LOW_COVERAGE_COUNT"
|
|
644
|
+
echo " =' Pure engine files (exclude candidates): $ENGINE_COUNT"
|
|
645
|
+
```text
|
|
646
|
+
|
|
647
|
+
## Phase 5: Generate Report
|
|
648
|
+
|
|
649
|
+
Create `.cover.report.local.md`:
|
|
650
|
+
|
|
651
|
+
```markdown
|
|
652
|
+
# Coverage Analysis Report
|
|
653
|
+
|
|
654
|
+
**Generated:** [timestamp ISO]
|
|
655
|
+
**Scope:** [all files | pattern | staged files]
|
|
656
|
+
**Overall Status:** [ PASS | L FAIL]
|
|
657
|
+
|
|
658
|
+
## Summary
|
|
659
|
+
|
|
660
|
+
- **Overall Coverage:**
|
|
661
|
+
- Functions: [X.XX]% (threshold: [80]%)
|
|
662
|
+
- Lines: [X.XX]% (threshold: [80]%)
|
|
663
|
+
- **Files Analyzed:** [count]
|
|
664
|
+
- **Files Below Threshold:** [count]
|
|
665
|
+
- **Action Required:** [Yes | No]
|
|
666
|
+
|
|
667
|
+
---
|
|
668
|
+
|
|
669
|
+
## Priority: Fix New Files First <�
|
|
670
|
+
|
|
671
|
+
**Issue:** AI-generated code often lacks tests. These files were added recently and have low/no coverage.
|
|
672
|
+
|
|
673
|
+
| File | Function % | Line % | Status |
|
|
674
|
+
|------|------------|--------|--------|
|
|
675
|
+
| src/cli/new-command.ts | 0.00 | 0.00 | No tests |
|
|
676
|
+
| src/utils/new-helper.ts | 25.00 | 30.00 | Partial |
|
|
677
|
+
|
|
678
|
+
**Action:**
|
|
679
|
+
- Add unit tests for these files first
|
|
680
|
+
- Follow TDD approach: write failing test (RED), implement (GREEN), refactor
|
|
681
|
+
- Focus on business logic and error paths
|
|
682
|
+
- Target: Achieve 80%+ coverage before merging
|
|
683
|
+
|
|
684
|
+
**TDD Resources:**
|
|
685
|
+
- See: `~/.claude/guides/agents.tdd.md` for TDD principles
|
|
686
|
+
- See: `~/.claude/guides/agents.tdd.ts.md` for TypeScript testing patterns
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
## Priority: High-Impact Files Below Threshold �
|
|
691
|
+
|
|
692
|
+
**Issue:** Core functionality with insufficient test coverage.
|
|
693
|
+
|
|
694
|
+
| File | Function % | Line % | Impact Area |
|
|
695
|
+
|------|------------|--------|-------------|
|
|
696
|
+
| src/cli/install.ts | 45.00 | 58.00 | CLI |
|
|
697
|
+
| src/state/config.ts | 62.00 | 70.00 | State |
|
|
698
|
+
|
|
699
|
+
**Action:**
|
|
700
|
+
- Add tests for critical paths and error handling
|
|
701
|
+
- Mock external dependencies (file system, network)
|
|
702
|
+
- Use TDD approach: test behavior, not implementation
|
|
703
|
+
- Prioritize by user-facing impact
|
|
704
|
+
|
|
705
|
+
---
|
|
706
|
+
|
|
707
|
+
## Priority: Architecture Issues ⚠️
|
|
708
|
+
|
|
709
|
+
**Issue:** Files with mixed business logic and system calls are untestable without refactoring.
|
|
710
|
+
|
|
711
|
+
| File | Function % | Line % | Issue |
|
|
712
|
+
|------|------------|--------|-------|
|
|
713
|
+
| src/utils/auth.ts | 35.00 | 42.00 | Mixed LDAP calls and validation |
|
|
714
|
+
| src/installers/npm.ts | 40.00 | 48.00 | Mixed execSync and business logic |
|
|
715
|
+
|
|
716
|
+
**Recommended Action:**
|
|
717
|
+
|
|
718
|
+
Use Clean Architecture refactoring instead of coverage exclusion:
|
|
719
|
+
|
|
720
|
+
```bash
|
|
721
|
+
# Analyze and refactor for testability
|
|
722
|
+
/architect:clean src/utils/auth.ts
|
|
723
|
+
|
|
724
|
+
# Review proposed refactorings in .clean.local.md
|
|
725
|
+
# The agent will:
|
|
726
|
+
# 1. Extract interfaces for system dependencies
|
|
727
|
+
# 2. Create *.system.ts files for system calls
|
|
728
|
+
# 3. Add dependency injection to business logic
|
|
729
|
+
# 4. Create mocks for testing
|
|
730
|
+
# 5. Update coverage configuration
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
**Why refactor instead of exclude:**
|
|
734
|
+
|
|
735
|
+
- Business logic becomes fully testable with mocks
|
|
736
|
+
- System files (*.system.ts) are excluded from coverage
|
|
737
|
+
- Overall coverage improves (business logic counted, system calls excluded)
|
|
738
|
+
- Better separation of concerns and maintainability
|
|
739
|
+
|
|
740
|
+
**See:** [Clean Architecture Guide](../guides/agents.clean.arch.md) | [/architect:clean Command](./architect/clean.md)
|
|
741
|
+
|
|
742
|
+
---
|
|
743
|
+
|
|
744
|
+
## Consider: Exclude Pure Engine Code ='
|
|
745
|
+
|
|
746
|
+
**Issue:** These files contain only re-exports or thin wrappers with no testable logic.
|
|
747
|
+
|
|
748
|
+
| File | Function % | Line % | Reason |
|
|
749
|
+
|------|------------|--------|--------|
|
|
750
|
+
| src/index.ts | 0.00 | 0.00 | Pure re-export |
|
|
751
|
+
| src/types/index.ts | 0.00 | 0.00 | Type-only |
|
|
752
|
+
|
|
753
|
+
**Recommendation:** Add Istanbul ignore or package.json exclusions:
|
|
754
|
+
|
|
755
|
+
### Option 1: Istanbul Ignore (TypeScript)
|
|
756
|
+
|
|
757
|
+
```typescript
|
|
758
|
+
/* istanbul ignore file */
|
|
759
|
+
|
|
760
|
+
// Rest of file...
|
|
761
|
+
```text
|
|
762
|
+
|
|
763
|
+
### Option 2: package.json Exclusions
|
|
764
|
+
|
|
765
|
+
```json
|
|
766
|
+
{
|
|
767
|
+
"coverage": {
|
|
768
|
+
"exclude": [
|
|
769
|
+
"src/index.ts",
|
|
770
|
+
"src/types/index.ts"
|
|
771
|
+
]
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
```text
|
|
775
|
+
|
|
776
|
+
**Verify with operator before excluding** - Ensure files truly have no testable logic.
|
|
777
|
+
|
|
778
|
+
---
|
|
779
|
+
|
|
780
|
+
## Low Coverage Files (Other) =�
|
|
781
|
+
|
|
782
|
+
**Issue:** Files below threshold but not high-impact.
|
|
783
|
+
|
|
784
|
+
| File | Function % | Line % |
|
|
785
|
+
|------|------------|--------|
|
|
786
|
+
| src/utils/format.ts | 65.00 | 72.00 |
|
|
787
|
+
| src/ui/prompts.ts | 55.00 | 60.00 |
|
|
788
|
+
|
|
789
|
+
**Action:**
|
|
790
|
+
|
|
791
|
+
- Add tests when time allows
|
|
792
|
+
- Focus on public API and error cases
|
|
793
|
+
- Lower priority than Tier 1 and Tier 2
|
|
794
|
+
|
|
795
|
+
---
|
|
796
|
+
|
|
797
|
+
## Excluded Files �
|
|
798
|
+
|
|
799
|
+
These files are excluded from coverage analysis per `package.json` configuration:
|
|
800
|
+
|
|
801
|
+
[List files with exclusion pattern]
|
|
802
|
+
|
|
803
|
+
---
|
|
804
|
+
|
|
805
|
+
## Comparison with Previous Report
|
|
806
|
+
|
|
807
|
+
[Only if --compare used]
|
|
808
|
+
|
|
809
|
+
### Changes Since Last Run ([timestamp])
|
|
810
|
+
|
|
811
|
+
- **Overall Functions:** [prev]% � [current]% ([+/- delta])
|
|
812
|
+
- **Overall Lines:** [prev]% � [current]% ([+/- delta])
|
|
813
|
+
- **Files Fixed:** [count] files now meet threshold
|
|
814
|
+
- **New Issues:** [count] files dropped below threshold
|
|
815
|
+
|
|
816
|
+
---
|
|
817
|
+
|
|
818
|
+
## Recommendations
|
|
819
|
+
|
|
820
|
+
### =4 Critical (Do First)
|
|
821
|
+
|
|
822
|
+
1. **Add tests to [X] new files** - Start with files that have 0% coverage
|
|
823
|
+
2. **Fix high-impact files** - Focus on CLI and state management
|
|
824
|
+
3. **Review coverage in CI** - Ensure coverage doesn't regress
|
|
825
|
+
|
|
826
|
+
### =� High Priority
|
|
827
|
+
|
|
828
|
+
1. **Verify engine code exclusions** - Confirm with operator before ignoring
|
|
829
|
+
2. **Add integration tests** - Cover module interactions
|
|
830
|
+
3. **Test error paths** - Ensure failure cases are tested
|
|
831
|
+
|
|
832
|
+
### =� Low Priority
|
|
833
|
+
|
|
834
|
+
1. **Increase coverage on utility files** - Improve from 65% � 80%
|
|
835
|
+
2. **Add edge case tests** - Cover boundary conditions
|
|
836
|
+
3. **Consider snapshot tests** - For output formatting
|
|
837
|
+
|
|
838
|
+
---
|
|
839
|
+
|
|
840
|
+
## Testing Pyramid Reference
|
|
841
|
+
|
|
842
|
+
Per `docs/QA.md`, follow the testing pyramid:
|
|
843
|
+
|
|
844
|
+
- **Unit Tests (80%+ coverage target)** - Fast, isolated, mocked dependencies
|
|
845
|
+
- **Integration Tests (selective coverage)** - Real modules, mocked I/O
|
|
846
|
+
- **E2E Tests (manual validation)** - Real system, not measured in coverage
|
|
847
|
+
|
|
848
|
+
See [docs/QA.md](../QA.md) for full testing strategy.
|
|
849
|
+
|
|
850
|
+
---
|
|
851
|
+
|
|
852
|
+
## Next Steps
|
|
853
|
+
|
|
854
|
+
- [ ] Fix [X] new files (Tier 1 priority)
|
|
855
|
+
- [ ] Add tests to [X] high-impact files (Tier 2)
|
|
856
|
+
- [ ] Review and exclude [X] engine files (verify first)
|
|
857
|
+
- [ ] Run `/cover --compare` after changes to track progress
|
|
858
|
+
|
|
859
|
+
---
|
|
860
|
+
|
|
861
|
+
**Report Location:** `.cover.report.local.md`
|
|
862
|
+
**Rerun:** `/cover` or `/cover --compare`
|
|
863
|
+
**Exit Code:** [0 = pass | 1 = fail (if --strict)]
|
|
864
|
+
|
|
865
|
+
```text
|
|
866
|
+
|
|
867
|
+
### 5.1 Write Report to File
|
|
868
|
+
|
|
869
|
+
```bash
|
|
870
|
+
# Write generated report
|
|
871
|
+
echo "$REPORT_CONTENT" > .cover.report.local.md
|
|
872
|
+
|
|
873
|
+
# Add to gitignore if not already
|
|
874
|
+
if ! grep -q "^\.cover\.report\.local\.md$" .gitignore 2>/dev/null; then
|
|
875
|
+
echo ".cover.report.local.md" >> .gitignore
|
|
876
|
+
fi
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
## Phase 6: Cleanup Temporary Files
|
|
880
|
+
|
|
881
|
+
**CRITICAL**: Remove all temporary files created during coverage analysis process.
|
|
882
|
+
|
|
883
|
+
```bash
|
|
884
|
+
echo "🧹 Cleaning up temporary files..."
|
|
885
|
+
|
|
886
|
+
# Remove all temporary coverage files
|
|
887
|
+
rm -f .bun-coverage.txt
|
|
888
|
+
rm -f .coverage-files.tmp
|
|
889
|
+
rm -f .coverage-analysis.tmp
|
|
890
|
+
rm -f .coverage-excluded.tmp
|
|
891
|
+
rm -f .coverage-exclude-candidates.tmp
|
|
892
|
+
rm -f .coverage-architecture-issues.tmp
|
|
893
|
+
rm -f .coverage-low.tmp
|
|
894
|
+
|
|
895
|
+
# Verify cleanup
|
|
896
|
+
if ls .coverage*.tmp .bun-coverage.txt 1> /dev/null 2>&1; then
|
|
897
|
+
echo "⚠️ Warning: Some temporary files remain"
|
|
898
|
+
ls -la .coverage*.tmp .bun-coverage.txt 2>/dev/null || true
|
|
899
|
+
else
|
|
900
|
+
echo "✅ Temporary files cleaned up"
|
|
901
|
+
fi
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
**Files to remove:**
|
|
905
|
+
|
|
906
|
+
- `.bun-coverage.txt` - Raw coverage output from test runner
|
|
907
|
+
- `.coverage-files.tmp` - Parsed individual file coverage data
|
|
908
|
+
- `.coverage-analysis.tmp` - Categorized analysis results
|
|
909
|
+
- `.coverage-excluded.tmp` - Files excluded from analysis
|
|
910
|
+
- `.coverage-exclude-candidates.tmp` - Pure engine code candidates
|
|
911
|
+
- `.coverage-architecture-issues.tmp` - Files with mixed business/system logic
|
|
912
|
+
- `.coverage-low.tmp` - Files below coverage threshold
|
|
913
|
+
|
|
914
|
+
**Files to keep:**
|
|
915
|
+
|
|
916
|
+
- `.cover.report.local.md` - Final human-readable report (preserved for review)
|
|
917
|
+
|
|
918
|
+
**Why cleanup matters:**
|
|
919
|
+
|
|
920
|
+
- Prevents root folder clutter with temporary files
|
|
921
|
+
- Avoids confusion about which files are part of the codebase
|
|
922
|
+
- Prevents accidental commits of temporary analysis data
|
|
923
|
+
- Keeps workspace clean for next coverage execution
|
|
924
|
+
|
|
925
|
+
## Phase 7: Present Results (Plan Mode)
|
|
926
|
+
|
|
927
|
+
### 7.1 Console Summary
|
|
928
|
+
|
|
929
|
+
**Success case (coverage meets threshold):**
|
|
930
|
+
|
|
931
|
+
```bash
|
|
932
|
+
echo ""
|
|
933
|
+
echo " Coverage meets threshold"
|
|
934
|
+
echo ""
|
|
935
|
+
echo "=� Overall Coverage:"
|
|
936
|
+
echo " Functions: ${OVERALL_FUNCTIONS}% (threshold: ${THRESHOLD_FUNCTIONS}%)"
|
|
937
|
+
echo " Lines: ${OVERALL_LINES}% (threshold: ${THRESHOLD_LINES}%)"
|
|
938
|
+
echo ""
|
|
939
|
+
echo "=� Files analyzed: [count]"
|
|
940
|
+
echo " Meeting threshold: [count]"
|
|
941
|
+
echo " � Below threshold: [count]"
|
|
942
|
+
echo ""
|
|
943
|
+
if [ "$NEW_FILE_COUNT" -gt 0 ]; then
|
|
944
|
+
echo "<� Recommendation: Fix $NEW_FILE_COUNT new files first"
|
|
945
|
+
fi
|
|
946
|
+
echo ""
|
|
947
|
+
echo "=� Full report: .cover.report.local.md"
|
|
948
|
+
```text
|
|
949
|
+
|
|
950
|
+
**Failure case (coverage below threshold):**
|
|
951
|
+
|
|
952
|
+
```bash
|
|
953
|
+
echo ""
|
|
954
|
+
echo "L Coverage below threshold"
|
|
955
|
+
echo ""
|
|
956
|
+
echo "=� Overall Coverage:"
|
|
957
|
+
echo " Functions: ${OVERALL_FUNCTIONS}% (threshold: ${THRESHOLD_FUNCTIONS}%) L"
|
|
958
|
+
echo " Lines: ${OVERALL_LINES}% (threshold: ${THRESHOLD_LINES}%) L"
|
|
959
|
+
echo ""
|
|
960
|
+
echo "=4 Action Required:"
|
|
961
|
+
if [ "$NEW_FILE_COUNT" -gt 0 ]; then
|
|
962
|
+
echo " 1. Fix $NEW_FILE_COUNT new files without tests (Tier 1)"
|
|
963
|
+
fi
|
|
964
|
+
if [ "$HIGH_IMPACT_COUNT" -gt 0 ]; then
|
|
965
|
+
echo " 2. Add tests to $HIGH_IMPACT_COUNT high-impact files (Tier 2)"
|
|
966
|
+
fi
|
|
967
|
+
if [ "$ENGINE_COUNT" -gt 0 ]; then
|
|
968
|
+
echo " 3. Consider excluding $ENGINE_COUNT pure engine files (verify first)"
|
|
969
|
+
fi
|
|
970
|
+
echo ""
|
|
971
|
+
echo "=� Full report: .cover.report.local.md"
|
|
972
|
+
echo ""
|
|
973
|
+
```text
|
|
974
|
+
|
|
975
|
+
### 7.2 Plan Mode Presentation
|
|
976
|
+
|
|
977
|
+
**Present findings and recommendations without making changes:**
|
|
978
|
+
|
|
979
|
+
1. **Show overall status** - Pass/fail vs threshold
|
|
980
|
+
2. **Present prioritized action plan** - Tier 1 � Tier 2 � Tier 3
|
|
981
|
+
3. **Highlight exclusion candidates** - Engine code to review
|
|
982
|
+
4. **Link to testing pyramid** - Reference docs/QA.md strategy
|
|
983
|
+
|
|
984
|
+
**DO NOT:**
|
|
985
|
+
|
|
986
|
+
- Automatically add Istanbul ignore comments
|
|
987
|
+
- Modify package.json exclusions
|
|
988
|
+
- Create test files
|
|
989
|
+
- Make any code changes
|
|
990
|
+
|
|
991
|
+
**Operator decides:**
|
|
992
|
+
|
|
993
|
+
- Which files to test vs exclude
|
|
994
|
+
- Testing approach (unit vs integration)
|
|
995
|
+
- Coverage targets for specific modules
|
|
996
|
+
|
|
997
|
+
### 7.3 Exit Codes
|
|
998
|
+
|
|
999
|
+
```bash
|
|
1000
|
+
# Determine exit code
|
|
1001
|
+
if [[ "$ARGUMENTS" =~ --strict ]]; then
|
|
1002
|
+
if [ "$OVERALL_PASS" = "true" ]; then
|
|
1003
|
+
exit 0 # Coverage meets threshold
|
|
1004
|
+
else
|
|
1005
|
+
exit 1 # Coverage below threshold (strict mode)
|
|
1006
|
+
fi
|
|
1007
|
+
else
|
|
1008
|
+
exit 0 # Always succeed in non-strict mode (plan mode)
|
|
1009
|
+
fi
|
|
1010
|
+
```text
|
|
1011
|
+
|
|
1012
|
+
## Error Handling
|
|
1013
|
+
|
|
1014
|
+
**Important**: Always cleanup temporary files before exiting, even on error:
|
|
1015
|
+
|
|
1016
|
+
```bash
|
|
1017
|
+
# Trap for cleanup on exit (success or failure)
|
|
1018
|
+
cleanup_temp_files() {
|
|
1019
|
+
rm -f .bun-coverage.txt
|
|
1020
|
+
rm -f .coverage-files.tmp
|
|
1021
|
+
rm -f .coverage-analysis.tmp
|
|
1022
|
+
rm -f .coverage-excluded.tmp
|
|
1023
|
+
rm -f .coverage-exclude-candidates.tmp
|
|
1024
|
+
rm -f .coverage-architecture-issues.tmp
|
|
1025
|
+
rm -f .coverage-low.tmp
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
# Register cleanup on exit
|
|
1029
|
+
trap cleanup_temp_files EXIT
|
|
1030
|
+
|
|
1031
|
+
# Or manual cleanup before error exit
|
|
1032
|
+
if [ $ERROR_CONDITION ]; then
|
|
1033
|
+
cleanup_temp_files
|
|
1034
|
+
exit 1
|
|
1035
|
+
fi
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
**Error handling guidelines:**
|
|
1039
|
+
|
|
1040
|
+
- **Cleanup fails**: Log warning but don't fail the command
|
|
1041
|
+
- **Coverage run fails**: Cleanup temps before exit
|
|
1042
|
+
- **Invalid pattern**: Warn but continue with analysis
|
|
1043
|
+
- **Git unavailable**: Error if --diff used, suggest alternative
|
|
1044
|
+
|
|
1045
|
+
### Coverage Run Failed
|
|
1046
|
+
|
|
1047
|
+
```bash
|
|
1048
|
+
if ! task test:coverage $SCOPE 2>&1 | tee .bun-coverage.txt; then
|
|
1049
|
+
echo "L Error: Coverage run failed"
|
|
1050
|
+
echo " Check test errors above"
|
|
1051
|
+
echo " Fix failing tests before analyzing coverage"
|
|
1052
|
+
exit 1
|
|
1053
|
+
fi
|
|
1054
|
+
```text
|
|
1055
|
+
|
|
1056
|
+
### No Coverage Data
|
|
1057
|
+
|
|
1058
|
+
```bash
|
|
1059
|
+
if [ ! -s .bun-coverage.txt ]; then
|
|
1060
|
+
echo "L Error: No coverage data generated"
|
|
1061
|
+
echo " Ensure tests ran successfully"
|
|
1062
|
+
echo " Try: task test:coverage"
|
|
1063
|
+
exit 1
|
|
1064
|
+
fi
|
|
1065
|
+
```text
|
|
1066
|
+
|
|
1067
|
+
### Invalid Scope
|
|
1068
|
+
|
|
1069
|
+
```bash
|
|
1070
|
+
if [[ "$SCOPE" == --files=* ]]; then
|
|
1071
|
+
PATTERN="${SCOPE#--files=}"
|
|
1072
|
+
FILE_COUNT=$(ls $PATTERN 2>/dev/null | wc -l)
|
|
1073
|
+
if [ "$FILE_COUNT" -eq 0 ]; then
|
|
1074
|
+
echo "� Warning: No files match pattern: $PATTERN"
|
|
1075
|
+
echo " Continuing with empty coverage..."
|
|
1076
|
+
fi
|
|
1077
|
+
fi
|
|
1078
|
+
```text
|
|
1079
|
+
|
|
1080
|
+
### Git Not Available (--diff mode)
|
|
1081
|
+
|
|
1082
|
+
```bash
|
|
1083
|
+
if [[ "$SCOPE" == "--diff" ]]; then
|
|
1084
|
+
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
1085
|
+
echo "L Error: --diff requires git repository"
|
|
1086
|
+
echo " Use glob pattern instead: /cover 'src/**/*.ts'"
|
|
1087
|
+
exit 1
|
|
1088
|
+
fi
|
|
1089
|
+
fi
|
|
1090
|
+
```text
|
|
1091
|
+
|
|
1092
|
+
## Phase 8: Usage Examples
|
|
1093
|
+
|
|
1094
|
+
```bash
|
|
1095
|
+
# Analyze all files
|
|
1096
|
+
/cover
|
|
1097
|
+
|
|
1098
|
+
# Analyze specific pattern
|
|
1099
|
+
/cover 'src/cli/**/*.ts'
|
|
1100
|
+
|
|
1101
|
+
# Analyze staged files only
|
|
1102
|
+
/cover --diff
|
|
1103
|
+
|
|
1104
|
+
# Strict mode (fail if below threshold)
|
|
1105
|
+
/cover --strict
|
|
1106
|
+
|
|
1107
|
+
# Compare with previous analysis
|
|
1108
|
+
/cover --compare
|
|
1109
|
+
|
|
1110
|
+
# Combination
|
|
1111
|
+
/cover 'src/state/**/*.ts' --strict --compare
|
|
1112
|
+
```
|
|
1113
|
+
|
|
1114
|
+
## Phase 9: Integration with Workflow
|
|
1115
|
+
|
|
1116
|
+
### After AI Code Generation
|
|
1117
|
+
|
|
1118
|
+
```bash
|
|
1119
|
+
# AI generated new files
|
|
1120
|
+
/cover --diff
|
|
1121
|
+
|
|
1122
|
+
# Review new files in report
|
|
1123
|
+
# Add tests to new files
|
|
1124
|
+
# Rerun to verify
|
|
1125
|
+
/cover --diff --compare
|
|
1126
|
+
```text
|
|
1127
|
+
|
|
1128
|
+
### Before Pull Request
|
|
1129
|
+
|
|
1130
|
+
```bash
|
|
1131
|
+
# Check overall coverage
|
|
1132
|
+
/cover --strict
|
|
1133
|
+
|
|
1134
|
+
# If fails, review report priorities
|
|
1135
|
+
# Fix Tier 1 and Tier 2 files
|
|
1136
|
+
# Verify coverage passes
|
|
1137
|
+
/cover --strict
|
|
1138
|
+
```text
|
|
1139
|
+
|
|
1140
|
+
### Regular Development
|
|
1141
|
+
|
|
1142
|
+
```bash
|
|
1143
|
+
# Quick check on working files
|
|
1144
|
+
/cover 'src/module/**/*.ts'
|
|
1145
|
+
|
|
1146
|
+
# Review recommendations
|
|
1147
|
+
# Add tests incrementally
|
|
1148
|
+
# Track progress with --compare
|
|
1149
|
+
```
|
|
1150
|
+
|
|
1151
|
+
### Architecture-First Workflow (Recommended)
|
|
1152
|
+
|
|
1153
|
+
When coverage issues stem from architectural problems, use `/architect:clean` before adding tests:
|
|
1154
|
+
|
|
1155
|
+
```bash
|
|
1156
|
+
# Step 1: Identify coverage issues
|
|
1157
|
+
/cover --diff
|
|
1158
|
+
|
|
1159
|
+
# Step 2: Review .cover.report.local.md
|
|
1160
|
+
# Look for "Priority: Architecture Issues ⚠️" section
|
|
1161
|
+
|
|
1162
|
+
# Step 3: Refactor files with mixed logic
|
|
1163
|
+
/architect:clean src/utils/auth.ts
|
|
1164
|
+
|
|
1165
|
+
# Step 4: Review proposed refactorings in .clean.local.md
|
|
1166
|
+
# Accept changes from worktree if satisfactory
|
|
1167
|
+
|
|
1168
|
+
# Step 5: Run coverage again to verify improvement
|
|
1169
|
+
/cover --diff --compare
|
|
1170
|
+
|
|
1171
|
+
# Step 6: Add unit tests for refactored business logic
|
|
1172
|
+
# Tests now use mocks instead of real system calls
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
**Why this workflow works:**
|
|
1176
|
+
|
|
1177
|
+
1. **Before refactoring**: Business logic mixed with system calls → Cannot test without real LDAP/file system/network
|
|
1178
|
+
2. **After refactoring**: Business logic separated with DI → Can test with mocks
|
|
1179
|
+
3. **Coverage impact**: System files excluded (*.system.ts), business logic included and testable
|
|
1180
|
+
|
|
1181
|
+
**Example:**
|
|
1182
|
+
|
|
1183
|
+
```bash
|
|
1184
|
+
# Initial state: auth.ts has 35% coverage (mixed LDAP and validation)
|
|
1185
|
+
/cover src/utils/
|
|
1186
|
+
|
|
1187
|
+
# Report shows: "Priority: Architecture Issues - src/utils/auth.ts"
|
|
1188
|
+
# Recommendation: Use /architect:clean instead of excluding from coverage
|
|
1189
|
+
|
|
1190
|
+
# Refactor for testability
|
|
1191
|
+
/architect:clean src/utils/auth.ts
|
|
1192
|
+
|
|
1193
|
+
# Result:
|
|
1194
|
+
# - ldap-interface.ts (interface definition)
|
|
1195
|
+
# - ldap.system.ts (LDAP calls, excluded from coverage)
|
|
1196
|
+
# - auth.ts (business logic with DI, now testable)
|
|
1197
|
+
# - tests/mocks/ldap-mock.ts (mock for unit tests)
|
|
1198
|
+
|
|
1199
|
+
# Add unit tests using mocks
|
|
1200
|
+
# auth.ts coverage: 35% → 90%
|
|
1201
|
+
# Overall coverage: Improved (system file excluded, business logic tested)
|
|
1202
|
+
|
|
1203
|
+
# Verify improvement
|
|
1204
|
+
/cover src/utils/ --compare
|
|
1205
|
+
```
|
|
1206
|
+
|
|
1207
|
+
**See also:**
|
|
1208
|
+
|
|
1209
|
+
- [Clean Architecture Guide](../guides/agents.clean.arch.md) - Principles and patterns
|
|
1210
|
+
- [/architect:clean Command](./architect/clean.md) - Automated refactoring
|
|
1211
|
+
- [Clean Architecture in TypeScript](../guides/agents.clean.arch.ts.md) - Language-specific guide
|
|
1212
|
+
|
|
1213
|
+
## Quick Reference
|
|
1214
|
+
|
|
1215
|
+
**Common workflows:**
|
|
1216
|
+
|
|
1217
|
+
```bash
|
|
1218
|
+
# Analyze all files
|
|
1219
|
+
/cover
|
|
1220
|
+
|
|
1221
|
+
# Analyze specific pattern
|
|
1222
|
+
/cover 'src/cli/**/*.ts'
|
|
1223
|
+
|
|
1224
|
+
# Check staged files
|
|
1225
|
+
/cover --diff
|
|
1226
|
+
|
|
1227
|
+
# Strict mode (fail if below threshold)
|
|
1228
|
+
/cover --strict
|
|
1229
|
+
|
|
1230
|
+
# Track progress over time
|
|
1231
|
+
/cover --compare
|
|
1232
|
+
```
|
|
1233
|
+
|
|
1234
|
+
**Coverage data workflow (performance optimized):**
|
|
1235
|
+
|
|
1236
|
+
1. **Fast path**: Use `task test:coverage:report` if available and coverage is fresh (< 5 minutes)
|
|
1237
|
+
2. **Regenerate**: Run `task test:coverage` if coverage is stale or missing
|
|
1238
|
+
3. **Fallback**: Detect test framework (Bun, Jest, Vitest) if no Taskfile tasks available
|
|
1239
|
+
4. **Analyze**: Parse lcov.info and junit.xml files directly for comprehensive analysis
|
|
1240
|
+
|
|
1241
|
+
**Coverage file locations checked:**
|
|
1242
|
+
|
|
1243
|
+
- `coverage/lcov.info` (standard)
|
|
1244
|
+
- `coverage/coverage-final.json` (JSON format)
|
|
1245
|
+
- `.coverage/lcov.info` (alternative)
|
|
1246
|
+
- `lcov.info` (root)
|
|
1247
|
+
|
|
1248
|
+
**JUnit file locations checked:**
|
|
1249
|
+
|
|
1250
|
+
- `test-results/junit.xml` (standard)
|
|
1251
|
+
- `junit.xml` (root)
|
|
1252
|
+
- `coverage/junit.xml` (with coverage)
|
|
1253
|
+
- `.test-results/junit.xml` (alternative)
|
|
1254
|
+
|
|
1255
|
+
**Temporary files created:**
|
|
1256
|
+
|
|
1257
|
+
- `.bun-coverage.txt` - Raw coverage output (if test run needed)
|
|
1258
|
+
- `.coverage-files.tmp` - Parsed file coverage data from lcov
|
|
1259
|
+
- `.coverage-analysis.tmp` - Analysis results by tier
|
|
1260
|
+
- `.coverage-excluded.tmp` - Excluded files list
|
|
1261
|
+
- `.coverage-exclude-candidates.tmp` - Pure engine code candidates
|
|
1262
|
+
- `.coverage-architecture-issues.tmp` - Files with mixed business/system logic
|
|
1263
|
+
- `.coverage-low.tmp` - Files below threshold
|
|
1264
|
+
|
|
1265
|
+
**CRITICAL**: Always cleanup temporary files after completion (see Phase 6)
|
|
1266
|
+
|
|
1267
|
+
**Priority tiers:**
|
|
1268
|
+
|
|
1269
|
+
1. **Tier 1 (Fix First)** - New files without tests
|
|
1270
|
+
2. **Tier 2 (High Impact)** - Core functionality below threshold
|
|
1271
|
+
3. **Architecture Issues** - Files with mixed business/system logic (use `/architect:clean`)
|
|
1272
|
+
4. **Tier 3 (Low Priority)** - Other files below threshold
|
|
1273
|
+
5. **Exclusion Candidates** - Pure engine code (verify before excluding)
|
|
1274
|
+
|
|
1275
|
+
**Execution order:**
|
|
1276
|
+
|
|
1277
|
+
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
|
|
1278
|
+
|
|
1279
|
+
**Report location:** `.cover.report.local.md`
|
|
1280
|
+
|
|
1281
|
+
**Exit codes:**
|
|
1282
|
+
- 0: Pass (or non-strict mode)
|
|
1283
|
+
- 1: Fail (strict mode with coverage below threshold)
|
|
1284
|
+
|
|
1285
|
+
**Performance benefits:**
|
|
1286
|
+
|
|
1287
|
+
- ✅ Uses existing coverage when fresh (no test execution overhead)
|
|
1288
|
+
- ✅ Detects test framework automatically (works without Taskfile)
|
|
1289
|
+
- ✅ Parses lcov directly (more reliable than text parsing)
|
|
1290
|
+
- ✅ Includes test results from junit.xml (comprehensive analysis)
|
|
1291
|
+
|
|
1292
|
+
**Integration with Clean Architecture:**
|
|
1293
|
+
|
|
1294
|
+
- For files with architectural issues, use `/architect:clean` to refactor before testing
|
|
1295
|
+
- System files (*.system.ts) excluded from coverage, business logic becomes testable
|
|
1296
|
+
- Improves coverage by separating concerns instead of excluding business logic
|
|
1297
|
+
- See [Clean Architecture Guide](../guides/agents.clean.arch.md) for principles
|
|
1298
|
+
````
|