/** * MAMA Database Manager (SQLite-only) * * SQLite-exclusive database interface for MAMA Plugin. * Uses better-sqlite3 for local storage. * * PostgreSQL support is only available in the legacy mcp-server repository. * * Features: * - WAL mode for better concurrency * - synchronous=NORMAL for performance * - Automatic migration management * - Vector similarity search (pure TS cosine similarity) * * @module db-manager * @version 2.1 (Plugin - SQLite-only) * @date 2026-02-01 * @source-of-truth packages/mama-core/src/db-manager.js (mama-core) */ import type { PreparedStatement } from './db-adapter/statement.js'; export type { PreparedStatement }; export interface DatabaseAdapter { connect: () => unknown; disconnect: () => void; runMigrations: (dir: string) => void; prepare: (sql: string) => PreparedStatement; transaction: (fn: () => T) => T; insertEmbedding: (rowid: number, embedding: Float32Array | number[]) => void; vectorSearch: (embedding: Float32Array | number[], limit: number, topicPrefix?: string) => Promise | VectorSearchResult[] | null; vectorSearchEnabled: boolean; reloadVectorCache?: () => void; getDbPath?: () => string; dbPath?: string; constructor: { name: string; }; } export interface VectorSearchResult { rowid: number; similarity?: number; distance?: number; } export interface DecisionRecord { id: string; topic: string; decision: string; reasoning?: string | null; outcome?: string | null; failure_reason?: string | null; limitation?: string | null; confidence?: number; supersedes?: string | null; superseded_by?: string | null; refined_from?: string | string[] | null; created_at: number; updated_at?: number; edges?: DecisionEdgeRow[]; /** ISO 8601 date when the event actually occurred. Null if not set. */ event_date?: string | null; /** Source event timestamp in milliseconds when known. Null if not set. */ event_datetime?: number | null; } export interface OutcomeData { outcome?: string | null; failure_reason?: string | null; limitation?: string | null; duration_days?: number | null; confidence?: number | null; } export interface VectorSearchParams { query: string; limit?: number; threshold?: number; timeWindow?: number; includeSuperseded?: boolean; } export interface DecisionEdgeRow { from_id: string; to_id: string; relationship: string; reason?: string | null; weight?: number; created_at?: number; created_by?: string; approved_by_user?: number | null; decision_id?: string | null; evidence?: string | null; } export interface SemanticEdgeItem { from_id: string; to_id: string; relationship: string; reason?: string; topic: string; decision: string; confidence?: number; created_at?: string; approved_by_user?: number | null; } export interface SemanticEdges { refines: SemanticEdgeItem[]; refined_by: SemanticEdgeItem[]; contradicts: SemanticEdgeItem[]; contradicted_by: SemanticEdgeItem[]; builds_on: SemanticEdgeItem[]; built_on_by: SemanticEdgeItem[]; debates: SemanticEdgeItem[]; debated_by: SemanticEdgeItem[]; synthesizes: SemanticEdgeItem[]; synthesized_by: SemanticEdgeItem[]; } /** * Initialize SQLite database adapter and connect * * Lazy initialization: Only connects when first accessed * Creates database file at ~/.claude/mama-memory.db by default * * Single-flight guard: Concurrent callers await the same promise * to prevent multiple adapters/migrations running simultaneously. * * @returns SQLite database connection */ export declare function initDB(): Promise; export declare function assertTestProcessIsNotUsingRealDb(effectivePath?: string, effectivePathSource?: string): void; /** * Get database connection (singleton pattern) * * Returns better-sqlite3 Database instance * * Note: Synchronous for backward compatibility with memory-store.js * Will throw if database not initialized * * @returns SQLite database connection */ export declare function getDB(): unknown; /** * Get database adapter instance * * Used for advanced operations (vectorSearch, insertEmbedding, etc.) * * @returns Adapter instance */ export declare function getAdapter(): DatabaseAdapter; /** * Close database connection * * Call this on process exit */ export declare function closeDB(): Promise; export declare function ensureMemoryScope(kind: string, externalId: string): Promise; export declare function bindMemoryToScope(memoryId: string, scopeId: string, isPrimary?: boolean): Promise; export declare function listScopesForMemory(memoryId: string): Promise>; /** * Insert embedding into vector search table * * Stores embedding in the embeddings table for vector similarity search * * @param decisionRowid - SQLite rowid * @param embedding - 1024-dim embedding vector */ export declare function insertEmbedding(decisionRowid: number, embedding: Float32Array | number[]): Promise; /** * Perform vector similarity search * * Returns empty array if vector search not available (no keyword fallback) * * @param queryEmbedding - Query embedding (1024-dim) * @param limit - Max results to return (default: 5) * @param threshold - Minimum similarity threshold (default: 0.7) * @returns Array of decisions with similarity scores, or empty array */ export declare function vectorSearch(queryEmbedding: Float32Array | number[], limit?: number, threshold?: number, topicPrefix?: string): Promise; /** * Decision input for storage */ export interface DecisionInput { id: string; topic: string; decision: string; reasoning?: string | null; outcome?: string | null; failure_reason?: string | null; limitation?: string | null; user_involvement?: string | null; session_id?: string | null; supersedes?: string | null; superseded_by?: string | null; refined_from?: string[] | null; confidence?: number; created_at?: number; updated_at?: number; needs_validation?: number; validation_attempts?: number; last_validated_at?: number | null; usage_count?: number; trust_context?: string | null; usage_success?: number; usage_failure?: number; time_saved?: number; evidence?: string | null; alternatives?: string | null; risks?: string | null; /** ISO 8601 date string for when the event actually occurred (e.g. "2023-01-15") */ event_date?: string | null; /** Source event timestamp in milliseconds when known. */ event_datetime?: number | null; agent_id?: string | null; model_run_id?: string | null; envelope_hash?: string | null; gateway_call_id?: string | null; source_refs_json?: string | null; provenance_json?: string | null; } /** * Insert decision with embedding * * Combined operation: Insert decision + Generate embedding + Insert embedding * SQLite-only implementation * * @param decision - Decision object * @returns Decision ID */ export declare function insertDecisionWithEmbedding(decision: DecisionInput): Promise; /** * Query decision graph for topic * * Recursive CTE to traverse supersedes chain * SQLite implementation using WITH RECURSIVE * * @param topic - Decision topic to query * @returns Array of decisions (ordered by recency) */ export declare function queryDecisionGraph(topic: string): Promise; /** * Query semantic edges for a list of decisions * * Returns both outgoing (from_id) and incoming (to_id) edges * for refines and contradicts relationships * * @param decisionIds - Decision IDs to query edges for * @returns Categorized edges */ export declare function querySemanticEdges(decisionIds: string[]): Promise; /** * Query vector search with time window and threshold * * Story 014.14: AC #1 - Vector Search for Related Decisions * * @param params - Search parameters * @returns Results with similarity scores and decision data */ export declare function queryVectorSearch(params: VectorSearchParams): Promise; /** * Update decision outcome * * @param decisionId - Decision ID * @param outcomeData - Outcome data */ export declare function updateDecisionOutcome(decisionId: string, outcomeData: OutcomeData): Promise; /** * Get prepared statement * * For backward compatibility with memory-store.js * Returns a compatibility shim that proxies to adapter.prepare() * * @param sql - SQL statement * @returns Statement-like object with run/get/all methods */ export declare function getPreparedStmt(sql: string): PreparedStatement; /** * Get database file path * * @returns Actual database path or 'Not initialized' */ export declare function getDbPath(): string; /** * Reset database state for testing * * Resets internal state without closing connection. * Use this in test teardown to allow re-initialization with different DB path. * * @param options - Reset options * @param options.disconnect - If true, also disconnect adapter (default: true) */ export declare function resetDBState(options?: { disconnect?: boolean; }): void; /** * Check if running in test mode * * Returns true if MAMA_TEST_MODE, VITEST, or NODE_ENV=test env vars are set */ export declare function isTestMode(): boolean; /** * FTS5 keyword search on decisions table. * Returns matching decision IDs with BM25 rank scores. */ export declare function fts5Search(query: string, limit?: number): Promise<{ id: string; rank: number; }[]>; /** * Re-generate all embeddings using the currently configured model. * Call this after changing the embedding model in config.json. * * @param onProgress - Optional callback with (completed, total) counts * @returns Number of embeddings regenerated */ export declare function reindexEmbeddings(onProgress?: (completed: number, total: number) => void): Promise; //# sourceMappingURL=db-manager.d.ts.map