# BudgetClaw - Local spend monitor for Claude Code

> Watches the JSONL session logs Claude Code writes under `~/.claude/projects/`, attributes each tool call's token cost to a project and git branch, and enforces budget caps by sending SIGTERM to the client process on breach. Pushes phone alerts via ntfy.

**Trust pledge:** Zero keys. Zero prompts. Zero latency added. BudgetClaw never touches API traffic. It is not a proxy. It only parses what Claude Code already writes to local disk.

- HTML page: https://roninforge.org/budgetclaw
- Source: https://github.com/RoninForge/budgetclaw
- Latest release: see https://github.com/RoninForge/budgetclaw/releases
- License: MIT

## Install

    curl -fsSL https://roninforge.org/get | sh

Or via Homebrew (macOS, Linux):

    brew install roninforge/tap/budgetclaw

Or build from source:

    git clone https://github.com/RoninForge/budgetclaw.git
    cd budgetclaw
    make build
    ./bin/budgetclaw version

Or via the Go toolchain:

    go install github.com/RoninForge/budgetclaw/cmd/budgetclaw@latest

The release artifact is a single statically-linked Go binary, ~5 MB, with zero runtime dependencies. Supported platforms: macOS arm64, macOS amd64, Linux amd64, Linux arm64, Windows amd64.

## Quick start

    # First-run: creates config + state directories, prints the paths it used.
    budgetclaw init

    # Cap the "myapp" project at $5/day across all branches; SIGTERM on breach.
    budgetclaw limit set --project myapp --period daily --cap 5.00 --action kill

    # Cap a specific feature branch at $1/day; warn only (no kill).
    budgetclaw limit set --project myapp --branch "feature/expensive" --period daily --cap 1.00 --action warn

    # Show today's spend, broken down by project and branch.
    budgetclaw status

    # Run the watcher in the foreground.
    budgetclaw watch

## Phone alerts via ntfy

    # 1. Install the ntfy app on your phone (iOS or Android).
    #    https://ntfy.sh/docs/subscribe/phone/

    # 2. Generate a secret topic name.
    TOPIC="budgetclaw-$(openssl rand -hex 12)"
    echo "Your topic: $TOPIC"

    # 3. Subscribe to that topic in the ntfy app.

    # 4. Configure budgetclaw.
    budgetclaw alerts setup --topic "$TOPIC"

ntfy.sh is the public free instance. You can also self-host ntfy and point BudgetClaw at it.

## Pricing audit

BudgetClaw runs a daily GitHub Action that hits Anthropic's `/v1/models` endpoint and cross-checks against LiteLLM's public per-token pricing table. If a new model appears, or if the price for an existing model has drifted, the workflow opens a GitHub issue against the BudgetClaw repo with the proposed update. New models are surfaced within 24 hours, so the embedded pricing table cannot silently lag a release.

This is the second-layer defense after the embedded pricing table itself, learned the hard way after v0.1.1 silently dropped Opus 4.7 events for a week before the bug was caught by a user.

## Configuration

BudgetClaw follows the XDG Base Directory Specification.

| Kind   | Path                                     |
| ------ | ---------------------------------------- |
| Config | `$XDG_CONFIG_HOME/budgetclaw/config.toml`|
| State  | `$XDG_STATE_HOME/budgetclaw/state.db`    |
| Data   | `$XDG_DATA_HOME/budgetclaw/`             |
| Cache  | `$XDG_CACHE_HOME/budgetclaw/`            |

Defaults when XDG variables are unset: `~/.config`, `~/.local/state`, `~/.local/share`, `~/.cache`.

Config format is **TOML**. A documented template ships at `examples/config.toml` in the repo.

## What it does NOT do

- Does not read prompts or responses. It reads only the `usage` and `cwd` fields of each JSONL line.
- Does not see your API key. It never opens a connection to Anthropic.
- Does not proxy, intercept, or modify requests. It is a local log reader.
- Does not kill arbitrary processes. It only SIGTERMs processes whose name matches `claude`.

## How it works

1. A background watcher tails `~/.claude/projects/*/*.jsonl` using inotify (Linux) and FSEvents (macOS).
2. Each log entry has `usage.*` token counts, `model`, `cwd`, and `timestamp`. BudgetClaw reads `cwd`, walks up to find `.git/HEAD`, and attributes the event to `{project, branch}`.
3. Token counts are priced against an embedded table covering Opus 4.1, Opus 4.5/4.6/4.7, Sonnet 4.x, Haiku 4.x, plus cache-read and cache-write multipliers. The cost is written to a local SQLite rollup.
4. On each new event the budget evaluator checks the active limit rules. If a cap is breached, BudgetClaw SIGTERMs the matching `claude` process and writes a lockfile to prevent silent relaunch.
5. A phone alert fires via ntfy with the breach context.

No data leaves the machine unless the user explicitly opts into a future hosted tier (none yet).

## Selected commands

    budgetclaw init                     # initialize config + state dirs
    budgetclaw limit set ...            # add or update a budget rule
    budgetclaw limit list               # show all configured limits
    budgetclaw status                   # spend by project and branch
    budgetclaw watch                    # foreground watcher
    budgetclaw alerts setup             # configure ntfy phone push
    budgetclaw unlock                   # remove lockfile after a kill
    budgetclaw pricing list             # show known models
    budgetclaw pricing rates            # show models with rates
    budgetclaw pricing diagnose         # scan JSONL for unknown models
    budgetclaw backfill                 # rescan JSONL idempotently
    budgetclaw backfill --rebuild       # wipe events + rollups, rescan

## Compatibility

- API-billed usage: exact dollar costs from token counts and published per-token pricing.
- Subscription plans (Pro, Max): token consumption tracked as a usage metric (no dollar cost since the bill is flat).

## Tutorial

For a step-by-step walkthrough that ends with the phone push firing on a real breach, see https://roninforge.org/tutorials/how-to-set-a-hard-spend-cap-on-claude-code.md.
