recker 1.0.12-alpha.a858d02 → 1.0.12-next.b76976a

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.
@@ -13,6 +13,8 @@ export declare class HybridSearch {
13
13
  private fuzzySearch;
14
14
  private semanticSearch;
15
15
  private extractSnippet;
16
+ private static STOP_WORDS;
17
+ private cleanQuery;
16
18
  private tokenize;
17
19
  private averageVectors;
18
20
  hasEmbeddings(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../../../src/mcp/search/hybrid-search.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AAkBpB,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAiC;IAC7C,OAAO,CAAC,IAAI,CAAoB;IAChC,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAA+B;gBAEjC,MAAM,GAAE,kBAAuB;IAYrC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YA6BrC,yBAAyB;IAuDjC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IA4CjF,OAAO,CAAC,WAAW;IAiCnB,OAAO,CAAC,cAAc;IA8GtB,OAAO,CAAC,cAAc;IAoDtB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,cAAc;IAmBtB,aAAa,IAAI,OAAO;IAOxB,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IAYD,OAAO,CAAC,GAAG;CAKZ;AAKD,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAE5E"}
1
+ {"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../../../src/mcp/search/hybrid-search.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AAkBpB,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAiC;IAC7C,OAAO,CAAC,IAAI,CAAoB;IAChC,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAA+B;gBAEjC,MAAM,GAAE,kBAAuB;IAYrC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YA+BrC,yBAAyB;IAuDjC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAmDjF,OAAO,CAAC,WAAW;IAiCnB,OAAO,CAAC,cAAc;IA8GtB,OAAO,CAAC,cAAc;IAoDtB,OAAO,CAAC,MAAM,CAAC,UAAU,CAoCtB;IAKH,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,cAAc;IAmBtB,aAAa,IAAI,OAAO;IAOxB,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IAYD,OAAO,CAAC,GAAG;CAKZ;AAKD,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAE5E"}
@@ -10,7 +10,7 @@ export class HybridSearch {
10
10
  config;
11
11
  constructor(config = {}) {
12
12
  this.config = {
13
- fuzzyThreshold: config.fuzzyThreshold ?? 0.4,
13
+ fuzzyThreshold: config.fuzzyThreshold ?? 0.6,
14
14
  fuzzyWeight: config.fuzzyWeight ?? 0.5,
15
15
  semanticWeight: config.semanticWeight ?? 0.5,
16
16
  debug: config.debug ?? false,
@@ -20,16 +20,18 @@ export class HybridSearch {
20
20
  this.docs = docs;
21
21
  this.fuse = new Fuse(docs, {
22
22
  keys: [
23
- { name: 'title', weight: 3 },
24
- { name: 'keywords', weight: 2 },
25
- { name: 'path', weight: 1.5 },
26
- { name: 'content', weight: 1 },
23
+ { name: 'keywords', weight: 6 },
24
+ { name: 'title', weight: 4 },
25
+ { name: 'section', weight: 3 },
26
+ { name: 'path', weight: 1 },
27
+ { name: 'content', weight: 0.3 },
27
28
  ],
28
29
  includeScore: true,
29
30
  threshold: this.config.fuzzyThreshold,
30
31
  ignoreLocation: true,
31
32
  useExtendedSearch: true,
32
33
  findAllMatches: true,
34
+ minMatchCharLength: 2,
33
35
  });
34
36
  await this.loadPrecomputedEmbeddings();
35
37
  this.initialized = true;
@@ -82,16 +84,19 @@ export class HybridSearch {
82
84
  if (!this.initialized) {
83
85
  throw new Error('HybridSearch not initialized. Call initialize() first.');
84
86
  }
87
+ const cleanedQuery = this.cleanQuery(query);
88
+ this.log(`Original query: "${query}" → Cleaned: "${cleanedQuery}"`);
89
+ const searchQuery = cleanedQuery.length > 0 ? cleanedQuery : query;
85
90
  const results = new Map();
86
91
  if (mode === 'hybrid' || mode === 'fuzzy') {
87
- const fuzzyResults = this.fuzzySearch(query, limit * 2, category);
92
+ const fuzzyResults = this.fuzzySearch(searchQuery, limit * 2, category);
88
93
  for (const result of fuzzyResults) {
89
94
  results.set(result.id, result);
90
95
  }
91
96
  this.log(`Fuzzy search found ${fuzzyResults.length} results`);
92
97
  }
93
98
  if ((mode === 'hybrid' || mode === 'semantic') && this.vectors.size > 0) {
94
- const semanticResults = this.semanticSearch(query, limit * 2, category);
99
+ const semanticResults = this.semanticSearch(searchQuery, limit * 2, category);
95
100
  for (const result of semanticResults) {
96
101
  const existing = results.get(result.id);
97
102
  if (existing) {
@@ -242,11 +247,52 @@ export class HybridSearch {
242
247
  snippet = snippet + '...';
243
248
  return snippet.replace(/\n+/g, ' ').replace(/\s+/g, ' ');
244
249
  }
250
+ static STOP_WORDS = new Set([
251
+ 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
252
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could', 'should',
253
+ 'may', 'might', 'must', 'shall', 'can', 'need', 'dare', 'ought', 'used',
254
+ 'and', 'but', 'or', 'nor', 'for', 'yet', 'so', 'both', 'either', 'neither',
255
+ 'not', 'only', 'own', 'same', 'than', 'too', 'very', 'just', 'also',
256
+ 'how', 'what', 'when', 'where', 'who', 'which', 'why', 'whom', 'whose',
257
+ 'this', 'that', 'these', 'those', 'here', 'there', 'all', 'each', 'every',
258
+ 'any', 'some', 'no', 'none', 'one', 'two', 'other', 'another', 'such',
259
+ 'to', 'of', 'in', 'on', 'at', 'by', 'with', 'from', 'as', 'into', 'through',
260
+ 'about', 'above', 'below', 'between', 'under', 'over', 'out', 'up', 'down',
261
+ 'if', 'then', 'else', 'because', 'while', 'although', 'though', 'unless',
262
+ 'my', 'your', 'his', 'her', 'its', 'our', 'their', 'me', 'you', 'him', 'us', 'them',
263
+ 'o', 'a', 'os', 'as', 'um', 'uma', 'uns', 'umas', 'de', 'do', 'da', 'dos', 'das',
264
+ 'em', 'no', 'na', 'nos', 'nas', 'por', 'para', 'com', 'sem', 'sob', 'sobre',
265
+ 'e', 'ou', 'mas', 'porem', 'todavia', 'contudo', 'entretanto',
266
+ 'que', 'qual', 'quais', 'quanto', 'quem', 'como', 'onde', 'quando', 'porque',
267
+ 'eu', 'tu', 'ele', 'ela', 'nos', 'vos', 'eles', 'elas', 'voce', 'voces',
268
+ 'meu', 'minha', 'meus', 'minhas', 'seu', 'sua', 'seus', 'suas',
269
+ 'este', 'esta', 'estes', 'estas', 'esse', 'essa', 'esses', 'essas',
270
+ 'isso', 'isto', 'aquilo', 'aquele', 'aquela', 'aqueles', 'aquelas',
271
+ 'ser', 'estar', 'ter', 'haver', 'fazer', 'ir', 'vir', 'poder', 'dever',
272
+ 'sim', 'nao', 'ja', 'ainda', 'sempre', 'nunca', 'tambem', 'so', 'apenas',
273
+ 'muito', 'pouco', 'mais', 'menos', 'bem', 'mal', 'assim', 'entao', 'logo',
274
+ 'yo', 'hey', 'oi', 'ola', 'bom', 'boa', 'obrigado', 'por favor',
275
+ 'configure', 'configuro', 'configurar', 'configurando',
276
+ 'use', 'usar', 'using', 'usar',
277
+ 'create', 'criar', 'creating', 'criando',
278
+ 'setup', 'setar', 'setting', 'setando',
279
+ 'add', 'adicionar', 'adding', 'adicionando',
280
+ 'get', 'getting', 'pegar', 'pegando',
281
+ 'set', 'setting', 'definir', 'definindo',
282
+ 'make', 'making', 'fazer', 'fazendo',
283
+ ]);
284
+ cleanQuery(query) {
285
+ const words = query
286
+ .toLowerCase()
287
+ .split(/[\s\-_.,;:!?()[\]{}'"]+/)
288
+ .filter((w) => w.length > 1 && !HybridSearch.STOP_WORDS.has(w));
289
+ return words.join(' ');
290
+ }
245
291
  tokenize(text) {
246
292
  return text
247
293
  .toLowerCase()
248
294
  .split(/[\s\-_.,;:!?()[\]{}'"]+/)
249
- .filter((t) => t.length > 2);
295
+ .filter((t) => t.length > 2 && !HybridSearch.STOP_WORDS.has(t));
250
296
  }
251
297
  averageVectors(vectors) {
252
298
  if (vectors.length === 0)
@@ -5,6 +5,8 @@ export interface IndexedDoc {
5
5
  content: string;
6
6
  category: string;
7
7
  keywords: string[];
8
+ section?: string;
9
+ parentPath?: string;
8
10
  }
9
11
  export interface SearchResult {
10
12
  id: string;
@@ -28,6 +30,8 @@ export interface EmbeddingEntry {
28
30
  title: string;
29
31
  category: string;
30
32
  keywords: string[];
33
+ section?: string;
34
+ parentPath?: string;
31
35
  vector: number[];
32
36
  }
33
37
  export interface SearchOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/mcp/search/types.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IAEzB,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,OAAO,EAAE,MAAM,CAAC;IAEhB,QAAQ,EAAE,MAAM,CAAC;IAEjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAKD,MAAM,WAAW,YAAY;IAE3B,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,OAAO,EAAE,MAAM,CAAC;IAEhB,OAAO,EAAE,MAAM,CAAC;IAEhB,KAAK,EAAE,MAAM,CAAC;IAEd,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;CACzC;AAMD,MAAM,WAAW,cAAc;IAE7B,OAAO,EAAE,MAAM,CAAC;IAEhB,KAAK,EAAE,MAAM,CAAC;IAEd,UAAU,EAAE,MAAM,CAAC;IAEnB,WAAW,EAAE,MAAM,CAAC;IAEpB,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B;AAKD,MAAM,WAAW,cAAc;IAE7B,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,QAAQ,EAAE,MAAM,CAAC;IAEjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAKD,MAAM,WAAW,aAAa;IAE5B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;IAEvC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,MAAM,WAAW,kBAAkB;IAEjC,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/mcp/search/types.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IAEzB,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,OAAO,EAAE,MAAM,CAAC;IAEhB,QAAQ,EAAE,MAAM,CAAC;IAEjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAKD,MAAM,WAAW,YAAY;IAE3B,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,OAAO,EAAE,MAAM,CAAC;IAEhB,OAAO,EAAE,MAAM,CAAC;IAEhB,KAAK,EAAE,MAAM,CAAC;IAEd,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;CACzC;AAMD,MAAM,WAAW,cAAc;IAE7B,OAAO,EAAE,MAAM,CAAC;IAEhB,KAAK,EAAE,MAAM,CAAC;IAEd,UAAU,EAAE,MAAM,CAAC;IAEnB,WAAW,EAAE,MAAM,CAAC;IAEpB,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B;AAKD,MAAM,WAAW,cAAc;IAE7B,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,QAAQ,EAAE,MAAM,CAAC;IAEjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAKD,MAAM,WAAW,aAAa;IAE5B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;IAEvC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAKD,MAAM,WAAW,kBAAkB;IAEjC,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recker",
3
- "version": "1.0.12-alpha.a858d02",
3
+ "version": "1.0.12-next.b76976a",
4
4
  "description": "AI & DevX focused HTTP client for Node.js 18+",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -166,7 +166,7 @@
166
166
  "zod": "^3.24.0"
167
167
  },
168
168
  "scripts": {
169
- "build": "tsc",
169
+ "build": "tsc && mkdir -p dist/mcp/data && cp src/mcp/data/embeddings.json dist/mcp/data/",
170
170
  "build:embeddings": "tsx scripts/build-embeddings.ts",
171
171
  "test": "vitest run",
172
172
  "test:coverage": "vitest run --coverage",