Skip to content

CLI

Terminal window
riff [OPTIONS] [TARGET]

One positional argument. riff pattern-matches it to work out whether you’re asking for a GitHub PR or a local diff — there is no --pr flag to remember.

TargetWhat you get
(none)Uncommitted changes in the working copy
prThe PR for the current branch or bookmark
123, #123PR #123 in the current repo
gh:owner/repo#123That PR, from anywhere on disk
https://github.com/owner/repo/pull/123The same, by URL
anything elseA local revision: commit, range, branch, or jj revset
Terminal window
riff # what you haven't committed yet
riff pr # the PR you're working on
riff 123
riff HEAD~3 # the last three commits
riff main..feature-branch # a branch comparison
riff branch:feature # shorthand for git diff feature...HEAD
riff @- # a jj revset: the parent change
riff gh:facebook/react#1234

Anything riff can’t recognise as a PR reference is handed to your VCS as a revision, so its error message is the one you’ll see if it isn’t valid.

riff checks for jj first — a jj repo also has a .git, so the order matters — and falls back to git.

With jj, the target is a revset: jj diff --git -r <target>. With no target, the diff is trunk() to the working copy, which is the whole of the change you’re currently building.

With git, no target means uncommitted work: unstaged changes, or staged if there are none, or git diff HEAD if everything is committed but unpushed. A target is passed to git diff directly, so ranges (main..feature), commits (HEAD~3) and everything else git accepts work as they do in git. branch:name is the one piece of riff-specific sugar — it expands to git diff name...HEAD, the three-dot form that shows what your branch added rather than everything that happened on name since.

riff pr resolves the PR for whatever branch or bookmark you’re on. The rest identify a PR directly. Before fetching, riff settles where comments will live and asks about it if it had to guess — see storage.

Flag
-h, --helpUsage, targets and examples
-v, --versionVersion number

The comments a review stored in .riff/, from the shell. Never touches GitHub.

Command
riff comments [--json] [target]List local comments; --json is the machine-readable form (below)
riff comments resolve <id> [target]Mark a thread done; it will never be published
riff comments unresolve <id> [target]Reopen it
riff comments remove <id> [target]Delete one comment
riff comments clear [target]Delete every local comment for the target
riff comments install-skill [--global]Install the Claude Code skill that works through them — this repo, or ~/.claude for all of them

target is the same argument riff takes and picks the comment set (local when omitted, or HEAD~3, 123, gh:owner/repo#123). <id> is the full id or the 8-character prefix the files are named by. See a review without GitHub.

Enough to act on a review without opening anything: counts, the repo root, and a threads array — replies already nested under their root comment — where each thread has id, file, line, side, resolved, body, replies, the diffHunk the reviewer saw, code (that line as it reads in the working copy now), context (the numbered lines around it, > marking the anchor), commentFile, and the literal resolve / remove commands that retire it.

code and context are null for a LEFT-side anchor — the line was deleted, so the working copy can’t show it and diffHunk is the record.

The riff repo is a plugin marketplace, so the skill can be installed the usual way instead:

Terminal window
claude plugin marketplace add candril/riff
claude plugin install riff@riff

One skill, riff-comments, ~80 tokens always-on. riff comments install-skill writes the same file directly if you’d rather not add a marketplace.

q quits. Draft comments are already on disk — there’s nothing to save on the way out.

Startup failures print to stderr and exit non-zero: not a repository, a PR that doesn’t exist, gh not authenticated. Failures during a session become toasts, and for GitHub rejections they carry GitHub’s own message rather than gh’s generic one.

riff shells out to whatever’s on your PATH, so these are only needed for the actions that use them: gh (all GitHub features), git or jj (local diffs), $EDITOR (gf, C, gP), tmux (gF), and difftastic, delta or nvim for the external-diff actions in the action menu.