Skip to content

fix(kimi): recover monthly Total usage from Desktop Local Storage - #3537

Open
OttoPrua wants to merge 1 commit into
steipete:mainfrom
OttoPrua:fix/kimi-desktop-monthly-quota
Open

fix(kimi): recover monthly Total usage from Desktop Local Storage#3537
OttoPrua wants to merge 1 commit into
steipete:mainfrom
OttoPrua:fix/kimi-desktop-monthly-quota

Conversation

@OttoPrua

Copy link
Copy Markdown

Summary

  • Current Kimi Desktop keeps the web access JWT in Local Storage and often no longer writes a kimi-auth cookie, so Auto never calls GetSubscriptionStats.
  • Code API 7-day / 5-hour windows can reset to unused while the shared monthly membership pool is already empty.
  • Read the Desktop Local Storage access JWT automatically (skip refresh / expired tokens), and prefer an exhausted extra window (Total usage) in automatic menu-bar mode.

Fixes #3536

Test plan

  • Stay signed into current Kimi Desktop with no kimi-auth cookie; Cookie source Automatic; API key configured
  • Confirm CodexBar recovers a live Desktop access JWT and enriches monthly Total usage from GetSubscriptionStats
  • Exhaust the monthly pool and confirm automatic menu bar shows 100% Total usage instead of unused 5-hour / 7-day windows
  • Confirm an existing Cookies kimi-auth still wins over Local Storage, and refresh / expired JWTs are ignored
  • swift test --filter KimiDesktopAuthTokenTests and swift test --filter KimiProviderTests

Made with Cursor

Current Desktop no longer writes kimi-auth cookies, so an exhausted membership pool stayed hidden behind unused Code rate-limit windows.

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

clawsweeper Bot commented Sep 10, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-10T10:01:33.334949Z a7afc05 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Sep 10, 2026
@clawsweeper

clawsweeper Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed September 10, 2026, 5:58 AM ET / 09:58 UTC.

ClawSweeper review

What this changes

The PR adds Kimi Desktop Local Storage token discovery and makes the automatic menu-bar indicator prioritize exhausted monthly usage, with tests and documentation.

Merge readiness

Blocked before merge - 8 items remain

This remains useful work for the linked issue: neither current main nor v0.58.0 resolves both reported gaps. The patch has a credential-selection defect, a failing test fixture, and no after-fix runtime proof.

Priority: P2
Reviewed head: a7afc05e59f76cf39c350eb9ad9b52429c18e621
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The focused repair has useful value, but credential resurrection, a broken fixture, and absent runtime proof prevent merge readiness.
Proof confidence 🦪 silver shellfish (2/6) Needs real behavior proof before merge: Authority-chain proof required: the supplied body contains an unchecked plan, with no after-fix Desktop-to-membership-request trace or exhausted-month indicator result. Evidence must show current-session success and rejection of deleted or replaced credentials before network dispatch, alongside preserved manual and Off controls. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🦐 gold shrimp (3/6) Security review found an item that needs attention.

Verification

Check Result Evidence
Real behavior Needs proof Needs real behavior proof before merge: Authority-chain proof required: the supplied body contains an unchecked plan, with no after-fix Desktop-to-membership-request trace or exhausted-month indicator result. Evidence must show current-session success and rejection of deleted or replaced credentials before network dispatch, alongside preserved manual and Off controls. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 11 items Applicable repository guidance: Read the complete root AGENTS.md; no nested AGENTS.md or maintainer notes were found under the inspected paths. Applied credential isolation, focused testing, and read-only review constraints. VISION.md requires sign-off for provider authentication and privacy behavior changes.
Verified introduced scope: The host pins the original head directly to the fetched main parent and supplies a complete five-file introduced patch. Local numstat confirms production +132/-8, tests +54/-0, and documentation +5/-2.
Current main still omits monthly indicator selection: The main-branch resolver checks only primary and secondary windows; monthly membership usage is represented separately in extraRateWindows.
Findings 2 actionable findings [P1] Preserve deletion filtering when no current token exists
[P2] Use a JWT fixture that satisfies the extraction pattern
Security Needs attention Deleted credentials can reach authenticated requests: A tombstoned but unexpired Desktop access token can be recovered from historical LevelDB values and sent to Kimi. Expiry and audience checks do not prove that the user still has an active local session.

