Generate a self-contained static HTML saga of a git diff — a chapter-by-chapter guided tour of a change.
Project description
Saga
Generate a chapter-by-chapter guided tour of a code change as a single, self-contained static HTML page, a saga of your diff. It partitions a diff into ordered chapters that tell one coherent story, each with a plain-language narration and just the hunks that belong to it. Large PRs become easy to review without losing the thread.
The output is one HTML file with everything inlined (diff2html, syntax highlighting, the data). Open it offline, email it, commit it, or drop it on any static host.
Requirements
- Python 3.11+
git- An API key for your chosen provider, in the standard environment variable:
ANTHROPIC_API_KEY,OPENAI_API_KEY, orOPENROUTER_API_KEY
Generation is one structured LLM call made through instructor.
Install
Install once and the saga command is available from any repo:
uv tool install saga-cli # recommended
# or
pipx install saga-cli
# or, into the current environment
pip install saga-cli
Installing from a local checkout instead? Point the installer at this directory,
e.g. uv tool install /path/to/saga. To upgrade: uv tool install --force saga-cli.
Usage
From inside the repo you want to review:
saga --base main --head my-feature -o saga.html --open
Run it from anywhere with --repo:
saga --repo ~/src/some-project --base main --head my-feature -o out.html
| Flag | Default | Meaning |
|---|---|---|
--base |
main |
Base ref to diff against |
--head |
current branch | Head ref to walk through |
--intent PATH |
— | Optional plan/spec describing the change's intent, for plan-aware narration and deviation flagging |
--model |
anthropic/claude-opus-4-8 |
provider/model string (see Providers); also $SAGA_MODEL |
-o, --output |
saga.html |
Output file |
--repo |
cwd | A path inside the target git repo |
--open / --no-open |
on | Open the result in a browser (on by default; --no-open to disable) |
Providers
The model is a single provider/model string, dispatched through instructor.
Choose it with --model or the SAGA_MODEL environment variable, and set
the matching API key:
| Provider | --model example |
API key env var |
|---|---|---|
| Anthropic | anthropic/claude-opus-4-8 |
ANTHROPIC_API_KEY |
| OpenAI | openai/gpt-4o |
OPENAI_API_KEY |
| OpenRouter | openrouter/anthropic/claude-3.5-sonnet |
OPENROUTER_API_KEY |
export SAGA_MODEL=openai/gpt-4o
export OPENAI_API_KEY=sk-…
saga --base main --head my-feature -o saga.html
As a Claude Code skill
The skills/ directory contains two Claude Code skills. To install both:
cp -R "$(pwd)/skills" ~/.claude/skills/saga
saga— say "/saga" (or "give me a walkthrough of this branch") to generate a saga. It resolves the base/head refs and runs the tool for you.saga-comments— say "/saga-comments" (or "address the saga comments") to read an exportedsaga.comments.jsonand act on the reviewer's feedback in code.
Reviewing: comments
The saga page is also a lightweight review surface. Open saga.html and leave three
kinds of comments — inline (click a line's number in any chapter's diff), per-file
(the "💬 File comment" control in each file header), and one overall review comment
(the box at the top of the Chapters list). Comments are drafted in your browser's
localStorage, so they survive a reload.
When you're done, click Export comments to download a saga.comments.json sidecar next
to the HTML. (Export is disabled in the hosted example
so it never writes a file — every other part of the review UX works.) Two commands consume it:
# Post everything as a single PENDING review on the PR (you submit it on GitHub).
saga comments push --comments saga.comments.json
# Emit the comments as JSON on stdout — for a coding agent to act on.
saga comments read --comments saga.comments.json
push uses the gh CLI: it finds the open PR for the sidecar's branch and creates one
pending review (inline → line comments, per-file → a note anchored to the file's first
changed line, overall → the review body). Nothing is submitted until you review and submit
it on GitHub. Requires the gh CLI, authenticated.
How it works
diff.pycomputesgit diff base...head(no checkout) and the commit list.model.pysplits the diff into stable-id hunks (h0, h1, …).generate.pysends the labeled diff + commits (+ optional intent) to the chosen model viainstructor, which returns chapters as schema-validated JSON. Coverage is re-validated in code — every hunk must belong to a chapter or generation fails.render.pyreconstructs each chapter's diff and inlines everything into one self-contained HTML file.
Not included (yet)
- Support for Local LLMs via ollama / LM Studio
- A GitHub Action to auto-generate saga on PRs.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file saga_cli-0.1.0.tar.gz.
File metadata
- Download URL: saga_cli-0.1.0.tar.gz
- Upload date:
- Size: 512.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1910ff550f951c24b98055e2ab046f65043c86a9ae0240c616b2b96d5ea8df7f
|
|
| MD5 |
a01a2312e4f021c32a9e08f1a373d6a6
|
|
| BLAKE2b-256 |
cecba965a971a06a9915720d9bfeffb09dafebeda5affd19d0aae6ac14ec47e0
|
File details
Details for the file saga_cli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: saga_cli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 31.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.22
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
225828d32f288de09363d18a7fae66c933adc08da8e313c6192f08c1f88a29ba
|
|
| MD5 |
19f2ce7b946ddb5ca79fb68de7a711f7
|
|
| BLAKE2b-256 |
9a0524db658fba348cf6a55e1fa69edd3e26e7db5fae1d2a6ca7af8c4cea115b
|