agentsclimarketplace

Diff recap

Skill allemaar/open-skills/skills/diff-recap

Readable agent skills with optional declarative YON protocols you can inspect and validate. A personal, field-used pack by Alexandru Mares.

Install
npx -y skills add allemaar/open-skills --skill diff-recap

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Turn a git diff into a PR-pasteable recap — one row per changed file whose path, status, and line counts are transcribed verbatim from `git diff --numstat` (true by construction; the model writes only the labels), emitted as an inline annotated widget plus a mandatory ASCII twin and a `diff-recap/1` record whose totals equal the sum of the rows. Fills the PR-summary gap the orient- family does not cover. Not /orient-map (shape + delta of the work) or /orient-status (position + ETA) — diff-recap recaps a concrete change-set. Zero external dependency: it renders inline, never to a hosted service.

SKILL.md

12.1 KB, as published. Nobody here has run it

/diff-recap

Turns a git diff into a recap you can paste into a pull request — a per-file change table whose numbers are transcribed from git, grouped and labelled, rendered as an inline annotated widget with a mandatory ASCII twin, and backed by a diff-recap/1 record. It fills the gap the orient- family leaves open: orient-map shows the shape of the work and orient-status shows where you stand, but neither recaps what a concrete change-set contains for a reviewer. diff-recap does exactly that, and only that.

Its differentiator is true by construction: the structured numbers (per-file added/removed/status and the headline totals) come straight from git diff --numstat and --name-status — the model authors only the prose labels. A record whose totals don't equal the sum of its rows is rejected by a value gate before it can be shown, so the recap cannot quietly lie about the diff. And unlike a hosted recap renderer, it has zero external dependency — the ASCII twin is self-contained and PR-pasteable in any channel.

Structured execution spec: protocol.yon. Read it for the canonical steps, rules, and gates; this file is the human-readable, self-sufficient explanation. The two must stay in sync — if you edit one, update the other and refresh the @STAMP date.

When to use

  • "Recap this diff / summarize these changes for a PR" — you want a reviewer-ready change summary, not a fresh read of the whole tree.
  • "What changed in this branch" as a change-set, grouped by area with a one-line why per file.
  • Right before opening a pull request, when you want a paste-able summary whose numbers you can trust.

How it works (self-sufficient — works without protocol.yon)