How this fits together

CodexBar’s Kimi provider combines Code usage with optional membership statistics fetched using a local web session. The resulting quota windows feed the menu-bar usage indicator.

flowchart TD
  A[Desktop session stores] --> B[Web token selection]
  B --> C[Kimi membership requests]
  D[Code API usage] --> E[Combined quota snapshot]
  C --> E
  E --> F[Automatic menu-bar indicator]
Loading

Decision needed

Question Recommendation
Approve extending Automatic Kimi Desktop credential discovery to current Local Storage access tokens after removing historical-token recovery? Approve bounded current-session discovery: Allow origin-scoped, deletion-aware access-token discovery after the defects and required proof are addressed.

Why: VISION.md explicitly requires sign-off for provider-authentication and privacy behavior changes; the existing cookie reader does not establish approval for the new storage scope.

Before merge

  • Add real behavior proof - Needs real behavior proof before merge: Authority-chain proof required: the supplied body contains an unchecked plan, with no after-fix Desktop-to-membership-request trace or exhausted-month indicator result. Evidence must show current-session success and rejection of deleted or replaced credentials before network dispatch, alongside preserved manual and Off controls. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Preserve deletion filtering when no current token exists (P1) - When Desktop deletes its access-token key, readEntries correctly returns no current value, but this fallback calls readTokenCandidates, which scans historical LevelDB entries without tombstone or origin filtering. A deleted JWT whose exp is still in the future is selected and passed to membership requests in Authorization/Cookie headers. Remove this raw fallback or replace it with current-record-aware discovery, and cover deletion before expiry so sign-out cannot resurrect a session.
  • Use a JWT fixture that satisfies the extraction pattern (P2) - The new extraction assertion expects makeJWT output to match jwtCandidates, but this helper emits the nine-character signature signature, while the production pattern requires at least ten signature characters. Consequently the assertion at line 90 returns an empty array on macOS. Use a realistic synthetic signature meeting the parser contract and run the focused suite.
  • Resolve security concern: Deleted credentials can reach authenticated requests - A tombstoned but unexpired Desktop access token can be recovered from historical LevelDB values and sent to Kimi. Expiry and audience checks do not prove that the user still has an active local session.
  • Resolve merge risk (P2) - The fallback can reuse a locally deleted session credential; whether Kimi rejects that credential server-side does not establish that CodexBar should send it.
  • Resolve merge risk (P1) - The current Desktop storage format and fresh-install versus upgraded-session behavior have not been demonstrated in the supplied proof.
  • Complete next step (P2) - Fix the credential fallback and JWT fixture, obtain authentication/privacy sign-off, and supply after-fix behavior and session-boundary proof before merge.
  • Resolve maintainer decision - Resolve the maintainer decision shown above before merge.

Findings

  • [P1] Preserve deletion filtering when no current token exists — Sources/CodexBarCore/Providers/Kimi/KimiDesktopAuthToken.swift:154-158
  • [P2] Use a JWT fixture that satisfies the extraction pattern — Tests/CodexBarTests/KimiDesktopAuthTokenTests.swift:202
  • [high] Deleted credentials can reach authenticated requests — Sources/CodexBarCore/Providers/Kimi/KimiDesktopAuthToken.swift:155
Agent review details

Security

Needs attention: The new historical-token fallback can bypass local session deletion; no dependency, workflow, or supply-chain changes were introduced.

Review metrics

Metric Value Why it matters
Production and test growth production +132/-8; tests +54/-0 Production growth supports the new credential source and quota selection, but the added tests do not exercise Local Storage deletion handling.

