@ruso-0/nreki 6.0.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/CHANGELOG.md +648 -0
- package/LICENSE +21 -0
- package/README.md +425 -0
- package/dist/ast-navigator.d.ts +29 -0
- package/dist/ast-navigator.d.ts.map +1 -0
- package/dist/ast-navigator.js +279 -0
- package/dist/ast-navigator.js.map +1 -0
- package/dist/ast-sandbox.d.ts +74 -0
- package/dist/ast-sandbox.d.ts.map +1 -0
- package/dist/ast-sandbox.js +242 -0
- package/dist/ast-sandbox.js.map +1 -0
- package/dist/chronos-memory.d.ts +69 -0
- package/dist/chronos-memory.d.ts.map +1 -0
- package/dist/chronos-memory.js +247 -0
- package/dist/chronos-memory.js.map +1 -0
- package/dist/circuit-breaker.d.ts +107 -0
- package/dist/circuit-breaker.d.ts.map +1 -0
- package/dist/circuit-breaker.js +330 -0
- package/dist/circuit-breaker.js.map +1 -0
- package/dist/compressor-advanced.d.ts +80 -0
- package/dist/compressor-advanced.d.ts.map +1 -0
- package/dist/compressor-advanced.js +555 -0
- package/dist/compressor-advanced.js.map +1 -0
- package/dist/compressor.d.ts +81 -0
- package/dist/compressor.d.ts.map +1 -0
- package/dist/compressor.js +227 -0
- package/dist/compressor.js.map +1 -0
- package/dist/database.d.ts +169 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +1029 -0
- package/dist/database.js.map +1 -0
- package/dist/embedder.d.ts +73 -0
- package/dist/embedder.d.ts.map +1 -0
- package/dist/embedder.js +165 -0
- package/dist/embedder.js.map +1 -0
- package/dist/engine.d.ts +224 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +582 -0
- package/dist/engine.js.map +1 -0
- package/dist/hologram/harvester.d.ts +41 -0
- package/dist/hologram/harvester.d.ts.map +1 -0
- package/dist/hologram/harvester.js +129 -0
- package/dist/hologram/harvester.js.map +1 -0
- package/dist/hologram/shadow-cache.d.ts +49 -0
- package/dist/hologram/shadow-cache.d.ts.map +1 -0
- package/dist/hologram/shadow-cache.js +165 -0
- package/dist/hologram/shadow-cache.js.map +1 -0
- package/dist/hologram/shadow-generator.d.ts +32 -0
- package/dist/hologram/shadow-generator.d.ts.map +1 -0
- package/dist/hologram/shadow-generator.js +828 -0
- package/dist/hologram/shadow-generator.js.map +1 -0
- package/dist/hooks/preToolUse.d.ts +63 -0
- package/dist/hooks/preToolUse.d.ts.map +1 -0
- package/dist/hooks/preToolUse.js +103 -0
- package/dist/hooks/preToolUse.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +367 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel/kernel-manager.d.ts +52 -0
- package/dist/kernel/kernel-manager.d.ts.map +1 -0
- package/dist/kernel/kernel-manager.js +197 -0
- package/dist/kernel/kernel-manager.js.map +1 -0
- package/dist/kernel/kernel-worker.d.ts +9 -0
- package/dist/kernel/kernel-worker.d.ts.map +1 -0
- package/dist/kernel/kernel-worker.js +76 -0
- package/dist/kernel/kernel-worker.js.map +1 -0
- package/dist/kernel/nreki-kernel.d.ts +244 -0
- package/dist/kernel/nreki-kernel.d.ts.map +1 -0
- package/dist/kernel/nreki-kernel.js +1656 -0
- package/dist/kernel/nreki-kernel.js.map +1 -0
- package/dist/middleware/circuit-breaker.d.ts +32 -0
- package/dist/middleware/circuit-breaker.d.ts.map +1 -0
- package/dist/middleware/circuit-breaker.js +160 -0
- package/dist/middleware/circuit-breaker.js.map +1 -0
- package/dist/middleware/file-lock.d.ts +33 -0
- package/dist/middleware/file-lock.d.ts.map +1 -0
- package/dist/middleware/file-lock.js +55 -0
- package/dist/middleware/file-lock.js.map +1 -0
- package/dist/middleware/validator.d.ts +26 -0
- package/dist/middleware/validator.d.ts.map +1 -0
- package/dist/middleware/validator.js +39 -0
- package/dist/middleware/validator.js.map +1 -0
- package/dist/monitor.d.ts +94 -0
- package/dist/monitor.d.ts.map +1 -0
- package/dist/monitor.js +221 -0
- package/dist/monitor.js.map +1 -0
- package/dist/parser-pool.d.ts +28 -0
- package/dist/parser-pool.d.ts.map +1 -0
- package/dist/parser-pool.js +81 -0
- package/dist/parser-pool.js.map +1 -0
- package/dist/parser.d.ts +91 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +311 -0
- package/dist/parser.js.map +1 -0
- package/dist/pin-memory.d.ts +35 -0
- package/dist/pin-memory.d.ts.map +1 -0
- package/dist/pin-memory.js +161 -0
- package/dist/pin-memory.js.map +1 -0
- package/dist/repo-map.d.ts +81 -0
- package/dist/repo-map.d.ts.map +1 -0
- package/dist/repo-map.js +550 -0
- package/dist/repo-map.js.map +1 -0
- package/dist/router.d.ts +102 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +1989 -0
- package/dist/router.js.map +1 -0
- package/dist/semantic-edit.d.ts +82 -0
- package/dist/semantic-edit.d.ts.map +1 -0
- package/dist/semantic-edit.js +529 -0
- package/dist/semantic-edit.js.map +1 -0
- package/dist/terminal-filter.d.ts +27 -0
- package/dist/terminal-filter.d.ts.map +1 -0
- package/dist/terminal-filter.js +257 -0
- package/dist/terminal-filter.js.map +1 -0
- package/dist/undo.d.ts +21 -0
- package/dist/undo.d.ts.map +1 -0
- package/dist/undo.js +55 -0
- package/dist/undo.js.map +1 -0
- package/dist/utils/code-tokenizer.d.ts +25 -0
- package/dist/utils/code-tokenizer.d.ts.map +1 -0
- package/dist/utils/code-tokenizer.js +52 -0
- package/dist/utils/code-tokenizer.js.map +1 -0
- package/dist/utils/file-filter.d.ts +23 -0
- package/dist/utils/file-filter.d.ts.map +1 -0
- package/dist/utils/file-filter.js +48 -0
- package/dist/utils/file-filter.js.map +1 -0
- package/dist/utils/imports.d.ts +32 -0
- package/dist/utils/imports.d.ts.map +1 -0
- package/dist/utils/imports.js +155 -0
- package/dist/utils/imports.js.map +1 -0
- package/dist/utils/path-jail.d.ts +27 -0
- package/dist/utils/path-jail.d.ts.map +1 -0
- package/dist/utils/path-jail.js +95 -0
- package/dist/utils/path-jail.js.map +1 -0
- package/dist/utils/read-source.d.ts +18 -0
- package/dist/utils/read-source.d.ts.map +1 -0
- package/dist/utils/read-source.js +22 -0
- package/dist/utils/read-source.js.map +1 -0
- package/dist/utils/safe-parse.d.ts +20 -0
- package/dist/utils/safe-parse.d.ts.map +1 -0
- package/dist/utils/safe-parse.js +25 -0
- package/dist/utils/safe-parse.js.map +1 -0
- package/package.json +75 -0
- package/scripts/download-wasm.js +46 -0
- package/wasm/.gitkeep +0 -0
- package/wasm/tree-sitter-go.wasm +0 -0
- package/wasm/tree-sitter-javascript.wasm +0 -0
- package/wasm/tree-sitter-python.wasm +0 -0
- package/wasm/tree-sitter-typescript.wasm +0 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* semantic-edit.ts - Zero-read surgical AST patching for NREKI.
|
|
3
|
+
*
|
|
4
|
+
* Replaces a single function/class/interface/type by name without
|
|
5
|
+
* reading or rewriting the entire file. Finds the exact AST node,
|
|
6
|
+
* splices only those bytes, and validates syntax before saving.
|
|
7
|
+
*
|
|
8
|
+
* Typically saves 60-80% of tokens vs native read+edit workflow.
|
|
9
|
+
*
|
|
10
|
+
* v3.2.0: Byte-index splicing (no more indexOf), auto-indentation,
|
|
11
|
+
* insert_before/insert_after modes, arrow function support,
|
|
12
|
+
* and fuzzy anchor heuristic.
|
|
13
|
+
*/
|
|
14
|
+
import fs from "fs";
|
|
15
|
+
import path from "path";
|
|
16
|
+
import { Embedder } from "./embedder.js";
|
|
17
|
+
import { readSource } from "./utils/read-source.js";
|
|
18
|
+
import { saveBackup } from "./undo.js";
|
|
19
|
+
import { extractSignature, cleanSignature } from "./repo-map.js";
|
|
20
|
+
// ─── Helpers ────────────────────────────────────────────────────────
|
|
21
|
+
/** Extract symbol name from a chunk's raw code. */
|
|
22
|
+
function extractName(chunk) {
|
|
23
|
+
const raw = chunk.rawCode.trim();
|
|
24
|
+
let m;
|
|
25
|
+
// TS/JS: Arrow functions (export const foo = async () => ...)
|
|
26
|
+
m = /(?:export\s+)?(?:default\s+)?(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?(?:(?:<[^>]*>\s*)?\([^)]*\)|[a-zA-Z0-9_]+)\s*=>/.exec(raw);
|
|
27
|
+
if (m)
|
|
28
|
+
return m[1];
|
|
29
|
+
// export [default] [async] function NAME
|
|
30
|
+
m = /(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s+(\w+)/.exec(raw);
|
|
31
|
+
if (m)
|
|
32
|
+
return m[1];
|
|
33
|
+
// class NAME
|
|
34
|
+
m = /(?:export\s+)?(?:default\s+)?(?:abstract\s+)?class\s+(\w+)/.exec(raw);
|
|
35
|
+
if (m)
|
|
36
|
+
return m[1];
|
|
37
|
+
// interface NAME
|
|
38
|
+
m = /(?:export\s+)?interface\s+(\w+)/.exec(raw);
|
|
39
|
+
if (m)
|
|
40
|
+
return m[1];
|
|
41
|
+
// type NAME
|
|
42
|
+
m = /(?:export\s+)?type\s+(\w+)/.exec(raw);
|
|
43
|
+
if (m)
|
|
44
|
+
return m[1];
|
|
45
|
+
// enum NAME
|
|
46
|
+
m = /(?:export\s+)?enum\s+(\w+)/.exec(raw);
|
|
47
|
+
if (m)
|
|
48
|
+
return m[1];
|
|
49
|
+
// method: NAME(
|
|
50
|
+
m = /(?:async\s+)?(?:static\s+)?(?:readonly\s+)?(?:public\s+|private\s+|protected\s+)?(\w+)\s*[(<]/.exec(raw);
|
|
51
|
+
if (m)
|
|
52
|
+
return m[1];
|
|
53
|
+
// Python: def NAME / class NAME
|
|
54
|
+
m = /(?:async\s+)?def\s+(\w+)/.exec(raw);
|
|
55
|
+
if (m)
|
|
56
|
+
return m[1];
|
|
57
|
+
m = /class\s+(\w+)/.exec(raw);
|
|
58
|
+
if (m)
|
|
59
|
+
return m[1];
|
|
60
|
+
// Go: func NAME / func (receiver) NAME
|
|
61
|
+
m = /func\s+(?:\([^)]*\)\s+)?(\w+)/.exec(raw);
|
|
62
|
+
if (m)
|
|
63
|
+
return m[1];
|
|
64
|
+
m = /type\s+(\w+)/.exec(raw);
|
|
65
|
+
if (m)
|
|
66
|
+
return m[1];
|
|
67
|
+
// Fallback
|
|
68
|
+
m = /(\w+)/.exec(raw);
|
|
69
|
+
return m ? m[1] : "";
|
|
70
|
+
}
|
|
71
|
+
/** Map file extension to language name for validation. */
|
|
72
|
+
function detectLanguage(filePath) {
|
|
73
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
74
|
+
const map = {
|
|
75
|
+
".ts": "typescript",
|
|
76
|
+
".tsx": "typescript",
|
|
77
|
+
".js": "javascript",
|
|
78
|
+
".jsx": "javascript",
|
|
79
|
+
".py": "python",
|
|
80
|
+
".go": "go",
|
|
81
|
+
};
|
|
82
|
+
return map[ext] ?? null;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Find a chunk by symbol name. Prefers AST symbolName, falls back to regex extraction.
|
|
86
|
+
*/
|
|
87
|
+
export function findChunkBySymbol(chunks, symbolName) {
|
|
88
|
+
// Exact match on AST symbolName first
|
|
89
|
+
const astMatch = chunks.find(c => c.symbolName && c.symbolName === symbolName);
|
|
90
|
+
if (astMatch)
|
|
91
|
+
return astMatch;
|
|
92
|
+
// Fallback: regex extraction
|
|
93
|
+
const regexMatch = chunks.find(c => extractName(c) === symbolName);
|
|
94
|
+
if (regexMatch)
|
|
95
|
+
return regexMatch;
|
|
96
|
+
// Case-insensitive fallback
|
|
97
|
+
const lower = symbolName.toLowerCase();
|
|
98
|
+
const fuzzy = chunks.find(c => {
|
|
99
|
+
const name = c.symbolName || extractName(c);
|
|
100
|
+
return name.toLowerCase() === lower;
|
|
101
|
+
});
|
|
102
|
+
return fuzzy ?? null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Apply a semantic splice on a string in RAM. Pure function: string in → string out.
|
|
106
|
+
* Verifies byte indices, rebases indentation, and splices by mode.
|
|
107
|
+
*/
|
|
108
|
+
export function applySemanticSplice(content, target, newCode, mode = "replace") {
|
|
109
|
+
const { startIndex, rawCode } = target;
|
|
110
|
+
// Verify tree-sitter byte position against actual content
|
|
111
|
+
let startIdx = startIndex;
|
|
112
|
+
if (content.substring(startIdx, startIdx + rawCode.length) !== rawCode) {
|
|
113
|
+
// Search in a local window of ±500 bytes around the AST-reported position
|
|
114
|
+
const windowStart = Math.max(0, startIdx - 500);
|
|
115
|
+
const windowEnd = Math.min(content.length, startIdx + rawCode.length + 500);
|
|
116
|
+
const searchWindow = content.substring(windowStart, windowEnd);
|
|
117
|
+
const localOffset = searchWindow.indexOf(rawCode);
|
|
118
|
+
if (localOffset >= 0) {
|
|
119
|
+
startIdx = windowStart + localOffset;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// M-05: No global fallback - risk of matching wrong occurrence in large files
|
|
123
|
+
startIdx = -1;
|
|
124
|
+
}
|
|
125
|
+
if (startIdx < 0) {
|
|
126
|
+
throw new Error(`Cannot locate symbol "${target.symbolName}" in file content. AST offset mismatch.`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const endIdx = startIdx + rawCode.length;
|
|
130
|
+
// Extract exact original indentation
|
|
131
|
+
let lineStart = startIdx;
|
|
132
|
+
while (lineStart > 0 && content[lineStart - 1] !== "\n")
|
|
133
|
+
lineStart--;
|
|
134
|
+
if (content[lineStart] === "\r")
|
|
135
|
+
lineStart++;
|
|
136
|
+
const indentMatch = content.slice(lineStart, startIdx).match(/^[ \t]*/);
|
|
137
|
+
const baseIndent = indentMatch ? indentMatch[0] : "";
|
|
138
|
+
// Calculate minimum indentation in the new code
|
|
139
|
+
const newLines = newCode.split("\n");
|
|
140
|
+
const nonBlank = newLines.filter(l => l.trim().length > 0);
|
|
141
|
+
let minClaudeIndent = Infinity;
|
|
142
|
+
for (const line of nonBlank) {
|
|
143
|
+
const match = line.match(/^[ \t]*/);
|
|
144
|
+
if (match && match[0].length < minClaudeIndent)
|
|
145
|
+
minClaudeIndent = match[0].length;
|
|
146
|
+
}
|
|
147
|
+
if (minClaudeIndent === Infinity)
|
|
148
|
+
minClaudeIndent = 0;
|
|
149
|
+
// Relative rebase: strip Claude's indent, apply baseIndent
|
|
150
|
+
const formattedNewCode = newLines.map((line, i) => {
|
|
151
|
+
if (line.trim() === "")
|
|
152
|
+
return "";
|
|
153
|
+
const strippedLine = line.slice(minClaudeIndent);
|
|
154
|
+
if (mode === "replace" && i === 0)
|
|
155
|
+
return strippedLine;
|
|
156
|
+
return baseIndent + strippedLine;
|
|
157
|
+
}).join("\n");
|
|
158
|
+
// Splice by mode
|
|
159
|
+
if (mode === "insert_before") {
|
|
160
|
+
return content.slice(0, lineStart) + formattedNewCode + "\n\n" + content.slice(lineStart);
|
|
161
|
+
}
|
|
162
|
+
else if (mode === "insert_after") {
|
|
163
|
+
let endOfLine = endIdx;
|
|
164
|
+
while (endOfLine < content.length && content[endOfLine] !== "\n")
|
|
165
|
+
endOfLine++;
|
|
166
|
+
return content.slice(0, endOfLine) + "\n\n" + formattedNewCode + content.slice(endOfLine);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
return content.slice(0, startIdx) + formattedNewCode + content.slice(endIdx);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Detect if a code edit changes the function/class signature.
|
|
174
|
+
* Compares cleaned signatures (keyword-stripped) of old and new code.
|
|
175
|
+
*/
|
|
176
|
+
export function detectSignatureChange(oldRawCode, newCode) {
|
|
177
|
+
const oldSig = cleanSignature(extractSignature(oldRawCode));
|
|
178
|
+
const newSig = cleanSignature(extractSignature(newCode));
|
|
179
|
+
return oldSig !== newSig;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Apply multiple edits atomically across multiple files.
|
|
183
|
+
* All-or-nothing: if ANY validation fails, ZERO files are written.
|
|
184
|
+
*/
|
|
185
|
+
export async function batchSemanticEdit(edits, parser, sandbox, projectRoot, dryRun = false) {
|
|
186
|
+
const { safePath } = await import("./utils/path-jail.js");
|
|
187
|
+
if (!edits || edits.length === 0) {
|
|
188
|
+
return { success: false, editCount: 0, fileCount: 0, files: [], error: "No edits provided." };
|
|
189
|
+
}
|
|
190
|
+
// 1. Group edits by file, resolving paths
|
|
191
|
+
const editsByFile = new Map();
|
|
192
|
+
for (const edit of edits) {
|
|
193
|
+
const resolved = safePath(projectRoot, edit.path);
|
|
194
|
+
const arr = editsByFile.get(resolved) || [];
|
|
195
|
+
arr.push(edit);
|
|
196
|
+
editsByFile.set(resolved, arr);
|
|
197
|
+
}
|
|
198
|
+
// 2. Build VFS in RAM
|
|
199
|
+
const vfs = new Map();
|
|
200
|
+
for (const filePath of editsByFile.keys()) {
|
|
201
|
+
try {
|
|
202
|
+
vfs.set(filePath, readSource(filePath));
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
return {
|
|
206
|
+
success: false, editCount: edits.length, fileCount: editsByFile.size, files: [],
|
|
207
|
+
error: `Cannot read file "${filePath}": ${err.message}`,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// Track old raw codes for blast radius detection
|
|
212
|
+
const oldRawCodes = new Map();
|
|
213
|
+
// 3. For each file: parse ONCE, map edits, reverse splice
|
|
214
|
+
for (const [filePath, fileEdits] of editsByFile.entries()) {
|
|
215
|
+
let virtualCode = vfs.get(filePath);
|
|
216
|
+
const parseResult = await parser.parse(filePath, virtualCode);
|
|
217
|
+
// Map each edit to its AST chunk
|
|
218
|
+
const mappedEdits = [];
|
|
219
|
+
for (const edit of fileEdits) {
|
|
220
|
+
const chunk = findChunkBySymbol(parseResult.chunks, edit.symbol);
|
|
221
|
+
if (!chunk) {
|
|
222
|
+
const available = parseResult.chunks
|
|
223
|
+
.map(c => c.symbolName || extractName(c))
|
|
224
|
+
.filter(Boolean)
|
|
225
|
+
.join(", ");
|
|
226
|
+
return {
|
|
227
|
+
success: false, editCount: edits.length, fileCount: editsByFile.size, files: [],
|
|
228
|
+
error: `Symbol "${edit.symbol}" not found in ${edit.path}. Available: ${available}`,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
mappedEdits.push({ edit, chunk });
|
|
232
|
+
}
|
|
233
|
+
// Detect overlapping ranges
|
|
234
|
+
for (let i = 0; i < mappedEdits.length; i++) {
|
|
235
|
+
for (let j = i + 1; j < mappedEdits.length; j++) {
|
|
236
|
+
const a = mappedEdits[i].chunk;
|
|
237
|
+
const b = mappedEdits[j].chunk;
|
|
238
|
+
if (a.startIndex < b.endIndex && b.startIndex < a.endIndex) {
|
|
239
|
+
return {
|
|
240
|
+
success: false, editCount: edits.length, fileCount: editsByFile.size, files: [],
|
|
241
|
+
error: `Overlapping edits: "${mappedEdits[i].edit.symbol}" and "${mappedEdits[j].edit.symbol}" ` +
|
|
242
|
+
`overlap in ${path.relative(projectRoot, filePath)}. Separate them into two calls.`,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Reverse splice: sort by startIndex DESCENDING (bottom-up)
|
|
248
|
+
mappedEdits.sort((a, b) => b.chunk.startIndex - a.chunk.startIndex);
|
|
249
|
+
for (const { edit, chunk } of mappedEdits) {
|
|
250
|
+
oldRawCodes.set(`${edit.path}::${edit.symbol}`, chunk.rawCode);
|
|
251
|
+
try {
|
|
252
|
+
virtualCode = applySemanticSplice(virtualCode, {
|
|
253
|
+
startIndex: chunk.startIndex,
|
|
254
|
+
endIndex: chunk.endIndex,
|
|
255
|
+
rawCode: chunk.rawCode,
|
|
256
|
+
symbolName: chunk.symbolName || extractName(chunk),
|
|
257
|
+
startLine: chunk.startLine,
|
|
258
|
+
}, edit.new_code, edit.mode || "replace");
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
return {
|
|
262
|
+
success: false, editCount: edits.length, fileCount: editsByFile.size, files: [],
|
|
263
|
+
error: `Error splicing "${edit.symbol}" in ${edit.path}: ${err.message}. No files modified.`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
vfs.set(filePath, virtualCode);
|
|
268
|
+
}
|
|
269
|
+
// 4. Validate ALL virtual files
|
|
270
|
+
await sandbox.initialize();
|
|
271
|
+
for (const [filePath, virtualContent] of vfs.entries()) {
|
|
272
|
+
const language = detectLanguage(filePath);
|
|
273
|
+
if (!language)
|
|
274
|
+
continue;
|
|
275
|
+
const validation = await sandbox.validateCode(virtualContent, language);
|
|
276
|
+
if (!validation.valid) {
|
|
277
|
+
const errDetail = validation.errors.slice(0, 3).map(e => ` L${e.line}:${e.column} - ${e.context.split("\n")[0].trim()}`).join("\n");
|
|
278
|
+
return {
|
|
279
|
+
success: false, editCount: edits.length, fileCount: editsByFile.size, files: [],
|
|
280
|
+
error: `TRANSACTION ABORTED - syntax error in ${path.relative(projectRoot, filePath)}:\n${errDetail}\n\n` +
|
|
281
|
+
`No files were modified.\n${validation.suggestion}\nFix the code and resend the full batch.`,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// 5. COMMIT: all passed validation → write to disk (if not dry run)
|
|
286
|
+
const writtenFiles = [];
|
|
287
|
+
if (!dryRun) {
|
|
288
|
+
for (const [filePath, virtualContent] of vfs.entries()) {
|
|
289
|
+
try {
|
|
290
|
+
saveBackup(projectRoot, filePath);
|
|
291
|
+
}
|
|
292
|
+
catch { /* non-fatal */ }
|
|
293
|
+
fs.writeFileSync(filePath, virtualContent, "utf-8");
|
|
294
|
+
writtenFiles.push(path.relative(projectRoot, filePath));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
for (const filePath of vfs.keys()) {
|
|
299
|
+
writtenFiles.push(path.relative(projectRoot, filePath));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
success: true,
|
|
304
|
+
editCount: edits.length,
|
|
305
|
+
fileCount: editsByFile.size,
|
|
306
|
+
files: writtenFiles,
|
|
307
|
+
oldRawCodes,
|
|
308
|
+
vfs,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
// ─── Core ───────────────────────────────────────────────────────────
|
|
312
|
+
/**
|
|
313
|
+
* Surgically edit a single symbol in a file by name.
|
|
314
|
+
*
|
|
315
|
+
* 1. Parse file to find the target AST node
|
|
316
|
+
* 2. Use exact byte indices from tree-sitter (no indexOf)
|
|
317
|
+
* 3. Auto-indent the replacement to match original context
|
|
318
|
+
* 4. Splice: before + newCode + after (supports replace/insert_before/insert_after)
|
|
319
|
+
* 5. Validate the result with tree-sitter
|
|
320
|
+
* 6. Write only if syntax is valid
|
|
321
|
+
*/
|
|
322
|
+
export async function semanticEdit(filePath, symbolName, newCode, parser, sandbox, mode = "replace", dryRun = false) {
|
|
323
|
+
// Read file
|
|
324
|
+
let content;
|
|
325
|
+
try {
|
|
326
|
+
content = readSource(filePath);
|
|
327
|
+
}
|
|
328
|
+
catch (err) {
|
|
329
|
+
return {
|
|
330
|
+
success: false,
|
|
331
|
+
filePath,
|
|
332
|
+
symbolName,
|
|
333
|
+
oldLines: 0,
|
|
334
|
+
newLines: 0,
|
|
335
|
+
tokensAvoided: 0,
|
|
336
|
+
syntaxValid: false,
|
|
337
|
+
error: `Cannot read file: ${err.message}`,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
// Parse to get AST chunks
|
|
341
|
+
const parseResult = await parser.parse(filePath, content);
|
|
342
|
+
if (parseResult.chunks.length === 0) {
|
|
343
|
+
return {
|
|
344
|
+
success: false,
|
|
345
|
+
filePath,
|
|
346
|
+
symbolName,
|
|
347
|
+
oldLines: 0,
|
|
348
|
+
newLines: 0,
|
|
349
|
+
tokensAvoided: 0,
|
|
350
|
+
syntaxValid: false,
|
|
351
|
+
error: "No symbols found in file. File may be empty or unsupported.",
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
// Find matching chunks by name (prefer AST symbolName, fallback to regex)
|
|
355
|
+
const matches = [];
|
|
356
|
+
const allNames = [];
|
|
357
|
+
for (const chunk of parseResult.chunks) {
|
|
358
|
+
const name = chunk.symbolName || extractName(chunk);
|
|
359
|
+
if (name)
|
|
360
|
+
allNames.push(`${name} (L${chunk.startLine}-L${chunk.endLine})`);
|
|
361
|
+
if (name === symbolName) {
|
|
362
|
+
matches.push({ chunk, name });
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// Symbol not found
|
|
366
|
+
if (matches.length === 0) {
|
|
367
|
+
const lowerSymbol = symbolName.toLowerCase();
|
|
368
|
+
const fuzzy = parseResult.chunks
|
|
369
|
+
.map((c) => ({ chunk: c, name: c.symbolName || extractName(c) }))
|
|
370
|
+
.filter((c) => c.name.toLowerCase() === lowerSymbol);
|
|
371
|
+
if (fuzzy.length > 0) {
|
|
372
|
+
return {
|
|
373
|
+
success: false,
|
|
374
|
+
filePath,
|
|
375
|
+
symbolName,
|
|
376
|
+
oldLines: 0,
|
|
377
|
+
newLines: 0,
|
|
378
|
+
tokensAvoided: 0,
|
|
379
|
+
syntaxValid: false,
|
|
380
|
+
error: `Symbol "${symbolName}" not found. Did you mean "${fuzzy[0].name}"? ` +
|
|
381
|
+
`Available symbols: ${allNames.join(", ")}`,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
// BONUS: JIT Heuristic - guess the intended symbol by comparing tokens
|
|
385
|
+
const codeTokens = new Set(newCode.match(/[a-zA-Z_]\w*/g) || []);
|
|
386
|
+
let bestChunk = null;
|
|
387
|
+
let bestScore = 0;
|
|
388
|
+
for (const chunk of parseResult.chunks) {
|
|
389
|
+
const chunkTokens = new Set(chunk.rawCode.match(/[a-zA-Z_]\w*/g) || []);
|
|
390
|
+
let score = 0;
|
|
391
|
+
for (const term of codeTokens) {
|
|
392
|
+
if (chunkTokens.has(term))
|
|
393
|
+
score++;
|
|
394
|
+
}
|
|
395
|
+
if (score > bestScore) {
|
|
396
|
+
bestScore = score;
|
|
397
|
+
bestChunk = chunk;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (bestChunk && bestScore >= 5) {
|
|
401
|
+
const guessedName = bestChunk.symbolName || extractName(bestChunk);
|
|
402
|
+
return {
|
|
403
|
+
success: false,
|
|
404
|
+
filePath,
|
|
405
|
+
symbolName,
|
|
406
|
+
oldLines: 0,
|
|
407
|
+
newLines: 0,
|
|
408
|
+
tokensAvoided: 0,
|
|
409
|
+
syntaxValid: false,
|
|
410
|
+
error: `Symbol "${symbolName}" not found. NREKI detected you likely meant to edit \`${guessedName}\`.\n` +
|
|
411
|
+
`Please retry using: symbol:"${guessedName}"`,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
success: false,
|
|
416
|
+
filePath,
|
|
417
|
+
symbolName,
|
|
418
|
+
oldLines: 0,
|
|
419
|
+
newLines: 0,
|
|
420
|
+
tokensAvoided: 0,
|
|
421
|
+
syntaxValid: false,
|
|
422
|
+
error: `Symbol "${symbolName}" not found. Available symbols: ${allNames.join(", ")}`,
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
// Multiple matches → ask Claude to disambiguate
|
|
426
|
+
if (matches.length > 1) {
|
|
427
|
+
const locs = matches
|
|
428
|
+
.map((m) => `L${m.chunk.startLine}-L${m.chunk.endLine}`)
|
|
429
|
+
.join(", ");
|
|
430
|
+
return {
|
|
431
|
+
success: false,
|
|
432
|
+
filePath,
|
|
433
|
+
symbolName,
|
|
434
|
+
oldLines: 0,
|
|
435
|
+
newLines: 0,
|
|
436
|
+
tokensAvoided: 0,
|
|
437
|
+
syntaxValid: false,
|
|
438
|
+
error: `Multiple symbols named "${symbolName}" found at: ${locs}. ` +
|
|
439
|
+
`Use nreki_navigate action:"definition" to identify the correct one.`,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
// ── Single match: perform the edit ──
|
|
443
|
+
const { chunk } = matches[0];
|
|
444
|
+
const rawCode = chunk.rawCode;
|
|
445
|
+
const oldLines = mode === "replace" ? chunk.rawCode.split("\n").length : 0;
|
|
446
|
+
// Apply splice via shared pure function
|
|
447
|
+
let newContent;
|
|
448
|
+
try {
|
|
449
|
+
newContent = applySemanticSplice(content, {
|
|
450
|
+
startIndex: chunk.startIndex,
|
|
451
|
+
endIndex: chunk.endIndex,
|
|
452
|
+
rawCode: chunk.rawCode,
|
|
453
|
+
symbolName: chunk.symbolName || extractName(chunk),
|
|
454
|
+
startLine: chunk.startLine,
|
|
455
|
+
}, newCode, mode);
|
|
456
|
+
}
|
|
457
|
+
catch (err) {
|
|
458
|
+
return {
|
|
459
|
+
success: false,
|
|
460
|
+
filePath,
|
|
461
|
+
symbolName,
|
|
462
|
+
oldLines: rawCode.split("\n").length,
|
|
463
|
+
newLines: newCode.split("\n").length,
|
|
464
|
+
tokensAvoided: 0,
|
|
465
|
+
syntaxValid: false,
|
|
466
|
+
error: err.message,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
// Validate syntax of the edited file
|
|
470
|
+
const language = detectLanguage(filePath);
|
|
471
|
+
if (!language) {
|
|
472
|
+
return {
|
|
473
|
+
success: false,
|
|
474
|
+
filePath,
|
|
475
|
+
symbolName,
|
|
476
|
+
oldLines: rawCode.split("\n").length,
|
|
477
|
+
newLines: newCode.split("\n").length,
|
|
478
|
+
tokensAvoided: 0,
|
|
479
|
+
syntaxValid: false,
|
|
480
|
+
error: "Unsupported file type for syntax validation.",
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
await sandbox.initialize();
|
|
484
|
+
const validation = await sandbox.validateCode(newContent, language);
|
|
485
|
+
if (!validation.valid) {
|
|
486
|
+
const errDetails = validation.errors
|
|
487
|
+
.slice(0, 5)
|
|
488
|
+
.map((e) => ` Line ${e.line}, Col ${e.column}: ${e.context.split("\n")[0].trim()}`)
|
|
489
|
+
.join("\n");
|
|
490
|
+
return {
|
|
491
|
+
success: false,
|
|
492
|
+
filePath,
|
|
493
|
+
symbolName,
|
|
494
|
+
oldLines: rawCode.split("\n").length,
|
|
495
|
+
newLines: newCode.split("\n").length,
|
|
496
|
+
tokensAvoided: 0,
|
|
497
|
+
syntaxValid: false,
|
|
498
|
+
error: `Syntax error in edited code - file NOT modified:\n${errDetails}\n\n${validation.suggestion}`,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
// Save backup and write to disk ONLY if not dry run
|
|
502
|
+
if (!dryRun) {
|
|
503
|
+
try {
|
|
504
|
+
saveBackup(process.cwd(), filePath);
|
|
505
|
+
}
|
|
506
|
+
catch {
|
|
507
|
+
// Non-fatal: don't block the edit if backup fails
|
|
508
|
+
}
|
|
509
|
+
fs.writeFileSync(filePath, newContent, "utf-8");
|
|
510
|
+
}
|
|
511
|
+
// Tokens avoided: without NREKI Claude reads full file + sends old symbol code.
|
|
512
|
+
// With NREKI: only sends newCode. Savings = (fullFile + oldSymbol) - newCode.
|
|
513
|
+
const fullFileTokens = Embedder.estimateTokens(content);
|
|
514
|
+
const symbolTokens = Embedder.estimateTokens(rawCode);
|
|
515
|
+
const newCodeTokens = Embedder.estimateTokens(newCode);
|
|
516
|
+
const tokensAvoided = Math.max(0, fullFileTokens + symbolTokens - newCodeTokens);
|
|
517
|
+
return {
|
|
518
|
+
success: true,
|
|
519
|
+
filePath,
|
|
520
|
+
symbolName,
|
|
521
|
+
oldLines,
|
|
522
|
+
newLines: newCode.split("\n").length,
|
|
523
|
+
tokensAvoided,
|
|
524
|
+
syntaxValid: true,
|
|
525
|
+
oldRawCode: rawCode,
|
|
526
|
+
newContent,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
//# sourceMappingURL=semantic-edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-edit.js","sourceRoot":"","sources":["../src/semantic-edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* terminal-filter.ts - Terminal entropy filter for NREKI.
|
|
3
|
+
*
|
|
4
|
+
* Filters noisy terminal output (npm errors, test failures, build logs)
|
|
5
|
+
* to extract only actionable information. Typical savings: 90-98% on
|
|
6
|
+
* error output from failed builds or test runs.
|
|
7
|
+
*/
|
|
8
|
+
export interface ErrorSummary {
|
|
9
|
+
errorCount: number;
|
|
10
|
+
uniqueErrors: string[];
|
|
11
|
+
firstError: string | null;
|
|
12
|
+
affectedFiles: string[];
|
|
13
|
+
summary: string;
|
|
14
|
+
}
|
|
15
|
+
export interface FilterResult {
|
|
16
|
+
original_tokens: number;
|
|
17
|
+
filtered_tokens: number;
|
|
18
|
+
reduction_percent: number;
|
|
19
|
+
error_summary: ErrorSummary;
|
|
20
|
+
filtered_text: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function stripAnsiCodes(text: string): string;
|
|
23
|
+
export declare function deduplicateLines(lines: string[]): string[];
|
|
24
|
+
export declare function filterNodeModules(lines: string[]): string[];
|
|
25
|
+
export declare function extractErrorSummary(text: string): ErrorSummary;
|
|
26
|
+
export declare function filterTerminalOutput(raw: string, maxLines?: number): FilterResult;
|
|
27
|
+
//# sourceMappingURL=terminal-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-filter.d.ts","sourceRoot":"","sources":["../src/terminal-filter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,YAAY;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,YAAY,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACzB;AAOD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AA0BD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAyE1D;AAQD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAyB3D;AAaD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAoE9D;AASD,wBAAgB,oBAAoB,CAChC,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,MAAY,GACvB,YAAY,CAsDd"}
|