make-laten 1.1.1 → 1.2.0
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 +3 -3
- package/dist/cli/index.js +306 -65
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +306 -65
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.js +288 -68
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +274 -67
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/server.js +250 -68
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/server.mjs +250 -68
- package/dist/mcp/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/mcp/server.js
CHANGED
|
@@ -52,29 +52,145 @@ function isKnownPattern(content) {
|
|
|
52
52
|
return patterns.some((p) => p.test(content));
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
// src/compress/strip.ts
|
|
56
|
+
function stripImports(content) {
|
|
57
|
+
return content.replace(/^import\s+[\s\S]*?from\s+['"][^'"]+['"]\s*;?\s*$/gm, "").replace(/^import\s+['"][^'"]+['"]\s*;?\s*$/gm, "").replace(/^import\s+\{[^}]*\}\s+from\s+['"][^'"]+['"]\s*;?\s*$/gm, "").split("\n").filter((l) => l.trim() !== "").join("\n");
|
|
58
|
+
}
|
|
59
|
+
function stripComments(content) {
|
|
60
|
+
let result = content.replace(/(?<!["'`])\/\/.*$/gm, "");
|
|
61
|
+
result = result.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
62
|
+
return result.split("\n").filter((l) => l.trim() !== "").join("\n");
|
|
63
|
+
}
|
|
64
|
+
function stripBlankLines(content) {
|
|
65
|
+
return content.replace(/\n{3,}/g, "\n\n");
|
|
66
|
+
}
|
|
67
|
+
function stripWhitespace(content) {
|
|
68
|
+
return content.replace(/[ \t]+$/gm, "");
|
|
69
|
+
}
|
|
70
|
+
function stripAll(content) {
|
|
71
|
+
let result = content;
|
|
72
|
+
result = stripImports(result);
|
|
73
|
+
result = stripComments(result);
|
|
74
|
+
result = stripBlankLines(result);
|
|
75
|
+
result = stripWhitespace(result);
|
|
76
|
+
return result.trim();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// src/compress/structure.ts
|
|
80
|
+
function extractExports(content) {
|
|
81
|
+
const lines = content.split("\n");
|
|
82
|
+
const exports2 = [];
|
|
83
|
+
for (const line of lines) {
|
|
84
|
+
const trimmed = line.trim();
|
|
85
|
+
if (/^export\s+(default\s+)?/.test(trimmed)) {
|
|
86
|
+
if (trimmed.includes("{") && !trimmed.includes("}")) {
|
|
87
|
+
exports2.push(trimmed.replace(/\{[\s\S]*$/, "{ ... }"));
|
|
88
|
+
} else {
|
|
89
|
+
exports2.push(trimmed);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return exports2.join("\n");
|
|
94
|
+
}
|
|
95
|
+
function extractClassMethods(content) {
|
|
96
|
+
const classRegex = /class\s+\w+[^{]*\{([\s\S]*?)\n\}/g;
|
|
97
|
+
const methods = [];
|
|
98
|
+
let match;
|
|
99
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
100
|
+
const classBody = match[1];
|
|
101
|
+
const methodRegex = /(^\s*(?:public|private|protected|static|async|abstract|\s)*\w+\s*\([^)]*\)(?:\s*:\s*[^{]+)?)\s*\{/gm;
|
|
102
|
+
let methodMatch;
|
|
103
|
+
while ((methodMatch = methodRegex.exec(classBody)) !== null) {
|
|
104
|
+
methods.push(methodMatch[1].trim());
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return methods.join("\n");
|
|
108
|
+
}
|
|
109
|
+
function extractFunctionSignatures(content) {
|
|
110
|
+
const funcRegex = /(export\s+)?(async\s+)?function\s+\w+\s*\([^)]*\)(?:\s*:\s*[^{]+)?\s*\{/g;
|
|
111
|
+
const signatures = [];
|
|
112
|
+
let match;
|
|
113
|
+
while ((match = funcRegex.exec(content)) !== null) {
|
|
114
|
+
signatures.push(match[0].replace(/\{$/, ""));
|
|
115
|
+
}
|
|
116
|
+
return signatures.join("\n");
|
|
117
|
+
}
|
|
118
|
+
function extractTypeDefinitions(content) {
|
|
119
|
+
const typeRegex = /(export\s+)?(interface|type)\s+\w+[^{]*\{[^}]*\}|(export\s+)?type\s+\w+\s*=[^;]+;?/g;
|
|
120
|
+
const types = [];
|
|
121
|
+
let match;
|
|
122
|
+
while ((match = typeRegex.exec(content)) !== null) {
|
|
123
|
+
types.push(match[0].trim());
|
|
124
|
+
}
|
|
125
|
+
return types.join("\n");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/compress/truncate.ts
|
|
129
|
+
function smartTruncate(content, maxTokens) {
|
|
130
|
+
const lines = content.split("\n");
|
|
131
|
+
const estimatedTokens = Math.ceil(content.length / 4);
|
|
132
|
+
if (estimatedTokens <= maxTokens) return content;
|
|
133
|
+
const targetLines = Math.round(maxTokens * 4 / (content.length / lines.length));
|
|
134
|
+
const headerLines = Math.floor(targetLines * 0.3);
|
|
135
|
+
const footerLines = Math.floor(targetLines * 0.3);
|
|
136
|
+
const omitted = lines.length - headerLines - footerLines;
|
|
137
|
+
const header = lines.slice(0, headerLines);
|
|
138
|
+
const footer = lines.slice(-footerLines);
|
|
139
|
+
return [...header, `
|
|
140
|
+
... [${omitted} lines omitted] ...
|
|
141
|
+
`, ...footer].join("\n");
|
|
142
|
+
}
|
|
143
|
+
|
|
55
144
|
// src/compress/file-read.ts
|
|
56
145
|
var FileReadCompressor = class {
|
|
57
146
|
async compress(input) {
|
|
58
147
|
const { content, filePath, language } = input;
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
|
|
148
|
+
const lines = content.split("\n").length;
|
|
149
|
+
const tokens = Math.ceil(content.length / 4);
|
|
150
|
+
if (tokens < 200) {
|
|
151
|
+
return {
|
|
152
|
+
content,
|
|
153
|
+
original: content,
|
|
154
|
+
confidence: 1,
|
|
155
|
+
metadata: {
|
|
156
|
+
strategy: "passthrough",
|
|
157
|
+
originalLines: lines,
|
|
158
|
+
compressedLines: lines,
|
|
159
|
+
savings: 0
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
const stripped = stripAll(content);
|
|
164
|
+
const exports2 = extractExports(stripped);
|
|
165
|
+
const classes = extractClassMethods(stripped);
|
|
166
|
+
const functions = extractFunctionSignatures(stripped);
|
|
167
|
+
const types = extractTypeDefinitions(stripped);
|
|
168
|
+
const sections = [
|
|
62
169
|
`// ${filePath} (${content.split("\n").length} lines)`,
|
|
63
170
|
"",
|
|
64
|
-
...signatures,
|
|
65
|
-
"",
|
|
66
171
|
"// Exports:",
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
172
|
+
exports2,
|
|
173
|
+
"",
|
|
174
|
+
"// Classes:",
|
|
175
|
+
classes,
|
|
176
|
+
"",
|
|
177
|
+
"// Functions:",
|
|
178
|
+
functions,
|
|
179
|
+
"",
|
|
180
|
+
"// Types:",
|
|
181
|
+
types
|
|
182
|
+
].filter((l) => l !== "" && !l.endsWith(":"));
|
|
183
|
+
let compressed = sections.join("\n");
|
|
184
|
+
const maxTokens = 2e3;
|
|
185
|
+
compressed = smartTruncate(compressed, maxTokens);
|
|
70
186
|
return {
|
|
71
187
|
content: compressed,
|
|
72
188
|
original: content,
|
|
73
189
|
confidence: calculateConfidence(content, compressed),
|
|
74
190
|
metadata: {
|
|
75
|
-
strategy: "
|
|
191
|
+
strategy: "hybrid",
|
|
76
192
|
originalLines: content.split("\n").length,
|
|
77
|
-
compressedLines:
|
|
193
|
+
compressedLines: compressed.split("\n").length,
|
|
78
194
|
savings: 1 - compressed.length / content.length
|
|
79
195
|
}
|
|
80
196
|
};
|
|
@@ -82,32 +198,6 @@ var FileReadCompressor = class {
|
|
|
82
198
|
async decompress(compressed) {
|
|
83
199
|
return compressed.original;
|
|
84
200
|
}
|
|
85
|
-
extractSignatures(content, language) {
|
|
86
|
-
const signatures = [];
|
|
87
|
-
const lines = content.split("\n");
|
|
88
|
-
for (const line of lines) {
|
|
89
|
-
const trimmed = line.trim();
|
|
90
|
-
if (/^(export\s+)?(async\s+)?function\s+\w+/.test(trimmed)) {
|
|
91
|
-
signatures.push(trimmed.replace(/\{[\s\S]*$/, "{ ... }"));
|
|
92
|
-
}
|
|
93
|
-
if (/^(export\s+)?class\s+\w+/.test(trimmed)) {
|
|
94
|
-
signatures.push(trimmed);
|
|
95
|
-
}
|
|
96
|
-
if (/^(export\s+)?(type|interface)\s+\w+/.test(trimmed)) {
|
|
97
|
-
signatures.push(trimmed);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return signatures;
|
|
101
|
-
}
|
|
102
|
-
extractExports(content) {
|
|
103
|
-
const exports2 = [];
|
|
104
|
-
const exportRegex = /export\s+(default\s+)?(function|class|const|let|var|type|interface)\s+(\w+)/g;
|
|
105
|
-
let match;
|
|
106
|
-
while ((match = exportRegex.exec(content)) !== null) {
|
|
107
|
-
exports2.push(` - ${match[3]} (${match[2]})`);
|
|
108
|
-
}
|
|
109
|
-
return exports2;
|
|
110
|
-
}
|
|
111
201
|
};
|
|
112
202
|
|
|
113
203
|
// src/compress/grep.ts
|
|
@@ -164,18 +254,21 @@ var GrepCompressor = class {
|
|
|
164
254
|
var GitDiffCompressor = class {
|
|
165
255
|
async compress(input) {
|
|
166
256
|
const { diff } = input;
|
|
167
|
-
const
|
|
168
|
-
const condensed = hunks.map((hunk) => ({
|
|
169
|
-
file: hunk.file,
|
|
170
|
-
changes: this.condenseHunk(hunk),
|
|
171
|
-
stats: { additions: hunk.additions, deletions: hunk.deletions }
|
|
172
|
-
}));
|
|
257
|
+
const files = this.parseDiff(diff);
|
|
173
258
|
const lines = [];
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
259
|
+
const totalAdd = files.reduce((s, f) => s + f.additions, 0);
|
|
260
|
+
const totalDel = files.reduce((s, f) => s + f.deletions, 0);
|
|
261
|
+
lines.push(`# ${files.length} files changed: +${totalAdd} -${totalDel}`);
|
|
262
|
+
lines.push("");
|
|
263
|
+
for (const file of files) {
|
|
264
|
+
lines.push(`${file.path} (+${file.additions} -${file.deletions})`);
|
|
265
|
+
const changes = file.lines.filter((l) => l.type === "add" || l.type === "del").map((l) => `${l.type === "add" ? "+" : "-"}${l.content}`);
|
|
266
|
+
const limited = changes.slice(0, 20);
|
|
267
|
+
lines.push(...limited);
|
|
268
|
+
if (changes.length > 20) {
|
|
269
|
+
lines.push(`... [${changes.length - 20} more changes]`);
|
|
178
270
|
}
|
|
271
|
+
lines.push("");
|
|
179
272
|
}
|
|
180
273
|
const compressed = lines.join("\n");
|
|
181
274
|
return {
|
|
@@ -184,7 +277,7 @@ var GitDiffCompressor = class {
|
|
|
184
277
|
confidence: calculateConfidence(diff, compressed),
|
|
185
278
|
metadata: {
|
|
186
279
|
strategy: "condensed",
|
|
187
|
-
filesChanged:
|
|
280
|
+
filesChanged: files.length,
|
|
188
281
|
savings: 1 - compressed.length / diff.length
|
|
189
282
|
}
|
|
190
283
|
};
|
|
@@ -193,34 +286,123 @@ var GitDiffCompressor = class {
|
|
|
193
286
|
return compressed.original;
|
|
194
287
|
}
|
|
195
288
|
parseDiff(diff) {
|
|
196
|
-
const
|
|
289
|
+
const files = [];
|
|
197
290
|
const lines = diff.split("\n");
|
|
198
|
-
let
|
|
291
|
+
let current = null;
|
|
199
292
|
for (const line of lines) {
|
|
200
293
|
if (line.startsWith("diff --git")) {
|
|
201
|
-
if (
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
lines: [],
|
|
294
|
+
if (current) files.push(current);
|
|
295
|
+
const match = line.match(/b\/(.+)/);
|
|
296
|
+
current = {
|
|
297
|
+
path: match?.[1] || "unknown",
|
|
206
298
|
additions: 0,
|
|
207
|
-
deletions: 0
|
|
299
|
+
deletions: 0,
|
|
300
|
+
lines: []
|
|
208
301
|
};
|
|
209
|
-
} else if (
|
|
302
|
+
} else if (current) {
|
|
210
303
|
if (line.startsWith("+")) {
|
|
211
|
-
|
|
212
|
-
|
|
304
|
+
current.additions++;
|
|
305
|
+
current.lines.push({ type: "add", content: line.slice(1) });
|
|
213
306
|
} else if (line.startsWith("-")) {
|
|
214
|
-
|
|
215
|
-
|
|
307
|
+
current.deletions++;
|
|
308
|
+
current.lines.push({ type: "del", content: line.slice(1) });
|
|
216
309
|
}
|
|
217
310
|
}
|
|
218
311
|
}
|
|
219
|
-
if (
|
|
220
|
-
return
|
|
312
|
+
if (current) files.push(current);
|
|
313
|
+
return files;
|
|
221
314
|
}
|
|
222
|
-
|
|
223
|
-
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
// src/compress/git-status.ts
|
|
318
|
+
var GitStatusCompressor = class {
|
|
319
|
+
async compress(input) {
|
|
320
|
+
const { status } = input;
|
|
321
|
+
const statusLines = status.split("\n").filter(Boolean).length;
|
|
322
|
+
const tokens = Math.ceil(status.length / 4);
|
|
323
|
+
if (tokens < 10) {
|
|
324
|
+
return {
|
|
325
|
+
content: status,
|
|
326
|
+
original: status,
|
|
327
|
+
confidence: 1,
|
|
328
|
+
metadata: {
|
|
329
|
+
strategy: "passthrough",
|
|
330
|
+
totalFiles: statusLines,
|
|
331
|
+
savings: 0
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
const files = this.parseStatus(status);
|
|
336
|
+
const grouped = this.groupByStatus(files);
|
|
337
|
+
const lines = [];
|
|
338
|
+
for (const [statusType, statusFiles] of grouped) {
|
|
339
|
+
const label = this.statusLabel(statusType);
|
|
340
|
+
lines.push(`${label} (${statusFiles.length})`);
|
|
341
|
+
const compressed2 = this.compressPaths(statusFiles.map((f) => f.path));
|
|
342
|
+
lines.push(...compressed2);
|
|
343
|
+
lines.push("");
|
|
344
|
+
}
|
|
345
|
+
const compressed = lines.join("\n");
|
|
346
|
+
return {
|
|
347
|
+
content: compressed,
|
|
348
|
+
original: status,
|
|
349
|
+
confidence: calculateConfidence(status, compressed),
|
|
350
|
+
metadata: {
|
|
351
|
+
strategy: "grouped",
|
|
352
|
+
totalFiles: files.length,
|
|
353
|
+
savings: 1 - compressed.length / status.length
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
async decompress(compressed) {
|
|
358
|
+
return compressed.original;
|
|
359
|
+
}
|
|
360
|
+
parseStatus(status) {
|
|
361
|
+
return status.split("\n").filter(Boolean).map((line) => {
|
|
362
|
+
const match = line.match(/^(\?\?|[MADRC]+\s+)(.+)$/);
|
|
363
|
+
if (match) {
|
|
364
|
+
return { status: match[1].trim(), path: match[2] };
|
|
365
|
+
}
|
|
366
|
+
return { status: line[0], path: line.slice(3) };
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
groupByStatus(files) {
|
|
370
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
371
|
+
for (const file of files) {
|
|
372
|
+
const existing = grouped.get(file.status) || [];
|
|
373
|
+
existing.push(file);
|
|
374
|
+
grouped.set(file.status, existing);
|
|
375
|
+
}
|
|
376
|
+
return grouped;
|
|
377
|
+
}
|
|
378
|
+
statusLabel(status) {
|
|
379
|
+
const labels = {
|
|
380
|
+
"M": "Modified",
|
|
381
|
+
"A": "Added",
|
|
382
|
+
"D": "Deleted",
|
|
383
|
+
"??": "Untracked",
|
|
384
|
+
"R": "Renamed"
|
|
385
|
+
};
|
|
386
|
+
return labels[status] || `Status ${status}`;
|
|
387
|
+
}
|
|
388
|
+
compressPaths(paths) {
|
|
389
|
+
if (paths.length <= 3) return paths.map((p) => ` ${p}`);
|
|
390
|
+
const parts = paths.map((p) => p.split("/"));
|
|
391
|
+
const minLength = Math.min(...parts.map((p) => p.length));
|
|
392
|
+
let commonIndex = 0;
|
|
393
|
+
for (let i = 0; i < minLength; i++) {
|
|
394
|
+
if (parts.every((p) => p[i] === parts[0][i])) {
|
|
395
|
+
commonIndex = i;
|
|
396
|
+
} else {
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (commonIndex > 0) {
|
|
401
|
+
const prefix = parts[0].slice(0, commonIndex).join("/");
|
|
402
|
+
const suffixes = paths.map((p) => p.slice(prefix.length + 1));
|
|
403
|
+
return [` ${prefix}/`, ...suffixes.map((s) => ` ${s}`)];
|
|
404
|
+
}
|
|
405
|
+
return paths.map((p) => ` ${p}`);
|
|
224
406
|
}
|
|
225
407
|
};
|
|
226
408
|
|
|
@@ -232,7 +414,7 @@ var execAsync = (0, import_util.promisify)(import_child_process.exec);
|
|
|
232
414
|
var TOOLS = [
|
|
233
415
|
{
|
|
234
416
|
name: "make-laten-read",
|
|
235
|
-
description: "Read and compress a file (
|
|
417
|
+
description: "Read and compress a file (65-90% token savings)",
|
|
236
418
|
inputSchema: {
|
|
237
419
|
type: "object",
|
|
238
420
|
properties: {
|
|
@@ -331,9 +513,9 @@ async function handleGitDiff(params) {
|
|
|
331
513
|
}
|
|
332
514
|
async function handleGitStatus() {
|
|
333
515
|
const { stdout } = await execAsync("git status --porcelain");
|
|
334
|
-
const
|
|
335
|
-
const
|
|
336
|
-
return { content: [{ type: "text", text: JSON.stringify({
|
|
516
|
+
const compressor = new GitStatusCompressor();
|
|
517
|
+
const result = await compressor.compress({ status: stdout });
|
|
518
|
+
return { content: [{ type: "text", text: JSON.stringify({ compressed: result.content, savings: result.metadata.savings }) }] };
|
|
337
519
|
}
|
|
338
520
|
async function handleCacheStats() {
|
|
339
521
|
return { content: [{ type: "text", text: JSON.stringify({ message: "Cache stats \u2014 use CLI: make-laten cache stats" }) }] };
|
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/compress/confidence.ts","../../src/compress/file-read.ts","../../src/compress/grep.ts","../../src/compress/git-diff.ts","../../src/mcp/server.ts"],"sourcesContent":["export function calculateConfidence(original: string, compressed: string): number {\n if (!original.length) return 0\n\n let score = 1.0\n\n // Penalize if too much dropped\n const ratio = compressed.length / original.length\n if (ratio < 0.01) score -= 0.5\n else if (ratio < 0.05) score -= 0.3\n\n // Penalize if code blocks were modified\n if (codeBlocksModified(original, compressed)) score -= 0.4\n\n // Bonus for known patterns\n if (isKnownPattern(original)) score += 0.1\n\n return Math.max(0, Math.min(1, score))\n}\n\nfunction codeBlocksModified(original: string, compressed: string): boolean {\n const codeBlockRegex = /```[\\s\\S]*?```/g\n const originalBlocks = original.match(codeBlockRegex) || []\n const compressedBlocks = compressed.match(codeBlockRegex) || []\n\n if (originalBlocks.length !== compressedBlocks.length) return true\n\n for (let i = 0; i < originalBlocks.length; i++) {\n if (originalBlocks[i] !== compressedBlocks[i]) return true\n }\n\n return false\n}\n\nfunction isKnownPattern(content: string): boolean {\n const patterns = [\n /export\\s+(default\\s+)?(function|class|const|let|var)/,\n /import\\s+.*from\\s+['\"]/\n ]\n return patterns.some(p => p.test(content))\n}\n","import type { Compressor, CompressedResult, FileReadInput } from './types.js'\nimport { calculateConfidence } from './confidence.js'\n\nexport class FileReadCompressor implements Compressor {\n async compress(input: unknown): Promise<CompressedResult> {\n const { content, filePath, language } = input as FileReadInput\n \n const signatures = this.extractSignatures(content, language)\n const exports = this.extractExports(content)\n \n const lines = [\n `// ${filePath} (${content.split('\\n').length} lines)`,\n '',\n ...signatures,\n '',\n '// Exports:',\n ...exports\n ]\n \n const compressed = lines.join('\\n')\n \n return {\n content: compressed,\n original: content,\n confidence: calculateConfidence(content, compressed),\n metadata: {\n strategy: 'signatures',\n originalLines: content.split('\\n').length,\n compressedLines: lines.length,\n savings: 1 - (compressed.length / content.length)\n }\n }\n }\n\n async decompress(compressed: CompressedResult): Promise<unknown> {\n return compressed.original\n }\n\n private extractSignatures(content: string, language?: string): string[] {\n const signatures: string[] = []\n const lines = content.split('\\n')\n \n for (const line of lines) {\n const trimmed = line.trim()\n \n if (/^(export\\s+)?(async\\s+)?function\\s+\\w+/.test(trimmed)) {\n signatures.push(trimmed.replace(/\\{[\\s\\S]*$/, '{ ... }'))\n }\n \n if (/^(export\\s+)?class\\s+\\w+/.test(trimmed)) {\n signatures.push(trimmed)\n }\n \n if (/^(export\\s+)?(type|interface)\\s+\\w+/.test(trimmed)) {\n signatures.push(trimmed)\n }\n }\n \n return signatures\n }\n\n private extractExports(content: string): string[] {\n const exports: string[] = []\n const exportRegex = /export\\s+(default\\s+)?(function|class|const|let|var|type|interface)\\s+(\\w+)/g\n let match\n \n while ((match = exportRegex.exec(content)) !== null) {\n exports.push(` - ${match[3]} (${match[2]})`)\n }\n \n return exports\n }\n}\n","import type { Compressor, CompressedResult, GrepInput } from './types.js'\nimport { calculateConfidence } from './confidence.js'\n\nexport class GrepCompressor implements Compressor {\n async compress(input: unknown): Promise<CompressedResult> {\n const { results } = input as GrepInput\n \n // Group by file\n const grouped = this.groupByFile(results)\n \n // Format output\n const lines: string[] = []\n for (const [file, matches] of grouped) {\n lines.push(`${file} (${matches.length} matches)`)\n const unique = this.deduplicate(matches)\n for (const match of unique) {\n lines.push(` L${match.line}: ${match.content}`)\n }\n }\n \n const compressed = lines.join('\\n')\n const original = results.map(r => `${r.file}:${r.line}: ${r.content}`).join('\\n')\n \n return {\n content: compressed,\n original,\n confidence: calculateConfidence(original, compressed),\n metadata: {\n strategy: 'grouped',\n totalMatches: results.length,\n uniqueFiles: grouped.size,\n savings: 1 - (compressed.length / original.length)\n }\n }\n }\n\n async decompress(compressed: CompressedResult): Promise<unknown> {\n return compressed.original\n }\n\n private groupByFile(results: GrepInput['results']): Map<string, GrepInput['results']> {\n const grouped = new Map<string, GrepInput['results']>()\n \n for (const result of results) {\n const existing = grouped.get(result.file) || []\n existing.push(result)\n grouped.set(result.file, existing)\n }\n \n return grouped\n }\n\n private deduplicate(matches: GrepInput['results']): GrepInput['results'] {\n const seen = new Set<string>()\n return matches.filter(match => {\n const key = match.content.trim()\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n }\n}\n","import type { Compressor, CompressedResult, GitDiffInput } from './types.js'\nimport { calculateConfidence } from './confidence.js'\n\nexport class GitDiffCompressor implements Compressor {\n async compress(input: unknown): Promise<CompressedResult> {\n const { diff } = input as GitDiffInput\n \n // Parse diff into hunks\n const hunks = this.parseDiff(diff)\n \n // Condense each hunk\n const condensed = hunks.map(hunk => ({\n file: hunk.file,\n changes: this.condenseHunk(hunk),\n stats: { additions: hunk.additions, deletions: hunk.deletions }\n }))\n \n // Format output\n const lines: string[] = []\n for (const hunk of condensed) {\n if (hunk.changes.length > 0) {\n lines.push(`${hunk.file} (+${hunk.stats.additions} -${hunk.stats.deletions})`)\n lines.push(...hunk.changes)\n }\n }\n \n const compressed = lines.join('\\n')\n \n return {\n content: compressed,\n original: diff,\n confidence: calculateConfidence(diff, compressed),\n metadata: {\n strategy: 'condensed',\n filesChanged: condensed.length,\n savings: 1 - (compressed.length / diff.length)\n }\n }\n }\n\n async decompress(compressed: CompressedResult): Promise<unknown> {\n return compressed.original\n }\n\n private parseDiff(diff: string): Hunk[] {\n const hunks: Hunk[] = []\n const lines = diff.split('\\n')\n \n let currentHunk: Hunk | null = null\n \n for (const line of lines) {\n if (line.startsWith('diff --git')) {\n if (currentHunk) hunks.push(currentHunk)\n const fileMatch = line.match(/b\\/(.+)/)\n currentHunk = {\n file: fileMatch?.[1] || 'unknown',\n lines: [],\n additions: 0,\n deletions: 0\n }\n } else if (currentHunk) {\n if (line.startsWith('+')) {\n currentHunk.additions++\n currentHunk.lines.push({ type: 'addition', content: line.slice(1) })\n } else if (line.startsWith('-')) {\n currentHunk.deletions++\n currentHunk.lines.push({ type: 'deletion', content: line.slice(1) })\n }\n }\n }\n \n if (currentHunk) hunks.push(currentHunk)\n return hunks\n }\n\n private condenseHunk(hunk: Hunk): string[] {\n return hunk.lines\n .filter(l => l.type === 'addition' || l.type === 'deletion')\n .map(l => `${l.type === 'addition' ? '+' : '-'} ${l.content}`)\n }\n}\n\ninterface Hunk {\n file: string\n lines: { type: string; content: string }[]\n additions: number\n deletions: number\n}\n","#!/usr/bin/env node\n\nimport { FileReadCompressor } from '../compress/file-read.js'\nimport { GrepCompressor } from '../compress/grep.js'\nimport { GitDiffCompressor } from '../compress/git-diff.js'\nimport { exec } from 'child_process'\nimport { promisify } from 'util'\nimport fs from 'fs/promises'\n\nconst execAsync = promisify(exec)\n\nconst TOOLS = [\n {\n name: 'make-laten-read',\n description: 'Read and compress a file (60-90% token savings)',\n inputSchema: {\n type: 'object',\n properties: {\n file_path: { type: 'string', description: 'Path to file' }\n },\n required: ['file_path']\n }\n },\n {\n name: 'make-laten-grep',\n description: 'Search code and return compressed grouped results',\n inputSchema: {\n type: 'object',\n properties: {\n pattern: { type: 'string', description: 'Search pattern' },\n path: { type: 'string', description: 'Directory to search', default: '.' }\n },\n required: ['pattern']\n }\n },\n {\n name: 'make-laten-git-diff',\n description: 'Compressed git diff output',\n inputSchema: {\n type: 'object',\n properties: {\n staged: { type: 'boolean', description: 'Show staged changes', default: false }\n }\n }\n },\n {\n name: 'make-laten-git-status',\n description: 'Compressed git status',\n inputSchema: { type: 'object', properties: {} }\n },\n {\n name: 'make-laten-cache-stats',\n description: 'Show cache performance stats',\n inputSchema: { type: 'object', properties: {} }\n }\n]\n\nfunction detectLanguage(filePath: string): string {\n const ext = filePath.split('.').pop()?.toLowerCase() || ''\n const map: Record<string, string> = {\n ts: 'typescript', tsx: 'typescript', js: 'javascript', jsx: 'javascript',\n py: 'python', rs: 'rust', go: 'go', java: 'java', rb: 'ruby',\n json: 'json', yaml: 'yaml', yml: 'yaml', md: 'markdown'\n }\n return map[ext] || 'text'\n}\n\nasync function handleRead(params: { file_path: string }) {\n const content = await fs.readFile(params.file_path, 'utf-8')\n const compressor = new FileReadCompressor()\n const result = await compressor.compress({\n content,\n filePath: params.file_path,\n language: detectLanguage(params.file_path)\n })\n return {\n content: [{ type: 'text', text: JSON.stringify({ compressed: result.content, savings: result.metadata.savings, confidence: result.confidence }) }]\n }\n}\n\nasync function handleGrep(params: { pattern: string; path?: string }) {\n const dir = params.path || '.'\n const { stdout } = await execAsync(`grep -rn \"${params.pattern}\" ${dir} 2>/dev/null || true`, { maxBuffer: 10 * 1024 * 1024 })\n\n if (!stdout.trim()) {\n return { content: [{ type: 'text', text: JSON.stringify({ matches: [], total: 0 }) }] }\n }\n\n const matches = stdout.split('\\n').filter(Boolean).map(line => {\n const parts = line.split(':')\n return { file: parts[0], line: parseInt(parts[1], 10) || 0, content: parts.slice(2).join(':').trim() }\n })\n\n const compressor = new GrepCompressor()\n const result = await compressor.compress({ results: matches, pattern: params.pattern, directory: dir })\n\n return { content: [{ type: 'text', text: JSON.stringify({ compressed: result.content, total: matches.length, savings: result.metadata.savings }) }] }\n}\n\nasync function handleGitDiff(params: { staged?: boolean }) {\n const flag = params.staged ? '--staged' : ''\n const { stdout } = await execAsync(`git diff ${flag}`, { maxBuffer: 10 * 1024 * 1024 })\n\n if (!stdout.trim()) {\n return { content: [{ type: 'text', text: JSON.stringify({ diff: '', changes: 0 }) }] }\n }\n\n const compressor = new GitDiffCompressor()\n const result = await compressor.compress({ diff: stdout })\n\n return { content: [{ type: 'text', text: JSON.stringify({ compressed: result.content, savings: result.metadata.savings }) }] }\n}\n\nasync function handleGitStatus() {\n const { stdout } = await execAsync('git status --porcelain')\n const lines = stdout.split('\\n').filter(Boolean)\n const files = lines.map(l => ({ status: l[0], path: l.slice(3) }))\n return { content: [{ type: 'text', text: JSON.stringify({ total: files.length, files }) }] }\n}\n\nasync function handleCacheStats() {\n return { content: [{ type: 'text', text: JSON.stringify({ message: 'Cache stats — use CLI: make-laten cache stats' }) }] }\n}\n\nconst handlers: Record<string, (params: any) => Promise<any>> = {\n 'make-laten-read': handleRead,\n 'make-laten-grep': handleGrep,\n 'make-laten-git-diff': handleGitDiff,\n 'make-laten-git-status': handleGitStatus,\n 'make-laten-cache-stats': handleCacheStats\n}\n\nlet requestId = 0\n\nfunction sendResponse(id: number, result: any) {\n const response = { jsonrpc: '2.0', id, result }\n process.stdout.write(JSON.stringify(response) + '\\n')\n}\n\nfunction sendError(id: number, code: number, message: string) {\n const response = { jsonrpc: '2.0', id, error: { code, message } }\n process.stdout.write(JSON.stringify(response) + '\\n')\n}\n\nasync function handleLine(line: string) {\n try {\n const request = JSON.parse(line)\n\n if (request.method === 'initialize') {\n sendResponse(request.id, {\n protocolVersion: '2024-11-05',\n capabilities: { tools: {} },\n serverInfo: { name: 'make-laten', version: '1.0.0' }\n })\n } else if (request.method === 'notifications/initialized') {\n // no response needed\n } else if (request.method === 'tools/list') {\n sendResponse(request.id, { tools: TOOLS })\n } else if (request.method === 'tools/call') {\n const { name, arguments: params } = request.params\n const handler = handlers[name]\n\n if (!handler) {\n sendError(request.id, -32601, `Unknown tool: ${name}`)\n return\n }\n\n try {\n const result = await handler(params || {})\n sendResponse(request.id, result)\n } catch (error: any) {\n sendError(request.id, -32000, error.message)\n }\n } else {\n sendError(request.id, -32601, `Method not found: ${request.method}`)\n }\n } catch (error: any) {\n process.stderr.write(`Error: ${error.message}\\n`)\n }\n}\n\nlet buffer = ''\n\nprocess.stdin.setEncoding('utf-8')\nprocess.stdin.on('data', async (chunk: string) => {\n buffer += chunk\n const lines = buffer.split('\\n')\n buffer = lines.pop() || ''\n\n for (const line of lines) {\n if (line.trim()) {\n await handleLine(line.trim())\n }\n }\n})\n\nprocess.stderr.write('make-laten MCP server started\\n')\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAO,SAAS,oBAAoB,UAAkB,YAA4B;AAChF,MAAI,CAAC,SAAS,OAAQ,QAAO;AAE7B,MAAI,QAAQ;AAGZ,QAAM,QAAQ,WAAW,SAAS,SAAS;AAC3C,MAAI,QAAQ,KAAM,UAAS;AAAA,WAClB,QAAQ,KAAM,UAAS;AAGhC,MAAI,mBAAmB,UAAU,UAAU,EAAG,UAAS;AAGvD,MAAI,eAAe,QAAQ,EAAG,UAAS;AAEvC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AAEA,SAAS,mBAAmB,UAAkB,YAA6B;AACzE,QAAM,iBAAiB;AACvB,QAAM,iBAAiB,SAAS,MAAM,cAAc,KAAK,CAAC;AAC1D,QAAM,mBAAmB,WAAW,MAAM,cAAc,KAAK,CAAC;AAE9D,MAAI,eAAe,WAAW,iBAAiB,OAAQ,QAAO;AAE9D,WAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;AAC9C,QAAI,eAAe,CAAC,MAAM,iBAAiB,CAAC,EAAG,QAAO;AAAA,EACxD;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,SAA0B;AAChD,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,EACF;AACA,SAAO,SAAS,KAAK,OAAK,EAAE,KAAK,OAAO,CAAC;AAC3C;;;ACpCO,IAAM,qBAAN,MAA+C;AAAA,EACpD,MAAM,SAAS,OAA2C;AACxD,UAAM,EAAE,SAAS,UAAU,SAAS,IAAI;AAExC,UAAM,aAAa,KAAK,kBAAkB,SAAS,QAAQ;AAC3D,UAAMA,WAAU,KAAK,eAAe,OAAO;AAE3C,UAAM,QAAQ;AAAA,MACZ,MAAM,QAAQ,KAAK,QAAQ,MAAM,IAAI,EAAE,MAAM;AAAA,MAC7C;AAAA,MACA,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA,GAAGA;AAAA,IACL;AAEA,UAAM,aAAa,MAAM,KAAK,IAAI;AAElC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA,MACV,YAAY,oBAAoB,SAAS,UAAU;AAAA,MACnD,UAAU;AAAA,QACR,UAAU;AAAA,QACV,eAAe,QAAQ,MAAM,IAAI,EAAE;AAAA,QACnC,iBAAiB,MAAM;AAAA,QACvB,SAAS,IAAK,WAAW,SAAS,QAAQ;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,YAAgD;AAC/D,WAAO,WAAW;AAAA,EACpB;AAAA,EAEQ,kBAAkB,SAAiB,UAA6B;AACtE,UAAM,aAAuB,CAAC;AAC9B,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAEhC,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,KAAK;AAE1B,UAAI,yCAAyC,KAAK,OAAO,GAAG;AAC1D,mBAAW,KAAK,QAAQ,QAAQ,cAAc,SAAS,CAAC;AAAA,MAC1D;AAEA,UAAI,2BAA2B,KAAK,OAAO,GAAG;AAC5C,mBAAW,KAAK,OAAO;AAAA,MACzB;AAEA,UAAI,sCAAsC,KAAK,OAAO,GAAG;AACvD,mBAAW,KAAK,OAAO;AAAA,MACzB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,eAAe,SAA2B;AAChD,UAAMA,WAAoB,CAAC;AAC3B,UAAM,cAAc;AACpB,QAAI;AAEJ,YAAQ,QAAQ,YAAY,KAAK,OAAO,OAAO,MAAM;AACnD,MAAAA,SAAQ,KAAK,OAAO,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,GAAG;AAAA,IAC9C;AAEA,WAAOA;AAAA,EACT;AACF;;;ACrEO,IAAM,iBAAN,MAA2C;AAAA,EAChD,MAAM,SAAS,OAA2C;AACxD,UAAM,EAAE,QAAQ,IAAI;AAGpB,UAAM,UAAU,KAAK,YAAY,OAAO;AAGxC,UAAM,QAAkB,CAAC;AACzB,eAAW,CAAC,MAAM,OAAO,KAAK,SAAS;AACrC,YAAM,KAAK,GAAG,IAAI,KAAK,QAAQ,MAAM,WAAW;AAChD,YAAM,SAAS,KAAK,YAAY,OAAO;AACvC,iBAAW,SAAS,QAAQ;AAC1B,cAAM,KAAK,MAAM,MAAM,IAAI,KAAK,MAAM,OAAO,EAAE;AAAA,MACjD;AAAA,IACF;AAEA,UAAM,aAAa,MAAM,KAAK,IAAI;AAClC,UAAM,WAAW,QAAQ,IAAI,OAAK,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI;AAEhF,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,YAAY,oBAAoB,UAAU,UAAU;AAAA,MACpD,UAAU;AAAA,QACR,UAAU;AAAA,QACV,cAAc,QAAQ;AAAA,QACtB,aAAa,QAAQ;AAAA,QACrB,SAAS,IAAK,WAAW,SAAS,SAAS;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,YAAgD;AAC/D,WAAO,WAAW;AAAA,EACpB;AAAA,EAEQ,YAAY,SAAkE;AACpF,UAAM,UAAU,oBAAI,IAAkC;AAEtD,eAAW,UAAU,SAAS;AAC5B,YAAM,WAAW,QAAQ,IAAI,OAAO,IAAI,KAAK,CAAC;AAC9C,eAAS,KAAK,MAAM;AACpB,cAAQ,IAAI,OAAO,MAAM,QAAQ;AAAA,IACnC;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,YAAY,SAAqD;AACvE,UAAM,OAAO,oBAAI,IAAY;AAC7B,WAAO,QAAQ,OAAO,WAAS;AAC7B,YAAM,MAAM,MAAM,QAAQ,KAAK;AAC/B,UAAI,KAAK,IAAI,GAAG,EAAG,QAAO;AAC1B,WAAK,IAAI,GAAG;AACZ,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;;;AC1DO,IAAM,oBAAN,MAA8C;AAAA,EACnD,MAAM,SAAS,OAA2C;AACxD,UAAM,EAAE,KAAK,IAAI;AAGjB,UAAM,QAAQ,KAAK,UAAU,IAAI;AAGjC,UAAM,YAAY,MAAM,IAAI,WAAS;AAAA,MACnC,MAAM,KAAK;AAAA,MACX,SAAS,KAAK,aAAa,IAAI;AAAA,MAC/B,OAAO,EAAE,WAAW,KAAK,WAAW,WAAW,KAAK,UAAU;AAAA,IAChE,EAAE;AAGF,UAAM,QAAkB,CAAC;AACzB,eAAW,QAAQ,WAAW;AAC5B,UAAI,KAAK,QAAQ,SAAS,GAAG;AAC3B,cAAM,KAAK,GAAG,KAAK,IAAI,MAAM,KAAK,MAAM,SAAS,KAAK,KAAK,MAAM,SAAS,GAAG;AAC7E,cAAM,KAAK,GAAG,KAAK,OAAO;AAAA,MAC5B;AAAA,IACF;AAEA,UAAM,aAAa,MAAM,KAAK,IAAI;AAElC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA,MACV,YAAY,oBAAoB,MAAM,UAAU;AAAA,MAChD,UAAU;AAAA,QACR,UAAU;AAAA,QACV,cAAc,UAAU;AAAA,QACxB,SAAS,IAAK,WAAW,SAAS,KAAK;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,YAAgD;AAC/D,WAAO,WAAW;AAAA,EACpB;AAAA,EAEQ,UAAU,MAAsB;AACtC,UAAM,QAAgB,CAAC;AACvB,UAAM,QAAQ,KAAK,MAAM,IAAI;AAE7B,QAAI,cAA2B;AAE/B,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,WAAW,YAAY,GAAG;AACjC,YAAI,YAAa,OAAM,KAAK,WAAW;AACvC,cAAM,YAAY,KAAK,MAAM,SAAS;AACtC,sBAAc;AAAA,UACZ,MAAM,YAAY,CAAC,KAAK;AAAA,UACxB,OAAO,CAAC;AAAA,UACR,WAAW;AAAA,UACX,WAAW;AAAA,QACb;AAAA,MACF,WAAW,aAAa;AACtB,YAAI,KAAK,WAAW,GAAG,GAAG;AACxB,sBAAY;AACZ,sBAAY,MAAM,KAAK,EAAE,MAAM,YAAY,SAAS,KAAK,MAAM,CAAC,EAAE,CAAC;AAAA,QACrE,WAAW,KAAK,WAAW,GAAG,GAAG;AAC/B,sBAAY;AACZ,sBAAY,MAAM,KAAK,EAAE,MAAM,YAAY,SAAS,KAAK,MAAM,CAAC,EAAE,CAAC;AAAA,QACrE;AAAA,MACF;AAAA,IACF;AAEA,QAAI,YAAa,OAAM,KAAK,WAAW;AACvC,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,MAAsB;AACzC,WAAO,KAAK,MACT,OAAO,OAAK,EAAE,SAAS,cAAc,EAAE,SAAS,UAAU,EAC1D,IAAI,OAAK,GAAG,EAAE,SAAS,aAAa,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE;AAAA,EACjE;AACF;;;AC3EA,2BAAqB;AACrB,kBAA0B;AAC1B,sBAAe;AAEf,IAAM,gBAAY,uBAAU,yBAAI;AAEhC,IAAM,QAAQ;AAAA,EACZ;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,WAAW,EAAE,MAAM,UAAU,aAAa,eAAe;AAAA,MAC3D;AAAA,MACA,UAAU,CAAC,WAAW;AAAA,IACxB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,iBAAiB;AAAA,QACzD,MAAM,EAAE,MAAM,UAAU,aAAa,uBAAuB,SAAS,IAAI;AAAA,MAC3E;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,QAAQ,EAAE,MAAM,WAAW,aAAa,uBAAuB,SAAS,MAAM;AAAA,MAChF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,CAAC,EAAE;AAAA,EAChD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,CAAC,EAAE;AAAA,EAChD;AACF;AAEA,SAAS,eAAe,UAA0B;AAChD,QAAM,MAAM,SAAS,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY,KAAK;AACxD,QAAM,MAA8B;AAAA,IAClC,IAAI;AAAA,IAAc,KAAK;AAAA,IAAc,IAAI;AAAA,IAAc,KAAK;AAAA,IAC5D,IAAI;AAAA,IAAU,IAAI;AAAA,IAAQ,IAAI;AAAA,IAAM,MAAM;AAAA,IAAQ,IAAI;AAAA,IACtD,MAAM;AAAA,IAAQ,MAAM;AAAA,IAAQ,KAAK;AAAA,IAAQ,IAAI;AAAA,EAC/C;AACA,SAAO,IAAI,GAAG,KAAK;AACrB;AAEA,eAAe,WAAW,QAA+B;AACvD,QAAM,UAAU,MAAM,gBAAAC,QAAG,SAAS,OAAO,WAAW,OAAO;AAC3D,QAAM,aAAa,IAAI,mBAAmB;AAC1C,QAAM,SAAS,MAAM,WAAW,SAAS;AAAA,IACvC;AAAA,IACA,UAAU,OAAO;AAAA,IACjB,UAAU,eAAe,OAAO,SAAS;AAAA,EAC3C,CAAC;AACD,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,EAAE,YAAY,OAAO,SAAS,SAAS,OAAO,SAAS,SAAS,YAAY,OAAO,WAAW,CAAC,EAAE,CAAC;AAAA,EACnJ;AACF;AAEA,eAAe,WAAW,QAA4C;AACpE,QAAM,MAAM,OAAO,QAAQ;AAC3B,QAAM,EAAE,OAAO,IAAI,MAAM,UAAU,aAAa,OAAO,OAAO,KAAK,GAAG,wBAAwB,EAAE,WAAW,KAAK,OAAO,KAAK,CAAC;AAE7H,MAAI,CAAC,OAAO,KAAK,GAAG;AAClB,WAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,EAAE,SAAS,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE;AAAA,EACxF;AAEA,QAAM,UAAU,OAAO,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE,IAAI,UAAQ;AAC7D,UAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,WAAO,EAAE,MAAM,MAAM,CAAC,GAAG,MAAM,SAAS,MAAM,CAAC,GAAG,EAAE,KAAK,GAAG,SAAS,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,KAAK,EAAE;AAAA,EACvG,CAAC;AAED,QAAM,aAAa,IAAI,eAAe;AACtC,QAAM,SAAS,MAAM,WAAW,SAAS,EAAE,SAAS,SAAS,SAAS,OAAO,SAAS,WAAW,IAAI,CAAC;AAEtG,SAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,EAAE,YAAY,OAAO,SAAS,OAAO,QAAQ,QAAQ,SAAS,OAAO,SAAS,QAAQ,CAAC,EAAE,CAAC,EAAE;AACtJ;AAEA,eAAe,cAAc,QAA8B;AACzD,QAAM,OAAO,OAAO,SAAS,aAAa;AAC1C,QAAM,EAAE,OAAO,IAAI,MAAM,UAAU,YAAY,IAAI,IAAI,EAAE,WAAW,KAAK,OAAO,KAAK,CAAC;AAEtF,MAAI,CAAC,OAAO,KAAK,GAAG;AAClB,WAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,EAAE,MAAM,IAAI,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE;AAAA,EACvF;AAEA,QAAM,aAAa,IAAI,kBAAkB;AACzC,QAAM,SAAS,MAAM,WAAW,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzD,SAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,EAAE,YAAY,OAAO,SAAS,SAAS,OAAO,SAAS,QAAQ,CAAC,EAAE,CAAC,EAAE;AAC/H;AAEA,eAAe,kBAAkB;AAC/B,QAAM,EAAE,OAAO,IAAI,MAAM,UAAU,wBAAwB;AAC3D,QAAM,QAAQ,OAAO,MAAM,IAAI,EAAE,OAAO,OAAO;AAC/C,QAAM,QAAQ,MAAM,IAAI,QAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE;AACjE,SAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,EAAE,OAAO,MAAM,QAAQ,MAAM,CAAC,EAAE,CAAC,EAAE;AAC7F;AAEA,eAAe,mBAAmB;AAChC,SAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,EAAE,SAAS,qDAAgD,CAAC,EAAE,CAAC,EAAE;AAC3H;AAEA,IAAM,WAA0D;AAAA,EAC9D,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,0BAA0B;AAC5B;AAIA,SAAS,aAAa,IAAY,QAAa;AAC7C,QAAM,WAAW,EAAE,SAAS,OAAO,IAAI,OAAO;AAC9C,UAAQ,OAAO,MAAM,KAAK,UAAU,QAAQ,IAAI,IAAI;AACtD;AAEA,SAAS,UAAU,IAAY,MAAc,SAAiB;AAC5D,QAAM,WAAW,EAAE,SAAS,OAAO,IAAI,OAAO,EAAE,MAAM,QAAQ,EAAE;AAChE,UAAQ,OAAO,MAAM,KAAK,UAAU,QAAQ,IAAI,IAAI;AACtD;AAEA,eAAe,WAAW,MAAc;AACtC,MAAI;AACF,UAAM,UAAU,KAAK,MAAM,IAAI;AAE/B,QAAI,QAAQ,WAAW,cAAc;AACnC,mBAAa,QAAQ,IAAI;AAAA,QACvB,iBAAiB;AAAA,QACjB,cAAc,EAAE,OAAO,CAAC,EAAE;AAAA,QAC1B,YAAY,EAAE,MAAM,cAAc,SAAS,QAAQ;AAAA,MACrD,CAAC;AAAA,IACH,WAAW,QAAQ,WAAW,6BAA6B;AAAA,IAE3D,WAAW,QAAQ,WAAW,cAAc;AAC1C,mBAAa,QAAQ,IAAI,EAAE,OAAO,MAAM,CAAC;AAAA,IAC3C,WAAW,QAAQ,WAAW,cAAc;AAC1C,YAAM,EAAE,MAAM,WAAW,OAAO,IAAI,QAAQ;AAC5C,YAAM,UAAU,SAAS,IAAI;AAE7B,UAAI,CAAC,SAAS;AACZ,kBAAU,QAAQ,IAAI,QAAQ,iBAAiB,IAAI,EAAE;AACrD;AAAA,MACF;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,QAAQ,UAAU,CAAC,CAAC;AACzC,qBAAa,QAAQ,IAAI,MAAM;AAAA,MACjC,SAAS,OAAY;AACnB,kBAAU,QAAQ,IAAI,OAAQ,MAAM,OAAO;AAAA,MAC7C;AAAA,IACF,OAAO;AACL,gBAAU,QAAQ,IAAI,QAAQ,qBAAqB,QAAQ,MAAM,EAAE;AAAA,IACrE;AAAA,EACF,SAAS,OAAY;AACnB,YAAQ,OAAO,MAAM,UAAU,MAAM,OAAO;AAAA,CAAI;AAAA,EAClD;AACF;AAEA,IAAI,SAAS;AAEb,QAAQ,MAAM,YAAY,OAAO;AACjC,QAAQ,MAAM,GAAG,QAAQ,OAAO,UAAkB;AAChD,YAAU;AACV,QAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,WAAS,MAAM,IAAI,KAAK;AAExB,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,KAAK,GAAG;AACf,YAAM,WAAW,KAAK,KAAK,CAAC;AAAA,IAC9B;AAAA,EACF;AACF,CAAC;AAED,QAAQ,OAAO,MAAM,iCAAiC;","names":["exports","fs"]}
|
|
1
|
+
{"version":3,"sources":["../../src/compress/confidence.ts","../../src/compress/strip.ts","../../src/compress/structure.ts","../../src/compress/truncate.ts","../../src/compress/file-read.ts","../../src/compress/grep.ts","../../src/compress/git-diff.ts","../../src/compress/git-status.ts","../../src/mcp/server.ts"],"sourcesContent":["export function calculateConfidence(original: string, compressed: string): number {\n if (!original.length) return 0\n\n let score = 1.0\n\n // Penalize if too much dropped\n const ratio = compressed.length / original.length\n if (ratio < 0.01) score -= 0.5\n else if (ratio < 0.05) score -= 0.3\n\n // Penalize if code blocks were modified\n if (codeBlocksModified(original, compressed)) score -= 0.4\n\n // Bonus for known patterns\n if (isKnownPattern(original)) score += 0.1\n\n return Math.max(0, Math.min(1, score))\n}\n\nfunction codeBlocksModified(original: string, compressed: string): boolean {\n const codeBlockRegex = /```[\\s\\S]*?```/g\n const originalBlocks = original.match(codeBlockRegex) || []\n const compressedBlocks = compressed.match(codeBlockRegex) || []\n\n if (originalBlocks.length !== compressedBlocks.length) return true\n\n for (let i = 0; i < originalBlocks.length; i++) {\n if (originalBlocks[i] !== compressedBlocks[i]) return true\n }\n\n return false\n}\n\nfunction isKnownPattern(content: string): boolean {\n const patterns = [\n /export\\s+(default\\s+)?(function|class|const|let|var)/,\n /import\\s+.*from\\s+['\"]/\n ]\n return patterns.some(p => p.test(content))\n}\n","export function stripImports(content: string): string {\n return content\n .replace(/^import\\s+[\\s\\S]*?from\\s+['\"][^'\"]+['\"]\\s*;?\\s*$/gm, '')\n .replace(/^import\\s+['\"][^'\"]+['\"]\\s*;?\\s*$/gm, '')\n .replace(/^import\\s+\\{[^}]*\\}\\s+from\\s+['\"][^'\"]+['\"]\\s*;?\\s*$/gm, '')\n .split('\\n')\n .filter(l => l.trim() !== '')\n .join('\\n')\n}\n\nexport function stripComments(content: string): string {\n let result = content.replace(/(?<![\"'`])\\/\\/.*$/gm, '')\n result = result.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n return result\n .split('\\n')\n .filter(l => l.trim() !== '')\n .join('\\n')\n}\n\nexport function stripBlankLines(content: string): string {\n return content.replace(/\\n{3,}/g, '\\n\\n')\n}\n\nexport function stripWhitespace(content: string): string {\n return content.replace(/[ \\t]+$/gm, '')\n}\n\nexport function stripAll(content: string): string {\n let result = content\n result = stripImports(result)\n result = stripComments(result)\n result = stripBlankLines(result)\n result = stripWhitespace(result)\n return result.trim()\n}\n","export function extractExports(content: string): string {\n const lines = content.split('\\n')\n const exports: string[] = []\n\n for (const line of lines) {\n const trimmed = line.trim()\n if (/^export\\s+(default\\s+)?/.test(trimmed)) {\n if (trimmed.includes('{') && !trimmed.includes('}')) {\n exports.push(trimmed.replace(/\\{[\\s\\S]*$/, '{ ... }'))\n } else {\n exports.push(trimmed)\n }\n }\n }\n\n return exports.join('\\n')\n}\n\nexport function extractClassMethods(content: string): string {\n const classRegex = /class\\s+\\w+[^{]*\\{([\\s\\S]*?)\\n\\}/g\n const methods: string[] = []\n\n let match\n while ((match = classRegex.exec(content)) !== null) {\n const classBody = match[1]\n const methodRegex = /(^\\s*(?:public|private|protected|static|async|abstract|\\s)*\\w+\\s*\\([^)]*\\)(?:\\s*:\\s*[^{]+)?)\\s*\\{/gm\n\n let methodMatch\n while ((methodMatch = methodRegex.exec(classBody)) !== null) {\n methods.push(methodMatch[1].trim())\n }\n }\n\n return methods.join('\\n')\n}\n\nexport function extractFunctionSignatures(content: string): string {\n const funcRegex = /(export\\s+)?(async\\s+)?function\\s+\\w+\\s*\\([^)]*\\)(?:\\s*:\\s*[^{]+)?\\s*\\{/g\n const signatures: string[] = []\n\n let match\n while ((match = funcRegex.exec(content)) !== null) {\n signatures.push(match[0].replace(/\\{$/, ''))\n }\n\n return signatures.join('\\n')\n}\n\nexport function extractTypeDefinitions(content: string): string {\n const typeRegex = /(export\\s+)?(interface|type)\\s+\\w+[^{]*\\{[^}]*\\}|(export\\s+)?type\\s+\\w+\\s*=[^;]+;?/g\n const types: string[] = []\n\n let match\n while ((match = typeRegex.exec(content)) !== null) {\n types.push(match[0].trim())\n }\n\n return types.join('\\n')\n}\n","export function smartTruncate(content: string, maxTokens: number): string {\n const lines = content.split('\\n')\n const estimatedTokens = Math.ceil(content.length / 4)\n\n if (estimatedTokens <= maxTokens) return content\n\n const targetLines = Math.round(maxTokens * 4 / (content.length / lines.length))\n const headerLines = Math.floor(targetLines * 0.3)\n const footerLines = Math.floor(targetLines * 0.3)\n const omitted = lines.length - headerLines - footerLines\n\n const header = lines.slice(0, headerLines)\n const footer = lines.slice(-footerLines)\n\n return [...header, `\\n... [${omitted} lines omitted] ...\\n`, ...footer].join('\\n')\n}\n\nexport function truncateByTokens(text: string, maxTokens: number): string {\n const maxChars = maxTokens * 4\n if (text.length <= maxChars) return text\n\n const truncated = text.slice(0, maxChars)\n const lastNewline = truncated.lastIndexOf('\\n')\n\n return truncated.slice(0, lastNewline > 0 ? lastNewline : maxChars) + '\\n\\n... (truncated)'\n}\n\nexport function preserveContext(lines: string[], targetIndex: number, before: number, after: number): string[] {\n const start = Math.max(0, targetIndex - before)\n const end = Math.min(lines.length, targetIndex + after + 1)\n return lines.slice(start, end)\n}\n","import type { Compressor, CompressedResult, FileReadInput } from './types.js'\nimport { calculateConfidence } from './confidence.js'\nimport { stripAll } from './strip.js'\nimport { extractExports, extractClassMethods, extractFunctionSignatures, extractTypeDefinitions } from './structure.js'\nimport { smartTruncate } from './truncate.js'\n\nexport class FileReadCompressor implements Compressor {\n async compress(input: unknown): Promise<CompressedResult> {\n const { content, filePath, language } = input as FileReadInput\n\n const lines = content.split('\\n').length\n const tokens = Math.ceil(content.length / 4)\n\n if (tokens < 200) {\n return {\n content: content,\n original: content,\n confidence: 1.0,\n metadata: {\n strategy: 'passthrough',\n originalLines: lines,\n compressedLines: lines,\n savings: 0\n }\n }\n }\n\n const stripped = stripAll(content)\n\n const exports = extractExports(stripped)\n const classes = extractClassMethods(stripped)\n const functions = extractFunctionSignatures(stripped)\n const types = extractTypeDefinitions(stripped)\n\n const sections = [\n `// ${filePath} (${content.split('\\n').length} lines)`,\n '',\n '// Exports:',\n exports,\n '',\n '// Classes:',\n classes,\n '',\n '// Functions:',\n functions,\n '',\n '// Types:',\n types\n ].filter(l => l !== '' && !l.endsWith(':'))\n\n let compressed = sections.join('\\n')\n\n const maxTokens = 2000\n compressed = smartTruncate(compressed, maxTokens)\n\n return {\n content: compressed,\n original: content,\n confidence: calculateConfidence(content, compressed),\n metadata: {\n strategy: 'hybrid',\n originalLines: content.split('\\n').length,\n compressedLines: compressed.split('\\n').length,\n savings: 1 - (compressed.length / content.length)\n }\n }\n }\n\n async decompress(compressed: CompressedResult): Promise<unknown> {\n return compressed.original\n }\n}\n","import type { Compressor, CompressedResult, GrepInput } from './types.js'\nimport { calculateConfidence } from './confidence.js'\n\nexport class GrepCompressor implements Compressor {\n async compress(input: unknown): Promise<CompressedResult> {\n const { results } = input as GrepInput\n \n // Group by file\n const grouped = this.groupByFile(results)\n \n // Format output\n const lines: string[] = []\n for (const [file, matches] of grouped) {\n lines.push(`${file} (${matches.length} matches)`)\n const unique = this.deduplicate(matches)\n for (const match of unique) {\n lines.push(` L${match.line}: ${match.content}`)\n }\n }\n \n const compressed = lines.join('\\n')\n const original = results.map(r => `${r.file}:${r.line}: ${r.content}`).join('\\n')\n \n return {\n content: compressed,\n original,\n confidence: calculateConfidence(original, compressed),\n metadata: {\n strategy: 'grouped',\n totalMatches: results.length,\n uniqueFiles: grouped.size,\n savings: 1 - (compressed.length / original.length)\n }\n }\n }\n\n async decompress(compressed: CompressedResult): Promise<unknown> {\n return compressed.original\n }\n\n private groupByFile(results: GrepInput['results']): Map<string, GrepInput['results']> {\n const grouped = new Map<string, GrepInput['results']>()\n \n for (const result of results) {\n const existing = grouped.get(result.file) || []\n existing.push(result)\n grouped.set(result.file, existing)\n }\n \n return grouped\n }\n\n private deduplicate(matches: GrepInput['results']): GrepInput['results'] {\n const seen = new Set<string>()\n return matches.filter(match => {\n const key = match.content.trim()\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n }\n}\n","import type { Compressor, CompressedResult, GitDiffInput } from './types.js'\nimport { calculateConfidence } from './confidence.js'\n\nexport class GitDiffCompressor implements Compressor {\n async compress(input: unknown): Promise<CompressedResult> {\n const { diff } = input as GitDiffInput\n\n const files = this.parseDiff(diff)\n\n const lines: string[] = []\n\n const totalAdd = files.reduce((s, f) => s + f.additions, 0)\n const totalDel = files.reduce((s, f) => s + f.deletions, 0)\n lines.push(`# ${files.length} files changed: +${totalAdd} -${totalDel}`)\n lines.push('')\n\n for (const file of files) {\n lines.push(`${file.path} (+${file.additions} -${file.deletions})`)\n\n const changes = file.lines\n .filter(l => l.type === 'add' || l.type === 'del')\n .map(l => `${l.type === 'add' ? '+' : '-'}${l.content}`)\n\n const limited = changes.slice(0, 20)\n lines.push(...limited)\n\n if (changes.length > 20) {\n lines.push(`... [${changes.length - 20} more changes]`)\n }\n\n lines.push('')\n }\n\n const compressed = lines.join('\\n')\n\n return {\n content: compressed,\n original: diff,\n confidence: calculateConfidence(diff, compressed),\n metadata: {\n strategy: 'condensed',\n filesChanged: files.length,\n savings: 1 - (compressed.length / diff.length)\n }\n }\n }\n\n async decompress(compressed: CompressedResult): Promise<unknown> {\n return compressed.original\n }\n\n private parseDiff(diff: string): FileDiff[] {\n const files: FileDiff[] = []\n const lines = diff.split('\\n')\n\n let current: FileDiff | null = null\n\n for (const line of lines) {\n if (line.startsWith('diff --git')) {\n if (current) files.push(current)\n const match = line.match(/b\\/(.+)/)\n current = {\n path: match?.[1] || 'unknown',\n additions: 0,\n deletions: 0,\n lines: []\n }\n } else if (current) {\n if (line.startsWith('+')) {\n current.additions++\n current.lines.push({ type: 'add', content: line.slice(1) })\n } else if (line.startsWith('-')) {\n current.deletions++\n current.lines.push({ type: 'del', content: line.slice(1) })\n }\n }\n }\n\n if (current) files.push(current)\n return files\n }\n}\n\ninterface FileDiff {\n path: string\n additions: number\n deletions: number\n lines: { type: string; content: string }[]\n}\n","import type { Compressor, CompressedResult } from './types.js'\nimport { calculateConfidence } from './confidence.js'\n\nexport class GitStatusCompressor implements Compressor {\n async compress(input: unknown): Promise<CompressedResult> {\n const { status } = input as { status: string }\n\n const statusLines = status.split('\\n').filter(Boolean).length\n const tokens = Math.ceil(status.length / 4)\n\n if (tokens < 10) {\n return {\n content: status,\n original: status,\n confidence: 1.0,\n metadata: {\n strategy: 'passthrough',\n totalFiles: statusLines,\n savings: 0\n }\n }\n }\n\n const files = this.parseStatus(status)\n const grouped = this.groupByStatus(files)\n\n const lines: string[] = []\n\n for (const [statusType, statusFiles] of grouped) {\n const label = this.statusLabel(statusType)\n lines.push(`${label} (${statusFiles.length})`)\n\n const compressed = this.compressPaths(statusFiles.map(f => f.path))\n lines.push(...compressed)\n lines.push('')\n }\n\n const compressed = lines.join('\\n')\n\n return {\n content: compressed,\n original: status,\n confidence: calculateConfidence(status, compressed),\n metadata: {\n strategy: 'grouped',\n totalFiles: files.length,\n savings: 1 - (compressed.length / status.length)\n }\n }\n }\n\n async decompress(compressed: CompressedResult): Promise<unknown> {\n return compressed.original\n }\n\n private parseStatus(status: string): { status: string; path: string }[] {\n return status.split('\\n')\n .filter(Boolean)\n .map(line => {\n const match = line.match(/^(\\?\\?|[MADRC]+\\s+)(.+)$/)\n if (match) {\n return { status: match[1].trim(), path: match[2] }\n }\n return { status: line[0], path: line.slice(3) }\n })\n }\n\n private groupByStatus(files: { status: string; path: string }[]): Map<string, { status: string; path: string }[]> {\n const grouped = new Map<string, { status: string; path: string }[]>()\n\n for (const file of files) {\n const existing = grouped.get(file.status) || []\n existing.push(file)\n grouped.set(file.status, existing)\n }\n\n return grouped\n }\n\n private statusLabel(status: string): string {\n const labels: Record<string, string> = {\n 'M': 'Modified',\n 'A': 'Added',\n 'D': 'Deleted',\n '??': 'Untracked',\n 'R': 'Renamed'\n }\n return labels[status] || `Status ${status}`\n }\n\n private compressPaths(paths: string[]): string[] {\n if (paths.length <= 3) return paths.map(p => ` ${p}`)\n\n const parts = paths.map(p => p.split('/'))\n const minLength = Math.min(...parts.map(p => p.length))\n\n let commonIndex = 0\n for (let i = 0; i < minLength; i++) {\n if (parts.every(p => p[i] === parts[0][i])) {\n commonIndex = i\n } else {\n break\n }\n }\n\n if (commonIndex > 0) {\n const prefix = parts[0].slice(0, commonIndex).join('/')\n const suffixes = paths.map(p => p.slice(prefix.length + 1))\n return [` ${prefix}/`, ...suffixes.map(s => ` ${s}`)]\n }\n\n return paths.map(p => ` ${p}`)\n }\n}\n","#!/usr/bin/env node\n\nimport { FileReadCompressor } from '../compress/file-read.js'\nimport { GrepCompressor } from '../compress/grep.js'\nimport { GitDiffCompressor } from '../compress/git-diff.js'\nimport { GitStatusCompressor } from '../compress/git-status.js'\nimport { exec } from 'child_process'\nimport { promisify } from 'util'\nimport fs from 'fs/promises'\n\nconst execAsync = promisify(exec)\n\nconst TOOLS = [\n {\n name: 'make-laten-read',\n description: 'Read and compress a file (65-90% token savings)',\n inputSchema: {\n type: 'object',\n properties: {\n file_path: { type: 'string', description: 'Path to file' }\n },\n required: ['file_path']\n }\n },\n {\n name: 'make-laten-grep',\n description: 'Search code and return compressed grouped results',\n inputSchema: {\n type: 'object',\n properties: {\n pattern: { type: 'string', description: 'Search pattern' },\n path: { type: 'string', description: 'Directory to search', default: '.' }\n },\n required: ['pattern']\n }\n },\n {\n name: 'make-laten-git-diff',\n description: 'Compressed git diff output',\n inputSchema: {\n type: 'object',\n properties: {\n staged: { type: 'boolean', description: 'Show staged changes', default: false }\n }\n }\n },\n {\n name: 'make-laten-git-status',\n description: 'Compressed git status',\n inputSchema: { type: 'object', properties: {} }\n },\n {\n name: 'make-laten-cache-stats',\n description: 'Show cache performance stats',\n inputSchema: { type: 'object', properties: {} }\n }\n]\n\nfunction detectLanguage(filePath: string): string {\n const ext = filePath.split('.').pop()?.toLowerCase() || ''\n const map: Record<string, string> = {\n ts: 'typescript', tsx: 'typescript', js: 'javascript', jsx: 'javascript',\n py: 'python', rs: 'rust', go: 'go', java: 'java', rb: 'ruby',\n json: 'json', yaml: 'yaml', yml: 'yaml', md: 'markdown'\n }\n return map[ext] || 'text'\n}\n\nasync function handleRead(params: { file_path: string }) {\n const content = await fs.readFile(params.file_path, 'utf-8')\n const compressor = new FileReadCompressor()\n const result = await compressor.compress({\n content,\n filePath: params.file_path,\n language: detectLanguage(params.file_path)\n })\n return {\n content: [{ type: 'text', text: JSON.stringify({ compressed: result.content, savings: result.metadata.savings, confidence: result.confidence }) }]\n }\n}\n\nasync function handleGrep(params: { pattern: string; path?: string }) {\n const dir = params.path || '.'\n const { stdout } = await execAsync(`grep -rn \"${params.pattern}\" ${dir} 2>/dev/null || true`, { maxBuffer: 10 * 1024 * 1024 })\n\n if (!stdout.trim()) {\n return { content: [{ type: 'text', text: JSON.stringify({ matches: [], total: 0 }) }] }\n }\n\n const matches = stdout.split('\\n').filter(Boolean).map(line => {\n const parts = line.split(':')\n return { file: parts[0], line: parseInt(parts[1], 10) || 0, content: parts.slice(2).join(':').trim() }\n })\n\n const compressor = new GrepCompressor()\n const result = await compressor.compress({ results: matches, pattern: params.pattern, directory: dir })\n\n return { content: [{ type: 'text', text: JSON.stringify({ compressed: result.content, total: matches.length, savings: result.metadata.savings }) }] }\n}\n\nasync function handleGitDiff(params: { staged?: boolean }) {\n const flag = params.staged ? '--staged' : ''\n const { stdout } = await execAsync(`git diff ${flag}`, { maxBuffer: 10 * 1024 * 1024 })\n\n if (!stdout.trim()) {\n return { content: [{ type: 'text', text: JSON.stringify({ diff: '', changes: 0 }) }] }\n }\n\n const compressor = new GitDiffCompressor()\n const result = await compressor.compress({ diff: stdout })\n\n return { content: [{ type: 'text', text: JSON.stringify({ compressed: result.content, savings: result.metadata.savings }) }] }\n}\n\nasync function handleGitStatus() {\n const { stdout } = await execAsync('git status --porcelain')\n const compressor = new GitStatusCompressor()\n const result = await compressor.compress({ status: stdout })\n return { content: [{ type: 'text', text: JSON.stringify({ compressed: result.content, savings: result.metadata.savings }) }] }\n}\n\nasync function handleCacheStats() {\n return { content: [{ type: 'text', text: JSON.stringify({ message: 'Cache stats — use CLI: make-laten cache stats' }) }] }\n}\n\nconst handlers: Record<string, (params: any) => Promise<any>> = {\n 'make-laten-read': handleRead,\n 'make-laten-grep': handleGrep,\n 'make-laten-git-diff': handleGitDiff,\n 'make-laten-git-status': handleGitStatus,\n 'make-laten-cache-stats': handleCacheStats\n}\n\nlet requestId = 0\n\nfunction sendResponse(id: number, result: any) {\n const response = { jsonrpc: '2.0', id, result }\n process.stdout.write(JSON.stringify(response) + '\\n')\n}\n\nfunction sendError(id: number, code: number, message: string) {\n const response = { jsonrpc: '2.0', id, error: { code, message } }\n process.stdout.write(JSON.stringify(response) + '\\n')\n}\n\nasync function handleLine(line: string) {\n try {\n const request = JSON.parse(line)\n\n if (request.method === 'initialize') {\n sendResponse(request.id, {\n protocolVersion: '2024-11-05',\n capabilities: { tools: {} },\n serverInfo: { name: 'make-laten', version: '1.0.0' }\n })\n } else if (request.method === 'notifications/initialized') {\n // no response needed\n } else if (request.method === 'tools/list') {\n sendResponse(request.id, { tools: TOOLS })\n } else if (request.method === 'tools/call') {\n const { name, arguments: params } = request.params\n const handler = handlers[name]\n\n if (!handler) {\n sendError(request.id, -32601, `Unknown tool: ${name}`)\n return\n }\n\n try {\n const result = await handler(params || {})\n sendResponse(request.id, result)\n } catch (error: any) {\n sendError(request.id, -32000, error.message)\n }\n } else {\n sendError(request.id, -32601, `Method not found: ${request.method}`)\n }\n } catch (error: any) {\n process.stderr.write(`Error: ${error.message}\\n`)\n }\n}\n\nlet buffer = ''\n\nprocess.stdin.setEncoding('utf-8')\nprocess.stdin.on('data', async (chunk: string) => {\n buffer += chunk\n const lines = buffer.split('\\n')\n buffer = lines.pop() || ''\n\n for (const line of lines) {\n if (line.trim()) {\n await handleLine(line.trim())\n }\n }\n})\n\nprocess.stderr.write('make-laten MCP server started\\n')\n"],"mappings":"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","names":["exports","exports","compressed","fs"]}
|