@reverse-craft/smart-fs 1.0.4 → 1.0.6
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/dist/server.js +154 -92
- package/dist/server.js.map +3 -3
- package/package.json +2 -2
package/dist/server.js
CHANGED
|
@@ -91,7 +91,6 @@ async function isLocalCacheValid(originalPath) {
|
|
|
91
91
|
}
|
|
92
92
|
async function ensureBeautified(originalPath, options) {
|
|
93
93
|
const absolutePath = path.resolve(originalPath);
|
|
94
|
-
const saveLocal = options?.saveLocal ?? false;
|
|
95
94
|
let stats;
|
|
96
95
|
try {
|
|
97
96
|
stats = await fs.stat(absolutePath);
|
|
@@ -99,22 +98,20 @@ async function ensureBeautified(originalPath, options) {
|
|
|
99
98
|
throw new Error(`File not found: ${originalPath}`);
|
|
100
99
|
}
|
|
101
100
|
const localPaths = getLocalPaths(absolutePath);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
} catch {
|
|
117
|
-
}
|
|
101
|
+
const localCacheCheck = await isLocalCacheValid(absolutePath);
|
|
102
|
+
if (localCacheCheck.isValid) {
|
|
103
|
+
try {
|
|
104
|
+
const [code2, mapContent] = await Promise.all([
|
|
105
|
+
fs.readFile(localPaths.beautifiedPath, "utf-8"),
|
|
106
|
+
fs.readFile(localPaths.mapPath, "utf-8")
|
|
107
|
+
]);
|
|
108
|
+
return {
|
|
109
|
+
code: code2,
|
|
110
|
+
rawMap: JSON.parse(mapContent),
|
|
111
|
+
localPath: localPaths.beautifiedPath,
|
|
112
|
+
localMapPath: localPaths.mapPath
|
|
113
|
+
};
|
|
114
|
+
} catch {
|
|
118
115
|
}
|
|
119
116
|
}
|
|
120
117
|
await ensureCacheDir();
|
|
@@ -127,11 +124,11 @@ async function ensureBeautified(originalPath, options) {
|
|
|
127
124
|
]);
|
|
128
125
|
const result2 = {
|
|
129
126
|
code: code2,
|
|
130
|
-
rawMap: JSON.parse(mapContent)
|
|
127
|
+
rawMap: JSON.parse(mapContent),
|
|
128
|
+
localPath: localPaths.beautifiedPath,
|
|
129
|
+
localMapPath: localPaths.mapPath
|
|
131
130
|
};
|
|
132
|
-
|
|
133
|
-
await saveToLocal(result2, localPaths, mapContent);
|
|
134
|
-
}
|
|
131
|
+
await saveToLocal(result2, localPaths, mapContent);
|
|
135
132
|
return result2;
|
|
136
133
|
}
|
|
137
134
|
let esbuildResult;
|
|
@@ -165,10 +162,13 @@ async function ensureBeautified(originalPath, options) {
|
|
|
165
162
|
fs.writeFile(beautifiedPath, code, "utf-8"),
|
|
166
163
|
fs.writeFile(mapPath, mapText, "utf-8")
|
|
167
164
|
]);
|
|
168
|
-
const result = {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
165
|
+
const result = {
|
|
166
|
+
code,
|
|
167
|
+
rawMap,
|
|
168
|
+
localPath: localPaths.beautifiedPath,
|
|
169
|
+
localMapPath: localPaths.mapPath
|
|
170
|
+
};
|
|
171
|
+
await saveToLocal(result, localPaths, mapText);
|
|
172
172
|
return result;
|
|
173
173
|
}
|
|
174
174
|
async function saveToLocal(result, localPaths, mapText) {
|
|
@@ -281,17 +281,14 @@ function formatSourcePosition(line, column) {
|
|
|
281
281
|
}
|
|
282
282
|
function formatHeader(filePath, startLine, endLine, totalLines) {
|
|
283
283
|
return [
|
|
284
|
-
|
|
285
|
-
`
|
|
286
|
-
`INFO: [Src L:C] = Location in original minified file (for Chrome Breakpoints)`,
|
|
287
|
-
"-".repeat(85)
|
|
284
|
+
`${filePath} (${startLine}-${endLine}/${totalLines})`,
|
|
285
|
+
`Src=original position for breakpoints`
|
|
288
286
|
].join("\n");
|
|
289
287
|
}
|
|
290
288
|
function formatCodeLine(lineNumber, sourcePos, code, maxLineNumWidth) {
|
|
291
289
|
const lineNumStr = String(lineNumber).padStart(maxLineNumWidth, " ");
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
return `${lineNumStr} | [${srcPosPadded}] | ${code}`;
|
|
290
|
+
const srcPos = sourcePos ? sourcePos.padEnd(10, " ") : " ";
|
|
291
|
+
return `${lineNumStr} ${srcPos} ${code}`;
|
|
295
292
|
}
|
|
296
293
|
function formatPaginationHint(nextStartLine) {
|
|
297
294
|
return `
|
|
@@ -331,13 +328,12 @@ var readCodeSmart = defineTool({
|
|
|
331
328
|
if (localPath) {
|
|
332
329
|
outputParts.push(`LOCAL: ${localPath}`);
|
|
333
330
|
if (localMapPath) {
|
|
334
|
-
outputParts.push(`
|
|
331
|
+
outputParts.push(`MAP: ${localMapPath}`);
|
|
335
332
|
}
|
|
336
333
|
}
|
|
337
334
|
if (localSaveError) {
|
|
338
|
-
outputParts.push(`
|
|
335
|
+
outputParts.push(`ERROR: ${localSaveError}`);
|
|
339
336
|
}
|
|
340
|
-
outputParts.push("-".repeat(85));
|
|
341
337
|
}
|
|
342
338
|
const maxLineNumWidth = String(effectiveEndLine).length;
|
|
343
339
|
for (let lineNum = effectiveStartLine; lineNum <= effectiveEndLine; lineNum++) {
|
|
@@ -518,14 +514,11 @@ import { z as z3 } from "zod";
|
|
|
518
514
|
|
|
519
515
|
// src/searcher.ts
|
|
520
516
|
import { SourceMapConsumer as SourceMapConsumer2 } from "source-map-js";
|
|
521
|
-
function
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
527
|
-
throw new Error(`Invalid regex: ${message}`);
|
|
528
|
-
}
|
|
517
|
+
function unescapeBackslashes(str) {
|
|
518
|
+
return str.replace(/\\\\/g, "\\");
|
|
519
|
+
}
|
|
520
|
+
function escapeRegex(str) {
|
|
521
|
+
return str.replace(/[()[\]{}.*+?^$|\\]/g, "\\$&");
|
|
529
522
|
}
|
|
530
523
|
function getOriginalPosition(consumer, lineNumber) {
|
|
531
524
|
const pos = consumer.originalPositionFor({
|
|
@@ -537,61 +530,126 @@ function getOriginalPosition(consumer, lineNumber) {
|
|
|
537
530
|
column: pos.column
|
|
538
531
|
};
|
|
539
532
|
}
|
|
540
|
-
function
|
|
533
|
+
function buildLineOffsets(code) {
|
|
534
|
+
let capacity = Math.max(16, Math.ceil(code.length / 40));
|
|
535
|
+
let offsets = new Int32Array(capacity);
|
|
536
|
+
let lineCount = 0;
|
|
537
|
+
offsets[0] = 0;
|
|
538
|
+
for (let i = 0; i < code.length; i++) {
|
|
539
|
+
if (code[i] === "\n") {
|
|
540
|
+
lineCount++;
|
|
541
|
+
if (lineCount >= capacity) {
|
|
542
|
+
capacity *= 2;
|
|
543
|
+
const newArr = new Int32Array(capacity);
|
|
544
|
+
newArr.set(offsets);
|
|
545
|
+
offsets = newArr;
|
|
546
|
+
}
|
|
547
|
+
offsets[lineCount] = i + 1;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
541
550
|
return {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
originalPosition: getOriginalPosition(consumer, lineNumber)
|
|
551
|
+
offsets: offsets.subarray(0, lineCount + 1),
|
|
552
|
+
totalLines: lineCount + 1
|
|
545
553
|
};
|
|
546
554
|
}
|
|
555
|
+
function getLineNumberFromIndex(offsets, totalLines, index) {
|
|
556
|
+
let low = 0;
|
|
557
|
+
let high = totalLines - 1;
|
|
558
|
+
while (low <= high) {
|
|
559
|
+
const mid = low + high >>> 1;
|
|
560
|
+
if (offsets[mid] <= index) {
|
|
561
|
+
low = mid + 1;
|
|
562
|
+
} else {
|
|
563
|
+
high = mid - 1;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return low;
|
|
567
|
+
}
|
|
568
|
+
function getLineContent(code, offsets, totalLines, lineNo) {
|
|
569
|
+
if (lineNo < 1 || lineNo > totalLines) return "";
|
|
570
|
+
const start = offsets[lineNo - 1];
|
|
571
|
+
let end;
|
|
572
|
+
if (lineNo < totalLines) {
|
|
573
|
+
end = offsets[lineNo] - 1;
|
|
574
|
+
} else {
|
|
575
|
+
end = code.length;
|
|
576
|
+
}
|
|
577
|
+
if (end > start && code[end - 1] === "\r") {
|
|
578
|
+
end--;
|
|
579
|
+
}
|
|
580
|
+
return code.slice(start, end);
|
|
581
|
+
}
|
|
547
582
|
function searchInCode(code, rawMap, options) {
|
|
548
583
|
const {
|
|
549
584
|
query,
|
|
550
585
|
contextLines = 2,
|
|
551
586
|
caseSensitive = false,
|
|
552
|
-
maxMatches =
|
|
587
|
+
maxMatches = 10,
|
|
588
|
+
isRegex = false,
|
|
589
|
+
timeoutMs = 500
|
|
553
590
|
} = options;
|
|
554
|
-
const
|
|
555
|
-
const
|
|
556
|
-
const
|
|
591
|
+
const { offsets, totalLines } = buildLineOffsets(code);
|
|
592
|
+
const flags = (caseSensitive ? "g" : "gi") + "m";
|
|
593
|
+
const patternStr = isRegex ? unescapeBackslashes(query) : escapeRegex(query);
|
|
594
|
+
let regex;
|
|
595
|
+
try {
|
|
596
|
+
regex = new RegExp(patternStr, flags);
|
|
597
|
+
} catch (err) {
|
|
598
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
599
|
+
throw new Error(`Invalid regex: ${message}`);
|
|
600
|
+
}
|
|
557
601
|
const consumer = new SourceMapConsumer2({
|
|
558
602
|
...rawMap,
|
|
559
603
|
version: String(rawMap.version)
|
|
560
604
|
});
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
605
|
+
const matches = [];
|
|
606
|
+
let lastMatchedLine = -1;
|
|
607
|
+
let totalMatchesFound = 0;
|
|
608
|
+
let match;
|
|
609
|
+
const startTime = Date.now();
|
|
610
|
+
while ((match = regex.exec(code)) !== null) {
|
|
611
|
+
if (match.index === regex.lastIndex) {
|
|
612
|
+
regex.lastIndex++;
|
|
567
613
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
const limitedLineNumbers = matchingLineNumbers.slice(0, maxMatches);
|
|
572
|
-
const matches = limitedLineNumbers.map((lineNumber) => {
|
|
573
|
-
const lineIndex = lineNumber - 1;
|
|
574
|
-
const lineContent = lines[lineIndex];
|
|
575
|
-
const contextBefore = [];
|
|
576
|
-
for (let i = Math.max(0, lineIndex - contextLines); i < lineIndex; i++) {
|
|
577
|
-
contextBefore.push(createContextLine(i + 1, lines[i], consumer));
|
|
614
|
+
const lineNumber = getLineNumberFromIndex(offsets, totalLines, match.index);
|
|
615
|
+
if (lineNumber === lastMatchedLine) {
|
|
616
|
+
continue;
|
|
578
617
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
618
|
+
lastMatchedLine = lineNumber;
|
|
619
|
+
totalMatchesFound++;
|
|
620
|
+
if (matches.length < maxMatches) {
|
|
621
|
+
const contextBefore = [];
|
|
622
|
+
for (let i = Math.max(1, lineNumber - contextLines); i < lineNumber; i++) {
|
|
623
|
+
contextBefore.push({
|
|
624
|
+
lineNumber: i,
|
|
625
|
+
content: getLineContent(code, offsets, totalLines, i),
|
|
626
|
+
originalPosition: getOriginalPosition(consumer, i)
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
const contextAfter = [];
|
|
630
|
+
for (let i = lineNumber + 1; i <= Math.min(totalLines, lineNumber + contextLines); i++) {
|
|
631
|
+
contextAfter.push({
|
|
632
|
+
lineNumber: i,
|
|
633
|
+
content: getLineContent(code, offsets, totalLines, i),
|
|
634
|
+
originalPosition: getOriginalPosition(consumer, i)
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
matches.push({
|
|
638
|
+
lineNumber,
|
|
639
|
+
lineContent: getLineContent(code, offsets, totalLines, lineNumber),
|
|
640
|
+
originalPosition: getOriginalPosition(consumer, lineNumber),
|
|
641
|
+
contextBefore,
|
|
642
|
+
contextAfter
|
|
643
|
+
});
|
|
582
644
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
contextBefore,
|
|
588
|
-
contextAfter
|
|
589
|
-
};
|
|
590
|
-
});
|
|
645
|
+
if (Date.now() - startTime > timeoutMs) {
|
|
646
|
+
break;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
591
649
|
return {
|
|
592
650
|
matches,
|
|
593
|
-
totalMatches,
|
|
594
|
-
truncated
|
|
651
|
+
totalMatches: totalMatchesFound,
|
|
652
|
+
truncated: totalMatchesFound > maxMatches
|
|
595
653
|
};
|
|
596
654
|
}
|
|
597
655
|
function formatSourcePosition2(line, column) {
|
|
@@ -600,12 +658,13 @@ function formatSourcePosition2(line, column) {
|
|
|
600
658
|
}
|
|
601
659
|
return "";
|
|
602
660
|
}
|
|
603
|
-
function formatSearchResult(filePath, query, caseSensitive, result, maxMatches = 50) {
|
|
661
|
+
function formatSearchResult(filePath, query, caseSensitive, result, maxMatches = 50, isRegex = false) {
|
|
604
662
|
const { matches, totalMatches, truncated } = result;
|
|
605
663
|
const outputParts = [];
|
|
606
664
|
const caseInfo = caseSensitive ? "case-sensitive" : "case-insensitive";
|
|
665
|
+
const modeInfo = isRegex ? "regex" : "literal";
|
|
607
666
|
outputParts.push(`FILE: ${filePath}`);
|
|
608
|
-
outputParts.push(`QUERY: "${query}" (${caseInfo})`);
|
|
667
|
+
outputParts.push(`QUERY: "${query}" (${modeInfo}, ${caseInfo})`);
|
|
609
668
|
if (totalMatches === 0) {
|
|
610
669
|
outputParts.push("MATCHES: No matches found");
|
|
611
670
|
return outputParts.join("\n");
|
|
@@ -652,7 +711,8 @@ var SearchCodeSmartInputSchema = z3.object({
|
|
|
652
711
|
context_lines: z3.number().int().min(0).default(2).describe("Number of context lines"),
|
|
653
712
|
case_sensitive: z3.boolean().default(false).describe("Case sensitive search"),
|
|
654
713
|
char_limit: z3.number().int().min(50).default(300).describe("Character limit for string truncation"),
|
|
655
|
-
max_line_chars: z3.number().int().min(80).default(500).describe("Maximum characters per line")
|
|
714
|
+
max_line_chars: z3.number().int().min(80).default(500).describe("Maximum characters per line"),
|
|
715
|
+
is_regex: z3.boolean().default(false).describe("Treat query as regex pattern (default: false for literal text search)")
|
|
656
716
|
});
|
|
657
717
|
var searchCodeSmart = defineTool({
|
|
658
718
|
name: "search_code_smart",
|
|
@@ -663,20 +723,22 @@ var searchCodeSmart = defineTool({
|
|
|
663
723
|
context_lines: z3.number().int().min(0).default(2).describe("Number of context lines"),
|
|
664
724
|
case_sensitive: z3.boolean().default(false).describe("Case sensitive search"),
|
|
665
725
|
char_limit: z3.number().int().min(50).default(300).describe("Character limit for string truncation"),
|
|
666
|
-
max_line_chars: z3.number().int().min(80).default(500).describe("Maximum characters per line")
|
|
726
|
+
max_line_chars: z3.number().int().min(80).default(500).describe("Maximum characters per line"),
|
|
727
|
+
is_regex: z3.boolean().default(false).describe("Treat query as regex pattern (default: false for literal text search)")
|
|
667
728
|
},
|
|
668
729
|
handler: async (params) => {
|
|
669
|
-
const { file_path, query, context_lines, case_sensitive, char_limit, max_line_chars } = params;
|
|
730
|
+
const { file_path, query, context_lines, case_sensitive, char_limit, max_line_chars, is_regex } = params;
|
|
731
|
+
const unescapedQuery = unescapeBackslashes(query);
|
|
670
732
|
const beautifyResult = await ensureBeautified(file_path);
|
|
671
733
|
const { code, rawMap } = beautifyResult;
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
query,
|
|
734
|
+
const searchResult = searchInCode(code, rawMap, {
|
|
735
|
+
query: unescapedQuery,
|
|
675
736
|
contextLines: context_lines,
|
|
676
737
|
caseSensitive: case_sensitive,
|
|
677
|
-
maxMatches: 50
|
|
738
|
+
maxMatches: 50,
|
|
739
|
+
isRegex: is_regex
|
|
678
740
|
});
|
|
679
|
-
let output = formatSearchResult(file_path,
|
|
741
|
+
let output = formatSearchResult(file_path, unescapedQuery, case_sensitive, searchResult, 50, is_regex);
|
|
680
742
|
output = truncateLongLines(output, max_line_chars);
|
|
681
743
|
return output;
|
|
682
744
|
}
|
|
@@ -726,7 +788,7 @@ function getOriginalPosition2(consumer, line, column) {
|
|
|
726
788
|
column: pos.column
|
|
727
789
|
};
|
|
728
790
|
}
|
|
729
|
-
function
|
|
791
|
+
function getLineContent2(lines, lineNumber) {
|
|
730
792
|
if (lineNumber < 1 || lineNumber > lines.length) {
|
|
731
793
|
return "";
|
|
732
794
|
}
|
|
@@ -737,7 +799,7 @@ function createLocationInfo(line, column, lines, consumer) {
|
|
|
737
799
|
line,
|
|
738
800
|
column,
|
|
739
801
|
originalPosition: getOriginalPosition2(consumer, line, column),
|
|
740
|
-
lineContent:
|
|
802
|
+
lineContent: getLineContent2(lines, line)
|
|
741
803
|
};
|
|
742
804
|
}
|
|
743
805
|
async function analyzeBindings(code, rawMap, identifier, options) {
|
package/dist/server.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/server.ts", "../src/tools/readCodeSmart.ts", "../src/tools/ToolDefinition.ts", "../src/beautifier.ts", "../src/truncator.ts", "../src/tools/applyCustomTransform.ts", "../src/transformer.ts", "../src/tools/searchCodeSmart.ts", "../src/searcher.ts", "../src/tools/findUsageSmart.ts", "../src/analyzer.ts", "../src/tools/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { tools } from './tools/index.js';\n\n// Create MCP Server instance\nconst server = new McpServer({\n name: 'smart-fs',\n version: '1.0.0',\n});\n\n/**\n * Register a tool with the MCP server.\n * Converts ToolDefinition to MCP tool registration format.\n * \n * @param tool - The tool definition to register\n */\nfunction registerTool(tool: {\n name: string;\n description: string;\n schema: z.ZodRawShape;\n handler: (params: Record<string, unknown>) => Promise<string>;\n}): void {\n // Create Zod object schema from raw shape for validation\n const zodSchema = z.object(tool.schema);\n\n // Register the tool with MCP server using registerTool API\n server.registerTool(\n tool.name,\n {\n description: tool.description,\n inputSchema: tool.schema,\n },\n async (params, _extra) => {\n try {\n // Validate and parse input using the Zod schema\n const validatedParams = zodSchema.parse(params);\n const result = await tool.handler(validatedParams as Record<string, unknown>);\n\n return {\n content: [{ type: 'text' as const, text: result }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n };\n }\n }\n );\n}\n\n// Register all tools from the tools array\nfor (const tool of tools) {\n registerTool(tool as unknown as {\n name: string;\n description: string;\n schema: z.ZodRawShape;\n handler: (params: Record<string, unknown>) => Promise<string>;\n });\n}\n\n// Main entry point\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error('Smart FS MCP Server running on stdio');\n}\n\nmain().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n", "import { z } from 'zod';\nimport { SourceMapConsumer } from 'source-map-js';\nimport { defineTool } from './ToolDefinition.js';\nimport { ensureBeautified } from '../beautifier.js';\nimport { truncateCodeHighPerf, truncateLongLines } from '../truncator.js';\n\n/**\n * Format source position as \"L{line}:{column}\" or empty placeholder\n */\nfunction formatSourcePosition(line: number | null, column: number | null): string {\n if (line !== null && column !== null) {\n return `L${line}:${column}`;\n }\n return '';\n}\n\n/**\n * Format output header with file info\n */\nfunction formatHeader(filePath: string, startLine: number, endLine: number, totalLines: number): string {\n return [\n `FILE: ${filePath}`,\n `VIEW: Auto-beautified (Lines ${startLine}-${endLine} of ${totalLines})`,\n `INFO: [Src L:C] = Location in original minified file (for Chrome Breakpoints)`,\n '-'.repeat(85),\n ].join('\\n');\n}\n\n/**\n * Format a single code line with line number, source coordinates, and content\n */\nfunction formatCodeLine(lineNumber: number, sourcePos: string, code: string, maxLineNumWidth: number): string {\n const lineNumStr = String(lineNumber).padStart(maxLineNumWidth, ' ');\n const srcPosStr = sourcePos ? `Src ${sourcePos}` : '';\n const srcPosPadded = srcPosStr.padEnd(14, ' ');\n return `${lineNumStr} | [${srcPosPadded}] | ${code}`;\n}\n\n/**\n * Format pagination hint\n */\nfunction formatPaginationHint(nextStartLine: number): string {\n return `\\n... (Use next start_line=${nextStartLine} to read more)`;\n}\n\n/**\n * read_code_smart tool definition\n * Read and beautify minified/obfuscated JavaScript code with source map coordinates.\n */\nexport const readCodeSmart = defineTool({\n name: 'read_code_smart',\n description:\n 'Read and beautify minified/obfuscated JavaScript code with source map coordinates. ' +\n 'Returns formatted code with original file positions for setting breakpoints. ' +\n 'Optionally saves the beautified file locally alongside the original file.',\n schema: {\n file_path: z.string().describe('Path to the JavaScript file'),\n start_line: z.number().int().min(1).describe('Start line number (1-based)'),\n end_line: z.number().int().min(1).describe('End line number (1-based)'),\n char_limit: z.number().int().min(50).default(300).describe('Character limit for string truncation'),\n max_line_chars: z.number().int().min(80).default(500).describe('Maximum characters per line'),\n save_local: z.boolean().optional().default(false).describe('Save beautified file to the same directory as the original file'),\n },\n handler: async (params) => {\n const { file_path, start_line, end_line, char_limit, max_line_chars, save_local } = params;\n\n // Beautify the file and get source map\n const beautifyResult = await ensureBeautified(file_path, { saveLocal: save_local });\n const { code, rawMap, localPath, localMapPath, localSaveError } = beautifyResult;\n\n // Truncate long strings\n const truncatedCode = truncateCodeHighPerf(code, char_limit);\n\n // Truncate long lines\n const lineTruncatedCode = truncateLongLines(truncatedCode, max_line_chars);\n\n // Split into lines\n const lines = lineTruncatedCode.split('\\n');\n const totalLines = lines.length;\n\n // Validate line range\n const effectiveStartLine = Math.max(1, start_line);\n const effectiveEndLine = Math.min(totalLines, end_line);\n\n if (effectiveStartLine > totalLines) {\n throw new Error(`Start line ${start_line} exceeds total lines ${totalLines}`);\n }\n\n // Create source map consumer (cast version to string as required by source-map-js)\n const consumer = new SourceMapConsumer({\n ...rawMap,\n version: String(rawMap.version),\n });\n\n // Build output\n const outputParts: string[] = [];\n\n // Add header\n outputParts.push(formatHeader(file_path, effectiveStartLine, effectiveEndLine, totalLines));\n\n // Add local save info if applicable\n if (save_local) {\n if (localPath) {\n outputParts.push(`LOCAL: ${localPath}`);\n if (localMapPath) {\n outputParts.push(`LOCAL_MAP: ${localMapPath}`);\n }\n }\n if (localSaveError) {\n outputParts.push(`LOCAL_SAVE_ERROR: ${localSaveError}`);\n }\n outputParts.push('-'.repeat(85));\n }\n\n // Calculate max line number width for alignment\n const maxLineNumWidth = String(effectiveEndLine).length;\n\n // Format each line\n for (let lineNum = effectiveStartLine; lineNum <= effectiveEndLine; lineNum++) {\n const lineIndex = lineNum - 1;\n const lineContent = lines[lineIndex] ?? '';\n\n // Get original position from source map\n const originalPos = consumer.originalPositionFor({\n line: lineNum,\n column: 0,\n });\n\n const sourcePos = formatSourcePosition(originalPos.line, originalPos.column);\n outputParts.push(formatCodeLine(lineNum, sourcePos, lineContent, maxLineNumWidth));\n }\n\n // Add pagination hint if there are more lines\n if (effectiveEndLine < totalLines) {\n outputParts.push(formatPaginationHint(effectiveEndLine + 1));\n }\n\n return outputParts.join('\\n');\n },\n});\n", "import { z } from 'zod';\n\n/**\n * Tool definition interface for MCP tools.\n * Each tool has a name, description, schema (Zod raw shape), and async handler.\n */\nexport interface ToolDefinition<TSchema extends z.ZodRawShape = z.ZodRawShape> {\n /** Unique tool name (e.g., 'read_code_smart') */\n name: string;\n /** Human-readable description of what the tool does */\n description: string;\n /** Zod schema object defining input parameters */\n schema: TSchema;\n /** Async handler function that processes the tool request */\n handler: (params: z.infer<z.ZodObject<TSchema>>) => Promise<string>;\n}\n\n/**\n * Helper function to create a type-safe tool definition.\n * Validates the tool definition structure at compile time.\n * \n * @param definition - The tool definition object\n * @returns The same definition with proper typing\n */\nexport function defineTool<TSchema extends z.ZodRawShape>(\n definition: ToolDefinition<TSchema>\n): ToolDefinition<TSchema> {\n return definition;\n}\n", "import * as esbuild from 'esbuild';\nimport * as crypto from 'crypto';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport * as os from 'os';\n\nconst TEMP_DIR = path.join(os.tmpdir(), 'smart-fs-mcp-cache');\n\nexport interface SourceMap {\n version: number;\n sources: string[];\n names: string[];\n mappings: string;\n file?: string;\n sourceRoot?: string;\n}\n\nexport interface BeautifyOptions {\n /** \u662F\u5426\u4FDD\u5B58\u5230\u539F\u59CB\u6587\u4EF6\u540C\u7EA7\u76EE\u5F55 */\n saveLocal?: boolean;\n}\n\nexport interface BeautifyResult {\n code: string;\n rawMap: SourceMap;\n /** \u672C\u5730\u4FDD\u5B58\u7684\u7F8E\u5316\u6587\u4EF6\u8DEF\u5F84 (\u4EC5\u5F53 saveLocal=true \u65F6\u5B58\u5728) */\n localPath?: string;\n /** \u672C\u5730\u4FDD\u5B58\u7684 source map \u8DEF\u5F84 (\u4EC5\u5F53 saveLocal=true \u65F6\u5B58\u5728) */\n localMapPath?: string;\n /** \u672C\u5730\u4FDD\u5B58\u5931\u8D25\u65F6\u7684\u9519\u8BEF\u4FE1\u606F */\n localSaveError?: string;\n}\n\n/**\n * Ensure the cache directory exists\n */\nasync function ensureCacheDir(): Promise<void> {\n await fs.mkdir(TEMP_DIR, { recursive: true });\n}\n\n/**\n * Calculate cache key based on file path and modification time\n */\nfunction calculateCacheKey(originalPath: string, mtimeMs: number): string {\n const fileKey = `${originalPath}-${mtimeMs}`;\n return crypto.createHash('md5').update(fileKey).digest('hex');\n}\n\n/**\n * Get cache file paths for a given original file\n */\nfunction getCachePaths(originalPath: string, hash: string): { beautifiedPath: string; mapPath: string } {\n const fileName = path.basename(originalPath, '.js');\n const beautifiedPath = path.join(TEMP_DIR, `${fileName}.${hash}.beautified.js`);\n const mapPath = `${beautifiedPath}.map`;\n return { beautifiedPath, mapPath };\n}\n\n\n/**\n * Local paths result interface\n */\nexport interface LocalPaths {\n /** Path to the beautified file in the same directory as the original */\n beautifiedPath: string;\n /** Path to the source map file in the same directory as the original */\n mapPath: string;\n}\n\n/**\n * Get local file paths for beautified output\n * Given an original file path, returns the paths where the beautified file\n * and source map should be saved in the same directory.\n * \n * Naming convention:\n * - Original: {filename}.js -> Beautified: {filename}.beautified.js\n * - Source map: {filename}.beautified.js.map\n * \n * @param originalPath - Path to the original JavaScript file\n * @returns Object containing beautifiedPath and mapPath\n */\nexport function getLocalPaths(originalPath: string): LocalPaths {\n const absolutePath = path.resolve(originalPath);\n const dir = path.dirname(absolutePath);\n const ext = path.extname(absolutePath);\n const baseName = path.basename(absolutePath, ext);\n \n const beautifiedPath = path.join(dir, `${baseName}.beautified.js`);\n const mapPath = `${beautifiedPath}.map`;\n \n return { beautifiedPath, mapPath };\n}\n\n/**\n * Check if cache exists and is valid (for temp directory cache)\n */\nasync function isCacheValid(beautifiedPath: string, mapPath: string): Promise<boolean> {\n try {\n await Promise.all([\n fs.access(beautifiedPath),\n fs.access(mapPath)\n ]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Local cache validation result interface\n */\nexport interface LocalCacheCheck {\n /** Original file modification time in milliseconds */\n originalMtime: number;\n /** Whether the beautified file exists */\n beautifiedExists: boolean;\n /** Beautified file modification time in milliseconds (0 if not exists) */\n beautifiedMtime: number;\n /** Whether the cache is valid (beautifiedMtime >= originalMtime) */\n isValid: boolean;\n}\n\n/**\n * Check if local beautified cache is valid\n * \n * A local cache is considered valid when:\n * 1. The beautified file exists\n * 2. The beautified file's modification time is >= the original file's modification time\n * \n * @param originalPath - Path to the original JavaScript file\n * @returns LocalCacheCheck object with validation details\n */\nexport async function isLocalCacheValid(originalPath: string): Promise<LocalCacheCheck> {\n const absolutePath = path.resolve(originalPath);\n const { beautifiedPath } = getLocalPaths(absolutePath);\n \n // Get original file stats\n let originalStats: Awaited<ReturnType<typeof fs.stat>>;\n try {\n originalStats = await fs.stat(absolutePath);\n } catch {\n // Original file doesn't exist - cache cannot be valid\n return {\n originalMtime: 0,\n beautifiedExists: false,\n beautifiedMtime: 0,\n isValid: false\n };\n }\n \n const originalMtime = originalStats.mtimeMs;\n \n // Check if beautified file exists and get its stats\n let beautifiedStats: Awaited<ReturnType<typeof fs.stat>>;\n try {\n beautifiedStats = await fs.stat(beautifiedPath);\n } catch {\n // Beautified file doesn't exist\n return {\n originalMtime,\n beautifiedExists: false,\n beautifiedMtime: 0,\n isValid: false\n };\n }\n \n const beautifiedMtime = beautifiedStats.mtimeMs;\n const isValid = beautifiedMtime >= originalMtime;\n \n return {\n originalMtime,\n beautifiedExists: true,\n beautifiedMtime,\n isValid\n };\n}\n\n/**\n * Beautify JavaScript file and generate Source Map\n * @param originalPath - Original file path\n * @param options - Optional beautify options (saveLocal, etc.)\n * @returns Beautified code and Source Map\n */\nexport async function ensureBeautified(\n originalPath: string,\n options?: BeautifyOptions\n): Promise<BeautifyResult> {\n // Resolve to absolute path\n const absolutePath = path.resolve(originalPath);\n const saveLocal = options?.saveLocal ?? false;\n \n // Check if file exists\n let stats: Awaited<ReturnType<typeof fs.stat>>;\n try {\n stats = await fs.stat(absolutePath);\n } catch {\n throw new Error(`File not found: ${originalPath}`);\n }\n \n // Get local paths for potential local save/read\n const localPaths = getLocalPaths(absolutePath);\n \n // If saveLocal is true, check local cache first\n if (saveLocal) {\n const localCacheCheck = await isLocalCacheValid(absolutePath);\n if (localCacheCheck.isValid) {\n // Local cache hit - read from local files\n try {\n const [code, mapContent] = await Promise.all([\n fs.readFile(localPaths.beautifiedPath, 'utf-8'),\n fs.readFile(localPaths.mapPath, 'utf-8')\n ]);\n return {\n code,\n rawMap: JSON.parse(mapContent) as SourceMap,\n localPath: localPaths.beautifiedPath,\n localMapPath: localPaths.mapPath\n };\n } catch {\n // If reading local cache fails, fall through to regenerate\n }\n }\n }\n \n // Ensure temp cache directory exists\n await ensureCacheDir();\n \n // Calculate cache key for temp directory\n const hash = calculateCacheKey(absolutePath, stats.mtimeMs);\n const { beautifiedPath, mapPath } = getCachePaths(absolutePath, hash);\n \n // Check temp cache\n if (await isCacheValid(beautifiedPath, mapPath)) {\n // Temp cache hit - read from cache\n const [code, mapContent] = await Promise.all([\n fs.readFile(beautifiedPath, 'utf-8'),\n fs.readFile(mapPath, 'utf-8')\n ]);\n \n const result: BeautifyResult = {\n code,\n rawMap: JSON.parse(mapContent) as SourceMap\n };\n \n // If saveLocal is true, also save to local directory\n if (saveLocal) {\n await saveToLocal(result, localPaths, mapContent);\n }\n \n return result;\n }\n \n // Cache miss - beautify with Esbuild\n let esbuildResult: esbuild.BuildResult;\n try {\n esbuildResult = await esbuild.build({\n entryPoints: [absolutePath],\n bundle: false,\n write: false,\n format: 'esm',\n sourcemap: 'external',\n sourcesContent: false,\n outfile: 'out.js',\n // Beautify settings\n minify: false,\n keepNames: true,\n treeShaking: false,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Esbuild processing failed: ${message}`);\n }\n \n // Extract code and source map from result\n const codeFile = esbuildResult.outputFiles?.find(f => f.path.endsWith('.js'));\n const mapFile = esbuildResult.outputFiles?.find(f => f.path.endsWith('.map'));\n \n if (!codeFile || !mapFile) {\n throw new Error('Esbuild processing failed: Missing output files');\n }\n \n const code = codeFile.text;\n const rawMap = JSON.parse(mapFile.text) as SourceMap;\n const mapText = mapFile.text;\n \n // Write to temp cache\n await Promise.all([\n fs.writeFile(beautifiedPath, code, 'utf-8'),\n fs.writeFile(mapPath, mapText, 'utf-8')\n ]);\n \n const result: BeautifyResult = { code, rawMap };\n \n // If saveLocal is true, also save to local directory\n if (saveLocal) {\n await saveToLocal(result, localPaths, mapText);\n }\n \n return result;\n}\n\n/**\n * Save beautified code and source map to local directory\n * Handles errors gracefully by setting localSaveError instead of throwing\n */\nasync function saveToLocal(\n result: BeautifyResult,\n localPaths: LocalPaths,\n mapText: string\n): Promise<void> {\n try {\n await Promise.all([\n fs.writeFile(localPaths.beautifiedPath, result.code, 'utf-8'),\n fs.writeFile(localPaths.mapPath, mapText, 'utf-8')\n ]);\n result.localPath = localPaths.beautifiedPath;\n result.localMapPath = localPaths.mapPath;\n } catch (err) {\n // Handle specific error types\n const error = err as NodeJS.ErrnoException;\n if (error.code === 'EACCES' || error.code === 'EPERM') {\n result.localSaveError = `Permission denied: Cannot write to ${path.dirname(localPaths.beautifiedPath)}`;\n } else if (error.code === 'ENOSPC') {\n result.localSaveError = `Insufficient disk space: Cannot write to ${path.dirname(localPaths.beautifiedPath)}`;\n } else {\n result.localSaveError = `Failed to save locally: ${error.message || String(err)}`;\n }\n // Don't throw - the temp cache result is still valid\n }\n}\n", "import { parse } from 'meriyah';\nimport { walk } from 'estree-walker';\nimport MagicString from 'magic-string';\nimport type { Node } from 'estree';\n\n/**\n * Count newlines in a string\n */\nfunction countNewlines(str: string): number {\n let count = 0;\n for (const char of str) {\n if (char === '\\n') count++;\n }\n return count;\n}\n\n/**\n * Create truncated string with preserved newlines\n * Format: \"start ...[TRUNCATED {length} CHARS]... \\n\\n\\nend\"\n */\nfunction createTruncatedString(original: string, previewLength: number): string {\n const newlineCount = countNewlines(original);\n const start = original.slice(0, previewLength);\n const end = original.slice(-previewLength);\n \n // Build the truncation marker with preserved newlines\n const marker = `...[TRUNCATED ${original.length} CHARS]...`;\n \n // Create newlines to preserve line count\n // We need to account for newlines already in start and end portions\n const startNewlines = countNewlines(start);\n const endNewlines = countNewlines(end);\n const preservedNewlines = Math.max(0, newlineCount - startNewlines - endNewlines);\n const newlineStr = '\\n'.repeat(preservedNewlines);\n \n return `${start}${marker}${newlineStr}${end}`;\n}\n\n/**\n * Truncate long strings in JavaScript code while preserving line numbers\n * @param sourceCode - Source code to process\n * @param limit - Character limit for strings (default 200)\n * @param previewLength - Length of start/end preview portions (default 50)\n * @returns Truncated code with preserved line count\n */\nexport function truncateCodeHighPerf(sourceCode: string, limit: number = 200, previewLength: number = 50): string {\n // Try to parse the AST\n let ast: ReturnType<typeof parse>;\n try {\n ast = parse(sourceCode, {\n module: true,\n next: true,\n ranges: true,\n loc: true,\n raw: true,\n });\n } catch {\n // AST parsing failed - return original code unchanged (Requirement 2.4)\n return sourceCode;\n }\n\n const magicString = new MagicString(sourceCode);\n \n // Walk the AST and find string literals to truncate\n walk(ast as unknown as Node, {\n enter(node: Node) {\n // Handle regular string literals\n if (node.type === 'Literal' && typeof (node as any).value === 'string') {\n const literal = node as any;\n const value = literal.value as string;\n \n if (value.length > limit && literal.start !== undefined && literal.end !== undefined) {\n const truncated = createTruncatedString(value, previewLength);\n // Wrap in quotes matching the original\n const originalText = sourceCode.slice(literal.start, literal.end);\n const quote = originalText[0]; // Get the quote character used\n magicString.overwrite(literal.start, literal.end, `${quote}${truncated}${quote}`);\n }\n }\n \n // Handle template literals\n if (node.type === 'TemplateLiteral') {\n const template = node as any;\n \n // Process each quasi (template element)\n for (const quasi of template.quasis) {\n const value = quasi.value.raw as string;\n \n if (value.length > limit && quasi.start !== undefined && quasi.end !== undefined) {\n const truncated = createTruncatedString(value, previewLength);\n // Template literal quasis don't have surrounding quotes\n magicString.overwrite(quasi.start, quasi.end, truncated);\n }\n }\n }\n }\n });\n\n return magicString.toString();\n}\n\n/**\n * Truncate lines that exceed the maximum character limit\n * @param code - Source code to process\n * @param maxLineChars - Maximum characters per line (default 500)\n * @param previewRatio - Ratio of line to show at start/end (default 0.2)\n * @returns Code with truncated long lines\n */\nexport function truncateLongLines(\n code: string,\n maxLineChars: number = 500,\n previewRatio: number = 0.2\n): string {\n if (!code) {\n return code;\n }\n\n const lines = code.split('\\n');\n const previewLength = Math.floor(maxLineChars * previewRatio);\n\n const processedLines = lines.map((line) => {\n if (line.length <= maxLineChars) {\n return line;\n }\n\n const start = line.slice(0, previewLength);\n const end = line.slice(-previewLength);\n const truncatedChars = line.length - previewLength * 2;\n const marker = `...[LINE TRUNCATED ${truncatedChars} CHARS]...`;\n\n return `${start}${marker}${end}`;\n });\n\n return processedLines.join('\\n');\n}\n", "import { z } from 'zod';\nimport { defineTool } from './ToolDefinition.js';\nimport { applyCustomTransform as runTransform } from '../transformer.js';\n\n/**\n * Schema for apply_custom_transform tool input validation\n */\nexport const ApplyCustomTransformInputSchema = z.object({\n target_file: z.string().describe('Path to the JavaScript file to transform'),\n script_path: z.string().describe('Path to a JS file exporting a Babel Plugin function'),\n output_suffix: z.string().default('_deob').describe('Suffix for output file name'),\n});\n\n/**\n * apply_custom_transform tool definition\n * Apply a custom Babel transformation to deobfuscate JavaScript code.\n */\nexport const applyCustomTransform = defineTool({\n name: 'apply_custom_transform',\n description:\n 'Apply a custom Babel transformation to deobfuscate JavaScript code. ' +\n 'Takes a target JS file and a Babel plugin script, runs the transformation, ' +\n 'and outputs the deobfuscated code with a cascaded source map that traces back to the original minified file. ' +\n 'The plugin script should export a function that returns a Babel visitor object.',\n schema: {\n target_file: z.string().describe('Path to the JavaScript file to transform'),\n script_path: z.string().describe('Path to a JS file exporting a Babel Plugin function'),\n output_suffix: z.string().default('_deob').describe('Suffix for output file name'),\n },\n handler: async (params) => {\n const { target_file, script_path, output_suffix } = params;\n\n // Call the transform function\n const result = await runTransform(target_file, {\n scriptPath: script_path,\n outputSuffix: output_suffix,\n });\n\n // Return success message with created file paths\n const successMessage = [\n 'Transform completed successfully!',\n '',\n `Output file: ${result.outputPath}`,\n `Source map: ${result.mapPath}`,\n ].join('\\n');\n\n return successMessage;\n },\n});\n", "import * as path from 'path';\nimport * as fs from 'fs/promises';\nimport { transformSync, type BabelFileResult, type PluginItem } from '@babel/core';\nimport { ensureBeautified, type SourceMap } from './beautifier.js';\n\n/**\n * Transform options interface\n */\nexport interface TransformOptions {\n /** Path to the user's Babel plugin script */\n scriptPath: string;\n /** Output file suffix (default \"_deob\") */\n outputSuffix?: string;\n}\n\n/**\n * Transform result interface\n */\nexport interface TransformResult {\n /** Transformed code */\n code: string;\n /** Cascaded Source Map */\n map: SourceMap;\n /** Output file path */\n outputPath: string;\n /** Source Map file path */\n mapPath: string;\n}\n\n/**\n * Output paths interface\n */\nexport interface OutputPaths {\n /** Output JS file path */\n outputPath: string;\n /** Source Map file path */\n mapPath: string;\n}\n\n/**\n * Clean basename by removing .beautified and _deob* suffixes\n * \n * Examples:\n * - main.js -> main\n * - main.beautified.js -> main\n * - main_deob.js -> main\n * - main.beautified_deob.js -> main\n * - main_deob_v2.js -> main\n * \n * @param filename - Original filename (with or without path)\n * @returns Cleaned basename without extension\n */\nexport function cleanBasename(filename: string): string {\n // Get just the filename without directory\n const base = path.basename(filename);\n \n // Remove .js extension\n let name = base.endsWith('.js') ? base.slice(0, -3) : base;\n \n // Remove _deob* suffix first (e.g., _deob, _deob_v2, _deob123)\n // This handles cases like main.beautified_deob.js\n name = name.replace(/_deob[^/]*$/, '');\n \n // Remove .beautified suffix if present\n if (name.endsWith('.beautified')) {\n name = name.slice(0, -'.beautified'.length);\n }\n \n return name;\n}\n\n/**\n * Calculate output paths for transformed file\n * \n * @param targetFile - Path to the target file\n * @param outputSuffix - Suffix for output file (default \"_deob\")\n * @returns Output paths for JS and map files\n */\nexport function getOutputPaths(targetFile: string, outputSuffix: string = '_deob'): OutputPaths {\n const absolutePath = path.resolve(targetFile);\n const dir = path.dirname(absolutePath);\n const basename = cleanBasename(absolutePath);\n \n const outputPath = path.join(dir, `${basename}${outputSuffix}.js`);\n const mapPath = `${outputPath}.map`;\n \n return { outputPath, mapPath };\n}\n\n/**\n * Babel plugin function type\n * A Babel plugin is a function that receives babel API and returns a visitor object\n */\nexport type BabelPluginFunction = (babel: { types: typeof import('@babel/types') }) => {\n visitor: Record<string, unknown>;\n};\n\n/**\n * Load a Babel plugin script from the given path\n * \n * Features:\n * - Resolves to absolute path\n * - Clears require cache for hot-reloading\n * - Validates plugin format\n * \n * @param scriptPath - Path to the Babel plugin script\n * @returns The loaded Babel plugin function\n * @throws Error if script not found or invalid format\n */\nexport async function loadBabelPlugin(scriptPath: string): Promise<BabelPluginFunction> {\n // Resolve to absolute path\n const absolutePath = path.resolve(scriptPath);\n \n // Check if file exists\n try {\n await fs.access(absolutePath);\n } catch {\n throw new Error(`Script not found: ${absolutePath}`);\n }\n \n // Convert to file URL for ESM import\n const fileUrl = `file://${absolutePath}?t=${Date.now()}`;\n \n // Dynamic import with cache busting for hot-reload\n let module: unknown;\n try {\n module = await import(fileUrl);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Failed to load script: ${message}`);\n }\n \n // Extract the plugin function\n const plugin = (module as { default?: unknown }).default ?? module;\n \n // Validate plugin format - must be a function\n if (typeof plugin !== 'function') {\n throw new Error(\n `Invalid Babel plugin: Script must export a function that returns a visitor object. ` +\n `Got ${typeof plugin} instead.`\n );\n }\n \n return plugin as BabelPluginFunction;\n}\n\n\n/**\n * Babel transform result interface\n */\ninterface BabelTransformResult {\n /** Transformed code */\n code: string;\n /** Generated source map (cascaded) */\n map: SourceMap;\n}\n\n/**\n * Run Babel transform with source map cascade\n * \n * Configuration:\n * - inputSourceMap: Enables cascade from beautified -> original\n * - sourceMaps: true to generate output source map\n * - retainLines: false for best readability\n * - compact: false for readable output\n * - minified: false for readable output\n * \n * @param code - Input code (beautified)\n * @param inputSourceMap - Source map from beautifier (beautified -> original)\n * @param plugin - Babel plugin function\n * @param filename - Original filename for source map\n * @returns Transformed code and cascaded source map\n */\nexport function runBabelTransform(\n code: string,\n inputSourceMap: SourceMap,\n plugin: BabelPluginFunction,\n filename: string\n): BabelTransformResult {\n let result: BabelFileResult | null;\n \n try {\n result = transformSync(code, {\n filename,\n plugins: [plugin as PluginItem],\n // Source map configuration for cascade\n // @ts-expect-error - SourceMap is compatible with InputSourceMap at runtime\n inputSourceMap: inputSourceMap,\n sourceMaps: true,\n // Readability settings\n retainLines: false,\n compact: false,\n minified: false,\n // Preserve code structure\n parserOpts: {\n sourceType: 'unambiguous',\n },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Babel Error: ${message}`);\n }\n \n if (!result || !result.code) {\n throw new Error('Babel Error: Transform produced no output');\n }\n \n if (!result.map) {\n throw new Error('Babel Error: Transform produced no source map');\n }\n \n return {\n code: result.code,\n map: result.map as unknown as SourceMap,\n };\n}\n\n\n/**\n * Apply custom Babel transform to a JavaScript file\n * \n * Process:\n * 1. Load and validate the Babel plugin script\n * 2. Get beautified code and source map from target file\n * 3. Run Babel transform with source map cascade\n * 4. Write output file and source map\n * 5. Append sourceMappingURL comment\n * \n * @param targetFile - Path to the JavaScript file to transform\n * @param options - Transform options (scriptPath, outputSuffix)\n * @returns Transform result with output paths\n */\nexport async function applyCustomTransform(\n targetFile: string,\n options: TransformOptions\n): Promise<TransformResult> {\n const { scriptPath, outputSuffix = '_deob' } = options;\n \n // Resolve target file path\n const absoluteTargetPath = path.resolve(targetFile);\n \n // Check if target file exists\n try {\n await fs.access(absoluteTargetPath);\n } catch {\n throw new Error(`File not found: ${targetFile}`);\n }\n \n // Load the Babel plugin script\n const plugin = await loadBabelPlugin(scriptPath);\n \n // Get beautified code and source map\n const beautifyResult = await ensureBeautified(absoluteTargetPath);\n const { code: beautifiedCode, rawMap: inputSourceMap } = beautifyResult;\n \n // Run Babel transform with source map cascade\n const transformResult = runBabelTransform(\n beautifiedCode,\n inputSourceMap,\n plugin,\n absoluteTargetPath\n );\n \n // Calculate output paths\n const { outputPath, mapPath } = getOutputPaths(absoluteTargetPath, outputSuffix);\n \n // Prepare output code with sourceMappingURL comment\n const mapFileName = path.basename(mapPath);\n const outputCode = `${transformResult.code}\\n//# sourceMappingURL=${mapFileName}`;\n \n // Prepare source map with correct file reference\n const outputMap: SourceMap = {\n ...transformResult.map,\n file: path.basename(outputPath),\n };\n \n // Write output files\n try {\n await Promise.all([\n fs.writeFile(outputPath, outputCode, 'utf-8'),\n fs.writeFile(mapPath, JSON.stringify(outputMap, null, 2), 'utf-8'),\n ]);\n } catch (err) {\n const error = err as NodeJS.ErrnoException;\n if (error.code === 'EACCES' || error.code === 'EPERM') {\n throw new Error(`Permission denied: Cannot write to ${path.dirname(outputPath)}`);\n }\n throw new Error(`Failed to write output files: ${error.message || String(err)}`);\n }\n \n return {\n code: outputCode,\n map: outputMap,\n outputPath,\n mapPath,\n };\n}\n", "import { z } from 'zod';\nimport { defineTool } from './ToolDefinition.js';\nimport { ensureBeautified } from '../beautifier.js';\nimport { truncateCodeHighPerf, truncateLongLines } from '../truncator.js';\nimport { searchInCode, formatSearchResult } from '../searcher.js';\n\n/**\n * Schema for search_code_smart tool input validation\n */\nexport const SearchCodeSmartInputSchema = z.object({\n file_path: z.string().describe('Path to the JavaScript file'),\n query: z.string().describe('Regex pattern or text to search'),\n context_lines: z.number().int().min(0).default(2).describe('Number of context lines'),\n case_sensitive: z.boolean().default(false).describe('Case sensitive search'),\n char_limit: z.number().int().min(50).default(300).describe('Character limit for string truncation'),\n max_line_chars: z.number().int().min(80).default(500).describe('Maximum characters per line'),\n});\n\n/**\n * search_code_smart tool definition\n * Search for text or regex patterns in beautified JavaScript code.\n */\nexport const searchCodeSmart = defineTool({\n name: 'search_code_smart',\n description:\n 'Search for text or regex patterns in beautified JavaScript code. ' +\n 'Returns matching lines with context and original source coordinates for setting breakpoints. ' +\n 'Useful for finding code patterns in minified/obfuscated files.',\n schema: {\n file_path: z.string().describe('Path to the JavaScript file'),\n query: z.string().describe('Regex pattern or text to search'),\n context_lines: z.number().int().min(0).default(2).describe('Number of context lines'),\n case_sensitive: z.boolean().default(false).describe('Case sensitive search'),\n char_limit: z.number().int().min(50).default(300).describe('Character limit for string truncation'),\n max_line_chars: z.number().int().min(80).default(500).describe('Maximum characters per line'),\n },\n handler: async (params) => {\n const { file_path, query, context_lines, case_sensitive, char_limit, max_line_chars } = params;\n\n // Beautify the file and get source map\n const beautifyResult = await ensureBeautified(file_path);\n const { code, rawMap } = beautifyResult;\n\n // Truncate long strings before searching\n const truncatedCode = truncateCodeHighPerf(code, char_limit);\n\n // Execute search\n const searchResult = searchInCode(truncatedCode, rawMap, {\n query,\n contextLines: context_lines,\n caseSensitive: case_sensitive,\n maxMatches: 50,\n });\n\n // Format the result\n let output = formatSearchResult(file_path, query, case_sensitive, searchResult, 50);\n\n // Truncate long lines in output\n output = truncateLongLines(output, max_line_chars);\n\n return output;\n },\n});\n", "import { SourceMapConsumer } from 'source-map-js';\nimport type { SourceMap } from './beautifier.js';\n\n/**\n * Original position from source map\n */\nexport interface OriginalPosition {\n line: number | null;\n column: number | null;\n}\n\n/**\n * Context line with position info\n */\nexport interface ContextLine {\n lineNumber: number;\n content: string;\n originalPosition: OriginalPosition;\n}\n\n/**\n * Search match result\n */\nexport interface SearchMatch {\n /** Match line number (1-based, in beautified code) */\n lineNumber: number;\n /** Match line content */\n lineContent: string;\n /** Original file coordinates */\n originalPosition: OriginalPosition;\n /** Context lines before match */\n contextBefore: ContextLine[];\n /** Context lines after match */\n contextAfter: ContextLine[];\n}\n\n/**\n * Search options\n */\nexport interface SearchOptions {\n /** Regex pattern or text to search */\n query: string;\n /** Number of context lines (default 2) */\n contextLines?: number;\n /** Case sensitive search (default false) */\n caseSensitive?: boolean;\n /** Maximum matches to return (default 50) */\n maxMatches?: number;\n}\n\n/**\n * Search result\n */\nexport interface SearchResult {\n /** Matched results */\n matches: SearchMatch[];\n /** Total matches found (before truncation) */\n totalMatches: number;\n /** Whether results were truncated */\n truncated: boolean;\n}\n\n\n/**\n * Create regex from query string with error handling\n * @param query - Regex pattern or text\n * @param caseSensitive - Whether to be case sensitive\n * @returns Created RegExp\n * @throws Error if regex is invalid\n */\nexport function createRegex(query: string, caseSensitive: boolean = false): RegExp {\n try {\n const flags = caseSensitive ? 'g' : 'gi';\n return new RegExp(query, flags);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Invalid regex: ${message}`);\n }\n}\n\n/**\n * Get original position for a line using source map consumer\n */\nfunction getOriginalPosition(\n consumer: SourceMapConsumer,\n lineNumber: number\n): OriginalPosition {\n const pos = consumer.originalPositionFor({\n line: lineNumber,\n column: 0,\n });\n return {\n line: pos.line,\n column: pos.column,\n };\n}\n\n/**\n * Create a context line object\n */\nfunction createContextLine(\n lineNumber: number,\n content: string,\n consumer: SourceMapConsumer\n): ContextLine {\n return {\n lineNumber,\n content,\n originalPosition: getOriginalPosition(consumer, lineNumber),\n };\n}\n\n/**\n * Search for pattern in code and return matches with context\n * @param code - Beautified code to search in\n * @param rawMap - Source map for coordinate mapping\n * @param options - Search options\n * @returns Search result with matches\n */\nexport function searchInCode(\n code: string,\n rawMap: SourceMap,\n options: SearchOptions\n): SearchResult {\n const {\n query,\n contextLines = 2,\n caseSensitive = false,\n maxMatches = 50,\n } = options;\n\n // Create regex from query\n const regex = createRegex(query, caseSensitive);\n\n // Split code into lines\n const lines = code.split('\\n');\n const totalLines = lines.length;\n\n // Create source map consumer\n const consumer = new SourceMapConsumer({\n ...rawMap,\n version: String(rawMap.version),\n });\n\n // Find all matching line numbers\n const matchingLineNumbers: number[] = [];\n for (let i = 0; i < totalLines; i++) {\n const line = lines[i];\n // Reset regex lastIndex for each line\n regex.lastIndex = 0;\n if (regex.test(line)) {\n matchingLineNumbers.push(i + 1); // 1-based line number\n }\n }\n\n const totalMatches = matchingLineNumbers.length;\n const truncated = totalMatches > maxMatches;\n\n // Limit matches\n const limitedLineNumbers = matchingLineNumbers.slice(0, maxMatches);\n\n // Build match results\n const matches: SearchMatch[] = limitedLineNumbers.map((lineNumber) => {\n const lineIndex = lineNumber - 1;\n const lineContent = lines[lineIndex];\n\n // Collect context before\n const contextBefore: ContextLine[] = [];\n for (let i = Math.max(0, lineIndex - contextLines); i < lineIndex; i++) {\n contextBefore.push(createContextLine(i + 1, lines[i], consumer));\n }\n\n // Collect context after\n const contextAfter: ContextLine[] = [];\n for (let i = lineIndex + 1; i <= Math.min(totalLines - 1, lineIndex + contextLines); i++) {\n contextAfter.push(createContextLine(i + 1, lines[i], consumer));\n }\n\n return {\n lineNumber,\n lineContent,\n originalPosition: getOriginalPosition(consumer, lineNumber),\n contextBefore,\n contextAfter,\n };\n });\n\n return {\n matches,\n totalMatches,\n truncated,\n };\n}\n\n/**\n * Format source position as \"L{line}:{column}\" or placeholder\n */\nexport function formatSourcePosition(line: number | null, column: number | null): string {\n if (line !== null && column !== null) {\n return `L${line}:${column}`;\n }\n return '';\n}\n\n/**\n * Format search result for output\n * @param filePath - Path to the file\n * @param query - Search query\n * @param caseSensitive - Whether search was case sensitive\n * @param result - Search result\n * @param maxMatches - Maximum matches limit\n * @returns Formatted output string\n */\nexport function formatSearchResult(\n filePath: string,\n query: string,\n caseSensitive: boolean,\n result: SearchResult,\n maxMatches: number = 50\n): string {\n const { matches, totalMatches, truncated } = result;\n\n const outputParts: string[] = [];\n\n // Header\n const caseInfo = caseSensitive ? 'case-sensitive' : 'case-insensitive';\n outputParts.push(`FILE: ${filePath}`);\n outputParts.push(`QUERY: \"${query}\" (${caseInfo})`);\n\n if (totalMatches === 0) {\n outputParts.push('MATCHES: No matches found');\n return outputParts.join('\\n');\n }\n\n const matchInfo = truncated\n ? `MATCHES: ${totalMatches} found (showing first ${maxMatches})`\n : `MATCHES: ${totalMatches} found`;\n outputParts.push(matchInfo);\n outputParts.push('-'.repeat(85));\n\n // Format each match\n for (const match of matches) {\n outputParts.push(`--- Match at Line ${match.lineNumber} ---`);\n\n // Calculate max line number width for alignment\n const allLineNumbers = [\n ...match.contextBefore.map((c) => c.lineNumber),\n match.lineNumber,\n ...match.contextAfter.map((c) => c.lineNumber),\n ];\n const maxLineNumWidth = Math.max(...allLineNumbers.map((n) => String(n).length));\n\n // Format context before\n for (const ctx of match.contextBefore) {\n const lineNumStr = String(ctx.lineNumber).padStart(maxLineNumWidth, ' ');\n const srcPos = formatSourcePosition(ctx.originalPosition.line, ctx.originalPosition.column);\n const srcPosPadded = srcPos ? `Src ${srcPos}` : '';\n outputParts.push(` ${lineNumStr} | [${srcPosPadded.padEnd(14, ' ')}] | ${ctx.content}`);\n }\n\n // Format match line with >> prefix\n const matchLineNumStr = String(match.lineNumber).padStart(maxLineNumWidth, ' ');\n const matchSrcPos = formatSourcePosition(match.originalPosition.line, match.originalPosition.column);\n const matchSrcPosPadded = matchSrcPos ? `Src ${matchSrcPos}` : '';\n outputParts.push(`>> ${matchLineNumStr} | [${matchSrcPosPadded.padEnd(14, ' ')}] | ${match.lineContent}`);\n\n // Format context after\n for (const ctx of match.contextAfter) {\n const lineNumStr = String(ctx.lineNumber).padStart(maxLineNumWidth, ' ');\n const srcPos = formatSourcePosition(ctx.originalPosition.line, ctx.originalPosition.column);\n const srcPosPadded = srcPos ? `Src ${srcPos}` : '';\n outputParts.push(` ${lineNumStr} | [${srcPosPadded.padEnd(14, ' ')}] | ${ctx.content}`);\n }\n\n outputParts.push(''); // Empty line between matches\n }\n\n // Add truncation message if needed\n if (truncated) {\n outputParts.push(`... (${totalMatches - maxMatches} more matches not shown)`);\n }\n\n return outputParts.join('\\n');\n}\n", "import { z } from 'zod';\nimport { defineTool } from './ToolDefinition.js';\nimport { ensureBeautified } from '../beautifier.js';\nimport { truncateCodeHighPerf, truncateLongLines } from '../truncator.js';\nimport { analyzeBindings, formatAnalysisResult } from '../analyzer.js';\n\n/**\n * Schema for find_usage_smart tool input validation\n */\nexport const FindUsageSmartInputSchema = z.object({\n file_path: z.string().describe('Path to the JavaScript file'),\n identifier: z.string().describe('Variable or function name to find'),\n line: z.number().int().positive().optional().describe(\n 'The line number where you see this variable. HIGHLY RECOMMENDED for precision in obfuscated code.'\n ),\n char_limit: z.number().int().min(50).default(300).describe('Character limit for string truncation'),\n max_line_chars: z.number().int().min(80).default(500).describe('Maximum characters per line'),\n});\n\n/**\n * find_usage_smart tool definition\n * Find all definitions and references of a variable/function using AST scope analysis.\n */\nexport const findUsageSmart = defineTool({\n name: 'find_usage_smart',\n description:\n 'Find all definitions and references of a variable/function using AST scope analysis. ' +\n 'Returns binding information grouped by scope with original source coordinates for setting breakpoints. ' +\n 'Useful for tracing variable usage in minified/obfuscated code with variable name reuse.',\n schema: {\n file_path: z.string().describe('Path to the JavaScript file'),\n identifier: z.string().describe('Variable or function name to find'),\n line: z.number().int().positive().optional().describe(\n 'The line number where you see this variable. HIGHLY RECOMMENDED for precision in obfuscated code.'\n ),\n char_limit: z.number().int().min(50).default(300).describe('Character limit for string truncation'),\n max_line_chars: z.number().int().min(80).default(500).describe('Maximum characters per line'),\n },\n handler: async (params) => {\n const { file_path, identifier, line, char_limit, max_line_chars } = params;\n\n // Beautify the file and get source map\n const beautifyResult = await ensureBeautified(file_path);\n const { code, rawMap } = beautifyResult;\n\n // Analyze bindings using full code (not truncated) for accurate AST analysis\n // When line is specified, increase maxReferences to 15 for targeted searches\n const analysisResult = await analyzeBindings(code, rawMap, identifier, {\n maxReferences: line ? 15 : 10,\n targetLine: line,\n });\n\n // Truncate the code for display purposes\n const truncatedCode = truncateCodeHighPerf(code, char_limit);\n const truncatedLines = truncatedCode.split('\\n');\n\n // Update line content in analysis result with truncated versions\n for (const binding of analysisResult.bindings) {\n // Update definition line content\n const defLineIdx = binding.definition.line - 1;\n if (defLineIdx >= 0 && defLineIdx < truncatedLines.length) {\n binding.definition.lineContent = truncatedLines[defLineIdx];\n }\n\n // Update reference line contents\n for (const ref of binding.references) {\n const refLineIdx = ref.line - 1;\n if (refLineIdx >= 0 && refLineIdx < truncatedLines.length) {\n ref.lineContent = truncatedLines[refLineIdx];\n }\n }\n }\n\n // Format the result\n let output = formatAnalysisResult(file_path, analysisResult, line ? 15 : 10);\n\n // Truncate long lines in output\n output = truncateLongLines(output, max_line_chars);\n\n return output;\n },\n});\n", "import { SourceMapConsumer } from 'source-map-js';\nimport { parse, ParserOptions } from '@babel/parser';\nimport type { NodePath } from '@babel/traverse';\nimport type { Identifier } from '@babel/types';\nimport type { SourceMap } from './beautifier.js';\n\n// Dynamic import for babel traverse to handle ESM/CJS interop\ntype TraverseFn = (\n parent: Parameters<typeof import('@babel/traverse').default>[0],\n opts?: Parameters<typeof import('@babel/traverse').default>[1],\n scope?: Parameters<typeof import('@babel/traverse').default>[2],\n state?: Parameters<typeof import('@babel/traverse').default>[3],\n parentPath?: Parameters<typeof import('@babel/traverse').default>[4]\n) => void;\n\nlet traverse: TraverseFn | null = null;\n\nasync function getTraverse(): Promise<TraverseFn> {\n if (!traverse) {\n const mod = await import('@babel/traverse');\n // Handle both ESM default export and CJS module.exports\n traverse = (mod.default?.default ?? mod.default) as TraverseFn;\n }\n return traverse;\n}\n\n/**\n * Original position from source map\n */\nexport interface OriginalPosition {\n line: number | null;\n column: number | null;\n}\n\n/**\n * Location information for a definition or reference\n */\nexport interface LocationInfo {\n /** Line number in beautified code (1-based) */\n line: number;\n /** Column number in beautified code (0-based) */\n column: number;\n /** Original file coordinates from source map */\n originalPosition: OriginalPosition;\n /** Content of the line containing this location */\n lineContent: string;\n}\n\n/**\n * Binding information for a variable/function\n */\nexport interface BindingInfo {\n /** Unique scope identifier */\n scopeUid: number;\n /** Binding kind (var, let, const, param, etc.) */\n kind: string;\n /** Definition location */\n definition: LocationInfo;\n /** All reference locations */\n references: LocationInfo[];\n /** Total reference count (before limiting) */\n totalReferences: number;\n /** The location that matched the target line (if targeted search) */\n hitLocation?: LocationInfo;\n}\n\n/**\n * Analysis result containing all bindings for an identifier\n */\nexport interface AnalysisResult {\n /** All bindings found for the identifier */\n bindings: BindingInfo[];\n /** The identifier that was searched */\n identifier: string;\n /** Whether this was a targeted (line-specific) search */\n isTargeted: boolean;\n /** The target line if specified */\n targetLine?: number;\n}\n\n\n/**\n * Default parser options for Babel\n */\nconst DEFAULT_PARSER_OPTIONS: ParserOptions = {\n sourceType: 'unambiguous',\n plugins: [\n 'jsx',\n 'typescript',\n 'classProperties',\n 'classPrivateProperties',\n 'classPrivateMethods',\n 'dynamicImport',\n 'optionalChaining',\n 'nullishCoalescingOperator',\n 'objectRestSpread',\n ],\n errorRecovery: true,\n};\n\n/**\n * Parse JavaScript/TypeScript code into an AST\n * @param code - Source code to parse\n * @returns Parsed AST\n * @throws Error if parsing fails\n */\nexport function parseCode(code: string) {\n try {\n return parse(code, DEFAULT_PARSER_OPTIONS);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Parse error: ${message}`);\n }\n}\n\n\n/**\n * Get original position for a location using source map consumer\n */\nfunction getOriginalPosition(\n consumer: SourceMapConsumer,\n line: number,\n column: number\n): OriginalPosition {\n const pos = consumer.originalPositionFor({ line, column });\n return {\n line: pos.line,\n column: pos.column,\n };\n}\n\n/**\n * Get line content from code by line number (1-based)\n */\nfunction getLineContent(lines: string[], lineNumber: number): string {\n if (lineNumber < 1 || lineNumber > lines.length) {\n return '';\n }\n return lines[lineNumber - 1];\n}\n\n/**\n * Create a LocationInfo object\n */\nfunction createLocationInfo(\n line: number,\n column: number,\n lines: string[],\n consumer: SourceMapConsumer\n): LocationInfo {\n return {\n line,\n column,\n originalPosition: getOriginalPosition(consumer, line, column),\n lineContent: getLineContent(lines, line),\n };\n}\n\n/**\n * Options for binding analysis\n */\nexport interface AnalyzeOptions {\n /** Maximum references to return per binding (default 10) */\n maxReferences?: number;\n /** Target line number for precise binding identification (1-based) */\n targetLine?: number;\n}\n\n/**\n * Analyze bindings for a specific identifier in the code\n * Uses Babel traverse to find all bindings and their references\n * \n * @param code - Beautified code to analyze\n * @param rawMap - Source map for coordinate mapping\n * @param identifier - Variable/function name to find\n * @param options - Analysis options\n * @returns Analysis result with all bindings\n */\nexport async function analyzeBindings(\n code: string,\n rawMap: SourceMap,\n identifier: string,\n options?: AnalyzeOptions\n): Promise<AnalysisResult> {\n const targetLine = options?.targetLine;\n const isTargeted = targetLine !== undefined;\n // Use 15 max references for targeted searches, 10 for regular searches\n const maxReferences = options?.maxReferences ?? (isTargeted ? 15 : 10);\n \n // Parse the code\n const ast = parseCode(code);\n \n // Split code into lines for content extraction\n const lines = code.split('\\n');\n \n // Create source map consumer\n const consumer = new SourceMapConsumer({\n ...rawMap,\n version: String(rawMap.version),\n });\n \n // Collect all bindings for the identifier\n const bindings: BindingInfo[] = [];\n const processedScopes = new Set<number>();\n \n // Get traverse function\n const traverse = await getTraverse();\n \n try {\n traverse(ast, {\n Identifier(path: NodePath<Identifier>) {\n // Only process if this is the identifier we're looking for\n if (path.node.name !== identifier) {\n return;\n }\n \n // For targeted search, check if this identifier is at the target line\n if (isTargeted) {\n const nodeLoc = path.node.loc;\n if (!nodeLoc || nodeLoc.start.line !== targetLine) {\n return;\n }\n }\n \n // Get the binding for this identifier\n const binding = path.scope.getBinding(identifier);\n if (!binding) {\n return;\n }\n \n // Get scope UID to avoid processing same binding multiple times\n const scopeUid = binding.scope.uid;\n if (processedScopes.has(scopeUid)) {\n return;\n }\n processedScopes.add(scopeUid);\n \n // Get definition location\n const defNode = binding.identifier;\n const defLoc = defNode.loc;\n if (!defLoc) {\n return;\n }\n \n const definition = createLocationInfo(\n defLoc.start.line,\n defLoc.start.column,\n lines,\n consumer\n );\n \n // Get all reference locations\n const allReferences: LocationInfo[] = [];\n for (const refPath of binding.referencePaths) {\n const refLoc = refPath.node.loc;\n if (!refLoc) {\n continue;\n }\n \n allReferences.push(\n createLocationInfo(\n refLoc.start.line,\n refLoc.start.column,\n lines,\n consumer\n )\n );\n }\n \n // Store total count before limiting\n const totalReferences = allReferences.length;\n \n // Limit references\n const limitedReferences = allReferences.slice(0, maxReferences);\n \n // Create hit location for targeted search\n let hitLocation: LocationInfo | undefined;\n if (isTargeted) {\n const nodeLoc = path.node.loc!;\n hitLocation = createLocationInfo(\n nodeLoc.start.line,\n nodeLoc.start.column,\n lines,\n consumer\n );\n }\n \n bindings.push({\n scopeUid,\n kind: binding.kind,\n definition,\n references: limitedReferences,\n totalReferences,\n hitLocation,\n });\n \n // For targeted search, stop after finding the first matching binding\n if (isTargeted) {\n path.stop();\n }\n },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Analysis error: ${message}`);\n }\n \n return {\n bindings,\n identifier,\n isTargeted,\n targetLine,\n };\n}\n\n\n/**\n * Format source position as \"L{line}:{column}\" or placeholder\n */\nexport function formatSourcePosition(line: number | null, column: number | null): string {\n if (line !== null && column !== null) {\n return `L${line}:${column}`;\n }\n return '';\n}\n\n/**\n * Check if two locations match (same line and column)\n */\nfunction locationsMatch(loc1: LocationInfo, loc2: LocationInfo): boolean {\n return loc1.line === loc2.line && loc1.column === loc2.column;\n}\n\n/**\n * Format analysis result for output\n * @param filePath - Path to the file\n * @param result - Analysis result\n * @param maxReferences - Maximum references shown per binding\n * @returns Formatted output string\n */\nexport function formatAnalysisResult(\n filePath: string,\n result: AnalysisResult,\n maxReferences: number = 10\n): string {\n const { bindings, identifier, isTargeted, targetLine } = result;\n \n const outputParts: string[] = [];\n \n // Header\n outputParts.push(`FILE: ${filePath}`);\n outputParts.push(`IDENTIFIER: \"${identifier}\"`);\n \n // Handle no bindings found\n if (bindings.length === 0) {\n if (isTargeted && targetLine !== undefined) {\n // Descriptive message for targeted search with no results\n outputParts.push(`BINDINGS: No binding found for \"${identifier}\" at line ${targetLine}`);\n outputParts.push(`The variable may be global, externally defined, or not present at this line.`);\n } else {\n outputParts.push('BINDINGS: No definitions or references found');\n }\n return outputParts.join('\\n');\n }\n \n // Display \"Targeted Scope\" header when isTargeted is true\n if (isTargeted) {\n outputParts.push(`BINDINGS: 1 found (Targeted Scope at line ${targetLine})`);\n } else {\n const scopeInfo = bindings.length > 1 ? ' (in different scopes)' : '';\n outputParts.push(`BINDINGS: ${bindings.length} found${scopeInfo}`);\n }\n outputParts.push('-'.repeat(85));\n \n // Format each binding\n for (let i = 0; i < bindings.length; i++) {\n const binding = bindings[i];\n \n // Use \"Targeted Scope\" label for targeted searches\n if (isTargeted) {\n outputParts.push(`=== Targeted Scope (${binding.kind}) ===`);\n } else {\n outputParts.push(`=== Scope #${i + 1} (${binding.kind}) ===`);\n }\n \n // Format definition - check if definition is the hit location\n const defIsHit = isTargeted && binding.hitLocation && \n locationsMatch(binding.definition, binding.hitLocation);\n const defPrefix = defIsHit ? '\uD83D\uDCCD Definition (hit):' : '\uD83D\uDCCD Definition:';\n outputParts.push(defPrefix);\n \n const defSrcPos = formatSourcePosition(\n binding.definition.originalPosition.line,\n binding.definition.originalPosition.column\n );\n const defSrcPosPadded = defSrcPos ? `Src ${defSrcPos}` : '';\n const defMarker = defIsHit ? ' \u25C0\u2500\u2500 hit' : '';\n outputParts.push(\n ` ${binding.definition.line} | [${defSrcPosPadded.padEnd(14, ' ')}] | ${binding.definition.lineContent}${defMarker}`\n );\n \n // Format references\n const totalRefs = binding.totalReferences;\n \n if (totalRefs === 0) {\n outputParts.push('\uD83D\uDD0E References: None');\n } else {\n outputParts.push(`\uD83D\uDD0E References (${totalRefs}):`);\n \n for (const ref of binding.references) {\n // Check if this reference is the hit location\n const refIsHit = isTargeted && binding.hitLocation && \n locationsMatch(ref, binding.hitLocation);\n \n const refSrcPos = formatSourcePosition(\n ref.originalPosition.line,\n ref.originalPosition.column\n );\n const refSrcPosPadded = refSrcPos ? `Src ${refSrcPos}` : '';\n const refMarker = refIsHit ? ' \u25C0\u2500\u2500 hit' : '';\n outputParts.push(\n ` ${ref.line} | [${refSrcPosPadded.padEnd(14, ' ')}] | ${ref.lineContent}${refMarker}`\n );\n }\n \n // Add truncation message if references were limited\n if (totalRefs > maxReferences) {\n const remaining = totalRefs - maxReferences;\n outputParts.push(` ... (${remaining} more references not shown)`);\n }\n }\n \n outputParts.push(''); // Empty line between bindings\n }\n \n return outputParts.join('\\n');\n}\n", "/**\n * Tool aggregation module\n * Collects all tool definitions and exports them as a unified array.\n */\n\nimport { readCodeSmart } from './readCodeSmart.js';\nimport { applyCustomTransform, ApplyCustomTransformInputSchema } from './applyCustomTransform.js';\nimport { searchCodeSmart, SearchCodeSmartInputSchema } from './searchCodeSmart.js';\nimport { findUsageSmart, FindUsageSmartInputSchema } from './findUsageSmart.js';\n\n/**\n * Array of all available MCP tool definitions.\n * To add a new tool:\n * 1. Create a new tool module in src/tools/\n * 2. Import it here\n * 3. Add it to this array\n */\nexport const tools = [\n readCodeSmart,\n applyCustomTransform,\n searchCodeSmart,\n findUsageSmart,\n] as const;\n\n// Re-export ToolDefinition interface and defineTool helper\nexport { ToolDefinition, defineTool } from './ToolDefinition.js';\n\n// Re-export input schemas for testing\nexport { ApplyCustomTransformInputSchema, SearchCodeSmartInputSchema, FindUsageSmartInputSchema };\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["z", "code", "result", "z", "path", "fs", "basename", "z", "applyCustomTransform", "z", "SourceMapConsumer", "formatSourcePosition", "z", "z", "SourceMapConsumer", "parse", "getOriginalPosition", "traverse", "path", "formatSourcePosition", "z", "applyCustomTransform", "z"]
|
|
4
|
+
"sourcesContent": ["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { tools } from './tools/index.js';\n\n// Create MCP Server instance\nconst server = new McpServer({\n name: 'smart-fs',\n version: '1.0.0',\n});\n\n/**\n * Register a tool with the MCP server.\n * Converts ToolDefinition to MCP tool registration format.\n * \n * @param tool - The tool definition to register\n */\nfunction registerTool(tool: {\n name: string;\n description: string;\n schema: z.ZodRawShape;\n handler: (params: Record<string, unknown>) => Promise<string>;\n}): void {\n // Create Zod object schema from raw shape for validation\n const zodSchema = z.object(tool.schema);\n\n // Register the tool with MCP server using registerTool API\n server.registerTool(\n tool.name,\n {\n description: tool.description,\n inputSchema: tool.schema,\n },\n async (params, _extra) => {\n try {\n // Validate and parse input using the Zod schema\n const validatedParams = zodSchema.parse(params);\n const result = await tool.handler(validatedParams as Record<string, unknown>);\n\n return {\n content: [{ type: 'text' as const, text: result }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n };\n }\n }\n );\n}\n\n// Register all tools from the tools array\nfor (const tool of tools) {\n registerTool(tool as unknown as {\n name: string;\n description: string;\n schema: z.ZodRawShape;\n handler: (params: Record<string, unknown>) => Promise<string>;\n });\n}\n\n// Main entry point\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error('Smart FS MCP Server running on stdio');\n}\n\nmain().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n", "import { z } from 'zod';\nimport { SourceMapConsumer } from 'source-map-js';\nimport { defineTool } from './ToolDefinition.js';\nimport { ensureBeautified } from '../beautifier.js';\nimport { truncateCodeHighPerf, truncateLongLines } from '../truncator.js';\n\n/**\n * Format source position as \"L{line}:{column}\" or empty placeholder\n */\nfunction formatSourcePosition(line: number | null, column: number | null): string {\n if (line !== null && column !== null) {\n return `L${line}:${column}`;\n }\n return '';\n}\n\n/**\n * Format output header with file info\n */\nfunction formatHeader(filePath: string, startLine: number, endLine: number, totalLines: number): string {\n return [\n `${filePath} (${startLine}-${endLine}/${totalLines})`,\n `Src=original position for breakpoints`,\n ].join('\\n');\n}\n\n/**\n * Format a single code line with line number, source coordinates, and content\n */\nfunction formatCodeLine(lineNumber: number, sourcePos: string, code: string, maxLineNumWidth: number): string {\n const lineNumStr = String(lineNumber).padStart(maxLineNumWidth, ' ');\n const srcPos = sourcePos ? sourcePos.padEnd(10, ' ') : ' ';\n return `${lineNumStr} ${srcPos} ${code}`;\n}\n\n/**\n * Format pagination hint\n */\nfunction formatPaginationHint(nextStartLine: number): string {\n return `\\n... (Use next start_line=${nextStartLine} to read more)`;\n}\n\n/**\n * read_code_smart tool definition\n * Read and beautify minified/obfuscated JavaScript code with source map coordinates.\n */\nexport const readCodeSmart = defineTool({\n name: 'read_code_smart',\n description:\n 'Read and beautify minified/obfuscated JavaScript code with source map coordinates. ' +\n 'Returns formatted code with original file positions for setting breakpoints. ' +\n 'Optionally saves the beautified file locally alongside the original file.',\n schema: {\n file_path: z.string().describe('Path to the JavaScript file'),\n start_line: z.number().int().min(1).describe('Start line number (1-based)'),\n end_line: z.number().int().min(1).describe('End line number (1-based)'),\n char_limit: z.number().int().min(50).default(300).describe('Character limit for string truncation'),\n max_line_chars: z.number().int().min(80).default(500).describe('Maximum characters per line'),\n save_local: z.boolean().optional().default(false).describe('Save beautified file to the same directory as the original file'),\n },\n handler: async (params) => {\n const { file_path, start_line, end_line, char_limit, max_line_chars, save_local } = params;\n\n // Beautify the file and get source map\n const beautifyResult = await ensureBeautified(file_path, { saveLocal: save_local });\n const { code, rawMap, localPath, localMapPath, localSaveError } = beautifyResult;\n\n // Truncate long strings\n const truncatedCode = truncateCodeHighPerf(code, char_limit);\n\n // Truncate long lines\n const lineTruncatedCode = truncateLongLines(truncatedCode, max_line_chars);\n\n // Split into lines\n const lines = lineTruncatedCode.split('\\n');\n const totalLines = lines.length;\n\n // Validate line range\n const effectiveStartLine = Math.max(1, start_line);\n const effectiveEndLine = Math.min(totalLines, end_line);\n\n if (effectiveStartLine > totalLines) {\n throw new Error(`Start line ${start_line} exceeds total lines ${totalLines}`);\n }\n\n // Create source map consumer (cast version to string as required by source-map-js)\n const consumer = new SourceMapConsumer({\n ...rawMap,\n version: String(rawMap.version),\n });\n\n // Build output\n const outputParts: string[] = [];\n\n // Add header\n outputParts.push(formatHeader(file_path, effectiveStartLine, effectiveEndLine, totalLines));\n\n // Add local save info if applicable\n if (save_local) {\n if (localPath) {\n outputParts.push(`LOCAL: ${localPath}`);\n if (localMapPath) {\n outputParts.push(`MAP: ${localMapPath}`);\n }\n }\n if (localSaveError) {\n outputParts.push(`ERROR: ${localSaveError}`);\n }\n }\n\n // Calculate max line number width for alignment\n const maxLineNumWidth = String(effectiveEndLine).length;\n\n // Format each line\n for (let lineNum = effectiveStartLine; lineNum <= effectiveEndLine; lineNum++) {\n const lineIndex = lineNum - 1;\n const lineContent = lines[lineIndex] ?? '';\n\n // Get original position from source map\n const originalPos = consumer.originalPositionFor({\n line: lineNum,\n column: 0,\n });\n\n const sourcePos = formatSourcePosition(originalPos.line, originalPos.column);\n outputParts.push(formatCodeLine(lineNum, sourcePos, lineContent, maxLineNumWidth));\n }\n\n // Add pagination hint if there are more lines\n if (effectiveEndLine < totalLines) {\n outputParts.push(formatPaginationHint(effectiveEndLine + 1));\n }\n\n return outputParts.join('\\n');\n },\n});\n", "import { z } from 'zod';\n\n/**\n * Tool definition interface for MCP tools.\n * Each tool has a name, description, schema (Zod raw shape), and async handler.\n */\nexport interface ToolDefinition<TSchema extends z.ZodRawShape = z.ZodRawShape> {\n /** Unique tool name (e.g., 'read_code_smart') */\n name: string;\n /** Human-readable description of what the tool does */\n description: string;\n /** Zod schema object defining input parameters */\n schema: TSchema;\n /** Async handler function that processes the tool request */\n handler: (params: z.infer<z.ZodObject<TSchema>>) => Promise<string>;\n}\n\n/**\n * Helper function to create a type-safe tool definition.\n * Validates the tool definition structure at compile time.\n * \n * @param definition - The tool definition object\n * @returns The same definition with proper typing\n */\nexport function defineTool<TSchema extends z.ZodRawShape>(\n definition: ToolDefinition<TSchema>\n): ToolDefinition<TSchema> {\n return definition;\n}\n", "import * as esbuild from 'esbuild';\nimport * as crypto from 'crypto';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport * as os from 'os';\n\nconst TEMP_DIR = path.join(os.tmpdir(), 'smart-fs-mcp-cache');\n\nexport interface SourceMap {\n version: number;\n sources: string[];\n names: string[];\n mappings: string;\n file?: string;\n sourceRoot?: string;\n}\n\nexport interface BeautifyOptions {\n // Reserved for future options\n}\n\nexport interface BeautifyResult {\n code: string;\n rawMap: SourceMap;\n /** \u672C\u5730\u4FDD\u5B58\u7684\u7F8E\u5316\u6587\u4EF6\u8DEF\u5F84 */\n localPath: string;\n /** \u672C\u5730\u4FDD\u5B58\u7684 source map \u8DEF\u5F84 */\n localMapPath: string;\n /** \u672C\u5730\u4FDD\u5B58\u5931\u8D25\u65F6\u7684\u9519\u8BEF\u4FE1\u606F */\n localSaveError?: string;\n}\n\n/**\n * Ensure the cache directory exists\n */\nasync function ensureCacheDir(): Promise<void> {\n await fs.mkdir(TEMP_DIR, { recursive: true });\n}\n\n/**\n * Calculate cache key based on file path and modification time\n */\nfunction calculateCacheKey(originalPath: string, mtimeMs: number): string {\n const fileKey = `${originalPath}-${mtimeMs}`;\n return crypto.createHash('md5').update(fileKey).digest('hex');\n}\n\n/**\n * Get cache file paths for a given original file\n */\nfunction getCachePaths(originalPath: string, hash: string): { beautifiedPath: string; mapPath: string } {\n const fileName = path.basename(originalPath, '.js');\n const beautifiedPath = path.join(TEMP_DIR, `${fileName}.${hash}.beautified.js`);\n const mapPath = `${beautifiedPath}.map`;\n return { beautifiedPath, mapPath };\n}\n\n\n/**\n * Local paths result interface\n */\nexport interface LocalPaths {\n /** Path to the beautified file in the same directory as the original */\n beautifiedPath: string;\n /** Path to the source map file in the same directory as the original */\n mapPath: string;\n}\n\n/**\n * Get local file paths for beautified output\n * Given an original file path, returns the paths where the beautified file\n * and source map should be saved in the same directory.\n * \n * Naming convention:\n * - Original: {filename}.js -> Beautified: {filename}.beautified.js\n * - Source map: {filename}.beautified.js.map\n * \n * @param originalPath - Path to the original JavaScript file\n * @returns Object containing beautifiedPath and mapPath\n */\nexport function getLocalPaths(originalPath: string): LocalPaths {\n const absolutePath = path.resolve(originalPath);\n const dir = path.dirname(absolutePath);\n const ext = path.extname(absolutePath);\n const baseName = path.basename(absolutePath, ext);\n \n const beautifiedPath = path.join(dir, `${baseName}.beautified.js`);\n const mapPath = `${beautifiedPath}.map`;\n \n return { beautifiedPath, mapPath };\n}\n\n/**\n * Check if cache exists and is valid (for temp directory cache)\n */\nasync function isCacheValid(beautifiedPath: string, mapPath: string): Promise<boolean> {\n try {\n await Promise.all([\n fs.access(beautifiedPath),\n fs.access(mapPath)\n ]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Local cache validation result interface\n */\nexport interface LocalCacheCheck {\n /** Original file modification time in milliseconds */\n originalMtime: number;\n /** Whether the beautified file exists */\n beautifiedExists: boolean;\n /** Beautified file modification time in milliseconds (0 if not exists) */\n beautifiedMtime: number;\n /** Whether the cache is valid (beautifiedMtime >= originalMtime) */\n isValid: boolean;\n}\n\n/**\n * Check if local beautified cache is valid\n * \n * A local cache is considered valid when:\n * 1. The beautified file exists\n * 2. The beautified file's modification time is >= the original file's modification time\n * \n * @param originalPath - Path to the original JavaScript file\n * @returns LocalCacheCheck object with validation details\n */\nexport async function isLocalCacheValid(originalPath: string): Promise<LocalCacheCheck> {\n const absolutePath = path.resolve(originalPath);\n const { beautifiedPath } = getLocalPaths(absolutePath);\n \n // Get original file stats\n let originalStats: Awaited<ReturnType<typeof fs.stat>>;\n try {\n originalStats = await fs.stat(absolutePath);\n } catch {\n // Original file doesn't exist - cache cannot be valid\n return {\n originalMtime: 0,\n beautifiedExists: false,\n beautifiedMtime: 0,\n isValid: false\n };\n }\n \n const originalMtime = originalStats.mtimeMs;\n \n // Check if beautified file exists and get its stats\n let beautifiedStats: Awaited<ReturnType<typeof fs.stat>>;\n try {\n beautifiedStats = await fs.stat(beautifiedPath);\n } catch {\n // Beautified file doesn't exist\n return {\n originalMtime,\n beautifiedExists: false,\n beautifiedMtime: 0,\n isValid: false\n };\n }\n \n const beautifiedMtime = beautifiedStats.mtimeMs;\n const isValid = beautifiedMtime >= originalMtime;\n \n return {\n originalMtime,\n beautifiedExists: true,\n beautifiedMtime,\n isValid\n };\n}\n\n/**\n * Beautify JavaScript file and generate Source Map\n * @param originalPath - Original file path\n * @param options - Optional beautify options (saveLocal, etc.)\n * @returns Beautified code and Source Map\n */\nexport async function ensureBeautified(\n originalPath: string,\n options?: BeautifyOptions\n): Promise<BeautifyResult> {\n // Resolve to absolute path\n const absolutePath = path.resolve(originalPath);\n \n // Check if file exists\n let stats: Awaited<ReturnType<typeof fs.stat>>;\n try {\n stats = await fs.stat(absolutePath);\n } catch {\n throw new Error(`File not found: ${originalPath}`);\n }\n \n // Get local paths for local save/read\n const localPaths = getLocalPaths(absolutePath);\n \n // Check local cache first\n const localCacheCheck = await isLocalCacheValid(absolutePath);\n if (localCacheCheck.isValid) {\n // Local cache hit - read from local files\n try {\n const [code, mapContent] = await Promise.all([\n fs.readFile(localPaths.beautifiedPath, 'utf-8'),\n fs.readFile(localPaths.mapPath, 'utf-8')\n ]);\n return {\n code,\n rawMap: JSON.parse(mapContent) as SourceMap,\n localPath: localPaths.beautifiedPath,\n localMapPath: localPaths.mapPath\n };\n } catch {\n // If reading local cache fails, fall through to regenerate\n }\n }\n \n // Ensure temp cache directory exists\n await ensureCacheDir();\n \n // Calculate cache key for temp directory\n const hash = calculateCacheKey(absolutePath, stats.mtimeMs);\n const { beautifiedPath, mapPath } = getCachePaths(absolutePath, hash);\n \n // Check temp cache\n if (await isCacheValid(beautifiedPath, mapPath)) {\n // Temp cache hit - read from cache\n const [code, mapContent] = await Promise.all([\n fs.readFile(beautifiedPath, 'utf-8'),\n fs.readFile(mapPath, 'utf-8')\n ]);\n \n const result: BeautifyResult = {\n code,\n rawMap: JSON.parse(mapContent) as SourceMap,\n localPath: localPaths.beautifiedPath,\n localMapPath: localPaths.mapPath\n };\n \n // Also save to local directory\n await saveToLocal(result, localPaths, mapContent);\n \n return result;\n }\n \n // Cache miss - beautify with Esbuild\n let esbuildResult: esbuild.BuildResult;\n try {\n esbuildResult = await esbuild.build({\n entryPoints: [absolutePath],\n bundle: false,\n write: false,\n format: 'esm',\n sourcemap: 'external',\n sourcesContent: false,\n outfile: 'out.js',\n // Beautify settings\n minify: false,\n keepNames: true,\n treeShaking: false,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Esbuild processing failed: ${message}`);\n }\n \n // Extract code and source map from result\n const codeFile = esbuildResult.outputFiles?.find(f => f.path.endsWith('.js'));\n const mapFile = esbuildResult.outputFiles?.find(f => f.path.endsWith('.map'));\n \n if (!codeFile || !mapFile) {\n throw new Error('Esbuild processing failed: Missing output files');\n }\n \n const code = codeFile.text;\n const rawMap = JSON.parse(mapFile.text) as SourceMap;\n const mapText = mapFile.text;\n \n // Write to temp cache\n await Promise.all([\n fs.writeFile(beautifiedPath, code, 'utf-8'),\n fs.writeFile(mapPath, mapText, 'utf-8')\n ]);\n \n const result: BeautifyResult = {\n code,\n rawMap,\n localPath: localPaths.beautifiedPath,\n localMapPath: localPaths.mapPath\n };\n \n // Save to local directory\n await saveToLocal(result, localPaths, mapText);\n \n return result;\n}\n\n/**\n * Save beautified code and source map to local directory\n * Handles errors gracefully by setting localSaveError instead of throwing\n */\nasync function saveToLocal(\n result: BeautifyResult,\n localPaths: LocalPaths,\n mapText: string\n): Promise<void> {\n try {\n await Promise.all([\n fs.writeFile(localPaths.beautifiedPath, result.code, 'utf-8'),\n fs.writeFile(localPaths.mapPath, mapText, 'utf-8')\n ]);\n result.localPath = localPaths.beautifiedPath;\n result.localMapPath = localPaths.mapPath;\n } catch (err) {\n // Handle specific error types\n const error = err as NodeJS.ErrnoException;\n if (error.code === 'EACCES' || error.code === 'EPERM') {\n result.localSaveError = `Permission denied: Cannot write to ${path.dirname(localPaths.beautifiedPath)}`;\n } else if (error.code === 'ENOSPC') {\n result.localSaveError = `Insufficient disk space: Cannot write to ${path.dirname(localPaths.beautifiedPath)}`;\n } else {\n result.localSaveError = `Failed to save locally: ${error.message || String(err)}`;\n }\n // Don't throw - the temp cache result is still valid\n }\n}\n", "import { parse } from 'meriyah';\nimport { walk } from 'estree-walker';\nimport MagicString from 'magic-string';\nimport type { Node } from 'estree';\n\n/**\n * Count newlines in a string\n */\nfunction countNewlines(str: string): number {\n let count = 0;\n for (const char of str) {\n if (char === '\\n') count++;\n }\n return count;\n}\n\n/**\n * Create truncated string with preserved newlines\n * Format: \"start ...[TRUNCATED {length} CHARS]... \\n\\n\\nend\"\n */\nfunction createTruncatedString(original: string, previewLength: number): string {\n const newlineCount = countNewlines(original);\n const start = original.slice(0, previewLength);\n const end = original.slice(-previewLength);\n \n // Build the truncation marker with preserved newlines\n const marker = `...[TRUNCATED ${original.length} CHARS]...`;\n \n // Create newlines to preserve line count\n // We need to account for newlines already in start and end portions\n const startNewlines = countNewlines(start);\n const endNewlines = countNewlines(end);\n const preservedNewlines = Math.max(0, newlineCount - startNewlines - endNewlines);\n const newlineStr = '\\n'.repeat(preservedNewlines);\n \n return `${start}${marker}${newlineStr}${end}`;\n}\n\n/**\n * Truncate long strings in JavaScript code while preserving line numbers\n * @param sourceCode - Source code to process\n * @param limit - Character limit for strings (default 200)\n * @param previewLength - Length of start/end preview portions (default 50)\n * @returns Truncated code with preserved line count\n */\nexport function truncateCodeHighPerf(sourceCode: string, limit: number = 200, previewLength: number = 50): string {\n // Try to parse the AST\n let ast: ReturnType<typeof parse>;\n try {\n ast = parse(sourceCode, {\n module: true,\n next: true,\n ranges: true,\n loc: true,\n raw: true,\n });\n } catch {\n // AST parsing failed - return original code unchanged (Requirement 2.4)\n return sourceCode;\n }\n\n const magicString = new MagicString(sourceCode);\n \n // Walk the AST and find string literals to truncate\n walk(ast as unknown as Node, {\n enter(node: Node) {\n // Handle regular string literals\n if (node.type === 'Literal' && typeof (node as any).value === 'string') {\n const literal = node as any;\n const value = literal.value as string;\n \n if (value.length > limit && literal.start !== undefined && literal.end !== undefined) {\n const truncated = createTruncatedString(value, previewLength);\n // Wrap in quotes matching the original\n const originalText = sourceCode.slice(literal.start, literal.end);\n const quote = originalText[0]; // Get the quote character used\n magicString.overwrite(literal.start, literal.end, `${quote}${truncated}${quote}`);\n }\n }\n \n // Handle template literals\n if (node.type === 'TemplateLiteral') {\n const template = node as any;\n \n // Process each quasi (template element)\n for (const quasi of template.quasis) {\n const value = quasi.value.raw as string;\n \n if (value.length > limit && quasi.start !== undefined && quasi.end !== undefined) {\n const truncated = createTruncatedString(value, previewLength);\n // Template literal quasis don't have surrounding quotes\n magicString.overwrite(quasi.start, quasi.end, truncated);\n }\n }\n }\n }\n });\n\n return magicString.toString();\n}\n\n/**\n * Truncate lines that exceed the maximum character limit\n * @param code - Source code to process\n * @param maxLineChars - Maximum characters per line (default 500)\n * @param previewRatio - Ratio of line to show at start/end (default 0.2)\n * @returns Code with truncated long lines\n */\nexport function truncateLongLines(\n code: string,\n maxLineChars: number = 500,\n previewRatio: number = 0.2\n): string {\n if (!code) {\n return code;\n }\n\n const lines = code.split('\\n');\n const previewLength = Math.floor(maxLineChars * previewRatio);\n\n const processedLines = lines.map((line) => {\n if (line.length <= maxLineChars) {\n return line;\n }\n\n const start = line.slice(0, previewLength);\n const end = line.slice(-previewLength);\n const truncatedChars = line.length - previewLength * 2;\n const marker = `...[LINE TRUNCATED ${truncatedChars} CHARS]...`;\n\n return `${start}${marker}${end}`;\n });\n\n return processedLines.join('\\n');\n}\n", "import { z } from 'zod';\nimport { defineTool } from './ToolDefinition.js';\nimport { applyCustomTransform as runTransform } from '../transformer.js';\n\n/**\n * Schema for apply_custom_transform tool input validation\n */\nexport const ApplyCustomTransformInputSchema = z.object({\n target_file: z.string().describe('Path to the JavaScript file to transform'),\n script_path: z.string().describe('Path to a JS file exporting a Babel Plugin function'),\n output_suffix: z.string().default('_deob').describe('Suffix for output file name'),\n});\n\n/**\n * apply_custom_transform tool definition\n * Apply a custom Babel transformation to deobfuscate JavaScript code.\n */\nexport const applyCustomTransform = defineTool({\n name: 'apply_custom_transform',\n description:\n 'Apply a custom Babel transformation to deobfuscate JavaScript code. ' +\n 'Takes a target JS file and a Babel plugin script, runs the transformation, ' +\n 'and outputs the deobfuscated code with a cascaded source map that traces back to the original minified file. ' +\n 'The plugin script should export a function that returns a Babel visitor object.',\n schema: {\n target_file: z.string().describe('Path to the JavaScript file to transform'),\n script_path: z.string().describe('Path to a JS file exporting a Babel Plugin function'),\n output_suffix: z.string().default('_deob').describe('Suffix for output file name'),\n },\n handler: async (params) => {\n const { target_file, script_path, output_suffix } = params;\n\n // Call the transform function\n const result = await runTransform(target_file, {\n scriptPath: script_path,\n outputSuffix: output_suffix,\n });\n\n // Return success message with created file paths\n const successMessage = [\n 'Transform completed successfully!',\n '',\n `Output file: ${result.outputPath}`,\n `Source map: ${result.mapPath}`,\n ].join('\\n');\n\n return successMessage;\n },\n});\n", "import * as path from 'path';\nimport * as fs from 'fs/promises';\nimport { transformSync, type BabelFileResult, type PluginItem } from '@babel/core';\nimport { ensureBeautified, type SourceMap } from './beautifier.js';\n\n/**\n * Transform options interface\n */\nexport interface TransformOptions {\n /** Path to the user's Babel plugin script */\n scriptPath: string;\n /** Output file suffix (default \"_deob\") */\n outputSuffix?: string;\n}\n\n/**\n * Transform result interface\n */\nexport interface TransformResult {\n /** Transformed code */\n code: string;\n /** Cascaded Source Map */\n map: SourceMap;\n /** Output file path */\n outputPath: string;\n /** Source Map file path */\n mapPath: string;\n}\n\n/**\n * Output paths interface\n */\nexport interface OutputPaths {\n /** Output JS file path */\n outputPath: string;\n /** Source Map file path */\n mapPath: string;\n}\n\n/**\n * Clean basename by removing .beautified and _deob* suffixes\n * \n * Examples:\n * - main.js -> main\n * - main.beautified.js -> main\n * - main_deob.js -> main\n * - main.beautified_deob.js -> main\n * - main_deob_v2.js -> main\n * \n * @param filename - Original filename (with or without path)\n * @returns Cleaned basename without extension\n */\nexport function cleanBasename(filename: string): string {\n // Get just the filename without directory\n const base = path.basename(filename);\n \n // Remove .js extension\n let name = base.endsWith('.js') ? base.slice(0, -3) : base;\n \n // Remove _deob* suffix first (e.g., _deob, _deob_v2, _deob123)\n // This handles cases like main.beautified_deob.js\n name = name.replace(/_deob[^/]*$/, '');\n \n // Remove .beautified suffix if present\n if (name.endsWith('.beautified')) {\n name = name.slice(0, -'.beautified'.length);\n }\n \n return name;\n}\n\n/**\n * Calculate output paths for transformed file\n * \n * @param targetFile - Path to the target file\n * @param outputSuffix - Suffix for output file (default \"_deob\")\n * @returns Output paths for JS and map files\n */\nexport function getOutputPaths(targetFile: string, outputSuffix: string = '_deob'): OutputPaths {\n const absolutePath = path.resolve(targetFile);\n const dir = path.dirname(absolutePath);\n const basename = cleanBasename(absolutePath);\n \n const outputPath = path.join(dir, `${basename}${outputSuffix}.js`);\n const mapPath = `${outputPath}.map`;\n \n return { outputPath, mapPath };\n}\n\n/**\n * Babel plugin function type\n * A Babel plugin is a function that receives babel API and returns a visitor object\n */\nexport type BabelPluginFunction = (babel: { types: typeof import('@babel/types') }) => {\n visitor: Record<string, unknown>;\n};\n\n/**\n * Load a Babel plugin script from the given path\n * \n * Features:\n * - Resolves to absolute path\n * - Clears require cache for hot-reloading\n * - Validates plugin format\n * \n * @param scriptPath - Path to the Babel plugin script\n * @returns The loaded Babel plugin function\n * @throws Error if script not found or invalid format\n */\nexport async function loadBabelPlugin(scriptPath: string): Promise<BabelPluginFunction> {\n // Resolve to absolute path\n const absolutePath = path.resolve(scriptPath);\n \n // Check if file exists\n try {\n await fs.access(absolutePath);\n } catch {\n throw new Error(`Script not found: ${absolutePath}`);\n }\n \n // Convert to file URL for ESM import\n const fileUrl = `file://${absolutePath}?t=${Date.now()}`;\n \n // Dynamic import with cache busting for hot-reload\n let module: unknown;\n try {\n module = await import(fileUrl);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Failed to load script: ${message}`);\n }\n \n // Extract the plugin function\n const plugin = (module as { default?: unknown }).default ?? module;\n \n // Validate plugin format - must be a function\n if (typeof plugin !== 'function') {\n throw new Error(\n `Invalid Babel plugin: Script must export a function that returns a visitor object. ` +\n `Got ${typeof plugin} instead.`\n );\n }\n \n return plugin as BabelPluginFunction;\n}\n\n\n/**\n * Babel transform result interface\n */\ninterface BabelTransformResult {\n /** Transformed code */\n code: string;\n /** Generated source map (cascaded) */\n map: SourceMap;\n}\n\n/**\n * Run Babel transform with source map cascade\n * \n * Configuration:\n * - inputSourceMap: Enables cascade from beautified -> original\n * - sourceMaps: true to generate output source map\n * - retainLines: false for best readability\n * - compact: false for readable output\n * - minified: false for readable output\n * \n * @param code - Input code (beautified)\n * @param inputSourceMap - Source map from beautifier (beautified -> original)\n * @param plugin - Babel plugin function\n * @param filename - Original filename for source map\n * @returns Transformed code and cascaded source map\n */\nexport function runBabelTransform(\n code: string,\n inputSourceMap: SourceMap,\n plugin: BabelPluginFunction,\n filename: string\n): BabelTransformResult {\n let result: BabelFileResult | null;\n \n try {\n result = transformSync(code, {\n filename,\n plugins: [plugin as PluginItem],\n // Source map configuration for cascade\n // @ts-expect-error - SourceMap is compatible with InputSourceMap at runtime\n inputSourceMap: inputSourceMap,\n sourceMaps: true,\n // Readability settings\n retainLines: false,\n compact: false,\n minified: false,\n // Preserve code structure\n parserOpts: {\n sourceType: 'unambiguous',\n },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Babel Error: ${message}`);\n }\n \n if (!result || !result.code) {\n throw new Error('Babel Error: Transform produced no output');\n }\n \n if (!result.map) {\n throw new Error('Babel Error: Transform produced no source map');\n }\n \n return {\n code: result.code,\n map: result.map as unknown as SourceMap,\n };\n}\n\n\n/**\n * Apply custom Babel transform to a JavaScript file\n * \n * Process:\n * 1. Load and validate the Babel plugin script\n * 2. Get beautified code and source map from target file\n * 3. Run Babel transform with source map cascade\n * 4. Write output file and source map\n * 5. Append sourceMappingURL comment\n * \n * @param targetFile - Path to the JavaScript file to transform\n * @param options - Transform options (scriptPath, outputSuffix)\n * @returns Transform result with output paths\n */\nexport async function applyCustomTransform(\n targetFile: string,\n options: TransformOptions\n): Promise<TransformResult> {\n const { scriptPath, outputSuffix = '_deob' } = options;\n \n // Resolve target file path\n const absoluteTargetPath = path.resolve(targetFile);\n \n // Check if target file exists\n try {\n await fs.access(absoluteTargetPath);\n } catch {\n throw new Error(`File not found: ${targetFile}`);\n }\n \n // Load the Babel plugin script\n const plugin = await loadBabelPlugin(scriptPath);\n \n // Get beautified code and source map\n const beautifyResult = await ensureBeautified(absoluteTargetPath);\n const { code: beautifiedCode, rawMap: inputSourceMap } = beautifyResult;\n \n // Run Babel transform with source map cascade\n const transformResult = runBabelTransform(\n beautifiedCode,\n inputSourceMap,\n plugin,\n absoluteTargetPath\n );\n \n // Calculate output paths\n const { outputPath, mapPath } = getOutputPaths(absoluteTargetPath, outputSuffix);\n \n // Prepare output code with sourceMappingURL comment\n const mapFileName = path.basename(mapPath);\n const outputCode = `${transformResult.code}\\n//# sourceMappingURL=${mapFileName}`;\n \n // Prepare source map with correct file reference\n const outputMap: SourceMap = {\n ...transformResult.map,\n file: path.basename(outputPath),\n };\n \n // Write output files\n try {\n await Promise.all([\n fs.writeFile(outputPath, outputCode, 'utf-8'),\n fs.writeFile(mapPath, JSON.stringify(outputMap, null, 2), 'utf-8'),\n ]);\n } catch (err) {\n const error = err as NodeJS.ErrnoException;\n if (error.code === 'EACCES' || error.code === 'EPERM') {\n throw new Error(`Permission denied: Cannot write to ${path.dirname(outputPath)}`);\n }\n throw new Error(`Failed to write output files: ${error.message || String(err)}`);\n }\n \n return {\n code: outputCode,\n map: outputMap,\n outputPath,\n mapPath,\n };\n}\n", "import { z } from 'zod';\nimport { defineTool } from './ToolDefinition.js';\nimport { ensureBeautified } from '../beautifier.js';\nimport { truncateLongLines } from '../truncator.js';\nimport { searchInCode, formatSearchResult, unescapeBackslashes } from '../searcher.js';\n\n/**\n * Schema for search_code_smart tool input validation\n */\nexport const SearchCodeSmartInputSchema = z.object({\n file_path: z.string().describe('Path to the JavaScript file'),\n query: z.string().describe('Regex pattern or text to search'),\n context_lines: z.number().int().min(0).default(2).describe('Number of context lines'),\n case_sensitive: z.boolean().default(false).describe('Case sensitive search'),\n char_limit: z.number().int().min(50).default(300).describe('Character limit for string truncation'),\n max_line_chars: z.number().int().min(80).default(500).describe('Maximum characters per line'),\n is_regex: z.boolean().default(false).describe('Treat query as regex pattern (default: false for literal text search)'),\n});\n\n/**\n * search_code_smart tool definition\n * Search for text or regex patterns in beautified JavaScript code.\n */\nexport const searchCodeSmart = defineTool({\n name: 'search_code_smart',\n description:\n 'Search for text or regex patterns in beautified JavaScript code. ' +\n 'Returns matching lines with context and original source coordinates for setting breakpoints. ' +\n 'Useful for finding code patterns in minified/obfuscated files.',\n schema: {\n file_path: z.string().describe('Path to the JavaScript file'),\n query: z.string().describe('Regex pattern or text to search'),\n context_lines: z.number().int().min(0).default(2).describe('Number of context lines'),\n case_sensitive: z.boolean().default(false).describe('Case sensitive search'),\n char_limit: z.number().int().min(50).default(300).describe('Character limit for string truncation'),\n max_line_chars: z.number().int().min(80).default(500).describe('Maximum characters per line'),\n is_regex: z.boolean().default(false).describe('Treat query as regex pattern (default: false for literal text search)'),\n },\n handler: async (params) => {\n const { file_path, query, context_lines, case_sensitive, char_limit, max_line_chars, is_regex } = params;\n\n // Unescape double-escaped backslashes from MCP JSON transmission\n const unescapedQuery = unescapeBackslashes(query);\n\n // Beautify the file and get source map\n const beautifyResult = await ensureBeautified(file_path);\n const { code, rawMap } = beautifyResult;\n\n // Execute search on original beautified code (no truncation before search)\n const searchResult = searchInCode(code, rawMap, {\n query: unescapedQuery,\n contextLines: context_lines,\n caseSensitive: case_sensitive,\n maxMatches: 50,\n isRegex: is_regex,\n });\n\n // Format the result\n let output = formatSearchResult(file_path, unescapedQuery, case_sensitive, searchResult, 50, is_regex);\n\n // Truncate long lines in output\n output = truncateLongLines(output, max_line_chars);\n\n return output;\n },\n});\n", "import { SourceMapConsumer } from 'source-map-js';\nimport type { SourceMap } from './beautifier.js';\n\n/**\n * Original position from source map\n */\nexport interface OriginalPosition {\n line: number | null;\n column: number | null;\n}\n\n/**\n * Context line with position info\n */\nexport interface ContextLine {\n lineNumber: number;\n content: string;\n originalPosition: OriginalPosition;\n}\n\n/**\n * Search match result\n */\nexport interface SearchMatch {\n /** Match line number (1-based, in beautified code) */\n lineNumber: number;\n /** Match line content */\n lineContent: string;\n /** Original file coordinates */\n originalPosition: OriginalPosition;\n /** Context lines before match */\n contextBefore: ContextLine[];\n /** Context lines after match */\n contextAfter: ContextLine[];\n}\n\n/**\n * Search options\n */\nexport interface SearchOptions {\n /** Regex pattern or text to search */\n query: string;\n /** Number of context lines (default 2) */\n contextLines?: number;\n /** Case sensitive search (default false) */\n caseSensitive?: boolean;\n /** Maximum matches to return (default 50) */\n maxMatches?: number;\n /** Treat query as regex pattern (default false for literal text search) */\n isRegex?: boolean;\n /** Timeout in milliseconds for search operation (default 500) */\n timeoutMs?: number;\n}\n\n/**\n * Search result\n */\nexport interface SearchResult {\n /** Matched results */\n matches: SearchMatch[];\n /** Total matches found (before truncation) */\n totalMatches: number;\n /** Whether results were truncated */\n truncated: boolean;\n}\n\n\n/**\n * Convert double-escaped backslashes to single backslashes.\n * Fixes MCP JSON transmission double-escaping issue.\n * \n * @param str - String with potentially double-escaped backslashes\n * @returns String with `\\\\` converted to `\\`\n * \n * @example\n * unescapeBackslashes(\"for\\\\s*\\\\(\") // returns \"for\\s*\\(\"\n * unescapeBackslashes(\"\\\\\\\\n\") // returns \"\\\\n\" (literal backslash + n)\n * unescapeBackslashes(\"hello\") // returns \"hello\" (unchanged)\n */\nexport function unescapeBackslashes(str: string): string {\n return str.replace(/\\\\\\\\/g, '\\\\');\n}\n\n/**\n * Escape all regex special characters in a string for literal matching\n * @param str - String to escape\n * @returns Escaped string safe for use in RegExp\n */\nexport function escapeRegex(str: string): string {\n return str.replace(/[()[\\]{}.*+?^$|\\\\]/g, '\\\\$&');\n}\n\n/**\n * Create regex from query string with error handling\n * @param query - Regex pattern or text\n * @param caseSensitive - Whether to be case sensitive\n * @param isRegex - Whether to treat query as regex (default false)\n * @returns Created RegExp\n * @throws Error if regex is invalid\n */\nexport function createRegex(query: string, caseSensitive: boolean = false, isRegex: boolean = false): RegExp {\n try {\n const flags = caseSensitive ? 'g' : 'gi';\n const pattern = isRegex ? query : escapeRegex(query);\n return new RegExp(pattern, flags);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Invalid regex: ${message}`);\n }\n}\n\n/**\n * Get original position for a line using source map consumer\n */\nfunction getOriginalPosition(\n consumer: SourceMapConsumer,\n lineNumber: number\n): OriginalPosition {\n const pos = consumer.originalPositionFor({\n line: lineNumber,\n column: 0,\n });\n return {\n line: pos.line,\n column: pos.column,\n };\n}\n\n/**\n * Build line offset index using Int32Array for memory efficiency.\n * Returns the offset array and total line count.\n */\nfunction buildLineOffsets(code: string): { offsets: Int32Array; totalLines: number } {\n // Pre-allocate with estimated average line length of 40 chars\n let capacity = Math.max(16, Math.ceil(code.length / 40));\n let offsets = new Int32Array(capacity);\n let lineCount = 0;\n\n offsets[0] = 0; // First line starts at index 0\n\n for (let i = 0; i < code.length; i++) {\n if (code[i] === '\\n') {\n lineCount++;\n // Dynamic resize if needed\n if (lineCount >= capacity) {\n capacity *= 2;\n const newArr = new Int32Array(capacity);\n newArr.set(offsets);\n offsets = newArr;\n }\n offsets[lineCount] = i + 1; // Next line starts after \\n\n }\n }\n\n return {\n offsets: offsets.subarray(0, lineCount + 1),\n totalLines: lineCount + 1,\n };\n}\n\n/**\n * Binary search to find line number (1-based) from character index.\n */\nfunction getLineNumberFromIndex(offsets: Int32Array, totalLines: number, index: number): number {\n let low = 0;\n let high = totalLines - 1;\n\n while (low <= high) {\n const mid = (low + high) >>> 1;\n if (offsets[mid] <= index) {\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n return low; // 1-based line number\n}\n\n/**\n * Get line content by line number (1-based) without splitting entire string.\n */\nfunction getLineContent(\n code: string,\n offsets: Int32Array,\n totalLines: number,\n lineNo: number\n): string {\n if (lineNo < 1 || lineNo > totalLines) return '';\n\n const start = offsets[lineNo - 1];\n let end: number;\n\n if (lineNo < totalLines) {\n // End is one before the next line's start (exclude \\n)\n end = offsets[lineNo] - 1;\n } else {\n // Last line: go to end of string\n end = code.length;\n }\n\n // Handle \\r\\n line endings\n if (end > start && code[end - 1] === '\\r') {\n end--;\n }\n\n return code.slice(start, end);\n}\n\n/**\n * Search for pattern in code and return matches with context.\n * Optimized version: avoids split() for large files, uses index-based iteration.\n *\n * @param code - Beautified code to search in\n * @param rawMap - Source map for coordinate mapping\n * @param options - Search options\n * @returns Search result with matches\n */\nexport function searchInCode(\n code: string,\n rawMap: SourceMap,\n options: SearchOptions\n): SearchResult {\n const {\n query,\n contextLines = 2,\n caseSensitive = false,\n maxMatches = 10,\n isRegex = false,\n timeoutMs = 500,\n } = options;\n\n // Build line offset index (memory efficient)\n const { offsets, totalLines } = buildLineOffsets(code);\n\n // Create regex with global + multiline flags\n const flags = (caseSensitive ? 'g' : 'gi') + 'm';\n const patternStr = isRegex ? unescapeBackslashes(query) : escapeRegex(query);\n\n let regex: RegExp;\n try {\n regex = new RegExp(patternStr, flags);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Invalid regex: ${message}`);\n }\n\n // Create source map consumer\n const consumer = new SourceMapConsumer({\n ...rawMap,\n version: String(rawMap.version),\n });\n\n const matches: SearchMatch[] = [];\n let lastMatchedLine = -1;\n let totalMatchesFound = 0;\n let match: RegExpExecArray | null;\n\n // Performance protection\n const startTime = Date.now();\n\n // Iterate matches using exec() - no string splitting\n while ((match = regex.exec(code)) !== null) {\n // Prevent infinite loop on zero-width matches\n if (match.index === regex.lastIndex) {\n regex.lastIndex++;\n }\n\n const lineNumber = getLineNumberFromIndex(offsets, totalLines, match.index);\n\n // Dedupe: skip if same line already matched\n if (lineNumber === lastMatchedLine) {\n continue;\n }\n lastMatchedLine = lineNumber;\n totalMatchesFound++;\n\n // Only build match details if we haven't hit the limit yet\n if (matches.length < maxMatches) {\n // Build context (lazy: only fetch line content when needed)\n const contextBefore: ContextLine[] = [];\n for (let i = Math.max(1, lineNumber - contextLines); i < lineNumber; i++) {\n contextBefore.push({\n lineNumber: i,\n content: getLineContent(code, offsets, totalLines, i),\n originalPosition: getOriginalPosition(consumer, i),\n });\n }\n\n const contextAfter: ContextLine[] = [];\n for (let i = lineNumber + 1; i <= Math.min(totalLines, lineNumber + contextLines); i++) {\n contextAfter.push({\n lineNumber: i,\n content: getLineContent(code, offsets, totalLines, i),\n originalPosition: getOriginalPosition(consumer, i),\n });\n }\n\n matches.push({\n lineNumber,\n lineContent: getLineContent(code, offsets, totalLines, lineNumber),\n originalPosition: getOriginalPosition(consumer, lineNumber),\n contextBefore,\n contextAfter,\n });\n }\n\n // Timeout protection (still count but stop searching)\n if (Date.now() - startTime > timeoutMs) {\n break;\n }\n }\n\n return {\n matches,\n totalMatches: totalMatchesFound,\n truncated: totalMatchesFound > maxMatches,\n };\n}\n\n/**\n * Format source position as \"L{line}:{column}\" or placeholder\n */\nexport function formatSourcePosition(line: number | null, column: number | null): string {\n if (line !== null && column !== null) {\n return `L${line}:${column}`;\n }\n return '';\n}\n\n/**\n * Format search result for output\n * @param filePath - Path to the file\n * @param query - Search query\n * @param caseSensitive - Whether search was case sensitive\n * @param result - Search result\n * @param maxMatches - Maximum matches limit\n * @param isRegex - Whether query was treated as regex pattern\n * @returns Formatted output string\n */\nexport function formatSearchResult(\n filePath: string,\n query: string,\n caseSensitive: boolean,\n result: SearchResult,\n maxMatches: number = 50,\n isRegex: boolean = false\n): string {\n const { matches, totalMatches, truncated } = result;\n\n const outputParts: string[] = [];\n\n // Header\n const caseInfo = caseSensitive ? 'case-sensitive' : 'case-insensitive';\n const modeInfo = isRegex ? 'regex' : 'literal';\n outputParts.push(`FILE: ${filePath}`);\n outputParts.push(`QUERY: \"${query}\" (${modeInfo}, ${caseInfo})`);\n\n if (totalMatches === 0) {\n outputParts.push('MATCHES: No matches found');\n return outputParts.join('\\n');\n }\n\n const matchInfo = truncated\n ? `MATCHES: ${totalMatches} found (showing first ${maxMatches})`\n : `MATCHES: ${totalMatches} found`;\n outputParts.push(matchInfo);\n outputParts.push('-'.repeat(85));\n\n // Format each match\n for (const match of matches) {\n outputParts.push(`--- Match at Line ${match.lineNumber} ---`);\n\n // Calculate max line number width for alignment\n const allLineNumbers = [\n ...match.contextBefore.map((c) => c.lineNumber),\n match.lineNumber,\n ...match.contextAfter.map((c) => c.lineNumber),\n ];\n const maxLineNumWidth = Math.max(...allLineNumbers.map((n) => String(n).length));\n\n // Format context before\n for (const ctx of match.contextBefore) {\n const lineNumStr = String(ctx.lineNumber).padStart(maxLineNumWidth, ' ');\n const srcPos = formatSourcePosition(ctx.originalPosition.line, ctx.originalPosition.column);\n const srcPosPadded = srcPos ? `Src ${srcPos}` : '';\n outputParts.push(` ${lineNumStr} | [${srcPosPadded.padEnd(14, ' ')}] | ${ctx.content}`);\n }\n\n // Format match line with >> prefix\n const matchLineNumStr = String(match.lineNumber).padStart(maxLineNumWidth, ' ');\n const matchSrcPos = formatSourcePosition(match.originalPosition.line, match.originalPosition.column);\n const matchSrcPosPadded = matchSrcPos ? `Src ${matchSrcPos}` : '';\n outputParts.push(`>> ${matchLineNumStr} | [${matchSrcPosPadded.padEnd(14, ' ')}] | ${match.lineContent}`);\n\n // Format context after\n for (const ctx of match.contextAfter) {\n const lineNumStr = String(ctx.lineNumber).padStart(maxLineNumWidth, ' ');\n const srcPos = formatSourcePosition(ctx.originalPosition.line, ctx.originalPosition.column);\n const srcPosPadded = srcPos ? `Src ${srcPos}` : '';\n outputParts.push(` ${lineNumStr} | [${srcPosPadded.padEnd(14, ' ')}] | ${ctx.content}`);\n }\n\n outputParts.push(''); // Empty line between matches\n }\n\n // Add truncation message if needed\n if (truncated) {\n outputParts.push(`... (${totalMatches - maxMatches} more matches not shown)`);\n }\n\n return outputParts.join('\\n');\n}\n", "import { z } from 'zod';\nimport { defineTool } from './ToolDefinition.js';\nimport { ensureBeautified } from '../beautifier.js';\nimport { truncateCodeHighPerf, truncateLongLines } from '../truncator.js';\nimport { analyzeBindings, formatAnalysisResult } from '../analyzer.js';\n\n/**\n * Schema for find_usage_smart tool input validation\n */\nexport const FindUsageSmartInputSchema = z.object({\n file_path: z.string().describe('Path to the JavaScript file'),\n identifier: z.string().describe('Variable or function name to find'),\n line: z.number().int().positive().optional().describe(\n 'The line number where you see this variable. HIGHLY RECOMMENDED for precision in obfuscated code.'\n ),\n char_limit: z.number().int().min(50).default(300).describe('Character limit for string truncation'),\n max_line_chars: z.number().int().min(80).default(500).describe('Maximum characters per line'),\n});\n\n/**\n * find_usage_smart tool definition\n * Find all definitions and references of a variable/function using AST scope analysis.\n */\nexport const findUsageSmart = defineTool({\n name: 'find_usage_smart',\n description:\n 'Find all definitions and references of a variable/function using AST scope analysis. ' +\n 'Returns binding information grouped by scope with original source coordinates for setting breakpoints. ' +\n 'Useful for tracing variable usage in minified/obfuscated code with variable name reuse.',\n schema: {\n file_path: z.string().describe('Path to the JavaScript file'),\n identifier: z.string().describe('Variable or function name to find'),\n line: z.number().int().positive().optional().describe(\n 'The line number where you see this variable. HIGHLY RECOMMENDED for precision in obfuscated code.'\n ),\n char_limit: z.number().int().min(50).default(300).describe('Character limit for string truncation'),\n max_line_chars: z.number().int().min(80).default(500).describe('Maximum characters per line'),\n },\n handler: async (params) => {\n const { file_path, identifier, line, char_limit, max_line_chars } = params;\n\n // Beautify the file and get source map\n const beautifyResult = await ensureBeautified(file_path);\n const { code, rawMap } = beautifyResult;\n\n // Analyze bindings using full code (not truncated) for accurate AST analysis\n // When line is specified, increase maxReferences to 15 for targeted searches\n const analysisResult = await analyzeBindings(code, rawMap, identifier, {\n maxReferences: line ? 15 : 10,\n targetLine: line,\n });\n\n // Truncate the code for display purposes\n const truncatedCode = truncateCodeHighPerf(code, char_limit);\n const truncatedLines = truncatedCode.split('\\n');\n\n // Update line content in analysis result with truncated versions\n for (const binding of analysisResult.bindings) {\n // Update definition line content\n const defLineIdx = binding.definition.line - 1;\n if (defLineIdx >= 0 && defLineIdx < truncatedLines.length) {\n binding.definition.lineContent = truncatedLines[defLineIdx];\n }\n\n // Update reference line contents\n for (const ref of binding.references) {\n const refLineIdx = ref.line - 1;\n if (refLineIdx >= 0 && refLineIdx < truncatedLines.length) {\n ref.lineContent = truncatedLines[refLineIdx];\n }\n }\n }\n\n // Format the result\n let output = formatAnalysisResult(file_path, analysisResult, line ? 15 : 10);\n\n // Truncate long lines in output\n output = truncateLongLines(output, max_line_chars);\n\n return output;\n },\n});\n", "import { SourceMapConsumer } from 'source-map-js';\nimport { parse, ParserOptions } from '@babel/parser';\nimport type { NodePath } from '@babel/traverse';\nimport type { Identifier } from '@babel/types';\nimport type { SourceMap } from './beautifier.js';\n\n// Dynamic import for babel traverse to handle ESM/CJS interop\ntype TraverseFn = (\n parent: Parameters<typeof import('@babel/traverse').default>[0],\n opts?: Parameters<typeof import('@babel/traverse').default>[1],\n scope?: Parameters<typeof import('@babel/traverse').default>[2],\n state?: Parameters<typeof import('@babel/traverse').default>[3],\n parentPath?: Parameters<typeof import('@babel/traverse').default>[4]\n) => void;\n\nlet traverse: TraverseFn | null = null;\n\nasync function getTraverse(): Promise<TraverseFn> {\n if (!traverse) {\n const mod = await import('@babel/traverse');\n // Handle both ESM default export and CJS module.exports\n traverse = (mod.default?.default ?? mod.default) as TraverseFn;\n }\n return traverse;\n}\n\n/**\n * Original position from source map\n */\nexport interface OriginalPosition {\n line: number | null;\n column: number | null;\n}\n\n/**\n * Location information for a definition or reference\n */\nexport interface LocationInfo {\n /** Line number in beautified code (1-based) */\n line: number;\n /** Column number in beautified code (0-based) */\n column: number;\n /** Original file coordinates from source map */\n originalPosition: OriginalPosition;\n /** Content of the line containing this location */\n lineContent: string;\n}\n\n/**\n * Binding information for a variable/function\n */\nexport interface BindingInfo {\n /** Unique scope identifier */\n scopeUid: number;\n /** Binding kind (var, let, const, param, etc.) */\n kind: string;\n /** Definition location */\n definition: LocationInfo;\n /** All reference locations */\n references: LocationInfo[];\n /** Total reference count (before limiting) */\n totalReferences: number;\n /** The location that matched the target line (if targeted search) */\n hitLocation?: LocationInfo;\n}\n\n/**\n * Analysis result containing all bindings for an identifier\n */\nexport interface AnalysisResult {\n /** All bindings found for the identifier */\n bindings: BindingInfo[];\n /** The identifier that was searched */\n identifier: string;\n /** Whether this was a targeted (line-specific) search */\n isTargeted: boolean;\n /** The target line if specified */\n targetLine?: number;\n}\n\n\n/**\n * Default parser options for Babel\n */\nconst DEFAULT_PARSER_OPTIONS: ParserOptions = {\n sourceType: 'unambiguous',\n plugins: [\n 'jsx',\n 'typescript',\n 'classProperties',\n 'classPrivateProperties',\n 'classPrivateMethods',\n 'dynamicImport',\n 'optionalChaining',\n 'nullishCoalescingOperator',\n 'objectRestSpread',\n ],\n errorRecovery: true,\n};\n\n/**\n * Parse JavaScript/TypeScript code into an AST\n * @param code - Source code to parse\n * @returns Parsed AST\n * @throws Error if parsing fails\n */\nexport function parseCode(code: string) {\n try {\n return parse(code, DEFAULT_PARSER_OPTIONS);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Parse error: ${message}`);\n }\n}\n\n\n/**\n * Get original position for a location using source map consumer\n */\nfunction getOriginalPosition(\n consumer: SourceMapConsumer,\n line: number,\n column: number\n): OriginalPosition {\n const pos = consumer.originalPositionFor({ line, column });\n return {\n line: pos.line,\n column: pos.column,\n };\n}\n\n/**\n * Get line content from code by line number (1-based)\n */\nfunction getLineContent(lines: string[], lineNumber: number): string {\n if (lineNumber < 1 || lineNumber > lines.length) {\n return '';\n }\n return lines[lineNumber - 1];\n}\n\n/**\n * Create a LocationInfo object\n */\nfunction createLocationInfo(\n line: number,\n column: number,\n lines: string[],\n consumer: SourceMapConsumer\n): LocationInfo {\n return {\n line,\n column,\n originalPosition: getOriginalPosition(consumer, line, column),\n lineContent: getLineContent(lines, line),\n };\n}\n\n/**\n * Options for binding analysis\n */\nexport interface AnalyzeOptions {\n /** Maximum references to return per binding (default 10) */\n maxReferences?: number;\n /** Target line number for precise binding identification (1-based) */\n targetLine?: number;\n}\n\n/**\n * Analyze bindings for a specific identifier in the code\n * Uses Babel traverse to find all bindings and their references\n * \n * @param code - Beautified code to analyze\n * @param rawMap - Source map for coordinate mapping\n * @param identifier - Variable/function name to find\n * @param options - Analysis options\n * @returns Analysis result with all bindings\n */\nexport async function analyzeBindings(\n code: string,\n rawMap: SourceMap,\n identifier: string,\n options?: AnalyzeOptions\n): Promise<AnalysisResult> {\n const targetLine = options?.targetLine;\n const isTargeted = targetLine !== undefined;\n // Use 15 max references for targeted searches, 10 for regular searches\n const maxReferences = options?.maxReferences ?? (isTargeted ? 15 : 10);\n \n // Parse the code\n const ast = parseCode(code);\n \n // Split code into lines for content extraction\n const lines = code.split('\\n');\n \n // Create source map consumer\n const consumer = new SourceMapConsumer({\n ...rawMap,\n version: String(rawMap.version),\n });\n \n // Collect all bindings for the identifier\n const bindings: BindingInfo[] = [];\n const processedScopes = new Set<number>();\n \n // Get traverse function\n const traverse = await getTraverse();\n \n try {\n traverse(ast, {\n Identifier(path: NodePath<Identifier>) {\n // Only process if this is the identifier we're looking for\n if (path.node.name !== identifier) {\n return;\n }\n \n // For targeted search, check if this identifier is at the target line\n if (isTargeted) {\n const nodeLoc = path.node.loc;\n if (!nodeLoc || nodeLoc.start.line !== targetLine) {\n return;\n }\n }\n \n // Get the binding for this identifier\n const binding = path.scope.getBinding(identifier);\n if (!binding) {\n return;\n }\n \n // Get scope UID to avoid processing same binding multiple times\n const scopeUid = binding.scope.uid;\n if (processedScopes.has(scopeUid)) {\n return;\n }\n processedScopes.add(scopeUid);\n \n // Get definition location\n const defNode = binding.identifier;\n const defLoc = defNode.loc;\n if (!defLoc) {\n return;\n }\n \n const definition = createLocationInfo(\n defLoc.start.line,\n defLoc.start.column,\n lines,\n consumer\n );\n \n // Get all reference locations\n const allReferences: LocationInfo[] = [];\n for (const refPath of binding.referencePaths) {\n const refLoc = refPath.node.loc;\n if (!refLoc) {\n continue;\n }\n \n allReferences.push(\n createLocationInfo(\n refLoc.start.line,\n refLoc.start.column,\n lines,\n consumer\n )\n );\n }\n \n // Store total count before limiting\n const totalReferences = allReferences.length;\n \n // Limit references\n const limitedReferences = allReferences.slice(0, maxReferences);\n \n // Create hit location for targeted search\n let hitLocation: LocationInfo | undefined;\n if (isTargeted) {\n const nodeLoc = path.node.loc!;\n hitLocation = createLocationInfo(\n nodeLoc.start.line,\n nodeLoc.start.column,\n lines,\n consumer\n );\n }\n \n bindings.push({\n scopeUid,\n kind: binding.kind,\n definition,\n references: limitedReferences,\n totalReferences,\n hitLocation,\n });\n \n // For targeted search, stop after finding the first matching binding\n if (isTargeted) {\n path.stop();\n }\n },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Analysis error: ${message}`);\n }\n \n return {\n bindings,\n identifier,\n isTargeted,\n targetLine,\n };\n}\n\n\n/**\n * Format source position as \"L{line}:{column}\" or placeholder\n */\nexport function formatSourcePosition(line: number | null, column: number | null): string {\n if (line !== null && column !== null) {\n return `L${line}:${column}`;\n }\n return '';\n}\n\n/**\n * Check if two locations match (same line and column)\n */\nfunction locationsMatch(loc1: LocationInfo, loc2: LocationInfo): boolean {\n return loc1.line === loc2.line && loc1.column === loc2.column;\n}\n\n/**\n * Format analysis result for output\n * @param filePath - Path to the file\n * @param result - Analysis result\n * @param maxReferences - Maximum references shown per binding\n * @returns Formatted output string\n */\nexport function formatAnalysisResult(\n filePath: string,\n result: AnalysisResult,\n maxReferences: number = 10\n): string {\n const { bindings, identifier, isTargeted, targetLine } = result;\n \n const outputParts: string[] = [];\n \n // Header\n outputParts.push(`FILE: ${filePath}`);\n outputParts.push(`IDENTIFIER: \"${identifier}\"`);\n \n // Handle no bindings found\n if (bindings.length === 0) {\n if (isTargeted && targetLine !== undefined) {\n // Descriptive message for targeted search with no results\n outputParts.push(`BINDINGS: No binding found for \"${identifier}\" at line ${targetLine}`);\n outputParts.push(`The variable may be global, externally defined, or not present at this line.`);\n } else {\n outputParts.push('BINDINGS: No definitions or references found');\n }\n return outputParts.join('\\n');\n }\n \n // Display \"Targeted Scope\" header when isTargeted is true\n if (isTargeted) {\n outputParts.push(`BINDINGS: 1 found (Targeted Scope at line ${targetLine})`);\n } else {\n const scopeInfo = bindings.length > 1 ? ' (in different scopes)' : '';\n outputParts.push(`BINDINGS: ${bindings.length} found${scopeInfo}`);\n }\n outputParts.push('-'.repeat(85));\n \n // Format each binding\n for (let i = 0; i < bindings.length; i++) {\n const binding = bindings[i];\n \n // Use \"Targeted Scope\" label for targeted searches\n if (isTargeted) {\n outputParts.push(`=== Targeted Scope (${binding.kind}) ===`);\n } else {\n outputParts.push(`=== Scope #${i + 1} (${binding.kind}) ===`);\n }\n \n // Format definition - check if definition is the hit location\n const defIsHit = isTargeted && binding.hitLocation && \n locationsMatch(binding.definition, binding.hitLocation);\n const defPrefix = defIsHit ? '\uD83D\uDCCD Definition (hit):' : '\uD83D\uDCCD Definition:';\n outputParts.push(defPrefix);\n \n const defSrcPos = formatSourcePosition(\n binding.definition.originalPosition.line,\n binding.definition.originalPosition.column\n );\n const defSrcPosPadded = defSrcPos ? `Src ${defSrcPos}` : '';\n const defMarker = defIsHit ? ' \u25C0\u2500\u2500 hit' : '';\n outputParts.push(\n ` ${binding.definition.line} | [${defSrcPosPadded.padEnd(14, ' ')}] | ${binding.definition.lineContent}${defMarker}`\n );\n \n // Format references\n const totalRefs = binding.totalReferences;\n \n if (totalRefs === 0) {\n outputParts.push('\uD83D\uDD0E References: None');\n } else {\n outputParts.push(`\uD83D\uDD0E References (${totalRefs}):`);\n \n for (const ref of binding.references) {\n // Check if this reference is the hit location\n const refIsHit = isTargeted && binding.hitLocation && \n locationsMatch(ref, binding.hitLocation);\n \n const refSrcPos = formatSourcePosition(\n ref.originalPosition.line,\n ref.originalPosition.column\n );\n const refSrcPosPadded = refSrcPos ? `Src ${refSrcPos}` : '';\n const refMarker = refIsHit ? ' \u25C0\u2500\u2500 hit' : '';\n outputParts.push(\n ` ${ref.line} | [${refSrcPosPadded.padEnd(14, ' ')}] | ${ref.lineContent}${refMarker}`\n );\n }\n \n // Add truncation message if references were limited\n if (totalRefs > maxReferences) {\n const remaining = totalRefs - maxReferences;\n outputParts.push(` ... (${remaining} more references not shown)`);\n }\n }\n \n outputParts.push(''); // Empty line between bindings\n }\n \n return outputParts.join('\\n');\n}\n", "/**\n * Tool aggregation module\n * Collects all tool definitions and exports them as a unified array.\n */\n\nimport { readCodeSmart } from './readCodeSmart.js';\nimport { applyCustomTransform, ApplyCustomTransformInputSchema } from './applyCustomTransform.js';\nimport { searchCodeSmart, SearchCodeSmartInputSchema } from './searchCodeSmart.js';\nimport { findUsageSmart, FindUsageSmartInputSchema } from './findUsageSmart.js';\n\n/**\n * Array of all available MCP tool definitions.\n * To add a new tool:\n * 1. Create a new tool module in src/tools/\n * 2. Import it here\n * 3. Add it to this array\n */\nexport const tools = [\n readCodeSmart,\n applyCustomTransform,\n searchCodeSmart,\n findUsageSmart,\n] as const;\n\n// Re-export ToolDefinition interface and defineTool helper\nexport { ToolDefinition, defineTool } from './ToolDefinition.js';\n\n// Re-export input schemas for testing\nexport { ApplyCustomTransformInputSchema, SearchCodeSmartInputSchema, FindUsageSmartInputSchema };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["z", "code", "result", "z", "path", "fs", "basename", "z", "applyCustomTransform", "z", "SourceMapConsumer", "SourceMapConsumer", "formatSourcePosition", "z", "z", "SourceMapConsumer", "parse", "getOriginalPosition", "getLineContent", "traverse", "path", "formatSourcePosition", "z", "applyCustomTransform", "z"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reverse-craft/smart-fs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "MCP server for AI-assisted JavaScript reverse engineering - beautifies minified code and truncates long strings to prevent context overflow",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/server.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|
|
32
|
-
"url": "https://github.com/reverse-craft/smart-fs"
|
|
32
|
+
"url": "git+https://github.com/reverse-craft/smart-fs.git"
|
|
33
33
|
},
|
|
34
34
|
"homepage": "https://github.com/reverse-craft/smart-fs#readme",
|
|
35
35
|
"bugs": {
|