make-laten 1.0.1 → 1.1.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/dist/cli/index.js +532 -262
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +532 -262
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.js +352 -69
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +352 -69
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/server.js +402 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/server.mjs +379 -0
- package/dist/mcp/server.mjs.map +1 -0
- package/package.json +12 -5
- package/shell/init.sh +62 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// src/compress/confidence.ts
|
|
27
|
+
function calculateConfidence(original, compressed) {
|
|
28
|
+
if (!original.length) return 0;
|
|
29
|
+
let score = 1;
|
|
30
|
+
const ratio = compressed.length / original.length;
|
|
31
|
+
if (ratio < 0.01) score -= 0.5;
|
|
32
|
+
else if (ratio < 0.05) score -= 0.3;
|
|
33
|
+
if (codeBlocksModified(original, compressed)) score -= 0.4;
|
|
34
|
+
if (isKnownPattern(original)) score += 0.1;
|
|
35
|
+
return Math.max(0, Math.min(1, score));
|
|
36
|
+
}
|
|
37
|
+
function codeBlocksModified(original, compressed) {
|
|
38
|
+
const codeBlockRegex = /```[\s\S]*?```/g;
|
|
39
|
+
const originalBlocks = original.match(codeBlockRegex) || [];
|
|
40
|
+
const compressedBlocks = compressed.match(codeBlockRegex) || [];
|
|
41
|
+
if (originalBlocks.length !== compressedBlocks.length) return true;
|
|
42
|
+
for (let i = 0; i < originalBlocks.length; i++) {
|
|
43
|
+
if (originalBlocks[i] !== compressedBlocks[i]) return true;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
function isKnownPattern(content) {
|
|
48
|
+
const patterns = [
|
|
49
|
+
/export\s+(default\s+)?(function|class|const|let|var)/,
|
|
50
|
+
/import\s+.*from\s+['"]/
|
|
51
|
+
];
|
|
52
|
+
return patterns.some((p) => p.test(content));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/compress/file-read.ts
|
|
56
|
+
var FileReadCompressor = class {
|
|
57
|
+
async compress(input) {
|
|
58
|
+
const { content, filePath, language } = input;
|
|
59
|
+
const signatures = this.extractSignatures(content, language);
|
|
60
|
+
const exports2 = this.extractExports(content);
|
|
61
|
+
const lines = [
|
|
62
|
+
`// ${filePath} (${content.split("\n").length} lines)`,
|
|
63
|
+
"",
|
|
64
|
+
...signatures,
|
|
65
|
+
"",
|
|
66
|
+
"// Exports:",
|
|
67
|
+
...exports2
|
|
68
|
+
];
|
|
69
|
+
const compressed = lines.join("\n");
|
|
70
|
+
return {
|
|
71
|
+
content: compressed,
|
|
72
|
+
original: content,
|
|
73
|
+
confidence: calculateConfidence(content, compressed),
|
|
74
|
+
metadata: {
|
|
75
|
+
strategy: "signatures",
|
|
76
|
+
originalLines: content.split("\n").length,
|
|
77
|
+
compressedLines: lines.length,
|
|
78
|
+
savings: 1 - compressed.length / content.length
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async decompress(compressed) {
|
|
83
|
+
return compressed.original;
|
|
84
|
+
}
|
|
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
|
+
};
|
|
112
|
+
|
|
113
|
+
// src/compress/grep.ts
|
|
114
|
+
var GrepCompressor = class {
|
|
115
|
+
async compress(input) {
|
|
116
|
+
const { results } = input;
|
|
117
|
+
const grouped = this.groupByFile(results);
|
|
118
|
+
const lines = [];
|
|
119
|
+
for (const [file, matches] of grouped) {
|
|
120
|
+
lines.push(`${file} (${matches.length} matches)`);
|
|
121
|
+
const unique = this.deduplicate(matches);
|
|
122
|
+
for (const match of unique) {
|
|
123
|
+
lines.push(` L${match.line}: ${match.content}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const compressed = lines.join("\n");
|
|
127
|
+
const original = results.map((r) => `${r.file}:${r.line}: ${r.content}`).join("\n");
|
|
128
|
+
return {
|
|
129
|
+
content: compressed,
|
|
130
|
+
original,
|
|
131
|
+
confidence: calculateConfidence(original, compressed),
|
|
132
|
+
metadata: {
|
|
133
|
+
strategy: "grouped",
|
|
134
|
+
totalMatches: results.length,
|
|
135
|
+
uniqueFiles: grouped.size,
|
|
136
|
+
savings: 1 - compressed.length / original.length
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
async decompress(compressed) {
|
|
141
|
+
return compressed.original;
|
|
142
|
+
}
|
|
143
|
+
groupByFile(results) {
|
|
144
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
145
|
+
for (const result of results) {
|
|
146
|
+
const existing = grouped.get(result.file) || [];
|
|
147
|
+
existing.push(result);
|
|
148
|
+
grouped.set(result.file, existing);
|
|
149
|
+
}
|
|
150
|
+
return grouped;
|
|
151
|
+
}
|
|
152
|
+
deduplicate(matches) {
|
|
153
|
+
const seen = /* @__PURE__ */ new Set();
|
|
154
|
+
return matches.filter((match) => {
|
|
155
|
+
const key = match.content.trim();
|
|
156
|
+
if (seen.has(key)) return false;
|
|
157
|
+
seen.add(key);
|
|
158
|
+
return true;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// src/compress/git-diff.ts
|
|
164
|
+
var GitDiffCompressor = class {
|
|
165
|
+
async compress(input) {
|
|
166
|
+
const { diff } = input;
|
|
167
|
+
const hunks = this.parseDiff(diff);
|
|
168
|
+
const condensed = hunks.map((hunk) => ({
|
|
169
|
+
file: hunk.file,
|
|
170
|
+
changes: this.condenseHunk(hunk),
|
|
171
|
+
stats: { additions: hunk.additions, deletions: hunk.deletions }
|
|
172
|
+
}));
|
|
173
|
+
const lines = [];
|
|
174
|
+
for (const hunk of condensed) {
|
|
175
|
+
if (hunk.changes.length > 0) {
|
|
176
|
+
lines.push(`${hunk.file} (+${hunk.stats.additions} -${hunk.stats.deletions})`);
|
|
177
|
+
lines.push(...hunk.changes);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const compressed = lines.join("\n");
|
|
181
|
+
return {
|
|
182
|
+
content: compressed,
|
|
183
|
+
original: diff,
|
|
184
|
+
confidence: calculateConfidence(diff, compressed),
|
|
185
|
+
metadata: {
|
|
186
|
+
strategy: "condensed",
|
|
187
|
+
filesChanged: condensed.length,
|
|
188
|
+
savings: 1 - compressed.length / diff.length
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
async decompress(compressed) {
|
|
193
|
+
return compressed.original;
|
|
194
|
+
}
|
|
195
|
+
parseDiff(diff) {
|
|
196
|
+
const hunks = [];
|
|
197
|
+
const lines = diff.split("\n");
|
|
198
|
+
let currentHunk = null;
|
|
199
|
+
for (const line of lines) {
|
|
200
|
+
if (line.startsWith("diff --git")) {
|
|
201
|
+
if (currentHunk) hunks.push(currentHunk);
|
|
202
|
+
const fileMatch = line.match(/b\/(.+)/);
|
|
203
|
+
currentHunk = {
|
|
204
|
+
file: fileMatch?.[1] || "unknown",
|
|
205
|
+
lines: [],
|
|
206
|
+
additions: 0,
|
|
207
|
+
deletions: 0
|
|
208
|
+
};
|
|
209
|
+
} else if (currentHunk) {
|
|
210
|
+
if (line.startsWith("+")) {
|
|
211
|
+
currentHunk.additions++;
|
|
212
|
+
currentHunk.lines.push({ type: "addition", content: line.slice(1) });
|
|
213
|
+
} else if (line.startsWith("-")) {
|
|
214
|
+
currentHunk.deletions++;
|
|
215
|
+
currentHunk.lines.push({ type: "deletion", content: line.slice(1) });
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (currentHunk) hunks.push(currentHunk);
|
|
220
|
+
return hunks;
|
|
221
|
+
}
|
|
222
|
+
condenseHunk(hunk) {
|
|
223
|
+
return hunk.lines.filter((l) => l.type === "addition" || l.type === "deletion").map((l) => `${l.type === "addition" ? "+" : "-"} ${l.content}`);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// src/mcp/server.ts
|
|
228
|
+
var import_child_process = require("child_process");
|
|
229
|
+
var import_util = require("util");
|
|
230
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
231
|
+
var execAsync = (0, import_util.promisify)(import_child_process.exec);
|
|
232
|
+
var TOOLS = [
|
|
233
|
+
{
|
|
234
|
+
name: "make-laten-read",
|
|
235
|
+
description: "Read and compress a file (60-90% token savings)",
|
|
236
|
+
inputSchema: {
|
|
237
|
+
type: "object",
|
|
238
|
+
properties: {
|
|
239
|
+
file_path: { type: "string", description: "Path to file" }
|
|
240
|
+
},
|
|
241
|
+
required: ["file_path"]
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
name: "make-laten-grep",
|
|
246
|
+
description: "Search code and return compressed grouped results",
|
|
247
|
+
inputSchema: {
|
|
248
|
+
type: "object",
|
|
249
|
+
properties: {
|
|
250
|
+
pattern: { type: "string", description: "Search pattern" },
|
|
251
|
+
path: { type: "string", description: "Directory to search", default: "." }
|
|
252
|
+
},
|
|
253
|
+
required: ["pattern"]
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
name: "make-laten-git-diff",
|
|
258
|
+
description: "Compressed git diff output",
|
|
259
|
+
inputSchema: {
|
|
260
|
+
type: "object",
|
|
261
|
+
properties: {
|
|
262
|
+
staged: { type: "boolean", description: "Show staged changes", default: false }
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "make-laten-git-status",
|
|
268
|
+
description: "Compressed git status",
|
|
269
|
+
inputSchema: { type: "object", properties: {} }
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: "make-laten-cache-stats",
|
|
273
|
+
description: "Show cache performance stats",
|
|
274
|
+
inputSchema: { type: "object", properties: {} }
|
|
275
|
+
}
|
|
276
|
+
];
|
|
277
|
+
function detectLanguage(filePath) {
|
|
278
|
+
const ext = filePath.split(".").pop()?.toLowerCase() || "";
|
|
279
|
+
const map = {
|
|
280
|
+
ts: "typescript",
|
|
281
|
+
tsx: "typescript",
|
|
282
|
+
js: "javascript",
|
|
283
|
+
jsx: "javascript",
|
|
284
|
+
py: "python",
|
|
285
|
+
rs: "rust",
|
|
286
|
+
go: "go",
|
|
287
|
+
java: "java",
|
|
288
|
+
rb: "ruby",
|
|
289
|
+
json: "json",
|
|
290
|
+
yaml: "yaml",
|
|
291
|
+
yml: "yaml",
|
|
292
|
+
md: "markdown"
|
|
293
|
+
};
|
|
294
|
+
return map[ext] || "text";
|
|
295
|
+
}
|
|
296
|
+
async function handleRead(params) {
|
|
297
|
+
const content = await import_promises.default.readFile(params.file_path, "utf-8");
|
|
298
|
+
const compressor = new FileReadCompressor();
|
|
299
|
+
const result = await compressor.compress({
|
|
300
|
+
content,
|
|
301
|
+
filePath: params.file_path,
|
|
302
|
+
language: detectLanguage(params.file_path)
|
|
303
|
+
});
|
|
304
|
+
return {
|
|
305
|
+
content: [{ type: "text", text: JSON.stringify({ compressed: result.content, savings: result.metadata.savings, confidence: result.confidence }) }]
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
async function handleGrep(params) {
|
|
309
|
+
const dir = params.path || ".";
|
|
310
|
+
const { stdout } = await execAsync(`grep -rn "${params.pattern}" ${dir} 2>/dev/null || true`, { maxBuffer: 10 * 1024 * 1024 });
|
|
311
|
+
if (!stdout.trim()) {
|
|
312
|
+
return { content: [{ type: "text", text: JSON.stringify({ matches: [], total: 0 }) }] };
|
|
313
|
+
}
|
|
314
|
+
const matches = stdout.split("\n").filter(Boolean).map((line) => {
|
|
315
|
+
const parts = line.split(":");
|
|
316
|
+
return { file: parts[0], line: parseInt(parts[1], 10) || 0, content: parts.slice(2).join(":").trim() };
|
|
317
|
+
});
|
|
318
|
+
const compressor = new GrepCompressor();
|
|
319
|
+
const result = await compressor.compress({ results: matches, pattern: params.pattern, directory: dir });
|
|
320
|
+
return { content: [{ type: "text", text: JSON.stringify({ compressed: result.content, total: matches.length, savings: result.metadata.savings }) }] };
|
|
321
|
+
}
|
|
322
|
+
async function handleGitDiff(params) {
|
|
323
|
+
const flag = params.staged ? "--staged" : "";
|
|
324
|
+
const { stdout } = await execAsync(`git diff ${flag}`, { maxBuffer: 10 * 1024 * 1024 });
|
|
325
|
+
if (!stdout.trim()) {
|
|
326
|
+
return { content: [{ type: "text", text: JSON.stringify({ diff: "", changes: 0 }) }] };
|
|
327
|
+
}
|
|
328
|
+
const compressor = new GitDiffCompressor();
|
|
329
|
+
const result = await compressor.compress({ diff: stdout });
|
|
330
|
+
return { content: [{ type: "text", text: JSON.stringify({ compressed: result.content, savings: result.metadata.savings }) }] };
|
|
331
|
+
}
|
|
332
|
+
async function handleGitStatus() {
|
|
333
|
+
const { stdout } = await execAsync("git status --porcelain");
|
|
334
|
+
const lines = stdout.split("\n").filter(Boolean);
|
|
335
|
+
const files = lines.map((l) => ({ status: l[0], path: l.slice(3) }));
|
|
336
|
+
return { content: [{ type: "text", text: JSON.stringify({ total: files.length, files }) }] };
|
|
337
|
+
}
|
|
338
|
+
async function handleCacheStats() {
|
|
339
|
+
return { content: [{ type: "text", text: JSON.stringify({ message: "Cache stats \u2014 use CLI: make-laten cache stats" }) }] };
|
|
340
|
+
}
|
|
341
|
+
var handlers = {
|
|
342
|
+
"make-laten-read": handleRead,
|
|
343
|
+
"make-laten-grep": handleGrep,
|
|
344
|
+
"make-laten-git-diff": handleGitDiff,
|
|
345
|
+
"make-laten-git-status": handleGitStatus,
|
|
346
|
+
"make-laten-cache-stats": handleCacheStats
|
|
347
|
+
};
|
|
348
|
+
function sendResponse(id, result) {
|
|
349
|
+
const response = { jsonrpc: "2.0", id, result };
|
|
350
|
+
process.stdout.write(JSON.stringify(response) + "\n");
|
|
351
|
+
}
|
|
352
|
+
function sendError(id, code, message) {
|
|
353
|
+
const response = { jsonrpc: "2.0", id, error: { code, message } };
|
|
354
|
+
process.stdout.write(JSON.stringify(response) + "\n");
|
|
355
|
+
}
|
|
356
|
+
async function handleLine(line) {
|
|
357
|
+
try {
|
|
358
|
+
const request = JSON.parse(line);
|
|
359
|
+
if (request.method === "initialize") {
|
|
360
|
+
sendResponse(request.id, {
|
|
361
|
+
protocolVersion: "2024-11-05",
|
|
362
|
+
capabilities: { tools: {} },
|
|
363
|
+
serverInfo: { name: "make-laten", version: "1.0.0" }
|
|
364
|
+
});
|
|
365
|
+
} else if (request.method === "notifications/initialized") {
|
|
366
|
+
} else if (request.method === "tools/list") {
|
|
367
|
+
sendResponse(request.id, { tools: TOOLS });
|
|
368
|
+
} else if (request.method === "tools/call") {
|
|
369
|
+
const { name, arguments: params } = request.params;
|
|
370
|
+
const handler = handlers[name];
|
|
371
|
+
if (!handler) {
|
|
372
|
+
sendError(request.id, -32601, `Unknown tool: ${name}`);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
try {
|
|
376
|
+
const result = await handler(params || {});
|
|
377
|
+
sendResponse(request.id, result);
|
|
378
|
+
} catch (error) {
|
|
379
|
+
sendError(request.id, -32e3, error.message);
|
|
380
|
+
}
|
|
381
|
+
} else {
|
|
382
|
+
sendError(request.id, -32601, `Method not found: ${request.method}`);
|
|
383
|
+
}
|
|
384
|
+
} catch (error) {
|
|
385
|
+
process.stderr.write(`Error: ${error.message}
|
|
386
|
+
`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
var buffer = "";
|
|
390
|
+
process.stdin.setEncoding("utf-8");
|
|
391
|
+
process.stdin.on("data", async (chunk) => {
|
|
392
|
+
buffer += chunk;
|
|
393
|
+
const lines = buffer.split("\n");
|
|
394
|
+
buffer = lines.pop() || "";
|
|
395
|
+
for (const line of lines) {
|
|
396
|
+
if (line.trim()) {
|
|
397
|
+
await handleLine(line.trim());
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
process.stderr.write("make-laten MCP server started\n");
|
|
402
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +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":"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","names":["exports","fs"]}
|