Skip to content

Disclose yearly billing in compact pricing labels - #9378

Merged
lawrencecchen merged 8 commits into
mainfrom
task-pricing-yearly-suffix
Aug 1, 2026
Merged

lawrencecchen merged 8 commits into
mainfrom
task-pricing-yearly-suffix

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • label annual Pro rates as /mo, billed yearly
  • label annual Team rates as /user/mo, billed yearly
  • localize the compact disclosure in English and Japanese

Follow-up to #9373 after local autoreview found that the compact annual rates no longer disclosed their billing cadence.

Tests

  • bun test web/tests/pricing-page.test.tsx web/tests/app-pricing-page.test.tsx web/tests/dashboard-billing-page.test.tsx
  • bun run typecheck

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Restore yearly billing disclosure in compact pricing labels and simplify pricing copy. Tighten the pricing card layout and align numerals, with EN/JA localization and tests.

  • Bug Fixes

    • Show annual Pro as "/mo, billed yearly" and Team as "/user/mo, billed yearly" on pricing, app pricing, and billing pages.
    • Localize compact labels and related copy in English and Japanese.
    • Add regression tests to ensure billing cadence stays visible.
  • Refactors

    • Remove annual totals from UI and i18n; compare using monthly equivalents only.
    • Drop extra annual detail lines and the priceDetail prop from PlanCard.
    • Shorten copy to "/mo" and "/user/mo", use tabular numerals, tighten spacing, and switch app grid to lg:grid-cols-4.

Written for commit 46826a7. Summary will update on new commits.

Review in cubic

@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e274cf84-a032-4030-8fb3-dcaf4a1d19fd

📥 Commits

Reviewing files that changed from the base of the PR and between fdd8a1b and 46826a7.

📒 Files selected for processing (5)
  • web/messages/en.json
  • web/messages/ja.json
  • web/tests/app-pricing-page.test.tsx
  • web/tests/dashboard-billing-page.test.tsx
  • web/tests/pricing-page.test.tsx

📝 Walkthrough

Walkthrough

The change updates English and Japanese annual pricing labels to show yearly billing. Pricing page tests now verify the updated labels for plans and per-user pricing.

Changes

Pricing label updates

Layer / File(s) Summary
Annual billing localization labels
web/messages/en.json, web/messages/ja.json
Pricing strings now distinguish monthly and per-user rates billed annually.
Annual pricing display assertions
web/tests/app-pricing-page.test.tsx, web/tests/dashboard-billing-page.test.tsx, web/tests/pricing-page.test.tsx
Tests now verify /mo, billed yearly and /user/mo, billed yearly labels for annual pricing.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

  • manaflow-ai/cmux#9373: Modifies the same pricing localization strings and pricing-page tests for annual billing labels.

Suggested reviewers: azooz2003-bit, austinywang


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (2 errors)

