This commit is contained in:
2026-04-12 01:06:31 +07:00
commit 10d660cbcb
1066 changed files with 228596 additions and 0 deletions

View File

@@ -0,0 +1,138 @@
---
name: ck:retro
description: "Data-driven sprint retrospective. Gathers git metrics (commits, LOC, hotspots, churn), computes derived health indicators, and generates a structured markdown or HTML report. Use after sprints, weekly check-ins, or any review period."
license: MIT
argument-hint: "[timeframe] [--compare] [--team] [--format html|md]"
metadata:
author: claudekit
version: "1.0.0"
---
# Retro Skill
You are a data-driven Engineering Retrospective Analyst. Your job is to collect objective git metrics, compute health indicators, and produce an actionable retrospective report — no guesswork, no invented data.
## Flags
| Flag | Default | Description |
|------|---------|-------------|
| `timeframe` | `7d` | Period to analyze. Accepts: `7d`, `2w`, `1m`, `sprint`, or `YYYY-MM-DD:YYYY-MM-DD` |
| `--compare` | off | Compare metrics against the preceding equal-length period |
| `--team` | off | Break down metrics per author |
| `--format html\|md` | `md` | Output format. `html` generates a self-contained HTML report |
## Step 1 — Parse Timeframe
Resolve `timeframe` argument to a `--since` date for git commands:
- `7d` → 7 days ago
- `2w` → 14 days ago
- `1m` → 1 month ago
- `sprint` → ask user for sprint start date if not inferable from git tags
- `YYYY-MM-DD:YYYY-MM-DD` → use `--since` / `--until` pair
Store resolved dates as `SINCE` and `UNTIL` (default UNTIL = now).
If `--compare` flag is set, also resolve the preceding period of equal length as `PREV_SINCE` / `PREV_UNTIL`.
## Step 2 — Gather Raw Git Metrics
Run each bash command. Capture output. If a command returns empty, record `0` or `N/A` — never fabricate values.
```bash
# Commits per day
git log --since="$SINCE" --until="$UNTIL" --format="%ai" \
| cut -d' ' -f1 | sort | uniq -c
# Total commits
git log --since="$SINCE" --until="$UNTIL" --oneline | wc -l
# LOC added / removed / net
git log --since="$SINCE" --until="$UNTIL" --numstat --format="" \
| awk 'NF==3 {add+=$1; del+=$2} END {print "added="add, "removed="del, "net="add-del}'
# File hotspots (top 10 most-changed files)
git log --since="$SINCE" --until="$UNTIL" --name-only --format="" \
| sort | uniq -c | sort -rn | head -10
# Commit type distribution (conventional commits)
git log --since="$SINCE" --until="$UNTIL" --format="%s" \
| sed 's/(.*//' | sed 's/:.*//' | sort | uniq -c | sort -rn
# Active authors
git log --since="$SINCE" --until="$UNTIL" --format="%ae" \
| sort -u
# Per-author commit count (used when --team flag set)
git log --since="$SINCE" --until="$UNTIL" --format="%ae" \
| sort | uniq -c | sort -rn
# Days with activity
git log --since="$SINCE" --until="$UNTIL" --format="%ai" \
| cut -d' ' -f1 | sort -u | wc -l
# Files changed (unique)
git log --since="$SINCE" --until="$UNTIL" --name-only --format="" \
| sort -u | grep -c .
# Test file changes
git log --since="$SINCE" --until="$UNTIL" --name-only --format="" \
| grep -E "(\.test\.|\.spec\.|__tests__|test_)" | wc -l
# Total file changes (for test ratio)
git log --since="$SINCE" --until="$UNTIL" --name-only --format="" \
| grep -v "^$" | wc -l
```
## Step 3 — Compute Derived Metrics
Compute from raw data. Show formula in report.
| Metric | Formula |
|--------|---------|
| Commit frequency | `total_commits / days_in_period` |
| Test-to-code ratio | `test_file_changes / total_file_changes * 100` |
| Churn rate | `(LOC_added + LOC_removed) / max(LOC_net, 1)` |
| Active day ratio | `days_with_commits / days_in_period * 100` |
| Plan completion rate | Count closed GitHub issues in period (use `gh issue list --state closed --json closedAt,title --jq "[.[] | select(.closedAt >= \"$SINCE\")]"`) divided by opened; mark `N/A` if gh unavailable |
## Step 4 — Check Plans Directory
Scan `plans/` for any plan files updated in the period. Count completed vs total tasks from checkbox lists (`- [x]` vs `- [ ]`). Add to plan completion section.
```bash
# Create sentinel file with the period start timestamp (macOS/BSD date syntax)
touch -t $(date -jf "%Y-%m-%d" "$SINCE" +%Y%m%d%H%M.%S 2>/dev/null || date -d "$SINCE" +%Y%m%d%H%M.%S) /tmp/retro-since-sentinel
# Find plan files modified in period
find plans/ -name "*.md" -newer /tmp/retro-since-sentinel 2>/dev/null | head -20
```
## Step 5 — Generate Report
Use the template from `references/report-template.md`.
- Fill all table cells with real data
- Mark cells `N/A` when data unavailable — never invent numbers
- Add 3-5 specific Recommendations based on actual findings (e.g., high churn on specific files, low test ratio, uneven commit distribution)
- Highlights: note standout positive metrics
- If `--compare` flag set: add delta column (`+/-`) to Velocity and Code Health tables
Output location: `plans/reports/retro-{YYMMDD}-{slug}.md`
Where `YYMMDD` = today's date from `bash -c 'date +%y%m%d'` and `slug` = timeframe (e.g., `7d`, `1m`, `sprint`).
## Step 6 — HTML Format (optional)
If `--format html` flag is set:
- Wrap report in a self-contained HTML page
- Use inline CSS for table styling (no external deps)
- Save as `plans/reports/retro-{YYMMDD}-{slug}.html`
- Output `[OK] Report saved: plans/reports/retro-{YYMMDD}-{slug}.html`
## Constraints
- Read-only — never commit, push, or modify any source files
- All metrics sourced from git history only (plus optional gh CLI for issues)
- Do not hallucinate metrics; `N/A` is always correct when data is missing
- Keep report under 200 lines; split into multiple files if needed

View File

@@ -0,0 +1,133 @@
# Metrics Reference Guide
Each metric: what it measures, why it matters, interpretation guidance, and the git command to compute it.
---
## Velocity Metrics
### Commits Per Day
**Measures:** Delivery cadence — how often work lands in the repo.
**Why it matters:** Low frequency may indicate large batched PRs (risky merges); high frequency with tiny commits suggests good trunk-based dev hygiene.
**Interpretation:**
- `< 1/day` — infrequent; check for blocked PRs or slow review cycles
- `1-3/day` — healthy for a solo dev or small team
- `> 5/day` — high activity; verify commits are meaningful, not noise
```bash
git log --since="$SINCE" --until="$UNTIL" --format="%ai" \
| cut -d' ' -f1 | sort | uniq -c
```
### Active Day Ratio
**Measures:** What fraction of working days had at least one commit.
**Why it matters:** Consistent daily progress vs burst-then-idle patterns.
**Interpretation:** `> 70%` = consistent; `< 40%` = batchy; investigate blockers.
```bash
# Days with activity
git log --since="$SINCE" --until="$UNTIL" --format="%ai" \
| cut -d' ' -f1 | sort -u | wc -l
# Divide by total calendar days in period
```
---
## Code Health Metrics
### LOC Added / Removed / Net
**Measures:** Raw volume of code written and deleted.
**Why it matters:** Net negative LOC (more deleted than added) is often a sign of healthy refactoring. Very high churn on specific files is a risk signal.
**Interpretation:**
- Net negative on non-test files = good (simplification)
- Net positive > 500 LOC/day sustained = high velocity, watch for quality regression
```bash
git log --since="$SINCE" --until="$UNTIL" --numstat --format="" \
| awk 'NF==3 {add+=$1; del+=$2} END {print "added="add, "removed="del, "net="add-del}'
```
### File Hotspots
**Measures:** Which files change most frequently.
**Why it matters:** High-churn files are coupling magnets and defect attractors. Files appearing in > 30% of commits warrant refactoring.
**Interpretation:** Top 3 hotspots in every sprint signal architectural debt.
```bash
git log --since="$SINCE" --until="$UNTIL" --name-only --format="" \
| sort | uniq -c | sort -rn | head -10
```
### Churn Rate
**Measures:** `(LOC_added + LOC_removed) / max(LOC_net, 1)` — how much code was rewritten vs kept.
**Why it matters:** Churn > 3x net LOC = significant rework; investigate root cause (unclear requirements, unstable APIs, poor initial design).
**Interpretation:**
- `1.0 - 1.5` = clean, additive work
- `1.5 - 3.0` = moderate iteration (normal)
- `> 3.0` = high rework; flag for retro discussion
---
## Quality Metrics
### Test-to-Code Ratio
**Measures:** `test_file_changes / total_file_changes * 100`
**Why it matters:** Proxy for whether tests accompany new code. Does not measure test quality, only presence.
**Interpretation:**
- `> 30%` = tests accompanying changes (healthy)
- `10-30%` = some test coverage added
- `< 10%` = tests lagging behind; technical debt accumulating
```bash
# Test file changes
git log --since="$SINCE" --until="$UNTIL" --name-only --format="" \
| grep -E "(\.test\.|\.spec\.|__tests__|test_)" | wc -l
# Total file changes
git log --since="$SINCE" --until="$UNTIL" --name-only --format="" \
| grep -v "^$" | wc -l
```
### Commit Type Distribution
**Measures:** Breakdown of conventional commit types (`feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `hotfix`).
**Why it matters:** Ratio reveals focus. Heavy `fix` ratio may indicate quality issues; heavy `chore` may mean infra debt; balanced mix = sustainable pace.
**Interpretation:**
- `feat > 40%` = feature-driven sprint
- `fix > 40%` = reactive sprint (bugs dominating)
- `refactor > 20%` = healthy investment in code quality
```bash
git log --since="$SINCE" --until="$UNTIL" --format="%s" \
| sed 's/(.*//' | sed 's/:.*//' | sort | uniq -c | sort -rn
```
---
## Plan Metrics
### Plan Completion Rate
**Measures:** Closed GitHub issues / total issues opened in period (or checkbox ratio in plan files).
**Why it matters:** Tracks delivery predictability. Consistent undercompletion signals scope inflation or estimation issues.
**Interpretation:**
- `> 80%` = on track
- `60-80%` = acceptable; review blockers
- `< 60%` = scope or capacity mismatch; action needed
```bash
# Requires gh CLI
gh issue list --state closed --json closedAt,createdAt \
--jq "[.[] | select(.closedAt >= \"$SINCE\")] | length"
```
```bash
# Plan file checkbox scan (fallback)
grep -r "\- \[x\]" plans/ | wc -l # completed
grep -r "\- \[ \]" plans/ | wc -l # open
```

View File

@@ -0,0 +1,110 @@
# Retrospective Report — {TIMEFRAME}
**Period:** {SINCE} → {UNTIL}
**Generated:** {TODAY}
**Repo:** {REPO_NAME}
**Authors:** {AUTHOR_COUNT} active
---
## Velocity
| Metric | Value | {COMPARE_COL} |
|--------|-------|---------------|
| Total commits | {TOTAL_COMMITS} | {DELTA_COMMITS} |
| Commits / day | {COMMITS_PER_DAY} | {DELTA_COMMITS_DAY} |
| Active days | {ACTIVE_DAYS} / {PERIOD_DAYS} ({ACTIVE_PCT}%) | {DELTA_ACTIVE} |
| Files changed | {FILES_CHANGED} | {DELTA_FILES} |
*Remove delta column if `--compare` not set.*
---
## Code Health
| Metric | Value | {COMPARE_COL} |
|--------|-------|---------------|
| LOC added | {LOC_ADDED} | {DELTA_LOC_ADDED} |
| LOC removed | {LOC_REMOVED} | {DELTA_LOC_REMOVED} |
| Net LOC | {LOC_NET} | {DELTA_LOC_NET} |
| Churn rate | {CHURN_RATE}x | {DELTA_CHURN} |
| Test-to-code ratio | {TEST_RATIO}% | {DELTA_TEST_RATIO} |
*Remove delta column if `--compare` not set.*
---
## Commit Distribution
```
{COMMIT_TYPE_BAR_OR_TABLE}
```
Example format:
```
feat ████████████ 12 (40%)
fix ████████ 8 (27%)
chore ████ 4 (13%)
refactor ███ 3 (10%)
test ██ 2 (7%)
docs █ 1 (3%)
```
---
## File Hotspots
Top files by change frequency:
| Rank | File | Changes |
|------|------|---------|
| 1 | {FILE_1} | {COUNT_1} |
| 2 | {FILE_2} | {COUNT_2} |
| 3 | {FILE_3} | {COUNT_3} |
| ... | ... | ... |
---
## Plan Progress
| Metric | Value |
|--------|-------|
| Completed tasks | {TASKS_DONE} |
| Open tasks | {TASKS_OPEN} |
| Completion rate | {PLAN_PCT}% |
| Issues closed (period) | {ISSUES_CLOSED} |
---
## Team Breakdown
*Include only when `--team` flag is set. Otherwise omit this section.*
| Author | Commits | LOC Net | Types |
|--------|---------|---------|-------|
| {AUTHOR_1} | {COMMITS_1} | {LOC_1} | {TYPES_1} |
| {AUTHOR_2} | {COMMITS_2} | {LOC_2} | {TYPES_2} |
---
## Highlights
- [OK] {POSITIVE_FINDING_1}
- [OK] {POSITIVE_FINDING_2}
- [!] {NOTABLE_FINDING}
*Replace with 2-4 factual observations from the data. No invented praise.*
---
## Recommendations
1. **{ACTION_1}** — {RATIONALE_1} (based on {METRIC})
2. **{ACTION_2}** — {RATIONALE_2} (based on {METRIC})
3. **{ACTION_3}** — {RATIONALE_3} (based on {METRIC})
*3-5 specific, actionable items grounded in the metrics above. No generic advice.*
---
*Generated by `ck:retro` — data sourced from git history only*