SuperAPI AI Directory

comprehende

General & other

View repository

Updated 10-16 00:06

About this skill

Comprehende

Group a git diff into review concerns and serve a local UI. The point is cognitive offloading over cognitive surrender: the human gets a why and a what of their own to hold against the live diff, instead of adopting the change blind.

Run every command inside the repository under review. Cwd is the repo; there is no --repo flag. Use the pinned CLI:

npx comprehende@0.10.1 <command>

The review document is interpretation only. It holds a title, groups, summaries, and hunk pointers. Do not copy patch text into it. serve reads the diff from git.

Work from the digest, not the diff. The digest is one line per file: kind, hunks, symbols, pairing and copy hints. Grouping needs that line; only ambiguity needs patch text. Fetch patch with show, batched in one call and scaled to the digest.

Workflow

Each step is one tool call where the step says so. Batch the commands as written; every extra round trip re-sends the whole context. Spend one tool call per phase: the step-2 batch, one sources call, one show batch, one write, validate. Further calls only fix what validate names.

  1. Name base and head. Use the refs the user named; three-dot (base...head) is the merge request or branch diff. When the change is already on the default branch, use the request's recorded base and head SHAs; the moving default-branch HEAD includes later merges. When only the head SHA is known, base is the merge-base of that head with the named base branch. Fetch a ref that is missing from the local clone. Done when both ref names are chosen. The next shell call verifies them.

  2. One shell call: verify the refs, write the draft, print the digest and the draft, log, and stat. $REVIEW_DIR comes from mktemp -d in that call (outside the repository; the work tree stays untouched, with no new gitignore entries). && stops the shell before pregroup when a ref does not resolve. Stop and tell the user which ref failed, rather than guess a ref.

    REVIEW_DIR=$(mktemp -d) && git rev-parse --verify --end-of-options "<base>^{commit}" && git rev-parse --verify --end-of-options "<head>^{commit}" && {
      npm view comprehende version || true
      npx comprehende@0.10.1 pregroup --base <base> --head <head> --data "$REVIEW_DIR/review.json"
      npx comprehende@0.10.1 digest --base <base> --head <head>
      cat "$REVIEW_DIR/review.json"
      git log --format='%s' --end-of-options <base>...<head>
      git diff --stat <base>...<head>
    }
    

    When the user names a local executable, use that command as written in place of npx comprehende@0.10.1, and run <executable> --version in this same shell call in place of npm view. That printed line is the CLI version.

    If that version is newer than this pin (npx comprehende@0.10.1), stop and tell the user. Show npx skills update as an option they can run. Do not run that command. Wait for them to continue with this pin, or to update and start this skill again. If the versions match or the query fails, continue. Defaults: --head is HEAD; --base is origin/HEAD, falling back to main or master. pregroup writes a draft: identical-copy clusters, one mechanical group (renames, copies, moves, generated output), and one change group for the rest, with stub prose. It does not invent a review. Done when that file exists and the digest and draft are in context. Trust the identical copy and pairs with hints; never fetch patch to confirm them. Never read the draft from disk; the cat above already printed it.

  3. One tool call for all sources, truncated at fetch time. Files on disk go through one shell call that caps each file, never a read per file:

    for f in "<sourcesDir>"/*; do echo "=== $f"; head -n 40 "$f"; done
    

    Sources behind a host CLI or MCP go in one parallel block, one fetch each: PR or ticket body to 15 lines, each review comment to 10 lines with whether its thread is resolved, whether the comment is outdated, and its current line, commit log subjects only. Never run a full git diff; the digest line is the file. Full bodies stay out of context; the caps above are the source. Done when the digest, the draft, and those sources are in context.

  4. Recover the why, write the title, write the what, and check each source item against the digest and the fetched hunks (see lookFor). Then write document title (always), document summary (always), document why (only when a source names the motive), and document lookFor (only when an item diverges; see lookFor). Summaries come from the digest symbols and kinds, plus fetched hunks where fetched. Replace the stub title and summary. Done when every source item has a verdict, every divergence is a document lookFor bullet, every ticket item a later comment changes is a bullet, and every lookFor bullet matches the code at head.

  5. Group the hunks by review concern, starting from the draft. Accept a draft group that already holds one concern. Split the change group where a reader would stop and review the first piece alone. Merge draft groups that serve one concern. A path covers every hunk of its file: keep the draft's path refs, and write hunk refs only for a file split across groups. Fetch patch only to decide a split: state the decision first ("login.ts hunks may belong apart"), then batch every fetch in the one show call below. Fetch at most one hunk per 3 files in the digest (at least 2, at most 8). Draft mirrors, mechanical, and one-concern groups need no fetch:

    npx comprehende@0.10.1 show --hunk "<ref>"; npx comprehende@0.10.1 show --file "<path>"
    

    Copy each ref from the draft into the group that holds it, verbatim; the draft refs already match live git. When one file's hunks belong in different groups, name each hunk as in the hunk identity paragraph. Set document size from review burden, not git diff --stat. Write the whole review.json in one write from the field shape below. Keep version and source from the draft. Done when every ref from the draft is in at least one group, every live hunk of a split file is named, every group has its why, stub prose is gone, and every named part has a matching document parts[] entry. Also done when each unit test sits in the group of the code it checks, each new harness sits with the build or CI that runs it, each feature spec sits with its seed and helpers, each one-line call site or declaration sits with the code it serves, unasked work that could have been its own PR has its own part, related enabling work stays one part, each dependsOn id names a group in the same part, and each mechanical summary says what the reader can skip. When a story builds on another part, suggestedOrder puts that part first.

    Field shape. The words are placeholders. This shape is enough to write a valid document.

    {
      "version": 1,
      "source": { "baseRef": "<base>", "headRef": "<head>", "range": "<base>...<head>" },
      "size": "small",
      "title": "Short name",
      "summary": "What the change is.",
      "groups": [
        {
          "id": "helper",
          "title": "Group title",
          "why": "Why this group exists.",
          "summary": "What this group is.",
          "suggestedOrder": 0,
          "hunkRefs": ["src/file.ts"]
        }
      ]
    }
    

    Add a field when the section that defines it says to write it: document why, lookFor, and parts (name, summary); sources (id, kind of ticket, pr, pr-comment, commit, or transcript, label, plus url, title, gist, and part when you have them). On a group: part, sources (those ids), lookFor, dependsOn (group ids). A pr-comment source also has author and body. A line pin adds path, side (old or new), and line together, and only for the pin case under PR comments. size is trivial, small, medium, large, or very-large.

  6. Run npx comprehende@0.10.1 validate --data "$REVIEW_DIR/review.json" with the absolute path. It checks exactly these: every live hunk sits in a group, every ref matches live git, every source: id exists in sources, every group part has a parts[] entry, every PR comment pin (path, side, line) matches a live line, and the document has no unknown fields. On failure, fix what the message names; the diff is git's, leave it alone. Done when validate exits 0.

  7. When they ask to upload the report, follow Export. Otherwise run npx comprehende@0.10.1 serve --data "$REVIEW_DIR/review.json" --open and give the user the localhost URL (127.0.0.1 only).

references/example.md is an optional filled sample of the field shape. The shape in step 5 is enough to write a document.

Export

Write a static site and put that folder where they asked.

npx comprehende@0.10.1 export --data "$REVIEW_DIR/review.json" --out "$EXPORT_DIR"

$EXPORT_DIR is a fresh directory outside the work tree, not a git repository. The folder is the UI plus frozen git payloads. There is no git in it. Done when they have the URL or path they named. If review.json is still a draft, finish the Workflow through validate, then export.

The title

Document title is a short name for the whole change. Always write one.

Prefer a title the human already wrote when it names this change: the pull request title, a ticket title, or the name they used in a transcript. Keep that wording when it is descriptive and represents the reviewed change.

Invent a title when those sources are missing, vague, or name something else. A branch slug, "WIP", or "fix" is not a title. Sources are a reference. Do not paste a title that does not fit.

The why

Document why names why the work exists, in one or two sentences, inferred only from the sources below. It is the problem or goal a source states. Before writing it, find the source sentence that states that problem or goal: "Support SSO login", "so admins can export audit logs", "retries flood the API". A sentence that only says what the change does ("the settings page becomes a modal", "uploads move to S3") belongs in the summary. When no source sentence states a problem or goal, or the sources are mixed, omit the why. Write it in the source's own terms, with no cause, benefit, or reader need the source does not name. The same holds for every group why: a citation carries only what that source says, and a source is the reason for a choice only when it states that reason. Do not derive document why from the digest, from group structure, or from a motive you infer from the patch. A request naming two unrelated product stories with no unifying source also gets no document why; each story keeps its own group whys.

Sources are read truncated, never copied into the review document, except PR review comments: copy author and body so the UI can show the quote. Keep ticket bodies, request descriptions, commit text, and transcript text out of review.json. Cite a source in prose with [text](source:s1) when that sentence leans on it.

  • Tickets and issues. Emit a sources item: short id (s1), kind ticket, label (#24), plus url, title, gist, and part when you have them. Read the ticket (host CLI, tools or MCP, whichever is available) when document why needs it. part goes on a ticket that belongs to one story, matching that story's group part; omit it only when the request or ticket title says the ticket covers the whole review. Commit count proves nothing about ticket scope. Do not copy the ticket body.
  • Pull request. When the user named a pull request or merge request, emit kind pr with a label like PR #32 and a gist from the description. Do not copy the description. PRs can also refer to tickets and issues in their description or branch names.
  • PR comments. Emit kind pr-comment. Label like alice on PR #32. Copy author and body. Flatten threads: one source per comment. Pin a comment that still sits on one line at head and whose thread is open. Copy path, side (old or new), and the forge's current line. GitHub LEFT is old, RIGHT is new, and the current line is line (the line on an older commit is original_line). A conversation comment has no pin. A resolved thread (isResolved) has no pin. An outdated comment has no pin (isOutdated, or the current line is null). When an unpinned comment still asks for work the change does not do, cite it in lookFor.
  • Commit messages. git log --format='%s' --end-of-options <base>...<head>. Emit kind commit when a commit names the motive. label is that subject line, or a SHA from the same log. They can clarify group why; document why needs one of the stronger sources above. These can also contain issues and tickets.
  • Transcripts. A coding-agent (like Cursor, Claude Code, Codex, etc.) transcript you already have (this session, or a historical one) supplies the human's stated reason. Emit kind transcript, a label like Cursor session · Aug 12, and a gist. Omit url. Do not copy transcript text.

Put those ids on the group sources array when the group uses them, even if the prose does not cite them inline. validate fails on a source: href whose id is missing from sources.

Every group has why: why this group exists. A source that names the concern is best. A foundation group with no source of its own says it enables the groups that depend on it; that is a complete why. Independent side work in its own part (docs-only, test-only) gets its own group why and leaves document why to the named motive.

The what

Document summary is one or two sentences naming what the change is, including each independent story when the PR is mixed. Every review has one, even when why is absent. It is a what, not a motive.

When groups use part, write one document parts[] entry per independent story. name is that part string. summary is one sentence saying what that story is, same voice as group summary. Document summary still names the stories; the part summary is the per-story what under the colored Overview column. Omit parts when no group has part.

Group summary is one sentence saying what the group is, describing how its hunks are related: "Calling the new validator from core.ts by the route in routes.ts", not a file-by-file recap or a path list. For draft mirrors and mechanical groups kept as-is, the summary says what the reader can skip and why that is safe: an identical copy, a pure move, or regenerated output that means the same.

Grouping rules

  • Group by review concern: why these hunks are read together. A directory qualifies only when that directory is the concern. The digest line plus the draft is enough for most files; the patch is for ambiguity only.
  • A group is one concern a reviewer names in a phrase. The code, the unit tests that check it, and the one-line call sites, declarations, and re-exports that serve it read together in that group. A unit test next to its module stays in that module's group; the digest pairs with hint names that module. A new integration harness is the concern: that harness and the build or CI files that run it are one group, not the production group they exercise. A new feature's code, fixtures, seeds, helpers, and the spec that runs them are one group. A seed or helper that only one spec uses stays in that spec's group. A foundation split is for a contract several later groups share. Split a concern only where a reader would stop and review the first piece alone. A small change has one to three groups.
  • A hunk may appear in several groups when it matters in more than one story. When one hunk holds two concerns, the group that holds it names both.
  • dependsOn marks a real dependency inside one story: the reader needs the earlier group to understand this one. It stays inside one part. Reading order inside a story: contracts and foundations, then call sites, then mechanical work. Independent work stands alone with its own part, empty dependsOn, and nothing depending on it. A second feature, extra product events, a dependency policy change, or standalone documentation that could have been its own PR is independent work. Unasked work that only enables the asked story (path renames, fixture layout, local startup) stays one part with that story, or one harness part. When unsure whether two concerns depend on each other, keep them separate under different parts: a false split is easy to see, a false chain hides a mixed PR.
  • part is a short name (a few words) for one independent story, the same on every group in that story; the UI colors shared parts together. One document parts[] entry per name.
  • Mechanical work (import reordering, identifier-only renames, generated code, formatting, pure moves) is its own group that keeps every hunk as refs, risk visible rather than folded into a file list. The draft mechanical group already holds the CLI-flagged files; check each line still belongs (a flagged file with a real behavior change moves out to its story) and write the summary that says what the reader can skip. An identical copy of a file in the draft mirrors group sits with its source; that group's summary still says the copy is identical. When a mechanical group exists only because of a story, it is that part's last group with nothing depending on it. When it could have been its own PR, it is its own part.
  • suggestedOrder walks the whole review, independent parts included. Mechanical parts, independent documentation, and test-only cleanup go last.
  • Document size is human review burden: trivial, small, medium, large, very-large. Forty files changing one import in one group are small. A new component plus follow-up changes across existing screens is medium. A new contract that later groups depend on is large. That size stays when those groups merge. The digest header (file and hunk counts) sets the starting point; the group count and dependencies adjust it.
  • Coverage: every live hunk sits in at least one group. A path covers every live hunk of that file. Duplicate refs across groups are allowed. Unreferenced hunks fail validate and show as Unassigned in the UI. Every ref in the draft already covers its hunks; splitting a file across groups needs hunk refs, everything else keeps the draft's paths.
  • Lockfiles have no hunk refs; the CLI leaves them out of the draft and the UI gives them their own closed bucket. Hunk refs exist only for hunks the draft lists.
  • A path stays valid when a rebase only shifts line numbers. path@oldStart+newStart goes stale when those starts move, and that fails validate. serve still starts, shows git at those SHAs, and flags the broken pointer. Re-run pregroup and copy fresh refs. A dirty work tree does not make refs stale.

A hunkRefs entry is a path string when the group holds every live hunk of that file. Copy the path from the draft. When a file is split across groups, name each hunk as path@oldStart+newStart, or old/path -> new/path@oldStart+newStart when that hunk is a rename. Take oldStart and newStart from the digest show of that file, or from the hunk's @@ -oldStart,oldLines +newStart,newLines @@ header. Identity is (path, oldStart, newStart) plus oldPath when renamed. Image files are paths. Git LFS images are read from .git/lfs/objects in the clone; a missing object leaves the image slot empty.

lookFor

lookFor is for what a careful engineer would miss on a first read of the live diff. Default to an empty lookFor and earn each bullet with a fetch: a bullet lives only where you ran show on its hunks, or where the digest plus the sources already prove it. Each bullet is one finding, stated as fact and true at head: optionally a short risk tag (Subtle, Breaking, Race, Perf), then one sentence on what the code at head does and what the reader would observe. The human checks it against the live diff and keeps the verdict. Pseudocode, diagrams, collapsed diffs, commit lists, hunk counts, and pass/fail marks stay out.

Group lookFor holds claims that live in those hunks. Fetch the hunk when a behavior change hides in it and write the predicted trace: a small realistic input, where the old and new paths diverge, and the observable result. A change in equality or identity (object versus primitive fields, pointer versus contents) uses two inputs that look the same and now compare differently. When a hunk works around app behavior (a sleep, a forced write, a retry), the bullet says what the app does without the workaround. A hunk under application source in a PR whose sources are about tests, CI, or tooling is production code in a test PR: the bullet says it is production code and names that behavior change. A setup or teardown script that deletes or overwrites a file that is not test output earns a bullet: the path, when it happens, and what the developer loses. So does a behavior change no source mentions, and a hunk that resolves a review comment in a way the hunk alone does not make obvious: the bullet says what the fix does. Empty is correct for a rename, a formatting change, or a wording-only docs group; leave it empty rather than fill it. Draft mirrors and mechanical groups stay empty unless a fetch proves otherwise.

Document lookFor holds claims about the whole change, and the divergences between the sources and the code at head. Source items are each requirement and acceptance item in a ticket, each behavior claim in the pull request description and commit messages, and each request in a review comment. Test plans, manual QA notes, and out-of-scope lists are context, not items. Read the truncated source for each item and give it a verdict: done as asked, done differently, not done, or not true at head. Each verdict other than done-as-asked is one bullet: what the source asks or says, what the digest or fetched hunk shows, and the reason when a source or the code gives one, or that no source gives one. When a later source changes what an earlier one asked (a review comment overrides the ticket), the ticket item is done differently, and the bullet names both sources. A manual step a source says the change needs (turn on a setting, run a migration) is also a bullet. Cite with [text](source:s1); the id goes in sources, and validate fails on an unknown id. Omit the field when nothing needs a bullet.

Write the prose

Document title, document why, group why, summary, and lookFor are for a tired engineer on the first read.

  • One thought per sentence; split past about 25 words.
  • Present tense. Name who does what.
  • Use the real symbol, path, flag, or command.
  • Cut every word that does no work. No changelog voice, no puffery, no "not just X, but Y".
  • A straightforward group needs only its title, why, and summary; the live diff does the rest.