ghostwriter

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 18, 2026 License: MIT

README ΒΆ

πŸ‘» ghostwriter

See exactly what your AI agent changed β€” as a story β€” before you accept it.

ghostwriter reads the changes sitting in your working tree (whatever Claude Code, Cursor, Codex, or Aider just did), narrates them grouped by intent in plain English, flags the risky bits, and lets you accept or reject each intent with one keystroke β€” applying your rejections back to your files.

Reviewing agent diffs is the most dreaded part of agentic coding. ghostwriter turns the wall of diff into a short, skimmable review.

CI Release Go Reference Go Report Card



Try it in one line β€” no signup, no API key required:

go run github.com/agenticraptor/ghostwriter/cmd/ghostwriter@latest --print

Run it in a repo your agent just edited. With no key it groups changes with fast, offline heuristics. Add an API key (or point it at a local Ollama) and the same command narrates each intent in plain English.

In the screen above, pressing r on intent 4 and q to finish reverts just that migration from your working tree β€” keeping the retry logic, tests, and dependency bump you accepted. Nothing else is touched, and the reverted change is backed up so you can restore it any time.

Prefer plain output? ghostwriter --print narrates without the UI and never touches your files β€” perfect for CI, piping, or a quick skim:

πŸ‘» ghostwriter  review of payments-api
4 intents Β· 4 files Β· +43/βˆ’6 Β· anthropic claude-sonnet-4-6

 1  FEATURE   Add exponential-backoff retries to the payments client
    Wraps the charge call in a 3-try backoff loop and updates its 3 call sites.
    internal/pay/client.go  +24/βˆ’6

 2  TEST      Cover the new retry behavior
    Adds a table-driven test asserting three attempts before giving up.
    internal/pay/client_test.go  +12/βˆ’0

 3  DEPS      Bump Stripe SDK and add cenkalti/backoff
    go.mod  +5/βˆ’1
    β„Ή deps

 4  OTHER     Add idempotency-key migration
    db/migrations/008_add_idempotency_key.sql  +2/βˆ’0
    ⚠ migration

dependency changes:
  οΌ‹ github.com/cenkalti/backoff/v4 v4.3.0 (go)
  οΌ‹ github.com/stripe/stripe-go/v76 v76.25.0 (go)

Why

In 2026 the bottleneck of AI-assisted coding isn't writing code β€” it's reviewing it. Agents produce sprawling, multi-file diffs that are "almost right but not quite," and reading them hunk-by-hunk is exhausting and error-prone. Raw diff viewers (delta, difftastic) make the diff prettier; they don't tell you what the agent was trying to do or let you act on it.

ghostwriter is the missing review layer:

  • A story, not a diff. Related hunks across files are grouped into a handful of plain-English intents β€” "added retry logic," "updated 3 call sites," "bumped the Stripe SDK."
  • Risk-aware. Migrations, lockfile and dependency edits, CI/Docker changes, possible secrets, and large or test-removing deletions are flagged automatically β€” even with no model.
  • Act per intent. Accept the good parts, reject the rest with one key, and ghostwriter applies your rejections back to the working tree for you.
  • Agent-agnostic & local. It reads your git working tree, so it works with any tool that edits files. Your code never leaves your machine unless you choose a cloud model.

Features

  • πŸͺ„ Intent-grouped review of everything your agent changed, rendered beautifully in your terminal (or as Markdown / JSON / plain text).
  • ⌨️ One-key accept/reject in an interactive TUI β€” rejections are reverted from your working tree via a safe, checked git apply, and backed up first so you can always restore them.
  • ⚠️ Automatic risk flags: migrations, lockfiles, dependency manifests, CI/Docker, infra-as-code, possible secrets, and risky deletions.
  • πŸ“¦ Dependency change detection across npm, Go, pip, and Cargo.
  • 🧠 Bring your own model: Anthropic, OpenAI, or a fully-local Ollama β€” auto-selected from your environment.
  • πŸͺ« Works with zero config: no API key? You still get a deterministic, offline review with the heuristic risk flags intact.
  • πŸ†• Sees new files too β€” untracked files your agent created are part of the review (reject = delete).
  • πŸ“¦ Single static binary. No runtime, a handful of direct dependencies.

