feat: pricing & updates polish — validate rates, surface unpriced models, ccam update-check, fast/intro pricing flags#237
Merged
Conversation
The route validated model_pattern/display_name presence and the intro_until
date shape, but every per-MTok rate field passed straight through to the
upsert with only `?? 0`. A typo'd value (Number("abc") -> NaN via the CLI's
Number() coercion, or a raw string/negative number from a direct API call)
was written into model_pricing as-is and silently corrupted all downstream
cost math until someone noticed the broken totals and fixed the row by hand.
Reject any present rate field that is not a non-negative finite number with
the route's structured 400 INVALID_INPUT error, and coerce accepted values
with Number() so a rate can never be bound into SQLite as text. Absent and
empty values keep defaulting to 0, so existing clients are unaffected.
Co-authored-by: seer-by-sentry[bot] <157164994+seer-by-sentry[bot]@users.noreply.github.com>
GET /api/pricing/cost deliberately reports unpriced_models — usage buckets that matched no pricing rule and were priced at $0 — so the total is never silently under-reported. The CLI's cost command dropped that field on the floor: after a brand-new model id shipped, `ccam cost` showed a too-low total with no hint that anything was missing. Print a warning block under the per-model chart listing each unpriced model with its token volume, plus the exact `ccam pricing set` invocation that fixes it. Nothing changes when every model is priced. Co-authored-by: OpenAI Codex <codex@openai.com>
The updates route (GET /api/updates/status, POST /api/updates/check) was the only major dashboard surface with no ccam command — ironic, because its whole design is "the dashboard never restarts itself; the user copies the printed command and runs it in a terminal". The terminal is exactly where that answer belongs. `ccam update-check` POSTs /api/updates/check (so an open dashboard tab picks up the same fresh result via the update_status broadcast) and prints the branch-aware status: behind-by count, the situation note for fork/feature- branch checkouts, and the copy-paste update command. Non-git installs and unreachable remotes report informationally with exit 0; offline (server down) refuses with the standard server-only reason. Also corrects the stale CLAUDE.md repo-map line that pointed at a scripts/self-update-restart.js which no longer exists — update detection lives in server/lib/update-check.js. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
PUT /api/pricing has accepted fast_input/fast_output_per_mtok and the full intro_* promo block for a while, and the Settings UI edits all of them — but the CLI could only send the four standard rates, so fast-mode premiums and time-limited launch pricing were unmanageable (and invisible) from the terminal. pricing set gains --cache-write-1h, --fast-input/--fast-output, and --intro-input/--intro-output/--intro-cache-read/--intro-cache-write/ --intro-cache-write-1h/--intro-until YYYY-MM-DD. The intro block is only sent when an --intro-* flag is actually present, honoring the API contract that a plain rate edit never clobbers an existing promo; a bare --intro-until clears it, mirroring the Settings UI. The pricing list (online and offline fallback, now one shared renderer) gains Fast In/Out and Intro In/Out columns so those rates are visible, and the new flags are registered with the REPL tab-completer. Co-authored-by: GPT-5 Codex <noreply@openai.com>
… the pre-commit hook Documentation sweep for this PR's feature set, applied across the full doc surface per the update-project-docs mapping: - docs/CLI.md: ccam update-check row (Administration), pricing set fast/intro flag rows, unpriced-model warning on the cost row, and the offline-mode server-required list. - README.md + README-VN/CN/KO: the ccam CLI block gains update-check, the pricing set flag lines, and the cost warning note (comments translated in each language's existing register; commands/flags kept in English). - docs/API.md, server/README.md, server/openapi-extra (+ regenerated openapi.yaml): PUT /api/pricing numeric-rate validation documented (400 INVALID_INPUT naming the offending field; numeric strings coerced). - wiki/index.html + i18n-content.js (zh/vi/ko) with the required cache bump (sw.js wiki-v41, i18n-content.js?v=32): CLI table + Pricing/Insights/ Administration descriptions, and an Update Notifier paragraph pointing at ccam update-check. Also hardens .husky/pre-commit against machine-load flakiness: the suite spins up dozens of concurrent test servers plus spawned CLI children with hard kill timeouts, and a loaded machine occasionally produced a one-off failure that passed on the very next run. Each suite now retries once on failure — a real regression is deterministic and still fails both runs, blocking the commit, so the gate stays exactly as strict while commits stop being a dice roll on machine load. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Five self-contained enhancements centered on the pricing and updates surfaces, closing gaps where the API was ahead of the CLI (or where invalid input could corrupt cost math), plus the required doc sweep and a pre-commit-hook reliability fix.
1.
fix(server): validate rate fields inPUT /api/pricingRate fields were passed to the upsert with only
?? 0, so aNaN(e.g. a typo'd CLI flag throughNumber()), a raw string, or a negative number was written intomodel_pricingas-is — silently corrupting all downstream cost math. Any present rate must now be a non-negative finite number (numeric strings coerced), else400 INVALID_INPUTnaming the offending field. Existing clients are unaffected.2.
feat(cli): surface unpriced models inccam cost/api/pricing/costdeliberately reportsunpriced_models(usage priced at $0 because no rule matched) so the total stays honest — but the CLI dropped the field, showing a too-low total with no hint.ccam costnow prints a warning listing each unpriced model, its token volume, and the exactccam pricing setfix.3.
feat(cli):ccam update-checkThe updates route was the only major surface with no CLI command — ironic, since its whole design is "the user copies the printed command and runs it in a terminal".
ccam update-checkPOSTs/api/updates/check(so open dashboard tabs refresh via theupdate_statusbroadcast) and prints the branch-/fork-aware status: behind-by count, situation note, and the copy-paste update command. Also fixes a staleCLAUDE.mdreference to ascripts/self-update-restart.jsthat no longer exists.4.
feat(cli): fast-mode & intro pricing fromccam pricing setThe API and Settings UI have long supported fast-mode premiums and time-limited intro (promo) rates; the CLI could only send the four standard rates. Adds
--cache-write-1h,--fast-input/--fast-output, and the--intro-*/--intro-until YYYY-MM-DDblock (only sent when present, so a plain edit never clobbers a promo; bare--intro-untilclears it). The pricing list — online and offline, now one shared renderer — gains Fast In/Out and Intro In/Out columns.5.
docs+ hook de-flakeFull doc sweep per the update-project-docs mapping (docs/CLI.md, docs/API.md, README + VN/CN/KO, server/README, OpenAPI regen, wiki + zh/vi/ko i18n with the required cache bump). Also hardens
.husky/pre-commit: each test suite retries once on failure, absorbing machine-load flakes (dozens of concurrent test servers + spawned CLI children) while a real regression still fails both runs and blocks the commit.Testing
npm run test:server— all suites green (ran repeatedly, incl. 3 full pre-commit hook runs; new tests: PUT validation ×4, cost unpriced warning, update-check, fast/intro round-trip)npm run test:client— 24 files / 261 tests green (via the pre-commit hook on every commit)bash .claude/skills/file-headers/scripts/check-headers.sh— exit 0update-check/fast-input/intro-until— canonical + all translations hit🤖 Generated with Claude Code