fix(ui): show synthesis as a 'Linking dynamic dispatch' phase; mute node:sqlite warning spam (#1299)

Two first-run UX bugs surfaced by indexing a real 1,342-file C repo:

1. After 'Resolving refs' hit 100%, the ~40 dynamic-dispatch synthesis
   passes ran with no progress surface, so the bar sat frozen at 100%
   long enough to read as a hang (the C fn-pointer pass alone can hold
   for a while on C-heavy repos). Synthesis now reports per-pass
   progress through a new 'linking' IndexProgress phase, rendered as
   'Linking dynamic dispatch'. The step total is pinned by a test to
   the synthesizer's actual __mark() count so adding a pass without
   bumping it fails loudly.

2. node:sqlite's ExperimentalWarning is emitted once per THREAD, so the
   main process plus every parse worker printed it mid-index,
   interleaved with the progress UI. All launch paths now pass
   --disable-warning=ExperimentalWarning: both bundle launchers, the
   Windows npm-shim invocation, and the CLI self-relaunch
   (NODE_RUNTIME_FLAGS, deliberately excluded from the re-exec gate so
   an older installed launcher never triggers a pointless re-exec, and
   version-gated off nodes older than the flag).

Verified end-to-end on the same repo: zero warnings, live linking bar,
byte-identical graph (50,520 nodes / 148,232 edges). Full suite green.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Colby Mchenry
2026-07-15 19:44:09 -05:00
committed by GitHub
co-authored by Claude Fable 5
parent 243ef1d3e2
commit ad5300a601
11 changed files with 239 additions and 35 deletions
+7 -2
View File
@@ -1258,7 +1258,8 @@ export class ReferenceResolver {
*/
async resolveAndPersistBatched(
onProgress?: (current: number, total: number) => void,
batchSize: number = 5000
batchSize: number = 5000,
onSynthesisProgress?: (done: number, total: number) => void
): Promise<ResolutionResult> {
// Resolution runs on the indexer's MAIN thread, and the #850 liveness
// watchdog SIGKILLs a process whose event loop stalls past its window (60s
@@ -1375,7 +1376,11 @@ export class ReferenceResolver {
// callbacks) that static parsing leaves out. Best-effort — never fail the
// index on it. See docs/design/callback-edge-synthesis.md.
try {
aggregateStats.byMethod['callback-synthesis'] = await synthesizeCallbackEdges(this.queries, this.context);
aggregateStats.byMethod['callback-synthesis'] = await synthesizeCallbackEdges(
this.queries,
this.context,
onSynthesisProgress
);
} catch {
// synthesis is additive and optional; ignore failures
}