Every call recomputes from the real diff; nothing is stored.

  1. Take range, repo, and intent as inputs — never prompt. range defaults to the working tree against HEAD (or a A..B range, or --staged); repo defaults to the cwd. intent (the PR's goal) shapes the labels — if it's ungrounded, the recap still emits the mechanical facts but caps the labels to descriptive and never invents a rationale.

  2. Gather from git, transcribe verbatim. Run git diff --name-status and git diff --numstat over the range. For each file, copy the status (A/M/D/R) and the added/removed counts exactly as git reports them. A binary file reports -/- in numstat → record 0/0 and mark the row binary in its label. The model never counts by hand — the numbers are git's.

  3. Group and label — the only model-written fields. Cluster the files by area (feature / tests / docs / config / …), and write one concise label per file and a one-line summary per group. path, status, added, removed are git-attested; label and group are the model's only freedom.

  4. Set the totals as the sum of the rows. total_files, total_added, total_removed are the exact count and sums of the per-file rows — that is the true-by-construction invariant: the headline is, by definition, the sum of the attested rows.

  5. Fail closed. No git, or an empty diff → gate_status = barren, attested = false, and a NO DIFF card — never a fabricated recap. A clean recap requires a real git source (attested = true); a partial source caps the verdict at partial.

  6. Emit the triple bundle. The YON record (below), the PR-pasteable markdown summary, and the visual face (Claude Code only). diff-recap honors the three render-face branches: a human on Claude Code with the visualize tool present on an explicit invocation gets the widget + ASCII twin; an agent gets the YON record only; any other runtime / no tool / indeterminate handler_type gets the ASCII twin (fail-closed). See the bundled, self-contained render-face contract. diff-recap adopts only this branching, not the orient family's footer roster, "you are here" breadcrumb, or staleness short-circuit. The information-complete ASCII twin is always emitted — it carries every file row, count, group, and total the widget does (worked trio at examples/diff-recap.{ascii.txt,widget.svg,example.yon}).

Record emission (the YON face — reserved tags only)

The record is a diff-recap/1 instance (recap-schema.yon). Reserved tags only. The envelope is @CFG id=recap; each changed file is one @CFG id=file.<n>; list fields (groups, provenance) go in a sidecar @MAP, never an in-set bracket-list (an in-set list corrupts the record silently and still validates). Never run yon format on an instanceCANON mode is destructive on set-internal lists. Validate with --profile exec, then run the value gate. Skeleton:

@CFG id=recap | set=[schema_version=diff-recap/1,computed_at:ts=…,ephemeral:bool=true,tool=diff-recap,range="HEAD",repo=".",total_files:int=4,total_added:int=155,total_removed:int=7,attested:bool=true,gate_status=clean,overall_trust=high]
@CFG id=subject | set=[name=…,kind=repo,purpose=…,intent_status=stated]
@CFG id=file.f1 | set=[path="src/rate-limit.ts",status=A,added:int=88,removed:int=0,group=feature,label="new token-bucket limiter"]
@CFG id=file.f2 | set=[path="src/server.ts",status=M,added:int=24,removed:int=6,group=feature,label="wire the limiter in"]
@MAP name=groups | pairs=["feature"->"limiter + wiring (2 files, +112/-6)"]
@MAP name=provenance | pairs=["recap.total_added"->"git-attested:high:git diff --numstat"]

On barren evidence the envelope degrades honestly: gate_status=barren, attested:bool=false, no file rows, and the visual is the NO DIFF card. A full worked instance ships at examples/diff-recap.example.yon.

The value gate — why the recap can't lie

yon validate checks structure, not values: a record can be valid YON yet state total_added=999 while its rows sum to 155. references/tools/diff-recap-check.mjs travels inside this skill folder and is the missing half — it asserts Σ per-file == totals, enum membership, and the fail-closed/attested gates, and with --numstat it checks every row against the real git numstat. An emitter runs it before emit; the source repository additionally exercises the worked and deliberately broken fixtures as release evidence.

node <skill-dir>/references/tools/diff-recap-check.mjs <skill-dir>/examples/diff-recap.example.yon --numstat <skill-dir>/examples/diff-recap.numstat

Output — worked examples (markdown / ASCII face)

📋 acme-api — add per-route rate limiting.    range: HEAD     [counts: ◆ git --numstat]
## 4 files · +155 / −7                                          ◆ git diff --numstat

feature   +112 / −6
  + src/rate-limit.ts         +88 / −0    new token-bucket limiter (per-route)      ◆ A
  ~ src/server.ts             +24 / −6    wire limiter in; drop old fixed counter   ◆ M
tests     +40 / −0
  + test/rate-limit.test.ts   +40 / −0    burst, refill, per-route isolation        ◆ A
docs      +3 / −1
  ~ README.md                 +3  / −1    document the RATE_LIMIT env var           ◆ M

Σ rows = +155 / −7  ==  headline  ✓  (true by construction)
**→ PR summary:** per-route token-bucket rate limiter + unit tests + env-var doc.
Trust: ◆◆◆ every count git-attested · the model wrote only the labels · gate: clean

Barren (honest degradation is the success case):

📋 ToDo — no git, or an empty diff.
┌───────────────────────────────┐
│  NO DIFF                       │   nothing to recap — no commits, no changes.
└───────────────────────────────┘
**→ Next:** stage or commit a change, and the recap becomes visible.
Trust: ◌◌◌ · [gate: barren · attested: false]

The ASCII twin + the Σ rows == headline line + the trust trailer are mandatory on every output.

Boundaries

  • Not /orient-map — that shows the shape + delta of the work (done → here → next); diff-recap recaps a concrete change-set for a reviewer. They never overlap: orient-map is trajectory, diff-recap is a PR table.
  • Not /orient-status — that reports position + remaining + ETA; diff-recap reports what a diff contains.
  • Not a code review — it summarizes what changed, it does not judge whether the change is good. Pipe it into /cold-review for that.
  • Read-only. It runs git diff and reads the tree; it never mutates state.
  • No hosted dependency. Unlike a hosted recap renderer, the ASCII twin is the floor and is self-contained — the recap works with no visualize tool, no server, no account.

Rules

  • MUST be true by construction — transcribe path, status, added, removed verbatim from git diff --name-status/--numstat; never count by hand. The model authors only label and group.
  • MUST set total_files/total_added/total_removed to the exact count and sums of the rows, so the headline equals the sum of the attested rows; the value gate rejects any record where they drift.
  • MUST fail closed — no git or an empty diff → gate_status = barren, attested = false, NO DIFF card; a clean verdict requires attested = true.
  • MUST always emit the information-complete ASCII twin — it is the only render in a no-SVG channel and is PR-pasteable verbatim.
  • MUST render the visual face per the render-face contract (Claude Code only, via mcp__visualize__show_widget): agent → YON record only; human + Claude + tool + explicit invocation → widget + ASCII twin; other runtime / no tool / indeterminate handler_type → ASCII twin (fail-closed). Widget and ASCII twin are projections of one row-structure (same rows + totals), chrome-compliant (no hardcoded color, role="img" with non-empty title/desc, fixed 680 viewBox).
  • MUST emit file rows as @CFG id=file.<n> and list fields (groups, provenance) as sidecar @MAP; never a bare in-set bracket-list; never yon format an instance.
  • MUST take intent as input and cap labels to descriptive when it's ungrounded — never fabricate a rationale.

Next skills. On completion, run the Next Skills protocol (next-skills/SKILL.md): surface the next-skills recommendations from front-matter for the caller to pick. Offer only — never auto-invoke.

Self-improvement. On completion, run the Self-Improvement Protocol (self-improve/SKILL.md): if this run surfaced a concrete, blocking-or-recurring weakness in this skill, propose a specific fix for the handler to approve. Conservative — silent otherwise. Never auto-apply.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.