@nxuss/lemma 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +203 -95
- package/dist/cjs/mcp/prompts.d.ts +1 -1
- package/dist/cjs/mcp/prompts.d.ts.map +1 -1
- package/dist/cjs/mcp/prompts.js +24 -0
- package/dist/cjs/mcp/prompts.js.map +1 -1
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +497 -0
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/cjs/utils/AutoContextBundle.d.ts +17 -0
- package/dist/cjs/utils/AutoContextBundle.d.ts.map +1 -0
- package/dist/cjs/utils/AutoContextBundle.js +125 -0
- package/dist/cjs/utils/AutoContextBundle.js.map +1 -0
- package/dist/cjs/utils/BulkFileDigest.d.ts +13 -0
- package/dist/cjs/utils/BulkFileDigest.d.ts.map +1 -0
- package/dist/cjs/utils/BulkFileDigest.js +64 -0
- package/dist/cjs/utils/BulkFileDigest.js.map +1 -0
- package/dist/cjs/utils/ConversationCheckpoint.d.ts +14 -0
- package/dist/cjs/utils/ConversationCheckpoint.d.ts.map +1 -0
- package/dist/cjs/utils/ConversationCheckpoint.js +77 -0
- package/dist/cjs/utils/ConversationCheckpoint.js.map +1 -0
- package/dist/cjs/utils/FileFingerprint.d.ts +11 -0
- package/dist/cjs/utils/FileFingerprint.d.ts.map +1 -0
- package/dist/cjs/utils/FileFingerprint.js +64 -0
- package/dist/cjs/utils/FileFingerprint.js.map +1 -0
- package/dist/cjs/utils/GitBlameHeat.d.ts +20 -0
- package/dist/cjs/utils/GitBlameHeat.d.ts.map +1 -0
- package/dist/cjs/utils/GitBlameHeat.js +91 -0
- package/dist/cjs/utils/GitBlameHeat.js.map +1 -0
- package/dist/cjs/utils/ImportTreeContext.d.ts +17 -0
- package/dist/cjs/utils/ImportTreeContext.d.ts.map +1 -0
- package/dist/cjs/utils/ImportTreeContext.js +159 -0
- package/dist/cjs/utils/ImportTreeContext.js.map +1 -0
- package/dist/cjs/utils/PromptPatternCache.d.ts +14 -0
- package/dist/cjs/utils/PromptPatternCache.d.ts.map +1 -0
- package/dist/cjs/utils/PromptPatternCache.js +104 -0
- package/dist/cjs/utils/PromptPatternCache.js.map +1 -0
- package/dist/cjs/utils/RepeatGuard.d.ts +9 -0
- package/dist/cjs/utils/RepeatGuard.d.ts.map +1 -0
- package/dist/cjs/utils/RepeatGuard.js +90 -0
- package/dist/cjs/utils/RepeatGuard.js.map +1 -0
- package/dist/cjs/utils/TestAutofixInterceptor.d.ts +17 -0
- package/dist/cjs/utils/TestAutofixInterceptor.d.ts.map +1 -0
- package/dist/cjs/utils/TestAutofixInterceptor.js +125 -0
- package/dist/cjs/utils/TestAutofixInterceptor.js.map +1 -0
- package/dist/cjs/utils/TokenBudgetedReader.d.ts +14 -0
- package/dist/cjs/utils/TokenBudgetedReader.d.ts.map +1 -0
- package/dist/cjs/utils/TokenBudgetedReader.js +157 -0
- package/dist/cjs/utils/TokenBudgetedReader.js.map +1 -0
- package/dist/cjs/utils/TypeCoverage.d.ts +15 -0
- package/dist/cjs/utils/TypeCoverage.d.ts.map +1 -0
- package/dist/cjs/utils/TypeCoverage.js +141 -0
- package/dist/cjs/utils/TypeCoverage.js.map +1 -0
- package/dist/esm/mcp/prompts.d.ts +1 -1
- package/dist/esm/mcp/prompts.d.ts.map +1 -1
- package/dist/esm/mcp/prompts.js +24 -0
- package/dist/esm/mcp/prompts.js.map +1 -1
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +497 -0
- package/dist/esm/mcp/tools.js.map +1 -1
- package/dist/esm/utils/AutoContextBundle.d.ts +17 -0
- package/dist/esm/utils/AutoContextBundle.d.ts.map +1 -0
- package/dist/esm/utils/AutoContextBundle.js +86 -0
- package/dist/esm/utils/AutoContextBundle.js.map +1 -0
- package/dist/esm/utils/BulkFileDigest.d.ts +13 -0
- package/dist/esm/utils/BulkFileDigest.d.ts.map +1 -0
- package/dist/esm/utils/BulkFileDigest.js +58 -0
- package/dist/esm/utils/BulkFileDigest.js.map +1 -0
- package/dist/esm/utils/ConversationCheckpoint.d.ts +14 -0
- package/dist/esm/utils/ConversationCheckpoint.d.ts.map +1 -0
- package/dist/esm/utils/ConversationCheckpoint.js +69 -0
- package/dist/esm/utils/ConversationCheckpoint.js.map +1 -0
- package/dist/esm/utils/FileFingerprint.d.ts +11 -0
- package/dist/esm/utils/FileFingerprint.d.ts.map +1 -0
- package/dist/esm/utils/FileFingerprint.js +56 -0
- package/dist/esm/utils/FileFingerprint.js.map +1 -0
- package/dist/esm/utils/GitBlameHeat.d.ts +20 -0
- package/dist/esm/utils/GitBlameHeat.d.ts.map +1 -0
- package/dist/esm/utils/GitBlameHeat.js +85 -0
- package/dist/esm/utils/GitBlameHeat.js.map +1 -0
- package/dist/esm/utils/ImportTreeContext.d.ts +17 -0
- package/dist/esm/utils/ImportTreeContext.d.ts.map +1 -0
- package/dist/esm/utils/ImportTreeContext.js +153 -0
- package/dist/esm/utils/ImportTreeContext.js.map +1 -0
- package/dist/esm/utils/PromptPatternCache.d.ts +14 -0
- package/dist/esm/utils/PromptPatternCache.d.ts.map +1 -0
- package/dist/esm/utils/PromptPatternCache.js +96 -0
- package/dist/esm/utils/PromptPatternCache.js.map +1 -0
- package/dist/esm/utils/RepeatGuard.d.ts +9 -0
- package/dist/esm/utils/RepeatGuard.d.ts.map +1 -0
- package/dist/esm/utils/RepeatGuard.js +83 -0
- package/dist/esm/utils/RepeatGuard.js.map +1 -0
- package/dist/esm/utils/TestAutofixInterceptor.d.ts +17 -0
- package/dist/esm/utils/TestAutofixInterceptor.d.ts.map +1 -0
- package/dist/esm/utils/TestAutofixInterceptor.js +122 -0
- package/dist/esm/utils/TestAutofixInterceptor.js.map +1 -0
- package/dist/esm/utils/TokenBudgetedReader.d.ts +14 -0
- package/dist/esm/utils/TokenBudgetedReader.d.ts.map +1 -0
- package/dist/esm/utils/TokenBudgetedReader.js +118 -0
- package/dist/esm/utils/TokenBudgetedReader.js.map +1 -0
- package/dist/esm/utils/TypeCoverage.d.ts +15 -0
- package/dist/esm/utils/TypeCoverage.d.ts.map +1 -0
- package/dist/esm/utils/TypeCoverage.js +102 -0
- package/dist/esm/utils/TypeCoverage.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
const IGNORE_DIRS = ['node_modules', '.git', 'dist', 'build', '.next', 'chroma_data'];
|
|
4
|
+
function parseImports(content) {
|
|
5
|
+
const entries = [];
|
|
6
|
+
// ES module imports: import [type] [symbols] from 'source'
|
|
7
|
+
// Handles: import { a } from 'x', import X from 'x', import * as X from 'x', import 'x'
|
|
8
|
+
const importRegex = /import\s+(?:type\s+)?(?:(\w+)\s+from\s+|{([^}]*)}\s+from\s+|\*\s*as\s+\w+\s+from\s+)?['"]([^'"]+)['"]/g;
|
|
9
|
+
let match;
|
|
10
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
11
|
+
const defaultImport = match[1] || '';
|
|
12
|
+
const namedImports = match[2]
|
|
13
|
+
? match[2].split(',').map(s => s.trim().split(/\s+as\s+/)[0].trim()).filter(Boolean)
|
|
14
|
+
: [];
|
|
15
|
+
const source = match[3];
|
|
16
|
+
const isLocal = source.startsWith('.') || source.startsWith('/');
|
|
17
|
+
const symbols = [...(defaultImport ? [defaultImport] : []), ...namedImports];
|
|
18
|
+
if (symbols.length > 0 || isLocal) {
|
|
19
|
+
entries.push({ source, symbols, isLocal });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Re-export: export { a } from 'x' or export * from 'x'
|
|
23
|
+
const reExportRegex = /export\s+(?:type\s+)?(?:{([^}]*)}|\*)\s+from\s+['"]([^'"]+)['"]/g;
|
|
24
|
+
while ((match = reExportRegex.exec(content)) !== null) {
|
|
25
|
+
const namedExports = match[1]
|
|
26
|
+
? match[1].split(',').map(s => s.trim().split(/\s+as\s+/)[0].trim()).filter(Boolean)
|
|
27
|
+
: [];
|
|
28
|
+
const source = match[2];
|
|
29
|
+
const isLocal = source.startsWith('.') || source.startsWith('/');
|
|
30
|
+
if (namedExports.length > 0 || isLocal) {
|
|
31
|
+
entries.push({ source, symbols: namedExports, isLocal });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// CommonJS: require('x')
|
|
35
|
+
const requireRegex = /(?:const|let|var)\s+(?:{([^}]+)}|(\w+))\s*=\s*require\(['"]([^'"]+)['"]\)/g;
|
|
36
|
+
while ((match = requireRegex.exec(content)) !== null) {
|
|
37
|
+
const namedImports = match[1]
|
|
38
|
+
? match[1].split(',').map(s => s.trim().split(/\s*:\s*\w+/)[0].trim()).filter(Boolean)
|
|
39
|
+
: [];
|
|
40
|
+
const defaultImport = match[2] || '';
|
|
41
|
+
const source = match[3];
|
|
42
|
+
const isLocal = source.startsWith('.') || source.startsWith('/');
|
|
43
|
+
const symbols = [...(defaultImport ? [defaultImport] : []), ...namedImports];
|
|
44
|
+
if (symbols.length > 0 || isLocal) {
|
|
45
|
+
entries.push({ source, symbols, isLocal });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return entries;
|
|
49
|
+
}
|
|
50
|
+
function resolveImportPath(source, fromFile, projectRoot) {
|
|
51
|
+
if (!source.startsWith('.'))
|
|
52
|
+
return null;
|
|
53
|
+
const dir = path.dirname(fromFile);
|
|
54
|
+
const candidates = [
|
|
55
|
+
path.join(dir, source),
|
|
56
|
+
path.join(dir, source + '.ts'),
|
|
57
|
+
path.join(dir, source + '.tsx'),
|
|
58
|
+
path.join(dir, source, 'index.ts'),
|
|
59
|
+
path.join(dir, source, 'index.tsx'),
|
|
60
|
+
path.join(dir, source + '.js'),
|
|
61
|
+
path.join(dir, source, 'index.js'),
|
|
62
|
+
];
|
|
63
|
+
for (const c of candidates) {
|
|
64
|
+
const resolved = path.resolve(projectRoot, c);
|
|
65
|
+
if (fs.existsSync(resolved))
|
|
66
|
+
return path.relative(projectRoot, resolved);
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
function collectFiles(dir, projectRoot, depth, maxDepth) {
|
|
71
|
+
if (depth > maxDepth)
|
|
72
|
+
return [];
|
|
73
|
+
try {
|
|
74
|
+
const entries = fs.readdirSync(path.resolve(projectRoot, dir), { withFileTypes: true });
|
|
75
|
+
const files = [];
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
if (IGNORE_DIRS.includes(entry.name))
|
|
78
|
+
continue;
|
|
79
|
+
const rel = dir ? `${dir}/${entry.name}` : entry.name;
|
|
80
|
+
if (entry.isDirectory()) {
|
|
81
|
+
files.push(...collectFiles(rel, projectRoot, depth + 1, maxDepth));
|
|
82
|
+
}
|
|
83
|
+
else if (/\.(ts|tsx|js|jsx)$/.test(entry.name)) {
|
|
84
|
+
files.push(rel);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return files;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function buildImportTree(filePath, projectRoot, depth = 2) {
|
|
94
|
+
const dir = path.dirname(filePath);
|
|
95
|
+
const files = collectFiles(dir === '.' ? '' : dir, projectRoot, 0, depth + 1);
|
|
96
|
+
if (!files.includes(filePath))
|
|
97
|
+
files.unshift(filePath);
|
|
98
|
+
const nodeMap = {};
|
|
99
|
+
for (const f of files) {
|
|
100
|
+
nodeMap[f] = { file: f, imports: [], importedBy: [] };
|
|
101
|
+
}
|
|
102
|
+
for (const f of files) {
|
|
103
|
+
const resolved = path.resolve(projectRoot, f);
|
|
104
|
+
try {
|
|
105
|
+
const content = fs.readFileSync(resolved, 'utf8');
|
|
106
|
+
const imports = parseImports(content);
|
|
107
|
+
for (const imp of imports) {
|
|
108
|
+
const target = resolveImportPath(imp.source, f, projectRoot);
|
|
109
|
+
if (target && nodeMap[target]) {
|
|
110
|
+
nodeMap[f].imports.push(imp);
|
|
111
|
+
nodeMap[target].importedBy.push(f);
|
|
112
|
+
}
|
|
113
|
+
else if (!imp.isLocal) {
|
|
114
|
+
nodeMap[f].imports.push(imp);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch { }
|
|
119
|
+
}
|
|
120
|
+
const nodes = Object.values(nodeMap);
|
|
121
|
+
const rootNode = nodeMap[filePath] || nodes[0];
|
|
122
|
+
const summaryLines = [`# Import Tree: ${filePath}\n`];
|
|
123
|
+
function renderNode(file, indent) {
|
|
124
|
+
const node = nodeMap[file];
|
|
125
|
+
if (!node)
|
|
126
|
+
return;
|
|
127
|
+
const prefix = ' '.repeat(indent);
|
|
128
|
+
const localImports = node.imports.filter(i => i.isLocal);
|
|
129
|
+
const extImports = node.imports.filter(i => !i.isLocal);
|
|
130
|
+
summaryLines.push(`${prefix}\`${file}\``);
|
|
131
|
+
if (localImports.length > 0) {
|
|
132
|
+
for (const imp of localImports) {
|
|
133
|
+
const resolved = resolveImportPath(imp.source, file, projectRoot);
|
|
134
|
+
summaryLines.push(`${prefix} -> ${imp.symbols.join(', ')} from \`${imp.source}\`${resolved ? ` (\`${resolved}\`)` : ''}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (extImports.length > 0) {
|
|
138
|
+
const extPkgs = [...new Set(extImports.map(imp => imp.source.split('/')[0] || imp.source))];
|
|
139
|
+
summaryLines.push(`${prefix} [ext] ${extPkgs.join(', ')}`);
|
|
140
|
+
}
|
|
141
|
+
if (node.importedBy.length > 0) {
|
|
142
|
+
summaryLines.push(`${prefix} ^ imported by: ${node.importedBy.map(f => `\`${f}\``).join(', ')}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
renderNode(filePath, 0);
|
|
146
|
+
for (const imp of (rootNode?.imports || []).filter(i => i.isLocal)) {
|
|
147
|
+
const resolved = resolveImportPath(imp.source, filePath, projectRoot);
|
|
148
|
+
if (resolved)
|
|
149
|
+
renderNode(resolved, 1);
|
|
150
|
+
}
|
|
151
|
+
return { root: filePath, nodes, summary: summaryLines.join('\n') };
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=ImportTreeContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImportTreeContext.js","sourceRoot":"","sources":["../../../src/utils/ImportTreeContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface PromptPattern {
|
|
2
|
+
id: string;
|
|
3
|
+
keywords: string[];
|
|
4
|
+
template: string;
|
|
5
|
+
hitCount: number;
|
|
6
|
+
avgTokensSaved: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function findPattern(query: string, projectRoot: string, threshold?: number): PromptPattern | null;
|
|
9
|
+
export declare function storePattern(query: string, template: string, tokensSaved: number, projectRoot: string): PromptPattern;
|
|
10
|
+
export declare function getPatternStats(projectRoot: string): {
|
|
11
|
+
totalPatterns: number;
|
|
12
|
+
topPatterns: PromptPattern[];
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=PromptPatternCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromptPatternCache.d.ts","sourceRoot":"","sources":["../../../src/utils/PromptPatternCache.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AA8CD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,aAAa,GAAG,IAAI,CAqB7G;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,aAAa,CAgCf;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,aAAa,EAAE,CAAA;CAAE,CAQ5G"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
const CACHE_FILE = '.lemma/prompt-patterns.json';
|
|
4
|
+
function getCachePath(projectRoot) {
|
|
5
|
+
return path.join(projectRoot, CACHE_FILE);
|
|
6
|
+
}
|
|
7
|
+
function loadCache(projectRoot) {
|
|
8
|
+
try {
|
|
9
|
+
const p = getCachePath(projectRoot);
|
|
10
|
+
if (fs.existsSync(p))
|
|
11
|
+
return JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
12
|
+
}
|
|
13
|
+
catch { }
|
|
14
|
+
return { patterns: [], lastUpdated: Date.now() };
|
|
15
|
+
}
|
|
16
|
+
function saveCache(projectRoot, data) {
|
|
17
|
+
try {
|
|
18
|
+
const dir = path.join(projectRoot, '.lemma');
|
|
19
|
+
if (!fs.existsSync(dir))
|
|
20
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
21
|
+
fs.writeFileSync(getCachePath(projectRoot), JSON.stringify(data, null, 2), 'utf8');
|
|
22
|
+
}
|
|
23
|
+
catch { }
|
|
24
|
+
}
|
|
25
|
+
function extractKeywords(text) {
|
|
26
|
+
return text.toLowerCase()
|
|
27
|
+
.replace(/[^a-z0-9\s]/g, '')
|
|
28
|
+
.split(/\s+/)
|
|
29
|
+
.filter(w => w.length > 3)
|
|
30
|
+
.slice(0, 20);
|
|
31
|
+
}
|
|
32
|
+
function matchScore(inputKeywords, patternKeywords) {
|
|
33
|
+
if (patternKeywords.length === 0)
|
|
34
|
+
return 0;
|
|
35
|
+
let matches = 0;
|
|
36
|
+
for (const pk of patternKeywords) {
|
|
37
|
+
if (inputKeywords.some(ik => ik.includes(pk) || pk.includes(ik)))
|
|
38
|
+
matches++;
|
|
39
|
+
}
|
|
40
|
+
return matches / patternKeywords.length;
|
|
41
|
+
}
|
|
42
|
+
export function findPattern(query, projectRoot, threshold = 0.5) {
|
|
43
|
+
const cache = loadCache(projectRoot);
|
|
44
|
+
const inputKw = extractKeywords(query);
|
|
45
|
+
let best = null;
|
|
46
|
+
let bestScore = 0;
|
|
47
|
+
for (const p of cache.patterns) {
|
|
48
|
+
const score = matchScore(inputKw, p.keywords);
|
|
49
|
+
if (score > bestScore && score >= threshold) {
|
|
50
|
+
bestScore = score;
|
|
51
|
+
best = p;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (best) {
|
|
55
|
+
best.hitCount++;
|
|
56
|
+
saveCache(projectRoot, cache);
|
|
57
|
+
}
|
|
58
|
+
return best;
|
|
59
|
+
}
|
|
60
|
+
export function storePattern(query, template, tokensSaved, projectRoot) {
|
|
61
|
+
const cache = loadCache(projectRoot);
|
|
62
|
+
const keywords = extractKeywords(query);
|
|
63
|
+
const id = `pattern-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
64
|
+
const existing = cache.patterns.find(p => matchScore(keywords, p.keywords) > 0.7);
|
|
65
|
+
if (existing) {
|
|
66
|
+
existing.hitCount++;
|
|
67
|
+
existing.avgTokensSaved = (existing.avgTokensSaved + tokensSaved) / 2;
|
|
68
|
+
saveCache(projectRoot, cache);
|
|
69
|
+
return existing;
|
|
70
|
+
}
|
|
71
|
+
const pattern = {
|
|
72
|
+
id,
|
|
73
|
+
keywords,
|
|
74
|
+
template,
|
|
75
|
+
hitCount: 1,
|
|
76
|
+
avgTokensSaved: tokensSaved,
|
|
77
|
+
};
|
|
78
|
+
cache.patterns.push(pattern);
|
|
79
|
+
cache.lastUpdated = Date.now();
|
|
80
|
+
// prune low-value patterns
|
|
81
|
+
cache.patterns = cache.patterns
|
|
82
|
+
.sort((a, b) => (b.hitCount * b.avgTokensSaved) - (a.hitCount * a.avgTokensSaved))
|
|
83
|
+
.slice(0, 50);
|
|
84
|
+
saveCache(projectRoot, cache);
|
|
85
|
+
return pattern;
|
|
86
|
+
}
|
|
87
|
+
export function getPatternStats(projectRoot) {
|
|
88
|
+
const cache = loadCache(projectRoot);
|
|
89
|
+
return {
|
|
90
|
+
totalPatterns: cache.patterns.length,
|
|
91
|
+
topPatterns: cache.patterns
|
|
92
|
+
.sort((a, b) => b.hitCount - a.hitCount)
|
|
93
|
+
.slice(0, 10),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=PromptPatternCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromptPatternCache.js","sourceRoot":"","sources":["../../../src/utils/PromptPatternCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface RepeatGuardResult {
|
|
2
|
+
isRepeat: boolean;
|
|
3
|
+
similarity: number;
|
|
4
|
+
previousOutput?: string;
|
|
5
|
+
suggestion: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function recordOutput(output: string, projectRoot: string): void;
|
|
8
|
+
export declare function checkRepeat(draftOutput: string, projectRoot: string, threshold?: number): RepeatGuardResult;
|
|
9
|
+
//# sourceMappingURL=RepeatGuard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RepeatGuard.d.ts","sourceRoot":"","sources":["../../../src/utils/RepeatGuard.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAoDD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAMtE;AAED,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,MAAa,GACvB,iBAAiB,CAiCnB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
const HISTORY_FILE = '.lemma/session/output-history.json';
|
|
4
|
+
const MAX_HISTORY = 20;
|
|
5
|
+
function getHistoryPath(projectRoot) {
|
|
6
|
+
return path.join(projectRoot, HISTORY_FILE);
|
|
7
|
+
}
|
|
8
|
+
function loadHistory(projectRoot) {
|
|
9
|
+
try {
|
|
10
|
+
const p = getHistoryPath(projectRoot);
|
|
11
|
+
if (fs.existsSync(p))
|
|
12
|
+
return JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
13
|
+
}
|
|
14
|
+
catch { }
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
function saveHistory(projectRoot, history) {
|
|
18
|
+
try {
|
|
19
|
+
const dir = path.join(projectRoot, '.lemma', 'session');
|
|
20
|
+
if (!fs.existsSync(dir))
|
|
21
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
22
|
+
fs.writeFileSync(getHistoryPath(projectRoot), JSON.stringify(history.slice(-MAX_HISTORY), null, 2), 'utf8');
|
|
23
|
+
}
|
|
24
|
+
catch { }
|
|
25
|
+
}
|
|
26
|
+
function fingerprint(text) {
|
|
27
|
+
const words = text.toLowerCase()
|
|
28
|
+
.replace(/[^a-z0-9\s]/g, '')
|
|
29
|
+
.split(/\s+/)
|
|
30
|
+
.filter(w => w.length > 3)
|
|
31
|
+
.sort();
|
|
32
|
+
const unique = [...new Set(words)];
|
|
33
|
+
return unique.join(' ');
|
|
34
|
+
}
|
|
35
|
+
function jaccardSimilarity(a, b) {
|
|
36
|
+
const setA = new Set(a.split(' '));
|
|
37
|
+
const setB = new Set(b.split(' '));
|
|
38
|
+
if (setA.size === 0 && setB.size === 0)
|
|
39
|
+
return 0;
|
|
40
|
+
let inter = 0;
|
|
41
|
+
for (const w of setA) {
|
|
42
|
+
if (setB.has(w))
|
|
43
|
+
inter++;
|
|
44
|
+
}
|
|
45
|
+
return inter / (setA.size + setB.size - inter);
|
|
46
|
+
}
|
|
47
|
+
export function recordOutput(output, projectRoot) {
|
|
48
|
+
const history = loadHistory(projectRoot);
|
|
49
|
+
const hash = fingerprint(output);
|
|
50
|
+
const preview = output.slice(0, 200).replace(/\n/g, ' ');
|
|
51
|
+
history.push({ hash, timestamp: Date.now(), preview });
|
|
52
|
+
saveHistory(projectRoot, history);
|
|
53
|
+
}
|
|
54
|
+
export function checkRepeat(draftOutput, projectRoot, threshold = 0.75) {
|
|
55
|
+
const history = loadHistory(projectRoot);
|
|
56
|
+
const draftFp = fingerprint(draftOutput);
|
|
57
|
+
if (history.length === 0) {
|
|
58
|
+
return { isRepeat: false, similarity: 0, suggestion: 'No previous outputs to compare.' };
|
|
59
|
+
}
|
|
60
|
+
let maxSim = 0;
|
|
61
|
+
let mostSimilar;
|
|
62
|
+
for (const entry of history) {
|
|
63
|
+
const sim = jaccardSimilarity(draftFp, entry.hash);
|
|
64
|
+
if (sim > maxSim) {
|
|
65
|
+
maxSim = sim;
|
|
66
|
+
mostSimilar = entry;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (maxSim >= threshold) {
|
|
70
|
+
return {
|
|
71
|
+
isRepeat: true,
|
|
72
|
+
similarity: Math.round(maxSim * 100) / 100,
|
|
73
|
+
previousOutput: mostSimilar?.preview,
|
|
74
|
+
suggestion: `This output is ${Math.round(maxSim * 100)}% similar to a previous response. Consider rephrasing or checking if the user already has this information.`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
isRepeat: false,
|
|
79
|
+
similarity: Math.round(maxSim * 100) / 100,
|
|
80
|
+
suggestion: maxSim > 0.5 ? `Moderate similarity (${Math.round(maxSim * 100)}%) to previous output. Probably fine.` : 'No significant repetition detected.',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=RepeatGuard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RepeatGuard.js","sourceRoot":"","sources":["../../../src/utils/RepeatGuard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface TestFailure {
|
|
2
|
+
testName: string;
|
|
3
|
+
error: string;
|
|
4
|
+
file?: string;
|
|
5
|
+
suggestedFix?: string;
|
|
6
|
+
brainHit: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface TestAutofixResult {
|
|
9
|
+
totalTests: number;
|
|
10
|
+
passed: number;
|
|
11
|
+
failed: number;
|
|
12
|
+
failures: TestFailure[];
|
|
13
|
+
autoFixAvailable: number;
|
|
14
|
+
rawOutput: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function runTestAutofix(command: string | undefined, projectRoot: string): TestAutofixResult;
|
|
17
|
+
//# sourceMappingURL=TestAutofixInterceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestAutofixInterceptor.d.ts","sourceRoot":"","sources":["../../../src/utils/TestAutofixInterceptor.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AA2FD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,YAAa,EAC5B,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAmCnB"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
function extractFailures(output) {
|
|
3
|
+
const failures = [];
|
|
4
|
+
// Jest/Vitest failure pattern
|
|
5
|
+
const jestPattern = /FAIL\s+(.+?)\n[\s\S]*?●\s+(.+?)\n\n([\s\S]*?)(?=\n\s*(?:●|Tests:|Test Suites:))/g;
|
|
6
|
+
let match;
|
|
7
|
+
while ((match = jestPattern.exec(output)) !== null) {
|
|
8
|
+
failures.push({
|
|
9
|
+
file: match[1]?.trim(),
|
|
10
|
+
testName: match[2]?.trim(),
|
|
11
|
+
error: match[3]?.trim().slice(0, 500),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
// Simpler fallback: capture lines after "FAIL" or "✕"
|
|
15
|
+
if (failures.length === 0) {
|
|
16
|
+
const lines = output.split('\n');
|
|
17
|
+
for (let i = 0; i < lines.length; i++) {
|
|
18
|
+
if (lines[i].includes('✕') || lines[i].includes('FAIL')) {
|
|
19
|
+
const testName = lines[i].replace(/[✕✗✘FAIL]\s*/, '').trim();
|
|
20
|
+
const errorLines = [];
|
|
21
|
+
for (let j = i + 1; j < Math.min(i + 10, lines.length); j++) {
|
|
22
|
+
if (lines[j].trim())
|
|
23
|
+
errorLines.push(lines[j].trim());
|
|
24
|
+
}
|
|
25
|
+
if (testName) {
|
|
26
|
+
failures.push({ testName, error: errorLines.join('\n').slice(0, 500) });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return failures;
|
|
32
|
+
}
|
|
33
|
+
function extractTestCounts(output) {
|
|
34
|
+
let total = 0, passed = 0, failed = 0;
|
|
35
|
+
const totalMatch = output.match(/Tests:\s+(\d+)\s+total/);
|
|
36
|
+
if (totalMatch)
|
|
37
|
+
total = parseInt(totalMatch[1], 10);
|
|
38
|
+
const passedMatch = output.match(/(\d+)\s+passed/);
|
|
39
|
+
if (passedMatch)
|
|
40
|
+
passed = parseInt(passedMatch[1], 10);
|
|
41
|
+
const failedMatch = output.match(/(\d+)\s+failed/);
|
|
42
|
+
if (failedMatch)
|
|
43
|
+
failed = parseInt(failedMatch[1], 10);
|
|
44
|
+
if (total === 0 && passed === 0 && failed === 0) {
|
|
45
|
+
const passMatch = output.match(/(\d+)\s+passed.*?(\d+)\s+failed/);
|
|
46
|
+
if (passMatch) {
|
|
47
|
+
passed = parseInt(passMatch[1], 10);
|
|
48
|
+
failed = parseInt(passMatch[2], 10);
|
|
49
|
+
total = passed + failed;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { total, passed, failed };
|
|
53
|
+
}
|
|
54
|
+
function searchBrainForFix(errorMessage, projectRoot) {
|
|
55
|
+
try {
|
|
56
|
+
const fs = require('fs');
|
|
57
|
+
const path = require('path');
|
|
58
|
+
const brainDir = path.join(projectRoot, '.lemma', 'memory');
|
|
59
|
+
if (!fs.existsSync(brainDir))
|
|
60
|
+
return { fix: null, hit: false };
|
|
61
|
+
const errorTokens = errorMessage.toLowerCase().split(/\s+/).filter((t) => t.length > 3);
|
|
62
|
+
const files = fs.readdirSync(brainDir).filter((f) => f.endsWith('.json'));
|
|
63
|
+
let bestScore = 0;
|
|
64
|
+
let bestFix = null;
|
|
65
|
+
for (const f of files) {
|
|
66
|
+
try {
|
|
67
|
+
const data = JSON.parse(fs.readFileSync(path.join(brainDir, f), 'utf8'));
|
|
68
|
+
const content = `${data.query || ''} ${data.response || ''}`.toLowerCase();
|
|
69
|
+
let score = 0;
|
|
70
|
+
for (const token of errorTokens) {
|
|
71
|
+
if (content.includes(token))
|
|
72
|
+
score++;
|
|
73
|
+
}
|
|
74
|
+
const normalizedScore = errorTokens.length > 0 ? score / errorTokens.length : 0;
|
|
75
|
+
if (normalizedScore > bestScore && normalizedScore > 0.3) {
|
|
76
|
+
bestScore = normalizedScore;
|
|
77
|
+
bestFix = String(data.response).slice(0, 500);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch { }
|
|
81
|
+
}
|
|
82
|
+
return { fix: bestFix, hit: bestScore > 0.3 };
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return { fix: null, hit: false };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function runTestAutofix(command = 'npm test', projectRoot) {
|
|
89
|
+
let rawOutput = '';
|
|
90
|
+
try {
|
|
91
|
+
rawOutput = execSync(command, {
|
|
92
|
+
cwd: projectRoot,
|
|
93
|
+
encoding: 'utf8',
|
|
94
|
+
timeout: 30000,
|
|
95
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
rawOutput = (err.stdout || '') + '\n' + (err.stderr || '') + '\n' + (err.message || '');
|
|
100
|
+
}
|
|
101
|
+
const counts = extractTestCounts(rawOutput);
|
|
102
|
+
const rawFailures = extractFailures(rawOutput);
|
|
103
|
+
const failures = rawFailures.map(f => {
|
|
104
|
+
const brainResult = searchBrainForFix(f.error, projectRoot);
|
|
105
|
+
return {
|
|
106
|
+
testName: f.testName,
|
|
107
|
+
error: f.error,
|
|
108
|
+
file: f.file,
|
|
109
|
+
suggestedFix: brainResult.fix || undefined,
|
|
110
|
+
brainHit: brainResult.hit,
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
totalTests: counts.total,
|
|
115
|
+
passed: counts.passed,
|
|
116
|
+
failed: counts.failed,
|
|
117
|
+
failures,
|
|
118
|
+
autoFixAvailable: failures.filter(f => f.brainHit).length,
|
|
119
|
+
rawOutput: rawOutput.slice(0, 2000),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=TestAutofixInterceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestAutofixInterceptor.js","sourceRoot":"","sources":["../../../src/utils/TestAutofixInterceptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface TokenBudgetedReadResult {
|
|
2
|
+
filePath: string;
|
|
3
|
+
content: string;
|
|
4
|
+
tokensUsed: number;
|
|
5
|
+
tokensBudget: number;
|
|
6
|
+
truncated: boolean;
|
|
7
|
+
relevantSections: Array<{
|
|
8
|
+
start: number;
|
|
9
|
+
end: number;
|
|
10
|
+
reason: string;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
export declare function readTokenBudgeted(filePath: string, projectRoot: string, query?: string, maxTokens?: number): TokenBudgetedReadResult;
|
|
14
|
+
//# sourceMappingURL=TokenBudgetedReader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenBudgetedReader.d.ts","sourceRoot":"","sources":["../../../src/utils/TokenBudgetedReader.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzE;AAgFD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,MAAW,EAClB,SAAS,GAAE,MAAa,GACvB,uBAAuB,CAgDzB"}
|