mirror of
https://github.com/giancarloerra/socraticode.git
synced 2026-07-03 14:05:21 +02:00
e075d6ffa4
Resolves #43. On Linux/Node combinations where one ast-grep grammar package's prebuilt parser binary is missing for the host architecture (reporter: Ubuntu 24.04 + WSL2 + Node 24, missing the cpp prebuild), the existing loader silently failed to register every dynamic grammar, not just the broken one. Mechanism: registerDynamicLanguage iterates the modules it receives and accesses the lazy libraryPath getter on each. If that getter throws (because the prebuild lookup fails), the entire batch call aborts atomically — none of the 13 dynamic grammars get registered. The empty inner `catch {}` in ensureDynamicLanguages discarded the underlying reason, and the failure surfaced only at WARN as a generic "Failed to register dynamic ast-grep languages", with no indication of which grammar was the culprit. Empirically verified against @ast-grep/napi@0.40.5 in a clean Node environment: - Sequential register({A}); register({B}) calls REPLACE rather than accumulate; only the last call's grammar survives. So the obvious alternative of "register one at a time" is actively broken — it would silently leave only the last grammar in langPackages registered (php, since it's last in our list). On a polyglot codebase that's a regression. - Batch register({A, B, C}) with one entry whose libraryPath getter throws aborts atomically — none of A/B/C end up registered. The fix is to pre-validate each grammar's libraryPath getter inside our own per-grammar try/catch, exclude any that throw, then make ONE batch registerDynamicLanguage call with only the survivors: - src/services/code-graph.ts: ensureDynamicLanguages now touches mod.libraryPath inside the inner try/catch so a missing-prebuild failure is contained to that one grammar. Adds module-level loadedDynamicLanguages and failedDynamicLanguages state plus a public getDynamicLanguageStatus() introspection API. The empty `catch {}` becomes `catch (err) { ... }` capturing the actual reason. Per-grammar failures and the (now-rare) catch-all log at warn level with the underlying message. - src/tools/graph-tools.ts: codebase_graph_status now appends an "AST grammars: Loaded / Failed" block listing both sets, with the failure reason for each unloaded grammar. Users see the loader state without needing to enable debug logging. - src/services/graph-symbols.ts: extractSymbolsAndCalls bumps its failure log from DEBUG to WARN with one-shot dedupe per language — one warn per language for the lifetime of the process, not one warn per file (potentially hundreds). - src/services/graph-imports.ts: extractImports gets the same one-shot dedupe per language treatment for consistency. - tests/unit/dynamic-language-loader.test.ts: nine new tests covering the sync contract, idempotence, loaded/failed sort order, disjoint sets, and a sanity check that at least one expected grammar registers in the test environment. The loader stays sync. createRequire stays. No call-site signature changes, no test fixture rewrites. Existing 721 tests pass; with the new file, 730 tests pass. typecheck and biome clean. CodeRabbit review of the diff returned no findings. Co-authored-by: X-Adam <X-Adam@users.noreply.github.com>