@inspecto-dev/core 0.2.0-alpha.2 → 0.2.0-alpha.4

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.
@@ -603,13 +603,20 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
603
603
  const loadingEl = document.createElement("div");
604
604
  loadingEl.className = loadingSpinnerClass;
605
605
  menu.appendChild(loadingEl);
606
- menu.style.left = `${Math.min(clickX, window.innerWidth - MENU_WIDTH)}px`;
606
+ const viewportWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
607
+ const safeWidth = viewportWidth > 0 ? viewportWidth : MENU_WIDTH;
608
+ menu.style.left = `${Math.min(clickX, Math.max(safeWidth - MENU_WIDTH, 0))}px`;
607
609
  menu.style.visibility = "hidden";
608
610
  menu.style.display = "block";
609
611
  shadowRoot.appendChild(menu);
610
612
  const updatePosition = () => {
611
613
  const rect = menu.getBoundingClientRect();
612
- menu.style.top = `${Math.min(clickY + 8, window.innerHeight - rect.height - 8)}px`;
614
+ const viewportHeight = Math.max(
615
+ document.documentElement.clientHeight || 0,
616
+ window.innerHeight || 0
617
+ );
618
+ const safeHeight = viewportHeight > 0 ? viewportHeight : rect.height + 16;
619
+ menu.style.top = `${Math.min(clickY + 8, Math.max(safeHeight - rect.height - 8, 0))}px`;
613
620
  };
614
621
  updatePosition();
615
622
  menu.style.visibility = "visible";
