recker 1.0.68 → 1.0.70-next.9b4eebc

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 (47) hide show
  1. package/dist/ai/index.d.ts +0 -1
  2. package/dist/ai/index.js +0 -1
  3. package/dist/browser/ai/index.d.ts +0 -1
  4. package/dist/browser/ai/index.js +0 -1
  5. package/dist/browser/index.iife.min.js +51 -51
  6. package/dist/browser/index.min.js +51 -51
  7. package/dist/browser/index.umd.min.js +51 -51
  8. package/dist/cli/index.js +0 -2
  9. package/dist/cli/tui/components/command-palette.d.ts +0 -3
  10. package/dist/cli/tui/components/command-palette.js +0 -16
  11. package/dist/cli/tui/shell-search.d.ts +10 -4
  12. package/dist/cli/tui/shell-search.js +55 -92
  13. package/dist/mcp/index.d.ts +0 -1
  14. package/dist/mcp/index.js +0 -1
  15. package/dist/mcp/server.d.ts +0 -6
  16. package/dist/mcp/server.js +27 -138
  17. package/dist/mcp/tools/ai.js +0 -82
  18. package/dist/mini.d.ts +0 -6
  19. package/dist/mini.js +0 -3
  20. package/dist/version.js +1 -1
  21. package/package.json +12 -16
  22. package/dist/ai/vector/index.d.ts +0 -2
  23. package/dist/ai/vector/index.js +0 -2
  24. package/dist/ai/vector/similarity.d.ts +0 -2
  25. package/dist/ai/vector/similarity.js +0 -27
  26. package/dist/ai/vector/store.d.ts +0 -27
  27. package/dist/ai/vector/store.js +0 -82
  28. package/dist/browser/ai/vector/index.d.ts +0 -2
  29. package/dist/browser/ai/vector/index.js +0 -2
  30. package/dist/browser/ai/vector/similarity.d.ts +0 -2
  31. package/dist/browser/ai/vector/similarity.js +0 -27
  32. package/dist/browser/ai/vector/store.d.ts +0 -27
  33. package/dist/browser/ai/vector/store.js +0 -82
  34. package/dist/cli/commands/vector.d.ts +0 -8
  35. package/dist/cli/commands/vector.js +0 -214
  36. package/dist/mcp/embeddings-loader.d.ts +0 -17
  37. package/dist/mcp/embeddings-loader.js +0 -162
  38. package/dist/mcp/search/embedder.d.ts +0 -9
  39. package/dist/mcp/search/embedder.js +0 -83
  40. package/dist/mcp/search/hybrid-search.d.ts +0 -30
  41. package/dist/mcp/search/hybrid-search.js +0 -402
  42. package/dist/mcp/search/index.d.ts +0 -4
  43. package/dist/mcp/search/index.js +0 -3
  44. package/dist/mcp/search/math.d.ts +0 -5
  45. package/dist/mcp/search/math.js +0 -63
  46. package/dist/mcp/search/types.d.ts +0 -51
  47. package/dist/mcp/search/types.js +0 -1
