@react-component-selector-mcp/react 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -125,12 +125,24 @@ function useWebSocketClient(options) {
125
125
  const hasConnectedRef = useRef(false);
126
126
  const [connected, setConnected] = useState(false);
127
127
  const [clientId, setClientId] = useState(null);
128
+ const pendingSelectionsRef = useRef([]);
129
+ const flushPendingSelections = useCallback(() => {
130
+ if (wsRef.current?.readyState === WebSocket.OPEN && pendingSelectionsRef.current.length > 0) {
131
+ const pending = pendingSelectionsRef.current.splice(0);
132
+ for (const data of pending) {
133
+ const message = createMessage("selection", data);
134
+ wsRef.current.send(JSON.stringify(message));
135
+ }
136
+ console.log(`[component-picker] Flushed ${pending.length} queued selection(s)`);
137
+ }
138
+ }, []);
128
139
  const sendSelection = useCallback((data) => {
129
140
  if (wsRef.current?.readyState === WebSocket.OPEN) {
130
141
  const message = createMessage("selection", data);
131
142
  wsRef.current.send(JSON.stringify(message));
132
143
  } else {
133
- console.warn("[component-picker] Cannot send selection - not connected");
144
+ pendingSelectionsRef.current.push(data);
145
+ console.log("[component-picker] Selection queued (will send when connected)");
134
146
  }
135
147
  }, []);
136
148
  useEffect(() => {
@@ -156,6 +168,7 @@ function useWebSocketClient(options) {
156
168
  console.log("[component-picker] Connected to server");
157
169
  setConnected(true);
158
170
  onConnectionChangeRef.current?.(true);
171
+ flushPendingSelections();
159
172
  pingIntervalRef.current = setInterval(() => {
160
173
  if (ws.readyState === WebSocket.OPEN) {
161
174
  ws.send(JSON.stringify(createMessage("ping")));
@@ -245,7 +258,7 @@ function useWebSocketClient(options) {
245
258
  wsRef.current = null;
246
259
  }
247
260
  };
248
- }, [port]);
261
+ }, [port, flushPendingSelections]);
249
262
  return {
250
263
  connected,
251
264
  sendSelection,
@@ -823,7 +836,7 @@ function ComponentPickerImpl({
823
836
  enableSelectionMode();
824
837
  }
825
838
  },
826
- enabled: connected
839
+ enabled: true
827
840
  });
828
841
  const handleSelect = useCallback(
829
842
  async (element) => {
@@ -880,7 +893,6 @@ function ComponentPickerImpl({
880
893
  {
881
894
  "data-component-picker": "status",
882
895
  onClick: () => {
883
- if (!connected) return;
884
896
  if (isSelectionMode) {
885
897
  disableSelectionMode();
886
898
  } else {
@@ -892,7 +904,7 @@ function ComponentPickerImpl({
892
904
  bottom: 16,
893
905
  right: 16,
894
906
  padding: "8px 12px",
895
- backgroundColor: !connected ? "#ef4444" : isSelectionMode ? "#3b82f6" : "#22c55e",
907
+ backgroundColor: isSelectionMode ? "#3b82f6" : "#22c55e",
896
908
  color: "white",
897
909
  borderRadius: "9999px",
898
910
  fontSize: "12px",
@@ -905,7 +917,7 @@ function ComponentPickerImpl({
905
917
  gap: "6px",
906
918
  boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
907
919
  border: "none",
908
- cursor: connected ? "pointer" : "not-allowed",
920
+ cursor: "pointer",
909
921
  transition: "background-color 0.2s ease"
910
922
  },
911
923
  children: [
@@ -916,12 +928,12 @@ function ComponentPickerImpl({
916
928
  width: 8,
917
929
  height: 8,
918
930
  borderRadius: "50%",
919
- backgroundColor: "white",
920
- animation: !connected ? "pulse 2s infinite" : isSelectionMode ? "pulse 1s infinite" : "none"
931
+ backgroundColor: !connected ? "#fbbf24" : "white",
932
+ animation: isSelectionMode ? "pulse 1s infinite" : !connected ? "pulse 2s infinite" : "none"
921
933
  }
922
934
  }
923
935
  ),
924
- !connected ? "Connecting..." : isSelectionMode ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
936
+ isSelectionMode ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
925
937
  /* @__PURE__ */ jsx("span", { children: selectionMessage || "Click a component" }),
926
938
  /* @__PURE__ */ jsx("span", { style: { opacity: 0.7, fontSize: "10px" }, children: "ESC to cancel" })
927
939
  ] }) : "Select Component"
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","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"]}
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 // Queue for selections made while disconnected\n const pendingSelectionsRef = useRef<SelectionData[]>([]);\n\n const flushPendingSelections = useCallback(() => {\n if (wsRef.current?.readyState === WebSocket.OPEN && pendingSelectionsRef.current.length > 0) {\n const pending = pendingSelectionsRef.current.splice(0);\n for (const data of pending) {\n const message = createMessage('selection', data);\n wsRef.current.send(JSON.stringify(message));\n }\n console.log(`[component-picker] Flushed ${pending.length} queued selection(s)`);\n }\n }, []);\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 pendingSelectionsRef.current.push(data);\n console.log('[component-picker] Selection queued (will send when 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 // Flush any selections made while disconnected\n flushPendingSelections();\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, flushPendingSelections]); // Only depend on port and flush callback\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: true,\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 (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: 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: 'pointer',\n transition: 'background-color 0.2s ease',\n }}\n >\n <span\n style={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: !connected ? '#fbbf24' : 'white',\n animation: isSelectionMode ? 'pulse 1s infinite' : !connected ? 'pulse 2s infinite' : 'none',\n }}\n />\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.3",
3
+ "version": "2.1.0",
4
4
  "description": "React component selector with browser selection UI",
5
5
  "license": "MIT",
6
6
  "author": "zakstam",