/** * Memory Bank - Persistent storage for evolved fragments * * Stores fragments with: * - Temporal metadata (when evolved, from which sessions) * - Source links (provenance to exact messages) * - Searchable index for fractal-grep */ import type { SourceLink, Conversation } from './session-parser.js'; import type { AllFragments, VocabularyFragment } from './schemas.js'; export interface MemoryEntry { /** When this entry was created/updated */ timestamp: Date; /** Which sessions contributed to this entry */ sessionIds: string[]; /** The evolved fragments */ fragments: AllFragments; } export interface MemoryIndex { /** Version for future migrations */ version: number; /** When the index was last updated */ lastUpdated: Date; /** Per-project memory entries */ projects: Record; /** Global vocabulary across all projects */ globalVocabulary: VocabularyFragment | null; /** Cursor: timestamp of oldest unprocessed session */ processingCursor?: Date; /** Global configuration settings */ config?: GlobalConfig; } export interface GlobalConfig { /** Should verbatim artifacts be generated? */ artifacts?: boolean; /** Where should artifacts be stored? 'vault' or 'local' */ mirrorMode?: 'vault' | 'local'; /** File extensions to index for source code search */ sourceExtensions?: string[]; /** Automatically re-index source during 'evolve' when git HEAD changes */ autoIndexSource?: boolean; /** Cosine similarity threshold for vector search (0.0-1.0) */ vectorThreshold?: number; /** API key for Jina embeddings (global fallback) */ jinaApiKey?: string; /** API key for OpenRouter LLM (global fallback) */ openRouterApiKey?: string; /** Generic LLM API key (global fallback) */ llmApiKey?: string; } export interface SessionProcessingState { sessionId: string; /** Number of messages processed */ messageCount: number; /** File modification time when last processed */ modifiedTime: Date; /** File size in bytes when last processed (for fast append-only check) */ fileSize?: number; } export interface ProjectMemory { /** Project path/name */ project: string; /** Current evolved fragments for this project (result of horizontal evolution) */ current: AllFragments; /** When last updated */ lastUpdated: Date; /** Sessions that have been processed (with state for incremental updates) */ processedSessions: SessionProcessingState[]; /** Absolute path to project root */ rootPath?: string; /** Per-session fragment snapshots (for horizontal evolution) */ sessionSnapshots: Array<{ sessionId: string; timestamp: Date; fragments: AllFragments; }>; /** Historical snapshots (optional, for time travel) */ history?: MemorySnapshot[]; /** Projects linked for cross-project context injection */ linkedProjects?: string[]; } export interface MemorySnapshot { timestamp: Date; fragments: AllFragments; sessionId: string; } /** * Get the default memory storage directory */ export declare function getMemoryDir(): string; /** * Get the path to the memory index file */ export declare function getIndexPath(): string; /** * Check if the memory vault is a Git repository */ export declare function isVaultRepo(): boolean; /** * Commit changes to the memory vault if it's a Git repo */ export declare function commitToVault(message: string): void; /** * Sanitize a file path into a project name string. * Replaces both / and \ with - and removes leading dash. */ export declare function sanitizePath(path: string): string; export declare function getProjectMemoryPath(projectName: string): string; /** * Get the path to a project's vector file */ export declare function getProjectVectorPath(projectName: string): string; /** * Generate a stable hash for a fragment */ export declare function calculateFragmentHash(type: string, content: string, context?: string): string; export declare function getSourceManifestPath(projectName: string): string; export declare function getSourceVectorPath(projectName: string): string; export interface ChronicleEntry { ts: string; emoji?: string; title: string; body?: string; } export declare function getChroniclePath(projectName: string): string; export declare function loadChronicle(projectName: string): ChronicleEntry[]; export declare function appendChronicleEntry(projectName: string, entry: ChronicleEntry): void; /** * Load the memory index */ export declare function loadMemoryIndex(): MemoryIndex; /** * Get effective global configuration (Env > Saved Config > Defaults) */ /** Default file extensions for source code indexing */ export declare const DEFAULT_SOURCE_EXTENSIONS: string[]; /** Default cosine similarity threshold for vector search */ export declare const DEFAULT_VECTOR_THRESHOLD = 0.6; export declare function getGlobalConfig(): GlobalConfig; /** * Save global configuration settings */ export declare function saveGlobalConfig(config: GlobalConfig): void; /** * Get API key with priority: environment variable > global config * @param keyType - 'jina' | 'openrouter' | 'llm' * @returns API key or undefined if not found */ export declare function getApiKey(keyType: 'jina' | 'openrouter' | 'llm'): string | undefined; export declare function loadSourceManifest(projectName: string): any | null; export declare function saveSourceManifest(manifest: any): void; export declare function loadSourceVectors(projectName: string): number[][]; export declare function saveSourceVectors(projectName: string, vectors: number[][]): void; /** * Save the memory index */ export declare function saveMemoryIndex(index: MemoryIndex): void; /** * Load a project's memory */ export declare function loadProjectMemory(projectName: string): ProjectMemory | null; /** * Save a project's memory */ export declare function saveProjectMemory(memory: ProjectMemory): void; /** * Load a project's vectors */ export declare function loadProjectVectors(projectName: string): Record; /** * Save a project's vectors */ export declare function saveProjectVectors(projectName: string, vectors: Record): void; /** * Create a new project memory */ export declare function createProjectMemory(project: string): ProjectMemory; /** * Update project memory with new evolved fragments from a session * This stores the session's fragments as a snapshot for horizontal evolution */ export declare function updateProjectMemory(memory: ProjectMemory, fragments: AllFragments, sessionId: string, messageCount: number, modifiedTime: Date, fileSize?: number, rootPath?: string): ProjectMemory; /** * Update the current (horizontally evolved) fragments */ export declare function updateCurrentFragments(memory: ProjectMemory, current: AllFragments): ProjectMemory; /** * Check if a session needs processing (new or has new messages) */ export declare function getSessionProcessingState(memory: ProjectMemory | null, sessionId: string): SessionProcessingState | null; /** * Check if a session needs (re)processing * Returns true if: never processed, or has new messages since last processing */ /** * Fast check using file size (no parsing needed for append-only JSONL) */ export declare function sessionNeedsProcessingFast(memory: ProjectMemory | null, sessionId: string, currentFileSize: number): boolean; /** * Full check (requires parsing - use sessionNeedsProcessingFast first) */ export declare function sessionNeedsProcessing(memory: ProjectMemory | null, sessionId: string, currentMessageCount: number, currentModifiedTime: Date): boolean; /** * Legacy check - kept for backwards compatibility */ export declare function isSessionProcessed(memory: ProjectMemory | null, sessionId: string): boolean; export interface SearchResult { project: string; type: 'decision' | 'insight' | 'gotcha' | 'narrative' | 'quote' | 'source'; content: string; context?: string; score: number; timestamp?: Date; sourceLink?: SourceLink; filePath?: string; } export declare function searchMemory(query: string, options?: { projects?: string[]; types?: SearchResult['type'][]; limit?: number; jinaApiKey?: string; all?: boolean; }): Promise; /** * Generate a Markdown context file from project memory * This can be symlinked as a Claude Code slash command */ export declare function generateContextMarkdown(projectName: string): string | null; /** * Redact sensitive information like API keys and tokens from a string */ export declare function redactSecrets(text: string): string; /** * Generate a verbatim Markdown record of a session */ export declare function generateVerbatimMarkdown(conversation: Conversation): string; /** * Write a verbatim session artifact to the Vault (default) or specified directory */ export declare function writeVerbatimSessionArtifact(conversation: Conversation, outputDir?: string): string; /** * Generate a Markdown summary for a single session snapshot */ export declare function generateSessionMarkdown(snapshot: { sessionId: string; timestamp: Date | string; fragments: AllFragments; }, projectName: string): string; /** * Export a session snapshot as a Markdown artifact (Summarized version) * Note: We are moving towards verbatim mirroring as the primary artifact. */ export declare function exportSessionSnapshotArtifact(snapshot: { sessionId: string; timestamp: Date | string; fragments: AllFragments; }, projectName: string, outputDir: string): string; /** * Write context markdown to a file (for slash command symlink) */ export declare function writeContextFile(projectName: string, outputPath: string): boolean; /** * Get memory statistics */ export declare function getMemoryStats(): { totalProjects: number; totalDecisions: number; totalInsights: number; totalSessions: number; lastUpdated: Date | null; }; //# sourceMappingURL=memory.d.ts.map