lmgrep 0.1.16 → 0.1.18

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 (45) hide show
  1. package/dist/cli.d.ts +1 -1
  2. package/dist/cli.js +203 -3
  3. package/dist/cli.js.map +1 -1
  4. package/dist/index.d.ts +14 -2
  5. package/dist/index.js +356 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/lib/build.d.ts +14 -0
  8. package/dist/lib/build.js +126 -36
  9. package/dist/lib/build.js.map +1 -1
  10. package/dist/lib/chunker/context.d.ts +4 -4
  11. package/dist/lib/chunker/context.js.map +1 -1
  12. package/dist/lib/chunker/index.js +64 -5
  13. package/dist/lib/chunker/index.js.map +1 -1
  14. package/dist/lib/chunker/languages.d.ts +1 -1
  15. package/dist/lib/chunker/languages.js +36 -17
  16. package/dist/lib/chunker/languages.js.map +1 -1
  17. package/dist/lib/embedder.d.ts +11 -1
  18. package/dist/lib/embedder.js +16 -1
  19. package/dist/lib/embedder.js.map +1 -1
  20. package/dist/lib/facet-session.d.ts +44 -0
  21. package/dist/lib/facet-session.js +125 -0
  22. package/dist/lib/facet-session.js.map +1 -0
  23. package/dist/lib/native-tuning.d.ts +1 -0
  24. package/dist/lib/native-tuning.js +9 -0
  25. package/dist/lib/native-tuning.js.map +1 -0
  26. package/dist/lib/repair.d.ts +9 -2
  27. package/dist/lib/repair.js +30 -77
  28. package/dist/lib/repair.js.map +1 -1
  29. package/dist/lib/search-tool.d.ts +9 -1
  30. package/dist/lib/search-tool.js +92 -12
  31. package/dist/lib/search-tool.js.map +1 -1
  32. package/dist/lib/serve.js +17 -0
  33. package/dist/lib/serve.js.map +1 -1
  34. package/dist/lib/store.d.ts +78 -3
  35. package/dist/lib/store.js +407 -16
  36. package/dist/lib/store.js.map +1 -1
  37. package/dist/lib/types.d.ts +65 -1
  38. package/dist/lib/types.js.map +1 -1
  39. package/dist/lib/vocab.d.ts +20 -0
  40. package/dist/lib/vocab.js +275 -0
  41. package/dist/lib/vocab.js.map +1 -0
  42. package/dist/mcp.d.ts +1 -1
  43. package/dist/mcp.js +13 -1
  44. package/dist/mcp.js.map +1 -1
  45. package/package.json +29 -3
