raggrep 0.1.0 → 0.1.3

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/utils/embeddings.ts", "../../src/domain/entities/config.ts", "../../src/domain/entities/index.ts", "../../src/utils/config.ts", "../../src/domain/services/bm25.ts", "../../src/modules/semantic/parseCode.ts", "../../src/domain/services/keywords.ts", "../../src/utils/tieredIndex.ts", "../../src/modules/semantic/index.ts", "../../src/modules/registry.ts", "../../src/indexer/index.ts", "../../src/search/index.ts", "../../src/cli/main.ts"],
3
+ "sources": ["../../src/utils/embeddings.ts", "../../src/domain/entities/config.ts", "../../src/domain/entities/index.ts", "../../src/utils/config.ts", "../../src/domain/services/bm25.ts", "../../src/modules/semantic/parseCode.ts", "../../src/domain/services/keywords.ts", "../../src/utils/tieredIndex.ts", "../../src/modules/semantic/index.ts", "../../src/modules/registry.ts", "../../src/indexer/watcher.ts", "../../src/indexer/index.ts", "../../src/search/index.ts", "../../src/cli/main.ts"],
4
4
  "sourcesContent": [
5
5
  "// Local embedding provider using Transformers.js\n// Models are automatically downloaded and cached on first use\n\nimport { pipeline, env, type FeatureExtractionPipeline } from '@xenova/transformers';\nimport * as path from 'path';\nimport * as os from 'os';\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\n// Configure cache directory for models\n// Uses ~/.cache/raggrep/models by default\nconst CACHE_DIR = path.join(os.homedir(), '.cache', 'raggrep', 'models');\n\n// Set the cache directory for transformers.js\nenv.cacheDir = CACHE_DIR;\n\n// Disable local model check (always try to use cache first, then download)\nenv.allowLocalModels = true;\n\n// Available embedding models (smaller = faster, larger = better quality)\nexport const EMBEDDING_MODELS = {\n // Default: Good balance of speed and quality (~33M params, 384 dimensions)\n 'all-MiniLM-L6-v2': 'Xenova/all-MiniLM-L6-v2',\n \n // Higher quality, slightly slower (~33M params, 384 dimensions)\n 'all-MiniLM-L12-v2': 'Xenova/all-MiniLM-L12-v2',\n \n // BGE small - good for code (~33M params, 384 dimensions)\n 'bge-small-en-v1.5': 'Xenova/bge-small-en-v1.5',\n \n // Even smaller/faster option (~22M params, 384 dimensions)\n 'paraphrase-MiniLM-L3-v2': 'Xenova/paraphrase-MiniLM-L3-v2',\n} as const;\n\nexport type EmbeddingModelName = keyof typeof EMBEDDING_MODELS;\n\n// ============================================================================\n// Embedding Provider\n// ============================================================================\n\nlet embeddingPipeline: FeatureExtractionPipeline | null = null;\nlet currentModelName: string | null = null;\nlet isInitializing = false;\nlet initPromise: Promise<void> | null = null;\n\nexport interface EmbeddingConfig {\n model: EmbeddingModelName;\n /** Show progress during model download */\n showProgress?: boolean;\n}\n\nconst DEFAULT_CONFIG: EmbeddingConfig = {\n model: 'all-MiniLM-L6-v2',\n showProgress: true,\n};\n\nlet currentConfig: EmbeddingConfig = { ...DEFAULT_CONFIG };\n\n/**\n * Configure the embedding model\n */\nexport function configureEmbeddings(config: Partial<EmbeddingConfig>): void {\n const newConfig = { ...currentConfig, ...config };\n \n // If model changed, reset pipeline\n if (newConfig.model !== currentConfig.model) {\n embeddingPipeline = null;\n currentModelName = null;\n }\n \n currentConfig = newConfig;\n}\n\n/**\n * Initialize the embedding pipeline (downloads model if needed)\n */\nasync function initializePipeline(): Promise<void> {\n if (embeddingPipeline && currentModelName === currentConfig.model) {\n return;\n }\n \n // Prevent multiple simultaneous initializations\n if (isInitializing && initPromise) {\n return initPromise;\n }\n \n isInitializing = true;\n \n initPromise = (async () => {\n const modelId = EMBEDDING_MODELS[currentConfig.model];\n \n if (currentConfig.showProgress) {\n console.log(`\\n Loading embedding model: ${currentConfig.model}`);\n console.log(` Cache: ${CACHE_DIR}`);\n }\n \n try {\n // Create the feature extraction pipeline\n // This will download the model on first run\n embeddingPipeline = await pipeline('feature-extraction', modelId, {\n progress_callback: currentConfig.showProgress \n ? (progress: { status: string; file?: string; progress?: number; loaded?: number; total?: number }) => {\n if (progress.status === 'progress' && progress.file) {\n const pct = progress.progress ? Math.round(progress.progress) : 0;\n process.stdout.write(`\\r Downloading ${progress.file}: ${pct}% `);\n } else if (progress.status === 'done' && progress.file) {\n process.stdout.write(`\\r Downloaded ${progress.file} \\n`);\n } else if (progress.status === 'ready') {\n // Model is ready\n }\n }\n : undefined,\n });\n \n currentModelName = currentConfig.model;\n \n if (currentConfig.showProgress) {\n console.log(` Model ready.\\n`);\n }\n } catch (error) {\n embeddingPipeline = null;\n currentModelName = null;\n throw new Error(`Failed to load embedding model: ${error}`);\n } finally {\n isInitializing = false;\n initPromise = null;\n }\n })();\n \n return initPromise;\n}\n\n/**\n * Get embedding for a single text\n */\nexport async function getEmbedding(text: string): Promise<number[]> {\n await initializePipeline();\n \n if (!embeddingPipeline) {\n throw new Error('Embedding pipeline not initialized');\n }\n \n // Get embeddings using mean pooling\n const output = await embeddingPipeline(text, {\n pooling: 'mean',\n normalize: true,\n });\n \n // Convert to array\n return Array.from(output.data as Float32Array);\n}\n\n/** Maximum number of texts to process in a single batch */\nconst BATCH_SIZE = 32;\n\n/**\n * Get embeddings for multiple texts (batched for efficiency)\n * \n * Processes texts in batches of BATCH_SIZE for better performance\n * while avoiding memory issues with very large batches.\n * \n * @param texts - Array of texts to embed\n * @returns Array of embedding vectors\n */\nexport async function getEmbeddings(texts: string[]): Promise<number[][]> {\n if (texts.length === 0) return [];\n \n await initializePipeline();\n \n if (!embeddingPipeline) {\n throw new Error('Embedding pipeline not initialized');\n }\n \n const results: number[][] = [];\n \n // Process in batches for efficiency\n for (let i = 0; i < texts.length; i += BATCH_SIZE) {\n const batch = texts.slice(i, i + BATCH_SIZE);\n \n // Process batch - transformers.js handles array inputs\n const outputs = await Promise.all(\n batch.map(async (text) => {\n const output = await embeddingPipeline!(text, {\n pooling: 'mean',\n normalize: true,\n });\n return Array.from(output.data as Float32Array);\n })\n );\n \n results.push(...outputs);\n }\n \n return results;\n}\n\n// ============================================================================\n// Vector Math\n// ============================================================================\n\n/**\n * Calculate cosine similarity between two vectors\n */\nexport function cosineSimilarity(a: number[], b: number[]): number {\n if (a.length !== b.length) {\n throw new Error('Vectors must have the same length');\n }\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n if (normA === 0 || normB === 0) return 0;\n\n return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));\n}\n\n/**\n * Get current embedding configuration\n */\nexport function getEmbeddingConfig(): EmbeddingConfig {\n return { ...currentConfig };\n}\n\n/**\n * Get the cache directory path\n */\nexport function getCacheDir(): string {\n return CACHE_DIR;\n}\n\n/**\n * Check if a model is already cached\n */\nexport async function isModelCached(model: EmbeddingModelName = currentConfig.model): Promise<boolean> {\n const modelId = EMBEDDING_MODELS[model];\n const modelPath = path.join(CACHE_DIR, modelId.replace('/', '--'));\n \n try {\n const fs = await import('fs/promises');\n await fs.access(modelPath);\n return true;\n } catch {\n return false;\n }\n}\n",
6
6
  "/**\n * Config Entity\n * \n * Configuration for RAGgrep indexing and search operations.\n */\n\n/**\n * Configuration for a specific index module.\n */\nexport interface ModuleConfig {\n /** Unique module identifier */\n id: string;\n \n /** Whether the module is enabled */\n enabled: boolean;\n \n /** Module-specific options */\n options?: Record<string, unknown>;\n}\n\n/**\n * Main RAGgrep configuration.\n */\nexport interface Config {\n /** RAGgrep version */\n version: string;\n \n /** Directory name for index storage (default: '.raggrep') */\n indexDir: string;\n \n /** File extensions to index (e.g., ['.ts', '.tsx', '.js']) */\n extensions: string[];\n \n /** Paths to ignore during indexing */\n ignorePaths: string[];\n \n /** Enabled modules and their configurations */\n modules: ModuleConfig[];\n}\n\n/**\n * Default paths to ignore during indexing.\n */\nexport const DEFAULT_IGNORE_PATHS = [\n // Package managers & dependencies\n 'node_modules',\n '.pnpm-store',\n '.yarn',\n 'vendor',\n \n // Version control\n '.git',\n \n // Build outputs\n 'dist',\n 'build',\n 'out',\n '.output',\n 'target',\n \n // Framework-specific build outputs\n '.next',\n '.nuxt',\n '.svelte-kit',\n '.vercel',\n '.netlify',\n \n // Caches\n '.cache',\n '.turbo',\n '.parcel-cache',\n '.eslintcache',\n \n // Test & coverage\n 'coverage',\n '.nyc_output',\n \n // Python\n '__pycache__',\n '.venv',\n 'venv',\n '.pytest_cache',\n '*.egg-info',\n \n // IDE & editor\n '.idea',\n \n // RAGgrep index\n '.raggrep',\n];\n\n/**\n * Default file extensions to index.\n */\nexport const DEFAULT_EXTENSIONS = [\n '.ts', '.tsx', '.js', '.jsx',\n '.py', '.go', '.rs', '.java', '.md',\n];\n\n/**\n * Create a default configuration.\n */\nexport function createDefaultConfig(): Config {\n return {\n version: '0.1.0',\n indexDir: '.raggrep',\n extensions: DEFAULT_EXTENSIONS,\n ignorePaths: DEFAULT_IGNORE_PATHS,\n modules: [\n {\n id: 'semantic',\n enabled: true,\n options: {\n embeddingModel: 'all-MiniLM-L6-v2',\n },\n },\n ],\n };\n}\n\n",
@@ -8,15 +8,16 @@
8
8
  "/**\n * Configuration utilities\n * \n * Provides functions for loading, saving, and managing RAGgrep configuration.\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs/promises';\nimport type { Config, ModuleConfig } from '../domain/entities';\nimport { createDefaultConfig } from '../domain/entities';\nimport { EmbeddingConfig, EmbeddingModelName, EMBEDDING_MODELS } from './embeddings';\n\n/** Default configuration instance */\nexport const DEFAULT_CONFIG: Config = createDefaultConfig();\n\n/**\n * Get the root .raggrep directory path\n */\nexport function getRaggrepDir(rootDir: string, config: Config = DEFAULT_CONFIG): string {\n return path.join(rootDir, config.indexDir);\n}\n\n/**\n * Get the index data directory for a specific module\n */\nexport function getModuleIndexPath(rootDir: string, moduleId: string, config: Config = DEFAULT_CONFIG): string {\n return path.join(rootDir, config.indexDir, 'index', moduleId);\n}\n\n/**\n * Get the manifest path for a specific module\n */\nexport function getModuleManifestPath(rootDir: string, moduleId: string, config: Config = DEFAULT_CONFIG): string {\n return path.join(rootDir, config.indexDir, 'index', moduleId, 'manifest.json');\n}\n\n/**\n * Get the global manifest path\n */\nexport function getGlobalManifestPath(rootDir: string, config: Config = DEFAULT_CONFIG): string {\n return path.join(rootDir, config.indexDir, 'manifest.json');\n}\n\n/**\n * Get the config file path\n */\nexport function getConfigPath(rootDir: string, config: Config = DEFAULT_CONFIG): string {\n return path.join(rootDir, config.indexDir, 'config.json');\n}\n\n/**\n * Load config from file or return default\n */\nexport async function loadConfig(rootDir: string): Promise<Config> {\n const configPath = getConfigPath(rootDir, DEFAULT_CONFIG);\n \n try {\n const content = await fs.readFile(configPath, 'utf-8');\n const savedConfig = JSON.parse(content) as Partial<Config>;\n return { ...DEFAULT_CONFIG, ...savedConfig };\n } catch {\n return DEFAULT_CONFIG;\n }\n}\n\n/**\n * Save config to file\n */\nexport async function saveConfig(rootDir: string, config: Config): Promise<void> {\n const configPath = getConfigPath(rootDir, config);\n await fs.mkdir(path.dirname(configPath), { recursive: true });\n await fs.writeFile(configPath, JSON.stringify(config, null, 2));\n}\n\n/**\n * Get module config by ID\n */\nexport function getModuleConfig(config: Config, moduleId: string): ModuleConfig | undefined {\n return config.modules.find(m => m.id === moduleId);\n}\n\n/**\n * Extract embedding config from module options\n */\nexport function getEmbeddingConfigFromModule(moduleConfig: ModuleConfig): EmbeddingConfig {\n const options = moduleConfig.options || {};\n const modelName = (options.embeddingModel as string) || 'all-MiniLM-L6-v2';\n \n // Validate model name\n if (!(modelName in EMBEDDING_MODELS)) {\n console.warn(`Unknown embedding model: ${modelName}, falling back to all-MiniLM-L6-v2`);\n return { model: 'all-MiniLM-L6-v2' };\n }\n \n return {\n model: modelName as EmbeddingModelName,\n showProgress: options.showProgress !== false,\n };\n}\n",
9
9
  "/**\n * BM25 (Best Matching 25) Implementation\n * \n * A ranking function for keyword-based search. This is a pure domain service\n * with no external dependencies - just algorithms operating on data.\n * \n * BM25 estimates relevance of documents to a search query using term frequency\n * and inverse document frequency with length normalization.\n */\n\n/**\n * BM25 parameters\n * - k1: Term frequency saturation (typical: 1.2-2.0)\n * - b: Length normalization (typical: 0.75)\n */\nconst BM25_K1 = 1.5;\nconst BM25_B = 0.75;\n\n/**\n * Tokenize text into normalized terms.\n * \n * @param text - Text to tokenize\n * @returns Array of lowercase tokens\n */\nexport function tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^\\w\\s]/g, ' ')\n .split(/\\s+/)\n .filter(token => token.length > 1);\n}\n\n/**\n * Calculate term frequency (TF) for a term in a document.\n */\nfunction termFrequency(term: string, tokens: string[]): number {\n return tokens.filter(t => t === term).length;\n}\n\n/**\n * Document data for BM25 scoring.\n */\nexport interface BM25Document {\n id: string;\n content: string;\n /** Pre-computed tokens (optional, computed from content if not provided) */\n tokens?: string[];\n}\n\n/**\n * BM25 search result.\n */\nexport interface BM25Result {\n id: string;\n score: number;\n}\n\n/**\n * BM25 search index.\n * \n * This is a pure in-memory data structure with no I/O operations.\n * Build the index by adding documents, then search against it.\n */\nexport class BM25Index {\n private documents: Map<string, { content: string; tokens: string[] }> = new Map();\n private avgDocLength: number = 0;\n private documentFrequencies: Map<string, number> = new Map();\n private totalDocs: number = 0;\n\n /**\n * Add documents to the index.\n * \n * @param documents - Array of documents to index\n */\n addDocuments(documents: BM25Document[]): void {\n let totalLength = this.avgDocLength * this.totalDocs;\n\n for (const doc of documents) {\n const tokens = doc.tokens ?? tokenize(doc.content);\n this.documents.set(doc.id, { content: doc.content, tokens });\n totalLength += tokens.length;\n this.totalDocs++;\n\n // Update document frequencies\n const uniqueTerms = new Set(tokens);\n for (const term of uniqueTerms) {\n const count = this.documentFrequencies.get(term) || 0;\n this.documentFrequencies.set(term, count + 1);\n }\n }\n\n this.avgDocLength = this.totalDocs > 0 ? totalLength / this.totalDocs : 0;\n }\n\n /**\n * Calculate IDF (Inverse Document Frequency) for a term.\n */\n private idf(term: string): number {\n const docFreq = this.documentFrequencies.get(term) || 0;\n if (docFreq === 0) return 0;\n \n // Standard IDF formula with smoothing\n return Math.log(1 + (this.totalDocs - docFreq + 0.5) / (docFreq + 0.5));\n }\n\n /**\n * Calculate BM25 score for a document given query terms.\n */\n private score(tokens: string[], queryTerms: string[]): number {\n const docLength = tokens.length;\n let score = 0;\n\n for (const term of queryTerms) {\n const tf = termFrequency(term, tokens);\n if (tf === 0) continue;\n\n const idfScore = this.idf(term);\n \n // BM25 formula\n const numerator = tf * (BM25_K1 + 1);\n const denominator = tf + BM25_K1 * (1 - BM25_B + BM25_B * (docLength / this.avgDocLength));\n \n score += idfScore * (numerator / denominator);\n }\n\n return score;\n }\n\n /**\n * Search the index with a query.\n * \n * @param query - Search query\n * @param topK - Maximum number of results to return\n * @returns Sorted array of results (highest score first)\n */\n search(query: string, topK: number = 10): BM25Result[] {\n const queryTerms = tokenize(query);\n if (queryTerms.length === 0) return [];\n\n const results: BM25Result[] = [];\n\n for (const [id, { tokens }] of this.documents) {\n const score = this.score(tokens, queryTerms);\n if (score > 0) {\n results.push({ id, score });\n }\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, topK);\n }\n\n /**\n * Get the number of indexed documents.\n */\n get size(): number {\n return this.totalDocs;\n }\n\n /**\n * Clear the index.\n */\n clear(): void {\n this.documents.clear();\n this.documentFrequencies.clear();\n this.avgDocLength = 0;\n this.totalDocs = 0;\n }\n}\n\n/**\n * Normalize a raw score to 0-1 range using sigmoid function.\n * \n * @param score - Raw score\n * @param midpoint - Score at which output is 0.5\n * @returns Normalized score between 0 and 1\n */\nexport function normalizeScore(score: number, midpoint: number = 5): number {\n return 1 / (1 + Math.exp(-score / midpoint + 1));\n}\n\n",
10
10
  "/**\n * TypeScript/JavaScript Code Parser\n * \n * Uses the TypeScript Compiler API for accurate AST-based parsing.\n * Extracts semantic chunks: functions, classes, interfaces, types, enums.\n */\n\nimport * as ts from 'typescript';\n\n/**\n * Chunk types that can be extracted from code\n */\nexport type ChunkType = \n | 'function' \n | 'class' \n | 'interface' \n | 'type' \n | 'enum'\n | 'variable'\n | 'block' \n | 'file';\n\n/**\n * Represents a parsed chunk of code with location information\n */\nexport interface ParsedChunk {\n /** The source code content */\n content: string;\n /** 1-based start line number */\n startLine: number;\n /** 1-based end line number */\n endLine: number;\n /** The type of code construct */\n type: ChunkType;\n /** Name of the construct (function name, class name, etc.) */\n name?: string;\n /** Whether this is exported */\n isExported?: boolean;\n /** JSDoc comment if present */\n jsDoc?: string;\n}\n\n/**\n * Parse code into semantic chunks based on file extension\n * @param content - The source code content\n * @param filepath - The file path (used to determine language)\n * @returns Array of parsed chunks\n */\nexport function parseCode(content: string, filepath: string): ParsedChunk[] {\n const ext = filepath.split('.').pop()?.toLowerCase();\n\n // For TypeScript/JavaScript files, use the TypeScript parser\n if (['ts', 'tsx', 'js', 'jsx', 'mts', 'cts', 'mjs', 'cjs'].includes(ext || '')) {\n return parseTypeScript(content, filepath);\n }\n\n // For other files, use simple line-based chunking\n return parseGenericCode(content);\n}\n\n/**\n * Parse TypeScript/JavaScript code using the TypeScript Compiler API\n * @param content - The source code content\n * @param filepath - The file path\n * @returns Array of parsed chunks\n */\nfunction parseTypeScript(content: string, filepath: string): ParsedChunk[] {\n const chunks: ParsedChunk[] = [];\n const lines = content.split('\\n');\n\n // Create a source file from the content\n const sourceFile = ts.createSourceFile(\n filepath,\n content,\n ts.ScriptTarget.Latest,\n true, // setParentNodes\n filepath.endsWith('.tsx') || filepath.endsWith('.jsx') \n ? ts.ScriptKind.TSX \n : ts.ScriptKind.TS\n );\n\n /**\n * Get line numbers for a node (1-based)\n */\n function getLineNumbers(node: ts.Node): { startLine: number; endLine: number } {\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n return {\n startLine: start.line + 1,\n endLine: end.line + 1,\n };\n }\n\n /**\n * Get the source text for a node\n */\n function getNodeText(node: ts.Node): string {\n return node.getText(sourceFile);\n }\n\n /**\n * Check if a node has export modifier\n */\n function isExported(node: ts.Node): boolean {\n if (!ts.canHaveModifiers(node)) return false;\n const modifiers = ts.getModifiers(node);\n return modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;\n }\n\n /**\n * Get JSDoc comment for a node\n */\n function getJSDoc(node: ts.Node): string | undefined {\n const jsDocNodes = ts.getJSDocCommentsAndTags(node);\n if (jsDocNodes.length === 0) return undefined;\n \n return jsDocNodes\n .map(doc => doc.getText(sourceFile))\n .join('\\n');\n }\n\n /**\n * Get function name from various function declarations\n */\n function getFunctionName(node: ts.Node): string | undefined {\n if (ts.isFunctionDeclaration(node) && node.name) {\n return node.name.text;\n }\n if (ts.isMethodDeclaration(node) && ts.isIdentifier(node.name)) {\n return node.name.text;\n }\n if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)) {\n return node.name.text;\n }\n return undefined;\n }\n\n /**\n * Visit nodes recursively to extract chunks\n */\n function visit(node: ts.Node): void {\n const { startLine, endLine } = getLineNumbers(node);\n\n // Function declarations (including async)\n if (ts.isFunctionDeclaration(node) && node.name) {\n chunks.push({\n content: getNodeText(node),\n startLine,\n endLine,\n type: 'function',\n name: node.name.text,\n isExported: isExported(node),\n jsDoc: getJSDoc(node),\n });\n return; // Don't recurse into function body\n }\n\n // Arrow functions and function expressions assigned to variables\n if (ts.isVariableStatement(node)) {\n for (const decl of node.declarationList.declarations) {\n if (decl.initializer && \n (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer))) {\n const name = ts.isIdentifier(decl.name) ? decl.name.text : undefined;\n chunks.push({\n content: getNodeText(node),\n startLine,\n endLine,\n type: 'function',\n name,\n isExported: isExported(node),\n jsDoc: getJSDoc(node),\n });\n return;\n }\n }\n }\n\n // Class declarations\n if (ts.isClassDeclaration(node) && node.name) {\n chunks.push({\n content: getNodeText(node),\n startLine,\n endLine,\n type: 'class',\n name: node.name.text,\n isExported: isExported(node),\n jsDoc: getJSDoc(node),\n });\n return; // Don't recurse into class body (it's included in the chunk)\n }\n\n // Interface declarations\n if (ts.isInterfaceDeclaration(node)) {\n chunks.push({\n content: getNodeText(node),\n startLine,\n endLine,\n type: 'interface',\n name: node.name.text,\n isExported: isExported(node),\n jsDoc: getJSDoc(node),\n });\n return;\n }\n\n // Type alias declarations\n if (ts.isTypeAliasDeclaration(node)) {\n chunks.push({\n content: getNodeText(node),\n startLine,\n endLine,\n type: 'type',\n name: node.name.text,\n isExported: isExported(node),\n jsDoc: getJSDoc(node),\n });\n return;\n }\n\n // Enum declarations\n if (ts.isEnumDeclaration(node)) {\n chunks.push({\n content: getNodeText(node),\n startLine,\n endLine,\n type: 'enum',\n name: node.name.text,\n isExported: isExported(node),\n jsDoc: getJSDoc(node),\n });\n return;\n }\n\n // Exported variable declarations (constants)\n if (ts.isVariableStatement(node) && isExported(node)) {\n for (const decl of node.declarationList.declarations) {\n // Skip if it's a function (already handled above)\n if (decl.initializer && \n (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer))) {\n continue;\n }\n const name = ts.isIdentifier(decl.name) ? decl.name.text : undefined;\n chunks.push({\n content: getNodeText(node),\n startLine,\n endLine,\n type: 'variable',\n name,\n isExported: true,\n jsDoc: getJSDoc(node),\n });\n }\n return;\n }\n\n // Recurse into children\n ts.forEachChild(node, visit);\n }\n\n // Start visiting from the root\n ts.forEachChild(sourceFile, visit);\n\n // If no semantic chunks found, fall back to block-based chunking\n if (chunks.length === 0) {\n return parseGenericCode(content);\n }\n\n return chunks;\n}\n\n/**\n * Parse generic code using line-based chunking\n * Used for non-TypeScript/JavaScript files or as fallback\n * @param content - The source code content\n * @returns Array of parsed chunks\n */\nfunction parseGenericCode(content: string): ParsedChunk[] {\n const chunks: ParsedChunk[] = [];\n const lines = content.split('\\n');\n const CHUNK_SIZE = 30; // lines per chunk\n const OVERLAP = 5; // overlap between chunks\n\n // If file is small, treat as single chunk\n if (lines.length <= CHUNK_SIZE) {\n return [\n {\n content: content,\n startLine: 1,\n endLine: lines.length,\n type: 'file',\n },\n ];\n }\n\n // Split into overlapping chunks\n for (let i = 0; i < lines.length; i += CHUNK_SIZE - OVERLAP) {\n const endIdx = Math.min(i + CHUNK_SIZE, lines.length);\n chunks.push({\n content: lines.slice(i, endIdx).join('\\n'),\n startLine: i + 1,\n endLine: endIdx,\n type: 'block',\n });\n\n if (endIdx >= lines.length) break;\n }\n\n return chunks;\n}\n\n/**\n * Generate a unique chunk ID from filepath and line numbers\n * @param filepath - The source file path\n * @param startLine - Start line number\n * @param endLine - End line number\n * @returns Unique chunk identifier\n */\nexport function generateChunkId(filepath: string, startLine: number, endLine: number): string {\n const safePath = filepath.replace(/[/\\\\]/g, '-').replace(/\\./g, '_');\n return `${safePath}-${startLine}-${endLine}`;\n}\n",
11
- "/**\n * Keyword Extraction Service\n * \n * Pure domain service for extracting keywords from code.\n * No external dependencies - operates only on string data.\n */\n\n/**\n * Common programming keywords to exclude from keyword extraction.\n * These appear in almost every code file and don't add search value.\n */\nexport const COMMON_KEYWORDS = new Set([\n // JavaScript/TypeScript\n 'const', 'let', 'var', 'function', 'class', 'interface', 'type', 'enum',\n 'export', 'import', 'from', 'return', 'async', 'await', 'new', 'this',\n 'true', 'false', 'null', 'undefined', 'if', 'else', 'for', 'while',\n 'switch', 'case', 'break', 'continue', 'try', 'catch', 'finally',\n 'throw', 'typeof', 'instanceof', 'void', 'delete', 'in', 'of',\n 'string', 'number', 'boolean', 'any', 'unknown', 'never', 'object',\n 'public', 'private', 'protected', 'static', 'readonly', 'abstract',\n 'implements', 'extends', 'super', 'get', 'set', 'constructor',\n // Common words\n 'the', 'and', 'for', 'not', 'with', 'are', 'was', 'has', 'have',\n]);\n\n/**\n * Extract keywords from code content and optional name.\n * \n * @param content - Code content to extract keywords from\n * @param name - Optional name (function name, class name, etc.)\n * @param maxKeywords - Maximum keywords to return (default: 50)\n * @returns Array of unique lowercase keywords\n */\nexport function extractKeywords(\n content: string, \n name?: string,\n maxKeywords: number = 50\n): string[] {\n const keywords = new Set<string>();\n \n // Add the name if present\n if (name) {\n keywords.add(name.toLowerCase());\n \n // Also add camelCase parts (e.g., \"getUserById\" → [\"get\", \"user\", \"by\", \"id\"])\n const parts = name.split(/(?=[A-Z])/).map(p => p.toLowerCase());\n parts.forEach(p => p.length > 2 && keywords.add(p));\n }\n \n // Extract identifiers from content\n const identifierRegex = /\\b([a-zA-Z_][a-zA-Z0-9_]{2,})\\b/g;\n let match;\n \n while ((match = identifierRegex.exec(content)) !== null) {\n const word = match[1].toLowerCase();\n \n // Skip common keywords and very short words\n if (!COMMON_KEYWORDS.has(word) && word.length > 2) {\n keywords.add(word);\n }\n }\n \n return Array.from(keywords).slice(0, maxKeywords);\n}\n\n/**\n * Extract keywords from a file path.\n * \n * @param filepath - File path to extract keywords from\n * @returns Array of keywords from path segments\n */\nexport function extractPathKeywords(filepath: string): string[] {\n return filepath\n .split(/[/\\\\.]/)\n .filter(p => p.length > 2 && !COMMON_KEYWORDS.has(p.toLowerCase()))\n .map(p => p.toLowerCase());\n}\n\n",
11
+ "/**\n * Keyword Extraction Service\n * \n * Pure domain service for extracting keywords from code.\n * No external dependencies - operates only on string data.\n */\n\n/**\n * Common programming keywords to exclude from keyword extraction.\n * These appear in almost every code file and don't add search value.\n */\nexport const COMMON_KEYWORDS = new Set([\n // JavaScript/TypeScript\n 'const', 'let', 'var', 'function', 'class', 'interface', 'type', 'enum',\n 'export', 'import', 'from', 'return', 'async', 'await', 'new', 'this',\n 'true', 'false', 'null', 'undefined', 'if', 'else', 'for', 'while',\n 'switch', 'case', 'break', 'continue', 'try', 'catch', 'finally',\n 'throw', 'typeof', 'instanceof', 'void', 'delete', 'in', 'of',\n 'string', 'number', 'boolean', 'any', 'unknown', 'never', 'object',\n 'public', 'private', 'protected', 'static', 'readonly', 'abstract',\n 'implements', 'extends', 'super', 'get', 'set', 'constructor',\n // Common words\n 'the', 'and', 'for', 'not', 'with', 'are', 'was', 'has', 'have',\n]);\n\n/**\n * Common architectural layer patterns in file names/paths.\n * Used to detect the layer a file belongs to.\n */\nexport const LAYER_PATTERNS: Record<string, string[]> = {\n 'controller': ['controller', 'controllers', 'handler', 'handlers', 'route', 'routes', 'api'],\n 'service': ['service', 'services', 'usecase', 'usecases', 'application'],\n 'repository': ['repository', 'repositories', 'repo', 'repos', 'dao', 'store', 'storage'],\n 'model': ['model', 'models', 'entity', 'entities', 'schema', 'schemas'],\n 'util': ['util', 'utils', 'utility', 'utilities', 'helper', 'helpers', 'common', 'shared'],\n 'config': ['config', 'configs', 'configuration', 'settings'],\n 'middleware': ['middleware', 'middlewares', 'interceptor', 'interceptors'],\n 'domain': ['domain', 'core', 'business'],\n 'infrastructure': ['infrastructure', 'infra', 'external', 'adapters'],\n 'presentation': ['presentation', 'view', 'views', 'component', 'components', 'ui'],\n 'test': ['test', 'tests', 'spec', 'specs', '__tests__', '__test__'],\n};\n\n/**\n * Extract keywords from code content and optional name.\n * \n * @param content - Code content to extract keywords from\n * @param name - Optional name (function name, class name, etc.)\n * @param maxKeywords - Maximum keywords to return (default: 50)\n * @returns Array of unique lowercase keywords\n */\nexport function extractKeywords(\n content: string, \n name?: string,\n maxKeywords: number = 50\n): string[] {\n const keywords = new Set<string>();\n \n // Add the name if present\n if (name) {\n keywords.add(name.toLowerCase());\n \n // Also add camelCase parts (e.g., \"getUserById\" → [\"get\", \"user\", \"by\", \"id\"])\n const parts = name.split(/(?=[A-Z])/).map(p => p.toLowerCase());\n parts.forEach(p => p.length > 2 && keywords.add(p));\n }\n \n // Extract identifiers from content\n const identifierRegex = /\\b([a-zA-Z_][a-zA-Z0-9_]{2,})\\b/g;\n let match;\n \n while ((match = identifierRegex.exec(content)) !== null) {\n const word = match[1].toLowerCase();\n \n // Skip common keywords and very short words\n if (!COMMON_KEYWORDS.has(word) && word.length > 2) {\n keywords.add(word);\n }\n }\n \n return Array.from(keywords).slice(0, maxKeywords);\n}\n\n/**\n * Split a string by camelCase, PascalCase, snake_case, and kebab-case.\n */\nfunction splitIdentifier(str: string): string[] {\n return str\n // Split camelCase and PascalCase\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n // Split snake_case and kebab-case\n .replace(/[_-]/g, ' ')\n .split(/\\s+/)\n .map(s => s.toLowerCase())\n .filter(s => s.length > 1);\n}\n\n/**\n * Extract keywords from a file path.\n * \n * Enhanced extraction that:\n * - Splits camelCase/PascalCase filenames\n * - Extracts directory segments\n * - Recognizes common patterns (Service, Controller, etc.)\n * \n * @param filepath - File path to extract keywords from\n * @returns Array of keywords from path segments\n */\nexport function extractPathKeywords(filepath: string): string[] {\n const keywords = new Set<string>();\n \n // Split path into segments (excluding extension)\n const pathWithoutExt = filepath.replace(/\\.[^.]+$/, '');\n const segments = pathWithoutExt.split(/[/\\\\]/);\n \n for (const segment of segments) {\n if (segment.length < 2) continue;\n \n // Add the full segment\n const lower = segment.toLowerCase();\n if (!COMMON_KEYWORDS.has(lower) && lower.length > 2) {\n keywords.add(lower);\n }\n \n // Split camelCase/PascalCase/snake_case and add parts\n const parts = splitIdentifier(segment);\n for (const part of parts) {\n if (!COMMON_KEYWORDS.has(part) && part.length > 2) {\n keywords.add(part);\n }\n }\n }\n \n return Array.from(keywords);\n}\n\n/**\n * Path context information extracted from a file path.\n */\nexport interface PathContext {\n /** Directory segments (excluding filename) */\n segments: string[];\n /** Detected architectural layer (service, controller, repository, etc.) */\n layer?: string;\n /** Detected feature domain (auth, users, payments, etc.) */\n domain?: string;\n /** Path depth (number of directory levels) */\n depth: number;\n /** Keywords extracted from the path */\n keywords: string[];\n}\n\n/**\n * Parse a file path and extract structural context.\n * \n * This helps with:\n * - Boosting files in related directories\n * - Understanding architectural layer\n * - Grouping by feature domain\n * \n * @param filepath - File path to parse\n * @returns Parsed path context\n */\nexport function parsePathContext(filepath: string): PathContext {\n const pathWithoutExt = filepath.replace(/\\.[^.]+$/, '');\n const allSegments = pathWithoutExt.split(/[/\\\\]/);\n const filename = allSegments[allSegments.length - 1];\n const dirSegments = allSegments.slice(0, -1);\n \n // Extract keywords from all segments\n const keywords = extractPathKeywords(filepath);\n \n // Detect layer from filename and path\n let layer: string | undefined;\n const allLower = [...dirSegments, filename].map(s => s.toLowerCase()).join(' ');\n const filenameLower = filename.toLowerCase();\n \n for (const [layerName, patterns] of Object.entries(LAYER_PATTERNS)) {\n for (const pattern of patterns) {\n // Check filename first (higher priority)\n if (filenameLower.includes(pattern)) {\n layer = layerName;\n break;\n }\n // Check path segments\n if (dirSegments.some(s => s.toLowerCase() === pattern)) {\n layer = layerName;\n break;\n }\n }\n if (layer) break;\n }\n \n // Detect domain from non-layer directory names\n // e.g., src/services/auth/authService.ts → domain = \"auth\"\n // Traverse from innermost to outermost to find the most specific domain\n let domain: string | undefined;\n const layerPatternSet = new Set(Object.values(LAYER_PATTERNS).flat());\n \n // Create a reversed copy to traverse from innermost to outermost\n const reversedSegments = [...dirSegments].reverse();\n for (const segment of reversedSegments) {\n const lower = segment.toLowerCase();\n // Skip common non-domain directories\n if (['src', 'lib', 'app', 'packages', 'modules'].includes(lower)) continue;\n // Skip layer directories\n if (layerPatternSet.has(lower)) continue;\n // This is likely the domain\n if (lower.length > 2) {\n domain = lower;\n break;\n }\n }\n \n return {\n segments: dirSegments,\n layer,\n domain,\n depth: dirSegments.length,\n keywords,\n };\n}\n\n/**\n * Generate a path context string for embedding.\n * This is prepended to content to give the embedding model path awareness.\n * \n * @param pathContext - Parsed path context\n * @returns A string representation of the path context\n */\nexport function formatPathContextForEmbedding(pathContext: PathContext): string {\n const parts: string[] = [];\n \n if (pathContext.domain) {\n parts.push(pathContext.domain);\n }\n \n if (pathContext.layer) {\n parts.push(pathContext.layer);\n }\n \n // Add significant path segments (limit to avoid noise)\n const significantSegments = pathContext.segments\n .slice(-3) // Last 3 directories\n .filter(s => s.length > 2 && !['src', 'lib', 'app'].includes(s.toLowerCase()));\n \n if (significantSegments.length > 0) {\n parts.push(...significantSegments.map(s => s.toLowerCase()));\n }\n \n if (parts.length === 0) return '';\n \n // Deduplicate\n const unique = [...new Set(parts)];\n return `[${unique.join(' ')}]`;\n}\n\n",
12
12
  "/**\n * Symbolic Index System\n * \n * Provides fast keyword-based filtering using BM25 before semantic search.\n * \n * Structure:\n * .raggrep/index/<module>/symbolic/\n * ├── _meta.json (BM25 statistics)\n * └── <filepath>.json (per-file summaries)\n * \n * This approach scales well because:\n * - Each file summary is stored separately\n * - BM25 metadata is small and loads quickly\n * - Summaries are loaded on-demand during search\n */\n\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { BM25Index } from '../domain/services/bm25';\nimport { extractKeywords, extractPathKeywords } from '../domain/services/keywords';\nimport type { FileSummary, SymbolicIndexMeta } from '../domain/entities';\n\n// Re-export for backwards compatibility\nexport type { FileSummary, SymbolicIndexMeta } from '../domain/entities';\nexport { extractKeywords } from '../domain/services/keywords';\n\n/** @deprecated Use SymbolicIndexMeta */\nexport type Tier1Manifest = SymbolicIndexMeta & { files: Record<string, FileSummary> };\n\n/**\n * Symbolic Index Manager\n * \n * Manages the keyword-based index for fast file filtering.\n */\nexport class SymbolicIndex {\n private meta: SymbolicIndexMeta | null = null;\n private fileSummaries: Map<string, FileSummary> = new Map();\n private bm25Index: BM25Index | null = null;\n private symbolicPath: string;\n private moduleId: string;\n\n constructor(indexDir: string, moduleId: string) {\n this.symbolicPath = path.join(indexDir, 'index', moduleId, 'symbolic');\n this.moduleId = moduleId;\n }\n\n /**\n * Initialize or load the symbolic index\n */\n async initialize(): Promise<void> {\n try {\n await this.load();\n } catch {\n // Create empty metadata\n this.meta = {\n version: '1.0.0',\n lastUpdated: new Date().toISOString(),\n moduleId: this.moduleId,\n fileCount: 0,\n bm25Data: {\n avgDocLength: 0,\n documentFrequencies: {},\n totalDocs: 0,\n },\n };\n this.bm25Index = new BM25Index();\n }\n }\n\n /**\n * Add or update a file summary\n */\n addFile(summary: FileSummary): void {\n this.fileSummaries.set(summary.filepath, summary);\n }\n\n /**\n * Remove a file from the index\n */\n removeFile(filepath: string): boolean {\n return this.fileSummaries.delete(filepath);\n }\n\n /**\n * Build BM25 index from file summaries\n */\n buildBM25Index(): void {\n this.bm25Index = new BM25Index();\n \n // Add each file's keywords as a document\n for (const [filepath, summary] of this.fileSummaries) {\n const content = [\n ...summary.keywords,\n ...summary.exports,\n ...extractPathKeywords(filepath),\n ].join(' ');\n \n this.bm25Index.addDocuments([{ id: filepath, content }]);\n }\n \n // Update metadata\n if (this.meta) {\n this.meta.fileCount = this.fileSummaries.size;\n this.meta.bm25Data.totalDocs = this.fileSummaries.size;\n }\n }\n\n /**\n * Find candidate files using BM25 keyword search\n */\n findCandidates(query: string, maxCandidates: number = 20): string[] {\n if (!this.bm25Index) {\n return Array.from(this.fileSummaries.keys());\n }\n \n const results = this.bm25Index.search(query, maxCandidates);\n return results.map(r => r.id);\n }\n\n /**\n * Get all file paths in the index\n */\n getAllFiles(): string[] {\n return Array.from(this.fileSummaries.keys());\n }\n\n /**\n * Get summary for a specific file\n */\n getFileSummary(filepath: string): FileSummary | undefined {\n return this.fileSummaries.get(filepath);\n }\n\n /**\n * Save the index to disk (per-file structure)\n */\n async save(): Promise<void> {\n if (!this.meta) throw new Error('Index not initialized');\n \n // Update metadata\n this.meta.lastUpdated = new Date().toISOString();\n this.meta.fileCount = this.fileSummaries.size;\n \n // Ensure symbolic directory exists\n await fs.mkdir(this.symbolicPath, { recursive: true });\n \n // Save metadata\n const metaPath = path.join(this.symbolicPath, '_meta.json');\n await fs.writeFile(metaPath, JSON.stringify(this.meta, null, 2));\n \n // Save each file summary\n for (const [filepath, summary] of this.fileSummaries) {\n const summaryPath = this.getFileSummaryPath(filepath);\n await fs.mkdir(path.dirname(summaryPath), { recursive: true });\n await fs.writeFile(summaryPath, JSON.stringify(summary, null, 2));\n }\n }\n\n /**\n * Load the index from disk\n */\n async load(): Promise<void> {\n // Load metadata\n const metaPath = path.join(this.symbolicPath, '_meta.json');\n const metaContent = await fs.readFile(metaPath, 'utf-8');\n this.meta = JSON.parse(metaContent);\n \n // Load all file summaries by walking the symbolic directory\n this.fileSummaries.clear();\n await this.loadFileSummariesRecursive(this.symbolicPath);\n \n // Rebuild BM25 index\n this.buildBM25Index();\n }\n\n /**\n * Recursively load file summaries from the symbolic directory\n */\n private async loadFileSummariesRecursive(dir: string): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n \n if (entry.isDirectory()) {\n await this.loadFileSummariesRecursive(fullPath);\n } else if (entry.name.endsWith('.json') && entry.name !== '_meta.json') {\n try {\n const content = await fs.readFile(fullPath, 'utf-8');\n const summary = JSON.parse(content) as FileSummary;\n if (summary.filepath) {\n this.fileSummaries.set(summary.filepath, summary);\n }\n } catch {\n // Skip invalid files\n }\n }\n }\n } catch {\n // Directory doesn't exist yet\n }\n }\n\n /**\n * Get the path for a file summary\n */\n private getFileSummaryPath(filepath: string): string {\n const jsonPath = filepath.replace(/\\.[^.]+$/, '.json');\n return path.join(this.symbolicPath, jsonPath);\n }\n\n /**\n * Delete a file summary from disk\n */\n async deleteFileSummary(filepath: string): Promise<void> {\n try {\n await fs.unlink(this.getFileSummaryPath(filepath));\n } catch {\n // Ignore if file doesn't exist\n }\n this.fileSummaries.delete(filepath);\n }\n\n /**\n * Check if the index exists on disk\n */\n async exists(): Promise<boolean> {\n try {\n const metaPath = path.join(this.symbolicPath, '_meta.json');\n await fs.access(metaPath);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get the number of indexed files\n */\n get size(): number {\n return this.fileSummaries.size;\n }\n\n /**\n * Clear the index\n */\n clear(): void {\n this.fileSummaries.clear();\n if (this.meta) {\n this.meta.fileCount = 0;\n this.meta.bm25Data = {\n avgDocLength: 0,\n documentFrequencies: {},\n totalDocs: 0,\n };\n }\n this.bm25Index = new BM25Index();\n }\n}\n\n// ============================================================================\n// Backwards compatibility aliases\n// ============================================================================\n\n/** @deprecated Use SymbolicIndex instead */\nexport const Tier1Index = SymbolicIndex;\n\n/** @deprecated Use SymbolicIndex instead */\nexport function getTier1Path(rootDir: string, moduleId: string, indexDir: string = '.raggrep'): string {\n return path.join(rootDir, indexDir, 'index', moduleId, 'tier1.json');\n}\n\nexport function getSymbolicPath(rootDir: string, moduleId: string, indexDir: string = '.raggrep'): string {\n return path.join(rootDir, indexDir, 'index', moduleId, 'symbolic');\n}\n",
13
- "/**\n * Semantic Index Module\n * \n * Uses local text embeddings for natural language code search.\n * Implements a tiered index system:\n * - Tier 1: Lightweight file summaries with keywords for fast filtering\n * - Tier 2: Full chunk embeddings for semantic similarity\n * \n * This approach keeps the filesystem-based design while enabling\n * efficient search by only loading relevant files.\n */\n\nimport * as path from 'path';\nimport {\n IndexModule,\n IndexContext,\n SearchContext,\n SearchOptions,\n FileIndex,\n SearchResult,\n Chunk,\n ModuleConfig,\n ChunkType,\n} from '../../types';\nimport {\n getEmbeddings,\n getEmbedding,\n cosineSimilarity,\n configureEmbeddings,\n EmbeddingConfig,\n getEmbeddingConfig,\n} from '../../utils/embeddings';\nimport { BM25Index, normalizeScore } from '../../utils/bm25';\nimport { getEmbeddingConfigFromModule, getRaggrepDir } from '../../utils/config';\nimport { parseCode, generateChunkId } from './parseCode';\nimport { SymbolicIndex, FileSummary, extractKeywords } from '../../utils/tieredIndex';\n\n/** Default minimum similarity score for search results */\nexport const DEFAULT_MIN_SCORE = 0.15;\n\n/** Default number of results to return */\nexport const DEFAULT_TOP_K = 10;\n\n/** Weight for semantic similarity in hybrid scoring (0-1) */\nconst SEMANTIC_WEIGHT = 0.7;\n\n/** Weight for BM25 keyword matching in hybrid scoring (0-1) */\nconst BM25_WEIGHT = 0.3;\n\n/**\n * Module-specific data stored alongside file index\n */\nexport interface SemanticModuleData {\n embeddings: number[][];\n /** Store the model used for these embeddings for compatibility checking */\n embeddingModel: string;\n [key: string]: unknown; // Index signature for compatibility with Record<string, unknown>\n}\n\n/** Number of candidate files to retrieve from Tier 1 before loading Tier 2 */\nconst TIER1_CANDIDATE_MULTIPLIER = 3;\n\nexport class SemanticModule implements IndexModule {\n readonly id = 'semantic';\n readonly name = 'Semantic Search';\n readonly description = 'Natural language code search using local text embeddings';\n readonly version = '1.0.0';\n\n private embeddingConfig: EmbeddingConfig | null = null;\n private symbolicIndex: SymbolicIndex | null = null;\n private pendingSummaries: Map<string, FileSummary> = new Map();\n private rootDir: string = '';\n\n async initialize(config: ModuleConfig): Promise<void> {\n // Extract embedding config from module options\n this.embeddingConfig = getEmbeddingConfigFromModule(config);\n \n // Configure the embedding provider\n configureEmbeddings(this.embeddingConfig);\n \n // Clear pending summaries for fresh indexing\n this.pendingSummaries.clear();\n }\n\n async indexFile(\n filepath: string,\n content: string,\n ctx: IndexContext\n ): Promise<FileIndex | null> {\n // Store rootDir for finalize\n this.rootDir = ctx.rootDir;\n \n // Parse code into chunks\n const parsedChunks = parseCode(content, filepath);\n\n if (parsedChunks.length === 0) {\n return null;\n }\n\n // Generate embeddings for all chunks\n const chunkContents = parsedChunks.map((c) => c.content);\n const embeddings = await getEmbeddings(chunkContents);\n\n // Create chunks with all metadata\n const chunks: Chunk[] = parsedChunks.map((pc) => ({\n id: generateChunkId(filepath, pc.startLine, pc.endLine),\n content: pc.content,\n startLine: pc.startLine,\n endLine: pc.endLine,\n type: pc.type,\n name: pc.name,\n isExported: pc.isExported,\n jsDoc: pc.jsDoc,\n }));\n\n // Extract references (imports)\n const references = this.extractReferences(content, filepath);\n\n const stats = await ctx.getFileStats(filepath);\n const currentConfig = getEmbeddingConfig();\n\n const moduleData: SemanticModuleData = {\n embeddings,\n embeddingModel: currentConfig.model,\n };\n\n // Build Tier 1 summary for this file\n const chunkTypes = [...new Set(parsedChunks.map(pc => pc.type))] as ChunkType[];\n const exports = parsedChunks\n .filter(pc => pc.isExported && pc.name)\n .map(pc => pc.name!);\n \n // Extract keywords from all chunks\n const allKeywords = new Set<string>();\n for (const pc of parsedChunks) {\n const keywords = extractKeywords(pc.content, pc.name);\n keywords.forEach(k => allKeywords.add(k));\n }\n\n const fileSummary: FileSummary = {\n filepath,\n chunkCount: chunks.length,\n chunkTypes,\n keywords: Array.from(allKeywords),\n exports,\n lastModified: stats.lastModified,\n };\n \n // Store summary for finalize\n this.pendingSummaries.set(filepath, fileSummary);\n\n return {\n filepath,\n lastModified: stats.lastModified,\n chunks,\n moduleData,\n references,\n };\n }\n\n /**\n * Finalize indexing by building and saving the symbolic index\n */\n async finalize(ctx: IndexContext): Promise<void> {\n const indexDir = getRaggrepDir(ctx.rootDir, ctx.config);\n \n // Initialize symbolic index\n this.symbolicIndex = new SymbolicIndex(indexDir, this.id);\n await this.symbolicIndex.initialize();\n \n // Add all pending summaries\n for (const [filepath, summary] of this.pendingSummaries) {\n this.symbolicIndex.addFile(summary);\n }\n \n // Build BM25 index from summaries\n this.symbolicIndex.buildBM25Index();\n \n // Save to disk (creates symbolic/ folder with per-file summaries)\n await this.symbolicIndex.save();\n \n console.log(` Symbolic index built with ${this.pendingSummaries.size} file summaries`);\n \n // Clear pending summaries\n this.pendingSummaries.clear();\n }\n\n /**\n * Search the semantic index for chunks matching the query.\n * \n * Uses a tiered approach for efficient search:\n * 1. Tier 1: Use BM25 on file summaries to find candidate files\n * 2. Tier 2: Load only candidate files and compute semantic similarity\n * \n * @param query - Natural language search query\n * @param ctx - Search context with index access\n * @param options - Search options (topK, minScore, filePatterns)\n * @returns Array of search results sorted by relevance\n */\n async search(\n query: string,\n ctx: SearchContext,\n options: SearchOptions = {}\n ): Promise<SearchResult[]> {\n const { topK = DEFAULT_TOP_K, minScore = DEFAULT_MIN_SCORE, filePatterns } = options;\n\n // Load symbolic index for candidate filtering\n const indexDir = getRaggrepDir(ctx.rootDir, ctx.config);\n const symbolicIndex = new SymbolicIndex(indexDir, this.id);\n \n let candidateFiles: string[];\n \n try {\n await symbolicIndex.initialize();\n \n // Use BM25 keyword search on symbolic index to find candidate files\n const maxCandidates = topK * TIER1_CANDIDATE_MULTIPLIER;\n candidateFiles = symbolicIndex.findCandidates(query, maxCandidates);\n \n // If no candidates found via BM25, fall back to all files\n if (candidateFiles.length === 0) {\n candidateFiles = symbolicIndex.getAllFiles();\n }\n } catch {\n // Symbolic index doesn't exist, fall back to loading all files\n candidateFiles = await ctx.listIndexedFiles();\n }\n\n // Apply file pattern filter\n if (filePatterns && filePatterns.length > 0) {\n candidateFiles = candidateFiles.filter(filepath => {\n return filePatterns.some(pattern => {\n if (pattern.startsWith('*.')) {\n const ext = pattern.slice(1);\n return filepath.endsWith(ext);\n }\n return filepath.includes(pattern);\n });\n });\n }\n\n // Get query embedding for semantic search\n const queryEmbedding = await getEmbedding(query);\n\n // Tier 2: Load only candidate files and compute scores\n const bm25Index = new BM25Index();\n const allChunksData: Array<{\n filepath: string;\n chunk: Chunk;\n embedding: number[];\n }> = [];\n\n for (const filepath of candidateFiles) {\n const fileIndex = await ctx.loadFileIndex(filepath);\n if (!fileIndex) continue;\n\n const moduleData = fileIndex.moduleData as unknown as SemanticModuleData;\n if (!moduleData?.embeddings) continue;\n\n for (let i = 0; i < fileIndex.chunks.length; i++) {\n const chunk = fileIndex.chunks[i];\n const embedding = moduleData.embeddings[i];\n\n if (!embedding) continue;\n\n allChunksData.push({\n filepath: fileIndex.filepath,\n chunk,\n embedding,\n });\n\n // Add to BM25 index for chunk-level keyword matching\n bm25Index.addDocuments([{ id: chunk.id, content: chunk.content }]);\n }\n }\n\n // Perform BM25 search at chunk level\n const bm25Results = bm25Index.search(query, topK * 3);\n const bm25Scores = new Map<string, number>();\n \n for (const result of bm25Results) {\n bm25Scores.set(result.id, normalizeScore(result.score, 3));\n }\n\n // Calculate hybrid scores for all chunks\n const results: SearchResult[] = [];\n\n for (const { filepath, chunk, embedding } of allChunksData) {\n const semanticScore = cosineSimilarity(queryEmbedding, embedding);\n const bm25Score = bm25Scores.get(chunk.id) || 0;\n \n // Hybrid score: weighted combination of semantic and BM25\n const hybridScore = (SEMANTIC_WEIGHT * semanticScore) + (BM25_WEIGHT * bm25Score);\n\n if (hybridScore >= minScore || bm25Score > 0.3) {\n results.push({\n filepath,\n chunk,\n score: hybridScore,\n moduleId: this.id,\n context: {\n semanticScore,\n bm25Score,\n },\n });\n }\n }\n\n // Sort by score descending and take top K\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, topK);\n }\n\n private extractReferences(content: string, filepath: string): string[] {\n const references: string[] = [];\n\n // Extract import statements\n const importRegex = /import\\s+.*?\\s+from\\s+['\"]([^'\"]+)['\"]/g;\n const requireRegex = /require\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n\n let match;\n while ((match = importRegex.exec(content)) !== null) {\n const importPath = match[1];\n if (importPath.startsWith('.')) {\n const dir = path.dirname(filepath);\n const resolved = path.normalize(path.join(dir, importPath));\n references.push(resolved);\n }\n }\n\n while ((match = requireRegex.exec(content)) !== null) {\n const importPath = match[1];\n if (importPath.startsWith('.')) {\n const dir = path.dirname(filepath);\n const resolved = path.normalize(path.join(dir, importPath));\n references.push(resolved);\n }\n }\n\n return references;\n }\n}\n",
13
+ "/**\n * Semantic Index Module\n * \n * Uses local text embeddings for natural language code search.\n * Implements a tiered index system:\n * - Tier 1: Lightweight file summaries with keywords for fast filtering\n * - Tier 2: Full chunk embeddings for semantic similarity\n * \n * This approach keeps the filesystem-based design while enabling\n * efficient search by only loading relevant files.\n */\n\nimport * as path from 'path';\nimport {\n IndexModule,\n IndexContext,\n SearchContext,\n SearchOptions,\n FileIndex,\n SearchResult,\n Chunk,\n ModuleConfig,\n ChunkType,\n} from '../../types';\nimport {\n getEmbeddings,\n getEmbedding,\n cosineSimilarity,\n configureEmbeddings,\n EmbeddingConfig,\n getEmbeddingConfig,\n} from '../../utils/embeddings';\nimport { BM25Index, normalizeScore } from '../../utils/bm25';\nimport { getEmbeddingConfigFromModule, getRaggrepDir } from '../../utils/config';\nimport { parseCode, generateChunkId } from './parseCode';\nimport { SymbolicIndex, extractKeywords } from '../../utils/tieredIndex';\nimport type { FileSummary } from '../../domain/entities';\nimport { parsePathContext, formatPathContextForEmbedding } from '../../domain/services/keywords';\n\n/** Default minimum similarity score for search results */\nexport const DEFAULT_MIN_SCORE = 0.15;\n\n/** Default number of results to return */\nexport const DEFAULT_TOP_K = 10;\n\n/** Weight for semantic similarity in hybrid scoring (0-1) */\nconst SEMANTIC_WEIGHT = 0.7;\n\n/** Weight for BM25 keyword matching in hybrid scoring (0-1) */\nconst BM25_WEIGHT = 0.3;\n\n/**\n * Module-specific data stored alongside file index\n */\nexport interface SemanticModuleData {\n embeddings: number[][];\n /** Store the model used for these embeddings for compatibility checking */\n embeddingModel: string;\n [key: string]: unknown; // Index signature for compatibility with Record<string, unknown>\n}\n\n/** Number of candidate files to retrieve from Tier 1 before loading Tier 2 */\nconst TIER1_CANDIDATE_MULTIPLIER = 3;\n\nexport class SemanticModule implements IndexModule {\n readonly id = 'semantic';\n readonly name = 'Semantic Search';\n readonly description = 'Natural language code search using local text embeddings';\n readonly version = '1.0.0';\n\n private embeddingConfig: EmbeddingConfig | null = null;\n private symbolicIndex: SymbolicIndex | null = null;\n private pendingSummaries: Map<string, FileSummary> = new Map();\n private rootDir: string = '';\n\n async initialize(config: ModuleConfig): Promise<void> {\n // Extract embedding config from module options\n this.embeddingConfig = getEmbeddingConfigFromModule(config);\n \n // Configure the embedding provider\n configureEmbeddings(this.embeddingConfig);\n \n // Clear pending summaries for fresh indexing\n this.pendingSummaries.clear();\n }\n\n async indexFile(\n filepath: string,\n content: string,\n ctx: IndexContext\n ): Promise<FileIndex | null> {\n // Store rootDir for finalize\n this.rootDir = ctx.rootDir;\n \n // Parse code into chunks\n const parsedChunks = parseCode(content, filepath);\n\n if (parsedChunks.length === 0) {\n return null;\n }\n\n // Parse path context for structural awareness\n const pathContext = parsePathContext(filepath);\n const pathPrefix = formatPathContextForEmbedding(pathContext);\n\n // Generate embeddings for all chunks with path context\n // Prepending path context helps the embedding model understand file structure\n const chunkContents = parsedChunks.map((c) => {\n // For named chunks, include the name for better embedding\n const namePrefix = c.name ? `${c.name}: ` : '';\n return `${pathPrefix} ${namePrefix}${c.content}`;\n });\n const embeddings = await getEmbeddings(chunkContents);\n\n // Create chunks with all metadata\n const chunks: Chunk[] = parsedChunks.map((pc) => ({\n id: generateChunkId(filepath, pc.startLine, pc.endLine),\n content: pc.content,\n startLine: pc.startLine,\n endLine: pc.endLine,\n type: pc.type,\n name: pc.name,\n isExported: pc.isExported,\n jsDoc: pc.jsDoc,\n }));\n\n // Extract references (imports)\n const references = this.extractReferences(content, filepath);\n\n const stats = await ctx.getFileStats(filepath);\n const currentConfig = getEmbeddingConfig();\n\n const moduleData: SemanticModuleData = {\n embeddings,\n embeddingModel: currentConfig.model,\n };\n\n // Build Tier 1 summary for this file\n const chunkTypes = [...new Set(parsedChunks.map(pc => pc.type))] as ChunkType[];\n const exports = parsedChunks\n .filter(pc => pc.isExported && pc.name)\n .map(pc => pc.name!);\n \n // Extract keywords from all chunks + path keywords\n const allKeywords = new Set<string>();\n for (const pc of parsedChunks) {\n const keywords = extractKeywords(pc.content, pc.name);\n keywords.forEach(k => allKeywords.add(k));\n }\n // Add path keywords\n pathContext.keywords.forEach(k => allKeywords.add(k));\n\n const fileSummary: FileSummary = {\n filepath,\n chunkCount: chunks.length,\n chunkTypes,\n keywords: Array.from(allKeywords),\n exports,\n lastModified: stats.lastModified,\n // Include parsed path context for search boosting\n pathContext: {\n segments: pathContext.segments,\n layer: pathContext.layer,\n domain: pathContext.domain,\n depth: pathContext.depth,\n },\n };\n \n // Store summary for finalize\n this.pendingSummaries.set(filepath, fileSummary);\n\n return {\n filepath,\n lastModified: stats.lastModified,\n chunks,\n moduleData,\n references,\n };\n }\n\n /**\n * Finalize indexing by building and saving the symbolic index\n */\n async finalize(ctx: IndexContext): Promise<void> {\n const indexDir = getRaggrepDir(ctx.rootDir, ctx.config);\n \n // Initialize symbolic index\n this.symbolicIndex = new SymbolicIndex(indexDir, this.id);\n await this.symbolicIndex.initialize();\n \n // Add all pending summaries\n for (const [filepath, summary] of this.pendingSummaries) {\n this.symbolicIndex.addFile(summary);\n }\n \n // Build BM25 index from summaries\n this.symbolicIndex.buildBM25Index();\n \n // Save to disk (creates symbolic/ folder with per-file summaries)\n await this.symbolicIndex.save();\n \n console.log(` Symbolic index built with ${this.pendingSummaries.size} file summaries`);\n \n // Clear pending summaries\n this.pendingSummaries.clear();\n }\n\n /**\n * Search the semantic index for chunks matching the query.\n * \n * Uses a tiered approach for efficient search:\n * 1. Tier 1: Use BM25 on file summaries to find candidate files\n * 2. Tier 2: Load only candidate files and compute semantic similarity\n * \n * @param query - Natural language search query\n * @param ctx - Search context with index access\n * @param options - Search options (topK, minScore, filePatterns)\n * @returns Array of search results sorted by relevance\n */\n async search(\n query: string,\n ctx: SearchContext,\n options: SearchOptions = {}\n ): Promise<SearchResult[]> {\n const { topK = DEFAULT_TOP_K, minScore = DEFAULT_MIN_SCORE, filePatterns } = options;\n\n // Load symbolic index for candidate filtering\n const indexDir = getRaggrepDir(ctx.rootDir, ctx.config);\n const symbolicIndex = new SymbolicIndex(indexDir, this.id);\n \n let candidateFiles: string[];\n \n try {\n await symbolicIndex.initialize();\n \n // Use BM25 keyword search on symbolic index to find candidate files\n const maxCandidates = topK * TIER1_CANDIDATE_MULTIPLIER;\n candidateFiles = symbolicIndex.findCandidates(query, maxCandidates);\n \n // If no candidates found via BM25, fall back to all files\n if (candidateFiles.length === 0) {\n candidateFiles = symbolicIndex.getAllFiles();\n }\n } catch {\n // Symbolic index doesn't exist, fall back to loading all files\n candidateFiles = await ctx.listIndexedFiles();\n }\n\n // Apply file pattern filter\n if (filePatterns && filePatterns.length > 0) {\n candidateFiles = candidateFiles.filter(filepath => {\n return filePatterns.some(pattern => {\n if (pattern.startsWith('*.')) {\n const ext = pattern.slice(1);\n return filepath.endsWith(ext);\n }\n return filepath.includes(pattern);\n });\n });\n }\n\n // Get query embedding for semantic search\n const queryEmbedding = await getEmbedding(query);\n\n // Tier 2: Load only candidate files and compute scores\n const bm25Index = new BM25Index();\n const allChunksData: Array<{\n filepath: string;\n chunk: Chunk;\n embedding: number[];\n }> = [];\n\n for (const filepath of candidateFiles) {\n const fileIndex = await ctx.loadFileIndex(filepath);\n if (!fileIndex) continue;\n\n const moduleData = fileIndex.moduleData as unknown as SemanticModuleData;\n if (!moduleData?.embeddings) continue;\n\n for (let i = 0; i < fileIndex.chunks.length; i++) {\n const chunk = fileIndex.chunks[i];\n const embedding = moduleData.embeddings[i];\n\n if (!embedding) continue;\n\n allChunksData.push({\n filepath: fileIndex.filepath,\n chunk,\n embedding,\n });\n\n // Add to BM25 index for chunk-level keyword matching\n bm25Index.addDocuments([{ id: chunk.id, content: chunk.content }]);\n }\n }\n\n // Perform BM25 search at chunk level\n const bm25Results = bm25Index.search(query, topK * 3);\n const bm25Scores = new Map<string, number>();\n \n for (const result of bm25Results) {\n bm25Scores.set(result.id, normalizeScore(result.score, 3));\n }\n\n // Extract query terms for path matching\n const queryTerms = query.toLowerCase().split(/\\s+/).filter(t => t.length > 2);\n \n // Build path boost map from file summaries\n const pathBoosts = new Map<string, number>();\n for (const filepath of candidateFiles) {\n const summary = symbolicIndex.getFileSummary(filepath);\n if (summary?.pathContext) {\n let boost = 0;\n const ctx = summary.pathContext;\n \n // Check if query terms match domain\n if (ctx.domain && queryTerms.some(t => ctx.domain!.includes(t) || t.includes(ctx.domain!))) {\n boost += 0.1;\n }\n \n // Check if query terms match layer\n if (ctx.layer && queryTerms.some(t => ctx.layer!.includes(t) || t.includes(ctx.layer!))) {\n boost += 0.05;\n }\n \n // Check if query terms match path segments\n const segmentMatch = ctx.segments.some(seg => \n queryTerms.some(t => seg.toLowerCase().includes(t) || t.includes(seg.toLowerCase()))\n );\n if (segmentMatch) {\n boost += 0.05;\n }\n \n pathBoosts.set(filepath, boost);\n }\n }\n\n // Calculate hybrid scores for all chunks\n const results: SearchResult[] = [];\n\n for (const { filepath, chunk, embedding } of allChunksData) {\n const semanticScore = cosineSimilarity(queryEmbedding, embedding);\n const bm25Score = bm25Scores.get(chunk.id) || 0;\n const pathBoost = pathBoosts.get(filepath) || 0;\n \n // Hybrid score: weighted combination of semantic, BM25, and path boost\n const hybridScore = (SEMANTIC_WEIGHT * semanticScore) + (BM25_WEIGHT * bm25Score) + pathBoost;\n\n if (hybridScore >= minScore || bm25Score > 0.3) {\n results.push({\n filepath,\n chunk,\n score: hybridScore,\n moduleId: this.id,\n context: {\n semanticScore,\n bm25Score,\n pathBoost,\n },\n });\n }\n }\n\n // Sort by score descending and take top K\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, topK);\n }\n\n private extractReferences(content: string, filepath: string): string[] {\n const references: string[] = [];\n\n // Extract import statements\n const importRegex = /import\\s+.*?\\s+from\\s+['\"]([^'\"]+)['\"]/g;\n const requireRegex = /require\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n\n let match;\n while ((match = importRegex.exec(content)) !== null) {\n const importPath = match[1];\n if (importPath.startsWith('.')) {\n const dir = path.dirname(filepath);\n const resolved = path.normalize(path.join(dir, importPath));\n references.push(resolved);\n }\n }\n\n while ((match = requireRegex.exec(content)) !== null) {\n const importPath = match[1];\n if (importPath.startsWith('.')) {\n const dir = path.dirname(filepath);\n const resolved = path.normalize(path.join(dir, importPath));\n references.push(resolved);\n }\n }\n\n return references;\n }\n}\n",
14
14
  "// Module registry - manages available index modules\nimport { IndexModule, ModuleRegistry, Config } from '../types';\n\nclass ModuleRegistryImpl implements ModuleRegistry {\n private modules = new Map<string, IndexModule>();\n\n register(module: IndexModule): void {\n if (this.modules.has(module.id)) {\n console.warn(`Module '${module.id}' is already registered, overwriting...`);\n }\n this.modules.set(module.id, module);\n }\n\n get(id: string): IndexModule | undefined {\n return this.modules.get(id);\n }\n\n list(): IndexModule[] {\n return Array.from(this.modules.values());\n }\n\n getEnabled(config: Config): IndexModule[] {\n const enabledIds = new Set(\n config.modules\n .filter(m => m.enabled)\n .map(m => m.id)\n );\n \n return this.list().filter(m => enabledIds.has(m.id));\n }\n}\n\n// Global singleton registry\nexport const registry: ModuleRegistry = new ModuleRegistryImpl();\n\n// Auto-register built-in modules\nexport async function registerBuiltInModules(): Promise<void> {\n // Dynamic import to avoid circular dependencies\n const { SemanticModule } = await import('./semantic');\n registry.register(new SemanticModule());\n}\n",
15
- "// Main indexer - coordinates modules for indexing files\nimport { glob } from 'glob';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport {\n Config,\n IndexContext,\n IndexModule,\n ModuleManifest,\n GlobalManifest,\n FileIndex,\n} from '../types';\nimport {\n DEFAULT_CONFIG,\n loadConfig,\n getModuleIndexPath,\n getModuleManifestPath,\n getGlobalManifestPath,\n getModuleConfig,\n} from '../utils/config';\nimport { registry, registerBuiltInModules } from '../modules/registry';\nimport { EmbeddingModelName } from '../utils/embeddings';\n\nexport interface IndexResult {\n moduleId: string;\n indexed: number;\n skipped: number;\n errors: number;\n}\n\nexport interface IndexOptions {\n /** Override the embedding model (semantic module) */\n model?: EmbeddingModelName;\n /** Show detailed progress */\n verbose?: boolean;\n}\n\nexport interface CleanupResult {\n moduleId: string;\n /** Number of stale entries removed */\n removed: number;\n /** Number of valid entries kept */\n kept: number;\n}\n\n/**\n * Index a directory using all enabled modules\n */\nexport async function indexDirectory(rootDir: string, options: IndexOptions = {}): Promise<IndexResult[]> {\n const verbose = options.verbose ?? false;\n \n // Ensure absolute path\n rootDir = path.resolve(rootDir);\n \n console.log(`Indexing directory: ${rootDir}`);\n\n // Load config\n const config = await loadConfig(rootDir);\n\n // Register built-in modules\n await registerBuiltInModules();\n\n // Get enabled modules\n const enabledModules = registry.getEnabled(config);\n\n if (enabledModules.length === 0) {\n console.log('No modules enabled. Check your configuration.');\n return [];\n }\n\n console.log(`Enabled modules: ${enabledModules.map((m) => m.id).join(', ')}`);\n\n // Get all files matching extensions\n const files = await findFiles(rootDir, config);\n console.log(`Found ${files.length} files to index`);\n\n // Index with each module\n const results: IndexResult[] = [];\n\n for (const module of enabledModules) {\n console.log(`\\n[${module.name}] Starting indexing...`);\n\n // Initialize module if needed\n const moduleConfig = getModuleConfig(config, module.id);\n if (module.initialize && moduleConfig) {\n // Apply CLI overrides to module config\n const configWithOverrides = { ...moduleConfig };\n if (options.model && module.id === 'semantic') {\n configWithOverrides.options = {\n ...configWithOverrides.options,\n embeddingModel: options.model,\n };\n }\n await module.initialize(configWithOverrides);\n }\n\n const result = await indexWithModule(rootDir, files, module, config, verbose);\n results.push(result);\n\n // Call finalize to build secondary indexes (Tier 1, BM25, etc.)\n if (module.finalize) {\n console.log(`[${module.name}] Building secondary indexes...`);\n const ctx: IndexContext = {\n rootDir,\n config,\n readFile: async (filepath: string) => {\n const fullPath = path.isAbsolute(filepath) ? filepath : path.join(rootDir, filepath);\n return fs.readFile(fullPath, 'utf-8');\n },\n getFileStats: async (filepath: string) => {\n const fullPath = path.isAbsolute(filepath) ? filepath : path.join(rootDir, filepath);\n const stats = await fs.stat(fullPath);\n return { lastModified: stats.mtime.toISOString() };\n },\n };\n await module.finalize(ctx);\n }\n\n console.log(`[${module.name}] Complete: ${result.indexed} indexed, ${result.skipped} skipped, ${result.errors} errors`);\n }\n\n // Update global manifest\n await updateGlobalManifest(rootDir, enabledModules, config);\n\n return results;\n}\n\n/**\n * Index files with a specific module\n */\nasync function indexWithModule(\n rootDir: string,\n files: string[],\n module: IndexModule,\n config: Config,\n verbose: boolean\n): Promise<IndexResult> {\n const result: IndexResult = {\n moduleId: module.id,\n indexed: 0,\n skipped: 0,\n errors: 0,\n };\n\n // Load existing manifest for this module\n const manifest = await loadModuleManifest(rootDir, module.id, config);\n\n // Create index context\n const ctx: IndexContext = {\n rootDir,\n config,\n readFile: async (filepath: string) => {\n const fullPath = path.isAbsolute(filepath) ? filepath : path.join(rootDir, filepath);\n return fs.readFile(fullPath, 'utf-8');\n },\n getFileStats: async (filepath: string) => {\n const fullPath = path.isAbsolute(filepath) ? filepath : path.join(rootDir, filepath);\n const stats = await fs.stat(fullPath);\n return { lastModified: stats.mtime.toISOString() };\n },\n };\n\n // Process each file\n for (const filepath of files) {\n const relativePath = path.relative(rootDir, filepath);\n \n try {\n const stats = await fs.stat(filepath);\n const lastModified = stats.mtime.toISOString();\n\n // Check if file needs re-indexing\n const existingEntry = manifest.files[relativePath];\n if (existingEntry && existingEntry.lastModified === lastModified) {\n if (verbose) {\n console.log(` Skipped ${relativePath} (unchanged)`);\n }\n result.skipped++;\n continue;\n }\n\n // Read and index file\n const content = await fs.readFile(filepath, 'utf-8');\n \n if (verbose) {\n console.log(` Processing ${relativePath}...`);\n }\n const fileIndex = await module.indexFile(relativePath, content, ctx);\n\n if (!fileIndex) {\n if (verbose) {\n console.log(` Skipped ${relativePath} (no chunks)`);\n }\n result.skipped++;\n continue;\n }\n\n // Write index file\n await writeFileIndex(rootDir, module.id, relativePath, fileIndex, config);\n\n // Update manifest\n manifest.files[relativePath] = {\n lastModified,\n chunkCount: fileIndex.chunks.length,\n };\n\n result.indexed++;\n } catch (error) {\n console.error(` Error indexing ${relativePath}:`, error);\n result.errors++;\n }\n }\n\n // Update manifest\n manifest.lastUpdated = new Date().toISOString();\n await writeModuleManifest(rootDir, module.id, manifest, config);\n\n return result;\n}\n\nasync function findFiles(rootDir: string, config: Config): Promise<string[]> {\n const patterns = config.extensions.map((ext) => `**/*${ext}`);\n const ignorePatterns = config.ignorePaths.map((p) => `**/${p}/**`);\n\n const files: string[] = [];\n for (const pattern of patterns) {\n const matches = await glob(pattern, {\n cwd: rootDir,\n absolute: true,\n ignore: ignorePatterns,\n });\n files.push(...matches);\n }\n\n return [...new Set(files)]; // Remove duplicates\n}\n\nasync function loadModuleManifest(\n rootDir: string,\n moduleId: string,\n config: Config\n): Promise<ModuleManifest> {\n const manifestPath = getModuleManifestPath(rootDir, moduleId, config);\n\n try {\n const content = await fs.readFile(manifestPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return {\n moduleId,\n version: '1.0.0',\n lastUpdated: new Date().toISOString(),\n files: {},\n };\n }\n}\n\nasync function writeModuleManifest(\n rootDir: string,\n moduleId: string,\n manifest: ModuleManifest,\n config: Config\n): Promise<void> {\n const manifestPath = getModuleManifestPath(rootDir, moduleId, config);\n await fs.mkdir(path.dirname(manifestPath), { recursive: true });\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2));\n}\n\nasync function writeFileIndex(\n rootDir: string,\n moduleId: string,\n filepath: string,\n fileIndex: FileIndex,\n config: Config\n): Promise<void> {\n const indexPath = getModuleIndexPath(rootDir, moduleId, config);\n const indexFilePath = path.join(indexPath, filepath.replace(/\\.[^.]+$/, '.json'));\n\n await fs.mkdir(path.dirname(indexFilePath), { recursive: true });\n await fs.writeFile(indexFilePath, JSON.stringify(fileIndex, null, 2));\n}\n\nasync function updateGlobalManifest(\n rootDir: string,\n modules: IndexModule[],\n config: Config\n): Promise<void> {\n const manifestPath = getGlobalManifestPath(rootDir, config);\n\n const manifest: GlobalManifest = {\n version: config.version,\n lastUpdated: new Date().toISOString(),\n modules: modules.map((m) => m.id),\n };\n\n await fs.mkdir(path.dirname(manifestPath), { recursive: true });\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2));\n}\n\n/**\n * Clean up stale index entries for files that no longer exist\n * @param rootDir - Root directory of the project\n * @param options - Cleanup options\n * @returns Array of cleanup results per module\n */\nexport async function cleanupIndex(\n rootDir: string, \n options: { verbose?: boolean } = {}\n): Promise<CleanupResult[]> {\n const verbose = options.verbose ?? false;\n \n // Ensure absolute path\n rootDir = path.resolve(rootDir);\n \n console.log(`Cleaning up index in: ${rootDir}`);\n\n // Load config\n const config = await loadConfig(rootDir);\n\n // Register built-in modules\n await registerBuiltInModules();\n\n // Get enabled modules\n const enabledModules = registry.getEnabled(config);\n\n if (enabledModules.length === 0) {\n console.log('No modules enabled.');\n return [];\n }\n\n const results: CleanupResult[] = [];\n\n for (const module of enabledModules) {\n console.log(`\\n[${module.name}] Checking for stale entries...`);\n \n const result = await cleanupModuleIndex(rootDir, module.id, config, verbose);\n results.push(result);\n \n console.log(`[${module.name}] Removed ${result.removed} stale entries, kept ${result.kept} valid entries`);\n }\n\n return results;\n}\n\n/**\n * Clean up stale index entries for a specific module\n */\nasync function cleanupModuleIndex(\n rootDir: string,\n moduleId: string,\n config: Config,\n verbose: boolean\n): Promise<CleanupResult> {\n const result: CleanupResult = {\n moduleId,\n removed: 0,\n kept: 0,\n };\n\n // Load manifest\n const manifest = await loadModuleManifest(rootDir, moduleId, config);\n const indexPath = getModuleIndexPath(rootDir, moduleId, config);\n \n const filesToRemove: string[] = [];\n const updatedFiles: ModuleManifest['files'] = {};\n\n // Check each indexed file\n for (const [filepath, entry] of Object.entries(manifest.files)) {\n const fullPath = path.join(rootDir, filepath);\n \n try {\n await fs.access(fullPath);\n // File exists, keep it\n updatedFiles[filepath] = entry;\n result.kept++;\n } catch {\n // File doesn't exist, mark for removal\n filesToRemove.push(filepath);\n result.removed++;\n \n if (verbose) {\n console.log(` Removing stale entry: ${filepath}`);\n }\n }\n }\n\n // Remove stale index files\n for (const filepath of filesToRemove) {\n const indexFilePath = path.join(indexPath, filepath.replace(/\\.[^.]+$/, '.json'));\n try {\n await fs.unlink(indexFilePath);\n } catch {\n // Index file may not exist, that's okay\n }\n }\n\n // Update manifest with only valid files\n manifest.files = updatedFiles;\n manifest.lastUpdated = new Date().toISOString();\n await writeModuleManifest(rootDir, moduleId, manifest, config);\n\n // Clean up empty directories in the index\n await cleanupEmptyDirectories(indexPath);\n\n return result;\n}\n\n/**\n * Recursively remove empty directories\n */\nasync function cleanupEmptyDirectories(dir: string): Promise<boolean> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n // Process subdirectories first\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const subDir = path.join(dir, entry.name);\n await cleanupEmptyDirectories(subDir);\n }\n }\n \n // Check if directory is now empty (re-read after potential subdirectory removal)\n const remainingEntries = await fs.readdir(dir);\n \n // Don't remove the root index directory or manifest files\n if (remainingEntries.length === 0) {\n await fs.rmdir(dir);\n return true;\n }\n \n return false;\n } catch {\n return false;\n }\n}\n",
15
+ "/**\n * File watcher for incremental indexing\n * \n * Best practices implemented:\n * - Debouncing: Batches rapid file changes (e.g., IDE saves, git operations)\n * - Queuing: Prevents concurrent index operations\n * - Efficient filtering: Only watches relevant file types\n * - Graceful shutdown: Proper cleanup on SIGINT/SIGTERM\n * - Error recovery: Continues watching after index errors\n */\n\nimport { watch, type FSWatcher } from 'chokidar';\nimport * as path from 'path';\nimport { loadConfig } from '../utils/config';\nimport type { Config } from '../domain/entities';\nimport { indexDirectory, cleanupIndex, type IndexOptions, type IndexResult } from './index';\n\n/** Default debounce delay in milliseconds */\nconst DEFAULT_DEBOUNCE_MS = 300;\n\n/** Maximum files to batch before forcing an index */\nconst MAX_BATCH_SIZE = 100;\n\nexport interface WatchOptions extends IndexOptions {\n /** Debounce delay in milliseconds (default: 300) */\n debounceMs?: number;\n /** Callback when indexing starts */\n onIndexStart?: (files: string[]) => void;\n /** Callback when indexing completes */\n onIndexComplete?: (results: IndexResult[]) => void;\n /** Callback when a file change is detected */\n onFileChange?: (event: 'add' | 'change' | 'unlink', filepath: string) => void;\n /** Callback for errors */\n onError?: (error: Error) => void;\n}\n\nexport interface FileWatcher {\n /** Stop watching and clean up */\n stop: () => Promise<void>;\n /** Whether the watcher is currently running */\n isRunning: () => boolean;\n}\n\n/**\n * Start watching a directory for file changes and index incrementally\n */\nexport async function watchDirectory(\n rootDir: string,\n options: WatchOptions = {}\n): Promise<FileWatcher> {\n const {\n debounceMs = DEFAULT_DEBOUNCE_MS,\n verbose = false,\n model,\n onIndexStart,\n onIndexComplete,\n onFileChange,\n onError,\n } = options;\n\n // Ensure absolute path\n rootDir = path.resolve(rootDir);\n \n // Load config\n const config = await loadConfig(rootDir);\n \n // Build glob patterns for watched files\n const watchPatterns = config.extensions.map(ext => `**/*${ext}`);\n \n // Build ignore patterns\n const ignorePatterns = [\n ...config.ignorePaths.map(p => `**/${p}/**`),\n `**/${config.indexDir}/**`, // Always ignore the index directory\n ];\n\n // State management\n let isRunning = true;\n let isIndexing = false;\n let pendingChanges = new Map<string, 'add' | 'change' | 'unlink'>();\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n let watcher: FSWatcher | null = null;\n\n /**\n * Process pending file changes\n */\n async function processPendingChanges(): Promise<void> {\n if (!isRunning || isIndexing || pendingChanges.size === 0) {\n return;\n }\n\n isIndexing = true;\n const changes = new Map(pendingChanges);\n pendingChanges.clear();\n\n try {\n // Separate additions/changes from deletions\n const filesToIndex: string[] = [];\n const filesToDelete: string[] = [];\n\n for (const [filepath, event] of changes) {\n if (event === 'unlink') {\n filesToDelete.push(filepath);\n } else {\n filesToIndex.push(filepath);\n }\n }\n\n // Handle deletions via cleanup\n if (filesToDelete.length > 0) {\n if (verbose) {\n console.log(`\\n[Watch] Cleaning up ${filesToDelete.length} deleted file(s)...`);\n }\n await cleanupIndex(rootDir, { verbose: false });\n }\n\n // Handle additions/changes via incremental index\n if (filesToIndex.length > 0) {\n if (onIndexStart) {\n onIndexStart(filesToIndex);\n }\n\n if (verbose) {\n console.log(`\\n[Watch] Indexing ${filesToIndex.length} changed file(s)...`);\n }\n\n const results = await indexDirectory(rootDir, {\n model,\n verbose: false, // Keep output clean in watch mode\n });\n\n if (onIndexComplete) {\n onIndexComplete(results);\n }\n\n // Print summary\n for (const result of results) {\n if (result.indexed > 0 || result.errors > 0) {\n console.log(`[Watch] ${result.moduleId}: ${result.indexed} indexed, ${result.errors} errors`);\n }\n }\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n console.error('[Watch] Error during indexing:', err.message);\n if (onError) {\n onError(err);\n }\n } finally {\n isIndexing = false;\n\n // Process any changes that came in while we were indexing\n if (pendingChanges.size > 0) {\n scheduleProcessing();\n }\n }\n }\n\n /**\n * Schedule processing of pending changes (with debounce)\n */\n function scheduleProcessing(): void {\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n\n // Force processing if batch is too large\n if (pendingChanges.size >= MAX_BATCH_SIZE) {\n processPendingChanges();\n return;\n }\n\n debounceTimer = setTimeout(() => {\n debounceTimer = null;\n processPendingChanges();\n }, debounceMs);\n }\n\n /**\n * Handle a file event\n */\n function handleFileEvent(event: 'add' | 'change' | 'unlink', filepath: string): void {\n if (!isRunning) return;\n\n // Convert to relative path\n const relativePath = path.relative(rootDir, filepath);\n\n // Skip if it's in an ignored directory (extra safety check)\n for (const ignorePath of config.ignorePaths) {\n if (relativePath.startsWith(ignorePath) || relativePath.includes(`/${ignorePath}/`)) {\n return;\n }\n }\n\n if (onFileChange) {\n onFileChange(event, relativePath);\n }\n\n if (verbose) {\n const symbol = event === 'add' ? '+' : event === 'unlink' ? '-' : '~';\n console.log(`[Watch] ${symbol} ${relativePath}`);\n }\n\n // Update pending changes (later events override earlier ones for same file)\n pendingChanges.set(relativePath, event);\n scheduleProcessing();\n }\n\n // Create the watcher\n watcher = watch(watchPatterns, {\n cwd: rootDir,\n ignored: ignorePatterns,\n persistent: true,\n ignoreInitial: true, // Don't trigger events for existing files\n awaitWriteFinish: {\n stabilityThreshold: 100, // Wait for file to be stable\n pollInterval: 50,\n },\n // Performance optimizations\n usePolling: false, // Use native fs events when possible\n atomic: true, // Handle atomic writes (common in editors)\n });\n\n // Set up event handlers\n watcher.on('add', (filepath) => handleFileEvent('add', path.join(rootDir, filepath)));\n watcher.on('change', (filepath) => handleFileEvent('change', path.join(rootDir, filepath)));\n watcher.on('unlink', (filepath) => handleFileEvent('unlink', path.join(rootDir, filepath)));\n\n watcher.on('error', (error: unknown) => {\n const err = error instanceof Error ? error : new Error(String(error));\n console.error('[Watch] Watcher error:', err);\n if (onError) {\n onError(err);\n }\n });\n\n // Wait for watcher to be ready\n await new Promise<void>((resolve) => {\n watcher!.on('ready', () => {\n resolve();\n });\n });\n\n // Return control interface\n return {\n stop: async () => {\n isRunning = false;\n \n if (debounceTimer) {\n clearTimeout(debounceTimer);\n debounceTimer = null;\n }\n \n if (watcher) {\n await watcher.close();\n watcher = null;\n }\n },\n isRunning: () => isRunning,\n };\n}\n\n",
16
+ "// Main indexer - coordinates modules for indexing files\nimport { glob } from 'glob';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport {\n Config,\n IndexContext,\n IndexModule,\n ModuleManifest,\n GlobalManifest,\n FileIndex,\n} from '../types';\nimport {\n DEFAULT_CONFIG,\n loadConfig,\n getModuleIndexPath,\n getModuleManifestPath,\n getGlobalManifestPath,\n getModuleConfig,\n} from '../utils/config';\nimport { registry, registerBuiltInModules } from '../modules/registry';\nimport { EmbeddingModelName } from '../utils/embeddings';\n\nexport interface IndexResult {\n moduleId: string;\n indexed: number;\n skipped: number;\n errors: number;\n}\n\nexport interface IndexOptions {\n /** Override the embedding model (semantic module) */\n model?: EmbeddingModelName;\n /** Show detailed progress */\n verbose?: boolean;\n}\n\nexport interface CleanupResult {\n moduleId: string;\n /** Number of stale entries removed */\n removed: number;\n /** Number of valid entries kept */\n kept: number;\n}\n\nexport interface IndexStatus {\n /** Whether an index exists */\n exists: boolean;\n /** Root directory path */\n rootDir: string;\n /** Index directory path */\n indexDir: string;\n /** Last time the index was updated */\n lastUpdated?: string;\n /** Active modules and their file counts */\n modules: Array<{\n id: string;\n fileCount: number;\n lastUpdated: string;\n }>;\n /** Total number of indexed files */\n totalFiles: number;\n}\n\n/**\n * Index a directory using all enabled modules\n */\nexport async function indexDirectory(rootDir: string, options: IndexOptions = {}): Promise<IndexResult[]> {\n const verbose = options.verbose ?? false;\n \n // Ensure absolute path\n rootDir = path.resolve(rootDir);\n \n console.log(`Indexing directory: ${rootDir}`);\n\n // Load config\n const config = await loadConfig(rootDir);\n\n // Register built-in modules\n await registerBuiltInModules();\n\n // Get enabled modules\n const enabledModules = registry.getEnabled(config);\n\n if (enabledModules.length === 0) {\n console.log('No modules enabled. Check your configuration.');\n return [];\n }\n\n console.log(`Enabled modules: ${enabledModules.map((m) => m.id).join(', ')}`);\n\n // Get all files matching extensions\n const files = await findFiles(rootDir, config);\n console.log(`Found ${files.length} files to index`);\n\n // Index with each module\n const results: IndexResult[] = [];\n\n for (const module of enabledModules) {\n console.log(`\\n[${module.name}] Starting indexing...`);\n\n // Initialize module if needed\n const moduleConfig = getModuleConfig(config, module.id);\n if (module.initialize && moduleConfig) {\n // Apply CLI overrides to module config\n const configWithOverrides = { ...moduleConfig };\n if (options.model && module.id === 'semantic') {\n configWithOverrides.options = {\n ...configWithOverrides.options,\n embeddingModel: options.model,\n };\n }\n await module.initialize(configWithOverrides);\n }\n\n const result = await indexWithModule(rootDir, files, module, config, verbose);\n results.push(result);\n\n // Call finalize to build secondary indexes (Tier 1, BM25, etc.)\n if (module.finalize) {\n console.log(`[${module.name}] Building secondary indexes...`);\n const ctx: IndexContext = {\n rootDir,\n config,\n readFile: async (filepath: string) => {\n const fullPath = path.isAbsolute(filepath) ? filepath : path.join(rootDir, filepath);\n return fs.readFile(fullPath, 'utf-8');\n },\n getFileStats: async (filepath: string) => {\n const fullPath = path.isAbsolute(filepath) ? filepath : path.join(rootDir, filepath);\n const stats = await fs.stat(fullPath);\n return { lastModified: stats.mtime.toISOString() };\n },\n };\n await module.finalize(ctx);\n }\n\n console.log(`[${module.name}] Complete: ${result.indexed} indexed, ${result.skipped} skipped, ${result.errors} errors`);\n }\n\n // Update global manifest\n await updateGlobalManifest(rootDir, enabledModules, config);\n\n return results;\n}\n\n/**\n * Index files with a specific module\n */\nasync function indexWithModule(\n rootDir: string,\n files: string[],\n module: IndexModule,\n config: Config,\n verbose: boolean\n): Promise<IndexResult> {\n const result: IndexResult = {\n moduleId: module.id,\n indexed: 0,\n skipped: 0,\n errors: 0,\n };\n\n // Load existing manifest for this module\n const manifest = await loadModuleManifest(rootDir, module.id, config);\n\n // Create index context\n const ctx: IndexContext = {\n rootDir,\n config,\n readFile: async (filepath: string) => {\n const fullPath = path.isAbsolute(filepath) ? filepath : path.join(rootDir, filepath);\n return fs.readFile(fullPath, 'utf-8');\n },\n getFileStats: async (filepath: string) => {\n const fullPath = path.isAbsolute(filepath) ? filepath : path.join(rootDir, filepath);\n const stats = await fs.stat(fullPath);\n return { lastModified: stats.mtime.toISOString() };\n },\n };\n\n // Process each file\n for (const filepath of files) {\n const relativePath = path.relative(rootDir, filepath);\n \n try {\n const stats = await fs.stat(filepath);\n const lastModified = stats.mtime.toISOString();\n\n // Check if file needs re-indexing\n const existingEntry = manifest.files[relativePath];\n if (existingEntry && existingEntry.lastModified === lastModified) {\n if (verbose) {\n console.log(` Skipped ${relativePath} (unchanged)`);\n }\n result.skipped++;\n continue;\n }\n\n // Read and index file\n const content = await fs.readFile(filepath, 'utf-8');\n \n if (verbose) {\n console.log(` Processing ${relativePath}...`);\n }\n const fileIndex = await module.indexFile(relativePath, content, ctx);\n\n if (!fileIndex) {\n if (verbose) {\n console.log(` Skipped ${relativePath} (no chunks)`);\n }\n result.skipped++;\n continue;\n }\n\n // Write index file\n await writeFileIndex(rootDir, module.id, relativePath, fileIndex, config);\n\n // Update manifest\n manifest.files[relativePath] = {\n lastModified,\n chunkCount: fileIndex.chunks.length,\n };\n\n result.indexed++;\n } catch (error) {\n console.error(` Error indexing ${relativePath}:`, error);\n result.errors++;\n }\n }\n\n // Update manifest\n manifest.lastUpdated = new Date().toISOString();\n await writeModuleManifest(rootDir, module.id, manifest, config);\n\n return result;\n}\n\nasync function findFiles(rootDir: string, config: Config): Promise<string[]> {\n const patterns = config.extensions.map((ext) => `**/*${ext}`);\n const ignorePatterns = config.ignorePaths.map((p) => `**/${p}/**`);\n\n const files: string[] = [];\n for (const pattern of patterns) {\n const matches = await glob(pattern, {\n cwd: rootDir,\n absolute: true,\n ignore: ignorePatterns,\n });\n files.push(...matches);\n }\n\n return [...new Set(files)]; // Remove duplicates\n}\n\nasync function loadModuleManifest(\n rootDir: string,\n moduleId: string,\n config: Config\n): Promise<ModuleManifest> {\n const manifestPath = getModuleManifestPath(rootDir, moduleId, config);\n\n try {\n const content = await fs.readFile(manifestPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return {\n moduleId,\n version: '1.0.0',\n lastUpdated: new Date().toISOString(),\n files: {},\n };\n }\n}\n\nasync function writeModuleManifest(\n rootDir: string,\n moduleId: string,\n manifest: ModuleManifest,\n config: Config\n): Promise<void> {\n const manifestPath = getModuleManifestPath(rootDir, moduleId, config);\n await fs.mkdir(path.dirname(manifestPath), { recursive: true });\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2));\n}\n\nasync function writeFileIndex(\n rootDir: string,\n moduleId: string,\n filepath: string,\n fileIndex: FileIndex,\n config: Config\n): Promise<void> {\n const indexPath = getModuleIndexPath(rootDir, moduleId, config);\n const indexFilePath = path.join(indexPath, filepath.replace(/\\.[^.]+$/, '.json'));\n\n await fs.mkdir(path.dirname(indexFilePath), { recursive: true });\n await fs.writeFile(indexFilePath, JSON.stringify(fileIndex, null, 2));\n}\n\nasync function updateGlobalManifest(\n rootDir: string,\n modules: IndexModule[],\n config: Config\n): Promise<void> {\n const manifestPath = getGlobalManifestPath(rootDir, config);\n\n const manifest: GlobalManifest = {\n version: config.version,\n lastUpdated: new Date().toISOString(),\n modules: modules.map((m) => m.id),\n };\n\n await fs.mkdir(path.dirname(manifestPath), { recursive: true });\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2));\n}\n\n/**\n * Clean up stale index entries for files that no longer exist\n * @param rootDir - Root directory of the project\n * @param options - Cleanup options\n * @returns Array of cleanup results per module\n */\nexport async function cleanupIndex(\n rootDir: string, \n options: { verbose?: boolean } = {}\n): Promise<CleanupResult[]> {\n const verbose = options.verbose ?? false;\n \n // Ensure absolute path\n rootDir = path.resolve(rootDir);\n \n console.log(`Cleaning up index in: ${rootDir}`);\n\n // Load config\n const config = await loadConfig(rootDir);\n\n // Register built-in modules\n await registerBuiltInModules();\n\n // Get enabled modules\n const enabledModules = registry.getEnabled(config);\n\n if (enabledModules.length === 0) {\n console.log('No modules enabled.');\n return [];\n }\n\n const results: CleanupResult[] = [];\n\n for (const module of enabledModules) {\n console.log(`\\n[${module.name}] Checking for stale entries...`);\n \n const result = await cleanupModuleIndex(rootDir, module.id, config, verbose);\n results.push(result);\n \n console.log(`[${module.name}] Removed ${result.removed} stale entries, kept ${result.kept} valid entries`);\n }\n\n return results;\n}\n\n/**\n * Clean up stale index entries for a specific module\n */\nasync function cleanupModuleIndex(\n rootDir: string,\n moduleId: string,\n config: Config,\n verbose: boolean\n): Promise<CleanupResult> {\n const result: CleanupResult = {\n moduleId,\n removed: 0,\n kept: 0,\n };\n\n // Load manifest\n const manifest = await loadModuleManifest(rootDir, moduleId, config);\n const indexPath = getModuleIndexPath(rootDir, moduleId, config);\n \n const filesToRemove: string[] = [];\n const updatedFiles: ModuleManifest['files'] = {};\n\n // Check each indexed file\n for (const [filepath, entry] of Object.entries(manifest.files)) {\n const fullPath = path.join(rootDir, filepath);\n \n try {\n await fs.access(fullPath);\n // File exists, keep it\n updatedFiles[filepath] = entry;\n result.kept++;\n } catch {\n // File doesn't exist, mark for removal\n filesToRemove.push(filepath);\n result.removed++;\n \n if (verbose) {\n console.log(` Removing stale entry: ${filepath}`);\n }\n }\n }\n\n // Remove stale index files\n for (const filepath of filesToRemove) {\n const indexFilePath = path.join(indexPath, filepath.replace(/\\.[^.]+$/, '.json'));\n try {\n await fs.unlink(indexFilePath);\n } catch {\n // Index file may not exist, that's okay\n }\n }\n\n // Update manifest with only valid files\n manifest.files = updatedFiles;\n manifest.lastUpdated = new Date().toISOString();\n await writeModuleManifest(rootDir, moduleId, manifest, config);\n\n // Clean up empty directories in the index\n await cleanupEmptyDirectories(indexPath);\n\n return result;\n}\n\n/**\n * Recursively remove empty directories\n */\nasync function cleanupEmptyDirectories(dir: string): Promise<boolean> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n // Process subdirectories first\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const subDir = path.join(dir, entry.name);\n await cleanupEmptyDirectories(subDir);\n }\n }\n \n // Check if directory is now empty (re-read after potential subdirectory removal)\n const remainingEntries = await fs.readdir(dir);\n \n // Don't remove the root index directory or manifest files\n if (remainingEntries.length === 0) {\n await fs.rmdir(dir);\n return true;\n }\n \n return false;\n } catch {\n return false;\n }\n}\n\n/**\n * Get the current status of the index\n * @param rootDir - Root directory of the project\n * @returns Index status information\n */\nexport async function getIndexStatus(rootDir: string): Promise<IndexStatus> {\n // Ensure absolute path\n rootDir = path.resolve(rootDir);\n \n // Load config\n const config = await loadConfig(rootDir);\n const indexDir = path.join(rootDir, config.indexDir);\n \n const status: IndexStatus = {\n exists: false,\n rootDir,\n indexDir,\n modules: [],\n totalFiles: 0,\n };\n \n // Check if index directory exists\n try {\n await fs.access(indexDir);\n } catch {\n return status;\n }\n \n // Try to load global manifest\n try {\n const globalManifestPath = getGlobalManifestPath(rootDir, config);\n const content = await fs.readFile(globalManifestPath, 'utf-8');\n const globalManifest: GlobalManifest = JSON.parse(content);\n \n status.exists = true;\n status.lastUpdated = globalManifest.lastUpdated;\n \n // Load each module's manifest\n for (const moduleId of globalManifest.modules) {\n try {\n const manifest = await loadModuleManifest(rootDir, moduleId, config);\n const fileCount = Object.keys(manifest.files).length;\n \n status.modules.push({\n id: moduleId,\n fileCount,\n lastUpdated: manifest.lastUpdated,\n });\n \n status.totalFiles += fileCount;\n } catch {\n // Module manifest doesn't exist or is corrupt\n }\n }\n } catch {\n // Global manifest doesn't exist - check if there's any index data\n try {\n const entries = await fs.readdir(path.join(indexDir, 'index'));\n if (entries.length > 0) {\n status.exists = true;\n // Try to load manifests for known modules\n for (const entry of entries) {\n try {\n const manifest = await loadModuleManifest(rootDir, entry, config);\n const fileCount = Object.keys(manifest.files).length;\n \n status.modules.push({\n id: entry,\n fileCount,\n lastUpdated: manifest.lastUpdated,\n });\n \n status.totalFiles += fileCount;\n } catch {\n // Skip\n }\n }\n }\n } catch {\n // No index directory\n }\n }\n \n return status;\n}\n\n// Re-export watcher\nexport { watchDirectory, type WatchOptions, type FileWatcher } from './watcher';\n",
16
17
  "// Search module - queries across all enabled modules\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport {\n Config,\n SearchContext,\n SearchOptions,\n SearchResult,\n FileIndex,\n IndexModule,\n GlobalManifest,\n} from '../types';\nimport {\n loadConfig,\n getModuleIndexPath,\n getGlobalManifestPath,\n getModuleConfig,\n} from '../utils/config';\nimport { registry, registerBuiltInModules } from '../modules/registry';\n\n/**\n * Search across all enabled modules\n */\nexport async function search(\n rootDir: string,\n query: string,\n options: SearchOptions = {}\n): Promise<SearchResult[]> {\n // Ensure absolute path\n rootDir = path.resolve(rootDir);\n\n console.log(`Searching for: \"${query}\"`);\n\n // Load config\n const config = await loadConfig(rootDir);\n\n // Register built-in modules\n await registerBuiltInModules();\n\n // Check which modules have indexes\n const globalManifest = await loadGlobalManifest(rootDir, config);\n \n if (!globalManifest || globalManifest.modules.length === 0) {\n console.log('No index found. Run \"bun run index\" first.');\n return [];\n }\n\n // Get modules that are both enabled and have indexes\n const modulesToSearch: IndexModule[] = [];\n \n for (const moduleId of globalManifest.modules) {\n const module = registry.get(moduleId);\n const moduleConfig = getModuleConfig(config, moduleId);\n \n if (module && moduleConfig?.enabled) {\n // Initialize module if needed\n if (module.initialize) {\n await module.initialize(moduleConfig);\n }\n modulesToSearch.push(module);\n }\n }\n\n if (modulesToSearch.length === 0) {\n console.log('No enabled modules with indexes found.');\n return [];\n }\n\n // Search with each module and aggregate results\n const allResults: SearchResult[] = [];\n\n for (const module of modulesToSearch) {\n const ctx = createSearchContext(rootDir, module.id, config);\n const moduleResults = await module.search(query, ctx, options);\n allResults.push(...moduleResults);\n }\n\n // Sort all results by score\n allResults.sort((a, b) => b.score - a.score);\n\n // Return top K\n const topK = options.topK ?? 10;\n return allResults.slice(0, topK);\n}\n\n/**\n * Create a search context for a specific module\n */\nfunction createSearchContext(\n rootDir: string,\n moduleId: string,\n config: Config\n): SearchContext {\n const indexPath = getModuleIndexPath(rootDir, moduleId, config);\n\n return {\n rootDir,\n config,\n \n loadFileIndex: async (filepath: string): Promise<FileIndex | null> => {\n // filepath may or may not have an extension\n // If it has an extension, replace it with .json; otherwise append .json\n const hasExtension = /\\.[^./]+$/.test(filepath);\n const indexFilePath = hasExtension\n ? path.join(indexPath, filepath.replace(/\\.[^.]+$/, '.json'))\n : path.join(indexPath, filepath + '.json');\n \n try {\n const content = await fs.readFile(indexFilePath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n },\n \n listIndexedFiles: async (): Promise<string[]> => {\n const files: string[] = [];\n await traverseDirectory(indexPath, files, indexPath);\n \n // Convert index file paths back to source file paths\n return files\n .filter(f => f.endsWith('.json') && !f.endsWith('manifest.json'))\n .map(f => {\n const relative = path.relative(indexPath, f);\n // Convert .json back to original extension (we'll handle this generically)\n return relative.replace(/\\.json$/, '');\n });\n },\n };\n}\n\nasync function traverseDirectory(dir: string, files: string[], basePath: string): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await traverseDirectory(fullPath, files, basePath);\n } else if (entry.isFile()) {\n files.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist\n }\n}\n\nasync function loadGlobalManifest(rootDir: string, config: Config): Promise<GlobalManifest | null> {\n const manifestPath = getGlobalManifestPath(rootDir, config);\n\n try {\n const content = await fs.readFile(manifestPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n/**\n * Format search results for display\n * @param results - Array of search results to format\n * @returns Formatted string for console output\n */\nexport function formatSearchResults(results: SearchResult[]): string {\n if (results.length === 0) {\n return 'No results found.';\n }\n\n let output = `Found ${results.length} results:\\n\\n`;\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n const { chunk } = result;\n \n // Format location with optional name\n const location = `${result.filepath}:${chunk.startLine}-${chunk.endLine}`;\n const nameInfo = chunk.name ? ` (${chunk.name})` : '';\n \n output += `${i + 1}. ${location}${nameInfo}\\n`;\n output += ` Score: ${(result.score * 100).toFixed(1)}% | Type: ${chunk.type}`;\n \n // Add export indicator\n if (chunk.isExported) {\n output += ' | exported';\n }\n output += '\\n';\n\n // Show preview (first 3 lines)\n const lines = chunk.content.split('\\n').slice(0, 3);\n for (const line of lines) {\n const trimmedLine = line.substring(0, 80);\n output += ` ${trimmedLine}${line.length > 80 ? '...' : ''}\\n`;\n }\n\n output += '\\n';\n }\n\n return output;\n}\n",
17
- "// Main CLI entry point for raggrep\n\nimport { EMBEDDING_MODELS, getCacheDir, type EmbeddingModelName } from '../utils/embeddings';\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\n/**\n * Parsed CLI flags from command line arguments\n */\ninterface ParsedFlags {\n /** Embedding model to use */\n model?: EmbeddingModelName;\n /** Number of results to return */\n topK?: number;\n /** Minimum similarity score threshold (0-1) */\n minScore?: number;\n /** File extension filter (e.g., 'ts', 'tsx') */\n fileType?: string;\n /** Show help message */\n help: boolean;\n /** Show detailed progress */\n verbose: boolean;\n /** Remaining positional arguments */\n remaining: string[];\n}\n\n/**\n * Parse CLI flags from command line arguments\n * @param args - Array of command line arguments (excluding command name)\n * @returns Parsed flags object\n */\nfunction parseFlags(args: string[]): ParsedFlags {\n const flags: ParsedFlags = {\n help: false,\n verbose: false,\n remaining: [],\n };\n \n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n \n if (arg === '--help' || arg === '-h') {\n flags.help = true;\n } else if (arg === '--verbose' || arg === '-v') {\n flags.verbose = true;\n } else if (arg === '--model' || arg === '-m') {\n const modelName = args[++i];\n if (modelName && modelName in EMBEDDING_MODELS) {\n flags.model = modelName as EmbeddingModelName;\n } else {\n console.error(`Invalid model: ${modelName}`);\n console.error(`Available models: ${Object.keys(EMBEDDING_MODELS).join(', ')}`);\n process.exit(1);\n }\n } else if (arg === '--top' || arg === '-k') {\n const k = parseInt(args[++i], 10);\n if (!isNaN(k) && k > 0) {\n flags.topK = k;\n }\n } else if (arg === '--min-score' || arg === '-s') {\n const score = parseFloat(args[++i]);\n if (!isNaN(score) && score >= 0 && score <= 1) {\n flags.minScore = score;\n } else {\n console.error(`Invalid min-score: ${args[i]}. Must be a number between 0 and 1.`);\n process.exit(1);\n }\n } else if (arg === '--type' || arg === '-t') {\n const type = args[++i];\n if (type) {\n // Normalize: remove leading dot if present\n flags.fileType = type.startsWith('.') ? type.slice(1) : type;\n } else {\n console.error('--type requires a file extension (e.g., ts, tsx, js)');\n process.exit(1);\n }\n } else if (!arg.startsWith('-')) {\n flags.remaining.push(arg);\n }\n }\n \n return flags;\n}\n\nasync function main() {\n const flags = parseFlags(args.slice(1)); // Skip the command itself\n \n switch (command) {\n case 'index': {\n if (flags.help) {\n const models = Object.keys(EMBEDDING_MODELS).join(', ');\n console.log(`\nraggrep index - Index the current directory for semantic search\n\nUsage:\n raggrep index [options]\n\nOptions:\n -m, --model <name> Embedding model to use (default: all-MiniLM-L6-v2)\n -v, --verbose Show detailed progress\n -h, --help Show this help message\n\nAvailable Models:\n ${models}\n\nModel Cache: ${getCacheDir()}\n\nExamples:\n raggrep index\n raggrep index --model bge-small-en-v1.5\n raggrep index --verbose\n`);\n process.exit(0);\n }\n\n const { indexDirectory } = await import('../indexer');\n console.log('RAGgrep Indexer');\n console.log('================\\n');\n try {\n const results = await indexDirectory(process.cwd(), { \n model: flags.model,\n verbose: flags.verbose,\n });\n console.log('\\n================');\n console.log('Summary:');\n for (const result of results) {\n console.log(` ${result.moduleId}: ${result.indexed} indexed, ${result.skipped} skipped, ${result.errors} errors`);\n }\n } catch (error) {\n console.error('Error during indexing:', error);\n process.exit(1);\n }\n break;\n }\n\n case 'query': {\n if (flags.help) {\n console.log(`\nraggrep query - Search the indexed codebase\n\nUsage:\n raggrep query <search query> [options]\n\nOptions:\n -k, --top <n> Number of results to return (default: 10)\n -s, --min-score <n> Minimum similarity score 0-1 (default: 0.15)\n -t, --type <ext> Filter by file extension (e.g., ts, tsx, js)\n -h, --help Show this help message\n\nExamples:\n raggrep query \"user authentication\"\n raggrep query \"handle errors\" --top 5\n raggrep query \"database\" --min-score 0.1\n raggrep query \"interface\" --type ts\n`);\n process.exit(0);\n }\n\n const { search, formatSearchResults } = await import('../search');\n const query = flags.remaining[0];\n \n if (!query) {\n console.error('Usage: raggrep query <search query>');\n console.error('Run \"raggrep query --help\" for more information.');\n process.exit(1);\n }\n \n console.log('RAGgrep Search');\n console.log('==============\\n');\n try {\n // Build file patterns if type filter specified\n const filePatterns = flags.fileType ? [`*.${flags.fileType}`] : undefined;\n \n const results = await search(process.cwd(), query, { \n topK: flags.topK ?? 10,\n minScore: flags.minScore,\n filePatterns,\n });\n console.log(formatSearchResults(results));\n } catch (error) {\n console.error('Error during search:', error);\n process.exit(1);\n }\n break;\n }\n\n case 'cleanup': {\n if (flags.help) {\n console.log(`\nraggrep cleanup - Remove stale index entries for deleted files\n\nUsage:\n raggrep cleanup [options]\n\nOptions:\n -v, --verbose Show detailed progress\n -h, --help Show this help message\n\nDescription:\n Scans the index and removes entries for files that no longer exist.\n Run this command after deleting files to clean up the index.\n\nExamples:\n raggrep cleanup\n raggrep cleanup --verbose\n`);\n process.exit(0);\n }\n\n const { cleanupIndex } = await import('../indexer');\n console.log('RAGgrep Cleanup');\n console.log('===============\\n');\n try {\n const results = await cleanupIndex(process.cwd(), { \n verbose: flags.verbose,\n });\n console.log('\\n===============');\n console.log('Summary:');\n for (const result of results) {\n console.log(` ${result.moduleId}: ${result.removed} removed, ${result.kept} kept`);\n }\n } catch (error) {\n console.error('Error during cleanup:', error);\n process.exit(1);\n }\n break;\n }\n\n default:\n console.log(`\nraggrep - Local filesystem-based RAG system for codebases\n\nUsage:\n raggrep <command> [options]\n\nCommands:\n index Index the current directory\n query Search the indexed codebase\n cleanup Remove stale index entries for deleted files\n\nOptions:\n -h, --help Show help for a command\n\nExamples:\n raggrep index\n raggrep index --model bge-small-en-v1.5\n raggrep query \"user login\"\n raggrep query \"handle errors\" --top 5\n raggrep cleanup\n\nRun 'raggrep <command> --help' for more information.\n`);\n if (command && command !== '--help' && command !== '-h') {\n console.error(`Unknown command: ${command}`);\n process.exit(1);\n }\n }\n}\n\nmain();\n"
18
+ "// Main CLI entry point for raggrep\n\nimport { EMBEDDING_MODELS, getCacheDir, type EmbeddingModelName } from '../utils/embeddings';\nimport { createRequire } from 'module';\n\n// Read version from package.json\nconst require = createRequire(import.meta.url);\nconst pkg = require('../../package.json');\nconst VERSION = pkg.version;\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\n// Handle --version / -v at top level (before any command)\nif (command === '--version' || command === '-v') {\n console.log(`raggrep v${VERSION}`);\n process.exit(0);\n}\n\n/**\n * Format a date as a human-readable \"time ago\" string\n */\nfunction formatTimeAgo(date: Date): string {\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffSecs = Math.floor(diffMs / 1000);\n const diffMins = Math.floor(diffSecs / 60);\n const diffHours = Math.floor(diffMins / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffSecs < 60) return 'just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n \n // For older dates, show the actual date\n return date.toLocaleDateString();\n}\n\n/**\n * Parsed CLI flags from command line arguments\n */\ninterface ParsedFlags {\n /** Embedding model to use */\n model?: EmbeddingModelName;\n /** Number of results to return */\n topK?: number;\n /** Minimum similarity score threshold (0-1) */\n minScore?: number;\n /** File extension filter (e.g., 'ts', 'tsx') */\n fileType?: string;\n /** Show help message */\n help: boolean;\n /** Show detailed progress */\n verbose: boolean;\n /** Watch mode for continuous indexing */\n watch: boolean;\n /** Remaining positional arguments */\n remaining: string[];\n}\n\n/**\n * Parse CLI flags from command line arguments\n * @param args - Array of command line arguments (excluding command name)\n * @returns Parsed flags object\n */\nfunction parseFlags(args: string[]): ParsedFlags {\n const flags: ParsedFlags = {\n help: false,\n verbose: false,\n watch: false,\n remaining: [],\n };\n \n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n \n if (arg === '--help' || arg === '-h') {\n flags.help = true;\n } else if (arg === '--verbose' || arg === '-v') {\n flags.verbose = true;\n } else if (arg === '--watch' || arg === '-w') {\n flags.watch = true;\n } else if (arg === '--model' || arg === '-m') {\n const modelName = args[++i];\n if (modelName && modelName in EMBEDDING_MODELS) {\n flags.model = modelName as EmbeddingModelName;\n } else {\n console.error(`Invalid model: ${modelName}`);\n console.error(`Available models: ${Object.keys(EMBEDDING_MODELS).join(', ')}`);\n process.exit(1);\n }\n } else if (arg === '--top' || arg === '-k') {\n const k = parseInt(args[++i], 10);\n if (!isNaN(k) && k > 0) {\n flags.topK = k;\n }\n } else if (arg === '--min-score' || arg === '-s') {\n const score = parseFloat(args[++i]);\n if (!isNaN(score) && score >= 0 && score <= 1) {\n flags.minScore = score;\n } else {\n console.error(`Invalid min-score: ${args[i]}. Must be a number between 0 and 1.`);\n process.exit(1);\n }\n } else if (arg === '--type' || arg === '-t') {\n const type = args[++i];\n if (type) {\n // Normalize: remove leading dot if present\n flags.fileType = type.startsWith('.') ? type.slice(1) : type;\n } else {\n console.error('--type requires a file extension (e.g., ts, tsx, js)');\n process.exit(1);\n }\n } else if (!arg.startsWith('-')) {\n flags.remaining.push(arg);\n }\n }\n \n return flags;\n}\n\nasync function main() {\n const flags = parseFlags(args.slice(1)); // Skip the command itself\n \n switch (command) {\n case 'index': {\n if (flags.help) {\n const models = Object.keys(EMBEDDING_MODELS).join(', ');\n console.log(`\nraggrep index - Index the current directory for semantic search\n\nUsage:\n raggrep index [options]\n\nOptions:\n -w, --watch Watch for file changes and re-index automatically\n -m, --model <name> Embedding model to use (default: all-MiniLM-L6-v2)\n -v, --verbose Show detailed progress\n -h, --help Show this help message\n\nAvailable Models:\n ${models}\n\nModel Cache: ${getCacheDir()}\n\nExamples:\n raggrep index\n raggrep index --watch\n raggrep index --model bge-small-en-v1.5\n raggrep index --verbose\n`);\n process.exit(0);\n }\n\n const { indexDirectory, watchDirectory } = await import('../indexer');\n \n // Initial indexing\n console.log('RAGgrep Indexer');\n console.log('================\\n');\n try {\n const results = await indexDirectory(process.cwd(), { \n model: flags.model,\n verbose: flags.verbose,\n });\n console.log('\\n================');\n console.log('Summary:');\n for (const result of results) {\n console.log(` ${result.moduleId}: ${result.indexed} indexed, ${result.skipped} skipped, ${result.errors} errors`);\n }\n } catch (error) {\n console.error('Error during indexing:', error);\n process.exit(1);\n }\n\n // Watch mode\n if (flags.watch) {\n console.log('\\n┌─────────────────────────────────────────┐');\n console.log('│ Watching for changes... (Ctrl+C to stop) │');\n console.log('└─────────────────────────────────────────┘\\n');\n\n try {\n const watcher = await watchDirectory(process.cwd(), {\n model: flags.model,\n verbose: flags.verbose,\n onFileChange: (event, filepath) => {\n if (flags.verbose) {\n const symbol = event === 'add' ? '+' : event === 'unlink' ? '-' : '~';\n console.log(` ${symbol} ${filepath}`);\n }\n },\n });\n\n // Handle graceful shutdown\n const shutdown = async () => {\n console.log('\\n\\nStopping watcher...');\n await watcher.stop();\n console.log('Done.');\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n // Keep the process running\n await new Promise(() => {}); // Never resolves\n } catch (error) {\n console.error('Error starting watcher:', error);\n process.exit(1);\n }\n }\n break;\n }\n\n case 'query': {\n if (flags.help) {\n console.log(`\nraggrep query - Search the indexed codebase\n\nUsage:\n raggrep query <search query> [options]\n\nOptions:\n -k, --top <n> Number of results to return (default: 10)\n -s, --min-score <n> Minimum similarity score 0-1 (default: 0.15)\n -t, --type <ext> Filter by file extension (e.g., ts, tsx, js)\n -h, --help Show this help message\n\nNote:\n If the current directory has not been indexed, raggrep will\n automatically index it before searching.\n\nExamples:\n raggrep query \"user authentication\"\n raggrep query \"handle errors\" --top 5\n raggrep query \"database\" --min-score 0.1\n raggrep query \"interface\" --type ts\n`);\n process.exit(0);\n }\n\n const { search, formatSearchResults } = await import('../search');\n const { getIndexStatus, indexDirectory } = await import('../indexer');\n const query = flags.remaining[0];\n \n if (!query) {\n console.error('Usage: raggrep query <search query>');\n console.error('Run \"raggrep query --help\" for more information.');\n process.exit(1);\n }\n \n try {\n // Check if index exists, if not, create it first\n const status = await getIndexStatus(process.cwd());\n \n if (!status.exists) {\n console.log('No index found. Indexing directory first...\\n');\n console.log('RAGgrep Indexer');\n console.log('================\\n');\n \n const indexResults = await indexDirectory(process.cwd(), { \n model: flags.model,\n verbose: false,\n });\n \n console.log('\\n================');\n console.log('Summary:');\n for (const result of indexResults) {\n console.log(` ${result.moduleId}: ${result.indexed} indexed, ${result.skipped} skipped, ${result.errors} errors`);\n }\n console.log('');\n }\n \n console.log('RAGgrep Search');\n console.log('==============\\n');\n \n // Build file patterns if type filter specified\n const filePatterns = flags.fileType ? [`*.${flags.fileType}`] : undefined;\n \n const results = await search(process.cwd(), query, { \n topK: flags.topK ?? 10,\n minScore: flags.minScore,\n filePatterns,\n });\n console.log(formatSearchResults(results));\n } catch (error) {\n console.error('Error during search:', error);\n process.exit(1);\n }\n break;\n }\n\n case 'cleanup': {\n if (flags.help) {\n console.log(`\nraggrep cleanup - Remove stale index entries for deleted files\n\nUsage:\n raggrep cleanup [options]\n\nOptions:\n -v, --verbose Show detailed progress\n -h, --help Show this help message\n\nDescription:\n Scans the index and removes entries for files that no longer exist.\n Run this command after deleting files to clean up the index.\n\nExamples:\n raggrep cleanup\n raggrep cleanup --verbose\n`);\n process.exit(0);\n }\n\n const { cleanupIndex } = await import('../indexer');\n console.log('RAGgrep Cleanup');\n console.log('===============\\n');\n try {\n const results = await cleanupIndex(process.cwd(), { \n verbose: flags.verbose,\n });\n console.log('\\n===============');\n console.log('Summary:');\n for (const result of results) {\n console.log(` ${result.moduleId}: ${result.removed} removed, ${result.kept} kept`);\n }\n } catch (error) {\n console.error('Error during cleanup:', error);\n process.exit(1);\n }\n break;\n }\n\n case 'status': {\n if (flags.help) {\n console.log(`\nraggrep status - Show the current state of the index\n\nUsage:\n raggrep status [options]\n\nOptions:\n -h, --help Show this help message\n\nDescription:\n Displays information about the index in the current directory,\n including whether it exists, how many files are indexed, and\n when it was last updated.\n\nExamples:\n raggrep status\n`);\n process.exit(0);\n }\n\n const { getIndexStatus } = await import('../indexer');\n try {\n const status = await getIndexStatus(process.cwd());\n \n if (!status.exists) {\n console.log(`\n┌─────────────────────────────────────────┐\n│ RAGgrep Status │\n├─────────────────────────────────────────┤\n│ ○ Not indexed │\n└─────────────────────────────────────────┘\n\n Directory: ${status.rootDir}\n\n Run \"raggrep index\" to create an index.\n`);\n } else {\n const date = status.lastUpdated ? new Date(status.lastUpdated) : null;\n const timeAgo = date ? formatTimeAgo(date) : 'unknown';\n \n console.log(`\n┌─────────────────────────────────────────┐\n│ RAGgrep Status │\n├─────────────────────────────────────────┤\n│ ● Indexed │\n└─────────────────────────────────────────┘\n\n Files: ${status.totalFiles.toString().padEnd(10)} Updated: ${timeAgo}\n Location: ${status.indexDir}\n`);\n if (status.modules.length > 0) {\n console.log(' Modules:');\n for (const mod of status.modules) {\n console.log(` └─ ${mod.id} (${mod.fileCount} files)`);\n }\n console.log('');\n }\n }\n } catch (error) {\n console.error('Error getting status:', error);\n process.exit(1);\n }\n break;\n }\n\n default:\n console.log(`\nraggrep v${VERSION} - Local filesystem-based RAG system for codebases\n\nUsage:\n raggrep <command> [options]\n\nCommands:\n index Index the current directory\n query Search the indexed codebase\n status Show the current state of the index\n cleanup Remove stale index entries for deleted files\n\nOptions:\n -h, --help Show help for a command\n -v, --version Show version number\n\nExamples:\n raggrep index\n raggrep query \"user login\"\n raggrep status\n raggrep cleanup\n\nRun 'raggrep <command> --help' for more information.\n`);\n if (command && command !== '--help' && command !== '-h') {\n console.error(`Unknown command: ${command}`);\n process.exit(1);\n }\n }\n}\n\nmain();\n"
18
19
  ],
