mcp-code-context 3.0.6 → 3.4.1
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/CHANGELOG.md +84 -1
- package/CHANGELOG_v3.2.0.md +196 -0
- package/CHANGELOG_v3.3.0.md +266 -0
- package/README.md +1 -1
- package/SECURITY.md +177 -0
- package/dist/src/core/engine.d.ts +2 -2
- package/dist/src/core/engine.js +24 -8
- package/dist/src/core/engine.js.map +1 -1
- package/dist/src/core/validator.d.ts +2 -2
- package/dist/src/core/validator.js +8 -7
- package/dist/src/core/validator.js.map +1 -1
- package/dist/src/index.d.ts +6 -6
- package/dist/src/index.js +499 -158
- package/dist/src/index.js.map +1 -1
- package/dist/src/operations/compress.d.ts +18 -0
- package/dist/src/operations/compress.js +89 -0
- package/dist/src/operations/compress.js.map +1 -0
- package/dist/src/operations/confirmationStore.d.ts +53 -0
- package/dist/src/operations/confirmationStore.js +91 -0
- package/dist/src/operations/confirmationStore.js.map +1 -0
- package/dist/src/operations/read.d.ts +50 -0
- package/dist/src/operations/read.js +228 -0
- package/dist/src/operations/read.js.map +1 -0
- package/dist/src/operations/write.d.ts +16 -4
- package/dist/src/operations/write.js +142 -48
- package/dist/src/operations/write.js.map +1 -1
- package/dist/src/parsers/base.d.ts +7 -2
- package/dist/src/parsers/base.js +18 -1
- package/dist/src/parsers/base.js.map +1 -1
- package/dist/src/parsers/dartTreeSitter.d.ts +3 -3
- package/dist/src/parsers/dartTreeSitter.js +6 -11
- package/dist/src/parsers/dartTreeSitter.js.map +1 -1
- package/dist/src/parsers/php.d.ts +2 -2
- package/dist/src/parsers/php.js +5 -10
- package/dist/src/parsers/php.js.map +1 -1
- package/dist/src/parsers/python.d.ts +2 -2
- package/dist/src/parsers/python.js +5 -10
- package/dist/src/parsers/python.js.map +1 -1
- package/dist/src/parsers/registry.d.ts +1 -1
- package/dist/src/parsers/registry.js +2 -2
- package/dist/src/parsers/registry.js.map +1 -1
- package/dist/src/parsers/typescript.d.ts +2 -2
- package/dist/src/parsers/typescript.js +8 -13
- package/dist/src/parsers/typescript.js.map +1 -1
- package/dist/src/utils/auditLogger.d.ts +90 -0
- package/dist/src/utils/auditLogger.js +271 -0
- package/dist/src/utils/auditLogger.js.map +1 -0
- package/dist/src/utils/backupManager.d.ts +33 -0
- package/dist/src/utils/backupManager.js +130 -0
- package/dist/src/utils/backupManager.js.map +1 -0
- package/dist/src/utils/constants.d.ts +12 -0
- package/dist/src/utils/constants.js +33 -0
- package/dist/src/utils/constants.js.map +1 -0
- package/dist/src/utils/diff.d.ts +13 -0
- package/dist/src/utils/diff.js +124 -0
- package/dist/src/utils/diff.js.map +1 -0
- package/dist/src/utils/fileLock.d.ts +63 -0
- package/dist/src/utils/fileLock.js +123 -0
- package/dist/src/utils/fileLock.js.map +1 -0
- package/dist/src/utils/rateLimiter.d.ts +61 -0
- package/dist/src/utils/rateLimiter.js +114 -0
- package/dist/src/utils/rateLimiter.js.map +1 -0
- package/dist/src/utils/safeRegex.d.ts +41 -0
- package/dist/src/utils/safeRegex.js +137 -0
- package/dist/src/utils/safeRegex.js.map +1 -0
- package/dist/src/utils/streaming.d.ts +43 -0
- package/dist/src/utils/streaming.js +175 -0
- package/dist/src/utils/streaming.js.map +1 -0
- package/dist/src/utils/telemetry.d.ts +91 -0
- package/dist/src/utils/telemetry.js +185 -0
- package/dist/src/utils/telemetry.js.map +1 -0
- package/llms.txt +46 -28
- package/package.json +5 -5
- package/scripts/replace-version.js +59 -0
- package/mcp-code-context-3.0.2.tgz +0 -0
- package/tsconfig.tests.json +0 -27
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe Regex - v3.4.1
|
|
3
|
+
* Regex execution with timeout to prevent ReDoS
|
|
4
|
+
*/
|
|
5
|
+
import { REGEX_TIMEOUT_MS } from './constants.js';
|
|
6
|
+
/**
|
|
7
|
+
* Execute regex with timeout protection
|
|
8
|
+
*/
|
|
9
|
+
export async function safeRegexTest(pattern, input, timeoutMs = REGEX_TIMEOUT_MS) {
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
|
|
12
|
+
let timedOut = false;
|
|
13
|
+
const timeout = setTimeout(() => {
|
|
14
|
+
timedOut = true;
|
|
15
|
+
resolve({
|
|
16
|
+
success: false,
|
|
17
|
+
matched: false,
|
|
18
|
+
error: `Regex execution exceeded ${timeoutMs}ms (potential ReDoS)`,
|
|
19
|
+
timedOut: true,
|
|
20
|
+
});
|
|
21
|
+
}, timeoutMs);
|
|
22
|
+
try {
|
|
23
|
+
const matched = regex.test(input);
|
|
24
|
+
clearTimeout(timeout);
|
|
25
|
+
if (timedOut)
|
|
26
|
+
return; // Already resolved
|
|
27
|
+
resolve({ success: true, matched });
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
clearTimeout(timeout);
|
|
31
|
+
if (timedOut)
|
|
32
|
+
return;
|
|
33
|
+
resolve({
|
|
34
|
+
success: false,
|
|
35
|
+
matched: false,
|
|
36
|
+
error: error instanceof Error ? error.message : String(error),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Execute regex match with timeout protection
|
|
43
|
+
*/
|
|
44
|
+
export async function safeRegexMatch(pattern, input, timeoutMs = REGEX_TIMEOUT_MS) {
|
|
45
|
+
return new Promise((resolve) => {
|
|
46
|
+
const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
|
|
47
|
+
let timedOut = false;
|
|
48
|
+
const timeout = setTimeout(() => {
|
|
49
|
+
timedOut = true;
|
|
50
|
+
resolve({
|
|
51
|
+
success: false,
|
|
52
|
+
error: `Regex execution exceeded ${timeoutMs}ms (potential ReDoS)`,
|
|
53
|
+
timedOut: true,
|
|
54
|
+
});
|
|
55
|
+
}, timeoutMs);
|
|
56
|
+
try {
|
|
57
|
+
const matches = input.match(regex);
|
|
58
|
+
clearTimeout(timeout);
|
|
59
|
+
if (timedOut)
|
|
60
|
+
return;
|
|
61
|
+
resolve({ success: true, matches });
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
clearTimeout(timeout);
|
|
65
|
+
if (timedOut)
|
|
66
|
+
return;
|
|
67
|
+
resolve({
|
|
68
|
+
success: false,
|
|
69
|
+
error: error instanceof Error ? error.message : String(error),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Validate regex pattern for safety
|
|
76
|
+
*/
|
|
77
|
+
export function validateRegexPattern(pattern) {
|
|
78
|
+
const issues = [];
|
|
79
|
+
// Check for catastrophic backtracking patterns
|
|
80
|
+
const dangerousPatterns = [
|
|
81
|
+
{ pattern: /\([^)]*\+\)\+/, message: 'Nested quantifiers (a+)+ detected' },
|
|
82
|
+
{ pattern: /\([^)]*\*\)\*/, message: 'Nested quantifiers (a*)* detected' },
|
|
83
|
+
{ pattern: /\([^)]*\+\)\*/, message: 'Nested quantifiers (a+)* detected' },
|
|
84
|
+
{ pattern: /\([^)]*\*\)\+/, message: 'Nested quantifiers (a*)+ detected' },
|
|
85
|
+
{ pattern: /\([^|]*\|[^)]*\)\*/, message: 'Alternation with star (a|b)* detected' },
|
|
86
|
+
{ pattern: /\([^|]*\|[^)]*\)\+/, message: 'Alternation with plus (a|b)+ detected' },
|
|
87
|
+
];
|
|
88
|
+
for (const { pattern: dangerousPattern, message } of dangerousPatterns) {
|
|
89
|
+
if (dangerousPattern.test(pattern)) {
|
|
90
|
+
issues.push(message);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Check for excessive repetition
|
|
94
|
+
if (/\{(\d+),\}/.test(pattern)) {
|
|
95
|
+
const match = pattern.match(/\{(\d+),\}/);
|
|
96
|
+
if (match && parseInt(match[1]) > 1000) {
|
|
97
|
+
issues.push('Excessive repetition {n,} with n > 1000');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Check for very long patterns (potential complexity)
|
|
101
|
+
if (pattern.length > 500) {
|
|
102
|
+
issues.push('Pattern exceeds 500 characters');
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
safe: issues.length === 0,
|
|
106
|
+
issues,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Sanitize regex pattern (escape metacharacters)
|
|
111
|
+
*/
|
|
112
|
+
export function sanitizeRegexPattern(input) {
|
|
113
|
+
return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Create safe regex with validation
|
|
117
|
+
*/
|
|
118
|
+
export function createSafeRegex(pattern, flags) {
|
|
119
|
+
const validation = validateRegexPattern(pattern);
|
|
120
|
+
if (!validation.safe) {
|
|
121
|
+
return {
|
|
122
|
+
regex: null,
|
|
123
|
+
error: `Unsafe regex pattern: ${validation.issues.join(', ')}`,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const regex = new RegExp(pattern, flags);
|
|
128
|
+
return { regex };
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
return {
|
|
132
|
+
regex: null,
|
|
133
|
+
error: error instanceof Error ? error.message : String(error),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=safeRegex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeRegex.js","sourceRoot":"","sources":["../../../src/utils/safeRegex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Streaming - v3.4.1
|
|
3
|
+
* Stream large files in chunks to avoid memory exhaustion
|
|
4
|
+
*/
|
|
5
|
+
export interface StreamOptions {
|
|
6
|
+
chunkSize?: number;
|
|
7
|
+
maxSize?: number;
|
|
8
|
+
encoding?: BufferEncoding;
|
|
9
|
+
}
|
|
10
|
+
export interface StreamResult {
|
|
11
|
+
success: boolean;
|
|
12
|
+
chunks?: string[];
|
|
13
|
+
totalSize?: number;
|
|
14
|
+
error?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Stream file in chunks
|
|
18
|
+
*/
|
|
19
|
+
export declare function streamFile(filePath: string, options?: StreamOptions): Promise<StreamResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Stream file line by line (memory efficient)
|
|
22
|
+
*/
|
|
23
|
+
export declare function streamLines(filePath: string, callback: (line: string, lineNumber: number) => Promise<boolean | void>): Promise<{
|
|
24
|
+
success: boolean;
|
|
25
|
+
linesProcessed: number;
|
|
26
|
+
error?: string;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Stream and parse large file with AST (chunked)
|
|
30
|
+
*/
|
|
31
|
+
export declare function streamParseFile(filePath: string, parser: any, options?: StreamOptions): Promise<{
|
|
32
|
+
success: boolean;
|
|
33
|
+
symbols?: any[];
|
|
34
|
+
error?: string;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Write file in chunks (streaming write)
|
|
38
|
+
*/
|
|
39
|
+
export declare function streamWriteFile(filePath: string, content: string, options?: StreamOptions): Promise<{
|
|
40
|
+
success: boolean;
|
|
41
|
+
bytesWritten?: number;
|
|
42
|
+
error?: string;
|
|
43
|
+
}>;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Streaming - v3.4.1
|
|
3
|
+
* Stream large files in chunks to avoid memory exhaustion
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
import * as readline from "node:readline";
|
|
7
|
+
import { MAX_FILE_SIZE_BYTES } from "./constants.js";
|
|
8
|
+
/**
|
|
9
|
+
* Stream file in chunks
|
|
10
|
+
*/
|
|
11
|
+
export async function streamFile(filePath, options = {}) {
|
|
12
|
+
const { chunkSize = 1024 * 1024, // 1MB chunks
|
|
13
|
+
maxSize = MAX_FILE_SIZE_BYTES, encoding = "utf-8", } = options;
|
|
14
|
+
try {
|
|
15
|
+
// Check file size first
|
|
16
|
+
const stat = await fs.promises.stat(filePath);
|
|
17
|
+
if (stat.size > maxSize) {
|
|
18
|
+
return {
|
|
19
|
+
success: false,
|
|
20
|
+
error: `File too large: ${(stat.size / 1024 / 1024).toFixed(2)}MB (max: ${(maxSize / 1024 / 1024).toFixed(2)}MB)`,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const chunks = [];
|
|
24
|
+
let totalSize = 0;
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const stream = fs.createReadStream(filePath, {
|
|
27
|
+
encoding,
|
|
28
|
+
highWaterMark: chunkSize,
|
|
29
|
+
});
|
|
30
|
+
stream.on("data", (chunk) => {
|
|
31
|
+
const chunkStr = typeof chunk === 'string' ? chunk : chunk.toString(encoding);
|
|
32
|
+
totalSize += Buffer.byteLength(chunkStr, encoding);
|
|
33
|
+
if (totalSize > maxSize) {
|
|
34
|
+
stream.destroy();
|
|
35
|
+
resolve({
|
|
36
|
+
success: false,
|
|
37
|
+
error: `File size exceeded during streaming: ${(totalSize / 1024 / 1024).toFixed(2)}MB`,
|
|
38
|
+
});
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
chunks.push(chunkStr);
|
|
42
|
+
});
|
|
43
|
+
stream.on("end", () => {
|
|
44
|
+
resolve({
|
|
45
|
+
success: true,
|
|
46
|
+
chunks,
|
|
47
|
+
totalSize,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
stream.on("error", (error) => {
|
|
51
|
+
resolve({
|
|
52
|
+
success: false,
|
|
53
|
+
error: error.message,
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
error: error instanceof Error ? error.message : String(error),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Stream file line by line (memory efficient)
|
|
67
|
+
*/
|
|
68
|
+
export async function streamLines(filePath, callback) {
|
|
69
|
+
try {
|
|
70
|
+
const fileStream = fs.createReadStream(filePath);
|
|
71
|
+
const rl = readline.createInterface({
|
|
72
|
+
input: fileStream,
|
|
73
|
+
crlfDelay: Infinity,
|
|
74
|
+
});
|
|
75
|
+
let lineNumber = 0;
|
|
76
|
+
let shouldContinue = true;
|
|
77
|
+
for await (const line of rl) {
|
|
78
|
+
lineNumber++;
|
|
79
|
+
if (!shouldContinue)
|
|
80
|
+
break;
|
|
81
|
+
const result = await callback(line, lineNumber);
|
|
82
|
+
if (result === false) {
|
|
83
|
+
shouldContinue = false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
success: true,
|
|
88
|
+
linesProcessed: lineNumber,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return {
|
|
93
|
+
success: false,
|
|
94
|
+
linesProcessed: 0,
|
|
95
|
+
error: error instanceof Error ? error.message : String(error),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Stream and parse large file with AST (chunked)
|
|
101
|
+
*/
|
|
102
|
+
export async function streamParseFile(filePath, parser, options = {}) {
|
|
103
|
+
try {
|
|
104
|
+
// For files >10MB, stream in chunks
|
|
105
|
+
const stat = await fs.promises.stat(filePath);
|
|
106
|
+
if (stat.size <= 10 * 1024 * 1024) {
|
|
107
|
+
// Small file, read normally
|
|
108
|
+
const content = await fs.promises.readFile(filePath, "utf-8");
|
|
109
|
+
const tree = parser.parse(content);
|
|
110
|
+
const symbols = parser.findSymbols(tree);
|
|
111
|
+
return { success: true, symbols };
|
|
112
|
+
}
|
|
113
|
+
// Large file, stream and parse incrementally
|
|
114
|
+
const streamResult = await streamFile(filePath, options);
|
|
115
|
+
if (!streamResult.success) {
|
|
116
|
+
return { success: false, error: streamResult.error };
|
|
117
|
+
}
|
|
118
|
+
// Combine chunks and parse
|
|
119
|
+
const content = streamResult.chunks.join("");
|
|
120
|
+
const tree = parser.parse(content);
|
|
121
|
+
const symbols = parser.findSymbols(tree);
|
|
122
|
+
return { success: true, symbols };
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
error: error instanceof Error ? error.message : String(error),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Write file in chunks (streaming write)
|
|
133
|
+
*/
|
|
134
|
+
export async function streamWriteFile(filePath, content, options = {}) {
|
|
135
|
+
const { chunkSize = 1024 * 1024, encoding = "utf-8" } = options;
|
|
136
|
+
try {
|
|
137
|
+
const tmpPath = filePath + ".tmp";
|
|
138
|
+
const writeStream = fs.createWriteStream(tmpPath, { encoding });
|
|
139
|
+
let bytesWritten = 0;
|
|
140
|
+
let offset = 0;
|
|
141
|
+
return new Promise((resolve) => {
|
|
142
|
+
const writeChunk = () => {
|
|
143
|
+
if (offset >= content.length) {
|
|
144
|
+
writeStream.end(() => {
|
|
145
|
+
fs.promises.rename(tmpPath, filePath)
|
|
146
|
+
.then(() => resolve({ success: true, bytesWritten }))
|
|
147
|
+
.catch((error) => resolve({ success: false, error: error.message }));
|
|
148
|
+
});
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const chunk = content.substring(offset, offset + chunkSize);
|
|
152
|
+
offset += chunkSize;
|
|
153
|
+
const canContinue = writeStream.write(chunk, encoding);
|
|
154
|
+
bytesWritten += Buffer.byteLength(chunk, encoding);
|
|
155
|
+
if (canContinue) {
|
|
156
|
+
writeChunk();
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
writeStream.once("drain", writeChunk);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
writeStream.on("error", (error) => {
|
|
163
|
+
resolve({ success: false, error: error.message });
|
|
164
|
+
});
|
|
165
|
+
writeChunk();
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
return {
|
|
170
|
+
success: false,
|
|
171
|
+
error: error instanceof Error ? error.message : String(error),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=streaming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../../src/utils/streaming.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry - v3.4.1
|
|
3
|
+
* Metrics collection and monitoring
|
|
4
|
+
*/
|
|
5
|
+
export interface Metric {
|
|
6
|
+
name: string;
|
|
7
|
+
value: number;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
tags?: Record<string, string>;
|
|
10
|
+
}
|
|
11
|
+
export interface OperationMetrics {
|
|
12
|
+
toolName: string;
|
|
13
|
+
duration: number;
|
|
14
|
+
success: boolean;
|
|
15
|
+
error?: string;
|
|
16
|
+
clientId?: string;
|
|
17
|
+
timestamp: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class TelemetryCollector {
|
|
20
|
+
private metrics;
|
|
21
|
+
private operations;
|
|
22
|
+
private readonly maxMetrics;
|
|
23
|
+
private readonly maxOperations;
|
|
24
|
+
constructor(maxMetrics?: number, maxOperations?: number);
|
|
25
|
+
/**
|
|
26
|
+
* Record a metric
|
|
27
|
+
*/
|
|
28
|
+
recordMetric(name: string, value: number, tags?: Record<string, string>): void;
|
|
29
|
+
/**
|
|
30
|
+
* Record operation execution
|
|
31
|
+
*/
|
|
32
|
+
recordOperation(metrics: Omit<OperationMetrics, "timestamp">): void;
|
|
33
|
+
/**
|
|
34
|
+
* Get metrics summary
|
|
35
|
+
*/
|
|
36
|
+
getSummary(): {
|
|
37
|
+
totalOperations: number;
|
|
38
|
+
successRate: number;
|
|
39
|
+
averageDuration: number;
|
|
40
|
+
errorRate: number;
|
|
41
|
+
operationsByTool: Record<string, number>;
|
|
42
|
+
recentErrors: Array<{
|
|
43
|
+
tool: string;
|
|
44
|
+
error: string;
|
|
45
|
+
timestamp: number;
|
|
46
|
+
}>;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Get metrics for specific tool
|
|
50
|
+
*/
|
|
51
|
+
getToolMetrics(toolName: string): {
|
|
52
|
+
count: number;
|
|
53
|
+
successRate: number;
|
|
54
|
+
averageDuration: number;
|
|
55
|
+
p50Duration: number;
|
|
56
|
+
p95Duration: number;
|
|
57
|
+
p99Duration: number;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Get cache hit rate (if applicable)
|
|
61
|
+
*/
|
|
62
|
+
getCacheMetrics(): {
|
|
63
|
+
hits: number;
|
|
64
|
+
misses: number;
|
|
65
|
+
hitRate: number;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Export metrics (for external monitoring)
|
|
69
|
+
*/
|
|
70
|
+
exportMetrics(): {
|
|
71
|
+
metrics: Metric[];
|
|
72
|
+
operations: OperationMetrics[];
|
|
73
|
+
summary: ReturnType<TelemetryCollector["getSummary"]>;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Clear all metrics
|
|
77
|
+
*/
|
|
78
|
+
clear(): void;
|
|
79
|
+
/**
|
|
80
|
+
* Get metrics in Prometheus format
|
|
81
|
+
*/
|
|
82
|
+
toPrometheus(): string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Global telemetry instance
|
|
86
|
+
*/
|
|
87
|
+
export declare const globalTelemetry: TelemetryCollector;
|
|
88
|
+
/**
|
|
89
|
+
* Helper to track operation duration
|
|
90
|
+
*/
|
|
91
|
+
export declare function trackOperation<T>(toolName: string, operation: () => Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry - v3.4.1
|
|
3
|
+
* Metrics collection and monitoring
|
|
4
|
+
*/
|
|
5
|
+
export class TelemetryCollector {
|
|
6
|
+
metrics = [];
|
|
7
|
+
operations = [];
|
|
8
|
+
maxMetrics;
|
|
9
|
+
maxOperations;
|
|
10
|
+
constructor(maxMetrics = 10000, maxOperations = 1000) {
|
|
11
|
+
this.maxMetrics = maxMetrics;
|
|
12
|
+
this.maxOperations = maxOperations;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Record a metric
|
|
16
|
+
*/
|
|
17
|
+
recordMetric(name, value, tags) {
|
|
18
|
+
this.metrics.push({
|
|
19
|
+
name,
|
|
20
|
+
value,
|
|
21
|
+
timestamp: Date.now(),
|
|
22
|
+
tags,
|
|
23
|
+
});
|
|
24
|
+
// Cleanup old metrics
|
|
25
|
+
if (this.metrics.length > this.maxMetrics) {
|
|
26
|
+
this.metrics = this.metrics.slice(-this.maxMetrics);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Record operation execution
|
|
31
|
+
*/
|
|
32
|
+
recordOperation(metrics) {
|
|
33
|
+
this.operations.push({
|
|
34
|
+
...metrics,
|
|
35
|
+
timestamp: Date.now(),
|
|
36
|
+
});
|
|
37
|
+
// Cleanup old operations
|
|
38
|
+
if (this.operations.length > this.maxOperations) {
|
|
39
|
+
this.operations = this.operations.slice(-this.maxOperations);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get metrics summary
|
|
44
|
+
*/
|
|
45
|
+
getSummary() {
|
|
46
|
+
const total = this.operations.length;
|
|
47
|
+
const successful = this.operations.filter((op) => op.success).length;
|
|
48
|
+
const avgDuration = this.operations.reduce((sum, op) => sum + op.duration, 0) / total || 0;
|
|
49
|
+
const operationsByTool = {};
|
|
50
|
+
for (const op of this.operations) {
|
|
51
|
+
operationsByTool[op.toolName] = (operationsByTool[op.toolName] || 0) + 1;
|
|
52
|
+
}
|
|
53
|
+
const recentErrors = this.operations
|
|
54
|
+
.filter((op) => !op.success && op.error)
|
|
55
|
+
.slice(-10)
|
|
56
|
+
.map((op) => ({
|
|
57
|
+
tool: op.toolName,
|
|
58
|
+
error: op.error,
|
|
59
|
+
timestamp: op.timestamp,
|
|
60
|
+
}));
|
|
61
|
+
return {
|
|
62
|
+
totalOperations: total,
|
|
63
|
+
successRate: total > 0 ? (successful / total) * 100 : 0,
|
|
64
|
+
averageDuration: avgDuration,
|
|
65
|
+
errorRate: total > 0 ? ((total - successful) / total) * 100 : 0,
|
|
66
|
+
operationsByTool,
|
|
67
|
+
recentErrors,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get metrics for specific tool
|
|
72
|
+
*/
|
|
73
|
+
getToolMetrics(toolName) {
|
|
74
|
+
const toolOps = this.operations.filter((op) => op.toolName === toolName);
|
|
75
|
+
const count = toolOps.length;
|
|
76
|
+
if (count === 0) {
|
|
77
|
+
return {
|
|
78
|
+
count: 0,
|
|
79
|
+
successRate: 0,
|
|
80
|
+
averageDuration: 0,
|
|
81
|
+
p50Duration: 0,
|
|
82
|
+
p95Duration: 0,
|
|
83
|
+
p99Duration: 0,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const successful = toolOps.filter((op) => op.success).length;
|
|
87
|
+
const durations = toolOps.map((op) => op.duration).sort((a, b) => a - b);
|
|
88
|
+
return {
|
|
89
|
+
count,
|
|
90
|
+
successRate: (successful / count) * 100,
|
|
91
|
+
averageDuration: durations.reduce((sum, d) => sum + d, 0) / count,
|
|
92
|
+
p50Duration: durations[Math.floor(count * 0.5)],
|
|
93
|
+
p95Duration: durations[Math.floor(count * 0.95)],
|
|
94
|
+
p99Duration: durations[Math.floor(count * 0.99)],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get cache hit rate (if applicable)
|
|
99
|
+
*/
|
|
100
|
+
getCacheMetrics() {
|
|
101
|
+
const cacheMetrics = this.metrics.filter((m) => m.name.startsWith("cache."));
|
|
102
|
+
const hits = cacheMetrics.filter((m) => m.name === "cache.hit").length;
|
|
103
|
+
const misses = cacheMetrics.filter((m) => m.name === "cache.miss").length;
|
|
104
|
+
const total = hits + misses;
|
|
105
|
+
return {
|
|
106
|
+
hits,
|
|
107
|
+
misses,
|
|
108
|
+
hitRate: total > 0 ? (hits / total) * 100 : 0,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Export metrics (for external monitoring)
|
|
113
|
+
*/
|
|
114
|
+
exportMetrics() {
|
|
115
|
+
return {
|
|
116
|
+
metrics: [...this.metrics],
|
|
117
|
+
operations: [...this.operations],
|
|
118
|
+
summary: this.getSummary(),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Clear all metrics
|
|
123
|
+
*/
|
|
124
|
+
clear() {
|
|
125
|
+
this.metrics = [];
|
|
126
|
+
this.operations = [];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get metrics in Prometheus format
|
|
130
|
+
*/
|
|
131
|
+
toPrometheus() {
|
|
132
|
+
const lines = [];
|
|
133
|
+
// Operation counts
|
|
134
|
+
const summary = this.getSummary();
|
|
135
|
+
lines.push(`# HELP mcp_operations_total Total number of operations`);
|
|
136
|
+
lines.push(`# TYPE mcp_operations_total counter`);
|
|
137
|
+
lines.push(`mcp_operations_total ${summary.totalOperations}`);
|
|
138
|
+
// Success rate
|
|
139
|
+
lines.push(`# HELP mcp_success_rate Success rate percentage`);
|
|
140
|
+
lines.push(`# TYPE mcp_success_rate gauge`);
|
|
141
|
+
lines.push(`mcp_success_rate ${summary.successRate.toFixed(2)}`);
|
|
142
|
+
// Average duration
|
|
143
|
+
lines.push(`# HELP mcp_duration_avg Average operation duration in ms`);
|
|
144
|
+
lines.push(`# TYPE mcp_duration_avg gauge`);
|
|
145
|
+
lines.push(`mcp_duration_avg ${summary.averageDuration.toFixed(2)}`);
|
|
146
|
+
// Operations by tool
|
|
147
|
+
lines.push(`# HELP mcp_operations_by_tool Operations count by tool`);
|
|
148
|
+
lines.push(`# TYPE mcp_operations_by_tool counter`);
|
|
149
|
+
for (const [tool, count] of Object.entries(summary.operationsByTool)) {
|
|
150
|
+
lines.push(`mcp_operations_by_tool{tool="${tool}"} ${count}`);
|
|
151
|
+
}
|
|
152
|
+
return lines.join("\n");
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Global telemetry instance
|
|
157
|
+
*/
|
|
158
|
+
export const globalTelemetry = new TelemetryCollector();
|
|
159
|
+
/**
|
|
160
|
+
* Helper to track operation duration
|
|
161
|
+
*/
|
|
162
|
+
export async function trackOperation(toolName, operation) {
|
|
163
|
+
const startTime = Date.now();
|
|
164
|
+
let success = true;
|
|
165
|
+
let error;
|
|
166
|
+
try {
|
|
167
|
+
const result = await operation();
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
success = false;
|
|
172
|
+
error = err instanceof Error ? err.message : String(err);
|
|
173
|
+
throw err;
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
const duration = Date.now() - startTime;
|
|
177
|
+
globalTelemetry.recordOperation({
|
|
178
|
+
toolName,
|
|
179
|
+
duration,
|
|
180
|
+
success,
|
|
181
|
+
error,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../../src/utils/telemetry.ts"],"names":[],"mappings":"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"}
|