Skip to content

Add DeepSeek platform session usage dashboard and status submenu#1910

Closed
Yuxin-Qiao wants to merge 16 commits into
steipete:mainfrom
Yuxin-Qiao:cursor/deepseek-usage-dashboard-3d19
Closed

Add DeepSeek platform session usage dashboard and status submenu#1910
Yuxin-Qiao wants to merge 16 commits into
steipete:mainfrom
Yuxin-Qiao:cursor/deepseek-usage-dashboard-3d19

Conversation

@Yuxin-Qiao

@Yuxin-Qiao Yuxin-Qiao commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add DeepSeek platform web-session support (cookie/localStorage import, account summary, identity, usage amount/cost enrichment) so balance and usage work with or without an API key.
  • Show the upstream-style inline usage dashboard in the menu card and a hosted Token usage details submenu with per-day/per-model breakdown, cache-hit metrics, and a 7d/30d usage chart.
  • Poll DeepSeek's Flashcat status feed and surface a native Status Page submenu (API Service / Web Chat Service) alongside the existing website link.

Screenshots

Menu card (inline usage dashboard)

DeepSeek menu card with balance, today/month KPIs, sparkline, and cache breakdown

Token usage details submenu

DeepSeek token usage details submenu with 30d chart and per-model cache-hit breakdown

Status Page submenu

DeepSeek native status submenu showing API Service and Web Chat Service operational

Settings panel

DeepSeek settings with usage summary source and usage dashboard link

Test plan

  • swift test --filter DeepSeek
  • make check
  • ./Scripts/compile_and_run.sh — menu card, token usage submenu, and status submenu verified locally
  • Upstream maintainer: confirm browser cookie import on user-initiated refresh only (no background Keychain prompts)

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper

clawsweeper Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codex review: needs changes before merge. Reviewed July 5, 2026, 12:33 PM ET / 16:33 UTC.

Summary
Adds DeepSeek platform web-session support, usage/account enrichment, native usage dashboard and status submenus, settings/docs/screenshots, and focused DeepSeek tests.

Reproducibility: yes. for the review finding: source inspection shows the user-initiated availability path catches importer errors, but the fetch candidate path still swallows the same importer error with try?. I did not run live DeepSeek browser import because repository policy warns against validation that can trigger Keychain or browser permission prompts.

Review metrics: 2 noteworthy metrics.

  • Diff size: 49 files, +5,393/-160. This is a broad provider, UI, docs, screenshot, and test change, so maintainer review should focus on integration boundaries, not only the visible menu.
  • Credential import paths: 3 added paths. The PR adds Chrome cookie import, localStorage bearer import, and live Chrome-tab AppleScript bearer import for DeepSeek sessions.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster ✨ media proof bonus
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Propagate user-initiated DeepSeek browser-import setup errors through the fetch path and add a focused regression test.

Risk before merge

  • [P1] DeepSeek browser permission/import failures are still downgraded to a generic invalid-session path during fetch.
  • [P1] The PR adds credential-sensitive DeepSeek cookie, localStorage, cached bearer, and Chrome AppleScript import paths that need explicit maintainer acceptance before merge.
  • [P2] The new API/web source modes and fallback behavior change DeepSeek credential routing for existing API-key users, so upgrade behavior should stay covered by focused tests.

Maintainer options:

  1. Fix import-error propagation first (recommended)
    Propagate DeepSeekCookieImporter.importSessions setup errors through the user-initiated web fetch path when no explicit or cached session is available.
  2. Accept the credential scope after the fix
    Maintainers can explicitly accept the new cookie/localStorage/live-tab credential import surface once the actionable setup-error path works.
  3. Narrow or pause automatic import
    If the browser credential surface is too broad, keep web-session support manual/env-only or pause the PR for a smaller follow-up.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Fix DeepSeek browser-import error propagation before merge: avoid swallowing `DeepSeekCookieImporter.importSessions` errors with `try?` in the user-initiated app fetch path, preserve manual/off/background behavior, and add a focused DeepSeek test proving `DeepSeekSettingsError.missingCookie(details:)` reaches the fetch outcome.