@@ -628,7 +635,12 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
628
635
  const handleSend = (promptText, snippetText, disable, restore) => __async(null, null, function* () {
629
636
  var _a2, _b2;
630
637
  disable();
631
- yield openFile(location);
638
+ const opened = yield openFile(location);
639
+ if (!opened) {
640
+ restore();
641
+ showError(menu, "Unable to open file in the IDE.", "IDE_UNAVAILABLE");
642
+ return;
643
+ }
632
644
  yield new Promise((r) => setTimeout(r, 100));
633
645
  const result = yield sendToAi({ location, snippet: snippetText, prompt: promptText });
634
646
  if (result.success) {
@@ -699,11 +711,17 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
699
711
  shortcutDiv.className = shortcutIconClass;
700
712
  shortcutDiv.textContent = "\u21B5";
701
713
  btn2.appendChild(shortcutDiv);
702
- btn2.addEventListener("click", (e) => {
714
+ btn2.addEventListener("click", (e) => __async(null, null, function* () {
703
715
  e.stopPropagation();
704
- openFile(location);
705
- cleanup();
706
- });
716
+ btn2.disabled = true;
717
+ const opened = yield openFile(location);
718
+ if (opened) {
719
+ cleanup();
720
+ return;
721
+ }
722
+ btn2.disabled = false;
723
+ showError(menu, "Unable to open file in the IDE.", "IDE_UNAVAILABLE");
724
+ }));
707
725
  menu.appendChild(btn2);
708
726
  continue;
709
727
  }
@@ -1094,4 +1112,4 @@ if (typeof customElements !== "undefined") {
1094
1112
  export {
1095
1113
  InspectoElement
1096
1114
  };
1097
- //# sourceMappingURL=component-4WPU23TV.js.map
1115
+ //# sourceMappingURL=component-VOGY7YTT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/styles.ts","../src/overlay.ts","../src/intents.ts","../src/http.ts","../src/menu.ts","../src/component.ts"],"sourcesContent":["export const overlayClass = 'inspecto-overlay'\nexport const menuClass = 'inspecto-menu'\nexport const menuTitleClass = 'inspecto-menu-title'\nexport const menuItemClass = 'inspecto-menu-item'\nexport const loadingSpinnerClass = 'inspecto-spinner'\nexport const errorMsgClass = 'inspecto-error'\nexport const badgeClass = 'inspecto-badge'\nexport const menuInputClass = 'inspecto-menu-input'\nexport const menuInputWrapperClass = 'inspecto-menu-input-wrapper'\nexport const menuInputIconClass = 'inspecto-menu-input-icon'\n\n// Tooltip & overlay specific classes\nexport const tooltipClass = 'inspecto-tooltip'\nexport const tooltipTopClass = 'inspecto-tooltip-top'\nexport const tooltipBottomClass = 'inspecto-tooltip-bottom'\nexport const tagClass = 'inspecto-tag'\nexport const idClass = 'inspecto-id'\nexport const classClass = 'inspecto-class'\nexport const dimClass = 'inspecto-dim'\nexport const separatorClass = 'inspecto-separator'\nexport const sourceClass = 'inspecto-source'\nexport const shortcutIconClass = 'ai-shortcut-icon'\n\nconst darkVars = `\n --inspecto-menu-bg: #252526;\n --inspecto-menu-border: #454545;\n --inspecto-menu-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);\n --inspecto-text: #cccccc;\n --inspecto-text-muted: #858585;\n --inspecto-hover-bg: #04395e;\n --inspecto-hover-text: #ffffff;\n --inspecto-hover-icon: #ffffff;\n --inspecto-input-bg: #3c3c3c;\n --inspecto-input-border: #007acc;\n --inspecto-shortcut-text: #858585;\n --inspecto-badge-bg: rgba(30, 30, 30, 0.7);\n --inspecto-badge-text: #e5e5e5;\n --inspecto-badge-active-bg: #007acc;\n --inspecto-badge-active-text: #ffffff;\n --inspecto-badge-border: 1px solid rgba(255, 255, 255, 0.1);\n \n --inspecto-tooltip-bg: #222222;\n --inspecto-tooltip-text: #cccccc;\n --inspecto-tooltip-border: #444;\n --inspecto-tooltip-shadow: 0 2px 10px rgba(0,0,0,0.5);\n --inspecto-tag-color: #d16969;\n --inspecto-id-color: #d16969;\n --inspecto-class-color: #9cdcfe;\n --inspecto-dim-color: #858585;\n --inspecto-error-color: #ef4444;\n`\n\nexport const inspectorStyles = `\n :host {\n /* Light theme (default) */\n --inspecto-menu-bg: #ffffff;\n --inspecto-menu-border: #d4d4d4;\n --inspecto-menu-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n --inspecto-text: #333333;\n --inspecto-text-muted: #6b7280;\n --inspecto-hover-bg: #0060c0;\n --inspecto-hover-text: #ffffff;\n --inspecto-hover-icon: #ffffff;\n --inspecto-input-bg: #ffffff;\n --inspecto-input-border: #007acc;\n --inspecto-shortcut-text: #9ca3af;\n --inspecto-badge-bg: rgba(30, 30, 30, 0.7);\n --inspecto-badge-text: #e5e5e5;\n --inspecto-badge-active-bg: #007acc;\n --inspecto-badge-active-text: #ffffff;\n --inspecto-badge-border: 1px solid rgba(255, 255, 255, 0.1);\n \n /* Chrome DevTools like colors */\n --inspecto-overlay-border: #4285f4; /* Google Blue */\n --inspecto-overlay-bg: rgba(66, 133, 244, 0.2); \n --inspecto-tooltip-bg: #ffffff;\n --inspecto-tooltip-text: #333333;\n --inspecto-tooltip-border: #ccc;\n --inspecto-tooltip-shadow: 0 2px 10px rgba(0,0,0,0.1);\n \n --inspecto-tag-color: #8b008b; /* Dark magenta */\n --inspecto-id-color: #8b008b;\n --inspecto-class-color: #00008b; /* Dark blue */\n --inspecto-dim-color: #555555;\n --inspecto-error-color: #ef4444;\n }\n\n :host([data-theme=\"dark\"]) {\n ${darkVars}\n }\n\n @media (prefers-color-scheme: dark) {\n :host(:not([data-theme=\"light\"])) {\n ${darkVars}\n }\n }\n\n .${overlayClass} {\n position: fixed;\n pointer-events: none;\n z-index: 2147483646;\n border: 1px dashed var(--inspecto-overlay-border);\n background: var(--inspecto-overlay-bg);\n box-sizing: border-box;\n transition: all 0.05s linear;\n }\n\n .${tooltipClass} {\n position: fixed;\n pointer-events: none;\n z-index: 2147483647;\n background: var(--inspecto-tooltip-bg);\n color: var(--inspecto-tooltip-text);\n border: 1px solid var(--inspecto-tooltip-border);\n border-radius: 4px;\n box-shadow: var(--inspecto-tooltip-shadow);\n padding: 6px 10px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 12px;\n line-height: 1.4;\n transition: all 0.05s linear;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n \n /* Create the small pointer arrow like Chrome DevTools */\n .${tooltipClass}::after {\n content: '';\n position: absolute;\n width: 0;\n height: 0;\n border-style: solid;\n }\n\n .${tooltipTopClass}::after {\n bottom: -6px;\n left: var(--inspecto-arrow-left, 10px);\n border-width: 6px 6px 0 6px;\n border-color: var(--inspecto-tooltip-bg) transparent transparent transparent;\n }\n\n .${tooltipBottomClass}::after {\n top: -6px;\n left: var(--inspecto-arrow-left, 10px);\n border-width: 0 6px 6px 6px;\n border-color: transparent transparent var(--inspecto-tooltip-bg) transparent;\n }\n \n /* Outline for the arrow to match border */\n .${tooltipClass}::before {\n content: '';\n position: absolute;\n width: 0;\n height: 0;\n border-style: solid;\n }\n \n .${tooltipTopClass}::before {\n bottom: -7px;\n left: calc(var(--inspecto-arrow-left, 10px) - 1px);\n border-width: 7px 7px 0 7px;\n border-color: var(--inspecto-tooltip-border) transparent transparent transparent;\n }\n \n .${tooltipBottomClass}::before {\n top: -7px;\n left: calc(var(--inspecto-arrow-left, 10px) - 1px);\n border-width: 0 7px 7px 7px;\n border-color: transparent transparent var(--inspecto-tooltip-border) transparent;\n }\n\n .${tagClass} {\n color: var(--inspecto-tag-color);\n font-weight: 600;\n font-family: monospace;\n }\n \n .${idClass} {\n color: var(--inspecto-id-color);\n font-weight: 600;\n font-family: monospace;\n }\n\n .${classClass} {\n color: var(--inspecto-class-color);\n font-family: monospace;\n }\n\n .${dimClass} {\n color: var(--inspecto-dim-color);\n margin-left: 4px;\n }\n \n .${separatorClass} {\n height: 1px;\n background: var(--inspecto-tooltip-border);\n margin: 2px -10px;\n opacity: 0.5;\n }\n \n .${sourceClass} {\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 11px;\n color: var(--inspecto-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n }\n\n .${menuClass} {\n position: fixed;\n z-index: 2147483647;\n background: var(--inspecto-menu-bg);\n border: 1px solid var(--inspecto-menu-border);\n border-radius: 6px;\n padding: 6px;\n min-width: 300px;\n box-shadow: var(--inspecto-menu-shadow);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n color: var(--inspecto-text);\n }\n\n .${menuInputWrapperClass} {\n display: flex;\n align-items: center;\n border: 1px solid var(--inspecto-menu-border);\n border-radius: 4px;\n padding: 6px 8px;\n margin: 4px;\n margin-bottom: 8px;\n }\n \n .${menuInputWrapperClass}:focus-within {\n border-color: var(--inspecto-input-border);\n }\n\n .${menuInputClass} {\n width: 100%;\n border: none;\n outline: none;\n font-size: 13px;\n color: var(--inspecto-text);\n background: transparent;\n }\n\n .${menuInputClass}::placeholder {\n color: var(--inspecto-text-muted);\n }\n\n .${menuInputIconClass} {\n color: var(--inspecto-text-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 4px;\n }\n\n .${menuInputIconClass}:hover {\n color: var(--inspecto-text);\n }\n\n .${menuItemClass} {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 10px;\n margin: 2px 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--inspecto-text);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n }\n\n .${menuItemClass}:hover {\n background: var(--inspecto-hover-bg);\n color: var(--inspecto-hover-text);\n }\n\n .${menuItemClass} .${shortcutIconClass} {\n margin-left: auto;\n color: var(--inspecto-text-muted);\n }\n\n .${menuItemClass}:hover .${shortcutIconClass} {\n color: var(--inspecto-hover-icon);\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .${loadingSpinnerClass} {\n width: 14px;\n height: 14px;\n border: 2px solid var(--inspecto-overlay-border);\n border-top-color: transparent;\n border-radius: 50%;\n animation: spin 0.7s linear infinite;\n margin: 4px auto;\n display: block;\n }\n\n .${errorMsgClass} {\n font-size: 11px;\n color: var(--inspecto-error-color);\n padding: 4px 8px;\n text-align: center;\n }\n\n .${badgeClass} {\n position: fixed;\n bottom: 16px;\n right: 16px;\n z-index: 2147483645;\n background: var(--inspecto-badge-bg);\n color: var(--inspecto-badge-text);\n border: var(--inspecto-badge-border);\n border-radius: 20px;\n padding: 6px 12px;\n font-size: 12px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n cursor: grab;\n opacity: 0.85;\n transition: background 0.2s, color 0.2s, opacity 0.2s, box-shadow 0.2s;\n pointer-events: all;\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n gap: 6px;\n user-select: none;\n -webkit-user-select: none;\n touch-action: none;\n }\n\n .${badgeClass}:active {\n cursor: grabbing;\n }\n\n .${badgeClass}-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: transparent;\n color: currentColor;\n font-size: 14px;\n line-height: 1;\n opacity: 0.5;\n transition: opacity 0.2s, background 0.2s;\n margin-left: 2px;\n cursor: pointer;\n }\n\n .${badgeClass}-close:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.2);\n }\n\n .${badgeClass}.active {\n background: var(--inspecto-badge-active-bg);\n color: var(--inspecto-badge-active-text);\n border: 1px solid transparent;\n box-shadow: 0 0 10px rgba(0, 122, 204, 0.3);\n }\n\n .${badgeClass}.disabled {\n background: rgba(30, 30, 30, 0.4);\n color: rgba(229, 229, 229, 0.5);\n text-decoration: line-through;\n border: 1px dashed rgba(255, 255, 255, 0.1);\n }\n\n .${badgeClass}.disabled .${badgeClass}-close {\n opacity: 0.8;\n text-decoration: none;\n transform: rotate(45deg);\n }\n\n .${badgeClass}:hover {\n opacity: 1;\n }\n`\n","import {\n overlayClass,\n tooltipClass,\n tooltipTopClass,\n tooltipBottomClass,\n tagClass,\n idClass,\n classClass,\n dimClass,\n separatorClass,\n sourceClass,\n} from './styles.js'\n\nconst GAP = 8\nconst EDGE_MARGIN = 4\n\nexport function createOverlay(shadowRoot: ShadowRoot): {\n show(el: Element, sourceLabel: string): void\n hide(): void\n} {\n const overlay = document.createElement('div')\n overlay.className = overlayClass\n overlay.style.display = 'none'\n\n const tooltip = document.createElement('div')\n tooltip.className = tooltipClass\n\n const tagSpan = document.createElement('span')\n tagSpan.className = tagClass\n\n const idSpan = document.createElement('span')\n idSpan.className = idClass\n\n const classSpan = document.createElement('span')\n classSpan.className = classClass\n\n const dimSpan = document.createElement('span')\n dimSpan.className = dimClass\n\n const separator = document.createElement('div')\n separator.className = separatorClass\n\n const sourceSpan = document.createElement('div')\n sourceSpan.className = sourceClass\n\n tooltip.appendChild(tagSpan)\n tooltip.appendChild(idSpan)\n tooltip.appendChild(classSpan)\n tooltip.appendChild(document.createTextNode(' '))\n tooltip.appendChild(dimSpan)\n tooltip.appendChild(separator)\n tooltip.appendChild(sourceSpan)\n\n shadowRoot.appendChild(overlay)\n shadowRoot.appendChild(tooltip)\n\n function show(el: Element, sourceLabel: string): void {\n const rect = el.getBoundingClientRect()\n\n // The overlay and tooltip are `position: fixed`, so we MUST use viewport coordinates (rect.left/top)\n // without adding window.scrollX/scrollY.\n\n // Update overlay box\n overlay.style.display = 'block'\n overlay.style.left = `${rect.left}px`\n overlay.style.top = `${rect.top}px`\n overlay.style.width = `${rect.width}px`\n overlay.style.height = `${rect.height}px`\n\n // Update tooltip content\n const tagName = el.tagName.toLowerCase()\n tagSpan.textContent = tagName\n\n idSpan.textContent = el.id ? `#${el.id}` : ''\n\n const classes = Array.from(el.classList)\n .map(c => `.${c}`)\n .join('')\n classSpan.textContent = classes\n\n dimSpan.textContent = `${Math.round(rect.width)} × ${Math.round(rect.height)}`\n\n sourceSpan.textContent = sourceLabel\n\n tooltip.style.visibility = 'hidden'\n tooltip.style.display = 'block'\n\n // Calculate tooltip position\n const tooltipRect = tooltip.getBoundingClientRect()\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth\n const viewportHeight = document.documentElement.clientHeight || window.innerHeight\n\n // Calculate vertical position (above or below)\n let tooltipTop = rect.top - tooltipRect.height - GAP\n let isBottom = false\n\n // If there's not enough space above, show it below\n if (tooltipTop < EDGE_MARGIN) {\n tooltipTop = rect.bottom + GAP\n // If showing below also goes off screen, clamp it to bottom of screen\n if (tooltipTop + tooltipRect.height > viewportHeight - EDGE_MARGIN) {\n tooltipTop = viewportHeight - tooltipRect.height - EDGE_MARGIN\n }\n isBottom = true\n }\n\n tooltip.classList.toggle(tooltipBottomClass, isBottom)\n tooltip.classList.toggle(tooltipTopClass, !isBottom)\n\n // Calculate horizontal position\n // Default to aligning with the left edge of the element\n let tooltipLeft = rect.left\n\n // Prevent overflowing the right edge\n if (tooltipLeft + tooltipRect.width > viewportWidth - EDGE_MARGIN) {\n tooltipLeft = viewportWidth - tooltipRect.width - EDGE_MARGIN\n }\n // Prevent overflowing the left edge\n if (tooltipLeft < EDGE_MARGIN) {\n tooltipLeft = EDGE_MARGIN\n }\n\n // Calculate arrow position so it always points at the element\n // The arrow normally points at rect.left + 10\n // But if the element is tiny, point at its center\n const targetPointX = rect.left + Math.min(15, rect.width / 2)\n\n // Calculate where the arrow should be relative to the tooltip\n let arrowLeft = targetPointX - tooltipLeft\n\n // Clamp arrow position so it doesn't detach from the tooltip bubble itself\n arrowLeft = Math.max(6, Math.min(arrowLeft, tooltipRect.width - 18))\n\n tooltip.style.left = `${tooltipLeft}px`\n tooltip.style.top = `${tooltipTop}px`\n tooltip.style.setProperty('--inspecto-arrow-left', `${arrowLeft}px`)\n\n tooltip.style.visibility = 'visible'\n }\n\n function hide(): void {\n overlay.style.display = 'none'\n tooltip.style.display = 'none'\n }\n\n return { show, hide }\n}\n","import type { SnippetResponse, SourceLocation } from '@inspecto-dev/types'\n\n/** Template for user-typed custom prompts from the ask input box. */\nexport function CUSTOM_PROMPT_TEMPLATE(userPrompt: string): string {\n return userPrompt\n}\n\n/**\n * Guess the UI framework based on file extension\n */\nfunction detectFramework(fileName: string): string {\n const ext = fileName.split('.').pop()?.toLowerCase() || ''\n switch (ext) {\n case 'vue':\n return 'Vue'\n case 'svelte':\n return 'Svelte'\n case 'astro':\n return 'Astro'\n case 'jsx':\n case 'tsx':\n return 'React'\n case 'ts':\n case 'js':\n return 'JavaScript/TypeScript'\n default:\n return 'UI'\n }\n}\n\n/**\n * Replace all {{placeholder}} tokens in a prompt template.\n */\nexport function buildPrompt(\n template: string,\n location: SourceLocation,\n snippetResult?: SnippetResponse | null,\n): string {\n const shortFile = location.file.split('/').pop() ?? location.file\n const ext = shortFile.split('.').pop()?.toLowerCase() || 'tsx'\n const framework = detectFramework(shortFile)\n\n let finalPrompt = template\n .replace(/\\{\\{file\\}\\}/g, location.file)\n .replace(/\\{\\{line\\}\\}/g, String(location.line))\n .replace(/\\{\\{column\\}\\}/g, String(location.column))\n .replace(/\\{\\{ext\\}\\}/g, ext)\n .replace(/\\{\\{framework\\}\\}/g, framework)\n .replace(/\\{\\{name\\}\\}/g, shortFile) // fallback\n\n if (snippetResult && snippetResult.snippet) {\n const name = snippetResult.name ?? shortFile\n finalPrompt = finalPrompt.replace(/\\{\\{name\\}\\}/g, name)\n // append snippet context\n finalPrompt += `\\n\\nContext from \\`${location.file}\\` (line ${location.line}):\\n\\`\\`\\`${ext}\\n${snippetResult.snippet}\\n\\`\\`\\``\n }\n\n return finalPrompt\n}\n","import type {\n SnippetResponse,\n SendToAiRequest,\n SendToAiResponse,\n OpenFileRequest,\n InspectoConfig,\n AiErrorCode,\n} from '@inspecto-dev/types'\nimport { INSPECTO_API_PATHS } from '@inspecto-dev/types'\n\nlet BASE_URL = globalThis.__AI_INSPECTOR_SERVER_URL__ || 'http://127.0.0.1:5678'\n\nexport function setBaseUrl(url: string): void {\n BASE_URL = url.replace(/\\/$/, '')\n}\n\nlet cachedConfig: InspectoConfig | null = null\n\nexport async function fetchIdeInfo(force = false): Promise<InspectoConfig | null> {\n if (cachedConfig && !force) return cachedConfig\n try {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.CLIENT_CONFIG}`)\n if (!res.ok) return null\n cachedConfig = await res.json()\n return cachedConfig\n } catch {\n return null\n }\n}\n\nexport async function openFile(req: OpenFileRequest): Promise<boolean> {\n try {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.IDE_OPEN}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(req),\n })\n return res.ok\n } catch {\n return false\n }\n}\n\nexport async function fetchSnippet(\n file: string,\n line: number,\n column: number,\n maxLines = 100,\n): Promise<SnippetResponse> {\n const params = new URLSearchParams({\n file,\n line: String(line),\n column: String(column),\n maxLines: String(maxLines),\n })\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.PROJECT_SNIPPET}?${params}`)\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { errorCode?: string }\n throw Object.assign(new Error('snippet fetch failed'), { errorCode: err.errorCode })\n }\n return res.json() as Promise<SnippetResponse>\n}\n\nexport async function sendToAi(req: SendToAiRequest): Promise<SendToAiResponse> {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.AI_DISPATCH}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(req),\n })\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { errorCode?: string; error?: string }\n return {\n success: false,\n error: err.error ?? 'Request failed',\n errorCode: err.errorCode as AiErrorCode,\n }\n }\n return res.json() as Promise<SendToAiResponse>\n}\n","import { buildPrompt, CUSTOM_PROMPT_TEMPLATE } from './intents.js'\nimport type { Provider, InspectorOptions, SourceLocation, IntentConfig } from '@inspecto-dev/types'\nimport { fetchSnippet, sendToAi, openFile, fetchIdeInfo } from './http.js'\nimport {\n menuClass,\n loadingSpinnerClass,\n errorMsgClass,\n menuItemClass,\n menuInputClass,\n menuInputWrapperClass,\n menuInputIconClass,\n shortcutIconClass,\n} from './styles.js'\n\nconst MENU_WIDTH = 280\n\nconst DISPLAY_NAMES: Record<Provider, string> = {\n copilot: 'GitHub Copilot',\n 'claude-code': 'Claude Code',\n gemini: 'Gemini',\n codex: 'Codex',\n coco: 'Coco CLI',\n trae: 'Trae AI',\n cursor: 'Cursor',\n}\n\nexport function showIntentMenu(\n shadowRoot: ShadowRoot,\n location: SourceLocation,\n clickX: number,\n clickY: number,\n options: InspectorOptions,\n onClose: () => void,\n): () => void {\n const maxSnippetLines = options.maxSnippetLines ?? 100\n const includeSnippet = options.includeSnippet ?? false\n\n const menu = document.createElement('div')\n menu.className = menuClass\n\n const { input, inputWrapper, sendIcon } = createAskInput(options.askPlaceholder)\n menu.appendChild(inputWrapper)\n\n const separator = document.createElement('div')\n separator.style.height = '1px'\n separator.style.background = 'var(--inspecto-menu-border)'\n separator.style.margin = '8px 4px 6px 4px'\n menu.appendChild(separator)\n\n const loadingEl = document.createElement('div')\n loadingEl.className = loadingSpinnerClass\n menu.appendChild(loadingEl)\n\n const viewportWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)\n const safeWidth = viewportWidth > 0 ? viewportWidth : MENU_WIDTH\n menu.style.left = `${Math.min(clickX, Math.max(safeWidth - MENU_WIDTH, 0))}px`\n menu.style.visibility = 'hidden'\n menu.style.display = 'block'\n\n shadowRoot.appendChild(menu)\n\n const updatePosition = () => {\n const rect = menu.getBoundingClientRect()\n const viewportHeight = Math.max(\n document.documentElement.clientHeight || 0,\n window.innerHeight || 0,\n )\n const safeHeight = viewportHeight > 0 ? viewportHeight : rect.height + 16\n menu.style.top = `${Math.min(clickY + 8, Math.max(safeHeight - rect.height - 8, 0))}px`\n }\n updatePosition()\n menu.style.visibility = 'visible'\n\n // Focus input automatically\n setTimeout(() => input.focus(), 0)\n\n const onDocClick = (e: MouseEvent): void => {\n // Because the menu is inside a Shadow DOM, e.target from the document's perspective\n // is just the <inspecto-overlay> custom element.\n const path = e.composedPath()\n if (path.includes(menu)) return\n cleanup()\n }\n // Use a small timeout so the click that opened the menu doesn't immediately close it\n setTimeout(() => document.addEventListener('click', onDocClick, { capture: true }), 0)\n\n function cleanup(): void {\n document.removeEventListener('click', onDocClick, { capture: true })\n menu.remove()\n onClose()\n }\n\n // Handle custom ask input\n const handleSend = async (\n promptText: string,\n snippetText: string,\n disable: () => void,\n restore: () => void,\n ) => {\n disable()\n\n // 1. 必须先 await openFile!\n // 如果不 await,openFile (基于 launch-ide 也就是 node child_process) 和 sendToAi (也就是 vscode:// URI handler)\n // 就会产生非常严重的竞态条件。\n // 如果 `sendToAi` 抢先获得了 focus 转移到了侧边栏,紧接着 `openFile` 才把文件在编辑器里打开,\n // 此时 activeTextEditor 就会被拉回源码文件,导致粘贴失败!\n const opened = await openFile(location)\n if (!opened) {\n restore()\n showError(menu, 'Unable to open file in the IDE.', 'IDE_UNAVAILABLE')\n return\n }\n\n // 可选:为了保证 IDE 完全缓冲好文件的打开,再微小延迟一点也是好的\n await new Promise(r => setTimeout(r, 100))\n\n // 2. 发送给 AI (触发 vscode URI handler,执行 focus 和 paste)\n const result = await sendToAi({ location, snippet: snippetText, prompt: promptText })\n\n if (result.success) {\n // Best-effort browser clipboard fallback. If the extension is not installed,\n // the user still gets the prompt in their clipboard.\n if (result.fallbackPayload?.prompt) {\n try {\n await navigator.clipboard.writeText(result.fallbackPayload.prompt)\n } catch (e) {\n // ignore\n }\n }\n cleanup()\n } else {\n restore()\n showError(menu, result.error ?? 'Unknown error', result.errorCode)\n }\n }\n\n const submitAsk = async () => {\n if (!input.value.trim()) return\n input.disabled = true\n sendIcon.style.pointerEvents = 'none'\n\n try {\n let snippetResult = null\n if (includeSnippet) {\n snippetResult = await fetchSnippet(\n location.file,\n location.line,\n location.column,\n maxSnippetLines,\n )\n }\n\n const prompt = buildPrompt(\n CUSTOM_PROMPT_TEMPLATE(input.value.trim()),\n location,\n snippetResult,\n )\n await handleSend(\n prompt,\n snippetResult?.snippet || '',\n () => {}, // already disabled\n () => {\n input.disabled = false\n sendIcon.style.pointerEvents = 'auto'\n },\n )\n } catch (err) {\n input.disabled = false\n sendIcon.style.pointerEvents = 'auto'\n showError(menu, (err as Error).message, (err as { errorCode?: string }).errorCode)\n }\n }\n\n input.addEventListener('keydown', e => {\n if (e.key === 'Enter') submitAsk()\n })\n sendIcon.addEventListener('click', submitAsk)\n\n // Fetch only IDE info to render the menu immediately\n fetchIdeInfo()\n .then(ideInfo => {\n loadingEl.remove()\n\n const intents = ideInfo?.prompts || []\n\n // Add intent buttons\n for (const intent of intents) {\n if (intent.isAction && intent.id === 'open-in-editor') {\n const btn = document.createElement('button')\n btn.className = menuItemClass\n const span = document.createElement('span')\n span.textContent = intent.label ?? 'Unknown'\n btn.appendChild(span)\n\n const shortcutDiv = document.createElement('div')\n shortcutDiv.className = shortcutIconClass\n shortcutDiv.textContent = '↵'\n btn.appendChild(shortcutDiv)\n\n btn.addEventListener('click', async e => {\n e.stopPropagation()\n btn.disabled = true\n const opened = await openFile(location)\n if (opened) {\n cleanup()\n return\n }\n btn.disabled = false\n showError(menu, 'Unable to open file in the IDE.', 'IDE_UNAVAILABLE')\n })\n menu.appendChild(btn)\n continue\n }\n\n let fullPromptTemplate = intent.prompt ?? ''\n if (intent.prependPrompt)\n fullPromptTemplate = intent.prependPrompt + '\\n\\n' + fullPromptTemplate\n if (intent.appendPrompt)\n fullPromptTemplate = fullPromptTemplate + '\\n\\n' + intent.appendPrompt\n\n const label = intent.label ?? intent.id ?? 'Unknown'\n const btn = document.createElement('button')\n btn.className = menuItemClass\n btn.textContent = label\n\n btn.addEventListener('click', async e => {\n e.stopPropagation()\n btn.disabled = true\n btn.textContent = 'Sending...'\n\n try {\n let snippetResult = null\n if (includeSnippet) {\n snippetResult = await fetchSnippet(\n location.file,\n location.line,\n location.column,\n maxSnippetLines,\n )\n }\n\n const prompt = buildPrompt(fullPromptTemplate, location, snippetResult)\n\n await handleSend(\n prompt,\n snippetResult?.snippet || '',\n () => {}, // already disabled\n () => {\n btn.disabled = false\n btn.textContent = label\n },\n )\n } catch (err) {\n btn.disabled = false\n btn.textContent = label\n showError(menu, (err as Error).message, (err as { errorCode?: string }).errorCode)\n }\n })\n\n menu.appendChild(btn)\n }\n updatePosition()\n })\n .catch((err: Error) => {\n loadingEl.remove()\n const isServerDown = err instanceof TypeError\n showError(\n menu,\n isServerDown\n ? 'Cannot connect to inspector server. Is the dev server running?'\n : err.message,\n (err as { errorCode?: string }).errorCode ?? 'UNKNOWN',\n )\n updatePosition()\n })\n\n return cleanup\n}\n\nfunction createAskInput(placeholder?: string) {\n const inputWrapper = document.createElement('div')\n inputWrapper.className = menuInputWrapperClass\n\n const input = document.createElement('input')\n input.className = menuInputClass\n input.type = 'text'\n input.placeholder = placeholder ?? 'Describe how to change this component...'\n\n const sendIcon = document.createElement('div')\n sendIcon.className = menuInputIconClass\n 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>`\n sendIcon.style.cursor = 'pointer'\n\n inputWrapper.appendChild(input)\n inputWrapper.appendChild(sendIcon)\n\n return { input, inputWrapper, sendIcon }\n}\n\nfunction showError(menu: HTMLElement, message: string, errorCode?: string): void {\n menu.querySelector(`.${errorMsgClass}`)?.remove()\n\n const errEl = document.createElement('div')\n errEl.className = errorMsgClass\n errEl.textContent =\n errorCode === 'FILE_NOT_FOUND'\n ? 'Source file not found. Is the server running?'\n : `Error: ${message}`\n menu.appendChild(errEl)\n}\n","import { createOverlay } from './overlay.js'\nimport { showIntentMenu } from './menu.js'\nimport type { InspectorOptions, HotKey, SourceLocation, HotKeys } from '@inspecto-dev/types'\nimport { setBaseUrl, fetchIdeInfo } from './http.js'\nimport { badgeClass, inspectorStyles } from './styles.js'\n\nconst ATTR_NAME = 'data-inspecto'\n\nfunction parseAttrValue(value: string): SourceLocation | null {\n const parts = value.split(':')\n if (parts.length < 3) return null\n\n const col = parseInt(parts[parts.length - 1]!, 10)\n const line = parseInt(parts[parts.length - 2]!, 10)\n const file = parts.slice(0, parts.length - 2).join(':')\n\n if (isNaN(line) || isNaN(col) || !file) return null\n return { file, line, column: col }\n}\n\nfunction findInspectable(el: Element | null): Element | null {\n while (el) {\n if (el.hasAttribute(ATTR_NAME)) return el\n el = el.parentElement\n }\n return null\n}\n\nfunction parseHotKeyString(hotKey: string): HotKey[] {\n const keys = hotKey.split('+').map(k => k.trim().toLowerCase())\n const result: HotKey[] = []\n\n if (keys.includes('alt') || keys.includes('option')) result.push('altKey')\n if (keys.includes('ctrl') || keys.includes('control')) result.push('ctrlKey')\n if (\n keys.includes('meta') ||\n keys.includes('cmd') ||\n keys.includes('command') ||\n keys.includes('win')\n )\n result.push('metaKey')\n if (keys.includes('shift')) result.push('shiftKey')\n\n return result\n}\n\nfunction hotKeysHeld(event: MouseEvent, hotKeys: string): boolean {\n if (!hotKeys) return false\n const mappedKeys = parseHotKeyString(hotKeys)\n if (mappedKeys.length === 0) return false\n return mappedKeys.every(key => event[key])\n}\n\n// Fallback class for SSR environments\nconst BaseElement =\n typeof HTMLElement !== 'undefined' ? HTMLElement : (class {} as typeof HTMLElement)\n\nclass InspectoElement extends BaseElement {\n private options: InspectorOptions = {}\n private serverHotKeys: HotKeys | null = null\n private active = false\n private disabled = false\n private isDragging = false\n private hasMoved = false\n private dragStartX = 0\n private dragStartY = 0\n private badgeInitialRight = 16\n private badgeInitialBottom = 16\n private shadowRootEl!: ShadowRoot\n private overlay!: ReturnType<typeof createOverlay>\n private cleanupMenu: (() => void) | null = null\n private badge!: HTMLButtonElement\n\n connectedCallback(): void {\n this.shadowRootEl = this.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = inspectorStyles\n this.shadowRootEl.appendChild(style)\n\n this.overlay = createOverlay(this.shadowRootEl)\n this.badge = this.createBadge()\n\n this.setupListeners()\n\n if (this.options.defaultActive) {\n this.setActive(true)\n }\n }\n\n disconnectedCallback(): void {\n this.teardownListeners()\n }\n\n configure(options: InspectorOptions): void {\n this.options = options\n if (options.serverUrl) {\n setBaseUrl(options.serverUrl)\n }\n\n // Apply explicitly configured theme, or fallback to auto (CSS media queries will take over if 'auto' or undefined)\n if (options.theme === 'dark') {\n this.setAttribute('data-theme', 'dark')\n } else if (options.theme === 'light') {\n this.setAttribute('data-theme', 'light')\n } else {\n this.removeAttribute('data-theme')\n }\n\n // Fetch hotKeys + other runtime config (prompts, targets) from the server.\n // hotKeys deliberately NOT baked into the injected script so that changes to\n // settings.json take effect on page refresh without restarting the dev server.\n fetchIdeInfo(true)\n .then(info => {\n if (info?.hotKeys !== undefined) {\n this.serverHotKeys = info.hotKeys\n this.updateBadgeContent()\n }\n if (info?.theme !== undefined) {\n if (info.theme === 'dark') {\n this.setAttribute('data-theme', 'dark')\n } else if (info.theme === 'light') {\n this.setAttribute('data-theme', 'light')\n } else {\n this.removeAttribute('data-theme')\n }\n }\n if (info?.includeSnippet !== undefined) {\n this.options.includeSnippet = info.includeSnippet\n }\n })\n .catch(() => {})\n }\n\n private createBadge(): HTMLButtonElement {\n const btn = document.createElement('button')\n btn.className = badgeClass\n btn.style.display = 'flex'\n\n const textSpan = document.createElement('span')\n textSpan.textContent = 'Inspecto Ready'\n\n const closeBtn = document.createElement('span')\n closeBtn.className = `${badgeClass}-close`\n closeBtn.innerHTML = '×'\n closeBtn.title = 'Pause Inspector'\n closeBtn.addEventListener('click', e => {\n e.stopPropagation()\n this.toggleDisabled()\n })\n\n btn.appendChild(textSpan)\n btn.appendChild(closeBtn)\n\n // Drag and Drop support\n btn.addEventListener('mousedown', this.onDragStart)\n\n btn.addEventListener('click', e => {\n // Prevent click if we were dragging\n if (this.hasMoved) {\n this.hasMoved = false\n return\n }\n\n if (this.disabled) {\n this.toggleDisabled()\n } else {\n this.setActive(!this.active)\n }\n })\n this.shadowRootEl.appendChild(btn)\n return btn\n }\n\n private readonly onDragStart = (e: MouseEvent): void => {\n // Only allow dragging with primary mouse button\n if (e.button !== 0) return\n\n // Don't drag if clicking the close button\n if ((e.target as Element).classList?.contains(`${badgeClass}-close`)) return\n\n e.preventDefault()\n\n this.isDragging = true\n this.hasMoved = false\n\n const rect = this.badge.getBoundingClientRect()\n // Calculate the exact offset where the user clicked inside the badge\n this.dragStartX = e.clientX - rect.left\n this.dragStartY = e.clientY - rect.top\n\n document.addEventListener('mousemove', this.onDragMove)\n document.addEventListener('mouseup', this.onDragEnd)\n }\n\n private readonly onDragMove = (e: MouseEvent): void => {\n if (!this.isDragging) return\n this.hasMoved = true\n\n // Calculate new position based on top/left\n let newLeft = e.clientX - this.dragStartX\n let newTop = e.clientY - this.dragStartY\n\n // Constrain to viewport\n const badgeWidth = this.badge.offsetWidth\n const badgeHeight = this.badge.offsetHeight\n\n newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - badgeWidth))\n newTop = Math.max(0, Math.min(newTop, window.innerHeight - badgeHeight))\n\n // Disable transition during drag for smoothness\n this.badge.style.transition = 'none'\n // Clear right/bottom to avoid conflicts\n this.badge.style.right = 'auto'\n this.badge.style.bottom = 'auto'\n this.badge.style.left = `${newLeft}px`\n this.badge.style.top = `${newTop}px`\n }\n\n private readonly onDragEnd = (): void => {\n document.removeEventListener('mousemove', this.onDragMove)\n document.removeEventListener('mouseup', this.onDragEnd)\n\n // Re-enable transitions\n this.badge.style.transition = ''\n\n // If it was just a click, reset isDragging state immediately\n // Otherwise, leave it true so the click handler knows to ignore the event\n setTimeout(() => {\n this.isDragging = false\n }, 0)\n }\n\n private toggleDisabled(): void {\n this.disabled = !this.disabled\n if (this.disabled) {\n this.active = false\n this.overlay.hide()\n this.cleanupMenu?.()\n this.cleanupMenu = null\n }\n this.updateBadgeContent()\n }\n\n private dismiss(): void {\n this.badge.style.display = 'none'\n this.setActive(false)\n }\n\n private getHotKeyHint(): string {\n const hotKeys = this.getEffectiveHotKeys()\n if (hotKeys === false) return 'Inspecto Ready'\n\n // Check if mac\n const isMac =\n typeof navigator !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.platform)\n\n const keys = hotKeys.split('+').map(k => k.trim().toLowerCase())\n const displayKeys = keys.map(k => {\n if (k === 'alt' || k === 'option') return isMac ? '⌥' : 'Alt'\n if (k === 'cmd' || k === 'meta' || k === 'win' || k === 'command') return isMac ? '⌘' : 'Win'\n if (k === 'ctrl' || k === 'control') return isMac ? '⌃' : 'Ctrl'\n if (k === 'shift') return isMac ? '⇧' : 'Shift'\n return k.charAt(0).toUpperCase() + k.slice(1)\n })\n\n return `Hold ${displayKeys.join(' + ')} to Inspect`\n }\n\n private getEffectiveHotKeys(): HotKeys {\n if (this.options.hotKeys !== undefined) return this.options.hotKeys\n if (this.serverHotKeys !== null) return this.serverHotKeys\n return 'alt'\n }\n\n private updateBadgeContent(): void {\n const textSpan = this.badge.querySelector('span')\n if (!textSpan) return\n\n if (this.disabled) {\n textSpan.textContent = 'Inspector Paused'\n this.badge.classList.remove('active')\n this.badge.classList.add('disabled')\n } else if (this.active) {\n textSpan.textContent = '🔍 Inspecting...'\n this.badge.classList.remove('disabled')\n this.badge.classList.add('active')\n } else {\n textSpan.textContent = this.getHotKeyHint()\n this.badge.classList.remove('active', 'disabled')\n }\n }\n\n private setActive(value: boolean): void {\n this.active = value\n this.updateBadgeContent()\n\n if (!value) {\n this.overlay.hide()\n this.cleanupMenu?.()\n this.cleanupMenu = null\n }\n }\n\n private readonly onMouseMove = (e: MouseEvent): void => {\n const isActive = this.isInspectorActive(e)\n if (!isActive) {\n this.overlay.hide()\n return\n }\n\n const target = findInspectable(e.target as Element)\n if (!target) {\n this.overlay.hide()\n return\n }\n\n const attrValue = target.getAttribute(ATTR_NAME)!\n const loc = parseAttrValue(attrValue)\n const label = loc ? `${loc.file.split('/').pop() ?? ''}:${loc.line}` : attrValue\n\n this.overlay.show(target, label)\n e.stopPropagation()\n }\n\n private readonly onClick = (e: MouseEvent): void => {\n this.handleTrigger(e)\n }\n\n private readonly onContextMenu = (e: MouseEvent): void => {\n if (this.isInspectorActive(e)) {\n this.handleTrigger(e)\n }\n }\n\n private handleTrigger(e: MouseEvent): void {\n if (!this.isInspectorActive(e)) return\n\n const target = findInspectable(e.target as Element)\n if (!target) return\n\n e.preventDefault()\n e.stopPropagation()\n\n const attrValue = target.getAttribute(ATTR_NAME)!\n const loc = parseAttrValue(attrValue)\n if (!loc) return\n\n this.cleanupMenu?.()\n\n this.cleanupMenu = showIntentMenu(\n this.shadowRootEl,\n loc,\n e.clientX,\n e.clientY,\n this.options,\n () => {\n this.cleanupMenu = null\n },\n )\n }\n\n private readonly onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') {\n this.cleanupMenu?.()\n this.overlay.hide()\n }\n }\n\n private isInspectorActive(e: MouseEvent): boolean {\n if (this.disabled) return false\n if (this.active) return true\n\n const hotKeys = this.getEffectiveHotKeys()\n if (hotKeys === false) return false\n return hotKeysHeld(e, hotKeys)\n }\n\n private setupListeners(): void {\n document.addEventListener('mousemove', this.onMouseMove, true)\n document.addEventListener('click', this.onClick, true)\n document.addEventListener('contextmenu', this.onContextMenu, true)\n document.addEventListener('keydown', this.onKeyDown, true)\n }\n\n private teardownListeners(): void {\n document.removeEventListener('mousemove', this.onMouseMove, true)\n document.removeEventListener('click', this.onClick, true)\n document.removeEventListener('contextmenu', this.onContextMenu, true)\n document.removeEventListener('keydown', this.onKeyDown, true)\n }\n}\n\nif (typeof customElements !== 'undefined') {\n customElements.define('inspecto-overlay', InspectoElement)\n}\n\nexport { InspectoElement }\n"],"mappings":"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","names":["_a","_b","btn"]}
package/dist/index.cjs CHANGED
@@ -664,13 +664,20 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
664
664
  const loadingEl = document.createElement("div");
665
665
  loadingEl.className = loadingSpinnerClass;
666
666
  menu.appendChild(loadingEl);
667
- menu.style.left = `${Math.min(clickX, window.innerWidth - MENU_WIDTH)}px`;
667
+ const viewportWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
668
+ const safeWidth = viewportWidth > 0 ? viewportWidth : MENU_WIDTH;
669
+ menu.style.left = `${Math.min(clickX, Math.max(safeWidth - MENU_WIDTH, 0))}px`;
668
670
  menu.style.visibility = "hidden";
669
671
  menu.style.display = "block";
670
672
  shadowRoot.appendChild(menu);
671
673
  const updatePosition = () => {
672
674
  const rect = menu.getBoundingClientRect();
673
- menu.style.top = `${Math.min(clickY + 8, window.innerHeight - rect.height - 8)}px`;
675
+ const viewportHeight = Math.max(
676
+ document.documentElement.clientHeight || 0,
677
+ window.innerHeight || 0
678
+ );
679
+ const safeHeight = viewportHeight > 0 ? viewportHeight : rect.height + 16;
680
+ menu.style.top = `${Math.min(clickY + 8, Math.max(safeHeight - rect.height - 8, 0))}px`;
674
681
  };
675
682
  updatePosition();
676
683
  menu.style.visibility = "visible";
@@ -689,7 +696,12 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
689
696
  const handleSend = (promptText, snippetText, disable, restore) => __async(null, null, function* () {
690
697
  var _a2, _b2;
691
698
  disable();
692
- yield openFile(location);
699
+ const opened = yield openFile(location);
700
+ if (!opened) {
701
+ restore();
702
+ showError(menu, "Unable to open file in the IDE.", "IDE_UNAVAILABLE");
703
+ return;
704
+ }
693
705
  yield new Promise((r) => setTimeout(r, 100));
694
706
  const result = yield sendToAi({ location, snippet: snippetText, prompt: promptText });
695
707
  if (result.success) {
@@ -760,11 +772,17 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose)
760
772
  shortcutDiv.className = shortcutIconClass;
761
773
  shortcutDiv.textContent = "\u21B5";
762
774
  btn2.appendChild(shortcutDiv);
763
- btn2.addEventListener("click", (e) => {
775
+ btn2.addEventListener("click", (e) => __async(null, null, function* () {
764
776
  e.stopPropagation();
765
- openFile(location);
766
- cleanup();
767
- });
777
+ btn2.disabled = true;
778
+ const opened = yield openFile(location);
779
+ if (opened) {
780
+ cleanup();
781
+ return;
782
+ }
783
+ btn2.disabled = false;
784
+ showError(menu, "Unable to open file in the IDE.", "IDE_UNAVAILABLE");
785
+ }));
768
786
  menu.appendChild(btn2);
769
787
  continue;
770
788
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/styles.ts","../src/overlay.ts","../src/intents.ts","../src/http.ts","../src/menu.ts","../src/component.ts","../src/index.ts"],"sourcesContent":["export const overlayClass = 'inspecto-overlay'\nexport const menuClass = 'inspecto-menu'\nexport const menuTitleClass = 'inspecto-menu-title'\nexport const menuItemClass = 'inspecto-menu-item'\nexport const loadingSpinnerClass = 'inspecto-spinner'\nexport const errorMsgClass = 'inspecto-error'\nexport const badgeClass = 'inspecto-badge'\nexport const menuInputClass = 'inspecto-menu-input'\nexport const menuInputWrapperClass = 'inspecto-menu-input-wrapper'\nexport const menuInputIconClass = 'inspecto-menu-input-icon'\n\n// Tooltip & overlay specific classes\nexport const tooltipClass = 'inspecto-tooltip'\nexport const tooltipTopClass = 'inspecto-tooltip-top'\nexport const tooltipBottomClass = 'inspecto-tooltip-bottom'\nexport const tagClass = 'inspecto-tag'\nexport const idClass = 'inspecto-id'\nexport const classClass = 'inspecto-class'\nexport const dimClass = 'inspecto-dim'\nexport const separatorClass = 'inspecto-separator'\nexport const sourceClass = 'inspecto-source'\nexport const shortcutIconClass = 'ai-shortcut-icon'\n\nconst darkVars = `\n --inspecto-menu-bg: #252526;\n --inspecto-menu-border: #454545;\n --inspecto-menu-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);\n --inspecto-text: #cccccc;\n --inspecto-text-muted: #858585;\n --inspecto-hover-bg: #04395e;\n --inspecto-hover-text: #ffffff;\n --inspecto-hover-icon: #ffffff;\n --inspecto-input-bg: #3c3c3c;\n --inspecto-input-border: #007acc;\n --inspecto-shortcut-text: #858585;\n --inspecto-badge-bg: rgba(30, 30, 30, 0.7);\n --inspecto-badge-text: #e5e5e5;\n --inspecto-badge-active-bg: #007acc;\n --inspecto-badge-active-text: #ffffff;\n --inspecto-badge-border: 1px solid rgba(255, 255, 255, 0.1);\n \n --inspecto-tooltip-bg: #222222;\n --inspecto-tooltip-text: #cccccc;\n --inspecto-tooltip-border: #444;\n --inspecto-tooltip-shadow: 0 2px 10px rgba(0,0,0,0.5);\n --inspecto-tag-color: #d16969;\n --inspecto-id-color: #d16969;\n --inspecto-class-color: #9cdcfe;\n --inspecto-dim-color: #858585;\n --inspecto-error-color: #ef4444;\n`\n\nexport const inspectorStyles = `\n :host {\n /* Light theme (default) */\n --inspecto-menu-bg: #ffffff;\n --inspecto-menu-border: #d4d4d4;\n --inspecto-menu-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n --inspecto-text: #333333;\n --inspecto-text-muted: #6b7280;\n --inspecto-hover-bg: #0060c0;\n --inspecto-hover-text: #ffffff;\n --inspecto-hover-icon: #ffffff;\n --inspecto-input-bg: #ffffff;\n --inspecto-input-border: #007acc;\n --inspecto-shortcut-text: #9ca3af;\n --inspecto-badge-bg: rgba(30, 30, 30, 0.7);\n --inspecto-badge-text: #e5e5e5;\n --inspecto-badge-active-bg: #007acc;\n --inspecto-badge-active-text: #ffffff;\n --inspecto-badge-border: 1px solid rgba(255, 255, 255, 0.1);\n \n /* Chrome DevTools like colors */\n --inspecto-overlay-border: #4285f4; /* Google Blue */\n --inspecto-overlay-bg: rgba(66, 133, 244, 0.2); \n --inspecto-tooltip-bg: #ffffff;\n --inspecto-tooltip-text: #333333;\n --inspecto-tooltip-border: #ccc;\n --inspecto-tooltip-shadow: 0 2px 10px rgba(0,0,0,0.1);\n \n --inspecto-tag-color: #8b008b; /* Dark magenta */\n --inspecto-id-color: #8b008b;\n --inspecto-class-color: #00008b; /* Dark blue */\n --inspecto-dim-color: #555555;\n --inspecto-error-color: #ef4444;\n }\n\n :host([data-theme=\"dark\"]) {\n ${darkVars}\n }\n\n @media (prefers-color-scheme: dark) {\n :host(:not([data-theme=\"light\"])) {\n ${darkVars}\n }\n }\n\n .${overlayClass} {\n position: fixed;\n pointer-events: none;\n z-index: 2147483646;\n border: 1px dashed var(--inspecto-overlay-border);\n background: var(--inspecto-overlay-bg);\n box-sizing: border-box;\n transition: all 0.05s linear;\n }\n\n .${tooltipClass} {\n position: fixed;\n pointer-events: none;\n z-index: 2147483647;\n background: var(--inspecto-tooltip-bg);\n color: var(--inspecto-tooltip-text);\n border: 1px solid var(--inspecto-tooltip-border);\n border-radius: 4px;\n box-shadow: var(--inspecto-tooltip-shadow);\n padding: 6px 10px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 12px;\n line-height: 1.4;\n transition: all 0.05s linear;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n \n /* Create the small pointer arrow like Chrome DevTools */\n .${tooltipClass}::after {\n content: '';\n position: absolute;\n width: 0;\n height: 0;\n border-style: solid;\n }\n\n .${tooltipTopClass}::after {\n bottom: -6px;\n left: var(--inspecto-arrow-left, 10px);\n border-width: 6px 6px 0 6px;\n border-color: var(--inspecto-tooltip-bg) transparent transparent transparent;\n }\n\n .${tooltipBottomClass}::after {\n top: -6px;\n left: var(--inspecto-arrow-left, 10px);\n border-width: 0 6px 6px 6px;\n border-color: transparent transparent var(--inspecto-tooltip-bg) transparent;\n }\n \n /* Outline for the arrow to match border */\n .${tooltipClass}::before {\n content: '';\n position: absolute;\n width: 0;\n height: 0;\n border-style: solid;\n }\n \n .${tooltipTopClass}::before {\n bottom: -7px;\n left: calc(var(--inspecto-arrow-left, 10px) - 1px);\n border-width: 7px 7px 0 7px;\n border-color: var(--inspecto-tooltip-border) transparent transparent transparent;\n }\n \n .${tooltipBottomClass}::before {\n top: -7px;\n left: calc(var(--inspecto-arrow-left, 10px) - 1px);\n border-width: 0 7px 7px 7px;\n border-color: transparent transparent var(--inspecto-tooltip-border) transparent;\n }\n\n .${tagClass} {\n color: var(--inspecto-tag-color);\n font-weight: 600;\n font-family: monospace;\n }\n \n .${idClass} {\n color: var(--inspecto-id-color);\n font-weight: 600;\n font-family: monospace;\n }\n\n .${classClass} {\n color: var(--inspecto-class-color);\n font-family: monospace;\n }\n\n .${dimClass} {\n color: var(--inspecto-dim-color);\n margin-left: 4px;\n }\n \n .${separatorClass} {\n height: 1px;\n background: var(--inspecto-tooltip-border);\n margin: 2px -10px;\n opacity: 0.5;\n }\n \n .${sourceClass} {\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 11px;\n color: var(--inspecto-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n }\n\n .${menuClass} {\n position: fixed;\n z-index: 2147483647;\n background: var(--inspecto-menu-bg);\n border: 1px solid var(--inspecto-menu-border);\n border-radius: 6px;\n padding: 6px;\n min-width: 300px;\n box-shadow: var(--inspecto-menu-shadow);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n color: var(--inspecto-text);\n }\n\n .${menuInputWrapperClass} {\n display: flex;\n align-items: center;\n border: 1px solid var(--inspecto-menu-border);\n border-radius: 4px;\n padding: 6px 8px;\n margin: 4px;\n margin-bottom: 8px;\n }\n \n .${menuInputWrapperClass}:focus-within {\n border-color: var(--inspecto-input-border);\n }\n\n .${menuInputClass} {\n width: 100%;\n border: none;\n outline: none;\n font-size: 13px;\n color: var(--inspecto-text);\n background: transparent;\n }\n\n .${menuInputClass}::placeholder {\n color: var(--inspecto-text-muted);\n }\n\n .${menuInputIconClass} {\n color: var(--inspecto-text-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 4px;\n }\n\n .${menuInputIconClass}:hover {\n color: var(--inspecto-text);\n }\n\n .${menuItemClass} {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 10px;\n margin: 2px 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--inspecto-text);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n }\n\n .${menuItemClass}:hover {\n background: var(--inspecto-hover-bg);\n color: var(--inspecto-hover-text);\n }\n\n .${menuItemClass} .${shortcutIconClass} {\n margin-left: auto;\n color: var(--inspecto-text-muted);\n }\n\n .${menuItemClass}:hover .${shortcutIconClass} {\n color: var(--inspecto-hover-icon);\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .${loadingSpinnerClass} {\n width: 14px;\n height: 14px;\n border: 2px solid var(--inspecto-overlay-border);\n border-top-color: transparent;\n border-radius: 50%;\n animation: spin 0.7s linear infinite;\n margin: 4px auto;\n display: block;\n }\n\n .${errorMsgClass} {\n font-size: 11px;\n color: var(--inspecto-error-color);\n padding: 4px 8px;\n text-align: center;\n }\n\n .${badgeClass} {\n position: fixed;\n bottom: 16px;\n right: 16px;\n z-index: 2147483645;\n background: var(--inspecto-badge-bg);\n color: var(--inspecto-badge-text);\n border: var(--inspecto-badge-border);\n border-radius: 20px;\n padding: 6px 12px;\n font-size: 12px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n cursor: grab;\n opacity: 0.85;\n transition: background 0.2s, color 0.2s, opacity 0.2s, box-shadow 0.2s;\n pointer-events: all;\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n gap: 6px;\n user-select: none;\n -webkit-user-select: none;\n touch-action: none;\n }\n\n .${badgeClass}:active {\n cursor: grabbing;\n }\n\n .${badgeClass}-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: transparent;\n color: currentColor;\n font-size: 14px;\n line-height: 1;\n opacity: 0.5;\n transition: opacity 0.2s, background 0.2s;\n margin-left: 2px;\n cursor: pointer;\n }\n\n .${badgeClass}-close:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.2);\n }\n\n .${badgeClass}.active {\n background: var(--inspecto-badge-active-bg);\n color: var(--inspecto-badge-active-text);\n border: 1px solid transparent;\n box-shadow: 0 0 10px rgba(0, 122, 204, 0.3);\n }\n\n .${badgeClass}.disabled {\n background: rgba(30, 30, 30, 0.4);\n color: rgba(229, 229, 229, 0.5);\n text-decoration: line-through;\n border: 1px dashed rgba(255, 255, 255, 0.1);\n }\n\n .${badgeClass}.disabled .${badgeClass}-close {\n opacity: 0.8;\n text-decoration: none;\n transform: rotate(45deg);\n }\n\n .${badgeClass}:hover {\n opacity: 1;\n }\n`\n","import {\n overlayClass,\n tooltipClass,\n tooltipTopClass,\n tooltipBottomClass,\n tagClass,\n idClass,\n classClass,\n dimClass,\n separatorClass,\n sourceClass,\n} from './styles.js'\n\nconst GAP = 8\nconst EDGE_MARGIN = 4\n\nexport function createOverlay(shadowRoot: ShadowRoot): {\n show(el: Element, sourceLabel: string): void\n hide(): void\n} {\n const overlay = document.createElement('div')\n overlay.className = overlayClass\n overlay.style.display = 'none'\n\n const tooltip = document.createElement('div')\n tooltip.className = tooltipClass\n\n const tagSpan = document.createElement('span')\n tagSpan.className = tagClass\n\n const idSpan = document.createElement('span')\n idSpan.className = idClass\n\n const classSpan = document.createElement('span')\n classSpan.className = classClass\n\n const dimSpan = document.createElement('span')\n dimSpan.className = dimClass\n\n const separator = document.createElement('div')\n separator.className = separatorClass\n\n const sourceSpan = document.createElement('div')\n sourceSpan.className = sourceClass\n\n tooltip.appendChild(tagSpan)\n tooltip.appendChild(idSpan)\n tooltip.appendChild(classSpan)\n tooltip.appendChild(document.createTextNode(' '))\n tooltip.appendChild(dimSpan)\n tooltip.appendChild(separator)\n tooltip.appendChild(sourceSpan)\n\n shadowRoot.appendChild(overlay)\n shadowRoot.appendChild(tooltip)\n\n function show(el: Element, sourceLabel: string): void {\n const rect = el.getBoundingClientRect()\n\n // The overlay and tooltip are `position: fixed`, so we MUST use viewport coordinates (rect.left/top)\n // without adding window.scrollX/scrollY.\n\n // Update overlay box\n overlay.style.display = 'block'\n overlay.style.left = `${rect.left}px`\n overlay.style.top = `${rect.top}px`\n overlay.style.width = `${rect.width}px`\n overlay.style.height = `${rect.height}px`\n\n // Update tooltip content\n const tagName = el.tagName.toLowerCase()\n tagSpan.textContent = tagName\n\n idSpan.textContent = el.id ? `#${el.id}` : ''\n\n const classes = Array.from(el.classList)\n .map(c => `.${c}`)\n .join('')\n classSpan.textContent = classes\n\n dimSpan.textContent = `${Math.round(rect.width)} × ${Math.round(rect.height)}`\n\n sourceSpan.textContent = sourceLabel\n\n tooltip.style.visibility = 'hidden'\n tooltip.style.display = 'block'\n\n // Calculate tooltip position\n const tooltipRect = tooltip.getBoundingClientRect()\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth\n const viewportHeight = document.documentElement.clientHeight || window.innerHeight\n\n // Calculate vertical position (above or below)\n let tooltipTop = rect.top - tooltipRect.height - GAP\n let isBottom = false\n\n // If there's not enough space above, show it below\n if (tooltipTop < EDGE_MARGIN) {\n tooltipTop = rect.bottom + GAP\n // If showing below also goes off screen, clamp it to bottom of screen\n if (tooltipTop + tooltipRect.height > viewportHeight - EDGE_MARGIN) {\n tooltipTop = viewportHeight - tooltipRect.height - EDGE_MARGIN\n }\n isBottom = true\n }\n\n tooltip.classList.toggle(tooltipBottomClass, isBottom)\n tooltip.classList.toggle(tooltipTopClass, !isBottom)\n\n // Calculate horizontal position\n // Default to aligning with the left edge of the element\n let tooltipLeft = rect.left\n\n // Prevent overflowing the right edge\n if (tooltipLeft + tooltipRect.width > viewportWidth - EDGE_MARGIN) {\n tooltipLeft = viewportWidth - tooltipRect.width - EDGE_MARGIN\n }\n // Prevent overflowing the left edge\n if (tooltipLeft < EDGE_MARGIN) {\n tooltipLeft = EDGE_MARGIN\n }\n\n // Calculate arrow position so it always points at the element\n // The arrow normally points at rect.left + 10\n // But if the element is tiny, point at its center\n const targetPointX = rect.left + Math.min(15, rect.width / 2)\n\n // Calculate where the arrow should be relative to the tooltip\n let arrowLeft = targetPointX - tooltipLeft\n\n // Clamp arrow position so it doesn't detach from the tooltip bubble itself\n arrowLeft = Math.max(6, Math.min(arrowLeft, tooltipRect.width - 18))\n\n tooltip.style.left = `${tooltipLeft}px`\n tooltip.style.top = `${tooltipTop}px`\n tooltip.style.setProperty('--inspecto-arrow-left', `${arrowLeft}px`)\n\n tooltip.style.visibility = 'visible'\n }\n\n function hide(): void {\n overlay.style.display = 'none'\n tooltip.style.display = 'none'\n }\n\n return { show, hide }\n}\n","import type { SnippetResponse, SourceLocation } from '@inspecto-dev/types'\n\n/** Template for user-typed custom prompts from the ask input box. */\nexport function CUSTOM_PROMPT_TEMPLATE(userPrompt: string): string {\n return userPrompt\n}\n\n/**\n * Guess the UI framework based on file extension\n */\nfunction detectFramework(fileName: string): string {\n const ext = fileName.split('.').pop()?.toLowerCase() || ''\n switch (ext) {\n case 'vue':\n return 'Vue'\n case 'svelte':\n return 'Svelte'\n case 'astro':\n return 'Astro'\n case 'jsx':\n case 'tsx':\n return 'React'\n case 'ts':\n case 'js':\n return 'JavaScript/TypeScript'\n default:\n return 'UI'\n }\n}\n\n/**\n * Replace all {{placeholder}} tokens in a prompt template.\n */\nexport function buildPrompt(\n template: string,\n location: SourceLocation,\n snippetResult?: SnippetResponse | null,\n): string {\n const shortFile = location.file.split('/').pop() ?? location.file\n const ext = shortFile.split('.').pop()?.toLowerCase() || 'tsx'\n const framework = detectFramework(shortFile)\n\n let finalPrompt = template\n .replace(/\\{\\{file\\}\\}/g, location.file)\n .replace(/\\{\\{line\\}\\}/g, String(location.line))\n .replace(/\\{\\{column\\}\\}/g, String(location.column))\n .replace(/\\{\\{ext\\}\\}/g, ext)\n .replace(/\\{\\{framework\\}\\}/g, framework)\n .replace(/\\{\\{name\\}\\}/g, shortFile) // fallback\n\n if (snippetResult && snippetResult.snippet) {\n const name = snippetResult.name ?? shortFile\n finalPrompt = finalPrompt.replace(/\\{\\{name\\}\\}/g, name)\n // append snippet context\n finalPrompt += `\\n\\nContext from \\`${location.file}\\` (line ${location.line}):\\n\\`\\`\\`${ext}\\n${snippetResult.snippet}\\n\\`\\`\\``\n }\n\n return finalPrompt\n}\n","import type {\n SnippetResponse,\n SendToAiRequest,\n SendToAiResponse,\n OpenFileRequest,\n InspectoConfig,\n AiErrorCode,\n} from '@inspecto-dev/types'\nimport { INSPECTO_API_PATHS } from '@inspecto-dev/types'\n\nlet BASE_URL = globalThis.__AI_INSPECTOR_SERVER_URL__ || 'http://127.0.0.1:5678'\n\nexport function setBaseUrl(url: string): void {\n BASE_URL = url.replace(/\\/$/, '')\n}\n\nlet cachedConfig: InspectoConfig | null = null\n\nexport async function fetchIdeInfo(force = false): Promise<InspectoConfig | null> {\n if (cachedConfig && !force) return cachedConfig\n try {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.CLIENT_CONFIG}`)\n if (!res.ok) return null\n cachedConfig = await res.json()\n return cachedConfig\n } catch {\n return null\n }\n}\n\nexport async function openFile(req: OpenFileRequest): Promise<boolean> {\n try {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.IDE_OPEN}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(req),\n })\n return res.ok\n } catch {\n return false\n }\n}\n\nexport async function fetchSnippet(\n file: string,\n line: number,\n column: number,\n maxLines = 100,\n): Promise<SnippetResponse> {\n const params = new URLSearchParams({\n file,\n line: String(line),\n column: String(column),\n maxLines: String(maxLines),\n })\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.PROJECT_SNIPPET}?${params}`)\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { errorCode?: string }\n throw Object.assign(new Error('snippet fetch failed'), { errorCode: err.errorCode })\n }\n return res.json() as Promise<SnippetResponse>\n}\n\nexport async function sendToAi(req: SendToAiRequest): Promise<SendToAiResponse> {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.AI_DISPATCH}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(req),\n })\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { errorCode?: string; error?: string }\n return {\n success: false,\n error: err.error ?? 'Request failed',\n errorCode: err.errorCode as AiErrorCode,\n }\n }\n return res.json() as Promise<SendToAiResponse>\n}\n","import { buildPrompt, CUSTOM_PROMPT_TEMPLATE } from './intents.js'\nimport type { Provider, InspectorOptions, SourceLocation, IntentConfig } from '@inspecto-dev/types'\nimport { fetchSnippet, sendToAi, openFile, fetchIdeInfo } from './http.js'\nimport {\n menuClass,\n loadingSpinnerClass,\n errorMsgClass,\n menuItemClass,\n menuInputClass,\n menuInputWrapperClass,\n menuInputIconClass,\n shortcutIconClass,\n} from './styles.js'\n\nconst MENU_WIDTH = 280\n\nconst DISPLAY_NAMES: Record<Provider, string> = {\n copilot: 'GitHub Copilot',\n 'claude-code': 'Claude Code',\n gemini: 'Gemini',\n codex: 'Codex',\n coco: 'Coco CLI',\n trae: 'Trae AI',\n cursor: 'Cursor',\n}\n\nexport function showIntentMenu(\n shadowRoot: ShadowRoot,\n location: SourceLocation,\n clickX: number,\n clickY: number,\n options: InspectorOptions,\n onClose: () => void,\n): () => void {\n const maxSnippetLines = options.maxSnippetLines ?? 100\n const includeSnippet = options.includeSnippet ?? false\n\n const menu = document.createElement('div')\n menu.className = menuClass\n\n const { input, inputWrapper, sendIcon } = createAskInput(options.askPlaceholder)\n menu.appendChild(inputWrapper)\n\n const separator = document.createElement('div')\n separator.style.height = '1px'\n separator.style.background = 'var(--inspecto-menu-border)'\n separator.style.margin = '8px 4px 6px 4px'\n menu.appendChild(separator)\n\n const loadingEl = document.createElement('div')\n loadingEl.className = loadingSpinnerClass\n menu.appendChild(loadingEl)\n\n menu.style.left = `${Math.min(clickX, window.innerWidth - MENU_WIDTH)}px`\n menu.style.visibility = 'hidden'\n menu.style.display = 'block'\n\n shadowRoot.appendChild(menu)\n\n const updatePosition = () => {\n const rect = menu.getBoundingClientRect()\n menu.style.top = `${Math.min(clickY + 8, window.innerHeight - rect.height - 8)}px`\n }\n updatePosition()\n menu.style.visibility = 'visible'\n\n // Focus input automatically\n setTimeout(() => input.focus(), 0)\n\n const onDocClick = (e: MouseEvent): void => {\n // Because the menu is inside a Shadow DOM, e.target from the document's perspective\n // is just the <inspecto-overlay> custom element.\n const path = e.composedPath()\n if (path.includes(menu)) return\n cleanup()\n }\n // Use a small timeout so the click that opened the menu doesn't immediately close it\n setTimeout(() => document.addEventListener('click', onDocClick, { capture: true }), 0)\n\n function cleanup(): void {\n document.removeEventListener('click', onDocClick, { capture: true })\n menu.remove()\n onClose()\n }\n\n // Handle custom ask input\n const handleSend = async (\n promptText: string,\n snippetText: string,\n disable: () => void,\n restore: () => void,\n ) => {\n disable()\n\n // 1. 必须先 await openFile!\n // 如果不 await,openFile (基于 launch-ide 也就是 node child_process) 和 sendToAi (也就是 vscode:// URI handler)\n // 就会产生非常严重的竞态条件。\n // 如果 `sendToAi` 抢先获得了 focus 转移到了侧边栏,紧接着 `openFile` 才把文件在编辑器里打开,\n // 此时 activeTextEditor 就会被拉回源码文件,导致粘贴失败!\n await openFile(location)\n\n // 可选:为了保证 IDE 完全缓冲好文件的打开,再微小延迟一点也是好的\n await new Promise(r => setTimeout(r, 100))\n\n // 2. 发送给 AI (触发 vscode URI handler,执行 focus 和 paste)\n const result = await sendToAi({ location, snippet: snippetText, prompt: promptText })\n\n if (result.success) {\n // Best-effort browser clipboard fallback. If the extension is not installed,\n // the user still gets the prompt in their clipboard.\n if (result.fallbackPayload?.prompt) {\n try {\n await navigator.clipboard.writeText(result.fallbackPayload.prompt)\n } catch (e) {\n // ignore\n }\n }\n cleanup()\n } else {\n restore()\n showError(menu, result.error ?? 'Unknown error', result.errorCode)\n }\n }\n\n const submitAsk = async () => {\n if (!input.value.trim()) return\n input.disabled = true\n sendIcon.style.pointerEvents = 'none'\n\n try {\n let snippetResult = null\n if (includeSnippet) {\n snippetResult = await fetchSnippet(\n location.file,\n location.line,\n location.column,\n maxSnippetLines,\n )\n }\n\n const prompt = buildPrompt(\n CUSTOM_PROMPT_TEMPLATE(input.value.trim()),\n location,\n snippetResult,\n )\n await handleSend(\n prompt,\n snippetResult?.snippet || '',\n () => {}, // already disabled\n () => {\n input.disabled = false\n sendIcon.style.pointerEvents = 'auto'\n },\n )\n } catch (err) {\n input.disabled = false\n sendIcon.style.pointerEvents = 'auto'\n showError(menu, (err as Error).message, (err as { errorCode?: string }).errorCode)\n }\n }\n\n input.addEventListener('keydown', e => {\n if (e.key === 'Enter') submitAsk()\n })\n sendIcon.addEventListener('click', submitAsk)\n\n // Fetch only IDE info to render the menu immediately\n fetchIdeInfo()\n .then(ideInfo => {\n loadingEl.remove()\n\n const intents = ideInfo?.prompts || []\n\n // Add intent buttons\n for (const intent of intents) {\n if (intent.isAction && intent.id === 'open-in-editor') {\n const btn = document.createElement('button')\n btn.className = menuItemClass\n const span = document.createElement('span')\n span.textContent = intent.label ?? 'Unknown'\n btn.appendChild(span)\n\n const shortcutDiv = document.createElement('div')\n shortcutDiv.className = shortcutIconClass\n shortcutDiv.textContent = '↵'\n btn.appendChild(shortcutDiv)\n\n btn.addEventListener('click', e => {\n e.stopPropagation()\n openFile(location)\n cleanup()\n })\n menu.appendChild(btn)\n continue\n }\n\n let fullPromptTemplate = intent.prompt ?? ''\n if (intent.prependPrompt)\n fullPromptTemplate = intent.prependPrompt + '\\n\\n' + fullPromptTemplate\n if (intent.appendPrompt)\n fullPromptTemplate = fullPromptTemplate + '\\n\\n' + intent.appendPrompt\n\n const label = intent.label ?? intent.id ?? 'Unknown'\n const btn = document.createElement('button')\n btn.className = menuItemClass\n btn.textContent = label\n\n btn.addEventListener('click', async e => {\n e.stopPropagation()\n btn.disabled = true\n btn.textContent = 'Sending...'\n\n try {\n let snippetResult = null\n if (includeSnippet) {\n snippetResult = await fetchSnippet(\n location.file,\n location.line,\n location.column,\n maxSnippetLines,\n )\n }\n\n const prompt = buildPrompt(fullPromptTemplate, location, snippetResult)\n\n await handleSend(\n prompt,\n snippetResult?.snippet || '',\n () => {}, // already disabled\n () => {\n btn.disabled = false\n btn.textContent = label\n },\n )\n } catch (err) {\n btn.disabled = false\n btn.textContent = label\n showError(menu, (err as Error).message, (err as { errorCode?: string }).errorCode)\n }\n })\n\n menu.appendChild(btn)\n }\n updatePosition()\n })\n .catch((err: Error) => {\n loadingEl.remove()\n const isServerDown = err instanceof TypeError\n showError(\n menu,\n isServerDown\n ? 'Cannot connect to inspector server. Is the dev server running?'\n : err.message,\n (err as { errorCode?: string }).errorCode ?? 'UNKNOWN',\n )\n updatePosition()\n })\n\n return cleanup\n}\n\nfunction createAskInput(placeholder?: string) {\n const inputWrapper = document.createElement('div')\n inputWrapper.className = menuInputWrapperClass\n\n const input = document.createElement('input')\n input.className = menuInputClass\n input.type = 'text'\n input.placeholder = placeholder ?? 'Describe how to change this component...'\n\n const sendIcon = document.createElement('div')\n sendIcon.className = menuInputIconClass\n 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>`\n sendIcon.style.cursor = 'pointer'\n\n inputWrapper.appendChild(input)\n inputWrapper.appendChild(sendIcon)\n\n return { input, inputWrapper, sendIcon }\n}\n\nfunction showError(menu: HTMLElement, message: string, errorCode?: string): void {\n menu.querySelector(`.${errorMsgClass}`)?.remove()\n\n const errEl = document.createElement('div')\n errEl.className = errorMsgClass\n errEl.textContent =\n errorCode === 'FILE_NOT_FOUND'\n ? 'Source file not found. Is the server running?'\n : `Error: ${message}`\n menu.appendChild(errEl)\n}\n","import { createOverlay } from './overlay.js'\nimport { showIntentMenu } from './menu.js'\nimport type { InspectorOptions, HotKey, SourceLocation, HotKeys } from '@inspecto-dev/types'\nimport { setBaseUrl, fetchIdeInfo } from './http.js'\nimport { badgeClass, inspectorStyles } from './styles.js'\n\nconst ATTR_NAME = 'data-inspecto'\n\nfunction parseAttrValue(value: string): SourceLocation | null {\n const parts = value.split(':')\n if (parts.length < 3) return null\n\n const col = parseInt(parts[parts.length - 1]!, 10)\n const line = parseInt(parts[parts.length - 2]!, 10)\n const file = parts.slice(0, parts.length - 2).join(':')\n\n if (isNaN(line) || isNaN(col) || !file) return null\n return { file, line, column: col }\n}\n\nfunction findInspectable(el: Element | null): Element | null {\n while (el) {\n if (el.hasAttribute(ATTR_NAME)) return el\n el = el.parentElement\n }\n return null\n}\n\nfunction parseHotKeyString(hotKey: string): HotKey[] {\n const keys = hotKey.split('+').map(k => k.trim().toLowerCase())\n const result: HotKey[] = []\n\n if (keys.includes('alt') || keys.includes('option')) result.push('altKey')\n if (keys.includes('ctrl') || keys.includes('control')) result.push('ctrlKey')\n if (\n keys.includes('meta') ||\n keys.includes('cmd') ||\n keys.includes('command') ||\n keys.includes('win')\n )\n result.push('metaKey')\n if (keys.includes('shift')) result.push('shiftKey')\n\n return result\n}\n\nfunction hotKeysHeld(event: MouseEvent, hotKeys: string): boolean {\n if (!hotKeys) return false\n const mappedKeys = parseHotKeyString(hotKeys)\n if (mappedKeys.length === 0) return false\n return mappedKeys.every(key => event[key])\n}\n\n// Fallback class for SSR environments\nconst BaseElement =\n typeof HTMLElement !== 'undefined' ? HTMLElement : (class {} as typeof HTMLElement)\n\nclass InspectoElement extends BaseElement {\n private options: InspectorOptions = {}\n private serverHotKeys: HotKeys | null = null\n private active = false\n private disabled = false\n private isDragging = false\n private hasMoved = false\n private dragStartX = 0\n private dragStartY = 0\n private badgeInitialRight = 16\n private badgeInitialBottom = 16\n private shadowRootEl!: ShadowRoot\n private overlay!: ReturnType<typeof createOverlay>\n private cleanupMenu: (() => void) | null = null\n private badge!: HTMLButtonElement\n\n connectedCallback(): void {\n this.shadowRootEl = this.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = inspectorStyles\n this.shadowRootEl.appendChild(style)\n\n this.overlay = createOverlay(this.shadowRootEl)\n this.badge = this.createBadge()\n\n this.setupListeners()\n\n if (this.options.defaultActive) {\n this.setActive(true)\n }\n }\n\n disconnectedCallback(): void {\n this.teardownListeners()\n }\n\n configure(options: InspectorOptions): void {\n this.options = options\n if (options.serverUrl) {\n setBaseUrl(options.serverUrl)\n }\n\n // Apply explicitly configured theme, or fallback to auto (CSS media queries will take over if 'auto' or undefined)\n if (options.theme === 'dark') {\n this.setAttribute('data-theme', 'dark')\n } else if (options.theme === 'light') {\n this.setAttribute('data-theme', 'light')\n } else {\n this.removeAttribute('data-theme')\n }\n\n // Fetch hotKeys + other runtime config (prompts, targets) from the server.\n // hotKeys deliberately NOT baked into the injected script so that changes to\n // settings.json take effect on page refresh without restarting the dev server.\n fetchIdeInfo(true)\n .then(info => {\n if (info?.hotKeys !== undefined) {\n this.serverHotKeys = info.hotKeys\n this.updateBadgeContent()\n }\n if (info?.theme !== undefined) {\n if (info.theme === 'dark') {\n this.setAttribute('data-theme', 'dark')\n } else if (info.theme === 'light') {\n this.setAttribute('data-theme', 'light')\n } else {\n this.removeAttribute('data-theme')\n }\n }\n if (info?.includeSnippet !== undefined) {\n this.options.includeSnippet = info.includeSnippet\n }\n })\n .catch(() => {})\n }\n\n private createBadge(): HTMLButtonElement {\n const btn = document.createElement('button')\n btn.className = badgeClass\n btn.style.display = 'flex'\n\n const textSpan = document.createElement('span')\n textSpan.textContent = 'Inspecto Ready'\n\n const closeBtn = document.createElement('span')\n closeBtn.className = `${badgeClass}-close`\n closeBtn.innerHTML = '×'\n closeBtn.title = 'Pause Inspector'\n closeBtn.addEventListener('click', e => {\n e.stopPropagation()\n this.toggleDisabled()\n })\n\n btn.appendChild(textSpan)\n btn.appendChild(closeBtn)\n\n // Drag and Drop support\n btn.addEventListener('mousedown', this.onDragStart)\n\n btn.addEventListener('click', e => {\n // Prevent click if we were dragging\n if (this.hasMoved) {\n this.hasMoved = false\n return\n }\n\n if (this.disabled) {\n this.toggleDisabled()\n } else {\n this.setActive(!this.active)\n }\n })\n this.shadowRootEl.appendChild(btn)\n return btn\n }\n\n private readonly onDragStart = (e: MouseEvent): void => {\n // Only allow dragging with primary mouse button\n if (e.button !== 0) return\n\n // Don't drag if clicking the close button\n if ((e.target as Element).classList?.contains(`${badgeClass}-close`)) return\n\n e.preventDefault()\n\n this.isDragging = true\n this.hasMoved = false\n\n const rect = this.badge.getBoundingClientRect()\n // Calculate the exact offset where the user clicked inside the badge\n this.dragStartX = e.clientX - rect.left\n this.dragStartY = e.clientY - rect.top\n\n document.addEventListener('mousemove', this.onDragMove)\n document.addEventListener('mouseup', this.onDragEnd)\n }\n\n private readonly onDragMove = (e: MouseEvent): void => {\n if (!this.isDragging) return\n this.hasMoved = true\n\n // Calculate new position based on top/left\n let newLeft = e.clientX - this.dragStartX\n let newTop = e.clientY - this.dragStartY\n\n // Constrain to viewport\n const badgeWidth = this.badge.offsetWidth\n const badgeHeight = this.badge.offsetHeight\n\n newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - badgeWidth))\n newTop = Math.max(0, Math.min(newTop, window.innerHeight - badgeHeight))\n\n // Disable transition during drag for smoothness\n this.badge.style.transition = 'none'\n // Clear right/bottom to avoid conflicts\n this.badge.style.right = 'auto'\n this.badge.style.bottom = 'auto'\n this.badge.style.left = `${newLeft}px`\n this.badge.style.top = `${newTop}px`\n }\n\n private readonly onDragEnd = (): void => {\n document.removeEventListener('mousemove', this.onDragMove)\n document.removeEventListener('mouseup', this.onDragEnd)\n\n // Re-enable transitions\n this.badge.style.transition = ''\n\n // If it was just a click, reset isDragging state immediately\n // Otherwise, leave it true so the click handler knows to ignore the event\n setTimeout(() => {\n this.isDragging = false\n }, 0)\n }\n\n private toggleDisabled(): void {\n this.disabled = !this.disabled\n if (this.disabled) {\n this.active = false\n this.overlay.hide()\n this.cleanupMenu?.()\n this.cleanupMenu = null\n }\n this.updateBadgeContent()\n }\n\n private dismiss(): void {\n this.badge.style.display = 'none'\n this.setActive(false)\n }\n\n private getHotKeyHint(): string {\n const hotKeys = this.getEffectiveHotKeys()\n if (hotKeys === false) return 'Inspecto Ready'\n\n // Check if mac\n const isMac =\n typeof navigator !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.platform)\n\n const keys = hotKeys.split('+').map(k => k.trim().toLowerCase())\n const displayKeys = keys.map(k => {\n if (k === 'alt' || k === 'option') return isMac ? '⌥' : 'Alt'\n if (k === 'cmd' || k === 'meta' || k === 'win' || k === 'command') return isMac ? '⌘' : 'Win'\n if (k === 'ctrl' || k === 'control') return isMac ? '⌃' : 'Ctrl'\n if (k === 'shift') return isMac ? '⇧' : 'Shift'\n return k.charAt(0).toUpperCase() + k.slice(1)\n })\n\n return `Hold ${displayKeys.join(' + ')} to Inspect`\n }\n\n private getEffectiveHotKeys(): HotKeys {\n if (this.options.hotKeys !== undefined) return this.options.hotKeys\n if (this.serverHotKeys !== null) return this.serverHotKeys\n return 'alt'\n }\n\n private updateBadgeContent(): void {\n const textSpan = this.badge.querySelector('span')\n if (!textSpan) return\n\n if (this.disabled) {\n textSpan.textContent = 'Inspector Paused'\n this.badge.classList.remove('active')\n this.badge.classList.add('disabled')\n } else if (this.active) {\n textSpan.textContent = '🔍 Inspecting...'\n this.badge.classList.remove('disabled')\n this.badge.classList.add('active')\n } else {\n textSpan.textContent = this.getHotKeyHint()\n this.badge.classList.remove('active', 'disabled')\n }\n }\n\n private setActive(value: boolean): void {\n this.active = value\n this.updateBadgeContent()\n\n if (!value) {\n this.overlay.hide()\n this.cleanupMenu?.()\n this.cleanupMenu = null\n }\n }\n\n private readonly onMouseMove = (e: MouseEvent): void => {\n const isActive = this.isInspectorActive(e)\n if (!isActive) {\n this.overlay.hide()\n return\n }\n\n const target = findInspectable(e.target as Element)\n if (!target) {\n this.overlay.hide()\n return\n }\n\n const attrValue = target.getAttribute(ATTR_NAME)!\n const loc = parseAttrValue(attrValue)\n const label = loc ? `${loc.file.split('/').pop() ?? ''}:${loc.line}` : attrValue\n\n this.overlay.show(target, label)\n e.stopPropagation()\n }\n\n private readonly onClick = (e: MouseEvent): void => {\n this.handleTrigger(e)\n }\n\n private readonly onContextMenu = (e: MouseEvent): void => {\n if (this.isInspectorActive(e)) {\n this.handleTrigger(e)\n }\n }\n\n private handleTrigger(e: MouseEvent): void {\n if (!this.isInspectorActive(e)) return\n\n const target = findInspectable(e.target as Element)\n if (!target) return\n\n e.preventDefault()\n e.stopPropagation()\n\n const attrValue = target.getAttribute(ATTR_NAME)!\n const loc = parseAttrValue(attrValue)\n if (!loc) return\n\n this.cleanupMenu?.()\n\n this.cleanupMenu = showIntentMenu(\n this.shadowRootEl,\n loc,\n e.clientX,\n e.clientY,\n this.options,\n () => {\n this.cleanupMenu = null\n },\n )\n }\n\n private readonly onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') {\n this.cleanupMenu?.()\n this.overlay.hide()\n }\n }\n\n private isInspectorActive(e: MouseEvent): boolean {\n if (this.disabled) return false\n if (this.active) return true\n\n const hotKeys = this.getEffectiveHotKeys()\n if (hotKeys === false) return false\n return hotKeysHeld(e, hotKeys)\n }\n\n private setupListeners(): void {\n document.addEventListener('mousemove', this.onMouseMove, true)\n document.addEventListener('click', this.onClick, true)\n document.addEventListener('contextmenu', this.onContextMenu, true)\n document.addEventListener('keydown', this.onKeyDown, true)\n }\n\n private teardownListeners(): void {\n document.removeEventListener('mousemove', this.onMouseMove, true)\n document.removeEventListener('click', this.onClick, true)\n document.removeEventListener('contextmenu', this.onContextMenu, true)\n document.removeEventListener('keydown', this.onKeyDown, true)\n }\n}\n\nif (typeof customElements !== 'undefined') {\n customElements.define('inspecto-overlay', InspectoElement)\n}\n\nexport { InspectoElement }\n","import type { InspectorOptions } from '@inspecto-dev/types'\n\n// Export types only, avoid top-level imports of DOM-dependent code\nexport type { InspectorOptions }\nexport type { InspectoElement } from './component.js'\n\nconst TAG_NAME = 'inspecto-overlay'\n\nexport async function mountInspector(options: InspectorOptions = {}): Promise<any> {\n if (typeof document === 'undefined') return null\n\n // Lazy import the component so that module evaluation does not happen during SSR\n const { InspectoElement } = await import('./component.js')\n\n const existing = document.querySelector(TAG_NAME)\n if (existing) {\n ;(existing as typeof InspectoElement.prototype).configure(options)\n return existing\n }\n\n const el = document.createElement(TAG_NAME)\n ;(el as typeof InspectoElement.prototype).configure(options)\n document.body.appendChild(el)\n return el\n}\n\nexport function unmountInspector(): void {\n if (typeof document === 'undefined') return\n const existing = document.querySelector(TAG_NAME)\n if (existing) {\n existing.remove()\n }\n}\n\n// Expose to global window for Webpack/Rspack EntryPlugin injection fallback\nif (typeof window !== 'undefined') {\n window.InspectoClient = {\n mountInspector,\n unmountInspector,\n }\n}\n"],"mappings":"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","names":["_a","_b","btn","InspectoElement"]}
1
+ {"version":3,"sources":["../src/styles.ts","../src/overlay.ts","../src/intents.ts","../src/http.ts","../src/menu.ts","../src/component.ts","../src/index.ts"],"sourcesContent":["export const overlayClass = 'inspecto-overlay'\nexport const menuClass = 'inspecto-menu'\nexport const menuTitleClass = 'inspecto-menu-title'\nexport const menuItemClass = 'inspecto-menu-item'\nexport const loadingSpinnerClass = 'inspecto-spinner'\nexport const errorMsgClass = 'inspecto-error'\nexport const badgeClass = 'inspecto-badge'\nexport const menuInputClass = 'inspecto-menu-input'\nexport const menuInputWrapperClass = 'inspecto-menu-input-wrapper'\nexport const menuInputIconClass = 'inspecto-menu-input-icon'\n\n// Tooltip & overlay specific classes\nexport const tooltipClass = 'inspecto-tooltip'\nexport const tooltipTopClass = 'inspecto-tooltip-top'\nexport const tooltipBottomClass = 'inspecto-tooltip-bottom'\nexport const tagClass = 'inspecto-tag'\nexport const idClass = 'inspecto-id'\nexport const classClass = 'inspecto-class'\nexport const dimClass = 'inspecto-dim'\nexport const separatorClass = 'inspecto-separator'\nexport const sourceClass = 'inspecto-source'\nexport const shortcutIconClass = 'ai-shortcut-icon'\n\nconst darkVars = `\n --inspecto-menu-bg: #252526;\n --inspecto-menu-border: #454545;\n --inspecto-menu-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);\n --inspecto-text: #cccccc;\n --inspecto-text-muted: #858585;\n --inspecto-hover-bg: #04395e;\n --inspecto-hover-text: #ffffff;\n --inspecto-hover-icon: #ffffff;\n --inspecto-input-bg: #3c3c3c;\n --inspecto-input-border: #007acc;\n --inspecto-shortcut-text: #858585;\n --inspecto-badge-bg: rgba(30, 30, 30, 0.7);\n --inspecto-badge-text: #e5e5e5;\n --inspecto-badge-active-bg: #007acc;\n --inspecto-badge-active-text: #ffffff;\n --inspecto-badge-border: 1px solid rgba(255, 255, 255, 0.1);\n \n --inspecto-tooltip-bg: #222222;\n --inspecto-tooltip-text: #cccccc;\n --inspecto-tooltip-border: #444;\n --inspecto-tooltip-shadow: 0 2px 10px rgba(0,0,0,0.5);\n --inspecto-tag-color: #d16969;\n --inspecto-id-color: #d16969;\n --inspecto-class-color: #9cdcfe;\n --inspecto-dim-color: #858585;\n --inspecto-error-color: #ef4444;\n`\n\nexport const inspectorStyles = `\n :host {\n /* Light theme (default) */\n --inspecto-menu-bg: #ffffff;\n --inspecto-menu-border: #d4d4d4;\n --inspecto-menu-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n --inspecto-text: #333333;\n --inspecto-text-muted: #6b7280;\n --inspecto-hover-bg: #0060c0;\n --inspecto-hover-text: #ffffff;\n --inspecto-hover-icon: #ffffff;\n --inspecto-input-bg: #ffffff;\n --inspecto-input-border: #007acc;\n --inspecto-shortcut-text: #9ca3af;\n --inspecto-badge-bg: rgba(30, 30, 30, 0.7);\n --inspecto-badge-text: #e5e5e5;\n --inspecto-badge-active-bg: #007acc;\n --inspecto-badge-active-text: #ffffff;\n --inspecto-badge-border: 1px solid rgba(255, 255, 255, 0.1);\n \n /* Chrome DevTools like colors */\n --inspecto-overlay-border: #4285f4; /* Google Blue */\n --inspecto-overlay-bg: rgba(66, 133, 244, 0.2); \n --inspecto-tooltip-bg: #ffffff;\n --inspecto-tooltip-text: #333333;\n --inspecto-tooltip-border: #ccc;\n --inspecto-tooltip-shadow: 0 2px 10px rgba(0,0,0,0.1);\n \n --inspecto-tag-color: #8b008b; /* Dark magenta */\n --inspecto-id-color: #8b008b;\n --inspecto-class-color: #00008b; /* Dark blue */\n --inspecto-dim-color: #555555;\n --inspecto-error-color: #ef4444;\n }\n\n :host([data-theme=\"dark\"]) {\n ${darkVars}\n }\n\n @media (prefers-color-scheme: dark) {\n :host(:not([data-theme=\"light\"])) {\n ${darkVars}\n }\n }\n\n .${overlayClass} {\n position: fixed;\n pointer-events: none;\n z-index: 2147483646;\n border: 1px dashed var(--inspecto-overlay-border);\n background: var(--inspecto-overlay-bg);\n box-sizing: border-box;\n transition: all 0.05s linear;\n }\n\n .${tooltipClass} {\n position: fixed;\n pointer-events: none;\n z-index: 2147483647;\n background: var(--inspecto-tooltip-bg);\n color: var(--inspecto-tooltip-text);\n border: 1px solid var(--inspecto-tooltip-border);\n border-radius: 4px;\n box-shadow: var(--inspecto-tooltip-shadow);\n padding: 6px 10px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 12px;\n line-height: 1.4;\n transition: all 0.05s linear;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n \n /* Create the small pointer arrow like Chrome DevTools */\n .${tooltipClass}::after {\n content: '';\n position: absolute;\n width: 0;\n height: 0;\n border-style: solid;\n }\n\n .${tooltipTopClass}::after {\n bottom: -6px;\n left: var(--inspecto-arrow-left, 10px);\n border-width: 6px 6px 0 6px;\n border-color: var(--inspecto-tooltip-bg) transparent transparent transparent;\n }\n\n .${tooltipBottomClass}::after {\n top: -6px;\n left: var(--inspecto-arrow-left, 10px);\n border-width: 0 6px 6px 6px;\n border-color: transparent transparent var(--inspecto-tooltip-bg) transparent;\n }\n \n /* Outline for the arrow to match border */\n .${tooltipClass}::before {\n content: '';\n position: absolute;\n width: 0;\n height: 0;\n border-style: solid;\n }\n \n .${tooltipTopClass}::before {\n bottom: -7px;\n left: calc(var(--inspecto-arrow-left, 10px) - 1px);\n border-width: 7px 7px 0 7px;\n border-color: var(--inspecto-tooltip-border) transparent transparent transparent;\n }\n \n .${tooltipBottomClass}::before {\n top: -7px;\n left: calc(var(--inspecto-arrow-left, 10px) - 1px);\n border-width: 0 7px 7px 7px;\n border-color: transparent transparent var(--inspecto-tooltip-border) transparent;\n }\n\n .${tagClass} {\n color: var(--inspecto-tag-color);\n font-weight: 600;\n font-family: monospace;\n }\n \n .${idClass} {\n color: var(--inspecto-id-color);\n font-weight: 600;\n font-family: monospace;\n }\n\n .${classClass} {\n color: var(--inspecto-class-color);\n font-family: monospace;\n }\n\n .${dimClass} {\n color: var(--inspecto-dim-color);\n margin-left: 4px;\n }\n \n .${separatorClass} {\n height: 1px;\n background: var(--inspecto-tooltip-border);\n margin: 2px -10px;\n opacity: 0.5;\n }\n \n .${sourceClass} {\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 11px;\n color: var(--inspecto-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n }\n\n .${menuClass} {\n position: fixed;\n z-index: 2147483647;\n background: var(--inspecto-menu-bg);\n border: 1px solid var(--inspecto-menu-border);\n border-radius: 6px;\n padding: 6px;\n min-width: 300px;\n box-shadow: var(--inspecto-menu-shadow);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n color: var(--inspecto-text);\n }\n\n .${menuInputWrapperClass} {\n display: flex;\n align-items: center;\n border: 1px solid var(--inspecto-menu-border);\n border-radius: 4px;\n padding: 6px 8px;\n margin: 4px;\n margin-bottom: 8px;\n }\n \n .${menuInputWrapperClass}:focus-within {\n border-color: var(--inspecto-input-border);\n }\n\n .${menuInputClass} {\n width: 100%;\n border: none;\n outline: none;\n font-size: 13px;\n color: var(--inspecto-text);\n background: transparent;\n }\n\n .${menuInputClass}::placeholder {\n color: var(--inspecto-text-muted);\n }\n\n .${menuInputIconClass} {\n color: var(--inspecto-text-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 4px;\n }\n\n .${menuInputIconClass}:hover {\n color: var(--inspecto-text);\n }\n\n .${menuItemClass} {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 10px;\n margin: 2px 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--inspecto-text);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n }\n\n .${menuItemClass}:hover {\n background: var(--inspecto-hover-bg);\n color: var(--inspecto-hover-text);\n }\n\n .${menuItemClass} .${shortcutIconClass} {\n margin-left: auto;\n color: var(--inspecto-text-muted);\n }\n\n .${menuItemClass}:hover .${shortcutIconClass} {\n color: var(--inspecto-hover-icon);\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .${loadingSpinnerClass} {\n width: 14px;\n height: 14px;\n border: 2px solid var(--inspecto-overlay-border);\n border-top-color: transparent;\n border-radius: 50%;\n animation: spin 0.7s linear infinite;\n margin: 4px auto;\n display: block;\n }\n\n .${errorMsgClass} {\n font-size: 11px;\n color: var(--inspecto-error-color);\n padding: 4px 8px;\n text-align: center;\n }\n\n .${badgeClass} {\n position: fixed;\n bottom: 16px;\n right: 16px;\n z-index: 2147483645;\n background: var(--inspecto-badge-bg);\n color: var(--inspecto-badge-text);\n border: var(--inspecto-badge-border);\n border-radius: 20px;\n padding: 6px 12px;\n font-size: 12px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n cursor: grab;\n opacity: 0.85;\n transition: background 0.2s, color 0.2s, opacity 0.2s, box-shadow 0.2s;\n pointer-events: all;\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n gap: 6px;\n user-select: none;\n -webkit-user-select: none;\n touch-action: none;\n }\n\n .${badgeClass}:active {\n cursor: grabbing;\n }\n\n .${badgeClass}-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: transparent;\n color: currentColor;\n font-size: 14px;\n line-height: 1;\n opacity: 0.5;\n transition: opacity 0.2s, background 0.2s;\n margin-left: 2px;\n cursor: pointer;\n }\n\n .${badgeClass}-close:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.2);\n }\n\n .${badgeClass}.active {\n background: var(--inspecto-badge-active-bg);\n color: var(--inspecto-badge-active-text);\n border: 1px solid transparent;\n box-shadow: 0 0 10px rgba(0, 122, 204, 0.3);\n }\n\n .${badgeClass}.disabled {\n background: rgba(30, 30, 30, 0.4);\n color: rgba(229, 229, 229, 0.5);\n text-decoration: line-through;\n border: 1px dashed rgba(255, 255, 255, 0.1);\n }\n\n .${badgeClass}.disabled .${badgeClass}-close {\n opacity: 0.8;\n text-decoration: none;\n transform: rotate(45deg);\n }\n\n .${badgeClass}:hover {\n opacity: 1;\n }\n`\n","import {\n overlayClass,\n tooltipClass,\n tooltipTopClass,\n tooltipBottomClass,\n tagClass,\n idClass,\n classClass,\n dimClass,\n separatorClass,\n sourceClass,\n} from './styles.js'\n\nconst GAP = 8\nconst EDGE_MARGIN = 4\n\nexport function createOverlay(shadowRoot: ShadowRoot): {\n show(el: Element, sourceLabel: string): void\n hide(): void\n} {\n const overlay = document.createElement('div')\n overlay.className = overlayClass\n overlay.style.display = 'none'\n\n const tooltip = document.createElement('div')\n tooltip.className = tooltipClass\n\n const tagSpan = document.createElement('span')\n tagSpan.className = tagClass\n\n const idSpan = document.createElement('span')\n idSpan.className = idClass\n\n const classSpan = document.createElement('span')\n classSpan.className = classClass\n\n const dimSpan = document.createElement('span')\n dimSpan.className = dimClass\n\n const separator = document.createElement('div')\n separator.className = separatorClass\n\n const sourceSpan = document.createElement('div')\n sourceSpan.className = sourceClass\n\n tooltip.appendChild(tagSpan)\n tooltip.appendChild(idSpan)\n tooltip.appendChild(classSpan)\n tooltip.appendChild(document.createTextNode(' '))\n tooltip.appendChild(dimSpan)\n tooltip.appendChild(separator)\n tooltip.appendChild(sourceSpan)\n\n shadowRoot.appendChild(overlay)\n shadowRoot.appendChild(tooltip)\n\n function show(el: Element, sourceLabel: string): void {\n const rect = el.getBoundingClientRect()\n\n // The overlay and tooltip are `position: fixed`, so we MUST use viewport coordinates (rect.left/top)\n // without adding window.scrollX/scrollY.\n\n // Update overlay box\n overlay.style.display = 'block'\n overlay.style.left = `${rect.left}px`\n overlay.style.top = `${rect.top}px`\n overlay.style.width = `${rect.width}px`\n overlay.style.height = `${rect.height}px`\n\n // Update tooltip content\n const tagName = el.tagName.toLowerCase()\n tagSpan.textContent = tagName\n\n idSpan.textContent = el.id ? `#${el.id}` : ''\n\n const classes = Array.from(el.classList)\n .map(c => `.${c}`)\n .join('')\n classSpan.textContent = classes\n\n dimSpan.textContent = `${Math.round(rect.width)} × ${Math.round(rect.height)}`\n\n sourceSpan.textContent = sourceLabel\n\n tooltip.style.visibility = 'hidden'\n tooltip.style.display = 'block'\n\n // Calculate tooltip position\n const tooltipRect = tooltip.getBoundingClientRect()\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth\n const viewportHeight = document.documentElement.clientHeight || window.innerHeight\n\n // Calculate vertical position (above or below)\n let tooltipTop = rect.top - tooltipRect.height - GAP\n let isBottom = false\n\n // If there's not enough space above, show it below\n if (tooltipTop < EDGE_MARGIN) {\n tooltipTop = rect.bottom + GAP\n // If showing below also goes off screen, clamp it to bottom of screen\n if (tooltipTop + tooltipRect.height > viewportHeight - EDGE_MARGIN) {\n tooltipTop = viewportHeight - tooltipRect.height - EDGE_MARGIN\n }\n isBottom = true\n }\n\n tooltip.classList.toggle(tooltipBottomClass, isBottom)\n tooltip.classList.toggle(tooltipTopClass, !isBottom)\n\n // Calculate horizontal position\n // Default to aligning with the left edge of the element\n let tooltipLeft = rect.left\n\n // Prevent overflowing the right edge\n if (tooltipLeft + tooltipRect.width > viewportWidth - EDGE_MARGIN) {\n tooltipLeft = viewportWidth - tooltipRect.width - EDGE_MARGIN\n }\n // Prevent overflowing the left edge\n if (tooltipLeft < EDGE_MARGIN) {\n tooltipLeft = EDGE_MARGIN\n }\n\n // Calculate arrow position so it always points at the element\n // The arrow normally points at rect.left + 10\n // But if the element is tiny, point at its center\n const targetPointX = rect.left + Math.min(15, rect.width / 2)\n\n // Calculate where the arrow should be relative to the tooltip\n let arrowLeft = targetPointX - tooltipLeft\n\n // Clamp arrow position so it doesn't detach from the tooltip bubble itself\n arrowLeft = Math.max(6, Math.min(arrowLeft, tooltipRect.width - 18))\n\n tooltip.style.left = `${tooltipLeft}px`\n tooltip.style.top = `${tooltipTop}px`\n tooltip.style.setProperty('--inspecto-arrow-left', `${arrowLeft}px`)\n\n tooltip.style.visibility = 'visible'\n }\n\n function hide(): void {\n overlay.style.display = 'none'\n tooltip.style.display = 'none'\n }\n\n return { show, hide }\n}\n","import type { SnippetResponse, SourceLocation } from '@inspecto-dev/types'\n\n/** Template for user-typed custom prompts from the ask input box. */\nexport function CUSTOM_PROMPT_TEMPLATE(userPrompt: string): string {\n return userPrompt\n}\n\n/**\n * Guess the UI framework based on file extension\n */\nfunction detectFramework(fileName: string): string {\n const ext = fileName.split('.').pop()?.toLowerCase() || ''\n switch (ext) {\n case 'vue':\n return 'Vue'\n case 'svelte':\n return 'Svelte'\n case 'astro':\n return 'Astro'\n case 'jsx':\n case 'tsx':\n return 'React'\n case 'ts':\n case 'js':\n return 'JavaScript/TypeScript'\n default:\n return 'UI'\n }\n}\n\n/**\n * Replace all {{placeholder}} tokens in a prompt template.\n */\nexport function buildPrompt(\n template: string,\n location: SourceLocation,\n snippetResult?: SnippetResponse | null,\n): string {\n const shortFile = location.file.split('/').pop() ?? location.file\n const ext = shortFile.split('.').pop()?.toLowerCase() || 'tsx'\n const framework = detectFramework(shortFile)\n\n let finalPrompt = template\n .replace(/\\{\\{file\\}\\}/g, location.file)\n .replace(/\\{\\{line\\}\\}/g, String(location.line))\n .replace(/\\{\\{column\\}\\}/g, String(location.column))\n .replace(/\\{\\{ext\\}\\}/g, ext)\n .replace(/\\{\\{framework\\}\\}/g, framework)\n .replace(/\\{\\{name\\}\\}/g, shortFile) // fallback\n\n if (snippetResult && snippetResult.snippet) {\n const name = snippetResult.name ?? shortFile\n finalPrompt = finalPrompt.replace(/\\{\\{name\\}\\}/g, name)\n // append snippet context\n finalPrompt += `\\n\\nContext from \\`${location.file}\\` (line ${location.line}):\\n\\`\\`\\`${ext}\\n${snippetResult.snippet}\\n\\`\\`\\``\n }\n\n return finalPrompt\n}\n","import type {\n SnippetResponse,\n SendToAiRequest,\n SendToAiResponse,\n OpenFileRequest,\n InspectoConfig,\n AiErrorCode,\n} from '@inspecto-dev/types'\nimport { INSPECTO_API_PATHS } from '@inspecto-dev/types'\n\nlet BASE_URL = globalThis.__AI_INSPECTOR_SERVER_URL__ || 'http://127.0.0.1:5678'\n\nexport function setBaseUrl(url: string): void {\n BASE_URL = url.replace(/\\/$/, '')\n}\n\nlet cachedConfig: InspectoConfig | null = null\n\nexport async function fetchIdeInfo(force = false): Promise<InspectoConfig | null> {\n if (cachedConfig && !force) return cachedConfig\n try {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.CLIENT_CONFIG}`)\n if (!res.ok) return null\n cachedConfig = await res.json()\n return cachedConfig\n } catch {\n return null\n }\n}\n\nexport async function openFile(req: OpenFileRequest): Promise<boolean> {\n try {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.IDE_OPEN}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(req),\n })\n return res.ok\n } catch {\n return false\n }\n}\n\nexport async function fetchSnippet(\n file: string,\n line: number,\n column: number,\n maxLines = 100,\n): Promise<SnippetResponse> {\n const params = new URLSearchParams({\n file,\n line: String(line),\n column: String(column),\n maxLines: String(maxLines),\n })\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.PROJECT_SNIPPET}?${params}`)\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { errorCode?: string }\n throw Object.assign(new Error('snippet fetch failed'), { errorCode: err.errorCode })\n }\n return res.json() as Promise<SnippetResponse>\n}\n\nexport async function sendToAi(req: SendToAiRequest): Promise<SendToAiResponse> {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.AI_DISPATCH}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(req),\n })\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { errorCode?: string; error?: string }\n return {\n success: false,\n error: err.error ?? 'Request failed',\n errorCode: err.errorCode as AiErrorCode,\n }\n }\n return res.json() as Promise<SendToAiResponse>\n}\n","import { buildPrompt, CUSTOM_PROMPT_TEMPLATE } from './intents.js'\nimport type { Provider, InspectorOptions, SourceLocation, IntentConfig } from '@inspecto-dev/types'\nimport { fetchSnippet, sendToAi, openFile, fetchIdeInfo } from './http.js'\nimport {\n menuClass,\n loadingSpinnerClass,\n errorMsgClass,\n menuItemClass,\n menuInputClass,\n menuInputWrapperClass,\n menuInputIconClass,\n shortcutIconClass,\n} from './styles.js'\n\nconst MENU_WIDTH = 280\n\nconst DISPLAY_NAMES: Record<Provider, string> = {\n copilot: 'GitHub Copilot',\n 'claude-code': 'Claude Code',\n gemini: 'Gemini',\n codex: 'Codex',\n coco: 'Coco CLI',\n trae: 'Trae AI',\n cursor: 'Cursor',\n}\n\nexport function showIntentMenu(\n shadowRoot: ShadowRoot,\n location: SourceLocation,\n clickX: number,\n clickY: number,\n options: InspectorOptions,\n onClose: () => void,\n): () => void {\n const maxSnippetLines = options.maxSnippetLines ?? 100\n const includeSnippet = options.includeSnippet ?? false\n\n const menu = document.createElement('div')\n menu.className = menuClass\n\n const { input, inputWrapper, sendIcon } = createAskInput(options.askPlaceholder)\n menu.appendChild(inputWrapper)\n\n const separator = document.createElement('div')\n separator.style.height = '1px'\n separator.style.background = 'var(--inspecto-menu-border)'\n separator.style.margin = '8px 4px 6px 4px'\n menu.appendChild(separator)\n\n const loadingEl = document.createElement('div')\n loadingEl.className = loadingSpinnerClass\n menu.appendChild(loadingEl)\n\n const viewportWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)\n const safeWidth = viewportWidth > 0 ? viewportWidth : MENU_WIDTH\n menu.style.left = `${Math.min(clickX, Math.max(safeWidth - MENU_WIDTH, 0))}px`\n menu.style.visibility = 'hidden'\n menu.style.display = 'block'\n\n shadowRoot.appendChild(menu)\n\n const updatePosition = () => {\n const rect = menu.getBoundingClientRect()\n const viewportHeight = Math.max(\n document.documentElement.clientHeight || 0,\n window.innerHeight || 0,\n )\n const safeHeight = viewportHeight > 0 ? viewportHeight : rect.height + 16\n menu.style.top = `${Math.min(clickY + 8, Math.max(safeHeight - rect.height - 8, 0))}px`\n }\n updatePosition()\n menu.style.visibility = 'visible'\n\n // Focus input automatically\n setTimeout(() => input.focus(), 0)\n\n const onDocClick = (e: MouseEvent): void => {\n // Because the menu is inside a Shadow DOM, e.target from the document's perspective\n // is just the <inspecto-overlay> custom element.\n const path = e.composedPath()\n if (path.includes(menu)) return\n cleanup()\n }\n // Use a small timeout so the click that opened the menu doesn't immediately close it\n setTimeout(() => document.addEventListener('click', onDocClick, { capture: true }), 0)\n\n function cleanup(): void {\n document.removeEventListener('click', onDocClick, { capture: true })\n menu.remove()\n onClose()\n }\n\n // Handle custom ask input\n const handleSend = async (\n promptText: string,\n snippetText: string,\n disable: () => void,\n restore: () => void,\n ) => {\n disable()\n\n // 1. 必须先 await openFile!\n // 如果不 await,openFile (基于 launch-ide 也就是 node child_process) 和 sendToAi (也就是 vscode:// URI handler)\n // 就会产生非常严重的竞态条件。\n // 如果 `sendToAi` 抢先获得了 focus 转移到了侧边栏,紧接着 `openFile` 才把文件在编辑器里打开,\n // 此时 activeTextEditor 就会被拉回源码文件,导致粘贴失败!\n const opened = await openFile(location)\n if (!opened) {\n restore()\n showError(menu, 'Unable to open file in the IDE.', 'IDE_UNAVAILABLE')\n return\n }\n\n // 可选:为了保证 IDE 完全缓冲好文件的打开,再微小延迟一点也是好的\n await new Promise(r => setTimeout(r, 100))\n\n // 2. 发送给 AI (触发 vscode URI handler,执行 focus 和 paste)\n const result = await sendToAi({ location, snippet: snippetText, prompt: promptText })\n\n if (result.success) {\n // Best-effort browser clipboard fallback. If the extension is not installed,\n // the user still gets the prompt in their clipboard.\n if (result.fallbackPayload?.prompt) {\n try {\n await navigator.clipboard.writeText(result.fallbackPayload.prompt)\n } catch (e) {\n // ignore\n }\n }\n cleanup()\n } else {\n restore()\n showError(menu, result.error ?? 'Unknown error', result.errorCode)\n }\n }\n\n const submitAsk = async () => {\n if (!input.value.trim()) return\n input.disabled = true\n sendIcon.style.pointerEvents = 'none'\n\n try {\n let snippetResult = null\n if (includeSnippet) {\n snippetResult = await fetchSnippet(\n location.file,\n location.line,\n location.column,\n maxSnippetLines,\n )\n }\n\n const prompt = buildPrompt(\n CUSTOM_PROMPT_TEMPLATE(input.value.trim()),\n location,\n snippetResult,\n )\n await handleSend(\n prompt,\n snippetResult?.snippet || '',\n () => {}, // already disabled\n () => {\n input.disabled = false\n sendIcon.style.pointerEvents = 'auto'\n },\n )\n } catch (err) {\n input.disabled = false\n sendIcon.style.pointerEvents = 'auto'\n showError(menu, (err as Error).message, (err as { errorCode?: string }).errorCode)\n }\n }\n\n input.addEventListener('keydown', e => {\n if (e.key === 'Enter') submitAsk()\n })\n sendIcon.addEventListener('click', submitAsk)\n\n // Fetch only IDE info to render the menu immediately\n fetchIdeInfo()\n .then(ideInfo => {\n loadingEl.remove()\n\n const intents = ideInfo?.prompts || []\n\n // Add intent buttons\n for (const intent of intents) {\n if (intent.isAction && intent.id === 'open-in-editor') {\n const btn = document.createElement('button')\n btn.className = menuItemClass\n const span = document.createElement('span')\n span.textContent = intent.label ?? 'Unknown'\n btn.appendChild(span)\n\n const shortcutDiv = document.createElement('div')\n shortcutDiv.className = shortcutIconClass\n shortcutDiv.textContent = '↵'\n btn.appendChild(shortcutDiv)\n\n btn.addEventListener('click', async e => {\n e.stopPropagation()\n btn.disabled = true\n const opened = await openFile(location)\n if (opened) {\n cleanup()\n return\n }\n btn.disabled = false\n showError(menu, 'Unable to open file in the IDE.', 'IDE_UNAVAILABLE')\n })\n menu.appendChild(btn)\n continue\n }\n\n let fullPromptTemplate = intent.prompt ?? ''\n if (intent.prependPrompt)\n fullPromptTemplate = intent.prependPrompt + '\\n\\n' + fullPromptTemplate\n if (intent.appendPrompt)\n fullPromptTemplate = fullPromptTemplate + '\\n\\n' + intent.appendPrompt\n\n const label = intent.label ?? intent.id ?? 'Unknown'\n const btn = document.createElement('button')\n btn.className = menuItemClass\n btn.textContent = label\n\n btn.addEventListener('click', async e => {\n e.stopPropagation()\n btn.disabled = true\n btn.textContent = 'Sending...'\n\n try {\n let snippetResult = null\n if (includeSnippet) {\n snippetResult = await fetchSnippet(\n location.file,\n location.line,\n location.column,\n maxSnippetLines,\n )\n }\n\n const prompt = buildPrompt(fullPromptTemplate, location, snippetResult)\n\n await handleSend(\n prompt,\n snippetResult?.snippet || '',\n () => {}, // already disabled\n () => {\n btn.disabled = false\n btn.textContent = label\n },\n )\n } catch (err) {\n btn.disabled = false\n btn.textContent = label\n showError(menu, (err as Error).message, (err as { errorCode?: string }).errorCode)\n }\n })\n\n menu.appendChild(btn)\n }\n updatePosition()\n })\n .catch((err: Error) => {\n loadingEl.remove()\n const isServerDown = err instanceof TypeError\n showError(\n menu,\n isServerDown\n ? 'Cannot connect to inspector server. Is the dev server running?'\n : err.message,\n (err as { errorCode?: string }).errorCode ?? 'UNKNOWN',\n )\n updatePosition()\n })\n\n return cleanup\n}\n\nfunction createAskInput(placeholder?: string) {\n const inputWrapper = document.createElement('div')\n inputWrapper.className = menuInputWrapperClass\n\n const input = document.createElement('input')\n input.className = menuInputClass\n input.type = 'text'\n input.placeholder = placeholder ?? 'Describe how to change this component...'\n\n const sendIcon = document.createElement('div')\n sendIcon.className = menuInputIconClass\n 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>`\n sendIcon.style.cursor = 'pointer'\n\n inputWrapper.appendChild(input)\n inputWrapper.appendChild(sendIcon)\n\n return { input, inputWrapper, sendIcon }\n}\n\nfunction showError(menu: HTMLElement, message: string, errorCode?: string): void {\n menu.querySelector(`.${errorMsgClass}`)?.remove()\n\n const errEl = document.createElement('div')\n errEl.className = errorMsgClass\n errEl.textContent =\n errorCode === 'FILE_NOT_FOUND'\n ? 'Source file not found. Is the server running?'\n : `Error: ${message}`\n menu.appendChild(errEl)\n}\n","import { createOverlay } from './overlay.js'\nimport { showIntentMenu } from './menu.js'\nimport type { InspectorOptions, HotKey, SourceLocation, HotKeys } from '@inspecto-dev/types'\nimport { setBaseUrl, fetchIdeInfo } from './http.js'\nimport { badgeClass, inspectorStyles } from './styles.js'\n\nconst ATTR_NAME = 'data-inspecto'\n\nfunction parseAttrValue(value: string): SourceLocation | null {\n const parts = value.split(':')\n if (parts.length < 3) return null\n\n const col = parseInt(parts[parts.length - 1]!, 10)\n const line = parseInt(parts[parts.length - 2]!, 10)\n const file = parts.slice(0, parts.length - 2).join(':')\n\n if (isNaN(line) || isNaN(col) || !file) return null\n return { file, line, column: col }\n}\n\nfunction findInspectable(el: Element | null): Element | null {\n while (el) {\n if (el.hasAttribute(ATTR_NAME)) return el\n el = el.parentElement\n }\n return null\n}\n\nfunction parseHotKeyString(hotKey: string): HotKey[] {\n const keys = hotKey.split('+').map(k => k.trim().toLowerCase())\n const result: HotKey[] = []\n\n if (keys.includes('alt') || keys.includes('option')) result.push('altKey')\n if (keys.includes('ctrl') || keys.includes('control')) result.push('ctrlKey')\n if (\n keys.includes('meta') ||\n keys.includes('cmd') ||\n keys.includes('command') ||\n keys.includes('win')\n )\n result.push('metaKey')\n if (keys.includes('shift')) result.push('shiftKey')\n\n return result\n}\n\nfunction hotKeysHeld(event: MouseEvent, hotKeys: string): boolean {\n if (!hotKeys) return false\n const mappedKeys = parseHotKeyString(hotKeys)\n if (mappedKeys.length === 0) return false\n return mappedKeys.every(key => event[key])\n}\n\n// Fallback class for SSR environments\nconst BaseElement =\n typeof HTMLElement !== 'undefined' ? HTMLElement : (class {} as typeof HTMLElement)\n\nclass InspectoElement extends BaseElement {\n private options: InspectorOptions = {}\n private serverHotKeys: HotKeys | null = null\n private active = false\n private disabled = false\n private isDragging = false\n private hasMoved = false\n private dragStartX = 0\n private dragStartY = 0\n private badgeInitialRight = 16\n private badgeInitialBottom = 16\n private shadowRootEl!: ShadowRoot\n private overlay!: ReturnType<typeof createOverlay>\n private cleanupMenu: (() => void) | null = null\n private badge!: HTMLButtonElement\n\n connectedCallback(): void {\n this.shadowRootEl = this.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = inspectorStyles\n this.shadowRootEl.appendChild(style)\n\n this.overlay = createOverlay(this.shadowRootEl)\n this.badge = this.createBadge()\n\n this.setupListeners()\n\n if (this.options.defaultActive) {\n this.setActive(true)\n }\n }\n\n disconnectedCallback(): void {\n this.teardownListeners()\n }\n\n configure(options: InspectorOptions): void {\n this.options = options\n if (options.serverUrl) {\n setBaseUrl(options.serverUrl)\n }\n\n // Apply explicitly configured theme, or fallback to auto (CSS media queries will take over if 'auto' or undefined)\n if (options.theme === 'dark') {\n this.setAttribute('data-theme', 'dark')\n } else if (options.theme === 'light') {\n this.setAttribute('data-theme', 'light')\n } else {\n this.removeAttribute('data-theme')\n }\n\n // Fetch hotKeys + other runtime config (prompts, targets) from the server.\n // hotKeys deliberately NOT baked into the injected script so that changes to\n // settings.json take effect on page refresh without restarting the dev server.\n fetchIdeInfo(true)\n .then(info => {\n if (info?.hotKeys !== undefined) {\n this.serverHotKeys = info.hotKeys\n this.updateBadgeContent()\n }\n if (info?.theme !== undefined) {\n if (info.theme === 'dark') {\n this.setAttribute('data-theme', 'dark')\n } else if (info.theme === 'light') {\n this.setAttribute('data-theme', 'light')\n } else {\n this.removeAttribute('data-theme')\n }\n }\n if (info?.includeSnippet !== undefined) {\n this.options.includeSnippet = info.includeSnippet\n }\n })\n .catch(() => {})\n }\n\n private createBadge(): HTMLButtonElement {\n const btn = document.createElement('button')\n btn.className = badgeClass\n btn.style.display = 'flex'\n\n const textSpan = document.createElement('span')\n textSpan.textContent = 'Inspecto Ready'\n\n const closeBtn = document.createElement('span')\n closeBtn.className = `${badgeClass}-close`\n closeBtn.innerHTML = '×'\n closeBtn.title = 'Pause Inspector'\n closeBtn.addEventListener('click', e => {\n e.stopPropagation()\n this.toggleDisabled()\n })\n\n btn.appendChild(textSpan)\n btn.appendChild(closeBtn)\n\n // Drag and Drop support\n btn.addEventListener('mousedown', this.onDragStart)\n\n btn.addEventListener('click', e => {\n // Prevent click if we were dragging\n if (this.hasMoved) {\n this.hasMoved = false\n return\n }\n\n if (this.disabled) {\n this.toggleDisabled()\n } else {\n this.setActive(!this.active)\n }\n })\n this.shadowRootEl.appendChild(btn)\n return btn\n }\n\n private readonly onDragStart = (e: MouseEvent): void => {\n // Only allow dragging with primary mouse button\n if (e.button !== 0) return\n\n // Don't drag if clicking the close button\n if ((e.target as Element).classList?.contains(`${badgeClass}-close`)) return\n\n e.preventDefault()\n\n this.isDragging = true\n this.hasMoved = false\n\n const rect = this.badge.getBoundingClientRect()\n // Calculate the exact offset where the user clicked inside the badge\n this.dragStartX = e.clientX - rect.left\n this.dragStartY = e.clientY - rect.top\n\n document.addEventListener('mousemove', this.onDragMove)\n document.addEventListener('mouseup', this.onDragEnd)\n }\n\n private readonly onDragMove = (e: MouseEvent): void => {\n if (!this.isDragging) return\n this.hasMoved = true\n\n // Calculate new position based on top/left\n let newLeft = e.clientX - this.dragStartX\n let newTop = e.clientY - this.dragStartY\n\n // Constrain to viewport\n const badgeWidth = this.badge.offsetWidth\n const badgeHeight = this.badge.offsetHeight\n\n newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - badgeWidth))\n newTop = Math.max(0, Math.min(newTop, window.innerHeight - badgeHeight))\n\n // Disable transition during drag for smoothness\n this.badge.style.transition = 'none'\n // Clear right/bottom to avoid conflicts\n this.badge.style.right = 'auto'\n this.badge.style.bottom = 'auto'\n this.badge.style.left = `${newLeft}px`\n this.badge.style.top = `${newTop}px`\n }\n\n private readonly onDragEnd = (): void => {\n document.removeEventListener('mousemove', this.onDragMove)\n document.removeEventListener('mouseup', this.onDragEnd)\n\n // Re-enable transitions\n this.badge.style.transition = ''\n\n // If it was just a click, reset isDragging state immediately\n // Otherwise, leave it true so the click handler knows to ignore the event\n setTimeout(() => {\n this.isDragging = false\n }, 0)\n }\n\n private toggleDisabled(): void {\n this.disabled = !this.disabled\n if (this.disabled) {\n this.active = false\n this.overlay.hide()\n this.cleanupMenu?.()\n this.cleanupMenu = null\n }\n this.updateBadgeContent()\n }\n\n private dismiss(): void {\n this.badge.style.display = 'none'\n this.setActive(false)\n }\n\n private getHotKeyHint(): string {\n const hotKeys = this.getEffectiveHotKeys()\n if (hotKeys === false) return 'Inspecto Ready'\n\n // Check if mac\n const isMac =\n typeof navigator !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.platform)\n\n const keys = hotKeys.split('+').map(k => k.trim().toLowerCase())\n const displayKeys = keys.map(k => {\n if (k === 'alt' || k === 'option') return isMac ? '⌥' : 'Alt'\n if (k === 'cmd' || k === 'meta' || k === 'win' || k === 'command') return isMac ? '⌘' : 'Win'\n if (k === 'ctrl' || k === 'control') return isMac ? '⌃' : 'Ctrl'\n if (k === 'shift') return isMac ? '⇧' : 'Shift'\n return k.charAt(0).toUpperCase() + k.slice(1)\n })\n\n return `Hold ${displayKeys.join(' + ')} to Inspect`\n }\n\n private getEffectiveHotKeys(): HotKeys {\n if (this.options.hotKeys !== undefined) return this.options.hotKeys\n if (this.serverHotKeys !== null) return this.serverHotKeys\n return 'alt'\n }\n\n private updateBadgeContent(): void {\n const textSpan = this.badge.querySelector('span')\n if (!textSpan) return\n\n if (this.disabled) {\n textSpan.textContent = 'Inspector Paused'\n this.badge.classList.remove('active')\n this.badge.classList.add('disabled')\n } else if (this.active) {\n textSpan.textContent = '🔍 Inspecting...'\n this.badge.classList.remove('disabled')\n this.badge.classList.add('active')\n } else {\n textSpan.textContent = this.getHotKeyHint()\n this.badge.classList.remove('active', 'disabled')\n }\n }\n\n private setActive(value: boolean): void {\n this.active = value\n this.updateBadgeContent()\n\n if (!value) {\n this.overlay.hide()\n this.cleanupMenu?.()\n this.cleanupMenu = null\n }\n }\n\n private readonly onMouseMove = (e: MouseEvent): void => {\n const isActive = this.isInspectorActive(e)\n if (!isActive) {\n this.overlay.hide()\n return\n }\n\n const target = findInspectable(e.target as Element)\n if (!target) {\n this.overlay.hide()\n return\n }\n\n const attrValue = target.getAttribute(ATTR_NAME)!\n const loc = parseAttrValue(attrValue)\n const label = loc ? `${loc.file.split('/').pop() ?? ''}:${loc.line}` : attrValue\n\n this.overlay.show(target, label)\n e.stopPropagation()\n }\n\n private readonly onClick = (e: MouseEvent): void => {\n this.handleTrigger(e)\n }\n\n private readonly onContextMenu = (e: MouseEvent): void => {\n if (this.isInspectorActive(e)) {\n this.handleTrigger(e)\n }\n }\n\n private handleTrigger(e: MouseEvent): void {\n if (!this.isInspectorActive(e)) return\n\n const target = findInspectable(e.target as Element)\n if (!target) return\n\n e.preventDefault()\n e.stopPropagation()\n\n const attrValue = target.getAttribute(ATTR_NAME)!\n const loc = parseAttrValue(attrValue)\n if (!loc) return\n\n this.cleanupMenu?.()\n\n this.cleanupMenu = showIntentMenu(\n this.shadowRootEl,\n loc,\n e.clientX,\n e.clientY,\n this.options,\n () => {\n this.cleanupMenu = null\n },\n )\n }\n\n private readonly onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') {\n this.cleanupMenu?.()\n this.overlay.hide()\n }\n }\n\n private isInspectorActive(e: MouseEvent): boolean {\n if (this.disabled) return false\n if (this.active) return true\n\n const hotKeys = this.getEffectiveHotKeys()\n if (hotKeys === false) return false\n return hotKeysHeld(e, hotKeys)\n }\n\n private setupListeners(): void {\n document.addEventListener('mousemove', this.onMouseMove, true)\n document.addEventListener('click', this.onClick, true)\n document.addEventListener('contextmenu', this.onContextMenu, true)\n document.addEventListener('keydown', this.onKeyDown, true)\n }\n\n private teardownListeners(): void {\n document.removeEventListener('mousemove', this.onMouseMove, true)\n document.removeEventListener('click', this.onClick, true)\n document.removeEventListener('contextmenu', this.onContextMenu, true)\n document.removeEventListener('keydown', this.onKeyDown, true)\n }\n}\n\nif (typeof customElements !== 'undefined') {\n customElements.define('inspecto-overlay', InspectoElement)\n}\n\nexport { InspectoElement }\n","import type { InspectorOptions } from '@inspecto-dev/types'\n\n// Export types only, avoid top-level imports of DOM-dependent code\nexport type { InspectorOptions }\nexport type { InspectoElement } from './component.js'\n\nconst TAG_NAME = 'inspecto-overlay'\n\nexport async function mountInspector(options: InspectorOptions = {}): Promise<any> {\n if (typeof document === 'undefined') return null\n\n // Lazy import the component so that module evaluation does not happen during SSR\n const { InspectoElement } = await import('./component.js')\n\n const existing = document.querySelector(TAG_NAME)\n if (existing) {\n ;(existing as typeof InspectoElement.prototype).configure(options)\n return existing\n }\n\n const el = document.createElement(TAG_NAME)\n ;(el as typeof InspectoElement.prototype).configure(options)\n document.body.appendChild(el)\n return el\n}\n\nexport function unmountInspector(): void {\n if (typeof document === 'undefined') return\n const existing = document.querySelector(TAG_NAME)\n if (existing) {\n existing.remove()\n }\n}\n\n// Expose to global window for Webpack/Rspack EntryPlugin injection fallback\nif (typeof window !== 'undefined') {\n window.InspectoClient = {\n mountInspector,\n unmountInspector,\n }\n}\n"],"mappings":"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","names":["_a","_b","btn","InspectoElement"]}
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ var TAG_NAME = "inspecto-overlay";
7
7
  function mountInspector() {
8
8
  return __async(this, arguments, function* (options = {}) {
9
9
  if (typeof document === "undefined") return null;
10
- const { InspectoElement } = yield import("./component-4WPU23TV.js");
10
+ const { InspectoElement } = yield import("./component-VOGY7YTT.js");
11
11
  const existing = document.querySelector(TAG_NAME);
12
12
  if (existing) {
13
13
  ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inspecto-dev/core",
3
- "version": "0.2.0-alpha.2",
3
+ "version": "0.2.0-alpha.4",
4
4
  "description": "Core browser runtime and server logic for Inspecto",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -39,7 +39,7 @@
39
39
  "dependencies": {
40
40
  "launch-ide": "^1.0.0",
41
41
  "portfinder": "^1.0.32",
42
- "@inspecto-dev/types": "0.2.0-alpha.2"
42
+ "@inspecto-dev/types": "0.2.0-alpha.4"
43
43
  },
44
44
  "scripts": {
45
45
  "build": "tsup",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/styles.ts","../src/overlay.ts","../src/intents.ts","../src/http.ts","../src/menu.ts","../src/component.ts"],"sourcesContent":["export const overlayClass = 'inspecto-overlay'\nexport const menuClass = 'inspecto-menu'\nexport const menuTitleClass = 'inspecto-menu-title'\nexport const menuItemClass = 'inspecto-menu-item'\nexport const loadingSpinnerClass = 'inspecto-spinner'\nexport const errorMsgClass = 'inspecto-error'\nexport const badgeClass = 'inspecto-badge'\nexport const menuInputClass = 'inspecto-menu-input'\nexport const menuInputWrapperClass = 'inspecto-menu-input-wrapper'\nexport const menuInputIconClass = 'inspecto-menu-input-icon'\n\n// Tooltip & overlay specific classes\nexport const tooltipClass = 'inspecto-tooltip'\nexport const tooltipTopClass = 'inspecto-tooltip-top'\nexport const tooltipBottomClass = 'inspecto-tooltip-bottom'\nexport const tagClass = 'inspecto-tag'\nexport const idClass = 'inspecto-id'\nexport const classClass = 'inspecto-class'\nexport const dimClass = 'inspecto-dim'\nexport const separatorClass = 'inspecto-separator'\nexport const sourceClass = 'inspecto-source'\nexport const shortcutIconClass = 'ai-shortcut-icon'\n\nconst darkVars = `\n --inspecto-menu-bg: #252526;\n --inspecto-menu-border: #454545;\n --inspecto-menu-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);\n --inspecto-text: #cccccc;\n --inspecto-text-muted: #858585;\n --inspecto-hover-bg: #04395e;\n --inspecto-hover-text: #ffffff;\n --inspecto-hover-icon: #ffffff;\n --inspecto-input-bg: #3c3c3c;\n --inspecto-input-border: #007acc;\n --inspecto-shortcut-text: #858585;\n --inspecto-badge-bg: rgba(30, 30, 30, 0.7);\n --inspecto-badge-text: #e5e5e5;\n --inspecto-badge-active-bg: #007acc;\n --inspecto-badge-active-text: #ffffff;\n --inspecto-badge-border: 1px solid rgba(255, 255, 255, 0.1);\n \n --inspecto-tooltip-bg: #222222;\n --inspecto-tooltip-text: #cccccc;\n --inspecto-tooltip-border: #444;\n --inspecto-tooltip-shadow: 0 2px 10px rgba(0,0,0,0.5);\n --inspecto-tag-color: #d16969;\n --inspecto-id-color: #d16969;\n --inspecto-class-color: #9cdcfe;\n --inspecto-dim-color: #858585;\n --inspecto-error-color: #ef4444;\n`\n\nexport const inspectorStyles = `\n :host {\n /* Light theme (default) */\n --inspecto-menu-bg: #ffffff;\n --inspecto-menu-border: #d4d4d4;\n --inspecto-menu-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n --inspecto-text: #333333;\n --inspecto-text-muted: #6b7280;\n --inspecto-hover-bg: #0060c0;\n --inspecto-hover-text: #ffffff;\n --inspecto-hover-icon: #ffffff;\n --inspecto-input-bg: #ffffff;\n --inspecto-input-border: #007acc;\n --inspecto-shortcut-text: #9ca3af;\n --inspecto-badge-bg: rgba(30, 30, 30, 0.7);\n --inspecto-badge-text: #e5e5e5;\n --inspecto-badge-active-bg: #007acc;\n --inspecto-badge-active-text: #ffffff;\n --inspecto-badge-border: 1px solid rgba(255, 255, 255, 0.1);\n \n /* Chrome DevTools like colors */\n --inspecto-overlay-border: #4285f4; /* Google Blue */\n --inspecto-overlay-bg: rgba(66, 133, 244, 0.2); \n --inspecto-tooltip-bg: #ffffff;\n --inspecto-tooltip-text: #333333;\n --inspecto-tooltip-border: #ccc;\n --inspecto-tooltip-shadow: 0 2px 10px rgba(0,0,0,0.1);\n \n --inspecto-tag-color: #8b008b; /* Dark magenta */\n --inspecto-id-color: #8b008b;\n --inspecto-class-color: #00008b; /* Dark blue */\n --inspecto-dim-color: #555555;\n --inspecto-error-color: #ef4444;\n }\n\n :host([data-theme=\"dark\"]) {\n ${darkVars}\n }\n\n @media (prefers-color-scheme: dark) {\n :host(:not([data-theme=\"light\"])) {\n ${darkVars}\n }\n }\n\n .${overlayClass} {\n position: fixed;\n pointer-events: none;\n z-index: 2147483646;\n border: 1px dashed var(--inspecto-overlay-border);\n background: var(--inspecto-overlay-bg);\n box-sizing: border-box;\n transition: all 0.05s linear;\n }\n\n .${tooltipClass} {\n position: fixed;\n pointer-events: none;\n z-index: 2147483647;\n background: var(--inspecto-tooltip-bg);\n color: var(--inspecto-tooltip-text);\n border: 1px solid var(--inspecto-tooltip-border);\n border-radius: 4px;\n box-shadow: var(--inspecto-tooltip-shadow);\n padding: 6px 10px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n font-size: 12px;\n line-height: 1.4;\n transition: all 0.05s linear;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n \n /* Create the small pointer arrow like Chrome DevTools */\n .${tooltipClass}::after {\n content: '';\n position: absolute;\n width: 0;\n height: 0;\n border-style: solid;\n }\n\n .${tooltipTopClass}::after {\n bottom: -6px;\n left: var(--inspecto-arrow-left, 10px);\n border-width: 6px 6px 0 6px;\n border-color: var(--inspecto-tooltip-bg) transparent transparent transparent;\n }\n\n .${tooltipBottomClass}::after {\n top: -6px;\n left: var(--inspecto-arrow-left, 10px);\n border-width: 0 6px 6px 6px;\n border-color: transparent transparent var(--inspecto-tooltip-bg) transparent;\n }\n \n /* Outline for the arrow to match border */\n .${tooltipClass}::before {\n content: '';\n position: absolute;\n width: 0;\n height: 0;\n border-style: solid;\n }\n \n .${tooltipTopClass}::before {\n bottom: -7px;\n left: calc(var(--inspecto-arrow-left, 10px) - 1px);\n border-width: 7px 7px 0 7px;\n border-color: var(--inspecto-tooltip-border) transparent transparent transparent;\n }\n \n .${tooltipBottomClass}::before {\n top: -7px;\n left: calc(var(--inspecto-arrow-left, 10px) - 1px);\n border-width: 0 7px 7px 7px;\n border-color: transparent transparent var(--inspecto-tooltip-border) transparent;\n }\n\n .${tagClass} {\n color: var(--inspecto-tag-color);\n font-weight: 600;\n font-family: monospace;\n }\n \n .${idClass} {\n color: var(--inspecto-id-color);\n font-weight: 600;\n font-family: monospace;\n }\n\n .${classClass} {\n color: var(--inspecto-class-color);\n font-family: monospace;\n }\n\n .${dimClass} {\n color: var(--inspecto-dim-color);\n margin-left: 4px;\n }\n \n .${separatorClass} {\n height: 1px;\n background: var(--inspecto-tooltip-border);\n margin: 2px -10px;\n opacity: 0.5;\n }\n \n .${sourceClass} {\n font-family: 'SF Mono', 'Fira Code', monospace;\n font-size: 11px;\n color: var(--inspecto-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 300px;\n }\n\n .${menuClass} {\n position: fixed;\n z-index: 2147483647;\n background: var(--inspecto-menu-bg);\n border: 1px solid var(--inspecto-menu-border);\n border-radius: 6px;\n padding: 6px;\n min-width: 300px;\n box-shadow: var(--inspecto-menu-shadow);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n color: var(--inspecto-text);\n }\n\n .${menuInputWrapperClass} {\n display: flex;\n align-items: center;\n border: 1px solid var(--inspecto-menu-border);\n border-radius: 4px;\n padding: 6px 8px;\n margin: 4px;\n margin-bottom: 8px;\n }\n \n .${menuInputWrapperClass}:focus-within {\n border-color: var(--inspecto-input-border);\n }\n\n .${menuInputClass} {\n width: 100%;\n border: none;\n outline: none;\n font-size: 13px;\n color: var(--inspecto-text);\n background: transparent;\n }\n\n .${menuInputClass}::placeholder {\n color: var(--inspecto-text-muted);\n }\n\n .${menuInputIconClass} {\n color: var(--inspecto-text-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 4px;\n }\n\n .${menuInputIconClass}:hover {\n color: var(--inspecto-text);\n }\n\n .${menuItemClass} {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 6px 10px;\n margin: 2px 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--inspecto-text);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n }\n\n .${menuItemClass}:hover {\n background: var(--inspecto-hover-bg);\n color: var(--inspecto-hover-text);\n }\n\n .${menuItemClass} .${shortcutIconClass} {\n margin-left: auto;\n color: var(--inspecto-text-muted);\n }\n\n .${menuItemClass}:hover .${shortcutIconClass} {\n color: var(--inspecto-hover-icon);\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .${loadingSpinnerClass} {\n width: 14px;\n height: 14px;\n border: 2px solid var(--inspecto-overlay-border);\n border-top-color: transparent;\n border-radius: 50%;\n animation: spin 0.7s linear infinite;\n margin: 4px auto;\n display: block;\n }\n\n .${errorMsgClass} {\n font-size: 11px;\n color: var(--inspecto-error-color);\n padding: 4px 8px;\n text-align: center;\n }\n\n .${badgeClass} {\n position: fixed;\n bottom: 16px;\n right: 16px;\n z-index: 2147483645;\n background: var(--inspecto-badge-bg);\n color: var(--inspecto-badge-text);\n border: var(--inspecto-badge-border);\n border-radius: 20px;\n padding: 6px 12px;\n font-size: 12px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n cursor: grab;\n opacity: 0.85;\n transition: background 0.2s, color 0.2s, opacity 0.2s, box-shadow 0.2s;\n pointer-events: all;\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n gap: 6px;\n user-select: none;\n -webkit-user-select: none;\n touch-action: none;\n }\n\n .${badgeClass}:active {\n cursor: grabbing;\n }\n\n .${badgeClass}-close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: transparent;\n color: currentColor;\n font-size: 14px;\n line-height: 1;\n opacity: 0.5;\n transition: opacity 0.2s, background 0.2s;\n margin-left: 2px;\n cursor: pointer;\n }\n\n .${badgeClass}-close:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.2);\n }\n\n .${badgeClass}.active {\n background: var(--inspecto-badge-active-bg);\n color: var(--inspecto-badge-active-text);\n border: 1px solid transparent;\n box-shadow: 0 0 10px rgba(0, 122, 204, 0.3);\n }\n\n .${badgeClass}.disabled {\n background: rgba(30, 30, 30, 0.4);\n color: rgba(229, 229, 229, 0.5);\n text-decoration: line-through;\n border: 1px dashed rgba(255, 255, 255, 0.1);\n }\n\n .${badgeClass}.disabled .${badgeClass}-close {\n opacity: 0.8;\n text-decoration: none;\n transform: rotate(45deg);\n }\n\n .${badgeClass}:hover {\n opacity: 1;\n }\n`\n","import {\n overlayClass,\n tooltipClass,\n tooltipTopClass,\n tooltipBottomClass,\n tagClass,\n idClass,\n classClass,\n dimClass,\n separatorClass,\n sourceClass,\n} from './styles.js'\n\nconst GAP = 8\nconst EDGE_MARGIN = 4\n\nexport function createOverlay(shadowRoot: ShadowRoot): {\n show(el: Element, sourceLabel: string): void\n hide(): void\n} {\n const overlay = document.createElement('div')\n overlay.className = overlayClass\n overlay.style.display = 'none'\n\n const tooltip = document.createElement('div')\n tooltip.className = tooltipClass\n\n const tagSpan = document.createElement('span')\n tagSpan.className = tagClass\n\n const idSpan = document.createElement('span')\n idSpan.className = idClass\n\n const classSpan = document.createElement('span')\n classSpan.className = classClass\n\n const dimSpan = document.createElement('span')\n dimSpan.className = dimClass\n\n const separator = document.createElement('div')\n separator.className = separatorClass\n\n const sourceSpan = document.createElement('div')\n sourceSpan.className = sourceClass\n\n tooltip.appendChild(tagSpan)\n tooltip.appendChild(idSpan)\n tooltip.appendChild(classSpan)\n tooltip.appendChild(document.createTextNode(' '))\n tooltip.appendChild(dimSpan)\n tooltip.appendChild(separator)\n tooltip.appendChild(sourceSpan)\n\n shadowRoot.appendChild(overlay)\n shadowRoot.appendChild(tooltip)\n\n function show(el: Element, sourceLabel: string): void {\n const rect = el.getBoundingClientRect()\n\n // The overlay and tooltip are `position: fixed`, so we MUST use viewport coordinates (rect.left/top)\n // without adding window.scrollX/scrollY.\n\n // Update overlay box\n overlay.style.display = 'block'\n overlay.style.left = `${rect.left}px`\n overlay.style.top = `${rect.top}px`\n overlay.style.width = `${rect.width}px`\n overlay.style.height = `${rect.height}px`\n\n // Update tooltip content\n const tagName = el.tagName.toLowerCase()\n tagSpan.textContent = tagName\n\n idSpan.textContent = el.id ? `#${el.id}` : ''\n\n const classes = Array.from(el.classList)\n .map(c => `.${c}`)\n .join('')\n classSpan.textContent = classes\n\n dimSpan.textContent = `${Math.round(rect.width)} × ${Math.round(rect.height)}`\n\n sourceSpan.textContent = sourceLabel\n\n tooltip.style.visibility = 'hidden'\n tooltip.style.display = 'block'\n\n // Calculate tooltip position\n const tooltipRect = tooltip.getBoundingClientRect()\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth\n const viewportHeight = document.documentElement.clientHeight || window.innerHeight\n\n // Calculate vertical position (above or below)\n let tooltipTop = rect.top - tooltipRect.height - GAP\n let isBottom = false\n\n // If there's not enough space above, show it below\n if (tooltipTop < EDGE_MARGIN) {\n tooltipTop = rect.bottom + GAP\n // If showing below also goes off screen, clamp it to bottom of screen\n if (tooltipTop + tooltipRect.height > viewportHeight - EDGE_MARGIN) {\n tooltipTop = viewportHeight - tooltipRect.height - EDGE_MARGIN\n }\n isBottom = true\n }\n\n tooltip.classList.toggle(tooltipBottomClass, isBottom)\n tooltip.classList.toggle(tooltipTopClass, !isBottom)\n\n // Calculate horizontal position\n // Default to aligning with the left edge of the element\n let tooltipLeft = rect.left\n\n // Prevent overflowing the right edge\n if (tooltipLeft + tooltipRect.width > viewportWidth - EDGE_MARGIN) {\n tooltipLeft = viewportWidth - tooltipRect.width - EDGE_MARGIN\n }\n // Prevent overflowing the left edge\n if (tooltipLeft < EDGE_MARGIN) {\n tooltipLeft = EDGE_MARGIN\n }\n\n // Calculate arrow position so it always points at the element\n // The arrow normally points at rect.left + 10\n // But if the element is tiny, point at its center\n const targetPointX = rect.left + Math.min(15, rect.width / 2)\n\n // Calculate where the arrow should be relative to the tooltip\n let arrowLeft = targetPointX - tooltipLeft\n\n // Clamp arrow position so it doesn't detach from the tooltip bubble itself\n arrowLeft = Math.max(6, Math.min(arrowLeft, tooltipRect.width - 18))\n\n tooltip.style.left = `${tooltipLeft}px`\n tooltip.style.top = `${tooltipTop}px`\n tooltip.style.setProperty('--inspecto-arrow-left', `${arrowLeft}px`)\n\n tooltip.style.visibility = 'visible'\n }\n\n function hide(): void {\n overlay.style.display = 'none'\n tooltip.style.display = 'none'\n }\n\n return { show, hide }\n}\n","import type { SnippetResponse, SourceLocation } from '@inspecto-dev/types'\n\n/** Template for user-typed custom prompts from the ask input box. */\nexport function CUSTOM_PROMPT_TEMPLATE(userPrompt: string): string {\n return userPrompt\n}\n\n/**\n * Guess the UI framework based on file extension\n */\nfunction detectFramework(fileName: string): string {\n const ext = fileName.split('.').pop()?.toLowerCase() || ''\n switch (ext) {\n case 'vue':\n return 'Vue'\n case 'svelte':\n return 'Svelte'\n case 'astro':\n return 'Astro'\n case 'jsx':\n case 'tsx':\n return 'React'\n case 'ts':\n case 'js':\n return 'JavaScript/TypeScript'\n default:\n return 'UI'\n }\n}\n\n/**\n * Replace all {{placeholder}} tokens in a prompt template.\n */\nexport function buildPrompt(\n template: string,\n location: SourceLocation,\n snippetResult?: SnippetResponse | null,\n): string {\n const shortFile = location.file.split('/').pop() ?? location.file\n const ext = shortFile.split('.').pop()?.toLowerCase() || 'tsx'\n const framework = detectFramework(shortFile)\n\n let finalPrompt = template\n .replace(/\\{\\{file\\}\\}/g, location.file)\n .replace(/\\{\\{line\\}\\}/g, String(location.line))\n .replace(/\\{\\{column\\}\\}/g, String(location.column))\n .replace(/\\{\\{ext\\}\\}/g, ext)\n .replace(/\\{\\{framework\\}\\}/g, framework)\n .replace(/\\{\\{name\\}\\}/g, shortFile) // fallback\n\n if (snippetResult && snippetResult.snippet) {\n const name = snippetResult.name ?? shortFile\n finalPrompt = finalPrompt.replace(/\\{\\{name\\}\\}/g, name)\n // append snippet context\n finalPrompt += `\\n\\nContext from \\`${location.file}\\` (line ${location.line}):\\n\\`\\`\\`${ext}\\n${snippetResult.snippet}\\n\\`\\`\\``\n }\n\n return finalPrompt\n}\n","import type {\n SnippetResponse,\n SendToAiRequest,\n SendToAiResponse,\n OpenFileRequest,\n InspectoConfig,\n AiErrorCode,\n} from '@inspecto-dev/types'\nimport { INSPECTO_API_PATHS } from '@inspecto-dev/types'\n\nlet BASE_URL = globalThis.__AI_INSPECTOR_SERVER_URL__ || 'http://127.0.0.1:5678'\n\nexport function setBaseUrl(url: string): void {\n BASE_URL = url.replace(/\\/$/, '')\n}\n\nlet cachedConfig: InspectoConfig | null = null\n\nexport async function fetchIdeInfo(force = false): Promise<InspectoConfig | null> {\n if (cachedConfig && !force) return cachedConfig\n try {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.CLIENT_CONFIG}`)\n if (!res.ok) return null\n cachedConfig = await res.json()\n return cachedConfig\n } catch {\n return null\n }\n}\n\nexport async function openFile(req: OpenFileRequest): Promise<boolean> {\n try {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.IDE_OPEN}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(req),\n })\n return res.ok\n } catch {\n return false\n }\n}\n\nexport async function fetchSnippet(\n file: string,\n line: number,\n column: number,\n maxLines = 100,\n): Promise<SnippetResponse> {\n const params = new URLSearchParams({\n file,\n line: String(line),\n column: String(column),\n maxLines: String(maxLines),\n })\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.PROJECT_SNIPPET}?${params}`)\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { errorCode?: string }\n throw Object.assign(new Error('snippet fetch failed'), { errorCode: err.errorCode })\n }\n return res.json() as Promise<SnippetResponse>\n}\n\nexport async function sendToAi(req: SendToAiRequest): Promise<SendToAiResponse> {\n const res = await fetch(`${BASE_URL}${INSPECTO_API_PATHS.AI_DISPATCH}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(req),\n })\n if (!res.ok) {\n const err = (await res.json().catch(() => ({}))) as { errorCode?: string; error?: string }\n return {\n success: false,\n error: err.error ?? 'Request failed',\n errorCode: err.errorCode as AiErrorCode,\n }\n }\n return res.json() as Promise<SendToAiResponse>\n}\n","import { buildPrompt, CUSTOM_PROMPT_TEMPLATE } from './intents.js'\nimport type { Provider, InspectorOptions, SourceLocation, IntentConfig } from '@inspecto-dev/types'\nimport { fetchSnippet, sendToAi, openFile, fetchIdeInfo } from './http.js'\nimport {\n menuClass,\n loadingSpinnerClass,\n errorMsgClass,\n menuItemClass,\n menuInputClass,\n menuInputWrapperClass,\n menuInputIconClass,\n shortcutIconClass,\n} from './styles.js'\n\nconst MENU_WIDTH = 280\n\nconst DISPLAY_NAMES: Record<Provider, string> = {\n copilot: 'GitHub Copilot',\n 'claude-code': 'Claude Code',\n gemini: 'Gemini',\n codex: 'Codex',\n coco: 'Coco CLI',\n trae: 'Trae AI',\n cursor: 'Cursor',\n}\n\nexport function showIntentMenu(\n shadowRoot: ShadowRoot,\n location: SourceLocation,\n clickX: number,\n clickY: number,\n options: InspectorOptions,\n onClose: () => void,\n): () => void {\n const maxSnippetLines = options.maxSnippetLines ?? 100\n const includeSnippet = options.includeSnippet ?? false\n\n const menu = document.createElement('div')\n menu.className = menuClass\n\n const { input, inputWrapper, sendIcon } = createAskInput(options.askPlaceholder)\n menu.appendChild(inputWrapper)\n\n const separator = document.createElement('div')\n separator.style.height = '1px'\n separator.style.background = 'var(--inspecto-menu-border)'\n separator.style.margin = '8px 4px 6px 4px'\n menu.appendChild(separator)\n\n const loadingEl = document.createElement('div')\n loadingEl.className = loadingSpinnerClass\n menu.appendChild(loadingEl)\n\n menu.style.left = `${Math.min(clickX, window.innerWidth - MENU_WIDTH)}px`\n menu.style.visibility = 'hidden'\n menu.style.display = 'block'\n\n shadowRoot.appendChild(menu)\n\n const updatePosition = () => {\n const rect = menu.getBoundingClientRect()\n menu.style.top = `${Math.min(clickY + 8, window.innerHeight - rect.height - 8)}px`\n }\n updatePosition()\n menu.style.visibility = 'visible'\n\n // Focus input automatically\n setTimeout(() => input.focus(), 0)\n\n const onDocClick = (e: MouseEvent): void => {\n // Because the menu is inside a Shadow DOM, e.target from the document's perspective\n // is just the <inspecto-overlay> custom element.\n const path = e.composedPath()\n if (path.includes(menu)) return\n cleanup()\n }\n // Use a small timeout so the click that opened the menu doesn't immediately close it\n setTimeout(() => document.addEventListener('click', onDocClick, { capture: true }), 0)\n\n function cleanup(): void {\n document.removeEventListener('click', onDocClick, { capture: true })\n menu.remove()\n onClose()\n }\n\n // Handle custom ask input\n const handleSend = async (\n promptText: string,\n snippetText: string,\n disable: () => void,\n restore: () => void,\n ) => {\n disable()\n\n // 1. 必须先 await openFile!\n // 如果不 await,openFile (基于 launch-ide 也就是 node child_process) 和 sendToAi (也就是 vscode:// URI handler)\n // 就会产生非常严重的竞态条件。\n // 如果 `sendToAi` 抢先获得了 focus 转移到了侧边栏,紧接着 `openFile` 才把文件在编辑器里打开,\n // 此时 activeTextEditor 就会被拉回源码文件,导致粘贴失败!\n await openFile(location)\n\n // 可选:为了保证 IDE 完全缓冲好文件的打开,再微小延迟一点也是好的\n await new Promise(r => setTimeout(r, 100))\n\n // 2. 发送给 AI (触发 vscode URI handler,执行 focus 和 paste)\n const result = await sendToAi({ location, snippet: snippetText, prompt: promptText })\n\n if (result.success) {\n // Best-effort browser clipboard fallback. If the extension is not installed,\n // the user still gets the prompt in their clipboard.\n if (result.fallbackPayload?.prompt) {\n try {\n await navigator.clipboard.writeText(result.fallbackPayload.prompt)\n } catch (e) {\n // ignore\n }\n }\n cleanup()\n } else {\n restore()\n showError(menu, result.error ?? 'Unknown error', result.errorCode)\n }\n }\n\n const submitAsk = async () => {\n if (!input.value.trim()) return\n input.disabled = true\n sendIcon.style.pointerEvents = 'none'\n\n try {\n let snippetResult = null\n if (includeSnippet) {\n snippetResult = await fetchSnippet(\n location.file,\n location.line,\n location.column,\n maxSnippetLines,\n )\n }\n\n const prompt = buildPrompt(\n CUSTOM_PROMPT_TEMPLATE(input.value.trim()),\n location,\n snippetResult,\n )\n await handleSend(\n prompt,\n snippetResult?.snippet || '',\n () => {}, // already disabled\n () => {\n input.disabled = false\n sendIcon.style.pointerEvents = 'auto'\n },\n )\n } catch (err) {\n input.disabled = false\n sendIcon.style.pointerEvents = 'auto'\n showError(menu, (err as Error).message, (err as { errorCode?: string }).errorCode)\n }\n }\n\n input.addEventListener('keydown', e => {\n if (e.key === 'Enter') submitAsk()\n })\n sendIcon.addEventListener('click', submitAsk)\n\n // Fetch only IDE info to render the menu immediately\n fetchIdeInfo()\n .then(ideInfo => {\n loadingEl.remove()\n\n const intents = ideInfo?.prompts || []\n\n // Add intent buttons\n for (const intent of intents) {\n if (intent.isAction && intent.id === 'open-in-editor') {\n const btn = document.createElement('button')\n btn.className = menuItemClass\n const span = document.createElement('span')\n span.textContent = intent.label ?? 'Unknown'\n btn.appendChild(span)\n\n const shortcutDiv = document.createElement('div')\n shortcutDiv.className = shortcutIconClass\n shortcutDiv.textContent = '↵'\n btn.appendChild(shortcutDiv)\n\n btn.addEventListener('click', e => {\n e.stopPropagation()\n openFile(location)\n cleanup()\n })\n menu.appendChild(btn)\n continue\n }\n\n let fullPromptTemplate = intent.prompt ?? ''\n if (intent.prependPrompt)\n fullPromptTemplate = intent.prependPrompt + '\\n\\n' + fullPromptTemplate\n if (intent.appendPrompt)\n fullPromptTemplate = fullPromptTemplate + '\\n\\n' + intent.appendPrompt\n\n const label = intent.label ?? intent.id ?? 'Unknown'\n const btn = document.createElement('button')\n btn.className = menuItemClass\n btn.textContent = label\n\n btn.addEventListener('click', async e => {\n e.stopPropagation()\n btn.disabled = true\n btn.textContent = 'Sending...'\n\n try {\n let snippetResult = null\n if (includeSnippet) {\n snippetResult = await fetchSnippet(\n location.file,\n location.line,\n location.column,\n maxSnippetLines,\n )\n }\n\n const prompt = buildPrompt(fullPromptTemplate, location, snippetResult)\n\n await handleSend(\n prompt,\n snippetResult?.snippet || '',\n () => {}, // already disabled\n () => {\n btn.disabled = false\n btn.textContent = label\n },\n )\n } catch (err) {\n btn.disabled = false\n btn.textContent = label\n showError(menu, (err as Error).message, (err as { errorCode?: string }).errorCode)\n }\n })\n\n menu.appendChild(btn)\n }\n updatePosition()\n })\n .catch((err: Error) => {\n loadingEl.remove()\n const isServerDown = err instanceof TypeError\n showError(\n menu,\n isServerDown\n ? 'Cannot connect to inspector server. Is the dev server running?'\n : err.message,\n (err as { errorCode?: string }).errorCode ?? 'UNKNOWN',\n )\n updatePosition()\n })\n\n return cleanup\n}\n\nfunction createAskInput(placeholder?: string) {\n const inputWrapper = document.createElement('div')\n inputWrapper.className = menuInputWrapperClass\n\n const input = document.createElement('input')\n input.className = menuInputClass\n input.type = 'text'\n input.placeholder = placeholder ?? 'Describe how to change this component...'\n\n const sendIcon = document.createElement('div')\n sendIcon.className = menuInputIconClass\n 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>`\n sendIcon.style.cursor = 'pointer'\n\n inputWrapper.appendChild(input)\n inputWrapper.appendChild(sendIcon)\n\n return { input, inputWrapper, sendIcon }\n}\n\nfunction showError(menu: HTMLElement, message: string, errorCode?: string): void {\n menu.querySelector(`.${errorMsgClass}`)?.remove()\n\n const errEl = document.createElement('div')\n errEl.className = errorMsgClass\n errEl.textContent =\n errorCode === 'FILE_NOT_FOUND'\n ? 'Source file not found. Is the server running?'\n : `Error: ${message}`\n menu.appendChild(errEl)\n}\n","import { createOverlay } from './overlay.js'\nimport { showIntentMenu } from './menu.js'\nimport type { InspectorOptions, HotKey, SourceLocation, HotKeys } from '@inspecto-dev/types'\nimport { setBaseUrl, fetchIdeInfo } from './http.js'\nimport { badgeClass, inspectorStyles } from './styles.js'\n\nconst ATTR_NAME = 'data-inspecto'\n\nfunction parseAttrValue(value: string): SourceLocation | null {\n const parts = value.split(':')\n if (parts.length < 3) return null\n\n const col = parseInt(parts[parts.length - 1]!, 10)\n const line = parseInt(parts[parts.length - 2]!, 10)\n const file = parts.slice(0, parts.length - 2).join(':')\n\n if (isNaN(line) || isNaN(col) || !file) return null\n return { file, line, column: col }\n}\n\nfunction findInspectable(el: Element | null): Element | null {\n while (el) {\n if (el.hasAttribute(ATTR_NAME)) return el\n el = el.parentElement\n }\n return null\n}\n\nfunction parseHotKeyString(hotKey: string): HotKey[] {\n const keys = hotKey.split('+').map(k => k.trim().toLowerCase())\n const result: HotKey[] = []\n\n if (keys.includes('alt') || keys.includes('option')) result.push('altKey')\n if (keys.includes('ctrl') || keys.includes('control')) result.push('ctrlKey')\n if (\n keys.includes('meta') ||\n keys.includes('cmd') ||\n keys.includes('command') ||\n keys.includes('win')\n )\n result.push('metaKey')\n if (keys.includes('shift')) result.push('shiftKey')\n\n return result\n}\n\nfunction hotKeysHeld(event: MouseEvent, hotKeys: string): boolean {\n if (!hotKeys) return false\n const mappedKeys = parseHotKeyString(hotKeys)\n if (mappedKeys.length === 0) return false\n return mappedKeys.every(key => event[key])\n}\n\n// Fallback class for SSR environments\nconst BaseElement =\n typeof HTMLElement !== 'undefined' ? HTMLElement : (class {} as typeof HTMLElement)\n\nclass InspectoElement extends BaseElement {\n private options: InspectorOptions = {}\n private serverHotKeys: HotKeys | null = null\n private active = false\n private disabled = false\n private isDragging = false\n private hasMoved = false\n private dragStartX = 0\n private dragStartY = 0\n private badgeInitialRight = 16\n private badgeInitialBottom = 16\n private shadowRootEl!: ShadowRoot\n private overlay!: ReturnType<typeof createOverlay>\n private cleanupMenu: (() => void) | null = null\n private badge!: HTMLButtonElement\n\n connectedCallback(): void {\n this.shadowRootEl = this.attachShadow({ mode: 'open' })\n\n const style = document.createElement('style')\n style.textContent = inspectorStyles\n this.shadowRootEl.appendChild(style)\n\n this.overlay = createOverlay(this.shadowRootEl)\n this.badge = this.createBadge()\n\n this.setupListeners()\n\n if (this.options.defaultActive) {\n this.setActive(true)\n }\n }\n\n disconnectedCallback(): void {\n this.teardownListeners()\n }\n\n configure(options: InspectorOptions): void {\n this.options = options\n if (options.serverUrl) {\n setBaseUrl(options.serverUrl)\n }\n\n // Apply explicitly configured theme, or fallback to auto (CSS media queries will take over if 'auto' or undefined)\n if (options.theme === 'dark') {\n this.setAttribute('data-theme', 'dark')\n } else if (options.theme === 'light') {\n this.setAttribute('data-theme', 'light')\n } else {\n this.removeAttribute('data-theme')\n }\n\n // Fetch hotKeys + other runtime config (prompts, targets) from the server.\n // hotKeys deliberately NOT baked into the injected script so that changes to\n // settings.json take effect on page refresh without restarting the dev server.\n fetchIdeInfo(true)\n .then(info => {\n if (info?.hotKeys !== undefined) {\n this.serverHotKeys = info.hotKeys\n this.updateBadgeContent()\n }\n if (info?.theme !== undefined) {\n if (info.theme === 'dark') {\n this.setAttribute('data-theme', 'dark')\n } else if (info.theme === 'light') {\n this.setAttribute('data-theme', 'light')\n } else {\n this.removeAttribute('data-theme')\n }\n }\n if (info?.includeSnippet !== undefined) {\n this.options.includeSnippet = info.includeSnippet\n }\n })\n .catch(() => {})\n }\n\n private createBadge(): HTMLButtonElement {\n const btn = document.createElement('button')\n btn.className = badgeClass\n btn.style.display = 'flex'\n\n const textSpan = document.createElement('span')\n textSpan.textContent = 'Inspecto Ready'\n\n const closeBtn = document.createElement('span')\n closeBtn.className = `${badgeClass}-close`\n closeBtn.innerHTML = '×'\n closeBtn.title = 'Pause Inspector'\n closeBtn.addEventListener('click', e => {\n e.stopPropagation()\n this.toggleDisabled()\n })\n\n btn.appendChild(textSpan)\n btn.appendChild(closeBtn)\n\n // Drag and Drop support\n btn.addEventListener('mousedown', this.onDragStart)\n\n btn.addEventListener('click', e => {\n // Prevent click if we were dragging\n if (this.hasMoved) {\n this.hasMoved = false\n return\n }\n\n if (this.disabled) {\n this.toggleDisabled()\n } else {\n this.setActive(!this.active)\n }\n })\n this.shadowRootEl.appendChild(btn)\n return btn\n }\n\n private readonly onDragStart = (e: MouseEvent): void => {\n // Only allow dragging with primary mouse button\n if (e.button !== 0) return\n\n // Don't drag if clicking the close button\n if ((e.target as Element).classList?.contains(`${badgeClass}-close`)) return\n\n e.preventDefault()\n\n this.isDragging = true\n this.hasMoved = false\n\n const rect = this.badge.getBoundingClientRect()\n // Calculate the exact offset where the user clicked inside the badge\n this.dragStartX = e.clientX - rect.left\n this.dragStartY = e.clientY - rect.top\n\n document.addEventListener('mousemove', this.onDragMove)\n document.addEventListener('mouseup', this.onDragEnd)\n }\n\n private readonly onDragMove = (e: MouseEvent): void => {\n if (!this.isDragging) return\n this.hasMoved = true\n\n // Calculate new position based on top/left\n let newLeft = e.clientX - this.dragStartX\n let newTop = e.clientY - this.dragStartY\n\n // Constrain to viewport\n const badgeWidth = this.badge.offsetWidth\n const badgeHeight = this.badge.offsetHeight\n\n newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - badgeWidth))\n newTop = Math.max(0, Math.min(newTop, window.innerHeight - badgeHeight))\n\n // Disable transition during drag for smoothness\n this.badge.style.transition = 'none'\n // Clear right/bottom to avoid conflicts\n this.badge.style.right = 'auto'\n this.badge.style.bottom = 'auto'\n this.badge.style.left = `${newLeft}px`\n this.badge.style.top = `${newTop}px`\n }\n\n private readonly onDragEnd = (): void => {\n document.removeEventListener('mousemove', this.onDragMove)\n document.removeEventListener('mouseup', this.onDragEnd)\n\n // Re-enable transitions\n this.badge.style.transition = ''\n\n // If it was just a click, reset isDragging state immediately\n // Otherwise, leave it true so the click handler knows to ignore the event\n setTimeout(() => {\n this.isDragging = false\n }, 0)\n }\n\n private toggleDisabled(): void {\n this.disabled = !this.disabled\n if (this.disabled) {\n this.active = false\n this.overlay.hide()\n this.cleanupMenu?.()\n this.cleanupMenu = null\n }\n this.updateBadgeContent()\n }\n\n private dismiss(): void {\n this.badge.style.display = 'none'\n this.setActive(false)\n }\n\n private getHotKeyHint(): string {\n const hotKeys = this.getEffectiveHotKeys()\n if (hotKeys === false) return 'Inspecto Ready'\n\n // Check if mac\n const isMac =\n typeof navigator !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.platform)\n\n const keys = hotKeys.split('+').map(k => k.trim().toLowerCase())\n const displayKeys = keys.map(k => {\n if (k === 'alt' || k === 'option') return isMac ? '⌥' : 'Alt'\n if (k === 'cmd' || k === 'meta' || k === 'win' || k === 'command') return isMac ? '⌘' : 'Win'\n if (k === 'ctrl' || k === 'control') return isMac ? '⌃' : 'Ctrl'\n if (k === 'shift') return isMac ? '⇧' : 'Shift'\n return k.charAt(0).toUpperCase() + k.slice(1)\n })\n\n return `Hold ${displayKeys.join(' + ')} to Inspect`\n }\n\n private getEffectiveHotKeys(): HotKeys {\n if (this.options.hotKeys !== undefined) return this.options.hotKeys\n if (this.serverHotKeys !== null) return this.serverHotKeys\n return 'alt'\n }\n\n private updateBadgeContent(): void {\n const textSpan = this.badge.querySelector('span')\n if (!textSpan) return\n\n if (this.disabled) {\n textSpan.textContent = 'Inspector Paused'\n this.badge.classList.remove('active')\n this.badge.classList.add('disabled')\n } else if (this.active) {\n textSpan.textContent = '🔍 Inspecting...'\n this.badge.classList.remove('disabled')\n this.badge.classList.add('active')\n } else {\n textSpan.textContent = this.getHotKeyHint()\n this.badge.classList.remove('active', 'disabled')\n }\n }\n\n private setActive(value: boolean): void {\n this.active = value\n this.updateBadgeContent()\n\n if (!value) {\n this.overlay.hide()\n this.cleanupMenu?.()\n this.cleanupMenu = null\n }\n }\n\n private readonly onMouseMove = (e: MouseEvent): void => {\n const isActive = this.isInspectorActive(e)\n if (!isActive) {\n this.overlay.hide()\n return\n }\n\n const target = findInspectable(e.target as Element)\n if (!target) {\n this.overlay.hide()\n return\n }\n\n const attrValue = target.getAttribute(ATTR_NAME)!\n const loc = parseAttrValue(attrValue)\n const label = loc ? `${loc.file.split('/').pop() ?? ''}:${loc.line}` : attrValue\n\n this.overlay.show(target, label)\n e.stopPropagation()\n }\n\n private readonly onClick = (e: MouseEvent): void => {\n this.handleTrigger(e)\n }\n\n private readonly onContextMenu = (e: MouseEvent): void => {\n if (this.isInspectorActive(e)) {\n this.handleTrigger(e)\n }\n }\n\n private handleTrigger(e: MouseEvent): void {\n if (!this.isInspectorActive(e)) return\n\n const target = findInspectable(e.target as Element)\n if (!target) return\n\n e.preventDefault()\n e.stopPropagation()\n\n const attrValue = target.getAttribute(ATTR_NAME)!\n const loc = parseAttrValue(attrValue)\n if (!loc) return\n\n this.cleanupMenu?.()\n\n this.cleanupMenu = showIntentMenu(\n this.shadowRootEl,\n loc,\n e.clientX,\n e.clientY,\n this.options,\n () => {\n this.cleanupMenu = null\n },\n )\n }\n\n private readonly onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') {\n this.cleanupMenu?.()\n this.overlay.hide()\n }\n }\n\n private isInspectorActive(e: MouseEvent): boolean {\n if (this.disabled) return false\n if (this.active) return true\n\n const hotKeys = this.getEffectiveHotKeys()\n if (hotKeys === false) return false\n return hotKeysHeld(e, hotKeys)\n }\n\n private setupListeners(): void {\n document.addEventListener('mousemove', this.onMouseMove, true)\n document.addEventListener('click', this.onClick, true)\n document.addEventListener('contextmenu', this.onContextMenu, true)\n document.addEventListener('keydown', this.onKeyDown, true)\n }\n\n private teardownListeners(): void {\n document.removeEventListener('mousemove', this.onMouseMove, true)\n document.removeEventListener('click', this.onClick, true)\n document.removeEventListener('contextmenu', this.onContextMenu, true)\n document.removeEventListener('keydown', this.onKeyDown, true)\n }\n}\n\nif (typeof customElements !== 'undefined') {\n customElements.define('inspecto-overlay', InspectoElement)\n}\n\nexport { InspectoElement }\n"],"mappings":"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","names":["_a","_b","btn"]}