Fix: index Cursor sessions from agent-transcripts/, support nested depths#752
Fix: index Cursor sessions from agent-transcripts/, support nested depths#752kix-sisigai wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthrough
ChangesCursor Transcript Indexing - Path-Based Project Resolution
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
server/modules/providers/tests/cursor-session-synchronizer.test.ts (1)
18-24: ⚡ Quick win
patchHomeDiruses a globalosmodule mutation that can bleed across parallel test files.
{ concurrency: false }only serializes tests within this file; the Node test runner runs different test files in parallel by default. If any other test file instantiatesCursorSessionSynchronizer(or callsos.homedir()) while this test is active, it will observe the patched value and fail with a spurious path.Consider making the home directory injectable via the constructor instead, which eliminates the need for monkey-patching entirely:
♻️ Proposed refactor (constructor injection)
In the provider:
export class CursorSessionSynchronizer implements IProviderSessionSynchronizer { private readonly provider = 'cursor' as const; - private readonly cursorHome = path.join(os.homedir(), '.cursor'); + private readonly cursorHome: string; + + constructor(cursorHome = path.join(os.homedir(), '.cursor')) { + this.cursorHome = cursorHome; + }In the test:
- const restoreHomeDir = patchHomeDir(tempRoot); - // ... + const cursorHome = path.join(tempRoot, '.cursor'); const sync = new CursorSessionSynchronizer(); + // pass cursorHome directly, no global patch needed - restoreHomeDir();🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@server/modules/providers/tests/cursor-session-synchronizer.test.ts` around lines 18 - 24, The test's global os.homedir monkeypatch (patchHomeDir) can leak across test files—avoid it by making the home directory injectable: add an optional homeDir (or basePath) parameter to the CursorSessionSynchronizer constructor and switch any internal uses of os.homedir() in that class to use this injected value (falling back to os.homedir() when the parameter is undefined); then update the tests to create the synchronizer with the temp/home path instead of calling patchHomeDir and remove patchHomeDir/any os.homedir mutations from the test file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@server/modules/providers/tests/cursor-session-synchronizer.test.ts`:
- Around line 18-24: The test's global os.homedir monkeypatch (patchHomeDir) can
leak across test files—avoid it by making the home directory injectable: add an
optional homeDir (or basePath) parameter to the CursorSessionSynchronizer
constructor and switch any internal uses of os.homedir() in that class to use
this injected value (falling back to os.homedir() when the parameter is
undefined); then update the tests to create the synchronizer with the temp/home
path instead of calling patchHomeDir and remove patchHomeDir/any os.homedir
mutations from the test file.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 9383800f-0752-4159-9738-f693eeeffaf2
📒 Files selected for processing (2)
server/modules/providers/list/cursor/cursor-session-synchronizer.provider.tsserver/modules/providers/tests/cursor-session-synchronizer.test.ts
Why
Recent cursor-agent versions write JSONL transcripts under
~/.cursor/projects/<project-dir>/agent-transcripts/<chatId>/.... The legacy~/.cursor/chats/<projectHash>/directory still exists but now holds only SQLitestore.dbfiles, used by the loader (cursor-sessions.provider.ts), not JSONL the indexer can parse. Result: onmain,CursorSessionSynchronizerfinds zero transcripts for any current Cursor user — every initial scan returns 0, advancesscan_state.last_scanned_at, and from then on the file watcher only catches whatever brand-new chats happen after startup.The transcript layout itself isn't fixed either — the same install can have chats at both
agent-transcripts/<chatId>/<chatId>.jsonlandagent-transcripts/<chatId>/<sub>/<chatId>.jsonl, so the hard-codedpath.dirname(path.dirname(filePath))silently skipped the deeper variant.Changes
~/.cursor/projects/<name>/agent-transcripts/for transcripts; the legacy hashedchats/dir is left to the loader, which already has its own md5 hashing.worker.logby walking up from the transcript file, bounded to~/.cursor/projects, so both nested depths work and a transcript outside the cursor home returns null instead of asserting on path arithmetic.projectPathfrom the project loop intoprocessSessionFileto avoid redundant per-file resolution; the watcher entry point still resolves it via the walk-up helper.md5helper andcryptoimport from the synchronizer.server/modules/providers/tests/cursor-session-synchronizer.test.tscovering: transcripts at both depths, a project missingworker.log, the legacychats/<hash>/store.dbpresence (must not be claimed by the indexer), watcher-added transcripts, transcripts outside~/.cursor/projects, and the incrementalsincefilter.Testing
Summary by CodeRabbit
Refactor
Tests