Skip to content

Port upstream 0.67.0: Raycast provider - #668

Draft
Finesssee wants to merge 2 commits into
port/upstream-0.67.0from
port/micro-0.67.0-raycast
Draft

Finesssee wants to merge 2 commits into
port/upstream-0.67.0from
port/micro-0.67.0-raycast

Conversation

@Finesssee

Copy link
Copy Markdown
Collaborator

Summary

Adds the Raycast AI credits provider (upstream CodexBar 0.67.0). It reads monthly credits from the signed-in www.raycast.com session and shows credits left, plan, and renewal date.

Upstream reference

  • Upstream release tag v0.67.0 (read-only, tag-pinned GET): Raycast provider, frontend_api/current_user/ai_credits.
  • Provider icon copied from the upstream v0.67.0 tag.

Ported

  • New ProviderId::Raycast (raycast, alias raycast-ai, cookie domain www.raycast.com, brand #FF6363), factory arm, no-token-account entry.
  • rust/src/providers/raycast/: request (Cookie, Accept, Origin, Referer, Chrome User-Agent), parse rules (numeric or numeric-string amounts; negative/invalid amounts, bad dates, non-object funding_subscription are parse failures), cookie filtering (only __raycast_session and csrf_token, exact host first), classified errors (missing/expired session, 403, 429, 5xx).
  • Auto imports from Chrome; a Manual header is pinned and never falls back to a browser; Off makes no request. 401 advances to the next candidate within one refresh; other failures stop retries.
  • Shell cookie-source options (auto/manual/off), tray dashboard link, settings source hint, frontend and dashboard icons, provider catalog fixture, docs, README row, changelog.

Deferred / caveats

  • Chrome Windows App-Bound Encryption may block automatic import; Manual is the fallback.
  • Chrome channels/Chromium profiles (upstream feat(browser): support Chrome channels and Chromium profiles #614) are not in this base; Auto reads all Chrome profiles merged.
  • Top-up packages and credits/details are not fetched.
  • The global default cookie source is Manual, so users choose Auto.
  • The shell maps Off to the CLI source mode, so the message says cookies are disabled.
  • Amount formatting rounds ties per Rust, which may differ marginally from JS toFixed.

Validation

  • cargo fmt --all: clean.
  • cargo clippy --workspace --all-targets -- -D warnings: pass.
  • cargo test -p codexbar raycast: 29 passed.
  • cargo test -p codexbar (full): 2189 passed, 0 failed, 1 ignored.
  • cargo test -p codexbar-desktop-tauri: 464 passed, 1 failed (commands::tests::bootstrap_payload_exposes_every_provider_variant: catalog 80 vs 79 active). That test calls get_bootstrap_state(), which loads this machine's real settings, so a deprecated provider that is enabled locally adds one catalog entry. It is environment-dependent and unrelated to the Raycast change; the three new Raycast shell tests pass.
  • pnpm test (vitest): 67 files, 402 tests passed.
  • pnpm run build: pass.

Affected areas

Shared: ProviderId, provider factory, token accounts, providers/mod.rs (new browser_cookies_from_browser helper). Shell: cookie-source options. Frontend: icon registry, tray dashboard set, settings source hint.

UI proof

Pending: coordinator will capture CUA proof on a fresh build. This PR is a draft for that reason.

Adds the Raycast AI credits provider (cookie-backed frontend_api/current_user/ai_credits), its cookie-source options, icons, catalog registration, and docs.
@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

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

Scope: head 4c68ec9 against the raycast entry in the 0.67.0 audit and AGENTS.md / PORTING.md section 5. The provider is well factored (cookies.rs / parse.rs / mod.rs / tests.rs), no file crosses 1000 lines because of this PR, registration matches the Replicate template file-for-file, and the spec matrix (invalid amounts, exact-host precedence, Manual pinned, Off makes no request, 401 advance) is covered by tests. Findings are small.

Fix in this review:

  1. parse.rs: amount + non_negative_amount were a two-layer wrapper whose only caller was the second layer. Folded the sign check into amount (one function, one error path, same messages).
  2. mod.rs::check_status: an if/else chain with an early return inside a let initializer. Rewritten as a match on StatusCode, same messages and mapping.

Left as-is, with reasons:

  1. error_state_kind compares error text to the MISSING_SESSION / SESSION_EXPIRED constants. It is a magic-string identity, but the trait doc explicitly allows a message guard, both strings are consts used at the raise site, and a typed alternative (NoCookies, OAuthExpired) would either change user-facing copy or need a new ProviderError variant in shared code. Tests pin the classification.
  2. Chrome cookies from all profiles are merged with no profile identity, so the optional csrf_token can come from a different profile than the session. The spec says CSRF is not required for this GET and to forward it when present; fixing this needs profile data on Cookie (shared browser layer), out of scope for a micro port.
  3. Request timeout: spec default is 15 s but the shell always passes web_timeout (60), so the clamp yields 30 s. Changing that means a per-provider default in shared fetch-context plumbing; not worth it here.
  4. Hardcoded English in cookie_source_options_for("raycast") follows the existing Replicate / Helmcode pattern in that function; locale keys for that catalog are a separate cleanup.
  5. TrayPanel.tsx HAS_DASHBOARD is a hand-maintained id set (pre-existing design); the one-word addition is consistent.

No UI-visible change comes from the fixes.

@Finesssee

Copy link
Copy Markdown
Collaborator Author

Thermo-nuclear review follow-up

Reviewed by Codex gpt-6-luna (xhigh); verified and validated by Claude. Fixes landed at d16c04d.

Fixed:

  • parse.rs: folded amount and non_negative_amount into one function; object helper removed (root uses as_object, funding_subscription matched inline; null and absent both read as no subscription).
  • mod.rs::check_status: rewritten as a match on StatusCode, same messages.
  • provider_settings.rs: Raycast cookie-source help text moved to locale keys (ProviderRaycast*), translated in all eight catalogs (English text unchanged).

Left out:

  • Codex also proposed making funding_subscription: null a parse failure. Not applied: the spec only lists {} as the empty-subscription fixture, and upstream decodes the field as optional, so null stays valid.
  • Earlier items 3 to 5 and 7 remain as explained in the first review.

Commands run: cargo +1.98.0 fmt --all, cargo +1.98.0 clippy --workspace --all-targets -- -D warnings (clean), cargo +1.98.0 test -p codexbar raycast (29 passed), -p codexbar locale (16 passed), -p codexbar-desktop-tauri cookie_source (7 passed). No desktop app run; UI change is limited to localized help text.

@Finesssee

Copy link
Copy Markdown
Collaborator Author

CUA proof

Build commit: d16c04d889369068261734445358adafcee7a162 (PR head). Debug desktop build, driven with cua-driver CLI in the background on a second monitor (no focus, keyboard or mouse taken). Fully isolated profile (CODEXBAR_PROOF_HOME) and a local mock; no real account data on screen.

Blocker found while building (PR code, not proof-only): unpatched head fails pnpm run tauri:build:debug because beforeBuildCommand runs pnpm run build -> check-locale: DRIFT DETECTED rust=882 ts=879; only in Rust: ProviderRaycastAutoImportHelp, ProviderRaycastManualCookieHelp, ProviderRaycastCookiesDisabled. The PR adds the keys to rust/src/locale.rs and the .ftl files but not to apps/desktop-tauri/src/i18n/keys.ts (ALL_LOCALE_KEYS). Any hosted gate that runs pnpm run build will fail until they are added.

Proof-only patches (uncommitted, restored afterwards):

  • Root Cargo.toml [patch.crates-io] dirs shim redirecting home/config/data dirs under CODEXBAR_PROOF_HOME (plus Cargo.lock).
  • rust/src/providers/raycast/mod.rs RaycastProvider::new(): env CODEXBAR_PROOF_RAYCAST_ORIGIN overrides the https origin, client .no_proxy(). Real fetch path runs against a local python mock; TLS/URL validation otherwise untouched.
  • apps/desktop-tauri/src/i18n/keys.ts: the 3 missing Raycast keys added so the build could pass (works around the blocker above).

Commands: bash launch.sh trayPanel | popOut | settings:providers, MOCK_VARIANT=nototal|expired bash launch.sh trayPanel; cua-driver call get_window_state ... --screenshot-out-file.

# Assertion Result
0 No real email/account from the machine visible; only Raycast provider present PASS
1 Dark theme under auto in tray, pop-out and settings PASS
2 Tray/pop-out: Raycast only, no error, "Credits" meter 25% used, plan Pro+ PASS
2b Reset 2026-12-01 PASS in Settings > Providers ("Resets in 61d 11h"); not shown in the compact tray card
2c Text "750 / 1000 credits left" NOT VISIBLE for the metered case (set as reset_description, but the UI shows the reset text instead); minor
3 Mock saw only __raycast_session and csrf_token; unrelated cookies stripped, no 401 PASS
4 nototal: no meter/percentage, Left 12.5 and Total 0 rows PASS. Note the summary reads "12.5 / 0 credits left" (Some(total=0) formatted as a pair), not "12.5 credits left"; cosmetic
5 expired: "Raycast website session expired. Sign in at www.raycast.com/settings or paste a fresh Cookie header." PASS
6 Settings: Raycast row enabled, cookie source Automatic / Manual / Disabled with Manual selected and helper "Paste a Cookie header from www.raycast.com/settings." PASS (Automatic helper text not checked: selecting Auto would read Chrome)
7 Logs under proof home; real %APPDATA%\CodexBar untouched PASS

Screenshots (local, not committed), C:\Users\FSOS\AppData\Local\Win-CodexBar\port-audit\proof\668\shots\: 01-tray-meter.png, 02-popout-meter.png, 03-settings-providers.png, 04-settings-cookie-source.png, 05-tray-nototal.png, 06-tray-expired.png.

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