Internal: performs the actual graph rebuild with progress tracking
( resolvedPath: string, opts: RebuildGraphOptions, )
| 180 | |
| 181 | /** Internal: performs the actual graph rebuild with progress tracking */ |
| 182 | async function doRebuildGraph( |
| 183 | resolvedPath: string, |
| 184 | opts: RebuildGraphOptions, |
| 185 | ): Promise<CodeGraph> { |
| 186 | const progress: GraphBuildProgress = { |
| 187 | startedAt: Date.now(), |
| 188 | filesTotal: 0, |
| 189 | filesProcessed: 0, |
| 190 | phase: "scanning files", |
| 191 | }; |
| 192 | graphBuildInProgress.set(resolvedPath, progress); |
| 193 | |
| 194 | try { |
| 195 | graphCache.delete(resolvedPath); |
| 196 | const built = await buildCodeGraph(resolvedPath, opts.extraExtensions, progress); |
| 197 | const graph: CodeGraph = { nodes: built.nodes, edges: built.edges }; |
| 198 | graphCache.set(resolvedPath, graph); |
| 199 | |
| 200 | // Persist file-import graph to Qdrant |
| 201 | progress.phase = "persisting"; |
| 202 | const projectId = projectIdFromPath(resolvedPath); |
| 203 | const graphCollName = graphCollectionName(projectId); |
| 204 | await saveGraphData(graphCollName, resolvedPath, graph); |
| 205 | |
| 206 | // Build & persist symbol graph (resolution + sharded persistence) — unless |
| 207 | // the caller asked to skip it (Phase F watcher path). |
| 208 | if (!opts.skipSymbolGraph) { |
| 209 | try { |
| 210 | progress.phase = "resolving symbols"; |
| 211 | resolveCallSites(graph, built.symbolsByFile, built.outgoingCallsByFile); |
| 212 | |
| 213 | progress.phase = "persisting symbols"; |
| 214 | await persistSymbolGraph(projectId, resolvedPath, built.symbolsByFile, built.outgoingCallsByFile); |
| 215 | } catch (err) { |
| 216 | logger.warn("Symbol graph build failed (file-import graph saved)", { |
| 217 | projectPath: resolvedPath, |
| 218 | error: err instanceof Error ? err.message : String(err), |
| 219 | }); |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | lastGraphBuildCompleted.set(resolvedPath, { |
| 224 | completedAt: Date.now(), |
| 225 | durationMs: Date.now() - progress.startedAt, |
| 226 | filesProcessed: progress.filesProcessed, |
| 227 | nodesCreated: graph.nodes.length, |
| 228 | edgesCreated: graph.edges.length, |
| 229 | }); |
| 230 | |
| 231 | return graph; |
| 232 | } catch (err) { |
| 233 | const message = err instanceof Error ? err.message : String(err); |
| 234 | progress.error = message; |
| 235 | lastGraphBuildCompleted.set(resolvedPath, { |
| 236 | completedAt: Date.now(), |
| 237 | durationMs: Date.now() - progress.startedAt, |
| 238 | filesProcessed: progress.filesProcessed, |
| 239 | nodesCreated: 0, |
no test coverage detected