Skip to content

Read Cursor tokens and line changes from modern state schema#1503

Closed
1chooo wants to merge 5 commits into
wakatime:developfrom
1chooo:bugfix/cursor-modern-schema-tokens
Closed

Read Cursor tokens and line changes from modern state schema#1503
1chooo wants to merge 5 commits into
wakatime:developfrom
1chooo:bugfix/cursor-modern-schema-tokens

Conversation

@1chooo

@1chooo 1chooo commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • read the cumulative context window usage (contextWindowStatusAtCreation.tokensUsed) on Cursor user bubbles as a cumulative input token counter, reusing the existing monotonic delta logic
  • compute AI line changes by diffing the before/after file snapshots referenced by beforeContentId/afterContentId in edit_file_v2/edit_file tool results (stored under composer.content.<hash> keys), used when streamingContent/code_edit is absent
  • include $.contextWindowStatusAtCreation and $.modelInfo rows in the SQLite query filter
  • add regression coverage modeled on the current Cursor schema (zero tokenCount placeholders, noCodeblock edit params, content snapshot blobs)

Root Cause

Recent Cursor versions (1.7.x) stopped persisting per-bubble token data entirely: every bubbleId: row now carries a {"inputTokens":0,"outputTokens":0} placeholder and no usage objects exist anywhere in state.vscdb, so #1496/#1499 could no longer recover tokens — the data source moved. Likewise edit_file_v2 params no longer include streamingContent ("noCodeblock":true), so AI line changes were always zero. The remaining local signals are the cumulative context window token usage on user bubbles and the before/after file content snapshots referenced by edit tool results.

Note: Cursor no longer persists output token counts locally, so only input/context tokens can be reported for now.

Validation

  • go test ./pkg/ai -count=1
  • ran the parser against a live Cursor 1.7.x state.vscdb: previously inputTokens=0 lineChanges=0 across 254 heartbeats in 24h; with this change inputTokens=462037 lineChanges=800

Fixes wakatime/vscode-wakatime#489.

🤖 Generated with Claude Code

Recent Cursor versions stopped writing per-bubble tokenCount/usage
values (only zero placeholders remain) and no longer include
streamingContent in edit_file_v2 params (noCodeblock=true), so AI
token counts and line changes were always zero.

Read the cumulative context window usage from
contextWindowStatusAtCreation.tokensUsed on user bubbles as input
token counter, and compute line changes by diffing the
before/after file snapshots referenced by beforeContentId and
afterContentId in edit tool results.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@alanhamlett

Copy link
Copy Markdown
Member

Can't merge, this breaks several things:

  • pkg/ai/cursor.go:198 contextWindowStatusAtCreation.tokensUsed we need real Cursor test data to confirm this is cumulative state and doesn't reset with compaction, throwing off the token counts.
  • pkg/ai/cursor.go:1107 reports snapshot-backed line changes as len(after) - LCS, which can only count added/modified lines. Line change counters should be diffs too, including deletions. Deletion-only AI edits become 0 here instead of a negative line-change value, unlike the existing unified-diff path.
  • pkg/ai/cursor.go:1118 adds an O(beforeLines * afterLines) LCS pass for every snapshot edit, up to 3,000 x 3,000 comparisons per edit across the 5,000-row Cursor scan window. That is too expensive for sync-time parsing, and the large-file fallback is also inaccurate because it only reports positive net line-count deltas, so large same-size rewrites or deletion-heavy edits are reported as 0.

1chooo and others added 3 commits July 8, 2026 20:48
Use source-aware token handling, bounded snapshot line counting, and a Cursor-specific checkpoint so schema drift degrades safely without misreporting usage or losing recoverable activity.

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

1chooo commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Hi @alanhamlett can you please approve the ci/cd?

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.75676% with 49 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.64%. Comparing base (14891b1) to head (8cd96b2).

Files with missing lines Patch % Lines
pkg/ai/cursor.go 88.61% 25 Missing and 12 partials ⚠️
pkg/ai/ai.go 73.33% 7 Missing and 5 partials ⚠️
@@             Coverage Diff             @@
##           develop    #1503      +/-   ##
===========================================
- Coverage    89.69%   89.64%   -0.06%     
===========================================
  Files          417      417              
  Lines        20809    21079     +270     
===========================================
+ Hits         18665    18896     +231     
- Misses        1301     1324      +23     
- Partials       843      859      +16     
Flag Coverage Δ
unittests 89.64% <86.75%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
pkg/ai/ai.go 91.73% <73.33%> (-0.97%) ⬇️
pkg/ai/cursor.go 90.52% <88.61%> (-1.48%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Exercise malformed schema rows, checkpoint failures, edit-source fallbacks, and SQLite error paths so the stabilization behavior remains protected and patch coverage stays merge-ready.

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

1chooo commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

@alanhamlett just make a new push for fixing codecov

@1chooo

1chooo commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

@alanhamlett can you check with this fix because Cursor right now can not count AI usage anymore...

Comment thread pkg/ai/ai.go
minAIHeartbeatTime, maxAIHeartbeatTime := minMaxAIHeartbeatTimes(heartbeats)

parsedAt := heartbeatTime(maxAIHeartbeatTime)
if parsedAt.Before(lastParsedAt) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Agent specific code doesn't belong in the ai.go file.

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.

Missing AI Token Usage Tracking for Cursor

2 participants