@reverse-craft/smart-fs 1.0.7 → 2.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.
Files changed (40) hide show
  1. package/README.md +82 -1
  2. package/dist/analyzer.d.ts +91 -0
  3. package/dist/analyzer.d.ts.map +1 -0
  4. package/dist/beautifier.d.ts +120 -0
  5. package/dist/beautifier.d.ts.map +1 -0
  6. package/dist/index.d.ts +102 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +1267 -0
  9. package/dist/index.js.map +7 -0
  10. package/dist/languageDetector.d.ts +74 -0
  11. package/dist/languageDetector.d.ts.map +1 -0
  12. package/dist/llmConfig.d.ts +34 -0
  13. package/dist/llmConfig.d.ts.map +1 -0
  14. package/dist/searcher.d.ts +113 -0
  15. package/dist/searcher.d.ts.map +1 -0
  16. package/dist/server.d.ts +2 -0
  17. package/dist/server.d.ts.map +1 -0
  18. package/dist/server.js +537 -41
  19. package/dist/server.js.map +4 -4
  20. package/dist/tools/ToolDefinition.d.ts +24 -0
  21. package/dist/tools/ToolDefinition.d.ts.map +1 -0
  22. package/dist/tools/aiFindJsvmpDispatcher.d.ts +79 -0
  23. package/dist/tools/aiFindJsvmpDispatcher.d.ts.map +1 -0
  24. package/dist/tools/applyCustomTransform.d.ts +14 -0
  25. package/dist/tools/applyCustomTransform.d.ts.map +1 -0
  26. package/dist/tools/findUsageSmart.d.ts +16 -0
  27. package/dist/tools/findUsageSmart.d.ts.map +1 -0
  28. package/dist/tools/index.d.ts +43 -0
  29. package/dist/tools/index.d.ts.map +1 -0
  30. package/dist/tools/readCodeSmart.d.ts +13 -0
  31. package/dist/tools/readCodeSmart.d.ts.map +1 -0
  32. package/dist/tools/searchCodeSmart.d.ts +18 -0
  33. package/dist/tools/searchCodeSmart.d.ts.map +1 -0
  34. package/dist/transformer.d.ts +119 -0
  35. package/dist/transformer.d.ts.map +1 -0
  36. package/dist/truncator.d.ts +69 -0
  37. package/dist/truncator.d.ts.map +1 -0
  38. package/dist/types.d.ts +61 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/package.json +16 -16