@@ -1,214 +0,0 @@
1
- import colors from '../../utils/colors.js';
2
- import { MemoryVectorStore } from '../../ai/vector/store.js';
3
- import { promises as fs } from 'node:fs';
4
- async function loadStore(filePath) {
5
- try {
6
- const content = await fs.readFile(filePath, 'utf-8');
7
- return JSON.parse(content);
8
- }
9
- catch {
10
- return [];
11
- }
12
- }
13
- async function saveStore(filePath, docs) {
14
- await fs.writeFile(filePath, JSON.stringify(docs, null, 2), 'utf-8');
15
- }
16
- async function initAI(provider, model) {
17
- const { createAI } = await import('../../ai/index.js');
18
- try {
19
- const aiClient = createAI({
20
- defaultProvider: provider,
21
- });
22
- return new MemoryVectorStore({
23
- client: aiClient,
24
- model: model
25
- });
26
- }
27
- catch (e) {
28
- console.error(colors.red(`AI Initialization Failed: ${e.message}`));
29
- console.log(colors.gray('Ensure you have OPENAI_API_KEY or other provider keys set.'));
30
- process.exit(1);
31
- }
32
- }
33
- export function registerVectorCommand(program) {
34
- const vector = program.command('vector')
35
- .description('Manage a local vector store for RAG (Retrieval-Augmented Generation)')
36
- .example('rek vector add "Recker is a network tool" -f data.json', 'Add document')
37
- .example('rek vector search "network tool" -f data.json -l 3', 'Search')
38
- .example('rek vector info -f data.json', 'Show stats');
39
- vector.command('add')
40
- .description('Add a document to the store')
41
- .argument('<content>', {
42
- type: 'string',
43
- description: 'Text content to add',
44
- example: 'Recker is a network tool',
45
- })
46
- .option('file', {
47
- type: 'string',
48
- short: 'f',
49
- default: 'vectors.json',
50
- description: 'Vector store file path',
51
- example: 'data.json',
52
- })
53
- .option('metadata', {
54
- type: 'string',
55
- short: 'm',
56
- description: 'Metadata JSON for the document',
57
- example: '{"source":"docs"}',
58
- })
59
- .option('provider', {
60
- type: 'string',
61
- short: 'p',
62
- description: 'AI Provider (openai, google, ollama)',
63
- example: 'openai',
64
- })
65
- .option('model', {
66
- type: 'string',
67
- description: 'Embedding model',
68
- example: 'text-embedding-3-small',
69
- })
70
- .example('rek vector add "Recker is a network SDK"', 'Add simple document')
71
- .example('rek vector add "API docs" -f docs.json -m \'{"type":"docs"}\'', 'Add with metadata')
72
- .action(async (content, args, cmdObj) => {
73
- const options = cmdObj.opts ? cmdObj.opts() : {};
74
- const filePath = options.file || 'vectors.json';
75
- const existingDocs = await loadStore(filePath);
76
- const store = await initAI(options.provider, options.model);
77
- if (existingDocs.length > 0) {
78
- await store.add(existingDocs);
79
- }
80
- let metadata = {};
81
- if (options.metadata) {
82
- try {
83
- metadata = JSON.parse(options.metadata);
84
- }
85
- catch {
86
- console.error(colors.red('Invalid metadata JSON'));
87
- process.exit(1);
88
- }
89
- }
90
- console.log(colors.gray(`Generating embedding for: "${content.slice(0, 50)}${content.length > 50 ? '...' : ''}"...`));
91
- await store.add([{ content, metadata }]);
92
- const allDocs = Array.from(store.documents.values());
93
- await saveStore(filePath, allDocs);
94
- console.log(colors.green(`✔ Added document. Total: ${store.count}`));
95
- });
96
- vector.command('search')
97
- .description('Search the vector store')
98
- .argument('<query>', {
99
- type: 'string',
100
- description: 'Search query',
101
- example: 'network tool',
102
- })
103
- .option('file', {
104
- type: 'string',
105
- short: 'f',
106
- default: 'vectors.json',
107
- description: 'Vector store file path',
108
- example: 'data.json',
109
- })
110
- .option('limit', {
111
- type: 'number',
112
- short: 'l',
113
- default: 3,
114
- description: 'Maximum results to return',
115
- example: '5',
116
- })
117
- .option('threshold', {
118
- type: 'number',
119
- short: 't',
120
- default: 0.0,
121
- description: 'Similarity threshold (0-1)',
122
- example: '0.5',
123
- })
124
- .option('provider', {
125
- type: 'string',
126
- short: 'p',
127
- description: 'AI Provider (openai, google, ollama)',
128
- example: 'openai',
129
- })
130
- .option('model', {
131
- type: 'string',
132
- description: 'Embedding model',
133
- example: 'text-embedding-3-small',
134
- })
135
- .option('json', {
136
- short: 'j',
137
- description: 'Output as JSON',
138
- })
139
- .example('rek vector search "how to make requests"', 'Basic search')
140
- .example('rek vector search "api" -f docs.json -l 5 -t 0.5', 'Search with options')
141
- .action(async (query, args, cmdObj) => {
142
- const options = cmdObj.opts ? cmdObj.opts() : {};
143
- const filePath = options.file || 'vectors.json';
144
- const limit = options.limit || 3;
145
- const threshold = options.threshold || 0.0;
146
- const jsonOutput = !!options.json;
147
- const existingDocs = await loadStore(filePath);
148
- const store = await initAI(options.provider, options.model);
149
- if (existingDocs.length > 0) {
150
- await store.add(existingDocs);
151
- }
152
- console.log(colors.gray(`Searching for: "${query}"...`));
153
- const results = await store.search(query, limit, threshold);
154
- if (jsonOutput) {
155
- console.log(JSON.stringify(results, null, 2));
156
- return;
157
- }
158
- console.log(`\n${colors.bold(colors.cyan('Search Results'))} (${results.length})\n`);
159
- results.forEach((res, i) => {
160
- const score = (res.score * 100).toFixed(1) + '%';
161
- const color = res.score > 0.8 ? colors.green : res.score > 0.5 ? colors.yellow : colors.gray;
162
- console.log(`${i + 1}. ${color(score)} - ${res.id}`);
163
- console.log(` ${res.content.slice(0, 100).replace(/\n/g, ' ')}${res.content.length > 100 ? '...' : ''}`);
164
- if (res.metadata && Object.keys(res.metadata).length > 0) {
165
- console.log(` ${colors.gray(JSON.stringify(res.metadata))}`);
166
- }
167
- console.log('');
168
- });
169
- });
170
- vector.command('info')
171
- .description('Show store statistics')
172
- .option('file', {
173
- type: 'string',
174
- short: 'f',
175
- default: 'vectors.json',
176
- description: 'Vector store file path',
177
- example: 'data.json',
178
- })
179
- .option('json', {
180
- short: 'j',
181
- description: 'Output as JSON',
182
- })
183
- .example('rek vector info', 'Show default store info')
184
- .example('rek vector info -f docs.json -j', 'Show as JSON')
185
- .action(async (args, cmdObj) => {
186
- const options = cmdObj.opts ? cmdObj.opts() : {};
187
- const filePath = options.file || 'vectors.json';
188
- const jsonOutput = !!options.json;
189
- const existingDocs = await loadStore(filePath);
190
- if (jsonOutput) {
191
- console.log(JSON.stringify({ file: filePath, count: existingDocs.length, documents: existingDocs }, null, 2));
192
- return;
193
- }
194
- console.log(colors.cyan(`Vector Store: ${filePath}`));
195
- console.log(`Documents: ${existingDocs.length}`);
196
- });
197
- vector.command('clear')
198
- .description('Clear the vector store')
199
- .option('file', {
200
- type: 'string',
201
- short: 'f',
202
- default: 'vectors.json',
203
- description: 'Vector store file path',
204
- example: 'data.json',
205
- })
206
- .example('rek vector clear', 'Clear default store')
207
- .example('rek vector clear -f docs.json', 'Clear specific store')
208
- .action(async (args, cmdObj) => {
209
- const options = cmdObj.opts ? cmdObj.opts() : {};
210
- const filePath = options.file || 'vectors.json';
211
- await saveStore(filePath, []);
212
- console.log(colors.green(`✔ Cleared vector store at ${filePath}`));
213
- });
214
- }
@@ -1,17 +0,0 @@
1
- import type { EmbeddingsData } from './search/types.js';
2
- declare function getPackageVersion(): string;
3
- export declare function getEmbeddingsCachePath(version?: string): string;
4
- export declare function hasLocalEmbeddings(version?: string): boolean;
5
- export declare function loadLocalEmbeddings(version?: string): EmbeddingsData | null;
6
- export declare function saveLocalEmbeddings(data: EmbeddingsData, version?: string): void;
7
- export declare function downloadEmbeddings(version?: string): Promise<EmbeddingsData>;
8
- export declare function loadBundledEmbeddings(): Promise<EmbeddingsData | null>;
9
- export interface LoadEmbeddingsOptions {
10
- forceDownload?: boolean;
11
- version?: string;
12
- offline?: boolean;
13
- debug?: boolean;
14
- }
15
- export declare function loadEmbeddings(options?: LoadEmbeddingsOptions): Promise<EmbeddingsData | null>;
16
- export declare function clearEmbeddingsCache(version?: string): void;
17
- export { getPackageVersion };
@@ -1,162 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
- import { join, dirname } from 'path';
3
- import { fileURLToPath } from 'url';
4
- import { DownloadError } from '../core/errors.js';
5
- function getPackageVersionFromPkg() {
6
- try {
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
- const paths = [
9
- join(__dirname, '..', '..', 'package.json'),
10
- join(__dirname, '..', '..', '..', 'package.json'),
11
- join(process.cwd(), 'package.json'),
12
- ];
13
- for (const pkgPath of paths) {
14
- if (existsSync(pkgPath)) {
15
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
16
- if (pkg.name === 'recker') {
17
- return pkg.version;
18
- }
19
- }
20
- }
21
- }
22
- catch {
23
- }
24
- return '1.0.15';
25
- }
26
- let _packageVersion = null;
27
- function getPackageVersion() {
28
- if (!_packageVersion) {
29
- _packageVersion = getPackageVersionFromPkg();
30
- }
31
- return _packageVersion;
32
- }
33
- const GITHUB_RELEASE_URL = 'https://github.com/forattini-dev/recker/releases/download';
34
- function getCacheDir() {
35
- const homeDir = process.env.HOME || process.env.USERPROFILE || '';
36
- if (homeDir) {
37
- return join(homeDir, '.cache', 'recker');
38
- }
39
- try {
40
- const __dirname = dirname(fileURLToPath(import.meta.url));
41
- return join(__dirname, '..', '..', 'node_modules', '.cache', 'recker');
42
- }
43
- catch {
44
- return join(process.cwd(), 'node_modules', '.cache', 'recker');
45
- }
46
- }
47
- export function getEmbeddingsCachePath(version) {
48
- const cacheDir = getCacheDir();
49
- const ver = version || getPackageVersion();
50
- return join(cacheDir, `embeddings-${ver}.json`);
51
- }
52
- export function hasLocalEmbeddings(version) {
53
- return existsSync(getEmbeddingsCachePath(version));
54
- }
55
- export function loadLocalEmbeddings(version) {
56
- const cachePath = getEmbeddingsCachePath(version);
57
- if (!existsSync(cachePath)) {
58
- return null;
59
- }
60
- try {
61
- const data = readFileSync(cachePath, 'utf-8');
62
- return JSON.parse(data);
63
- }
64
- catch {
65
- return null;
66
- }
67
- }
68
- export function saveLocalEmbeddings(data, version) {
69
- const cachePath = getEmbeddingsCachePath(version);
70
- const cacheDir = dirname(cachePath);
71
- if (!existsSync(cacheDir)) {
72
- mkdirSync(cacheDir, { recursive: true });
73
- }
74
- writeFileSync(cachePath, JSON.stringify(data));
75
- }
76
- export async function downloadEmbeddings(version) {
77
- const ver = version || getPackageVersion();
78
- const url = `${GITHUB_RELEASE_URL}/v${ver}/embeddings.json`;
79
- try {
80
- const response = await fetch(url);
81
- if (!response.ok) {
82
- throw new DownloadError(`Failed to download embeddings: ${response.status} ${response.statusText}`, {
83
- url,
84
- statusCode: response.status,
85
- retriable: response.status >= 500,
86
- });
87
- }
88
- const data = await response.json();
89
- saveLocalEmbeddings(data, ver);
90
- return data;
91
- }
92
- catch (error) {
93
- if (error instanceof DownloadError)
94
- throw error;
95
- throw new DownloadError(`Failed to download embeddings from ${url}: ${error}`, {
96
- url,
97
- retriable: true,
98
- });
99
- }
100
- }
101
- export async function loadBundledEmbeddings() {
102
- try {
103
- const __dirname = dirname(fileURLToPath(import.meta.url));
104
- const bundledPath = join(__dirname, 'data', 'embeddings.json');
105
- if (existsSync(bundledPath)) {
106
- const data = readFileSync(bundledPath, 'utf-8');
107
- return JSON.parse(data);
108
- }
109
- const srcPath = join(__dirname, '..', 'mcp', 'data', 'embeddings.json');
110
- if (existsSync(srcPath)) {
111
- const data = readFileSync(srcPath, 'utf-8');
112
- return JSON.parse(data);
113
- }
114
- }
115
- catch {
116
- }
117
- return null;
118
- }
119
- export async function loadEmbeddings(options = {}) {
120
- const { forceDownload = false, version, offline = false, debug = false } = options;
121
- const log = (msg) => {
122
- if (debug)
123
- console.log(`[embeddings-loader] ${msg}`);
124
- };
125
- if (!forceDownload) {
126
- const cached = loadLocalEmbeddings(version);
127
- if (cached) {
128
- log(`Loaded from cache: ${getEmbeddingsCachePath(version)}`);
129
- return cached;
130
- }
131
- }
132
- const bundled = await loadBundledEmbeddings();
133
- if (bundled) {
134
- log('Loaded bundled embeddings');
135
- return bundled;
136
- }
137
- if (!offline) {
138
- try {
139
- log(`Downloading embeddings v${version || getPackageVersion()}...`);
140
- const downloaded = await downloadEmbeddings(version);
141
- log(`Downloaded and cached: ${downloaded.documents?.length || 0} documents`);
142
- return downloaded;
143
- }
144
- catch (error) {
145
- log(`Download failed: ${error}`);
146
- }
147
- }
148
- log('No embeddings available');
149
- return null;
150
- }
151
- export function clearEmbeddingsCache(version) {
152
- const cachePath = getEmbeddingsCachePath(version);
153
- try {
154
- const fs = require('fs');
155
- if (fs.existsSync(cachePath)) {
156
- fs.unlinkSync(cachePath);
157
- }
158
- }
159
- catch {
160
- }
161
- }
162
- export { getPackageVersion };
@@ -1,9 +0,0 @@
1
- export declare function unloadEmbedder(): void;
2
- export declare function embed(text: string): Promise<number[]>;
3
- export declare function embedBatch(texts: string[]): Promise<number[][]>;
4
- export declare function createEmbedder(): (text: string, model?: string) => Promise<number[]>;
5
- export declare function isFastembedAvailable(): Promise<boolean>;
6
- export declare function getModelInfo(): {
7
- name: string;
8
- dimensions: number;
9
- };
@@ -1,83 +0,0 @@
1
- const MODEL_NAME = 'BGESmallENV15';
2
- const MODEL_DIMENSIONS = 384;
3
- let embedderInstance = null;
4
- let embedderPromise = null;
5
- let idleTimer = null;
6
- const IDLE_TIMEOUT_MS = 5 * 60 * 1000;
7
- function resetIdleTimer() {
8
- if (idleTimer) {
9
- clearTimeout(idleTimer);
10
- }
11
- idleTimer = setTimeout(() => {
12
- unloadEmbedder();
13
- }, IDLE_TIMEOUT_MS);
14
- }
15
- export function unloadEmbedder() {
16
- if (idleTimer) {
17
- clearTimeout(idleTimer);
18
- idleTimer = null;
19
- }
20
- embedderInstance = null;
21
- embedderPromise = null;
22
- }
23
- async function getEmbedder() {
24
- if (embedderInstance) {
25
- resetIdleTimer();
26
- return embedderInstance;
27
- }
28
- if (embedderPromise) {
29
- return embedderPromise;
30
- }
31
- embedderPromise = (async () => {
32
- try {
33
- const { EmbeddingModel, FlagEmbedding } = await import('fastembed');
34
- embedderInstance = await FlagEmbedding.init({
35
- model: EmbeddingModel[MODEL_NAME],
36
- });
37
- resetIdleTimer();
38
- return embedderInstance;
39
- }
40
- catch (error) {
41
- embedderPromise = null;
42
- throw new Error(`Failed to initialize embedder: ${error}`);
43
- }
44
- })();
45
- return embedderPromise;
46
- }
47
- export async function embed(text) {
48
- const embedder = await getEmbedder();
49
- const embeddings = await embedder.embed([text]);
50
- for await (const embedding of embeddings) {
51
- const vec = Array.isArray(embedding) ? embedding[0] : embedding;
52
- return Array.from(vec);
53
- }
54
- throw new Error('No embedding generated');
55
- }
56
- export async function embedBatch(texts) {
57
- const embedder = await getEmbedder();
58
- const embeddings = await embedder.embed(texts);
59
- const results = [];
60
- for await (const embedding of embeddings) {
61
- const vec = Array.isArray(embedding) ? embedding[0] : embedding;
62
- results.push(Array.from(vec));
63
- }
64
- return results;
65
- }
66
- export function createEmbedder() {
67
- return (text, _model) => embed(text);
68
- }
69
- export async function isFastembedAvailable() {
70
- try {
71
- await import('fastembed');
72
- return true;
73
- }
74
- catch {
75
- return false;
76
- }
77
- }
78
- export function getModelInfo() {
79
- return {
80
- name: MODEL_NAME,
81
- dimensions: MODEL_DIMENSIONS,
82
- };
83
- }
@@ -1,30 +0,0 @@
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
- setEmbedder(embedder: (text: string, model?: string) => Promise<number[]>): void;
11
- initialize(docs: IndexedDoc[]): Promise<void>;
12
- private loadPrecomputedEmbeddings;
13
- search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
14
- private fuzzySearch;
15
- private semanticSearch;
16
- private extractSnippet;
17
- private static STOP_WORDS;
18
- private cleanQuery;
19
- private tokenize;
20
- private averageVectors;
21
- hasEmbeddings(): boolean;
22
- getStats(): {
23
- documents: number;
24
- embeddings: number;
25
- model?: string;
26
- dimensions?: number;
27
- };
28
- private log;
29
- }
30
- export declare function createHybridSearch(config?: HybridSearchConfig): HybridSearch;