All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
v1.7.32 - 2026-08-25
- pricing: refresh vendored ai-price-index to
v2026.08.25-2d837b1. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.31 - 2026-08-24
- pricing: refresh vendored ai-price-index to
v2026.08.24-7843041. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.30 - 2026-08-24
- pricing: refresh vendored ai-price-index to
v2026.08.24-d74b1e2. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.29 - 2026-08-23
- pricing: refresh vendored ai-price-index to
v2026.08.23-5f05c60. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.28 - 2026-08-22
- pricing: refresh vendored ai-price-index to
v2026.08.22-665c2ca. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.27 - 2026-08-21
- pricing: refresh vendored ai-price-index to
v2026.08.21-e63cc3c. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.26 - 2026-08-21
- pricing: refresh vendored ai-price-index to
v2026.08.21-dcddd30. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.25 - 2026-08-20
- pricing: refresh vendored ai-price-index to
v2026.08.20-fcf9c9e. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.24 - 2026-08-19
- pricing: refresh vendored ai-price-index to
v2026.08.19-3ab5df2. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.23 - 2026-08-19
- pricing: refresh vendored ai-price-index to
v2026.08.19-5b2a925. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.22 - 2026-08-18
- pricing: refresh vendored ai-price-index to
v2026.08.18-44074a7. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.21 - 2026-08-17
- pricing: refresh vendored ai-price-index to
v2026.08.17-534dbb5. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.20 - 2026-08-16
- pricing: refresh vendored ai-price-index to
v2026.08.16-0fef063. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.19 - 2026-08-15
- pricing: refresh vendored ai-price-index to
v2026.08.15-1c3e485. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.18 - 2026-08-14
- pricing: refresh vendored ai-price-index to
v2026.08.14-ff17de8. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.17 - 2026-08-13
- pricing: refresh vendored ai-price-index to
v2026.08.13-2bcfb00. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.16 - 2026-08-12
- pricing: refresh vendored ai-price-index to
v2026.08.12-982c705. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.15 - 2026-08-11
- pricing: refresh vendored ai-price-index to
v2026.08.11-06759c3. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.14 - 2026-08-10
- pricing: refresh vendored ai-price-index to
v2026.08.10-5d9dcef. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.13 - 2026-08-09
- pricing: refresh vendored ai-price-index to
v2026.08.09-f7c9e5b. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.12 - 2026-08-09
- pricing: refresh vendored ai-price-index to
v2026.08.09-e2736ef. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.11 - 2026-08-08
- pricing: refresh vendored ai-price-index to
v2026.08.08-44c3043. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.10 - 2026-08-07
- pricing: refresh vendored ai-price-index to
v2026.08.07-e80fd19. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.9 - 2026-08-06
- pricing: refresh vendored ai-price-index to
v2026.08.06-b9c554c. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.8 - 2026-08-05
- pricing: refresh vendored ai-price-index to
v2026.08.05-7d5fd37. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.7 - 2026-08-04
- pricing: refresh vendored ai-price-index to
v2026.08.04-27473de. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.6 - 2026-08-03
- pricing: refresh vendored ai-price-index to
v2026.08.03-1f4f712. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.5 - 2026-08-02
- pricing: refresh vendored ai-price-index to
v2026.08.02-caea47c. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.4 - 2026-08-01
- pricing: refresh vendored ai-price-index to
v2026.08.01-0a70567. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.3 - 2026-07-31
- pricing: refresh vendored ai-price-index to
v2026.07.31-67139bb. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.2 - 2026-07-30
- The published price table's detached signature went missing from the server between 09:20 and 10:47 UTC on 2026-07-30. During that window a client with
pricing auto onrefused every update. Nothing was lost and no recorded spend was affected: clients did exactly what they are built to do, kept the price table compiled into the binary, and carried on. Prices simply could not advance, and because that failure is silent by design there was no symptom to notice. The cause was outside this binary, in a second publishing path that deleted the signature, and it is fixed at the source. A daily check now verifies the live published signature against the key compiled into this release, so a recurrence surfaces within a day instead of whenever someone happens to look.
- When a downloaded price table is refused, the log now names the check that refused it (
gate=rate_out_of_range,gate=rollback,gate=model_loss, and so on) rather than only reporting that a plausibility check failed. A refusal should be diagnosable: a code naming a unit error in the published data says the problem is ours to fix, not yours. - Hardening for the price guard, with no change to how pricing behaves: a pinned corpus of hostile bundles each required to be refused by a named check, the shared golden vectors run through all three routes a price can reach a lookup (compiled in, fetched, and re-read from cache) to prove they cannot disagree, a canary that measures rather than documents the promise that the default posture makes no network requests, and a lint rule confining network access to the three packages that have a reason to make a request.
v1.7.1 - 2026-07-30
- pricing: refresh vendored ai-price-index to
v2026.07.30-6627801. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.7.0 - 2026-07-30
budgetclaw pricing auto onopts in to refreshing the price table over the network, so a model released after your build starts pricing without waiting for an upgrade. Off by default, and fully offline operation stays a first-class supported mode. Turning it on prints exactly what happens: an HTTPS GET for a public price file, with no key, no token, no identifier, no usage data, no query string and no cookie. Your API traffic is still never touched, and nothing is added to the path of a Claude Code call.budgetclaw pricing refreshfetches now;--forcefetches once without changing the saved setting.- A downloaded table is only used if its Ed25519 signature verifies against a key compiled into this binary AND the contents pass plausibility checks: rates within a sane range per million tokens, no jump of more than tenfold on a model you already price, no mass loss of models, and no going backwards to an older dataset. Anything else is discarded and the table already in force is kept, which is stale but never wrong. You can verify the same file yourself with the standard
minisigntool; see the ai-price-index README. budgetclaw watchchecks about once a day on a jittered schedule, and immediately (rate limited) when it meets a model it cannot price, so a new model shows as unpriced for about a minute rather than until your next upgrade. The check never runs on the event path: rates are read from memory through a single atomic load.budgetclaw pricing provenancenow reports the data date and whether the rates in force came from this binary or from a verified download.
v1.6.1 - 2026-07-30
- pricing: refresh vendored ai-price-index to
v2026.07.30-d31d0e2. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
budgetclaw backfill --rebuildnow refuses to run when it would destroy history the logs can no longer replay, and says exactly what would be lost. A rebuild wipes the database and replays from Claude Code's session logs, but those are pruned after roughly a month while the database keeps everything, so a rebuild could silently discard months of spend. Pass--forceif you accept losing it. When the logs do cover the database, the rebuild proceeds as before and reports the range it checked.- A
--rebuildpointed at a missing log directory no longer wipes the database before discovering there is nothing to replay. The directory is opened first. --rebuild's documented purpose is narrowed to repairing a database written by a pre-dedupe binary. A pricing correction no longer needs it, because stored events reprice in place.
v1.6.0 - 2026-07-29
- An event whose model the pricing table does not know is now stored instead of discarded. It keeps its full token counts with a cost of zero, so a model released after your build no longer costs you the record of what you spent. Previously the event was dropped and the only way to recover it was to re-scan Claude Code's session logs, which are pruned after roughly a month.
- Those stored events are priced automatically as soon as the pricing table learns the model. The pass runs at the start of
watch,statusandbackfill, prices each event at the rate that was effective on its own date, and reports what it recovered:repriced 900 previously unpriced event(s): $63.00 recovered. It works entirely from the stored rows, so it recovers spend whose original logs are long gone. There is nothing to run and no flag to remember: upgrade, and the next command settles it. budgetclaw statusmarks any figure covering unpriced events with a trailing+, meaning "at least this much", and lists each affected model with its event count, token volume and first-seen date. It never estimates a dollar value for a model it has no rate for. When nothing is unpriced, the output is unchanged.
budgetclaw backfillnow reportsstored unpriced Nwhere it previously reportedskipped N, because those events are no longer skipped.
- Upgrading is enough. The database migration is additive and runs on first use, every event already recorded stays priced exactly as it was, and dollar totals do not move: an unpriced event contributes zero until it is priced, so budget caps and Guard Mode behave as before. No
backfill --rebuildis needed.
v1.5.2 - 2026-07-29
- pricing: refresh vendored ai-price-index to
v2026.07.29-ca6c5bd. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.5.1 - 2026-07-25
- pricing: refresh vendored ai-price-index to
v2026.07.25-6d94c00. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
budgetclaw prs on/off/status: opt in to cost-per-PR. With it on,budgetclaw syncreads local git for the repos you already have Claude Code spend in and sends content-free pull-request metadata (the PR number, base branch, commit count, and added/removed line counts) so Goei can show usage value per merged PR, per commit, and per in-flight branch. Off by default: git is a new data source beyond the Claude Code logs, so it is never read until you turn it on. Never a commit message, a title, or a line of code leaves your machine, and you can see exactly what would be sent withbudgetclaw sync --show-payload.- Squash-merged PRs are scoped to your own git identity, so opting in never sends a teammate's PR metadata.
v1.4.1 - 2026-07-22
- pricing: refresh vendored ai-price-index to
v2026.07.22-a1292a4. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
budgetclaw team join: join a Goei team from inside a repo whose lead has committed a.budgetclaw.tomlpointer. The command requests to join, prints a short code plus a URL to confirm in your browser, and finishes automatically once a team owner or admin approves your device, saving the device token and running a first sync. No API keys change hands, and no credential ever lives in the repo: the committed file holds only a team name, endpoint, and a revocable join code that authorizes a request to join, never access to any data. A repo-readable code never auto-admits anyone; a human always approves the device. If the pointer targets a non-default host, the host is shown before anything is contacted.budgetclaw team link: write the committed.budgetclaw.tomlpointer for a repo from a join code you copy out of Goei (Link a repo), for leads who prefer the terminal to the web panel.budgetclaw statusshows a one-line notice, at most once per repo every 14 days, when the current repo has a team pointer but this machine has not joined. Setprompts = falsein the pointer's[goei]section to silence it. The line is generated purely by reading the committed file; a non-member never makes a network call.
- Guard Mode: enforce your Goei team's budget caps locally. Opt in with
budgetclaw guard on;budgetclaw watchthen fetches the caps your team owner set (over your existing device token) and enforces them on this machine, even offline. A per-developer or team cap sums your whole machine's spend; a per-project cap sums that project. Only caps that are exactly computable on your machine can kill (SIGTERM the runaway, plus a lockfile that names the rule, who set it, and spend versus cap); team-aggregate caps warn only and show how stale the team figure is. It polices agents, not developers: a kill stops a runaway session, and every enforcement event that syncs back is content-free (rule id, amount, cap, machine, timestamp; never prompts or code). A device never obeys a server until you turn Guard Mode on. budgetclaw guard on/off/statusmanage the opt-in and show which caps are cached.budgetclaw limit listgains a SOURCE column so local rules and team (goei) caps are distinguishable at a glance.
budgetclaw syncnow carries any queued Guard Mode audit events up with your spend and refreshes the cached policy set from the response. Nothing new leaves your machine beyond the content-free enforcement events above.
v1.2.1 - 2026-07-20
- pricing: refresh vendored ai-price-index to
v2026.07.20-cb66f43. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
budgetclaw sync --show-payloadprints the exact JSON request body thatsyncwould POST to Goei and sends nothing. It needs no device token, so you can audit every byte that would leave your machine (daily cost and token rollups, model, project, branch, and machine label; never prompts or code) against Goei's published ingest contract before ever connecting an account.budgetclaw sync --savepersists the resolved device token (and any explicit--endpoint/--machine) to the config file so later syncs run with no flags. Empty arguments are preserved, so saving just a token keeps an existing endpoint or machine.
v1.1.4 - 2026-07-10
- pricing: refresh vendored ai-price-index to
v2026.07.10-cc35e0b. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.1.3 - 2026-07-09
- pricing: refresh vendored ai-price-index to
v2026.07.09-43f905c. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.1.2 - 2026-07-08
- pricing: refresh vendored ai-price-index to
v2026.07.08-8eaf41d. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
- Discovery and docs: expanded the plugin keywords and refreshed the README and spend skill copy with high-intent Claude Code cost-tracking terms (cost per project, per branch, per model; ccusage alternative), and documented that
syncfeeds a hosted team dashboard (Goei) with re-priced 12-month history across every machine and teammate. Metadata and copy only; no CLI behavior change.
Migration: existing Goei-synced users will see a one-time double-count over the first re-synced window (default 30 days) after upgrading. Because
syncnow stamps every record with a machine identity (defaulting to your hostname) and the Goei server keeps per-machine rows separate, it no longer deletes the pre-machine untagged rows it stored before (that would discard data once you sync from more than one machine). So for the re-synced window, the old untagged rows and the new machine-tagged rows briefly coexist and add up. New installs are unaffected. The double-count is a one-time step, not an ongoing error: it does not grow with each sync, it self-limits as older days age out of the sync window, and it clears fully once every machine on the account has upgraded and re-synced, after which the stale untagged rows can be removed on the Goei side. During the transition window it may trip a single spurious budget alert.
budgetclaw syncnow stamps a per-machine identity on every spend record it sends to Goei (newmachinefield,omitempty), so the Goei server keeps two machines' rollups from colliding instead of merging the same (day, project, branch, model) from a laptop and a desktop into one row. The value resolves as--machineflag, then theGOEI_MACHINEenv var, then[goei].machinein config, and finally falls back to the OS hostname. The hostname is not a secret, so sync stays zero-key and zero-prompt; the overrides exist for anyone who would rather send a custom label. Backward compatible: the field is additive and omitted when empty, so an older Goei server simply ignores it.--dry-runnow also reports the machine identity being sent.
v1.0.8 - 2026-07-01
- pricing: refresh vendored ai-price-index to
v2026.07.01-b9ae0e4. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.0.7 - 2026-07-01
- pricing: refresh vendored ai-price-index to
v2026.07.01-c31b7c3. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.0.6 - 2026-06-29
- pricing: refresh vendored ai-price-index to
v2026.06.29-f7199e3. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.0.5 - 2026-06-24
- pricing: refresh vendored ai-price-index to
v2026.06.24-a997f8b. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.0.4 - 2026-06-22
- pricing: refresh vendored ai-price-index to
v2026.06.22-becbe72. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.0.3 - 2026-06-17
- pricing: refresh vendored ai-price-index to
v2026.06.17-4ab5db2. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.0.2 - 2026-06-17
- pricing: refresh vendored ai-price-index to
v2026.06.17-2a11475. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.0.1 - 2026-06-16
- pricing: refresh vendored ai-price-index to
v2026.06.16-5063362. Point-in-time pricing means a new rate adds a new interval and does not change rows already priced at their then-effective rate, so nobackfill --rebuildis needed.
v1.0.0 - 2026-06-16
Migration: after upgrading, run
budgetclaw backfill --rebuildonce. v1.0.0 re-prices every event at its then-effective rate. Existing rollups were priced at whatever the table said when the event was first seen; the rebuild wipes and replays so every historical event reflects the rate that was in effect on its own timestamp.
- Pricing is now sourced from the vendored, pinned ai-price-index dataset (tag
v2026.06.16-662bfa9) instead of a hand-maintained rate table. The dataset's anthropic artifacts are committed underinternal/pricing/index/**(with sha256 provenance) and code-generated intointernal/pricing/table_gen.goat build time. Still zero-key, zero-latency, and fully offline: the price table is embedded in the binary, there is no runtime network access. Cache-write/read multipliers stay engine constants. - Point-in-time pricing. Each event is now priced at the rate that was in effect on its own timestamp, not at today's rate. An event recorded while a model was on an older tier is priced at that older tier, so historical cost stays frozen as fact. The
watchpipeline andbackfillboth re-price this way. Events for a known model with no rate covering their timestamp (a retired model, or an event older than the model's earliest recorded price) are skipped non-fatally, like unknown models.
budgetclaw pricing history <model> [--json]prints the full point-in-time price table for one model: each interval's effective-from date, through date (open when current), and input/output rate per MTok. Accepts canonical ids and aliases.budgetclaw pricing provenance [--json]prints the pinned ai-price-index dataset tag and the exact repo commit the embedded rates were generated from, so every rate traces back to an upstream commit.budgetclaw syncnow sends a per-(day, project, branch, model) token rollup inline on each spend record (tokens: {input, output, cache_read, cache_write_5m, cache_write_1h}), at the same grain as the dollar amount, so a future Goei server can re-price tokens at its own point-in-time rate.amountCentsis still sent; the change is backward compatible (the current server ignores the new field).--dry-runnow also reports the total token count.- CI freshness gate: a
pricing-codegenjob runsgo generate ./...against the vendored dataset and fails if the committedinternal/pricing/table_gen.godrifted from what the data produces, keeping the embedded rates hermetic.
budgetclaw pricing ratesno longer errors when the dataset includes retired models.KnownModels()now spans retired models that have no current rate;pricing rates/pricing rates --jsonskip those so the current-rates output (consumed by the pricing-audit workflow) stays limited to currently-priced models with an unchanged JSON shape.
- Cost overcount of 2.5-2.85x, all prior versions affected. Claude Code writes the same assistant API response across multiple JSONL lines (identical
message.idandrequestId, distinct line uuids), and budgetclaw counted every line as a separate event. Events carrying a message id now dedup on(message_id, request_id)with last-line-wins semantics, matching how the same response is reconciled by Anthropic billing. Verified against an independent reference computed from the same logs: all closed days matched exactly after the fix. After upgrading, runbudgetclaw backfill --rebuildonce to clean an existing database; until then, totals remain inflated.
budgetclaw syncpushes locally-computed daily spend and token aggregates to a Goei dashboard (https://goei.roninforge.org) using a device token. Zero-key: only dollar-and-token rollups leave the machine, never prompts or API keys. Flags:--days,--since,--no-branch,--dry-run; token via--token,GOEI_DEVICE_TOKEN, or[goei].tokenin config.- Spend records sent to Goei carry the git branch as a dedicated field, with the project name kept bare, enabling clean per-project and per-branch attribution server-side.
--no-branchomits the field so branches collapse into one project row.
- modernc.org/sqlite bumped from 1.50.1 to 1.51.0.
- Claude Fable 5 (
claude-fable-5) added to the pricing table at $10/MTok input, $50/MTok output, a new flagship tier above Opus introduced in the 2026-06-09 Fable 5 / Mythos 5 launch. Before this, Fable 5 events were silently skipped as an unknown model (verified against live local logs: 322claude-fable-5events were going unpriced). Re-verified every existing rate against the live Anthropic pricing page on 2026-06-10: no older model changed price, cache multipliers unchanged. Mythos 5 ships at the same $10/$50 rate but is restricted-access (Project Glasswing), has no published API model ID, and never reaches Claude Code's JSONL, so it is intentionally not added.
- Claude Opus 4.8 (
claude-opus-4-8) added to the pricing table at $5/MTok input, $25/MTok output (the same tier as Opus 4.5/4.6/4.7). Before this, Opus 4.8 events were silently skipped as an unknown model. Re-verified every existing rate against the live Anthropic pricing page on 2026-05-29: no older model changed price, cache multipliers unchanged.
- Dependency bumps:
github.com/shirou/gopsutil/v44.26.3 -> 4.26.4 (#15),modernc.org/sqlite1.50.0 -> 1.50.1 (#18),github.com/fsnotify/fsnotify1.9.0 -> 1.10.1 (#17, applied manually on top of #15 and #18 to resolve ago.sumconflict).
AGENTS.mdat the repo root for AI coding agents (Claude Code, Cursor) operating on the codebase.
- CI: model-audit and the LiteLLM cross-check are now a single bundled workflow (
pricing-audit.yml). Reduces maintainer triage to one issue, one PR, one release when a new Anthropic launch coincides with a price cut on the legacy tier (the Opus 4.7 launch + 4.5 / 4.6 price-cut pattern, see v0.1.4).
budgetclaw pricing rates [--json]subcommand prints every model with its input + output rate per MTok. Feeds the daily LiteLLM cross-check workflow.- The daily
pricing-auditworkflow now also cross-checks every embedded rate against BerriAI/litellm'smodel_prices_and_context_window.json. Closes the gap that v0.1.4 surfaced:/v1/modelsreturns IDs only, so price changes on existing models would slip past the model-only audit. (Bundled into a singlepricing-audit.ymlworkflow in v0.1.6.)
- Opus 4.5 / 4.6 / 4.7 input + output rates corrected from $15 / $75 to $5 / $25 per MTok. Anthropic moved Opus 4.5+ to a new lower tier; the original maintainer's snapshot from 2026-04-09 captured the pre-cut prices, and prior releases inherited the wrong rate by tier-pattern. Discovered by cross-checking against BerriAI/litellm's
model_prices_and_context_window.json, then confirmed against the maintainer's screenshot of the Anthropic pricing page. Existing rollups are not auto-corrected becauseInsertis idempotent on uuid; runbudgetclaw backfill --rebuildto wipe rollups and recompute every historical event at the corrected rates. Opus 4.1 stays at $15 / $75 (still on the legacy tier per Anthropic's published pricing).
budgetclaw backfill --rebuildflag truncates events and rollups before scanning so a pricing correction is reflected in historical totals. Without--rebuild, idempotent inserts leave the old rate baked into existing rollup rows.
- Pricing table comment now names the cross-check methodology (Anthropic page + LiteLLM JSON) and the date, so the next maintainer knows where to verify.
budgetclaw backfillsubcommand walks$HOME/.claude/projects/**/*.jsonl, prices every assistant event, and inserts rollups into the local state DB. Safe to run repeatedly thanks to the existingON CONFLICT(uuid) DO NOTHINGconstraint. Use after upgrading to a release that adds new model pricing to recover attribution for events the prior watcher dropped.- Pricing table now recognizes two more dated Opus variants the daily audit detected on Anthropic's
/v1/models:claude-opus-4-5-20251101andclaude-opus-4-1-20250805. (Initial rates were Opus tier at the time; v0.1.4 corrects 4-5-20251101 to $5/$25.)
- Issue body opened by
pricing-auditworkflow now correctly says "daily" rather than "weekly" (the cron schedule was changed to daily on the same day as v0.1.2; the body template was overlooked).
- Pricing table now recognizes
claude-opus-4-7. Previously the watcher loggedpricing: unknown model, skipping eventfor every Opus 4.7 tool-call, causing silent under-attribution: spend was not counted, rollups stayed at $0, andkill-action caps could never fire on Opus 4.7 sessions. Rates set to the established Opus tier ($15 input / $75 output per MTok), matching 4-5 and 4-6. - Watcher no longer floods stderr with one
pricing: unknown modelline per skipped event. Each unknown model now produces a single loud WARN per watcher run (with a hint pointing atbudgetclaw pricing diagnose); subsequent events for the same model log at DEBUG level only.
budgetclaw pricing listsubcommand prints every model ID in the embedded pricing table (--jsonfor scripting).budgetclaw pricing diagnosesubcommand walks$HOME/.claude/projects/**/*.jsonl, counts every model seen, and flags any missing from the pricing table. Returns a non-zero exit code when missing models are detected so it composes cleanly into shell pipelines.- Daily
pricing-auditGitHub Action calls Anthropic's/v1/modelsendpoint, diffs the result against the embedded pricing table, and opens an issue when a new model is detected. Detection is automated; pricing remains a manual step because a wrong auto-merged price would compromise the kill action. - Initial project scaffold: cobra CLI,
versionsubcommand, XDG path helpers, build/test/lint/release pipeline - MIT license
- Issue templates, PR template, dependabot, CI + release + CodeQL workflows
.goreleaser.yamlwith multi-arch binary builds for darwin-amd64, darwin-arm64, linux-amd64, linux-arm64- XDG-first filesystem layout with tests
- README with trust-pitch framing and honest feature list
- JSONL parser for Claude Code session logs (
internal/parser) - Static pricing table with Anthropic-published rates and cache multipliers (
internal/pricing) - SQLite-backed event and rollup persistence with WAL mode (
internal/db) - TOML budget config: per-project/branch rules, glob matching, daily/weekly/monthly periods (
internal/budget) - Period-aware budget evaluator with timezone support (
internal/budget) - SIGTERM-based process killer with gopsutil process enumeration (
internal/enforcer) - Filesystem-backed lockfile store for breach persistence across restarts (
internal/enforcer) - ntfy.sh push notification client with exponential backoff and retry (
internal/ntfy) - fsnotify-based JSONL file tailer with append-tailing and truncation detection (
internal/watcher) - Full data pipeline wiring all packages into a single watcher handler (
internal/pipeline) budgetclaw watchlong-running daemon modebudgetclaw statustabular spend view by project and branchbudgetclaw limit set/list/rmbudget rule managementbudgetclaw alerts setup/testntfy configurationbudgetclaw unlockandbudgetclaw locks list/pathlock managementbudgetclaw initXDG directory setup and default config generationbudgetclaw config pathdiagnostic helper- Claude Code plugin manifest with
/spendskill and session-start hook