Content
# Rudder
**Rudder records the prompts you give your AI coding assistants and turns a day's
worth of them into a readable summary of what you actually worked on.**
Rudder is a tool for understanding what you actually do when you code with AI.
AI coding tools make it easy to generate, edit, review, and ship code quickly,
but they can also make your work hard to see. You can spend hours prompting,
reading, accepting, rejecting, rewriting, testing, and steering the tool without
actually feeling like you truly produced the eventual code output.
The goal of rudder is to give the person doing the work a truthful record
of their own AI-assisted coding process so they can understand their decisions,
improve their workflow, and build better software.
It installs lightweight hooks into **Claude Code** and **Codex** that quietly log
every prompt you send to a local SQLite database.
## Quickstart
```bash
npm install -g @vivekyy/rudder # puts `rudder` on your PATH
rudder init # create the database and install the hooks
```
Then just use Claude Code and/or Codex as you normally would — every prompt is
logged automatically. Whenever you want to see what you've been doing:
```bash
rudder start # live dashboard: correction rate + category breakdown, updated as you work
rudder stats # the same numbers, printed to the terminal
rudder digest # write a readable Markdown summary of the day to ./digest.md
```
Requires Node.js ≥ 23.6 and at least one of `claude` / `codex` on your `PATH`.
See [Install](#install) and [Commands](#commands) for the full details.
## Why
Rudder starts from a simple problem: When I code with AI, I feel like I haven't
done anything except watch my agent code for me.
The final diff tells only part of the story. It does not show how I got there,
where I changed direction, what I trusted, what I rewrote, or what I tested.
Rudder exists to make that path visible.
The important question is not "Did AI write this?" It is "What did the human
do?"
## How it works
```
┌──────────────┐ UserPromptSubmit hook ┌─────────────────┐
│ Claude Code │ ────────────────────────▶ │ │
└──────────────┘ │ ~/.rudder/ │
┌──────────────┐ notify program │ rudder.db │
│ Codex │ ────────────────────────▶ │ (SQLite) │
└──────────────┘ └────────┬────────┘
│ rudder digest
▼
reads the day's prompts,
pipes them to `claude -p`
(or `codex exec`) and writes
./digest.md
```
- **Local only.** Everything lives in `~/.rudder/rudder.db`. Nothing is uploaded;
the digest is generated by the LLM CLI you already use. Your data stays yours.
- **Non-intrusive.** The hooks are fail-safe — if rudder ever errors, it logs to
stderr and exits `0` so it never blocks or breaks Claude Code or Codex.
## Requirements
- **Node.js ≥ 23.6**
- **Claude Code** (`claude`) and/or **Codex** (`codex`) on your `PATH`. You only
need one of them; rudder records whichever is installed and uses whichever is
available to generate the digest.
## Install
```bash
npm install -g @vivekyy/rudder # puts `rudder` on your PATH
rudder init # creates the database and installs the hooks
```
`rudder init`:
1. Creates `~/.rudder/rudder.db`.
2. Adds a `UserPromptSubmit` hook to `~/.claude/settings.json`.
3. Adds a top-level `notify` program to `~/.codex/config.toml`.
Existing config files are backed up to `*.rudder-bak` before being modified, and
the command is idempotent — running it twice won't duplicate the hooks.
### From source
```bash
git clone https://github.com/Vivekyy/Rudder.git rudder && cd rudder
npm install # install dependencies
npm run build # compile to dist/ (npm link's `rudder` bin points here)
npm link # puts `rudder` on your PATH
rudder init
```
> If you don't want to `npm link`, you can run rudder directly with
> `node /path/to/rudder/bin/rudder.ts <command>`. `rudder init` always wires the
> hooks to an absolute path, so they keep working regardless of your `PATH`.
## Upgrade
```bash
npm update -g @vivekyy/rudder # or: npm install -g @vivekyy/rudder@latest
```
The hooks point at the global install's absolute path, which is stable across
upgrades, so there's nothing to re-wire. Re-run `rudder init` only after an
upgrade whose notes say the hook format changed (it's idempotent and safe to
re-run). If you installed from source, upgrade with `git pull && npm install`
instead — the `npm link` symlink picks up the new code with no rebuild.
## Commands
| Command | Description |
| --- | --- |
| `rudder init` | Create the database and install the Claude Code + Codex hooks. |
| `rudder start [options]` | Open the live dashboard app; updates as you work. |
| `rudder stats [options]` | Print today's correction rate and category breakdown. |
| `rudder digest [options]` | Summarize a day's prompts into a Markdown digest. |
| `rudder tag [options]` | Classify untagged prompts and print the day's stats. |
| `rudder help` | Show usage. |
| `rudder hook claude` | *(internal)* Record a Claude Code prompt — invoked by the hook. |
| `rudder hook codex` | *(internal)* Record a Codex turn — invoked by `notify`. |
### `rudder start`
Starts a small local server (on `127.0.0.1`, port `41789` — override with
`RUDDER_PORT`). While it runs, each new prompt is classified out-of-band by your
`claude`/`codex` CLI and the dashboard updates live with your correction rate and
category breakdown for today.
The dashboard is a **standalone app** (a PWA):
- The **first** time, `rudder start` opens a small installer page — click **Install
app** (or, in Safari, `File → Add to Dock`) to add rudder to your dock with its
own icon and no browser chrome. The installed window auto-sizes to its content.
- **After** it's installed, `rudder start` launches the app directly (no browser
tab). The app loads from the running daemon, so keep `rudder start` running.
If you'd rather not install anything, open `http://127.0.0.1:41789/` in a browser.
### `rudder stats`
Prints the same correction rate and category breakdown as the dashboard, on the
command line:
```
$ rudder stats
rudder — 2026-06-18
26 prompts · 3 git chores skipped · 23 counted
You said no to your AI 12% of the time (3 of 25 yes/no reactions)
Architecting 30% █████░░░░░░░░░░░ 7
Tuning 17% ███░░░░░░░░░░░░░ 4
Bugfixing 9% █░░░░░░░░░░░░░░░ 2
Housekeeping 43% ███████░░░░░░░░░ 10
```
It classifies any not-yet-tagged prompts first (pass `--no-tag` for an instant
read of only what's already classified, and `--date YYYY-MM-DD` for another day).
| Option | Default | Description |
| --- | --- | --- |
| `--agent claude\|codex` | `claude`, else `codex` | Which LLM classifies prompts. |
| `--no-tag` | off | Show only already-classified prompts; skip the tagging pass. |
| `--date YYYY-MM-DD` | today (local) | Day to report. |
It's safe to leave running and safe to run twice (a second `rudder start` just
re-opens the window). Nothing is required for the digest to work — if the daemon
isn't running, prompts are simply classified the next time you run `rudder start`,
`rudder tag`, or `rudder digest`.
### `rudder digest`
| Option | Default | Description |
| --- | --- | --- |
| `--date YYYY-MM-DD` | today (local time) | Which day to summarize. |
| `--agent claude\|codex` | `claude`, else `codex` | Which LLM CLI generates the digest. |
| `--out PATH` | `./digest.md` | Where to write the digest. |
Examples:
```bash
rudder digest # today → ./digest.md
rudder digest --date 2026-06-16 # a specific day
rudder digest --agent codex --out ~/digests/today.md
```
The digest produces a Summary (with your "said no to your AI" rate); Architecting,
Tuning, Bugfixing, and Housekeeping breakdowns (each with the share of prompts and
the top things you worked on); Highlights; and Open threads. The percentages are
computed from the per-prompt tags rudder stores (see below), so they match the
`rudder start` dashboard exactly — the LLM only writes the prose around them.
## Data & privacy
All prompts are stored in plaintext in `~/.rudder/rudder.db` (schema: timestamp,
local day, source, session id, working directory, project, prompt text, model,
and the raw hook payload). A companion `prompt_tags` table holds each prompt's
computed category and reaction (the data behind the dashboard and digest stats).
Classification uses the same local `claude`/`codex` CLI as the digest — nothing
is sent anywhere else. To wipe everything, delete `~/.rudder/`. To stop recording,
remove the hook from `~/.claude/settings.json` and the `notify` line from
`~/.codex/config.toml`.
Set `RUDDER_HOME` to override the storage location (used by the test suite). The
hooks honor `RUDDER_DISABLE` — rudder sets it on the agent it spawns for `rudder
digest`, so the digest's own prompt is never recorded.
## Uninstall
1. Remove the `UserPromptSubmit` entry from `~/.claude/settings.json`.
2. Remove the `notify = [...]` line from `~/.codex/config.toml`.
3. `rm -rf ~/.rudder`.
## Development
```bash
npm install
npm run typecheck # tsc --noEmit
npm test # node --test
npm run build # compile to dist/ (the only code published to npm)
```
Source lives in `src/` and the CLI entry point is `bin/rudder.ts`. In development
these `.ts` files run directly via Node's native type stripping; `npm run build`
compiles them to `dist/`, which is what gets published and what the installed
`rudder` bin runs.
Connection Info
You Might Also Like
No recommendations available