Skip to content
reposummary
Edit
On this page

#reposummary

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.

#Quick start

Install the binary, then summarize a repository. --window and --synthesis are both required and have no default, so every run states which span it covers and whether an LLM narrates it.

go install github.com/smm-h/reposummary@latest

reposummary summarize . --window today --synthesis none

npm (npm i -g reposummary) and PyPI (pip install reposummary) ship wrappers that download the same prebuilt binary.

#Documentation

The usage guide covers every window form, the three synthesis backends and the on-disk cache. The CLI reference is generated from the command declarations themselves, so it lists each flag exactly as the binary parses it.

#Packages

The work is split so that the expensive part stays optional: window parsing, git extraction and digesting are deterministic and cost nothing, rendering turns a digest into Markdown, and synthesis is the only stage that talks to a model. The cache sits underneath, keyed on the inputs that fully determine a journal, and prunes entries unread for 90 days.

#internal/window

Package window parses the --window flag into a resolved time/rev range spec.

A window is either a "daterange" (git --since/--until dates over a tip) or a "range" (an explicit git revision range like a..b, or the full history). Parsing is strict: an unrecognized form is a hard error, never a silent fallthrough.

#Spec

Go go
type Spec struct

Spec is a resolved time window.

#ParseWindow

Go go
func ParseWindow(spec string) (Spec, error)

ParseWindow resolves a window spec string. Forms are matched in order; an unrecognized form returns an error listing the supported forms.

#internal/gitdata

Package gitdata extracts commit metadata, file churn, and tags from a git repository over a resolved window. Everything is read deterministically from git subprocesses; no LLM tokens are spent here.

#FileChange

Go go
type FileChange struct

FileChange is a single file touched by a commit. Added/Deleted are 0 for binary files (git reports "-" for those).

#Commit

Go go
type Commit struct

Commit is a single commit's extracted metadata.

#Tag

Go go
type Tag struct

Tag is a git tag whose target resolves to a collected commit.

#GitBase

Go go
func GitBase(repo string) ([]string, error)

GitBase returns the git command prefix for a repo, or an error if the path is not a git repository. It supports normal repos (.git dir or a working git rev-parse) and the ".bare" convention (a bare repo stored under /.bare).

#Collect

Go go
func Collect(base []string, win window.Spec, tip string) ([]Commit, []Tag, error)

Collect gathers commits, their file churn, and matching tags for a window. Empty output yields empty slices and a nil error.

#internal/digest

Package digest turns raw git data into a structured, deterministic summary: commit classification, per-directory churn, issue references, author counts, and per-day activity. This is the free (no-LLM) narrative layer.

#Digest

Go go
type Digest struct

Digest is the structured summary of a window's activity.

#Classify

Go go
func Classify(c gitdata.Commit) string

Classify returns the change category for a commit: one of "breaking", "feature", "fix", or "other".

#CleanSubject

Go go
func CleanSubject(c gitdata.Commit) string

CleanSubject strips a Conventional Commits prefix if present, otherwise returns the subject unchanged. The result is trimmed.

#Build

Go go
func Build(commits []gitdata.Commit, tags []gitdata.Tag, win window.Spec, repoName string) Digest

Build assembles a Digest from collected commits and tags. Commits are assumed to be newest-first (git log order).

#internal/render

Package render turns a Digest (plus an optional LLM narrative) into the final Markdown journal, and produces the compact plain-text digest fed to the LLM prompt. It never imports synth, avoiding an import cycle.

#Markdown

Go go
func Markdown(d digest.Digest, narrative, version string) string

Markdown renders the full journal for a digest and narrative.

#DigestForLLM

Go go
func DigestForLLM(d digest.Digest) string

DigestForLLM produces a compact plain-text digest for the LLM prompt.

#internal/synth

Package synth turns a digest into prose via an explicitly-chosen LLM backend.

There is NO silent fallback: if the chosen backend fails at runtime, that is a hard error. The caller picks "none", "claude-cli", or "anthropic-api"; the choice is honored or it errors.

#PROMPT_TEMPLATE

