Using Shelley
Commit tours
A guided walkthrough of a commit's diff, written by the agent, stored as a git note, and shown in Shelley's diff viewer.
A commit tour is an annotated reading of one commit. Instead of files in alphabetical order, you get the diff in the order it makes sense: data model first, then the core logic, then tests, with a sentence or two on why each piece looks the way it does. Generated files, renames, and whitespace collapse out of the way. A tour can also list the key design decisions, ask you questions, and include screenshots or short recordings of a UI change.
Tours cover the whole diff, every hunk exactly once. Shelley checks this by replaying the tour onto the commit’s parent and requiring the exact commit tree, so a tour can reorder the change but can’t leave anything out or quietly alter it.
Asking for one
Any of these starts a tour for a commit:
- Type
/tourin a conversation forHEADof its working directory, or/tour <hash>for another commit. It takes a commit hash (abbreviated is fine), not a ref likeHEAD~1or a branch name. - Click request tour on the “now at
<hash>” line that appears after the agent commits. - Select a commit in the git graph and click Build tour. The diff viewer shows the same button when it’s showing a single commit with no tour.
These run a separate worker conversation with the built-in commit-tour
skill, using the current conversation’s model and reasoning level. While
it works, a building link next to the commit opens it. The worker is told not to
touch tracked files, commits, branches, or remotes, and it has 30 minutes.
Tours can be requested from top-level conversations only, and not from an
unsent draft. If the commit already has a valid tour, it just opens.
You can also ask in plain words (“write a commit tour for that”) and the agent follows the same skill itself. To get one for every commit, say so in your AGENTS.md.
Reading a tour
A toured commit is marked tour in the git graph and in the diff viewer’s commit picker, and the “now at” line gets a tour link. Opening it in the diff viewer shows a Tour tab next to Files: title and intro, Key design decisions, Questions for you, then the diff as titled sections with commentary. Trivial changes are collapsed. Each question has an Answer button that puts a quoted reply in your composer; decisions and diff lines take comments the same way. Comments on screenshots work like comments on any image.
Shelley only shows a tour that still verifies against its commit. A note that no longer matches won’t open (the tour badge only checks that a note exists), and requesting a tour for that commit builds a new one.
Where tours live
Tours are git notes on the ref
refs/notes/shelley-tour, one JSON note per commit, in the repository
itself rather than Shelley’s database. Screenshots and recordings are stored
as git blobs pinned by that ref, so the note is self-contained.
git notes --ref=shelley-tour list
git notes --ref=shelley-tour show HEAD
Git doesn’t push or fetch notes unless you ask:
git push origin refs/notes/shelley-tour
git fetch origin refs/notes/shelley-tour:refs/notes/shelley-tour
Pushing the ref pushes its pinned media too, and notes history keeps it. Notes are attached to a commit hash, so amending or rebasing leaves the tour behind. Git can carry it over if you tell it to:
git config notes.rewriteRef refs/notes/shelley-tour
The copied tour still has to verify against the new commit, so this helps with reworded messages more than with changed code.
The shelley tour command
This is what the agent runs, and you can too. Every subcommand takes
-C <dir> for the repository (default: the current directory); put flags
before the commit. Run shelley tour alone for the usage summary.
| Subcommand | Does |
|---|---|
chunks <commit> |
Print the commit’s diff split into numbered chunks (JSON) |
scaffold <commit> |
Print a starting tour that references every chunk in diff order |
verify <commit> <tour.json> |
Check that the tour reproduces the commit exactly |
attach <commit> <tour.json> |
Verify, then store the tour as the commit’s note |
show <commit> |
Print the stored tour |
chunks has three views: the default JSON (hash, subject, and each chunk’s
id, file, and patch), -index for one line per chunk with no patch
bodies, and -text for raw patches. -only narrows it to chunk IDs and
ranges (0,3-5) or a single file path:
shelley tour chunks -index HEAD
shelley tour chunks -text -only 4,7-9 HEAD
shelley tour chunks -text -only server/model.go HEAD
The index marks chunks that are provably mechanical (generated files,
whitespace-only hunks, renames, binaries) as [trivial: reason], and
scaffold pre-marks them trivial. A typical run:
shelley tour scaffold HEAD > /tmp/tour.json
# reorder entries, add headers and comments
shelley tour verify HEAD /tmp/tour.json
shelley tour attach HEAD /tmp/tour.json
verify prints tour for HEAD verifies, or an error and exits nonzero. A
tour that leaves something out fails with tour produces tree <x>, want <y>. attach re-verifies, replaces any existing note, and is safe to run
concurrently. It stores chunk references resolved to their patch text, so
show prints patches rather than IDs.
The tour format
{
"version": 1,
"title": "Short plain-text title",
"intro": "Markdown: what changed and why.",
"decisions": [{"title": "One-line decision", "body": "Why, and what was rejected."}],
"questions": [{"title": "Something for you to decide?"}],
"chunks": [
{"header": "## The data model"},
{"ref": 4, "comment": "Why this shape matters."},
{"media": "/tmp/after.png", "name": "Settings, after", "comment": "The new screen."},
{"ref": 0, "trivial": true}
]
}
Each entry in chunks has exactly one of header (a Markdown heading),
ref (a chunk ID from chunks), patch (literal patch text, for splitting a
hunk by hand), or media. Patch and ref entries may carry comment and
trivial. Media must be PNG, JPEG, GIF, WebP, MP4, or WebM, 10 MiB at most;
relative media paths resolve against the current directory, not -C.
decisions and questions are optional. The full guidance the agent
follows is the skill itself:
shelley skill cat commit-tour