dev3000 0.0.81 → 0.0.82
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/mcp-server/.next/BUILD_ID +1 -1
- package/mcp-server/.next/build-manifest.json +2 -2
- package/mcp-server/.next/fallback-build-manifest.json +2 -2
- package/mcp-server/.next/prerender-manifest.json +3 -3
- package/mcp-server/.next/server/app/_global-error.html +2 -2
- package/mcp-server/.next/server/app/_global-error.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/mcp-server/.next/server/app/_not-found.html +1 -1
- package/mcp-server/.next/server/app/_not-found.rsc +2 -2
- package/mcp-server/.next/server/app/index.html +1 -1
- package/mcp-server/.next/server/app/index.rsc +2 -2
- package/mcp-server/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/mcp-server/.next/server/app/mcp/route.js +2 -2
- package/mcp-server/.next/server/app/page_client-reference-manifest.js +1 -1
- package/mcp-server/.next/server/app/video/[session]/page_client-reference-manifest.js +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__00592d3f._.js +64 -7
- package/mcp-server/.next/server/chunks/[root-of-the-server]__00592d3f._.js.map +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__177c72c6._.js +5 -23
- package/mcp-server/.next/server/chunks/[root-of-the-server]__177c72c6._.js.map +1 -1
- package/mcp-server/.next/server/server-reference-manifest.js +1 -1
- package/mcp-server/.next/server/server-reference-manifest.json +1 -1
- package/mcp-server/.next/static/chunks/{3d37ed424c6aaf63.css → 0cf268b98f36b0b5.css} +1 -1
- package/mcp-server/app/mcp/route.ts +16 -120
- package/mcp-server/app/mcp/tools.ts +345 -13
- package/package.json +1 -1
- /package/mcp-server/.next/static/{ccZG8o-A7VKCh1bOl43LW → A1zsECiQync8Ag1Q1mulr}/_buildManifest.js +0 -0
- /package/mcp-server/.next/static/{ccZG8o-A7VKCh1bOl43LW → A1zsECiQync8Ag1Q1mulr}/_clientMiddlewareManifest.json +0 -0
- /package/mcp-server/.next/static/{ccZG8o-A7VKCh1bOl43LW → A1zsECiQync8Ag1Q1mulr}/_ssgManifest.js +0 -0
|
@@ -14,20 +14,14 @@ export const TOOL_DESCRIPTIONS = {
|
|
|
14
14
|
fix_my_app:
|
|
15
15
|
"🔧 **THE ULTIMATE FIND→FIX→VERIFY MACHINE!** This tool doesn't just find bugs - it FIXES them! Pure dev3000 magic that identifies issues, provides exact fixes, and verifies everything works! 🪄\n\n🔥 **INSTANT FIXING SUPERPOWERS:**\n• Detects ALL error types: server crashes, browser errors, build failures, API issues, performance problems\n• Shows EXACT user interactions that triggered each error (clicks, navigation, etc.)\n• Provides EXACT fix code with file locations and line numbers\n• Guides you through implementing fixes step-by-step\n• Verifies fixes by replaying the same interactions that caused the error!\n\n📍 **INTERACTION-BASED VERIFICATION:**\n• Every error includes the user interactions that led to it\n• Use execute_browser_action to replay these exact interactions\n• Verify your fix works by confirming the error doesn't reoccur\n• Example: Error shows '[INTERACTION] Click at (450,300)' → After fix, use execute_browser_action(action='click', params={x:450, y:300}) to verify\n\n⚡ **3 ACTION MODES:**\n• FIX NOW: 'What's broken RIGHT NOW?' → Find and fix immediately\n• FIX REGRESSION: 'What broke during testing?' → Compare before/after and fix\n• FIX CONTINUOUSLY: 'Fix issues as they appear' → Monitor and fix proactively\n\n🎪 **THE FIX-IT WORKFLOW:**\n1️⃣ I FIND all issues with their triggering interactions\n2️⃣ I provide EXACT FIXES with code snippets\n3️⃣ You implement the fixes\n4️⃣ We REPLAY the interactions to VERIFY everything works\n\n💡 **PERFECT FOR:** 'fix my app' or 'debug my app' requests, error resolution, code repairs, making broken apps work again. This tool doesn't just identify problems - it SOLVES them with precise reproduction steps!",
|
|
16
16
|
|
|
17
|
-
create_integrated_workflow:
|
|
18
|
-
"🧠 **INTELLIGENT DEBUGGING ORCHESTRATOR** - Transform dev3000 from a standalone tool into the conductor of your debugging orchestra! This tool automatically detects available MCPs and creates integrated workflows that leverage the unique strengths of each tool.\n\n🎼 **ORCHESTRATION SUPERPOWERS:**\n• Auto-detects nextjs-dev and chrome-devtools MCPs when available\n• Creates 3-phase systematic debugging workflows\n• Provides AI-powered correlation between server/client/browser layers\n• Returns concrete function calls for Claude to execute across MCPs\n\n⚡ **3-PHASE WORKFLOW MAGIC:**\n• Phase 1: Parallel Data Collection (across all available MCPs)\n• Phase 2: Deep Targeted Analysis (sequential, context-aware)\n• Phase 3: Fix Implementation & Verification (orchestrated testing)\n\n🔗 **INTEGRATION BENEFITS:**\n• With nextjs-dev: Framework-specific build/runtime error context\n• With chrome-devtools: Precise browser state inspection\n• Together: Complete full-stack debugging coverage with AI correlation\n\n💡 **PERFECT FOR:** Multi-MCP environments where you want dev3000 to intelligently coordinate debugging across tools instead of using them individually. Makes other MCPs more powerful when used together!",
|
|
19
|
-
|
|
20
17
|
execute_browser_action:
|
|
21
18
|
"🌐 **INTELLIGENT BROWSER AUTOMATION** - Smart browser action routing that automatically delegates to chrome-devtools MCP when available for superior automation capabilities.\n\n🎯 **INTELLIGENT DELEGATION:**\n• Screenshots → chrome-devtools MCP (better quality, no conflicts)\n• Navigation → chrome-devtools MCP (more reliable page handling)\n• Clicks → chrome-devtools MCP (precise coordinate-based interaction)\n• JavaScript evaluation → chrome-devtools MCP (enhanced debugging)\n• Scrolling & typing → dev3000 fallback (specialized actions)\n\n⚡ **PROGRESSIVE ENHANCEMENT:**\n• Uses chrome-devtools MCP when available for best results\n• Falls back to dev3000's native implementation when chrome-devtools unavailable\n• Shares the same Chrome instance via CDP URL coordination\n• Eliminates browser conflicts between tools\n\n💡 **PERFECT FOR:** Browser automation that automatically chooses the best tool for each action, ensuring optimal results whether chrome-devtools MCP is available or not.",
|
|
22
19
|
|
|
23
|
-
discover_available_mcps:
|
|
24
|
-
"🔍 **PROACTIVE MCP DISCOVERY** - Automatically discover other MCPs running on the system using process detection and port pinging. No need to manually specify which MCPs are available!\n\n🎯 **DISCOVERY METHODS:**\n• Process Detection: Scans running processes for known MCP patterns\n• Port Pinging: Tests standard MCP ports with HTTP/WebSocket health checks\n• Cross-Platform: Works on macOS, Linux, and Windows\n\n⚡ **SMART DETECTION:**\n• Detects nextjs-dev, chrome-devtools, and other common MCPs\n• Fallback from process detection to port pinging\n• Logs all discovery attempts for transparency\n\n💡 **PERFECT FOR:** 'What MCPs are available?' or when you want dev3000 to automatically find and integrate with other debugging tools!",
|
|
25
|
-
|
|
26
|
-
get_mcp_capabilities:
|
|
27
|
-
"🔍 **MCP CAPABILITY INSPECTOR** - Discover and inspect the current capabilities of available MCPs (dev3000-chrome-devtools and dev3000-nextjs-dev). Shows dynamically discovered functions with descriptions and categories. Perfect for understanding what enhanced capabilities are available for augmented delegation.\n\n⚡ **DYNAMIC DISCOVERY:**\n• Introspects MCP logs and schemas to find available functions\n• Categorizes capabilities as 'advanced' vs 'basic'\n• Generates intelligent descriptions based on function names\n• Caches results for performance (5min TTL)\n\n🎯 **REAL-TIME UPDATES:**\n• Automatically adapts when MCPs add new capabilities\n• No manual maintenance required\n• Always shows current state of available tools\n\n💡 **PERFECT FOR:** Understanding what enhanced capabilities are currently available, debugging MCP integration issues, or planning augmented debugging workflows.",
|
|
28
|
-
|
|
29
20
|
analyze_visual_diff:
|
|
30
|
-
"🔍 **VISUAL DIFF ANALYZER** - Analyzes two screenshots to identify and describe visual differences. Returns detailed instructions for Claude to load and compare the images, focusing on what changed that could cause layout shifts.\n\n🎯 **WHAT IT PROVIDES:**\n• Direct instructions to load both images via Read tool\n• Context about what to look for\n• Guidance on identifying layout shift causes\n• Structured format for easy analysis\n\n💡 **PERFECT FOR:** Understanding what visual changes occurred between before/after frames in CLS detection, identifying elements that appeared/moved/resized."
|
|
21
|
+
"🔍 **VISUAL DIFF ANALYZER** - Analyzes two screenshots to identify and describe visual differences. Returns detailed instructions for Claude to load and compare the images, focusing on what changed that could cause layout shifts.\n\n🎯 **WHAT IT PROVIDES:**\n• Direct instructions to load both images via Read tool\n• Context about what to look for\n• Guidance on identifying layout shift causes\n• Structured format for easy analysis\n\n💡 **PERFECT FOR:** Understanding what visual changes occurred between before/after frames in CLS detection, identifying elements that appeared/moved/resized.",
|
|
22
|
+
|
|
23
|
+
find_component_source:
|
|
24
|
+
"🔍 **COMPONENT SOURCE FINDER** - Maps DOM elements to their source code by extracting the React component function and finding unique patterns to search for.\n\n🎯 **HOW IT WORKS:**\n• Inspects the element via Chrome DevTools Protocol\n• Extracts the React component function source using .toString()\n• Identifies unique code patterns (specific JSX, classNames, imports)\n• Returns targeted grep patterns to find the exact source file\n\n💡 **PERFECT FOR:** Finding which file contains the code for a specific element, especially useful for CLS debugging when you need to fix layout shifts in specific components."
|
|
31
25
|
}
|
|
32
26
|
|
|
33
27
|
// Types
|
|
@@ -671,6 +665,17 @@ export async function fixMyApp({
|
|
|
671
665
|
results.push(
|
|
672
666
|
` 💡 Use analyze_visual_diff tool with these URLs to get a detailed description of what changed`
|
|
673
667
|
)
|
|
668
|
+
|
|
669
|
+
// Extract CSS selector from element description (e.g., "Navigation header (<nav>)" -> "nav")
|
|
670
|
+
if (jank.element) {
|
|
671
|
+
const selectorMatch = jank.element.match(/<(\w+)>/)
|
|
672
|
+
if (selectorMatch) {
|
|
673
|
+
const selector = selectorMatch[1].toLowerCase()
|
|
674
|
+
results.push(
|
|
675
|
+
` 💡 Use find_component_source tool with selector "${selector}" to locate the source code`
|
|
676
|
+
)
|
|
677
|
+
}
|
|
678
|
+
}
|
|
674
679
|
}
|
|
675
680
|
})
|
|
676
681
|
|
|
@@ -1598,7 +1603,9 @@ export async function executeBrowserAction({
|
|
|
1598
1603
|
/^document\.querySelector\(['"][^'"]*['"]\)\.textContent$/,
|
|
1599
1604
|
/^document\.body\.scrollHeight$/,
|
|
1600
1605
|
/^window\.scrollY$/,
|
|
1601
|
-
/^window\.scrollX
|
|
1606
|
+
/^window\.scrollX$/,
|
|
1607
|
+
// Allow React Fiber inspection (read-only introspection)
|
|
1608
|
+
/^\s*\(function\(\)\s*\{[\s\S]*__reactFiber\$[\s\S]*\}\)\(\)\s*$/
|
|
1602
1609
|
]
|
|
1603
1610
|
|
|
1604
1611
|
if (!safeExpressions.some((regex) => regex.test(expression))) {
|
|
@@ -2736,10 +2743,10 @@ export async function analyzeVisualDiff(params: {
|
|
|
2736
2743
|
results.push("To analyze the visual differences between these two screenshots:")
|
|
2737
2744
|
results.push("")
|
|
2738
2745
|
results.push("**Step 1: Load the BEFORE image**")
|
|
2739
|
-
results.push(`Use the Read tool to load:
|
|
2746
|
+
results.push(`Use the Read tool to load: \`${beforeImageUrl}\``)
|
|
2740
2747
|
results.push("")
|
|
2741
2748
|
results.push("**Step 2: Load the AFTER image**")
|
|
2742
|
-
results.push(`Use the Read tool to load:
|
|
2749
|
+
results.push(`Use the Read tool to load: \`${afterImageUrl}\``)
|
|
2743
2750
|
results.push("")
|
|
2744
2751
|
results.push("**Step 3: Compare and describe the differences**")
|
|
2745
2752
|
|
|
@@ -2767,3 +2774,328 @@ export async function analyzeVisualDiff(params: {
|
|
|
2767
2774
|
content: [{ type: "text", text: results.join("\n") }]
|
|
2768
2775
|
}
|
|
2769
2776
|
}
|
|
2777
|
+
|
|
2778
|
+
export async function findComponentSource(params: {
|
|
2779
|
+
selector: string
|
|
2780
|
+
projectName?: string
|
|
2781
|
+
}): Promise<{ content: Array<{ type: "text"; text: string }> }> {
|
|
2782
|
+
const { selector } = params
|
|
2783
|
+
|
|
2784
|
+
try {
|
|
2785
|
+
const sessions = findActiveSessions()
|
|
2786
|
+
if (sessions.length === 0) {
|
|
2787
|
+
return {
|
|
2788
|
+
content: [
|
|
2789
|
+
{
|
|
2790
|
+
type: "text",
|
|
2791
|
+
text: "❌ **NO ACTIVE SESSIONS**\n\nNo active dev3000 sessions found. Make sure your app is running with dev3000."
|
|
2792
|
+
}
|
|
2793
|
+
]
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2797
|
+
const sessionData = JSON.parse(readFileSync(sessions[0].sessionFile, "utf-8"))
|
|
2798
|
+
let cdpUrl = sessionData.cdpUrl
|
|
2799
|
+
|
|
2800
|
+
if (!cdpUrl) {
|
|
2801
|
+
try {
|
|
2802
|
+
const response = await fetch("http://localhost:9222/json")
|
|
2803
|
+
const pages = await response.json()
|
|
2804
|
+
const activePage = pages.find(
|
|
2805
|
+
(page: { type: string; url: string }) => page.type === "page" && !page.url.startsWith("chrome://")
|
|
2806
|
+
)
|
|
2807
|
+
if (activePage) {
|
|
2808
|
+
cdpUrl = activePage.webSocketDebuggerUrl
|
|
2809
|
+
}
|
|
2810
|
+
} catch {
|
|
2811
|
+
return {
|
|
2812
|
+
content: [
|
|
2813
|
+
{
|
|
2814
|
+
type: "text",
|
|
2815
|
+
text: "❌ **NO CDP CONNECTION**\n\nFailed to find Chrome DevTools Protocol URL."
|
|
2816
|
+
}
|
|
2817
|
+
]
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2822
|
+
if (!cdpUrl) {
|
|
2823
|
+
return {
|
|
2824
|
+
content: [
|
|
2825
|
+
{
|
|
2826
|
+
type: "text",
|
|
2827
|
+
text: "❌ **NO CDP CONNECTION**\n\nNo Chrome DevTools Protocol URL found."
|
|
2828
|
+
}
|
|
2829
|
+
]
|
|
2830
|
+
}
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
// Execute the component extraction script
|
|
2834
|
+
const extractScript = `
|
|
2835
|
+
(function() {
|
|
2836
|
+
try {
|
|
2837
|
+
const element = document.querySelector(${JSON.stringify(selector)});
|
|
2838
|
+
if (!element) {
|
|
2839
|
+
return { error: "Element not found with selector: ${selector}" };
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
// Try to find React Fiber
|
|
2843
|
+
const fiberKey = Object.keys(element).find(k => k.startsWith("__reactFiber$"));
|
|
2844
|
+
if (!fiberKey) {
|
|
2845
|
+
return { error: "No React internals found - element may not be a React component" };
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2848
|
+
const fiber = element[fiberKey];
|
|
2849
|
+
let componentFunction = null;
|
|
2850
|
+
let componentName = "Unknown";
|
|
2851
|
+
|
|
2852
|
+
// Walk up the fiber tree to find a function component
|
|
2853
|
+
let current = fiber;
|
|
2854
|
+
let depth = 0;
|
|
2855
|
+
|
|
2856
|
+
while (current && depth < 10) {
|
|
2857
|
+
if (typeof current.type === 'function') {
|
|
2858
|
+
componentFunction = current.type;
|
|
2859
|
+
componentName = current.type.name || current.type.displayName || "Anonymous";
|
|
2860
|
+
break;
|
|
2861
|
+
}
|
|
2862
|
+
current = current.return;
|
|
2863
|
+
depth++;
|
|
2864
|
+
}
|
|
2865
|
+
|
|
2866
|
+
if (!componentFunction) {
|
|
2867
|
+
return { error: "Could not find component function in fiber tree" };
|
|
2868
|
+
}
|
|
2869
|
+
|
|
2870
|
+
// Get the source code
|
|
2871
|
+
const sourceCode = componentFunction.toString();
|
|
2872
|
+
|
|
2873
|
+
return {
|
|
2874
|
+
success: true,
|
|
2875
|
+
componentName,
|
|
2876
|
+
sourceCode
|
|
2877
|
+
};
|
|
2878
|
+
} catch (error) {
|
|
2879
|
+
return { error: error.message };
|
|
2880
|
+
}
|
|
2881
|
+
})()
|
|
2882
|
+
`
|
|
2883
|
+
|
|
2884
|
+
const result = await new Promise<unknown>((resolve, reject) => {
|
|
2885
|
+
const ws = new WebSocket(cdpUrl)
|
|
2886
|
+
let evalId: number | null = null
|
|
2887
|
+
let resolved = false
|
|
2888
|
+
|
|
2889
|
+
const timeout = setTimeout(() => {
|
|
2890
|
+
if (!resolved) {
|
|
2891
|
+
resolved = true
|
|
2892
|
+
ws.close()
|
|
2893
|
+
reject(new Error("CDP evaluation timeout after 5 seconds"))
|
|
2894
|
+
}
|
|
2895
|
+
}, 5000)
|
|
2896
|
+
|
|
2897
|
+
ws.on("open", async () => {
|
|
2898
|
+
try {
|
|
2899
|
+
ws.send(JSON.stringify({ id: 1, method: "Target.getTargets", params: {} }))
|
|
2900
|
+
|
|
2901
|
+
let messageId = 2
|
|
2902
|
+
|
|
2903
|
+
ws.on("message", async (data) => {
|
|
2904
|
+
const message = JSON.parse(data.toString())
|
|
2905
|
+
|
|
2906
|
+
if (message.id === 1) {
|
|
2907
|
+
const pageTarget = message.result.targetInfos.find((t: Record<string, unknown>) => t.type === "page")
|
|
2908
|
+
if (!pageTarget) {
|
|
2909
|
+
clearTimeout(timeout)
|
|
2910
|
+
resolved = true
|
|
2911
|
+
ws.close()
|
|
2912
|
+
reject(new Error("No page targets found"))
|
|
2913
|
+
return
|
|
2914
|
+
}
|
|
2915
|
+
|
|
2916
|
+
ws.send(
|
|
2917
|
+
JSON.stringify({
|
|
2918
|
+
id: messageId++,
|
|
2919
|
+
method: "Target.attachToTarget",
|
|
2920
|
+
params: { targetId: pageTarget.targetId, flatten: true }
|
|
2921
|
+
})
|
|
2922
|
+
)
|
|
2923
|
+
return
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
if (message.method === "Target.attachedToTarget") {
|
|
2927
|
+
evalId = messageId++
|
|
2928
|
+
ws.send(
|
|
2929
|
+
JSON.stringify({
|
|
2930
|
+
id: evalId,
|
|
2931
|
+
method: "Runtime.evaluate",
|
|
2932
|
+
params: { expression: extractScript, returnByValue: true }
|
|
2933
|
+
})
|
|
2934
|
+
)
|
|
2935
|
+
return
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
if (evalId !== null && message.id === evalId) {
|
|
2939
|
+
clearTimeout(timeout)
|
|
2940
|
+
resolved = true
|
|
2941
|
+
ws.close()
|
|
2942
|
+
if (message.error) {
|
|
2943
|
+
reject(new Error(message.error.message))
|
|
2944
|
+
} else {
|
|
2945
|
+
const value = message.result?.result?.value
|
|
2946
|
+
resolve(value)
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
})
|
|
2950
|
+
|
|
2951
|
+
ws.on("error", (err) => {
|
|
2952
|
+
clearTimeout(timeout)
|
|
2953
|
+
if (!resolved) {
|
|
2954
|
+
resolved = true
|
|
2955
|
+
reject(err)
|
|
2956
|
+
}
|
|
2957
|
+
})
|
|
2958
|
+
} catch (error) {
|
|
2959
|
+
clearTimeout(timeout)
|
|
2960
|
+
resolved = true
|
|
2961
|
+
ws.close()
|
|
2962
|
+
reject(error)
|
|
2963
|
+
}
|
|
2964
|
+
})
|
|
2965
|
+
|
|
2966
|
+
ws.on("error", (err) => {
|
|
2967
|
+
clearTimeout(timeout)
|
|
2968
|
+
if (!resolved) {
|
|
2969
|
+
resolved = true
|
|
2970
|
+
reject(err)
|
|
2971
|
+
}
|
|
2972
|
+
})
|
|
2973
|
+
})
|
|
2974
|
+
|
|
2975
|
+
const evalResult = result as
|
|
2976
|
+
| { error: string }
|
|
2977
|
+
| {
|
|
2978
|
+
success: true
|
|
2979
|
+
componentName: string
|
|
2980
|
+
sourceCode: string
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2983
|
+
if ("error" in evalResult) {
|
|
2984
|
+
return {
|
|
2985
|
+
content: [
|
|
2986
|
+
{
|
|
2987
|
+
type: "text",
|
|
2988
|
+
text: `❌ **ERROR EXTRACTING COMPONENT**\n\n${evalResult.error}\n\n💡 **TIPS:**\n• Make sure the selector matches an element on the page\n• Ensure the element is rendered by a React component\n• Try a simpler selector like 'nav' or '.header'`
|
|
2989
|
+
}
|
|
2990
|
+
]
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2994
|
+
if (!evalResult.success) {
|
|
2995
|
+
return {
|
|
2996
|
+
content: [
|
|
2997
|
+
{
|
|
2998
|
+
type: "text",
|
|
2999
|
+
text: "❌ **FAILED TO EXTRACT COMPONENT**\n\nUnexpected result format."
|
|
3000
|
+
}
|
|
3001
|
+
]
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
|
|
3005
|
+
// Extract unique patterns from the source code
|
|
3006
|
+
const { componentName, sourceCode } = evalResult
|
|
3007
|
+
const patterns: string[] = []
|
|
3008
|
+
|
|
3009
|
+
// Look for unique JSX patterns (excluding common ones like <div>, <span>)
|
|
3010
|
+
const jsxPattern = /<([A-Z][a-zA-Z0-9]*)/g
|
|
3011
|
+
const customComponents = new Set<string>()
|
|
3012
|
+
let jsxMatch = jsxPattern.exec(sourceCode)
|
|
3013
|
+
|
|
3014
|
+
while (jsxMatch !== null) {
|
|
3015
|
+
customComponents.add(jsxMatch[1])
|
|
3016
|
+
jsxMatch = jsxPattern.exec(sourceCode)
|
|
3017
|
+
}
|
|
3018
|
+
|
|
3019
|
+
// Look for unique className patterns
|
|
3020
|
+
const classNamePattern = /className=["']([^"']+)["']/g
|
|
3021
|
+
const classNames = new Set<string>()
|
|
3022
|
+
let classNameMatch = classNamePattern.exec(sourceCode)
|
|
3023
|
+
|
|
3024
|
+
while (classNameMatch !== null) {
|
|
3025
|
+
classNames.add(classNameMatch[1])
|
|
3026
|
+
classNameMatch = classNamePattern.exec(sourceCode)
|
|
3027
|
+
}
|
|
3028
|
+
|
|
3029
|
+
// Build search patterns
|
|
3030
|
+
const lines: string[] = []
|
|
3031
|
+
lines.push("🔍 **COMPONENT SOURCE FINDER**")
|
|
3032
|
+
lines.push("")
|
|
3033
|
+
lines.push(`**Selector:** \`${selector}\``)
|
|
3034
|
+
lines.push(`**Component:** ${componentName}`)
|
|
3035
|
+
lines.push("")
|
|
3036
|
+
|
|
3037
|
+
if (componentName !== "Anonymous") {
|
|
3038
|
+
patterns.push(`function ${componentName}`)
|
|
3039
|
+
patterns.push(`const ${componentName} =`)
|
|
3040
|
+
patterns.push(`export default function ${componentName}`)
|
|
3041
|
+
}
|
|
3042
|
+
|
|
3043
|
+
// Add unique component references
|
|
3044
|
+
if (customComponents.size > 0) {
|
|
3045
|
+
const uniqueComponents = Array.from(customComponents).filter(
|
|
3046
|
+
(name) => !["Fragment", "Suspense", "ErrorBoundary"].includes(name)
|
|
3047
|
+
)
|
|
3048
|
+
if (uniqueComponents.length > 0) {
|
|
3049
|
+
patterns.push(`<${uniqueComponents[0]}`)
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
|
|
3053
|
+
// Add unique classNames
|
|
3054
|
+
if (classNames.size > 0) {
|
|
3055
|
+
const firstClassName = Array.from(classNames)[0]
|
|
3056
|
+
patterns.push(`className="${firstClassName}"`)
|
|
3057
|
+
}
|
|
3058
|
+
|
|
3059
|
+
if (patterns.length === 0) {
|
|
3060
|
+
lines.push("⚠️ **NO UNIQUE PATTERNS FOUND**")
|
|
3061
|
+
lines.push("")
|
|
3062
|
+
lines.push("The component source code doesn't contain distinctive patterns to search for.")
|
|
3063
|
+
lines.push("You may need to manually search for the component.")
|
|
3064
|
+
} else {
|
|
3065
|
+
lines.push("📍 **SEARCH PATTERNS**")
|
|
3066
|
+
lines.push("")
|
|
3067
|
+
lines.push("Use these grep patterns to find the source file:")
|
|
3068
|
+
lines.push("")
|
|
3069
|
+
|
|
3070
|
+
for (const pattern of patterns.slice(0, 3)) {
|
|
3071
|
+
lines.push(`\`\`\``)
|
|
3072
|
+
lines.push(`grep -r "${pattern.replace(/"/g, '\\"')}" .`)
|
|
3073
|
+
lines.push(`\`\`\``)
|
|
3074
|
+
lines.push("")
|
|
3075
|
+
}
|
|
3076
|
+
|
|
3077
|
+
lines.push("💡 **TIP:** Start with the first pattern. If it returns multiple results, try combining patterns.")
|
|
3078
|
+
}
|
|
3079
|
+
|
|
3080
|
+
// Show a preview of the source code
|
|
3081
|
+
const preview = sourceCode.substring(0, 300)
|
|
3082
|
+
lines.push("")
|
|
3083
|
+
lines.push("**Source Code Preview:**")
|
|
3084
|
+
lines.push("```javascript")
|
|
3085
|
+
lines.push(`${preview}...`)
|
|
3086
|
+
lines.push("```")
|
|
3087
|
+
|
|
3088
|
+
return {
|
|
3089
|
+
content: [{ type: "text", text: lines.join("\n") }]
|
|
3090
|
+
}
|
|
3091
|
+
} catch (error) {
|
|
3092
|
+
return {
|
|
3093
|
+
content: [
|
|
3094
|
+
{
|
|
3095
|
+
type: "text",
|
|
3096
|
+
text: `❌ **ERROR**\n\n${error instanceof Error ? error.message : String(error)}`
|
|
3097
|
+
}
|
|
3098
|
+
]
|
|
3099
|
+
}
|
|
3100
|
+
}
|
|
3101
|
+
}
|
package/package.json
CHANGED
/package/mcp-server/.next/static/{ccZG8o-A7VKCh1bOl43LW → A1zsECiQync8Ag1Q1mulr}/_buildManifest.js
RENAMED
|
File without changes
|
|
File without changes
|
/package/mcp-server/.next/static/{ccZG8o-A7VKCh1bOl43LW → A1zsECiQync8Ag1Q1mulr}/_ssgManifest.js
RENAMED
|
File without changes
|