mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-04-19 03:51:31 +00:00
Merge branch 'main' into mcp-rebased-2
# Conflicts: # server/claude-sdk.js # server/cursor-cli.js # server/gemini-cli.js # server/openai-codex.js # server/providers/cursor/adapter.js # server/providers/registry.js # server/providers/types.js # server/routes/cli-auth.js # server/routes/cursor.js
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import crypto from 'node:crypto';
|
||||
import { createRequire } from 'node:module';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
@@ -10,9 +11,22 @@ 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<string, any>;
|
||||
|
||||
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;
|
||||
@@ -47,21 +61,15 @@ 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<CursorMessageBlob[]> {
|
||||
const sqlite3Module = await import('sqlite3');
|
||||
const sqlite3 = sqlite3Module.default;
|
||||
const { open } = await import('sqlite');
|
||||
const Database = nodeRequire('better-sqlite3') as BetterSqliteConstructor;
|
||||
|
||||
const cwdId = crypto.createHash('md5').update(projectPath || process.cwd()).digest('hex');
|
||||
const storeDbPath = path.join(os.homedir(), '.cursor', 'chats', cwdId, sessionId, 'store.db');
|
||||
|
||||
const db = await open({
|
||||
filename: storeDbPath,
|
||||
driver: sqlite3.Database,
|
||||
mode: sqlite3.OPEN_READONLY,
|
||||
});
|
||||
const db = new Database(storeDbPath, { readonly: true, fileMustExist: true });
|
||||
|
||||
try {
|
||||
const allBlobs = await db.all('SELECT rowid, id, data FROM blobs') as CursorDbBlob[];
|
||||
const allBlobs = db.prepare('SELECT rowid, id, data FROM blobs').all();
|
||||
|
||||
const blobMap = new Map<string, CursorDbBlob>();
|
||||
const parentRefs = new Map<string, string[]>();
|
||||
@@ -170,7 +178,7 @@ export class CursorProvider extends AbstractProvider {
|
||||
|
||||
return messages;
|
||||
} finally {
|
||||
await db.close();
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { providerRegistry } from '@/modules/providers/provider.registry.js';
|
||||
import type { ProviderAuthStatus } from '@/shared/types.js';
|
||||
import type { LLMProvider, ProviderAuthStatus } from '@/shared/types.js';
|
||||
|
||||
export const providerAuthService = {
|
||||
/**
|
||||
@@ -9,4 +9,18 @@ export const providerAuthService = {
|
||||
const provider = providerRegistry.resolveProvider(providerName);
|
||||
return provider.auth.getStatus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns whether a provider runtime appears installed.
|
||||
* Falls back to true if status lookup itself fails so callers preserve the
|
||||
* original runtime error instead of replacing it with a status-check failure.
|
||||
*/
|
||||
async isProviderInstalled(providerName: LLMProvider): Promise<boolean> {
|
||||
try {
|
||||
const status = await this.getProviderAuthStatus(providerName);
|
||||
return status.installed;
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user