Turn a git repository's history into a Markdown journal: pick a time window or revision range and get a readable digest of what changed, optionally narrated by an LLM.
It is built for developers and AI agents who need a readable account of what a repository has been doing without walking the log commit by commit. Everything in the journal -- commit classification, per-directory churn, issue references, authors and tags -- is extracted deterministically from git, so LLM tokens are spent only on the optional prose layer.
- Go:
go install github.com/smm-h/reposummary@latest - npm:
npm i -g reposummary - PyPI:
pip install reposummary
(The npm and PyPI packages download the prebuilt binary.)
reposummary summarize <repo> --window <window> --synthesis <backend>
<repo> defaults to the current directory. --window and --synthesis are required (no default).
# Deterministic journal for today, no LLM
reposummary summarize . --window today --synthesis none
# A fixed one-month span from a date
reposummary summarize . --window 2026-06-11+1month --synthesis none
# The whole history, narrated via the local claude CLI
reposummary summarize . --window all --synthesis claude-cli --model haiku
| Command | Description |
|---|---|
summarize |
Extract a git repository's activity over a time window and render a Markdown journal, optionally narrated by an LLM. |
today— commits since local midnight todayyesterday— the previous calendar dayweek/7d— the last 7 daysmonth/30d— the last 30 daysall/start/start..now— the full history<YYYY-MM-DD>+<N><unit>— a fixed span from a date (e.g.2026-06-11+1month)<refA>..<refB>— an explicit git revision range (e.g.v0.1.0..HEAD)
An unrecognized window is a hard error, never a silent fallthrough. See the usage guide (.stricttools/docs/guide.md) for details.
--synthesis selects the prose backend explicitly — there is no silent fallback. A chosen backend that fails is a hard error, not a quiet downgrade.
none— no LLM; the journal is the deterministic extraction only.claude-cli— shells out toclaude -p --model <model>(no API key needed).anthropic-api— calls the Anthropic Messages API; requiresANTHROPIC_API_KEYin the environment (no implicit default).
--model selects the model id (default haiku). Short aliases (e.g. haiku) and full model ids (e.g. claude-haiku-4-5-20251001) both work — the model string is passed through to the backend verbatim.
A journal for a fixed (firstSHA, lastSHA, synthesis, model, version, windowLabel) tuple is deterministic, so identical windows reuse cached output on disk. The cache key is a sha256 of those inputs; the window label is included so that distinct empty windows (both SHAs empty) never share an entry. Entries are plain Markdown files under $XDG_CACHE_HOME/reposummary (or ~/.cache/reposummary). Repeated summaries therefore cost O(new commits), not O(window size). Entries age out on their own: each write opportunistically prunes entries not read in the last 90 days, and every cache hit refreshes an entry's timestamp so frequently-used journals stay warm. Disable with --no-cache, or point elsewhere with --cache-dir.