Install

go install
go install github.com/agenticraptor/ghostwriter/cmd/ghostwriter@latest
Pre-built binaries

Grab a binary for your OS/arch from the Releases page.

Homebrew (macOS / Linux)
brew install agenticraptor/tap/ghostwriter

Available once the Homebrew tap is published β€” see the note in .goreleaser.yaml to enable it.

From source
git clone https://github.com/agenticraptor/ghostwriter
cd ghostwriter
make install

Quickstart

# 1. Your agent just made a mess of edits. Review them interactively:
cd ~/code/my-project
ghostwriter

#    ↑/↓ to move, a/r to accept/reject each intent, q to finish.
#    Rejected intents are reverted from your working tree.

# 2. Just want the narrated summary (no UI, never modifies files)?
ghostwriter --print

# 3. Turn on AI narration (pick one):
export ANTHROPIC_API_KEY=sk-ant-...      # or OPENAI_API_KEY=sk-...
ghostwriter

# 4. Prefer 100% local? Run Ollama and use it instead:
ghostwriter --provider ollama --model llama3.1

# 5. Offline, instant, free β€” heuristic grouping with risk flags:
ghostwriter --no-ai --print

Usage

ghostwriter [flags]            Review pending changes (interactive in a terminal)
ghostwriter review [flags]     Same as above, explicitly
ghostwriter config <init|path|show>
ghostwriter doctor             Check your environment and configuration
ghostwriter version

Common flags:

Flag Description
-r, --repo <path> Repository to review (default .)
--against <ref> Compare the working tree against this ref (default HEAD)
--staged Review only staged changes (index vs HEAD)
--no-untracked Skip new, untracked files
--print Print the narrated review; never modifies files
-f, --format term Β· plain Β· markdown Β· json
-o, --output <file> Write the review to a file
--provider, --model Override the LLM provider/model
--no-ai Skip the model; use deterministic offline grouping
-y, --yes Apply rejections without the confirmation prompt
--no-color Disable colored output

Examples:

ghostwriter --print -f markdown -o review.md   # a shareable Markdown review
ghostwriter --no-ai                            # offline, instant, free
ghostwriter --staged                           # only what you've git-added
ghostwriter --print -f json | jq '.intents[].risks'   # machine-readable

How it works

                 β”Œβ”€ git diff HEAD ─────────────┐
working tree ─────                             β”œβ”€β–Ί parse into files + hunks ─┐
                 └─ untracked new files β”€β”€β”€β”€β”€β”€β”€β”˜                             β”‚
                                                                            β–Ό
                                              group into intents  ◄── LLM narrator
                                              (deterministic if no model)   β”‚
                                                                            β–Ό
                                          annotate with risk flags + dep changes
                                                                            β”‚
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β–Ό                               β–Ό
        interactive TUI                    render (term / md / json)
   accept / reject per intent                 (read-only)
                  β”‚
                  β–Ό
   git apply --reverse (checked)  ──►  rejected intents reverted; rest kept

Every line count and risk flag is recomputed from the real diff, so the numbers are trustworthy even when the narrative comes from a model. Rejections are applied with a checked git apply --reverse (a dry run must pass first), so a change that can't be cleanly reverted is reported rather than half-applied β€” ghostwriter never corrupts your tree.

See docs/how-it-works.md for the full pipeline.

Configuration

Configuration is optional. The file lives at ~/.config/ghostwriter/config.toml (run ghostwriter config path to see the exact location). Create a documented starter with:

ghostwriter config init
[ai]
provider = ""            # anthropic | openai | ollama (empty = auto-detect)
model = ""               # empty = provider default
enabled = true           # false = always use offline heuristics
max_diff_bytes = 14000   # caps tokens sent to the model

[review]
against = "HEAD"
include_untracked = true

API keys are never stored in the file β€” they're read from the environment (ANTHROPIC_API_KEY, OPENAI_API_KEY). See docs/configuration.md and docs/providers.md for the full reference.

Privacy

