@inspecto-dev/core 0.2.0-alpha.1 → 0.2.0-alpha.3

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.cjs CHANGED
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
6
9
  var __export = (target, all) => {
7
10
  for (var name in all)
8
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -16,37 +19,52 @@ var __copyProps = (to, from, except, desc) => {
16
19
  return to;
17
20
  };
18
21
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
23
- InspectoElement: () => InspectoElement,
24
- mountInspector: () => mountInspector,
25
- unmountInspector: () => unmountInspector
26
- });
27
- module.exports = __toCommonJS(src_exports);
22
+ var __async = (__this, __arguments, generator) => {
23
+ return new Promise((resolve, reject) => {
24
+ var fulfilled = (value) => {
25
+ try {
26
+ step(generator.next(value));
27
+ } catch (e) {
28
+ reject(e);
29
+ }
30
+ };
31
+ var rejected = (value) => {
32
+ try {
33
+ step(generator.throw(value));
34
+ } catch (e) {
35
+ reject(e);
36
+ }
37
+ };
38
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
39
+ step((generator = generator.apply(__this, __arguments)).next());
40
+ });
41
+ };
28
42
 
29
43
  // src/styles.ts
30
- var overlayClass = "inspecto-overlay";
31
- var menuClass = "inspecto-menu";
32
- var menuItemClass = "inspecto-menu-item";
33
- var loadingSpinnerClass = "inspecto-spinner";
34
- var errorMsgClass = "inspecto-error";
35
- var badgeClass = "inspecto-badge";
36
- var menuInputClass = "inspecto-menu-input";
37
- var menuInputWrapperClass = "inspecto-menu-input-wrapper";
38
- var menuInputIconClass = "inspecto-menu-input-icon";
39
- var tooltipClass = "inspecto-tooltip";
40
- var tooltipTopClass = "inspecto-tooltip-top";
41
- var tooltipBottomClass = "inspecto-tooltip-bottom";
42
- var tagClass = "inspecto-tag";
43
- var idClass = "inspecto-id";
44
- var classClass = "inspecto-class";
45
- var dimClass = "inspecto-dim";
46
- var separatorClass = "inspecto-separator";
47
- var sourceClass = "inspecto-source";
48
- var shortcutIconClass = "ai-shortcut-icon";
49
- var darkVars = `
44
+ var overlayClass, menuClass, menuItemClass, loadingSpinnerClass, errorMsgClass, badgeClass, menuInputClass, menuInputWrapperClass, menuInputIconClass, tooltipClass, tooltipTopClass, tooltipBottomClass, tagClass, idClass, classClass, dimClass, separatorClass, sourceClass, shortcutIconClass, darkVars, inspectorStyles;
45
+ var init_styles = __esm({
46
+ "src/styles.ts"() {
47
+ "use strict";
48
+ overlayClass = "inspecto-overlay";
49
+ menuClass = "inspecto-menu";
50
+ menuItemClass = "inspecto-menu-item";
51
+ loadingSpinnerClass = "inspecto-spinner";
52
+ errorMsgClass = "inspecto-error";
53
+ badgeClass = "inspecto-badge";
54
+ menuInputClass = "inspecto-menu-input";
55
+ menuInputWrapperClass = "inspecto-menu-input-wrapper";
56
+ menuInputIconClass = "inspecto-menu-input-icon";
57
+ tooltipClass = "inspecto-tooltip";
58
+ tooltipTopClass = "inspecto-tooltip-top";
59
+ tooltipBottomClass = "inspecto-tooltip-bottom";
60
+ tagClass = "inspecto-tag";
61
+ idClass = "inspecto-id";
62
+ classClass = "inspecto-class";
63
+ dimClass = "inspecto-dim";
64
+ separatorClass = "inspecto-separator";
65
+ sourceClass = "inspecto-source";
66
+ shortcutIconClass = "ai-shortcut-icon";
67
+ darkVars = `
50
68
  --inspecto-menu-bg: #252526;
51
69
  --inspecto-menu-border: #454545;
52
70
  --inspecto-menu-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
@@ -74,7 +92,7 @@ var darkVars = `
74
92
  --inspecto-dim-color: #858585;
75
93
  --inspecto-error-color: #ef4444;
76
94
  `;
77
- var inspectorStyles = `
95
+ inspectorStyles = `
78
96
  :host {
79
97
  /* Light theme (default) */
80
98
  --inspecto-menu-bg: #ffffff;
@@ -413,10 +431,10 @@ var inspectorStyles = `
413
431
  opacity: 1;
414
432
  }
415
433
  `;
434
+ }
435
+ });
416
436
 
417
437
  // src/overlay.ts
418
- var GAP = 8;
419
- var EDGE_MARGIN = 4;
420
438
  function createOverlay(shadowRoot) {
421
439
  const overlay = document.createElement("div");
422
440
  overlay.className = overlayClass;
@@ -495,138 +513,23 @@ function createOverlay(shadowRoot) {
495
513
  }
496
514
  return { show, hide };
497
515
  }
516
+ var GAP, EDGE_MARGIN;
517
+ var init_overlay = __esm({
518
+ "src/overlay.ts"() {
519
+ "use strict";
520
+ init_styles();
521
+ GAP = 8;
522
+ EDGE_MARGIN = 4;
523
+ }
524
+ });
498
525
 
499
526
  // src/intents.ts
500
527
  function CUSTOM_PROMPT_TEMPLATE(userPrompt) {
501
528
  return userPrompt;
502
529
  }
