diff --git a/src/cursor-cache.ts b/src/cursor-cache.ts index 21509c2..3c7dfda 100644 --- a/src/cursor-cache.ts +++ b/src/cursor-cache.ts @@ -3,7 +3,7 @@ import { join } from 'path' import { homedir } from 'os' type CacheEntry = { - lastCreatedAt: number + lastCreatedAt: string dbSizeBytes: number } @@ -26,7 +26,7 @@ export async function readCursorCache(): Promise { } } -export async function writeCursorCache(lastCreatedAt: number, dbSizeBytes: number): Promise { +export async function writeCursorCache(lastCreatedAt: string, dbSizeBytes: number): Promise { const dir = getCacheDir() await mkdir(dir, { recursive: true }) const entry: CacheEntry = { lastCreatedAt, dbSizeBytes } diff --git a/src/providers/cursor.ts b/src/providers/cursor.ts index 38bf75d..c52548a 100644 --- a/src/providers/cursor.ts +++ b/src/providers/cursor.ts @@ -28,7 +28,7 @@ type BubbleRow = { input_tokens: number | null output_tokens: number | null model: string | null - created_at: number | null + created_at: string | null conversation_id: string | null } @@ -80,13 +80,14 @@ function validateSchema(db: SqliteDatabase): boolean { } } -function parseBubbles(db: SqliteDatabase, seenKeys: Set, afterTimestamp?: number): { calls: ParsedProviderCall[]; maxCreatedAt: number } { +function parseBubbles(db: SqliteDatabase, seenKeys: Set, afterTimestamp?: string): { calls: ParsedProviderCall[]; maxCreatedAt: string } { const results: ParsedProviderCall[] = [] let skipped = 0 - let maxCreatedAt = afterTimestamp ?? 0 + let maxCreatedAt = afterTimestamp ?? '' - const DEFAULT_LOOKBACK_MS = 120 * 24 * 60 * 60 * 1000 - const timeFloor = afterTimestamp ?? (Date.now() - DEFAULT_LOOKBACK_MS) + const DEFAULT_LOOKBACK_DAYS = 120 + const timeFloor = afterTimestamp + ?? new Date(Date.now() - DEFAULT_LOOKBACK_DAYS * 24 * 60 * 60 * 1000).toISOString() let rows: BubbleRow[] try { @@ -101,7 +102,7 @@ function parseBubbles(db: SqliteDatabase, seenKeys: Set, afterTimestamp? const outputTokens = row.output_tokens ?? 0 if (inputTokens === 0 && outputTokens === 0) continue - const createdAt = row.created_at ?? 0 + const createdAt = (row.created_at as string) ?? '' if (createdAt > maxCreatedAt) maxCreatedAt = createdAt const conversationId = row.conversation_id ?? 'unknown' const dedupKey = `cursor:${conversationId}:${createdAt}:${inputTokens}:${outputTokens}` @@ -114,9 +115,7 @@ function parseBubbles(db: SqliteDatabase, seenKeys: Set, afterTimestamp? const costUSD = calculateCost(pricingModel, inputTokens, outputTokens, 0, 0, 0) - const timestamp = createdAt > 0 - ? new Date(createdAt).toISOString() - : '' + const timestamp = createdAt || '' results.push({ provider: 'cursor', @@ -174,7 +173,7 @@ function createParser(source: SessionSource, seenKeys: Set): SessionPars let dbSize = 0 try { dbSize = statSync(source.path).size } catch {} const cacheValid = cache - && cache.lastCreatedAt > 0 + && cache.lastCreatedAt.length > 0 && cache.dbSizeBytes > 0 && dbSize >= cache.dbSizeBytes const afterTimestamp = cacheValid ? cache.lastCreatedAt : undefined @@ -183,7 +182,7 @@ function createParser(source: SessionSource, seenKeys: Set): SessionPars const { calls, maxCreatedAt } = parseBubbles(db, seenKeys, afterTimestamp) - if (maxCreatedAt > 0) { + if (maxCreatedAt.length > 0) { await writeCursorCache(maxCreatedAt, dbSize).catch(() => {}) }