Changelog

Changelog

What changed in each release, described as something you'd notice using the product — not internal refactors. Dates are the dates each version was published. Several entries are corrections that make Cheaper's reported savings smaller: the old numbers were wrong, and we would rather say so plainly than quietly ship different figures. The currently published CLI is cheaper@0.4.2 (npm).

0.4.2 current

2026-08-19

npx cheaper install --all now installs the cheaper command it spends the rest of its output telling you to run.

  • cheaper install and cheaper install --all now install the CLI launcher. They did not, and the install that followed reported nothing but green ticks and then did not work: the very first command it printed — cheaper gateway start — failed with zsh: command not found: cheaper. The invisible half was worse. The same run writes the literal string cheaper peek --tagline … into the global-instructions file of every harness it detects, so an install that printed "✓ tagline wired" for Codex, Copilot and the rest had in fact wired instructions that could never execute, and nothing would ever have reported it. A launcher is one file and it is ours to write, so it is no longer optional. autostart remains opt-in and is still unreachable from --all.
  • The autostart question is no longer asked when it cannot be answered. It was offered whenever the gateway installed, but a login entry points at the stable CLI copy at ~/.cheaper/cli; without it, answering yes returned ✗ nothing to autostart. Because the answer is remembered per machine, that spent the one question this install ever asks on an outcome already known to fail.

0.4.1

2026-08-10

Cheaper can start itself at login and survive a reboot, and it has stopped claiming success it never checked.

  • Cheaper can now start itself at login, if you ask it to. cheaper autostart enable registers a per-user login entry — a LaunchAgent on macOS, a systemd user unit on Linux, a Scheduled Task on Windows — that starts the gateway and brings it back if it crashes. Nothing came back after a reboot before this. It is opt-in only: neither cheaper install nor cheaper install --all can ever register it, you have to name it. cheaper autostart disable deregisters the entry and deletes the file it wrote, and cheaper autostart status re-checks that the paths it recorded still exist, so upgrading Node no longer leaves a login entry crash-looping in silence.
  • The end-of-chat line no longer shows a dashboard link when the gateway isn't running. It used to print the dashboard address on every chat without ever checking it, so clicking it gave a connection error. The link now appears only when the gateway actually answered.
  • An unreachable gateway now says so. When Cheaper can't reach the gateway it falls back to estimating from your local chat history — and it used to do that silently, while a gateway that answered with stale data got a visible warning. The unreachable case now gets a notice of the same weight, naming the port it tried.
  • cheaper gateway start no longer reports success for a gateway that died. If a second gateway couldn't claim the port and exited immediately, the command still printed a green "started" tick — and cheaper gateway stop afterwards could no longer reach the real one.
  • cheaper status no longer shows a stopped gateway in green. It was already asking the gateway whether it was alive, then colouring the answer as though it were.
  • cheaper gateway stop now confirms it is stopping Cheaper's gateway. After a reboot the recorded process id can belong to something else entirely, and stopping the gateway could have signalled an unrelated program. If that check can't be made, the command refuses to act rather than assume.
  • A real --port flag, plus cheaper gateway restart and cheaper gateway serve for running the gateway in the foreground under a supervisor. The dashboard launcher, the freshness checks and the end-of-chat line now all use the port the gateway actually bound instead of assuming 8787 — which matters as soon as autostart picks 8788 because 8787 was busy.
  • cheaper status now re-checks everything the installer wrote, not just one of the six places. Five of them were never re-verified, which is why switching accounts in your coding tool could break the setup with nothing reporting it.
  • Mistral requests are answered by the tier they were sold as. The middle slot held a model catalogued a tier below it and the top slot a mid-capability model, so a mid-tier request was answered one tier down, and a hard request that escalated was answered by a mid-capability model while being reported as top tier. The corrected top-tier target is both more capable and cheaper than the one it replaced.
  • Every price in the catalog was re-read against its vendor's own page. 71 of 75 rows could be checked against a live pricing sheet and every one of them already matched, to the cent. What was missing was six OpenAI long-context tiers the vendor publishes and Cheaper did not carry — an undercount on exactly the long inputs where the rate changes.
  • cheaper peek now reports how many calls were actually re-routed, beside the existing count of calls that were eligible for a cheaper tier. Those are two different sets, and showing only the second invited you to derive the dollars from a number the dollars don't come from. A Routing line appears only when the two counts differ — that is, exactly when reading them as one number would mislead you.
  • A route whose target has no published price is now named and counted. It moves no money, which is correct, but that left a 0 you couldn't tell apart from a measured one. Cheaper now says which models need a price, and a report written before these counters existed shows a dash rather than a fabricated zero.
  • Status labels in the savings report say what they mean. A window whose figures can't be published — because the store's own state couldn't be read — was rendered in the same visual weight as a mild "these figures are provisional", and two statuses explained themselves by repeating their own name.
  • Linux downloads are current, and arm64 is a first-class target. The Linux .deb, .rpm and .AppImage downloads had been serving the 0.1.0 build for days, and the Windows installer was three days old; all now serve the current release. New arm64 .deb, .rpm and .AppImage builds ship alongside them.
  • AppImage downloads are linked from the site. They were being published and never offered anywhere you could see them, on either the download page or the thank-you page, with per-architecture install steps.
  • Cheaper stops overstating what it is wired into. A menu entry named a desktop app it has no integration with — every path it touches belongs to the Codex command-line tool, so it says Codex CLI now, and two neighbouring labels had the same overclaim. The documentation now says where you first meet it that routing is opt-in in every tool, including Claude Code, and the end-of-chat line no longer credits Cheaper for a tool's own model choices when it was never routing them.

