make-laten 1.2.2 → 1.2.3
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 +154 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +154 -14
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.js +143 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +143 -3
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/server.js +148 -8
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/server.mjs +150 -10
- package/dist/mcp/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/mcp/server.mjs
CHANGED
|
@@ -475,14 +475,55 @@ var StrategyRouter = class {
|
|
|
475
475
|
};
|
|
476
476
|
|
|
477
477
|
// src/learn/pattern-miner.ts
|
|
478
|
+
import fs from "fs";
|
|
479
|
+
import path from "path";
|
|
480
|
+
var DATA_FILE = path.join(process.env.HOME || "~", ".make-laten", "patterns.json");
|
|
478
481
|
var PatternMiner = class {
|
|
479
482
|
operations = [];
|
|
480
483
|
patterns = /* @__PURE__ */ new Map();
|
|
484
|
+
persistencePath;
|
|
485
|
+
lastPersist = 0;
|
|
486
|
+
constructor(options) {
|
|
487
|
+
this.persistencePath = options?.persistencePath || DATA_FILE;
|
|
488
|
+
this.loadFromDisk();
|
|
489
|
+
}
|
|
490
|
+
loadFromDisk() {
|
|
491
|
+
try {
|
|
492
|
+
if (fs.existsSync(this.persistencePath)) {
|
|
493
|
+
const data = JSON.parse(fs.readFileSync(this.persistencePath, "utf-8"));
|
|
494
|
+
if (Array.isArray(data.patterns)) {
|
|
495
|
+
for (const p of data.patterns) {
|
|
496
|
+
this.patterns.set(p.type, p);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
if (Array.isArray(data.operations)) {
|
|
500
|
+
this.operations = data.operations.slice(-100);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
} catch {
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
persistToDisk() {
|
|
507
|
+
const now = Date.now();
|
|
508
|
+
if (now - this.lastPersist < 5e3) return;
|
|
509
|
+
this.lastPersist = now;
|
|
510
|
+
try {
|
|
511
|
+
const dir = path.dirname(this.persistencePath);
|
|
512
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
513
|
+
fs.writeFileSync(this.persistencePath, JSON.stringify({
|
|
514
|
+
patterns: Array.from(this.patterns.values()),
|
|
515
|
+
operations: this.operations.slice(-100)
|
|
516
|
+
}, null, 2));
|
|
517
|
+
} catch {
|
|
518
|
+
}
|
|
519
|
+
}
|
|
481
520
|
record(operation) {
|
|
482
521
|
this.operations.push(operation);
|
|
522
|
+
if (this.operations.length > 100) this.operations.shift();
|
|
483
523
|
if (operation.success) {
|
|
484
524
|
this.updatePatterns(operation);
|
|
485
525
|
}
|
|
526
|
+
this.persistToDisk();
|
|
486
527
|
}
|
|
487
528
|
getPatterns() {
|
|
488
529
|
return Array.from(this.patterns.values());
|
|
@@ -509,8 +550,43 @@ var PatternMiner = class {
|
|
|
509
550
|
};
|
|
510
551
|
|
|
511
552
|
// src/learn/failure-learner.ts
|
|
553
|
+
import fs2 from "fs";
|
|
554
|
+
import path2 from "path";
|
|
555
|
+
var DATA_FILE2 = path2.join(process.env.HOME || "~", ".make-laten", "failures.json");
|
|
512
556
|
var FailureLearner = class {
|
|
513
557
|
failures = /* @__PURE__ */ new Map();
|
|
558
|
+
persistencePath;
|
|
559
|
+
lastPersist = 0;
|
|
560
|
+
constructor(options) {
|
|
561
|
+
this.persistencePath = options?.persistencePath || DATA_FILE2;
|
|
562
|
+
this.loadFromDisk();
|
|
563
|
+
}
|
|
564
|
+
loadFromDisk() {
|
|
565
|
+
try {
|
|
566
|
+
if (fs2.existsSync(this.persistencePath)) {
|
|
567
|
+
const data = JSON.parse(fs2.readFileSync(this.persistencePath, "utf-8"));
|
|
568
|
+
if (Array.isArray(data.failures)) {
|
|
569
|
+
for (const f of data.failures) {
|
|
570
|
+
this.failures.set(`${f.type}:${f.error}`, f);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
} catch {
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
persistToDisk() {
|
|
578
|
+
const now = Date.now();
|
|
579
|
+
if (now - this.lastPersist < 5e3) return;
|
|
580
|
+
this.lastPersist = now;
|
|
581
|
+
try {
|
|
582
|
+
const dir = path2.dirname(this.persistencePath);
|
|
583
|
+
if (!fs2.existsSync(dir)) fs2.mkdirSync(dir, { recursive: true });
|
|
584
|
+
fs2.writeFileSync(this.persistencePath, JSON.stringify({
|
|
585
|
+
failures: Array.from(this.failures.values())
|
|
586
|
+
}, null, 2));
|
|
587
|
+
} catch {
|
|
588
|
+
}
|
|
589
|
+
}
|
|
514
590
|
record(failure) {
|
|
515
591
|
const key = `${failure.type}:${failure.error}`;
|
|
516
592
|
const existing = this.failures.get(key);
|
|
@@ -524,6 +600,7 @@ var FailureLearner = class {
|
|
|
524
600
|
count: 1
|
|
525
601
|
});
|
|
526
602
|
}
|
|
603
|
+
this.persistToDisk();
|
|
527
604
|
}
|
|
528
605
|
getFailures() {
|
|
529
606
|
return Array.from(this.failures.values());
|
|
@@ -550,32 +627,95 @@ var FailureLearner = class {
|
|
|
550
627
|
};
|
|
551
628
|
|
|
552
629
|
// src/correct/auto-correct.ts
|
|
630
|
+
import fs3 from "fs";
|
|
631
|
+
import path3 from "path";
|
|
632
|
+
var DEFAULT_RULES = [
|
|
633
|
+
// Common typos
|
|
634
|
+
{ name: "typo-teh", description: "Common typo", pattern: "teh", replacement: "the" },
|
|
635
|
+
{ name: "typo-adn", description: "Common typo", pattern: "adn", replacement: "and" },
|
|
636
|
+
{ name: "typo-fo", description: "Common typo", pattern: " fo ", replacement: " of " },
|
|
637
|
+
{ name: "typo-ot", description: "Common typo", pattern: " ot ", replacement: " to " },
|
|
638
|
+
{ name: "typo-isnt", description: "Common typo", pattern: "isnt", replacement: "isn't" },
|
|
639
|
+
{ name: "typo-dont", description: "Common typo", pattern: "dont", replacement: "don't" },
|
|
640
|
+
{ name: "typo-cant", description: "Common typo", pattern: "cant", replacement: "can't" },
|
|
641
|
+
{ name: "typo-wont", description: "Common typo", pattern: "wont", replacement: "won't" },
|
|
642
|
+
{ name: "typo-youre", description: "Common typo", pattern: "youre", replacement: "you're" },
|
|
643
|
+
{ name: "typo-its", description: "Common typo", pattern: "its a", replacement: "it's a" },
|
|
644
|
+
// Code patterns
|
|
645
|
+
{ name: "code-console-log", description: "Remove console.log", pattern: /console\.log\([^)]*\);?\n?/g, replacement: "" },
|
|
646
|
+
{ name: "code-debugger", description: "Remove debugger", pattern: /debugger;?\n?/g, replacement: "" },
|
|
647
|
+
{ name: "code-var-let", description: "var to let", pattern: /\bvar\b/g, replacement: "let" },
|
|
648
|
+
// Markdown
|
|
649
|
+
{ name: "md-double-space", description: "Double space to single", pattern: " ", replacement: " " }
|
|
650
|
+
];
|
|
651
|
+
var DATA_FILE3 = path3.join(process.env.HOME || "~", ".make-laten", "corrections.json");
|
|
553
652
|
var AutoCorrect = class {
|
|
554
|
-
rules
|
|
653
|
+
rules;
|
|
555
654
|
corrections = [];
|
|
556
655
|
appliedCount = 0;
|
|
656
|
+
persistencePath;
|
|
657
|
+
constructor(options) {
|
|
658
|
+
this.persistencePath = options?.persistencePath || DATA_FILE3;
|
|
659
|
+
this.rules = [...DEFAULT_RULES];
|
|
660
|
+
this.loadPersistedRules();
|
|
661
|
+
}
|
|
662
|
+
loadPersistedRules() {
|
|
663
|
+
try {
|
|
664
|
+
if (fs3.existsSync(this.persistencePath)) {
|
|
665
|
+
const data = JSON.parse(fs3.readFileSync(this.persistencePath, "utf-8"));
|
|
666
|
+
if (Array.isArray(data.customRules)) {
|
|
667
|
+
this.rules.push(...data.customRules);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
} catch {
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
persistRules() {
|
|
674
|
+
try {
|
|
675
|
+
const dir = path3.dirname(this.persistencePath);
|
|
676
|
+
if (!fs3.existsSync(dir)) fs3.mkdirSync(dir, { recursive: true });
|
|
677
|
+
const existing = this.loadExistingData();
|
|
678
|
+
existing.customRules = this.rules.filter((r) => !DEFAULT_RULES.includes(r));
|
|
679
|
+
fs3.writeFileSync(this.persistencePath, JSON.stringify(existing, null, 2));
|
|
680
|
+
} catch {
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
loadExistingData() {
|
|
684
|
+
try {
|
|
685
|
+
if (fs3.existsSync(this.persistencePath)) {
|
|
686
|
+
return JSON.parse(fs3.readFileSync(this.persistencePath, "utf-8"));
|
|
687
|
+
}
|
|
688
|
+
} catch {
|
|
689
|
+
}
|
|
690
|
+
return { customRules: [] };
|
|
691
|
+
}
|
|
557
692
|
addRule(rule) {
|
|
558
693
|
this.rules.push(rule);
|
|
694
|
+
this.persistRules();
|
|
559
695
|
}
|
|
560
696
|
getRules() {
|
|
561
697
|
return this.rules;
|
|
562
698
|
}
|
|
563
699
|
correct(input) {
|
|
564
700
|
let output = input;
|
|
701
|
+
let changed = false;
|
|
565
702
|
for (const rule of this.rules) {
|
|
566
703
|
if (typeof rule.pattern === "string") {
|
|
567
704
|
if (output.includes(rule.pattern)) {
|
|
568
705
|
output = output.split(rule.pattern).join(rule.replacement);
|
|
569
|
-
|
|
706
|
+
changed = true;
|
|
570
707
|
}
|
|
571
708
|
} else {
|
|
572
709
|
const matches = output.match(rule.pattern);
|
|
573
710
|
if (matches) {
|
|
574
711
|
output = output.replace(rule.pattern, rule.replacement);
|
|
575
|
-
|
|
712
|
+
changed = true;
|
|
576
713
|
}
|
|
577
714
|
}
|
|
578
715
|
}
|
|
716
|
+
if (changed) {
|
|
717
|
+
this.recordCorrection(input, output, "auto");
|
|
718
|
+
}
|
|
579
719
|
return output;
|
|
580
720
|
}
|
|
581
721
|
getStats() {
|
|
@@ -959,7 +1099,7 @@ function extractSimpleTitle(html) {
|
|
|
959
1099
|
// src/mcp/server.ts
|
|
960
1100
|
import { exec } from "child_process";
|
|
961
1101
|
import { promisify } from "util";
|
|
962
|
-
import
|
|
1102
|
+
import fs4 from "fs/promises";
|
|
963
1103
|
var execAsync = promisify(exec);
|
|
964
1104
|
var sessionCache = new SessionCache();
|
|
965
1105
|
var toolRouter = new ToolRouter();
|
|
@@ -1069,17 +1209,17 @@ var TOOLS = [
|
|
|
1069
1209
|
// Learn Layer
|
|
1070
1210
|
{
|
|
1071
1211
|
name: "make-laten-patterns",
|
|
1072
|
-
description: "Get learned patterns from usage",
|
|
1212
|
+
description: "Get learned patterns from usage (persisted across sessions)",
|
|
1073
1213
|
inputSchema: { type: "object", properties: {} }
|
|
1074
1214
|
},
|
|
1075
1215
|
{
|
|
1076
1216
|
name: "make-laten-failures",
|
|
1077
|
-
description: "Get failure records and suggestions",
|
|
1217
|
+
description: "Get failure records and suggestions (persisted across sessions)",
|
|
1078
1218
|
inputSchema: { type: "object", properties: {} }
|
|
1079
1219
|
},
|
|
1080
1220
|
{
|
|
1081
1221
|
name: "make-laten-suggestions",
|
|
1082
|
-
description: "Get suggestions based on learned patterns",
|
|
1222
|
+
description: "Get suggestions based on learned patterns and failures",
|
|
1083
1223
|
inputSchema: {
|
|
1084
1224
|
type: "object",
|
|
1085
1225
|
properties: {
|
|
@@ -1090,7 +1230,7 @@ var TOOLS = [
|
|
|
1090
1230
|
// Correct Layer
|
|
1091
1231
|
{
|
|
1092
1232
|
name: "make-laten-correct",
|
|
1093
|
-
description: "Apply auto-corrections to text",
|
|
1233
|
+
description: "Apply auto-corrections to text (11 built-in rules + custom rules)",
|
|
1094
1234
|
inputSchema: {
|
|
1095
1235
|
type: "object",
|
|
1096
1236
|
properties: {
|
|
@@ -1151,7 +1291,7 @@ function detectLanguage(filePath) {
|
|
|
1151
1291
|
return map[ext] || "text";
|
|
1152
1292
|
}
|
|
1153
1293
|
async function handleRead(params) {
|
|
1154
|
-
const content = await
|
|
1294
|
+
const content = await fs4.readFile(params.file_path, "utf-8");
|
|
1155
1295
|
const compressor = new FileReadCompressor();
|
|
1156
1296
|
const result = await compressor.compress({
|
|
1157
1297
|
content,
|
|
@@ -1293,7 +1433,7 @@ async function handleLine(line) {
|
|
|
1293
1433
|
sendResponse(request.id, {
|
|
1294
1434
|
protocolVersion: "2024-11-05",
|
|
1295
1435
|
capabilities: { tools: {} },
|
|
1296
|
-
serverInfo: { name: "make-laten", version: "1.
|
|
1436
|
+
serverInfo: { name: "make-laten", version: "1.3.0" }
|
|
1297
1437
|
});
|
|
1298
1438
|
} else if (request.method === "notifications/initialized") {
|
|
1299
1439
|
} else if (request.method === "tools/list") {
|