bluera-knowledge 0.11.18 → 0.11.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +55 -0
  3. package/dist/{chunk-6FHWC36B.js → chunk-HRQD3MPH.js} +8 -6
  4. package/dist/chunk-HRQD3MPH.js.map +1 -0
  5. package/dist/{chunk-ZZNABJMQ.js → chunk-MQGRQ2EG.js} +99 -34
  6. package/dist/chunk-MQGRQ2EG.js.map +1 -0
  7. package/dist/{chunk-ZDEO4WJT.js → chunk-Q2ZGPJ66.js} +22 -70
  8. package/dist/chunk-Q2ZGPJ66.js.map +1 -0
  9. package/dist/{chunk-5NUI6JL6.js → chunk-ZSKQIMD7.js} +5 -2
  10. package/dist/chunk-ZSKQIMD7.js.map +1 -0
  11. package/dist/index.js +36 -18
  12. package/dist/index.js.map +1 -1
  13. package/dist/mcp/server.js +3 -3
  14. package/dist/watch.service-OPLKIDFQ.js +7 -0
  15. package/dist/workers/background-worker-cli.js +3 -3
  16. package/package.json +1 -1
  17. package/src/cli/commands/crawl.ts +1 -1
  18. package/src/cli/commands/index-cmd.test.ts +14 -4
  19. package/src/cli/commands/index-cmd.ts +11 -4
  20. package/src/cli/commands/store.test.ts +211 -18
  21. package/src/cli/commands/store.ts +26 -8
  22. package/src/crawl/article-converter.test.ts +30 -61
  23. package/src/crawl/article-converter.ts +2 -8
  24. package/src/crawl/bridge.test.ts +14 -0
  25. package/src/crawl/bridge.ts +17 -5
  26. package/src/crawl/intelligent-crawler.test.ts +65 -76
  27. package/src/crawl/intelligent-crawler.ts +33 -69
  28. package/src/db/lance.test.ts +3 -4
  29. package/src/db/lance.ts +14 -19
  30. package/src/mcp/server.test.ts +56 -1
  31. package/src/mcp/server.ts +5 -1
  32. package/src/plugin/git-clone.test.ts +44 -0
  33. package/src/plugin/git-clone.ts +4 -0
  34. package/src/services/code-unit.service.test.ts +59 -6
  35. package/src/services/code-unit.service.ts +47 -2
  36. package/src/services/index.ts +19 -3
  37. package/src/services/job.service.test.ts +10 -7
  38. package/src/services/job.service.ts +12 -6
  39. package/src/services/search.service.ts +15 -9
  40. package/src/services/services.test.ts +19 -6
  41. package/src/services/watch.service.test.ts +80 -56
  42. package/src/services/watch.service.ts +9 -6
  43. package/dist/chunk-5NUI6JL6.js.map +0 -1
  44. package/dist/chunk-6FHWC36B.js.map +0 -1
  45. package/dist/chunk-ZDEO4WJT.js.map +0 -1
  46. package/dist/chunk-ZZNABJMQ.js.map +0 -1
  47. package/dist/watch.service-BJV3TI3F.js +0 -7
  48. /package/dist/{watch.service-BJV3TI3F.js.map → watch.service-OPLKIDFQ.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bluera-knowledge",
3
- "version": "0.11.18",
3
+ "version": "0.11.20",
4
4
  "description": "Clone repos, crawl docs, search locally. Fast, authoritative answers for AI coding agents.",
5
5
  "mcpServers": {
6
6
  "bluera-knowledge": {
package/CHANGELOG.md CHANGED
@@ -2,6 +2,61 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [0.11.20](https://github.com/blueraai/bluera-knowledge/compare/v0.11.6...v0.11.20) (2026-01-10)
6
+
7
+
8
+ ### Features
9
+
10
+ * **code-unit:** add interface and type extraction support ([190dded](https://github.com/blueraai/bluera-knowledge/commit/190dded78be68985c3f94c0da6ebed03659da313))
11
+ * **commands:** add test-plugin command for comprehensive plugin testing ([c6eb5e7](https://github.com/blueraai/bluera-knowledge/commit/c6eb5e7762376810a9ff3e79f794f05ff0c77b97))
12
+ * **scripts:** add post-release npm validation script ([e4c29a0](https://github.com/blueraai/bluera-knowledge/commit/e4c29a0c83907de4bc293a69a58412629457fb22))
13
+ * **scripts:** add suggest, sync, serve, mcp tests to npm validation ([49d85da](https://github.com/blueraai/bluera-knowledge/commit/49d85dad1a89691060c12f152d644844baf6e6e6))
14
+ * **scripts:** log expected vs installed version in validation script ([c77d039](https://github.com/blueraai/bluera-knowledge/commit/c77d039b27a3ccf54d50006af161ac4dcfea7b21))
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * address code review issues - resource leak and error handling ([c14e9b2](https://github.com/blueraai/bluera-knowledge/commit/c14e9b22782f0d62c04fb312a70345d7f4248ed4))
20
+ * **bridge:** close readline interfaces on stop to prevent resource leak ([e970bf9](https://github.com/blueraai/bluera-knowledge/commit/e970bf94f74bdba24803eed8714d47ed8e874117))
21
+ * **cli:** plugin-api commands now respect global options ([d3cca02](https://github.com/blueraai/bluera-knowledge/commit/d3cca02ffc679ffc187b76c7682f3cc177eabdea))
22
+ * **commands:** fix test-plugin reliability issues ([2841e9a](https://github.com/blueraai/bluera-knowledge/commit/2841e9aa6438f9fd60c70ab921575088b2921810))
23
+ * **commands:** move test-plugin to commands/ for plugin distribution ([0a3ff5f](https://github.com/blueraai/bluera-knowledge/commit/0a3ff5f91666db7efa213d5abd4c447fb07749fc))
24
+ * **crawl:** throw errors instead of fallback/graceful degradation ([19962c2](https://github.com/blueraai/bluera-knowledge/commit/19962c2114406f2fea22e5973e242f190ab65fb7))
25
+ * **git-clone:** add error handler for spawn failures ([4bf50e2](https://github.com/blueraai/bluera-knowledge/commit/4bf50e2348505dccdc94522cf42f1d4d3471480c))
26
+ * improve error handling and type safety from code review ([61710aa](https://github.com/blueraai/bluera-knowledge/commit/61710aaed48c87c457628b75e3968686377a6c92))
27
+ * **plugin:** properly close services after command execution ([eeaf743](https://github.com/blueraai/bluera-knowledge/commit/eeaf743750be73fd9c7a9e72440b2fd0fb5a53fa))
28
+ * **scripts:** show real-time output in validation script ([8a4bdec](https://github.com/blueraai/bluera-knowledge/commit/8a4bdec8b63c504d34ba35bfe19da795f7f7fd07))
29
+ * **scripts:** use mktemp for temp directories in validation script ([3107861](https://github.com/blueraai/bluera-knowledge/commit/3107861bd7a966016fde2a121469dd84756f39be))
30
+ * **search:** add defaults for env vars so CLI works standalone ([b2d2ce5](https://github.com/blueraai/bluera-knowledge/commit/b2d2ce534e8cd2ba0fc0abdac505c912a1a76035))
31
+ * **services:** throw errors instead of graceful degradation ([ca992b5](https://github.com/blueraai/bluera-knowledge/commit/ca992b5cfa4d9ebad62ee82231cfdd2d3d64012e))
32
+
33
+ ## [0.11.19](https://github.com/blueraai/bluera-knowledge/compare/v0.11.6...v0.11.19) (2026-01-10)
34
+
35
+
36
+ ### Features
37
+
38
+ * **code-unit:** add interface and type extraction support ([190dded](https://github.com/blueraai/bluera-knowledge/commit/190dded78be68985c3f94c0da6ebed03659da313))
39
+ * **commands:** add test-plugin command for comprehensive plugin testing ([c6eb5e7](https://github.com/blueraai/bluera-knowledge/commit/c6eb5e7762376810a9ff3e79f794f05ff0c77b97))
40
+ * **scripts:** add post-release npm validation script ([e4c29a0](https://github.com/blueraai/bluera-knowledge/commit/e4c29a0c83907de4bc293a69a58412629457fb22))
41
+ * **scripts:** add suggest, sync, serve, mcp tests to npm validation ([49d85da](https://github.com/blueraai/bluera-knowledge/commit/49d85dad1a89691060c12f152d644844baf6e6e6))
42
+ * **scripts:** log expected vs installed version in validation script ([c77d039](https://github.com/blueraai/bluera-knowledge/commit/c77d039b27a3ccf54d50006af161ac4dcfea7b21))
43
+
44
+
45
+ ### Bug Fixes
46
+
47
+ * **bridge:** close readline interfaces on stop to prevent resource leak ([e970bf9](https://github.com/blueraai/bluera-knowledge/commit/e970bf94f74bdba24803eed8714d47ed8e874117))
48
+ * **cli:** plugin-api commands now respect global options ([d3cca02](https://github.com/blueraai/bluera-knowledge/commit/d3cca02ffc679ffc187b76c7682f3cc177eabdea))
49
+ * **commands:** fix test-plugin reliability issues ([2841e9a](https://github.com/blueraai/bluera-knowledge/commit/2841e9aa6438f9fd60c70ab921575088b2921810))
50
+ * **commands:** move test-plugin to commands/ for plugin distribution ([0a3ff5f](https://github.com/blueraai/bluera-knowledge/commit/0a3ff5f91666db7efa213d5abd4c447fb07749fc))
51
+ * **crawl:** throw errors instead of fallback/graceful degradation ([19962c2](https://github.com/blueraai/bluera-knowledge/commit/19962c2114406f2fea22e5973e242f190ab65fb7))
52
+ * **git-clone:** add error handler for spawn failures ([4bf50e2](https://github.com/blueraai/bluera-knowledge/commit/4bf50e2348505dccdc94522cf42f1d4d3471480c))
53
+ * improve error handling and type safety from code review ([61710aa](https://github.com/blueraai/bluera-knowledge/commit/61710aaed48c87c457628b75e3968686377a6c92))
54
+ * **plugin:** properly close services after command execution ([eeaf743](https://github.com/blueraai/bluera-knowledge/commit/eeaf743750be73fd9c7a9e72440b2fd0fb5a53fa))
55
+ * **scripts:** show real-time output in validation script ([8a4bdec](https://github.com/blueraai/bluera-knowledge/commit/8a4bdec8b63c504d34ba35bfe19da795f7f7fd07))
56
+ * **scripts:** use mktemp for temp directories in validation script ([3107861](https://github.com/blueraai/bluera-knowledge/commit/3107861bd7a966016fde2a121469dd84756f39be))
57
+ * **search:** add defaults for env vars so CLI works standalone ([b2d2ce5](https://github.com/blueraai/bluera-knowledge/commit/b2d2ce534e8cd2ba0fc0abdac505c912a1a76035))
58
+ * **services:** throw errors instead of graceful degradation ([ca992b5](https://github.com/blueraai/bluera-knowledge/commit/ca992b5cfa4d9ebad62ee82231cfdd2d3d64012e))
59
+
5
60
  ## [0.11.18](https://github.com/blueraai/bluera-knowledge/compare/v0.11.6...v0.11.18) (2026-01-10)
6
61
 
7
62
 
@@ -9,7 +9,7 @@ var WatchService = class {
9
9
  this.indexService = indexService;
10
10
  this.lanceStore = lanceStore;
11
11
  }
12
- async watch(store, debounceMs = 1e3, onReindex) {
12
+ async watch(store, debounceMs, onReindex, onError) {
13
13
  if (this.watchers.has(store.id)) {
14
14
  return Promise.resolve();
15
15
  }
@@ -28,16 +28,18 @@ var WatchService = class {
28
28
  await this.lanceStore.initialize(store.id);
29
29
  await this.indexService.indexStore(store);
30
30
  onReindex?.();
31
- } catch (error) {
32
- console.error("Error during reindexing:", error);
31
+ } catch (e) {
32
+ const error = e instanceof Error ? e : new Error(String(e));
33
+ onError(error);
33
34
  }
34
35
  })();
35
36
  }, debounceMs);
36
37
  this.pendingTimeouts.set(store.id, timeout);
37
38
  };
38
39
  watcher.on("all", reindexHandler);
39
- watcher.on("error", (error) => {
40
- console.error("Watcher error:", error);
40
+ watcher.on("error", (e) => {
41
+ const error = e instanceof Error ? e : new Error(String(e));
42
+ onError(error);
41
43
  });
42
44
  this.watchers.set(store.id, watcher);
43
45
  return Promise.resolve();
@@ -64,4 +66,4 @@ var WatchService = class {
64
66
  export {
65
67
  WatchService
66
68
  };
67
- //# sourceMappingURL=chunk-6FHWC36B.js.map
69
+ //# sourceMappingURL=chunk-HRQD3MPH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/services/watch.service.ts"],"sourcesContent":["import { watch, type FSWatcher } from 'chokidar';\nimport type { IndexService } from './index.service.js';\nimport type { LanceStore } from '../db/lance.js';\nimport type { FileStore, RepoStore } from '../types/store.js';\n\nexport class WatchService {\n private readonly watchers: Map<string, FSWatcher> = new Map();\n private readonly pendingTimeouts: Map<string, NodeJS.Timeout> = new Map();\n private readonly indexService: IndexService;\n private readonly lanceStore: LanceStore;\n\n constructor(indexService: IndexService, lanceStore: LanceStore) {\n this.indexService = indexService;\n this.lanceStore = lanceStore;\n }\n\n async watch(\n store: FileStore | RepoStore,\n debounceMs: number,\n onReindex: (() => void) | undefined,\n onError: (error: Error) => void\n ): Promise<void> {\n if (this.watchers.has(store.id)) {\n return Promise.resolve(); // Already watching\n }\n\n let timeout: NodeJS.Timeout | null = null;\n\n const watcher = watch(store.path, {\n ignored: /(^|[/\\\\])\\.(git|node_modules|dist|build)/,\n persistent: true,\n ignoreInitial: true,\n });\n\n const reindexHandler = (): void => {\n if (timeout) clearTimeout(timeout);\n timeout = setTimeout(() => {\n this.pendingTimeouts.delete(store.id);\n void (async (): Promise<void> => {\n try {\n await this.lanceStore.initialize(store.id);\n await this.indexService.indexStore(store);\n onReindex?.();\n } catch (e) {\n const error = e instanceof Error ? e : new Error(String(e));\n onError(error);\n }\n })();\n }, debounceMs);\n this.pendingTimeouts.set(store.id, timeout);\n };\n\n watcher.on('all', reindexHandler);\n\n watcher.on('error', (e) => {\n const error = e instanceof Error ? e : new Error(String(e));\n onError(error);\n });\n\n this.watchers.set(store.id, watcher);\n return Promise.resolve();\n }\n\n async unwatch(storeId: string): Promise<void> {\n // Clear any pending timeout to prevent timer leak\n const pendingTimeout = this.pendingTimeouts.get(storeId);\n if (pendingTimeout) {\n clearTimeout(pendingTimeout);\n this.pendingTimeouts.delete(storeId);\n }\n\n const watcher = this.watchers.get(storeId);\n if (watcher) {\n await watcher.close();\n this.watchers.delete(storeId);\n }\n }\n\n async unwatchAll(): Promise<void> {\n for (const [id] of this.watchers) {\n await this.unwatch(id);\n }\n }\n}\n"],"mappings":";AAAA,SAAS,aAA6B;AAK/B,IAAM,eAAN,MAAmB;AAAA,EACP,WAAmC,oBAAI,IAAI;AAAA,EAC3C,kBAA+C,oBAAI,IAAI;AAAA,EACvD;AAAA,EACA;AAAA,EAEjB,YAAY,cAA4B,YAAwB;AAC9D,SAAK,eAAe;AACpB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,MACJ,OACA,YACA,WACA,SACe;AACf,QAAI,KAAK,SAAS,IAAI,MAAM,EAAE,GAAG;AAC/B,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAEA,QAAI,UAAiC;AAErC,UAAM,UAAU,MAAM,MAAM,MAAM;AAAA,MAChC,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,eAAe;AAAA,IACjB,CAAC;AAED,UAAM,iBAAiB,MAAY;AACjC,UAAI,QAAS,cAAa,OAAO;AACjC,gBAAU,WAAW,MAAM;AACzB,aAAK,gBAAgB,OAAO,MAAM,EAAE;AACpC,cAAM,YAA2B;AAC/B,cAAI;AACF,kBAAM,KAAK,WAAW,WAAW,MAAM,EAAE;AACzC,kBAAM,KAAK,aAAa,WAAW,KAAK;AACxC,wBAAY;AAAA,UACd,SAAS,GAAG;AACV,kBAAM,QAAQ,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,CAAC,CAAC;AAC1D,oBAAQ,KAAK;AAAA,UACf;AAAA,QACF,GAAG;AAAA,MACL,GAAG,UAAU;AACb,WAAK,gBAAgB,IAAI,MAAM,IAAI,OAAO;AAAA,IAC5C;AAEA,YAAQ,GAAG,OAAO,cAAc;AAEhC,YAAQ,GAAG,SAAS,CAAC,MAAM;AACzB,YAAM,QAAQ,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,CAAC,CAAC;AAC1D,cAAQ,KAAK;AAAA,IACf,CAAC;AAED,SAAK,SAAS,IAAI,MAAM,IAAI,OAAO;AACnC,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAEA,MAAM,QAAQ,SAAgC;AAE5C,UAAM,iBAAiB,KAAK,gBAAgB,IAAI,OAAO;AACvD,QAAI,gBAAgB;AAClB,mBAAa,cAAc;AAC3B,WAAK,gBAAgB,OAAO,OAAO;AAAA,IACrC;AAEA,UAAM,UAAU,KAAK,SAAS,IAAI,OAAO;AACzC,QAAI,SAAS;AACX,YAAM,QAAQ,MAAM;AACpB,WAAK,SAAS,OAAO,OAAO;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,MAAM,aAA4B;AAChC,eAAW,CAAC,EAAE,KAAK,KAAK,UAAU;AAChC,YAAM,KAAK,QAAQ,EAAE;AAAA,IACvB;AAAA,EACF;AACF;","names":[]}
@@ -323,8 +323,9 @@ var JobService = class {
323
323
  const content = fs.readFileSync(jobFile, "utf-8");
324
324
  return JSON.parse(content);
325
325
  } catch (error) {
326
- console.error(`Error reading job ${jobId}:`, error);
327
- return null;
326
+ throw new Error(
327
+ `Failed to read job ${jobId}: ${error instanceof Error ? error.message : String(error)}`
328
+ );
328
329
  }
329
330
  }
330
331
  /**
@@ -352,7 +353,9 @@ var JobService = class {
352
353
  jobs.push(job);
353
354
  }
354
355
  } catch (error) {
355
- console.error(`Error reading job file ${file}:`, error);
356
+ throw new Error(
357
+ `Failed to read job file ${file}: ${error instanceof Error ? error.message : String(error)}`
358
+ );
356
359
  }
357
360
  }
358
361
  jobs.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
@@ -413,7 +416,9 @@ var JobService = class {
413
416
  fs.unlinkSync(jobFile);
414
417
  cleaned++;
415
418
  } catch (error) {
416
- console.error(`Error deleting job file ${job.id}:`, error);
419
+ throw new Error(
420
+ `Failed to delete job file ${job.id}: ${error instanceof Error ? error.message : String(error)}`
421
+ );
417
422
  }
418
423
  }
419
424
  }
@@ -431,8 +436,9 @@ var JobService = class {
431
436
  fs.unlinkSync(jobFile);
432
437
  return true;
433
438
  } catch (error) {
434
- console.error(`Error deleting job ${jobId}:`, error);
435
- return false;
439
+ throw new Error(
440
+ `Failed to delete job ${jobId}: ${error instanceof Error ? error.message : String(error)}`
441
+ );
436
442
  }
437
443
  }
438
444
  /**
@@ -2572,6 +2578,16 @@ var CodeUnitService = class {
2572
2578
  type = "class";
2573
2579
  break;
2574
2580
  }
2581
+ if (line.match(new RegExp(`interface\\s+${symbolName}(?:\\s|{|<)`))) {
2582
+ startLine = i + 1;
2583
+ type = "interface";
2584
+ break;
2585
+ }
2586
+ if (line.match(new RegExp(`type\\s+${symbolName}(?:\\s|=|<)`))) {
2587
+ startLine = i + 1;
2588
+ type = "type";
2589
+ break;
2590
+ }
2575
2591
  if (line.match(new RegExp(`(?:const|let|var)\\s+${symbolName}\\s*=`))) {
2576
2592
  startLine = i + 1;
2577
2593
  type = "const";
@@ -2582,6 +2598,23 @@ var CodeUnitService = class {
2582
2598
  let endLine = startLine;
2583
2599
  let braceCount = 0;
2584
2600
  let foundFirstBrace = false;
2601
+ if (type === "type") {
2602
+ const firstLine2 = lines[startLine - 1] ?? "";
2603
+ if (!firstLine2.includes("{") && firstLine2.includes(";")) {
2604
+ endLine = startLine;
2605
+ const fullContent2 = firstLine2;
2606
+ const signature2 = this.extractSignature(firstLine2, symbolName, type);
2607
+ return {
2608
+ type,
2609
+ name: symbolName,
2610
+ signature: signature2,
2611
+ fullContent: fullContent2,
2612
+ startLine,
2613
+ endLine,
2614
+ language
2615
+ };
2616
+ }
2617
+ }
2585
2618
  let inSingleQuote = false;
2586
2619
  let inDoubleQuote = false;
2587
2620
  let inTemplateLiteral = false;
@@ -2672,6 +2705,16 @@ var CodeUnitService = class {
2672
2705
  if (type === "class") {
2673
2706
  return `class ${name}`;
2674
2707
  }
2708
+ if (type === "interface") {
2709
+ return `interface ${name}`;
2710
+ }
2711
+ if (type === "type") {
2712
+ const typeMatch = sig.match(new RegExp(`type\\s+(${name}(?:<[^>]+>)?)\\s*=`));
2713
+ if (typeMatch?.[1] !== void 0 && typeMatch[1].length > 0) {
2714
+ return `type ${typeMatch[1]}`;
2715
+ }
2716
+ return `type ${name}`;
2717
+ }
2675
2718
  if (type === "const") {
2676
2719
  const arrowMatch = sig.match(
2677
2720
  new RegExp(
@@ -3061,15 +3104,18 @@ var SearchService = class {
3061
3104
  async ftsSearch(query, stores, limit) {
3062
3105
  const results = [];
3063
3106
  for (const storeId of stores) {
3064
- const hits = await this.lanceStore.fullTextSearch(storeId, query, limit);
3065
- results.push(
3066
- ...hits.map((r) => ({
3067
- id: r.id,
3068
- score: r.score,
3069
- content: r.content,
3070
- metadata: r.metadata
3071
- }))
3072
- );
3107
+ try {
3108
+ const hits = await this.lanceStore.fullTextSearch(storeId, query, limit);
3109
+ results.push(
3110
+ ...hits.map((r) => ({
3111
+ id: r.id,
3112
+ score: r.score,
3113
+ content: r.content,
3114
+ metadata: r.metadata
3115
+ }))
3116
+ );
3117
+ } catch {
3118
+ }
3073
3119
  }
3074
3120
  return results.sort((a, b) => b.score - a.score).slice(0, limit);
3075
3121
  }
@@ -3640,6 +3686,9 @@ async function cloneRepository(options) {
3640
3686
  git.stderr.on("data", (data) => {
3641
3687
  stderr += data.toString();
3642
3688
  });
3689
+ git.on("error", (error) => {
3690
+ resolve3(err(error));
3691
+ });
3643
3692
  git.on("close", (code) => {
3644
3693
  if (code === 0) {
3645
3694
  resolve3(ok(targetDir));
@@ -3993,6 +4042,8 @@ var PythonBridge = class {
3993
4042
  process = null;
3994
4043
  pending = /* @__PURE__ */ new Map();
3995
4044
  stoppingIntentionally = false;
4045
+ stdoutReadline = null;
4046
+ stderrReadline = null;
3996
4047
  start() {
3997
4048
  if (this.process) return Promise.resolve();
3998
4049
  logger3.debug("Starting Python bridge process");
@@ -4015,8 +4066,8 @@ var PythonBridge = class {
4015
4066
  this.stoppingIntentionally = false;
4016
4067
  });
4017
4068
  if (this.process.stderr) {
4018
- const stderrRl = createInterface({ input: this.process.stderr });
4019
- stderrRl.on("line", (line) => {
4069
+ this.stderrReadline = createInterface({ input: this.process.stderr });
4070
+ this.stderrReadline.on("line", (line) => {
4020
4071
  logger3.warn({ stderr: line }, "Python bridge stderr output");
4021
4072
  });
4022
4073
  }
@@ -4025,8 +4076,8 @@ var PythonBridge = class {
4025
4076
  this.process = null;
4026
4077
  return Promise.reject(new Error("Python bridge process stdout is null"));
4027
4078
  }
4028
- const rl = createInterface({ input: this.process.stdout });
4029
- rl.on("line", (line) => {
4079
+ this.stdoutReadline = createInterface({ input: this.process.stdout });
4080
+ this.stdoutReadline.on("line", (line) => {
4030
4081
  if (!line.trim().startsWith("{")) {
4031
4082
  return;
4032
4083
  }
@@ -4188,6 +4239,14 @@ var PythonBridge = class {
4188
4239
  return new Promise((resolve3) => {
4189
4240
  this.stoppingIntentionally = true;
4190
4241
  this.rejectAllPending(new Error("Python bridge stopped"));
4242
+ if (this.stdoutReadline) {
4243
+ this.stdoutReadline.close();
4244
+ this.stdoutReadline = null;
4245
+ }
4246
+ if (this.stderrReadline) {
4247
+ this.stderrReadline.close();
4248
+ this.stderrReadline = null;
4249
+ }
4191
4250
  const proc = this.process;
4192
4251
  if (proc === null) {
4193
4252
  resolve3();
@@ -4332,18 +4391,14 @@ var LanceStore = class {
4332
4391
  }
4333
4392
  async fullTextSearch(storeId, query, limit) {
4334
4393
  const table = await this.getTable(storeId);
4335
- try {
4336
- const results = await table.search(query, "fts").limit(limit).toArray();
4337
- return results.map((r) => ({
4338
- id: createDocumentId(r.id),
4339
- content: r.content,
4340
- score: r._score,
4341
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
4342
- metadata: JSON.parse(r.metadata)
4343
- }));
4344
- } catch {
4345
- return [];
4346
- }
4394
+ const results = await table.search(query, "fts").limit(limit).toArray();
4395
+ return results.map((r) => ({
4396
+ id: createDocumentId(r.id),
4397
+ content: r.content,
4398
+ score: r._score,
4399
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
4400
+ metadata: JSON.parse(r.metadata)
4401
+ }));
4347
4402
  }
4348
4403
  async deleteStore(storeId) {
4349
4404
  const tableName = this.getTableName(storeId);
@@ -4419,18 +4474,28 @@ async function createServices(configPath, dataDir, projectRoot) {
4419
4474
  }
4420
4475
  async function destroyServices(services) {
4421
4476
  logger4.info("Shutting down services");
4477
+ const errors = [];
4422
4478
  try {
4423
4479
  await services.lance.closeAsync();
4424
4480
  } catch (e) {
4425
- logger4.error({ error: e }, "Error closing LanceStore");
4481
+ const error = e instanceof Error ? e : new Error(String(e));
4482
+ logger4.error({ error }, "Error closing LanceStore");
4483
+ errors.push(error);
4426
4484
  }
4427
4485
  try {
4428
4486
  await services.pythonBridge.stop();
4429
4487
  } catch (e) {
4430
- logger4.error({ error: e }, "Error stopping Python bridge");
4488
+ const error = e instanceof Error ? e : new Error(String(e));
4489
+ logger4.error({ error }, "Error stopping Python bridge");
4490
+ errors.push(error);
4431
4491
  }
4432
4492
  await new Promise((resolve3) => setTimeout(resolve3, 100));
4433
4493
  await shutdownLogger();
4494
+ if (errors.length === 1 && errors[0] !== void 0) {
4495
+ throw new Error(`Service shutdown failed: ${errors[0].message}`, { cause: errors[0] });
4496
+ } else if (errors.length > 1) {
4497
+ throw new AggregateError(errors, "Multiple errors during service shutdown");
4498
+ }
4434
4499
  }
4435
4500
 
4436
4501
  export {
@@ -4453,4 +4518,4 @@ export {
4453
4518
  createServices,
4454
4519
  destroyServices
4455
4520
  };
4456
- //# sourceMappingURL=chunk-ZZNABJMQ.js.map
4521
+ //# sourceMappingURL=chunk-MQGRQ2EG.js.map