diff --git a/package-lock.json b/package-lock.json index 964fcbe8..b8f5cfb2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,6 +74,7 @@ "@commitlint/config-conventional": "^20.5.0", "@eslint/js": "^9.39.3", "@release-it/conventional-changelog": "^10.0.5", + "@types/better-sqlite3": "^7.6.13", "@types/cross-spawn": "^6.0.6", "@types/express": "^5.0.6", "@types/node": "^22.19.7", @@ -3707,6 +3708,16 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/better-sqlite3": { + "version": "7.6.13", + "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.13.tgz", + "integrity": "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/body-parser": { "version": "1.19.6", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", diff --git a/package.json b/package.json index c768557c..e2f0c960 100644 --- a/package.json +++ b/package.json @@ -126,6 +126,7 @@ "@commitlint/config-conventional": "^20.5.0", "@eslint/js": "^9.39.3", "@release-it/conventional-changelog": "^10.0.5", + "@types/better-sqlite3": "^7.6.13", "@types/cross-spawn": "^6.0.6", "@types/express": "^5.0.6", "@types/node": "^22.19.7", diff --git a/server/modules/providers/list/cursor/cursor.provider.ts b/server/modules/providers/list/cursor/cursor.provider.ts index 94c81e03..00edf0d4 100644 --- a/server/modules/providers/list/cursor/cursor.provider.ts +++ b/server/modules/providers/list/cursor/cursor.provider.ts @@ -1,5 +1,4 @@ import crypto from 'node:crypto'; -import { createRequire } from 'node:module'; import os from 'node:os'; import path from 'node:path'; @@ -11,22 +10,9 @@ import type { FetchHistoryOptions, FetchHistoryResult, NormalizedMessage } from import { createNormalizedMessage, generateMessageId, readObjectRecord } from '@/shared/utils.js'; const PROVIDER = 'cursor'; -const nodeRequire = createRequire(import.meta.url); type RawProviderMessage = Record; -type BetterSqliteDatabase = { - prepare(sql: string): { - all(): CursorDbBlob[]; - }; - close(): void; -}; - -type BetterSqliteConstructor = new ( - filename: string, - options: { readonly: boolean; fileMustExist: boolean }, -) => BetterSqliteDatabase; - type CursorDbBlob = { rowid: number; id: string; @@ -61,7 +47,8 @@ export class CursorProvider extends AbstractProvider { * order. Cursor history is stored as content-addressed blobs rather than JSONL. */ private async loadCursorBlobs(sessionId: string, projectPath: string): Promise { - const Database = nodeRequire('better-sqlite3') as BetterSqliteConstructor; + // Lazy-import better-sqlite3 so the module doesn't fail if it's unavailable + const { default: Database } = await import('better-sqlite3'); const cwdId = crypto.createHash('md5').update(projectPath || process.cwd()).digest('hex'); const storeDbPath = path.join(os.homedir(), '.cursor', 'chats', cwdId, sessionId, 'store.db'); @@ -69,7 +56,7 @@ export class CursorProvider extends AbstractProvider { const db = new Database(storeDbPath, { readonly: true, fileMustExist: true }); try { - const allBlobs = db.prepare('SELECT rowid, id, data FROM blobs').all(); + const allBlobs = db.prepare<[], CursorDbBlob>('SELECT rowid, id, data FROM blobs').all(); const blobMap = new Map(); const parentRefs = new Map();