Go go
const PROMPT_TEMPLATE = `You are writing a short journal entry narrating what happened in a software repository over a time window.

PROMPT_TEMPLATE instructs the model to write flowing prose from the digest.

#Synthesize

Go go
func Synthesize(d digest.Digest, mode, model string) (string, error)

Synthesize produces narrative prose for a digest using the chosen backend.

#internal/cache

Package cache is a deterministic on-disk journal cache. The journal for a fixed (firstSHA, lastSHA, synthesis, model, version, windowLabel) tuple is deterministic, so identical windows reuse cached output: cost is O(new commits), not O(window size). Storage is plain files; no database. Entries age out: a successful write prunes entries not read in the last 90 days, while a cache hit refreshes an entry's mtime so hot entries stay warm.

#Cache

Go go
type Cache struct

Cache is a filesystem-backed journal cache rooted at a directory.

#New

Go go
func New(dir string) (*Cache, error)

New opens (creating if needed) a cache at dir. An empty dir uses DefaultDir().

#DefaultDir

Go go
func DefaultDir() string

DefaultDir returns the default cache directory: $XDG_CACHE_HOME/reposummary, or ~/.cache/reposummary.

#MakeKey

Go go
func MakeKey(firstSHA, lastSHA, synthesis, model, version, windowLabel string) string

MakeKey returns the sha256 hex of the join of the cache inputs. The journal is fully determined by this tuple.

windowLabel is part of the key because a zero-commit window has empty firstSHA/lastSHA: without the label, every distinct empty window would collapse to the same key and a cached "no activity" journal could be served under the wrong window heading.

#Cache.Get

Go go
func (c *Cache) Get(key string) (string, bool)

Get reads a cached journal by key. The second return is false on a miss. On a hit the entry's mtime is refreshed so that frequently-read entries survive age-based pruning. A failed touch is non-fatal (the read still succeeds).

#Cache.Set

Go go
func (c *Cache) Set(key, md string) error

Set writes a journal to the cache under key, then opportunistically prunes entries older than maxAge. Pruning is best-effort housekeeping: its failures are swallowed and never turn a successful write into an error.

More tools from this site

  • claudestream Drive Claude Code from Python: run it as a subprocess and read its output as typed events, with async and sync sessions, sandbox policies, and tools you define in Python
  • claudewheel A TUI Claude Code Launcher that lets you have more than one profile, manage sessions lifecycle, pick the exact CC version, model to use (even older unlisted ones), pick which GitHub account to use, etc.
  • dirstat Fast, single-binary directory statistics CLI: every file under a tree grouped by format, with counts, sizes, and lines of code, as a colored terminal table or as JSON
  • fastware A batteries-included ASGI framework: msgspec JSON, a managed Granian server, dependency injection, SSE, WebSockets, auth, and a test client
  • go-toml-edit Zero-dep TOML editing library for Go with comment preservation
  • howmuchleft The fastest Claude Code statusline: context window, 5-hour, and weekly limit usage as three customizable gradient bars, rendering in about 6 ms
  • orxtra
  • pgdesign
  • predraw Declarative rendering pipeline: describe a scene in JSON and get SVG, PNG and WebP out, with light and dark style tokens, reusable components and text converted to path outlines
  • rlsbl Release orchestration and project scaffolding CLI that bumps versions, validates a structured JSONL changelog, tags only the commit CI verified, and publishes to npm, PyPI, Go and more
  • safegit git wrapper CLI that gives each commit its own temporary index and retries ref updates on conflict, so concurrent agents share one repository
  • saferm Command-line replacement for rm that archives every deletion with a mandatory reason and the context it ran in, so deleted files can be listed, inspected and restored
  • selfdoc Static Site Generator that builds a project's documentation site directly from its source code, so the docs can never drift from the code they describe, with SEO/AEO, first-class blog, search, and cross-project linking built in
  • strictcli
  • stricttest An always-on test-isolation floor: a pytest plugin and a Go env-hygiene module that make a test suite structurally unable to reach real credentials, the real HOME, the network, or the development repository.
  • wesktop A Python framework that turns an ASGI web app into a desktop application, serving it from a local Granian server and displaying it in a native OS window via pywebview
Search