@@ -112,7 +112,14 @@ export class ResilientEmbedder {
112
112
  static BATCH_DELAY_MS = 200;
113
113
  static MAX_CONSECUTIVE_FAILURES = 3;
114
114
  static MAX_RELOADS = 3;
115
- async embedBatched(texts) {
115
+ /**
116
+ * Embed `texts` batch by batch. After each batch, `onBatch` (if given) is
117
+ * awaited with the items that just embedded successfully, so the caller can
118
+ * persist incrementally rather than buffering every vector until the end —
119
+ * embeddings then survive a hard crash and resume skips completed work.
120
+ * Each successful index is reported through `onBatch` exactly once.
121
+ */
122
+ async embedBatched(texts, onBatch) {
116
123
  const batchSize = this.config.batchSize;
117
124
  const vectors = new Array(texts.length).fill(null);
118
125
  const failedIndices = new Set();
@@ -122,10 +129,12 @@ export class ResilientEmbedder {
122
129
  const end = Math.min(i + batchSize, texts.length);
123
130
  const batch = texts.slice(i, end);
124
131
  this.events?.onBatchStart?.(batchNum, totalBatches);
132
+ const persisted = [];
125
133
  try {
126
134
  const batchVectors = await this.embedder.embed(batch);
127
135
  for (let j = 0; j < batch.length; j++) {
128
136
  vectors[i + j] = batchVectors[j];
137
+ persisted.push({ index: i + j, vector: batchVectors[j] });
129
138
  }
130
139
  this.consecutiveFailures = 0;
131
140
  }
@@ -136,6 +145,7 @@ export class ResilientEmbedder {
136
145
  try {
137
146
  const [vec] = await this.embedder.embed([batch[j]]);
138
147
  vectors[i + j] = vec;
148
+ persisted.push({ index: i + j, vector: vec });
139
149
  }
140
150
  catch (err) {
141
151
  failedIndices.add(i + j);
@@ -150,6 +160,11 @@ export class ResilientEmbedder {
150
160
  this.consecutiveFailures = 0;
151
161
  }
152
162
  }
163
+ // Persist this batch's successes before any abort below, so partial
164
+ // progress is durable even if the next batches force an abort.
165
+ if (onBatch && persisted.length > 0) {
166
+ await onBatch(persisted);
167
+ }
153
168
  const succeeded = vectors.filter((v) => v !== null).length;
154
169
  this.events?.onBatchDone?.(batchNum, succeeded, failedIndices.size);
155
170
  // Handle consecutive failures
@@ -1 +1 @@
1
- {"version":3,"file":"embedder.js","sourceRoot":"","sources":["../../src/lib/embedder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"embedder.js","sourceRoot":"","sources":["../../src/lib/embedder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAuB,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,IAAI,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAchD;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAE5B;IACA;IACA;IAHjB,YACiB,OAA4B,EAC5B,aAA0B,EAC1B,KAAa;QAE7B,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;QAC3D,KAAK,CACJ,2BAA2B,aAAa,CAAC,IAAI,aAAa;YACzD,GAAG,SAAS,IAAI,KAAK,iCAAiC;YACtD,mEAAmE,CACpE,CAAC;QATc,YAAO,GAAP,OAAO,CAAqB;QAC5B,kBAAa,GAAb,aAAa,CAAa;QAC1B,UAAK,GAAL,KAAK,CAAQ;QAQ7B,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACnC,CAAC;CACD;AAaD,MAAM,OAAO,aAAa;IACjB,WAAW,CAA6B;IACxC,MAAM,CAAsB;IAC5B,SAAS,GAAG,KAAK,CAAC;IAE1B,YAAY,MAAoB;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAEO,iBAAiB,CAAC,MAAgB;QACzC,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IACC,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI;YAC9B,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,UAAU,EACvC,CAAC;YACF,MAAM,IAAI,KAAK,CACd,0CAA0C,IAAI,CAAC,MAAM,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,2CAA2C,CACjI,CAAC;QACH,CAAC;IACF,CAAC;IAEO,KAAK,CAAC,QAAQ;QACrB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC;QAE9C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACd,mDAAmD,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CACvE,CAAC;QACH,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,WAAW,YAAY,EAAE,CAAC;QAC9D,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;QAEjD,IAAI,gBAAgB,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;QAEpD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACzD,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CACtB,CAAC;YACF,IAAI,UAAU,EAAE,CAAC;gBAChB,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAE7B,CAAC;gBACb,gBAAgB,GAAG,OAAO,CAAC;oBAC1B,IAAI,EAAE,YAAY;oBAClB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAChE,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACd,YAAY,GAAG,+CAA+C,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtG,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,sBAAsB,CAAC;YACvC,CAAC,YAAY,CAAC,EAAE,gBAAgB;SACP,CAAC,CAAC;QAE5B,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC,cAAc,CACzC,IAAI,CAAC,MAAM,CAAC,KAA8B,CACxB,CAAC;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAe;QAC1B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;QAChD,MAAM,aAAa,GAAe,EAAE,CAAC;QAErC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACxD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC7D,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1D,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;gBAAE,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;YACjE,aAAa,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,aAAa,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAa;QAC7B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;QAC7C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAClC,OAAO,SAAS,CAAC;IAClB,CAAC;CACD;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAiB;IAMpB;IACA;IACA;IAPD,mBAAmB,GAAG,CAAC,CAAC;IACxB,OAAO,GAAG,CAAC,CAAC;IACH,OAAO,CAAU;IAElC,YACS,QAAkB,EAClB,MAAoB,EACpB,MAAuB;QAFvB,aAAQ,GAAR,QAAQ,CAAU;QAClB,WAAM,GAAN,MAAM,CAAc;QACpB,WAAM,GAAN,MAAM,CAAiB;QAE/B,IAAI,CAAC,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAEO,MAAM,CAAU,cAAc,GAAG,GAAG,CAAC;IACrC,MAAM,CAAU,wBAAwB,GAAG,CAAC,CAAC;IAC7C,MAAM,CAAU,WAAW,GAAG,CAAC,CAAC;IAExC;;;;;;OAMG;IACH,KAAK,CAAC,YAAY,CACjB,KAAe,EACf,OAEkB;QAElB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QACxC,MAAM,OAAO,GAAwB,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QACxC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;QAEzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAElC,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YAEpD,MAAM,SAAS,GAA+C,EAAE,CAAC;YAEjE,IAAI,CAAC;gBACJ,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACtD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACvC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;oBACjC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC3D,CAAC;gBACD,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACR,oCAAoC;gBACpC,IAAI,WAAW,GAAG,CAAC,CAAC;gBACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACvC,IAAI,CAAC;wBACJ,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACpD,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;wBACrB,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;oBAC/C,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACd,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;wBACzB,WAAW,EAAE,CAAC;wBACd,OAAO,CAAC,KAAK,CACZ,gBAAgB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAClG,CAAC;oBACH,CAAC;gBACF,CAAC;gBAED,IAAI,WAAW,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;oBAClC,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC5B,CAAC;qBAAM,CAAC;oBACP,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;gBAC9B,CAAC;YACF,CAAC;YAED,oEAAoE;YACpE,+DAA+D;YAC/D,IAAI,OAAO,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;YAC1B,CAAC;YAED,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;YAC3D,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;YAEpE,8BAA8B;YAC9B,IACC,IAAI,CAAC,mBAAmB;gBACxB,iBAAiB,CAAC,wBAAwB,EACzC,CAAC;gBACF,+CAA+C;gBAC/C,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;oBAClE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACf,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CACtB,IAAI,CAAC,OAAO,EACZ,iBAAiB,CAAC,WAAW,CAC7B,CAAC;oBACF,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;oBACpC,IAAI,EAAE,EAAE,CAAC;wBACR,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;wBAC7B,CAAC,IAAI,iBAAiB,CAAC,wBAAwB,GAAG,SAAS,CAAC;wBAC5D,SAAS;oBACV,CAAC;gBACF,CAAC;gBAED,2BAA2B;gBAC3B,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACzC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACtB,CAAC;gBAED,+DAA+D;gBAC/D,MAAM,IAAI,mBAAmB,CAC5B,OAAO,EACP,aAAa,EACb,KAAK,CAAC,MAAM,CACZ,CAAC;YACH,CAAC;YAED,2BAA2B;YAC3B,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBACxB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACvB,UAAU,CAAC,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAC/C,CAAC;YACH,CAAC;QACF,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IACnC,CAAC;IAEO,KAAK,CAAC,WAAW;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,uBAAuB,CAAC;QAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAEhD,IAAI,CAAC;YACJ,MAAM,KAAK,CAAC,GAAG,OAAO,uBAAuB,EAAE;gBAC9C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;aAC9C,CAAC,CAAC;YACH,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,qBAAqB,EAAE;gBACxD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACpB,KAAK,EAAE,OAAO;oBACd,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,IAAI;iBAC7C,CAAC;aACF,CAAC,CAAC;YACH,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;;AAGF,SAAS,eAAe,CAAC,OAAgB;IACxC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;QACvC,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,SAAS,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC"}
@@ -0,0 +1,44 @@
1
+ export interface FacetNode {
2
+ /** "/"-joined labels from root, empty for the root node */
3
+ path: string;
4
+ /** Chunk ids in this pool (ordered by initial retrieval score) */
5
+ hits: string[];
6
+ /** Children produced by a facet computation; absent until refined */
7
+ children?: Array<{
8
+ label: string;
9
+ size: number;
10
+ hits: string[];
11
+ /** Top vocab candidates for this cluster's axis (label first). */
12
+ candidates?: string[];
13
+ /** Deduped pairwise qualifiers for compact display. */
14
+ qualifiers?: string[];
15
+ /** Pairwise discriminators against each sibling cluster. */
16
+ disambiguators?: Array<{
17
+ vs: string;
18
+ terms: string[];
19
+ }>;
20
+ }>;
21
+ }
22
+ export interface FacetSession {
23
+ id: string;
24
+ query: string;
25
+ createdAt: number;
26
+ /** Map from path ("", "token", "token/access") → node */
27
+ nodes: Record<string, FacetNode>;
28
+ }
29
+ export declare function generateSessionId(existing: Set<string>): string;
30
+ export declare function listSessions(projectRoot: string): string[];
31
+ export declare function loadSession(projectRoot: string, id: string): FacetSession | undefined;
32
+ export declare function saveSession(projectRoot: string, session: FacetSession): void;
33
+ export declare function createSession(projectRoot: string, query: string, rootHits: string[]): FacetSession;
34
+ /**
35
+ * Parse a path like "kx3" or "kx3/token/access" into { id, segments }.
36
+ * Returns undefined if malformed.
37
+ */
38
+ export declare function parseFacetPath(input: string): {
39
+ id: string;
40
+ segments: string[];
41
+ } | undefined;
42
+ export declare function nodeKey(segments: string[]): string;
43
+ /** All ancestor labels along a path — used to prevent label collisions in refinement. */
44
+ export declare function ancestorLabels(segments: string[]): string[];
@@ -0,0 +1,125 @@
1
+ import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { buildSlug } from "./store.js";
5
+ const SESSIONS_SUBDIR = "facet-sessions";
6
+ /** Max sessions per project before we LRU-evict the oldest on write. */
7
+ const MAX_SESSIONS = 50;
8
+ /** Sessions older than this are pruned on next access. */
9
+ const TTL_MS = 24 * 60 * 60 * 1000;
10
+ function sessionsDir(projectRoot) {
11
+ return join(homedir(), ".local", "state", "lmgrep", buildSlug(projectRoot), SESSIONS_SUBDIR);
12
+ }
13
+ function sessionPath(projectRoot, id) {
14
+ return join(sessionsDir(projectRoot), `${id}.json`);
15
+ }
16
+ const ID_ALPHABET = "abcdefghijkmnopqrstuvwxyz23456789"; // no 0/1/l confusables
17
+ export function generateSessionId(existing) {
18
+ for (let len = 3; len <= 5; len++) {
19
+ for (let attempt = 0; attempt < 50; attempt++) {
20
+ let id = "";
21
+ for (let i = 0; i < len; i++) {
22
+ id += ID_ALPHABET[Math.floor(Math.random() * ID_ALPHABET.length)];
23
+ }
24
+ if (!existing.has(id))
25
+ return id;
26
+ }
27
+ }
28
+ throw new Error("Could not allocate session id");
29
+ }
30
+ export function listSessions(projectRoot) {
31
+ const dir = sessionsDir(projectRoot);
32
+ if (!existsSync(dir))
33
+ return [];
34
+ return readdirSync(dir)
35
+ .filter((f) => f.endsWith(".json"))
36
+ .map((f) => f.slice(0, -5));
37
+ }
38
+ export function loadSession(projectRoot, id) {
39
+ const p = sessionPath(projectRoot, id);
40
+ if (!existsSync(p))
41
+ return undefined;
42
+ try {
43
+ return JSON.parse(readFileSync(p, "utf-8"));
44
+ }
45
+ catch {
46
+ return undefined;
47
+ }
48
+ }
49
+ export function saveSession(projectRoot, session) {
50
+ const dir = sessionsDir(projectRoot);
51
+ mkdirSync(dir, { recursive: true });
52
+ pruneOld(dir);
53
+ writeFileSync(sessionPath(projectRoot, session.id), JSON.stringify(session));
54
+ }
55
+ function pruneOld(dir) {
56
+ let entries;
57
+ try {
58
+ entries = readdirSync(dir)
59
+ .filter((f) => f.endsWith(".json"))
60
+ .map((f) => ({
61
+ name: f,
62
+ mtimeMs: statSync(join(dir, f)).mtimeMs,
63
+ }));
64
+ }
65
+ catch {
66
+ return;
67
+ }
68
+ const now = Date.now();
69
+ // TTL prune
70
+ for (const e of entries) {
71
+ if (now - e.mtimeMs > TTL_MS) {
72
+ try {
73
+ unlinkSync(join(dir, e.name));
74
+ }
75
+ catch { }
76
+ }
77
+ }
78
+ // LRU prune
79
+ const remaining = entries.filter((e) => now - e.mtimeMs <= TTL_MS);
80
+ if (remaining.length >= MAX_SESSIONS) {
81
+ remaining.sort((a, b) => a.mtimeMs - b.mtimeMs);
82
+ const overflow = remaining.length - MAX_SESSIONS + 1;
83
+ for (let i = 0; i < overflow; i++) {
84
+ try {
85
+ unlinkSync(join(dir, remaining[i].name));
86
+ }
87
+ catch { }
88
+ }
89
+ }
90
+ }
91
+ export function createSession(projectRoot, query, rootHits) {
92
+ const existing = new Set(listSessions(projectRoot));
93
+ const id = generateSessionId(existing);
94
+ const session = {
95
+ id,
96
+ query,
97
+ createdAt: Date.now(),
98
+ nodes: {
99
+ "": { path: "", hits: rootHits },
100
+ },
101
+ };
102
+ saveSession(projectRoot, session);
103
+ return session;
104
+ }
105
+ /**
106
+ * Parse a path like "kx3" or "kx3/token/access" into { id, segments }.
107
+ * Returns undefined if malformed.
108
+ */
109
+ export function parseFacetPath(input) {
110
+ const parts = input.split("/").filter(Boolean);
111
+ if (parts.length === 0)
112
+ return undefined;
113
+ const id = parts[0];
114
+ if (!/^[a-z2-9]+$/.test(id))
115
+ return undefined;
116
+ return { id, segments: parts.slice(1) };
117
+ }
118
+ export function nodeKey(segments) {
119
+ return segments.join("/");
120
+ }
121
+ /** All ancestor labels along a path — used to prevent label collisions in refinement. */
122
+ export function ancestorLabels(segments) {
123
+ return [...segments];
124
+ }
125
+ //# sourceMappingURL=facet-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facet-session.js","sourceRoot":"","sources":["../../src/lib/facet-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ // Set before any native module (LanceDB, libuv) initializes its thread pool.
2
+ // This module is imported first by entry points to ensure the env is in
3
+ // place before downstream imports load native bindings.
4
+ process.env.TOKIO_WORKER_THREADS ??= "4";
5
+ process.env.UV_THREADPOOL_SIZE ??= "4";
6
+ process.env.RAYON_NUM_THREADS ??= "4";
7
+ process.env.MATMUL_NUM_THREADS ??= "4";
8
+ export {};
9
+ //# sourceMappingURL=native-tuning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-tuning.js","sourceRoot":"","sources":["../../src/lib/native-tuning.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,wEAAwE;AACxE,wDAAwD;AACxD,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG,CAAC;AACzC,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG,CAAC;AACvC,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,GAAG,CAAC;AACtC,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG,CAAC"}
@@ -1,3 +1,10 @@
1
1
  import type { Store } from "./store.js";
2
- import type { Chunker, Logger, RepairResult } from "./types.js";
3
- export declare function repair(cwd: string, store: Store, chunker: Chunker, dry?: boolean, logger?: Logger): Promise<RepairResult>;
2
+ import type { Logger, RepairResult } from "./types.js";
3
+ /**
4
+ * Reconcile the current-branch file manifest with the working tree.
5
+ * Any manifest row whose path is missing from disk, or whose stored hash
6
+ * disagrees with the on-disk hash, is removed. Chunks for those paths are
7
+ * deleted too (guarded cross-branch inside the store). The next
8
+ * `lmgrep index` run will then treat those files as additions and re-embed.
9
+ */
10
+ export declare function repair(cwd: string, store: Store, dry?: boolean, logger?: Logger): Promise<RepairResult>;
@@ -1,104 +1,57 @@
1
- import { createHash } from "node:crypto";
2
- import { readFileSync } from "node:fs";
3
- import { join } from "node:path";
4
- import { walkFiles } from "./scanner.js";
1
+ import { hashFile, walkFiles } from "./scanner.js";
5
2
  import { consoleLogger } from "./types.js";
6
- export async function repair(cwd, store, chunker, dry = false, logger = consoleLogger) {
3
+ /**
4
+ * Reconcile the current-branch file manifest with the working tree.
5
+ * Any manifest row whose path is missing from disk, or whose stored hash
6
+ * disagrees with the on-disk hash, is removed. Chunks for those paths are
7
+ * deleted too (guarded cross-branch inside the store). The next
8
+ * `lmgrep index` run will then treat those files as additions and re-embed.
9
+ */
10
+ export async function repair(cwd, store, dry = false, logger = consoleLogger) {
7
11
  const log = logger.info.bind(logger);
8
- log("Scanning index for inconsistencies...");
12
+ log("Reconciling current-branch manifest with working tree...");
9
13
  const chunkCountBefore = await store.chunkCount();
10
- const indexedFiles = await store.getIndexedFiles();
11
14
  const storedFileHashes = await store.getFileHashes();
12
15
  const diskFiles = new Set(walkFiles(cwd));
13
- // 1. Orphaned files (indexed but deleted from disk)
14
16
  const orphaned = [];
15
- const allIndexedPaths = new Set([
16
- ...indexedFiles.keys(),
17
- ...storedFileHashes.keys(),
18
- ]);
19
- for (const fp of allIndexedPaths) {
20
- if (!diskFiles.has(fp))
21
- orphaned.push(fp);
22
- }
23
- // 2. Stale files (hash mismatch)
24
17
  const stale = [];
25
- for (const fp of diskFiles) {
26
- const storedHash = storedFileHashes.get(fp);
27
- if (!storedHash)
18
+ for (const [fp, storedHash] of storedFileHashes) {
19
+ if (!diskFiles.has(fp)) {
20
+ orphaned.push(fp);
28
21
  continue;
29
- try {
30
- const content = readFileSync(join(cwd, fp));
31
- const currentHash = createHash("sha256")
32
- .update(content)
33
- .digest("hex")
34
- .slice(0, 16);
35
- if (storedHash !== currentHash)
36
- stale.push(fp);
37
22
  }
38
- catch {
23
+ const currentHash = hashFile(cwd, fp);
24
+ if (currentHash === undefined) {
39
25
  orphaned.push(fp);
40
- }
41
- }
42
- // 3. Chunk mismatches
43
- const chunkMismatch = [];
44
- for (const [fp, indexedHashes] of indexedFiles) {
45
- if (orphaned.includes(fp) || stale.includes(fp))
46
26
  continue;
47
- if (!diskFiles.has(fp))
48
- continue;
49
- try {
50
- const currentChunks = await chunker.chunk(fp, cwd);
51
- const currentHashSet = new Set(currentChunks.map((c) => c.hash));
52
- const indexedSet = new Set(indexedHashes);
53
- const hasStale = indexedHashes.some((h) => !currentHashSet.has(h));
54
- const hasMissing = currentChunks.some((c) => !indexedSet.has(c.hash));
55
- if (hasStale || hasMissing)
56
- chunkMismatch.push(fp);
57
- }
58
- catch {
59
- // skip
60
27
  }
28
+ if (currentHash !== storedHash)
29
+ stale.push(fp);
61
30
  }
62
- const total = orphaned.length + stale.length + chunkMismatch.length;
31
+ const total = orphaned.length + stale.length;
63
32
  if (total === 0) {
64
- log("Index is consistent. No repairs needed.");
65
- return {
66
- orphaned: [],
67
- stale: [],
68
- chunkMismatch: [],
69
- chunksRemoved: 0,
70
- };
33
+ log("Manifest matches working tree. No repairs needed.");
34
+ return { orphaned: [], stale: [], chunksRemoved: 0 };
71
35
  }
72
- log(`Found ${total} issues:`);
36
+ log(`Found ${total} inconsistencies:`);
73
37
  if (orphaned.length > 0)
74
38
  log(` ${orphaned.length} orphaned files`);
75
39
  if (stale.length > 0)
76
40
  log(` ${stale.length} stale files`);
77
- if (chunkMismatch.length > 0)
78
- log(` ${chunkMismatch.length} chunk mismatches`);
79
41
  if (dry) {
80
42
  for (const fp of orphaned)
81
- log(` [orphan] ${fp}`);
43
+ log(` [orphan] ${fp}`);
82
44
  for (const fp of stale)
83
- log(` [stale] ${fp}`);
84
- for (const fp of chunkMismatch)
85
- log(` [mismatch] ${fp}`);
86
- return { orphaned, stale, chunkMismatch, chunksRemoved: 0 };
87
- }
88
- if (orphaned.length > 0) {
89
- await store.deleteChunksByFiles(orphaned);
90
- await store.deleteFileHashes(orphaned);
91
- log(`Removed ${orphaned.length} orphaned files`);
92
- }
93
- const toInvalidate = [...stale, ...chunkMismatch];
94
- if (toInvalidate.length > 0) {
95
- await store.deleteChunksByFiles(toInvalidate);
96
- await store.deleteFileHashes(toInvalidate);
97
- log(`Invalidated ${toInvalidate.length} files — run \`lmgrep index\` to re-embed`);
45
+ log(` [stale] ${fp}`);
46
+ return { orphaned, stale, chunksRemoved: 0 };
98
47
  }
48
+ const toDrop = [...orphaned, ...stale];
49
+ await store.deleteChunksByFiles(toDrop);
50
+ await store.deleteFileHashes(toDrop);
99
51
  const chunkCountAfter = await store.chunkCount();
100
52
  const chunksRemoved = chunkCountBefore - chunkCountAfter;
101
- log(`Repair complete. Removed ${chunksRemoved} stale chunks.`);
102
- return { orphaned, stale, chunkMismatch, chunksRemoved };
53
+ log(`Dropped ${toDrop.length} manifest entries (${chunksRemoved} chunks removed). ` +
54
+ `Run \`lmgrep index\` to re-embed stale files.`);
55
+ return { orphaned, stale, chunksRemoved };
103
56
  }
104
57
  //# sourceMappingURL=repair.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/lib/repair.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/lib/repair.ts"],"names":[],"mappings":"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"}
@@ -30,15 +30,23 @@ export interface SearchParamSpecs {
30
30
  }
31
31
  export declare const searchParamSpecs: SearchParamSpecs;
32
32
  export declare const listProjectsDescription: string;
33
+ export interface FacetArgs {
34
+ query: string;
35
+ }
36
+ export declare const facetDescription: string;
37
+ export declare const facetParamSpec: ParamSpec;
33
38
  export interface LmgrepCore {
34
39
  readonly cwd: string;
35
40
  readonly searchParams: SearchParamSpecs;
41
+ readonly facetParam: ParamSpec;
42
+ readonly facetDescription: string;
36
43
  readonly listProjectsDescription: string;
37
44
  buildSearchDescription(): string;
38
45
  currentHealth(): HealthState;
39
46
  onHealthChange(cb: (state: HealthState) => void): () => void;
40
- startHealthLoop(): void;
47
+ start(): void;
41
48
  executeSearch(args: SearchArgs): Promise<ToolResult>;
49
+ executeFacet(args: FacetArgs): Promise<ToolResult>;
42
50
  executeListProjects(): Promise<ToolResult>;
43
51
  dispose(): Promise<void>;
44
52
  }
@@ -12,7 +12,7 @@ export const searchParamSpecs = {
12
12
  },
13
13
  limit: {
14
14
  description: "Maximum number of results",
15
- default: 10,
15
+ default: 5,
16
16
  },
17
17
  filePrefix: {
18
18
  description: "Restrict to files under this path (e.g. 'src/lib')",
@@ -30,6 +30,21 @@ export const searchParamSpecs = {
30
30
  export const listProjectsDescription = "List all indexed projects other than the current one. " +
31
31
  "Use this to discover what projects are available for cross-project search " +
32
32
  "via the `project` parameter on the search tool.";
33
+ export const facetDescription = [
34
+ "**Get a labeled overview of what *kinds* of code match a query, instead of raw results.** Returns 5 clusters, each with a one-word label, a handful of qualifier words describing that cluster's angle, and a size. No file paths, no chunks — just the shape of the result space.",
35
+ "",
36
+ "**Use facet when:**",
37
+ "- The query is broad or exploratory (`auth`, `error handling`, `payment flow`).",
38
+ "- You don't yet know the vocabulary the codebase uses for a concept — the qualifiers surface the real terms (e.g. `auth` → clusters revealing `fireauth`, `oauth`, `serviceaccount`).",
39
+ "- A previous `search` returned a heterogeneous mix and you want to see why.",
40
+ "",
41
+ "**Do NOT use facet when:** the query is already specific (a symbol, a precise question, an error message). Call `search` directly.",
42
+ "",
43
+ "**How to act on the output:** pick the cluster that matches your intent, then call `search` with a narrower query that combines the original intent with the cluster's label + qualifiers (e.g. after `facet(\"auth\")` returns a cluster `email: fireauth, phone, provider`, call `search(\"authentication with fireauth phone provider\")`). This uses the corpus's own vocabulary and dramatically improves recall.",
44
+ ].join("\n");
45
+ export const facetParamSpec = {
46
+ description: "Broad, natural-language query to faceted over. Same phrasing as `search`, but use when the query is exploratory and you want to see the categories of matching code.",
47
+ };
33
48
  export async function createLmgrepCore(opts) {
34
49
  const cwd = opts.cwd;
35
50
  const index = await createIndex({ cwd });
@@ -71,6 +86,8 @@ export async function createLmgrepCore(opts) {
71
86
  const listeners = new Set();
72
87
  let stopWatcher;
73
88
  let pollTimer;
89
+ let polling = false;
90
+ let pollDelayMs = 0;
74
91
  let disposed = false;
75
92
  function tryStartWatcher() {
76
93
  if (stopWatcher)
@@ -129,23 +146,53 @@ export async function createLmgrepCore(opts) {
129
146
  for (const cb of listeners)
130
147
  cb(next);
131
148
  }
132
- if (next.healthy)
149
+ if (next.healthy) {
150
+ // Recovery detected — stop pinging so we don't keep the embedder
151
+ // awake now that it's back. The loop re-arms only on the next
152
+ // failed search/facet.
133
153
  tryStartWatcher();
154
+ stopHealthLoop();
155
+ }
156
+ }
157
+ // Boot: start the file watcher but DO NOT poll the embedder. While healthy
158
+ // and idle we never ping it — the initial (optimistic) state already drives
159
+ // an accurate tool description, and the embedder is free to sleep. The poll
160
+ // loop arms only when a real search hits a down embedder (see the catch
161
+ // blocks in executeSearch/executeFacet).
162
+ function start() {
163
+ tryStartWatcher();
164
+ }
165
+ // Recovery poll: armed when a search fails because the embedder is down.
166
+ // Pings on a backoff schedule purely to detect when the embedder comes
167
+ // back, then disarms itself (refreshHealth → stopHealthLoop on recovery).
168
+ const POLL_BASE_MS = index.config.local ? 10_000 : 60_000;
169
+ // Cap the interval so a long-down embedder isn't pinged every base period
170
+ // for hours — ~2min local, ~5min for billable remote providers.
171
+ const POLL_MAX_MS = index.config.local ? 120_000 : 300_000;
172
+ async function runHealthPoll() {
173
+ if (!polling || disposed)
174
+ return;
175
+ await refreshHealth();
176
+ // refreshHealth() calls stopHealthLoop() if the embedder recovered.
177
+ if (!polling || disposed)
178
+ return;
179
+ pollTimer = setTimeout(runHealthPoll, pollDelayMs);
180
+ pollDelayMs = Math.min(pollDelayMs * 2, POLL_MAX_MS);
134
181
  }
135
182
  function startHealthLoop() {
136
- if (pollTimer)
183
+ if (polling)
137
184
  return;
185
+ polling = true;
186
+ pollDelayMs = POLL_BASE_MS;
138
187
  tryStartWatcher();
139
- // Non-local providers may bill per request — poll less often.
140
- const intervalMs = index.config.local ? 10_000 : 60_000;
141
- refreshHealth();
142
- pollTimer = setInterval(refreshHealth, intervalMs);
188
+ void runHealthPoll();
143
189
  }
144
190
  function stopHealthLoop() {
145
- if (!pollTimer)
146
- return;
147
- clearInterval(pollTimer);
148
- pollTimer = undefined;
191
+ polling = false;
192
+ if (pollTimer) {
193
+ clearTimeout(pollTimer);
194
+ pollTimer = undefined;
195
+ }
149
196
  }
150
197
  function markHealthy() {
151
198
  if (!state.healthy || state.reason !== "ok") {
@@ -199,6 +246,36 @@ export async function createLmgrepCore(opts) {
199
246
  return { text: `Error: ${msg}`, isError: true };
200
247
  }
201
248
  }
249
+ async function executeFacet(args) {
250
+ if (state.reason === "embedding_failed") {
251
+ return {
252
+ text: "lmgrep is unavailable: the embedding provider is unreachable. Ask the user to check their lmgrep configuration (`lmgrep status`) before retrying.",
253
+ isError: true,
254
+ };
255
+ }
256
+ try {
257
+ const result = await index.facetSearch(args.query, {});
258
+ markHealthy();
259
+ stopHealthLoop();
260
+ if (result.labels.length === 0) {
261
+ return { text: "No results found." };
262
+ }
263
+ const total = result.labels.length;
264
+ const header = `Facets for "${args.query}" (${total} clusters):`;
265
+ const lines = result.labels.map((label, i) => {
266
+ const quals = result.qualifiers?.[i] ?? [];
267
+ const qualText = quals.length > 0 ? `: ${quals.join(", ")}` : "";
268
+ return `- ${label}${qualText}`;
269
+ });
270
+ const footer = "\nPick a cluster and call `search` with a refined query that combines your original intent with the label + qualifiers to drill in.";
271
+ return { text: [header, ...lines, footer].join("\n") };
272
+ }
273
+ catch (err) {
274
+ startHealthLoop();
275
+ const msg = err instanceof Error ? err.message : String(err);
276
+ return { text: `Error: ${msg}`, isError: true };
277
+ }
278
+ }
202
279
  async function executeListProjects() {
203
280
  const others = getOtherProjects();
204
281
  if (others.length === 0) {
@@ -223,6 +300,8 @@ export async function createLmgrepCore(opts) {
223
300
  return {
224
301
  cwd,
225
302
  searchParams: searchParamSpecs,
303
+ facetParam: facetParamSpec,
304
+ facetDescription,
226
305
  listProjectsDescription,
227
306
  buildSearchDescription,
228
307
  currentHealth: () => state,
@@ -230,8 +309,9 @@ export async function createLmgrepCore(opts) {
230
309
  listeners.add(cb);
231
310
  return () => listeners.delete(cb);
232
311
  },
233
- startHealthLoop,
312
+ start,
234
313
  executeSearch,
314
+ executeFacet,
235
315
  executeListProjects,
236
316
  dispose,
237
317
  };