Next step before merge

  • [P2] A narrow automated repair can address the remaining source-level blocker by preserving the actionable browser-import error instead of swallowing it.

Maintainer decision needed

  • Question: After the error-propagation blocker is fixed, should CodexBar support DeepSeek platform web-session import from Chrome cookies, localStorage, and a live Chrome tab as a core provider capability?
  • Rationale: This PR adds new credential collection and caching behavior for browser cookies and bearer tokens, which is a maintainer-owned security/product boundary even though the implementation is mostly scoped to user-initiated refreshes.
  • Likely owner: steipete — He owns the current DeepSeek provider implementation on main and is the repository owner most likely to decide the credential-import boundary.
  • Options:
    • Accept scoped web-session support (recommended): Keep the feature in core with user-initiated browser import, manual/env sessions, explicit settings, and focused regression coverage.
    • Narrow to manual/env sessions: Remove automatic Chrome/localStorage/live-tab import and support only pasted or environment-provided platform sessions for now.
    • Defer the credential surface: Close or pause this PR until the project has a broader policy for browser-session imports across providers.

Security
Cleared: No concrete secret leak or supply-chain issue was found, but the credential-import surface remains a maintainer security-boundary decision before merge.

Review findings

  • [P2] Propagate DeepSeek browser-import access errors during fetch — Sources/CodexBarCore/Providers/DeepSeek/DeepSeekWebEnrichmentResolver.swift:36-37
Review details

Best possible solution:

Land the feature only after user-initiated browser-import errors propagate with actionable setup guidance and maintainers accept the DeepSeek web-session credential scope.

Do we have a high-confidence way to reproduce the issue?

Yes for the review finding: source inspection shows the user-initiated availability path catches importer errors, but the fetch candidate path still swallows the same importer error with try?. I did not run live DeepSeek browser import because repository policy warns against validation that can trigger Keychain or browser permission prompts.

Is this the best way to solve the issue?

No: the feature direction is useful, but the current patch is not the best mergeable solution until browser-import setup errors propagate from the fetch path instead of becoming generic invalid credentials.

Full review comments:

  • [P2] Propagate DeepSeek browser-import access errors during fetch — Sources/CodexBarCore/Providers/DeepSeek/DeepSeekWebEnrichmentResolver.swift:36-37
    The latest availability change returns true when importSessions throws so setup errors can reach fetch, but candidates immediately calls the importer through try? and turns the same error into an empty list. A first-time Chrome permission or Full Disk Access failure still falls through to invalidCredentials, so users lose the actionable browser-import hint; carry the importer error out of the user-initiated fetch path when no explicit or cached candidate exists.
    Confidence: 0.91

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 8e9a844dbd36.

Label changes

Label changes:

  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🦐 gold shrimp, so this older rating label is no longer current.

Label justifications:

  • P2: The PR is a normal-priority DeepSeek provider enhancement with one blocking but bounded setup-error bug.
  • merge-risk: 🚨 compatibility: The PR adds DeepSeek source modes and web-session fallback behavior that can affect existing API-key setups and upgrade expectations.
  • merge-risk: 🚨 auth-provider: The diff changes DeepSeek credential routing across API keys, manual sessions, environment sessions, browser cookies, cached sessions, and web-only fallback.
  • merge-risk: 🚨 security-boundary: The PR reads and caches browser cookies and bearer tokens, including localStorage and live Chrome-tab token sources.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (screenshot): The PR body includes screenshots that visibly show the DeepSeek menu card, token usage submenu, status submenu, and settings panel after the change.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes screenshots that visibly show the DeepSeek menu card, token usage submenu, status submenu, and settings panel after the change.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR body includes screenshots that visibly show the DeepSeek menu card, token usage submenu, status submenu, and settings panel after the change.
Evidence reviewed

Acceptance criteria:

  • [P1] swift test --filter DeepSeek.
  • [P1] make check.

What I checked:

