* fix: add platform-aware semantic fallback
Make VECTOR an optional capability so Windows analysis remains stable while semantic embeddings can fall back to exact scan when native vector indexing is unavailable.
Made-with: Cursor
* fix: remove stale vector pool import
Keep the merge with main lint-clean after VECTOR loading moved out of the read pool.
* fix(lbug): bound DuckDB extension install via ExtensionManager (closes#1128)
`gitnexus analyze` could hang indefinitely (60% / 85% on Windows) when
DuckDB's `INSTALL fts` or `INSTALL VECTOR` was unable to reach
`extensions.duckdb.org`. The DuckDB driver's INSTALL is a synchronous
network call, so any blocked egress would block the Node event loop
forever.
Replace the ad-hoc, in-process INSTALL/LOAD scattered across
`lbug-adapter.ts` and `pool-adapter.ts` with a single
`ExtensionManager` that owns the lifecycle of optional DuckDB
extensions:
* `LOAD` is always tried first — per-connection, idempotent, no network.
* If `LOAD` fails and policy permits, INSTALL runs in a short-lived
child Node process bounded by `GITNEXUS_LBUG_EXTENSION_INSTALL_TIMEOUT_MS`
(default 15s). The parent loop keeps spinning; on timeout the child is
killed with SIGKILL and the capability is flagged unavailable.
* Capabilities and install attempts are cached per process, so a single
bounded install per extension covers every subsequent call.
Install policy is now an explicit, per-context decision:
* `auto` (default for analyze) — try LOAD, fall back to bounded INSTALL.
* `load-only` — used by `pool-adapter` (serve / MCP read paths) so user
queries never block on a network install.
* `never` — operator escape hatch for offline / airgapped environments.
`createFTSIndex` and `createVectorIndex` now check the boolean return
value before issuing the index DDL, so missing extensions degrade BM25
and semantic search gracefully without ever throwing during analyze.
Tests:
- New unit suite for `ExtensionManager` covering LOAD-first behavior,
all three policies, install caching, observability, and warn dedup.
- Existing vector-extension integration tests pass against the new
boolean return type.
- Existing embedding-pipeline mocks updated to return `true`.
Docs: `gitnexus/README.md` documents `GITNEXUS_LBUG_EXTENSION_INSTALL`
and `GITNEXUS_LBUG_EXTENSION_INSTALL_TIMEOUT_MS` with examples for
offline and slow-network environments.
Made-with: Cursor
* fix(lbug): move DuckDB extension install child into script
Keep the bounded out-of-process INSTALL behavior, but replace the inline child code with a stable packaged ESM script. This makes the child process directly runnable and gives debuggable stack traces without source-vs-dist branching or a runtime transpiler.
Made-with: Cursor
* fix: load VECTOR extension during DB init for semantic search
The VECTOR extension was only loaded inside the embedding generation
pipeline (createVectorIndex). On a fresh gitnexus serve session,
semantic and hybrid search failed because QUERY_VECTOR_INDEX was
unknown.
Now loads the VECTOR extension alongside FTS during database
initialization in both the single-connection and pool-based paths.
Fixes#766
* fix: reset vectorExtensionLoaded on DB close and retry paths
The vectorExtensionLoaded flag was not being reset in closeLbug() or
the busy-retry cleanup path in withLbugDb(). This caused the VECTOR
extension to not be re-loaded after a close+re-init cycle, breaking
semantic search on reconnection.
Also resets shared.ftsLoaded and shared.vectorLoaded in the pool
adapter closeOne() for external DB entries, preventing stale extension
state when the pool is re-opened.
Adds integration tests covering vector extension loading, idempotency,
and state reset on both close and busy-retry paths.
* fix: set ftsLoaded flag in initLbugWithDb to avoid redundant extension reloads
* fix: set shared.vectorLoaded flag in initLbugWithDb to avoid redundant reloads