503
- var DEFAULT_INTENTS = [
504
- // ── 1. Explain Component ─────────────────────────────────────────────────
505
- // Frequency: ★★★★★ — Most common action when navigating unfamiliar codebases
506
- {
507
- id: "explain",
508
- label: "Explain Component",
509
- prompt: `The following is a {{framework}} component from \`{{file}}\` (line {{line}}).
510
-
511
- Please explain:
512
-
513
- 1. What this component does and its responsibility in the UI
514
- 2. Key props and their purpose
515
- 3. Important state or side effects (if applicable)
516
- 4. Any non-obvious logic or edge cases worth noting`
517
- },
518
- // ── 2. Fix Bug ───────────────────────────────────────────────────────────
519
- // Frequency: ★★★★★ — Debugging is the highest time-cost activity in frontend dev
520
- {
521
- id: "fix-bug",
522
- label: "Fix Bug",
523
- prompt: `I found a bug in the following {{framework}} component from \`{{file}}\` (line {{line}}).
524
-
525
- Please:
526
-
527
- 1. Identify potential bugs or issues in this code
528
- 2. Explain the root cause of each issue
529
- 3. Provide a fixed version with minimal changes
530
-
531
- If you need more context (e.g. parent component, API response shape),
532
- please ask before suggesting a fix.`
533
- },
534
- // ── 3. Fix Styles ────────────────────────────────────────────────────────
535
- // Frequency: ★★★★ — Styling issues are top-3 daily pain points for frontend devs
536
- {
537
- id: "fix-styles",
538
- label: "Fix Styles",
539
- prompt: `The following component from \`{{file}}\` (line {{line}}) has a styling issue.
540
-
541
- Please:
542
-
543
- 1. Review the current styles (className / inline styles / CSS-in-JS / Style blocks)
544
- 2. Identify common issues: layout shifts, overflow, z-index conflicts,
545
- responsive breakpoints, or visual inconsistencies
546
- 3. Suggest fixes using the same styling approach already in use
547
-
548
- Note: Maintain the existing styling conventions (e.g. Tailwind, CSS Modules, scoped styles).`
549
- },
550
- // ── 4. Refactor Component ────────────────────────────────────────────────
551
- // Frequency: ★★★★ — Sustained demand after features stabilize; large component splits
552
- {
553
- id: "refactor",
554
- label: "Refactor Component",
555
- prompt: `Please refactor the following {{framework}} component from \`{{file}}\` (line {{line}}).
556
-
557
- Refactoring goals (apply as relevant):
558
-
559
- - Extract reusable sub-components or composables/hooks
560
- - Improve readability and reduce complexity
561
- - Remove redundant state or unnecessary re-renders
562
- - Apply {{framework}} best practices
563
- - Maintain existing behavior \u2014 no functional changes
564
-
565
- Please show the refactored version with a brief explanation of each change.`
566
- },
567
- // ── 5. Code Review ───────────────────────────────────────────────────────
568
- // Frequency: ★★★ — Concentrated at PR stage; slightly less frequent than daily fixes
569
- {
570
- id: "code-review",
571
- label: "Code Review",
572
- prompt: `Please do a code review for the following {{framework}} component from \`{{file}}\` (line {{line}}).
573
-
574
- Review dimensions:
575
-
576
- - Correctness: logic errors, edge cases, race conditions
577
- - {{framework}} best practices: lifecycle usage, key props, reactivity rules
578
- - Performance: unnecessary renders, missing memoization
579
- - Accessibility: ARIA attributes, keyboard navigation, semantic HTML
580
- - Security: XSS risks, unsafe HTML injection, user input handling
581
- - Maintainability: naming clarity, code duplication, complexity
582
-
583
- Format your response as a prioritized list: \u{1F534} Critical / \u{1F7E1} Warning / \u{1F7E2} Suggestion.`
584
- },
585
- // ── 6. Generate Test ─────────────────────────────────────────────────────
586
- // Frequency: ★★★ — Common but often deferred; great AI use case
587
- {
588
- id: "generate-test",
589
- label: "Generate Test",
590
- prompt: `Please generate unit tests for the following {{framework}} component from \`{{file}}\` (line {{line}}).
591
-
592
- Requirements:
593
-
594
- - Use Vitest + Testing Library (or Jest if the codebase implies it)
595
- - Cover: render correctness, user interactions, edge cases, error states
596
- - Mock external dependencies (API calls, context/providers, router)
597
- - Use accessible queries (getByRole, getByLabelText) over getByTestId
598
-
599
- Generate a complete, runnable test file. Include all import statements.`
600
- },
601
- // ── 7. Performance Analysis ──────────────────────────────────────────────
602
- // Frequency: ★★ — Targeted use during perf sprints; not a daily operation
603
- {
604
- id: "performance",
605
- label: "Performance Analysis",
606
- prompt: `Please analyze the performance of the following {{framework}} component from \`{{file}}\` (line {{line}}).
607
-
608
- Focus on:
609
-
610
- 1. Unnecessary re-renders or reactive updates
611
- 2. Expensive computations that should be memoized/computed
612
- 3. Heavy operations in the render path
613
- 4. Dependency arrays or watchers \u2014 missing or over-specified
614
- 5. Large bundle impact (heavy imports that could be lazy-loaded)
615
-
616
- For each issue found, provide: problem description \u2192 recommended fix \u2192 expected impact.`
617
- },
618
- // ── 8. Open in Editor ────────────────────────────────────────────────────
619
- // Type: local action (no AI prompt) — jumps directly to source in IDE
620
- {
621
- id: "open-in-editor",
622
- label: "Open in Editor",
623
- prompt: "",
624
- // unused — isAction handles this
625
- isAction: true
626
- }
627
- ];
628
530
  function detectFramework(fileName) {
629
- const ext = fileName.split(".").pop()?.toLowerCase() || "";
531
+ var _a;
532
+ const ext = ((_a = fileName.split(".").pop()) == null ? void 0 : _a.toLowerCase()) || "";
630
533
  switch (ext) {
631
534
  case "vue":
632
535
  return "Vue";
@@ -645,12 +548,13 @@ function detectFramework(fileName) {
645
548
  }
646
549
  }
647
550
  function buildPrompt(template, location, snippetResult) {
648
- const shortFile = location.file.split("/").pop() ?? location.file;
649
- const ext = shortFile.split(".").pop()?.toLowerCase() || "tsx";
551
+ var _a, _b, _c;
552
+ const shortFile = (_a = location.file.split("/").pop()) != null ? _a : location.file;
553
+ const ext = ((_b = shortFile.split(".").pop()) == null ? void 0 : _b.toLowerCase()) || "tsx";
650
554
  const framework = detectFramework(shortFile);
651
555
  let finalPrompt = template.replace(/\{\{file\}\}/g, location.file).replace(/\{\{line\}\}/g, String(location.line)).replace(/\{\{column\}\}/g, String(location.column)).replace(/\{\{ext\}\}/g, ext).replace(/\{\{framework\}\}/g, framework).replace(/\{\{name\}\}/g, shortFile);
652
556
  if (snippetResult && snippetResult.snippet) {
653
- const name = snippetResult.name ?? shortFile;
557
+ const name = (_c = snippetResult.name) != null ? _c : shortFile;
654
558
  finalPrompt = finalPrompt.replace(/\{\{name\}\}/g, name);
655
559
  finalPrompt += `
656
560
 
@@ -661,72 +565,93 @@ ${snippetResult.snippet}
661
565
  }
662
566
  return finalPrompt;
663
567
  }
568
+ var init_intents = __esm({
569
+ "src/intents.ts"() {
570
+ "use strict";
571
+ }
572
+ });
664
573
 
665
574
  // src/http.ts
666
- var BASE_URL = globalThis.__AI_INSPECTOR_SERVER_URL__ || "http://127.0.0.1:5678";
667
575
  function setBaseUrl(url) {
668
576
  BASE_URL = url.replace(/\/$/, "");
669
577
  }
670
- var cachedConfig = null;
671
- async function fetchIdeInfo(force = false) {
672
- if (cachedConfig && !force) return cachedConfig;
673
- try {
674
- const res = await fetch(`${BASE_URL}/config`);
675
- if (!res.ok) return null;
676
- cachedConfig = await res.json();
677
- return cachedConfig;
678
- } catch {
679
- return null;
680
- }
578
+ function fetchIdeInfo(force = false) {
579
+ return __async(this, null, function* () {
580
+ if (cachedConfig && !force) return cachedConfig;
581
+ try {
582
+ const res = yield fetch(`${BASE_URL}${import_types.INSPECTO_API_PATHS.CLIENT_CONFIG}`);
583
+ if (!res.ok) return null;
584
+ cachedConfig = yield res.json();
585
+ return cachedConfig;
586
+ } catch (e) {
587
+ return null;
588
+ }
589
+ });
681
590
  }
682
- async function openFile(req) {
683
- try {
684
- const res = await fetch(`${BASE_URL}/open`, {
591
+ function openFile(req) {
592
+ return __async(this, null, function* () {
593
+ try {
594
+ const res = yield fetch(`${BASE_URL}${import_types.INSPECTO_API_PATHS.IDE_OPEN}`, {
595
+ method: "POST",
596
+ headers: { "Content-Type": "application/json" },
597
+ body: JSON.stringify(req)
598
+ });
599
+ return res.ok;
600
+ } catch (e) {
601
+ return false;
602
+ }
603
+ });
604
+ }
605
+ function fetchSnippet(file, line, column, maxLines = 100) {
606
+ return __async(this, null, function* () {
607
+ const params = new URLSearchParams({
608
+ file,
609
+ line: String(line),
610
+ column: String(column),
611
+ maxLines: String(maxLines)
612
+ });
613
+ const res = yield fetch(`${BASE_URL}${import_types.INSPECTO_API_PATHS.PROJECT_SNIPPET}?${params}`);
614
+ if (!res.ok) {
615
+ const err = yield res.json().catch(() => ({}));
616
+ throw Object.assign(new Error("snippet fetch failed"), { errorCode: err.errorCode });
617
+ }
618
+ return res.json();
619
+ });
620
+ }
621
+ function sendToAi(req) {
622
+ return __async(this, null, function* () {
623
+ var _a;
624
+ const res = yield fetch(`${BASE_URL}${import_types.INSPECTO_API_PATHS.AI_DISPATCH}`, {
685
625
  method: "POST",
686
626
  headers: { "Content-Type": "application/json" },
687
627
  body: JSON.stringify(req)
688
628
  });
689
- return res.ok;
690
- } catch {
691
- return false;
692
- }
693
- }
694
- async function fetchSnippet(file, line, column, maxLines = 100) {
695
- const params = new URLSearchParams({
696
- file,
697
- line: String(line),
698
- column: String(column),
699
- maxLines: String(maxLines)
629
+ if (!res.ok) {
630
+ const err = yield res.json().catch(() => ({}));
631
+ return {
632
+ success: false,
633
+ error: (_a = err.error) != null ? _a : "Request failed",
634
+ errorCode: err.errorCode
635
+ };
636
+ }
637
+ return res.json();
700
638
  });
701
- const res = await fetch(`${BASE_URL}/snippet?${params}`);
702
- if (!res.ok) {
703
- const err = await res.json().catch(() => ({}));
704
- throw Object.assign(new Error("snippet fetch failed"), { errorCode: err.errorCode });
705
- }
706
- return res.json();
707
639
  }
708
- async function sendToAi(req) {
709
- const res = await fetch(`${BASE_URL}/send-to-ai`, {
710
- method: "POST",
711
- headers: { "Content-Type": "application/json" },
712
- body: JSON.stringify(req)
713
- });
714
- if (!res.ok) {
715
- const err = await res.json().catch(() => ({}));
716
- return {
717
- success: false,
718
- error: err.error ?? "Request failed",
719
- errorCode: err.errorCode
720
- };
640
+ var import_types, BASE_URL, cachedConfig;
641
+ var init_http = __esm({
642
+ "src/http.ts"() {
643
+ "use strict";
644
+ import_types = require("@inspecto-dev/types");
645
+ BASE_URL = globalThis.__AI_INSPECTOR_SERVER_URL__ || "http://127.0.0.1:5678";
646
+ cachedConfig = null;
721
647
  }
722
- return res.json();
723
- }
648
+ });
724
649
 
725
650
  // src/menu.ts
726
- var MENU_WIDTH = 280;
727
651
  function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose) {
728
- const maxSnippetLines = options.maxSnippetLines ?? 100;
729
- const includeSnippet = options.includeSnippet ?? false;
652
+ var _a, _b;
653
+ const maxSnippetLines = (_a = options.maxSnippetLines) != null ? _a : 100;
654
+ const includeSnippet = (_b = options.includeSnippet) != null ? _b : false;
730
655
  const menu = document.createElement("div");
731
656
  menu.className = menuClass;
732
657
  const { input, inputWrapper, sendIcon } = createAskInput(options.askPlaceholder);
@@ -761,26 +686,33 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
761
686
  menu.remove();
762
687
  onClose();
763
688
  }
764
- const handleSend = async (promptText, snippetText, disable, restore) => {
689
+ const handleSend = (promptText, snippetText, disable, restore) => __async(null, null, function* () {
690
+ var _a2, _b2;
765
691
  disable();
766
- await openFile(location);
767
- await new Promise((r) => setTimeout(r, 100));
768
- const result = await sendToAi({ location, snippet: snippetText, prompt: promptText });
692
+ yield openFile(location);
693
+ yield new Promise((r) => setTimeout(r, 100));
694
+ const result = yield sendToAi({ location, snippet: snippetText, prompt: promptText });
769
695
  if (result.success) {
696
+ if ((_a2 = result.fallbackPayload) == null ? void 0 : _a2.prompt) {
697
+ try {
698
+ yield navigator.clipboard.writeText(result.fallbackPayload.prompt);
699
+ } catch (e) {
700
+ }
701
+ }
770
702
  cleanup();
771
703
  } else {
772
704
  restore();
773
- showError(menu, result.error ?? "Unknown error", result.errorCode);
705
+ showError(menu, (_b2 = result.error) != null ? _b2 : "Unknown error", result.errorCode);
774
706
  }
775
- };
776
- const submitAsk = async () => {
707
+ });
708
+ const submitAsk = () => __async(null, null, function* () {
777
709
  if (!input.value.trim()) return;
778
710
  input.disabled = true;
779
711
  sendIcon.style.pointerEvents = "none";
780
712
  try {
781
713
  let snippetResult = null;
782
714
  if (includeSnippet) {
783
- snippetResult = await fetchSnippet(
715
+ snippetResult = yield fetchSnippet(
784
716
  location.file,
785
717
  location.line,
786
718
  location.column,
@@ -792,9 +724,9 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
792
724
  location,
793
725
  snippetResult
794
726
  );
795
- await handleSend(
727
+ yield handleSend(
796
728
  prompt,
797
- snippetResult?.snippet || "",
729
+ (snippetResult == null ? void 0 : snippetResult.snippet) || "",
798
730
  () => {
799
731
  },
800
732
  // already disabled
@@ -808,20 +740,21 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
808
740
  sendIcon.style.pointerEvents = "auto";
809
741
  showError(menu, err.message, err.errorCode);
810
742
  }
811
- };
743
+ });
812
744
  input.addEventListener("keydown", (e) => {
813
745
  if (e.key === "Enter") submitAsk();
814
746
  });
815
747
  sendIcon.addEventListener("click", submitAsk);
816
748
  fetchIdeInfo().then((ideInfo) => {
749
+ var _a2, _b2, _c, _d;
817
750
  loadingEl.remove();
818
- const intents = resolveIntents(ideInfo?.prompts);
751
+ const intents = (ideInfo == null ? void 0 : ideInfo.prompts) || [];
819
752
  for (const intent of intents) {
820
753
  if (intent.isAction && intent.id === "open-in-editor") {
821
754
  const btn2 = document.createElement("button");
822
755
  btn2.className = menuItemClass;
823
756
  const span = document.createElement("span");
824
- span.textContent = intent.label ?? "Unknown";
757
+ span.textContent = (_a2 = intent.label) != null ? _a2 : "Unknown";
825
758
  btn2.appendChild(span);
826
759
  const shortcutDiv = document.createElement("div");
827
760
  shortcutDiv.className = shortcutIconClass;
@@ -835,23 +768,23 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
835
768
  menu.appendChild(btn2);
836
769
  continue;
837
770
  }
838
- let fullPromptTemplate = intent.prompt ?? "";
771
+ let fullPromptTemplate = (_b2 = intent.prompt) != null ? _b2 : "";
839
772
  if (intent.prependPrompt)
840
773
  fullPromptTemplate = intent.prependPrompt + "\n\n" + fullPromptTemplate;
841
774
  if (intent.appendPrompt)
842
775
  fullPromptTemplate = fullPromptTemplate + "\n\n" + intent.appendPrompt;
843
- const label = intent.label ?? intent.id ?? "Unknown";
776
+ const label = (_d = (_c = intent.label) != null ? _c : intent.id) != null ? _d : "Unknown";
844
777
  const btn = document.createElement("button");
845
778
  btn.className = menuItemClass;
846
779
  btn.textContent = label;
847
- btn.addEventListener("click", async (e) => {
780
+ btn.addEventListener("click", (e) => __async(null, null, function* () {
848
781
  e.stopPropagation();
849
782
  btn.disabled = true;
850
783
  btn.textContent = "Sending...";
851
784
  try {
852
785
  let snippetResult = null;
853
786
  if (includeSnippet) {
854
- snippetResult = await fetchSnippet(
787
+ snippetResult = yield fetchSnippet(
855
788
  location.file,
856
789
  location.line,
857
790
  location.column,
@@ -859,9 +792,9 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
859
792
  );
860
793
  }
861
794
  const prompt = buildPrompt(fullPromptTemplate, location, snippetResult);
862
- await handleSend(
795
+ yield handleSend(
863
796
  prompt,
864
- snippetResult?.snippet || "",
797
+ (snippetResult == null ? void 0 : snippetResult.snippet) || "",
865
798
  () => {
866
799
  },
867
800
  // already disabled
@@ -875,117 +808,30 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
875
808
  btn.textContent = label;
876
809
  showError(menu, err.message, err.errorCode);
877
810
  }
878
- });
811
+ }));
879
812
  menu.appendChild(btn);
880
813
  }
881
814
  updatePosition();
882
815
  }).catch((err) => {
816
+ var _a2;
883
817
  loadingEl.remove();
884
818
  const isServerDown = err instanceof TypeError;
885
819
  showError(
886
820
  menu,
887
821
  isServerDown ? "Cannot connect to inspector server. Is the dev server running?" : err.message,
888
- err.errorCode ?? "UNKNOWN"
822
+ (_a2 = err.errorCode) != null ? _a2 : "UNKNOWN"
889
823
  );
890
824
  updatePosition();
891
825
  });
892
826
  return cleanup;
893
827
  }
894
- function resolveIntents(serverPrompts) {
895
- const baseMap = /* @__PURE__ */ new Map();
896
- for (const intent of DEFAULT_INTENTS) {
897
- if (intent.id) baseMap.set(intent.id, { ...intent });
898
- }
899
- const defaults = () => ensureOpenInEditorLast(Array.from(baseMap.values()));
900
- if (!serverPrompts) return defaults();
901
- const isReplace = !Array.isArray(serverPrompts) && typeof serverPrompts === "object" && serverPrompts.$replace === true;
902
- const promptsArray = Array.isArray(serverPrompts) ? serverPrompts : isReplace ? serverPrompts.items : [];
903
- if (!promptsArray || promptsArray.length === 0) return defaults();
904
- if (isReplace) {
905
- const result = [];
906
- for (const item of promptsArray) {
907
- if (typeof item === "string") {
908
- if (baseMap.has(item)) {
909
- result.push(baseMap.get(item));
910
- } else {
911
- console.warn(
912
- `[inspecto] Unknown built-in intent id: "${item}". Available: ${[...baseMap.keys()].join(", ")}`
913
- );
914
- }
915
- } else if (typeof item === "object") {
916
- if (!item.id) {
917
- console.warn('[inspecto] Intent object missing required "id" field, skipping.');
918
- continue;
919
- }
920
- if (item.enabled === false) {
921
- console.warn(
922
- `[inspecto] Intent "${item.id}" is listed in $replace but has enabled:false \u2014 it will be excluded.`
923
- );
924
- continue;
925
- }
926
- if (item.isAction && item.id !== "open-in-editor") {
927
- console.warn(
928
- `[inspecto] isAction is reserved for built-in actions. Ignoring intent "${item.id}".`
929
- );
930
- continue;
931
- }
932
- result.push(baseMap.has(item.id) ? { ...baseMap.get(item.id), ...item } : item);
933
- }
934
- }
935
- return ensureOpenInEditorLast(result);
936
- }
937
- const merged = Array.from(baseMap.values());
938
- for (const item of promptsArray) {
939
- if (typeof item === "string") {
940
- if (!baseMap.has(item)) {
941
- console.warn(
942
- `[inspecto] Unknown built-in intent id: "${item}". In append mode, strings have no effect on ordering \u2014 use $replace to control order.`
943
- );
944
- }
945
- continue;
946
- }
947
- if (typeof item === "object") {
948
- if (!item.id) {
949
- console.warn('[inspecto] Intent object missing required "id" field, skipping.');
950
- continue;
951
- }
952
- if (item.isAction && item.id !== "open-in-editor") {
953
- console.warn(
954
- `[inspecto] isAction is reserved for built-in actions. Ignoring intent "${item.id}".`
955
- );
956
- continue;
957
- }
958
- const existingIdx = merged.findIndex((i) => i.id === item.id);
959
- if (existingIdx !== -1) {
960
- if (item.enabled === false) {
961
- merged.splice(existingIdx, 1);
962
- } else {
963
- merged[existingIdx] = { ...merged[existingIdx], ...item };
964
- }
965
- } else {
966
- if (item.enabled !== false) {
967
- merged.push(item);
968
- }
969
- }
970
- }
971
- }
972
- return ensureOpenInEditorLast(merged);
973
- }
974
- function ensureOpenInEditorLast(intents) {
975
- const idx = intents.findIndex((i) => i.id === "open-in-editor");
976
- if (idx === -1 || idx === intents.length - 1) return intents;
977
- const result = [...intents];
978
- const item = result.splice(idx, 1)[0];
979
- result.push(item);
980
- return result;
981
- }
982
828
  function createAskInput(placeholder) {
983
829
  const inputWrapper = document.createElement("div");
984
830
  inputWrapper.className = menuInputWrapperClass;
985
831
  const input = document.createElement("input");
986
832
  input.className = menuInputClass;
987
833
  input.type = "text";
988
- input.placeholder = placeholder ?? "Describe how to change this component...";
834
+ input.placeholder = placeholder != null ? placeholder : "Describe how to change this component...";
989
835
  const sendIcon = document.createElement("div");
990
836
  sendIcon.className = menuInputIconClass;
991
837
  sendIcon.innerHTML = `<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>`;
@@ -995,15 +841,29 @@ function createAskInput(placeholder) {
995
841
  return { input, inputWrapper, sendIcon };
996
842
  }
997
843
  function showError(menu, message, errorCode) {
998
- menu.querySelector(`.${errorMsgClass}`)?.remove();
844
+ var _a;
845
+ (_a = menu.querySelector(`.${errorMsgClass}`)) == null ? void 0 : _a.remove();
999
846
  const errEl = document.createElement("div");
1000
847
  errEl.className = errorMsgClass;
1001
848
  errEl.textContent = errorCode === "FILE_NOT_FOUND" ? "Source file not found. Is the server running?" : `Error: ${message}`;
1002
849
  menu.appendChild(errEl);
1003
850
  }
851
+ var MENU_WIDTH;
852
+ var init_menu = __esm({
853
+ "src/menu.ts"() {
854
+ "use strict";
855
+ init_intents();
856
+ init_http();
857
+ init_styles();
858
+ MENU_WIDTH = 280;
859
+ }
860
+ });
1004
861
 
1005
862
  // src/component.ts
1006
- var ATTR_NAME = "data-inspecto";
863
+ var component_exports = {};
864
+ __export(component_exports, {
865
+ InspectoElement: () => InspectoElement
866
+ });
1007
867
  function parseAttrValue(value) {
1008
868
  const parts = value.split(":");
1009
869
  if (parts.length < 3) return null;
@@ -1020,277 +880,329 @@ function findInspectable(el) {
1020
880
  }
1021
881
  return null;
1022
882
  }
883
+ function parseHotKeyString(hotKey) {
884
+ const keys = hotKey.split("+").map((k) => k.trim().toLowerCase());
885
+ const result = [];
886
+ if (keys.includes("alt") || keys.includes("option")) result.push("altKey");
887
+ if (keys.includes("ctrl") || keys.includes("control")) result.push("ctrlKey");
888
+ if (keys.includes("meta") || keys.includes("cmd") || keys.includes("command") || keys.includes("win"))
889
+ result.push("metaKey");
890
+ if (keys.includes("shift")) result.push("shiftKey");
891
+ return result;
892
+ }
1023
893
  function hotKeysHeld(event, hotKeys) {
1024
- return hotKeys.every((key) => event[key]);
894
+ if (!hotKeys) return false;
895
+ const mappedKeys = parseHotKeyString(hotKeys);
896
+ if (mappedKeys.length === 0) return false;
897
+ return mappedKeys.every((key) => event[key]);
1025
898
  }
1026
- var BaseElement = typeof HTMLElement !== "undefined" ? HTMLElement : class {
1027
- };
1028
- var InspectoElement = class extends BaseElement {
1029
- constructor() {
1030
- super(...arguments);
1031
- this.options = {};
1032
- this.serverHotKeys = null;
1033
- this.active = false;
1034
- this.disabled = false;
1035
- this.isDragging = false;
1036
- this.hasMoved = false;
1037
- this.dragStartX = 0;
1038
- this.dragStartY = 0;
1039
- this.badgeInitialRight = 16;
1040
- this.badgeInitialBottom = 16;
1041
- this.cleanupMenu = null;
1042
- this.onDragStart = (e) => {
1043
- if (e.button !== 0) return;
1044
- if (e.target.classList?.contains(`${badgeClass}-close`)) return;
1045
- e.preventDefault();
1046
- this.isDragging = true;
1047
- this.hasMoved = false;
1048
- const rect = this.badge.getBoundingClientRect();
1049
- this.dragStartX = e.clientX - rect.left;
1050
- this.dragStartY = e.clientY - rect.top;
1051
- document.addEventListener("mousemove", this.onDragMove);
1052
- document.addEventListener("mouseup", this.onDragEnd);
899
+ var ATTR_NAME, BaseElement, InspectoElement;
900
+ var init_component = __esm({
901
+ "src/component.ts"() {
902
+ "use strict";
903
+ init_overlay();
904
+ init_menu();
905
+ init_http();
906
+ init_styles();
907
+ ATTR_NAME = "data-inspecto";
908
+ BaseElement = typeof HTMLElement !== "undefined" ? HTMLElement : class {
1053
909
  };
1054
- this.onDragMove = (e) => {
1055
- if (!this.isDragging) return;
1056
- this.hasMoved = true;
1057
- let newLeft = e.clientX - this.dragStartX;
1058
- let newTop = e.clientY - this.dragStartY;
1059
- const badgeWidth = this.badge.offsetWidth;
1060
- const badgeHeight = this.badge.offsetHeight;
1061
- newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - badgeWidth));
1062
- newTop = Math.max(0, Math.min(newTop, window.innerHeight - badgeHeight));
1063
- this.badge.style.transition = "none";
1064
- this.badge.style.right = "auto";
1065
- this.badge.style.bottom = "auto";
1066
- this.badge.style.left = `${newLeft}px`;
1067
- this.badge.style.top = `${newTop}px`;
1068
- };
1069
- this.onDragEnd = () => {
1070
- document.removeEventListener("mousemove", this.onDragMove);
1071
- document.removeEventListener("mouseup", this.onDragEnd);
1072
- this.badge.style.transition = "";
1073
- setTimeout(() => {
910
+ InspectoElement = class extends BaseElement {
911
+ constructor() {
912
+ super(...arguments);
913
+ this.options = {};
914
+ this.serverHotKeys = null;
915
+ this.active = false;
916
+ this.disabled = false;
1074
917
  this.isDragging = false;
1075
- }, 0);
1076
- };
1077
- this.onMouseMove = (e) => {
1078
- const isActive = this.isInspectorActive(e);
1079
- if (!isActive) {
1080
- this.overlay.hide();
1081
- return;
918
+ this.hasMoved = false;
919
+ this.dragStartX = 0;
920
+ this.dragStartY = 0;
921
+ this.badgeInitialRight = 16;
922
+ this.badgeInitialBottom = 16;
923
+ this.cleanupMenu = null;
924
+ this.onDragStart = (e) => {
925
+ var _a;
926
+ if (e.button !== 0) return;
927
+ if ((_a = e.target.classList) == null ? void 0 : _a.contains(`${badgeClass}-close`)) return;
928
+ e.preventDefault();
929
+ this.isDragging = true;
930
+ this.hasMoved = false;
931
+ const rect = this.badge.getBoundingClientRect();
932
+ this.dragStartX = e.clientX - rect.left;
933
+ this.dragStartY = e.clientY - rect.top;
934
+ document.addEventListener("mousemove", this.onDragMove);
935
+ document.addEventListener("mouseup", this.onDragEnd);
936
+ };
937
+ this.onDragMove = (e) => {
938
+ if (!this.isDragging) return;
939
+ this.hasMoved = true;
940
+ let newLeft = e.clientX - this.dragStartX;
941
+ let newTop = e.clientY - this.dragStartY;
942
+ const badgeWidth = this.badge.offsetWidth;
943
+ const badgeHeight = this.badge.offsetHeight;
944
+ newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - badgeWidth));
945
+ newTop = Math.max(0, Math.min(newTop, window.innerHeight - badgeHeight));
946
+ this.badge.style.transition = "none";
947
+ this.badge.style.right = "auto";
948
+ this.badge.style.bottom = "auto";
949
+ this.badge.style.left = `${newLeft}px`;
950
+ this.badge.style.top = `${newTop}px`;
951
+ };
952
+ this.onDragEnd = () => {
953
+ document.removeEventListener("mousemove", this.onDragMove);
954
+ document.removeEventListener("mouseup", this.onDragEnd);
955
+ this.badge.style.transition = "";
956
+ setTimeout(() => {
957
+ this.isDragging = false;
958
+ }, 0);
959
+ };
960
+ this.onMouseMove = (e) => {
961
+ var _a;
962
+ const isActive = this.isInspectorActive(e);
963
+ if (!isActive) {
964
+ this.overlay.hide();
965
+ return;
966
+ }
967
+ const target = findInspectable(e.target);
968
+ if (!target) {
969
+ this.overlay.hide();
970
+ return;
971
+ }
972
+ const attrValue = target.getAttribute(ATTR_NAME);
973
+ const loc = parseAttrValue(attrValue);
974
+ const label = loc ? `${(_a = loc.file.split("/").pop()) != null ? _a : ""}:${loc.line}` : attrValue;
975
+ this.overlay.show(target, label);
976
+ e.stopPropagation();
977
+ };
978
+ this.onClick = (e) => {
979
+ this.handleTrigger(e);
980
+ };
981
+ this.onContextMenu = (e) => {
982
+ if (this.isInspectorActive(e)) {
983
+ this.handleTrigger(e);
984
+ }
985
+ };
986
+ this.onKeyDown = (e) => {
987
+ var _a;
988
+ if (e.key === "Escape") {
989
+ (_a = this.cleanupMenu) == null ? void 0 : _a.call(this);
990
+ this.overlay.hide();
991
+ }
992
+ };
1082
993
  }
1083
- const target = findInspectable(e.target);
1084
- if (!target) {
1085
- this.overlay.hide();
1086
- return;
994
+ connectedCallback() {
995
+ this.shadowRootEl = this.attachShadow({ mode: "open" });
996
+ const style = document.createElement("style");
997
+ style.textContent = inspectorStyles;
998
+ this.shadowRootEl.appendChild(style);
999
+ this.overlay = createOverlay(this.shadowRootEl);
1000
+ this.badge = this.createBadge();
1001
+ this.setupListeners();
1002
+ if (this.options.defaultActive) {
1003
+ this.setActive(true);
1004
+ }
1087
1005
  }
1088
- const attrValue = target.getAttribute(ATTR_NAME);
1089
- const loc = parseAttrValue(attrValue);
1090
- const label = loc ? `${loc.file.split("/").pop() ?? ""}:${loc.line}` : attrValue;
1091
- this.overlay.show(target, label);
1092
- e.stopPropagation();
1093
- };
1094
- this.onClick = (e) => {
1095
- this.handleTrigger(e);
1096
- };
1097
- this.onContextMenu = (e) => {
1098
- if (this.isInspectorActive(e)) {
1099
- this.handleTrigger(e);
1006
+ disconnectedCallback() {
1007
+ this.teardownListeners();
1100
1008
  }
1101
- };
1102
- this.onKeyDown = (e) => {
1103
- if (e.key === "Escape") {
1104
- this.cleanupMenu?.();
1105
- this.overlay.hide();
1009
+ configure(options) {
1010
+ this.options = options;
1011
+ if (options.serverUrl) {
1012
+ setBaseUrl(options.serverUrl);
1013
+ }
1014
+ if (options.theme === "dark") {
1015
+ this.setAttribute("data-theme", "dark");
1016
+ } else if (options.theme === "light") {
1017
+ this.setAttribute("data-theme", "light");
1018
+ } else {
1019
+ this.removeAttribute("data-theme");
1020
+ }
1021
+ fetchIdeInfo(true).then((info) => {
1022
+ if ((info == null ? void 0 : info.hotKeys) !== void 0) {
1023
+ this.serverHotKeys = info.hotKeys;
1024
+ this.updateBadgeContent();
1025
+ }
1026
+ if ((info == null ? void 0 : info.theme) !== void 0) {
1027
+ if (info.theme === "dark") {
1028
+ this.setAttribute("data-theme", "dark");
1029
+ } else if (info.theme === "light") {
1030
+ this.setAttribute("data-theme", "light");
1031
+ } else {
1032
+ this.removeAttribute("data-theme");
1033
+ }
1034
+ }
1035
+ if ((info == null ? void 0 : info.includeSnippet) !== void 0) {
1036
+ this.options.includeSnippet = info.includeSnippet;
1037
+ }
1038
+ }).catch(() => {
1039
+ });
1106
1040
  }
1107
- };
1108
- }
1109
- connectedCallback() {
1110
- this.shadowRootEl = this.attachShadow({ mode: "open" });
1111
- const style = document.createElement("style");
1112
- style.textContent = inspectorStyles;
1113
- this.shadowRootEl.appendChild(style);
1114
- this.overlay = createOverlay(this.shadowRootEl);
1115
- this.badge = this.createBadge();
1116
- this.setupListeners();
1117
- if (this.options.defaultActive) {
1118
- this.setActive(true);
1119
- }
1120
- }
1121
- disconnectedCallback() {
1122
- this.teardownListeners();
1123
- }
1124
- configure(options) {
1125
- this.options = options;
1126
- if (options.serverUrl) {
1127
- setBaseUrl(options.serverUrl);
1128
- }
1129
- if (options.theme === "dark") {
1130
- this.setAttribute("data-theme", "dark");
1131
- } else if (options.theme === "light") {
1132
- this.setAttribute("data-theme", "light");
1133
- } else {
1134
- this.removeAttribute("data-theme");
1135
- }
1136
- fetchIdeInfo(true).then((info) => {
1137
- if (info?.hotKeys !== void 0) {
1138
- this.serverHotKeys = info.hotKeys;
1041
+ createBadge() {
1042
+ const btn = document.createElement("button");
1043
+ btn.className = badgeClass;
1044
+ btn.style.display = "flex";
1045
+ const textSpan = document.createElement("span");
1046
+ textSpan.textContent = "Inspecto Ready";
1047
+ const closeBtn = document.createElement("span");
1048
+ closeBtn.className = `${badgeClass}-close`;
1049
+ closeBtn.innerHTML = "\xD7";
1050
+ closeBtn.title = "Pause Inspector";
1051
+ closeBtn.addEventListener("click", (e) => {
1052
+ e.stopPropagation();
1053
+ this.toggleDisabled();
1054
+ });
1055
+ btn.appendChild(textSpan);
1056
+ btn.appendChild(closeBtn);
1057
+ btn.addEventListener("mousedown", this.onDragStart);
1058
+ btn.addEventListener("click", (e) => {
1059
+ if (this.hasMoved) {
1060
+ this.hasMoved = false;
1061
+ return;
1062
+ }
1063
+ if (this.disabled) {
1064
+ this.toggleDisabled();
1065
+ } else {
1066
+ this.setActive(!this.active);
1067
+ }
1068
+ });
1069
+ this.shadowRootEl.appendChild(btn);
1070
+ return btn;
1071
+ }
1072
+ toggleDisabled() {
1073
+ var _a;
1074
+ this.disabled = !this.disabled;
1075
+ if (this.disabled) {
1076
+ this.active = false;
1077
+ this.overlay.hide();
1078
+ (_a = this.cleanupMenu) == null ? void 0 : _a.call(this);
1079
+ this.cleanupMenu = null;
1080
+ }
1139
1081
  this.updateBadgeContent();
1140
1082
  }
1141
- if (info?.includeSnippet !== void 0) {
1142
- this.options.includeSnippet = info.includeSnippet;
1083
+ dismiss() {
1084
+ this.badge.style.display = "none";
1085
+ this.setActive(false);
1143
1086
  }
1144
- }).catch(() => {
1145
- });
1146
- }
1147
- createBadge() {
1148
- const btn = document.createElement("button");
1149
- btn.className = badgeClass;
1150
- btn.style.display = "flex";
1151
- const textSpan = document.createElement("span");
1152
- textSpan.textContent = "Inspecto Ready";
1153
- const closeBtn = document.createElement("span");
1154
- closeBtn.className = `${badgeClass}-close`;
1155
- closeBtn.innerHTML = "\xD7";
1156
- closeBtn.title = "Pause Inspector";
1157
- closeBtn.addEventListener("click", (e) => {
1158
- e.stopPropagation();
1159
- this.toggleDisabled();
1160
- });
1161
- btn.appendChild(textSpan);
1162
- btn.appendChild(closeBtn);
1163
- btn.addEventListener("mousedown", this.onDragStart);
1164
- btn.addEventListener("click", (e) => {
1165
- if (this.hasMoved) {
1166
- this.hasMoved = false;
1167
- return;
1087
+ getHotKeyHint() {
1088
+ const hotKeys = this.getEffectiveHotKeys();
1089
+ if (hotKeys === false) return "Inspecto Ready";
1090
+ const isMac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
1091
+ const keys = hotKeys.split("+").map((k) => k.trim().toLowerCase());
1092
+ const displayKeys = keys.map((k) => {
1093
+ if (k === "alt" || k === "option") return isMac ? "\u2325" : "Alt";
1094
+ if (k === "cmd" || k === "meta" || k === "win" || k === "command") return isMac ? "\u2318" : "Win";
1095
+ if (k === "ctrl" || k === "control") return isMac ? "\u2303" : "Ctrl";
1096
+ if (k === "shift") return isMac ? "\u21E7" : "Shift";
1097
+ return k.charAt(0).toUpperCase() + k.slice(1);
1098
+ });
1099
+ return `Hold ${displayKeys.join(" + ")} to Inspect`;
1168
1100
  }
1169
- if (this.disabled) {
1170
- this.toggleDisabled();
1171
- } else {
1172
- this.setActive(!this.active);
1101
+ getEffectiveHotKeys() {
1102
+ if (this.options.hotKeys !== void 0) return this.options.hotKeys;
1103
+ if (this.serverHotKeys !== null) return this.serverHotKeys;
1104
+ return "alt";
1173
1105
  }
1174
- });
1175
- this.shadowRootEl.appendChild(btn);
1176
- return btn;
1177
- }
1178
- toggleDisabled() {
1179
- this.disabled = !this.disabled;
1180
- if (this.disabled) {
1181
- this.active = false;
1182
- this.overlay.hide();
1183
- this.cleanupMenu?.();
1184
- this.cleanupMenu = null;
1185
- }
1186
- this.updateBadgeContent();
1187
- }
1188
- dismiss() {
1189
- this.badge.style.display = "none";
1190
- this.setActive(false);
1191
- }
1192
- getHotKeyHint() {
1193
- const hotKeys = this.getEffectiveHotKeys();
1194
- if (hotKeys === false || hotKeys.length === 0) return "Inspecto Ready";
1195
- const isMac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
1196
- const keys = hotKeys.map((k) => {
1197
- if (k === "altKey") return isMac ? "\u2325" : "Alt";
1198
- if (k === "metaKey") return isMac ? "\u2318" : "Win";
1199
- if (k === "ctrlKey") return isMac ? "\u2303" : "Ctrl";
1200
- if (k === "shiftKey") return isMac ? "\u21E7" : "Shift";
1201
- return k;
1202
- });
1203
- return `Hold ${keys.join(" + ")} to Inspect`;
1204
- }
1205
- getEffectiveHotKeys() {
1206
- if (this.options.hotKeys !== void 0) return this.options.hotKeys;
1207
- if (this.serverHotKeys !== null) return this.serverHotKeys;
1208
- return ["altKey"];
1209
- }
1210
- updateBadgeContent() {
1211
- const textSpan = this.badge.querySelector("span");
1212
- if (!textSpan) return;
1213
- if (this.disabled) {
1214
- textSpan.textContent = "Inspector Paused";
1215
- this.badge.classList.remove("active");
1216
- this.badge.classList.add("disabled");
1217
- } else if (this.active) {
1218
- textSpan.textContent = "\u{1F50D} Inspecting...";
1219
- this.badge.classList.remove("disabled");
1220
- this.badge.classList.add("active");
1221
- } else {
1222
- textSpan.textContent = this.getHotKeyHint();
1223
- this.badge.classList.remove("active", "disabled");
1224
- }
1225
- }
1226
- setActive(value) {
1227
- this.active = value;
1228
- this.updateBadgeContent();
1229
- if (!value) {
1230
- this.overlay.hide();
1231
- this.cleanupMenu?.();
1232
- this.cleanupMenu = null;
1233
- }
1234
- }
1235
- handleTrigger(e) {
1236
- if (!this.isInspectorActive(e)) return;
1237
- const target = findInspectable(e.target);
1238
- if (!target) return;
1239
- e.preventDefault();
1240
- e.stopPropagation();
1241
- const attrValue = target.getAttribute(ATTR_NAME);
1242
- const loc = parseAttrValue(attrValue);
1243
- if (!loc) return;
1244
- this.cleanupMenu?.();
1245
- this.cleanupMenu = showIntentMenu(
1246
- this.shadowRootEl,
1247
- loc,
1248
- e.clientX,
1249
- e.clientY,
1250
- this.options,
1251
- () => {
1252
- this.cleanupMenu = null;
1106
+ updateBadgeContent() {
1107
+ const textSpan = this.badge.querySelector("span");
1108
+ if (!textSpan) return;
1109
+ if (this.disabled) {
1110
+ textSpan.textContent = "Inspector Paused";
1111
+ this.badge.classList.remove("active");
1112
+ this.badge.classList.add("disabled");
1113
+ } else if (this.active) {
1114
+ textSpan.textContent = "\u{1F50D} Inspecting...";
1115
+ this.badge.classList.remove("disabled");
1116
+ this.badge.classList.add("active");
1117
+ } else {
1118
+ textSpan.textContent = this.getHotKeyHint();
1119
+ this.badge.classList.remove("active", "disabled");
1120
+ }
1253
1121
  }
1254
- );
1255
- }
1256
- isInspectorActive(e) {
1257
- if (this.disabled) return false;
1258
- if (this.active) return true;
1259
- const hotKeys = this.getEffectiveHotKeys();
1260
- if (hotKeys === false) return false;
1261
- return hotKeysHeld(e, hotKeys);
1262
- }
1263
- setupListeners() {
1264
- document.addEventListener("mousemove", this.onMouseMove, true);
1265
- document.addEventListener("click", this.onClick, true);
1266
- document.addEventListener("contextmenu", this.onContextMenu, true);
1267
- document.addEventListener("keydown", this.onKeyDown, true);
1268
- }
1269
- teardownListeners() {
1270
- document.removeEventListener("mousemove", this.onMouseMove, true);
1271
- document.removeEventListener("click", this.onClick, true);
1272
- document.removeEventListener("contextmenu", this.onContextMenu, true);
1273
- document.removeEventListener("keydown", this.onKeyDown, true);
1122
+ setActive(value) {
1123
+ var _a;
1124
+ this.active = value;
1125
+ this.updateBadgeContent();
1126
+ if (!value) {
1127
+ this.overlay.hide();
1128
+ (_a = this.cleanupMenu) == null ? void 0 : _a.call(this);
1129
+ this.cleanupMenu = null;
1130
+ }
1131
+ }
1132
+ handleTrigger(e) {
1133
+ var _a;
1134
+ if (!this.isInspectorActive(e)) return;
1135
+ const target = findInspectable(e.target);
1136
+ if (!target) return;
1137
+ e.preventDefault();
1138
+ e.stopPropagation();
1139
+ const attrValue = target.getAttribute(ATTR_NAME);
1140
+ const loc = parseAttrValue(attrValue);
1141
+ if (!loc) return;
1142
+ (_a = this.cleanupMenu) == null ? void 0 : _a.call(this);
1143
+ this.cleanupMenu = showIntentMenu(
1144
+ this.shadowRootEl,
1145
+ loc,
1146
+ e.clientX,
1147
+ e.clientY,
1148
+ this.options,
1149
+ () => {
1150
+ this.cleanupMenu = null;
1151
+ }
1152
+ );
1153
+ }
1154
+ isInspectorActive(e) {
1155
+ if (this.disabled) return false;
1156
+ if (this.active) return true;
1157
+ const hotKeys = this.getEffectiveHotKeys();
1158
+ if (hotKeys === false) return false;
1159
+ return hotKeysHeld(e, hotKeys);
1160
+ }
1161
+ setupListeners() {
1162
+ document.addEventListener("mousemove", this.onMouseMove, true);
1163
+ document.addEventListener("click", this.onClick, true);
1164
+ document.addEventListener("contextmenu", this.onContextMenu, true);
1165
+ document.addEventListener("keydown", this.onKeyDown, true);
1166
+ }
1167
+ teardownListeners() {
1168
+ document.removeEventListener("mousemove", this.onMouseMove, true);
1169
+ document.removeEventListener("click", this.onClick, true);
1170
+ document.removeEventListener("contextmenu", this.onContextMenu, true);
1171
+ document.removeEventListener("keydown", this.onKeyDown, true);
1172
+ }
1173
+ };
1174
+ if (typeof customElements !== "undefined") {
1175
+ customElements.define("inspecto-overlay", InspectoElement);
1176
+ }
1274
1177
  }
1275
- };
1276
- if (typeof customElements !== "undefined") {
1277
- customElements.define("inspecto-overlay", InspectoElement);
1278
- }
1178
+ });
1279
1179
 
1280
1180
  // src/index.ts
1181
+ var src_exports = {};
1182
+ __export(src_exports, {
1183
+ mountInspector: () => mountInspector,
1184
+ unmountInspector: () => unmountInspector
1185
+ });
1186
+ module.exports = __toCommonJS(src_exports);
1281
1187
  var TAG_NAME = "inspecto-overlay";
1282
- function mountInspector(options = {}) {
1283
- const existing = document.querySelector(TAG_NAME);
1284
- if (existing) {
1285
- existing.configure(options);
1286
- return existing;
1287
- }
1288
- const el = document.createElement(TAG_NAME);
1289
- el.configure(options);
1290
- document.body.appendChild(el);
1291
- return el;
1188
+ function mountInspector() {
1189
+ return __async(this, arguments, function* (options = {}) {
1190
+ if (typeof document === "undefined") return null;
1191
+ const { InspectoElement: InspectoElement2 } = yield Promise.resolve().then(() => (init_component(), component_exports));
1192
+ const existing = document.querySelector(TAG_NAME);
1193
+ if (existing) {
1194
+ ;
1195
+ existing.configure(options);
1196
+ return existing;
1197
+ }
1198
+ const el = document.createElement(TAG_NAME);
1199
+ el.configure(options);
1200
+ document.body.appendChild(el);
1201
+ return el;
1202
+ });
1292
1203
  }
1293
1204
  function unmountInspector() {
1205
+ if (typeof document === "undefined") return;
1294
1206
  const existing = document.querySelector(TAG_NAME);
1295
1207
  if (existing) {
1296
1208
  existing.remove();