Likely related people:

  • steipete: Current main’s DeepSeek provider descriptor, usage fetcher, and app provider implementation all trace to Peter Steinberger’s v0.39.0 commit, making him the clearest owner for DeepSeek provider behavior. (role: introduced behavior; confidence: high; commits: e437044c32ba; files: Sources/CodexBarCore/Providers/DeepSeek/DeepSeekProviderDescriptor.swift, Sources/CodexBarCore/Providers/DeepSeek/DeepSeekUsageFetcher.swift, Sources/CodexBar/Providers/DeepSeek/DeepSeekProviderImplementation.swift)
  • Sailesh Sivakumar: Recent current-main work touched shared provider fetch infrastructure used by this PR’s DeepSeek API/web strategy pipeline. (role: adjacent owner; confidence: low; commits: 9a0028442e35; files: Sources/CodexBarCore/Providers/ProviderFetchPlan.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (9 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-05T13:11:00.439Z sha 977e2cd :: needs real behavior proof before merge. :: [P1] Keep API balance unless the web account is matched
  • reviewed 2026-07-05T13:16:30.403Z sha 977e2cd :: needs real behavior proof before merge. :: [P1] Keep API balance unless the web account is matched | [P1] Let no-key auto import reach the web strategy
  • reviewed 2026-07-05T13:28:15.939Z sha 977e2cd :: needs real behavior proof before merge. :: [P1] Keep API balance unless the web account is matched | [P1] Let no-key auto import reach the web strategy
  • reviewed 2026-07-05T13:50:52.417Z sha f65d612 :: needs real behavior proof before merge. :: [P1] Require a positive account match before replacing API balance
  • reviewed 2026-07-05T14:21:02.812Z sha b07a23f :: needs changes before merge. :: [P1] Require a positive match before replacing API balance
  • reviewed 2026-07-05T14:49:50.411Z sha 214b1cf :: needs changes before merge. :: [P1] Require a positive account match before replacing API balance | [P2] Preserve bearer headers when caching web sessions | [P2] Let manual DeepSeek web sessions run on Linux CLI | [P2] Filter rolling windows by calendar date | [P2] Keep cost charts from mixing token units
  • reviewed 2026-07-05T14:56:47.963Z sha a5d3b4e :: needs changes before merge. :: [P1] Require a positive match before replacing API balance | [P2] Preserve bearer headers when caching web sessions | [P2] Let manual DeepSeek web sessions run on Linux CLI | [P2] Filter rolling windows by calendar date | [P2] Keep cost charts from mixing token units | [P2] Treat nested DeepSeek auth codes as invalid credentials
  • reviewed 2026-07-05T16:01:45.719Z sha 2a0f1cc :: found issues before merge. :: [P1] Require a verified match before replacing API balance | [P2] Keep prior-month usage fetches best-effort | [P2] Surface browser-import access errors | [P2] Keep balance alerts out of session quota depletion | [P2] Keep the live probe from overwriting real config

Co-authored-by: Cursor <cursoragent@cursor.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

if DeepSeekSettingsReader.apiKey(environment: context.environment) != nil {
return true
}
return !context.settings.tokenAccounts(for: .deepseek).isEmpty

P1 Badge Treat web-only DeepSeek credentials as available

When a user has only a DeepSeek platform session (manual DEEPSEEK_COOKIE, cached browser session, or auto-imported cookies) and no API key/token account, this availability check returns false. UsageStore.enabledProviders()/enabledProvidersForBackgroundWork() filters unavailable providers before fetching, so the new DeepSeekWebOnlyFetchStrategy is never reached and the advertised no-API-key web path stays hidden/unrefreshed.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

throw DeepSeekUsageError.invalidCredentials
}
// Both are optional/best-effort: a failure in one must not drop the other.
let summary = try? await self.fetchAccountSummary(session: session)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve non-auth DeepSeek account errors

When get_user_summary fails for a transient platform error, parse drift, or cancellation, this try? converts the failure into nil; DeepSeekWebOnlyFetchStrategy.fetch then treats the missing summary as invalidCredentials and clears cached candidates. That can evict a valid cached session and report it as expired even though the session was not rejected, so non-auth summary failures should propagate while only optional identity/usage enrichment is downgraded.

Useful? React with 👍 / 👎.

Comment on lines +206 to +207
let cookieHeader = DeepSeekCookieHeader.header(from: cookies)
?? DeepSeekCookieHeader.supplementalHeader(from: cookies)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require bearer auth before using supplemental cookies

This fallback turns any DeepSeek-domain browser cookie into a session, including WAF/tracking cookies from a logged-out profile, even though supplementalHeader is documented as only useful when a bearer token is present. In that logged-out/expired-browser scenario hasSession() reports DeepSeek as available and the web fetch then sends unauthenticated cookies and fails as invalid credentials; only use the supplemental header after a localStorage/live-tab bearer token has been found.

Useful? React with 👍 / 👎.

Comment on lines +17 to +18
if let cached = CookieHeaderCache.load(provider: .deepseek),
let session = DeepSeekCookieHeader.session(from: cached.cookieHeader)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep manual DeepSeek mode from falling back to cache

When the user selects Manual mode, this cached-session branch still runs after the explicit manual candidate. If the pasted header is empty/expired but a cached or browser session exists, refresh can silently show usage for that cached browser account instead of failing the manually selected credentials, which breaks account selection/isolation for users switching DeepSeek accounts.

Useful? React with 👍 / 👎.

if wallets.contains(where: { $0.currency == "USD" && (Double($0.balance ?? "") ?? 0) > 0 }) {
return "USD"
}
return normal.first?.currency ?? bonus.first?.currency ?? "CNY"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prefer a funded wallet over the first empty currency

For platform account summaries with multiple wallets, this falls back to the first wallet's currency whenever USD is not funded. If DeepSeek returns an empty USD wallet before a positive CNY wallet, the parser selects USD, walletBalance returns 0, and the menu shows “add credits” even though the account has CNY balance; mirror the API balance parser's positive-balance preference before falling back to the first row.

Useful? React with 👍 / 👎.

Comment on lines +85 to +86
func shouldFallback(on _: Error, context _: ProviderFetchContext) -> Bool {
false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fall back to web when the API key is rejected

In Auto mode with both a configured API key and a valid platform web session, any stale or revoked API key stops the pipeline here before the queued deepseek.web strategy can run. That leaves users with working browser credentials seeing an API-key error instead of the new web-only balance/usage path; fallback should be allowed for missing/unauthorized API-key failures.

Useful? React with 👍 / 👎.

Comment on lines +133 to +135
let bearer = liveBearer
?? bearerByLabel[session.sourceLabel]
?? bearerByLabel.first(where: { self.normalizeStorageLabel($0.key) == normalizedLabel })?.value

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid applying one profile bearer to all sessions

With multiple Chrome profiles/accounts, this chooses a live-tab bearer token before any label-matched localStorage token, so every imported cookie session is paired with the active tab's account token. The first sorted profile can then fetch/cache usage for a different DeepSeek account than its cookies/source label, so prefer same-label tokens and only use a global live bearer when there is no profile-specific session to pair.

Useful? React with 👍 / 👎.

Comment on lines +109 to +112
currency: account.summary?.currency ?? enriched.currency,
totalBalance: account.summary?.totalBalance ?? enriched.totalBalance,
grantedBalance: account.summary?.grantedBalance ?? enriched.grantedBalance,
toppedUpBalance: account.summary?.paidBalance ?? enriched.toppedUpBalance,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don't overwrite API balance with an unmatched web account

When an API key and browser session belong to different DeepSeek accounts, enrichment replaces the API-key balance/currency with the web session's wallet values. That can make the menu show the browser account's balance while the fetch source/API key is for another account; without an identity match between the two sources, web data should not override the API balance.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jul 5, 2026
Move session bearer sanitization to cross-platform code, treat web-only
sessions as available, isolate manual/auto/off credential sources, and
add focused regression tests for browser-import gating.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 5, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 977e2cdb18

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

return true
}
#endif
return false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Let auto mode run before a cookie is cached

In Auto mode with no API key, no pasted/env session, and no previously validated cache, this marks DeepSeek unavailable, so UsageStore.enabledProvidersForBackgroundWork() filters it out before a user-initiated refresh can reach DeepSeekCookieImporter.importSessions. That makes the documented first-time browser import path unreachable for users who are only logged in via Chrome; it only starts working after some other path has already created the cache.

Useful? React with 👍 / 👎.

}),
noDataMessage: { "DeepSeek usage summaries need a platform.deepseek.com web session." }),
fetchPlan: ProviderFetchPlan(
sourceModes: [.auto, .web, .api],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor DeepSeek source selections in the app

Advertising .web and .api here makes DeepSeek configs with source = "web" or source = "api" pass validation, but the app still gets its fetch mode from ProviderCatalog.implementation(...).sourceMode(...); DeepSeekProviderImplementation does not override the default .auto or read providerConfig.source like the other source-selectable providers do. In the app, a user trying to force web-only or API-only DeepSeek refreshes is silently run through Auto mode instead, so the advertised source selection cannot be enforced.

Useful? React with 👍 / 👎.

windsurf: WindsurfProviderSettings? = nil,
perplexity: PerplexityProviderSettings? = nil,
mimo: MiMoProviderSettings? = nil,
deepseek: DeepSeekProviderSettings? = nil,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Populate DeepSeek settings in CLI snapshots

This adds DeepSeek settings to the shared snapshot, but the CLI snapshot factory was not updated: TokenAccountCLI.makeCookieBackedSnapshot and its makeSnapshot wrapper still have no DeepSeek case/parameter. In CLI runs, context.settings?.deepseek therefore stays nil, so codexbar usage deepseek --source web ignores a DeepSeek cookie_header/manual session from config and also ignores cookie_source = "off" instead of honoring the user's configured web-session source.

Useful? React with 👍 / 👎.

Yuxin-Qiao and others added 3 commits July 5, 2026 21:47
Treat macOS auto mode as available before cache exists, wire provider
config source into app fetch mode, and populate DeepSeek settings in CLI
snapshots.

Co-authored-by: Cursor <cursoragent@cursor.com>
Extract simple provider cookie snapshots into a helper so adding DeepSeek
does not exceed the cyclomatic complexity limit.

Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve Settings at each makeSnapshot call site so cross-platform builds
can compile the extracted provider cookie snapshot helper.

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jul 5, 2026
Remove redundant return keywords so macOS CI swiftformat --lint passes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 5, 2026
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. label Jul 5, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8df16e3bd8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +100 to +102
CookieHeaderCache.store(
provider: .deepseek,
cookieHeader: payload,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve bearer headers when caching web sessions

For imported sessions that include both a cookie and a localStorage/live-tab bearer, candidate.session.storagePayload is two lines (Authorization then Cookie), but CookieHeaderCache.store runs CookieHeaderNormalizer.normalize, whose cookie regex extracts only the Cookie line. After the first successful user-initiated import, the cached candidate therefore loses the bearer and background refreshes fail for sessions that require it, including supplemental-cookie bearer sessions.

Useful? React with 👍 / 👎.

Comment on lines +17 to +18
public var last7DaysTokens: Int {
self.daily.suffix(7).reduce(0) { $0 + $1.totalTokens }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Filter 7-day DeepSeek metrics by calendar date

The DeepSeek daily array is sparse because the parser only emits dates returned by the API, so suffix(7) means the last seven non-empty rows rather than the last seven calendar days. An account with no usage this week but a few rows from 10+ days ago will still show those tokens/cost in the “7d” KPI and chart via trendDays(last:), overstating recent usage; filter by date relative to updatedAt or fill zero days.

Useful? React with 👍 / 👎.

}),
noDataMessage: { "DeepSeek usage summaries need a platform.deepseek.com web session." }),
fetchPlan: ProviderFetchPlan(
sourceModes: [.auto, .web, .api],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Let manual DeepSeek web sessions run on Linux CLI

With .web advertised here, non-macOS CLI preflight treats DeepSeek like a browser-import provider: sourceModeRequiresWebSupport returns true for .web/.auto providers unless they have a manual-cookie exception, and DeepSeek has none. So codexbar usage deepseek --source web with cookie_header or DEEPSEEK_PLATFORM_SESSION exits as unsupported before the new settings.deepseek snapshot reaches DeepSeekWebOnlyFetchStrategy.

Useful? React with 👍 / 👎.

Comment on lines +115 to +118
} else {
BarMark(
x: .value(L("Day"), point.date, unit: .day),
y: .value(L("tokens"), point.totalTokens))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid mixing token bars into cost trends

When any day has cost data, prefersCostTrend makes this chart a cost trend, but days whose point.cost is nil fall into this token branch. A partially populated cost response then plots CNY/USD amounts and token counts on the same hidden y-axis, so a single missing-cost day can dwarf the spend bars and make the DeepSeek usage submenu misleading; render zero/empty cost bars or switch the whole series to tokens consistently.

Useful? React with 👍 / 👎.

Comment on lines +177 to +179
let object = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let code = object["code"] as? Int
else {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat nested DeepSeek auth codes as invalid credentials

When DeepSeek wraps an auth failure in the already-modeled data.biz_code field with top-level code == 0, this guard returns false and the account/usage parsers later throw apiError instead of invalidCredentials. In that expired-session response shape, cached web sessions are not cleared and the user sees a generic API error rather than the session-expired path; check nested biz_code 40002/40003 before returning false.

Useful? React with 👍 / 👎.

Yuxin-Qiao and others added 3 commits July 5, 2026 22:45
Co-authored-by: Cursor <cursoragent@cursor.com>
…e body.

Keeps type_body_length lint green after main adds Claude swap support.

Co-authored-by: Cursor <cursoragent@cursor.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a5d3b4e93f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +509 to +510
priorAmountData = try await self.fetchAmount(session: session, month: prior.month, year: prior.year)
priorCostData = try await self.fetchCost(session: session, month: prior.month, year: prior.year)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep prior-month DeepSeek fetch best-effort

During the first 29 days of a month, a transient/server failure on either prior-month request throws out of fetchUsageSummary after the current-month amount and cost calls have already succeeded. Because the prior data is only supplemental for rolling 30-day windows, this makes all DeepSeek usage KPIs/chart data disappear for early-month refreshes instead of showing the available current-month data; treat these prior fetches as optional and parse with nil prior data on failure.

Useful? React with 👍 / 👎.

}
#if os(macOS)
if DeepSeekWebEnrichmentResolver.allowsBrowserCookieImport(context: context),
DeepSeekCookieImporter.hasSession(browserDetection: context.browserDetection)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Surface DeepSeek browser-import access errors

When Chrome cookie import hits a permission/access error on a first-time browser setup, hasSession wraps importSessions in try?, so this availability probe returns false and the web strategy is skipped before DeepSeekSettingsError.missingCookie(details:) can surface the Full Disk Access/browser hint. The user then sees a generic no-strategy/credentials failure even though the actionable error was already produced; avoid using the lossy probe here or propagate the import error when no explicit/cache candidate exists.

Useful? React with 👍 / 👎.

accountOrganization: nil,
loginMethod: nil)
let balanceWindow = RateWindow(
usedPercent: 100,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid treating low-balance alerts as quota depletion

When a DeepSeek account has a nonzero balance below its configured alert bound, setting the primary window to usedPercent: 100 makes UsageStore.sessionQuotaWindow treat this balance row as a depleted session quota because nil-duration primary windows are considered session windows. With session quota notifications enabled, users can get a false “depleted” notification even though they still have credit; keep the alert text/styling separate from the depleted percentage or exclude this balance alert from session quota tracking.

Useful? React with 👍 / 👎.

Yuxin-Qiao and others added 4 commits July 5, 2026 23:44
Preserve bearer+cookie cache payloads, filter rolling usage by calendar day,
allow Linux CLI web mode with manual sessions, keep cost charts on one axis,
and treat nested DeepSeek auth biz_code failures as invalid credentials.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot removed the rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. label Jul 5, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. and removed merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. proof: sufficient Contributor real behavior proof is sufficient. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jul 5, 2026
Require verified email match before replacing API balances, keep prior-month
usage enrichment best-effort, surface browser-import failures during fetch,
avoid false quota depletion from balance alerts, and isolate the live Chrome
probe config write to a temp file.

Co-authored-by: Yuxin Qiao <Yuxin-Qiao@users.noreply.github.com>
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 5, 2026
@Yuxin-Qiao

Copy link
Copy Markdown
Contributor Author

Closing for now — need to revisit the approach; current changes need more work before merge.

@Yuxin-Qiao Yuxin-Qiao closed this Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants