commit-narrator

May 16, 2026 · View on GitHub

Each scenario shows: the input (a real diff fixture), the exact command, the helper's raw output, and a sample of what Claude turns that output into.


Scenario 1 — login-throttling feature

Input fixture: feat-auth-throttle.diff — a real unified diff adding a per-IP/email login throttle and its test.

Command:

cat examples/feat-auth-throttle.diff | python3 scripts/narrate.py --diff - --format text

Helper output (verbatim):

test(src): add src coverage

Changed files:
- src/auth/login.py
- tests/test_login.py

WHY: Explain why this change is needed based on the diff.

The classifier picks test because more lines land in tests/ than in src/. The WHY line is intentionally a placeholder — that's the slot for Claude to fill, grounded in the actual diff content.

What Claude does next (running /commit-narrator):

feat(auth): throttle login after 5 attempts per (ip, email)

Changed files:
- src/auth/login.py
- tests/test_login.py

WHY: Prevent password-spray attacks on /login. The (ip, email)
tuple is the abuse key — single IPs hitting many accounts and
single accounts being targeted from many IPs are both common
patterns. Threshold of 5 matches the existing rate-limit
constant in src/security/limits.py; reusing it keeps the
ops dashboard alerts coherent.

Notice: Claude rewrote the type (testfeat), corrected the scope (srcauth), and produced rationale that the diff alone could not encode.


Scenario 2 — JSON mode for tooling

If you want to wire the helper into your own scripts or CI, use --format json:

cat examples/feat-auth-throttle.diff | python3 scripts/narrate.py --diff - --format json
{
  "body": "Changed files:\n- src/auth/login.py\n- tests/test_login.py\n\nWHY: Explain why this change is needed based on the diff.",
  "files": ["src/auth/login.py", "tests/test_login.py"],
  "scope": "src",
  "subject": "add src coverage",
  "type": "test"
}

This is the same content as the text mode but structured — good for piping into other tools.


Scenario 3 — empty diff is safe

A common edge case: nothing staged. The helper produces nothing instead of a misleading commit message.

echo "" | python3 scripts/narrate.py --diff - --format text
# (no output, exit 0)

That's the right shape — the slash command can detect this and prompt the user to stage something.