claude-memory-layer 1.0.23 → 1.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +11 -0
- package/README.md +2 -0
- package/dist/cli/index.js +85 -17
- package/dist/cli/index.js.map +2 -2
- package/dist/core/index.js +28 -5
- package/dist/core/index.js.map +2 -2
- package/dist/hooks/post-tool-use.js +115 -18
- package/dist/hooks/post-tool-use.js.map +2 -2
- package/dist/hooks/semantic-daemon.js +7337 -0
- package/dist/hooks/semantic-daemon.js.map +7 -0
- package/dist/hooks/session-end.js +69 -16
- package/dist/hooks/session-end.js.map +2 -2
- package/dist/hooks/session-start.js +154 -24
- package/dist/hooks/session-start.js.map +4 -4
- package/dist/hooks/stop.js +99 -18
- package/dist/hooks/stop.js.map +2 -2
- package/dist/hooks/user-prompt-submit.js +289 -102
- package/dist/hooks/user-prompt-submit.js.map +4 -4
- package/dist/server/api/index.js +69 -16
- package/dist/server/api/index.js.map +2 -2
- package/dist/server/index.js +69 -16
- package/dist/server/index.js.map +2 -2
- package/dist/services/memory-service.js +69 -16
- package/dist/services/memory-service.js.map +2 -2
- package/dist/ui/app.js +48 -1
- package/dist/ui/index.html +11 -3
- package/memory/_index.md +1 -0
- package/memory/agent_response/uncategorized/2026-03-04.md +1098 -1
- package/memory/session_summary/uncategorized/2026-03-04.md +31 -0
- package/memory/tool_observation/uncategorized/2026-03-04.md +733 -1
- package/memory/user_prompt/uncategorized/2026-03-04.md +371 -1
- package/package.json +1 -1
- package/scripts/build.ts +2 -1
- package/specs/selective-tool-observation/context.md +100 -0
- package/specs/selective-tool-observation/plan.md +158 -0
- package/specs/selective-tool-observation/spec.md +127 -0
- package/src/cli/index.ts +1 -0
- package/src/core/embedder.ts +13 -4
- package/src/core/sqlite-event-store.ts +16 -0
- package/src/core/turn-state.ts +48 -0
- package/src/core/types.ts +1 -0
- package/src/hooks/post-tool-use.ts +47 -2
- package/src/hooks/semantic-daemon-client.ts +208 -0
- package/src/hooks/semantic-daemon.ts +276 -0
- package/src/hooks/session-start.ts +7 -0
- package/src/hooks/stop.ts +19 -4
- package/src/hooks/user-prompt-submit.ts +48 -40
- package/src/services/memory-service.ts +59 -16
- package/src/services/session-history-importer.ts +18 -0
- package/src/ui/app.js +48 -1
- package/src/ui/index.html +11 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/services/memory-service.ts", "../../src/core/event-store.ts", "../../src/core/canonical-key.ts", "../../src/core/db-wrapper.ts", "../../src/core/sqlite-event-store.ts", "../../src/core/sqlite-wrapper.ts", "../../src/core/markdown-mirror.ts", "../../src/core/sync-worker.ts", "../../src/core/vector-store.ts", "../../src/core/embedder.ts", "../../src/core/vector-outbox.ts", "../../src/core/vector-worker.ts", "../../src/core/matcher.ts", "../../src/core/retriever.ts", "../../src/core/graduation.ts", "../../src/core/shared-event-store.ts", "../../src/core/shared-store.ts", "../../src/core/shared-vector-store.ts", "../../src/core/shared-promoter.ts", "../../src/core/metadata-extractor.ts", "../../src/core/working-set-store.ts", "../../src/core/consolidated-store.ts", "../../src/core/consolidation-worker.ts", "../../src/core/continuity-manager.ts", "../../src/core/graduation-worker.ts", "../../src/core/md-mirror.ts", "../../src/core/ingest-interceptor.ts", "../../src/core/tag-taxonomy.ts", "../../src/hooks/session-start.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Memory Service - Main entry point for memory operations\n * Coordinates EventStore, VectorStore, Retriever, and Graduation\n */\n\nimport * as path from 'path';\nimport * as os from 'os';\nimport * as fs from 'fs';\nimport * as crypto from 'crypto';\n\nimport { EventStore } from '../core/event-store.js';\nimport { SQLiteEventStore } from '../core/sqlite-event-store.js';\nimport { SyncWorker } from '../core/sync-worker.js';\nimport { VectorStore } from '../core/vector-store.js';\nimport { Embedder, getDefaultEmbedder } from '../core/embedder.js';\nimport { VectorWorker, createVectorWorker } from '../core/vector-worker.js';\nimport { Matcher, getDefaultMatcher } from '../core/matcher.js';\nimport { Retriever, createRetriever, RetrievalResult, UnifiedRetrievalResult } from '../core/retriever.js';\nimport { GraduationPipeline, createGraduationPipeline } from '../core/graduation.js';\nimport { SharedEventStore, createSharedEventStore } from '../core/shared-event-store.js';\nimport { SharedStore, createSharedStore } from '../core/shared-store.js';\nimport { SharedVectorStore, createSharedVectorStore } from '../core/shared-vector-store.js';\nimport { SharedPromoter, createSharedPromoter, PromotionResult } from '../core/shared-promoter.js';\nimport type {\n MemoryEventInput,\n AppendResult,\n MemoryEvent,\n Config,\n ConfigSchema,\n ToolObservationPayload,\n MemoryMode,\n EndlessModeConfig,\n EndlessModeConfigSchema,\n WorkingSet,\n ConsolidatedMemory,\n EndlessModeStatus,\n ContextSnapshot,\n ContinuityScore,\n SharedStoreConfig,\n Entry\n} from '../core/types.js';\nimport { createToolObservationEmbedding } from '../core/metadata-extractor.js';\nimport { WorkingSetStore, createWorkingSetStore } from '../core/working-set-store.js';\nimport { ConsolidatedStore, createConsolidatedStore } from '../core/consolidated-store.js';\nimport { ConsolidationWorker, createConsolidationWorker } from '../core/consolidation-worker.js';\nimport { ContinuityManager, createContinuityManager } from '../core/continuity-manager.js';\nimport { GraduationWorker, createGraduationWorker, GraduationRunResult } from '../core/graduation-worker.js';\nimport { MarkdownMirror } from '../core/md-mirror.js';\nimport {\n IngestInterceptor,\n IngestInterceptorRegistry,\n mergeHierarchicalMetadata\n} from '../core/ingest-interceptor.js';\nimport { normalizeTags } from '../core/tag-taxonomy.js';\n\nexport interface MemoryServiceConfig {\n storagePath: string;\n embeddingModel?: string;\n readOnly?: boolean;\n /** Enable DuckDB analytics store (default: true for server, false for hooks) */\n analyticsEnabled?: boolean;\n /** Lightweight mode for hooks - skip heavy initialization (default: false) */\n lightweightMode?: boolean;\n}\n\n// ============================================================\n// Project Path Utilities\n// ============================================================\n\n/**\n * Normalize and resolve a project path, handling symlinks\n */\nfunction normalizePath(projectPath: string): string {\n const expanded = projectPath.startsWith('~')\n ? path.join(os.homedir(), projectPath.slice(1))\n : projectPath;\n\n try {\n // Resolve symlinks for consistent paths\n return fs.realpathSync(expanded);\n } catch {\n // Path doesn't exist yet, just resolve it\n return path.resolve(expanded);\n }\n}\n\n/**\n * Generate a stable 8-character hash from a project path\n */\nexport function hashProjectPath(projectPath: string): string {\n const normalizedPath = normalizePath(projectPath);\n return crypto.createHash('sha256')\n .update(normalizedPath)\n .digest('hex')\n .slice(0, 8);\n}\n\n/**\n * Get the storage path for a specific project\n */\nexport function getProjectStoragePath(projectPath: string): string {\n const hash = hashProjectPath(projectPath);\n return path.join(os.homedir(), '.claude-code', 'memory', 'projects', hash);\n}\n\n// ============================================================\n// Session Registry\n// ============================================================\n\nconst REGISTRY_PATH = path.join(os.homedir(), '.claude-code', 'memory', 'session-registry.json');\nconst SHARED_STORAGE_PATH = path.join(os.homedir(), '.claude-code', 'memory', 'shared');\n\nexport interface SessionRegistryEntry {\n projectPath: string;\n projectHash: string;\n registeredAt: string;\n}\n\nexport interface SessionRegistry {\n version: number;\n sessions: Record<string, SessionRegistryEntry>;\n}\n\nexport function loadSessionRegistry(): SessionRegistry {\n try {\n if (fs.existsSync(REGISTRY_PATH)) {\n const data = fs.readFileSync(REGISTRY_PATH, 'utf-8');\n return JSON.parse(data);\n }\n } catch (error) {\n console.error('Failed to load session registry:', error);\n }\n return { version: 1, sessions: {} };\n}\n\nfunction saveSessionRegistry(registry: SessionRegistry): void {\n const dir = path.dirname(REGISTRY_PATH);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Atomic write using temp file\n const tempPath = REGISTRY_PATH + '.tmp';\n fs.writeFileSync(tempPath, JSON.stringify(registry, null, 2));\n fs.renameSync(tempPath, REGISTRY_PATH);\n}\n\n/**\n * Register a session with its project path\n */\nexport function registerSession(sessionId: string, projectPath: string): void {\n const registry = loadSessionRegistry();\n\n registry.sessions[sessionId] = {\n projectPath: normalizePath(projectPath),\n projectHash: hashProjectPath(projectPath),\n registeredAt: new Date().toISOString()\n };\n\n // Clean up old sessions (keep last 1000)\n const entries = Object.entries(registry.sessions);\n if (entries.length > 1000) {\n const sorted = entries.sort((a, b) =>\n new Date(b[1].registeredAt).getTime() - new Date(a[1].registeredAt).getTime()\n );\n registry.sessions = Object.fromEntries(sorted.slice(0, 1000));\n }\n\n saveSessionRegistry(registry);\n}\n\n/**\n * Get the project path for a session\n */\nexport function getSessionProject(sessionId: string): SessionRegistryEntry | null {\n const registry = loadSessionRegistry();\n return registry.sessions[sessionId] || null;\n}\n\nexport class MemoryService {\n // Primary store: SQLite (WAL mode) - for hooks, always available\n private readonly sqliteStore: SQLiteEventStore;\n // Analytics store: DuckDB - for server reads (optional, synced from SQLite)\n private readonly analyticsStore: EventStore | null;\n private syncWorker: SyncWorker | null = null;\n\n private readonly vectorStore: VectorStore;\n private readonly embedder: Embedder;\n private readonly matcher: Matcher;\n private readonly retriever: Retriever;\n private readonly graduation: GraduationPipeline;\n private vectorWorker: VectorWorker | null = null;\n private graduationWorker: GraduationWorker | null = null;\n private initialized = false;\n private readonly ingestInterceptors = new IngestInterceptorRegistry();\n\n // Endless Mode components\n private workingSetStore: WorkingSetStore | null = null;\n private consolidatedStore: ConsolidatedStore | null = null;\n private consolidationWorker: ConsolidationWorker | null = null;\n private continuityManager: ContinuityManager | null = null;\n private endlessMode: MemoryMode = 'session';\n\n // Shared Store components (cross-project knowledge)\n private sharedEventStore: SharedEventStore | null = null;\n private sharedStore: SharedStore | null = null;\n private sharedVectorStore: SharedVectorStore | null = null;\n private sharedPromoter: SharedPromoter | null = null;\n private sharedStoreConfig: SharedStoreConfig | null = null;\n private projectHash: string | null = null;\n private projectPath: string | null = null;\n\n private readonly readOnly: boolean;\n private readonly lightweightMode: boolean;\n private readonly mdMirror: MarkdownMirror;\n private readonly storagePath: string;\n\n constructor(config: MemoryServiceConfig & { projectHash?: string; projectPath?: string; sharedStoreConfig?: SharedStoreConfig }) {\n const storagePath = this.expandPath(config.storagePath);\n this.storagePath = storagePath;\n this.readOnly = config.readOnly ?? false;\n this.lightweightMode = config.lightweightMode ?? false;\n this.mdMirror = new MarkdownMirror(process.cwd());\n\n // Ensure storage directory exists (only if not read-only)\n if (!this.readOnly && !fs.existsSync(storagePath)) {\n fs.mkdirSync(storagePath, { recursive: true });\n }\n\n // Store project hash for shared store operations\n this.projectHash = config.projectHash || null;\n this.projectPath = config.projectPath || null;\n // Default: shared store enabled\n this.sharedStoreConfig = config.sharedStoreConfig ?? { enabled: true };\n\n // Initialize PRIMARY store: SQLite (WAL mode)\n // This is always used for writes and is the source of truth\n this.sqliteStore = new SQLiteEventStore(\n path.join(storagePath, 'events.sqlite'),\n {\n readonly: this.readOnly,\n markdownMirrorRoot: storagePath\n }\n );\n\n // Initialize ANALYTICS store: DuckDB (optional, for server reads)\n // Hooks set analyticsEnabled=false to avoid DuckDB lock conflicts\n const analyticsEnabled = config.analyticsEnabled ?? this.readOnly; // Default: enabled only for read-only (server)\n\n if (!analyticsEnabled) {\n // Hook mode: skip DuckDB entirely to avoid lock conflicts\n this.analyticsStore = null;\n } else if (this.readOnly) {\n // Server mode: try to use DuckDB for analytics, will fallback to SQLite\n try {\n this.analyticsStore = new EventStore(\n path.join(storagePath, 'analytics.duckdb'),\n { readOnly: true }\n );\n } catch {\n // DuckDB not available, will use SQLite for reads\n this.analyticsStore = null;\n }\n } else {\n // Writer mode with analytics: create DuckDB for sync target\n this.analyticsStore = new EventStore(\n path.join(storagePath, 'analytics.duckdb'),\n { readOnly: false }\n );\n }\n\n this.vectorStore = new VectorStore(path.join(storagePath, 'vectors'));\n const embeddingModel = config.embeddingModel || process.env.CLAUDE_MEMORY_EMBEDDING_MODEL;\n this.embedder = embeddingModel\n ? new Embedder(embeddingModel)\n : getDefaultEmbedder();\n this.matcher = getDefaultMatcher();\n // Retriever uses SQLite as primary (always available)\n this.retriever = createRetriever(\n this.sqliteStore as unknown as EventStore, // Interface compatible\n this.vectorStore,\n this.embedder,\n this.matcher\n );\n this.retriever.setQueryRewriter((q) => this.rewriteQueryIntent(q));\n this.graduation = createGraduationPipeline(this.sqliteStore as unknown as EventStore);\n }\n\n /**\n * Initialize all components\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Initialize PRIMARY store: SQLite (always)\n await this.sqliteStore.initialize();\n\n // Lightweight mode: only SQLite, no embedder/vector/workers\n // Used for hooks that just need to store data quickly\n if (this.lightweightMode) {\n this.initialized = true;\n return;\n }\n\n // Initialize analytics store if available (DuckDB)\n if (this.analyticsStore) {\n try {\n await this.analyticsStore.initialize();\n } catch (error) {\n console.warn('[MemoryService] Analytics store (DuckDB) initialization failed, using SQLite for reads:', error);\n // Continue without analytics - SQLite will be used for reads\n }\n }\n\n await this.vectorStore.initialize();\n await this.embedder.initialize();\n\n // Skip write-related workers in read-only mode\n if (!this.readOnly) {\n // Start vector worker (uses SQLite as source)\n this.vectorWorker = createVectorWorker(\n this.sqliteStore as unknown as EventStore,\n this.vectorStore,\n this.embedder\n );\n this.vectorWorker.start();\n\n // Connect graduation pipeline to retriever for access tracking\n this.retriever.setGraduationPipeline(this.graduation);\n\n // Start graduation worker for automatic level promotion\n this.graduationWorker = createGraduationWorker(\n this.sqliteStore as unknown as EventStore,\n this.graduation\n );\n this.graduationWorker.start();\n\n // Start sync worker (SQLite -> DuckDB) if analytics store is available\n if (this.analyticsStore) {\n this.syncWorker = new SyncWorker(\n this.sqliteStore,\n this.analyticsStore,\n { intervalMs: 30000, batchSize: 500 }\n );\n this.syncWorker.start();\n }\n\n // Load endless mode setting\n const savedMode = await this.sqliteStore.getEndlessConfig('mode') as MemoryMode | null;\n if (savedMode === 'endless') {\n this.endlessMode = 'endless';\n await this.initializeEndlessMode();\n }\n\n // Initialize shared store (enabled by default)\n if (this.sharedStoreConfig?.enabled !== false) {\n await this.initializeSharedStore();\n }\n }\n\n this.initialized = true;\n }\n\n /**\n * Initialize Shared Store components\n */\n private async initializeSharedStore(): Promise<void> {\n const sharedPath = this.sharedStoreConfig?.sharedStoragePath\n ? this.expandPath(this.sharedStoreConfig.sharedStoragePath)\n : SHARED_STORAGE_PATH;\n\n // Ensure shared directory exists\n if (!fs.existsSync(sharedPath)) {\n fs.mkdirSync(sharedPath, { recursive: true });\n }\n\n this.sharedEventStore = createSharedEventStore(\n path.join(sharedPath, 'shared.duckdb')\n );\n await this.sharedEventStore.initialize();\n\n this.sharedStore = createSharedStore(this.sharedEventStore);\n this.sharedVectorStore = createSharedVectorStore(\n path.join(sharedPath, 'vectors')\n );\n await this.sharedVectorStore.initialize();\n\n this.sharedPromoter = createSharedPromoter(\n this.sharedStore,\n this.sharedVectorStore,\n this.embedder,\n this.sharedStoreConfig || undefined\n );\n\n // Connect shared stores to retriever\n this.retriever.setSharedStores(this.sharedStore, this.sharedVectorStore);\n }\n\n registerIngestBefore(interceptor: IngestInterceptor): () => void {\n return this.ingestInterceptors.registerBefore(interceptor);\n }\n\n registerIngestAfter(interceptor: IngestInterceptor): () => void {\n return this.ingestInterceptors.registerAfter(interceptor);\n }\n\n registerIngestOnError(interceptor: IngestInterceptor): () => void {\n return this.ingestInterceptors.registerOnError(interceptor);\n }\n\n private async ingestWithInterceptors(\n operation: 'user_prompt' | 'agent_response' | 'session_summary' | 'tool_observation',\n input: MemoryEventInput,\n onSuccess?: (eventId: string) => Promise<void>\n ): Promise<AppendResult> {\n const normalizedInput: MemoryEventInput = {\n ...input,\n metadata: mergeHierarchicalMetadata(\n {\n ingest: {\n operation,\n pipeline: 'default',\n ts: new Date().toISOString()\n },\n ...(this.projectHash\n ? {\n scope: {\n project: {\n hash: this.projectHash,\n ...(this.projectPath ? { path: this.projectPath } : {})\n }\n },\n tags: [`proj:${this.projectHash}`]\n }\n : {})\n },\n input.metadata\n )\n };\n\n if (this.projectHash && normalizedInput.metadata) {\n const meta = normalizedInput.metadata as Record<string, unknown>;\n const currentTags = Array.isArray(meta.tags)\n ? meta.tags.filter((x): x is string => typeof x === 'string')\n : [];\n const projectTag = `proj:${this.projectHash}`;\n if (!currentTags.includes(projectTag)) {\n meta.tags = [...currentTags, projectTag];\n }\n }\n\n if (normalizedInput.metadata) {\n const meta = normalizedInput.metadata as Record<string, unknown>;\n const normalizedTags = normalizeTags(meta.tags);\n if (normalizedTags.length > 0) {\n meta.tags = normalizedTags;\n }\n }\n\n await this.ingestInterceptors.run('before', {\n operation,\n sessionId: normalizedInput.sessionId,\n event: normalizedInput\n });\n\n try {\n const result = await this.sqliteStore.append(normalizedInput);\n if (result.success && !result.isDuplicate) {\n if (onSuccess) {\n await onSuccess(result.eventId);\n }\n try {\n await this.mdMirror.append(normalizedInput, result.eventId);\n } catch {\n // non-breaking markdown mirror write\n }\n }\n\n await this.ingestInterceptors.run('after', {\n operation,\n sessionId: normalizedInput.sessionId,\n event: normalizedInput\n });\n\n return result;\n } catch (error) {\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n await this.ingestInterceptors.run('error', {\n operation,\n sessionId: normalizedInput.sessionId,\n event: normalizedInput,\n error: normalizedError\n });\n throw error;\n }\n }\n\n /**\n * Start a new session\n */\n async startSession(sessionId: string, projectPath?: string): Promise<void> {\n await this.initialize();\n\n await this.sqliteStore.upsertSession({\n id: sessionId,\n startedAt: new Date(),\n projectPath\n });\n }\n\n /**\n * End a session\n */\n async endSession(sessionId: string, summary?: string): Promise<void> {\n await this.initialize();\n\n await this.sqliteStore.upsertSession({\n id: sessionId,\n endedAt: new Date(),\n summary\n });\n }\n\n /**\n * Store a user prompt\n */\n async storeUserPrompt(\n sessionId: string,\n content: string,\n metadata?: Record<string, unknown>\n ): Promise<AppendResult> {\n await this.initialize();\n\n return this.ingestWithInterceptors(\n 'user_prompt',\n {\n eventType: 'user_prompt',\n sessionId,\n timestamp: new Date(),\n content,\n metadata\n },\n async (eventId) => {\n await this.sqliteStore.enqueueForEmbedding(eventId, content);\n }\n );\n }\n\n /**\n * Store an agent response\n */\n async storeAgentResponse(\n sessionId: string,\n content: string,\n metadata?: Record<string, unknown>\n ): Promise<AppendResult> {\n await this.initialize();\n\n return this.ingestWithInterceptors(\n 'agent_response',\n {\n eventType: 'agent_response',\n sessionId,\n timestamp: new Date(),\n content,\n metadata\n },\n async (eventId) => {\n await this.sqliteStore.enqueueForEmbedding(eventId, content);\n }\n );\n }\n\n /**\n * Store a session summary\n */\n async storeSessionSummary(\n sessionId: string,\n summary: string,\n metadata?: Record<string, unknown>\n ): Promise<AppendResult> {\n await this.initialize();\n\n return this.ingestWithInterceptors(\n 'session_summary',\n {\n eventType: 'session_summary',\n sessionId,\n timestamp: new Date(),\n content: summary,\n metadata\n },\n async (eventId) => {\n await this.sqliteStore.enqueueForEmbedding(eventId, summary);\n }\n );\n }\n\n /**\n * Store a tool observation\n */\n async storeToolObservation(\n sessionId: string,\n payload: ToolObservationPayload\n ): Promise<AppendResult> {\n await this.initialize();\n\n // Create content for storage (JSON stringified payload)\n const content = JSON.stringify(payload);\n\n // Extract turnId from payload metadata if present (set by PostToolUse hook)\n const turnId = payload.metadata?.turnId;\n\n return this.ingestWithInterceptors(\n 'tool_observation',\n {\n eventType: 'tool_observation',\n sessionId,\n timestamp: new Date(),\n content,\n metadata: {\n toolName: payload.toolName,\n success: payload.success,\n ...(turnId ? { turnId } : {})\n }\n },\n async (eventId) => {\n const embeddingContent = createToolObservationEmbedding(\n payload.toolName,\n payload.metadata || {},\n payload.success\n );\n await this.sqliteStore.enqueueForEmbedding(eventId, embeddingContent);\n }\n );\n }\n\n /**\n * Retrieve relevant memories for a query\n */\n async retrieveMemories(\n query: string,\n options?: {\n topK?: number;\n minScore?: number;\n sessionId?: string;\n includeShared?: boolean;\n adaptiveRerank?: boolean;\n intentRewrite?: boolean;\n projectScopeMode?: 'strict' | 'prefer' | 'global';\n allowedProjectHashes?: string[];\n }\n ): Promise<UnifiedRetrievalResult> {\n await this.initialize();\n\n // Note: Pending embeddings are processed by the background worker\n // Don't block retrieval - search with whatever vectors are available\n\n const rerankWeights = await this.getRerankWeights(options?.adaptiveRerank === true);\n\n // Use unified retrieval if shared search is requested\n let result: UnifiedRetrievalResult;\n\n if (options?.includeShared && this.sharedStore) {\n result = await this.retriever.retrieveUnified(query, {\n ...options,\n intentRewrite: options?.intentRewrite === true,\n rerankWeights,\n includeShared: true,\n projectHash: this.projectHash || undefined,\n projectScopeMode: options?.projectScopeMode ?? (this.projectHash ? 'strict' : 'global'),\n allowedProjectHashes: options?.allowedProjectHashes\n });\n } else {\n result = await this.retriever.retrieve(query, {\n ...options,\n intentRewrite: options?.intentRewrite === true,\n rerankWeights,\n projectHash: this.projectHash || undefined,\n projectScopeMode: options?.projectScopeMode ?? (this.projectHash ? 'strict' : 'global'),\n allowedProjectHashes: options?.allowedProjectHashes\n });\n }\n\n try {\n const selectedEventIds = result.memories.map((m) => m.event.id);\n const selectedDetails = (result.selectedDebug || []).map((d) => ({\n eventId: d.eventId,\n score: d.score,\n semanticScore: d.semanticScore,\n lexicalScore: d.lexicalScore,\n recencyScore: d.recencyScore,\n }));\n const candidateDetails = (result.candidateDebug || []).map((d) => ({\n eventId: d.eventId,\n score: d.score,\n semanticScore: d.semanticScore,\n lexicalScore: d.lexicalScore,\n recencyScore: d.recencyScore,\n }));\n const candidateEventIds = candidateDetails.length > 0\n ? candidateDetails.map((d) => d.eventId)\n : selectedEventIds;\n await this.sqliteStore.recordRetrievalTrace({\n sessionId: options?.sessionId,\n projectHash: this.projectHash || undefined,\n queryText: query,\n strategy: options?.strategy || 'auto',\n candidateEventIds,\n selectedEventIds,\n candidateDetails,\n selectedDetails,\n confidence: result.matchResult.confidence,\n fallbackTrace: result.fallbackTrace || []\n });\n } catch {\n // non-blocking telemetry\n }\n\n return result;\n }\n\n private getConfiguredRerankWeights(): { semantic: number; lexical: number; recency: number } | undefined {\n const semantic = Number(process.env.MEMORY_RERANK_WEIGHT_SEMANTIC ?? '');\n const lexical = Number(process.env.MEMORY_RERANK_WEIGHT_LEXICAL ?? '');\n const recency = Number(process.env.MEMORY_RERANK_WEIGHT_RECENCY ?? '');\n\n const allFinite = [semantic, lexical, recency].every((v) => Number.isFinite(v));\n if (!allFinite) return undefined;\n\n const nonNegative = [semantic, lexical, recency].every((v) => v >= 0);\n const total = semantic + lexical + recency;\n if (!nonNegative || total <= 0) return undefined;\n\n return {\n semantic: semantic / total,\n lexical: lexical / total,\n recency: recency / total,\n };\n }\n\n private async getRerankWeights(adaptive: boolean): Promise<{ semantic: number; lexical: number; recency: number } | undefined> {\n const configured = this.getConfiguredRerankWeights();\n if (configured) return configured;\n if (adaptive) return this.getAdaptiveRerankWeights();\n return undefined;\n }\n\n private async rewriteQueryIntent(query: string): Promise<string | null> {\n if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== '1') return null;\n\n const apiUrl = process.env.COMPANY_STOCK_API_URL || process.env.COMPANY_INT_API_URL;\n if (!apiUrl) return null;\n\n const controller = new AbortController();\n const timeoutMs = Number(process.env.MEMORY_INTENT_REWRITE_TIMEOUT_MS || 5000);\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const prompt = [\n 'Rewrite user query for memory retrieval intent expansion.',\n 'Return plain text only, one line, no markdown.',\n `Query: ${query}`,\n ].join('\\n');\n\n const res = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: '*/*',\n Origin: process.env.COMPANY_INT_ORIGIN || 'http://company-int.aplusai.ai',\n Referer: process.env.COMPANY_INT_REFERER || 'http://company-int.aplusai.ai/',\n },\n body: JSON.stringify({\n question: prompt,\n company_name: null,\n conversation_id: null,\n }),\n signal: controller.signal,\n });\n\n const text = (await res.text()).trim();\n if (!text) return null;\n\n const oneLine = text\n .replace(/^data:\\s*/gm, '')\n .split(/\\r?\\n/)\n .map((x) => x.trim())\n .filter(Boolean)\n .join(' ')\n .slice(0, 240);\n\n if (!oneLine || oneLine.toLowerCase() === query.toLowerCase()) return null;\n return oneLine;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private async getAdaptiveRerankWeights(): Promise<{ semantic: number; lexical: number; recency: number } | undefined> {\n try {\n const s = await this.sqliteStore.getHelpfulnessStats();\n if (s.totalEvaluated < 20) return undefined;\n\n // base weights\n let semantic = 0.7;\n let lexical = 0.2;\n let recency = 0.1;\n\n if (s.avgScore < 0.45) {\n semantic -= 0.1;\n lexical += 0.1;\n } else if (s.avgScore > 0.75) {\n semantic += 0.05;\n lexical -= 0.05;\n }\n\n if (s.unhelpful > s.helpful) {\n recency += 0.05;\n semantic -= 0.03;\n lexical -= 0.02;\n }\n\n return { semantic, lexical, recency };\n } catch {\n return undefined;\n }\n }\n\n /**\n * Fast keyword search using SQLite FTS5\n * Much faster than vector search - no embedding model needed\n */\n async keywordSearch(\n query: string,\n options?: { topK?: number; minScore?: number }\n ): Promise<Array<{event: MemoryEvent; score: number}>> {\n await this.initialize();\n\n const results = await this.sqliteStore.keywordSearch(query, options?.topK ?? 10);\n\n // Normalize FTS5 rank to a score (0-1 range)\n // FTS5 rank is negative (higher is worse), so we convert it\n const maxRank = Math.min(...results.map(r => r.rank), -0.001);\n const minRank = Math.max(...results.map(r => r.rank), -1000);\n const rankRange = maxRank - minRank || 1;\n\n return results.map(r => ({\n event: r.event,\n score: 1 - (r.rank - minRank) / rankRange // Normalize to 0-1\n })).filter(r => !options?.minScore || r.score >= options.minScore);\n }\n\n /**\n * Rebuild FTS index (call after database upgrade)\n */\n async rebuildFtsIndex(): Promise<number> {\n await this.initialize();\n return this.sqliteStore.rebuildFtsIndex();\n }\n\n /**\n * Get session history\n */\n async getSessionHistory(sessionId: string): Promise<MemoryEvent[]> {\n await this.initialize();\n return this.sqliteStore.getSessionEvents(sessionId);\n }\n\n /**\n * Get recent events\n */\n async getRecentEvents(limit: number = 100): Promise<MemoryEvent[]> {\n await this.initialize();\n return this.sqliteStore.getRecentEvents(limit);\n }\n\n /**\n * Get memory statistics\n */\n\n async getOutboxStats(): Promise<{\n embedding: { pending: number; processing: number; failed: number; total: number };\n vector: { pending: number; processing: number; failed: number; total: number };\n }> {\n await this.initialize();\n return this.sqliteStore.getOutboxStats();\n }\n\n async getRetrievalTraceStats(): Promise<{\n totalQueries: number;\n avgCandidateCount: number;\n avgSelectedCount: number;\n selectionRate: number;\n }> {\n await this.initialize();\n return this.sqliteStore.getRetrievalTraceStats();\n }\n\n async getRecentRetrievalTraces(limit: number = 50) {\n await this.initialize();\n return this.sqliteStore.getRecentRetrievalTraces(limit);\n }\n\n async getStats(): Promise<{\n totalEvents: number;\n vectorCount: number;\n levelStats: Array<{ level: string; count: number }>;\n }> {\n await this.initialize();\n\n const recentEvents = await this.sqliteStore.getRecentEvents(10000);\n const vectorCount = await this.vectorStore.count();\n const levelStats = await this.graduation.getStats();\n\n return {\n totalEvents: recentEvents.length,\n vectorCount,\n levelStats\n };\n }\n\n /**\n * Process pending embeddings\n */\n async processPendingEmbeddings(): Promise<number> {\n if (this.vectorWorker) {\n return this.vectorWorker.processAll();\n }\n return 0;\n }\n\n /**\n * Get events by memory level\n */\n async getEventsByLevel(level: string, options?: { limit?: number; offset?: number }): Promise<MemoryEvent[]> {\n await this.initialize();\n return this.sqliteStore.getEventsByLevel(level, options);\n }\n\n /**\n * Get memory level for a specific event\n */\n async getEventLevel(eventId: string): Promise<string | null> {\n await this.initialize();\n return this.sqliteStore.getEventLevel(eventId);\n }\n\n /**\n * Format retrieval results as context for Claude\n */\n formatAsContext(result: RetrievalResult): string {\n if (!result.context) {\n return '';\n }\n\n const confidence = result.matchResult.confidence;\n let header = '';\n\n if (confidence === 'high') {\n header = '\uD83C\uDFAF **High-confidence memory match found:**\\n\\n';\n } else if (confidence === 'suggested') {\n header = '\uD83D\uDCA1 **Suggested memories (may be relevant):**\\n\\n';\n }\n\n return header + result.context;\n }\n\n // ============================================================\n // Shared Store Methods (Cross-Project Knowledge)\n // ============================================================\n\n /**\n * Check if shared store is enabled and initialized\n */\n isSharedStoreEnabled(): boolean {\n return this.sharedStore !== null;\n }\n\n /**\n * Promote an entry to shared storage\n */\n async promoteToShared(entry: Entry): Promise<PromotionResult> {\n if (!this.sharedPromoter || !this.projectHash) {\n return {\n success: false,\n error: 'Shared store not initialized or project hash not set'\n };\n }\n\n return this.sharedPromoter.promoteEntry(entry, this.projectHash);\n }\n\n /**\n * Get shared store statistics\n */\n async getSharedStoreStats(): Promise<{\n total: number;\n averageConfidence: number;\n topTopics: Array<{ topic: string; count: number }>;\n totalUsageCount: number;\n } | null> {\n if (!this.sharedStore) return null;\n return this.sharedStore.getStats();\n }\n\n /**\n * Search shared troubleshooting entries\n */\n async searchShared(\n query: string,\n options?: { topK?: number; minConfidence?: number }\n ) {\n if (!this.sharedStore) return [];\n return this.sharedStore.search(query, options);\n }\n\n /**\n * Get project hash for this service\n */\n getProjectHash(): string | null {\n return this.projectHash;\n }\n\n // ============================================================\n // Endless Mode Methods\n // ============================================================\n\n /**\n * Get the default endless mode config\n */\n private getDefaultEndlessConfig(): EndlessModeConfig {\n return {\n enabled: true,\n workingSet: {\n maxEvents: 100,\n timeWindowHours: 24,\n minRelevanceScore: 0.5\n },\n consolidation: {\n triggerIntervalMs: 3600000, // 1 hour\n triggerEventCount: 100,\n triggerIdleMs: 1800000, // 30 minutes\n useLLMSummarization: false\n },\n continuity: {\n minScoreForSeamless: 0.7,\n topicDecayHours: 48\n }\n };\n }\n\n /**\n * Initialize Endless Mode components\n */\n async initializeEndlessMode(): Promise<void> {\n const config = await this.getEndlessConfig();\n\n this.workingSetStore = createWorkingSetStore(this.sqliteStore, config);\n this.consolidatedStore = createConsolidatedStore(this.sqliteStore);\n this.consolidationWorker = createConsolidationWorker(\n this.workingSetStore,\n this.consolidatedStore,\n config\n );\n this.continuityManager = createContinuityManager(this.sqliteStore, config);\n\n // Start consolidation worker\n this.consolidationWorker.start();\n }\n\n /**\n * Get Endless Mode configuration\n */\n async getEndlessConfig(): Promise<EndlessModeConfig> {\n const savedConfig = await this.sqliteStore.getEndlessConfig('config') as EndlessModeConfig | null;\n return savedConfig || this.getDefaultEndlessConfig();\n }\n\n /**\n * Set Endless Mode configuration\n */\n async setEndlessConfig(config: Partial<EndlessModeConfig>): Promise<void> {\n const current = await this.getEndlessConfig();\n const merged = { ...current, ...config };\n await this.sqliteStore.setEndlessConfig('config', merged);\n }\n\n /**\n * Set memory mode (session or endless)\n */\n async setMode(mode: MemoryMode): Promise<void> {\n await this.initialize();\n\n if (mode === this.endlessMode) return;\n\n this.endlessMode = mode;\n await this.sqliteStore.setEndlessConfig('mode', mode);\n\n if (mode === 'endless') {\n await this.initializeEndlessMode();\n } else {\n // Stop endless mode components\n if (this.consolidationWorker) {\n this.consolidationWorker.stop();\n this.consolidationWorker = null;\n }\n this.workingSetStore = null;\n this.consolidatedStore = null;\n this.continuityManager = null;\n }\n }\n\n /**\n * Get current memory mode\n */\n getMode(): MemoryMode {\n return this.endlessMode;\n }\n\n /**\n * Check if endless mode is active\n */\n isEndlessModeActive(): boolean {\n return this.endlessMode === 'endless';\n }\n\n /**\n * Add event to Working Set (Endless Mode)\n */\n async addToWorkingSet(eventId: string, relevanceScore?: number): Promise<void> {\n if (!this.workingSetStore) return;\n await this.workingSetStore.add(eventId, relevanceScore);\n }\n\n /**\n * Get the current Working Set\n */\n async getWorkingSet(): Promise<WorkingSet | null> {\n if (!this.workingSetStore) return null;\n return this.workingSetStore.get();\n }\n\n /**\n * Search consolidated memories\n */\n async searchConsolidated(\n query: string,\n options?: { topK?: number }\n ): Promise<ConsolidatedMemory[]> {\n if (!this.consolidatedStore) return [];\n return this.consolidatedStore.search(query, options);\n }\n\n /**\n * Get all consolidated memories\n */\n async getConsolidatedMemories(limit?: number): Promise<ConsolidatedMemory[]> {\n if (!this.consolidatedStore) return [];\n return this.consolidatedStore.getAll({ limit });\n }\n\n /**\n * Extract topic keywords from event content (markdown headings and key terms)\n */\n private extractTopicsFromContent(content: string): string[] {\n const topics: Set<string> = new Set();\n\n // Extract markdown headings (## heading)\n const headings = content.match(/^#{1,3}\\s+(.+)$/gm);\n if (headings) {\n for (const h of headings.slice(0, 5)) {\n const text = h.replace(/^#+\\s+/, '').replace(/[*_`#]/g, '').trim();\n if (text.length > 2 && text.length < 50) {\n topics.add(text);\n }\n }\n }\n\n // Extract bold terms (**term**)\n const boldTerms = content.match(/\\*\\*([^*]+)\\*\\*/g);\n if (boldTerms) {\n for (const b of boldTerms.slice(0, 5)) {\n const text = b.replace(/\\*\\*/g, '').trim();\n if (text.length > 2 && text.length < 30) {\n topics.add(text);\n }\n }\n }\n\n return Array.from(topics).slice(0, 5);\n }\n\n /**\n * Increment access count for memories that were used in prompts\n */\n async incrementMemoryAccess(eventIds: string[]): Promise<void> {\n if (eventIds.length === 0) return;\n\n // Use SQLite event store if available\n if (this.sqliteStore) {\n await this.sqliteStore.incrementAccessCount(eventIds);\n } else if (this.eventStore) {\n // Fallback to regular event store (which has a stub implementation)\n await this.eventStore.incrementAccessCount(eventIds);\n }\n }\n\n /**\n * Get most accessed memories from events\n */\n async getMostAccessedMemories(limit: number = 10): Promise<any[]> {\n console.log('[getMostAccessedMemories] sqliteStore available:', !!this.sqliteStore);\n\n // Try to get from SQLite event store if available\n if (this.sqliteStore) {\n const events = await this.sqliteStore.getMostAccessed(limit);\n console.log('[getMostAccessedMemories] Got events from SQLite:', events.length);\n return events.map(event => ({\n memoryId: event.id,\n summary: event.content.substring(0, 200) + (event.content.length > 200 ? '...' : ''),\n topics: this.extractTopicsFromContent(event.content),\n accessCount: (event as any).access_count || 0,\n lastAccessed: (event as any).last_accessed_at || null,\n confidence: 1.0,\n createdAt: event.timestamp\n }));\n }\n\n // Fallback to consolidated store if available\n if (this.consolidatedStore) {\n const consolidated = await this.consolidatedStore.getMostAccessed(limit);\n return consolidated.map(m => ({\n memoryId: m.memoryId,\n summary: m.summary,\n topics: m.topics,\n accessCount: m.accessCount,\n lastAccessed: m.accessedAt,\n confidence: m.confidence,\n createdAt: m.createdAt\n }));\n }\n\n return [];\n }\n\n /**\n * Record a memory retrieval for helpfulness tracking\n */\n async recordRetrieval(eventId: string, sessionId: string, score: number, query: string): Promise<void> {\n await this.initialize();\n await this.sqliteStore.recordRetrieval(eventId, sessionId, score, query);\n }\n\n /**\n * Evaluate helpfulness of retrievals in a session (called at session end)\n */\n async evaluateSessionHelpfulness(sessionId: string): Promise<void> {\n await this.initialize();\n await this.sqliteStore.evaluateSessionHelpfulness(sessionId);\n }\n\n /**\n * Get most helpful memories ranked by helpfulness score\n */\n async getHelpfulMemories(limit: number = 10): Promise<Array<{\n eventId: string;\n summary: string;\n helpfulnessScore: number;\n accessCount: number;\n evaluationCount: number;\n }>> {\n await this.initialize();\n return this.sqliteStore.getHelpfulMemories(limit);\n }\n\n /**\n * Get helpfulness statistics for dashboard\n */\n async getHelpfulnessStats(): Promise<{\n avgScore: number;\n totalEvaluated: number;\n totalRetrievals: number;\n helpful: number;\n neutral: number;\n unhelpful: number;\n }> {\n await this.initialize();\n return this.sqliteStore.getHelpfulnessStats();\n }\n\n /**\n * Mark a consolidated memory as accessed\n */\n async markMemoryAccessed(memoryId: string): Promise<void> {\n if (!this.consolidatedStore) return;\n await this.consolidatedStore.markAccessed(memoryId);\n }\n\n /**\n * Calculate continuity score for current context\n */\n async calculateContinuity(\n content: string,\n metadata?: { files?: string[]; entities?: string[] }\n ): Promise<ContinuityScore | null> {\n if (!this.continuityManager) return null;\n\n const snapshot = this.continuityManager.createSnapshot(\n crypto.randomUUID(),\n content,\n metadata\n );\n\n return this.continuityManager.calculateScore(snapshot);\n }\n\n /**\n * Record activity (for consolidation idle trigger)\n */\n recordActivity(): void {\n if (this.consolidationWorker) {\n this.consolidationWorker.recordActivity();\n }\n }\n\n /**\n * Force a consolidation run\n */\n async forceConsolidation(): Promise<number> {\n if (!this.consolidationWorker) return 0;\n return this.consolidationWorker.forceRun();\n }\n\n /**\n * Get Endless Mode status\n */\n async getEndlessModeStatus(): Promise<EndlessModeStatus> {\n await this.initialize();\n\n let workingSetSize = 0;\n let continuityScore = 0.5;\n let consolidatedCount = 0;\n let lastConsolidation: Date | null = null;\n\n if (this.workingSetStore) {\n workingSetSize = await this.workingSetStore.count();\n const workingSet = await this.workingSetStore.get();\n continuityScore = workingSet.continuityScore;\n }\n\n if (this.consolidatedStore) {\n consolidatedCount = await this.consolidatedStore.count();\n lastConsolidation = await this.consolidatedStore.getLastConsolidationTime();\n }\n\n return {\n mode: this.endlessMode,\n workingSetSize,\n continuityScore,\n consolidatedCount,\n lastConsolidation\n };\n }\n\n // ============================================================\n // Turn Grouping Methods\n // ============================================================\n\n /**\n * Get events grouped by turn for a session\n */\n async getSessionTurns(sessionId: string, options?: { limit?: number; offset?: number }): Promise<Array<{\n turnId: string;\n events: MemoryEvent[];\n startedAt: Date;\n promptPreview: string;\n eventCount: number;\n toolCount: number;\n hasResponse: boolean;\n }>> {\n await this.initialize();\n return this.sqliteStore.getSessionTurns(sessionId, options);\n }\n\n /**\n * Get all events for a specific turn\n */\n async getEventsByTurn(turnId: string): Promise<MemoryEvent[]> {\n await this.initialize();\n return this.sqliteStore.getEventsByTurn(turnId);\n }\n\n /**\n * Count total turns for a session\n */\n async countSessionTurns(sessionId: string): Promise<number> {\n await this.initialize();\n return this.sqliteStore.countSessionTurns(sessionId);\n }\n\n /**\n * Backfill turn_ids from metadata for events stored before the migration\n */\n async backfillTurnIds(): Promise<number> {\n await this.initialize();\n return this.sqliteStore.backfillTurnIds();\n }\n\n /**\n * Delete all events for a session (for force reimport)\n */\n async deleteSessionEvents(sessionId: string): Promise<number> {\n await this.initialize();\n return this.sqliteStore.deleteSessionEvents(sessionId);\n }\n\n /**\n * Format Endless Mode context for Claude\n */\n async formatEndlessContext(query: string): Promise<string> {\n if (!this.isEndlessModeActive()) {\n return '';\n }\n\n const workingSet = await this.getWorkingSet();\n const consolidated = await this.searchConsolidated(query, { topK: 3 });\n const continuity = await this.calculateContinuity(query);\n\n const parts: string[] = [];\n\n // Continuity status\n if (continuity) {\n const statusEmoji = continuity.transitionType === 'seamless' ? '\uD83D\uDD17' :\n continuity.transitionType === 'topic_shift' ? '\u21AA\uFE0F' : '\uD83C\uDD95';\n parts.push(`${statusEmoji} Context: ${continuity.transitionType} (score: ${continuity.score.toFixed(2)})`);\n }\n\n // Working set summary\n if (workingSet && workingSet.recentEvents.length > 0) {\n parts.push('\\n## Recent Context (Working Set)');\n const recent = workingSet.recentEvents.slice(0, 5);\n for (const event of recent) {\n const preview = event.content.slice(0, 80) + (event.content.length > 80 ? '...' : '');\n const time = event.timestamp.toLocaleTimeString();\n parts.push(`- ${time} [${event.eventType}] ${preview}`);\n }\n }\n\n // Consolidated memories\n if (consolidated.length > 0) {\n parts.push('\\n## Related Knowledge (Consolidated)');\n for (const memory of consolidated) {\n parts.push(`- ${memory.topics.slice(0, 3).join(', ')}: ${memory.summary.slice(0, 100)}...`);\n }\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Force a graduation evaluation run\n */\n async forceGraduation(): Promise<GraduationRunResult> {\n if (!this.graduationWorker) {\n return { evaluated: 0, graduated: 0, byLevel: {} };\n }\n return this.graduationWorker.forceRun();\n }\n\n /**\n * Record access to a memory event (for graduation scoring)\n */\n recordMemoryAccess(eventId: string, sessionId: string, confidence: number = 1.0): void {\n this.graduation.recordAccess(eventId, sessionId, confidence);\n }\n\n getEmbeddingModelName(): string {\n return this.embedder.getModelName();\n }\n\n /**\n * Ensure embedding model metadata is in sync and optionally migrate vectors.\n * Migration strategy: clear vector index + clear embedding outbox + re-enqueue all events.\n */\n async ensureEmbeddingModelForImport(options?: { autoMigrate?: boolean }): Promise<{\n changed: boolean;\n previousModel: string | null;\n currentModel: string;\n enqueued: number;\n reason?: string;\n }> {\n await this.initialize();\n\n const currentModel = this.getEmbeddingModelName();\n const metaPath = path.join(this.storagePath, 'embedding-meta.json');\n\n let previousModel: string | null = null;\n try {\n if (fs.existsSync(metaPath)) {\n const parsed = JSON.parse(fs.readFileSync(metaPath, 'utf-8')) as { model?: string };\n previousModel = parsed?.model || null;\n }\n } catch {\n previousModel = null;\n }\n\n const stats = await this.getStats();\n const hasExistingVectors = (stats.vectorCount || 0) > 0;\n\n // First-time metadata write (no migration needed unless legacy vectors exist)\n if (!previousModel && !hasExistingVectors) {\n fs.writeFileSync(metaPath, JSON.stringify({ model: currentModel, updatedAt: new Date().toISOString() }, null, 2));\n return { changed: false, previousModel: null, currentModel, enqueued: 0, reason: 'initialized-meta' };\n }\n\n const modelChanged = previousModel !== currentModel;\n const legacyUnknownButVectorsExist = !previousModel && hasExistingVectors;\n\n if (!modelChanged && !legacyUnknownButVectorsExist) {\n return { changed: false, previousModel, currentModel, enqueued: 0 };\n }\n\n if (options?.autoMigrate === false) {\n return {\n changed: true,\n previousModel,\n currentModel,\n enqueued: 0,\n reason: legacyUnknownButVectorsExist ? 'legacy-vectors-without-meta' : 'model-mismatch'\n };\n }\n\n // Pause background vector processing while preparing migration\n const wasRunning = this.vectorWorker?.isRunning() || false;\n if (wasRunning) this.vectorWorker?.stop();\n\n // Reset vector and outbox state\n await this.vectorStore.clearAll();\n await this.sqliteStore.clearEmbeddingOutbox();\n\n // Re-enqueue all events for new embeddings\n const pageSize = 1000;\n let offset = 0;\n let enqueued = 0;\n\n while (true) {\n const page = await this.sqliteStore.getEventsPage(pageSize, offset);\n if (page.length === 0) break;\n\n for (const event of page) {\n await this.sqliteStore.enqueueForEmbedding(event.id, event.content);\n enqueued += 1;\n }\n\n offset += page.length;\n if (page.length < pageSize) break;\n }\n\n fs.writeFileSync(\n metaPath,\n JSON.stringify(\n {\n model: currentModel,\n previousModel,\n migratedAt: new Date().toISOString(),\n enqueued\n },\n null,\n 2\n )\n );\n\n if (wasRunning) this.vectorWorker?.start();\n\n return {\n changed: true,\n previousModel,\n currentModel,\n enqueued,\n reason: legacyUnknownButVectorsExist ? 'legacy-vectors-without-meta' : 'model-mismatch'\n };\n }\n\n /**\n * Backward-compatible alias used by some hooks\n */\n async close(): Promise<void> {\n await this.shutdown();\n }\n\n /**\n * Shutdown service\n */\n async shutdown(): Promise<void> {\n // Stop graduation worker\n if (this.graduationWorker) {\n this.graduationWorker.stop();\n }\n\n // Stop endless mode components\n if (this.consolidationWorker) {\n this.consolidationWorker.stop();\n }\n\n if (this.vectorWorker) {\n this.vectorWorker.stop();\n }\n\n // Stop sync worker\n if (this.syncWorker) {\n this.syncWorker.stop();\n }\n\n // Close shared store\n if (this.sharedEventStore) {\n await this.sharedEventStore.close();\n }\n\n // Close primary store (SQLite)\n await this.sqliteStore.close();\n\n // Close analytics store (DuckDB)\n if (this.analyticsStore) {\n await this.analyticsStore.close();\n }\n }\n\n /**\n * Expand ~ to home directory\n */\n private expandPath(p: string): string {\n if (p.startsWith('~')) {\n return path.join(os.homedir(), p.slice(1));\n }\n return p;\n }\n}\n\n// ============================================================\n// Service Instance Management\n// ============================================================\n\n// Instance cache: Map from project hash (or '__global__') to MemoryService\nconst serviceCache = new Map<string, MemoryService>();\nconst GLOBAL_KEY = '__global__';\nconst GLOBAL_READONLY_KEY = '__global_readonly__';\n\n/**\n * Get the global memory service (backward compatibility)\n * Use this for operations not tied to a specific project\n * Note: analyticsEnabled=false and sharedStore disabled to avoid DuckDB lock conflicts\n */\nexport function getDefaultMemoryService(): MemoryService {\n if (!serviceCache.has(GLOBAL_KEY)) {\n serviceCache.set(GLOBAL_KEY, new MemoryService({\n storagePath: '~/.claude-code/memory',\n analyticsEnabled: false, // Hooks don't need DuckDB\n sharedStoreConfig: { enabled: false } // Shared store uses DuckDB too\n }));\n }\n return serviceCache.get(GLOBAL_KEY)!;\n}\n\n/**\n * Get a read-only global memory service\n * Use this for web server/dashboard that only needs to read data\n * Creates a fresh connection each time to avoid blocking the main writer process\n * Uses SQLite (WAL mode) which supports concurrent readers\n */\nexport function getReadOnlyMemoryService(): MemoryService {\n // Don't cache - create fresh instance each time to avoid holding locks\n // The connection will be closed when the request completes\n // Uses SQLite which supports concurrent readers via WAL mode\n return new MemoryService({\n storagePath: '~/.claude-code/memory',\n readOnly: true,\n analyticsEnabled: false, // Use SQLite for reads (WAL supports concurrent readers)\n sharedStoreConfig: { enabled: false } // Skip shared store for now\n });\n}\n\n/**\n * Get memory service for a specific project path\n * Creates isolated storage at ~/.claude-code/memory/projects/{hash}/\n * Note: analyticsEnabled=false and sharedStore disabled to avoid DuckDB lock conflicts\n */\nexport function getMemoryServiceForProject(\n projectPath: string,\n sharedStoreConfig?: SharedStoreConfig\n): MemoryService {\n const hash = hashProjectPath(projectPath);\n\n if (!serviceCache.has(hash)) {\n const storagePath = getProjectStoragePath(projectPath);\n serviceCache.set(hash, new MemoryService({\n storagePath,\n projectHash: hash,\n projectPath,\n // Override shared store config - hooks don't need DuckDB\n sharedStoreConfig: sharedStoreConfig ?? { enabled: false },\n analyticsEnabled: false // Hooks don't need DuckDB\n }));\n }\n\n return serviceCache.get(hash)!;\n}\n\n/**\n * Get memory service for a session by looking up its project\n * Falls back to global storage if session not found in registry\n */\nexport function getMemoryServiceForSession(sessionId: string): MemoryService {\n const projectInfo = getSessionProject(sessionId);\n\n if (projectInfo) {\n return getMemoryServiceForProject(projectInfo.projectPath);\n }\n\n // Fallback to global storage for unknown sessions (backward compat)\n return getDefaultMemoryService();\n}\n\n/**\n * Get a lightweight memory service for hooks\n * Only initializes SQLite - no embedder, no vector store, no workers\n * This is FAST (<100ms) compared to full initialization (3-5s)\n */\nexport function getLightweightMemoryService(sessionId: string): MemoryService {\n const projectInfo = getSessionProject(sessionId);\n const key = projectInfo ? `lightweight_${projectInfo.projectHash}` : 'lightweight_global';\n\n if (!serviceCache.has(key)) {\n const storagePath = projectInfo\n ? getProjectStoragePath(projectInfo.projectPath)\n : path.join(os.homedir(), '.claude-code', 'memory');\n\n serviceCache.set(key, new MemoryService({\n storagePath,\n projectHash: projectInfo?.projectHash,\n projectPath: projectInfo?.projectPath,\n lightweightMode: true, // Skip embedder/vector/workers\n analyticsEnabled: false,\n sharedStoreConfig: { enabled: false }\n }));\n }\n\n return serviceCache.get(key)!;\n}\n\nexport function createMemoryService(config: MemoryServiceConfig): MemoryService {\n return new MemoryService(config);\n}\n", "/**\n * AXIOMMIND EventStore implementation\n * Principles: Append-only, Single Source of Truth, Idempotency\n */\n\nimport { randomUUID } from 'crypto';\nimport {\n MemoryEvent,\n MemoryEventInput,\n Session,\n AppendResult,\n OutboxItem\n} from './types.js';\nimport { makeCanonicalKey, makeDedupeKey } from './canonical-key.js';\nimport { createDatabase, dbRun, dbAll, dbClose, toDate, type Database, type DatabaseOptions } from './db-wrapper.js';\n\nexport interface EventStoreOptions extends DatabaseOptions {\n // Additional options can be added here\n}\n\nexport class EventStore {\n private db: Database;\n private initialized = false;\n private readonly readOnly: boolean;\n\n constructor(private dbPath: string, options?: EventStoreOptions) {\n this.readOnly = options?.readOnly ?? false;\n this.db = createDatabase(dbPath, { readOnly: this.readOnly });\n }\n\n /**\n * Initialize database schema\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // In read-only mode, skip schema creation (tables already exist)\n if (this.readOnly) {\n this.initialized = true;\n return;\n }\n\n // L0 EventStore: Single Source of Truth (immutable, append-only)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS events (\n id VARCHAR PRIMARY KEY,\n event_type VARCHAR NOT NULL,\n session_id VARCHAR NOT NULL,\n timestamp TIMESTAMP NOT NULL,\n content TEXT NOT NULL,\n canonical_key VARCHAR NOT NULL,\n dedupe_key VARCHAR UNIQUE,\n metadata JSON\n )\n `);\n\n // Dedup table for idempotency\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS event_dedup (\n dedupe_key VARCHAR PRIMARY KEY,\n event_id VARCHAR NOT NULL,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Session metadata\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS sessions (\n id VARCHAR PRIMARY KEY,\n started_at TIMESTAMP NOT NULL,\n ended_at TIMESTAMP,\n project_path VARCHAR,\n summary TEXT,\n tags JSON\n )\n `);\n\n // Insights (derived data, rebuildable)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS insights (\n id VARCHAR PRIMARY KEY,\n insight_type VARCHAR NOT NULL,\n content TEXT NOT NULL,\n canonical_key VARCHAR NOT NULL,\n confidence FLOAT,\n source_events JSON,\n created_at TIMESTAMP,\n last_updated TIMESTAMP\n )\n `);\n\n // Embedding Outbox (Single-Writer Pattern)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS embedding_outbox (\n id VARCHAR PRIMARY KEY,\n event_id VARCHAR NOT NULL,\n content TEXT NOT NULL,\n status VARCHAR DEFAULT 'pending',\n retry_count INT DEFAULT 0,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n processed_at TIMESTAMP,\n error_message TEXT\n )\n `);\n\n // Projection offset tracking\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS projection_offsets (\n projection_name VARCHAR PRIMARY KEY,\n last_event_id VARCHAR,\n last_timestamp TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Memory level tracking\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS memory_levels (\n event_id VARCHAR PRIMARY KEY,\n level VARCHAR NOT NULL DEFAULT 'L0',\n promoted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // ============================================================\n // Entity-Edge Model Tables\n // ============================================================\n\n // Entries (immutable memory units)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS entries (\n entry_id VARCHAR PRIMARY KEY,\n created_ts TIMESTAMP NOT NULL,\n entry_type VARCHAR NOT NULL,\n title VARCHAR NOT NULL,\n content_json JSON NOT NULL,\n stage VARCHAR NOT NULL DEFAULT 'raw',\n status VARCHAR DEFAULT 'active',\n superseded_by VARCHAR,\n build_id VARCHAR,\n evidence_json JSON,\n canonical_key VARCHAR,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Entities (task/condition/artifact)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS entities (\n entity_id VARCHAR PRIMARY KEY,\n entity_type VARCHAR NOT NULL,\n canonical_key VARCHAR NOT NULL,\n title VARCHAR NOT NULL,\n stage VARCHAR NOT NULL DEFAULT 'raw',\n status VARCHAR NOT NULL DEFAULT 'active',\n current_json JSON NOT NULL,\n title_norm VARCHAR,\n search_text VARCHAR,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Entity aliases for canonical key lookup\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS entity_aliases (\n entity_type VARCHAR NOT NULL,\n canonical_key VARCHAR NOT NULL,\n entity_id VARCHAR NOT NULL,\n is_primary BOOLEAN DEFAULT FALSE,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY(entity_type, canonical_key)\n )\n `);\n\n // Edges (relationships between entries/entities)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS edges (\n edge_id VARCHAR PRIMARY KEY,\n src_type VARCHAR NOT NULL,\n src_id VARCHAR NOT NULL,\n rel_type VARCHAR NOT NULL,\n dst_type VARCHAR NOT NULL,\n dst_id VARCHAR NOT NULL,\n meta_json JSON,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // ============================================================\n // Vector Outbox V2 Table\n // ============================================================\n\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS vector_outbox (\n job_id VARCHAR PRIMARY KEY,\n item_kind VARCHAR NOT NULL,\n item_id VARCHAR NOT NULL,\n embedding_version VARCHAR NOT NULL,\n status VARCHAR NOT NULL DEFAULT 'pending',\n retry_count INT DEFAULT 0,\n error VARCHAR,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n UNIQUE(item_kind, item_id, embedding_version)\n )\n `);\n\n // ============================================================\n // Build Runs & Metrics Tables\n // ============================================================\n\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS build_runs (\n build_id VARCHAR PRIMARY KEY,\n started_at TIMESTAMP NOT NULL,\n finished_at TIMESTAMP,\n extractor_model VARCHAR NOT NULL,\n extractor_prompt_hash VARCHAR NOT NULL,\n embedder_model VARCHAR NOT NULL,\n embedding_version VARCHAR NOT NULL,\n idris_version VARCHAR NOT NULL,\n schema_version VARCHAR NOT NULL,\n status VARCHAR NOT NULL DEFAULT 'running',\n error VARCHAR\n )\n `);\n\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS pipeline_metrics (\n id VARCHAR PRIMARY KEY,\n ts TIMESTAMP NOT NULL,\n stage VARCHAR NOT NULL,\n latency_ms DOUBLE NOT NULL,\n success BOOLEAN NOT NULL,\n error VARCHAR,\n session_id VARCHAR\n )\n `);\n\n // ============================================================\n // Endless Mode Tables\n // ============================================================\n\n // Working Set table (active memory window)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS working_set (\n id VARCHAR PRIMARY KEY,\n event_id VARCHAR NOT NULL,\n added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n relevance_score FLOAT DEFAULT 1.0,\n topics JSON,\n expires_at TIMESTAMP\n )\n `);\n\n // Consolidated Memories table (long-term integrated memories)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS consolidated_memories (\n memory_id VARCHAR PRIMARY KEY,\n summary TEXT NOT NULL,\n topics JSON,\n source_events JSON,\n confidence FLOAT DEFAULT 0.5,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n accessed_at TIMESTAMP,\n access_count INTEGER DEFAULT 0\n )\n `);\n\n // Continuity Log table (tracks context transitions)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS continuity_log (\n log_id VARCHAR PRIMARY KEY,\n from_context_id VARCHAR,\n to_context_id VARCHAR,\n continuity_score FLOAT,\n transition_type VARCHAR,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Consolidated Rules table (long-term stable memory)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS consolidated_rules (\n rule_id VARCHAR PRIMARY KEY,\n rule TEXT NOT NULL,\n topics JSON,\n source_memory_ids JSON,\n source_events JSON,\n confidence FLOAT DEFAULT 0.5,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Endless Mode Config table\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS endless_config (\n key VARCHAR PRIMARY KEY,\n value JSON,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // ============================================================\n // Create Indexes\n // ============================================================\n\n // Entry indexes\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entries_type ON entries(entry_type)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entries_stage ON entries(stage)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entries_canonical ON entries(canonical_key)`);\n\n // Entity indexes\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entities_type_key ON entities(entity_type, canonical_key)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entities_status ON entities(status)`);\n\n // Edge indexes\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_edges_src ON edges(src_id, rel_type)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_edges_dst ON edges(dst_id, rel_type)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_edges_rel ON edges(rel_type)`);\n\n // Outbox indexes\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_outbox_status ON vector_outbox(status)`);\n\n // Endless Mode indexes\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_working_set_expires ON working_set(expires_at)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_working_set_relevance ON working_set(relevance_score DESC)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_consolidated_confidence ON consolidated_memories(confidence DESC)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_consolidated_rules_confidence ON consolidated_rules(confidence DESC)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_continuity_created ON continuity_log(created_at)`);\n\n this.initialized = true;\n }\n\n /**\n * Append event to store (AXIOMMIND Principle 2: Append-only)\n * Returns existing event ID if duplicate (Principle 3: Idempotency)\n */\n async append(input: MemoryEventInput): Promise<AppendResult> {\n await this.initialize();\n\n const canonicalKey = makeCanonicalKey(input.content);\n const dedupeKey = makeDedupeKey(input.content, input.sessionId);\n\n // Check for duplicate\n const existing = await dbAll<{ event_id: string }>(\n this.db,\n `SELECT event_id FROM event_dedup WHERE dedupe_key = ?`,\n [dedupeKey]\n );\n\n if (existing.length > 0) {\n return {\n success: true,\n eventId: existing[0].event_id,\n isDuplicate: true\n };\n }\n\n const id = randomUUID();\n const timestamp = input.timestamp.toISOString();\n\n try {\n await dbRun(\n this.db,\n `INSERT INTO events (id, event_type, session_id, timestamp, content, canonical_key, dedupe_key, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n id,\n input.eventType,\n input.sessionId,\n timestamp,\n input.content,\n canonicalKey,\n dedupeKey,\n JSON.stringify(input.metadata || {})\n ]\n );\n\n await dbRun(\n this.db,\n `INSERT INTO event_dedup (dedupe_key, event_id) VALUES (?, ?)`,\n [dedupeKey, id]\n );\n\n // Initialize at L0\n await dbRun(\n this.db,\n `INSERT INTO memory_levels (event_id, level) VALUES (?, 'L0')`,\n [id]\n );\n\n return { success: true, eventId: id, isDuplicate: false };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n\n /**\n * Get events by session ID\n */\n async getSessionEvents(sessionId: string): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,\n [sessionId]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Get recent events\n */\n async getRecentEvents(limit: number = 100): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events ORDER BY timestamp DESC LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Get event by ID\n */\n async getEvent(id: string): Promise<MemoryEvent | null> {\n await this.initialize();\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE id = ?`,\n [id]\n );\n\n if (rows.length === 0) return null;\n return this.rowToEvent(rows[0]);\n }\n\n /**\n * Create or update session\n */\n async upsertSession(session: Partial<Session> & { id: string }): Promise<void> {\n await this.initialize();\n\n const existing = await dbAll<{ id: string }>(\n this.db,\n `SELECT id FROM sessions WHERE id = ?`,\n [session.id]\n );\n\n if (existing.length === 0) {\n await dbRun(\n this.db,\n `INSERT INTO sessions (id, started_at, project_path, tags)\n VALUES (?, ?, ?, ?)`,\n [\n session.id,\n (session.startedAt || new Date()).toISOString(),\n session.projectPath || null,\n JSON.stringify(session.tags || [])\n ]\n );\n } else {\n const updates: string[] = [];\n const values: unknown[] = [];\n\n if (session.endedAt) {\n updates.push('ended_at = ?');\n values.push(session.endedAt.toISOString());\n }\n if (session.summary) {\n updates.push('summary = ?');\n values.push(session.summary);\n }\n if (session.tags) {\n updates.push('tags = ?');\n values.push(JSON.stringify(session.tags));\n }\n\n if (updates.length > 0) {\n values.push(session.id);\n await dbRun(\n this.db,\n `UPDATE sessions SET ${updates.join(', ')} WHERE id = ?`,\n values\n );\n }\n }\n }\n\n /**\n * Get session by ID\n */\n async getSession(id: string): Promise<Session | null> {\n await this.initialize();\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM sessions WHERE id = ?`,\n [id]\n );\n\n if (rows.length === 0) return null;\n\n const row = rows[0];\n return {\n id: row.id as string,\n startedAt: toDate(row.started_at),\n endedAt: row.ended_at ? toDate(row.ended_at) : undefined,\n projectPath: row.project_path as string | undefined,\n summary: row.summary as string | undefined,\n tags: row.tags ? JSON.parse(row.tags as string) : undefined\n };\n }\n\n /**\n * Add to embedding outbox (Single-Writer Pattern)\n */\n async enqueueForEmbedding(eventId: string, content: string): Promise<string> {\n await this.initialize();\n\n const id = randomUUID();\n await dbRun(\n this.db,\n `INSERT INTO embedding_outbox (id, event_id, content, status, retry_count)\n VALUES (?, ?, ?, 'pending', 0)`,\n [id, eventId, content]\n );\n\n return id;\n }\n\n /**\n * Get pending outbox items\n */\n async getPendingOutboxItems(limit: number = 32): Promise<OutboxItem[]> {\n await this.initialize();\n\n // First, get pending items\n const pending = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM embedding_outbox\n WHERE status = 'pending'\n ORDER BY created_at\n LIMIT ?`,\n [limit]\n );\n\n if (pending.length === 0) return [];\n\n // Update status to processing\n const ids = pending.map(r => r.id as string);\n const placeholders = ids.map(() => '?').join(',');\n await dbRun(\n this.db,\n `UPDATE embedding_outbox SET status = 'processing' WHERE id IN (${placeholders})`,\n ids\n );\n\n return pending.map(row => ({\n id: row.id as string,\n eventId: row.event_id as string,\n content: row.content as string,\n status: 'processing' as const,\n retryCount: row.retry_count as number,\n createdAt: toDate(row.created_at),\n errorMessage: row.error_message as string | undefined\n }));\n }\n\n /**\n * Mark outbox items as done\n */\n async completeOutboxItems(ids: string[]): Promise<void> {\n if (ids.length === 0) return;\n\n const placeholders = ids.map(() => '?').join(',');\n await dbRun(\n this.db,\n `DELETE FROM embedding_outbox WHERE id IN (${placeholders})`,\n ids\n );\n }\n\n /**\n * Mark outbox items as failed\n */\n async failOutboxItems(ids: string[], error: string): Promise<void> {\n if (ids.length === 0) return;\n\n const placeholders = ids.map(() => '?').join(',');\n await dbRun(\n this.db,\n `UPDATE embedding_outbox\n SET status = CASE WHEN retry_count >= 3 THEN 'failed' ELSE 'pending' END,\n retry_count = retry_count + 1,\n error_message = ?\n WHERE id IN (${placeholders})`,\n [error, ...ids]\n );\n }\n\n /**\n * Update memory level\n */\n async updateMemoryLevel(eventId: string, level: string): Promise<void> {\n await this.initialize();\n\n await dbRun(\n this.db,\n `UPDATE memory_levels SET level = ?, promoted_at = CURRENT_TIMESTAMP WHERE event_id = ?`,\n [level, eventId]\n );\n }\n\n /**\n * Get memory level statistics\n */\n async getLevelStats(): Promise<Array<{ level: string; count: number }>> {\n await this.initialize();\n\n const rows = await dbAll<{ level: string; count: number }>(\n this.db,\n `SELECT level, COUNT(*) as count FROM memory_levels GROUP BY level`\n );\n\n return rows;\n }\n\n /**\n * Get events by memory level\n */\n async getEventsByLevel(level: string, options?: { limit?: number; offset?: number }): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const limit = options?.limit || 50;\n const offset = options?.offset || 0;\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT e.* FROM events e\n INNER JOIN memory_levels ml ON e.id = ml.event_id\n WHERE ml.level = ?\n ORDER BY e.timestamp DESC\n LIMIT ? OFFSET ?`,\n [level, limit, offset]\n );\n\n return rows.map(row => this.rowToEvent(row));\n }\n\n /**\n * Get memory level for a specific event\n */\n async getEventLevel(eventId: string): Promise<string | null> {\n await this.initialize();\n\n const rows = await dbAll<{ level: string }>(\n this.db,\n `SELECT level FROM memory_levels WHERE event_id = ?`,\n [eventId]\n );\n\n return rows.length > 0 ? rows[0].level : null;\n }\n\n // ============================================================\n // Endless Mode Helper Methods\n // ============================================================\n\n /**\n * Get database instance for Endless Mode stores\n */\n getDatabase(): Database {\n return this.db;\n }\n\n /**\n * Get config value for endless mode\n */\n async getEndlessConfig(key: string): Promise<unknown | null> {\n await this.initialize();\n\n const rows = await dbAll<{ value: string }>(\n this.db,\n `SELECT value FROM endless_config WHERE key = ?`,\n [key]\n );\n\n if (rows.length === 0) return null;\n return JSON.parse(rows[0].value);\n }\n\n /**\n * Set config value for endless mode\n */\n async setEndlessConfig(key: string, value: unknown): Promise<void> {\n await this.initialize();\n\n await dbRun(\n this.db,\n `INSERT OR REPLACE INTO endless_config (key, value, updated_at)\n VALUES (?, ?, CURRENT_TIMESTAMP)`,\n [key, JSON.stringify(value)]\n );\n }\n\n /**\n * Get all sessions\n */\n async getAllSessions(): Promise<Session[]> {\n await this.initialize();\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM sessions ORDER BY started_at DESC`\n );\n\n return rows.map(row => ({\n id: row.id as string,\n startedAt: toDate(row.started_at),\n endedAt: row.ended_at ? toDate(row.ended_at) : undefined,\n projectPath: row.project_path as string | undefined,\n summary: row.summary as string | undefined,\n tags: row.tags ? JSON.parse(row.tags as string) : undefined\n }));\n }\n\n /**\n * Increment access count for events (stub for compatibility)\n */\n async incrementAccessCount(eventIds: string[]): Promise<void> {\n // This is a stub method for compatibility\n // Actual implementation is in SQLiteEventStore\n return Promise.resolve();\n }\n\n /**\n * Get most accessed memories (stub for compatibility)\n */\n async getMostAccessed(limit: number = 10): Promise<MemoryEvent[]> {\n // This is a stub method for compatibility\n // Actual implementation is in SQLiteEventStore\n return [];\n }\n\n /**\n * Close database connection\n */\n async close(): Promise<void> {\n await dbClose(this.db);\n }\n\n /**\n * Convert database row to MemoryEvent\n */\n private rowToEvent(row: Record<string, unknown>): MemoryEvent {\n return {\n id: row.id as string,\n eventType: row.event_type as 'user_prompt' | 'agent_response' | 'session_summary',\n sessionId: row.session_id as string,\n timestamp: toDate(row.timestamp),\n content: row.content as string,\n canonicalKey: row.canonical_key as string,\n dedupeKey: row.dedupe_key as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined\n };\n }\n}\n", "/**\n * AXIOMMIND canonical_key.py port\n * Deterministic normalization ensuring identical titles always map to same keys\n */\n\nimport { createHash } from 'crypto';\n\nconst MAX_KEY_LENGTH = 200;\n\n/**\n * Convert text to a normalized canonical key\n *\n * Normalization steps:\n * 1. NFKC unicode normalization\n * 2. Lowercase conversion\n * 3. Punctuation removal\n * 4. Consecutive whitespace cleanup\n * 5. Context addition (optional)\n * 6. Long key truncation with MD5\n */\nexport function makeCanonicalKey(\n title: string,\n context?: { project?: string; sessionId?: string }\n): string {\n // Step 1: NFKC normalization\n let normalized = title.normalize('NFKC');\n\n // Step 2: Lowercase conversion\n normalized = normalized.toLowerCase();\n\n // Step 3: Punctuation removal (unicode compatible)\n normalized = normalized.replace(/[^\\p{L}\\p{N}\\s]/gu, '');\n\n // Step 4: Consecutive whitespace cleanup\n normalized = normalized.replace(/\\s+/g, ' ').trim();\n\n // Step 5: Context addition\n let key = normalized;\n if (context?.project) {\n key = `${context.project}::${key}`;\n }\n\n // Step 6: Long key handling\n if (key.length > MAX_KEY_LENGTH) {\n const hashSuffix = createHash('md5').update(key).digest('hex').slice(0, 8);\n key = key.slice(0, MAX_KEY_LENGTH - 9) + '_' + hashSuffix;\n }\n\n return key;\n}\n\n/**\n * Check if two texts have the same canonical key\n */\nexport function isSameCanonicalKey(a: string, b: string): boolean {\n return makeCanonicalKey(a) === makeCanonicalKey(b);\n}\n\n/**\n * Generate dedupe key (content + session for uniqueness)\n * AXIOMMIND Principle 3: Idempotency guarantee\n */\nexport function makeDedupeKey(content: string, sessionId: string): string {\n const contentHash = createHash('sha256').update(content).digest('hex');\n return `${sessionId}:${contentHash}`;\n}\n\n/**\n * Generate content hash for deduplication\n */\nexport function hashContent(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\n// ============================================================\n// Entity Canonical Keys (Task Entity System)\n// ============================================================\n\nexport type EntityKeyType = 'task' | 'condition' | 'artifact';\n\n/**\n * Normalize text for entity key generation\n */\nfunction normalizeForKey(text: string): string {\n return text\n .normalize('NFKC')\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s]/gu, '')\n .replace(/\\s+/g, '_')\n .trim();\n}\n\n/**\n * Generate canonical key for entities\n * Format: {type}:{project}:{normalized_identifier}\n */\nexport function makeEntityCanonicalKey(\n entityType: EntityKeyType,\n identifier: string,\n context?: { project?: string }\n): string {\n const project = context?.project ?? 'default';\n\n switch (entityType) {\n case 'task':\n return `task:${project}:${normalizeForKey(identifier)}`;\n case 'condition':\n return `cond:${project}:${normalizeForKey(identifier)}`;\n case 'artifact':\n return makeArtifactKey(identifier);\n }\n}\n\n/**\n * Generate canonical key for artifacts based on identifier pattern\n * - URL: art:url:{sha1(url)}\n * - JIRA key: art:jira:{key}\n * - GitHub issue: art:gh_issue:{repo}:{num}\n * - Generic: art:generic:{sha1(identifier)}\n */\nexport function makeArtifactKey(identifier: string): string {\n // URL pattern\n if (/^https?:\\/\\//.test(identifier)) {\n const hash = createHash('sha1').update(identifier).digest('hex').slice(0, 12);\n return `art:url:${hash}`;\n }\n\n // JIRA key pattern (e.g., PROJ-123)\n const jiraMatch = identifier.match(/^([A-Z]+-\\d+)$/);\n if (jiraMatch) {\n return `art:jira:${jiraMatch[1].toLowerCase()}`;\n }\n\n // GitHub issue pattern (e.g., owner/repo#123)\n const ghMatch = identifier.match(/^([^\\/]+\\/[^#]+)#(\\d+)$/);\n if (ghMatch) {\n return `art:gh_issue:${ghMatch[1]}:${ghMatch[2]}`;\n }\n\n // Generic identifier\n const hash = createHash('sha1').update(identifier).digest('hex').slice(0, 12);\n return `art:generic:${hash}`;\n}\n\n/**\n * Generate dedupe key for task events\n */\nexport function makeTaskEventDedupeKey(\n eventType: string,\n taskId: string,\n sessionId: string,\n additionalContext?: string\n): string {\n const parts = [eventType, taskId, sessionId];\n if (additionalContext) {\n parts.push(additionalContext);\n }\n const combined = parts.join(':');\n return createHash('sha256').update(combined).digest('hex');\n}\n\n/**\n * Parse entity canonical key to extract type and identifier\n */\nexport function parseEntityCanonicalKey(canonicalKey: string): {\n entityType: EntityKeyType;\n project?: string;\n identifier: string;\n} | null {\n const taskMatch = canonicalKey.match(/^task:([^:]+):(.+)$/);\n if (taskMatch) {\n return { entityType: 'task', project: taskMatch[1], identifier: taskMatch[2] };\n }\n\n const condMatch = canonicalKey.match(/^cond:([^:]+):(.+)$/);\n if (condMatch) {\n return { entityType: 'condition', project: condMatch[1], identifier: condMatch[2] };\n }\n\n const artMatch = canonicalKey.match(/^art:([^:]+):(.+)$/);\n if (artMatch) {\n return { entityType: 'artifact', identifier: artMatch[2] };\n }\n\n return null;\n}\n", "/**\n * DuckDB Promise Wrapper\n * Wraps the callback-based DuckDB API with Promise-based async/await interface\n */\n\nimport duckdb from 'duckdb';\n\nexport type Database = duckdb.Database;\n\n/**\n * Converts BigInt values to Number in an object\n * DuckDB returns BigInt for COUNT(*) and other aggregate functions\n */\nfunction convertBigInts<T>(obj: T): T {\n if (obj === null || obj === undefined) return obj;\n if (typeof obj === 'bigint') return Number(obj) as unknown as T;\n if (obj instanceof Date) return obj; // Preserve Date objects\n if (Array.isArray(obj)) return obj.map(convertBigInts) as unknown as T;\n if (typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n result[key] = convertBigInts(value);\n }\n return result as T;\n }\n return obj;\n}\n\n/**\n * Safely converts a value to a Date object\n * Handles both Date objects and string timestamps from DuckDB\n */\nexport function toDate(value: unknown): Date {\n if (value instanceof Date) return value;\n if (typeof value === 'string') return new Date(value);\n if (typeof value === 'number') return new Date(value);\n return new Date(String(value));\n}\n\nexport interface DatabaseOptions {\n readOnly?: boolean;\n}\n\n/**\n * Creates a new DuckDB database with Promise-based API\n */\nexport function createDatabase(path: string, options?: DatabaseOptions): Database {\n if (options?.readOnly) {\n return new duckdb.Database(path, { access_mode: 'READ_ONLY' });\n }\n return new duckdb.Database(path);\n}\n\n/**\n * Promisified db.run() - executes a statement that doesn't return rows\n */\nexport function dbRun(db: Database, sql: string, params: unknown[] = []): Promise<void> {\n return new Promise((resolve, reject) => {\n if (params.length === 0) {\n db.run(sql, (err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n } else {\n db.run(sql, ...params, (err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n }\n });\n}\n\n/**\n * Promisified db.all() - executes a query and returns all rows\n * Automatically converts BigInt values to Number\n */\nexport function dbAll<T = Record<string, unknown>>(\n db: Database,\n sql: string,\n params: unknown[] = []\n): Promise<T[]> {\n return new Promise((resolve, reject) => {\n if (params.length === 0) {\n db.all(sql, (err: Error | null, rows: T[]) => {\n if (err) reject(err);\n else resolve(convertBigInts(rows || []));\n });\n } else {\n db.all(sql, ...params, (err: Error | null, rows: T[]) => {\n if (err) reject(err);\n else resolve(convertBigInts(rows || []));\n });\n }\n });\n}\n\n/**\n * Promisified db.close() - closes the database connection\n */\nexport function dbClose(db: Database): Promise<void> {\n return new Promise((resolve, reject) => {\n db.close((err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n });\n}\n\n/**\n * Promisified db.exec() - executes multiple statements\n */\nexport function dbExec(db: Database, sql: string): Promise<void> {\n return new Promise((resolve, reject) => {\n db.exec(sql, (err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n });\n}\n", "/**\n * SQLite-based EventStore implementation\n * Primary store for hooks - WAL mode enables concurrent access\n */\n\nimport { randomUUID } from 'crypto';\nimport {\n MemoryEvent,\n MemoryEventInput,\n Session,\n AppendResult,\n OutboxItem\n} from './types.js';\nimport { makeCanonicalKey, makeDedupeKey } from './canonical-key.js';\nimport {\n createSQLiteDatabase,\n sqliteRun,\n sqliteAll,\n sqliteGet,\n sqliteClose,\n sqliteExec,\n toDateFromSQLite,\n toSQLiteTimestamp,\n type SQLiteDatabase,\n type SQLiteOptions\n} from './sqlite-wrapper.js';\nimport { MarkdownMirror } from './markdown-mirror.js';\n\nexport interface SQLiteEventStoreOptions extends SQLiteOptions {\n markdownMirrorRoot?: string;\n}\n\nexport class SQLiteEventStore {\n private db: SQLiteDatabase;\n private initialized = false;\n private readonly readOnly: boolean;\n private readonly markdownMirror: MarkdownMirror | null;\n\n constructor(private dbPath: string, options?: SQLiteEventStoreOptions) {\n this.readOnly = options?.readonly ?? false;\n this.db = createSQLiteDatabase(dbPath, {\n readonly: this.readOnly,\n walMode: !this.readOnly\n });\n this.markdownMirror = this.readOnly || !options?.markdownMirrorRoot\n ? null\n : new MarkdownMirror(options.markdownMirrorRoot);\n }\n\n /**\n * Initialize database schema\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // In read-only mode, skip schema creation\n if (this.readOnly) {\n this.initialized = true;\n return;\n }\n\n // Create all tables in a single exec for efficiency\n sqliteExec(this.db, `\n -- L0 EventStore: Single Source of Truth (immutable, append-only)\n CREATE TABLE IF NOT EXISTS events (\n id TEXT PRIMARY KEY,\n event_type TEXT NOT NULL,\n session_id TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n content TEXT NOT NULL,\n canonical_key TEXT NOT NULL,\n dedupe_key TEXT UNIQUE,\n metadata TEXT,\n access_count INTEGER DEFAULT 0,\n last_accessed_at TEXT\n );\n\n -- Dedup table for idempotency\n CREATE TABLE IF NOT EXISTS event_dedup (\n dedupe_key TEXT PRIMARY KEY,\n event_id TEXT NOT NULL,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Session metadata\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n started_at TEXT NOT NULL,\n ended_at TEXT,\n project_path TEXT,\n summary TEXT,\n tags TEXT\n );\n\n -- Insights (derived data, rebuildable)\n CREATE TABLE IF NOT EXISTS insights (\n id TEXT PRIMARY KEY,\n insight_type TEXT NOT NULL,\n content TEXT NOT NULL,\n canonical_key TEXT NOT NULL,\n confidence REAL,\n source_events TEXT,\n created_at TEXT,\n last_updated TEXT\n );\n\n -- Embedding Outbox (Single-Writer Pattern)\n CREATE TABLE IF NOT EXISTS embedding_outbox (\n id TEXT PRIMARY KEY,\n event_id TEXT NOT NULL,\n content TEXT NOT NULL,\n status TEXT DEFAULT 'pending',\n retry_count INTEGER DEFAULT 0,\n created_at TEXT DEFAULT (datetime('now')),\n processed_at TEXT,\n error_message TEXT\n );\n\n -- Projection offset tracking\n CREATE TABLE IF NOT EXISTS projection_offsets (\n projection_name TEXT PRIMARY KEY,\n last_event_id TEXT,\n last_timestamp TEXT,\n updated_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Memory level tracking\n CREATE TABLE IF NOT EXISTS memory_levels (\n event_id TEXT PRIMARY KEY,\n level TEXT NOT NULL DEFAULT 'L0',\n promoted_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Entries (immutable memory units)\n CREATE TABLE IF NOT EXISTS entries (\n entry_id TEXT PRIMARY KEY,\n created_ts TEXT NOT NULL,\n entry_type TEXT NOT NULL,\n title TEXT NOT NULL,\n content_json TEXT NOT NULL,\n stage TEXT NOT NULL DEFAULT 'raw',\n status TEXT DEFAULT 'active',\n superseded_by TEXT,\n build_id TEXT,\n evidence_json TEXT,\n canonical_key TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Entities (task/condition/artifact)\n CREATE TABLE IF NOT EXISTS entities (\n entity_id TEXT PRIMARY KEY,\n entity_type TEXT NOT NULL,\n canonical_key TEXT NOT NULL,\n title TEXT NOT NULL,\n stage TEXT NOT NULL DEFAULT 'raw',\n status TEXT NOT NULL DEFAULT 'active',\n current_json TEXT NOT NULL,\n title_norm TEXT,\n search_text TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Entity aliases for canonical key lookup\n CREATE TABLE IF NOT EXISTS entity_aliases (\n entity_type TEXT NOT NULL,\n canonical_key TEXT NOT NULL,\n entity_id TEXT NOT NULL,\n is_primary INTEGER DEFAULT 0,\n created_at TEXT DEFAULT (datetime('now')),\n PRIMARY KEY(entity_type, canonical_key)\n );\n\n -- Edges (relationships between entries/entities)\n CREATE TABLE IF NOT EXISTS edges (\n edge_id TEXT PRIMARY KEY,\n src_type TEXT NOT NULL,\n src_id TEXT NOT NULL,\n rel_type TEXT NOT NULL,\n dst_type TEXT NOT NULL,\n dst_id TEXT NOT NULL,\n meta_json TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Vector Outbox V2 Table\n CREATE TABLE IF NOT EXISTS vector_outbox (\n job_id TEXT PRIMARY KEY,\n item_kind TEXT NOT NULL,\n item_id TEXT NOT NULL,\n embedding_version TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n retry_count INTEGER DEFAULT 0,\n error TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now')),\n UNIQUE(item_kind, item_id, embedding_version)\n );\n\n -- Build Runs\n CREATE TABLE IF NOT EXISTS build_runs (\n build_id TEXT PRIMARY KEY,\n started_at TEXT NOT NULL,\n finished_at TEXT,\n extractor_model TEXT NOT NULL,\n extractor_prompt_hash TEXT NOT NULL,\n embedder_model TEXT NOT NULL,\n embedding_version TEXT NOT NULL,\n idris_version TEXT NOT NULL,\n schema_version TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'running',\n error TEXT\n );\n\n -- Pipeline Metrics\n CREATE TABLE IF NOT EXISTS pipeline_metrics (\n id TEXT PRIMARY KEY,\n ts TEXT NOT NULL,\n stage TEXT NOT NULL,\n latency_ms REAL NOT NULL,\n success INTEGER NOT NULL,\n error TEXT,\n session_id TEXT\n );\n\n -- Working Set table (active memory window)\n CREATE TABLE IF NOT EXISTS working_set (\n id TEXT PRIMARY KEY,\n event_id TEXT NOT NULL,\n added_at TEXT DEFAULT (datetime('now')),\n relevance_score REAL DEFAULT 1.0,\n topics TEXT,\n expires_at TEXT\n );\n\n -- Consolidated Memories table (long-term integrated memories)\n CREATE TABLE IF NOT EXISTS consolidated_memories (\n memory_id TEXT PRIMARY KEY,\n summary TEXT NOT NULL,\n topics TEXT,\n source_events TEXT,\n confidence REAL DEFAULT 0.5,\n created_at TEXT DEFAULT (datetime('now')),\n accessed_at TEXT,\n access_count INTEGER DEFAULT 0\n );\n\n -- Continuity Log table (tracks context transitions)\n CREATE TABLE IF NOT EXISTS continuity_log (\n log_id TEXT PRIMARY KEY,\n from_context_id TEXT,\n to_context_id TEXT,\n continuity_score REAL,\n transition_type TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Consolidated Rules table (long-term stable memory)\n CREATE TABLE IF NOT EXISTS consolidated_rules (\n rule_id TEXT PRIMARY KEY,\n rule TEXT NOT NULL,\n topics TEXT,\n source_memory_ids TEXT,\n source_events TEXT,\n confidence REAL DEFAULT 0.5,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Endless Mode Config table\n CREATE TABLE IF NOT EXISTS endless_config (\n key TEXT PRIMARY KEY,\n value TEXT,\n updated_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Memory Helpfulness tracking\n CREATE TABLE IF NOT EXISTS memory_helpfulness (\n id TEXT PRIMARY KEY,\n event_id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n retrieval_score REAL DEFAULT 0,\n query_preview TEXT,\n session_continued INTEGER DEFAULT 0,\n prompt_count_after INTEGER DEFAULT 0,\n tool_success_count INTEGER DEFAULT 0,\n tool_total_count INTEGER DEFAULT 0,\n was_reasked INTEGER DEFAULT 0,\n helpfulness_score REAL DEFAULT 0.5,\n created_at TEXT DEFAULT (datetime('now')),\n measured_at TEXT\n );\n\n -- Retrieval trace log (query -> candidates -> selected for context)\n CREATE TABLE IF NOT EXISTS retrieval_traces (\n trace_id TEXT PRIMARY KEY,\n session_id TEXT,\n project_hash TEXT,\n query_text TEXT NOT NULL,\n strategy TEXT,\n candidate_event_ids TEXT,\n selected_event_ids TEXT,\n candidate_details_json TEXT,\n selected_details_json TEXT,\n candidate_count INTEGER DEFAULT 0,\n selected_count INTEGER DEFAULT 0,\n confidence TEXT,\n fallback_trace TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Sync position tracking (for SQLite -> DuckDB sync)\n CREATE TABLE IF NOT EXISTS sync_positions (\n target_name TEXT PRIMARY KEY,\n last_event_id TEXT,\n last_timestamp TEXT,\n updated_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Create indexes\n CREATE INDEX IF NOT EXISTS idx_events_session ON events(session_id);\n CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);\n CREATE INDEX IF NOT EXISTS idx_entries_type ON entries(entry_type);\n CREATE INDEX IF NOT EXISTS idx_entries_stage ON entries(stage);\n CREATE INDEX IF NOT EXISTS idx_entries_canonical ON entries(canonical_key);\n CREATE INDEX IF NOT EXISTS idx_entities_type_key ON entities(entity_type, canonical_key);\n CREATE INDEX IF NOT EXISTS idx_entities_status ON entities(status);\n CREATE INDEX IF NOT EXISTS idx_edges_src ON edges(src_id, rel_type);\n CREATE INDEX IF NOT EXISTS idx_edges_dst ON edges(dst_id, rel_type);\n CREATE INDEX IF NOT EXISTS idx_edges_rel ON edges(rel_type);\n CREATE INDEX IF NOT EXISTS idx_outbox_status ON vector_outbox(status);\n CREATE INDEX IF NOT EXISTS idx_working_set_expires ON working_set(expires_at);\n CREATE INDEX IF NOT EXISTS idx_working_set_relevance ON working_set(relevance_score);\n CREATE INDEX IF NOT EXISTS idx_consolidated_confidence ON consolidated_memories(confidence);\n CREATE INDEX IF NOT EXISTS idx_continuity_created ON continuity_log(created_at);\n CREATE INDEX IF NOT EXISTS idx_consolidated_rules_confidence ON consolidated_rules(confidence);\n CREATE INDEX IF NOT EXISTS idx_embedding_outbox_status ON embedding_outbox(status);\n CREATE INDEX IF NOT EXISTS idx_helpfulness_event ON memory_helpfulness(event_id);\n CREATE INDEX IF NOT EXISTS idx_helpfulness_session ON memory_helpfulness(session_id);\n CREATE INDEX IF NOT EXISTS idx_helpfulness_score ON memory_helpfulness(helpfulness_score DESC);\n CREATE INDEX IF NOT EXISTS idx_retrieval_traces_created_at ON retrieval_traces(created_at DESC);\n CREATE INDEX IF NOT EXISTS idx_retrieval_traces_project_hash ON retrieval_traces(project_hash);\n CREATE INDEX IF NOT EXISTS idx_retrieval_traces_session_id ON retrieval_traces(session_id);\n\n -- FTS5 Full-Text Search for fast keyword search\n CREATE VIRTUAL TABLE IF NOT EXISTS events_fts USING fts5(\n content,\n event_id UNINDEXED,\n content='events',\n content_rowid='rowid'\n );\n\n -- Triggers to keep FTS in sync with events table\n CREATE TRIGGER IF NOT EXISTS events_fts_insert AFTER INSERT ON events BEGIN\n INSERT INTO events_fts(rowid, content, event_id) VALUES (NEW.rowid, NEW.content, NEW.id);\n END;\n\n CREATE TRIGGER IF NOT EXISTS events_fts_delete AFTER DELETE ON events BEGIN\n INSERT INTO events_fts(events_fts, rowid, content, event_id) VALUES('delete', OLD.rowid, OLD.content, OLD.id);\n END;\n\n CREATE TRIGGER IF NOT EXISTS events_fts_update AFTER UPDATE ON events BEGIN\n INSERT INTO events_fts(events_fts, rowid, content, event_id) VALUES('delete', OLD.rowid, OLD.content, OLD.id);\n INSERT INTO events_fts(rowid, content, event_id) VALUES (NEW.rowid, NEW.content, NEW.id);\n END;\n `);\n\n\n // Best-effort forward migration for retrieval trace detail column\n try {\n sqliteExec(this.db, `ALTER TABLE retrieval_traces ADD COLUMN selected_details_json TEXT;`);\n } catch {\n // column may already exist\n }\n try {\n sqliteExec(this.db, `ALTER TABLE retrieval_traces ADD COLUMN candidate_details_json TEXT;`);\n } catch {\n // column may already exist\n }\n\n // Migrate existing events table to add new columns if they don't exist\n // Check if columns exist before trying to add them\n const tableInfo = sqliteAll(this.db, \"PRAGMA table_info(events)\", []);\n const columnNames = tableInfo.map((col: any) => col.name);\n\n if (!columnNames.includes('access_count')) {\n try {\n sqliteExec(this.db, `\n ALTER TABLE events ADD COLUMN access_count INTEGER DEFAULT 0;\n `);\n } catch (err: any) {\n console.error('Error adding access_count column:', err);\n }\n }\n\n if (!columnNames.includes('last_accessed_at')) {\n try {\n sqliteExec(this.db, `\n ALTER TABLE events ADD COLUMN last_accessed_at TEXT;\n `);\n } catch (err: any) {\n console.error('Error adding last_accessed_at column:', err);\n }\n }\n\n // Add turn_id column for grouping events within a conversation turn\n if (!columnNames.includes('turn_id')) {\n try {\n sqliteExec(this.db, `\n ALTER TABLE events ADD COLUMN turn_id TEXT;\n `);\n } catch (err: any) {\n console.error('Error adding turn_id column:', err);\n }\n }\n\n // Create indexes for new columns if they don't exist\n try {\n sqliteExec(this.db, `\n CREATE INDEX IF NOT EXISTS idx_events_access_count ON events(access_count DESC);\n `);\n } catch (err: any) {\n // Index may already exist, ignore\n }\n\n try {\n sqliteExec(this.db, `\n CREATE INDEX IF NOT EXISTS idx_events_last_accessed ON events(last_accessed_at DESC);\n `);\n } catch (err: any) {\n // Index may already exist, ignore\n }\n\n try {\n sqliteExec(this.db, `\n CREATE INDEX IF NOT EXISTS idx_events_turn_id ON events(turn_id);\n `);\n } catch (err: any) {\n // Index may already exist, ignore\n }\n\n this.initialized = true;\n }\n\n /**\n * Append event to store (Append-only, Idempotent)\n */\n async append(input: MemoryEventInput): Promise<AppendResult> {\n await this.initialize();\n\n const canonicalKey = makeCanonicalKey(input.content);\n const dedupeKey = makeDedupeKey(input.content, input.sessionId);\n\n // Check for duplicate\n const existing = sqliteGet<{ event_id: string }>(\n this.db,\n `SELECT event_id FROM event_dedup WHERE dedupe_key = ?`,\n [dedupeKey]\n );\n\n if (existing) {\n return {\n success: true,\n eventId: existing.event_id,\n isDuplicate: true\n };\n }\n\n const id = randomUUID();\n const timestamp = toSQLiteTimestamp(input.timestamp);\n\n try {\n // Extract turnId from metadata if present\n const metadata = input.metadata || {};\n const turnId = (metadata.turnId as string) || null;\n\n // Use transaction for atomicity\n const insertEvent = this.db.prepare(`\n INSERT INTO events (id, event_type, session_id, timestamp, content, canonical_key, dedupe_key, metadata, turn_id)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const insertDedup = this.db.prepare(`\n INSERT INTO event_dedup (dedupe_key, event_id) VALUES (?, ?)\n `);\n\n const insertLevel = this.db.prepare(`\n INSERT INTO memory_levels (event_id, level) VALUES (?, 'L0')\n `);\n\n const transaction = this.db.transaction(() => {\n insertEvent.run(\n id,\n input.eventType,\n input.sessionId,\n timestamp,\n input.content,\n canonicalKey,\n dedupeKey,\n JSON.stringify(metadata),\n turnId\n );\n insertDedup.run(dedupeKey, id);\n insertLevel.run(id);\n });\n\n transaction();\n\n if (this.markdownMirror) {\n const event: MemoryEvent = {\n id,\n eventType: input.eventType,\n sessionId: input.sessionId,\n timestamp: input.timestamp,\n content: input.content,\n canonicalKey,\n dedupeKey,\n metadata\n };\n this.markdownMirror.append(event).catch((err) => {\n console.warn('[SQLiteEventStore] markdown mirror append failed:', err);\n });\n }\n\n return { success: true, eventId: id, isDuplicate: false };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n\n /**\n * Get events by session ID\n */\n async getSessionEvents(sessionId: string): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,\n [sessionId]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Get recent events\n */\n async getRecentEvents(limit: number = 100): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events ORDER BY timestamp DESC LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Get event by ID\n */\n async getEvent(id: string): Promise<MemoryEvent | null> {\n await this.initialize();\n\n const row = sqliteGet<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE id = ?`,\n [id]\n );\n\n if (!row) return null;\n return this.rowToEvent(row);\n }\n\n /**\n * Get events since a timestamp (for sync)\n */\n async getEventsSince(timestamp: string, limit: number = 1000): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE timestamp > ? ORDER BY timestamp ASC LIMIT ?`,\n [timestamp, limit]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Get events since a SQLite rowid (for robust incremental replication).\n * Rowid is monotonic for append-only tables, independent of client timestamps.\n */\n async getEventsSinceRowid(\n lastRowid: number,\n limit: number = 1000\n ): Promise<Array<{ rowid: number; event: MemoryEvent }>> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT rowid as _rowid, * FROM events WHERE rowid > ? ORDER BY rowid ASC LIMIT ?`,\n [lastRowid, limit]\n );\n\n return rows.map(row => ({\n rowid: row._rowid as number,\n event: this.rowToEvent(row)\n }));\n }\n\n /**\n * Import events with fixed IDs (used for cross-machine replication).\n * Idempotent: skips if event id or dedupeKey already exists.\n *\n * NOTE: This bypasses the append() id generation to preserve stable IDs.\n */\n async importEvents(events: MemoryEvent[]): Promise<{ inserted: number; skipped: number }> {\n if (events.length === 0) return { inserted: 0, skipped: 0 };\n if (this.readOnly) return { inserted: 0, skipped: events.length };\n\n await this.initialize();\n\n const getById = this.db.prepare(`SELECT id FROM events WHERE id = ?`);\n const getByDedupe = this.db.prepare(`SELECT event_id FROM event_dedup WHERE dedupe_key = ?`);\n\n const insertEvent = this.db.prepare(`\n INSERT INTO events (id, event_type, session_id, timestamp, content, canonical_key, dedupe_key, metadata, turn_id)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const insertDedup = this.db.prepare(`\n INSERT INTO event_dedup (dedupe_key, event_id) VALUES (?, ?)\n `);\n\n const insertLevel = this.db.prepare(`\n INSERT INTO memory_levels (event_id, level) VALUES (?, 'L0')\n `);\n\n let inserted = 0;\n let skipped = 0;\n const insertedEvents: MemoryEvent[] = [];\n\n const tx = this.db.transaction((batch: MemoryEvent[]) => {\n for (const ev of batch) {\n // Skip if already present by id\n const existingById = getById.get(ev.id) as { id: string } | undefined;\n if (existingById) {\n skipped++;\n continue;\n }\n\n const canonicalKey = ev.canonicalKey || makeCanonicalKey(ev.content);\n const dedupeKey = ev.dedupeKey || makeDedupeKey(ev.content, ev.sessionId);\n\n // Skip if already present by dedupe key\n const existingByDedupe = getByDedupe.get(dedupeKey) as { event_id: string } | undefined;\n if (existingByDedupe) {\n skipped++;\n continue;\n }\n\n const metadata = ev.metadata || {};\n const turnId = (metadata as any).turnId as string | undefined;\n\n insertEvent.run(\n ev.id,\n ev.eventType,\n ev.sessionId,\n toSQLiteTimestamp(ev.timestamp),\n ev.content,\n canonicalKey,\n dedupeKey,\n JSON.stringify(metadata),\n turnId ?? null\n );\n\n insertDedup.run(dedupeKey, ev.id);\n insertLevel.run(ev.id);\n inserted++;\n insertedEvents.push(ev);\n }\n });\n\n tx(events);\n\n if (this.markdownMirror && insertedEvents.length > 0) {\n for (const ev of insertedEvents) {\n this.markdownMirror.append(ev).catch((err) => {\n console.warn('[SQLiteEventStore] markdown mirror append failed:', err);\n });\n }\n }\n\n return { inserted, skipped };\n }\n\n /**\n * Create or update session\n */\n async upsertSession(session: Partial<Session> & { id: string }): Promise<void> {\n await this.initialize();\n\n const existing = sqliteGet<{ id: string }>(\n this.db,\n `SELECT id FROM sessions WHERE id = ?`,\n [session.id]\n );\n\n if (!existing) {\n sqliteRun(\n this.db,\n `INSERT INTO sessions (id, started_at, project_path, tags)\n VALUES (?, ?, ?, ?)`,\n [\n session.id,\n toSQLiteTimestamp(session.startedAt || new Date()),\n session.projectPath || null,\n JSON.stringify(session.tags || [])\n ]\n );\n } else {\n const updates: string[] = [];\n const values: unknown[] = [];\n\n if (session.endedAt) {\n updates.push('ended_at = ?');\n values.push(toSQLiteTimestamp(session.endedAt));\n }\n if (session.summary) {\n updates.push('summary = ?');\n values.push(session.summary);\n }\n if (session.tags) {\n updates.push('tags = ?');\n values.push(JSON.stringify(session.tags));\n }\n\n if (updates.length > 0) {\n values.push(session.id);\n sqliteRun(\n this.db,\n `UPDATE sessions SET ${updates.join(', ')} WHERE id = ?`,\n values\n );\n }\n }\n }\n\n /**\n * Get session by ID\n */\n async getSession(id: string): Promise<Session | null> {\n await this.initialize();\n\n const row = sqliteGet<Record<string, unknown>>(\n this.db,\n `SELECT * FROM sessions WHERE id = ?`,\n [id]\n );\n\n if (!row) return null;\n\n return {\n id: row.id as string,\n startedAt: toDateFromSQLite(row.started_at),\n endedAt: row.ended_at ? toDateFromSQLite(row.ended_at) : undefined,\n projectPath: row.project_path as string | undefined,\n summary: row.summary as string | undefined,\n tags: row.tags ? JSON.parse(row.tags as string) : undefined\n };\n }\n\n /**\n * Get all sessions\n */\n async getAllSessions(): Promise<Session[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM sessions ORDER BY started_at DESC`\n );\n\n return rows.map(row => ({\n id: row.id as string,\n startedAt: toDateFromSQLite(row.started_at),\n endedAt: row.ended_at ? toDateFromSQLite(row.ended_at) : undefined,\n projectPath: row.project_path as string | undefined,\n summary: row.summary as string | undefined,\n tags: row.tags ? JSON.parse(row.tags as string) : undefined\n }));\n }\n\n /**\n * Add to embedding outbox\n */\n async enqueueForEmbedding(eventId: string, content: string): Promise<string> {\n await this.initialize();\n\n const id = randomUUID();\n sqliteRun(\n this.db,\n `INSERT INTO embedding_outbox (id, event_id, content, status, retry_count)\n VALUES (?, ?, ?, 'pending', 0)`,\n [id, eventId, content]\n );\n\n return id;\n }\n\n /**\n * Get pending outbox items\n */\n async getPendingOutboxItems(limit: number = 32): Promise<OutboxItem[]> {\n await this.initialize();\n\n const pending = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM embedding_outbox\n WHERE status = 'pending'\n ORDER BY created_at\n LIMIT ?`,\n [limit]\n );\n\n if (pending.length === 0) return [];\n\n // Update status to processing\n const ids = pending.map(r => r.id as string);\n const placeholders = ids.map(() => '?').join(',');\n sqliteRun(\n this.db,\n `UPDATE embedding_outbox SET status = 'processing' WHERE id IN (${placeholders})`,\n ids\n );\n\n return pending.map(row => ({\n id: row.id as string,\n eventId: row.event_id as string,\n content: row.content as string,\n status: 'processing' as const,\n retryCount: row.retry_count as number,\n createdAt: toDateFromSQLite(row.created_at),\n errorMessage: row.error_message as string | undefined\n }));\n }\n\n /**\n * Mark outbox items as done\n */\n async completeOutboxItems(ids: string[]): Promise<void> {\n if (ids.length === 0) return;\n\n const placeholders = ids.map(() => '?').join(',');\n sqliteRun(\n this.db,\n `DELETE FROM embedding_outbox WHERE id IN (${placeholders})`,\n ids\n );\n }\n\n /**\n * Clear embedding outbox (used for embedding model migration)\n */\n async clearEmbeddingOutbox(): Promise<void> {\n await this.initialize();\n sqliteRun(this.db, `DELETE FROM embedding_outbox`);\n }\n\n /**\n * Count total events\n */\n async countEvents(): Promise<number> {\n await this.initialize();\n const row = sqliteGet<{ count: number }>(this.db, `SELECT COUNT(*) as count FROM events`);\n return row?.count || 0;\n }\n\n /**\n * Get events page in timestamp ascending order (stable migration/reindex scans)\n */\n async getEventsPage(limit: number = 1000, offset: number = 0): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events ORDER BY timestamp ASC LIMIT ? OFFSET ?`,\n [limit, offset]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Mark outbox items as failed\n */\n async failOutboxItems(ids: string[], error: string): Promise<void> {\n if (ids.length === 0) return;\n\n const placeholders = ids.map(() => '?').join(',');\n sqliteRun(\n this.db,\n `UPDATE embedding_outbox\n SET status = CASE WHEN retry_count >= 3 THEN 'failed' ELSE 'pending' END,\n retry_count = retry_count + 1,\n error_message = ?\n WHERE id IN (${placeholders})`,\n [error, ...ids]\n );\n }\n\n\n /**\n * Get embedding/vector outbox health statistics\n */\n async getOutboxStats(): Promise<{\n embedding: { pending: number; processing: number; failed: number; total: number };\n vector: { pending: number; processing: number; failed: number; total: number };\n }> {\n await this.initialize();\n\n const embeddingRows = sqliteAll<{ status: string; count: number }>(\n this.db,\n `SELECT status, COUNT(*) as count FROM embedding_outbox GROUP BY status`\n );\n const vectorRows = sqliteAll<{ status: string; count: number }>(\n this.db,\n `SELECT status, COUNT(*) as count FROM vector_outbox GROUP BY status`\n );\n\n const fromRows = (rows: Array<{ status: string; count: number }>) => {\n const out = { pending: 0, processing: 0, failed: 0, total: 0 };\n for (const row of rows) {\n const key = row.status as 'pending' | 'processing' | 'failed' | 'done';\n if (key === 'pending' || key === 'processing' || key === 'failed') {\n out[key] += row.count;\n }\n out.total += row.count;\n }\n return out;\n };\n\n return {\n embedding: fromRows(embeddingRows),\n vector: fromRows(vectorRows)\n };\n }\n\n /**\n * Update memory level\n */\n async updateMemoryLevel(eventId: string, level: string): Promise<void> {\n await this.initialize();\n\n sqliteRun(\n this.db,\n `UPDATE memory_levels SET level = ?, promoted_at = datetime('now') WHERE event_id = ?`,\n [level, eventId]\n );\n }\n\n /**\n * Get memory level statistics\n */\n async getLevelStats(): Promise<Array<{ level: string; count: number }>> {\n await this.initialize();\n\n const rows = sqliteAll<{ level: string; count: number }>(\n this.db,\n `SELECT level, COUNT(*) as count FROM memory_levels GROUP BY level`\n );\n\n return rows;\n }\n\n /**\n * Get events by memory level\n */\n async getEventsByLevel(level: string, options?: { limit?: number; offset?: number }): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const limit = options?.limit || 50;\n const offset = options?.offset || 0;\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT e.* FROM events e\n INNER JOIN memory_levels ml ON e.id = ml.event_id\n WHERE ml.level = ?\n ORDER BY e.timestamp DESC\n LIMIT ? OFFSET ?`,\n [level, limit, offset]\n );\n\n return rows.map(row => this.rowToEvent(row));\n }\n\n /**\n * Get memory level for a specific event\n */\n async getEventLevel(eventId: string): Promise<string | null> {\n await this.initialize();\n\n const row = sqliteGet<{ level: string }>(\n this.db,\n `SELECT level FROM memory_levels WHERE event_id = ?`,\n [eventId]\n );\n\n return row ? row.level : null;\n }\n\n /**\n * Get sync position for a target\n */\n async getSyncPosition(targetName: string): Promise<{ lastEventId: string | null; lastTimestamp: string | null }> {\n await this.initialize();\n\n const row = sqliteGet<{ last_event_id: string | null; last_timestamp: string | null }>(\n this.db,\n `SELECT last_event_id, last_timestamp FROM sync_positions WHERE target_name = ?`,\n [targetName]\n );\n\n return {\n lastEventId: row?.last_event_id ?? null,\n lastTimestamp: row?.last_timestamp ?? null\n };\n }\n\n /**\n * Update sync position for a target\n */\n async updateSyncPosition(targetName: string, lastEventId: string, lastTimestamp: string): Promise<void> {\n await this.initialize();\n\n sqliteRun(\n this.db,\n `INSERT OR REPLACE INTO sync_positions (target_name, last_event_id, last_timestamp, updated_at)\n VALUES (?, ?, ?, datetime('now'))`,\n [targetName, lastEventId, lastTimestamp]\n );\n }\n\n /**\n * Get config value for endless mode\n */\n async getEndlessConfig(key: string): Promise<unknown | null> {\n await this.initialize();\n\n const row = sqliteGet<{ value: string }>(\n this.db,\n `SELECT value FROM endless_config WHERE key = ?`,\n [key]\n );\n\n if (!row) return null;\n return JSON.parse(row.value);\n }\n\n /**\n * Set config value for endless mode\n */\n async setEndlessConfig(key: string, value: unknown): Promise<void> {\n await this.initialize();\n\n sqliteRun(\n this.db,\n `INSERT OR REPLACE INTO endless_config (key, value, updated_at)\n VALUES (?, ?, datetime('now'))`,\n [key, JSON.stringify(value)]\n );\n }\n\n /**\n * Increment access count for events\n */\n async incrementAccessCount(eventIds: string[]): Promise<void> {\n if (eventIds.length === 0 || this.readOnly) return;\n\n await this.initialize();\n\n const placeholders = eventIds.map(() => '?').join(',');\n const currentTime = toSQLiteTimestamp(new Date());\n\n sqliteRun(\n this.db,\n `UPDATE events\n SET access_count = access_count + 1,\n last_accessed_at = ?\n WHERE id IN (${placeholders})`,\n [currentTime, ...eventIds]\n );\n }\n\n /**\n * Get most accessed memories (falls back to recent events if none accessed)\n */\n async getMostAccessed(limit: number = 10): Promise<MemoryEvent[]> {\n await this.initialize();\n\n // First try events with access_count > 0\n let rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events\n WHERE access_count > 0\n ORDER BY access_count DESC, last_accessed_at DESC\n LIMIT ?`,\n [limit]\n );\n\n // Fallback: if no accessed events, show recent events\n if (rows.length === 0) {\n rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events\n ORDER BY timestamp DESC\n LIMIT ?`,\n [limit]\n );\n }\n\n return rows.map(row => this.rowToEvent(row));\n }\n\n /**\n * Record a memory retrieval for helpfulness tracking\n */\n async recordRetrieval(eventId: string, sessionId: string, score: number, query: string): Promise<void> {\n if (this.readOnly) return;\n await this.initialize();\n\n const id = randomUUID();\n sqliteRun(\n this.db,\n `INSERT INTO memory_helpfulness (id, event_id, session_id, retrieval_score, query_preview, created_at)\n VALUES (?, ?, ?, ?, ?, datetime('now'))`,\n [id, eventId, sessionId, score, query.slice(0, 100)]\n );\n }\n\n /**\n * Evaluate helpfulness for all retrievals in a session\n * Called at session end - uses behavioral signals to compute score\n */\n async evaluateSessionHelpfulness(sessionId: string): Promise<void> {\n if (this.readOnly) return;\n await this.initialize();\n\n // Get all retrieval records for this session\n const retrievals = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM memory_helpfulness WHERE session_id = ? AND measured_at IS NULL`,\n [sessionId]\n );\n\n if (retrievals.length === 0) return;\n\n // Get session events to analyze behavior after retrieval\n const sessionEvents = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,\n [sessionId]\n );\n\n const promptEvents = sessionEvents.filter((e: any) => e.event_type === 'user_prompt');\n const toolEvents = sessionEvents.filter((e: any) => e.event_type === 'tool_observation');\n\n // Count successful vs failed tools\n let toolSuccessCount = 0;\n let toolTotalCount = toolEvents.length;\n for (const t of toolEvents) {\n try {\n const content = JSON.parse(t.content as string);\n if (content.success !== false) toolSuccessCount++;\n } catch {\n toolSuccessCount++; // Assume success if can't parse\n }\n }\n const toolSuccessRatio = toolTotalCount > 0 ? toolSuccessCount / toolTotalCount : 0.5;\n\n for (const retrieval of retrievals) {\n const retrievalTime = retrieval.created_at as string;\n\n // 1. Session continued after retrieval?\n const eventsAfter = sessionEvents.filter((e: any) => e.timestamp > retrievalTime);\n const sessionContinued = eventsAfter.length > 0 ? 1 : 0;\n\n // 2. How many prompts came after?\n const promptsAfter = promptEvents.filter((e: any) => e.timestamp > retrievalTime);\n const promptCountAfter = promptsAfter.length;\n\n // 3. Was a similar query asked again? (simple word overlap check)\n const queryWords = new Set((retrieval.query_preview as string || '').toLowerCase().split(/\\s+/).filter(w => w.length > 2));\n let wasReasked = 0;\n for (const p of promptsAfter) {\n const pWords = new Set((p.content as string).toLowerCase().split(/\\s+/).filter((w: string) => w.length > 2));\n let overlap = 0;\n for (const w of queryWords) {\n if (pWords.has(w)) overlap++;\n }\n if (queryWords.size > 0 && overlap / queryWords.size > 0.5) {\n wasReasked = 1;\n break;\n }\n }\n\n // Calculate helpfulness score\n const retrievalScore = retrieval.retrieval_score as number || 0;\n const helpfulnessScore = (\n 0.30 * Math.min(retrievalScore, 1.0) +\n 0.25 * (sessionContinued ? 1.0 : 0.0) +\n 0.25 * toolSuccessRatio +\n 0.20 * (wasReasked ? 0.0 : 1.0)\n );\n\n sqliteRun(\n this.db,\n `UPDATE memory_helpfulness\n SET session_continued = ?, prompt_count_after = ?,\n tool_success_count = ?, tool_total_count = ?,\n was_reasked = ?, helpfulness_score = ?,\n measured_at = datetime('now')\n WHERE id = ?`,\n [sessionContinued, promptCountAfter, toolSuccessCount, toolTotalCount,\n wasReasked, helpfulnessScore, retrieval.id]\n );\n }\n }\n\n /**\n * Get most helpful memories ranked by helpfulness score\n */\n async getHelpfulMemories(limit: number = 10): Promise<Array<{\n eventId: string;\n summary: string;\n helpfulnessScore: number;\n accessCount: number;\n evaluationCount: number;\n }>> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT\n mh.event_id,\n AVG(mh.helpfulness_score) as avg_score,\n COUNT(*) as eval_count,\n e.content,\n e.access_count\n FROM memory_helpfulness mh\n JOIN events e ON e.id = mh.event_id\n WHERE mh.measured_at IS NOT NULL\n GROUP BY mh.event_id\n ORDER BY avg_score DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(r => ({\n eventId: r.event_id as string,\n summary: (r.content as string).substring(0, 200) + ((r.content as string).length > 200 ? '...' : ''),\n helpfulnessScore: Math.round((r.avg_score as number) * 100) / 100,\n accessCount: (r.access_count as number) || 0,\n evaluationCount: r.eval_count as number\n }));\n }\n\n /**\n * Get helpfulness statistics for dashboard\n */\n async getHelpfulnessStats(): Promise<{\n avgScore: number;\n totalEvaluated: number;\n totalRetrievals: number;\n helpful: number;\n neutral: number;\n unhelpful: number;\n }> {\n await this.initialize();\n\n const stats = sqliteGet<Record<string, unknown>>(\n this.db,\n `SELECT\n AVG(helpfulness_score) as avg_score,\n COUNT(*) as total_evaluated,\n SUM(CASE WHEN helpfulness_score >= 0.7 THEN 1 ELSE 0 END) as helpful,\n SUM(CASE WHEN helpfulness_score >= 0.4 AND helpfulness_score < 0.7 THEN 1 ELSE 0 END) as neutral,\n SUM(CASE WHEN helpfulness_score < 0.4 THEN 1 ELSE 0 END) as unhelpful\n FROM memory_helpfulness\n WHERE measured_at IS NOT NULL`\n );\n\n const totalRow = sqliteGet<Record<string, unknown>>(\n this.db,\n `SELECT COUNT(*) as total FROM memory_helpfulness`\n );\n\n return {\n avgScore: Math.round(((stats?.avg_score as number) || 0) * 100) / 100,\n totalEvaluated: (stats?.total_evaluated as number) || 0,\n totalRetrievals: (totalRow?.total as number) || 0,\n helpful: (stats?.helpful as number) || 0,\n neutral: (stats?.neutral as number) || 0,\n unhelpful: (stats?.unhelpful as number) || 0\n };\n }\n\n /**\n * Fast keyword search using FTS5\n * Returns events matching the search query, ranked by relevance\n */\n async keywordSearch(query: string, limit: number = 10): Promise<Array<{event: MemoryEvent; rank: number}>> {\n await this.initialize();\n\n // Escape special FTS5 characters and prepare search terms\n const searchTerms = query\n .replace(/['\"(){}[\\]^~*?:\\\\/-]/g, ' ') // Remove special chars\n .split(/\\s+/)\n .filter(term => term.length > 1) // Filter short terms\n .map(term => `\"${term}\"*`) // Prefix matching\n .join(' OR ');\n\n if (!searchTerms) {\n return [];\n }\n\n try {\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT e.*, fts.rank\n FROM events_fts fts\n JOIN events e ON e.id = fts.event_id\n WHERE events_fts MATCH ?\n ORDER BY fts.rank\n LIMIT ?`,\n [searchTerms, limit]\n );\n\n return rows.map(row => ({\n event: this.rowToEvent(row),\n rank: row.rank as number\n }));\n } catch (error: any) {\n // FTS table might not exist yet (old database)\n // Fallback to LIKE search\n const likePattern = `%${query}%`;\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT *, 0 as rank FROM events\n WHERE content LIKE ?\n ORDER BY timestamp DESC\n LIMIT ?`,\n [likePattern, limit]\n );\n\n return rows.map(row => ({\n event: this.rowToEvent(row),\n rank: 0\n }));\n }\n }\n\n /**\n * Rebuild FTS index from existing events\n * Call this once after upgrading to FTS5\n */\n async rebuildFtsIndex(): Promise<number> {\n await this.initialize();\n\n // Get count of events to index\n const countRow = sqliteGet<{count: number}>(this.db, 'SELECT COUNT(*) as count FROM events', []);\n const totalEvents = countRow?.count ?? 0;\n\n // Clear and rebuild FTS index\n sqliteExec(this.db, `\n DELETE FROM events_fts;\n INSERT INTO events_fts(rowid, content, event_id)\n SELECT rowid, content, id FROM events;\n `);\n\n return totalEvents;\n }\n\n /**\n * Get database instance for direct access\n */\n getDatabase(): SQLiteDatabase {\n return this.db;\n }\n\n\n async recordRetrievalTrace(input: {\n sessionId?: string;\n projectHash?: string;\n queryText: string;\n strategy?: string;\n candidateEventIds: string[];\n selectedEventIds: string[];\n candidateDetails?: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n selectedDetails?: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n confidence?: string;\n fallbackTrace?: string[];\n }): Promise<void> {\n await this.initialize();\n\n const traceId = randomUUID();\n sqliteRun(\n this.db,\n `INSERT INTO retrieval_traces (\n trace_id, session_id, project_hash, query_text, strategy,\n candidate_event_ids, selected_event_ids, candidate_details_json, selected_details_json,\n candidate_count, selected_count, confidence, fallback_trace\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n traceId,\n input.sessionId || null,\n input.projectHash || null,\n input.queryText,\n input.strategy || null,\n JSON.stringify(input.candidateEventIds || []),\n JSON.stringify(input.selectedEventIds || []),\n JSON.stringify(input.candidateDetails || []),\n JSON.stringify(input.selectedDetails || []),\n (input.candidateEventIds || []).length,\n (input.selectedEventIds || []).length,\n input.confidence || null,\n JSON.stringify(input.fallbackTrace || [])\n ]\n );\n }\n\n async getRecentRetrievalTraces(limit: number = 50): Promise<Array<{\n traceId: string;\n sessionId?: string;\n projectHash?: string;\n queryText: string;\n strategy?: string;\n candidateEventIds: string[];\n selectedEventIds: string[];\n candidateDetails: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n selectedDetails: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n candidateCount: number;\n selectedCount: number;\n confidence?: string;\n fallbackTrace: string[];\n createdAt: Date;\n }>> {\n await this.initialize();\n\n try {\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM retrieval_traces ORDER BY created_at DESC LIMIT ?`,\n [limit]\n );\n\n return rows.map((row) => ({\n traceId: row.trace_id as string,\n sessionId: (row.session_id as string) || undefined,\n projectHash: (row.project_hash as string) || undefined,\n queryText: row.query_text as string,\n strategy: (row.strategy as string) || undefined,\n candidateEventIds: row.candidate_event_ids ? JSON.parse(row.candidate_event_ids as string) : [],\n selectedEventIds: row.selected_event_ids ? JSON.parse(row.selected_event_ids as string) : [],\n candidateDetails: row.candidate_details_json ? JSON.parse(row.candidate_details_json as string) : [],\n selectedDetails: row.selected_details_json ? JSON.parse(row.selected_details_json as string) : [],\n candidateCount: Number(row.candidate_count || 0),\n selectedCount: Number(row.selected_count || 0),\n confidence: (row.confidence as string) || undefined,\n fallbackTrace: row.fallback_trace ? JSON.parse(row.fallback_trace as string) : [],\n createdAt: toDateFromSQLite(row.created_at),\n }));\n } catch (err: any) {\n if (err?.message?.includes('no such table')) return [];\n throw err;\n }\n }\n\n async getRetrievalTraceStats(): Promise<{\n totalQueries: number;\n avgCandidateCount: number;\n avgSelectedCount: number;\n selectionRate: number;\n }> {\n await this.initialize();\n\n try {\n const row = sqliteGet<Record<string, unknown>>(\n this.db,\n `SELECT\n COUNT(*) as total_queries,\n AVG(candidate_count) as avg_candidate_count,\n AVG(selected_count) as avg_selected_count,\n CASE\n WHEN SUM(candidate_count) > 0 THEN (SUM(selected_count) * 1.0 / SUM(candidate_count))\n ELSE 0\n END as selection_rate\n FROM retrieval_traces`,\n []\n );\n\n return {\n totalQueries: Number(row?.total_queries || 0),\n avgCandidateCount: Number(row?.avg_candidate_count || 0),\n avgSelectedCount: Number(row?.avg_selected_count || 0),\n selectionRate: Number(row?.selection_rate || 0),\n };\n } catch (err: any) {\n if (err?.message?.includes('no such table')) {\n return { totalQueries: 0, avgCandidateCount: 0, avgSelectedCount: 0, selectionRate: 0 };\n }\n throw err;\n }\n }\n\n /**\n * Close database connection\n */\n async close(): Promise<void> {\n sqliteClose(this.db);\n }\n\n /**\n * Get events grouped by turn_id for a session\n * Returns turns ordered by first event timestamp (newest first)\n */\n async getSessionTurns(sessionId: string, options?: { limit?: number; offset?: number }): Promise<Array<{\n turnId: string;\n events: MemoryEvent[];\n startedAt: Date;\n promptPreview: string;\n eventCount: number;\n toolCount: number;\n hasResponse: boolean;\n }>> {\n await this.initialize();\n\n const limit = options?.limit || 20;\n const offset = options?.offset || 0;\n\n // Get distinct turn_ids for this session, ordered by first event timestamp\n const turnRows = sqliteAll<{ turn_id: string; min_ts: string }>(\n this.db,\n `SELECT turn_id, MIN(timestamp) as min_ts\n FROM events\n WHERE session_id = ? AND turn_id IS NOT NULL\n GROUP BY turn_id\n ORDER BY min_ts DESC\n LIMIT ? OFFSET ?`,\n [sessionId, limit, offset]\n );\n\n const turns: Array<{\n turnId: string;\n events: MemoryEvent[];\n startedAt: Date;\n promptPreview: string;\n eventCount: number;\n toolCount: number;\n hasResponse: boolean;\n }> = [];\n\n for (const turnRow of turnRows) {\n const events = await this.getEventsByTurn(turnRow.turn_id);\n\n const promptEvent = events.find(e => e.eventType === 'user_prompt');\n const toolEvents = events.filter(e => e.eventType === 'tool_observation');\n const hasResponse = events.some(e => e.eventType === 'agent_response');\n\n turns.push({\n turnId: turnRow.turn_id,\n events,\n startedAt: toDateFromSQLite(turnRow.min_ts),\n promptPreview: promptEvent\n ? promptEvent.content.slice(0, 200) + (promptEvent.content.length > 200 ? '...' : '')\n : '(no prompt)',\n eventCount: events.length,\n toolCount: toolEvents.length,\n hasResponse\n });\n }\n\n return turns;\n }\n\n /**\n * Get all events for a specific turn_id\n */\n async getEventsByTurn(turnId: string): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE turn_id = ? ORDER BY timestamp ASC`,\n [turnId]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Count total turns for a session\n */\n async countSessionTurns(sessionId: string): Promise<number> {\n await this.initialize();\n\n const row = sqliteGet<{ count: number }>(\n this.db,\n `SELECT COUNT(DISTINCT turn_id) as count\n FROM events\n WHERE session_id = ? AND turn_id IS NOT NULL`,\n [sessionId]\n );\n\n return row?.count || 0;\n }\n\n /**\n * Migrate existing events: backfill turn_id for events that have turnId in metadata\n * but no turn_id column value (for events stored before this migration)\n */\n async backfillTurnIds(): Promise<number> {\n await this.initialize();\n\n // Find events with turnId in metadata JSON but no turn_id column value\n const rows = sqliteAll<{ id: string; metadata: string }>(\n this.db,\n `SELECT id, metadata FROM events\n WHERE turn_id IS NULL AND metadata IS NOT NULL AND metadata LIKE '%turnId%'`\n );\n\n let updated = 0;\n for (const row of rows) {\n try {\n const metadata = JSON.parse(row.metadata);\n if (metadata.turnId) {\n sqliteRun(\n this.db,\n `UPDATE events SET turn_id = ? WHERE id = ?`,\n [metadata.turnId, row.id]\n );\n updated++;\n }\n } catch {\n // Skip rows with invalid JSON\n }\n }\n\n return updated;\n }\n\n /**\n * Delete all events for a session (for force reimport)\n */\n async deleteSessionEvents(sessionId: string): Promise<number> {\n await this.initialize();\n\n // Get event IDs first for cascading deletes\n const events = sqliteAll<{ id: string }>(\n this.db,\n `SELECT id FROM events WHERE session_id = ?`,\n [sessionId]\n );\n\n if (events.length === 0) return 0;\n\n const eventIds = events.map(e => e.id);\n const placeholders = eventIds.map(() => '?').join(',');\n\n // Drop FTS triggers to prevent SQLITE_CORRUPT_VTAB during bulk delete\n const ftsTriggersDropped: string[] = [];\n for (const triggerName of ['events_fts_delete', 'events_fts_update', 'events_fts_insert']) {\n try {\n sqliteRun(this.db, `DROP TRIGGER IF EXISTS ${triggerName}`);\n ftsTriggersDropped.push(triggerName);\n } catch {\n // Trigger may not exist\n }\n }\n\n // Delete from related tables first (some may not exist depending on DB version)\n for (const table of ['event_dedup', 'memory_levels', 'embedding_queue', 'embedding_outbox', 'vector_outbox']) {\n try {\n sqliteRun(this.db, `DELETE FROM ${table} WHERE event_id IN (${placeholders})`, eventIds);\n } catch {\n // Table may not exist\n }\n }\n\n // Delete events\n const result = sqliteRun(this.db, `DELETE FROM events WHERE session_id = ?`, [sessionId]);\n\n // Rebuild FTS index if we dropped triggers\n if (ftsTriggersDropped.length > 0) {\n try {\n // Rebuild FTS from remaining events\n sqliteRun(this.db, `INSERT INTO events_fts(events_fts) VALUES('rebuild')`);\n\n // Recreate triggers\n sqliteRun(this.db, `CREATE TRIGGER IF NOT EXISTS events_fts_insert AFTER INSERT ON events BEGIN\n INSERT INTO events_fts(rowid, content) VALUES (NEW.rowid, NEW.content);\n END`);\n sqliteRun(this.db, `CREATE TRIGGER IF NOT EXISTS events_fts_delete AFTER DELETE ON events BEGIN\n INSERT INTO events_fts(events_fts, rowid, content) VALUES('delete', OLD.rowid, OLD.content);\n END`);\n sqliteRun(this.db, `CREATE TRIGGER IF NOT EXISTS events_fts_update AFTER UPDATE ON events BEGIN\n INSERT INTO events_fts(events_fts, rowid, content) VALUES('delete', OLD.rowid, OLD.content);\n INSERT INTO events_fts(rowid, content) VALUES (NEW.rowid, NEW.content);\n END`);\n } catch {\n // FTS rebuild failed - non-critical, will be rebuilt on next initialize\n }\n }\n\n return result.changes || 0;\n }\n\n /**\n * Convert database row to MemoryEvent\n */\n private rowToEvent(row: Record<string, unknown>): MemoryEvent {\n const event: any = {\n id: row.id as string,\n eventType: row.event_type as 'user_prompt' | 'agent_response' | 'session_summary',\n sessionId: row.session_id as string,\n timestamp: toDateFromSQLite(row.timestamp),\n content: row.content as string,\n canonicalKey: row.canonical_key as string,\n dedupeKey: row.dedupe_key as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined\n };\n\n // Include access tracking fields if present\n if (row.access_count !== undefined) {\n event.access_count = row.access_count;\n }\n if (row.last_accessed_at !== undefined) {\n event.last_accessed_at = row.last_accessed_at;\n }\n // Include turn_id if present\n if (row.turn_id !== undefined && row.turn_id !== null) {\n event.turn_id = row.turn_id;\n }\n\n return event;\n }\n}\n", "/**\n * SQLite Wrapper with WAL Mode Support\n * Primary store for hooks - always available, no lock conflicts\n */\n\nimport Database from 'better-sqlite3';\nimport * as fs from 'fs';\nimport * as nodePath from 'path';\n\nexport type SQLiteDatabase = Database.Database;\n\nexport interface SQLiteOptions {\n readonly?: boolean;\n walMode?: boolean;\n}\n\n/**\n * Creates a new SQLite database with WAL mode\n */\nexport function createSQLiteDatabase(path: string, options?: SQLiteOptions): SQLiteDatabase {\n // Ensure parent directory exists\n const dir = nodePath.dirname(path);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n const db = new Database(path, {\n readonly: options?.readonly ?? false,\n });\n\n // Enable WAL mode for concurrent access (unless read-only)\n if (!options?.readonly && (options?.walMode ?? true)) {\n db.pragma('journal_mode = WAL');\n db.pragma('synchronous = NORMAL');\n db.pragma('busy_timeout = 5000');\n }\n\n return db;\n}\n\n/**\n * Execute a statement that doesn't return rows (INSERT, UPDATE, DELETE)\n */\nexport function sqliteRun(\n db: SQLiteDatabase,\n sql: string,\n params: unknown[] = []\n): Database.RunResult {\n const stmt = db.prepare(sql);\n return stmt.run(...params);\n}\n\n/**\n * Execute a query and return all rows\n */\nexport function sqliteAll<T = Record<string, unknown>>(\n db: SQLiteDatabase,\n sql: string,\n params: unknown[] = []\n): T[] {\n const stmt = db.prepare(sql);\n return stmt.all(...params) as T[];\n}\n\n/**\n * Execute a query and return first row\n */\nexport function sqliteGet<T = Record<string, unknown>>(\n db: SQLiteDatabase,\n sql: string,\n params: unknown[] = []\n): T | undefined {\n const stmt = db.prepare(sql);\n return stmt.get(...params) as T | undefined;\n}\n\n/**\n * Execute multiple statements (for schema creation)\n */\nexport function sqliteExec(db: SQLiteDatabase, sql: string): void {\n db.exec(sql);\n}\n\n/**\n * Close database connection\n */\nexport function sqliteClose(db: SQLiteDatabase): void {\n db.close();\n}\n\n/**\n * Run multiple statements in a transaction\n */\nexport function sqliteTransaction<T>(\n db: SQLiteDatabase,\n fn: () => T\n): T {\n return db.transaction(fn)();\n}\n\n/**\n * Safely converts a value to a Date object\n */\nexport function toDateFromSQLite(value: unknown): Date {\n if (value instanceof Date) return value;\n if (typeof value === 'string') return new Date(value);\n if (typeof value === 'number') return new Date(value);\n return new Date(String(value));\n}\n\n/**\n * Convert Date to ISO string for SQLite storage\n */\nexport function toSQLiteTimestamp(date: Date): string {\n return date.toISOString();\n}\n", "import * as fs from 'fs/promises';\nimport * as path from 'path';\nimport type { MemoryEvent } from './types.js';\n\nconst DEFAULT_NAMESPACE = 'default';\nconst DEFAULT_CATEGORY = 'uncategorized';\n\nexport function sanitizeSegment(input: unknown, fallback: string): string {\n const raw = String(input ?? '').trim().toLowerCase();\n const safe = raw\n .normalize('NFKD')\n .replace(/[^a-z0-9_-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n if (!safe || safe === '.' || safe === '..') return fallback;\n return safe;\n}\n\nfunction getCategorySegments(metadata: Record<string, unknown> | undefined, eventType: string): string[] {\n const raw = metadata?.categoryPath;\n if (Array.isArray(raw) && raw.length > 0) {\n return raw.map((s) => sanitizeSegment(s, DEFAULT_CATEGORY));\n }\n const single = metadata?.category;\n if (typeof single === 'string' && single.trim()) {\n return [sanitizeSegment(single, DEFAULT_CATEGORY)];\n }\n return [sanitizeSegment(eventType, DEFAULT_CATEGORY)];\n}\n\nexport function buildMirrorPath(rootDir: string, event: MemoryEvent): string {\n const metadata = event.metadata as Record<string, unknown> | undefined;\n const namespace = sanitizeSegment(metadata?.namespace, DEFAULT_NAMESPACE);\n const categories = getCategorySegments(metadata, event.eventType);\n\n const d = event.timestamp;\n const yyyy = d.getFullYear();\n const mm = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n\n return path.join(rootDir, 'memory', namespace, ...categories, `${yyyy}-${mm}-${dd}.md`);\n}\n\nexport function formatMirrorEntry(event: MemoryEvent): string {\n const category = Array.isArray((event.metadata as any)?.categoryPath)\n ? ((event.metadata as any).categoryPath as unknown[]).join('/')\n : String((event.metadata as any)?.category ?? event.eventType);\n\n return [\n '',\n `- ts: ${event.timestamp.toISOString()}`,\n ` id: ${event.id}`,\n ` type: ${event.eventType}`,\n ` session: ${event.sessionId}`,\n ` category: ${category}`,\n ' content: |',\n ...event.content.split('\\n').map((line) => ` ${line}`)\n ].join('\\n') + '\\n';\n}\n\nexport class MarkdownMirror {\n constructor(private readonly rootDir: string) {}\n\n async append(event: MemoryEvent): Promise<string> {\n const outPath = buildMirrorPath(this.rootDir, event);\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.appendFile(outPath, formatMirrorEntry(event), 'utf8');\n return outPath;\n }\n}\n", "/**\n * Sync Worker - SQLite to DuckDB synchronization\n * Runs periodically to sync primary store (SQLite) to analytics store (DuckDB)\n */\n\nimport { SQLiteEventStore } from './sqlite-event-store.js';\nimport { EventStore } from './event-store.js';\nimport { MemoryEvent } from './types.js';\n\nexport interface SyncWorkerConfig {\n intervalMs: number; // Sync interval (default: 30000 = 30 seconds)\n batchSize: number; // Events per batch (default: 500)\n maxRetries: number; // Max retries on failure (default: 3)\n retryDelayMs: number; // Delay between retries (default: 5000)\n}\n\nconst DEFAULT_CONFIG: SyncWorkerConfig = {\n intervalMs: 30000,\n batchSize: 500,\n maxRetries: 3,\n retryDelayMs: 5000\n};\n\nexport interface SyncStats {\n lastSyncAt: Date | null;\n eventsSynced: number;\n sessionsSynced: number;\n errors: number;\n status: 'idle' | 'syncing' | 'error' | 'stopped';\n}\n\nexport class SyncWorker {\n private config: SyncWorkerConfig;\n private intervalHandle: NodeJS.Timeout | null = null;\n private running = false;\n private stats: SyncStats = {\n lastSyncAt: null,\n eventsSynced: 0,\n sessionsSynced: 0,\n errors: 0,\n status: 'idle'\n };\n\n constructor(\n private sqliteStore: SQLiteEventStore,\n private duckdbStore: EventStore,\n config?: Partial<SyncWorkerConfig>\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Start the sync worker\n */\n start(): void {\n if (this.running) return;\n\n this.running = true;\n this.stats.status = 'idle';\n\n // Run initial sync\n this.syncNow().catch(err => {\n console.error('[SyncWorker] Initial sync failed:', err);\n });\n\n // Schedule periodic sync\n this.intervalHandle = setInterval(() => {\n this.syncNow().catch(err => {\n console.error('[SyncWorker] Periodic sync failed:', err);\n });\n }, this.config.intervalMs);\n }\n\n /**\n * Stop the sync worker\n */\n stop(): void {\n this.running = false;\n this.stats.status = 'stopped';\n\n if (this.intervalHandle) {\n clearInterval(this.intervalHandle);\n this.intervalHandle = null;\n }\n }\n\n /**\n * Trigger immediate sync\n */\n async syncNow(): Promise<void> {\n if (this.stats.status === 'syncing') {\n return; // Already syncing\n }\n\n this.stats.status = 'syncing';\n\n try {\n await this.syncEvents();\n await this.syncSessions();\n this.stats.lastSyncAt = new Date();\n this.stats.status = 'idle';\n } catch (error) {\n this.stats.errors++;\n this.stats.status = 'error';\n throw error;\n }\n }\n\n /**\n * Sync events from SQLite to DuckDB\n */\n private async syncEvents(): Promise<void> {\n const targetName = 'duckdb_analytics';\n\n // Get last sync position from SQLite\n const position = await this.sqliteStore.getSyncPosition(targetName);\n const lastTimestamp = position.lastTimestamp || '1970-01-01T00:00:00.000Z';\n\n let hasMore = true;\n let totalSynced = 0;\n\n while (hasMore) {\n // Get batch of events since last sync\n const events = await this.sqliteStore.getEventsSince(lastTimestamp, this.config.batchSize);\n\n if (events.length === 0) {\n hasMore = false;\n break;\n }\n\n // Insert into DuckDB with retry\n await this.retryWithBackoff(async () => {\n for (const event of events) {\n await this.insertEventToDuckDB(event);\n }\n });\n\n totalSynced += events.length;\n\n // Update sync position\n const lastEvent = events[events.length - 1];\n await this.sqliteStore.updateSyncPosition(\n targetName,\n lastEvent.id,\n lastEvent.timestamp.toISOString()\n );\n\n // Check if we got a full batch (more to sync)\n hasMore = events.length === this.config.batchSize;\n }\n\n this.stats.eventsSynced += totalSynced;\n }\n\n /**\n * Sync sessions from SQLite to DuckDB\n */\n private async syncSessions(): Promise<void> {\n // Get all sessions from SQLite\n const sessions = await this.sqliteStore.getAllSessions();\n\n // Upsert each session to DuckDB\n for (const session of sessions) {\n await this.retryWithBackoff(async () => {\n await this.duckdbStore.upsertSession(session);\n });\n }\n\n this.stats.sessionsSynced = sessions.length;\n }\n\n /**\n * Insert a single event into DuckDB\n */\n private async insertEventToDuckDB(event: MemoryEvent): Promise<void> {\n // Use append which handles deduplication\n await this.duckdbStore.append({\n eventType: event.eventType,\n sessionId: event.sessionId,\n timestamp: event.timestamp,\n content: event.content,\n metadata: event.metadata\n });\n }\n\n /**\n * Retry operation with exponential backoff\n */\n private async retryWithBackoff<T>(fn: () => Promise<T>): Promise<T> {\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt < this.config.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt < this.config.maxRetries - 1) {\n const delay = this.config.retryDelayMs * Math.pow(2, attempt);\n await this.sleep(delay);\n }\n }\n }\n\n throw lastError;\n }\n\n /**\n * Sleep utility\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n /**\n * Get sync statistics\n */\n getStats(): SyncStats {\n return { ...this.stats };\n }\n\n /**\n * Check if worker is running\n */\n isRunning(): boolean {\n return this.running;\n }\n}\n", "/**\n * LanceDB Vector Store for semantic search\n * AXIOMMIND Principle 6: Vector store consistency (DuckDB \u2192 outbox \u2192 LanceDB unidirectional)\n */\n\nimport * as lancedb from '@lancedb/lancedb';\nimport type { VectorRecord } from './types.js';\n\nexport interface SearchResult {\n id: string;\n eventId: string;\n content: string;\n score: number;\n sessionId: string;\n eventType: string;\n timestamp: string;\n}\n\nexport class VectorStore {\n private db: lancedb.Connection | null = null;\n private table: lancedb.Table | null = null;\n private readonly tableName = 'conversations';\n\n constructor(private dbPath: string) {}\n\n /**\n * Initialize LanceDB connection\n */\n async initialize(): Promise<void> {\n if (this.db) return;\n\n this.db = await lancedb.connect(this.dbPath);\n\n // Try to open existing table\n try {\n const tables = await this.db.tableNames();\n if (tables.includes(this.tableName)) {\n this.table = await this.db.openTable(this.tableName);\n }\n } catch {\n // Table doesn't exist yet, will be created on first insert\n this.table = null;\n }\n }\n\n /**\n * Add or update vector record\n */\n async upsert(record: VectorRecord): Promise<void> {\n await this.initialize();\n\n if (!this.db) {\n throw new Error('Database not initialized');\n }\n\n const data = {\n id: record.id,\n eventId: record.eventId,\n sessionId: record.sessionId,\n eventType: record.eventType,\n content: record.content,\n vector: record.vector,\n timestamp: record.timestamp,\n metadata: JSON.stringify(record.metadata || {})\n };\n\n if (!this.table) {\n // Create table with first record (handle race condition)\n try {\n this.table = await this.db.createTable(this.tableName, [data]);\n } catch (e: any) {\n if (e?.message?.includes('already exists')) {\n this.table = await this.db.openTable(this.tableName);\n await this.table.add([data]);\n } else {\n throw e;\n }\n }\n } else {\n await this.table.add([data]);\n }\n }\n\n /**\n * Add multiple vector records in batch\n */\n async upsertBatch(records: VectorRecord[]): Promise<void> {\n if (records.length === 0) return;\n\n await this.initialize();\n\n if (!this.db) {\n throw new Error('Database not initialized');\n }\n\n const data = records.map(record => ({\n id: record.id,\n eventId: record.eventId,\n sessionId: record.sessionId,\n eventType: record.eventType,\n content: record.content,\n vector: record.vector,\n timestamp: record.timestamp,\n metadata: JSON.stringify(record.metadata || {})\n }));\n\n if (!this.table) {\n try {\n this.table = await this.db.createTable(this.tableName, data);\n } catch (e: any) {\n if (e?.message?.includes('already exists')) {\n this.table = await this.db.openTable(this.tableName);\n await this.table.add(data);\n } else {\n throw e;\n }\n }\n } else {\n await this.table.add(data);\n }\n }\n\n /**\n * Search for similar vectors\n */\n async search(\n queryVector: number[],\n options: {\n limit?: number;\n minScore?: number;\n sessionId?: string;\n } = {}\n ): Promise<SearchResult[]> {\n await this.initialize();\n\n if (!this.table) {\n return [];\n }\n\n const { limit = 5, minScore = 0.7, sessionId } = options;\n\n // Use cosine distance for semantic similarity\n let query = this.table\n .search(queryVector)\n .distanceType('cosine')\n .limit(limit * 2); // Get more for filtering\n\n // Apply session filter if specified\n if (sessionId) {\n query = query.where(`sessionId = '${sessionId}'`);\n }\n\n const results = await query.toArray();\n\n return results\n .filter(r => {\n // Convert cosine distance to similarity score\n // Cosine distance ranges from 0 (identical) to 2 (opposite)\n // Score = 1 - (distance / 2) gives range [0, 1]\n const distance = r._distance || 0;\n const score = 1 - (distance / 2);\n return score >= minScore;\n })\n .slice(0, limit)\n .map(r => {\n const distance = r._distance || 0;\n const score = 1 - (distance / 2);\n return {\n id: r.id as string,\n eventId: r.eventId as string,\n content: r.content as string,\n score,\n sessionId: r.sessionId as string,\n eventType: r.eventType as string,\n timestamp: r.timestamp as string\n };\n });\n }\n\n /**\n * Delete vector by event ID\n */\n async delete(eventId: string): Promise<void> {\n if (!this.table) return;\n await this.table.delete(`eventId = '${eventId}'`);\n }\n\n /**\n * Get total count of vectors\n */\n async count(): Promise<number> {\n if (!this.table) return 0;\n const result = await this.table.countRows();\n return result;\n }\n\n /**\n * Clear all vectors (used for embedding model migration)\n */\n async clearAll(): Promise<void> {\n await this.initialize();\n if (!this.db) return;\n\n try {\n if (typeof (this.db as any).dropTable === 'function') {\n await (this.db as any).dropTable(this.tableName);\n } else if (typeof (this.db as any).drop_table === 'function') {\n await (this.db as any).drop_table(this.tableName);\n }\n } catch {\n // Ignore if table does not exist\n }\n\n this.table = null;\n }\n\n /**\n * Check if vector exists for event\n */\n async exists(eventId: string): Promise<boolean> {\n if (!this.table) return false;\n\n const results = await this.table\n .search([])\n .where(`eventId = '${eventId}'`)\n .limit(1)\n .toArray();\n\n return results.length > 0;\n }\n}\n", "/**\n * Local Embedding Generator using @xenova/transformers\n * AXIOMMIND Principle 7: Standard JSON format for vectors\n */\n\nimport { pipeline, Pipeline } from '@huggingface/transformers';\n\nexport interface EmbeddingResult {\n vector: number[];\n model: string;\n dimensions: number;\n}\n\nexport class Embedder {\n private pipeline: Pipeline | null = null;\n private readonly modelName: string;\n private activeModelName: string;\n private initialized = false;\n\n constructor(modelName: string = 'jinaai/jina-embeddings-v5-text-nano-text-matching') {\n this.modelName = modelName;\n this.activeModelName = modelName;\n }\n\n /**\n * Initialize the embedding pipeline\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n try {\n this.pipeline = await pipeline('feature-extraction', this.modelName);\n this.activeModelName = this.modelName;\n this.initialized = true;\n return;\n } catch (primaryError) {\n const fallbackModel = process.env.CLAUDE_MEMORY_EMBEDDING_FALLBACK_MODEL || 'onnx-community/embeddinggemma-300m-ONNX';\n if (fallbackModel === this.modelName) {\n throw primaryError;\n }\n\n console.warn(`[Embedder] Primary model failed (${this.modelName}). Falling back to ${fallbackModel}`);\n this.pipeline = await pipeline('feature-extraction', fallbackModel);\n this.activeModelName = fallbackModel;\n this.initialized = true;\n }\n }\n\n /**\n * Generate embedding for a single text\n */\n async embed(text: string): Promise<EmbeddingResult> {\n await this.initialize();\n\n if (!this.pipeline) {\n throw new Error('Embedding pipeline not initialized');\n }\n\n const output = await this.pipeline(text, {\n pooling: 'mean',\n normalize: true,\n truncation: true\n });\n\n const vector = Array.from(output.data as Float32Array);\n\n return {\n vector,\n model: this.activeModelName,\n dimensions: vector.length\n };\n }\n\n /**\n * Generate embeddings for multiple texts in batch\n */\n async embedBatch(texts: string[]): Promise<EmbeddingResult[]> {\n await this.initialize();\n\n if (!this.pipeline) {\n throw new Error('Embedding pipeline not initialized');\n }\n\n const results: EmbeddingResult[] = [];\n\n // Process in batches of 32 for memory efficiency\n const batchSize = 32;\n for (let i = 0; i < texts.length; i += batchSize) {\n const batch = texts.slice(i, i + batchSize);\n\n for (const text of batch) {\n const output = await this.pipeline(text, {\n pooling: 'mean',\n normalize: true,\n truncation: true\n });\n\n const vector = Array.from(output.data as Float32Array);\n\n results.push({\n vector,\n model: this.activeModelName,\n dimensions: vector.length\n });\n }\n }\n\n return results;\n }\n\n /**\n * Get embedding dimensions for the current model\n */\n async getDimensions(): Promise<number> {\n const result = await this.embed('test');\n return result.dimensions;\n }\n\n /**\n * Check if embedder is ready\n */\n isReady(): boolean {\n return this.initialized && this.pipeline !== null;\n }\n\n /**\n * Get model name\n */\n getModelName(): string {\n return this.activeModelName;\n }\n}\n\n// Singleton instance for reuse\nlet defaultEmbedder: Embedder | null = null;\n\nexport function getDefaultEmbedder(): Embedder {\n const envModel = process.env.CLAUDE_MEMORY_EMBEDDING_MODEL;\n if (!defaultEmbedder) {\n defaultEmbedder = new Embedder(envModel || undefined);\n }\n return defaultEmbedder;\n}\n", "/**\n * Vector Outbox V2 - Transactional Outbox Pattern\n * AXIOMMIND Principle 6: DuckDB \u2192 outbox \u2192 LanceDB unidirectional flow\n */\n\nimport { dbRun, dbAll, toDate, type Database } from './db-wrapper.js';\nimport { randomUUID } from 'crypto';\nimport type {\n OutboxJob,\n OutboxStatus,\n OutboxItemKind,\n VALID_OUTBOX_TRANSITIONS\n} from './types.js';\n\nexport interface OutboxConfig {\n embeddingVersion: string;\n maxRetries: number;\n stuckThresholdMs: number;\n cleanupDays: number;\n}\n\nconst DEFAULT_CONFIG: OutboxConfig = {\n embeddingVersion: 'v1',\n maxRetries: 3,\n stuckThresholdMs: 5 * 60 * 1000, // 5 minutes\n cleanupDays: 7\n};\n\nexport interface OutboxMetrics {\n pendingCount: number;\n processingCount: number;\n doneCount: number;\n failedCount: number;\n oldestPendingAge: number | null;\n}\n\nexport class VectorOutbox {\n private config: OutboxConfig;\n\n constructor(\n private db: Database,\n config?: Partial<OutboxConfig>\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Enqueue item for vectorization (idempotent)\n */\n async enqueue(\n itemKind: OutboxItemKind,\n itemId: string,\n embeddingVersion?: string\n ): Promise<string> {\n const version = embeddingVersion ?? this.config.embeddingVersion;\n const jobId = randomUUID();\n const now = new Date().toISOString();\n\n await dbRun(\n this.db,\n `INSERT INTO vector_outbox (\n job_id, item_kind, item_id, embedding_version, status, retry_count, created_at, updated_at\n ) VALUES (?, ?, ?, ?, 'pending', 0, ?, ?)\n ON CONFLICT (item_kind, item_id, embedding_version) DO NOTHING`,\n [jobId, itemKind, itemId, version, now, now]\n );\n\n return jobId;\n }\n\n /**\n * Claim pending jobs for processing\n */\n async claimJobs(limit: number = 32): Promise<OutboxJob[]> {\n const now = new Date().toISOString();\n\n // Atomic claim using UPDATE RETURNING\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `UPDATE vector_outbox\n SET status = 'processing', updated_at = ?\n WHERE job_id IN (\n SELECT job_id FROM vector_outbox\n WHERE status = 'pending'\n ORDER BY created_at ASC\n LIMIT ?\n )\n RETURNING *`,\n [now, limit]\n );\n\n return rows.map(row => this.rowToJob(row));\n }\n\n /**\n * Mark job as done\n */\n async markDone(jobId: string): Promise<void> {\n await dbRun(\n this.db,\n `UPDATE vector_outbox\n SET status = 'done', updated_at = ?\n WHERE job_id = ?`,\n [new Date().toISOString(), jobId]\n );\n }\n\n /**\n * Mark job as failed\n */\n async markFailed(jobId: string, error: string): Promise<void> {\n const now = new Date().toISOString();\n\n // Check retry count\n const rows = await dbAll<{ retry_count: number }>(\n this.db,\n `SELECT retry_count FROM vector_outbox WHERE job_id = ?`,\n [jobId]\n );\n\n if (rows.length === 0) return;\n\n const retryCount = rows[0].retry_count;\n const newStatus: OutboxStatus = retryCount >= this.config.maxRetries - 1\n ? 'failed'\n : 'pending'; // Will retry\n\n await dbRun(\n this.db,\n `UPDATE vector_outbox\n SET status = ?, error = ?, retry_count = retry_count + 1, updated_at = ?\n WHERE job_id = ?`,\n [newStatus, error, now, jobId]\n );\n }\n\n /**\n * Get job by ID\n */\n async getJob(jobId: string): Promise<OutboxJob | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM vector_outbox WHERE job_id = ?`,\n [jobId]\n );\n\n if (rows.length === 0) return null;\n return this.rowToJob(rows[0]);\n }\n\n /**\n * Get jobs by status\n */\n async getJobsByStatus(status: OutboxStatus, limit: number = 100): Promise<OutboxJob[]> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM vector_outbox\n WHERE status = ?\n ORDER BY created_at ASC\n LIMIT ?`,\n [status, limit]\n );\n\n return rows.map(row => this.rowToJob(row));\n }\n\n /**\n * Reconcile: recover stuck and retry failed jobs\n */\n async reconcile(): Promise<{ recovered: number; retried: number }> {\n const now = new Date();\n const stuckThreshold = new Date(now.getTime() - this.config.stuckThresholdMs);\n\n // Recover stuck processing jobs\n await dbRun(\n this.db,\n `UPDATE vector_outbox\n SET status = 'pending', updated_at = ?\n WHERE status = 'processing'\n AND updated_at < ?`,\n [now.toISOString(), stuckThreshold.toISOString()]\n );\n\n // Retry failed jobs that haven't exceeded max retries\n await dbRun(\n this.db,\n `UPDATE vector_outbox\n SET status = 'pending', updated_at = ?\n WHERE status = 'failed'\n AND retry_count < ?`,\n [now.toISOString(), this.config.maxRetries]\n );\n\n // Get counts (DuckDB doesn't return affected rows easily)\n const recoveredRows = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM vector_outbox\n WHERE status = 'pending' AND updated_at = ?`,\n [now.toISOString()]\n );\n\n return {\n recovered: 0, // Approximate\n retried: 0 // Approximate\n };\n }\n\n /**\n * Cleanup old done jobs\n */\n async cleanup(): Promise<number> {\n const threshold = new Date();\n threshold.setDate(threshold.getDate() - this.config.cleanupDays);\n\n await dbRun(\n this.db,\n `DELETE FROM vector_outbox\n WHERE status = 'done'\n AND updated_at < ?`,\n [threshold.toISOString()]\n );\n\n return 0; // DuckDB doesn't return affected rows easily\n }\n\n /**\n * Get metrics\n */\n async getMetrics(): Promise<OutboxMetrics> {\n const statusCounts = await dbAll<{ status: string; count: number }>(\n this.db,\n `SELECT status, COUNT(*) as count\n FROM vector_outbox\n GROUP BY status`\n );\n\n const oldestPending = await dbAll<{ created_at: string }>(\n this.db,\n `SELECT created_at FROM vector_outbox\n WHERE status = 'pending'\n ORDER BY created_at ASC\n LIMIT 1`\n );\n\n const metrics: OutboxMetrics = {\n pendingCount: 0,\n processingCount: 0,\n doneCount: 0,\n failedCount: 0,\n oldestPendingAge: null\n };\n\n for (const row of statusCounts) {\n switch (row.status) {\n case 'pending':\n metrics.pendingCount = Number(row.count);\n break;\n case 'processing':\n metrics.processingCount = Number(row.count);\n break;\n case 'done':\n metrics.doneCount = Number(row.count);\n break;\n case 'failed':\n metrics.failedCount = Number(row.count);\n break;\n }\n }\n\n if (oldestPending.length > 0) {\n const oldestDate = new Date(oldestPending[0].created_at);\n metrics.oldestPendingAge = Date.now() - oldestDate.getTime();\n }\n\n return metrics;\n }\n\n /**\n * Validate state transition\n */\n isValidTransition(from: OutboxStatus, to: OutboxStatus): boolean {\n const validTransitions = [\n { from: 'pending', to: 'processing' },\n { from: 'processing', to: 'done' },\n { from: 'processing', to: 'failed' },\n { from: 'failed', to: 'pending' }\n ];\n\n return validTransitions.some(t => t.from === from && t.to === to);\n }\n\n /**\n * Convert database row to OutboxJob\n */\n private rowToJob(row: Record<string, unknown>): OutboxJob {\n return {\n jobId: row.job_id as string,\n itemKind: row.item_kind as OutboxItemKind,\n itemId: row.item_id as string,\n embeddingVersion: row.embedding_version as string,\n status: row.status as OutboxStatus,\n retryCount: row.retry_count as number,\n error: row.error as string | undefined,\n createdAt: toDate(row.created_at),\n updatedAt: toDate(row.updated_at)\n };\n }\n}\n", "/**\n * Vector Worker - Single-Writer Pattern Implementation\n * AXIOMMIND Principle 6: DuckDB \u2192 outbox \u2192 LanceDB unidirectional flow\n */\n\nimport { EventStore } from './event-store.js';\nimport { VectorStore } from './vector-store.js';\nimport { Embedder } from './embedder.js';\nimport type { OutboxItem, VectorRecord } from './types.js';\n\nexport interface WorkerConfig {\n batchSize: number;\n pollIntervalMs: number;\n maxRetries: number;\n}\n\nconst DEFAULT_CONFIG: WorkerConfig = {\n batchSize: 32,\n pollIntervalMs: 1000,\n maxRetries: 3\n};\n\nexport class VectorWorker {\n private readonly eventStore: EventStore;\n private readonly vectorStore: VectorStore;\n private readonly embedder: Embedder;\n private readonly config: WorkerConfig;\n private running = false;\n private stopping = false;\n private pollTimeout: NodeJS.Timeout | null = null;\n\n constructor(\n eventStore: EventStore,\n vectorStore: VectorStore,\n embedder: Embedder,\n config: Partial<WorkerConfig> = {}\n ) {\n this.eventStore = eventStore;\n this.vectorStore = vectorStore;\n this.embedder = embedder;\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Start the worker polling loop\n */\n start(): void {\n if (this.running) return;\n this.running = true;\n this.stopping = false;\n this.poll();\n }\n\n /**\n * Stop the worker\n */\n stop(): void {\n this.running = false;\n this.stopping = true;\n if (this.pollTimeout) {\n clearTimeout(this.pollTimeout);\n this.pollTimeout = null;\n }\n }\n\n /**\n * Process a single batch of outbox items\n */\n async processBatch(): Promise<number> {\n const items = await this.eventStore.getPendingOutboxItems(this.config.batchSize);\n\n if (items.length === 0) {\n return 0;\n }\n\n const successful: string[] = [];\n const failed: string[] = [];\n\n try {\n // Generate embeddings for all items\n const embeddings = await this.embedder.embedBatch(items.map(i => i.content));\n\n // Prepare vector records\n const records: VectorRecord[] = [];\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const embedding = embeddings[i];\n\n // Get event details\n const event = await this.eventStore.getEvent(item.eventId);\n if (!event) {\n failed.push(item.id);\n continue;\n }\n\n records.push({\n id: `vec_${item.id}`,\n eventId: item.eventId,\n sessionId: event.sessionId,\n eventType: event.eventType,\n content: item.content,\n vector: embedding.vector,\n timestamp: event.timestamp.toISOString(),\n metadata: event.metadata\n });\n\n successful.push(item.id);\n }\n\n // Batch insert to vector store\n if (records.length > 0) {\n await this.vectorStore.upsertBatch(records);\n }\n\n // Mark successful items as done\n if (successful.length > 0) {\n await this.eventStore.completeOutboxItems(successful);\n }\n\n // Mark failed items\n if (failed.length > 0) {\n await this.eventStore.failOutboxItems(failed, 'Event not found');\n }\n\n return successful.length;\n } catch (error) {\n // Mark all items as failed, but only if not stopping (DB might be closed)\n if (!this.stopping) {\n try {\n const allIds = items.map(i => i.id);\n const errorMessage = error instanceof Error ? error.message : String(error);\n await this.eventStore.failOutboxItems(allIds, errorMessage);\n } catch (failError) {\n // Database might be closed during shutdown, ignore\n console.warn('Could not mark outbox items as failed (database may be closed)');\n }\n }\n throw error;\n }\n }\n\n /**\n * Poll for new items\n */\n private async poll(): Promise<void> {\n if (!this.running || this.stopping) return;\n\n try {\n await this.processBatch();\n } catch (error) {\n // Only log if not stopping (error during shutdown is expected)\n if (!this.stopping) {\n console.error('Vector worker error:', error);\n }\n }\n\n // Schedule next poll only if still running\n if (this.running && !this.stopping) {\n this.pollTimeout = setTimeout(() => this.poll(), this.config.pollIntervalMs);\n }\n }\n\n /**\n * Process all pending items (blocking)\n */\n async processAll(): Promise<number> {\n let totalProcessed = 0;\n let processed: number;\n\n do {\n processed = await this.processBatch();\n totalProcessed += processed;\n } while (processed > 0);\n\n return totalProcessed;\n }\n\n /**\n * Check if worker is running\n */\n isRunning(): boolean {\n return this.running;\n }\n}\n\n/**\n * Create and start a vector worker\n */\nexport function createVectorWorker(\n eventStore: EventStore,\n vectorStore: VectorStore,\n embedder: Embedder,\n config?: Partial<WorkerConfig>\n): VectorWorker {\n const worker = new VectorWorker(eventStore, vectorStore, embedder, config);\n return worker;\n}\n\n// ============================================================\n// Vector Worker V2 - Extended for Task Entity System\n// ============================================================\n\nimport { dbAll, type Database } from './db-wrapper.js';\nimport { VectorOutbox } from './vector-outbox.js';\nimport type { OutboxJob, OutboxItemKind } from './types.js';\n\nexport interface WorkerConfigV2 {\n batchSize: number;\n pollIntervalMs: number;\n maxRetries: number;\n embeddingVersion: string;\n}\n\nconst DEFAULT_CONFIG_V2: WorkerConfigV2 = {\n batchSize: 32,\n pollIntervalMs: 1000,\n maxRetries: 3,\n embeddingVersion: 'v1'\n};\n\n/**\n * Content provider interface for different item kinds\n */\nexport interface ContentProvider {\n getContent(itemKind: OutboxItemKind, itemId: string): Promise<{\n content: string;\n metadata: Record<string, unknown>;\n } | null>;\n}\n\n/**\n * Default content provider using database\n */\nexport class DefaultContentProvider implements ContentProvider {\n constructor(private db: Database) {}\n\n async getContent(itemKind: OutboxItemKind, itemId: string): Promise<{\n content: string;\n metadata: Record<string, unknown>;\n } | null> {\n switch (itemKind) {\n case 'entry':\n return this.getEntryContent(itemId);\n case 'task_title':\n return this.getTaskTitleContent(itemId);\n case 'event':\n return this.getEventContent(itemId);\n default:\n return null;\n }\n }\n\n private async getEntryContent(entryId: string): Promise<{\n content: string;\n metadata: Record<string, unknown>;\n } | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,\n [entryId]\n );\n\n if (rows.length === 0) return null;\n\n const row = rows[0];\n const contentJson = typeof row.content_json === 'string'\n ? JSON.parse(row.content_json)\n : row.content_json;\n\n return {\n content: `${row.title}\\n${JSON.stringify(contentJson)}`,\n metadata: {\n itemKind: 'entry',\n entryType: row.entry_type\n }\n };\n }\n\n private async getTaskTitleContent(taskId: string): Promise<{\n content: string;\n metadata: Record<string, unknown>;\n } | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT title, search_text, current_json FROM entities\n WHERE entity_id = ? AND entity_type = 'task'`,\n [taskId]\n );\n\n if (rows.length === 0) return null;\n\n const row = rows[0];\n return {\n content: row.search_text as string || row.title as string,\n metadata: {\n itemKind: 'task_title',\n entityType: 'task'\n }\n };\n }\n\n private async getEventContent(eventId: string): Promise<{\n content: string;\n metadata: Record<string, unknown>;\n } | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT content, event_type, session_id FROM events WHERE id = ?`,\n [eventId]\n );\n\n if (rows.length === 0) return null;\n\n const row = rows[0];\n return {\n content: row.content as string,\n metadata: {\n itemKind: 'event',\n eventType: row.event_type,\n sessionId: row.session_id\n }\n };\n }\n}\n\n/**\n * Vector Worker V2 - Supports multiple item kinds\n */\nexport class VectorWorkerV2 {\n private readonly outbox: VectorOutbox;\n private readonly vectorStore: VectorStore;\n private readonly embedder: Embedder;\n private readonly contentProvider: ContentProvider;\n private readonly config: WorkerConfigV2;\n private running = false;\n private stopping = false;\n private pollTimeout: NodeJS.Timeout | null = null;\n\n constructor(\n db: Database,\n vectorStore: VectorStore,\n embedder: Embedder,\n config: Partial<WorkerConfigV2> = {},\n contentProvider?: ContentProvider\n ) {\n this.outbox = new VectorOutbox(db, {\n embeddingVersion: config.embeddingVersion ?? DEFAULT_CONFIG_V2.embeddingVersion,\n maxRetries: config.maxRetries ?? DEFAULT_CONFIG_V2.maxRetries\n });\n this.vectorStore = vectorStore;\n this.embedder = embedder;\n this.config = { ...DEFAULT_CONFIG_V2, ...config };\n this.contentProvider = contentProvider ?? new DefaultContentProvider(db);\n }\n\n /**\n * Start the worker polling loop\n */\n start(): void {\n if (this.running) return;\n this.running = true;\n this.stopping = false;\n this.poll();\n }\n\n /**\n * Stop the worker\n */\n stop(): void {\n this.running = false;\n this.stopping = true;\n if (this.pollTimeout) {\n clearTimeout(this.pollTimeout);\n this.pollTimeout = null;\n }\n }\n\n /**\n * Process a single batch of outbox jobs\n */\n async processBatch(): Promise<number> {\n const jobs = await this.outbox.claimJobs(this.config.batchSize);\n\n if (jobs.length === 0) {\n return 0;\n }\n\n let successCount = 0;\n\n for (const job of jobs) {\n try {\n await this.processJob(job);\n await this.outbox.markDone(job.jobId);\n successCount++;\n } catch (error) {\n // Only try to mark as failed if not stopping (DB might be closed)\n if (!this.stopping) {\n try {\n const errorMessage = error instanceof Error ? error.message : String(error);\n await this.outbox.markFailed(job.jobId, errorMessage);\n } catch {\n // Database might be closed during shutdown, ignore\n }\n }\n }\n }\n\n return successCount;\n }\n\n /**\n * Process a single job\n */\n private async processJob(job: OutboxJob): Promise<void> {\n // Get content\n const contentData = await this.contentProvider.getContent(job.itemKind, job.itemId);\n\n if (!contentData) {\n // Item not found, mark as done (skip)\n return;\n }\n\n // Generate embedding\n const embedding = await this.embedder.embed(contentData.content);\n\n // Upsert to vector store\n const record: VectorRecord = {\n id: `${job.itemKind}_${job.itemId}_${job.embeddingVersion}`,\n eventId: job.itemKind === 'event' ? job.itemId : '',\n sessionId: (contentData.metadata.sessionId as string) ?? '',\n eventType: (contentData.metadata.eventType as string) ?? job.itemKind,\n content: contentData.content,\n vector: embedding.vector,\n timestamp: new Date().toISOString(),\n metadata: {\n ...contentData.metadata,\n embeddingVersion: job.embeddingVersion\n }\n };\n\n // Use idempotent upsert (delete + add)\n await this.vectorStore.upsertBatch([record]);\n }\n\n /**\n * Poll for new jobs\n */\n private async poll(): Promise<void> {\n if (!this.running || this.stopping) return;\n\n try {\n await this.processBatch();\n } catch (error) {\n // Only log if not stopping (error during shutdown is expected)\n if (!this.stopping) {\n console.error('Vector worker V2 error:', error);\n }\n }\n\n // Schedule next poll only if still running\n if (this.running && !this.stopping) {\n this.pollTimeout = setTimeout(() => this.poll(), this.config.pollIntervalMs);\n }\n }\n\n /**\n * Process all pending jobs (blocking)\n */\n async processAll(): Promise<number> {\n let totalProcessed = 0;\n let processed: number;\n\n do {\n processed = await this.processBatch();\n totalProcessed += processed;\n } while (processed > 0);\n\n return totalProcessed;\n }\n\n /**\n * Run reconciliation\n */\n async reconcile(): Promise<{ recovered: number; retried: number }> {\n return this.outbox.reconcile();\n }\n\n /**\n * Get metrics\n */\n async getMetrics() {\n return this.outbox.getMetrics();\n }\n\n /**\n * Check if worker is running\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Get the outbox instance for direct access\n */\n getOutbox(): VectorOutbox {\n return this.outbox;\n }\n}\n\n/**\n * Create a Vector Worker V2 instance\n */\nexport function createVectorWorkerV2(\n db: Database,\n vectorStore: VectorStore,\n embedder: Embedder,\n config?: Partial<WorkerConfigV2>\n): VectorWorkerV2 {\n return new VectorWorkerV2(db, vectorStore, embedder, config);\n}\n", "/**\n * AXIOMMIND Matcher - Weighted scoring with confidence classification\n * Implements matching thresholds: high (\u22650.92), suggested (\u22650.75), none (<0.75)\n */\n\nimport type {\n MemoryEvent,\n MemoryMatch,\n MatchResult,\n MatchConfidence,\n MATCH_THRESHOLDS\n} from './types.js';\nimport { SearchResult } from './vector-store.js';\n\nexport interface MatchWeights {\n semanticSimilarity: number;\n ftsScore: number;\n recencyBonus: number;\n statusWeight: number;\n}\n\nexport interface MatcherConfig {\n weights: MatchWeights;\n minCombinedScore: number;\n minGap: number;\n suggestionThreshold: number;\n}\n\nconst DEFAULT_CONFIG: MatcherConfig = {\n weights: {\n semanticSimilarity: 0.4,\n ftsScore: 0.25,\n recencyBonus: 0.2,\n statusWeight: 0.15\n },\n minCombinedScore: 0.92,\n minGap: 0.03,\n suggestionThreshold: 0.75\n};\n\nexport class Matcher {\n private readonly config: MatcherConfig;\n\n constructor(config: Partial<MatcherConfig> = {}) {\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n weights: { ...DEFAULT_CONFIG.weights, ...config.weights }\n };\n }\n\n /**\n * Calculate combined score using AXIOMMIND weighted formula\n */\n calculateCombinedScore(\n semanticScore: number,\n ftsScore: number = 0,\n recencyDays: number = 0,\n isActive: boolean = true\n ): number {\n const { weights } = this.config;\n\n // Recency bonus: decays over 30 days\n const recencyBonus = Math.max(0, 1 - recencyDays / 30);\n\n // Status weight: active events get full weight\n const statusMultiplier = isActive ? 1.0 : 0.7;\n\n const combinedScore =\n weights.semanticSimilarity * semanticScore +\n weights.ftsScore * ftsScore +\n weights.recencyBonus * recencyBonus +\n weights.statusWeight * statusMultiplier;\n\n return Math.min(1.0, combinedScore);\n }\n\n /**\n * Classify match confidence based on AXIOMMIND thresholds\n */\n classifyConfidence(\n topScore: number,\n secondScore: number | null\n ): MatchConfidence {\n const { minCombinedScore, minGap, suggestionThreshold } = this.config;\n\n // Calculate gap (infinity if no second match)\n const gap = secondScore !== null ? topScore - secondScore : Infinity;\n\n // High confidence: score \u2265 0.92 AND gap \u2265 0.03\n if (topScore >= minCombinedScore && gap >= minGap) {\n return 'high';\n }\n\n // Suggested: score \u2265 0.75\n if (topScore >= suggestionThreshold) {\n return 'suggested';\n }\n\n // No match\n return 'none';\n }\n\n /**\n * Match search results to find best memory\n */\n matchSearchResults(\n results: SearchResult[],\n getEventAge: (eventId: string) => number\n ): MatchResult {\n if (results.length === 0) {\n return {\n match: null,\n confidence: 'none'\n };\n }\n\n // Calculate combined scores\n const scoredResults = results.map(result => {\n const ageDays = getEventAge(result.eventId);\n const combinedScore = this.calculateCombinedScore(\n result.score,\n 0, // FTS score - would need to be passed in\n ageDays,\n true // Assume active\n );\n\n return {\n result,\n combinedScore\n };\n });\n\n // Sort by combined score\n scoredResults.sort((a, b) => b.combinedScore - a.combinedScore);\n\n const topResult = scoredResults[0];\n const secondScore = scoredResults.length > 1 ? scoredResults[1].combinedScore : null;\n\n // Classify confidence\n const confidence = this.classifyConfidence(topResult.combinedScore, secondScore);\n\n // Build match result\n const match: MemoryMatch = {\n event: {\n id: topResult.result.eventId,\n eventType: topResult.result.eventType as 'user_prompt' | 'agent_response' | 'session_summary',\n sessionId: topResult.result.sessionId,\n timestamp: new Date(topResult.result.timestamp),\n content: topResult.result.content,\n canonicalKey: '', // Would need to be fetched\n dedupeKey: '' // Would need to be fetched\n },\n score: topResult.combinedScore\n };\n\n const gap = secondScore !== null ? topResult.combinedScore - secondScore : undefined;\n\n // Build alternatives for suggested matches\n const alternatives = confidence === 'suggested'\n ? scoredResults.slice(1, 4).map(sr => ({\n event: {\n id: sr.result.eventId,\n eventType: sr.result.eventType as 'user_prompt' | 'agent_response' | 'session_summary',\n sessionId: sr.result.sessionId,\n timestamp: new Date(sr.result.timestamp),\n content: sr.result.content,\n canonicalKey: '',\n dedupeKey: ''\n },\n score: sr.combinedScore\n }))\n : undefined;\n\n return {\n match: confidence !== 'none' ? match : null,\n confidence,\n gap,\n alternatives\n };\n }\n\n /**\n * Calculate days between two dates\n */\n static calculateAgeDays(timestamp: Date): number {\n const now = new Date();\n const diffMs = now.getTime() - timestamp.getTime();\n return diffMs / (1000 * 60 * 60 * 24);\n }\n\n /**\n * Get current configuration\n */\n getConfig(): Readonly<MatcherConfig> {\n return { ...this.config };\n }\n}\n\n/**\n * Default matcher instance\n */\nlet defaultMatcher: Matcher | null = null;\n\nexport function getDefaultMatcher(): Matcher {\n if (!defaultMatcher) {\n defaultMatcher = new Matcher();\n }\n return defaultMatcher;\n}\n", "/**\n * Memory Retriever - Unified retrieval interface\n * Combines vector search, keyword search, scoped filtering, and matching\n */\n\nimport { EventStore } from './event-store.js';\nimport { VectorStore, SearchResult } from './vector-store.js';\nimport { Embedder } from './embedder.js';\nimport { Matcher } from './matcher.js';\nimport { SharedStore } from './shared-store.js';\nimport { SharedVectorStore } from './shared-vector-store.js';\nimport { GraduationPipeline } from './graduation.js';\nimport type { MemoryEvent, MatchResult, SharedTroubleshootingEntry } from './types.js';\n\nexport interface RetrievalScope {\n sessionId?: string;\n eventTypes?: MemoryEvent['eventType'][];\n metadata?: Record<string, unknown>;\n canonicalKeyPrefix?: string;\n sessionIdPrefix?: string;\n contentIncludes?: string[];\n}\n\nexport type RetrievalStrategy = 'auto' | 'fast' | 'deep';\nexport type ProjectScopeMode = 'strict' | 'prefer' | 'global';\n\nexport interface RetrievalOptions {\n topK: number;\n minScore: number;\n sessionId?: string;\n maxTokens: number;\n includeSessionContext: boolean;\n scope?: RetrievalScope;\n strategy?: RetrievalStrategy;\n rerankWithKeyword?: boolean;\n rerankWeights?: {\n semantic?: number;\n lexical?: number;\n recency?: number;\n };\n decayPolicy?: {\n enabled?: boolean;\n windowDays?: number;\n maxPenalty?: number;\n };\n intentRewrite?: boolean;\n graphHop?: {\n enabled?: boolean;\n maxHops?: number;\n hopPenalty?: number;\n };\n projectScopeMode?: ProjectScopeMode;\n projectHash?: string;\n allowedProjectHashes?: string[];\n}\n\nexport interface RetrievalResult {\n memories: MemoryWithContext[];\n matchResult: MatchResult;\n totalTokens: number;\n context: string;\n fallbackTrace?: string[];\n selectedDebug?: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n candidateDebug?: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n}\n\nexport interface MemoryWithContext {\n event: MemoryEvent;\n score: number;\n sessionContext?: string;\n}\n\nexport interface UnifiedRetrievalOptions extends RetrievalOptions {\n includeShared?: boolean;\n projectHash?: string;\n}\n\nexport interface UnifiedRetrievalResult extends RetrievalResult {\n sharedMemories?: SharedTroubleshootingEntry[];\n}\n\nconst DEFAULT_OPTIONS: RetrievalOptions = {\n topK: 5,\n minScore: 0.7,\n maxTokens: 2000,\n includeSessionContext: true,\n strategy: 'auto',\n rerankWithKeyword: true,\n decayPolicy: {\n enabled: true,\n windowDays: 30,\n maxPenalty: 0.15\n },\n graphHop: {\n enabled: true,\n maxHops: 1,\n hopPenalty: 0.08\n },\n projectScopeMode: 'global'\n};\n\nexport interface SharedStoreOptions {\n sharedStore?: SharedStore;\n sharedVectorStore?: SharedVectorStore;\n}\n\ntype EventStoreLike = EventStore & {\n keywordSearch?: (query: string, limit?: number) => Promise<Array<{ event: MemoryEvent; rank: number }>>;\n};\n\nexport class Retriever {\n private readonly eventStore: EventStoreLike;\n private readonly vectorStore: VectorStore;\n private readonly embedder: Embedder;\n private readonly matcher: Matcher;\n private sharedStore?: SharedStore;\n private sharedVectorStore?: SharedVectorStore;\n private graduation?: GraduationPipeline;\n private queryRewriter?: (query: string) => Promise<string | null>;\n\n constructor(\n eventStore: EventStore,\n vectorStore: VectorStore,\n embedder: Embedder,\n matcher: Matcher,\n sharedOptions?: SharedStoreOptions\n ) {\n this.eventStore = eventStore as EventStoreLike;\n this.vectorStore = vectorStore;\n this.embedder = embedder;\n this.matcher = matcher;\n this.sharedStore = sharedOptions?.sharedStore;\n this.sharedVectorStore = sharedOptions?.sharedVectorStore;\n }\n\n setGraduationPipeline(graduation: GraduationPipeline): void {\n this.graduation = graduation;\n }\n\n setSharedStores(sharedStore: SharedStore, sharedVectorStore: SharedVectorStore): void {\n this.sharedStore = sharedStore;\n this.sharedVectorStore = sharedVectorStore;\n }\n\n setQueryRewriter(rewriter: (query: string) => Promise<string | null>): void {\n this.queryRewriter = rewriter;\n }\n\n async retrieve(\n query: string,\n options: Partial<RetrievalOptions> = {}\n ): Promise<RetrievalResult> {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const sessionFilter = opts.scope?.sessionId ?? opts.sessionId;\n const fallbackTrace: string[] = [];\n\n const fallbackEnabled = (opts.strategy ?? 'auto') === 'auto';\n\n // Stage 1: primary retrieval\n const primaryStrategy: RetrievalStrategy = opts.strategy === 'auto' ? 'fast' : (opts.strategy || 'fast');\n let current = await this.runStage(query, {\n strategy: primaryStrategy,\n topK: opts.topK,\n minScore: opts.minScore,\n sessionId: sessionFilter,\n scope: opts.scope,\n rerankWithKeyword: opts.rerankWithKeyword !== false,\n rerankWeights: opts.rerankWeights,\n decayPolicy: opts.decayPolicy,\n intentRewrite: opts.intentRewrite === true,\n graphHop: opts.graphHop,\n projectScopeMode: opts.projectScopeMode,\n projectHash: opts.projectHash,\n allowedProjectHashes: opts.allowedProjectHashes\n });\n fallbackTrace.push(`stage:primary:${primaryStrategy}`);\n\n // Stage 2: deep fallback\n if (fallbackEnabled && this.shouldFallback(current.matchResult, current.results) && primaryStrategy !== 'deep') {\n current = await this.runStage(query, {\n strategy: 'deep',\n topK: opts.topK,\n minScore: opts.minScore,\n sessionId: sessionFilter,\n scope: opts.scope,\n rerankWithKeyword: opts.rerankWithKeyword !== false,\n rerankWeights: opts.rerankWeights,\n decayPolicy: opts.decayPolicy,\n graphHop: opts.graphHop,\n projectScopeMode: opts.projectScopeMode,\n projectHash: opts.projectHash,\n allowedProjectHashes: opts.allowedProjectHashes\n });\n fallbackTrace.push('fallback:deep');\n }\n\n // Stage 3: scope-expanded deep fallback\n if (fallbackEnabled && this.shouldFallback(current.matchResult, current.results)) {\n current = await this.runStage(query, {\n strategy: 'deep',\n topK: opts.topK,\n minScore: Math.max(0.5, opts.minScore - 0.15),\n sessionId: undefined,\n scope: undefined,\n rerankWithKeyword: true,\n rerankWeights: opts.rerankWeights,\n decayPolicy: opts.decayPolicy,\n graphHop: opts.graphHop,\n projectScopeMode: opts.projectScopeMode,\n projectHash: opts.projectHash,\n allowedProjectHashes: opts.allowedProjectHashes\n });\n fallbackTrace.push('fallback:scope-expanded');\n }\n\n // Stage 4: summary fallback\n if (fallbackEnabled && this.shouldFallback(current.matchResult, current.results)) {\n const summary = await this.buildSummaryFallback(query, opts.topK);\n current = {\n results: summary,\n candidateResults: summary,\n matchResult: this.matcher.matchSearchResults(summary, () => 0)\n };\n fallbackTrace.push('fallback:summary');\n }\n\n const memories = await this.enrichResults(current.results.slice(0, opts.topK), opts as RetrievalOptions);\n const context = this.buildContext(memories, opts.maxTokens);\n\n return {\n memories,\n matchResult: current.matchResult,\n totalTokens: this.estimateTokens(context),\n context,\n fallbackTrace,\n selectedDebug: current.results.slice(0, opts.topK).map((r: SearchResult & { semanticScore?: number; lexicalScore?: number; recencyScore?: number }) => ({\n eventId: r.eventId,\n score: r.score,\n semanticScore: r.semanticScore,\n lexicalScore: r.lexicalScore,\n recencyScore: r.recencyScore,\n })),\n candidateDebug: (current.candidateResults || []).slice(0, Math.max(opts.topK * 3, 20)).map((r: SearchResult & { semanticScore?: number; lexicalScore?: number; recencyScore?: number }) => ({\n eventId: r.eventId,\n score: r.score,\n semanticScore: r.semanticScore,\n lexicalScore: r.lexicalScore,\n recencyScore: r.recencyScore,\n }))\n };\n }\n\n async retrieveUnified(\n query: string,\n options: Partial<UnifiedRetrievalOptions> = {}\n ): Promise<UnifiedRetrievalResult> {\n const projectResult = await this.retrieve(query, options);\n\n if (!options.includeShared || !this.sharedStore || !this.sharedVectorStore) {\n return projectResult;\n }\n\n try {\n const queryEmbedding = await this.embedder.embed(query);\n const sharedVectorResults = await this.sharedVectorStore.search(queryEmbedding.vector, {\n limit: options.topK || 5,\n minScore: options.minScore || 0.7,\n excludeProjectHash: options.projectHash\n });\n\n const sharedMemories: SharedTroubleshootingEntry[] = [];\n for (const result of sharedVectorResults) {\n const entry = await this.sharedStore.get(result.entryId);\n if (!entry) continue;\n if (!options.projectHash || entry.sourceProjectHash !== options.projectHash) {\n sharedMemories.push(entry);\n await this.sharedStore.recordUsage(entry.entryId);\n }\n }\n\n const unifiedContext = this.buildUnifiedContext(projectResult, sharedMemories);\n return {\n ...projectResult,\n context: unifiedContext,\n totalTokens: this.estimateTokens(unifiedContext),\n sharedMemories\n };\n } catch (error) {\n console.error('Shared search failed:', error);\n return projectResult;\n }\n }\n\n private async runStage(\n query: string,\n input: {\n strategy: RetrievalStrategy;\n topK: number;\n minScore: number;\n sessionId?: string;\n scope?: RetrievalScope;\n rerankWithKeyword: boolean;\n rerankWeights?: {\n semantic?: number;\n lexical?: number;\n recency?: number;\n };\n decayPolicy?: {\n enabled?: boolean;\n windowDays?: number;\n maxPenalty?: number;\n };\n intentRewrite?: boolean;\n graphHop?: {\n enabled?: boolean;\n maxHops?: number;\n hopPenalty?: number;\n };\n projectScopeMode?: ProjectScopeMode;\n projectHash?: string;\n allowedProjectHashes?: string[];\n }\n ): Promise<{ results: SearchResult[]; matchResult: MatchResult }> {\n let initialResults = await this.searchByStrategy(query, {\n strategy: input.strategy,\n topK: input.topK,\n minScore: input.minScore,\n sessionId: input.sessionId\n });\n\n if (input.intentRewrite && input.strategy === 'deep' && this.queryRewriter) {\n const rewritten = (await this.queryRewriter(query))?.trim();\n if (rewritten && rewritten !== query) {\n const rewrittenResults = await this.searchByStrategy(rewritten, {\n strategy: 'deep',\n topK: input.topK,\n minScore: Math.max(0.5, input.minScore - 0.1),\n sessionId: input.sessionId\n });\n initialResults = this.mergeResults(initialResults, rewrittenResults, input.topK * 3);\n }\n }\n\n const expandedResults = input.graphHop?.enabled === false\n ? initialResults\n : await this.expandGraphHops(initialResults, {\n maxHops: Math.max(1, input.graphHop?.maxHops ?? 1),\n hopPenalty: Math.max(0, input.graphHop?.hopPenalty ?? 0.08),\n limit: input.topK * 4,\n });\n\n const rerankedResults = input.rerankWithKeyword\n ? this.rerankByKeywordOverlap(expandedResults, query, input.rerankWeights, input.decayPolicy)\n : expandedResults;\n\n const filtered = await this.applyScopeFilters(rerankedResults, {\n scope: input.scope,\n projectScopeMode: input.projectScopeMode,\n projectHash: input.projectHash,\n allowedProjectHashes: input.allowedProjectHashes\n });\n const top = filtered.slice(0, input.topK);\n const matchResult = this.matcher.matchSearchResults(top, () => 0);\n\n return { results: top, candidateResults: filtered, matchResult };\n }\n\n private mergeResults(primary: SearchResult[], secondary: SearchResult[], limit: number): SearchResult[] {\n const byId = new Map<string, SearchResult>();\n for (const row of primary) byId.set(row.eventId, row);\n for (const row of secondary) {\n const prev = byId.get(row.eventId);\n if (!prev || row.score > prev.score) {\n byId.set(row.eventId, row);\n }\n }\n return [...byId.values()].sort((a, b) => b.score - a.score).slice(0, limit);\n }\n\n private async expandGraphHops(\n seeds: SearchResult[],\n opts: { maxHops: number; hopPenalty: number; limit: number }\n ): Promise<SearchResult[]> {\n const byId = new Map<string, SearchResult>();\n for (const s of seeds) byId.set(s.eventId, s);\n\n let frontier = seeds.map((s) => ({ row: s, hop: 0 }));\n\n for (let hop = 1; hop <= opts.maxHops; hop += 1) {\n const next: Array<{ row: SearchResult; hop: number }> = [];\n\n for (const f of frontier) {\n const ev = await this.eventStore.getEvent(f.row.eventId);\n if (!ev) continue;\n const rel = ((ev.metadata as Record<string, unknown> | undefined)?.relatedEventIds ?? []) as unknown;\n const relatedIds = Array.isArray(rel)\n ? rel.filter((x): x is string => typeof x === 'string')\n : [];\n\n for (const rid of relatedIds) {\n if (byId.has(rid)) continue;\n const target = await this.eventStore.getEvent(rid);\n if (!target) continue;\n\n const score = Math.max(0, f.row.score - opts.hopPenalty * hop);\n const row: SearchResult = {\n id: `hop-${hop}-${rid}`,\n eventId: target.id,\n content: target.content,\n score,\n sessionId: target.sessionId,\n eventType: target.eventType,\n timestamp: target.timestamp.toISOString(),\n };\n\n byId.set(row.eventId, row);\n next.push({ row, hop });\n if (byId.size >= opts.limit) break;\n }\n if (byId.size >= opts.limit) break;\n }\n\n frontier = next;\n if (frontier.length === 0 || byId.size >= opts.limit) break;\n }\n\n return [...byId.values()].sort((a, b) => b.score - a.score).slice(0, opts.limit);\n }\n\n private shouldFallback(matchResult: MatchResult, results: SearchResult[]): boolean {\n if (results.length === 0) return true;\n if (matchResult.confidence === 'none') return true;\n return false;\n }\n\n private async buildSummaryFallback(query: string, topK: number): Promise<SearchResult[]> {\n const recent = await this.eventStore.getRecentEvents(Math.max(topK * 6, 20));\n const q = this.tokenize(query);\n\n const ranked = recent\n .map((e) => ({ e, overlap: this.keywordOverlap(q, this.tokenize(e.content)) }))\n .filter((r) => r.overlap > 0)\n .sort((a, b) => b.overlap - a.overlap)\n .slice(0, topK)\n .map((row, idx) => ({\n id: `summary-${row.e.id}`,\n eventId: row.e.id,\n content: row.e.content,\n score: Math.max(0.25, 0.6 - idx * 0.05),\n sessionId: row.e.sessionId,\n eventType: row.e.eventType,\n timestamp: row.e.timestamp.toISOString()\n }));\n\n return ranked;\n }\n\n private async searchByStrategy(\n query: string,\n input: { strategy: RetrievalStrategy; topK: number; minScore: number; sessionId?: string }\n ): Promise<SearchResult[]> {\n const strategy = input.strategy === 'auto' ? 'deep' : input.strategy;\n\n if (strategy === 'fast') {\n const keyword = await this.searchByKeyword(query, {\n limit: Math.max(5, input.topK * 3),\n sessionId: input.sessionId\n });\n return keyword;\n }\n\n const queryEmbedding = await this.embedder.embed(query);\n return this.vectorStore.search(queryEmbedding.vector, {\n limit: Math.max(5, input.topK * 3),\n minScore: input.minScore,\n sessionId: input.sessionId\n });\n }\n\n private async searchByKeyword(\n query: string,\n input: { limit: number; sessionId?: string }\n ): Promise<SearchResult[]> {\n if (this.eventStore.keywordSearch) {\n const rows = await this.eventStore.keywordSearch(query, input.limit);\n const filtered = input.sessionId ? rows.filter((r) => r.event.sessionId === input.sessionId) : rows;\n return filtered.map((row, idx) => ({\n id: `kw-${row.event.id}`,\n eventId: row.event.id,\n content: row.event.content,\n score: Math.max(0.4, 1 - idx * 0.04),\n sessionId: row.event.sessionId,\n eventType: row.event.eventType,\n timestamp: row.event.timestamp.toISOString()\n }));\n }\n\n const recent = await this.eventStore.getRecentEvents(input.limit * 4);\n const tokens = this.tokenize(query);\n const filtered = recent\n .filter((e) => (input.sessionId ? e.sessionId === input.sessionId : true))\n .map((e) => ({ e, overlap: this.keywordOverlap(tokens, this.tokenize(e.content)) }))\n .filter((r) => r.overlap > 0)\n .sort((a, b) => b.overlap - a.overlap)\n .slice(0, input.limit);\n\n return filtered.map((row, idx) => ({\n id: `kw-fallback-${row.e.id}`,\n eventId: row.e.id,\n content: row.e.content,\n score: Math.max(0.3, 0.9 - idx * 0.05),\n sessionId: row.e.sessionId,\n eventType: row.e.eventType,\n timestamp: row.e.timestamp.toISOString()\n }));\n }\n\n private rerankByKeywordOverlap(\n results: SearchResult[],\n query: string,\n weights?: { semantic?: number; lexical?: number; recency?: number },\n decayPolicy?: { enabled?: boolean; windowDays?: number; maxPenalty?: number }\n ): SearchResult[] {\n const q = this.tokenize(query);\n const now = Date.now();\n\n const sw = Math.max(0, weights?.semantic ?? 0.7);\n const lw = Math.max(0, weights?.lexical ?? 0.2);\n const rw = Math.max(0, weights?.recency ?? 0.1);\n const total = sw + lw + rw || 1;\n\n const decayEnabled = decayPolicy?.enabled !== false;\n const decayWindow = Math.max(1, decayPolicy?.windowDays ?? 30);\n const decayMaxPenalty = Math.max(0, decayPolicy?.maxPenalty ?? 0.15);\n\n return [...results]\n .map((r) => {\n const overlap = this.keywordOverlap(q, this.tokenize(r.content));\n const recencyDays = Math.max(0, (now - new Date(r.timestamp).getTime()) / (1000 * 60 * 60 * 24));\n const recency = Math.max(0, 1 - recencyDays / decayWindow);\n let blended = (r.score * sw + overlap * lw + recency * rw) / total;\n\n if (decayEnabled && recencyDays > decayWindow && overlap < 0.5) {\n const ageFactor = Math.min(1, (recencyDays - decayWindow) / decayWindow);\n blended -= decayMaxPenalty * ageFactor;\n }\n\n return { ...r, score: Math.max(0, blended), semanticScore: r.score, lexicalScore: overlap, recencyScore: recency };\n })\n .sort((a, b) => b.score - a.score);\n }\n\n private async applyScopeFilters(\n results: SearchResult[],\n options?: {\n scope?: RetrievalScope;\n projectScopeMode?: ProjectScopeMode;\n projectHash?: string;\n allowedProjectHashes?: string[];\n }\n ): Promise<SearchResult[]> {\n const scope = options?.scope;\n const projectScopeMode = options?.projectScopeMode ?? 'global';\n const allowedProjectHashes = new Set(\n [options?.projectHash, ...(options?.allowedProjectHashes || [])].filter(\n (value): value is string => typeof value === 'string' && value.length > 0\n )\n );\n\n if (!scope && projectScopeMode === 'global') return results;\n\n const normalizedIncludes = (scope?.contentIncludes || []).map((s) => s.toLowerCase());\n const filtered: Array<{ result: SearchResult; projectHash?: string }> = [];\n\n for (const result of results) {\n if (scope?.sessionId && result.sessionId !== scope.sessionId) continue;\n if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix)) continue;\n if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType as MemoryEvent['eventType'])) continue;\n\n const event = await this.eventStore.getEvent(result.eventId);\n if (!event) continue;\n\n if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix)) continue;\n if (normalizedIncludes.length > 0) {\n const lc = event.content.toLowerCase();\n if (!normalizedIncludes.some((needle) => lc.includes(needle))) continue;\n }\n if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata)) continue;\n\n const projectHash = this.extractProjectHash(event.metadata);\n filtered.push({ result, projectHash });\n }\n\n if (projectScopeMode === 'global' || allowedProjectHashes.size === 0) {\n return filtered.map((x) => x.result);\n }\n\n const projectMatched = filtered.filter((x) => x.projectHash && allowedProjectHashes.has(x.projectHash));\n\n if (projectScopeMode === 'strict') {\n return projectMatched.map((x) => x.result);\n }\n\n return (projectMatched.length > 0 ? projectMatched : filtered).map((x) => x.result);\n }\n\n private extractProjectHash(metadata: Record<string, unknown> | undefined): string | undefined {\n if (!metadata || typeof metadata !== 'object') return undefined;\n const scope = metadata.scope;\n if (!scope || typeof scope !== 'object') return undefined;\n const project = (scope as Record<string, unknown>).project;\n if (!project || typeof project !== 'object') return undefined;\n const hash = (project as Record<string, unknown>).hash;\n return typeof hash === 'string' && hash.length > 0 ? hash : undefined;\n }\n\n async retrieveFromSession(sessionId: string): Promise<MemoryEvent[]> {\n return this.eventStore.getSessionEvents(sessionId);\n }\n\n async retrieveRecent(limit: number = 100): Promise<MemoryEvent[]> {\n return this.eventStore.getRecentEvents(limit);\n }\n\n private async enrichResults(results: SearchResult[], options: RetrievalOptions): Promise<MemoryWithContext[]> {\n const memories: MemoryWithContext[] = [];\n\n for (const result of results) {\n const event = await this.eventStore.getEvent(result.eventId);\n if (!event) continue;\n\n if (this.graduation) {\n this.graduation.recordAccess(event.id, options.sessionId || 'unknown', result.score);\n }\n\n let sessionContext: string | undefined;\n if (options.includeSessionContext) {\n sessionContext = await this.getSessionContext(event.sessionId, event.id);\n }\n\n memories.push({ event, score: result.score, sessionContext });\n }\n\n return memories;\n }\n\n private async getSessionContext(sessionId: string, eventId: string): Promise<string | undefined> {\n const sessionEvents = await this.eventStore.getSessionEvents(sessionId);\n const eventIndex = sessionEvents.findIndex(e => e.id === eventId);\n if (eventIndex === -1) return undefined;\n\n const start = Math.max(0, eventIndex - 1);\n const end = Math.min(sessionEvents.length, eventIndex + 2);\n const contextEvents = sessionEvents.slice(start, end);\n if (contextEvents.length <= 1) return undefined;\n\n return contextEvents\n .filter(e => e.id !== eventId)\n .map(e => `[${e.eventType}]: ${e.content.slice(0, 200)}...`)\n .join('\\n');\n }\n\n private buildUnifiedContext(projectResult: RetrievalResult, sharedMemories: SharedTroubleshootingEntry[]): string {\n let context = projectResult.context;\n if (sharedMemories.length === 0) return context;\n\n context += '\\n\\n## Cross-Project Knowledge\\n\\n';\n for (const memory of sharedMemories.slice(0, 3)) {\n context += `### ${memory.title}\\n`;\n if (memory.symptoms.length > 0) context += `**Symptoms:** ${memory.symptoms.join(', ')}\\n`;\n context += `**Root Cause:** ${memory.rootCause}\\n`;\n context += `**Solution:** ${memory.solution}\\n`;\n if (memory.technologies && memory.technologies.length > 0) context += `**Technologies:** ${memory.technologies.join(', ')}\\n`;\n context += `_Confidence: ${(memory.confidence * 100).toFixed(0)}%_\\n\\n`;\n }\n\n return context;\n }\n\n private buildContext(memories: MemoryWithContext[], maxTokens: number): string {\n const parts: string[] = [];\n let currentTokens = 0;\n\n for (const memory of memories) {\n const memoryText = this.formatMemory(memory);\n const memoryTokens = this.estimateTokens(memoryText);\n if (currentTokens + memoryTokens > maxTokens) break;\n parts.push(memoryText);\n currentTokens += memoryTokens;\n }\n\n if (parts.length === 0) return '';\n return `## Relevant Memories\\n\\n${parts.join('\\n\\n---\\n\\n')}`;\n }\n\n private formatMemory(memory: MemoryWithContext): string {\n const { event, score, sessionContext } = memory;\n const date = event.timestamp.toISOString().split('T')[0];\n\n let text = `**${event.eventType}** (${date}, score: ${score.toFixed(2)})\\n${event.content}`;\n if (sessionContext) text += `\\n\\n_Context:_ ${sessionContext}`;\n return text;\n }\n\n private matchesMetadataScope(\n metadata: Record<string, unknown> | undefined,\n expected: Record<string, unknown>\n ): boolean {\n if (!metadata) return false;\n\n return Object.entries(expected).every(([path, value]) => {\n const actual = path.split('.').reduce<unknown>((acc, key) => {\n if (typeof acc !== 'object' || acc === null) return undefined;\n return (acc as Record<string, unknown>)[key];\n }, metadata);\n\n return actual === value;\n });\n }\n\n private tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s]/gu, ' ')\n .split(/\\s+/)\n .filter((t) => t.length >= 2)\n .slice(0, 64);\n }\n\n private keywordOverlap(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n const bs = new Set(b);\n let hit = 0;\n for (const t of a) if (bs.has(t)) hit += 1;\n return hit / a.length;\n }\n\n private estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n }\n}\n\nexport function createRetriever(\n eventStore: EventStore,\n vectorStore: VectorStore,\n embedder: Embedder,\n matcher: Matcher\n): Retriever {\n return new Retriever(eventStore, vectorStore, embedder, matcher);\n}\n", "/**\n * Memory Graduation Pipeline - AXIOMMIND L0\u2192L1\u2192L2\u2192L3\u2192L4\n *\n * L0: EventStore (raw events, append-only)\n * L1: Structured JSON (session summaries, patterns)\n * L2: Type Candidates (Idris2-inspired, validated schemas)\n * L3: Verified Knowledge (cross-session validated)\n * L4: Active/Searchable (indexed, readily available)\n */\n\nimport { EventStore } from './event-store.js';\nimport type {\n MemoryEvent,\n MemoryLevel,\n GraduationResult,\n Insight,\n InsightType\n} from './types.js';\n\nexport interface GraduationCriteria {\n minAccessCount: number;\n minConfidence: number;\n minCrossSessionRefs: number;\n maxAgeDays: number;\n}\n\nexport interface LevelCriteria {\n L0toL1: GraduationCriteria;\n L1toL2: GraduationCriteria;\n L2toL3: GraduationCriteria;\n L3toL4: GraduationCriteria;\n}\n\nconst DEFAULT_CRITERIA: LevelCriteria = {\n L0toL1: {\n minAccessCount: 1,\n minConfidence: 0.5,\n minCrossSessionRefs: 0,\n maxAgeDays: 30\n },\n L1toL2: {\n minAccessCount: 3,\n minConfidence: 0.7,\n minCrossSessionRefs: 1,\n maxAgeDays: 60\n },\n L2toL3: {\n minAccessCount: 5,\n minConfidence: 0.85,\n minCrossSessionRefs: 2,\n maxAgeDays: 90\n },\n L3toL4: {\n minAccessCount: 10,\n minConfidence: 0.92,\n minCrossSessionRefs: 3,\n maxAgeDays: 180\n }\n};\n\nexport interface EventMetrics {\n eventId: string;\n accessCount: number;\n lastAccessed: Date;\n crossSessionRefs: number;\n confidence: number;\n}\n\nexport class GraduationPipeline {\n private readonly eventStore: EventStore;\n private readonly criteria: LevelCriteria;\n private readonly metrics: Map<string, EventMetrics> = new Map();\n\n constructor(\n eventStore: EventStore,\n criteria: Partial<LevelCriteria> = {}\n ) {\n this.eventStore = eventStore;\n this.criteria = {\n L0toL1: { ...DEFAULT_CRITERIA.L0toL1, ...criteria.L0toL1 },\n L1toL2: { ...DEFAULT_CRITERIA.L1toL2, ...criteria.L1toL2 },\n L2toL3: { ...DEFAULT_CRITERIA.L2toL3, ...criteria.L2toL3 },\n L3toL4: { ...DEFAULT_CRITERIA.L3toL4, ...criteria.L3toL4 }\n };\n }\n\n // Track which sessions have accessed each event\n private readonly sessionAccesses: Map<string, Set<string>> = new Map();\n\n /**\n * Record an access to an event (used for graduation scoring)\n */\n recordAccess(eventId: string, fromSessionId: string, confidence: number = 1.0): void {\n const existing = this.metrics.get(eventId);\n\n // Track sessions that have accessed this event\n if (!this.sessionAccesses.has(eventId)) {\n this.sessionAccesses.set(eventId, new Set());\n }\n const sessions = this.sessionAccesses.get(eventId)!;\n const isNewSession = !sessions.has(fromSessionId);\n sessions.add(fromSessionId);\n\n if (existing) {\n existing.accessCount++;\n existing.lastAccessed = new Date();\n existing.confidence = Math.max(existing.confidence, confidence);\n // Update cross-session references count\n if (isNewSession && sessions.size > 1) {\n existing.crossSessionRefs = sessions.size - 1;\n }\n } else {\n this.metrics.set(eventId, {\n eventId,\n accessCount: 1,\n lastAccessed: new Date(),\n crossSessionRefs: 0,\n confidence\n });\n }\n }\n\n /**\n * Evaluate if an event should graduate to the next level\n */\n async evaluateGraduation(eventId: string, currentLevel: MemoryLevel): Promise<GraduationResult> {\n const metrics = this.metrics.get(eventId);\n\n if (!metrics) {\n return {\n eventId,\n fromLevel: currentLevel,\n toLevel: currentLevel,\n success: false,\n reason: 'No metrics available for event'\n };\n }\n\n const nextLevel = this.getNextLevel(currentLevel);\n if (!nextLevel) {\n return {\n eventId,\n fromLevel: currentLevel,\n toLevel: currentLevel,\n success: false,\n reason: 'Already at maximum level'\n };\n }\n\n const criteria = this.getCriteria(currentLevel, nextLevel);\n const evaluation = this.checkCriteria(metrics, criteria);\n\n if (evaluation.passed) {\n // Update level in event store\n await this.eventStore.updateMemoryLevel(eventId, nextLevel);\n\n return {\n eventId,\n fromLevel: currentLevel,\n toLevel: nextLevel,\n success: true\n };\n }\n\n return {\n eventId,\n fromLevel: currentLevel,\n toLevel: currentLevel,\n success: false,\n reason: evaluation.reason\n };\n }\n\n /**\n * Run graduation evaluation for all events at a given level\n */\n async graduateBatch(level: MemoryLevel): Promise<GraduationResult[]> {\n const results: GraduationResult[] = [];\n\n for (const [eventId, metrics] of this.metrics) {\n const result = await this.evaluateGraduation(eventId, level);\n results.push(result);\n }\n\n return results;\n }\n\n /**\n * Extract insights from graduated events (L1+)\n */\n extractInsights(events: MemoryEvent[]): Insight[] {\n const insights: Insight[] = [];\n\n // Pattern detection: Look for repeated themes\n const patterns = this.detectPatterns(events);\n for (const pattern of patterns) {\n insights.push({\n id: crypto.randomUUID(),\n insightType: 'pattern',\n content: pattern.description,\n canonicalKey: pattern.key,\n confidence: pattern.confidence,\n sourceEvents: pattern.eventIds,\n createdAt: new Date(),\n lastUpdated: new Date()\n });\n }\n\n // Preference detection: Look for user preferences\n const preferences = this.detectPreferences(events);\n for (const pref of preferences) {\n insights.push({\n id: crypto.randomUUID(),\n insightType: 'preference',\n content: pref.description,\n canonicalKey: pref.key,\n confidence: pref.confidence,\n sourceEvents: pref.eventIds,\n createdAt: new Date(),\n lastUpdated: new Date()\n });\n }\n\n return insights;\n }\n\n /**\n * Get the next level in the graduation pipeline\n */\n private getNextLevel(current: MemoryLevel): MemoryLevel | null {\n const levels: MemoryLevel[] = ['L0', 'L1', 'L2', 'L3', 'L4'];\n const currentIndex = levels.indexOf(current);\n\n if (currentIndex === -1 || currentIndex >= levels.length - 1) {\n return null;\n }\n\n return levels[currentIndex + 1];\n }\n\n /**\n * Get criteria for level transition\n */\n private getCriteria(from: MemoryLevel, to: MemoryLevel): GraduationCriteria {\n const key = `${from}to${to}` as keyof LevelCriteria;\n return this.criteria[key] || DEFAULT_CRITERIA.L0toL1;\n }\n\n /**\n * Check if metrics meet criteria\n */\n private checkCriteria(\n metrics: EventMetrics,\n criteria: GraduationCriteria\n ): { passed: boolean; reason?: string } {\n if (metrics.accessCount < criteria.minAccessCount) {\n return {\n passed: false,\n reason: `Access count ${metrics.accessCount} < ${criteria.minAccessCount}`\n };\n }\n\n if (metrics.confidence < criteria.minConfidence) {\n return {\n passed: false,\n reason: `Confidence ${metrics.confidence} < ${criteria.minConfidence}`\n };\n }\n\n if (metrics.crossSessionRefs < criteria.minCrossSessionRefs) {\n return {\n passed: false,\n reason: `Cross-session refs ${metrics.crossSessionRefs} < ${criteria.minCrossSessionRefs}`\n };\n }\n\n const ageDays = (Date.now() - metrics.lastAccessed.getTime()) / (1000 * 60 * 60 * 24);\n if (ageDays > criteria.maxAgeDays) {\n return {\n passed: false,\n reason: `Event too old: ${ageDays.toFixed(1)} days > ${criteria.maxAgeDays}`\n };\n }\n\n return { passed: true };\n }\n\n /**\n * Detect patterns in events\n */\n private detectPatterns(events: MemoryEvent[]): Array<{\n key: string;\n description: string;\n confidence: number;\n eventIds: string[];\n }> {\n // Simple pattern detection: group by canonical key and look for repeats\n const keyGroups = new Map<string, MemoryEvent[]>();\n\n for (const event of events) {\n const existing = keyGroups.get(event.canonicalKey) || [];\n existing.push(event);\n keyGroups.set(event.canonicalKey, existing);\n }\n\n const patterns: Array<{\n key: string;\n description: string;\n confidence: number;\n eventIds: string[];\n }> = [];\n\n for (const [key, groupEvents] of keyGroups) {\n if (groupEvents.length >= 2) {\n patterns.push({\n key,\n description: `Repeated topic: ${key.slice(0, 50)}`,\n confidence: Math.min(1.0, groupEvents.length / 5),\n eventIds: groupEvents.map(e => e.id)\n });\n }\n }\n\n return patterns;\n }\n\n /**\n * Detect user preferences from events\n */\n private detectPreferences(events: MemoryEvent[]): Array<{\n key: string;\n description: string;\n confidence: number;\n eventIds: string[];\n }> {\n // Simple preference detection: look for keywords\n const preferenceKeywords = ['prefer', 'like', 'want', 'always', 'never', 'favorite'];\n const preferences: Array<{\n key: string;\n description: string;\n confidence: number;\n eventIds: string[];\n }> = [];\n\n for (const event of events) {\n if (event.eventType !== 'user_prompt') continue;\n\n const lowerContent = event.content.toLowerCase();\n for (const keyword of preferenceKeywords) {\n if (lowerContent.includes(keyword)) {\n preferences.push({\n key: `preference_${keyword}_${event.id.slice(0, 8)}`,\n description: `User preference: ${event.content.slice(0, 100)}`,\n confidence: 0.7,\n eventIds: [event.id]\n });\n break;\n }\n }\n }\n\n return preferences;\n }\n\n /**\n * Get graduation statistics\n */\n async getStats(): Promise<{ level: string; count: number }[]> {\n return this.eventStore.getLevelStats();\n }\n}\n\n/**\n * Create graduation pipeline with default settings\n */\nexport function createGraduationPipeline(eventStore: EventStore): GraduationPipeline {\n return new GraduationPipeline(eventStore);\n}\n", "/**\n * SharedEventStore - Global database for cross-project knowledge\n * Location: ~/.claude-code/memory/shared/\n */\n\nimport {\n createDatabase,\n dbRun,\n dbClose,\n type Database\n} from './db-wrapper.js';\n\nexport class SharedEventStore {\n private db: Database;\n private initialized = false;\n\n constructor(private dbPath: string) {\n this.db = createDatabase(dbPath);\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Shared troubleshooting entries table\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS shared_troubleshooting (\n entry_id VARCHAR PRIMARY KEY,\n source_project_hash VARCHAR NOT NULL,\n source_entry_id VARCHAR NOT NULL,\n title VARCHAR NOT NULL,\n symptoms JSON NOT NULL,\n root_cause TEXT NOT NULL,\n solution TEXT NOT NULL,\n topics JSON NOT NULL,\n technologies JSON,\n confidence REAL NOT NULL DEFAULT 0.8,\n usage_count INTEGER DEFAULT 0,\n last_used_at TIMESTAMP,\n promoted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n UNIQUE(source_project_hash, source_entry_id)\n )\n `);\n\n // Future extensibility: best practices table\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS shared_best_practices (\n entry_id VARCHAR PRIMARY KEY,\n source_project_hash VARCHAR NOT NULL,\n source_entry_id VARCHAR NOT NULL,\n title VARCHAR NOT NULL,\n content_json JSON NOT NULL,\n topics JSON NOT NULL,\n confidence REAL NOT NULL DEFAULT 0.8,\n usage_count INTEGER DEFAULT 0,\n promoted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n UNIQUE(source_project_hash, source_entry_id)\n )\n `);\n\n // Future extensibility: common errors table\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS shared_common_errors (\n entry_id VARCHAR PRIMARY KEY,\n source_project_hash VARCHAR NOT NULL,\n source_entry_id VARCHAR NOT NULL,\n title VARCHAR NOT NULL,\n error_pattern TEXT NOT NULL,\n solution TEXT NOT NULL,\n topics JSON NOT NULL,\n technologies JSON,\n confidence REAL NOT NULL DEFAULT 0.8,\n usage_count INTEGER DEFAULT 0,\n promoted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n UNIQUE(source_project_hash, source_entry_id)\n )\n `);\n\n // Indexes for troubleshooting\n await dbRun(this.db, `\n CREATE INDEX IF NOT EXISTS idx_shared_ts_confidence\n ON shared_troubleshooting(confidence DESC)\n `);\n await dbRun(this.db, `\n CREATE INDEX IF NOT EXISTS idx_shared_ts_usage\n ON shared_troubleshooting(usage_count DESC)\n `);\n await dbRun(this.db, `\n CREATE INDEX IF NOT EXISTS idx_shared_ts_source\n ON shared_troubleshooting(source_project_hash)\n `);\n\n this.initialized = true;\n }\n\n getDatabase(): Database {\n return this.db;\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n async close(): Promise<void> {\n await dbClose(this.db);\n this.initialized = false;\n }\n}\n\nexport function createSharedEventStore(dbPath: string): SharedEventStore {\n return new SharedEventStore(dbPath);\n}\n", "/**\n * SharedStore - Cross-project troubleshooting knowledge store\n * Manages promotion from verified entries to shared storage\n */\n\nimport { randomUUID } from 'crypto';\nimport { dbRun, dbAll, toDate, type Database } from './db-wrapper.js';\nimport type {\n SharedTroubleshootingEntry,\n SharedTroubleshootingInput\n} from './types.js';\nimport { SharedEventStore } from './shared-event-store.js';\n\nexport class SharedStore {\n constructor(private sharedEventStore: SharedEventStore) {}\n\n private get db(): Database {\n return this.sharedEventStore.getDatabase();\n }\n\n /**\n * Promote a verified troubleshooting entry to shared storage\n */\n async promoteEntry(\n input: SharedTroubleshootingInput\n ): Promise<string> {\n const entryId = randomUUID();\n\n await dbRun(\n this.db,\n `INSERT INTO shared_troubleshooting (\n entry_id, source_project_hash, source_entry_id,\n title, symptoms, root_cause, solution, topics,\n technologies, confidence, promoted_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)\n ON CONFLICT (source_project_hash, source_entry_id)\n DO UPDATE SET\n title = excluded.title,\n symptoms = excluded.symptoms,\n root_cause = excluded.root_cause,\n solution = excluded.solution,\n topics = excluded.topics,\n technologies = excluded.technologies,\n confidence = CASE\n WHEN excluded.confidence > shared_troubleshooting.confidence\n THEN excluded.confidence\n ELSE shared_troubleshooting.confidence\n END`,\n [\n entryId,\n input.sourceProjectHash,\n input.sourceEntryId,\n input.title,\n JSON.stringify(input.symptoms),\n input.rootCause,\n input.solution,\n JSON.stringify(input.topics),\n JSON.stringify(input.technologies || []),\n input.confidence\n ]\n );\n\n return entryId;\n }\n\n /**\n * Search troubleshooting entries by text query\n */\n async search(\n query: string,\n options?: { topK?: number; minConfidence?: number }\n ): Promise<SharedTroubleshootingEntry[]> {\n const topK = options?.topK || 5;\n const minConfidence = options?.minConfidence || 0.5;\n const searchPattern = `%${query}%`;\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM shared_troubleshooting\n WHERE (title LIKE ? OR root_cause LIKE ? OR solution LIKE ?)\n AND confidence >= ?\n ORDER BY confidence DESC, usage_count DESC\n LIMIT ?`,\n [searchPattern, searchPattern, searchPattern, minConfidence, topK]\n );\n\n return rows.map(this.rowToEntry);\n }\n\n /**\n * Search by topics\n */\n async searchByTopics(\n topics: string[],\n options?: { topK?: number; excludeProjectHash?: string }\n ): Promise<SharedTroubleshootingEntry[]> {\n const topK = options?.topK || 5;\n\n if (topics.length === 0) {\n return [];\n }\n\n const topicConditions = topics.map(() => `topics LIKE ?`).join(' OR ');\n const topicParams = topics.map(t => `%\"${t}\"%`);\n\n let query = `SELECT * FROM shared_troubleshooting WHERE (${topicConditions})`;\n const params: unknown[] = [...topicParams];\n\n if (options?.excludeProjectHash) {\n query += ` AND source_project_hash != ?`;\n params.push(options.excludeProjectHash);\n }\n\n query += ` ORDER BY confidence DESC, usage_count DESC LIMIT ?`;\n params.push(topK);\n\n const rows = await dbAll<Record<string, unknown>>(this.db, query, params);\n return rows.map(this.rowToEntry);\n }\n\n /**\n * Record usage of a shared entry (for ranking)\n */\n async recordUsage(entryId: string): Promise<void> {\n await dbRun(\n this.db,\n `UPDATE shared_troubleshooting\n SET usage_count = usage_count + 1,\n last_used_at = CURRENT_TIMESTAMP\n WHERE entry_id = ?`,\n [entryId]\n );\n }\n\n /**\n * Get entry by ID\n */\n async get(entryId: string): Promise<SharedTroubleshootingEntry | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM shared_troubleshooting WHERE entry_id = ?`,\n [entryId]\n );\n\n if (rows.length === 0) return null;\n return this.rowToEntry(rows[0]);\n }\n\n /**\n * Get entry by source (project hash + entry ID)\n */\n async getBySource(\n projectHash: string,\n sourceEntryId: string\n ): Promise<SharedTroubleshootingEntry | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM shared_troubleshooting\n WHERE source_project_hash = ? AND source_entry_id = ?`,\n [projectHash, sourceEntryId]\n );\n\n if (rows.length === 0) return null;\n return this.rowToEntry(rows[0]);\n }\n\n /**\n * Check if an entry already exists in shared store\n */\n async exists(projectHash: string, sourceEntryId: string): Promise<boolean> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM shared_troubleshooting\n WHERE source_project_hash = ? AND source_entry_id = ?`,\n [projectHash, sourceEntryId]\n );\n return (result[0]?.count || 0) > 0;\n }\n\n /**\n * Get all entries (with limit for safety)\n */\n async getAll(options?: { limit?: number }): Promise<SharedTroubleshootingEntry[]> {\n const limit = options?.limit || 100;\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM shared_troubleshooting\n ORDER BY confidence DESC, usage_count DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToEntry);\n }\n\n /**\n * Get total count\n */\n async count(): Promise<number> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM shared_troubleshooting`\n );\n return result[0]?.count || 0;\n }\n\n /**\n * Get statistics\n */\n async getStats(): Promise<{\n total: number;\n averageConfidence: number;\n topTopics: Array<{ topic: string; count: number }>;\n totalUsageCount: number;\n }> {\n const countResult = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM shared_troubleshooting`\n );\n const total = countResult[0]?.count || 0;\n\n const avgResult = await dbAll<{ avg: number | null }>(\n this.db,\n `SELECT AVG(confidence) as avg FROM shared_troubleshooting`\n );\n const averageConfidence = avgResult[0]?.avg || 0;\n\n const usageResult = await dbAll<{ total: number }>(\n this.db,\n `SELECT SUM(usage_count) as total FROM shared_troubleshooting`\n );\n const totalUsageCount = usageResult[0]?.total || 0;\n\n // Get topic counts\n const entries = await this.getAll({ limit: 1000 });\n const topicCounts: Record<string, number> = {};\n for (const entry of entries) {\n for (const topic of entry.topics) {\n topicCounts[topic] = (topicCounts[topic] || 0) + 1;\n }\n }\n\n const topTopics = Object.entries(topicCounts)\n .map(([topic, count]) => ({ topic, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 10);\n\n return { total, averageConfidence, topTopics, totalUsageCount };\n }\n\n /**\n * Delete an entry\n */\n async delete(entryId: string): Promise<boolean> {\n const before = await this.count();\n await dbRun(\n this.db,\n `DELETE FROM shared_troubleshooting WHERE entry_id = ?`,\n [entryId]\n );\n const after = await this.count();\n return before > after;\n }\n\n private rowToEntry(row: Record<string, unknown>): SharedTroubleshootingEntry {\n return {\n entryId: row.entry_id as string,\n sourceProjectHash: row.source_project_hash as string,\n sourceEntryId: row.source_entry_id as string,\n title: row.title as string,\n symptoms: JSON.parse(row.symptoms as string || '[]'),\n rootCause: row.root_cause as string,\n solution: row.solution as string,\n topics: JSON.parse(row.topics as string || '[]'),\n technologies: JSON.parse(row.technologies as string || '[]'),\n confidence: row.confidence as number,\n usageCount: row.usage_count as number || 0,\n lastUsedAt: row.last_used_at ? toDate(row.last_used_at) : undefined,\n promotedAt: toDate(row.promoted_at),\n createdAt: toDate(row.created_at)\n };\n }\n}\n\nexport function createSharedStore(\n sharedEventStore: SharedEventStore\n): SharedStore {\n return new SharedStore(sharedEventStore);\n}\n", "/**\n * SharedVectorStore - Vector store for cross-project semantic search\n * Location: ~/.claude-code/memory/shared/vectors/\n */\n\nimport * as lancedb from '@lancedb/lancedb';\nimport type { SharedEntryType, SharedSearchResult } from './types.js';\n\nexport interface SharedVectorRecord {\n id: string;\n entryId: string;\n entryType: SharedEntryType;\n content: string;\n vector: number[];\n topics: string[];\n sourceProjectHash?: string;\n}\n\nexport class SharedVectorStore {\n private db: lancedb.Connection | null = null;\n private table: lancedb.Table | null = null;\n private readonly tableName = 'shared_knowledge';\n\n constructor(private dbPath: string) {}\n\n /**\n * Initialize LanceDB connection\n */\n async initialize(): Promise<void> {\n if (this.db) return;\n\n this.db = await lancedb.connect(this.dbPath);\n\n try {\n const tables = await this.db.tableNames();\n if (tables.includes(this.tableName)) {\n this.table = await this.db.openTable(this.tableName);\n }\n } catch {\n this.table = null;\n }\n }\n\n /**\n * Add or update a shared vector record\n */\n async upsert(record: SharedVectorRecord): Promise<void> {\n await this.initialize();\n\n if (!this.db) {\n throw new Error('Database not initialized');\n }\n\n const data = {\n id: record.id,\n entryId: record.entryId,\n entryType: record.entryType,\n content: record.content,\n vector: record.vector,\n topics: JSON.stringify(record.topics),\n sourceProjectHash: record.sourceProjectHash || ''\n };\n\n if (!this.table) {\n this.table = await this.db.createTable(this.tableName, [data]);\n } else {\n // Delete existing entry before adding (upsert behavior)\n try {\n await this.table.delete(`entryId = '${record.entryId}'`);\n } catch {\n // Entry might not exist, ignore\n }\n await this.table.add([data]);\n }\n }\n\n /**\n * Add multiple records in batch\n */\n async upsertBatch(records: SharedVectorRecord[]): Promise<void> {\n if (records.length === 0) return;\n\n await this.initialize();\n\n if (!this.db) {\n throw new Error('Database not initialized');\n }\n\n const data = records.map(record => ({\n id: record.id,\n entryId: record.entryId,\n entryType: record.entryType,\n content: record.content,\n vector: record.vector,\n topics: JSON.stringify(record.topics),\n sourceProjectHash: record.sourceProjectHash || ''\n }));\n\n if (!this.table) {\n this.table = await this.db.createTable(this.tableName, data);\n } else {\n await this.table.add(data);\n }\n }\n\n /**\n * Search for similar vectors\n */\n async search(\n queryVector: number[],\n options: {\n limit?: number;\n minScore?: number;\n excludeProjectHash?: string;\n entryType?: SharedEntryType;\n } = {}\n ): Promise<SharedSearchResult[]> {\n await this.initialize();\n\n if (!this.table) {\n return [];\n }\n\n const { limit = 5, minScore = 0.7, excludeProjectHash, entryType } = options;\n\n let query = this.table\n .search(queryVector)\n .distanceType('cosine')\n .limit(limit * 2);\n\n // Apply filters\n const filters: string[] = [];\n if (excludeProjectHash) {\n filters.push(`sourceProjectHash != '${excludeProjectHash}'`);\n }\n if (entryType) {\n filters.push(`entryType = '${entryType}'`);\n }\n\n if (filters.length > 0) {\n query = query.where(filters.join(' AND '));\n }\n\n const results = await query.toArray();\n\n return results\n .filter(r => {\n const distance = r._distance || 0;\n const score = 1 - (distance / 2);\n return score >= minScore;\n })\n .slice(0, limit)\n .map(r => {\n const distance = r._distance || 0;\n const score = 1 - (distance / 2);\n return {\n id: r.id as string,\n entryId: r.entryId as string,\n content: r.content as string,\n score,\n entryType: r.entryType as SharedEntryType\n };\n });\n }\n\n /**\n * Delete vector by entry ID\n */\n async delete(entryId: string): Promise<void> {\n if (!this.table) return;\n await this.table.delete(`entryId = '${entryId}'`);\n }\n\n /**\n * Get total count\n */\n async count(): Promise<number> {\n if (!this.table) return 0;\n return this.table.countRows();\n }\n\n /**\n * Check if vector exists for entry\n */\n async exists(entryId: string): Promise<boolean> {\n if (!this.table) return false;\n\n try {\n const results = await this.table\n .search([])\n .where(`entryId = '${entryId}'`)\n .limit(1)\n .toArray();\n return results.length > 0;\n } catch {\n return false;\n }\n }\n}\n\nexport function createSharedVectorStore(dbPath: string): SharedVectorStore {\n return new SharedVectorStore(dbPath);\n}\n", "/**\n * SharedPromoter - Handles auto-promotion of verified troubleshooting entries\n * Promotes entries from project-local storage to cross-project shared storage\n */\n\nimport { randomUUID } from 'crypto';\nimport { SharedStore } from './shared-store.js';\nimport { SharedVectorStore } from './shared-vector-store.js';\nimport { Embedder } from './embedder.js';\nimport type { Entry, SharedTroubleshootingInput, SharedStoreConfig } from './types.js';\n\nexport interface TroubleshootingContent {\n symptoms?: string[];\n rootCause?: string;\n solution?: string;\n technologies?: string[];\n}\n\nexport interface PromotionResult {\n success: boolean;\n entryId?: string;\n error?: string;\n skipped?: boolean;\n skipReason?: string;\n}\n\nexport class SharedPromoter {\n constructor(\n private sharedStore: SharedStore,\n private sharedVectorStore: SharedVectorStore,\n private embedder: Embedder,\n private config?: SharedStoreConfig\n ) {}\n\n /**\n * Check if an entry is eligible for promotion\n */\n isEligibleForPromotion(entry: Entry): boolean {\n // Must be troubleshooting type\n if (entry.entryType !== 'troubleshooting') {\n return false;\n }\n\n // Must be at least 'verified' stage\n if (entry.stage !== 'verified' && entry.stage !== 'certified') {\n return false;\n }\n\n // Must be active status\n if (entry.status !== 'active') {\n return false;\n }\n\n return true;\n }\n\n /**\n * Promote a verified troubleshooting entry to shared storage\n */\n async promoteEntry(\n entry: Entry,\n projectHash: string\n ): Promise<PromotionResult> {\n // Validate eligibility\n if (!this.isEligibleForPromotion(entry)) {\n return {\n success: false,\n skipped: true,\n skipReason: `Entry not eligible: type=${entry.entryType}, stage=${entry.stage}, status=${entry.status}`\n };\n }\n\n // Check if already promoted\n const exists = await this.sharedStore.exists(projectHash, entry.entryId);\n if (exists) {\n return {\n success: true,\n skipped: true,\n skipReason: 'Entry already exists in shared store'\n };\n }\n\n try {\n const content = entry.contentJson as TroubleshootingContent;\n const confidence = this.calculateConfidence(entry);\n\n // Check minimum confidence threshold\n const minConfidence = this.config?.minConfidenceForPromotion ?? 0.8;\n if (confidence < minConfidence) {\n return {\n success: false,\n skipped: true,\n skipReason: `Confidence ${confidence} below threshold ${minConfidence}`\n };\n }\n\n const input: SharedTroubleshootingInput = {\n sourceProjectHash: projectHash,\n sourceEntryId: entry.entryId,\n title: entry.title,\n symptoms: content.symptoms || [],\n rootCause: content.rootCause || '',\n solution: content.solution || '',\n topics: this.extractTopics(entry),\n technologies: content.technologies || [],\n confidence\n };\n\n // Promote to shared store\n const entryId = await this.sharedStore.promoteEntry(input);\n\n // Create embedding for vector search\n const embeddingContent = this.createEmbeddingContent(input);\n const embedding = await this.embedder.embed(embeddingContent);\n\n await this.sharedVectorStore.upsert({\n id: randomUUID(),\n entryId,\n entryType: 'troubleshooting',\n content: embeddingContent,\n vector: embedding.vector,\n topics: input.topics,\n sourceProjectHash: projectHash\n });\n\n return {\n success: true,\n entryId\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n\n /**\n * Batch promote multiple entries\n */\n async promoteEntries(\n entries: Entry[],\n projectHash: string\n ): Promise<Map<string, PromotionResult>> {\n const results = new Map<string, PromotionResult>();\n\n for (const entry of entries) {\n const result = await this.promoteEntry(entry, projectHash);\n results.set(entry.entryId, result);\n }\n\n return results;\n }\n\n /**\n * Extract topics from entry\n */\n private extractTopics(entry: Entry): string[] {\n const topics: string[] = [];\n\n // Extract from title (meaningful words)\n const titleWords = entry.title\n .toLowerCase()\n .split(/[\\s\\-_]+/)\n .filter(w => w.length > 3 && !this.isStopWord(w));\n topics.push(...titleWords);\n\n // Extract from content if available\n const content = entry.contentJson as Record<string, unknown>;\n if (content.topics && Array.isArray(content.topics)) {\n topics.push(...content.topics.map(t => String(t).toLowerCase()));\n }\n\n // Extract technologies as topics\n if (content.technologies && Array.isArray(content.technologies)) {\n topics.push(...content.technologies.map(t => String(t).toLowerCase()));\n }\n\n // Dedupe and return\n return [...new Set(topics)];\n }\n\n /**\n * Check if word is a stop word\n */\n private isStopWord(word: string): boolean {\n const stopWords = new Set([\n 'the', 'and', 'for', 'with', 'this', 'that', 'from', 'have', 'been',\n 'were', 'are', 'was', 'had', 'has', 'will', 'would', 'could', 'should',\n 'when', 'where', 'what', 'which', 'while', 'error', 'problem', 'issue'\n ]);\n return stopWords.has(word);\n }\n\n /**\n * Calculate confidence score for entry\n */\n private calculateConfidence(entry: Entry): number {\n let confidence = 0.8; // Base confidence for verified entries\n\n // Boost if certified\n if (entry.stage === 'certified') {\n confidence = 0.95;\n }\n\n // Could add more factors:\n // - Number of evidence items\n // - Age of entry (older verified entries may be more reliable)\n // - Usage count if tracked\n\n return Math.min(confidence, 1.0);\n }\n\n /**\n * Create embedding content from input\n */\n private createEmbeddingContent(input: SharedTroubleshootingInput): string {\n const parts: string[] = [];\n\n parts.push(`Problem: ${input.title}`);\n\n if (input.symptoms.length > 0) {\n parts.push(`Symptoms: ${input.symptoms.join(', ')}`);\n }\n\n if (input.rootCause) {\n parts.push(`Root Cause: ${input.rootCause}`);\n }\n\n if (input.solution) {\n parts.push(`Solution: ${input.solution}`);\n }\n\n if (input.technologies && input.technologies.length > 0) {\n parts.push(`Technologies: ${input.technologies.join(', ')}`);\n }\n\n return parts.join('\\n');\n }\n}\n\nexport function createSharedPromoter(\n sharedStore: SharedStore,\n sharedVectorStore: SharedVectorStore,\n embedder: Embedder,\n config?: SharedStoreConfig\n): SharedPromoter {\n return new SharedPromoter(sharedStore, sharedVectorStore, embedder, config);\n}\n", "/**\n * Metadata Extractor\n * Extracts tool-specific metadata from tool inputs and outputs\n */\n\nimport type { ToolMetadata } from './types.js';\n\n/**\n * Get file type from path\n */\nfunction getFileType(filePath: string): string | undefined {\n const ext = filePath.split('.').pop()?.toLowerCase();\n if (!ext) return undefined;\n\n const typeMap: Record<string, string> = {\n ts: 'typescript',\n tsx: 'typescript',\n js: 'javascript',\n jsx: 'javascript',\n py: 'python',\n rb: 'ruby',\n go: 'go',\n rs: 'rust',\n java: 'java',\n kt: 'kotlin',\n swift: 'swift',\n c: 'c',\n cpp: 'cpp',\n h: 'header',\n hpp: 'header',\n cs: 'csharp',\n php: 'php',\n html: 'html',\n css: 'css',\n scss: 'scss',\n json: 'json',\n yaml: 'yaml',\n yml: 'yaml',\n xml: 'xml',\n md: 'markdown',\n sql: 'sql',\n sh: 'shell',\n bash: 'shell',\n zsh: 'shell'\n };\n\n return typeMap[ext];\n}\n\n/**\n * Count lines in content\n */\nfunction countLines(content: string): number {\n return content.split('\\n').length;\n}\n\n/**\n * Extract bash command (without arguments that might contain secrets)\n */\nfunction extractCommand(fullCommand: string): string {\n // Get first word (command name)\n const parts = fullCommand.trim().split(/\\s+/);\n const command = parts[0];\n\n // For common commands, include safe arguments\n const safeCommands = ['git', 'npm', 'yarn', 'pnpm', 'node', 'python', 'go', 'cargo', 'make'];\n if (safeCommands.includes(command) && parts.length > 1) {\n // Include subcommand for these\n return `${command} ${parts[1]}`;\n }\n\n return command;\n}\n\n/**\n * Extract metadata from tool usage\n */\nexport function extractMetadata(\n toolName: string,\n input: Record<string, unknown>,\n output: string,\n success: boolean\n): ToolMetadata {\n switch (toolName) {\n case 'Read': {\n const filePath = input.file_path as string | undefined;\n return {\n filePath,\n fileType: filePath ? getFileType(filePath) : undefined,\n lineCount: success ? countLines(output) : undefined\n };\n }\n\n case 'Write': {\n const filePath = input.file_path as string | undefined;\n const content = input.content as string | undefined;\n return {\n filePath,\n fileType: filePath ? getFileType(filePath) : undefined,\n lineCount: content ? countLines(content) : undefined\n };\n }\n\n case 'Edit': {\n const filePath = input.file_path as string | undefined;\n return {\n filePath,\n fileType: filePath ? getFileType(filePath) : undefined\n };\n }\n\n case 'Bash': {\n const fullCommand = input.command as string | undefined;\n return {\n command: fullCommand ? extractCommand(fullCommand) : undefined\n };\n }\n\n case 'Grep': {\n const pattern = input.pattern as string | undefined;\n // Count matches from output\n const matchCount = success\n ? (output.match(/\\n/g) || []).length + (output.trim() ? 1 : 0)\n : undefined;\n return {\n pattern,\n matchCount\n };\n }\n\n case 'Glob': {\n const pattern = input.pattern as string | undefined;\n const matchCount = success\n ? (output.match(/\\n/g) || []).length + (output.trim() ? 1 : 0)\n : undefined;\n return {\n pattern,\n matchCount\n };\n }\n\n case 'WebFetch': {\n const url = input.url as string | undefined;\n // Try to extract status code from output\n const statusMatch = output.match(/status:\\s*(\\d{3})/i);\n return {\n url,\n statusCode: statusMatch ? parseInt(statusMatch[1], 10) : undefined\n };\n }\n\n case 'WebSearch': {\n return {};\n }\n\n case 'NotebookEdit': {\n const notebookPath = input.notebook_path as string | undefined;\n return {\n filePath: notebookPath,\n fileType: 'jupyter'\n };\n }\n\n default:\n return {};\n }\n}\n\n/**\n * Create embedding content for tool observation\n */\nexport function createToolObservationEmbedding(\n toolName: string,\n metadata: ToolMetadata,\n success: boolean\n): string {\n const parts: string[] = [];\n\n parts.push(`Tool: ${toolName}`);\n\n if (metadata.filePath) {\n parts.push(`File: ${metadata.filePath}`);\n }\n if (metadata.command) {\n parts.push(`Command: ${metadata.command}`);\n }\n if (metadata.pattern) {\n parts.push(`Pattern: ${metadata.pattern}`);\n }\n if (metadata.url) {\n // Only include domain for privacy\n try {\n const url = new URL(metadata.url);\n parts.push(`URL: ${url.hostname}`);\n } catch {\n // Invalid URL, skip\n }\n }\n\n parts.push(`Result: ${success ? 'Success' : 'Failed'}`);\n\n return parts.join('\\n');\n}\n", "/**\n * Working Set Store\n * Manages the active memory window for Endless Mode\n * Biomimetic: Simulates human working memory (7\u00B12 items, 15-30s duration)\n */\n\nimport { randomUUID } from 'crypto';\nimport { dbRun, dbAll, toDate, type Database } from './db-wrapper.js';\nimport type {\n MemoryEvent,\n EndlessModeConfig,\n WorkingSet,\n WorkingSetItem\n} from './types.js';\nimport { EventStore } from './event-store.js';\n\nexport class WorkingSetStore {\n constructor(\n private eventStore: EventStore,\n private config: EndlessModeConfig\n ) {}\n\n private get db(): Database {\n return this.eventStore.getDatabase();\n }\n\n /**\n * Add an event to the working set\n */\n async add(eventId: string, relevanceScore: number = 1.0, topics?: string[]): Promise<void> {\n const expiresAt = new Date(\n Date.now() + this.config.workingSet.timeWindowHours * 60 * 60 * 1000\n );\n\n await dbRun(\n this.db,\n `INSERT OR REPLACE INTO working_set (id, event_id, added_at, relevance_score, topics, expires_at)\n VALUES (?, ?, CURRENT_TIMESTAMP, ?, ?, ?)`,\n [\n randomUUID(),\n eventId,\n relevanceScore,\n JSON.stringify(topics || []),\n expiresAt.toISOString()\n ]\n );\n\n // Enforce size limit\n await this.enforceLimit();\n }\n\n /**\n * Get the current working set\n */\n async get(): Promise<WorkingSet> {\n // Clean up expired items first\n await this.cleanup();\n\n // Get working set items with their events\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT ws.*, e.*\n FROM working_set ws\n JOIN events e ON ws.event_id = e.id\n ORDER BY ws.relevance_score DESC, ws.added_at DESC\n LIMIT ?`,\n [this.config.workingSet.maxEvents]\n );\n\n const events: MemoryEvent[] = rows.map(row => ({\n id: row.id as string,\n eventType: row.event_type as 'user_prompt' | 'agent_response' | 'session_summary' | 'tool_observation',\n sessionId: row.session_id as string,\n timestamp: toDate(row.timestamp),\n content: row.content as string,\n canonicalKey: row.canonical_key as string,\n dedupeKey: row.dedupe_key as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined\n }));\n\n return {\n recentEvents: events,\n lastActivity: events.length > 0 ? events[0].timestamp : new Date(),\n continuityScore: await this.calculateContinuityScore()\n };\n }\n\n /**\n * Get working set items (metadata only)\n */\n async getItems(): Promise<WorkingSetItem[]> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM working_set ORDER BY relevance_score DESC, added_at DESC`\n );\n\n return rows.map(row => ({\n id: row.id as string,\n eventId: row.event_id as string,\n addedAt: toDate(row.added_at),\n relevanceScore: row.relevance_score as number,\n topics: row.topics ? JSON.parse(row.topics as string) : undefined,\n expiresAt: toDate(row.expires_at)\n }));\n }\n\n /**\n * Update relevance score for an event\n */\n async updateRelevance(eventId: string, score: number): Promise<void> {\n await dbRun(\n this.db,\n `UPDATE working_set SET relevance_score = ? WHERE event_id = ?`,\n [score, eventId]\n );\n }\n\n /**\n * Prune specific events from working set (after consolidation)\n */\n async prune(eventIds: string[]): Promise<void> {\n if (eventIds.length === 0) return;\n\n const placeholders = eventIds.map(() => '?').join(',');\n await dbRun(\n this.db,\n `DELETE FROM working_set WHERE event_id IN (${placeholders})`,\n eventIds\n );\n }\n\n /**\n * Get the count of items in working set\n */\n async count(): Promise<number> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM working_set`\n );\n return result[0]?.count || 0;\n }\n\n /**\n * Clear the entire working set\n */\n async clear(): Promise<void> {\n await dbRun(this.db, `DELETE FROM working_set`);\n }\n\n /**\n * Check if an event is in the working set\n */\n async contains(eventId: string): Promise<boolean> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM working_set WHERE event_id = ?`,\n [eventId]\n );\n return (result[0]?.count || 0) > 0;\n }\n\n /**\n * Refresh expiration for an event (rehears al - keep relevant items longer)\n */\n async refresh(eventId: string): Promise<void> {\n const newExpiresAt = new Date(\n Date.now() + this.config.workingSet.timeWindowHours * 60 * 60 * 1000\n );\n\n await dbRun(\n this.db,\n `UPDATE working_set SET expires_at = ? WHERE event_id = ?`,\n [newExpiresAt.toISOString(), eventId]\n );\n }\n\n /**\n * Clean up expired items\n */\n private async cleanup(): Promise<void> {\n await dbRun(\n this.db,\n `DELETE FROM working_set WHERE expires_at < datetime('now')`\n );\n }\n\n /**\n * Enforce the maximum size limit\n * Removes lowest relevance items when over limit\n */\n private async enforceLimit(): Promise<void> {\n const maxEvents = this.config.workingSet.maxEvents;\n\n // Get IDs to keep (highest relevance, most recent)\n const keepIds = await dbAll<{ id: string }>(\n this.db,\n `SELECT id FROM working_set\n ORDER BY relevance_score DESC, added_at DESC\n LIMIT ?`,\n [maxEvents]\n );\n\n if (keepIds.length === 0) return;\n\n const keepIdList = keepIds.map(r => r.id);\n const placeholders = keepIdList.map(() => '?').join(',');\n\n // Delete everything not in the keep list\n await dbRun(\n this.db,\n `DELETE FROM working_set WHERE id NOT IN (${placeholders})`,\n keepIdList\n );\n }\n\n /**\n * Calculate continuity score based on recent context transitions\n */\n private async calculateContinuityScore(): Promise<number> {\n const result = await dbAll<{ avg_score: number | null }>(\n this.db,\n `SELECT AVG(continuity_score) as avg_score\n FROM continuity_log\n WHERE created_at > datetime('now', '-1 hour')`\n );\n\n return result[0]?.avg_score ?? 0.5;\n }\n\n /**\n * Get topics from current working set for context matching\n */\n async getActiveTopics(): Promise<string[]> {\n const rows = await dbAll<{ topics: string }>(\n this.db,\n `SELECT topics FROM working_set WHERE topics IS NOT NULL`\n );\n\n const allTopics = new Set<string>();\n for (const row of rows) {\n const topics = JSON.parse(row.topics) as string[];\n topics.forEach(t => allTopics.add(t));\n }\n\n return Array.from(allTopics);\n }\n}\n\n/**\n * Create a Working Set Store instance\n */\nexport function createWorkingSetStore(\n eventStore: EventStore,\n config: EndlessModeConfig\n): WorkingSetStore {\n return new WorkingSetStore(eventStore, config);\n}\n", "/**\n * Consolidated Store\n * Manages long-term integrated memories for Endless Mode\n * Biomimetic: Simulates memory consolidation that occurs during sleep\n */\n\nimport { randomUUID } from 'crypto';\nimport { dbRun, dbAll, toDate, type Database } from './db-wrapper.js';\nimport type {\n ConsolidatedMemory,\n ConsolidatedMemoryInput,\n ConsolidationRule,\n ConsolidationRuleInput\n} from './types.js';\nimport { EventStore } from './event-store.js';\n\nexport class ConsolidatedStore {\n constructor(private eventStore: EventStore) {}\n\n private get db(): Database {\n return this.eventStore.getDatabase();\n }\n\n /**\n * Create a new consolidated memory\n */\n async create(input: ConsolidatedMemoryInput): Promise<string> {\n const memoryId = randomUUID();\n\n await dbRun(\n this.db,\n `INSERT INTO consolidated_memories\n (memory_id, summary, topics, source_events, confidence, created_at)\n VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)`,\n [\n memoryId,\n input.summary,\n JSON.stringify(input.topics),\n JSON.stringify(input.sourceEvents),\n input.confidence\n ]\n );\n\n return memoryId;\n }\n\n /**\n * Get a consolidated memory by ID\n */\n async get(memoryId: string): Promise<ConsolidatedMemory | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories WHERE memory_id = ?`,\n [memoryId]\n );\n\n if (rows.length === 0) return null;\n return this.rowToMemory(rows[0]);\n }\n\n /**\n * Search consolidated memories by query (simple text search)\n */\n async search(query: string, options?: { topK?: number }): Promise<ConsolidatedMemory[]> {\n const topK = options?.topK || 5;\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories\n WHERE summary LIKE ?\n ORDER BY confidence DESC\n LIMIT ?`,\n [`%${query}%`, topK]\n );\n\n return rows.map(this.rowToMemory);\n }\n\n /**\n * Search by topics\n */\n async searchByTopics(topics: string[], options?: { topK?: number }): Promise<ConsolidatedMemory[]> {\n const topK = options?.topK || 5;\n\n // Build topic filter\n const topicConditions = topics.map(() => `topics LIKE ?`).join(' OR ');\n const topicParams = topics.map(t => `%\"${t}\"%`);\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories\n WHERE ${topicConditions}\n ORDER BY confidence DESC\n LIMIT ?`,\n [...topicParams, topK]\n );\n\n return rows.map(this.rowToMemory);\n }\n\n /**\n * Get all consolidated memories ordered by confidence\n */\n async getAll(options?: { limit?: number }): Promise<ConsolidatedMemory[]> {\n const limit = options?.limit || 100;\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories\n ORDER BY confidence DESC, created_at DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToMemory);\n }\n\n /**\n * Get recently created memories\n */\n async getRecent(options?: { limit?: number; hours?: number }): Promise<ConsolidatedMemory[]> {\n const limit = options?.limit || 10;\n const hours = options?.hours || 24;\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories\n WHERE created_at > datetime('now', '-${hours} hours')\n ORDER BY created_at DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToMemory);\n }\n\n /**\n * Mark a memory as accessed (tracks usage for importance scoring)\n */\n async markAccessed(memoryId: string): Promise<void> {\n await dbRun(\n this.db,\n `UPDATE consolidated_memories\n SET accessed_at = CURRENT_TIMESTAMP,\n access_count = access_count + 1\n WHERE memory_id = ?`,\n [memoryId]\n );\n }\n\n /**\n * Update confidence score for a memory\n */\n async updateConfidence(memoryId: string, confidence: number): Promise<void> {\n await dbRun(\n this.db,\n `UPDATE consolidated_memories\n SET confidence = ?\n WHERE memory_id = ?`,\n [confidence, memoryId]\n );\n }\n\n /**\n * Delete a consolidated memory\n */\n async delete(memoryId: string): Promise<void> {\n await dbRun(\n this.db,\n `DELETE FROM consolidated_memories WHERE memory_id = ?`,\n [memoryId]\n );\n }\n\n /**\n * Create a long-term rule promoted from stable summaries\n */\n async createRule(input: ConsolidationRuleInput): Promise<string> {\n const ruleId = randomUUID();\n\n await dbRun(\n this.db,\n `INSERT INTO consolidated_rules\n (rule_id, rule, topics, source_memory_ids, source_events, confidence, created_at)\n VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)`,\n [\n ruleId,\n input.rule,\n JSON.stringify(input.topics),\n JSON.stringify(input.sourceMemoryIds),\n JSON.stringify(input.sourceEvents),\n input.confidence\n ]\n );\n\n return ruleId;\n }\n\n async getRules(options?: { limit?: number }): Promise<ConsolidationRule[]> {\n const limit = options?.limit || 100;\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_rules ORDER BY confidence DESC, created_at DESC LIMIT ?`,\n [limit]\n );\n\n return rows.map((row) => ({\n ruleId: row.rule_id as string,\n rule: row.rule as string,\n topics: JSON.parse((row.topics as string) || '[]'),\n sourceMemoryIds: JSON.parse((row.source_memory_ids as string) || '[]'),\n sourceEvents: JSON.parse((row.source_events as string) || '[]'),\n confidence: Number(row.confidence ?? 0.5),\n createdAt: toDate(row.created_at) || new Date()\n }));\n }\n\n async countRules(): Promise<number> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM consolidated_rules`\n );\n return result[0]?.count || 0;\n }\n\n async hasRuleForSourceMemory(memoryId: string): Promise<boolean> {\n const rows = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM consolidated_rules WHERE source_memory_ids LIKE ?`,\n [`%\"${memoryId}\"%`]\n );\n return (rows[0]?.count || 0) > 0;\n }\n\n /**\n * Get count of consolidated memories\n */\n async count(): Promise<number> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM consolidated_memories`\n );\n return result[0]?.count || 0;\n }\n\n /**\n * Get most accessed memories (for importance scoring)\n */\n async getMostAccessed(limit: number = 10): Promise<ConsolidatedMemory[]> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories\n WHERE access_count > 0\n ORDER BY access_count DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToMemory);\n }\n\n /**\n * Get statistics about consolidated memories\n */\n async getStats(): Promise<{\n total: number;\n averageConfidence: number;\n topicCounts: Record<string, number>;\n recentCount: number;\n }> {\n const total = await this.count();\n\n const avgResult = await dbAll<{ avg: number | null }>(\n this.db,\n `SELECT AVG(confidence) as avg FROM consolidated_memories`\n );\n const averageConfidence = avgResult[0]?.avg || 0;\n\n const recentResult = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM consolidated_memories\n WHERE created_at > datetime('now', '-24 hours')`\n );\n const recentCount = recentResult[0]?.count || 0;\n\n // Get topic counts\n const allMemories = await this.getAll({ limit: 1000 });\n const topicCounts: Record<string, number> = {};\n for (const memory of allMemories) {\n for (const topic of memory.topics) {\n topicCounts[topic] = (topicCounts[topic] || 0) + 1;\n }\n }\n\n return {\n total,\n averageConfidence,\n topicCounts,\n recentCount\n };\n }\n\n /**\n * Check if source events are already consolidated\n */\n async isAlreadyConsolidated(eventIds: string[]): Promise<boolean> {\n for (const eventId of eventIds) {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM consolidated_memories\n WHERE source_events LIKE ?`,\n [`%\"${eventId}\"%`]\n );\n if ((result[0]?.count || 0) > 0) return true;\n }\n return false;\n }\n\n /**\n * Get the last consolidation time\n */\n async getLastConsolidationTime(): Promise<Date | null> {\n const result = await dbAll<{ created_at: string }>(\n this.db,\n `SELECT created_at FROM consolidated_memories\n ORDER BY created_at DESC\n LIMIT 1`\n );\n\n if (result.length === 0) return null;\n return new Date(result[0].created_at);\n }\n\n /**\n * Convert database row to ConsolidatedMemory\n */\n private rowToMemory(row: Record<string, unknown>): ConsolidatedMemory {\n return {\n memoryId: row.memory_id as string,\n summary: row.summary as string,\n topics: JSON.parse(row.topics as string || '[]'),\n sourceEvents: JSON.parse(row.source_events as string || '[]'),\n confidence: row.confidence as number,\n createdAt: toDate(row.created_at),\n accessedAt: row.accessed_at ? toDate(row.accessed_at) : undefined,\n accessCount: row.access_count as number || 0\n };\n }\n}\n\n/**\n * Create a Consolidated Store instance\n */\nexport function createConsolidatedStore(eventStore: EventStore): ConsolidatedStore {\n return new ConsolidatedStore(eventStore);\n}\n", "/**\n * Consolidation Worker\n * Periodically consolidates working set into long-term memory\n * Biomimetic: Simulates memory consolidation during sleep/idle periods\n */\n\nimport type {\n EndlessModeConfig,\n MemoryEvent,\n EventGroup,\n WorkingSet,\n ConsolidationCostQualityReport\n} from './types.js';\nimport { WorkingSetStore } from './working-set-store.js';\nimport { ConsolidatedStore } from './consolidated-store.js';\n\nexport class ConsolidationWorker {\n private running = false;\n private timeout: NodeJS.Timeout | null = null;\n private lastActivity: Date = new Date();\n\n constructor(\n private workingSetStore: WorkingSetStore,\n private consolidatedStore: ConsolidatedStore,\n private config: EndlessModeConfig\n ) {}\n\n /**\n * Start the consolidation worker\n */\n start(): void {\n if (this.running) return;\n this.running = true;\n this.scheduleNext();\n }\n\n /**\n * Stop the consolidation worker\n */\n stop(): void {\n this.running = false;\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n }\n\n /**\n * Record activity (resets idle timer)\n */\n recordActivity(): void {\n this.lastActivity = new Date();\n }\n\n /**\n * Check if currently running\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Force a consolidation run (manual trigger)\n */\n async forceRun(): Promise<number> {\n const out = await this.consolidateWithReport();\n return out.consolidatedCount;\n }\n\n /**\n * Force a consolidation run and return metrics report\n */\n async forceRunWithReport(): Promise<{\n consolidatedCount: number;\n promotedRuleCount: number;\n report: ConsolidationCostQualityReport;\n }> {\n return this.consolidateWithReport();\n }\n\n /**\n * Schedule the next consolidation check\n */\n private scheduleNext(): void {\n if (!this.running) return;\n\n this.timeout = setTimeout(\n () => this.run(),\n this.config.consolidation.triggerIntervalMs\n );\n }\n\n /**\n * Run consolidation check\n */\n private async run(): Promise<void> {\n if (!this.running) return;\n\n try {\n await this.checkAndConsolidate();\n } catch (error) {\n console.error('Consolidation error:', error);\n }\n\n this.scheduleNext();\n }\n\n /**\n * Check conditions and consolidate if needed\n */\n private async checkAndConsolidate(): Promise<void> {\n const workingSet = await this.workingSetStore.get();\n\n if (!this.shouldConsolidate(workingSet)) {\n return;\n }\n\n await this.consolidate();\n }\n\n /**\n * Perform consolidation\n */\n private async consolidate(): Promise<number> {\n const out = await this.consolidateWithReport();\n return out.consolidatedCount;\n }\n\n private async consolidateWithReport(): Promise<{\n consolidatedCount: number;\n promotedRuleCount: number;\n report: ConsolidationCostQualityReport;\n }> {\n const workingSet = await this.workingSetStore.get();\n\n if (workingSet.recentEvents.length < 3) {\n return {\n consolidatedCount: 0,\n promotedRuleCount: 0,\n report: this.buildCostQualityReport(workingSet.recentEvents, [], 0)\n };\n }\n\n // Group events by topic\n const groups = this.groupByTopic(workingSet.recentEvents);\n let consolidatedCount = 0;\n const createdMemoryIds: string[] = [];\n\n for (const group of groups) {\n // Require minimum 3 events per group\n if (group.events.length < 3) continue;\n\n // Check if already consolidated\n const eventIds = group.events.map(e => e.id);\n const alreadyConsolidated = await this.consolidatedStore.isAlreadyConsolidated(eventIds);\n if (alreadyConsolidated) continue;\n\n // Generate summary\n const summary = await this.summarize(group);\n\n // Create consolidated memory\n const memoryId = await this.consolidatedStore.create({\n summary,\n topics: group.topics,\n sourceEvents: eventIds,\n confidence: this.calculateConfidence(group)\n });\n createdMemoryIds.push(memoryId);\n consolidatedCount++;\n }\n\n const promotedRuleCount = await this.promoteStableSummariesToRules(createdMemoryIds);\n\n // Prune consolidated events from working set\n if (consolidatedCount > 0) {\n const consolidatedEventIds = groups\n .filter(g => g.events.length >= 3)\n .flatMap(g => g.events.map(e => e.id));\n\n // Only prune old events (keep recent for context)\n const oldEventIds = consolidatedEventIds.filter(id => {\n const event = workingSet.recentEvents.find(e => e.id === id);\n if (!event) return false;\n const ageHours = (Date.now() - event.timestamp.getTime()) / (1000 * 60 * 60);\n return ageHours > this.config.workingSet.timeWindowHours / 2;\n });\n\n if (oldEventIds.length > 0) {\n await this.workingSetStore.prune(oldEventIds);\n }\n }\n\n const report = this.buildCostQualityReport(workingSet.recentEvents, groups, consolidatedCount);\n return { consolidatedCount, promotedRuleCount, report };\n }\n\n private async promoteStableSummariesToRules(memoryIds: string[]): Promise<number> {\n let promoted = 0;\n\n for (const memoryId of memoryIds) {\n const memory = await this.consolidatedStore.get(memoryId);\n if (!memory) continue;\n if (memory.confidence < 0.55) continue;\n if (memory.sourceEvents.length < 4) continue;\n\n const exists = await this.consolidatedStore.hasRuleForSourceMemory(memoryId);\n if (exists) continue;\n\n const rule = this.buildRuleFromSummary(memory.summary, memory.topics);\n if (!rule) continue;\n\n await this.consolidatedStore.createRule({\n rule,\n topics: memory.topics,\n sourceMemoryIds: [memory.memoryId],\n sourceEvents: memory.sourceEvents,\n confidence: Math.min(1, memory.confidence + 0.08)\n });\n promoted++;\n }\n\n return promoted;\n }\n\n private buildRuleFromSummary(summary: string, topics: string[]): string | null {\n const lines = summary\n .split(/\\r?\\n/)\n .map((l) => l.trim())\n .filter(Boolean)\n .filter((l) => !l.toLowerCase().startsWith('topics:'));\n\n const bullet = lines.find((l) => l.startsWith('- '))?.replace(/^-\\s*/, '');\n const seed = bullet || lines[0];\n if (!seed || seed.length < 8) return null;\n\n const topicPrefix = topics.length > 0 ? `[${topics.slice(0, 2).join(', ')}] ` : '';\n return `${topicPrefix}${seed}`;\n }\n\n private buildCostQualityReport(\n events: MemoryEvent[],\n groups: EventGroup[],\n consolidatedCount: number\n ): ConsolidationCostQualityReport {\n const beforeTokenEstimate = events.reduce((acc, e) => acc + this.estimateTokens(e.content), 0);\n\n const afterSummaries = groups\n .filter((g) => g.events.length >= 3)\n .slice(0, Math.max(consolidatedCount, 1));\n\n const afterTokenEstimate = afterSummaries.length > 0\n ? afterSummaries.reduce((acc, g) => acc + this.estimateTokens(this.ruleBasedSummary(g)), 0)\n : beforeTokenEstimate;\n\n const reductionRatio = beforeTokenEstimate > 0\n ? Math.max(0, (beforeTokenEstimate - afterTokenEstimate) / beforeTokenEstimate)\n : 0;\n\n const qualityGuardPassed = consolidatedCount === 0\n ? true\n : groups.filter((g) => g.events.length >= 3).every((g) => this.calculateConfidence(g) >= 0.55);\n\n return {\n beforeTokenEstimate,\n afterTokenEstimate,\n reductionRatio,\n qualityGuardPassed,\n details: `groups=${groups.length}, consolidated=${consolidatedCount}`\n };\n }\n\n private estimateTokens(text: string): number {\n return Math.ceil((text || '').length / 4);\n }\n\n /**\n * Check if consolidation should run\n */\n private shouldConsolidate(workingSet: WorkingSet): boolean {\n // Check event count trigger\n if (workingSet.recentEvents.length >= this.config.consolidation.triggerEventCount) {\n return true;\n }\n\n // Check idle time trigger\n const idleTime = Date.now() - this.lastActivity.getTime();\n if (idleTime >= this.config.consolidation.triggerIdleMs) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Group events by topic using simple keyword extraction\n */\n private groupByTopic(events: MemoryEvent[]): EventGroup[] {\n const groups = new Map<string, EventGroup>();\n\n for (const event of events) {\n const topics = this.extractTopics(event.content);\n\n for (const topic of topics) {\n if (!groups.has(topic)) {\n groups.set(topic, { topics: [topic], events: [] });\n }\n const group = groups.get(topic)!;\n if (!group.events.find(e => e.id === event.id)) {\n group.events.push(event);\n }\n }\n }\n\n // Merge groups with overlapping events\n const mergedGroups = this.mergeOverlappingGroups(Array.from(groups.values()));\n\n return mergedGroups;\n }\n\n /**\n * Extract topics from content using simple keyword extraction\n */\n private extractTopics(content: string): string[] {\n const topics: string[] = [];\n\n // Extract code-related keywords\n const codePatterns = [\n /\\b(function|class|interface|type|const|let|var)\\s+(\\w+)/gi,\n /\\b(import|export)\\s+.*?from\\s+['\"]([^'\"]+)['\"]/gi,\n /\\bfile[:\\s]+([^\\s,]+)/gi\n ];\n\n for (const pattern of codePatterns) {\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const keyword = match[2] || match[1];\n if (keyword && keyword.length > 2) {\n topics.push(keyword.toLowerCase());\n }\n }\n }\n\n // Extract common programming terms\n const commonTerms = [\n 'bug', 'fix', 'error', 'issue', 'feature',\n 'test', 'refactor', 'implement', 'add', 'remove',\n 'update', 'change', 'modify', 'create', 'delete'\n ];\n\n const contentLower = content.toLowerCase();\n for (const term of commonTerms) {\n if (contentLower.includes(term)) {\n topics.push(term);\n }\n }\n\n return [...new Set(topics)].slice(0, 5); // Limit to 5 topics\n }\n\n /**\n * Merge groups that have significant event overlap\n */\n private mergeOverlappingGroups(groups: EventGroup[]): EventGroup[] {\n const merged: EventGroup[] = [];\n\n for (const group of groups) {\n let foundMerge = false;\n\n for (const existing of merged) {\n const overlap = group.events.filter(e =>\n existing.events.some(ex => ex.id === e.id)\n );\n\n // If > 50% overlap, merge\n if (overlap.length > group.events.length / 2) {\n existing.topics = [...new Set([...existing.topics, ...group.topics])];\n for (const event of group.events) {\n if (!existing.events.find(e => e.id === event.id)) {\n existing.events.push(event);\n }\n }\n foundMerge = true;\n break;\n }\n }\n\n if (!foundMerge) {\n merged.push(group);\n }\n }\n\n return merged;\n }\n\n /**\n * Generate summary for a group of events\n * Rule-based extraction (no LLM by default)\n */\n private async summarize(group: EventGroup): Promise<string> {\n if (this.config.consolidation.useLLMSummarization) {\n // Future: LLM-based summarization\n return this.ruleBasedSummary(group);\n }\n\n return this.ruleBasedSummary(group);\n }\n\n /**\n * Rule-based summary generation\n */\n private ruleBasedSummary(group: EventGroup): string {\n const keyPoints: string[] = [];\n\n for (const event of group.events.slice(0, 10)) {\n const keyPoint = this.extractKeyPoint(event.content);\n if (keyPoint) {\n keyPoints.push(keyPoint);\n }\n }\n\n const topicsStr = group.topics.slice(0, 3).join(', ');\n const summary = [\n `Topics: ${topicsStr}`,\n '',\n 'Key points:',\n ...keyPoints.map(kp => `- ${kp}`)\n ].join('\\n');\n\n return summary;\n }\n\n /**\n * Extract key point from content\n */\n private extractKeyPoint(content: string): string | null {\n // Get first meaningful sentence\n const sentences = content.split(/[.!?\\n]+/).filter(s => s.trim().length > 10);\n if (sentences.length === 0) return null;\n\n const firstSentence = sentences[0].trim();\n\n // Truncate if too long\n if (firstSentence.length > 100) {\n return firstSentence.slice(0, 100) + '...';\n }\n\n return firstSentence;\n }\n\n /**\n * Calculate confidence score for a group\n */\n private calculateConfidence(group: EventGroup): number {\n // Factor 1: Event count (more events = higher confidence)\n const eventScore = Math.min(group.events.length / 10, 1);\n\n // Factor 2: Time proximity (events closer together = higher confidence)\n const timeScore = this.calculateTimeProximity(group.events);\n\n // Factor 3: Topic consistency (fewer topics per event = higher confidence)\n const topicScore = Math.min(3 / group.topics.length, 1);\n\n return (eventScore * 0.4 + timeScore * 0.4 + topicScore * 0.2);\n }\n\n /**\n * Calculate time proximity score\n */\n private calculateTimeProximity(events: MemoryEvent[]): number {\n if (events.length < 2) return 1;\n\n const timestamps = events.map(e => e.timestamp.getTime()).sort((a, b) => a - b);\n const timeSpan = timestamps[timestamps.length - 1] - timestamps[0];\n\n // Score based on average time between events\n const avgGap = timeSpan / (events.length - 1);\n const hourInMs = 60 * 60 * 1000;\n\n // Within 1 hour average = score 1, 24 hours = score 0.5, etc.\n return Math.max(0, 1 - (avgGap / (24 * hourInMs)));\n }\n}\n\n/**\n * Create a Consolidation Worker instance\n */\nexport function createConsolidationWorker(\n workingSetStore: WorkingSetStore,\n consolidatedStore: ConsolidatedStore,\n config: EndlessModeConfig\n): ConsolidationWorker {\n return new ConsolidationWorker(workingSetStore, consolidatedStore, config);\n}\n", "/**\n * Continuity Manager\n * Tracks and calculates context continuity between interactions\n * Biomimetic: Simulates context-dependent memory retrieval\n */\n\nimport { randomUUID } from 'crypto';\nimport { dbRun, dbAll, toDate, type Database } from './db-wrapper.js';\nimport type {\n EndlessModeConfig,\n ContextSnapshot,\n ContinuityScore,\n TransitionType,\n ContinuityLog\n} from './types.js';\nimport { EventStore } from './event-store.js';\n\nexport class ContinuityManager {\n private lastContext: ContextSnapshot | null = null;\n\n constructor(\n private eventStore: EventStore,\n private config: EndlessModeConfig\n ) {}\n\n private get db(): Database {\n return this.eventStore.getDatabase();\n }\n\n /**\n * Calculate continuity score between current and previous context\n */\n async calculateScore(\n currentContext: ContextSnapshot,\n previousContext?: ContextSnapshot\n ): Promise<ContinuityScore> {\n const prev = previousContext || this.lastContext;\n\n if (!prev) {\n // No previous context - this is a fresh start\n this.lastContext = currentContext;\n return { score: 0.5, transitionType: 'break' };\n }\n\n let score = 0;\n\n // Topic continuity (30%)\n const topicOverlap = this.calculateOverlap(\n currentContext.topics,\n prev.topics\n );\n score += topicOverlap * 0.3;\n\n // File continuity (20%)\n const fileOverlap = this.calculateOverlap(\n currentContext.files,\n prev.files\n );\n score += fileOverlap * 0.2;\n\n // Time proximity (30%)\n const timeDiff = currentContext.timestamp - prev.timestamp;\n const decayHours = this.config.continuity.topicDecayHours;\n const timeScore = Math.exp(-timeDiff / (decayHours * 3600000));\n score += timeScore * 0.3;\n\n // Entity continuity (20%)\n const entityOverlap = this.calculateOverlap(\n currentContext.entities,\n prev.entities\n );\n score += entityOverlap * 0.2;\n\n // Determine transition type\n const transitionType = this.determineTransitionType(score);\n\n // Log the transition\n await this.logTransition(currentContext, prev, score, transitionType);\n\n // Update last context\n this.lastContext = currentContext;\n\n return { score, transitionType };\n }\n\n /**\n * Create a context snapshot from current state\n */\n createSnapshot(\n id: string,\n content: string,\n metadata?: {\n files?: string[];\n entities?: string[];\n }\n ): ContextSnapshot {\n return {\n id,\n timestamp: Date.now(),\n topics: this.extractTopics(content),\n files: metadata?.files || this.extractFiles(content),\n entities: metadata?.entities || this.extractEntities(content)\n };\n }\n\n /**\n * Get recent continuity logs\n */\n async getRecentLogs(limit: number = 10): Promise<ContinuityLog[]> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM continuity_log\n ORDER BY created_at DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(row => ({\n logId: row.log_id as string,\n fromContextId: row.from_context_id as string | undefined,\n toContextId: row.to_context_id as string | undefined,\n continuityScore: row.continuity_score as number,\n transitionType: row.transition_type as TransitionType,\n createdAt: toDate(row.created_at)\n }));\n }\n\n /**\n * Get average continuity score over time period\n */\n async getAverageScore(hours: number = 1): Promise<number> {\n const result = await dbAll<{ avg_score: number | null }>(\n this.db,\n `SELECT AVG(continuity_score) as avg_score\n FROM continuity_log\n WHERE created_at > datetime('now', '-${hours} hours')`\n );\n\n return result[0]?.avg_score ?? 0.5;\n }\n\n /**\n * Get transition type distribution\n */\n async getTransitionStats(hours: number = 24): Promise<Record<TransitionType, number>> {\n const rows = await dbAll<{ transition_type: string; count: number }>(\n this.db,\n `SELECT transition_type, COUNT(*) as count\n FROM continuity_log\n WHERE created_at > datetime('now', '-${hours} hours')\n GROUP BY transition_type`\n );\n\n const stats: Record<TransitionType, number> = {\n seamless: 0,\n topic_shift: 0,\n break: 0\n };\n\n for (const row of rows) {\n stats[row.transition_type as TransitionType] = row.count;\n }\n\n return stats;\n }\n\n /**\n * Clear old continuity logs\n */\n async cleanup(olderThanDays: number = 7): Promise<number> {\n const result = await dbAll<{ changes: number }>(\n this.db,\n `DELETE FROM continuity_log\n WHERE created_at < datetime('now', '-${olderThanDays} days')\n RETURNING COUNT(*) as changes`\n );\n\n return result[0]?.changes || 0;\n }\n\n /**\n * Calculate overlap between two arrays\n */\n private calculateOverlap(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n\n const setA = new Set(a.map(s => s.toLowerCase()));\n const setB = new Set(b.map(s => s.toLowerCase()));\n\n const intersection = [...setA].filter(x => setB.has(x));\n const union = new Set([...setA, ...setB]);\n\n return intersection.length / union.size; // Jaccard similarity\n }\n\n /**\n * Determine transition type based on score\n */\n private determineTransitionType(score: number): TransitionType {\n if (score >= this.config.continuity.minScoreForSeamless) {\n return 'seamless';\n } else if (score >= 0.4) {\n return 'topic_shift';\n } else {\n return 'break';\n }\n }\n\n /**\n * Log a context transition\n */\n private async logTransition(\n current: ContextSnapshot,\n previous: ContextSnapshot,\n score: number,\n type: TransitionType\n ): Promise<void> {\n await dbRun(\n this.db,\n `INSERT INTO continuity_log\n (log_id, from_context_id, to_context_id, continuity_score, transition_type, created_at)\n VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)`,\n [randomUUID(), previous.id, current.id, score, type]\n );\n }\n\n /**\n * Extract topics from content\n */\n private extractTopics(content: string): string[] {\n const topics: string[] = [];\n const contentLower = content.toLowerCase();\n\n // Programming language keywords\n const langPatterns = [\n { pattern: /typescript|\\.ts\\b/i, topic: 'typescript' },\n { pattern: /javascript|\\.js\\b/i, topic: 'javascript' },\n { pattern: /python|\\.py\\b/i, topic: 'python' },\n { pattern: /rust|\\.rs\\b/i, topic: 'rust' },\n { pattern: /go\\b|golang/i, topic: 'go' }\n ];\n\n for (const { pattern, topic } of langPatterns) {\n if (pattern.test(content)) {\n topics.push(topic);\n }\n }\n\n // Common development topics\n const devTopics = [\n 'api', 'database', 'test', 'bug', 'feature', 'refactor',\n 'component', 'function', 'class', 'module', 'hook',\n 'deploy', 'build', 'config', 'docker', 'git'\n ];\n\n for (const topic of devTopics) {\n if (contentLower.includes(topic)) {\n topics.push(topic);\n }\n }\n\n return [...new Set(topics)].slice(0, 10);\n }\n\n /**\n * Extract file paths from content\n */\n private extractFiles(content: string): string[] {\n const filePatterns = [\n /(?:^|\\s)([a-zA-Z0-9_\\-./]+\\.[a-zA-Z0-9]+)(?:\\s|$|:)/gm,\n /['\"](\\.?\\/[^'\"]+\\.[a-zA-Z0-9]+)['\"]/g,\n /file[:\\s]+([^\\s,]+)/gi\n ];\n\n const files = new Set<string>();\n\n for (const pattern of filePatterns) {\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const file = match[1];\n if (file && file.length > 3 && file.length < 100) {\n // Filter out common non-file patterns\n if (!file.match(/^(https?:|mailto:|ftp:)/i)) {\n files.add(file);\n }\n }\n }\n }\n\n return Array.from(files).slice(0, 10);\n }\n\n /**\n * Extract entity names from content (functions, classes, variables)\n */\n private extractEntities(content: string): string[] {\n const entities = new Set<string>();\n\n const entityPatterns = [\n /\\b(function|const|let|var|class|interface|type)\\s+([a-zA-Z_][a-zA-Z0-9_]*)/g,\n /\\b([A-Z][a-zA-Z0-9_]*(?:Component|Service|Store|Manager|Handler|Factory|Provider))\\b/g,\n /\\b(use[A-Z][a-zA-Z0-9_]*)\\b/g // React hooks\n ];\n\n for (const pattern of entityPatterns) {\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const entity = match[2] || match[1];\n if (entity && entity.length > 2) {\n entities.add(entity);\n }\n }\n }\n\n return Array.from(entities).slice(0, 20);\n }\n\n /**\n * Reset the last context (for testing or manual reset)\n */\n resetLastContext(): void {\n this.lastContext = null;\n }\n\n /**\n * Get the last context snapshot\n */\n getLastContext(): ContextSnapshot | null {\n return this.lastContext;\n }\n}\n\n/**\n * Create a Continuity Manager instance\n */\nexport function createContinuityManager(\n eventStore: EventStore,\n config: EndlessModeConfig\n): ContinuityManager {\n return new ContinuityManager(eventStore, config);\n}\n", "/**\n * Graduation Worker\n * Periodically evaluates memory events for promotion to higher levels\n * L0 \u2192 L1 \u2192 L2 \u2192 L3 \u2192 L4 based on access patterns and confidence\n */\n\nimport type { MemoryLevel } from './types.js';\nimport { EventStore } from './event-store.js';\nimport { GraduationPipeline } from './graduation.js';\n\nexport interface GraduationWorkerConfig {\n /** How often to run graduation evaluation (ms) */\n evaluationIntervalMs: number;\n /** Batch size for graduation evaluation */\n batchSize: number;\n /** Minimum time between evaluations of the same event (ms) */\n cooldownMs: number;\n}\n\nconst DEFAULT_CONFIG: GraduationWorkerConfig = {\n evaluationIntervalMs: 300000, // 5 minutes\n batchSize: 50,\n cooldownMs: 3600000 // 1 hour cooldown between evaluations\n};\n\nexport class GraduationWorker {\n private running = false;\n private timeout: NodeJS.Timeout | null = null;\n private lastEvaluated: Map<string, number> = new Map();\n\n constructor(\n private eventStore: EventStore,\n private graduation: GraduationPipeline,\n private config: GraduationWorkerConfig = DEFAULT_CONFIG\n ) {}\n\n /**\n * Start the graduation worker\n */\n start(): void {\n if (this.running) return;\n this.running = true;\n this.scheduleNext();\n }\n\n /**\n * Stop the graduation worker\n */\n stop(): void {\n this.running = false;\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n }\n\n /**\n * Check if currently running\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Force a graduation evaluation run\n */\n async forceRun(): Promise<GraduationRunResult> {\n return await this.runGraduation();\n }\n\n /**\n * Schedule the next graduation check\n */\n private scheduleNext(): void {\n if (!this.running) return;\n\n this.timeout = setTimeout(\n () => this.run(),\n this.config.evaluationIntervalMs\n );\n }\n\n /**\n * Run graduation evaluation\n */\n private async run(): Promise<void> {\n if (!this.running) return;\n\n try {\n await this.runGraduation();\n } catch (error) {\n console.error('Graduation error:', error);\n }\n\n this.scheduleNext();\n }\n\n /**\n * Perform graduation evaluation across all levels\n */\n private async runGraduation(): Promise<GraduationRunResult> {\n const result: GraduationRunResult = {\n evaluated: 0,\n graduated: 0,\n byLevel: {}\n };\n\n const levels: MemoryLevel[] = ['L0', 'L1', 'L2', 'L3'];\n const now = Date.now();\n\n for (const level of levels) {\n const events = await this.eventStore.getEventsByLevel(level, {\n limit: this.config.batchSize\n });\n\n let levelGraduated = 0;\n\n for (const event of events) {\n // Check cooldown\n const lastEval = this.lastEvaluated.get(event.id);\n if (lastEval && (now - lastEval) < this.config.cooldownMs) {\n continue;\n }\n\n result.evaluated++;\n this.lastEvaluated.set(event.id, now);\n\n const gradResult = await this.graduation.evaluateGraduation(event.id, level);\n\n if (gradResult.success) {\n result.graduated++;\n levelGraduated++;\n }\n }\n\n if (levelGraduated > 0) {\n result.byLevel[level] = levelGraduated;\n }\n }\n\n // Clean up old cooldown entries (keep last 1000)\n if (this.lastEvaluated.size > 1000) {\n const entries = Array.from(this.lastEvaluated.entries());\n entries.sort((a, b) => b[1] - a[1]);\n this.lastEvaluated = new Map(entries.slice(0, 1000));\n }\n\n return result;\n }\n}\n\nexport interface GraduationRunResult {\n evaluated: number;\n graduated: number;\n byLevel: Record<string, number>;\n}\n\n/**\n * Create a Graduation Worker instance\n */\nexport function createGraduationWorker(\n eventStore: EventStore,\n graduation: GraduationPipeline,\n config?: Partial<GraduationWorkerConfig>\n): GraduationWorker {\n return new GraduationWorker(\n eventStore,\n graduation,\n { ...DEFAULT_CONFIG, ...config }\n );\n}\n", "import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { MemoryEventInput } from './types.js';\n\nfunction sanitizeSegment(input: string | undefined, fallback: string): string {\n const v = (input || '').trim().toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');\n return v || fallback;\n}\n\nfunction getAtPath(obj: Record<string, unknown> | undefined, dotted: string): unknown {\n if (!obj) return undefined;\n return dotted.split('.').reduce<unknown>((acc, key) => {\n if (!acc || typeof acc !== 'object') return undefined;\n return (acc as Record<string, unknown>)[key];\n }, obj);\n}\n\nexport function buildMirrorPath(rootDir: string, event: MemoryEventInput): string {\n const meta = event.metadata as Record<string, unknown> | undefined;\n\n const namespaceRaw = getAtPath(meta, 'namespace') ?? getAtPath(meta, 'scope.namespace') ?? event.eventType;\n const namespace = sanitizeSegment(typeof namespaceRaw === 'string' ? namespaceRaw : undefined, 'general');\n\n const categoryRaw = getAtPath(meta, 'categoryPath') ?? getAtPath(meta, 'scope.categoryPath');\n const categoryPath = Array.isArray(categoryRaw) && categoryRaw.length > 0\n ? categoryRaw.map((x) => sanitizeSegment(typeof x === 'string' ? x : undefined, 'uncategorized'))\n : ['uncategorized'];\n\n const d = event.timestamp;\n const yyyy = d.getFullYear();\n const mm = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n\n return path.join(rootDir, 'memory', namespace, ...categoryPath, `${yyyy}-${mm}-${dd}.md`);\n}\n\nexport class MarkdownMirror {\n constructor(private readonly rootDir: string) {}\n\n async append(event: MemoryEventInput, eventId?: string): Promise<void> {\n const out = buildMirrorPath(this.rootDir, event);\n fs.mkdirSync(path.dirname(out), { recursive: true });\n\n const lines = [\n '',\n `## ${event.timestamp.toISOString()} | ${eventId ?? 'pending-id'}`,\n `- type: ${event.eventType}`,\n `- session: ${event.sessionId}`,\n event.content,\n ];\n\n await fs.promises.appendFile(out, lines.join('\\n'), 'utf8');\n await this.refreshIndex();\n }\n\n private async refreshIndex(): Promise<void> {\n const memoryRoot = path.join(this.rootDir, 'memory');\n await fs.promises.mkdir(memoryRoot, { recursive: true });\n\n const files: string[] = [];\n await this.walk(memoryRoot, files);\n\n const mdFiles = files\n .filter((f) => f.endsWith('.md'))\n .map((f) => path.relative(this.rootDir, f))\n .filter((rel) => rel !== path.join('memory', '_index.md'))\n .sort();\n\n const index = [\n '# Memory Index',\n '',\n 'Generated automatically by MarkdownMirror.',\n '',\n ...mdFiles.map((rel) => `- ${rel}`),\n '',\n ].join('\\n');\n\n await fs.promises.writeFile(path.join(memoryRoot, '_index.md'), index, 'utf8');\n }\n\n private async walk(dir: string, out: string[]): Promise<void> {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n for (const e of entries) {\n const full = path.join(dir, e.name);\n if (e.isDirectory()) {\n await this.walk(full, out);\n } else {\n out.push(full);\n }\n }\n }\n}\n", "import type { MemoryEventInput } from './types.js';\n\nexport type IngestStage = 'before' | 'after' | 'error';\n\nexport interface IngestContext {\n stage: IngestStage;\n operation: 'user_prompt' | 'agent_response' | 'session_summary' | 'tool_observation';\n sessionId: string;\n event: MemoryEventInput;\n error?: Error;\n}\n\nexport type IngestInterceptor = (context: IngestContext) => Promise<void> | void;\n\nexport class IngestInterceptorRegistry {\n private before: IngestInterceptor[] = [];\n private after: IngestInterceptor[] = [];\n private onError: IngestInterceptor[] = [];\n\n registerBefore(interceptor: IngestInterceptor): () => void {\n this.before.push(interceptor);\n return () => {\n this.before = this.before.filter((i) => i !== interceptor);\n };\n }\n\n registerAfter(interceptor: IngestInterceptor): () => void {\n this.after.push(interceptor);\n return () => {\n this.after = this.after.filter((i) => i !== interceptor);\n };\n }\n\n registerOnError(interceptor: IngestInterceptor): () => void {\n this.onError.push(interceptor);\n return () => {\n this.onError = this.onError.filter((i) => i !== interceptor);\n };\n }\n\n async run(stage: IngestStage, context: Omit<IngestContext, 'stage'>): Promise<void> {\n const interceptors = stage === 'before'\n ? this.before\n : stage === 'after'\n ? this.after\n : this.onError;\n\n for (const interceptor of interceptors) {\n await interceptor({ ...context, stage });\n }\n }\n}\n\nexport function mergeHierarchicalMetadata(\n base: Record<string, unknown> | undefined,\n patch: Record<string, unknown> | undefined\n): Record<string, unknown> | undefined {\n if (!base && !patch) return undefined;\n if (!base) return patch;\n if (!patch) return base;\n\n const result: Record<string, unknown> = { ...base };\n\n for (const [key, value] of Object.entries(patch)) {\n const current = result[key];\n if (\n typeof current === 'object' && current !== null && !Array.isArray(current) &&\n typeof value === 'object' && value !== null && !Array.isArray(value)\n ) {\n result[key] = mergeHierarchicalMetadata(\n current as Record<string, unknown>,\n value as Record<string, unknown>\n );\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n", "export const TAG_NAMESPACES = {\n SYSTEM: 'sys:',\n QUALITY: 'q:',\n PROJECT: 'proj:',\n TOPIC: 'topic:',\n TEMPORAL: 't:',\n USER: 'user:',\n AGENT: 'agent:'\n} as const;\n\nexport const VALID_TAG_NAMESPACES = new Set<string>(Object.values(TAG_NAMESPACES));\n\nexport function parseTag(tag: string): { namespace?: string; value: string } {\n const value = (tag || '').trim();\n const idx = value.indexOf(':');\n if (idx <= 0) return { value };\n\n const namespace = `${value.slice(0, idx)}:`;\n const tagValue = value.slice(idx + 1);\n if (!tagValue) return { value };\n\n return { namespace, value: tagValue };\n}\n\nexport function validateTag(tag: string): boolean {\n const normalized = (tag || '').trim();\n if (!normalized) return false;\n\n const { namespace } = parseTag(normalized);\n if (!namespace) return true; // backward compatibility for legacy tags\n return VALID_TAG_NAMESPACES.has(namespace);\n}\n\nexport function withNamespace(value: string, namespace: string): string {\n const clean = parseTag(value).value.trim();\n return `${namespace}${clean}`;\n}\n\nexport function normalizeTags(tags: unknown): string[] {\n if (!Array.isArray(tags)) return [];\n\n const dedup = new Set<string>();\n for (const item of tags) {\n if (typeof item !== 'string') continue;\n const normalized = item.trim();\n if (!validateTag(normalized)) continue;\n dedup.add(normalized);\n }\n\n return [...dedup];\n}\n", "#!/usr/bin/env node\n/**\n * Session Start Hook\n * Called when a new Claude Code session starts\n */\n\nimport {\n getLightweightMemoryService,\n registerSession\n} from '../services/memory-service.js';\nimport type { SessionStartInput, SessionStartOutput } from '../core/types.js';\n\nasync function main(): Promise<void> {\n // Read input from stdin\n const inputData = await readStdin();\n const input: SessionStartInput = JSON.parse(inputData);\n\n // Register session with project path for other hooks to find\n registerSession(input.session_id, input.cwd);\n\n // Use lightweight service to avoid starting background workers in hook process\n const memoryService = getLightweightMemoryService(input.session_id);\n\n try {\n // Start session in memory service\n await memoryService.startSession(input.session_id, input.cwd);\n\n // Get recent context for this project (now automatically scoped)\n const recentEvents = await memoryService.getRecentEvents(10);\n\n let context = '';\n if (recentEvents.length > 0) {\n context = `## Previous Session Context\\n\\nYou have worked on this project before. Here are some relevant memories:\\n\\n`;\n for (const event of recentEvents.slice(0, 3)) {\n const date = event.timestamp.toISOString().split('T')[0];\n context += `- **${date}**: ${event.content.slice(0, 150)}...\\n`;\n }\n }\n\n const output: SessionStartOutput = { context };\n console.log(JSON.stringify(output));\n } catch (error) {\n console.error('Memory hook error:', error);\n console.log(JSON.stringify({ context: '' }));\n } finally {\n try {\n await memoryService.close();\n } catch {\n // Best-effort cleanup\n }\n }\n}\n\nfunction readStdin(): Promise<string> {\n return new Promise((resolve) => {\n let data = '';\n process.stdin.setEncoding('utf8');\n process.stdin.on('data', (chunk) => {\n data += chunk;\n });\n process.stdin.on('end', () => {\n resolve(data);\n });\n });\n}\n\nmain().catch(console.error);\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["path", "fs", "crypto", "path", "resolve", "randomUUID", "path", "fs", "randomUUID", "resolve", "DEFAULT_CONFIG", "DEFAULT_CONFIG", "DEFAULT_CONFIG", "filtered", "path", "randomUUID", "randomUUID", "lancedb", "randomUUID", "randomUUID", "randomUUID", "randomUUID", "randomUUID", "randomUUID", "randomUUID", "DEFAULT_CONFIG", "fs", "path", "sanitizeSegment", "buildMirrorPath", "MarkdownMirror", "MarkdownMirror", "resolve"]
|
|
3
|
+
"sources": ["../../src/services/memory-service.ts", "../../src/core/event-store.ts", "../../src/core/canonical-key.ts", "../../src/core/db-wrapper.ts", "../../src/core/sqlite-event-store.ts", "../../src/core/sqlite-wrapper.ts", "../../src/core/markdown-mirror.ts", "../../src/core/sync-worker.ts", "../../src/core/vector-store.ts", "../../src/core/embedder.ts", "../../src/core/vector-outbox.ts", "../../src/core/vector-worker.ts", "../../src/core/matcher.ts", "../../src/core/retriever.ts", "../../src/core/graduation.ts", "../../src/core/shared-event-store.ts", "../../src/core/shared-store.ts", "../../src/core/shared-vector-store.ts", "../../src/core/shared-promoter.ts", "../../src/core/metadata-extractor.ts", "../../src/core/working-set-store.ts", "../../src/core/consolidated-store.ts", "../../src/core/consolidation-worker.ts", "../../src/core/continuity-manager.ts", "../../src/core/graduation-worker.ts", "../../src/core/md-mirror.ts", "../../src/core/ingest-interceptor.ts", "../../src/core/tag-taxonomy.ts", "../../src/hooks/semantic-daemon-client.ts", "../../src/hooks/session-start.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Memory Service - Main entry point for memory operations\n * Coordinates EventStore, VectorStore, Retriever, and Graduation\n */\n\nimport * as path from 'path';\nimport * as os from 'os';\nimport * as fs from 'fs';\nimport * as crypto from 'crypto';\n\nimport { EventStore } from '../core/event-store.js';\nimport { SQLiteEventStore } from '../core/sqlite-event-store.js';\nimport { SyncWorker } from '../core/sync-worker.js';\nimport { VectorStore } from '../core/vector-store.js';\nimport { Embedder, getDefaultEmbedder } from '../core/embedder.js';\nimport { VectorWorker, createVectorWorker } from '../core/vector-worker.js';\nimport { Matcher, getDefaultMatcher } from '../core/matcher.js';\nimport { Retriever, createRetriever, RetrievalResult, UnifiedRetrievalResult } from '../core/retriever.js';\nimport { GraduationPipeline, createGraduationPipeline } from '../core/graduation.js';\nimport { SharedEventStore, createSharedEventStore } from '../core/shared-event-store.js';\nimport { SharedStore, createSharedStore } from '../core/shared-store.js';\nimport { SharedVectorStore, createSharedVectorStore } from '../core/shared-vector-store.js';\nimport { SharedPromoter, createSharedPromoter, PromotionResult } from '../core/shared-promoter.js';\nimport type {\n MemoryEventInput,\n AppendResult,\n MemoryEvent,\n Config,\n ConfigSchema,\n ToolObservationPayload,\n MemoryMode,\n EndlessModeConfig,\n EndlessModeConfigSchema,\n WorkingSet,\n ConsolidatedMemory,\n EndlessModeStatus,\n ContextSnapshot,\n ContinuityScore,\n SharedStoreConfig,\n Entry\n} from '../core/types.js';\nimport { createToolObservationEmbedding } from '../core/metadata-extractor.js';\nimport { WorkingSetStore, createWorkingSetStore } from '../core/working-set-store.js';\nimport { ConsolidatedStore, createConsolidatedStore } from '../core/consolidated-store.js';\nimport { ConsolidationWorker, createConsolidationWorker } from '../core/consolidation-worker.js';\nimport { ContinuityManager, createContinuityManager } from '../core/continuity-manager.js';\nimport { GraduationWorker, createGraduationWorker, GraduationRunResult } from '../core/graduation-worker.js';\nimport { MarkdownMirror } from '../core/md-mirror.js';\nimport {\n IngestInterceptor,\n IngestInterceptorRegistry,\n mergeHierarchicalMetadata\n} from '../core/ingest-interceptor.js';\nimport { normalizeTags } from '../core/tag-taxonomy.js';\n\nexport interface MemoryServiceConfig {\n storagePath: string;\n embeddingModel?: string;\n readOnly?: boolean;\n /** Enable DuckDB analytics store (default: true for server, false for hooks) */\n analyticsEnabled?: boolean;\n /** Lightweight mode for hooks - skip heavy initialization (default: false) */\n lightweightMode?: boolean;\n /** Start only VectorWorker, skip GraduationWorker and SyncWorker (default: false) */\n embeddingOnly?: boolean;\n}\n\n// ============================================================\n// Project Path Utilities\n// ============================================================\n\n/**\n * Normalize and resolve a project path, handling symlinks\n */\nfunction normalizePath(projectPath: string): string {\n const expanded = projectPath.startsWith('~')\n ? path.join(os.homedir(), projectPath.slice(1))\n : projectPath;\n\n try {\n // Resolve symlinks for consistent paths\n return fs.realpathSync(expanded);\n } catch {\n // Path doesn't exist yet, just resolve it\n return path.resolve(expanded);\n }\n}\n\n/**\n * Generate a stable 8-character hash from a project path\n */\nexport function hashProjectPath(projectPath: string): string {\n const normalizedPath = normalizePath(projectPath);\n return crypto.createHash('sha256')\n .update(normalizedPath)\n .digest('hex')\n .slice(0, 8);\n}\n\n/**\n * Get the storage path for a specific project\n */\nexport function getProjectStoragePath(projectPath: string): string {\n const hash = hashProjectPath(projectPath);\n return path.join(os.homedir(), '.claude-code', 'memory', 'projects', hash);\n}\n\n// ============================================================\n// Session Registry\n// ============================================================\n\nconst REGISTRY_PATH = path.join(os.homedir(), '.claude-code', 'memory', 'session-registry.json');\nconst SHARED_STORAGE_PATH = path.join(os.homedir(), '.claude-code', 'memory', 'shared');\n\nexport interface SessionRegistryEntry {\n projectPath: string;\n projectHash: string;\n registeredAt: string;\n}\n\nexport interface SessionRegistry {\n version: number;\n sessions: Record<string, SessionRegistryEntry>;\n}\n\nexport function loadSessionRegistry(): SessionRegistry {\n try {\n if (fs.existsSync(REGISTRY_PATH)) {\n const data = fs.readFileSync(REGISTRY_PATH, 'utf-8');\n return JSON.parse(data);\n }\n } catch (error) {\n console.error('Failed to load session registry:', error);\n }\n return { version: 1, sessions: {} };\n}\n\nfunction saveSessionRegistry(registry: SessionRegistry): void {\n const dir = path.dirname(REGISTRY_PATH);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Atomic write using temp file\n const tempPath = REGISTRY_PATH + '.tmp';\n fs.writeFileSync(tempPath, JSON.stringify(registry, null, 2));\n fs.renameSync(tempPath, REGISTRY_PATH);\n}\n\n/**\n * Register a session with its project path\n */\nexport function registerSession(sessionId: string, projectPath: string): void {\n const registry = loadSessionRegistry();\n\n registry.sessions[sessionId] = {\n projectPath: normalizePath(projectPath),\n projectHash: hashProjectPath(projectPath),\n registeredAt: new Date().toISOString()\n };\n\n // Clean up old sessions (keep last 1000)\n const entries = Object.entries(registry.sessions);\n if (entries.length > 1000) {\n const sorted = entries.sort((a, b) =>\n new Date(b[1].registeredAt).getTime() - new Date(a[1].registeredAt).getTime()\n );\n registry.sessions = Object.fromEntries(sorted.slice(0, 1000));\n }\n\n saveSessionRegistry(registry);\n}\n\n/**\n * Get the project path for a session\n */\nexport function getSessionProject(sessionId: string): SessionRegistryEntry | null {\n const registry = loadSessionRegistry();\n return registry.sessions[sessionId] || null;\n}\n\nexport class MemoryService {\n // Primary store: SQLite (WAL mode) - for hooks, always available\n private readonly sqliteStore: SQLiteEventStore;\n // Analytics store: DuckDB - for server reads (optional, synced from SQLite)\n private readonly analyticsStore: EventStore | null;\n private syncWorker: SyncWorker | null = null;\n\n private readonly vectorStore: VectorStore;\n private readonly embedder: Embedder;\n private readonly matcher: Matcher;\n private readonly retriever: Retriever;\n private readonly graduation: GraduationPipeline;\n private vectorWorker: VectorWorker | null = null;\n private graduationWorker: GraduationWorker | null = null;\n private initialized = false;\n private readonly ingestInterceptors = new IngestInterceptorRegistry();\n\n // Endless Mode components\n private workingSetStore: WorkingSetStore | null = null;\n private consolidatedStore: ConsolidatedStore | null = null;\n private consolidationWorker: ConsolidationWorker | null = null;\n private continuityManager: ContinuityManager | null = null;\n private endlessMode: MemoryMode = 'session';\n\n // Shared Store components (cross-project knowledge)\n private sharedEventStore: SharedEventStore | null = null;\n private sharedStore: SharedStore | null = null;\n private sharedVectorStore: SharedVectorStore | null = null;\n private sharedPromoter: SharedPromoter | null = null;\n private sharedStoreConfig: SharedStoreConfig | null = null;\n private projectHash: string | null = null;\n private projectPath: string | null = null;\n\n private readonly readOnly: boolean;\n private readonly lightweightMode: boolean;\n private readonly embeddingOnly: boolean;\n private readonly mdMirror: MarkdownMirror;\n private readonly storagePath: string;\n\n constructor(config: MemoryServiceConfig & { projectHash?: string; projectPath?: string; sharedStoreConfig?: SharedStoreConfig }) {\n const storagePath = this.expandPath(config.storagePath);\n this.storagePath = storagePath;\n this.readOnly = config.readOnly ?? false;\n this.lightweightMode = config.lightweightMode ?? false;\n this.embeddingOnly = config.embeddingOnly ?? false;\n this.mdMirror = new MarkdownMirror(process.cwd());\n\n // Ensure storage directory exists (only if not read-only)\n if (!this.readOnly && !fs.existsSync(storagePath)) {\n fs.mkdirSync(storagePath, { recursive: true });\n }\n\n // Store project hash for shared store operations\n this.projectHash = config.projectHash || null;\n this.projectPath = config.projectPath || null;\n // Default: shared store enabled\n this.sharedStoreConfig = config.sharedStoreConfig ?? { enabled: true };\n\n // Initialize PRIMARY store: SQLite (WAL mode)\n // This is always used for writes and is the source of truth\n this.sqliteStore = new SQLiteEventStore(\n path.join(storagePath, 'events.sqlite'),\n {\n readonly: this.readOnly,\n markdownMirrorRoot: storagePath\n }\n );\n\n // Initialize ANALYTICS store: DuckDB (optional, for server reads)\n // Hooks set analyticsEnabled=false to avoid DuckDB lock conflicts\n const analyticsEnabled = config.analyticsEnabled ?? this.readOnly; // Default: enabled only for read-only (server)\n\n if (!analyticsEnabled) {\n // Hook mode: skip DuckDB entirely to avoid lock conflicts\n this.analyticsStore = null;\n } else if (this.readOnly) {\n // Server mode: try to use DuckDB for analytics, will fallback to SQLite\n try {\n this.analyticsStore = new EventStore(\n path.join(storagePath, 'analytics.duckdb'),\n { readOnly: true }\n );\n } catch {\n // DuckDB not available, will use SQLite for reads\n this.analyticsStore = null;\n }\n } else {\n // Writer mode with analytics: create DuckDB for sync target\n this.analyticsStore = new EventStore(\n path.join(storagePath, 'analytics.duckdb'),\n { readOnly: false }\n );\n }\n\n this.vectorStore = new VectorStore(path.join(storagePath, 'vectors'));\n const embeddingModel = config.embeddingModel || process.env.CLAUDE_MEMORY_EMBEDDING_MODEL;\n this.embedder = embeddingModel\n ? new Embedder(embeddingModel)\n : getDefaultEmbedder();\n this.matcher = getDefaultMatcher();\n // Retriever uses SQLite as primary (always available)\n this.retriever = createRetriever(\n this.sqliteStore as unknown as EventStore, // Interface compatible\n this.vectorStore,\n this.embedder,\n this.matcher\n );\n this.retriever.setQueryRewriter((q) => this.rewriteQueryIntent(q));\n this.graduation = createGraduationPipeline(this.sqliteStore as unknown as EventStore);\n }\n\n /**\n * Initialize all components\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Initialize PRIMARY store: SQLite (always)\n await this.sqliteStore.initialize();\n\n // Lightweight mode: only SQLite, no embedder/vector/workers\n // Used for hooks that just need to store data quickly\n if (this.lightweightMode) {\n this.initialized = true;\n return;\n }\n\n // Initialize analytics store if available (DuckDB)\n if (this.analyticsStore) {\n try {\n await this.analyticsStore.initialize();\n } catch (error) {\n console.warn('[MemoryService] Analytics store (DuckDB) initialization failed, using SQLite for reads:', error);\n // Continue without analytics - SQLite will be used for reads\n }\n }\n\n await this.vectorStore.initialize();\n await this.embedder.initialize();\n\n // Skip write-related workers in read-only mode\n if (!this.readOnly) {\n // Start vector worker (uses SQLite as source)\n this.vectorWorker = createVectorWorker(\n this.sqliteStore as unknown as EventStore,\n this.vectorStore,\n this.embedder\n );\n this.vectorWorker.start();\n\n if (!this.embeddingOnly) {\n // Connect graduation pipeline to retriever for access tracking\n this.retriever.setGraduationPipeline(this.graduation);\n\n // Start graduation worker for automatic level promotion\n this.graduationWorker = createGraduationWorker(\n this.sqliteStore as unknown as EventStore,\n this.graduation\n );\n this.graduationWorker.start();\n\n // Start sync worker (SQLite -> DuckDB) if analytics store is available\n if (this.analyticsStore) {\n this.syncWorker = new SyncWorker(\n this.sqliteStore,\n this.analyticsStore,\n { intervalMs: 30000, batchSize: 500 }\n );\n this.syncWorker.start();\n }\n }\n\n // Load endless mode setting\n const savedMode = await this.sqliteStore.getEndlessConfig('mode') as MemoryMode | null;\n if (savedMode === 'endless') {\n this.endlessMode = 'endless';\n await this.initializeEndlessMode();\n }\n\n // Initialize shared store (enabled by default)\n if (this.sharedStoreConfig?.enabled !== false) {\n await this.initializeSharedStore();\n }\n }\n\n this.initialized = true;\n }\n\n /**\n * Initialize Shared Store components\n */\n private async initializeSharedStore(): Promise<void> {\n const sharedPath = this.sharedStoreConfig?.sharedStoragePath\n ? this.expandPath(this.sharedStoreConfig.sharedStoragePath)\n : SHARED_STORAGE_PATH;\n\n // Ensure shared directory exists\n if (!fs.existsSync(sharedPath)) {\n fs.mkdirSync(sharedPath, { recursive: true });\n }\n\n this.sharedEventStore = createSharedEventStore(\n path.join(sharedPath, 'shared.duckdb')\n );\n await this.sharedEventStore.initialize();\n\n this.sharedStore = createSharedStore(this.sharedEventStore);\n this.sharedVectorStore = createSharedVectorStore(\n path.join(sharedPath, 'vectors')\n );\n await this.sharedVectorStore.initialize();\n\n this.sharedPromoter = createSharedPromoter(\n this.sharedStore,\n this.sharedVectorStore,\n this.embedder,\n this.sharedStoreConfig || undefined\n );\n\n // Connect shared stores to retriever\n this.retriever.setSharedStores(this.sharedStore, this.sharedVectorStore);\n }\n\n registerIngestBefore(interceptor: IngestInterceptor): () => void {\n return this.ingestInterceptors.registerBefore(interceptor);\n }\n\n registerIngestAfter(interceptor: IngestInterceptor): () => void {\n return this.ingestInterceptors.registerAfter(interceptor);\n }\n\n registerIngestOnError(interceptor: IngestInterceptor): () => void {\n return this.ingestInterceptors.registerOnError(interceptor);\n }\n\n private async ingestWithInterceptors(\n operation: 'user_prompt' | 'agent_response' | 'session_summary' | 'tool_observation',\n input: MemoryEventInput,\n onSuccess?: (eventId: string) => Promise<void>\n ): Promise<AppendResult> {\n const normalizedInput: MemoryEventInput = {\n ...input,\n metadata: mergeHierarchicalMetadata(\n {\n ingest: {\n operation,\n pipeline: 'default',\n ts: new Date().toISOString()\n },\n ...(this.projectHash\n ? {\n scope: {\n project: {\n hash: this.projectHash,\n ...(this.projectPath ? { path: this.projectPath } : {})\n }\n },\n tags: [`proj:${this.projectHash}`]\n }\n : {})\n },\n input.metadata\n )\n };\n\n if (this.projectHash && normalizedInput.metadata) {\n const meta = normalizedInput.metadata as Record<string, unknown>;\n const currentTags = Array.isArray(meta.tags)\n ? meta.tags.filter((x): x is string => typeof x === 'string')\n : [];\n const projectTag = `proj:${this.projectHash}`;\n if (!currentTags.includes(projectTag)) {\n meta.tags = [...currentTags, projectTag];\n }\n }\n\n if (normalizedInput.metadata) {\n const meta = normalizedInput.metadata as Record<string, unknown>;\n const normalizedTags = normalizeTags(meta.tags);\n if (normalizedTags.length > 0) {\n meta.tags = normalizedTags;\n }\n }\n\n await this.ingestInterceptors.run('before', {\n operation,\n sessionId: normalizedInput.sessionId,\n event: normalizedInput\n });\n\n try {\n const result = await this.sqliteStore.append(normalizedInput);\n if (result.success && !result.isDuplicate) {\n if (onSuccess) {\n await onSuccess(result.eventId);\n }\n try {\n await this.mdMirror.append(normalizedInput, result.eventId);\n } catch {\n // non-breaking markdown mirror write\n }\n }\n\n await this.ingestInterceptors.run('after', {\n operation,\n sessionId: normalizedInput.sessionId,\n event: normalizedInput\n });\n\n return result;\n } catch (error) {\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n await this.ingestInterceptors.run('error', {\n operation,\n sessionId: normalizedInput.sessionId,\n event: normalizedInput,\n error: normalizedError\n });\n throw error;\n }\n }\n\n /**\n * Start a new session\n */\n async startSession(sessionId: string, projectPath?: string): Promise<void> {\n await this.initialize();\n\n await this.sqliteStore.upsertSession({\n id: sessionId,\n startedAt: new Date(),\n projectPath\n });\n }\n\n /**\n * End a session\n */\n async endSession(sessionId: string, summary?: string): Promise<void> {\n await this.initialize();\n\n await this.sqliteStore.upsertSession({\n id: sessionId,\n endedAt: new Date(),\n summary\n });\n }\n\n /**\n * Store a user prompt\n */\n async storeUserPrompt(\n sessionId: string,\n content: string,\n metadata?: Record<string, unknown>\n ): Promise<AppendResult> {\n await this.initialize();\n\n return this.ingestWithInterceptors(\n 'user_prompt',\n {\n eventType: 'user_prompt',\n sessionId,\n timestamp: new Date(),\n content,\n metadata\n },\n async (eventId) => {\n await this.sqliteStore.enqueueForEmbedding(eventId, content);\n }\n );\n }\n\n /**\n * Store an agent response\n */\n async storeAgentResponse(\n sessionId: string,\n content: string,\n metadata?: Record<string, unknown>\n ): Promise<AppendResult> {\n await this.initialize();\n\n return this.ingestWithInterceptors(\n 'agent_response',\n {\n eventType: 'agent_response',\n sessionId,\n timestamp: new Date(),\n content,\n metadata\n },\n async (eventId) => {\n await this.sqliteStore.enqueueForEmbedding(eventId, content);\n }\n );\n }\n\n /**\n * Store a session summary\n */\n async storeSessionSummary(\n sessionId: string,\n summary: string,\n metadata?: Record<string, unknown>\n ): Promise<AppendResult> {\n await this.initialize();\n\n return this.ingestWithInterceptors(\n 'session_summary',\n {\n eventType: 'session_summary',\n sessionId,\n timestamp: new Date(),\n content: summary,\n metadata\n },\n async (eventId) => {\n await this.sqliteStore.enqueueForEmbedding(eventId, summary);\n }\n );\n }\n\n /**\n * Store a tool observation\n */\n async storeToolObservation(\n sessionId: string,\n payload: ToolObservationPayload\n ): Promise<AppendResult> {\n await this.initialize();\n\n // Create content for storage (JSON stringified payload)\n const content = JSON.stringify(payload);\n\n // Extract turnId from payload metadata if present (set by PostToolUse hook)\n const turnId = payload.metadata?.turnId;\n\n return this.ingestWithInterceptors(\n 'tool_observation',\n {\n eventType: 'tool_observation',\n sessionId,\n timestamp: new Date(),\n content,\n metadata: {\n toolName: payload.toolName,\n success: payload.success,\n ...(turnId ? { turnId } : {})\n }\n },\n async (eventId) => {\n const embeddingContent = createToolObservationEmbedding(\n payload.toolName,\n payload.metadata || {},\n payload.success\n );\n await this.sqliteStore.enqueueForEmbedding(eventId, embeddingContent);\n }\n );\n }\n\n /**\n * Retrieve relevant memories for a query\n */\n async retrieveMemories(\n query: string,\n options?: {\n topK?: number;\n minScore?: number;\n sessionId?: string;\n includeShared?: boolean;\n adaptiveRerank?: boolean;\n intentRewrite?: boolean;\n projectScopeMode?: 'strict' | 'prefer' | 'global';\n allowedProjectHashes?: string[];\n }\n ): Promise<UnifiedRetrievalResult> {\n await this.initialize();\n\n // Note: Pending embeddings are processed by the background worker\n // Don't block retrieval - search with whatever vectors are available\n\n const rerankWeights = await this.getRerankWeights(options?.adaptiveRerank === true);\n\n // Use unified retrieval if shared search is requested\n let result: UnifiedRetrievalResult;\n\n if (options?.includeShared && this.sharedStore) {\n result = await this.retriever.retrieveUnified(query, {\n ...options,\n intentRewrite: options?.intentRewrite === true,\n rerankWeights,\n includeShared: true,\n projectHash: this.projectHash || undefined,\n projectScopeMode: options?.projectScopeMode ?? (this.projectHash ? 'strict' : 'global'),\n allowedProjectHashes: options?.allowedProjectHashes\n });\n } else {\n result = await this.retriever.retrieve(query, {\n ...options,\n intentRewrite: options?.intentRewrite === true,\n rerankWeights,\n projectHash: this.projectHash || undefined,\n projectScopeMode: options?.projectScopeMode ?? (this.projectHash ? 'strict' : 'global'),\n allowedProjectHashes: options?.allowedProjectHashes\n });\n }\n\n try {\n const selectedEventIds = result.memories.map((m) => m.event.id);\n const selectedDetails = (result.selectedDebug || []).map((d) => ({\n eventId: d.eventId,\n score: d.score,\n semanticScore: d.semanticScore,\n lexicalScore: d.lexicalScore,\n recencyScore: d.recencyScore,\n }));\n const candidateDetails = (result.candidateDebug || []).map((d) => ({\n eventId: d.eventId,\n score: d.score,\n semanticScore: d.semanticScore,\n lexicalScore: d.lexicalScore,\n recencyScore: d.recencyScore,\n }));\n const candidateEventIds = candidateDetails.length > 0\n ? candidateDetails.map((d) => d.eventId)\n : selectedEventIds;\n await this.sqliteStore.recordRetrievalTrace({\n sessionId: options?.sessionId,\n projectHash: this.projectHash || undefined,\n queryText: query,\n strategy: options?.strategy || 'auto',\n candidateEventIds,\n selectedEventIds,\n candidateDetails,\n selectedDetails,\n confidence: result.matchResult.confidence,\n fallbackTrace: result.fallbackTrace || []\n });\n } catch {\n // non-blocking telemetry\n }\n\n return result;\n }\n\n private getConfiguredRerankWeights(): { semantic: number; lexical: number; recency: number } | undefined {\n const semantic = Number(process.env.MEMORY_RERANK_WEIGHT_SEMANTIC ?? '');\n const lexical = Number(process.env.MEMORY_RERANK_WEIGHT_LEXICAL ?? '');\n const recency = Number(process.env.MEMORY_RERANK_WEIGHT_RECENCY ?? '');\n\n const allFinite = [semantic, lexical, recency].every((v) => Number.isFinite(v));\n if (!allFinite) return undefined;\n\n const nonNegative = [semantic, lexical, recency].every((v) => v >= 0);\n const total = semantic + lexical + recency;\n if (!nonNegative || total <= 0) return undefined;\n\n return {\n semantic: semantic / total,\n lexical: lexical / total,\n recency: recency / total,\n };\n }\n\n private async getRerankWeights(adaptive: boolean): Promise<{ semantic: number; lexical: number; recency: number } | undefined> {\n const configured = this.getConfiguredRerankWeights();\n if (configured) return configured;\n if (adaptive) return this.getAdaptiveRerankWeights();\n return undefined;\n }\n\n private async rewriteQueryIntent(query: string): Promise<string | null> {\n if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== '1') return null;\n\n const apiUrl = process.env.COMPANY_STOCK_API_URL || process.env.COMPANY_INT_API_URL;\n if (!apiUrl) return null;\n\n const controller = new AbortController();\n const timeoutMs = Number(process.env.MEMORY_INTENT_REWRITE_TIMEOUT_MS || 5000);\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const prompt = [\n 'Rewrite user query for memory retrieval intent expansion.',\n 'Return plain text only, one line, no markdown.',\n `Query: ${query}`,\n ].join('\\n');\n\n const res = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: '*/*',\n Origin: process.env.COMPANY_INT_ORIGIN || 'http://company-int.aplusai.ai',\n Referer: process.env.COMPANY_INT_REFERER || 'http://company-int.aplusai.ai/',\n },\n body: JSON.stringify({\n question: prompt,\n company_name: null,\n conversation_id: null,\n }),\n signal: controller.signal,\n });\n\n const text = (await res.text()).trim();\n if (!text) return null;\n\n const oneLine = text\n .replace(/^data:\\s*/gm, '')\n .split(/\\r?\\n/)\n .map((x) => x.trim())\n .filter(Boolean)\n .join(' ')\n .slice(0, 240);\n\n if (!oneLine || oneLine.toLowerCase() === query.toLowerCase()) return null;\n return oneLine;\n } catch {\n return null;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private async getAdaptiveRerankWeights(): Promise<{ semantic: number; lexical: number; recency: number } | undefined> {\n try {\n const s = await this.sqliteStore.getHelpfulnessStats();\n if (s.totalEvaluated < 20) return undefined;\n\n // base weights\n let semantic = 0.7;\n let lexical = 0.2;\n let recency = 0.1;\n\n if (s.avgScore < 0.45) {\n semantic -= 0.1;\n lexical += 0.1;\n } else if (s.avgScore > 0.75) {\n semantic += 0.05;\n lexical -= 0.05;\n }\n\n if (s.unhelpful > s.helpful) {\n recency += 0.05;\n semantic -= 0.03;\n lexical -= 0.02;\n }\n\n return { semantic, lexical, recency };\n } catch {\n return undefined;\n }\n }\n\n /**\n * Fast keyword search using SQLite FTS5\n * Much faster than vector search - no embedding model needed\n */\n async keywordSearch(\n query: string,\n options?: { topK?: number; minScore?: number }\n ): Promise<Array<{event: MemoryEvent; score: number}>> {\n await this.initialize();\n\n const results = await this.sqliteStore.keywordSearch(query, options?.topK ?? 10);\n\n // Normalize FTS5 rank to a score (0-1 range)\n // FTS5 rank is negative (higher is worse), so we convert it\n const maxRank = Math.min(...results.map(r => r.rank), -0.001);\n const minRank = Math.max(...results.map(r => r.rank), -1000);\n const rankRange = maxRank - minRank || 1;\n\n return results.map(r => ({\n event: r.event,\n score: 1 - (r.rank - minRank) / rankRange // Normalize to 0-1\n })).filter(r => !options?.minScore || r.score >= options.minScore);\n }\n\n /**\n * Rebuild FTS index (call after database upgrade)\n */\n async rebuildFtsIndex(): Promise<number> {\n await this.initialize();\n return this.sqliteStore.rebuildFtsIndex();\n }\n\n /**\n * Get session history\n */\n async getSessionHistory(sessionId: string): Promise<MemoryEvent[]> {\n await this.initialize();\n return this.sqliteStore.getSessionEvents(sessionId);\n }\n\n /**\n * Get recent events\n */\n async getRecentEvents(limit: number = 100): Promise<MemoryEvent[]> {\n await this.initialize();\n return this.sqliteStore.getRecentEvents(limit);\n }\n\n /**\n * Get memory statistics\n */\n\n async getOutboxStats(): Promise<{\n embedding: { pending: number; processing: number; failed: number; total: number };\n vector: { pending: number; processing: number; failed: number; total: number };\n }> {\n await this.initialize();\n return this.sqliteStore.getOutboxStats();\n }\n\n async getRetrievalTraceStats(): Promise<{\n totalQueries: number;\n avgCandidateCount: number;\n avgSelectedCount: number;\n selectionRate: number;\n }> {\n await this.initialize();\n return this.sqliteStore.getRetrievalTraceStats();\n }\n\n async getRecentRetrievalTraces(limit: number = 50) {\n await this.initialize();\n return this.sqliteStore.getRecentRetrievalTraces(limit);\n }\n\n async getStats(): Promise<{\n totalEvents: number;\n vectorCount: number;\n levelStats: Array<{ level: string; count: number }>;\n }> {\n await this.initialize();\n\n const recentEvents = await this.sqliteStore.getRecentEvents(10000);\n const vectorCount = await this.vectorStore.count();\n const levelStats = await this.graduation.getStats();\n\n return {\n totalEvents: recentEvents.length,\n vectorCount,\n levelStats\n };\n }\n\n /**\n * Process pending embeddings\n */\n async processPendingEmbeddings(): Promise<number> {\n if (this.vectorWorker) {\n return this.vectorWorker.processAll();\n }\n return 0;\n }\n\n /**\n * Get events by memory level\n */\n async getEventsByLevel(level: string, options?: { limit?: number; offset?: number }): Promise<MemoryEvent[]> {\n await this.initialize();\n return this.sqliteStore.getEventsByLevel(level, options);\n }\n\n /**\n * Get memory level for a specific event\n */\n async getEventLevel(eventId: string): Promise<string | null> {\n await this.initialize();\n return this.sqliteStore.getEventLevel(eventId);\n }\n\n /**\n * Format retrieval results as context for Claude\n */\n formatAsContext(result: RetrievalResult): string {\n if (!result.context) {\n return '';\n }\n\n const confidence = result.matchResult.confidence;\n let header = '';\n\n if (confidence === 'high') {\n header = '\uD83C\uDFAF **High-confidence memory match found:**\\n\\n';\n } else if (confidence === 'suggested') {\n header = '\uD83D\uDCA1 **Suggested memories (may be relevant):**\\n\\n';\n }\n\n return header + result.context;\n }\n\n // ============================================================\n // Shared Store Methods (Cross-Project Knowledge)\n // ============================================================\n\n /**\n * Check if shared store is enabled and initialized\n */\n isSharedStoreEnabled(): boolean {\n return this.sharedStore !== null;\n }\n\n /**\n * Promote an entry to shared storage\n */\n async promoteToShared(entry: Entry): Promise<PromotionResult> {\n if (!this.sharedPromoter || !this.projectHash) {\n return {\n success: false,\n error: 'Shared store not initialized or project hash not set'\n };\n }\n\n return this.sharedPromoter.promoteEntry(entry, this.projectHash);\n }\n\n /**\n * Get shared store statistics\n */\n async getSharedStoreStats(): Promise<{\n total: number;\n averageConfidence: number;\n topTopics: Array<{ topic: string; count: number }>;\n totalUsageCount: number;\n } | null> {\n if (!this.sharedStore) return null;\n return this.sharedStore.getStats();\n }\n\n /**\n * Search shared troubleshooting entries\n */\n async searchShared(\n query: string,\n options?: { topK?: number; minConfidence?: number }\n ) {\n if (!this.sharedStore) return [];\n return this.sharedStore.search(query, options);\n }\n\n /**\n * Get project hash for this service\n */\n getProjectHash(): string | null {\n return this.projectHash;\n }\n\n // ============================================================\n // Endless Mode Methods\n // ============================================================\n\n /**\n * Get the default endless mode config\n */\n private getDefaultEndlessConfig(): EndlessModeConfig {\n return {\n enabled: true,\n workingSet: {\n maxEvents: 100,\n timeWindowHours: 24,\n minRelevanceScore: 0.5\n },\n consolidation: {\n triggerIntervalMs: 3600000, // 1 hour\n triggerEventCount: 100,\n triggerIdleMs: 1800000, // 30 minutes\n useLLMSummarization: false\n },\n continuity: {\n minScoreForSeamless: 0.7,\n topicDecayHours: 48\n }\n };\n }\n\n /**\n * Initialize Endless Mode components\n */\n async initializeEndlessMode(): Promise<void> {\n const config = await this.getEndlessConfig();\n\n this.workingSetStore = createWorkingSetStore(this.sqliteStore, config);\n this.consolidatedStore = createConsolidatedStore(this.sqliteStore);\n this.consolidationWorker = createConsolidationWorker(\n this.workingSetStore,\n this.consolidatedStore,\n config\n );\n this.continuityManager = createContinuityManager(this.sqliteStore, config);\n\n // Start consolidation worker\n this.consolidationWorker.start();\n }\n\n /**\n * Get Endless Mode configuration\n */\n async getEndlessConfig(): Promise<EndlessModeConfig> {\n const savedConfig = await this.sqliteStore.getEndlessConfig('config') as EndlessModeConfig | null;\n return savedConfig || this.getDefaultEndlessConfig();\n }\n\n /**\n * Set Endless Mode configuration\n */\n async setEndlessConfig(config: Partial<EndlessModeConfig>): Promise<void> {\n const current = await this.getEndlessConfig();\n const merged = { ...current, ...config };\n await this.sqliteStore.setEndlessConfig('config', merged);\n }\n\n /**\n * Set memory mode (session or endless)\n */\n async setMode(mode: MemoryMode): Promise<void> {\n await this.initialize();\n\n if (mode === this.endlessMode) return;\n\n this.endlessMode = mode;\n await this.sqliteStore.setEndlessConfig('mode', mode);\n\n if (mode === 'endless') {\n await this.initializeEndlessMode();\n } else {\n // Stop endless mode components\n if (this.consolidationWorker) {\n this.consolidationWorker.stop();\n this.consolidationWorker = null;\n }\n this.workingSetStore = null;\n this.consolidatedStore = null;\n this.continuityManager = null;\n }\n }\n\n /**\n * Get current memory mode\n */\n getMode(): MemoryMode {\n return this.endlessMode;\n }\n\n /**\n * Check if endless mode is active\n */\n isEndlessModeActive(): boolean {\n return this.endlessMode === 'endless';\n }\n\n /**\n * Add event to Working Set (Endless Mode)\n */\n async addToWorkingSet(eventId: string, relevanceScore?: number): Promise<void> {\n if (!this.workingSetStore) return;\n await this.workingSetStore.add(eventId, relevanceScore);\n }\n\n /**\n * Get the current Working Set\n */\n async getWorkingSet(): Promise<WorkingSet | null> {\n if (!this.workingSetStore) return null;\n return this.workingSetStore.get();\n }\n\n /**\n * Search consolidated memories\n */\n async searchConsolidated(\n query: string,\n options?: { topK?: number }\n ): Promise<ConsolidatedMemory[]> {\n if (!this.consolidatedStore) return [];\n return this.consolidatedStore.search(query, options);\n }\n\n /**\n * Get all consolidated memories\n */\n async getConsolidatedMemories(limit?: number): Promise<ConsolidatedMemory[]> {\n if (!this.consolidatedStore) return [];\n return this.consolidatedStore.getAll({ limit });\n }\n\n /**\n * Extract topic keywords from event content (markdown headings and key terms)\n */\n private extractTopicsFromContent(content: string): string[] {\n const topics: Set<string> = new Set();\n\n // Extract markdown headings (## heading)\n const headings = content.match(/^#{1,3}\\s+(.+)$/gm);\n if (headings) {\n for (const h of headings.slice(0, 5)) {\n const text = h.replace(/^#+\\s+/, '').replace(/[*_`#]/g, '').trim();\n if (text.length > 2 && text.length < 50) {\n topics.add(text);\n }\n }\n }\n\n // Extract bold terms (**term**)\n const boldTerms = content.match(/\\*\\*([^*]+)\\*\\*/g);\n if (boldTerms) {\n for (const b of boldTerms.slice(0, 5)) {\n const text = b.replace(/\\*\\*/g, '').trim();\n if (text.length > 2 && text.length < 30) {\n topics.add(text);\n }\n }\n }\n\n return Array.from(topics).slice(0, 5);\n }\n\n /**\n * Increment access count for memories that were used in prompts\n */\n async incrementMemoryAccess(eventIds: string[]): Promise<void> {\n if (eventIds.length === 0) return;\n\n // Use SQLite event store if available\n if (this.sqliteStore) {\n await this.sqliteStore.incrementAccessCount(eventIds);\n } else if (this.eventStore) {\n // Fallback to regular event store (which has a stub implementation)\n await this.eventStore.incrementAccessCount(eventIds);\n }\n }\n\n /**\n * Get most accessed memories from events\n */\n async getMostAccessedMemories(limit: number = 10): Promise<any[]> {\n console.log('[getMostAccessedMemories] sqliteStore available:', !!this.sqliteStore);\n\n // Try to get from SQLite event store if available\n if (this.sqliteStore) {\n const events = await this.sqliteStore.getMostAccessed(limit);\n console.log('[getMostAccessedMemories] Got events from SQLite:', events.length);\n return events.map(event => ({\n memoryId: event.id,\n summary: event.content.substring(0, 200) + (event.content.length > 200 ? '...' : ''),\n topics: this.extractTopicsFromContent(event.content),\n accessCount: (event as any).access_count || 0,\n lastAccessed: (event as any).last_accessed_at || null,\n confidence: 1.0,\n createdAt: event.timestamp\n }));\n }\n\n // Fallback to consolidated store if available\n if (this.consolidatedStore) {\n const consolidated = await this.consolidatedStore.getMostAccessed(limit);\n return consolidated.map(m => ({\n memoryId: m.memoryId,\n summary: m.summary,\n topics: m.topics,\n accessCount: m.accessCount,\n lastAccessed: m.accessedAt,\n confidence: m.confidence,\n createdAt: m.createdAt\n }));\n }\n\n return [];\n }\n\n /**\n * Record a memory retrieval for helpfulness tracking\n */\n async recordRetrieval(eventId: string, sessionId: string, score: number, query: string): Promise<void> {\n await this.initialize();\n await this.sqliteStore.recordRetrieval(eventId, sessionId, score, query);\n }\n\n /**\n * Record a query-level retrieval trace (used by user-prompt-submit hook).\n * Feeds the retrieval_traces table that powers dashboard stats.\n */\n async recordQueryTrace(input: {\n sessionId: string;\n queryText: string;\n strategy: string;\n candidateEventIds: string[];\n selectedEventIds: string[];\n confidence: string;\n }): Promise<void> {\n await this.initialize();\n await this.sqliteStore.recordRetrievalTrace({\n ...input,\n candidateDetails: [],\n selectedDetails: [],\n fallbackTrace: [],\n });\n }\n\n /**\n * Evaluate helpfulness of retrievals in a session (called at session end)\n */\n async evaluateSessionHelpfulness(sessionId: string): Promise<void> {\n await this.initialize();\n await this.sqliteStore.evaluateSessionHelpfulness(sessionId);\n }\n\n /**\n * Backfill helpfulness evaluation for sessions that ended without Stop hook.\n * Call on first turn of a new session to catch missed evaluations.\n */\n async evaluatePendingSessions(currentSessionId: string): Promise<void> {\n await this.initialize();\n const sessions = await this.sqliteStore.getUnevaluatedSessions(currentSessionId, 5);\n for (const sid of sessions) {\n try {\n await this.sqliteStore.evaluateSessionHelpfulness(sid);\n } catch {\n // non-critical, skip failed\n }\n }\n }\n\n /**\n * Get most helpful memories ranked by helpfulness score\n */\n async getHelpfulMemories(limit: number = 10): Promise<Array<{\n eventId: string;\n summary: string;\n helpfulnessScore: number;\n accessCount: number;\n evaluationCount: number;\n }>> {\n await this.initialize();\n return this.sqliteStore.getHelpfulMemories(limit);\n }\n\n /**\n * Get helpfulness statistics for dashboard\n */\n async getHelpfulnessStats(): Promise<{\n avgScore: number;\n totalEvaluated: number;\n totalRetrievals: number;\n helpful: number;\n neutral: number;\n unhelpful: number;\n }> {\n await this.initialize();\n return this.sqliteStore.getHelpfulnessStats();\n }\n\n /**\n * Mark a consolidated memory as accessed\n */\n async markMemoryAccessed(memoryId: string): Promise<void> {\n if (!this.consolidatedStore) return;\n await this.consolidatedStore.markAccessed(memoryId);\n }\n\n /**\n * Calculate continuity score for current context\n */\n async calculateContinuity(\n content: string,\n metadata?: { files?: string[]; entities?: string[] }\n ): Promise<ContinuityScore | null> {\n if (!this.continuityManager) return null;\n\n const snapshot = this.continuityManager.createSnapshot(\n crypto.randomUUID(),\n content,\n metadata\n );\n\n return this.continuityManager.calculateScore(snapshot);\n }\n\n /**\n * Record activity (for consolidation idle trigger)\n */\n recordActivity(): void {\n if (this.consolidationWorker) {\n this.consolidationWorker.recordActivity();\n }\n }\n\n /**\n * Force a consolidation run\n */\n async forceConsolidation(): Promise<number> {\n if (!this.consolidationWorker) return 0;\n return this.consolidationWorker.forceRun();\n }\n\n /**\n * Get Endless Mode status\n */\n async getEndlessModeStatus(): Promise<EndlessModeStatus> {\n await this.initialize();\n\n let workingSetSize = 0;\n let continuityScore = 0.5;\n let consolidatedCount = 0;\n let lastConsolidation: Date | null = null;\n\n if (this.workingSetStore) {\n workingSetSize = await this.workingSetStore.count();\n const workingSet = await this.workingSetStore.get();\n continuityScore = workingSet.continuityScore;\n }\n\n if (this.consolidatedStore) {\n consolidatedCount = await this.consolidatedStore.count();\n lastConsolidation = await this.consolidatedStore.getLastConsolidationTime();\n }\n\n return {\n mode: this.endlessMode,\n workingSetSize,\n continuityScore,\n consolidatedCount,\n lastConsolidation\n };\n }\n\n // ============================================================\n // Turn Grouping Methods\n // ============================================================\n\n /**\n * Get events grouped by turn for a session\n */\n async getSessionTurns(sessionId: string, options?: { limit?: number; offset?: number }): Promise<Array<{\n turnId: string;\n events: MemoryEvent[];\n startedAt: Date;\n promptPreview: string;\n eventCount: number;\n toolCount: number;\n hasResponse: boolean;\n }>> {\n await this.initialize();\n return this.sqliteStore.getSessionTurns(sessionId, options);\n }\n\n /**\n * Get all events for a specific turn\n */\n async getEventsByTurn(turnId: string): Promise<MemoryEvent[]> {\n await this.initialize();\n return this.sqliteStore.getEventsByTurn(turnId);\n }\n\n /**\n * Count total turns for a session\n */\n async countSessionTurns(sessionId: string): Promise<number> {\n await this.initialize();\n return this.sqliteStore.countSessionTurns(sessionId);\n }\n\n /**\n * Backfill turn_ids from metadata for events stored before the migration\n */\n async backfillTurnIds(): Promise<number> {\n await this.initialize();\n return this.sqliteStore.backfillTurnIds();\n }\n\n /**\n * Delete all events for a session (for force reimport)\n */\n async deleteSessionEvents(sessionId: string): Promise<number> {\n await this.initialize();\n return this.sqliteStore.deleteSessionEvents(sessionId);\n }\n\n /**\n * Format Endless Mode context for Claude\n */\n async formatEndlessContext(query: string): Promise<string> {\n if (!this.isEndlessModeActive()) {\n return '';\n }\n\n const workingSet = await this.getWorkingSet();\n const consolidated = await this.searchConsolidated(query, { topK: 3 });\n const continuity = await this.calculateContinuity(query);\n\n const parts: string[] = [];\n\n // Continuity status\n if (continuity) {\n const statusEmoji = continuity.transitionType === 'seamless' ? '\uD83D\uDD17' :\n continuity.transitionType === 'topic_shift' ? '\u21AA\uFE0F' : '\uD83C\uDD95';\n parts.push(`${statusEmoji} Context: ${continuity.transitionType} (score: ${continuity.score.toFixed(2)})`);\n }\n\n // Working set summary\n if (workingSet && workingSet.recentEvents.length > 0) {\n parts.push('\\n## Recent Context (Working Set)');\n const recent = workingSet.recentEvents.slice(0, 5);\n for (const event of recent) {\n const preview = event.content.slice(0, 80) + (event.content.length > 80 ? '...' : '');\n const time = event.timestamp.toLocaleTimeString();\n parts.push(`- ${time} [${event.eventType}] ${preview}`);\n }\n }\n\n // Consolidated memories\n if (consolidated.length > 0) {\n parts.push('\\n## Related Knowledge (Consolidated)');\n for (const memory of consolidated) {\n parts.push(`- ${memory.topics.slice(0, 3).join(', ')}: ${memory.summary.slice(0, 100)}...`);\n }\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Force a graduation evaluation run\n */\n async forceGraduation(): Promise<GraduationRunResult> {\n if (!this.graduationWorker) {\n return { evaluated: 0, graduated: 0, byLevel: {} };\n }\n return this.graduationWorker.forceRun();\n }\n\n /**\n * Record access to a memory event (for graduation scoring)\n */\n recordMemoryAccess(eventId: string, sessionId: string, confidence: number = 1.0): void {\n this.graduation.recordAccess(eventId, sessionId, confidence);\n }\n\n getEmbeddingModelName(): string {\n return this.embedder.getModelName();\n }\n\n /**\n * Ensure embedding model metadata is in sync and optionally migrate vectors.\n * Migration strategy: clear vector index + clear embedding outbox + re-enqueue all events.\n */\n async ensureEmbeddingModelForImport(options?: { autoMigrate?: boolean }): Promise<{\n changed: boolean;\n previousModel: string | null;\n currentModel: string;\n enqueued: number;\n reason?: string;\n }> {\n await this.initialize();\n\n const currentModel = this.getEmbeddingModelName();\n const metaPath = path.join(this.storagePath, 'embedding-meta.json');\n\n let previousModel: string | null = null;\n try {\n if (fs.existsSync(metaPath)) {\n const parsed = JSON.parse(fs.readFileSync(metaPath, 'utf-8')) as { model?: string };\n previousModel = parsed?.model || null;\n }\n } catch {\n previousModel = null;\n }\n\n const stats = await this.getStats();\n const hasExistingVectors = (stats.vectorCount || 0) > 0;\n\n // First-time metadata write (no migration needed unless legacy vectors exist)\n if (!previousModel && !hasExistingVectors) {\n fs.writeFileSync(metaPath, JSON.stringify({ model: currentModel, updatedAt: new Date().toISOString() }, null, 2));\n return { changed: false, previousModel: null, currentModel, enqueued: 0, reason: 'initialized-meta' };\n }\n\n const modelChanged = previousModel !== currentModel;\n const legacyUnknownButVectorsExist = !previousModel && hasExistingVectors;\n\n if (!modelChanged && !legacyUnknownButVectorsExist) {\n return { changed: false, previousModel, currentModel, enqueued: 0 };\n }\n\n if (options?.autoMigrate === false) {\n return {\n changed: true,\n previousModel,\n currentModel,\n enqueued: 0,\n reason: legacyUnknownButVectorsExist ? 'legacy-vectors-without-meta' : 'model-mismatch'\n };\n }\n\n // Pause background vector processing while preparing migration\n const wasRunning = this.vectorWorker?.isRunning() || false;\n if (wasRunning) this.vectorWorker?.stop();\n\n // Reset vector and outbox state\n await this.vectorStore.clearAll();\n await this.sqliteStore.clearEmbeddingOutbox();\n\n // Re-enqueue all events for new embeddings\n const pageSize = 1000;\n let offset = 0;\n let enqueued = 0;\n\n while (true) {\n const page = await this.sqliteStore.getEventsPage(pageSize, offset);\n if (page.length === 0) break;\n\n for (const event of page) {\n await this.sqliteStore.enqueueForEmbedding(event.id, event.content);\n enqueued += 1;\n }\n\n offset += page.length;\n if (page.length < pageSize) break;\n }\n\n fs.writeFileSync(\n metaPath,\n JSON.stringify(\n {\n model: currentModel,\n previousModel,\n migratedAt: new Date().toISOString(),\n enqueued\n },\n null,\n 2\n )\n );\n\n if (wasRunning) this.vectorWorker?.start();\n\n return {\n changed: true,\n previousModel,\n currentModel,\n enqueued,\n reason: legacyUnknownButVectorsExist ? 'legacy-vectors-without-meta' : 'model-mismatch'\n };\n }\n\n /**\n * Backward-compatible alias used by some hooks\n */\n async close(): Promise<void> {\n await this.shutdown();\n }\n\n /**\n * Shutdown service\n */\n async shutdown(): Promise<void> {\n // Stop graduation worker\n if (this.graduationWorker) {\n this.graduationWorker.stop();\n }\n\n // Stop endless mode components\n if (this.consolidationWorker) {\n this.consolidationWorker.stop();\n }\n\n if (this.vectorWorker) {\n this.vectorWorker.stop();\n }\n\n // Stop sync worker\n if (this.syncWorker) {\n this.syncWorker.stop();\n }\n\n // Close shared store\n if (this.sharedEventStore) {\n await this.sharedEventStore.close();\n }\n\n // Close primary store (SQLite)\n await this.sqliteStore.close();\n\n // Close analytics store (DuckDB)\n if (this.analyticsStore) {\n await this.analyticsStore.close();\n }\n }\n\n /**\n * Expand ~ to home directory\n */\n private expandPath(p: string): string {\n if (p.startsWith('~')) {\n return path.join(os.homedir(), p.slice(1));\n }\n return p;\n }\n}\n\n// ============================================================\n// Service Instance Management\n// ============================================================\n\n// Instance cache: Map from project hash (or '__global__') to MemoryService\nconst serviceCache = new Map<string, MemoryService>();\nconst GLOBAL_KEY = '__global__';\nconst GLOBAL_READONLY_KEY = '__global_readonly__';\n\n/**\n * Get the global memory service (backward compatibility)\n * Use this for operations not tied to a specific project\n * Note: analyticsEnabled=false and sharedStore disabled to avoid DuckDB lock conflicts\n */\nexport function getDefaultMemoryService(): MemoryService {\n if (!serviceCache.has(GLOBAL_KEY)) {\n serviceCache.set(GLOBAL_KEY, new MemoryService({\n storagePath: '~/.claude-code/memory',\n analyticsEnabled: false, // Hooks don't need DuckDB\n sharedStoreConfig: { enabled: false } // Shared store uses DuckDB too\n }));\n }\n return serviceCache.get(GLOBAL_KEY)!;\n}\n\n/**\n * Get a read-only global memory service\n * Use this for web server/dashboard that only needs to read data\n * Creates a fresh connection each time to avoid blocking the main writer process\n * Uses SQLite (WAL mode) which supports concurrent readers\n */\nexport function getReadOnlyMemoryService(): MemoryService {\n // Don't cache - create fresh instance each time to avoid holding locks\n // The connection will be closed when the request completes\n // Uses SQLite which supports concurrent readers via WAL mode\n return new MemoryService({\n storagePath: '~/.claude-code/memory',\n readOnly: true,\n analyticsEnabled: false, // Use SQLite for reads (WAL supports concurrent readers)\n sharedStoreConfig: { enabled: false } // Skip shared store for now\n });\n}\n\n/**\n * Get memory service for a specific project path\n * Creates isolated storage at ~/.claude-code/memory/projects/{hash}/\n * Note: analyticsEnabled=false and sharedStore disabled to avoid DuckDB lock conflicts\n */\nexport function getMemoryServiceForProject(\n projectPath: string,\n sharedStoreConfig?: SharedStoreConfig\n): MemoryService {\n const hash = hashProjectPath(projectPath);\n\n if (!serviceCache.has(hash)) {\n const storagePath = getProjectStoragePath(projectPath);\n serviceCache.set(hash, new MemoryService({\n storagePath,\n projectHash: hash,\n projectPath,\n // Override shared store config - hooks don't need DuckDB\n sharedStoreConfig: sharedStoreConfig ?? { enabled: false },\n analyticsEnabled: false // Hooks don't need DuckDB\n }));\n }\n\n return serviceCache.get(hash)!;\n}\n\n/**\n * Get memory service for a session by looking up its project\n * Falls back to global storage if session not found in registry\n */\nexport function getMemoryServiceForSession(sessionId: string): MemoryService {\n const projectInfo = getSessionProject(sessionId);\n\n if (projectInfo) {\n return getMemoryServiceForProject(projectInfo.projectPath);\n }\n\n // Fallback to global storage for unknown sessions (backward compat)\n return getDefaultMemoryService();\n}\n\n/**\n * Get a lightweight memory service for hooks\n * Only initializes SQLite - no embedder, no vector store, no workers\n * This is FAST (<100ms) compared to full initialization (3-5s)\n */\nexport function getLightweightMemoryService(sessionId: string): MemoryService {\n const projectInfo = getSessionProject(sessionId);\n const key = projectInfo ? `lightweight_${projectInfo.projectHash}` : 'lightweight_global';\n\n if (!serviceCache.has(key)) {\n const storagePath = projectInfo\n ? getProjectStoragePath(projectInfo.projectPath)\n : path.join(os.homedir(), '.claude-code', 'memory');\n\n serviceCache.set(key, new MemoryService({\n storagePath,\n projectHash: projectInfo?.projectHash,\n projectPath: projectInfo?.projectPath,\n lightweightMode: true, // Skip embedder/vector/workers\n analyticsEnabled: false,\n sharedStoreConfig: { enabled: false }\n }));\n }\n\n return serviceCache.get(key)!;\n}\n\nexport function createMemoryService(config: MemoryServiceConfig): MemoryService {\n return new MemoryService(config);\n}\n", "/**\n * AXIOMMIND EventStore implementation\n * Principles: Append-only, Single Source of Truth, Idempotency\n */\n\nimport { randomUUID } from 'crypto';\nimport {\n MemoryEvent,\n MemoryEventInput,\n Session,\n AppendResult,\n OutboxItem\n} from './types.js';\nimport { makeCanonicalKey, makeDedupeKey } from './canonical-key.js';\nimport { createDatabase, dbRun, dbAll, dbClose, toDate, type Database, type DatabaseOptions } from './db-wrapper.js';\n\nexport interface EventStoreOptions extends DatabaseOptions {\n // Additional options can be added here\n}\n\nexport class EventStore {\n private db: Database;\n private initialized = false;\n private readonly readOnly: boolean;\n\n constructor(private dbPath: string, options?: EventStoreOptions) {\n this.readOnly = options?.readOnly ?? false;\n this.db = createDatabase(dbPath, { readOnly: this.readOnly });\n }\n\n /**\n * Initialize database schema\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // In read-only mode, skip schema creation (tables already exist)\n if (this.readOnly) {\n this.initialized = true;\n return;\n }\n\n // L0 EventStore: Single Source of Truth (immutable, append-only)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS events (\n id VARCHAR PRIMARY KEY,\n event_type VARCHAR NOT NULL,\n session_id VARCHAR NOT NULL,\n timestamp TIMESTAMP NOT NULL,\n content TEXT NOT NULL,\n canonical_key VARCHAR NOT NULL,\n dedupe_key VARCHAR UNIQUE,\n metadata JSON\n )\n `);\n\n // Dedup table for idempotency\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS event_dedup (\n dedupe_key VARCHAR PRIMARY KEY,\n event_id VARCHAR NOT NULL,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Session metadata\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS sessions (\n id VARCHAR PRIMARY KEY,\n started_at TIMESTAMP NOT NULL,\n ended_at TIMESTAMP,\n project_path VARCHAR,\n summary TEXT,\n tags JSON\n )\n `);\n\n // Insights (derived data, rebuildable)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS insights (\n id VARCHAR PRIMARY KEY,\n insight_type VARCHAR NOT NULL,\n content TEXT NOT NULL,\n canonical_key VARCHAR NOT NULL,\n confidence FLOAT,\n source_events JSON,\n created_at TIMESTAMP,\n last_updated TIMESTAMP\n )\n `);\n\n // Embedding Outbox (Single-Writer Pattern)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS embedding_outbox (\n id VARCHAR PRIMARY KEY,\n event_id VARCHAR NOT NULL,\n content TEXT NOT NULL,\n status VARCHAR DEFAULT 'pending',\n retry_count INT DEFAULT 0,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n processed_at TIMESTAMP,\n error_message TEXT\n )\n `);\n\n // Projection offset tracking\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS projection_offsets (\n projection_name VARCHAR PRIMARY KEY,\n last_event_id VARCHAR,\n last_timestamp TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Memory level tracking\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS memory_levels (\n event_id VARCHAR PRIMARY KEY,\n level VARCHAR NOT NULL DEFAULT 'L0',\n promoted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // ============================================================\n // Entity-Edge Model Tables\n // ============================================================\n\n // Entries (immutable memory units)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS entries (\n entry_id VARCHAR PRIMARY KEY,\n created_ts TIMESTAMP NOT NULL,\n entry_type VARCHAR NOT NULL,\n title VARCHAR NOT NULL,\n content_json JSON NOT NULL,\n stage VARCHAR NOT NULL DEFAULT 'raw',\n status VARCHAR DEFAULT 'active',\n superseded_by VARCHAR,\n build_id VARCHAR,\n evidence_json JSON,\n canonical_key VARCHAR,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Entities (task/condition/artifact)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS entities (\n entity_id VARCHAR PRIMARY KEY,\n entity_type VARCHAR NOT NULL,\n canonical_key VARCHAR NOT NULL,\n title VARCHAR NOT NULL,\n stage VARCHAR NOT NULL DEFAULT 'raw',\n status VARCHAR NOT NULL DEFAULT 'active',\n current_json JSON NOT NULL,\n title_norm VARCHAR,\n search_text VARCHAR,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Entity aliases for canonical key lookup\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS entity_aliases (\n entity_type VARCHAR NOT NULL,\n canonical_key VARCHAR NOT NULL,\n entity_id VARCHAR NOT NULL,\n is_primary BOOLEAN DEFAULT FALSE,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY(entity_type, canonical_key)\n )\n `);\n\n // Edges (relationships between entries/entities)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS edges (\n edge_id VARCHAR PRIMARY KEY,\n src_type VARCHAR NOT NULL,\n src_id VARCHAR NOT NULL,\n rel_type VARCHAR NOT NULL,\n dst_type VARCHAR NOT NULL,\n dst_id VARCHAR NOT NULL,\n meta_json JSON,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // ============================================================\n // Vector Outbox V2 Table\n // ============================================================\n\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS vector_outbox (\n job_id VARCHAR PRIMARY KEY,\n item_kind VARCHAR NOT NULL,\n item_id VARCHAR NOT NULL,\n embedding_version VARCHAR NOT NULL,\n status VARCHAR NOT NULL DEFAULT 'pending',\n retry_count INT DEFAULT 0,\n error VARCHAR,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n UNIQUE(item_kind, item_id, embedding_version)\n )\n `);\n\n // ============================================================\n // Build Runs & Metrics Tables\n // ============================================================\n\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS build_runs (\n build_id VARCHAR PRIMARY KEY,\n started_at TIMESTAMP NOT NULL,\n finished_at TIMESTAMP,\n extractor_model VARCHAR NOT NULL,\n extractor_prompt_hash VARCHAR NOT NULL,\n embedder_model VARCHAR NOT NULL,\n embedding_version VARCHAR NOT NULL,\n idris_version VARCHAR NOT NULL,\n schema_version VARCHAR NOT NULL,\n status VARCHAR NOT NULL DEFAULT 'running',\n error VARCHAR\n )\n `);\n\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS pipeline_metrics (\n id VARCHAR PRIMARY KEY,\n ts TIMESTAMP NOT NULL,\n stage VARCHAR NOT NULL,\n latency_ms DOUBLE NOT NULL,\n success BOOLEAN NOT NULL,\n error VARCHAR,\n session_id VARCHAR\n )\n `);\n\n // ============================================================\n // Endless Mode Tables\n // ============================================================\n\n // Working Set table (active memory window)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS working_set (\n id VARCHAR PRIMARY KEY,\n event_id VARCHAR NOT NULL,\n added_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n relevance_score FLOAT DEFAULT 1.0,\n topics JSON,\n expires_at TIMESTAMP\n )\n `);\n\n // Consolidated Memories table (long-term integrated memories)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS consolidated_memories (\n memory_id VARCHAR PRIMARY KEY,\n summary TEXT NOT NULL,\n topics JSON,\n source_events JSON,\n confidence FLOAT DEFAULT 0.5,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n accessed_at TIMESTAMP,\n access_count INTEGER DEFAULT 0\n )\n `);\n\n // Continuity Log table (tracks context transitions)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS continuity_log (\n log_id VARCHAR PRIMARY KEY,\n from_context_id VARCHAR,\n to_context_id VARCHAR,\n continuity_score FLOAT,\n transition_type VARCHAR,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Consolidated Rules table (long-term stable memory)\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS consolidated_rules (\n rule_id VARCHAR PRIMARY KEY,\n rule TEXT NOT NULL,\n topics JSON,\n source_memory_ids JSON,\n source_events JSON,\n confidence FLOAT DEFAULT 0.5,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // Endless Mode Config table\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS endless_config (\n key VARCHAR PRIMARY KEY,\n value JSON,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // ============================================================\n // Create Indexes\n // ============================================================\n\n // Entry indexes\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entries_type ON entries(entry_type)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entries_stage ON entries(stage)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entries_canonical ON entries(canonical_key)`);\n\n // Entity indexes\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entities_type_key ON entities(entity_type, canonical_key)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_entities_status ON entities(status)`);\n\n // Edge indexes\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_edges_src ON edges(src_id, rel_type)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_edges_dst ON edges(dst_id, rel_type)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_edges_rel ON edges(rel_type)`);\n\n // Outbox indexes\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_outbox_status ON vector_outbox(status)`);\n\n // Endless Mode indexes\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_working_set_expires ON working_set(expires_at)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_working_set_relevance ON working_set(relevance_score DESC)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_consolidated_confidence ON consolidated_memories(confidence DESC)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_consolidated_rules_confidence ON consolidated_rules(confidence DESC)`);\n await dbRun(this.db, `CREATE INDEX IF NOT EXISTS idx_continuity_created ON continuity_log(created_at)`);\n\n this.initialized = true;\n }\n\n /**\n * Append event to store (AXIOMMIND Principle 2: Append-only)\n * Returns existing event ID if duplicate (Principle 3: Idempotency)\n */\n async append(input: MemoryEventInput): Promise<AppendResult> {\n await this.initialize();\n\n const canonicalKey = makeCanonicalKey(input.content);\n const dedupeKey = makeDedupeKey(input.content, input.sessionId);\n\n // Check for duplicate\n const existing = await dbAll<{ event_id: string }>(\n this.db,\n `SELECT event_id FROM event_dedup WHERE dedupe_key = ?`,\n [dedupeKey]\n );\n\n if (existing.length > 0) {\n return {\n success: true,\n eventId: existing[0].event_id,\n isDuplicate: true\n };\n }\n\n const id = randomUUID();\n const timestamp = input.timestamp.toISOString();\n\n try {\n await dbRun(\n this.db,\n `INSERT INTO events (id, event_type, session_id, timestamp, content, canonical_key, dedupe_key, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n id,\n input.eventType,\n input.sessionId,\n timestamp,\n input.content,\n canonicalKey,\n dedupeKey,\n JSON.stringify(input.metadata || {})\n ]\n );\n\n await dbRun(\n this.db,\n `INSERT INTO event_dedup (dedupe_key, event_id) VALUES (?, ?)`,\n [dedupeKey, id]\n );\n\n // Initialize at L0\n await dbRun(\n this.db,\n `INSERT INTO memory_levels (event_id, level) VALUES (?, 'L0')`,\n [id]\n );\n\n return { success: true, eventId: id, isDuplicate: false };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n\n /**\n * Get events by session ID\n */\n async getSessionEvents(sessionId: string): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,\n [sessionId]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Get recent events\n */\n async getRecentEvents(limit: number = 100): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events ORDER BY timestamp DESC LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Get event by ID\n */\n async getEvent(id: string): Promise<MemoryEvent | null> {\n await this.initialize();\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE id = ?`,\n [id]\n );\n\n if (rows.length === 0) return null;\n return this.rowToEvent(rows[0]);\n }\n\n /**\n * Create or update session\n */\n async upsertSession(session: Partial<Session> & { id: string }): Promise<void> {\n await this.initialize();\n\n const existing = await dbAll<{ id: string }>(\n this.db,\n `SELECT id FROM sessions WHERE id = ?`,\n [session.id]\n );\n\n if (existing.length === 0) {\n await dbRun(\n this.db,\n `INSERT INTO sessions (id, started_at, project_path, tags)\n VALUES (?, ?, ?, ?)`,\n [\n session.id,\n (session.startedAt || new Date()).toISOString(),\n session.projectPath || null,\n JSON.stringify(session.tags || [])\n ]\n );\n } else {\n const updates: string[] = [];\n const values: unknown[] = [];\n\n if (session.endedAt) {\n updates.push('ended_at = ?');\n values.push(session.endedAt.toISOString());\n }\n if (session.summary) {\n updates.push('summary = ?');\n values.push(session.summary);\n }\n if (session.tags) {\n updates.push('tags = ?');\n values.push(JSON.stringify(session.tags));\n }\n\n if (updates.length > 0) {\n values.push(session.id);\n await dbRun(\n this.db,\n `UPDATE sessions SET ${updates.join(', ')} WHERE id = ?`,\n values\n );\n }\n }\n }\n\n /**\n * Get session by ID\n */\n async getSession(id: string): Promise<Session | null> {\n await this.initialize();\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM sessions WHERE id = ?`,\n [id]\n );\n\n if (rows.length === 0) return null;\n\n const row = rows[0];\n return {\n id: row.id as string,\n startedAt: toDate(row.started_at),\n endedAt: row.ended_at ? toDate(row.ended_at) : undefined,\n projectPath: row.project_path as string | undefined,\n summary: row.summary as string | undefined,\n tags: row.tags ? JSON.parse(row.tags as string) : undefined\n };\n }\n\n /**\n * Add to embedding outbox (Single-Writer Pattern)\n */\n async enqueueForEmbedding(eventId: string, content: string): Promise<string> {\n await this.initialize();\n\n const id = randomUUID();\n await dbRun(\n this.db,\n `INSERT INTO embedding_outbox (id, event_id, content, status, retry_count)\n VALUES (?, ?, ?, 'pending', 0)`,\n [id, eventId, content]\n );\n\n return id;\n }\n\n /**\n * Get pending outbox items\n */\n async getPendingOutboxItems(limit: number = 32): Promise<OutboxItem[]> {\n await this.initialize();\n\n // First, get pending items\n const pending = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM embedding_outbox\n WHERE status = 'pending'\n ORDER BY created_at\n LIMIT ?`,\n [limit]\n );\n\n if (pending.length === 0) return [];\n\n // Update status to processing\n const ids = pending.map(r => r.id as string);\n const placeholders = ids.map(() => '?').join(',');\n await dbRun(\n this.db,\n `UPDATE embedding_outbox SET status = 'processing' WHERE id IN (${placeholders})`,\n ids\n );\n\n return pending.map(row => ({\n id: row.id as string,\n eventId: row.event_id as string,\n content: row.content as string,\n status: 'processing' as const,\n retryCount: row.retry_count as number,\n createdAt: toDate(row.created_at),\n errorMessage: row.error_message as string | undefined\n }));\n }\n\n /**\n * Mark outbox items as done\n */\n async completeOutboxItems(ids: string[]): Promise<void> {\n if (ids.length === 0) return;\n\n const placeholders = ids.map(() => '?').join(',');\n await dbRun(\n this.db,\n `DELETE FROM embedding_outbox WHERE id IN (${placeholders})`,\n ids\n );\n }\n\n /**\n * Mark outbox items as failed\n */\n async failOutboxItems(ids: string[], error: string): Promise<void> {\n if (ids.length === 0) return;\n\n const placeholders = ids.map(() => '?').join(',');\n await dbRun(\n this.db,\n `UPDATE embedding_outbox\n SET status = CASE WHEN retry_count >= 3 THEN 'failed' ELSE 'pending' END,\n retry_count = retry_count + 1,\n error_message = ?\n WHERE id IN (${placeholders})`,\n [error, ...ids]\n );\n }\n\n /**\n * Update memory level\n */\n async updateMemoryLevel(eventId: string, level: string): Promise<void> {\n await this.initialize();\n\n await dbRun(\n this.db,\n `UPDATE memory_levels SET level = ?, promoted_at = CURRENT_TIMESTAMP WHERE event_id = ?`,\n [level, eventId]\n );\n }\n\n /**\n * Get memory level statistics\n */\n async getLevelStats(): Promise<Array<{ level: string; count: number }>> {\n await this.initialize();\n\n const rows = await dbAll<{ level: string; count: number }>(\n this.db,\n `SELECT level, COUNT(*) as count FROM memory_levels GROUP BY level`\n );\n\n return rows;\n }\n\n /**\n * Get events by memory level\n */\n async getEventsByLevel(level: string, options?: { limit?: number; offset?: number }): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const limit = options?.limit || 50;\n const offset = options?.offset || 0;\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT e.* FROM events e\n INNER JOIN memory_levels ml ON e.id = ml.event_id\n WHERE ml.level = ?\n ORDER BY e.timestamp DESC\n LIMIT ? OFFSET ?`,\n [level, limit, offset]\n );\n\n return rows.map(row => this.rowToEvent(row));\n }\n\n /**\n * Get memory level for a specific event\n */\n async getEventLevel(eventId: string): Promise<string | null> {\n await this.initialize();\n\n const rows = await dbAll<{ level: string }>(\n this.db,\n `SELECT level FROM memory_levels WHERE event_id = ?`,\n [eventId]\n );\n\n return rows.length > 0 ? rows[0].level : null;\n }\n\n // ============================================================\n // Endless Mode Helper Methods\n // ============================================================\n\n /**\n * Get database instance for Endless Mode stores\n */\n getDatabase(): Database {\n return this.db;\n }\n\n /**\n * Get config value for endless mode\n */\n async getEndlessConfig(key: string): Promise<unknown | null> {\n await this.initialize();\n\n const rows = await dbAll<{ value: string }>(\n this.db,\n `SELECT value FROM endless_config WHERE key = ?`,\n [key]\n );\n\n if (rows.length === 0) return null;\n return JSON.parse(rows[0].value);\n }\n\n /**\n * Set config value for endless mode\n */\n async setEndlessConfig(key: string, value: unknown): Promise<void> {\n await this.initialize();\n\n await dbRun(\n this.db,\n `INSERT OR REPLACE INTO endless_config (key, value, updated_at)\n VALUES (?, ?, CURRENT_TIMESTAMP)`,\n [key, JSON.stringify(value)]\n );\n }\n\n /**\n * Get all sessions\n */\n async getAllSessions(): Promise<Session[]> {\n await this.initialize();\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM sessions ORDER BY started_at DESC`\n );\n\n return rows.map(row => ({\n id: row.id as string,\n startedAt: toDate(row.started_at),\n endedAt: row.ended_at ? toDate(row.ended_at) : undefined,\n projectPath: row.project_path as string | undefined,\n summary: row.summary as string | undefined,\n tags: row.tags ? JSON.parse(row.tags as string) : undefined\n }));\n }\n\n /**\n * Increment access count for events (stub for compatibility)\n */\n async incrementAccessCount(eventIds: string[]): Promise<void> {\n // This is a stub method for compatibility\n // Actual implementation is in SQLiteEventStore\n return Promise.resolve();\n }\n\n /**\n * Get most accessed memories (stub for compatibility)\n */\n async getMostAccessed(limit: number = 10): Promise<MemoryEvent[]> {\n // This is a stub method for compatibility\n // Actual implementation is in SQLiteEventStore\n return [];\n }\n\n /**\n * Close database connection\n */\n async close(): Promise<void> {\n await dbClose(this.db);\n }\n\n /**\n * Convert database row to MemoryEvent\n */\n private rowToEvent(row: Record<string, unknown>): MemoryEvent {\n return {\n id: row.id as string,\n eventType: row.event_type as 'user_prompt' | 'agent_response' | 'session_summary',\n sessionId: row.session_id as string,\n timestamp: toDate(row.timestamp),\n content: row.content as string,\n canonicalKey: row.canonical_key as string,\n dedupeKey: row.dedupe_key as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined\n };\n }\n}\n", "/**\n * AXIOMMIND canonical_key.py port\n * Deterministic normalization ensuring identical titles always map to same keys\n */\n\nimport { createHash } from 'crypto';\n\nconst MAX_KEY_LENGTH = 200;\n\n/**\n * Convert text to a normalized canonical key\n *\n * Normalization steps:\n * 1. NFKC unicode normalization\n * 2. Lowercase conversion\n * 3. Punctuation removal\n * 4. Consecutive whitespace cleanup\n * 5. Context addition (optional)\n * 6. Long key truncation with MD5\n */\nexport function makeCanonicalKey(\n title: string,\n context?: { project?: string; sessionId?: string }\n): string {\n // Step 1: NFKC normalization\n let normalized = title.normalize('NFKC');\n\n // Step 2: Lowercase conversion\n normalized = normalized.toLowerCase();\n\n // Step 3: Punctuation removal (unicode compatible)\n normalized = normalized.replace(/[^\\p{L}\\p{N}\\s]/gu, '');\n\n // Step 4: Consecutive whitespace cleanup\n normalized = normalized.replace(/\\s+/g, ' ').trim();\n\n // Step 5: Context addition\n let key = normalized;\n if (context?.project) {\n key = `${context.project}::${key}`;\n }\n\n // Step 6: Long key handling\n if (key.length > MAX_KEY_LENGTH) {\n const hashSuffix = createHash('md5').update(key).digest('hex').slice(0, 8);\n key = key.slice(0, MAX_KEY_LENGTH - 9) + '_' + hashSuffix;\n }\n\n return key;\n}\n\n/**\n * Check if two texts have the same canonical key\n */\nexport function isSameCanonicalKey(a: string, b: string): boolean {\n return makeCanonicalKey(a) === makeCanonicalKey(b);\n}\n\n/**\n * Generate dedupe key (content + session for uniqueness)\n * AXIOMMIND Principle 3: Idempotency guarantee\n */\nexport function makeDedupeKey(content: string, sessionId: string): string {\n const contentHash = createHash('sha256').update(content).digest('hex');\n return `${sessionId}:${contentHash}`;\n}\n\n/**\n * Generate content hash for deduplication\n */\nexport function hashContent(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\n// ============================================================\n// Entity Canonical Keys (Task Entity System)\n// ============================================================\n\nexport type EntityKeyType = 'task' | 'condition' | 'artifact';\n\n/**\n * Normalize text for entity key generation\n */\nfunction normalizeForKey(text: string): string {\n return text\n .normalize('NFKC')\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s]/gu, '')\n .replace(/\\s+/g, '_')\n .trim();\n}\n\n/**\n * Generate canonical key for entities\n * Format: {type}:{project}:{normalized_identifier}\n */\nexport function makeEntityCanonicalKey(\n entityType: EntityKeyType,\n identifier: string,\n context?: { project?: string }\n): string {\n const project = context?.project ?? 'default';\n\n switch (entityType) {\n case 'task':\n return `task:${project}:${normalizeForKey(identifier)}`;\n case 'condition':\n return `cond:${project}:${normalizeForKey(identifier)}`;\n case 'artifact':\n return makeArtifactKey(identifier);\n }\n}\n\n/**\n * Generate canonical key for artifacts based on identifier pattern\n * - URL: art:url:{sha1(url)}\n * - JIRA key: art:jira:{key}\n * - GitHub issue: art:gh_issue:{repo}:{num}\n * - Generic: art:generic:{sha1(identifier)}\n */\nexport function makeArtifactKey(identifier: string): string {\n // URL pattern\n if (/^https?:\\/\\//.test(identifier)) {\n const hash = createHash('sha1').update(identifier).digest('hex').slice(0, 12);\n return `art:url:${hash}`;\n }\n\n // JIRA key pattern (e.g., PROJ-123)\n const jiraMatch = identifier.match(/^([A-Z]+-\\d+)$/);\n if (jiraMatch) {\n return `art:jira:${jiraMatch[1].toLowerCase()}`;\n }\n\n // GitHub issue pattern (e.g., owner/repo#123)\n const ghMatch = identifier.match(/^([^\\/]+\\/[^#]+)#(\\d+)$/);\n if (ghMatch) {\n return `art:gh_issue:${ghMatch[1]}:${ghMatch[2]}`;\n }\n\n // Generic identifier\n const hash = createHash('sha1').update(identifier).digest('hex').slice(0, 12);\n return `art:generic:${hash}`;\n}\n\n/**\n * Generate dedupe key for task events\n */\nexport function makeTaskEventDedupeKey(\n eventType: string,\n taskId: string,\n sessionId: string,\n additionalContext?: string\n): string {\n const parts = [eventType, taskId, sessionId];\n if (additionalContext) {\n parts.push(additionalContext);\n }\n const combined = parts.join(':');\n return createHash('sha256').update(combined).digest('hex');\n}\n\n/**\n * Parse entity canonical key to extract type and identifier\n */\nexport function parseEntityCanonicalKey(canonicalKey: string): {\n entityType: EntityKeyType;\n project?: string;\n identifier: string;\n} | null {\n const taskMatch = canonicalKey.match(/^task:([^:]+):(.+)$/);\n if (taskMatch) {\n return { entityType: 'task', project: taskMatch[1], identifier: taskMatch[2] };\n }\n\n const condMatch = canonicalKey.match(/^cond:([^:]+):(.+)$/);\n if (condMatch) {\n return { entityType: 'condition', project: condMatch[1], identifier: condMatch[2] };\n }\n\n const artMatch = canonicalKey.match(/^art:([^:]+):(.+)$/);\n if (artMatch) {\n return { entityType: 'artifact', identifier: artMatch[2] };\n }\n\n return null;\n}\n", "/**\n * DuckDB Promise Wrapper\n * Wraps the callback-based DuckDB API with Promise-based async/await interface\n */\n\nimport duckdb from 'duckdb';\n\nexport type Database = duckdb.Database;\n\n/**\n * Converts BigInt values to Number in an object\n * DuckDB returns BigInt for COUNT(*) and other aggregate functions\n */\nfunction convertBigInts<T>(obj: T): T {\n if (obj === null || obj === undefined) return obj;\n if (typeof obj === 'bigint') return Number(obj) as unknown as T;\n if (obj instanceof Date) return obj; // Preserve Date objects\n if (Array.isArray(obj)) return obj.map(convertBigInts) as unknown as T;\n if (typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n result[key] = convertBigInts(value);\n }\n return result as T;\n }\n return obj;\n}\n\n/**\n * Safely converts a value to a Date object\n * Handles both Date objects and string timestamps from DuckDB\n */\nexport function toDate(value: unknown): Date {\n if (value instanceof Date) return value;\n if (typeof value === 'string') return new Date(value);\n if (typeof value === 'number') return new Date(value);\n return new Date(String(value));\n}\n\nexport interface DatabaseOptions {\n readOnly?: boolean;\n}\n\n/**\n * Creates a new DuckDB database with Promise-based API\n */\nexport function createDatabase(path: string, options?: DatabaseOptions): Database {\n if (options?.readOnly) {\n return new duckdb.Database(path, { access_mode: 'READ_ONLY' });\n }\n return new duckdb.Database(path);\n}\n\n/**\n * Promisified db.run() - executes a statement that doesn't return rows\n */\nexport function dbRun(db: Database, sql: string, params: unknown[] = []): Promise<void> {\n return new Promise((resolve, reject) => {\n if (params.length === 0) {\n db.run(sql, (err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n } else {\n db.run(sql, ...params, (err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n }\n });\n}\n\n/**\n * Promisified db.all() - executes a query and returns all rows\n * Automatically converts BigInt values to Number\n */\nexport function dbAll<T = Record<string, unknown>>(\n db: Database,\n sql: string,\n params: unknown[] = []\n): Promise<T[]> {\n return new Promise((resolve, reject) => {\n if (params.length === 0) {\n db.all(sql, (err: Error | null, rows: T[]) => {\n if (err) reject(err);\n else resolve(convertBigInts(rows || []));\n });\n } else {\n db.all(sql, ...params, (err: Error | null, rows: T[]) => {\n if (err) reject(err);\n else resolve(convertBigInts(rows || []));\n });\n }\n });\n}\n\n/**\n * Promisified db.close() - closes the database connection\n */\nexport function dbClose(db: Database): Promise<void> {\n return new Promise((resolve, reject) => {\n db.close((err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n });\n}\n\n/**\n * Promisified db.exec() - executes multiple statements\n */\nexport function dbExec(db: Database, sql: string): Promise<void> {\n return new Promise((resolve, reject) => {\n db.exec(sql, (err: Error | null) => {\n if (err) reject(err);\n else resolve();\n });\n });\n}\n", "/**\n * SQLite-based EventStore implementation\n * Primary store for hooks - WAL mode enables concurrent access\n */\n\nimport { randomUUID } from 'crypto';\nimport {\n MemoryEvent,\n MemoryEventInput,\n Session,\n AppendResult,\n OutboxItem\n} from './types.js';\nimport { makeCanonicalKey, makeDedupeKey } from './canonical-key.js';\nimport {\n createSQLiteDatabase,\n sqliteRun,\n sqliteAll,\n sqliteGet,\n sqliteClose,\n sqliteExec,\n toDateFromSQLite,\n toSQLiteTimestamp,\n type SQLiteDatabase,\n type SQLiteOptions\n} from './sqlite-wrapper.js';\nimport { MarkdownMirror } from './markdown-mirror.js';\n\nexport interface SQLiteEventStoreOptions extends SQLiteOptions {\n markdownMirrorRoot?: string;\n}\n\nexport class SQLiteEventStore {\n private db: SQLiteDatabase;\n private initialized = false;\n private readonly readOnly: boolean;\n private readonly markdownMirror: MarkdownMirror | null;\n\n constructor(private dbPath: string, options?: SQLiteEventStoreOptions) {\n this.readOnly = options?.readonly ?? false;\n this.db = createSQLiteDatabase(dbPath, {\n readonly: this.readOnly,\n walMode: !this.readOnly\n });\n this.markdownMirror = this.readOnly || !options?.markdownMirrorRoot\n ? null\n : new MarkdownMirror(options.markdownMirrorRoot);\n }\n\n /**\n * Initialize database schema\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // In read-only mode, skip schema creation\n if (this.readOnly) {\n this.initialized = true;\n return;\n }\n\n // Create all tables in a single exec for efficiency\n sqliteExec(this.db, `\n -- L0 EventStore: Single Source of Truth (immutable, append-only)\n CREATE TABLE IF NOT EXISTS events (\n id TEXT PRIMARY KEY,\n event_type TEXT NOT NULL,\n session_id TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n content TEXT NOT NULL,\n canonical_key TEXT NOT NULL,\n dedupe_key TEXT UNIQUE,\n metadata TEXT,\n access_count INTEGER DEFAULT 0,\n last_accessed_at TEXT\n );\n\n -- Dedup table for idempotency\n CREATE TABLE IF NOT EXISTS event_dedup (\n dedupe_key TEXT PRIMARY KEY,\n event_id TEXT NOT NULL,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Session metadata\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n started_at TEXT NOT NULL,\n ended_at TEXT,\n project_path TEXT,\n summary TEXT,\n tags TEXT\n );\n\n -- Insights (derived data, rebuildable)\n CREATE TABLE IF NOT EXISTS insights (\n id TEXT PRIMARY KEY,\n insight_type TEXT NOT NULL,\n content TEXT NOT NULL,\n canonical_key TEXT NOT NULL,\n confidence REAL,\n source_events TEXT,\n created_at TEXT,\n last_updated TEXT\n );\n\n -- Embedding Outbox (Single-Writer Pattern)\n CREATE TABLE IF NOT EXISTS embedding_outbox (\n id TEXT PRIMARY KEY,\n event_id TEXT NOT NULL,\n content TEXT NOT NULL,\n status TEXT DEFAULT 'pending',\n retry_count INTEGER DEFAULT 0,\n created_at TEXT DEFAULT (datetime('now')),\n processed_at TEXT,\n error_message TEXT\n );\n\n -- Projection offset tracking\n CREATE TABLE IF NOT EXISTS projection_offsets (\n projection_name TEXT PRIMARY KEY,\n last_event_id TEXT,\n last_timestamp TEXT,\n updated_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Memory level tracking\n CREATE TABLE IF NOT EXISTS memory_levels (\n event_id TEXT PRIMARY KEY,\n level TEXT NOT NULL DEFAULT 'L0',\n promoted_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Entries (immutable memory units)\n CREATE TABLE IF NOT EXISTS entries (\n entry_id TEXT PRIMARY KEY,\n created_ts TEXT NOT NULL,\n entry_type TEXT NOT NULL,\n title TEXT NOT NULL,\n content_json TEXT NOT NULL,\n stage TEXT NOT NULL DEFAULT 'raw',\n status TEXT DEFAULT 'active',\n superseded_by TEXT,\n build_id TEXT,\n evidence_json TEXT,\n canonical_key TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Entities (task/condition/artifact)\n CREATE TABLE IF NOT EXISTS entities (\n entity_id TEXT PRIMARY KEY,\n entity_type TEXT NOT NULL,\n canonical_key TEXT NOT NULL,\n title TEXT NOT NULL,\n stage TEXT NOT NULL DEFAULT 'raw',\n status TEXT NOT NULL DEFAULT 'active',\n current_json TEXT NOT NULL,\n title_norm TEXT,\n search_text TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Entity aliases for canonical key lookup\n CREATE TABLE IF NOT EXISTS entity_aliases (\n entity_type TEXT NOT NULL,\n canonical_key TEXT NOT NULL,\n entity_id TEXT NOT NULL,\n is_primary INTEGER DEFAULT 0,\n created_at TEXT DEFAULT (datetime('now')),\n PRIMARY KEY(entity_type, canonical_key)\n );\n\n -- Edges (relationships between entries/entities)\n CREATE TABLE IF NOT EXISTS edges (\n edge_id TEXT PRIMARY KEY,\n src_type TEXT NOT NULL,\n src_id TEXT NOT NULL,\n rel_type TEXT NOT NULL,\n dst_type TEXT NOT NULL,\n dst_id TEXT NOT NULL,\n meta_json TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Vector Outbox V2 Table\n CREATE TABLE IF NOT EXISTS vector_outbox (\n job_id TEXT PRIMARY KEY,\n item_kind TEXT NOT NULL,\n item_id TEXT NOT NULL,\n embedding_version TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n retry_count INTEGER DEFAULT 0,\n error TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now')),\n UNIQUE(item_kind, item_id, embedding_version)\n );\n\n -- Build Runs\n CREATE TABLE IF NOT EXISTS build_runs (\n build_id TEXT PRIMARY KEY,\n started_at TEXT NOT NULL,\n finished_at TEXT,\n extractor_model TEXT NOT NULL,\n extractor_prompt_hash TEXT NOT NULL,\n embedder_model TEXT NOT NULL,\n embedding_version TEXT NOT NULL,\n idris_version TEXT NOT NULL,\n schema_version TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'running',\n error TEXT\n );\n\n -- Pipeline Metrics\n CREATE TABLE IF NOT EXISTS pipeline_metrics (\n id TEXT PRIMARY KEY,\n ts TEXT NOT NULL,\n stage TEXT NOT NULL,\n latency_ms REAL NOT NULL,\n success INTEGER NOT NULL,\n error TEXT,\n session_id TEXT\n );\n\n -- Working Set table (active memory window)\n CREATE TABLE IF NOT EXISTS working_set (\n id TEXT PRIMARY KEY,\n event_id TEXT NOT NULL,\n added_at TEXT DEFAULT (datetime('now')),\n relevance_score REAL DEFAULT 1.0,\n topics TEXT,\n expires_at TEXT\n );\n\n -- Consolidated Memories table (long-term integrated memories)\n CREATE TABLE IF NOT EXISTS consolidated_memories (\n memory_id TEXT PRIMARY KEY,\n summary TEXT NOT NULL,\n topics TEXT,\n source_events TEXT,\n confidence REAL DEFAULT 0.5,\n created_at TEXT DEFAULT (datetime('now')),\n accessed_at TEXT,\n access_count INTEGER DEFAULT 0\n );\n\n -- Continuity Log table (tracks context transitions)\n CREATE TABLE IF NOT EXISTS continuity_log (\n log_id TEXT PRIMARY KEY,\n from_context_id TEXT,\n to_context_id TEXT,\n continuity_score REAL,\n transition_type TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Consolidated Rules table (long-term stable memory)\n CREATE TABLE IF NOT EXISTS consolidated_rules (\n rule_id TEXT PRIMARY KEY,\n rule TEXT NOT NULL,\n topics TEXT,\n source_memory_ids TEXT,\n source_events TEXT,\n confidence REAL DEFAULT 0.5,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Endless Mode Config table\n CREATE TABLE IF NOT EXISTS endless_config (\n key TEXT PRIMARY KEY,\n value TEXT,\n updated_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Memory Helpfulness tracking\n CREATE TABLE IF NOT EXISTS memory_helpfulness (\n id TEXT PRIMARY KEY,\n event_id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n retrieval_score REAL DEFAULT 0,\n query_preview TEXT,\n session_continued INTEGER DEFAULT 0,\n prompt_count_after INTEGER DEFAULT 0,\n tool_success_count INTEGER DEFAULT 0,\n tool_total_count INTEGER DEFAULT 0,\n was_reasked INTEGER DEFAULT 0,\n helpfulness_score REAL DEFAULT 0.5,\n created_at TEXT DEFAULT (datetime('now')),\n measured_at TEXT\n );\n\n -- Retrieval trace log (query -> candidates -> selected for context)\n CREATE TABLE IF NOT EXISTS retrieval_traces (\n trace_id TEXT PRIMARY KEY,\n session_id TEXT,\n project_hash TEXT,\n query_text TEXT NOT NULL,\n strategy TEXT,\n candidate_event_ids TEXT,\n selected_event_ids TEXT,\n candidate_details_json TEXT,\n selected_details_json TEXT,\n candidate_count INTEGER DEFAULT 0,\n selected_count INTEGER DEFAULT 0,\n confidence TEXT,\n fallback_trace TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Sync position tracking (for SQLite -> DuckDB sync)\n CREATE TABLE IF NOT EXISTS sync_positions (\n target_name TEXT PRIMARY KEY,\n last_event_id TEXT,\n last_timestamp TEXT,\n updated_at TEXT DEFAULT (datetime('now'))\n );\n\n -- Create indexes\n CREATE INDEX IF NOT EXISTS idx_events_session ON events(session_id);\n CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);\n CREATE INDEX IF NOT EXISTS idx_entries_type ON entries(entry_type);\n CREATE INDEX IF NOT EXISTS idx_entries_stage ON entries(stage);\n CREATE INDEX IF NOT EXISTS idx_entries_canonical ON entries(canonical_key);\n CREATE INDEX IF NOT EXISTS idx_entities_type_key ON entities(entity_type, canonical_key);\n CREATE INDEX IF NOT EXISTS idx_entities_status ON entities(status);\n CREATE INDEX IF NOT EXISTS idx_edges_src ON edges(src_id, rel_type);\n CREATE INDEX IF NOT EXISTS idx_edges_dst ON edges(dst_id, rel_type);\n CREATE INDEX IF NOT EXISTS idx_edges_rel ON edges(rel_type);\n CREATE INDEX IF NOT EXISTS idx_outbox_status ON vector_outbox(status);\n CREATE INDEX IF NOT EXISTS idx_working_set_expires ON working_set(expires_at);\n CREATE INDEX IF NOT EXISTS idx_working_set_relevance ON working_set(relevance_score);\n CREATE INDEX IF NOT EXISTS idx_consolidated_confidence ON consolidated_memories(confidence);\n CREATE INDEX IF NOT EXISTS idx_continuity_created ON continuity_log(created_at);\n CREATE INDEX IF NOT EXISTS idx_consolidated_rules_confidence ON consolidated_rules(confidence);\n CREATE INDEX IF NOT EXISTS idx_embedding_outbox_status ON embedding_outbox(status);\n CREATE INDEX IF NOT EXISTS idx_helpfulness_event ON memory_helpfulness(event_id);\n CREATE INDEX IF NOT EXISTS idx_helpfulness_session ON memory_helpfulness(session_id);\n CREATE INDEX IF NOT EXISTS idx_helpfulness_score ON memory_helpfulness(helpfulness_score DESC);\n CREATE INDEX IF NOT EXISTS idx_retrieval_traces_created_at ON retrieval_traces(created_at DESC);\n CREATE INDEX IF NOT EXISTS idx_retrieval_traces_project_hash ON retrieval_traces(project_hash);\n CREATE INDEX IF NOT EXISTS idx_retrieval_traces_session_id ON retrieval_traces(session_id);\n\n -- FTS5 Full-Text Search for fast keyword search\n CREATE VIRTUAL TABLE IF NOT EXISTS events_fts USING fts5(\n content,\n event_id UNINDEXED,\n content='events',\n content_rowid='rowid'\n );\n\n -- Triggers to keep FTS in sync with events table\n CREATE TRIGGER IF NOT EXISTS events_fts_insert AFTER INSERT ON events BEGIN\n INSERT INTO events_fts(rowid, content, event_id) VALUES (NEW.rowid, NEW.content, NEW.id);\n END;\n\n CREATE TRIGGER IF NOT EXISTS events_fts_delete AFTER DELETE ON events BEGIN\n INSERT INTO events_fts(events_fts, rowid, content, event_id) VALUES('delete', OLD.rowid, OLD.content, OLD.id);\n END;\n\n CREATE TRIGGER IF NOT EXISTS events_fts_update AFTER UPDATE ON events BEGIN\n INSERT INTO events_fts(events_fts, rowid, content, event_id) VALUES('delete', OLD.rowid, OLD.content, OLD.id);\n INSERT INTO events_fts(rowid, content, event_id) VALUES (NEW.rowid, NEW.content, NEW.id);\n END;\n `);\n\n\n // Best-effort forward migration for retrieval trace detail column\n try {\n sqliteExec(this.db, `ALTER TABLE retrieval_traces ADD COLUMN selected_details_json TEXT;`);\n } catch {\n // column may already exist\n }\n try {\n sqliteExec(this.db, `ALTER TABLE retrieval_traces ADD COLUMN candidate_details_json TEXT;`);\n } catch {\n // column may already exist\n }\n\n // Migrate existing events table to add new columns if they don't exist\n // Check if columns exist before trying to add them\n const tableInfo = sqliteAll(this.db, \"PRAGMA table_info(events)\", []);\n const columnNames = tableInfo.map((col: any) => col.name);\n\n if (!columnNames.includes('access_count')) {\n try {\n sqliteExec(this.db, `\n ALTER TABLE events ADD COLUMN access_count INTEGER DEFAULT 0;\n `);\n } catch (err: any) {\n console.error('Error adding access_count column:', err);\n }\n }\n\n if (!columnNames.includes('last_accessed_at')) {\n try {\n sqliteExec(this.db, `\n ALTER TABLE events ADD COLUMN last_accessed_at TEXT;\n `);\n } catch (err: any) {\n console.error('Error adding last_accessed_at column:', err);\n }\n }\n\n // Add turn_id column for grouping events within a conversation turn\n if (!columnNames.includes('turn_id')) {\n try {\n sqliteExec(this.db, `\n ALTER TABLE events ADD COLUMN turn_id TEXT;\n `);\n } catch (err: any) {\n console.error('Error adding turn_id column:', err);\n }\n }\n\n // Create indexes for new columns if they don't exist\n try {\n sqliteExec(this.db, `\n CREATE INDEX IF NOT EXISTS idx_events_access_count ON events(access_count DESC);\n `);\n } catch (err: any) {\n // Index may already exist, ignore\n }\n\n try {\n sqliteExec(this.db, `\n CREATE INDEX IF NOT EXISTS idx_events_last_accessed ON events(last_accessed_at DESC);\n `);\n } catch (err: any) {\n // Index may already exist, ignore\n }\n\n try {\n sqliteExec(this.db, `\n CREATE INDEX IF NOT EXISTS idx_events_turn_id ON events(turn_id);\n `);\n } catch (err: any) {\n // Index may already exist, ignore\n }\n\n this.initialized = true;\n }\n\n /**\n * Append event to store (Append-only, Idempotent)\n */\n async append(input: MemoryEventInput): Promise<AppendResult> {\n await this.initialize();\n\n const canonicalKey = makeCanonicalKey(input.content);\n const dedupeKey = makeDedupeKey(input.content, input.sessionId);\n\n // Check for duplicate\n const existing = sqliteGet<{ event_id: string }>(\n this.db,\n `SELECT event_id FROM event_dedup WHERE dedupe_key = ?`,\n [dedupeKey]\n );\n\n if (existing) {\n return {\n success: true,\n eventId: existing.event_id,\n isDuplicate: true\n };\n }\n\n const id = randomUUID();\n const timestamp = toSQLiteTimestamp(input.timestamp);\n\n try {\n // Extract turnId from metadata if present\n const metadata = input.metadata || {};\n const turnId = (metadata.turnId as string) || null;\n\n // Use transaction for atomicity\n const insertEvent = this.db.prepare(`\n INSERT INTO events (id, event_type, session_id, timestamp, content, canonical_key, dedupe_key, metadata, turn_id)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const insertDedup = this.db.prepare(`\n INSERT INTO event_dedup (dedupe_key, event_id) VALUES (?, ?)\n `);\n\n const insertLevel = this.db.prepare(`\n INSERT INTO memory_levels (event_id, level) VALUES (?, 'L0')\n `);\n\n const transaction = this.db.transaction(() => {\n insertEvent.run(\n id,\n input.eventType,\n input.sessionId,\n timestamp,\n input.content,\n canonicalKey,\n dedupeKey,\n JSON.stringify(metadata),\n turnId\n );\n insertDedup.run(dedupeKey, id);\n insertLevel.run(id);\n });\n\n transaction();\n\n if (this.markdownMirror) {\n const event: MemoryEvent = {\n id,\n eventType: input.eventType,\n sessionId: input.sessionId,\n timestamp: input.timestamp,\n content: input.content,\n canonicalKey,\n dedupeKey,\n metadata\n };\n this.markdownMirror.append(event).catch((err) => {\n console.warn('[SQLiteEventStore] markdown mirror append failed:', err);\n });\n }\n\n return { success: true, eventId: id, isDuplicate: false };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n\n /**\n * Get events by session ID\n */\n async getSessionEvents(sessionId: string): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,\n [sessionId]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Get recent events\n */\n async getRecentEvents(limit: number = 100): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events ORDER BY timestamp DESC LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Get event by ID\n */\n async getEvent(id: string): Promise<MemoryEvent | null> {\n await this.initialize();\n\n const row = sqliteGet<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE id = ?`,\n [id]\n );\n\n if (!row) return null;\n return this.rowToEvent(row);\n }\n\n /**\n * Get events since a timestamp (for sync)\n */\n async getEventsSince(timestamp: string, limit: number = 1000): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE timestamp > ? ORDER BY timestamp ASC LIMIT ?`,\n [timestamp, limit]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Get events since a SQLite rowid (for robust incremental replication).\n * Rowid is monotonic for append-only tables, independent of client timestamps.\n */\n async getEventsSinceRowid(\n lastRowid: number,\n limit: number = 1000\n ): Promise<Array<{ rowid: number; event: MemoryEvent }>> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT rowid as _rowid, * FROM events WHERE rowid > ? ORDER BY rowid ASC LIMIT ?`,\n [lastRowid, limit]\n );\n\n return rows.map(row => ({\n rowid: row._rowid as number,\n event: this.rowToEvent(row)\n }));\n }\n\n /**\n * Import events with fixed IDs (used for cross-machine replication).\n * Idempotent: skips if event id or dedupeKey already exists.\n *\n * NOTE: This bypasses the append() id generation to preserve stable IDs.\n */\n async importEvents(events: MemoryEvent[]): Promise<{ inserted: number; skipped: number }> {\n if (events.length === 0) return { inserted: 0, skipped: 0 };\n if (this.readOnly) return { inserted: 0, skipped: events.length };\n\n await this.initialize();\n\n const getById = this.db.prepare(`SELECT id FROM events WHERE id = ?`);\n const getByDedupe = this.db.prepare(`SELECT event_id FROM event_dedup WHERE dedupe_key = ?`);\n\n const insertEvent = this.db.prepare(`\n INSERT INTO events (id, event_type, session_id, timestamp, content, canonical_key, dedupe_key, metadata, turn_id)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n const insertDedup = this.db.prepare(`\n INSERT INTO event_dedup (dedupe_key, event_id) VALUES (?, ?)\n `);\n\n const insertLevel = this.db.prepare(`\n INSERT INTO memory_levels (event_id, level) VALUES (?, 'L0')\n `);\n\n let inserted = 0;\n let skipped = 0;\n const insertedEvents: MemoryEvent[] = [];\n\n const tx = this.db.transaction((batch: MemoryEvent[]) => {\n for (const ev of batch) {\n // Skip if already present by id\n const existingById = getById.get(ev.id) as { id: string } | undefined;\n if (existingById) {\n skipped++;\n continue;\n }\n\n const canonicalKey = ev.canonicalKey || makeCanonicalKey(ev.content);\n const dedupeKey = ev.dedupeKey || makeDedupeKey(ev.content, ev.sessionId);\n\n // Skip if already present by dedupe key\n const existingByDedupe = getByDedupe.get(dedupeKey) as { event_id: string } | undefined;\n if (existingByDedupe) {\n skipped++;\n continue;\n }\n\n const metadata = ev.metadata || {};\n const turnId = (metadata as any).turnId as string | undefined;\n\n insertEvent.run(\n ev.id,\n ev.eventType,\n ev.sessionId,\n toSQLiteTimestamp(ev.timestamp),\n ev.content,\n canonicalKey,\n dedupeKey,\n JSON.stringify(metadata),\n turnId ?? null\n );\n\n insertDedup.run(dedupeKey, ev.id);\n insertLevel.run(ev.id);\n inserted++;\n insertedEvents.push(ev);\n }\n });\n\n tx(events);\n\n if (this.markdownMirror && insertedEvents.length > 0) {\n for (const ev of insertedEvents) {\n this.markdownMirror.append(ev).catch((err) => {\n console.warn('[SQLiteEventStore] markdown mirror append failed:', err);\n });\n }\n }\n\n return { inserted, skipped };\n }\n\n /**\n * Create or update session\n */\n async upsertSession(session: Partial<Session> & { id: string }): Promise<void> {\n await this.initialize();\n\n const existing = sqliteGet<{ id: string }>(\n this.db,\n `SELECT id FROM sessions WHERE id = ?`,\n [session.id]\n );\n\n if (!existing) {\n sqliteRun(\n this.db,\n `INSERT INTO sessions (id, started_at, project_path, tags)\n VALUES (?, ?, ?, ?)`,\n [\n session.id,\n toSQLiteTimestamp(session.startedAt || new Date()),\n session.projectPath || null,\n JSON.stringify(session.tags || [])\n ]\n );\n } else {\n const updates: string[] = [];\n const values: unknown[] = [];\n\n if (session.endedAt) {\n updates.push('ended_at = ?');\n values.push(toSQLiteTimestamp(session.endedAt));\n }\n if (session.summary) {\n updates.push('summary = ?');\n values.push(session.summary);\n }\n if (session.tags) {\n updates.push('tags = ?');\n values.push(JSON.stringify(session.tags));\n }\n\n if (updates.length > 0) {\n values.push(session.id);\n sqliteRun(\n this.db,\n `UPDATE sessions SET ${updates.join(', ')} WHERE id = ?`,\n values\n );\n }\n }\n }\n\n /**\n * Get session by ID\n */\n async getSession(id: string): Promise<Session | null> {\n await this.initialize();\n\n const row = sqliteGet<Record<string, unknown>>(\n this.db,\n `SELECT * FROM sessions WHERE id = ?`,\n [id]\n );\n\n if (!row) return null;\n\n return {\n id: row.id as string,\n startedAt: toDateFromSQLite(row.started_at),\n endedAt: row.ended_at ? toDateFromSQLite(row.ended_at) : undefined,\n projectPath: row.project_path as string | undefined,\n summary: row.summary as string | undefined,\n tags: row.tags ? JSON.parse(row.tags as string) : undefined\n };\n }\n\n /**\n * Get all sessions\n */\n async getAllSessions(): Promise<Session[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM sessions ORDER BY started_at DESC`\n );\n\n return rows.map(row => ({\n id: row.id as string,\n startedAt: toDateFromSQLite(row.started_at),\n endedAt: row.ended_at ? toDateFromSQLite(row.ended_at) : undefined,\n projectPath: row.project_path as string | undefined,\n summary: row.summary as string | undefined,\n tags: row.tags ? JSON.parse(row.tags as string) : undefined\n }));\n }\n\n /**\n * Add to embedding outbox\n */\n async enqueueForEmbedding(eventId: string, content: string): Promise<string> {\n await this.initialize();\n\n const id = randomUUID();\n sqliteRun(\n this.db,\n `INSERT INTO embedding_outbox (id, event_id, content, status, retry_count)\n VALUES (?, ?, ?, 'pending', 0)`,\n [id, eventId, content]\n );\n\n return id;\n }\n\n /**\n * Get pending outbox items\n */\n async getPendingOutboxItems(limit: number = 32): Promise<OutboxItem[]> {\n await this.initialize();\n\n const pending = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM embedding_outbox\n WHERE status = 'pending'\n ORDER BY created_at\n LIMIT ?`,\n [limit]\n );\n\n if (pending.length === 0) return [];\n\n // Update status to processing\n const ids = pending.map(r => r.id as string);\n const placeholders = ids.map(() => '?').join(',');\n sqliteRun(\n this.db,\n `UPDATE embedding_outbox SET status = 'processing' WHERE id IN (${placeholders})`,\n ids\n );\n\n return pending.map(row => ({\n id: row.id as string,\n eventId: row.event_id as string,\n content: row.content as string,\n status: 'processing' as const,\n retryCount: row.retry_count as number,\n createdAt: toDateFromSQLite(row.created_at),\n errorMessage: row.error_message as string | undefined\n }));\n }\n\n /**\n * Mark outbox items as done\n */\n async completeOutboxItems(ids: string[]): Promise<void> {\n if (ids.length === 0) return;\n\n const placeholders = ids.map(() => '?').join(',');\n sqliteRun(\n this.db,\n `DELETE FROM embedding_outbox WHERE id IN (${placeholders})`,\n ids\n );\n }\n\n /**\n * Clear embedding outbox (used for embedding model migration)\n */\n async clearEmbeddingOutbox(): Promise<void> {\n await this.initialize();\n sqliteRun(this.db, `DELETE FROM embedding_outbox`);\n }\n\n /**\n * Count total events\n */\n async countEvents(): Promise<number> {\n await this.initialize();\n const row = sqliteGet<{ count: number }>(this.db, `SELECT COUNT(*) as count FROM events`);\n return row?.count || 0;\n }\n\n /**\n * Get events page in timestamp ascending order (stable migration/reindex scans)\n */\n async getEventsPage(limit: number = 1000, offset: number = 0): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events ORDER BY timestamp ASC LIMIT ? OFFSET ?`,\n [limit, offset]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Mark outbox items as failed\n */\n async failOutboxItems(ids: string[], error: string): Promise<void> {\n if (ids.length === 0) return;\n\n const placeholders = ids.map(() => '?').join(',');\n sqliteRun(\n this.db,\n `UPDATE embedding_outbox\n SET status = CASE WHEN retry_count >= 3 THEN 'failed' ELSE 'pending' END,\n retry_count = retry_count + 1,\n error_message = ?\n WHERE id IN (${placeholders})`,\n [error, ...ids]\n );\n }\n\n\n /**\n * Get embedding/vector outbox health statistics\n */\n async getOutboxStats(): Promise<{\n embedding: { pending: number; processing: number; failed: number; total: number };\n vector: { pending: number; processing: number; failed: number; total: number };\n }> {\n await this.initialize();\n\n const embeddingRows = sqliteAll<{ status: string; count: number }>(\n this.db,\n `SELECT status, COUNT(*) as count FROM embedding_outbox GROUP BY status`\n );\n const vectorRows = sqliteAll<{ status: string; count: number }>(\n this.db,\n `SELECT status, COUNT(*) as count FROM vector_outbox GROUP BY status`\n );\n\n const fromRows = (rows: Array<{ status: string; count: number }>) => {\n const out = { pending: 0, processing: 0, failed: 0, total: 0 };\n for (const row of rows) {\n const key = row.status as 'pending' | 'processing' | 'failed' | 'done';\n if (key === 'pending' || key === 'processing' || key === 'failed') {\n out[key] += row.count;\n }\n out.total += row.count;\n }\n return out;\n };\n\n return {\n embedding: fromRows(embeddingRows),\n vector: fromRows(vectorRows)\n };\n }\n\n /**\n * Update memory level\n */\n async updateMemoryLevel(eventId: string, level: string): Promise<void> {\n await this.initialize();\n\n sqliteRun(\n this.db,\n `UPDATE memory_levels SET level = ?, promoted_at = datetime('now') WHERE event_id = ?`,\n [level, eventId]\n );\n }\n\n /**\n * Get memory level statistics\n */\n async getLevelStats(): Promise<Array<{ level: string; count: number }>> {\n await this.initialize();\n\n const rows = sqliteAll<{ level: string; count: number }>(\n this.db,\n `SELECT level, COUNT(*) as count FROM memory_levels GROUP BY level`\n );\n\n return rows;\n }\n\n /**\n * Get events by memory level\n */\n async getEventsByLevel(level: string, options?: { limit?: number; offset?: number }): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const limit = options?.limit || 50;\n const offset = options?.offset || 0;\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT e.* FROM events e\n INNER JOIN memory_levels ml ON e.id = ml.event_id\n WHERE ml.level = ?\n ORDER BY e.timestamp DESC\n LIMIT ? OFFSET ?`,\n [level, limit, offset]\n );\n\n return rows.map(row => this.rowToEvent(row));\n }\n\n /**\n * Get memory level for a specific event\n */\n async getEventLevel(eventId: string): Promise<string | null> {\n await this.initialize();\n\n const row = sqliteGet<{ level: string }>(\n this.db,\n `SELECT level FROM memory_levels WHERE event_id = ?`,\n [eventId]\n );\n\n return row ? row.level : null;\n }\n\n /**\n * Get sync position for a target\n */\n async getSyncPosition(targetName: string): Promise<{ lastEventId: string | null; lastTimestamp: string | null }> {\n await this.initialize();\n\n const row = sqliteGet<{ last_event_id: string | null; last_timestamp: string | null }>(\n this.db,\n `SELECT last_event_id, last_timestamp FROM sync_positions WHERE target_name = ?`,\n [targetName]\n );\n\n return {\n lastEventId: row?.last_event_id ?? null,\n lastTimestamp: row?.last_timestamp ?? null\n };\n }\n\n /**\n * Update sync position for a target\n */\n async updateSyncPosition(targetName: string, lastEventId: string, lastTimestamp: string): Promise<void> {\n await this.initialize();\n\n sqliteRun(\n this.db,\n `INSERT OR REPLACE INTO sync_positions (target_name, last_event_id, last_timestamp, updated_at)\n VALUES (?, ?, ?, datetime('now'))`,\n [targetName, lastEventId, lastTimestamp]\n );\n }\n\n /**\n * Get config value for endless mode\n */\n async getEndlessConfig(key: string): Promise<unknown | null> {\n await this.initialize();\n\n const row = sqliteGet<{ value: string }>(\n this.db,\n `SELECT value FROM endless_config WHERE key = ?`,\n [key]\n );\n\n if (!row) return null;\n return JSON.parse(row.value);\n }\n\n /**\n * Set config value for endless mode\n */\n async setEndlessConfig(key: string, value: unknown): Promise<void> {\n await this.initialize();\n\n sqliteRun(\n this.db,\n `INSERT OR REPLACE INTO endless_config (key, value, updated_at)\n VALUES (?, ?, datetime('now'))`,\n [key, JSON.stringify(value)]\n );\n }\n\n /**\n * Increment access count for events\n */\n async incrementAccessCount(eventIds: string[]): Promise<void> {\n if (eventIds.length === 0 || this.readOnly) return;\n\n await this.initialize();\n\n const placeholders = eventIds.map(() => '?').join(',');\n const currentTime = toSQLiteTimestamp(new Date());\n\n sqliteRun(\n this.db,\n `UPDATE events\n SET access_count = access_count + 1,\n last_accessed_at = ?\n WHERE id IN (${placeholders})`,\n [currentTime, ...eventIds]\n );\n }\n\n /**\n * Get most accessed memories (falls back to recent events if none accessed)\n */\n async getMostAccessed(limit: number = 10): Promise<MemoryEvent[]> {\n await this.initialize();\n\n // First try events with access_count > 0\n let rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events\n WHERE access_count > 0\n ORDER BY access_count DESC, last_accessed_at DESC\n LIMIT ?`,\n [limit]\n );\n\n // Fallback: if no accessed events, show recent events\n if (rows.length === 0) {\n rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events\n ORDER BY timestamp DESC\n LIMIT ?`,\n [limit]\n );\n }\n\n return rows.map(row => this.rowToEvent(row));\n }\n\n /**\n * Record a memory retrieval for helpfulness tracking\n */\n async recordRetrieval(eventId: string, sessionId: string, score: number, query: string): Promise<void> {\n if (this.readOnly) return;\n await this.initialize();\n\n const id = randomUUID();\n sqliteRun(\n this.db,\n `INSERT INTO memory_helpfulness (id, event_id, session_id, retrieval_score, query_preview, created_at)\n VALUES (?, ?, ?, ?, ?, datetime('now'))`,\n [id, eventId, sessionId, score, query.slice(0, 100)]\n );\n }\n\n /**\n * Get session IDs that have unevaluated retrievals (measured_at IS NULL).\n * Excludes the current session. Used to backfill sessions that ended without Stop hook.\n */\n async getUnevaluatedSessions(currentSessionId: string, limit = 5): Promise<string[]> {\n await this.initialize();\n const rows = sqliteAll<{ session_id: string }>(\n this.db,\n `SELECT DISTINCT session_id FROM memory_helpfulness\n WHERE measured_at IS NULL AND session_id != ?\n ORDER BY created_at DESC LIMIT ?`,\n [currentSessionId, limit]\n );\n return rows.map((r) => r.session_id);\n }\n\n /**\n * Evaluate helpfulness for all retrievals in a session\n * Called at session end - uses behavioral signals to compute score\n */\n async evaluateSessionHelpfulness(sessionId: string): Promise<void> {\n if (this.readOnly) return;\n await this.initialize();\n\n // Get all retrieval records for this session\n const retrievals = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM memory_helpfulness WHERE session_id = ? AND measured_at IS NULL`,\n [sessionId]\n );\n\n if (retrievals.length === 0) return;\n\n // Get session events to analyze behavior after retrieval\n const sessionEvents = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,\n [sessionId]\n );\n\n const promptEvents = sessionEvents.filter((e: any) => e.event_type === 'user_prompt');\n const toolEvents = sessionEvents.filter((e: any) => e.event_type === 'tool_observation');\n\n // Count successful vs failed tools\n let toolSuccessCount = 0;\n let toolTotalCount = toolEvents.length;\n for (const t of toolEvents) {\n try {\n const content = JSON.parse(t.content as string);\n if (content.success !== false) toolSuccessCount++;\n } catch {\n toolSuccessCount++; // Assume success if can't parse\n }\n }\n const toolSuccessRatio = toolTotalCount > 0 ? toolSuccessCount / toolTotalCount : 0.5;\n\n for (const retrieval of retrievals) {\n const retrievalTime = retrieval.created_at as string;\n\n // 1. Session continued after retrieval?\n const eventsAfter = sessionEvents.filter((e: any) => e.timestamp > retrievalTime);\n const sessionContinued = eventsAfter.length > 0 ? 1 : 0;\n\n // 2. How many prompts came after?\n const promptsAfter = promptEvents.filter((e: any) => e.timestamp > retrievalTime);\n const promptCountAfter = promptsAfter.length;\n\n // 3. Was a similar query asked again? (simple word overlap check)\n const queryWords = new Set((retrieval.query_preview as string || '').toLowerCase().split(/\\s+/).filter(w => w.length > 2));\n let wasReasked = 0;\n for (const p of promptsAfter) {\n const pWords = new Set((p.content as string).toLowerCase().split(/\\s+/).filter((w: string) => w.length > 2));\n let overlap = 0;\n for (const w of queryWords) {\n if (pWords.has(w)) overlap++;\n }\n if (queryWords.size > 0 && overlap / queryWords.size > 0.5) {\n wasReasked = 1;\n break;\n }\n }\n\n // Calculate helpfulness score\n const retrievalScore = retrieval.retrieval_score as number || 0;\n const helpfulnessScore = (\n 0.30 * Math.min(retrievalScore, 1.0) +\n 0.25 * (sessionContinued ? 1.0 : 0.0) +\n 0.25 * toolSuccessRatio +\n 0.20 * (wasReasked ? 0.0 : 1.0)\n );\n\n sqliteRun(\n this.db,\n `UPDATE memory_helpfulness\n SET session_continued = ?, prompt_count_after = ?,\n tool_success_count = ?, tool_total_count = ?,\n was_reasked = ?, helpfulness_score = ?,\n measured_at = datetime('now')\n WHERE id = ?`,\n [sessionContinued, promptCountAfter, toolSuccessCount, toolTotalCount,\n wasReasked, helpfulnessScore, retrieval.id]\n );\n }\n }\n\n /**\n * Get most helpful memories ranked by helpfulness score\n */\n async getHelpfulMemories(limit: number = 10): Promise<Array<{\n eventId: string;\n summary: string;\n helpfulnessScore: number;\n accessCount: number;\n evaluationCount: number;\n }>> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT\n mh.event_id,\n AVG(mh.helpfulness_score) as avg_score,\n COUNT(*) as eval_count,\n e.content,\n e.access_count\n FROM memory_helpfulness mh\n JOIN events e ON e.id = mh.event_id\n WHERE mh.measured_at IS NOT NULL\n GROUP BY mh.event_id\n ORDER BY avg_score DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(r => ({\n eventId: r.event_id as string,\n summary: (r.content as string).substring(0, 200) + ((r.content as string).length > 200 ? '...' : ''),\n helpfulnessScore: Math.round((r.avg_score as number) * 100) / 100,\n accessCount: (r.access_count as number) || 0,\n evaluationCount: r.eval_count as number\n }));\n }\n\n /**\n * Get helpfulness statistics for dashboard\n */\n async getHelpfulnessStats(): Promise<{\n avgScore: number;\n totalEvaluated: number;\n totalRetrievals: number;\n helpful: number;\n neutral: number;\n unhelpful: number;\n }> {\n await this.initialize();\n\n const stats = sqliteGet<Record<string, unknown>>(\n this.db,\n `SELECT\n AVG(helpfulness_score) as avg_score,\n COUNT(*) as total_evaluated,\n SUM(CASE WHEN helpfulness_score >= 0.7 THEN 1 ELSE 0 END) as helpful,\n SUM(CASE WHEN helpfulness_score >= 0.4 AND helpfulness_score < 0.7 THEN 1 ELSE 0 END) as neutral,\n SUM(CASE WHEN helpfulness_score < 0.4 THEN 1 ELSE 0 END) as unhelpful\n FROM memory_helpfulness\n WHERE measured_at IS NOT NULL`\n );\n\n const totalRow = sqliteGet<Record<string, unknown>>(\n this.db,\n `SELECT COUNT(*) as total FROM memory_helpfulness`\n );\n\n return {\n avgScore: Math.round(((stats?.avg_score as number) || 0) * 100) / 100,\n totalEvaluated: (stats?.total_evaluated as number) || 0,\n totalRetrievals: (totalRow?.total as number) || 0,\n helpful: (stats?.helpful as number) || 0,\n neutral: (stats?.neutral as number) || 0,\n unhelpful: (stats?.unhelpful as number) || 0\n };\n }\n\n /**\n * Fast keyword search using FTS5\n * Returns events matching the search query, ranked by relevance\n */\n async keywordSearch(query: string, limit: number = 10): Promise<Array<{event: MemoryEvent; rank: number}>> {\n await this.initialize();\n\n // Escape special FTS5 characters and prepare search terms\n const searchTerms = query\n .replace(/['\"(){}[\\]^~*?:\\\\/-]/g, ' ') // Remove special chars\n .split(/\\s+/)\n .filter(term => term.length > 1) // Filter short terms\n .map(term => `\"${term}\"*`) // Prefix matching\n .join(' OR ');\n\n if (!searchTerms) {\n return [];\n }\n\n try {\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT e.*, fts.rank\n FROM events_fts fts\n JOIN events e ON e.id = fts.event_id\n WHERE events_fts MATCH ?\n ORDER BY fts.rank\n LIMIT ?`,\n [searchTerms, limit]\n );\n\n return rows.map(row => ({\n event: this.rowToEvent(row),\n rank: row.rank as number\n }));\n } catch (error: any) {\n // FTS table might not exist yet (old database)\n // Fallback to LIKE search\n const likePattern = `%${query}%`;\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT *, 0 as rank FROM events\n WHERE content LIKE ?\n ORDER BY timestamp DESC\n LIMIT ?`,\n [likePattern, limit]\n );\n\n return rows.map(row => ({\n event: this.rowToEvent(row),\n rank: 0\n }));\n }\n }\n\n /**\n * Rebuild FTS index from existing events\n * Call this once after upgrading to FTS5\n */\n async rebuildFtsIndex(): Promise<number> {\n await this.initialize();\n\n // Get count of events to index\n const countRow = sqliteGet<{count: number}>(this.db, 'SELECT COUNT(*) as count FROM events', []);\n const totalEvents = countRow?.count ?? 0;\n\n // Clear and rebuild FTS index\n sqliteExec(this.db, `\n DELETE FROM events_fts;\n INSERT INTO events_fts(rowid, content, event_id)\n SELECT rowid, content, id FROM events;\n `);\n\n return totalEvents;\n }\n\n /**\n * Get database instance for direct access\n */\n getDatabase(): SQLiteDatabase {\n return this.db;\n }\n\n\n async recordRetrievalTrace(input: {\n sessionId?: string;\n projectHash?: string;\n queryText: string;\n strategy?: string;\n candidateEventIds: string[];\n selectedEventIds: string[];\n candidateDetails?: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n selectedDetails?: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n confidence?: string;\n fallbackTrace?: string[];\n }): Promise<void> {\n await this.initialize();\n\n const traceId = randomUUID();\n sqliteRun(\n this.db,\n `INSERT INTO retrieval_traces (\n trace_id, session_id, project_hash, query_text, strategy,\n candidate_event_ids, selected_event_ids, candidate_details_json, selected_details_json,\n candidate_count, selected_count, confidence, fallback_trace\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n traceId,\n input.sessionId || null,\n input.projectHash || null,\n input.queryText,\n input.strategy || null,\n JSON.stringify(input.candidateEventIds || []),\n JSON.stringify(input.selectedEventIds || []),\n JSON.stringify(input.candidateDetails || []),\n JSON.stringify(input.selectedDetails || []),\n (input.candidateEventIds || []).length,\n (input.selectedEventIds || []).length,\n input.confidence || null,\n JSON.stringify(input.fallbackTrace || [])\n ]\n );\n }\n\n async getRecentRetrievalTraces(limit: number = 50): Promise<Array<{\n traceId: string;\n sessionId?: string;\n projectHash?: string;\n queryText: string;\n strategy?: string;\n candidateEventIds: string[];\n selectedEventIds: string[];\n candidateDetails: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n selectedDetails: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n candidateCount: number;\n selectedCount: number;\n confidence?: string;\n fallbackTrace: string[];\n createdAt: Date;\n }>> {\n await this.initialize();\n\n try {\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM retrieval_traces ORDER BY created_at DESC LIMIT ?`,\n [limit]\n );\n\n return rows.map((row) => ({\n traceId: row.trace_id as string,\n sessionId: (row.session_id as string) || undefined,\n projectHash: (row.project_hash as string) || undefined,\n queryText: row.query_text as string,\n strategy: (row.strategy as string) || undefined,\n candidateEventIds: row.candidate_event_ids ? JSON.parse(row.candidate_event_ids as string) : [],\n selectedEventIds: row.selected_event_ids ? JSON.parse(row.selected_event_ids as string) : [],\n candidateDetails: row.candidate_details_json ? JSON.parse(row.candidate_details_json as string) : [],\n selectedDetails: row.selected_details_json ? JSON.parse(row.selected_details_json as string) : [],\n candidateCount: Number(row.candidate_count || 0),\n selectedCount: Number(row.selected_count || 0),\n confidence: (row.confidence as string) || undefined,\n fallbackTrace: row.fallback_trace ? JSON.parse(row.fallback_trace as string) : [],\n createdAt: toDateFromSQLite(row.created_at),\n }));\n } catch (err: any) {\n if (err?.message?.includes('no such table')) return [];\n throw err;\n }\n }\n\n async getRetrievalTraceStats(): Promise<{\n totalQueries: number;\n avgCandidateCount: number;\n avgSelectedCount: number;\n selectionRate: number;\n }> {\n await this.initialize();\n\n try {\n const row = sqliteGet<Record<string, unknown>>(\n this.db,\n `SELECT\n COUNT(*) as total_queries,\n AVG(candidate_count) as avg_candidate_count,\n AVG(selected_count) as avg_selected_count,\n CASE\n WHEN SUM(candidate_count) > 0 THEN (SUM(selected_count) * 1.0 / SUM(candidate_count))\n ELSE 0\n END as selection_rate\n FROM retrieval_traces`,\n []\n );\n\n return {\n totalQueries: Number(row?.total_queries || 0),\n avgCandidateCount: Number(row?.avg_candidate_count || 0),\n avgSelectedCount: Number(row?.avg_selected_count || 0),\n selectionRate: Number(row?.selection_rate || 0),\n };\n } catch (err: any) {\n if (err?.message?.includes('no such table')) {\n return { totalQueries: 0, avgCandidateCount: 0, avgSelectedCount: 0, selectionRate: 0 };\n }\n throw err;\n }\n }\n\n /**\n * Close database connection\n */\n async close(): Promise<void> {\n sqliteClose(this.db);\n }\n\n /**\n * Get events grouped by turn_id for a session\n * Returns turns ordered by first event timestamp (newest first)\n */\n async getSessionTurns(sessionId: string, options?: { limit?: number; offset?: number }): Promise<Array<{\n turnId: string;\n events: MemoryEvent[];\n startedAt: Date;\n promptPreview: string;\n eventCount: number;\n toolCount: number;\n hasResponse: boolean;\n }>> {\n await this.initialize();\n\n const limit = options?.limit || 20;\n const offset = options?.offset || 0;\n\n // Get distinct turn_ids for this session, ordered by first event timestamp\n const turnRows = sqliteAll<{ turn_id: string; min_ts: string }>(\n this.db,\n `SELECT turn_id, MIN(timestamp) as min_ts\n FROM events\n WHERE session_id = ? AND turn_id IS NOT NULL\n GROUP BY turn_id\n ORDER BY min_ts DESC\n LIMIT ? OFFSET ?`,\n [sessionId, limit, offset]\n );\n\n const turns: Array<{\n turnId: string;\n events: MemoryEvent[];\n startedAt: Date;\n promptPreview: string;\n eventCount: number;\n toolCount: number;\n hasResponse: boolean;\n }> = [];\n\n for (const turnRow of turnRows) {\n const events = await this.getEventsByTurn(turnRow.turn_id);\n\n const promptEvent = events.find(e => e.eventType === 'user_prompt');\n const toolEvents = events.filter(e => e.eventType === 'tool_observation');\n const hasResponse = events.some(e => e.eventType === 'agent_response');\n\n turns.push({\n turnId: turnRow.turn_id,\n events,\n startedAt: toDateFromSQLite(turnRow.min_ts),\n promptPreview: promptEvent\n ? promptEvent.content.slice(0, 200) + (promptEvent.content.length > 200 ? '...' : '')\n : '(no prompt)',\n eventCount: events.length,\n toolCount: toolEvents.length,\n hasResponse\n });\n }\n\n return turns;\n }\n\n /**\n * Get all events for a specific turn_id\n */\n async getEventsByTurn(turnId: string): Promise<MemoryEvent[]> {\n await this.initialize();\n\n const rows = sqliteAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM events WHERE turn_id = ? ORDER BY timestamp ASC`,\n [turnId]\n );\n\n return rows.map(this.rowToEvent);\n }\n\n /**\n * Count total turns for a session\n */\n async countSessionTurns(sessionId: string): Promise<number> {\n await this.initialize();\n\n const row = sqliteGet<{ count: number }>(\n this.db,\n `SELECT COUNT(DISTINCT turn_id) as count\n FROM events\n WHERE session_id = ? AND turn_id IS NOT NULL`,\n [sessionId]\n );\n\n return row?.count || 0;\n }\n\n /**\n * Migrate existing events: backfill turn_id for events that have turnId in metadata\n * but no turn_id column value (for events stored before this migration)\n */\n async backfillTurnIds(): Promise<number> {\n await this.initialize();\n\n // Find events with turnId in metadata JSON but no turn_id column value\n const rows = sqliteAll<{ id: string; metadata: string }>(\n this.db,\n `SELECT id, metadata FROM events\n WHERE turn_id IS NULL AND metadata IS NOT NULL AND metadata LIKE '%turnId%'`\n );\n\n let updated = 0;\n for (const row of rows) {\n try {\n const metadata = JSON.parse(row.metadata);\n if (metadata.turnId) {\n sqliteRun(\n this.db,\n `UPDATE events SET turn_id = ? WHERE id = ?`,\n [metadata.turnId, row.id]\n );\n updated++;\n }\n } catch {\n // Skip rows with invalid JSON\n }\n }\n\n return updated;\n }\n\n /**\n * Delete all events for a session (for force reimport)\n */\n async deleteSessionEvents(sessionId: string): Promise<number> {\n await this.initialize();\n\n // Get event IDs first for cascading deletes\n const events = sqliteAll<{ id: string }>(\n this.db,\n `SELECT id FROM events WHERE session_id = ?`,\n [sessionId]\n );\n\n if (events.length === 0) return 0;\n\n const eventIds = events.map(e => e.id);\n const placeholders = eventIds.map(() => '?').join(',');\n\n // Drop FTS triggers to prevent SQLITE_CORRUPT_VTAB during bulk delete\n const ftsTriggersDropped: string[] = [];\n for (const triggerName of ['events_fts_delete', 'events_fts_update', 'events_fts_insert']) {\n try {\n sqliteRun(this.db, `DROP TRIGGER IF EXISTS ${triggerName}`);\n ftsTriggersDropped.push(triggerName);\n } catch {\n // Trigger may not exist\n }\n }\n\n // Delete from related tables first (some may not exist depending on DB version)\n for (const table of ['event_dedup', 'memory_levels', 'embedding_queue', 'embedding_outbox', 'vector_outbox']) {\n try {\n sqliteRun(this.db, `DELETE FROM ${table} WHERE event_id IN (${placeholders})`, eventIds);\n } catch {\n // Table may not exist\n }\n }\n\n // Delete events\n const result = sqliteRun(this.db, `DELETE FROM events WHERE session_id = ?`, [sessionId]);\n\n // Rebuild FTS index if we dropped triggers\n if (ftsTriggersDropped.length > 0) {\n try {\n // Rebuild FTS from remaining events\n sqliteRun(this.db, `INSERT INTO events_fts(events_fts) VALUES('rebuild')`);\n\n // Recreate triggers\n sqliteRun(this.db, `CREATE TRIGGER IF NOT EXISTS events_fts_insert AFTER INSERT ON events BEGIN\n INSERT INTO events_fts(rowid, content) VALUES (NEW.rowid, NEW.content);\n END`);\n sqliteRun(this.db, `CREATE TRIGGER IF NOT EXISTS events_fts_delete AFTER DELETE ON events BEGIN\n INSERT INTO events_fts(events_fts, rowid, content) VALUES('delete', OLD.rowid, OLD.content);\n END`);\n sqliteRun(this.db, `CREATE TRIGGER IF NOT EXISTS events_fts_update AFTER UPDATE ON events BEGIN\n INSERT INTO events_fts(events_fts, rowid, content) VALUES('delete', OLD.rowid, OLD.content);\n INSERT INTO events_fts(rowid, content) VALUES (NEW.rowid, NEW.content);\n END`);\n } catch {\n // FTS rebuild failed - non-critical, will be rebuilt on next initialize\n }\n }\n\n return result.changes || 0;\n }\n\n /**\n * Convert database row to MemoryEvent\n */\n private rowToEvent(row: Record<string, unknown>): MemoryEvent {\n const event: any = {\n id: row.id as string,\n eventType: row.event_type as 'user_prompt' | 'agent_response' | 'session_summary',\n sessionId: row.session_id as string,\n timestamp: toDateFromSQLite(row.timestamp),\n content: row.content as string,\n canonicalKey: row.canonical_key as string,\n dedupeKey: row.dedupe_key as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined\n };\n\n // Include access tracking fields if present\n if (row.access_count !== undefined) {\n event.access_count = row.access_count;\n }\n if (row.last_accessed_at !== undefined) {\n event.last_accessed_at = row.last_accessed_at;\n }\n // Include turn_id if present\n if (row.turn_id !== undefined && row.turn_id !== null) {\n event.turn_id = row.turn_id;\n }\n\n return event;\n }\n}\n", "/**\n * SQLite Wrapper with WAL Mode Support\n * Primary store for hooks - always available, no lock conflicts\n */\n\nimport Database from 'better-sqlite3';\nimport * as fs from 'fs';\nimport * as nodePath from 'path';\n\nexport type SQLiteDatabase = Database.Database;\n\nexport interface SQLiteOptions {\n readonly?: boolean;\n walMode?: boolean;\n}\n\n/**\n * Creates a new SQLite database with WAL mode\n */\nexport function createSQLiteDatabase(path: string, options?: SQLiteOptions): SQLiteDatabase {\n // Ensure parent directory exists\n const dir = nodePath.dirname(path);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n const db = new Database(path, {\n readonly: options?.readonly ?? false,\n });\n\n // Enable WAL mode for concurrent access (unless read-only)\n if (!options?.readonly && (options?.walMode ?? true)) {\n db.pragma('journal_mode = WAL');\n db.pragma('synchronous = NORMAL');\n db.pragma('busy_timeout = 5000');\n }\n\n return db;\n}\n\n/**\n * Execute a statement that doesn't return rows (INSERT, UPDATE, DELETE)\n */\nexport function sqliteRun(\n db: SQLiteDatabase,\n sql: string,\n params: unknown[] = []\n): Database.RunResult {\n const stmt = db.prepare(sql);\n return stmt.run(...params);\n}\n\n/**\n * Execute a query and return all rows\n */\nexport function sqliteAll<T = Record<string, unknown>>(\n db: SQLiteDatabase,\n sql: string,\n params: unknown[] = []\n): T[] {\n const stmt = db.prepare(sql);\n return stmt.all(...params) as T[];\n}\n\n/**\n * Execute a query and return first row\n */\nexport function sqliteGet<T = Record<string, unknown>>(\n db: SQLiteDatabase,\n sql: string,\n params: unknown[] = []\n): T | undefined {\n const stmt = db.prepare(sql);\n return stmt.get(...params) as T | undefined;\n}\n\n/**\n * Execute multiple statements (for schema creation)\n */\nexport function sqliteExec(db: SQLiteDatabase, sql: string): void {\n db.exec(sql);\n}\n\n/**\n * Close database connection\n */\nexport function sqliteClose(db: SQLiteDatabase): void {\n db.close();\n}\n\n/**\n * Run multiple statements in a transaction\n */\nexport function sqliteTransaction<T>(\n db: SQLiteDatabase,\n fn: () => T\n): T {\n return db.transaction(fn)();\n}\n\n/**\n * Safely converts a value to a Date object\n */\nexport function toDateFromSQLite(value: unknown): Date {\n if (value instanceof Date) return value;\n if (typeof value === 'string') return new Date(value);\n if (typeof value === 'number') return new Date(value);\n return new Date(String(value));\n}\n\n/**\n * Convert Date to ISO string for SQLite storage\n */\nexport function toSQLiteTimestamp(date: Date): string {\n return date.toISOString();\n}\n", "import * as fs from 'fs/promises';\nimport * as path from 'path';\nimport type { MemoryEvent } from './types.js';\n\nconst DEFAULT_NAMESPACE = 'default';\nconst DEFAULT_CATEGORY = 'uncategorized';\n\nexport function sanitizeSegment(input: unknown, fallback: string): string {\n const raw = String(input ?? '').trim().toLowerCase();\n const safe = raw\n .normalize('NFKD')\n .replace(/[^a-z0-9_-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n if (!safe || safe === '.' || safe === '..') return fallback;\n return safe;\n}\n\nfunction getCategorySegments(metadata: Record<string, unknown> | undefined, eventType: string): string[] {\n const raw = metadata?.categoryPath;\n if (Array.isArray(raw) && raw.length > 0) {\n return raw.map((s) => sanitizeSegment(s, DEFAULT_CATEGORY));\n }\n const single = metadata?.category;\n if (typeof single === 'string' && single.trim()) {\n return [sanitizeSegment(single, DEFAULT_CATEGORY)];\n }\n return [sanitizeSegment(eventType, DEFAULT_CATEGORY)];\n}\n\nexport function buildMirrorPath(rootDir: string, event: MemoryEvent): string {\n const metadata = event.metadata as Record<string, unknown> | undefined;\n const namespace = sanitizeSegment(metadata?.namespace, DEFAULT_NAMESPACE);\n const categories = getCategorySegments(metadata, event.eventType);\n\n const d = event.timestamp;\n const yyyy = d.getFullYear();\n const mm = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n\n return path.join(rootDir, 'memory', namespace, ...categories, `${yyyy}-${mm}-${dd}.md`);\n}\n\nexport function formatMirrorEntry(event: MemoryEvent): string {\n const category = Array.isArray((event.metadata as any)?.categoryPath)\n ? ((event.metadata as any).categoryPath as unknown[]).join('/')\n : String((event.metadata as any)?.category ?? event.eventType);\n\n return [\n '',\n `- ts: ${event.timestamp.toISOString()}`,\n ` id: ${event.id}`,\n ` type: ${event.eventType}`,\n ` session: ${event.sessionId}`,\n ` category: ${category}`,\n ' content: |',\n ...event.content.split('\\n').map((line) => ` ${line}`)\n ].join('\\n') + '\\n';\n}\n\nexport class MarkdownMirror {\n constructor(private readonly rootDir: string) {}\n\n async append(event: MemoryEvent): Promise<string> {\n const outPath = buildMirrorPath(this.rootDir, event);\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.appendFile(outPath, formatMirrorEntry(event), 'utf8');\n return outPath;\n }\n}\n", "/**\n * Sync Worker - SQLite to DuckDB synchronization\n * Runs periodically to sync primary store (SQLite) to analytics store (DuckDB)\n */\n\nimport { SQLiteEventStore } from './sqlite-event-store.js';\nimport { EventStore } from './event-store.js';\nimport { MemoryEvent } from './types.js';\n\nexport interface SyncWorkerConfig {\n intervalMs: number; // Sync interval (default: 30000 = 30 seconds)\n batchSize: number; // Events per batch (default: 500)\n maxRetries: number; // Max retries on failure (default: 3)\n retryDelayMs: number; // Delay between retries (default: 5000)\n}\n\nconst DEFAULT_CONFIG: SyncWorkerConfig = {\n intervalMs: 30000,\n batchSize: 500,\n maxRetries: 3,\n retryDelayMs: 5000\n};\n\nexport interface SyncStats {\n lastSyncAt: Date | null;\n eventsSynced: number;\n sessionsSynced: number;\n errors: number;\n status: 'idle' | 'syncing' | 'error' | 'stopped';\n}\n\nexport class SyncWorker {\n private config: SyncWorkerConfig;\n private intervalHandle: NodeJS.Timeout | null = null;\n private running = false;\n private stats: SyncStats = {\n lastSyncAt: null,\n eventsSynced: 0,\n sessionsSynced: 0,\n errors: 0,\n status: 'idle'\n };\n\n constructor(\n private sqliteStore: SQLiteEventStore,\n private duckdbStore: EventStore,\n config?: Partial<SyncWorkerConfig>\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Start the sync worker\n */\n start(): void {\n if (this.running) return;\n\n this.running = true;\n this.stats.status = 'idle';\n\n // Run initial sync\n this.syncNow().catch(err => {\n console.error('[SyncWorker] Initial sync failed:', err);\n });\n\n // Schedule periodic sync\n this.intervalHandle = setInterval(() => {\n this.syncNow().catch(err => {\n console.error('[SyncWorker] Periodic sync failed:', err);\n });\n }, this.config.intervalMs);\n }\n\n /**\n * Stop the sync worker\n */\n stop(): void {\n this.running = false;\n this.stats.status = 'stopped';\n\n if (this.intervalHandle) {\n clearInterval(this.intervalHandle);\n this.intervalHandle = null;\n }\n }\n\n /**\n * Trigger immediate sync\n */\n async syncNow(): Promise<void> {\n if (this.stats.status === 'syncing') {\n return; // Already syncing\n }\n\n this.stats.status = 'syncing';\n\n try {\n await this.syncEvents();\n await this.syncSessions();\n this.stats.lastSyncAt = new Date();\n this.stats.status = 'idle';\n } catch (error) {\n this.stats.errors++;\n this.stats.status = 'error';\n throw error;\n }\n }\n\n /**\n * Sync events from SQLite to DuckDB\n */\n private async syncEvents(): Promise<void> {\n const targetName = 'duckdb_analytics';\n\n // Get last sync position from SQLite\n const position = await this.sqliteStore.getSyncPosition(targetName);\n const lastTimestamp = position.lastTimestamp || '1970-01-01T00:00:00.000Z';\n\n let hasMore = true;\n let totalSynced = 0;\n\n while (hasMore) {\n // Get batch of events since last sync\n const events = await this.sqliteStore.getEventsSince(lastTimestamp, this.config.batchSize);\n\n if (events.length === 0) {\n hasMore = false;\n break;\n }\n\n // Insert into DuckDB with retry\n await this.retryWithBackoff(async () => {\n for (const event of events) {\n await this.insertEventToDuckDB(event);\n }\n });\n\n totalSynced += events.length;\n\n // Update sync position\n const lastEvent = events[events.length - 1];\n await this.sqliteStore.updateSyncPosition(\n targetName,\n lastEvent.id,\n lastEvent.timestamp.toISOString()\n );\n\n // Check if we got a full batch (more to sync)\n hasMore = events.length === this.config.batchSize;\n }\n\n this.stats.eventsSynced += totalSynced;\n }\n\n /**\n * Sync sessions from SQLite to DuckDB\n */\n private async syncSessions(): Promise<void> {\n // Get all sessions from SQLite\n const sessions = await this.sqliteStore.getAllSessions();\n\n // Upsert each session to DuckDB\n for (const session of sessions) {\n await this.retryWithBackoff(async () => {\n await this.duckdbStore.upsertSession(session);\n });\n }\n\n this.stats.sessionsSynced = sessions.length;\n }\n\n /**\n * Insert a single event into DuckDB\n */\n private async insertEventToDuckDB(event: MemoryEvent): Promise<void> {\n // Use append which handles deduplication\n await this.duckdbStore.append({\n eventType: event.eventType,\n sessionId: event.sessionId,\n timestamp: event.timestamp,\n content: event.content,\n metadata: event.metadata\n });\n }\n\n /**\n * Retry operation with exponential backoff\n */\n private async retryWithBackoff<T>(fn: () => Promise<T>): Promise<T> {\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt < this.config.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt < this.config.maxRetries - 1) {\n const delay = this.config.retryDelayMs * Math.pow(2, attempt);\n await this.sleep(delay);\n }\n }\n }\n\n throw lastError;\n }\n\n /**\n * Sleep utility\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n /**\n * Get sync statistics\n */\n getStats(): SyncStats {\n return { ...this.stats };\n }\n\n /**\n * Check if worker is running\n */\n isRunning(): boolean {\n return this.running;\n }\n}\n", "/**\n * LanceDB Vector Store for semantic search\n * AXIOMMIND Principle 6: Vector store consistency (DuckDB \u2192 outbox \u2192 LanceDB unidirectional)\n */\n\nimport * as lancedb from '@lancedb/lancedb';\nimport type { VectorRecord } from './types.js';\n\nexport interface SearchResult {\n id: string;\n eventId: string;\n content: string;\n score: number;\n sessionId: string;\n eventType: string;\n timestamp: string;\n}\n\nexport class VectorStore {\n private db: lancedb.Connection | null = null;\n private table: lancedb.Table | null = null;\n private readonly tableName = 'conversations';\n\n constructor(private dbPath: string) {}\n\n /**\n * Initialize LanceDB connection\n */\n async initialize(): Promise<void> {\n if (this.db) return;\n\n this.db = await lancedb.connect(this.dbPath);\n\n // Try to open existing table\n try {\n const tables = await this.db.tableNames();\n if (tables.includes(this.tableName)) {\n this.table = await this.db.openTable(this.tableName);\n }\n } catch {\n // Table doesn't exist yet, will be created on first insert\n this.table = null;\n }\n }\n\n /**\n * Add or update vector record\n */\n async upsert(record: VectorRecord): Promise<void> {\n await this.initialize();\n\n if (!this.db) {\n throw new Error('Database not initialized');\n }\n\n const data = {\n id: record.id,\n eventId: record.eventId,\n sessionId: record.sessionId,\n eventType: record.eventType,\n content: record.content,\n vector: record.vector,\n timestamp: record.timestamp,\n metadata: JSON.stringify(record.metadata || {})\n };\n\n if (!this.table) {\n // Create table with first record (handle race condition)\n try {\n this.table = await this.db.createTable(this.tableName, [data]);\n } catch (e: any) {\n if (e?.message?.includes('already exists')) {\n this.table = await this.db.openTable(this.tableName);\n await this.table.add([data]);\n } else {\n throw e;\n }\n }\n } else {\n await this.table.add([data]);\n }\n }\n\n /**\n * Add multiple vector records in batch\n */\n async upsertBatch(records: VectorRecord[]): Promise<void> {\n if (records.length === 0) return;\n\n await this.initialize();\n\n if (!this.db) {\n throw new Error('Database not initialized');\n }\n\n const data = records.map(record => ({\n id: record.id,\n eventId: record.eventId,\n sessionId: record.sessionId,\n eventType: record.eventType,\n content: record.content,\n vector: record.vector,\n timestamp: record.timestamp,\n metadata: JSON.stringify(record.metadata || {})\n }));\n\n if (!this.table) {\n try {\n this.table = await this.db.createTable(this.tableName, data);\n } catch (e: any) {\n if (e?.message?.includes('already exists')) {\n this.table = await this.db.openTable(this.tableName);\n await this.table.add(data);\n } else {\n throw e;\n }\n }\n } else {\n await this.table.add(data);\n }\n }\n\n /**\n * Search for similar vectors\n */\n async search(\n queryVector: number[],\n options: {\n limit?: number;\n minScore?: number;\n sessionId?: string;\n } = {}\n ): Promise<SearchResult[]> {\n await this.initialize();\n\n if (!this.table) {\n return [];\n }\n\n const { limit = 5, minScore = 0.7, sessionId } = options;\n\n // Use cosine distance for semantic similarity\n let query = this.table\n .search(queryVector)\n .distanceType('cosine')\n .limit(limit * 2); // Get more for filtering\n\n // Apply session filter if specified\n if (sessionId) {\n query = query.where(`sessionId = '${sessionId}'`);\n }\n\n const results = await query.toArray();\n\n return results\n .filter(r => {\n // Convert cosine distance to similarity score\n // Cosine distance ranges from 0 (identical) to 2 (opposite)\n // Score = 1 - (distance / 2) gives range [0, 1]\n const distance = r._distance || 0;\n const score = 1 - (distance / 2);\n return score >= minScore;\n })\n .slice(0, limit)\n .map(r => {\n const distance = r._distance || 0;\n const score = 1 - (distance / 2);\n return {\n id: r.id as string,\n eventId: r.eventId as string,\n content: r.content as string,\n score,\n sessionId: r.sessionId as string,\n eventType: r.eventType as string,\n timestamp: r.timestamp as string\n };\n });\n }\n\n /**\n * Delete vector by event ID\n */\n async delete(eventId: string): Promise<void> {\n if (!this.table) return;\n await this.table.delete(`eventId = '${eventId}'`);\n }\n\n /**\n * Get total count of vectors\n */\n async count(): Promise<number> {\n if (!this.table) return 0;\n const result = await this.table.countRows();\n return result;\n }\n\n /**\n * Clear all vectors (used for embedding model migration)\n */\n async clearAll(): Promise<void> {\n await this.initialize();\n if (!this.db) return;\n\n try {\n if (typeof (this.db as any).dropTable === 'function') {\n await (this.db as any).dropTable(this.tableName);\n } else if (typeof (this.db as any).drop_table === 'function') {\n await (this.db as any).drop_table(this.tableName);\n }\n } catch {\n // Ignore if table does not exist\n }\n\n this.table = null;\n }\n\n /**\n * Check if vector exists for event\n */\n async exists(eventId: string): Promise<boolean> {\n if (!this.table) return false;\n\n const results = await this.table\n .search([])\n .where(`eventId = '${eventId}'`)\n .limit(1)\n .toArray();\n\n return results.length > 0;\n }\n}\n", "/**\n * Local Embedding Generator using @xenova/transformers\n * AXIOMMIND Principle 7: Standard JSON format for vectors\n */\n\nimport { pipeline, Pipeline } from '@huggingface/transformers';\n\nexport interface EmbeddingResult {\n vector: number[];\n model: string;\n dimensions: number;\n}\n\nexport class Embedder {\n private pipeline: Pipeline | null = null;\n private readonly modelName: string;\n private activeModelName: string;\n private initialized = false;\n\n constructor(modelName: string = 'jinaai/jina-embeddings-v5-text-nano-text-matching') {\n this.modelName = modelName;\n this.activeModelName = modelName;\n }\n\n /**\n * Initialize the embedding pipeline\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n try {\n this.pipeline = await pipeline('feature-extraction', this.modelName);\n this.activeModelName = this.modelName;\n this.initialized = true;\n return;\n } catch (primaryError) {\n const fallbackModel = process.env.CLAUDE_MEMORY_EMBEDDING_FALLBACK_MODEL || 'onnx-community/embeddinggemma-300m-ONNX';\n if (fallbackModel === this.modelName) {\n throw primaryError;\n }\n\n console.warn(`[Embedder] Primary model failed (${this.modelName}). Falling back to ${fallbackModel}`);\n this.pipeline = await pipeline('feature-extraction', fallbackModel);\n this.activeModelName = fallbackModel;\n this.initialized = true;\n }\n }\n\n // ~4 chars per token; 512 tokens * 4 = 2048, use 2000 to be safe\n private static readonly MAX_CHARS = 2000;\n\n private truncate(text: string): string {\n return text.length > Embedder.MAX_CHARS ? text.slice(0, Embedder.MAX_CHARS) : text;\n }\n\n /**\n * Generate embedding for a single text\n */\n async embed(text: string): Promise<EmbeddingResult> {\n await this.initialize();\n\n if (!this.pipeline) {\n throw new Error('Embedding pipeline not initialized');\n }\n\n const output = await this.pipeline(this.truncate(text), {\n pooling: 'mean',\n normalize: true,\n truncation: true,\n max_length: 512\n });\n\n const vector = Array.from(output.data as Float32Array);\n\n return {\n vector,\n model: this.activeModelName,\n dimensions: vector.length\n };\n }\n\n /**\n * Generate embeddings for multiple texts in batch\n */\n async embedBatch(texts: string[]): Promise<EmbeddingResult[]> {\n await this.initialize();\n\n if (!this.pipeline) {\n throw new Error('Embedding pipeline not initialized');\n }\n\n const results: EmbeddingResult[] = [];\n\n // Process in batches of 32 for memory efficiency\n const batchSize = 32;\n for (let i = 0; i < texts.length; i += batchSize) {\n const batch = texts.slice(i, i + batchSize);\n\n for (const text of batch) {\n const output = await this.pipeline(this.truncate(text), {\n pooling: 'mean',\n normalize: true,\n truncation: true,\n max_length: 512\n });\n\n const vector = Array.from(output.data as Float32Array);\n\n results.push({\n vector,\n model: this.activeModelName,\n dimensions: vector.length\n });\n }\n }\n\n return results;\n }\n\n /**\n * Get embedding dimensions for the current model\n */\n async getDimensions(): Promise<number> {\n const result = await this.embed('test');\n return result.dimensions;\n }\n\n /**\n * Check if embedder is ready\n */\n isReady(): boolean {\n return this.initialized && this.pipeline !== null;\n }\n\n /**\n * Get model name\n */\n getModelName(): string {\n return this.activeModelName;\n }\n}\n\n// Singleton instance for reuse\nlet defaultEmbedder: Embedder | null = null;\n\nexport function getDefaultEmbedder(): Embedder {\n const envModel = process.env.CLAUDE_MEMORY_EMBEDDING_MODEL;\n if (!defaultEmbedder) {\n defaultEmbedder = new Embedder(envModel || undefined);\n }\n return defaultEmbedder;\n}\n", "/**\n * Vector Outbox V2 - Transactional Outbox Pattern\n * AXIOMMIND Principle 6: DuckDB \u2192 outbox \u2192 LanceDB unidirectional flow\n */\n\nimport { dbRun, dbAll, toDate, type Database } from './db-wrapper.js';\nimport { randomUUID } from 'crypto';\nimport type {\n OutboxJob,\n OutboxStatus,\n OutboxItemKind,\n VALID_OUTBOX_TRANSITIONS\n} from './types.js';\n\nexport interface OutboxConfig {\n embeddingVersion: string;\n maxRetries: number;\n stuckThresholdMs: number;\n cleanupDays: number;\n}\n\nconst DEFAULT_CONFIG: OutboxConfig = {\n embeddingVersion: 'v1',\n maxRetries: 3,\n stuckThresholdMs: 5 * 60 * 1000, // 5 minutes\n cleanupDays: 7\n};\n\nexport interface OutboxMetrics {\n pendingCount: number;\n processingCount: number;\n doneCount: number;\n failedCount: number;\n oldestPendingAge: number | null;\n}\n\nexport class VectorOutbox {\n private config: OutboxConfig;\n\n constructor(\n private db: Database,\n config?: Partial<OutboxConfig>\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Enqueue item for vectorization (idempotent)\n */\n async enqueue(\n itemKind: OutboxItemKind,\n itemId: string,\n embeddingVersion?: string\n ): Promise<string> {\n const version = embeddingVersion ?? this.config.embeddingVersion;\n const jobId = randomUUID();\n const now = new Date().toISOString();\n\n await dbRun(\n this.db,\n `INSERT INTO vector_outbox (\n job_id, item_kind, item_id, embedding_version, status, retry_count, created_at, updated_at\n ) VALUES (?, ?, ?, ?, 'pending', 0, ?, ?)\n ON CONFLICT (item_kind, item_id, embedding_version) DO NOTHING`,\n [jobId, itemKind, itemId, version, now, now]\n );\n\n return jobId;\n }\n\n /**\n * Claim pending jobs for processing\n */\n async claimJobs(limit: number = 32): Promise<OutboxJob[]> {\n const now = new Date().toISOString();\n\n // Atomic claim using UPDATE RETURNING\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `UPDATE vector_outbox\n SET status = 'processing', updated_at = ?\n WHERE job_id IN (\n SELECT job_id FROM vector_outbox\n WHERE status = 'pending'\n ORDER BY created_at ASC\n LIMIT ?\n )\n RETURNING *`,\n [now, limit]\n );\n\n return rows.map(row => this.rowToJob(row));\n }\n\n /**\n * Mark job as done\n */\n async markDone(jobId: string): Promise<void> {\n await dbRun(\n this.db,\n `UPDATE vector_outbox\n SET status = 'done', updated_at = ?\n WHERE job_id = ?`,\n [new Date().toISOString(), jobId]\n );\n }\n\n /**\n * Mark job as failed\n */\n async markFailed(jobId: string, error: string): Promise<void> {\n const now = new Date().toISOString();\n\n // Check retry count\n const rows = await dbAll<{ retry_count: number }>(\n this.db,\n `SELECT retry_count FROM vector_outbox WHERE job_id = ?`,\n [jobId]\n );\n\n if (rows.length === 0) return;\n\n const retryCount = rows[0].retry_count;\n const newStatus: OutboxStatus = retryCount >= this.config.maxRetries - 1\n ? 'failed'\n : 'pending'; // Will retry\n\n await dbRun(\n this.db,\n `UPDATE vector_outbox\n SET status = ?, error = ?, retry_count = retry_count + 1, updated_at = ?\n WHERE job_id = ?`,\n [newStatus, error, now, jobId]\n );\n }\n\n /**\n * Get job by ID\n */\n async getJob(jobId: string): Promise<OutboxJob | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM vector_outbox WHERE job_id = ?`,\n [jobId]\n );\n\n if (rows.length === 0) return null;\n return this.rowToJob(rows[0]);\n }\n\n /**\n * Get jobs by status\n */\n async getJobsByStatus(status: OutboxStatus, limit: number = 100): Promise<OutboxJob[]> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM vector_outbox\n WHERE status = ?\n ORDER BY created_at ASC\n LIMIT ?`,\n [status, limit]\n );\n\n return rows.map(row => this.rowToJob(row));\n }\n\n /**\n * Reconcile: recover stuck and retry failed jobs\n */\n async reconcile(): Promise<{ recovered: number; retried: number }> {\n const now = new Date();\n const stuckThreshold = new Date(now.getTime() - this.config.stuckThresholdMs);\n\n // Recover stuck processing jobs\n await dbRun(\n this.db,\n `UPDATE vector_outbox\n SET status = 'pending', updated_at = ?\n WHERE status = 'processing'\n AND updated_at < ?`,\n [now.toISOString(), stuckThreshold.toISOString()]\n );\n\n // Retry failed jobs that haven't exceeded max retries\n await dbRun(\n this.db,\n `UPDATE vector_outbox\n SET status = 'pending', updated_at = ?\n WHERE status = 'failed'\n AND retry_count < ?`,\n [now.toISOString(), this.config.maxRetries]\n );\n\n // Get counts (DuckDB doesn't return affected rows easily)\n const recoveredRows = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM vector_outbox\n WHERE status = 'pending' AND updated_at = ?`,\n [now.toISOString()]\n );\n\n return {\n recovered: 0, // Approximate\n retried: 0 // Approximate\n };\n }\n\n /**\n * Cleanup old done jobs\n */\n async cleanup(): Promise<number> {\n const threshold = new Date();\n threshold.setDate(threshold.getDate() - this.config.cleanupDays);\n\n await dbRun(\n this.db,\n `DELETE FROM vector_outbox\n WHERE status = 'done'\n AND updated_at < ?`,\n [threshold.toISOString()]\n );\n\n return 0; // DuckDB doesn't return affected rows easily\n }\n\n /**\n * Get metrics\n */\n async getMetrics(): Promise<OutboxMetrics> {\n const statusCounts = await dbAll<{ status: string; count: number }>(\n this.db,\n `SELECT status, COUNT(*) as count\n FROM vector_outbox\n GROUP BY status`\n );\n\n const oldestPending = await dbAll<{ created_at: string }>(\n this.db,\n `SELECT created_at FROM vector_outbox\n WHERE status = 'pending'\n ORDER BY created_at ASC\n LIMIT 1`\n );\n\n const metrics: OutboxMetrics = {\n pendingCount: 0,\n processingCount: 0,\n doneCount: 0,\n failedCount: 0,\n oldestPendingAge: null\n };\n\n for (const row of statusCounts) {\n switch (row.status) {\n case 'pending':\n metrics.pendingCount = Number(row.count);\n break;\n case 'processing':\n metrics.processingCount = Number(row.count);\n break;\n case 'done':\n metrics.doneCount = Number(row.count);\n break;\n case 'failed':\n metrics.failedCount = Number(row.count);\n break;\n }\n }\n\n if (oldestPending.length > 0) {\n const oldestDate = new Date(oldestPending[0].created_at);\n metrics.oldestPendingAge = Date.now() - oldestDate.getTime();\n }\n\n return metrics;\n }\n\n /**\n * Validate state transition\n */\n isValidTransition(from: OutboxStatus, to: OutboxStatus): boolean {\n const validTransitions = [\n { from: 'pending', to: 'processing' },\n { from: 'processing', to: 'done' },\n { from: 'processing', to: 'failed' },\n { from: 'failed', to: 'pending' }\n ];\n\n return validTransitions.some(t => t.from === from && t.to === to);\n }\n\n /**\n * Convert database row to OutboxJob\n */\n private rowToJob(row: Record<string, unknown>): OutboxJob {\n return {\n jobId: row.job_id as string,\n itemKind: row.item_kind as OutboxItemKind,\n itemId: row.item_id as string,\n embeddingVersion: row.embedding_version as string,\n status: row.status as OutboxStatus,\n retryCount: row.retry_count as number,\n error: row.error as string | undefined,\n createdAt: toDate(row.created_at),\n updatedAt: toDate(row.updated_at)\n };\n }\n}\n", "/**\n * Vector Worker - Single-Writer Pattern Implementation\n * AXIOMMIND Principle 6: DuckDB \u2192 outbox \u2192 LanceDB unidirectional flow\n */\n\nimport { EventStore } from './event-store.js';\nimport { VectorStore } from './vector-store.js';\nimport { Embedder } from './embedder.js';\nimport type { OutboxItem, VectorRecord } from './types.js';\n\nexport interface WorkerConfig {\n batchSize: number;\n pollIntervalMs: number;\n maxRetries: number;\n}\n\nconst DEFAULT_CONFIG: WorkerConfig = {\n batchSize: 32,\n pollIntervalMs: 1000,\n maxRetries: 3\n};\n\nexport class VectorWorker {\n private readonly eventStore: EventStore;\n private readonly vectorStore: VectorStore;\n private readonly embedder: Embedder;\n private readonly config: WorkerConfig;\n private running = false;\n private stopping = false;\n private pollTimeout: NodeJS.Timeout | null = null;\n\n constructor(\n eventStore: EventStore,\n vectorStore: VectorStore,\n embedder: Embedder,\n config: Partial<WorkerConfig> = {}\n ) {\n this.eventStore = eventStore;\n this.vectorStore = vectorStore;\n this.embedder = embedder;\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Start the worker polling loop\n */\n start(): void {\n if (this.running) return;\n this.running = true;\n this.stopping = false;\n this.poll();\n }\n\n /**\n * Stop the worker\n */\n stop(): void {\n this.running = false;\n this.stopping = true;\n if (this.pollTimeout) {\n clearTimeout(this.pollTimeout);\n this.pollTimeout = null;\n }\n }\n\n /**\n * Process a single batch of outbox items\n */\n async processBatch(): Promise<number> {\n const items = await this.eventStore.getPendingOutboxItems(this.config.batchSize);\n\n if (items.length === 0) {\n return 0;\n }\n\n const successful: string[] = [];\n const failed: string[] = [];\n\n try {\n // Generate embeddings for all items\n const embeddings = await this.embedder.embedBatch(items.map(i => i.content));\n\n // Prepare vector records\n const records: VectorRecord[] = [];\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const embedding = embeddings[i];\n\n // Get event details\n const event = await this.eventStore.getEvent(item.eventId);\n if (!event) {\n failed.push(item.id);\n continue;\n }\n\n records.push({\n id: `vec_${item.id}`,\n eventId: item.eventId,\n sessionId: event.sessionId,\n eventType: event.eventType,\n content: item.content,\n vector: embedding.vector,\n timestamp: event.timestamp.toISOString(),\n metadata: event.metadata\n });\n\n successful.push(item.id);\n }\n\n // Batch insert to vector store\n if (records.length > 0) {\n await this.vectorStore.upsertBatch(records);\n }\n\n // Mark successful items as done\n if (successful.length > 0) {\n await this.eventStore.completeOutboxItems(successful);\n }\n\n // Mark failed items\n if (failed.length > 0) {\n await this.eventStore.failOutboxItems(failed, 'Event not found');\n }\n\n return successful.length;\n } catch (error) {\n // Mark all items as failed, but only if not stopping (DB might be closed)\n if (!this.stopping) {\n try {\n const allIds = items.map(i => i.id);\n const errorMessage = error instanceof Error ? error.message : String(error);\n await this.eventStore.failOutboxItems(allIds, errorMessage);\n } catch (failError) {\n // Database might be closed during shutdown, ignore\n console.warn('Could not mark outbox items as failed (database may be closed)');\n }\n }\n throw error;\n }\n }\n\n /**\n * Poll for new items\n */\n private async poll(): Promise<void> {\n if (!this.running || this.stopping) return;\n\n try {\n await this.processBatch();\n } catch (error) {\n // Only log if not stopping (error during shutdown is expected)\n if (!this.stopping) {\n console.error('Vector worker error:', error);\n }\n }\n\n // Schedule next poll only if still running\n if (this.running && !this.stopping) {\n this.pollTimeout = setTimeout(() => this.poll(), this.config.pollIntervalMs);\n }\n }\n\n /**\n * Process all pending items (blocking)\n */\n async processAll(): Promise<number> {\n let totalProcessed = 0;\n let processed: number;\n\n do {\n processed = await this.processBatch();\n totalProcessed += processed;\n } while (processed > 0);\n\n return totalProcessed;\n }\n\n /**\n * Check if worker is running\n */\n isRunning(): boolean {\n return this.running;\n }\n}\n\n/**\n * Create and start a vector worker\n */\nexport function createVectorWorker(\n eventStore: EventStore,\n vectorStore: VectorStore,\n embedder: Embedder,\n config?: Partial<WorkerConfig>\n): VectorWorker {\n const worker = new VectorWorker(eventStore, vectorStore, embedder, config);\n return worker;\n}\n\n// ============================================================\n// Vector Worker V2 - Extended for Task Entity System\n// ============================================================\n\nimport { dbAll, type Database } from './db-wrapper.js';\nimport { VectorOutbox } from './vector-outbox.js';\nimport type { OutboxJob, OutboxItemKind } from './types.js';\n\nexport interface WorkerConfigV2 {\n batchSize: number;\n pollIntervalMs: number;\n maxRetries: number;\n embeddingVersion: string;\n}\n\nconst DEFAULT_CONFIG_V2: WorkerConfigV2 = {\n batchSize: 32,\n pollIntervalMs: 1000,\n maxRetries: 3,\n embeddingVersion: 'v1'\n};\n\n/**\n * Content provider interface for different item kinds\n */\nexport interface ContentProvider {\n getContent(itemKind: OutboxItemKind, itemId: string): Promise<{\n content: string;\n metadata: Record<string, unknown>;\n } | null>;\n}\n\n/**\n * Default content provider using database\n */\nexport class DefaultContentProvider implements ContentProvider {\n constructor(private db: Database) {}\n\n async getContent(itemKind: OutboxItemKind, itemId: string): Promise<{\n content: string;\n metadata: Record<string, unknown>;\n } | null> {\n switch (itemKind) {\n case 'entry':\n return this.getEntryContent(itemId);\n case 'task_title':\n return this.getTaskTitleContent(itemId);\n case 'event':\n return this.getEventContent(itemId);\n default:\n return null;\n }\n }\n\n private async getEntryContent(entryId: string): Promise<{\n content: string;\n metadata: Record<string, unknown>;\n } | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,\n [entryId]\n );\n\n if (rows.length === 0) return null;\n\n const row = rows[0];\n const contentJson = typeof row.content_json === 'string'\n ? JSON.parse(row.content_json)\n : row.content_json;\n\n return {\n content: `${row.title}\\n${JSON.stringify(contentJson)}`,\n metadata: {\n itemKind: 'entry',\n entryType: row.entry_type\n }\n };\n }\n\n private async getTaskTitleContent(taskId: string): Promise<{\n content: string;\n metadata: Record<string, unknown>;\n } | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT title, search_text, current_json FROM entities\n WHERE entity_id = ? AND entity_type = 'task'`,\n [taskId]\n );\n\n if (rows.length === 0) return null;\n\n const row = rows[0];\n return {\n content: row.search_text as string || row.title as string,\n metadata: {\n itemKind: 'task_title',\n entityType: 'task'\n }\n };\n }\n\n private async getEventContent(eventId: string): Promise<{\n content: string;\n metadata: Record<string, unknown>;\n } | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT content, event_type, session_id FROM events WHERE id = ?`,\n [eventId]\n );\n\n if (rows.length === 0) return null;\n\n const row = rows[0];\n return {\n content: row.content as string,\n metadata: {\n itemKind: 'event',\n eventType: row.event_type,\n sessionId: row.session_id\n }\n };\n }\n}\n\n/**\n * Vector Worker V2 - Supports multiple item kinds\n */\nexport class VectorWorkerV2 {\n private readonly outbox: VectorOutbox;\n private readonly vectorStore: VectorStore;\n private readonly embedder: Embedder;\n private readonly contentProvider: ContentProvider;\n private readonly config: WorkerConfigV2;\n private running = false;\n private stopping = false;\n private pollTimeout: NodeJS.Timeout | null = null;\n\n constructor(\n db: Database,\n vectorStore: VectorStore,\n embedder: Embedder,\n config: Partial<WorkerConfigV2> = {},\n contentProvider?: ContentProvider\n ) {\n this.outbox = new VectorOutbox(db, {\n embeddingVersion: config.embeddingVersion ?? DEFAULT_CONFIG_V2.embeddingVersion,\n maxRetries: config.maxRetries ?? DEFAULT_CONFIG_V2.maxRetries\n });\n this.vectorStore = vectorStore;\n this.embedder = embedder;\n this.config = { ...DEFAULT_CONFIG_V2, ...config };\n this.contentProvider = contentProvider ?? new DefaultContentProvider(db);\n }\n\n /**\n * Start the worker polling loop\n */\n start(): void {\n if (this.running) return;\n this.running = true;\n this.stopping = false;\n this.poll();\n }\n\n /**\n * Stop the worker\n */\n stop(): void {\n this.running = false;\n this.stopping = true;\n if (this.pollTimeout) {\n clearTimeout(this.pollTimeout);\n this.pollTimeout = null;\n }\n }\n\n /**\n * Process a single batch of outbox jobs\n */\n async processBatch(): Promise<number> {\n const jobs = await this.outbox.claimJobs(this.config.batchSize);\n\n if (jobs.length === 0) {\n return 0;\n }\n\n let successCount = 0;\n\n for (const job of jobs) {\n try {\n await this.processJob(job);\n await this.outbox.markDone(job.jobId);\n successCount++;\n } catch (error) {\n // Only try to mark as failed if not stopping (DB might be closed)\n if (!this.stopping) {\n try {\n const errorMessage = error instanceof Error ? error.message : String(error);\n await this.outbox.markFailed(job.jobId, errorMessage);\n } catch {\n // Database might be closed during shutdown, ignore\n }\n }\n }\n }\n\n return successCount;\n }\n\n /**\n * Process a single job\n */\n private async processJob(job: OutboxJob): Promise<void> {\n // Get content\n const contentData = await this.contentProvider.getContent(job.itemKind, job.itemId);\n\n if (!contentData) {\n // Item not found, mark as done (skip)\n return;\n }\n\n // Generate embedding\n const embedding = await this.embedder.embed(contentData.content);\n\n // Upsert to vector store\n const record: VectorRecord = {\n id: `${job.itemKind}_${job.itemId}_${job.embeddingVersion}`,\n eventId: job.itemKind === 'event' ? job.itemId : '',\n sessionId: (contentData.metadata.sessionId as string) ?? '',\n eventType: (contentData.metadata.eventType as string) ?? job.itemKind,\n content: contentData.content,\n vector: embedding.vector,\n timestamp: new Date().toISOString(),\n metadata: {\n ...contentData.metadata,\n embeddingVersion: job.embeddingVersion\n }\n };\n\n // Use idempotent upsert (delete + add)\n await this.vectorStore.upsertBatch([record]);\n }\n\n /**\n * Poll for new jobs\n */\n private async poll(): Promise<void> {\n if (!this.running || this.stopping) return;\n\n try {\n await this.processBatch();\n } catch (error) {\n // Only log if not stopping (error during shutdown is expected)\n if (!this.stopping) {\n console.error('Vector worker V2 error:', error);\n }\n }\n\n // Schedule next poll only if still running\n if (this.running && !this.stopping) {\n this.pollTimeout = setTimeout(() => this.poll(), this.config.pollIntervalMs);\n }\n }\n\n /**\n * Process all pending jobs (blocking)\n */\n async processAll(): Promise<number> {\n let totalProcessed = 0;\n let processed: number;\n\n do {\n processed = await this.processBatch();\n totalProcessed += processed;\n } while (processed > 0);\n\n return totalProcessed;\n }\n\n /**\n * Run reconciliation\n */\n async reconcile(): Promise<{ recovered: number; retried: number }> {\n return this.outbox.reconcile();\n }\n\n /**\n * Get metrics\n */\n async getMetrics() {\n return this.outbox.getMetrics();\n }\n\n /**\n * Check if worker is running\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Get the outbox instance for direct access\n */\n getOutbox(): VectorOutbox {\n return this.outbox;\n }\n}\n\n/**\n * Create a Vector Worker V2 instance\n */\nexport function createVectorWorkerV2(\n db: Database,\n vectorStore: VectorStore,\n embedder: Embedder,\n config?: Partial<WorkerConfigV2>\n): VectorWorkerV2 {\n return new VectorWorkerV2(db, vectorStore, embedder, config);\n}\n", "/**\n * AXIOMMIND Matcher - Weighted scoring with confidence classification\n * Implements matching thresholds: high (\u22650.92), suggested (\u22650.75), none (<0.75)\n */\n\nimport type {\n MemoryEvent,\n MemoryMatch,\n MatchResult,\n MatchConfidence,\n MATCH_THRESHOLDS\n} from './types.js';\nimport { SearchResult } from './vector-store.js';\n\nexport interface MatchWeights {\n semanticSimilarity: number;\n ftsScore: number;\n recencyBonus: number;\n statusWeight: number;\n}\n\nexport interface MatcherConfig {\n weights: MatchWeights;\n minCombinedScore: number;\n minGap: number;\n suggestionThreshold: number;\n}\n\nconst DEFAULT_CONFIG: MatcherConfig = {\n weights: {\n semanticSimilarity: 0.4,\n ftsScore: 0.25,\n recencyBonus: 0.2,\n statusWeight: 0.15\n },\n minCombinedScore: 0.92,\n minGap: 0.03,\n suggestionThreshold: 0.75\n};\n\nexport class Matcher {\n private readonly config: MatcherConfig;\n\n constructor(config: Partial<MatcherConfig> = {}) {\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n weights: { ...DEFAULT_CONFIG.weights, ...config.weights }\n };\n }\n\n /**\n * Calculate combined score using AXIOMMIND weighted formula\n */\n calculateCombinedScore(\n semanticScore: number,\n ftsScore: number = 0,\n recencyDays: number = 0,\n isActive: boolean = true\n ): number {\n const { weights } = this.config;\n\n // Recency bonus: decays over 30 days\n const recencyBonus = Math.max(0, 1 - recencyDays / 30);\n\n // Status weight: active events get full weight\n const statusMultiplier = isActive ? 1.0 : 0.7;\n\n const combinedScore =\n weights.semanticSimilarity * semanticScore +\n weights.ftsScore * ftsScore +\n weights.recencyBonus * recencyBonus +\n weights.statusWeight * statusMultiplier;\n\n return Math.min(1.0, combinedScore);\n }\n\n /**\n * Classify match confidence based on AXIOMMIND thresholds\n */\n classifyConfidence(\n topScore: number,\n secondScore: number | null\n ): MatchConfidence {\n const { minCombinedScore, minGap, suggestionThreshold } = this.config;\n\n // Calculate gap (infinity if no second match)\n const gap = secondScore !== null ? topScore - secondScore : Infinity;\n\n // High confidence: score \u2265 0.92 AND gap \u2265 0.03\n if (topScore >= minCombinedScore && gap >= minGap) {\n return 'high';\n }\n\n // Suggested: score \u2265 0.75\n if (topScore >= suggestionThreshold) {\n return 'suggested';\n }\n\n // No match\n return 'none';\n }\n\n /**\n * Match search results to find best memory\n */\n matchSearchResults(\n results: SearchResult[],\n getEventAge: (eventId: string) => number\n ): MatchResult {\n if (results.length === 0) {\n return {\n match: null,\n confidence: 'none'\n };\n }\n\n // Calculate combined scores\n const scoredResults = results.map(result => {\n const ageDays = getEventAge(result.eventId);\n const combinedScore = this.calculateCombinedScore(\n result.score,\n 0, // FTS score - would need to be passed in\n ageDays,\n true // Assume active\n );\n\n return {\n result,\n combinedScore\n };\n });\n\n // Sort by combined score\n scoredResults.sort((a, b) => b.combinedScore - a.combinedScore);\n\n const topResult = scoredResults[0];\n const secondScore = scoredResults.length > 1 ? scoredResults[1].combinedScore : null;\n\n // Classify confidence\n const confidence = this.classifyConfidence(topResult.combinedScore, secondScore);\n\n // Build match result\n const match: MemoryMatch = {\n event: {\n id: topResult.result.eventId,\n eventType: topResult.result.eventType as 'user_prompt' | 'agent_response' | 'session_summary',\n sessionId: topResult.result.sessionId,\n timestamp: new Date(topResult.result.timestamp),\n content: topResult.result.content,\n canonicalKey: '', // Would need to be fetched\n dedupeKey: '' // Would need to be fetched\n },\n score: topResult.combinedScore\n };\n\n const gap = secondScore !== null ? topResult.combinedScore - secondScore : undefined;\n\n // Build alternatives for suggested matches\n const alternatives = confidence === 'suggested'\n ? scoredResults.slice(1, 4).map(sr => ({\n event: {\n id: sr.result.eventId,\n eventType: sr.result.eventType as 'user_prompt' | 'agent_response' | 'session_summary',\n sessionId: sr.result.sessionId,\n timestamp: new Date(sr.result.timestamp),\n content: sr.result.content,\n canonicalKey: '',\n dedupeKey: ''\n },\n score: sr.combinedScore\n }))\n : undefined;\n\n return {\n match: confidence !== 'none' ? match : null,\n confidence,\n gap,\n alternatives\n };\n }\n\n /**\n * Calculate days between two dates\n */\n static calculateAgeDays(timestamp: Date): number {\n const now = new Date();\n const diffMs = now.getTime() - timestamp.getTime();\n return diffMs / (1000 * 60 * 60 * 24);\n }\n\n /**\n * Get current configuration\n */\n getConfig(): Readonly<MatcherConfig> {\n return { ...this.config };\n }\n}\n\n/**\n * Default matcher instance\n */\nlet defaultMatcher: Matcher | null = null;\n\nexport function getDefaultMatcher(): Matcher {\n if (!defaultMatcher) {\n defaultMatcher = new Matcher();\n }\n return defaultMatcher;\n}\n", "/**\n * Memory Retriever - Unified retrieval interface\n * Combines vector search, keyword search, scoped filtering, and matching\n */\n\nimport { EventStore } from './event-store.js';\nimport { VectorStore, SearchResult } from './vector-store.js';\nimport { Embedder } from './embedder.js';\nimport { Matcher } from './matcher.js';\nimport { SharedStore } from './shared-store.js';\nimport { SharedVectorStore } from './shared-vector-store.js';\nimport { GraduationPipeline } from './graduation.js';\nimport type { MemoryEvent, MatchResult, SharedTroubleshootingEntry } from './types.js';\n\nexport interface RetrievalScope {\n sessionId?: string;\n eventTypes?: MemoryEvent['eventType'][];\n metadata?: Record<string, unknown>;\n canonicalKeyPrefix?: string;\n sessionIdPrefix?: string;\n contentIncludes?: string[];\n}\n\nexport type RetrievalStrategy = 'auto' | 'fast' | 'deep';\nexport type ProjectScopeMode = 'strict' | 'prefer' | 'global';\n\nexport interface RetrievalOptions {\n topK: number;\n minScore: number;\n sessionId?: string;\n maxTokens: number;\n includeSessionContext: boolean;\n scope?: RetrievalScope;\n strategy?: RetrievalStrategy;\n rerankWithKeyword?: boolean;\n rerankWeights?: {\n semantic?: number;\n lexical?: number;\n recency?: number;\n };\n decayPolicy?: {\n enabled?: boolean;\n windowDays?: number;\n maxPenalty?: number;\n };\n intentRewrite?: boolean;\n graphHop?: {\n enabled?: boolean;\n maxHops?: number;\n hopPenalty?: number;\n };\n projectScopeMode?: ProjectScopeMode;\n projectHash?: string;\n allowedProjectHashes?: string[];\n}\n\nexport interface RetrievalResult {\n memories: MemoryWithContext[];\n matchResult: MatchResult;\n totalTokens: number;\n context: string;\n fallbackTrace?: string[];\n selectedDebug?: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n candidateDebug?: Array<{\n eventId: string;\n score: number;\n semanticScore?: number;\n lexicalScore?: number;\n recencyScore?: number;\n }>;\n}\n\nexport interface MemoryWithContext {\n event: MemoryEvent;\n score: number;\n sessionContext?: string;\n}\n\nexport interface UnifiedRetrievalOptions extends RetrievalOptions {\n includeShared?: boolean;\n projectHash?: string;\n}\n\nexport interface UnifiedRetrievalResult extends RetrievalResult {\n sharedMemories?: SharedTroubleshootingEntry[];\n}\n\nconst DEFAULT_OPTIONS: RetrievalOptions = {\n topK: 5,\n minScore: 0.7,\n maxTokens: 2000,\n includeSessionContext: true,\n strategy: 'auto',\n rerankWithKeyword: true,\n decayPolicy: {\n enabled: true,\n windowDays: 30,\n maxPenalty: 0.15\n },\n graphHop: {\n enabled: true,\n maxHops: 1,\n hopPenalty: 0.08\n },\n projectScopeMode: 'global'\n};\n\nexport interface SharedStoreOptions {\n sharedStore?: SharedStore;\n sharedVectorStore?: SharedVectorStore;\n}\n\ntype EventStoreLike = EventStore & {\n keywordSearch?: (query: string, limit?: number) => Promise<Array<{ event: MemoryEvent; rank: number }>>;\n};\n\nexport class Retriever {\n private readonly eventStore: EventStoreLike;\n private readonly vectorStore: VectorStore;\n private readonly embedder: Embedder;\n private readonly matcher: Matcher;\n private sharedStore?: SharedStore;\n private sharedVectorStore?: SharedVectorStore;\n private graduation?: GraduationPipeline;\n private queryRewriter?: (query: string) => Promise<string | null>;\n\n constructor(\n eventStore: EventStore,\n vectorStore: VectorStore,\n embedder: Embedder,\n matcher: Matcher,\n sharedOptions?: SharedStoreOptions\n ) {\n this.eventStore = eventStore as EventStoreLike;\n this.vectorStore = vectorStore;\n this.embedder = embedder;\n this.matcher = matcher;\n this.sharedStore = sharedOptions?.sharedStore;\n this.sharedVectorStore = sharedOptions?.sharedVectorStore;\n }\n\n setGraduationPipeline(graduation: GraduationPipeline): void {\n this.graduation = graduation;\n }\n\n setSharedStores(sharedStore: SharedStore, sharedVectorStore: SharedVectorStore): void {\n this.sharedStore = sharedStore;\n this.sharedVectorStore = sharedVectorStore;\n }\n\n setQueryRewriter(rewriter: (query: string) => Promise<string | null>): void {\n this.queryRewriter = rewriter;\n }\n\n async retrieve(\n query: string,\n options: Partial<RetrievalOptions> = {}\n ): Promise<RetrievalResult> {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const sessionFilter = opts.scope?.sessionId ?? opts.sessionId;\n const fallbackTrace: string[] = [];\n\n const fallbackEnabled = (opts.strategy ?? 'auto') === 'auto';\n\n // Stage 1: primary retrieval\n const primaryStrategy: RetrievalStrategy = opts.strategy === 'auto' ? 'fast' : (opts.strategy || 'fast');\n let current = await this.runStage(query, {\n strategy: primaryStrategy,\n topK: opts.topK,\n minScore: opts.minScore,\n sessionId: sessionFilter,\n scope: opts.scope,\n rerankWithKeyword: opts.rerankWithKeyword !== false,\n rerankWeights: opts.rerankWeights,\n decayPolicy: opts.decayPolicy,\n intentRewrite: opts.intentRewrite === true,\n graphHop: opts.graphHop,\n projectScopeMode: opts.projectScopeMode,\n projectHash: opts.projectHash,\n allowedProjectHashes: opts.allowedProjectHashes\n });\n fallbackTrace.push(`stage:primary:${primaryStrategy}`);\n\n // Stage 2: deep fallback\n if (fallbackEnabled && this.shouldFallback(current.matchResult, current.results) && primaryStrategy !== 'deep') {\n current = await this.runStage(query, {\n strategy: 'deep',\n topK: opts.topK,\n minScore: opts.minScore,\n sessionId: sessionFilter,\n scope: opts.scope,\n rerankWithKeyword: opts.rerankWithKeyword !== false,\n rerankWeights: opts.rerankWeights,\n decayPolicy: opts.decayPolicy,\n graphHop: opts.graphHop,\n projectScopeMode: opts.projectScopeMode,\n projectHash: opts.projectHash,\n allowedProjectHashes: opts.allowedProjectHashes\n });\n fallbackTrace.push('fallback:deep');\n }\n\n // Stage 3: scope-expanded deep fallback\n if (fallbackEnabled && this.shouldFallback(current.matchResult, current.results)) {\n current = await this.runStage(query, {\n strategy: 'deep',\n topK: opts.topK,\n minScore: Math.max(0.5, opts.minScore - 0.15),\n sessionId: undefined,\n scope: undefined,\n rerankWithKeyword: true,\n rerankWeights: opts.rerankWeights,\n decayPolicy: opts.decayPolicy,\n graphHop: opts.graphHop,\n projectScopeMode: opts.projectScopeMode,\n projectHash: opts.projectHash,\n allowedProjectHashes: opts.allowedProjectHashes\n });\n fallbackTrace.push('fallback:scope-expanded');\n }\n\n // Stage 4: summary fallback\n if (fallbackEnabled && this.shouldFallback(current.matchResult, current.results)) {\n const summary = await this.buildSummaryFallback(query, opts.topK);\n current = {\n results: summary,\n candidateResults: summary,\n matchResult: this.matcher.matchSearchResults(summary, () => 0)\n };\n fallbackTrace.push('fallback:summary');\n }\n\n const memories = await this.enrichResults(current.results.slice(0, opts.topK), opts as RetrievalOptions);\n const context = this.buildContext(memories, opts.maxTokens);\n\n return {\n memories,\n matchResult: current.matchResult,\n totalTokens: this.estimateTokens(context),\n context,\n fallbackTrace,\n selectedDebug: current.results.slice(0, opts.topK).map((r: SearchResult & { semanticScore?: number; lexicalScore?: number; recencyScore?: number }) => ({\n eventId: r.eventId,\n score: r.score,\n semanticScore: r.semanticScore,\n lexicalScore: r.lexicalScore,\n recencyScore: r.recencyScore,\n })),\n candidateDebug: (current.candidateResults || []).slice(0, Math.max(opts.topK * 3, 20)).map((r: SearchResult & { semanticScore?: number; lexicalScore?: number; recencyScore?: number }) => ({\n eventId: r.eventId,\n score: r.score,\n semanticScore: r.semanticScore,\n lexicalScore: r.lexicalScore,\n recencyScore: r.recencyScore,\n }))\n };\n }\n\n async retrieveUnified(\n query: string,\n options: Partial<UnifiedRetrievalOptions> = {}\n ): Promise<UnifiedRetrievalResult> {\n const projectResult = await this.retrieve(query, options);\n\n if (!options.includeShared || !this.sharedStore || !this.sharedVectorStore) {\n return projectResult;\n }\n\n try {\n const queryEmbedding = await this.embedder.embed(query);\n const sharedVectorResults = await this.sharedVectorStore.search(queryEmbedding.vector, {\n limit: options.topK || 5,\n minScore: options.minScore || 0.7,\n excludeProjectHash: options.projectHash\n });\n\n const sharedMemories: SharedTroubleshootingEntry[] = [];\n for (const result of sharedVectorResults) {\n const entry = await this.sharedStore.get(result.entryId);\n if (!entry) continue;\n if (!options.projectHash || entry.sourceProjectHash !== options.projectHash) {\n sharedMemories.push(entry);\n await this.sharedStore.recordUsage(entry.entryId);\n }\n }\n\n const unifiedContext = this.buildUnifiedContext(projectResult, sharedMemories);\n return {\n ...projectResult,\n context: unifiedContext,\n totalTokens: this.estimateTokens(unifiedContext),\n sharedMemories\n };\n } catch (error) {\n console.error('Shared search failed:', error);\n return projectResult;\n }\n }\n\n private async runStage(\n query: string,\n input: {\n strategy: RetrievalStrategy;\n topK: number;\n minScore: number;\n sessionId?: string;\n scope?: RetrievalScope;\n rerankWithKeyword: boolean;\n rerankWeights?: {\n semantic?: number;\n lexical?: number;\n recency?: number;\n };\n decayPolicy?: {\n enabled?: boolean;\n windowDays?: number;\n maxPenalty?: number;\n };\n intentRewrite?: boolean;\n graphHop?: {\n enabled?: boolean;\n maxHops?: number;\n hopPenalty?: number;\n };\n projectScopeMode?: ProjectScopeMode;\n projectHash?: string;\n allowedProjectHashes?: string[];\n }\n ): Promise<{ results: SearchResult[]; matchResult: MatchResult }> {\n let initialResults = await this.searchByStrategy(query, {\n strategy: input.strategy,\n topK: input.topK,\n minScore: input.minScore,\n sessionId: input.sessionId\n });\n\n if (input.intentRewrite && input.strategy === 'deep' && this.queryRewriter) {\n const rewritten = (await this.queryRewriter(query))?.trim();\n if (rewritten && rewritten !== query) {\n const rewrittenResults = await this.searchByStrategy(rewritten, {\n strategy: 'deep',\n topK: input.topK,\n minScore: Math.max(0.5, input.minScore - 0.1),\n sessionId: input.sessionId\n });\n initialResults = this.mergeResults(initialResults, rewrittenResults, input.topK * 3);\n }\n }\n\n const expandedResults = input.graphHop?.enabled === false\n ? initialResults\n : await this.expandGraphHops(initialResults, {\n maxHops: Math.max(1, input.graphHop?.maxHops ?? 1),\n hopPenalty: Math.max(0, input.graphHop?.hopPenalty ?? 0.08),\n limit: input.topK * 4,\n });\n\n const rerankedResults = input.rerankWithKeyword\n ? this.rerankByKeywordOverlap(expandedResults, query, input.rerankWeights, input.decayPolicy)\n : expandedResults;\n\n const filtered = await this.applyScopeFilters(rerankedResults, {\n scope: input.scope,\n projectScopeMode: input.projectScopeMode,\n projectHash: input.projectHash,\n allowedProjectHashes: input.allowedProjectHashes\n });\n const top = filtered.slice(0, input.topK);\n const matchResult = this.matcher.matchSearchResults(top, () => 0);\n\n return { results: top, candidateResults: filtered, matchResult };\n }\n\n private mergeResults(primary: SearchResult[], secondary: SearchResult[], limit: number): SearchResult[] {\n const byId = new Map<string, SearchResult>();\n for (const row of primary) byId.set(row.eventId, row);\n for (const row of secondary) {\n const prev = byId.get(row.eventId);\n if (!prev || row.score > prev.score) {\n byId.set(row.eventId, row);\n }\n }\n return [...byId.values()].sort((a, b) => b.score - a.score).slice(0, limit);\n }\n\n private async expandGraphHops(\n seeds: SearchResult[],\n opts: { maxHops: number; hopPenalty: number; limit: number }\n ): Promise<SearchResult[]> {\n const byId = new Map<string, SearchResult>();\n for (const s of seeds) byId.set(s.eventId, s);\n\n let frontier = seeds.map((s) => ({ row: s, hop: 0 }));\n\n for (let hop = 1; hop <= opts.maxHops; hop += 1) {\n const next: Array<{ row: SearchResult; hop: number }> = [];\n\n for (const f of frontier) {\n const ev = await this.eventStore.getEvent(f.row.eventId);\n if (!ev) continue;\n const rel = ((ev.metadata as Record<string, unknown> | undefined)?.relatedEventIds ?? []) as unknown;\n const relatedIds = Array.isArray(rel)\n ? rel.filter((x): x is string => typeof x === 'string')\n : [];\n\n for (const rid of relatedIds) {\n if (byId.has(rid)) continue;\n const target = await this.eventStore.getEvent(rid);\n if (!target) continue;\n\n const score = Math.max(0, f.row.score - opts.hopPenalty * hop);\n const row: SearchResult = {\n id: `hop-${hop}-${rid}`,\n eventId: target.id,\n content: target.content,\n score,\n sessionId: target.sessionId,\n eventType: target.eventType,\n timestamp: target.timestamp.toISOString(),\n };\n\n byId.set(row.eventId, row);\n next.push({ row, hop });\n if (byId.size >= opts.limit) break;\n }\n if (byId.size >= opts.limit) break;\n }\n\n frontier = next;\n if (frontier.length === 0 || byId.size >= opts.limit) break;\n }\n\n return [...byId.values()].sort((a, b) => b.score - a.score).slice(0, opts.limit);\n }\n\n private shouldFallback(matchResult: MatchResult, results: SearchResult[]): boolean {\n if (results.length === 0) return true;\n if (matchResult.confidence === 'none') return true;\n return false;\n }\n\n private async buildSummaryFallback(query: string, topK: number): Promise<SearchResult[]> {\n const recent = await this.eventStore.getRecentEvents(Math.max(topK * 6, 20));\n const q = this.tokenize(query);\n\n const ranked = recent\n .map((e) => ({ e, overlap: this.keywordOverlap(q, this.tokenize(e.content)) }))\n .filter((r) => r.overlap > 0)\n .sort((a, b) => b.overlap - a.overlap)\n .slice(0, topK)\n .map((row, idx) => ({\n id: `summary-${row.e.id}`,\n eventId: row.e.id,\n content: row.e.content,\n score: Math.max(0.25, 0.6 - idx * 0.05),\n sessionId: row.e.sessionId,\n eventType: row.e.eventType,\n timestamp: row.e.timestamp.toISOString()\n }));\n\n return ranked;\n }\n\n private async searchByStrategy(\n query: string,\n input: { strategy: RetrievalStrategy; topK: number; minScore: number; sessionId?: string }\n ): Promise<SearchResult[]> {\n const strategy = input.strategy === 'auto' ? 'deep' : input.strategy;\n\n if (strategy === 'fast') {\n const keyword = await this.searchByKeyword(query, {\n limit: Math.max(5, input.topK * 3),\n sessionId: input.sessionId\n });\n return keyword;\n }\n\n const queryEmbedding = await this.embedder.embed(query);\n return this.vectorStore.search(queryEmbedding.vector, {\n limit: Math.max(5, input.topK * 3),\n minScore: input.minScore,\n sessionId: input.sessionId\n });\n }\n\n private async searchByKeyword(\n query: string,\n input: { limit: number; sessionId?: string }\n ): Promise<SearchResult[]> {\n if (this.eventStore.keywordSearch) {\n const rows = await this.eventStore.keywordSearch(query, input.limit);\n const filtered = input.sessionId ? rows.filter((r) => r.event.sessionId === input.sessionId) : rows;\n return filtered.map((row, idx) => ({\n id: `kw-${row.event.id}`,\n eventId: row.event.id,\n content: row.event.content,\n score: Math.max(0.4, 1 - idx * 0.04),\n sessionId: row.event.sessionId,\n eventType: row.event.eventType,\n timestamp: row.event.timestamp.toISOString()\n }));\n }\n\n const recent = await this.eventStore.getRecentEvents(input.limit * 4);\n const tokens = this.tokenize(query);\n const filtered = recent\n .filter((e) => (input.sessionId ? e.sessionId === input.sessionId : true))\n .map((e) => ({ e, overlap: this.keywordOverlap(tokens, this.tokenize(e.content)) }))\n .filter((r) => r.overlap > 0)\n .sort((a, b) => b.overlap - a.overlap)\n .slice(0, input.limit);\n\n return filtered.map((row, idx) => ({\n id: `kw-fallback-${row.e.id}`,\n eventId: row.e.id,\n content: row.e.content,\n score: Math.max(0.3, 0.9 - idx * 0.05),\n sessionId: row.e.sessionId,\n eventType: row.e.eventType,\n timestamp: row.e.timestamp.toISOString()\n }));\n }\n\n private rerankByKeywordOverlap(\n results: SearchResult[],\n query: string,\n weights?: { semantic?: number; lexical?: number; recency?: number },\n decayPolicy?: { enabled?: boolean; windowDays?: number; maxPenalty?: number }\n ): SearchResult[] {\n const q = this.tokenize(query);\n const now = Date.now();\n\n const sw = Math.max(0, weights?.semantic ?? 0.7);\n const lw = Math.max(0, weights?.lexical ?? 0.2);\n const rw = Math.max(0, weights?.recency ?? 0.1);\n const total = sw + lw + rw || 1;\n\n const decayEnabled = decayPolicy?.enabled !== false;\n const decayWindow = Math.max(1, decayPolicy?.windowDays ?? 30);\n const decayMaxPenalty = Math.max(0, decayPolicy?.maxPenalty ?? 0.15);\n\n return [...results]\n .map((r) => {\n const overlap = this.keywordOverlap(q, this.tokenize(r.content));\n const recencyDays = Math.max(0, (now - new Date(r.timestamp).getTime()) / (1000 * 60 * 60 * 24));\n const recency = Math.max(0, 1 - recencyDays / decayWindow);\n let blended = (r.score * sw + overlap * lw + recency * rw) / total;\n\n if (decayEnabled && recencyDays > decayWindow && overlap < 0.5) {\n const ageFactor = Math.min(1, (recencyDays - decayWindow) / decayWindow);\n blended -= decayMaxPenalty * ageFactor;\n }\n\n return { ...r, score: Math.max(0, blended), semanticScore: r.score, lexicalScore: overlap, recencyScore: recency };\n })\n .sort((a, b) => b.score - a.score);\n }\n\n private async applyScopeFilters(\n results: SearchResult[],\n options?: {\n scope?: RetrievalScope;\n projectScopeMode?: ProjectScopeMode;\n projectHash?: string;\n allowedProjectHashes?: string[];\n }\n ): Promise<SearchResult[]> {\n const scope = options?.scope;\n const projectScopeMode = options?.projectScopeMode ?? 'global';\n const allowedProjectHashes = new Set(\n [options?.projectHash, ...(options?.allowedProjectHashes || [])].filter(\n (value): value is string => typeof value === 'string' && value.length > 0\n )\n );\n\n if (!scope && projectScopeMode === 'global') return results;\n\n const normalizedIncludes = (scope?.contentIncludes || []).map((s) => s.toLowerCase());\n const filtered: Array<{ result: SearchResult; projectHash?: string }> = [];\n\n for (const result of results) {\n if (scope?.sessionId && result.sessionId !== scope.sessionId) continue;\n if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix)) continue;\n if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType as MemoryEvent['eventType'])) continue;\n\n const event = await this.eventStore.getEvent(result.eventId);\n if (!event) continue;\n\n if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix)) continue;\n if (normalizedIncludes.length > 0) {\n const lc = event.content.toLowerCase();\n if (!normalizedIncludes.some((needle) => lc.includes(needle))) continue;\n }\n if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata)) continue;\n\n const projectHash = this.extractProjectHash(event.metadata);\n filtered.push({ result, projectHash });\n }\n\n if (projectScopeMode === 'global' || allowedProjectHashes.size === 0) {\n return filtered.map((x) => x.result);\n }\n\n const projectMatched = filtered.filter((x) => x.projectHash && allowedProjectHashes.has(x.projectHash));\n\n if (projectScopeMode === 'strict') {\n return projectMatched.map((x) => x.result);\n }\n\n return (projectMatched.length > 0 ? projectMatched : filtered).map((x) => x.result);\n }\n\n private extractProjectHash(metadata: Record<string, unknown> | undefined): string | undefined {\n if (!metadata || typeof metadata !== 'object') return undefined;\n const scope = metadata.scope;\n if (!scope || typeof scope !== 'object') return undefined;\n const project = (scope as Record<string, unknown>).project;\n if (!project || typeof project !== 'object') return undefined;\n const hash = (project as Record<string, unknown>).hash;\n return typeof hash === 'string' && hash.length > 0 ? hash : undefined;\n }\n\n async retrieveFromSession(sessionId: string): Promise<MemoryEvent[]> {\n return this.eventStore.getSessionEvents(sessionId);\n }\n\n async retrieveRecent(limit: number = 100): Promise<MemoryEvent[]> {\n return this.eventStore.getRecentEvents(limit);\n }\n\n private async enrichResults(results: SearchResult[], options: RetrievalOptions): Promise<MemoryWithContext[]> {\n const memories: MemoryWithContext[] = [];\n\n for (const result of results) {\n const event = await this.eventStore.getEvent(result.eventId);\n if (!event) continue;\n\n if (this.graduation) {\n this.graduation.recordAccess(event.id, options.sessionId || 'unknown', result.score);\n }\n\n let sessionContext: string | undefined;\n if (options.includeSessionContext) {\n sessionContext = await this.getSessionContext(event.sessionId, event.id);\n }\n\n memories.push({ event, score: result.score, sessionContext });\n }\n\n return memories;\n }\n\n private async getSessionContext(sessionId: string, eventId: string): Promise<string | undefined> {\n const sessionEvents = await this.eventStore.getSessionEvents(sessionId);\n const eventIndex = sessionEvents.findIndex(e => e.id === eventId);\n if (eventIndex === -1) return undefined;\n\n const start = Math.max(0, eventIndex - 1);\n const end = Math.min(sessionEvents.length, eventIndex + 2);\n const contextEvents = sessionEvents.slice(start, end);\n if (contextEvents.length <= 1) return undefined;\n\n return contextEvents\n .filter(e => e.id !== eventId)\n .map(e => `[${e.eventType}]: ${e.content.slice(0, 200)}...`)\n .join('\\n');\n }\n\n private buildUnifiedContext(projectResult: RetrievalResult, sharedMemories: SharedTroubleshootingEntry[]): string {\n let context = projectResult.context;\n if (sharedMemories.length === 0) return context;\n\n context += '\\n\\n## Cross-Project Knowledge\\n\\n';\n for (const memory of sharedMemories.slice(0, 3)) {\n context += `### ${memory.title}\\n`;\n if (memory.symptoms.length > 0) context += `**Symptoms:** ${memory.symptoms.join(', ')}\\n`;\n context += `**Root Cause:** ${memory.rootCause}\\n`;\n context += `**Solution:** ${memory.solution}\\n`;\n if (memory.technologies && memory.technologies.length > 0) context += `**Technologies:** ${memory.technologies.join(', ')}\\n`;\n context += `_Confidence: ${(memory.confidence * 100).toFixed(0)}%_\\n\\n`;\n }\n\n return context;\n }\n\n private buildContext(memories: MemoryWithContext[], maxTokens: number): string {\n const parts: string[] = [];\n let currentTokens = 0;\n\n for (const memory of memories) {\n const memoryText = this.formatMemory(memory);\n const memoryTokens = this.estimateTokens(memoryText);\n if (currentTokens + memoryTokens > maxTokens) break;\n parts.push(memoryText);\n currentTokens += memoryTokens;\n }\n\n if (parts.length === 0) return '';\n return `## Relevant Memories\\n\\n${parts.join('\\n\\n---\\n\\n')}`;\n }\n\n private formatMemory(memory: MemoryWithContext): string {\n const { event, score, sessionContext } = memory;\n const date = event.timestamp.toISOString().split('T')[0];\n\n let text = `**${event.eventType}** (${date}, score: ${score.toFixed(2)})\\n${event.content}`;\n if (sessionContext) text += `\\n\\n_Context:_ ${sessionContext}`;\n return text;\n }\n\n private matchesMetadataScope(\n metadata: Record<string, unknown> | undefined,\n expected: Record<string, unknown>\n ): boolean {\n if (!metadata) return false;\n\n return Object.entries(expected).every(([path, value]) => {\n const actual = path.split('.').reduce<unknown>((acc, key) => {\n if (typeof acc !== 'object' || acc === null) return undefined;\n return (acc as Record<string, unknown>)[key];\n }, metadata);\n\n return actual === value;\n });\n }\n\n private tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s]/gu, ' ')\n .split(/\\s+/)\n .filter((t) => t.length >= 2)\n .slice(0, 64);\n }\n\n private keywordOverlap(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n const bs = new Set(b);\n let hit = 0;\n for (const t of a) if (bs.has(t)) hit += 1;\n return hit / a.length;\n }\n\n private estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n }\n}\n\nexport function createRetriever(\n eventStore: EventStore,\n vectorStore: VectorStore,\n embedder: Embedder,\n matcher: Matcher\n): Retriever {\n return new Retriever(eventStore, vectorStore, embedder, matcher);\n}\n", "/**\n * Memory Graduation Pipeline - AXIOMMIND L0\u2192L1\u2192L2\u2192L3\u2192L4\n *\n * L0: EventStore (raw events, append-only)\n * L1: Structured JSON (session summaries, patterns)\n * L2: Type Candidates (Idris2-inspired, validated schemas)\n * L3: Verified Knowledge (cross-session validated)\n * L4: Active/Searchable (indexed, readily available)\n */\n\nimport { EventStore } from './event-store.js';\nimport type {\n MemoryEvent,\n MemoryLevel,\n GraduationResult,\n Insight,\n InsightType\n} from './types.js';\n\nexport interface GraduationCriteria {\n minAccessCount: number;\n minConfidence: number;\n minCrossSessionRefs: number;\n maxAgeDays: number;\n}\n\nexport interface LevelCriteria {\n L0toL1: GraduationCriteria;\n L1toL2: GraduationCriteria;\n L2toL3: GraduationCriteria;\n L3toL4: GraduationCriteria;\n}\n\nconst DEFAULT_CRITERIA: LevelCriteria = {\n L0toL1: {\n minAccessCount: 1,\n minConfidence: 0.5,\n minCrossSessionRefs: 0,\n maxAgeDays: 30\n },\n L1toL2: {\n minAccessCount: 3,\n minConfidence: 0.7,\n minCrossSessionRefs: 1,\n maxAgeDays: 60\n },\n L2toL3: {\n minAccessCount: 5,\n minConfidence: 0.85,\n minCrossSessionRefs: 2,\n maxAgeDays: 90\n },\n L3toL4: {\n minAccessCount: 10,\n minConfidence: 0.92,\n minCrossSessionRefs: 3,\n maxAgeDays: 180\n }\n};\n\nexport interface EventMetrics {\n eventId: string;\n accessCount: number;\n lastAccessed: Date;\n crossSessionRefs: number;\n confidence: number;\n}\n\nexport class GraduationPipeline {\n private readonly eventStore: EventStore;\n private readonly criteria: LevelCriteria;\n private readonly metrics: Map<string, EventMetrics> = new Map();\n\n constructor(\n eventStore: EventStore,\n criteria: Partial<LevelCriteria> = {}\n ) {\n this.eventStore = eventStore;\n this.criteria = {\n L0toL1: { ...DEFAULT_CRITERIA.L0toL1, ...criteria.L0toL1 },\n L1toL2: { ...DEFAULT_CRITERIA.L1toL2, ...criteria.L1toL2 },\n L2toL3: { ...DEFAULT_CRITERIA.L2toL3, ...criteria.L2toL3 },\n L3toL4: { ...DEFAULT_CRITERIA.L3toL4, ...criteria.L3toL4 }\n };\n }\n\n // Track which sessions have accessed each event\n private readonly sessionAccesses: Map<string, Set<string>> = new Map();\n\n /**\n * Record an access to an event (used for graduation scoring)\n */\n recordAccess(eventId: string, fromSessionId: string, confidence: number = 1.0): void {\n const existing = this.metrics.get(eventId);\n\n // Track sessions that have accessed this event\n if (!this.sessionAccesses.has(eventId)) {\n this.sessionAccesses.set(eventId, new Set());\n }\n const sessions = this.sessionAccesses.get(eventId)!;\n const isNewSession = !sessions.has(fromSessionId);\n sessions.add(fromSessionId);\n\n if (existing) {\n existing.accessCount++;\n existing.lastAccessed = new Date();\n existing.confidence = Math.max(existing.confidence, confidence);\n // Update cross-session references count\n if (isNewSession && sessions.size > 1) {\n existing.crossSessionRefs = sessions.size - 1;\n }\n } else {\n this.metrics.set(eventId, {\n eventId,\n accessCount: 1,\n lastAccessed: new Date(),\n crossSessionRefs: 0,\n confidence\n });\n }\n }\n\n /**\n * Evaluate if an event should graduate to the next level\n */\n async evaluateGraduation(eventId: string, currentLevel: MemoryLevel): Promise<GraduationResult> {\n const metrics = this.metrics.get(eventId);\n\n if (!metrics) {\n return {\n eventId,\n fromLevel: currentLevel,\n toLevel: currentLevel,\n success: false,\n reason: 'No metrics available for event'\n };\n }\n\n const nextLevel = this.getNextLevel(currentLevel);\n if (!nextLevel) {\n return {\n eventId,\n fromLevel: currentLevel,\n toLevel: currentLevel,\n success: false,\n reason: 'Already at maximum level'\n };\n }\n\n const criteria = this.getCriteria(currentLevel, nextLevel);\n const evaluation = this.checkCriteria(metrics, criteria);\n\n if (evaluation.passed) {\n // Update level in event store\n await this.eventStore.updateMemoryLevel(eventId, nextLevel);\n\n return {\n eventId,\n fromLevel: currentLevel,\n toLevel: nextLevel,\n success: true\n };\n }\n\n return {\n eventId,\n fromLevel: currentLevel,\n toLevel: currentLevel,\n success: false,\n reason: evaluation.reason\n };\n }\n\n /**\n * Run graduation evaluation for all events at a given level\n */\n async graduateBatch(level: MemoryLevel): Promise<GraduationResult[]> {\n const results: GraduationResult[] = [];\n\n for (const [eventId, metrics] of this.metrics) {\n const result = await this.evaluateGraduation(eventId, level);\n results.push(result);\n }\n\n return results;\n }\n\n /**\n * Extract insights from graduated events (L1+)\n */\n extractInsights(events: MemoryEvent[]): Insight[] {\n const insights: Insight[] = [];\n\n // Pattern detection: Look for repeated themes\n const patterns = this.detectPatterns(events);\n for (const pattern of patterns) {\n insights.push({\n id: crypto.randomUUID(),\n insightType: 'pattern',\n content: pattern.description,\n canonicalKey: pattern.key,\n confidence: pattern.confidence,\n sourceEvents: pattern.eventIds,\n createdAt: new Date(),\n lastUpdated: new Date()\n });\n }\n\n // Preference detection: Look for user preferences\n const preferences = this.detectPreferences(events);\n for (const pref of preferences) {\n insights.push({\n id: crypto.randomUUID(),\n insightType: 'preference',\n content: pref.description,\n canonicalKey: pref.key,\n confidence: pref.confidence,\n sourceEvents: pref.eventIds,\n createdAt: new Date(),\n lastUpdated: new Date()\n });\n }\n\n return insights;\n }\n\n /**\n * Get the next level in the graduation pipeline\n */\n private getNextLevel(current: MemoryLevel): MemoryLevel | null {\n const levels: MemoryLevel[] = ['L0', 'L1', 'L2', 'L3', 'L4'];\n const currentIndex = levels.indexOf(current);\n\n if (currentIndex === -1 || currentIndex >= levels.length - 1) {\n return null;\n }\n\n return levels[currentIndex + 1];\n }\n\n /**\n * Get criteria for level transition\n */\n private getCriteria(from: MemoryLevel, to: MemoryLevel): GraduationCriteria {\n const key = `${from}to${to}` as keyof LevelCriteria;\n return this.criteria[key] || DEFAULT_CRITERIA.L0toL1;\n }\n\n /**\n * Check if metrics meet criteria\n */\n private checkCriteria(\n metrics: EventMetrics,\n criteria: GraduationCriteria\n ): { passed: boolean; reason?: string } {\n if (metrics.accessCount < criteria.minAccessCount) {\n return {\n passed: false,\n reason: `Access count ${metrics.accessCount} < ${criteria.minAccessCount}`\n };\n }\n\n if (metrics.confidence < criteria.minConfidence) {\n return {\n passed: false,\n reason: `Confidence ${metrics.confidence} < ${criteria.minConfidence}`\n };\n }\n\n if (metrics.crossSessionRefs < criteria.minCrossSessionRefs) {\n return {\n passed: false,\n reason: `Cross-session refs ${metrics.crossSessionRefs} < ${criteria.minCrossSessionRefs}`\n };\n }\n\n const ageDays = (Date.now() - metrics.lastAccessed.getTime()) / (1000 * 60 * 60 * 24);\n if (ageDays > criteria.maxAgeDays) {\n return {\n passed: false,\n reason: `Event too old: ${ageDays.toFixed(1)} days > ${criteria.maxAgeDays}`\n };\n }\n\n return { passed: true };\n }\n\n /**\n * Detect patterns in events\n */\n private detectPatterns(events: MemoryEvent[]): Array<{\n key: string;\n description: string;\n confidence: number;\n eventIds: string[];\n }> {\n // Simple pattern detection: group by canonical key and look for repeats\n const keyGroups = new Map<string, MemoryEvent[]>();\n\n for (const event of events) {\n const existing = keyGroups.get(event.canonicalKey) || [];\n existing.push(event);\n keyGroups.set(event.canonicalKey, existing);\n }\n\n const patterns: Array<{\n key: string;\n description: string;\n confidence: number;\n eventIds: string[];\n }> = [];\n\n for (const [key, groupEvents] of keyGroups) {\n if (groupEvents.length >= 2) {\n patterns.push({\n key,\n description: `Repeated topic: ${key.slice(0, 50)}`,\n confidence: Math.min(1.0, groupEvents.length / 5),\n eventIds: groupEvents.map(e => e.id)\n });\n }\n }\n\n return patterns;\n }\n\n /**\n * Detect user preferences from events\n */\n private detectPreferences(events: MemoryEvent[]): Array<{\n key: string;\n description: string;\n confidence: number;\n eventIds: string[];\n }> {\n // Simple preference detection: look for keywords\n const preferenceKeywords = ['prefer', 'like', 'want', 'always', 'never', 'favorite'];\n const preferences: Array<{\n key: string;\n description: string;\n confidence: number;\n eventIds: string[];\n }> = [];\n\n for (const event of events) {\n if (event.eventType !== 'user_prompt') continue;\n\n const lowerContent = event.content.toLowerCase();\n for (const keyword of preferenceKeywords) {\n if (lowerContent.includes(keyword)) {\n preferences.push({\n key: `preference_${keyword}_${event.id.slice(0, 8)}`,\n description: `User preference: ${event.content.slice(0, 100)}`,\n confidence: 0.7,\n eventIds: [event.id]\n });\n break;\n }\n }\n }\n\n return preferences;\n }\n\n /**\n * Get graduation statistics\n */\n async getStats(): Promise<{ level: string; count: number }[]> {\n return this.eventStore.getLevelStats();\n }\n}\n\n/**\n * Create graduation pipeline with default settings\n */\nexport function createGraduationPipeline(eventStore: EventStore): GraduationPipeline {\n return new GraduationPipeline(eventStore);\n}\n", "/**\n * SharedEventStore - Global database for cross-project knowledge\n * Location: ~/.claude-code/memory/shared/\n */\n\nimport {\n createDatabase,\n dbRun,\n dbClose,\n type Database\n} from './db-wrapper.js';\n\nexport class SharedEventStore {\n private db: Database;\n private initialized = false;\n\n constructor(private dbPath: string) {\n this.db = createDatabase(dbPath);\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Shared troubleshooting entries table\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS shared_troubleshooting (\n entry_id VARCHAR PRIMARY KEY,\n source_project_hash VARCHAR NOT NULL,\n source_entry_id VARCHAR NOT NULL,\n title VARCHAR NOT NULL,\n symptoms JSON NOT NULL,\n root_cause TEXT NOT NULL,\n solution TEXT NOT NULL,\n topics JSON NOT NULL,\n technologies JSON,\n confidence REAL NOT NULL DEFAULT 0.8,\n usage_count INTEGER DEFAULT 0,\n last_used_at TIMESTAMP,\n promoted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n UNIQUE(source_project_hash, source_entry_id)\n )\n `);\n\n // Future extensibility: best practices table\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS shared_best_practices (\n entry_id VARCHAR PRIMARY KEY,\n source_project_hash VARCHAR NOT NULL,\n source_entry_id VARCHAR NOT NULL,\n title VARCHAR NOT NULL,\n content_json JSON NOT NULL,\n topics JSON NOT NULL,\n confidence REAL NOT NULL DEFAULT 0.8,\n usage_count INTEGER DEFAULT 0,\n promoted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n UNIQUE(source_project_hash, source_entry_id)\n )\n `);\n\n // Future extensibility: common errors table\n await dbRun(this.db, `\n CREATE TABLE IF NOT EXISTS shared_common_errors (\n entry_id VARCHAR PRIMARY KEY,\n source_project_hash VARCHAR NOT NULL,\n source_entry_id VARCHAR NOT NULL,\n title VARCHAR NOT NULL,\n error_pattern TEXT NOT NULL,\n solution TEXT NOT NULL,\n topics JSON NOT NULL,\n technologies JSON,\n confidence REAL NOT NULL DEFAULT 0.8,\n usage_count INTEGER DEFAULT 0,\n promoted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n UNIQUE(source_project_hash, source_entry_id)\n )\n `);\n\n // Indexes for troubleshooting\n await dbRun(this.db, `\n CREATE INDEX IF NOT EXISTS idx_shared_ts_confidence\n ON shared_troubleshooting(confidence DESC)\n `);\n await dbRun(this.db, `\n CREATE INDEX IF NOT EXISTS idx_shared_ts_usage\n ON shared_troubleshooting(usage_count DESC)\n `);\n await dbRun(this.db, `\n CREATE INDEX IF NOT EXISTS idx_shared_ts_source\n ON shared_troubleshooting(source_project_hash)\n `);\n\n this.initialized = true;\n }\n\n getDatabase(): Database {\n return this.db;\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n\n async close(): Promise<void> {\n await dbClose(this.db);\n this.initialized = false;\n }\n}\n\nexport function createSharedEventStore(dbPath: string): SharedEventStore {\n return new SharedEventStore(dbPath);\n}\n", "/**\n * SharedStore - Cross-project troubleshooting knowledge store\n * Manages promotion from verified entries to shared storage\n */\n\nimport { randomUUID } from 'crypto';\nimport { dbRun, dbAll, toDate, type Database } from './db-wrapper.js';\nimport type {\n SharedTroubleshootingEntry,\n SharedTroubleshootingInput\n} from './types.js';\nimport { SharedEventStore } from './shared-event-store.js';\n\nexport class SharedStore {\n constructor(private sharedEventStore: SharedEventStore) {}\n\n private get db(): Database {\n return this.sharedEventStore.getDatabase();\n }\n\n /**\n * Promote a verified troubleshooting entry to shared storage\n */\n async promoteEntry(\n input: SharedTroubleshootingInput\n ): Promise<string> {\n const entryId = randomUUID();\n\n await dbRun(\n this.db,\n `INSERT INTO shared_troubleshooting (\n entry_id, source_project_hash, source_entry_id,\n title, symptoms, root_cause, solution, topics,\n technologies, confidence, promoted_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)\n ON CONFLICT (source_project_hash, source_entry_id)\n DO UPDATE SET\n title = excluded.title,\n symptoms = excluded.symptoms,\n root_cause = excluded.root_cause,\n solution = excluded.solution,\n topics = excluded.topics,\n technologies = excluded.technologies,\n confidence = CASE\n WHEN excluded.confidence > shared_troubleshooting.confidence\n THEN excluded.confidence\n ELSE shared_troubleshooting.confidence\n END`,\n [\n entryId,\n input.sourceProjectHash,\n input.sourceEntryId,\n input.title,\n JSON.stringify(input.symptoms),\n input.rootCause,\n input.solution,\n JSON.stringify(input.topics),\n JSON.stringify(input.technologies || []),\n input.confidence\n ]\n );\n\n return entryId;\n }\n\n /**\n * Search troubleshooting entries by text query\n */\n async search(\n query: string,\n options?: { topK?: number; minConfidence?: number }\n ): Promise<SharedTroubleshootingEntry[]> {\n const topK = options?.topK || 5;\n const minConfidence = options?.minConfidence || 0.5;\n const searchPattern = `%${query}%`;\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM shared_troubleshooting\n WHERE (title LIKE ? OR root_cause LIKE ? OR solution LIKE ?)\n AND confidence >= ?\n ORDER BY confidence DESC, usage_count DESC\n LIMIT ?`,\n [searchPattern, searchPattern, searchPattern, minConfidence, topK]\n );\n\n return rows.map(this.rowToEntry);\n }\n\n /**\n * Search by topics\n */\n async searchByTopics(\n topics: string[],\n options?: { topK?: number; excludeProjectHash?: string }\n ): Promise<SharedTroubleshootingEntry[]> {\n const topK = options?.topK || 5;\n\n if (topics.length === 0) {\n return [];\n }\n\n const topicConditions = topics.map(() => `topics LIKE ?`).join(' OR ');\n const topicParams = topics.map(t => `%\"${t}\"%`);\n\n let query = `SELECT * FROM shared_troubleshooting WHERE (${topicConditions})`;\n const params: unknown[] = [...topicParams];\n\n if (options?.excludeProjectHash) {\n query += ` AND source_project_hash != ?`;\n params.push(options.excludeProjectHash);\n }\n\n query += ` ORDER BY confidence DESC, usage_count DESC LIMIT ?`;\n params.push(topK);\n\n const rows = await dbAll<Record<string, unknown>>(this.db, query, params);\n return rows.map(this.rowToEntry);\n }\n\n /**\n * Record usage of a shared entry (for ranking)\n */\n async recordUsage(entryId: string): Promise<void> {\n await dbRun(\n this.db,\n `UPDATE shared_troubleshooting\n SET usage_count = usage_count + 1,\n last_used_at = CURRENT_TIMESTAMP\n WHERE entry_id = ?`,\n [entryId]\n );\n }\n\n /**\n * Get entry by ID\n */\n async get(entryId: string): Promise<SharedTroubleshootingEntry | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM shared_troubleshooting WHERE entry_id = ?`,\n [entryId]\n );\n\n if (rows.length === 0) return null;\n return this.rowToEntry(rows[0]);\n }\n\n /**\n * Get entry by source (project hash + entry ID)\n */\n async getBySource(\n projectHash: string,\n sourceEntryId: string\n ): Promise<SharedTroubleshootingEntry | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM shared_troubleshooting\n WHERE source_project_hash = ? AND source_entry_id = ?`,\n [projectHash, sourceEntryId]\n );\n\n if (rows.length === 0) return null;\n return this.rowToEntry(rows[0]);\n }\n\n /**\n * Check if an entry already exists in shared store\n */\n async exists(projectHash: string, sourceEntryId: string): Promise<boolean> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM shared_troubleshooting\n WHERE source_project_hash = ? AND source_entry_id = ?`,\n [projectHash, sourceEntryId]\n );\n return (result[0]?.count || 0) > 0;\n }\n\n /**\n * Get all entries (with limit for safety)\n */\n async getAll(options?: { limit?: number }): Promise<SharedTroubleshootingEntry[]> {\n const limit = options?.limit || 100;\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM shared_troubleshooting\n ORDER BY confidence DESC, usage_count DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToEntry);\n }\n\n /**\n * Get total count\n */\n async count(): Promise<number> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM shared_troubleshooting`\n );\n return result[0]?.count || 0;\n }\n\n /**\n * Get statistics\n */\n async getStats(): Promise<{\n total: number;\n averageConfidence: number;\n topTopics: Array<{ topic: string; count: number }>;\n totalUsageCount: number;\n }> {\n const countResult = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM shared_troubleshooting`\n );\n const total = countResult[0]?.count || 0;\n\n const avgResult = await dbAll<{ avg: number | null }>(\n this.db,\n `SELECT AVG(confidence) as avg FROM shared_troubleshooting`\n );\n const averageConfidence = avgResult[0]?.avg || 0;\n\n const usageResult = await dbAll<{ total: number }>(\n this.db,\n `SELECT SUM(usage_count) as total FROM shared_troubleshooting`\n );\n const totalUsageCount = usageResult[0]?.total || 0;\n\n // Get topic counts\n const entries = await this.getAll({ limit: 1000 });\n const topicCounts: Record<string, number> = {};\n for (const entry of entries) {\n for (const topic of entry.topics) {\n topicCounts[topic] = (topicCounts[topic] || 0) + 1;\n }\n }\n\n const topTopics = Object.entries(topicCounts)\n .map(([topic, count]) => ({ topic, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 10);\n\n return { total, averageConfidence, topTopics, totalUsageCount };\n }\n\n /**\n * Delete an entry\n */\n async delete(entryId: string): Promise<boolean> {\n const before = await this.count();\n await dbRun(\n this.db,\n `DELETE FROM shared_troubleshooting WHERE entry_id = ?`,\n [entryId]\n );\n const after = await this.count();\n return before > after;\n }\n\n private rowToEntry(row: Record<string, unknown>): SharedTroubleshootingEntry {\n return {\n entryId: row.entry_id as string,\n sourceProjectHash: row.source_project_hash as string,\n sourceEntryId: row.source_entry_id as string,\n title: row.title as string,\n symptoms: JSON.parse(row.symptoms as string || '[]'),\n rootCause: row.root_cause as string,\n solution: row.solution as string,\n topics: JSON.parse(row.topics as string || '[]'),\n technologies: JSON.parse(row.technologies as string || '[]'),\n confidence: row.confidence as number,\n usageCount: row.usage_count as number || 0,\n lastUsedAt: row.last_used_at ? toDate(row.last_used_at) : undefined,\n promotedAt: toDate(row.promoted_at),\n createdAt: toDate(row.created_at)\n };\n }\n}\n\nexport function createSharedStore(\n sharedEventStore: SharedEventStore\n): SharedStore {\n return new SharedStore(sharedEventStore);\n}\n", "/**\n * SharedVectorStore - Vector store for cross-project semantic search\n * Location: ~/.claude-code/memory/shared/vectors/\n */\n\nimport * as lancedb from '@lancedb/lancedb';\nimport type { SharedEntryType, SharedSearchResult } from './types.js';\n\nexport interface SharedVectorRecord {\n id: string;\n entryId: string;\n entryType: SharedEntryType;\n content: string;\n vector: number[];\n topics: string[];\n sourceProjectHash?: string;\n}\n\nexport class SharedVectorStore {\n private db: lancedb.Connection | null = null;\n private table: lancedb.Table | null = null;\n private readonly tableName = 'shared_knowledge';\n\n constructor(private dbPath: string) {}\n\n /**\n * Initialize LanceDB connection\n */\n async initialize(): Promise<void> {\n if (this.db) return;\n\n this.db = await lancedb.connect(this.dbPath);\n\n try {\n const tables = await this.db.tableNames();\n if (tables.includes(this.tableName)) {\n this.table = await this.db.openTable(this.tableName);\n }\n } catch {\n this.table = null;\n }\n }\n\n /**\n * Add or update a shared vector record\n */\n async upsert(record: SharedVectorRecord): Promise<void> {\n await this.initialize();\n\n if (!this.db) {\n throw new Error('Database not initialized');\n }\n\n const data = {\n id: record.id,\n entryId: record.entryId,\n entryType: record.entryType,\n content: record.content,\n vector: record.vector,\n topics: JSON.stringify(record.topics),\n sourceProjectHash: record.sourceProjectHash || ''\n };\n\n if (!this.table) {\n this.table = await this.db.createTable(this.tableName, [data]);\n } else {\n // Delete existing entry before adding (upsert behavior)\n try {\n await this.table.delete(`entryId = '${record.entryId}'`);\n } catch {\n // Entry might not exist, ignore\n }\n await this.table.add([data]);\n }\n }\n\n /**\n * Add multiple records in batch\n */\n async upsertBatch(records: SharedVectorRecord[]): Promise<void> {\n if (records.length === 0) return;\n\n await this.initialize();\n\n if (!this.db) {\n throw new Error('Database not initialized');\n }\n\n const data = records.map(record => ({\n id: record.id,\n entryId: record.entryId,\n entryType: record.entryType,\n content: record.content,\n vector: record.vector,\n topics: JSON.stringify(record.topics),\n sourceProjectHash: record.sourceProjectHash || ''\n }));\n\n if (!this.table) {\n this.table = await this.db.createTable(this.tableName, data);\n } else {\n await this.table.add(data);\n }\n }\n\n /**\n * Search for similar vectors\n */\n async search(\n queryVector: number[],\n options: {\n limit?: number;\n minScore?: number;\n excludeProjectHash?: string;\n entryType?: SharedEntryType;\n } = {}\n ): Promise<SharedSearchResult[]> {\n await this.initialize();\n\n if (!this.table) {\n return [];\n }\n\n const { limit = 5, minScore = 0.7, excludeProjectHash, entryType } = options;\n\n let query = this.table\n .search(queryVector)\n .distanceType('cosine')\n .limit(limit * 2);\n\n // Apply filters\n const filters: string[] = [];\n if (excludeProjectHash) {\n filters.push(`sourceProjectHash != '${excludeProjectHash}'`);\n }\n if (entryType) {\n filters.push(`entryType = '${entryType}'`);\n }\n\n if (filters.length > 0) {\n query = query.where(filters.join(' AND '));\n }\n\n const results = await query.toArray();\n\n return results\n .filter(r => {\n const distance = r._distance || 0;\n const score = 1 - (distance / 2);\n return score >= minScore;\n })\n .slice(0, limit)\n .map(r => {\n const distance = r._distance || 0;\n const score = 1 - (distance / 2);\n return {\n id: r.id as string,\n entryId: r.entryId as string,\n content: r.content as string,\n score,\n entryType: r.entryType as SharedEntryType\n };\n });\n }\n\n /**\n * Delete vector by entry ID\n */\n async delete(entryId: string): Promise<void> {\n if (!this.table) return;\n await this.table.delete(`entryId = '${entryId}'`);\n }\n\n /**\n * Get total count\n */\n async count(): Promise<number> {\n if (!this.table) return 0;\n return this.table.countRows();\n }\n\n /**\n * Check if vector exists for entry\n */\n async exists(entryId: string): Promise<boolean> {\n if (!this.table) return false;\n\n try {\n const results = await this.table\n .search([])\n .where(`entryId = '${entryId}'`)\n .limit(1)\n .toArray();\n return results.length > 0;\n } catch {\n return false;\n }\n }\n}\n\nexport function createSharedVectorStore(dbPath: string): SharedVectorStore {\n return new SharedVectorStore(dbPath);\n}\n", "/**\n * SharedPromoter - Handles auto-promotion of verified troubleshooting entries\n * Promotes entries from project-local storage to cross-project shared storage\n */\n\nimport { randomUUID } from 'crypto';\nimport { SharedStore } from './shared-store.js';\nimport { SharedVectorStore } from './shared-vector-store.js';\nimport { Embedder } from './embedder.js';\nimport type { Entry, SharedTroubleshootingInput, SharedStoreConfig } from './types.js';\n\nexport interface TroubleshootingContent {\n symptoms?: string[];\n rootCause?: string;\n solution?: string;\n technologies?: string[];\n}\n\nexport interface PromotionResult {\n success: boolean;\n entryId?: string;\n error?: string;\n skipped?: boolean;\n skipReason?: string;\n}\n\nexport class SharedPromoter {\n constructor(\n private sharedStore: SharedStore,\n private sharedVectorStore: SharedVectorStore,\n private embedder: Embedder,\n private config?: SharedStoreConfig\n ) {}\n\n /**\n * Check if an entry is eligible for promotion\n */\n isEligibleForPromotion(entry: Entry): boolean {\n // Must be troubleshooting type\n if (entry.entryType !== 'troubleshooting') {\n return false;\n }\n\n // Must be at least 'verified' stage\n if (entry.stage !== 'verified' && entry.stage !== 'certified') {\n return false;\n }\n\n // Must be active status\n if (entry.status !== 'active') {\n return false;\n }\n\n return true;\n }\n\n /**\n * Promote a verified troubleshooting entry to shared storage\n */\n async promoteEntry(\n entry: Entry,\n projectHash: string\n ): Promise<PromotionResult> {\n // Validate eligibility\n if (!this.isEligibleForPromotion(entry)) {\n return {\n success: false,\n skipped: true,\n skipReason: `Entry not eligible: type=${entry.entryType}, stage=${entry.stage}, status=${entry.status}`\n };\n }\n\n // Check if already promoted\n const exists = await this.sharedStore.exists(projectHash, entry.entryId);\n if (exists) {\n return {\n success: true,\n skipped: true,\n skipReason: 'Entry already exists in shared store'\n };\n }\n\n try {\n const content = entry.contentJson as TroubleshootingContent;\n const confidence = this.calculateConfidence(entry);\n\n // Check minimum confidence threshold\n const minConfidence = this.config?.minConfidenceForPromotion ?? 0.8;\n if (confidence < minConfidence) {\n return {\n success: false,\n skipped: true,\n skipReason: `Confidence ${confidence} below threshold ${minConfidence}`\n };\n }\n\n const input: SharedTroubleshootingInput = {\n sourceProjectHash: projectHash,\n sourceEntryId: entry.entryId,\n title: entry.title,\n symptoms: content.symptoms || [],\n rootCause: content.rootCause || '',\n solution: content.solution || '',\n topics: this.extractTopics(entry),\n technologies: content.technologies || [],\n confidence\n };\n\n // Promote to shared store\n const entryId = await this.sharedStore.promoteEntry(input);\n\n // Create embedding for vector search\n const embeddingContent = this.createEmbeddingContent(input);\n const embedding = await this.embedder.embed(embeddingContent);\n\n await this.sharedVectorStore.upsert({\n id: randomUUID(),\n entryId,\n entryType: 'troubleshooting',\n content: embeddingContent,\n vector: embedding.vector,\n topics: input.topics,\n sourceProjectHash: projectHash\n });\n\n return {\n success: true,\n entryId\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n\n /**\n * Batch promote multiple entries\n */\n async promoteEntries(\n entries: Entry[],\n projectHash: string\n ): Promise<Map<string, PromotionResult>> {\n const results = new Map<string, PromotionResult>();\n\n for (const entry of entries) {\n const result = await this.promoteEntry(entry, projectHash);\n results.set(entry.entryId, result);\n }\n\n return results;\n }\n\n /**\n * Extract topics from entry\n */\n private extractTopics(entry: Entry): string[] {\n const topics: string[] = [];\n\n // Extract from title (meaningful words)\n const titleWords = entry.title\n .toLowerCase()\n .split(/[\\s\\-_]+/)\n .filter(w => w.length > 3 && !this.isStopWord(w));\n topics.push(...titleWords);\n\n // Extract from content if available\n const content = entry.contentJson as Record<string, unknown>;\n if (content.topics && Array.isArray(content.topics)) {\n topics.push(...content.topics.map(t => String(t).toLowerCase()));\n }\n\n // Extract technologies as topics\n if (content.technologies && Array.isArray(content.technologies)) {\n topics.push(...content.technologies.map(t => String(t).toLowerCase()));\n }\n\n // Dedupe and return\n return [...new Set(topics)];\n }\n\n /**\n * Check if word is a stop word\n */\n private isStopWord(word: string): boolean {\n const stopWords = new Set([\n 'the', 'and', 'for', 'with', 'this', 'that', 'from', 'have', 'been',\n 'were', 'are', 'was', 'had', 'has', 'will', 'would', 'could', 'should',\n 'when', 'where', 'what', 'which', 'while', 'error', 'problem', 'issue'\n ]);\n return stopWords.has(word);\n }\n\n /**\n * Calculate confidence score for entry\n */\n private calculateConfidence(entry: Entry): number {\n let confidence = 0.8; // Base confidence for verified entries\n\n // Boost if certified\n if (entry.stage === 'certified') {\n confidence = 0.95;\n }\n\n // Could add more factors:\n // - Number of evidence items\n // - Age of entry (older verified entries may be more reliable)\n // - Usage count if tracked\n\n return Math.min(confidence, 1.0);\n }\n\n /**\n * Create embedding content from input\n */\n private createEmbeddingContent(input: SharedTroubleshootingInput): string {\n const parts: string[] = [];\n\n parts.push(`Problem: ${input.title}`);\n\n if (input.symptoms.length > 0) {\n parts.push(`Symptoms: ${input.symptoms.join(', ')}`);\n }\n\n if (input.rootCause) {\n parts.push(`Root Cause: ${input.rootCause}`);\n }\n\n if (input.solution) {\n parts.push(`Solution: ${input.solution}`);\n }\n\n if (input.technologies && input.technologies.length > 0) {\n parts.push(`Technologies: ${input.technologies.join(', ')}`);\n }\n\n return parts.join('\\n');\n }\n}\n\nexport function createSharedPromoter(\n sharedStore: SharedStore,\n sharedVectorStore: SharedVectorStore,\n embedder: Embedder,\n config?: SharedStoreConfig\n): SharedPromoter {\n return new SharedPromoter(sharedStore, sharedVectorStore, embedder, config);\n}\n", "/**\n * Metadata Extractor\n * Extracts tool-specific metadata from tool inputs and outputs\n */\n\nimport type { ToolMetadata } from './types.js';\n\n/**\n * Get file type from path\n */\nfunction getFileType(filePath: string): string | undefined {\n const ext = filePath.split('.').pop()?.toLowerCase();\n if (!ext) return undefined;\n\n const typeMap: Record<string, string> = {\n ts: 'typescript',\n tsx: 'typescript',\n js: 'javascript',\n jsx: 'javascript',\n py: 'python',\n rb: 'ruby',\n go: 'go',\n rs: 'rust',\n java: 'java',\n kt: 'kotlin',\n swift: 'swift',\n c: 'c',\n cpp: 'cpp',\n h: 'header',\n hpp: 'header',\n cs: 'csharp',\n php: 'php',\n html: 'html',\n css: 'css',\n scss: 'scss',\n json: 'json',\n yaml: 'yaml',\n yml: 'yaml',\n xml: 'xml',\n md: 'markdown',\n sql: 'sql',\n sh: 'shell',\n bash: 'shell',\n zsh: 'shell'\n };\n\n return typeMap[ext];\n}\n\n/**\n * Count lines in content\n */\nfunction countLines(content: string): number {\n return content.split('\\n').length;\n}\n\n/**\n * Extract bash command (without arguments that might contain secrets)\n */\nfunction extractCommand(fullCommand: string): string {\n // Get first word (command name)\n const parts = fullCommand.trim().split(/\\s+/);\n const command = parts[0];\n\n // For common commands, include safe arguments\n const safeCommands = ['git', 'npm', 'yarn', 'pnpm', 'node', 'python', 'go', 'cargo', 'make'];\n if (safeCommands.includes(command) && parts.length > 1) {\n // Include subcommand for these\n return `${command} ${parts[1]}`;\n }\n\n return command;\n}\n\n/**\n * Extract metadata from tool usage\n */\nexport function extractMetadata(\n toolName: string,\n input: Record<string, unknown>,\n output: string,\n success: boolean\n): ToolMetadata {\n switch (toolName) {\n case 'Read': {\n const filePath = input.file_path as string | undefined;\n return {\n filePath,\n fileType: filePath ? getFileType(filePath) : undefined,\n lineCount: success ? countLines(output) : undefined\n };\n }\n\n case 'Write': {\n const filePath = input.file_path as string | undefined;\n const content = input.content as string | undefined;\n return {\n filePath,\n fileType: filePath ? getFileType(filePath) : undefined,\n lineCount: content ? countLines(content) : undefined\n };\n }\n\n case 'Edit': {\n const filePath = input.file_path as string | undefined;\n return {\n filePath,\n fileType: filePath ? getFileType(filePath) : undefined\n };\n }\n\n case 'Bash': {\n const fullCommand = input.command as string | undefined;\n return {\n command: fullCommand ? extractCommand(fullCommand) : undefined\n };\n }\n\n case 'Grep': {\n const pattern = input.pattern as string | undefined;\n // Count matches from output\n const matchCount = success\n ? (output.match(/\\n/g) || []).length + (output.trim() ? 1 : 0)\n : undefined;\n return {\n pattern,\n matchCount\n };\n }\n\n case 'Glob': {\n const pattern = input.pattern as string | undefined;\n const matchCount = success\n ? (output.match(/\\n/g) || []).length + (output.trim() ? 1 : 0)\n : undefined;\n return {\n pattern,\n matchCount\n };\n }\n\n case 'WebFetch': {\n const url = input.url as string | undefined;\n // Try to extract status code from output\n const statusMatch = output.match(/status:\\s*(\\d{3})/i);\n return {\n url,\n statusCode: statusMatch ? parseInt(statusMatch[1], 10) : undefined\n };\n }\n\n case 'WebSearch': {\n return {};\n }\n\n case 'NotebookEdit': {\n const notebookPath = input.notebook_path as string | undefined;\n return {\n filePath: notebookPath,\n fileType: 'jupyter'\n };\n }\n\n default:\n return {};\n }\n}\n\n/**\n * Create embedding content for tool observation\n */\nexport function createToolObservationEmbedding(\n toolName: string,\n metadata: ToolMetadata,\n success: boolean\n): string {\n const parts: string[] = [];\n\n parts.push(`Tool: ${toolName}`);\n\n if (metadata.filePath) {\n parts.push(`File: ${metadata.filePath}`);\n }\n if (metadata.command) {\n parts.push(`Command: ${metadata.command}`);\n }\n if (metadata.pattern) {\n parts.push(`Pattern: ${metadata.pattern}`);\n }\n if (metadata.url) {\n // Only include domain for privacy\n try {\n const url = new URL(metadata.url);\n parts.push(`URL: ${url.hostname}`);\n } catch {\n // Invalid URL, skip\n }\n }\n\n parts.push(`Result: ${success ? 'Success' : 'Failed'}`);\n\n return parts.join('\\n');\n}\n", "/**\n * Working Set Store\n * Manages the active memory window for Endless Mode\n * Biomimetic: Simulates human working memory (7\u00B12 items, 15-30s duration)\n */\n\nimport { randomUUID } from 'crypto';\nimport { dbRun, dbAll, toDate, type Database } from './db-wrapper.js';\nimport type {\n MemoryEvent,\n EndlessModeConfig,\n WorkingSet,\n WorkingSetItem\n} from './types.js';\nimport { EventStore } from './event-store.js';\n\nexport class WorkingSetStore {\n constructor(\n private eventStore: EventStore,\n private config: EndlessModeConfig\n ) {}\n\n private get db(): Database {\n return this.eventStore.getDatabase();\n }\n\n /**\n * Add an event to the working set\n */\n async add(eventId: string, relevanceScore: number = 1.0, topics?: string[]): Promise<void> {\n const expiresAt = new Date(\n Date.now() + this.config.workingSet.timeWindowHours * 60 * 60 * 1000\n );\n\n await dbRun(\n this.db,\n `INSERT OR REPLACE INTO working_set (id, event_id, added_at, relevance_score, topics, expires_at)\n VALUES (?, ?, CURRENT_TIMESTAMP, ?, ?, ?)`,\n [\n randomUUID(),\n eventId,\n relevanceScore,\n JSON.stringify(topics || []),\n expiresAt.toISOString()\n ]\n );\n\n // Enforce size limit\n await this.enforceLimit();\n }\n\n /**\n * Get the current working set\n */\n async get(): Promise<WorkingSet> {\n // Clean up expired items first\n await this.cleanup();\n\n // Get working set items with their events\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT ws.*, e.*\n FROM working_set ws\n JOIN events e ON ws.event_id = e.id\n ORDER BY ws.relevance_score DESC, ws.added_at DESC\n LIMIT ?`,\n [this.config.workingSet.maxEvents]\n );\n\n const events: MemoryEvent[] = rows.map(row => ({\n id: row.id as string,\n eventType: row.event_type as 'user_prompt' | 'agent_response' | 'session_summary' | 'tool_observation',\n sessionId: row.session_id as string,\n timestamp: toDate(row.timestamp),\n content: row.content as string,\n canonicalKey: row.canonical_key as string,\n dedupeKey: row.dedupe_key as string,\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined\n }));\n\n return {\n recentEvents: events,\n lastActivity: events.length > 0 ? events[0].timestamp : new Date(),\n continuityScore: await this.calculateContinuityScore()\n };\n }\n\n /**\n * Get working set items (metadata only)\n */\n async getItems(): Promise<WorkingSetItem[]> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM working_set ORDER BY relevance_score DESC, added_at DESC`\n );\n\n return rows.map(row => ({\n id: row.id as string,\n eventId: row.event_id as string,\n addedAt: toDate(row.added_at),\n relevanceScore: row.relevance_score as number,\n topics: row.topics ? JSON.parse(row.topics as string) : undefined,\n expiresAt: toDate(row.expires_at)\n }));\n }\n\n /**\n * Update relevance score for an event\n */\n async updateRelevance(eventId: string, score: number): Promise<void> {\n await dbRun(\n this.db,\n `UPDATE working_set SET relevance_score = ? WHERE event_id = ?`,\n [score, eventId]\n );\n }\n\n /**\n * Prune specific events from working set (after consolidation)\n */\n async prune(eventIds: string[]): Promise<void> {\n if (eventIds.length === 0) return;\n\n const placeholders = eventIds.map(() => '?').join(',');\n await dbRun(\n this.db,\n `DELETE FROM working_set WHERE event_id IN (${placeholders})`,\n eventIds\n );\n }\n\n /**\n * Get the count of items in working set\n */\n async count(): Promise<number> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM working_set`\n );\n return result[0]?.count || 0;\n }\n\n /**\n * Clear the entire working set\n */\n async clear(): Promise<void> {\n await dbRun(this.db, `DELETE FROM working_set`);\n }\n\n /**\n * Check if an event is in the working set\n */\n async contains(eventId: string): Promise<boolean> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM working_set WHERE event_id = ?`,\n [eventId]\n );\n return (result[0]?.count || 0) > 0;\n }\n\n /**\n * Refresh expiration for an event (rehears al - keep relevant items longer)\n */\n async refresh(eventId: string): Promise<void> {\n const newExpiresAt = new Date(\n Date.now() + this.config.workingSet.timeWindowHours * 60 * 60 * 1000\n );\n\n await dbRun(\n this.db,\n `UPDATE working_set SET expires_at = ? WHERE event_id = ?`,\n [newExpiresAt.toISOString(), eventId]\n );\n }\n\n /**\n * Clean up expired items\n */\n private async cleanup(): Promise<void> {\n await dbRun(\n this.db,\n `DELETE FROM working_set WHERE expires_at < datetime('now')`\n );\n }\n\n /**\n * Enforce the maximum size limit\n * Removes lowest relevance items when over limit\n */\n private async enforceLimit(): Promise<void> {\n const maxEvents = this.config.workingSet.maxEvents;\n\n // Get IDs to keep (highest relevance, most recent)\n const keepIds = await dbAll<{ id: string }>(\n this.db,\n `SELECT id FROM working_set\n ORDER BY relevance_score DESC, added_at DESC\n LIMIT ?`,\n [maxEvents]\n );\n\n if (keepIds.length === 0) return;\n\n const keepIdList = keepIds.map(r => r.id);\n const placeholders = keepIdList.map(() => '?').join(',');\n\n // Delete everything not in the keep list\n await dbRun(\n this.db,\n `DELETE FROM working_set WHERE id NOT IN (${placeholders})`,\n keepIdList\n );\n }\n\n /**\n * Calculate continuity score based on recent context transitions\n */\n private async calculateContinuityScore(): Promise<number> {\n const result = await dbAll<{ avg_score: number | null }>(\n this.db,\n `SELECT AVG(continuity_score) as avg_score\n FROM continuity_log\n WHERE created_at > datetime('now', '-1 hour')`\n );\n\n return result[0]?.avg_score ?? 0.5;\n }\n\n /**\n * Get topics from current working set for context matching\n */\n async getActiveTopics(): Promise<string[]> {\n const rows = await dbAll<{ topics: string }>(\n this.db,\n `SELECT topics FROM working_set WHERE topics IS NOT NULL`\n );\n\n const allTopics = new Set<string>();\n for (const row of rows) {\n const topics = JSON.parse(row.topics) as string[];\n topics.forEach(t => allTopics.add(t));\n }\n\n return Array.from(allTopics);\n }\n}\n\n/**\n * Create a Working Set Store instance\n */\nexport function createWorkingSetStore(\n eventStore: EventStore,\n config: EndlessModeConfig\n): WorkingSetStore {\n return new WorkingSetStore(eventStore, config);\n}\n", "/**\n * Consolidated Store\n * Manages long-term integrated memories for Endless Mode\n * Biomimetic: Simulates memory consolidation that occurs during sleep\n */\n\nimport { randomUUID } from 'crypto';\nimport { dbRun, dbAll, toDate, type Database } from './db-wrapper.js';\nimport type {\n ConsolidatedMemory,\n ConsolidatedMemoryInput,\n ConsolidationRule,\n ConsolidationRuleInput\n} from './types.js';\nimport { EventStore } from './event-store.js';\n\nexport class ConsolidatedStore {\n constructor(private eventStore: EventStore) {}\n\n private get db(): Database {\n return this.eventStore.getDatabase();\n }\n\n /**\n * Create a new consolidated memory\n */\n async create(input: ConsolidatedMemoryInput): Promise<string> {\n const memoryId = randomUUID();\n\n await dbRun(\n this.db,\n `INSERT INTO consolidated_memories\n (memory_id, summary, topics, source_events, confidence, created_at)\n VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)`,\n [\n memoryId,\n input.summary,\n JSON.stringify(input.topics),\n JSON.stringify(input.sourceEvents),\n input.confidence\n ]\n );\n\n return memoryId;\n }\n\n /**\n * Get a consolidated memory by ID\n */\n async get(memoryId: string): Promise<ConsolidatedMemory | null> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories WHERE memory_id = ?`,\n [memoryId]\n );\n\n if (rows.length === 0) return null;\n return this.rowToMemory(rows[0]);\n }\n\n /**\n * Search consolidated memories by query (simple text search)\n */\n async search(query: string, options?: { topK?: number }): Promise<ConsolidatedMemory[]> {\n const topK = options?.topK || 5;\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories\n WHERE summary LIKE ?\n ORDER BY confidence DESC\n LIMIT ?`,\n [`%${query}%`, topK]\n );\n\n return rows.map(this.rowToMemory);\n }\n\n /**\n * Search by topics\n */\n async searchByTopics(topics: string[], options?: { topK?: number }): Promise<ConsolidatedMemory[]> {\n const topK = options?.topK || 5;\n\n // Build topic filter\n const topicConditions = topics.map(() => `topics LIKE ?`).join(' OR ');\n const topicParams = topics.map(t => `%\"${t}\"%`);\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories\n WHERE ${topicConditions}\n ORDER BY confidence DESC\n LIMIT ?`,\n [...topicParams, topK]\n );\n\n return rows.map(this.rowToMemory);\n }\n\n /**\n * Get all consolidated memories ordered by confidence\n */\n async getAll(options?: { limit?: number }): Promise<ConsolidatedMemory[]> {\n const limit = options?.limit || 100;\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories\n ORDER BY confidence DESC, created_at DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToMemory);\n }\n\n /**\n * Get recently created memories\n */\n async getRecent(options?: { limit?: number; hours?: number }): Promise<ConsolidatedMemory[]> {\n const limit = options?.limit || 10;\n const hours = options?.hours || 24;\n\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories\n WHERE created_at > datetime('now', '-${hours} hours')\n ORDER BY created_at DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToMemory);\n }\n\n /**\n * Mark a memory as accessed (tracks usage for importance scoring)\n */\n async markAccessed(memoryId: string): Promise<void> {\n await dbRun(\n this.db,\n `UPDATE consolidated_memories\n SET accessed_at = CURRENT_TIMESTAMP,\n access_count = access_count + 1\n WHERE memory_id = ?`,\n [memoryId]\n );\n }\n\n /**\n * Update confidence score for a memory\n */\n async updateConfidence(memoryId: string, confidence: number): Promise<void> {\n await dbRun(\n this.db,\n `UPDATE consolidated_memories\n SET confidence = ?\n WHERE memory_id = ?`,\n [confidence, memoryId]\n );\n }\n\n /**\n * Delete a consolidated memory\n */\n async delete(memoryId: string): Promise<void> {\n await dbRun(\n this.db,\n `DELETE FROM consolidated_memories WHERE memory_id = ?`,\n [memoryId]\n );\n }\n\n /**\n * Create a long-term rule promoted from stable summaries\n */\n async createRule(input: ConsolidationRuleInput): Promise<string> {\n const ruleId = randomUUID();\n\n await dbRun(\n this.db,\n `INSERT INTO consolidated_rules\n (rule_id, rule, topics, source_memory_ids, source_events, confidence, created_at)\n VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)`,\n [\n ruleId,\n input.rule,\n JSON.stringify(input.topics),\n JSON.stringify(input.sourceMemoryIds),\n JSON.stringify(input.sourceEvents),\n input.confidence\n ]\n );\n\n return ruleId;\n }\n\n async getRules(options?: { limit?: number }): Promise<ConsolidationRule[]> {\n const limit = options?.limit || 100;\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_rules ORDER BY confidence DESC, created_at DESC LIMIT ?`,\n [limit]\n );\n\n return rows.map((row) => ({\n ruleId: row.rule_id as string,\n rule: row.rule as string,\n topics: JSON.parse((row.topics as string) || '[]'),\n sourceMemoryIds: JSON.parse((row.source_memory_ids as string) || '[]'),\n sourceEvents: JSON.parse((row.source_events as string) || '[]'),\n confidence: Number(row.confidence ?? 0.5),\n createdAt: toDate(row.created_at) || new Date()\n }));\n }\n\n async countRules(): Promise<number> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM consolidated_rules`\n );\n return result[0]?.count || 0;\n }\n\n async hasRuleForSourceMemory(memoryId: string): Promise<boolean> {\n const rows = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM consolidated_rules WHERE source_memory_ids LIKE ?`,\n [`%\"${memoryId}\"%`]\n );\n return (rows[0]?.count || 0) > 0;\n }\n\n /**\n * Get count of consolidated memories\n */\n async count(): Promise<number> {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM consolidated_memories`\n );\n return result[0]?.count || 0;\n }\n\n /**\n * Get most accessed memories (for importance scoring)\n */\n async getMostAccessed(limit: number = 10): Promise<ConsolidatedMemory[]> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM consolidated_memories\n WHERE access_count > 0\n ORDER BY access_count DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(this.rowToMemory);\n }\n\n /**\n * Get statistics about consolidated memories\n */\n async getStats(): Promise<{\n total: number;\n averageConfidence: number;\n topicCounts: Record<string, number>;\n recentCount: number;\n }> {\n const total = await this.count();\n\n const avgResult = await dbAll<{ avg: number | null }>(\n this.db,\n `SELECT AVG(confidence) as avg FROM consolidated_memories`\n );\n const averageConfidence = avgResult[0]?.avg || 0;\n\n const recentResult = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM consolidated_memories\n WHERE created_at > datetime('now', '-24 hours')`\n );\n const recentCount = recentResult[0]?.count || 0;\n\n // Get topic counts\n const allMemories = await this.getAll({ limit: 1000 });\n const topicCounts: Record<string, number> = {};\n for (const memory of allMemories) {\n for (const topic of memory.topics) {\n topicCounts[topic] = (topicCounts[topic] || 0) + 1;\n }\n }\n\n return {\n total,\n averageConfidence,\n topicCounts,\n recentCount\n };\n }\n\n /**\n * Check if source events are already consolidated\n */\n async isAlreadyConsolidated(eventIds: string[]): Promise<boolean> {\n for (const eventId of eventIds) {\n const result = await dbAll<{ count: number }>(\n this.db,\n `SELECT COUNT(*) as count FROM consolidated_memories\n WHERE source_events LIKE ?`,\n [`%\"${eventId}\"%`]\n );\n if ((result[0]?.count || 0) > 0) return true;\n }\n return false;\n }\n\n /**\n * Get the last consolidation time\n */\n async getLastConsolidationTime(): Promise<Date | null> {\n const result = await dbAll<{ created_at: string }>(\n this.db,\n `SELECT created_at FROM consolidated_memories\n ORDER BY created_at DESC\n LIMIT 1`\n );\n\n if (result.length === 0) return null;\n return new Date(result[0].created_at);\n }\n\n /**\n * Convert database row to ConsolidatedMemory\n */\n private rowToMemory(row: Record<string, unknown>): ConsolidatedMemory {\n return {\n memoryId: row.memory_id as string,\n summary: row.summary as string,\n topics: JSON.parse(row.topics as string || '[]'),\n sourceEvents: JSON.parse(row.source_events as string || '[]'),\n confidence: row.confidence as number,\n createdAt: toDate(row.created_at),\n accessedAt: row.accessed_at ? toDate(row.accessed_at) : undefined,\n accessCount: row.access_count as number || 0\n };\n }\n}\n\n/**\n * Create a Consolidated Store instance\n */\nexport function createConsolidatedStore(eventStore: EventStore): ConsolidatedStore {\n return new ConsolidatedStore(eventStore);\n}\n", "/**\n * Consolidation Worker\n * Periodically consolidates working set into long-term memory\n * Biomimetic: Simulates memory consolidation during sleep/idle periods\n */\n\nimport type {\n EndlessModeConfig,\n MemoryEvent,\n EventGroup,\n WorkingSet,\n ConsolidationCostQualityReport\n} from './types.js';\nimport { WorkingSetStore } from './working-set-store.js';\nimport { ConsolidatedStore } from './consolidated-store.js';\n\nexport class ConsolidationWorker {\n private running = false;\n private timeout: NodeJS.Timeout | null = null;\n private lastActivity: Date = new Date();\n\n constructor(\n private workingSetStore: WorkingSetStore,\n private consolidatedStore: ConsolidatedStore,\n private config: EndlessModeConfig\n ) {}\n\n /**\n * Start the consolidation worker\n */\n start(): void {\n if (this.running) return;\n this.running = true;\n this.scheduleNext();\n }\n\n /**\n * Stop the consolidation worker\n */\n stop(): void {\n this.running = false;\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n }\n\n /**\n * Record activity (resets idle timer)\n */\n recordActivity(): void {\n this.lastActivity = new Date();\n }\n\n /**\n * Check if currently running\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Force a consolidation run (manual trigger)\n */\n async forceRun(): Promise<number> {\n const out = await this.consolidateWithReport();\n return out.consolidatedCount;\n }\n\n /**\n * Force a consolidation run and return metrics report\n */\n async forceRunWithReport(): Promise<{\n consolidatedCount: number;\n promotedRuleCount: number;\n report: ConsolidationCostQualityReport;\n }> {\n return this.consolidateWithReport();\n }\n\n /**\n * Schedule the next consolidation check\n */\n private scheduleNext(): void {\n if (!this.running) return;\n\n this.timeout = setTimeout(\n () => this.run(),\n this.config.consolidation.triggerIntervalMs\n );\n }\n\n /**\n * Run consolidation check\n */\n private async run(): Promise<void> {\n if (!this.running) return;\n\n try {\n await this.checkAndConsolidate();\n } catch (error) {\n console.error('Consolidation error:', error);\n }\n\n this.scheduleNext();\n }\n\n /**\n * Check conditions and consolidate if needed\n */\n private async checkAndConsolidate(): Promise<void> {\n const workingSet = await this.workingSetStore.get();\n\n if (!this.shouldConsolidate(workingSet)) {\n return;\n }\n\n await this.consolidate();\n }\n\n /**\n * Perform consolidation\n */\n private async consolidate(): Promise<number> {\n const out = await this.consolidateWithReport();\n return out.consolidatedCount;\n }\n\n private async consolidateWithReport(): Promise<{\n consolidatedCount: number;\n promotedRuleCount: number;\n report: ConsolidationCostQualityReport;\n }> {\n const workingSet = await this.workingSetStore.get();\n\n if (workingSet.recentEvents.length < 3) {\n return {\n consolidatedCount: 0,\n promotedRuleCount: 0,\n report: this.buildCostQualityReport(workingSet.recentEvents, [], 0)\n };\n }\n\n // Group events by topic\n const groups = this.groupByTopic(workingSet.recentEvents);\n let consolidatedCount = 0;\n const createdMemoryIds: string[] = [];\n\n for (const group of groups) {\n // Require minimum 3 events per group\n if (group.events.length < 3) continue;\n\n // Check if already consolidated\n const eventIds = group.events.map(e => e.id);\n const alreadyConsolidated = await this.consolidatedStore.isAlreadyConsolidated(eventIds);\n if (alreadyConsolidated) continue;\n\n // Generate summary\n const summary = await this.summarize(group);\n\n // Create consolidated memory\n const memoryId = await this.consolidatedStore.create({\n summary,\n topics: group.topics,\n sourceEvents: eventIds,\n confidence: this.calculateConfidence(group)\n });\n createdMemoryIds.push(memoryId);\n consolidatedCount++;\n }\n\n const promotedRuleCount = await this.promoteStableSummariesToRules(createdMemoryIds);\n\n // Prune consolidated events from working set\n if (consolidatedCount > 0) {\n const consolidatedEventIds = groups\n .filter(g => g.events.length >= 3)\n .flatMap(g => g.events.map(e => e.id));\n\n // Only prune old events (keep recent for context)\n const oldEventIds = consolidatedEventIds.filter(id => {\n const event = workingSet.recentEvents.find(e => e.id === id);\n if (!event) return false;\n const ageHours = (Date.now() - event.timestamp.getTime()) / (1000 * 60 * 60);\n return ageHours > this.config.workingSet.timeWindowHours / 2;\n });\n\n if (oldEventIds.length > 0) {\n await this.workingSetStore.prune(oldEventIds);\n }\n }\n\n const report = this.buildCostQualityReport(workingSet.recentEvents, groups, consolidatedCount);\n return { consolidatedCount, promotedRuleCount, report };\n }\n\n private async promoteStableSummariesToRules(memoryIds: string[]): Promise<number> {\n let promoted = 0;\n\n for (const memoryId of memoryIds) {\n const memory = await this.consolidatedStore.get(memoryId);\n if (!memory) continue;\n if (memory.confidence < 0.55) continue;\n if (memory.sourceEvents.length < 4) continue;\n\n const exists = await this.consolidatedStore.hasRuleForSourceMemory(memoryId);\n if (exists) continue;\n\n const rule = this.buildRuleFromSummary(memory.summary, memory.topics);\n if (!rule) continue;\n\n await this.consolidatedStore.createRule({\n rule,\n topics: memory.topics,\n sourceMemoryIds: [memory.memoryId],\n sourceEvents: memory.sourceEvents,\n confidence: Math.min(1, memory.confidence + 0.08)\n });\n promoted++;\n }\n\n return promoted;\n }\n\n private buildRuleFromSummary(summary: string, topics: string[]): string | null {\n const lines = summary\n .split(/\\r?\\n/)\n .map((l) => l.trim())\n .filter(Boolean)\n .filter((l) => !l.toLowerCase().startsWith('topics:'));\n\n const bullet = lines.find((l) => l.startsWith('- '))?.replace(/^-\\s*/, '');\n const seed = bullet || lines[0];\n if (!seed || seed.length < 8) return null;\n\n const topicPrefix = topics.length > 0 ? `[${topics.slice(0, 2).join(', ')}] ` : '';\n return `${topicPrefix}${seed}`;\n }\n\n private buildCostQualityReport(\n events: MemoryEvent[],\n groups: EventGroup[],\n consolidatedCount: number\n ): ConsolidationCostQualityReport {\n const beforeTokenEstimate = events.reduce((acc, e) => acc + this.estimateTokens(e.content), 0);\n\n const afterSummaries = groups\n .filter((g) => g.events.length >= 3)\n .slice(0, Math.max(consolidatedCount, 1));\n\n const afterTokenEstimate = afterSummaries.length > 0\n ? afterSummaries.reduce((acc, g) => acc + this.estimateTokens(this.ruleBasedSummary(g)), 0)\n : beforeTokenEstimate;\n\n const reductionRatio = beforeTokenEstimate > 0\n ? Math.max(0, (beforeTokenEstimate - afterTokenEstimate) / beforeTokenEstimate)\n : 0;\n\n const qualityGuardPassed = consolidatedCount === 0\n ? true\n : groups.filter((g) => g.events.length >= 3).every((g) => this.calculateConfidence(g) >= 0.55);\n\n return {\n beforeTokenEstimate,\n afterTokenEstimate,\n reductionRatio,\n qualityGuardPassed,\n details: `groups=${groups.length}, consolidated=${consolidatedCount}`\n };\n }\n\n private estimateTokens(text: string): number {\n return Math.ceil((text || '').length / 4);\n }\n\n /**\n * Check if consolidation should run\n */\n private shouldConsolidate(workingSet: WorkingSet): boolean {\n // Check event count trigger\n if (workingSet.recentEvents.length >= this.config.consolidation.triggerEventCount) {\n return true;\n }\n\n // Check idle time trigger\n const idleTime = Date.now() - this.lastActivity.getTime();\n if (idleTime >= this.config.consolidation.triggerIdleMs) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Group events by topic using simple keyword extraction\n */\n private groupByTopic(events: MemoryEvent[]): EventGroup[] {\n const groups = new Map<string, EventGroup>();\n\n for (const event of events) {\n const topics = this.extractTopics(event.content);\n\n for (const topic of topics) {\n if (!groups.has(topic)) {\n groups.set(topic, { topics: [topic], events: [] });\n }\n const group = groups.get(topic)!;\n if (!group.events.find(e => e.id === event.id)) {\n group.events.push(event);\n }\n }\n }\n\n // Merge groups with overlapping events\n const mergedGroups = this.mergeOverlappingGroups(Array.from(groups.values()));\n\n return mergedGroups;\n }\n\n /**\n * Extract topics from content using simple keyword extraction\n */\n private extractTopics(content: string): string[] {\n const topics: string[] = [];\n\n // Extract code-related keywords\n const codePatterns = [\n /\\b(function|class|interface|type|const|let|var)\\s+(\\w+)/gi,\n /\\b(import|export)\\s+.*?from\\s+['\"]([^'\"]+)['\"]/gi,\n /\\bfile[:\\s]+([^\\s,]+)/gi\n ];\n\n for (const pattern of codePatterns) {\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const keyword = match[2] || match[1];\n if (keyword && keyword.length > 2) {\n topics.push(keyword.toLowerCase());\n }\n }\n }\n\n // Extract common programming terms\n const commonTerms = [\n 'bug', 'fix', 'error', 'issue', 'feature',\n 'test', 'refactor', 'implement', 'add', 'remove',\n 'update', 'change', 'modify', 'create', 'delete'\n ];\n\n const contentLower = content.toLowerCase();\n for (const term of commonTerms) {\n if (contentLower.includes(term)) {\n topics.push(term);\n }\n }\n\n return [...new Set(topics)].slice(0, 5); // Limit to 5 topics\n }\n\n /**\n * Merge groups that have significant event overlap\n */\n private mergeOverlappingGroups(groups: EventGroup[]): EventGroup[] {\n const merged: EventGroup[] = [];\n\n for (const group of groups) {\n let foundMerge = false;\n\n for (const existing of merged) {\n const overlap = group.events.filter(e =>\n existing.events.some(ex => ex.id === e.id)\n );\n\n // If > 50% overlap, merge\n if (overlap.length > group.events.length / 2) {\n existing.topics = [...new Set([...existing.topics, ...group.topics])];\n for (const event of group.events) {\n if (!existing.events.find(e => e.id === event.id)) {\n existing.events.push(event);\n }\n }\n foundMerge = true;\n break;\n }\n }\n\n if (!foundMerge) {\n merged.push(group);\n }\n }\n\n return merged;\n }\n\n /**\n * Generate summary for a group of events\n * Rule-based extraction (no LLM by default)\n */\n private async summarize(group: EventGroup): Promise<string> {\n if (this.config.consolidation.useLLMSummarization) {\n // Future: LLM-based summarization\n return this.ruleBasedSummary(group);\n }\n\n return this.ruleBasedSummary(group);\n }\n\n /**\n * Rule-based summary generation\n */\n private ruleBasedSummary(group: EventGroup): string {\n const keyPoints: string[] = [];\n\n for (const event of group.events.slice(0, 10)) {\n const keyPoint = this.extractKeyPoint(event.content);\n if (keyPoint) {\n keyPoints.push(keyPoint);\n }\n }\n\n const topicsStr = group.topics.slice(0, 3).join(', ');\n const summary = [\n `Topics: ${topicsStr}`,\n '',\n 'Key points:',\n ...keyPoints.map(kp => `- ${kp}`)\n ].join('\\n');\n\n return summary;\n }\n\n /**\n * Extract key point from content\n */\n private extractKeyPoint(content: string): string | null {\n // Get first meaningful sentence\n const sentences = content.split(/[.!?\\n]+/).filter(s => s.trim().length > 10);\n if (sentences.length === 0) return null;\n\n const firstSentence = sentences[0].trim();\n\n // Truncate if too long\n if (firstSentence.length > 100) {\n return firstSentence.slice(0, 100) + '...';\n }\n\n return firstSentence;\n }\n\n /**\n * Calculate confidence score for a group\n */\n private calculateConfidence(group: EventGroup): number {\n // Factor 1: Event count (more events = higher confidence)\n const eventScore = Math.min(group.events.length / 10, 1);\n\n // Factor 2: Time proximity (events closer together = higher confidence)\n const timeScore = this.calculateTimeProximity(group.events);\n\n // Factor 3: Topic consistency (fewer topics per event = higher confidence)\n const topicScore = Math.min(3 / group.topics.length, 1);\n\n return (eventScore * 0.4 + timeScore * 0.4 + topicScore * 0.2);\n }\n\n /**\n * Calculate time proximity score\n */\n private calculateTimeProximity(events: MemoryEvent[]): number {\n if (events.length < 2) return 1;\n\n const timestamps = events.map(e => e.timestamp.getTime()).sort((a, b) => a - b);\n const timeSpan = timestamps[timestamps.length - 1] - timestamps[0];\n\n // Score based on average time between events\n const avgGap = timeSpan / (events.length - 1);\n const hourInMs = 60 * 60 * 1000;\n\n // Within 1 hour average = score 1, 24 hours = score 0.5, etc.\n return Math.max(0, 1 - (avgGap / (24 * hourInMs)));\n }\n}\n\n/**\n * Create a Consolidation Worker instance\n */\nexport function createConsolidationWorker(\n workingSetStore: WorkingSetStore,\n consolidatedStore: ConsolidatedStore,\n config: EndlessModeConfig\n): ConsolidationWorker {\n return new ConsolidationWorker(workingSetStore, consolidatedStore, config);\n}\n", "/**\n * Continuity Manager\n * Tracks and calculates context continuity between interactions\n * Biomimetic: Simulates context-dependent memory retrieval\n */\n\nimport { randomUUID } from 'crypto';\nimport { dbRun, dbAll, toDate, type Database } from './db-wrapper.js';\nimport type {\n EndlessModeConfig,\n ContextSnapshot,\n ContinuityScore,\n TransitionType,\n ContinuityLog\n} from './types.js';\nimport { EventStore } from './event-store.js';\n\nexport class ContinuityManager {\n private lastContext: ContextSnapshot | null = null;\n\n constructor(\n private eventStore: EventStore,\n private config: EndlessModeConfig\n ) {}\n\n private get db(): Database {\n return this.eventStore.getDatabase();\n }\n\n /**\n * Calculate continuity score between current and previous context\n */\n async calculateScore(\n currentContext: ContextSnapshot,\n previousContext?: ContextSnapshot\n ): Promise<ContinuityScore> {\n const prev = previousContext || this.lastContext;\n\n if (!prev) {\n // No previous context - this is a fresh start\n this.lastContext = currentContext;\n return { score: 0.5, transitionType: 'break' };\n }\n\n let score = 0;\n\n // Topic continuity (30%)\n const topicOverlap = this.calculateOverlap(\n currentContext.topics,\n prev.topics\n );\n score += topicOverlap * 0.3;\n\n // File continuity (20%)\n const fileOverlap = this.calculateOverlap(\n currentContext.files,\n prev.files\n );\n score += fileOverlap * 0.2;\n\n // Time proximity (30%)\n const timeDiff = currentContext.timestamp - prev.timestamp;\n const decayHours = this.config.continuity.topicDecayHours;\n const timeScore = Math.exp(-timeDiff / (decayHours * 3600000));\n score += timeScore * 0.3;\n\n // Entity continuity (20%)\n const entityOverlap = this.calculateOverlap(\n currentContext.entities,\n prev.entities\n );\n score += entityOverlap * 0.2;\n\n // Determine transition type\n const transitionType = this.determineTransitionType(score);\n\n // Log the transition\n await this.logTransition(currentContext, prev, score, transitionType);\n\n // Update last context\n this.lastContext = currentContext;\n\n return { score, transitionType };\n }\n\n /**\n * Create a context snapshot from current state\n */\n createSnapshot(\n id: string,\n content: string,\n metadata?: {\n files?: string[];\n entities?: string[];\n }\n ): ContextSnapshot {\n return {\n id,\n timestamp: Date.now(),\n topics: this.extractTopics(content),\n files: metadata?.files || this.extractFiles(content),\n entities: metadata?.entities || this.extractEntities(content)\n };\n }\n\n /**\n * Get recent continuity logs\n */\n async getRecentLogs(limit: number = 10): Promise<ContinuityLog[]> {\n const rows = await dbAll<Record<string, unknown>>(\n this.db,\n `SELECT * FROM continuity_log\n ORDER BY created_at DESC\n LIMIT ?`,\n [limit]\n );\n\n return rows.map(row => ({\n logId: row.log_id as string,\n fromContextId: row.from_context_id as string | undefined,\n toContextId: row.to_context_id as string | undefined,\n continuityScore: row.continuity_score as number,\n transitionType: row.transition_type as TransitionType,\n createdAt: toDate(row.created_at)\n }));\n }\n\n /**\n * Get average continuity score over time period\n */\n async getAverageScore(hours: number = 1): Promise<number> {\n const result = await dbAll<{ avg_score: number | null }>(\n this.db,\n `SELECT AVG(continuity_score) as avg_score\n FROM continuity_log\n WHERE created_at > datetime('now', '-${hours} hours')`\n );\n\n return result[0]?.avg_score ?? 0.5;\n }\n\n /**\n * Get transition type distribution\n */\n async getTransitionStats(hours: number = 24): Promise<Record<TransitionType, number>> {\n const rows = await dbAll<{ transition_type: string; count: number }>(\n this.db,\n `SELECT transition_type, COUNT(*) as count\n FROM continuity_log\n WHERE created_at > datetime('now', '-${hours} hours')\n GROUP BY transition_type`\n );\n\n const stats: Record<TransitionType, number> = {\n seamless: 0,\n topic_shift: 0,\n break: 0\n };\n\n for (const row of rows) {\n stats[row.transition_type as TransitionType] = row.count;\n }\n\n return stats;\n }\n\n /**\n * Clear old continuity logs\n */\n async cleanup(olderThanDays: number = 7): Promise<number> {\n const result = await dbAll<{ changes: number }>(\n this.db,\n `DELETE FROM continuity_log\n WHERE created_at < datetime('now', '-${olderThanDays} days')\n RETURNING COUNT(*) as changes`\n );\n\n return result[0]?.changes || 0;\n }\n\n /**\n * Calculate overlap between two arrays\n */\n private calculateOverlap(a: string[], b: string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n\n const setA = new Set(a.map(s => s.toLowerCase()));\n const setB = new Set(b.map(s => s.toLowerCase()));\n\n const intersection = [...setA].filter(x => setB.has(x));\n const union = new Set([...setA, ...setB]);\n\n return intersection.length / union.size; // Jaccard similarity\n }\n\n /**\n * Determine transition type based on score\n */\n private determineTransitionType(score: number): TransitionType {\n if (score >= this.config.continuity.minScoreForSeamless) {\n return 'seamless';\n } else if (score >= 0.4) {\n return 'topic_shift';\n } else {\n return 'break';\n }\n }\n\n /**\n * Log a context transition\n */\n private async logTransition(\n current: ContextSnapshot,\n previous: ContextSnapshot,\n score: number,\n type: TransitionType\n ): Promise<void> {\n await dbRun(\n this.db,\n `INSERT INTO continuity_log\n (log_id, from_context_id, to_context_id, continuity_score, transition_type, created_at)\n VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)`,\n [randomUUID(), previous.id, current.id, score, type]\n );\n }\n\n /**\n * Extract topics from content\n */\n private extractTopics(content: string): string[] {\n const topics: string[] = [];\n const contentLower = content.toLowerCase();\n\n // Programming language keywords\n const langPatterns = [\n { pattern: /typescript|\\.ts\\b/i, topic: 'typescript' },\n { pattern: /javascript|\\.js\\b/i, topic: 'javascript' },\n { pattern: /python|\\.py\\b/i, topic: 'python' },\n { pattern: /rust|\\.rs\\b/i, topic: 'rust' },\n { pattern: /go\\b|golang/i, topic: 'go' }\n ];\n\n for (const { pattern, topic } of langPatterns) {\n if (pattern.test(content)) {\n topics.push(topic);\n }\n }\n\n // Common development topics\n const devTopics = [\n 'api', 'database', 'test', 'bug', 'feature', 'refactor',\n 'component', 'function', 'class', 'module', 'hook',\n 'deploy', 'build', 'config', 'docker', 'git'\n ];\n\n for (const topic of devTopics) {\n if (contentLower.includes(topic)) {\n topics.push(topic);\n }\n }\n\n return [...new Set(topics)].slice(0, 10);\n }\n\n /**\n * Extract file paths from content\n */\n private extractFiles(content: string): string[] {\n const filePatterns = [\n /(?:^|\\s)([a-zA-Z0-9_\\-./]+\\.[a-zA-Z0-9]+)(?:\\s|$|:)/gm,\n /['\"](\\.?\\/[^'\"]+\\.[a-zA-Z0-9]+)['\"]/g,\n /file[:\\s]+([^\\s,]+)/gi\n ];\n\n const files = new Set<string>();\n\n for (const pattern of filePatterns) {\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const file = match[1];\n if (file && file.length > 3 && file.length < 100) {\n // Filter out common non-file patterns\n if (!file.match(/^(https?:|mailto:|ftp:)/i)) {\n files.add(file);\n }\n }\n }\n }\n\n return Array.from(files).slice(0, 10);\n }\n\n /**\n * Extract entity names from content (functions, classes, variables)\n */\n private extractEntities(content: string): string[] {\n const entities = new Set<string>();\n\n const entityPatterns = [\n /\\b(function|const|let|var|class|interface|type)\\s+([a-zA-Z_][a-zA-Z0-9_]*)/g,\n /\\b([A-Z][a-zA-Z0-9_]*(?:Component|Service|Store|Manager|Handler|Factory|Provider))\\b/g,\n /\\b(use[A-Z][a-zA-Z0-9_]*)\\b/g // React hooks\n ];\n\n for (const pattern of entityPatterns) {\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const entity = match[2] || match[1];\n if (entity && entity.length > 2) {\n entities.add(entity);\n }\n }\n }\n\n return Array.from(entities).slice(0, 20);\n }\n\n /**\n * Reset the last context (for testing or manual reset)\n */\n resetLastContext(): void {\n this.lastContext = null;\n }\n\n /**\n * Get the last context snapshot\n */\n getLastContext(): ContextSnapshot | null {\n return this.lastContext;\n }\n}\n\n/**\n * Create a Continuity Manager instance\n */\nexport function createContinuityManager(\n eventStore: EventStore,\n config: EndlessModeConfig\n): ContinuityManager {\n return new ContinuityManager(eventStore, config);\n}\n", "/**\n * Graduation Worker\n * Periodically evaluates memory events for promotion to higher levels\n * L0 \u2192 L1 \u2192 L2 \u2192 L3 \u2192 L4 based on access patterns and confidence\n */\n\nimport type { MemoryLevel } from './types.js';\nimport { EventStore } from './event-store.js';\nimport { GraduationPipeline } from './graduation.js';\n\nexport interface GraduationWorkerConfig {\n /** How often to run graduation evaluation (ms) */\n evaluationIntervalMs: number;\n /** Batch size for graduation evaluation */\n batchSize: number;\n /** Minimum time between evaluations of the same event (ms) */\n cooldownMs: number;\n}\n\nconst DEFAULT_CONFIG: GraduationWorkerConfig = {\n evaluationIntervalMs: 300000, // 5 minutes\n batchSize: 50,\n cooldownMs: 3600000 // 1 hour cooldown between evaluations\n};\n\nexport class GraduationWorker {\n private running = false;\n private timeout: NodeJS.Timeout | null = null;\n private lastEvaluated: Map<string, number> = new Map();\n\n constructor(\n private eventStore: EventStore,\n private graduation: GraduationPipeline,\n private config: GraduationWorkerConfig = DEFAULT_CONFIG\n ) {}\n\n /**\n * Start the graduation worker\n */\n start(): void {\n if (this.running) return;\n this.running = true;\n this.scheduleNext();\n }\n\n /**\n * Stop the graduation worker\n */\n stop(): void {\n this.running = false;\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n }\n\n /**\n * Check if currently running\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Force a graduation evaluation run\n */\n async forceRun(): Promise<GraduationRunResult> {\n return await this.runGraduation();\n }\n\n /**\n * Schedule the next graduation check\n */\n private scheduleNext(): void {\n if (!this.running) return;\n\n this.timeout = setTimeout(\n () => this.run(),\n this.config.evaluationIntervalMs\n );\n }\n\n /**\n * Run graduation evaluation\n */\n private async run(): Promise<void> {\n if (!this.running) return;\n\n try {\n await this.runGraduation();\n } catch (error) {\n console.error('Graduation error:', error);\n }\n\n this.scheduleNext();\n }\n\n /**\n * Perform graduation evaluation across all levels\n */\n private async runGraduation(): Promise<GraduationRunResult> {\n const result: GraduationRunResult = {\n evaluated: 0,\n graduated: 0,\n byLevel: {}\n };\n\n const levels: MemoryLevel[] = ['L0', 'L1', 'L2', 'L3'];\n const now = Date.now();\n\n for (const level of levels) {\n const events = await this.eventStore.getEventsByLevel(level, {\n limit: this.config.batchSize\n });\n\n let levelGraduated = 0;\n\n for (const event of events) {\n // Check cooldown\n const lastEval = this.lastEvaluated.get(event.id);\n if (lastEval && (now - lastEval) < this.config.cooldownMs) {\n continue;\n }\n\n result.evaluated++;\n this.lastEvaluated.set(event.id, now);\n\n const gradResult = await this.graduation.evaluateGraduation(event.id, level);\n\n if (gradResult.success) {\n result.graduated++;\n levelGraduated++;\n }\n }\n\n if (levelGraduated > 0) {\n result.byLevel[level] = levelGraduated;\n }\n }\n\n // Clean up old cooldown entries (keep last 1000)\n if (this.lastEvaluated.size > 1000) {\n const entries = Array.from(this.lastEvaluated.entries());\n entries.sort((a, b) => b[1] - a[1]);\n this.lastEvaluated = new Map(entries.slice(0, 1000));\n }\n\n return result;\n }\n}\n\nexport interface GraduationRunResult {\n evaluated: number;\n graduated: number;\n byLevel: Record<string, number>;\n}\n\n/**\n * Create a Graduation Worker instance\n */\nexport function createGraduationWorker(\n eventStore: EventStore,\n graduation: GraduationPipeline,\n config?: Partial<GraduationWorkerConfig>\n): GraduationWorker {\n return new GraduationWorker(\n eventStore,\n graduation,\n { ...DEFAULT_CONFIG, ...config }\n );\n}\n", "import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { MemoryEventInput } from './types.js';\n\nfunction sanitizeSegment(input: string | undefined, fallback: string): string {\n const v = (input || '').trim().toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');\n return v || fallback;\n}\n\nfunction getAtPath(obj: Record<string, unknown> | undefined, dotted: string): unknown {\n if (!obj) return undefined;\n return dotted.split('.').reduce<unknown>((acc, key) => {\n if (!acc || typeof acc !== 'object') return undefined;\n return (acc as Record<string, unknown>)[key];\n }, obj);\n}\n\nexport function buildMirrorPath(rootDir: string, event: MemoryEventInput): string {\n const meta = event.metadata as Record<string, unknown> | undefined;\n\n const namespaceRaw = getAtPath(meta, 'namespace') ?? getAtPath(meta, 'scope.namespace') ?? event.eventType;\n const namespace = sanitizeSegment(typeof namespaceRaw === 'string' ? namespaceRaw : undefined, 'general');\n\n const categoryRaw = getAtPath(meta, 'categoryPath') ?? getAtPath(meta, 'scope.categoryPath');\n const categoryPath = Array.isArray(categoryRaw) && categoryRaw.length > 0\n ? categoryRaw.map((x) => sanitizeSegment(typeof x === 'string' ? x : undefined, 'uncategorized'))\n : ['uncategorized'];\n\n const d = event.timestamp;\n const yyyy = d.getFullYear();\n const mm = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n\n return path.join(rootDir, 'memory', namespace, ...categoryPath, `${yyyy}-${mm}-${dd}.md`);\n}\n\nexport class MarkdownMirror {\n constructor(private readonly rootDir: string) {}\n\n async append(event: MemoryEventInput, eventId?: string): Promise<void> {\n const out = buildMirrorPath(this.rootDir, event);\n fs.mkdirSync(path.dirname(out), { recursive: true });\n\n const lines = [\n '',\n `## ${event.timestamp.toISOString()} | ${eventId ?? 'pending-id'}`,\n `- type: ${event.eventType}`,\n `- session: ${event.sessionId}`,\n event.content,\n ];\n\n await fs.promises.appendFile(out, lines.join('\\n'), 'utf8');\n await this.refreshIndex();\n }\n\n private async refreshIndex(): Promise<void> {\n const memoryRoot = path.join(this.rootDir, 'memory');\n await fs.promises.mkdir(memoryRoot, { recursive: true });\n\n const files: string[] = [];\n await this.walk(memoryRoot, files);\n\n const mdFiles = files\n .filter((f) => f.endsWith('.md'))\n .map((f) => path.relative(this.rootDir, f))\n .filter((rel) => rel !== path.join('memory', '_index.md'))\n .sort();\n\n const index = [\n '# Memory Index',\n '',\n 'Generated automatically by MarkdownMirror.',\n '',\n ...mdFiles.map((rel) => `- ${rel}`),\n '',\n ].join('\\n');\n\n await fs.promises.writeFile(path.join(memoryRoot, '_index.md'), index, 'utf8');\n }\n\n private async walk(dir: string, out: string[]): Promise<void> {\n const entries = await fs.promises.readdir(dir, { withFileTypes: true });\n for (const e of entries) {\n const full = path.join(dir, e.name);\n if (e.isDirectory()) {\n await this.walk(full, out);\n } else {\n out.push(full);\n }\n }\n }\n}\n", "import type { MemoryEventInput } from './types.js';\n\nexport type IngestStage = 'before' | 'after' | 'error';\n\nexport interface IngestContext {\n stage: IngestStage;\n operation: 'user_prompt' | 'agent_response' | 'session_summary' | 'tool_observation';\n sessionId: string;\n event: MemoryEventInput;\n error?: Error;\n}\n\nexport type IngestInterceptor = (context: IngestContext) => Promise<void> | void;\n\nexport class IngestInterceptorRegistry {\n private before: IngestInterceptor[] = [];\n private after: IngestInterceptor[] = [];\n private onError: IngestInterceptor[] = [];\n\n registerBefore(interceptor: IngestInterceptor): () => void {\n this.before.push(interceptor);\n return () => {\n this.before = this.before.filter((i) => i !== interceptor);\n };\n }\n\n registerAfter(interceptor: IngestInterceptor): () => void {\n this.after.push(interceptor);\n return () => {\n this.after = this.after.filter((i) => i !== interceptor);\n };\n }\n\n registerOnError(interceptor: IngestInterceptor): () => void {\n this.onError.push(interceptor);\n return () => {\n this.onError = this.onError.filter((i) => i !== interceptor);\n };\n }\n\n async run(stage: IngestStage, context: Omit<IngestContext, 'stage'>): Promise<void> {\n const interceptors = stage === 'before'\n ? this.before\n : stage === 'after'\n ? this.after\n : this.onError;\n\n for (const interceptor of interceptors) {\n await interceptor({ ...context, stage });\n }\n }\n}\n\nexport function mergeHierarchicalMetadata(\n base: Record<string, unknown> | undefined,\n patch: Record<string, unknown> | undefined\n): Record<string, unknown> | undefined {\n if (!base && !patch) return undefined;\n if (!base) return patch;\n if (!patch) return base;\n\n const result: Record<string, unknown> = { ...base };\n\n for (const [key, value] of Object.entries(patch)) {\n const current = result[key];\n if (\n typeof current === 'object' && current !== null && !Array.isArray(current) &&\n typeof value === 'object' && value !== null && !Array.isArray(value)\n ) {\n result[key] = mergeHierarchicalMetadata(\n current as Record<string, unknown>,\n value as Record<string, unknown>\n );\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n", "export const TAG_NAMESPACES = {\n SYSTEM: 'sys:',\n QUALITY: 'q:',\n PROJECT: 'proj:',\n TOPIC: 'topic:',\n TEMPORAL: 't:',\n USER: 'user:',\n AGENT: 'agent:'\n} as const;\n\nexport const VALID_TAG_NAMESPACES = new Set<string>(Object.values(TAG_NAMESPACES));\n\nexport function parseTag(tag: string): { namespace?: string; value: string } {\n const value = (tag || '').trim();\n const idx = value.indexOf(':');\n if (idx <= 0) return { value };\n\n const namespace = `${value.slice(0, idx)}:`;\n const tagValue = value.slice(idx + 1);\n if (!tagValue) return { value };\n\n return { namespace, value: tagValue };\n}\n\nexport function validateTag(tag: string): boolean {\n const normalized = (tag || '').trim();\n if (!normalized) return false;\n\n const { namespace } = parseTag(normalized);\n if (!namespace) return true; // backward compatibility for legacy tags\n return VALID_TAG_NAMESPACES.has(namespace);\n}\n\nexport function withNamespace(value: string, namespace: string): string {\n const clean = parseTag(value).value.trim();\n return `${namespace}${clean}`;\n}\n\nexport function normalizeTags(tags: unknown): string[] {\n if (!Array.isArray(tags)) return [];\n\n const dedup = new Set<string>();\n for (const item of tags) {\n if (typeof item !== 'string') continue;\n const normalized = item.trim();\n if (!validateTag(normalized)) continue;\n dedup.add(normalized);\n }\n\n return [...dedup];\n}\n", "import { spawn } from 'child_process';\nimport * as fs from 'fs';\nimport * as net from 'net';\nimport * as os from 'os';\nimport * as path from 'path';\n\ninterface SemanticRequest {\n sessionId: string;\n prompt: string;\n topK: number;\n minScore: number;\n}\n\ninterface SemanticMemory {\n type: string;\n content: string;\n id?: string;\n score?: number;\n}\n\ninterface SemanticDaemonRequest {\n type: 'retrieve';\n sessionId: string;\n prompt: string;\n topK: number;\n minScore: number;\n}\n\ninterface SemanticDaemonResponse {\n ok: boolean;\n memories?: SemanticMemory[];\n error?: string;\n}\n\nconst DEFAULT_SOCKET_PATH = path.join(\n os.homedir(),\n '.claude-code',\n 'memory',\n 'semantic-daemon.sock'\n);\n\nconst DAEMON_SOCKET_PATH = process.env.CLAUDE_MEMORY_SEMANTIC_SOCKET || DEFAULT_SOCKET_PATH;\nconst DAEMON_START_TIMEOUT_MS = parseInt(process.env.CLAUDE_MEMORY_SEMANTIC_DAEMON_START_MS || '1500');\n\nlet daemonStartPromise: Promise<void> | null = null;\n\nexport async function retrieveSemanticMemories(\n request: SemanticRequest,\n timeoutMs: number\n): Promise<SemanticMemory[]> {\n const payload: SemanticDaemonRequest = {\n type: 'retrieve',\n sessionId: request.sessionId,\n prompt: request.prompt,\n topK: request.topK,\n minScore: request.minScore\n };\n\n try {\n return await requestFromDaemon(payload, timeoutMs);\n } catch (error) {\n if (!isConnectionError(error)) {\n throw error;\n }\n\n await ensureDaemonRunning();\n return requestFromDaemon(payload, timeoutMs).catch((retryError) => {\n if (process.env.CLAUDE_MEMORY_DEBUG) {\n console.error('[semantic-client] retry failed after daemon start:', retryError);\n }\n throw retryError;\n });\n }\n}\n\nfunction requestFromDaemon(\n payload: SemanticDaemonRequest,\n timeoutMs: number\n): Promise<SemanticMemory[]> {\n return new Promise((resolve, reject) => {\n const client = net.createConnection(DAEMON_SOCKET_PATH);\n client.setEncoding('utf8');\n\n let settled = false;\n let responseRaw = '';\n const timer = setTimeout(() => {\n const timeoutError = new Error(`semantic daemon timeout (${timeoutMs}ms)`);\n (timeoutError as NodeJS.ErrnoException).code = 'ETIMEDOUT';\n settle(timeoutError);\n client.destroy();\n }, timeoutMs);\n\n const settle = (error?: Error, memories?: SemanticMemory[]) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (error) {\n reject(error);\n } else {\n resolve(memories || []);\n }\n };\n\n client.on('connect', () => {\n client.end(JSON.stringify(payload));\n });\n\n client.on('data', (chunk) => {\n responseRaw += chunk;\n if (responseRaw.length > 4 * 1024 * 1024) {\n settle(new Error('semantic daemon response too large'));\n client.destroy();\n }\n });\n\n client.on('end', () => {\n try {\n const parsed = JSON.parse(responseRaw || '{}') as SemanticDaemonResponse;\n if (!parsed.ok) {\n settle(new Error(parsed.error || 'semantic daemon error'));\n return;\n }\n settle(undefined, parsed.memories || []);\n } catch (error) {\n settle(error as Error);\n }\n });\n\n client.on('error', (error) => {\n settle(error as Error);\n });\n });\n}\n\nexport async function ensureDaemonRunning(): Promise<void> {\n if (daemonStartPromise) {\n return daemonStartPromise;\n }\n\n daemonStartPromise = (async () => {\n if (await canConnect()) {\n return;\n }\n\n const daemonScriptPath = getDaemonScriptPath();\n if (!fs.existsSync(daemonScriptPath)) {\n throw new Error(`semantic daemon script not found: ${daemonScriptPath}`);\n }\n\n const daemonDir = path.dirname(DAEMON_SOCKET_PATH);\n if (!fs.existsSync(daemonDir)) {\n fs.mkdirSync(daemonDir, { recursive: true });\n }\n\n const child = spawn(process.execPath, [daemonScriptPath], {\n detached: true,\n stdio: 'ignore',\n env: process.env\n });\n child.unref();\n\n const startDeadline = Date.now() + DAEMON_START_TIMEOUT_MS;\n while (Date.now() < startDeadline) {\n if (await canConnect()) {\n return;\n }\n await sleep(60);\n }\n\n throw new Error(`semantic daemon start timeout (${DAEMON_START_TIMEOUT_MS}ms)`);\n })();\n\n try {\n await daemonStartPromise;\n } finally {\n daemonStartPromise = null;\n }\n}\n\nfunction getDaemonScriptPath(): string {\n return path.join(path.dirname(new URL(import.meta.url).pathname), 'semantic-daemon.js');\n}\n\nfunction canConnect(): Promise<boolean> {\n return new Promise((resolve) => {\n let settled = false;\n const client = net.createConnection(DAEMON_SOCKET_PATH);\n const finalize = (ok: boolean) => {\n if (settled) return;\n settled = true;\n client.destroy();\n resolve(ok);\n };\n\n client.on('connect', () => finalize(true));\n client.on('error', () => finalize(false));\n setTimeout(() => finalize(false), 120).unref();\n });\n}\n\nfunction isConnectionError(error: unknown): boolean {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n return code === 'ENOENT' || code === 'ECONNREFUSED' || code === 'EPIPE' || code === 'ECONNRESET';\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n", "#!/usr/bin/env node\n/**\n * Session Start Hook\n * Called when a new Claude Code session starts\n */\n\nimport {\n getLightweightMemoryService,\n registerSession\n} from '../services/memory-service.js';\nimport { ensureDaemonRunning } from './semantic-daemon-client.js';\nimport type { SessionStartInput, SessionStartOutput } from '../core/types.js';\n\nasync function main(): Promise<void> {\n // Read input from stdin\n const inputData = await readStdin();\n const input: SessionStartInput = JSON.parse(inputData);\n\n // Register session with project path for other hooks to find\n registerSession(input.session_id, input.cwd);\n\n // Start semantic daemon in the background (non-blocking) so VectorWorker\n // can process any pending embedding_outbox items immediately.\n ensureDaemonRunning().catch(() => {\n // Ignore - daemon will start on first prompt if needed\n });\n\n // Use lightweight service to avoid starting background workers in hook process\n const memoryService = getLightweightMemoryService(input.session_id);\n\n try {\n // Start session in memory service\n await memoryService.startSession(input.session_id, input.cwd);\n\n // Get recent context for this project (now automatically scoped)\n const recentEvents = await memoryService.getRecentEvents(10);\n\n let context = '';\n if (recentEvents.length > 0) {\n context = `## Previous Session Context\\n\\nYou have worked on this project before. Here are some relevant memories:\\n\\n`;\n for (const event of recentEvents.slice(0, 3)) {\n const date = event.timestamp.toISOString().split('T')[0];\n context += `- **${date}**: ${event.content.slice(0, 150)}...\\n`;\n }\n }\n\n const output: SessionStartOutput = { context };\n console.log(JSON.stringify(output));\n } catch (error) {\n console.error('Memory hook error:', error);\n console.log(JSON.stringify({ context: '' }));\n } finally {\n try {\n await memoryService.close();\n } catch {\n // Best-effort cleanup\n }\n }\n}\n\nfunction readStdin(): Promise<string> {\n return new Promise((resolve) => {\n let data = '';\n process.stdin.setEncoding('utf8');\n process.stdin.on('data', (chunk) => {\n data += chunk;\n });\n process.stdin.on('end', () => {\n resolve(data);\n });\n });\n}\n\nmain().catch(console.error);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["path", "fs", "crypto", "path", "resolve", "randomUUID", "path", "fs", "randomUUID", "resolve", "DEFAULT_CONFIG", "DEFAULT_CONFIG", "DEFAULT_CONFIG", "filtered", "path", "randomUUID", "randomUUID", "lancedb", "randomUUID", "randomUUID", "randomUUID", "randomUUID", "randomUUID", "randomUUID", "randomUUID", "DEFAULT_CONFIG", "fs", "path", "sanitizeSegment", "buildMirrorPath", "MarkdownMirror", "MarkdownMirror", "fs", "os", "path", "resolve", "resolve", "resolve"]
|
|
7
7
|
}
|