Merge-risk options

Maintainer options:

  1. Preserve current-session boundaries (recommended)
    Remove raw historical-token recovery and demonstrate that deleted or replaced sessions cannot authorize subsequent membership requests.
  2. Defer credential discovery
    Separate the menu-bar correction if the Local Storage authorization boundary cannot yet be established.

Technical review

Best possible solution:

Use approved, read-only current-session discovery that honors deletions and existing credential controls, while retaining the focused exhausted-month presentation change.

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

Yes, from source: current main ignores exhausted monthly extra windows, and its Desktop loader cannot read Local Storage. The introduced tombstone bypass and test-fixture mismatch are also source-traceable; no tests or live probes were run.

Is this the best way to solve the issue?

No, not as submitted: extending the existing owners is appropriate, but raw historical token scanning defeats current-session filtering and the new extraction test cannot pass.

Full review comments:

  • [P1] Preserve deletion filtering when no current token exists — Sources/CodexBarCore/Providers/Kimi/KimiDesktopAuthToken.swift:154-158
    When Desktop deletes its access-token key, readEntries correctly returns no current value, but this fallback calls readTokenCandidates, which scans historical LevelDB entries without tombstone or origin filtering. A deleted JWT whose exp is still in the future is selected and passed to membership requests in Authorization/Cookie headers. Remove this raw fallback or replace it with current-record-aware discovery, and cover deletion before expiry so sign-out cannot resurrect a session.
    Confidence: 0.99
  • [P2] Use a JWT fixture that satisfies the extraction pattern — Tests/CodexBarTests/KimiDesktopAuthTokenTests.swift:202
    The new extraction assertion expects makeJWT output to match jwtCandidates, but this helper emits the nine-character signature signature, while the production pattern requires at least ten signature characters. Consequently the assertion at line 90 returns an empty array on macOS. Use a realistic synthetic signature meeting the parser contract and run the focused suite.
    Confidence: 1

Overall correctness: patch is incorrect
Overall confidence: 0.98

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 7fdc17636f16.

Labels

Label changes:

  • add P2: This repairs provider-specific session discovery and misleading quota presentation with limited product-wide impact.
  • add merge-risk: 🚨 security-boundary: The new fallback can recover deleted credentials from historical storage records and send them in authenticated requests.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Authority-chain proof required: the supplied body contains an unchecked plan, with no after-fix Desktop-to-membership-request trace or exhausted-month indicator result. Evidence must show current-session success and rejection of deleted or replaced credentials before network dispatch, alongside preserved manual and Off controls. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Label justifications:

  • P2: This repairs provider-specific session discovery and misleading quota presentation with limited product-wide impact.
  • merge-risk: 🚨 security-boundary: The new fallback can recover deleted credentials from historical storage records and send them in authenticated requests.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: Authority-chain proof required: the supplied body contains an unchecked plan, with no after-fix Desktop-to-membership-request trace or exhausted-month indicator result. Evidence must show current-session success and rejection of deleted or replaced credentials before network dispatch, alongside preserved manual and Off controls. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Evidence

Security concerns:

  • [high] Deleted credentials can reach authenticated requests — Sources/CodexBarCore/Providers/Kimi/KimiDesktopAuthToken.swift:155
    A tombstoned but unexpired Desktop access token can be recovered from historical LevelDB values and sent to Kimi. Expiry and audience checks do not prove that the user still has an active local session.
    Confidence: 0.99

