Skip to content

Port upstream 0.65.0: Zed opt-in browser billing (stacked on #619) - #674

Draft
Finesssee wants to merge 14 commits into
codex/port-0.65-provider-packfrom
port/micro-0.65.0-zed-browser-billing
Draft

Finesssee wants to merge 14 commits into
codex/port-0.65-provider-packfrom
port/micro-0.65.0-zed-browser-billing

Conversation

@Finesssee

Copy link
Copy Markdown
Collaborator

Summary

Ports upstream 0.65.0 Zed browser billing as an opt-in lane next to the existing editor-credential lane.

  • Default and API (oauth) sources keep using the editor credential against cloud.zed.dev/client/users/me. Behavior is unchanged for existing users, and the browser session is never consulted.
  • New Browser session (web) source reads cloud.zed.dev/frontend/billing/usage with a zed.dev cookie (pasted Cookie header or browser import). It never sends the editor credential and never falls back to it.
  • Browser lane reports token spend in USD (from cents), the spend limit, the remaining budget (floored at 0), the plan label, and edit-prediction usage (unlimited, null, integer or {"limited": n} limits).
  • Editor lane now uses the same strict validation, and keeps identity, cycle progress, and an "Overdue invoices" billing row.
  • Browser billing is opt-in through a new Provider::web_is_opt_in() hook. The shell would otherwise turn Auto into Web as soon as ProviderId::Zed gained a cookie domain (zed.dev) and the default cookie source (manual) had a stored cookie.
  • 401/403 on the browser lane map to an expired-session state; 429 and 5xx get distinct messages.
  • Settings gets a Zed usage-source policy (Auto / API / Browser session).

Upstream reference

Upstream steipete/CodexBar tag v0.65.0 (read-only, tag-pinned): zed.js, ZedPluginTests.swift, ZedStatusProbeTests.swift, docs/zed.md. Endpoint evidence: upstream steipete#3172.

Ported / Deferred

Ported: strict validation (safe integers, non-negative cents, non-blank text, missing limit key fails, root must be an object), spend/limit/remaining rows, CostSnapshot with cap, plan label, editor cycle and overdue rows, per-lane status classification, bounded response read.

Deferred:

  • Cookie cache reject-on-401: the Zed lane has no cookie cache here, so there is nothing to reject.
  • A Zed cookie-source "off" picker: not added. A disabled source arrives as Cli and returns a friendly error with no request and no cookie import.
  • Only the root JSON object shape is checked; nested arrays where objects are expected fail through serde as usual, without a separate up-front check.
  • Zed settings-file server URL and keychain credential discovery (macOS-only upstream) are unchanged.

Validation

  • cargo fmt --all: clean
  • cargo clippy --workspace --all-targets -- -D warnings: clean
  • cargo test -p codexbar: 2272 passed, 0 failed (56 Zed-filtered, all new Zed tests included)
  • cargo test -p codexbar-desktop-tauri: 491 passed, 0 failed (includes two new build_fetch_context Zed tests)
  • pnpm exec vitest run src/surfaces/settings/providers: 86 passed
  • pnpm run lint: only pre-existing warnings; pnpm run build: passed

Affected areas

rust/src/providers/zed/ (mod, snapshot, tests), rust/src/core/provider.rs (web_is_opt_in, Zed cookie domain), apps/desktop-tauri/src-tauri/src/commands/providers.rs (build_fetch_context opt-in arm), settings usage-source policy for Zed.

UI proof

Pending: coordinator will capture CUA proof on a fresh build. Not run by this change author.

@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

@Finesssee

Copy link
Copy Markdown
Collaborator Author

Thermo-nuclear review

Reviewed by Codex gpt-6-luna (xhigh); verified and validated by Claude

  • P2 commands/providers.rs:138: with Zed set to Browser session and no saved manual cookie, the generic shell fallback could import cookies from a browser the user did not select. Fix: Zed declares ManualEmptyCookiePolicy::FailClosedWeb (same as Replicate).
  • P3 usageSourcePolicy.ts:58: the Zed source picker labels and help text were hard-coded English. Fix: locale keys plus translations in all eight catalogs.
  • P3 zed/snapshot.rs:163: response body decoded to Value then re-parsed into the typed struct. Suggested fix: deserialize directly. Not applied (see follow-up).

@Finesssee

Copy link
Copy Markdown
Collaborator Author

Thermo-nuclear review: fixes landed at bd00551

Fixed: the P2 fail-closed policy for Zed browser mode, and the P3 localization of the Zed source picker (plus a missing LocaleKey import that Claude added to usageSourcePolicy.ts).

Left: the P3 snapshot parse change was reverted. serde derived structs also accept JSON arrays, so direct deserialization would stop rejecting non-object roots, which the existing parse_root guard does on purpose.

Commands run (slot-7, E-cores, Rust 1.98.0): cargo fmt --all --check, clippy -D warnings on both crates, cargo test --lib zed locale (72 passed), tsc --noEmit, vitest on src/i18n and src/surfaces/settings/providers (87 passed). No desktop/CUA run; the fix changes the Zed source picker text and Zed browser-mode fallback, so it needs UI proof.

Zed fails closed on empty manual cookie in browser mode; localize Zed usage-source picker.
@Finesssee

Copy link
Copy Markdown
Collaborator Author

CUA proof

Build commit: bd005516fe3dc203a5cfc90f62bdb20dd19378b3 (PR head). Fresh local debug build (pnpm --dir apps/desktop-tauri run tauri:build:debug), driven with the cua-driver CLI using background actions only (window-state screenshots, UIA element invokes) on a secondary monitor.

Proof-only patches (uncommitted, reverted, not pushed)

  • Root Cargo.toml [patch.crates-io] dirs shim, so config/home dirs live under an isolated proof home (no real settings, cookies or accounts).
  • rust/src/providers/zed/mod.rs read_body: with env CODEXBAR_PROOF_ZED_FIXTURE set, the real request is built, its lane, URL and header presence (cookie=, authorization=) are logged, and the response body comes from a fixture file instead of https. The real parser, build_fetch_context lane selection and status mapping run unchanged; no TLS or URL validation was weakened.
  • Data is fake (proof-editor-user, dummy credential, dummy cookie); cookie_source=manual, so no browser cookies were read.

Results

# Check Result
0 No real email/account from the machine visible in any screenshot PASS
1 Auto + stored cookie + API key uses the editor lane only. Log: editor .../client/users/me cookie=false authorization=true, no web request. Tray: Zed Free, Edits 60%, Cycle 33% PASS
2 Browser session (web) hits /frontend/billing/usage with Cookie and no Authorization. Shows Zed Pro, Edits 24% (120 / 500), Token spend $12.34, Spend limit $20.00, Remaining budget $7.66 PASS
3 Browser 401 shows "Zed browser session expired. Sign in to zed.dev in Chrome or update the Cookie header." with no editor-lane fallback (only web requests logged) PASS
4 Browser session with no stored cookie shows the friendly "Sign in to zed.dev..." message and sends zero requests (no editor fallback although an API key exists, no browser import) PASS
5 Settings > Providers > Zed shows the Usage source picker (auto / api / Browser session) with the Browser-session help text; selecting auto and refreshing switches the data source from web to api and the log shows editor ... authorization=true. Editor lane also shows Account, Zed Free, Weekly cycle and a Billing row "Overdue invoices" PASS
6 Dark theme under auto, no clipped text PASS

Notes (not failures): the picker's first two radio labels render lowercase (auto, api) in the UIA tree and screenshot; the Billing overdue row renders as a red "Exhausted" bar with "Resets Overdue invoices" text.

Screenshots (local, not committed)

C:\Users\FSOS\AppData\Local\Win-CodexBar\port-audit\proof\674\shots\

  • 01-editor-auto.png, 02-web-browser-session.png, 03-web-expired-401.png, 04-web-no-cookie.png
  • 05-settings-providers.png, 06-usage-source-picker.png, 07-picker-auto-editor-lane.png, 08-after-refresh-auto.png

Commands

bash launch.sh trayPanel <editor|web|expired|nocookie> and bash launch.sh settings:providers web (kit in ...\port-audit\proof\674\), then cua-driver call list_windows / get_window_state --screenshot-out-file / click (UIA invoke, background delivery).

@Finesssee

Copy link
Copy Markdown
Collaborator Author

Adversarial validation (lane-A) at 4eedc06

Review verdict: the branch matches the 0.65.0 audit PR 7 spec: opt-in browser billing (web_is_opt_in guard) with the editor credential as the default lane; available_sources = Auto/Web/OAuth; Web request GET https://cloud.zed.dev/frontend/billing/usage with Accept + Cookie (manual header or browser zed.dev cookies, never Authorization), no redirects, 512 KiB cap, 15 s timeout; 401/403 on the web lane reject the cookie with the fixed "Zed browser session expired…" message; 429 rate limited; 5xx unavailable; the lanes are never combined and Web never falls back to the editor credential; Cli (cookie source off) fails closed without importing cookies or sending a request. The shared snapshot.rs mapping covers the upstream fixture set (billing used/limit cents, overage floors, limit_in_cents null/missing, plan forms, overdue invoices, malformed bodies without echo). Frontend: zed source picker (auto/API/Browser session), cookie field, locale keys, zed.dev cookie domain.

Merge outcome: the branch absorbed the current #619 head (26181982) and the #620 head (4663218d) plus the thermo-review commit (bd005516) to keep the stack fresh. Two merge seams were fixed along the way:

  1. 51ff0f88/218db32e: the merges reordered build_fetch_context's cookie-domain match so the web_is_opt_in guard lost its position ahead of the Hyper session-only arm in the cookie-domain-present branch; the stored-cookie test caught Zed Auto being rewritten to Web. Restored the guard arm there (218db32e).
  2. 4eedc069 merges the thermo-review commit that had landed on origin after the ledger head.

Checks at 4eedc06 (CARGO_TARGET_DIR=W:\cargo-target\lane-a, jobs=4, RUST_TEST_THREADS=4):

  • cargo fmt --all --check: pass.
  • cargo clippy both manifests --all-targets -- -D warnings: only the 3 documented pre-existing main-drift findings; 0 in this PR's diff.
  • cargo test rust manifest: 2303 passed / 0 failed / 1 ignored (zed focused: 56/0).
  • cargo test desktop manifest: 490 passed / 1 failed — bootstrap_payload_exposes_every_provider_variant, the documented Isolate bootstrap payload test from real settings #684 environment-dependent baseline on branches without Make the bootstrap catalog test hermetic (#684) #711 (expected; hermetic fix lives on release/v0.70.0). The zed guard regression test is green.
  • Vitest UsageSourceSection.test.tsx: 3 passed.

Fast-forward push chain bd005516..4eedc069 (ls-remote verified).

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