* Rebuild the project's database from scratch and return a fresh, empty * instance — the "same result as a fresh init" semantics that `codegraph * index` documents. * * Unlike `open()` followed by `clear()`, this DISCARDS the existing * `.codegraph/codegraph.db` (and its `-wal`/`-shm`
(projectRoot: string)
| 379 | * (and running migrations against) the poisoned database entirely. |
| 380 | */ |
| 381 | static async recreate(projectRoot: string): Promise<CodeGraph> { |
| 382 | await initGrammars(); |
| 383 | const resolvedRoot = path.resolve(projectRoot); |
| 384 | |
| 385 | // Check if initialized — recreate REBUILDS an existing project; it is not a |
| 386 | // first-time `init`. |
| 387 | if (!isInitialized(resolvedRoot)) { |
| 388 | throw new Error(`CodeGraph not initialized in ${resolvedRoot}. Run init() first.`); |
| 389 | } |
| 390 | |
| 391 | const dbPath = getDatabasePath(resolvedRoot); |
| 392 | try { |
| 393 | removeDatabaseFiles(dbPath); |
| 394 | } catch (err) { |
| 395 | // POSIX unlinks an open file fine; this fires mainly on Windows when a |
| 396 | // live daemon/MCP server still holds the database. Turn the raw EBUSY into |
| 397 | // an actionable instruction instead of a generic failure. |
| 398 | const reason = err instanceof Error ? err.message : String(err); |
| 399 | throw new Error( |
| 400 | `Could not rebuild the index — the database file is in use (${reason}). ` + |
| 401 | `Stop any running CodeGraph MCP server/daemon for this project and retry, ` + |
| 402 | `or remove the ${getCodeGraphDir(resolvedRoot)} directory and run "codegraph init".` |
| 403 | ); |
| 404 | } |
| 405 | |
| 406 | // Re-create an empty, freshly-schema'd database at the same path. |
| 407 | const db = DatabaseConnection.initialize(dbPath); |
| 408 | const queries = new QueryBuilder(db.getDb()); |
| 409 | |
| 410 | return new CodeGraph(db, queries, resolvedRoot); |
| 411 | } |
| 412 | |
| 413 | /** |
| 414 | * Open synchronously (without sync) |