ghostwriter runs entirely on your machine. The only time anything leaves your computer is when you opt into a cloud model (Anthropic/OpenAI), in which case a size-capped sample of the diff is sent to that provider to write the narrative β€” and lines that look like secrets are redacted before they are sent. Want zero egress? Use --no-ai or --provider ollama and nothing ever leaves your laptop.

A few safety guarantees worth knowing: untracked symlinks are never followed (so a repo can't trick ghostwriter into reading files outside it), --against refs are validated so they can't be smuggled to git as options, and every rejection is backed up to <git-dir>/ghostwriter/rejected-*.patch before it is applied β€” restore any time with git apply. See SECURITY.md.

Contributing

Contributions are very welcome β€” see CONTRIBUTING.md. Good first issues include Cursor/Aider session awareness, more dependency ecosystems (Maven, Composer, RubyGems), richer risk heuristics, and a --html shareable report. Please also read our Code of Conduct.

License

MIT Β© ghostwriter contributors.

Directories ΒΆ

Path Synopsis
cmd
ghostwriter command
Command ghostwriter narrates the changes your AI coding agent made and lets you accept or reject each one before it lands.
Command ghostwriter narrates the changes your AI coding agent made and lets you accept or reject each one before it lands.
internal
buildinfo
Package buildinfo exposes version metadata injected at build time via -ldflags.
Package buildinfo exposes version metadata injected at build time via -ldflags.
cli
Package cli wires the ghostwriter command-line interface together.
Package cli wires the ghostwriter command-line interface together.
config
Package config loads ghostwriter's optional TOML configuration.
Package config loads ghostwriter's optional TOML configuration.
deps
Package deps detects dependencies added or removed by a change, across the common ecosystems (npm, Go, pip, Cargo).
Package deps detects dependencies added or removed by a change, across the common ecosystems (npm, Go, pip, Cargo).
gitdiff
Package gitdiff collects and parses the changes an AI agent (or anyone) has made to a git repository, and can reverse-apply a selected subset of those changes back to the working tree.
Package gitdiff collects and parses the changes an AI agent (or anyone) has made to a git repository, and can reverse-apply a selected subset of those changes back to the working tree.
intent
Package intent groups the raw hunks of a diff into human-meaningful "intents" β€” the handful of things an agent was actually trying to do β€” so a reviewer reads a short story instead of a wall of diff.
Package intent groups the raw hunks of a diff into human-meaningful "intents" β€” the handful of things an agent was actually trying to do β€” so a reviewer reads a short story instead of a wall of diff.
llm
Package llm provides a tiny, dependency-free client for the chat APIs of Anthropic, OpenAI, and Ollama.
Package llm provides a tiny, dependency-free client for the chat APIs of Anthropic, OpenAI, and Ollama.
render
Package render turns a Review into output: a styled terminal report (the default), Markdown, JSON, or uncolored plain text.
Package render turns a Review into output: a styled terminal report (the default), Markdown, JSON, or uncolored plain text.
review
Package review orchestrates a full ghostwriter review: it collects the diff, detects dependency changes, and groups the hunks into narrated intents β€” using a model when one is available and falling back to deterministic, offline grouping otherwise.
Package review orchestrates a full ghostwriter review: it collects the diff, detects dependency changes, and groups the hunks into narrated intents β€” using a model when one is available and falling back to deterministic, offline grouping otherwise.
risk
Package risk applies fast, deterministic heuristics to a changed file and flags the kinds of changes a reviewer should look at twice β€” migrations, dependency and lockfile edits, CI/Docker changes, possible secrets, and large or test-removing deletions.
Package risk applies fast, deterministic heuristics to a changed file and flags the kinds of changes a reviewer should look at twice β€” migrations, dependency and lockfile edits, CI/Docker changes, possible secrets, and large or test-removing deletions.
tui
Package tui implements ghostwriter's interactive review: a Bubble Tea program that shows each intent as a card with its underlying diff and lets you accept or reject it with a single keystroke.
Package tui implements ghostwriter's interactive review: a Bubble Tea program that shows each intent as a card with its underlying diff and lets you accept or reject it with a single keystroke.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL