codesearch-mcp 0.0.9-alpha → 0.0.11-alpha
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.
- package/README.md +26 -14
- package/dist/app.js +24 -143
- package/dist/src/commands/BackfillCommand.d.ts +7 -0
- package/dist/src/commands/BackfillCommand.js +27 -0
- package/dist/src/commands/ICommand.d.ts +3 -0
- package/dist/src/commands/ICommand.js +2 -0
- package/dist/src/commands/IndexCommand.d.ts +9 -0
- package/dist/src/commands/IndexCommand.js +75 -0
- package/dist/src/commands/McpCommand.d.ts +7 -0
- package/dist/src/commands/McpCommand.js +21 -0
- package/dist/src/commands/SetupCommand.d.ts +4 -0
- package/dist/src/commands/SetupCommand.js +10 -0
- package/dist/src/config.d.ts +1 -0
- package/dist/src/config.js +41 -2
- package/dist/src/container.d.ts +15 -0
- package/dist/src/container.js +21 -0
- package/dist/src/db/entities/code-chunk.entity.d.ts +1 -1
- package/dist/src/db/entities/code-chunk.entity.js +2 -2
- package/dist/src/db/entities/code-symbol.entity.d.ts +10 -0
- package/dist/src/db/entities/code-symbol.entity.js +59 -0
- package/dist/src/db/index.d.ts +1 -2
- package/dist/src/db/index.js +3 -6
- package/dist/src/file-utils.d.ts +2 -1
- package/dist/src/file-utils.js +10 -5
- package/dist/src/graph.js +5 -4
- package/dist/src/help.js +1 -1
- package/dist/src/interfaces/IAstParser.d.ts +24 -0
- package/dist/src/interfaces/IAstParser.js +2 -0
- package/dist/src/interfaces/IEmbedder.d.ts +4 -0
- package/dist/src/interfaces/IEmbedder.js +2 -0
- package/dist/src/interrupt.d.ts +1 -3
- package/dist/src/interrupt.js +14 -16
- package/dist/src/services/AstParserService.d.ts +14 -0
- package/dist/src/services/AstParserService.js +256 -0
- package/dist/src/services/DatabaseService.d.ts +14 -0
- package/dist/src/services/DatabaseService.js +133 -0
- package/dist/src/services/IndexerService.d.ts +39 -0
- package/dist/src/services/IndexerService.js +286 -0
- package/dist/src/services/LoggerService.d.ts +12 -0
- package/dist/src/services/LoggerService.js +73 -0
- package/dist/src/services/McpServer.d.ts +13 -0
- package/dist/src/services/McpServer.js +411 -0
- package/dist/src/services/OllamaEmbedder.d.ts +9 -0
- package/dist/src/services/OllamaEmbedder.js +27 -0
- package/dist/src/services/SearcherService.d.ts +91 -0
- package/dist/src/services/SearcherService.js +453 -0
- package/dist/src/setup.js +23 -7
- package/package.json +11 -10
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Config } from '../config';
|
|
2
|
+
import type { IEmbedder } from '../interfaces/IEmbedder';
|
|
3
|
+
import type { IAstParser } from '../interfaces/IAstParser';
|
|
4
|
+
import type { DatabaseService } from './DatabaseService';
|
|
5
|
+
import { LoggerService } from './LoggerService';
|
|
6
|
+
export interface IndexStats {
|
|
7
|
+
serviceName: string;
|
|
8
|
+
indexed: number;
|
|
9
|
+
skipped: number;
|
|
10
|
+
failed: number;
|
|
11
|
+
chunks: number;
|
|
12
|
+
elapsedSec: number;
|
|
13
|
+
warnings: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare class IndexerService {
|
|
16
|
+
private db;
|
|
17
|
+
private embedder;
|
|
18
|
+
private ast;
|
|
19
|
+
private config;
|
|
20
|
+
private logger;
|
|
21
|
+
private readonly jsSplitter;
|
|
22
|
+
private readonly schemaSplitter;
|
|
23
|
+
constructor(db: DatabaseService, embedder: IEmbedder, ast: IAstParser, config: Config, logger?: LoggerService);
|
|
24
|
+
backfillSymbols(signal?: AbortSignal): Promise<{
|
|
25
|
+
total: number;
|
|
26
|
+
processed: number;
|
|
27
|
+
skipped: number;
|
|
28
|
+
failed: number;
|
|
29
|
+
}>;
|
|
30
|
+
discoverProjects(rootDir: string): {
|
|
31
|
+
name: string;
|
|
32
|
+
path: string;
|
|
33
|
+
}[];
|
|
34
|
+
private writeDepEdges;
|
|
35
|
+
scanAndIndex(dir: string, serviceName: string, force?: boolean, signal?: AbortSignal, preCollectedFiles?: string[]): Promise<IndexStats>;
|
|
36
|
+
private getSplitter;
|
|
37
|
+
private embedText;
|
|
38
|
+
private ingestFile;
|
|
39
|
+
}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.IndexerService = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const textsplitters_1 = require("@langchain/textsplitters");
|
|
40
|
+
const cli_progress_1 = require("cli-progress");
|
|
41
|
+
const db_1 = require("../db");
|
|
42
|
+
const file_utils_1 = require("../file-utils");
|
|
43
|
+
const LoggerService_1 = require("./LoggerService");
|
|
44
|
+
const SCHEMA_EXTENSIONS = /\.(prisma|graphql|gql)$/;
|
|
45
|
+
class IndexerService {
|
|
46
|
+
db;
|
|
47
|
+
embedder;
|
|
48
|
+
ast;
|
|
49
|
+
config;
|
|
50
|
+
logger;
|
|
51
|
+
jsSplitter;
|
|
52
|
+
schemaSplitter;
|
|
53
|
+
constructor(db, embedder, ast, config, logger = LoggerService_1.LoggerService.silent()) {
|
|
54
|
+
this.db = db;
|
|
55
|
+
this.embedder = embedder;
|
|
56
|
+
this.ast = ast;
|
|
57
|
+
this.config = config;
|
|
58
|
+
this.logger = logger;
|
|
59
|
+
this.jsSplitter = textsplitters_1.RecursiveCharacterTextSplitter.fromLanguage('js', {
|
|
60
|
+
chunkSize: config.indexer.chunkSize,
|
|
61
|
+
chunkOverlap: config.indexer.chunkOverlap,
|
|
62
|
+
});
|
|
63
|
+
this.schemaSplitter = new textsplitters_1.RecursiveCharacterTextSplitter({
|
|
64
|
+
chunkSize: config.indexer.chunkSize,
|
|
65
|
+
chunkOverlap: config.indexer.chunkOverlap,
|
|
66
|
+
separators: ['\n\n', '\n', ' '],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
async backfillSymbols(signal) {
|
|
70
|
+
const rows = await this.db.query(`SELECT DISTINCT "serviceName", "filePath" FROM code_chunk ORDER BY "serviceName", "filePath"`);
|
|
71
|
+
let processed = 0, skipped = 0, failed = 0;
|
|
72
|
+
for (const { serviceName, filePath } of rows) {
|
|
73
|
+
if (signal?.aborted)
|
|
74
|
+
break;
|
|
75
|
+
const absPath = path.join(this.config.workspaceRoot, filePath);
|
|
76
|
+
const projectRoot = path.join(this.config.workspaceRoot, serviceName);
|
|
77
|
+
if (!fs.existsSync(absPath)) {
|
|
78
|
+
skipped++;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const { symbols: rawSymbols } = await this.ast.analyzeFile(absPath, serviceName, projectRoot);
|
|
83
|
+
const symbols = rawSymbols.map(s => ({ ...s, filePath }));
|
|
84
|
+
await this.db.transaction(async (manager) => {
|
|
85
|
+
await manager.delete(db_1.CodeSymbol, { project: serviceName, filePath });
|
|
86
|
+
if (symbols.length > 0) {
|
|
87
|
+
await manager.createQueryBuilder().insert().into(db_1.CodeSymbol).values(symbols).execute();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
processed++;
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
const reason = err.message;
|
|
94
|
+
console.error(` Failed: ${filePath} — ${reason}`);
|
|
95
|
+
this.logger.error('IndexerService: symbol backfill failed', { file: filePath, reason });
|
|
96
|
+
failed++;
|
|
97
|
+
}
|
|
98
|
+
const count = processed + failed;
|
|
99
|
+
if (count > 0 && count % 50 === 0) {
|
|
100
|
+
const msg = ` ${count}/${rows.length} files...`;
|
|
101
|
+
process.stdout.isTTY ? process.stdout.write(msg + '\r') : console.log(msg);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return { total: rows.length, processed, skipped, failed };
|
|
105
|
+
}
|
|
106
|
+
discoverProjects(rootDir) {
|
|
107
|
+
return fs.readdirSync(rootDir, { withFileTypes: true })
|
|
108
|
+
.filter(d => d.isDirectory() && !file_utils_1.IGNORE_DIRS.has(d.name))
|
|
109
|
+
.map(d => ({ name: d.name, path: path.join(rootDir, d.name) }))
|
|
110
|
+
.filter(p => fs.existsSync(path.join(p.path, 'package.json')));
|
|
111
|
+
}
|
|
112
|
+
async writeDepEdges(serviceName, relFilePath, edges, manager) {
|
|
113
|
+
const run = async (mgr) => {
|
|
114
|
+
await mgr.delete(db_1.CodeDependency, { project: serviceName, fromFile: relFilePath });
|
|
115
|
+
if (edges.length > 0) {
|
|
116
|
+
await mgr.createQueryBuilder().insert().into(db_1.CodeDependency).values(edges).execute();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
if (manager)
|
|
120
|
+
await run(manager);
|
|
121
|
+
else
|
|
122
|
+
await this.db.transaction(run);
|
|
123
|
+
}
|
|
124
|
+
async scanAndIndex(dir, serviceName, force = false, signal, preCollectedFiles) {
|
|
125
|
+
const startTime = Date.now();
|
|
126
|
+
const repo = this.db.getRepository(db_1.CodeChunk);
|
|
127
|
+
if (force) {
|
|
128
|
+
await this.db.query(`UPDATE code_chunk SET "lastModified" = NULL WHERE "serviceName" = $1`, [serviceName]);
|
|
129
|
+
}
|
|
130
|
+
const files = preCollectedFiles ?? (0, file_utils_1.collectFiles)(dir, (0, file_utils_1.loadIgnore)(dir), dir);
|
|
131
|
+
const collectedRelPaths = new Set(files.map(f => path.relative(this.config.workspaceRoot, f)));
|
|
132
|
+
const dbPaths = await this.db.query(`SELECT DISTINCT "filePath" FROM code_chunk WHERE "serviceName" = $1`, [serviceName]);
|
|
133
|
+
for (const { filePath } of dbPaths) {
|
|
134
|
+
if (!collectedRelPaths.has(filePath)) {
|
|
135
|
+
await repo.delete({ serviceName, filePath });
|
|
136
|
+
await this.db.query(`DELETE FROM code_dependency WHERE project = $1 AND "fromFile" = $2`, [serviceName, filePath]);
|
|
137
|
+
await this.db.query(`DELETE FROM code_dependency WHERE project = $1 AND "toFile" = $2`, [serviceName, filePath]);
|
|
138
|
+
console.log(` Removed stale: ${path.basename(filePath)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const bar = new cli_progress_1.SingleBar({
|
|
142
|
+
format: `{serviceName} {bar} {percentage}% | {value}/{total} | {duration_formatted} elapsed | ~{eta_formatted} left | {filename}`,
|
|
143
|
+
barCompleteChar: '█',
|
|
144
|
+
barIncompleteChar: '░',
|
|
145
|
+
hideCursor: true,
|
|
146
|
+
clearOnComplete: false,
|
|
147
|
+
}, cli_progress_1.Presets.shades_grey);
|
|
148
|
+
const warnings = [];
|
|
149
|
+
console.log(`\nIndexing ${serviceName}: ${files.length} files`);
|
|
150
|
+
const meta = (0, file_utils_1.readRagMeta)(dir);
|
|
151
|
+
if (meta === 'invalid') {
|
|
152
|
+
const msg = `.ragmeta.json found but invalid JSON`;
|
|
153
|
+
console.log(` ⚠ ${msg}`);
|
|
154
|
+
warnings.push(msg);
|
|
155
|
+
}
|
|
156
|
+
else if (meta !== 'missing') {
|
|
157
|
+
const parts = [meta.description, meta.stack && `[${meta.stack}]`].filter(Boolean).join(' ');
|
|
158
|
+
console.log(` ✓ .ragmeta.json: ${parts || '(no fields)'}`);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
const msg = `No .ragmeta.json — add {"description":"...","stack":"...","notes":"..."} so list_projects can describe this project`;
|
|
162
|
+
console.log(` ⚠ ${msg}`);
|
|
163
|
+
warnings.push(msg);
|
|
164
|
+
}
|
|
165
|
+
if (!fs.existsSync(path.join(dir, '.ragignore'))) {
|
|
166
|
+
const msg = `No .ragignore — create one to exclude generated/codegen files (e.g. src/gql/graphql.ts, **/__snapshots__/**)`;
|
|
167
|
+
console.log(` ⚠ ${msg}`);
|
|
168
|
+
warnings.push(msg);
|
|
169
|
+
}
|
|
170
|
+
bar.start(files.length, 0, { serviceName, filename: '' });
|
|
171
|
+
const stats = {
|
|
172
|
+
serviceName, indexed: 0, skipped: 0, failed: 0, chunks: 0, elapsedSec: 0, warnings,
|
|
173
|
+
};
|
|
174
|
+
for (const filePath of files) {
|
|
175
|
+
if (signal?.aborted) {
|
|
176
|
+
bar.stop();
|
|
177
|
+
console.log(`\n Interrupted — ${serviceName}`);
|
|
178
|
+
stats.elapsedSec = Math.round((Date.now() - startTime) / 100) / 10;
|
|
179
|
+
return stats;
|
|
180
|
+
}
|
|
181
|
+
bar.update({ filename: path.relative(dir, filePath) });
|
|
182
|
+
const mtimeMs = fs.statSync(filePath).mtimeMs;
|
|
183
|
+
const result = await this.ingestFile(filePath, serviceName, mtimeMs, dir);
|
|
184
|
+
if (result.status === 'indexed')
|
|
185
|
+
stats.indexed++;
|
|
186
|
+
else if (result.status === 'skipped')
|
|
187
|
+
stats.skipped++;
|
|
188
|
+
else
|
|
189
|
+
stats.failed++;
|
|
190
|
+
stats.chunks += result.chunks;
|
|
191
|
+
bar.increment();
|
|
192
|
+
}
|
|
193
|
+
bar.stop();
|
|
194
|
+
process.stdout.write('\x1B[J');
|
|
195
|
+
stats.elapsedSec = Math.round((Date.now() - startTime) / 100) / 10;
|
|
196
|
+
return stats;
|
|
197
|
+
}
|
|
198
|
+
getSplitter(filePath) {
|
|
199
|
+
return SCHEMA_EXTENSIONS.test(filePath) ? this.schemaSplitter : this.jsSplitter;
|
|
200
|
+
}
|
|
201
|
+
async embedText(prompt) {
|
|
202
|
+
return this.embedder.embed(prompt);
|
|
203
|
+
}
|
|
204
|
+
async ingestFile(filePath, serviceName, mtimeMs, projectRoot) {
|
|
205
|
+
try {
|
|
206
|
+
const repo = this.db.getRepository(db_1.CodeChunk);
|
|
207
|
+
const relFilePath = path.relative(this.config.workspaceRoot, filePath);
|
|
208
|
+
const existing = await repo.findOne({
|
|
209
|
+
select: ['id', 'lastModified'],
|
|
210
|
+
where: { serviceName, filePath: relFilePath },
|
|
211
|
+
});
|
|
212
|
+
if (existing?.lastModified === mtimeMs) {
|
|
213
|
+
return { status: 'skipped', chunks: 0 };
|
|
214
|
+
}
|
|
215
|
+
const t0 = Date.now();
|
|
216
|
+
const { edges: rawEdges, symbols: rawSymbols } = await this.ast.analyzeFile(filePath, serviceName, projectRoot);
|
|
217
|
+
// normalize edges to workspace-relative paths
|
|
218
|
+
const edges = rawEdges
|
|
219
|
+
.filter(e => e.toFile.startsWith(this.config.workspaceRoot))
|
|
220
|
+
.map(e => ({
|
|
221
|
+
...e,
|
|
222
|
+
fromFile: path.relative(this.config.workspaceRoot, e.fromFile),
|
|
223
|
+
toFile: path.relative(this.config.workspaceRoot, e.toFile),
|
|
224
|
+
}));
|
|
225
|
+
// normalize symbols: replace absolute filePath with workspace-relative
|
|
226
|
+
const symbols = rawSymbols.map(s => ({ ...s, filePath: relFilePath }));
|
|
227
|
+
const depsMs = Date.now() - t0;
|
|
228
|
+
const code = fs.readFileSync(filePath, 'utf-8');
|
|
229
|
+
const chunks = await this.getSplitter(filePath).createDocuments([code]);
|
|
230
|
+
const relPath = path.relative(projectRoot, filePath);
|
|
231
|
+
const t2 = Date.now();
|
|
232
|
+
const records = [];
|
|
233
|
+
for (let i = 0; i < chunks.length; i += this.config.indexer.batchSize) {
|
|
234
|
+
const batch = chunks.slice(i, i + this.config.indexer.batchSize);
|
|
235
|
+
const embedded = await Promise.all(batch.map(async (chunk) => {
|
|
236
|
+
const startLine = (chunk.metadata?.loc?.lines?.from ?? 1);
|
|
237
|
+
const prompt = `Project: ${serviceName} | Path: ${relPath}\n${chunk.pageContent}`;
|
|
238
|
+
const embedding = await this.embedText(prompt);
|
|
239
|
+
return repo.create({
|
|
240
|
+
serviceName, filePath: relFilePath, startLine,
|
|
241
|
+
content: chunk.pageContent,
|
|
242
|
+
embedding: `[${embedding}]`,
|
|
243
|
+
lastModified: mtimeMs,
|
|
244
|
+
});
|
|
245
|
+
}));
|
|
246
|
+
records.push(...embedded);
|
|
247
|
+
}
|
|
248
|
+
const embedMs = Date.now() - t2;
|
|
249
|
+
const t3 = Date.now();
|
|
250
|
+
await this.db.transaction(async (manager) => {
|
|
251
|
+
await manager.delete(db_1.CodeChunk, { serviceName, filePath: relFilePath });
|
|
252
|
+
for (let i = 0; i < records.length; i += this.config.indexer.batchSize) {
|
|
253
|
+
await manager.createQueryBuilder()
|
|
254
|
+
.insert()
|
|
255
|
+
.into(db_1.CodeChunk)
|
|
256
|
+
.values(records.slice(i, i + this.config.indexer.batchSize))
|
|
257
|
+
.execute();
|
|
258
|
+
}
|
|
259
|
+
await this.writeDepEdges(serviceName, relFilePath, edges, manager);
|
|
260
|
+
await manager.delete(db_1.CodeSymbol, { project: serviceName, filePath: relFilePath });
|
|
261
|
+
if (symbols.length > 0) {
|
|
262
|
+
await manager.createQueryBuilder()
|
|
263
|
+
.insert()
|
|
264
|
+
.into(db_1.CodeSymbol)
|
|
265
|
+
.values(symbols)
|
|
266
|
+
.execute();
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
const dbMs = Date.now() - t3;
|
|
270
|
+
if (chunks.length > 0) {
|
|
271
|
+
this.logger.debug('IndexerService: file indexed', {
|
|
272
|
+
file: relFilePath, chunks: chunks.length,
|
|
273
|
+
depsMs, embedMs, dbMs, totalMs: Date.now() - t0,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
return { status: 'indexed', chunks: chunks.length };
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
const reason = err.message;
|
|
280
|
+
console.error(`\n[indexer] Failed: ${filePath} — ${reason}`);
|
|
281
|
+
this.logger.error('IndexerService: failed to index file', { file: filePath, reason });
|
|
282
|
+
return { status: 'failed', chunks: 0 };
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
exports.IndexerService = IndexerService;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import pino from 'pino';
|
|
2
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
3
|
+
export declare class LoggerService {
|
|
4
|
+
private readonly logger;
|
|
5
|
+
constructor(logger: pino.Logger);
|
|
6
|
+
static silent(): LoggerService;
|
|
7
|
+
static fromEnv(): LoggerService;
|
|
8
|
+
debug(msg: string, data?: Record<string, unknown>): void;
|
|
9
|
+
info(msg: string, data?: Record<string, unknown>): void;
|
|
10
|
+
warn(msg: string, data?: Record<string, unknown>): void;
|
|
11
|
+
error(msg: string, data?: Record<string, unknown>): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.LoggerService = void 0;
|
|
40
|
+
const pino_1 = __importDefault(require("pino"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const DEFAULT_LOG_FILE = path.join(os.homedir(), '.config', 'codesearch-mcp', 'rag.log');
|
|
45
|
+
class LoggerService {
|
|
46
|
+
logger;
|
|
47
|
+
constructor(logger) {
|
|
48
|
+
this.logger = logger;
|
|
49
|
+
}
|
|
50
|
+
static silent() {
|
|
51
|
+
return new LoggerService((0, pino_1.default)({ level: 'silent' }));
|
|
52
|
+
}
|
|
53
|
+
static fromEnv() {
|
|
54
|
+
const level = (process.env.LOG_LEVEL ?? 'error');
|
|
55
|
+
const logFileEnv = process.env.LOG_FILE;
|
|
56
|
+
const enabled = logFileEnv !== 'false' && logFileEnv !== '0';
|
|
57
|
+
const filePath = enabled ? (logFileEnv || DEFAULT_LOG_FILE) : null;
|
|
58
|
+
if (filePath)
|
|
59
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
60
|
+
const transport = filePath
|
|
61
|
+
? pino_1.default.transport({ targets: [{ target: 'pino/file', options: { destination: filePath }, level }] })
|
|
62
|
+
: undefined;
|
|
63
|
+
const logger = transport
|
|
64
|
+
? (0, pino_1.default)({ level }, transport)
|
|
65
|
+
: (0, pino_1.default)({ level: 'silent' });
|
|
66
|
+
return new LoggerService(logger);
|
|
67
|
+
}
|
|
68
|
+
debug(msg, data) { this.logger.debug(data ?? {}, msg); }
|
|
69
|
+
info(msg, data) { this.logger.info(data ?? {}, msg); }
|
|
70
|
+
warn(msg, data) { this.logger.warn(data ?? {}, msg); }
|
|
71
|
+
error(msg, data) { this.logger.error(data ?? {}, msg); }
|
|
72
|
+
}
|
|
73
|
+
exports.LoggerService = LoggerService;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Config } from '../config';
|
|
2
|
+
import { SearcherService } from './SearcherService';
|
|
3
|
+
import { LoggerService } from './LoggerService';
|
|
4
|
+
export declare class McpServer {
|
|
5
|
+
private searcher;
|
|
6
|
+
private config;
|
|
7
|
+
private logger;
|
|
8
|
+
constructor(searcher: SearcherService, config: Config, logger?: LoggerService);
|
|
9
|
+
start(): Promise<void>;
|
|
10
|
+
private formatChunk;
|
|
11
|
+
private formatDependencies;
|
|
12
|
+
private formatDependents;
|
|
13
|
+
}
|