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/README.md
CHANGED
|
@@ -18,10 +18,10 @@ User → AI Agent → make-laten intercept → compress (60-90% savings) → ret
|
|
|
18
18
|
|
|
19
19
|
| Command | Savings | Description |
|
|
20
20
|
|---------|---------|-------------|
|
|
21
|
-
| `read` | **
|
|
21
|
+
| `read` | **65-92%** | Compressed file read — exports, classes, functions only |
|
|
22
22
|
| `grep` | **70%** | Grouped by file with line numbers |
|
|
23
|
-
| `git diff` | **
|
|
24
|
-
| `git status` | **65%** | Status summary |
|
|
23
|
+
| `git diff` | **61%** | Condensed hunks, only changes shown |
|
|
24
|
+
| `git status` | **50-65%** | Status summary |
|
|
25
25
|
| `fetch` | **75%** | Web content with semantic extraction |
|
|
26
26
|
|
|
27
27
|
## Quick Start
|
package/dist/cli/index.js
CHANGED
|
@@ -58,29 +58,145 @@ function isKnownPattern(content) {
|
|
|
58
58
|
return patterns.some((p) => p.test(content));
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
// src/compress/strip.ts
|
|
62
|
+
function stripImports(content) {
|
|
63
|
+
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");
|
|
64
|
+
}
|
|
65
|
+
function stripComments(content) {
|
|
66
|
+
let result = content.replace(/(?<!["'`])\/\/.*$/gm, "");
|
|
67
|
+
result = result.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
68
|
+
return result.split("\n").filter((l) => l.trim() !== "").join("\n");
|
|
69
|
+
}
|
|
70
|
+
function stripBlankLines(content) {
|
|
71
|
+
return content.replace(/\n{3,}/g, "\n\n");
|
|
72
|
+
}
|
|
73
|
+
function stripWhitespace(content) {
|
|
74
|
+
return content.replace(/[ \t]+$/gm, "");
|
|
75
|
+
}
|
|
76
|
+
function stripAll(content) {
|
|
77
|
+
let result = content;
|
|
78
|
+
result = stripImports(result);
|
|
79
|
+
result = stripComments(result);
|
|
80
|
+
result = stripBlankLines(result);
|
|
81
|
+
result = stripWhitespace(result);
|
|
82
|
+
return result.trim();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/compress/structure.ts
|
|
86
|
+
function extractExports(content) {
|
|
87
|
+
const lines = content.split("\n");
|
|
88
|
+
const exports2 = [];
|
|
89
|
+
for (const line of lines) {
|
|
90
|
+
const trimmed = line.trim();
|
|
91
|
+
if (/^export\s+(default\s+)?/.test(trimmed)) {
|
|
92
|
+
if (trimmed.includes("{") && !trimmed.includes("}")) {
|
|
93
|
+
exports2.push(trimmed.replace(/\{[\s\S]*$/, "{ ... }"));
|
|
94
|
+
} else {
|
|
95
|
+
exports2.push(trimmed);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return exports2.join("\n");
|
|
100
|
+
}
|
|
101
|
+
function extractClassMethods(content) {
|
|
102
|
+
const classRegex = /class\s+\w+[^{]*\{([\s\S]*?)\n\}/g;
|
|
103
|
+
const methods = [];
|
|
104
|
+
let match;
|
|
105
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
106
|
+
const classBody = match[1];
|
|
107
|
+
const methodRegex = /(^\s*(?:public|private|protected|static|async|abstract|\s)*\w+\s*\([^)]*\)(?:\s*:\s*[^{]+)?)\s*\{/gm;
|
|
108
|
+
let methodMatch;
|
|
109
|
+
while ((methodMatch = methodRegex.exec(classBody)) !== null) {
|
|
110
|
+
methods.push(methodMatch[1].trim());
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return methods.join("\n");
|
|
114
|
+
}
|
|
115
|
+
function extractFunctionSignatures(content) {
|
|
116
|
+
const funcRegex = /(export\s+)?(async\s+)?function\s+\w+\s*\([^)]*\)(?:\s*:\s*[^{]+)?\s*\{/g;
|
|
117
|
+
const signatures = [];
|
|
118
|
+
let match;
|
|
119
|
+
while ((match = funcRegex.exec(content)) !== null) {
|
|
120
|
+
signatures.push(match[0].replace(/\{$/, ""));
|
|
121
|
+
}
|
|
122
|
+
return signatures.join("\n");
|
|
123
|
+
}
|
|
124
|
+
function extractTypeDefinitions(content) {
|
|
125
|
+
const typeRegex = /(export\s+)?(interface|type)\s+\w+[^{]*\{[^}]*\}|(export\s+)?type\s+\w+\s*=[^;]+;?/g;
|
|
126
|
+
const types = [];
|
|
127
|
+
let match;
|
|
128
|
+
while ((match = typeRegex.exec(content)) !== null) {
|
|
129
|
+
types.push(match[0].trim());
|
|
130
|
+
}
|
|
131
|
+
return types.join("\n");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// src/compress/truncate.ts
|
|
135
|
+
function smartTruncate(content, maxTokens) {
|
|
136
|
+
const lines = content.split("\n");
|
|
137
|
+
const estimatedTokens = Math.ceil(content.length / 4);
|
|
138
|
+
if (estimatedTokens <= maxTokens) return content;
|
|
139
|
+
const targetLines = Math.round(maxTokens * 4 / (content.length / lines.length));
|
|
140
|
+
const headerLines = Math.floor(targetLines * 0.3);
|
|
141
|
+
const footerLines = Math.floor(targetLines * 0.3);
|
|
142
|
+
const omitted = lines.length - headerLines - footerLines;
|
|
143
|
+
const header = lines.slice(0, headerLines);
|
|
144
|
+
const footer = lines.slice(-footerLines);
|
|
145
|
+
return [...header, `
|
|
146
|
+
... [${omitted} lines omitted] ...
|
|
147
|
+
`, ...footer].join("\n");
|
|
148
|
+
}
|
|
149
|
+
|
|
61
150
|
// src/compress/file-read.ts
|
|
62
151
|
var FileReadCompressor = class {
|
|
63
152
|
async compress(input) {
|
|
64
153
|
const { content, filePath, language } = input;
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
|
|
154
|
+
const lines = content.split("\n").length;
|
|
155
|
+
const tokens = Math.ceil(content.length / 4);
|
|
156
|
+
if (tokens < 200) {
|
|
157
|
+
return {
|
|
158
|
+
content,
|
|
159
|
+
original: content,
|
|
160
|
+
confidence: 1,
|
|
161
|
+
metadata: {
|
|
162
|
+
strategy: "passthrough",
|
|
163
|
+
originalLines: lines,
|
|
164
|
+
compressedLines: lines,
|
|
165
|
+
savings: 0
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const stripped = stripAll(content);
|
|
170
|
+
const exports2 = extractExports(stripped);
|
|
171
|
+
const classes = extractClassMethods(stripped);
|
|
172
|
+
const functions = extractFunctionSignatures(stripped);
|
|
173
|
+
const types = extractTypeDefinitions(stripped);
|
|
174
|
+
const sections = [
|
|
68
175
|
`// ${filePath} (${content.split("\n").length} lines)`,
|
|
69
176
|
"",
|
|
70
|
-
...signatures,
|
|
71
|
-
"",
|
|
72
177
|
"// Exports:",
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
178
|
+
exports2,
|
|
179
|
+
"",
|
|
180
|
+
"// Classes:",
|
|
181
|
+
classes,
|
|
182
|
+
"",
|
|
183
|
+
"// Functions:",
|
|
184
|
+
functions,
|
|
185
|
+
"",
|
|
186
|
+
"// Types:",
|
|
187
|
+
types
|
|
188
|
+
].filter((l) => l !== "" && !l.endsWith(":"));
|
|
189
|
+
let compressed = sections.join("\n");
|
|
190
|
+
const maxTokens = 2e3;
|
|
191
|
+
compressed = smartTruncate(compressed, maxTokens);
|
|
76
192
|
return {
|
|
77
193
|
content: compressed,
|
|
78
194
|
original: content,
|
|
79
195
|
confidence: calculateConfidence(content, compressed),
|
|
80
196
|
metadata: {
|
|
81
|
-
strategy: "
|
|
197
|
+
strategy: "hybrid",
|
|
82
198
|
originalLines: content.split("\n").length,
|
|
83
|
-
compressedLines:
|
|
199
|
+
compressedLines: compressed.split("\n").length,
|
|
84
200
|
savings: 1 - compressed.length / content.length
|
|
85
201
|
}
|
|
86
202
|
};
|
|
@@ -88,32 +204,6 @@ var FileReadCompressor = class {
|
|
|
88
204
|
async decompress(compressed) {
|
|
89
205
|
return compressed.original;
|
|
90
206
|
}
|
|
91
|
-
extractSignatures(content, language) {
|
|
92
|
-
const signatures = [];
|
|
93
|
-
const lines = content.split("\n");
|
|
94
|
-
for (const line of lines) {
|
|
95
|
-
const trimmed = line.trim();
|
|
96
|
-
if (/^(export\s+)?(async\s+)?function\s+\w+/.test(trimmed)) {
|
|
97
|
-
signatures.push(trimmed.replace(/\{[\s\S]*$/, "{ ... }"));
|
|
98
|
-
}
|
|
99
|
-
if (/^(export\s+)?class\s+\w+/.test(trimmed)) {
|
|
100
|
-
signatures.push(trimmed);
|
|
101
|
-
}
|
|
102
|
-
if (/^(export\s+)?(type|interface)\s+\w+/.test(trimmed)) {
|
|
103
|
-
signatures.push(trimmed);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return signatures;
|
|
107
|
-
}
|
|
108
|
-
extractExports(content) {
|
|
109
|
-
const exports2 = [];
|
|
110
|
-
const exportRegex = /export\s+(default\s+)?(function|class|const|let|var|type|interface)\s+(\w+)/g;
|
|
111
|
-
let match;
|
|
112
|
-
while ((match = exportRegex.exec(content)) !== null) {
|
|
113
|
-
exports2.push(` - ${match[3]} (${match[2]})`);
|
|
114
|
-
}
|
|
115
|
-
return exports2;
|
|
116
|
-
}
|
|
117
207
|
};
|
|
118
208
|
|
|
119
209
|
// src/cli/commands/read.ts
|
|
@@ -272,18 +362,21 @@ var import_util2 = require("util");
|
|
|
272
362
|
var GitDiffCompressor = class {
|
|
273
363
|
async compress(input) {
|
|
274
364
|
const { diff } = input;
|
|
275
|
-
const
|
|
276
|
-
const condensed = hunks.map((hunk) => ({
|
|
277
|
-
file: hunk.file,
|
|
278
|
-
changes: this.condenseHunk(hunk),
|
|
279
|
-
stats: { additions: hunk.additions, deletions: hunk.deletions }
|
|
280
|
-
}));
|
|
365
|
+
const files = this.parseDiff(diff);
|
|
281
366
|
const lines = [];
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
367
|
+
const totalAdd = files.reduce((s, f) => s + f.additions, 0);
|
|
368
|
+
const totalDel = files.reduce((s, f) => s + f.deletions, 0);
|
|
369
|
+
lines.push(`# ${files.length} files changed: +${totalAdd} -${totalDel}`);
|
|
370
|
+
lines.push("");
|
|
371
|
+
for (const file of files) {
|
|
372
|
+
lines.push(`${file.path} (+${file.additions} -${file.deletions})`);
|
|
373
|
+
const changes = file.lines.filter((l) => l.type === "add" || l.type === "del").map((l) => `${l.type === "add" ? "+" : "-"}${l.content}`);
|
|
374
|
+
const limited = changes.slice(0, 20);
|
|
375
|
+
lines.push(...limited);
|
|
376
|
+
if (changes.length > 20) {
|
|
377
|
+
lines.push(`... [${changes.length - 20} more changes]`);
|
|
286
378
|
}
|
|
379
|
+
lines.push("");
|
|
287
380
|
}
|
|
288
381
|
const compressed = lines.join("\n");
|
|
289
382
|
return {
|
|
@@ -292,7 +385,7 @@ var GitDiffCompressor = class {
|
|
|
292
385
|
confidence: calculateConfidence(diff, compressed),
|
|
293
386
|
metadata: {
|
|
294
387
|
strategy: "condensed",
|
|
295
|
-
filesChanged:
|
|
388
|
+
filesChanged: files.length,
|
|
296
389
|
savings: 1 - compressed.length / diff.length
|
|
297
390
|
}
|
|
298
391
|
};
|
|
@@ -301,34 +394,31 @@ var GitDiffCompressor = class {
|
|
|
301
394
|
return compressed.original;
|
|
302
395
|
}
|
|
303
396
|
parseDiff(diff) {
|
|
304
|
-
const
|
|
397
|
+
const files = [];
|
|
305
398
|
const lines = diff.split("\n");
|
|
306
|
-
let
|
|
399
|
+
let current = null;
|
|
307
400
|
for (const line of lines) {
|
|
308
401
|
if (line.startsWith("diff --git")) {
|
|
309
|
-
if (
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
lines: [],
|
|
402
|
+
if (current) files.push(current);
|
|
403
|
+
const match = line.match(/b\/(.+)/);
|
|
404
|
+
current = {
|
|
405
|
+
path: match?.[1] || "unknown",
|
|
314
406
|
additions: 0,
|
|
315
|
-
deletions: 0
|
|
407
|
+
deletions: 0,
|
|
408
|
+
lines: []
|
|
316
409
|
};
|
|
317
|
-
} else if (
|
|
410
|
+
} else if (current) {
|
|
318
411
|
if (line.startsWith("+")) {
|
|
319
|
-
|
|
320
|
-
|
|
412
|
+
current.additions++;
|
|
413
|
+
current.lines.push({ type: "add", content: line.slice(1) });
|
|
321
414
|
} else if (line.startsWith("-")) {
|
|
322
|
-
|
|
323
|
-
|
|
415
|
+
current.deletions++;
|
|
416
|
+
current.lines.push({ type: "del", content: line.slice(1) });
|
|
324
417
|
}
|
|
325
418
|
}
|
|
326
419
|
}
|
|
327
|
-
if (
|
|
328
|
-
return
|
|
329
|
-
}
|
|
330
|
-
condenseHunk(hunk) {
|
|
331
|
-
return hunk.lines.filter((l) => l.type === "addition" || l.type === "deletion").map((l) => `${l.type === "addition" ? "+" : "-"} ${l.content}`);
|
|
420
|
+
if (current) files.push(current);
|
|
421
|
+
return files;
|
|
332
422
|
}
|
|
333
423
|
};
|
|
334
424
|
|
|
@@ -1513,6 +1603,156 @@ async function initCommand(options) {
|
|
|
1513
1603
|
console.log("");
|
|
1514
1604
|
}
|
|
1515
1605
|
|
|
1606
|
+
// src/compress/git-status.ts
|
|
1607
|
+
var GitStatusCompressor = class {
|
|
1608
|
+
async compress(input) {
|
|
1609
|
+
const { status } = input;
|
|
1610
|
+
const statusLines = status.split("\n").filter(Boolean).length;
|
|
1611
|
+
const tokens = Math.ceil(status.length / 4);
|
|
1612
|
+
if (tokens < 10) {
|
|
1613
|
+
return {
|
|
1614
|
+
content: status,
|
|
1615
|
+
original: status,
|
|
1616
|
+
confidence: 1,
|
|
1617
|
+
metadata: {
|
|
1618
|
+
strategy: "passthrough",
|
|
1619
|
+
totalFiles: statusLines,
|
|
1620
|
+
savings: 0
|
|
1621
|
+
}
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
const files = this.parseStatus(status);
|
|
1625
|
+
const grouped = this.groupByStatus(files);
|
|
1626
|
+
const lines = [];
|
|
1627
|
+
for (const [statusType, statusFiles] of grouped) {
|
|
1628
|
+
const label = this.statusLabel(statusType);
|
|
1629
|
+
lines.push(`${label} (${statusFiles.length})`);
|
|
1630
|
+
const compressed2 = this.compressPaths(statusFiles.map((f) => f.path));
|
|
1631
|
+
lines.push(...compressed2);
|
|
1632
|
+
lines.push("");
|
|
1633
|
+
}
|
|
1634
|
+
const compressed = lines.join("\n");
|
|
1635
|
+
return {
|
|
1636
|
+
content: compressed,
|
|
1637
|
+
original: status,
|
|
1638
|
+
confidence: calculateConfidence(status, compressed),
|
|
1639
|
+
metadata: {
|
|
1640
|
+
strategy: "grouped",
|
|
1641
|
+
totalFiles: files.length,
|
|
1642
|
+
savings: 1 - compressed.length / status.length
|
|
1643
|
+
}
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
async decompress(compressed) {
|
|
1647
|
+
return compressed.original;
|
|
1648
|
+
}
|
|
1649
|
+
parseStatus(status) {
|
|
1650
|
+
return status.split("\n").filter(Boolean).map((line) => {
|
|
1651
|
+
const match = line.match(/^(\?\?|[MADRC]+\s+)(.+)$/);
|
|
1652
|
+
if (match) {
|
|
1653
|
+
return { status: match[1].trim(), path: match[2] };
|
|
1654
|
+
}
|
|
1655
|
+
return { status: line[0], path: line.slice(3) };
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1658
|
+
groupByStatus(files) {
|
|
1659
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
1660
|
+
for (const file of files) {
|
|
1661
|
+
const existing = grouped.get(file.status) || [];
|
|
1662
|
+
existing.push(file);
|
|
1663
|
+
grouped.set(file.status, existing);
|
|
1664
|
+
}
|
|
1665
|
+
return grouped;
|
|
1666
|
+
}
|
|
1667
|
+
statusLabel(status) {
|
|
1668
|
+
const labels = {
|
|
1669
|
+
"M": "Modified",
|
|
1670
|
+
"A": "Added",
|
|
1671
|
+
"D": "Deleted",
|
|
1672
|
+
"??": "Untracked",
|
|
1673
|
+
"R": "Renamed"
|
|
1674
|
+
};
|
|
1675
|
+
return labels[status] || `Status ${status}`;
|
|
1676
|
+
}
|
|
1677
|
+
compressPaths(paths) {
|
|
1678
|
+
if (paths.length <= 3) return paths.map((p) => ` ${p}`);
|
|
1679
|
+
const parts = paths.map((p) => p.split("/"));
|
|
1680
|
+
const minLength = Math.min(...parts.map((p) => p.length));
|
|
1681
|
+
let commonIndex = 0;
|
|
1682
|
+
for (let i = 0; i < minLength; i++) {
|
|
1683
|
+
if (parts.every((p) => p[i] === parts[0][i])) {
|
|
1684
|
+
commonIndex = i;
|
|
1685
|
+
} else {
|
|
1686
|
+
break;
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
if (commonIndex > 0) {
|
|
1690
|
+
const prefix = parts[0].slice(0, commonIndex).join("/");
|
|
1691
|
+
const suffixes = paths.map((p) => p.slice(prefix.length + 1));
|
|
1692
|
+
return [` ${prefix}/`, ...suffixes.map((s) => ` ${s}`)];
|
|
1693
|
+
}
|
|
1694
|
+
return paths.map((p) => ` ${p}`);
|
|
1695
|
+
}
|
|
1696
|
+
};
|
|
1697
|
+
|
|
1698
|
+
// src/cli/commands/benchmark.ts
|
|
1699
|
+
var import_fs = __toESM(require("fs"));
|
|
1700
|
+
var import_path3 = __toESM(require("path"));
|
|
1701
|
+
var import_child_process5 = require("child_process");
|
|
1702
|
+
async function benchmark() {
|
|
1703
|
+
const fileCompressor = new FileReadCompressor();
|
|
1704
|
+
const diffCompressor = new GitDiffCompressor();
|
|
1705
|
+
const statusCompressor = new GitStatusCompressor();
|
|
1706
|
+
const projectPath = process.cwd();
|
|
1707
|
+
console.log("");
|
|
1708
|
+
console.log(" make-laten benchmark");
|
|
1709
|
+
console.log(" ===================");
|
|
1710
|
+
console.log("");
|
|
1711
|
+
const results = [];
|
|
1712
|
+
const testFiles = ["src/index.ts", "package.json", "README.md", "src/mcp/server.ts"];
|
|
1713
|
+
for (const file of testFiles) {
|
|
1714
|
+
const full = import_path3.default.join(projectPath, file);
|
|
1715
|
+
if (!import_fs.default.existsSync(full)) continue;
|
|
1716
|
+
const content = import_fs.default.readFileSync(full, "utf-8");
|
|
1717
|
+
const raw = Math.round(content.length / 4);
|
|
1718
|
+
const result = await fileCompressor.compress({ content, filePath: file });
|
|
1719
|
+
const compressed = Math.round(result.content.length / 4);
|
|
1720
|
+
results.push({ name: `read ${file}`, raw, compressed, savings: Math.round((1 - compressed / raw) * 100) });
|
|
1721
|
+
}
|
|
1722
|
+
try {
|
|
1723
|
+
const diff = (0, import_child_process5.execSync)('git diff HEAD~1 2>/dev/null || echo ""', { cwd: projectPath, encoding: "utf-8" }).trim();
|
|
1724
|
+
if (diff) {
|
|
1725
|
+
const raw = Math.round(diff.length / 4);
|
|
1726
|
+
const result = await diffCompressor.compress({ diff });
|
|
1727
|
+
const compressed = Math.round(result.content.length / 4);
|
|
1728
|
+
results.push({ name: "git-diff", raw, compressed, savings: Math.round((1 - compressed / raw) * 100) });
|
|
1729
|
+
}
|
|
1730
|
+
} catch {
|
|
1731
|
+
}
|
|
1732
|
+
try {
|
|
1733
|
+
const status = (0, import_child_process5.execSync)('git status --porcelain 2>/dev/null || echo ""', { cwd: projectPath, encoding: "utf-8" }).trim();
|
|
1734
|
+
if (status) {
|
|
1735
|
+
const raw = Math.round(status.length / 4);
|
|
1736
|
+
const result = await statusCompressor.compress({ status });
|
|
1737
|
+
const compressed = Math.round(result.content.length / 4);
|
|
1738
|
+
results.push({ name: "git-status", raw, compressed, savings: Math.round((1 - compressed / raw) * 100) });
|
|
1739
|
+
}
|
|
1740
|
+
} catch {
|
|
1741
|
+
}
|
|
1742
|
+
console.log(" Command".padEnd(28) + "Raw".padEnd(10) + "Compressed".padEnd(12) + "Savings");
|
|
1743
|
+
console.log(" " + "\u2500".repeat(60));
|
|
1744
|
+
for (const r of results) {
|
|
1745
|
+
console.log(` ${r.name}`.padEnd(28) + `${r.raw}`.padEnd(10) + `${r.compressed}`.padEnd(12) + `${r.savings}%`);
|
|
1746
|
+
}
|
|
1747
|
+
const totalRaw = results.reduce((s, r) => s + r.raw, 0);
|
|
1748
|
+
const totalCompressed = results.reduce((s, r) => s + r.compressed, 0);
|
|
1749
|
+
const savings = Math.round((1 - totalCompressed / totalRaw) * 100);
|
|
1750
|
+
console.log("");
|
|
1751
|
+
console.log(` Total: ${totalRaw} \u2192 ${totalCompressed} tokens (${savings}% saved)`);
|
|
1752
|
+
console.log("");
|
|
1753
|
+
}
|
|
1754
|
+
benchmark();
|
|
1755
|
+
|
|
1516
1756
|
// src/cli/index.ts
|
|
1517
1757
|
var program = new import_commander.Command();
|
|
1518
1758
|
program.name("make-laten").description("Universal efficiency toolkit for AI coding agents").version("1.0.3");
|
|
@@ -1528,5 +1768,6 @@ program.command("search").description("Search the web").argument("<query>", "Sea
|
|
|
1528
1768
|
program.command("fetch").description("Fetch and compress web content").argument("<url>", "URL to fetch").option("--no-compress", "Disable compression").option("--no-extract", "Disable semantic extraction").action(fetchCommand);
|
|
1529
1769
|
program.command("install").description("Install make-laten across all detected platforms").option("-u, --uninstall", "Remove adapters").option("-s, --status", "Show installation status").action(installCommand);
|
|
1530
1770
|
program.command("init").description("Interactive setup wizard \u2014 detect agents & configure MCP").option("-a, --all", "Configure all detected agents (no prompts)").option("-p, --project", "Create .mcp.json in current directory only").action(initCommand);
|
|
1771
|
+
program.command("benchmark").description("Compare raw vs compressed output").action(void 0);
|
|
1531
1772
|
program.parse();
|
|
1532
1773
|
//# sourceMappingURL=index.js.map
|