Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/cursor-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import type { ParsedProviderCall } from './providers/types.js'
// router relies on those composer ids to bucket calls per project.
// Version 2 caches contain `sessionId: 'unknown'` for every call and would
// route everything to the orphan project, so we invalidate them.
const CURSOR_CACHE_VERSION = 3
// Bumped to 4 after skipping bubble rows without createdAt: version 3 caches
// could contain historical Cursor bubbles timestamped with the parse time.
const CURSOR_CACHE_VERSION = 4

type ResultCache = {
version?: number
Expand All @@ -23,7 +25,7 @@ type ResultCache = {
const CACHE_FILE = 'cursor-results.json'

function getCacheDir(): string {
return join(homedir(), '.cache', 'codeburn')
return process.env['CODEBURN_CACHE_DIR'] ?? join(homedir(), '.cache', 'codeburn')
}

function getCachePath(): string {
Expand Down
46 changes: 46 additions & 0 deletions tests/cursor-cache.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import { mkdir, mkdtemp, rm, stat, writeFile } from 'fs/promises'
import { join } from 'path'
import { tmpdir } from 'os'

import { readCachedResults } from '../src/cursor-cache.js'

let tmpDir: string
let oldCacheDir: string | undefined

beforeEach(async () => {
tmpDir = await mkdtemp(join(tmpdir(), 'cursor-cache-'))
oldCacheDir = process.env['CODEBURN_CACHE_DIR']
process.env['CODEBURN_CACHE_DIR'] = join(tmpDir, 'cache')
})

afterEach(async () => {
if (oldCacheDir === undefined) {
delete process.env['CODEBURN_CACHE_DIR']
} else {
process.env['CODEBURN_CACHE_DIR'] = oldCacheDir
}
await rm(tmpDir, { recursive: true, force: true })
})

describe('cursor result cache', () => {
it('invalidates v3 caches written before the missing-createdAt fix', async () => {
const dbPath = join(tmpDir, 'state.vscdb')
await writeFile(dbPath, 'cursor db')
const fp = await stat(dbPath)

const cacheDir = process.env['CODEBURN_CACHE_DIR']!
await mkdir(cacheDir, { recursive: true })
await writeFile(
join(cacheDir, 'cursor-results.json'),
JSON.stringify({
version: 3,
dbMtimeMs: fp.mtimeMs,
dbSizeBytes: fp.size,
calls: [],
}),
)

await expect(readCachedResults(dbPath)).resolves.toBeNull()
})
})