0.4.0

2026-08-08

The router stops ratcheting up to the priciest model, and the dashboard stops publishing unmeasured arithmetic under a headline that reads as measured.

  • Routing now looks only at your current message, not your whole conversation history or either side's system prompt. The old router classified the entire transcript every time, so one matching word anywhere in a chat pinned every later turn to the most expensive tier for the rest of that conversation — a one-way ratchet that never came back down. Replayed over roughly 47,000 real calls, the old behavior routed 89.9% of traffic to the top tier and saved 2.03%; scoping the classifier to the current turn took the same traffic to 28.7% saved.
  • The cheap triage classifier was reading the wrong end of your chat. With the whole conversation concatenated, the text it actually saw was the system prompt and the oldest messages — the request it was supposed to classify had been truncated away entirely.
  • The gateway now refuses to substitute a different vendor's model. A request naming one company's model could previously be served a different vendor's model, and the call would succeed with nothing in the response indicating the swap — so a harness comparing vendors through Cheaper was measuring the same vendor every time.
  • The "never spend more than the model you asked for" ceiling now covers every model. It had no effect for 62 of 89 model ids, because Cheaper couldn't place them in a tier and no tier meant no ceiling. A cheap model paired with a hard question was being upgraded on a setup where upgrades are switched off.
  • Hard, correctness-critical requests (concurrency, security, proofs and similar) are protected from being downgraded to save money. This is a downgrade veto, not an upgrade: Cheaper still never routes a request to a model pricier than the one you asked for.
  • A saving is no longer picked for having the friendlier sign. When the measured figure and the estimated one disagreed, Cheaper chose between them by which was larger — so a measured loss of $2.00 could print as "saved about $84.00" and write $84 into your lifetime total.
  • A call the price catalog can't value is no longer counted as spend. It was being added to Spent at *today's* rate, which is wrong for anything priced under a promotion that has since expired, and moves on its own when a promotional window opens or closes. It is now excluded from every dollar total and counted only in a named exclusion bucket, so the dollars and the call counts reconcile.
  • vs all-frontier can show a loss. It was floored at $0.00, so a period where routing cost more than the all-frontier baseline read as an honest, measured break-even. A real negative is now shown as one.
  • cheaper peek reads your live gateway settings instead of assuming the defaults. Measured against one real history on the same day, the difference was $470 of over-claim, 6.2% — Cheaper was pricing the middle tier against a model on a promotional rate while the gateway was actually routing to a different, list-priced one. An unreachable gateway is now an answer ("assuming defaults"), not an error, and the assumptions it made are listed.
  • Models Cheaper can't route are moved out of the headline, not zeroed. Four of six model families have no routing endpoint at all; their spend still counts toward what you paid, and their savings are reported separately instead of quietly inflating the top-line number.
  • The dashboard's headline can no longer be read as measured by accident. On one real machine, 90 of 94 recorded calls were probes that returned no output tokens, and the measured path had never once fired — yet the whole figure was published under a headline that reads as measured. Cheaper now publishes how many calls were measured against how many weren't, explains the wall of $0.00 in the log rather than papering over it, and a figure with no measured basis has to be asked for by name.
  • "Live" now means data arrived, not that a socket is open. An idle gateway looked identical to a busy one. Cheaper now reports how old the newest call is, and an empty store says so instead of showing a fabricated zero.
  • The desktop app no longer leaks its access token into browser history. "Open dashboard in browser" was putting a long-lived token in the address bar; internal windows now pass it invisibly.
  • The desktop app adopts a gateway it left behind. A crash or force-quit used to strand the gateway holding the port, after which the next launch could neither stop nor restart it while the menu bar read "Gateway: stopped".
  • The desktop app updates itself, and only pages Cheaper serves can reach its privileged bridge — any link, redirect or script-driven navigation previously carried it to whatever page loaded next.

0.3.0

2026-08-07