package/dist/index.js ADDED
@@ -0,0 +1,1267 @@
1
+ // src/index.ts
2
+ import * as fs3 from "fs/promises";
3
+ import * as path4 from "path";
4
+
5
+ // src/languageDetector.ts
6
+ import * as path from "path";
7
+ var LANGUAGE_CONFIG = {
8
+ javascript: {
9
+ language: "javascript",
10
+ supportsAST: true,
11
+ supportsBeautify: true,
12
+ supportsSourceMap: true
13
+ },
14
+ typescript: {
15
+ language: "typescript",
16
+ supportsAST: true,
17
+ supportsBeautify: true,
18
+ supportsSourceMap: true
19
+ },
20
+ json: {
21
+ language: "json",
22
+ supportsAST: false,
23
+ supportsBeautify: true,
24
+ supportsSourceMap: false
25
+ },
26
+ html: {
27
+ language: "html",
28
+ supportsAST: false,
29
+ supportsBeautify: true,
30
+ supportsSourceMap: false
31
+ },
32
+ xml: {
33
+ language: "xml",
34
+ supportsAST: false,
35
+ supportsBeautify: true,
36
+ supportsSourceMap: false
37
+ },
38
+ css: {
39
+ language: "css",
40
+ supportsAST: false,
41
+ supportsBeautify: true,
42
+ supportsSourceMap: false
43
+ },
44
+ unknown: {
45
+ language: "unknown",
46
+ supportsAST: false,
47
+ supportsBeautify: false,
48
+ supportsSourceMap: false
49
+ }
50
+ };
51
+ var EXTENSION_MAP = {
52
+ ".js": "javascript",
53
+ ".mjs": "javascript",
54
+ ".cjs": "javascript",
55
+ ".jsx": "javascript",
56
+ ".ts": "typescript",
57
+ ".tsx": "typescript",
58
+ ".mts": "typescript",
59
+ ".cts": "typescript",
60
+ ".json": "json",
61
+ ".html": "html",
62
+ ".htm": "html",
63
+ ".xml": "xml",
64
+ ".svg": "xml",
65
+ ".css": "css"
66
+ };
67
+ function detectLanguage(filePath) {
68
+ const ext = path.extname(filePath).toLowerCase();
69
+ const language = EXTENSION_MAP[ext] ?? "unknown";
70
+ return LANGUAGE_CONFIG[language];
71
+ }
72
+ function getLanguageInfo(language) {
73
+ return LANGUAGE_CONFIG[language];
74
+ }
75
+ function isFullySupportedLanguage(language) {
76
+ const info = LANGUAGE_CONFIG[language];
77
+ return info.supportsAST && info.supportsBeautify && info.supportsSourceMap;
78
+ }
79
+ function getSupportedExtensions() {
80
+ return Object.keys(EXTENSION_MAP);
81
+ }
82
+ function isExtensionSupported(ext) {
83
+ const normalizedExt = ext.startsWith(".") ? ext.toLowerCase() : `.${ext.toLowerCase()}`;
84
+ return normalizedExt in EXTENSION_MAP;
85
+ }
86
+
87
+ // src/beautifier.ts
88
+ import * as esbuild from "esbuild";
89
+ import * as crypto from "crypto";
90
+ import * as fs from "fs/promises";
91
+ import * as path2 from "path";
92
+ import * as os from "os";
93
+ var TEMP_DIR = path2.join(os.tmpdir(), "smart-fs-mcp-cache");
94
+ async function ensureCacheDir() {
95
+ await fs.mkdir(TEMP_DIR, { recursive: true });
96
+ }
97
+ function calculateCacheKey(originalPath, mtimeMs) {
98
+ const fileKey = `${originalPath}-${mtimeMs}`;
99
+ return crypto.createHash("md5").update(fileKey).digest("hex");
100
+ }
101
+ function getCachePaths(originalPath, hash) {
102
+ const fileName = path2.basename(originalPath, ".js");
103
+ const beautifiedPath = path2.join(TEMP_DIR, `${fileName}.${hash}.beautified.js`);
104
+ const mapPath = `${beautifiedPath}.map`;
105
+ return { beautifiedPath, mapPath };
106
+ }
107
+ function getLocalPaths(originalPath) {
108
+ const absolutePath = path2.resolve(originalPath);
109
+ const dir = path2.dirname(absolutePath);
110
+ const ext = path2.extname(absolutePath);
111
+ const baseName = path2.basename(absolutePath, ext);
112
+ const beautifiedPath = path2.join(dir, `${baseName}.beautified.js`);
113
+ const mapPath = `${beautifiedPath}.map`;
114
+ return { beautifiedPath, mapPath };
115
+ }
116
+ async function isCacheValid(beautifiedPath, mapPath) {
117
+ try {
118
+ await Promise.all([
119
+ fs.access(beautifiedPath),
120
+ fs.access(mapPath)
121
+ ]);
122
+ return true;
123
+ } catch {
124
+ return false;
125
+ }
126
+ }
127
+ async function isLocalCacheValid(originalPath) {
128
+ const absolutePath = path2.resolve(originalPath);
129
+ const { beautifiedPath } = getLocalPaths(absolutePath);
130
+ let originalStats;
131
+ try {
132
+ originalStats = await fs.stat(absolutePath);
133
+ } catch {
134
+ return {
135
+ originalMtime: 0,
136
+ beautifiedExists: false,
137
+ beautifiedMtime: 0,
138
+ isValid: false
139
+ };
140
+ }
141
+ const originalMtime = originalStats.mtimeMs;
142
+ let beautifiedStats;
143
+ try {
144
+ beautifiedStats = await fs.stat(beautifiedPath);
145
+ } catch {
146
+ return {
147
+ originalMtime,
148
+ beautifiedExists: false,
149
+ beautifiedMtime: 0,
150
+ isValid: false
151
+ };
152
+ }
153
+ const beautifiedMtime = beautifiedStats.mtimeMs;
154
+ const isValid = beautifiedMtime >= originalMtime;
155
+ return {
156
+ originalMtime,
157
+ beautifiedExists: true,
158
+ beautifiedMtime,
159
+ isValid
160
+ };
161
+ }
162
+ function beautifyJson(content) {
163
+ try {
164
+ const parsed = JSON.parse(content);
165
+ return { code: JSON.stringify(parsed, null, 2), parseFailed: false };
166
+ } catch {
167
+ return { code: content, parseFailed: true };
168
+ }
169
+ }
170
+ function beautifyHtml(content) {
171
+ try {
172
+ let formatted = "";
173
+ let indent = 0;
174
+ const indentStr = " ";
175
+ const normalized = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
176
+ const tokens = normalized.split(/(<[^>]+>)/g).filter((token) => token.trim() !== "");
177
+ for (const token of tokens) {
178
+ const trimmedToken = token.trim();
179
+ if (!trimmedToken) continue;
180
+ if (trimmedToken.startsWith("<")) {
181
+ if (trimmedToken.startsWith("<!") || trimmedToken.startsWith("<?") || trimmedToken.endsWith("/>")) {
182
+ formatted += indentStr.repeat(indent) + trimmedToken + "\n";
183
+ } else if (trimmedToken.startsWith("</")) {
184
+ indent = Math.max(0, indent - 1);
185
+ formatted += indentStr.repeat(indent) + trimmedToken + "\n";
186
+ } else {
187
+ formatted += indentStr.repeat(indent) + trimmedToken + "\n";
188
+ indent++;
189
+ }
190
+ } else {
191
+ const textLines = trimmedToken.split("\n");
192
+ for (const line of textLines) {
193
+ const trimmedLine = line.trim();
194
+ if (trimmedLine) {
195
+ formatted += indentStr.repeat(indent) + trimmedLine + "\n";
196
+ }
197
+ }
198
+ }
199
+ }
200
+ return formatted.trimEnd();
201
+ } catch {
202
+ return content;
203
+ }
204
+ }
205
+ function beautifyCss(content) {
206
+ try {
207
+ let formatted = content;
208
+ formatted = formatted.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
209
+ formatted = formatted.replace(/\{/g, " {\n");
210
+ formatted = formatted.replace(/\}/g, "\n}\n");
211
+ formatted = formatted.replace(/;/g, ";\n");
212
+ formatted = formatted.replace(/\n\s*\n/g, "\n");
213
+ const lines = formatted.split("\n");
214
+ let indent = 0;
215
+ const indentStr = " ";
216
+ const result = [];
217
+ for (const line of lines) {
218
+ const trimmed = line.trim();
219
+ if (!trimmed) continue;
220
+ if (trimmed.startsWith("}")) {
221
+ indent = Math.max(0, indent - 1);
222
+ }
223
+ result.push(indentStr.repeat(indent) + trimmed);
224
+ if (trimmed.endsWith("{")) {
225
+ indent++;
226
+ }
227
+ }
228
+ return result.join("\n");
229
+ } catch {
230
+ return content;
231
+ }
232
+ }
233
+ function beautifyCode(code, language) {
234
+ const langInfo = getLanguageInfo(language);
235
+ if (!langInfo.supportsBeautify) {
236
+ return { code, usedFallback: true };
237
+ }
238
+ switch (language) {
239
+ case "json": {
240
+ const result = beautifyJson(code);
241
+ return { code: result.code, usedFallback: result.parseFailed };
242
+ }
243
+ case "html":
244
+ case "xml":
245
+ return { code: beautifyHtml(code), usedFallback: false };
246
+ case "css":
247
+ return { code: beautifyCss(code), usedFallback: false };
248
+ case "javascript":
249
+ case "typescript":
250
+ return { code, usedFallback: true };
251
+ default:
252
+ return { code, usedFallback: true };
253
+ }
254
+ }
255
+ async function ensureBeautified(originalPath, options) {
256
+ const absolutePath = path2.resolve(originalPath);
257
+ let stats;
258
+ try {
259
+ stats = await fs.stat(absolutePath);
260
+ } catch {
261
+ throw new Error(`File not found: ${originalPath}`);
262
+ }
263
+ const langInfo = options?.language ? getLanguageInfo(options.language) : detectLanguage(absolutePath);
264
+ const language = langInfo.language;
265
+ const localPaths = getLocalPaths(absolutePath);
266
+ if (language !== "javascript" && language !== "typescript") {
267
+ const content = await fs.readFile(absolutePath, "utf-8");
268
+ const beautified = beautifyCode(content, language);
269
+ return {
270
+ code: beautified.code,
271
+ rawMap: null,
272
+ // No source map for non-JS/TS
273
+ localPath: localPaths.beautifiedPath,
274
+ localMapPath: localPaths.mapPath,
275
+ usedFallback: beautified.usedFallback
276
+ };
277
+ }
278
+ const localCacheCheck = await isLocalCacheValid(absolutePath);
279
+ if (localCacheCheck.isValid) {
280
+ try {
281
+ const [code2, mapContent] = await Promise.all([
282
+ fs.readFile(localPaths.beautifiedPath, "utf-8"),
283
+ fs.readFile(localPaths.mapPath, "utf-8")
284
+ ]);
285
+ return {
286
+ code: code2,
287
+ rawMap: JSON.parse(mapContent),
288
+ localPath: localPaths.beautifiedPath,
289
+ localMapPath: localPaths.mapPath,
290
+ usedFallback: false
291
+ };
292
+ } catch {
293
+ }
294
+ }
295
+ await ensureCacheDir();
296
+ const hash = calculateCacheKey(absolutePath, stats.mtimeMs);
297
+ const { beautifiedPath, mapPath } = getCachePaths(absolutePath, hash);
298
+ if (await isCacheValid(beautifiedPath, mapPath)) {
299
+ const [code2, mapContent] = await Promise.all([
300
+ fs.readFile(beautifiedPath, "utf-8"),
301
+ fs.readFile(mapPath, "utf-8")
302
+ ]);
303
+ const result2 = {
304
+ code: code2,
305
+ rawMap: JSON.parse(mapContent),
306
+ localPath: localPaths.beautifiedPath,
307
+ localMapPath: localPaths.mapPath,
308
+ usedFallback: false
309
+ };
310
+ await saveToLocal(result2, localPaths, mapContent);
311
+ return result2;
312
+ }
313
+ let esbuildResult;
314
+ try {
315
+ esbuildResult = await esbuild.build({
316
+ entryPoints: [absolutePath],
317
+ bundle: false,
318
+ write: false,
319
+ format: "esm",
320
+ sourcemap: "external",
321
+ sourcesContent: false,
322
+ outfile: "out.js",
323
+ // Beautify settings
324
+ minify: false,
325
+ keepNames: true,
326
+ treeShaking: false
327
+ });
328
+ } catch (err) {
329
+ const content = await fs.readFile(absolutePath, "utf-8");
330
+ return {
331
+ code: content,
332
+ rawMap: null,
333
+ localPath: localPaths.beautifiedPath,
334
+ localMapPath: localPaths.mapPath,
335
+ usedFallback: true
336
+ };
337
+ }
338
+ const codeFile = esbuildResult.outputFiles?.find((f) => f.path.endsWith(".js"));
339
+ const mapFile = esbuildResult.outputFiles?.find((f) => f.path.endsWith(".map"));
340
+ if (!codeFile || !mapFile) {
341
+ const content = await fs.readFile(absolutePath, "utf-8");
342
+ return {
343
+ code: content,
344
+ rawMap: null,
345
+ localPath: localPaths.beautifiedPath,
346
+ localMapPath: localPaths.mapPath,
347
+ usedFallback: true
348
+ };
349
+ }
350
+ const code = codeFile.text;
351
+ const rawMap = JSON.parse(mapFile.text);
352
+ const mapText = mapFile.text;
353
+ await Promise.all([
354
+ fs.writeFile(beautifiedPath, code, "utf-8"),
355
+ fs.writeFile(mapPath, mapText, "utf-8")
356
+ ]);
357
+ const result = {
358
+ code,
359
+ rawMap,
360
+ localPath: localPaths.beautifiedPath,
361
+ localMapPath: localPaths.mapPath,
362
+ usedFallback: false
363
+ };
364
+ await saveToLocal(result, localPaths, mapText);
365
+ return result;
366
+ }
367
+ async function saveToLocal(result, localPaths, mapText) {
368
+ try {
369
+ await Promise.all([
370
+ fs.writeFile(localPaths.beautifiedPath, result.code, "utf-8"),
371
+ fs.writeFile(localPaths.mapPath, mapText, "utf-8")
372
+ ]);
373
+ result.localPath = localPaths.beautifiedPath;
374
+ result.localMapPath = localPaths.mapPath;
375
+ } catch (err) {
376
+ const error = err;
377
+ if (error.code === "EACCES" || error.code === "EPERM") {
378
+ result.localSaveError = `Permission denied: Cannot write to ${path2.dirname(localPaths.beautifiedPath)}`;
379
+ } else if (error.code === "ENOSPC") {
380
+ result.localSaveError = `Insufficient disk space: Cannot write to ${path2.dirname(localPaths.beautifiedPath)}`;
381
+ } else {
382
+ result.localSaveError = `Failed to save locally: ${error.message || String(err)}`;
383
+ }
384
+ }
385
+ }
386
+
387
+ // src/truncator.ts
388
+ import { parse } from "meriyah";
389
+ import { walk } from "estree-walker";
390
+ import MagicString from "magic-string";
391
+ function countNewlines(str) {
392
+ let count = 0;
393
+ for (const char of str) {
394
+ if (char === "\n") count++;
395
+ }
396
+ return count;
397
+ }
398
+ function createTruncatedString(original, previewLength) {
399
+ const newlineCount = countNewlines(original);
400
+ const start = original.slice(0, previewLength);
401
+ const end = original.slice(-previewLength);
402
+ const marker = `...[TRUNCATED ${original.length} CHARS]...`;
403
+ const startNewlines = countNewlines(start);
404
+ const endNewlines = countNewlines(end);
405
+ const preservedNewlines = Math.max(0, newlineCount - startNewlines - endNewlines);
406
+ const newlineStr = "\n".repeat(preservedNewlines);
407
+ return `${start}${marker}${newlineStr}${end}`;
408
+ }
409
+ function truncateCodeAST(sourceCode, limit = 200, previewLength = 50) {
410
+ let ast;
411
+ try {
412
+ ast = parse(sourceCode, {
413
+ module: true,
414
+ next: true,
415
+ ranges: true,
416
+ loc: true,
417
+ raw: true
418
+ });
419
+ } catch {
420
+ return { code: sourceCode, parseFailed: true };
421
+ }
422
+ const magicString = new MagicString(sourceCode);
423
+ walk(ast, {
424
+ enter(node) {
425
+ if (node.type === "Literal" && typeof node.value === "string") {
426
+ const literal = node;
427
+ const value = literal.value;
428
+ if (value.length > limit && literal.start !== void 0 && literal.end !== void 0) {
429
+ const truncated = createTruncatedString(value, previewLength);
430
+ const originalText = sourceCode.slice(literal.start, literal.end);
431
+ const quote = originalText[0];
432
+ magicString.overwrite(literal.start, literal.end, `${quote}${truncated}${quote}`);
433
+ }
434
+ }
435
+ if (node.type === "TemplateLiteral") {
436
+ const template = node;
437
+ for (const quasi of template.quasis) {
438
+ const value = quasi.value.raw;
439
+ if (value.length > limit && quasi.start !== void 0 && quasi.end !== void 0) {
440
+ const truncated = createTruncatedString(value, previewLength);
441
+ magicString.overwrite(quasi.start, quasi.end, truncated);
442
+ }
443
+ }
444
+ }
445
+ }
446
+ });
447
+ return { code: magicString.toString(), parseFailed: false };
448
+ }
449
+ function truncateCodeHighPerf(sourceCode, limit = 200, previewLength = 50) {
450
+ return truncateCodeAST(sourceCode, limit, previewLength).code;
451
+ }
452
+ function truncateFallback(code, maxLineChars = 500, previewLength = 50) {
453
+ if (!code) {
454
+ return code;
455
+ }
456
+ const lines = code.split("\n");
457
+ const processedLines = lines.map((line) => {
458
+ if (line.length <= maxLineChars) {
459
+ return line;
460
+ }
461
+ const start = line.slice(0, previewLength);
462
+ const end = line.slice(-previewLength);
463
+ const truncatedChars = line.length - previewLength * 2;
464
+ const marker = `...[LINE TRUNCATED ${truncatedChars} CHARS]...`;
465
+ return `${start}${marker}${end}`;
466
+ });
467
+ return processedLines.join("\n");
468
+ }
469
+ function truncateCode(code, options) {
470
+ const {
471
+ language,
472
+ charLimit = 200,
473
+ maxLineChars = 500,
474
+ previewLength = 50
475
+ } = options ?? {};
476
+ const langInfo = language ? getLanguageInfo(language) : null;
477
+ const supportsAST = langInfo?.supportsAST ?? false;
478
+ if (supportsAST && (language === "javascript" || language === "typescript")) {
479
+ const astResult = truncateCodeAST(code, charLimit, previewLength);
480
+ if (astResult.parseFailed) {
481
+ const truncatedCode3 = truncateFallback(code, maxLineChars, previewLength);
482
+ return {
483
+ code: truncatedCode3,
484
+ usedFallback: true
485
+ };
486
+ }
487
+ const truncatedCode2 = truncateLongLines(astResult.code, maxLineChars, previewLength / maxLineChars);
488
+ return {
489
+ code: truncatedCode2,
490
+ usedFallback: false
491
+ };
492
+ }
493
+ const truncatedCode = truncateFallback(code, maxLineChars, previewLength);
494
+ return {
495
+ code: truncatedCode,
496
+ usedFallback: true
497
+ };
498
+ }
499
+ function truncateCodeFromFile(filePath, code, options) {
500
+ const language = options?.language ?? detectLanguage(filePath).language;
501
+ return truncateCode(code, {
502
+ ...options,
503
+ language
504
+ });
505
+ }
506
+ function truncateLongLines(code, maxLineChars = 500, previewRatio = 0.2) {
507
+ if (!code) {
508
+ return code;
509
+ }
510
+ const lines = code.split("\n");
511
+ const previewLength = Math.floor(maxLineChars * previewRatio);
512
+ const processedLines = lines.map((line) => {
513
+ if (line.length <= maxLineChars) {
514
+ return line;
515
+ }
516
+ const start = line.slice(0, previewLength);
517
+ const end = line.slice(-previewLength);
518
+ const truncatedChars = line.length - previewLength * 2;
519
+ const marker = `...[LINE TRUNCATED ${truncatedChars} CHARS]...`;
520
+ return `${start}${marker}${end}`;
521
+ });
522
+ return processedLines.join("\n");
523
+ }
524
+
525
+ // src/searcher.ts
526
+ import { SourceMapConsumer } from "source-map-js";
527
+ function unescapeBackslashes(str) {
528
+ return str.replace(/\\\\/g, "\\");
529
+ }
530
+ function escapeRegex(str) {
531
+ return str.replace(/[()[\]{}.*+?^$|\\]/g, "\\$&");
532
+ }
533
+ function createRegex(query, caseSensitive = false, isRegex = false) {
534
+ try {
535
+ const flags = caseSensitive ? "g" : "gi";
536
+ const pattern = isRegex ? query : escapeRegex(query);
537
+ return new RegExp(pattern, flags);
538
+ } catch (err) {
539
+ const message = err instanceof Error ? err.message : String(err);
540
+ throw new Error(`Invalid regex: ${message}`);
541
+ }
542
+ }
543
+ function getOriginalPosition(consumer, lineNumber) {
544
+ const pos = consumer.originalPositionFor({
545
+ line: lineNumber,
546
+ column: 0
547
+ });
548
+ return {
549
+ line: pos.line,
550
+ column: pos.column
551
+ };
552
+ }
553
+ function buildLineOffsets(code) {
554
+ let capacity = Math.max(16, Math.ceil(code.length / 40));
555
+ let offsets = new Int32Array(capacity);
556
+ let lineCount = 0;
557
+ offsets[0] = 0;
558
+ for (let i = 0; i < code.length; i++) {
559
+ if (code[i] === "\n") {
560
+ lineCount++;
561
+ if (lineCount >= capacity) {
562
+ capacity *= 2;
563
+ const newArr = new Int32Array(capacity);
564
+ newArr.set(offsets);
565
+ offsets = newArr;
566
+ }
567
+ offsets[lineCount] = i + 1;
568
+ }
569
+ }
570
+ return {
571
+ offsets: offsets.subarray(0, lineCount + 1),
572
+ totalLines: lineCount + 1
573
+ };
574
+ }
575
+ function getLineNumberFromIndex(offsets, totalLines, index) {
576
+ let low = 0;
577
+ let high = totalLines - 1;
578
+ while (low <= high) {
579
+ const mid = low + high >>> 1;
580
+ if (offsets[mid] <= index) {
581
+ low = mid + 1;
582
+ } else {
583
+ high = mid - 1;
584
+ }
585
+ }
586
+ return low;
587
+ }
588
+ function getLineContent(code, offsets, totalLines, lineNo) {
589
+ if (lineNo < 1 || lineNo > totalLines) return "";
590
+ const start = offsets[lineNo - 1];
591
+ let end;
592
+ if (lineNo < totalLines) {
593
+ end = offsets[lineNo] - 1;
594
+ } else {
595
+ end = code.length;
596
+ }
597
+ if (end > start && code[end - 1] === "\r") {
598
+ end--;
599
+ }
600
+ return code.slice(start, end);
601
+ }
602
+ function searchInCode(code, rawMap, options) {
603
+ const {
604
+ query,
605
+ contextLines = 2,
606
+ caseSensitive = false,
607
+ maxMatches = 10,
608
+ isRegex = false,
609
+ timeoutMs = 500
610
+ } = options;
611
+ const { offsets, totalLines } = buildLineOffsets(code);
612
+ const flags = (caseSensitive ? "g" : "gi") + "m";
613
+ const patternStr = isRegex ? unescapeBackslashes(query) : escapeRegex(query);
614
+ let regex;
615
+ try {
616
+ regex = new RegExp(patternStr, flags);
617
+ } catch (err) {
618
+ const message = err instanceof Error ? err.message : String(err);
619
+ throw new Error(`Invalid regex: ${message}`);
620
+ }
621
+ const consumer = new SourceMapConsumer({
622
+ ...rawMap,
623
+ version: String(rawMap.version)
624
+ });
625
+ const matches = [];
626
+ let lastMatchedLine = -1;
627
+ let totalMatchesFound = 0;
628
+ let match;
629
+ const startTime = Date.now();
630
+ while ((match = regex.exec(code)) !== null) {
631
+ if (match.index === regex.lastIndex) {
632
+ regex.lastIndex++;
633
+ }
634
+ const lineNumber = getLineNumberFromIndex(offsets, totalLines, match.index);
635
+ if (lineNumber === lastMatchedLine) {
636
+ continue;
637
+ }
638
+ lastMatchedLine = lineNumber;
639
+ totalMatchesFound++;
640
+ if (matches.length < maxMatches) {
641
+ const contextBefore = [];
642
+ for (let i = Math.max(1, lineNumber - contextLines); i < lineNumber; i++) {
643
+ contextBefore.push({
644
+ lineNumber: i,
645
+ content: getLineContent(code, offsets, totalLines, i),
646
+ originalPosition: getOriginalPosition(consumer, i)
647
+ });
648
+ }
649
+ const contextAfter = [];
650
+ for (let i = lineNumber + 1; i <= Math.min(totalLines, lineNumber + contextLines); i++) {
651
+ contextAfter.push({
652
+ lineNumber: i,
653
+ content: getLineContent(code, offsets, totalLines, i),
654
+ originalPosition: getOriginalPosition(consumer, i)
655
+ });
656
+ }
657
+ matches.push({
658
+ lineNumber,
659
+ lineContent: getLineContent(code, offsets, totalLines, lineNumber),
660
+ originalPosition: getOriginalPosition(consumer, lineNumber),
661
+ contextBefore,
662
+ contextAfter
663
+ });
664
+ }
665
+ if (Date.now() - startTime > timeoutMs) {
666
+ break;
667
+ }
668
+ }
669
+ return {
670
+ matches,
671
+ totalMatches: totalMatchesFound,
672
+ truncated: totalMatchesFound > maxMatches
673
+ };
674
+ }
675
+ function formatSourcePosition(line, column) {
676
+ if (line !== null && column !== null) {
677
+ return `L${line}:${column}`;
678
+ }
679
+ return "";
680
+ }
681
+ function formatCodeLine(lineNumber, sourcePos, code, maxLineNumWidth, prefix = " ") {
682
+ const lineNumStr = String(lineNumber).padStart(maxLineNumWidth, " ");
683
+ const srcPosPadded = sourcePos ? sourcePos.padEnd(10, " ") : " ";
684
+ return `${prefix}${lineNumStr} ${srcPosPadded} ${code}`;
685
+ }
686
+ function formatSearchResult(filePath, query, caseSensitive, result, maxMatches = 50, isRegex = false) {
687
+ const { matches, totalMatches, truncated } = result;
688
+ const outputParts = [];
689
+ const caseInfo = caseSensitive ? "case-sensitive" : "case-insensitive";
690
+ const modeInfo = isRegex ? "regex" : "literal";
691
+ outputParts.push(`${filePath}`);
692
+ outputParts.push(`Query="${query}" (${modeInfo}, ${caseInfo})`);
693
+ outputParts.push(`Src=original position for breakpoints`);
694
+ if (totalMatches === 0) {
695
+ outputParts.push("Matches: None");
696
+ return outputParts.join("\n");
697
+ }
698
+ const matchInfo = truncated ? `Matches: ${totalMatches} (showing first ${maxMatches})` : `Matches: ${totalMatches}`;
699
+ outputParts.push(matchInfo);
700
+ for (const match of matches) {
701
+ outputParts.push(`--- Line ${match.lineNumber} ---`);
702
+ const allLineNumbers = [
703
+ ...match.contextBefore.map((c) => c.lineNumber),
704
+ match.lineNumber,
705
+ ...match.contextAfter.map((c) => c.lineNumber)
706
+ ];
707
+ const maxLineNumWidth = Math.max(...allLineNumbers.map((n) => String(n).length));
708
+ for (const ctx of match.contextBefore) {
709
+ const srcPos = formatSourcePosition(ctx.originalPosition.line, ctx.originalPosition.column);
710
+ outputParts.push(formatCodeLine(ctx.lineNumber, srcPos, ctx.content, maxLineNumWidth, " "));
711
+ }
712
+ const matchSrcPos = formatSourcePosition(match.originalPosition.line, match.originalPosition.column);
713
+ outputParts.push(formatCodeLine(match.lineNumber, matchSrcPos, match.lineContent, maxLineNumWidth, ">>"));
714
+ for (const ctx of match.contextAfter) {
715
+ const srcPos = formatSourcePosition(ctx.originalPosition.line, ctx.originalPosition.column);
716
+ outputParts.push(formatCodeLine(ctx.lineNumber, srcPos, ctx.content, maxLineNumWidth, " "));
717
+ }
718
+ }
719
+ if (truncated) {
720
+ outputParts.push(`
721
+ ... (${totalMatches - maxMatches} more matches not shown)`);
722
+ }
723
+ return outputParts.join("\n");
724
+ }
725
+
726
+ // src/analyzer.ts
727
+ import { SourceMapConsumer as SourceMapConsumer2 } from "source-map-js";
728
+ import { parse as parse2 } from "@babel/parser";
729
+ var traverse = null;
730
+ async function getTraverse() {
731
+ if (!traverse) {
732
+ const mod = await import("@babel/traverse");
733
+ traverse = mod.default?.default ?? mod.default;
734
+ }
735
+ return traverse;
736
+ }
737
+ var DEFAULT_PARSER_OPTIONS = {
738
+ sourceType: "unambiguous",
739
+ plugins: [
740
+ "jsx",
741
+ "typescript",
742
+ "classProperties",
743
+ "classPrivateProperties",
744
+ "classPrivateMethods",
745
+ "dynamicImport",
746
+ "optionalChaining",
747
+ "nullishCoalescingOperator",
748
+ "objectRestSpread"
749
+ ],
750
+ errorRecovery: true
751
+ };
752
+ function parseCode(code) {
753
+ try {
754
+ return parse2(code, DEFAULT_PARSER_OPTIONS);
755
+ } catch (err) {
756
+ const message = err instanceof Error ? err.message : String(err);
757
+ throw new Error(`Parse error: ${message}`);
758
+ }
759
+ }
760
+ function getOriginalPosition2(consumer, line, column) {
761
+ const pos = consumer.originalPositionFor({ line, column });
762
+ return {
763
+ line: pos.line,
764
+ column: pos.column
765
+ };
766
+ }
767
+ function getLineContent2(lines, lineNumber) {
768
+ if (lineNumber < 1 || lineNumber > lines.length) {
769
+ return "";
770
+ }
771
+ return lines[lineNumber - 1];
772
+ }
773
+ function createLocationInfo(line, column, lines, consumer) {
774
+ return {
775
+ line,
776
+ column,
777
+ originalPosition: getOriginalPosition2(consumer, line, column),
778
+ lineContent: getLineContent2(lines, line)
779
+ };
780
+ }
781
+ async function analyzeBindings(code, rawMap, identifier, options) {
782
+ const targetLine = options?.targetLine;
783
+ const isTargeted = targetLine !== void 0;
784
+ const maxReferences = options?.maxReferences ?? (isTargeted ? 15 : 10);
785
+ const ast = parseCode(code);
786
+ const lines = code.split("\n");
787
+ const consumer = new SourceMapConsumer2({
788
+ ...rawMap,
789
+ version: String(rawMap.version)
790
+ });
791
+ const bindings = [];
792
+ const processedScopes = /* @__PURE__ */ new Set();
793
+ const traverse2 = await getTraverse();
794
+ try {
795
+ traverse2(ast, {
796
+ Identifier(path5) {
797
+ if (path5.node.name !== identifier) {
798
+ return;
799
+ }
800
+ if (isTargeted) {
801
+ const nodeLoc = path5.node.loc;
802
+ if (!nodeLoc || nodeLoc.start.line !== targetLine) {
803
+ return;
804
+ }
805
+ }
806
+ const binding = path5.scope.getBinding(identifier);
807
+ if (!binding) {
808
+ return;
809
+ }
810
+ const scopeUid = binding.scope.uid;
811
+ if (processedScopes.has(scopeUid)) {
812
+ return;
813
+ }
814
+ processedScopes.add(scopeUid);
815
+ const defNode = binding.identifier;
816
+ const defLoc = defNode.loc;
817
+ if (!defLoc) {
818
+ return;
819
+ }
820
+ const definition = createLocationInfo(
821
+ defLoc.start.line,
822
+ defLoc.start.column,
823
+ lines,
824
+ consumer
825
+ );
826
+ const allReferences = [];
827
+ for (const refPath of binding.referencePaths) {
828
+ const refLoc = refPath.node.loc;
829
+ if (!refLoc) {
830
+ continue;
831
+ }
832
+ allReferences.push(
833
+ createLocationInfo(
834
+ refLoc.start.line,
835
+ refLoc.start.column,
836
+ lines,
837
+ consumer
838
+ )
839
+ );
840
+ }
841
+ const totalReferences = allReferences.length;
842
+ const limitedReferences = allReferences.slice(0, maxReferences);
843
+ let hitLocation;
844
+ if (isTargeted) {
845
+ const nodeLoc = path5.node.loc;
846
+ hitLocation = createLocationInfo(
847
+ nodeLoc.start.line,
848
+ nodeLoc.start.column,
849
+ lines,
850
+ consumer
851
+ );
852
+ }
853
+ bindings.push({
854
+ scopeUid,
855
+ kind: binding.kind,
856
+ definition,
857
+ references: limitedReferences,
858
+ totalReferences,
859
+ hitLocation
860
+ });
861
+ if (isTargeted) {
862
+ path5.stop();
863
+ }
864
+ }
865
+ });
866
+ } catch (err) {
867
+ const message = err instanceof Error ? err.message : String(err);
868
+ throw new Error(`Analysis error: ${message}`);
869
+ }
870
+ return {
871
+ bindings,
872
+ identifier,
873
+ isTargeted,
874
+ targetLine
875
+ };
876
+ }
877
+ function formatSourcePosition2(line, column) {
878
+ if (line !== null && column !== null) {
879
+ return `L${line}:${column}`;
880
+ }
881
+ return "";
882
+ }
883
+ function formatCodeLine2(lineNumber, sourcePos, code, prefix = " ") {
884
+ const lineNumStr = String(lineNumber).padStart(5, " ");
885
+ const srcPosPadded = sourcePos ? sourcePos.padEnd(10, " ") : " ";
886
+ return `${prefix}${lineNumStr} ${srcPosPadded} ${code}`;
887
+ }
888
+ function locationsMatch(loc1, loc2) {
889
+ return loc1.line === loc2.line && loc1.column === loc2.column;
890
+ }
891
+ function formatAnalysisResult(filePath, result, maxReferences = 10) {
892
+ const { bindings, identifier, isTargeted, targetLine } = result;
893
+ const outputParts = [];
894
+ outputParts.push(`${filePath}`);
895
+ outputParts.push(`Identifier="${identifier}"`);
896
+ outputParts.push(`Src=original position for breakpoints`);
897
+ if (bindings.length === 0) {
898
+ if (isTargeted && targetLine !== void 0) {
899
+ outputParts.push(`Bindings: None at line ${targetLine}`);
900
+ outputParts.push(`The variable may be global, externally defined, or not present at this line.`);
901
+ } else {
902
+ outputParts.push("Bindings: None");
903
+ }
904
+ return outputParts.join("\n");
905
+ }
906
+ if (isTargeted) {
907
+ outputParts.push(`Bindings: 1 (Targeted at line ${targetLine})`);
908
+ } else {
909
+ const scopeInfo = bindings.length > 1 ? " (different scopes)" : "";
910
+ outputParts.push(`Bindings: ${bindings.length}${scopeInfo}`);
911
+ }
912
+ for (let i = 0; i < bindings.length; i++) {
913
+ const binding = bindings[i];
914
+ if (isTargeted) {
915
+ outputParts.push(`--- Targeted Scope (${binding.kind}) ---`);
916
+ } else {
917
+ outputParts.push(`--- Scope #${i + 1} (${binding.kind}) ---`);
918
+ }
919
+ const defIsHit = isTargeted && binding.hitLocation && locationsMatch(binding.definition, binding.hitLocation);
920
+ const defPrefix = defIsHit ? "\u{1F4CD} Definition (hit):" : "\u{1F4CD} Definition:";
921
+ outputParts.push(defPrefix);
922
+ const defSrcPos = formatSourcePosition2(
923
+ binding.definition.originalPosition.line,
924
+ binding.definition.originalPosition.column
925
+ );
926
+ const defMarker = defIsHit ? " \u25C0\u2500\u2500 hit" : "";
927
+ outputParts.push(formatCodeLine2(binding.definition.line, defSrcPos, binding.definition.lineContent + defMarker, " "));
928
+ const totalRefs = binding.totalReferences;
929
+ if (totalRefs === 0) {
930
+ outputParts.push("\u{1F50E} References: None");
931
+ } else {
932
+ outputParts.push(`\u{1F50E} References (${totalRefs}):`);
933
+ for (const ref of binding.references) {
934
+ const refIsHit = isTargeted && binding.hitLocation && locationsMatch(ref, binding.hitLocation);
935
+ const refSrcPos = formatSourcePosition2(
936
+ ref.originalPosition.line,
937
+ ref.originalPosition.column
938
+ );
939
+ const refMarker = refIsHit ? " \u25C0\u2500\u2500 hit" : "";
940
+ outputParts.push(formatCodeLine2(ref.line, refSrcPos, ref.lineContent + refMarker, " "));
941
+ }
942
+ if (totalRefs > maxReferences) {
943
+ const remaining = totalRefs - maxReferences;
944
+ outputParts.push(` ... (${remaining} more references not shown)`);
945
+ }
946
+ }
947
+ }
948
+ return outputParts.join("\n");
949
+ }
950
+
951
+ // src/transformer.ts
952
+ import * as path3 from "path";
953
+ import * as fs2 from "fs/promises";
954
+ import { transformSync } from "@babel/core";
955
+ function cleanBasename(filename) {
956
+ const base = path3.basename(filename);
957
+ let name = base.endsWith(".js") ? base.slice(0, -3) : base;
958
+ name = name.replace(/_deob[^/]*$/, "");
959
+ if (name.endsWith(".beautified")) {
960
+ name = name.slice(0, -".beautified".length);
961
+ }
962
+ return name;
963
+ }
964
+ function getOutputPaths(targetFile, outputSuffix = "_deob") {
965
+ const absolutePath = path3.resolve(targetFile);
966
+ const dir = path3.dirname(absolutePath);
967
+ const basename3 = cleanBasename(absolutePath);
968
+ const outputPath = path3.join(dir, `${basename3}${outputSuffix}.js`);
969
+ const mapPath = `${outputPath}.map`;
970
+ return { outputPath, mapPath };
971
+ }
972
+ async function loadBabelPlugin(scriptPath) {
973
+ const absolutePath = path3.resolve(scriptPath);
974
+ try {
975
+ await fs2.access(absolutePath);
976
+ } catch {
977
+ throw new Error(`Script not found: ${absolutePath}`);
978
+ }
979
+ const fileUrl = `file://${absolutePath}?t=${Date.now()}`;
980
+ let module;
981
+ try {
982
+ module = await import(fileUrl);
983
+ } catch (err) {
984
+ const message = err instanceof Error ? err.message : String(err);
985
+ throw new Error(`Failed to load script: ${message}`);
986
+ }
987
+ const plugin = module.default ?? module;
988
+ if (typeof plugin !== "function") {
989
+ throw new Error(
990
+ `Invalid Babel plugin: Script must export a function that returns a visitor object. Got ${typeof plugin} instead.`
991
+ );
992
+ }
993
+ return plugin;
994
+ }
995
+ function runBabelTransform(code, inputSourceMap, plugin, filename) {
996
+ let result;
997
+ try {
998
+ result = transformSync(code, {
999
+ filename,
1000
+ plugins: [plugin],
1001
+ // Source map configuration for cascade
1002
+ // @ts-expect-error - SourceMap is compatible with InputSourceMap at runtime
1003
+ inputSourceMap,
1004
+ sourceMaps: true,
1005
+ // Readability settings
1006
+ retainLines: false,
1007
+ compact: false,
1008
+ minified: false,
1009
+ // Preserve code structure
1010
+ parserOpts: {
1011
+ sourceType: "unambiguous"
1012
+ }
1013
+ });
1014
+ } catch (err) {
1015
+ const message = err instanceof Error ? err.message : String(err);
1016
+ throw new Error(`Babel Error: ${message}`);
1017
+ }
1018
+ if (!result || !result.code) {
1019
+ throw new Error("Babel Error: Transform produced no output");
1020
+ }
1021
+ if (!result.map) {
1022
+ throw new Error("Babel Error: Transform produced no source map");
1023
+ }
1024
+ return {
1025
+ code: result.code,
1026
+ map: result.map
1027
+ };
1028
+ }
1029
+ async function applyCustomTransform(targetFile, options) {
1030
+ const { scriptPath, outputSuffix = "_deob" } = options;
1031
+ const absoluteTargetPath = path3.resolve(targetFile);
1032
+ try {
1033
+ await fs2.access(absoluteTargetPath);
1034
+ } catch {
1035
+ throw new Error(`File not found: ${targetFile}`);
1036
+ }
1037
+ const plugin = await loadBabelPlugin(scriptPath);
1038
+ const beautifyResult = await ensureBeautified(absoluteTargetPath);
1039
+ const { code: beautifiedCode, rawMap: inputSourceMap } = beautifyResult;
1040
+ const transformResult = runBabelTransform(
1041
+ beautifiedCode,
1042
+ inputSourceMap,
1043
+ plugin,
1044
+ absoluteTargetPath
1045
+ );
1046
+ const { outputPath, mapPath } = getOutputPaths(absoluteTargetPath, outputSuffix);
1047
+ const mapFileName = path3.basename(mapPath);
1048
+ const outputCode = `${transformResult.code}
1049
+ //# sourceMappingURL=${mapFileName}`;
1050
+ const outputMap = {
1051
+ ...transformResult.map,
1052
+ file: path3.basename(outputPath)
1053
+ };
1054
+ try {
1055
+ await Promise.all([
1056
+ fs2.writeFile(outputPath, outputCode, "utf-8"),
1057
+ fs2.writeFile(mapPath, JSON.stringify(outputMap, null, 2), "utf-8")
1058
+ ]);
1059
+ } catch (err) {
1060
+ const error = err;
1061
+ if (error.code === "EACCES" || error.code === "EPERM") {
1062
+ throw new Error(`Permission denied: Cannot write to ${path3.dirname(outputPath)}`);
1063
+ }
1064
+ throw new Error(`Failed to write output files: ${error.message || String(err)}`);
1065
+ }
1066
+ return {
1067
+ code: outputCode,
1068
+ map: outputMap,
1069
+ outputPath,
1070
+ mapPath
1071
+ };
1072
+ }
1073
+
1074
+ // src/index.ts
1075
+ async function smartRead(filePath, options) {
1076
+ const absolutePath = path4.resolve(filePath);
1077
+ try {
1078
+ await fs3.access(absolutePath);
1079
+ } catch {
1080
+ return {
1081
+ code: "",
1082
+ sourceMap: null,
1083
+ language: "unknown",
1084
+ usedFallback: true,
1085
+ error: `File not found: ${filePath}`
1086
+ };
1087
+ }
1088
+ const langInfo = options?.language ? getLanguageInfo(options.language) : detectLanguage(absolutePath);
1089
+ try {
1090
+ const beautifyResult = await ensureBeautified(absolutePath, {
1091
+ language: options?.language,
1092
+ saveLocal: options?.saveLocal
1093
+ });
1094
+ let code = beautifyResult.code;
1095
+ if (options?.startLine !== void 0 || options?.endLine !== void 0) {
1096
+ const lines = code.split("\n");
1097
+ const startLine = Math.max(1, options?.startLine ?? 1);
1098
+ const endLine = Math.min(lines.length, options?.endLine ?? lines.length);
1099
+ code = lines.slice(startLine - 1, endLine).join("\n");
1100
+ }
1101
+ const truncateResult = truncateCodeFromFile(absolutePath, code, {
1102
+ language: options?.language,
1103
+ charLimit: options?.charLimit,
1104
+ maxLineChars: options?.maxLineChars,
1105
+ previewLength: options?.previewLength
1106
+ });
1107
+ return {
1108
+ code: truncateResult.code,
1109
+ sourceMap: beautifyResult.rawMap,
1110
+ language: langInfo.language,
1111
+ usedFallback: beautifyResult.usedFallback || truncateResult.usedFallback,
1112
+ localPath: beautifyResult.localPath
1113
+ };
1114
+ } catch (err) {
1115
+ const message = err instanceof Error ? err.message : String(err);
1116
+ return {
1117
+ code: "",
1118
+ sourceMap: null,
1119
+ language: langInfo.language,
1120
+ usedFallback: true,
1121
+ error: message
1122
+ };
1123
+ }
1124
+ }
1125
+ async function smartSearch(filePath, query, options) {
1126
+ const absolutePath = path4.resolve(filePath);
1127
+ try {
1128
+ await fs3.access(absolutePath);
1129
+ } catch {
1130
+ return {
1131
+ matches: [],
1132
+ totalMatches: 0,
1133
+ truncated: false,
1134
+ formatted: `File not found: ${filePath}`,
1135
+ error: `File not found: ${filePath}`
1136
+ };
1137
+ }
1138
+ try {
1139
+ const beautifyResult = await ensureBeautified(absolutePath);
1140
+ if (!beautifyResult.rawMap) {
1141
+ return {
1142
+ matches: [],
1143
+ totalMatches: 0,
1144
+ truncated: false,
1145
+ formatted: `Search not supported for this file type (no source map available)`,
1146
+ error: `Search requires source map support`
1147
+ };
1148
+ }
1149
+ const searchResult = searchInCode(
1150
+ beautifyResult.code,
1151
+ beautifyResult.rawMap,
1152
+ options ?? { query }
1153
+ );
1154
+ const formatted = formatSearchResult(
1155
+ filePath,
1156
+ query,
1157
+ options?.caseSensitive ?? false,
1158
+ searchResult,
1159
+ options?.maxMatches ?? 50,
1160
+ options?.isRegex ?? false
1161
+ );
1162
+ return {
1163
+ ...searchResult,
1164
+ formatted
1165
+ };
1166
+ } catch (err) {
1167
+ const message = err instanceof Error ? err.message : String(err);
1168
+ return {
1169
+ matches: [],
1170
+ totalMatches: 0,
1171
+ truncated: false,
1172
+ formatted: `Search error: ${message}`,
1173
+ error: message
1174
+ };
1175
+ }
1176
+ }
1177
+ async function findUsage(filePath, identifier, options) {
1178
+ const absolutePath = path4.resolve(filePath);
1179
+ try {
1180
+ await fs3.access(absolutePath);
1181
+ } catch {
1182
+ return {
1183
+ bindings: [],
1184
+ identifier,
1185
+ isTargeted: options?.targetLine !== void 0,
1186
+ targetLine: options?.targetLine,
1187
+ formatted: `File not found: ${filePath}`,
1188
+ error: `File not found: ${filePath}`
1189
+ };
1190
+ }
1191
+ try {
1192
+ const beautifyResult = await ensureBeautified(absolutePath);
1193
+ if (!beautifyResult.rawMap) {
1194
+ return {
1195
+ bindings: [],
1196
+ identifier,
1197
+ isTargeted: options?.targetLine !== void 0,
1198
+ targetLine: options?.targetLine,
1199
+ formatted: `Analysis not supported for this file type (no source map available)`,
1200
+ error: `Analysis requires source map support`
1201
+ };
1202
+ }
1203
+ const analysisResult = await analyzeBindings(
1204
+ beautifyResult.code,
1205
+ beautifyResult.rawMap,
1206
+ identifier,
1207
+ options
1208
+ );
1209
+ const formatted = formatAnalysisResult(
1210
+ filePath,
1211
+ analysisResult,
1212
+ options?.maxReferences ?? 10
1213
+ );
1214
+ return {
1215
+ ...analysisResult,
1216
+ formatted
1217
+ };
1218
+ } catch (err) {
1219
+ const message = err instanceof Error ? err.message : String(err);
1220
+ return {
1221
+ bindings: [],
1222
+ identifier,
1223
+ isTargeted: options?.targetLine !== void 0,
1224
+ targetLine: options?.targetLine,
1225
+ formatted: `Analysis error: ${message}`,
1226
+ error: message
1227
+ };
1228
+ }
1229
+ }
1230
+ export {
1231
+ analyzeBindings,
1232
+ applyCustomTransform,
1233
+ beautifyCode,
1234
+ beautifyCss,
1235
+ beautifyHtml,
1236
+ beautifyJson,
1237
+ cleanBasename,
1238
+ createRegex,
1239
+ detectLanguage,
1240
+ ensureBeautified,
1241
+ escapeRegex,
1242
+ findUsage,
1243
+ formatAnalysisResult,
1244
+ formatSourcePosition2 as formatAnalyzeSourcePosition,
1245
+ formatSearchResult,
1246
+ formatSourcePosition as formatSearchSourcePosition,
1247
+ getLanguageInfo,
1248
+ getLocalPaths,
1249
+ getOutputPaths,
1250
+ getSupportedExtensions,
1251
+ isExtensionSupported,
1252
+ isFullySupportedLanguage,
1253
+ isLocalCacheValid,
1254
+ loadBabelPlugin,
1255
+ parseCode,
1256
+ runBabelTransform,
1257
+ searchInCode,
1258
+ smartRead,
1259
+ smartSearch,
1260
+ truncateCode,
1261
+ truncateCodeFromFile,
1262
+ truncateCodeHighPerf,
1263
+ truncateFallback,
1264
+ truncateLongLines,
1265
+ unescapeBackslashes
1266
+ };
1267
+ //# sourceMappingURL=index.js.map