@react-component-selector-mcp/react 1.0.0 → 2.0.1

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
@@ -3,8 +3,6 @@ import { useCallback, useState, useRef, useEffect } from 'react';
3
3
  import { z } from 'zod';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { nanoid } from 'nanoid';
6
- import { SourceMapConsumer } from 'source-map-js';
7
- import { toPng } from 'html-to-image';
8
6
 
9
7
  var ComponentTypeSchema = z.enum(["function", "class", "forwardRef", "memo"]);
10
8
  var ComponentInfoSchema = z.object({
@@ -31,11 +29,6 @@ var DOMInfoSchema = z.object({
31
29
  className: z.string().nullable(),
32
30
  boundingRect: BoundingRectSchema
33
31
  });
34
- var ScreenshotSchema = z.object({
35
- dataUrl: z.string(),
36
- width: z.number(),
37
- height: z.number()
38
- });
39
32
  var SelectionContextSchema = z.object({
40
33
  pageUrl: z.string(),
41
34
  parentComponents: z.array(z.string())
@@ -48,7 +41,6 @@ var SelectionDataSchema = z.object({
48
41
  props: z.record(z.unknown()),
49
42
  state: z.record(z.unknown()).nullable(),
50
43
  dom: DOMInfoSchema,
51
- screenshot: ScreenshotSchema,
52
44
  context: SelectionContextSchema
53
45
  });
54
46
  var MessageTypeSchema = z.enum([
@@ -130,6 +122,7 @@ function useWebSocketClient(options) {
130
122
  const reconnectTimeoutRef = useRef(null);
131
123
  const pingIntervalRef = useRef(null);
132
124
  const isCleaningUpRef = useRef(false);
125
+ const hasConnectedRef = useRef(false);
133
126
  const [connected, setConnected] = useState(false);
134
127
  const [clientId, setClientId] = useState(null);
135
128
  const sendSelection = useCallback((data) => {
@@ -145,17 +138,21 @@ function useWebSocketClient(options) {
145
138
  if (wsRef.current?.readyState === WebSocket.OPEN) {
146
139
  return;
147
140
  }
141
+ let connectTimeoutId = null;
148
142
  const connect = () => {
149
143
  if (wsRef.current?.readyState === WebSocket.OPEN || isCleaningUpRef.current) {
150
144
  return;
151
145
  }
152
146
  try {
153
147
  const ws = new WebSocket(`ws://localhost:${port}`);
148
+ let wasIntentionallyClosed = false;
154
149
  ws.onopen = () => {
155
150
  if (isCleaningUpRef.current) {
151
+ wasIntentionallyClosed = true;
156
152
  ws.close();
157
153
  return;
158
154
  }
155
+ hasConnectedRef.current = true;
159
156
  console.log("[component-picker] Connected to server");
160
157
  setConnected(true);
161
158
  onConnectionChangeRef.current?.(true);
@@ -166,7 +163,9 @@ function useWebSocketClient(options) {
166
163
  }, 25e3);
167
164
  };
168
165
  ws.onclose = () => {
169
- console.log("[component-picker] Disconnected from server");
166
+ if (hasConnectedRef.current && !wasIntentionallyClosed && !isCleaningUpRef.current) {
167
+ console.log("[component-picker] Disconnected from server");
168
+ }
170
169
  setConnected(false);
171
170
  setClientId(null);
172
171
  onConnectionChangeRef.current?.(false);
@@ -212,7 +211,6 @@ function useWebSocketClient(options) {
212
211
  };
213
212
  wsRef.current = ws;
214
213
  } catch (error) {
215
- console.error("[component-picker] Failed to connect:", error);
216
214
  if (!isCleaningUpRef.current) {
217
215
  reconnectTimeoutRef.current = setTimeout(() => {
218
216
  connect();
@@ -220,9 +218,18 @@ function useWebSocketClient(options) {
220
218
  }
221
219
  }
222
220
  };
223
- connect();
221
+ connectTimeoutId = setTimeout(() => {
222
+ connectTimeoutId = null;
223
+ if (!isCleaningUpRef.current) {
224
+ connect();
225
+ }
226
+ }, 100);
224
227
  return () => {
225
228
  isCleaningUpRef.current = true;
229
+ if (connectTimeoutId) {
230
+ clearTimeout(connectTimeoutId);
231
+ connectTimeoutId = null;
232
+ }
226
233
  if (reconnectTimeoutRef.current) {
227
234
  clearTimeout(reconnectTimeoutRef.current);
228
235
  reconnectTimeoutRef.current = null;
@@ -232,7 +239,9 @@ function useWebSocketClient(options) {
232
239
  pingIntervalRef.current = null;
233
240
  }
234
241
  if (wsRef.current) {
235
- wsRef.current.close();
242
+ if (wsRef.current.readyState === WebSocket.OPEN || wsRef.current.readyState === WebSocket.CONNECTING) {
243
+ wsRef.current.close();
244
+ }
236
245
  wsRef.current = null;
237
246
  }
238
247
  };
@@ -329,7 +338,7 @@ function useFiberInspector() {
329
338
  return "function";
330
339
  }
331
340
  }, []);
332
- const getComponentName2 = useCallback((fiber) => {
341
+ const getComponentName = useCallback((fiber) => {
333
342
  const type = fiber.type;
334
343
  if (!type) return "Unknown";
335
344
  if (typeof type === "function") {
@@ -349,7 +358,7 @@ function useFiberInspector() {
349
358
  while (current) {
350
359
  const tag = current.tag;
351
360
  if (tag === FIBER_TAGS.FunctionComponent || tag === FIBER_TAGS.ClassComponent || tag === FIBER_TAGS.ForwardRef || tag === FIBER_TAGS.MemoComponent || tag === FIBER_TAGS.SimpleMemoComponent) {
352
- const name = getComponentName2(current);
361
+ const name = getComponentName(current);
353
362
  if (!name.startsWith("_") && name !== "Unknown" && name !== "Anonymous") {
354
363
  return current;
355
364
  }
@@ -357,7 +366,7 @@ function useFiberInspector() {
357
366
  current = current.return;
358
367
  }
359
368
  return null;
360
- }, [getComponentName2]);
369
+ }, [getComponentName]);
361
370
  const getParentComponents = useCallback(
362
371
  (fiber) => {
363
372
  const parents = [];
@@ -365,7 +374,7 @@ function useFiberInspector() {
365
374
  while (current && parents.length < 10) {
366
375
  const tag = current.tag;
367
376
  if (tag === FIBER_TAGS.FunctionComponent || tag === FIBER_TAGS.ClassComponent || tag === FIBER_TAGS.ForwardRef || tag === FIBER_TAGS.MemoComponent || tag === FIBER_TAGS.SimpleMemoComponent) {
368
- const name = getComponentName2(current);
377
+ const name = getComponentName(current);
369
378
  if (!name.startsWith("_") && name !== "Unknown") {
370
379
  parents.push(name);
371
380
  }
@@ -374,7 +383,7 @@ function useFiberInspector() {
374
383
  }
375
384
  return parents;
376
385
  },
377
- [getComponentName2]
386
+ [getComponentName]
378
387
  );
379
388
  const serializeProps = useCallback((props) => {
380
389
  const result = {};
@@ -416,7 +425,7 @@ function useFiberInspector() {
416
425
  (fiber) => {
417
426
  return {
418
427
  componentInfo: {
419
- name: getComponentName2(fiber),
428
+ name: getComponentName(fiber),
420
429
  type: getComponentType(fiber)
421
430
  },
422
431
  props: serializeProps(fiber.memoizedProps || {}),
@@ -429,7 +438,7 @@ function useFiberInspector() {
429
438
  }
430
439
  };
431
440
  },
432
- [getComponentName2, getComponentType, serializeProps, extractState, getParentComponents]
441
+ [getComponentName, getComponentType, serializeProps, extractState, getParentComponents]
433
442
  );
434
443
  return {
435
444
  getFiberFromElement,
@@ -439,13 +448,12 @@ function useFiberInspector() {
439
448
  }
440
449
  function SelectionOverlay({
441
450
  enabled,
442
- message,
443
451
  onSelect,
444
452
  onCancel
445
453
  }) {
446
454
  const [highlight, setHighlight] = useState(null);
447
455
  const hoveredElementRef = useRef(null);
448
- const getComponentName2 = useCallback((element) => {
456
+ const getComponentName = useCallback((element) => {
449
457
  const fiberKey = Object.keys(element).find(
450
458
  (k) => k.startsWith("__reactFiber$") || k.startsWith("__reactInternalInstance$")
451
459
  );
@@ -503,10 +511,10 @@ function SelectionOverlay({
503
511
  left: rect.left,
504
512
  width: rect.width,
505
513
  height: rect.height,
506
- componentName: getComponentName2(target)
514
+ componentName: getComponentName(target)
507
515
  });
508
516
  },
509
- [enabled, getComponentName2]
517
+ [enabled, getComponentName]
510
518
  );
511
519
  const handleClick = useCallback(
512
520
  (event) => {
@@ -551,215 +559,46 @@ function SelectionOverlay({
551
559
  };
552
560
  }, [enabled, handleMouseMove, handleClick, handleKeyDown]);
553
561
  if (!enabled) return null;
554
- return /* @__PURE__ */ jsxs(Fragment, { children: [
555
- highlight && /* @__PURE__ */ jsx(
556
- "div",
557
- {
558
- "data-component-picker": "highlight",
559
- style: {
560
- position: "fixed",
561
- top: highlight.top,
562
- left: highlight.left,
563
- width: highlight.width,
564
- height: highlight.height,
565
- border: "2px solid #3b82f6",
566
- backgroundColor: "rgba(59, 130, 246, 0.1)",
567
- pointerEvents: "none",
568
- zIndex: 999998,
569
- boxSizing: "border-box"
570
- },
571
- children: /* @__PURE__ */ jsx(
572
- "div",
573
- {
574
- style: {
575
- position: "absolute",
576
- top: -24,
577
- left: -2,
578
- padding: "2px 8px",
579
- backgroundColor: "#3b82f6",
580
- color: "white",
581
- fontSize: "12px",
582
- fontFamily: "system-ui, sans-serif",
583
- fontWeight: 500,
584
- borderRadius: "4px 4px 0 0",
585
- whiteSpace: "nowrap",
586
- maxWidth: "300px",
587
- overflow: "hidden",
588
- textOverflow: "ellipsis"
589
- },
590
- children: highlight.componentName
591
- }
592
- )
593
- }
594
- ),
595
- /* @__PURE__ */ jsxs(
596
- "div",
597
- {
598
- "data-component-picker": "info-bar",
599
- style: {
600
- position: "fixed",
601
- top: 0,
602
- left: 0,
603
- right: 0,
604
- padding: "12px 16px",
605
- backgroundColor: "#3b82f6",
606
- color: "white",
607
- fontFamily: "system-ui, sans-serif",
608
- fontSize: "14px",
609
- textAlign: "center",
610
- zIndex: 999999,
611
- display: "flex",
612
- justifyContent: "center",
613
- alignItems: "center",
614
- gap: "16px",
615
- boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)"
616
- },
617
- children: [
618
- /* @__PURE__ */ jsx("span", { style: { fontWeight: 500 }, children: message || "Click a component to select it" }),
619
- /* @__PURE__ */ jsx("span", { style: { opacity: 0.8, fontSize: "12px" }, children: "Press ESC to cancel" })
620
- ]
621
- }
622
- )
623
- ] });
624
- }
625
- var sourceMapCache = /* @__PURE__ */ new Map();
626
- var failedFetches = /* @__PURE__ */ new Set();
627
- async function fetchSourceMap(scriptUrl) {
628
- if (sourceMapCache.has(scriptUrl)) {
629
- return sourceMapCache.get(scriptUrl) || null;
630
- }
631
- if (failedFetches.has(scriptUrl)) {
632
- return null;
633
- }
634
- try {
635
- const sourceMapUrl = await findSourceMapUrl(scriptUrl);
636
- if (!sourceMapUrl) {
637
- failedFetches.add(scriptUrl);
638
- sourceMapCache.set(scriptUrl, null);
639
- return null;
640
- }
641
- const response = await fetch(sourceMapUrl);
642
- if (!response.ok) {
643
- failedFetches.add(scriptUrl);
644
- sourceMapCache.set(scriptUrl, null);
645
- return null;
646
- }
647
- const sourceMapData = await response.json();
648
- const consumer = new SourceMapConsumer(sourceMapData);
649
- sourceMapCache.set(scriptUrl, consumer);
650
- return consumer;
651
- } catch (error) {
652
- console.debug("[component-picker] Failed to fetch source map:", error);
653
- failedFetches.add(scriptUrl);
654
- sourceMapCache.set(scriptUrl, null);
655
- return null;
656
- }
657
- }
658
- async function findSourceMapUrl(scriptUrl) {
659
- try {
660
- const scriptResponse = await fetch(scriptUrl);
661
- if (scriptResponse.ok) {
662
- const scriptContent = await scriptResponse.text();
663
- const match = scriptContent.match(
664
- /\/\/[#@]\s*sourceMappingURL=([^\s'"]+)/
665
- );
666
- if (match?.[1]) {
667
- const mapUrl = match[1];
668
- if (mapUrl.startsWith("data:")) {
669
- return null;
670
- }
671
- return new URL(mapUrl, scriptUrl).href;
672
- }
673
- }
674
- const patterns = [
675
- `${scriptUrl}.map`,
676
- scriptUrl.replace(/\.js$/, ".js.map"),
677
- scriptUrl.replace(/\.mjs$/, ".mjs.map")
678
- ];
679
- for (const pattern of patterns) {
680
- try {
681
- const response = await fetch(pattern, { method: "HEAD" });
682
- if (response.ok) {
683
- return pattern;
684
- }
685
- } catch {
686
- }
687
- }
688
- return null;
689
- } catch {
690
- return null;
691
- }
692
- }
693
- function resolveSourcePath(sourcePath, scriptUrl) {
694
- if (sourcePath.startsWith("webpack://")) {
695
- const match = sourcePath.match(/webpack:\/\/(?:[^/]+)?\/\.?\/?(.+)/);
696
- if (match?.[1]) {
697
- return match[1];
698
- }
699
- }
700
- if (sourcePath.startsWith("[project]/")) {
701
- return sourcePath.replace("[project]/", "");
702
- }
703
- if (sourcePath.startsWith("./") || sourcePath.startsWith("../")) {
704
- try {
705
- const scriptDir = scriptUrl.substring(0, scriptUrl.lastIndexOf("/"));
706
- const resolved = new URL(sourcePath, scriptDir + "/").pathname;
707
- return resolved.replace(/^\//, "");
708
- } catch {
709
- return sourcePath;
710
- }
711
- }
712
- if (sourcePath.startsWith("/")) {
713
- return sourcePath.substring(1);
714
- }
715
- return sourcePath;
716
- }
717
- async function searchSourceMapsForComponent(componentName) {
718
- const scripts = Array.from(document.querySelectorAll("script[src]")).map((s) => s.src).filter((src) => src && !src.includes("node_modules"));
719
- const nextScripts = Array.from(
720
- document.querySelectorAll('script[src*="/_next/"]')
721
- ).map((s) => s.src);
722
- const allScripts = [.../* @__PURE__ */ new Set([...scripts, ...nextScripts])];
723
- for (const scriptUrl of allScripts) {
724
- const consumer = await fetchSourceMap(scriptUrl);
725
- if (!consumer) continue;
726
- const sources = consumer.sources || [];
727
- for (const source of sources) {
728
- const fileName = source.split("/").pop() || "";
729
- const baseName = fileName.replace(/\.(tsx?|jsx?)$/, "");
730
- if (baseName === componentName || fileName.toLowerCase().includes(componentName.toLowerCase())) {
731
- try {
732
- let firstMapping = null;
733
- consumer.eachMapping((mapping) => {
734
- if (mapping.source === source && !firstMapping) {
735
- if (mapping.name === componentName && mapping.originalLine !== null && mapping.originalColumn !== null) {
736
- firstMapping = {
737
- line: mapping.originalLine,
738
- column: mapping.originalColumn
739
- };
740
- }
741
- }
742
- });
743
- if (firstMapping !== null) {
744
- return {
745
- source: resolveSourcePath(source, scriptUrl),
746
- line: firstMapping.line,
747
- column: firstMapping.column
748
- };
749
- }
750
- if (baseName === componentName) {
751
- return {
752
- source: resolveSourcePath(source, scriptUrl),
753
- line: 1,
754
- column: 0
755
- };
756
- }
757
- } catch {
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
758
598
  }
759
- }
599
+ )
760
600
  }
761
- }
762
- return null;
601
+ ) });
763
602
  }
764
603
 
765
604
  // src/utils/stackTraceParser.ts
@@ -834,15 +673,11 @@ function filterInternalFrames(frames) {
834
673
  }
835
674
 
836
675
  // src/utils/sourceLocationResolver.ts
837
- async function resolveSourceLocation(fiber, element) {
676
+ async function resolveSourceLocation(fiber, _element) {
838
677
  const debugSourceResult = tryDebugSource(fiber);
839
678
  if (debugSourceResult.filePath) {
840
679
  return debugSourceResult;
841
680
  }
842
- const sourceMapResult = await trySourceMapResolution(fiber);
843
- if (sourceMapResult?.filePath) {
844
- return sourceMapResult;
845
- }
846
681
  const stackResult = tryStackTraceParsing();
847
682
  if (stackResult?.filePath) {
848
683
  return stackResult;
@@ -854,11 +689,6 @@ async function resolveSourceLocation(fiber, element) {
854
689
  };
855
690
  }
856
691
  function tryDebugSource(fiber) {
857
- if (fiber) {
858
- console.log("[component-picker] Fiber keys:", Object.keys(fiber));
859
- console.log("[component-picker] _debugSource:", fiber._debugSource);
860
- console.log("[component-picker] _debugInfo:", fiber._debugInfo);
861
- }
862
692
  if (!fiber?._debugSource) {
863
693
  return { filePath: null, lineNumber: null, columnNumber: null };
864
694
  }
@@ -872,26 +702,6 @@ function tryDebugSource(fiber) {
872
702
  columnNumber: columnNumber ?? null
873
703
  };
874
704
  }
875
- async function trySourceMapResolution(fiber, _element) {
876
- try {
877
- const componentName = fiber?.type ? getComponentName(fiber.type) : null;
878
- if (!componentName) {
879
- return null;
880
- }
881
- const result = await searchSourceMapsForComponent(componentName);
882
- if (!result) {
883
- return null;
884
- }
885
- return {
886
- filePath: formatFilePath(result.source),
887
- lineNumber: result.line,
888
- columnNumber: result.column
889
- };
890
- } catch (error) {
891
- console.debug("[component-picker] Source map resolution failed:", error);
892
- return null;
893
- }
894
- }
895
705
  function tryStackTraceParsing() {
896
706
  try {
897
707
  const error = new Error();
@@ -914,17 +724,6 @@ function tryStackTraceParsing() {
914
724
  return null;
915
725
  }
916
726
  }
917
- function getComponentName(type) {
918
- if (!type) return null;
919
- if (typeof type === "function") {
920
- return type.displayName || type.name || null;
921
- }
922
- if (typeof type === "object" && type !== null) {
923
- const obj = type;
924
- return obj.displayName || obj.render?.displayName || obj.render?.name || null;
925
- }
926
- return null;
927
- }
928
727
  function extractFilePathFromUrl(url) {
929
728
  try {
930
729
  const urlObj = new URL(url);
@@ -946,67 +745,6 @@ function formatFilePath(filePath) {
946
745
  cleaned = cleaned.replace(/\\/g, "/");
947
746
  return cleaned;
948
747
  }
949
- var DEFAULT_OPTIONS = {
950
- maxWidth: 800,
951
- maxHeight: 600,
952
- backgroundColor: "#ffffff",
953
- pixelRatio: 1,
954
- padding: 10
955
- };
956
- async function captureScreenshot(element, options = {}) {
957
- const opts = { ...DEFAULT_OPTIONS, ...options };
958
- try {
959
- const rect = element.getBoundingClientRect();
960
- const width = Math.min(rect.width + opts.padding * 2, opts.maxWidth);
961
- const height = Math.min(rect.height + opts.padding * 2, opts.maxHeight);
962
- const dataUrl = await toPng(element, {
963
- backgroundColor: opts.backgroundColor,
964
- pixelRatio: opts.pixelRatio,
965
- width: rect.width,
966
- height: rect.height,
967
- style: {
968
- margin: "0",
969
- padding: "0"
970
- },
971
- filter: (node) => {
972
- if (node instanceof Element) {
973
- if (node.hasAttribute("data-component-picker")) {
974
- return false;
975
- }
976
- }
977
- return true;
978
- }
979
- });
980
- return {
981
- dataUrl,
982
- width: Math.round(width),
983
- height: Math.round(height)
984
- };
985
- } catch (error) {
986
- console.error("[component-picker] Screenshot capture failed:", error);
987
- return {
988
- dataUrl: createFallbackScreenshot(element),
989
- width: 200,
990
- height: 100
991
- };
992
- }
993
- }
994
- function createFallbackScreenshot(element) {
995
- const canvas = document.createElement("canvas");
996
- canvas.width = 200;
997
- canvas.height = 100;
998
- const ctx = canvas.getContext("2d");
999
- if (ctx) {
1000
- ctx.fillStyle = "#f0f0f0";
1001
- ctx.fillRect(0, 0, 200, 100);
1002
- ctx.fillStyle = "#666";
1003
- ctx.font = "12px sans-serif";
1004
- ctx.textAlign = "center";
1005
- ctx.fillText("Screenshot unavailable", 100, 45);
1006
- ctx.fillText(element.tagName.toLowerCase(), 100, 65);
1007
- }
1008
- return canvas.toDataURL("image/png");
1009
- }
1010
748
 
1011
749
  // src/utils/componentMetadata.ts
1012
750
  function extractDOMInfo(element) {
@@ -1031,7 +769,6 @@ async function buildSelectionData(element, fiberData, options = {}) {
1031
769
  _debugSource: fiberData.debugSource
1032
770
  };
1033
771
  const source = await resolveSourceLocation(fiber);
1034
- const screenshot = await captureScreenshot(element, options.screenshotOptions);
1035
772
  const selectionData = {
1036
773
  id: nanoid(),
1037
774
  timestamp: Date.now(),
@@ -1044,7 +781,6 @@ async function buildSelectionData(element, fiberData, options = {}) {
1044
781
  props: fiberData.props,
1045
782
  state: fiberData.state,
1046
783
  dom: extractDOMInfo(element),
1047
- screenshot,
1048
784
  context: {
1049
785
  pageUrl: window.location.href,
1050
786
  parentComponents: fiberData.parentComponents
@@ -1135,7 +871,6 @@ function ComponentPickerImpl({
1135
871
  SelectionOverlay,
1136
872
  {
1137
873
  enabled: isSelectionMode,
1138
- message: selectionMessage,
1139
874
  onSelect: handleSelect,
1140
875
  onCancel: disableSelectionMode
1141
876
  }
@@ -1157,7 +892,7 @@ function ComponentPickerImpl({
1157
892
  bottom: 16,
1158
893
  right: 16,
1159
894
  padding: "8px 12px",
1160
- backgroundColor: !connected ? "#ef4444" : isSelectionMode ? "#f59e0b" : "#22c55e",
895
+ backgroundColor: !connected ? "#ef4444" : isSelectionMode ? "#3b82f6" : "#22c55e",
1161
896
  color: "white",
1162
897
  borderRadius: "9999px",
1163
898
  fontSize: "12px",
@@ -1182,11 +917,14 @@ function ComponentPickerImpl({
1182
917
  height: 8,
1183
918
  borderRadius: "50%",
1184
919
  backgroundColor: "white",
1185
- animation: !connected ? "pulse 2s infinite" : "none"
920
+ animation: !connected ? "pulse 2s infinite" : isSelectionMode ? "pulse 1s infinite" : "none"
1186
921
  }
1187
922
  }
1188
923
  ),
1189
- !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"
1190
928
  ]
1191
929
  }
1192
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/sourceMapClient.ts","../src/utils/stackTraceParser.ts","../src/utils/sourceLocationResolver.ts","../src/utils/screenshotCapture.ts","../src/utils/componentMetadata.ts","../src/ComponentPicker.tsx"],"names":["z","useCallback","useEffect","useState","getComponentName","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 ScreenshotSchema = z.object({\n dataUrl: z.string(),\n width: z.number(),\n height: z.number(),\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 screenshot: ScreenshotSchema,\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 * Source map client for fetching and parsing source maps from dev servers\n * Uses source-map-js for browser-compatible source map parsing\n */\n\nimport { SourceMapConsumer, type RawSourceMap } from 'source-map-js';\n\nexport interface OriginalPosition {\n source: string | null;\n line: number | null;\n column: number | null;\n name: string | null;\n}\n\n// Cache for source map consumers (keyed by script URL)\nconst sourceMapCache = new Map<string, SourceMapConsumer | null>();\n\n// Cache for failed fetches to avoid repeated attempts\nconst failedFetches = new Set<string>();\n\n/**\n * Fetch and parse a source map for a given script URL\n */\nexport async function fetchSourceMap(\n scriptUrl: string\n): Promise<SourceMapConsumer | null> {\n // Check cache first\n if (sourceMapCache.has(scriptUrl)) {\n return sourceMapCache.get(scriptUrl) || null;\n }\n\n // Skip if we already failed to fetch this one\n if (failedFetches.has(scriptUrl)) {\n return null;\n }\n\n try {\n // Try to find the source map URL\n const sourceMapUrl = await findSourceMapUrl(scriptUrl);\n if (!sourceMapUrl) {\n failedFetches.add(scriptUrl);\n sourceMapCache.set(scriptUrl, null);\n return null;\n }\n\n // Fetch the source map\n const response = await fetch(sourceMapUrl);\n if (!response.ok) {\n failedFetches.add(scriptUrl);\n sourceMapCache.set(scriptUrl, null);\n return null;\n }\n\n const sourceMapData = (await response.json()) as RawSourceMap;\n\n // Create the consumer\n const consumer = new SourceMapConsumer(sourceMapData);\n sourceMapCache.set(scriptUrl, consumer);\n return consumer;\n } catch (error) {\n console.debug('[component-picker] Failed to fetch source map:', error);\n failedFetches.add(scriptUrl);\n sourceMapCache.set(scriptUrl, null);\n return null;\n }\n}\n\n/**\n * Find the source map URL for a script\n * Tries multiple strategies:\n * 1. Fetch script and look for //# sourceMappingURL comment\n * 2. Try common source map URL patterns\n */\nasync function findSourceMapUrl(scriptUrl: string): Promise<string | null> {\n try {\n // Strategy 1: Fetch the script and look for sourceMappingURL\n const scriptResponse = await fetch(scriptUrl);\n if (scriptResponse.ok) {\n const scriptContent = await scriptResponse.text();\n\n // Look for sourceMappingURL comment\n const match = scriptContent.match(\n /\\/\\/[#@]\\s*sourceMappingURL=([^\\s'\"]+)/\n );\n if (match?.[1]) {\n const mapUrl = match[1];\n // Handle relative URLs\n if (mapUrl.startsWith('data:')) {\n // Inline source map - not supported yet\n return null;\n }\n return new URL(mapUrl, scriptUrl).href;\n }\n }\n\n // Strategy 2: Try common patterns\n const patterns = [\n `${scriptUrl}.map`,\n scriptUrl.replace(/\\.js$/, '.js.map'),\n scriptUrl.replace(/\\.mjs$/, '.mjs.map'),\n ];\n\n for (const pattern of patterns) {\n try {\n const response = await fetch(pattern, { method: 'HEAD' });\n if (response.ok) {\n return pattern;\n }\n } catch {\n // Continue to next pattern\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve the original position from a bundled position\n */\nexport async function resolveOriginalPosition(\n scriptUrl: string,\n line: number,\n column: number\n): Promise<OriginalPosition | null> {\n const consumer = await fetchSourceMap(scriptUrl);\n if (!consumer) {\n return null;\n }\n\n try {\n const position = consumer.originalPositionFor({\n line,\n column,\n });\n\n // source-map-js returns { source: null } when it can't find the position\n if (!position.source) {\n return null;\n }\n\n return {\n source: position.source,\n line: position.line,\n column: position.column,\n name: position.name ?? null,\n };\n } catch (error) {\n console.debug('[component-picker] Failed to resolve position:', error);\n return null;\n }\n}\n\n/**\n * Resolve source path to an absolute or project-relative path\n */\nexport function resolveSourcePath(\n sourcePath: string,\n scriptUrl: string\n): string {\n // Handle webpack:// protocol\n if (sourcePath.startsWith('webpack://')) {\n // Format: webpack://package-name/./src/file.tsx\n // or: webpack:///./src/file.tsx\n const match = sourcePath.match(/webpack:\\/\\/(?:[^/]+)?\\/\\.?\\/?(.+)/);\n if (match?.[1]) {\n return match[1];\n }\n }\n\n // Handle turbopack paths\n if (sourcePath.startsWith('[project]/')) {\n return sourcePath.replace('[project]/', '');\n }\n\n // Handle relative paths\n if (sourcePath.startsWith('./') || sourcePath.startsWith('../')) {\n try {\n // Resolve relative to script URL's directory\n const scriptDir = scriptUrl.substring(0, scriptUrl.lastIndexOf('/'));\n const resolved = new URL(sourcePath, scriptDir + '/').pathname;\n // Remove leading slash for consistency\n return resolved.replace(/^\\//, '');\n } catch {\n return sourcePath;\n }\n }\n\n // Handle absolute paths that start with /\n if (sourcePath.startsWith('/')) {\n return sourcePath.substring(1);\n }\n\n return sourcePath;\n}\n\n/**\n * Clear the source map cache\n * Useful for HMR scenarios where source maps may have changed\n */\nexport function clearSourceMapCache(): void {\n sourceMapCache.clear();\n failedFetches.clear();\n}\n\n/**\n * Get cache statistics for debugging\n */\nexport function getCacheStats(): { cached: number; failed: number } {\n return {\n cached: sourceMapCache.size,\n failed: failedFetches.size,\n };\n}\n\n/**\n * Search source maps for a component definition by name\n * This is a heuristic approach when _debugSource isn't available\n */\nexport async function searchSourceMapsForComponent(\n componentName: string\n): Promise<{ source: string; line: number; column: number } | null> {\n // Get all script URLs from the page\n const scripts = Array.from(document.querySelectorAll('script[src]'))\n .map((s) => (s as HTMLScriptElement).src)\n .filter((src) => src && !src.includes('node_modules'));\n\n // Also check for Next.js chunks\n const nextScripts = Array.from(\n document.querySelectorAll('script[src*=\"/_next/\"]')\n ).map((s) => (s as HTMLScriptElement).src);\n\n const allScripts = [...new Set([...scripts, ...nextScripts])];\n\n for (const scriptUrl of allScripts) {\n const consumer = await fetchSourceMap(scriptUrl);\n if (!consumer) continue;\n\n // Search through all sources in this source map\n const sources = (consumer as unknown as { sources: string[] }).sources || [];\n\n for (const source of sources) {\n // Check if this source file might contain the component\n // Look for patterns like \"Card.tsx\", \"Card.jsx\", etc.\n const fileName = source.split('/').pop() || '';\n const baseName = fileName.replace(/\\.(tsx?|jsx?)$/, '');\n\n if (\n baseName === componentName ||\n fileName.toLowerCase().includes(componentName.toLowerCase())\n ) {\n // Try to find the component definition in this source\n // Look for \"function ComponentName\" or \"const ComponentName\"\n try {\n // Get all mappings for this source\n let firstMapping: { line: number; column: number } | null = null;\n\n consumer.eachMapping((mapping) => {\n if (mapping.source === source && !firstMapping) {\n // Check if this mapping has the component name\n if (mapping.name === componentName && mapping.originalLine !== null && mapping.originalColumn !== null) {\n firstMapping = {\n line: mapping.originalLine,\n column: mapping.originalColumn,\n };\n }\n }\n });\n\n if (firstMapping !== null) {\n return {\n source: resolveSourcePath(source, scriptUrl),\n line: (firstMapping as { line: number; column: number }).line,\n column: (firstMapping as { line: number; column: number }).column,\n };\n }\n\n // If no exact name match, return the start of the file that matches the name\n if (baseName === componentName) {\n return {\n source: resolveSourcePath(source, scriptUrl),\n line: 1,\n column: 0,\n };\n }\n } catch {\n // Continue to next source\n }\n }\n }\n }\n\n return null;\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 * Multi-strategy source location resolver\n *\n * Attempts to resolve source file locations using three strategies:\n * 1. React's _debugSource (fastest, works with Babel-based builds)\n * 2. Source map resolution (works with any bundler in dev mode)\n * 3. Stack trace parsing (fallback, less accurate)\n */\n\nimport type { SourceLocation } from '@react-component-selector-mcp/shared';\nimport { searchSourceMapsForComponent } from './sourceMapClient.js';\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 source map resolution\n const sourceMapResult = await trySourceMapResolution(fiber, element);\n if (sourceMapResult?.filePath) {\n return sourceMapResult;\n }\n\n // Strategy 3: 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 // Debug: log what's in the fiber\n if (fiber) {\n console.log('[component-picker] Fiber keys:', Object.keys(fiber));\n console.log('[component-picker] _debugSource:', fiber._debugSource);\n console.log('[component-picker] _debugInfo:', (fiber as Record<string, unknown>)._debugInfo);\n }\n\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: Resolve source via source maps\n * Uses component name to search source maps for the definition\n */\nasync function trySourceMapResolution(\n fiber: Fiber | null,\n _element?: HTMLElement\n): Promise<SourceLocation | null> {\n try {\n // Get component name from fiber\n const componentName = fiber?.type ? getComponentName(fiber.type) : null;\n if (!componentName) {\n return null;\n }\n\n // Search source maps for a file/definition matching this component name\n const result = await searchSourceMapsForComponent(componentName);\n if (!result) {\n return null;\n }\n\n return {\n filePath: formatFilePath(result.source),\n lineNumber: result.line,\n columnNumber: result.column,\n };\n } catch (error) {\n console.debug('[component-picker] Source map resolution failed:', error);\n return null;\n }\n}\n\n/**\n * Strategy 3: 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 component name from fiber type\n */\nfunction getComponentName(type: unknown): string | null {\n if (!type) return null;\n\n if (typeof type === 'function') {\n return (type as { displayName?: string; name?: string }).displayName ||\n (type as { name?: string }).name ||\n null;\n }\n\n if (typeof type === 'object' && type !== null) {\n // Handle forwardRef, memo, etc.\n const obj = type as { displayName?: string; render?: { displayName?: string; name?: string } };\n return obj.displayName || obj.render?.displayName || obj.render?.name || null;\n }\n\n return null;\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 { toPng } from 'html-to-image';\nimport type { Screenshot } from '@react-component-selector-mcp/shared';\n\nexport interface CaptureOptions {\n /** Maximum width of the screenshot (default: 800) */\n maxWidth?: number;\n /** Maximum height of the screenshot (default: 600) */\n maxHeight?: number;\n /** Background color (default: transparent) */\n backgroundColor?: string;\n /** Pixel ratio for higher quality (default: 1) */\n pixelRatio?: number;\n /** Padding around the element (default: 10) */\n padding?: number;\n}\n\nconst DEFAULT_OPTIONS: Required<CaptureOptions> = {\n maxWidth: 800,\n maxHeight: 600,\n backgroundColor: '#ffffff',\n pixelRatio: 1,\n padding: 10,\n};\n\n/**\n * Capture a screenshot of an HTML element\n */\nexport async function captureScreenshot(\n element: HTMLElement,\n options: CaptureOptions = {}\n): Promise<Screenshot> {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n\n try {\n // Get element dimensions\n const rect = element.getBoundingClientRect();\n const width = Math.min(rect.width + opts.padding * 2, opts.maxWidth);\n const height = Math.min(rect.height + opts.padding * 2, opts.maxHeight);\n\n // Capture the element\n const dataUrl = await toPng(element, {\n backgroundColor: opts.backgroundColor,\n pixelRatio: opts.pixelRatio,\n width: rect.width,\n height: rect.height,\n style: {\n margin: '0',\n padding: '0',\n },\n filter: (node) => {\n // Skip our overlay elements\n if (node instanceof Element) {\n if (node.hasAttribute('data-component-picker')) {\n return false;\n }\n }\n return true;\n },\n });\n\n return {\n dataUrl,\n width: Math.round(width),\n height: Math.round(height),\n };\n } catch (error) {\n console.error('[component-picker] Screenshot capture failed:', error);\n\n // Return a fallback empty screenshot\n return {\n dataUrl: createFallbackScreenshot(element),\n width: 200,\n height: 100,\n };\n }\n}\n\n/**\n * Create a simple fallback screenshot when capture fails\n */\nfunction createFallbackScreenshot(element: HTMLElement): string {\n const canvas = document.createElement('canvas');\n canvas.width = 200;\n canvas.height = 100;\n\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.fillStyle = '#f0f0f0';\n ctx.fillRect(0, 0, 200, 100);\n\n ctx.fillStyle = '#666';\n ctx.font = '12px sans-serif';\n ctx.textAlign = 'center';\n ctx.fillText('Screenshot unavailable', 100, 45);\n ctx.fillText(element.tagName.toLowerCase(), 100, 65);\n }\n\n return canvas.toDataURL('image/png');\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';\nimport { captureScreenshot, type CaptureOptions } from './screenshotCapture.js';\n\nexport interface MetadataOptions {\n screenshotOptions?: CaptureOptions;\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 // Capture screenshot\n const screenshot = await captureScreenshot(element, options.screenshotOptions);\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 screenshot,\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": "1.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "React component selector with browser selection UI",
5
5
  "license": "MIT",
6
6
  "author": "zakstam",
@@ -39,9 +39,7 @@
39
39
  "clean": "rimraf dist"
40
40
  },
41
41
  "dependencies": {
42
- "html-to-image": "^1.11.11",
43
42
  "nanoid": "^5.0.9",
44
- "source-map-js": "^1.2.1",
45
43
  "zod": "^3.24.1"
46
44
  },
47
45
  "peerDependencies": {
@@ -60,5 +58,9 @@
60
58
  },
61
59
  "engines": {
62
60
  "node": ">=18"
61
+ },
62
+ "publishConfig": {
63
+ "access": "public",
64
+ "provenance": true
63
65
  }
64
66
  }