@nxuss/lemma 0.9.3 → 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.
Files changed (93) hide show
  1. package/README.md +35 -4
  2. package/bin/cli.js +97 -0
  3. package/bin/init.js +307 -0
  4. package/cache-proxy.js +191 -0
  5. package/dist/cjs/autopilot/AutopilotWatcher.d.ts +3 -2
  6. package/dist/cjs/autopilot/AutopilotWatcher.d.ts.map +1 -1
  7. package/dist/cjs/autopilot/AutopilotWatcher.js +48 -54
  8. package/dist/cjs/autopilot/AutopilotWatcher.js.map +1 -1
  9. package/dist/cjs/autopilot/Notifier.d.ts +5 -0
  10. package/dist/cjs/autopilot/Notifier.d.ts.map +1 -0
  11. package/dist/cjs/autopilot/Notifier.js +59 -0
  12. package/dist/cjs/autopilot/Notifier.js.map +1 -0
  13. package/dist/cjs/autopilot/PatchStore.d.ts +26 -0
  14. package/dist/cjs/autopilot/PatchStore.d.ts.map +1 -0
  15. package/dist/cjs/autopilot/PatchStore.js +88 -0
  16. package/dist/cjs/autopilot/PatchStore.js.map +1 -0
  17. package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
  18. package/dist/cjs/cli/lemma-proxy.js +123 -4
  19. package/dist/cjs/cli/lemma-proxy.js.map +1 -1
  20. package/dist/cjs/mcp/index.js +1 -1
  21. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  22. package/dist/cjs/mcp/tools.js +303 -77
  23. package/dist/cjs/mcp/tools.js.map +1 -1
  24. package/dist/cjs/subconscious/TheBrainV2.d.ts +102 -0
  25. package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -0
  26. package/dist/cjs/subconscious/TheBrainV2.js +444 -0
  27. package/dist/cjs/subconscious/TheBrainV2.js.map +1 -0
  28. package/dist/cjs/utils/ContextCollapser.d.ts +21 -0
  29. package/dist/cjs/utils/ContextCollapser.d.ts.map +1 -0
  30. package/dist/cjs/utils/ContextCollapser.js +132 -0
  31. package/dist/cjs/utils/ContextCollapser.js.map +1 -0
  32. package/dist/cjs/utils/ExecutiveReport.d.ts +29 -0
  33. package/dist/cjs/utils/ExecutiveReport.d.ts.map +1 -0
  34. package/dist/cjs/utils/ExecutiveReport.js +111 -0
  35. package/dist/cjs/utils/ExecutiveReport.js.map +1 -0
  36. package/dist/cjs/utils/SurgicalASTInsert.d.ts +21 -0
  37. package/dist/cjs/utils/SurgicalASTInsert.d.ts.map +1 -0
  38. package/dist/cjs/utils/SurgicalASTInsert.js +173 -0
  39. package/dist/cjs/utils/SurgicalASTInsert.js.map +1 -0
  40. package/dist/cjs/utils/SymbolSurgicalContext.d.ts +25 -0
  41. package/dist/cjs/utils/SymbolSurgicalContext.d.ts.map +1 -0
  42. package/dist/cjs/utils/SymbolSurgicalContext.js +265 -0
  43. package/dist/cjs/utils/SymbolSurgicalContext.js.map +1 -0
  44. package/dist/cjs/utils/WormholeCompressor.d.ts +22 -0
  45. package/dist/cjs/utils/WormholeCompressor.d.ts.map +1 -0
  46. package/dist/cjs/utils/WormholeCompressor.js +152 -0
  47. package/dist/cjs/utils/WormholeCompressor.js.map +1 -0
  48. package/dist/esm/autopilot/AutopilotWatcher.d.ts +3 -2
  49. package/dist/esm/autopilot/AutopilotWatcher.d.ts.map +1 -1
  50. package/dist/esm/autopilot/AutopilotWatcher.js +48 -54
  51. package/dist/esm/autopilot/AutopilotWatcher.js.map +1 -1
  52. package/dist/esm/autopilot/Notifier.d.ts +5 -0
  53. package/dist/esm/autopilot/Notifier.d.ts.map +1 -0
  54. package/dist/esm/autopilot/Notifier.js +51 -0
  55. package/dist/esm/autopilot/Notifier.js.map +1 -0
  56. package/dist/esm/autopilot/PatchStore.d.ts +26 -0
  57. package/dist/esm/autopilot/PatchStore.d.ts.map +1 -0
  58. package/dist/esm/autopilot/PatchStore.js +77 -0
  59. package/dist/esm/autopilot/PatchStore.js.map +1 -0
  60. package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
  61. package/dist/esm/cli/lemma-proxy.js +123 -4
  62. package/dist/esm/cli/lemma-proxy.js.map +1 -1
  63. package/dist/esm/mcp/index.js +1 -1
  64. package/dist/esm/mcp/tools.d.ts.map +1 -1
  65. package/dist/esm/mcp/tools.js +303 -77
  66. package/dist/esm/mcp/tools.js.map +1 -1
  67. package/dist/esm/subconscious/TheBrainV2.d.ts +102 -0
  68. package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -0
  69. package/dist/esm/subconscious/TheBrainV2.js +431 -0
  70. package/dist/esm/subconscious/TheBrainV2.js.map +1 -0
  71. package/dist/esm/utils/ContextCollapser.d.ts +21 -0
  72. package/dist/esm/utils/ContextCollapser.d.ts.map +1 -0
  73. package/dist/esm/utils/ContextCollapser.js +128 -0
  74. package/dist/esm/utils/ContextCollapser.js.map +1 -0
  75. package/dist/esm/utils/ExecutiveReport.d.ts +29 -0
  76. package/dist/esm/utils/ExecutiveReport.d.ts.map +1 -0
  77. package/dist/esm/utils/ExecutiveReport.js +105 -0
  78. package/dist/esm/utils/ExecutiveReport.js.map +1 -0
  79. package/dist/esm/utils/SurgicalASTInsert.d.ts +21 -0
  80. package/dist/esm/utils/SurgicalASTInsert.d.ts.map +1 -0
  81. package/dist/esm/utils/SurgicalASTInsert.js +134 -0
  82. package/dist/esm/utils/SurgicalASTInsert.js.map +1 -0
  83. package/dist/esm/utils/SymbolSurgicalContext.d.ts +25 -0
  84. package/dist/esm/utils/SymbolSurgicalContext.d.ts.map +1 -0
  85. package/dist/esm/utils/SymbolSurgicalContext.js +226 -0
  86. package/dist/esm/utils/SymbolSurgicalContext.js.map +1 -0
  87. package/dist/esm/utils/WormholeCompressor.d.ts +22 -0
  88. package/dist/esm/utils/WormholeCompressor.d.ts.map +1 -0
  89. package/dist/esm/utils/WormholeCompressor.js +148 -0
  90. package/dist/esm/utils/WormholeCompressor.js.map +1 -0
  91. package/lemma-proxy.cjs +31 -14
  92. package/mcp-server.js +220 -0
  93. package/package.json +7 -2
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ /**
3
+ * SymbolSurgicalContext — Surgical AST extraction tool.
4
+ *
5
+ * Scans a file for a specific symbol (class, function, variable, interface),
6
+ * extracts its implementation, parses its AST to find workspace dependencies,
7
+ * and extracts ONLY the signatures of those dependencies (not their entire files).
8
+ *
9
+ * Saves up to 90% of token context in LLM prompts.
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.getSymbolSurgicalContext = getSymbolSurgicalContext;
49
+ const fs_1 = __importDefault(require("fs"));
50
+ const path_1 = __importDefault(require("path"));
51
+ const ts = __importStar(require("typescript"));
52
+ const utils_1 = require("../mcp/utils");
53
+ /**
54
+ * Traverses AST to find the node defining the specified symbol name.
55
+ */
56
+ function findSymbolNode(sourceFile, name) {
57
+ let targetNode = null;
58
+ function walk(node) {
59
+ if (targetNode)
60
+ return;
61
+ if (ts.isFunctionDeclaration(node) && node.name && node.name.text === name) {
62
+ targetNode = node;
63
+ return;
64
+ }
65
+ if (ts.isClassDeclaration(node) && node.name && node.name.text === name) {
66
+ targetNode = node;
67
+ return;
68
+ }
69
+ if (ts.isInterfaceDeclaration(node) && node.name && node.name.text === name) {
70
+ targetNode = node;
71
+ return;
72
+ }
73
+ if (ts.isTypeAliasDeclaration(node) && node.name && node.name.text === name) {
74
+ targetNode = node;
75
+ return;
76
+ }
77
+ if (ts.isEnumDeclaration(node) && node.name && node.name.text === name) {
78
+ targetNode = node;
79
+ return;
80
+ }
81
+ if (ts.isVariableStatement(node)) {
82
+ for (const decl of node.declarationList.declarations) {
83
+ if (ts.isIdentifier(decl.name) && decl.name.text === name) {
84
+ targetNode = node; // return the entire variable statement
85
+ return;
86
+ }
87
+ }
88
+ }
89
+ ts.forEachChild(node, walk);
90
+ }
91
+ walk(sourceFile);
92
+ return targetNode;
93
+ }
94
+ /**
95
+ * Extracts referenced identifiers from a node.
96
+ */
97
+ function extractReferences(node) {
98
+ const refs = new Set();
99
+ function walk(n) {
100
+ if (ts.isIdentifier(n)) {
101
+ refs.add(n.text);
102
+ }
103
+ ts.forEachChild(n, walk);
104
+ }
105
+ walk(node);
106
+ return refs;
107
+ }
108
+ /**
109
+ * Finds the import declarations in a file to map imported symbols to their paths.
110
+ */
111
+ function parseImports(sourceFile, currentFilePath, workspaceRoot) {
112
+ const importMap = new Map(); // symbol name -> relative module path
113
+ ts.forEachChild(sourceFile, (node) => {
114
+ if (ts.isImportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
115
+ const spec = node.moduleSpecifier.text;
116
+ // We only care about relative imports (workspace files)
117
+ if (spec.startsWith('.')) {
118
+ const importDir = path_1.default.dirname(currentFilePath);
119
+ let resolvedPath = path_1.default.resolve(importDir, spec);
120
+ // Find exact extension matching
121
+ for (const ext of ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js']) {
122
+ if (fs_1.default.existsSync(resolvedPath + ext)) {
123
+ resolvedPath += ext;
124
+ break;
125
+ }
126
+ }
127
+ const relPath = path_1.default.relative(workspaceRoot, resolvedPath).replace(/\\/g, '/');
128
+ // Extract imported names
129
+ if (node.importClause) {
130
+ // Default import: import Foo from './Foo'
131
+ if (node.importClause.name) {
132
+ importMap.set(node.importClause.name.text, relPath);
133
+ }
134
+ // Named imports: import { Foo, Bar } from './Module'
135
+ if (node.importClause.namedBindings) {
136
+ if (ts.isNamedImports(node.importClause.namedBindings)) {
137
+ for (const el of node.importClause.namedBindings.elements) {
138
+ importMap.set(el.name.text, relPath);
139
+ }
140
+ }
141
+ else if (ts.isNamespaceImport(node.importClause.namedBindings)) {
142
+ // import * as Foo from './Module'
143
+ importMap.set(node.importClause.namedBindings.name.text, relPath);
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ });
150
+ return importMap;
151
+ }
152
+ /**
153
+ * Extracts ONLY the signature declaration of a symbol, dropping the function/method body.
154
+ */
155
+ function getSignatureText(node, sourceText) {
156
+ if (ts.isFunctionDeclaration(node)) {
157
+ const start = node.getStart();
158
+ let end = node.body ? node.body.getStart() : node.getEnd();
159
+ let sig = sourceText.substring(start, end).trim();
160
+ if (sig.endsWith('{'))
161
+ sig = sig.slice(0, -1).trim();
162
+ return { signature: sig, type: 'function' };
163
+ }
164
+ if (ts.isClassDeclaration(node)) {
165
+ const start = node.getStart();
166
+ // For class declaration, get just the class definition signature and public methods signatures
167
+ let end = node.members.length > 0 ? node.members[0].getStart() : node.getEnd();
168
+ let classHeader = sourceText.substring(start, end).trim();
169
+ if (classHeader.endsWith('{'))
170
+ classHeader = classHeader.slice(0, -1).trim();
171
+ // Add public methods/members signatures
172
+ const memberSigs = [];
173
+ for (const member of node.members) {
174
+ if (ts.isMethodDeclaration(member) && member.name) {
175
+ // Only include public methods
176
+ const modifiers = ts.getModifiers(member);
177
+ const isPrivate = modifiers?.some(m => m.kind === ts.SyntaxKind.PrivateKeyword);
178
+ if (!isPrivate) {
179
+ const mStart = member.getStart();
180
+ let mEnd = member.body ? member.body.getStart() : member.getEnd();
181
+ let mSig = sourceText.substring(mStart, mEnd).trim();
182
+ if (mSig.endsWith('{'))
183
+ mSig = mSig.slice(0, -1).trim();
184
+ memberSigs.push(` ${mSig};`);
185
+ }
186
+ }
187
+ else if (ts.isPropertyDeclaration(member) && member.name) {
188
+ memberSigs.push(` ${member.getText().split('=')[0].trim()};`);
189
+ }
190
+ }
191
+ return {
192
+ signature: `${classHeader} {\n${memberSigs.join('\n')}\n}`,
193
+ type: 'class'
194
+ };
195
+ }
196
+ if (ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node)) {
197
+ return { signature: node.getText().trim(), type: 'type' };
198
+ }
199
+ return { signature: node.getText().trim(), type: 'variable' };
200
+ }
201
+ /**
202
+ * Extracts a specific symbol signature from a dependency file.
203
+ */
204
+ function extractDependencySignature(filePath, symbolName) {
205
+ try {
206
+ if (!fs_1.default.existsSync(filePath))
207
+ return null;
208
+ const src = fs_1.default.readFileSync(filePath, 'utf8');
209
+ const sf = ts.createSourceFile(filePath, src, ts.ScriptTarget.Latest, true);
210
+ const node = findSymbolNode(sf, symbolName);
211
+ if (!node)
212
+ return null;
213
+ return getSignatureText(node, src);
214
+ }
215
+ catch {
216
+ return null;
217
+ }
218
+ }
219
+ /**
220
+ * Core orchestrator for Surgical Symbol Context Extraction.
221
+ */
222
+ function getSymbolSurgicalContext(workspaceRoot, relativeFilePath, symbolName) {
223
+ const { resolved: resolvedTarget } = (0, utils_1.safeResolvePath)(workspaceRoot, relativeFilePath);
224
+ if (!fs_1.default.existsSync(resolvedTarget)) {
225
+ throw new Error(`File not found: ${relativeFilePath}`);
226
+ }
227
+ const src = fs_1.default.readFileSync(resolvedTarget, 'utf8');
228
+ const sf = ts.createSourceFile(resolvedTarget, src, ts.ScriptTarget.Latest, true);
229
+ const node = findSymbolNode(sf, symbolName);
230
+ if (!node) {
231
+ throw new Error(`Symbol "${symbolName}" not found in file "${relativeFilePath}"`);
232
+ }
233
+ // 1. Get entire implementation of target symbol
234
+ const implementation = node.getText();
235
+ // 2. Map imports of this file
236
+ const importsMap = parseImports(sf, resolvedTarget, workspaceRoot);
237
+ // 3. Find all identifiers referenced in the symbol implementation
238
+ const refs = extractReferences(node);
239
+ // 4. Resolve references that are imported from other workspace files
240
+ const dependencies = [];
241
+ for (const ref of refs) {
242
+ if (ref === symbolName)
243
+ continue; // skip self reference
244
+ const moduleRelPath = importsMap.get(ref);
245
+ if (moduleRelPath) {
246
+ const depAbsPath = path_1.default.resolve(workspaceRoot, moduleRelPath);
247
+ const depInfo = extractDependencySignature(depAbsPath, ref);
248
+ if (depInfo) {
249
+ dependencies.push({
250
+ name: ref,
251
+ filePath: moduleRelPath,
252
+ signature: depInfo.signature,
253
+ type: depInfo.type
254
+ });
255
+ }
256
+ }
257
+ }
258
+ return {
259
+ symbolName,
260
+ filePath: relativeFilePath,
261
+ implementation,
262
+ dependencies
263
+ };
264
+ }
265
+ //# sourceMappingURL=SymbolSurgicalContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SymbolSurgicalContext.js","sourceRoot":"","sources":["../../../src/utils/SymbolSurgicalContext.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * WormholeCompressor — Reversible, token-dense serialization for source code.
3
+ *
4
+ * Compresses source code into a highly dense representation, substituting keywords
5
+ * and repeating identifiers with short tokens. Includes a self-contained dictionary
6
+ * header so the LLM or helper scripts can inflate/deflate it on the fly.
7
+ *
8
+ * Reduces token footprint for long files by 60-70% while keeping it structured and reversible.
9
+ */
10
+ export interface CompressedPayload {
11
+ dict: Record<string, string>;
12
+ payload: string;
13
+ }
14
+ /**
15
+ * Compresses source code into a Wormhole representation.
16
+ */
17
+ export declare function compressWormhole(code: string): string;
18
+ /**
19
+ * Reverts a Wormhole-compressed payload back to standard source code.
20
+ */
21
+ export declare function decompressWormhole(wormholeCode: string): string;
22
+ //# sourceMappingURL=WormholeCompressor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WormholeCompressor.d.ts","sourceRoot":"","sources":["../../../src/utils/WormholeCompressor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAqCH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAwErD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAsC/D"}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ /**
3
+ * WormholeCompressor — Reversible, token-dense serialization for source code.
4
+ *
5
+ * Compresses source code into a highly dense representation, substituting keywords
6
+ * and repeating identifiers with short tokens. Includes a self-contained dictionary
7
+ * header so the LLM or helper scripts can inflate/deflate it on the fly.
8
+ *
9
+ * Reduces token footprint for long files by 60-70% while keeping it structured and reversible.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.compressWormhole = compressWormhole;
13
+ exports.decompressWormhole = decompressWormhole;
14
+ // ─── Dictionary mappings ───
15
+ const KEYWORD_MAP = {
16
+ 'function': 'ƒ',
17
+ 'const': '¢',
18
+ 'let': 'ℓ',
19
+ 'return': '⏎',
20
+ 'export': '⨂',
21
+ 'async': '⨁',
22
+ 'await': '⨀',
23
+ 'import': '⨃',
24
+ 'Promise': '⨄',
25
+ 'interface': '⨅',
26
+ 'class': '⨆',
27
+ 'undefined': '⨇',
28
+ 'null': '⨈',
29
+ 'console.log': '⨍',
30
+ 'console.error': '⨎',
31
+ 'console.warn': '⨏',
32
+ 'this.': '⨌',
33
+ 'public': '⨗',
34
+ 'private': '⨘',
35
+ 'protected': '⨙',
36
+ 'static': '⨚',
37
+ 'constructor': '⨛',
38
+ 'implements': '⨜',
39
+ 'extends': '⨝'
40
+ };
41
+ // Reverse map for decompression
42
+ const REVERSE_KEYWORD_MAP = {};
43
+ for (const [k, v] of Object.entries(KEYWORD_MAP)) {
44
+ REVERSE_KEYWORD_MAP[v] = k;
45
+ }
46
+ /**
47
+ * Compresses source code into a Wormhole representation.
48
+ */
49
+ function compressWormhole(code) {
50
+ // 1. Strip comments first to maximize savings (since this is reversible, comments are lost,
51
+ // but for LLM context reading that is exactly what we want)
52
+ let clean = code
53
+ .replace(/\/\*[\s\S]*?\*\//g, '')
54
+ .replace(/\/\/.*$/gm, '')
55
+ .split('\n')
56
+ .map(line => line.trimEnd())
57
+ .filter(line => line.trim().length > 0)
58
+ .join('\n');
59
+ // 2. Identify long repeating identifiers (camelCase/PascalCase > 6 chars)
60
+ const identifierRegex = /\b[a-zA-Z_][a-zA-Z0-9_]{5,}\b/g;
61
+ const matches = clean.match(identifierRegex) || [];
62
+ const freq = {};
63
+ for (const m of matches) {
64
+ // Skip words that are standard keywords
65
+ if (KEYWORD_MAP[m] || m === 'String' || m === 'Number' || m === 'Boolean' || m === 'Object' || m === 'Array')
66
+ continue;
67
+ freq[m] = (freq[m] || 0) + 1;
68
+ }
69
+ // Filter identifiers that appear at least twice
70
+ const sortedIdentifiers = Object.entries(freq)
71
+ .filter(([, count]) => count >= 2)
72
+ .sort((a, b) => b[1] - a[1])
73
+ .map(([word]) => word);
74
+ // 3. Create short alias map ($a, $b, ... $z, $A, $B...)
75
+ const dictionary = {};
76
+ const revDictionary = {};
77
+ const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
78
+ let aliasIndex = 0;
79
+ for (const word of sortedIdentifiers) {
80
+ if (aliasIndex >= chars.length)
81
+ break; // cap at 52 unique replacements
82
+ const alias = `$${chars[aliasIndex]}`;
83
+ dictionary[word] = alias;
84
+ revDictionary[alias] = word;
85
+ aliasIndex++;
86
+ }
87
+ // 4. Perform replacements
88
+ let payload = clean;
89
+ // Replace identifiers
90
+ for (const [word, alias] of Object.entries(dictionary)) {
91
+ // Use word boundary to avoid partial replacements
92
+ const escaped = word.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
93
+ const regex = new RegExp(`\\b${escaped}\\b`, 'g');
94
+ payload = payload.replace(regex, alias);
95
+ }
96
+ // Replace standard keywords
97
+ for (const [word, alias] of Object.entries(KEYWORD_MAP)) {
98
+ // Avoid boundary checks for things ending/starting with special characters like "this." or "console."
99
+ if (word.includes('.')) {
100
+ payload = payload.split(word).join(alias);
101
+ }
102
+ else {
103
+ const regex = new RegExp(`\\b${word}\\b`, 'g');
104
+ payload = payload.replace(regex, alias);
105
+ }
106
+ }
107
+ // Collapse extra whitespace/consecutive spaces
108
+ payload = payload.replace(/[ \t]+/g, ' ');
109
+ // 5. Serialize with Dictionary Header
110
+ const dictHeader = Object.entries(revDictionary)
111
+ .map(([alias, word]) => `${alias}=${word}`)
112
+ .join(',');
113
+ return `⸎WORMHOLE;DICT:[${dictHeader}]\n${payload}`;
114
+ }
115
+ /**
116
+ * Reverts a Wormhole-compressed payload back to standard source code.
117
+ */
118
+ function decompressWormhole(wormholeCode) {
119
+ if (!wormholeCode.startsWith('⸎WORMHOLE;DICT:[')) {
120
+ return wormholeCode; // Not a wormhole payload
121
+ }
122
+ const headerEnd = wormholeCode.indexOf(']\n');
123
+ if (headerEnd === -1)
124
+ return wormholeCode;
125
+ const header = wormholeCode.substring('⸎WORMHOLE;DICT:['.length, headerEnd);
126
+ let payload = wormholeCode.substring(headerEnd + 2);
127
+ // Parse dictionary
128
+ const dictionary = {};
129
+ if (header.trim().length > 0) {
130
+ const parts = header.split(',');
131
+ for (const part of parts) {
132
+ const eqIdx = part.indexOf('=');
133
+ if (eqIdx !== -1) {
134
+ const alias = part.substring(0, eqIdx);
135
+ const word = part.substring(eqIdx + 1);
136
+ dictionary[alias] = word;
137
+ }
138
+ }
139
+ }
140
+ // 1. Decompress standard keywords
141
+ for (const [alias, word] of Object.entries(REVERSE_KEYWORD_MAP)) {
142
+ payload = payload.split(alias).join(word);
143
+ }
144
+ // 2. Decompress custom identifiers
145
+ for (const [alias, word] of Object.entries(dictionary)) {
146
+ const escaped = alias.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
147
+ const regex = new RegExp(`${escaped}\\b`, 'g');
148
+ payload = payload.replace(regex, word);
149
+ }
150
+ return payload;
151
+ }
152
+ //# sourceMappingURL=WormholeCompressor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WormholeCompressor.js","sourceRoot":"","sources":["../../../src/utils/WormholeCompressor.ts"],"names":[],"mappings":"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"}
@@ -3,9 +3,10 @@ export declare class AutopilotWatcher {
3
3
  private watchDir;
4
4
  private debounceTimer;
5
5
  private activeBuildProcess;
6
- constructor(watchDir?: string);
6
+ private nonInvasive;
7
+ constructor(watchDir?: string, nonInvasive?: boolean);
7
8
  start(): void;
8
- private triggerBuildAndHeal;
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":"AAKA,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,kBAAkB,CAAa;gBAE3B,QAAQ,GAAE,MAAc;IAIpC,KAAK;IAuBL,OAAO,CAAC,mBAAmB;IAuF3B,IAAI;CAML"}
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[Autopilot]\x1b[0m Starting active background watcher on: ${this.watchDir}`);
17
- console.log(`💡 \x1b[36mAutopilot is actively monitoring your saves. Make code errors and watch them heal!\x1b[0m\n`);
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.triggerBuildAndHeal(filename);
31
+ this.triggerBuild(filename);
31
32
  }, 1500);
32
33
  });
33
34
  }
34
- triggerBuildAndHeal(modifiedFile) {
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
- console.log(`❌ \x1b[31m[Autopilot] Compilation error detected!\x1b[0m`);
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
- const file = match[1];
70
- const line = match[2];
71
- const errorMsg = match[4];
72
- console.log(`🩺 \x1b[35m[Autopilot] Parser details:\x1b[0m File: ${file}, Line: ${line}, Error: ${errorMsg}`);
73
- // Write the crash state to both projectRoot/.lemma/live-context.md and process.cwd()/.lemma/live-context.md
74
- const contextDirs = [
75
- path.join(projectRoot, '.lemma'),
76
- path.join(process.cwd(), '.lemma')
77
- ];
78
- for (const dir of contextDirs) {
79
- if (!fs.existsSync(dir)) {
80
- fs.mkdirSync(dir, { recursive: true });
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
- fs.writeFileSync(path.join(dir, 'live-context.md'), liveContextContent, 'utf8');
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
- else {
107
- console.log(`⚠️ \x1b[33m[Autopilot] Could not parse compile error layout automatically. Output:\x1b[0m`);
108
- console.log(output.trim().substring(0, 300) + '...');
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(`🛸 \x1b[35m[Autopilot]\x1b[0m Background watcher stopped.`);
112
+ console.log(`\n🛸 \x1b[35m[Lemma Watch]\x1b[0m Background watcher stopped.`);
119
113
  }
120
114
  }
121
115
  //# sourceMappingURL=AutopilotWatcher.js.map