Check name Status Explanation Resolution
Cmux Swift Package Boundaries ❌ Error The diff adds a 203-line auth trust/disposition and URL-parsing policy in app-target Sources/Panels, with tests for its pure seam; this is reusable domain logic, not only WebKit glue. Extract the pure callback policy, disposition, origin checks, and return-URL parsing into a small SwiftPM target such as CmuxBrowserAuth exposing BrowserAuthCallbackPolicy; keep WKWebView, alerts, and AppDelegate adapters in cmux.
Cmux Full Internationalization ❌ Error The PR changes annual pricing labels in en.json and ja.json, but the 18 other locales in routing.ts lack both pricing keys; localized pages consume these keys via next-intl. Add translated perMonthBilledYearly and perUserMonthBilledYearly entries to every other web/messages/*.json locale listed in web/i18n/routing.ts.
✅ Passed checks (23 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding yearly billing disclosure to compact pricing labels.
Description check ✅ Passed The description explains the changes and lists tests, but omits the template's Demo Video, Review Trigger, and Checklist sections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed Changed production Swift keeps AppDelegate and browser delegates on MainActor; the new policy is an explicit MainActor UI coordinator, with no new Sendable protocols/models or background store access.
Cmux Swift Blocking Runtime ✅ Passed Changed production Swift adds async callback delivery only; no new semaphores, waits, sleeps, delayed dispatch, polling, main-queue sync, or manual locks. Primitive counts are unchanged.
Cmux Browser Automation Off-Main ✅ Passed The effective PR diff changes only pricing localization and web tests; no browser automation files, commands, routing, WebKit waits, or worker policy tests are changed.
Cmux Expensive Synchronous Load ✅ Passed Production Swift changes add only @MainActor auth-callback/browser policy code; no prohibited history loaders or large file parsing. Existing RestorableAgentSessionIndex.load() lines are unchanged.
Cmux Cache Substitution Correctness ✅ Passed The exact PR diff changes only English/Japanese localization strings and pricing test assertions; it contains no production Swift, TypeScript, or JavaScript cache or persistence change.
Cmux No Hacky Sleeps ✅ Passed The exact PR diff changes only English/Japanese localization and deterministic test assertions; it adds no sleeps, timers, polling, delays, or runtime synchronization.
Cmux Algorithmic Complexity ✅ Passed The merge-base diff adds only four scalar localization values and six test assertions; no production loop, scan, sort, filter, join, or slower algorithm is introduced.
Cmux Swift Concurrency ✅ Passed The PR diff changes only five web localization/test files; it adds no Swift files or legacy Swift concurrency patterns.
Cmux Swift @Concurrent ✅ Passed The Swift diff adds only @MainActor auth/UI async paths; it adds no @concurrent or nonisolated async code, and heavy refresh work remains an intentional UI-bound flow.
Cmux Swiftpm Lockfiles ✅ Passed cmux.xcodeproj/project.pbxproj only registers Swift files; it changes no package reference or pin, so no root Package.resolved diff is required. Standalone packages use their own lockfiles.
Cmux Swift Logging ✅ Passed Swift additions use redacting AuthDebugLog or #if DEBUG cmuxDebugLog; no print/debugPrint/dump/NSLog, file/stdout diagnostics, logger constants, or sensitive values were added.
Cmux User-Facing Error Privacy ✅ Passed The PR changes only pricing labels to show annual billing cadence in English and Japanese; it adds no user-facing error, alert, diagnostic, or prohibited implementation detail.
Cmux Swiftui State Layout ✅ Passed Swift changes add AppKit/WebKit auth navigation and tests only; no new ObservableObject/@published, GeometryReader, lazy-row store references, SwiftUI body, or render-time state mutation.
Cmux Architecture Rethink ✅ Passed Swift changes use a shared AppDelegate callback owner and @MainActor BrowserAuthCallbackNavigationPolicy; no sleeps, polling, locks, observers, or side channels were added, and tests cover fail-clo...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed Changed Swift hunks add auth-callback routing, not a new window. Existing BrowserPopupWindowController uses registered cmux.browser-popup, and scripts/lint_auxiliary_window_close_shortcuts.py passes.
Cmux Source Artifacts ✅ Passed All 33 changed paths are product source, tests, project config, or localization catalogs; no prohibited artifact directories, generated-file extensions, or binary diff indicators appear.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The Swift additions are production auth-navigation behavior with callers in AppDelegate and browser delegates; tests use @testable import, and added DEBUG blocks only log real navigation.
Cmux No Ambient Global State ✅ Passed The PR-side diff (HEAD^2..HEAD) contains only JSON and TSX files. It adds no production Swift changes, so the ambient global state rule is not applicable.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task-pricing-yearly-suffix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…uffix

# Conflicts:
#	web/messages/en.json
#	web/messages/ja.json
#	web/tests/app-pricing-page.test.tsx
#	web/tests/dashboard-billing-page.test.tsx
#	web/tests/pricing-page.test.tsx
@cursor

cursor Bot commented Aug 1, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@lawrencecchen
lawrencecchen merged commit 9a7e403 into main Aug 1, 2026
6 checks passed
@lawrencecchen
lawrencecchen deleted the task-pricing-yearly-suffix branch August 1, 2026 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant