Log what you ship.
A single-binary CLI that crawls your repos, summarizes the work in your own voice with the AI of your choice, and stores it where you own the data.
what it is
shiplog watches your code directory, groups commits into bundles (per‑day, per‑week, per‑commit — your call), runs each bundle through an AI to write a short, human summary in your voice, and stores the result as a changelog.json in ~/.shiplog/. Sinks publish copies elsewhere — Cloudflare R2, S3, a CSV mirror for spreadsheets — but the local file is the source of truth.
It’s a single Go binary. No daemon required (though one is included). No SaaS, no telemetry, no account. Bring your own AI key (Anthropic, Gemini, OpenAI, or Ollama for local).
install
macOS & Linux, amd64 & arm64. Drops shiplog in ~/.local/bin (or /usr/local/bin with sudo). The script verifies a sha256 against the published checksums before installing. macOS binaries are signed and notarized so Gatekeeper doesn’t prompt.
Pin a version with SHIPLOG_VERSION=v0.1.0, change the install dir with SHIPLOG_PREFIX=/path. Confirm with shiplog --version.
first run
One wizard. Pick your identity (the git email that counts as “you”), the directory shiplog should crawl, and the AI provider it should call.
the four commands you’ll actually use
shiplog scan
Walks every tracked repo since the last scan, groups new commits, summarizes them, writes to ~/.shiplog/changelog.json, and fans out to any configured sinks. Cursor-driven by default — only new work gets summarized.
Useful flags:
--since=7d— only commits in the last 7 days--repo=~/code/foo— limit to one repo--force— ignore cursors and re-walk the full range (idempotent thanks to bundle-id dedup)--group=per-day|per-week|per-commit— override granularity for this run--dry-run— show what would be summarized without calling the AI--dump=DIR— write each bundle’s prompt to a file instead of calling the AI
shiplog log
Browse what you’ve shipped. Interactive on a TTY, flat list when piped.
Highlight a row and press e to edit, d to delete. / filters by project, tag, or note text.
shiplog add
Manual entry — for shipping things that aren’t commits (a launch, a talk, a write-up). Same shape as the AI-generated entries, written to the same changelog.
shiplog status
What does shiplog know about right now? One row per tracked repo, with last-scan age and pending work.
configuration
Everything lives in ~/.shiplog/:
config.json— identities, code roots, AI provider, sinks, granularity overrideschangelog.json— the source of truth (this is whatlogreads)state.json— per-repo cursors so scans only see new workprojects.json— project name + public URL per repovoice.md— the prompt fragment that shapes how the AI soundsignore.conf— gitignore-style patterns excluded from diffs (per repo or global)
shiplog ai
Pick your provider, paste your key. Keys go to the macOS Keychain — never to config.json.
shiplog sink
Sinks publish your changelog elsewhere. The local file is always written; sinks are extras.
Supported today: file, csv, r2, s3. CSV writes a UTF-8 BOM + CRLF Excel-friendly mirror. Webhook + SFTP are planned.
shiplog repo
Decide what gets crawled. Anything under your roots is auto-discovered; repo add tracks something outside, repo ignore excludes one.
what shiplog won’t do
- Send your code anywhere you didn’t configure. The AI provider you pick is the only network call (and you can swap it for local Ollama).
- Store secrets in
config.json. Every credential goes to the Keychain. - Touch your repos. Read-only — no checkouts, no fetches, no writes.
- Lock you in. The changelog is a plain JSON array. Take it and go.
operating it
Run shiplog daemon to scan on a schedule (default every hour). Or run it as a launchd / systemd unit. Or wire it into a git post-push hook if you only want manual triggers. The CLI is the same in every mode.
If anything looks off, shiplog doctor checks the lot — config, AI key, Keychain, git, sinks — and tells you exactly what’s broken.