@nxuss/lemma 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -2
- package/dist/cjs/autopilot/AutopilotWatcher.d.ts +3 -2
- package/dist/cjs/autopilot/AutopilotWatcher.d.ts.map +1 -1
- package/dist/cjs/autopilot/AutopilotWatcher.js +48 -54
- package/dist/cjs/autopilot/AutopilotWatcher.js.map +1 -1
- package/dist/cjs/autopilot/Notifier.d.ts +5 -0
- package/dist/cjs/autopilot/Notifier.d.ts.map +1 -0
- package/dist/cjs/autopilot/Notifier.js +59 -0
- package/dist/cjs/autopilot/Notifier.js.map +1 -0
- package/dist/cjs/autopilot/PatchStore.d.ts +26 -0
- package/dist/cjs/autopilot/PatchStore.d.ts.map +1 -0
- package/dist/cjs/autopilot/PatchStore.js +88 -0
- package/dist/cjs/autopilot/PatchStore.js.map +1 -0
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +121 -0
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +11 -6
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/esm/autopilot/AutopilotWatcher.d.ts +3 -2
- package/dist/esm/autopilot/AutopilotWatcher.d.ts.map +1 -1
- package/dist/esm/autopilot/AutopilotWatcher.js +48 -54
- package/dist/esm/autopilot/AutopilotWatcher.js.map +1 -1
- package/dist/esm/autopilot/Notifier.d.ts +5 -0
- package/dist/esm/autopilot/Notifier.d.ts.map +1 -0
- package/dist/esm/autopilot/Notifier.js +51 -0
- package/dist/esm/autopilot/Notifier.js.map +1 -0
- package/dist/esm/autopilot/PatchStore.d.ts +26 -0
- package/dist/esm/autopilot/PatchStore.d.ts.map +1 -0
- package/dist/esm/autopilot/PatchStore.js +77 -0
- package/dist/esm/autopilot/PatchStore.js.map +1 -0
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +121 -0
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +11 -6
- package/dist/esm/mcp/tools.js.map +1 -1
- package/mcp-server.js +6 -6
- package/package.json +3 -2
|
@@ -3,9 +3,10 @@ export declare class AutopilotWatcher {
|
|
|
3
3
|
private watchDir;
|
|
4
4
|
private debounceTimer;
|
|
5
5
|
private activeBuildProcess;
|
|
6
|
-
|
|
6
|
+
private nonInvasive;
|
|
7
|
+
constructor(watchDir?: string, nonInvasive?: boolean);
|
|
7
8
|
start(): void;
|
|
8
|
-
private
|
|
9
|
+
private triggerBuild;
|
|
9
10
|
stop(): void;
|
|
10
11
|
}
|
|
11
12
|
//# sourceMappingURL=AutopilotWatcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutopilotWatcher.d.ts","sourceRoot":"","sources":["../../../src/autopilot/AutopilotWatcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AutopilotWatcher.d.ts","sourceRoot":"","sources":["../../../src/autopilot/AutopilotWatcher.ts"],"names":[],"mappings":"AAOA,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,WAAW,CAAS;gBAEhB,QAAQ,GAAE,MAAc,EAAE,WAAW,GAAE,OAAc;IAKjE,KAAK;IAoBL,OAAO,CAAC,YAAY;IA6EpB,IAAI;CAML"}
|
|
@@ -2,42 +2,41 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { exec } from 'child_process';
|
|
4
4
|
import { performAutoHeal } from '../cli/lemma-proxy';
|
|
5
|
+
import { savePatch, countPending } from './PatchStore';
|
|
6
|
+
import { notifyPatch } from './Notifier';
|
|
5
7
|
export class AutopilotWatcher {
|
|
6
|
-
constructor(watchDir = 'src') {
|
|
8
|
+
constructor(watchDir = 'src', nonInvasive = true) {
|
|
7
9
|
this.isRunning = false;
|
|
8
10
|
this.debounceTimer = null;
|
|
9
11
|
this.activeBuildProcess = null;
|
|
10
12
|
this.watchDir = path.resolve(process.cwd(), watchDir);
|
|
13
|
+
this.nonInvasive = nonInvasive;
|
|
11
14
|
}
|
|
12
15
|
start() {
|
|
13
16
|
if (this.isRunning)
|
|
14
17
|
return;
|
|
15
18
|
this.isRunning = true;
|
|
16
|
-
console.log(`\n🛸 \x1b[35m[
|
|
17
|
-
console.log(`💡 \x1b[
|
|
19
|
+
console.log(`\n🛸 \x1b[35m[Lemma Watch]\x1b[0m Silent background watcher on: ${this.watchDir}`);
|
|
20
|
+
console.log(`💡 \x1b[36mWill silently detect and store fixes. Use \x1b[1mlemma patches\x1b[0m\x1b[36m to see them.\x1b[0m\n`);
|
|
18
21
|
if (!fs.existsSync(this.watchDir)) {
|
|
19
22
|
console.log(`⚠️ Watch directory ${this.watchDir} does not exist. Creating it.`);
|
|
20
23
|
fs.mkdirSync(this.watchDir, { recursive: true });
|
|
21
24
|
}
|
|
22
|
-
// Watch files recursively natively (mac supports recursive natively)
|
|
23
25
|
fs.watch(this.watchDir, { recursive: true }, (eventType, filename) => {
|
|
24
26
|
if (!filename || filename.endsWith('.fixed') || filename.includes('.lemma'))
|
|
25
27
|
return;
|
|
26
|
-
// Debounce trigger
|
|
27
28
|
if (this.debounceTimer)
|
|
28
29
|
clearTimeout(this.debounceTimer);
|
|
29
30
|
this.debounceTimer = setTimeout(() => {
|
|
30
|
-
this.
|
|
31
|
+
this.triggerBuild(filename);
|
|
31
32
|
}, 1500);
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
+
triggerBuild(modifiedFile) {
|
|
35
36
|
if (this.activeBuildProcess) {
|
|
36
37
|
this.activeBuildProcess.kill();
|
|
37
38
|
this.activeBuildProcess = null;
|
|
38
39
|
}
|
|
39
|
-
console.log(`\n📝 \x1b[33m[Autopilot]\x1b[0m Change detected in ${modifiedFile}. Running background compilation...`);
|
|
40
|
-
// Determine the project root by searching upwards for package.json or tsconfig.json
|
|
41
40
|
let projectRoot = this.watchDir;
|
|
42
41
|
while (projectRoot && projectRoot !== '/' && !fs.existsSync(path.join(projectRoot, 'package.json')) && !fs.existsSync(path.join(projectRoot, 'tsconfig.json'))) {
|
|
43
42
|
const parent = path.dirname(projectRoot);
|
|
@@ -48,65 +47,60 @@ export class AutopilotWatcher {
|
|
|
48
47
|
if (!fs.existsSync(path.join(projectRoot, 'package.json')) && !fs.existsSync(path.join(projectRoot, 'tsconfig.json'))) {
|
|
49
48
|
projectRoot = process.cwd();
|
|
50
49
|
}
|
|
51
|
-
// Determine the build/validation command
|
|
52
50
|
let cmd = 'npx tsc --noEmit';
|
|
53
51
|
if (!fs.existsSync(path.join(projectRoot, 'tsconfig.json'))) {
|
|
54
|
-
cmd = 'npm run build';
|
|
52
|
+
cmd = 'npm run build 2>&1 || true';
|
|
55
53
|
}
|
|
56
54
|
this.activeBuildProcess = exec(cmd, { cwd: projectRoot }, async (error, stdout, stderr) => {
|
|
57
55
|
this.activeBuildProcess = null;
|
|
58
|
-
if (!error)
|
|
59
|
-
console.log(`✨ \x1b[32m[Autopilot] Build compiled perfectly!\x1b[0m`);
|
|
56
|
+
if (!error)
|
|
60
57
|
return;
|
|
61
|
-
}
|
|
62
58
|
const output = stdout + '\n' + stderr;
|
|
63
|
-
|
|
64
|
-
// Parse TypeScript compiler output
|
|
65
|
-
// Standard format: src/utils/ContextSqueezer.ts:130:50 - error TS7006: Parameter 'match' implicitly has an 'any' type.
|
|
66
|
-
const tsErrorRegex = /([^\s\n]+\.ts)[\s\(:]+(\d+)[\s,:]+(\d+)?[\s\)]*[\s-:]+error\s+([^\n]+)/;
|
|
59
|
+
const tsErrorRegex = /([^\s\n]+\.(?:ts|tsx|js|jsx))[\s\(:]+(\d+)[\s,:]+(\d+)?[\s\)]*[\s-:]+error\s+(TS\d+):\s+([^\n]+)/;
|
|
67
60
|
const match = output.match(tsErrorRegex);
|
|
68
|
-
if (match)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
const absoluteFile = path.resolve(projectRoot, file);
|
|
83
|
-
const liveContextContent = `# Autopilot Telemetry Crash Report
|
|
61
|
+
if (!match)
|
|
62
|
+
return;
|
|
63
|
+
const [, file, line, , errorCode, errorMsg] = match;
|
|
64
|
+
const absoluteFile = path.resolve(projectRoot, file);
|
|
65
|
+
const relFile = path.relative(projectRoot, absoluteFile) || file;
|
|
66
|
+
const contextDirs = [
|
|
67
|
+
path.join(projectRoot, '.lemma'),
|
|
68
|
+
path.join(process.cwd(), '.lemma')
|
|
69
|
+
];
|
|
70
|
+
for (const dir of contextDirs) {
|
|
71
|
+
if (!fs.existsSync(dir))
|
|
72
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
73
|
+
const content = `# Lemma Watch Crash Report
|
|
84
74
|
Timestamp: ${new Date().toISOString()}
|
|
85
75
|
Message: ${errorMsg} in ${absoluteFile}:${line}
|
|
76
|
+
Error: ${errorCode}
|
|
86
77
|
Stack:
|
|
87
78
|
at ${absoluteFile}:${line}:0
|
|
88
79
|
`;
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
// Execute performAutoHeal in apply mode!
|
|
92
|
-
console.log(`⚡ \x1b[35m[Autopilot] Calling auto-healing agent...\x1b[0m`);
|
|
93
|
-
try {
|
|
94
|
-
const res = await performAutoHeal(true);
|
|
95
|
-
if (res.success) {
|
|
96
|
-
console.log(`✔ \x1b[32m[Autopilot] Auto-healed: ${res.message}\x1b[0m\n`);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
console.log(`⚠️ \x1b[33m[Autopilot] Healing agent failed: ${res.message}\x1b[0m\n`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
catch (err) {
|
|
103
|
-
console.log(`⚠️ \x1b[33m[Autopilot] Healing agent error: ${err.message}\x1b[0m\n`);
|
|
104
|
-
}
|
|
80
|
+
fs.writeFileSync(path.join(dir, 'live-context.md'), content, 'utf8');
|
|
105
81
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
82
|
+
try {
|
|
83
|
+
const res = await performAutoHeal(false);
|
|
84
|
+
if (!res.success || !res.fileAfter)
|
|
85
|
+
return;
|
|
86
|
+
const patch = savePatch({
|
|
87
|
+
filePath: relFile,
|
|
88
|
+
line: parseInt(line, 10),
|
|
89
|
+
errorCode: errorCode || 'UNKNOWN',
|
|
90
|
+
errorMsg,
|
|
91
|
+
explanation: res.message,
|
|
92
|
+
patch: res.patch || '',
|
|
93
|
+
fileBefore: res.fileBefore || '',
|
|
94
|
+
fileAfter: res.fileAfter,
|
|
95
|
+
});
|
|
96
|
+
notifyPatch(patch);
|
|
97
|
+
const pending = countPending();
|
|
98
|
+
console.log(`\n🩺 \x1b[35m[Lemma Watch]\x1b[0m ${errorCode} in ${relFile}:${line}`);
|
|
99
|
+
console.log(` \x1b[33m${errorMsg.substring(0, 100)}\x1b[0m`);
|
|
100
|
+
console.log(` \x1b[36mFix ready → \x1b[1mlemma apply ${patch.id}\x1b[0m`);
|
|
101
|
+
console.log(` \x1b[90m${pending} pending fix${pending !== 1 ? 'es' : ''} total\x1b[0m\n`);
|
|
109
102
|
}
|
|
103
|
+
catch { }
|
|
110
104
|
});
|
|
111
105
|
}
|
|
112
106
|
stop() {
|
|
@@ -115,7 +109,7 @@ Stack:
|
|
|
115
109
|
clearTimeout(this.debounceTimer);
|
|
116
110
|
if (this.activeBuildProcess)
|
|
117
111
|
this.activeBuildProcess.kill();
|
|
118
|
-
console.log(
|
|
112
|
+
console.log(`\n🛸 \x1b[35m[Lemma Watch]\x1b[0m Background watcher stopped.`);
|
|
119
113
|
}
|
|
120
114
|
}
|
|
121
115
|
//# sourceMappingURL=AutopilotWatcher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutopilotWatcher.js","sourceRoot":"","sources":["../../../src/autopilot/AutopilotWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"AutopilotWatcher.js","sourceRoot":"","sources":["../../../src/autopilot/AutopilotWatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Patch } from './PatchStore';
|
|
2
|
+
export declare function sendNotification(title: string, subtitle: string, message: string): void;
|
|
3
|
+
export declare function notifyPatch(patch: Patch): void;
|
|
4
|
+
export declare function notifyClear(): void;
|
|
5
|
+
//# sourceMappingURL=Notifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Notifier.d.ts","sourceRoot":"","sources":["../../../src/autopilot/Notifier.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AAyBzC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAKvF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAO9C;AAgBD,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
const DASHBOARD_API_BASE = 'http://localhost:8081';
|
|
5
|
+
const LEMMA_ICON = path.join(__dirname, '..', '..', 'assets', 'icon.png');
|
|
6
|
+
function osascriptNotify(title, subtitle, message) {
|
|
7
|
+
try {
|
|
8
|
+
execSync(`osascript -e 'display notification "${message.replace(/"/g, '\\"')}" with title "${title.replace(/"/g, '\\"')}" subtitle "${subtitle.replace(/"/g, '\\"')}" sound name "default"'`, { timeout: 3000 });
|
|
9
|
+
}
|
|
10
|
+
catch { }
|
|
11
|
+
}
|
|
12
|
+
function terminalNotifierNotify(title, subtitle, message) {
|
|
13
|
+
try {
|
|
14
|
+
execSync(`terminal-notifier -title "${title.replace(/"/g, '\\"')}" -subtitle "${subtitle.replace(/"/g, '\\"')}" -message "${message.replace(/"/g, '\\"')}" -sound default -timeout 10`, { timeout: 3000 });
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
osascriptNotify(title, subtitle, message);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function sendNotification(title, subtitle, message) {
|
|
21
|
+
if (process.platform === 'darwin') {
|
|
22
|
+
if (process.env.CI || process.env.NO_NOTIFY)
|
|
23
|
+
return;
|
|
24
|
+
terminalNotifierNotify(title, subtitle, message);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function notifyPatch(patch) {
|
|
28
|
+
const title = `🩺 Lemma: ${patch.errorCode}`;
|
|
29
|
+
const subtitle = `${path.basename(patch.filePath)}:${patch.line}`;
|
|
30
|
+
const msg = patch.explanation.substring(0, 120);
|
|
31
|
+
sendNotification(title, subtitle, msg);
|
|
32
|
+
pushToDashboard(patch);
|
|
33
|
+
}
|
|
34
|
+
async function pushToDashboard(patch) {
|
|
35
|
+
try {
|
|
36
|
+
await axios.post(`${DASHBOARD_API_BASE}/api/patches/notify`, {
|
|
37
|
+
id: patch.id,
|
|
38
|
+
filePath: patch.filePath,
|
|
39
|
+
line: patch.line,
|
|
40
|
+
errorCode: patch.errorCode,
|
|
41
|
+
errorMsg: patch.errorMsg,
|
|
42
|
+
explanation: patch.explanation,
|
|
43
|
+
timestamp: patch.timestamp,
|
|
44
|
+
}, { timeout: 1000 });
|
|
45
|
+
}
|
|
46
|
+
catch { }
|
|
47
|
+
}
|
|
48
|
+
export function notifyClear() {
|
|
49
|
+
sendNotification('Lemma', 'All patches applied', '✨ No pending fixes');
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=Notifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Notifier.js","sourceRoot":"","sources":["../../../src/autopilot/Notifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,IAAI,MAAM,MAAM,CAAA;AAIvB,MAAM,kBAAkB,GAAG,uBAAuB,CAAA;AAClD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;AAEzE,SAAS,eAAe,CAAC,KAAa,EAAE,QAAgB,EAAE,OAAe;IACvE,IAAI,CAAC;QACH,QAAQ,CACN,uCAAuC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,iBAAiB,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,eAAe,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,yBAAyB,EACnL,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB,CAAA;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAa,EAAE,QAAgB,EAAE,OAAe;IAC9E,IAAI,CAAC;QACH,QAAQ,CACN,6BAA6B,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,gBAAgB,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,eAAe,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,8BAA8B,EAC7K,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB,CAAA;IACH,CAAC;IAAC,MAAM,CAAC;QACP,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,QAAgB,EAAE,OAAe;IAC/E,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS;YAAE,OAAM;QACnD,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;IAClD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAY;IACtC,MAAM,KAAK,GAAG,aAAa,KAAK,CAAC,SAAS,EAAE,CAAA;IAC5C,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAA;IACjE,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAE/C,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAA;IACtC,eAAe,CAAC,KAAK,CAAC,CAAA;AACxB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,KAAY;IACzC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,kBAAkB,qBAAqB,EAAE;YAC3D,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAA;AACxE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface Patch {
|
|
2
|
+
id: string;
|
|
3
|
+
filePath: string;
|
|
4
|
+
line: number;
|
|
5
|
+
errorCode: string;
|
|
6
|
+
errorMsg: string;
|
|
7
|
+
explanation: string;
|
|
8
|
+
patch: string;
|
|
9
|
+
fileBefore: string;
|
|
10
|
+
fileAfter: string;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
status: 'pending' | 'applied' | 'discarded';
|
|
13
|
+
}
|
|
14
|
+
export declare function savePatch(meta: Omit<Patch, 'id' | 'timestamp' | 'status'>): Patch;
|
|
15
|
+
export declare function listPatches(status?: Patch['status']): Patch[];
|
|
16
|
+
export declare function getPatch(id: string): Patch | null;
|
|
17
|
+
export declare function applyPatch(id: string): {
|
|
18
|
+
success: boolean;
|
|
19
|
+
message: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function discardPatch(id: string): {
|
|
22
|
+
success: boolean;
|
|
23
|
+
message: string;
|
|
24
|
+
};
|
|
25
|
+
export declare function countPending(): number;
|
|
26
|
+
//# sourceMappingURL=PatchStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PatchStore.d.ts","sourceRoot":"","sources":["../../../src/autopilot/PatchStore.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,CAAA;CAC5C;AAUD,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,WAAW,GAAG,QAAQ,CAAC,GAAG,KAAK,CASjF;AAED,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,EAAE,CAa7D;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CASjD;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAgB5E;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAO9E;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
const PATCHES_DIR = path.join(process.cwd(), '.lemma', 'patches');
|
|
4
|
+
function ensureDir() {
|
|
5
|
+
if (!fs.existsSync(PATCHES_DIR)) {
|
|
6
|
+
fs.mkdirSync(PATCHES_DIR, { recursive: true });
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export function savePatch(meta) {
|
|
10
|
+
ensureDir();
|
|
11
|
+
const errorSlug = meta.errorCode.toLowerCase().replace(/\s+/g, '-');
|
|
12
|
+
const fileSlug = path.basename(meta.filePath).replace(/\./g, '-');
|
|
13
|
+
const id = `${errorSlug}-${fileSlug}-${Date.now()}`;
|
|
14
|
+
const patch = { ...meta, id, timestamp: Date.now(), status: 'pending' };
|
|
15
|
+
const filePath = path.join(PATCHES_DIR, `${id}.json`);
|
|
16
|
+
fs.writeFileSync(filePath, JSON.stringify(patch, null, 2));
|
|
17
|
+
return patch;
|
|
18
|
+
}
|
|
19
|
+
export function listPatches(status) {
|
|
20
|
+
ensureDir();
|
|
21
|
+
const files = fs.readdirSync(PATCHES_DIR).filter(f => f.endsWith('.json'));
|
|
22
|
+
const patches = [];
|
|
23
|
+
for (const f of files) {
|
|
24
|
+
try {
|
|
25
|
+
const p = JSON.parse(fs.readFileSync(path.join(PATCHES_DIR, f), 'utf8'));
|
|
26
|
+
patches.push(p);
|
|
27
|
+
}
|
|
28
|
+
catch { }
|
|
29
|
+
}
|
|
30
|
+
patches.sort((a, b) => b.timestamp - a.timestamp);
|
|
31
|
+
if (status)
|
|
32
|
+
return patches.filter(p => p.status === status);
|
|
33
|
+
return patches;
|
|
34
|
+
}
|
|
35
|
+
export function getPatch(id) {
|
|
36
|
+
ensureDir();
|
|
37
|
+
const filePath = path.join(PATCHES_DIR, `${id}.json`);
|
|
38
|
+
if (!fs.existsSync(filePath))
|
|
39
|
+
return null;
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function applyPatch(id) {
|
|
48
|
+
const patch = getPatch(id);
|
|
49
|
+
if (!patch)
|
|
50
|
+
return { success: false, message: `Patch ${id} not found` };
|
|
51
|
+
if (patch.status === 'applied')
|
|
52
|
+
return { success: false, message: `Patch ${id} already applied` };
|
|
53
|
+
if (patch.status === 'discarded')
|
|
54
|
+
return { success: false, message: `Patch ${id} was discarded` };
|
|
55
|
+
const targetFile = path.resolve(process.cwd(), patch.filePath);
|
|
56
|
+
if (!fs.existsSync(targetFile)) {
|
|
57
|
+
return { success: false, message: `File ${patch.filePath} no longer exists` };
|
|
58
|
+
}
|
|
59
|
+
fs.writeFileSync(targetFile, patch.fileAfter, 'utf8');
|
|
60
|
+
patch.status = 'applied';
|
|
61
|
+
const filePath = path.join(PATCHES_DIR, `${id}.json`);
|
|
62
|
+
fs.writeFileSync(filePath, JSON.stringify(patch, null, 2));
|
|
63
|
+
return { success: true, message: `Applied fix for ${patch.errorCode} in ${patch.filePath}` };
|
|
64
|
+
}
|
|
65
|
+
export function discardPatch(id) {
|
|
66
|
+
const patch = getPatch(id);
|
|
67
|
+
if (!patch)
|
|
68
|
+
return { success: false, message: `Patch ${id} not found` };
|
|
69
|
+
patch.status = 'discarded';
|
|
70
|
+
const filePath = path.join(PATCHES_DIR, `${id}.json`);
|
|
71
|
+
fs.writeFileSync(filePath, JSON.stringify(patch, null, 2));
|
|
72
|
+
return { success: true, message: `Patch ${id} discarded` };
|
|
73
|
+
}
|
|
74
|
+
export function countPending() {
|
|
75
|
+
return listPatches('pending').length;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=PatchStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PatchStore.js","sourceRoot":"","sources":["../../../src/autopilot/PatchStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AAgBvB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;AAEjE,SAAS,SAAS;IAChB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAChD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAgD;IACxE,SAAS,EAAE,CAAA;IACX,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACjE,MAAM,EAAE,GAAG,GAAG,SAAS,IAAI,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;IACnD,MAAM,KAAK,GAAU,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IAC9E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACrD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC1D,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAwB;IAClD,SAAS,EAAE,CAAA;IACX,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;IAC1E,MAAM,OAAO,GAAY,EAAE,CAAA;IAC3B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAU,CAAA;YACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAA;IACjD,IAAI,MAAM;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;IAC3D,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EAAU;IACjC,SAAS,EAAE,CAAA;IACX,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IACzC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAU,CAAA;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC1B,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAA;IACvE,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAA;IACjG,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAA;IAEjG,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC9D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,KAAK,CAAC,QAAQ,mBAAmB,EAAE,CAAA;IAC/E,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IACrD,KAAK,CAAC,MAAM,GAAG,SAAS,CAAA;IACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACrD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC1D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,mBAAmB,KAAK,CAAC,SAAS,OAAO,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAA;AAC9F,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAU;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC1B,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAA;IACvE,KAAK,CAAC,MAAM,GAAG,WAAW,CAAA;IAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACrD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC1D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAA;AAC5D,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAA;AACtC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lemma-proxy.d.ts","sourceRoot":"","sources":["../../../src/cli/lemma-proxy.ts"],"names":[],"mappings":";AA2cA,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA4DvF;
|
|
1
|
+
{"version":3,"file":"lemma-proxy.d.ts","sourceRoot":"","sources":["../../../src/cli/lemma-proxy.ts"],"names":[],"mappings":";AA2cA,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA4DvF;AAijED,wBAAsB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6KhL"}
|
|
@@ -1529,6 +1529,51 @@ class LemmaServer {
|
|
|
1529
1529
|
});
|
|
1530
1530
|
this.app.get('/dashboard/*', (req, res) => res.sendFile(path.join(this.dashboardPath, 'index.html')));
|
|
1531
1531
|
}
|
|
1532
|
+
// Patch API — works regardless of dashboard
|
|
1533
|
+
this.app.post('/api/patches/notify', (req, res) => {
|
|
1534
|
+
const patch = req.body;
|
|
1535
|
+
if (!patch.id)
|
|
1536
|
+
return res.status(400).json({ error: 'Missing patch id' });
|
|
1537
|
+
logEvent({
|
|
1538
|
+
type: 'patch:available',
|
|
1539
|
+
patchId: patch.id,
|
|
1540
|
+
filePath: patch.filePath,
|
|
1541
|
+
line: patch.line,
|
|
1542
|
+
errorCode: patch.errorCode,
|
|
1543
|
+
timestamp: patch.timestamp,
|
|
1544
|
+
});
|
|
1545
|
+
res.json({ success: true });
|
|
1546
|
+
});
|
|
1547
|
+
this.app.get('/api/patches', (req, res) => {
|
|
1548
|
+
try {
|
|
1549
|
+
const { listPatches } = require('../autopilot/PatchStore');
|
|
1550
|
+
const patches = listPatches();
|
|
1551
|
+
res.json({ patches });
|
|
1552
|
+
}
|
|
1553
|
+
catch (err) {
|
|
1554
|
+
res.status(500).json({ error: err.message });
|
|
1555
|
+
}
|
|
1556
|
+
});
|
|
1557
|
+
this.app.post('/api/patches/:id/apply', (req, res) => {
|
|
1558
|
+
try {
|
|
1559
|
+
const { applyPatch } = require('../autopilot/PatchStore');
|
|
1560
|
+
const result = applyPatch(req.params.id);
|
|
1561
|
+
res.json(result);
|
|
1562
|
+
}
|
|
1563
|
+
catch (err) {
|
|
1564
|
+
res.status(500).json({ error: err.message });
|
|
1565
|
+
}
|
|
1566
|
+
});
|
|
1567
|
+
this.app.post('/api/patches/:id/discard', (req, res) => {
|
|
1568
|
+
try {
|
|
1569
|
+
const { discardPatch } = require('../autopilot/PatchStore');
|
|
1570
|
+
const result = discardPatch(req.params.id);
|
|
1571
|
+
res.json(result);
|
|
1572
|
+
}
|
|
1573
|
+
catch (err) {
|
|
1574
|
+
res.status(500).json({ error: err.message });
|
|
1575
|
+
}
|
|
1576
|
+
});
|
|
1532
1577
|
// Mount PR Review webhook endpoints
|
|
1533
1578
|
const { createWebhookRouter } = require('../pr-review/webhook/WebhookServer');
|
|
1534
1579
|
this.app.use('/api/webhook', createWebhookRouter());
|
|
@@ -2539,6 +2584,82 @@ Ensure you return strictly JSON. Do not return any other text outside the JSON b
|
|
|
2539
2584
|
}
|
|
2540
2585
|
}
|
|
2541
2586
|
}
|
|
2587
|
+
program.command('watch')
|
|
2588
|
+
.description('Start silent background watcher — detects compile errors and saves patches without applying')
|
|
2589
|
+
.option('--dir <directory>', 'Directory to monitor for changes', 'src')
|
|
2590
|
+
.action(async (opts) => {
|
|
2591
|
+
try {
|
|
2592
|
+
const { AutopilotWatcher } = require('../autopilot/AutopilotWatcher');
|
|
2593
|
+
const watcher = new AutopilotWatcher(opts.dir, true);
|
|
2594
|
+
watcher.start();
|
|
2595
|
+
process.stdin.resume();
|
|
2596
|
+
process.on('SIGINT', () => {
|
|
2597
|
+
watcher.stop();
|
|
2598
|
+
process.exit(0);
|
|
2599
|
+
});
|
|
2600
|
+
}
|
|
2601
|
+
catch (err) {
|
|
2602
|
+
console.error('❌ Error starting watcher:', err.message);
|
|
2603
|
+
process.exit(1);
|
|
2604
|
+
}
|
|
2605
|
+
});
|
|
2606
|
+
program.command('patches')
|
|
2607
|
+
.description('List available patches from the silent watcher')
|
|
2608
|
+
.option('--pending', 'Show only pending patches')
|
|
2609
|
+
.option('--all', 'Show all patches (including applied/discarded)')
|
|
2610
|
+
.action((opts) => {
|
|
2611
|
+
const { listPatches, countPending } = require('../autopilot/PatchStore');
|
|
2612
|
+
const status = opts.pending ? 'pending' : undefined;
|
|
2613
|
+
const showAll = opts.all;
|
|
2614
|
+
const patches = showAll ? listPatches() : listPatches(status);
|
|
2615
|
+
const pending = patches.filter((p) => p.status === 'pending');
|
|
2616
|
+
const applied = patches.filter((p) => p.status === 'applied');
|
|
2617
|
+
const discarded = patches.filter((p) => p.status === 'discarded');
|
|
2618
|
+
if (patches.length === 0) {
|
|
2619
|
+
console.log(`\n📋 \x1b[1mLemma Patches\x1b[0m — No patches found.\n`);
|
|
2620
|
+
return;
|
|
2621
|
+
}
|
|
2622
|
+
console.log(`\n📋 \x1b[1mLemma Patches\x1b[0m`);
|
|
2623
|
+
console.log(` ${pending.length} pending | ${applied.length} applied | ${discarded.length} discarded\n`);
|
|
2624
|
+
for (const p of patches) {
|
|
2625
|
+
const date = new Date(p.timestamp).toLocaleTimeString();
|
|
2626
|
+
const statusIcon = p.status === 'pending' ? '\x1b[33m⏳\x1b[0m' : p.status === 'applied' ? '\x1b[32m✔\x1b[0m' : '\x1b[90m✖\x1b[0m';
|
|
2627
|
+
console.log(` ${statusIcon} \x1b[1m${p.id}\x1b[0m`);
|
|
2628
|
+
console.log(` ${p.errorCode} in ${p.filePath}:${p.line}`);
|
|
2629
|
+
console.log(` \x1b[90m${p.errorMsg.substring(0, 100)}\x1b[0m`);
|
|
2630
|
+
console.log(` \x1b[90m${date}\x1b[0m`);
|
|
2631
|
+
if (p.status === 'pending') {
|
|
2632
|
+
console.log(` → \x1b[36mlemma apply ${p.id}\x1b[0m | \x1b[2mlemma discard ${p.id}\x1b[0m`);
|
|
2633
|
+
}
|
|
2634
|
+
console.log();
|
|
2635
|
+
}
|
|
2636
|
+
});
|
|
2637
|
+
program.command('apply <id>')
|
|
2638
|
+
.description('Apply a pending fix patch')
|
|
2639
|
+
.action((id) => {
|
|
2640
|
+
const { applyPatch } = require('../autopilot/PatchStore');
|
|
2641
|
+
const res = applyPatch(id);
|
|
2642
|
+
if (res.success) {
|
|
2643
|
+
console.log(`\n✔ \x1b[32m${res.message}\x1b[0m\n`);
|
|
2644
|
+
}
|
|
2645
|
+
else {
|
|
2646
|
+
console.log(`\n❌ \x1b[31m${res.message}\x1b[0m\n`);
|
|
2647
|
+
process.exit(1);
|
|
2648
|
+
}
|
|
2649
|
+
});
|
|
2650
|
+
program.command('discard <id>')
|
|
2651
|
+
.description('Discard a pending fix patch')
|
|
2652
|
+
.action((id) => {
|
|
2653
|
+
const { discardPatch } = require('../autopilot/PatchStore');
|
|
2654
|
+
const res = discardPatch(id);
|
|
2655
|
+
if (res.success) {
|
|
2656
|
+
console.log(`\n✖ \x1b[33m${res.message}\x1b[0m\n`);
|
|
2657
|
+
}
|
|
2658
|
+
else {
|
|
2659
|
+
console.log(`\n❌ \x1b[31m${res.message}\x1b[0m\n`);
|
|
2660
|
+
process.exit(1);
|
|
2661
|
+
}
|
|
2662
|
+
});
|
|
2542
2663
|
program.command('heal')
|
|
2543
2664
|
.description('[Pro] Diagnose and auto-heal the latest local server crash from .lemma/live-context.md')
|
|
2544
2665
|
.option('--apply', 'Apply the auto-generated code fix automatically', false)
|