Claude Code built it. Do you understand what it actually changed?
Claude Code can build a feature, fix a bug, and edit a dozen files in a single session. If you don't read code, it's still hard to tell what really happened in there.
Run /dev-report and Claude explains the session in plain language: what it did, why it did it that way, what's still unfinished, and what you should do next.
It makes the session easy to follow without dropping the reasoning you need to decide what happens next.
한국어 README · Install · See the difference · Worked examples
Two commands, typed inside Claude Code:
/plugin marketplace add delpicorp/dev-report
/plugin install dev-report@delpicorp
That's it — no terminal, no file copying. /dev-report and three localized aliases install together, and /plugin update dev-report keeps you current. The skill adds about 380 tokens of always-on context.
Note
Installing as a plugin needs Claude Code v2.1.142 or later. On an older version, use the manual install below.
Manual install (git clone) — no plugin system involved
macOS / Linux:
git clone https://github.com/delpicorp/dev-report.git ~/.claude/skills/dev-report
cp ~/.claude/skills/dev-report/commands/dev-report.md ~/.claude/commands/Windows (PowerShell):
git clone https://github.com/delpicorp/dev-report.git "$HOME\.claude\skills\dev-report"
Copy-Item "$HOME\.claude\skills\dev-report\commands\dev-report.md" "$HOME\.claude\commands\"Restart Claude Code, then type /dev-report. Localized aliases are opt-in here — copy the ones you want out of commands/localized/.
To install for a single project instead of globally, use .claude/skills/ and .claude/commands/ inside that project.
At the end of a session, type:
/dev-report
Anything you add after the command tells it what to cover, and it wins over the skill's own defaults:
/dev-report this week
/dev-report just the payment work
/dev-report keep it short, she only has a minute
- nothing — the session you just had
- a time range — that period, checking git as well as the conversation
- a topic — only that thread of work
- a length or tone hint — including "keep it short"
Note
The skill only runs when you ask for it. It won't hijack a casual "what did you just do?" — that question wants a two-line answer, and handing back a formal report instead is its own kind of failure.
Ask Claude "what did we do today?" and you get a competent engineering summary — file names, function names, a change list. It's accurate, and it's written for someone who reads code. Ask for it "simply" instead and the reasoning goes out with the jargon, leaving a short paragraph you still can't act on.
Here's the same session both ways. It started as routine maintenance and turned into a bug hunt.
A normal summary:
Fixed a missing event handler for
payment.succeeded.v2in the notification service. Registered both event names and backfilled the 47 dropped confirmation emails.
How the dev-report version opens:
Today was supposed to be clearing four small items off the backlog. I got through two of them, then found that about one in six customers hasn't been receiving their order confirmation email since the payment provider upgrade three weeks ago. That's fixed and live now. The other two backlog items are untouched.
Both are true. Only one tells you what happened to your product. And it doesn't stop there — the report goes on to quote the log line that gave the bug away, explain why it hid for three weeks, and say which cleaner-looking fix was turned down and why.
Excerpt from a worked example that ships with the skill.
Four things, every time:
- What Claude built or changed — described in terms of your product, not your file tree
- Why it chose that approach — including the option it considered and turned down, and what would have gone wrong
- What's still unfinished or unverified — what was actually tested, what's only assumed, what was never checked
- What you should do next — including the calls only you can make, stated clearly enough to answer in a sentence
Technical terms aren't removed — they're explained the moment they first appear. So the report stays readable without becoming vague, and you can still repeat what it says to someone else.
People building with Claude Code. Non-developer vibe coders, indie hackers, solo founders — and PMs, team leads, or founders when they're the one personally prompting the feature into existence. You don't need another list of changed files. You need to know what changed, why it was done that way, what's still shaky, and what to do next.
Developers who have to explain the session to someone who doesn't read code. A founder, a client, a PM. dev-report keeps the technical substance — the mechanism, the tradeoff, the option you rejected — and turns it into something the reader can act on instead of nod at.
A normal summary lists the changes. dev-report explains the decisions behind them.
How this differs from changelog generators, release-note kits, and "explain it simply"
| Direction | Optimized for | |
|---|---|---|
| Changelog generators (e.g. changelog-generator) | commits → release notes | format conversion; the reasoning behind the changes isn't carried along |
| Release-note kits (e.g. release-kit) | team → end users | announcing what shipped; deliberately excludes implementation detail — the right call for that audience |
| "Explain it simply" | Claude → you | brevity — which discards the reasoning you needed to judge anything |
| dev-report | coding session → the person deciding what's next | the full reasoning, with every term explained on first use |
Eight sections. Any section this session didn't produce gets dropped rather than padded:
- 📌 One-line summary — what the session actually turned out to be
- 🎯 Why we started here — what was blocking, what the state was before
- 🔍 What we found / built — the real log line or number quoted first, then explained
- 🧩 Why it happened / how it works — the causal chain, including which parts behaved correctly
- 🔧 How we solved it, and why this way ← the longest section: the mechanism, the rejected option, why multiple changes
- 📊 Numbers — before/after, with a denominator on every rate
- 🧪 Verified / assumed / untested — three explicit buckets
- 🚀 Next, and what I need from you — decisions only you can make
Each heading carries its emoji into the report itself, and nothing else in the report does — a long report stays scrollable, and your eye finds the numbers table and the honesty section without reading.
A report you can't check is just a nicer-sounding summary. Five rules do the work:
- Evidence before interpretation. The actual log line or number is quoted first, then explained.
- The rejected option is required. Section 5 has to say what else could have been done and what would have gone wrong — otherwise you have no way to sanity-check a technical decision.
- Verified / assumed / untested, as three explicit buckets. What was measured, what was inferred, what was never checked.
- The real completion state. Edited on disk, committed, pushed, deployed, and observed working are five different things, and the report never reports one as another.
- Decisions named, not implied. What needs your call is kept separate from what Claude will handle on its own.
Design notes — why these choices, in more depth
It only runs when asked. Most skill guidance pushes you to make descriptions eager, because skills tend to under-fire. This one is deliberately narrow. A report is a heavyweight artifact; producing one in response to a passing question is worse than not having the skill.
Evidence before interpretation. Someone who only ever receives conclusions can't tell analysis from confident storytelling, and over time believes either everything or nothing.
Naming who was right. When something breaks, the report says which components behaved correctly. Without that, a reader generalizes from one failure to "the system is unreliable," which is expensive and hard to walk back.
A mandatory honesty section. Volunteering your own gaps is what makes the rest of the report load-bearing. Reports that never say "I don't know" get read as marketing.
Terms are explained, not avoided. The failure mode to avoid isn't "too technical" — it's technical words with no referent. Anyone can follow deep reasoning as long as every noun in it has been given a meaning first.
The report comes out in the language you wrote the command in. /dev-report 이번 주 정리해줘 produces a Korean report; /dev-report resume la semana produces a Spanish one. With no text, it follows the language the conversation has been in.
File paths, function names, commands, log lines, and error messages always stay in their original form — you need to paste them into a search box or say them to someone else, and a translated identifier is a broken one.
If you'd rather type the command itself in your own language, ready-made aliases ship with the skill:
| Command | Language |
|---|---|
/개발보고 |
Korean |
/開発報告 |
Japanese |
/informe-desarrollo |
Spanish |
The plugin install includes all three. With the manual install, copy the one you want:
cp ~/.claude/skills/dev-report/commands/localized/개발보고.md ~/.claude/commands/Adding your own is a five-line file — copy any of the above, rename it to the command you want to type, and translate the body. The last line, which pins the output language, is the part that matters. Pull requests with new languages are welcome — see CONTRIBUTING.md.
Two complete example reports ship in references/examples.md — one in English from a bug-hunt session, one in Korean from a session where routine verification turned up a regression. The skill reads them for calibration; they're also the fastest way to decide whether the register fits you.
The part most write-ups skip — why this fix and not the other one:
I considered the alternative of pinning every server to the new library and listening only for
.v2. That is cleaner, and I rejected it because it makes email delivery depend on all six servers being perfectly in sync at all times. They weren't today and they won't be during the next deploy either. Correctness shouldn't rest on a condition we've already watched fail.
And the register it holds when something breaks — naming which component was right (from references/craft.md):
The sanitizer did exactly what it was built to do — it deletes links to pages that don't exist, and
/some-sluggenuinely returns a 404. The gap was one step upstream: nobody had told the writing step that real URLs on this site begin with/blog/. So it invented a plausible address, and the checker correctly threw it away.
No diff pasted, no term left undefined — and you just followed an engineering decision end to end without reading a line of code.
Issues and PRs welcome — especially new language aliases, and example reports from session shapes not yet covered (migrations, incidents, greenfield builds, long refactors). See CONTRIBUTING.md — adding a language alias is a single five-line file.
MIT — see LICENSE.
If dev-report makes your Claude Code sessions easier to understand, a star helps other people find it.