What I checked:

  • Applicable repository guidance: Read the complete root AGENTS.md; no nested AGENTS.md or maintainer notes were found under the inspected paths. Applied credential isolation, focused testing, and read-only review constraints. VISION.md requires sign-off for provider authentication and privacy behavior changes. (AGENTS.md:1, a7afc05e59f7)
  • Verified introduced scope: The host pins the original head directly to the fetched main parent and supplies a complete five-file introduced patch. Local numstat confirms production +132/-8, tests +54/-0, and documentation +5/-2. (a7afc05e59f7)
  • Current main still omits monthly indicator selection: The main-branch resolver checks only primary and secondary windows; monthly membership usage is represented separately in extraRateWindows. (Sources/CodexBarCore/Providers/Kimi/KimiProviderDescriptor.swift:113, 7fdc17636f16)
  • Latest release retains the Desktop discovery gap: The v0.58.0 Desktop loader reads only the Cookies database. Separate inspection of the release's provider descriptor also found primary/secondary-only automatic selection. (Sources/CodexBarCore/Providers/Kimi/KimiDesktopAuthToken.swift:23, 88fa2f45fa1e)
  • Dependency contract is directly exercised: The introduced importer calls SweetCookieKit's readEntries and readTokenCandidates APIs. Package.resolved identifies steipete/SweetCookieKit version 0.5.2 at d5ea6d92298779ec0c3ddf7d3d99da186a305e14; its source and root guidance were inspected through GitHub. (Sources/CodexBarCore/Providers/Kimi/KimiDesktopAuthToken.swift:146, a7afc05e59f7)
  • Raw scanning bypasses current-record filtering: readEntries processes deletion tombstones and filters origins. readTokenCandidates instead scans every historical entry's key and value, without applying either restriction. A deleted unexpired JWT remains a candidate for the PR's fallback. (Sources/SweetCookieKit/ChromiumLocalStorageReader.swift, d5ea6d922987)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
  • xirong: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Remove historical-token recovery and add final-request coverage proving deleted or replaced credentials are not sent.
  • Correct the JWT fixture, then run focused Kimi tests, make test, and make check in an authorized environment.
  • Add redacted after-fix runtime logs or terminal output for Desktop enrichment and fresh/upgrade credential controls, plus a screenshot or recording for the exhausted-month indicator; remove tokens, account details, IPs, and private endpoints. Updating the PR body should trigger review, or a maintainer can request @clawsweeper re-review.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • 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.

@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: a7afc05e59

ℹ️ 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 +197 to +201
if let audience = claims["aud"] as? String {
return audience.contains("kimi.com")
}
if let audience = claims["aud"] as? [String] {
return audience.contains(where: { $0.contains("kimi.com") })

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 a real Kimi audience match

When the raw LevelDB fallback returns an unrelated access JWT whose audience is, for example, notkimi.com or kimi.com.example, this substring check accepts it as a Kimi token. If it has the latest expiry, selectAccessToken then prefers it over the genuine token and sends it to Kimi in both the Authorization and Cookie headers, breaking session recovery and potentially disclosing an unrelated bearer token. Validate the audience as an exact Kimi host/domain rather than using contains for both scalar and array audiences.

Useful? React with 👍 / 👎.

steipete added a commit that referenced this pull request Sep 10, 2026
Prioritize the known exhausted kimi-monthly pool in automatic menu-bar usage and highest-usage ranking, preserving explicit window choices and normal Code-window fallback.

Extracts the display correction from #3537 and partially addresses #3536; authentication/storage work remains separate. Includes regressions, isolated test fixture cleanup, signed synthetic native before/after proof, provider docs and changelog.

Validation: 189 focused tests, full 1,061-selection suite, lint and independent P0–P2 review passed. Signed native baseline/final tests verify both status-image percentages in light and dark appearances using synthetic quotas.

Co-authored-by: Otto <ottoprua@OttodeMac-mini-2.local>
@steipete

Copy link
Copy Markdown
Owner

I extracted and landed the independently verifiable display correction in #3543, with credit to @OttoPrua. A known exhausted monthly pool now takes precedence in Auto, with regression coverage and signed native before/after proof.

This PR remains open for the Desktop authentication work. That portion still needs evidence that the selected credential belongs to the current active session and that sign-out/deletion state is respected before it can be adopted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kimi Code shows unused weekly/5h windows after monthly membership is exhausted

2 participants