Coco Blame
coco blame <file> runs git blame and optionally asks an LLM to explain why each blamed range was introduced.
Basic Usage
bash
1# Standard blame output (no AI, no API key needed)
2coco blame src/index.ts
3
4# Blame a specific line range
5coco blame src/index.ts --lines 10:50
6
7# Ask the LLM to explain the introducing commits
8coco blame src/index.ts --lines 10:50 --explain
9
10# JSON output
11coco blame src/index.ts --explain --jsonOptions
| Flag | Default | Description |
|---|---|---|
<file> (positional) | required | Repo-relative path to the file to blame |
--lines <range> | entire file | Limit to a 1-based inclusive line range: "10:20", "10:" (open-ended), or "10" (single line) |
--explain | false | Send the blamed commits to the LLM for a natural-language explanation of why each range was introduced |
--json | false | Emit machine-readable JSON output |
Plain Blame (no --explain)
Without --explain, coco blame prints a formatted table of blame annotations (commit hash, author, date, line number, content). This mode requires no API key and makes no network calls beyond git blame itself.
AI-Powered Explanation (--explain)
With --explain, coco:
- Groups the blamed lines by introducing commit hash.
- Fetches the full commit detail (message, diff stats) for each unique commit.
- Sends the grouped context to the configured LLM and asks it to explain, per commit, why those lines were written.
- Prints both the blame table and the per-commit explanations.
Cost Guardrails
To prevent runaway cost on large files:
- Line cap:
--explainis limited to 400 lines. Narrow the range with--linesif you exceed this. - Commit cap: At most 25 unique commits are explained per invocation. If the range touches more, the oldest are truncated with a note.
- Uncommitted/staged lines (the all-zero sha) are always excluded from explanation.
Example Output
$ coco blame src/lib/config/types.ts --lines 1:30 --explain
Hash Author Date Line Content
a1b2c3d gfargo 2026-03-12 1 import { ... }
a1b2c3d gfargo 2026-03-12 2 ...
f4e5d6c contributor 2026-05-01 15 export type LLMProvider = ...
...
Explanations:
a1b2c3d (gfargo, 2026-03-12)
Initial module scaffold — established the config type hierarchy and
provider union for the langchain integration layer.
f4e5d6c (contributor, 2026-05-01)
Added the OpenAI-compatible provider presets (deepseek, groq, xai, etc.)
to the LLMProvider union, extending the type system to cover the new
first-class provider category.
JSON Output
With --json, the output is a structured object:
json
1{
2 "path": "src/lib/config/types.ts",
3 "lines": [ ... ],
4 "explanations": [
5 {
6 "hash": "a1b2c3d...",
7 "shortHash": "a1b2c3d",
8 "author": "gfargo",
9 "lines": "1-14",
10 "subject": "feat: initial config type scaffold",
11 "explanation": "Established the config type hierarchy..."
12 }
13 ]
14}See Also
- Command Reference
- Dynamic Model Routing —
blameExplainis a routable task when usingservice.model: "dynamic"