@react-component-selector-mcp/react 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # React Component Selector MCP
2
+
3
+ [![npm](https://img.shields.io/npm/v/@react-component-selector-mcp/react)](https://www.npmjs.com/package/@react-component-selector-mcp/react)
4
+
5
+ Select React components visually in the browser and expose selection data to Claude Code via [MCP](https://modelcontextprotocol.io/).
6
+
7
+ ![Claude Code showing selected component details](screenshots/Screenshot-1.png)
8
+
9
+ ## Quick Start
10
+
11
+ ### 1. Install
12
+
13
+ ```bash
14
+ npm install @react-component-selector-mcp/react
15
+ ```
16
+
17
+ ### 2. Wrap Your App
18
+
19
+ ```tsx
20
+ // In your root layout (app/layout.tsx, _app.tsx, or main.tsx)
21
+ import { ComponentPicker } from "@react-component-selector-mcp/react";
22
+
23
+ export default function RootLayout({ children }) {
24
+ return <ComponentPicker>{children}</ComponentPicker>;
25
+ }
26
+ ```
27
+
28
+ ### 3. Configure MCP
29
+
30
+ Create `.mcp.json` in your project root:
31
+
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "react-component-selector": {
36
+ "command": "npx",
37
+ "args": ["@react-component-selector-mcp/cli", "mcp"]
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ Restart Claude Code to load the MCP server.
44
+
45
+ ### Claude Code Setup
46
+
47
+ Copy this prompt to Claude Code to automate the setup:
48
+
49
+ ```
50
+ Set up react-component-selector-mcp in this project:
51
+ 1. Install @react-component-selector-mcp/react
52
+ 2. Wrap the root layout with <ComponentPicker>{children}</ComponentPicker>
53
+ 3. Create .mcp.json with: {"mcpServers":{"react-component-selector":{"command":"npx","args":["@react-component-selector-mcp/cli","mcp"]}}}
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ 1. Start your dev server and open the app in browser
59
+ 2. Press **Ctrl+Alt+C** (Windows/Linux) or **Cmd+Option+C** (Mac)
60
+ 3. Click any component to select it
61
+ 4. Ask Claude about the selected component
62
+
63
+ ### MCP Tools
64
+
65
+ | Tool | Description |
66
+ |------|-------------|
67
+ | `get_selected_component` | Returns the most recently selected component |
68
+ | `wait_for_selection` | Waits for user to select a component |
69
+ | `get_selection_history` | Returns recent selections |
70
+
71
+ <details>
72
+ <summary><strong>Troubleshooting</strong></summary>
73
+
74
+ ### Component not detected
75
+ - Ensure `ComponentPicker` wraps your entire app
76
+ - Verify React version is 18.0.0 or higher
77
+
78
+ ### MCP connection failed
79
+ - Check status: `npx @react-component-selector-mcp/cli status`
80
+ - Stop and restart: `npx @react-component-selector-mcp/cli stop`
81
+ - Restart Claude Code after changing MCP configuration
82
+
83
+ ### Source location not available
84
+ Source locations require development mode with `@babel/plugin-transform-react-jsx-source` (enabled by default in CRA, Next.js, Vite).
85
+
86
+ </details>
87
+
88
+ <details>
89
+ <summary><strong>CLI Reference</strong></summary>
90
+
91
+ ```bash
92
+ # Check daemon status
93
+ npx @react-component-selector-mcp/cli status
94
+
95
+ # Stop daemon
96
+ npx @react-component-selector-mcp/cli stop
97
+
98
+ # Custom ports (default: WebSocket 3333, API 3334)
99
+ npx @react-component-selector-mcp/cli mcp --ws-port 4444 --api-port 4445
100
+ ```
101
+
102
+ When using custom ports, update the component to match:
103
+
104
+ ```tsx
105
+ <ComponentPicker port={4444}>{children}</ComponentPicker>
106
+ ```
107
+
108
+ </details>
109
+
110
+ ## Contributing
111
+
112
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup.
113
+
114
+ ## License
115
+
116
+ [MIT](LICENSE)
package/dist/index.js CHANGED
@@ -122,6 +122,7 @@ function useWebSocketClient(options) {
122
122
  const reconnectTimeoutRef = useRef(null);
123
123
  const pingIntervalRef = useRef(null);
124
124
  const isCleaningUpRef = useRef(false);
125
+ const hasConnectedRef = useRef(false);
125
126
  const [connected, setConnected] = useState(false);
126
127
  const [clientId, setClientId] = useState(null);
127
128
  const sendSelection = useCallback((data) => {
@@ -137,17 +138,21 @@ function useWebSocketClient(options) {
137
138
  if (wsRef.current?.readyState === WebSocket.OPEN) {
138
139
  return;
139
140
  }
141
+ let connectTimeoutId = null;
140
142
  const connect = () => {
141
143
  if (wsRef.current?.readyState === WebSocket.OPEN || isCleaningUpRef.current) {
142
144
  return;
143
145
  }
144
146
  try {
145
147
  const ws = new WebSocket(`ws://localhost:${port}`);
148
+ let wasIntentionallyClosed = false;
146
149
  ws.onopen = () => {
147
150
  if (isCleaningUpRef.current) {
151
+ wasIntentionallyClosed = true;
148
152
  ws.close();
149
153
  return;
150
154
  }
155
+ hasConnectedRef.current = true;
151
156
  console.log("[component-picker] Connected to server");
152
157
  setConnected(true);
153
158
  onConnectionChangeRef.current?.(true);
@@ -158,7 +163,9 @@ function useWebSocketClient(options) {
158
163
  }, 25e3);
159
164
  };
160
165
  ws.onclose = () => {
161
- console.log("[component-picker] Disconnected from server");
166
+ if (hasConnectedRef.current && !wasIntentionallyClosed && !isCleaningUpRef.current) {
167
+ console.log("[component-picker] Disconnected from server");
168
+ }
162
169
  setConnected(false);
163
170
  setClientId(null);
164
171
  onConnectionChangeRef.current?.(false);
@@ -204,7 +211,6 @@ function useWebSocketClient(options) {
204
211
  };
205
212
  wsRef.current = ws;
206
213
  } catch (error) {
207
- console.error("[component-picker] Failed to connect:", error);
208
214
  if (!isCleaningUpRef.current) {
209
215
  reconnectTimeoutRef.current = setTimeout(() => {
210
216
  connect();
@@ -212,9 +218,18 @@ function useWebSocketClient(options) {
212
218
  }
213
219
  }
214
220
  };
215
- connect();
221
+ connectTimeoutId = setTimeout(() => {
222
+ connectTimeoutId = null;
223
+ if (!isCleaningUpRef.current) {
224
+ connect();
225
+ }
226
+ }, 100);
216
227
  return () => {
217
228
  isCleaningUpRef.current = true;
229
+ if (connectTimeoutId) {
230
+ clearTimeout(connectTimeoutId);
231
+ connectTimeoutId = null;
232
+ }
218
233
  if (reconnectTimeoutRef.current) {
219
234
  clearTimeout(reconnectTimeoutRef.current);
220
235
  reconnectTimeoutRef.current = null;
@@ -224,7 +239,9 @@ function useWebSocketClient(options) {
224
239
  pingIntervalRef.current = null;
225
240
  }
226
241
  if (wsRef.current) {
227
- wsRef.current.close();
242
+ if (wsRef.current.readyState === WebSocket.OPEN || wsRef.current.readyState === WebSocket.CONNECTING) {
243
+ wsRef.current.close();
244
+ }
228
245
  wsRef.current = null;
229
246
  }
230
247
  };
@@ -431,7 +448,6 @@ function useFiberInspector() {
431
448
  }
432
449
  function SelectionOverlay({
433
450
  enabled,
434
- message,
435
451
  onSelect,
436
452
  onCancel
437
453
  }) {
@@ -543,76 +559,46 @@ function SelectionOverlay({
543
559
  };
544
560
  }, [enabled, handleMouseMove, handleClick, handleKeyDown]);
545
561
  if (!enabled) return null;
546
- return /* @__PURE__ */ jsxs(Fragment, { children: [
547
- highlight && /* @__PURE__ */ jsx(
548
- "div",
549
- {
550
- "data-component-picker": "highlight",
551
- style: {
552
- position: "fixed",
553
- top: highlight.top,
554
- left: highlight.left,
555
- width: highlight.width,
556
- height: highlight.height,
557
- border: "2px solid #3b82f6",
558
- backgroundColor: "rgba(59, 130, 246, 0.1)",
559
- pointerEvents: "none",
560
- zIndex: 999998,
561
- boxSizing: "border-box"
562
- },
563
- children: /* @__PURE__ */ jsx(
564
- "div",
565
- {
566
- style: {
567
- position: "absolute",
568
- top: -24,
569
- left: -2,
570
- padding: "2px 8px",
571
- backgroundColor: "#3b82f6",
572
- color: "white",
573
- fontSize: "12px",
574
- fontFamily: "system-ui, sans-serif",
575
- fontWeight: 500,
576
- borderRadius: "4px 4px 0 0",
577
- whiteSpace: "nowrap",
578
- maxWidth: "300px",
579
- overflow: "hidden",
580
- textOverflow: "ellipsis"
581
- },
582
- children: highlight.componentName
583
- }
584
- )
585
- }
586
- ),
587
- /* @__PURE__ */ jsxs(
588
- "div",
589
- {
590
- "data-component-picker": "info-bar",
591
- style: {
592
- position: "fixed",
593
- top: 0,
594
- left: 0,
595
- right: 0,
596
- padding: "12px 16px",
597
- backgroundColor: "#3b82f6",
598
- color: "white",
599
- fontFamily: "system-ui, sans-serif",
600
- fontSize: "14px",
601
- textAlign: "center",
602
- zIndex: 999999,
603
- display: "flex",
604
- justifyContent: "center",
605
- alignItems: "center",
606
- gap: "16px",
607
- boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)"
608
- },
609
- children: [
610
- /* @__PURE__ */ jsx("span", { style: { fontWeight: 500 }, children: message || "Click a component to select it" }),
611
- /* @__PURE__ */ jsx("span", { style: { opacity: 0.8, fontSize: "12px" }, children: "Press ESC to cancel" })
612
- ]
613
- }
614
- )
615
- ] });
562
+ return /* @__PURE__ */ jsx(Fragment, { children: highlight && /* @__PURE__ */ jsx(
563
+ "div",
564
+ {
565
+ "data-component-picker": "highlight",
566
+ style: {
567
+ position: "fixed",
568
+ top: highlight.top,
569
+ left: highlight.left,
570
+ width: highlight.width,
571
+ height: highlight.height,
572
+ border: "2px solid #3b82f6",
573
+ backgroundColor: "rgba(59, 130, 246, 0.1)",
574
+ pointerEvents: "none",
575
+ zIndex: 999998,
576
+ boxSizing: "border-box"
577
+ },
578
+ children: /* @__PURE__ */ jsx(
579
+ "div",
580
+ {
581
+ style: {
582
+ position: "absolute",
583
+ top: -24,
584
+ left: -2,
585
+ padding: "2px 8px",
586
+ backgroundColor: "#3b82f6",
587
+ color: "white",
588
+ fontSize: "12px",
589
+ fontFamily: "system-ui, sans-serif",
590
+ fontWeight: 500,
591
+ borderRadius: "4px 4px 0 0",
592
+ whiteSpace: "nowrap",
593
+ maxWidth: "300px",
594
+ overflow: "hidden",
595
+ textOverflow: "ellipsis"
596
+ },
597
+ children: highlight.componentName
598
+ }
599
+ )
600
+ }
601
+ ) });
616
602
  }
617
603
 
618
604
  // src/utils/stackTraceParser.ts
@@ -885,7 +871,6 @@ function ComponentPickerImpl({
885
871
  SelectionOverlay,
886
872
  {
887
873
  enabled: isSelectionMode,
888
- message: selectionMessage,
889
874
  onSelect: handleSelect,
890
875
  onCancel: disableSelectionMode
891
876
  }
@@ -907,7 +892,7 @@ function ComponentPickerImpl({
907
892
  bottom: 16,
908
893
  right: 16,
909
894
  padding: "8px 12px",
910
- backgroundColor: !connected ? "#ef4444" : isSelectionMode ? "#f59e0b" : "#22c55e",
895
+ backgroundColor: !connected ? "#ef4444" : isSelectionMode ? "#3b82f6" : "#22c55e",
911
896
  color: "white",
912
897
  borderRadius: "9999px",
913
898
  fontSize: "12px",
@@ -932,11 +917,14 @@ function ComponentPickerImpl({
932
917
  height: 8,
933
918
  borderRadius: "50%",
934
919
  backgroundColor: "white",
935
- animation: !connected ? "pulse 2s infinite" : "none"
920
+ animation: !connected ? "pulse 2s infinite" : isSelectionMode ? "pulse 1s infinite" : "none"
936
921
  }
937
922
  }
938
923
  ),
939
- !connected ? "Connecting..." : isSelectionMode ? "Click a Component" : "Select Component"
924
+ !connected ? "Connecting..." : isSelectionMode ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
925
+ /* @__PURE__ */ jsx("span", { children: selectionMessage || "Click a component" }),
926
+ /* @__PURE__ */ jsx("span", { style: { opacity: 0.7, fontSize: "10px" }, children: "ESC to cancel" })
927
+ ] }) : "Select Component"
940
928
  ]
941
929
  }
942
930
  )
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../shared/src/schemas.ts","../../shared/src/messages.ts","../src/hooks/useWebSocketClient.ts","../src/hooks/useKeyboardShortcut.ts","../src/hooks/useSelectionMode.ts","../src/hooks/useFiberInspector.ts","../src/SelectionOverlay.tsx","../src/utils/stackTraceParser.ts","../src/utils/sourceLocationResolver.ts","../src/utils/componentMetadata.ts","../src/ComponentPicker.tsx"],"names":["z","useCallback","useEffect","useState","useRef","jsx","jsxs","Fragment"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\nexport const ComponentTypeSchema = z.enum(['function', 'class', 'forwardRef', 'memo']);\n\nexport const ComponentInfoSchema = z.object({\n name: z.string(),\n type: ComponentTypeSchema,\n});\n\nexport const SourceLocationSchema = z.object({\n filePath: z.string().nullable(),\n lineNumber: z.number().nullable(),\n columnNumber: z.number().nullable(),\n});\n\nexport const BoundingRectSchema = z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n top: z.number(),\n right: z.number(),\n bottom: z.number(),\n left: z.number(),\n});\n\nexport const DOMInfoSchema = z.object({\n tagName: z.string(),\n className: z.string().nullable(),\n boundingRect: BoundingRectSchema,\n});\n\nexport const SelectionContextSchema = z.object({\n pageUrl: z.string(),\n parentComponents: z.array(z.string()),\n});\n\nexport const SelectionDataSchema = z.object({\n id: z.string(),\n timestamp: z.number(),\n component: ComponentInfoSchema,\n source: SourceLocationSchema,\n props: z.record(z.unknown()),\n state: z.record(z.unknown()).nullable(),\n dom: DOMInfoSchema,\n context: SelectionContextSchema,\n});\n\nexport type SelectionDataInput = z.infer<typeof SelectionDataSchema>;\n","import { z } from 'zod';\nimport { SelectionDataSchema } from './schemas.js';\n\n/**\n * WebSocket message types for browser <-> CLI communication\n */\n\n// Message type enum\nexport const MessageTypeSchema = z.enum([\n 'selection',\n 'ping',\n 'pong',\n 'connect',\n 'disconnect',\n 'error',\n 'selectionMode',\n]);\n\nexport type MessageType = z.infer<typeof MessageTypeSchema>;\n\n// Base message structure\nconst BaseMessageSchema = z.object({\n type: MessageTypeSchema,\n timestamp: z.number(),\n});\n\n// Selection message - browser -> CLI\nexport const SelectionMessageSchema = BaseMessageSchema.extend({\n type: z.literal('selection'),\n payload: SelectionDataSchema,\n});\n\n// Ping/Pong for keepalive\nexport const PingMessageSchema = BaseMessageSchema.extend({\n type: z.literal('ping'),\n});\n\nexport const PongMessageSchema = BaseMessageSchema.extend({\n type: z.literal('pong'),\n});\n\n// Connection status messages\nexport const ConnectMessageSchema = BaseMessageSchema.extend({\n type: z.literal('connect'),\n payload: z.object({\n clientId: z.string(),\n userAgent: z.string().optional(),\n }),\n});\n\nexport const DisconnectMessageSchema = BaseMessageSchema.extend({\n type: z.literal('disconnect'),\n payload: z.object({\n clientId: z.string(),\n reason: z.string().optional(),\n }),\n});\n\n// Error message\nexport const ErrorMessageSchema = BaseMessageSchema.extend({\n type: z.literal('error'),\n payload: z.object({\n code: z.string(),\n message: z.string(),\n }),\n});\n\n// Selection mode toggle - CLI -> browser\nexport const SelectionModeMessageSchema = BaseMessageSchema.extend({\n type: z.literal('selectionMode'),\n payload: z.object({\n enabled: z.boolean(),\n message: z.string().optional(),\n }),\n});\n\n// Union of all message types\nexport const WebSocketMessageSchema = z.discriminatedUnion('type', [\n SelectionMessageSchema,\n PingMessageSchema,\n PongMessageSchema,\n ConnectMessageSchema,\n DisconnectMessageSchema,\n ErrorMessageSchema,\n SelectionModeMessageSchema,\n]);\n\nexport type WebSocketMessage = z.infer<typeof WebSocketMessageSchema>;\nexport type SelectionMessage = z.infer<typeof SelectionMessageSchema>;\nexport type PingMessage = z.infer<typeof PingMessageSchema>;\nexport type PongMessage = z.infer<typeof PongMessageSchema>;\nexport type ConnectMessage = z.infer<typeof ConnectMessageSchema>;\nexport type DisconnectMessage = z.infer<typeof DisconnectMessageSchema>;\nexport type ErrorMessage = z.infer<typeof ErrorMessageSchema>;\nexport type SelectionModeMessage = z.infer<typeof SelectionModeMessageSchema>;\n\n// Helper to create messages with overloads for type safety\nexport function createMessage(type: 'ping'): PingMessage;\nexport function createMessage(type: 'pong'): PongMessage;\nexport function createMessage(type: 'selection', payload: SelectionMessage['payload']): SelectionMessage;\nexport function createMessage(type: 'connect', payload: ConnectMessage['payload']): ConnectMessage;\nexport function createMessage(type: 'disconnect', payload: DisconnectMessage['payload']): DisconnectMessage;\nexport function createMessage(type: 'error', payload: ErrorMessage['payload']): ErrorMessage;\nexport function createMessage(type: 'selectionMode', payload: SelectionModeMessage['payload']): SelectionModeMessage;\nexport function createMessage(type: MessageType, payload?: unknown): WebSocketMessage {\n const base = { type, timestamp: Date.now() };\n if (payload !== undefined) {\n return { ...base, payload } as WebSocketMessage;\n }\n return base as WebSocketMessage;\n}\n","import { useEffect, useRef, useState, useCallback } from 'react';\nimport {\n WebSocketMessageSchema,\n createMessage,\n type SelectionData,\n type SelectionModeMessage,\n} from '@react-component-selector-mcp/shared';\n\nexport interface UseWebSocketClientOptions {\n port: number;\n onSelectionModeChange?: (enabled: boolean, message?: string) => void;\n onConnectionChange?: (connected: boolean) => void;\n}\n\nexport interface UseWebSocketClientReturn {\n connected: boolean;\n sendSelection: (data: SelectionData) => void;\n clientId: string | null;\n}\n\nexport function useWebSocketClient(\n options: UseWebSocketClientOptions\n): UseWebSocketClientReturn {\n const { port } = options;\n\n // Use refs for callbacks to avoid re-triggering effects\n const onSelectionModeChangeRef = useRef(options.onSelectionModeChange);\n const onConnectionChangeRef = useRef(options.onConnectionChange);\n onSelectionModeChangeRef.current = options.onSelectionModeChange;\n onConnectionChangeRef.current = options.onConnectionChange;\n\n const wsRef = useRef<WebSocket | null>(null);\n const reconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pingIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const isCleaningUpRef = useRef(false);\n\n const [connected, setConnected] = useState(false);\n const [clientId, setClientId] = useState<string | null>(null);\n\n const sendSelection = useCallback((data: SelectionData) => {\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n const message = createMessage('selection', data);\n wsRef.current.send(JSON.stringify(message));\n } else {\n console.warn('[component-picker] Cannot send selection - not connected');\n }\n }, []);\n\n useEffect(() => {\n // Reset cleanup flag on mount\n isCleaningUpRef.current = false;\n\n // Prevent running if already connected\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n return;\n }\n\n const connect = () => {\n if (wsRef.current?.readyState === WebSocket.OPEN || isCleaningUpRef.current) {\n return;\n }\n\n try {\n const ws = new WebSocket(`ws://localhost:${port}`);\n\n ws.onopen = () => {\n if (isCleaningUpRef.current) {\n ws.close();\n return;\n }\n console.log('[component-picker] Connected to server');\n setConnected(true);\n onConnectionChangeRef.current?.(true);\n\n // Start ping interval\n pingIntervalRef.current = setInterval(() => {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(createMessage('ping')));\n }\n }, 25000);\n };\n\n ws.onclose = () => {\n console.log('[component-picker] Disconnected from server');\n setConnected(false);\n setClientId(null);\n onConnectionChangeRef.current?.(false);\n\n if (pingIntervalRef.current) {\n clearInterval(pingIntervalRef.current);\n pingIntervalRef.current = null;\n }\n\n // Only attempt reconnection if not cleaning up\n if (!isCleaningUpRef.current) {\n reconnectTimeoutRef.current = setTimeout(() => {\n connect();\n }, 3000);\n }\n };\n\n ws.onerror = () => {\n // Error is logged but we don't need to do anything special\n // onclose will be called after onerror\n };\n\n ws.onmessage = (event: MessageEvent) => {\n try {\n const parsed = JSON.parse(event.data);\n const result = WebSocketMessageSchema.safeParse(parsed);\n\n if (!result.success) {\n console.warn('[component-picker] Invalid message:', result.error);\n return;\n }\n\n const message = result.data;\n\n switch (message.type) {\n case 'connect':\n setClientId(message.payload.clientId);\n break;\n\n case 'selectionMode':\n onSelectionModeChangeRef.current?.(\n (message as SelectionModeMessage).payload.enabled,\n (message as SelectionModeMessage).payload.message\n );\n break;\n\n case 'pong':\n // Keepalive acknowledged\n break;\n\n default:\n break;\n }\n } catch (error) {\n console.error('[component-picker] Error handling message:', error);\n }\n };\n\n wsRef.current = ws;\n } catch (error) {\n console.error('[component-picker] Failed to connect:', error);\n\n // Retry connection if not cleaning up\n if (!isCleaningUpRef.current) {\n reconnectTimeoutRef.current = setTimeout(() => {\n connect();\n }, 3000);\n }\n }\n };\n\n connect();\n\n return () => {\n isCleaningUpRef.current = true;\n\n if (reconnectTimeoutRef.current) {\n clearTimeout(reconnectTimeoutRef.current);\n reconnectTimeoutRef.current = null;\n }\n if (pingIntervalRef.current) {\n clearInterval(pingIntervalRef.current);\n pingIntervalRef.current = null;\n }\n if (wsRef.current) {\n wsRef.current.close();\n wsRef.current = null;\n }\n };\n }, [port]); // Only depend on port\n\n return {\n connected,\n sendSelection,\n clientId,\n };\n}\n","import { useEffect, useCallback } from 'react';\n\nexport interface UseKeyboardShortcutOptions {\n /** Key to press with modifiers (default: 'C') */\n key?: string;\n /** Callback when shortcut is triggered */\n onTrigger: () => void;\n /** Whether the shortcut is enabled */\n enabled?: boolean;\n}\n\n/**\n * Hook to handle Ctrl+Alt+C (Windows/Linux) / Cmd+Option+C (Mac) keyboard shortcut\n */\nexport function useKeyboardShortcut(options: UseKeyboardShortcutOptions): void {\n const { key = 'C', onTrigger, enabled = true } = options;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (!enabled) return;\n\n // Check for Ctrl+Alt+C (Windows/Linux) or Cmd+Option+C (Mac)\n const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;\n const modifierKey = isMac ? event.metaKey : event.ctrlKey;\n\n if (modifierKey && event.altKey && event.key.toUpperCase() === key.toUpperCase()) {\n event.preventDefault();\n event.stopPropagation();\n onTrigger();\n }\n },\n [key, onTrigger, enabled]\n );\n\n useEffect(() => {\n if (!enabled) return;\n\n window.addEventListener('keydown', handleKeyDown, true);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown, true);\n };\n }, [handleKeyDown, enabled]);\n}\n","import { useState, useCallback } from 'react';\n\nexport interface UseSelectionModeReturn {\n isSelectionMode: boolean;\n selectionMessage: string | undefined;\n enableSelectionMode: (message?: string) => void;\n disableSelectionMode: () => void;\n toggleSelectionMode: () => void;\n}\n\n/**\n * Hook to manage selection mode state\n */\nexport function useSelectionMode(): UseSelectionModeReturn {\n const [isSelectionMode, setIsSelectionMode] = useState(false);\n const [selectionMessage, setSelectionMessage] = useState<string | undefined>();\n\n const enableSelectionMode = useCallback((message?: string) => {\n setIsSelectionMode(true);\n setSelectionMessage(message);\n }, []);\n\n const disableSelectionMode = useCallback(() => {\n setIsSelectionMode(false);\n setSelectionMessage(undefined);\n }, []);\n\n const toggleSelectionMode = useCallback(() => {\n setIsSelectionMode((prev) => !prev);\n if (isSelectionMode) {\n setSelectionMessage(undefined);\n }\n }, [isSelectionMode]);\n\n return {\n isSelectionMode,\n selectionMessage,\n enableSelectionMode,\n disableSelectionMode,\n toggleSelectionMode,\n };\n}\n","import { useCallback } from 'react';\nimport type { ComponentInfo, ComponentType } from '@react-component-selector-mcp/shared';\n\n// React Fiber types (internal)\ninterface Fiber {\n tag: number;\n type: unknown;\n stateNode: unknown;\n return: Fiber | null;\n memoizedProps: Record<string, unknown>;\n memoizedState: unknown;\n _debugSource?: {\n fileName: string;\n lineNumber: number;\n columnNumber?: number;\n };\n}\n\n// React DevTools global hook\ninterface ReactDevToolsHook {\n renderers?: Map<number, {\n findFiberByHostInstance?: (element: Element) => Fiber | null;\n }>;\n}\n\ndeclare global {\n interface Window {\n __REACT_DEVTOOLS_GLOBAL_HOOK__?: ReactDevToolsHook;\n }\n}\n\n// React Fiber tags\nconst FIBER_TAGS = {\n FunctionComponent: 0,\n ClassComponent: 1,\n ForwardRef: 11,\n MemoComponent: 14,\n SimpleMemoComponent: 15,\n} as const;\n\nexport interface FiberData {\n componentInfo: ComponentInfo;\n props: Record<string, unknown>;\n state: Record<string, unknown> | null;\n parentComponents: string[];\n debugSource: {\n fileName: string | null;\n lineNumber: number | null;\n columnNumber: number | null;\n };\n}\n\nexport interface UseFiberInspectorReturn {\n getFiberFromElement: (element: HTMLElement) => Fiber | null;\n extractFiberData: (fiber: Fiber) => FiberData;\n findNearestComponentFiber: (fiber: Fiber) => Fiber | null;\n}\n\n/**\n * Hook for inspecting React Fiber internals\n */\nexport function useFiberInspector(): UseFiberInspectorReturn {\n /**\n * Get React Fiber from DOM element\n */\n const getFiberFromElement = useCallback((element: HTMLElement): Fiber | null => {\n // Try DevTools hook first (most reliable)\n if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers) {\n for (const renderer of window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.values()) {\n const fiber = renderer.findFiberByHostInstance?.(element);\n if (fiber) return fiber;\n }\n }\n\n // Fallback to internal keys\n const fiberKey = Object.keys(element).find(\n (key) => key.startsWith('__reactFiber$') || key.startsWith('__reactInternalInstance$')\n );\n\n if (fiberKey) {\n const fiber = (element as unknown as Record<string, Fiber | undefined>)[fiberKey];\n return fiber ?? null;\n }\n\n return null;\n }, []);\n\n /**\n * Get component type from fiber tag\n */\n const getComponentType = useCallback((fiber: Fiber): ComponentType => {\n switch (fiber.tag) {\n case FIBER_TAGS.ClassComponent:\n return 'class';\n case FIBER_TAGS.ForwardRef:\n return 'forwardRef';\n case FIBER_TAGS.MemoComponent:\n case FIBER_TAGS.SimpleMemoComponent:\n return 'memo';\n case FIBER_TAGS.FunctionComponent:\n default:\n return 'function';\n }\n }, []);\n\n /**\n * Get component name from fiber\n */\n const getComponentName = useCallback((fiber: Fiber): string => {\n const type = fiber.type;\n\n if (!type) return 'Unknown';\n\n // Function or class component\n if (typeof type === 'function') {\n const fn = type as { displayName?: string; name?: string };\n return fn.displayName || fn.name || 'Anonymous';\n }\n\n // ForwardRef\n if (typeof type === 'object' && type !== null) {\n const obj = type as { displayName?: string; render?: { displayName?: string; name?: string }; type?: { displayName?: string; name?: string } };\n\n if (obj.displayName) return obj.displayName;\n if (obj.render) return obj.render.displayName || obj.render.name || 'ForwardRef';\n if (obj.type) return obj.type.displayName || obj.type.name || 'Memo';\n }\n\n return 'Unknown';\n }, []);\n\n /**\n * Find the nearest user-defined component fiber (skip host/native elements)\n */\n const findNearestComponentFiber = useCallback((fiber: Fiber): Fiber | null => {\n let current: Fiber | null = fiber;\n\n while (current) {\n // Check if it's a user component (function, class, forwardRef, memo)\n const tag = current.tag;\n if (\n tag === FIBER_TAGS.FunctionComponent ||\n tag === FIBER_TAGS.ClassComponent ||\n tag === FIBER_TAGS.ForwardRef ||\n tag === FIBER_TAGS.MemoComponent ||\n tag === FIBER_TAGS.SimpleMemoComponent\n ) {\n const name = getComponentName(current);\n // Skip internal React components\n if (!name.startsWith('_') && name !== 'Unknown' && name !== 'Anonymous') {\n return current;\n }\n }\n\n current = current.return;\n }\n\n return null;\n }, [getComponentName]);\n\n /**\n * Get parent component names from fiber tree\n */\n const getParentComponents = useCallback(\n (fiber: Fiber): string[] => {\n const parents: string[] = [];\n let current = fiber.return;\n\n while (current && parents.length < 10) {\n const tag = current.tag;\n if (\n tag === FIBER_TAGS.FunctionComponent ||\n tag === FIBER_TAGS.ClassComponent ||\n tag === FIBER_TAGS.ForwardRef ||\n tag === FIBER_TAGS.MemoComponent ||\n tag === FIBER_TAGS.SimpleMemoComponent\n ) {\n const name = getComponentName(current);\n if (!name.startsWith('_') && name !== 'Unknown') {\n parents.push(name);\n }\n }\n current = current.return;\n }\n\n return parents;\n },\n [getComponentName]\n );\n\n /**\n * Safely serialize props (handle circular refs, functions, etc.)\n */\n const serializeProps = useCallback((props: Record<string, unknown>): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(props)) {\n // Skip React internal props\n if (key === 'children' || key === 'key' || key === 'ref') continue;\n\n try {\n if (typeof value === 'function') {\n result[key] = '[Function]';\n } else if (value instanceof Element) {\n result[key] = '[Element]';\n } else if (typeof value === 'object' && value !== null) {\n // Attempt JSON serialization to check for circular refs\n JSON.stringify(value);\n result[key] = value;\n } else {\n result[key] = value;\n }\n } catch {\n result[key] = '[Circular or Unserializable]';\n }\n }\n\n return result;\n }, []);\n\n /**\n * Extract state from class component\n */\n const extractState = useCallback((fiber: Fiber): Record<string, unknown> | null => {\n if (fiber.tag !== FIBER_TAGS.ClassComponent) {\n return null;\n }\n\n const instance = fiber.stateNode as { state?: Record<string, unknown> } | null;\n if (instance?.state) {\n try {\n JSON.stringify(instance.state);\n return instance.state;\n } catch {\n return { error: '[Unserializable state]' };\n }\n }\n\n return null;\n }, []);\n\n /**\n * Extract all relevant data from a fiber\n */\n const extractFiberData = useCallback(\n (fiber: Fiber): FiberData => {\n return {\n componentInfo: {\n name: getComponentName(fiber),\n type: getComponentType(fiber),\n },\n props: serializeProps(fiber.memoizedProps || {}),\n state: extractState(fiber),\n parentComponents: getParentComponents(fiber),\n debugSource: {\n fileName: fiber._debugSource?.fileName ?? null,\n lineNumber: fiber._debugSource?.lineNumber ?? null,\n columnNumber: fiber._debugSource?.columnNumber ?? null,\n },\n };\n },\n [getComponentName, getComponentType, serializeProps, extractState, getParentComponents]\n );\n\n return {\n getFiberFromElement,\n extractFiberData,\n findNearestComponentFiber,\n };\n}\n","import React, { useEffect, useState, useCallback, useRef } from 'react';\n\nexport interface SelectionOverlayProps {\n enabled: boolean;\n message?: string;\n onSelect: (element: HTMLElement) => void;\n onCancel: () => void;\n}\n\ninterface HighlightRect {\n top: number;\n left: number;\n width: number;\n height: number;\n componentName: string;\n}\n\n/**\n * Overlay component that highlights elements on hover and captures clicks\n */\nexport function SelectionOverlay({\n enabled,\n message,\n onSelect,\n onCancel,\n}: SelectionOverlayProps): React.ReactElement | null {\n const [highlight, setHighlight] = useState<HighlightRect | null>(null);\n const hoveredElementRef = useRef<HTMLElement | null>(null);\n\n // Get display name from element (prefer React component name, then className + text)\n const getComponentName = useCallback((element: HTMLElement): string => {\n // Try to get React component name from fiber first\n const fiberKey = Object.keys(element).find(\n (k) => k.startsWith('__reactFiber$') || k.startsWith('__reactInternalInstance$')\n );\n\n let reactName: string | null = null;\n if (fiberKey) {\n const fiber = (element as unknown as Record<string, unknown>)[fiberKey] as {\n type?: { displayName?: string; name?: string } | string;\n return?: { type?: { displayName?: string; name?: string } };\n };\n\n // Check current fiber\n if (fiber?.type && typeof fiber.type === 'function') {\n const fn = fiber.type as { displayName?: string; name?: string };\n reactName = fn.displayName || fn.name || null;\n }\n\n // Walk up to find nearest named component\n if (!reactName || reactName === 'div' || reactName === 'button') {\n let current = fiber;\n while (current?.return) {\n current = current.return as typeof fiber;\n if (current?.type && typeof current.type === 'function') {\n const fn = current.type as { displayName?: string; name?: string };\n const name = fn.displayName || fn.name;\n if (name && !['Fragment', 'Suspense', 'Provider', 'Consumer'].includes(name)) {\n reactName = name;\n break;\n }\n }\n }\n }\n }\n\n // Get text content for context (truncated)\n const textContent = element.textContent?.trim().slice(0, 20) || '';\n const textSuffix = textContent ? ` \"${textContent}${element.textContent && element.textContent.length > 20 ? '...' : ''}\"` : '';\n\n // If we found a React component name, use it\n if (reactName && !['div', 'button', 'span', 'p', 'h1', 'h2', 'h3'].includes(reactName.toLowerCase())) {\n return `<${reactName}>${textSuffix}`;\n }\n\n // Fall back to className with text\n if (element.className && typeof element.className === 'string' && element.className.trim()) {\n const classes = element.className.trim().split(/\\s+/)[0]; // Just first class\n return `.${classes}${textSuffix}`;\n }\n\n // Last resort: tag name with text\n return `<${element.tagName.toLowerCase()}>${textSuffix}`;\n }, []);\n\n // Handle mouse movement\n const handleMouseMove = useCallback(\n (event: MouseEvent) => {\n if (!enabled) return;\n\n const target = event.target as HTMLElement;\n\n // Skip our own overlay elements\n if (target.closest('[data-component-picker]')) {\n setHighlight(null);\n hoveredElementRef.current = null;\n return;\n }\n\n // Skip html, body, and script elements\n if (['HTML', 'BODY', 'SCRIPT', 'STYLE', 'NOSCRIPT'].includes(target.tagName)) {\n setHighlight(null);\n hoveredElementRef.current = null;\n return;\n }\n\n const rect = target.getBoundingClientRect();\n hoveredElementRef.current = target;\n\n setHighlight({\n top: rect.top,\n left: rect.left,\n width: rect.width,\n height: rect.height,\n componentName: getComponentName(target),\n });\n },\n [enabled, getComponentName]\n );\n\n // Handle click\n const handleClick = useCallback(\n (event: MouseEvent) => {\n if (!enabled) return;\n\n const target = event.target as HTMLElement;\n\n // Skip our own overlay elements\n if (target.closest('[data-component-picker]')) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n if (hoveredElementRef.current) {\n onSelect(hoveredElementRef.current);\n }\n },\n [enabled, onSelect]\n );\n\n // Handle escape key\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (!enabled) return;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n onCancel();\n }\n },\n [enabled, onCancel]\n );\n\n // Add event listeners\n useEffect(() => {\n if (!enabled) {\n setHighlight(null);\n hoveredElementRef.current = null;\n return;\n }\n\n document.addEventListener('mousemove', handleMouseMove, true);\n document.addEventListener('click', handleClick, true);\n document.addEventListener('keydown', handleKeyDown, true);\n\n // Change cursor\n document.body.style.cursor = 'crosshair';\n\n return () => {\n document.removeEventListener('mousemove', handleMouseMove, true);\n document.removeEventListener('click', handleClick, true);\n document.removeEventListener('keydown', handleKeyDown, true);\n document.body.style.cursor = '';\n };\n }, [enabled, handleMouseMove, handleClick, handleKeyDown]);\n\n if (!enabled) return null;\n\n return (\n <>\n {/* Highlight box */}\n {highlight && (\n <div\n data-component-picker=\"highlight\"\n style={{\n position: 'fixed',\n top: highlight.top,\n left: highlight.left,\n width: highlight.width,\n height: highlight.height,\n border: '2px solid #3b82f6',\n backgroundColor: 'rgba(59, 130, 246, 0.1)',\n pointerEvents: 'none',\n zIndex: 999998,\n boxSizing: 'border-box',\n }}\n >\n {/* Component name label */}\n <div\n style={{\n position: 'absolute',\n top: -24,\n left: -2,\n padding: '2px 8px',\n backgroundColor: '#3b82f6',\n color: 'white',\n fontSize: '12px',\n fontFamily: 'system-ui, sans-serif',\n fontWeight: 500,\n borderRadius: '4px 4px 0 0',\n whiteSpace: 'nowrap',\n maxWidth: '300px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {highlight.componentName}\n </div>\n </div>\n )}\n\n {/* Info bar at top */}\n <div\n data-component-picker=\"info-bar\"\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n padding: '12px 16px',\n backgroundColor: '#3b82f6',\n color: 'white',\n fontFamily: 'system-ui, sans-serif',\n fontSize: '14px',\n textAlign: 'center',\n zIndex: 999999,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: '16px',\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)',\n }}\n >\n <span style={{ fontWeight: 500 }}>\n {message || 'Click a component to select it'}\n </span>\n <span style={{ opacity: 0.8, fontSize: '12px' }}>Press ESC to cancel</span>\n </div>\n </>\n );\n}\n","/**\n * Cross-browser stack trace parser\n * Extracts source locations from JavaScript error stack traces\n */\n\nexport interface StackFrame {\n functionName: string | null;\n url: string;\n lineNumber: number;\n columnNumber: number;\n}\n\n/**\n * Parse an error stack trace into structured frames\n * Supports Chrome, Firefox, Safari, and Edge\n */\nexport function parseStackTrace(error: Error): StackFrame[] {\n const stack = error.stack;\n if (!stack) return [];\n\n const frames: StackFrame[] = [];\n const lines = stack.split('\\n');\n\n for (const line of lines) {\n const frame = parseStackLine(line);\n if (frame) {\n frames.push(frame);\n }\n }\n\n return frames;\n}\n\n/**\n * Parse a single stack trace line\n */\nfunction parseStackLine(line: string): StackFrame | null {\n // Chrome/Edge/Node format:\n // \" at FunctionName (http://localhost:3000/file.js:10:15)\"\n // \" at http://localhost:3000/file.js:10:15\"\n // \" at async FunctionName (http://localhost:3000/file.js:10:15)\"\n const chromeMatch = line.match(\n /^\\s*at\\s+(?:async\\s+)?(?:(\\S+)\\s+)?\\(?(https?:\\/\\/[^)]+|file:\\/\\/[^)]+):(\\d+):(\\d+)\\)?/\n );\n if (chromeMatch) {\n return {\n functionName: chromeMatch[1] || null,\n url: chromeMatch[2]!,\n lineNumber: parseInt(chromeMatch[3]!, 10),\n columnNumber: parseInt(chromeMatch[4]!, 10),\n };\n }\n\n // Firefox/Safari format:\n // \"functionName@http://localhost:3000/file.js:10:15\"\n // \"@http://localhost:3000/file.js:10:15\"\n const firefoxMatch = line.match(\n /^(?:(\\S*)@)?(https?:\\/\\/[^:]+|file:\\/\\/[^:]+):(\\d+):(\\d+)/\n );\n if (firefoxMatch) {\n return {\n functionName: firefoxMatch[1] || null,\n url: firefoxMatch[2]!,\n lineNumber: parseInt(firefoxMatch[3]!, 10),\n columnNumber: parseInt(firefoxMatch[4]!, 10),\n };\n }\n\n return null;\n}\n\n/**\n * Filter out internal React and framework frames\n */\nexport function filterInternalFrames(frames: StackFrame[]): StackFrame[] {\n const internalPatterns = [\n /node_modules/,\n /react-dom/,\n /react\\.production/,\n /react\\.development/,\n /scheduler/,\n /\\/_next\\/static\\/chunks\\/webpack/,\n /\\/__webpack_/,\n /\\/turbopack-/,\n // React internal function names\n /^(?:renderWithHooks|mountIndeterminateComponent|beginWork|performUnitOfWork)/,\n /^(?:callCallback|invokeGuardedCallbackDev|invokeGuardedCallback)/,\n /^(?:commitRoot|flushSync|batchedUpdates)/,\n ];\n\n return frames.filter((frame) => {\n // Check URL patterns\n for (const pattern of internalPatterns) {\n if (pattern.test(frame.url)) {\n return false;\n }\n }\n\n // Check function name patterns\n if (frame.functionName) {\n for (const pattern of internalPatterns) {\n if (pattern.test(frame.functionName)) {\n return false;\n }\n }\n }\n\n return true;\n });\n}\n\n/**\n * Get the first user component frame from the stack\n * This is typically the component that was clicked\n */\nexport function getComponentFrame(frames: StackFrame[]): StackFrame | null {\n const userFrames = filterInternalFrames(frames);\n return userFrames[0] || null;\n}\n\n/**\n * Create a stack trace at the current execution point\n * Useful for capturing where a component render is happening\n */\nexport function captureStackTrace(): StackFrame[] {\n const error = new Error();\n return parseStackTrace(error);\n}\n\n/**\n * Extract the script URL from a frame, normalizing various bundler formats\n */\nexport function normalizeScriptUrl(url: string): string {\n try {\n const urlObj = new URL(url);\n // Remove query params (like HMR timestamps)\n urlObj.search = '';\n urlObj.hash = '';\n return urlObj.href;\n } catch {\n return url;\n }\n}\n","/**\n * Source location resolver\n *\n * Attempts to resolve source file locations using two strategies:\n * 1. React's _debugSource (fastest, works with Babel-based builds)\n * 2. Stack trace parsing (fallback, less accurate)\n */\n\nimport type { SourceLocation } from '@react-component-selector-mcp/shared';\nimport { parseStackTrace, filterInternalFrames } from './stackTraceParser.js';\n\nexport interface DebugSource {\n fileName: string | null;\n lineNumber: number | null;\n columnNumber?: number | null;\n}\n\nexport interface Fiber {\n _debugSource?: DebugSource;\n type?: unknown;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any;\n}\n\n/**\n * Resolve source location using multiple strategies\n * This is the main entry point for source resolution\n */\nexport async function resolveSourceLocation(\n fiber: Fiber | null,\n _element?: HTMLElement\n): Promise<SourceLocation> {\n // Strategy 1: Try _debugSource first (fastest)\n const debugSourceResult = tryDebugSource(fiber);\n if (debugSourceResult.filePath) {\n return debugSourceResult;\n }\n\n // Strategy 2: Try stack trace parsing (fallback)\n const stackResult = tryStackTraceParsing();\n if (stackResult?.filePath) {\n return stackResult;\n }\n\n // No source information available\n return {\n filePath: null,\n lineNumber: null,\n columnNumber: null,\n };\n}\n\n/**\n * Strategy 1: Extract source from React's _debugSource\n * This is set by @babel/plugin-transform-react-jsx-source\n */\nfunction tryDebugSource(fiber: Fiber | null): SourceLocation {\n if (!fiber?._debugSource) {\n return { filePath: null, lineNumber: null, columnNumber: null };\n }\n\n const { fileName, lineNumber, columnNumber } = fiber._debugSource;\n\n if (!fileName) {\n return { filePath: null, lineNumber: null, columnNumber: null };\n }\n\n return {\n filePath: formatFilePath(fileName),\n lineNumber: lineNumber ?? null,\n columnNumber: columnNumber ?? null,\n };\n}\n\n/**\n * Strategy 2: Parse stack trace directly for source location\n * Less accurate but works as a last resort\n */\nfunction tryStackTraceParsing(): SourceLocation | null {\n try {\n const error = new Error();\n const frames = parseStackTrace(error);\n const userFrames = filterInternalFrames(frames);\n\n if (userFrames.length === 0) {\n return null;\n }\n\n const frame = userFrames[0]!;\n\n // Extract file path from URL\n const filePath = extractFilePathFromUrl(frame.url);\n if (!filePath) {\n return null;\n }\n\n return {\n filePath,\n lineNumber: frame.lineNumber,\n columnNumber: frame.columnNumber,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Extract relative file path from URL\n */\nfunction extractFilePathFromUrl(url: string): string | null {\n try {\n const urlObj = new URL(url);\n let path = urlObj.pathname;\n\n // Remove leading slash\n path = path.replace(/^\\/+/, '');\n\n // Handle various bundler prefixes\n path = path\n // Next.js\n .replace(/^_next\\/static\\/chunks\\//, '')\n .replace(/^_next\\/static\\/[^/]+\\/pages\\//, 'pages/')\n // Vite\n .replace(/^\\/@fs\\//, '')\n .replace(/^@vite\\//, '')\n // Webpack\n .replace(/^webpack:\\/\\/[^/]+\\//, '')\n // Turbopack\n .replace(/^\\[project\\]\\//, '');\n\n // Remove query params and hash (HMR timestamps etc)\n path = path.split('?')[0]?.split('#')[0] || path;\n\n // If the path looks like a hash (e.g., \"app-pages-internals.js\")\n // and doesn't have a recognizable extension path, it's not useful\n if (!path.includes('/') && !path.match(/\\.(tsx?|jsx?|mjs)$/)) {\n return null;\n }\n\n return path || null;\n } catch {\n return url;\n }\n}\n\n/**\n * Clean up file path for display\n */\nexport function formatFilePath(filePath: string | null): string | null {\n if (!filePath) return null;\n\n let cleaned = filePath\n // Remove webpack:// prefix\n .replace(/^webpack:\\/\\/[^/]+\\//, '')\n // Remove ./ prefix\n .replace(/^\\.\\//g, '')\n // Remove leading slashes\n .replace(/^\\/+/, '')\n // Remove turbopack prefix\n .replace(/^\\[project\\]\\//, '');\n\n // Normalize Windows paths to forward slashes\n cleaned = cleaned.replace(/\\\\/g, '/');\n\n return cleaned;\n}\n\n/**\n * Synchronous version for backward compatibility\n * Only uses _debugSource strategy\n */\nexport function resolveSourceLocationSync(\n debugSource: DebugSource | null\n): SourceLocation {\n if (!debugSource?.fileName) {\n return { filePath: null, lineNumber: null, columnNumber: null };\n }\n\n return {\n filePath: formatFilePath(debugSource.fileName),\n lineNumber: debugSource.lineNumber ?? null,\n columnNumber: debugSource.columnNumber ?? null,\n };\n}\n","import { nanoid } from 'nanoid';\nimport type { SelectionData, DOMInfo } from '@react-component-selector-mcp/shared';\nimport type { FiberData } from '../hooks/useFiberInspector.js';\nimport {\n resolveSourceLocation,\n formatFilePath,\n type Fiber,\n} from './sourceLocationResolver.js';\n\nexport interface MetadataOptions {\n /** The raw React fiber for enhanced source resolution */\n fiber?: Fiber | null;\n}\n\n/**\n * Extract DOM information from an element\n */\nexport function extractDOMInfo(element: HTMLElement): DOMInfo {\n const rect = element.getBoundingClientRect();\n\n return {\n tagName: element.tagName.toLowerCase(),\n className: element.className || null,\n boundingRect: {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n top: rect.top,\n right: rect.right,\n bottom: rect.bottom,\n left: rect.left,\n },\n };\n}\n\n/**\n * Build complete selection data from fiber data and DOM element\n */\nexport async function buildSelectionData(\n element: HTMLElement,\n fiberData: FiberData,\n options: MetadataOptions = {}\n): Promise<SelectionData> {\n // Resolve source location using multi-strategy approach\n // Pass fiber for enhanced source map resolution\n const fiber = options.fiber ?? {\n _debugSource: fiberData.debugSource,\n };\n const source = await resolveSourceLocation(fiber, element);\n\n // Build complete selection data\n const selectionData: SelectionData = {\n id: nanoid(),\n timestamp: Date.now(),\n component: fiberData.componentInfo,\n source: {\n filePath: formatFilePath(source.filePath),\n lineNumber: source.lineNumber,\n columnNumber: source.columnNumber,\n },\n props: fiberData.props,\n state: fiberData.state,\n dom: extractDOMInfo(element),\n context: {\n pageUrl: window.location.href,\n parentComponents: fiberData.parentComponents,\n },\n };\n\n return selectionData;\n}\n","import React, { useCallback, type ReactNode } from 'react';\nimport { useWebSocketClient } from './hooks/useWebSocketClient.js';\nimport { useKeyboardShortcut } from './hooks/useKeyboardShortcut.js';\nimport { useSelectionMode } from './hooks/useSelectionMode.js';\nimport { useFiberInspector } from './hooks/useFiberInspector.js';\nimport { SelectionOverlay } from './SelectionOverlay.js';\nimport { buildSelectionData } from './utils/componentMetadata.js';\n\nexport interface ComponentPickerProps {\n /** WebSocket server port (default: 3333) */\n port?: number;\n /** Children to wrap */\n children: ReactNode;\n /** Keyboard shortcut key (default: 'C' for Ctrl+Alt+C / Cmd+Option+C) */\n shortcutKey?: string;\n /** Called when connection status changes */\n onConnectionChange?: (connected: boolean) => void;\n /** Called when a component is selected */\n onSelect?: (componentName: string, filePath: string | null) => void;\n}\n\n/**\n * Wrapper component that enables component selection in development mode.\n * In production, this is a no-op passthrough.\n */\nexport function ComponentPicker(props: ComponentPickerProps): ReactNode {\n // No-op in production\n if (process.env.NODE_ENV !== 'development') {\n return props.children;\n }\n\n return <ComponentPickerImpl {...props} />;\n}\n\n/**\n * Implementation component (only rendered in development)\n */\nfunction ComponentPickerImpl({\n port = 3333,\n children,\n shortcutKey = 'C',\n onConnectionChange,\n onSelect,\n}: ComponentPickerProps): React.ReactElement {\n const { isSelectionMode, selectionMessage, enableSelectionMode, disableSelectionMode } =\n useSelectionMode();\n\n const { getFiberFromElement, extractFiberData, findNearestComponentFiber } = useFiberInspector();\n\n const { connected, sendSelection } = useWebSocketClient({\n port,\n onSelectionModeChange: (enabled, message) => {\n if (enabled) {\n enableSelectionMode(message);\n } else {\n disableSelectionMode();\n }\n },\n onConnectionChange,\n });\n\n // Handle keyboard shortcut\n useKeyboardShortcut({\n key: shortcutKey,\n onTrigger: () => {\n if (isSelectionMode) {\n disableSelectionMode();\n } else {\n enableSelectionMode();\n }\n },\n enabled: connected,\n });\n\n // Handle element selection\n const handleSelect = useCallback(\n async (element: HTMLElement) => {\n try {\n // Get fiber from element\n const fiber = getFiberFromElement(element);\n if (!fiber) {\n console.warn('[component-picker] No React fiber found for element');\n disableSelectionMode();\n return;\n }\n\n // Find nearest component fiber\n const componentFiber = findNearestComponentFiber(fiber);\n if (!componentFiber) {\n console.warn('[component-picker] No component fiber found');\n disableSelectionMode();\n return;\n }\n\n // Extract fiber data\n const fiberData = extractFiberData(componentFiber);\n\n // Build complete selection data (pass fiber for enhanced source resolution)\n const selectionData = await buildSelectionData(element, fiberData, {\n fiber: componentFiber,\n });\n\n // Send to server\n sendSelection(selectionData);\n\n // Notify callback\n onSelect?.(selectionData.component.name, selectionData.source.filePath);\n\n console.log(\n `[component-picker] Selected: ${selectionData.component.name}`,\n selectionData.source.filePath\n ? `at ${selectionData.source.filePath}:${selectionData.source.lineNumber}`\n : ''\n );\n } catch (error) {\n console.error('[component-picker] Selection error:', error);\n } finally {\n disableSelectionMode();\n }\n },\n [\n getFiberFromElement,\n findNearestComponentFiber,\n extractFiberData,\n sendSelection,\n disableSelectionMode,\n onSelect,\n ]\n );\n\n return (\n <>\n {children}\n <SelectionOverlay\n enabled={isSelectionMode}\n message={selectionMessage}\n onSelect={handleSelect}\n onCancel={disableSelectionMode}\n />\n {/* Selection toggle button (bottom-right corner) */}\n {process.env.NODE_ENV === 'development' && (\n <button\n data-component-picker=\"status\"\n onClick={() => {\n if (!connected) return;\n if (isSelectionMode) {\n disableSelectionMode();\n } else {\n enableSelectionMode();\n }\n }}\n style={{\n position: 'fixed',\n bottom: 16,\n right: 16,\n padding: '8px 12px',\n backgroundColor: !connected\n ? '#ef4444'\n : isSelectionMode\n ? '#f59e0b'\n : '#22c55e',\n color: 'white',\n borderRadius: '9999px',\n fontSize: '12px',\n fontFamily: 'system-ui, sans-serif',\n fontWeight: 500,\n zIndex: 999997,\n opacity: 0.9,\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)',\n border: 'none',\n cursor: connected ? 'pointer' : 'not-allowed',\n transition: 'background-color 0.2s ease',\n }}\n >\n <span\n style={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: 'white',\n animation: !connected ? 'pulse 2s infinite' : 'none',\n }}\n />\n {!connected\n ? 'Connecting...'\n : isSelectionMode\n ? 'Click a Component'\n : 'Select Component'}\n </button>\n )}\n </>\n );\n}\n"]}
1
+ {"version":3,"sources":["../../shared/src/schemas.ts","../../shared/src/messages.ts","../src/hooks/useWebSocketClient.ts","../src/hooks/useKeyboardShortcut.ts","../src/hooks/useSelectionMode.ts","../src/hooks/useFiberInspector.ts","../src/SelectionOverlay.tsx","../src/utils/stackTraceParser.ts","../src/utils/sourceLocationResolver.ts","../src/utils/componentMetadata.ts","../src/ComponentPicker.tsx"],"names":["z","useCallback","useEffect","useState","useRef","jsx","Fragment"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\nexport const ComponentTypeSchema = z.enum(['function', 'class', 'forwardRef', 'memo']);\n\nexport const ComponentInfoSchema = z.object({\n name: z.string(),\n type: ComponentTypeSchema,\n});\n\nexport const SourceLocationSchema = z.object({\n filePath: z.string().nullable(),\n lineNumber: z.number().nullable(),\n columnNumber: z.number().nullable(),\n});\n\nexport const BoundingRectSchema = z.object({\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n top: z.number(),\n right: z.number(),\n bottom: z.number(),\n left: z.number(),\n});\n\nexport const DOMInfoSchema = z.object({\n tagName: z.string(),\n className: z.string().nullable(),\n boundingRect: BoundingRectSchema,\n});\n\nexport const SelectionContextSchema = z.object({\n pageUrl: z.string(),\n parentComponents: z.array(z.string()),\n});\n\nexport const SelectionDataSchema = z.object({\n id: z.string(),\n timestamp: z.number(),\n component: ComponentInfoSchema,\n source: SourceLocationSchema,\n props: z.record(z.unknown()),\n state: z.record(z.unknown()).nullable(),\n dom: DOMInfoSchema,\n context: SelectionContextSchema,\n});\n\nexport type SelectionDataInput = z.infer<typeof SelectionDataSchema>;\n","import { z } from 'zod';\nimport { SelectionDataSchema } from './schemas.js';\n\n/**\n * WebSocket message types for browser <-> CLI communication\n */\n\n// Message type enum\nexport const MessageTypeSchema = z.enum([\n 'selection',\n 'ping',\n 'pong',\n 'connect',\n 'disconnect',\n 'error',\n 'selectionMode',\n]);\n\nexport type MessageType = z.infer<typeof MessageTypeSchema>;\n\n// Base message structure\nconst BaseMessageSchema = z.object({\n type: MessageTypeSchema,\n timestamp: z.number(),\n});\n\n// Selection message - browser -> CLI\nexport const SelectionMessageSchema = BaseMessageSchema.extend({\n type: z.literal('selection'),\n payload: SelectionDataSchema,\n});\n\n// Ping/Pong for keepalive\nexport const PingMessageSchema = BaseMessageSchema.extend({\n type: z.literal('ping'),\n});\n\nexport const PongMessageSchema = BaseMessageSchema.extend({\n type: z.literal('pong'),\n});\n\n// Connection status messages\nexport const ConnectMessageSchema = BaseMessageSchema.extend({\n type: z.literal('connect'),\n payload: z.object({\n clientId: z.string(),\n userAgent: z.string().optional(),\n }),\n});\n\nexport const DisconnectMessageSchema = BaseMessageSchema.extend({\n type: z.literal('disconnect'),\n payload: z.object({\n clientId: z.string(),\n reason: z.string().optional(),\n }),\n});\n\n// Error message\nexport const ErrorMessageSchema = BaseMessageSchema.extend({\n type: z.literal('error'),\n payload: z.object({\n code: z.string(),\n message: z.string(),\n }),\n});\n\n// Selection mode toggle - CLI -> browser\nexport const SelectionModeMessageSchema = BaseMessageSchema.extend({\n type: z.literal('selectionMode'),\n payload: z.object({\n enabled: z.boolean(),\n message: z.string().optional(),\n }),\n});\n\n// Union of all message types\nexport const WebSocketMessageSchema = z.discriminatedUnion('type', [\n SelectionMessageSchema,\n PingMessageSchema,\n PongMessageSchema,\n ConnectMessageSchema,\n DisconnectMessageSchema,\n ErrorMessageSchema,\n SelectionModeMessageSchema,\n]);\n\nexport type WebSocketMessage = z.infer<typeof WebSocketMessageSchema>;\nexport type SelectionMessage = z.infer<typeof SelectionMessageSchema>;\nexport type PingMessage = z.infer<typeof PingMessageSchema>;\nexport type PongMessage = z.infer<typeof PongMessageSchema>;\nexport type ConnectMessage = z.infer<typeof ConnectMessageSchema>;\nexport type DisconnectMessage = z.infer<typeof DisconnectMessageSchema>;\nexport type ErrorMessage = z.infer<typeof ErrorMessageSchema>;\nexport type SelectionModeMessage = z.infer<typeof SelectionModeMessageSchema>;\n\n// Helper to create messages with overloads for type safety\nexport function createMessage(type: 'ping'): PingMessage;\nexport function createMessage(type: 'pong'): PongMessage;\nexport function createMessage(type: 'selection', payload: SelectionMessage['payload']): SelectionMessage;\nexport function createMessage(type: 'connect', payload: ConnectMessage['payload']): ConnectMessage;\nexport function createMessage(type: 'disconnect', payload: DisconnectMessage['payload']): DisconnectMessage;\nexport function createMessage(type: 'error', payload: ErrorMessage['payload']): ErrorMessage;\nexport function createMessage(type: 'selectionMode', payload: SelectionModeMessage['payload']): SelectionModeMessage;\nexport function createMessage(type: MessageType, payload?: unknown): WebSocketMessage {\n const base = { type, timestamp: Date.now() };\n if (payload !== undefined) {\n return { ...base, payload } as WebSocketMessage;\n }\n return base as WebSocketMessage;\n}\n","import { useEffect, useRef, useState, useCallback } from 'react';\nimport {\n WebSocketMessageSchema,\n createMessage,\n type SelectionData,\n type SelectionModeMessage,\n} from '@react-component-selector-mcp/shared';\n\nexport interface UseWebSocketClientOptions {\n port: number;\n onSelectionModeChange?: (enabled: boolean, message?: string) => void;\n onConnectionChange?: (connected: boolean) => void;\n}\n\nexport interface UseWebSocketClientReturn {\n connected: boolean;\n sendSelection: (data: SelectionData) => void;\n clientId: string | null;\n}\n\nexport function useWebSocketClient(\n options: UseWebSocketClientOptions\n): UseWebSocketClientReturn {\n const { port } = options;\n\n // Use refs for callbacks to avoid re-triggering effects\n const onSelectionModeChangeRef = useRef(options.onSelectionModeChange);\n const onConnectionChangeRef = useRef(options.onConnectionChange);\n onSelectionModeChangeRef.current = options.onSelectionModeChange;\n onConnectionChangeRef.current = options.onConnectionChange;\n\n const wsRef = useRef<WebSocket | null>(null);\n const reconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pingIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const isCleaningUpRef = useRef(false);\n // Track if we've ever successfully connected (to suppress initial connection errors)\n const hasConnectedRef = useRef(false);\n\n const [connected, setConnected] = useState(false);\n const [clientId, setClientId] = useState<string | null>(null);\n\n const sendSelection = useCallback((data: SelectionData) => {\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n const message = createMessage('selection', data);\n wsRef.current.send(JSON.stringify(message));\n } else {\n console.warn('[component-picker] Cannot send selection - not connected');\n }\n }, []);\n\n useEffect(() => {\n // Reset cleanup flag on mount\n isCleaningUpRef.current = false;\n\n // Prevent running if already connected\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n return;\n }\n\n // Small delay to handle React Strict Mode double-invoke\n // This prevents \"WebSocket closed before connection established\" errors\n let connectTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const connect = () => {\n if (wsRef.current?.readyState === WebSocket.OPEN || isCleaningUpRef.current) {\n return;\n }\n\n try {\n const ws = new WebSocket(`ws://localhost:${port}`);\n // Track whether this specific connection was intentionally closed during cleanup\n let wasIntentionallyClosed = false;\n\n ws.onopen = () => {\n if (isCleaningUpRef.current) {\n wasIntentionallyClosed = true;\n ws.close();\n return;\n }\n hasConnectedRef.current = true;\n console.log('[component-picker] Connected to server');\n setConnected(true);\n onConnectionChangeRef.current?.(true);\n\n // Start ping interval\n pingIntervalRef.current = setInterval(() => {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(createMessage('ping')));\n }\n }, 25000);\n };\n\n ws.onclose = () => {\n // Only log disconnection if we were previously connected (not during initial failed attempts)\n if (hasConnectedRef.current && !wasIntentionallyClosed && !isCleaningUpRef.current) {\n console.log('[component-picker] Disconnected from server');\n }\n setConnected(false);\n setClientId(null);\n onConnectionChangeRef.current?.(false);\n\n if (pingIntervalRef.current) {\n clearInterval(pingIntervalRef.current);\n pingIntervalRef.current = null;\n }\n\n // Only attempt reconnection if not cleaning up\n if (!isCleaningUpRef.current) {\n reconnectTimeoutRef.current = setTimeout(() => {\n connect();\n }, 3000);\n }\n };\n\n ws.onerror = () => {\n // Silently handle errors - the UI shows connection status\n // onclose will be called after onerror for reconnection\n };\n\n ws.onmessage = (event: MessageEvent) => {\n try {\n const parsed = JSON.parse(event.data);\n const result = WebSocketMessageSchema.safeParse(parsed);\n\n if (!result.success) {\n console.warn('[component-picker] Invalid message:', result.error);\n return;\n }\n\n const message = result.data;\n\n switch (message.type) {\n case 'connect':\n setClientId(message.payload.clientId);\n break;\n\n case 'selectionMode':\n onSelectionModeChangeRef.current?.(\n (message as SelectionModeMessage).payload.enabled,\n (message as SelectionModeMessage).payload.message\n );\n break;\n\n case 'pong':\n // Keepalive acknowledged\n break;\n\n default:\n break;\n }\n } catch (error) {\n console.error('[component-picker] Error handling message:', error);\n }\n };\n\n wsRef.current = ws;\n } catch (error) {\n // Silently handle initial connection errors - UI shows status\n // Retry connection if not cleaning up\n if (!isCleaningUpRef.current) {\n reconnectTimeoutRef.current = setTimeout(() => {\n connect();\n }, 3000);\n }\n }\n };\n\n // Delay initial connection to handle React Strict Mode\n // In Strict Mode, effects run twice quickly - the delay allows cleanup to run before connection starts\n connectTimeoutId = setTimeout(() => {\n connectTimeoutId = null;\n if (!isCleaningUpRef.current) {\n connect();\n }\n }, 100);\n\n return () => {\n isCleaningUpRef.current = true;\n\n // Clear the initial connection timeout\n if (connectTimeoutId) {\n clearTimeout(connectTimeoutId);\n connectTimeoutId = null;\n }\n\n if (reconnectTimeoutRef.current) {\n clearTimeout(reconnectTimeoutRef.current);\n reconnectTimeoutRef.current = null;\n }\n if (pingIntervalRef.current) {\n clearInterval(pingIntervalRef.current);\n pingIntervalRef.current = null;\n }\n if (wsRef.current) {\n // Only close if not already closed/closing\n if (wsRef.current.readyState === WebSocket.OPEN ||\n wsRef.current.readyState === WebSocket.CONNECTING) {\n wsRef.current.close();\n }\n wsRef.current = null;\n }\n };\n }, [port]); // Only depend on port\n\n return {\n connected,\n sendSelection,\n clientId,\n };\n}\n","import { useEffect, useCallback } from 'react';\n\nexport interface UseKeyboardShortcutOptions {\n /** Key to press with modifiers (default: 'C') */\n key?: string;\n /** Callback when shortcut is triggered */\n onTrigger: () => void;\n /** Whether the shortcut is enabled */\n enabled?: boolean;\n}\n\n/**\n * Hook to handle Ctrl+Alt+C (Windows/Linux) / Cmd+Option+C (Mac) keyboard shortcut\n */\nexport function useKeyboardShortcut(options: UseKeyboardShortcutOptions): void {\n const { key = 'C', onTrigger, enabled = true } = options;\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (!enabled) return;\n\n // Check for Ctrl+Alt+C (Windows/Linux) or Cmd+Option+C (Mac)\n const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;\n const modifierKey = isMac ? event.metaKey : event.ctrlKey;\n\n if (modifierKey && event.altKey && event.key.toUpperCase() === key.toUpperCase()) {\n event.preventDefault();\n event.stopPropagation();\n onTrigger();\n }\n },\n [key, onTrigger, enabled]\n );\n\n useEffect(() => {\n if (!enabled) return;\n\n window.addEventListener('keydown', handleKeyDown, true);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown, true);\n };\n }, [handleKeyDown, enabled]);\n}\n","import { useState, useCallback } from 'react';\n\nexport interface UseSelectionModeReturn {\n isSelectionMode: boolean;\n selectionMessage: string | undefined;\n enableSelectionMode: (message?: string) => void;\n disableSelectionMode: () => void;\n toggleSelectionMode: () => void;\n}\n\n/**\n * Hook to manage selection mode state\n */\nexport function useSelectionMode(): UseSelectionModeReturn {\n const [isSelectionMode, setIsSelectionMode] = useState(false);\n const [selectionMessage, setSelectionMessage] = useState<string | undefined>();\n\n const enableSelectionMode = useCallback((message?: string) => {\n setIsSelectionMode(true);\n setSelectionMessage(message);\n }, []);\n\n const disableSelectionMode = useCallback(() => {\n setIsSelectionMode(false);\n setSelectionMessage(undefined);\n }, []);\n\n const toggleSelectionMode = useCallback(() => {\n setIsSelectionMode((prev) => !prev);\n if (isSelectionMode) {\n setSelectionMessage(undefined);\n }\n }, [isSelectionMode]);\n\n return {\n isSelectionMode,\n selectionMessage,\n enableSelectionMode,\n disableSelectionMode,\n toggleSelectionMode,\n };\n}\n","import { useCallback } from 'react';\nimport type { ComponentInfo, ComponentType } from '@react-component-selector-mcp/shared';\n\n// React Fiber types (internal)\ninterface Fiber {\n tag: number;\n type: unknown;\n stateNode: unknown;\n return: Fiber | null;\n memoizedProps: Record<string, unknown>;\n memoizedState: unknown;\n _debugSource?: {\n fileName: string;\n lineNumber: number;\n columnNumber?: number;\n };\n}\n\n// React DevTools global hook\ninterface ReactDevToolsHook {\n renderers?: Map<number, {\n findFiberByHostInstance?: (element: Element) => Fiber | null;\n }>;\n}\n\ndeclare global {\n interface Window {\n __REACT_DEVTOOLS_GLOBAL_HOOK__?: ReactDevToolsHook;\n }\n}\n\n// React Fiber tags\nconst FIBER_TAGS = {\n FunctionComponent: 0,\n ClassComponent: 1,\n ForwardRef: 11,\n MemoComponent: 14,\n SimpleMemoComponent: 15,\n} as const;\n\nexport interface FiberData {\n componentInfo: ComponentInfo;\n props: Record<string, unknown>;\n state: Record<string, unknown> | null;\n parentComponents: string[];\n debugSource: {\n fileName: string | null;\n lineNumber: number | null;\n columnNumber: number | null;\n };\n}\n\nexport interface UseFiberInspectorReturn {\n getFiberFromElement: (element: HTMLElement) => Fiber | null;\n extractFiberData: (fiber: Fiber) => FiberData;\n findNearestComponentFiber: (fiber: Fiber) => Fiber | null;\n}\n\n/**\n * Hook for inspecting React Fiber internals\n */\nexport function useFiberInspector(): UseFiberInspectorReturn {\n /**\n * Get React Fiber from DOM element\n */\n const getFiberFromElement = useCallback((element: HTMLElement): Fiber | null => {\n // Try DevTools hook first (most reliable)\n if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers) {\n for (const renderer of window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.values()) {\n const fiber = renderer.findFiberByHostInstance?.(element);\n if (fiber) return fiber;\n }\n }\n\n // Fallback to internal keys\n const fiberKey = Object.keys(element).find(\n (key) => key.startsWith('__reactFiber$') || key.startsWith('__reactInternalInstance$')\n );\n\n if (fiberKey) {\n const fiber = (element as unknown as Record<string, Fiber | undefined>)[fiberKey];\n return fiber ?? null;\n }\n\n return null;\n }, []);\n\n /**\n * Get component type from fiber tag\n */\n const getComponentType = useCallback((fiber: Fiber): ComponentType => {\n switch (fiber.tag) {\n case FIBER_TAGS.ClassComponent:\n return 'class';\n case FIBER_TAGS.ForwardRef:\n return 'forwardRef';\n case FIBER_TAGS.MemoComponent:\n case FIBER_TAGS.SimpleMemoComponent:\n return 'memo';\n case FIBER_TAGS.FunctionComponent:\n default:\n return 'function';\n }\n }, []);\n\n /**\n * Get component name from fiber\n */\n const getComponentName = useCallback((fiber: Fiber): string => {\n const type = fiber.type;\n\n if (!type) return 'Unknown';\n\n // Function or class component\n if (typeof type === 'function') {\n const fn = type as { displayName?: string; name?: string };\n return fn.displayName || fn.name || 'Anonymous';\n }\n\n // ForwardRef\n if (typeof type === 'object' && type !== null) {\n const obj = type as { displayName?: string; render?: { displayName?: string; name?: string }; type?: { displayName?: string; name?: string } };\n\n if (obj.displayName) return obj.displayName;\n if (obj.render) return obj.render.displayName || obj.render.name || 'ForwardRef';\n if (obj.type) return obj.type.displayName || obj.type.name || 'Memo';\n }\n\n return 'Unknown';\n }, []);\n\n /**\n * Find the nearest user-defined component fiber (skip host/native elements)\n */\n const findNearestComponentFiber = useCallback((fiber: Fiber): Fiber | null => {\n let current: Fiber | null = fiber;\n\n while (current) {\n // Check if it's a user component (function, class, forwardRef, memo)\n const tag = current.tag;\n if (\n tag === FIBER_TAGS.FunctionComponent ||\n tag === FIBER_TAGS.ClassComponent ||\n tag === FIBER_TAGS.ForwardRef ||\n tag === FIBER_TAGS.MemoComponent ||\n tag === FIBER_TAGS.SimpleMemoComponent\n ) {\n const name = getComponentName(current);\n // Skip internal React components\n if (!name.startsWith('_') && name !== 'Unknown' && name !== 'Anonymous') {\n return current;\n }\n }\n\n current = current.return;\n }\n\n return null;\n }, [getComponentName]);\n\n /**\n * Get parent component names from fiber tree\n */\n const getParentComponents = useCallback(\n (fiber: Fiber): string[] => {\n const parents: string[] = [];\n let current = fiber.return;\n\n while (current && parents.length < 10) {\n const tag = current.tag;\n if (\n tag === FIBER_TAGS.FunctionComponent ||\n tag === FIBER_TAGS.ClassComponent ||\n tag === FIBER_TAGS.ForwardRef ||\n tag === FIBER_TAGS.MemoComponent ||\n tag === FIBER_TAGS.SimpleMemoComponent\n ) {\n const name = getComponentName(current);\n if (!name.startsWith('_') && name !== 'Unknown') {\n parents.push(name);\n }\n }\n current = current.return;\n }\n\n return parents;\n },\n [getComponentName]\n );\n\n /**\n * Safely serialize props (handle circular refs, functions, etc.)\n */\n const serializeProps = useCallback((props: Record<string, unknown>): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(props)) {\n // Skip React internal props\n if (key === 'children' || key === 'key' || key === 'ref') continue;\n\n try {\n if (typeof value === 'function') {\n result[key] = '[Function]';\n } else if (value instanceof Element) {\n result[key] = '[Element]';\n } else if (typeof value === 'object' && value !== null) {\n // Attempt JSON serialization to check for circular refs\n JSON.stringify(value);\n result[key] = value;\n } else {\n result[key] = value;\n }\n } catch {\n result[key] = '[Circular or Unserializable]';\n }\n }\n\n return result;\n }, []);\n\n /**\n * Extract state from class component\n */\n const extractState = useCallback((fiber: Fiber): Record<string, unknown> | null => {\n if (fiber.tag !== FIBER_TAGS.ClassComponent) {\n return null;\n }\n\n const instance = fiber.stateNode as { state?: Record<string, unknown> } | null;\n if (instance?.state) {\n try {\n JSON.stringify(instance.state);\n return instance.state;\n } catch {\n return { error: '[Unserializable state]' };\n }\n }\n\n return null;\n }, []);\n\n /**\n * Extract all relevant data from a fiber\n */\n const extractFiberData = useCallback(\n (fiber: Fiber): FiberData => {\n return {\n componentInfo: {\n name: getComponentName(fiber),\n type: getComponentType(fiber),\n },\n props: serializeProps(fiber.memoizedProps || {}),\n state: extractState(fiber),\n parentComponents: getParentComponents(fiber),\n debugSource: {\n fileName: fiber._debugSource?.fileName ?? null,\n lineNumber: fiber._debugSource?.lineNumber ?? null,\n columnNumber: fiber._debugSource?.columnNumber ?? null,\n },\n };\n },\n [getComponentName, getComponentType, serializeProps, extractState, getParentComponents]\n );\n\n return {\n getFiberFromElement,\n extractFiberData,\n findNearestComponentFiber,\n };\n}\n","import React, { useEffect, useState, useCallback, useRef } from 'react';\n\nexport interface SelectionOverlayProps {\n enabled: boolean;\n onSelect: (element: HTMLElement) => void;\n onCancel: () => void;\n}\n\ninterface HighlightRect {\n top: number;\n left: number;\n width: number;\n height: number;\n componentName: string;\n}\n\n/**\n * Overlay component that highlights elements on hover and captures clicks\n */\nexport function SelectionOverlay({\n enabled,\n onSelect,\n onCancel,\n}: SelectionOverlayProps): React.ReactElement | null {\n const [highlight, setHighlight] = useState<HighlightRect | null>(null);\n const hoveredElementRef = useRef<HTMLElement | null>(null);\n\n // Get display name from element (prefer React component name, then className + text)\n const getComponentName = useCallback((element: HTMLElement): string => {\n // Try to get React component name from fiber first\n const fiberKey = Object.keys(element).find(\n (k) => k.startsWith('__reactFiber$') || k.startsWith('__reactInternalInstance$')\n );\n\n let reactName: string | null = null;\n if (fiberKey) {\n const fiber = (element as unknown as Record<string, unknown>)[fiberKey] as {\n type?: { displayName?: string; name?: string } | string;\n return?: { type?: { displayName?: string; name?: string } };\n };\n\n // Check current fiber\n if (fiber?.type && typeof fiber.type === 'function') {\n const fn = fiber.type as { displayName?: string; name?: string };\n reactName = fn.displayName || fn.name || null;\n }\n\n // Walk up to find nearest named component\n if (!reactName || reactName === 'div' || reactName === 'button') {\n let current = fiber;\n while (current?.return) {\n current = current.return as typeof fiber;\n if (current?.type && typeof current.type === 'function') {\n const fn = current.type as { displayName?: string; name?: string };\n const name = fn.displayName || fn.name;\n if (name && !['Fragment', 'Suspense', 'Provider', 'Consumer'].includes(name)) {\n reactName = name;\n break;\n }\n }\n }\n }\n }\n\n // Get text content for context (truncated)\n const textContent = element.textContent?.trim().slice(0, 20) || '';\n const textSuffix = textContent ? ` \"${textContent}${element.textContent && element.textContent.length > 20 ? '...' : ''}\"` : '';\n\n // If we found a React component name, use it\n if (reactName && !['div', 'button', 'span', 'p', 'h1', 'h2', 'h3'].includes(reactName.toLowerCase())) {\n return `<${reactName}>${textSuffix}`;\n }\n\n // Fall back to className with text\n if (element.className && typeof element.className === 'string' && element.className.trim()) {\n const classes = element.className.trim().split(/\\s+/)[0]; // Just first class\n return `.${classes}${textSuffix}`;\n }\n\n // Last resort: tag name with text\n return `<${element.tagName.toLowerCase()}>${textSuffix}`;\n }, []);\n\n // Handle mouse movement\n const handleMouseMove = useCallback(\n (event: MouseEvent) => {\n if (!enabled) return;\n\n const target = event.target as HTMLElement;\n\n // Skip our own overlay elements\n if (target.closest('[data-component-picker]')) {\n setHighlight(null);\n hoveredElementRef.current = null;\n return;\n }\n\n // Skip html, body, and script elements\n if (['HTML', 'BODY', 'SCRIPT', 'STYLE', 'NOSCRIPT'].includes(target.tagName)) {\n setHighlight(null);\n hoveredElementRef.current = null;\n return;\n }\n\n const rect = target.getBoundingClientRect();\n hoveredElementRef.current = target;\n\n setHighlight({\n top: rect.top,\n left: rect.left,\n width: rect.width,\n height: rect.height,\n componentName: getComponentName(target),\n });\n },\n [enabled, getComponentName]\n );\n\n // Handle click\n const handleClick = useCallback(\n (event: MouseEvent) => {\n if (!enabled) return;\n\n const target = event.target as HTMLElement;\n\n // Skip our own overlay elements\n if (target.closest('[data-component-picker]')) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n if (hoveredElementRef.current) {\n onSelect(hoveredElementRef.current);\n }\n },\n [enabled, onSelect]\n );\n\n // Handle escape key\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (!enabled) return;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n onCancel();\n }\n },\n [enabled, onCancel]\n );\n\n // Add event listeners\n useEffect(() => {\n if (!enabled) {\n setHighlight(null);\n hoveredElementRef.current = null;\n return;\n }\n\n document.addEventListener('mousemove', handleMouseMove, true);\n document.addEventListener('click', handleClick, true);\n document.addEventListener('keydown', handleKeyDown, true);\n\n // Change cursor\n document.body.style.cursor = 'crosshair';\n\n return () => {\n document.removeEventListener('mousemove', handleMouseMove, true);\n document.removeEventListener('click', handleClick, true);\n document.removeEventListener('keydown', handleKeyDown, true);\n document.body.style.cursor = '';\n };\n }, [enabled, handleMouseMove, handleClick, handleKeyDown]);\n\n if (!enabled) return null;\n\n return (\n <>\n {/* Highlight box */}\n {highlight && (\n <div\n data-component-picker=\"highlight\"\n style={{\n position: 'fixed',\n top: highlight.top,\n left: highlight.left,\n width: highlight.width,\n height: highlight.height,\n border: '2px solid #3b82f6',\n backgroundColor: 'rgba(59, 130, 246, 0.1)',\n pointerEvents: 'none',\n zIndex: 999998,\n boxSizing: 'border-box',\n }}\n >\n {/* Component name label */}\n <div\n style={{\n position: 'absolute',\n top: -24,\n left: -2,\n padding: '2px 8px',\n backgroundColor: '#3b82f6',\n color: 'white',\n fontSize: '12px',\n fontFamily: 'system-ui, sans-serif',\n fontWeight: 500,\n borderRadius: '4px 4px 0 0',\n whiteSpace: 'nowrap',\n maxWidth: '300px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {highlight.componentName}\n </div>\n </div>\n )}\n\n </>\n );\n}\n","/**\n * Cross-browser stack trace parser\n * Extracts source locations from JavaScript error stack traces\n */\n\nexport interface StackFrame {\n functionName: string | null;\n url: string;\n lineNumber: number;\n columnNumber: number;\n}\n\n/**\n * Parse an error stack trace into structured frames\n * Supports Chrome, Firefox, Safari, and Edge\n */\nexport function parseStackTrace(error: Error): StackFrame[] {\n const stack = error.stack;\n if (!stack) return [];\n\n const frames: StackFrame[] = [];\n const lines = stack.split('\\n');\n\n for (const line of lines) {\n const frame = parseStackLine(line);\n if (frame) {\n frames.push(frame);\n }\n }\n\n return frames;\n}\n\n/**\n * Parse a single stack trace line\n */\nfunction parseStackLine(line: string): StackFrame | null {\n // Chrome/Edge/Node format:\n // \" at FunctionName (http://localhost:3000/file.js:10:15)\"\n // \" at http://localhost:3000/file.js:10:15\"\n // \" at async FunctionName (http://localhost:3000/file.js:10:15)\"\n const chromeMatch = line.match(\n /^\\s*at\\s+(?:async\\s+)?(?:(\\S+)\\s+)?\\(?(https?:\\/\\/[^)]+|file:\\/\\/[^)]+):(\\d+):(\\d+)\\)?/\n );\n if (chromeMatch) {\n return {\n functionName: chromeMatch[1] || null,\n url: chromeMatch[2]!,\n lineNumber: parseInt(chromeMatch[3]!, 10),\n columnNumber: parseInt(chromeMatch[4]!, 10),\n };\n }\n\n // Firefox/Safari format:\n // \"functionName@http://localhost:3000/file.js:10:15\"\n // \"@http://localhost:3000/file.js:10:15\"\n const firefoxMatch = line.match(\n /^(?:(\\S*)@)?(https?:\\/\\/[^:]+|file:\\/\\/[^:]+):(\\d+):(\\d+)/\n );\n if (firefoxMatch) {\n return {\n functionName: firefoxMatch[1] || null,\n url: firefoxMatch[2]!,\n lineNumber: parseInt(firefoxMatch[3]!, 10),\n columnNumber: parseInt(firefoxMatch[4]!, 10),\n };\n }\n\n return null;\n}\n\n/**\n * Filter out internal React and framework frames\n */\nexport function filterInternalFrames(frames: StackFrame[]): StackFrame[] {\n const internalPatterns = [\n /node_modules/,\n /react-dom/,\n /react\\.production/,\n /react\\.development/,\n /scheduler/,\n /\\/_next\\/static\\/chunks\\/webpack/,\n /\\/__webpack_/,\n /\\/turbopack-/,\n // React internal function names\n /^(?:renderWithHooks|mountIndeterminateComponent|beginWork|performUnitOfWork)/,\n /^(?:callCallback|invokeGuardedCallbackDev|invokeGuardedCallback)/,\n /^(?:commitRoot|flushSync|batchedUpdates)/,\n ];\n\n return frames.filter((frame) => {\n // Check URL patterns\n for (const pattern of internalPatterns) {\n if (pattern.test(frame.url)) {\n return false;\n }\n }\n\n // Check function name patterns\n if (frame.functionName) {\n for (const pattern of internalPatterns) {\n if (pattern.test(frame.functionName)) {\n return false;\n }\n }\n }\n\n return true;\n });\n}\n\n/**\n * Get the first user component frame from the stack\n * This is typically the component that was clicked\n */\nexport function getComponentFrame(frames: StackFrame[]): StackFrame | null {\n const userFrames = filterInternalFrames(frames);\n return userFrames[0] || null;\n}\n\n/**\n * Create a stack trace at the current execution point\n * Useful for capturing where a component render is happening\n */\nexport function captureStackTrace(): StackFrame[] {\n const error = new Error();\n return parseStackTrace(error);\n}\n\n/**\n * Extract the script URL from a frame, normalizing various bundler formats\n */\nexport function normalizeScriptUrl(url: string): string {\n try {\n const urlObj = new URL(url);\n // Remove query params (like HMR timestamps)\n urlObj.search = '';\n urlObj.hash = '';\n return urlObj.href;\n } catch {\n return url;\n }\n}\n","/**\n * Source location resolver\n *\n * Attempts to resolve source file locations using two strategies:\n * 1. React's _debugSource (fastest, works with Babel-based builds)\n * 2. Stack trace parsing (fallback, less accurate)\n */\n\nimport type { SourceLocation } from '@react-component-selector-mcp/shared';\nimport { parseStackTrace, filterInternalFrames } from './stackTraceParser.js';\n\nexport interface DebugSource {\n fileName: string | null;\n lineNumber: number | null;\n columnNumber?: number | null;\n}\n\nexport interface Fiber {\n _debugSource?: DebugSource;\n type?: unknown;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any;\n}\n\n/**\n * Resolve source location using multiple strategies\n * This is the main entry point for source resolution\n */\nexport async function resolveSourceLocation(\n fiber: Fiber | null,\n _element?: HTMLElement\n): Promise<SourceLocation> {\n // Strategy 1: Try _debugSource first (fastest)\n const debugSourceResult = tryDebugSource(fiber);\n if (debugSourceResult.filePath) {\n return debugSourceResult;\n }\n\n // Strategy 2: Try stack trace parsing (fallback)\n const stackResult = tryStackTraceParsing();\n if (stackResult?.filePath) {\n return stackResult;\n }\n\n // No source information available\n return {\n filePath: null,\n lineNumber: null,\n columnNumber: null,\n };\n}\n\n/**\n * Strategy 1: Extract source from React's _debugSource\n * This is set by @babel/plugin-transform-react-jsx-source\n */\nfunction tryDebugSource(fiber: Fiber | null): SourceLocation {\n if (!fiber?._debugSource) {\n return { filePath: null, lineNumber: null, columnNumber: null };\n }\n\n const { fileName, lineNumber, columnNumber } = fiber._debugSource;\n\n if (!fileName) {\n return { filePath: null, lineNumber: null, columnNumber: null };\n }\n\n return {\n filePath: formatFilePath(fileName),\n lineNumber: lineNumber ?? null,\n columnNumber: columnNumber ?? null,\n };\n}\n\n/**\n * Strategy 2: Parse stack trace directly for source location\n * Less accurate but works as a last resort\n */\nfunction tryStackTraceParsing(): SourceLocation | null {\n try {\n const error = new Error();\n const frames = parseStackTrace(error);\n const userFrames = filterInternalFrames(frames);\n\n if (userFrames.length === 0) {\n return null;\n }\n\n const frame = userFrames[0]!;\n\n // Extract file path from URL\n const filePath = extractFilePathFromUrl(frame.url);\n if (!filePath) {\n return null;\n }\n\n return {\n filePath,\n lineNumber: frame.lineNumber,\n columnNumber: frame.columnNumber,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Extract relative file path from URL\n */\nfunction extractFilePathFromUrl(url: string): string | null {\n try {\n const urlObj = new URL(url);\n let path = urlObj.pathname;\n\n // Remove leading slash\n path = path.replace(/^\\/+/, '');\n\n // Handle various bundler prefixes\n path = path\n // Next.js\n .replace(/^_next\\/static\\/chunks\\//, '')\n .replace(/^_next\\/static\\/[^/]+\\/pages\\//, 'pages/')\n // Vite\n .replace(/^\\/@fs\\//, '')\n .replace(/^@vite\\//, '')\n // Webpack\n .replace(/^webpack:\\/\\/[^/]+\\//, '')\n // Turbopack\n .replace(/^\\[project\\]\\//, '');\n\n // Remove query params and hash (HMR timestamps etc)\n path = path.split('?')[0]?.split('#')[0] || path;\n\n // If the path looks like a hash (e.g., \"app-pages-internals.js\")\n // and doesn't have a recognizable extension path, it's not useful\n if (!path.includes('/') && !path.match(/\\.(tsx?|jsx?|mjs)$/)) {\n return null;\n }\n\n return path || null;\n } catch {\n return url;\n }\n}\n\n/**\n * Clean up file path for display\n */\nexport function formatFilePath(filePath: string | null): string | null {\n if (!filePath) return null;\n\n let cleaned = filePath\n // Remove webpack:// prefix\n .replace(/^webpack:\\/\\/[^/]+\\//, '')\n // Remove ./ prefix\n .replace(/^\\.\\//g, '')\n // Remove leading slashes\n .replace(/^\\/+/, '')\n // Remove turbopack prefix\n .replace(/^\\[project\\]\\//, '');\n\n // Normalize Windows paths to forward slashes\n cleaned = cleaned.replace(/\\\\/g, '/');\n\n return cleaned;\n}\n\n/**\n * Synchronous version for backward compatibility\n * Only uses _debugSource strategy\n */\nexport function resolveSourceLocationSync(\n debugSource: DebugSource | null\n): SourceLocation {\n if (!debugSource?.fileName) {\n return { filePath: null, lineNumber: null, columnNumber: null };\n }\n\n return {\n filePath: formatFilePath(debugSource.fileName),\n lineNumber: debugSource.lineNumber ?? null,\n columnNumber: debugSource.columnNumber ?? null,\n };\n}\n","import { nanoid } from 'nanoid';\nimport type { SelectionData, DOMInfo } from '@react-component-selector-mcp/shared';\nimport type { FiberData } from '../hooks/useFiberInspector.js';\nimport {\n resolveSourceLocation,\n formatFilePath,\n type Fiber,\n} from './sourceLocationResolver.js';\n\nexport interface MetadataOptions {\n /** The raw React fiber for enhanced source resolution */\n fiber?: Fiber | null;\n}\n\n/**\n * Extract DOM information from an element\n */\nexport function extractDOMInfo(element: HTMLElement): DOMInfo {\n const rect = element.getBoundingClientRect();\n\n return {\n tagName: element.tagName.toLowerCase(),\n className: element.className || null,\n boundingRect: {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n top: rect.top,\n right: rect.right,\n bottom: rect.bottom,\n left: rect.left,\n },\n };\n}\n\n/**\n * Build complete selection data from fiber data and DOM element\n */\nexport async function buildSelectionData(\n element: HTMLElement,\n fiberData: FiberData,\n options: MetadataOptions = {}\n): Promise<SelectionData> {\n // Resolve source location using multi-strategy approach\n // Pass fiber for enhanced source map resolution\n const fiber = options.fiber ?? {\n _debugSource: fiberData.debugSource,\n };\n const source = await resolveSourceLocation(fiber, element);\n\n // Build complete selection data\n const selectionData: SelectionData = {\n id: nanoid(),\n timestamp: Date.now(),\n component: fiberData.componentInfo,\n source: {\n filePath: formatFilePath(source.filePath),\n lineNumber: source.lineNumber,\n columnNumber: source.columnNumber,\n },\n props: fiberData.props,\n state: fiberData.state,\n dom: extractDOMInfo(element),\n context: {\n pageUrl: window.location.href,\n parentComponents: fiberData.parentComponents,\n },\n };\n\n return selectionData;\n}\n","import React, { useCallback, type ReactNode } from 'react';\nimport { useWebSocketClient } from './hooks/useWebSocketClient.js';\nimport { useKeyboardShortcut } from './hooks/useKeyboardShortcut.js';\nimport { useSelectionMode } from './hooks/useSelectionMode.js';\nimport { useFiberInspector } from './hooks/useFiberInspector.js';\nimport { SelectionOverlay } from './SelectionOverlay.js';\nimport { buildSelectionData } from './utils/componentMetadata.js';\n\nexport interface ComponentPickerProps {\n /** WebSocket server port (default: 3333) */\n port?: number;\n /** Children to wrap */\n children: ReactNode;\n /** Keyboard shortcut key (default: 'C' for Ctrl+Alt+C / Cmd+Option+C) */\n shortcutKey?: string;\n /** Called when connection status changes */\n onConnectionChange?: (connected: boolean) => void;\n /** Called when a component is selected */\n onSelect?: (componentName: string, filePath: string | null) => void;\n}\n\n/**\n * Wrapper component that enables component selection in development mode.\n * In production, this is a no-op passthrough.\n */\nexport function ComponentPicker(props: ComponentPickerProps): ReactNode {\n // No-op in production\n if (process.env.NODE_ENV !== 'development') {\n return props.children;\n }\n\n return <ComponentPickerImpl {...props} />;\n}\n\n/**\n * Implementation component (only rendered in development)\n */\nfunction ComponentPickerImpl({\n port = 3333,\n children,\n shortcutKey = 'C',\n onConnectionChange,\n onSelect,\n}: ComponentPickerProps): React.ReactElement {\n const { isSelectionMode, selectionMessage, enableSelectionMode, disableSelectionMode } =\n useSelectionMode();\n\n const { getFiberFromElement, extractFiberData, findNearestComponentFiber } = useFiberInspector();\n\n const { connected, sendSelection } = useWebSocketClient({\n port,\n onSelectionModeChange: (enabled, message) => {\n if (enabled) {\n enableSelectionMode(message);\n } else {\n disableSelectionMode();\n }\n },\n onConnectionChange,\n });\n\n // Handle keyboard shortcut\n useKeyboardShortcut({\n key: shortcutKey,\n onTrigger: () => {\n if (isSelectionMode) {\n disableSelectionMode();\n } else {\n enableSelectionMode();\n }\n },\n enabled: connected,\n });\n\n // Handle element selection\n const handleSelect = useCallback(\n async (element: HTMLElement) => {\n try {\n // Get fiber from element\n const fiber = getFiberFromElement(element);\n if (!fiber) {\n console.warn('[component-picker] No React fiber found for element');\n disableSelectionMode();\n return;\n }\n\n // Find nearest component fiber\n const componentFiber = findNearestComponentFiber(fiber);\n if (!componentFiber) {\n console.warn('[component-picker] No component fiber found');\n disableSelectionMode();\n return;\n }\n\n // Extract fiber data\n const fiberData = extractFiberData(componentFiber);\n\n // Build complete selection data (pass fiber for enhanced source resolution)\n const selectionData = await buildSelectionData(element, fiberData, {\n fiber: componentFiber,\n });\n\n // Send to server\n sendSelection(selectionData);\n\n // Notify callback\n onSelect?.(selectionData.component.name, selectionData.source.filePath);\n\n console.log(\n `[component-picker] Selected: ${selectionData.component.name}`,\n selectionData.source.filePath\n ? `at ${selectionData.source.filePath}:${selectionData.source.lineNumber}`\n : ''\n );\n } catch (error) {\n console.error('[component-picker] Selection error:', error);\n } finally {\n disableSelectionMode();\n }\n },\n [\n getFiberFromElement,\n findNearestComponentFiber,\n extractFiberData,\n sendSelection,\n disableSelectionMode,\n onSelect,\n ]\n );\n\n return (\n <>\n {children}\n <SelectionOverlay\n enabled={isSelectionMode}\n onSelect={handleSelect}\n onCancel={disableSelectionMode}\n />\n {/* Selection toggle button (bottom-right corner) */}\n {process.env.NODE_ENV === 'development' && (\n <button\n data-component-picker=\"status\"\n onClick={() => {\n if (!connected) return;\n if (isSelectionMode) {\n disableSelectionMode();\n } else {\n enableSelectionMode();\n }\n }}\n style={{\n position: 'fixed',\n bottom: 16,\n right: 16,\n padding: '8px 12px',\n backgroundColor: !connected\n ? '#ef4444'\n : isSelectionMode\n ? '#3b82f6'\n : '#22c55e',\n color: 'white',\n borderRadius: '9999px',\n fontSize: '12px',\n fontFamily: 'system-ui, sans-serif',\n fontWeight: 500,\n zIndex: 999997,\n opacity: 0.9,\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)',\n border: 'none',\n cursor: connected ? 'pointer' : 'not-allowed',\n transition: 'background-color 0.2s ease',\n }}\n >\n <span\n style={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: 'white',\n animation: !connected ? 'pulse 2s infinite' : isSelectionMode ? 'pulse 1s infinite' : 'none',\n }}\n />\n {!connected\n ? 'Connecting...'\n : isSelectionMode\n ? (\n <span style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n <span>{selectionMessage || 'Click a component'}</span>\n <span style={{ opacity: 0.7, fontSize: '10px' }}>ESC to cancel</span>\n </span>\n )\n : 'Select Component'}\n </button>\n )}\n </>\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-component-selector-mcp/react",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "React component selector with browser selection UI",
5
5
  "license": "MIT",
6
6
  "author": "zakstam",
@@ -20,7 +20,8 @@
20
20
  "model-context-protocol"
21
21
  ],
22
22
  "files": [
23
- "dist"
23
+ "dist",
24
+ "README.md"
24
25
  ],
25
26
  "type": "module",
26
27
  "main": "./dist/index.js",