Savings are recorded per call at the time the call happened, priced from a real per-model catalog, and a period Cheaper can't vouch for says so instead of showing $0.00.

  • Retired Opus pricing was being applied to current Opus work. A single hardcoded rate bucket valued all top-tier Anthropic usage at Claude Opus 4's retired rate, 2.74× the real cost of Opus 5. Replaced with a per-model price catalog transcribed from each provider's own pricing page, with the transcription date recorded.
  • An unrecognized model no longer inherits a neighboring model's price. Matching used to fall back to the nearest older entry, so a newly released model silently adopted a retired rate. Matching is now exact; a model with no published price is unpriceable and contributes $0, never a guessed rate.
  • Savings are computed in dollars from the catalog, not inferred from a model's name. Name and price disagree in 38 places in the current catalog, and the two approaches had drifted far enough apart that the same session could report $24.00 or $84.00 purely from the order lines appeared in the log file.
  • Cache, long-context, batch and promotional rates are modeled per model — including Anthropic's 1-hour cache-write rate, which is what Claude Code actually uses and was previously undercounted. Promotional windows are evaluated against the date each call happened, so a launch price that ends doesn't get quoted forever.
  • The gateway prices a routed call at the exact model it served, not a tier-average stand-in — the earlier approach could over-report by roughly 50% on some calls.
  • Cache-aware pricing on your local chat history. Transcripts fold cached input into the plain input count, and Cheaper was charging all of it at full rate — inflating one live session's total roughly 7× ($1,038 against a real $148), and its savings with it.
  • Savings are tracked per call, by when the call happened — not per chat, by when the end-of-chat summary last printed. The old ledger could report 100% of lifetime savings under "today" for work spanning weeks, and re-running an old chat's summary moved its money into a different day. Period columns now partition history instead of nesting, so they add up to your lifetime total rather than counting today six times.
  • Streamed calls are finally measured. Claude Code always streams, and the gateway parsed no token usage at all on that path — every streamed call was stored as a character-count guess. It now reads the provider's own usage data out of the stream.
  • Retries are never priced. An automatic retry after a rate-limit used to be recorded as a separate priced call, so a retry storm could book the same saving several times over for one delivered answer.
  • A period Cheaper can't vouch for shows a labelled reason, never $0.00 — a range before the store was watching, a partly covered range, a window where more than 20% of tokens are unpriceable, or a session you deleted with cheaper forget. Measured and estimated figures are never added together; they get separate columns.
  • The end-of-chat line names models, not tiers. "12 calls on claude-sonnet-5 instead of claude-opus-5" is checkable; "sonnet tier instead of opus" was not. "You spent $X" is gone — most sessions run against a flat-rate plan where that sum is never charged, so the line reports the metered value at list API rates instead. A running lifetime total was added, and it is signed: a chat where routing cost extra now subtracts, where it used to only ever ratchet upward.
  • The gateway's dashboard and other local read endpoints now require a per-machine token. Loopback isn't a trust boundary on a shared machine — any other account could read your full usage record. Run cheaper dashboard and it mints the token and opens the tokened address for you. Exports guard against spreadsheet formula injection.
  • New commands: cheaper import, cheaper forget, cheaper compact, cheaper export, and cheaper logs / reports / monitor / dashboard, each with a --json or --terminal option. New surfaces: a rebuilt logs register and reports tab, and a cheaper:// link that opens the desktop app on the right tab even from cold.
  • A "savings" figure on the marketing site was generated at random. It incremented on a timer, reset on page load, and was never connected to any data. It has been removed. The savings calculators now state that they are illustrative, and the tool counts published across the site (36 with documented setup, 8 detected, 7 read) are reconciled instead of being quoted five different ways.

0.2.2

2026-08-06

Every chat ends with a branded, per-chat savings line.

  • A "Cheaper.app saved $X and N tokens…" line at the end of every chat, wired into Claude Code, Codex, Cursor, Copilot, Gemini, Grok, OpenCode and PI.dev. It is exact when the gateway served the calls and marked as an estimate when it is read from your local transcript, and it never claims a phantom, sub-cent or zero-token saving.
  • A chat's sub-agents are credited to that chat. Delegated work runs on cheaper models and was being left out entirely, so a chat that delegated heavily reported "no cheaper routing warranted" or $0 while it was saving real money.

0.1.0

2026-08-06

First release.

  • Gateway: an Anthropic- and OpenAI-compatible routing proxy with a local monitor and dashboard.
  • Router: content-based tiering with a requested-model cost ceiling by default — Cheaper only downgrades or matches, it never spends more than the model you asked for.
  • CLI: cheaper install (skill / hook / plugin / gateway), gateway, monitor, status, and cheaper peek, which reads your existing chat history and estimates what routing would have saved before you install anything.
  • Plugin: a skill, an always-on hook, and three tiered agents.
  • Desktop: a menu-bar app with a live monitor, which start/stops the gateway and shows savings as they happen.

See how we measure for every pricing correction with dates, and the full commit history for everything not summarized above.