@nxuss/lemma 1.0.0 → 1.0.2
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/lemma-proxy.cjs +13 -3
- package/mcp-server.js +6 -6
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# 🧠 Lemma v1.0.
|
|
1
|
+
# 🧠 Lemma v1.0.1
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@nxuss/lemma)
|
|
4
4
|
[](https://github.com/Nxusbets/lemma/blob/main/LICENSE)
|
|
@@ -117,6 +117,18 @@ Exposes `write_workspace_file`, smart `apply_workspace_patch` (collision-safe se
|
|
|
117
117
|
### 🩺 AutoPilot & Auto-Heal
|
|
118
118
|
Lemma's background file watcher detects TypeScript compilation errors on every save, parses the error, and calls the auto-heal agent to apply a fix — automatically. When Autopilot succeeds, the fix is stored in The Brain for future sessions.
|
|
119
119
|
|
|
120
|
+
### 🕵️ Silent Patch Watcher *(NEW in v1.0.1)*
|
|
121
|
+
**Magia negra, no invasiva.** Like Autopilot, but **never touches your code**. Lemma watches your project silently, detects TypeScript errors on save, generates fixes, and stores them as patches in `.lemma/patches/`. You review with `lemma patches` and apply with `lemma apply <id>`.
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
lemma watch ← starts silently watching src/
|
|
125
|
+
[you save a file with a bug]
|
|
126
|
+
📬 macOS notification ← "Lemma: TS2322 in route.ts:42"
|
|
127
|
+
lemma patches ← shows 1 pending fix
|
|
128
|
+
lemma apply ts2322-... ← applies the fix
|
|
129
|
+
npm run build ← ✅ passes
|
|
130
|
+
```
|
|
131
|
+
|
|
120
132
|
### 🧬 `get_symbol_surgical_context` — Surgical Symbol Context *(NEW in v1.0.0)*
|
|
121
133
|
**Saves up to 90% input tokens.** Instead of reading complete dependency source files, this tool parses your workspace via TS Compiler AST and extracts ONLY the targeted symbol implementation along with the precise function/class signatures of all its direct workspace imports.
|
|
122
134
|
|
|
@@ -160,7 +172,11 @@ lemma start
|
|
|
160
172
|
| `lemma stats` | Real-time token and cost savings metrics. |
|
|
161
173
|
| `lemma mcp` | Starts the stdin/stdout MCP server for IDE integration. |
|
|
162
174
|
| `lemma heal` | Auto-diagnose and repair the latest server crash from live context logs. |
|
|
163
|
-
| `lemma autopilot` | Toggle autonomous background watcher mode. |
|
|
175
|
+
| `lemma autopilot` | Toggle autonomous background watcher mode (auto-applies fixes). |
|
|
176
|
+
| `lemma watch` | **NEW** Silent background watcher — saves patches without touching code. |
|
|
177
|
+
| `lemma patches` | **NEW** List available patches (`--all`, `--pending`). |
|
|
178
|
+
| `lemma apply <id>` | **NEW** Apply a pending fix patch. |
|
|
179
|
+
| `lemma discard <id>` | **NEW** Discard a pending fix patch. |
|
|
164
180
|
|
|
165
181
|
### Customizing via `lemma.config.json`
|
|
166
182
|
|
|
@@ -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"}
|
|
@@ -8,42 +8,41 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const child_process_1 = require("child_process");
|
|
10
10
|
const lemma_proxy_1 = require("../cli/lemma-proxy");
|
|
11
|
+
const PatchStore_1 = require("./PatchStore");
|
|
12
|
+
const Notifier_1 = require("./Notifier");
|
|
11
13
|
class AutopilotWatcher {
|
|
12
|
-
constructor(watchDir = 'src') {
|
|
14
|
+
constructor(watchDir = 'src', nonInvasive = true) {
|
|
13
15
|
this.isRunning = false;
|
|
14
16
|
this.debounceTimer = null;
|
|
15
17
|
this.activeBuildProcess = null;
|
|
16
18
|
this.watchDir = path_1.default.resolve(process.cwd(), watchDir);
|
|
19
|
+
this.nonInvasive = nonInvasive;
|
|
17
20
|
}
|
|
18
21
|
start() {
|
|
19
22
|
if (this.isRunning)
|
|
20
23
|
return;
|
|
21
24
|
this.isRunning = true;
|
|
22
|
-
console.log(`\n🛸 \x1b[35m[
|
|
23
|
-
console.log(`💡 \x1b[
|
|
25
|
+
console.log(`\n🛸 \x1b[35m[Lemma Watch]\x1b[0m Silent background watcher on: ${this.watchDir}`);
|
|
26
|
+
console.log(`💡 \x1b[36mWill silently detect and store fixes. Use \x1b[1mlemma patches\x1b[0m\x1b[36m to see them.\x1b[0m\n`);
|
|
24
27
|
if (!fs_1.default.existsSync(this.watchDir)) {
|
|
25
28
|
console.log(`⚠️ Watch directory ${this.watchDir} does not exist. Creating it.`);
|
|
26
29
|
fs_1.default.mkdirSync(this.watchDir, { recursive: true });
|
|
27
30
|
}
|
|
28
|
-
// Watch files recursively natively (mac supports recursive natively)
|
|
29
31
|
fs_1.default.watch(this.watchDir, { recursive: true }, (eventType, filename) => {
|
|
30
32
|
if (!filename || filename.endsWith('.fixed') || filename.includes('.lemma'))
|
|
31
33
|
return;
|
|
32
|
-
// Debounce trigger
|
|
33
34
|
if (this.debounceTimer)
|
|
34
35
|
clearTimeout(this.debounceTimer);
|
|
35
36
|
this.debounceTimer = setTimeout(() => {
|
|
36
|
-
this.
|
|
37
|
+
this.triggerBuild(filename);
|
|
37
38
|
}, 1500);
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
+
triggerBuild(modifiedFile) {
|
|
41
42
|
if (this.activeBuildProcess) {
|
|
42
43
|
this.activeBuildProcess.kill();
|
|
43
44
|
this.activeBuildProcess = null;
|
|
44
45
|
}
|
|
45
|
-
console.log(`\n📝 \x1b[33m[Autopilot]\x1b[0m Change detected in ${modifiedFile}. Running background compilation...`);
|
|
46
|
-
// Determine the project root by searching upwards for package.json or tsconfig.json
|
|
47
46
|
let projectRoot = this.watchDir;
|
|
48
47
|
while (projectRoot && projectRoot !== '/' && !fs_1.default.existsSync(path_1.default.join(projectRoot, 'package.json')) && !fs_1.default.existsSync(path_1.default.join(projectRoot, 'tsconfig.json'))) {
|
|
49
48
|
const parent = path_1.default.dirname(projectRoot);
|
|
@@ -54,65 +53,60 @@ class AutopilotWatcher {
|
|
|
54
53
|
if (!fs_1.default.existsSync(path_1.default.join(projectRoot, 'package.json')) && !fs_1.default.existsSync(path_1.default.join(projectRoot, 'tsconfig.json'))) {
|
|
55
54
|
projectRoot = process.cwd();
|
|
56
55
|
}
|
|
57
|
-
// Determine the build/validation command
|
|
58
56
|
let cmd = 'npx tsc --noEmit';
|
|
59
57
|
if (!fs_1.default.existsSync(path_1.default.join(projectRoot, 'tsconfig.json'))) {
|
|
60
|
-
cmd = 'npm run build';
|
|
58
|
+
cmd = 'npm run build 2>&1 || true';
|
|
61
59
|
}
|
|
62
60
|
this.activeBuildProcess = (0, child_process_1.exec)(cmd, { cwd: projectRoot }, async (error, stdout, stderr) => {
|
|
63
61
|
this.activeBuildProcess = null;
|
|
64
|
-
if (!error)
|
|
65
|
-
console.log(`✨ \x1b[32m[Autopilot] Build compiled perfectly!\x1b[0m`);
|
|
62
|
+
if (!error)
|
|
66
63
|
return;
|
|
67
|
-
}
|
|
68
64
|
const output = stdout + '\n' + stderr;
|
|
69
|
-
|
|
70
|
-
// Parse TypeScript compiler output
|
|
71
|
-
// Standard format: src/utils/ContextSqueezer.ts:130:50 - error TS7006: Parameter 'match' implicitly has an 'any' type.
|
|
72
|
-
const tsErrorRegex = /([^\s\n]+\.ts)[\s\(:]+(\d+)[\s,:]+(\d+)?[\s\)]*[\s-:]+error\s+([^\n]+)/;
|
|
65
|
+
const tsErrorRegex = /([^\s\n]+\.(?:ts|tsx|js|jsx))[\s\(:]+(\d+)[\s,:]+(\d+)?[\s\)]*[\s-:]+error\s+(TS\d+):\s+([^\n]+)/;
|
|
73
66
|
const match = output.match(tsErrorRegex);
|
|
74
|
-
if (match)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
const absoluteFile = path_1.default.resolve(projectRoot, file);
|
|
89
|
-
const liveContextContent = `# Autopilot Telemetry Crash Report
|
|
67
|
+
if (!match)
|
|
68
|
+
return;
|
|
69
|
+
const [, file, line, , errorCode, errorMsg] = match;
|
|
70
|
+
const absoluteFile = path_1.default.resolve(projectRoot, file);
|
|
71
|
+
const relFile = path_1.default.relative(projectRoot, absoluteFile) || file;
|
|
72
|
+
const contextDirs = [
|
|
73
|
+
path_1.default.join(projectRoot, '.lemma'),
|
|
74
|
+
path_1.default.join(process.cwd(), '.lemma')
|
|
75
|
+
];
|
|
76
|
+
for (const dir of contextDirs) {
|
|
77
|
+
if (!fs_1.default.existsSync(dir))
|
|
78
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
79
|
+
const content = `# Lemma Watch Crash Report
|
|
90
80
|
Timestamp: ${new Date().toISOString()}
|
|
91
81
|
Message: ${errorMsg} in ${absoluteFile}:${line}
|
|
82
|
+
Error: ${errorCode}
|
|
92
83
|
Stack:
|
|
93
84
|
at ${absoluteFile}:${line}:0
|
|
94
85
|
`;
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
// Execute performAutoHeal in apply mode!
|
|
98
|
-
console.log(`⚡ \x1b[35m[Autopilot] Calling auto-healing agent...\x1b[0m`);
|
|
99
|
-
try {
|
|
100
|
-
const res = await (0, lemma_proxy_1.performAutoHeal)(true);
|
|
101
|
-
if (res.success) {
|
|
102
|
-
console.log(`✔ \x1b[32m[Autopilot] Auto-healed: ${res.message}\x1b[0m\n`);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
console.log(`⚠️ \x1b[33m[Autopilot] Healing agent failed: ${res.message}\x1b[0m\n`);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
console.log(`⚠️ \x1b[33m[Autopilot] Healing agent error: ${err.message}\x1b[0m\n`);
|
|
110
|
-
}
|
|
86
|
+
fs_1.default.writeFileSync(path_1.default.join(dir, 'live-context.md'), content, 'utf8');
|
|
111
87
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
88
|
+
try {
|
|
89
|
+
const res = await (0, lemma_proxy_1.performAutoHeal)(false);
|
|
90
|
+
if (!res.success || !res.fileAfter)
|
|
91
|
+
return;
|
|
92
|
+
const patch = (0, PatchStore_1.savePatch)({
|
|
93
|
+
filePath: relFile,
|
|
94
|
+
line: parseInt(line, 10),
|
|
95
|
+
errorCode: errorCode || 'UNKNOWN',
|
|
96
|
+
errorMsg,
|
|
97
|
+
explanation: res.message,
|
|
98
|
+
patch: res.patch || '',
|
|
99
|
+
fileBefore: res.fileBefore || '',
|
|
100
|
+
fileAfter: res.fileAfter,
|
|
101
|
+
});
|
|
102
|
+
(0, Notifier_1.notifyPatch)(patch);
|
|
103
|
+
const pending = (0, PatchStore_1.countPending)();
|
|
104
|
+
console.log(`\n🩺 \x1b[35m[Lemma Watch]\x1b[0m ${errorCode} in ${relFile}:${line}`);
|
|
105
|
+
console.log(` \x1b[33m${errorMsg.substring(0, 100)}\x1b[0m`);
|
|
106
|
+
console.log(` \x1b[36mFix ready → \x1b[1mlemma apply ${patch.id}\x1b[0m`);
|
|
107
|
+
console.log(` \x1b[90m${pending} pending fix${pending !== 1 ? 'es' : ''} total\x1b[0m\n`);
|
|
115
108
|
}
|
|
109
|
+
catch { }
|
|
116
110
|
});
|
|
117
111
|
}
|
|
118
112
|
stop() {
|
|
@@ -121,7 +115,7 @@ Stack:
|
|
|
121
115
|
clearTimeout(this.debounceTimer);
|
|
122
116
|
if (this.activeBuildProcess)
|
|
123
117
|
this.activeBuildProcess.kill();
|
|
124
|
-
console.log(
|
|
118
|
+
console.log(`\n🛸 \x1b[35m[Lemma Watch]\x1b[0m Background watcher stopped.`);
|
|
125
119
|
}
|
|
126
120
|
}
|
|
127
121
|
exports.AutopilotWatcher = AutopilotWatcher;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutopilotWatcher.js","sourceRoot":"","sources":["../../../src/autopilot/AutopilotWatcher.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
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,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.sendNotification = sendNotification;
|
|
7
|
+
exports.notifyPatch = notifyPatch;
|
|
8
|
+
exports.notifyClear = notifyClear;
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
const axios_1 = __importDefault(require("axios"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const DASHBOARD_API_BASE = 'http://localhost:8081';
|
|
13
|
+
const LEMMA_ICON = path_1.default.join(__dirname, '..', '..', 'assets', 'icon.png');
|
|
14
|
+
function osascriptNotify(title, subtitle, message) {
|
|
15
|
+
try {
|
|
16
|
+
(0, child_process_1.execSync)(`osascript -e 'display notification "${message.replace(/"/g, '\\"')}" with title "${title.replace(/"/g, '\\"')}" subtitle "${subtitle.replace(/"/g, '\\"')}" sound name "default"'`, { timeout: 3000 });
|
|
17
|
+
}
|
|
18
|
+
catch { }
|
|
19
|
+
}
|
|
20
|
+
function terminalNotifierNotify(title, subtitle, message) {
|
|
21
|
+
try {
|
|
22
|
+
(0, child_process_1.execSync)(`terminal-notifier -title "${title.replace(/"/g, '\\"')}" -subtitle "${subtitle.replace(/"/g, '\\"')}" -message "${message.replace(/"/g, '\\"')}" -sound default -timeout 10`, { timeout: 3000 });
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
osascriptNotify(title, subtitle, message);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function sendNotification(title, subtitle, message) {
|
|
29
|
+
if (process.platform === 'darwin') {
|
|
30
|
+
if (process.env.CI || process.env.NO_NOTIFY)
|
|
31
|
+
return;
|
|
32
|
+
terminalNotifierNotify(title, subtitle, message);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function notifyPatch(patch) {
|
|
36
|
+
const title = `🩺 Lemma: ${patch.errorCode}`;
|
|
37
|
+
const subtitle = `${path_1.default.basename(patch.filePath)}:${patch.line}`;
|
|
38
|
+
const msg = patch.explanation.substring(0, 120);
|
|
39
|
+
sendNotification(title, subtitle, msg);
|
|
40
|
+
pushToDashboard(patch);
|
|
41
|
+
}
|
|
42
|
+
async function pushToDashboard(patch) {
|
|
43
|
+
try {
|
|
44
|
+
await axios_1.default.post(`${DASHBOARD_API_BASE}/api/patches/notify`, {
|
|
45
|
+
id: patch.id,
|
|
46
|
+
filePath: patch.filePath,
|
|
47
|
+
line: patch.line,
|
|
48
|
+
errorCode: patch.errorCode,
|
|
49
|
+
errorMsg: patch.errorMsg,
|
|
50
|
+
explanation: patch.explanation,
|
|
51
|
+
timestamp: patch.timestamp,
|
|
52
|
+
}, { timeout: 1000 });
|
|
53
|
+
}
|
|
54
|
+
catch { }
|
|
55
|
+
}
|
|
56
|
+
function notifyClear() {
|
|
57
|
+
sendNotification('Lemma', 'All patches applied', '✨ No pending fixes');
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=Notifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Notifier.js","sourceRoot":"","sources":["../../../src/autopilot/Notifier.ts"],"names":[],"mappings":";;;;;AA6BA,4CAKC;AAED,kCAOC;AAgBD,kCAEC;AA7DD,iDAAwC;AACxC,kDAAyB;AACzB,gDAAuB;AAIvB,MAAM,kBAAkB,GAAG,uBAAuB,CAAA;AAClD,MAAM,UAAU,GAAG,cAAI,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,IAAA,wBAAQ,EACN,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,IAAA,wBAAQ,EACN,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,SAAgB,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,SAAgB,WAAW,CAAC,KAAY;IACtC,MAAM,KAAK,GAAG,aAAa,KAAK,CAAC,SAAS,EAAE,CAAA;IAC5C,MAAM,QAAQ,GAAG,GAAG,cAAI,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,eAAK,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,SAAgB,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,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.savePatch = savePatch;
|
|
7
|
+
exports.listPatches = listPatches;
|
|
8
|
+
exports.getPatch = getPatch;
|
|
9
|
+
exports.applyPatch = applyPatch;
|
|
10
|
+
exports.discardPatch = discardPatch;
|
|
11
|
+
exports.countPending = countPending;
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
const PATCHES_DIR = path_1.default.join(process.cwd(), '.lemma', 'patches');
|
|
15
|
+
function ensureDir() {
|
|
16
|
+
if (!fs_1.default.existsSync(PATCHES_DIR)) {
|
|
17
|
+
fs_1.default.mkdirSync(PATCHES_DIR, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function savePatch(meta) {
|
|
21
|
+
ensureDir();
|
|
22
|
+
const errorSlug = meta.errorCode.toLowerCase().replace(/\s+/g, '-');
|
|
23
|
+
const fileSlug = path_1.default.basename(meta.filePath).replace(/\./g, '-');
|
|
24
|
+
const id = `${errorSlug}-${fileSlug}-${Date.now()}`;
|
|
25
|
+
const patch = { ...meta, id, timestamp: Date.now(), status: 'pending' };
|
|
26
|
+
const filePath = path_1.default.join(PATCHES_DIR, `${id}.json`);
|
|
27
|
+
fs_1.default.writeFileSync(filePath, JSON.stringify(patch, null, 2));
|
|
28
|
+
return patch;
|
|
29
|
+
}
|
|
30
|
+
function listPatches(status) {
|
|
31
|
+
ensureDir();
|
|
32
|
+
const files = fs_1.default.readdirSync(PATCHES_DIR).filter(f => f.endsWith('.json'));
|
|
33
|
+
const patches = [];
|
|
34
|
+
for (const f of files) {
|
|
35
|
+
try {
|
|
36
|
+
const p = JSON.parse(fs_1.default.readFileSync(path_1.default.join(PATCHES_DIR, f), 'utf8'));
|
|
37
|
+
patches.push(p);
|
|
38
|
+
}
|
|
39
|
+
catch { }
|
|
40
|
+
}
|
|
41
|
+
patches.sort((a, b) => b.timestamp - a.timestamp);
|
|
42
|
+
if (status)
|
|
43
|
+
return patches.filter(p => p.status === status);
|
|
44
|
+
return patches;
|
|
45
|
+
}
|
|
46
|
+
function getPatch(id) {
|
|
47
|
+
ensureDir();
|
|
48
|
+
const filePath = path_1.default.join(PATCHES_DIR, `${id}.json`);
|
|
49
|
+
if (!fs_1.default.existsSync(filePath))
|
|
50
|
+
return null;
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(fs_1.default.readFileSync(filePath, 'utf8'));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function applyPatch(id) {
|
|
59
|
+
const patch = getPatch(id);
|
|
60
|
+
if (!patch)
|
|
61
|
+
return { success: false, message: `Patch ${id} not found` };
|
|
62
|
+
if (patch.status === 'applied')
|
|
63
|
+
return { success: false, message: `Patch ${id} already applied` };
|
|
64
|
+
if (patch.status === 'discarded')
|
|
65
|
+
return { success: false, message: `Patch ${id} was discarded` };
|
|
66
|
+
const targetFile = path_1.default.resolve(process.cwd(), patch.filePath);
|
|
67
|
+
if (!fs_1.default.existsSync(targetFile)) {
|
|
68
|
+
return { success: false, message: `File ${patch.filePath} no longer exists` };
|
|
69
|
+
}
|
|
70
|
+
fs_1.default.writeFileSync(targetFile, patch.fileAfter, 'utf8');
|
|
71
|
+
patch.status = 'applied';
|
|
72
|
+
const filePath = path_1.default.join(PATCHES_DIR, `${id}.json`);
|
|
73
|
+
fs_1.default.writeFileSync(filePath, JSON.stringify(patch, null, 2));
|
|
74
|
+
return { success: true, message: `Applied fix for ${patch.errorCode} in ${patch.filePath}` };
|
|
75
|
+
}
|
|
76
|
+
function discardPatch(id) {
|
|
77
|
+
const patch = getPatch(id);
|
|
78
|
+
if (!patch)
|
|
79
|
+
return { success: false, message: `Patch ${id} not found` };
|
|
80
|
+
patch.status = 'discarded';
|
|
81
|
+
const filePath = path_1.default.join(PATCHES_DIR, `${id}.json`);
|
|
82
|
+
fs_1.default.writeFileSync(filePath, JSON.stringify(patch, null, 2));
|
|
83
|
+
return { success: true, message: `Patch ${id} discarded` };
|
|
84
|
+
}
|
|
85
|
+
function countPending() {
|
|
86
|
+
return listPatches('pending').length;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=PatchStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PatchStore.js","sourceRoot":"","sources":["../../../src/autopilot/PatchStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -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"}
|
|
@@ -1536,6 +1536,51 @@ class LemmaServer {
|
|
|
1536
1536
|
});
|
|
1537
1537
|
this.app.get('/dashboard/*', (req, res) => res.sendFile(path_1.default.join(this.dashboardPath, 'index.html')));
|
|
1538
1538
|
}
|
|
1539
|
+
// Patch API — works regardless of dashboard
|
|
1540
|
+
this.app.post('/api/patches/notify', (req, res) => {
|
|
1541
|
+
const patch = req.body;
|
|
1542
|
+
if (!patch.id)
|
|
1543
|
+
return res.status(400).json({ error: 'Missing patch id' });
|
|
1544
|
+
logEvent({
|
|
1545
|
+
type: 'patch:available',
|
|
1546
|
+
patchId: patch.id,
|
|
1547
|
+
filePath: patch.filePath,
|
|
1548
|
+
line: patch.line,
|
|
1549
|
+
errorCode: patch.errorCode,
|
|
1550
|
+
timestamp: patch.timestamp,
|
|
1551
|
+
});
|
|
1552
|
+
res.json({ success: true });
|
|
1553
|
+
});
|
|
1554
|
+
this.app.get('/api/patches', (req, res) => {
|
|
1555
|
+
try {
|
|
1556
|
+
const { listPatches } = require('../autopilot/PatchStore');
|
|
1557
|
+
const patches = listPatches();
|
|
1558
|
+
res.json({ patches });
|
|
1559
|
+
}
|
|
1560
|
+
catch (err) {
|
|
1561
|
+
res.status(500).json({ error: err.message });
|
|
1562
|
+
}
|
|
1563
|
+
});
|
|
1564
|
+
this.app.post('/api/patches/:id/apply', (req, res) => {
|
|
1565
|
+
try {
|
|
1566
|
+
const { applyPatch } = require('../autopilot/PatchStore');
|
|
1567
|
+
const result = applyPatch(req.params.id);
|
|
1568
|
+
res.json(result);
|
|
1569
|
+
}
|
|
1570
|
+
catch (err) {
|
|
1571
|
+
res.status(500).json({ error: err.message });
|
|
1572
|
+
}
|
|
1573
|
+
});
|
|
1574
|
+
this.app.post('/api/patches/:id/discard', (req, res) => {
|
|
1575
|
+
try {
|
|
1576
|
+
const { discardPatch } = require('../autopilot/PatchStore');
|
|
1577
|
+
const result = discardPatch(req.params.id);
|
|
1578
|
+
res.json(result);
|
|
1579
|
+
}
|
|
1580
|
+
catch (err) {
|
|
1581
|
+
res.status(500).json({ error: err.message });
|
|
1582
|
+
}
|
|
1583
|
+
});
|
|
1539
1584
|
// Mount PR Review webhook endpoints
|
|
1540
1585
|
const { createWebhookRouter } = require('../pr-review/webhook/WebhookServer');
|
|
1541
1586
|
this.app.use('/api/webhook', createWebhookRouter());
|
|
@@ -2546,6 +2591,82 @@ Ensure you return strictly JSON. Do not return any other text outside the JSON b
|
|
|
2546
2591
|
}
|
|
2547
2592
|
}
|
|
2548
2593
|
}
|
|
2594
|
+
commander_1.program.command('watch')
|
|
2595
|
+
.description('Start silent background watcher — detects compile errors and saves patches without applying')
|
|
2596
|
+
.option('--dir <directory>', 'Directory to monitor for changes', 'src')
|
|
2597
|
+
.action(async (opts) => {
|
|
2598
|
+
try {
|
|
2599
|
+
const { AutopilotWatcher } = require('../autopilot/AutopilotWatcher');
|
|
2600
|
+
const watcher = new AutopilotWatcher(opts.dir, true);
|
|
2601
|
+
watcher.start();
|
|
2602
|
+
process.stdin.resume();
|
|
2603
|
+
process.on('SIGINT', () => {
|
|
2604
|
+
watcher.stop();
|
|
2605
|
+
process.exit(0);
|
|
2606
|
+
});
|
|
2607
|
+
}
|
|
2608
|
+
catch (err) {
|
|
2609
|
+
console.error('❌ Error starting watcher:', err.message);
|
|
2610
|
+
process.exit(1);
|
|
2611
|
+
}
|
|
2612
|
+
});
|
|
2613
|
+
commander_1.program.command('patches')
|
|
2614
|
+
.description('List available patches from the silent watcher')
|
|
2615
|
+
.option('--pending', 'Show only pending patches')
|
|
2616
|
+
.option('--all', 'Show all patches (including applied/discarded)')
|
|
2617
|
+
.action((opts) => {
|
|
2618
|
+
const { listPatches, countPending } = require('../autopilot/PatchStore');
|
|
2619
|
+
const status = opts.pending ? 'pending' : undefined;
|
|
2620
|
+
const showAll = opts.all;
|
|
2621
|
+
const patches = showAll ? listPatches() : listPatches(status);
|
|
2622
|
+
const pending = patches.filter((p) => p.status === 'pending');
|
|
2623
|
+
const applied = patches.filter((p) => p.status === 'applied');
|
|
2624
|
+
const discarded = patches.filter((p) => p.status === 'discarded');
|
|
2625
|
+
if (patches.length === 0) {
|
|
2626
|
+
console.log(`\n📋 \x1b[1mLemma Patches\x1b[0m — No patches found.\n`);
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
console.log(`\n📋 \x1b[1mLemma Patches\x1b[0m`);
|
|
2630
|
+
console.log(` ${pending.length} pending | ${applied.length} applied | ${discarded.length} discarded\n`);
|
|
2631
|
+
for (const p of patches) {
|
|
2632
|
+
const date = new Date(p.timestamp).toLocaleTimeString();
|
|
2633
|
+
const statusIcon = p.status === 'pending' ? '\x1b[33m⏳\x1b[0m' : p.status === 'applied' ? '\x1b[32m✔\x1b[0m' : '\x1b[90m✖\x1b[0m';
|
|
2634
|
+
console.log(` ${statusIcon} \x1b[1m${p.id}\x1b[0m`);
|
|
2635
|
+
console.log(` ${p.errorCode} in ${p.filePath}:${p.line}`);
|
|
2636
|
+
console.log(` \x1b[90m${p.errorMsg.substring(0, 100)}\x1b[0m`);
|
|
2637
|
+
console.log(` \x1b[90m${date}\x1b[0m`);
|
|
2638
|
+
if (p.status === 'pending') {
|
|
2639
|
+
console.log(` → \x1b[36mlemma apply ${p.id}\x1b[0m | \x1b[2mlemma discard ${p.id}\x1b[0m`);
|
|
2640
|
+
}
|
|
2641
|
+
console.log();
|
|
2642
|
+
}
|
|
2643
|
+
});
|
|
2644
|
+
commander_1.program.command('apply <id>')
|
|
2645
|
+
.description('Apply a pending fix patch')
|
|
2646
|
+
.action((id) => {
|
|
2647
|
+
const { applyPatch } = require('../autopilot/PatchStore');
|
|
2648
|
+
const res = applyPatch(id);
|
|
2649
|
+
if (res.success) {
|
|
2650
|
+
console.log(`\n✔ \x1b[32m${res.message}\x1b[0m\n`);
|
|
2651
|
+
}
|
|
2652
|
+
else {
|
|
2653
|
+
console.log(`\n❌ \x1b[31m${res.message}\x1b[0m\n`);
|
|
2654
|
+
process.exit(1);
|
|
2655
|
+
}
|
|
2656
|
+
});
|
|
2657
|
+
commander_1.program.command('discard <id>')
|
|
2658
|
+
.description('Discard a pending fix patch')
|
|
2659
|
+
.action((id) => {
|
|
2660
|
+
const { discardPatch } = require('../autopilot/PatchStore');
|
|
2661
|
+
const res = discardPatch(id);
|
|
2662
|
+
if (res.success) {
|
|
2663
|
+
console.log(`\n✖ \x1b[33m${res.message}\x1b[0m\n`);
|
|
2664
|
+
}
|
|
2665
|
+
else {
|
|
2666
|
+
console.log(`\n❌ \x1b[31m${res.message}\x1b[0m\n`);
|
|
2667
|
+
process.exit(1);
|
|
2668
|
+
}
|
|
2669
|
+
});
|
|
2549
2670
|
commander_1.program.command('heal')
|
|
2550
2671
|
.description('[Pro] Diagnose and auto-heal the latest local server crash from .lemma/live-context.md')
|
|
2551
2672
|
.option('--apply', 'Apply the auto-generated code fix automatically', false)
|