feat(cursor-agent): discover and reconstruct sessions from store.db (fixes #986) - #1233
Open
maheshsingh20 wants to merge 1 commit into
Open
feat(cursor-agent): discover and reconstruct sessions from store.db (fixes #986)#1233maheshsingh20 wants to merge 1 commit into
maheshsingh20 wants to merge 1 commit into
Conversation
…chats/**/store.db Fixes getagentseal#986. ## What changed - **Discovery**: discoverSessions() now scans ~/.cursor/chats/<hash>/<uuid>/store.db in addition to the existing ~/.cursor/projects/**/agent-transcripts/ transcript walk. probeRoots() gains a chats entry so codeburn doctor can report it. - **Schema validation**: each store.db is checked for the required meta and �lobs tables before any reads are attempted. A missing or incompatible schema emits a warning and falls through to the transcript fallback. - **Metadata decoding**: meta['0'] is hex-decoded from UTF-8 JSON to extract �gentId, latestRootBlobId, ame, createdAt, and lastUsedModel. �lobEncryptionKey is explicitly excluded from the decoded object and must never appear in logs, caches, exports, snapshots, or committed fixtures. - **Blob-graph reconstruction**: starting at latestRootBlobId, the parser walks extBlobId chains and childBlobIds arrays in BFS order, classifying blobs by ole (user / assistant / model / request). Unknown fields are silently ignored for forward compatibility. - **Token provenance**: explicit per-request inputTokens/outputTokens fields are used when present and plausible (≤ 2 000 000 — values above that are treated as context-window gauges and discarded). Missing components are estimated from character counts. costIsEstimated is set on calls where any count was estimated. - **Timestamps**: internal request/blob timestamps take precedence; the session createdAt is used as a session-level fallback. File mtime is never reported as an exact request timestamp. - **WAL-aware cache**: the in-memory per-session cache is keyed on a fingerprint combining the store.db mtime and the -wal sidecar size/mtime, so active sessions (written via WAL) always trigger a re-parse. - **Source precedence + dedup**: store.db sources are emitted first. A successfully decoded store records a sentinel in seenKeys; transcript parsers for the same session UUID check the sentinel and skip themselves. A store that fails schema/metadata validation does not set the sentinel, so the transcript fallback runs normally. ## Tests (44 new, 0 regressions) Covers all items from the issue test matrix: empty chats dir, valid minimal store, multi-turn blob graph, malformed hex metadata, missing/invalid root blob, unknown fields, seconds vs milliseconds timestamps, exact/partial/gauge/absent token data, store+transcript dedup, transcript fallback on corrupt store, WAL-aware cache invalidation, blobEncryptionKey redaction.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #986.
The
cursor-agentprovider previously missed CLI sessions stored in~/.cursor/chats/**/store.db. This PR adds full discovery and reconstruction for those sessions, with proper source precedence, deduplication, WAL-aware caching, andblobEncryptionKeyredaction.Changes
src/providers/cursor-agent.tsDiscovery
discoverSessions()now scans~/.cursor/chats/<hash>/<uuid>/store.dbbefore the existing transcript walk, without following symlinks beyond two directory levels.probeRoots()gains achatsentry socodeburn doctorreports it.Schema validation
meta+blobstables before any data is read. A missing or incompatible schema emits a warning and falls through to the transcript fallback.Metadata decoding
meta['0']is hex-decoded from UTF-8 JSON to extractagentId,latestRootBlobId,name,createdAt, andlastUsedModel.blobEncryptionKeyis explicitly excluded from the decoded object and never appears in logs, caches, exports, snapshots, emitted calls, or stderr output.Blob-graph reconstruction
latestRootBlobId, followingnextBlobIdchains andchildBlobIdsarrays.role(user / assistant / model / request).textstrings and content-block arrays ([{type:'text', text:'...'}]).toolCalls: [{name}]and content-block{type:'tool_use', name}formats.Token provenance
inputTokens/outputTokensused when present and plausible (<=2,000,000). Values above that threshold are treated as context-window gauges and replaced by char-based estimates.cacheCreationInputTokensandcacheReadInputTokensrecorded when present.costIsEstimated: trueset on any call where at least one count was estimated.Timestamps
createdAtused as session-level fallback. File mtime is never reported as an exact request timestamp.WAL-aware in-memory cache
-walsidecar size/mtime. Active sessions always trigger a re-parse when the WAL changes.Source precedence and deduplication
discoverSessions().cursor-agent-store-decoded:<uuid>sentinel inseenKeys; transcript parsers for the same session UUID check it and skip themselves.tests/providers/cursor-agent-store.test.ts(new, 44 tests)Test results