recker 1.0.11 → 1.0.12-alpha.1ab8aa7

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.
@@ -1,30 +1,453 @@
1
+ import zlib from 'node:zlib';
2
+ import os from 'node:os';
3
+ import { getEffectiveTotalMemoryBytes, resolveCacheMemoryLimit, formatBytes, getHeapStats, } from './memory-limits.js';
1
4
  export class MemoryStorage {
2
5
  storage = new Map();
3
- ttls = new Map();
6
+ meta = new Map();
7
+ maxSize;
8
+ maxMemoryBytes;
9
+ maxMemoryPercent;
10
+ defaultTtl;
11
+ evictionPolicy;
12
+ compressionEnabled;
13
+ compressionThreshold;
14
+ enableStats;
15
+ heapUsageThreshold;
16
+ onEvict;
17
+ onPressure;
18
+ currentMemoryBytes = 0;
19
+ evictedDueToMemory = 0;
20
+ memoryPressureEvents = 0;
21
+ accessCounter = 0;
22
+ monitorHandle = null;
23
+ cleanupHandle = null;
24
+ stats = {
25
+ hits: 0,
26
+ misses: 0,
27
+ sets: 0,
28
+ deletes: 0,
29
+ evictions: 0,
30
+ };
31
+ compressionStats = {
32
+ totalCompressed: 0,
33
+ totalOriginalSize: 0,
34
+ totalCompressedSize: 0,
35
+ };
36
+ constructor(options = {}) {
37
+ if (options.maxMemoryBytes &&
38
+ options.maxMemoryBytes > 0 &&
39
+ options.maxMemoryPercent &&
40
+ options.maxMemoryPercent > 0) {
41
+ throw new Error('[MemoryStorage] Cannot use both maxMemoryBytes and maxMemoryPercent');
42
+ }
43
+ if (options.maxMemoryPercent !== undefined &&
44
+ (options.maxMemoryPercent < 0 || options.maxMemoryPercent > 1)) {
45
+ throw new Error('[MemoryStorage] maxMemoryPercent must be between 0 and 1');
46
+ }
47
+ this.maxSize = options.maxSize ?? 1000;
48
+ this.defaultTtl = options.ttl ?? 300000;
49
+ this.evictionPolicy = options.evictionPolicy ?? 'lru';
50
+ this.enableStats = options.enableStats ?? false;
51
+ this.heapUsageThreshold = options.heapUsageThreshold ?? 0.6;
52
+ if (options.maxMemoryBytes && options.maxMemoryBytes > 0) {
53
+ this.maxMemoryBytes = options.maxMemoryBytes;
54
+ this.maxMemoryPercent = 0;
55
+ }
56
+ else if (options.maxMemoryPercent && options.maxMemoryPercent > 0) {
57
+ const effectiveTotal = getEffectiveTotalMemoryBytes();
58
+ this.maxMemoryBytes = Math.floor(effectiveTotal * options.maxMemoryPercent);
59
+ this.maxMemoryPercent = options.maxMemoryPercent;
60
+ }
61
+ else {
62
+ const resolved = resolveCacheMemoryLimit({});
63
+ this.maxMemoryBytes = resolved.maxMemoryBytes;
64
+ this.maxMemoryPercent = resolved.inferredPercent ?? 0;
65
+ }
66
+ if (options.compression === true) {
67
+ this.compressionEnabled = true;
68
+ this.compressionThreshold = 1024;
69
+ }
70
+ else if (typeof options.compression === 'object' &&
71
+ options.compression.enabled) {
72
+ this.compressionEnabled = true;
73
+ this.compressionThreshold = options.compression.threshold ?? 1024;
74
+ }
75
+ else {
76
+ this.compressionEnabled = false;
77
+ this.compressionThreshold = 1024;
78
+ }
79
+ this.onEvict = options.onEvict;
80
+ this.onPressure = options.onPressure;
81
+ const monitorInterval = options.monitorInterval ?? 15000;
82
+ if (monitorInterval > 0) {
83
+ this.monitorHandle = setInterval(() => this.memoryHealthCheck(), monitorInterval);
84
+ this.monitorHandle.unref();
85
+ }
86
+ const cleanupInterval = options.cleanupInterval ?? 60000;
87
+ if (cleanupInterval > 0) {
88
+ this.cleanupHandle = setInterval(() => this.cleanupExpired(), cleanupInterval);
89
+ this.cleanupHandle.unref();
90
+ }
91
+ }
4
92
  async get(key) {
5
- const entry = this.storage.get(key);
6
- if (!entry) {
93
+ const data = this.storage.get(key);
94
+ const metadata = this.meta.get(key);
95
+ if (!data || !metadata) {
96
+ this.recordStat('misses');
7
97
  return undefined;
8
98
  }
9
- const expiry = this.ttls.get(key);
10
- if (expiry && Date.now() > expiry) {
11
- this.delete(key);
99
+ const now = Date.now();
100
+ if (now > metadata.expiresAt) {
101
+ this.deleteInternal(key);
102
+ this.recordStat('misses');
12
103
  return undefined;
13
104
  }
14
- return entry;
105
+ if (this.evictionPolicy === 'lru') {
106
+ metadata.lastAccess = now;
107
+ metadata.accessOrder = ++this.accessCounter;
108
+ }
109
+ this.recordStat('hits');
110
+ if (this.isCompressed(data)) {
111
+ try {
112
+ const decompressed = this.decompress(data);
113
+ return JSON.parse(decompressed);
114
+ }
115
+ catch {
116
+ this.deleteInternal(key);
117
+ return undefined;
118
+ }
119
+ }
120
+ return JSON.parse(data);
15
121
  }
16
122
  async set(key, entry, ttl) {
17
- this.storage.set(key, entry);
18
- if (ttl) {
19
- this.ttls.set(key, Date.now() + ttl);
123
+ const effectiveTtl = ttl ?? this.defaultTtl;
124
+ const now = Date.now();
125
+ const serialized = JSON.stringify(entry);
126
+ const originalSize = Buffer.byteLength(serialized, 'utf8');
127
+ let finalData = serialized;
128
+ let compressedSize = originalSize;
129
+ let compressed = false;
130
+ if (this.compressionEnabled && originalSize >= this.compressionThreshold) {
131
+ try {
132
+ const result = this.compress(serialized);
133
+ finalData = result;
134
+ compressedSize = Buffer.byteLength(result.__data, 'utf8');
135
+ compressed = true;
136
+ this.compressionStats.totalCompressed++;
137
+ this.compressionStats.totalOriginalSize += originalSize;
138
+ this.compressionStats.totalCompressedSize += compressedSize;
139
+ }
140
+ catch {
141
+ }
20
142
  }
143
+ const existingMeta = this.meta.get(key);
144
+ if (existingMeta) {
145
+ this.currentMemoryBytes -= existingMeta.compressedSize;
146
+ }
147
+ if (!this.enforceMemoryLimit(compressedSize)) {
148
+ this.evictedDueToMemory++;
149
+ return;
150
+ }
151
+ if (!existingMeta && this.storage.size >= this.maxSize) {
152
+ this.evictOne('size');
153
+ }
154
+ this.storage.set(key, finalData);
155
+ this.meta.set(key, {
156
+ createdAt: now,
157
+ expiresAt: now + effectiveTtl,
158
+ lastAccess: now,
159
+ insertOrder: ++this.accessCounter,
160
+ accessOrder: this.accessCounter,
161
+ compressed,
162
+ originalSize,
163
+ compressedSize,
164
+ });
165
+ this.currentMemoryBytes += compressedSize;
166
+ this.recordStat('sets');
21
167
  }
22
168
  async delete(key) {
169
+ this.deleteInternal(key);
170
+ this.recordStat('deletes');
171
+ }
172
+ clear(prefix) {
173
+ if (!prefix) {
174
+ this.storage.clear();
175
+ this.meta.clear();
176
+ this.currentMemoryBytes = 0;
177
+ this.evictedDueToMemory = 0;
178
+ if (this.enableStats) {
179
+ this.stats = { hits: 0, misses: 0, sets: 0, deletes: 0, evictions: 0 };
180
+ }
181
+ return;
182
+ }
183
+ for (const key of this.storage.keys()) {
184
+ if (key.startsWith(prefix)) {
185
+ this.deleteInternal(key);
186
+ }
187
+ }
188
+ }
189
+ size() {
190
+ return this.storage.size;
191
+ }
192
+ keys() {
193
+ return Array.from(this.storage.keys());
194
+ }
195
+ has(key) {
196
+ const meta = this.meta.get(key);
197
+ if (!meta)
198
+ return false;
199
+ if (Date.now() > meta.expiresAt) {
200
+ this.deleteInternal(key);
201
+ return false;
202
+ }
203
+ return true;
204
+ }
205
+ getStats() {
206
+ const total = this.stats.hits + this.stats.misses;
207
+ const hitRate = total > 0 ? this.stats.hits / total : 0;
208
+ return {
209
+ enabled: this.enableStats,
210
+ ...this.stats,
211
+ hitRate,
212
+ totalItems: this.storage.size,
213
+ memoryUsageBytes: this.currentMemoryBytes,
214
+ maxMemoryBytes: this.maxMemoryBytes,
215
+ evictedDueToMemory: this.evictedDueToMemory,
216
+ };
217
+ }
218
+ getMemoryStats() {
219
+ const totalItems = this.storage.size;
220
+ const memoryUsagePercent = this.maxMemoryBytes > 0
221
+ ? (this.currentMemoryBytes / this.maxMemoryBytes) * 100
222
+ : 0;
223
+ const systemTotal = os.totalmem();
224
+ const systemFree = os.freemem();
225
+ const systemUsed = systemTotal - systemFree;
226
+ const cachePercentOfSystem = systemTotal > 0 ? (this.currentMemoryBytes / systemTotal) * 100 : 0;
227
+ return {
228
+ currentMemoryBytes: this.currentMemoryBytes,
229
+ maxMemoryBytes: this.maxMemoryBytes,
230
+ maxMemoryPercent: this.maxMemoryPercent,
231
+ memoryUsagePercent: parseFloat(memoryUsagePercent.toFixed(2)),
232
+ cachePercentOfSystemMemory: parseFloat(cachePercentOfSystem.toFixed(2)),
233
+ totalItems,
234
+ maxSize: this.maxSize,
235
+ evictedDueToMemory: this.evictedDueToMemory,
236
+ memoryPressureEvents: this.memoryPressureEvents,
237
+ averageItemSize: totalItems > 0 ? Math.round(this.currentMemoryBytes / totalItems) : 0,
238
+ memoryUsage: {
239
+ current: formatBytes(this.currentMemoryBytes),
240
+ max: formatBytes(this.maxMemoryBytes),
241
+ available: formatBytes(Math.max(0, this.maxMemoryBytes - this.currentMemoryBytes)),
242
+ },
243
+ systemMemory: {
244
+ total: formatBytes(systemTotal),
245
+ free: formatBytes(systemFree),
246
+ used: formatBytes(systemUsed),
247
+ cachePercent: `${cachePercentOfSystem.toFixed(2)}%`,
248
+ },
249
+ };
250
+ }
251
+ getCompressionStats() {
252
+ if (!this.compressionEnabled) {
253
+ return {
254
+ enabled: false,
255
+ totalItems: this.storage.size,
256
+ compressedItems: 0,
257
+ compressionThreshold: this.compressionThreshold,
258
+ totalOriginalSize: 0,
259
+ totalCompressedSize: 0,
260
+ averageCompressionRatio: '0',
261
+ spaceSavingsPercent: '0',
262
+ memoryUsage: {
263
+ uncompressed: '0 B',
264
+ compressed: '0 B',
265
+ saved: '0 B',
266
+ },
267
+ };
268
+ }
269
+ const ratio = this.compressionStats.totalOriginalSize > 0
270
+ ? (this.compressionStats.totalCompressedSize /
271
+ this.compressionStats.totalOriginalSize).toFixed(2)
272
+ : '0';
273
+ const savings = this.compressionStats.totalOriginalSize > 0
274
+ ? (((this.compressionStats.totalOriginalSize -
275
+ this.compressionStats.totalCompressedSize) /
276
+ this.compressionStats.totalOriginalSize) *
277
+ 100).toFixed(2)
278
+ : '0';
279
+ const saved = this.compressionStats.totalOriginalSize -
280
+ this.compressionStats.totalCompressedSize;
281
+ return {
282
+ enabled: true,
283
+ totalItems: this.storage.size,
284
+ compressedItems: this.compressionStats.totalCompressed,
285
+ compressionThreshold: this.compressionThreshold,
286
+ totalOriginalSize: this.compressionStats.totalOriginalSize,
287
+ totalCompressedSize: this.compressionStats.totalCompressedSize,
288
+ averageCompressionRatio: ratio,
289
+ spaceSavingsPercent: savings,
290
+ memoryUsage: {
291
+ uncompressed: formatBytes(this.compressionStats.totalOriginalSize),
292
+ compressed: formatBytes(this.compressionStats.totalCompressedSize),
293
+ saved: formatBytes(saved),
294
+ },
295
+ };
296
+ }
297
+ shutdown() {
298
+ if (this.monitorHandle) {
299
+ clearInterval(this.monitorHandle);
300
+ this.monitorHandle = null;
301
+ }
302
+ if (this.cleanupHandle) {
303
+ clearInterval(this.cleanupHandle);
304
+ this.cleanupHandle = null;
305
+ }
306
+ }
307
+ deleteInternal(key) {
308
+ const meta = this.meta.get(key);
309
+ if (meta) {
310
+ this.currentMemoryBytes -= meta.compressedSize;
311
+ }
23
312
  this.storage.delete(key);
24
- this.ttls.delete(key);
313
+ this.meta.delete(key);
25
314
  }
26
- clear() {
27
- this.storage.clear();
28
- this.ttls.clear();
315
+ recordStat(type) {
316
+ if (this.enableStats) {
317
+ this.stats[type]++;
318
+ }
319
+ }
320
+ isCompressed(data) {
321
+ return (typeof data === 'object' && data !== null && '__compressed' in data);
322
+ }
323
+ compress(data) {
324
+ const buffer = Buffer.from(data, 'utf8');
325
+ const compressed = zlib.gzipSync(buffer);
326
+ return {
327
+ __compressed: true,
328
+ __data: compressed.toString('base64'),
329
+ __originalSize: buffer.length,
330
+ };
331
+ }
332
+ decompress(data) {
333
+ const buffer = Buffer.from(data.__data, 'base64');
334
+ const decompressed = zlib.gunzipSync(buffer);
335
+ return decompressed.toString('utf8');
336
+ }
337
+ selectEvictionCandidate() {
338
+ if (this.meta.size === 0)
339
+ return null;
340
+ let candidate = null;
341
+ let candidateValue = this.evictionPolicy === 'lru' ? Infinity : Infinity;
342
+ for (const [key, meta] of this.meta) {
343
+ const value = this.evictionPolicy === 'lru' ? meta.accessOrder : meta.insertOrder;
344
+ if (value < candidateValue) {
345
+ candidateValue = value;
346
+ candidate = key;
347
+ }
348
+ }
349
+ return candidate;
350
+ }
351
+ evictOne(reason) {
352
+ const candidate = this.selectEvictionCandidate();
353
+ if (!candidate)
354
+ return null;
355
+ const meta = this.meta.get(candidate);
356
+ const freedBytes = meta?.compressedSize ?? 0;
357
+ this.deleteInternal(candidate);
358
+ this.stats.evictions++;
359
+ if (reason === 'memory' || reason === 'heap') {
360
+ this.evictedDueToMemory++;
361
+ }
362
+ this.onEvict?.({
363
+ reason,
364
+ key: candidate,
365
+ freedBytes,
366
+ currentBytes: this.currentMemoryBytes,
367
+ maxMemoryBytes: this.maxMemoryBytes,
368
+ });
369
+ return { key: candidate, freedBytes };
370
+ }
371
+ enforceMemoryLimit(incomingSize) {
372
+ if (incomingSize > this.maxMemoryBytes) {
373
+ return false;
374
+ }
375
+ while (this.currentMemoryBytes + incomingSize > this.maxMemoryBytes &&
376
+ this.storage.size > 0) {
377
+ const result = this.evictOne('memory');
378
+ if (!result)
379
+ break;
380
+ }
381
+ return this.currentMemoryBytes + incomingSize <= this.maxMemoryBytes;
382
+ }
383
+ reduceMemoryTo(targetBytes) {
384
+ targetBytes = Math.max(0, targetBytes);
385
+ let freedBytes = 0;
386
+ while (this.currentMemoryBytes > targetBytes && this.storage.size > 0) {
387
+ const result = this.evictOne('memory');
388
+ if (!result)
389
+ break;
390
+ freedBytes += result.freedBytes;
391
+ }
392
+ return freedBytes;
393
+ }
394
+ memoryHealthCheck() {
395
+ let totalFreed = 0;
396
+ if (this.currentMemoryBytes > this.maxMemoryBytes) {
397
+ const before = this.currentMemoryBytes;
398
+ this.enforceMemoryLimit(0);
399
+ const freed = before - this.currentMemoryBytes;
400
+ if (freed > 0) {
401
+ totalFreed += freed;
402
+ this.memoryPressureEvents++;
403
+ this.onPressure?.({
404
+ reason: 'limit',
405
+ heapLimit: getHeapStats().heapLimit,
406
+ heapUsed: getHeapStats().heapUsed,
407
+ currentBytes: this.currentMemoryBytes,
408
+ maxMemoryBytes: this.maxMemoryBytes,
409
+ freedBytes: freed,
410
+ });
411
+ }
412
+ }
413
+ const { heapUsed, heapLimit, heapRatio } = getHeapStats();
414
+ if (heapLimit > 0 && heapRatio >= this.heapUsageThreshold) {
415
+ const before = this.currentMemoryBytes;
416
+ const target = Math.floor(this.currentMemoryBytes * 0.5);
417
+ this.reduceMemoryTo(target);
418
+ const freed = before - this.currentMemoryBytes;
419
+ if (freed > 0) {
420
+ totalFreed += freed;
421
+ this.memoryPressureEvents++;
422
+ this.onPressure?.({
423
+ reason: 'heap',
424
+ heapLimit,
425
+ heapUsed,
426
+ heapRatio,
427
+ currentBytes: this.currentMemoryBytes,
428
+ maxMemoryBytes: this.maxMemoryBytes,
429
+ freedBytes: freed,
430
+ });
431
+ }
432
+ }
433
+ return totalFreed;
434
+ }
435
+ cleanupExpired() {
436
+ const now = Date.now();
437
+ let cleaned = 0;
438
+ for (const [key, meta] of this.meta) {
439
+ if (now > meta.expiresAt) {
440
+ this.deleteInternal(key);
441
+ cleaned++;
442
+ this.onEvict?.({
443
+ reason: 'expired',
444
+ key,
445
+ freedBytes: meta.compressedSize,
446
+ currentBytes: this.currentMemoryBytes,
447
+ maxMemoryBytes: this.maxMemoryBytes,
448
+ });
449
+ }
450
+ }
451
+ return cleaned;
29
452
  }
30
453
  }
package/dist/cli/index.js CHANGED
@@ -326,6 +326,82 @@ ${pc.bold(pc.yellow('Examples:'))}
326
326
  const { startLoadDashboard } = await import('./tui/load-dashboard.js');
327
327
  await startLoadDashboard({ url, users, duration, mode, http2, rampUp });
328
328
  });
329
+ program
330
+ .command('mcp')
331
+ .description('Start MCP server for AI agents to access Recker documentation')
332
+ .option('-t, --transport <mode>', 'Transport mode: stdio, http, sse', 'stdio')
333
+ .option('-p, --port <number>', 'Server port (for http/sse modes)', '3100')
334
+ .option('-d, --docs <path>', 'Path to documentation folder')
335
+ .option('--debug', 'Enable debug logging')
336
+ .addHelpText('after', `
337
+ ${pc.bold(pc.yellow('Transport Modes:'))}
338
+ ${pc.cyan('stdio')} ${pc.gray('(default)')} For Claude Code and other CLI tools
339
+ ${pc.cyan('http')} Simple HTTP POST endpoint
340
+ ${pc.cyan('sse')} HTTP + Server-Sent Events for real-time notifications
341
+
342
+ ${pc.bold(pc.yellow('Usage:'))}
343
+ ${pc.green('$ rek mcp')} ${pc.gray('Start in stdio mode (for Claude Code)')}
344
+ ${pc.green('$ rek mcp -t http')} ${pc.gray('Start HTTP server on port 3100')}
345
+ ${pc.green('$ rek mcp -t sse -p 8080')} ${pc.gray('Start SSE server on custom port')}
346
+ ${pc.green('$ rek mcp --debug')} ${pc.gray('Enable debug logging')}
347
+
348
+ ${pc.bold(pc.yellow('Tools provided:'))}
349
+ ${pc.cyan('search_docs')} Search documentation by keyword
350
+ ${pc.cyan('get_doc')} Get full content of a doc file
351
+
352
+ ${pc.bold(pc.yellow('Claude Code config (~/.claude.json):'))}
353
+ ${pc.gray(`{
354
+ "mcpServers": {
355
+ "recker-docs": {
356
+ "command": "npx",
357
+ "args": ["recker", "mcp"]
358
+ }
359
+ }
360
+ }`)}
361
+ `)
362
+ .action(async (options) => {
363
+ const { MCPServer } = await import('../mcp/server.js');
364
+ const transport = options.transport;
365
+ const server = new MCPServer({
366
+ transport,
367
+ port: parseInt(options.port),
368
+ docsPath: options.docs,
369
+ debug: options.debug,
370
+ });
371
+ if (transport === 'stdio') {
372
+ await server.start();
373
+ return;
374
+ }
375
+ await server.start();
376
+ const endpoints = transport === 'sse'
377
+ ? `
378
+ │ POST / - JSON-RPC endpoint │
379
+ │ GET /sse - Server-Sent Events │
380
+ │ GET /health - Health check │`
381
+ : `
382
+ │ POST / - JSON-RPC endpoint │`;
383
+ console.log(pc.green(`
384
+ ┌─────────────────────────────────────────────┐
385
+ │ ${pc.bold('Recker MCP Server')} │
386
+ ├─────────────────────────────────────────────┤
387
+ │ Transport: ${pc.cyan(transport.padEnd(31))}│
388
+ │ Endpoint: ${pc.cyan(`http://localhost:${options.port}`.padEnd(32))}│
389
+ │ Docs indexed: ${pc.yellow(String(server.getDocsCount()).padEnd(28))}│
390
+ ├─────────────────────────────────────────────┤${endpoints}
391
+ ├─────────────────────────────────────────────┤
392
+ │ Tools: │
393
+ │ • ${pc.cyan('search_docs')} - Search documentation │
394
+ │ • ${pc.cyan('get_doc')} - Get full doc content │
395
+ │ │
396
+ │ Press ${pc.bold('Ctrl+C')} to stop │
397
+ └─────────────────────────────────────────────┘
398
+ `));
399
+ process.on('SIGINT', async () => {
400
+ console.log(pc.yellow('\nShutting down MCP server...'));
401
+ await server.stop();
402
+ process.exit(0);
403
+ });
404
+ });
329
405
  program.parse();
330
406
  }
331
407
  main().catch((error) => {
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export * from './cookies/memory-cookie-jar.js';
18
18
  export * from './runner/request-runner.js';
19
19
  export * from './contract/index.js';
20
20
  export * from './cache/memory-storage.js';
21
+ export * from './cache/memory-limits.js';
21
22
  export * from './cache/file-storage.js';
22
23
  export * from './utils/body.js';
23
24
  export * from './plugins/xsrf.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAGlD,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAGlC,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAGlD,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAGlC,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ export * from './cookies/memory-cookie-jar.js';
18
18
  export * from './runner/request-runner.js';
19
19
  export * from './contract/index.js';
20
20
  export * from './cache/memory-storage.js';
21
+ export * from './cache/memory-limits.js';
21
22
  export * from './cache/file-storage.js';
22
23
  export * from './utils/body.js';
23
24
  export * from './plugins/xsrf.js';
@@ -1,3 +1,4 @@
1
1
  export * from './types.js';
2
2
  export * from './client.js';
3
+ export * from './server.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAKA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAKA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
package/dist/mcp/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './types.js';
2
2
  export * from './client.js';
3
+ export * from './server.js';
@@ -0,0 +1,28 @@
1
+ import type { IndexedDoc, SearchResult, SearchOptions, HybridSearchConfig } from './types.js';
2
+ export declare class HybridSearch {
3
+ private fuse;
4
+ private docs;
5
+ private vectors;
6
+ private embeddingsData;
7
+ private initialized;
8
+ private config;
9
+ constructor(config?: HybridSearchConfig);
10
+ initialize(docs: IndexedDoc[]): Promise<void>;
11
+ private loadPrecomputedEmbeddings;
12
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
13
+ private fuzzySearch;
14
+ private semanticSearch;
15
+ private extractSnippet;
16
+ private tokenize;
17
+ private averageVectors;
18
+ hasEmbeddings(): boolean;
19
+ getStats(): {
20
+ documents: number;
21
+ embeddings: number;
22
+ model?: string;
23
+ dimensions?: number;
24
+ };
25
+ private log;
26
+ }
27
+ export declare function createHybridSearch(config?: HybridSearchConfig): HybridSearch;
28
+ //# sourceMappingURL=hybrid-search.d.ts.map
@@ -0,0 +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"}