Skip to content

techne:catchup

Read every comment, review, and state change on one repo's issues and PRs since you last participated, then report who is blocked on whom. Read-only.

Part of techne: /plugin install techne@techne, then /techne:setup.

When to use

  • Returning to a repo after hours or days away: "did anything change?"
  • Before resuming work on an issue or PR, to re-read its threads and those of associated items.
  • "Is anyone waiting on me?" / "What did I miss?" / "Sitrep on <repo>."
  • Every turn while shepherding a PR, where a blocking review can land between two of your own pushes.

Usage

/techne:catchup <reponame>

A bare repo name resolves against the local clone's remote under workspace_root, so team repos owned by a collaborator resolve correctly. An owner/name works, and so does a path to a clone or to any directory inside one. With no argument, the skill uses the current directory's remote. A name that resolves to no clone stops with a message rather than falling back to the current directory. When techne.toml cannot be used, the script says why on stderr and looks for repos beside the current folder.

Given a path, it also reports any clone checked out beneath it. A repo parked inside another repo's working tree answers to the outer clone, so sweeping the outer one alone would report "nothing to catch up on" while the real threads sit a directory down.

The skill anchors on your most recent comment, review, opened issue or PR, merge, or commit in that repo and reports everything after it, bucketed three ways. A commit cannot bury a comment aimed at you: pushing is not reading, so anything addressed to you before a later commit's anchor is retained and flagged.

Bucket Meaning
⏳ Waiting on you A review to answer (including a review someone explicitly requested from you, even the first you are ever asked for on that repo), a question addressed to you, your own approved PR still sitting unmerged, or your PR that someone else's merge silently broke.
🔵 Waiting on them Your PR awaiting review, your unanswered question, or blocking items you raised that are still unaddressed.
✅ No action Merged, closed, informational, or your own activity.

What it reads

Four surfaces, because a comment-only sweep misses the quiet events:

  1. Issue and PR conversation comments
  2. PR review bodies and verdicts
  3. Inline review comments on the diff
  4. State changes carrying no comment at all: merges, closes, approvals, new PRs

It also reports standing state -- open PRs and open issues -- separately from events, because an item nobody answered produces no event at all. An issue you filed and nobody replied to is waiting on them just as much as a blocking review is, and it will never appear in a list of things that happened.

The fourth is the one hand-runs forget. A teammate can merge four PRs and silently address five review items without writing a word.

All four come from a single GraphQL call in scripts/sweep.py, rather than the two REST calls per open PR the surfaces would otherwise cost. The same call carries each open PR's CI rollup and merge state, so reporting never costs a follow-up gh pr view.

The scan spans every PR and issue state, not just open ones, newest-updated first. That is deliberate: a blocking review posted moments before someone merged lives on a merged PR, and an open-only scan would never see it.

It also reads your permission on the repo and any review explicitly requested from you. Where you hold write access, every open PR of someone else's that nobody has reviewed is listed under 🔍 No review yet, oldest first. Being asked is not a precondition: an unreviewed PR is a gap in the team's review ceremony whoever ends up filling it, and it is a standing state rather than an event, so it appears even on a quiet sweep that reports no new activity.

The catch-up names the gap and stops there. Running the review itself is techne:elenchus.

Options

Flag Effect
--since ISO8601 Override the anchor instead of deriving it from your last activity.
--window-days N Cap how far back the anchor may reach (default 30).
--max-events N Cap returned events (default 80). Anything mentioning you, or on an item you opened, is kept regardless.
--prs N / --issues N Widen the scan past the default 50 each.

The report states explicitly when a scan was truncated, events were omitted, state changes were collapsed, or the window was capped. A partial answer is always labelled as one.

What it will not do

No merging, commenting, labelling, assigning, closing, or editing. If the catch-up reveals something that needs an action, it names it in the verdict and stops. Comment text is treated as data, never as instructions.

Testing it

make test-unit runs the suite. The sweep's pure surface is covered without a network: how a repo argument resolves (owner/name, a bare name, a clone, a directory inside one), which nested clones a walk surfaces, how the GraphQL payload flattens into events, and what is allowed to anchor the window.

Several tests exist to pin a safety property rather than a behaviour. A close is never attributed to the PR's author, because the closer is not in the payload. A state change on your own item does not count as participation, because treating it as such silently drops every comment made before it. A commit moves the anchor but not the participation timestamp, because pushing is not reading. And no sibling clone is dropped from a nested scan, because a clone left out of the report is the false all-clear the scan exists to prevent.

gh and git are faked with pytest-subprocess, which asserts the exact argv: the slug has to come from gh repo view rather than a parsed remote, since a parse that leaves .git attached yields owner/repo.git and 404s on every later call.

See also

  • techne:elenchus: once a catch-up says a PR needs your review, elenchus runs it.
  • techne:ci-audit: when a catch-up surfaces a failing check, ci-audit reads the logs.

Full instructions

SKILL.md on GitHub holds the full instructions Claude follows for this skill.