Skip to content

[codex] Add experimental Cursor source#5

Merged
majiayu000 merged 1 commit intomainfrom
codex/cursor-experimental-source
Apr 27, 2026
Merged

[codex] Add experimental Cursor source#5
majiayu000 merged 1 commit intomainfrom
codex/cursor-experimental-source

Conversation

@majiayu000
Copy link
Copy Markdown
Owner

Summary

  • add an experimental cursor / cur source
  • read Cursor local SQLite state.vscdb files in read-only mode
  • parse cursorDiskKV bubble records and legacy ItemTable generation records when explicit tokenCount fields are present
  • skip records without real token counts instead of estimating from message text
  • document the source and add an isolated SQLite integration test

Notes

Cursor's local chat schema is not a stable public API. This PR intentionally keeps the source conservative: if Cursor does not persist non-zero token counts, ccstats reports no Cursor usage rather than showing approximate cost data.

References used for storage layout:

Validation

  • cargo fmt --check
  • cargo test --locked
  • git diff --check

Note: cargo clippy --all-targets -- -D warnings remains blocked by existing unrelated warnings. New clippy warnings introduced by this change were fixed before PR creation.

@majiayu000 majiayu000 force-pushed the codex/cursor-experimental-source branch from 6f9c753 to d4ab4c9 Compare April 27, 2026 09:17
@majiayu000 majiayu000 marked this pull request as ready for review April 27, 2026 09:18
@majiayu000 majiayu000 merged commit 7589149 into main Apr 27, 2026
2 checks passed
Copy link
Copy Markdown

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

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: d4ab4c9196

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +133 to +137
if let Some(timestamp) = string_at(value, &["createdAt"])
.or_else(|| string_at(value, &["timestamp"]))
.or_else(|| string_at(value, &["time"]))
{
return timestamp.parse::<DateTime<Utc>>().ok();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Parse Cursor timingInfo timestamps before dropping entries

timestamp_from_value only looks for top-level createdAt/timestamp/time strings, but Cursor assistant bubbles with tokenCount commonly store their time in timingInfo millisecond fields (for example clientEndTime / clientSettleTime). In that case entry_from_bubble gets None for the timestamp and skips the record entirely, so --source cursor can show little or no usage even when token-bearing bubbles exist. Add timingInfo timestamp fallbacks before rejecting the entry.

Useful? React with 👍 / 👎.

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