19
- "mappings": "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",
20
- "debugId": "8E6C629D8A1BA14F64756E2164756E21",
20
+ "mappings": "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",
21
+ "debugId": "0D3D8495D3A140B664756E2164756E21",
21
22
  "names": []
22
23
  }
@@ -7,6 +7,19 @@
7
7
  * Stored as individual files in: .raggrep/index/<module>/symbolic/<filepath>.json
8
8
  */
9
9
  import type { ChunkType } from "./chunk";
10
+ /**
11
+ * Path context information for structural search boosting.
12
+ */
13
+ export interface PathContext {
14
+ /** Directory segments (excluding filename) */
15
+ segments: string[];
16
+ /** Detected architectural layer (service, controller, repository, etc.) */
17
+ layer?: string;
18
+ /** Detected feature domain (auth, users, payments, etc.) */
19
+ domain?: string;
20
+ /** Path depth (number of directory levels) */
21
+ depth: number;
22
+ }
10
23
  /**
11
24
  * Lightweight file summary for fast filtering.
12
25
  *
@@ -26,6 +39,11 @@ export interface FileSummary {
26
39
  exports: string[];
27
40
  /** ISO timestamp of when the file was last modified */
28
41
  lastModified: string;
42
+ /**
43
+ * Parsed path context for structural boosting.
44
+ * Includes detected layer, domain, and path depth.
45
+ */
46
+ pathContext?: PathContext;
29
47
  }
30
48
  /**
31
49
  * Metadata for the symbolic index.