From f109193e627257492a21f35dff2dfeb4fe376264 Mon Sep 17 00:00:00 2001 From: Tobi Lutke Date: Sat, 13 Dec 2025 10:27:01 -0500 Subject: [PATCH] Drop collections and path_contexts tables from schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove collections and path_contexts table creation from initializeDatabase() - Update all queries to work without these tables - Remove JOINs with collections table from document retrieval functions - Compute absolute file paths from YAML collections in application code - Update deleteContext() to use collection names instead of IDs - Update qmd.ts status command to use listCollections() from YAML - Deprecate cleanupDuplicateCollections() (returns 0) All collection and context metadata is now managed exclusively in YAML at ~/.config/qmd/index.yml. Database contains only documents and content (content-addressable storage). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .beads/issues.jsonl | 4 +- src/qmd.ts | 17 ++--- src/store.ts | 166 +++++++++++++++++++++----------------------- 3 files changed, 86 insertions(+), 101 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 933e6a0..a43b1ed 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -8,7 +8,7 @@ {"id":"qmd-6s5","title":"Export current database to index.yml","description":"Write a script to export current collections and path_contexts from SQLite to ~/.config/qmd/index.yml format. Include all collection metadata and contexts.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-13T09:54:52.707844-05:00","updated_at":"2025-12-13T09:57:36.650437-05:00","closed_at":"2025-12-13T09:57:36.650437-05:00","dependencies":[{"issue_id":"qmd-6s5","depends_on_id":"qmd-3z9","type":"blocks","created_at":"2025-12-13T09:55:07.606834-05:00","created_by":"daemon"}]} {"id":"qmd-7ss","title":"remove all the symlinks and stuff in the git repo, clean up the root directory","description":"","status":"closed","priority":4,"issue_type":"task","created_at":"2025-12-12T16:40:00.744982-05:00","updated_at":"2025-12-12T17:11:18.034215-05:00","closed_at":"2025-12-12T17:11:18.034215-05:00"} {"id":"qmd-8eu","title":"Update documents table schema for collection names","description":"Change documents.collection_id (integer FK) to documents.collection (text). Update all queries and indices. Keep backwards compatibility during transition.","design":"Schema change:\n- Add `collection TEXT` column\n- Migrate data: UPDATE documents SET collection = (SELECT name FROM collections WHERE id = collection_id)\n- Drop collection_id column\n- Update FTS5 trigger\n- Update all queries in store.ts","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-13T09:54:52.830305-05:00","updated_at":"2025-12-13T10:08:24.88716-05:00","closed_at":"2025-12-13T10:08:24.88716-05:00","dependencies":[{"issue_id":"qmd-8eu","depends_on_id":"qmd-6s5","type":"blocks","created_at":"2025-12-13T09:55:07.662048-05:00","created_by":"daemon"}]} -{"id":"qmd-9ua","title":"Update all qmd commands for YAML-based collections","description":"Update qmd.ts commands: collection add/list/remove/rename, status, update, ls. All should use collections.ts instead of store.ts collection functions.","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-13T09:54:53.14644-05:00","updated_at":"2025-12-13T09:54:53.14644-05:00","dependencies":[{"issue_id":"qmd-9ua","depends_on_id":"qmd-u84","type":"blocks","created_at":"2025-12-13T09:55:07.893268-05:00","created_by":"daemon"},{"issue_id":"qmd-9ua","depends_on_id":"qmd-oxy","type":"blocks","created_at":"2025-12-13T09:55:07.942221-05:00","created_by":"daemon"}]} +{"id":"qmd-9ua","title":"Update all qmd commands for YAML-based collections","description":"Update qmd.ts commands: collection add/list/remove/rename, status, update, ls. All should use collections.ts instead of store.ts collection functions.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-13T09:54:53.14644-05:00","updated_at":"2025-12-13T10:17:39.67707-05:00","closed_at":"2025-12-13T10:17:39.67707-05:00","dependencies":[{"issue_id":"qmd-9ua","depends_on_id":"qmd-u84","type":"blocks","created_at":"2025-12-13T09:55:07.893268-05:00","created_by":"daemon"},{"issue_id":"qmd-9ua","depends_on_id":"qmd-oxy","type":"blocks","created_at":"2025-12-13T09:55:07.942221-05:00","created_by":"daemon"}]} {"id":"qmd-afe","title":"implement qmd collection rename, which changes the global path prefix for the collection","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-12T15:55:54.779325-05:00","updated_at":"2025-12-12T16:29:24.153196-05:00","closed_at":"2025-12-12T16:29:24.153196-05:00"} {"id":"qmd-ama","title":"Refactor database system","description":"All documents should be stored as content addressable hash, e.g. hash, doc, created_at,\n┃ updated_at. documents should be a file system layer on top e.g. collection, path, hash,\n┃ created_at, updated_at. (collection,path)\n┃\n┃\n\n┃ All documents should be stored as content addressable hash, e.g. hash, doc, created_at,\n┃ updated_at. documents should be a file system layer on top e.g. collection_id, path, hash,\n┃ created_at, updated_at. (collection,path) is unique. There is also collection which stores PWD\n┃ + glob pattern, name (\\w+). Every document is treated as path qmd://collection.name/","notes":"## Completed\n- ✅ Implemented content-addressable storage (content table with hash→doc mapping)\n- ✅ Refactored documents table as file system layer (collection_id, path, hash)\n- ✅ Added collection names (e.g., \"pages\", \"journals\", \"archive\")\n- ✅ Implemented virtual paths (qmd://collection-name/path/to/file.md)\n- ✅ Added hierarchical context support (collection-scoped)\n- ✅ Successfully migrated existing database\n- ✅ Updated search functions to work with new schema\n- ✅ Updated indexing logic to use content-addressable storage\n- ✅ Orphaned content hash cleanup\n\n## Still TODO\n- Fix migration SQL to properly extract basename (currently needs manual fix)\n- Implement `qmd collection add . --name \u003cname\u003e --mask '**/*.md'`\n- Implement `qmd ls [path]` for exploring virtual file tree","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-10T10:57:35.497489-05:00","updated_at":"2025-12-12T15:39:48.879143-05:00","closed_at":"2025-12-12T15:39:48.879143-05:00"} {"id":"qmd-bs8","title":"Update documentation for YAML configuration","description":"Update CLAUDE.md, README.md with new YAML configuration approach. Document index.yml format and manual editing instructions.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-13T09:54:53.449584-05:00","updated_at":"2025-12-13T09:54:53.449584-05:00","dependencies":[{"issue_id":"qmd-bs8","depends_on_id":"qmd-1xd","type":"blocks","created_at":"2025-12-13T09:55:08.264615-05:00","created_by":"daemon"}]} @@ -28,7 +28,7 @@ {"id":"qmd-rck","title":"move the source files to src/*, clean up teh directory","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-12T16:40:19.198119-05:00","updated_at":"2025-12-12T17:12:22.502746-05:00","closed_at":"2025-12-12T17:12:22.502746-05:00"} {"id":"qmd-rhd","title":"Fix 'qmd status' output for new schema","description":"Update status to show collections by name, cleaner context display, virtual path examples.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-12T15:29:54.020596-05:00","updated_at":"2025-12-12T16:13:28.08389-05:00","closed_at":"2025-12-12T16:13:28.08389-05:00","dependencies":[{"issue_id":"qmd-rhd","depends_on_id":"qmd-ama","type":"discovered-from","created_at":"2025-12-12T15:29:54.021095-05:00","created_by":"daemon"}]} {"id":"qmd-s1y","title":"Update 'qmd add-context' for collection scoping","description":"Update add-context to work with collection-scoped contexts using new path_contexts schema.","notes":"Refactoring to:\n- qmd context add [path] \"text\" (defaults to current collection if in one)\n- qmd context list\n- qmd context rm \u003cpath\u003e\n- Support \"/\" for global/system context\n- Auto-detect collection from pwd","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-12T15:29:54.076582-05:00","updated_at":"2025-12-12T15:37:47.683263-05:00","closed_at":"2025-12-12T15:37:47.683263-05:00"} -{"id":"qmd-thw","title":"Drop collections and path_contexts tables","description":"Remove collections and path_contexts tables from schema. Update initDb() to not create these tables. Only keep documents, content, and search indices.","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-13T09:54:53.247136-05:00","updated_at":"2025-12-13T09:54:53.247136-05:00","dependencies":[{"issue_id":"qmd-thw","depends_on_id":"qmd-9ua","type":"blocks","created_at":"2025-12-13T09:55:08.027101-05:00","created_by":"daemon"}]} +{"id":"qmd-thw","title":"Drop collections and path_contexts tables","description":"Remove collections and path_contexts tables from schema. Update initDb() to not create these tables. Only keep documents, content, and search indices.","status":"in_progress","priority":1,"issue_type":"task","created_at":"2025-12-13T09:54:53.247136-05:00","updated_at":"2025-12-13T10:20:15.923202-05:00","dependencies":[{"issue_id":"qmd-thw","depends_on_id":"qmd-9ua","type":"blocks","created_at":"2025-12-13T09:55:08.027101-05:00","created_by":"daemon"}]} {"id":"qmd-u84","title":"Refactor store.ts to use collections.ts","description":"Replace all collection DB queries with collections.ts calls. Remove getCollectionById, getCollectionByName, listCollections DB functions. Use YAML config instead.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-13T09:54:52.936782-05:00","updated_at":"2025-12-13T10:16:07.681047-05:00","closed_at":"2025-12-13T10:16:07.681047-05:00","dependencies":[{"issue_id":"qmd-u84","depends_on_id":"qmd-3z9","type":"blocks","created_at":"2025-12-13T09:55:07.720439-05:00","created_by":"daemon"},{"issue_id":"qmd-u84","depends_on_id":"qmd-8eu","type":"blocks","created_at":"2025-12-13T09:55:07.782051-05:00","created_by":"daemon"}]} {"id":"qmd-vro","title":"Update 'qmd get' to support virtual paths","description":"Allow qmd get to accept both virtual paths (qmd://journals/...) and filesystem paths, plus fuzzy matching by filename.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-12-12T15:29:53.963113-05:00","updated_at":"2025-12-12T15:47:29.178955-05:00","closed_at":"2025-12-12T15:47:29.178955-05:00","dependencies":[{"issue_id":"qmd-vro","depends_on_id":"qmd-ama","type":"discovered-from","created_at":"2025-12-12T15:29:53.963641-05:00","created_by":"daemon"}]} {"id":"qmd-x19","title":"Update 'qmd add-context' for collection-scoped contexts","description":"Update add-context to work with collections:\n- qmd add-context \u003ccollection\u003e/\u003cpath\u003e \"context description\"\n- Support both virtual and filesystem paths\n- Update to use new path_contexts schema","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-12T15:29:38.142575-05:00","updated_at":"2025-12-12T15:53:00.525001-05:00","closed_at":"2025-12-12T15:53:00.525001-05:00"} diff --git a/src/qmd.ts b/src/qmd.ts index 0ab2657..f1a110f 100755 --- a/src/qmd.ts +++ b/src/qmd.ts @@ -435,17 +435,8 @@ function showStatus(): void { indexSize = stat; } catch {} - // Collections info - const collections = db.prepare(` - SELECT c.id, c.name, c.pwd, c.glob_pattern, c.created_at, - COUNT(d.id) as doc_count, - SUM(CASE WHEN d.active = 1 THEN 1 ELSE 0 END) as active_count, - MAX(d.modified_at) as last_modified - FROM collections c - LEFT JOIN documents d ON d.collection = c.name - GROUP BY c.id - ORDER BY c.name - `).all() as { id: number; name: string; pwd: string; glob_pattern: string; created_at: string; doc_count: number; active_count: number; last_modified: string | null }[]; + // Collections info (from YAML + database stats) + const collections = listCollections(db); // Overall stats const totalDocs = db.prepare(`SELECT COUNT(*) as count FROM documents WHERE active = 1`).get() as { count: number }; @@ -768,7 +759,7 @@ function contextRemove(pathArg: string): void { process.exit(1); } - const changes = deleteContext(db, coll.id, parsed.path); + const changes = deleteContext(db, coll.name, parsed.path); if (changes === 0) { console.error(`${c.yellow}No context found for: ${pathArg}${c.reset}`); @@ -796,7 +787,7 @@ function contextRemove(pathArg: string): void { process.exit(1); } - const changes = deleteContext(db, detected.collectionId, detected.relativePath); + const changes = deleteContext(db, detected.collectionName, detected.relativePath); if (changes === 0) { console.error(`${c.yellow}No context found for: qmd://${detected.collectionName}/${detected.relativePath}${c.reset}`); diff --git a/src/store.ts b/src/store.ts index 8656cfc..be0eb64 100644 --- a/src/store.ts +++ b/src/store.ts @@ -217,6 +217,10 @@ function initializeDatabase(db: Database): void { return; // Migration will call initializeDatabase again } + // Drop legacy tables that are now managed in YAML + db.exec(`DROP TABLE IF EXISTS path_contexts`); + db.exec(`DROP TABLE IF EXISTS collections`); + // Content-addressable storage - the source of truth for document content db.exec(` CREATE TABLE IF NOT EXISTS content ( @@ -226,20 +230,8 @@ function initializeDatabase(db: Database): void { ) `); - // Collections table with name field - db.exec(` - CREATE TABLE IF NOT EXISTS collections ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL UNIQUE, - pwd TEXT NOT NULL, - glob_pattern TEXT NOT NULL, - created_at TEXT NOT NULL, - updated_at TEXT NOT NULL, - UNIQUE(pwd, glob_pattern) - ) - `); - // Documents table - file system layer mapping virtual paths to content hashes + // Collections are now managed in ~/.config/qmd/index.yml db.exec(` CREATE TABLE IF NOT EXISTS documents ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -259,20 +251,6 @@ function initializeDatabase(db: Database): void { db.exec(`CREATE INDEX IF NOT EXISTS idx_documents_hash ON documents(hash)`); db.exec(`CREATE INDEX IF NOT EXISTS idx_documents_path ON documents(path, active)`); - // Path-based context (collection-scoped, hierarchical) - db.exec(` - CREATE TABLE IF NOT EXISTS path_contexts ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - collection_id INTEGER NOT NULL, - path_prefix TEXT NOT NULL, - context TEXT NOT NULL, - created_at TEXT NOT NULL, - FOREIGN KEY (collection_id) REFERENCES collections(id) ON DELETE CASCADE, - UNIQUE(collection_id, path_prefix) - ) - `); - db.exec(`CREATE INDEX IF NOT EXISTS idx_path_contexts_collection ON path_contexts(collection_id, path_prefix)`); - // Cache table for Ollama API calls db.exec(` CREATE TABLE IF NOT EXISTS ollama_cache ( @@ -1026,25 +1004,12 @@ export function cleanupOrphanedVectors(db: Database): number { /** * Remove duplicate collections, keeping the oldest one per (pwd, glob_pattern). - * Also removes bogus "." glob pattern entries. - * Returns the number of duplicate collections removed. + * NOTE: This function is deprecated since collections are now managed in YAML. + * Kept for backwards compatibility but returns 0. */ export function cleanupDuplicateCollections(db: Database): number { - // Count duplicates before removal - const beforeCount = (db.prepare(`SELECT COUNT(*) as c FROM collections`).get() as { c: number }).c; - - // Remove duplicates keeping the oldest one - db.exec(` - DELETE FROM collections WHERE id NOT IN ( - SELECT MIN(id) FROM collections GROUP BY pwd, glob_pattern - ) - `); - - // Remove bogus "." glob pattern entries (from earlier bug) - db.exec(`DELETE FROM collections WHERE glob_pattern = '.'`); - - const afterCount = (db.prepare(`SELECT COUNT(*) as c FROM collections`).get() as { c: number }).c; - return beforeCount - afterCount; + // Collections are now managed in YAML, no cleanup needed + return 0; } /** @@ -1447,15 +1412,9 @@ export function insertContext(db: Database, collectionId: number, pathPrefix: st * Delete a context for a specific collection and path prefix. * Returns the number of contexts deleted. */ -export function deleteContext(db: Database, collectionId: number, pathPrefix: string): number { - // Get collection name from ID - const coll = db.prepare(`SELECT name FROM collections WHERE id = ?`).get(collectionId) as { name: string } | null; - if (!coll) { - return 0; - } - +export function deleteContext(db: Database, collectionName: string, pathPrefix: string): number { // Use collections.ts to remove context - const success = collectionsRemoveContext(coll.name, pathPrefix); + const success = collectionsRemoveContext(collectionName, pathPrefix); return success ? 1 : 0; } @@ -1901,11 +1860,11 @@ export function reciprocalRankFusion( // ============================================================================= type DbDocRow = { - filepath: string; display_path: string; title: string; hash: string; collection: string; + path: string; modified_at: string; body_length: number; body?: string; @@ -1928,46 +1887,54 @@ export function findDocument(db: Database, filename: string, options: { includeB const bodyCol = options.includeBody ? `, content.doc as body` : ``; - // Build computed columns for filepath and display_path + // Build computed columns for display_path + // Note: filepath is computed from YAML collections after query const selectCols = ` - c.pwd || '/' || d.path as filepath, 'qmd://' || d.collection || '/' || d.path as display_path, d.title, d.hash, d.collection, + d.path, d.modified_at, LENGTH(content.doc) as body_length ${bodyCol} `; - // Try various match strategies - always join content for body_length + // Try to match by virtual path first let doc = db.prepare(` SELECT ${selectCols} FROM documents d - JOIN collections c ON c.name = d.collection JOIN content ON content.hash = d.hash - WHERE c.pwd || '/' || d.path = ? AND d.active = 1 + WHERE 'qmd://' || d.collection || '/' || d.path = ? AND d.active = 1 `).get(filepath) as DbDocRow | null; + // Try fuzzy match by virtual path if (!doc) { doc = db.prepare(` SELECT ${selectCols} FROM documents d - JOIN collections c ON c.name = d.collection JOIN content ON content.hash = d.hash - WHERE 'qmd://' || d.collection || '/' || d.path = ? AND d.active = 1 - `).get(filepath) as DbDocRow | null; + WHERE 'qmd://' || d.collection || '/' || d.path LIKE ? AND d.active = 1 + LIMIT 1 + `).get(`%${filepath}`) as DbDocRow | null; } - if (!doc) { - doc = db.prepare(` - SELECT ${selectCols} - FROM documents d - JOIN collections c ON c.name = d.collection - JOIN content ON content.hash = d.hash - WHERE (c.pwd || '/' || d.path LIKE ? OR 'qmd://' || d.collection || '/' || d.path LIKE ?) AND d.active = 1 - LIMIT 1 - `).get(`%${filepath}`, `%${filepath}`) as DbDocRow | null; + // Try to match by absolute path (requires looking up collection paths from YAML) + if (!doc && !filepath.startsWith('qmd://')) { + const collections = collectionsListCollections(); + for (const coll of collections) { + const absPath = `${coll.path}/${filepath}`; + const relativePath = absPath.startsWith(coll.path + '/') ? absPath.slice(coll.path.length + 1) : null; + if (relativePath) { + doc = db.prepare(` + SELECT ${selectCols} + FROM documents d + JOIN content ON content.hash = d.hash + WHERE d.collection = ? AND d.path = ? AND d.active = 1 + `).get(coll.name, relativePath) as DbDocRow | null; + if (doc) break; + } + } } if (!doc) { @@ -1975,10 +1942,13 @@ export function findDocument(db: Database, filename: string, options: { includeB return { error: "not_found", query: filename, similarFiles: similar }; } - const context = getContextForFile(db, doc.filepath); + // Compute absolute filepath from collection (in YAML) and relative path + const coll = getCollection(doc.collection); + const absoluteFilepath = coll ? `${coll.path}/${doc.path}` : doc.path; + const context = getContextForFile(db, absoluteFilepath); return { - filepath: doc.filepath, + filepath: absoluteFilepath, displayPath: doc.display_path, title: doc.title, context, @@ -1996,13 +1966,37 @@ export function findDocument(db: Database, filename: string, options: { includeB */ export function getDocumentBody(db: Database, doc: DocumentResult | { filepath: string }, fromLine?: number, maxLines?: number): string | null { const filepath = 'filepath' in doc ? doc.filepath : doc.filepath; - const row = db.prepare(` - SELECT content.doc as body - FROM documents d - JOIN collections c ON c.name = d.collection - JOIN content ON content.hash = d.hash - WHERE c.pwd || '/' || d.path = ? AND d.active = 1 - `).get(filepath) as { body: string } | null; + + // Try to resolve document by filepath (absolute or virtual) + let row: { body: string } | null = null; + + // Try virtual path first + if (filepath.startsWith('qmd://')) { + row = db.prepare(` + SELECT content.doc as body + FROM documents d + JOIN content ON content.hash = d.hash + WHERE 'qmd://' || d.collection || '/' || d.path = ? AND d.active = 1 + `).get(filepath) as { body: string } | null; + } + + // Try absolute path by looking up in YAML collections + if (!row) { + const collections = collectionsListCollections(); + for (const coll of collections) { + if (filepath.startsWith(coll.path + '/')) { + const relativePath = filepath.slice(coll.path.length + 1); + row = db.prepare(` + SELECT content.doc as body + FROM documents d + JOIN content ON content.hash = d.hash + WHERE d.collection = ? AND d.path = ? AND d.active = 1 + `).get(coll.name, relativePath) as { body: string } | null; + if (row) break; + } + } + } + if (!row) return null; let body = row.body; @@ -2059,11 +2053,11 @@ export function findDocuments( const bodyCol = options.includeBody ? `, content.doc as body` : ``; const selectCols = ` - c.pwd || '/' || d.path as filepath, 'qmd://' || d.collection || '/' || d.path as display_path, d.title, d.hash, d.collection, + d.path, d.modified_at, LENGTH(content.doc) as body_length ${bodyCol} @@ -2078,7 +2072,6 @@ export function findDocuments( let doc = db.prepare(` SELECT ${selectCols} FROM documents d - JOIN collections c ON c.name = d.collection JOIN content ON content.hash = d.hash WHERE 'qmd://' || d.collection || '/' || d.path = ? AND d.active = 1 `).get(name) as DbDocRow | null; @@ -2086,7 +2079,6 @@ export function findDocuments( doc = db.prepare(` SELECT ${selectCols} FROM documents d - JOIN collections c ON c.name = d.collection JOIN content ON content.hash = d.hash WHERE 'qmd://' || d.collection || '/' || d.path LIKE ? AND d.active = 1 LIMIT 1 @@ -2115,7 +2107,6 @@ export function findDocuments( fileRows = db.prepare(` SELECT ${selectCols} FROM documents d - JOIN collections c ON c.name = d.collection JOIN content ON content.hash = d.hash WHERE 'qmd://' || d.collection || '/' || d.path IN (${placeholders}) AND d.active = 1 `).all(...virtualPaths) as DbDocRow[]; @@ -2124,11 +2115,14 @@ export function findDocuments( const results: MultiGetResult[] = []; for (const row of fileRows) { - const context = getContextForFile(db, row.filepath); + // Compute absolute filepath from collection + const coll = getCollection(row.collection); + const absoluteFilepath = coll ? `${coll.path}/${row.path}` : row.path; + const context = getContextForFile(db, absoluteFilepath); if (row.body_length > maxBytes) { results.push({ - doc: { filepath: row.filepath, displayPath: row.display_path }, + doc: { filepath: absoluteFilepath, displayPath: row.display_path }, skipped: true, skipReason: `File too large (${Math.round(row.body_length / 1024)}KB > ${Math.round(maxBytes / 1024)}KB)`, }); @@ -2137,7 +2131,7 @@ export function findDocuments( results.push({ doc: { - filepath: row.filepath, + filepath: absoluteFilepath, displayPath: row.display_path, title: row.title || row.display_path.split('/').pop() || row.display_path, context,